forked from space-syndicate/space-station-14
-
Notifications
You must be signed in to change notification settings - Fork 9
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #117 from Lemirda/fatigue-system
task №3 and task №19
- Loading branch information
Showing
24 changed files
with
1,049 additions
and
1 deletion.
There are no files selected for viewing
130 changes: 130 additions & 0 deletions
130
Content.Client/Andromeda/Lemird/Nearsighted/NearsightedOverlays.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,130 @@ | ||
using Content.Shared.Andromeda.Lemird.Nearsighted; | ||
using Robust.Client.GameObjects; | ||
using Robust.Client.Graphics; | ||
using Robust.Client.Player; | ||
using Robust.Shared.Enums; | ||
using Robust.Shared.Prototypes; | ||
using Robust.Shared.Timing; | ||
|
||
namespace Content.Client.Andromeda.Lemird.Nearsighted; | ||
|
||
public sealed class NearsightedOverlay : Overlay | ||
{ | ||
[Dependency] private readonly IGameTiming _timing = default!; | ||
[Dependency] private readonly IPrototypeManager _prototypeManager = default!; | ||
[Dependency] private readonly IEntityManager _entityManager = default!; | ||
[Dependency] private readonly IPlayerManager _playerManager = default!; | ||
|
||
public override OverlaySpace Space => OverlaySpace.WorldSpace; | ||
private readonly ShaderInstance _nearsightShader; | ||
|
||
public float Radius; | ||
private float _oldRadius; | ||
public float Darkness; | ||
private float _oldDarkness; | ||
|
||
private float _lerpTime; | ||
public float LerpDuration; | ||
|
||
|
||
public NearsightedOverlay() | ||
{ | ||
IoCManager.InjectDependencies(this); | ||
_nearsightShader = _prototypeManager.Index<ShaderPrototype>("GradientCircleMask").InstanceUnique(); | ||
} | ||
|
||
protected override bool BeforeDraw(in OverlayDrawArgs args) | ||
{ | ||
// Check if the player has a NearsightedComponent and is controlling it | ||
if (!_entityManager.TryGetComponent(_playerManager.LocalPlayer?.ControlledEntity, out NearsightedComponent? nearComp) || | ||
_playerManager.LocalPlayer?.ControlledEntity != nearComp.Owner) | ||
return false; | ||
|
||
// Check if the player has an EyeComponent and if the overlay should be drawn for this eye | ||
if (!_entityManager.TryGetComponent(_playerManager.LocalPlayer?.ControlledEntity, out EyeComponent? eyeComp) || | ||
args.Viewport.Eye != eyeComp.Eye) | ||
return false; | ||
|
||
return true; | ||
} | ||
|
||
protected override void Draw(in OverlayDrawArgs args) | ||
{ | ||
// We already checked if they have a NearsightedComponent and are controlling it in BeforeDraw, so we assume this hasn't changed | ||
var nearComp = _entityManager.GetComponent<NearsightedComponent>(_playerManager.LocalPlayer!.ControlledEntity!.Value); | ||
|
||
// Set LerpDuration based on nearComp.LerpDuration | ||
LerpDuration = nearComp.LerpDuration; | ||
|
||
// Set the radius and darkness values based on whether the player is wearing glasses or not | ||
if (nearComp.Active) | ||
{ | ||
Radius = nearComp.EquippedRadius; | ||
Darkness = nearComp.EquippedAlpha; | ||
} | ||
else | ||
{ | ||
Radius = nearComp.Radius; | ||
Darkness = nearComp.Alpha; | ||
} | ||
|
||
|
||
var viewport = args.WorldAABB; | ||
var handle = args.WorldHandle; | ||
var distance = args.ViewportBounds.Width; | ||
|
||
var lastFrameTime = (float) _timing.FrameTime.TotalSeconds; | ||
|
||
|
||
// If the current radius value is different from the previous one, lerp between them | ||
if (!MathHelper.CloseTo(_oldRadius, Radius, 0.001f)) | ||
{ | ||
_lerpTime += lastFrameTime; | ||
var t = MathHelper.Clamp(_lerpTime / LerpDuration, 0f, 1f); // Calculate lerp time | ||
_oldRadius = MathHelper.Lerp(_oldRadius, Radius, t); // Lerp between old and new radius values | ||
} | ||
// If the current radius value is the same as the previous one, reset the lerp time and old radius value | ||
else | ||
{ | ||
_lerpTime = 0f; | ||
_oldRadius = Radius; | ||
} | ||
|
||
// If the current darkness value is different from the previous one, lerp between them | ||
if (!MathHelper.CloseTo(_oldDarkness, Darkness, 0.001f)) | ||
{ | ||
_lerpTime += lastFrameTime; | ||
var t = MathHelper.Clamp(_lerpTime / LerpDuration, 0f, 1f); // Calculate lerp time | ||
_oldDarkness = MathHelper.Lerp(_oldDarkness, Darkness, t); // Lerp between old and new darkness values | ||
} | ||
// If the current darkness value is the same as the previous one, reset the lerp time and old darkness value | ||
else | ||
{ | ||
_lerpTime = 0f; | ||
_oldDarkness = Darkness; | ||
} | ||
|
||
|
||
// Calculate the outer and inner radii based on the current radius value | ||
var outerMaxLevel = 0.6f * distance; | ||
var outerMinLevel = 0.06f * distance; | ||
var innerMaxLevel = 0.02f * distance; | ||
var innerMinLevel = 0.02f * distance; | ||
|
||
var outerRadius = outerMaxLevel - _oldRadius * (outerMaxLevel - outerMinLevel); | ||
var innerRadius = innerMaxLevel - _oldRadius * (innerMaxLevel - innerMinLevel); | ||
|
||
// Set the shader parameters and draw the overlay | ||
_nearsightShader.SetParameter("time", 0.0f); | ||
_nearsightShader.SetParameter("color", new Vector3(1f, 1f, 1f)); | ||
_nearsightShader.SetParameter("darknessAlphaOuter", _oldDarkness); | ||
_nearsightShader.SetParameter("innerCircleRadius", innerRadius); | ||
_nearsightShader.SetParameter("innerCircleMaxRadius", innerRadius); | ||
_nearsightShader.SetParameter("outerCircleRadius", outerRadius); | ||
_nearsightShader.SetParameter("outerCircleMaxRadius", outerRadius + 0.2f * distance); | ||
handle.UseShader(_nearsightShader); | ||
handle.DrawRect(viewport, Color.Black); | ||
|
||
handle.UseShader(null); | ||
} | ||
} |
63 changes: 63 additions & 0 deletions
63
Content.Client/Andromeda/Lemird/Nearsighted/NearsightedSystems.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,63 @@ | ||
using Content.Client.Andromeda.Lemird.Nearsighted; | ||
using Content.Shared.Inventory.Events; | ||
using Content.Shared.Andromeda.Lemird.Nearsighted; | ||
using Content.Shared.Tag; | ||
using Robust.Client.Graphics; | ||
|
||
namespace Content.Client.Andromeda.Lemird.Nearsighted; | ||
|
||
public sealed class NearsightedSystem : EntitySystem | ||
{ | ||
[Dependency] private readonly IOverlayManager _overlayMan = default!; | ||
|
||
private NearsightedOverlay _overlay = default!; | ||
|
||
public override void Initialize() | ||
{ | ||
base.Initialize(); | ||
|
||
_overlay = new NearsightedOverlay(); | ||
|
||
SubscribeLocalEvent<NearsightedComponent, ComponentStartup>(OnStartup); | ||
SubscribeLocalEvent<GotEquippedEvent>(OnEquip); | ||
SubscribeLocalEvent<GotUnequippedEvent>(OnUnEquip); | ||
} | ||
|
||
|
||
private void OnStartup(EntityUid uid, NearsightedComponent component, ComponentStartup args) | ||
{ | ||
UpdateShader(component, false); | ||
} | ||
|
||
private void OnEquip(GotEquippedEvent args) | ||
{ | ||
// Note: it would be cleaner to check if the glasses are being equipped | ||
// to the eyes rather than the pockets using `args.SlotFlags.HasFlag(SlotFlags.EYES)`, | ||
// but this field is not present on GotUnequippedEvent. This method is | ||
// used for both equip and unequip to make it consistent between checks. | ||
if (TryComp<NearsightedComponent>(args.Equipee, out var nearsighted) && | ||
EnsureComp<TagComponent>(args.Equipment).Tags.Contains("GlassesNearsight") && | ||
args.Slot == "eyes") | ||
UpdateShader(nearsighted, true); | ||
} | ||
|
||
private void OnUnEquip(GotUnequippedEvent args) | ||
{ | ||
if (TryComp<NearsightedComponent>(args.Equipee, out var nearsighted) && | ||
EnsureComp<TagComponent>(args.Equipment).Tags.Contains("GlassesNearsight") && | ||
args.Slot == "eyes") | ||
UpdateShader(nearsighted, false); | ||
} | ||
|
||
|
||
private void UpdateShader(NearsightedComponent component, bool booLean) | ||
{ | ||
while (_overlayMan.HasOverlay<NearsightedOverlay>()) | ||
{ | ||
_overlayMan.RemoveOverlay(_overlay); | ||
} | ||
|
||
component.Active = booLean; | ||
_overlayMan.AddOverlay(_overlay); | ||
} | ||
} |
65 changes: 65 additions & 0 deletions
65
Content.Server/Andromeda/Fatigue/FatigueMovementSpeedSystem.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,65 @@ | ||
using System.Threading; | ||
using Content.Server.Andromeda.Fatigue; | ||
using Content.Shared.Movement.Components; | ||
using Content.Shared.Movement.Systems; | ||
|
||
namespace Content.Shared.Andromeda.Lemird.Fatigue; | ||
|
||
public sealed class FatigueMovementSpeedSystem : EntitySystem | ||
{ | ||
[Dependency] private readonly MovementSpeedModifierSystem _movementSpeedModifierSystem = default!; | ||
|
||
public void UpdateMovementSpeed(EntityUid uid, FatigueComponent fatigueComp, MovementSpeedModifierComponent? moveMod = null) | ||
{ | ||
if (!Resolve(uid, ref moveMod)) | ||
return; | ||
|
||
var fatigueLevel = fatigueComp.CurrentFatigue; | ||
|
||
if (fatigueLevel > 45 && fatigueLevel <= 60) | ||
{ | ||
var newWalkSpeed = fatigueComp.OriginalWalkSpeed * 0.8f; // 20% снижение скорости | ||
var newSprintSpeed = fatigueComp.OriginalSprintSpeed * 0.8f; // 20% снижение скорости | ||
|
||
_movementSpeedModifierSystem.ChangeBaseSpeed(uid, newWalkSpeed, newSprintSpeed, moveMod.Acceleration); | ||
|
||
if (!fatigueComp.SpeedReduced) | ||
{ | ||
fatigueComp.SpeedReduced = true; | ||
} | ||
} | ||
else if (fatigueLevel > 20 && fatigueLevel <= 45) | ||
{ | ||
var newWalkSpeed = fatigueComp.OriginalWalkSpeed * 0.6f; // 40% снижение скорости | ||
var newSprintSpeed = fatigueComp.OriginalSprintSpeed * 0.6f; // 40% снижение скорости | ||
|
||
_movementSpeedModifierSystem.ChangeBaseSpeed(uid, newWalkSpeed, newSprintSpeed, moveMod.Acceleration); | ||
|
||
if (!fatigueComp.SpeedReduced) | ||
{ | ||
fatigueComp.SpeedReduced = true; | ||
} | ||
} | ||
else if (fatigueLevel > 0 && fatigueLevel <= 20) | ||
{ | ||
var newWalkSpeed = fatigueComp.OriginalWalkSpeed * 0.45f; // 55% снижение скорости | ||
var newSprintSpeed = fatigueComp.OriginalSprintSpeed * 0.45f; // 55% снижение скорости | ||
|
||
_movementSpeedModifierSystem.ChangeBaseSpeed(uid, newWalkSpeed, newSprintSpeed, moveMod.Acceleration); | ||
|
||
if (!fatigueComp.SpeedReduced) | ||
{ | ||
fatigueComp.SpeedReduced = true; | ||
} | ||
} | ||
else if (fatigueLevel > 60 || fatigueComp.SpeedReduced == false) | ||
{ | ||
_movementSpeedModifierSystem.ChangeBaseSpeed(uid, fatigueComp.OriginalWalkSpeed, fatigueComp.OriginalSprintSpeed, moveMod.Acceleration); | ||
|
||
if (fatigueComp.SpeedReduced) | ||
{ | ||
fatigueComp.SpeedReduced = false; | ||
} | ||
} | ||
} | ||
} |
Oops, something went wrong.