diff --git a/Content.Server/Flash/Components/FlashComponent.cs b/Content.Server/Flash/Components/FlashComponent.cs index 53213f65d8..3f2ca0e389 100644 --- a/Content.Server/Flash/Components/FlashComponent.cs +++ b/Content.Server/Flash/Components/FlashComponent.cs @@ -9,10 +9,6 @@ namespace Content.Server.Flash.Components [ViewVariables(VVAccess.ReadWrite)] public int FlashDuration { get; set; } = 5000; - [DataField("uses")] - [ViewVariables(VVAccess.ReadWrite)] - public int Uses { get; set; } = 5; - [DataField("range")] [ViewVariables(VVAccess.ReadWrite)] public float Range { get; set; } = 7f; @@ -30,7 +26,5 @@ namespace Content.Server.Flash.Components public SoundSpecifier Sound { get; set; } = new SoundPathSpecifier("/Audio/Weapons/flash.ogg"); public bool Flashing; - - public bool HasUses => Uses > 0; } } diff --git a/Content.Server/Flash/FlashSystem.cs b/Content.Server/Flash/FlashSystem.cs index 40bb9eb6f0..6cab18daf3 100644 --- a/Content.Server/Flash/FlashSystem.cs +++ b/Content.Server/Flash/FlashSystem.cs @@ -3,7 +3,8 @@ using Content.Server.Flash.Components; using Content.Server.Light.EntitySystems; using Content.Server.Popups; using Content.Server.Stunnable; -using Content.Shared.Examine; +using Content.Shared.Charges.Components; +using Content.Shared.Charges.Systems; using Content.Shared.Eye.Blinding.Components; using Content.Shared.Flash; using Content.Shared.IdentityManagement; @@ -25,22 +26,23 @@ namespace Content.Server.Flash { internal sealed class FlashSystem : SharedFlashSystem { - [Dependency] private readonly EntityLookupSystem _entityLookup = default!; - [Dependency] private readonly IGameTiming _gameTiming = default!; - [Dependency] private readonly StunSystem _stunSystem = default!; - [Dependency] private readonly InventorySystem _inventorySystem = default!; - [Dependency] private readonly AudioSystem _audio = default!; - [Dependency] private readonly SharedInteractionSystem _interactionSystem = default!; - [Dependency] private readonly TagSystem _tagSystem = default!; - [Dependency] private readonly PopupSystem _popup = default!; [Dependency] private readonly AppearanceSystem _appearance = default!; + [Dependency] private readonly AudioSystem _audio = default!; + [Dependency] private readonly SharedChargesSystem _charges = default!; + [Dependency] private readonly EntityLookupSystem _entityLookup = default!; + [Dependency] private readonly IGameTiming _timing = default!; + [Dependency] private readonly SharedInteractionSystem _interaction = default!; + [Dependency] private readonly InventorySystem _inventory = default!; + [Dependency] private readonly PopupSystem _popup = default!; + [Dependency] private readonly StunSystem _stun = default!; + [Dependency] private readonly TagSystem _tag = default!; public override void Initialize() { base.Initialize(); SubscribeLocalEvent(OnFlashMeleeHit); + // ran before toggling light for extra-bright lantern SubscribeLocalEvent(OnFlashUseInHand, before: new []{ typeof(HandheldLightSystem) }); - SubscribeLocalEvent(OnFlashExamined); SubscribeLocalEvent(OnInventoryFlashAttempt); @@ -76,18 +78,22 @@ namespace Content.Server.Flash private bool UseFlash(EntityUid uid, FlashComponent comp, EntityUid user) { - if (!comp.HasUses || comp.Flashing) + if (comp.Flashing) return false; - comp.Uses--; + TryComp(uid, out var charges); + if (_charges.IsEmpty(uid, charges)) + return false; + + _charges.UseCharge(uid, charges); _audio.PlayPvs(comp.Sound, uid); comp.Flashing = true; _appearance.SetData(uid, FlashVisuals.Flashing, true); - if (comp.Uses == 0) + if (_charges.IsEmpty(uid, charges)) { _appearance.SetData(uid, FlashVisuals.Burnt, true); - _tagSystem.AddTag(uid, "Trash"); + _tag.AddTag(uid, "Trash"); _popup.PopupEntity(Loc.GetString("flash-component-becomes-empty"), user); } @@ -110,11 +116,11 @@ namespace Content.Server.Flash if (attempt.Cancelled) return; - flashable.LastFlash = _gameTiming.CurTime; + flashable.LastFlash = _timing.CurTime; flashable.Duration = flashDuration / 1000f; // TODO: Make this sane... Dirty(flashable); - _stunSystem.TrySlowdown(target, TimeSpan.FromSeconds(flashDuration/1000f), true, + _stun.TrySlowdown(target, TimeSpan.FromSeconds(flashDuration/1000f), true, slowTo, slowTo); if (displayPopup && user != null && target != user && EntityManager.EntityExists(user.Value)) @@ -142,7 +148,7 @@ namespace Content.Server.Flash foreach (var entity in flashableEntities) { // Check for unobstructed entities while ignoring the mobs with flashable components. - if (!_interactionSystem.InRangeUnobstructed(entity, mapPosition, range, CollisionGroup.Opaque, (e) => flashableEntities.Contains(e) || e == source)) + if (!_interaction.InRangeUnobstructed(entity, mapPosition, range, CollisionGroup.Opaque, (e) => flashableEntities.Contains(e) || e == source)) continue; // They shouldn't have flash removed in between right? @@ -154,33 +160,13 @@ namespace Content.Server.Flash } } - private void OnFlashExamined(EntityUid uid, FlashComponent comp, ExaminedEvent args) - { - if (!comp.HasUses) - { - args.PushText(Loc.GetString("flash-component-examine-empty")); - return; - } - - if (args.IsInDetailsRange) - { - args.PushMarkup( - Loc.GetString( - "flash-component-examine-detail-count", - ("count", comp.Uses), - ("markupCountColor", "green") - ) - ); - } - } - private void OnInventoryFlashAttempt(EntityUid uid, InventoryComponent component, FlashAttemptEvent args) { foreach (var slot in new[] { "head", "eyes", "mask" }) { if (args.Cancelled) break; - if (_inventorySystem.TryGetSlotEntity(uid, slot, out var item, component)) + if (_inventory.TryGetSlotEntity(uid, slot, out var item, component)) RaiseLocalEvent(item.Value, args, true); } } diff --git a/Resources/Locale/en-US/flash/components/flash-component.ftl b/Resources/Locale/en-US/flash/components/flash-component.ftl index 352077fa0f..efa44287eb 100644 --- a/Resources/Locale/en-US/flash/components/flash-component.ftl +++ b/Resources/Locale/en-US/flash/components/flash-component.ftl @@ -1,19 +1,7 @@ - -### UI - -# Shown when an empty flash is examined at any range -flash-component-examine-empty = It's burnt out! - -# Shown when a flash is examined in details range -flash-component-examine-detail-count = The flash has [color={$markupCountColor}]{$count}[/color] {$count -> - [one] use - *[other] uses -} remaining. - ### Interaction Messages # Shown when someone flashes you with a flash flash-component-user-blinds-you = {$user} blinds you with the flash! # Shown when a flash runs out of uses -flash-component-becomes-empty = The flash burns out! \ No newline at end of file +flash-component-becomes-empty = The flash burns out! diff --git a/Resources/Prototypes/Entities/Objects/Tools/lantern.yml b/Resources/Prototypes/Entities/Objects/Tools/lantern.yml index 2262675d35..11cbf0ff65 100644 --- a/Resources/Prototypes/Entities/Objects/Tools/lantern.yml +++ b/Resources/Prototypes/Entities/Objects/Tools/lantern.yml @@ -83,7 +83,13 @@ energy: 10 color: "#FFC458" - type: Flash - uses: 15 + - type: LimitedCharges + maxCharges: 15 + charges: 15 + - type: MeleeWeapon + damage: + types: + Blunt: 0 # melee weapon to allow flashing individual targets - type: Appearance - type: GenericVisualizer visuals: diff --git a/Resources/Prototypes/Entities/Objects/Weapons/security.yml b/Resources/Prototypes/Entities/Objects/Weapons/security.yml index 8e3e333090..f56fcbef36 100644 --- a/Resources/Prototypes/Entities/Objects/Weapons/security.yml +++ b/Resources/Prototypes/Entities/Objects/Weapons/security.yml @@ -61,10 +61,13 @@ visible: false shader: unshaded - type: Flash + - type: LimitedCharges + maxCharges: 5 + charges: 5 - type: MeleeWeapon damage: types: - Blunt: 0 # why is this classed as a melee weapon? Is it needed for some interaction? + Blunt: 0 # melee weapon to allow flashing individual targets angle: 10 - type: Item size: 5 @@ -127,4 +130,3 @@ radius: 0 softness: 0 enabled: true -