Skip to content

Commit

Permalink
Merge pull request #527 from ze-dom/bugfix/staff_rise_and_other_opts
Browse files Browse the repository at this point in the history
Bugfix/staff rise and other opts
  • Loading branch information
sven-n authored Nov 15, 2024
2 parents a4b82f1 + 792e186 commit ea4af9c
Show file tree
Hide file tree
Showing 16 changed files with 667 additions and 91 deletions.
5 changes: 5 additions & 0 deletions src/GameLogic/Attributes/Stats.cs
Original file line number Diff line number Diff line change
Expand Up @@ -231,6 +231,11 @@ public class Stats
/// </summary>
public static AttributeDefinition ScepterRise { get; } = new(new Guid("FB374862-D360-4FF0-AB88-2C170E6A9F85"), "Scepter Rise Percentage", string.Empty);

/// <summary>
/// Gets the book rise percentage attribute definition.
/// </summary>
public static AttributeDefinition BookRise { get; } = new(new Guid("AD9C9AE0-BA76-4C99-9F53-AE8F1AF6CAD4"), "Book Rise Percentage", string.Empty);

/// <summary>
/// Gets the minimum curse base DMG attribute definition.
/// </summary>
Expand Down
30 changes: 22 additions & 8 deletions src/GameLogic/ItemExtensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -146,17 +146,17 @@ public static bool IsJewelry(this Item item)
/// </returns>
public static bool IsPhysicalWeapon(this Item item, [NotNullWhen(true)] out float? minimumDmg)
{
minimumDmg = item.Definition?.BasePowerUpAttributes.FirstOrDefault(a => a.TargetAttribute == Stats.MinimumPhysBaseDmg)?.BaseValue;
minimumDmg = item.Definition?.BasePowerUpAttributes.FirstOrDefault(a => a.TargetAttribute == Stats.MinimumPhysBaseDmgByWeapon)?.BaseValue;
return minimumDmg is not null;
}

/// <summary>
/// Determines whether this instance is a weapon which deals wizardry damage.
/// Determines whether this instance is a weapon which increases wizardry damage.
/// </summary>
/// <param name="item">The item.</param>
/// <param name="staffRise">The staff rise percentage of the weapon.</param>
/// <param name="staffRise">The staff/stick's wizardry damage rise percentage.</param>
/// <returns>
/// <c>true</c> if this instance is a weapon which deals wizardry damage; otherwise, <c>false</c>.
/// <c>true</c> if this instance is a weapon which increases wizardry damage; otherwise, <c>false</c>.
/// </returns>
public static bool IsWizardryWeapon(this Item item, [NotNullWhen(true)] out float? staffRise)
{
Expand All @@ -168,14 +168,28 @@ public static bool IsWizardryWeapon(this Item item, [NotNullWhen(true)] out floa
/// Determines whether this instance is a scepter which increases raven damage.
/// </summary>
/// <param name="item">The item.</param>
/// <param name="stickRise">The stick rise percentage of the weapon.</param>
/// <param name="scepterRise">The scepter's pet attack rise percentage.</param>
/// <returns>
/// <c>true</c> if this instance is a scepter which increases raven damage; otherwise, <c>false</c>.
/// </returns>
public static bool IsScepter(this Item item, [NotNullWhen(true)] out float? stickRise)
public static bool IsScepter(this Item item, [NotNullWhen(true)] out float? scepterRise)
{
stickRise = item.Definition?.BasePowerUpAttributes.FirstOrDefault(a => a.TargetAttribute == Stats.ScepterRise)?.BaseValue;
return stickRise is not null;
scepterRise = item.Definition?.BasePowerUpAttributes.FirstOrDefault(a => a.TargetAttribute == Stats.ScepterRise)?.BaseValue;
return scepterRise is not null;
}

/// <summary>
/// Determines whether this instance is a book which increases curse damage.
/// </summary>
/// <param name="item">The item.</param>
/// <param name="bookRise">The book's curse damage rise percentage.</param>
/// <returns>
/// <c>true</c> if this instance is a book which increases curse damage; otherwise, <c>false</c>.
/// </returns>
public static bool IsBook(this Item item, [NotNullWhen(true)] out float? bookRise)
{
bookRise = item.Definition?.BasePowerUpAttributes.FirstOrDefault(a => a.TargetAttribute == Stats.BookRise)?.BaseValue;
return bookRise is not null;
}

/// <summary>
Expand Down
24 changes: 17 additions & 7 deletions src/GameLogic/ItemPowerUpFactory.cs
Original file line number Diff line number Diff line change
Expand Up @@ -272,10 +272,9 @@ private IEnumerable<PowerUpWrapper> CreateExcellentAndAncientBasePowerUpWrappers
var baseDefense = (int)(item.Definition?.BasePowerUpAttributes.FirstOrDefault(a => a.TargetAttribute == Stats.DefenseBase)?.BaseValue ?? 0);
var additionalDefense = (baseDefense * 12 / baseDropLevel) + (baseDropLevel / 5) + 4;
yield return new PowerUpWrapper(new SimpleElement(additionalDefense, AggregateType.AddRaw), Stats.DefenseBase, attributeHolder);

if (itemIsAncient)
{
var ancientDefenseBonus = (baseDefense * 3 / ancientDropLevel) + (ancientDropLevel / 30) + 2;
var ancientDefenseBonus = 2 + ((baseDefense + additionalDefense) * 3 / ancientDropLevel) + (ancientDropLevel / 30);
yield return new PowerUpWrapper(new SimpleElement(ancientDefenseBonus, AggregateType.AddRaw), Stats.DefenseBase, attributeHolder);
}
}
Expand All @@ -288,7 +287,7 @@ private IEnumerable<PowerUpWrapper> CreateExcellentAndAncientBasePowerUpWrappers
if (itemIsAncient)
{
var baseDefense = (int)(item.Definition?.BasePowerUpAttributes.FirstOrDefault(a => a.TargetAttribute == Stats.DefenseBase)?.BaseValue ?? 0);
var ancientDefenseBonus = (baseDefense * 20 / ancientDropLevel) + 2;
var ancientDefenseBonus = 2 + ((baseDefense + item.Level) * 20 / ancientDropLevel);
yield return new PowerUpWrapper(new SimpleElement(ancientDefenseBonus, AggregateType.AddRaw), Stats.DefenseBase, attributeHolder);
}
}
Expand All @@ -308,25 +307,36 @@ private IEnumerable<PowerUpWrapper> CreateExcellentAndAncientBasePowerUpWrappers

if (item.IsWizardryWeapon(out var staffRise))
{
var additionalRise = ((int)staffRise * 25 / baseDropLevel) + 5;
var additionalRise = (((int)staffRise * 2 * 25 / baseDropLevel) + 5) / 2;
yield return new PowerUpWrapper(new SimpleElement(additionalRise, AggregateType.AddRaw), Stats.StaffRise, attributeHolder);
if (itemIsAncient)
{
var ancientRiseBonus = 5 + (ancientDropLevel / 60);
var ancientRiseBonus = (2 + (ancientDropLevel / 60)) / 2;
yield return new PowerUpWrapper(new SimpleElement(ancientRiseBonus, AggregateType.AddRaw), Stats.StaffRise, attributeHolder);
}
}

if (item.IsScepter(out var scepterRise))
{
var additionalRise = ((int)scepterRise * 25 / baseDropLevel) + 5;
var additionalRise = (((int)scepterRise * 2 * 25 / baseDropLevel) + 5) / 2;
yield return new PowerUpWrapper(new SimpleElement(additionalRise, AggregateType.AddRaw), Stats.ScepterRise, attributeHolder);
if (itemIsAncient)
{
var ancientRiseBonus = 5 + (ancientDropLevel / 60);
var ancientRiseBonus = (2 + (ancientDropLevel / 60)) / 2;
yield return new PowerUpWrapper(new SimpleElement(ancientRiseBonus, AggregateType.AddRaw), Stats.ScepterRise, attributeHolder);
}
}

if (item.IsBook(out var curseRise))
{
var additionalRise = (((int)curseRise * 2 * 25 / baseDropLevel) + 5) / 2;
yield return new PowerUpWrapper(new SimpleElement(additionalRise, AggregateType.AddRaw), Stats.BookRise, attributeHolder);
if (itemIsAncient)
{
var ancientRiseBonus = (2 + (ancientDropLevel / 60)) / 2;
yield return new PowerUpWrapper(new SimpleElement(ancientRiseBonus, AggregateType.AddRaw), Stats.BookRise, attributeHolder);
}
}
}

private PowerUpWrapper? GetPetLevel(Item item, AttributeSystem attributeHolder)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -166,7 +166,7 @@ private bool TryAddItemOption(Item item, IContext persistenceContext)
else
{
// ItemOptionTypes.Option
optionLink.ItemOption = possibleOptions.First();
optionLink.ItemOption = possibleOptions.SelectRandom();
optionLink.Level = 1;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,7 @@ private CharacterClass CreateSummoner(CharacterClassNumber number, string name,

result.AttributeCombinations.Add(this.CreateAttributeRelationship(Stats.MinimumCurseBaseDmg, 1.0f / 9, Stats.TotalEnergy));
result.AttributeCombinations.Add(this.CreateAttributeRelationship(Stats.MaximumCurseBaseDmg, 1.0f / 4, Stats.TotalEnergy));
result.AttributeCombinations.Add(this.CreateAttributeRelationship(Stats.CurseAttackDamageIncrease, 1.0f / 100, Stats.BookRise));

result.AttributeCombinations.Add(this.CreateConditionalRelationship(Stats.WizardryBaseDmg, Stats.IsStickEquipped, Stats.StickBonusBaseDamage));

Expand Down
5 changes: 4 additions & 1 deletion src/Persistence/Initialization/Items/ExcellentOptions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -51,9 +51,12 @@ public override void Initialize()
this.CreateDefenseOptions();
this.CreatePhysicalAttackOptions();
this.CreateWizardryAttackOptions();
this.CreateCurseAttackOptions();

// this.CreateCurseAttackOptions();
}

[Obsolete(@"There are no curse attack excellent options until Season 14 (Summoner renewal). Until then, excellent curse spell books had excellent wizardry attack options.
Reference: https://muonline.webzen.com/pt/gameinfo/guide/detail/91")]
private void CreateCurseAttackOptions()
{
var definition = this.Context.CreateNew<ItemOptionDefinition>();
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
// <copyright file="FixWeaponRisePercentagePlugIn075.cs" company="MUnique">
// Licensed under the MIT License. See LICENSE file in the project root for full license information.
// </copyright>

namespace MUnique.OpenMU.Persistence.Initialization.Updates;

using System.Runtime.InteropServices;
using MUnique.OpenMU.PlugIns;

/// <summary>
/// This update fixes weapons (staff) rise percentage.
/// </summary>
[PlugIn(PlugInName, PlugInDescription)]
[Guid("5B63534D-E5DF-46B1-992D-C1637B197EE1")]
public class FixWeaponRisePercentagePlugIn075 : FixWeaponRisePercentagePlugInBase
{
/// <inheritdoc />
public override string DataInitializationKey => Version075.DataInitialization.Id;

/// <inheritdoc />
public override UpdateVersion Version => UpdateVersion.FixWeaponRisePercentage075;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
// <copyright file="FixWeaponRisePercentagePlugIn095d.cs" company="MUnique">
// Licensed under the MIT License. See LICENSE file in the project root for full license information.
// </copyright>

namespace MUnique.OpenMU.Persistence.Initialization.Updates;

using System.Runtime.InteropServices;
using MUnique.OpenMU.PlugIns;

/// <summary>
/// This update fixes weapons (staff) rise percentage.
/// </summary>
[PlugIn(PlugInName, PlugInDescription)]
[Guid("33259706-F3DF-4F4D-9935-3DEF7E53BF81")]
public class FixWeaponRisePercentagePlugIn095D : FixWeaponRisePercentagePlugInBase
{
/// <inheritdoc />
public override string DataInitializationKey => Version095d.DataInitialization.Id;

/// <inheritdoc />
public override UpdateVersion Version => UpdateVersion.FixWeaponRisePercentage095d;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
// <copyright file="FixWeaponRisePercentagePlugInBase.cs" company="MUnique">
// Licensed under the MIT License. See LICENSE file in the project root for full license information.
// </copyright>

namespace MUnique.OpenMU.Persistence.Initialization.Updates;

using MUnique.OpenMU.DataModel.Configuration;
using MUnique.OpenMU.DataModel.Configuration.Items;
using MUnique.OpenMU.GameLogic.Attributes;
using MUnique.OpenMU.Persistence.Initialization.Items;

/// <summary>
/// This update fixes weapons (staff) rise percentage.
/// </summary>
public abstract class FixWeaponRisePercentagePlugInBase : UpdatePlugInBase
{
/// <summary>
/// The plug in name.
/// </summary>
internal const string PlugInName = "Fix Weapon Rise Percentage";

/// <summary>
/// The plug in description.
/// </summary>
internal const string PlugInDescription = "This update fixes weapons (staff) rise percentage";

/// <inheritdoc />
public override string Name => PlugInName;

/// <inheritdoc />
public override string Description => PlugInDescription;

/// <inheritdoc />
public override bool IsMandatory => true;

/// <inheritdoc />
public override DateTime CreatedAt => new(2024, 11, 11, 16, 0, 0, DateTimeKind.Utc);

/// <inheritdoc />
protected override async ValueTask ApplyAsync(IContext context, GameConfiguration gameConfiguration)
{
var staffRiseBonusTable = gameConfiguration.ItemLevelBonusTables.Single(bt => bt.Name == "Staff Rise");

// Modify existing table name and description
staffRiseBonusTable.Name = "Staff Rise (even)";
staffRiseBonusTable.Description = "The staff rise bonus per item level for even magic power staves.";

// Add new staff odd increase table
float[] staffRiseIncreaseByLevelOdd = { 0, 4, 7, 11, 14, 18, 21, 25, 28, 32, 36, 40, 45, 51, 57, 63 };

var staffOddTable = context.CreateNew<ItemLevelBonusTable>();
gameConfiguration.ItemLevelBonusTables.Add(staffOddTable);
staffOddTable.Name = "Staff Rise (odd)";
staffOddTable.Description = "The staff rise bonus per item level for odd magic power staves.";
for (int level = 0; level < staffRiseIncreaseByLevelOdd.Length; level++)
{
var value = staffRiseIncreaseByLevelOdd[level];
if (value != 0)
{
var levelBonus = context.CreateNew<LevelBonus>();
levelBonus.Level = level;
levelBonus.AdditionalValue = staffRiseIncreaseByLevelOdd[level];
staffOddTable.BonusPerLevel.Add(levelBonus);
}
}

// Fix Group 5 weapons (staves)
var staves = gameConfiguration.Items.Where(i => i.Group == (int)ItemGroups.Staff && i.BasePowerUpAttributes.Any(pua => pua.TargetAttribute == Stats.StaffRise));
foreach (var staff in staves)
{
if (staff.BasePowerUpAttributes.FirstOrDefault(pua => pua.TargetAttribute == Stats.StaffRise) is { } staffRiseAttr)
{
if ((int)staffRiseAttr.BaseValue % 2 != 0)
{
staffRiseAttr.BonusPerLevelTable = staffOddTable;
}

staffRiseAttr.BaseValue /= 2.0f;
}
}
}
}
Loading

0 comments on commit ea4af9c

Please sign in to comment.