farming-weight
Version:
Tools for calculating farming weight and fortune in Hypixel Skyblock
285 lines • 11.1 kB
JavaScript
import { FARMING_ATTRIBUTE_SHARDS, getAttributeAmount, getShardLevel } from '../../constants/attributes.js';
import { Crop } from '../../constants/crops.js';
import { Rarity } from '../../constants/reforges.js';
import { Stat } from '../../constants/stats.js';
import { FortuneSource } from './base.js';
import { statsToEffects } from './effects-util.js';
const ATTRIBUTE_SHARDS_STAT_SOURCE = 'Attribute Shards';
export class CropeetleShard extends FortuneSource {
id = 'cropeetle';
name = FARMING_ATTRIBUTE_SHARDS.crop_bug?.name ?? 'Cropeetle Shard';
getEffects(player, _env) {
const level = getShardLevel(Rarity.Rare, getAttributeAmount(player.options.attributes, 'crop_bug'));
if (level <= 0)
return [];
return statsToEffects({ [Stat.Overbloom]: level }, this.name);
}
}
/**
* Warty Bug Shard - adds Warty drops while farming Nether Wart.
*
* Emits an `add-drop` effect crop-scoped to Nether Wart. Drops are tagged
* `['overbloom','rare-crop']` so Overbloom (and any future global rare-crop
* multipliers) buff them by default. The drop kind is `'rare'`.
*/
export class WartyBugShard extends FortuneSource {
id = 'wart_eater';
name = FARMING_ATTRIBUTE_SHARDS.wart_eater?.name ?? 'Warty Bug Shard';
getEffects(player, env) {
if (env.crop !== Crop.NetherWart)
return [];
const level = getShardLevel(Rarity.Legendary, getAttributeAmount(player.options.attributes, 'wart_eater'));
if (level <= 0)
return [];
const chance = 0.00005 * level;
return [
{
source: this.name,
op: 'add-drop',
scope: { crops: [Crop.NetherWart] },
drop: {
itemId: 'WARTY',
chance,
dropKind: 'rare',
tags: ['overbloom', 'rare-crop'],
},
meta: { description: `${(chance * 100).toFixed(3)}% chance per block to drop Warty` },
},
];
}
}
/**
* Dragonfly Shard - `+0.5` Farming Wisdom per level. Always active.
*/
export class DragonflyShard extends FortuneSource {
id = 'dragonfly';
name = FARMING_ATTRIBUTE_SHARDS.garden_wisdom?.name ?? 'Dragonfly Shard';
getEffects(player, _env) {
const level = getShardLevel(Rarity.Epic, getAttributeAmount(player.options.attributes, 'garden_wisdom'));
if (level <= 0)
return [];
return [{ source: ATTRIBUTE_SHARDS_STAT_SOURCE, op: 'add-stat', stat: Stat.FarmingWisdom, value: 0.5 * level }];
}
}
/**
* Firefly Shard - `+5` Farming Fortune per level during the day.
*
* Active rules (preserved from the existing implementation, which assumes the
* world is during the day unless overridden):
* - If the player has selected Sunflower, force active.
* - If the player has selected Moonflower, force inactive.
* - If Lunar Moth shard is at an equal-or-higher level, defer to it (inactive).
* - Otherwise active.
*/
export class FireflyShard extends FortuneSource {
id = 'firefly';
name = FARMING_ATTRIBUTE_SHARDS.solar_power?.name ?? 'Firefly Shard';
resolve(player, env) {
const fireflyAmount = getAttributeAmount(player.options.attributes, 'solar_power');
const lunarAmount = getAttributeAmount(player.options.attributes, 'lunar_power');
const fireflyLevel = getShardLevel(Rarity.Epic, fireflyAmount);
const lunarLevel = getShardLevel(Rarity.Epic, lunarAmount);
return { fireflyLevel, lunarLevel, env };
}
getActive(player, env) {
const { fireflyLevel, lunarLevel } = this.resolve(player, env);
if (env.selectedCrop === Crop.Sunflower) {
return { active: true, reason: 'Forced active by selected Sunflower.' };
}
if (env.selectedCrop === Crop.Moonflower) {
return {
active: false,
reason: 'Disabled by selected Moonflower (Lunar Moth used instead).',
fortune: 5 * lunarLevel,
};
}
if (lunarLevel >= fireflyLevel) {
return {
active: false,
reason: 'Lunar Moth shard is at a higher or equal level, using it instead.',
fortune: 5 * lunarLevel,
};
}
return { active: true, reason: 'Active during the day.' };
}
getEffects(player, env) {
const { fireflyLevel } = this.resolve(player, env);
if (fireflyLevel <= 0)
return [];
const state = this.getActive(player, env);
if (!state.active)
return [];
return [
{
source: ATTRIBUTE_SHARDS_STAT_SOURCE,
op: 'add-stat',
stat: Stat.FarmingFortune,
value: 5 * fireflyLevel,
},
];
}
}
/**
* Lunar Moth Shard - `+5` Farming Fortune per level during the night.
*
* Active rules mirror Firefly (Moonflower forces active, Sunflower forces
* inactive, otherwise the higher-level shard wins ties going to Lunar Moth).
*/
export class LunarMothShard extends FortuneSource {
id = 'lunar_moth';
name = FARMING_ATTRIBUTE_SHARDS.lunar_power?.name ?? 'Lunar Moth Shard';
resolve(player) {
const fireflyAmount = getAttributeAmount(player.options.attributes, 'solar_power');
const lunarAmount = getAttributeAmount(player.options.attributes, 'lunar_power');
const fireflyLevel = getShardLevel(Rarity.Epic, fireflyAmount);
const lunarLevel = getShardLevel(Rarity.Epic, lunarAmount);
return { fireflyLevel, lunarLevel };
}
getActive(player, env) {
const { fireflyLevel, lunarLevel } = this.resolve(player);
if (env.selectedCrop === Crop.Moonflower) {
return { active: true, reason: 'Forced active by selected Moonflower.' };
}
if (env.selectedCrop === Crop.Sunflower) {
return {
active: false,
reason: 'Disabled by selected Sunflower (Firefly used instead).',
fortune: 5 * fireflyLevel,
};
}
if (fireflyLevel > lunarLevel) {
return {
active: false,
reason: 'Firefly shard is at a higher level, using it instead.',
fortune: 5 * fireflyLevel,
};
}
return { active: true, reason: 'Active during the night.' };
}
getEffects(player, env) {
const { lunarLevel } = this.resolve(player);
if (lunarLevel <= 0)
return [];
const state = this.getActive(player, env);
if (!state.active)
return [];
return [
{ source: ATTRIBUTE_SHARDS_STAT_SOURCE, op: 'add-stat', stat: Stat.FarmingFortune, value: 5 * lunarLevel },
];
}
}
/**
* Termite Shard - `+3` Farming Fortune per level while on an infested plot.
*/
export class TermiteShard extends FortuneSource {
id = 'termite';
name = FARMING_ATTRIBUTE_SHARDS.infiltration?.name ?? 'Termite Shard';
getActive(player, env) {
const level = getShardLevel(Rarity.Uncommon, getAttributeAmount(player.options.attributes, 'infiltration'));
if (!env.infestedPlot) {
return {
active: false,
reason: 'Termite shard is only active on infested plots.',
fortune: 3 * level,
};
}
return { active: true, reason: 'Active on infested plots.' };
}
getEffects(player, env) {
if (!env.infestedPlot)
return [];
const level = getShardLevel(Rarity.Uncommon, getAttributeAmount(player.options.attributes, 'infiltration'));
if (level <= 0)
return [];
return [{ source: ATTRIBUTE_SHARDS_STAT_SOURCE, op: 'add-stat', stat: Stat.FarmingFortune, value: 3 * level }];
}
}
/**
* Galaxy Fish Shard - `+1` Farming/Mining/Foraging Fortune per level.
*/
export class GalaxyFishShard extends FortuneSource {
id = 'galaxy_fish';
name = FARMING_ATTRIBUTE_SHARDS.ultimate_dna?.name ?? 'Galaxy Fish Shard';
getEffects(player, _env) {
const level = getShardLevel(Rarity.Legendary, getAttributeAmount(player.options.attributes, 'ultimate_dna'));
if (level <= 0)
return [];
const out = [
{ source: ATTRIBUTE_SHARDS_STAT_SOURCE, op: 'add-stat', stat: Stat.FarmingFortune, value: 1 * level },
{ source: ATTRIBUTE_SHARDS_STAT_SOURCE, op: 'add-stat', stat: Stat.MiningFortune, value: 1 * level },
{ source: ATTRIBUTE_SHARDS_STAT_SOURCE, op: 'add-stat', stat: Stat.ForagingFortune, value: 1 * level },
];
return out;
}
}
export class LadybugShard extends FortuneSource {
id = 'ladybug';
name = FARMING_ATTRIBUTE_SHARDS.pretty_clothes?.name ?? 'Ladybug Shard';
getEffects(_player, _env) {
return [];
}
}
export class InvisibugShard extends FortuneSource {
id = 'invisibug';
name = FARMING_ATTRIBUTE_SHARDS.fancy_visit?.name ?? 'Invisibug Shard';
getEffects(_player, _env) {
return [];
}
}
export class PrayingMantisShard extends FortuneSource {
id = 'praying_mantis';
name = FARMING_ATTRIBUTE_SHARDS.insect_power?.name ?? 'Praying Mantis Shard';
getEffects(_player, _env) {
return [];
}
}
export class PestShard extends FortuneSource {
id = 'pest';
name = FARMING_ATTRIBUTE_SHARDS.pest_luck?.name ?? 'Pest Shard';
getEffects(player, _env) {
const level = getShardLevel(Rarity.Uncommon, getAttributeAmount(player.options.attributes, 'pest_luck'));
if (level <= 0)
return [];
return [
{
source: this.name,
op: 'add-rare-pct',
value: level * 2,
scope: { tags: ['pest'] },
relatedStats: [Stat.Overbloom],
meta: {
description: 'Pest Overbloom',
valueDisplay: 'stat',
valueStat: Stat.Overbloom,
},
},
];
}
}
export class MudwormShard extends FortuneSource {
id = 'mudworm';
name = FARMING_ATTRIBUTE_SHARDS.visitor_bait?.name ?? 'Mudworm Shard';
getEffects(_player, _env) {
return [];
}
}
/**
* Class registry of every farming attribute shard, keyed by the SkyBlock
* attribute key (matching `FARMING_ATTRIBUTE_SHARDS`). Use this to enumerate
* sources during effect collection.
*/
export const FARMING_ATTRIBUTE_SHARD_CLASSES = {
wart_eater: new WartyBugShard(),
garden_wisdom: new DragonflyShard(),
solar_power: new FireflyShard(),
lunar_power: new LunarMothShard(),
pretty_clothes: new LadybugShard(),
crop_bug: new CropeetleShard(),
fancy_visit: new InvisibugShard(),
infiltration: new TermiteShard(),
insect_power: new PrayingMantisShard(),
pest_luck: new PestShard(),
visitor_bait: new MudwormShard(),
ultimate_dna: new GalaxyFishShard(),
};
//# sourceMappingURL=attributes.js.map