import type { AlbionCity } from '../types/api' // Source: Albion Online Wiki — Production Bonuses // Formula: RRR% = (1 - 1 / (1 + LPB/100)) × 100 // // Royal cities base LPB: 18% → RRR ≈ 15.3% // Specialization bonus: +15% → total 33% LPB → RRR ≈ 24.8% // Black Market (not a crafting location): 0% LPB → RRR = 0% const BASE_ROYAL_LPB = 18 const SPECIALIZATION_BONUS = 15 export const FOCUS_LPB = 59 // flat bonus added when using focus const ROYAL_CITIES = new Set([ 'Fort Sterling', 'Lymhurst', 'Bridgewatch', 'Martlock', 'Thetford', 'Caerleon', ]) // Each regex matches all output item IDs that receive the +15% specialization bonus // in that city, including artifact / avalon / crystal variants. const SPECIALIZATION_PATTERNS: Partial> = { 'Fort Sterling': /_MAIN_HAMMER|_2H_HAMMER|_2H_POLEHAMMER|_2H_DUALHAMMER|_2H_RAM_|_MAIN_SPEAR|_2H_SPEAR|_2H_GLAIVE|_2H_HARPOON|_2H_TRIDENT|_HOLYSTAFF|_DIVINESTAFF|_HEAD_PLATE_|_ARMOR_CLOTH_/, 'Lymhurst': /_MAIN_SWORD|_2H_CLAYMORE|_2H_DUALSWORD|_SCIMITAR|_2H_CLEAVER|_2H_BOW|_LONGBOW|_WARBOW|_ARCANESTAFF|_ENIGMATICSTAFF|_ENIGMATICORB|_ARCANE_RINGPAIR|_HEAD_LEATHER_|_SHOES_LEATHER_/, 'Bridgewatch': /_CROSSBOW|_1HCROSSBOW|_DAGGER|_CLAWPAIR|_RAPIER|_DUALSICKLE|_CURSEDSTAFF|_DEMONICSTAFF|_SKULLORB|_ARMOR_PLATE_|_SHOES_CLOTH_/, 'Martlock': /_MAIN_AXE|_2H_AXE|_2H_HALBERD|_2H_SCYTHE|_2H_DUALAXE|_QUARTERSTAFF|_IRONCLADEDSTAFF|_DOUBLEBLADEDSTAFF|_COMBATSTAFF|_TWINSCYTHE|_ROCKSTAFF|_FROSTSTAFF|_GLACIALSTAFF|_ICEGAUNTLETS|_ICECRYSTAL|_SHOES_PLATE_|_OFF_/, 'Thetford': /_MAIN_MACE|_2H_MACE|_2H_FLAIL|_ROCKMACE|_2H_DUALMACE|_NATURESTAFF|_WILDSTAFF|_FIRESTAFF|_INFERNOSTAFF|_FIRE_RINGPAIR|_ARMOR_LEATHER_|_HEAD_CLOTH_/, 'Caerleon': /_2H_KNUCKLES|_SHAPESHIFTER|_2H_TOOL_/, } // Returns the Local Production Bonus (%) for crafting this item in the given city. export function localProductionBonus(city: AlbionCity, outputItemId: string): number { if (!ROYAL_CITIES.has(city)) return 0 // Black Market: no bonus const pattern = SPECIALIZATION_PATTERNS[city] const baseId = outputItemId.replace(/@\d$/, '') // strip enchantment suffix const isSpecialized = pattern ? pattern.test(baseId) : false return BASE_ROYAL_LPB + (isSpecialized ? SPECIALIZATION_BONUS : 0) } // Converts a Local Production Bonus (%) to the resulting Resource Return Rate (%). // Formula: RRR = 1 - 1/(1 + LPB/100) export function rrrFromBonus(lpb: number): number { if (lpb === 0) return 0 return (1 - 1 / (1 + lpb / 100)) * 100 } // Returns the effective RRR (%) for crafting this item in the given city. export function cityRrr(city: AlbionCity, outputItemId: string): number { return rrrFromBonus(localProductionBonus(city, outputItemId)) } // Returns true for ingredients that are NOT subject to RRR (artefacts, ALCHEMY_RARE). // Only basic resources (bars, planks, leather, cloth) are returned by the city bonus. export function isRrrExempt(itemId: string): boolean { return itemId.includes('_ARTEFACT_') || itemId.includes('_ALCHEMY_RARE_') }