initial commit
This commit is contained in:
456
src/data/categories.json
Normal file
456
src/data/categories.json
Normal file
@@ -0,0 +1,456 @@
|
||||
[
|
||||
{
|
||||
"label": "Weapons",
|
||||
"children": [
|
||||
{
|
||||
"label": "Bow",
|
||||
"children": [
|
||||
"Bow",
|
||||
"Longbow",
|
||||
"Warbow",
|
||||
"Whispering Bow",
|
||||
"Wailing Bow",
|
||||
"Bow of Badon",
|
||||
"Mistpiercer",
|
||||
"Skystrider Bow"
|
||||
]
|
||||
},
|
||||
{
|
||||
"label": "Crossbow",
|
||||
"children": [
|
||||
"Crossbow",
|
||||
"Heavy Crossbow",
|
||||
"Light Crossbow",
|
||||
"Weeping Repeater",
|
||||
"Boltcasters",
|
||||
"Siegebow",
|
||||
"Energy Shaper",
|
||||
"Arclight Blasters"
|
||||
]
|
||||
},
|
||||
{
|
||||
"label": "Axe",
|
||||
"children": [
|
||||
"Battleaxe",
|
||||
"Greataxe",
|
||||
"Halberd",
|
||||
"Carrioncaller",
|
||||
"Infernal Scythe",
|
||||
"Bear Paws",
|
||||
"Realmbreaker",
|
||||
"Crystal Reaper"
|
||||
]
|
||||
},
|
||||
{
|
||||
"label": "Dagger",
|
||||
"children": [
|
||||
"Dagger",
|
||||
"Dagger Pair",
|
||||
"Claws",
|
||||
"Bloodletter",
|
||||
"Demon Fang",
|
||||
"Deathgivers",
|
||||
"Bridled Fury",
|
||||
"Twin Slayers"
|
||||
]
|
||||
},
|
||||
{
|
||||
"label": "Hammer",
|
||||
"children": [
|
||||
"Hammer",
|
||||
"Great Hammer",
|
||||
"Polehammer",
|
||||
"Tombhammer",
|
||||
"Forge Hammers",
|
||||
"Grovekeeper",
|
||||
"Hand of Justice",
|
||||
"Truebolt Hammer"
|
||||
]
|
||||
},
|
||||
{
|
||||
"label": "War Gloves",
|
||||
"children": [
|
||||
"Brawler Gloves",
|
||||
"Battle Bracers",
|
||||
"Spiked Gauntlets",
|
||||
"Ursine Maulers",
|
||||
"Hellfire Hands",
|
||||
"Ravenstrike Cestus",
|
||||
"Fists of Avalon",
|
||||
"Forcepulse Bracers"
|
||||
]
|
||||
},
|
||||
{
|
||||
"label": "Mace",
|
||||
"children": [
|
||||
"Mace",
|
||||
"Heavy Mace",
|
||||
"Morning Star",
|
||||
"Bedrock Mace",
|
||||
"Incubus Mace",
|
||||
"Camlann Mace",
|
||||
"Oathkeepers",
|
||||
"Dreadstorm Monarch"
|
||||
]
|
||||
},
|
||||
{
|
||||
"label": "Quarterstaff",
|
||||
"children": [
|
||||
"Quarterstaff",
|
||||
"Iron-clad Staff",
|
||||
"Double Bladed Staff",
|
||||
"Black Monk Stave",
|
||||
"Staff of Balance",
|
||||
"Grailseeker",
|
||||
"Phantom Twinblade"
|
||||
]
|
||||
},
|
||||
{
|
||||
"label": "Spear",
|
||||
"children": [
|
||||
"Spear",
|
||||
"Pike",
|
||||
"Glaive",
|
||||
"Heron Spear",
|
||||
"Spirithunter",
|
||||
"Trinity Spear",
|
||||
"Daybreaker",
|
||||
"Rift Glaive"
|
||||
]
|
||||
},
|
||||
{
|
||||
"label": "Sword",
|
||||
"children": [
|
||||
"Broadsword",
|
||||
"Claymore",
|
||||
"Dual Swords",
|
||||
"Clarent Blade",
|
||||
"Carving Sword",
|
||||
"Galatine Pair",
|
||||
"Kingmaker",
|
||||
"Infinity Blade"
|
||||
]
|
||||
},
|
||||
{
|
||||
"label": "Arcane Staff",
|
||||
"children": [
|
||||
"Arcane Staff",
|
||||
"Great Arcane Staff",
|
||||
"Enigmatic Staff",
|
||||
"Witchwork Staff",
|
||||
"Occult Staff",
|
||||
"Malevolent Locus",
|
||||
"Evensong",
|
||||
"Astral Staff"
|
||||
]
|
||||
},
|
||||
{
|
||||
"label": "Cursed Staff",
|
||||
"children": [
|
||||
"Cursed Staff",
|
||||
"Great Cursed Staff",
|
||||
"Demonic Staff",
|
||||
"Lifecurse Staff",
|
||||
"Cursed Skull",
|
||||
"Damnation Staff",
|
||||
"Shadowcaller",
|
||||
"Rotcaller Staff"
|
||||
]
|
||||
},
|
||||
{
|
||||
"label": "Fire Staff",
|
||||
"children": [
|
||||
"Fire Staff",
|
||||
"Great Fire Staff",
|
||||
"Infernal Staff",
|
||||
"Wildfire Staff",
|
||||
"Brimstone Staff",
|
||||
"Blazing Staff",
|
||||
"Dawnsong",
|
||||
"Flamewalker Staff"
|
||||
]
|
||||
},
|
||||
{
|
||||
"label": "Frost Staff",
|
||||
"children": [
|
||||
"Frost Staff",
|
||||
"Great Frost Staff",
|
||||
"Glacial Staff",
|
||||
"Hoarfrost Staff",
|
||||
"Icicle Staff",
|
||||
"Permafrost Prism",
|
||||
"Chillhowl",
|
||||
"Arctic Staff"
|
||||
]
|
||||
},
|
||||
{
|
||||
"label": "Holy Staff",
|
||||
"children": [
|
||||
"Holy Staff",
|
||||
"Great Holy Staff",
|
||||
"Divine Staff",
|
||||
"Lifetouch Staff",
|
||||
"Fallen Staff",
|
||||
"Redemption Staff",
|
||||
"Hallowfall",
|
||||
"Exalted Staff"
|
||||
]
|
||||
},
|
||||
{
|
||||
"label": "Nature Staff",
|
||||
"children": [
|
||||
"Nature Staff",
|
||||
"Great Nature Staff",
|
||||
"Wild Staff",
|
||||
"Druidic Staff",
|
||||
"Blight Staff",
|
||||
"Rampant Staff",
|
||||
"Ironroot Staff",
|
||||
"Forgebark Staff"
|
||||
]
|
||||
},
|
||||
{
|
||||
"label": "Shapeshifter",
|
||||
"children": [
|
||||
"Prowling Staff",
|
||||
"Rootbound Staff",
|
||||
"Primal Staff",
|
||||
"Bloodmoon Staff",
|
||||
"Hellspawn Staff",
|
||||
"Earthrune Staff",
|
||||
"Lightcaller",
|
||||
"Stillgaze Staff"
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"label": "Armor",
|
||||
"children": [
|
||||
{
|
||||
"label": "Head",
|
||||
"children": [
|
||||
{
|
||||
"label": "Plate",
|
||||
"children": [
|
||||
"Soldier Helmet",
|
||||
"Knight Helmet",
|
||||
"Guardian Helmet",
|
||||
"Graveguard Helmet",
|
||||
"Royal Helmet",
|
||||
"Demon Helmet",
|
||||
"Judicator Helmet",
|
||||
"Duskweaver Helmet",
|
||||
"Helmet of Valor"
|
||||
]
|
||||
},
|
||||
{
|
||||
"label": "Leather",
|
||||
"children": [
|
||||
"Mercenary Hood",
|
||||
"Hunter Hood",
|
||||
"Assassin Hood",
|
||||
"Stalker Hood",
|
||||
"Royal Hood",
|
||||
"Hellion Hood",
|
||||
"Specter Hood",
|
||||
"Mistwalker Hood",
|
||||
"Hood of Tenacity"
|
||||
]
|
||||
},
|
||||
{
|
||||
"label": "Cloth",
|
||||
"children": [
|
||||
"Scholar Cowl",
|
||||
"Cleric Cowl",
|
||||
"Mage Cowl",
|
||||
"Druid Cowl",
|
||||
"Royal Cowl",
|
||||
"Fiend Cowl",
|
||||
"Cultist Cowl",
|
||||
"Feyscale Cowl",
|
||||
"Cowl of Purity"
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"label": "Chest",
|
||||
"children": [
|
||||
{
|
||||
"label": "Plate",
|
||||
"children": [
|
||||
"Soldier Armor",
|
||||
"Knight Armor",
|
||||
"Guardian Armor",
|
||||
"Graveguard Armor",
|
||||
"Royal Armor",
|
||||
"Demon Armor",
|
||||
"Judicator Armor",
|
||||
"Duskweaver Armor",
|
||||
"Armor of Valor"
|
||||
]
|
||||
},
|
||||
{
|
||||
"label": "Leather",
|
||||
"children": [
|
||||
"Mercenary Jacket",
|
||||
"Hunter Jacket",
|
||||
"Assassin Jacket",
|
||||
"Stalker Jacket",
|
||||
"Royal Jacket",
|
||||
"Hellion Jacket",
|
||||
"Specter Jacket",
|
||||
"Mistwalker Jacket",
|
||||
"Jacket of Tenacity"
|
||||
]
|
||||
},
|
||||
{
|
||||
"label": "Cloth",
|
||||
"children": [
|
||||
"Scholar Robe",
|
||||
"Cleric Robe",
|
||||
"Mage Robe",
|
||||
"Druid Robe",
|
||||
"Royal Robe",
|
||||
"Fiend Robe",
|
||||
"Cultist Robe",
|
||||
"Feyscale Robe",
|
||||
"Robe of Purity"
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"label": "Boots",
|
||||
"children": [
|
||||
{
|
||||
"label": "Plate",
|
||||
"children": [
|
||||
"Soldier Boots",
|
||||
"Knight Boots",
|
||||
"Guardian Boots",
|
||||
"Graveguard Boots",
|
||||
"Royal Boots",
|
||||
"Demon Boots",
|
||||
"Judicator Boots",
|
||||
"Duskweaver Boots",
|
||||
"Boots of Valor"
|
||||
]
|
||||
},
|
||||
{
|
||||
"label": "Leather",
|
||||
"children": [
|
||||
"Mercenary Shoes",
|
||||
"Hunter Shoes",
|
||||
"Assassin Shoes",
|
||||
"Stalker Shoes",
|
||||
"Royal Shoes",
|
||||
"Hellion Shoes",
|
||||
"Specter Shoes",
|
||||
"Mistwalker Shoes",
|
||||
"Shoes of Tenacity"
|
||||
]
|
||||
},
|
||||
{
|
||||
"label": "Cloth",
|
||||
"children": [
|
||||
"Scholar Sandals",
|
||||
"Cleric Sandals",
|
||||
"Mage Sandals",
|
||||
"Druid Sandals",
|
||||
"Royal Sandals",
|
||||
"Fiend Sandals",
|
||||
"Cultist Sandals",
|
||||
"Feyscale Sandals",
|
||||
"Sandals of Purity"
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"label": "Off-hand",
|
||||
"children": [
|
||||
{
|
||||
"label": "Mage",
|
||||
"children": []
|
||||
},
|
||||
{
|
||||
"label": "Hunter",
|
||||
"children": []
|
||||
},
|
||||
{
|
||||
"label": "Warrior",
|
||||
"children": []
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"label": "Gathering Equipment",
|
||||
"children": [
|
||||
{
|
||||
"label": "Fishing",
|
||||
"children": [
|
||||
"Fishing Rods",
|
||||
"Garbs",
|
||||
"Caps",
|
||||
"Workboots",
|
||||
"Backpacks"
|
||||
]
|
||||
},
|
||||
{
|
||||
"label": "Fiber",
|
||||
"children": [
|
||||
"Sickle",
|
||||
"Garbs",
|
||||
"Caps",
|
||||
"Workboots",
|
||||
"Backpacks"
|
||||
]
|
||||
},
|
||||
{
|
||||
"label": "Hide",
|
||||
"children": [
|
||||
"Skinning Knife",
|
||||
"Garbs",
|
||||
"Caps",
|
||||
"Workboots",
|
||||
"Backpacks"
|
||||
]
|
||||
},
|
||||
{
|
||||
"label": "Ore",
|
||||
"children": [
|
||||
"Pickaxe",
|
||||
"Garbs",
|
||||
"Caps",
|
||||
"Workboots",
|
||||
"Backpacks"
|
||||
]
|
||||
},
|
||||
{
|
||||
"label": "Stone",
|
||||
"children": [
|
||||
"Hammer",
|
||||
"Garbs",
|
||||
"Caps",
|
||||
"Workboots",
|
||||
"Backpacks"
|
||||
]
|
||||
},
|
||||
{
|
||||
"label": "Wood",
|
||||
"children": [
|
||||
"Axes",
|
||||
"Garbs",
|
||||
"Caps",
|
||||
"Workboots",
|
||||
"Backpacks"
|
||||
]
|
||||
},
|
||||
"Tracking Toolkit"
|
||||
]
|
||||
}
|
||||
]
|
||||
24
src/data/constants.ts
Normal file
24
src/data/constants.ts
Normal file
@@ -0,0 +1,24 @@
|
||||
import type { AlbionCity, AlbionQuality } from '../types/api'
|
||||
import type { Tier, ItemCategory, Enchantment } from '../types/crafting'
|
||||
|
||||
export const CITIES: AlbionCity[] = [
|
||||
'Caerleon',
|
||||
'Bridgewatch',
|
||||
'Fort Sterling',
|
||||
'Lymhurst',
|
||||
'Martlock',
|
||||
'Thetford',
|
||||
'Black Market',
|
||||
]
|
||||
|
||||
export const QUALITIES: { label: string; value: AlbionQuality }[] = [
|
||||
{ label: 'Normal', value: 1 },
|
||||
{ label: 'Good', value: 2 },
|
||||
{ label: 'Outstanding', value: 3 },
|
||||
{ label: 'Excellent', value: 4 },
|
||||
{ label: 'Masterpiece', value: 5 },
|
||||
]
|
||||
|
||||
export const TIERS: Tier[] = [4, 5, 6, 7, 8]
|
||||
export const ENCHANTMENTS: Enchantment[] = [0, 1, 2, 3, 4]
|
||||
export const CATEGORIES: ItemCategory[] = ['Weapons', 'Armor', 'Gathering']
|
||||
29
src/data/itemTree.ts
Normal file
29
src/data/itemTree.ts
Normal file
@@ -0,0 +1,29 @@
|
||||
import rawCategories from './categories.json'
|
||||
|
||||
export interface TreeNode {
|
||||
label: string
|
||||
children?: TreeNode[]
|
||||
}
|
||||
|
||||
type RawNode = { label: string; children?: (RawNode | string)[] }
|
||||
|
||||
function normalize(raw: RawNode): TreeNode {
|
||||
if (!raw.children) return { label: raw.label }
|
||||
return {
|
||||
label: raw.label,
|
||||
children: raw.children.map(c => typeof c === 'string' ? { label: c } : normalize(c)),
|
||||
}
|
||||
}
|
||||
|
||||
export function getLeaves(node: TreeNode): string[] {
|
||||
if (!node.children) return [node.label]
|
||||
const result: string[] = []
|
||||
for (const child of node.children) {
|
||||
result.push(...getLeaves(child))
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
export const ITEM_TREE: TreeNode[] = (rawCategories as RawNode[]).map(normalize)
|
||||
|
||||
export const ALL_ITEM_NAMES: Set<string> = new Set(ITEM_TREE.flatMap(getLeaves))
|
||||
2287
src/data/recipes.json
Normal file
2287
src/data/recipes.json
Normal file
File diff suppressed because it is too large
Load Diff
80
src/data/recipes.ts
Normal file
80
src/data/recipes.ts
Normal file
@@ -0,0 +1,80 @@
|
||||
import type { CraftingRecipe, Tier, Enchantment, ItemCategory, JournalType } from '../types/crafting'
|
||||
import { ENCHANTMENTS } from './constants'
|
||||
import rawRecipes from './recipes.json'
|
||||
|
||||
// ─── Template types ───────────────────────────────────────────────────────────
|
||||
|
||||
interface IngredientTemplate {
|
||||
itemId: string
|
||||
qty: number | Record<string, number>
|
||||
noEnchant?: boolean
|
||||
}
|
||||
|
||||
interface RecipeTemplate {
|
||||
id: string
|
||||
displayName: string
|
||||
category: ItemCategory
|
||||
outputId: string
|
||||
enchanted?: boolean
|
||||
ingredients: IngredientTemplate[]
|
||||
}
|
||||
|
||||
const ALL_TIERS: Tier[] = [4, 5, 6, 7, 8]
|
||||
|
||||
// ─── Journal type inference ────────────────────────────────────────────────────
|
||||
|
||||
function inferJournalType(outputId: string): JournalType {
|
||||
if (outputId.includes('_TOOL_')) return 'toolmaker'
|
||||
if (/FIRESTAFF|INFERNOSTAFF|ARCANESTAFF|ENIGMATICSTAFF|CURSEDSTAFF|DEMONICSTAFF|FROSTSTAFF|GLACIALSTAFF|HOLYSTAFF|DIVINESTAFF|NATURESTAFF|WILDSTAFF|_CLOTH_|OFF_BOOK|ENIGMATICORB|RINGPAIR|SKULLORB|ICEGAUNTLETS|ICECRYSTAL/.test(outputId)) return 'mage'
|
||||
if (/BOW|_LEATHER_|MAIN_DAGGER|DAGGERPAIR|CLAWPAIR|OFF_TORCH|SHAPESHIFTER|RAPIER|DUALSICKLE|2H_DAGGER/.test(outputId)) return 'hunter'
|
||||
return 'warrior'
|
||||
}
|
||||
|
||||
// ─── Helpers ──────────────────────────────────────────────────────────────────
|
||||
|
||||
function applyTier(template: string, tier: number): string {
|
||||
return template
|
||||
.replace(/\{t-1\}/g, String(tier - 1))
|
||||
.replace(/\{t\}/g, String(tier))
|
||||
}
|
||||
|
||||
function resolveQty(qty: number | Record<string, number>, tier: number): number {
|
||||
if (typeof qty === 'number') return qty
|
||||
const val = qty[String(tier)]
|
||||
if (val === undefined) throw new Error(`No qty defined for tier ${tier}`)
|
||||
return val
|
||||
}
|
||||
|
||||
// ─── Build all recipes ────────────────────────────────────────────────────────
|
||||
|
||||
export const ALL_RECIPES: CraftingRecipe[] = []
|
||||
|
||||
for (const entry of rawRecipes) {
|
||||
if (!('outputId' in entry)) continue // skip comment-only entries
|
||||
const template = entry as unknown as RecipeTemplate
|
||||
|
||||
const enchants: Enchantment[] = template.enchanted === false ? [0] : ENCHANTMENTS
|
||||
|
||||
for (const tier of ALL_TIERS) {
|
||||
for (const enc of enchants) {
|
||||
const baseOutputId = applyTier(template.outputId, tier)
|
||||
const outputItemId = enc === 0 ? baseOutputId : `${baseOutputId}@${enc}`
|
||||
|
||||
const ingredients = template.ingredients.map(ing => {
|
||||
const baseId = applyTier(ing.itemId, tier)
|
||||
const itemId = (ing.noEnchant === true || enc === 0) ? baseId : `${baseId}_LEVEL${enc}`
|
||||
return { itemId, quantity: resolveQty(ing.qty, tier) }
|
||||
})
|
||||
|
||||
ALL_RECIPES.push({
|
||||
outputItemId,
|
||||
displayName: `T${tier}.${enc} ${template.displayName}`,
|
||||
tier,
|
||||
enchantment: enc,
|
||||
category: template.category,
|
||||
journalType: inferJournalType(template.outputId),
|
||||
ingredients,
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user