Skip to content

Defense calculations refactoring #602

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Draft
wants to merge 7 commits into
base: master
Choose a base branch
from

Conversation

ze-dom
Copy link
Contributor

@ze-dom ze-dom commented May 12, 2025

To-do:

  • Update plugins (after discussion)

Changes:

  • Defense calculations reviewed end to end
  • Attack rate (PvM) reviewed
  • Defense rate (PvM) reviewed

Bugfixes:

  • Item skill not checking char class requirements
  • MST shield mastery skills (GM, LE, HE) now increase defense rate (PvM) instead of defense
  • MST defense rate increase multiplier value

Notes:
Following the zTeamS6.3 or emu sources, defense calculation order goes as follows:

  1. (+) all armor items, wings, shield defense
  2. (+) horse bonus defense
  3. (x) (5-30)% set level bonus
  4. (+) MST (Armor set bonus inc - 315) (if complete set of same type; N/A to S6)
  5. (+) MST (Defense inc - 309/587)
  6. (x) 0.5 ("defense halving")
  7. (x) 1.1 (elite transfer skeleton xfm ring)
  8. (+) 10 (robot knight xfm ring)
  9. (+) 50 (panda pet)
  10. (+) 50 (unicorn pet)
  11. (+) JoH option / 2
  12. (+) socket
  13. (+) ancient set opt / 2
  14. (x) ancient and socket def increase with shield
  15. (+) consumables bonus (Jack O'Lantern Cry) / 2
  16. (+) Greater Defense buff (elf)
  17. (+) MST bonus defense with shield (Shield strengthener)
  18. (+) MST dark horse strengthener
  19. (+) lvl380 guardian option (pants) / 2 (PvP only)
  20. (x) 0.9 fireslash defense reduction effect

I've tried to keep this as close as possible with OpenMU's attribute values structure (with a few compromises here and there).

Copy link

@gemini-code-assist gemini-code-assist bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hello @ze-dom, I'm Gemini Code Assist1! I'm currently reviewing this pull request and will post my feedback shortly. In the meantime, here's a summary to help you and other reviewers quickly get up to speed!

Summary of Changes

This pull request focuses on refactoring defense calculations within the game, reviewing attack and defense rates for PvM, and fixing bugs related to the attack rate ancient set option and item skill character class requirements. The changes involve modifications to attribute relationships, magic effect definitions, stat calculations, skill lists, character class initializations, skill effects, item options, and socket system options.

Highlights

  • Defense Calculations Refactoring: The pull request overhauls the defense calculations, introducing a new 'DefenseFinal' attribute and adjusting how various bonuses and reductions are applied in PvM and PvP scenarios.
  • Attack and Defense Rate Review: Attack and defense rates for PvM have been reviewed and adjusted, including the incorporation of ancient set options and MST bonuses.
  • Bug Fixes: The pull request addresses bugs related to the attack rate ancient set option and ensures that item skills correctly check character class requirements.
  • Item and Skill Initialization: The pull request modifies item set options, socket options, and skill definitions to align with the refactored defense calculations.

Changelog

Click here to see the changelog
  • src/AttributeSystem/AttributeRelationshipElement.cs
    • Minor formatting change: Added a missing newline at the end of the file.
  • src/DataModel/Configuration/MagicEffectDefinition.cs
    • Expanded the description of MagicEffectDefinition to include effects from attack skills.
  • src/GameLogic/Attributes/Stats.cs
    • Added detailed remarks to the AttackRatePvm, DefenseBase, DefenseFinal, DefensePvm, DefensePvp, DefenseRatePvm, and DefenseIncreaseWithEquippedShield attribute definitions, clarifying how different aggregate types contribute to the final values.
    • Renamed 'BonusDefenseWithShield' to 'BonusDefenseWithShield (MST)' and 'BonusDefenseWithHorse' to 'BonusDefenseWithHorse (MST)' to indicate MST-specific bonuses.
    • Added a new attribute definition 'BonusDefenseRateWithShield' for PvM defense rate increase with an equipped shield (MST).
  • src/GameLogic/PlayerActions/Quests/ElfSoldierBuffRequestAction.cs
    • Modified the Elf Soldier buff to apply to 'Stats.DefenseFinal' instead of 'Stats.DefenseBase', using AggregateType.AddFinal.
  • src/GameLogic/SkillList.cs
    • Added a check to ensure that the character class is qualified to use the item skill before adding it to the skill list.
  • src/Persistence/Initialization/CharacterClasses/CharacterClassInitialization.cs
    • Reorganized attribute relationships for defense calculations, introducing 'DefenseFinal' as an intermediate attribute.
    • Modified how shield-related defense bonuses are applied, using conditional relationships and aggregate types to ensure correct calculations.
    • Added conditional relationships for 'BonusDefenseWithShield' and 'BonusDefenseRateWithShield' based on shield equipment.
  • src/Persistence/Initialization/CharacterClasses/ClassDarkKnight.cs
    • Changed the attribute relationship for 'MaximumShield' to use 'Stats.DefenseFinal' instead of 'Stats.DefenseBase'.
  • src/Persistence/Initialization/CharacterClasses/ClassDarkLord.cs
    • Added a conditional relationship for 'BonusDefenseWithHorse' to 'Stats.DefenseFinal' when a horse is equipped.
    • Changed the attribute relationship for 'MaximumShield' to use 'Stats.DefenseFinal' instead of 'Stats.DefenseBase'.
  • src/Persistence/Initialization/CharacterClasses/ClassDarkWizard.cs
    • Changed the attribute relationship for 'MaximumShield' to use 'Stats.DefenseFinal' instead of 'Stats.DefenseBase'.
  • src/Persistence/Initialization/CharacterClasses/ClassFairyElf.cs
    • Changed the attribute relationship for 'MaximumShield' to use 'Stats.DefenseFinal' instead of 'Stats.DefenseBase'.
  • src/Persistence/Initialization/CharacterClasses/ClassMagicGladiator.cs
    • Changed the attribute relationship for 'MaximumShield' to use 'Stats.DefenseFinal' instead of 'Stats.DefenseBase'.
  • src/Persistence/Initialization/CharacterClasses/ClassRageFighter.cs
    • Changed the attribute relationship for 'MaximumShield' to use 'Stats.DefenseFinal' instead of 'Stats.DefenseBase'.
  • src/Persistence/Initialization/CharacterClasses/ClassSummoner.cs
    • Changed the attribute relationship for 'MaximumShield' to use 'Stats.DefenseFinal' instead of 'Stats.DefenseBase'.
  • src/Persistence/Initialization/Skills/DefenseEffectInitializer.cs
    • Increased the duration of the defense effect from 1 second to 4 seconds.
  • src/Persistence/Initialization/Skills/DefenseReductionEffectInitializer.cs
    • Modified the defense reduction effect to apply separately to 'DefensePvm' and 'DefensePvp' instead of 'DefenseBase'.
  • src/Persistence/Initialization/Skills/GreaterDefenseEffectInitializer.cs
    • Modified the Greater Defense effect to target 'Stats.DefenseFinal' instead of 'Stats.DefenseBase', using AggregateType.AddFinal.
  • src/Persistence/Initialization/Version095d/GameConfigurationInitializer.cs
    • No functional changes; just whitespace/formatting.
  • src/Persistence/Initialization/VersionSeasonSix/Items/AncientSets.cs
    • Updated ancient set options to include AggregateType specifications.
    • Replaced 'ShieldBlockDamageDecrement' with 'DefenseIncreaseWithEquippedShield' in the Anonymous set.
    • Modified 'AttackRatePvm' in several sets to use AggregateType.Multiplicate instead of AddRaw.
    • Corrected 'ExcellentDamageChance' to 'ExcellentDamageBonus' in the Anubis set.
  • src/Persistence/Initialization/VersionSeasonSix/Items/GuardianOptions.cs
    • Modified the Guardian pants option to apply to 'Stats.DefensePvp' instead of 'Stats.DefenseBase', halving the value.
  • src/Persistence/Initialization/VersionSeasonSix/Items/HarmonyOptions.cs
    • Modified the Harmony defense option to use AggregateType.AddFinal instead of AddRaw.
  • src/Persistence/Initialization/VersionSeasonSix/Items/Potions.cs
    • Modified the Jack O'Lantern Cry effect to target 'Stats.DefenseFinal' instead of 'Stats.DefenseBase', halving the value and using AggregateType.AddFinal.
    • Added overloads to CreateConsumeEffect to allow specifying AggregateType for boosts.
  • src/Persistence/Initialization/VersionSeasonSix/SkillsInitializer.cs
    • Modified master skill definitions to use AggregateType.AddFinal for 'AttackRatePvm' in several skills.
    • Modified master skill definitions to target 'BonusDefenseRateWithShield' instead of 'BonusDefenseWithShield' in several skills.
    • Modified master skill definitions to use AggregateType.AddFinal for 'DefenseBase' in 'DefenseIncrease'.
  • src/Persistence/Initialization/VersionSeasonSix/SocketSystem.cs
    • Modified socket options to target 'Stats.DefenseFinal' instead of 'Stats.DefenseBase'.
    • Replaced 'ShieldDecreaseRateIncrease' with 'DefenseIncreaseWithEquippedShield' in water options.
    • Modified socket bonus options for armors to target 'Stats.DefenseFinal' instead of 'Stats.DefenseBase'.
Using Gemini Code Assist

The full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips.

Invoking Gemini

You can request assistance from Gemini at any point in your pull request via creating an issue comment (i.e. comment on the pull request page) using either /gemini <command> or @gemini-code-assist <command>. Below is a summary of the supported commands.

Feature Command Description
Code Review /gemini review Performs a code review for the current pull request in its current state.
Pull Request Summary /gemini summary Provides a summary of the current pull request in its current state.
Comment @gemini-code-assist Responds in comments when explicitly tagged, both in issue comments and review comments.
Help /gemini help Displays a list of available commands.

Customization

To customize Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a .gemini/ folder in the base of the repository. Detailed instructions can be found here.

Limitations & Feedback

Gemini Code Assist is currently in preview and may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counter productive. You can react with 👍 and 👎 on @gemini-code-assist comments to provide feedback.

You can also get AI-powered code generation, chat, as well as code reviews directly in the IDE at no cost with the Gemini Code Assist IDE Extension.


A knight's shield, a wizard's spell,
Defense is key, all must fare well.
With stats aligned,
The game's refined,
A balanced world, the code does tell.

Footnotes

  1. Review the Privacy Notices, Generative AI Prohibited Use Policy, Terms of Service, and learn how to configure Gemini Code Assist in GitHub here. Gemini can make mistakes, so double check it and use code with caution.

Copy link

@gemini-code-assist gemini-code-assist bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request refactors defense calculations and addresses some bugs related to attack rate and item skill requirements. The changes appear to be well-structured and include helpful comments. However, there are a few areas where further clarification or adjustments could improve the code.

Summary of Findings

  • AggregateType Usage in Ancient Sets: The changes in AncientSets.cs introduce explicit AggregateType specifications for ancient set bonuses. While this is generally good, ensure that the chosen AggregateType aligns with the intended effect of each bonus. Specifically, double-check if AddRaw is always the correct choice, or if AddFinal or Multiplicate would be more appropriate in certain cases.
  • DefenseBase vs. DefenseFinal: The pull request shifts calculations from DefenseBase to DefenseFinal. Ensure that this change is thoroughly tested and validated across all game scenarios to prevent unintended consequences or imbalances.
  • Inconsistent use of AddRaw vs AddFinal: There are some inconsistencies in the use of AddRaw vs AddFinal. For example, in SkillsInitializer.cs, DefenseIncrease is changed to AddFinal while AttackSuccRateInc is changed to AddFinal. Please double check if these are correct.

Merge Readiness

The pull request introduces significant changes to defense calculations and item attributes. While the changes seem well-reasoned, thorough testing is crucial to ensure that the new calculations are balanced and do not introduce any unintended side effects. I recommend addressing the comments below, particularly those related to the use of AggregateType and the shift from DefenseBase to DefenseFinal, before merging. I am unable to directly approve this pull request, and recommend that others review and approve this code before merging.

(Stats.DefenseBase, 100.0f));
(Stats.MaximumHealth, 100.0f, AggregateType.AddRaw),
(Stats.MaximumMana, 100.0f, AggregateType.AddRaw),
(Stats.DefenseBase, 100.0f, AggregateType.AddFinal));

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

high

Why was this changed to AddFinal? Does this mean the defense bonus from the Fase set is now applied after all other defense calculations? Please confirm that this is the intended behavior.

@@ -449,7 +449,7 @@ private ItemDefinition CreateJackOLanternCry()
item.Width = 1;
item.Height = 2;
item.SetGuid(item.Group, item.Number);
this.CreateConsumeEffect(item, 16, MagicEffectNumber.JackOlanternCry, TimeSpan.FromMinutes(30), (Stats.DefenseBase, 100));
this.CreateConsumeEffect(item, 16, MagicEffectNumber.JackOlanternCry, TimeSpan.FromMinutes(30), (Stats.DefenseFinal, 100 / 2, AggregateType.AddFinal));

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

high

Why was this changed to AddFinal? Does this mean the defense bonus from the Jack O'Lantern Cry is now applied after all other defense calculations? Please confirm that this is the intended behavior.

@@ -397,7 +397,7 @@ private ItemOptionDefinition CreateBonusOptionForArmorsOptionDefinition()
definition.Name = "Socket Bonus Options (Armors)";
definition.MaximumOptionsPerItem = 1;
definition.AddChance = 0.30f;
definition.PossibleOptions.Add(this.CreateSocketBonusOption(4, Stats.DefenseBase, 24));
definition.PossibleOptions.Add(this.CreateSocketBonusOption(4, Stats.DefenseFinal, 24));

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

high

Should this be DefenseFinal instead of DefenseBase? It seems like the intention is to increase the final defense value.

(Stats.SkillDamageBonus, 10.0f, AggregateType.AddRaw),
(Stats.MaximumAbility, 20.0f, AggregateType.AddRaw),
(Stats.AbilityRecoveryAbsolute, 5.0f, AggregateType.AddRaw),
(Stats.DefenseBase, 20.0f, AggregateType.AddFinal),

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

high

Why was this changed to AddFinal? Does this mean the defense bonus from the Warrior set is now applied after all other defense calculations? Please confirm that this is the intended behavior.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I want to know this, too 😆

Copy link
Contributor Author

@ze-dom ze-dom May 15, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah, this was my effort to preserve the defense calculation order (refer to the PR's updated description).
Because the ancient option appears to be added after the set level bonus AggregatyeType.Multiplier, my intent was to keep it out of that.

The client seems to follow this order too (+15 set => +30%):
Screenshot from 2025-05-15 14-11-32

The same goes for harmony option (+13 set => +20%):
Screenshot from 2025-05-15 14-31-32

The 51.82 comes from MST:
image

(Stats.CriticalDamageChance, 0.10f),
(Stats.ExcellentDamageChance, 0.10f));
(Stats.SkillDamageBonus, 15.0f, AggregateType.AddRaw),
(Stats.AttackRatePvm, 1.50f, AggregateType.Multiplicate),

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

high

Why was this changed to Multiplicate? It seems like the attack rate bonus from the Eplete set is now a multiplier instead of an additive bonus. Please confirm that this is the intended behavior.

Copy link
Contributor Author

@ze-dom ze-dom May 13, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

According to these server sources (zTeam, emu) the attack rate set option increase is a multiplier.
However, on the client's side it is simply added:

Screenshot from 2025-05-13 11-22-57
Screenshot from 2025-05-13 11-28-18

@@ -667,6 +667,11 @@ private void AddItems(ItemSetGroup set, params (short Number, ItemGroups Group,
}

private ItemSetGroup AddAncientSet(string name, short setNumber, params (AttributeDefinition Attribute, float Value)[] ancientOptions)
{
return this.AddAncientSet(name, setNumber, ancientOptions.Select(ancOpt => (ancOpt.Attribute, ancOpt.Value, AggregateType.AddRaw)).ToArray());

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

This change introduces a default AggregateType.AddRaw for ancient set bonuses. Ensure that this default is appropriate for all existing and future set bonuses. Consider providing a more descriptive comment explaining the rationale behind this default.

Comment on lines +531 to +538
/// <remarks>
/// <see cref="AggregateType.AddRaw"/> values include:
/// Armor, shield, and wings defense plus their item options; dark horse defense bonus.
/// <see cref="AggregateType.Multiplicate"/> values include:
/// Set level bonus; elite transfer skeleton xfm ring bonus.
/// <see cref="AggregateType.AddFinal"/> values include:
/// Harmony defense bonus option; ancient defense bonus option; MST defense increase bonus.
/// </remarks>

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

It's great that you've added these remarks to clarify the aggregate types for this attribute. This is very helpful for understanding how the defense is calculated. Consider adding similar remarks to other attribute definitions as well, especially those involved in complex calculations.

@@ -524,6 +524,11 @@ private ItemDefinition CreateCherryBlossomFlowerPetal()
}

private MagicEffectDefinition CreateConsumeEffect(ItemDefinition item, byte subType, MagicEffectNumber effectNumber, TimeSpan duration, params (AttributeDefinition TargetAttribute, float BoostValue)[] boosts)
{
return this.CreateConsumeEffect(item, subType, effectNumber, duration, boosts.Select(b => (b.TargetAttribute, b.BoostValue, AggregateType.AddRaw)).ToArray());

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

This change introduces a default AggregateType.AddRaw for consume effects. Ensure that this default is appropriate for all existing and future effects. Consider providing a more descriptive comment explaining the rationale behind this default.

Comment on lines 566 to +573
/// Gets the defense PVP attribute definition.
/// </summary>
/// <remarks>
/// <see cref="AggregateType.AddRaw"/> values include:
/// <see cref="DefenseFinal"/>; pants guardian option (halved).
/// <see cref="AggregateType.Multiplicate"/> values include:
/// Fire slash defense reduction.
/// </remarks>

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

It's great that you've added these remarks to clarify the aggregate types for this attribute. This is very helpful for understanding how the defense is calculated. Consider adding similar remarks to other attribute definitions as well, especially those involved in complex calculations.

Comment on lines 577 to 584
/// Gets the defense rate PVM attribute definition.
/// </summary>
/// <remarks>
/// <see cref="AggregateType.AddRaw"/> values include:
/// Base defense rate from agility; MST bonus defense rate with shield (shield mastery).
/// <see cref="AggregateType.Multiplicate"/> values include:
/// Complete set bonus multiplier (+10%); MST PvM defense rate increase multiplier; excellent DR option multiplier.
/// </remarks>

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

It's great that you've added these remarks to clarify the aggregate types for this attribute. This is very helpful for understanding how the defense is calculated. Consider adding similar remarks to other attribute definitions as well, especially those involved in complex calculations.

{
return;
}

Copy link
Contributor Author

@ze-dom ze-dom May 12, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For example, shield defense skill was being listed for DW, elf.
Screenshot from 2025-05-13 14-26-41

@@ -96,7 +96,7 @@ protected CharacterClass CreateDarkKnight(CharacterClassNumber number, string na
result.AttributeCombinations.Add(this.CreateAttributeRelationship(Stats.MaximumShield, 1.2f, Stats.TotalVitality));
result.AttributeCombinations.Add(this.CreateAttributeRelationship(Stats.MaximumShield, 1.2f, Stats.TotalAgility));
result.AttributeCombinations.Add(this.CreateAttributeRelationship(Stats.MaximumShield, 1.2f, Stats.TotalStrength));
result.AttributeCombinations.Add(this.CreateAttributeRelationship(Stats.MaximumShield, 0.5f, Stats.DefenseBase));
result.AttributeCombinations.Add(this.CreateAttributeRelationship(Stats.MaximumShield, 1f, Stats.DefenseFinal));
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

reduceDefenseEffect.Boost = this.Context.CreateNew<PowerUpDefinitionValue>();
reduceDefenseEffect.Boost.ConstantValue.Value = 0.9f;
reduceDefenseEffect.Boost.ConstantValue.AggregateType = AggregateType.Multiplicate;
var reducePvmDefenseEffect = this.Context.CreateNew<PowerUpDefinition>();
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Wouldn't it work on the new DefenseFinal, too?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The rational for this is this effect appears to be the very last multiplier applied on defense calculation (zTeamS6.3, emu).

If it targeted DefenseFinal, as an AggregateType.Multiplicate, it would miss out on DefenseFinal's AggregateType.AddFinal values, as well as the the 380/guardian pants option (+200/2), which goes only into DefensePvp, thus lessening its effect.

(Stats.SkillDamageBonus, 10.0f, AggregateType.AddRaw),
(Stats.MaximumAbility, 20.0f, AggregateType.AddRaw),
(Stats.AbilityRecoveryAbsolute, 5.0f, AggregateType.AddRaw),
(Stats.DefenseBase, 20.0f, AggregateType.AddFinal),
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I want to know this, too 😆

@@ -694,7 +694,7 @@ private void InitializeMasterSkillData()
this.AddPassiveMasterSkillDefinition(SkillNumber.ShieldStrengthenerGrandMaster, Stats.BonusDefenseWithShield, AggregateType.AddRaw, Formula803, 2, 3); // todo: check if this is correct
this.AddPassiveMasterSkillDefinition(SkillNumber.OneHandedStaffMaster, Stats.AttackSpeed, AggregateType.AddRaw, Formula1, 3, 3, SkillNumber.OneHandedStaffStrengthener, SkillNumber.Undefined, 10);
this.AddPassiveMasterSkillDefinition(SkillNumber.TwoHandedStaffMaster, Stats.TwoHandedStaffBonusBaseDamage, AggregateType.AddRaw, Formula1154, 3, 3, SkillNumber.TwoHandedStaffStrengthener); // todo: only pvp
this.AddPassiveMasterSkillDefinition(SkillNumber.ShieldMasteryGrandMaster, Stats.BonusDefenseWithShield, AggregateType.AddRaw, Formula1204, 3, 3, SkillNumber.ShieldStrengthenerGrandMaster);
this.AddPassiveMasterSkillDefinition(SkillNumber.ShieldMasteryGrandMaster, Stats.BonusDefenseRateWithShield, AggregateType.AddRaw, Formula1204, 3, 3, SkillNumber.ShieldStrengthenerGrandMaster);
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Poorly described in the client, but both client and server consider this as defense rate:
zTeam6.3
Screenshot from 2025-05-14 15-28-23
Screenshot from 2025-05-14 15-30-20

Applies to LE, GM, HE.

this.AddPassiveMasterSkillDefinition(SkillNumber.AutomaticAgRecInc, Stats.AbilityRecoveryMultiplier, AggregateType.AddRaw, FormulaRecoveryIncrease120, Formula120, 4, 1, SkillNumber.AutomaticHpRecInc, SkillNumber.Undefined, 20);
this.AddPassiveMasterSkillDefinition(SkillNumber.IceResistanceIncrease, Stats.IceResistance, AggregateType.AddRaw, Formula120Value, Formula120, 2, 1, requiredSkill1: SkillNumber.LightningResistanceInc);
this.AddPassiveMasterSkillDefinition(SkillNumber.DurabilityReduction3, Stats.ItemDurationIncrease, AggregateType.Multiplicate, Formula1204, 5, 1, SkillNumber.DurabilityReduction2);
this.AddPassiveMasterSkillDefinition(SkillNumber.DefenseSuccessRateInc, Stats.DefenseRatePvm, AggregateType.AddRaw, Formula120, 5, 1, SkillNumber.DefenseIncrease);
this.AddPassiveMasterSkillDefinition(SkillNumber.DefenseSuccessRateInc, Stats.DefenseRatePvm, AggregateType.Multiplicate, $"1 + {Formula120} / 100", 5, 1, SkillNumber.DefenseIncrease);
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As is, with the bugged value:
Screenshot from 2025-05-14 12-56-32

Below, the first calculation is the S6E3 client's way, the second is the server's to-be.
Screenshot from 2025-05-14 12-19-18

@@ -633,11 +633,11 @@ private void InitializeMasterSkillData()
this.AddMasterSkillDefinition(SkillNumber.SdRecoverySpeedInc, SkillNumber.MaximumSDincrease, SkillNumber.Undefined, 1, 3, SkillNumber.Undefined, 20, Formula120);
this.AddPassiveMasterSkillDefinition(SkillNumber.AutomaticHpRecInc, Stats.HealthRecoveryMultiplier, AggregateType.AddRaw, FormulaRecoveryIncrease120, Formula120, 3, 1, SkillNumber.AutomaticManaRecInc, SkillNumber.Undefined, 20);
this.AddPassiveMasterSkillDefinition(SkillNumber.LightningResistanceInc, Stats.LightningResistance, AggregateType.AddRaw, Formula120Value, Formula120, 2, 1, requiredSkill1: SkillNumber.PoisonResistanceInc);
this.AddPassiveMasterSkillDefinition(SkillNumber.DefenseIncrease, Stats.DefenseBase, AggregateType.AddRaw, Formula6020, 4, 1);
this.AddPassiveMasterSkillDefinition(SkillNumber.DefenseIncrease, Stats.DefenseBase, AggregateType.AddFinal, Formula6020, 4, 1);
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Screenshot from 2025-05-14 11-48-31
Screenshot from 2025-05-14 11-49-16

definition.PossibleOptions.Add(this.CreateSocketOption(1, SocketSubOptionType.Water, Stats.DefenseBase, AggregateType.AddRaw, 30, 33, 36, 39, 42));
definition.PossibleOptions.Add(this.CreateSocketOption(2, SocketSubOptionType.Water, Stats.ShieldDecreaseRateIncrease, AggregateType.AddRaw, 0.07f, 0.10f, 0.15f, 0.20f, 0.30f));
definition.PossibleOptions.Add(this.CreateSocketOption(1, SocketSubOptionType.Water, Stats.DefenseFinal, AggregateType.AddRaw, 30, 33, 36, 39, 42));
definition.PossibleOptions.Add(this.CreateSocketOption(2, SocketSubOptionType.Water, Stats.DefenseIncreaseWithEquippedShield, AggregateType.AddRaw, 0.07f, 0.10f, 0.15f, 0.20f, 0.30f));
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There seems to be a discrepancy between S6E3 client and server sources here.

While the server sources (zTeamS6.3, emu) say this is the same stat as the ancient def increase with equipped shield (zTeamS6.3, emu), the client applies this multiplier only to the shield's defense:
image
image
image
375 + (27 *1.15) = 406

I am guessing the client is correct here, otherwise you could get +30% total defense several times over, which seems excessive. If this is original code on the server side that's a huge bug 😄 !

@ze-dom ze-dom requested a review from sven-n May 16, 2025 14:31
@@ -35,7 +35,7 @@ public override void Initialize()
magicEffect.SendDuration = false;
magicEffect.StopByDeath = true;
magicEffect.Duration = this.Context.CreateNew<PowerUpDefinitionValue>();
magicEffect.Duration.ConstantValue!.Value = 1; // 1 Second
magicEffect.Duration.ConstantValue!.Value = 4; // 4 Seconds
Copy link
Contributor Author

@ze-dom ze-dom May 20, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copy link
Member

@sven-n sven-n left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good, is it still a draft or can I merge it?

@ze-dom
Copy link
Contributor Author

ze-dom commented May 22, 2025

No! Still a draft. Just wanted your input before moving on. The Update Plugins are still missing and I still need to add the fix for this issue.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants