UNPKG

skyhelper-networth

Version:

SkyHelper's Networth Calculation for Hypixel SkyBlock

203 lines (171 loc) 7.47 kB
const { getHypixelItemInformationFromId } = require('../../constants/itemsMap'); const { NON_COSMETIC_ITEMS } = require('../../constants/misc'); const { ValidationError } = require('../../helper/errors'); const { titleCase } = require('../../helper/functions'); /** * Base class for calculating the networth of an item */ class SkyBlockItemNetworthHelper { /** * Creates a new SkyBlockItemNetworthHelper * @param {object} itemData The item data containing properties like `tag` and `Count`. */ constructor(itemData) { this.itemData = itemData; // Validate the item this.#validateItem(); // Extract item properties this.itemName = this.itemData.tag.display.Name.replace(/§[0-9a-fk-or]/gi, '').replace(/%%[^%]+%%/g, ''); this.extraAttributes = this.itemData.tag.ExtraAttributes ?? {}; this.itemId = this.extraAttributes.id; this.skyblockItem = getHypixelItemInformationFromId(this.itemId) ?? {}; this.itemLore = this.itemData.tag.display.Lore ?? []; this.count = this.itemData.Count ?? 1; this.baseItemId = this.itemId; // Initialize calculation properties this.nonCosmetic = false; this.calculation = []; this.basePrice = 0; this.price = 0; this.soulboundPortion = 0; } /** * Validates that the item data is correct */ #validateItem() { if (!this.itemData || typeof this.itemData !== 'object') { throw new ValidationError('Item must be an object'); } if (this.itemData?.tag?.display?.Name === undefined) { throw new ValidationError('Invalid item provided'); } } /** * Gets the item id based on the item's properties * @param {object} prices A prices object generated from the getPrices function * @returns {string} The item id */ getItemId(prices) { // If the item has a skin if (this.extraAttributes.skin && !this.nonCosmetic) { const itemId = `${this.itemId}_SKINNED_${this.extraAttributes.skin}`; if (prices[itemId] && prices[itemId] > prices[this.itemId]) { return itemId; } } // If the item is a sloth party hat if (this.itemId === 'PARTY_HAT_SLOTH' && this.extraAttributes.party_hat_emoji) { const itemId = `${this.itemId}_${this.extraAttributes.party_hat_emoji.toUpperCase()}`; if (prices[itemId]) { return itemId; } } // If the item is a rune if ((this.isUniqueRune() || this.isRune()) && !this.nonCosmetic) { const [runeType, runeTier] = Object.entries(this.extraAttributes.runes)[0]; return `RUNE_${runeType}_${runeTier}`.toUpperCase(); } // If the item is a new year cake if (this.itemId === 'NEW_YEAR_CAKE') { return `NEW_YEAR_CAKE_${this.extraAttributes.new_years_cake}`; } // If the item is a crab party hat if (['PARTY_HAT_CRAB', 'PARTY_HAT_CRAB_ANIMATED', 'BALLOON_HAT_2024', 'BALLOON_HAT_2025'].includes(this.itemId) && this.extraAttributes.party_hat_color) { return `${this.itemId}_${this.extraAttributes.party_hat_color.toUpperCase()}`; } // If the item is a space helmet if (this.itemId === 'DCTR_SPACE_HELM' && this.extraAttributes.edition !== undefined) { return 'DCTR_SPACE_HELM_EDITIONED'; } // If the item is a creative mind if (this.itemId === 'CREATIVE_MIND' && !this.extraAttributes.edition) { return 'CREATIVE_MIND_UNEDITIONED'; } // If the item is an ancient elevator if (this.itemId === 'ANCIENT_ELEVATOR' && this.extraAttributes.edition !== undefined) { return 'ANCIENT_ELEVATOR_EDITIONED'; } // If the item is the shiny variant if (this.extraAttributes.is_shiny && prices[`${this.itemId}_SHINY`]) { return `${this.itemId}_SHINY`; } // If the item is fragged if (this.itemId?.startsWith('STARRED_') && !prices[this.itemId] && prices[this.itemId.replace('STARRED_', '')]) { return this.itemId.replace('STARRED_', ''); } // Otherwise, return the item id return this.itemId; } /** * Gets the item name based on the item's properties * @returns {string} The item name */ getItemName() { if (['Beastmaster Crest', 'Griffin Upgrade Stone', 'Wisp Upgrade Stone'].includes(this.itemName)) { const tier = this.skyblockItem.tier ? titleCase(this.skyblockItem.tier.replaceAll('_', ' ')) : 'Unknown'; return `${this.itemName} (${tier})`; } if (this.itemName.endsWith(' Exp Boost')) { const itemId = this.skyblockItem.id ? titleCase(this.skyblockItem.id.split('_').at(-1)) : 'Unknown'; return `${this.itemName} (${itemId})`; } return this.itemName; } /** * Checks if the item is a rune * @returns {boolean} Whether the item is a rune */ isRune() { const isRuneId = this.itemId === 'RUNE'; const hasRuneType = this.extraAttributes.runes && Object.keys(this.extraAttributes.runes).length > 0; return isRuneId && hasRuneType; } /** * Checks if the item is an unique rune * @returns {boolean} Whether the item is an unqiue rune */ isUniqueRune() { const isRuneId = this.itemId === 'UNIQUE_RUNE'; const hasRuneType = this.extraAttributes.runes && Object.keys(this.extraAttributes.runes).length > 0; return isRuneId && hasRuneType; } /** * Checks if the item is cosmetic * @returns {boolean} Whether the item is cosmetic */ isCosmetic() { const testId = (this.itemId + this.itemName).toUpperCase(); const isSkinOrDye = testId.includes('DYE') || testId.includes('SKIN'); const isCosmetic = this.skyblockItem.category === 'COSMETIC' || this.itemLore.at(-1)?.includes('COSMETIC'); const isMemento = this.skyblockItem.category === 'MEMENTO'; const isOnCosmeticBlacklist = NON_COSMETIC_ITEMS.has(this.baseItemId); return isCosmetic || isSkinOrDye || isMemento || isOnCosmeticBlacklist || this.isRune() || this.isUniqueRune(); } /** * Checks if the item is recombobulated * @returns {boolean} Whether the item is recombobulated */ isRecombobulated() { return this.extraAttributes.rarity_upgrades > 0 && !this.extraAttributes.item_tier; } /** * Checks if the item is soulbound * @returns {boolean} Whether the item is soulbound */ isSoulbound() { return !!(this.extraAttributes.donated_museum || this.itemLore.includes('§8§l* §8Co-op Soulbound §8§l*') || this.itemLore.includes('§8§l* §8Soulbound §8§l*')); } /** * Sets the base price for the item * @param {object} prices A prices object generated from the getPrices function */ getBasePrice(prices) { // Get the item id and name this.itemName = this.getItemName(); this.itemId = this.getItemId(prices); // Get the base price for the item const itemPrice = prices[this.itemId] ?? 0; this.basePrice = itemPrice * (this.itemData.Count ?? 1); } } module.exports = SkyBlockItemNetworthHelper;