CatStation/Content.Shared/Stunnable/StunbatonSystem.cs
psykana 880536d1b6
Predict stunbatons and add an integration test for them (#43117)
* predict stunbatons and add a test

* update

* formatting

* move explosion to riggable

* cleanup

* fix mousetrap

* fix test

* IOC readonly

* fix obsolete

* refactor test a bit

* fix riggable, add test

* moar tests

* fix proto

* EnterMultipleScope

* owner cleanup

* early return

* onActivate

* Fix GetVerb detonating rigged baton, add docs

* test updates

* docs

* improve riggable test

* TestOf

* predicted popup

* Update Content.IntegrationTests/Tests/Chemistry/RiggableTest.cs

* review

* review 2

* the end times

* review

* nesting

* nesting 2

---------

Co-authored-by: slarticodefast <161409025+slarticodefast@users.noreply.github.com>
Co-authored-by: Connor Huffine <chuffine@gmail.com>
2026-07-13 18:24:31 +00:00

76 lines
2.7 KiB
C#

using Content.Shared.Damage.Events;
using Content.Shared.Examine;
using Content.Shared.Item.ItemToggle;
using Content.Shared.Item.ItemToggle.Components;
using Content.Shared.Popups;
using Content.Shared.Power;
using Content.Shared.Power.Components;
using Content.Shared.Power.EntitySystems;
namespace Content.Shared.Stunnable;
public sealed partial class StunbatonSystem : EntitySystem
{
[Dependency] private SharedBatterySystem _battery = default!;
[Dependency] private ItemToggleSystem _itemToggle = default!;
[Dependency] private SharedPopupSystem _popup = default!;
/// <summary>
/// Handle stamina damage application.
/// Make sure the stunbaton is active and there's enough battery juice.
/// </summary>
[SubscribeLocalEvent]
private void OnStaminaHitAttempt(Entity<StunbatonComponent> entity, ref StaminaDamageOnHitAttemptEvent args)
{
if (_itemToggle.IsActivated(entity.Owner) && _battery.TryUseCharge(entity.Owner, entity.Comp.EnergyPerUse))
return;
args.Cancelled = true;
}
/// <summary>
/// Communicate the stunbaton's status and number of remaining uses.
/// </summary>
[SubscribeLocalEvent]
private void OnExamined(Entity<StunbatonComponent> entity, ref ExaminedEvent args)
{
var onMsg = _itemToggle.IsActivated(entity.Owner)
? Loc.GetString("comp-stunbaton-examined-on")
: Loc.GetString("comp-stunbaton-examined-off");
args.PushMarkup(onMsg);
if (!TryComp<BatteryComponent>(entity, out var battery))
return;
var count = _battery.GetRemainingUses((entity, battery), entity.Comp.EnergyPerUse);
args.PushMarkup(Loc.GetString("melee-battery-examine", ("color", "yellow"), ("count", count)));
}
/// <summary>
/// Handle activation attempt.
/// Make sure there's at least <see cref="StunbatonComponent.EnergyPerUse"/> left in the battery.
/// </summary>
[SubscribeLocalEvent]
private void TryTurnOn(Entity<StunbatonComponent> entity, ref ItemToggleActivateAttemptEvent args)
{
if (_battery.GetCharge(entity.Owner) >= entity.Comp.EnergyPerUse)
return;
args.Cancelled = true;
if (args.User != null)
_popup.PopupEntity(Loc.GetString("stunbaton-component-low-charge"), args.User.Value);
}
/// <summary>
/// Turns off the stunbaton when battery level drops below <see cref="StunbatonComponent.EnergyPerUse"/>.
/// </summary>
[SubscribeLocalEvent]
private void OnChargeChanged(Entity<StunbatonComponent> entity, ref ChargeChangedEvent args)
{
if (_battery.GetCharge(entity.Owner) >= entity.Comp.EnergyPerUse)
return;
_itemToggle.TryDeactivate(entity.Owner);
}
}