Merge pull request #1263 from DrSmugleaf/buckle-locker-fix-1262

Fix buckle in general
This commit is contained in:
Víctor Aguilera Puerto
2020-07-09 00:15:28 +02:00
committed by GitHub
53 changed files with 347 additions and 158 deletions

View File

@@ -1,6 +1,7 @@
using Content.Client.GameObjects.Components.Strap;
using Content.Client.GameObjects.Components.Strap;
using Content.Client.Interfaces.GameObjects.Components.Interaction;
using Content.Shared.GameObjects.Components.Mobs;
using Robust.Client.GameObjects;
using Robust.Shared.GameObjects;
namespace Content.Client.GameObjects.Components.Mobs
@@ -9,6 +10,9 @@ namespace Content.Client.GameObjects.Components.Mobs
public class BuckleComponent : SharedBuckleComponent, IClientDraggable
{
private bool _buckled;
private int? _originalDrawDepth;
protected override bool Buckled => _buckled;
public override void HandleComponentState(ComponentState curState, ComponentState nextState)
{
@@ -18,9 +22,25 @@ namespace Content.Client.GameObjects.Components.Mobs
}
_buckled = buckle.Buckled;
}
protected override bool Buckled => _buckled;
if (!Owner.TryGetComponent(out SpriteComponent ownerSprite))
{
return;
}
if (_buckled && buckle.DrawDepth.HasValue)
{
_originalDrawDepth ??= ownerSprite.DrawDepth;
ownerSprite.DrawDepth = buckle.DrawDepth.Value;
return;
}
if (!_buckled && _originalDrawDepth.HasValue)
{
ownerSprite.DrawDepth = _originalDrawDepth.Value;
_originalDrawDepth = null;
}
}
bool IClientDraggable.ClientCanDropOn(CanDropEventArgs eventArgs)
{

View File

@@ -1,6 +1,7 @@
using Content.Server.AI.Utility;
using Content.Server.AI.WorldState.States.Inventory;
using Content.Server.GameObjects.Components;
using Content.Server.GameObjects.Components.Items.Storage;
using Content.Server.Interfaces.GameObjects.Components.Interaction;
using Content.Server.Utility;
using Robust.Shared.Interfaces.GameObjects;

View File

@@ -1,6 +1,7 @@
using Content.Server.AI.Utility;
using Content.Server.AI.WorldState.States.Inventory;
using Content.Server.GameObjects.Components;
using Content.Server.GameObjects.Components.Items.Storage;
using Content.Server.Interfaces.GameObjects.Components.Interaction;
using Content.Server.Utility;
using Content.Shared.GameObjects.EntitySystems;
@@ -29,7 +30,7 @@ namespace Content.Server.AI.Operators.Inventory
{
return Outcome.Success;
}
if (!InteractionChecks.InRangeUnobstructed(_owner, container.Owner.Transform.MapPosition, ignoredEnt: container.Owner))
{
return Outcome.Failed;

View File

@@ -1,4 +1,5 @@
using Content.Server.GameObjects;
using Content.Server.GameObjects.Components;
using Content.Server.GameObjects.EntitySystems.Click;
using Content.Server.Utility;
using Robust.Shared.Containers;

View File

@@ -1,4 +1,5 @@
using Content.Server.GameObjects;
using Content.Server.GameObjects.Components;
using Robust.Shared.Interfaces.GameObjects;
namespace Content.Server.AI.Operators.Inventory

View File

@@ -1,6 +1,7 @@
using Content.Server.AI.WorldState;
using Content.Server.AI.WorldState.States;
using Content.Server.GameObjects.Components;
using Content.Server.GameObjects.Components.Items.Storage;
using Robust.Shared.Containers;
namespace Content.Server.AI.Utility.Considerations.Containers

View File

@@ -1,6 +1,7 @@
using Content.Server.AI.WorldState;
using Content.Server.AI.WorldState.States;
using Content.Server.GameObjects;
using Content.Server.GameObjects.Components;
namespace Content.Server.AI.Utility.Considerations.Hands
{

View File

@@ -2,7 +2,7 @@ using Content.Server.AI.WorldState;
using Content.Server.AI.WorldState.States;
using Content.Server.AI.WorldState.States.Hands;
using Content.Server.AI.WorldState.States.Inventory;
using Content.Server.GameObjects;
using Content.Server.GameObjects.Components;
namespace Content.Server.AI.Utility.Considerations.Inventory
{

View File

@@ -1,7 +1,7 @@
using Content.Server.AI.WorldState;
using Content.Server.AI.WorldState.States;
using Content.Server.AI.WorldState.States.Inventory;
using Content.Server.GameObjects;
using Content.Server.GameObjects.Components;
namespace Content.Server.AI.Utility.Considerations.Inventory
{

View File

@@ -1,4 +1,3 @@
using System;
using System.Collections.Generic;
using Content.Server.AI.Utility.Actions;
using Content.Server.AI.Utility.Actions.Clothing.Head;
@@ -6,7 +5,6 @@ using Content.Server.AI.WorldState;
using Content.Server.AI.WorldState.States;
using Content.Server.AI.WorldState.States.Inventory;
using Content.Server.GameObjects;
using Content.Server.GameObjects.Components.Movement;
using Content.Shared.GameObjects.Components.Inventory;
namespace Content.Server.AI.Utility.ExpandableActions.Clothing.Head

View File

@@ -1,4 +1,5 @@
using Content.Server.GameObjects.Components;
using Content.Server.GameObjects.Components.Items.Storage;
using Robust.Shared.Interfaces.GameObjects;
using Logger = Robust.Shared.Log.Logger;

View File

@@ -1,6 +1,7 @@
using System.Collections.Generic;
using Content.Server.AI.Utils;
using Content.Server.GameObjects.Components;
using Content.Server.GameObjects.Components.Items.Storage;
using Content.Server.GameObjects.Components.Movement;
using Content.Server.GameObjects.Components.Nutrition;
using JetBrains.Annotations;

View File

@@ -1,6 +1,7 @@
using System.Collections.Generic;
using Content.Server.AI.Utils;
using Content.Server.GameObjects.Components;
using Content.Server.GameObjects.Components.Items.Storage;
using Content.Server.GameObjects.Components.Movement;
using Content.Server.GameObjects.Components.Nutrition;
using JetBrains.Annotations;

View File

@@ -12,6 +12,7 @@ using Robust.Shared.Interfaces.GameObjects;
using Robust.Shared.IoC;
using Robust.Shared.Localization;
using System.Linq;
using Content.Server.GameObjects.Components;
namespace Content.Server.Chat
{

View File

@@ -2,6 +2,7 @@
using System;
using System.Collections.Generic;
using System.Linq;
using Content.Server.GameObjects.Components.Items.Storage;
using Content.Server.Interfaces;
using Content.Server.Interfaces.GameObjects;
using Content.Shared.GameObjects.Components.Inventory;

View File

@@ -1,5 +1,6 @@
using System.Collections.Generic;
using System.Linq;
using Content.Server.GameObjects.Components.Items.Storage;
using Content.Server.GameObjects.EntitySystems;
using Content.Server.Interfaces.GameObjects.Components.Interaction;
using Content.Server.Interfaces;

View File

@@ -1,5 +1,6 @@
using System;
using System.Linq;
using Content.Server.GameObjects.Components.Items.Storage;
using Content.Server.GameObjects.Components.Sound;
using Content.Server.Interfaces.GameObjects.Components.Interaction;
using Content.Server.GameObjects.Components.Power;

View File

@@ -1,3 +1,4 @@
using Content.Server.GameObjects.Components.Items.Storage;
using Content.Server.GameObjects.Components.Weapon;
using Content.Server.GameObjects.EntitySystems;
using Content.Server.Interfaces.GameObjects.Components.Interaction;

View File

@@ -1,7 +1,8 @@
using Content.Server.GameObjects.Components;
using Content.Server.GameObjects.Components.Items.Storage;
using Robust.Server.GameObjects.Components.Container;
using Robust.Shared.GameObjects;
using Robust.Shared.Interfaces.GameObjects;
using Robust.Shared.Interfaces.Network;
using Robust.Shared.Localization;
using Robust.Shared.Timers;
using static Content.Shared.GameObjects.Components.Inventory.EquipmentSlotDefines;

View File

@@ -1,14 +1,13 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks.Dataflow;
using Content.Server.GameObjects.Components;
using Content.Server.GameObjects.EntitySystems.Click;
using Content.Server.Interfaces.GameObjects.Components.Interaction;
using Content.Server.Interfaces;
using Content.Shared.GameObjects;
using Content.Shared.GameObjects.EntitySystems;
using Robust.Server.GameObjects.Components.Container;
using Robust.Server.Interfaces.Player;
using Robust.Shared.GameObjects;
using Robust.Shared.Interfaces.GameObjects;
using Robust.Shared.Interfaces.GameObjects.Components;

View File

@@ -4,9 +4,8 @@ using Robust.Shared.Utility;
using System;
using System.Collections.Generic;
using System.Linq;
using Content.Server.GameObjects.EntitySystems;
using Content.Server.GameObjects.Components;
using Content.Server.GameObjects.EntitySystems.Click;
using Content.Server.Interfaces.GameObjects.Components.Interaction;
using Content.Server.Interfaces.GameObjects;
using Content.Shared.GameObjects;
using Robust.Server.GameObjects;

View File

@@ -1,8 +1,6 @@
using Content.Server.GameObjects.Components.Power;
using Content.Server.GameObjects.Components.Sound;
using Content.Server.GameObjects.EntitySystems.Click;
using Content.Server.Interfaces.GameObjects.Components.Interaction;
using Content.Server.GameObjects.EntitySystems;
using Content.Server.Interfaces.GameObjects;
using Content.Shared.GameObjects;
using Content.Shared.GameObjects.Components;
@@ -19,7 +17,7 @@ using Robust.Shared.IoC;
using Robust.Shared.Localization;
using Robust.Shared.Utility;
using Robust.Shared.ViewVariables;
using System;
using Content.Server.GameObjects.Components.Items.Storage;
namespace Content.Server.GameObjects.Components.Interactable
{

View File

@@ -2,6 +2,7 @@
using System;
using System.Runtime.Remoting;
using Content.Server.GameObjects.Components.Chemistry;
using Content.Server.GameObjects.Components.Items.Storage;
using Content.Server.GameObjects.EntitySystems.Click;
using Content.Server.Interfaces.GameObjects.Components.Interaction;
using Content.Server.Interfaces;

View File

@@ -3,6 +3,8 @@
using Robust.Shared.Utility;
using System;
using System.Collections.Generic;
using Content.Server.GameObjects.Components;
using Content.Server.GameObjects.Components.Items.Storage;
using Content.Server.Interfaces.GameObjects.Components.Interaction;
using Content.Server.Interfaces;
using Content.Shared.GameObjects;

View File

@@ -2,7 +2,6 @@
using System.Linq;
using Content.Server.GameObjects.Components.Interactable;
using Content.Server.GameObjects.Components.Items.Storage;
using Content.Server.GameObjects.Components.Sound;
using Content.Server.Interfaces.GameObjects.Components.Interaction;
using Content.Shared.GameObjects;
using Content.Shared.GameObjects.Components.Interactable;
@@ -30,7 +29,7 @@ namespace Content.Server.GameObjects.Components
[RegisterComponent]
[ComponentReference(typeof(IActivate))]
[ComponentReference(typeof(IStorageComponent))]
public class EntityStorageComponent : Component, IActivate, IStorageComponent, IInteractUsing, IDestroyAct
public class EntityStorageComponent : Component, IActivate, IStorageComponent, IInteractUsing, IDestroyAct, IActionBlocker
{
public override string Name => "EntityStorage";
@@ -40,13 +39,13 @@ namespace Content.Server.GameObjects.Components
private TimeSpan _lastInternalOpenAttempt;
[ViewVariables]
private int StorageCapacityMax;
private int _storageCapacityMax;
[ViewVariables]
private bool IsCollidableWhenOpen;
private bool _isCollidableWhenOpen;
[ViewVariables]
private Container Contents;
private Container _contents;
[ViewVariables]
private IEntityQuery entityQuery;
private IEntityQuery _entityQuery;
private bool _showContents;
private bool _open;
private bool _isWeldedShut;
@@ -63,7 +62,7 @@ namespace Content.Server.GameObjects.Components
set
{
_showContents = value;
Contents.ShowContents = _showContents;
_contents.ShowContents = _showContents;
}
}
@@ -96,10 +95,10 @@ namespace Content.Server.GameObjects.Components
public override void Initialize()
{
base.Initialize();
Contents = ContainerManagerComponent.Ensure<Container>(nameof(EntityStorageComponent), Owner);
entityQuery = new IntersectingEntityQuery(Owner);
_contents = ContainerManagerComponent.Ensure<Container>(nameof(EntityStorageComponent), Owner);
_entityQuery = new IntersectingEntityQuery(Owner);
Contents.ShowContents = _showContents;
_contents.ShowContents = _showContents;
if (Owner.TryGetComponent<PlaceableSurfaceComponent>(out var placeableSurfaceComponent))
{
@@ -112,8 +111,8 @@ namespace Content.Server.GameObjects.Components
{
base.ExposeData(serializer);
serializer.DataField(ref StorageCapacityMax, "Capacity", 30);
serializer.DataField(ref IsCollidableWhenOpen, "IsCollidableWhenOpen", false);
serializer.DataField(ref _storageCapacityMax, "Capacity", 30);
serializer.DataField(ref _isCollidableWhenOpen, "IsCollidableWhenOpen", false);
serializer.DataField(ref _showContents, "showContents", false);
serializer.DataField(ref _open, "open", false);
serializer.DataField(this, a => a.IsWeldedShut, "IsWeldedShut", false);
@@ -146,7 +145,7 @@ namespace Content.Server.GameObjects.Components
private void CloseStorage()
{
Open = false;
var entities = Owner.EntityManager.GetEntities(entityQuery);
var entities = Owner.EntityManager.GetEntities(_entityQuery);
var count = 0;
foreach (var entity in entities)
{
@@ -163,7 +162,7 @@ namespace Content.Server.GameObjects.Components
continue;
}
count++;
if (count >= StorageCapacityMax)
if (count >= _storageCapacityMax)
{
break;
}
@@ -180,12 +179,11 @@ namespace Content.Server.GameObjects.Components
EmptyContents();
ModifyComponents();
EntitySystem.Get<AudioSystem>().PlayFromEntity("/Audio/Machines/closetopen.ogg", Owner);
}
private void ModifyComponents()
{
if (!IsCollidableWhenOpen && Owner.TryGetComponent<ICollidableComponent>(out var collidableComponent))
if (!_isCollidableWhenOpen && Owner.TryGetComponent<ICollidableComponent>(out var collidableComponent))
{
var physShape = collidableComponent.PhysicsShapes[0];
if (Open)
@@ -242,7 +240,7 @@ namespace Content.Server.GameObjects.Components
entity.Transform.WorldPosition += new Vector2(0, collidableComponent.WorldAABB.Top - entityCollidableComponent.WorldAABB.Top);
}
}
if (Contents.CanInsert(entity))
if (_contents.CanInsert(entity))
{
// Because Insert sets the local position to (0,0), and we want to keep the contents spread out,
// we re-apply the world position after inserting.
@@ -255,7 +253,7 @@ namespace Content.Server.GameObjects.Components
{
worldPos = entity.Transform.WorldPosition;
}
Contents.Insert(entity);
_contents.Insert(entity);
entity.Transform.WorldPosition = worldPos;
if (entityCollidableComponent != null)
{
@@ -268,9 +266,9 @@ namespace Content.Server.GameObjects.Components
private void EmptyContents()
{
foreach (var contained in Contents.ContainedEntities.ToArray())
foreach (var contained in _contents.ContainedEntities.ToArray())
{
if(Contents.Remove(contained))
if(_contents.Remove(contained))
{
if (contained.TryGetComponent<ICollidableComponent>(out var entityCollidableComponent))
{
@@ -317,7 +315,7 @@ namespace Content.Server.GameObjects.Components
/// <inheritdoc />
public bool Remove(IEntity entity)
{
return Contents.CanRemove(entity);
return _contents.CanRemove(entity);
}
/// <inheritdoc />
@@ -330,7 +328,7 @@ namespace Content.Server.GameObjects.Components
return true;
}
return Contents.Insert(entity);
return _contents.Insert(entity);
}
/// <inheritdoc />
@@ -341,12 +339,37 @@ namespace Content.Server.GameObjects.Components
return true;
}
if (Contents.ContainedEntities.Count >= StorageCapacityMax)
if (_contents.ContainedEntities.Count >= _storageCapacityMax)
{
return false;
}
return Contents.CanInsert(entity);
return _contents.CanInsert(entity);
}
bool IInteractUsing.InteractUsing(InteractUsingEventArgs eventArgs)
{
if (Open)
return false;
if (!CanWeldShut)
return false;
if (!eventArgs.Using.TryGetComponent(out WelderComponent tool))
return false;
if (!tool.UseTool(eventArgs.User, Owner, ToolQuality.Welding, 1f))
return false;
IsWeldedShut ^= true;
return true;
}
void IDestroyAct.OnDestroy(DestructionEventArgs eventArgs)
{
Open = true;
EmptyContents();
}
[Verb]
@@ -388,29 +411,5 @@ namespace Content.Server.GameObjects.Components
data.Text = component.Open ? "Close" : "Open";
}
public bool InteractUsing(InteractUsingEventArgs eventArgs)
{
if (Open)
return false;
if (!CanWeldShut)
return false;
if (!eventArgs.Using.TryGetComponent(out WelderComponent tool))
return false;
if (!tool.UseTool(eventArgs.User, Owner, ToolQuality.Welding, 1f))
return false;
IsWeldedShut ^= true;
return true;
}
public void OnDestroy(DestructionEventArgs eventArgs)
{
EmptyContents();
}
}
}

View File

@@ -1,8 +1,5 @@
using System;
using Content.Server.GameObjects.Components;
using Content.Server.GameObjects.Components.Destructible;
using Content.Server.GameObjects.Components.Items.Storage;
using Content.Server.Interfaces.GameObjects.Components.Interaction;
using Content.Server.GameObjects.EntitySystems;
using Content.Server.Interfaces.GameObjects;
using Content.Server.Throw;
using Content.Server.Utility;
@@ -21,7 +18,7 @@ using Robust.Shared.Maths;
using Robust.Shared.Random;
using Robust.Shared.Serialization;
namespace Content.Server.GameObjects
namespace Content.Server.GameObjects.Components
{
[RegisterComponent]
[ComponentReference(typeof(StoreableComponent))]

View File

@@ -1,7 +1,7 @@
using Robust.Shared.GameObjects;
using Robust.Shared.Serialization;
namespace Content.Server.GameObjects
namespace Content.Server.GameObjects.Components.Items.Storage
{
[RegisterComponent]
public class StoreableComponent : Component

View File

@@ -24,6 +24,7 @@ using Robust.Shared.Audio;
using Content.Server.Interfaces.GameObjects;
using Content.Server.Interfaces.Chat;
using Content.Server.BodySystem;
using Content.Server.GameObjects.Components.Items.Storage;
using Content.Shared.BodySystem;
using Robust.Shared.GameObjects.Systems;
using Content.Server.GameObjects.Components.Power.ApcNetComponents;

View File

@@ -1,6 +1,6 @@
#nullable enable
using System;
using Content.Server.GameObjects.Components.Strap;
using Content.Server.GameObjects.EntitySystems;
using Content.Server.Interfaces;
using Content.Server.Interfaces.GameObjects.Components.Interaction;
using Content.Server.Mobs;
@@ -10,9 +10,12 @@ using Content.Shared.GameObjects.Components.Mobs;
using Content.Shared.GameObjects.Components.Strap;
using Content.Shared.GameObjects.EntitySystems;
using Robust.Server.GameObjects;
using Robust.Server.GameObjects.EntitySystemMessages;
using Robust.Server.GameObjects.EntitySystems;
using Robust.Shared.Containers;
using Robust.Shared.GameObjects;
using Robust.Shared.Interfaces.GameObjects;
using Robust.Shared.Interfaces.Timing;
using Robust.Shared.IoC;
using Robust.Shared.Localization;
using Robust.Shared.Maths;
@@ -25,13 +28,35 @@ namespace Content.Server.GameObjects.Components.Mobs
public class BuckleComponent : SharedBuckleComponent, IInteractHand, IDragDrop
{
#pragma warning disable 649
[Dependency] private readonly IEntityManager _entityManager = default!;
[Dependency] private readonly IEntitySystemManager _entitySystem = default!;
[Dependency] private readonly IGameTiming _gameTiming = default!;
[Dependency] private readonly IServerNotifyManager _notifyManager = default!;
#pragma warning restore 649
private StrapComponent? _buckledTo;
/// <summary>
/// The amount of space that this entity occupies in a <see cref="StrapComponent"/>.
/// </summary>
private int _size;
/// <summary>
/// The range from which this entity can buckle to a <see cref="StrapComponent"/>.
/// </summary>
private float _range;
/// <summary>
/// The amount of time that must pass for this entity to
/// be able to unbuckle after recently buckling.
/// </summary>
private TimeSpan _unbuckleDelay;
/// <summary>
/// The time that this entity buckled at.
/// </summary>
private TimeSpan _buckleTime;
private StrapComponent? _buckledTo;
[ViewVariables]
public StrapComponent? BuckledTo
{
@@ -39,6 +64,7 @@ namespace Content.Server.GameObjects.Components.Mobs
private set
{
_buckledTo = value;
_buckleTime = _gameTiming.CurTime;
Dirty();
}
}
@@ -46,6 +72,8 @@ namespace Content.Server.GameObjects.Components.Mobs
[ViewVariables]
protected override bool Buckled => BuckledTo != null;
public bool ContainerChanged { get; private set; }
[ViewVariables]
public int Size => _size;
@@ -55,11 +83,35 @@ namespace Content.Server.GameObjects.Components.Mobs
{
status.ChangeStatusEffectIcon(StatusEffect.Buckled,
Buckled
? "/Textures/Interface/StatusEffects/Buckle/buckled.png"
? BuckledTo!.BuckledIcon
: "/Textures/Interface/StatusEffects/Buckle/unbuckled.png");
}
}
private void ReAttach(StrapComponent strap)
{
var ownTransform = Owner.Transform;
var strapTransform = strap.Owner.Transform;
ownTransform.GridPosition = strapTransform.GridPosition;
ownTransform.AttachParent(strapTransform);
switch (strap.Position)
{
case StrapPosition.None:
ownTransform.WorldRotation = strapTransform.WorldRotation;
break;
case StrapPosition.Stand:
StandingStateHelper.Standing(Owner);
ownTransform.WorldRotation = strapTransform.WorldRotation;
break;
case StrapPosition.Down:
StandingStateHelper.Down(Owner);
ownTransform.WorldRotation = Angle.South;
break;
}
}
private bool TryBuckle(IEntity user, IEntity to)
{
if (user == null || user == to)
@@ -74,30 +126,40 @@ namespace Content.Server.GameObjects.Components.Mobs
return false;
}
var strapPosition = Owner.Transform.MapPosition;
var range = SharedInteractionSystem.InteractionRange / 2;
if (!InteractionChecks.InRangeUnobstructed(user, strapPosition, range))
if (!to.TryGetComponent(out StrapComponent strap))
{
_notifyManager.PopupMessage(user, user,
Loc.GetString("You can't reach there!"));
_notifyManager.PopupMessage(Owner, user,
Loc.GetString(Owner == user
? "You can't buckle yourself there!"
: "You can't buckle {0:them} there!", Owner));
return false;
}
if (!user.TryGetComponent(out HandsComponent hands))
var strapPosition = strap.Owner.Transform.MapPosition;
if (!InteractionChecks.InRangeUnobstructed(user, strapPosition, _range))
{
return false;
}
if (ContainerHelpers.TryGetContainer(Owner, out var ownerContainer))
{
if (!ContainerHelpers.TryGetContainer(strap.Owner, out var strapContainer) ||
ownerContainer != strapContainer)
{
_notifyManager.PopupMessage(strap.Owner, user,
Loc.GetString("You can't reach there!"));
return false;
}
}
if (!user.HasComponent<HandsComponent>())
{
_notifyManager.PopupMessage(user, user,
Loc.GetString("You don't have hands!"));
return false;
}
if (hands.GetActiveHand != null)
{
_notifyManager.PopupMessage(user, user,
Loc.GetString("Your hand isn't free!"));
return false;
}
if (Buckled)
{
_notifyManager.PopupMessage(Owner, user,
@@ -107,15 +169,6 @@ namespace Content.Server.GameObjects.Components.Mobs
return false;
}
if (!to.TryGetComponent(out StrapComponent strap))
{
_notifyManager.PopupMessage(Owner, user,
Loc.GetString(Owner == user
? "You can't buckle yourself there!"
: "You can't buckle {0:them} there!", Owner));
return false;
}
var parent = to.Transform.Parent;
while (parent != null)
{
@@ -152,34 +205,14 @@ namespace Content.Server.GameObjects.Components.Mobs
return false;
}
BuckledTo = strap;
if (Owner.TryGetComponent(out AppearanceComponent appearance))
{
appearance.SetData(BuckleVisuals.Buckled, true);
}
var ownTransform = Owner.Transform;
var strapTransform = strap.Owner.Transform;
ownTransform.GridPosition = strapTransform.GridPosition;
ownTransform.AttachParent(strapTransform);
switch (strap.Position)
{
case StrapPosition.None:
ownTransform.WorldRotation = strapTransform.WorldRotation;
break;
case StrapPosition.Stand:
StandingStateHelper.Standing(Owner);
ownTransform.WorldRotation = strapTransform.WorldRotation;
break;
case StrapPosition.Down:
StandingStateHelper.Down(Owner);
ownTransform.WorldRotation = Angle.South;
break;
}
ReAttach(strap);
BuckledTo = strap;
BuckleStatus();
return true;
@@ -194,6 +227,11 @@ namespace Content.Server.GameObjects.Components.Mobs
if (!force)
{
if (_gameTiming.CurTime < _buckleTime + _unbuckleDelay)
{
return false;
}
if (!ActionBlockerSystem.CanInteract(user))
{
_notifyManager.PopupMessage(user, user,
@@ -202,11 +240,10 @@ namespace Content.Server.GameObjects.Components.Mobs
}
var strapPosition = Owner.Transform.MapPosition;
var range = SharedInteractionSystem.InteractionRange / 2;
if (!InteractionChecks.InRangeUnobstructed(user, strapPosition, range))
if (!InteractionChecks.InRangeUnobstructed(user, strapPosition, _range))
{
_notifyManager.PopupMessage(user, user,
_notifyManager.PopupMessage(Owner, user,
Loc.GetString("You can't reach there!"));
return false;
}
@@ -219,8 +256,12 @@ namespace Content.Server.GameObjects.Components.Mobs
.PlayFromEntity(strap.UnbuckleSound, Owner);
}
Owner.Transform.DetachParent();
Owner.Transform.WorldRotation = BuckledTo.Owner.Transform.WorldRotation;
if (Owner.Transform.Parent == BuckledTo.Owner.Transform)
{
Owner.Transform.DetachParent();
Owner.Transform.WorldRotation = BuckledTo.Owner.Transform.WorldRotation;
}
BuckledTo = null;
if (Owner.TryGetComponent(out AppearanceComponent appearance))
@@ -249,18 +290,46 @@ namespace Content.Server.GameObjects.Components.Mobs
public bool ToggleBuckle(IEntity user, IEntity to)
{
if (BuckledTo == null)
{
return TryBuckle(user, to);
}
else if (BuckledTo.Owner == to)
if (BuckledTo?.Owner == to)
{
return TryUnbuckle(user);
}
else
return TryBuckle(user, to);
}
private void InsertIntoContainer(ContainerModifiedMessage message)
{
if (message.Entity != Owner)
{
return false;
return;
}
ContainerChanged = true;
}
public void Update()
{
if (!ContainerChanged || BuckledTo == null)
{
return;
}
var contained = ContainerHelpers.TryGetContainer(Owner, out var ownContainer);
var strapContained = ContainerHelpers.TryGetContainer(BuckledTo.Owner, out var strapContainer);
if (contained != strapContained || ownContainer != strapContainer)
{
TryUnbuckle(Owner, true);
return;
}
if (!contained && !strapContained)
{
ReAttach(BuckledTo);
}
ContainerChanged = false;
}
public override void ExposeData(ObjectSerializer serializer)
@@ -268,6 +337,20 @@ namespace Content.Server.GameObjects.Components.Mobs
base.ExposeData(serializer);
serializer.DataField(ref _size, "size", 100);
serializer.DataField(ref _range, "range", SharedInteractionSystem.InteractionRange / 2);
var seconds = 0.25f;
serializer.DataField(ref seconds, "cooldown", 0.25f);
_unbuckleDelay = TimeSpan.FromSeconds(seconds);
}
public override void Initialize()
{
base.Initialize();
_entityManager.EventBus.SubscribeEvent<EntInsertedIntoContainerMessage>(EventSource.Local, this, InsertIntoContainer);
_entityManager.EventBus.SubscribeEvent<EntRemovedFromContainerMessage>(EventSource.Local, this, InsertIntoContainer);
}
protected override void Startup()
@@ -280,18 +363,32 @@ namespace Content.Server.GameObjects.Components.Mobs
{
base.OnRemove();
if (BuckledTo != null && BuckledTo.Owner.TryGetComponent(out StrapComponent strap))
_entityManager.EventBus.UnsubscribeEvents(this);
if (BuckledTo != null &&
BuckledTo.Owner.TryGetComponent(out StrapComponent strap))
{
strap.Remove(this);
}
BuckledTo = null;
TryUnbuckle(Owner, true);
_buckleTime = default;
BuckleStatus();
}
public override ComponentState GetComponentState()
{
return new BuckleComponentState(Buckled);
int? drawDepth = null;
if (BuckledTo != null &&
Owner.Transform.WorldRotation.GetCardinalDir() == Direction.North &&
BuckledTo.Owner.TryGetComponent(out SpriteComponent strapSprite))
{
drawDepth = strapSprite.DrawDepth - 1;
}
return new BuckleComponentState(Buckled, drawDepth);
}
bool IInteractHand.InteractHand(InteractHandEventArgs eventArgs)

View File

@@ -1,9 +1,6 @@
using System;
using Content.Shared.GameObjects.Components.Inventory;
using Content.Shared.GameObjects.Components.Inventory;
using Robust.Shared.GameObjects;
using CannyFastMath;
using Math = CannyFastMath.Math;
using MathF = CannyFastMath.MathF;
namespace Content.Server.GameObjects
{

View File

@@ -1,6 +1,7 @@
using System;
using System.Collections.Generic;
using Content.Server.GameObjects.Components.Chemistry;
using Content.Server.GameObjects.Components.Items.Storage;
using Content.Server.GameObjects.Components.Utensil;
using Content.Server.GameObjects.EntitySystems;
using Content.Server.Utility;

View File

@@ -1,6 +1,7 @@
using System;
using System.Collections.Generic;
using System.Linq;
using Content.Server.GameObjects.Components.Items.Storage;
using Content.Server.Interfaces.GameObjects.Components.Interaction;
using Content.Shared.GameObjects.Components.Nutrition;
using Robust.Server.GameObjects;

View File

@@ -4,6 +4,7 @@ using System.Collections;
using System.Collections.Generic;
using System.Linq;
using Content.Server.GameObjects.Components.Access;
using Content.Server.GameObjects.Components.Items.Storage;
using Content.Server.Interfaces.GameObjects.Components.Interaction;
using Content.Server.Interfaces;
using Content.Server.Interfaces.PDA;

View File

@@ -1,3 +1,4 @@
using Content.Server.GameObjects.Components.Items.Storage;
using Content.Server.Interfaces.GameObjects.Components.Interaction;
using Content.Server.Interfaces.GameObjects;
using Content.Shared.Audio;

View File

@@ -1,4 +1,5 @@
using System;
using Content.Server.GameObjects.Components.Items.Storage;
using Content.Server.GameObjects.Components.Power.ApcNetComponents;
using Content.Server.GameObjects.Components.Weapon.Ranged.Barrels;
using Content.Server.GameObjects.EntitySystems;

View File

@@ -1,4 +1,5 @@
using System;
using Content.Server.GameObjects.Components.Items.Storage;
using Content.Server.GameObjects.Components.Power.ApcNetComponents;
using Content.Server.GameObjects.Components.Sound;
using Content.Server.Interfaces.GameObjects.Components.Interaction;

View File

@@ -20,6 +20,7 @@ namespace Content.Server.GameObjects.Components.Strap
private StrapPosition _position;
private string _buckleSound;
private string _unbuckleSound;
private string _buckledIcon;
private int _rotation;
private int _size;
@@ -53,6 +54,12 @@ namespace Content.Server.GameObjects.Components.Strap
[ViewVariables]
public string UnbuckleSound => _unbuckleSound;
/// <summary>
/// The icon to be displayed as a status when buckled
/// </summary>
[ViewVariables]
public string BuckledIcon => _buckledIcon;
/// <summary>
/// The angle in degrees to rotate the player by when they get strapped
/// </summary>
@@ -123,6 +130,7 @@ namespace Content.Server.GameObjects.Components.Strap
serializer.DataField(ref _position, "position", StrapPosition.None);
serializer.DataField(ref _buckleSound, "buckleSound", "/Audio/Effects/buckle.ogg");
serializer.DataField(ref _unbuckleSound, "unbuckleSound", "/Audio/Effects/unbuckle.ogg");
serializer.DataField(ref _buckledIcon, "buckledIcon", "/Textures/Interface/StatusEffects/Buckle/buckled.png");
serializer.DataField(ref _rotation, "rotation", 0);
var defaultSize = 100;
@@ -154,6 +162,16 @@ namespace Content.Server.GameObjects.Components.Strap
return new StrapComponentState(Position);
}
bool IInteractHand.InteractHand(InteractHandEventArgs eventArgs)
{
if (!eventArgs.User.TryGetComponent(out BuckleComponent buckle))
{
return false;
}
return buckle.ToggleBuckle(eventArgs.User, Owner);
}
[Verb]
private sealed class StrapVerb : Verb<StrapComponent>
{
@@ -206,15 +224,5 @@ namespace Content.Server.GameObjects.Components.Strap
buckle.ToggleBuckle(user, component.Owner);
}
}
bool IInteractHand.InteractHand(InteractHandEventArgs eventArgs)
{
if (!eventArgs.User.TryGetComponent(out BuckleComponent buckle))
{
return false;
}
return buckle.ToggleBuckle(eventArgs.User, Owner);
}
}
}

View File

@@ -1,4 +1,5 @@
using System.Collections.Generic;
using Content.Server.GameObjects.Components.Items.Storage;
using Content.Server.GameObjects.Components.Mobs;
using Content.Server.GameObjects.Components.Power;
using Content.Server.GameObjects.EntitySystems.Click;

View File

@@ -1,5 +1,6 @@
using System;
using System.Collections.Generic;
using Content.Server.GameObjects.Components.Items.Storage;
using Content.Server.GameObjects.Components.Weapon.Ranged.Barrels;
using Content.Server.GameObjects.EntitySystems;
using Content.Server.Interfaces.GameObjects.Components.Interaction;

View File

@@ -1,5 +1,6 @@
using System;
using System.Collections.Generic;
using Content.Server.GameObjects.Components.Items.Storage;
using Content.Server.GameObjects.Components.Weapon.Ranged.Barrels;
using Content.Server.GameObjects.EntitySystems;
using Content.Server.Interfaces.GameObjects.Components.Interaction;

View File

@@ -1,4 +1,5 @@
using System.Collections.Generic;
using Content.Server.GameObjects.Components.Items.Storage;
using Content.Server.GameObjects.Components.Weapon.Ranged.Barrels;
using Content.Server.GameObjects.EntitySystems;
using Content.Server.Interfaces.GameObjects.Components.Interaction;

View File

@@ -1,5 +1,6 @@
using System;
using System.Collections.Generic;
using Content.Server.GameObjects.Components.Items.Storage;
using Content.Server.GameObjects.Components.Power;
using Content.Server.GameObjects.Components.Projectiles;
using Content.Server.GameObjects.Components.Sound;

View File

@@ -1,5 +1,6 @@
using System;
using System.Collections.Generic;
using Content.Server.GameObjects.Components.Items.Storage;
using Content.Server.GameObjects.Components.Weapon.Ranged.Ammunition;
using Content.Server.GameObjects.EntitySystems;
using Content.Server.Interfaces.GameObjects.Components.Interaction;

View File

@@ -0,0 +1,34 @@
using Content.Server.GameObjects.Components.Mobs;
using Content.Server.GameObjects.EntitySystems.Click;
using Robust.Server.GameObjects.EntitySystems;
using Robust.Shared.GameObjects;
using Robust.Shared.GameObjects.Systems;
namespace Content.Server.GameObjects.EntitySystems
{
public class BuckleSystem : EntitySystem
{
public override void Initialize()
{
base.Initialize();
EntityQuery = new TypeEntityQuery(typeof(BuckleComponent));
UpdatesAfter.Add(typeof(InteractionSystem));
UpdatesAfter.Add(typeof(InputSystem));
}
public override void Update(float frameTime)
{
foreach (var entity in RelevantEntities)
{
if (!entity.TryGetComponent(out BuckleComponent buckle))
{
continue;
}
buckle.Update();
}
}
}
}

View File

@@ -11,10 +11,9 @@ using Content.Shared.GameObjects.EntitySystems;
using Content.Shared.Input;
using JetBrains.Annotations;
using Robust.Server.GameObjects;
using Robust.Server.GameObjects.EntitySystems;
using Robust.Server.Interfaces.Player;
using Robust.Shared.Containers;
using Robust.Shared.GameObjects;
using Robust.Shared.GameObjects.Components;
using Robust.Shared.Input;
using Robust.Shared.Input.Binding;
using Robust.Shared.Interfaces.GameObjects;
@@ -266,6 +265,19 @@ namespace Content.Server.GameObjects.EntitySystems.Click
return;
}
// In a container where the attacked entity is not the container's owner
if (ContainerHelpers.TryGetContainer(player, out var playerContainer) &&
attacked != playerContainer.Owner)
{
// Either the attacked entity is null, not contained or in a different container
if (attacked == null ||
!ContainerHelpers.TryGetContainer(attacked, out var attackedContainer) ||
attackedContainer != playerContainer)
{
return;
}
}
// TODO: Check if client should be able to see that object to click on it in the first place
// Clicked on empty space behavior, try using ranged attack

View File

@@ -1,5 +1,6 @@
using System;
using System.Collections.Generic;
using Content.Server.GameObjects.Components;
using Content.Server.GameObjects.Components.Construction;
using Content.Server.GameObjects.Components.Interactable;
using Content.Server.GameObjects.Components.Stack;

View File

@@ -1,7 +1,5 @@
using System.Linq;
using Content.Server.GameObjects.Components.Stack;
using Content.Server.Interfaces;
using Content.Server.Interfaces.GameObjects;
using Content.Server.Throw;
using Content.Shared.GameObjects.Components.Inventory;
using Content.Shared.Input;
@@ -10,7 +8,6 @@ using Robust.Server.GameObjects.EntitySystemMessages;
using Robust.Server.Interfaces.Player;
using Robust.Shared.GameObjects;
using Robust.Shared.GameObjects.Systems;
using Robust.Shared.Input;
using Robust.Shared.Input.Binding;
using Robust.Shared.Interfaces.Map;
using Robust.Shared.IoC;
@@ -20,6 +17,7 @@ using Robust.Shared.Players;
using System;
using Content.Shared.GameObjects.EntitySystems;
using Content.Server.GameObjects;
using Content.Server.GameObjects.Components;
using Content.Server.GameObjects.EntitySystems.Click;
namespace Content.Server.Interfaces.GameObjects.Components.Interaction

View File

@@ -1,6 +1,7 @@
#nullable enable
using Content.Server.GameObjects;
using Content.Server.GameObjects.Components;
using Content.Server.GameObjects.Components.Items.Storage;
using Content.Server.GameObjects.Components.Mobs;
using Content.Server.GameObjects.Components.Movement;
using Content.Server.GameObjects.Components.Sound;

View File

@@ -4,13 +4,13 @@ using System.Linq;
using System.Threading;
using System.Threading.Tasks;
using Content.Server.GameObjects;
using Content.Server.GameObjects.Components;
using Content.Server.GameObjects.Components.Access;
using Content.Server.GameObjects.Components.Markers;
using Content.Server.GameObjects.Components.Mobs;
using Content.Server.GameObjects.Components.Observer;
using Content.Server.GameObjects.Components.PDA;
using Content.Server.Interfaces.GameObjects.Components.Interaction;
using Content.Server.GameObjects.EntitySystems;
using Content.Server.GameObjects.EntitySystems.AI.Pathfinding;
using Content.Server.GameTicking.GamePresets;
using Content.Server.Interfaces;
@@ -23,7 +23,6 @@ using Content.Shared;
using Content.Shared.Chat;
using Content.Shared.GameObjects.Components.PDA;
using Content.Shared.Jobs;
using Content.Shared.Physics;
using Content.Shared.Preferences;
using Prometheus;
using Robust.Server.Interfaces;
@@ -34,7 +33,6 @@ using Robust.Server.ServerStatus;
using Robust.Shared.Configuration;
using Robust.Shared.Enums;
using Robust.Shared.GameObjects;
using Robust.Shared.GameObjects.Components;
using Robust.Shared.GameObjects.Systems;
using Robust.Shared.Interfaces.Configuration;
using Robust.Shared.Interfaces.GameObjects;

View File

@@ -1,6 +1,6 @@
using System;
using System.Collections.Generic;
using Content.Server.GameObjects;
using Content.Server.GameObjects.Components;
using Content.Shared.GameObjects.EntitySystems;
using Robust.Server.GameObjects.Components.Container;
using Robust.Server.GameObjects.EntitySystemMessages;

View File

@@ -1,6 +1,7 @@
using System.Collections.Generic;
using System.Linq;
using Content.Server.GameObjects;
using Content.Server.GameObjects.Components;
using Content.Server.GameObjects.Components.Mobs;
using Content.Server.Interfaces.PDA;
using Content.Shared.GameObjects.Components.PDA;

View File

@@ -31,12 +31,14 @@ namespace Content.Shared.GameObjects.Components.Mobs
[Serializable, NetSerializable]
protected sealed class BuckleComponentState : ComponentState
{
public BuckleComponentState(bool buckled) : base(ContentNetIDs.BUCKLE)
public BuckleComponentState(bool buckled, int? drawDepth) : base(ContentNetIDs.BUCKLE)
{
Buckled = buckled;
DrawDepth = drawDepth;
}
public bool Buckled { get; }
public int? DrawDepth;
}
[Serializable, NetSerializable]

View File

@@ -254,4 +254,3 @@
- type: SpeciesVisualizer2D
- type: HumanoidAppearance