let levels: number[] = []; export type Chapter = 'chapter1' | 'chapter2'; export interface Skill { index: number; title: string; desc: string[]; consume: (level: number) => number; front: [skill: number, level: number][]; loc: LocArr; max: number; effect: (level: number) => string[]; } /** * @type {Record} */ export const skills: Record = { chapter1: [ { index: 0, title: '力量', desc: ['力量就是根本!可以通过智慧增加力量,每级增加2点攻击。'], consume: level => 10 * level + 10, front: [], loc: [1, 2], max: 10, effect: level => [`攻击 + ${level * 2}`] }, { index: 1, title: '致命一击', desc: ['爆发出全部力量攻击敌人,每级增加5点额外攻击。'], consume: level => 30 * level + 30, front: [[0, 5]], loc: [2, 1], max: 10, effect: level => [`额外攻击 + ${level * 5}`] }, { index: 2, title: '断灭之刃', desc: [ '主动技能,快捷键1,', '开启后会在战斗时会额外增加一定量的攻击,但同时减少一定量的防御。' ], consume: level => 200 * level + 400, front: [[1, 5]], loc: [4, 1], max: 5, effect: level => [`增加${level * 10}%攻击,减少${level * 10}%防御`] }, { index: 3, title: '坚韧', desc: ['由智慧转化出坚韧!每级增加2点防御'], consume: level => 10 * level + 10, front: [], loc: [1, 4], max: 10, effect: level => [`防御 + ${level * 2}`] }, { index: 4, title: '回春', desc: ['让智慧化为治愈之泉水!每级增加1点生命回复'], consume: level => 20 * level + 20, front: [[3, 5]], loc: [2, 5], max: 25, effect: level => [`生命回复 + ${level}`] }, { index: 5, title: '治愈之泉', desc: [ '让生命变得更多一些吧!每吃50瓶血瓶就增加当前生命回复10%的生命回复' ], consume: () => 1500, front: [[4, 25]], loc: [4, 5], max: 1, effect: () => [`50瓶血10%生命回复`] }, { index: 6, title: '坚固之盾', desc: ['让护甲更加坚硬一些吧!每级增加10点防御'], consume: level => 50 + level * 50, front: [[3, 5]], loc: [2, 3], max: 10, effect: level => [`防御 + ${level * 10}`] }, { index: 7, title: '无上之盾', desc: [ '第一章终极技能,战斗时智慧的 1/10 会充当等量护盾。' ], consume: () => 2500, front: [ [6, 10], [5, 1], [2, 2] ], loc: [5, 3], max: 1, effect: () => [`战斗时智慧会充当护盾`] } ], chapter2: [ { index: 8, title: '锋利', desc: ['让剑变得更加锋利!每级使攻击增加1%(buff式增加)'], consume: level => (level > 5 ? 50 * level ** 2 : 250 * level + 250), front: [], loc: [1, 2], max: 15, effect: level => [`攻击增加${level}%`] }, { index: 9, title: '坚硬', desc: ['让盾牌变得更加坚固!每级使防御增加1%(buff式增加)'], consume: level => (level > 5 ? 50 * level ** 2 : 250 * level + 250), front: [], loc: [1, 4], max: 15, effect: level => [`防御增加${level}%`] }, { index: 10, title: '铸剑为盾', desc: [ '主动技能,快捷键3,', '减少一定的攻击,增加一定的防御' ], consume: level => 1000 * level ** 2 + 1000, front: [[9, 5]], loc: [2, 5], max: 5, effect: level => [ `增加${level * 10}%的防御,减少${level * 10}%的攻击` ] }, { index: 11, title: '魔法盾', desc: ['为主角提供魔法防御,每级增加100点魔法防御'], consume: level => 5000 * level + 5000, front: [ [8, 10], [12, 10] ], loc: [4, 1], max: 10, effect: level => [`魔法防御 + ${level * 100}`] }, { index: 12, title: '聪慧', desc: ['使主角变得更加聪明,每级使绿宝石增加的智慧点上升5%'], consume: level => level > 5 ? 100 * level ** 2 : 250 * level + 1250, front: [ [8, 10], [9, 10] ], loc: [3, 3], max: 20, effect: level => [`增加${level * 5}%绿宝石效果`] }, { index: 13, title: '治愈', desc: ['使主角能够更好地回复生命,每级使血瓶的加血量增加2%'], consume: level => level > 5 ? 100 * level ** 2 : 250 * level + 1250, front: [[10, 3]], loc: [4, 5], max: 10, effect: level => [`增加${level * 2}%的血瓶回血量`] }, { index: 14, title: '胜利之号', desc: [ '第二章终极技能,', '勇士攻防增加10%(buff式增加)' ], consume: () => 25000, front: [ [13, 10], [12, 10], [11, 3] ], loc: [5, 3], max: 1, effect: () => [`攻防增加10%`] } ] }; export function resetSkillLevel() { levels = []; } export function getSkillFromIndex(index: number) { for (const [, skill] of Object.entries(skills)) { const s = skill.find(v => v.index === index); if (s) return s; } } /** * 获取技能等级 */ export function getSkillLevel(skill: number) { levels[skill] ??= 0; return levels[skill]; } export function getSkillConsume(skill: number) { const s = getSkillFromIndex(skill); if (!s) return 0; return s.consume(getSkillLevel(skill)); } export function openTree() { if (main.replayChecking) return; Mota.require('@motajs/legacy-ui').mainUi.open('skillTree'); } /** * 能否升级某个技能 */ export function canUpgrade(skill: number) { const consume = getSkillConsume(skill); if (consume > core.status.hero.mdef) return false; const level = getSkillLevel(skill); const s = getSkillFromIndex(skill); if (level === s?.max) return false; const front = s?.front ?? []; for (const [skill, level] of front) { if (getSkillLevel(skill) < level) return false; } return true; } /** * 实际升级效果 * @param {number} skill */ export function upgradeSkill(skill: number) { if (!canUpgrade(skill)) return false; switch (skill) { case 0: // 力量 +2攻击 core.status.hero.atk += 2; break; case 1: // 致命一击 +5额外攻击 core.status.hero.mana += 5; break; case 2: // 断灭之刃 HeroSkill.learnSkill(HeroSkill.Blade); break; case 3: // 坚韧 +2防御 core.status.hero.def += 2; break; case 4: // 回春 +1回复 core.status.hero.hpmax += 1; break; case 5: // 治愈之泉 core.setFlag('spring', true); break; case 6: // 坚固之盾 +10防御 core.status.hero.def += 10; break; case 7: // 无上之盾 core.setFlag('superSheild', true); break; case 8: // 锋利 +1%攻击 core.addBuff('atk', 0.01); break; case 9: // 锋利 +1%防御 core.addBuff('def', 0.01); break; case 10: // 铸剑为盾 HeroSkill.learnSkill(HeroSkill.Shield); break; case 11: // 魔法盾 core.status.hero.magicDef += 100; break; case 14: core.addBuff('atk', 0.1); core.addBuff('def', 0.1); break; } const consume = getSkillConsume(skill); core.status.hero.mdef -= consume; levels[skill]++; core.updateStatusBar(); return true; } export function saveSkillTree() { return levels.slice(); } export function loadSkillTree(data: number[]) { levels = data ?? []; } export namespace HeroSkill { export const enum Skill { None, /** 断灭之刃 */ Blade, /** 铸剑为盾 */ Shield, /** 跳跃 */ Jump } export const Blade = Skill.Blade; export const Shield = Skill.Shield; export const Jump = Skill.Jump; const skillNameMap = new Map([ [Skill.Blade, '断灭之刃'], [Skill.Shield, '铸剑为盾'], [Skill.Jump, '跳跃'] ]); const skillDesc = new Map string>([ [ Skill.Blade, level => `攻击上升 ${level * 10}%,防御下降 ${level * 10}%` ], [ Skill.Shield, level => `防御上升 ${level * 10}%,攻击下降 ${level * 10}%` ], [Skill.Jump, () => `跳过前方障碍,或踢走面前的怪物`] ]); interface SkillSave { autoSkill: boolean; learned: Skill[]; } const learned = new Set(); let autoSkill = true; let enabled: Skill = Skill.None; export function getLevel(skill: Skill = getEnabled()) { switch (skill) { case Blade: return getSkillLevel(2); case Jump: return learned.has(Jump) ? 1 : 0; case Shield: return getSkillLevel(10); } return 0; } export function getSkillName(skill: Skill = getEnabled()) { return skillNameMap.get(skill) ?? '未开启技能'; } export function getSkillDesc( skill: Skill = getEnabled(), level: number = getLevel() ) { return skillDesc.get(skill)?.(level) ?? ''; } export function setAutoSkill(auto: boolean) { autoSkill = auto; } export function getAutoSkill() { return autoSkill; } export function learnedSkill(skill: Skill) { return learned.has(skill); } export function learnSkill(skill: Skill) { learned.add(skill); } export function forgetSkill(skill: Skill) { learned.delete(skill); } export function clearSkill() { learned.clear(); } export function saveSkill(): SkillSave { return { autoSkill, learned: [...learned] }; } export function loadSkill(skills: SkillSave) { learned.clear(); for (const skill of skills.learned) { learned.add(skill); } autoSkill = skills.autoSkill; } export function getAll() { return learned; } export function toggleSkill(skill: Skill) { if (!learned.has(skill)) return; if (enabled !== skill) enabled = skill; else enabled = Skill.None; } export function enableSkill(skill: Skill) { if (!learned.has(skill)) return; enabled = skill; } export function disableSkill() { enabled = Skill.None; } export function getEnabled() { return enabled; } }