Merge pull request #825 from eduardosmaniotto/feature/configurable-npc-buffs
feature: configurable npc buffs (cherry picked from commit 6a061fcad756e644dadf3721e84e3cce2a25bceb)
This commit is contained in:
@@ -423,6 +423,12 @@ public sealed class Party : AsyncDisposable
|
||||
if (!shouldDispose)
|
||||
{
|
||||
this._partyMembers = this._partyMembers.Where(m => m != member).ToArray();
|
||||
|
||||
// If the party master is leaving, assign the new master to the first remaining member.
|
||||
if (this.PartyMaster == member && this._partyMembers.Length > 0)
|
||||
{
|
||||
this.PartyMaster = this._partyMembers[0];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,64 +0,0 @@
|
||||
// <copyright file="ElfSoldierBuffRequestAction.cs" company="MUnique">
|
||||
// Licensed under the MIT License. See LICENSE file in the project root for full license information.
|
||||
// </copyright>
|
||||
|
||||
namespace MUnique.OpenMU.GameLogic.PlayerActions.Quests;
|
||||
|
||||
using MUnique.OpenMU.AttributeSystem;
|
||||
using MUnique.OpenMU.DataModel.Attributes;
|
||||
using MUnique.OpenMU.GameLogic.Attributes;
|
||||
using MUnique.OpenMU.GameLogic.Views;
|
||||
using MUnique.OpenMU.Interfaces;
|
||||
|
||||
/// <summary>
|
||||
/// Action of requesting the elf soldier buff.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// Instead of hard-coding all this stuff, we could define something like a 'RequestableBuff' in the MonsterDefinition.
|
||||
/// </remarks>
|
||||
public class ElfSoldierBuffRequestAction
|
||||
{
|
||||
private static readonly short ElfSoldierNumber = 257;
|
||||
|
||||
private static readonly MagicEffectDefinition BuffEffect = new SoldierBuffMagicEffectDefinition
|
||||
{
|
||||
InformObservers = true,
|
||||
Name = "Elf Soldier Buff",
|
||||
Number = 3,
|
||||
StopByDeath = true,
|
||||
};
|
||||
|
||||
/// <summary>
|
||||
/// Requests the buff and adds it to the <see cref="Player.MagicEffectList"/> when the player is allowed to get it.
|
||||
/// </summary>
|
||||
/// <param name="player">The player.</param>
|
||||
public async ValueTask RequestBuffAsync(Player player)
|
||||
{
|
||||
if (player.OpenedNpc is null
|
||||
|| player.OpenedNpc.Definition.NpcWindow != NpcWindow.NpcDialog
|
||||
|| player.OpenedNpc.Definition.Number != ElfSoldierNumber)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (player.Level > 220)
|
||||
{
|
||||
await player.ShowLocalizedBlueMessageAsync(nameof(PlayerMessage.ElfSoldierStrongEnoughMessage)).ConfigureAwait(false);
|
||||
return;
|
||||
}
|
||||
|
||||
await player.MagicEffectList.AddEffectAsync(new MagicEffect(
|
||||
TimeSpan.FromMinutes(60),
|
||||
BuffEffect,
|
||||
new MagicEffect.ElementWithTarget(new ConstantElement(50 + (player.Level / 5), AggregateType.AddFinal), Stats.DefenseFinal),
|
||||
new MagicEffect.ElementWithTarget(new ConstantElement(45 + (player.Level / 3)), Stats.GreaterDamageBonus))).ConfigureAwait(false);
|
||||
}
|
||||
|
||||
private sealed class SoldierBuffMagicEffectDefinition : MagicEffectDefinition
|
||||
{
|
||||
public SoldierBuffMagicEffectDefinition()
|
||||
{
|
||||
this.PowerUpDefinitions = new List<PowerUpDefinition>(2);
|
||||
}
|
||||
}
|
||||
}
|
||||
90
src/GameLogic/PlayerActions/Quests/NpcBuffRequestAction.cs
Normal file
90
src/GameLogic/PlayerActions/Quests/NpcBuffRequestAction.cs
Normal file
@@ -0,0 +1,90 @@
|
||||
// <copyright file="NpcBuffRequestAction.cs" company="MUnique">
|
||||
// Licensed under the MIT License. See LICENSE file in the project root for full license information.
|
||||
// </copyright>
|
||||
|
||||
namespace MUnique.OpenMU.GameLogic.PlayerActions.Quests;
|
||||
|
||||
using MUnique.OpenMU.DataModel.Configuration;
|
||||
using MUnique.OpenMU.GameLogic.Attributes;
|
||||
using MUnique.OpenMU.GameLogic.Views;
|
||||
using MUnique.OpenMU.Interfaces;
|
||||
|
||||
/// <summary>
|
||||
/// Action which applies the <see cref="Buff"/>s of the currently opened NPC.
|
||||
/// </summary>
|
||||
public class NpcBuffRequestAction
|
||||
{
|
||||
/// <summary>
|
||||
/// Requests the buffs from the opened NPC and adds them to the <see cref="Player.MagicEffectList"/>.
|
||||
/// </summary>
|
||||
/// <param name="player">The player.</param>
|
||||
public async ValueTask RequestBuffAsync(Player player)
|
||||
{
|
||||
if (player.OpenedNpc?.Definition is not { NpcWindow: NpcWindow.NpcDialog, Buffs: { } buffs } || !buffs.Any())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
var anyApplied = false;
|
||||
var anyTooLow = false;
|
||||
var anyTooStrong = false;
|
||||
var anyValidEffect = false;
|
||||
foreach (var buff in buffs)
|
||||
{
|
||||
if (buff.MagicEffectDefinition is not { } effectDef)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
anyValidEffect = true;
|
||||
|
||||
if (buff.MinimumLevel.HasValue && player.Level < buff.MinimumLevel.Value)
|
||||
{
|
||||
anyTooLow = true;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (buff.MaximumLevel.HasValue && player.Level > buff.MaximumLevel.Value)
|
||||
{
|
||||
anyTooStrong = true;
|
||||
continue;
|
||||
}
|
||||
|
||||
var duration = TimeSpan.FromSeconds(effectDef.Duration?.ConstantValue?.Value ?? 0);
|
||||
if (duration.TotalSeconds == 0)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
var boosts = effectDef.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)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
var effect = new MagicEffect(duration, effectDef, boosts);
|
||||
await player.MagicEffectList.AddEffectAsync(effect).ConfigureAwait(false);
|
||||
anyApplied = true;
|
||||
}
|
||||
|
||||
if (anyApplied)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (anyValidEffect && anyTooLow)
|
||||
{
|
||||
await player.ShowLocalizedBlueMessageAsync(nameof(PlayerMessage.CharacterNotStrongEnoughMessage)).ConfigureAwait(false);
|
||||
return;
|
||||
}
|
||||
|
||||
if (anyValidEffect && anyTooStrong)
|
||||
{
|
||||
await player.ShowLocalizedBlueMessageAsync(nameof(PlayerMessage.CharacterTooStrongMessage)).ConfigureAwait(false);
|
||||
}
|
||||
}
|
||||
}
|
||||
13
src/GameLogic/Properties/PlayerMessage.Designer.cs
generated
13
src/GameLogic/Properties/PlayerMessage.Designer.cs
generated
@@ -405,9 +405,9 @@ namespace MUnique.OpenMU.GameLogic.Properties {
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to You're strong enough on your own..
|
||||
/// </summary>
|
||||
public static string ElfSoldierStrongEnoughMessage {
|
||||
public static string CharacterTooStrongMessage {
|
||||
get {
|
||||
return ResourceManager.GetString("ElfSoldierStrongEnoughMessage", resourceCulture);
|
||||
return ResourceManager.GetString("CharacterTooStrongMessage", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1814,5 +1814,14 @@ namespace MUnique.OpenMU.GameLogic.Properties {
|
||||
return ResourceManager.GetString("StatsResetSuccessfully", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to You are not strong enough for this buff yet..
|
||||
/// </summary>
|
||||
public static string CharacterNotStrongEnoughMessage {
|
||||
get {
|
||||
return ResourceManager.GetString("CharacterNotStrongEnoughMessage", resourceCulture);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -522,7 +522,7 @@
|
||||
<data name="PlayerStoreNotOpen" xml:space="preserve">
|
||||
<value>Player's Store not open.</value>
|
||||
</data>
|
||||
<data name="ElfSoldierStrongEnoughMessage" xml:space="preserve">
|
||||
<data name="CharacterTooStrongMessage" xml:space="preserve">
|
||||
<value>You're strong enough on your own.</value>
|
||||
</data>
|
||||
<data name="NotEnoughMoneyToProceed" xml:space="preserve">
|
||||
@@ -702,4 +702,7 @@
|
||||
<data name="ItemDoesNotBelongToYou" xml:space="preserve">
|
||||
<value>This item doesn't belong to you.</value>
|
||||
</data>
|
||||
<data name="CharacterNotStrongEnoughMessage" xml:space="preserve">
|
||||
<value>You are not strong enough for this yet.</value>
|
||||
</data>
|
||||
</root>
|
||||
|
||||
Reference in New Issue
Block a user