//
// Licensed under the MIT License. See LICENSE file in the project root for full license information.
//
namespace MUnique.OpenMU.GameLogic.CastleSiege;
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 talking to the Castle Siege 'Guardsman' NPC (number 224): registers the talking
/// player's guild for the current siege while the state machine is in the registration phase.
/// P2 first increment — guild marks, entrance fee and minimum-guild requirements come later.
///
[Guid("CA5710A0-7A1B-4C2D-8E3F-000000000224")]
[PlugIn]
[Display(Name = "Castle Siege Guardsman", Description = "Registers a guild for the Castle Siege when talking to the Guardsman (NPC 224).")]
public class CastleSiegeGuardsmanTalkPlugIn : IPlayerTalkToNpcPlugIn
{
/// Gets the NPC number of the Castle Siege 'Guardsman'.
public static short GuardsmanNpcNumber => 224;
///
public async ValueTask PlayerTalksToNpcAsync(Player player, NonPlayerCharacter npc, NpcTalkEventArgs eventArgs)
{
if (npc.Definition.Number != GuardsmanNpcNumber)
{
return;
}
// We handle the dialog ourselves (no client-side window), so suppress the default "not implemented" message.
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 (!CastleSiegeEventPlugIn.IsCastleSiegeServer(player.GameContext))
{
await ShowAsync(player, $"The Castle Siege runs on server {context.Configuration.CastleSiegeServerId}. Switch to that server to register and fight.").ConfigureAwait(false);
return;
}
if (context.State != CastleSiegeState.RegisterGuild)
{
await ShowAsync(player, "Castle Siege registration is not open right now.").ConfigureAwait(false);
return;
}
if (player.GuildStatus is not { } guildStatus || guildStatus.Position != GuildPosition.GuildMaster)
{
await ShowAsync(player, "Only a guild master can register for the Castle Siege.").ConfigureAwait(false);
return;
}
// Registrations are keyed on the guild's persistent id, so a later rename cannot detach them.
if (await CastleSiegeEventPlugIn.GetPersistentGuildAsync(player).ConfigureAwait(false) is not { } guild)
{
await ShowAsync(player, "Your guild could not be resolved. Please try again in a moment.").ConfigureAwait(false);
return;
}
var guildName = guild.Name;
if (context.IsRegistered(guild.Id))
{
await ShowAsync(player, $"Your guild '{guildName}' is already registered for the Castle Siege.").ConfigureAwait(false);
return;
}
var fee = context.Configuration.RegistrationFee;
if (fee > 0 && !player.TryRemoveMoney(fee))
{
await ShowAsync(player, $"You need {fee} zen to register your guild for the Castle Siege.").ConfigureAwait(false);
return;
}
context.RegisterGuild(guild.Id, guildName);
await ShowAsync(player, fee > 0
? $"Your guild '{guildName}' is registered for the Castle Siege. ({fee} zen paid)"
: $"Your guild '{guildName}' is registered for the Castle Siege.").ConfigureAwait(false);
}
private static ValueTask ShowAsync(Player player, string text)
=> player.InvokeViewPlugInAsync(p => p.ShowMessageAsync(text, MessageType.BlueNormal));
}