//
// Licensed under the MIT License. See LICENSE file in the project root for full license information.
//
namespace MUnique.OpenMU.GameLogic.PlayerActions.ItemConsumeActions;
using MUnique.OpenMU.DataModel.Configuration.Items;
using MUnique.OpenMU.GameLogic.Attributes;
///
/// for s which have a defined .
///
public class ApplyMagicEffectConsumeHandlerPlugIn : BaseConsumeHandlerPlugIn
{
///
public override ItemIdentifier Key => new(0xFF, 0xFF);
///
public override async ValueTask ConsumeItemAsync(Player player, Item item, Item? targetItem, FruitUsage fruitUsage)
{
if (item.Definition?.ConsumeEffect is not { } effectDefinition)
{
return false;
}
return await this.ConsumeItemAsyncCore(player, item, targetItem, fruitUsage, effectDefinition).ConfigureAwait(false);
}
///
/// Consumes the item at the specified slot with the specified effect and reduces its durability by one.
/// If the durability has reached 0, the item is getting destroyed.
/// If a target slot is specified, the consumption targets the item on this slot (e.g. upgrade of an item by a jewel).
///
/// The player which is consuming.
/// The item which gets consumed.
/// The item which is the target of the consumption (e.g. upgrade target of a jewel).
/// In case the item is a fruit, this parameter defines how the fruit should be used.
/// The effect definition.
///
/// The success of the consumption.
///
protected async ValueTask ConsumeItemAsyncCore(Player player, Item item, Item? targetItem, FruitUsage fruitUsage, MagicEffectDefinition effectDefinition)
{
if (!effectDefinition.PowerUpDefinitions.Any()
|| effectDefinition.Duration?.ConstantValue.Value is not { } durationInSeconds)
{
return false;
}
if (await player.MagicEffectList.TryGetActiveEffectOfSubTypeAsync(effectDefinition.SubType).ConfigureAwait(false) is { } existingEffect)
{
await existingEffect.DisposeAsync().ConfigureAwait(false);
}
var boosts = effectDefinition.PowerUpDefinitions
.Where(def => def.Boost is not null && def.TargetAttribute is not null)
.Select(def => new MagicEffect.ElementWithTarget(player.Attributes!.CreateElement(def), def.TargetAttribute!))
.ToArray();
if (boosts.Length == 0)
{
return false;
}
if (!await base.ConsumeItemAsync(player, item, targetItem, fruitUsage).ConfigureAwait(false))
{
return false;
}
var effect = new MagicEffect(TimeSpan.FromSeconds(durationInSeconds), effectDefinition, boosts!);
await player.MagicEffectList.AddEffectAsync(effect).ConfigureAwait(false);
return true;
}
}