using Content.Shared.Actions.Behaviors;
using Content.Shared.Actions.Behaviors.Item;
using Content.Shared.Actions.Components;
using Content.Shared.Actions.Prototypes;
using Robust.Shared.GameObjects;
using Robust.Shared.Input.Binding;
using Robust.Shared.Map;
namespace Content.Shared.Actions
{
///
/// An attempt to perform a specific action. Main purpose of this interface is to
/// reduce code duplication related to handling attempts to perform non-item vs item actions by
/// providing a single interface for various functionality that needs to be performed on both.
///
public interface IActionAttempt
{
///
/// Action Prototype attempting to be performed
///
BaseActionPrototype Action { get; }
ComponentMessage PerformInstantActionMessage();
ComponentMessage PerformToggleActionMessage(bool on);
ComponentMessage PerformTargetPointActionMessage(PointerInputCmdHandler.PointerInputCmdArgs args);
ComponentMessage PerformTargetEntityActionMessage(PointerInputCmdHandler.PointerInputCmdArgs args);
///
/// Tries to get the action state for this action from the actionsComponent, returning
/// true if found.
///
bool TryGetActionState(SharedActionsComponent actionsComponent, out ActionState actionState);
///
/// Toggles the action within the provided action component
///
void ToggleAction(SharedActionsComponent actionsComponent, bool toggleOn);
///
/// Perform the server-side logic of the action
///
void DoInstantAction(IEntity player);
///
/// Perform the server-side logic of the toggle action
///
/// true if the attempt to toggle was successful, meaning the state should be toggled to the
/// indicated value
bool DoToggleAction(IEntity player, bool on);
///
/// Perform the server-side logic of the target point action
///
void DoTargetPointAction(IEntity player, EntityCoordinates target);
///
/// Perform the server-side logic of the target entity action
///
void DoTargetEntityAction(IEntity player, IEntity target);
}
public class ActionAttempt : IActionAttempt
{
private readonly ActionPrototype _action;
public BaseActionPrototype Action => _action;
public ActionAttempt(ActionPrototype action)
{
_action = action;
}
public bool TryGetActionState(SharedActionsComponent actionsComponent, out ActionState actionState)
{
return actionsComponent.TryGetActionState(_action.ActionType, out actionState);
}
public void ToggleAction(SharedActionsComponent actionsComponent, bool toggleOn)
{
actionsComponent.ToggleAction(_action.ActionType, toggleOn);
}
public void DoInstantAction(IEntity player)
{
_action.InstantAction.DoInstantAction(new InstantActionEventArgs(player, _action.ActionType));
}
public bool DoToggleAction(IEntity player, bool on)
{
return _action.ToggleAction.DoToggleAction(new ToggleActionEventArgs(player, _action.ActionType, on));
}
public void DoTargetPointAction(IEntity player, EntityCoordinates target)
{
_action.TargetPointAction.DoTargetPointAction(new TargetPointActionEventArgs(player, target, _action.ActionType));
}
public void DoTargetEntityAction(IEntity player, IEntity target)
{
_action.TargetEntityAction.DoTargetEntityAction(new TargetEntityActionEventArgs(player, _action.ActionType,
target));
}
public ComponentMessage PerformInstantActionMessage()
{
return new PerformInstantActionMessage(_action.ActionType);
}
public ComponentMessage PerformToggleActionMessage(bool toggleOn)
{
if (toggleOn)
{
return new PerformToggleOnActionMessage(_action.ActionType);
}
return new PerformToggleOffActionMessage(_action.ActionType);
}
public ComponentMessage PerformTargetPointActionMessage(PointerInputCmdHandler.PointerInputCmdArgs args)
{
return new PerformTargetPointActionMessage(_action.ActionType, args.Coordinates);
}
public ComponentMessage PerformTargetEntityActionMessage(PointerInputCmdHandler.PointerInputCmdArgs args)
{
return new PerformTargetEntityActionMessage(_action.ActionType, args.EntityUid);
}
public override string ToString()
{
return $"{nameof(_action)}: {_action.ActionType}";
}
}
public class ItemActionAttempt : IActionAttempt
{
private readonly ItemActionPrototype _action;
private readonly IEntity _item;
private readonly ItemActionsComponent _itemActions;
public BaseActionPrototype Action => _action;
public ItemActionAttempt(ItemActionPrototype action, IEntity item, ItemActionsComponent itemActions)
{
_action = action;
_item = item;
_itemActions = itemActions;
}
public void DoInstantAction(IEntity player)
{
_action.InstantAction.DoInstantAction(new InstantItemActionEventArgs(player, _item, _action.ActionType));
}
public bool DoToggleAction(IEntity player, bool on)
{
return _action.ToggleAction.DoToggleAction(new ToggleItemActionEventArgs(player, on, _item, _action.ActionType));
}
public void DoTargetPointAction(IEntity player, EntityCoordinates target)
{
_action.TargetPointAction.DoTargetPointAction(new TargetPointItemActionEventArgs(player, target, _item,
_action.ActionType));
}
public void DoTargetEntityAction(IEntity player, IEntity target)
{
_action.TargetEntityAction.DoTargetEntityAction(new TargetEntityItemActionEventArgs(player, target,
_item, _action.ActionType));
}
public bool TryGetActionState(SharedActionsComponent actionsComponent, out ActionState actionState)
{
return actionsComponent.TryGetItemActionState(_action.ActionType, _item, out actionState);
}
public void ToggleAction(SharedActionsComponent actionsComponent, bool toggleOn)
{
_itemActions.Toggle(_action.ActionType, toggleOn);
}
public ComponentMessage PerformInstantActionMessage()
{
return new PerformInstantItemActionMessage(_action.ActionType, _item.Uid);
}
public ComponentMessage PerformToggleActionMessage(bool toggleOn)
{
if (toggleOn)
{
return new PerformToggleOnItemActionMessage(_action.ActionType, _item.Uid);
}
return new PerformToggleOffItemActionMessage(_action.ActionType, _item.Uid);
}
public ComponentMessage PerformTargetPointActionMessage(PointerInputCmdHandler.PointerInputCmdArgs args)
{
return new PerformTargetPointItemActionMessage(_action.ActionType, _item.Uid, args.Coordinates);
}
public ComponentMessage PerformTargetEntityActionMessage(PointerInputCmdHandler.PointerInputCmdArgs args)
{
return new PerformTargetEntityItemActionMessage(_action.ActionType, _item.Uid, args.EntityUid);
}
public override string ToString()
{
return $"{nameof(_action)}: {_action.ActionType}, {nameof(_item)}: {_item}";
}
}
}