Files
AdamuSw/src/Persistence/Initialization/Updates/FixDefenseCalcsPlugInSeason6.cs
2026-07-14 19:00:35 +03:00

195 lines
10 KiB
C#

// <copyright file="FixDefenseCalcsPlugInSeason6.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.AttributeSystem;
using MUnique.OpenMU.DataModel.Attributes;
using MUnique.OpenMU.DataModel.Configuration;
using MUnique.OpenMU.GameLogic;
using MUnique.OpenMU.GameLogic.Attributes;
using MUnique.OpenMU.Persistence.Initialization.Skills;
using MUnique.OpenMU.PlugIns;
/// <summary>
/// This update fixes character stats, magic effects, and options related to defense.
/// </summary>
[PlugIn]
[Display(Name = PlugInName, Description = PlugInDescription)]
[Guid("447FA95B-091B-4950-B1F3-F4EB6D20DE19")]
public class FixDefenseCalcsPlugInSeason6 : FixDefenseCalcsPlugInBase
{
/// <inheritdoc />
public override string DataInitializationKey => VersionSeasonSix.DataInitialization.Id;
/// <inheritdoc />
public override UpdateVersion Version => UpdateVersion.FixDefenseCalcsSeason6;
/// <inheritdoc />
protected override async ValueTask ApplyAsync(IContext context, GameConfiguration gameConfiguration)
{
// Update Anonymous Leather ancient set obsolete option prior to its removal
var shieldBlockDamageDecrementId = new Guid("DAC6690B-5922-4446-BCE5-5E701BE62EC1");
var anonymousLeatherOptsId = new Guid("00000083-0029-0002-0100-000000000000");
var anonymousLeatherOpts = gameConfiguration.ItemOptions.FirstOrDefault(i => i.GetId() == anonymousLeatherOptsId);
if (gameConfiguration.Attributes.FirstOrDefault(a => a.Id == shieldBlockDamageDecrementId) is { } shieldBlockDamageDecrement
&& anonymousLeatherOpts?.PossibleOptions.FirstOrDefault(opt => opt.PowerUpDefinition?.TargetAttribute == shieldBlockDamageDecrement) is { } shieldBlockDamageDecrementOpt)
{
shieldBlockDamageDecrementOpt.PowerUpDefinition!.TargetAttribute = Stats.DefenseIncreaseWithEquippedShield.GetPersistent(gameConfiguration);
}
await base.ApplyAsync(context, gameConfiguration).ConfigureAwait(false);
var defenseBase = Stats.DefenseBase.GetPersistent(gameConfiguration);
var defenseFinal = Stats.DefenseFinal.GetPersistent(gameConfiguration);
var defensePvm = Stats.DefensePvm.GetPersistent(gameConfiguration);
var defensePvp = Stats.DefensePvp.GetPersistent(gameConfiguration);
var shieldItemDefenseIncrease = Stats.ShieldItemDefenseIncrease.GetPersistent(gameConfiguration);
var bonusDefenseRateWithShield = Stats.BonusDefenseRateWithShield.GetPersistent(gameConfiguration);
var excellentDamageChance = Stats.ExcellentDamageChance.GetPersistent(gameConfiguration);
var excellentDamageBonus = Stats.ExcellentDamageBonus.GetPersistent(gameConfiguration);
// Update attribute combinations
gameConfiguration.CharacterClasses.ForEach(charClass =>
{
if (charClass.AttributeCombinations.FirstOrDefault(attrCombo => attrCombo.TargetAttribute == Stats.MaximumShield && attrCombo.InputAttribute == Stats.DefenseBase) is { } defenseBaseToMaximumShield)
{
defenseBaseToMaximumShield.InputOperand = 1;
defenseBaseToMaximumShield.InputAttribute = defenseFinal;
}
});
// Update magic effects
var defenseReductionEffect = gameConfiguration.MagicEffects.FirstOrDefault(m => m.Number == (short)MagicEffectNumber.DefenseReduction);
if (defenseReductionEffect is not null)
{
defenseReductionEffect.PowerUpDefinitions.Clear();
var reducePvmDefenseEffect = context.CreateNew<PowerUpDefinition>();
defenseReductionEffect.PowerUpDefinitions.Add(reducePvmDefenseEffect);
reducePvmDefenseEffect.TargetAttribute = defensePvm;
reducePvmDefenseEffect.Boost = context.CreateNew<PowerUpDefinitionValue>();
reducePvmDefenseEffect.Boost.ConstantValue.Value = 0.9f;
reducePvmDefenseEffect.Boost.ConstantValue.AggregateType = AggregateType.Multiplicate;
var reducePvpDefenseEffect = context.CreateNew<PowerUpDefinition>();
defenseReductionEffect.PowerUpDefinitions.Add(reducePvpDefenseEffect);
reducePvpDefenseEffect.TargetAttribute = defensePvp;
reducePvpDefenseEffect.Boost = context.CreateNew<PowerUpDefinitionValue>();
reducePvpDefenseEffect.Boost.ConstantValue.Value = 0.9f;
reducePvpDefenseEffect.Boost.ConstantValue.AggregateType = AggregateType.Multiplicate;
}
var jackOlanternCry = gameConfiguration.Items.FirstOrDefault(m => m.Group == 14 && m.Number == 48);
if (jackOlanternCry?.ConsumeEffect is { } effect)
{
foreach (var powerUp in effect.PowerUpDefinitions)
{
powerUp.TargetAttribute = defenseFinal;
powerUp.Boost!.ConstantValue.Value = 100 / 2;
powerUp.Boost.ConstantValue.AggregateType = AggregateType.AddFinal;
}
}
// Update options
var ancientSetsOpts = gameConfiguration.ItemOptions.Where(io => io.Name.ValueInNeutralLanguageAsSpan.EndsWith("(Ancient Set)"));
foreach (var ancientSetOpts in ancientSetsOpts)
{
if (ancientSetOpts.PossibleOptions.FirstOrDefault(o => o.PowerUpDefinition?.TargetAttribute == defenseBase) is { } defenseBaseAncOpt)
{
defenseBaseAncOpt.PowerUpDefinition!.Boost!.ConstantValue.AggregateType = AggregateType.AddFinal;
}
}
var anubisLegendaryOptsId = new Guid("00000083-0029-0013-0100-000000000000");
var anubisLegendaryOpts = gameConfiguration.ItemOptions.FirstOrDefault(i => i.GetId() == anubisLegendaryOptsId);
if (anubisLegendaryOpts?.PossibleOptions.FirstOrDefault(opt =>
opt.PowerUpDefinition?.TargetAttribute == excellentDamageChance
&& opt.PowerUpDefinition.Boost?.ConstantValue.Value == 20.0f) is { } excellentDamageChanceOpt)
{
excellentDamageChanceOpt.PowerUpDefinition!.TargetAttribute = excellentDamageBonus;
}
var pantsGuardianOptions = gameConfiguration.ItemOptions.FirstOrDefault(o => o.Name == "Guardian Option (Pants)");
if (pantsGuardianOptions is not null
&& pantsGuardianOptions.PossibleOptions.FirstOrDefault(o => o.PowerUpDefinition?.TargetAttribute == defenseBase) is { } defenseOpt)
{
defenseOpt.PowerUpDefinition!.TargetAttribute = defensePvp;
defenseOpt.PowerUpDefinition.Boost!.ConstantValue.Value = 200 / 2;
}
var harmonyDefOptions = gameConfiguration.ItemOptions.FirstOrDefault(o => o.Name == "Harmony Defense Options");
if (harmonyDefOptions is not null
&& harmonyDefOptions.PossibleOptions.FirstOrDefault(o => o.Number == 1) is { } defenseBaseOpt)
{
foreach (var level in defenseBaseOpt.LevelDependentOptions)
{
level.PowerUpDefinition!.Boost!.ConstantValue.AggregateType = AggregateType.AddFinal;
}
}
var socketOptionsWaterId = new Guid("00000083-0033-0000-0000-000000000000");
var waterSocketOptions = gameConfiguration.ItemOptions.FirstOrDefault(o => o.GetId() == socketOptionsWaterId);
if (waterSocketOptions is not null)
{
if (waterSocketOptions.PossibleOptions.FirstOrDefault(o => o.Number == 1) is { } defenseBaseSockOpt)
{
foreach (var level in defenseBaseSockOpt.LevelDependentOptions)
{
level.PowerUpDefinition!.TargetAttribute = defenseFinal;
}
}
if (waterSocketOptions.PossibleOptions.FirstOrDefault(o => o.Number == 2) is { } shieldItemdefenseSockOpt)
{
foreach (var level in shieldItemdefenseSockOpt.LevelDependentOptions)
{
level.PowerUpDefinition!.TargetAttribute = shieldItemDefenseIncrease;
}
}
}
var socketBonusOptionsArmorsId = new Guid("00000083-0031-0003-0000-000000000000");
var socketArmorsBonusOptions = gameConfiguration.ItemOptions.FirstOrDefault(o => o.GetId() == socketBonusOptionsArmorsId);
if (socketArmorsBonusOptions is not null
&& socketArmorsBonusOptions.PossibleOptions.FirstOrDefault(o => o.Number == 4) is { } defenseBaseSockBonusOpt)
{
defenseBaseSockBonusOpt.PowerUpDefinition!.TargetAttribute = defenseFinal;
}
// Update master skills
if (gameConfiguration.Skills.FirstOrDefault(s => s.Number == (short)SkillNumber.DefenseIncrease)?.MasterDefinition is { } defenseIncrease)
{
defenseIncrease.Aggregation = AggregateType.AddFinal;
}
if (gameConfiguration.Skills.FirstOrDefault(s => s.Number == (short)SkillNumber.IncreasesDefense)?.MasterDefinition is { } increasesDefense)
{
increasesDefense.Aggregation = AggregateType.AddFinal;
}
if (gameConfiguration.Skills.FirstOrDefault(s => s.Number == (short)SkillNumber.DefenseSuccessRateInc)?.MasterDefinition is { } defenseSuccessRateInc)
{
string formula120 = "(1 + (((((((level - 30) ^ 3) + 25000) / 499) / 50) * 100) / 12))";
defenseSuccessRateInc.ValueFormula = $"1 + {formula120} / 100";
defenseSuccessRateInc.Aggregation = AggregateType.Multiplicate;
}
if (gameConfiguration.Skills.FirstOrDefault(s => s.Number == (short)SkillNumber.ShieldMasteryGrandMaster)?.MasterDefinition is { } shieldMasteryGrandMaster)
{
shieldMasteryGrandMaster.TargetAttribute = bonusDefenseRateWithShield;
}
if (gameConfiguration.Skills.FirstOrDefault(s => s.Number == (short)SkillNumber.ShieldMasteryHighElf)?.MasterDefinition is { } shieldMasteryHighElf)
{
shieldMasteryHighElf.TargetAttribute = bonusDefenseRateWithShield;
}
if (gameConfiguration.Skills.FirstOrDefault(s => s.Number == (short)SkillNumber.ShieldMastery)?.MasterDefinition is { } shieldMastery)
{
shieldMastery.TargetAttribute = bonusDefenseRateWithShield;
}
}
}