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.
This commit is contained in:
metalgearsloth
2019-10-31 02:37:22 +11:00
committed by Pieter-Jan Briers
parent 6497cdf8ff
commit 12cf5559c2
16 changed files with 431 additions and 241 deletions

View File

@@ -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
/// <summary>
/// Changes the hud state when a threshold is reached
/// </summary>
/// <param name="state"></param>
/// <param name="damage"></param>
/// <returns></returns>
public abstract HudStateChange ChangeHudState(DamageableComponent damage);
public abstract void ChangeHudState(DamageableComponent damage);
//public abstract ResistanceSet resistanceset { get; }

View File

@@ -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();
}

View File

@@ -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();
}
}
}

View File

@@ -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<StatusEffect, string> _statusEffects = new Dictionary<StatusEffect, string>();
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();
}
}
}

View File

@@ -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<DamageableComponent>());
SendNetworkMessage(hudstatechange);
if (CanReceiveStatusEffect(Owner)) {
DamageableComponent damage = Owner.GetComponent<DamageableComponent>();
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<ServerStatusEffectsComponent>() &&
!user.HasComponent<ServerOverlayEffectsComponent>())
{
return false;
}
if (user.HasComponent<DamageableComponent>())
{
return true;
}
return false;
}
private void ChangeDamageState(ThresholdType threshold)
{
if (threshold == currentstate)