diff --git a/Content.Server/GameObjects/Components/Power/PowerStorageComponent.cs b/Content.Server/GameObjects/Components/Power/PowerStorageComponent.cs index d3dea3e93a..ad07f6ebfc 100644 --- a/Content.Server/GameObjects/Components/Power/PowerStorageComponent.cs +++ b/Content.Server/GameObjects/Components/Power/PowerStorageComponent.cs @@ -84,7 +84,7 @@ namespace Content.Server.GameObjects.Components.Power /// public bool CanDeductCharge(float toDeduct) { - if (Charge > toDeduct) + if (Charge >= toDeduct) return true; return false; } diff --git a/Content.Server/GameObjects/Components/Weapon/Melee/StunbatonComponent.cs b/Content.Server/GameObjects/Components/Weapon/Melee/StunbatonComponent.cs index 21000d1e39..a1a0898ad3 100644 --- a/Content.Server/GameObjects/Components/Weapon/Melee/StunbatonComponent.cs +++ b/Content.Server/GameObjects/Components/Weapon/Melee/StunbatonComponent.cs @@ -1,29 +1,41 @@ -using System.Collections.Generic; +using System.Collections.Generic; using Content.Server.GameObjects.Components.Mobs; +using Content.Server.GameObjects.Components.Power; using Content.Server.GameObjects.EntitySystems; +using Content.Server.Interfaces.GameObjects; using Content.Shared.Audio; +using Content.Shared.GameObjects; +using Content.Shared.Interfaces; using Robust.Server.GameObjects; +using Robust.Server.GameObjects.Components.Container; using Robust.Server.GameObjects.EntitySystems; +using Robust.Server.Interfaces.GameObjects; using Robust.Shared.GameObjects; using Robust.Shared.Interfaces.GameObjects; using Robust.Shared.Interfaces.Random; using Robust.Shared.IoC; +using Robust.Shared.Localization; using Robust.Shared.Random; using Robust.Shared.Serialization; +using Robust.Shared.Utility; using Robust.Shared.ViewVariables; namespace Content.Server.GameObjects.Components.Weapon.Melee { [RegisterComponent] - public class StunbatonComponent : MeleeWeaponComponent, IUse + public class StunbatonComponent : MeleeWeaponComponent, IUse, IExamine, IMapInit, IInteractUsing { [Dependency] private IRobustRandom _robustRandom; [Dependency] private IEntitySystemManager _entitySystemManager; + [Dependency] private readonly ISharedNotifyManager _notifyManager; + [Dependency] private readonly ILocalizationManager _localizationManager; public override string Name => "Stunbaton"; private bool _activated = false; + [ViewVariables] private ContainerSlot _cellContainer; + [ViewVariables(VVAccess.ReadWrite)] private float _paralyzeChance = 0.25f; @@ -33,9 +45,30 @@ namespace Content.Server.GameObjects.Components.Weapon.Melee [ViewVariables(VVAccess.ReadWrite)] private float _slowdownTime = 5f; + [ViewVariables(VVAccess.ReadWrite)] public float EnergyPerUse { get; set; } = 1000; + [ViewVariables] public bool Activated => _activated; + [ViewVariables] + private PowerCellComponent Cell + { + get + { + if (_cellContainer.ContainedEntity == null) return null; + + _cellContainer.ContainedEntity.TryGetComponent(out PowerCellComponent cell); + return cell; + } + } + + public override void Initialize() + { + base.Initialize(); + _cellContainer = + ContainerManagerComponent.Ensure("stunbaton_cell_container", Owner, out var existed); + } + public override void ExposeData(ObjectSerializer serializer) { base.ExposeData(serializer); @@ -47,11 +80,11 @@ namespace Content.Server.GameObjects.Components.Weapon.Melee public override bool OnHitEntities(IReadOnlyList entities) { - if (!Activated || entities.Count == 0) + var cell = Cell; + if (!Activated || entities.Count == 0 || cell == null || !cell.CanDeductCharge(EnergyPerUse)) return false; - _entitySystemManager.GetEntitySystem() - .Play("/Audio/weapons/egloves.ogg", Owner.Transform.GridPosition, AudioHelpers.WithVariation(0.25f)); + _entitySystemManager.GetEntitySystem().Play("/Audio/weapons/egloves.ogg", Owner.Transform.GridPosition, AudioHelpers.WithVariation(0.25f)); foreach (var entity in entities) { @@ -63,31 +96,175 @@ namespace Content.Server.GameObjects.Components.Weapon.Melee stunnable.Slowdown(_slowdownTime); } + cell.DeductCharge(EnergyPerUse); + if(cell.Charge < EnergyPerUse) + { + _entitySystemManager.GetEntitySystem().Play(AudioHelpers.GetRandomFileFromSoundCollection("sparks"), Owner.Transform.GridPosition, AudioHelpers.WithVariation(0.25f)); + TurnOff(); + } + return false; } - public bool UseEntity(UseEntityEventArgs eventArgs) + private bool ToggleStatus(IEntity user) { - var sprite = Owner.GetComponent(); - var item = Owner.GetComponent(); - - if (_activated) + if (Activated) { - item.EquippedPrefix = "off"; - sprite.LayerSetState(0, "stunbaton_off"); - _activated = false; + TurnOff(); } else { - _entitySystemManager.GetEntitySystem() - .Play(AudioHelpers.GetRandomFileFromSoundCollection("sparks"), Owner.Transform.GridPosition, AudioHelpers.WithVariation(0.25f)); - - item.EquippedPrefix = "on"; - sprite.LayerSetState(0, "stunbaton_on"); - _activated = true; + TurnOn(user); } return true; } + + private void TurnOff() + { + if (!_activated) + { + return; + } + + var sprite = Owner.GetComponent(); + var item = Owner.GetComponent(); + + _entitySystemManager.GetEntitySystem().Play(AudioHelpers.GetRandomFileFromSoundCollection("sparks"), Owner.Transform.GridPosition, AudioHelpers.WithVariation(0.25f)); + + item.EquippedPrefix = "off"; + sprite.LayerSetState(0, "stunbaton_off"); + _activated = false; + } + + private void TurnOn(IEntity user) + { + if (_activated) + { + return; + } + + var sprite = Owner.GetComponent(); + var item = Owner.GetComponent(); + var cell = Cell; + + if (cell == null) + { + _entitySystemManager.GetEntitySystem().Play("/Audio/machines/button.ogg", Owner.Transform.GridPosition, AudioHelpers.WithVariation(0.25f)); + + _notifyManager.PopupMessage(Owner, user, _localizationManager.GetString("Cell missing...")); + return; + } + + if (cell.Charge < EnergyPerUse) + { + _entitySystemManager.GetEntitySystem().Play("/Audio/machines/button.ogg", Owner.Transform.GridPosition, AudioHelpers.WithVariation(0.25f)); + _notifyManager.PopupMessage(Owner, user, _localizationManager.GetString("Dead cell...")); + return; + } + + _entitySystemManager.GetEntitySystem().Play(AudioHelpers.GetRandomFileFromSoundCollection("sparks"), Owner.Transform.GridPosition, AudioHelpers.WithVariation(0.25f)); + + item.EquippedPrefix = "on"; + sprite.LayerSetState(0, "stunbaton_on"); + _activated = true; + } + + public bool UseEntity(UseEntityEventArgs eventArgs) + { + ToggleStatus(eventArgs.User); + + return true; + } + + public bool InteractUsing(InteractUsingEventArgs eventArgs) + { + if (!eventArgs.Using.HasComponent()) return false; + + if (Cell != null) return false; + + var handsComponent = eventArgs.User.GetComponent(); + + if (!handsComponent.Drop(eventArgs.Using, _cellContainer)) + { + return false; + } + + _entitySystemManager.GetEntitySystem().Play("/Audio/items/weapons/pistol_magin.ogg"); + + Dirty(); + + return true; + } + + private void EjectCell(IEntity user) + { + if (Cell == null) + { + return; + } + + var cell = Cell; + + if (!_cellContainer.Remove(cell.Owner)) + { + return; + } + + if (!user.TryGetComponent(out HandsComponent hands)) + { + return; + } + + if (!hands.PutInHand(cell.Owner.GetComponent())) + { + cell.Owner.Transform.GridPosition = user.Transform.GridPosition; + } + + _entitySystemManager.GetEntitySystem().Play("/Audio/items/weapons/pistol_magout.ogg", Owner.Transform.GridPosition, AudioHelpers.WithVariation(0.25f)); + } + + public void Examine(FormattedMessage message) + { + var loc = IoCManager.Resolve(); + + if (Activated) + { + message.AddMarkup(loc.GetString("The light is currently [color=darkgreen]on[/color].")); + } + } + + public void MapInit() + { + if (_cellContainer.ContainedEntity != null) + { + return; + } + + var cell = Owner.EntityManager.SpawnEntity("PowerCellSmallHyper", Owner.Transform.GridPosition); + _cellContainer.Insert(cell); + } + + [Verb] + public sealed class EjectCellVerb : Verb + { + protected override void GetData(IEntity user, StunbatonComponent component, VerbData data) + { + if (component.Cell == null) + { + data.Text = "Eject cell (cell missing)"; + data.Visibility = VerbVisibility.Disabled; + } + else + { + data.Text = "Eject cell"; + } + } + + protected override void Activate(IEntity user, StunbatonComponent component) + { + component.EjectCell(user); + } + } } }