import { BattleRole, callReducPercent, replace } from '@/tool'; import { type_boss } from '@/config'; import i18n from '../i18n'; import { ControlBuff } from './buff'; const { t } = i18n; export interface Skill { order: number; lv?: number; type: string; name: string; cd: number; rmdCd: number; desc(): string; beforeBattle(owner: BattleRole, target: BattleRole): void; beforeAtk(owner: BattleRole, target: BattleRole): void; afterAtk(owner: BattleRole, target: BattleRole): void; afterBattle(owner: BattleRole, target: BattleRole): void; onAtked(owner: BattleRole, target: BattleRole): void; } export const skill_type_action = 'action'; export const skill_type_passive = 'passive'; //主动技能 export abstract class ActionSkill implements Skill { type: string = skill_type_action; order: number = 10; abstract name: string; abstract cd: number; rmdCd: number = 0; abstract desc(): string; beforeBattle(owner: BattleRole, target: BattleRole): void {} beforeAtk(owner: BattleRole, target: BattleRole): void { if (this.rmdCd > 0) { this.rmdCd--; } else if (owner.action) { return; } else { this.rmdCd = this.cd - 1; owner.action = this; } } abstract use(owner: BattleRole, target: BattleRole): void; afterAtk(owner: BattleRole, target: BattleRole): void {} afterBattle(owner: BattleRole, target: BattleRole): void {} onAtked(owner: BattleRole, target: BattleRole): void {} } //被动技能 export abstract class PassiveSkill implements Skill { type: string = skill_type_passive; abstract name: string; order: number = 1; cd: number = 0; last: number = 1; rmdCd: number = 0; rmdLast: number = -1; abstract desc(): string; beforeBattle(owner: BattleRole, target: BattleRole): void {} beforeAtk(owner: BattleRole, target: BattleRole): void {} check(owner: BattleRole, target: BattleRole): void { if (this.rmdCd > 0) { this.rmdCd--; } else if (this.trigger(owner, target)) { this.rmdCd = this.cd - 1; this.rmdLast = this.last; } if (this.rmdLast > 0) { this.rmdLast--; this.takeEffect(owner, target); } } abstract trigger(owner: BattleRole, target: BattleRole): boolean; abstract takeEffect(owner: BattleRole, target: BattleRole): void; afterAtk(owner: BattleRole, target: BattleRole): void {} afterBattle(owner: BattleRole, target: BattleRole): void {} onAtked(owner: BattleRole, target: BattleRole): void {} } //战斗开始前触发 export abstract class StartPassiveSkill extends PassiveSkill { beforeBattle(owner: BattleRole, target: BattleRole): void { this.takeEffect(owner, target); } trigger(owner: BattleRole, target: BattleRole): boolean { return true; } } //攻击前触发的被动 export abstract class PrePassiveSkill extends PassiveSkill { beforeAtk(owner: BattleRole, target: BattleRole): void { this.check(owner, target); } } //攻击后触发的被动 export abstract class SufPassiveSkill extends PassiveSkill { afterAtk(owner: BattleRole, target: BattleRole): void { this.check(owner, target); } } //被攻击后触发的被动 export abstract class CounterSkill extends PassiveSkill { onAtked(owner: BattleRole, target: BattleRole): void { this.check(owner, target); } } //收益技能 export abstract class GainsSkill implements Skill { order: number = 1; type: string = skill_type_passive; abstract name: string; cd: number = 0; rmdCd: number = 0; abstract desc(): string; beforeBattle(owner: BattleRole, target: BattleRole): void {} beforeAtk(owner: BattleRole, target: BattleRole): void {} afterAtk(owner: BattleRole, target: BattleRole): void {} abstract afterBattle(owner: BattleRole, target: BattleRole): void; onAtked(owner: BattleRole, target: BattleRole): void {} } //吸血技能 export abstract class Vampire extends SufPassiveSkill { abstract percent: number; name: string = 'vampire'; rate: number = 100; desc(): string { return replace(t('skill.vampire.1'), [this.percent]); } trigger(owner: BattleRole, target: BattleRole): boolean { return true; } takeEffect(owner: BattleRole, target: BattleRole): void { if (owner.dmg <= 0) { return; } let sneak = Math.ceil((owner.dmg * this.percent) / 100); const tmp = owner.attr.hp - owner.attr.curHp; sneak = sneak > tmp ? tmp : sneak; owner.addHp(sneak); if (sneak > 0) { const log = replace(t('skill.vampire.2'), [sneak]); owner.battleLog(log); } } } //主动控制技能 export abstract class Control extends ActionSkill { abstract last: number; abstract rate: number; abstract bossRate: number; use(owner: BattleRole, target: BattleRole) { const rate = target.type == type_boss ? this.bossRate : this.rate; let log = t('skill.control.1'); if (Math.random() < rate / 100) { target.putBuff(new ControlBuff(this.name, this.last)); log = replace(t('skill.control.0'), [t(target.type), this.last]); } log = log = replace(t('skill.user'), [t(owner.type), t('skill.' + this.name + '.0')]) + log; owner.battleLog(log); } } //主动攻击技能(普通攻击) export class Attack extends ActionSkill { order: number = 999; name: string = 'attack'; cd: number = 1; precent: number = 100; desc(): string { return t('skill.attack.1'); } use(owner: BattleRole, target: BattleRole) { owner.skillPercent += this.precent; owner.callDmg(target); let critLog = owner.crit ? t('skill.crit.0') : ''; if (owner.dmg) { target.addHp(-1 * owner.dmg); const log = replace(t('skill.attack.2'), [t(owner.type), t('skill.' + this.name + '.0'), t(target.type), owner.dmg, critLog]); owner.battleLog(log); } } } //主动增益技能 export abstract class BuffSkill extends ActionSkill { abstract last: number; rmdLast = 0; beforeAtk(owner: BattleRole, target: BattleRole): void { super.beforeAtk(owner, target); this.check(owner, target); } check(owner: BattleRole, target: BattleRole): void { if (this.rmdLast > 0) { this.rmdLast--; this.takeEffect(owner, target); } } abstract takeEffect(owner: BattleRole, target: BattleRole): void; use(owner: BattleRole, target: BattleRole): void { this.rmdLast = this.last; this.log(owner, target); this.check(owner, target); } abstract log(owner: BattleRole, target: BattleRole): void; }