Initial commit — Jianghu Chronicles: Road of the Wandering Blade
Original open-world wuxia browser RPG: - Graphical 48px tile world (12 locations) with walkable character, NPC interaction, action spots, roaming enemies, travel portals - Tactical 10x7 grid battles: shapes, statuses, internals, 30+ techniques incl. tier-V ultimates & support arts across 6 weapon types - Full equipment: weapon/head/body/feet/2 accessories, 5 tiers, smithing - 6-chapter main story + side jobs board + bounty hunts + tournament - Crafting (smith/alchemy), fishing minigame, gambling, pickpocketing - Companions with chemistry passives, affection, romance, sects - Achievements, monster codex, day/night cycle, endings - 25-test headless smoke suite; no-cache static server included
This commit is contained in:
@@ -0,0 +1,339 @@
|
||||
'use strict';
|
||||
/* ============================================================
|
||||
DATA: NPCs, world map, quests, origins, recipes, tournament
|
||||
All names & lore are original fiction.
|
||||
============================================================ */
|
||||
|
||||
/* ---------------- NPCs ---------------- */
|
||||
const NPCS = {};
|
||||
function defNpc(id, o) { o.id = id; NPCS[id] = o; }
|
||||
|
||||
defNpc('n_elderchen', { name: 'Elder Chen', title: 'Village Elder', loc: 'l_village', gender: 'm', hue: '#c9b28a', char: '陈', role: 'Keeps the peace and worries about everyone', dlg: 'd_elder', giftTags: ['kind'] });
|
||||
defNpc('n_innkeeper_ma', { name: 'Innkeeper Ma', title: 'Willow Creek Inn', loc: 'l_village', gender: 'f', hue: '#b58f7a', char: '马', role: 'Hot beds, hotter congee', dlg: 'd_inn_ma', inn: 8, giftTags: ['kind'] });
|
||||
defNpc('n_kid_xiaoli', { name: 'Xiaoli', title: 'Village Kid', loc: 'l_village', gender: 'f', hue: '#d4b84e', char: '李', role: 'Knows every rumor worth half a candy', dlg: 'd_kid', giftTags: ['youth', 'kind'] });
|
||||
defNpc('n_merchant_su', { name: 'Merchant Su', title: 'Su & Sons Trading', loc: 'l_city', gender: 'm', hue: '#8fae6f', char: '苏', role: 'General goods, fair prices, better gossip', dlg: 'd_su', shop: { name: 'General Goods', stock: ['c_bun', 'c_herb_green', 'c_herb_red', 'ar_body_1', 'ar_body_2', 'ar_head_1', 'ar_foot_1', 'ar_foot_2', 'w_sword_1', 'w_blade_1', 'w_spear_1', 'w_staff_1', 'w_fist_1', 'w_hidden_1', 'gift_tea', 'gift_cakes', 'ac_jade'] }, giftTags: ['noble'] });
|
||||
defNpc('n_innkeeper_zhou', { name: 'Innkeeper Zhou', title: 'Golden Carp Inn', loc: 'l_city', gender: 'm', hue: '#caa25f', char: '周', role: 'Runs the finest inn between two mountains', dlg: 'd_inn_zhou', inn: 14, giftTags: ['drinker'] });
|
||||
defNpc('n_captain_yan', { name: 'Captain Yan', title: 'Garrison Liaison Office', loc: 'l_city', gender: 'f', hue: '#7d93ad', char: '燕', role: 'Sharp uniform, sharper tongue', dlg: 'd_yan', giftTags: ['scholar'] });
|
||||
defNpc('n_arena_qian', { name: 'Host Qian', title: 'Martial Tournament Grounds', loc: 'l_city', gender: 'm', hue: '#c07a52', char: '钱', role: 'Announcer, bookie, friend of heroes', dlg: 'd_qian', giftTags: ['noble'] });
|
||||
defNpc('n_beggar_hong', { name: 'Hong the Beggar', title: 'Wherever the wine is', loc: 'l_city', gender: 'm', hue: '#9c8f76', char: '洪', role: 'Drunk, ridiculous, occasionally terrifying', dlg: 'd_hong', spar: true, hiddenNpc: true, giftTags: ['drinker', 'kind'] });
|
||||
defNpc('n_smith_wang', { name: 'Smith Wang', title: 'Ember Forge', loc: 'l_town', gender: 'm', hue: '#a5643f', char: '王', role: 'Forges blades and opinions equally hot', dlg: 'd_wang', smith: true, shop: { name: 'Forge Goods', stock: ['w_sword_2', 'w_blade_2', 'w_spear_2', 'w_staff_2', 'w_fist_2', 'w_hidden_2', 'ar_body_2', 'ar_body_3', 'ar_head_2', 'ar_foot_2', 'ar_foot_3', 'ac_bracer', 'mat_ore_1'] }, giftTags: ['fighter'] });
|
||||
defNpc('n_alchemist_bai', { name: 'Alchemist Bai', title: 'Bai\u2019s Remedies', loc: 'l_town', gender: 'f', hue: '#9dbb74', char: '白', role: 'If it can be brewed, she has brewed it', dlg: 'd_bai', alchemy: true, shop: { name: 'Remedies', stock: ['c_pill_hp', 'c_pill_mp', 'c_antidote', 'c_herb_red', 'c_lotus', 'gift_tea'] }, giftTags: ['scholar'] });
|
||||
defNpc('n_innkeeper_lu', { name: 'Innkeeper Lu', title: 'Ember Lodge', loc: 'l_town', gender: 'f', hue: '#bd9a6a', char: '卢', role: 'Feeds smiths, miners, and occasional heroes', dlg: 'd_inn_lu', inn: 10, giftTags: ['kind'] });
|
||||
defNpc('n_hunter_ren', { name: 'Hunter Ren', title: 'Bamboo Edge Cabin', loc: 'l_bamboo', gender: 'm', hue: '#7f9663', char: '任', role: 'Traps wolves, trades pelts, mistrusts cities', dlg: 'd_ren', spar: true, teach: [{ tech: 't_blade_1', aff: 25, cost: 0, note: 'free for trusted friends' }], giftTags: ['fighter', 'drinker'] });
|
||||
defNpc('n_tiehu', { name: 'Zhao Tiehu', title: 'Dockside Challenger', loc: 'l_dock', gender: 'm', hue: '#bf7d4f', char: '赵', role: 'Undefeated arm-wrestler of Peach Blossom Dock', dlg: 'd_tiehu', spar: true, companion: { wt: 'fist', techs: ['t_fist_1', 't_fist_2'], internal: 'i_water', hpM: 1.25, atkM: 0.95, defM: 1.15 }, giftTags: ['fighter', 'drinker'] });
|
||||
defNpc('n_ferryman', { name: 'Old Gao the Ferryman', title: 'Peach Blossom Dock', loc: 'l_dock', gender: 'm', hue: '#8d9aa5', char: '高', role: 'Rows at night to a shore not on maps', dlg: 'd_ferry', giftTags: ['drinker'] });
|
||||
defNpc('n_abbot_lian', { name: 'Abbot Lian', title: 'Pure Lotus Temple', loc: 'l_temple', gender: 'm', hue: '#c8b46a', char: '莲', role: 'Sweeps leaves, teaches sutras, sees everything', dlg: 'd_abbot',
|
||||
teach: [
|
||||
{ tech: 't_staff_2', aff: 20, cost: 300 },
|
||||
{ tech: 't_staff_3', aff: 55, cost: 900, reqRep: ['temple', 20] },
|
||||
{ internal: 'i_vajra', aff: 40, cost: 500 },
|
||||
{ internal: 'i_sun', aff: 90, cost: 2000, reqFlag: 'sunHint' }
|
||||
], giftTags: ['monk', 'scholar'] });
|
||||
defNpc('n_monk_jing', { name: 'Monk Jing', title: 'Pure Lotus Temple', loc: 'l_temple', gender: 'm', hue: '#a8a06b', char: '静', role: 'Training-yard partner with infinite patience', dlg: 'd_jing', spar: true, giftTags: ['monk'] });
|
||||
defNpc('n_master_yun', { name: 'Master Yun', title: 'Azure Cloud Sect', loc: 'l_sect', gender: 'f', hue: '#7d9bb8', char: '云', role: 'First Blade of Azure Cloud Peak', dlg: 'd_yun',
|
||||
teach: [
|
||||
{ tech: 't_sword_2', aff: 20, cost: 300 },
|
||||
{ tech: 't_sword_3', aff: 55, cost: 900, reqRep: ['azure', 20] },
|
||||
{ internal: 'i_azure', aff: 40, cost: 500 }
|
||||
], giftTags: ['scholar'] });
|
||||
defNpc('n_lin', { name: 'Lin Wan\u2019er', title: 'Azure Cloud Disciple', loc: 'l_sect', gender: 'f', hue: '#b8797d', char: '林', role: 'Sword prodigy, chronic winner, terrible loser', dlg: 'd_lin', spar: true, romanceable: true,
|
||||
companion: { wt: 'sword', techs: ['t_sword_1', 't_sword_2'], internal: 'i_water', hpM: 1.0, atkM: 1.1, defM: 0.95 }, giftTags: ['fighter', 'romance'] });
|
||||
defNpc('n_lady_miao', { name: 'Lady Miao', title: 'Serpent Veil Valley', loc: 'l_valley', gender: 'f', hue: '#87a06b', char: '苗', role: 'Smiles like honey, seasons everything with venom', dlg: 'd_miao',
|
||||
teach: [
|
||||
{ tech: 't_hidden_2', aff: 15, cost: 250 },
|
||||
{ tech: 't_hidden_3', aff: 50, cost: 850, reqRep: ['serpent', 20] },
|
||||
{ internal: 'i_serpent', aff: 35, cost: 450 }
|
||||
], giftTags: ['noble'] });
|
||||
defNpc('n_suqing', { name: 'Su Qingluo', title: 'Valley Physician', loc: 'l_valley', gender: 'f', hue: '#a5b879', char: '青', role: 'Cures what ails you; causes what cures you', dlg: 'd_suqing', romanceable: true,
|
||||
companion: { wt: 'hidden', techs: ['t_hidden_1', 't_hidden_2'], internal: 'i_water', ai: 'support', hpM: 0.9, atkM: 1.0, defM: 0.95 }, giftTags: ['scholar', 'romance'] });
|
||||
defNpc('n_master_guo', { name: 'Master Guo', title: 'Iron Fist Guild Hall', loc: 'l_garrison', gender: 'm', hue: '#b3703f', char: '郭', role: 'Retired pit-fighter running the guild hall', dlg: 'd_guo', spar: true,
|
||||
teach: [
|
||||
{ tech: 't_fist_2', aff: 20, cost: 300 },
|
||||
{ tech: 't_fist_3', aff: 55, cost: 900, reqRep: ['fist', 20] }
|
||||
], giftTags: ['fighter', 'drinker'] });
|
||||
defNpc('n_drill_capt', { name: 'Drill-Captain Pei', title: 'Black Tortoise Garrison', loc: 'l_garrison', gender: 'm', hue: '#6f8296', char: '裴', role: 'Runs drills, bounty boards, and recruits ragged', dlg: 'd_pei', giftTags: ['fighter'] });
|
||||
defNpc('n_broker_qiu', { name: 'Broker Qiu', title: 'Ghost Market', loc: 'l_market', gender: 'm', hue: '#9a86a8', char: '邱', role: 'Sells secrets by the ounce', dlg: 'd_broker', giftTags: ['scholar', 'noble'] });
|
||||
defNpc('n_fence_wu', { name: 'Fence Wu', title: 'Ghost Market', loc: 'l_market', gender: 'f', hue: '#8a7d9c', char: '吴', role: 'Everything has a previous owner', dlg: 'd_fence', shop: { name: 'Acquisitions', stock: ['m_l_cloud', 'm_l_shadow', 'm_t_sword_2', 'm_t_blade_2', 'm_t_spear_2', 'm_t_staff_2', 'm_t_fist_2', 'm_t_hidden_2', 'ac_goldbell', 'c_fragment', 'c_elixir_power', 'c_elixir_swift', 'gift_silk', 'gift_book', 'gift_hairpin'] }, giftTags: ['noble'] });
|
||||
|
||||
/* ---------------- WORLD ---------------- */
|
||||
const LOCS = {};
|
||||
function defLoc(id, o) { o.id = id; LOCS[id] = o; }
|
||||
|
||||
defLoc('l_village', { name: 'Willow Creek Village', desc: 'Your home. Willows lean over the creek; chickens own the road.', danger: 0, region: 'Heartlands',
|
||||
actions: [{ id: 'herb', label: 'Gather herbs', note: '1h · daily' }],
|
||||
npcs: ['n_elderchen', 'n_innkeeper_ma', 'n_kid_xiaoli'] });
|
||||
defLoc('l_city', { name: 'Qingyun City', desc: 'Ten thousand roofs, one hundred rumors, at least nine true.', danger: 0, region: 'Heartlands',
|
||||
actions: [{ id: 'board', label: 'Bulletin Board', note: 'bounties & notices' }, { id: 'gamble', label: 'Dice den', note: 'moderate stakes' }, { id: 'pickpocket', label: 'Work the crowd', note: 'risky · daily' }],
|
||||
npcs: ['n_merchant_su', 'n_innkeeper_zhou', 'n_captain_yan', 'n_arena_qian', 'n_beggar_hong'] });
|
||||
defLoc('l_town', { name: 'Ember Town', desc: 'Coal smoke, ringing anvils, and the best noodles in the prefecture.', danger: 0, region: 'Heartlands',
|
||||
npcs: ['n_smith_wang', 'n_alchemist_bai', 'n_innkeeper_lu'] });
|
||||
defLoc('l_dock', { name: 'Peach Blossom Dock', desc: 'Petals on black water; barges going everywhere and nowhere.', danger: 0, region: 'Riverlands',
|
||||
actions: [{ id: 'pickpocket', label: 'Work the crowd', note: 'risky · daily' }, { id: 'fish', label: 'Fish off the pier', note: 'timing · ×10 daily' }],
|
||||
npcs: ['n_tiehu', 'n_ferryman'] });
|
||||
defLoc('l_garrison', { name: 'Black Tortoise Garrison', desc: 'Banners, drill-yards, and the Empire\u2019s long memory.', danger: 0, region: 'Heartlands',
|
||||
actions: [{ id: 'board', label: 'Military Bounty Board', note: 'better-paying bounties' }],
|
||||
npcs: ['n_master_guo', 'n_drill_capt'] });
|
||||
defLoc('l_bamboo', { name: 'Verdant Bamboo Sea', desc: 'Green light falls in stripes. Something is always watching.', danger: 2, region: 'Wilds',
|
||||
pools: { low: ['e_wolf', 'e_snake'], mid: ['e_wolf', 'e_tiger', 'e_bandit'], high: ['e_tiger', 'e_bandit_vet'] },
|
||||
actions: [{ id: 'herb', label: 'Gather herbs', note: '1h · daily' }, { id: 'camp', label: 'Make camp', note: '6h · restore 55%' }],
|
||||
npcs: ['n_hunter_ren'] });
|
||||
defLoc('l_mountain', { name: 'Cloudmist Ridge', desc: 'The pass winds through fog, old shrines, and newer ambushes.', danger: 2, region: 'Wilds',
|
||||
pools: { low: ['e_wolf', 'e_boar'], mid: ['e_wolf', 'e_tiger', 'e_bandit'], high: ['e_tiger', 'e_bandit_vet', 'e_bear'] },
|
||||
actions: [{ id: 'mine', label: 'Prospect for ore', note: '2h · daily' }, { id: 'camp', label: 'Make camp', note: '6h · restore 55%' }],
|
||||
npcs: [] });
|
||||
defLoc('l_valley', { name: 'Serpent Veil Valley', desc: 'Beautiful, fragrant, and quietly lethal. Mind where you step.', danger: 3, region: 'Deep Wilds',
|
||||
pools: { mid: ['e_snake', 'e_poisoner'], high: ['e_poisoner', 'e_tiger', 'e_assassin'] },
|
||||
actions: [{ id: 'herb', label: 'Gather rare herbs', note: '1h · daily' }, { id: 'camp', label: 'Make camp', note: '6h · restore 55%' }],
|
||||
npcs: ['n_lady_miao', 'n_suqing'] });
|
||||
defLoc('l_temple', { name: 'Pure Lotus Temple', desc: 'Incense, bells, and a training yard swept to mirror-brightness.', danger: 0, region: 'Highlands',
|
||||
actions: [{ id: 'meditate', label: 'Meditate in the hall', note: '2h · cultivates internal arts' }, { id: 'dummy', label: 'Train at the posts', note: '1h · practice a technique' }],
|
||||
npcs: ['n_abbot_lian', 'n_monk_jing'] });
|
||||
defLoc('l_sect', { name: 'Azure Cloud Peak', desc: 'Stone stairs above the cloud-line; swords sing at dawn.', danger: 0, region: 'Highlands',
|
||||
actions: [{ id: 'meditate', label: 'Meditate on the terrace', note: '2h' }, { id: 'dummy', label: 'Train at the posts', note: '1h · practice a technique' }, { id: 'secttasks', label: 'Mission Hall', note: 'tasks for sect reputation' }],
|
||||
npcs: ['n_master_yun', 'n_lin'] });
|
||||
defLoc('l_market', { name: 'Ghost Market', desc: 'A market with no daylight and no questions. Entry after dusk only.', danger: 1, region: 'Underworld', nightOnly: true,
|
||||
actions: [{ id: 'gamble', label: 'Dice den', note: 'high stakes' }, { id: 'pickpocket', label: 'Lift a purse', note: 'very risky' }],
|
||||
npcs: ['n_broker_qiu', 'n_fence_wu'] });
|
||||
defLoc('l_tomb', { name: 'Ancient Tomb of the First Sword', desc: 'Buried stairs, patient dead things, and a door that remembers.', danger: 4, region: 'Deep Wilds',
|
||||
pools: { high: ['e_sentinel', 'e_assassin'] },
|
||||
npcs: [] });
|
||||
|
||||
const TRAVEL = [
|
||||
['l_village', 'l_mountain', 2],
|
||||
['l_village', 'l_city', 4],
|
||||
['l_city', 'l_town', 2],
|
||||
['l_city', 'l_dock', 1],
|
||||
['l_city', 'l_garrison', 2],
|
||||
['l_city', 'l_bamboo', 3],
|
||||
['l_dock', 'l_market', 1],
|
||||
['l_bamboo', 'l_sect', 2],
|
||||
['l_bamboo', 'l_valley', 3],
|
||||
['l_town', 'l_temple', 3],
|
||||
['l_mountain', 'l_tomb', 3]
|
||||
];
|
||||
|
||||
/* ---------------- QUESTS ---------------- */
|
||||
const QUESTS = {
|
||||
q_main_1: { name: 'Wolf Trouble', main: true, stages: [
|
||||
'Speak with Elder Chen.',
|
||||
'Cull the wolf packs on Cloudmist Ridge. (%K/wolves)',
|
||||
'Report back to Elder Chen.'
|
||||
],
|
||||
doneText: 'The flocks sleep easy — for now.' },
|
||||
q_main_2: { name: 'A Trail Leads to Qingyun', main: true, stages: [
|
||||
'Find Captain Yan at the Garrison Liaison Office in Qingyun City.',
|
||||
'Destroy the bandit camp on Cloudmist Ridge.',
|
||||
'Defeat "One-Eye" Qiang.',
|
||||
'Search the camp for evidence.'
|
||||
],
|
||||
doneText: 'Qiang’s lead token now sits in Captain Yan’s evidence box.' },
|
||||
q_main_3: { name: 'The Iron Umbrella', main: true, stages: [
|
||||
'Learn about the Iron Umbrella Society. (Try the Ghost Market at night.)',
|
||||
'Buy Broker Qiu\u2019s intelligence on the tournament plot.',
|
||||
'Win through to the tournament finals in Qingyun City.',
|
||||
'Expose the impostor among the finalists.'
|
||||
],
|
||||
doneText: 'Du Kang escaped with his life — but not his secrets.' },
|
||||
q_main_4: { name: 'Gathering Storm', main: true, stages: [
|
||||
'Recruit at least two companions to your banner.',
|
||||
'Join a school or earn Garrison trust (rep 30).',
|
||||
'Report to Captain Yan.'
|
||||
],
|
||||
doneText: 'You are no longer alone on the road.' },
|
||||
q_main_5: { name: 'The Heaven\u2019s Ledger', main: true, stages: [
|
||||
'Take the mountain path to the Ancient Tomb of the First Sword.',
|
||||
'Silence two Tomb Sentinels guarding the descent. (%K/sentinels)',
|
||||
'Reach the inner door before the Iron Umbrella takes the Ledger.',
|
||||
'Claim the Heaven\u2019s Ledger.'
|
||||
],
|
||||
doneText: 'The Ledger weighs almost nothing, and changes everything.' },
|
||||
q_main_6: { name: 'Showdown at Azure Peak', main: true, stages: [
|
||||
'The Iron Umbrella marches on Azure Cloud Peak. Go there and hold the line.',
|
||||
'Defeat Wu Zhaoshan.'
|
||||
],
|
||||
doneText: 'The umbrellas folded, one by one, until the sky was only sky.' },
|
||||
q_cure: { name: 'The Alchemist\u2019s Favor', stages: [
|
||||
'Alchemist Bai needs 2 Snake Gallbladders and 3 Green Herbs.',
|
||||
'Bring the ingredients to Alchemist Bai in Ember Town.'
|
||||
],
|
||||
doneText: 'Bai’s fever cure saved three children. She shares her real recipes.' },
|
||||
q_missing: { name: 'The Missing Woodcutter', stages: [
|
||||
'Ask Hunter Ren in the Bamboo Sea about Uncle Ping.',
|
||||
'Search the deep bamboo past the third bend.',
|
||||
'Tell Elder Chen the news.'
|
||||
],
|
||||
doneText: 'Uncle Ping rests beneath the willows now. The village will remember.' },
|
||||
q_trial_az: { name: 'Trials of Azure Cloud', stages: [
|
||||
'Bring 2 Lotus Herbs from the Bamboo Sea to Master Yun.',
|
||||
'Deliver the herbs.'
|
||||
],
|
||||
doneText: 'The gates of Azure Cloud Sect stand open to you.' }
|
||||
};
|
||||
|
||||
/* ---------------- ORIGINS ---------------- */
|
||||
const ORIGINS = {
|
||||
farm: { name: 'Farmhand\u2019s Child', attrs: { con: 1, str: 1 }, silver: 30, items: ['w_staff_1', 'c_bun', 'c_bun'], techs: ['t_staff_1', 't_univ_1'],
|
||||
desc: 'Raised on hoe-handles and early mornings.' },
|
||||
merchant: { name: 'Merchant\u2019s Heir', attrs: { cha: 2, luk: 1 }, silver: 260, items: ['ac_jade', 'gift_fan', 'c_bun'], techs: ['t_univ_1'],
|
||||
desc: 'You know what everything costs, including pride.' },
|
||||
scholar: { name: 'Runaway Scholar', attrs: { wit: 3 }, silver: 90, items: ['gift_book', 'c_bun'], techs: ['t_univ_1'],
|
||||
desc: 'You memorized the classics, then ran off to live in one.' },
|
||||
hunter: { name: 'Hunter\u2019s Child', attrs: { agi: 2, str: 1 }, silver: 60, items: ['w_blade_1', 'mat_pelt', 'mat_pelt'], techs: ['t_blade_1', 't_univ_1'],
|
||||
desc: 'You gutted your first boar at nine.' },
|
||||
orphan: { name: 'Street Orphan', attrs: { agi: 2, luk: 2 }, silver: 45, items: ['w_hidden_1', 'c_bun'], techs: ['t_hidden_1', 't_univ_1'],
|
||||
desc: 'The streets fed you table scraps and knife skills alike.' },
|
||||
foundling: { name: 'Temple Foundling', attrs: { con: 2, wit: 1 }, silver: 20, items: ['w_staff_1', 'c_pill_hp'], techs: ['t_staff_1', 't_univ_1'],
|
||||
desc: 'Left at the temple gate with a staff and a name tag. Both served you well.' }
|
||||
};
|
||||
const ORIGIN_IDS = Object.keys(ORIGINS);
|
||||
|
||||
/* ---------------- RECIPES ---------------- */
|
||||
const SMITH_UPGRADES = {
|
||||
w_sword_1: { to: 'w_sword_2', silver: 120, mats: { mat_ore_1: 2 } },
|
||||
w_sword_2: { to: 'w_sword_3', silver: 450, mats: { mat_ore_2: 2 } },
|
||||
w_sword_3: { to: 'w_sword_4', silver: 1400, mats: { mat_ore_3: 1, mat_ore_2: 2 } },
|
||||
w_blade_1: { to: 'w_blade_2', silver: 120, mats: { mat_ore_1: 2 } },
|
||||
w_blade_2: { to: 'w_blade_3', silver: 450, mats: { mat_ore_2: 2 } },
|
||||
w_blade_3: { to: 'w_blade_4', silver: 1400, mats: { mat_ore_3: 1, mat_ore_2: 2 } },
|
||||
w_spear_1: { to: 'w_spear_2', silver: 120, mats: { mat_ore_1: 2 } },
|
||||
w_spear_2: { to: 'w_spear_3', silver: 450, mats: { mat_ore_2: 2 } },
|
||||
w_spear_3: { to: 'w_spear_4', silver: 1400, mats: { mat_ore_3: 1, mat_ore_2: 2 } },
|
||||
w_staff_1: { to: 'w_staff_2', silver: 110, mats: { mat_ore_1: 2 } },
|
||||
w_staff_2: { to: 'w_staff_3', silver: 430, mats: { mat_ore_2: 2 } },
|
||||
w_staff_3: { to: 'w_staff_4', silver: 1350, mats: { mat_ore_3: 1, mat_ore_2: 2 } },
|
||||
w_fist_1: { to: 'w_fist_2', silver: 110, mats: { mat_ore_1: 2 } },
|
||||
w_fist_2: { to: 'w_fist_3', silver: 430, mats: { mat_ore_2: 2 } },
|
||||
w_fist_3: { to: 'w_fist_4', silver: 1350, mats: { mat_ore_3: 1, mat_ore_2: 2 } },
|
||||
w_hidden_1: { to: 'w_hidden_2', silver: 110, mats: { mat_ore_1: 2 } },
|
||||
w_hidden_2: { to: 'w_hidden_3', silver: 430, mats: { mat_ore_2: 2 } },
|
||||
w_hidden_3: { to: 'w_hidden_4', silver: 1350, mats: { mat_ore_3: 1, mat_ore_2: 2 } },
|
||||
ar_body_1: { to: 'ar_body_2', silver: 90, mats: { mat_ore_1: 2 } },
|
||||
ar_body_2: { to: 'ar_body_3', silver: 300, mats: { mat_ore_2: 2 } },
|
||||
ar_body_3: { to: 'ar_body_4', silver: 900, mats: { mat_ore_3: 1, mat_ore_2: 2 } },
|
||||
ar_head_1: { to: 'ar_head_2', silver: 70, mats: { mat_ore_1: 1 } },
|
||||
ar_head_2: { to: 'ar_head_3', silver: 240, mats: { mat_ore_2: 1 } },
|
||||
ar_head_3: { to: 'ar_head_4', silver: 750, mats: { mat_ore_3: 1 } },
|
||||
ar_foot_1: { to: 'ar_foot_2', silver: 60, mats: { mat_pelt: 2 } },
|
||||
ar_foot_2: { to: 'ar_foot_3', silver: 200, mats: { mat_ore_1: 1, mat_pelt: 1 } },
|
||||
ar_foot_3: { to: 'ar_foot_4', silver: 650, mats: { mat_ore_2: 1, mat_pelt: 2 } }
|
||||
};
|
||||
|
||||
const ALCHEMY_RECIPES = [
|
||||
{ id: 'r_hp', name: 'Healing Pill ×2', out: 'c_pill_hp', qty: 2, mats: { c_herb_red: 2 }, silver: 15, needFlag: null },
|
||||
{ id: 'r_mp', name: 'Clear-Mind Pill ×2', out: 'c_pill_mp', qty: 2, mats: { c_lotus: 1, c_herb_green: 1 }, silver: 15, needFlag: null },
|
||||
{ id: 'r_anti', name: 'Antidote Powder ×2', out: 'c_antidote', qty: 2, mats: { c_herb_green: 2 }, silver: 10, needFlag: null },
|
||||
{ id: 'r_pow', name: 'Battle Elixir', out: 'c_elixir_power', qty: 1, mats: { mat_gall: 1, c_herb_red: 2 }, silver: 40, needFlag: 'knowsAlchemy' },
|
||||
{ id: 'r_swi', name: 'Swift Elixir', out: 'c_elixir_swift', qty: 1, mats: { c_lotus: 1, mat_fang: 1 }, silver: 40, needFlag: 'knowsAlchemy' },
|
||||
{ id: 'r_ven', name: 'Coat of Venom', out: 'c_venom', qty: 1, mats: { mat_gall: 2 }, silver: 30, needFlag: 'knowsAlchemy' },
|
||||
{ id: 'r_ton', name: 'Vital Tonic', out: 'c_tonic', qty: 1, mats: { c_lotus: 2, mat_gall: 1 }, silver: 80, needFlag: 'knowsAlchemy' }
|
||||
];
|
||||
|
||||
/* ---------------- TOURNAMENT ---------------- */
|
||||
ENEMIES['e_champ_camellia'] = Object.assign({}, ENEMIES.e_bandit_vet, {
|
||||
id: 'e_champ_camellia', name: 'Madame Camellia', tier: 3, hp: 150, atk: 22, def: 10, spd: 12, silver: [80, 130], exp: 130,
|
||||
moves: [
|
||||
{ n: 'Silk Whip Combo', mp: 12, p: 96, r: 1, sh: 'foe', hits: 2 },
|
||||
{ n: 'Camellia Stance', mp: 12, p: 0, r: 0, sh: 'self', buff: { stat: 'spd', pct: 0.3, dur: 2 } },
|
||||
{ n: 'Petal Storm Kick', mp: 16, p: 150, r: 1, sh: 'cross' }
|
||||
]
|
||||
});
|
||||
const TOURNEY_LADDER = [
|
||||
{ name: '"Brickwall" Luo', base: 'e_thug' },
|
||||
{ name: 'Iron Sash Wei', base: 'e_bandit_vet' },
|
||||
{ name: 'Madame Camellia', base: 'e_champ_camellia' },
|
||||
{ name: 'Blade Saint Yun-Fei', base: 'e_duelist' }
|
||||
];
|
||||
|
||||
/* ---------------- BOUNTY POOLS ---------------- */
|
||||
const BOUNTY_POOLS = {
|
||||
1: ['e_wolf', 'e_boar', 'e_snake', 'e_bandit', 'e_thug'],
|
||||
2: ['e_tiger', 'e_bandit_vet', 'e_bandit_chief', 'e_guard_deserter_placeholder'],
|
||||
3: ['e_assassin', 'e_poisoner', 'e_bear']
|
||||
};
|
||||
ENEMIES['e_deserter'] = Object.assign({}, ENEMIES.e_bandit_vet, {
|
||||
id: 'e_deserter', name: 'Runaway Soldier', tier: 2, def: 8,
|
||||
moves: [{ n: 'Saber Drill', mp: 8, p: 138, r: 1, sh: 'foe' }, { n: 'Braced Guard', mp: 10, p: 0, r: 0, sh: 'self', shield: 35 }]
|
||||
});
|
||||
BOUNTY_POOLS[2] = ['e_tiger', 'e_bandit_vet', 'e_bandit_chief', 'e_deserter'];
|
||||
|
||||
/* ---------------- TEMPLE TRIAL QUEST ---------------- */
|
||||
QUESTS['q_trial_fl'] = {
|
||||
name: 'Sweeping the Courtyard',
|
||||
stages: [
|
||||
'Prove patience: meditate once in the temple hall, then spar with Monk Jing.',
|
||||
'Report to Abbot Lian.'
|
||||
],
|
||||
doneText: 'The Pure Lotus Temple opens its gates; the broom, however, remains yours.'
|
||||
};
|
||||
|
||||
/* ---------------- ACHIEVEMENTS ---------------- */
|
||||
const ACHIEVEMENTS = {
|
||||
first_blood: { name: 'First Blood', desc: 'Win your first battle.' },
|
||||
ridge_guardian:{ name: 'Ridge Guardian', desc: 'Complete "Wolf Trouble".' },
|
||||
champion: { name: 'Ring Champion', desc: 'Win the Qingyun tournament.' },
|
||||
hong_heir: { name: 'Hong\u2019s Heir', desc: 'Learn the Ten Thousand Rivers Palms.' },
|
||||
sun_dawn: { name: 'Blazing Dawn', desc: 'Cultivate the lost Blazing Sun Manual.' },
|
||||
keeper_truth: { name: 'Keeper of Truth', desc: 'Claim the Heaven\u2019s Ledger.' },
|
||||
fat_purse: { name: 'Heavy Purse', desc: 'Hold 2,000 silver at once.' },
|
||||
journeyman: { name: 'Journeyman', desc: 'Reach level 10.' },
|
||||
master_qi: { name: 'Master of Qi', desc: 'Reach level 20.' },
|
||||
band_three: { name: 'Band of Three', desc: 'Travel with three companions.' },
|
||||
two_rivers: { name: 'Two Rivers, One Heart', desc: 'Find romance on the road.' },
|
||||
after_dark: { name: 'After-Dark Customer',desc: 'Set foot in the Ghost Market.' },
|
||||
water_patience:{ name: 'Patience of Water', desc: 'Catch 25 fish in a lifetime.' },
|
||||
umbrellas_fall:{ name: 'Umbrellas Fold', desc: 'Finish the main story.' }
|
||||
};
|
||||
|
||||
/* ---------------- BESTIARY LORE ---------------- */
|
||||
const BEAST_LORE = {
|
||||
e_wolf: 'Grey pack-hunters that grow bold whenever granaries do.',
|
||||
e_boar: 'All shoulder and temper; farmers tell stories, fences tell more.',
|
||||
e_snake: 'Green as spring bamboo, twice as patient.',
|
||||
e_tiger: 'The Cloudmist stripe is prized by poets and avoided by everyone else.',
|
||||
e_bear: 'It owns the berry slopes. You are renting.',
|
||||
e_bandit: 'A knife, a grudge, and poor arithmetic.',
|
||||
e_bandit_vet: 'Survived enough ambushes to run one properly.',
|
||||
e_bandit_chief: 'Promoted by attrition \u2014 the men above him kept dying.',
|
||||
e_thug: 'Collects debts for people who dislike paperwork.',
|
||||
e_guard: 'Garrison drilled, halberd regulation, patience limited.',
|
||||
e_assassin: 'An umbrella\u2019s shadow, sharpened.',
|
||||
e_cultist: 'Sworn to silver paper oaths they cannot show their families.',
|
||||
e_poisoner: 'Expelled from the Valley for excessive enthusiasm.',
|
||||
e_duelist: 'Walks from town to town collecting styles and scars.',
|
||||
e_sentinel: 'Carved to guard, carved to last, carved to kill.',
|
||||
e_boss_qiang: 'Lost an eye to a magistrate\u2019s chain; repaid the ledger in lead.',
|
||||
e_boss_dukang: 'Silk manners, silver umbrella, no refunds.',
|
||||
e_boss_heihu: 'The Patriarch\u2019s enforcer. The umbrella never opens twice.',
|
||||
e_boss_wu: 'Built the Iron Umbrella Society the way rivers build canyons.',
|
||||
e_deserter: 'Kept the training, misplaced the flag.',
|
||||
e_champ_camellia: 'Retired opera dancer; the kicks stayed.'
|
||||
};
|
||||
|
||||
/* tier-V ultimates & support arts — masters' final teachings */
|
||||
NPCS.n_hunter_ren.teach.push({ tech: 't_blade_5', aff: 75, cost: 2400 });
|
||||
NPCS.n_master_yun.teach.push({ tech: 't_sword_5', aff: 80, cost: 2600 });
|
||||
NPCS.n_abbot_lian.teach.push({ tech: 't_staff_5', aff: 80, cost: 2600 }, { tech: 't_univ_2', aff: 45, cost: 900 }, { tech: 't_univ_3', aff: 60, cost: 1200 });
|
||||
NPCS.n_master_guo.teach.push({ tech: 't_fist_5', aff: 80, cost: 2600 });
|
||||
NPCS.n_lady_miao.teach.push({ tech: 't_hidden_5', aff: 78, cost: 2500 });
|
||||
NPCS.n_drill_capt.teach = [{ tech: 't_spear_5', aff: 70, cost: 2400 }];
|
||||
|
||||
/* richer shop stocks (late-game reach) */
|
||||
NPCS.n_fence_wu.shop.stock.push('m_t_sword_5', 'm_t_blade_5', 'm_t_spear_5', 'm_t_staff_5', 'm_t_fist_5', 'm_t_hidden_5', 'm_univ_2', 'm_univ_3', 'ar_head_4', 'ar_body_4', 'ar_foot_4', 'ac_eye');
|
||||
NPCS.n_smith_wang.shop.stock.push('ar_head_3');
|
||||
NPCS.n_merchant_su.shop.stock.push('ar_foot_2');
|
||||
|
||||
/* ---------------- SIDE JOB QUESTS (job board) ---------------- */
|
||||
Object.assign(QUESTS, {
|
||||
q_herb_bai: { name: 'Bitter Roots, Kind Hearts', stages: ['Gather 5 Red Herb (herb spots in the wilds).', 'Deliver them at the job board.'],
|
||||
doneText: 'Bai\u2019s shelves are full again; your pockets are, too.' },
|
||||
q_ring_reeds: { name: 'The Ring in the Reeds', stages: ['Widow Chen\u2019s ring went down with a serpent\u2019s dinner. Cull 4 valley snakes.', 'Deliver the news at the job board.'],
|
||||
doneText: 'The ring was in the third belly. The fourth was personal.' },
|
||||
q_forge_coal: { name: 'Fuel for the Forge', stages: ['Prospect ore twice at Cloudmist Ridge.', 'Report to the job board.'],
|
||||
doneText: 'Wang\u2019s forge roars for a week. He names an anvil after you.' },
|
||||
q_night_watch: { name: 'Night Watch', stages: ['Cull 3 bandits on the roads.', 'Collect your wage at the job board.'],
|
||||
doneText: 'The pass is quieter. Pei pretends not to be impressed.' },
|
||||
q_alms_lotus: { name: 'Alms for the Lotus', stages: ['Donate 300 silver to the temple fund.', "Receive the abbot's blessing at the job board."],
|
||||
doneText: 'Three hundred silver, one quiet mind. Fair trade.' },
|
||||
q_lantern_dead: { name: 'Lanterns for the Dead', stages: ['Bring 2 Mulled Wine and 1 Lotus Herb for the river rite.', 'Deliver them at the job board.'],
|
||||
doneText: 'Two lanterns downstream, one old song, no ghosts.' }
|
||||
});
|
||||
Reference in New Issue
Block a user