Skip to content

Commit

Permalink
Merge pull request #117 from Lemirda/fatigue-system
Browse files Browse the repository at this point in the history
task №3 and task №19
  • Loading branch information
13lackHawk authored May 3, 2024
2 parents 86658b7 + 04b9ec1 commit 448086c
Show file tree
Hide file tree
Showing 24 changed files with 1,049 additions and 1 deletion.
130 changes: 130 additions & 0 deletions Content.Client/Andromeda/Lemird/Nearsighted/NearsightedOverlays.cs
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 Content.Client/Andromeda/Lemird/Nearsighted/NearsightedSystems.cs
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 Content.Server/Andromeda/Fatigue/FatigueMovementSpeedSystem.cs
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;
}
}
}
}
Loading

0 comments on commit 448086c

Please sign in to comment.