using System.Linq; using Content.Shared._CP14.MeleeWeapon.Components; using Content.Shared.Damage; using Content.Shared.Examine; using Content.Shared.Interaction; using Content.Shared.Placeable; using Content.Shared.Popups; using Content.Shared.Timing; using Content.Shared.Weapons.Melee.Events; using Content.Shared.Wieldable; using Robust.Shared.Audio.Systems; using Robust.Shared.Network; namespace Content.Shared._CP14.MeleeWeapon.EntitySystems; public sealed class CP14SharpeningSystem : EntitySystem { [Dependency] private readonly DamageableSystem _damageableSystem = default!; [Dependency] private readonly UseDelaySystem _useDelay = default!; [Dependency] private readonly SharedAudioSystem _audio = default!; [Dependency] private readonly SharedPopupSystem _popup = default!; [Dependency] private readonly INetManager _net = default!; public override void Initialize() { base.Initialize(); SubscribeLocalEvent(OnGetMeleeDamage, after: new[] { typeof(WieldableSystem) }); SubscribeLocalEvent(OnExamined); SubscribeLocalEvent(OnMeleeHit); SubscribeLocalEvent(OnAfterInteract); SubscribeLocalEvent(OnInteract); } private void OnMeleeHit(Entity sharpened, ref MeleeHitEvent args) { if (!args.HitEntities.Any()) return; sharpened.Comp.Sharpness = MathHelper.Clamp(sharpened.Comp.Sharpness - args.BaseDamage.GetTotal().Float() * sharpened.Comp.SharpnessDamageBy1Damage, 0.1f, 1f); } private void OnInteract(Entity stone, ref ActivateInWorldEvent args) { if (args.Handled) return; if (!TryComp(stone, out var itemPlacer)) return; if (itemPlacer.PlacedEntities.Count <= 0) return; foreach (var item in itemPlacer.PlacedEntities) { if (!TryComp(item, out var sharpened)) continue; SharpThing(stone, item, sharpened, args.User); return; } } private void OnAfterInteract(Entity stone, ref AfterInteractEvent args) { if (!args.CanReach || args.Target == null || !TryComp(args.Target, out var sharpened)) return; if (TryComp(stone, out var useDelay) && _useDelay.IsDelayed( new Entity(stone, useDelay))) return; SharpThing(stone, args.Target.Value, sharpened, args.User); } private void SharpThing(Entity stone, EntityUid target, CP14SharpenedComponent component, EntityUid user) { var ev = new SharpingEvent() { User = user, Target = target, }; RaiseLocalEvent(stone, ev); if (!ev.Canceled) { _audio.PlayPredicted(stone.Comp.SharpeningSound, target, user); _damageableSystem.TryChangeDamage(stone, stone.Comp.SelfDamage); _damageableSystem.TryChangeDamage(target, stone.Comp.TargetDamage); component.Sharpness = MathHelper.Clamp01(component.Sharpness + stone.Comp.SharpnessHeal); if (_net.IsServer) { Spawn("EffectSparks", Transform(target).Coordinates); if (component.Sharpness >= 0.99) _popup.PopupEntity(Loc.GetString("sharpening-ready"), target, user); } } _useDelay.TryResetDelay(stone); } private void OnExamined(Entity sharpened, ref ExaminedEvent args) { if (sharpened.Comp.Sharpness > 0.95f) { args.PushMarkup(Loc.GetString("sharpening-examined-95")); return; } if (sharpened.Comp.Sharpness > 0.75f) { args.PushMarkup(Loc.GetString("sharpening-examined-75")); return; } if (sharpened.Comp.Sharpness > 0.5f) { args.PushMarkup(Loc.GetString("sharpening-examined-50")); return; } args.PushMarkup(Loc.GetString("sharpening-examined-25")); } private void OnGetMeleeDamage(Entity sharpened, ref GetMeleeDamageEvent args) { args.Damage *= sharpened.Comp.Sharpness; } } /// /// Caused on a sharpening stone when someone tries to sharpen an object with it /// public sealed class SharpingEvent : EntityEventArgs { public bool Canceled = false; public EntityUid User; public EntityUid Target; }