249 lines
9.0 KiB
TypeScript
249 lines
9.0 KiB
TypeScript
import { ABI_STAGE, ABI_STAGE_TO_TYPE, ABI_TYPE, ABI_TYPE_MAIN, HERO_CE_RATIO, HERO_SYSTEM_TYPE, SEID_TYPE } from "../../consts";
|
||
import { HeroModel, HeroUpdate, CeAttrData } from "../../db/Hero";
|
||
import { CeAttrDataRole, RoleUpdate } from "../../db/Role";
|
||
import { gameData, getHeroStarByQuality, getHeroWakeByQuality } from "../../pubUtils/data";
|
||
import { DicRandomEffectPool } from "../../pubUtils/dictionary/DicRandomEffectPool";
|
||
import { DicSe } from "../../pubUtils/dictionary/DicSe";
|
||
import { deepCopy } from "../../pubUtils/util";
|
||
import { AttributeCal } from "./attribute";
|
||
|
||
export class CalRoleCe {
|
||
private roleInfo: RoleUpdate;
|
||
private roleCeWithAttr: Map<ABI_TYPE, CeAttrDataRole> = new Map();
|
||
|
||
constructor(roleInfo?: RoleUpdate) {
|
||
this.roleInfo = roleInfo;
|
||
}
|
||
|
||
public cal(type: HERO_SYSTEM_TYPE) {
|
||
switch (type) {
|
||
case HERO_SYSTEM_TYPE.INIT:
|
||
this.calTitleAbility();
|
||
this.calTeraphMainAttr();
|
||
break;
|
||
}
|
||
return this.getRoleAttr();
|
||
}
|
||
|
||
private calTitleAbility() {
|
||
let { title } = this.roleInfo;
|
||
|
||
let dicTitle = gameData.title.get(title)||{ mainAttrValue: new Map(), assiAttrValue: new Map() };
|
||
|
||
for (let i = ABI_TYPE.ABI_HP; i < ABI_TYPE.ABI_MAX; i++) {
|
||
if (dicTitle.mainAttrValue.has(i)) {
|
||
let fixUp = dicTitle.mainAttrValue.get(i) || 0;
|
||
this.getSingleAttrObj(i).updateAttr({ inc: { fixUp } });
|
||
}
|
||
if (dicTitle.assiAttrValue.has(i)) {
|
||
let fixUp = dicTitle.assiAttrValue.get(i) || 0;
|
||
this.getSingleAttrObj(i).updateAttr({ inc: { fixUp } });
|
||
}
|
||
}
|
||
}
|
||
|
||
private calTeraphMainAttr(id?: number) {
|
||
let { teraphs = [] } = this.roleInfo;
|
||
for(let teraph of teraphs) {
|
||
if(id == undefined || teraph.id == id) {
|
||
for(let [attrId, val] of teraph.attr) {
|
||
this.getSingleAttrObj(attrId).updateAttr({ inc: { fixUp: val } });
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
// 获取一个CeAttrData对象,没有就新建
|
||
public getSingleAttrObj(attrId: ABI_TYPE) {
|
||
if(!this.roleCeWithAttr.has(attrId)) {
|
||
let calSingleAttr = new CeAttrDataRole(attrId);
|
||
this.roleCeWithAttr.set(attrId, calSingleAttr);
|
||
}
|
||
return this.roleCeWithAttr.get(attrId);
|
||
}
|
||
|
||
private getRoleAttr() {
|
||
let attr: CeAttrDataRole[] = [];
|
||
this.roleCeWithAttr.forEach(value => {
|
||
if(value.ratioUp > 0 || value.fixUp > 0) {
|
||
attr.push(value);
|
||
}
|
||
});
|
||
return attr;
|
||
}
|
||
}
|
||
|
||
export class CalHeroCe {
|
||
private hid: number;
|
||
private heroInfo: HeroUpdate;
|
||
private heroCeWithAttr: Map<ABI_TYPE, CeAttrData> = new Map();
|
||
|
||
constructor(hid: number, heroInfo?: HeroUpdate) {
|
||
this.hid = hid;
|
||
if(heroInfo) this.heroInfo = heroInfo;
|
||
}
|
||
|
||
public async setHeroInfoByHid(roleId: string) {
|
||
let hero = await HeroModel.findByHidAndRole(this.hid, roleId);
|
||
this.heroInfo = hero;
|
||
}
|
||
|
||
// 主要接口
|
||
public cal(type: HERO_SYSTEM_TYPE) {
|
||
switch (type) {
|
||
case HERO_SYSTEM_TYPE.INIT:
|
||
this.calBaseAbility();
|
||
this.calSkinSeid();
|
||
this.calJobAbility();
|
||
break;
|
||
}
|
||
return this.getHeroAttr()
|
||
}
|
||
|
||
// 计算基础属性
|
||
private calBaseAbility() {
|
||
let { star, starStage, quality, colorStar, colorStarStage, lv, skinId } = this.heroInfo;
|
||
const dicHero = gameData.hero.get(skinId);
|
||
if(!dicHero) {
|
||
console.error(`not found hero: ${skinId}`);
|
||
return;
|
||
}
|
||
|
||
for (let stage = ABI_STAGE.START + 1; stage <= ABI_STAGE.END; stage++) {
|
||
let attrId = ABI_STAGE_TO_TYPE.get(stage);
|
||
|
||
const isWake = colorStar > 0; // 是否觉醒,只要激活了觉醒,彩星就会 > 1
|
||
// console.log('*isUpstar', isUpStar, originStar, star, originColorStar, colorStar)
|
||
|
||
const dicStar = isWake ? getHeroWakeByQuality(dicHero.jobClass, dicHero.quality, colorStarStage < stage? colorStar - 1: colorStar) : getHeroStarByQuality(dicHero.jobClass, quality, starStage < stage? star - 1: star); // 星级表
|
||
|
||
let heroAttr = dicHero.baseAbilityArr.get(attrId); // 武将表hp等
|
||
let heroUpAttr = dicHero.baseAbilityUpArr.get(attrId); // 武将表hp_up等
|
||
let starUp = 0; // 星级成长
|
||
if (!!dicStar && !!dicStar.ceAttr) {
|
||
starUp = dicStar.ceAttr.get(stage);
|
||
}
|
||
let base = heroAttr + lv * (heroUpAttr + starUp);
|
||
this.getSingleAttrObj(attrId).updateAttr({ set: { base } });
|
||
};
|
||
}
|
||
|
||
// 计算职业属性
|
||
private calJobAbility() {
|
||
let { job, jobStage } = this.heroInfo;
|
||
|
||
const dicJob = gameData.job.get(job);
|
||
for(let i = 1; i <= dicJob.maxStage; i++) {
|
||
if(jobStage >= i) {
|
||
let { id, attr } = dicJob.ceAttr.get(i);
|
||
this.getSingleAttrObj(id).updateAttr({ inc: { fixUp: attr } });
|
||
}
|
||
}
|
||
addSeidEffect.bind(this, dicJob.seid);
|
||
}
|
||
|
||
|
||
// 计算皮肤属性
|
||
private calSkinSeid() {
|
||
let { skinId, star: _star, colorStar: _colorStar } = this.heroInfo;
|
||
|
||
let seidList = new Map<number, number>(); // type => seid
|
||
let dicHero = gameData.hero.get(skinId);
|
||
let { starSeidArr, colorStarSeidArr } = gameData.heroSkill.get(dicHero.skill);
|
||
for (let { star, value, type } of starSeidArr) {
|
||
if (_star >= star) {
|
||
seidList.set(type, value);
|
||
}
|
||
}
|
||
for (let { star, value, type } of colorStarSeidArr) {
|
||
if (_colorStar >= star) {
|
||
seidList.set(type, value);
|
||
}
|
||
}
|
||
let list: number[] = [];
|
||
for(let [_type, value] of seidList) list.push(value);
|
||
addSeidEffect.bind(this, list);
|
||
}
|
||
|
||
public getHeroAttr() {
|
||
let attr: CeAttrData[] = [];
|
||
this.heroCeWithAttr.forEach(value => {
|
||
if(value.base > 0 || value.equipUp > 0 || value.fixUp > 0 || value.ratioUp > 0) {
|
||
attr.push(value);
|
||
}
|
||
});
|
||
return attr;
|
||
}
|
||
|
||
// 获取一个CeAttrData对象,没有就新建
|
||
public getSingleAttrObj(attrId: ABI_TYPE) {
|
||
if(!this.heroCeWithAttr.has(attrId)) {
|
||
let calSingleAttr = new CeAttrData(attrId);
|
||
this.heroCeWithAttr.set(attrId, calSingleAttr);
|
||
}
|
||
return this.heroCeWithAttr.get(attrId);
|
||
}
|
||
|
||
public getCalculatedCe(roleAttr: CeAttrDataRole[]) {
|
||
let attrCal = new AttributeCal();
|
||
attrCal.setLv(this.heroInfo.lv);
|
||
attrCal.setByDbData(roleAttr, this.getHeroAttr());
|
||
return attrCal.calCe();
|
||
}
|
||
}
|
||
|
||
// 添加技能增加的被动属性
|
||
function addSeidEffect(this: CalRoleCe|CalHeroCe, seidList: number[]) {
|
||
// console.log('******addSeidEffect',this, seidList)
|
||
|
||
// console.log('addSeidList', addSeidList.join())
|
||
// console.log('removeSeidList', removeSeidList.join())
|
||
let effectList: DicSe[] = []; // any: dic_zyz_se表内容
|
||
|
||
for (let ii = 0; ii < seidList.length; ii += 2) {
|
||
let seid = seidList[ii];
|
||
let rand = seidList[ii + 1] || 0;
|
||
let dicSeid: DicSe | DicRandomEffectPool = gameData.se.get(seid);
|
||
if (!dicSeid) dicSeid = gameData.randomEffectPool.get(seid);
|
||
if (dicSeid && dicSeid.id > 0) {
|
||
addSeid(effectList, dicSeid.id, rand, dicSeid.gainValueArr)
|
||
}
|
||
}
|
||
|
||
// console.log('effectList', JSON.stringify(effectList));
|
||
for (let { type, gainValueArr: [ability, value] } of effectList) {
|
||
if (type == SEID_TYPE.TYPE101) { // 加值
|
||
this.getSingleAttrObj(ability).updateAttr({ inc: { fixUp: value } });
|
||
} else if (type == SEID_TYPE.TYPE103) { // 主属性加百分比
|
||
if(ABI_TYPE_MAIN.includes(ability)) {
|
||
this.getSingleAttrObj(ability).updateAttr({ inc: {ratioUp: value / 1000} });
|
||
}
|
||
} else if (type == SEID_TYPE.TYPE104) { // 次级属性加百分比
|
||
if(!ABI_TYPE_MAIN.includes(ability)) {
|
||
this.getSingleAttrObj(ability).updateAttr({ inc: { fixUp: value * 100 * HERO_CE_RATIO } });
|
||
}
|
||
}
|
||
|
||
}
|
||
|
||
}
|
||
|
||
// 获取dic_zyz_se内容
|
||
function addSeid(effectList: (DicSe | DicRandomEffectPool)[], seidId: number, rand: number, seidValue: number[] = []) {
|
||
let curSeid: DicSe | DicRandomEffectPool = gameData.se.get(seidId);
|
||
if (!curSeid) curSeid = gameData.randomEffectPool.get(seidId);
|
||
if (!curSeid) { console.log("seidId not found:" + seidId); return; }
|
||
if (!seidValue) seidValue = curSeid.gainValueArr;
|
||
|
||
if (curSeid.type === SEID_TYPE.TYPE999) {
|
||
for (let i = 0; i < seidValue.length; i++) {
|
||
addSeid(effectList, seidValue[i], rand);
|
||
}
|
||
return;
|
||
}
|
||
let seid: DicSe | DicRandomEffectPool = deepCopy(curSeid);
|
||
if (curSeid.index > 0) {
|
||
seid.gainValueArr[curSeid.index - 1] = rand;
|
||
}
|
||
effectList.push(seid);
|
||
} |