Files
ZYZ/shared/pubUtils/playerCe.ts
2022-03-22 20:46:17 +08:00

1156 lines
46 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
/**
* 体力系统
*/
import { HERO_SYSTEM_TYPE, ABI_TYPE, HERO_CE_RATIO, LINEUP_NUM, TALENT_RELATION_TYPE } from '../consts';
import { cal, deepCopy, getAllAttrStage, reduceCe } from './util';
import { HeroModel, HeroType, HeroUpdate, CeAttrData, EPlace, Stone, Talent } from '../db/Hero';
import { RoleModel, RoleType, RoleUpdate, CeAttrDataRole } from '../db/Role';
import { AttributeCal } from '../domain/roleField/attribute';
import { ABI_STAGE, SEID_TYPE } from '../consts';
import { gameData, getJobByGradeAndClass, getHeroWakeByQuality, getHeroStarByQuality, getFriendShipById, getSchoolRateByStar, getScollByStar, getTeraph, getEquipQualityIdByEquipIdAndPoint, getEquipSuitByHero, getEquipStarAttrByStage, getJewelConditionByLvAndSeId } from './data';
import { DicSe } from './dictionary/DicSe';
import { DicRandomEffectPool } from './dictionary/DicRandomEffectPool';
import { SchoolModel } from '../db/School';
import { ABI_TYPE_MAIN, ABI_JOB_STAGE, ABI_STAGE_TO_TYPE } from '../consts/constModules/abilityConst'
import { PvpDefenseModel } from '../db/PvpDefense';
import { findIndex } from 'underscore';
import { GuildModel } from '../db/Guild';
import { DicJob } from './dictionary/DicJob';
import { saveCeChangeLog } from './logUtil';
import { JewelType } from '../db/Jewel';
import { type } from 'os';
// 修改并下发战力
export async function calPlayerCeAndSave(type: number, roleId: string, originHero: HeroType, update: HeroUpdate, args?: Array<number>, params?: any) {
let role = await RoleModel.findByRoleId(roleId);
let { attr: roleAttrs = [], serverId } = role;
let heroAttrs = await calPlayerCe(originHero, update, type, args, params); // 根据操作计算attr的增加
let newAttr = new AttributeCal();
newAttr.setLv(update.lv||originHero.lv);
newAttr.setByDbData(roleAttrs, heroAttrs);
let heroCe = newAttr.calCe(); // 计算最终战力
let incCe = heroCe - originHero.ce;
// 更新到武将
update.attr = heroAttrs;
update.ce = heroCe;
if (originHero.historyCe < heroCe) update.historyCe = heroCe;
let hero = await HeroModel.updateHeroInfo(roleId, originHero.hid, update, null, true); // 更新武将 返回是战力缩过的
// 更新到角色
let { topLineup, topLineupCe } = await calculatetopLineup(role, originHero.hid, heroCe, originHero._id); // 计算更新最强五人战力
role = await RoleModel.updateRoleInfo(roleId, { ce: role.ce + incCe, topLineup, topLineupCe });
await PvpDefenseModel.updateCe(roleId, originHero.hid, reduceCe(incCe)); // 更新pvp防守阵战力
let guild = await GuildModel.updateCe(roleId, incCe); // 公会更新战力
let pushHeros = new Array<{ hid: number, ce: number, incHeroCe: number }>();
pushHeros.push({
hid: originHero.hid,
ce: reduceCe(heroCe),
incHeroCe: reduceCe(incCe),
});
saveCeChangeLog(role, incCe, role.ce, type, [originHero.hid]);
return { pushHeros, role, topLineupCe, hero, guild, serverId }
}
//全局属性加成
export async function reCalAllHeroCe(type: number, roleId: string, update: RoleUpdate, args?: Array<number>, params?: any) {
let role = await RoleModel.findByRoleId(roleId);
let heros = await HeroModel.findByRole(roleId);
let roleAttrs = await reCalRoleAttr(type, heros, role, update, args, params);
if(!roleAttrs) return {role, pushHeros: [], ce: role.ce, topLineupCe: role.topLineupCe, serverId: role.serverId, heros }; // 无加成
let pushHeros = new Array<{ hid: number, ce: number, incHeroCe: number }>();
let allIncCe = 0;
let resultHeroes = [];
for (let hero of heros) {
let { attr: heroAttrs, lv } = hero;
let newAttr = new AttributeCal();
newAttr.setLv(lv);
newAttr.setByDbData(roleAttrs, heroAttrs);
let heroCe = newAttr.calCe(); // 计算最终战力
if(heroCe != hero.ce) {
let incHeroCe = heroCe - hero.ce;
allIncCe += incHeroCe;
pushHeros.push({ hid: hero.hid, ce: reduceCe(heroCe), incHeroCe: reduceCe(incHeroCe) });
let resultHero = await HeroModel.updateHeroInfo(roleId, hero.hid, { ce: heroCe });
resultHeroes.push(resultHero);
await PvpDefenseModel.updateCe(roleId, hero.hid, reduceCe(incHeroCe)); // 更新pvp防守阵战力
} else {
resultHeroes.push(hero);
}
}
let { topLineup, topLineupCe } = await calculatetopLineup(role); // 计算更新最强五人战力
if(allIncCe != 0) {
update.attr = roleAttrs;
update.topLineup = topLineup;
update.topLineupCe = topLineupCe;
}
// console.log('************ roleAttr', update.attr)
role = await RoleModel.incRoleInfo(roleId, { ce: allIncCe },update);
let guild = await GuildModel.updateCe(roleId, allIncCe); // 公会更新战力
saveCeChangeLog(role, allIncCe, role.ce, type, args);
return { role, pushHeros, ce: role.ce, topLineupCe: role.topLineupCe, guild, serverId: role.serverId, heros: resultHeroes }
}
// 计算武将全局战力
async function reCalRoleAttr(type: number, heros: Array<HeroType>, role: RoleType, update: RoleUpdate, args: Array<number>, params: any) {
let { attr: roleAttrs } = role;
switch (type) {
case HERO_SYSTEM_TYPE.ADD_SKIN:
roleAttrs = calHeroAddSkin(role, args);
break;
case HERO_SYSTEM_TYPE.SCHOOL:
roleAttrs = calSchoolAddAttr(role, heros, args[0], args[1], args[2]);
break;
case HERO_SYSTEM_TYPE.SCROLL:
roleAttrs = calScrollAddAttr(role, heros, args[0]);
break;
case HERO_SYSTEM_TYPE.STAR:
case HERO_SYSTEM_TYPE.COLORSTAR:
case HERO_SYSTEM_TYPE.QUALITY:
roleAttrs = await calSchoolStarIncAttr(role, heros, type, args[0], args[1]);
break;
case HERO_SYSTEM_TYPE.TITLE:
roleAttrs = calTitle(role, update);
break;
case HERO_SYSTEM_TYPE.TERAPH:
roleAttrs = calTeraphMainAttr(role, update, args[0]);
break;
case HERO_SYSTEM_TYPE.TERAPH_UP:
roleAttrs = calTeraphAssistAttr(role, update, args[0]);
break;
case HERO_SYSTEM_TYPE.REBIRTH:
roleAttrs = await calHeroRebirth(role, params.originHero, params.heroUpdate);
break;
}
return roleAttrs;
}
// 计算单个武将战力
export async function calPlayerCe(hero: HeroType, update: HeroUpdate, type: number, args: Array<number> = [], params) {
let heroAttrs: CeAttrData[] = []; // {"hp": {"base": number, "fixUp": number, "ratioUp": number}}
let addSeidList = new Array<number>();
let removeSeidList = new Array<number>();
switch (type) {
case HERO_SYSTEM_TYPE.STAR:
case HERO_SYSTEM_TYPE.LVUP:
case HERO_SYSTEM_TYPE.COLORSTAR:
case HERO_SYSTEM_TYPE.QUALITY:
heroAttrs = calHeroStarIncAttr(hero, update, type, addSeidList, removeSeidList); // args: 升的星盘
break;
case HERO_SYSTEM_TYPE.TRAIN:
heroAttrs = calHeroTrainIncAttr(hero, update);
break;
case HERO_SYSTEM_TYPE.STAGEUP:
// heroAttrs = calHeroJobStageUpIncAttr(hero, update, addSeidList, removeSeidList);
break;
case HERO_SYSTEM_TYPE.SKIN:
heroAttrs = calHeroWearSkinIncAttr(hero, update, addSeidList, removeSeidList);
break;
case HERO_SYSTEM_TYPE.FAVOUR:
heroAttrs = calHeroFavourUpIncAttr(hero, update);
break;
case HERO_SYSTEM_TYPE.CONNECT:
heroAttrs = calHeroConectIncAttr(hero, update, args[0]);
break;
case HERO_SYSTEM_TYPE.COMPOSE_EQUIP:
heroAttrs = calComposeEquipIncAttr(hero, update, args[0]);
break;
case HERO_SYSTEM_TYPE.EQUIP_STRENGTH:
heroAttrs = calEquipStrengthIncAttr(hero, update, args);
break;
case HERO_SYSTEM_TYPE.EQUIP_QUALITY:
heroAttrs = calEquipQualityIncAttr(hero, update, args);
break;
case HERO_SYSTEM_TYPE.EQUIP_STAR:
heroAttrs = calEquipStarIncAttr(hero, update, args, addSeidList, removeSeidList);
break;
case HERO_SYSTEM_TYPE.EQUIP_JEWEL:
heroAttrs = calEquipPutOnOrOffJewelIncAttr(hero, update, args, params, addSeidList, removeSeidList);
break;
case HERO_SYSTEM_TYPE.EQUIP_STONE:
heroAttrs = calEquipPutOnOrOffStoneIncAttr(hero, update, args, params, addSeidList, removeSeidList);
break;
case HERO_SYSTEM_TYPE.JEWEL_RESET_RANDSE:
case HERO_SYSTEM_TYPE.JEWEL_QUENCH:
heroAttrs = calJewelResetRandSeIncAttr(hero, args, params, addSeidList, removeSeidList);
break;
case HERO_SYSTEM_TYPE.SCROLL:
heroAttrs = calHeroCeScrollIncAttr(hero, update);
break;
case HERO_SYSTEM_TYPE.TALENT:
heroAttrs = calHeroTalent(hero, update, addSeidList, removeSeidList);
break;
default:
break;
}
addSeidEffect(heroAttrs, addSeidList, removeSeidList); // 处理加值
return heroAttrs;
}
/**
* 计算最强阵容战力
* @param role
* @param hid
* @param ce
* @param heroId
*/
export async function calculatetopLineup(role: RoleType, hid?: number, ce?: number, heroId?: string) {
let topLineup = role?.topLineup || new Array();
if(!hid) { // 直接重新排
let heroes = await HeroModel.getTopHero(role.roleId, LINEUP_NUM);
topLineup = heroes.map(cur => { return { hid: cur.hid, ce: cur.ce, hero: cur._id } });
} else {
topLineup.sort((a, b) => { return b.ce - a.ce }); // 0-6最大-最小
let index = topLineup.findIndex(cur => cur.hid == hid);
if(index != -1 && !heroId) {
let heroes = await HeroModel.getTopHero(role.roleId, LINEUP_NUM);
topLineup = heroes.map(cur => { return { hid: cur.hid, ce: cur.ce, hero: cur._id } });
} else {
if (index == -1) { // 不在最强列表
if (topLineup.length < LINEUP_NUM) { // 不满6人
topLineup.push({ hid, ce, hero: heroId });
} else if (topLineup.length == LINEUP_NUM) {
if (ce > topLineup[topLineup.length - 1].ce) { // 跻身最强6人
topLineup.pop();
topLineup.push({ hid, ce, hero: heroId });
}
} else {
topLineup.splice(LINEUP_NUM, topLineup.length - LINEUP_NUM);
}
} else { // 原来就是最强6人
if (ce < topLineup[topLineup.length - 1].ce) { // 滑出最强
let heroes = await HeroModel.getTopHero(role.roleId, LINEUP_NUM);
topLineup = heroes.map(cur => { return { hid: cur.hid, ce: cur.ce, hero: cur._id } });
} else {
topLineup[index].ce = ce;
}
}
}
}
let topLineupCe = topLineup.reduce((pre, cur) => {
return pre + cur.ce
}, 0);
return { topLineup, topLineupCe };
}
/**
* 添加皮肤全局加成
* @param args
* @param ceAttr
*/
function calHeroAddSkin(role: RoleType, skinIds: Array<number>) {
let { attr: roleAttrs } = role;
for (let id of skinIds) {
let addSkin = gameData.fashion.get(id);
for (let attr of addSkin.globalAttr) {
let fixUp = attr.number * HERO_CE_RATIO;
updateRoleAttr(roleAttrs, attr.id, { inc: { fixUp } });
}
}
role.attr = roleAttrs;
return roleAttrs;
}
/**
* 升星觉醒升品等
* @param {HeroType} hero 武将更新前的值
* @param {HeroUpdate} update 更新的值
* @param {number} type 养成类型
* @param {number[]} addSeidList 用于更新被动
* @param {number[]} removeSeidList 用于更新被动
*/
export function calHeroStarIncAttr(originHero: HeroType, update: HeroUpdate, type: number, addSeidList: Array<number>, removeSeidList: Array<number>) {
let { star: originStar, starStage: originStarStage, quality: originQuality, colorStar: originColorStar, colorStarStage: originColorStarStage, attr: heroAttrs, skinId: originSkinId, lv: oldLv } = originHero;
let { star = originStar, starStage = originStarStage, quality = originQuality, colorStar = originColorStar, colorStarStage = originColorStarStage, skinId = originSkinId, lv = oldLv } = update;
const dicHero = gameData.hero.get(skinId);
const isWake = colorStar > 0; // 是否觉醒,只要激活了觉醒,彩星就会 > 1
const isFirstWake = colorStar > 0 && originColorStar <= 0; // 是否是初次觉醒
const isUpStar = originStar != star || originColorStar != colorStar; // 是否有升星
// console.log('*isUpstar', isUpStar, originStar, star, originColorStar, colorStar)
if(starStage == ABI_STAGE.START) star--;
if(colorStarStage == ABI_STAGE.START) colorStar--;
const dicStar = isWake ? getHeroWakeByQuality(dicHero.jobClass, dicHero.quality, colorStar) : getHeroStarByQuality(dicHero.jobClass, quality, star); // 星级表
let stages = new Array<number>(); // 需要升级的阶
if (type == HERO_SYSTEM_TYPE.LVUP) {
stages = getAllAttrStage();
} else if (type == HERO_SYSTEM_TYPE.STAR) {
let end = isUpStar? ABI_STAGE.END: starStage;
if(end < originStarStage) {
stages = getAllAttrStage();
} else {
for(let i = originStarStage; i < end; i++) {
stages.push(i + 1);
}
}
} else if (type == HERO_SYSTEM_TYPE.QUALITY) {
stages = getAllAttrStage();
} else if (type = HERO_SYSTEM_TYPE.COLORSTAR) {
if (isFirstWake) { // 首次觉醒
stages = getAllAttrStage();
} else {
let end = isUpStar? ABI_STAGE.END: colorStarStage;
if(end < originColorStarStage) {
stages = getAllAttrStage();
} else {
for(let i = originColorStarStage; i < end; i++) {
stages.push(i + 1);
}
}
}
} else if (type == HERO_SYSTEM_TYPE.SKIN) {
stages = getAllAttrStage();
}
for (let stage of stages) {
let targetAttrId = ABI_STAGE_TO_TYPE.get(stage); // 转换为18维的属性id
let heroAttr = dicHero.baseAbilityArr.get(targetAttrId); // 武将表hp等
let heroUpAttr = dicHero.baseAbilityUpArr.get(targetAttrId); // 武将表hp_up等
let starUp = 0; // 星级成长
if (!!dicStar && !!dicStar.ceAttr) {
starUp = dicStar.ceAttr.get(stage);
}
let newBase = (heroAttr + lv * (heroUpAttr + starUp)) * HERO_CE_RATIO;
updateHeroAttr(heroAttrs, targetAttrId, { set: { base: newBase } });
}
let curSeidList = getSeidListOfFashion(skinId, star, colorStar);
let preSeidList = getSeidListOfFashion(originSkinId, originStar, originColorStar);
curSeidList.forEach((seid, type) => {
if (!preSeidList.has(type)) {
addSeidList.push(seid, 0);
}
});
preSeidList.forEach((seid, type) => {
if (!curSeidList.has(type)) {
removeSeidList.push(seid, 0);
}
});
originHero.attr = heroAttrs;
return heroAttrs;//属性增量可以是多个
}
type updateCeAttr = Partial<CeAttrData>;
function updateHeroAttr(heroAttrs: CeAttrData[], id: number, update: { inc?: updateCeAttr, set?: updateCeAttr }) {
let index = heroAttrs.findIndex(cur => cur.id == id);
let curAttr = heroAttrs[index];
if(!curAttr) {
curAttr = new CeAttrData(id);
heroAttrs.push(curAttr);
index = heroAttrs.length - 1;
}
if(update.inc) {
let { base, equipUp, fixUp, ratioUp } = update.inc;
if(base != undefined) curAttr.base += base;
if(equipUp != undefined) curAttr.equipUp += equipUp;
if(fixUp != undefined) curAttr.fixUp += fixUp;
if(ratioUp != undefined) curAttr.ratioUp += ratioUp;
}
if(update.set) {
let { base, equipUp, fixUp, ratioUp } = update.set;
if(base != undefined) curAttr.base = base;
if(equipUp != undefined) curAttr.equipUp = equipUp;
if(fixUp != undefined) curAttr.fixUp = fixUp;
if(ratioUp != undefined) curAttr.ratioUp = ratioUp;
}
if(curAttr.base <= 0 && curAttr.equipUp <=0 && curAttr.fixUp <=0 && curAttr.ratioUp <= 0) {
heroAttrs.splice(index, 1);
}
}
type updateCeAttrRole = Partial<CeAttrDataRole>;
function updateRoleAttr(roleAttrs: CeAttrDataRole[], id: number, update: { inc?: updateCeAttrRole, set?: updateCeAttrRole }) {
let curAttr = roleAttrs.find(cur => cur.id == id);
if(!curAttr) {
curAttr = new CeAttrDataRole(id);
roleAttrs.push(curAttr);
}
if(update.inc) {
let { fixUp, ratioUp } = update.inc;
if(fixUp) curAttr.fixUp = cal.add(curAttr.fixUp, fixUp);
if(ratioUp) curAttr.ratioUp = cal.add(curAttr.ratioUp, ratioUp);
}
if(update.set) {
let { fixUp, ratioUp } = update.set;
if(fixUp) curAttr.fixUp = fixUp;
if(ratioUp) curAttr.ratioUp = ratioUp;
}
}
/**
* 获取皮肤上的seid
* @param skinId
* @param originStar
* @param originColorStar
*/
function getSeidListOfFashion(skinId: number, originStar: number, originColorStar: number) {
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 (originStar >= star) {
seidList.set(type, value);
}
}
for (let { star, value, type } of colorStarSeidArr) {
if (originColorStar >= star) {
seidList.set(type, value);
}
}
return seidList
}
/**
* 兵种训练
* @param {HeroType} originHero 原始武将
* @param {HeroUpdate} update 更新的数据
*/
export function calHeroTrainIncAttr(originHero: HeroType, update: HeroUpdate) {
let { attr: heroAttrs, job: oldJob, jobStage: oldJobStage } = originHero;
let { job = oldJob, jobStage = oldJobStage } = update;
let dicJob = gameData.job.get(job);
let lastJob = getJobByGradeAndClass(dicJob.job_class, dicJob.grade - 1);
let dicLastJob = lastJob? gameData.job.get(lastJob.jobid): null;
for(let i = 1; i <= dicJob.maxStage; i++) {
if(oldJobStage < i && jobStage >= i) {
let lastAttr = dicLastJob? dicLastJob.ceAttr.get(i).attr: 0;
let targetAttrId = dicJob.ceAttr.get(i).id;
let targetAttrValue = dicJob.ceAttr.get(i).attr;
let inc = (targetAttrValue - lastAttr) * HERO_CE_RATIO;
// console.log('*******', targetAttrId, targetAttrValue, lastAttr, inc )
updateHeroAttr(heroAttrs, targetAttrId, { inc: { fixUp: inc } });
}
}
return heroAttrs;
}
/**
* 兵种进阶
* @param {HeroType} originHero 原始武将
* @param {HeroUpdate} update 更新内容
* @param {number[]} addSeidList 用于更新被动
* @param {number[]} removeSeidList 用于更新被动
*/
// export function calHeroJobStageUpIncAttr(originHero: HeroType, update: HeroUpdate, addSeidList: Array<number>, removeSeidList: Array<number>) {
// let { job: oldJob, attr: heroAttrs } = originHero;
// let { job = oldJob } = update;
// let lastJob = gameData.job.get(oldJob);
// let currentJob = gameData.job.get(job);
// let lastSeids = lastJob?.seid||new Array<number>();
// let curSeids = currentJob?.seid||new Array<number>();
// for (let seid of curSeids) {
// let index = findIndex(lastSeids, seid);
// if (index < 0) {
// addSeidList.push(seid, 0);
// }
// }
// for (let seid of lastSeids) {
// let index = findIndex(curSeids, seid);
// if (index < 0) {
// removeSeidList.push(seid, 0);
// }
// }
// return heroAttrs;
// }
/**
* 初始计算兵种属性
* @param {HeroType} originHero 原始武将
* @param {HeroUpdate} hero 更新后的武将
* @param {number[]} addSeidList 用于更新被动
* @param {number[]} removeSeidList 用于更新被动
*/
export function calHeroJobAttr(originHero: HeroType, hero: HeroUpdate, addSeidList: Array<number>, removeSeidList: Array<number>) {
let { attr: heroAttrs } = originHero;
let currentJob = gameData.job.get(hero.job);
let jobGradeAndClass = getJobByGradeAndClass(currentJob.job_class, currentJob.grade - 1);
let lastJob: DicJob;
if (!!jobGradeAndClass) {
lastJob = gameData.job.get(jobGradeAndClass.jobid);
}
for (let stage = ABI_JOB_STAGE.START; stage <= ABI_JOB_STAGE.END; stage++) {
if(hero.jobStage >= stage) {
let targetAttrId = currentJob.ceAttr.get(stage).id;
let fixUp = currentJob.ceAttr.get(stage).attr * HERO_CE_RATIO;
updateHeroAttr(heroAttrs, targetAttrId, { inc: { fixUp }})
} else {
if(lastJob) {
let targetAttrId = lastJob.ceAttr.get(stage).id;
let fixUp = lastJob.ceAttr.get(stage).attr * HERO_CE_RATIO;
updateHeroAttr(heroAttrs, targetAttrId, { inc: { fixUp } });
}
}
};
originHero.attr = heroAttrs;
// heroAttrs = calHeroJobStageUpIncAttr(originHero, hero, addSeidList, removeSeidList);
return heroAttrs;
}
/**
* 穿戴时装的单武将加成
* @param {HeroType} originHero 原始武将
* @param {number} wearSkinId 穿戴的皮肤
* @param {number} pullSkinId 脱下的皮肤
* @param {number[]} addSeidList 用于更新被动
* @param {number[]} removeSeidList 用于更新被动
* @param {boolean} isInit 是否是计算初始战力
*/
export function calHeroWearSkinIncAttr(originHero: HeroType, update: HeroUpdate, addSeidList: number[], removeSeidList: number[]) {
let { attr: heroAttrs, skinId: originSkinId } = originHero;
let { skinId = originSkinId, ePlace: newEplace } = update;
calHeroStarIncAttr(originHero, update, HERO_SYSTEM_TYPE.SKIN, addSeidList, removeSeidList);
let addSkin = gameData.fashionBySkinId.get(skinId);
let delSkin = gameData.fashionBySkinId.get(originSkinId);
if (delSkin) {
for (let attr of delSkin.actorAttr) {
let fixUp = -1 * attr.number * HERO_CE_RATIO;
updateHeroAttr(heroAttrs, attr.id, { inc: { fixUp } });
}
}
for (let attr of addSkin.actorAttr) {
let fixUp = attr.number * HERO_CE_RATIO;
updateHeroAttr(heroAttrs, attr.id, { inc: { fixUp } });
}
originHero.attr = heroAttrs;
let eplaceIds = newEplace.map(cur => cur.id);
calEquipStrengthIncAttr(originHero, update, eplaceIds);
calEquipQualityIncAttr(originHero, update, eplaceIds);
calEquipStarIncAttr(originHero, update, eplaceIds, addSeidList, removeSeidList);
// 天赋点
calHeroTalent(originHero, update, addSeidList, removeSeidList);
return heroAttrs;
}
/**
* 羁绊解锁
* @param {HeroType} originHero 原始武将
* @param {HeroUpdate} update 更新数据
* @param {number} shipId 解锁的那个id
*/
export function calHeroConectIncAttr(originHero: HeroType, update: HeroUpdate, shipId: number) {
let { connections: oldConnections = [], favourLv, attr: heroAttrs } = originHero;
let { connections = oldConnections } = update;
let oldConnect = oldConnections.find(cur => cur.shipId == shipId);
let connect = connections.find(cur => cur.shipId == shipId);
let oldLevel = oldConnect?.level||0;
let level = connect?.level||0;
let fiendShipLevel = gameData.friendShipLevelMap.get(favourLv);
let currentShip = getFriendShipById(shipId, level);
if (currentShip) {
for (let attr of currentShip.attributes) {
let fixUp = attr.number * (HERO_CE_RATIO + fiendShipLevel.add);
updateHeroAttr(heroAttrs, attr.id, { inc: { fixUp } });
}
}
if (level > 1) {
let lastShip = getFriendShipById(shipId, oldLevel);
if (lastShip) {
for (let attr of lastShip.attributes) {
let fixUp = -1 * attr.number * (HERO_CE_RATIO + fiendShipLevel.add);
updateHeroAttr(heroAttrs, attr.id, { inc: { fixUp } })
}
}
}
originHero.attr = heroAttrs;
return heroAttrs;
}
/**
* 好感度升级,影响羁绊加成
*
* @param {HeroType} originHero 原始武将数据
* @param {HeroUpdate} update 更新的数据
*/
export function calHeroFavourUpIncAttr(originHero: HeroType, update: HeroUpdate) {
let { favourLv: oldFavourLv, attr: heroAttrs } = originHero;
let { favourLv = oldFavourLv } = update;
let currentFiendShipLevel = gameData.friendShipLevelMap.get(favourLv);
let difAdd = currentFiendShipLevel.add;
if (oldFavourLv && oldFavourLv > 0) { // 减上一级好感
let lastFiendShipLevel = gameData.friendShipLevelMap.get(oldFavourLv);
difAdd -= lastFiendShipLevel.add;
}
for (let {shipId, level} of originHero.connections) {
let dicHeroFriendShip = getFriendShipById(shipId, level);
for (let attr of dicHeroFriendShip.attributes) {
let fixUp = (attr.number + difAdd ) * HERO_CE_RATIO;
updateHeroAttr(heroAttrs, attr.id, { inc: { fixUp } });
}
}
originHero.attr = heroAttrs;
return heroAttrs;
}
export function calComposeEquipIncAttr(hero: HeroType, update: HeroUpdate, eplaceId: number) {
let { attr: heroAttrs } = hero;
let newEquip = update.ePlace.find(cur => cur.id == eplaceId);
if(newEquip) {
let dicEquip = gameData.equipById.get(newEquip.equipId);
for(let attr of dicEquip.attribute) {
updateHeroAttr(heroAttrs, attr.id, { inc: { fixUp: attr.num * HERO_CE_RATIO } });
}
}
return heroAttrs;
}
export function calEquipStrengthIncAttr(hero: HeroType, update: HeroUpdate, eplaceIds: number[]) {
let { attr: heroAttrs, ePlace: oldEplace } = hero;
let { ePlace: newEplace } = update;
for(let eplaceId of eplaceIds) {
let oldEquip = oldEplace.find(cur => cur.id == eplaceId);
let newEquip = newEplace.find(cur => cur.id == eplaceId);
if(newEquip && oldEquip) {
let dicOldEquip = gameData.equipById.get(oldEquip.equipId);
let dicNewEquip = gameData.equipById.get(newEquip.equipId);
for(let attr of dicOldEquip.attributeUp) {
updateHeroAttr(heroAttrs, attr.id, { inc: { fixUp: -1 * attr.num * oldEquip.lv * HERO_CE_RATIO } });
}
for(let attr of dicNewEquip.attributeUp) {
updateHeroAttr(heroAttrs, attr.id, { inc: { fixUp: attr.num * newEquip.lv * HERO_CE_RATIO } });
}
}
}
hero.attr = heroAttrs;
return heroAttrs
}
export function calEquipQualityIncAttr(hero: HeroType, update: HeroUpdate, eplaceIds: number[]) {
let { attr: heroAttrs, ePlace: oldEplace } = hero;
let { ePlace: newEplace } = update;
for(let eplaceId of eplaceIds) {
let oldEquip = oldEplace.find(cur => cur.id == eplaceId);
let newEquip = newEplace.find(cur => cur.id == eplaceId);
if(newEquip && oldEquip) {
let dicOldEquipQuality = getEquipQualityIdByEquipIdAndPoint(oldEquip.equipId, oldEquip.quality, oldEquip.qualityStage);
let dicNewEquipQuality = getEquipQualityIdByEquipIdAndPoint(newEquip.equipId, newEquip.quality, newEquip.qualityStage);
for(let attr of dicOldEquipQuality.attribute) {
updateHeroAttr(heroAttrs, attr.id, { inc: { fixUp: -1 * attr.num * HERO_CE_RATIO } });
}
for(let attr of dicNewEquipQuality.attribute) {
updateHeroAttr(heroAttrs, attr.id, { inc: { fixUp: attr.num * HERO_CE_RATIO } });
}
}
}
hero.attr = heroAttrs;
return heroAttrs
}
export function calEquipStarIncAttr(hero: HeroType, update: HeroUpdate, eplaceIds: number[], addSeidList: number[], removeSeidList: number[]) {
// 升星本身的属性加成
let { hid, attr: heroAttrs, ePlace: oldEplace } = hero;
let { ePlace: newEplace } = update;
for(let eplaceId of eplaceIds) {
let oldEquip = oldEplace.find(cur => cur.id == eplaceId);
let newEquip = newEplace.find(cur => cur.id == eplaceId);
if(newEquip && oldEquip) {
let { mainAttr: oldMainAttr, subAttr: oldSubAttr } = getEquipStarAttrByStage(oldEquip.equipId, oldEquip.star, oldEquip.starStage);
let { mainAttr: newMainAttr, subAttr: newSubAttr } = getEquipStarAttrByStage(newEquip.equipId, newEquip.star, newEquip.starStage);
// 主属性
for(let attr of oldMainAttr) {
updateHeroAttr(heroAttrs, attr.id, { inc: { fixUp: -1 * attr.num * HERO_CE_RATIO } });
}
for(let attr of newMainAttr) {
updateHeroAttr(heroAttrs, attr.id, { inc: { fixUp: attr.num * HERO_CE_RATIO } });
}
for(let attr of oldSubAttr) {
updateHeroAttr(heroAttrs, attr.id, { inc: { fixUp: -1 * attr.num * HERO_CE_RATIO } });
}
for(let attr of newSubAttr) {
updateHeroAttr(heroAttrs, attr.id, { inc: { fixUp: attr.num * HERO_CE_RATIO } });
}
}
}
// 套装属性
calEquipSuitIncAttr(hid, oldEplace, newEplace, addSeidList, removeSeidList);
hero.attr = heroAttrs;
return heroAttrs;
}
function calEquipSuitIncAttr(hid: number, oldEplace: EPlace[], newEplace: EPlace[], addSeidList: number[], removeSeidList: number[]) {
let dicEquipSuit = getEquipSuitByHero(hid);
let oldSuitStars: number[] = [], newSuitStars: number[] = [];
for(let equipId of dicEquipSuit.equips) {
let oldEquip = oldEplace.find(cur => cur.equipId == equipId);
oldSuitStars.push(oldEquip? oldEquip.star: 0);
let newEquip = newEplace.find(cur => cur.equipId == equipId);
newSuitStars.push(newEquip? newEquip.star: 0);
}
let oldStar = Math.min(...oldSuitStars);
let newStar = Math.min(...newSuitStars);
for(let { star, seid } of dicEquipSuit.effect) {
if(oldStar >= star) removeSeidList.push(seid);
if(newStar >= star) addSeidList.push(seid, 0);
}
}
export function calEquipPutOnOrOffJewelIncAttr(hero: HeroType, update: HeroUpdate, eplaceIds: number[], params: { oldJewel: JewelType, newJewel: JewelType }, addSeidList: number[], removeSeidList: number[]) {
let { attr: heroAttrs, ePlace: oldEplace } = hero;
let { ePlace: newEplace } = update;
for(let eplaceId of eplaceIds) {
let oldEquip = oldEplace.find(cur => cur.id == eplaceId);
setRandSeToSeidList(params.oldJewel, oldEquip, removeSeidList);
let newEquip = newEplace.find(cur => cur.id == eplaceId);
setRandSeToSeidList(params.newJewel, newEquip, addSeidList);
}
return heroAttrs;
}
function setRandSeToSeidList(jewel: JewelType, equip: EPlace, list: number[]) {
if(equip && jewel) {
for(let { id, seid, rand } of jewel.randSe) {
if(isRandSeUnLock(jewel.id, id, equip.stones)) {
list.push(seid, rand);
}
}
}
}
export function isRandSeUnLock(jewelId: number, randSeId: number, stones: Stone[]) {
let dicJewel = gameData.jewel.get(jewelId);
let dicJewelCondition = getJewelConditionByLvAndSeId(dicJewel.lv, randSeId);
let stoneCnt = 0, stoneLv = 0;
for(let { stone } of stones) {
let dicStone = gameData.stone.get(stone);
if(dicStone) {
stoneCnt++;
stoneLv += dicStone.lv;
}
}
return stoneCnt >= dicJewelCondition.stoneCnt && stoneLv >= dicJewelCondition.stoneLv;
}
export function calEquipPutOnOrOffStoneIncAttr(hero: HeroType, update: HeroUpdate, eplaceIds: number[], params: { jewel: JewelType }, addSeidList: number[], removeSeidList: number[]) {
let { attr: heroAttrs, ePlace: oldEplace } = hero;
let { ePlace: newEplace } = update;
for(let eplaceId of eplaceIds) {
let oldEquip = oldEplace.find(cur => cur.id == eplaceId);
updateHeroAttrOfStone(heroAttrs, oldEquip, -1);
setRandSeToSeidList(params.jewel, oldEquip, removeSeidList);
let newEquip = newEplace.find(cur => cur.id == eplaceId);
updateHeroAttrOfStone(heroAttrs, newEquip, 1);
setRandSeToSeidList(params.jewel, newEquip, addSeidList); // 地玉石阶数变化可能导致属性词条解锁变化
}
return heroAttrs;
}
function updateHeroAttrOfStone(heroAttrs: CeAttrData[], equip: EPlace, ratio: number) {
for(let { stone } of equip.stones) {
let dicStone = gameData.stone.get(stone);
if(dicStone) {
for(let attr of dicStone.attribute) {
updateHeroAttr(heroAttrs, attr.id, { inc: { fixUp: ratio * attr.num * HERO_CE_RATIO } });
}
}
}
}
export function calJewelResetRandSeIncAttr(hero: HeroType, eplaceIds: number[], params: { oldJewel: JewelType, newJewel: JewelType }, addSeidList: number[], removeSeidList: number[]) {
let { attr: heroAttrs, ePlace } = hero;
for(let eplaceId of eplaceIds) {
let equip = ePlace.find(cur => cur.id == eplaceId);
setRandSeToSeidList(params.oldJewel, equip, removeSeidList);
setRandSeToSeidList(params.newJewel, equip, addSeidList);
}
return heroAttrs;
}
// 添加技能增加的被动属性
function addSeidEffect(heroAttrs: CeAttrData[], addSeidList: Array<number>, removeSeidList: Array<number>) {
// console.log('addSeidList', addSeidList.join())
// console.log('removeSeidList', removeSeidList.join())
let otiginalSeidList = [
{ list: addSeidList, multi: 1 },
{ list: removeSeidList, multi: -1 }
];
for (let { list, multi } of otiginalSeidList) {
let effectList = new Array<DicSe>(); // any: dic_zyz_se表内容
for (let ii = 0; ii < list.length; ii += 2) {
let seid = list[ii];
let rand = list[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) { // 加值
updateHeroAttr(heroAttrs, ability, { inc: {fixUp: value * multi * HERO_CE_RATIO} });
} else if (type == SEID_TYPE.TYPE103) { // 主属性加百分比
if(ABI_TYPE_MAIN.includes(ability)) {
updateHeroAttr(heroAttrs, ability, { inc: {ratioUp: value / 1000 * multi} });
}
} else if (type == SEID_TYPE.TYPE104) { // 次级属性加百分比
if(!ABI_TYPE_MAIN.includes(ability)) {
updateHeroAttr(heroAttrs, ability, { inc: {fixUp: value * 100 * multi * HERO_CE_RATIO } });
}
}
}
}
}
// 获取dic_zyz_se内容
function addSeid(effectList: Array<any>, seidId: number, rand: number, seidValue = new Array<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);
}
/**
* 全局加成,百家学宫
* @param role 角色
* @param heros 所有武将
* @param schoolId 学宫学派
* @param hid 换上的武将
* @param preHid 撤下的武将
*/
function calSchoolAddAttr(role: RoleType, heros: HeroType[], schoolId: number, hid: number, preHid: number) {
let { attr: roleAttrs } = role;
let school = gameData.school.get(schoolId);
if (!school) return null;
let preHero = heros.find(cur => cur.hid == preHid);
let curHero = heros.find(cur => cur.hid == hid);
let defaultPercent = { mainAttrAPerent: 0, assiAttrAddValue: 0 };
let preRate = preHero ? getSchoolRateByStar(preHero.star, preHero.colorStar, preHero.quality) : defaultPercent;
let curRate = curHero ? getSchoolRateByStar(curHero.star, curHero.colorStar, curHero.quality) : defaultPercent;
for (let attrId of school.upAttribute) {
if(ABI_TYPE_MAIN.includes(attrId)) { // 主属性
let ratioUp = curRate.mainAttrAPerent - preRate.mainAttrAPerent;
updateRoleAttr(roleAttrs, attrId, { inc: { ratioUp } });
} else {
let fixUp = (curRate.assiAttrAddValue - preRate.assiAttrAddValue) * HERO_CE_RATIO;
updateRoleAttr(roleAttrs, attrId, { inc: { fixUp } });
}
}
return roleAttrs;
}
/**
* 升星,觉醒,升品时,百家学宫配置武将会相应修改全局战力
* @param {HeroType[]} heros 全部武将
* @param {number} type 类型 HERO_SYSTEM_TYPE
* @param {number} hid 更新的那个武将
* @param {number} isStarUp 是否升星
*/
async function calSchoolStarIncAttr(role: RoleType, heros: HeroType[], type: number, hid: number, isStarUp: number) {
let { roleId, attr: roleAttrs } = role;
if ((type == HERO_SYSTEM_TYPE.STAR || type == HERO_SYSTEM_TYPE.COLORSTAR) && !isStarUp) {
return null;
}
let hero = heros.find(cur => cur.hid == hid);
if(!hero) return null;
let curHeroInSchool = await SchoolModel.findByHid(roleId, hid);
if (!curHeroInSchool) return null;
let preStar = hero.star, preColorStar = hero.colorStar, preQuality = hero.quality;
if (type == HERO_SYSTEM_TYPE.STAR && isStarUp) {
preStar--;
} else if (type == HERO_SYSTEM_TYPE.QUALITY) {
preQuality--;
} else if (type == HERO_SYSTEM_TYPE.COLORSTAR) {
preColorStar--;
if(preColorStar <= 0) preQuality--;
} else {
return null;
}
let school = gameData.school.get(curHeroInSchool.schoolId);
let preRate = getSchoolRateByStar(preStar, preColorStar, preQuality);
let curRate = getSchoolRateByStar(hero.star, hero.colorStar, hero.quality);
for (let attrId of school.upAttribute) {
if(ABI_TYPE_MAIN.includes(attrId)) { // 主属性
let ratioUp = curRate.mainAttrAPerent - preRate.mainAttrAPerent;
updateRoleAttr(roleAttrs, attrId, { inc: { ratioUp } });
} else {
let fixUp = (curRate.assiAttrAddValue - preRate.assiAttrAddValue) * HERO_CE_RATIO;
updateRoleAttr(roleAttrs, attrId, { inc: { fixUp } });
}
}
return roleAttrs;
}
/**
* 全局加成, 名将谱
* @param heros 所有武将
* @param hid 激活的武将
* @param ceAttr
*/
function calScrollAddAttr(role: RoleType,heros: HeroType[], hid: number) {
let { attr: roleAttrs } = role;
// console.log('********** calScrollAddAttr', hid)
let curHero = heros.find(cur => cur.hid == hid);
let dicHero = gameData.hero.get(hid);
if (!curHero || !dicHero) return roleAttrs;
let { quality } = dicHero;
let { star, quality: curQuality, colorStar } = curHero;
// console.log('********** calScrollAddAttr curHero', star, curQuality, colorStar);
let heroScroll = getScollByStar(quality, star, curQuality, colorStar);
if (!heroScroll) return roleAttrs;
// console.log('********** heroScroll', heroScroll);
let isInit = star == dicHero.initialStars && curQuality == dicHero.quality && colorStar == 0;
let preScroll = isInit? null: gameData.preHeroScroll.get(heroScroll.id);
// console.log('********** preScroll', preScroll);
heroScroll.ceAttr.forEach((add, attrId) => {
let preAdd = preScroll ? preScroll.ceAttr.get(attrId) : 0;
let fixUp = (add - preAdd) * HERO_CE_RATIO;
// console.log('********** preAdd', attrId, preAdd, fixUp);
updateRoleAttr(roleAttrs, attrId, { inc: { fixUp } });
});
return roleAttrs;
}
/**
* 名将谱激活增加单个武将好感
* @param originHero 原始武将
* @param update 更新数据
*/
function calHeroCeScrollIncAttr(originHero: HeroType, update: HeroUpdate) {
let { attr: heroAttrs, favourLv: oldFavourLv } = originHero;
let { favourLv = oldFavourLv } = update;
if (favourLv != oldFavourLv) {
heroAttrs = calHeroFavourUpIncAttr(originHero, update);
}
return heroAttrs;
}
function calHeroTalent(originHero: HeroType, update: HeroUpdate, addSeidList: number[], removeSeidList: number[]) {
let { attr: heroAttrs, skins: oldSkins } = originHero;
let { skins } = update;
let oldSkin = oldSkins.find(cur => cur.enable);
let newSkin = skins.find(cur => cur.enable);
let oldSeids = getTalentSeid(oldSkin.talent);
let newSeids = getTalentSeid(newSkin.talent);
for(let seid of newSeids) addSeidList.push(seid);
for(let seid of oldSeids) removeSeidList.push(seid);
return heroAttrs
}
function getTalentSeid(talent: Talent[]) {
let seids = new Map<number, number[]>(); // id, seids
for(let { id, level } of talent) {
let dicHeroTalent = gameData.heroTalent.get(id);
for(let { type, ids} of dicHeroTalent.relation) {
if(type == TALENT_RELATION_TYPE.REPLACE) {
for(let id of ids) {
seids.delete(id);
}
}
}
for(let { lv, seid } of dicHeroTalent.level) {
if(level >= lv) {
if(!seids.has(id)) seids.set(id, []);
seids.get(id).push(seid);
}
}
}
let result: number[] = [];
for(let [_, ids] of seids) {
result.push(...ids);
}
return result;
}
/**
* 升爵位
* @param role 角色数据
* @param titleId 升到哪个爵位
*/
function calTitle(role: RoleType, update: RoleUpdate) {
let { title: oldTitle, attr: roleAttrs } = role;
let { title: newTitle = oldTitle } = update;
let dicOldTitle = gameData.title.get(oldTitle)||{ mainAttrValue: new Map(), assiAttrValue: new Map() };
let dicNewTitle = gameData.title.get(newTitle);
for (let i = ABI_TYPE.ABI_HP; i < ABI_TYPE.ABI_MAX; i++) {
if (dicNewTitle.mainAttrValue.has(i) || dicOldTitle.mainAttrValue.has(i)) {
let fixUp = ((dicNewTitle.mainAttrValue.get(i) || 0) - (dicOldTitle.mainAttrValue.get(i) || 0)) * HERO_CE_RATIO;
updateRoleAttr(roleAttrs, i, { inc: { fixUp } });
}
if (dicNewTitle.assiAttrValue.has(i) || dicOldTitle.mainAttrValue.has(i)) {
let fixUp = ((dicNewTitle.assiAttrValue.get(i) || 0) - (dicOldTitle.assiAttrValue.get(i) || 0)) * HERO_CE_RATIO;
updateRoleAttr(roleAttrs, i, { inc: { fixUp } });
}
}
return roleAttrs;
}
/**
* 神像强化,更新主属性加成
* @param role 角色数据
* @param update 更新数据
* @param id 更新哪座神像
*/
function calTeraphMainAttr(role: RoleType, update: RoleUpdate, id: number) {
let { attr: roleAttrs, teraphs: oldTeraphs = [] } = role;
let { teraphs = oldTeraphs } = update;
let oldTeraph = oldTeraphs.find(cur => cur.id == id);
let teraph = teraphs.find(cur => cur.id == id);
if(teraph && teraph.attr) {
for(let [attrId, val] of teraph.attr) {
let oldVal = 0;
if(oldTeraph && oldTeraph.attr && oldTeraph.attr.has(attrId)) {
oldVal = oldTeraph.attr.get(attrId);
}
let fixUp = (val - oldVal) * HERO_CE_RATIO;
updateRoleAttr(roleAttrs, attrId, { inc: {fixUp} })
}
}
return roleAttrs;
}
/**
* 神像进阶,更新次级属性加成
* @param role 角色数据
* @param update 更新数据
* @param id 更新哪座神像
*/
function calTeraphAssistAttr(role: RoleType, update: RoleUpdate, id: number) {
let { attr: roleAttrs, teraphs: oldTeraphs = [] } = role;
let { teraphs = oldTeraphs } = update;
let oldTeraph = oldTeraphs.find(cur => cur.id == id);
let teraph = teraphs.find(cur => cur.id == id);
let dicOldTeraph = getTeraph(id, oldTeraph?.grade);
let dicTeraph = getTeraph(id, teraph?.grade);
if(!dicTeraph) return null;
dicTeraph.assiAttrValue.forEach((val, attrId) => {
let oldVal = 0;
if(dicOldTeraph && dicOldTeraph.assiAttrValue && dicOldTeraph.assiAttrValue.has(attrId)) {
oldVal = dicOldTeraph.assiAttrValue.get(attrId);
}
let fixUp = (val - oldVal) * HERO_CE_RATIO;
updateRoleAttr(roleAttrs, attrId, { inc: { fixUp } });
});
return roleAttrs;
}
async function calHeroRebirth(role: RoleType, originHero: HeroType, updateHero: HeroUpdate) {
let { roleId, attr: roleAttrs } = role;
// 1. 名将谱
let dicHero = gameData.hero.get(originHero.hid);
let dicHeroScroll = getScollByStar(dicHero.quality, updateHero.star, updateHero.quality, updateHero.colorStar);
let dicPreScroll = getScollByStar(dicHero.quality, originHero.star, originHero.quality, originHero.colorStar);
if(dicHeroScroll) {
for(let [attrId, value] of dicHeroScroll.ceAttr) {
updateRoleAttr(roleAttrs, attrId, { inc: { fixUp: value * HERO_CE_RATIO } });
}
}
if(dicPreScroll) {
for(let [attrId, value] of dicPreScroll.ceAttr) {
updateRoleAttr(roleAttrs, attrId, { inc: { fixUp: -value * HERO_CE_RATIO } });
}
}
// 2. 百家学宫
let school = await SchoolModel.findByHid(roleId, originHero.hid);
if(school) {
let dicSchool = gameData.school.get(school.schoolId);
let preRate = getSchoolRateByStar(originHero.star, originHero.colorStar, originHero.quality);
let curRate = getSchoolRateByStar(updateHero.star, updateHero.colorStar, updateHero.quality);
console.log('####', updateHero.star, updateHero.colorStar, updateHero.quality)
for (let attrId of dicSchool.upAttribute) {
if(ABI_TYPE_MAIN.includes(attrId)) { // 主属性
let ratioUp = (curRate?.mainAttrAPerent||0) - (preRate?.mainAttrAPerent||0);
updateRoleAttr(roleAttrs, attrId, { inc: { ratioUp } });
} else {
let fixUp = ((curRate?.assiAttrAddValue||0) - (preRate?.assiAttrAddValue||0)) * HERO_CE_RATIO;
updateRoleAttr(roleAttrs, attrId, { inc: { fixUp } });
}
}
}
return roleAttrs;
}