UNPKG

farming-weight

Version:

Tools for calculating farming weight and fortune in Hypixel Skyblock

176 lines 9.14 kB
import { FARMING_ENCHANTS } from '../../constants/enchants.js'; import { compareRarity, Rarity, REFORGES, ReforgeTarget } from '../../constants/reforges.js'; import { Skill } from '../../constants/skills.js'; import { Stat } from '../../constants/stats.js'; import { GemRarity } from '../../fortune/item.js'; import { getMaxStatFromEnchant, getOptimisticStatFromEnchant, getStatFromEnchant } from '../../util/enchants.js'; import { getPeridotFortune, getPeridotGemFortune } from '../../util/gems.js'; import { getUpgradeableEnchant } from '../enchantupgrades.js'; import { getCurrentReforgeEffectSummaries, getUpgradeableGems, getUpgradeableReforges } from '../upgrades.js'; export const GEAR_FORTUNE_SOURCES = [ { name: 'Base Stats', exists: (gear) => { return Object.keys((gear.getLastItemUpgrade() ?? gear)?.info?.baseStats ?? {}).length > 0; }, max: (gear) => { return (gear.getLastItemUpgrade() ?? gear)?.info?.baseStats?.[Stat.FarmingFortune] ?? 0; }, current: (gear) => { return gear.info.baseStats?.[Stat.FarmingFortune] ?? 0; }, maxStat: (gear, stat) => { return (gear.getLastItemUpgrade() ?? gear)?.info?.baseStats?.[stat] ?? 0; }, currentStat: (gear, stat) => { return gear.info.baseStats?.[stat] ?? 0; }, }, { name: 'Reforge Stats', exists: () => true, wiki: (gear) => { return gear.type === ReforgeTarget.Equipment ? REFORGES?.rooted?.wiki : REFORGES?.mossy?.wiki; }, max: (gear) => { const maxRarity = (gear.getLastItemUpgrade()?.info.maxRarity ?? gear.info.maxRarity); const current = gear.reforgeStats?.stats?.[Stat.FarmingFortune] ?? 0; const max = gear.type === ReforgeTarget.Equipment ? (REFORGES.rooted?.tiers[maxRarity]?.stats[Stat.FarmingFortune] ?? 0) : (REFORGES.mossy?.tiers[maxRarity]?.stats[Stat.FarmingFortune] ?? 0); // If an item is recombobulated beyond its base max rarity, keep max >= current. return Math.max(max, current); }, current: (gear) => { return gear.reforgeStats?.stats?.[Stat.FarmingFortune] ?? 0; }, maxStat: (gear, stat) => { const maxRarity = (gear.getLastItemUpgrade()?.info.maxRarity ?? gear.info.maxRarity); const current = gear.reforgeStats?.stats?.[stat] ?? 0; let best = 0; for (const reforge of Object.values(REFORGES)) { if (!reforge || !reforge.appliesTo.includes(gear.type)) continue; // Keep "max" aligned with what we can suggest/cost (stone-based). if (!reforge.stone?.id) continue; const tier = reforge.tiers?.[maxRarity]; const val = tier?.stats?.[stat] ?? 0; if (val > best) best = val; } return Math.max(best, current); }, currentStat: (gear, stat) => { return gear.reforgeStats?.stats?.[stat] ?? 0; }, effects: getCurrentReforgeEffectSummaries, upgrades: getUpgradeableReforges, }, { name: 'Gemstone Slots', wiki: () => 'https://w.elitesb.gg/Gemstone_Slot', exists: (upgradeable) => { const lastInfo = (upgradeable.getLastItemUpgrade() ?? upgradeable)?.info; const currentInfo = upgradeable.info; return (lastInfo?.gemSlots?.some((s) => s.slot_type === 'PERIDOT') === true || currentInfo?.gemSlots?.some((s) => s.slot_type === 'PERIDOT') === true); }, max: (upgradeable) => { const lastInfo = (upgradeable.getLastItemUpgrade() ?? upgradeable)?.info; const currentInfo = upgradeable.info; const maxRarity = (lastInfo?.maxRarity ?? currentInfo?.maxRarity ?? Rarity.Common); const rarity = (compareRarity(upgradeable.rarity, maxRarity) > 0 ? upgradeable.rarity : maxRarity); const peridotSlots = Math.max(lastInfo?.gemSlots?.filter((s) => s.slot_type === 'PERIDOT').length ?? 0, currentInfo?.gemSlots?.filter((s) => s.slot_type === 'PERIDOT').length ?? 0); return peridotSlots * getPeridotGemFortune(rarity, GemRarity.Perfect); }, current: (upgradeable) => { return getPeridotFortune(upgradeable.rarity, upgradeable.item); }, maxStat: (upgradeable, stat) => { if (stat !== Stat.FarmingFortune) return 0; const lastInfo = (upgradeable.getLastItemUpgrade() ?? upgradeable)?.info; const currentInfo = upgradeable.info; const maxRarity = (lastInfo?.maxRarity ?? currentInfo?.maxRarity ?? Rarity.Common); const rarity = (compareRarity(upgradeable.rarity, maxRarity) > 0 ? upgradeable.rarity : maxRarity); const peridotSlots = Math.max(lastInfo?.gemSlots?.filter((s) => s.slot_type === 'PERIDOT').length ?? 0, currentInfo?.gemSlots?.filter((s) => s.slot_type === 'PERIDOT').length ?? 0); return peridotSlots * getPeridotGemFortune(rarity, GemRarity.Perfect); }, currentStat: (upgradeable, stat) => { return stat === Stat.FarmingFortune ? getPeridotFortune(upgradeable.rarity, upgradeable.item) : 0; }, upgrades: getUpgradeableGems, }, { name: 'Visitors Served Bonus', wiki: (gear) => gear.info.wiki, exists: (gear) => gear.type === ReforgeTarget.Equipment && gear.info.family === 'LOTUS', max: (_gear) => 22.5, current: (gear) => { return gear.getPieceBonus(); }, maxStat: (_gear, stat) => (stat === Stat.FarmingFortune ? 22.5 : 0), currentStat: (gear, stat) => (stat === Stat.FarmingFortune ? gear.getPieceBonus() : 0), }, { name: 'Farming Level', wiki: (gear) => gear.info.wiki, exists: (gear) => gear.type === ReforgeTarget.Armor && gear.info.perLevelStats?.skill === Skill.Farming, max: (gear) => { const last = (gear.getLastItemUpgrade() ?? gear)?.info; return 'perLevelStats' in last && last.perLevelStats?.skill === Skill.Farming ? (last?.perLevelStats?.stats[Stat.FarmingFortune] ?? 0) * 60 : (gear.info?.perLevelStats?.stats[Stat.FarmingFortune] ?? 0) * 60; }, current: (gear) => { return (gear.info.perLevelStats?.stats[Stat.FarmingFortune] ?? 0) * (gear.options?.farmingLevel ?? 0); }, maxStat: (gear, stat) => { const last = (gear.getLastItemUpgrade() ?? gear)?.info; if (!('perLevelStats' in last) || last.perLevelStats?.skill !== Skill.Farming) return 0; return (last.perLevelStats?.stats?.[stat] ?? 0) * 60; }, currentStat: (gear, stat) => { return (gear.info.perLevelStats?.stats?.[stat] ?? 0) * (gear.options?.farmingLevel ?? 0); }, }, ...Object.entries(FARMING_ENCHANTS ?? {}) .filter(([, enchant]) => enchant.appliesTo.includes(ReforgeTarget.Armor) || enchant.appliesTo.includes(ReforgeTarget.Equipment)) .map(([id, enchant]) => ({ name: enchant.name, wiki: () => enchant.wiki, exists: (gear) => enchant.appliesTo.includes(gear.type), max: (gear) => { const currentOverbloom = getOptimisticStatFromEnchant(gear.item.enchantments?.[id] ?? 0, enchant, Stat.Overbloom, gear.options, gear.crop); return (getMaxStatFromEnchant(enchant, Stat.FarmingFortune, gear.options) || (currentOverbloom > 0 ? getMaxStatFromEnchant(enchant, Stat.Overbloom, gear.options, gear.crop) : 0)); }, current: (gear) => getStatFromEnchant(gear.item.enchantments?.[id] ?? 0, enchant, Stat.FarmingFortune, gear.options) || getOptimisticStatFromEnchant(gear.item.enchantments?.[id] ?? 0, enchant, Stat.Overbloom, gear.options, gear.crop), maxStat: (gear, stat) => getMaxStatFromEnchant(enchant, stat, gear.options, gear.crop), currentStat: (gear, stat) => getOptimisticStatFromEnchant(gear.item.enchantments?.[id] ?? 0, enchant, stat, gear.options, gear.crop), upgrades: (gear, stats) => { const chains = []; for (const s of stats ?? [Stat.FarmingFortune]) { if (!chains.includes(s)) chains.push(s); } if (chains.length === 0) chains.push(Stat.FarmingFortune); const upgrades = chains.flatMap((s) => getUpgradeableEnchant(gear, id, s)); const seen = new Set(); return upgrades.filter((u) => { const key = u.conflictKey ?? `${u.title}:${u.action}`; if (seen.has(key)) return false; seen.add(key); return true; }); }, })), ]; //# sourceMappingURL=gearsources.js.map