mirror of
https://github.com/space-wizards/RobustToolbox.git
synced 2026-09-15 14:52:35 +02:00
* Removed the EntitySystem event implementation, it now uses the more advanced EventBus. Removed EntitySystem.RegisterMessageTypes() function. Removed EntitySystem.SubscribeEvents() function. Added EntitySystemMessage.NetChannel field. This holds the remote net channel the event originated from. * Removed the Sender object from events. If you needed this field, add it to the event class. * Removed unused event proxy methods from Entity. SubscribeEvent() has been split into SubscribeNetworkEvent() and SubscribeLocalEvent() methods on EntitySystem. Most methods on EntityEventBus now require callers to specify the source (Local or Network) of the events.
140 lines
5.0 KiB
C#
140 lines
5.0 KiB
C#
using System;
|
|
using Robust.Client.GameObjects.Components;
|
|
using Robust.Client.Interfaces.Input;
|
|
using Robust.Client.Player;
|
|
using Robust.Shared.GameObjects;
|
|
using Robust.Shared.GameObjects.Systems;
|
|
using Robust.Shared.Input;
|
|
using Robust.Shared.Interfaces.GameObjects;
|
|
using Robust.Shared.IoC;
|
|
using Robust.Shared.Log;
|
|
using Robust.Shared.Players;
|
|
using Robust.Shared.Utility;
|
|
|
|
namespace Robust.Client.GameObjects.EntitySystems
|
|
{
|
|
/// <summary>
|
|
/// Client-side processing of all input commands through the simulation.
|
|
/// </summary>
|
|
public class InputSystem : EntitySystem
|
|
{
|
|
#pragma warning disable 649
|
|
[Dependency] private readonly IInputManager _inputManager;
|
|
[Dependency] private readonly IPlayerManager _playerManager;
|
|
#pragma warning restore 649
|
|
|
|
private readonly IPlayerCommandStates _cmdStates = new PlayerCommandStates();
|
|
private readonly CommandBindMapping _bindMap = new CommandBindMapping();
|
|
|
|
/// <summary>
|
|
/// Current states for all of the keyFunctions.
|
|
/// </summary>
|
|
public IPlayerCommandStates CmdStates => _cmdStates;
|
|
|
|
/// <summary>
|
|
/// Holds the keyFunction -> handler bindings for the simulation.
|
|
/// </summary>
|
|
public ICommandBindMapping BindMap => _bindMap;
|
|
|
|
/// <summary>
|
|
/// Inserts an Input Command into the simulation.
|
|
/// </summary>
|
|
/// <param name="session">Player session that raised the command. On client, this is always the LocalPlayer session.</param>
|
|
/// <param name="function">Function that is being changed.</param>
|
|
/// <param name="message">Arguments for this event.</param>
|
|
public void HandleInputCommand(ICommonSession session, BoundKeyFunction function, FullInputCmdMessage message)
|
|
{
|
|
#if DEBUG
|
|
|
|
var funcId = _inputManager.NetworkBindMap.KeyFunctionID(function);
|
|
DebugTools.Assert(funcId == message.InputFunctionId, "Function ID in message does not match function.");
|
|
|
|
#endif
|
|
|
|
// set state, state change is updated regardless if it is locally bound
|
|
_cmdStates.SetState(function, message.State);
|
|
|
|
// handle local binds before sending off
|
|
if (_bindMap.TryGetHandler(function, out var handler))
|
|
{
|
|
// local handlers can block sending over the network.
|
|
if (handler.HandleCmdMessage(session, message))
|
|
return;
|
|
}
|
|
|
|
RaiseNetworkEvent(message);
|
|
}
|
|
|
|
public override void Initialize()
|
|
{
|
|
SubscribeLocalEvent<PlayerAttachSysMessage>(OnAttachedEntityChanged);
|
|
}
|
|
|
|
private void OnAttachedEntityChanged(PlayerAttachSysMessage message)
|
|
{
|
|
if (message.AttachedEntity != null) // attach
|
|
{
|
|
SetEntityContextActive(_inputManager, message.AttachedEntity);
|
|
}
|
|
else // detach
|
|
{
|
|
_inputManager.Contexts.SetActiveContext(InputContextContainer.DefaultContextName);
|
|
}
|
|
}
|
|
|
|
private static void SetEntityContextActive(IInputManager inputMan, IEntity entity)
|
|
{
|
|
if(entity == null || !entity.IsValid())
|
|
throw new ArgumentNullException(nameof(entity));
|
|
|
|
if (!entity.TryGetComponent(out InputComponent inputComp))
|
|
{
|
|
Logger.DebugS("input.context", $"AttachedEnt has no InputComponent: entId={entity.Uid}, entProto={entity.Prototype}");
|
|
return;
|
|
}
|
|
|
|
if (inputMan.Contexts.Exists(inputComp.ContextName))
|
|
{
|
|
inputMan.Contexts.SetActiveContext(inputComp.ContextName);
|
|
}
|
|
else
|
|
{
|
|
Logger.ErrorS("input.context", $"Unknown context: entId={entity.Uid}, entProto={entity.Prototype}, context={inputComp.ContextName}");
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Sets the active context to the defined context on the attached entity.
|
|
/// </summary>
|
|
public void SetEntityContextActive()
|
|
{
|
|
if (_playerManager.LocalPlayer.ControlledEntity == null)
|
|
{
|
|
return;
|
|
}
|
|
|
|
SetEntityContextActive(_inputManager, _playerManager.LocalPlayer.ControlledEntity);
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Entity system message that is raised when the player changes attached entities.
|
|
/// </summary>
|
|
public class PlayerAttachSysMessage : EntitySystemMessage
|
|
{
|
|
/// <summary>
|
|
/// New entity the player is attached to.
|
|
/// </summary>
|
|
public IEntity AttachedEntity { get; }
|
|
|
|
/// <summary>
|
|
/// Creates a new instance of <see cref="PlayerAttachSysMessage"/>.
|
|
/// </summary>
|
|
/// <param name="attachedEntity">New entity the player is attached to.</param>
|
|
public PlayerAttachSysMessage(IEntity attachedEntity)
|
|
{
|
|
AttachedEntity = attachedEntity;
|
|
}
|
|
}
|
|
}
|