From 30cec0b1fd101022787a9ec917256aa017437d34 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=82ngelo=20Tadeucci?= Date: Fri, 20 Sep 2024 09:24:12 -0300 Subject: [PATCH 1/6] Fix: Stats --- Maple2.File.Ingest/MapperExtensions.cs | 2 +- Maple2.Model/Game/Item/ItemStats.cs | 5 ++++- Maple2.Server.Game/Commands/ItemCommand.cs | 8 ++++--- .../Manager/Items/ItemDropManager.cs | 4 ++-- .../Util/ItemStatsCalculator.cs | 22 +++++++++---------- 5 files changed, 23 insertions(+), 18 deletions(-) diff --git a/Maple2.File.Ingest/MapperExtensions.cs b/Maple2.File.Ingest/MapperExtensions.cs index 3c422ace..c85875d2 100644 --- a/Maple2.File.Ingest/MapperExtensions.cs +++ b/Maple2.File.Ingest/MapperExtensions.cs @@ -432,7 +432,7 @@ public static Dictionary> ToDictionary } var option = new ItemOption( - MultiplyFactor: entry.multiply_factor, + MultiplyFactor: entry.multiply_factor == 0 ? 1 : entry.multiply_factor, NumPick: new ItemOption.Range(entry.optionNumPick[0], entry.optionNumPick[1]), Entries: optionEntries.ToArray()); if (results[entry.code].ContainsKey(entry.grade)) { diff --git a/Maple2.Model/Game/Item/ItemStats.cs b/Maple2.Model/Game/Item/ItemStats.cs index 187a6c29..0be74341 100644 --- a/Maple2.Model/Game/Item/ItemStats.cs +++ b/Maple2.Model/Game/Item/ItemStats.cs @@ -100,11 +100,14 @@ public class Option { public readonly Dictionary Basic; public readonly Dictionary Special; + public readonly float MultiplyFactor; + public int Count => Basic.Count + Special.Count; - public Option(Dictionary? basicOption = null, Dictionary? specialOption = null) { + public Option(Dictionary? basicOption = null, Dictionary? specialOption = null, float multiplyFactor = 1) { Basic = basicOption ?? new Dictionary(); Special = specialOption ?? new Dictionary(); + MultiplyFactor = multiplyFactor; } public override string ToString() { diff --git a/Maple2.Server.Game/Commands/ItemCommand.cs b/Maple2.Server.Game/Commands/ItemCommand.cs index 3e6165a3..32c91885 100644 --- a/Maple2.Server.Game/Commands/ItemCommand.cs +++ b/Maple2.Server.Game/Commands/ItemCommand.cs @@ -28,18 +28,20 @@ public ItemCommand(GameSession session, ItemMetadataStorage itemStorage) : base( var amount = new Option(["--amount", "-a"], () => 1, "Amount of the item."); var rarity = new Option(["--rarity", "-r"], () => 1, "Rarity of the item."); var drop = new Option(["--drop"], "Drop item instead of adding to inventory"); + var rollMax = new Option(["--roll-max"], () => false, "Max roll stats."); AddArgument(id); AddOption(amount); AddOption(rarity); AddOption(drop); - this.SetHandler(Handle, id, amount, rarity, drop); + AddOption(rollMax); + this.SetHandler(Handle, id, amount, rarity, drop, rollMax); } - private void Handle(InvocationContext ctx, int itemId, int amount, int rarity, bool drop) { + private void Handle(InvocationContext ctx, int itemId, int amount, int rarity, bool drop, bool rollMax) { try { rarity = Math.Clamp(rarity, 1, MAX_RARITY); - Item? item = session.Field.ItemDrop.CreateItem(itemId, rarity); + Item? item = session.Field.ItemDrop.CreateItem(itemId, rarity, rollMax: rollMax); if (item == null) { ctx.Console.Error.WriteLine($"Invalid Item: {itemId}"); return; diff --git a/Maple2.Server.Game/Manager/Items/ItemDropManager.cs b/Maple2.Server.Game/Manager/Items/ItemDropManager.cs index 276d69dd..e7c00e7c 100644 --- a/Maple2.Server.Game/Manager/Items/ItemDropManager.cs +++ b/Maple2.Server.Game/Manager/Items/ItemDropManager.cs @@ -290,7 +290,7 @@ private bool IsItemJobRecommended(int itemId, JobCode job) { return itemMetadata.Limit.JobRecommends.Contains(job) || itemMetadata.Limit.JobRecommends.Contains(JobCode.None); } - public Item? CreateItem(int itemId, int rarity = -1, int amount = 1) { + public Item? CreateItem(int itemId, int rarity = -1, int amount = 1, bool rollMax = false) { if (!field.ItemMetadata.TryGet(itemId, out ItemMetadata? itemMetadata)) { return null; } @@ -304,7 +304,7 @@ private bool IsItemJobRecommended(int itemId, JobCode job) { } var item = new Item(itemMetadata, rarity, amount); - item.Stats = field.ItemStatsCalc.GetStats(item); + item.Stats = field.ItemStatsCalc.GetStats(item, rollMax); item.Socket = field.ItemStatsCalc.GetSockets(item); if (item.Appearance != null) { diff --git a/Maple2.Server.Game/Util/ItemStatsCalculator.cs b/Maple2.Server.Game/Util/ItemStatsCalculator.cs index 8f8ca8f6..5eed7a70 100644 --- a/Maple2.Server.Game/Util/ItemStatsCalculator.cs +++ b/Maple2.Server.Game/Util/ItemStatsCalculator.cs @@ -18,7 +18,7 @@ public sealed class ItemStatsCalculator { // ReSharper restore All #endregion - public ItemStats? GetStats(Item item) { + public ItemStats? GetStats(Item item, bool rollMax = false) { if (item.Metadata.Option == null) { return null; } @@ -36,7 +36,7 @@ public sealed class ItemStatsCalculator { } if (GetRandomOption(item, out ItemStats.Option? option)) { - RandomizeValues(item.Type, ref option); + RandomizeValues(item.Type, ref option, rollMax); stats[ItemStats.Type.Random] = option; } @@ -106,30 +106,30 @@ public bool UpdateRandomOption(ref Item item, params LockOption[] presets) { } // TODO: These should technically be weighted towards the lower end. - public bool RandomizeValues(in ItemType type, ref ItemStats.Option option) { + public bool RandomizeValues(in ItemType type, ref ItemStats.Option option, bool rollMax = false) { ItemEquipVariationTable? table = GetVariationTable(type); if (table == null) { return false; } foreach (BasicAttribute attribute in option.Basic.Keys) { - int index = Random.Shared.Next(2, 18); + int index = rollMax ? 17 : Random.Shared.Next(2, 18); if (table.Values.TryGetValue(attribute, out int[]? values)) { int value = values.ElementAtOrDefault(index); - option.Basic[attribute] = new BasicOption(value); + option.Basic[attribute] = new BasicOption((int) (value * option.MultiplyFactor)); } else if (table.Rates.TryGetValue(attribute, out float[]? rates)) { float rate = rates.ElementAtOrDefault(index); - option.Basic[attribute] = new BasicOption(rate); + option.Basic[attribute] = new BasicOption(rate * option.MultiplyFactor); } } foreach (SpecialAttribute attribute in option.Special.Keys) { - int index = Random.Shared.Next(2, 18); + int index = rollMax ? 17 : Random.Shared.Next(2, 18); if (table.SpecialValues.TryGetValue(attribute, out int[]? values)) { int value = values.ElementAtOrDefault(index); - option.Special[attribute] = new SpecialOption(0f, value); + option.Special[attribute] = new SpecialOption(0f, value * option.MultiplyFactor); } else if (table.SpecialRates.TryGetValue(attribute, out float[]? rates)) { float rate = rates.ElementAtOrDefault(index); - option.Special[attribute] = new SpecialOption(rate); + option.Special[attribute] = new SpecialOption(rate * option.MultiplyFactor); } } @@ -251,7 +251,7 @@ private static ItemStats.Option RandomItemOption(ItemOption option, int count = int total = count < 0 ? Random.Shared.Next(option.NumPick.Min, option.NumPick.Max + 1) : count; if (total == 0) { - return new ItemStats.Option(statResult, specialResult); + return new ItemStats.Option(statResult, specialResult, multiplyFactor: option.MultiplyFactor); } // Ensures that there are enough options to choose. total = Math.Min(total, option.Entries.Length); @@ -276,7 +276,7 @@ private static ItemStats.Option RandomItemOption(ItemOption option, int count = } } - return new ItemStats.Option(statResult, specialResult); + return new ItemStats.Option(statResult, specialResult, multiplyFactor: option.MultiplyFactor); // Helper function bool AddResult(ItemOption.Entry entry, IDictionary statDict, IDictionary specialDict) { From 2246b20eee960b993ac4f837bcc80359ba5fafd4 Mon Sep 17 00:00:00 2001 From: Zin <62830952+Zintixx@users.noreply.github.com> Date: Fri, 7 Feb 2025 10:56:53 -0800 Subject: [PATCH 2/6] Differentiate random stats by RandomMakeType --- Maple2.File.Ingest/Maple2.File.Ingest.csproj | 2 +- Maple2.File.Ingest/Mapper/ItemMapper.cs | 2 +- Maple2.File.Ingest/Mapper/TableMapper.cs | 63 ++++-- Maple2.Model/Enum/ItemOptionMakeType.cs | 6 + Maple2.Model/Metadata/ItemMetadata.cs | 2 +- .../Metadata/Table/ItemOptionTable.cs | 22 +- .../ChangeAttributesScrollHandler.cs | 59 +++--- .../Util/ItemStatsCalculator.cs | 189 +++++++++++++++--- 8 files changed, 259 insertions(+), 86 deletions(-) create mode 100644 Maple2.Model/Enum/ItemOptionMakeType.cs diff --git a/Maple2.File.Ingest/Maple2.File.Ingest.csproj b/Maple2.File.Ingest/Maple2.File.Ingest.csproj index 37c1075d..7286a848 100644 --- a/Maple2.File.Ingest/Maple2.File.Ingest.csproj +++ b/Maple2.File.Ingest/Maple2.File.Ingest.csproj @@ -19,7 +19,7 @@ - + diff --git a/Maple2.File.Ingest/Mapper/ItemMapper.cs b/Maple2.File.Ingest/Mapper/ItemMapper.cs index 43b86000..51942187 100644 --- a/Maple2.File.Ingest/Mapper/ItemMapper.cs +++ b/Maple2.File.Ingest/Mapper/ItemMapper.cs @@ -123,7 +123,7 @@ protected override IEnumerable Map() { StaticId: data.option.@static, StaticType: data.option.staticMakeType, RandomId: data.option.random, - RandomType: data.option.randomMakeType, + RandomType: (RandomMakeType) data.option.randomMakeType, ConstantId: data.option.constant, ConstantType: data.option.constantMakeType, LevelFactor: levelFactor, diff --git a/Maple2.File.Ingest/Mapper/TableMapper.cs b/Maple2.File.Ingest/Mapper/TableMapper.cs index 166c97ad..ee6d54ef 100644 --- a/Maple2.File.Ingest/Mapper/TableMapper.cs +++ b/Maple2.File.Ingest/Mapper/TableMapper.cs @@ -460,10 +460,10 @@ private ItemOptionPickTable ParseItemOptionPick() { } private ItemVariationTable ParseItemVariation() { - var values = new Dictionary>(); - var rates = new Dictionary>(); - var specialValues = new Dictionary>(); - var specialRates = new Dictionary>(); + var values = new Dictionary>>(); + var rates = new Dictionary>>(); + var specialValues = new Dictionary>>(); + var specialRates = new Dictionary>>(); foreach (ItemOptionVariation.Option option in optionParser.ParseVariation()) { string name = option.OptionName; if (name.StartsWith("sid")) continue; // Don't know what stat this maps to. @@ -472,11 +472,19 @@ private ItemVariationTable ParseItemVariation() { var variation = new ItemVariationTable.Range( Min: option.OptionValueMin, Max: option.OptionValueMax, - Interval: option.OptionValueVariation); + Variation: option.OptionValueVariation); try { - values[name.ToBasicAttribute()] = variation; + if (values.ContainsKey(name.ToBasicAttribute())) { + values[name.ToBasicAttribute()].Add(variation); + } else { + values.Add(name.ToBasicAttribute(), [variation]); + } } catch (ArgumentOutOfRangeException) { - specialValues[name.ToSpecialAttribute()] = variation; + if (specialValues.ContainsKey(name.ToSpecialAttribute())) { + specialValues[name.ToSpecialAttribute()].Add(variation); + } else { + specialValues.Add(name.ToSpecialAttribute(), [variation]); + } } } else if (option.OptionRateVariation != 0) { if (name.EndsWith("_rate")) { @@ -486,30 +494,45 @@ private ItemVariationTable ParseItemVariation() { var variation = new ItemVariationTable.Range( Min: option.OptionRateMin, Max: option.OptionRateMax, - Interval: option.OptionRateVariation); + Variation: option.OptionRateVariation); try { - rates[name.ToBasicAttribute()] = variation; + if (rates.ContainsKey(name.ToBasicAttribute())) { + rates[name.ToBasicAttribute()].Add(variation); + } else { + rates.Add(name.ToBasicAttribute(), [variation]); + } } catch (ArgumentOutOfRangeException) { - specialRates[name.ToSpecialAttribute()] = variation; + if (specialRates.ContainsKey(name.ToSpecialAttribute())) { + specialRates[name.ToSpecialAttribute()].Add(variation); + } else { + specialRates.Add(name.ToSpecialAttribute(), [variation]); + } } } } - return new ItemVariationTable(values, rates, specialValues, specialRates); + Dictionary[]> valuesArray = values.ToDictionary(kvp => kvp.Key, kvp => kvp.Value.ToArray()); + Dictionary[]> ratesArray = rates.ToDictionary(kvp => kvp.Key, kvp => kvp.Value.ToArray()); + Dictionary[]> specialValuesArray = specialValues.ToDictionary(kvp => kvp.Key, kvp => kvp.Value.ToArray()); + Dictionary[]> specialRatesArray = specialRates.ToDictionary(kvp => kvp.Key, kvp => kvp.Value.ToArray()); + + return new ItemVariationTable(valuesArray, ratesArray, specialValuesArray, specialRatesArray); } private IEnumerable<(string Type, ItemEquipVariationTable Table)> ParseItemEquipVariation() { foreach ((string type, List options) in optionParser.ParseVariationEquip()) { - var values = new Dictionary(); - var rates = new Dictionary(); - var specialValues = new Dictionary(); - var specialRates = new Dictionary(); + var values = new Dictionary[]>(); + var rates = new Dictionary[]>(); + var specialValues = new Dictionary[]>(); + var specialRates = new Dictionary[]>(); foreach (ItemOptionVariationEquip.Option option in options) { string name = option.name.ToLower(); if (name.EndsWith("value")) { - int[] entries = new int[18]; + var entries = new ItemEquipVariationTable.Set[18]; for (int i = 0; i < 18; i++) { - entries[i] = (int) option[i]; + entries[i] = new ItemEquipVariationTable.Set( + Value: (int) option[i], + Weight: 1); // TODO: Weight } name = name[..^"value".Length]; // Remove suffix @@ -520,9 +543,11 @@ private ItemVariationTable ParseItemVariation() { } } else if (name.EndsWith("rate")) { - float[] entries = new float[18]; + var entries = new ItemEquipVariationTable.Set[18]; for (int i = 0; i < 18; i++) { - entries[i] = option[i]; + entries[i] = new ItemEquipVariationTable.Set( + Value: option[i], + Weight: 1); // TODO: Weight } name = name[..^"rate".Length]; // Remove suffix diff --git a/Maple2.Model/Enum/ItemOptionMakeType.cs b/Maple2.Model/Enum/ItemOptionMakeType.cs new file mode 100644 index 00000000..78670b10 --- /dev/null +++ b/Maple2.Model/Enum/ItemOptionMakeType.cs @@ -0,0 +1,6 @@ +namespace Maple2.Model.Enum; + +public enum RandomMakeType { + Base = 0, // uses itemoptionvariation table + Range = 1, // uses itemoptionvariation_* tables +} diff --git a/Maple2.Model/Metadata/ItemMetadata.cs b/Maple2.Model/Metadata/ItemMetadata.cs index aea1f43f..a8dd1b21 100644 --- a/Maple2.Model/Metadata/ItemMetadata.cs +++ b/Maple2.Model/Metadata/ItemMetadata.cs @@ -91,7 +91,7 @@ public record ItemMetadataOption( int StaticId, int StaticType, int RandomId, - int RandomType, + RandomMakeType RandomType, int ConstantId, int ConstantType, int LevelFactor, diff --git a/Maple2.Model/Metadata/Table/ItemOptionTable.cs b/Maple2.Model/Metadata/Table/ItemOptionTable.cs index e7dd6257..694ea329 100644 --- a/Maple2.Model/Metadata/Table/ItemOptionTable.cs +++ b/Maple2.Model/Metadata/Table/ItemOptionTable.cs @@ -49,17 +49,19 @@ IReadOnlyDictionary RandomRate } public record ItemVariationTable( - IReadOnlyDictionary> Values, - IReadOnlyDictionary> Rates, - IReadOnlyDictionary> SpecialValues, - IReadOnlyDictionary> SpecialRates + IReadOnlyDictionary[]> Values, + IReadOnlyDictionary[]> Rates, + IReadOnlyDictionary[]> SpecialValues, + IReadOnlyDictionary[]> SpecialRates ) : Table { - public readonly record struct Range(T Min, T Max, T Interval) where T : INumber; + public readonly record struct Range(T Min, T Max, T Variation) where T : INumber; } public record ItemEquipVariationTable( - IReadOnlyDictionary Values, - IReadOnlyDictionary Rates, - IReadOnlyDictionary SpecialValues, - IReadOnlyDictionary SpecialRates -) : Table; + IReadOnlyDictionary[]> Values, + IReadOnlyDictionary[]> Rates, + IReadOnlyDictionary[]> SpecialValues, + IReadOnlyDictionary[]> SpecialRates +) : Table { + public record Set(T Value, int Weight) where T : INumber; +} diff --git a/Maple2.Server.Game/PacketHandlers/ChangeAttributesScrollHandler.cs b/Maple2.Server.Game/PacketHandlers/ChangeAttributesScrollHandler.cs index a1f23544..d5da8dab 100644 --- a/Maple2.Server.Game/PacketHandlers/ChangeAttributesScrollHandler.cs +++ b/Maple2.Server.Game/PacketHandlers/ChangeAttributesScrollHandler.cs @@ -9,7 +9,7 @@ using Maple2.Server.Game.Packets; using Maple2.Server.Game.Session; using Maple2.Server.Game.Util; -using static Maple2.Model.Error.ChangeAttributesScrollError; +using Maple2.Tools.Extensions; namespace Maple2.Server.Game.PacketHandlers; @@ -57,21 +57,22 @@ private void HandleChange(GameSession session, IByteReader packet) { lock (session.Item) { Item? scroll = session.Item.Inventory.Get(scrollUid, InventoryType.Misc); if (scroll == null || scroll.Metadata.Function?.Type != ItemFunction.ItemRemakeScroll) { - session.Send(ChangeAttributesScrollPacket.Error(s_itemremake_scroll_error_invalid_scroll)); + session.Send(ChangeAttributesScrollPacket.Error(ChangeAttributesScrollError.s_itemremake_scroll_error_invalid_scroll)); return; } Item? item = session.Item.Inventory.Get(itemUid, InventoryType.Gear); if (item == null) { - session.Send(ChangeAttributesScrollPacket.Error(s_itemremake_scroll_error_invalid_target_data)); + session.Send(ChangeAttributesScrollPacket.Error(ChangeAttributesScrollError.s_itemremake_scroll_error_invalid_target_data)); return; } if (item.Stats == null) { - session.Send(ChangeAttributesScrollPacket.Error(s_itemremake_scroll_error_invalid_target_stat)); + session.Send(ChangeAttributesScrollPacket.Error(ChangeAttributesScrollError.s_itemremake_scroll_error_invalid_target_stat)); return; } + ChangeAttributesScrollError error = IsCompatibleScroll(item, scroll); - if (error != none) { + if (error != ChangeAttributesScrollError.none) { session.Send(ChangeAttributesScrollPacket.Error(error)); return; } @@ -81,19 +82,19 @@ private void HandleChange(GameSession session, IByteReader packet) { ItemStats.Option itemOption = item.Stats[ItemStats.Type.Random]; if (isSpecialAttribute) { if (!itemOption.Special.ContainsKey((SpecialAttribute) attribute)) { - session.Send(ChangeAttributesScrollPacket.Error(s_itemremake_scroll_error_impossible_property)); + session.Send(ChangeAttributesScrollPacket.Error(ChangeAttributesScrollError.s_itemremake_scroll_error_impossible_property)); return; } } else { if (!itemOption.Basic.ContainsKey((BasicAttribute) attribute)) { - session.Send(ChangeAttributesScrollPacket.Error(s_itemremake_scroll_error_impossible_property)); + session.Send(ChangeAttributesScrollPacket.Error(ChangeAttributesScrollError.s_itemremake_scroll_error_impossible_property)); return; } } lockItem = ChangeAttributesHandler.GetLockConsumeItem(session, item); if (lockItem == null) { - session.Send(ChangeAttributesScrollPacket.Error(s_itemremake_error_server_fail_lack_lock_consume_item)); + session.Send(ChangeAttributesScrollPacket.Error(ChangeAttributesScrollError.s_itemremake_error_server_fail_lack_lock_consume_item)); return; } } @@ -101,13 +102,23 @@ private void HandleChange(GameSession session, IByteReader packet) { // Clone the item so we can preview changes without modifying existing item. Item changeItem = item.Clone(); if (changeItem.Stats == null) { // This should be impossible, but check again to make linter happy. - session.Send(ChangeAttributesScrollPacket.Error(s_itemremake_scroll_error_invalid_target_stat)); + session.Send(ChangeAttributesScrollPacket.Error(ChangeAttributesScrollError.s_itemremake_scroll_error_invalid_target_stat)); + return; + } + + if (changeItem.Metadata.Option == null) { // This should be impossible, but check again to make linter happy. + session.Send(ChangeAttributesScrollPacket.Error(ChangeAttributesScrollError.s_itemremake_scroll_error_impossible_item)); + return; + } + + if (!TableMetadata.ItemOptionRandomTable.Options.TryGetValue(changeItem.Metadata.Option.RandomId, changeItem.Rarity, out ItemOption? itemOptionMetadata)) { + session.Send(ChangeAttributesScrollPacket.Error(ChangeAttributesScrollError.s_itemremake_scroll_error_impossible_item)); return; } ItemStats.Option changeOption = changeItem.Stats[ItemStats.Type.Random]; - if (!ItemStatsCalc.RandomizeValues(changeItem.Type, ref changeOption)) { - session.Send(ChangeAttributesScrollPacket.Error(s_itemremake_scroll_error_server_fail_remake)); + if (!ItemStatsCalc.RandomizeValues(changeItem.Type, itemOptionMetadata, changeItem.Metadata.Option, ref changeOption)) { + session.Send(ChangeAttributesScrollPacket.Error(ChangeAttributesScrollError.s_itemremake_scroll_error_server_fail_remake)); return; } @@ -124,11 +135,11 @@ private void HandleChange(GameSession session, IByteReader packet) { } if (!session.Item.Inventory.Consume(scroll.Uid, 1)) { - session.Send(ChangeAttributesScrollPacket.Error(s_itemremake_scroll_error_server_fail_consume_scroll)); + session.Send(ChangeAttributesScrollPacket.Error(ChangeAttributesScrollError.s_itemremake_scroll_error_server_fail_consume_scroll)); return; } if (lockItem != null && !session.Item.Inventory.Consume(lockItem.Uid, 1)) { - session.Send(ChangeAttributesScrollPacket.Error(s_itemremake_error_server_fail_lack_lock_consume_item)); + session.Send(ChangeAttributesScrollPacket.Error(ChangeAttributesScrollError.s_itemremake_error_server_fail_lack_lock_consume_item)); return; } @@ -140,19 +151,19 @@ private void HandleChange(GameSession session, IByteReader packet) { private static void HandleSelect(GameSession session, IByteReader packet) { long itemUid = packet.ReadLong(); if (session.ChangeAttributesItem == null || session.ChangeAttributesItem.Uid != itemUid) { - session.Send(ChangeAttributesScrollPacket.Error(s_itemremake_scroll_error_server_fail_apply_before_option)); + session.Send(ChangeAttributesScrollPacket.Error(ChangeAttributesScrollError.s_itemremake_scroll_error_server_fail_apply_before_option)); return; } lock (session.Item) { Item? item = session.Item.Inventory.Get(itemUid, InventoryType.Gear); if (item == null) { - session.Send(ChangeAttributesScrollPacket.Error(s_itemremake_scroll_error_invalid_target_data)); + session.Send(ChangeAttributesScrollPacket.Error(ChangeAttributesScrollError.s_itemremake_scroll_error_invalid_target_data)); return; } if (item.Stats == null || session.ChangeAttributesItem.Stats == null) { - session.Send(ChangeAttributesScrollPacket.Error(s_itemremake_scroll_error_server_fail_apply_before_option)); + session.Send(ChangeAttributesScrollPacket.Error(ChangeAttributesScrollError.s_itemremake_scroll_error_server_fail_apply_before_option)); return; } @@ -164,30 +175,30 @@ private static void HandleSelect(GameSession session, IByteReader packet) { private ChangeAttributesScrollError IsCompatibleScroll(Item item, Item scroll) { if (item.Rarity is < Constant.ChangeAttributesMinRarity or > Constant.ChangeAttributesMaxRarity) { - return s_itemremake_scroll_error_impossible_rank; + return ChangeAttributesScrollError.s_itemremake_scroll_error_impossible_rank; } if (!item.Type.IsWeapon && !item.Type.IsArmor && !item.Type.IsAccessory) { - return s_itemremake_scroll_error_impossible_slot; + return ChangeAttributesScrollError.s_itemremake_scroll_error_impossible_slot; } if (item.Metadata.Limit.Level < Constant.ChangeAttributesMinLevel) { - return s_itemremake_scroll_error_impossible_level; + return ChangeAttributesScrollError.s_itemremake_scroll_error_impossible_level; } // Validate scroll conditions if (!int.TryParse(scroll.Metadata.Function?.Parameters, out int remakeId)) { - return s_itemremake_scroll_error_invalid_scroll_data; + return ChangeAttributesScrollError.s_itemremake_scroll_error_invalid_scroll_data; } if (!TableMetadata.ItemRemakeScrollTable.Entries.TryGetValue(remakeId, out ItemRemakeScrollMetadata? metadata)) { - return s_itemremake_scroll_error_invalid_scroll_data; + return ChangeAttributesScrollError.s_itemremake_scroll_error_invalid_scroll_data; } if (item.Metadata.Limit.Level < metadata.MinLevel || item.Metadata.Limit.Level > metadata.MaxLevel) { - return s_itemremake_scroll_error_impossible_item; + return ChangeAttributesScrollError.s_itemremake_scroll_error_impossible_item; } if (!metadata.Rarities.Contains(item.Rarity) || !metadata.ItemTypes.Contains(item.Type.Type)) { - return s_itemremake_scroll_error_impossible_item; + return ChangeAttributesScrollError.s_itemremake_scroll_error_impossible_item; } - return none; + return ChangeAttributesScrollError.none; } } diff --git a/Maple2.Server.Game/Util/ItemStatsCalculator.cs b/Maple2.Server.Game/Util/ItemStatsCalculator.cs index 5eed7a70..3f4f23d5 100644 --- a/Maple2.Server.Game/Util/ItemStatsCalculator.cs +++ b/Maple2.Server.Game/Util/ItemStatsCalculator.cs @@ -6,6 +6,7 @@ using Maple2.Model.Metadata; using Maple2.Tools.Extensions; using Maple2.Server.Core.Formulas; +using Maple2.Tools; using Serilog; namespace Maple2.Server.Game.Util; @@ -35,8 +36,10 @@ public sealed class ItemStatsCalculator { stats[ItemStats.Type.Static] = staticOption; } - if (GetRandomOption(item, out ItemStats.Option? option)) { - RandomizeValues(item.Type, ref option, rollMax); + + if (TableMetadata.ItemOptionRandomTable.Options.TryGetValue(item.Metadata.Option.RandomId, item.Rarity, out ItemOption? itemOption)) { + ItemStats.Option option = GetRandomOption(itemOption); + RandomizeValues(item.Type, itemOption, item.Metadata.Option, ref option, rollMax); stats[ItemStats.Type.Random] = option; } @@ -77,11 +80,12 @@ public bool UpdateRandomOption(ref Item item, params LockOption[] presets) { } // Get some random options - if (!GetRandomOption(item, out ItemStats.Option? randomOption, option.Count, presets)) { + if (!TableMetadata.ItemOptionRandomTable.Options.TryGetValue(item.Metadata.Option.RandomId, item.Rarity, out ItemOption? itemOption)) { return false; } + ItemStats.Option randomOption = GetRandomOption(itemOption, option.Count, presets); - if (!RandomizeValues(item.Type, ref randomOption)) { + if (!RandomizeValues(item.Type, itemOption, item.Metadata.Option, ref randomOption)) { return false; } @@ -106,34 +110,132 @@ public bool UpdateRandomOption(ref Item item, params LockOption[] presets) { } // TODO: These should technically be weighted towards the lower end. - public bool RandomizeValues(in ItemType type, ref ItemStats.Option option, bool rollMax = false) { + /// + /// + /// + /// Item Type + /// Item's Random Option Metadata + /// Item Metadata Option + /// + /// Select the highest possible roll and circumvents the randomness + /// + public bool RandomizeValues(in ItemType type, ItemOption itemOptionMetadata, ItemMetadataOption itemMetadataOption, ref ItemStats.Option option, bool rollMax = false) { ItemEquipVariationTable? table = GetVariationTable(type); if (table == null) { return false; } foreach (BasicAttribute attribute in option.Basic.Keys) { - int index = rollMax ? 17 : Random.Shared.Next(2, 18); - if (table.Values.TryGetValue(attribute, out int[]? values)) { - int value = values.ElementAtOrDefault(index); + int index = Random.Shared.Next(2, 18); + if (table.Values.TryGetValue(attribute, out ItemEquipVariationTable.Set[]? values)) { + int value = GetValue(itemMetadataOption, itemOptionMetadata, attribute, tableValues: values, rollMax: rollMax); option.Basic[attribute] = new BasicOption((int) (value * option.MultiplyFactor)); - } else if (table.Rates.TryGetValue(attribute, out float[]? rates)) { - float rate = rates.ElementAtOrDefault(index); - option.Basic[attribute] = new BasicOption(rate * option.MultiplyFactor); + } else if (table.Rates.TryGetValue(attribute, out ItemEquipVariationTable.Set[]? rates)) { + int rateInt = GetValue(itemMetadataOption, itemOptionMetadata, attribute, tableRates: rates, rollMax: rollMax); + option.Basic[attribute] = new BasicOption((rateInt / 1000f) * option.MultiplyFactor); } } foreach (SpecialAttribute attribute in option.Special.Keys) { - int index = rollMax ? 17 : Random.Shared.Next(2, 18); - if (table.SpecialValues.TryGetValue(attribute, out int[]? values)) { - int value = values.ElementAtOrDefault(index); + int index = Random.Shared.Next(2, 18); + if (table.SpecialValues.TryGetValue(attribute, out ItemEquipVariationTable.Set[]? values)) { + int value = GetValue(itemMetadataOption, itemOptionMetadata, specialAttribute: attribute, tableValues: values, rollMax: rollMax); option.Special[attribute] = new SpecialOption(0f, value * option.MultiplyFactor); - } else if (table.SpecialRates.TryGetValue(attribute, out float[]? rates)) { - float rate = rates.ElementAtOrDefault(index); - option.Special[attribute] = new SpecialOption(rate * option.MultiplyFactor); + } else if (table.SpecialRates.TryGetValue(attribute, out ItemEquipVariationTable.Set[]? rates)) { + int rateInt = GetValue(itemMetadataOption, itemOptionMetadata, specialAttribute: attribute, tableRates: rates, rollMax: rollMax); + option.Special[attribute] = new SpecialOption((rateInt / 1000f) * option.MultiplyFactor); } } return true; + + int GetValue(ItemMetadataOption itemMetadataOption, ItemOption itemOptionMetadata, BasicAttribute? attribute = null, SpecialAttribute? specialAttribute = null, ItemEquipVariationTable.Set[]? tableValues = null, ItemEquipVariationTable.Set[]? tableRates = null, bool rollMax = false) { + switch (itemMetadataOption.RandomType) { + case RandomMakeType.Range: + var weightedValues = new WeightedSet(); + var weightedRates = new WeightedSet(); + switch (itemMetadataOption.LevelFactor) { + case < 50: + if (rollMax) { + if (tableValues != null) { + return tableValues[2].Value; + } + if (tableRates != null) { + return (int) (tableRates[2].Value * 1000); + } + } + // only gets values from idx 0 to 2 + for (int i = 0; i < 3; i++) { + if (tableValues != null) { + weightedValues.Add(tableValues[i].Value, tableValues[i].Weight); + } else if (tableRates != null) { + weightedRates.Add(tableRates[i].Value, tableRates[i].Weight); + } + } + break; + case < 70: + if (rollMax) { + if (tableValues != null) { + return tableValues[9].Value; + } + if (tableRates != null) { + return (int) (tableRates[9].Value * 1000); + } + } + // only gets values from idx 2 to 9 + for (int i = 2; i < 10; i++) { + if (tableValues != null) { + weightedValues.Add(tableValues[i].Value, tableValues[i].Weight); + } else if (tableRates != null) { + weightedRates.Add(tableRates[i].Value, tableRates[i].Weight); + } + } + break; + case >= 70: + if (rollMax) { + if (tableValues != null) { + return tableValues[17].Value; + } + if (tableRates != null) { + return (int) (tableRates[17].Value * 1000); + } + } + // only gets values from idx 10 to 17 + for (int i = 10; i < 18; i++) { + if (tableValues != null) { + weightedValues.Add(tableValues[i].Value, tableValues[i].Weight); + } else if (tableRates != null) { + weightedRates.Add(tableRates[i].Value, tableRates[i].Weight); + } + } + break; + } + if (tableValues != null) { + return weightedValues.Get(); + } + if (tableRates != null) { + return (int) (weightedRates.Get() * 1000); + } + break; + case RandomMakeType.Base: + default: + float minRate = 0; + int minValue = 0; + if (attribute != null) { + ItemOption.Entry entry = itemOptionMetadata.Entries.FirstOrDefault(optionEntry => optionEntry.BasicAttribute == attribute); + minRate = entry.Rates?.Min ?? 0; + minValue = entry.Values?.Min ?? 0; + return GetItemVariationValue(basicAttribute: attribute, value: minValue, rate: minRate); + } + if (specialAttribute != null) { + ItemOption.Entry entry = itemOptionMetadata.Entries.FirstOrDefault(optionEntry => optionEntry.SpecialAttribute == specialAttribute); + minRate = entry.Rates?.Min ?? 0; + minValue = entry.Values?.Min ?? 0; + return GetItemVariationValue(specialAttribute: specialAttribute, value: minValue, rate: minRate); + } + break; + } + return 0; + } } // Used to calculate the default constant attributes for a given item. @@ -194,19 +296,8 @@ private bool GetStaticOption(Item item, int job, ItemOptionPickTable.Option? pic } // Used to calculate the default random attributes for a given item. - private bool GetRandomOption(Item item, [NotNullWhen(true)] out ItemStats.Option? option, int count = -1, params LockOption[] presets) { - if (item.Metadata.Option == null) { - option = null; - return false; - } - - if (TableMetadata.ItemOptionRandomTable.Options.TryGetValue(item.Metadata.Option.RandomId, item.Rarity, out ItemOption? itemOption)) { - option = RandomItemOption(itemOption, count, presets); - return true; - } - - option = null; - return false; + private ItemStats.Option GetRandomOption(ItemOption itemOption, int count = -1, params LockOption[] presets) { + return RandomItemOption(itemOption, count, presets); } private ItemEquipVariationTable? GetVariationTable(in ItemType type) { @@ -226,6 +317,44 @@ private bool GetRandomOption(Item item, [NotNullWhen(true)] out ItemStats.Option return null; } + /// If the expected value is a rate, it will be multiplied by 1000. Conversion needs to be done afterward. + private int GetItemVariationValue(BasicAttribute? basicAttribute = null, SpecialAttribute? specialAttribute = null, int value = 0, float rate = 0) { + if (basicAttribute != null) { + if (TableMetadata.ItemVariationTable.Values.TryGetValue(basicAttribute.Value, out ItemVariationTable.Range[]? values)) { + foreach (ItemVariationTable.Range range in values) { + if (value >= range.Min && value <= range.Max) { + return Random.Shared.Next(value, value + range.Variation + 1); + } + } + } else if (TableMetadata.ItemVariationTable.Rates.TryGetValue(basicAttribute.Value, out ItemVariationTable.Range[]? rates)) { + foreach (ItemVariationTable.Range range in rates) { + if (rate >= range.Min && rate <= range.Max) { + int convertedVariation = (int) range.Variation * 1000; + int convertedRate = (int) rate * 1000; + return Random.Shared.Next(convertedRate, convertedRate + convertedVariation + 1); + } + } + } + } else if (specialAttribute != null) { + if (TableMetadata.ItemVariationTable.SpecialValues.TryGetValue(specialAttribute.Value, out ItemVariationTable.Range[]? values)) { + foreach (ItemVariationTable.Range range in values) { + if (value >= range.Min && value <= range.Max) { + return Random.Shared.Next(value, value + range.Variation + 1); + } + } + } else if (TableMetadata.ItemVariationTable.SpecialRates.TryGetValue(specialAttribute.Value, out ItemVariationTable.Range[]? rates)) { + foreach (ItemVariationTable.Range range in rates) { + if (rate >= range.Min && rate <= range.Max) { + int convertedVariation = (int) range.Variation * 1000; + int convertedRate = (int) rate * 1000; + return Random.Shared.Next(convertedRate, convertedRate + convertedVariation + 1); + } + } + } + } + return 0; + } + private static ItemStats.Option ConstantItemOption(ItemOptionConstant option) { var statResult = new Dictionary(); var specialResult = new Dictionary(); From 10b395ede93e86614ee26b970d1180bfcadddfc7 Mon Sep 17 00:00:00 2001 From: Zin <62830952+Zintixx@users.noreply.github.com> Date: Fri, 7 Feb 2025 11:05:50 -0800 Subject: [PATCH 3/6] small format fix --- Maple2.Server.Game/Util/ItemStatsCalculator.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Maple2.Server.Game/Util/ItemStatsCalculator.cs b/Maple2.Server.Game/Util/ItemStatsCalculator.cs index 3f4f23d5..c2581822 100644 --- a/Maple2.Server.Game/Util/ItemStatsCalculator.cs +++ b/Maple2.Server.Game/Util/ItemStatsCalculator.cs @@ -208,7 +208,7 @@ int GetValue(ItemMetadataOption itemMetadataOption, ItemOption itemOptionMetadat } } break; - } + } if (tableValues != null) { return weightedValues.Get(); } From 01ad0598433ee4b6fac1a2868bd53e43b38f5ff3 Mon Sep 17 00:00:00 2001 From: Zin <62830952+Zintixx@users.noreply.github.com> Date: Fri, 7 Feb 2025 11:11:27 -0800 Subject: [PATCH 4/6] Remove unused --- Maple2.Server.Game/Util/ItemStatsCalculator.cs | 6 ------ 1 file changed, 6 deletions(-) diff --git a/Maple2.Server.Game/Util/ItemStatsCalculator.cs b/Maple2.Server.Game/Util/ItemStatsCalculator.cs index c2581822..9af5bcae 100644 --- a/Maple2.Server.Game/Util/ItemStatsCalculator.cs +++ b/Maple2.Server.Game/Util/ItemStatsCalculator.cs @@ -110,15 +110,11 @@ public bool UpdateRandomOption(ref Item item, params LockOption[] presets) { } // TODO: These should technically be weighted towards the lower end. - /// - /// - /// /// Item Type /// Item's Random Option Metadata /// Item Metadata Option /// /// Select the highest possible roll and circumvents the randomness - /// public bool RandomizeValues(in ItemType type, ItemOption itemOptionMetadata, ItemMetadataOption itemMetadataOption, ref ItemStats.Option option, bool rollMax = false) { ItemEquipVariationTable? table = GetVariationTable(type); if (table == null) { @@ -126,7 +122,6 @@ public bool RandomizeValues(in ItemType type, ItemOption itemOptionMetadata, Ite } foreach (BasicAttribute attribute in option.Basic.Keys) { - int index = Random.Shared.Next(2, 18); if (table.Values.TryGetValue(attribute, out ItemEquipVariationTable.Set[]? values)) { int value = GetValue(itemMetadataOption, itemOptionMetadata, attribute, tableValues: values, rollMax: rollMax); option.Basic[attribute] = new BasicOption((int) (value * option.MultiplyFactor)); @@ -136,7 +131,6 @@ public bool RandomizeValues(in ItemType type, ItemOption itemOptionMetadata, Ite } } foreach (SpecialAttribute attribute in option.Special.Keys) { - int index = Random.Shared.Next(2, 18); if (table.SpecialValues.TryGetValue(attribute, out ItemEquipVariationTable.Set[]? values)) { int value = GetValue(itemMetadataOption, itemOptionMetadata, specialAttribute: attribute, tableValues: values, rollMax: rollMax); option.Special[attribute] = new SpecialOption(0f, value * option.MultiplyFactor); From e01ad1316d36f3fb8b3f5567d30a5fafbf9de2dc Mon Sep 17 00:00:00 2001 From: Zin <62830952+Zintixx@users.noreply.github.com> Date: Fri, 7 Feb 2025 21:05:24 -0800 Subject: [PATCH 5/6] Changes to support pet bonus attributes --- .../ChangeAttributesScrollHandler.cs | 2 +- .../Util/ItemStatsCalculator.cs | 81 +++++++++++++++---- 2 files changed, 66 insertions(+), 17 deletions(-) diff --git a/Maple2.Server.Game/PacketHandlers/ChangeAttributesScrollHandler.cs b/Maple2.Server.Game/PacketHandlers/ChangeAttributesScrollHandler.cs index d5da8dab..e4d3b2c3 100644 --- a/Maple2.Server.Game/PacketHandlers/ChangeAttributesScrollHandler.cs +++ b/Maple2.Server.Game/PacketHandlers/ChangeAttributesScrollHandler.cs @@ -117,7 +117,7 @@ private void HandleChange(GameSession session, IByteReader packet) { } ItemStats.Option changeOption = changeItem.Stats[ItemStats.Type.Random]; - if (!ItemStatsCalc.RandomizeValues(changeItem.Type, itemOptionMetadata, changeItem.Metadata.Option, ref changeOption)) { + if (!ItemStatsCalc.RandomizeValues(changeItem, itemOptionMetadata, ref changeOption)) { session.Send(ChangeAttributesScrollPacket.Error(ChangeAttributesScrollError.s_itemremake_scroll_error_server_fail_remake)); return; } diff --git a/Maple2.Server.Game/Util/ItemStatsCalculator.cs b/Maple2.Server.Game/Util/ItemStatsCalculator.cs index 9af5bcae..d048843f 100644 --- a/Maple2.Server.Game/Util/ItemStatsCalculator.cs +++ b/Maple2.Server.Game/Util/ItemStatsCalculator.cs @@ -39,7 +39,7 @@ public sealed class ItemStatsCalculator { if (TableMetadata.ItemOptionRandomTable.Options.TryGetValue(item.Metadata.Option.RandomId, item.Rarity, out ItemOption? itemOption)) { ItemStats.Option option = GetRandomOption(itemOption); - RandomizeValues(item.Type, itemOption, item.Metadata.Option, ref option, rollMax); + RandomizeValues(item, itemOption, ref option, rollMax); stats[ItemStats.Type.Random] = option; } @@ -85,7 +85,7 @@ public bool UpdateRandomOption(ref Item item, params LockOption[] presets) { } ItemStats.Option randomOption = GetRandomOption(itemOption, option.Count, presets); - if (!RandomizeValues(item.Type, itemOption, item.Metadata.Option, ref randomOption)) { + if (!RandomizeValues(item, itemOption, ref randomOption)) { return false; } @@ -109,45 +109,92 @@ public bool UpdateRandomOption(ref Item item, params LockOption[] presets) { return true; } - // TODO: These should technically be weighted towards the lower end. - /// Item Type + /// Item /// Item's Random Option Metadata - /// Item Metadata Option /// /// Select the highest possible roll and circumvents the randomness - public bool RandomizeValues(in ItemType type, ItemOption itemOptionMetadata, ItemMetadataOption itemMetadataOption, ref ItemStats.Option option, bool rollMax = false) { - ItemEquipVariationTable? table = GetVariationTable(type); + public bool RandomizeValues(Item item, ItemOption itemOptionMetadata, ref ItemStats.Option option, bool rollMax = false) { + if (item.Metadata.Option == null) { + return false; + } + ItemEquipVariationTable? table = GetVariationTable(item.Type); if (table == null) { return false; } foreach (BasicAttribute attribute in option.Basic.Keys) { if (table.Values.TryGetValue(attribute, out ItemEquipVariationTable.Set[]? values)) { - int value = GetValue(itemMetadataOption, itemOptionMetadata, attribute, tableValues: values, rollMax: rollMax); + int value = GetValue(item, itemOptionMetadata, attribute, tableValues: values, rollMax: rollMax); option.Basic[attribute] = new BasicOption((int) (value * option.MultiplyFactor)); } else if (table.Rates.TryGetValue(attribute, out ItemEquipVariationTable.Set[]? rates)) { - int rateInt = GetValue(itemMetadataOption, itemOptionMetadata, attribute, tableRates: rates, rollMax: rollMax); + int rateInt = GetValue(item, itemOptionMetadata, attribute, tableRates: rates, rollMax: rollMax); option.Basic[attribute] = new BasicOption((rateInt / 1000f) * option.MultiplyFactor); } } foreach (SpecialAttribute attribute in option.Special.Keys) { if (table.SpecialValues.TryGetValue(attribute, out ItemEquipVariationTable.Set[]? values)) { - int value = GetValue(itemMetadataOption, itemOptionMetadata, specialAttribute: attribute, tableValues: values, rollMax: rollMax); + int value = GetValue(item, itemOptionMetadata, specialAttribute: attribute, tableValues: values, rollMax: rollMax); option.Special[attribute] = new SpecialOption(0f, value * option.MultiplyFactor); } else if (table.SpecialRates.TryGetValue(attribute, out ItemEquipVariationTable.Set[]? rates)) { - int rateInt = GetValue(itemMetadataOption, itemOptionMetadata, specialAttribute: attribute, tableRates: rates, rollMax: rollMax); + int rateInt = GetValue(item, itemOptionMetadata, specialAttribute: attribute, tableRates: rates, rollMax: rollMax); option.Special[attribute] = new SpecialOption((rateInt / 1000f) * option.MultiplyFactor); } } return true; - int GetValue(ItemMetadataOption itemMetadataOption, ItemOption itemOptionMetadata, BasicAttribute? attribute = null, SpecialAttribute? specialAttribute = null, ItemEquipVariationTable.Set[]? tableValues = null, ItemEquipVariationTable.Set[]? tableRates = null, bool rollMax = false) { - switch (itemMetadataOption.RandomType) { + int GetValue(Item item, ItemOption itemOptionMetadata, BasicAttribute? attribute = null, SpecialAttribute? specialAttribute = null, ItemEquipVariationTable.Set[]? tableValues = null, ItemEquipVariationTable.Set[]? tableRates = null, bool rollMax = false) { + var weightedValues = new WeightedSet(); + var weightedRates = new WeightedSet(); + if (item.Type.IsPet) { + switch (item.Rarity) { + case < 3: + if (rollMax) { + if (tableValues != null) { + return tableValues[4].Value; + } + if (tableRates != null) { + return (int) (tableRates[4].Value * 1000); + } + } + // only gets values from idx 0 to 4 + for (int i = 0; i < 5; i++) { + if (tableValues != null) { + weightedValues.Add(tableValues[i].Value, tableValues[i].Weight); + } else if (tableRates != null) { + weightedRates.Add(tableRates[i].Value, tableRates[i].Weight); + } + } + break; + default: + if (rollMax) { + if (tableValues != null) { + return tableValues[17].Value; + } + if (tableRates != null) { + return (int) (tableRates[17].Value * 1000); + } + } + // only gets values from idx 0 to 17 (entire array) + for (int i = 0; i < 18; i++) { + if (tableValues != null) { + weightedValues.Add(tableValues[i].Value, tableValues[i].Weight); + } else if (tableRates != null) { + weightedRates.Add(tableRates[i].Value, tableRates[i].Weight); + } + } + break; + } + if (tableValues != null) { + return weightedValues.Get(); + } + if (tableRates != null) { + return (int) (weightedRates.Get() * 1000); + } + } else { + switch (item.Metadata.Option!.RandomType) { case RandomMakeType.Range: - var weightedValues = new WeightedSet(); - var weightedRates = new WeightedSet(); - switch (itemMetadataOption.LevelFactor) { + switch (item.Metadata.Option.LevelFactor) { case < 50: if (rollMax) { if (tableValues != null) { @@ -228,6 +275,8 @@ int GetValue(ItemMetadataOption itemMetadataOption, ItemOption itemOptionMetadat } break; } + } + return 0; } } From b96eaf018f563f7b215f1191fb34582a21d90ec7 Mon Sep 17 00:00:00 2001 From: Zin <62830952+Zintixx@users.noreply.github.com> Date: Fri, 7 Feb 2025 21:08:55 -0800 Subject: [PATCH 6/6] formatting --- .../Util/ItemStatsCalculator.cs | 152 +++++++++--------- 1 file changed, 76 insertions(+), 76 deletions(-) diff --git a/Maple2.Server.Game/Util/ItemStatsCalculator.cs b/Maple2.Server.Game/Util/ItemStatsCalculator.cs index d048843f..059285a2 100644 --- a/Maple2.Server.Game/Util/ItemStatsCalculator.cs +++ b/Maple2.Server.Game/Util/ItemStatsCalculator.cs @@ -193,88 +193,88 @@ int GetValue(Item item, ItemOption itemOptionMetadata, BasicAttribute? attribute } } else { switch (item.Metadata.Option!.RandomType) { - case RandomMakeType.Range: - switch (item.Metadata.Option.LevelFactor) { - case < 50: - if (rollMax) { - if (tableValues != null) { - return tableValues[2].Value; + case RandomMakeType.Range: + switch (item.Metadata.Option.LevelFactor) { + case < 50: + if (rollMax) { + if (tableValues != null) { + return tableValues[2].Value; + } + if (tableRates != null) { + return (int) (tableRates[2].Value * 1000); + } } - if (tableRates != null) { - return (int) (tableRates[2].Value * 1000); + // only gets values from idx 0 to 2 + for (int i = 0; i < 3; i++) { + if (tableValues != null) { + weightedValues.Add(tableValues[i].Value, tableValues[i].Weight); + } else if (tableRates != null) { + weightedRates.Add(tableRates[i].Value, tableRates[i].Weight); + } } - } - // only gets values from idx 0 to 2 - for (int i = 0; i < 3; i++) { - if (tableValues != null) { - weightedValues.Add(tableValues[i].Value, tableValues[i].Weight); - } else if (tableRates != null) { - weightedRates.Add(tableRates[i].Value, tableRates[i].Weight); - } - } - break; - case < 70: - if (rollMax) { - if (tableValues != null) { - return tableValues[9].Value; - } - if (tableRates != null) { - return (int) (tableRates[9].Value * 1000); - } - } - // only gets values from idx 2 to 9 - for (int i = 2; i < 10; i++) { - if (tableValues != null) { - weightedValues.Add(tableValues[i].Value, tableValues[i].Weight); - } else if (tableRates != null) { - weightedRates.Add(tableRates[i].Value, tableRates[i].Weight); + break; + case < 70: + if (rollMax) { + if (tableValues != null) { + return tableValues[9].Value; + } + if (tableRates != null) { + return (int) (tableRates[9].Value * 1000); + } } - } - break; - case >= 70: - if (rollMax) { - if (tableValues != null) { - return tableValues[17].Value; + // only gets values from idx 2 to 9 + for (int i = 2; i < 10; i++) { + if (tableValues != null) { + weightedValues.Add(tableValues[i].Value, tableValues[i].Weight); + } else if (tableRates != null) { + weightedRates.Add(tableRates[i].Value, tableRates[i].Weight); + } } - if (tableRates != null) { - return (int) (tableRates[17].Value * 1000); + break; + case >= 70: + if (rollMax) { + if (tableValues != null) { + return tableValues[17].Value; + } + if (tableRates != null) { + return (int) (tableRates[17].Value * 1000); + } } - } - // only gets values from idx 10 to 17 - for (int i = 10; i < 18; i++) { - if (tableValues != null) { - weightedValues.Add(tableValues[i].Value, tableValues[i].Weight); - } else if (tableRates != null) { - weightedRates.Add(tableRates[i].Value, tableRates[i].Weight); + // only gets values from idx 10 to 17 + for (int i = 10; i < 18; i++) { + if (tableValues != null) { + weightedValues.Add(tableValues[i].Value, tableValues[i].Weight); + } else if (tableRates != null) { + weightedRates.Add(tableRates[i].Value, tableRates[i].Weight); + } } - } - break; - } - if (tableValues != null) { - return weightedValues.Get(); - } - if (tableRates != null) { - return (int) (weightedRates.Get() * 1000); - } - break; - case RandomMakeType.Base: - default: - float minRate = 0; - int minValue = 0; - if (attribute != null) { - ItemOption.Entry entry = itemOptionMetadata.Entries.FirstOrDefault(optionEntry => optionEntry.BasicAttribute == attribute); - minRate = entry.Rates?.Min ?? 0; - minValue = entry.Values?.Min ?? 0; - return GetItemVariationValue(basicAttribute: attribute, value: minValue, rate: minRate); - } - if (specialAttribute != null) { - ItemOption.Entry entry = itemOptionMetadata.Entries.FirstOrDefault(optionEntry => optionEntry.SpecialAttribute == specialAttribute); - minRate = entry.Rates?.Min ?? 0; - minValue = entry.Values?.Min ?? 0; - return GetItemVariationValue(specialAttribute: specialAttribute, value: minValue, rate: minRate); - } - break; - } + break; + } + if (tableValues != null) { + return weightedValues.Get(); + } + if (tableRates != null) { + return (int) (weightedRates.Get() * 1000); + } + break; + case RandomMakeType.Base: + default: + float minRate = 0; + int minValue = 0; + if (attribute != null) { + ItemOption.Entry entry = itemOptionMetadata.Entries.FirstOrDefault(optionEntry => optionEntry.BasicAttribute == attribute); + minRate = entry.Rates?.Min ?? 0; + minValue = entry.Values?.Min ?? 0; + return GetItemVariationValue(basicAttribute: attribute, value: minValue, rate: minRate); + } + if (specialAttribute != null) { + ItemOption.Entry entry = itemOptionMetadata.Entries.FirstOrDefault(optionEntry => optionEntry.SpecialAttribute == specialAttribute); + minRate = entry.Rates?.Min ?? 0; + minValue = entry.Values?.Min ?? 0; + return GetItemVariationValue(specialAttribute: specialAttribute, value: minValue, rate: minRate); + } + break; + } } return 0;