using System.Linq; using Content.Shared._White.WeaponModules; using Content.Shared.Actions; using Content.Shared.Examine; using Content.Shared.Hands; using Content.Shared.Verbs; using Content.Shared.Weapons.Ranged.Components; using Robust.Shared.Utility; namespace Content.Shared.Weapons.Ranged.Systems; public abstract partial class SharedGunSystem { private void OnExamine(EntityUid uid, GunComponent component, ExaminedEvent args) { if (!args.IsInDetailsRange || !component.ShowExamineText) return; using (args.PushGroup(nameof(GunComponent))) { args.PushMarkup(Loc.GetString("gun-selected-mode-examine", ("color", ModeExamineColor), ("mode", GetLocSelector(component.SelectedMode)))); args.PushMarkup(Loc.GetString("gun-fire-rate-examine", ("color", FireRateExamineColor), ("fireRate", $"{component.FireRateModified:0.0}"))); if (TryComp(uid, out var weaponModulesComponent)) { if (weaponModulesComponent.Modules.Count == 0) { args.PushMarkup(Loc.GetString("gun-modules", ("modules", "Пусто"))); return; } var moduleNames = weaponModulesComponent.Modules.Select(module => Name(module)).ToArray(); args.PushMarkup(Loc.GetString("gun-modules", ("modules", string.Join(", ", moduleNames)))); } if (!TryComp(uid, out var comp)) return; args.PushMarkup(Loc.GetString("gun-twomode-mode-examine", ("color", TwoModeExamineColor), ("mode", GetLocMode(comp)))); } } private object GetLocMode(TwoModeEnergyAmmoProviderComponent comp) { return Loc.GetString($"gun-twomode-{comp.ModeNames[comp.CurrentMode]}"); } private string GetLocSelector(SelectiveFire mode) { return Loc.GetString($"gun-{mode.ToString()}"); } private void OnAltVerb(EntityUid uid, GunComponent component, GetVerbsEvent args) { if (!args.CanAccess || !args.CanInteract || component.SelectedMode == component.AvailableModes) return; var nextMode = GetNextMode(component); AlternativeVerb verb = new() { Act = () => SelectFire(uid, component, nextMode, args.User), Text = Loc.GetString("gun-selector-verb", ("mode", GetLocSelector(nextMode))), Icon = new SpriteSpecifier.Texture(new("/Textures/Interface/VerbIcons/fold.svg.192dpi.png")), }; args.Verbs.Add(verb); } private SelectiveFire GetNextMode(GunComponent component) { var modes = new List(); foreach (var mode in Enum.GetValues()) { if ((mode & component.AvailableModes) == 0x0) continue; modes.Add(mode); } var index = modes.IndexOf(component.SelectedMode); return modes[(index + 1) % modes.Count]; } private void SelectFire(EntityUid uid, GunComponent component, SelectiveFire fire, EntityUid? user = null) { if (component.SelectedMode == fire) return; DebugTools.Assert((component.AvailableModes & fire) != 0x0); component.SelectedMode = fire; if (!Paused(uid)) { var curTime = Timing.CurTime; var cooldown = TimeSpan.FromSeconds(InteractNextFire); if (component.NextFire < curTime) component.NextFire = curTime + cooldown; else component.NextFire += cooldown; } Audio.PlayPredicted(component.SoundMode, uid, user); Popup(Loc.GetString("gun-selected-mode", ("mode", GetLocSelector(fire))), uid, user); Dirty(uid, component); } /// /// Cycles the gun's to the next available one. /// public void CycleFire(EntityUid uid, GunComponent component, EntityUid? user = null) { // Noop if (component.SelectedMode == component.AvailableModes) return; DebugTools.Assert((component.AvailableModes & component.SelectedMode) == component.SelectedMode); var nextMode = GetNextMode(component); SelectFire(uid, component, nextMode, user); } // TODO: Actions need doing for guns anyway. private sealed partial class CycleModeEvent : InstantActionEvent { public SelectiveFire Mode = default; } private void OnCycleMode(EntityUid uid, GunComponent component, CycleModeEvent args) { SelectFire(uid, component, args.Mode, args.Performer); } private void OnGunSelected(EntityUid uid, GunComponent component, HandSelectedEvent args) { // WD EDIT START if (component.FireRateModified <= 0f) component.FireRateModified = component.FireRate; if (component.FireRateModified <= 0f) return; // WD EDIT END var fireDelay = 1f / component.FireRateModified; if (fireDelay.Equals(0f)) return; if (!component.ResetOnHandSelected) return; if (Paused(uid)) return; // If someone swaps to this weapon then reset its cd. var curTime = Timing.CurTime; var minimum = curTime + TimeSpan.FromSeconds(fireDelay); if (minimum < component.NextFire) return; component.NextFire = minimum; Dirty(uid, component); } }