Files
wwdpublic/Content.Server/Medical/PenLightSystem.cs
SleepyScarecrow 7e936e3a95 Fixed Penlight UI and Blind Detection (#2139)
<!--
This is a semi-strict format, you can add/remove sections as needed but
the order/format should be kept the same
Remove these comments before submitting
-->

# Description

<!--
Explain this PR in as much detail as applicable

Some example prompts to consider:
How might this affect the game? The codebase?
What might be some alternatives to this?
How/Who does this benefit/hurt [the game/codebase]?
-->

Fixed up the penlights again. Made it so that the UI messages stored,
because there was an issue with the UI opening blank since the diagnoses
were already done beforehand, and they weren't readable. Further, I
updated the system to properly detect eye damage and blindess.

---

# TODO

<!--
A list of everything you have to do before this PR is "complete"
You probably won't have to complete everything before merging but it's
good to leave future references
-->

- [x] Fixed Penlights

---

# Changelog

<!--
You can add an author after the `🆑` to change the name that appears
in the changelog (ex: `🆑 Death`)
Leaving it blank will default to your GitHub display name
This includes all available types for the changelog
-->

🆑 SleepyScarecrow
- fix: Fixed penlights.

(cherry picked from commit bb7e69c8ac34eab72f6b03e99ee54efff96342a1)
2025-04-18 17:05:26 +03:00

149 lines
4.8 KiB
C#

using Content.Server.DoAfter;
using Content.Server.Popups;
using Content.Server.PowerCell;
using Content.Shared.Damage;
using Content.Shared.DoAfter;
using Content.Shared.Drugs;
using Content.Shared.Drunk;
using Content.Shared.Eye.Blinding.Components;
using Content.Shared.Interaction;
using Content.Shared.Medical;
using Content.Shared.Mobs.Components;
using Content.Shared.Mobs.Systems;
using Content.Shared.Traits.Assorted.Components;
using Robust.Server.GameObjects;
using Robust.Shared.Player;
using Robust.Shared.Timing;
namespace Content.Server.Medical;
/// <summary>
/// This stores the eye exam system for <see cref="PenLightComponent"/>
/// </summary>
public sealed class PenLightSystem : EntitySystem
{
[Dependency] private readonly IEntityManager _entityManager = default!;
[Dependency] private readonly DoAfterSystem _doAfter = default!;
[Dependency] private readonly PowerCellSystem _powerCell = default!;
[Dependency] private readonly PopupSystem _popup = default!;
[Dependency] private readonly UserInterfaceSystem _uiSystem = default!;
/// <inheritdoc/>
public override void Initialize()
{
SubscribeLocalEvent<PenLightComponent, AfterInteractEvent>(OnAfterInteract);
SubscribeLocalEvent<PenLightComponent, PenLightDoAfterEvent>(OnDoAfter);
}
private void OnAfterInteract(EntityUid uid, PenLightComponent component, ref AfterInteractEvent args)
{
if (args.Handled
|| args.Target is not {} target
|| target == null
|| !args.CanReach
|| !HasComp<MobStateComponent>(target)
|| !_powerCell.HasDrawCharge(uid, user: args.User))
return;
args.Handled = TryStartExam(uid, target, args.User, component);
}
private void OnDoAfter(Entity<PenLightComponent> uid, ref PenLightDoAfterEvent args)
{
if (args.Handled
|| args.Cancelled
|| args.Target == null
|| !_powerCell.HasDrawCharge(uid, user: args.User))
return;
OpenUserInterface(args.User, uid);
Diagnose(uid, args.Target.Value);
args.Handled = true;
}
/// <summary>
/// Checks if the PointLight component is enabled.
/// </summary>
private bool IsLightEnabled(EntityUid uid)
{
return TryComp<PointLightComponent>(uid, out var pointLight) && pointLight.Enabled;
}
/// <summary>
/// Actually handles the exam interaction.
/// </summary>
public bool TryStartExam(EntityUid uid, EntityUid target, EntityUid user, PenLightComponent? component = null)
{
if (!Resolve(uid, ref component))
return false;
if (!IsLightEnabled(uid))
{
if (user != null)
_popup.PopupEntity(Loc.GetString("penlight-off"), uid, user);
return false;
}
// can't examine your own eyes, dingus
if (user == target)
{
_popup.PopupEntity(Loc.GetString("penlight-cannot-examine-self"), uid, user);
return false;
}
return _doAfter.TryStartDoAfter(new DoAfterArgs(EntityManager, user, component.ExamSpeed, new PenLightDoAfterEvent(),
uid, target, uid)
{
BlockDuplicate = true,
BreakOnMove = true,
BreakOnHandChange = true,
NeedHand = true
});
}
private void OpenUserInterface(EntityUid user, EntityUid penlight)
{
if (!_uiSystem.HasUi(penlight, PenLightUiKey.Key))
return;
_uiSystem.OpenUi(penlight, PenLightUiKey.Key, user);
}
/// <summary>
/// Runs the checks for the different types of eye damage
/// </summary>
private void Diagnose(EntityUid penlight, EntityUid target)
{
if (!_uiSystem.HasUi(penlight, PenLightUiKey.Key)
|| !HasComp<EyeComponent>(target)
|| !HasComp<DamageableComponent>(target))
return;
// Blind
var blind = _entityManager.HasComponent<PermanentBlindnessComponent>(target);
// Drunk
var drunk = _entityManager.HasComponent<DrunkComponent>(target);
// EyeDamage
var eyeDamage = false;
if (TryComp<BlindableComponent>(target, out var blindable))
{
eyeDamage = blindable.EyeDamage > 0;
}
// Hallucinating
var seeingRainbows = _entityManager.HasComponent<SeeingRainbowsComponent>(target);
// Healthy
var healthy = !(blind || drunk || eyeDamage || seeingRainbows);
_uiSystem.ServerSendUiMessage(
penlight,
PenLightUiKey.Key,
new PenLightUserMessage(GetNetEntity(target),
blind,
drunk,
eyeDamage,
healthy,
seeingRainbows
)
);
}
}