diff --git a/Content.Client/EntryPoint.cs b/Content.Client/EntryPoint.cs
index 8453efe74c..23be4fd207 100644
--- a/Content.Client/EntryPoint.cs
+++ b/Content.Client/EntryPoint.cs
@@ -110,6 +110,7 @@ namespace Content.Client
"Airlock",
"MedicalScanner",
"WirePlacer",
+ "Species",
};
foreach (var ignoreName in registerIgnore)
diff --git a/Content.Client/GameObjects/Components/Mobs/ClientOverlayEffectsComponent.cs b/Content.Client/GameObjects/Components/Mobs/ClientOverlayEffectsComponent.cs
new file mode 100644
index 0000000000..79f0ed6549
--- /dev/null
+++ b/Content.Client/GameObjects/Components/Mobs/ClientOverlayEffectsComponent.cs
@@ -0,0 +1,107 @@
+using System.Collections.Generic;
+using Content.Client.Graphics.Overlays;
+using Content.Shared.GameObjects.Components.Mobs;
+using Robust.Client.GameObjects;
+using Robust.Client.Graphics.Overlays;
+using Robust.Client.Interfaces.Graphics.Overlays;
+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.Log;
+
+namespace Content.Client.GameObjects
+{
+ ///
+ /// A character UI component which shows the current damage state of the mob (living/dead)
+ ///
+ [RegisterComponent]
+ [ComponentReference(typeof(SharedOverlayEffectsComponent))]
+ public sealed class ClientOverlayEffectsComponent : SharedOverlayEffectsComponent//, ICharacterUI
+ {
+
+ ///
+ /// An enum representing the current state being applied to the user
+ ///
+ private ScreenEffects _currentEffect = ScreenEffects.None;
+
+#pragma warning disable 649
+ // Required dependencies
+ [Dependency] private readonly IOverlayManager _overlayManager;
+ [Dependency] private readonly IPlayerManager _playerManager;
+#pragma warning restore 649
+
+ ///
+ /// Holds the screen effects that can be applied mapped ot their relevant overlay
+ ///
+ private Dictionary _effectsDictionary;
+
+ ///
+ /// Allows calculating if we need to act due to this component being controlled by the current mob
+ ///
+ private bool CurrentlyControlled => _playerManager.LocalPlayer.ControlledEntity == Owner;
+
+ public override void OnAdd()
+ {
+ base.OnAdd();
+
+ _effectsDictionary = new Dictionary()
+ {
+ { ScreenEffects.CircleMask, new CircleMaskOverlay() },
+ { ScreenEffects.GradientCircleMask, new GradientCircleMask() }
+ };
+ }
+
+ public override void HandleMessage(ComponentMessage message, INetChannel netChannel = null, IComponent component = null)
+ {
+ switch (message)
+ {
+ case PlayerAttachedMsg _:
+ SetOverlay(_currentEffect);
+ break;
+ }
+ }
+
+ public override void HandleComponentState(ComponentState curState, ComponentState nextState)
+ {
+ base.HandleComponentState(curState, nextState);
+ if (!(curState is OverlayEffectComponentState state) || _currentEffect == state.ScreenEffect) return;
+ SetOverlay(state.ScreenEffect);
+ }
+
+ private void SetOverlay(ScreenEffects effect)
+ {
+ RemoveOverlay();
+
+ _currentEffect = effect;
+
+ ApplyOverlay();
+ }
+
+ private void RemoveOverlay()
+ {
+ if (CurrentlyControlled && _currentEffect != ScreenEffects.None)
+ {
+ var appliedEffect = _effectsDictionary[_currentEffect];
+ _overlayManager.RemoveOverlay(appliedEffect.ID);
+ }
+
+ _currentEffect = ScreenEffects.None;
+ }
+
+ private void ApplyOverlay()
+ {
+ if (CurrentlyControlled && _currentEffect != ScreenEffects.None)
+ {
+ var overlay = _effectsDictionary[_currentEffect];
+ if (_overlayManager.HasOverlay(overlay.ID))
+ {
+ return;
+ }
+ _overlayManager.AddOverlay(overlay);
+ Logger.InfoS("overlay", $"Changed overlay to {overlay}");
+ }
+ }
+ }
+}
diff --git a/Content.Client/GameObjects/Components/Mobs/ClientStatusEffectsComponent.cs b/Content.Client/GameObjects/Components/Mobs/ClientStatusEffectsComponent.cs
new file mode 100644
index 0000000000..ed7cb3dcdf
--- /dev/null
+++ b/Content.Client/GameObjects/Components/Mobs/ClientStatusEffectsComponent.cs
@@ -0,0 +1,116 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using Content.Client.UserInterface;
+using Content.Client.Utility;
+using Content.Shared.GameObjects.Components.Mobs;
+using Robust.Client.GameObjects;
+using Robust.Client.Interfaces.ResourceManagement;
+using Robust.Client.Interfaces.UserInterface;
+using Robust.Client.Player;
+using Robust.Client.UserInterface.Controls;
+using Robust.Shared.GameObjects;
+using Robust.Shared.Interfaces.GameObjects;
+using Robust.Shared.Interfaces.Network;
+using Robust.Shared.IoC;
+using Robust.Shared.Log;
+using Robust.Shared.ViewVariables;
+
+namespace Content.Client.GameObjects.Components.Mobs
+{
+ ///
+ [RegisterComponent]
+ public sealed class ClientStatusEffectsComponent : SharedStatusEffectsComponent
+ {
+#pragma warning disable 649
+ [Dependency] private readonly IPlayerManager _playerManager;
+ [Dependency] private readonly IResourceCache _resourceCache;
+ [Dependency] private readonly IUserInterfaceManager _userInterfaceManager;
+#pragma warning restore 649
+
+ private StatusEffectsUI _ui;
+ private IDictionary _icons = new Dictionary();
+
+ ///
+ /// Allows calculating if we need to act due to this component being controlled by the current mob
+ ///
+ private bool CurrentlyControlled => _playerManager.LocalPlayer.ControlledEntity == Owner;
+
+ protected override void Shutdown()
+ {
+ base.Shutdown();
+ PlayerDetached();
+ }
+
+ public override void HandleMessage(ComponentMessage message, INetChannel netChannel = null,
+ IComponent component = null)
+ {
+ base.HandleMessage(message, netChannel, component);
+ switch (message)
+ {
+ case PlayerAttachedMsg _:
+ PlayerAttached();
+ break;
+ case PlayerDetachedMsg _:
+ PlayerDetached();
+ break;
+ }
+ }
+
+ public override void HandleComponentState(ComponentState curState, ComponentState nextState)
+ {
+ base.HandleComponentState(curState, nextState);
+ if (!(curState is StatusEffectComponentState state) || _icons == state.StatusEffects) return;
+ _icons = state.StatusEffects;
+ UpdateIcons();
+ }
+
+ private void PlayerAttached()
+ {
+ if (!CurrentlyControlled || _ui != null)
+ {
+ return;
+ }
+ _ui = new StatusEffectsUI();
+ _userInterfaceManager.StateRoot.AddChild(_ui);
+ UpdateIcons();
+ }
+
+ private void PlayerDetached()
+ {
+ if (!CurrentlyControlled)
+ {
+ return;
+ }
+ _ui?.Dispose();
+ }
+
+ public void UpdateIcons()
+ {
+ if (!CurrentlyControlled || _ui == null)
+ {
+ return;
+ }
+ _ui.VBox.DisposeAllChildren();
+
+ foreach (var effect in _icons.OrderBy(x => (int) x.Key))
+ {
+ TextureRect newIcon = new TextureRect
+ {
+ TextureScale = (2, 2),
+ Texture = _resourceCache.GetTexture(effect.Value)
+ };
+
+ newIcon.Texture = _resourceCache.GetTexture(effect.Value);
+ _ui.VBox.AddChild(newIcon);
+ }
+ }
+
+ public void RemoveIcon(StatusEffect name)
+ {
+ _icons.Remove(name);
+ UpdateIcons();
+ Logger.InfoS("statuseffects", $"Removed icon {name}");
+ }
+ }
+}
diff --git a/Content.Client/GameObjects/Components/Mobs/SpeciesUI.cs b/Content.Client/GameObjects/Components/Mobs/SpeciesUI.cs
deleted file mode 100644
index 2999ede1bf..0000000000
--- a/Content.Client/GameObjects/Components/Mobs/SpeciesUI.cs
+++ /dev/null
@@ -1,171 +0,0 @@
-using System.Collections.Generic;
-using Content.Client.GameObjects.Components.Actor;
-using Content.Client.Graphics.Overlays;
-using Content.Client.UserInterface;
-using Content.Client.Utility;
-using Content.Shared.GameObjects;
-using Content.Shared.GameObjects.Components.Mobs;
-using Robust.Client.GameObjects;
-using Robust.Client.Graphics;
-using Robust.Client.Graphics.Overlays;
-using Robust.Client.Interfaces.Graphics.Overlays;
-using Robust.Client.Interfaces.ResourceManagement;
-using Robust.Client.Interfaces.UserInterface;
-using Robust.Client.Player;
-using Robust.Client.UserInterface;
-using Robust.Client.UserInterface.Controls;
-using Robust.Shared.GameObjects;
-using Robust.Shared.GameObjects.Components.Renderable;
-using Robust.Shared.Interfaces.GameObjects;
-using Robust.Shared.Interfaces.Network;
-using Robust.Shared.IoC;
-
-namespace Content.Client.GameObjects
-{
- ///
- /// A character UI component which shows the current damage state of the mob (living/dead)
- ///
- [RegisterComponent]
- public class SpeciesUI : SharedSpeciesComponent//, ICharacterUI
- {
- private StatusEffectsUI _ui;
-
- ///
- /// Holds the godot control for the species window
- ///
- private SpeciesWindow _window;
-
- ///
- /// An enum representing the current state being applied to the user
- ///
- private ScreenEffects _currentEffect = ScreenEffects.None;
-
-#pragma warning disable 649
- // Required dependencies
- [Dependency] private readonly IOverlayManager _overlayManager;
- [Dependency] private readonly IPlayerManager _playerManager;
- [Dependency] private readonly IUserInterfaceManager _userInterfaceManager;
- [Dependency] private readonly IResourceCache _resourceCache;
-#pragma warning restore 649
-
- //Relevant interface implementation for the character UI controller
- public Control Scene => _window;
- public UIPriority Priority => UIPriority.Species;
-
- ///
- /// Allows calculating if we need to act due to this component being controlled by the current mob
- ///
- private bool CurrentlyControlled => _playerManager.LocalPlayer.ControlledEntity == Owner;
-
- ///
- /// Holds the screen effects that can be applied mapped ot their relevant overlay
- ///
- private Dictionary EffectsDictionary;
-
- public override void OnRemove()
- {
- base.OnRemove();
-
- _window.Dispose();
- }
-
- public override void OnAdd()
- {
- base.OnAdd();
-
- _window = new SpeciesWindow();
- _ui = new StatusEffectsUI();
-
- EffectsDictionary = new Dictionary()
- {
- { ScreenEffects.CircleMask, new CircleMaskOverlay() },
- { ScreenEffects.GradientCircleMask, new GradientCircleMask() }
- };
- }
-
- public override void HandleMessage(ComponentMessage message, INetChannel netChannel = null, IComponent component = null)
- {
- switch (message)
- {
- case HudStateChange msg:
- if (CurrentlyControlled)
- {
- ChangeHudIcon(msg);
- }
- break;
-
- case PlayerAttachedMsg _:
- _ui.Parent?.RemoveChild(_ui);
-
- _userInterfaceManager.StateRoot.AddChild(_ui);
- ApplyOverlay();
- break;
-
- case PlayerDetachedMsg _:
- _ui.Parent?.RemoveChild(_ui);
- RemoveOverlay();
- break;
- }
- }
-
- private void ChangeHudIcon(HudStateChange changeMessage)
- {
- var path = SharedSpriteComponent.TextureRoot / changeMessage.StateSprite;
- var texture = _resourceCache.GetTexture(path);
-
- _window.SetIcon(texture);
- _ui.SetHealthIcon(texture);
-
- SetOverlay(changeMessage);
- }
-
- private void SetOverlay(HudStateChange message)
- {
- RemoveOverlay();
-
- _currentEffect = message.effect;
-
- ApplyOverlay();
- }
-
- private void RemoveOverlay()
- {
- if (_currentEffect != ScreenEffects.None)
- {
- var appliedEffect = EffectsDictionary[_currentEffect];
- _overlayManager.RemoveOverlay(appliedEffect.ID);
- }
-
- _currentEffect = ScreenEffects.None;
- }
-
- private void ApplyOverlay()
- {
- if (_currentEffect != ScreenEffects.None)
- {
- var overlay = EffectsDictionary[_currentEffect];
- if (_overlayManager.HasOverlay(overlay.ID))
- {
- return;
- }
- _overlayManager.AddOverlay(overlay);
- }
- }
-
- private class SpeciesWindow : TextureRect
- {
- public SpeciesWindow()
- {
- SizeFlagsHorizontal = SizeFlags.ShrinkCenter;
- SizeFlagsVertical = SizeFlags.None;
-
- Texture = IoCManager.Resolve().GetTexture("/Textures/Mob/UI/Human/human0.png");
- }
-
- public void SetIcon(Texture texture)
- {
- Texture = texture;
- }
- }
- }
-}
diff --git a/Content.Client/UserInterface/StatusEffectsUI.cs b/Content.Client/UserInterface/StatusEffectsUI.cs
index aee3707e58..ce32c8f6e6 100644
--- a/Content.Client/UserInterface/StatusEffectsUI.cs
+++ b/Content.Client/UserInterface/StatusEffectsUI.cs
@@ -12,29 +12,16 @@ namespace Content.Client.UserInterface
///
public sealed class StatusEffectsUI : Control
{
+ public VBoxContainer VBox => _vBox;
private readonly VBoxContainer _vBox;
- private TextureRect _healthStatusRect;
-
public StatusEffectsUI()
{
_vBox = new VBoxContainer {GrowHorizontal = GrowDirection.Begin};
AddChild(_vBox);
-
- _vBox.AddChild(_healthStatusRect = new TextureRect
- {
- TextureScale = (2, 2),
- Texture = IoCManager.Resolve().GetTexture("/Textures/Mob/UI/Human/human0.png")
- });
-
SetAnchorAndMarginPreset(LayoutPreset.TopRight);
MarginTop = 250;
MarginRight = 10;
}
-
- public void SetHealthIcon(Texture texture)
- {
- _healthStatusRect.Texture = texture;
- }
}
}
diff --git a/Content.Server/GameObjects/Components/Mobs/DamageThresholdTemplates/DamageThresholdTemplates.cs b/Content.Server/GameObjects/Components/Mobs/DamageThresholdTemplates/DamageThresholdTemplates.cs
index b31e1edc77..3a61c96188 100644
--- a/Content.Server/GameObjects/Components/Mobs/DamageThresholdTemplates/DamageThresholdTemplates.cs
+++ b/Content.Server/GameObjects/Components/Mobs/DamageThresholdTemplates/DamageThresholdTemplates.cs
@@ -1,5 +1,7 @@
using System.Collections.Generic;
using Content.Shared.GameObjects;
+using Content.Shared.GameObjects.Components.Mobs;
+using Robust.Shared.Interfaces.GameObjects;
namespace Content.Server.GameObjects
{
@@ -13,10 +15,9 @@ namespace Content.Server.GameObjects
///
/// Changes the hud state when a threshold is reached
///
- ///
///
///
- public abstract HudStateChange ChangeHudState(DamageableComponent damage);
+ public abstract void ChangeHudState(DamageableComponent damage);
//public abstract ResistanceSet resistanceset { get; }
diff --git a/Content.Server/GameObjects/Components/Mobs/DamageThresholdTemplates/HumanTemplate.cs b/Content.Server/GameObjects/Components/Mobs/DamageThresholdTemplates/HumanTemplate.cs
index 76c7b68d02..07325f98f4 100644
--- a/Content.Server/GameObjects/Components/Mobs/DamageThresholdTemplates/HumanTemplate.cs
+++ b/Content.Server/GameObjects/Components/Mobs/DamageThresholdTemplates/HumanTemplate.cs
@@ -1,8 +1,13 @@
using Content.Shared.GameObjects;
using System.Collections.Generic;
+using Content.Server.GameObjects.Components.Mobs;
+using Content.Shared.GameObjects.Components.Mobs;
+using JetBrains.Annotations;
+using ScreenEffects = Content.Shared.GameObjects.Components.Mobs.ScreenEffects;
namespace Content.Server.GameObjects
{
+ [UsedImplicitly]
public class Human : DamageTemplates
{
int critvalue = 200;
@@ -30,9 +35,11 @@ namespace Content.Server.GameObjects
}
}
- public override HudStateChange ChangeHudState(DamageableComponent damage)
+ public override void ChangeHudState(DamageableComponent damage)
{
ThresholdType healthstate = CalculateDamageState(damage);
+ damage.Owner.TryGetComponent(out ServerStatusEffectsComponent statusEffectsComponent);
+ damage.Owner.TryGetComponent(out ServerOverlayEffectsComponent overlayComponent);
switch (healthstate)
{
case ThresholdType.None:
@@ -42,23 +49,26 @@ namespace Content.Server.GameObjects
throw new System.InvalidOperationException(); //these should all be below the crit value, possibly going over multiple thresholds at once?
}
var modifier = totaldamage / (critvalue / normalstates); //integer division floors towards zero
- return new HudStateChange()
- {
- StateSprite = "Mob/UI/Human/human" + modifier.ToString() + ".png",
- effect = ScreenEffects.None
- };
+ statusEffectsComponent?.ChangeStatus(StatusEffect.Health,
+ "/Textures/Mob/UI/Human/human" + modifier + ".png");
+
+ overlayComponent?.ChangeOverlay(ScreenEffects.None);
+
+ return;
case ThresholdType.Critical:
- return new HudStateChange()
- {
- StateSprite = "Mob/UI/Human/humancrit-0.png", //TODO: display as gif or alternate with -0 and -1 as frames
- effect = ScreenEffects.GradientCircleMask
- };
+ statusEffectsComponent?.ChangeStatus(
+ StatusEffect.Health,
+ "/Textures/Mob/UI/Human/humancrit-0.png");
+ overlayComponent?.ChangeOverlay(ScreenEffects.GradientCircleMask);
+
+ return;
case ThresholdType.Death:
- return new HudStateChange()
- {
- StateSprite = "Mob/UI/Human/humandead.png",
- effect = ScreenEffects.CircleMask
- };
+ statusEffectsComponent?.ChangeStatus(
+ StatusEffect.Health,
+ "/Textures/Mob/UI/Human/humandead.png");
+ overlayComponent?.ChangeOverlay(ScreenEffects.CircleMask);
+
+ return;
default:
throw new System.InvalidOperationException();
}
diff --git a/Content.Server/GameObjects/Components/Mobs/ServerOverlayEffectsComponent.cs b/Content.Server/GameObjects/Components/Mobs/ServerOverlayEffectsComponent.cs
new file mode 100644
index 0000000000..8cfcb33cb8
--- /dev/null
+++ b/Content.Server/GameObjects/Components/Mobs/ServerOverlayEffectsComponent.cs
@@ -0,0 +1,27 @@
+using Content.Shared.GameObjects.Components.Mobs;
+using Robust.Shared.GameObjects;
+
+namespace Content.Server.GameObjects.Components.Mobs
+{
+ [RegisterComponent]
+ [ComponentReference(typeof(SharedOverlayEffectsComponent))]
+ public sealed class ServerOverlayEffectsComponent : SharedOverlayEffectsComponent
+ {
+ private ScreenEffects _currentOverlay = ScreenEffects.None;
+
+ public override ComponentState GetComponentState()
+ {
+ return new OverlayEffectComponentState(_currentOverlay);
+ }
+
+ public void ChangeOverlay(ScreenEffects effect)
+ {
+ if (effect == _currentOverlay)
+ {
+ return;
+ }
+ _currentOverlay = effect;
+ Dirty();
+ }
+ }
+}
diff --git a/Content.Server/GameObjects/Components/Mobs/ServerStatusEffectsComponent.cs b/Content.Server/GameObjects/Components/Mobs/ServerStatusEffectsComponent.cs
new file mode 100644
index 0000000000..646396d3e4
--- /dev/null
+++ b/Content.Server/GameObjects/Components/Mobs/ServerStatusEffectsComponent.cs
@@ -0,0 +1,40 @@
+using System.Collections.Generic;
+using Content.Shared.GameObjects.Components.Mobs;
+using Robust.Shared.GameObjects;
+
+namespace Content.Server.GameObjects.Components.Mobs
+{
+ [RegisterComponent]
+ [ComponentReference(typeof(SharedStatusEffectsComponent))]
+ public sealed class ServerStatusEffectsComponent : SharedStatusEffectsComponent
+ {
+ private readonly Dictionary _statusEffects = new Dictionary();
+
+ public override ComponentState GetComponentState()
+ {
+ return new StatusEffectComponentState(_statusEffects);
+ }
+
+ public void ChangeStatus(StatusEffect effect, string icon)
+ {
+ if (_statusEffects.TryGetValue(effect, out string value) && value == icon)
+ {
+ return;
+ }
+
+ _statusEffects[effect] = icon;
+ Dirty();
+ }
+
+ public void RemoveStatus(StatusEffect effect)
+ {
+ if (!_statusEffects.Remove(effect))
+ {
+ return;
+ }
+
+ Dirty();
+ }
+ }
+
+}
diff --git a/Content.Server/GameObjects/Components/Mobs/SpeciesComponent.cs b/Content.Server/GameObjects/Components/Mobs/SpeciesComponent.cs
index 33cb0b6627..c3a9f9d2cc 100644
--- a/Content.Server/GameObjects/Components/Mobs/SpeciesComponent.cs
+++ b/Content.Server/GameObjects/Components/Mobs/SpeciesComponent.cs
@@ -1,5 +1,6 @@
using System;
using System.Collections.Generic;
+using Content.Server.GameObjects.Components.Mobs;
using Content.Server.GameObjects.EntitySystems;
using Content.Server.Interfaces;
using Content.Shared.GameObjects.Components.Mobs;
@@ -56,12 +57,26 @@ namespace Content.Server.GameObjects
switch (message)
{
case PlayerAttachedMsg _:
- var hudstatechange = DamageTemplate.ChangeHudState(Owner.GetComponent());
- SendNetworkMessage(hudstatechange);
+ if (CanReceiveStatusEffect(Owner)) {
+ DamageableComponent damage = Owner.GetComponent();
+ DamageTemplate.ChangeHudState(damage);
+ }
+ break;
+ case PlayerDetachedMsg _:
break;
}
}
+ public override void OnRemove()
+ {
+ base.OnRemove();
+ Owner.TryGetComponent(out ServerStatusEffectsComponent statusEffectsComponent);
+ statusEffectsComponent?.RemoveStatus(StatusEffect.Health);
+
+ Owner.TryGetComponent(out ServerOverlayEffectsComponent overlayEffectsComponent);
+ overlayEffectsComponent?.ChangeOverlay(ScreenEffects.None);
+ }
+
bool IActionBlocker.CanMove()
{
return CurrentDamageState.CanMove();
@@ -103,14 +118,28 @@ namespace Content.Server.GameObjects
ChangeDamageState(DamageTemplate.CalculateDamageState(damage));
}
- if (Owner.TryGetComponent(out BasicActorComponent actor)
- ) //specifies if we have a client to update the hud for
+ //specifies if we have a client to update the hud for
+ if (CanReceiveStatusEffect(Owner))
{
- var hudstatechange = DamageTemplate.ChangeHudState(damage);
- SendNetworkMessage(hudstatechange);
+ DamageTemplate.ChangeHudState(damage);
}
}
+ private bool CanReceiveStatusEffect(IEntity user)
+ {
+ if (!user.HasComponent() &&
+ !user.HasComponent())
+ {
+ return false;
+ }
+ if (user.HasComponent())
+ {
+ return true;
+ }
+
+ return false;
+ }
+
private void ChangeDamageState(ThresholdType threshold)
{
if (threshold == currentstate)
diff --git a/Content.Shared/GameObjects/Components/Mobs/SharedOverlayEffectsComponent.cs b/Content.Shared/GameObjects/Components/Mobs/SharedOverlayEffectsComponent.cs
new file mode 100644
index 0000000000..681efcd60b
--- /dev/null
+++ b/Content.Shared/GameObjects/Components/Mobs/SharedOverlayEffectsComponent.cs
@@ -0,0 +1,34 @@
+using System;
+using Robust.Shared.GameObjects;
+using Robust.Shared.Serialization;
+
+namespace Content.Shared.GameObjects.Components.Mobs
+{
+ ///
+ /// Full screen overlays; Blindness, death, flash, alcohol etc.
+ ///
+ public abstract class SharedOverlayEffectsComponent : Component
+ {
+ public override string Name => "OverlayEffectsUI";
+ public sealed override uint? NetID => ContentNetIDs.OVERLAYEFFECTS;
+ public sealed override Type StateType => typeof(OverlayEffectComponentState);
+ }
+
+ public enum ScreenEffects
+ {
+ None,
+ CircleMask,
+ GradientCircleMask,
+ }
+
+ [Serializable, NetSerializable]
+ public class OverlayEffectComponentState : ComponentState
+ {
+ public ScreenEffects ScreenEffect;
+
+ public OverlayEffectComponentState(ScreenEffects screenEffect) : base(ContentNetIDs.OVERLAYEFFECTS)
+ {
+ ScreenEffect = screenEffect;
+ }
+ }
+}
diff --git a/Content.Shared/GameObjects/Components/Mobs/SharedSpeciesComponent.cs b/Content.Shared/GameObjects/Components/Mobs/SharedSpeciesComponent.cs
index a3e99f4e9f..0396410c9a 100644
--- a/Content.Shared/GameObjects/Components/Mobs/SharedSpeciesComponent.cs
+++ b/Content.Shared/GameObjects/Components/Mobs/SharedSpeciesComponent.cs
@@ -8,8 +8,6 @@ namespace Content.Shared.GameObjects.Components.Mobs
{
public sealed override string Name => "Species";
- public sealed override uint? NetID => ContentNetIDs.SPECIES;
-
[Serializable, NetSerializable]
public enum MobVisuals
{
@@ -29,6 +27,6 @@ namespace Content.Shared.GameObjects.Components.Mobs
///
Down,
}
-
+
}
}
diff --git a/Content.Shared/GameObjects/Components/Mobs/SharedStatusEffectsComponent.cs b/Content.Shared/GameObjects/Components/Mobs/SharedStatusEffectsComponent.cs
new file mode 100644
index 0000000000..ff26d8172e
--- /dev/null
+++ b/Content.Shared/GameObjects/Components/Mobs/SharedStatusEffectsComponent.cs
@@ -0,0 +1,36 @@
+using System;
+using System.Collections.Generic;
+using Robust.Shared.GameObjects;
+using Robust.Shared.Serialization;
+
+namespace Content.Shared.GameObjects.Components.Mobs
+{
+ ///
+ /// Handles the icons on the right side of the screen.
+ /// Should only be used for player-controlled entities
+ ///
+ public abstract class SharedStatusEffectsComponent : Component
+ {
+ public override string Name => "StatusEffectsUI";
+ public override uint? NetID => ContentNetIDs.STATUSEFFECTS;
+ public sealed override Type StateType => typeof(StatusEffectComponentState);
+
+ }
+
+ [Serializable, NetSerializable]
+ public class StatusEffectComponentState : ComponentState
+ {
+ public Dictionary StatusEffects;
+
+ public StatusEffectComponentState(Dictionary statusEffects) : base(ContentNetIDs.STATUSEFFECTS)
+ {
+ StatusEffects = statusEffects;
+ }
+ }
+
+ // Each status effect is assumed to be unique
+ public enum StatusEffect
+ {
+ Health,
+ }
+}
diff --git a/Content.Shared/GameObjects/ContentNetIDs.cs b/Content.Shared/GameObjects/ContentNetIDs.cs
index 3387bb90e4..868560f7d0 100644
--- a/Content.Shared/GameObjects/ContentNetIDs.cs
+++ b/Content.Shared/GameObjects/ContentNetIDs.cs
@@ -12,7 +12,6 @@
public const uint INVENTORY = 1006;
public const uint POWER_DEBUG_TOOL = 1007;
public const uint CONSTRUCTOR = 1008;
- public const uint SPECIES = 1009;
public const uint RANGED_WEAPON = 1010;
public const uint CAMERA_RECOIL = 1011;
public const uint SOUND = 1012;
@@ -29,5 +28,7 @@
public const uint RESEARCH_CONSOLE = 1023;
public const uint WIRES = 1024;
public const uint COMBATMODE = 1025;
+ public const uint STATUSEFFECTS = 1026;
+ public const uint OVERLAYEFFECTS = 1027;
}
}
diff --git a/Content.Shared/GameObjects/Messages/Mob/HealthHud.cs b/Content.Shared/GameObjects/Messages/Mob/HealthHud.cs
deleted file mode 100644
index b28927f453..0000000000
--- a/Content.Shared/GameObjects/Messages/Mob/HealthHud.cs
+++ /dev/null
@@ -1,28 +0,0 @@
-using Robust.Shared.GameObjects;
-using Robust.Shared.Serialization;
-using System;
-
-namespace Content.Shared.GameObjects
-{
- ///
- /// Sends updates to the standard species health hud with the sprite to change the hud to
- ///
- [Serializable, NetSerializable]
- public class HudStateChange : ComponentMessage
- {
- public string StateSprite;
- public ScreenEffects effect;
-
- public HudStateChange()
- {
- Directed = true;
- }
- }
-
- public enum ScreenEffects
- {
- None,
- CircleMask,
- GradientCircleMask,
- }
-}
diff --git a/Resources/Prototypes/Entities/mobs/human.yml b/Resources/Prototypes/Entities/mobs/human.yml
index fe72758873..8be4fcd21b 100644
--- a/Resources/Prototypes/Entities/mobs/human.yml
+++ b/Resources/Prototypes/Entities/mobs/human.yml
@@ -52,6 +52,8 @@
- type: Species
Template: Human
HeatResistance: 323
+ - type: StatusEffectsUI
+ - type: OverlayEffectsUI
- type: HeatResistance
- type: Damageable