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
Some checks failed
.NET Core / build (push) Has been cancelled
This commit is contained in:
@@ -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/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 |
|
||||
| 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)* | | | |
|
||||
|
||||
## 10. Test stratejisi
|
||||
|
||||
@@ -709,6 +709,11 @@ public class Player : AsyncDisposable, IBucketMapObserver, IAttackable, IAttacke
|
||||
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/>
|
||||
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 &&
|
||||
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;
|
||||
}
|
||||
|
||||
@@ -8,6 +8,7 @@ using System.Collections.Concurrent;
|
||||
using System.Linq;
|
||||
using System.Runtime.InteropServices;
|
||||
using MUnique.OpenMU.GameLogic.CastleSiege;
|
||||
using MUnique.OpenMU.GameLogic.Views;
|
||||
using MUnique.OpenMU.Interfaces;
|
||||
using MUnique.OpenMU.PlugIns;
|
||||
|
||||
@@ -46,14 +47,8 @@ public sealed class CastleSiegeEventPlugIn : IPeriodicTaskPlugIn, ISupportCustom
|
||||
{
|
||||
var created = new CastleSiegeContext(this.Configuration ?? new CastleSiegeConfiguration());
|
||||
|
||||
// When the siege phase begins, pull all registered guild members onto the battle map.
|
||||
created.PhaseChanged += phase =>
|
||||
{
|
||||
if (phase == CastleSiegePhase.Siege)
|
||||
{
|
||||
_ = WarpRegisteredMembersToSiegeAsync(gc, created);
|
||||
}
|
||||
};
|
||||
// Announce phase changes to the whole server and, when the siege begins, warp registered members.
|
||||
created.PhaseChanged += phase => _ = OnPhaseChangedAsync(gc, created, phase);
|
||||
|
||||
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)
|
||||
{
|
||||
try
|
||||
|
||||
Reference in New Issue
Block a user