2020-07-25 15:11:16 +02:00
|
|
|
|
#nullable enable
|
|
|
|
|
|
using System;
|
2018-03-03 18:07:09 -08:00
|
|
|
|
using System.Collections.Generic;
|
2020-07-25 15:11:16 +02:00
|
|
|
|
using System.Diagnostics.CodeAnalysis;
|
2020-06-18 19:26:55 +02:00
|
|
|
|
using System.Linq;
|
2020-08-13 14:40:27 +02:00
|
|
|
|
using Content.Server.GameObjects.Components.Items.Storage;
|
2020-07-27 00:54:32 +02:00
|
|
|
|
using Content.Server.GameObjects.Components.Mobs;
|
|
|
|
|
|
using Content.Server.GameObjects.Components.Movement;
|
2020-07-06 14:27:03 -07:00
|
|
|
|
using Content.Server.GameObjects.EntitySystems.Click;
|
2020-07-25 15:11:16 +02:00
|
|
|
|
using Content.Server.Interfaces.GameObjects.Components.Interaction;
|
Bodysystem and damagesystem rework (#1544)
* Things and stuff with grids, unfinished w/ code debug changes.
* Updated submodule and also lost some progress cause I fucked it up xd
* First unfinished draft of the BodySystem. Doesn't compile.
* More changes to make it compile, but still just a framework. Doesn't do anything at the moment.
* Many cleanup changes.
* Revert "Merge branch 'master' of https://github.com/GlassEclipse/space-station-14 into body_system"
This reverts commit ddd4aebbc76cf2a0b7b102f72b93d55a0816c88c, reversing
changes made to 12d0dd752706bdda8879393bd8191a1199a0c978.
* Commit human.yml
* Updated a lot of things to be more classy, more progress overall, etc. etc.
* Latest update with many changes
* Minor changes
* Fixed Travis build bug
* Adds first draft of Body Scanner console, apparently I also forgot to tie Mechanisms into body parts so now a heart just sits in the Torso like a good boy :)
* Commit rest of stuff
* Latest changes
* Latest changes again
* 14 naked cowboys
* Yay!
* Latest changes (probably doesnt compile)
* Surgery!!!!!!!!!~1116y
* Cleaned some stuff up
* More cleanup
* Refactoring of code. Basic surgery path now done.
* Removed readme, has been added to HackMD
* Fixes typo (and thus test errors)
* WIP changes, committing so I can pull latest master changes
* Still working on that god awful merge
* Latest changes
* Latest changes!!
* Beginning of refactor to BoundUserInterface
* Surgery!
* Latest changes - fixes pr change requests and random fixes
* oops
* Fixes bodypart recursion
* Beginning of work on revamping the damage system.
* More latest changes
* Latest changes
* Finished merge
* Commit before removing old healthcode
* Almost done with removing speciescomponent...
* It compiles!!!
* yahoo more work
* Fixes to make it work
* Merge conflict fixes
* Deleting species visualizer was a mistake
* IDE warnings are VERBOTEN
* makes the server not kill itself on startup, some cleanup (#1)
* Namespaces, comments and exception fixes
* Fix conveyor and conveyor switch serialization
SS14 in reactive when
* Move damage, acts and body to shared
Damage cleanup
Comment cleanup
* Rename SpeciesComponent to RotationComponent and cleanup
Damage cleanup
Comment cleanup
* Fix nullable warnings
* Address old reviews
Fix off welder suicide damage type, deathmatch and suspicion
* Fix new test fail with units being able to accept items when unpowered
* Remove RotationComponent, change references to IBodyManagerComponent
* Add a bloodstream to humans
* More cleanups
* Add body conduits, connections, connectors substances and valves
* Revert "Add body conduits, connections, connectors substances and valves"
This reverts commit 9ab0b50e6b15fe98852d7b0836c0cdbf4bd76d20.
* Implement the heart mechanism behavior with the circulatory network
* Added network property to mechanism behaviors
* Changed human organ sprites and added missing ones
* Fix tests
* Add individual body part sprite rendering
* Fix error where dropped mechanisms are not initialized
* Implement client/server body damage
* Make DamageContainer take care of raising events
* Reimplement medical scanner with the new body system
* Improve the medical scanner ui
* Merge conflict fixes
* Fix crash when colliding with something
* Fix microwave suicides and eyes sprite rendering
* Fix nullable reference error
* Fix up surgery client side
* Fix missing using from merge conflict
* Add breathing
*inhale
* Merge conflict fixes
* Fix accumulatedframetime being reset to 0 instead of decreased by the threshold
https://github.com/space-wizards/space-station-14/pull/1617
* Use and add to the new AtmosHelpers
* Fix feet
* Add proper coloring to dropped body parts
* Fix Urist's lungs being too strong
* Merge conflict fixes
* Merge conflict fixes
* Merge conflict fixes
Co-authored-by: GlassEclipse <tsymall5@gmail.com>
Co-authored-by: Pieter-Jan Briers <pieterjan.briers+git@gmail.com>
Co-authored-by: AJCM-git <60196617+AJCM-git@users.noreply.github.com>
2020-08-17 01:42:42 +02:00
|
|
|
|
using Content.Shared.GameObjects.Components.Body;
|
2020-08-13 14:40:27 +02:00
|
|
|
|
using Content.Server.Interfaces.GameObjects.Components.Items;
|
|
|
|
|
|
using Content.Shared.GameObjects.Components.Items;
|
2020-07-27 00:54:32 +02:00
|
|
|
|
using Content.Shared.GameObjects.Components.Mobs;
|
2020-08-16 16:30:52 +02:00
|
|
|
|
using Content.Shared.GameObjects.EntitySystems;
|
2020-08-16 18:51:21 +02:00
|
|
|
|
using Content.Shared.Physics.Pull;
|
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;
|
2020-07-09 12:35:18 +02:00
|
|
|
|
using Robust.Shared.Containers;
|
2019-04-15 21:11:38 -06:00
|
|
|
|
using Robust.Shared.GameObjects;
|
2020-07-01 12:03:19 -07:00
|
|
|
|
using Robust.Shared.GameObjects.Components;
|
2020-08-16 21:08:05 +02:00
|
|
|
|
using Robust.Shared.GameObjects.Components.Transform;
|
2019-04-15 21:11:38 -06:00
|
|
|
|
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.ViewVariables;
|
2017-09-24 21:09:26 +02:00
|
|
|
|
|
2020-07-25 15:11:16 +02:00
|
|
|
|
namespace Content.Server.GameObjects.Components.GUI
|
2017-09-24 21:09:26 +02:00
|
|
|
|
{
|
2019-07-31 15:02:36 +02:00
|
|
|
|
[RegisterComponent]
|
|
|
|
|
|
[ComponentReference(typeof(IHandsComponent))]
|
2020-07-27 00:54:32 +02:00
|
|
|
|
[ComponentReference(typeof(ISharedHandsComponent))]
|
2020-07-25 15:11:16 +02:00
|
|
|
|
public class HandsComponent : SharedHandsComponent, IHandsComponent, IBodyPartAdded, IBodyPartRemoved
|
2017-09-24 21:09:26 +02:00
|
|
|
|
{
|
2019-04-29 13:12:50 +02:00
|
|
|
|
#pragma warning disable 649
|
2020-07-25 15:11:16 +02:00
|
|
|
|
[Dependency] private readonly IEntitySystemManager _entitySystemManager = default!;
|
2019-04-29 13:12:50 +02:00
|
|
|
|
#pragma warning restore 649
|
2019-04-20 16:18:16 -07:00
|
|
|
|
|
2020-07-25 15:11:16 +02:00
|
|
|
|
private string? _activeHand;
|
|
|
|
|
|
private uint _nextHand;
|
2018-03-03 18:07:09 -08:00
|
|
|
|
|
2020-08-15 20:33:42 +02:00
|
|
|
|
public event Action? OnItemChanged;
|
|
|
|
|
|
|
2018-09-09 15:34:43 +02:00
|
|
|
|
[ViewVariables(VVAccess.ReadWrite)]
|
2020-07-25 15:11:16 +02:00
|
|
|
|
public string? ActiveHand
|
2017-09-24 23:19:47 +02:00
|
|
|
|
{
|
2020-07-25 15:11:16 +02:00
|
|
|
|
get => _activeHand;
|
2017-09-24 23:19:47 +02:00
|
|
|
|
set
|
|
|
|
|
|
{
|
2020-07-25 15:11:16 +02:00
|
|
|
|
if (value != null && GetHand(value) == null)
|
2017-09-24 23:19:47 +02:00
|
|
|
|
{
|
|
|
|
|
|
throw new ArgumentException($"No hand '{value}'");
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2020-07-25 15:11:16 +02:00
|
|
|
|
_activeHand = value;
|
2018-05-13 11:54:21 +02:00
|
|
|
|
Dirty();
|
2017-09-24 23:19:47 +02:00
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2020-07-25 15:11:16 +02:00
|
|
|
|
[ViewVariables] private readonly List<Hand> _hands = new List<Hand>();
|
2017-09-24 23:19:47 +02:00
|
|
|
|
|
2020-08-15 20:33:42 +02:00
|
|
|
|
public IEnumerable<string> Hands => _hands.Select(h => h.Name);
|
|
|
|
|
|
|
2017-09-30 12:17:45 +02:00
|
|
|
|
// Mostly arbitrary.
|
2020-07-09 12:35:18 +02:00
|
|
|
|
public const float PickupRange = 2;
|
2017-09-30 12:17:45 +02:00
|
|
|
|
|
2020-07-25 15:11:16 +02:00
|
|
|
|
[ViewVariables] public int Count => _hands.Count;
|
2020-07-20 16:03:05 +02:00
|
|
|
|
|
2020-07-25 15:11:16 +02:00
|
|
|
|
// TODO: This does not serialize what objects are held.
|
|
|
|
|
|
protected override void Startup()
|
2017-09-24 23:19:47 +02:00
|
|
|
|
{
|
2020-07-25 15:11:16 +02:00
|
|
|
|
base.Startup();
|
|
|
|
|
|
ActiveHand = _hands.LastOrDefault()?.Name;
|
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
|
|
|
|
{
|
2020-07-25 15:11:16 +02:00
|
|
|
|
foreach (var hand in _hands)
|
2017-09-24 23:19:47 +02:00
|
|
|
|
{
|
2020-07-25 15:11:16 +02:00
|
|
|
|
if (hand.Entity != null)
|
2017-09-24 23:19:47 +02:00
|
|
|
|
{
|
2020-07-25 15:11:16 +02:00
|
|
|
|
yield return hand.Entity.GetComponent<ItemComponent>();
|
2017-09-24 23:19:47 +02:00
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2019-03-27 12:29:43 +00:00
|
|
|
|
public bool IsHolding(IEntity entity)
|
|
|
|
|
|
{
|
2020-07-25 15:11:16 +02:00
|
|
|
|
foreach (var hand in _hands)
|
2019-03-27 12:29:43 +00:00
|
|
|
|
{
|
2020-07-25 15:11:16 +02:00
|
|
|
|
if (hand.Entity == entity)
|
2019-03-27 12:29:43 +00:00
|
|
|
|
{
|
|
|
|
|
|
return true;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
return false;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2020-07-25 15:11:16 +02:00
|
|
|
|
private Hand? GetHand(string name)
|
|
|
|
|
|
{
|
|
|
|
|
|
return _hands.FirstOrDefault(hand => hand.Name == name);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
public ItemComponent? GetItem(string handName)
|
2017-09-24 23:19:47 +02:00
|
|
|
|
{
|
2020-07-25 15:11:16 +02:00
|
|
|
|
return GetHand(handName)?.Entity?.GetComponent<ItemComponent>();
|
2017-09-24 23:19:47 +02:00
|
|
|
|
}
|
|
|
|
|
|
|
2020-08-15 20:33:42 +02:00
|
|
|
|
public bool TryGetItem(string handName, [MaybeNullWhen(false)] out ItemComponent item)
|
|
|
|
|
|
{
|
|
|
|
|
|
item = GetItem(handName);
|
|
|
|
|
|
return item != null;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2020-07-25 15:11:16 +02:00
|
|
|
|
public ItemComponent? GetActiveHand => ActiveHand == null
|
|
|
|
|
|
? null
|
|
|
|
|
|
: GetItem(ActiveHand);
|
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>
|
2020-06-18 22:52:44 +10:00
|
|
|
|
public IEnumerable<string> ActivePriorityEnumerable()
|
2017-09-24 23:19:47 +02:00
|
|
|
|
{
|
2020-07-25 15:11:16 +02:00
|
|
|
|
if (ActiveHand != null)
|
2017-09-24 23:19:47 +02:00
|
|
|
|
{
|
2020-07-25 15:11:16 +02:00
|
|
|
|
yield return ActiveHand;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
foreach (var hand in _hands)
|
|
|
|
|
|
{
|
|
|
|
|
|
if (hand.Name == ActiveHand)
|
2017-09-24 23:19:47 +02:00
|
|
|
|
{
|
|
|
|
|
|
continue;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2020-07-25 15:11:16 +02:00
|
|
|
|
yield return hand.Name;
|
2017-09-24 23:19:47 +02:00
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2020-08-16 16:30:52 +02:00
|
|
|
|
public bool PutInHand(ItemComponent item, bool mobCheck = true)
|
2017-09-24 23:19:47 +02:00
|
|
|
|
{
|
|
|
|
|
|
foreach (var hand in ActivePriorityEnumerable())
|
|
|
|
|
|
{
|
2020-08-16 16:30:52 +02:00
|
|
|
|
if (PutInHand(item, hand, false, mobCheck))
|
2017-09-24 23:19:47 +02:00
|
|
|
|
{
|
2020-08-15 20:33:42 +02:00
|
|
|
|
OnItemChanged?.Invoke();
|
|
|
|
|
|
|
2017-09-24 23:19:47 +02:00
|
|
|
|
return true;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
return false;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2020-08-16 16:30:52 +02:00
|
|
|
|
public bool PutInHand(ItemComponent item, string index, bool fallback = true, bool mobChecks = true)
|
2017-09-24 23:19:47 +02:00
|
|
|
|
{
|
2020-07-25 15:11:16 +02:00
|
|
|
|
var hand = GetHand(index);
|
2020-08-16 16:30:52 +02:00
|
|
|
|
if (!CanPutInHand(item, index, mobChecks) || hand == null)
|
2017-09-24 23:19:47 +02:00
|
|
|
|
{
|
|
|
|
|
|
return fallback && PutInHand(item);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2018-05-13 11:54:21 +02:00
|
|
|
|
Dirty();
|
2020-07-25 15:11:16 +02:00
|
|
|
|
var success = hand.Container.Insert(item.Owner);
|
2019-03-22 22:18:17 +01:00
|
|
|
|
if (success)
|
|
|
|
|
|
{
|
|
|
|
|
|
item.Owner.Transform.LocalPosition = Vector2.Zero;
|
2020-08-15 20:33:42 +02:00
|
|
|
|
OnItemChanged?.Invoke();
|
2019-03-22 22:18:17 +01:00
|
|
|
|
}
|
|
|
|
|
|
|
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
|
|
|
|
|
2020-08-16 16:30:52 +02:00
|
|
|
|
public void PutInHandOrDrop(ItemComponent item, bool mobCheck = true)
|
2020-05-05 00:39:15 +02:00
|
|
|
|
{
|
2020-08-16 16:30:52 +02:00
|
|
|
|
if (!PutInHand(item, mobCheck))
|
2020-07-25 15:11:16 +02:00
|
|
|
|
{
|
2020-05-05 00:39:15 +02:00
|
|
|
|
item.Owner.Transform.GridPosition = Owner.Transform.GridPosition;
|
2020-07-25 15:11:16 +02:00
|
|
|
|
}
|
2020-05-05 00:39:15 +02:00
|
|
|
|
}
|
2017-09-24 23:19:47 +02:00
|
|
|
|
|
2020-08-16 16:30:52 +02:00
|
|
|
|
public bool CanPutInHand(ItemComponent item, bool mobCheck = true)
|
2017-09-24 23:19:47 +02:00
|
|
|
|
{
|
2020-08-16 16:30:52 +02:00
|
|
|
|
if (mobCheck && !ActionBlockerSystem.CanPickup(Owner))
|
|
|
|
|
|
return false;
|
|
|
|
|
|
|
2020-07-25 15:11:16 +02:00
|
|
|
|
foreach (var handName in ActivePriorityEnumerable())
|
2017-09-24 23:19:47 +02:00
|
|
|
|
{
|
2020-08-16 16:30:52 +02:00
|
|
|
|
// We already did a mobCheck, so let's not waste cycles.
|
|
|
|
|
|
if (CanPutInHand(item, handName, false))
|
2017-09-24 23:19:47 +02:00
|
|
|
|
{
|
|
|
|
|
|
return true;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
return false;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2020-08-16 16:30:52 +02:00
|
|
|
|
public bool CanPutInHand(ItemComponent item, string index, bool mobCheck = true)
|
2017-09-24 23:19:47 +02:00
|
|
|
|
{
|
2020-08-16 16:30:52 +02:00
|
|
|
|
if (mobCheck && !ActionBlockerSystem.CanPickup(Owner))
|
|
|
|
|
|
return false;
|
|
|
|
|
|
|
2020-07-25 15:11:16 +02:00
|
|
|
|
return GetHand(index)?.Container.CanInsert(item.Owner) == true;
|
2017-09-24 23:19:47 +02:00
|
|
|
|
}
|
|
|
|
|
|
|
2020-08-09 20:52:52 +02:00
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// Calls the Dropped Interaction with the item.
|
|
|
|
|
|
/// </summary>
|
|
|
|
|
|
/// <param name="item">The itemcomponent of the item to be dropped</param>
|
|
|
|
|
|
/// <param name="doMobChecks">Check if the item can be dropped</param>
|
|
|
|
|
|
/// <returns>True if IDropped.Dropped was called, otherwise false</returns>
|
|
|
|
|
|
private bool DroppedInteraction(ItemComponent item, bool doMobChecks)
|
|
|
|
|
|
{
|
|
|
|
|
|
var interactionSystem = _entitySystemManager.GetEntitySystem<InteractionSystem>();
|
|
|
|
|
|
if (doMobChecks)
|
|
|
|
|
|
{
|
|
|
|
|
|
if (!interactionSystem.TryDroppedInteraction(Owner, item.Owner))
|
|
|
|
|
|
return false;
|
|
|
|
|
|
}
|
2020-08-13 14:40:27 +02:00
|
|
|
|
|
2020-08-09 20:52:52 +02:00
|
|
|
|
interactionSystem.DroppedInteraction(Owner, item.Owner);
|
|
|
|
|
|
return true;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2020-07-25 15:11:16 +02:00
|
|
|
|
public bool TryHand(IEntity entity, [MaybeNullWhen(false)] out string handName)
|
2018-11-21 20:58:11 +01:00
|
|
|
|
{
|
2020-07-25 15:11:16 +02:00
|
|
|
|
handName = null;
|
|
|
|
|
|
|
|
|
|
|
|
foreach (var hand in _hands)
|
2018-11-21 20:58:11 +01:00
|
|
|
|
{
|
2020-07-25 15:11:16 +02:00
|
|
|
|
if (hand.Entity == entity)
|
2018-11-21 20:58:11 +01:00
|
|
|
|
{
|
2020-07-25 15:11:16 +02:00
|
|
|
|
handName = hand.Name;
|
|
|
|
|
|
return true;
|
2018-11-21 20:58:11 +01:00
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2020-07-25 15:11:16 +02:00
|
|
|
|
return false;
|
2018-11-21 20:58:11 +01:00
|
|
|
|
}
|
|
|
|
|
|
|
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
|
|
|
|
{
|
2020-07-25 15:11:16 +02:00
|
|
|
|
var hand = GetHand(slot);
|
|
|
|
|
|
if (!CanDrop(slot) || hand?.Entity == null)
|
2017-09-24 23:19:47 +02:00
|
|
|
|
{
|
|
|
|
|
|
return false;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2020-07-25 15:11:16 +02:00
|
|
|
|
var item = hand.Entity.GetComponent<ItemComponent>();
|
2020-04-25 12:03:20 +02:00
|
|
|
|
|
2020-07-25 15:11:16 +02:00
|
|
|
|
if (!hand.Container.Remove(hand.Entity))
|
2018-04-25 06:42:35 -05:00
|
|
|
|
{
|
|
|
|
|
|
return false;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2020-08-09 20:52:52 +02:00
|
|
|
|
if (!DroppedInteraction(item, doMobChecks))
|
2020-07-09 12:35:18 +02:00
|
|
|
|
return false;
|
2018-04-25 06:42:35 -05:00
|
|
|
|
|
2020-07-09 12:35:18 +02:00
|
|
|
|
item.RemovedFromSlot();
|
2019-01-18 11:40:30 +01:00
|
|
|
|
item.Owner.Transform.GridPosition = coords;
|
2018-11-21 20:58:11 +01:00
|
|
|
|
|
2020-07-25 15:11:16 +02:00
|
|
|
|
if (ContainerHelpers.TryGetContainer(Owner, out var container))
|
|
|
|
|
|
{
|
|
|
|
|
|
container.Insert(item.Owner);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2020-08-15 20:33:42 +02:00
|
|
|
|
OnItemChanged?.Invoke();
|
|
|
|
|
|
|
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));
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2020-07-25 15:11:16 +02:00
|
|
|
|
if (!TryHand(entity, out var slot))
|
2018-11-21 20:58:11 +01:00
|
|
|
|
{
|
|
|
|
|
|
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-08-16 16:30:52 +02:00
|
|
|
|
public bool Drop(string slot, bool mobChecks = true)
|
2018-11-21 20:58:11 +01:00
|
|
|
|
{
|
2020-07-25 15:11:16 +02:00
|
|
|
|
var hand = GetHand(slot);
|
2020-08-16 16:30:52 +02:00
|
|
|
|
if (!CanDrop(slot, mobChecks) || hand?.Entity == null)
|
2018-11-21 20:58:11 +01:00
|
|
|
|
{
|
|
|
|
|
|
return false;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2020-07-25 15:11:16 +02:00
|
|
|
|
var item = hand.Entity.GetComponent<ItemComponent>();
|
2020-01-22 23:09:36 +01:00
|
|
|
|
|
2020-08-16 16:30:52 +02:00
|
|
|
|
if (!DroppedInteraction(item, mobChecks))
|
2018-11-21 20:58:11 +01:00
|
|
|
|
return false;
|
|
|
|
|
|
|
2020-07-25 15:11:16 +02:00
|
|
|
|
if (!hand.Container.Remove(hand.Entity))
|
2020-07-09 12:35:18 +02:00
|
|
|
|
{
|
|
|
|
|
|
return false;
|
|
|
|
|
|
}
|
2018-11-21 20:58:11 +01:00
|
|
|
|
|
2020-07-09 12:35:18 +02:00
|
|
|
|
item.RemovedFromSlot();
|
2019-01-18 11:40:30 +01:00
|
|
|
|
item.Owner.Transform.GridPosition = Owner.Transform.GridPosition;
|
2020-07-09 12:35:18 +02:00
|
|
|
|
|
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
|
|
|
|
|
2020-07-25 15:11:16 +02:00
|
|
|
|
if (ContainerHelpers.TryGetContainer(Owner, out var container))
|
|
|
|
|
|
{
|
|
|
|
|
|
container.Insert(item.Owner);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2020-08-15 20:33:42 +02:00
|
|
|
|
OnItemChanged?.Invoke();
|
|
|
|
|
|
|
2018-11-21 20:58:11 +01:00
|
|
|
|
Dirty();
|
|
|
|
|
|
return true;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2020-08-16 16:30:52 +02:00
|
|
|
|
public bool Drop(IEntity entity, bool mobChecks = true)
|
2018-11-21 20:58:11 +01:00
|
|
|
|
{
|
|
|
|
|
|
if (entity == null)
|
|
|
|
|
|
{
|
|
|
|
|
|
throw new ArgumentNullException(nameof(entity));
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2020-07-25 15:11:16 +02:00
|
|
|
|
if (!TryHand(entity, out var slot))
|
2018-11-21 20:58:11 +01:00
|
|
|
|
{
|
|
|
|
|
|
throw new ArgumentException("Entity must be held in one of our hands.", nameof(entity));
|
|
|
|
|
|
}
|
2018-08-22 01:19:47 -07:00
|
|
|
|
|
2020-08-16 16:30:52 +02:00
|
|
|
|
return Drop(slot, mobChecks);
|
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));
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2020-07-25 15:11:16 +02:00
|
|
|
|
var hand = GetHand(slot);
|
|
|
|
|
|
if (!CanDrop(slot) || hand?.Entity == null)
|
2018-11-21 20:58:11 +01:00
|
|
|
|
{
|
|
|
|
|
|
return false;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2020-07-25 15:11:16 +02:00
|
|
|
|
var item = hand.Entity.GetComponent<ItemComponent>();
|
2020-06-07 16:48:53 +02:00
|
|
|
|
|
2020-08-09 20:52:52 +02:00
|
|
|
|
if (!DroppedInteraction(item, doMobChecks))
|
2020-06-07 16:48:53 +02:00
|
|
|
|
return false;
|
|
|
|
|
|
|
2020-07-25 15:11:16 +02:00
|
|
|
|
if (!hand.Container.CanRemove(hand.Entity))
|
2018-11-21 20:58:11 +01:00
|
|
|
|
{
|
|
|
|
|
|
return false;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2020-07-25 15:11:16 +02:00
|
|
|
|
if (!targetContainer.CanInsert(hand.Entity))
|
2018-11-21 20:58:11 +01:00
|
|
|
|
{
|
|
|
|
|
|
return false;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2020-07-25 15:11:16 +02:00
|
|
|
|
if (!hand.Container.Remove(hand.Entity))
|
2018-11-21 20:58:11 +01:00
|
|
|
|
{
|
|
|
|
|
|
throw new InvalidOperationException();
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
item.RemovedFromSlot();
|
|
|
|
|
|
|
|
|
|
|
|
if (!targetContainer.Insert(item.Owner))
|
|
|
|
|
|
{
|
|
|
|
|
|
throw new InvalidOperationException();
|
|
|
|
|
|
}
|
2018-08-22 01:19:47 -07:00
|
|
|
|
|
2020-08-15 20:33:42 +02:00
|
|
|
|
OnItemChanged?.Invoke();
|
|
|
|
|
|
|
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));
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2020-07-25 15:11:16 +02:00
|
|
|
|
if (!TryHand(entity, out var slot))
|
2018-11-21 20:58:11 +01:00
|
|
|
|
{
|
|
|
|
|
|
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>
|
2020-07-25 15:11:16 +02:00
|
|
|
|
/// <param name="name">The slot to check for.</param>
|
2018-04-25 06:42:35 -05:00
|
|
|
|
/// <returns>
|
|
|
|
|
|
/// True if there is an item in the slot and it can be dropped, false otherwise.
|
|
|
|
|
|
/// </returns>
|
2020-08-16 16:30:52 +02:00
|
|
|
|
public bool CanDrop(string name, bool mobCheck = true)
|
2017-09-24 23:19:47 +02:00
|
|
|
|
{
|
2020-07-25 15:11:16 +02:00
|
|
|
|
var hand = GetHand(name);
|
2020-08-16 16:30:52 +02:00
|
|
|
|
|
|
|
|
|
|
if (mobCheck && !ActionBlockerSystem.CanDrop(Owner))
|
|
|
|
|
|
return false;
|
|
|
|
|
|
|
2020-07-25 15:11:16 +02:00
|
|
|
|
if (hand?.Entity == null)
|
2020-07-09 12:35:18 +02:00
|
|
|
|
return false;
|
|
|
|
|
|
|
2020-07-25 15:11:16 +02:00
|
|
|
|
return hand.Container.CanRemove(hand.Entity);
|
2017-09-24 23:19:47 +02:00
|
|
|
|
}
|
2017-09-25 20:52:39 +02:00
|
|
|
|
|
2020-07-25 15:11:16 +02:00
|
|
|
|
public void AddHand(string name)
|
2017-09-25 20:52:39 +02:00
|
|
|
|
{
|
2020-07-25 15:11:16 +02:00
|
|
|
|
if (HasHand(name))
|
2017-09-25 20:52:39 +02:00
|
|
|
|
{
|
2020-07-25 15:11:16 +02:00
|
|
|
|
throw new InvalidOperationException($"Hand '{name}' already exists.");
|
2017-09-25 20:52:39 +02:00
|
|
|
|
}
|
|
|
|
|
|
|
2020-07-25 15:11:16 +02:00
|
|
|
|
var container = ContainerManagerComponent.Create<ContainerSlot>($"hand {_nextHand++}", Owner);
|
|
|
|
|
|
var hand = new Hand(name, container);
|
|
|
|
|
|
|
|
|
|
|
|
_hands.Add(hand);
|
|
|
|
|
|
|
|
|
|
|
|
ActiveHand ??= name;
|
2018-11-21 20:58:11 +01:00
|
|
|
|
|
2020-08-15 20:33:42 +02:00
|
|
|
|
OnItemChanged?.Invoke();
|
|
|
|
|
|
|
2018-05-13 11:54:21 +02:00
|
|
|
|
Dirty();
|
2017-09-25 20:52:39 +02:00
|
|
|
|
}
|
|
|
|
|
|
|
2020-07-25 15:11:16 +02:00
|
|
|
|
public void RemoveHand(string name)
|
2017-09-25 20:52:39 +02:00
|
|
|
|
{
|
2020-07-25 15:11:16 +02:00
|
|
|
|
var hand = GetHand(name);
|
|
|
|
|
|
if (hand == null)
|
2017-09-25 20:52:39 +02:00
|
|
|
|
{
|
2020-07-25 15:11:16 +02:00
|
|
|
|
throw new InvalidOperationException($"Hand '{name}' does not exist.");
|
2017-09-25 20:52:39 +02:00
|
|
|
|
}
|
|
|
|
|
|
|
2020-07-25 15:11:16 +02:00
|
|
|
|
Drop(hand.Name, false);
|
|
|
|
|
|
hand!.Dispose();
|
|
|
|
|
|
_hands.Remove(hand);
|
2017-09-29 18:38:27 +02:00
|
|
|
|
|
2020-07-25 15:11:16 +02:00
|
|
|
|
if (name == ActiveHand)
|
2017-09-29 18:38:27 +02:00
|
|
|
|
{
|
2020-07-25 15:11:16 +02:00
|
|
|
|
_activeHand = _hands.FirstOrDefault()?.Name;
|
2017-09-29 18:38:27 +02:00
|
|
|
|
}
|
2018-11-21 20:58:11 +01:00
|
|
|
|
|
2020-08-15 20:33:42 +02:00
|
|
|
|
OnItemChanged?.Invoke();
|
|
|
|
|
|
|
2018-05-13 11:54:21 +02:00
|
|
|
|
Dirty();
|
2017-09-25 20:52:39 +02:00
|
|
|
|
}
|
|
|
|
|
|
|
2020-07-25 15:11:16 +02:00
|
|
|
|
public bool HasHand(string name)
|
2017-09-25 20:52:39 +02:00
|
|
|
|
{
|
2020-07-25 15:11:16 +02:00
|
|
|
|
return _hands.Any(hand => hand.Name == name);
|
2017-09-25 20:52:39 +02:00
|
|
|
|
}
|
|
|
|
|
|
|
2017-09-26 21:27:48 +02:00
|
|
|
|
public override ComponentState GetComponentState()
|
|
|
|
|
|
{
|
2020-07-25 15:11:16 +02:00
|
|
|
|
var hands = new SharedHand[_hands.Count];
|
|
|
|
|
|
|
|
|
|
|
|
for (var i = 0; i < _hands.Count; i++)
|
2017-09-26 21:27:48 +02:00
|
|
|
|
{
|
2020-07-25 15:11:16 +02:00
|
|
|
|
var location = i == 0
|
|
|
|
|
|
? HandLocation.Right
|
|
|
|
|
|
: i == _hands.Count - 1
|
|
|
|
|
|
? HandLocation.Left
|
|
|
|
|
|
: HandLocation.Middle;
|
|
|
|
|
|
|
|
|
|
|
|
var hand = _hands[i].ToShared(i, location);
|
|
|
|
|
|
hands[i] = hand;
|
2017-09-26 21:27:48 +02:00
|
|
|
|
}
|
2018-11-21 20:58:11 +01:00
|
|
|
|
|
2020-07-25 15:11:16 +02:00
|
|
|
|
return new HandsComponentState(hands, ActiveHand);
|
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
|
|
|
|
{
|
2020-07-25 15:11:16 +02:00
|
|
|
|
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);
|
2017-09-29 18:38:27 +02:00
|
|
|
|
index++;
|
2020-07-25 15:11:16 +02:00
|
|
|
|
if (index == _hands.Count)
|
2017-09-29 18:38:27 +02:00
|
|
|
|
{
|
|
|
|
|
|
index = 0;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2020-07-25 15:11:16 +02:00
|
|
|
|
ActiveHand = _hands[index].Name;
|
2017-09-29 18:38:27 +02:00
|
|
|
|
}
|
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-07-27 00:54:32 +02:00
|
|
|
|
public void StartPull(PullableComponent pullable)
|
|
|
|
|
|
{
|
|
|
|
|
|
if (Owner == pullable.Owner)
|
|
|
|
|
|
{
|
|
|
|
|
|
return;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2020-08-16 18:51:21 +02:00
|
|
|
|
if (!Owner.IsInSameOrNoContainer(pullable.Owner))
|
2020-07-29 13:32:02 +02:00
|
|
|
|
{
|
2020-08-16 18:51:21 +02:00
|
|
|
|
return;
|
2020-07-29 13:32:02 +02:00
|
|
|
|
}
|
|
|
|
|
|
|
2020-07-27 00:54:32 +02:00
|
|
|
|
if (IsPulling)
|
|
|
|
|
|
{
|
|
|
|
|
|
StopPull();
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
PulledObject = pullable.Owner.GetComponent<ICollidableComponent>();
|
2020-08-16 18:51:21 +02:00
|
|
|
|
var controller = PulledObject.EnsureController<PullController>();
|
|
|
|
|
|
controller.StartPull(Owner.GetComponent<ICollidableComponent>());
|
2020-07-27 00:54:32 +02:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
public void MovePulledObject(GridCoordinates puller, GridCoordinates to)
|
|
|
|
|
|
{
|
|
|
|
|
|
if (PulledObject != null &&
|
|
|
|
|
|
PulledObject.TryGetController(out PullController controller))
|
|
|
|
|
|
{
|
|
|
|
|
|
controller.TryMoveTo(puller, to);
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2020-08-16 21:08:05 +02:00
|
|
|
|
private void MoveEvent(MoveEvent moveEvent)
|
|
|
|
|
|
{
|
|
|
|
|
|
if (moveEvent.Sender != Owner)
|
|
|
|
|
|
{
|
|
|
|
|
|
return;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
if (!IsPulling)
|
|
|
|
|
|
{
|
|
|
|
|
|
return;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
PulledObject!.WakeBody();
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2020-08-16 18:51:21 +02:00
|
|
|
|
public override void HandleMessage(ComponentMessage message, IComponent? component)
|
|
|
|
|
|
{
|
|
|
|
|
|
base.HandleMessage(message, component);
|
|
|
|
|
|
|
|
|
|
|
|
if (!(message is PullMessage pullMessage) ||
|
|
|
|
|
|
pullMessage.Puller.Owner != Owner)
|
|
|
|
|
|
{
|
|
|
|
|
|
return;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
switch (message)
|
|
|
|
|
|
{
|
|
|
|
|
|
case PullStartedMessage msg:
|
2020-08-16 21:08:05 +02:00
|
|
|
|
Owner.EntityManager.EventBus.SubscribeEvent<MoveEvent>(EventSource.Local, this, MoveEvent);
|
|
|
|
|
|
|
2020-08-16 18:51:21 +02:00
|
|
|
|
AddPullingStatuses(msg.Pulled.Owner);
|
|
|
|
|
|
break;
|
|
|
|
|
|
case PullStoppedMessage msg:
|
2020-08-16 21:08:05 +02:00
|
|
|
|
Owner.EntityManager.EventBus.UnsubscribeEvent<MoveEvent>(EventSource.Local, this);
|
|
|
|
|
|
|
2020-08-16 18:51:21 +02:00
|
|
|
|
RemovePullingStatuses(msg.Pulled.Owner);
|
|
|
|
|
|
break;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2020-07-25 15:11:16 +02: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))
|
2020-07-25 15:11:16 +02:00
|
|
|
|
{
|
|
|
|
|
|
ActiveHand = msg.Index;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2018-11-21 20:58:11 +01:00
|
|
|
|
break;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
case ClientAttackByInHandMsg msg:
|
|
|
|
|
|
{
|
2020-07-25 15:11:16 +02:00
|
|
|
|
var hand = GetHand(msg.Index);
|
|
|
|
|
|
if (hand == null)
|
2018-04-22 06:11:38 -05:00
|
|
|
|
{
|
2020-07-25 15:11:16 +02:00
|
|
|
|
Logger.WarningS("go.comp.hands", "Got a ClientAttackByInHandMsg with invalid hand name '{0}'",
|
2018-11-21 20:58:11 +01:00
|
|
|
|
msg.Index);
|
|
|
|
|
|
return;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
var playerEntity = session.AttachedEntity;
|
|
|
|
|
|
var used = GetActiveHand?.Owner;
|
2018-03-03 18:07:09 -08:00
|
|
|
|
|
2020-07-25 15:11:16 +02:00
|
|
|
|
if (playerEntity == Owner && hand.Entity != null)
|
2019-08-07 15:56:22 -07:00
|
|
|
|
{
|
2019-04-20 16:18:16 -07:00
|
|
|
|
var interactionSystem = _entitySystemManager.GetEntitySystem<InteractionSystem>();
|
2019-08-07 15:56:22 -07:00
|
|
|
|
if (used != null)
|
|
|
|
|
|
{
|
2020-07-25 15:11:16 +02:00
|
|
|
|
interactionSystem.Interaction(Owner, used, hand.Entity,
|
2019-12-29 18:12:56 -08:00
|
|
|
|
GridCoordinates.InvalidGrid);
|
2019-08-07 15:56:22 -07:00
|
|
|
|
}
|
|
|
|
|
|
else
|
|
|
|
|
|
{
|
2020-07-25 15:11:16 +02:00
|
|
|
|
var entity = hand.Entity;
|
2019-08-25 04:10:59 -07:00
|
|
|
|
if (!Drop(entity))
|
2020-07-25 15:11:16 +02:00
|
|
|
|
{
|
2019-08-25 04:10:59 -07:00
|
|
|
|
break;
|
2020-07-25 15:11:16 +02:00
|
|
|
|
}
|
|
|
|
|
|
|
2019-08-25 04:10:59 -07:00
|
|
|
|
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-07-25 15:11:16 +02:00
|
|
|
|
case UseInHandMsg _:
|
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;
|
2020-07-25 15:11:16 +02:00
|
|
|
|
var used = GetItem(msg.Index)?.Owner;
|
2020-01-17 18:41:47 -08:00
|
|
|
|
|
|
|
|
|
|
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)
|
|
|
|
|
|
{
|
2020-07-25 15:11:16 +02:00
|
|
|
|
foreach (var hand in _hands)
|
2019-05-05 13:09:21 +02:00
|
|
|
|
{
|
2020-07-25 15:11:16 +02:00
|
|
|
|
if (hand.Container != message.Container)
|
2019-05-05 13:09:21 +02:00
|
|
|
|
{
|
|
|
|
|
|
continue;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
Dirty();
|
2020-06-18 22:52:44 +10:00
|
|
|
|
|
2020-08-20 16:48:00 +02:00
|
|
|
|
if (!message.Entity.TryGetComponent(out ICollidableComponent? collidable))
|
2019-05-05 13:09:21 +02:00
|
|
|
|
{
|
|
|
|
|
|
return;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// set velocity to zero
|
2020-08-16 05:38:35 +02:00
|
|
|
|
collidable.Stop();
|
2019-05-05 13:09:21 +02:00
|
|
|
|
return;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
2020-07-25 15:11:16 +02:00
|
|
|
|
|
2020-08-16 18:51:21 +02:00
|
|
|
|
private void AddPullingStatuses(IEntity pulled)
|
2020-07-27 00:54:32 +02:00
|
|
|
|
{
|
2020-08-20 16:48:00 +02:00
|
|
|
|
if (pulled.TryGetComponent(out ServerStatusEffectsComponent? pulledStatus))
|
2020-07-27 00:54:32 +02:00
|
|
|
|
{
|
|
|
|
|
|
pulledStatus.ChangeStatusEffectIcon(StatusEffect.Pulled,
|
|
|
|
|
|
"/Textures/Interface/StatusEffects/Pull/pulled.png");
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2020-08-20 16:48:00 +02:00
|
|
|
|
if (Owner.TryGetComponent(out ServerStatusEffectsComponent? ownerStatus))
|
2020-07-27 00:54:32 +02:00
|
|
|
|
{
|
|
|
|
|
|
ownerStatus.ChangeStatusEffectIcon(StatusEffect.Pulling,
|
|
|
|
|
|
"/Textures/Interface/StatusEffects/Pull/pulling.png");
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2020-08-16 18:51:21 +02:00
|
|
|
|
private void RemovePullingStatuses(IEntity pulled)
|
2020-07-27 00:54:32 +02:00
|
|
|
|
{
|
2020-08-20 16:48:00 +02:00
|
|
|
|
if (pulled.TryGetComponent(out ServerStatusEffectsComponent? pulledStatus))
|
2020-07-27 00:54:32 +02:00
|
|
|
|
{
|
|
|
|
|
|
pulledStatus.RemoveStatusEffect(StatusEffect.Pulled);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2020-08-20 16:48:00 +02:00
|
|
|
|
if (Owner.TryGetComponent(out ServerStatusEffectsComponent? ownerStatus))
|
2020-07-27 00:54:32 +02:00
|
|
|
|
{
|
|
|
|
|
|
ownerStatus.RemoveStatusEffect(StatusEffect.Pulling);
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2020-07-25 15:11:16 +02:00
|
|
|
|
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);
|
|
|
|
|
|
}
|
2017-09-24 21:09:26 +02:00
|
|
|
|
}
|
|
|
|
|
|
}
|