2019-11-13 17:37:46 -05:00
|
|
|
|
// Only unused on .NET Core due to KeyValuePair.Deconstruct
|
|
|
|
|
|
// ReSharper disable once RedundantUsingDirective
|
|
|
|
|
|
using Robust.Shared.Utility;
|
|
|
|
|
|
using System;
|
2018-03-03 18:07:09 -08:00
|
|
|
|
using System.Collections.Generic;
|
2018-04-22 06:11:38 -05:00
|
|
|
|
using Content.Server.GameObjects.EntitySystems;
|
2018-03-03 18:07:09 -08:00
|
|
|
|
using Content.Server.Interfaces.GameObjects;
|
2017-09-26 21:27:48 +02:00
|
|
|
|
using Content.Shared.GameObjects;
|
2019-04-15 21:11:38 -06:00
|
|
|
|
using Robust.Server.GameObjects;
|
|
|
|
|
|
using Robust.Server.GameObjects.Components.Container;
|
2019-05-05 13:09:21 +02:00
|
|
|
|
using Robust.Server.GameObjects.EntitySystemMessages;
|
2019-04-15 21:11:38 -06:00
|
|
|
|
using Robust.Server.Interfaces.Player;
|
|
|
|
|
|
using Robust.Shared.GameObjects;
|
|
|
|
|
|
using Robust.Shared.Interfaces.GameObjects;
|
|
|
|
|
|
using Robust.Shared.Interfaces.Network;
|
|
|
|
|
|
using Robust.Shared.IoC;
|
|
|
|
|
|
using Robust.Shared.Log;
|
|
|
|
|
|
using Robust.Shared.Map;
|
|
|
|
|
|
using Robust.Shared.Maths;
|
2020-04-20 10:36:02 +01:00
|
|
|
|
using Robust.Shared.Players;
|
2019-04-15 21:11:38 -06:00
|
|
|
|
using Robust.Shared.Serialization;
|
|
|
|
|
|
using Robust.Shared.ViewVariables;
|
2017-09-24 21:09:26 +02:00
|
|
|
|
|
2017-09-24 23:19:47 +02:00
|
|
|
|
namespace Content.Server.GameObjects
|
2017-09-24 21:09:26 +02:00
|
|
|
|
{
|
2019-07-31 15:02:36 +02:00
|
|
|
|
[RegisterComponent]
|
|
|
|
|
|
[ComponentReference(typeof(IHandsComponent))]
|
2017-09-26 21:27:48 +02:00
|
|
|
|
public class HandsComponent : SharedHandsComponent, IHandsComponent
|
2017-09-24 21:09:26 +02:00
|
|
|
|
{
|
2019-04-29 13:12:50 +02:00
|
|
|
|
#pragma warning disable 649
|
2019-04-20 16:18:16 -07:00
|
|
|
|
[Dependency] private readonly IEntitySystemManager _entitySystemManager;
|
2019-04-29 13:12:50 +02:00
|
|
|
|
#pragma warning restore 649
|
2019-04-20 16:18:16 -07:00
|
|
|
|
|
2017-09-24 23:19:47 +02:00
|
|
|
|
private string activeIndex;
|
2018-03-03 18:07:09 -08:00
|
|
|
|
|
2018-09-09 15:34:43 +02:00
|
|
|
|
[ViewVariables(VVAccess.ReadWrite)]
|
2017-09-24 23:19:47 +02:00
|
|
|
|
public string ActiveIndex
|
|
|
|
|
|
{
|
|
|
|
|
|
get => activeIndex;
|
|
|
|
|
|
set
|
|
|
|
|
|
{
|
|
|
|
|
|
if (!hands.ContainsKey(value))
|
|
|
|
|
|
{
|
|
|
|
|
|
throw new ArgumentException($"No hand '{value}'");
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
activeIndex = value;
|
2018-05-13 11:54:21 +02:00
|
|
|
|
Dirty();
|
2017-09-24 23:19:47 +02:00
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2018-11-21 20:58:11 +01:00
|
|
|
|
[ViewVariables] private Dictionary<string, ContainerSlot> hands = new Dictionary<string, ContainerSlot>();
|
|
|
|
|
|
[ViewVariables] private List<string> orderedHands = new List<string>();
|
2017-09-24 23:19:47 +02:00
|
|
|
|
|
2017-09-30 12:17:45 +02:00
|
|
|
|
// Mostly arbitrary.
|
|
|
|
|
|
public const float PICKUP_RANGE = 2;
|
|
|
|
|
|
|
2018-07-26 23:38:16 +02:00
|
|
|
|
public override void ExposeData(ObjectSerializer serializer)
|
2017-09-24 23:19:47 +02:00
|
|
|
|
{
|
2018-04-25 06:42:35 -05:00
|
|
|
|
base.ExposeData(serializer);
|
|
|
|
|
|
|
2018-07-26 23:38:16 +02:00
|
|
|
|
// TODO: This does not serialize what objects are held.
|
2018-04-25 06:42:35 -05:00
|
|
|
|
serializer.DataField(ref orderedHands, "hands", new List<string>(0));
|
2018-05-27 23:27:32 +02:00
|
|
|
|
if (serializer.Reading)
|
2017-09-26 23:10:10 +02:00
|
|
|
|
{
|
2018-05-27 23:27:32 +02:00
|
|
|
|
foreach (var handsname in orderedHands)
|
|
|
|
|
|
{
|
|
|
|
|
|
AddHand(handsname);
|
|
|
|
|
|
}
|
2017-09-26 23:10:10 +02:00
|
|
|
|
}
|
2017-09-25 20:52:39 +02:00
|
|
|
|
}
|
|
|
|
|
|
|
2018-04-25 06:42:35 -05:00
|
|
|
|
public IEnumerable<ItemComponent> GetAllHeldItems()
|
2017-09-25 20:52:39 +02:00
|
|
|
|
{
|
2017-09-24 23:19:47 +02:00
|
|
|
|
foreach (var slot in hands.Values)
|
|
|
|
|
|
{
|
2018-04-25 06:42:35 -05:00
|
|
|
|
if (slot.ContainedEntity != null)
|
2017-09-24 23:19:47 +02:00
|
|
|
|
{
|
2018-04-25 06:42:35 -05:00
|
|
|
|
yield return slot.ContainedEntity.GetComponent<ItemComponent>();
|
2017-09-24 23:19:47 +02:00
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2019-03-27 12:29:43 +00:00
|
|
|
|
public bool IsHolding(IEntity entity)
|
|
|
|
|
|
{
|
|
|
|
|
|
foreach (var slot in hands.Values)
|
|
|
|
|
|
{
|
|
|
|
|
|
if (slot.ContainedEntity == entity)
|
|
|
|
|
|
{
|
|
|
|
|
|
return true;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
return false;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2018-04-25 06:42:35 -05:00
|
|
|
|
public ItemComponent GetHand(string index)
|
2017-09-24 23:19:47 +02:00
|
|
|
|
{
|
|
|
|
|
|
var slot = hands[index];
|
2018-04-25 06:42:35 -05:00
|
|
|
|
return slot.ContainedEntity?.GetComponent<ItemComponent>();
|
2017-09-24 23:19:47 +02:00
|
|
|
|
}
|
|
|
|
|
|
|
2018-04-25 06:42:35 -05:00
|
|
|
|
public ItemComponent GetActiveHand => GetHand(ActiveIndex);
|
2018-04-22 06:11:38 -05:00
|
|
|
|
|
2017-09-24 23:19:47 +02:00
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// Enumerates over the hand keys, returning the active hand first.
|
|
|
|
|
|
/// </summary>
|
|
|
|
|
|
private IEnumerable<string> ActivePriorityEnumerable()
|
|
|
|
|
|
{
|
|
|
|
|
|
yield return ActiveIndex;
|
|
|
|
|
|
foreach (var hand in hands.Keys)
|
|
|
|
|
|
{
|
|
|
|
|
|
if (hand == ActiveIndex)
|
|
|
|
|
|
{
|
|
|
|
|
|
continue;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
yield return hand;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2018-04-25 06:42:35 -05:00
|
|
|
|
public bool PutInHand(ItemComponent item)
|
2017-09-24 23:19:47 +02:00
|
|
|
|
{
|
|
|
|
|
|
foreach (var hand in ActivePriorityEnumerable())
|
|
|
|
|
|
{
|
|
|
|
|
|
if (PutInHand(item, hand, fallback: false))
|
|
|
|
|
|
{
|
|
|
|
|
|
return true;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
return false;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2018-04-25 06:42:35 -05:00
|
|
|
|
public bool PutInHand(ItemComponent item, string index, bool fallback = true)
|
2017-09-24 23:19:47 +02:00
|
|
|
|
{
|
|
|
|
|
|
if (!CanPutInHand(item, index))
|
|
|
|
|
|
{
|
|
|
|
|
|
return fallback && PutInHand(item);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
var slot = hands[index];
|
2018-05-13 11:54:21 +02:00
|
|
|
|
Dirty();
|
2019-03-22 22:18:17 +01:00
|
|
|
|
var success = slot.Insert(item.Owner);
|
|
|
|
|
|
if (success)
|
|
|
|
|
|
{
|
|
|
|
|
|
item.Owner.Transform.LocalPosition = Vector2.Zero;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2019-11-25 00:11:47 +01:00
|
|
|
|
_entitySystemManager.GetEntitySystem<InteractionSystem>().HandSelectedInteraction(Owner, item.Owner);
|
|
|
|
|
|
|
2019-03-22 22:18:17 +01:00
|
|
|
|
return success;
|
2017-09-24 23:19:47 +02:00
|
|
|
|
}
|
2020-05-05 00:39:15 +02:00
|
|
|
|
|
|
|
|
|
|
public void PutInHandOrDrop(ItemComponent item)
|
|
|
|
|
|
{
|
|
|
|
|
|
if (!PutInHand(item))
|
|
|
|
|
|
item.Owner.Transform.GridPosition = Owner.Transform.GridPosition;
|
|
|
|
|
|
}
|
2017-09-24 23:19:47 +02:00
|
|
|
|
|
2018-04-25 06:42:35 -05:00
|
|
|
|
public bool CanPutInHand(ItemComponent item)
|
2017-09-24 23:19:47 +02:00
|
|
|
|
{
|
|
|
|
|
|
foreach (var hand in ActivePriorityEnumerable())
|
|
|
|
|
|
{
|
|
|
|
|
|
if (CanPutInHand(item, hand))
|
|
|
|
|
|
{
|
|
|
|
|
|
return true;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
return false;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2018-04-25 06:42:35 -05:00
|
|
|
|
public bool CanPutInHand(ItemComponent item, string index)
|
2017-09-24 23:19:47 +02:00
|
|
|
|
{
|
|
|
|
|
|
var slot = hands[index];
|
2018-04-25 06:42:35 -05:00
|
|
|
|
return slot.CanInsert(item.Owner);
|
2017-09-24 23:19:47 +02:00
|
|
|
|
}
|
|
|
|
|
|
|
2018-11-21 20:58:11 +01:00
|
|
|
|
public string FindHand(IEntity entity)
|
|
|
|
|
|
{
|
|
|
|
|
|
foreach (var (index, slot) in hands)
|
|
|
|
|
|
{
|
|
|
|
|
|
if (slot.ContainedEntity == entity)
|
|
|
|
|
|
{
|
|
|
|
|
|
return index;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
return null;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2020-06-07 16:48:53 +02:00
|
|
|
|
public bool Drop(string slot, GridCoordinates coords, bool doMobChecks = true)
|
2017-09-24 23:19:47 +02:00
|
|
|
|
{
|
2018-04-25 06:42:35 -05:00
|
|
|
|
if (!CanDrop(slot))
|
2017-09-24 23:19:47 +02:00
|
|
|
|
{
|
|
|
|
|
|
return false;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2018-04-25 06:42:35 -05:00
|
|
|
|
var inventorySlot = hands[slot];
|
|
|
|
|
|
var item = inventorySlot.ContainedEntity.GetComponent<ItemComponent>();
|
2020-04-25 12:03:20 +02:00
|
|
|
|
|
2018-04-25 06:42:35 -05:00
|
|
|
|
if (!inventorySlot.Remove(inventorySlot.ContainedEntity))
|
|
|
|
|
|
{
|
|
|
|
|
|
return false;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2020-06-07 16:48:53 +02:00
|
|
|
|
if (doMobChecks && !_entitySystemManager.GetEntitySystem<InteractionSystem>().TryDroppedInteraction(Owner, item.Owner))
|
2020-04-25 12:03:20 +02:00
|
|
|
|
return false;
|
|
|
|
|
|
|
2018-04-25 06:42:35 -05:00
|
|
|
|
item.RemovedFromSlot();
|
|
|
|
|
|
|
|
|
|
|
|
// TODO: The item should be dropped to the container our owner is in, if any.
|
2019-01-18 11:40:30 +01:00
|
|
|
|
item.Owner.Transform.GridPosition = coords;
|
2018-11-21 20:58:11 +01:00
|
|
|
|
|
|
|
|
|
|
Dirty();
|
|
|
|
|
|
return true;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2020-06-07 16:48:53 +02:00
|
|
|
|
public bool Drop(IEntity entity, GridCoordinates coords, bool doMobChecks = true)
|
2018-11-21 20:58:11 +01:00
|
|
|
|
{
|
|
|
|
|
|
if (entity == null)
|
|
|
|
|
|
{
|
|
|
|
|
|
throw new ArgumentNullException(nameof(entity));
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
var slot = FindHand(entity);
|
|
|
|
|
|
if (slot == null)
|
|
|
|
|
|
{
|
|
|
|
|
|
throw new ArgumentException("Entity must be held in one of our hands.", nameof(entity));
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2020-06-07 16:48:53 +02:00
|
|
|
|
return Drop(slot, coords, doMobChecks);
|
2018-11-21 20:58:11 +01:00
|
|
|
|
}
|
|
|
|
|
|
|
2020-06-07 16:48:53 +02:00
|
|
|
|
public bool Drop(string slot, bool doMobChecks = true)
|
2018-11-21 20:58:11 +01:00
|
|
|
|
{
|
|
|
|
|
|
if (!CanDrop(slot))
|
|
|
|
|
|
{
|
|
|
|
|
|
return false;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
var inventorySlot = hands[slot];
|
|
|
|
|
|
var item = inventorySlot.ContainedEntity.GetComponent<ItemComponent>();
|
2020-01-22 23:09:36 +01:00
|
|
|
|
|
2020-06-07 16:48:53 +02:00
|
|
|
|
if (doMobChecks && !_entitySystemManager.GetEntitySystem<InteractionSystem>().TryDroppedInteraction(Owner, item.Owner))
|
2020-01-22 23:09:36 +01:00
|
|
|
|
return false;
|
|
|
|
|
|
|
2018-11-21 20:58:11 +01:00
|
|
|
|
if (!inventorySlot.Remove(inventorySlot.ContainedEntity))
|
|
|
|
|
|
{
|
|
|
|
|
|
return false;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
item.RemovedFromSlot();
|
|
|
|
|
|
|
|
|
|
|
|
// TODO: The item should be dropped to the container our owner is in, if any.
|
2019-01-18 11:40:30 +01:00
|
|
|
|
item.Owner.Transform.GridPosition = Owner.Transform.GridPosition;
|
2019-04-17 23:26:00 +02:00
|
|
|
|
if (item.Owner.TryGetComponent<SpriteComponent>(out var spriteComponent))
|
|
|
|
|
|
{
|
|
|
|
|
|
spriteComponent.RenderOrder = item.Owner.EntityManager.CurrentTick.Value;
|
|
|
|
|
|
}
|
2018-11-21 20:58:11 +01:00
|
|
|
|
|
|
|
|
|
|
Dirty();
|
|
|
|
|
|
return true;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2020-06-07 16:48:53 +02:00
|
|
|
|
public bool Drop(IEntity entity, bool doMobChecks = true)
|
2018-11-21 20:58:11 +01:00
|
|
|
|
{
|
|
|
|
|
|
if (entity == null)
|
|
|
|
|
|
{
|
|
|
|
|
|
throw new ArgumentNullException(nameof(entity));
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
var slot = FindHand(entity);
|
|
|
|
|
|
if (slot == null)
|
|
|
|
|
|
{
|
|
|
|
|
|
throw new ArgumentException("Entity must be held in one of our hands.", nameof(entity));
|
|
|
|
|
|
}
|
2018-08-22 01:19:47 -07:00
|
|
|
|
|
2020-06-07 16:48:53 +02:00
|
|
|
|
return Drop(slot, doMobChecks);
|
2018-11-21 20:58:11 +01:00
|
|
|
|
}
|
|
|
|
|
|
|
2020-06-07 16:48:53 +02:00
|
|
|
|
public bool Drop(string slot, BaseContainer targetContainer, bool doMobChecks = true)
|
2018-11-21 20:58:11 +01:00
|
|
|
|
{
|
2018-12-13 05:49:05 -08:00
|
|
|
|
if (slot == null)
|
|
|
|
|
|
{
|
|
|
|
|
|
throw new ArgumentNullException(nameof(slot));
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
if (targetContainer == null)
|
|
|
|
|
|
{
|
|
|
|
|
|
throw new ArgumentNullException(nameof(targetContainer));
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2018-11-21 20:58:11 +01:00
|
|
|
|
if (!CanDrop(slot))
|
|
|
|
|
|
{
|
|
|
|
|
|
return false;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2020-06-07 16:48:53 +02:00
|
|
|
|
|
2018-11-21 20:58:11 +01:00
|
|
|
|
var inventorySlot = hands[slot];
|
|
|
|
|
|
var item = inventorySlot.ContainedEntity.GetComponent<ItemComponent>();
|
2020-06-07 16:48:53 +02:00
|
|
|
|
|
|
|
|
|
|
if (doMobChecks && !_entitySystemManager.GetEntitySystem<InteractionSystem>().TryDroppedInteraction(Owner, item.Owner))
|
|
|
|
|
|
{
|
|
|
|
|
|
return false;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2018-11-21 20:58:11 +01:00
|
|
|
|
if (!inventorySlot.CanRemove(inventorySlot.ContainedEntity))
|
|
|
|
|
|
{
|
|
|
|
|
|
return false;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
if (!targetContainer.CanInsert(inventorySlot.ContainedEntity))
|
|
|
|
|
|
{
|
|
|
|
|
|
return false;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
if (!inventorySlot.Remove(inventorySlot.ContainedEntity))
|
|
|
|
|
|
{
|
|
|
|
|
|
throw new InvalidOperationException();
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
item.RemovedFromSlot();
|
|
|
|
|
|
|
|
|
|
|
|
if (!targetContainer.Insert(item.Owner))
|
|
|
|
|
|
{
|
|
|
|
|
|
throw new InvalidOperationException();
|
|
|
|
|
|
}
|
2018-08-22 01:19:47 -07:00
|
|
|
|
|
2018-05-13 11:54:21 +02:00
|
|
|
|
Dirty();
|
2018-04-25 06:42:35 -05:00
|
|
|
|
return true;
|
2017-09-24 23:19:47 +02:00
|
|
|
|
}
|
|
|
|
|
|
|
2020-06-07 16:48:53 +02:00
|
|
|
|
public bool Drop(IEntity entity, BaseContainer targetContainer, bool doMobChecks = true)
|
2018-11-21 20:58:11 +01:00
|
|
|
|
{
|
|
|
|
|
|
if (entity == null)
|
|
|
|
|
|
{
|
|
|
|
|
|
throw new ArgumentNullException(nameof(entity));
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
var slot = FindHand(entity);
|
|
|
|
|
|
if (slot == null)
|
|
|
|
|
|
{
|
|
|
|
|
|
throw new ArgumentException("Entity must be held in one of our hands.", nameof(entity));
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2020-06-07 16:48:53 +02:00
|
|
|
|
return Drop(slot, targetContainer, doMobChecks);
|
2018-11-21 20:58:11 +01:00
|
|
|
|
}
|
|
|
|
|
|
|
2018-04-25 06:42:35 -05:00
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// Checks whether an item can be dropped from the specified slot.
|
|
|
|
|
|
/// </summary>
|
|
|
|
|
|
/// <param name="slot">The slot to check for.</param>
|
|
|
|
|
|
/// <returns>
|
|
|
|
|
|
/// True if there is an item in the slot and it can be dropped, false otherwise.
|
|
|
|
|
|
/// </returns>
|
|
|
|
|
|
public bool CanDrop(string slot)
|
2017-09-24 23:19:47 +02:00
|
|
|
|
{
|
2018-04-25 06:42:35 -05:00
|
|
|
|
var inventorySlot = hands[slot];
|
|
|
|
|
|
return inventorySlot.CanRemove(inventorySlot.ContainedEntity);
|
2017-09-24 23:19:47 +02:00
|
|
|
|
}
|
2017-09-25 20:52:39 +02:00
|
|
|
|
|
|
|
|
|
|
public void AddHand(string index)
|
|
|
|
|
|
{
|
|
|
|
|
|
if (HasHand(index))
|
|
|
|
|
|
{
|
|
|
|
|
|
throw new InvalidOperationException($"Hand '{index}' already exists.");
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2018-04-25 06:42:35 -05:00
|
|
|
|
var slot = ContainerManagerComponent.Create<ContainerSlot>(Name + "_" + index, Owner);
|
2017-09-25 20:52:39 +02:00
|
|
|
|
hands[index] = slot;
|
2018-05-13 11:54:21 +02:00
|
|
|
|
if (!orderedHands.Contains(index))
|
2018-04-25 06:42:35 -05:00
|
|
|
|
{
|
|
|
|
|
|
orderedHands.Add(index);
|
|
|
|
|
|
}
|
2018-11-21 20:58:11 +01:00
|
|
|
|
|
2017-09-30 12:17:45 +02:00
|
|
|
|
if (ActiveIndex == null)
|
|
|
|
|
|
{
|
|
|
|
|
|
ActiveIndex = index;
|
|
|
|
|
|
}
|
2018-11-21 20:58:11 +01:00
|
|
|
|
|
2018-05-13 11:54:21 +02:00
|
|
|
|
Dirty();
|
2017-09-25 20:52:39 +02:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
public void RemoveHand(string index)
|
|
|
|
|
|
{
|
|
|
|
|
|
if (!HasHand(index))
|
|
|
|
|
|
{
|
|
|
|
|
|
throw new InvalidOperationException($"Hand '{index}' does not exist.");
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2018-04-25 06:42:35 -05:00
|
|
|
|
hands[index].Shutdown(); //TODO verify this
|
2017-09-25 20:52:39 +02:00
|
|
|
|
hands.Remove(index);
|
2017-09-29 18:38:27 +02:00
|
|
|
|
orderedHands.Remove(index);
|
|
|
|
|
|
|
|
|
|
|
|
if (index == ActiveIndex)
|
|
|
|
|
|
{
|
|
|
|
|
|
if (orderedHands.Count == 0)
|
|
|
|
|
|
{
|
|
|
|
|
|
activeIndex = null;
|
|
|
|
|
|
}
|
|
|
|
|
|
else
|
|
|
|
|
|
{
|
|
|
|
|
|
activeIndex = orderedHands[0];
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
2018-11-21 20:58:11 +01:00
|
|
|
|
|
2018-05-13 11:54:21 +02:00
|
|
|
|
Dirty();
|
2017-09-25 20:52:39 +02:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
public bool HasHand(string index)
|
|
|
|
|
|
{
|
|
|
|
|
|
return hands.ContainsKey(index);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// Get the name of the slot passed to the inventory component.
|
|
|
|
|
|
/// </summary>
|
|
|
|
|
|
private string HandSlotName(string index) => $"_hand_{index}";
|
2017-09-26 21:27:48 +02:00
|
|
|
|
|
|
|
|
|
|
public override ComponentState GetComponentState()
|
|
|
|
|
|
{
|
2018-01-20 14:46:31 -08:00
|
|
|
|
var dict = new Dictionary<string, EntityUid>(hands.Count);
|
2017-09-26 21:27:48 +02:00
|
|
|
|
foreach (var hand in hands)
|
|
|
|
|
|
{
|
2018-04-25 06:42:35 -05:00
|
|
|
|
if (hand.Value.ContainedEntity != null)
|
2017-09-26 21:27:48 +02:00
|
|
|
|
{
|
2018-04-25 06:42:35 -05:00
|
|
|
|
dict[hand.Key] = hand.Value.ContainedEntity.Uid;
|
2017-09-26 21:27:48 +02:00
|
|
|
|
}
|
|
|
|
|
|
}
|
2018-11-21 20:58:11 +01:00
|
|
|
|
|
2017-09-30 16:56:19 +02:00
|
|
|
|
return new HandsComponentState(dict, ActiveIndex);
|
2017-09-26 21:27:48 +02:00
|
|
|
|
}
|
2018-05-13 11:54:21 +02:00
|
|
|
|
|
2018-08-18 15:28:02 -07:00
|
|
|
|
public void SwapHands()
|
2017-09-30 12:17:45 +02:00
|
|
|
|
{
|
2017-09-29 18:38:27 +02:00
|
|
|
|
var index = orderedHands.FindIndex(x => x == ActiveIndex);
|
|
|
|
|
|
index++;
|
|
|
|
|
|
if (index >= orderedHands.Count)
|
|
|
|
|
|
{
|
|
|
|
|
|
index = 0;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
ActiveIndex = orderedHands[index];
|
|
|
|
|
|
}
|
2017-09-30 12:17:45 +02:00
|
|
|
|
|
2018-08-18 15:28:02 -07:00
|
|
|
|
public void ActivateItem()
|
|
|
|
|
|
{
|
|
|
|
|
|
var used = GetActiveHand?.Owner;
|
|
|
|
|
|
if (used != null)
|
|
|
|
|
|
{
|
2019-04-20 16:18:16 -07:00
|
|
|
|
var interactionSystem = _entitySystemManager.GetEntitySystem<InteractionSystem>();
|
|
|
|
|
|
interactionSystem.TryUseInteraction(Owner, used);
|
2018-08-18 15:28:02 -07:00
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2019-07-18 23:33:02 +02:00
|
|
|
|
public bool ThrowItem()
|
|
|
|
|
|
{
|
|
|
|
|
|
var item = GetActiveHand?.Owner;
|
|
|
|
|
|
if (item != null)
|
|
|
|
|
|
{
|
|
|
|
|
|
var interactionSystem = _entitySystemManager.GetEntitySystem<InteractionSystem>();
|
|
|
|
|
|
return interactionSystem.TryThrowInteraction(Owner, item);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
return false;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2020-04-20 10:36:02 +01:00
|
|
|
|
public override void HandleNetworkMessage(ComponentMessage message, INetChannel channel, ICommonSession session = null)
|
2017-09-30 16:56:19 +02:00
|
|
|
|
{
|
2020-04-20 10:36:02 +01:00
|
|
|
|
base.HandleNetworkMessage(message, channel, session);
|
|
|
|
|
|
|
|
|
|
|
|
if (session == null)
|
|
|
|
|
|
{
|
|
|
|
|
|
throw new ArgumentNullException(nameof(session));
|
|
|
|
|
|
}
|
2018-05-13 11:54:21 +02:00
|
|
|
|
|
2018-02-24 11:48:23 -08:00
|
|
|
|
switch (message)
|
2017-09-30 16:56:19 +02:00
|
|
|
|
{
|
2018-02-24 11:48:23 -08:00
|
|
|
|
case ClientChangedHandMsg msg:
|
2018-11-21 20:58:11 +01:00
|
|
|
|
{
|
|
|
|
|
|
var playerEntity = session.AttachedEntity;
|
|
|
|
|
|
|
|
|
|
|
|
if (playerEntity == Owner && HasHand(msg.Index))
|
|
|
|
|
|
ActiveIndex = msg.Index;
|
|
|
|
|
|
break;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
case ClientAttackByInHandMsg msg:
|
|
|
|
|
|
{
|
|
|
|
|
|
if (!hands.TryGetValue(msg.Index, out var slot))
|
2018-04-22 06:11:38 -05:00
|
|
|
|
{
|
2018-11-21 20:58:11 +01:00
|
|
|
|
Logger.WarningS("go.comp.hands", "Got a ClientAttackByInHandMsg with invalid hand index '{0}'",
|
|
|
|
|
|
msg.Index);
|
|
|
|
|
|
return;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
var playerEntity = session.AttachedEntity;
|
|
|
|
|
|
var used = GetActiveHand?.Owner;
|
2018-03-03 18:07:09 -08:00
|
|
|
|
|
2019-08-07 15:56:22 -07:00
|
|
|
|
if (playerEntity == Owner && slot.ContainedEntity != null)
|
|
|
|
|
|
{
|
2019-04-20 16:18:16 -07:00
|
|
|
|
var interactionSystem = _entitySystemManager.GetEntitySystem<InteractionSystem>();
|
2019-08-07 15:56:22 -07:00
|
|
|
|
if (used != null)
|
|
|
|
|
|
{
|
|
|
|
|
|
interactionSystem.Interaction(Owner, used, slot.ContainedEntity,
|
2019-12-29 18:12:56 -08:00
|
|
|
|
GridCoordinates.InvalidGrid);
|
2019-08-07 15:56:22 -07:00
|
|
|
|
}
|
|
|
|
|
|
else
|
|
|
|
|
|
{
|
2019-08-25 04:10:59 -07:00
|
|
|
|
var entity = slot.ContainedEntity;
|
|
|
|
|
|
if (!Drop(entity))
|
|
|
|
|
|
break;
|
|
|
|
|
|
interactionSystem.Interaction(Owner, entity);
|
2019-08-07 15:56:22 -07:00
|
|
|
|
}
|
2018-04-22 06:11:38 -05:00
|
|
|
|
}
|
|
|
|
|
|
|
2018-11-21 20:58:11 +01:00
|
|
|
|
break;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2020-01-17 18:41:47 -08:00
|
|
|
|
case UseInHandMsg msg:
|
2018-11-21 20:58:11 +01:00
|
|
|
|
{
|
|
|
|
|
|
var playerEntity = session.AttachedEntity;
|
|
|
|
|
|
var used = GetActiveHand?.Owner;
|
|
|
|
|
|
|
|
|
|
|
|
if (playerEntity == Owner && used != null)
|
2018-04-22 06:11:38 -05:00
|
|
|
|
{
|
2019-04-20 16:18:16 -07:00
|
|
|
|
var interactionSystem = _entitySystemManager.GetEntitySystem<InteractionSystem>();
|
|
|
|
|
|
interactionSystem.TryUseInteraction(Owner, used);
|
2018-04-22 06:11:38 -05:00
|
|
|
|
}
|
2018-11-21 20:58:11 +01:00
|
|
|
|
|
|
|
|
|
|
break;
|
|
|
|
|
|
}
|
2020-01-17 18:41:47 -08:00
|
|
|
|
|
|
|
|
|
|
case ActivateInHandMsg msg:
|
|
|
|
|
|
{
|
|
|
|
|
|
var playerEntity = session.AttachedEntity;
|
|
|
|
|
|
var used = GetHand(msg.Index)?.Owner;
|
|
|
|
|
|
|
|
|
|
|
|
if (playerEntity == Owner && used != null)
|
|
|
|
|
|
{
|
|
|
|
|
|
var interactionSystem = _entitySystemManager.GetEntitySystem<InteractionSystem>();
|
|
|
|
|
|
interactionSystem.TryInteractionActivate(Owner, used);
|
|
|
|
|
|
}
|
|
|
|
|
|
break;
|
|
|
|
|
|
}
|
2017-09-30 16:56:19 +02:00
|
|
|
|
}
|
|
|
|
|
|
}
|
2019-05-05 13:09:21 +02:00
|
|
|
|
|
|
|
|
|
|
public void HandleSlotModifiedMaybe(ContainerModifiedMessage message)
|
|
|
|
|
|
{
|
|
|
|
|
|
foreach (var container in hands.Values)
|
|
|
|
|
|
{
|
|
|
|
|
|
if (container != message.Container)
|
|
|
|
|
|
{
|
|
|
|
|
|
continue;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
Dirty();
|
|
|
|
|
|
if (!message.Entity.TryGetComponent(out PhysicsComponent physics))
|
|
|
|
|
|
{
|
|
|
|
|
|
return;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// set velocity to zero
|
|
|
|
|
|
physics.LinearVelocity = Vector2.Zero;
|
|
|
|
|
|
return;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
2017-09-24 21:09:26 +02:00
|
|
|
|
}
|
|
|
|
|
|
}
|