Files
wwdpublic/Content.Server/Medical/PenLightSystem.cs
SleepyScarecrow 527d31908d Penlight-Fixes (#900)
<!--
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]?
-->

Tweaked penlights some. You can no longer examine random objects, you
cannot examine your own eyes, and the penlight now needs to be actually
on in order to use. Also tweaked the messages to be more accurate.



# 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
-->

🆑 Tilkku
- tweak: Penlight Exam Messages
- fix: Penlights now need to be on in order to examine
- fix: Penlights can no longer be used on self

---------

Signed-off-by: SleepyScarecrow <136123749+SleepyScarecrow@users.noreply.github.com>
Co-authored-by: VMSolidus <evilexecutive@gmail.com>
2024-10-19 12:46:27 +07:00

147 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,
BreakOnUserMove = true,
BreakOnTargetMove = true,
BreakOnHandChange = true,
NeedHand = true
});
}
private void OpenUserInterface(EntityUid user, EntityUid penlight)
{
if (!TryComp<ActorComponent>(user, out var actor)
|| !_uiSystem.TryGetUi(penlight, PenLightUiKey.Key, out var ui))
return;
_uiSystem.OpenUi(ui, actor.PlayerSession);
}
/// <summary>
/// Runs the checks for the different types of eye damage
/// </summary>
private void Diagnose(EntityUid penlight, EntityUid target)
{
if (!_uiSystem.TryGetUi(penlight, PenLightUiKey.Key, out var ui)
|| !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 eyeDam))
{
eyeDamage = eyeDam.EyeDamage > 0 && eyeDam.EyeDamage < 6; //6 means perma-blind
}
// Hallucinating
var seeingRainbows = _entityManager.HasComponent<SeeingRainbowsComponent>(target);
// Healthy
var healthy = !(blind || drunk || eyeDamage || seeingRainbows);
_uiSystem.SendUiMessage(ui, new PenLightUserMessage(GetNetEntity(target),
blind,
drunk,
eyeDamage,
healthy,
seeingRainbows
));
}
}