// // Licensed under the MIT License. See LICENSE file in the project root for full license information. // namespace MUnique.OpenMU.GameLogic.CastleSiege; using System.Linq; using System.Runtime.InteropServices; using MUnique.OpenMU.GameLogic.NPC; using MUnique.OpenMU.GameLogic.PlugIns; using MUnique.OpenMU.GameLogic.PlugIns.PeriodicTasks; using MUnique.OpenMU.GameLogic.Views; using MUnique.OpenMU.Interfaces; using MUnique.OpenMU.PlugIns; /// /// Handles registering on the throne at the Sinior (223) / Crown (216) NPCs on Valley of Loren. /// A registered guild takes the throne only when it has destroyed all castle defenses (gates + statues) /// AND is holding both Crown Switches (a member standing on each). The guild on the throne when the siege /// ends becomes the castle owner. Capturing broadcasts a server-wide golden message. /// [Guid("CA5710A0-7A1B-4C2D-8E3F-000000000223")] [PlugIn] [Display(Name = "Castle Siege Throne (Sinior/Crown)", Description = "Registers a guild on the throne (Sinior 223 / Crown 216) once defenses are down and both switches held.")] public class CastleSiegeThroneCaptureTalkPlugIn : IPlayerTalkToNpcPlugIn { private static readonly short[] ThroneNpcNumbers = { 223, 216 }; /// public async ValueTask PlayerTalksToNpcAsync(Player player, NonPlayerCharacter npc, NpcTalkEventArgs eventArgs) { if (!ThroneNpcNumbers.Contains(npc.Definition.Number)) { return; } eventArgs.HasBeenHandled = true; var context = CastleSiegeEventPlugIn.TryGetContext(player.GameContext); if (context is null) { await ShowAsync(player, "Castle Siege is not active on this server.").ConfigureAwait(false); return; } if (player.GuildStatus is not { } guildStatus) { await ShowAsync(player, "Only members of a registered guild can take the throne.").ConfigureAwait(false); return; } var guildName = guildStatus.GuildId.ToString(); if (player.GameContext is IGameServerContext serverContext) { var guild = await serverContext.GuildServer.GetGuildAsync(guildStatus.GuildId).ConfigureAwait(false); if (guild?.Name is { Length: > 0 } name) { guildName = name; } } if (!context.RegisteredGuilds.Contains(guildName)) { await ShowAsync(player, "Your guild is not registered for this Castle Siege.").ConfigureAwait(false); return; } // The throne is taken by holding the Crown, not by talking here — give guidance based on the state. await ShowAsync(player, DescribeThroneStep(context, guildName)).ConfigureAwait(false); } private static string DescribeThroneStep(CastleSiegeContext context, string guildName) { if (context.Phase != CastleSiegePhase.Siege) { return "The siege is not running yet."; } if (context.DefensesRemaining > 0) { return $"Destroy all castle gates first ({context.DefensesRemaining} remaining), then hold both Crown Switches."; } var eligible = context.GetShieldEligibleGuild(); if (eligible is null) { return "All gates are down! Hold BOTH Crown Switches with your guild — the Crown's shield will drop."; } if (eligible == guildName) { return "Your guild holds both switches and the shield is down — send your GUILD MASTER to hold the Crown to take the throne!"; } return $"Guild '{eligible}' is holding both switches. Take a switch back to raise their shield."; } private static ValueTask ShowAsync(Player player, string text) => player.InvokeViewPlugInAsync(p => p.ShowMessageAsync(text, MessageType.BlueNormal)); }