feat(CS-P3): siege PvP on Valley of Loren during siege (ADAMU-CUSTOM) + golden phase announcements
Some checks failed
.NET Core / build (push) Has been cancelled

This commit is contained in:
Acentech Dev
2026-07-15 01:23:57 +03:00
parent c7147f7a63
commit 5549c2bec7
3 changed files with 45 additions and 10 deletions

View File

@@ -166,7 +166,8 @@ docker push <hub>/adamu-openmu:<tag>
| `GameLogic/PlayerActions/TalkNpcAction.cs` | 0b | remote-NPC: `TalkToNpcByNumberAsync` (additive metod) | ✅ Uygulandı, `// ADAMU-CUSTOM` işaretli | | `GameLogic/PlayerActions/TalkNpcAction.cs` | 0b | remote-NPC: `TalkToNpcByNumberAsync` (additive metod) | ✅ Uygulandı, `// ADAMU-CUSTOM` işaretli |
| `GameLogic/GameMap.cs` | 0b | remote-NPC: `GetNpcByNumber` helper (additive metod) | ✅ Uygulandı, `// ADAMU-CUSTOM` işaretli; test: `GameMapTest.GetNpcByNumberFindsSpawnedNpcAsync` | | `GameLogic/GameMap.cs` | 0b | remote-NPC: `GetNpcByNumber` helper (additive metod) | ✅ Uygulandı, `// ADAMU-CUSTOM` işaretli; test: `GameMapTest.GetNpcByNumberFindsSpawnedNpcAsync` |
| `GameServer/MessageHandler/TalkNpcHandlerPlugInBase.cs` | 0b | remote-NPC: `0x8000` marker dalı (tek gerçek core-logic dokunuşu) | ✅ Uygulandı, `// ADAMU-CUSTOM` işaretli | | `GameServer/MessageHandler/TalkNpcHandlerPlugInBase.cs` | 0b | remote-NPC: `0x8000` marker dalı (tek gerçek core-logic dokunuşu) | ✅ Uygulandı, `// ADAMU-CUSTOM` işaretli |
| DataModel + Initialization (CS entity'leri) | P1 | CS persistence | ⏳ Planlanacak (EF migration gerekir) | | `GameLogic/Player.cs` | P3 | CS PvP: Siege fazında Valley of Loren'de (map 30) kill izni (`IsCastleSiegeBattleActive`) | ✅ Uygulandı, `// ADAMU-CUSTOM` |
| DataModel + Initialization (CS entity'leri) | P4 | CS persistence (sahiplik/vergi) | ⏳ Planlanacak (EF migration gerekir) |
| *(fazlar ilerledikçe eklenecek)* | | | | | *(fazlar ilerledikçe eklenecek)* | | | |
## 10. Test stratejisi ## 10. Test stratejisi

View File

@@ -709,6 +709,11 @@ public class Player : AsyncDisposable, IBucketMapObserver, IAttackable, IAttacke
return this.InvokeViewPlugInAsync<IShowMessagePlugIn>(p => p.ShowMessageAsync(message, MessageType.BlueNormal)); return this.InvokeViewPlugInAsync<IShowMessagePlugIn>(p => p.ShowMessageAsync(message, MessageType.BlueNormal));
} }
// ADAMU-CUSTOM: Castle Siege PvP gate — true while the siege phase runs on Valley of Loren (map 30).
private bool IsCastleSiegeBattleActive()
=> this.CurrentMap?.Definition.Number == 30
&& PlugIns.PeriodicTasks.CastleSiegeEventPlugIn.TryGetContext(this.GameContext)?.Phase == CastleSiege.CastleSiegePhase.Siege;
/// <inheritdoc/> /// <inheritdoc/>
public async ValueTask<HitInfo?> AttackByAsync(IAttacker attacker, SkillEntry? skill, bool isCombo, double damageFactor = 1.0, bool? isFinalStreakHit = null) public async ValueTask<HitInfo?> AttackByAsync(IAttacker attacker, SkillEntry? skill, bool isCombo, double damageFactor = 1.0, bool? isFinalStreakHit = null)
{ {
@@ -723,7 +728,10 @@ public class Player : AsyncDisposable, IBucketMapObserver, IAttackable, IAttacke
} }
if (!this.GameContext.PvpEnabled && this.CurrentMap?.Definition.BattleZone == null && if (!this.GameContext.PvpEnabled && this.CurrentMap?.Definition.BattleZone == null &&
this.CurrentMiniGame?.AllowPlayerKilling is false) this.CurrentMiniGame?.AllowPlayerKilling is false
// ADAMU-CUSTOM: Castle Siege — enable PvP on Valley of Loren (30) while the siege phase runs.
&& !this.IsCastleSiegeBattleActive())
{ {
return null; return null;
} }

View File

@@ -8,6 +8,7 @@ using System.Collections.Concurrent;
using System.Linq; using System.Linq;
using System.Runtime.InteropServices; using System.Runtime.InteropServices;
using MUnique.OpenMU.GameLogic.CastleSiege; using MUnique.OpenMU.GameLogic.CastleSiege;
using MUnique.OpenMU.GameLogic.Views;
using MUnique.OpenMU.Interfaces; using MUnique.OpenMU.Interfaces;
using MUnique.OpenMU.PlugIns; using MUnique.OpenMU.PlugIns;
@@ -46,14 +47,8 @@ public sealed class CastleSiegeEventPlugIn : IPeriodicTaskPlugIn, ISupportCustom
{ {
var created = new CastleSiegeContext(this.Configuration ?? new CastleSiegeConfiguration()); var created = new CastleSiegeContext(this.Configuration ?? new CastleSiegeConfiguration());
// When the siege phase begins, pull all registered guild members onto the battle map. // Announce phase changes to the whole server and, when the siege begins, warp registered members.
created.PhaseChanged += phase => created.PhaseChanged += phase => _ = OnPhaseChangedAsync(gc, created, phase);
{
if (phase == CastleSiegePhase.Siege)
{
_ = WarpRegisteredMembersToSiegeAsync(gc, created);
}
};
return created; return created;
}); });
@@ -71,6 +66,37 @@ public sealed class CastleSiegeEventPlugIn : IPeriodicTaskPlugIn, ISupportCustom
} }
} }
private static async Task OnPhaseChangedAsync(IGameContext gameContext, CastleSiegeContext context, CastleSiegePhase phase)
{
try
{
switch (phase)
{
case CastleSiegePhase.Registration:
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 WarpRegisteredMembersToSiegeAsync(gameContext, context).ConfigureAwait(false);
break;
case CastleSiegePhase.Ownership when context.OwnerGuildName is { } owner:
await AnnounceAsync(gameContext, $"The Castle Siege has ended. The castle now belongs to the guild '{owner}'!").ConfigureAwait(false);
break;
default:
break;
}
}
catch (Exception ex)
{
gameContext.LoggerFactory.CreateLogger<CastleSiegeEventPlugIn>()
.LogError(ex, "Castle Siege: error handling phase change to {phase}.", phase);
}
}
private static ValueTask AnnounceAsync(IGameContext gameContext, string message)
=> gameContext.ForEachPlayerAsync(player =>
player.InvokeViewPlugInAsync<IShowMessagePlugIn>(p => p.ShowMessageAsync(message, MessageType.GoldenCenter)).AsTask());
private static async Task WarpRegisteredMembersToSiegeAsync(IGameContext gameContext, CastleSiegeContext context) private static async Task WarpRegisteredMembersToSiegeAsync(IGameContext gameContext, CastleSiegeContext context)
{ {
try try