feat(CS-P3): full siege objective chain - guardian statues (Destructible spawn) + dual Crown Switch hold + throne capture gating
This commit is contained in:
@@ -8,6 +8,7 @@ using System.Collections.Concurrent;
|
||||
using System.Linq;
|
||||
using System.Runtime.InteropServices;
|
||||
using MUnique.OpenMU.GameLogic.CastleSiege;
|
||||
using MUnique.OpenMU.GameLogic.NPC;
|
||||
using MUnique.OpenMU.GameLogic.Views;
|
||||
using MUnique.OpenMU.Interfaces;
|
||||
using MUnique.OpenMU.PlugIns;
|
||||
@@ -23,6 +24,8 @@ using MUnique.OpenMU.PlugIns;
|
||||
public sealed class CastleSiegeEventPlugIn : IPeriodicTaskPlugIn, ISupportCustomConfiguration<CastleSiegeConfiguration>, ISupportDefaultCustomConfiguration
|
||||
{
|
||||
private const ushort ValleyOfLorenMapNumber = 30;
|
||||
private const short GuardianStatueNumber = 132; // reuse the "Statue of Saint" destructible definition
|
||||
private static readonly (byte X, byte Y)[] StatuePositions = { (170, 206), (182, 206) };
|
||||
|
||||
private static readonly ConcurrentDictionary<IGameContext, CastleSiegeContext> Contexts = new();
|
||||
|
||||
@@ -76,7 +79,8 @@ public sealed class CastleSiegeEventPlugIn : IPeriodicTaskPlugIn, ISupportCustom
|
||||
await AnnounceAsync(gameContext, "Castle Siege registration is now open! Guild masters, register at the Guardsman in the Valley of Loren.").ConfigureAwait(false);
|
||||
break;
|
||||
case CastleSiegePhase.Siege:
|
||||
await AnnounceAsync(gameContext, "The Castle Siege has begun! Fight your way to the throne and capture it to win the castle!").ConfigureAwait(false);
|
||||
await AnnounceAsync(gameContext, "The Castle Siege has begun! Destroy the guardian statues, hold both Crown Switches, then take the throne!").ConfigureAwait(false);
|
||||
await SpawnGuardianStatuesAsync(gameContext, context).ConfigureAwait(false);
|
||||
await WarpRegisteredMembersToSiegeAsync(gameContext, context).ConfigureAwait(false);
|
||||
break;
|
||||
case CastleSiegePhase.Ownership when context.OwnerGuildName is { } owner:
|
||||
@@ -97,6 +101,58 @@ public sealed class CastleSiegeEventPlugIn : IPeriodicTaskPlugIn, ISupportCustom
|
||||
=> gameContext.ForEachPlayerAsync(player =>
|
||||
player.InvokeViewPlugInAsync<IShowMessagePlugIn>(p => p.ShowMessageAsync(message, MessageType.GoldenCenter)).AsTask());
|
||||
|
||||
private static async Task SpawnGuardianStatuesAsync(IGameContext gameContext, CastleSiegeContext context)
|
||||
{
|
||||
try
|
||||
{
|
||||
if (gameContext is not GameContext concrete)
|
||||
{
|
||||
context.SetStatueCount(0);
|
||||
return;
|
||||
}
|
||||
|
||||
var map = await gameContext.GetMapAsync(ValleyOfLorenMapNumber).ConfigureAwait(false);
|
||||
var statueDef = gameContext.Configuration.Monsters.FirstOrDefault(m => m.Number == GuardianStatueNumber);
|
||||
if (map is null || statueDef is null)
|
||||
{
|
||||
context.SetStatueCount(0);
|
||||
return;
|
||||
}
|
||||
|
||||
var spawned = 0;
|
||||
for (var i = 0; i < StatuePositions.Length; i++)
|
||||
{
|
||||
var pos = StatuePositions[i];
|
||||
var spawnArea = new MonsterSpawnArea
|
||||
{
|
||||
MonsterDefinition = statueDef,
|
||||
Quantity = 1,
|
||||
X1 = pos.X,
|
||||
X2 = pos.X,
|
||||
Y1 = pos.Y,
|
||||
Y2 = pos.Y,
|
||||
Direction = Direction.South,
|
||||
SpawnTrigger = SpawnTrigger.OnceAtEventStart,
|
||||
};
|
||||
|
||||
var npc = await concrete.MapInitializer.InitializeSpawnAsync(1000 + i, map, spawnArea).ConfigureAwait(false);
|
||||
if (npc is AttackableNpcBase attackable)
|
||||
{
|
||||
attackable.Died += (_, _) => context.NotifyStatueDestroyed();
|
||||
spawned++;
|
||||
}
|
||||
}
|
||||
|
||||
context.SetStatueCount(spawned);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
gameContext.LoggerFactory.CreateLogger<CastleSiegeEventPlugIn>()
|
||||
.LogError(ex, "Castle Siege: error while spawning guardian statues.");
|
||||
context.SetStatueCount(0);
|
||||
}
|
||||
}
|
||||
|
||||
private static async Task WarpRegisteredMembersToSiegeAsync(IGameContext gameContext, CastleSiegeContext context)
|
||||
{
|
||||
try
|
||||
|
||||
Reference in New Issue
Block a user