//
// Licensed under the MIT License. See LICENSE file in the project root for full license information.
//
namespace MUnique.OpenMU.GameLogic.Offline;
using MUnique.OpenMU.GameLogic.MuHelper;
using MUnique.OpenMU.GameLogic.Views.MuHelper;
///
/// Handles the periodic Zen consumption for the offline player.
///
internal sealed class ZenConsumptionHandler
{
private readonly OfflinePlayer _player;
private readonly MuHelperConfiguration _configuration;
private DateTime _lastPayTimestamp;
///
/// Initializes a new instance of the class.
///
/// The player.
public ZenConsumptionHandler(OfflinePlayer player)
{
this._player = player;
this._configuration = player.GameContext.FeaturePlugIns.GetPlugIn()?.Configuration
?? new MuHelperConfiguration();
this._lastPayTimestamp = player.StartTimestamp;
}
///
/// Deducts Zen from the player based on the server configuration and the player's level.
///
/// true if the player can continue; false if insufficient Zen.
public async ValueTask DeductZenAsync()
{
// Bots are exempt from the PC-Cafe fee: they don't accumulate Zen fast enough
// to cover it and would otherwise go bankrupt and stop. Human offline-leveling
// players (IsBot == false) keep paying as before.
if (this._player.Account?.IsBot == true)
{
return true;
}
if (DateTime.UtcNow - this._lastPayTimestamp < this._configuration.PayInterval)
{
return true;
}
var amount = MuHelperZenCostCalculator.Calculate(this._player, this._configuration, this._player.StartTimestamp);
if (amount > 0 && this._player.TryRemoveMoney(amount))
{
this._lastPayTimestamp = DateTime.UtcNow;
await this._player
.InvokeViewPlugInAsync(p => p.ConsumeMoneyAsync((uint)amount))
.ConfigureAwait(false);
return true;
}
if (amount > 0)
{
this._player.Logger.LogDebug("Insufficient Zen for {CharacterName}.", this._player.Name);
return false;
}
return true;
}
}