Files
ZYZ/shared/pubUtils/playerCe.ts
2021-01-28 12:01:26 +08:00

928 lines
36 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, reduceCe } from './util';
import { HeroModel, HeroType } from '../db/Hero';
import { RoleModel, RoleType } 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 { DicSe } from './dictionary/DicSe';
import { EquipType } from '../db/Equip';
import { DicRandomEffectPool } from './dictionary/DicRandomEffectPool';
import { getGoodById } from './gamedata';
import { SchoolModel } from '../db/School';
import { getTeraphAttr, HEROTARIN } from '../consts/constModules/abilityConst'
import { PvpDefenseModel } from '../db/PvpDefense';
const HERO_CE_RATIO = 100;
import { findIndex } from 'underscore';
import { GuildModel } from '../db/Guild';
//战力计算TODO
export function calPlayerCe(globalCeAttr: CeAttrRole, hero: HeroType, type: number, args: Array<number> = []) {
let heroCe = 0;
let reIncAttr: CeAttr = {}; // {"hp": {"base": number, "fixUp": number, "ratioUp": number}}
let addSeidList = new Array<number>();
let removeSeidList = new Array<number>();
switch (type) {
case HERO_SYSTEM_TYPE.INIT:
reIncAttr = calHeroInitIncAttr(hero, addSeidList, removeSeidList); // args: 升的星盘
break;
case HERO_SYSTEM_TYPE.STAR:
case HERO_SYSTEM_TYPE.LVUP:
case HERO_SYSTEM_TYPE.COLORSTAR:
case HERO_SYSTEM_TYPE.QUALITY:
reIncAttr = calHeroStarIncAttr(hero, type, args.shift(), args, addSeidList, removeSeidList); // args: 升的星盘
break;
case HERO_SYSTEM_TYPE.TRAIN:
reIncAttr = calHeroTrainIncAttr(hero);
break;
case HERO_SYSTEM_TYPE.STAGEUP:
reIncAttr = calHeroJobStageUpIncAttr(hero, args, addSeidList, removeSeidList);
break;
case HERO_SYSTEM_TYPE.SKIN:
reIncAttr = calHeroWearSkinIncAttr(hero, args, addSeidList, removeSeidList);
break;
case HERO_SYSTEM_TYPE.FAVOUR:
reIncAttr = calHeroFavourUpIncAttr(hero, args);
break;
case HERO_SYSTEM_TYPE.CONNECT:
reIncAttr = calHeroConectIncAttr(hero, args);
break;
case HERO_SYSTEM_TYPE.EQUIP:
reIncAttr = calEquipPutOnOffIncAttr(hero, args, addSeidList, removeSeidList);
break;
case HERO_SYSTEM_TYPE.EQUIP_BASE:
reIncAttr = calHeroEquipIncAttr(hero);
break;
case HERO_SYSTEM_TYPE.RESTRENGTHEN:
reIncAttr = calRestrengthenIncAttr(hero, args.shift(), args, addSeidList, removeSeidList);
break;
case HERO_SYSTEM_TYPE.JEWEL_ON:
reIncAttr = calHeroCeWhenJewelOn(hero, args);
break;
case HERO_SYSTEM_TYPE.JEWEL_OFF:
reIncAttr = calHeroCeWhenJewelOff(hero, args);
break;
case HERO_SYSTEM_TYPE.SCROLL:
reIncAttr = calHeroCeScrollIncAttr(hero, args[0], args[1]);
break;
default:
break;
}
addSeidEffect(reIncAttr, hero.ceAttr, addSeidList, removeSeidList); // 处理加值
if (!hero.ceAttr) hero.ceAttr = new CeAttr();
for (let attrName in hero.ceAttr) {
if (attrName == '_id') continue;
let globalAttrData: CeAttrDataRole = globalCeAttr[attrName] || new CeAttrDataRole();
if (!hero.ceAttr[attrName]) hero.ceAttr[attrName] = new CeAttrData();
if (!!reIncAttr[attrName]) {
for (let attrKey in reIncAttr[attrName]) {
hero.ceAttr[attrName][attrKey] = parseInt(reIncAttr[attrName][attrKey] || 0);
}
}
let attrNumber = (hero.ceAttr[attrName].fixUp + (hero.ceAttr[attrName].equipUp || 0) + globalAttrData.fixUp) * HERO_CE_RATIO + hero.ceAttr[attrName].base * (HERO_CE_RATIO + hero.ceAttr[attrName].ratioUp + globalAttrData.ratioUp);
// console.log(hero.hid, attrNumber, attrName, getAttrCeRatio(attrName))
heroCe += attrNumber * getAttrCeRatio(attrName);
}
let incCe = heroCe - hero.ce;
hero.ce = heroCe > 0 ? heroCe : 1;
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();
await reCalRoleAttr(heros, role.globalCeAttr, type, args);
for (let hero of heros) {
let incHeroCe = calPlayerCe(role.globalCeAttr, hero, type, args);
incPlayerCe += incHeroCe;
await calculateTopFive(role, hero.hid, hero.ce, hero._id); // 计算更新最强五人战力
await HeroModel.updateHeroInfo(roleId, hero.hid, hero);
await PvpDefenseModel.updateCe(roleId, hero.hid, hero.ce); // 更新pvp防守阵战力
pushHeros.push({
hid: hero.hid,
ce: reduceCe(hero.ce),
incHeroCe: reduceCe(incHeroCe),
});
}
role.ce += incPlayerCe;
let { topFive, topFiveCe } = role;
await RoleModel.updateRoleInfo(roleId, { globalCeAttr: role.globalCeAttr, ce: role.ce, topFive, topFiveCe });
await GuildModel.updateCe(roleId, incPlayerCe);
return { pushHeros, role, topFiveCe }
}
export async function calculateTopFive(role: RoleType, hid: number, ce: number, heroId: string) {
let topFive = role?.topFive || new Array();
topFive.sort((a, b) => { return b.ce - a.ce }); // 0-5最大-最小
let index = topFive.findIndex(cur => cur.hid == hid);
if(index != -1 && !heroId) {
let heroes = await HeroModel.getTopHero(role.roleId, 5);
topFive = heroes.map(cur => { return { hid: cur.hid, ce: cur.ce, hero: cur._id } });
} else {
if (index == -1) { // 不在最强列表
if (topFive.length < 5) { // 不满5人
topFive.push({ hid, ce, hero: heroId });
} else if (topFive.length == 5) {
if (ce > topFive[topFive.length - 1].ce) { // 跻身最强5人
topFive.pop();
topFive.push({ hid, ce, hero: heroId });
}
} else {
topFive.splice(5, topFive.length - 5);
}
} else { // 原来就是最强5人
if (ce < topFive[topFive.length - 1].ce) { // 滑出最强
let heroes = await HeroModel.getTopHero(role.roleId, 5);
topFive = heroes.map(cur => { return { hid: cur.hid, ce: cur.ce, hero: cur._id } });
} else {
topFive[index].ce = ce;
}
}
}
let topFiveCe = topFive.reduce((pre, cur) => {
return pre + cur.ce
}, 0);
role.topFive = topFive;
role.topFiveCe = topFiveCe;
return role;
}
// 初始战力
export function calHeroInitIncAttr(hero: HeroType, addSeidList: Array<number>, removeSeidList: Array<number>) {
let res = calHeroStarIncAttr(hero, HERO_SYSTEM_TYPE.INIT, hero.hid, [], addSeidList, removeSeidList);
let curSkin = hero.skins.find(cur => cur.enable);
calHeroWearSkinIncAttr(hero, [curSkin ? curSkin.id : 0, 0], addSeidList, removeSeidList, true, res);
calHeroJobAttr(hero, res, addSeidList, removeSeidList);
return res;
}
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;
}
/**
*
* @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(dicHero.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 - 1) * (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) {
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 calHeroJobAttr(hero: HeroType, res: CeAttr, addSeidList: Array<number>, removeSeidList: Array<number>) {
let currentJob = gameData.job.get(hero.job);
let jobGradeAndClass = getJobByGradeAndClass(currentJob.job_class, currentJob.grade - 1);
let lastJob;
if (!!jobGradeAndClass) {
lastJob = gameData.job.get(jobGradeAndClass.jobid);
}
for (let key in HEROTARIN) {
let attrName: string = HEROTARIN[key];
res[attrName] = res[attrName] || { fixUp: hero.ceAttr[attrName].fixUp, base: hero.ceAttr[attrName].base, ratioUp: hero.ceAttr[attrName].ratioUp };
if (hero.jobStage >= parseInt(key)) {
res[attrName].fixUp += currentJob[attrName] * HERO_CE_RATIO;
} else {
if (lastJob)
res[attrName].fixUp += lastJob[attrName] * HERO_CE_RATIO;
}
}
calHeroJobStageUpIncAttr(hero, [0], addSeidList, removeSeidList);
return res;
}
//穿戴时装
export function calHeroWearSkinIncAttr(hero: HeroType, args: Array<number>, addSeidList: Array<number>, removeSeidList: Array<number>, isInit = false, heroAttr?: CeAttr) {
let res: CeAttr = heroAttr || {};
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] = 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] = 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, suits.get(e.suitId) + 1);
} else {
suits.set(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 calEquipSeids(hero: HeroType) {
let seids = [];
// 计算被动技能
let { ePlace } = hero;
let suits = new Map<number, number>();
for (let { equip } of ePlace) {
if (equip) {
let e = <EquipType>equip;
if (!!e.randSe) {
for (let { seid, rand } of e.randSe) {
seids.push(seid, rand);
}
}
if (e.suitId > 0) {
if (suits.has(e.suitId)) {
suits.set(e.suitId, suits.get(e.suitId) + 1);
} else {
suits.set(e.suitId, 1);
}
}
}
}
suits.forEach((suitId, count) => {
let { effect } = gameData.suit.get(suitId);
for (let e of effect) {
if (count >= e.count) {
seids.push(e.seid, 0);
}
}
});
return seids;
}
// 装备,装备栏升级,装备精炼等涉及到值的
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], 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] - 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;
}
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 role = await RoleModel.findByRoleId(roleId);
if (!role.globalCeAttr) role.globalCeAttr = new CeAttr();
let pushHeros: Array<{ hid: number, ce: number, incHeroCe: number }> = []
let heros = await HeroModel.findByRole(roleId);
await reCalRoleAttr(heros, role.globalCeAttr, type, args);
role.ce = 0;
for (let hero of heros) {
let heroCe = 0;
for (let attrName in role.globalCeAttr) {
if (attrName == '_id')
continue;
let heroAttrData: CeAttrData = hero.ceAttr[attrName] || new CeAttrData();
let globalAttrData: CeAttrData = role.globalCeAttr[attrName];
let attrNumber = (heroAttrData.fixUp + (heroAttrData.equipUp || 0) + globalAttrData.fixUp) * HERO_CE_RATIO + heroAttrData.base * (HERO_CE_RATIO + heroAttrData.ratioUp + globalAttrData.ratioUp);
heroCe += attrNumber * getAttrCeRatio(attrName);
}
let incHeroCe = heroCe - hero.ce;
hero.ce = heroCe;
role.ce += hero.ce;
pushHeros.push({ hid: hero.hid, ce: reduceCe(hero.ce), incHeroCe: reduceCe(incHeroCe) });
await HeroModel.updateHeroInfo(roleId, hero.hid, { ce: hero.ce });
}
role = await RoleModel.updateRoleInfo(roleId, { globalCeAttr: role.globalCeAttr, ce: role.ce });
return { pushHeros, ce: role.ce, topFiveCe: role.topFiveCe }
}
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;
}
function calTitle(args: Array<number>, ceAttr: CeAttrRole) {
let res: CeAttrRole = {};
let titleId = args[0];
let titleInfo = gameData.title.get(titleId);
for (let attrName in getTeraphAttr()) {
res[attrName] = { fixUp: ceAttr[attrName].fixUp, ratioUp: ceAttr[attrName].ratioUp };
res[attrName].fixUp += titleInfo[attrName] * HERO_CE_RATIO;
}
for (let attr of titleInfo.assiAttrValue) {
let attrName = getAtrrNameById(attr.id);
if (!attrName) continue;
res[attrName] = res[attrName] || { fixUp: ceAttr[attrName].fixUp, ratioUp: ceAttr[attrName].ratioUp };
res[attrName].ratioUp += attr.number * HERO_CE_RATIO;
}
return res;
}
export function initRoleAtrr(role: RoleType) {
if (!role.globalCeAttr) role.globalCeAttr = new CeAttr();
let titleId = role.title;
let titleInfo = gameData.title.get(titleId);
if (!!titleInfo) {
for (let attrName in getTeraphAttr()) {
if (!attrName) continue;
role.globalCeAttr[attrName].fixUp += titleInfo[attrName] * HERO_CE_RATIO;
}
for (let attr of titleInfo.assiAttrValue) {
let attrName = getAtrrNameById(attr.id);
if (!attrName) continue;
role.globalCeAttr[attrName].ratioUp += attr.number * HERO_CE_RATIO;
}
}
return;
}
async function reCalRoleAttr(heros: Array<HeroType>, ceAttr: CeAttrRole, type: number, args: Array<number>) {
let reIncAttr: CeAttrRole = {}; // role表属性增量
switch (type) {
case HERO_SYSTEM_TYPE.INIT:
reIncAttr = calRoleInitIncAttr(heros, ceAttr); // 全局变量增
break;
case HERO_SYSTEM_TYPE.ADD_SKIN:
reIncAttr = calHeroAddSkin(args, ceAttr);
break;
case HERO_SYSTEM_TYPE.SCHOOL:
reIncAttr = calSchoolAddAttr(heros, args[0], args[1], args[2], ceAttr);
break;
case HERO_SYSTEM_TYPE.SCROLL:
reIncAttr = calScrollAddAttr(heros, args[0], ceAttr);
break;
case HERO_SYSTEM_TYPE.STAR:
case HERO_SYSTEM_TYPE.COLORSTAR:
case HERO_SYSTEM_TYPE.QUALITY:
reIncAttr = await calSchoolStarIncAttr(heros, type, args, ceAttr);
break;
case HERO_SYSTEM_TYPE.TITLE:
reIncAttr = calTitle(args, ceAttr);
}
for (let attrName in reIncAttr) {
if (attrName == '_id') continue;
let globalAttrData: CeAttrDataRole = reIncAttr[attrName] || new CeAttrDataRole();
for (let key in globalAttrData) {
ceAttr[attrName][key] = parseInt(globalAttrData[key] || 0);
}
}
}