Add changing the amount of hands on the GUI depending on your body parts (#1406)
* Multiple hands in gui first pass * Remove IHandsComponent interface * Create hand class and more hand textures * Refactor ServerHandsComponent to use a single list of hands * Seal SharedHand * Fix picked up items not showing on top of the hand buttons * Remove HandsGui buttons and panels dictionaries * Fix items in hands rendering * Fix wrong hand container comparison * Fix not updating the location of duplicate hands * Change ClientHandsComponent to use a SortedList instead of a dictionary * More merge conflict fixes * Change SortedList to List * Fix hand button order * Add item tooltip for more than 2 hands and updating when removing hands * Add add hand and remove hand command * Merge conflict fixes * Remove nullable reference type from ContainerSlot * Fix texture errors * Fix error when reaching 0 hands * Fix error when swapping hands with no hands * Merged remove hand methods * Fix item panel texture errors * Merge conflict fixes * Fix addhand and removehand command descriptions * Add properly displaying tooltips for 2 hands * Make hand indexes and locations consistent across the client and server * Add dropping held entity if a hand is removed * Change hand location to be calculated by index * Made different hand gui updates more consistent * Remove human body yml testing changes * Sanitize addhand and removehand commands * Merge conflict fixes * Remove testing changes * Revert body system changes * Add missing imports * Remove obsolete hands parameter in yml files * Fix broken import * Fix startup error and adding and removing hands on the same tick * Make hand container id use an uint In case someone gets more than 2 billion hands * Rename hand component files * Make hands state use an array
This commit is contained in:
@@ -1,4 +1,5 @@
|
|||||||
using Content.Shared.GameObjects;
|
using Content.Client.GameObjects.Components.Items;
|
||||||
|
using Content.Shared.GameObjects;
|
||||||
using Content.Shared.GameObjects.Components.Inventory;
|
using Content.Shared.GameObjects.Components.Inventory;
|
||||||
using Content.Shared.GameObjects.Components.Items;
|
using Content.Shared.GameObjects.Components.Items;
|
||||||
using Robust.Client.Graphics;
|
using Robust.Client.Graphics;
|
||||||
|
|||||||
@@ -1,215 +0,0 @@
|
|||||||
using System.Collections.Generic;
|
|
||||||
using System.Linq;
|
|
||||||
using Content.Client.Interfaces.GameObjects;
|
|
||||||
using Content.Client.UserInterface;
|
|
||||||
using Content.Shared.GameObjects;
|
|
||||||
using Robust.Client.GameObjects;
|
|
||||||
using Robust.Client.Interfaces.GameObjects.Components;
|
|
||||||
using Robust.Shared.GameObjects;
|
|
||||||
using Robust.Shared.Interfaces.GameObjects;
|
|
||||||
using Robust.Shared.IoC;
|
|
||||||
using Robust.Shared.Serialization;
|
|
||||||
using Robust.Shared.ViewVariables;
|
|
||||||
|
|
||||||
namespace Content.Client.GameObjects
|
|
||||||
{
|
|
||||||
[RegisterComponent]
|
|
||||||
[ComponentReference(typeof(IHandsComponent))]
|
|
||||||
public class HandsComponent : SharedHandsComponent, IHandsComponent
|
|
||||||
{
|
|
||||||
private HandsGui _gui;
|
|
||||||
|
|
||||||
#pragma warning disable 649
|
|
||||||
[Dependency] private readonly IGameHud _gameHud;
|
|
||||||
#pragma warning restore 649
|
|
||||||
|
|
||||||
[ViewVariables] private readonly Dictionary<string, IEntity> _hands = new Dictionary<string, IEntity>();
|
|
||||||
|
|
||||||
[ViewVariables] public string ActiveIndex { get; private set; }
|
|
||||||
|
|
||||||
[ViewVariables] private ISpriteComponent _sprite;
|
|
||||||
|
|
||||||
[ViewVariables] public IEntity ActiveHand => GetEntity(ActiveIndex);
|
|
||||||
|
|
||||||
public override void OnRemove()
|
|
||||||
{
|
|
||||||
base.OnRemove();
|
|
||||||
|
|
||||||
_gui?.Dispose();
|
|
||||||
}
|
|
||||||
|
|
||||||
public override void Initialize()
|
|
||||||
{
|
|
||||||
base.Initialize();
|
|
||||||
|
|
||||||
if (Owner.TryGetComponent(out _sprite))
|
|
||||||
{
|
|
||||||
foreach (var slot in _hands.Keys)
|
|
||||||
{
|
|
||||||
_sprite.LayerMapReserveBlank($"hand-{slot}");
|
|
||||||
_setHand(slot, _hands[slot]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public IEntity GetEntity(string index)
|
|
||||||
{
|
|
||||||
if (!string.IsNullOrEmpty(index) && _hands.TryGetValue(index, out var entity))
|
|
||||||
{
|
|
||||||
return entity;
|
|
||||||
}
|
|
||||||
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
public override void HandleComponentState(ComponentState curState, ComponentState nextState)
|
|
||||||
{
|
|
||||||
if (curState == null)
|
|
||||||
return;
|
|
||||||
|
|
||||||
var cast = (HandsComponentState) curState;
|
|
||||||
foreach (var (slot, uid) in cast.Hands)
|
|
||||||
{
|
|
||||||
IEntity entity = null;
|
|
||||||
try
|
|
||||||
{
|
|
||||||
entity = Owner.EntityManager.GetEntity(uid);
|
|
||||||
}
|
|
||||||
catch
|
|
||||||
{
|
|
||||||
// Nothing.
|
|
||||||
}
|
|
||||||
|
|
||||||
_hands[slot] = entity;
|
|
||||||
_setHand(slot, entity);
|
|
||||||
}
|
|
||||||
|
|
||||||
foreach (var slot in _hands.Keys.ToList())
|
|
||||||
{
|
|
||||||
if (!cast.Hands.ContainsKey(slot))
|
|
||||||
{
|
|
||||||
_hands[slot] = null;
|
|
||||||
_setHand(slot, null);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
ActiveIndex = cast.ActiveIndex;
|
|
||||||
|
|
||||||
_gui?.UpdateHandIcons();
|
|
||||||
RefreshInHands();
|
|
||||||
}
|
|
||||||
|
|
||||||
private void _setHand(string hand, IEntity entity)
|
|
||||||
{
|
|
||||||
if (_sprite == null)
|
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (entity == null)
|
|
||||||
{
|
|
||||||
_sprite.LayerSetVisible($"hand-{hand}", false);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
SetInHands(hand, entity);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void SetInHands(string hand, IEntity entity)
|
|
||||||
{
|
|
||||||
if (entity == null)
|
|
||||||
{
|
|
||||||
_sprite.LayerSetVisible($"hand-{hand}", false);
|
|
||||||
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!entity.TryGetComponent(out ItemComponent item)) return;
|
|
||||||
var maybeInhands = item.GetInHandStateInfo(hand);
|
|
||||||
if (!maybeInhands.HasValue)
|
|
||||||
{
|
|
||||||
_sprite.LayerSetVisible($"hand-{hand}", false);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
var (rsi, state) = maybeInhands.Value;
|
|
||||||
_sprite.LayerSetVisible($"hand-{hand}", true);
|
|
||||||
_sprite.LayerSetState($"hand-{hand}", state, rsi);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public void RefreshInHands()
|
|
||||||
{
|
|
||||||
if (!Initialized) return;
|
|
||||||
|
|
||||||
foreach (var (hand, entity) in _hands)
|
|
||||||
{
|
|
||||||
SetInHands(hand, entity);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public override void ExposeData(ObjectSerializer serializer)
|
|
||||||
{
|
|
||||||
base.ExposeData(serializer);
|
|
||||||
|
|
||||||
serializer.DataReadWriteFunction(
|
|
||||||
"hands",
|
|
||||||
new List<string>(),
|
|
||||||
hands => hands.ForEach(slot => _hands.Add(slot, null)),
|
|
||||||
() => _hands.Keys.ToList());
|
|
||||||
|
|
||||||
serializer.DataField(this, x => ActiveIndex, "defaultHand", _hands.Keys.LastOrDefault());
|
|
||||||
}
|
|
||||||
|
|
||||||
public override void HandleMessage(ComponentMessage message, IComponent component)
|
|
||||||
{
|
|
||||||
base.HandleMessage(message, component);
|
|
||||||
|
|
||||||
switch (message)
|
|
||||||
{
|
|
||||||
case PlayerAttachedMsg _:
|
|
||||||
if (_gui == null)
|
|
||||||
{
|
|
||||||
_gui = new HandsGui();
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
_gui.Parent?.RemoveChild(_gui);
|
|
||||||
}
|
|
||||||
|
|
||||||
_gameHud.HandsContainer.AddChild(_gui);
|
|
||||||
_gui.UpdateHandIcons();
|
|
||||||
break;
|
|
||||||
|
|
||||||
case PlayerDetachedMsg _:
|
|
||||||
_gui.Parent?.RemoveChild(_gui);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public void SendChangeHand(string index)
|
|
||||||
{
|
|
||||||
SendNetworkMessage(new ClientChangedHandMsg(index));
|
|
||||||
}
|
|
||||||
|
|
||||||
public void AttackByInHand(string index)
|
|
||||||
{
|
|
||||||
SendNetworkMessage(new ClientAttackByInHandMsg(index));
|
|
||||||
}
|
|
||||||
|
|
||||||
public void UseActiveHand()
|
|
||||||
{
|
|
||||||
if (GetEntity(ActiveIndex) != null)
|
|
||||||
{
|
|
||||||
SendNetworkMessage(new UseInHandMsg());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public void ActivateItemInHand(string handIndex)
|
|
||||||
{
|
|
||||||
if (GetEntity(handIndex) == null)
|
|
||||||
return;
|
|
||||||
SendNetworkMessage(new ActivateInHandMsg(handIndex));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
256
Content.Client/GameObjects/Components/Items/HandsComponent.cs
Normal file
256
Content.Client/GameObjects/Components/Items/HandsComponent.cs
Normal file
@@ -0,0 +1,256 @@
|
|||||||
|
#nullable enable
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Diagnostics.CodeAnalysis;
|
||||||
|
using System.Linq;
|
||||||
|
using Content.Client.UserInterface;
|
||||||
|
using Content.Shared.GameObjects.Components.Items;
|
||||||
|
using Robust.Client.GameObjects;
|
||||||
|
using Robust.Client.Interfaces.GameObjects.Components;
|
||||||
|
using Robust.Shared.GameObjects;
|
||||||
|
using Robust.Shared.Interfaces.GameObjects;
|
||||||
|
using Robust.Shared.IoC;
|
||||||
|
using Robust.Shared.ViewVariables;
|
||||||
|
|
||||||
|
namespace Content.Client.GameObjects.Components.Items
|
||||||
|
{
|
||||||
|
[RegisterComponent]
|
||||||
|
public class HandsComponent : SharedHandsComponent
|
||||||
|
{
|
||||||
|
private HandsGui? _gui;
|
||||||
|
|
||||||
|
#pragma warning disable 649
|
||||||
|
[Dependency] private readonly IGameHud _gameHud = default!;
|
||||||
|
#pragma warning restore 649
|
||||||
|
|
||||||
|
private readonly List<Hand> _hands = new List<Hand>();
|
||||||
|
|
||||||
|
[ViewVariables] public IReadOnlyList<Hand> Hands => _hands;
|
||||||
|
|
||||||
|
[ViewVariables] public string? ActiveIndex { get; private set; }
|
||||||
|
|
||||||
|
[ViewVariables] private ISpriteComponent? _sprite;
|
||||||
|
|
||||||
|
[ViewVariables] public IEntity? ActiveHand => GetEntity(ActiveIndex);
|
||||||
|
|
||||||
|
private void AddHand(Hand hand)
|
||||||
|
{
|
||||||
|
_hands.Insert(hand.Index, hand);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Hand? GetHand(string? name)
|
||||||
|
{
|
||||||
|
return Hands.FirstOrDefault(hand => hand.Name == name);
|
||||||
|
}
|
||||||
|
|
||||||
|
private bool TryHand(string name, [MaybeNullWhen(false)] out Hand hand)
|
||||||
|
{
|
||||||
|
return (hand = GetHand(name)) != null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public IEntity? GetEntity(string? handName)
|
||||||
|
{
|
||||||
|
if (handName == null)
|
||||||
|
{
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
return GetHand(handName)?.Entity;
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void OnRemove()
|
||||||
|
{
|
||||||
|
base.OnRemove();
|
||||||
|
|
||||||
|
_gui?.Dispose();
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void Initialize()
|
||||||
|
{
|
||||||
|
base.Initialize();
|
||||||
|
|
||||||
|
if (Owner.TryGetComponent(out _sprite))
|
||||||
|
{
|
||||||
|
foreach (var hand in _hands)
|
||||||
|
{
|
||||||
|
_sprite.LayerMapReserveBlank($"hand-{hand.Name}");
|
||||||
|
UpdateHandSprites(hand);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void HandleComponentState(ComponentState? curState, ComponentState? nextState)
|
||||||
|
{
|
||||||
|
if (curState == null)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
var cast = (HandsComponentState) curState;
|
||||||
|
foreach (var sharedHand in cast.Hands)
|
||||||
|
{
|
||||||
|
if (!TryHand(sharedHand.Name, out var hand))
|
||||||
|
{
|
||||||
|
hand = new Hand(sharedHand, Owner.EntityManager);
|
||||||
|
AddHand(hand);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
hand.Location = sharedHand.Location;
|
||||||
|
|
||||||
|
hand.Entity = sharedHand.EntityUid.HasValue
|
||||||
|
? Owner.EntityManager.GetEntity(sharedHand.EntityUid.Value)
|
||||||
|
: null;
|
||||||
|
}
|
||||||
|
|
||||||
|
UpdateHandSprites(hand);
|
||||||
|
}
|
||||||
|
|
||||||
|
foreach (var currentHand in _hands.ToList())
|
||||||
|
{
|
||||||
|
if (cast.Hands.All(newHand => newHand.Name != currentHand.Name))
|
||||||
|
{
|
||||||
|
_hands.Remove(currentHand);
|
||||||
|
_gui?.RemoveHand(currentHand);
|
||||||
|
HideHand(currentHand);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ActiveIndex = cast.ActiveIndex;
|
||||||
|
|
||||||
|
_gui?.UpdateHandIcons();
|
||||||
|
RefreshInHands();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void HideHand(Hand hand)
|
||||||
|
{
|
||||||
|
_sprite?.LayerSetVisible($"hand-{hand.Name}", false);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void UpdateHandSprites(Hand hand)
|
||||||
|
{
|
||||||
|
if (_sprite == null)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
var entity = hand.Entity;
|
||||||
|
var name = hand.Name;
|
||||||
|
|
||||||
|
if (entity == null)
|
||||||
|
{
|
||||||
|
_sprite.LayerSetVisible($"hand-{name}", false);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!entity.TryGetComponent(out ItemComponent item)) return;
|
||||||
|
|
||||||
|
var maybeInHands = item.GetInHandStateInfo(name);
|
||||||
|
|
||||||
|
if (!maybeInHands.HasValue)
|
||||||
|
{
|
||||||
|
_sprite.LayerSetVisible($"hand-{name}", false);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
var (rsi, state) = maybeInHands.Value;
|
||||||
|
_sprite.LayerSetVisible($"hand-{name}", true);
|
||||||
|
_sprite.LayerSetState($"hand-{name}", state, rsi);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void RefreshInHands()
|
||||||
|
{
|
||||||
|
if (!Initialized) return;
|
||||||
|
|
||||||
|
foreach (var hand in _hands)
|
||||||
|
{
|
||||||
|
UpdateHandSprites(hand);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override void Startup()
|
||||||
|
{
|
||||||
|
ActiveIndex = _hands.LastOrDefault()?.Name;
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void HandleMessage(ComponentMessage message, IComponent? component)
|
||||||
|
{
|
||||||
|
base.HandleMessage(message, component);
|
||||||
|
|
||||||
|
switch (message)
|
||||||
|
{
|
||||||
|
case PlayerAttachedMsg _:
|
||||||
|
if (_gui == null)
|
||||||
|
{
|
||||||
|
_gui = new HandsGui();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
_gui.Parent?.RemoveChild(_gui);
|
||||||
|
}
|
||||||
|
|
||||||
|
_gameHud.HandsContainer.AddChild(_gui);
|
||||||
|
_gui.UpdateHandIcons();
|
||||||
|
break;
|
||||||
|
|
||||||
|
case PlayerDetachedMsg _:
|
||||||
|
_gui?.Parent?.RemoveChild(_gui);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void SendChangeHand(string index)
|
||||||
|
{
|
||||||
|
SendNetworkMessage(new ClientChangedHandMsg(index));
|
||||||
|
}
|
||||||
|
|
||||||
|
public void AttackByInHand(string index)
|
||||||
|
{
|
||||||
|
SendNetworkMessage(new ClientAttackByInHandMsg(index));
|
||||||
|
}
|
||||||
|
|
||||||
|
public void UseActiveHand()
|
||||||
|
{
|
||||||
|
if (GetEntity(ActiveIndex) != null)
|
||||||
|
{
|
||||||
|
SendNetworkMessage(new UseInHandMsg());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void ActivateItemInHand(string handIndex)
|
||||||
|
{
|
||||||
|
if (GetEntity(handIndex) == null)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
SendNetworkMessage(new ActivateInHandMsg(handIndex));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public class Hand
|
||||||
|
{
|
||||||
|
// TODO: Separate into server hand and client hand
|
||||||
|
public Hand(SharedHand hand, IEntityManager manager, HandButton? button = null)
|
||||||
|
{
|
||||||
|
Index = hand.Index;
|
||||||
|
Name = hand.Name;
|
||||||
|
Location = hand.Location;
|
||||||
|
Button = button;
|
||||||
|
|
||||||
|
if (!hand.EntityUid.HasValue)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
manager.TryGetEntity(hand.EntityUid.Value, out var entity);
|
||||||
|
Entity = entity;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int Index { get; }
|
||||||
|
public string Name { get; }
|
||||||
|
public HandLocation Location { get; set; }
|
||||||
|
public IEntity? Entity { get; set; }
|
||||||
|
public HandButton? Button { get; set; }
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -14,7 +14,7 @@ using Robust.Shared.Serialization;
|
|||||||
using Robust.Shared.Utility;
|
using Robust.Shared.Utility;
|
||||||
using Robust.Shared.ViewVariables;
|
using Robust.Shared.ViewVariables;
|
||||||
|
|
||||||
namespace Content.Client.GameObjects
|
namespace Content.Client.GameObjects.Components.Items
|
||||||
{
|
{
|
||||||
[RegisterComponent]
|
[RegisterComponent]
|
||||||
[ComponentReference(typeof(IItemComponent))]
|
[ComponentReference(typeof(IItemComponent))]
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
using Content.Client.GameObjects.Components.Items;
|
||||||
using Content.Shared.GameObjects.Components.Storage;
|
using Content.Shared.GameObjects.Components.Storage;
|
||||||
using Content.Client.Interfaces.GameObjects;
|
|
||||||
using Content.Client.Interfaces.GameObjects.Components.Interaction;
|
using Content.Client.Interfaces.GameObjects.Components.Interaction;
|
||||||
using Robust.Client.Graphics.Drawing;
|
using Robust.Client.Graphics.Drawing;
|
||||||
using Robust.Client.Interfaces.GameObjects.Components;
|
using Robust.Client.Interfaces.GameObjects.Components;
|
||||||
@@ -137,7 +137,7 @@ namespace Content.Client.GameObjects.Components.Storage
|
|||||||
{
|
{
|
||||||
var controlledEntity = IoCManager.Resolve<IPlayerManager>().LocalPlayer.ControlledEntity;
|
var controlledEntity = IoCManager.Resolve<IPlayerManager>().LocalPlayer.ControlledEntity;
|
||||||
|
|
||||||
if (controlledEntity.TryGetComponent(out IHandsComponent hands))
|
if (controlledEntity.TryGetComponent(out HandsComponent hands))
|
||||||
{
|
{
|
||||||
StorageEntity.SendNetworkMessage(new InsertEntityMessage());
|
StorageEntity.SendNetworkMessage(new InsertEntityMessage());
|
||||||
}
|
}
|
||||||
@@ -250,7 +250,7 @@ namespace Content.Client.GameObjects.Components.Storage
|
|||||||
{
|
{
|
||||||
var controlledEntity = IoCManager.Resolve<IPlayerManager>().LocalPlayer.ControlledEntity;
|
var controlledEntity = IoCManager.Resolve<IPlayerManager>().LocalPlayer.ControlledEntity;
|
||||||
|
|
||||||
if (controlledEntity.TryGetComponent(out IHandsComponent hands))
|
if (controlledEntity.TryGetComponent(out HandsComponent hands))
|
||||||
{
|
{
|
||||||
StorageEntity.SendNetworkMessage(new InsertEntityMessage());
|
StorageEntity.SendNetworkMessage(new InsertEntityMessage());
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
using System;
|
using System;
|
||||||
|
using Content.Client.GameObjects.Components.Items;
|
||||||
using Content.Client.GameObjects.Components.Weapons.Ranged;
|
using Content.Client.GameObjects.Components.Weapons.Ranged;
|
||||||
using Content.Client.Interfaces.GameObjects;
|
|
||||||
using Content.Shared.GameObjects.Components.Weapons.Ranged;
|
using Content.Shared.GameObjects.Components.Weapons.Ranged;
|
||||||
using Robust.Client.GameObjects.EntitySystems;
|
using Robust.Client.GameObjects.EntitySystems;
|
||||||
using Robust.Client.Interfaces.Graphics.ClientEye;
|
using Robust.Client.Interfaces.Graphics.ClientEye;
|
||||||
@@ -11,7 +11,6 @@ using Robust.Shared.Input;
|
|||||||
using Robust.Shared.Interfaces.Map;
|
using Robust.Shared.Interfaces.Map;
|
||||||
using Robust.Shared.Interfaces.Timing;
|
using Robust.Shared.Interfaces.Timing;
|
||||||
using Robust.Shared.IoC;
|
using Robust.Shared.IoC;
|
||||||
using Robust.Shared.Log;
|
|
||||||
|
|
||||||
namespace Content.Client.GameObjects.EntitySystems
|
namespace Content.Client.GameObjects.EntitySystems
|
||||||
{
|
{
|
||||||
@@ -48,7 +47,7 @@ namespace Content.Client.GameObjects.EntitySystems
|
|||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
var state = _inputSystem.CmdStates.GetState(EngineKeyFunctions.Use);
|
var state = _inputSystem.CmdStates.GetState(EngineKeyFunctions.Use);
|
||||||
if (!_combatModeSystem.IsInCombatMode() || state != BoundKeyState.Down)
|
if (!_combatModeSystem.IsInCombatMode() || state != BoundKeyState.Down)
|
||||||
{
|
{
|
||||||
@@ -58,7 +57,7 @@ namespace Content.Client.GameObjects.EntitySystems
|
|||||||
}
|
}
|
||||||
|
|
||||||
var entity = _playerManager.LocalPlayer.ControlledEntity;
|
var entity = _playerManager.LocalPlayer.ControlledEntity;
|
||||||
if (entity == null || !entity.TryGetComponent(out IHandsComponent hands))
|
if (entity == null || !entity.TryGetComponent(out HandsComponent hands))
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,19 +0,0 @@
|
|||||||
using Robust.Shared.Interfaces.GameObjects;
|
|
||||||
|
|
||||||
namespace Content.Client.Interfaces.GameObjects
|
|
||||||
{
|
|
||||||
// HYPER SIMPLE HANDS API CLIENT SIDE.
|
|
||||||
// To allow for showing the HUD, mostly.
|
|
||||||
public interface IHandsComponent
|
|
||||||
{
|
|
||||||
IEntity GetEntity(string index);
|
|
||||||
string ActiveIndex { get; }
|
|
||||||
IEntity ActiveHand { get; }
|
|
||||||
|
|
||||||
void SendChangeHand(string index);
|
|
||||||
void AttackByInHand(string index);
|
|
||||||
void UseActiveHand();
|
|
||||||
void ActivateItemInHand(string handIndex);
|
|
||||||
void RefreshInHands();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
15
Content.Client/UserInterface/HandButton.cs
Normal file
15
Content.Client/UserInterface/HandButton.cs
Normal file
@@ -0,0 +1,15 @@
|
|||||||
|
using Content.Shared.GameObjects.Components.Items;
|
||||||
|
using Robust.Client.Graphics;
|
||||||
|
|
||||||
|
namespace Content.Client.UserInterface
|
||||||
|
{
|
||||||
|
public class HandButton : ItemSlotButton
|
||||||
|
{
|
||||||
|
public HandButton(Texture texture, Texture storageTexture, HandLocation location) : base(texture, storageTexture)
|
||||||
|
{
|
||||||
|
Location = location;
|
||||||
|
}
|
||||||
|
|
||||||
|
public HandLocation Location { get; }
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,14 +1,15 @@
|
|||||||
using Content.Client.GameObjects;
|
using System;
|
||||||
using Content.Client.Interfaces.GameObjects;
|
using System.Linq;
|
||||||
|
using Content.Client.GameObjects.Components.Items;
|
||||||
using Content.Client.Utility;
|
using Content.Client.Utility;
|
||||||
|
using Content.Shared.GameObjects.Components.Items;
|
||||||
using Content.Shared.Input;
|
using Content.Shared.Input;
|
||||||
using Robust.Client.Interfaces.GameObjects.Components;
|
using Robust.Client.Graphics;
|
||||||
using Robust.Client.Interfaces.ResourceManagement;
|
using Robust.Client.Interfaces.ResourceManagement;
|
||||||
using Robust.Client.Player;
|
using Robust.Client.Player;
|
||||||
using Robust.Client.UserInterface;
|
using Robust.Client.UserInterface;
|
||||||
using Robust.Client.UserInterface.Controls;
|
using Robust.Client.UserInterface.Controls;
|
||||||
using Robust.Shared.Input;
|
using Robust.Shared.Input;
|
||||||
using Robust.Shared.Interfaces.GameObjects;
|
|
||||||
using Robust.Shared.IoC;
|
using Robust.Shared.IoC;
|
||||||
using Robust.Shared.Timing;
|
using Robust.Shared.Timing;
|
||||||
|
|
||||||
@@ -16,67 +17,140 @@ namespace Content.Client.UserInterface
|
|||||||
{
|
{
|
||||||
public class HandsGui : Control
|
public class HandsGui : Control
|
||||||
{
|
{
|
||||||
private const string HandNameLeft = "left";
|
|
||||||
private const string HandNameRight = "right";
|
|
||||||
|
|
||||||
#pragma warning disable 0649
|
#pragma warning disable 0649
|
||||||
[Dependency] private readonly IPlayerManager _playerManager;
|
[Dependency] private readonly IPlayerManager _playerManager;
|
||||||
[Dependency] private readonly IResourceCache _resourceCache;
|
[Dependency] private readonly IResourceCache _resourceCache;
|
||||||
[Dependency] private readonly IItemSlotManager _itemSlotManager;
|
[Dependency] private readonly IItemSlotManager _itemSlotManager;
|
||||||
#pragma warning restore 0649
|
#pragma warning restore 0649
|
||||||
|
|
||||||
private IEntity _leftHand;
|
private readonly TextureRect _activeHandRect;
|
||||||
private IEntity _rightHand;
|
|
||||||
|
|
||||||
private readonly TextureRect ActiveHandRect;
|
private readonly Texture _leftHandTexture;
|
||||||
|
private readonly Texture _middleHandTexture;
|
||||||
|
private readonly Texture _rightHandTexture;
|
||||||
|
|
||||||
private readonly ItemSlotButton _leftButton;
|
private readonly ItemStatusPanel _leftPanel;
|
||||||
private readonly ItemSlotButton _rightButton;
|
private readonly ItemStatusPanel _topPanel;
|
||||||
|
private readonly ItemStatusPanel _rightPanel;
|
||||||
|
|
||||||
private readonly ItemStatusPanel _rightStatusPanel;
|
private readonly HBoxContainer _guiContainer;
|
||||||
private readonly ItemStatusPanel _leftStatusPanel;
|
private readonly VBoxContainer _handsColumn;
|
||||||
|
private readonly HBoxContainer _handsContainer;
|
||||||
|
|
||||||
|
private int _lastHands;
|
||||||
|
|
||||||
public HandsGui()
|
public HandsGui()
|
||||||
{
|
{
|
||||||
IoCManager.InjectDependencies(this);
|
IoCManager.InjectDependencies(this);
|
||||||
|
|
||||||
var textureHandLeft = _resourceCache.GetTexture("/Textures/Interface/Inventory/hand_l.png");
|
AddChild(_guiContainer = new HBoxContainer
|
||||||
var textureHandRight = _resourceCache.GetTexture("/Textures/Interface/Inventory/hand_r.png");
|
|
||||||
var textureHandActive = _resourceCache.GetTexture("/Textures/Interface/Inventory/hand_active.png");
|
|
||||||
var storageTexture = _resourceCache.GetTexture("/Textures/Interface/Inventory/back.png");
|
|
||||||
|
|
||||||
_rightStatusPanel = new ItemStatusPanel(true);
|
|
||||||
_leftStatusPanel = new ItemStatusPanel(false);
|
|
||||||
|
|
||||||
_leftButton = new ItemSlotButton(textureHandLeft, storageTexture);
|
|
||||||
_rightButton = new ItemSlotButton(textureHandRight, storageTexture);
|
|
||||||
var hBox = new HBoxContainer
|
|
||||||
{
|
{
|
||||||
SeparationOverride = 0,
|
SeparationOverride = 0,
|
||||||
Children = {_rightStatusPanel, _rightButton, _leftButton, _leftStatusPanel}
|
Children =
|
||||||
};
|
{
|
||||||
|
(_rightPanel = ItemStatusPanel.FromSide(HandLocation.Right)),
|
||||||
|
(_handsColumn = new VBoxContainer
|
||||||
|
{
|
||||||
|
Children =
|
||||||
|
{
|
||||||
|
(_topPanel = ItemStatusPanel.FromSide(HandLocation.Middle)),
|
||||||
|
(_handsContainer = new HBoxContainer {SeparationOverride = 0})
|
||||||
|
}
|
||||||
|
}),
|
||||||
|
(_leftPanel = ItemStatusPanel.FromSide(HandLocation.Left))
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
AddChild(hBox);
|
var textureHandActive = _resourceCache.GetTexture("/Textures/Interface/Inventory/hand_active.png");
|
||||||
|
|
||||||
_leftButton.OnPressed += args => HandKeyBindDown(args, HandNameLeft);
|
|
||||||
_leftButton.OnStoragePressed += args => _OnStoragePressed(args, HandNameLeft);
|
|
||||||
_rightButton.OnPressed += args => HandKeyBindDown(args, HandNameRight);
|
|
||||||
_rightButton.OnStoragePressed += args => _OnStoragePressed(args, HandNameRight);
|
|
||||||
|
|
||||||
// Active hand
|
// Active hand
|
||||||
_leftButton.AddChild(ActiveHandRect = new TextureRect
|
_activeHandRect = new TextureRect
|
||||||
{
|
{
|
||||||
Texture = textureHandActive,
|
Texture = textureHandActive,
|
||||||
TextureScale = (2, 2)
|
TextureScale = (2, 2)
|
||||||
});
|
};
|
||||||
|
|
||||||
|
_leftHandTexture = _resourceCache.GetTexture("/Textures/Interface/Inventory/hand_l.png");
|
||||||
|
_middleHandTexture = _resourceCache.GetTexture("/Textures/Interface/Inventory/hand_middle.png");
|
||||||
|
_rightHandTexture = _resourceCache.GetTexture("/Textures/Interface/Inventory/hand_r.png");
|
||||||
|
}
|
||||||
|
|
||||||
|
private ItemStatusPanel GetItemPanel(Hand hand)
|
||||||
|
{
|
||||||
|
return hand.Location switch
|
||||||
|
{
|
||||||
|
HandLocation.Left => _rightPanel,
|
||||||
|
HandLocation.Middle => _topPanel,
|
||||||
|
HandLocation.Right => _leftPanel,
|
||||||
|
_ => throw new IndexOutOfRangeException()
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
private Texture HandTexture(HandLocation location)
|
||||||
|
{
|
||||||
|
switch (location)
|
||||||
|
{
|
||||||
|
case HandLocation.Left:
|
||||||
|
return _leftHandTexture;
|
||||||
|
case HandLocation.Middle:
|
||||||
|
return _middleHandTexture;
|
||||||
|
case HandLocation.Right:
|
||||||
|
return _rightHandTexture;
|
||||||
|
default:
|
||||||
|
throw new ArgumentOutOfRangeException(nameof(location), location, null);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets the hands component controling this gui, returns true if successful and false if failure
|
/// Adds a new hand to this control
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="hand">The hand to add to this control</param>
|
||||||
|
/// <param name="buttonLocation">
|
||||||
|
/// The actual location of the button. The right hand is drawn
|
||||||
|
/// on the LEFT of the screen.
|
||||||
|
/// </param>
|
||||||
|
private void AddHand(Hand hand, HandLocation buttonLocation)
|
||||||
|
{
|
||||||
|
var buttonTexture = HandTexture(buttonLocation);
|
||||||
|
var storageTexture = _resourceCache.GetTexture("/Textures/Interface/Inventory/back.png");
|
||||||
|
var button = new HandButton(buttonTexture, storageTexture, buttonLocation);
|
||||||
|
var slot = hand.Name;
|
||||||
|
|
||||||
|
button.OnPressed += args => HandKeyBindDown(args, slot);
|
||||||
|
button.OnStoragePressed += args => _OnStoragePressed(args, slot);
|
||||||
|
|
||||||
|
_handsContainer.AddChild(button);
|
||||||
|
|
||||||
|
if (_activeHandRect.Parent == null)
|
||||||
|
{
|
||||||
|
button.AddChild(_activeHandRect);
|
||||||
|
_activeHandRect.SetPositionInParent(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
hand.Button = button;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void RemoveHand(Hand hand)
|
||||||
|
{
|
||||||
|
var button = hand.Button;
|
||||||
|
|
||||||
|
if (button != null)
|
||||||
|
{
|
||||||
|
if (button.Children.Contains(_activeHandRect))
|
||||||
|
{
|
||||||
|
button.RemoveChild(_activeHandRect);
|
||||||
|
}
|
||||||
|
|
||||||
|
_handsContainer.RemoveChild(button);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets the hands component controlling this gui
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="hands"></param>
|
/// <param name="hands"></param>
|
||||||
/// <returns></returns>
|
/// <returns>true if successful and false if failure</returns>
|
||||||
private bool TryGetHands(out IHandsComponent hands)
|
private bool TryGetHands(out HandsComponent hands)
|
||||||
{
|
{
|
||||||
hands = default;
|
hands = default;
|
||||||
|
|
||||||
@@ -93,50 +167,63 @@ namespace Content.Client.UserInterface
|
|||||||
|
|
||||||
UpdateDraw();
|
UpdateDraw();
|
||||||
|
|
||||||
if (!TryGetHands(out var hands))
|
if (!TryGetHands(out var component))
|
||||||
|
{
|
||||||
return;
|
return;
|
||||||
|
|
||||||
var left = hands.GetEntity(HandNameLeft);
|
|
||||||
var right = hands.GetEntity(HandNameRight);
|
|
||||||
|
|
||||||
ActiveHandRect.Parent.RemoveChild(ActiveHandRect);
|
|
||||||
var parent = hands.ActiveIndex == HandNameLeft ? _leftButton : _rightButton;
|
|
||||||
parent.AddChild(ActiveHandRect);
|
|
||||||
ActiveHandRect.SetPositionInParent(1);
|
|
||||||
|
|
||||||
if (left != _leftHand)
|
|
||||||
{
|
|
||||||
_leftHand = left;
|
|
||||||
_itemSlotManager.SetItemSlot(_leftButton, _leftHand);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (right != _rightHand)
|
// TODO: Remove button on remove hand
|
||||||
|
|
||||||
|
var hands = component.Hands.OrderByDescending(x => x.Location).ToArray();
|
||||||
|
for (var i = 0; i < hands.Length; i++)
|
||||||
{
|
{
|
||||||
_rightHand = right;
|
var hand = hands[i];
|
||||||
_itemSlotManager.SetItemSlot(_rightButton, _rightHand);
|
|
||||||
|
if (hand.Button == null)
|
||||||
|
{
|
||||||
|
AddHand(hand, hand.Location);
|
||||||
|
}
|
||||||
|
|
||||||
|
hand.Button!.Button.Texture = HandTexture(hand.Location);
|
||||||
|
hand.Button!.SetPositionInParent(i);
|
||||||
|
_itemSlotManager.SetItemSlot(hand.Button, hand.Entity);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
_activeHandRect.Parent?.RemoveChild(_activeHandRect);
|
||||||
|
component.GetHand(component.ActiveIndex)?.Button?.AddChild(_activeHandRect);
|
||||||
|
|
||||||
|
if (hands.Length > 0)
|
||||||
|
{
|
||||||
|
_activeHandRect.SetPositionInParent(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
_leftPanel.SetPositionFirst();
|
||||||
|
_rightPanel.SetPositionLast();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void HandKeyBindDown(GUIBoundKeyEventArgs args, string handIndex)
|
private void HandKeyBindDown(GUIBoundKeyEventArgs args, string slotName)
|
||||||
{
|
{
|
||||||
if (!TryGetHands(out var hands))
|
if (!TryGetHands(out var hands))
|
||||||
|
{
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if (args.Function == ContentKeyFunctions.MouseMiddle)
|
if (args.Function == ContentKeyFunctions.MouseMiddle)
|
||||||
{
|
{
|
||||||
hands.SendChangeHand(handIndex);
|
hands.SendChangeHand(slotName);
|
||||||
args.Handle();
|
args.Handle();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
var entity = hands.GetEntity(handIndex);
|
var entity = hands.GetEntity(slotName);
|
||||||
if (entity == null)
|
if (entity == null)
|
||||||
{
|
{
|
||||||
if (args.Function == EngineKeyFunctions.UIClick && hands.ActiveIndex != handIndex)
|
if (args.Function == EngineKeyFunctions.UIClick && hands.ActiveIndex != slotName)
|
||||||
{
|
{
|
||||||
hands.SendChangeHand(handIndex);
|
hands.SendChangeHand(slotName);
|
||||||
args.Handle();
|
args.Handle();
|
||||||
}
|
}
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -148,37 +235,131 @@ namespace Content.Client.UserInterface
|
|||||||
|
|
||||||
if (args.Function == EngineKeyFunctions.UIClick)
|
if (args.Function == EngineKeyFunctions.UIClick)
|
||||||
{
|
{
|
||||||
if (hands.ActiveIndex == handIndex)
|
if (hands.ActiveIndex == slotName)
|
||||||
{
|
{
|
||||||
hands.UseActiveHand();
|
hands.UseActiveHand();
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
hands.AttackByInHand(handIndex);
|
hands.AttackByInHand(slotName);
|
||||||
}
|
}
|
||||||
|
|
||||||
args.Handle();
|
args.Handle();
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void _OnStoragePressed(GUIBoundKeyEventArgs args, string handIndex)
|
private void _OnStoragePressed(GUIBoundKeyEventArgs args, string handIndex)
|
||||||
{
|
{
|
||||||
if (args.Function != EngineKeyFunctions.UIClick)
|
if (args.Function != EngineKeyFunctions.UIClick || !TryGetHands(out var hands))
|
||||||
return;
|
{
|
||||||
if (!TryGetHands(out var hands))
|
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
hands.ActivateItemInHand(handIndex);
|
hands.ActivateItemInHand(handIndex);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void UpdatePanels()
|
||||||
|
{
|
||||||
|
if (!TryGetHands(out var component))
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
foreach (var hand in component.Hands)
|
||||||
|
{
|
||||||
|
_itemSlotManager.UpdateCooldown(hand.Button, hand.Entity);
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (component.Hands.Count)
|
||||||
|
{
|
||||||
|
case var n when n == 0 && _lastHands != 0:
|
||||||
|
_guiContainer.Visible = false;
|
||||||
|
|
||||||
|
_topPanel.Update(null);
|
||||||
|
_leftPanel.Update(null);
|
||||||
|
_rightPanel.Update(null);
|
||||||
|
|
||||||
|
break;
|
||||||
|
case 1:
|
||||||
|
if (_lastHands != 1)
|
||||||
|
{
|
||||||
|
_guiContainer.Visible = true;
|
||||||
|
|
||||||
|
_topPanel.Update(null);
|
||||||
|
_topPanel.Visible = false;
|
||||||
|
|
||||||
|
_leftPanel.Update(null);
|
||||||
|
_leftPanel.Visible = false;
|
||||||
|
|
||||||
|
_rightPanel.Visible = true;
|
||||||
|
|
||||||
|
if (!_guiContainer.Children.Contains(_rightPanel))
|
||||||
|
{
|
||||||
|
_rightPanel.AddChild(_rightPanel);
|
||||||
|
_rightPanel.SetPositionFirst();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
_rightPanel.Update(component.Hands[0].Entity);
|
||||||
|
|
||||||
|
break;
|
||||||
|
case 2:
|
||||||
|
if (_lastHands != 2)
|
||||||
|
{
|
||||||
|
_guiContainer.Visible = true;
|
||||||
|
_topPanel.Update(null);
|
||||||
|
_topPanel.Visible = false;
|
||||||
|
|
||||||
|
_leftPanel.Visible = true;
|
||||||
|
_rightPanel.Visible = true;
|
||||||
|
|
||||||
|
if (_handsColumn.Children.Contains(_topPanel))
|
||||||
|
{
|
||||||
|
_handsColumn.RemoveChild(_topPanel);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
_leftPanel.Update(component.Hands[0].Entity);
|
||||||
|
_rightPanel.Update(component.Hands[1].Entity);
|
||||||
|
|
||||||
|
// Order is left, right
|
||||||
|
foreach (var hand in component.Hands)
|
||||||
|
{
|
||||||
|
var tooltip = GetItemPanel(hand);
|
||||||
|
tooltip.Update(hand.Entity);
|
||||||
|
}
|
||||||
|
|
||||||
|
break;
|
||||||
|
case var n when n > 2:
|
||||||
|
if (_lastHands <= 2)
|
||||||
|
{
|
||||||
|
_guiContainer.Visible = true;
|
||||||
|
|
||||||
|
_topPanel.Visible = true;
|
||||||
|
_leftPanel.Visible = false;
|
||||||
|
_rightPanel.Visible = false;
|
||||||
|
|
||||||
|
if (!_handsColumn.Children.Contains(_topPanel))
|
||||||
|
{
|
||||||
|
_handsColumn.AddChild(_topPanel);
|
||||||
|
_topPanel.SetPositionFirst();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
_topPanel.Update(component.ActiveHand);
|
||||||
|
_leftPanel.Update(null);
|
||||||
|
_rightPanel.Update(null);
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
_lastHands = component.Hands.Count;
|
||||||
|
}
|
||||||
|
|
||||||
protected override void FrameUpdate(FrameEventArgs args)
|
protected override void FrameUpdate(FrameEventArgs args)
|
||||||
{
|
{
|
||||||
base.FrameUpdate(args);
|
base.FrameUpdate(args);
|
||||||
|
UpdatePanels();
|
||||||
_itemSlotManager.UpdateCooldown(_leftButton, _leftHand);
|
|
||||||
_itemSlotManager.UpdateCooldown(_rightButton, _rightHand);
|
|
||||||
|
|
||||||
_rightStatusPanel.Update(_rightHand);
|
|
||||||
_leftStatusPanel.Update(_leftHand);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,15 +1,14 @@
|
|||||||
using System;
|
using System;
|
||||||
using Content.Client.UserInterface;
|
using Content.Shared.GameObjects.Components.Items;
|
||||||
using Content.Shared.Input;
|
|
||||||
using Robust.Client.Graphics;
|
using Robust.Client.Graphics;
|
||||||
using Robust.Client.UserInterface;
|
using Robust.Client.UserInterface;
|
||||||
using Robust.Client.UserInterface.Controls;
|
using Robust.Client.UserInterface.Controls;
|
||||||
using Robust.Shared.Input;
|
using Robust.Shared.Input;
|
||||||
using Robust.Shared.Maths;
|
using Robust.Shared.Maths;
|
||||||
|
|
||||||
namespace Content.Client.GameObjects
|
namespace Content.Client.UserInterface
|
||||||
{
|
{
|
||||||
public sealed class ItemSlotButton : MarginContainer
|
public class ItemSlotButton : MarginContainer
|
||||||
{
|
{
|
||||||
public TextureRect Button { get; }
|
public TextureRect Button { get; }
|
||||||
public SpriteView SpriteView { get; }
|
public SpriteView SpriteView { get; }
|
||||||
|
|||||||
@@ -1,7 +1,11 @@
|
|||||||
|
#nullable enable
|
||||||
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using Content.Client.GameObjects.Components;
|
using Content.Client.GameObjects.Components;
|
||||||
using Content.Client.UserInterface.Stylesheets;
|
using Content.Client.UserInterface.Stylesheets;
|
||||||
using Content.Client.Utility;
|
using Content.Client.Utility;
|
||||||
|
using Content.Shared.GameObjects.Components.Items;
|
||||||
|
using Robust.Client.Graphics;
|
||||||
using Robust.Client.Graphics.Drawing;
|
using Robust.Client.Graphics.Drawing;
|
||||||
using Robust.Client.UserInterface;
|
using Robust.Client.UserInterface;
|
||||||
using Robust.Client.UserInterface.Controls;
|
using Robust.Client.UserInterface.Controls;
|
||||||
@@ -26,22 +30,17 @@ namespace Content.Client.UserInterface
|
|||||||
private readonly PanelContainer _panel;
|
private readonly PanelContainer _panel;
|
||||||
|
|
||||||
[ViewVariables]
|
[ViewVariables]
|
||||||
private IEntity _entity;
|
private IEntity? _entity;
|
||||||
|
|
||||||
public ItemStatusPanel(bool isRightHand)
|
public ItemStatusPanel(Texture texture, StyleBox.Margin margin)
|
||||||
{
|
{
|
||||||
// isRightHand means on the LEFT of the screen.
|
|
||||||
// Keep that in mind.
|
|
||||||
var panel = new StyleBoxTexture
|
var panel = new StyleBoxTexture
|
||||||
{
|
{
|
||||||
Texture = ResC.GetTexture(isRightHand
|
Texture = texture
|
||||||
? "/Textures/Interface/Nano/item_status_right.svg.96dpi.png"
|
|
||||||
: "/Textures/Interface/Nano/item_status_left.svg.96dpi.png")
|
|
||||||
};
|
};
|
||||||
panel.SetContentMarginOverride(StyleBox.Margin.Vertical, 4);
|
panel.SetContentMarginOverride(StyleBox.Margin.Vertical, 4);
|
||||||
panel.SetContentMarginOverride(StyleBox.Margin.Horizontal, 6);
|
panel.SetContentMarginOverride(StyleBox.Margin.Horizontal, 6);
|
||||||
panel.SetPatchMargin((isRightHand ? StyleBox.Margin.Left : StyleBox.Margin.Right) | StyleBox.Margin.Top,
|
panel.SetPatchMargin(margin, 13);
|
||||||
13);
|
|
||||||
|
|
||||||
AddChild(_panel = new PanelContainer
|
AddChild(_panel = new PanelContainer
|
||||||
{
|
{
|
||||||
@@ -67,7 +66,42 @@ namespace Content.Client.UserInterface
|
|||||||
SizeFlagsVertical = SizeFlags.ShrinkEnd;
|
SizeFlagsVertical = SizeFlags.ShrinkEnd;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Update(IEntity entity)
|
/// <summary>
|
||||||
|
/// Creates a new instance of <see cref="ItemStatusPanel"/>
|
||||||
|
/// based on whether or not it is being created for the right
|
||||||
|
/// or left hand.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="location">
|
||||||
|
/// The location of the hand that this panel is for
|
||||||
|
/// </param>
|
||||||
|
/// <returns>the new <see cref="ItemStatusPanel"/> instance</returns>
|
||||||
|
public static ItemStatusPanel FromSide(HandLocation location)
|
||||||
|
{
|
||||||
|
string texture;
|
||||||
|
StyleBox.Margin margin;
|
||||||
|
|
||||||
|
switch (location)
|
||||||
|
{
|
||||||
|
case HandLocation.Left:
|
||||||
|
texture = "/Textures/Interface/Nano/item_status_right.svg.96dpi.png";
|
||||||
|
margin = StyleBox.Margin.Left | StyleBox.Margin.Top;
|
||||||
|
break;
|
||||||
|
case HandLocation.Middle:
|
||||||
|
texture = "/Textures/Interface/Nano/item_status_left.svg.96dpi.png";
|
||||||
|
margin = StyleBox.Margin.Right | StyleBox.Margin.Top;
|
||||||
|
break;
|
||||||
|
case HandLocation.Right:
|
||||||
|
texture = "/Textures/Interface/Nano/item_status_left.svg.96dpi.png";
|
||||||
|
margin = StyleBox.Margin.Right | StyleBox.Margin.Top;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
throw new ArgumentOutOfRangeException(nameof(location), location, null);
|
||||||
|
}
|
||||||
|
|
||||||
|
return new ItemStatusPanel(ResC.GetTexture(texture), margin);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Update(IEntity? entity)
|
||||||
{
|
{
|
||||||
if (entity == null)
|
if (entity == null)
|
||||||
{
|
{
|
||||||
@@ -105,7 +139,7 @@ namespace Content.Client.UserInterface
|
|||||||
|
|
||||||
ClearOldStatus();
|
ClearOldStatus();
|
||||||
|
|
||||||
foreach (var statusComponent in _entity.GetAllComponents<IItemStatus>())
|
foreach (var statusComponent in _entity!.GetAllComponents<IItemStatus>())
|
||||||
{
|
{
|
||||||
var control = statusComponent.MakeControl();
|
var control = statusComponent.MakeControl();
|
||||||
_statusContents.AddChild(control);
|
_statusContents.AddChild(control);
|
||||||
@@ -114,9 +148,10 @@ namespace Content.Client.UserInterface
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TODO: Depending on if its a two-hand panel or not
|
||||||
protected override Vector2 CalculateMinimumSize()
|
protected override Vector2 CalculateMinimumSize()
|
||||||
{
|
{
|
||||||
return Vector2.ComponentMax(base.CalculateMinimumSize(), (150, 00));
|
return Vector2.ComponentMax(base.CalculateMinimumSize(), (150, 0));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
using Content.Server.GameObjects;
|
using Content.Server.GameObjects;
|
||||||
|
using Content.Server.GameObjects.Components.GUI;
|
||||||
using Content.Server.GameObjects.Components.Mobs;
|
using Content.Server.GameObjects.Components.Mobs;
|
||||||
using Content.Server.GameObjects.Components.Weapon.Melee;
|
using Content.Server.GameObjects.Components.Weapon.Melee;
|
||||||
using Content.Server.GameObjects.EntitySystems;
|
using Content.Server.GameObjects.EntitySystems;
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
using Content.Server.GameObjects;
|
using Content.Server.GameObjects;
|
||||||
|
using Content.Server.GameObjects.Components.GUI;
|
||||||
using Robust.Shared.Interfaces.GameObjects;
|
using Robust.Shared.Interfaces.GameObjects;
|
||||||
using Robust.Shared.Log;
|
using Robust.Shared.Log;
|
||||||
|
|
||||||
@@ -21,7 +22,8 @@ namespace Content.Server.AI.Operators.Inventory
|
|||||||
/// <returns></returns>
|
/// <returns></returns>
|
||||||
public override Outcome Execute(float frameTime)
|
public override Outcome Execute(float frameTime)
|
||||||
{
|
{
|
||||||
if (!_owner.TryGetComponent(out HandsComponent handsComponent) || handsComponent.FindHand(_entity) == null)
|
if (!_owner.TryGetComponent(out HandsComponent handsComponent) ||
|
||||||
|
!handsComponent.TryHand(_entity, out _))
|
||||||
{
|
{
|
||||||
return Outcome.Failed;
|
return Outcome.Failed;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
using Content.Server.GameObjects;
|
using Content.Server.GameObjects;
|
||||||
|
using Content.Server.GameObjects.Components.GUI;
|
||||||
using Robust.Shared.Interfaces.GameObjects;
|
using Robust.Shared.Interfaces.GameObjects;
|
||||||
|
|
||||||
namespace Content.Server.AI.Operators.Inventory
|
namespace Content.Server.AI.Operators.Inventory
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
using Content.Server.GameObjects;
|
using Content.Server.GameObjects;
|
||||||
|
using Content.Server.GameObjects.Components.GUI;
|
||||||
using Robust.Shared.Interfaces.GameObjects;
|
using Robust.Shared.Interfaces.GameObjects;
|
||||||
|
|
||||||
namespace Content.Server.AI.Operators.Inventory
|
namespace Content.Server.AI.Operators.Inventory
|
||||||
@@ -22,9 +23,9 @@ namespace Content.Server.AI.Operators.Inventory
|
|||||||
// TODO: If in clothing then click on it
|
// TODO: If in clothing then click on it
|
||||||
foreach (var hand in handsComponent.ActivePriorityEnumerable())
|
foreach (var hand in handsComponent.ActivePriorityEnumerable())
|
||||||
{
|
{
|
||||||
if (handsComponent.GetHand(hand)?.Owner == _entity)
|
if (handsComponent.GetItem(hand)?.Owner == _entity)
|
||||||
{
|
{
|
||||||
handsComponent.ActiveIndex = hand;
|
handsComponent.ActiveHand = hand;
|
||||||
return Outcome.Success;
|
return Outcome.Success;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
using Content.Server.GameObjects;
|
|
||||||
using Content.Server.GameObjects.Components;
|
using Content.Server.GameObjects.Components;
|
||||||
|
using Content.Server.GameObjects.Components.GUI;
|
||||||
using Content.Server.GameObjects.EntitySystems.Click;
|
using Content.Server.GameObjects.EntitySystems.Click;
|
||||||
using Content.Server.Utility;
|
using Content.Server.Utility;
|
||||||
using Robust.Shared.Containers;
|
using Robust.Shared.Containers;
|
||||||
@@ -41,11 +41,11 @@ namespace Content.Server.AI.Operators.Inventory
|
|||||||
|
|
||||||
foreach (var hand in handsComponent.ActivePriorityEnumerable())
|
foreach (var hand in handsComponent.ActivePriorityEnumerable())
|
||||||
{
|
{
|
||||||
if (handsComponent.GetHand(hand) == null)
|
if (handsComponent.GetItem(hand) == null)
|
||||||
{
|
{
|
||||||
if (handsComponent.ActiveIndex != hand)
|
if (handsComponent.ActiveHand != hand)
|
||||||
{
|
{
|
||||||
handsComponent.ActiveIndex = hand;
|
handsComponent.ActiveHand = hand;
|
||||||
}
|
}
|
||||||
|
|
||||||
emptyHands = true;
|
emptyHands = true;
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
using Content.Server.GameObjects;
|
|
||||||
using Content.Server.GameObjects.Components;
|
using Content.Server.GameObjects.Components;
|
||||||
|
using Content.Server.GameObjects.Components.GUI;
|
||||||
using Robust.Shared.Interfaces.GameObjects;
|
using Robust.Shared.Interfaces.GameObjects;
|
||||||
|
|
||||||
namespace Content.Server.AI.Operators.Inventory
|
namespace Content.Server.AI.Operators.Inventory
|
||||||
@@ -38,8 +38,8 @@ namespace Content.Server.AI.Operators.Inventory
|
|||||||
|
|
||||||
foreach (var slot in handsComponent.ActivePriorityEnumerable())
|
foreach (var slot in handsComponent.ActivePriorityEnumerable())
|
||||||
{
|
{
|
||||||
if (handsComponent.GetHand(slot) != itemComponent) continue;
|
if (handsComponent.GetItem(slot) != itemComponent) continue;
|
||||||
handsComponent.ActiveIndex = slot;
|
handsComponent.ActiveHand = slot;
|
||||||
handsComponent.ActivateItem();
|
handsComponent.ActivateItem();
|
||||||
return Outcome.Success;
|
return Outcome.Success;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
using Content.Server.AI.WorldState;
|
using Content.Server.AI.WorldState;
|
||||||
using Content.Server.AI.WorldState.States;
|
using Content.Server.AI.WorldState.States;
|
||||||
using Content.Server.GameObjects;
|
using Content.Server.GameObjects;
|
||||||
|
using Content.Server.GameObjects.Components.GUI;
|
||||||
|
|
||||||
namespace Content.Server.AI.Utility.Considerations.Hands
|
namespace Content.Server.AI.Utility.Considerations.Hands
|
||||||
{
|
{
|
||||||
@@ -21,7 +22,7 @@ namespace Content.Server.AI.Utility.Considerations.Hands
|
|||||||
foreach (var hand in handsComponent.ActivePriorityEnumerable())
|
foreach (var hand in handsComponent.ActivePriorityEnumerable())
|
||||||
{
|
{
|
||||||
handCount++;
|
handCount++;
|
||||||
if (handsComponent.GetHand(hand) == null)
|
if (handsComponent.GetItem(hand) == null)
|
||||||
{
|
{
|
||||||
freeCount += 1;
|
freeCount += 1;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
using Content.Server.AI.WorldState;
|
using Content.Server.AI.WorldState;
|
||||||
using Content.Server.AI.WorldState.States;
|
using Content.Server.AI.WorldState.States;
|
||||||
using Content.Server.GameObjects;
|
|
||||||
using Content.Server.GameObjects.Components;
|
using Content.Server.GameObjects.Components;
|
||||||
|
using Content.Server.GameObjects.Components.GUI;
|
||||||
|
|
||||||
namespace Content.Server.AI.Utility.Considerations.Hands
|
namespace Content.Server.AI.Utility.Considerations.Hands
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
using Content.Server.GameObjects;
|
using Content.Server.GameObjects;
|
||||||
|
using Content.Server.GameObjects.Components.GUI;
|
||||||
using JetBrains.Annotations;
|
using JetBrains.Annotations;
|
||||||
|
|
||||||
namespace Content.Server.AI.WorldState.States.Hands
|
namespace Content.Server.AI.WorldState.States.Hands
|
||||||
@@ -16,7 +17,7 @@ namespace Content.Server.AI.WorldState.States.Hands
|
|||||||
|
|
||||||
foreach (var hand in handsComponent.ActivePriorityEnumerable())
|
foreach (var hand in handsComponent.ActivePriorityEnumerable())
|
||||||
{
|
{
|
||||||
if (handsComponent.GetHand(hand) == null)
|
if (handsComponent.GetItem(hand) == null)
|
||||||
{
|
{
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using Content.Server.GameObjects;
|
using Content.Server.GameObjects;
|
||||||
|
using Content.Server.GameObjects.Components.GUI;
|
||||||
using JetBrains.Annotations;
|
using JetBrains.Annotations;
|
||||||
|
|
||||||
namespace Content.Server.AI.WorldState.States.Hands
|
namespace Content.Server.AI.WorldState.States.Hands
|
||||||
@@ -20,7 +21,7 @@ namespace Content.Server.AI.WorldState.States.Hands
|
|||||||
|
|
||||||
foreach (var hand in handsComponent.ActivePriorityEnumerable())
|
foreach (var hand in handsComponent.ActivePriorityEnumerable())
|
||||||
{
|
{
|
||||||
if (handsComponent.GetHand(hand) == null)
|
if (handsComponent.GetItem(hand) == null)
|
||||||
{
|
{
|
||||||
result.Add(hand);
|
result.Add(hand);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using Content.Server.GameObjects;
|
using Content.Server.GameObjects;
|
||||||
|
using Content.Server.GameObjects.Components.GUI;
|
||||||
using JetBrains.Annotations;
|
using JetBrains.Annotations;
|
||||||
using Robust.Shared.Interfaces.GameObjects;
|
using Robust.Shared.Interfaces.GameObjects;
|
||||||
|
|
||||||
@@ -19,7 +20,7 @@ namespace Content.Server.AI.WorldState.States.Hands
|
|||||||
|
|
||||||
foreach (var hand in handsComponent.ActivePriorityEnumerable())
|
foreach (var hand in handsComponent.ActivePriorityEnumerable())
|
||||||
{
|
{
|
||||||
var item = handsComponent.GetHand(hand);
|
var item = handsComponent.GetItem(hand);
|
||||||
|
|
||||||
if (item != null)
|
if (item != null)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
using Content.Server.GameObjects;
|
using Content.Server.GameObjects;
|
||||||
|
using Content.Server.GameObjects.Components.GUI;
|
||||||
using JetBrains.Annotations;
|
using JetBrains.Annotations;
|
||||||
using Robust.Shared.Interfaces.GameObjects;
|
using Robust.Shared.Interfaces.GameObjects;
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using Content.Server.GameObjects;
|
using Content.Server.GameObjects;
|
||||||
|
using Content.Server.GameObjects.Components.GUI;
|
||||||
using JetBrains.Annotations;
|
using JetBrains.Annotations;
|
||||||
using Robust.Shared.Interfaces.GameObjects;
|
using Robust.Shared.Interfaces.GameObjects;
|
||||||
|
|
||||||
|
|||||||
@@ -4,7 +4,6 @@ using Content.Server.Interfaces.Chat;
|
|||||||
using Content.Server.Interfaces.GameObjects;
|
using Content.Server.Interfaces.GameObjects;
|
||||||
using Content.Server.Players;
|
using Content.Server.Players;
|
||||||
using Content.Shared.GameObjects;
|
using Content.Shared.GameObjects;
|
||||||
using Robust.Server.Console;
|
|
||||||
using Robust.Server.Interfaces.Console;
|
using Robust.Server.Interfaces.Console;
|
||||||
using Robust.Server.Interfaces.Player;
|
using Robust.Server.Interfaces.Player;
|
||||||
using Robust.Shared.Enums;
|
using Robust.Shared.Enums;
|
||||||
@@ -13,6 +12,7 @@ using Robust.Shared.IoC;
|
|||||||
using Robust.Shared.Localization;
|
using Robust.Shared.Localization;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using Content.Server.GameObjects.Components;
|
using Content.Server.GameObjects.Components;
|
||||||
|
using Content.Server.GameObjects.Components.GUI;
|
||||||
|
|
||||||
namespace Content.Server.Chat
|
namespace Content.Server.Chat
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -5,6 +5,7 @@ using System.Linq;
|
|||||||
using Content.Server.GameObjects.Components.Items.Storage;
|
using Content.Server.GameObjects.Components.Items.Storage;
|
||||||
using Content.Server.Interfaces;
|
using Content.Server.Interfaces;
|
||||||
using Content.Server.Interfaces.GameObjects;
|
using Content.Server.Interfaces.GameObjects;
|
||||||
|
using Content.Server.Interfaces.GameObjects.Components.Items;
|
||||||
using Content.Shared.GameObjects.Components.Inventory;
|
using Content.Shared.GameObjects.Components.Inventory;
|
||||||
using JetBrains.Annotations;
|
using JetBrains.Annotations;
|
||||||
using Robust.Shared.GameObjects;
|
using Robust.Shared.GameObjects;
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using Content.Server.Interfaces;
|
using Content.Server.Interfaces;
|
||||||
using Content.Server.Interfaces.GameObjects;
|
using Content.Server.Interfaces.GameObjects.Components.Items;
|
||||||
using Content.Shared.Access;
|
using Content.Shared.Access;
|
||||||
using Content.Shared.GameObjects.Components.Access;
|
using Content.Shared.GameObjects.Components.Access;
|
||||||
using Content.Shared.Interfaces.GameObjects.Components;
|
using Content.Shared.Interfaces.GameObjects.Components;
|
||||||
@@ -132,7 +132,7 @@ namespace Content.Server.GameObjects.Components.Access
|
|||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if(!hands.Drop(hands.ActiveIndex, container))
|
if(!hands.Drop(hands.ActiveHand, container))
|
||||||
{
|
{
|
||||||
_notifyManager.PopupMessage(Owner.Transform.GridPosition, user, _localizationManager.GetString("You can't let go of the ID card!"));
|
_notifyManager.PopupMessage(Owner.Transform.GridPosition, user, _localizationManager.GetString("You can't let go of the ID card!"));
|
||||||
return;
|
return;
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
#nullable enable
|
#nullable enable
|
||||||
using System;
|
using System;
|
||||||
|
using Content.Server.GameObjects.Components.GUI;
|
||||||
using Content.Server.GameObjects.Components.Mobs;
|
using Content.Server.GameObjects.Components.Mobs;
|
||||||
using Content.Server.GameObjects.Components.Strap;
|
using Content.Server.GameObjects.Components.Strap;
|
||||||
using Content.Server.GameObjects.EntitySystems;
|
using Content.Server.GameObjects.EntitySystems;
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
|
using Content.Server.GameObjects.Components.GUI;
|
||||||
using Content.Server.Interfaces.GameObjects.Components.Interaction;
|
using Content.Server.Interfaces.GameObjects.Components.Interaction;
|
||||||
using Content.Server.Interfaces;
|
using Content.Server.Interfaces;
|
||||||
using Content.Server.Interfaces.GameObjects;
|
using Content.Server.Interfaces.GameObjects;
|
||||||
@@ -19,6 +20,7 @@ using Robust.Shared.ViewVariables;
|
|||||||
using Robust.Server.GameObjects.EntitySystems;
|
using Robust.Server.GameObjects.EntitySystems;
|
||||||
using Robust.Shared.GameObjects.Systems;
|
using Robust.Shared.GameObjects.Systems;
|
||||||
using Content.Server.GameObjects.Components.Power.ApcNetComponents;
|
using Content.Server.GameObjects.Components.Power.ApcNetComponents;
|
||||||
|
using Content.Server.Interfaces.GameObjects.Components.Items;
|
||||||
using Content.Shared.Interfaces.GameObjects.Components;
|
using Content.Shared.Interfaces.GameObjects.Components;
|
||||||
using Robust.Shared.Interfaces.Random;
|
using Robust.Shared.Interfaces.Random;
|
||||||
using Robust.Shared.Maths;
|
using Robust.Shared.Maths;
|
||||||
|
|||||||
@@ -1,8 +1,8 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
|
using Content.Server.GameObjects.Components.GUI;
|
||||||
using Content.Server.Interfaces.GameObjects.Components.Interaction;
|
using Content.Server.Interfaces.GameObjects.Components.Interaction;
|
||||||
using Content.Server.Interfaces;
|
using Content.Server.Interfaces;
|
||||||
using Content.Server.Interfaces.GameObjects;
|
|
||||||
using Content.Shared.Chemistry;
|
using Content.Shared.Chemistry;
|
||||||
using Content.Shared.GameObjects.Components.Chemistry;
|
using Content.Shared.GameObjects.Components.Chemistry;
|
||||||
using Content.Shared.GameObjects.EntitySystems;
|
using Content.Shared.GameObjects.EntitySystems;
|
||||||
@@ -21,6 +21,7 @@ using Robust.Server.GameObjects.EntitySystems;
|
|||||||
using Robust.Shared.GameObjects.Systems;
|
using Robust.Shared.GameObjects.Systems;
|
||||||
using Content.Server.GameObjects.Components.Power.ApcNetComponents;
|
using Content.Server.GameObjects.Components.Power.ApcNetComponents;
|
||||||
using Content.Shared.Interfaces.GameObjects.Components;
|
using Content.Shared.Interfaces.GameObjects.Components;
|
||||||
|
using Content.Server.Interfaces.GameObjects.Components.Items;
|
||||||
|
|
||||||
namespace Content.Server.GameObjects.Components.Chemistry
|
namespace Content.Server.GameObjects.Components.Chemistry
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -17,6 +17,7 @@ using Robust.Shared.Utility;
|
|||||||
using Robust.Shared.ViewVariables;
|
using Robust.Shared.ViewVariables;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
|
using Content.Server.GameObjects.Components.GUI;
|
||||||
using Content.Shared.GameObjects.EntitySystems;
|
using Content.Shared.GameObjects.EntitySystems;
|
||||||
using Robust.Shared.GameObjects.Systems;
|
using Robust.Shared.GameObjects.Systems;
|
||||||
using Content.Server.GameObjects.EntitySystems.Click;
|
using Content.Server.GameObjects.EntitySystems.Click;
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using Content.Server.GameObjects.Components.Access;
|
using Content.Server.GameObjects.Components.Access;
|
||||||
|
using Content.Server.GameObjects.Components.GUI;
|
||||||
using Content.Server.GameObjects.Components.Mobs;
|
using Content.Server.GameObjects.Components.Mobs;
|
||||||
using Content.Server.Interfaces.GameObjects;
|
using Content.Server.Interfaces.GameObjects;
|
||||||
using Content.Shared.GameObjects.Components.Doors;
|
using Content.Shared.GameObjects.Components.Doors;
|
||||||
|
|||||||
@@ -1,10 +1,13 @@
|
|||||||
using System;
|
#nullable enable
|
||||||
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
using System.Diagnostics.CodeAnalysis;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using Content.Server.GameObjects.Components;
|
using Content.Server.Interfaces.GameObjects.Components.Items;
|
||||||
|
using Content.Shared.GameObjects.Components.Items;
|
||||||
using Content.Server.GameObjects.EntitySystems.Click;
|
using Content.Server.GameObjects.EntitySystems.Click;
|
||||||
using Content.Server.Interfaces.GameObjects;
|
using Content.Server.Interfaces.GameObjects.Components.Interaction;
|
||||||
using Content.Shared.GameObjects;
|
using Content.Shared.BodySystem;
|
||||||
using Robust.Server.GameObjects;
|
using Robust.Server.GameObjects;
|
||||||
using Robust.Server.GameObjects.Components.Container;
|
using Robust.Server.GameObjects.Components.Container;
|
||||||
using Robust.Server.GameObjects.EntitySystemMessages;
|
using Robust.Server.GameObjects.EntitySystemMessages;
|
||||||
@@ -18,72 +21,67 @@ using Robust.Shared.Log;
|
|||||||
using Robust.Shared.Map;
|
using Robust.Shared.Map;
|
||||||
using Robust.Shared.Maths;
|
using Robust.Shared.Maths;
|
||||||
using Robust.Shared.Players;
|
using Robust.Shared.Players;
|
||||||
using Robust.Shared.Serialization;
|
|
||||||
using Robust.Shared.ViewVariables;
|
using Robust.Shared.ViewVariables;
|
||||||
|
|
||||||
namespace Content.Server.GameObjects
|
namespace Content.Server.GameObjects.Components.GUI
|
||||||
{
|
{
|
||||||
[RegisterComponent]
|
[RegisterComponent]
|
||||||
[ComponentReference(typeof(IHandsComponent))]
|
[ComponentReference(typeof(IHandsComponent))]
|
||||||
public class HandsComponent : SharedHandsComponent, IHandsComponent
|
public class HandsComponent : SharedHandsComponent, IHandsComponent, IBodyPartAdded, IBodyPartRemoved
|
||||||
{
|
{
|
||||||
#pragma warning disable 649
|
#pragma warning disable 649
|
||||||
[Dependency] private readonly IEntitySystemManager _entitySystemManager;
|
[Dependency] private readonly IEntitySystemManager _entitySystemManager = default!;
|
||||||
#pragma warning restore 649
|
#pragma warning restore 649
|
||||||
|
|
||||||
private string _activeIndex;
|
private string? _activeHand;
|
||||||
|
private uint _nextHand;
|
||||||
|
|
||||||
[ViewVariables(VVAccess.ReadWrite)]
|
[ViewVariables(VVAccess.ReadWrite)]
|
||||||
public string ActiveIndex
|
public string? ActiveHand
|
||||||
{
|
{
|
||||||
get => _activeIndex;
|
get => _activeHand;
|
||||||
set
|
set
|
||||||
{
|
{
|
||||||
if (!_hands.ContainsKey(value))
|
if (value != null && GetHand(value) == null)
|
||||||
{
|
{
|
||||||
throw new ArgumentException($"No hand '{value}'");
|
throw new ArgumentException($"No hand '{value}'");
|
||||||
}
|
}
|
||||||
|
|
||||||
_activeIndex = value;
|
_activeHand = value;
|
||||||
Dirty();
|
Dirty();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
[ViewVariables] private readonly Dictionary<string, ContainerSlot> _hands = new Dictionary<string, ContainerSlot>();
|
[ViewVariables] private readonly List<Hand> _hands = new List<Hand>();
|
||||||
[ViewVariables] private List<string> _orderedHands = new List<string>();
|
|
||||||
|
|
||||||
// Mostly arbitrary.
|
// Mostly arbitrary.
|
||||||
public const float PickupRange = 2;
|
public const float PickupRange = 2;
|
||||||
|
|
||||||
[ViewVariables] public int Count => _orderedHands.Count;
|
[ViewVariables] public int Count => _hands.Count;
|
||||||
|
|
||||||
public override void ExposeData(ObjectSerializer serializer)
|
// TODO: This does not serialize what objects are held.
|
||||||
|
protected override void Startup()
|
||||||
{
|
{
|
||||||
base.ExposeData(serializer);
|
base.Startup();
|
||||||
|
ActiveHand = _hands.LastOrDefault()?.Name;
|
||||||
serializer.DataReadWriteFunction("hands",
|
|
||||||
new List<string>(0),
|
|
||||||
hands => hands.ForEach(AddHand),
|
|
||||||
() => _orderedHands);
|
|
||||||
serializer.DataField(ref _activeIndex, "defaultHand", _orderedHands.LastOrDefault());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public IEnumerable<ItemComponent> GetAllHeldItems()
|
public IEnumerable<ItemComponent> GetAllHeldItems()
|
||||||
{
|
{
|
||||||
foreach (var slot in _hands.Values)
|
foreach (var hand in _hands)
|
||||||
{
|
{
|
||||||
if (slot.ContainedEntity != null)
|
if (hand.Entity != null)
|
||||||
{
|
{
|
||||||
yield return slot.ContainedEntity.GetComponent<ItemComponent>();
|
yield return hand.Entity.GetComponent<ItemComponent>();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public bool IsHolding(IEntity entity)
|
public bool IsHolding(IEntity entity)
|
||||||
{
|
{
|
||||||
foreach (var slot in _hands.Values)
|
foreach (var hand in _hands)
|
||||||
{
|
{
|
||||||
if (slot.ContainedEntity == entity)
|
if (hand.Entity == entity)
|
||||||
{
|
{
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@@ -91,28 +89,38 @@ namespace Content.Server.GameObjects
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
public ItemComponent GetHand(string index)
|
private Hand? GetHand(string name)
|
||||||
{
|
{
|
||||||
var slot = _hands[index];
|
return _hands.FirstOrDefault(hand => hand.Name == name);
|
||||||
return slot.ContainedEntity?.GetComponent<ItemComponent>();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public ItemComponent GetActiveHand => GetHand(ActiveIndex);
|
public ItemComponent? GetItem(string handName)
|
||||||
|
{
|
||||||
|
return GetHand(handName)?.Entity?.GetComponent<ItemComponent>();
|
||||||
|
}
|
||||||
|
|
||||||
|
public ItemComponent? GetActiveHand => ActiveHand == null
|
||||||
|
? null
|
||||||
|
: GetItem(ActiveHand);
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Enumerates over the hand keys, returning the active hand first.
|
/// Enumerates over the hand keys, returning the active hand first.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public IEnumerable<string> ActivePriorityEnumerable()
|
public IEnumerable<string> ActivePriorityEnumerable()
|
||||||
{
|
{
|
||||||
yield return ActiveIndex;
|
if (ActiveHand != null)
|
||||||
foreach (var hand in _hands.Keys)
|
|
||||||
{
|
{
|
||||||
if (hand == ActiveIndex)
|
yield return ActiveHand;
|
||||||
|
}
|
||||||
|
|
||||||
|
foreach (var hand in _hands)
|
||||||
|
{
|
||||||
|
if (hand.Name == ActiveHand)
|
||||||
{
|
{
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
yield return hand;
|
yield return hand.Name;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -120,7 +128,7 @@ namespace Content.Server.GameObjects
|
|||||||
{
|
{
|
||||||
foreach (var hand in ActivePriorityEnumerable())
|
foreach (var hand in ActivePriorityEnumerable())
|
||||||
{
|
{
|
||||||
if (PutInHand(item, hand, fallback: false))
|
if (PutInHand(item, hand, false))
|
||||||
{
|
{
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@@ -131,14 +139,14 @@ namespace Content.Server.GameObjects
|
|||||||
|
|
||||||
public bool PutInHand(ItemComponent item, string index, bool fallback = true)
|
public bool PutInHand(ItemComponent item, string index, bool fallback = true)
|
||||||
{
|
{
|
||||||
if (!CanPutInHand(item, index))
|
var hand = GetHand(index);
|
||||||
|
if (!CanPutInHand(item, index) || hand == null)
|
||||||
{
|
{
|
||||||
return fallback && PutInHand(item);
|
return fallback && PutInHand(item);
|
||||||
}
|
}
|
||||||
|
|
||||||
var slot = _hands[index];
|
|
||||||
Dirty();
|
Dirty();
|
||||||
var success = slot.Insert(item.Owner);
|
var success = hand.Container.Insert(item.Owner);
|
||||||
if (success)
|
if (success)
|
||||||
{
|
{
|
||||||
item.Owner.Transform.LocalPosition = Vector2.Zero;
|
item.Owner.Transform.LocalPosition = Vector2.Zero;
|
||||||
@@ -152,14 +160,16 @@ namespace Content.Server.GameObjects
|
|||||||
public void PutInHandOrDrop(ItemComponent item)
|
public void PutInHandOrDrop(ItemComponent item)
|
||||||
{
|
{
|
||||||
if (!PutInHand(item))
|
if (!PutInHand(item))
|
||||||
|
{
|
||||||
item.Owner.Transform.GridPosition = Owner.Transform.GridPosition;
|
item.Owner.Transform.GridPosition = Owner.Transform.GridPosition;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public bool CanPutInHand(ItemComponent item)
|
public bool CanPutInHand(ItemComponent item)
|
||||||
{
|
{
|
||||||
foreach (var hand in ActivePriorityEnumerable())
|
foreach (var handName in ActivePriorityEnumerable())
|
||||||
{
|
{
|
||||||
if (CanPutInHand(item, hand))
|
if (CanPutInHand(item, handName))
|
||||||
{
|
{
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@@ -170,43 +180,42 @@ namespace Content.Server.GameObjects
|
|||||||
|
|
||||||
public bool CanPutInHand(ItemComponent item, string index)
|
public bool CanPutInHand(ItemComponent item, string index)
|
||||||
{
|
{
|
||||||
var slot = _hands[index];
|
return GetHand(index)?.Container.CanInsert(item.Owner) == true;
|
||||||
return slot.CanInsert(item.Owner);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public string FindHand(IEntity entity)
|
public bool TryHand(IEntity entity, [MaybeNullWhen(false)] out string handName)
|
||||||
{
|
{
|
||||||
foreach (var (index, slot) in _hands)
|
handName = null;
|
||||||
|
|
||||||
|
foreach (var hand in _hands)
|
||||||
{
|
{
|
||||||
if (slot.ContainedEntity == entity)
|
if (hand.Entity == entity)
|
||||||
{
|
{
|
||||||
return index;
|
handName = hand.Name;
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return null;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
public bool Drop(string slot, GridCoordinates coords, bool doMobChecks = true)
|
public bool Drop(string slot, GridCoordinates coords, bool doMobChecks = true)
|
||||||
{
|
{
|
||||||
if (!CanDrop(slot))
|
var hand = GetHand(slot);
|
||||||
|
if (!CanDrop(slot) || hand?.Entity == null)
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
var inventorySlot = _hands[slot];
|
var item = hand.Entity.GetComponent<ItemComponent>();
|
||||||
var item = inventorySlot.ContainedEntity.GetComponent<ItemComponent>();
|
|
||||||
|
|
||||||
if (!inventorySlot.Remove(inventorySlot.ContainedEntity))
|
if (!hand.Container.Remove(hand.Entity))
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (doMobChecks && !_entitySystemManager.GetEntitySystem<InteractionSystem>().TryDroppedInteraction(Owner, item.Owner))
|
if (doMobChecks &&
|
||||||
return false;
|
!_entitySystemManager.GetEntitySystem<InteractionSystem>().TryDroppedInteraction(Owner, item.Owner))
|
||||||
|
|
||||||
if (ContainerHelpers.TryGetContainer(Owner, out var container) &&
|
|
||||||
!container.Insert(item.Owner))
|
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@@ -214,6 +223,11 @@ namespace Content.Server.GameObjects
|
|||||||
item.RemovedFromSlot();
|
item.RemovedFromSlot();
|
||||||
item.Owner.Transform.GridPosition = coords;
|
item.Owner.Transform.GridPosition = coords;
|
||||||
|
|
||||||
|
if (ContainerHelpers.TryGetContainer(Owner, out var container))
|
||||||
|
{
|
||||||
|
container.Insert(item.Owner);
|
||||||
|
}
|
||||||
|
|
||||||
Dirty();
|
Dirty();
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@@ -225,8 +239,7 @@ namespace Content.Server.GameObjects
|
|||||||
throw new ArgumentNullException(nameof(entity));
|
throw new ArgumentNullException(nameof(entity));
|
||||||
}
|
}
|
||||||
|
|
||||||
var slot = FindHand(entity);
|
if (!TryHand(entity, out var slot))
|
||||||
if (slot == null)
|
|
||||||
{
|
{
|
||||||
throw new ArgumentException("Entity must be held in one of our hands.", nameof(entity));
|
throw new ArgumentException("Entity must be held in one of our hands.", nameof(entity));
|
||||||
}
|
}
|
||||||
@@ -236,24 +249,21 @@ namespace Content.Server.GameObjects
|
|||||||
|
|
||||||
public bool Drop(string slot, bool doMobChecks = true)
|
public bool Drop(string slot, bool doMobChecks = true)
|
||||||
{
|
{
|
||||||
if (!CanDrop(slot))
|
var hand = GetHand(slot);
|
||||||
|
if (!CanDrop(slot) || hand?.Entity == null)
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
var inventorySlot = _hands[slot];
|
var item = hand.Entity.GetComponent<ItemComponent>();
|
||||||
var item = inventorySlot.ContainedEntity.GetComponent<ItemComponent>();
|
|
||||||
|
|
||||||
if (doMobChecks && !_entitySystemManager.GetEntitySystem<InteractionSystem>().TryDroppedInteraction(Owner, item.Owner))
|
if (doMobChecks &&
|
||||||
return false;
|
!_entitySystemManager.GetEntitySystem<InteractionSystem>().TryDroppedInteraction(Owner, item.Owner))
|
||||||
|
|
||||||
if (!inventorySlot.Remove(inventorySlot.ContainedEntity))
|
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ContainerHelpers.TryGetContainer(Owner, out var container) &&
|
if (!hand.Container.Remove(hand.Entity))
|
||||||
!container.Insert(item.Owner))
|
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@@ -266,6 +276,11 @@ namespace Content.Server.GameObjects
|
|||||||
spriteComponent.RenderOrder = item.Owner.EntityManager.CurrentTick.Value;
|
spriteComponent.RenderOrder = item.Owner.EntityManager.CurrentTick.Value;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (ContainerHelpers.TryGetContainer(Owner, out var container))
|
||||||
|
{
|
||||||
|
container.Insert(item.Owner);
|
||||||
|
}
|
||||||
|
|
||||||
Dirty();
|
Dirty();
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@@ -277,8 +292,7 @@ namespace Content.Server.GameObjects
|
|||||||
throw new ArgumentNullException(nameof(entity));
|
throw new ArgumentNullException(nameof(entity));
|
||||||
}
|
}
|
||||||
|
|
||||||
var slot = FindHand(entity);
|
if (!TryHand(entity, out var slot))
|
||||||
if (slot == null)
|
|
||||||
{
|
{
|
||||||
throw new ArgumentException("Entity must be held in one of our hands.", nameof(entity));
|
throw new ArgumentException("Entity must be held in one of our hands.", nameof(entity));
|
||||||
}
|
}
|
||||||
@@ -298,31 +312,30 @@ namespace Content.Server.GameObjects
|
|||||||
throw new ArgumentNullException(nameof(targetContainer));
|
throw new ArgumentNullException(nameof(targetContainer));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!CanDrop(slot))
|
var hand = GetHand(slot);
|
||||||
|
if (!CanDrop(slot) || hand?.Entity == null)
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var item = hand.Entity.GetComponent<ItemComponent>();
|
||||||
var inventorySlot = _hands[slot];
|
|
||||||
var item = inventorySlot.ContainedEntity.GetComponent<ItemComponent>();
|
|
||||||
|
|
||||||
if (doMobChecks && !_entitySystemManager.GetEntitySystem<InteractionSystem>().TryDroppedInteraction(Owner, item.Owner))
|
if (doMobChecks && !_entitySystemManager.GetEntitySystem<InteractionSystem>().TryDroppedInteraction(Owner, item.Owner))
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!inventorySlot.CanRemove(inventorySlot.ContainedEntity))
|
if (!hand.Container.CanRemove(hand.Entity))
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!targetContainer.CanInsert(inventorySlot.ContainedEntity))
|
if (!targetContainer.CanInsert(hand.Entity))
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!inventorySlot.Remove(inventorySlot.ContainedEntity))
|
if (!hand.Container.Remove(hand.Entity))
|
||||||
{
|
{
|
||||||
throw new InvalidOperationException();
|
throw new InvalidOperationException();
|
||||||
}
|
}
|
||||||
@@ -345,8 +358,7 @@ namespace Content.Server.GameObjects
|
|||||||
throw new ArgumentNullException(nameof(entity));
|
throw new ArgumentNullException(nameof(entity));
|
||||||
}
|
}
|
||||||
|
|
||||||
var slot = FindHand(entity);
|
if (!TryHand(entity, out var slot))
|
||||||
if (slot == null)
|
|
||||||
{
|
{
|
||||||
throw new ArgumentException("Entity must be held in one of our hands.", nameof(entity));
|
throw new ArgumentException("Entity must be held in one of our hands.", nameof(entity));
|
||||||
}
|
}
|
||||||
@@ -357,94 +369,103 @@ namespace Content.Server.GameObjects
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// Checks whether an item can be dropped from the specified slot.
|
/// Checks whether an item can be dropped from the specified slot.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="slot">The slot to check for.</param>
|
/// <param name="name">The slot to check for.</param>
|
||||||
/// <returns>
|
/// <returns>
|
||||||
/// True if there is an item in the slot and it can be dropped, false otherwise.
|
/// True if there is an item in the slot and it can be dropped, false otherwise.
|
||||||
/// </returns>
|
/// </returns>
|
||||||
public bool CanDrop(string slot)
|
public bool CanDrop(string name)
|
||||||
{
|
{
|
||||||
var inventorySlot = _hands[slot];
|
var hand = GetHand(name);
|
||||||
|
if (hand?.Entity == null)
|
||||||
if (ContainerHelpers.TryGetContainer(Owner, out var container) &&
|
|
||||||
!container.CanInsert(inventorySlot.ContainedEntity))
|
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
return inventorySlot.CanRemove(inventorySlot.ContainedEntity);
|
return hand.Container.CanRemove(hand.Entity);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void AddHand(string index)
|
public void AddHand(string name)
|
||||||
{
|
{
|
||||||
if (HasHand(index))
|
if (HasHand(name))
|
||||||
{
|
{
|
||||||
throw new InvalidOperationException($"Hand '{index}' already exists.");
|
throw new InvalidOperationException($"Hand '{name}' already exists.");
|
||||||
}
|
}
|
||||||
|
|
||||||
var slot = ContainerManagerComponent.Create<ContainerSlot>(Name + "_" + index, Owner);
|
var container = ContainerManagerComponent.Create<ContainerSlot>($"hand {_nextHand++}", Owner);
|
||||||
_hands[index] = slot;
|
var hand = new Hand(name, container);
|
||||||
if (!_orderedHands.Contains(index))
|
|
||||||
{
|
_hands.Add(hand);
|
||||||
_orderedHands.Add(index);
|
|
||||||
}
|
ActiveHand ??= name;
|
||||||
|
|
||||||
ActiveIndex ??= index;
|
|
||||||
Dirty();
|
Dirty();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void RemoveHand(string index)
|
public void RemoveHand(string name)
|
||||||
{
|
{
|
||||||
if (!HasHand(index))
|
var hand = GetHand(name);
|
||||||
|
if (hand == null)
|
||||||
{
|
{
|
||||||
throw new InvalidOperationException($"Hand '{index}' does not exist.");
|
throw new InvalidOperationException($"Hand '{name}' does not exist.");
|
||||||
}
|
}
|
||||||
|
|
||||||
_hands[index].Shutdown(); //TODO verify this
|
Drop(hand.Name, false);
|
||||||
_hands.Remove(index);
|
hand!.Dispose();
|
||||||
_orderedHands.Remove(index);
|
_hands.Remove(hand);
|
||||||
|
|
||||||
if (index == ActiveIndex)
|
if (name == ActiveHand)
|
||||||
{
|
{
|
||||||
_activeIndex = _orderedHands.Count == 0 ? null : _orderedHands[0];
|
_activeHand = _hands.FirstOrDefault()?.Name;
|
||||||
}
|
}
|
||||||
|
|
||||||
Dirty();
|
Dirty();
|
||||||
}
|
}
|
||||||
|
|
||||||
public bool HasHand(string index)
|
public bool HasHand(string name)
|
||||||
{
|
{
|
||||||
return _hands.ContainsKey(index);
|
return _hands.Any(hand => hand.Name == name);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Get the name of the slot passed to the inventory component.
|
|
||||||
/// </summary>
|
|
||||||
private string HandSlotName(string index) => $"_hand_{index}";
|
|
||||||
|
|
||||||
public override ComponentState GetComponentState()
|
public override ComponentState GetComponentState()
|
||||||
{
|
{
|
||||||
var dict = new Dictionary<string, EntityUid>(_hands.Count);
|
var hands = new SharedHand[_hands.Count];
|
||||||
foreach (var hand in _hands)
|
|
||||||
|
for (var i = 0; i < _hands.Count; i++)
|
||||||
{
|
{
|
||||||
if (hand.Value.ContainedEntity != null)
|
var location = i == 0
|
||||||
{
|
? HandLocation.Right
|
||||||
dict[hand.Key] = hand.Value.ContainedEntity.Uid;
|
: i == _hands.Count - 1
|
||||||
}
|
? HandLocation.Left
|
||||||
|
: HandLocation.Middle;
|
||||||
|
|
||||||
|
var hand = _hands[i].ToShared(i, location);
|
||||||
|
hands[i] = hand;
|
||||||
}
|
}
|
||||||
|
|
||||||
return new HandsComponentState(dict, ActiveIndex);
|
return new HandsComponentState(hands, ActiveHand);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void SwapHands()
|
public void SwapHands()
|
||||||
{
|
{
|
||||||
var index = _orderedHands.FindIndex(x => x == ActiveIndex);
|
if (ActiveHand == null)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
var hand = GetHand(ActiveHand);
|
||||||
|
if (hand == null)
|
||||||
|
{
|
||||||
|
throw new InvalidOperationException($"No hand found with name {ActiveHand}");
|
||||||
|
}
|
||||||
|
|
||||||
|
var index = _hands.IndexOf(hand);
|
||||||
index++;
|
index++;
|
||||||
if (index >= _orderedHands.Count)
|
if (index == _hands.Count)
|
||||||
{
|
{
|
||||||
index = 0;
|
index = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
ActiveIndex = _orderedHands[index];
|
ActiveHand = _hands[index].Name;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void ActivateItem()
|
public void ActivateItem()
|
||||||
@@ -469,7 +490,7 @@ namespace Content.Server.GameObjects
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
public override void HandleNetworkMessage(ComponentMessage message, INetChannel channel, ICommonSession session = null)
|
public override void HandleNetworkMessage(ComponentMessage message, INetChannel channel, ICommonSession? session = null)
|
||||||
{
|
{
|
||||||
base.HandleNetworkMessage(message, channel, session);
|
base.HandleNetworkMessage(message, channel, session);
|
||||||
|
|
||||||
@@ -485,15 +506,19 @@ namespace Content.Server.GameObjects
|
|||||||
var playerEntity = session.AttachedEntity;
|
var playerEntity = session.AttachedEntity;
|
||||||
|
|
||||||
if (playerEntity == Owner && HasHand(msg.Index))
|
if (playerEntity == Owner && HasHand(msg.Index))
|
||||||
ActiveIndex = msg.Index;
|
{
|
||||||
|
ActiveHand = msg.Index;
|
||||||
|
}
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
case ClientAttackByInHandMsg msg:
|
case ClientAttackByInHandMsg msg:
|
||||||
{
|
{
|
||||||
if (!_hands.TryGetValue(msg.Index, out var slot))
|
var hand = GetHand(msg.Index);
|
||||||
|
if (hand == null)
|
||||||
{
|
{
|
||||||
Logger.WarningS("go.comp.hands", "Got a ClientAttackByInHandMsg with invalid hand index '{0}'",
|
Logger.WarningS("go.comp.hands", "Got a ClientAttackByInHandMsg with invalid hand name '{0}'",
|
||||||
msg.Index);
|
msg.Index);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -501,19 +526,22 @@ namespace Content.Server.GameObjects
|
|||||||
var playerEntity = session.AttachedEntity;
|
var playerEntity = session.AttachedEntity;
|
||||||
var used = GetActiveHand?.Owner;
|
var used = GetActiveHand?.Owner;
|
||||||
|
|
||||||
if (playerEntity == Owner && slot.ContainedEntity != null)
|
if (playerEntity == Owner && hand.Entity != null)
|
||||||
{
|
{
|
||||||
var interactionSystem = _entitySystemManager.GetEntitySystem<InteractionSystem>();
|
var interactionSystem = _entitySystemManager.GetEntitySystem<InteractionSystem>();
|
||||||
if (used != null)
|
if (used != null)
|
||||||
{
|
{
|
||||||
interactionSystem.Interaction(Owner, used, slot.ContainedEntity,
|
interactionSystem.Interaction(Owner, used, hand.Entity,
|
||||||
GridCoordinates.InvalidGrid);
|
GridCoordinates.InvalidGrid);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
var entity = slot.ContainedEntity;
|
var entity = hand.Entity;
|
||||||
if (!Drop(entity))
|
if (!Drop(entity))
|
||||||
|
{
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
interactionSystem.Interaction(Owner, entity);
|
interactionSystem.Interaction(Owner, entity);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -521,7 +549,7 @@ namespace Content.Server.GameObjects
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
case UseInHandMsg msg:
|
case UseInHandMsg _:
|
||||||
{
|
{
|
||||||
var playerEntity = session.AttachedEntity;
|
var playerEntity = session.AttachedEntity;
|
||||||
var used = GetActiveHand?.Owner;
|
var used = GetActiveHand?.Owner;
|
||||||
@@ -538,7 +566,7 @@ namespace Content.Server.GameObjects
|
|||||||
case ActivateInHandMsg msg:
|
case ActivateInHandMsg msg:
|
||||||
{
|
{
|
||||||
var playerEntity = session.AttachedEntity;
|
var playerEntity = session.AttachedEntity;
|
||||||
var used = GetHand(msg.Index)?.Owner;
|
var used = GetItem(msg.Index)?.Owner;
|
||||||
|
|
||||||
if (playerEntity == Owner && used != null)
|
if (playerEntity == Owner && used != null)
|
||||||
{
|
{
|
||||||
@@ -552,9 +580,9 @@ namespace Content.Server.GameObjects
|
|||||||
|
|
||||||
public void HandleSlotModifiedMaybe(ContainerModifiedMessage message)
|
public void HandleSlotModifiedMaybe(ContainerModifiedMessage message)
|
||||||
{
|
{
|
||||||
foreach (var container in _hands.Values)
|
foreach (var hand in _hands)
|
||||||
{
|
{
|
||||||
if (container != message.Container)
|
if (hand.Container != message.Container)
|
||||||
{
|
{
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
@@ -571,5 +599,48 @@ namespace Content.Server.GameObjects
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void IBodyPartAdded.BodyPartAdded(BodyPartAddedEventArgs eventArgs)
|
||||||
|
{
|
||||||
|
if (eventArgs.Part.PartType != BodyPartType.Hand)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
AddHand(eventArgs.SlotName);
|
||||||
|
}
|
||||||
|
|
||||||
|
void IBodyPartRemoved.BodyPartRemoved(BodyPartRemovedEventArgs eventArgs)
|
||||||
|
{
|
||||||
|
if (eventArgs.Part.PartType != BodyPartType.Hand)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
RemoveHand(eventArgs.SlotName);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public class Hand : IDisposable
|
||||||
|
{
|
||||||
|
public Hand(string name, ContainerSlot container)
|
||||||
|
{
|
||||||
|
Name = name;
|
||||||
|
Container = container;
|
||||||
|
}
|
||||||
|
|
||||||
|
public string Name { get; }
|
||||||
|
public IEntity? Entity => Container.ContainedEntity;
|
||||||
|
public ContainerSlot Container { get; }
|
||||||
|
|
||||||
|
public void Dispose()
|
||||||
|
{
|
||||||
|
Container.Shutdown(); // TODO verify this
|
||||||
|
}
|
||||||
|
|
||||||
|
public SharedHand ToShared(int index, HandLocation location)
|
||||||
|
{
|
||||||
|
return new SharedHand(index, Name, Entity?.Uid, location);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -2,6 +2,7 @@
|
|||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using Content.Server.GameObjects.Components;
|
using Content.Server.GameObjects.Components;
|
||||||
|
using Content.Server.GameObjects.Components.GUI;
|
||||||
using Content.Shared.GameObjects.Components.Inventory;
|
using Content.Shared.GameObjects.Components.Inventory;
|
||||||
using Content.Server.GameObjects.Components.Items.Storage;
|
using Content.Server.GameObjects.Components.Items.Storage;
|
||||||
using Content.Server.GameObjects.EntitySystems.Click;
|
using Content.Server.GameObjects.EntitySystems.Click;
|
||||||
@@ -326,7 +327,7 @@ namespace Content.Server.GameObjects
|
|||||||
var activeHand = hands.GetActiveHand;
|
var activeHand = hands.GetActiveHand;
|
||||||
if (activeHand != null && activeHand.Owner.TryGetComponent(out ItemComponent clothing))
|
if (activeHand != null && activeHand.Owner.TryGetComponent(out ItemComponent clothing))
|
||||||
{
|
{
|
||||||
hands.Drop(hands.ActiveIndex);
|
hands.Drop(hands.ActiveHand);
|
||||||
if (!Equip(msg.Inventoryslot, clothing, out var reason))
|
if (!Equip(msg.Inventoryslot, clothing, out var reason))
|
||||||
{
|
{
|
||||||
hands.PutInHand(clothing);
|
hands.PutInHand(clothing);
|
||||||
|
|||||||
@@ -1,10 +1,12 @@
|
|||||||
using Content.Server.GameObjects.Components.Power;
|
using Content.Server.GameObjects.Components.GUI;
|
||||||
|
using Content.Server.GameObjects.Components.Power;
|
||||||
using Content.Server.GameObjects.EntitySystems.Click;
|
using Content.Server.GameObjects.EntitySystems.Click;
|
||||||
using Content.Server.Interfaces.GameObjects;
|
using Content.Server.Interfaces.GameObjects.Components.Items;
|
||||||
using Content.Shared.GameObjects;
|
using Content.Shared.GameObjects;
|
||||||
using Content.Shared.GameObjects.Components;
|
using Content.Shared.GameObjects.Components;
|
||||||
using Content.Shared.GameObjects.EntitySystems;
|
using Content.Shared.GameObjects.EntitySystems;
|
||||||
using Content.Shared.Interfaces;
|
using Content.Shared.Interfaces;
|
||||||
|
using Content.Shared.Interfaces.GameObjects.Components;
|
||||||
using Robust.Server.GameObjects;
|
using Robust.Server.GameObjects;
|
||||||
using Robust.Server.GameObjects.Components.Container;
|
using Robust.Server.GameObjects.Components.Container;
|
||||||
using Robust.Server.GameObjects.EntitySystems;
|
using Robust.Server.GameObjects.EntitySystems;
|
||||||
@@ -16,7 +18,6 @@ using Robust.Shared.IoC;
|
|||||||
using Robust.Shared.Localization;
|
using Robust.Shared.Localization;
|
||||||
using Robust.Shared.Utility;
|
using Robust.Shared.Utility;
|
||||||
using Robust.Shared.ViewVariables;
|
using Robust.Shared.ViewVariables;
|
||||||
using Content.Shared.Interfaces.GameObjects.Components;
|
|
||||||
|
|
||||||
namespace Content.Server.GameObjects.Components.Interactable
|
namespace Content.Server.GameObjects.Components.Interactable
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using Content.Server.GameObjects.Components;
|
using Content.Server.GameObjects.Components;
|
||||||
|
using Content.Server.GameObjects.Components.GUI;
|
||||||
using Content.Server.GameObjects.Components.Items.Storage;
|
using Content.Server.GameObjects.Components.Items.Storage;
|
||||||
using Content.Server.Interfaces;
|
using Content.Server.Interfaces;
|
||||||
using Content.Shared.GameObjects;
|
using Content.Shared.GameObjects;
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
|
using Content.Server.GameObjects.Components.GUI;
|
||||||
using Content.Server.GameObjects.Components.Interactable;
|
using Content.Server.GameObjects.Components.Interactable;
|
||||||
using Content.Server.GameObjects.Components.Items.Storage;
|
using Content.Server.GameObjects.Components.Items.Storage;
|
||||||
using Content.Server.Interfaces.GameObjects.Components.Interaction;
|
using Content.Server.Interfaces.GameObjects.Components.Interaction;
|
||||||
|
|||||||
@@ -1,6 +1,8 @@
|
|||||||
using Content.Server.GameObjects.Components.Items.Storage;
|
using Content.Server.GameObjects.Components.GUI;
|
||||||
|
using Content.Server.GameObjects.Components.Items.Storage;
|
||||||
using Content.Server.Interfaces.GameObjects.Components.Interaction;
|
using Content.Server.Interfaces.GameObjects.Components.Interaction;
|
||||||
using Content.Server.Interfaces.GameObjects;
|
using Content.Server.Interfaces.GameObjects;
|
||||||
|
using Content.Server.Interfaces.GameObjects.Components.Items;
|
||||||
using Content.Server.Throw;
|
using Content.Server.Throw;
|
||||||
using Content.Server.Utility;
|
using Content.Server.Utility;
|
||||||
using Content.Shared.GameObjects;
|
using Content.Shared.GameObjects;
|
||||||
@@ -100,7 +102,7 @@ namespace Content.Server.GameObjects.Components
|
|||||||
if (!CanPickup(eventArgs.User)) return false;
|
if (!CanPickup(eventArgs.User)) return false;
|
||||||
|
|
||||||
var hands = eventArgs.User.GetComponent<IHandsComponent>();
|
var hands = eventArgs.User.GetComponent<IHandsComponent>();
|
||||||
hands.PutInHand(this, hands.ActiveIndex, fallback: false);
|
hands.PutInHand(this, hands.ActiveHand, false);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -2,8 +2,10 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
|
using Content.Server.GameObjects.Components.GUI;
|
||||||
using Content.Server.Interfaces.GameObjects;
|
using Content.Server.Interfaces.GameObjects;
|
||||||
using Content.Server.Interfaces.GameObjects.Components.Interaction;
|
using Content.Server.Interfaces.GameObjects.Components.Interaction;
|
||||||
|
using Content.Server.Interfaces.GameObjects.Components.Items;
|
||||||
using Content.Server.Utility;
|
using Content.Server.Utility;
|
||||||
using Content.Shared.GameObjects.Components.Storage;
|
using Content.Shared.GameObjects.Components.Storage;
|
||||||
using Content.Shared.GameObjects.EntitySystems;
|
using Content.Shared.GameObjects.EntitySystems;
|
||||||
|
|||||||
@@ -1,10 +1,12 @@
|
|||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
|
using Content.Server.BodySystem;
|
||||||
using Content.Server.Interfaces.GameObjects.Components.Interaction;
|
using Content.Server.Interfaces.GameObjects.Components.Interaction;
|
||||||
using Robust.Shared.GameObjects;
|
using Robust.Shared.GameObjects;
|
||||||
using Robust.Shared.IoC;
|
using Robust.Shared.IoC;
|
||||||
using Robust.Shared.ViewVariables;
|
using Robust.Shared.ViewVariables;
|
||||||
using Content.Server.GameObjects.Components.Chemistry;
|
using Content.Server.GameObjects.Components.Chemistry;
|
||||||
|
using Content.Server.GameObjects.Components.GUI;
|
||||||
using Content.Shared.Chemistry;
|
using Content.Shared.Chemistry;
|
||||||
using Robust.Shared.Serialization;
|
using Robust.Shared.Serialization;
|
||||||
using Robust.Shared.Interfaces.GameObjects;
|
using Robust.Shared.Interfaces.GameObjects;
|
||||||
@@ -22,10 +24,10 @@ using Content.Server.Interfaces;
|
|||||||
using Robust.Shared.Audio;
|
using Robust.Shared.Audio;
|
||||||
using Content.Server.Interfaces.GameObjects;
|
using Content.Server.Interfaces.GameObjects;
|
||||||
using Content.Server.Interfaces.Chat;
|
using Content.Server.Interfaces.Chat;
|
||||||
using Content.Server.BodySystem;
|
|
||||||
using Content.Shared.BodySystem;
|
using Content.Shared.BodySystem;
|
||||||
using Robust.Shared.GameObjects.Systems;
|
using Robust.Shared.GameObjects.Systems;
|
||||||
using Content.Server.GameObjects.Components.Power.ApcNetComponents;
|
using Content.Server.GameObjects.Components.Power.ApcNetComponents;
|
||||||
|
using Content.Shared.Interfaces;
|
||||||
using Content.Shared.Interfaces.GameObjects.Components;
|
using Content.Shared.Interfaces.GameObjects.Components;
|
||||||
|
|
||||||
namespace Content.Server.GameObjects.Components.Kitchen
|
namespace Content.Server.GameObjects.Components.Kitchen
|
||||||
@@ -211,9 +213,15 @@ namespace Content.Server.GameObjects.Components.Kitchen
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
var itemEntity = eventArgs.User.GetComponent<HandsComponent>().GetActiveHand.Owner;
|
var itemEntity = eventArgs.User.GetComponent<HandsComponent>().GetActiveHand?.Owner;
|
||||||
|
|
||||||
if(itemEntity.TryGetComponent<PourableComponent>(out var attackPourable))
|
if (itemEntity == null)
|
||||||
|
{
|
||||||
|
eventArgs.User.PopupMessage(eventArgs.User, Loc.GetString("You have no active hand!"));
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (itemEntity.TryGetComponent<PourableComponent>(out var attackPourable))
|
||||||
{
|
{
|
||||||
if (!itemEntity.TryGetComponent<SolutionComponent>(out var attackSolution)
|
if (!itemEntity.TryGetComponent<SolutionComponent>(out var attackSolution)
|
||||||
|| !attackSolution.CanPourOut)
|
|| !attackSolution.CanPourOut)
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using Content.Server.GameObjects.Components.Chemistry;
|
using Content.Server.GameObjects.Components.Chemistry;
|
||||||
|
using Content.Server.GameObjects.Components.GUI;
|
||||||
using Content.Server.GameObjects.Components.Utensil;
|
using Content.Server.GameObjects.Components.Utensil;
|
||||||
using Content.Server.Utility;
|
using Content.Server.Utility;
|
||||||
using Content.Shared.Chemistry;
|
using Content.Shared.Chemistry;
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
|
using Content.Server.GameObjects.Components.GUI;
|
||||||
using Content.Shared.GameObjects.Components.Nutrition;
|
using Content.Shared.GameObjects.Components.Nutrition;
|
||||||
using Content.Shared.Interfaces.GameObjects.Components;
|
using Content.Shared.Interfaces.GameObjects.Components;
|
||||||
using Robust.Server.GameObjects;
|
using Robust.Server.GameObjects;
|
||||||
@@ -54,8 +55,11 @@ namespace Content.Server.GameObjects.Components.Nutrition
|
|||||||
|
|
||||||
bool IUse.UseEntity(UseEntityEventArgs eventArgs)
|
bool IUse.UseEntity(UseEntityEventArgs eventArgs)
|
||||||
{
|
{
|
||||||
|
if (!eventArgs.User.TryGetComponent(out HandsComponent handsComponent))
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
var hands = eventArgs.User.TryGetComponent(out HandsComponent handsComponent);
|
|
||||||
var itemToSpawn = _entityManager.SpawnEntity(GetRandomPrototype(), Owner.Transform.GridPosition);
|
var itemToSpawn = _entityManager.SpawnEntity(GetRandomPrototype(), Owner.Transform.GridPosition);
|
||||||
handsComponent.PutInHandOrDrop(itemToSpawn.GetComponent<ItemComponent>());
|
handsComponent.PutInHandOrDrop(itemToSpawn.GetComponent<ItemComponent>());
|
||||||
_count--;
|
_count--;
|
||||||
|
|||||||
@@ -4,6 +4,7 @@ using System.Collections;
|
|||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using Content.Server.GameObjects.Components.Access;
|
using Content.Server.GameObjects.Components.Access;
|
||||||
|
using Content.Server.GameObjects.Components.GUI;
|
||||||
using Content.Server.Interfaces;
|
using Content.Server.Interfaces;
|
||||||
using Content.Server.Interfaces.PDA;
|
using Content.Server.Interfaces.PDA;
|
||||||
using Content.Shared.GameObjects;
|
using Content.Shared.GameObjects;
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
using Content.Shared.GameObjects.Components;
|
using Content.Server.GameObjects.Components.GUI;
|
||||||
|
using Content.Shared.GameObjects.Components;
|
||||||
using Content.Shared.Interfaces.GameObjects.Components;
|
using Content.Shared.Interfaces.GameObjects.Components;
|
||||||
using Robust.Shared.GameObjects;
|
using Robust.Shared.GameObjects;
|
||||||
using Robust.Shared.Serialization;
|
using Robust.Shared.Serialization;
|
||||||
@@ -17,6 +18,7 @@ namespace Content.Server.GameObjects.Components
|
|||||||
|
|
||||||
serializer.DataField(ref _isPlaceable, "IsPlaceable", true);
|
serializer.DataField(ref _isPlaceable, "IsPlaceable", true);
|
||||||
}
|
}
|
||||||
|
|
||||||
public bool InteractUsing(InteractUsingEventArgs eventArgs)
|
public bool InteractUsing(InteractUsingEventArgs eventArgs)
|
||||||
{
|
{
|
||||||
if (!IsPlaceable)
|
if (!IsPlaceable)
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
using Content.Server.GameObjects.Components.Items.Storage;
|
using Content.Server.GameObjects.Components.GUI;
|
||||||
using Content.Server.Interfaces.GameObjects;
|
using Content.Server.GameObjects.Components.Items.Storage;
|
||||||
|
using Content.Server.Interfaces.GameObjects.Components.Items;
|
||||||
using Content.Shared.Audio;
|
using Content.Shared.Audio;
|
||||||
using Content.Shared.Interfaces;
|
using Content.Shared.Interfaces;
|
||||||
using Content.Shared.Interfaces.GameObjects.Components;
|
using Content.Shared.Interfaces.GameObjects.Components;
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
using System;
|
using System;
|
||||||
|
using Content.Server.GameObjects.Components.GUI;
|
||||||
using Content.Server.GameObjects.Components.Power.ApcNetComponents;
|
using Content.Server.GameObjects.Components.Power.ApcNetComponents;
|
||||||
using Content.Server.GameObjects.Components.Weapon.Ranged.Barrels;
|
using Content.Server.GameObjects.Components.Weapon.Ranged.Barrels;
|
||||||
using Content.Shared.GameObjects;
|
using Content.Shared.GameObjects;
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
using System;
|
using System;
|
||||||
|
using Content.Server.GameObjects.Components.GUI;
|
||||||
using Content.Server.GameObjects.Components.Power.ApcNetComponents;
|
using Content.Server.GameObjects.Components.Power.ApcNetComponents;
|
||||||
using Content.Server.GameObjects.EntitySystems;
|
using Content.Server.GameObjects.EntitySystems;
|
||||||
using Content.Server.Interfaces;
|
using Content.Server.Interfaces;
|
||||||
|
|||||||
@@ -1,8 +1,9 @@
|
|||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
using Content.Server.GameObjects.Components.GUI;
|
||||||
using Content.Server.GameObjects.Components.Mobs;
|
using Content.Server.GameObjects.Components.Mobs;
|
||||||
using Content.Server.GameObjects.Components.Power;
|
using Content.Server.GameObjects.Components.Power;
|
||||||
using Content.Server.GameObjects.EntitySystems.Click;
|
using Content.Server.GameObjects.EntitySystems.Click;
|
||||||
using Content.Server.Interfaces.GameObjects;
|
using Content.Server.Interfaces.GameObjects.Components.Items;
|
||||||
using Content.Shared.Audio;
|
using Content.Shared.Audio;
|
||||||
using Content.Shared.GameObjects;
|
using Content.Shared.GameObjects;
|
||||||
using Content.Shared.GameObjects.EntitySystems;
|
using Content.Shared.GameObjects.EntitySystems;
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
using Content.Server.GameObjects.Components.GUI;
|
||||||
using Content.Server.GameObjects.Components.Weapon.Ranged.Barrels;
|
using Content.Server.GameObjects.Components.Weapon.Ranged.Barrels;
|
||||||
using Content.Shared.GameObjects;
|
using Content.Shared.GameObjects;
|
||||||
using Content.Shared.GameObjects.Components.Weapons.Ranged.Barrels;
|
using Content.Shared.GameObjects.Components.Weapons.Ranged.Barrels;
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
using Content.Server.GameObjects.Components.GUI;
|
||||||
using Content.Server.GameObjects.Components.Weapon.Ranged.Barrels;
|
using Content.Server.GameObjects.Components.Weapon.Ranged.Barrels;
|
||||||
using Content.Shared.GameObjects.Components.Weapons.Ranged.Barrels;
|
using Content.Shared.GameObjects.Components.Weapons.Ranged.Barrels;
|
||||||
using Content.Shared.Interfaces;
|
using Content.Shared.Interfaces;
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
using Content.Server.GameObjects.Components.GUI;
|
||||||
using Content.Server.GameObjects.Components.Weapon.Ranged.Barrels;
|
using Content.Server.GameObjects.Components.Weapon.Ranged.Barrels;
|
||||||
using Content.Shared.GameObjects.Components.Weapons.Ranged.Barrels;
|
using Content.Shared.GameObjects.Components.Weapons.Ranged.Barrels;
|
||||||
using Content.Shared.Interfaces;
|
using Content.Shared.Interfaces;
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
using Content.Server.GameObjects.Components.GUI;
|
||||||
using Content.Server.GameObjects.Components.Power;
|
using Content.Server.GameObjects.Components.Power;
|
||||||
using Content.Server.GameObjects.Components.Projectiles;
|
using Content.Server.GameObjects.Components.Projectiles;
|
||||||
using Content.Shared.GameObjects;
|
using Content.Shared.GameObjects;
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
using Content.Server.GameObjects.Components.GUI;
|
||||||
using Content.Server.GameObjects.Components.Weapon.Ranged.Ammunition;
|
using Content.Server.GameObjects.Components.Weapon.Ranged.Ammunition;
|
||||||
using Content.Server.GameObjects.EntitySystems.Click;
|
using Content.Server.GameObjects.EntitySystems.Click;
|
||||||
using Content.Shared.GameObjects;
|
using Content.Shared.GameObjects;
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
using System;
|
using System;
|
||||||
|
using Content.Server.GameObjects.Components.GUI;
|
||||||
using Content.Server.GameObjects.Components.Mobs;
|
using Content.Server.GameObjects.Components.Mobs;
|
||||||
using Content.Server.GameObjects.Components.Weapon.Ranged.Barrels;
|
using Content.Server.GameObjects.Components.Weapon.Ranged.Barrels;
|
||||||
using Content.Shared.GameObjects.Components.Weapons.Ranged;
|
using Content.Shared.GameObjects.Components.Weapons.Ranged;
|
||||||
|
|||||||
@@ -8,6 +8,7 @@ using Content.Server.GameObjects.EntitySystems.Click;
|
|||||||
using Content.Server.Interfaces.GameObjects.Components.Interaction;
|
using Content.Server.Interfaces.GameObjects.Components.Interaction;
|
||||||
using Content.Server.Interfaces;
|
using Content.Server.Interfaces;
|
||||||
using Content.Server.Interfaces.GameObjects;
|
using Content.Server.Interfaces.GameObjects;
|
||||||
|
using Content.Server.Interfaces.GameObjects.Components.Items;
|
||||||
using Content.Shared.GameObjects.Components;
|
using Content.Shared.GameObjects.Components;
|
||||||
using Content.Shared.GameObjects.Components.Interactable;
|
using Content.Shared.GameObjects.Components.Interactable;
|
||||||
using Content.Shared.GameObjects.EntitySystems;
|
using Content.Shared.GameObjects.EntitySystems;
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
using System.Linq;
|
using System.Linq;
|
||||||
using Content.Server.GameObjects.Components.Mobs;
|
using Content.Server.GameObjects.Components.Mobs;
|
||||||
using Content.Server.GameObjects.Components.Timing;
|
using Content.Server.GameObjects.Components.Timing;
|
||||||
using Content.Server.Interfaces.GameObjects;
|
using Content.Server.Interfaces.GameObjects.Components.Items;
|
||||||
using Content.Server.Utility;
|
using Content.Server.Utility;
|
||||||
using Content.Shared.GameObjects.Components.Inventory;
|
using Content.Shared.GameObjects.Components.Inventory;
|
||||||
using Content.Shared.GameObjects.EntitySystemMessages;
|
using Content.Shared.GameObjects.EntitySystemMessages;
|
||||||
|
|||||||
@@ -2,6 +2,7 @@
|
|||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using Content.Server.GameObjects.Components;
|
using Content.Server.GameObjects.Components;
|
||||||
using Content.Server.GameObjects.Components.Construction;
|
using Content.Server.GameObjects.Components.Construction;
|
||||||
|
using Content.Server.GameObjects.Components.GUI;
|
||||||
using Content.Server.GameObjects.Components.Interactable;
|
using Content.Server.GameObjects.Components.Interactable;
|
||||||
using Content.Server.GameObjects.Components.Stack;
|
using Content.Server.GameObjects.Components.Stack;
|
||||||
using Content.Server.GameObjects.EntitySystems.Click;
|
using Content.Server.GameObjects.EntitySystems.Click;
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
using System.Linq;
|
using System.Linq;
|
||||||
using Content.Server.GameObjects.Components.Stack;
|
using Content.Server.GameObjects.Components.Stack;
|
||||||
|
using Content.Server.Interfaces;
|
||||||
using Content.Server.Throw;
|
using Content.Server.Throw;
|
||||||
using Content.Shared.GameObjects.Components.Inventory;
|
using Content.Shared.GameObjects.Components.Inventory;
|
||||||
using Content.Shared.Input;
|
using Content.Shared.Input;
|
||||||
@@ -15,6 +16,8 @@ using Robust.Shared.Localization;
|
|||||||
using Robust.Shared.Map;
|
using Robust.Shared.Map;
|
||||||
using Robust.Shared.Players;
|
using Robust.Shared.Players;
|
||||||
using System;
|
using System;
|
||||||
|
using Content.Server.GameObjects.Components.GUI;
|
||||||
|
using Content.Server.Interfaces.GameObjects.Components.Items;
|
||||||
using Content.Shared.GameObjects.EntitySystems;
|
using Content.Shared.GameObjects.EntitySystems;
|
||||||
using Content.Server.GameObjects;
|
using Content.Server.GameObjects;
|
||||||
using Content.Server.GameObjects.Components;
|
using Content.Server.GameObjects.Components;
|
||||||
@@ -74,11 +77,10 @@ namespace Content.Server.Interfaces.GameObjects.Components.Interaction
|
|||||||
|
|
||||||
var ent = session.AttachedEntity;
|
var ent = session.AttachedEntity;
|
||||||
|
|
||||||
if (ent == null || !ent.IsValid())
|
if (ent == null || !ent.IsValid() || !ent.TryGetComponent(out T comp))
|
||||||
return false;
|
{
|
||||||
|
|
||||||
if (!ent.TryGetComponent(out T comp))
|
|
||||||
return false;
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
component = comp;
|
component = comp;
|
||||||
return true;
|
return true;
|
||||||
@@ -87,9 +89,11 @@ namespace Content.Server.Interfaces.GameObjects.Components.Interaction
|
|||||||
private static void HandleSwapHands(ICommonSession session)
|
private static void HandleSwapHands(ICommonSession session)
|
||||||
{
|
{
|
||||||
if (!TryGetAttachedComponent(session as IPlayerSession, out HandsComponent handsComp))
|
if (!TryGetAttachedComponent(session as IPlayerSession, out HandsComponent handsComp))
|
||||||
|
{
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
var interactionSystem = EntitySystem.Get<InteractionSystem>();
|
var interactionSystem = Get<InteractionSystem>();
|
||||||
|
|
||||||
var oldItem = handsComp.GetActiveHand;
|
var oldItem = handsComp.GetActiveHand;
|
||||||
|
|
||||||
@@ -97,11 +101,15 @@ namespace Content.Server.Interfaces.GameObjects.Components.Interaction
|
|||||||
|
|
||||||
var newItem = handsComp.GetActiveHand;
|
var newItem = handsComp.GetActiveHand;
|
||||||
|
|
||||||
if(oldItem != null)
|
if (oldItem != null)
|
||||||
|
{
|
||||||
interactionSystem.HandDeselectedInteraction(handsComp.Owner, oldItem.Owner);
|
interactionSystem.HandDeselectedInteraction(handsComp.Owner, oldItem.Owner);
|
||||||
|
}
|
||||||
|
|
||||||
if(newItem != null)
|
if (newItem != null)
|
||||||
|
{
|
||||||
interactionSystem.HandSelectedInteraction(handsComp.Owner, newItem.Owner);
|
interactionSystem.HandSelectedInteraction(handsComp.Owner, newItem.Owner);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private bool HandleDrop(ICommonSession session, GridCoordinates coords, EntityUid uid)
|
private bool HandleDrop(ICommonSession session, GridCoordinates coords, EntityUid uid)
|
||||||
@@ -119,11 +127,11 @@ namespace Content.Server.Interfaces.GameObjects.Components.Interaction
|
|||||||
|
|
||||||
var entCoords = ent.Transform.GridPosition.Position;
|
var entCoords = ent.Transform.GridPosition.Position;
|
||||||
var entToDesiredDropCoords = coords.Position - entCoords;
|
var entToDesiredDropCoords = coords.Position - entCoords;
|
||||||
var targetLength = Math.Min(entToDesiredDropCoords.Length, InteractionSystem.InteractionRange - 0.001f); // InteractionRange is reduced due to InRange not dealing with floating point error
|
var targetLength = Math.Min(entToDesiredDropCoords.Length, SharedInteractionSystem.InteractionRange - 0.001f); // InteractionRange is reduced due to InRange not dealing with floating point error
|
||||||
var newCoords = new GridCoordinates((entToDesiredDropCoords.Normalized * targetLength) + entCoords, coords.GridID);
|
var newCoords = new GridCoordinates((entToDesiredDropCoords.Normalized * targetLength) + entCoords, coords.GridID);
|
||||||
var rayLength = EntitySystem.Get<SharedInteractionSystem>().UnobstructedRayLength(ent.Transform.MapPosition, newCoords.ToMap(_mapManager), ignoredEnt: ent);
|
var rayLength = Get<SharedInteractionSystem>().UnobstructedRayLength(ent.Transform.MapPosition, newCoords.ToMap(_mapManager), ignoredEnt: ent);
|
||||||
|
|
||||||
handsComp.Drop(handsComp.ActiveIndex, new GridCoordinates(entCoords + (entToDesiredDropCoords.Normalized * rayLength), coords.GridID));
|
handsComp.Drop(handsComp.ActiveHand, new GridCoordinates(entCoords + (entToDesiredDropCoords.Normalized * rayLength), coords.GridID));
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@@ -146,10 +154,10 @@ namespace Content.Server.Interfaces.GameObjects.Components.Interaction
|
|||||||
if (!plyEnt.TryGetComponent(out HandsComponent handsComp))
|
if (!plyEnt.TryGetComponent(out HandsComponent handsComp))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
if (!handsComp.CanDrop(handsComp.ActiveIndex))
|
if (!handsComp.CanDrop(handsComp.ActiveHand))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
var throwEnt = handsComp.GetHand(handsComp.ActiveIndex).Owner;
|
var throwEnt = handsComp.GetItem(handsComp.ActiveHand).Owner;
|
||||||
|
|
||||||
if (!handsComp.ThrowItem())
|
if (!handsComp.ThrowItem())
|
||||||
return false;
|
return false;
|
||||||
@@ -157,7 +165,7 @@ namespace Content.Server.Interfaces.GameObjects.Components.Interaction
|
|||||||
// throw the item, split off from a stack if it's meant to be thrown individually
|
// throw the item, split off from a stack if it's meant to be thrown individually
|
||||||
if (!throwEnt.TryGetComponent(out StackComponent stackComp) || stackComp.Count < 2 || !stackComp.ThrowIndividually)
|
if (!throwEnt.TryGetComponent(out StackComponent stackComp) || stackComp.Count < 2 || !stackComp.ThrowIndividually)
|
||||||
{
|
{
|
||||||
handsComp.Drop(handsComp.ActiveIndex);
|
handsComp.Drop(handsComp.ActiveHand);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@@ -201,7 +209,7 @@ namespace Content.Server.Interfaces.GameObjects.Components.Interaction
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
var heldItem = handsComp.GetHand(handsComp.ActiveIndex)?.Owner;
|
var heldItem = handsComp.GetItem(handsComp.ActiveHand)?.Owner;
|
||||||
|
|
||||||
if (heldItem != null)
|
if (heldItem != null)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -6,6 +6,7 @@ using System.Threading.Tasks;
|
|||||||
using Content.Server.GameObjects;
|
using Content.Server.GameObjects;
|
||||||
using Content.Server.GameObjects.Components;
|
using Content.Server.GameObjects.Components;
|
||||||
using Content.Server.GameObjects.Components.Access;
|
using Content.Server.GameObjects.Components.Access;
|
||||||
|
using Content.Server.GameObjects.Components.GUI;
|
||||||
using Content.Server.GameObjects.Components.Markers;
|
using Content.Server.GameObjects.Components.Markers;
|
||||||
using Content.Server.GameObjects.Components.Mobs;
|
using Content.Server.GameObjects.Components.Mobs;
|
||||||
using Content.Server.GameObjects.Components.Observer;
|
using Content.Server.GameObjects.Components.Observer;
|
||||||
|
|||||||
@@ -1,7 +1,10 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using Content.Server.BodySystem;
|
||||||
using Content.Server.Interfaces.GameTicking;
|
using Content.Server.Interfaces.GameTicking;
|
||||||
using Content.Server.Players;
|
using Content.Server.Players;
|
||||||
|
using Content.Shared.BodySystem;
|
||||||
using Content.Shared.Jobs;
|
using Content.Shared.Jobs;
|
||||||
using Robust.Server.Interfaces.Console;
|
using Robust.Server.Interfaces.Console;
|
||||||
using Robust.Server.Interfaces.Player;
|
using Robust.Server.Interfaces.Player;
|
||||||
@@ -321,4 +324,56 @@ namespace Content.Server.GameTicking
|
|||||||
shell.SendText(player, $"Created unloaded map from file {args[1]} with id {args[0]}. Use \"savebp 4 foo.yml\" to save it.");
|
shell.SendText(player, $"Created unloaded map from file {args[1]} with id {args[0]}. Use \"savebp 4 foo.yml\" to save it.");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
class AddHandCommand : IClientCommand
|
||||||
|
{
|
||||||
|
public string Command => "addhand";
|
||||||
|
public string Description => "Adds a hand to your entity.";
|
||||||
|
public string Help => $"Usage: {Command}";
|
||||||
|
|
||||||
|
public void Execute(IConsoleShell shell, IPlayerSession player, string[] args)
|
||||||
|
{
|
||||||
|
if (player == null)
|
||||||
|
{
|
||||||
|
shell.SendText(player, "Only a player can run this command.");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (player.AttachedEntity == null)
|
||||||
|
{
|
||||||
|
shell.SendText(player, "You have no entity.");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
var manager = player.AttachedEntity.GetComponent<BodyManagerComponent>();
|
||||||
|
var hand = manager.PartDictionary.First(x => x.Key == string.Join(" ", args));
|
||||||
|
manager.InstallBodyPart(hand.Value, hand.Key + new Random());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class RemoveHandCommand : IClientCommand
|
||||||
|
{
|
||||||
|
public string Command => "removehand";
|
||||||
|
public string Description => "Removes a hand from your entity.";
|
||||||
|
public string Help => $"Usage: {Command}";
|
||||||
|
|
||||||
|
public void Execute(IConsoleShell shell, IPlayerSession player, string[] args)
|
||||||
|
{
|
||||||
|
if (player == null)
|
||||||
|
{
|
||||||
|
shell.SendText(player, "Only a player can run this command.");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (player.AttachedEntity == null)
|
||||||
|
{
|
||||||
|
shell.SendText(player, "You have no entity.");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
var manager = player.AttachedEntity.GetComponent<BodyManagerComponent>();
|
||||||
|
var hand = manager.PartDictionary.First(x => x.Value.PartType == BodyPartType.Hand);
|
||||||
|
manager.DisconnectBodyPart(hand.Value, true);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -8,6 +8,7 @@ using Content.Shared.BodySystem;
|
|||||||
using Robust.Shared.ViewVariables;
|
using Robust.Shared.ViewVariables;
|
||||||
using Robust.Shared.Interfaces.GameObjects;
|
using Robust.Shared.Interfaces.GameObjects;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
|
using Content.Server.Interfaces.GameObjects.Components.Interaction;
|
||||||
|
|
||||||
namespace Content.Server.BodySystem {
|
namespace Content.Server.BodySystem {
|
||||||
|
|
||||||
@@ -178,8 +179,7 @@ namespace Content.Server.BodySystem {
|
|||||||
///////// Server-specific stuff
|
///////// Server-specific stuff
|
||||||
/////////
|
/////////
|
||||||
|
|
||||||
public override void ExposeData(ObjectSerializer serializer)
|
public override void ExposeData(ObjectSerializer serializer) {
|
||||||
{
|
|
||||||
base.ExposeData(serializer);
|
base.ExposeData(serializer);
|
||||||
|
|
||||||
serializer.DataReadWriteFunction(
|
serializer.DataReadWriteFunction(
|
||||||
@@ -225,8 +225,16 @@ namespace Content.Server.BodySystem {
|
|||||||
if (!_prototypeManager.TryIndex(partID, out BodyPartPrototype newPartData)) { //Get the BodyPartPrototype corresponding to the BodyPart ID we grabbed.
|
if (!_prototypeManager.TryIndex(partID, out BodyPartPrototype newPartData)) { //Get the BodyPartPrototype corresponding to the BodyPart ID we grabbed.
|
||||||
throw new InvalidOperationException("BodyPart prototype with ID " + partID + " could not be found!");
|
throw new InvalidOperationException("BodyPart prototype with ID " + partID + " could not be found!");
|
||||||
}
|
}
|
||||||
_partDictionary.Remove(slotName); //Try and remove an existing limb if that exists.
|
|
||||||
_partDictionary.Add(slotName, new BodyPart(newPartData)); //Add a new BodyPart with the BodyPartPrototype as a baseline to our BodyComponent.
|
//Try and remove an existing limb if that exists.
|
||||||
|
if (_partDictionary.Remove(slotName, out var removedPart))
|
||||||
|
{
|
||||||
|
BodyPartRemoved(removedPart, slotName);
|
||||||
|
}
|
||||||
|
|
||||||
|
var addedPart = new BodyPart(newPartData);
|
||||||
|
_partDictionary.Add(slotName, addedPart); //Add a new BodyPart with the BodyPartPrototype as a baseline to our BodyComponent.
|
||||||
|
BodyPartAdded(addedPart, slotName);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -264,6 +272,8 @@ namespace Content.Server.BodySystem {
|
|||||||
if (TryGetBodyPart(slotName, out BodyPart result)) //And that nothing is in it
|
if (TryGetBodyPart(slotName, out BodyPart result)) //And that nothing is in it
|
||||||
return false;
|
return false;
|
||||||
_partDictionary.Add(slotName, part);
|
_partDictionary.Add(slotName, part);
|
||||||
|
BodyPartAdded(part, slotName);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@@ -316,7 +326,11 @@ namespace Content.Server.BodySystem {
|
|||||||
return;
|
return;
|
||||||
if (part != null) {
|
if (part != null) {
|
||||||
string slotName = _partDictionary.FirstOrDefault(x => x.Value == part).Key;
|
string slotName = _partDictionary.FirstOrDefault(x => x.Value == part).Key;
|
||||||
_partDictionary.Remove(slotName);
|
if (_partDictionary.Remove(slotName, out var partRemoved))
|
||||||
|
{
|
||||||
|
BodyPartRemoved(partRemoved, slotName);
|
||||||
|
}
|
||||||
|
|
||||||
if (TryGetBodyPartConnections(slotName, out List<string> connections)) //Call disconnect on all limbs that were hanging off this limb.
|
if (TryGetBodyPartConnections(slotName, out List<string> connections)) //Call disconnect on all limbs that were hanging off this limb.
|
||||||
{
|
{
|
||||||
foreach (string connectionName in connections) //This loop is an unoptimized travesty. TODO: optimize to be less shit
|
foreach (string connectionName in connections) //This loop is an unoptimized travesty. TODO: optimize to be less shit
|
||||||
@@ -340,7 +354,11 @@ namespace Content.Server.BodySystem {
|
|||||||
if (!TryGetBodyPart(name, out BodyPart part))
|
if (!TryGetBodyPart(name, out BodyPart part))
|
||||||
return;
|
return;
|
||||||
if (part != null) {
|
if (part != null) {
|
||||||
_partDictionary.Remove(name);
|
if (_partDictionary.Remove(name, out var partRemoved))
|
||||||
|
{
|
||||||
|
BodyPartRemoved(partRemoved, name);
|
||||||
|
}
|
||||||
|
|
||||||
if (TryGetBodyPartConnections(name, out List<string> connections)) {
|
if (TryGetBodyPartConnections(name, out List<string> connections)) {
|
||||||
foreach (string connectionName in connections) {
|
foreach (string connectionName in connections) {
|
||||||
if (TryGetBodyPart(connectionName, out BodyPart result) && !ConnectedToCenterPart(result)) {
|
if (TryGetBodyPart(connectionName, out BodyPart result) && !ConnectedToCenterPart(result)) {
|
||||||
@@ -355,5 +373,24 @@ namespace Content.Server.BodySystem {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void BodyPartAdded(BodyPart part, string slotName)
|
||||||
|
{
|
||||||
|
var argsAdded = new BodyPartAddedEventArgs(part, slotName);
|
||||||
|
|
||||||
|
foreach (var component in Owner.GetAllComponents<IBodyPartAdded>().ToArray())
|
||||||
|
{
|
||||||
|
component.BodyPartAdded(argsAdded);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void BodyPartRemoved(BodyPart part, string slotName)
|
||||||
|
{
|
||||||
|
var args = new BodyPartRemovedEventArgs(part, slotName);
|
||||||
|
|
||||||
|
foreach (var component in Owner.GetAllComponents<IBodyPartRemoved>())
|
||||||
|
{
|
||||||
|
component.BodyPartRemoved(args);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,49 @@
|
|||||||
|
using System;
|
||||||
|
using Content.Server.BodySystem;
|
||||||
|
|
||||||
|
namespace Content.Server.Interfaces.GameObjects.Components.Interaction
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// This interface gives components behavior when a body part
|
||||||
|
/// is added to their owning entity.
|
||||||
|
/// </summary>
|
||||||
|
public interface IBodyPartAdded
|
||||||
|
{
|
||||||
|
void BodyPartAdded(BodyPartAddedEventArgs eventArgs);
|
||||||
|
}
|
||||||
|
|
||||||
|
public class BodyPartAddedEventArgs : EventArgs
|
||||||
|
{
|
||||||
|
public BodyPartAddedEventArgs(BodyPart part, string slotName)
|
||||||
|
{
|
||||||
|
Part = part;
|
||||||
|
SlotName = slotName;
|
||||||
|
}
|
||||||
|
|
||||||
|
public BodyPart Part { get; }
|
||||||
|
|
||||||
|
public string SlotName { get; }
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// This interface gives components behavior when a body part
|
||||||
|
/// is removed from their owning entity.
|
||||||
|
/// </summary>
|
||||||
|
public interface IBodyPartRemoved
|
||||||
|
{
|
||||||
|
void BodyPartRemoved(BodyPartRemovedEventArgs eventArgs);
|
||||||
|
}
|
||||||
|
|
||||||
|
public class BodyPartRemovedEventArgs : EventArgs
|
||||||
|
{
|
||||||
|
public BodyPartRemovedEventArgs(BodyPart part, string slotName)
|
||||||
|
{
|
||||||
|
Part = part;
|
||||||
|
SlotName = slotName;
|
||||||
|
}
|
||||||
|
|
||||||
|
public BodyPart Part { get; }
|
||||||
|
|
||||||
|
public string SlotName { get; }
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -7,14 +7,14 @@ using Robust.Server.GameObjects.EntitySystemMessages;
|
|||||||
using Robust.Shared.Interfaces.GameObjects;
|
using Robust.Shared.Interfaces.GameObjects;
|
||||||
using Robust.Shared.Map;
|
using Robust.Shared.Map;
|
||||||
|
|
||||||
namespace Content.Server.Interfaces.GameObjects
|
namespace Content.Server.Interfaces.GameObjects.Components.Items
|
||||||
{
|
{
|
||||||
public interface IHandsComponent : IComponent
|
public interface IHandsComponent : IComponent
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The hand index of the currently active hand.
|
/// The hand name of the currently active hand.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
string ActiveIndex { get; set; }
|
string ActiveHand { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Enumerates over every held item.
|
/// Enumerates over every held item.
|
||||||
@@ -24,9 +24,9 @@ namespace Content.Server.Interfaces.GameObjects
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets the item held by a hand.
|
/// Gets the item held by a hand.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="index">The index of the hand to get.</param>
|
/// <param name="handName">The name of the hand to get.</param>
|
||||||
/// <returns>The item in the held, null if no item is held</returns>
|
/// <returns>The item in the held, null if no item is held</returns>
|
||||||
ItemComponent GetHand(string index);
|
ItemComponent GetItem(string handName);
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets item held by the current active hand
|
/// Gets item held by the current active hand
|
||||||
@@ -44,7 +44,7 @@ namespace Content.Server.Interfaces.GameObjects
|
|||||||
/// Puts an item into a specific hand.
|
/// Puts an item into a specific hand.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="item">The item to put in the hand.</param>
|
/// <param name="item">The item to put in the hand.</param>
|
||||||
/// <param name="index">The index of the hand to put the item into.</param>
|
/// <param name="index">The name of the hand to put the item into.</param>
|
||||||
/// <param name="fallback">
|
/// <param name="fallback">
|
||||||
/// If true and the provided hand is full, the method will fall back to <see cref="PutInHand(ItemComponent)" />
|
/// If true and the provided hand is full, the method will fall back to <see cref="PutInHand(ItemComponent)" />
|
||||||
/// </param>
|
/// </param>
|
||||||
@@ -62,20 +62,22 @@ namespace Content.Server.Interfaces.GameObjects
|
|||||||
/// Checks to see if an item can be put in the specified hand.
|
/// Checks to see if an item can be put in the specified hand.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="item">The item to check for.</param>
|
/// <param name="item">The item to check for.</param>
|
||||||
/// <param name="index">The index for the hand to check for.</param>
|
/// <param name="index">The name for the hand to check for.</param>
|
||||||
/// <returns>True if the item can be inserted, false otherwise.</returns>
|
/// <returns>True if the item can be inserted, false otherwise.</returns>
|
||||||
bool CanPutInHand(ItemComponent item, string index);
|
bool CanPutInHand(ItemComponent item, string index);
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Finds the hand slot holding the specified entity, if any.
|
/// Finds the hand slot holding the specified entity, if any.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="entity">
|
/// <param name="entity">The entity to look for in our hands.</param>
|
||||||
/// The entity to look for in our hands.
|
/// <param name="handName">
|
||||||
|
/// The name of the hand slot if the entity is indeed held,
|
||||||
|
/// <see langword="null" /> otherwise.
|
||||||
/// </param>
|
/// </param>
|
||||||
/// <returns>
|
/// <returns>
|
||||||
/// The index of the hand slot if the entity is indeed held, <see langword="null" /> otherwise.
|
/// true if the entity is held, false otherwise
|
||||||
/// </returns>
|
/// </returns>
|
||||||
string FindHand(IEntity entity);
|
bool TryHand(IEntity entity, out string handName);
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Drops the item contained in the slot to the same position as our entity.
|
/// Drops the item contained in the slot to the same position as our entity.
|
||||||
@@ -135,7 +137,7 @@ namespace Content.Server.Interfaces.GameObjects
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="slot">The slot of which to drop the entity.</param>
|
/// <param name="slot">The slot of which to drop the entity.</param>
|
||||||
/// <param name="targetContainer">The container to drop into.</param>
|
/// <param name="targetContainer">The container to drop into.</param>
|
||||||
/// <param name="doMobChecks">Whether to check the <see cref="ActionBlockerSystem.CanDrop()"/> for the mob or not.</param>
|
/// <param name="doMobChecks">Whether to check the <see cref="ActionBlockerSystem.CanDrop(IEntity)"/> for the mob or not.</param>
|
||||||
/// <returns>True on success, false if something was blocked (insertion or removal).</returns>
|
/// <returns>True on success, false if something was blocked (insertion or removal).</returns>
|
||||||
/// <exception cref="InvalidOperationException">
|
/// <exception cref="InvalidOperationException">
|
||||||
/// Thrown if dry-run checks reported OK to remove and insert,
|
/// Thrown if dry-run checks reported OK to remove and insert,
|
||||||
@@ -167,20 +169,20 @@ namespace Content.Server.Interfaces.GameObjects
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// Checks whether the item in the specified hand can be dropped.
|
/// Checks whether the item in the specified hand can be dropped.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="index">The hand to check for.</param>
|
/// <param name="name">The hand to check for.</param>
|
||||||
/// <returns>
|
/// <returns>
|
||||||
/// True if the item can be dropped, false if the hand is empty or the item in the hand cannot be dropped.
|
/// True if the item can be dropped, false if the hand is empty or the item in the hand cannot be dropped.
|
||||||
/// </returns>
|
/// </returns>
|
||||||
bool CanDrop(string index);
|
bool CanDrop(string name);
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Adds a new hand to this hands component.
|
/// Adds a new hand to this hands component.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="index">The name of the hand to add.</param>
|
/// <param name="name">The name of the hand to add.</param>
|
||||||
/// <exception cref="InvalidOperationException">
|
/// <exception cref="InvalidOperationException">
|
||||||
/// Thrown if a hand with specified name already exists.
|
/// Thrown if a hand with specified name already exists.
|
||||||
/// </exception>
|
/// </exception>
|
||||||
void AddHand(string index);
|
void AddHand(string name);
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Removes a hand from this hands component.
|
/// Removes a hand from this hands component.
|
||||||
@@ -188,15 +190,15 @@ namespace Content.Server.Interfaces.GameObjects
|
|||||||
/// <remarks>
|
/// <remarks>
|
||||||
/// If the hand contains an item, the item is dropped.
|
/// If the hand contains an item, the item is dropped.
|
||||||
/// </remarks>
|
/// </remarks>
|
||||||
/// <param name="index">The name of the hand to remove.</param>
|
/// <param name="name">The name of the hand to remove.</param>
|
||||||
void RemoveHand(string index);
|
void RemoveHand(string name);
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Checks whether a hand with the specified name exists.
|
/// Checks whether a hand with the specified name exists.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="index">The hand name to check.</param>
|
/// <param name="name">The hand name to check.</param>
|
||||||
/// <returns>True if the hand exists, false otherwise.</returns>
|
/// <returns>True if the hand exists, false otherwise.</returns>
|
||||||
bool HasHand(string index);
|
bool HasHand(string name);
|
||||||
|
|
||||||
void HandleSlotModifiedMaybe(ContainerModifiedMessage message);
|
void HandleSlotModifiedMaybe(ContainerModifiedMessage message);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
using Content.Server.Interfaces.GameObjects;
|
using Content.Server.Interfaces.GameObjects;
|
||||||
|
using Content.Server.Interfaces.GameObjects.Components.Items;
|
||||||
using Content.Shared.Audio;
|
using Content.Shared.Audio;
|
||||||
using Content.Shared.GameObjects.Components.Mobs;
|
using Content.Shared.GameObjects.Components.Mobs;
|
||||||
using Content.Shared.GameObjects.EntitySystems;
|
using Content.Shared.GameObjects.EntitySystems;
|
||||||
|
|||||||
@@ -2,6 +2,7 @@ using System.Collections.Generic;
|
|||||||
using System.Linq;
|
using System.Linq;
|
||||||
using Content.Server.GameObjects;
|
using Content.Server.GameObjects;
|
||||||
using Content.Server.GameObjects.Components;
|
using Content.Server.GameObjects.Components;
|
||||||
|
using Content.Server.GameObjects.Components.GUI;
|
||||||
using Content.Server.GameObjects.Components.Mobs;
|
using Content.Server.GameObjects.Components.Mobs;
|
||||||
using Content.Server.Interfaces.PDA;
|
using Content.Server.Interfaces.PDA;
|
||||||
using Content.Shared.GameObjects.Components.PDA;
|
using Content.Shared.GameObjects.Components.PDA;
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
using Content.Server.GameObjects;
|
using Content.Server.GameObjects;
|
||||||
using Content.Server.GameObjects.Components;
|
using Content.Server.GameObjects.Components;
|
||||||
|
using Content.Server.GameObjects.Components.GUI;
|
||||||
using Content.Server.GameTicking;
|
using Content.Server.GameTicking;
|
||||||
using Content.Server.Interfaces.GameTicking;
|
using Content.Server.Interfaces.GameTicking;
|
||||||
using Content.Shared.Sandbox;
|
using Content.Shared.Sandbox;
|
||||||
|
|||||||
@@ -1,9 +1,11 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
using JetBrains.Annotations;
|
||||||
using Robust.Shared.GameObjects;
|
using Robust.Shared.GameObjects;
|
||||||
|
using Robust.Shared.Interfaces.GameObjects;
|
||||||
using Robust.Shared.Serialization;
|
using Robust.Shared.Serialization;
|
||||||
|
|
||||||
namespace Content.Shared.GameObjects
|
namespace Content.Shared.GameObjects.Components.Items
|
||||||
{
|
{
|
||||||
public abstract class SharedHandsComponent : Component
|
public abstract class SharedHandsComponent : Component
|
||||||
{
|
{
|
||||||
@@ -11,14 +13,31 @@ namespace Content.Shared.GameObjects
|
|||||||
public sealed override uint? NetID => ContentNetIDs.HANDS;
|
public sealed override uint? NetID => ContentNetIDs.HANDS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[Serializable, NetSerializable]
|
||||||
|
public sealed class SharedHand
|
||||||
|
{
|
||||||
|
public readonly int Index;
|
||||||
|
public readonly string Name;
|
||||||
|
public readonly EntityUid? EntityUid;
|
||||||
|
public readonly HandLocation Location;
|
||||||
|
|
||||||
|
public SharedHand(int index, string name, EntityUid? entityUid, HandLocation location)
|
||||||
|
{
|
||||||
|
Index = index;
|
||||||
|
Name = name;
|
||||||
|
EntityUid = entityUid;
|
||||||
|
Location = location;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// The IDs of the items get synced over the network.
|
// The IDs of the items get synced over the network.
|
||||||
[Serializable, NetSerializable]
|
[Serializable, NetSerializable]
|
||||||
public class HandsComponentState : ComponentState
|
public class HandsComponentState : ComponentState
|
||||||
{
|
{
|
||||||
public readonly Dictionary<string, EntityUid> Hands;
|
public readonly SharedHand[] Hands;
|
||||||
public readonly string ActiveIndex;
|
public readonly string ActiveIndex;
|
||||||
|
|
||||||
public HandsComponentState(Dictionary<string, EntityUid> hands, string activeIndex) : base(ContentNetIDs.HANDS)
|
public HandsComponentState(SharedHand[] hands, string activeIndex) : base(ContentNetIDs.HANDS)
|
||||||
{
|
{
|
||||||
Hands = hands;
|
Hands = hands;
|
||||||
ActiveIndex = activeIndex;
|
ActiveIndex = activeIndex;
|
||||||
@@ -75,4 +94,11 @@ namespace Content.Shared.GameObjects
|
|||||||
Index = index;
|
Index = index;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public enum HandLocation : byte
|
||||||
|
{
|
||||||
|
Left,
|
||||||
|
Middle,
|
||||||
|
Right
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -86,6 +86,8 @@
|
|||||||
- deleteewc
|
- deleteewc
|
||||||
- asay
|
- asay
|
||||||
- mapping
|
- mapping
|
||||||
|
- addhand
|
||||||
|
- removehand
|
||||||
CanViewVar: true
|
CanViewVar: true
|
||||||
CanAdminPlace: true
|
CanAdminPlace: true
|
||||||
|
|
||||||
@@ -159,6 +161,8 @@
|
|||||||
- sudo
|
- sudo
|
||||||
- asay
|
- asay
|
||||||
- mapping
|
- mapping
|
||||||
|
- addhand
|
||||||
|
- removehand
|
||||||
CanViewVar: true
|
CanViewVar: true
|
||||||
CanAdminPlace: true
|
CanAdminPlace: true
|
||||||
CanScript: true
|
CanScript: true
|
||||||
|
|||||||
@@ -10,9 +10,6 @@
|
|||||||
- type: AiController
|
- type: AiController
|
||||||
logic: Mimic
|
logic: Mimic
|
||||||
- type: Hands
|
- type: Hands
|
||||||
hands:
|
|
||||||
- left
|
|
||||||
- right
|
|
||||||
- type: MovementSpeedModifier
|
- type: MovementSpeedModifier
|
||||||
- type: InteractionOutline
|
- type: InteractionOutline
|
||||||
- type: Sprite
|
- type: Sprite
|
||||||
|
|||||||
@@ -10,9 +10,6 @@
|
|||||||
- type: AiController
|
- type: AiController
|
||||||
logic: Xeno
|
logic: Xeno
|
||||||
- type: Hands
|
- type: Hands
|
||||||
hands:
|
|
||||||
- left
|
|
||||||
- right
|
|
||||||
- type: MovementSpeedModifier
|
- type: MovementSpeedModifier
|
||||||
- type: InteractionOutline
|
- type: InteractionOutline
|
||||||
- type: Sprite
|
- type: Sprite
|
||||||
|
|||||||
@@ -10,9 +10,6 @@
|
|||||||
components:
|
components:
|
||||||
- type: Flashable
|
- type: Flashable
|
||||||
- type: Hands
|
- type: Hands
|
||||||
hands:
|
|
||||||
- left
|
|
||||||
- right
|
|
||||||
- type: MovementSpeedModifier
|
- type: MovementSpeedModifier
|
||||||
- type: Hunger
|
- type: Hunger
|
||||||
- type: Thirst
|
- type: Thirst
|
||||||
@@ -150,10 +147,6 @@
|
|||||||
description: A dummy human meant to be used in character setup
|
description: A dummy human meant to be used in character setup
|
||||||
components:
|
components:
|
||||||
- type: Hands
|
- type: Hands
|
||||||
hands:
|
|
||||||
- left
|
|
||||||
- right
|
|
||||||
|
|
||||||
- type: Inventory
|
- type: Inventory
|
||||||
- type: Sprite
|
- type: Sprite
|
||||||
netsync: false
|
netsync: false
|
||||||
|
|||||||
BIN
Resources/Textures/Interface/Inventory/hand_l_no_letter.png
Normal file
BIN
Resources/Textures/Interface/Inventory/hand_l_no_letter.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 2.5 KiB |
BIN
Resources/Textures/Interface/Inventory/hand_middle.png
Normal file
BIN
Resources/Textures/Interface/Inventory/hand_middle.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 2.4 KiB |
BIN
Resources/Textures/Interface/Inventory/hand_r_no_letter.png
Normal file
BIN
Resources/Textures/Interface/Inventory/hand_r_no_letter.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 2.4 KiB |
Reference in New Issue
Block a user