Files
ZYZ/shared/pubUtils/playerCe.ts
2020-12-26 17:37:04 +08:00

812 lines
33 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, JEWEL_ATTR } from '../consts';
import { deepCopy, getAllAttrStage } from './util';
import { HeroModel, HeroType } from '../db/Hero';
import { RoleModel } from '../db/Role';
import { CeAttrData, CeAttr, CeAttrRole, CeAttrNumber, CeAttrDataRole } from '../db/generalField';
import { getAttrNameByJobStage, getAttrCeRatio, getAtrrNameById, ABI_STAGE, SEID_TYPE} from '../consts';
import { gameData, getJobByGradeAndClass, getHeroWakeByQuality, getHeroStarByQuality, getFriendShipById, getSchoolRateByStar, getScollByStar, getFieldByStage } from './data';
import { Attributes } from './interface';
import { DicSe } from './dictionary/DicSe';
import { EquipType } from '../db/Equip';
import { DicRandomEffectPool } from './dictionary/DicRandomEffectPool';
import { getGoodById } from './gamedata';
import { SchoolModel } from '../db/School';
const HERO_CE_RATIO = 100;
const _ = require('underscore');
//战力计算TODO
export function calPlayerCe(globalCeAttr: CeAttrRole, hero: HeroType, type: number, args: Array<number> = []) {
let incCe = 0;
let incArr: Attributes = {};
let reIncAttr: CeAttr = {}; // {"hp": {"base": number, "fixUp": number, "ratioUp": number}}
let addSeidList = new Array<number>();
let removeSeidList = new Array<number>();
if (type == HERO_SYSTEM_TYPE.INIT) {
reIncAttr = calHeroInitIncAttr(hero, addSeidList, removeSeidList); // args: 升的星盘
} else if (type == HERO_SYSTEM_TYPE.STAR || type == HERO_SYSTEM_TYPE.LVUP || type == HERO_SYSTEM_TYPE.COLORSTAR || type == HERO_SYSTEM_TYPE.QUALITY) {
reIncAttr = calHeroStarIncAttr(hero, type, args.shift(), args, addSeidList, removeSeidList); // args: 升的星盘
} else if (type == HERO_SYSTEM_TYPE.TRAIN) {
reIncAttr = calHeroTrainIncAttr(hero);
} else if (type == HERO_SYSTEM_TYPE.STAGEUP) {
reIncAttr = calHeroJobStageUpIncAttr(hero, args, addSeidList, removeSeidList );
} else if (type == HERO_SYSTEM_TYPE.SKIN) {
reIncAttr = calHeroWearSkinIncAttr(hero, args, addSeidList, removeSeidList );
} else if (type == HERO_SYSTEM_TYPE.FAVOUR) {
reIncAttr = calHeroFavourUpIncAttr(hero, args);
} else if (type == HERO_SYSTEM_TYPE.CONNECT) {
reIncAttr = calHeroConectIncAttr(hero, args);
} else if (type == HERO_SYSTEM_TYPE.EQUIP) {
reIncAttr = calEquipPutOnOffIncAttr(hero, args, addSeidList, removeSeidList);
} else if (type == HERO_SYSTEM_TYPE.EQUIP_BASE) {
reIncAttr = calHeroEquipIncAttr(hero);
} else if (type == HERO_SYSTEM_TYPE.RESTRENGTHEN) {
reIncAttr = calRestrengthenIncAttr(hero, args.shift(), args, addSeidList, removeSeidList);
} else if (type == HERO_SYSTEM_TYPE.JEWEL_ON) {//宝石穿戴
reIncAttr = calHeroCeWhenJewelOn(hero, args);
} else if (type == HERO_SYSTEM_TYPE.JEWEL_OFF) {//宝石卸下
reIncAttr = calHeroCeWhenJewelOff(hero, args);
} else if (type == HERO_SYSTEM_TYPE.SCROLL) { // 名将谱初次激活增加好感度
reIncAttr = calHeroCeScrollIncAttr(hero, args[0], args[1]);
} else {
reIncAttr = hero.ceAttr;
}
addSeidEffect(reIncAttr, hero.ceAttr, addSeidList, removeSeidList); // 处理加值
if(!hero.ceAttr) hero.ceAttr = new CeAttr();
for (let attrName in reIncAttr) {
if(!reIncAttr[attrName] || attrName == '_id') continue;
let originalAttrData: CeAttrData = hero.ceAttr[attrName]||new CeAttrData();
let originalGlobalAttrData: CeAttrDataRole = globalCeAttr[attrName]||new CeAttrDataRole();
let oldCe = (originalAttrData.fixUp + (originalAttrData.equipUp||0)) * HERO_CE_RATIO + originalAttrData.base *(HERO_CE_RATIO + originalAttrData.ratioUp + originalGlobalAttrData.ratioUp);
if(!hero.ceAttr[attrName]) hero.ceAttr[attrName] = new CeAttrData();
for (let attrKey in reIncAttr[attrName]) {
if(attrKey == '_id') continue;
hero.ceAttr[attrName][attrKey] = parseInt(reIncAttr[attrName][attrKey]||0);
}
incArr[attrName] = (reIncAttr[attrName].fixUp + (reIncAttr[attrName].equipUp||0)) * HERO_CE_RATIO + reIncAttr[attrName].base *(HERO_CE_RATIO + reIncAttr[attrName].ratioUp + originalGlobalAttrData.ratioUp) - oldCe; //计算属性
incCe += incArr[attrName] * getAttrCeRatio(attrName);
}
hero.ce += incCe;
if(hero.historyCe < hero.ce) hero.historyCe = hero.ce;
return incCe;
}
//修改并下发战力
export async function calPlayerCeAndSave(roleId: string, heros: Array<HeroType>, type?: number, args?: Array<number>) {
if(!heros.length) heros = await HeroModel.findByRole(roleId);
let incPlayerCe = 0;
let pushHeros = new Array<{hid: number, ce: number, incHeroCe: number}>();
let role = await RoleModel.findByRoleId(roleId);
if(!role.globalCeAttr) role.globalCeAttr = new CeAttr();
let originalAttr = role.globalCeAttr;
let reIncAttr: CeAttrRole = {}; // role表属性增量
if (type == HERO_SYSTEM_TYPE.INIT) {
reIncAttr = calRoleInitIncAttr(heros, role.globalCeAttr); // 全局变量增
} else if (type == HERO_SYSTEM_TYPE.ADD_SKIN) {
reIncAttr = calHeroAddSkin(args, role.globalCeAttr);
} else if (type == HERO_SYSTEM_TYPE.SCHOOL) {
reIncAttr = calSchoolAddAttr(heros, args[0], args[1], args[2], role.globalCeAttr);
} else if (type == HERO_SYSTEM_TYPE.SCROLL) {
reIncAttr = calScrollAddAttr(heros, args[0], role.globalCeAttr);
} else if (type == HERO_SYSTEM_TYPE.STAR || type == HERO_SYSTEM_TYPE.COLORSTAR || type == HERO_SYSTEM_TYPE.QUALITY) { // 升星时,在百家学宫中部署的武将加成会同时增加
reIncAttr = await calSchoolStarIncAttr(heros, type, args, role.globalCeAttr);
}
for (let hero of heros) {
let incHeroCe = calPlayerCe(role.globalCeAttr, hero, type, args);
for (let attrName in reIncAttr) {
let oldcCe = originalAttr[attrName].fixUp * HERO_CE_RATIO + hero.ceAttr[attrName].base * (HERO_CE_RATIO + originalAttr[attrName].ratioUp);
let incArr = reIncAttr[attrName].fixUp * HERO_CE_RATIO + hero.ceAttr[attrName].base * (HERO_CE_RATIO + reIncAttr[attrName].ratioUp) - oldcCe;
incHeroCe += incArr * getAttrCeRatio(attrName);
}
incPlayerCe += incHeroCe;
hero.ce += incHeroCe;
await HeroModel.updateHeroInfo(roleId, hero.hid, hero);
pushHeros.push({
hid: hero.hid,
ce: hero.ce,
incHeroCe : incHeroCe,
});
}
for (let attrName in reIncAttr) {
role.globalCeAttr[attrName].fixUp = reIncAttr[attrName].fixUp;
role.globalCeAttr[attrName].ratioUp = reIncAttr[attrName].ratioUp;
}
role.ce += incPlayerCe;
await RoleModel.updateRoleInfo(roleId, {globalCeAttr: role.globalCeAttr, ce: role.ce});
return {pushHeros, role}
}
// 初始战力
export function calHeroInitIncAttr(hero: HeroType, addSeidList: Array<number>, removeSeidList: Array<number>) {
let res1 = calHeroStarIncAttr(hero, HERO_SYSTEM_TYPE.INIT, hero.hid, [], addSeidList, removeSeidList);
let hero1 = combineHeroCeAttr(hero, res1);
let curSkin = hero.skins.find(cur => cur.enable);
let res2 = calHeroWearSkinIncAttr(hero1, [curSkin?curSkin.id:0, 0], addSeidList, removeSeidList, true);
let hero2 = combineHeroCeAttr(hero, res2);
calHeroJobStageUpIncAttr(hero2, [0], addSeidList, removeSeidList);
let result: CeAttr = {};
combineAttrResult(result, res1);
combineAttrResult(result, res2);
return res1
}
function combineAttrResult(target: CeAttr, origin: CeAttr) {
for(let attrName in origin) {
for(let attrKey in origin[attrName]) {
if(!target.hasOwnProperty(attrName)) {
target[attrName] = {};
}
if(!target[attrName].hasOwnProperty(attrKey)) {
target[attrName][attrKey] = 0;
}
if(origin[attrName][attrKey] > target[attrName][attrKey]) {
target[attrName][attrKey] = origin[attrName][attrKey];
}
}
}
}
export function calRoleInitIncAttr(heros: HeroType[], globalCeAttr: CeAttrRole) {
let args = new Array<number>();
for(let hero of heros) {
for(let skin of hero.skins) {
args.push(skin.id);
}
}
let res = calHeroAddSkin(args, globalCeAttr);
return res;
}
// 将hero的ceAttr暂时更新不更新在originalHero本体上
function combineHeroCeAttr(originalHero: HeroType, result: CeAttr) {
let hero = deepCopy(originalHero);
if(!hero.ceAttr) hero.ceAttr = new CeAttr();
for (let attrName in result) {
if(!result[attrName]) continue;
if(!hero.ceAttr[attrName]) hero.ceAttr[attrName] = new CeAttrData();
for (let attrKey in result[attrName]) {
hero.ceAttr[attrName][attrKey] = parseInt(result[attrName][attrKey]||0);
}
}
delete hero._id;
return hero;
}
/**
*
* @param hero HeroType 武将更新后的值
* @param type number 类型
* @param hid number 当前武将id
* @param args number[] 当升星时一个参数0-是否升了一星当觉醒时两个参数0-是否升了一星1-是否初次觉醒
* @param addSeidList number[] 用于更新被动
* @param removeSeidList number[] 用于更新被动
*/
export function calHeroStarIncAttr (hero: HeroType, type: number, hid: number, args: number[], addSeidList: Array<number>, removeSeidList: Array<number>) {
let isInit = type == HERO_SYSTEM_TYPE.INIT;
let {star, starStage, quality, colorStar, colorStarStage, ceAttr, skins} = hero;
let originStar = star, originColorStar = colorStar;
let res: CeAttr = {};
if(hero.hid != hid) return res;
const dicHero = gameData.hero.get(hero.hid);
const isWake = colorStar > 0; // 是否觉醒,只要激活了觉醒,彩星就会 > 1
if(isWake) {
if(colorStarStage == ABI_STAGE.START) originColorStar = colorStar - 1;
} else {
if(starStage == ABI_STAGE.START) originStar = star - 1;
}
const dicStar = isWake? getHeroWakeByQuality(quality, originColorStar): getHeroStarByQuality(quality, originStar); // 星级表
let stages = new Array<number>(); // 需要升级的阶
if(type == HERO_SYSTEM_TYPE.INIT) {
stages = getAllAttrStage();
} else if (type == HERO_SYSTEM_TYPE.LVUP) {
stages = getAllAttrStage();
} else if (type == HERO_SYSTEM_TYPE.STAR) {
stages = [args[0]? ABI_STAGE.END: starStage];
} else if (type == HERO_SYSTEM_TYPE.QUALITY) {
stages = getAllAttrStage();
} else if (type = HERO_SYSTEM_TYPE.COLORSTAR) {
if(args[1]) { // 首次觉醒
stages = getAllAttrStage();
} else {
stages.push(args[0]? ABI_STAGE.END: hero.colorStarStage)
}
}
for(let stage of stages) {
let targetAttrId = getFieldByStage(stage, hero.job); // 转换为17维的属性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 + hero.lv * (heroUpAttr + starUp)) * HERO_CE_RATIO;
let field = getAtrrNameById(targetAttrId);
let ceAttrData: CeAttrData = ceAttr[field]||new CeAttrData(); // 存表中的属性下的basefixupratioup
let {ratioUp = 0, fixUp = 0} = ceAttrData;
res[field] = { base: newBase, ratioUp, fixUp}; // base变动增量为△base * ratio + 0
}
// 解锁技能
let curSkin = skins.find(cur => cur.enable);
let curSeidList = getSeidListOfFashion(curSkin.id, star, colorStar);
let preSeidList = getSeidListOfFashion(curSkin.id, isInit?0:originStar, isInit?0:originColorStar);
for(let [type, seid] of curSeidList) {
if(!preSeidList.has(type)) {
addSeidList.push(seid, 0);
}
}
for(let [type, seid] of preSeidList) {
console.log(type, seid)
if(!curSeidList.has(type)) {
removeSeidList.push(seid, 0);
}
}
return res;//属性增量可以是多个
}
function getSeidListOfFashion(fashionid: number, originStar: number, originColorStar: number) {
let seidList = new Map<number, number>(); // type => seid
if(!gameData.fashion.has(fashionid)) return seidList;
let { skillId } = gameData.fashion.get(fashionid);
let { starSeidArr, colorStarSeidArr } = gameData.heroSkill.get(skillId);
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
}
//训练
export function calHeroTrainIncAttr(hero: HeroType) {
let res: CeAttr = {};
let attrName: string = getAttrNameByJobStage(hero.jobStage);
res[attrName] = {fixUp: hero.ceAttr[attrName].fixUp, base: hero.ceAttr[attrName].base, ratioUp: hero.ceAttr[attrName].ratioUp};
let currentJob = gameData.job.get(hero.job);
if (currentJob.grade > 1) {
let jobGradeAndClass = getJobByGradeAndClass(currentJob.job_class, currentJob.grade - 1);
let lastJob = gameData.job.get(jobGradeAndClass.jobid);
res[attrName].fixUp += (currentJob[attrName] - lastJob[attrName]) * HERO_CE_RATIO;
} else {
res[attrName].fixUp += currentJob[attrName] * HERO_CE_RATIO;
}
return res;
}
//进阶
export function calHeroJobStageUpIncAttr(hero: HeroType, args: Array<number>, addSeidList: Array<number>, removeSeidList: Array<number>) {
let res: CeAttr = {};
let lastJob = gameData.job.get(args[0])||{seid:[]};
let currentJob = gameData.job.get(hero.job);
for (let seid of currentJob.seid) {
let index = _.findIndex(lastJob.seid, seid);
if (index < 0) {
addSeidList.push(seid, 0);
}
}
for (let seid of lastJob.seid) {
let index = _.findIndex(currentJob.seid, seid);
if (index < 0) {
removeSeidList.push(seid, 0);
}
}
return res;
}
//穿戴时装
export function calHeroWearSkinIncAttr(hero: HeroType, args: Array<number>, addSeidList: Array<number>, removeSeidList: Array<number>, isInit = false) {
let res: CeAttr = {};
let addSkin = gameData.fashion.get(args[0]);
let delSkin = gameData.fashion.get(args[1]);
let attrName: string;
if(delSkin) {
for (let attr of delSkin.actorAttr) {
attrName = getAtrrNameById(attr.id);
res[attrName] = {fixUp: hero.ceAttr[attrName].fixUp, base: hero.ceAttr[attrName].base, ratioUp: hero.ceAttr[attrName].ratioUp};
res[attrName].fixUp -= attr.number * HERO_CE_RATIO;
}
}
for (let attr of addSkin.actorAttr) {
attrName = getAtrrNameById(attr.id);
res[attrName] = {fixUp: hero.ceAttr[attrName].fixUp, base: hero.ceAttr[attrName].base, ratioUp: hero.ceAttr[attrName].ratioUp};
res[attrName].fixUp += attr.number * HERO_CE_RATIO;
}
if(!isInit) { // 初始的时候这一段技能在calHeroStarIncAttr里计算了不用重复算
let { star, colorStar } = hero;
let curSeidList = getSeidListOfFashion(args[0], star, colorStar);
let preSeidList = getSeidListOfFashion(args[1], star, colorStar);
for(let [type, seid] of curSeidList) {
if(!preSeidList.has(type)) {
removeSeidList.push(seid, 0);
}
}
for(let [type, seid] of preSeidList) {
if(!curSeidList.has(type)) {
addSeidList.push(seid, 0);
}
}
}
return res;
}
//羁绊解锁
export function calHeroConectIncAttr(hero: HeroType, args: Array<number>) {
let res: CeAttr = {};
let fiendShipLevel = gameData.friendShipLevelMap.get(hero.favourLv);
let shipId = args[0];//当前升级的羁绊序号
let level = args[1];//当前升级的羁绊等级
let attrName: string;
let currentShip = getFriendShipById(shipId, level);
for (let attr of currentShip.attributes) {
attrName = getAtrrNameById(attr.id);
res[attrName] = {fixUp: hero.ceAttr[attrName].fixUp, base: hero.ceAttr[attrName].base, ratioUp: hero.ceAttr[attrName].ratioUp};
res[attrName].fixUp += attr.number * (HERO_CE_RATIO + fiendShipLevel.add);
}
if (level > 1) {
let lastShip = getFriendShipById(shipId, level - 1);
for (let attr of lastShip.attributes) {
attrName = getAtrrNameById(attr.id);
res[attrName] = {fixUp: hero.ceAttr[attrName].fixUp, base: hero.ceAttr[attrName].base, ratioUp: hero.ceAttr[attrName].ratioUp};
res[attrName].fixUp -= attr.number * (HERO_CE_RATIO + fiendShipLevel.add);
}
}
return res;
}
//好感升级
export function calHeroFavourUpIncAttr(hero: HeroType, args: Array<number>) {
let res: CeAttr = {};
let currentFiendShipLevel = gameData.friendShipLevelMap.get(hero.favourLv);
let difAdd = currentFiendShipLevel.add;
if (!!args[0]) {
let lastFiendShipLevel = gameData.friendShipLevelMap.get(args[0]);
difAdd -= lastFiendShipLevel.add;
}
let attrName: string;
for (let connect of hero.connections) {
let heroShip = getFriendShipById(connect.shipId, connect.level);
for (let attr of heroShip.attributes) {
attrName = getAtrrNameById(attr.id);
res[attrName] = {fixUp: hero.ceAttr[attrName].fixUp, base: hero.ceAttr[attrName].base, ratioUp: hero.ceAttr[attrName].ratioUp};
res[attrName].fixUp += attr.number * (HERO_CE_RATIO + difAdd);
}
}
return res;
}
// 穿脱, removeSeidList原来身上穿着的所有装备的seid包括套装的
export function calEquipPutOnOffIncAttr(hero: HeroType, args: Array<number>, addSeidList: Array<number>, removeSeidList: Array<number>) {
// 计算身上所有装备的战力值(特技相关以外)
let res = calHeroEquipIncAttr(hero);
// 计算被动技能
let { ePlace } = hero;
let suits = new Map<number, number>();
for(let { equip } of ePlace) {
if(equip) {
let e = <EquipType>equip;
for(let { seid, rand } of e.randSe) {
addSeidList.push(seid, rand);
}
if(e.suitId > 0) {
if(suits.has(e.suitId)) {
suits.set(e.suitId, 1);
} else {
suits.set(e.suitId, suits.get(e.suitId) + 1);
}
}
}
}
suits.forEach((suitId, count) => {
let { effect } = gameData.suit.get(suitId);
for(let e of effect) {
if(count >= e.count) {
addSeidList.push(e.seid, 0);
}
}
});
for(let arg of args) { removeSeidList.push(arg) }
return res
}
// 装备,装备栏升级,装备精炼等涉及到值的
export function calHeroEquipIncAttr(hero: HeroType) {
let res: CeAttr = {};
let { ePlace } = hero;
let attrResult = new CeAttrNumber();
for(let {equip, lv, refineLv} of ePlace) {
if(equip) {
let e = <EquipType>equip;
let dicGoods = gameData.goods.get(e.id);
let {goodsAbility, goodsAbilityUp} = dicGoods;
let dicRefine = gameData.refine.get(refineLv);
let jewel = new Map<number, number>();
for(let {jewel: jewelId} of e.holes) {
if(jewelId > 0) {
let g = gameData.goods.get(jewelId);
if(g) {
let jGoods = g.goodsAbility;
jGoods.forEach((value, key) => {
if(jewel.has(key)) {
jewel.set(key, value);
} else {
jewel.set(key, jewel.get(key) + value);
}
})
}
}
}
for(let i = ABI_TYPE.ABI_HP; i < ABI_TYPE.ABI_MAX; i++) {
if(i == ABI_TYPE.ABI_SPEED || i == ABI_TYPE.ABI_AP) continue;
let attrName = getAtrrNameById(i);
// console.log('***', i, attrName);
let value1 = goodsAbility.get(i)||0 * (HERO_CE_RATIO + e.randRange);
// console.log('基础值', value1);
let valueup = goodsAbilityUp.get(i)||0;
// console.log('成长', lv, valueup);
let valueRefine = dicRefine?dicRefine.upPercent:0;
// console.log('refine', dicRefine?dicRefine.upPercent:0 );
let valueJewel = jewel.get(i)||0;
// console.log('jewel', valueJewel);
let attr = (value1 + lv * valueup) * ( HERO_CE_RATIO + valueRefine) + valueJewel * HERO_CE_RATIO;
attrResult[attrName] += attr;
}
}
}
for(let attrName in attrResult) {
let originalCe = hero.ceAttr[attrName].equipUp||0;
console.log('装备战力:', attrName, attrResult[attrName] * HERO_CE_RATIO, originalCe);
res[attrName] = {fixUp: hero.ceAttr[attrName].fixUp, base: hero.ceAttr[attrName].base, ratioUp: hero.ceAttr[attrName].ratioUp, equipUp: originalCe};
res[attrName].equipUp += attrResult[attrName] * HERO_CE_RATIO - originalCe;
}
return res;
}
// 洗炼
export function calRestrengthenIncAttr (hero: HeroType, ePaceId: number, args: Array<number>, addSeidList: Array<number>, removeSeidList: Array<number>) {
let res: CeAttr = {};
let {ePlace} = hero;
let curPlace = ePlace.find(cur => cur.id == ePaceId);
if(curPlace && curPlace.equip) {
let e = <EquipType>curPlace.equip;
for(let { seid, rand } of e.randSe) {
addSeidList.push(seid, rand);
}
}
for(let arg of args) { removeSeidList.push(arg) }
return res
}
// 添加技能增加的被动属性
function addSeidEffect(reIncAttr: CeAttr, heroCeAttr: CeAttr,addSeidList: Array<number>, removeSeidList: Array<number>) {
console.log('addSeidList', addSeidList)
console.log('removeSeidList', removeSeidList)
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)
}
}
for(let {type, gainValueArr: [ability, value]} of effectList) {
let attrName = getAtrrNameById(ability);
if(!attrName) continue;
if(type == SEID_TYPE.TYPE101) { // 加值
if(!reIncAttr[attrName]) {
reIncAttr[attrName] = deepCopy(heroCeAttr[attrName]);
}
if(!reIncAttr[attrName]) {
delete reIncAttr[attrName];
continue;
}
reIncAttr[attrName].fixUp += value * multi * HERO_CE_RATIO;
delete reIncAttr[attrName]._id;
} else if (type == SEID_TYPE.TYPE102) { // 加百分比
if(!reIncAttr[attrName]) {
reIncAttr[attrName] = deepCopy(heroCeAttr[attrName]);
}
if(!reIncAttr[attrName]) {
delete reIncAttr[attrName];
continue;
}
reIncAttr[attrName].ratioUp += value * multi;
delete reIncAttr[attrName]._id;
}
}
}
}
// 获取dic_zyz_se内容
function addSeid(effectList: Array<any>, seidId:number, rand: number, seidValue = new Array<number>()){
// console.log('addSeidEffect', seidId, seidValue)
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;
}
effectList.push(curSeid);
let seid: DicSe|DicRandomEffectPool = deepCopy(curSeid);
if(curSeid.index > 0) {
seid.gainValueArr[curSeid.index - 1] = rand;
}
effectList.push(seid);
}
function calHeroCeWhenJewelOn(hero: HeroType, args: Array<number>) {
let res: CeAttr = {};
let id = args[0];
let oldId = args[1];
let goodInfo = getGoodById(id);
let oldGoodInfo;
if (!!oldId)
oldGoodInfo = getGoodById(oldId);
for (let attrName in JEWEL_ATTR) {
if (!!goodInfo[attrName]) {
res[attrName] = {fixUp: hero.ceAttr[attrName].fixUp, base: hero.ceAttr[attrName].base, ratioUp: hero.ceAttr[attrName].ratioUp};
res[attrName].fixUp += goodInfo[attrName];
if (oldGoodInfo)
res[attrName].fixUp -= oldGoodInfo[attrName];
}
}
return res;
}
function calHeroCeWhenJewelOff(hero: HeroType, args: Array<number>) {
let res: CeAttr = {};
for (let id of args) {
let goodInfo = getGoodById(id);
for (let attrName in JEWEL_ATTR) {
if (!!goodInfo[attrName]) {
res[attrName] = {fixUp: hero.ceAttr[attrName].fixUp, base: hero.ceAttr[attrName].base, ratioUp: hero.ceAttr[attrName].ratioUp};
res[attrName].fixUp -= goodInfo[attrName];
}
}
}
return res;
}
//全局属性加成
export async function reCalAllHeroCe(roleId: string, type: number, args:Array<number>) {
let reIncAttr: CeAttrRole = {};
let role = await RoleModel.findByRoleId(roleId);
if(!role.globalCeAttr) role.globalCeAttr = new CeAttrRole();
let originalAttr = role.globalCeAttr;
let pushHeros:Array<{hid:number, ce:number, incHeroCe:number}> = []
if (type == 1) {//获得皮肤
reIncAttr = calHeroAddSkin(args, role.globalCeAttr);
}
for (let attrName in reIncAttr) {
role.globalCeAttr[attrName].fixUp = reIncAttr[attrName].fixUp;
role.globalCeAttr[attrName].ratioUp = reIncAttr[attrName].ratioUp;
}
let heros = await HeroModel.findByRole(roleId);
for (let hero of heros) {
let incHeroCe = 0;
for (let attrName in reIncAttr) {
let oldcCe = originalAttr[attrName].fixUp * HERO_CE_RATIO + hero.ceAttr[attrName].base * (HERO_CE_RATIO + originalAttr[attrName].ratioUp);
let incArr = role.globalCeAttr[attrName].fixUp * HERO_CE_RATIO + hero.ceAttr[attrName].base * (HERO_CE_RATIO + role.globalCeAttr[attrName].ratioUp) - oldcCe;
incHeroCe += incArr * getAttrCeRatio(attrName);
}
incHeroCe += incHeroCe;
hero.ce += incHeroCe;
pushHeros.push({ hid: hero.hid, ce: hero.ce, incHeroCe });
await HeroModel.updateHeroInfo(roleId, hero.hid, {ce: hero.ce});
}
await RoleModel.updateRoleInfo(roleId, {globalCeAttr: role.globalCeAttr, ce: role.ce});
return {pushHeros, ce: role.ce}
}
function calHeroAddSkin(args:Array<number>, ceAttr: CeAttrRole){
let res: CeAttrRole = {};
for (let arg of args) {
let addSkin = gameData.fashion.get(arg);
let attrName: string;
for (let attr of addSkin.globalAttr) {
attrName = getAtrrNameById(attr.id);
res[attrName] = {fixUp: ceAttr[attrName].fixUp, ratioUp: ceAttr[attrName].ratioUp};
res[attrName].fixUp += attr.number * HERO_CE_RATIO;
}
}
return res;
}
/**
* 全局加成,百家学宫
* @param heros 所有武将
* @param schoolId 学宫学派
* @param hid 换上的武将
* @param preHid 撤下的武将
* @param ceAttr
*/
function calSchoolAddAttr(heros: HeroType[], schoolId: number, hid: number, preHid: number, ceAttr: CeAttrRole){
let res: CeAttrRole = {};
let school = gameData.school.get(schoolId);
let preHero = heros.find(cur => cur.hid == preHid);
let curHero = heros.find(cur => cur.hid == hid);
if(!school ) return res;
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;
let attrName: string;
for(let attrId of school.upAttribute) {
attrName = getAtrrNameById(attrId);
res[attrName] = {fixUp: ceAttr[attrName].fixUp, ratioUp: ceAttr[attrName].ratioUp};
if(attrId < ABI_TYPE.ABI_SPEED) { // 主属性
res[attrName].ratioUp += curRate.mainAttrAPerent - preRate.mainAttrAPerent;
} else { // 次级属性
res[attrName].fixUp += (curRate.assiAttrAddValue - preRate.assiAttrAddValue) * HERO_CE_RATIO;
}
}
return res;
}
/**
* 升星,觉醒,升品时,百家学宫配置武将会相应修改全局战力
* @param heros HeroType[] 传入只有一个如果有全局计算后面push其他武将
* @param type number 类型
* @param args
* @param ceAttr
*/
async function calSchoolStarIncAttr(heros: HeroType[], type: number, args: number[], ceAttr: CeAttrRole) {
let res: CeAttrRole = {};
let [hid, isStarUp] = args; // 是否升星,是否初次觉醒
let needCal = false;
let roleId: string = '';
for(let hero of heros) {
if(hero.hid != hid) {
continue;
}
if((type == HERO_SYSTEM_TYPE.STAR || type == HERO_SYSTEM_TYPE.COLORSTAR) && !isStarUp) {
continue;
}
roleId = hero.roleId;
let curHeroInSchool = await SchoolModel.findByHid(roleId, hid);
if(!curHeroInSchool) continue;
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 --;
} else {
continue;
}
let school = gameData.school.get(curHeroInSchool.schoolId);
let preRate = getSchoolRateByStar(preStar, preColorStar, preQuality);
let curRate = getSchoolRateByStar(hero.star, hero.colorStar, hero.quality);
let attrName: string;
for(let attrId of school.upAttribute) {
attrName = getAtrrNameById(attrId);
res[attrName] = {fixUp: ceAttr[attrName].fixUp, ratioUp: ceAttr[attrName].ratioUp};
if(attrId < ABI_TYPE.ABI_SPEED) { // 主属性
res[attrName].ratioUp += curRate.mainAttrAPerent - preRate.mainAttrAPerent;
} else { // 次级属性
res[attrName].fixUp += (curRate.assiAttrAddValue - preRate.assiAttrAddValue) * HERO_CE_RATIO;
}
}
needCal = true;
}
if(needCal) {
const allHeros = await HeroModel.findByRole(roleId);
for(let hero of allHeros) {
if(hero.hid != hid) heros.push(hero);
}
}
return res;
}
/**
* 全局加成, 名将谱
* @param heros 所有武将
* @param hid 激活的武将
* @param ceAttr
*/
function calScrollAddAttr(heros: HeroType[], hid: number, ceAttr: CeAttrRole){
let res: CeAttrRole = {};
let curHero = heros.find(cur => cur.hid == hid);
let dicHero = gameData.hero.get(hid);
if(!curHero|| ! dicHero) return res;
let { quality } = dicHero;
let { star, quality: curQuality, colorStar, job } = curHero;
let heroScroll = getScollByStar(quality, star, curQuality, colorStar);
if(!heroScroll) return res;
let preScroll = gameData.preHeroScroll.get(heroScroll.id);
heroScroll.ceAttr.forEach((add, id) => {
let attId = getFieldByStage(id, job);
let attrName = getAtrrNameById(attId);
let preAdd = preScroll?preScroll.ceAttr.get(id): 0;
res[attrName] = {fixUp: ceAttr[attrName].fixUp, ratioUp: ceAttr[attrName].ratioUp};
res[attrName].fixUp += (add - preAdd) * HERO_CE_RATIO;
});
return res;
}
/**
* 名将谱激活增加单个武将好感
* @param hero 当前武将
* @param hid 激活武将
* @param preFavourLv 之前的好感度等级,有提升时才计算加成
*/
function calHeroCeScrollIncAttr(hero: HeroType, hid: number, preFavourLv: number) {
let res: CeAttr = {};
if(hero.hid == hid && hero.favourLv != preFavourLv) {
res = calHeroFavourUpIncAttr(hero, [preFavourLv]);
}
return res;
}