farming-weight
Version:
Tools for calculating farming weight and fortune in Hypixel Skyblock
206 lines • 7.73 kB
JavaScript
import { Crop } from '../constants/crops.js';
import { BONUS_WEIGHT, CROP_WEIGHT, TIER_12_MINIONS } from '../constants/weight.js';
import { calculateJacobContestMedal } from '../util/jacob.js';
import { uncountedCropsFromPests } from '../util/pests.js';
export function createFarmingWeightCalculator(info) {
return new FarmingWeight(info);
}
const crops = [
Crop.Cactus,
Crop.Carrot,
Crop.CocoaBeans,
Crop.Melon,
Crop.Mushroom,
Crop.NetherWart,
Crop.Potato,
Crop.Pumpkin,
Crop.SugarCane,
Crop.Wheat,
Crop.Sunflower,
Crop.Moonflower,
Crop.WildRose,
];
class FarmingWeight {
info;
constructor(info) {
this.info = info;
this.collection = {};
this.levelCapUpgrade = info?.levelCapUpgrade ?? 0;
this.anitaBonusFarmingFortuneLevel = info?.anitaBonusFarmingFortuneLevel ?? 0;
this.farmingXp = info?.farmingXp ?? 0;
this.earnedMedals = { diamond: 0, platinum: 0, gold: 0 };
this.tier12MinionCount = 0;
this.bonusSources = {};
this.uncountedCrops = {};
this.setContests(info?.contests ?? []);
this.calcUncountedCrops(info?.pests ?? {});
this.setCropsFromCollections(info?.collection ?? {});
this.addMinions(info?.minions ?? []);
}
/**
* Expects a dictionary of collections and amounts with the default Hypixel SkyBlock IDs
* @param {Record<string, number>} collections
* @returns {FarmingWeight}
*/
setCropsFromCollections(collections) {
for (const crop of crops) {
this.collection[crop] = collections[crop] ?? 0;
}
this.getCropWeights();
return this;
}
setCrop = (crop, collection) => {
this.collection[crop] = collection;
this.getCropWeights();
return this;
};
setLevelCap = (levelCap) => {
this.levelCapUpgrade = levelCap;
return this;
};
setFarmingXp = (farmingXp) => {
this.farmingXp = farmingXp;
return this;
};
setAnitaBonusLevel = (anitaBonusFarmingFortuneLevel) => {
this.anitaBonusFarmingFortuneLevel = anitaBonusFarmingFortuneLevel;
return this;
};
addMinions = (minions) => {
for (const minion of minions) {
if (!minion.endsWith('_12'))
continue;
if (!TIER_12_MINIONS.includes(minion))
continue;
this.tier12MinionCount++;
}
return this;
};
setEarnedMedals = ({ diamond, platinum, gold }) => {
this.earnedMedals = {
diamond: diamond ?? this.earnedMedals.diamond,
platinum: platinum ?? this.earnedMedals.platinum,
gold: gold ?? this.earnedMedals.gold,
};
return this;
};
setTier12MinionCount = (count) => {
this.tier12MinionCount = count;
return this;
};
setContests = (contests) => {
if (!contests?.length)
return this;
for (const contest of contests) {
const medal = calculateJacobContestMedal(contest);
if (!medal)
continue;
if (medal === 'diamond') {
this.earnedMedals.diamond++;
}
else if (medal === 'platinum') {
this.earnedMedals.platinum++;
}
else if (medal === 'gold') {
this.earnedMedals.gold++;
}
}
this.getBonusWeights();
return this;
};
getWeightInfo = () => {
const bonus = this.getBonusWeights();
const crops = this.getCropWeights();
const bonusTotal = Object.values(bonus).reduce((a, b) => a + b, 0);
const cropTotal = Object.values(crops).reduce((a, b) => a + b, 0);
return {
totalWeight: bonusTotal + cropTotal,
bonusWeight: bonusTotal,
cropWeight: cropTotal,
bonusSources: bonus,
uncountedCrops: this.uncountedCrops,
};
};
getBonusWeights = () => {
this.bonusSources = {};
if (this.farmingXp >= 111_672_425 && this.levelCapUpgrade >= 10) {
// Farming 60 bonus
this.bonusSources['Farming 60'] = BONUS_WEIGHT.Farming60Bonus;
}
else if (this.farmingXp >= 55_172_425) {
// Farming 50 bonus
this.bonusSources['Farming 50'] = BONUS_WEIGHT.Farming50Bonus;
}
// Tier 12 minion bonus
if (this.tier12MinionCount > 0) {
this.bonusSources['Tier 12 Minions'] = this.tier12MinionCount * BONUS_WEIGHT.MinionRewardWeight;
}
// Anita bonus
if (this.anitaBonusFarmingFortuneLevel > 0) {
this.bonusSources['Anita Bonus'] =
this.anitaBonusFarmingFortuneLevel * BONUS_WEIGHT.AnitaBuffBonusMultiplier;
}
const maxMedals = BONUS_WEIGHT.MaxMedalsCounted;
if (this.earnedMedals.diamond >= maxMedals) {
this.bonusSources['Contest Medals'] = BONUS_WEIGHT.WeightPerDiamondMedal * BONUS_WEIGHT.MaxMedalsCounted;
}
else {
const diamond = this.earnedMedals.diamond;
const platinum = Math.min(maxMedals - diamond, this.earnedMedals.platinum);
const gold = Math.min(maxMedals - diamond - platinum, this.earnedMedals.gold);
const medals = diamond * BONUS_WEIGHT.WeightPerDiamondMedal +
platinum * BONUS_WEIGHT.WeightPerPlatinumMedal +
gold * BONUS_WEIGHT.WeightPerGoldMedal;
this.bonusSources['Contest Medals'] = medals;
}
return this.bonusSources;
};
getCropWeights = () => {
const cropWeight = {};
let totalWeight = 0;
let doubleBreakWeight = 0;
for (const crop of crops) {
let collected = this.collection[crop] ?? 0;
// Subtract uncounted crops
if (this.uncountedCrops[crop]) {
collected = Math.max(0, collected - (this.uncountedCrops[crop] ?? 0));
}
const weight = collected / CROP_WEIGHT[crop];
totalWeight += weight;
if (crop === Crop.Cactus || crop === Crop.SugarCane) {
doubleBreakWeight += weight;
}
cropWeight[crop] = weight;
}
// Mushroom is a special case, it needs to be calculated dynamically based on the
// ratio between the farmed crops that give two mushrooms per break with cow pet
// and the farmed crops that give one mushroom per break with cow pet
const mushroomCollection = this.collection[Crop.Mushroom] ?? 0;
const mushroomWeightNumber = CROP_WEIGHT[Crop.Mushroom];
const doubleBreakRatio = doubleBreakWeight / totalWeight;
const normalCropRatio = (totalWeight - doubleBreakWeight) / totalWeight;
const mushroomWeight = doubleBreakRatio * (mushroomCollection / (mushroomWeightNumber * 2)) +
normalCropRatio * (mushroomCollection / mushroomWeightNumber);
cropWeight[Crop.Mushroom] = mushroomWeight;
return cropWeight;
};
calcUncountedCrops = (bestiary) => {
this.uncountedCrops = uncountedCropsFromPests(bestiary);
this.getCropWeights();
return this;
};
getCropWeight = (crop) => {
CROP_WEIGHT[crop];
};
}
/**
* Get the weight of a single crop based on the collection amount.
* Use `createFarmingWeightCalculator` to calculate accurate weight of multiple crops
* @param {Crop} crop
* @param {number} collection
* @returns {number}
*/
export function calcWeightForCrop(crop, collection) {
return collection / CROP_WEIGHT[crop];
}
//# sourceMappingURL=weightcalc.js.map