Files
ZYZ/game-server/app/services/playerCeService.ts
2020-12-15 16:02:59 +08:00

285 lines
11 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 } from '../consts';
import { pinus } from 'pinus';
import { STATUS } from '../consts/statusCode';
import { resResult, deepCopy } from '../pubUtils/util';
import Hero from '../db/Hero';
import { RoleModel } from '../db/Role';
import { CeAttrData, CeAttr } from '../db/BaseModel';
import { getFashionsById, getJobInfoById, getJobByGradeAndClass, getHeroInfoById, getHeroStar, getHeroWake, getFiendShipLevel, getFriendShipById, getHeroSkillById, getSeidById } from '../pubUtils/gamedata';
import { getAttrNameByJobStage, getAttrCeRatio, getAtrrNameById, ABI_TYPE_TO_STAGE, ABI_STAGE, SEID_TYPE, HERO_ATTR} from '../consts';
const HERO_CE_RATIO = 100;
const _ = require('underscore');
//战力计算TODO
export function calPlayerCe(hero: any, type: number, args: Array<number>) {
let incCe = 0;
let incArr = {};
let reIncAttr = {}; // {"hp": {"base": number, "fixUp": number, "ratioUp": number}}
let addSeidList = new Array<number>();
let removeSeidList = new Array<number>();
if (type == HERO_SYSTEM_TYPE.STAR) {
reIncAttr = calHeroStarIncAttr(hero, 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 = calWaerHeroSkinIncAttr(hero, args);
} else if (type == HERO_SYSTEM_TYPE.FAVOUR) {
reIncAttr = calHeroFavourUpIncAttr(hero, args);
} else if (type == HERO_SYSTEM_TYPE.CONNECT) {
reIncAttr = calHeroConectIncAttr(hero, args);
}
addSeidEffect(reIncAttr, addSeidList, removeSeidList); // 处理加值
if(!hero.ceAttr) hero.ceAttr = new CeAttr();
for (let attrName in reIncAttr) {
let originalAttrData: CeAttrData = hero.ceAttr[attrName]||new CeAttrData();
let oldCe = originalAttrData.fixUp * HERO_CE_RATIO + originalAttrData.base *(HERO_CE_RATIO + originalAttrData.ratioUp)
if(!hero.ceAttr[attrName]) hero.ceAttr[attrName] = new CeAttrData();
for (let attrKey in reIncAttr[attrName]) {
hero.ceAttr[attrName][attrKey] = parseInt(reIncAttr[attrName][attrKey]);
}
incArr[attrName] = reIncAttr[attrName].fixUp * HERO_CE_RATIO + reIncAttr[attrName].base *(HERO_CE_RATIO + reIncAttr[attrName].ratioUp) - oldCe; //计算属性
incCe += incArr[attrName] * getAttrCeRatio(attrName);
}
hero.ce += incCe;
return incCe;
}
//修改并下发战力
export async function calPlayerCeAndSave(sid: string, roleId: string, heros: Array<any>, type?: number, args?: Array<number>) {
let incPlayerCe = 0;
let pushHeros = [];
for (let hero of heros) {
let incHeroCe = calPlayerCe(hero, type, args);
incPlayerCe += incHeroCe;
await hero.save();
pushHeros.push({
hid: hero.hid,
ce: hero.ce,
incHeroCe : incHeroCe,
});
}
let role = await RoleModel.findByRoleId(roleId);
role.ce += incPlayerCe;
await RoleModel.updateRoleInfo(roleId, role);
//下发战力
let uids = [{ uid: roleId, sid }];
pinus.app.get('channelService').pushMessageByUids('onPlayerCeUpdate', resResult(STATUS.SUCCESS, { ce: role.ce, heros: pushHeros, topFiveCe: 0 }), uids);
return heros;
}
export function calHeroStarIncAttr (hero: Hero, args: Array<number>, addSeidList: Array<number>, removeSeidList: Array<number>) {
let {star, starStage, quality, colorStar, colorStarStage, ceAttr} = hero;
let res = {};
const dicHero = getHeroInfoById(hero.hid);
const isWake = colorStar > 0; // 是否觉醒,只要激活了觉醒,彩星就会 > 1
if(isWake) {
if(colorStarStage == ABI_STAGE.START) colorStar = colorStar -1;
} else {
if(starStage == ABI_STAGE.START) star = star -1;
}
const dicStar = isWake? getHeroWake(quality, colorStar): getHeroStar(quality, star); // 星级表
for(let stage of args) {
let targetAttrId = getFieldByStage(stage, hero.job); // 转换为17维的属性id
let heroAttr = dicHero.baseAbilityArr[targetAttrId]; // 武将表hp等
let heroUpAttr = dicHero.baseAbilityUpArr[targetAttrId]; // 武将表hp_up等
let starUp = dicStar.ceAttr.get(stage);
let newBase = heroAttr + hero.lv * (heroUpAttr + starUp);
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
}
// 解锁技能
if(dicHero.skill){
let {starSeidArr, colorStarSeidArr} = getHeroSkillById(dicHero.skill);
if(isWake) {
for(let {star, value} of starSeidArr){
if(hero.star == star){
addSeidList.push(value);
}
}
} else {
for(let {star, value} of colorStarSeidArr){
if(hero.colorStar == star){
addSeidList.push(value);
}
}
}
}
return res;//属性增量可以是多个
}
export function getAllAttrStage () {
let attrs = new Array<number>(); // 有升级的属性 1-hp 2-atk 3-def 4-mdef 5-agi 6-luk
for(let stage = ABI_STAGE.START + 1; stage <= ABI_STAGE.END; stage++) {
attrs.push(stage)
};
return attrs;
}
//训练
export function calHeroTrainIncAttr(hero: any) {
let res = {};
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 = getJobInfoById(hero.job);
if (currentJob.grade > 1) {
let jobGradeAndClass = getJobByGradeAndClass(currentJob.job_class, currentJob.grade - 1);
let lastJob = getJobInfoById(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: any, args: Array<number>, addSeidList: Array<number>, removeSeidList: Array<number> ) {
let res = {};
let lastJob = getJobInfoById(args[0]);
let currentJob = getJobInfoById(hero.job);
addSeidList.concat(deepCopy(currentJob.seids));
for (let seid of lastJob.seids) {
let index = _.indexOf(currentJob.seids, seid);
if (index > 0) {
addSeidList.splice(index, 1);
} else {
removeSeidList.push(seid);
}
}
return res;
}
//穿戴时装
export function calWaerHeroSkinIncAttr(hero: any, args: Array<number>) {
let res = {};
let addSkin = getFashionsById(args[0]);
let delSkin = getFashionsById(args[1]);
let attrName;
for (let attr of delSkin.actorAttrs) {
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.actorAttrs) {
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;
}
return res;
}
//羁绊解锁
export function calHeroConectIncAttr(hero: any, args: Array<number>) {
let res = {};
let fiendShipLevel = getFiendShipLevel(hero.favourLv);
let shipId = args[0];//当前升级的羁绊序号
let level = args[1];//当前升级的羁绊等级
let attrName;
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: any, args: Array<number>) {
let res = {};
let currentFiendShipLevel = getFiendShipLevel(hero.favourLv);
let difAdd = currentFiendShipLevel.add;
if (!!args[0]) {
let lastFiendShipLevel = getFiendShipLevel(args[0]);
difAdd -= lastFiendShipLevel.add;
}
let attrName;
for (let connect of hero.conections) {
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;
}
// 根据存在升星表等的stage字段的id对应17维id
function getFieldByStage(stage: number, jobid: number) {
let targetAttrId = ABI_TYPE_TO_STAGE.get(stage);
if(typeof targetAttrId === 'number') {
return targetAttrId
} else {
const dicJob = getJobInfoById(jobid);
return targetAttrId(dicJob.type);
}
}
// 添加技能增加的被动属性
function addSeidEffect(reIncAttr: CeAttr, addSeidList: Array<number>, removeSeidList: Array<number>) {
let otiginalSeidList = [
{list: addSeidList, multi: 1},
{list: removeSeidList, multi: -1}
];
for(let {list, multi} of otiginalSeidList) {
let effectList = new Array<any>(); // any: dic_zyz_se表内容
for(let seid of list) {
let dicSeid = getSeidById(seid);
if(dicSeid && dicSeid.id > 0){
addSeid(effectList, dicSeid.id, dicSeid.gainValueArr)
}
}
for(let {type, gainValueArr: [ability, value]} of effectList) {
if(!reIncAttr[HERO_ATTR[ability]]) {
reIncAttr[HERO_ATTR[ability]] = new CeAttrData();
}
if(type == SEID_TYPE.TYPE101) { // 加值
reIncAttr[HERO_ATTR[ability]].ratioUp += value * multi;
} else if (type == SEID_TYPE.TYPE102) { // 加百分比
reIncAttr[HERO_ATTR[ability]].fixUp += value * multi;
}
}
}
}
// 获取dic_zyz_se内容
function addSeid(effectList: Array<any>, seidId:number, seidValue = new Array<number>()){
// console.log('addSeidEffect', seidId, seidValue)
let curSeid = getSeidById(seidId);
if(!curSeid) {console.log("seidId not found:"+seidId);return;}
if(!seidValue) seidValue = curSeid.gainValueArr;
if(curSeid.type === 999){
for(let i = 0;i < seidValue.length;i++){
addSeid(effectList, seidValue[i]);
}
return;
}
effectList.push(curSeid);
}