fix(CS): send crown shield packet (0xB2/0x16) only on change, not every tick
Some checks failed
.NET Core / build (push) Has been cancelled
Some checks failed
.NET Core / build (push) Has been cancelled
The shield packet pops a modal message box on the client; sending it every tick re-opened the modal continuously and froze player input at siege start. Track the shield state in the context and only push the packet when it actually flips.
This commit is contained in:
@@ -25,6 +25,7 @@ public class CastleSiegeContext
|
||||
private bool _dirty;
|
||||
private string? _crownHoldGuild;
|
||||
private DateTime? _crownHoldStartUtc;
|
||||
private bool _lastShieldDown;
|
||||
|
||||
/// <summary>Initializes a new instance of the <see cref="CastleSiegeContext"/> class.</summary>
|
||||
/// <param name="configuration">The cycle timing configuration.</param>
|
||||
@@ -217,28 +218,31 @@ public class CastleSiegeContext
|
||||
/// <param name="holdDuration">How long the master must hold to capture.</param>
|
||||
public CrownTickResult TickCrownHold(string? eligibleGuild, bool masterHolding, DateTime now, TimeSpan holdDuration)
|
||||
{
|
||||
var shieldDown = this.Phase == CastleSiegePhase.Siege && eligibleGuild is not null;
|
||||
var shieldChanged = shieldDown != this._lastShieldDown;
|
||||
this._lastShieldDown = shieldDown;
|
||||
|
||||
if (this.Phase != CastleSiegePhase.Siege)
|
||||
{
|
||||
this._crownHoldGuild = null;
|
||||
this._crownHoldStartUtc = null;
|
||||
return new CrownTickResult(false, CrownEvent.None, null);
|
||||
return new CrownTickResult(false, shieldChanged, CrownEvent.None, null);
|
||||
}
|
||||
|
||||
var shieldDown = eligibleGuild is not null;
|
||||
var wasHolding = this._crownHoldGuild is not null;
|
||||
|
||||
if (eligibleGuild is null || !masterHolding)
|
||||
{
|
||||
this._crownHoldGuild = null;
|
||||
this._crownHoldStartUtc = null;
|
||||
return new CrownTickResult(shieldDown, wasHolding ? CrownEvent.HoldReset : CrownEvent.None, null);
|
||||
return new CrownTickResult(shieldDown, shieldChanged, wasHolding ? CrownEvent.HoldReset : CrownEvent.None, null);
|
||||
}
|
||||
|
||||
if (this._crownHoldGuild != eligibleGuild || this._crownHoldStartUtc is null)
|
||||
{
|
||||
this._crownHoldGuild = eligibleGuild;
|
||||
this._crownHoldStartUtc = now;
|
||||
return new CrownTickResult(shieldDown, CrownEvent.HoldStarted, eligibleGuild);
|
||||
return new CrownTickResult(shieldDown, shieldChanged, CrownEvent.HoldStarted, eligibleGuild);
|
||||
}
|
||||
|
||||
if (now - this._crownHoldStartUtc.Value >= holdDuration)
|
||||
@@ -247,10 +251,10 @@ public class CastleSiegeContext
|
||||
this._crownHoldGuild = null;
|
||||
this._crownHoldStartUtc = null;
|
||||
this._dirty = true;
|
||||
return new CrownTickResult(shieldDown, CrownEvent.Captured, eligibleGuild);
|
||||
return new CrownTickResult(shieldDown, shieldChanged, CrownEvent.Captured, eligibleGuild);
|
||||
}
|
||||
|
||||
return new CrownTickResult(shieldDown, CrownEvent.None, eligibleGuild);
|
||||
return new CrownTickResult(shieldDown, shieldChanged, CrownEvent.None, eligibleGuild);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -363,6 +367,7 @@ public class CastleSiegeContext
|
||||
this._occupier = null;
|
||||
this._crownHoldGuild = null;
|
||||
this._crownHoldStartUtc = null;
|
||||
this._lastShieldDown = false;
|
||||
}
|
||||
|
||||
private ValueTask TransitionAsync(CastleSiegePhase phase, DateTime now)
|
||||
@@ -393,6 +398,7 @@ public enum CrownEvent
|
||||
|
||||
/// <summary>The result of a crown-hold tick: the shield state and any event that occurred.</summary>
|
||||
/// <param name="ShieldDown">Whether the crown shield is currently down (both switches held, defenses cleared).</param>
|
||||
/// <param name="ShieldChanged">Whether the shield state changed this tick (only then should the client be told).</param>
|
||||
/// <param name="Event">The event that occurred this tick.</param>
|
||||
/// <param name="Guild">The guild the event refers to, if any.</param>
|
||||
public readonly record struct CrownTickResult(bool ShieldDown, CrownEvent Event, string? Guild);
|
||||
public readonly record struct CrownTickResult(bool ShieldDown, bool ShieldChanged, CrownEvent Event, string? Guild);
|
||||
|
||||
@@ -428,7 +428,12 @@ public sealed class CastleSiegeEventPlugIn : IPeriodicTaskPlugIn, ISupportCustom
|
||||
return;
|
||||
}
|
||||
|
||||
await player.InvokeViewPlugInAsync<ICastleSiegeStatusViewPlugIn>(p => p.SetCrownShieldAsync(crown.ShieldDown)).ConfigureAwait(false);
|
||||
// Only tell the client when the shield state actually flips — the 0xB2/0x16 packet pops a modal
|
||||
// message box, so sending it every tick would block player input.
|
||||
if (crown.ShieldChanged)
|
||||
{
|
||||
await player.InvokeViewPlugInAsync<ICastleSiegeStatusViewPlugIn>(p => p.SetCrownShieldAsync(crown.ShieldDown)).ConfigureAwait(false);
|
||||
}
|
||||
|
||||
switch (crown.Event)
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user