add local production bonuses
This commit is contained in:
55
src/data/cityBonuses.ts
Normal file
55
src/data/cityBonuses.ts
Normal file
@@ -0,0 +1,55 @@
|
||||
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
|
||||
|
||||
const ROYAL_CITIES = new Set<AlbionCity>([
|
||||
'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<Record<AlbionCity, RegExp>> = {
|
||||
'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_')
|
||||
}
|
||||
Reference in New Issue
Block a user