fix(hs): no PvP before battle + clean team assignment on leave

#1: block all player-vs-player damage while State != Playing (registration/
prep), keep same-team friendly-fire off during battle. Prevents pre-battle
kills (which also caused deaths to route to Lorencia instead of a base).
#3: remove a player from their team on OnObjectRemovedFromMapAsync (real
leave to another map), not on same-map death-respawn, so team counts stay
accurate and re-joining works.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
Acentech Dev
2026-07-21 02:18:49 +03:00
parent a174c1a29f
commit 5750ab6511
2 changed files with 31 additions and 5 deletions

View File

@@ -331,6 +331,22 @@ public class HeykelSavasiContext : MiniGameContext
/// <param name="player">The player.</param>
private void RemoveTeam(Player player) => this._teams.TryRemove(player, out _);
/// <summary>
/// Removes a player from their team when they leave the event map for good (disconnect, or warp
/// to another map such as Lorencia). A same-map death-respawn does NOT trigger this (RespawnAtAsync
/// skips the map-removal when respawning on the same map), so dying at your own base keeps your team
/// assignment and earned progress intact. This keeps team counts accurate so re-joining works.
/// </summary>
protected override async ValueTask OnObjectRemovedFromMapAsync((GameMap Map, ILocateable Object) args)
{
if (args.Object is Player player)
{
this.RemoveTeam(player);
}
await base.OnObjectRemovedFromMapAsync(args).ConfigureAwait(false);
}
/// <inheritdoc />
/// <remarks>
/// Cancels the event if either team is empty at start (no opponent to fight); otherwise

View File

@@ -736,13 +736,23 @@ public class Player : AsyncDisposable, IBucketMapObserver, IAttackable, IAttacke
return null;
}
// ADAMU-CUSTOM: Heykel Savasi -> same-team players cannot damage each other.
// ADAMU-CUSTOM: Heykel Savasi PvP rules.
if (this.CurrentMiniGame is HeykelSavasiContext heykelSavasi
&& attacker is Player heykelAttacker
&& heykelSavasi.GetTeam(this) != HeykelSavasiTeam.None
&& heykelSavasi.GetTeam(this) == heykelSavasi.GetTeam(heykelAttacker))
&& attacker is Player heykelAttacker)
{
return null;
// No player-vs-player damage before the battle actually starts (registration / 30s preparation).
if (heykelSavasi.State != MiniGameState.Playing)
{
return null;
}
// Never friendly-fire within the same team.
var heykelVictimTeam = heykelSavasi.GetTeam(this);
if (heykelVictimTeam != HeykelSavasiTeam.None
&& heykelVictimTeam == heykelSavasi.GetTeam(heykelAttacker))
{
return null;
}
}
var hitInfo = await attacker.CalculateDamageAsync(this, skill, isCombo, damageFactor).ConfigureAwait(false);