using Content.Server._DV.CosmicCult.Components; using Content.Shared._DV.CosmicCult; using Content.Shared._DV.CosmicCult.Components; using Content.Shared.Audio; using Content.Shared.DoAfter; using Content.Shared.Humanoid; using Content.Shared.Interaction; using Content.Shared.UserInterface; using Robust.Shared.Utility; namespace Content.Server._DV.CosmicCult; public sealed partial class CosmicCultSystem : SharedCosmicCultSystem { /// /// Used to calculate when the finale song should start playing /// public void SubscribeFinale() { SubscribeLocalEvent(OnInteract); SubscribeLocalEvent(OnFinaleStartDoAfter); SubscribeLocalEvent(OnFinaleCancelDoAfter); } private void OnInteract(Entity ent, ref InteractHandEvent args) { if (!HasComp(args.User)) return; // humanoids only! if (!EntityIsCultist(args.User) && !args.Handled && !ent.Comp.Occupied && ent.Comp.FinaleActive) { ent.Comp.Occupied = true; var doargs = new DoAfterArgs(EntityManager, args.User, ent.Comp.InteractionTime, new CancelFinaleDoAfterEvent(), ent, ent) { DistanceThreshold = 1f, Hidden = false, BreakOnHandChange = true, BreakOnDamage = true, BreakOnMove = true }; _popup.PopupEntity(Loc.GetString("cosmiccult-finale-cancel-begin"), args.User, args.User); _doAfter.TryStartDoAfter(doargs); args.Handled = true; } else if (EntityIsCultist(args.User) && !args.Handled && !ent.Comp.Occupied && !ent.Comp.FinaleActive && ent.Comp.CurrentState != FinaleState.Unavailable) { ent.Comp.Occupied = true; var doargs = new DoAfterArgs(EntityManager, args.User, ent.Comp.InteractionTime, new StartFinaleDoAfterEvent(), ent, ent) { DistanceThreshold = 1f, Hidden = false, BreakOnHandChange = true, BreakOnDamage = true, BreakOnMove = true }; _popup.PopupEntity(Loc.GetString("cosmiccult-finale-beckon-begin"), args.User, args.User); _doAfter.TryStartDoAfter(doargs); args.Handled = true; } } private void OnFinaleStartDoAfter(Entity uid, ref StartFinaleDoAfterEvent args) { if (args.Args.Target == null || args.Cancelled || args.Handled) { uid.Comp.Occupied = false; return; } _popup.PopupEntity(Loc.GetString("cosmiccult-finale-beckon-success"), args.Args.User, args.Args.User); StartFinale(uid); } private void StartFinale(Entity uid) { var comp = uid.Comp; var indicatedLocation = FormattedMessage.RemoveMarkupOrThrow(_navMap.GetNearestBeaconString((uid, Transform(uid)))); if (!TryComp(uid, out var monument) || !TryComp(uid, out var corruptingComp)) return; comp.FinaleTimer = _timing.CurTime + comp.FinaleRemainingTime; comp.SelectedSong = comp.FinaleMusic; uid.Comp.CurrentState = FinaleState.ActiveFinale; _corrupting.SetCorruptionTime((uid, corruptingComp), TimeSpan.FromSeconds(1)); _appearance.SetData(uid, MonumentVisuals.FinaleReached, 2); _sound.DispatchStationEventMusic(uid, comp.SelectedSong, StationEventMusicType.CosmicCult); _chatSystem.DispatchStationAnnouncement(uid, Loc.GetString("cosmiccult-finale-location", ("location", indicatedLocation)), null, false, null, Color.FromHex("#cae8e8")); var stationUid = _station.GetStationInMap(Transform(uid).MapID); if (stationUid != null) { _alert.SetLevel(stationUid.Value, "octarine", true, true, true, true); } if (TryComp(uid, out var uiComp)) uiComp.Key = MonumentKey.Key; // wow! This is the laziest way to enable a UI ever! _monument.Enable((uid, monument)); comp.FinaleActive = true; comp.FinaleAnnounceCheck = true; Dirty(uid, monument); _ui.SetUiState(uid.Owner, MonumentKey.Key, new MonumentBuiState(monument)); } private void OnFinaleCancelDoAfter(Entity uid, ref CancelFinaleDoAfterEvent args) { var comp = uid.Comp; if (args.Args.Target is not {} target || args.Cancelled || args.Handled) { uid.Comp.Occupied = false; return; } var stationUid = _station.GetOwningStation(uid); if (stationUid != null) _alert.SetLevel(stationUid.Value, "green", true, true, true); _sound.PlayGlobalOnStation(uid, _audio.ResolveSound(comp.CancelEventSound)); _sound.StopStationEventMusic(uid, StationEventMusicType.CosmicCult); uid.Comp.CurrentState = FinaleState.ReadyFinale; if (TryComp(uid, out var corruptingComp)) _corrupting.SetCorruptionTime((uid, corruptingComp), TimeSpan.FromSeconds(6)); if (TryComp(uid, out var uiComp)) { _ui.CloseUi(uid.Owner, MonumentKey.Key); uiComp.Key = null; //kazne called this the laziest way to disable a UI ever } _appearance.SetData(uid, MonumentVisuals.FinaleReached, 1); if (!TryComp(target, out var monument)) return; _monument.Disable((uid, monument)); comp.FinaleActive = false; comp.FinaleAnnounceCheck = false; Dirty(target, monument); _ui.SetUiState(uid.Owner, MonumentKey.Key, new MonumentBuiState(monument)); } }