Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
28 changes: 19 additions & 9 deletions Maple2.Server.Game/Util/ItemStatsCalculator.cs
Original file line number Diff line number Diff line change
Expand Up @@ -517,28 +517,39 @@ private static ItemStats.Option RandomItemOption(ItemOption option, in ItemType
// Ensures that there are enough options to choose.
total = Math.Min(total, option.Entries.Length);

// Create a mutable list of entries
List<ItemOption.Entry> availableEntries = option.Entries.ToList();

// Compute locked options first.
foreach (LockOption preset in presets) {
if (preset.TryGet(out BasicAttribute basic, out bool _)) {
ItemOption.Entry entry = option.Entries.FirstOrDefault(e => e.BasicAttribute == basic);
// Ignore any invalid presets, they will get populated with valid data below.
AddResult(entry, statResult, specialResult);
availableEntries.Remove(entry);
} else if (preset.TryGet(out SpecialAttribute special, out bool _)) {
ItemOption.Entry entry = option.Entries.FirstOrDefault(e => e.SpecialAttribute == special);
// Ignore any invalid presets, they will get populated with valid data below.
AddResult(entry, statResult, specialResult);
availableEntries.Remove(entry);
Comment thread
AngeloTadeucci marked this conversation as resolved.
}
}

while (statResult.Count + specialResult.Count < total) {
ItemOption.Entry entry = option.Entries.Random();
while (statResult.Count + specialResult.Count < total && availableEntries.Count > 0) {
ItemOption.Entry entry = availableEntries.Random();
if (statsType == ItemStats.Type.Random &&
!IsValidStat(itemType, total, statResult, specialResult, entry)) {
availableEntries.Remove(entry);
continue;
}
if (!AddResult(entry, statResult, specialResult)) {
Log.Error("Failed to select random item option: {Entry}", entry); // Invalid entry
Log.Logger.Error("Failed to select random item option: {Entry}", entry); // Invalid entry
}
availableEntries.Remove(entry);
}

if (availableEntries.Count == 0) {
Log.Logger.Error("Failed to select random item option, no more entries available. ItemType: {ItemType}, StatsType: {StatsType}, Total: {Total}", itemType, statsType, total);
}

return new ItemStats.Option(statResult, specialResult, multiplyFactor: option.MultiplyFactor);
Expand Down Expand Up @@ -588,15 +599,14 @@ private static bool IsValidStat(ItemType itemType, int statLineCount, IDictionar
return damageTypeStatCount < 1;
}

if (itemType is { IsCombatPet: false, IsWeapon: false, IsAccessory: false }) {
bool isBaseOffense = entry.BasicAttribute != null && offenseBasicAttributes.Contains((BasicAttribute) entry.BasicAttribute);
bool isSpecialOffense = entry.SpecialAttribute != null && offenseSpecialAttributes.Contains((SpecialAttribute) entry.SpecialAttribute);
if (itemType is { IsCombatPet: false, IsWeapon: false, IsAccessory: false } && (isBaseOffense || isSpecialOffense)) {
int offenseStatCount = statDict.Keys.Count(stat => offenseBasicAttributes.Contains(stat));
offenseStatCount += specialDict.Keys.Count(stat => offenseSpecialAttributes.Contains(stat));

if (entry.BasicAttribute != null && offenseBasicAttributes.Contains((BasicAttribute) entry.BasicAttribute)) {
offenseStatCount++;
} else if (entry.SpecialAttribute != null && offenseSpecialAttributes.Contains((SpecialAttribute) entry.SpecialAttribute)) {
offenseStatCount++;
}
// Simulate the addition of the new stat
offenseStatCount++;

return (float) offenseStatCount / statLineCount <= OFFENSE_LINE_MAX_THRESHOLD;
}
Expand Down