Merge branch 'master' into DecimalReagents
This commit is contained in:
@@ -288,7 +288,7 @@ namespace Content.Client.Chat
|
||||
WriteChatMessage(storedMessage);
|
||||
|
||||
// Local messages that have an entity attached get a speech bubble.
|
||||
if (msg.Channel == ChatChannel.Local && msg.SenderEntity != default)
|
||||
if ((msg.Channel == ChatChannel.Local || msg.Channel == ChatChannel.Dead) && msg.SenderEntity != default)
|
||||
{
|
||||
AddSpeechBubble(msg);
|
||||
}
|
||||
|
||||
@@ -0,0 +1,99 @@
|
||||
using Content.Client.UserInterface;
|
||||
using Content.Shared.GameObjects.Components.Observer;
|
||||
using Robust.Client.GameObjects;
|
||||
using Robust.Client.Player;
|
||||
using Robust.Shared.GameObjects;
|
||||
using Robust.Shared.Interfaces.GameObjects;
|
||||
using Robust.Shared.Interfaces.Network;
|
||||
using Robust.Shared.IoC;
|
||||
using Robust.Shared.ViewVariables;
|
||||
|
||||
namespace Content.Client.GameObjects.Components.Observer
|
||||
{
|
||||
[RegisterComponent]
|
||||
public class GhostComponent : SharedGhostComponent
|
||||
{
|
||||
private GhostGui _gui;
|
||||
|
||||
[ViewVariables(VVAccess.ReadOnly)]
|
||||
public bool CanReturnToBody { get; private set; } = true;
|
||||
|
||||
#pragma warning disable 649
|
||||
[Dependency] private readonly IGameHud _gameHud;
|
||||
[Dependency] private readonly IPlayerManager _playerManager;
|
||||
[Dependency] private IComponentManager _componentManager;
|
||||
#pragma warning restore 649
|
||||
|
||||
public override void OnRemove()
|
||||
{
|
||||
base.OnRemove();
|
||||
|
||||
_gui?.Dispose();
|
||||
}
|
||||
|
||||
|
||||
private void SetGhostVisibility(bool visibility)
|
||||
{
|
||||
// So, for now this is a client-side hack... Please, PLEASE someone make this work server-side.
|
||||
foreach (var ghost in _componentManager.GetAllComponents(typeof(GhostComponent)))
|
||||
{
|
||||
if (ghost.Owner.TryGetComponent(out SpriteComponent component))
|
||||
component.Visible = visibility;
|
||||
}
|
||||
}
|
||||
|
||||
public override void Initialize()
|
||||
{
|
||||
base.Initialize();
|
||||
|
||||
if (Owner.TryGetComponent(out SpriteComponent component))
|
||||
component.Visible = _playerManager.LocalPlayer.ControlledEntity?.HasComponent<GhostComponent>() ?? false;
|
||||
}
|
||||
|
||||
public override void HandleMessage(ComponentMessage message, INetChannel netChannel = null,
|
||||
IComponent component = null)
|
||||
{
|
||||
base.HandleMessage(message, netChannel, component);
|
||||
|
||||
switch (message)
|
||||
{
|
||||
case PlayerAttachedMsg _:
|
||||
if (_gui == null)
|
||||
{
|
||||
_gui = new GhostGui(this);
|
||||
}
|
||||
else
|
||||
{
|
||||
_gui.Orphan();
|
||||
}
|
||||
|
||||
_gameHud.HandsContainer.AddChild(_gui);
|
||||
SetGhostVisibility(true);
|
||||
|
||||
break;
|
||||
|
||||
case PlayerDetachedMsg _:
|
||||
_gui.Parent?.RemoveChild(_gui);
|
||||
SetGhostVisibility(false);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
public void SendReturnToBodyMessage() => SendNetworkMessage(new ReturnToBodyComponentMessage());
|
||||
|
||||
public override void HandleComponentState(ComponentState curState, ComponentState nextState)
|
||||
{
|
||||
base.HandleComponentState(curState, nextState);
|
||||
|
||||
if (!(curState is GhostComponentState state)) return;
|
||||
|
||||
CanReturnToBody = state.CanReturnToBody;
|
||||
|
||||
if (Owner == _playerManager.LocalPlayer.ControlledEntity)
|
||||
{
|
||||
_gui?.Update();
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
34
Content.Client/UserInterface/GhostGui.cs
Normal file
34
Content.Client/UserInterface/GhostGui.cs
Normal file
@@ -0,0 +1,34 @@
|
||||
using System.Data;
|
||||
using Content.Client.GameObjects.Components.Observer;
|
||||
using Robust.Client.UserInterface;
|
||||
using Robust.Client.UserInterface.Controls;
|
||||
using Robust.Shared.IoC;
|
||||
|
||||
namespace Content.Client.UserInterface
|
||||
{
|
||||
public class GhostGui : Control
|
||||
{
|
||||
public Button ReturnToBody = new Button(){Text = "Return to body"};
|
||||
private GhostComponent _owner;
|
||||
|
||||
public GhostGui(GhostComponent owner)
|
||||
{
|
||||
IoCManager.InjectDependencies(this);
|
||||
|
||||
_owner = owner;
|
||||
|
||||
MouseFilter = MouseFilterMode.Ignore;
|
||||
|
||||
ReturnToBody.OnPressed += (args) => { owner.SendReturnToBodyMessage(); };
|
||||
|
||||
AddChild(ReturnToBody);
|
||||
|
||||
Update();
|
||||
}
|
||||
|
||||
public void Update()
|
||||
{
|
||||
ReturnToBody.Disabled = !_owner.CanReturnToBody;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -4,6 +4,7 @@ using Content.Server.GameTicking;
|
||||
using Content.Server.Interfaces.GameTicking;
|
||||
using Content.Shared;
|
||||
using Robust.Server.Interfaces.Player;
|
||||
using Robust.Shared.Map;
|
||||
using Robust.Shared.Timing;
|
||||
|
||||
namespace Content.IntegrationTests
|
||||
@@ -54,6 +55,10 @@ namespace Content.IntegrationTests
|
||||
{
|
||||
}
|
||||
|
||||
public GridCoordinates GetLateJoinSpawnPoint() => GridCoordinates.InvalidGrid;
|
||||
public GridCoordinates GetJobSpawnPoint(string jobId) => GridCoordinates.InvalidGrid;
|
||||
public GridCoordinates GetObserverSpawnPoint() => GridCoordinates.InvalidGrid;
|
||||
|
||||
public T AddGameRule<T>() where T : GameRule, new()
|
||||
{
|
||||
return new T();
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
using Content.Server.Players;
|
||||
using Content.Server.GameObjects.Components.Observer;
|
||||
using Content.Server.Players;
|
||||
using Robust.Server.Interfaces.Console;
|
||||
using Robust.Server.Interfaces.Player;
|
||||
using Robust.Shared.Interfaces.GameObjects;
|
||||
@@ -30,10 +31,14 @@ namespace Content.Server.Administration
|
||||
}
|
||||
else
|
||||
{
|
||||
var canReturn = mind.CurrentEntity != null && !mind.CurrentEntity.HasComponent<GhostComponent>();
|
||||
var entityManager = IoCManager.Resolve<IEntityManager>();
|
||||
var ghost = entityManager.SpawnEntity("AdminObserver", player.AttachedEntity.Transform.GridPosition);
|
||||
|
||||
mind.Visit(ghost);
|
||||
if(canReturn)
|
||||
mind.Visit(ghost);
|
||||
else
|
||||
mind.TransferTo(ghost);
|
||||
ghost.GetComponent<GhostComponent>().CanReturnToBody = canReturn;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,4 +1,6 @@
|
||||
using Content.Server.Interfaces.Chat;
|
||||
using Content.Server.GameObjects.Components.Observer;
|
||||
using Content.Server.Interfaces.Chat;
|
||||
using Content.Server.Observer;
|
||||
using Robust.Server.Interfaces.Console;
|
||||
using Robust.Server.Interfaces.Player;
|
||||
using Robust.Shared.Enums;
|
||||
@@ -24,7 +26,10 @@ namespace Content.Server.Chat
|
||||
|
||||
var message = string.Join(" ", args);
|
||||
|
||||
chat.EntitySay(player.AttachedEntity, message);
|
||||
if (player.AttachedEntity.HasComponent<GhostComponent>())
|
||||
chat.SendDeadChat(player, message);
|
||||
else
|
||||
chat.EntitySay(player.AttachedEntity, message);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,12 +1,17 @@
|
||||
using System.Linq;
|
||||
using Content.Server.GameObjects.Components.Observer;
|
||||
using Content.Server.GameObjects.EntitySystems;
|
||||
using Content.Server.Interfaces;
|
||||
using Content.Server.Interfaces.Chat;
|
||||
using Content.Server.Observer;
|
||||
using Content.Server.Players;
|
||||
using Content.Shared.Chat;
|
||||
using Robust.Server.Interfaces.Player;
|
||||
using Robust.Shared.Interfaces.GameObjects;
|
||||
using Robust.Shared.Interfaces.Network;
|
||||
using Robust.Shared.IoC;
|
||||
using Robust.Shared.Localization;
|
||||
using Robust.Shared.Log;
|
||||
|
||||
namespace Content.Server.Chat
|
||||
{
|
||||
@@ -20,6 +25,7 @@ namespace Content.Server.Chat
|
||||
#pragma warning disable 649
|
||||
[Dependency] private readonly IServerNetManager _netManager;
|
||||
[Dependency] private readonly IPlayerManager _playerManager;
|
||||
[Dependency] private readonly ILocalizationManager _localizationManager;
|
||||
[Dependency] private readonly IMoMMILink _mommiLink;
|
||||
#pragma warning restore 649
|
||||
|
||||
@@ -93,6 +99,18 @@ namespace Content.Server.Chat
|
||||
_mommiLink.SendOOCMessage(player.SessionId.ToString(), message);
|
||||
}
|
||||
|
||||
public void SendDeadChat(IPlayerSession player, string message)
|
||||
{
|
||||
var clients = _playerManager.GetPlayersBy(x => x.AttachedEntity != null && x.AttachedEntity.HasComponent<GhostComponent>()).Select(p => p.ConnectedClient);;
|
||||
|
||||
var msg = _netManager.CreateNetMessage<MsgChatMessage>();
|
||||
msg.Channel = ChatChannel.Dead;
|
||||
msg.Message = message;
|
||||
msg.MessageWrap = $"{_localizationManager.GetString("DEAD")}: {player.AttachedEntity.Name}: {{0}}";
|
||||
msg.SenderEntity = player.AttachedEntityUid.GetValueOrDefault();
|
||||
_netManager.ServerSendToMany(msg, clients.ToList());
|
||||
}
|
||||
|
||||
public void SendHookOOC(string sender, string message)
|
||||
{
|
||||
var msg = _netManager.CreateNetMessage<MsgChatMessage>();
|
||||
|
||||
@@ -75,7 +75,13 @@ namespace Content.Server.GameObjects
|
||||
{
|
||||
if (damageType == DamageType.Total)
|
||||
{
|
||||
throw new ArgumentException("Cannot take damage for DamageType.Total");
|
||||
foreach (DamageType e in Enum.GetValues(typeof(DamageType)))
|
||||
{
|
||||
if (e == damageType) continue;
|
||||
TakeDamage(e, amount, source, sourceMob);
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
InitializeDamageType(damageType);
|
||||
|
||||
|
||||
@@ -38,5 +38,6 @@ namespace Content.Server.GameObjects.Components.Markers
|
||||
Unset = 0,
|
||||
LateJoin,
|
||||
Job,
|
||||
Observer,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,66 @@
|
||||
using Content.Server.GameObjects.EntitySystems;
|
||||
using Content.Server.Players;
|
||||
using Content.Shared.GameObjects.Components.Observer;
|
||||
using Robust.Server.GameObjects;
|
||||
using Robust.Server.Interfaces.GameObjects;
|
||||
using Robust.Shared.GameObjects;
|
||||
using Robust.Shared.Interfaces.GameObjects;
|
||||
using Robust.Shared.Interfaces.Network;
|
||||
using Robust.Shared.ViewVariables;
|
||||
using Timer = Robust.Shared.Timers.Timer;
|
||||
|
||||
|
||||
namespace Content.Server.GameObjects.Components.Observer
|
||||
{
|
||||
[RegisterComponent]
|
||||
public class GhostComponent : SharedGhostComponent, IActionBlocker
|
||||
{
|
||||
private bool _canReturnToBody = true;
|
||||
|
||||
[ViewVariables(VVAccess.ReadWrite)]
|
||||
public bool CanReturnToBody
|
||||
{
|
||||
get => _canReturnToBody;
|
||||
set
|
||||
{
|
||||
_canReturnToBody = value;
|
||||
Dirty();
|
||||
}
|
||||
}
|
||||
|
||||
public override ComponentState GetComponentState() => new GhostComponentState(CanReturnToBody);
|
||||
|
||||
public override void HandleMessage(ComponentMessage message, INetChannel netChannel = null,
|
||||
IComponent component = null)
|
||||
{
|
||||
base.HandleMessage(message, netChannel, component);
|
||||
|
||||
switch (message)
|
||||
{
|
||||
case ReturnToBodyComponentMessage reenter:
|
||||
if (!Owner.TryGetComponent(out IActorComponent actor) || !CanReturnToBody) break;
|
||||
if (netChannel == null || netChannel == actor.playerSession.ConnectedClient)
|
||||
{
|
||||
actor.playerSession.ContentData().Mind.UnVisit();
|
||||
}
|
||||
break;
|
||||
case PlayerAttachedMsg _:
|
||||
Dirty();
|
||||
break;
|
||||
case PlayerDetachedMsg _:
|
||||
Timer.Spawn(100, Owner.Delete);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
public bool CanInteract() => false;
|
||||
public bool CanUse() => false;
|
||||
public bool CanThrow() => false;
|
||||
public bool CanDrop() => false;
|
||||
public bool CanPickup() => false;
|
||||
public bool CanEmote() => false;
|
||||
public bool CanAttack() => false;
|
||||
}
|
||||
}
|
||||
@@ -5,23 +5,23 @@ namespace Content.Server.GameObjects.EntitySystems
|
||||
{
|
||||
public interface IActionBlocker
|
||||
{
|
||||
bool CanMove();
|
||||
bool CanMove() => true;
|
||||
|
||||
bool CanInteract();
|
||||
bool CanInteract() => true;
|
||||
|
||||
bool CanUse();
|
||||
bool CanUse() => true;
|
||||
|
||||
bool CanThrow();
|
||||
bool CanThrow() => true;
|
||||
|
||||
bool CanSpeak();
|
||||
bool CanSpeak() => true;
|
||||
|
||||
bool CanDrop();
|
||||
bool CanDrop() => true;
|
||||
|
||||
bool CanPickup();
|
||||
bool CanPickup() => true;
|
||||
|
||||
bool CanEmote();
|
||||
bool CanEmote() => true;
|
||||
|
||||
bool CanAttack();
|
||||
bool CanAttack() => true;
|
||||
}
|
||||
|
||||
public class ActionBlockerSystem : EntitySystem
|
||||
|
||||
@@ -3,12 +3,14 @@ using Content.Server.GameObjects.Components.Mobs;
|
||||
using Content.Server.GameObjects.Components.Movement;
|
||||
using Content.Server.GameObjects.Components.Sound;
|
||||
using Content.Server.Interfaces.GameObjects.Components.Movement;
|
||||
using Content.Server.Observer;
|
||||
using Content.Shared.Audio;
|
||||
using Content.Shared.GameObjects.Components.Inventory;
|
||||
using Content.Shared.Maps;
|
||||
using JetBrains.Annotations;
|
||||
using Robust.Server.GameObjects;
|
||||
using Robust.Server.GameObjects.EntitySystems;
|
||||
using Robust.Server.Interfaces.GameObjects;
|
||||
using Robust.Server.Interfaces.Player;
|
||||
using Robust.Server.Interfaces.Timing;
|
||||
using Robust.Shared.Configuration;
|
||||
@@ -25,6 +27,7 @@ using Robust.Shared.IoC;
|
||||
using Robust.Shared.Log;
|
||||
using Robust.Shared.Map;
|
||||
using Robust.Shared.Maths;
|
||||
using Robust.Shared.Network;
|
||||
using Robust.Shared.Players;
|
||||
using Robust.Shared.Prototypes;
|
||||
using Robust.Shared.Random;
|
||||
@@ -138,6 +141,7 @@ namespace Content.Server.GameObjects.EntitySystems
|
||||
{
|
||||
if (physics.LinearVelocity != Vector2.Zero)
|
||||
physics.LinearVelocity = Vector2.Zero;
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -185,6 +189,11 @@ namespace Content.Server.GameObjects.EntitySystems
|
||||
if (!TryGetAttachedComponent(session as IPlayerSession, out IMoverComponent moverComp))
|
||||
return;
|
||||
|
||||
var owner = (session as IPlayerSession)?.AttachedEntity;
|
||||
|
||||
if (owner != null && owner.TryGetComponent(out SpeciesComponent species) && species.CurrentDamageState is DeadState)
|
||||
new Ghost().Execute(null, (IPlayerSession)session, null);
|
||||
|
||||
moverComp.SetVelocityDirection(dir, state);
|
||||
}
|
||||
|
||||
|
||||
@@ -273,7 +273,7 @@ namespace Content.Server.GameTicking
|
||||
|
||||
private IEntity _spawnPlayerMob(Job job, bool lateJoin = true)
|
||||
{
|
||||
GridCoordinates coordinates = lateJoin ? _getLateJoinSpawnPoint() : _getJobSpawnPoint(job.Prototype.ID);
|
||||
GridCoordinates coordinates = lateJoin ? GetLateJoinSpawnPoint() : GetJobSpawnPoint(job.Prototype.ID);
|
||||
var entity = _entityManager.SpawnEntity(PlayerPrototypeName, coordinates);
|
||||
if (entity.TryGetComponent(out InventoryComponent inventory))
|
||||
{
|
||||
@@ -299,11 +299,11 @@ namespace Content.Server.GameTicking
|
||||
|
||||
private IEntity _spawnObserverMob()
|
||||
{
|
||||
GridCoordinates coordinates = _getLateJoinSpawnPoint();
|
||||
var coordinates = GetObserverSpawnPoint();
|
||||
return _entityManager.SpawnEntity(ObserverPrototypeName, coordinates);
|
||||
}
|
||||
|
||||
private GridCoordinates _getLateJoinSpawnPoint()
|
||||
public GridCoordinates GetLateJoinSpawnPoint()
|
||||
{
|
||||
var location = _spawnPoint;
|
||||
|
||||
@@ -319,7 +319,7 @@ namespace Content.Server.GameTicking
|
||||
return location;
|
||||
}
|
||||
|
||||
private GridCoordinates _getJobSpawnPoint(string jobId)
|
||||
public GridCoordinates GetJobSpawnPoint(string jobId)
|
||||
{
|
||||
var location = _spawnPoint;
|
||||
|
||||
@@ -336,6 +336,23 @@ namespace Content.Server.GameTicking
|
||||
return location;
|
||||
}
|
||||
|
||||
public GridCoordinates GetObserverSpawnPoint()
|
||||
{
|
||||
var location = _spawnPoint;
|
||||
|
||||
var possiblePoints = new List<GridCoordinates>();
|
||||
foreach (var entity in _entityManager.GetEntities(new TypeEntityQuery(typeof(SpawnPointComponent))))
|
||||
{
|
||||
var point = entity.GetComponent<SpawnPointComponent>();
|
||||
if (point.SpawnType == SpawnPointType.Observer)
|
||||
possiblePoints.Add(entity.Transform.GridPosition);
|
||||
}
|
||||
|
||||
if (possiblePoints.Count != 0) location = _robustRandom.Pick(possiblePoints);
|
||||
|
||||
return location;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Cleanup that has to run to clear up anything from the previous round.
|
||||
/// Stuff like wiping the previous map clean.
|
||||
|
||||
@@ -18,6 +18,7 @@ namespace Content.Server.Interfaces.Chat
|
||||
void EntityMe(IEntity source, string action);
|
||||
|
||||
void SendOOC(IPlayerSession player, string message);
|
||||
void SendDeadChat(IPlayerSession player, string message);
|
||||
|
||||
void SendHookOOC(string sender, string message);
|
||||
}
|
||||
|
||||
@@ -2,6 +2,7 @@ using System;
|
||||
using System.Collections.Generic;
|
||||
using Content.Server.GameTicking;
|
||||
using Robust.Server.Interfaces.Player;
|
||||
using Robust.Shared.Map;
|
||||
using Robust.Shared.Timing;
|
||||
|
||||
namespace Content.Server.Interfaces.GameTicking
|
||||
@@ -27,6 +28,10 @@ namespace Content.Server.Interfaces.GameTicking
|
||||
void MakeJoinGame(IPlayerSession player);
|
||||
void ToggleReady(IPlayerSession player, bool ready);
|
||||
|
||||
GridCoordinates GetLateJoinSpawnPoint();
|
||||
GridCoordinates GetJobSpawnPoint(string jobId);
|
||||
GridCoordinates GetObserverSpawnPoint();
|
||||
|
||||
// GameRule system.
|
||||
T AddGameRule<T>() where T : GameRule, new();
|
||||
void RemoveGameRule(GameRule rule);
|
||||
|
||||
74
Content.Server/Observer/Ghost.cs
Normal file
74
Content.Server/Observer/Ghost.cs
Normal file
@@ -0,0 +1,74 @@
|
||||
using Content.Server.GameObjects;
|
||||
using Content.Server.GameObjects.Components.Observer;
|
||||
using Content.Server.GameObjects.EntitySystems;
|
||||
using Content.Server.Interfaces.GameTicking;
|
||||
using Content.Server.Players;
|
||||
using Content.Shared.GameObjects;
|
||||
using Robust.Server.Interfaces.Console;
|
||||
using Robust.Server.Interfaces.Player;
|
||||
using Robust.Shared.Interfaces.GameObjects;
|
||||
using Robust.Shared.IoC;
|
||||
using Robust.Shared.Log;
|
||||
using Robust.Shared.Map;
|
||||
|
||||
namespace Content.Server.Observer
|
||||
{
|
||||
public class Ghost : IClientCommand
|
||||
{
|
||||
public string Command => "ghost";
|
||||
public string Description => "Give up on life and become a ghost.";
|
||||
public string Help => "ghost";
|
||||
|
||||
public void Execute(IConsoleShell shell, IPlayerSession player, string[] args)
|
||||
{
|
||||
if (player == null)
|
||||
{
|
||||
shell.SendText((IPlayerSession) null, "Nah");
|
||||
return;
|
||||
}
|
||||
|
||||
var mind = player.ContentData().Mind;
|
||||
var canReturn = player.AttachedEntity != null;
|
||||
var name = player.AttachedEntity?.Name ?? player.Name;
|
||||
|
||||
if (player.AttachedEntity != null && player.AttachedEntity.HasComponent<GhostComponent>())
|
||||
return;
|
||||
|
||||
if (mind.VisitingEntity != null)
|
||||
{
|
||||
mind.UnVisit();
|
||||
}
|
||||
|
||||
var position = player.AttachedEntity?.Transform.GridPosition ?? IoCManager.Resolve<IGameTicker>().GetObserverSpawnPoint();
|
||||
|
||||
if (canReturn && player.AttachedEntity.TryGetComponent(out SpeciesComponent species))
|
||||
{
|
||||
switch (species.CurrentDamageState)
|
||||
{
|
||||
case DeadState _:
|
||||
canReturn = true;
|
||||
break;
|
||||
case CriticalState _:
|
||||
canReturn = true;
|
||||
if (!player.AttachedEntity.TryGetComponent(out DamageableComponent damageable)) break;
|
||||
damageable.TakeDamage(DamageType.Total, 100); // TODO: Use airloss/oxyloss instead
|
||||
break;
|
||||
default:
|
||||
canReturn = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
var entityManager = IoCManager.Resolve<IEntityManager>();
|
||||
var ghost = entityManager.SpawnEntity("MobObserver", position);
|
||||
ghost.Name = name;
|
||||
var ghostComponent = ghost.GetComponent<GhostComponent>();
|
||||
ghostComponent.CanReturnToBody = canReturn;
|
||||
|
||||
if(canReturn)
|
||||
mind.Visit(ghost);
|
||||
else
|
||||
mind.TransferTo(ghost);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -6,7 +6,7 @@ namespace Content.Shared.Chat
|
||||
/// Represents chat channels that the player can filter chat tabs by.
|
||||
/// </summary>
|
||||
[Flags]
|
||||
public enum ChatChannel : byte
|
||||
public enum ChatChannel : short
|
||||
{
|
||||
None = 0,
|
||||
|
||||
@@ -46,9 +46,14 @@ namespace Content.Shared.Chat
|
||||
/// </summary>
|
||||
Emotes = 64,
|
||||
|
||||
/// <summary>
|
||||
/// Deadchat
|
||||
/// </summary>
|
||||
Dead = 128,
|
||||
|
||||
/// <summary>
|
||||
/// Unspecified.
|
||||
/// </summary>
|
||||
Unspecified = 128,
|
||||
Unspecified = 256,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -35,7 +35,7 @@ namespace Content.Shared.Chat
|
||||
|
||||
/// <summary>
|
||||
/// The sending entity.
|
||||
/// Only applies to <see cref="ChatChannel.Local"/> and <see cref="ChatChannel.Emotes"/>.
|
||||
/// Only applies to <see cref="ChatChannel.Local"/>, <see cref="ChatChannel.Dead"/> and <see cref="ChatChannel.Emotes"/>.
|
||||
/// </summary>
|
||||
public EntityUid SenderEntity { get; set; }
|
||||
|
||||
@@ -48,6 +48,7 @@ namespace Content.Shared.Chat
|
||||
switch (Channel)
|
||||
{
|
||||
case ChatChannel.Local:
|
||||
case ChatChannel.Dead:
|
||||
case ChatChannel.Emotes:
|
||||
SenderEntity = buffer.ReadEntityUid();
|
||||
break;
|
||||
@@ -63,6 +64,7 @@ namespace Content.Shared.Chat
|
||||
switch (Channel)
|
||||
{
|
||||
case ChatChannel.Local:
|
||||
case ChatChannel.Dead:
|
||||
case ChatChannel.Emotes:
|
||||
buffer.Write(SenderEntity);
|
||||
break;
|
||||
|
||||
@@ -0,0 +1,29 @@
|
||||
using System;
|
||||
using Robust.Shared.GameObjects;
|
||||
using Robust.Shared.Serialization;
|
||||
|
||||
namespace Content.Shared.GameObjects.Components.Observer
|
||||
{
|
||||
public class SharedGhostComponent : Component
|
||||
{
|
||||
public override string Name => "Ghost";
|
||||
public override uint? NetID => ContentNetIDs.GHOST;
|
||||
}
|
||||
|
||||
[Serializable, NetSerializable]
|
||||
public class GhostComponentState : ComponentState
|
||||
{
|
||||
public bool CanReturnToBody { get; }
|
||||
|
||||
public GhostComponentState(bool canReturnToBody) : base(ContentNetIDs.GHOST)
|
||||
{
|
||||
CanReturnToBody = canReturnToBody;
|
||||
}
|
||||
}
|
||||
|
||||
[Serializable, NetSerializable]
|
||||
public class ReturnToBodyComponentMessage : ComponentMessage
|
||||
{
|
||||
public ReturnToBodyComponentMessage() => Directed = true;
|
||||
}
|
||||
}
|
||||
@@ -41,5 +41,6 @@
|
||||
public const uint HANDHELD_LIGHT = 1036;
|
||||
public const uint PAPER = 1037;
|
||||
public const uint REAGENT_INJECTOR = 1038;
|
||||
public const uint GHOST = 1039;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -11,6 +11,7 @@
|
||||
- ooc
|
||||
- observe
|
||||
- toggleready
|
||||
- ghost
|
||||
|
||||
- Index: 50
|
||||
Name: Moderator
|
||||
@@ -26,6 +27,7 @@
|
||||
- showtime
|
||||
- observe
|
||||
- toggleready
|
||||
- ghost
|
||||
- kick
|
||||
- listplayers
|
||||
- loc
|
||||
@@ -44,6 +46,7 @@
|
||||
- aghost
|
||||
- observe
|
||||
- toggleready
|
||||
- ghost
|
||||
- spawn
|
||||
- delete
|
||||
- tp
|
||||
@@ -84,6 +87,7 @@
|
||||
- aghost
|
||||
- observe
|
||||
- toggleready
|
||||
- ghost
|
||||
- spawn
|
||||
- delete
|
||||
- tp
|
||||
|
||||
@@ -15,3 +15,8 @@
|
||||
- type: Examiner
|
||||
DoRangeCheck: false
|
||||
- type: IgnorePause
|
||||
- type: Ghost
|
||||
- type: Sprite
|
||||
netsync: false
|
||||
drawdepth: Mobs
|
||||
texture: Mob/observer.png
|
||||
|
||||
Submodule RobustToolbox updated: ec52102d02...1cdb279319
Reference in New Issue
Block a user