From 12cf5559c277f2791a88f6422fa5c72c827e8846 Mon Sep 17 00:00:00 2001 From: metalgearsloth <31366439+metalgearsloth@users.noreply.github.com> Date: Thu, 31 Oct 2019 02:37:22 +1100 Subject: [PATCH] Refactor SpeciesUI into overlay and status effects (#381) * Refactor SpeciesUI into overlay and status effects All components that update the UI will need to use PlayerAttached for cases where the Mind transfers I think. * Change overlay / status effects to use states * Change TryRemoveStatus to RemoveStatus Doesn't return a bool so not trying. Addressing PJB's feedback. --- Content.Client/EntryPoint.cs | 1 + .../Mobs/ClientOverlayEffectsComponent.cs | 107 +++++++++++ .../Mobs/ClientStatusEffectsComponent.cs | 116 ++++++++++++ .../GameObjects/Components/Mobs/SpeciesUI.cs | 171 ------------------ .../UserInterface/StatusEffectsUI.cs | 15 +- .../DamageThresholdTemplates.cs | 5 +- .../DamageThresholdTemplates/HumanTemplate.cs | 42 +++-- .../Mobs/ServerOverlayEffectsComponent.cs | 27 +++ .../Mobs/ServerStatusEffectsComponent.cs | 40 ++++ .../Components/Mobs/SpeciesComponent.cs | 41 ++++- .../Mobs/SharedOverlayEffectsComponent.cs | 34 ++++ .../Components/Mobs/SharedSpeciesComponent.cs | 4 +- .../Mobs/SharedStatusEffectsComponent.cs | 36 ++++ Content.Shared/GameObjects/ContentNetIDs.cs | 3 +- .../GameObjects/Messages/Mob/HealthHud.cs | 28 --- Resources/Prototypes/Entities/mobs/human.yml | 2 + 16 files changed, 431 insertions(+), 241 deletions(-) create mode 100644 Content.Client/GameObjects/Components/Mobs/ClientOverlayEffectsComponent.cs create mode 100644 Content.Client/GameObjects/Components/Mobs/ClientStatusEffectsComponent.cs delete mode 100644 Content.Client/GameObjects/Components/Mobs/SpeciesUI.cs create mode 100644 Content.Server/GameObjects/Components/Mobs/ServerOverlayEffectsComponent.cs create mode 100644 Content.Server/GameObjects/Components/Mobs/ServerStatusEffectsComponent.cs create mode 100644 Content.Shared/GameObjects/Components/Mobs/SharedOverlayEffectsComponent.cs create mode 100644 Content.Shared/GameObjects/Components/Mobs/SharedStatusEffectsComponent.cs delete mode 100644 Content.Shared/GameObjects/Messages/Mob/HealthHud.cs 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