Some checks failed
.NET Core / build (push) Has been cancelled
With multiple game servers each has its own map instances, so the siege ran independently on all of them - a guild could win uncontested on an empty server's Valley of Loren. Now the siege (tick/spawn/battle/registration) runs only on the server whose Id == config.CastleSiegeServerId (AdminPanel-editable). Other servers skip the siege and just mirror the shared castle owner from config so the hunting-map gate + castle flag rewards still work everywhere. The Guardsman on non-siege servers tells players which server to switch to.
96 lines
3.9 KiB
C#
96 lines
3.9 KiB
C#
// <copyright file="CastleSiegeGuardsmanTalkPlugIn.cs" company="MUnique">
|
|
// Licensed under the MIT License. See LICENSE file in the project root for full license information.
|
|
// </copyright>
|
|
|
|
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;
|
|
|
|
/// <summary>
|
|
/// 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.
|
|
/// </summary>
|
|
[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
|
|
{
|
|
/// <summary>Gets the NPC number of the Castle Siege 'Guardsman'.</summary>
|
|
public static short GuardsmanNpcNumber => 224;
|
|
|
|
/// <inheritdoc />
|
|
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.Phase != CastleSiegePhase.Registration)
|
|
{
|
|
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;
|
|
}
|
|
|
|
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 '{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(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<IShowMessagePlugIn>(p => p.ShowMessageAsync(text, MessageType.BlueNormal));
|
|
}
|