import { pickRandom } from '../util'; import { DefaultItems, Item, Items, formatItem, formatItems, formatItemsArray, getDefaultItem, getItemQuantity } from './items'; export interface CraftingStation { key: string, name: string, verb?: string, description: string, emoji: string, requires?: Item, // in seconds cooldown?: number, formatRecipe?: (inputs: Items[], requirements: Items[], outputs: Items[], disableBold?: boolean) => string, manipulateResults?: (outputs: Items[]) => Items[] } export function getStation(key: string) { return craftingStations.find(station => station.key === key); } export const defaultVerb = 'Crafted'; const rollBunch = (outputs: Items[]) => { const totalItems = outputs.reduce((a, b) => a + b.quantity, 0); // grab from 1/3 to the entire pool, ensure it never goes below 1 const rolledItems = Math.max(Math.round(totalItems/3 + Math.random() * totalItems*2/3), 1); const res: Items[] = []; for (let i = 0; i < rolledItems; i++) { const rolled = pickRandom(outputs); const r = res.find(r => r.item.id === rolled.item.id); if (r) { if (r.quantity === rolled.quantity) { // don't roll more than can be rolled i--; } else { r.quantity = r.quantity + 1; } } else { res.push({ item: rolled.item, quantity: 1 }); } } return res; }; const formatMaybeCountable = (inputs: Items[], requirements: Items[], outputs: Items[], disableBold = false) => `${inputs.length > 0 ? formatItemsArray(inputs, disableBold) : ''} ${requirements.length > 0 ? `w/ ${formatItemsArray(requirements, disableBold)}: ` : ''}${outputs.map(i => formatItems(i.item, i.quantity, disableBold) + '?').join(' ')}`; const formatMaybe = (inputs: Items[], requirements: Items[], outputs: Items[], disableBold = false) => `${inputs.length > 0 ? formatItemsArray(inputs, disableBold) : ''} ${requirements.length > 0 ? `w/ ${formatItemsArray(requirements, disableBold)} ` : ''}=> ${outputs.map(i => formatItem(i.item, disableBold) + '?').join(' ')}`; export const craftingStations: CraftingStation[] = [ { key: 'forage', name: 'Forage', verb: 'Foraged', description: 'Pick up various sticks and stones from the forest', emoji: '🌲', cooldown: 60 * 5, formatRecipe: formatMaybeCountable, manipulateResults: rollBunch }, { key: 'hand', name: 'Hand', verb: 'Made', description: 'You can use your hands to make a small assortment of things', emoji: '✋' }, { key: 'workbench', name: 'Workbench', description: 'A place for you to work with tools, for simple things', emoji: '🛠️', requires: getDefaultItem(DefaultItems.WORKBENCH) }, { key: 'fishing', name: 'Fishing', verb: 'Fished up', description: 'fish gaming wednesday', emoji: '🎣', cooldown: 60 * 60 * 2, requires: getDefaultItem(DefaultItems.FISHING_ROD), formatRecipe: formatMaybe, // weighted random manipulateResults: (outputs) => { const pool: Item[] = []; for (const out of outputs) { for (let i = 0; i < out.quantity; i++) { pool.push(out.item); } } return [{ item: pickRandom(pool), quantity: 1 }]; } }, { key: 'mining', name: 'Mining', verb: 'Mined', description: 'mine diamonds', emoji: '⛏️', cooldown: 60 * 30, requires: getDefaultItem(DefaultItems.MINESHAFT), formatRecipe: formatMaybeCountable, manipulateResults: rollBunch, }, { key: 'smelting', name: 'Smelting', verb: 'Smelt', description: 'Smelt ores, minerals, food, whatever you please', emoji: '🔥', cooldown: 30, requires: getDefaultItem(DefaultItems.FURNACE), }, ]; export async function canUseStation(user: string, station: CraftingStation) { if (!station.requires) return true; const inv = await getItemQuantity(user, station.requires.id); return inv.quantity > 0; } export function verb(station: CraftingStation) { return station.verb || defaultVerb; }