You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
211 lines
6.1 KiB
211 lines
6.1 KiB
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; |
|
skillPercent: number = 100; |
|
|
|
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); |
|
this.skillPercent = 100; |
|
}; |
|
|
|
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.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; |
|
}; |
|
|
|
/** |
|
* |
|
* @param skillPercent 技能伤害倍率 |
|
* @param target 被攻击目标 |
|
* @returns |
|
*/ |
|
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 * (this.skillPercent / 100); //造成伤害 |
|
const reducPercent = callReducPercent(target.attr.def + target.extraAttr.def); //目标防御提供的伤害减免 |
|
const takeDmgPercent = (1 - reducPercent) * (1 - target.attr.dmgReduc / 100) * (1 - target.extraAttr.dmgReduc / 100); //目标承受伤害比例 |
|
const bloc = target.attr.bloc + target.extraAttr.bloc; //目标格挡值 |
|
dmg = dmg * takeDmgPercent - bloc; //目标承受伤害 |
|
const crit = attr.crit + extra.crit - target.attr.critAvoid - target.extraAttr.critAvoid; //最终暴击率 |
|
this.crit = Math.random() < crit / 100; |
|
if (this.crit) { |
|
let critDmg = attr.critDmg + extra.critDmg - target.attr.critDmgReduc - target.extraAttr.critDmg; //目标最终承受暴击伤害 |
|
critDmg < 100 ? 100 : critDmg; //暴击伤害不低于100% |
|
dmg *= critDmg / 100; //暴击时目标承受伤害 |
|
} |
|
dmg = dmg <= 0 ? 1 : dmg; //最低造成1点伤害 |
|
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; |
|
};
|
|
|