UNPKG

farming-weight

Version:

Tools for calculating farming weight and fortune in Hypixel Skyblock

184 lines 7.51 kB
import { CROP_INFO, Crop, MAX_CROP_FORTUNE } from '../constants/crops.js'; import { REFORGES, Rarity } from '../constants/reforges.js'; import { Stat } from '../constants/stats.js'; import { calculateMelonPerkBonus } from '../crops/melon.js'; import { calculatePumpkinPerkBonus } from '../crops/pumpkin.js'; import { calculateAverageSpecialCrops } from '../crops/special.js'; import { BEST_FARMING_TOOLS } from '../items/tools.js'; const crops = [ Crop.Cactus, Crop.Carrot, Crop.CocoaBeans, Crop.Melon, Crop.Mushroom, Crop.NetherWart, Crop.Potato, Crop.Pumpkin, Crop.SugarCane, Crop.Wheat, Crop.Seeds, ]; export function calculateAverageDrops(options) { const result = {}; for (const crop of crops) { result[crop] = calculateExpectedDrops({ crop: crop, ...options, }); } return result; } export function calculateDetailedAverageDrops(options) { const result = {}; for (const crop of crops) { result[crop] = calculateDetailedDrops({ crop: crop, ...options, }); } const wheat = result[Crop.Wheat]; const seeds = result[Crop.Seeds]; // Combine seeds into wheat const seedCollection = seeds.collection - options.blocksBroken; wheat.otherCollection['Seeds'] = seedCollection; wheat.coinSources['Seeds'] = seedCollection * CROP_INFO[Crop.Seeds].npc; if (options.bountiful) { wheat.coinSources['Bountiful (Seeds)'] = seeds.coinSources['Bountiful'] ?? 0; } wheat.npcCoins = Object.values(wheat.coinSources).reduce((a, b) => a + b, 0); // Count mooshroom mushrooms as normal mushroom collection if (options.mooshroom) { const mushroom = result[Crop.Mushroom]; const mooshroom = mushroom.otherCollection['Mushroom'] ?? 0; mushroom.collection += mooshroom; mushroom.otherCollection['Mooshroom'] = mooshroom; delete mushroom.otherCollection['Mushroom']; } return result; } export function calculateExpectedDrops(options) { const { farmingFortune, blocksBroken, crop } = options; const fortune = farmingFortune ?? MAX_CROP_FORTUNE[crop] ?? 0; if (fortune <= 0 || blocksBroken < 0) return 0; const { drops } = getCropInfo(crop); if (!drops) return 0; const baseDrops = blocksBroken * drops * ((fortune + 100) * 0.01); switch (crop) { case Crop.Cactus: case Crop.Wheat: case Crop.Mushroom: case Crop.SugarCane: return Math.round(baseDrops); case Crop.Carrot: case Crop.CocoaBeans: case Crop.NetherWart: case Crop.Potato: case Crop.Seeds: return Math.round(baseDrops - blocksBroken); // Replenish takes away one drop per block broken case Crop.Pumpkin: return Math.round(baseDrops + calculatePumpkinPerkBonus(blocksBroken, options.dicerLevel)); case Crop.Melon: return Math.round(baseDrops + calculateMelonPerkBonus(blocksBroken, options.dicerLevel)); default: return 0; } } export function calculateDetailedDrops(options) { const result = { collection: 0, npcCoins: 0, fortune: 0, coinSources: {}, otherCollection: {}, }; const { farmingFortune, blocksBroken, crop, bountiful, armorPieces = 4 } = options; result.fortune = farmingFortune ?? MAX_CROP_FORTUNE[crop] ?? 0; let fortune = result.fortune + 100; if (fortune <= 0 || blocksBroken < 0) return result; if (!bountiful && !farmingFortune) { // Add the difference in farming fortune if the user has blessed instead of bountiful const maxRarity = BEST_FARMING_TOOLS[crop]?.maxRarity ?? Rarity.Mythic; const bountifulFortune = REFORGES.bountiful?.tiers[maxRarity]?.stats?.[Stat.FarmingFortune] ?? 0; const blessedFortune = REFORGES.blessed?.tiers[maxRarity]?.stats?.[Stat.FarmingFortune] ?? 0; fortune += blessedFortune - bountifulFortune; } const { drops, npc, breaks = 1, replenish = false } = getCropInfo(crop); if (!drops) return result; const baseDrops = blocksBroken * drops * (fortune * 0.01); result.otherCollection['Normal'] = Math.round(baseDrops); // Coin sources if (bountiful) { result.coinSources['Bountiful'] = Math.round(baseDrops * 0.2); } if (options.mooshroom) { const mushroomDrops = Math.round(blocksBroken * breaks); result.coinSources['Mooshroom'] = mushroomDrops * CROP_INFO[Crop.Mushroom].npc; result.otherCollection['Mushroom'] = mushroomDrops; } const specialCrops = calculateAverageSpecialCrops(blocksBroken, crop, armorPieces); result.otherCollection[specialCrops.type] = Math.round(specialCrops.amount); result.coinSources[specialCrops.type] = Math.round(specialCrops.npc); let extraDrops = 0; switch (crop) { case Crop.Pumpkin: extraDrops = Math.round(calculatePumpkinPerkBonus(blocksBroken, options.dicerLevel)); result.coinSources['Dicer RNG'] = Math.round(extraDrops * npc); result.coinSources['Collection'] = Math.round(baseDrops * npc); result.otherCollection['RNG Pumpkin'] = Math.round(extraDrops); result.collection = Math.round(baseDrops + extraDrops); break; case Crop.Melon: extraDrops = Math.round(calculateMelonPerkBonus(blocksBroken, options.dicerLevel)); result.coinSources['Dicer RNG'] = Math.round(extraDrops * npc); result.coinSources['Collection'] = Math.round(baseDrops * npc); result.otherCollection['RNG Melon'] = Math.round(extraDrops); result.collection = Math.round(baseDrops + extraDrops); break; default: if (replenish) { // Replenish takes away one drop per block broken result.coinSources['Collection'] = Math.round((baseDrops - blocksBroken * breaks) * npc); result.otherCollection['Replenish'] = -Math.round(blocksBroken * breaks); result.collection = Math.round(baseDrops); break; } result.coinSources['Collection'] = Math.round(baseDrops * npc); result.collection = Math.round(baseDrops); break; } result.npcCoins = Object.values(result.coinSources).reduce((a, b) => a + b, 0); return result; } export function getFortuneRequiredForCollection(options) { const { blocksBroken, crop, useDicers, useMooshroom } = options; let { collection } = options; const { drops } = getCropInfo(options.crop); if (useDicers) switch (crop) { case Crop.Pumpkin: collection -= calculatePumpkinPerkBonus(blocksBroken); break; case Crop.Melon: collection -= calculateMelonPerkBonus(blocksBroken); break; } if (useMooshroom && crop === Crop.Mushroom) { collection -= blocksBroken; // "* breaks" not needed because it's always 1 for mushroom } const fortune = (collection * 100) / (drops * blocksBroken) - 100; return Math.ceil(fortune); } export function getNPCProfitFromCrops(crop, amount) { const { npc } = getCropInfo(crop); if (!npc) return 0; return npc * amount; } export function getCropInfo(crop) { return CROP_INFO[crop] ?? {}; } //# sourceMappingURL=ratecalc.js.map