UNPKG

farming-weight

Version:

Tools for calculating farming weight and fortune in Hypixel Skyblock

210 lines (209 loc) 6.69 kB
'use strict'; Object.defineProperty(exports, '__esModule', { value: true }); exports.FarmingArmor = exports.ArmorSet = void 0; const ARMOR_1 = require('../constants/armor'); const ENCHANTS_1 = require('../constants/enchants'); const REFORGES_1 = require('../constants/reforges'); const SKILLS_1 = require('../constants/skills'); const SPECIALCROPS_1 = require('../constants/specialcrops'); const SPECIAL_1 = require('../crops/special'); const GEMS_1 = require('../util/gems'); const ITEMSTATS_1 = require('../util/itemstats'); class ArmorSet { get armor() { return [this.helmet ?? null, this.chestplate ?? null, this.leggings ?? null, this.boots ?? null]; } constructor(armor) { armor.sort((a, b) => b.potential - a.potential); this.pieces = armor; this.helmet = armor.find((a) => a.slot === ARMOR_1.GearSlot.Helmet); this.chestplate = armor.find((a) => a.slot === ARMOR_1.GearSlot.Chestplate); this.leggings = armor.find((a) => a.slot === ARMOR_1.GearSlot.Leggings); this.boots = armor.find((a) => a.slot === ARMOR_1.GearSlot.Boots); this.recalculateFamilies(); } getPiece(slot) { switch (slot) { case ARMOR_1.GearSlot.Helmet: return this.helmet; case ARMOR_1.GearSlot.Chestplate: return this.chestplate; case ARMOR_1.GearSlot.Leggings: return this.leggings; case ARMOR_1.GearSlot.Boots: return this.boots; default: return undefined; } } setPiece(armor) { switch (armor.slot) { case ARMOR_1.GearSlot.Helmet: this.helmet = armor; break; case ARMOR_1.GearSlot.Chestplate: this.chestplate = armor; break; case ARMOR_1.GearSlot.Leggings: this.leggings = armor; break; case ARMOR_1.GearSlot.Boots: this.boots = armor; break; default: return; } this.recalculateFamilies(); } recalculateFamilies() { const FAMILIES = new Map(); const ARMOR = this.armor.filter((a) => a); this.setBonuses = []; for (const PIECE of ARMOR) { if (!PIECE.armor.family) continue; FAMILIES.set(PIECE.armor.family, (FAMILIES.get(PIECE.armor.family) ?? 0) + 1); } for (const [FAMILY, COUNT] of FAMILIES.entries()) { if (COUNT < 2) continue; const BONUS = ARMOR_1.ARMOR_SET_BONUS[FAMILY]; if (!BONUS) continue; this.setBonuses.push({ count: COUNT, from: ARMOR.filter((a) => a.armor.family === FAMILY).map((a) => a.slot), bonus: BONUS, special: BONUS.special, }); } this.getFortuneBreakdown(); } getFortuneBreakdown(reloadFamilies = false) { if (reloadFamilies) { this.recalculateFamilies(); } let SUM = 0; const BREAKDOWN = {}; for (const PIECE of this.armor) { if (!PIECE) continue; const FORTUNE = PIECE.fortune; if (FORTUNE > 0) { BREAKDOWN[PIECE.item.name ?? ''] = FORTUNE; SUM += FORTUNE; } } for (const { bonus, count } of this.setBonuses) { if (count < 2 || count > 4) continue; const FORTUNE = bonus.stats?.[count]?.[REFORGES_1.Stat.FarmingFortune] ?? 0; if (FORTUNE > 0) { BREAKDOWN[bonus.name] = FORTUNE; SUM += FORTUNE; } } this.fortune = SUM; return BREAKDOWN; } specialDropsCalc(blocksBroken, crop) { const SPECIAL = SPECIALCROPS_1.MATCHING_SPECIAL_CROP[crop]; const APPLICABLE_BONUSES = this.setBonuses.filter((b) => b.special?.includes(SPECIAL)); if (APPLICABLE_BONUSES.length === 0) return null; // Armor set counts need to be combined for special crops // There will only be 2 applicable bonuses at most when Fermento armor plus // a lower tier armor is used. Hypixel appeats to count these as the same // set bonus instead of rolling them separately. let COUNT = 0; for (const BONUS of APPLICABLE_BONUSES) { COUNT += BONUS.count; } return (0, SPECIAL_1.calculateAverageSpecialCrops)(blocksBroken, crop, COUNT); } } exports.ArmorSet = ArmorSet; class FarmingArmor { get slot() { return this.armor.slot; } get potential() { if (!this.armor.family) { return this.fortune; } // Add the set bonus potential to the fortune return ( this.fortune + (ARMOR_1.ARMOR_SET_BONUS[this.armor.family]?.piecePotential?.[REFORGES_1.Stat.FarmingFortune] ?? 0) ); } constructor(item, options) { this.options = options; this.item = item; const ARMOR = ARMOR_1.ARMOR_INFO[item.skyblockId]; if (!ARMOR) { throw new Error(`Unknown farming armor: ${item.name} (${item.skyblockId})`); } this.armor = ARMOR; if (item.lore) { this.rarity = (0, ITEMSTATS_1.getRarityFromLore)(item.lore); } this.reforge = REFORGES_1.REFORGES[item.attributes?.modifier ?? ''] ?? undefined; this.reforgeStats = this.reforge?.tiers?.[this.rarity]; this.recombobulated = this.item.attributes?.rarity_upgrades === '1'; this.sumFortune(); } setOptions(options) { this.options = options; this.fortune = this.sumFortune(); } sumFortune() { this.fortuneBreakdown = {}; let SUM = 0; // Base fortune const BASE = this.armor.stats?.[REFORGES_1.Stat.FarmingFortune] ?? 0; if (BASE > 0) { this.fortuneBreakdown['Base Stats'] = BASE; SUM += BASE; } // Per farming level stats like Rancher's Boots if (this.armor.perLevelStats?.skill === SKILLS_1.Skill.Farming && this.options?.farmingLevel) { const PER_LEVEL = this.armor.perLevelStats?.stats[REFORGES_1.Stat.FarmingFortune] ?? 0; if (PER_LEVEL > 0) { this.fortuneBreakdown['Farming Level'] = PER_LEVEL * this.options.farmingLevel; SUM += PER_LEVEL * this.options.farmingLevel; } } // Reforge stats const REFORGE = this.reforgeStats?.stats?.[REFORGES_1.Stat.FarmingFortune] ?? 0; if (REFORGE > 0) { this.fortuneBreakdown[this.reforge?.name ?? 'Reforge'] = REFORGE; SUM += REFORGE; } // Gems const PERIDOT = (0, GEMS_1.getPeridotFortune)(this.rarity, this.item); if (PERIDOT > 0) { this.fortuneBreakdown['Peridot Gems'] = PERIDOT; SUM += PERIDOT; } // Enchantments const ENCHANTMENTS = Object.entries(this.item.enchantments ?? {}); for (const [ENCHANT, LEVEL] of ENCHANTMENTS) { if (!LEVEL) continue; const ENCHANTMENT = ENCHANTS_1.FARMING_ARMOR_ENCHANTS[ENCHANT]; if (!ENCHANTMENT || !LEVEL) continue; const FORTUNE = ENCHANTMENT.levels?.[LEVEL]?.[REFORGES_1.Stat.FarmingFortune] ?? 0; if (FORTUNE > 0) { this.fortuneBreakdown[ENCHANTMENT.name] = FORTUNE; SUM += FORTUNE; } } this.fortune = SUM; return SUM; } static isValid(item) { return ARMOR_1.ARMOR_INFO[item.skyblockId] !== undefined; } static fromArray(items, options) { return items .filter((item) => FarmingArmor.isValid(item)) .map((item) => new FarmingArmor(item, options)) .sort((a, b) => b.fortune - a.fortune); } } exports.FarmingArmor = FarmingArmor; //# sourceMappingURL=farmingarmor.js.map