--- /dev/null
+namespace Content.Server.Ninja.Events;
+
+/// <summary>
+/// Raised on the ninja when the suit has its powercell changed.
+/// </summary>
+[ByRefEvent]
+public record struct NinjaBatteryChangedEvent(EntityUid Battery, EntityUid BatteryHolder);
+using Content.Server.Ninja.Events;
using Content.Server.Power.Components;
using Content.Server.Power.EntitySystems;
using Content.Shared.DoAfter;
base.Initialize();
SubscribeLocalEvent<BatteryDrainerComponent, BeforeInteractHandEvent>(OnBeforeInteractHand);
+ SubscribeLocalEvent<BatteryDrainerComponent, NinjaBatteryChangedEvent>(OnBatteryChanged);
}
/// <summary>
_doAfter.TryStartDoAfter(doAfterArgs);
}
+ private void OnBatteryChanged(EntityUid uid, BatteryDrainerComponent comp, ref NinjaBatteryChangedEvent args)
+ {
+ SetBattery(uid, args.Battery, comp);
+ }
+
/// <inheritdoc/>
protected override void OnDoAfterAttempt(EntityUid uid, BatteryDrainerComponent comp, DoAfterAttemptEvent<DrainDoAfterEvent> args)
{
using Content.Server.Communications;
using Content.Server.DoAfter;
using Content.Server.Mind;
-using Content.Server.Ninja.Systems;
+using Content.Server.Ninja.Events;
using Content.Server.Power.Components;
using Content.Server.Roles;
using Content.Shared.Communications;
public sealed class NinjaGlovesSystem : SharedNinjaGlovesSystem
{
[Dependency] private readonly EmagProviderSystem _emagProvider = default!;
- [Dependency] private readonly SharedBatteryDrainerSystem _drainer = default!;
- [Dependency] private readonly SharedStunProviderSystem _stunProvider = default!;
- [Dependency] private readonly SpaceNinjaSystem _ninja = default!;
[Dependency] private readonly CommsHackerSystem _commsHacker = default!;
[Dependency] private readonly MindSystem _mind = default!;
+ [Dependency] private readonly SharedStunProviderSystem _stunProvider = default!;
+ [Dependency] private readonly SpaceNinjaSystem _ninja = default!;
public override void Initialize()
{
private void EnableGloves(EntityUid uid, NinjaGlovesComponent comp, EntityUid user, SpaceNinjaComponent ninja)
{
+ // can't use abilities if suit is not equipped, this is checked elsewhere but just making sure to satisfy nullability
+ if (ninja.Suit == null)
+ return;
+
comp.User = user;
Dirty(uid, comp);
_ninja.AssignGloves(user, uid, ninja);
_stunProvider.SetNoPowerPopup(user, "ninja-no-power", stun);
if (_ninja.GetNinjaBattery(user, out var battery, out var _))
{
- _drainer.SetBattery(user, battery, drainer);
- _stunProvider.SetBattery(user, battery, stun);
+ var ev = new NinjaBatteryChangedEvent(battery.Value, ninja.Suit.Value);
+ RaiseLocalEvent(user, ref ev);
}
var emag = EnsureComp<EmagProviderComponent>(user);
using Content.Server.Emp;
+using Content.Server.Ninja.Events;
using Content.Server.Popups;
using Content.Server.Power.Components;
using Content.Server.PowerCell;
using Content.Shared.Ninja.Components;
using Content.Shared.Ninja.Systems;
using Content.Shared.Popups;
+using Content.Shared.PowerCell.Components;
using Robust.Shared.Containers;
namespace Content.Server.Ninja.Systems;
// TODO: or put MaxCharge in shared along with powercellslot
private void OnSuitInsertAttempt(EntityUid uid, NinjaSuitComponent comp, ContainerIsInsertingAttemptEvent args)
{
+ // this is for handling battery upgrading, not stopping actions from being added
+ // if another container like ActionsContainer is specified, don't handle it
+ if (TryComp<PowerCellSlotComponent>(uid, out var slot) && args.Container.ID != slot.CellSlotId)
+ return;
+
// no power cell for some reason??? allow it
if (!_powerCell.TryGetBatteryFromSlot(uid, out var battery))
return;
args.Cancel();
}
- // TODO: raise event on ninja telling it to update battery
+ // tell ninja abilities that use battery to update it so they don't use charge from the old one
+ var user = Transform(uid).ParentUid;
+ if (!HasComp<SpaceNinjaComponent>(user))
+ return;
+
+ var ev = new NinjaBatteryChangedEvent(args.EntityUid, uid);
+ RaiseLocalEvent(user, ref ev);
}
private void OnEmpAttempt(EntityUid uid, NinjaSuitComponent comp, EmpAttemptEvent args)
+using Content.Server.Ninja.Events;
+using Content.Server.Power.EntitySystems;
using Content.Shared.Electrocution;
using Content.Shared.Interaction;
using Content.Shared.Ninja.Components;
using Content.Shared.Ninja.Systems;
using Content.Shared.Popups;
using Content.Shared.Whitelist;
-using Content.Server.Power.EntitySystems;
+using Robust.Shared.Audio;
using Robust.Shared.Timing;
namespace Content.Server.Ninja.Systems;
{
[Dependency] private readonly BatterySystem _battery = default!;
[Dependency] private readonly IGameTiming _timing = default!;
+ [Dependency] private readonly SharedAudioSystem _audio = default!;
[Dependency] private readonly SharedElectrocutionSystem _electrocution = default!;
[Dependency] private readonly SharedNinjaGlovesSystem _gloves = default!;
[Dependency] private readonly SharedPopupSystem _popup = default!;
base.Initialize();
SubscribeLocalEvent<StunProviderComponent, BeforeInteractHandEvent>(OnBeforeInteractHand);
+ SubscribeLocalEvent<StunProviderComponent, NinjaBatteryChangedEvent>(OnBatteryChanged);
}
/// <summary>
return;
}
+ _audio.PlayPvs(comp.Sound, target);
+
// not holding hands with target so insuls don't matter
_electrocution.TryDoElectrocution(target, uid, comp.StunDamage, comp.StunTime, false, ignoreInsulation: true);
// short cooldown to prevent instant stunlocking
comp.NextStun = _timing.CurTime + comp.Cooldown;
- Dirty(uid, comp);
args.Handled = true;
}
+
+ private void OnBatteryChanged(EntityUid uid, StunProviderComponent comp, ref NinjaBatteryChangedEvent args)
+ {
+ SetBattery(uid, args.Battery, comp);
+ }
}
using Content.Shared.Ninja.Systems;
using Content.Shared.Whitelist;
+using Robust.Shared.Audio;
using Robust.Shared.GameStates;
using Robust.Shared.Serialization.TypeSerializers.Implementations.Custom;
[DataField("batteryUid"), ViewVariables(VVAccess.ReadWrite), AutoNetworkedField]
public EntityUid? BatteryUid;
+ /// <summary>
+ /// Sound played when stunning someone.
+ /// </summary>
+ [DataField("sound"), ViewVariables(VVAccess.ReadWrite)]
+ public SoundSpecifier Sound = new SoundCollectionSpecifier("sparks");
+
/// <summary>
/// Joules required in the battery to stun someone. Defaults to 10 uses on a small battery.
/// </summary>
/// Time that someone is stunned for, stacks if done multiple times.
/// </summary>
[DataField("stunTime"), ViewVariables(VVAccess.ReadWrite)]
- public TimeSpan StunTime = TimeSpan.FromSeconds(3);
+ public TimeSpan StunTime = TimeSpan.FromSeconds(5);
/// <summary>
/// How long stunning is disabled after stunning something.
/// </summary>
[DataField("cooldown"), ViewVariables(VVAccess.ReadWrite)]
- public TimeSpan Cooldown = TimeSpan.FromSeconds(1);
+ public TimeSpan Cooldown = TimeSpan.FromSeconds(2);
/// <summary>
/// Locale string to popup when there is no power