import { Equip, Skills, Monster, Attribute, Player } from '@/config'; import { randonBootyEquip, deepCopy, replace, callReducPercent } from '@/tool'; import i18n from '@/config/i18n'; const { t } = i18n; export class BattleRole { attr: Attribute; actions: Skills.Skill[] = new Array(); passives: Skills.Skill[] = new Array(); commit; type: string; control: number = 0; //临时状态 action: Skills.ActionSkill | null = null; dmg: number = 0; crit: boolean = false; extraAttr: Attribute = new Attribute(); shield: number = 0; constructor(attr: Attribute, commit, type: string) { this.attr = attr; this.commit = commit; this.type = type; this.addSkill(attr.skill); //添加默认主动技能普通攻击 this.initTmp(); } initTmp = () => { this.action = null; this.dmg = 0; this.crit = false; this.extraAttr = new Attribute(); this.extraAttr.hp = 0; this.extraAttr.critDmg = 0; this.shield = Math.ceil(this.shield * 0.9); }; addSkill = (skillName, lv?) => { lv = lv || 1; const skills = createSkill(skillName, lv); skills.forEach((skill) => { const type = skill.type; if (type == Skills.skill_type_action) { this.actions.push(skill); //主动技能 } else if (type == Skills.skill_type_passive) { this.passives.push(skill); //被动技能 } }); }; onStartBattle = (target: BattleRole) => { //技能排序 this.actions.sort((a, b) => { return (a.order = b.order); }); //战斗开始前触发的技能 this.passives.forEach((skill) => { skill.beforeBattle(this, target); }); }; attack = (target: BattleRole) => { //选择使用的主动技能 this.actions.forEach((skill) => { skill.beforeAtk(this, target); }); //攻击前触发的被动技能 this.passives.forEach((skill) => { skill.beforeAtk(this, target); }); this.action?.use(this, target); //攻击后触发的被动技能 this.passives.forEach((skill) => { skill.afterAtk(this, target); }); //触发攻击目标的反制技能 target.onAttacked(this); //初始化临时状态 this.initTmp(); }; onAttacked = (target: BattleRole) => { //触发反制技能 this.passives.forEach((skill) => { skill.onAtked(this, target); }); }; battleLog = (log: string) => { this.commit('set_sys_info', { type: 'battle', msg: log }); }; addHp = (hp: number) => { if (hp < 0 && this.shield > 0) { if (this.shield > -1 * hp) { this.shield += hp; return; } else { hp += this.shield; this.shield = 0; } } if (this.type == 'player') { this.commit('add_player_curhp', hp); } else { this.attr.curHp += hp; } }; getBootys = (target: BattleRole) => { //战斗结束后触发的技能 this.passives.forEach((skill) => { skill.afterBattle(this, target); }); const equips = randonBootyEquip(target.attr); const coins = target.attr.coins; return { equips: equips, coins: coins }; }; isDeath = () => { return this.attr.curHp <= 0; }; callDmg = (target: BattleRole) => { if (this.control > 0) { const log = replace(t('skill.control.3'), [t(this.type), this.control]); this.battleLog(log); this.control--; return; } const attr = this.attr; const extra = this.extraAttr; const baseAtk = attr.baseAtk + extra.baseAtk; const atkPercent = 1 + (attr.atkPercent + extra.atkPercent) / 100; const dmgPercent = (1 + attr.dmgPercent / 100) * (1 + extra.dmgPercent / 100); let dmg = baseAtk * atkPercent * dmgPercent; const reducPercent = callReducPercent(target.attr.def + target.extraAttr.def); dmg = dmg * (1 - reducPercent) * (1 - target.attr.dmgReduc / 100) - target.attr.bloc; this.crit = Math.random() < (attr.crit - target.attr.critAvoid) / 100; if (this.crit) { let critDmg = attr.critDmg - target.attr.critDmgReduc; critDmg < 100 ? 100 : critDmg; dmg *= critDmg / 100; } dmg = dmg <= 0 ? 1 : dmg; this.dmg = Math.ceil(dmg); }; } export const createBattleRole = (player: Player, monster: Monster, commit) => { const playerRole = new BattleRole(player.attribute, commit, 'player'); const palyerEquips = [player.weapon, player.armor, player.neck, player.ring, player.jewelry, player.pants, player.shoes, player.bracers]; palyerEquips.forEach((equip) => { equip && playerRole.addSkill(equip.base.skill); }); monster = deepCopy(monster); monster.curHp = monster.hp; const monsterRole = new BattleRole(monster, commit, monster.type); return { player: playerRole, monster: monsterRole }; }; /** * 初始化装备技能 * @param equip 装备 * @returns */ export const createEquipSkill = (equip): Skills.Skill[] => { if (!equip) { return []; } return createSkill(equip.base.skill, equip.lv); }; /** * 初始化技能 * @param skillName 技能名称 * @returns */ export const createSkill = (skillName, lv): Skills.Skill[] => { const skills: Skills.Skill[] = new Array(); if (!skillName) { return skills; } const names: string[] = skillName.split(','); names.forEach((name) => { const clazz = Skills[name]; if (clazz) { const skill: Skills.Skill = new clazz(); skill.lv = lv; skills.push(skill); } }); return skills; };