Some checks failed
.NET Core / build (push) Has been cancelled
Ownership reward: only members of the current castle-owning guild may warp into Land of Trials (map 31); sealed while unowned; GMs bypass. Enforced in both WarpAction and WarpGateAction (// ADAMU-CUSTOM). Tax system deferred per user. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
76 lines
2.8 KiB
C#
76 lines
2.8 KiB
C#
// <copyright file="CastleSiegeMapAccess.cs" company="MUnique">
|
|
// Licensed under the MIT License. See LICENSE file in the project root for full license information.
|
|
// </copyright>
|
|
|
|
namespace MUnique.OpenMU.GameLogic.CastleSiege;
|
|
|
|
using MUnique.OpenMU.DataModel.Entities;
|
|
using MUnique.OpenMU.GameLogic.PlugIns.PeriodicTasks;
|
|
using MUnique.OpenMU.Interfaces;
|
|
|
|
/// <summary>
|
|
/// ADAMU-CUSTOM (Castle Siege P4 — ownership reward): gates entry to the castle-exclusive hunting map
|
|
/// (Land of Trials, map 31). Only members of the current castle-owning guild may enter; while the castle
|
|
/// has no owner the map stays sealed. Game masters always pass (admin/testing).
|
|
/// </summary>
|
|
public static class CastleSiegeMapAccess
|
|
{
|
|
/// <summary>The castle-exclusive hunting map number (Land of Trials).</summary>
|
|
public const short CastleHuntingMapNumber = 31;
|
|
|
|
/// <summary>
|
|
/// Checks whether the player may enter the given map. Only the castle hunting map (31) is restricted;
|
|
/// every other map is always allowed.
|
|
/// </summary>
|
|
/// <param name="player">The player attempting to enter.</param>
|
|
/// <param name="mapNumber">The target map number.</param>
|
|
/// <returns>Whether entry is allowed and, when not, a human-readable reason to show the player.</returns>
|
|
public static async ValueTask<(bool Allowed, string? Error)> CanEnterMapAsync(Player player, short mapNumber)
|
|
{
|
|
if (mapNumber != CastleHuntingMapNumber)
|
|
{
|
|
return (true, null);
|
|
}
|
|
|
|
// Game masters may always enter (admin/testing).
|
|
if (player.SelectedCharacter?.CharacterStatus >= CharacterStatus.GameMaster)
|
|
{
|
|
return (true, null);
|
|
}
|
|
|
|
var context = CastleSiegeEventPlugIn.TryGetContext(player.GameContext);
|
|
var owner = context?.OwnerGuildName;
|
|
if (string.IsNullOrEmpty(owner))
|
|
{
|
|
return (false, "The castle hunting ground is sealed until a guild owns the castle.");
|
|
}
|
|
|
|
var guildName = await GetGuildNameAsync(player).ConfigureAwait(false);
|
|
if (guildName is not null && string.Equals(guildName, owner, StringComparison.Ordinal))
|
|
{
|
|
return (true, null);
|
|
}
|
|
|
|
return (false, $"Only members of the castle-owning guild '{owner}' may enter this hunting ground.");
|
|
}
|
|
|
|
private static async ValueTask<string?> GetGuildNameAsync(Player player)
|
|
{
|
|
if (player.GuildStatus is not { } guildStatus)
|
|
{
|
|
return null;
|
|
}
|
|
|
|
if (player.GameContext is IGameServerContext serverContext)
|
|
{
|
|
var guild = await serverContext.GuildServer.GetGuildAsync(guildStatus.GuildId).ConfigureAwait(false);
|
|
if (guild?.Name is { Length: > 0 } name)
|
|
{
|
|
return name;
|
|
}
|
|
}
|
|
|
|
return guildStatus.GuildId.ToString();
|
|
}
|
|
}
|