百家学宫,名将谱战力

This commit is contained in:
luying
2020-12-26 16:42:33 +08:00
parent a3c5f6b57f
commit ffb12668f7
13 changed files with 796 additions and 826 deletions
+29 -1
View File
@@ -33,6 +33,9 @@ import { dicSuit } from './dictionary/DicSuit';
import { dicTitle } from './dictionary/DicTitle';
import { dicTeraph } from './dictionary/DicTeraph';
import { dicSchool } from './dictionary/DicSchool';
import { dicSchoolRate } from './dictionary/DicSchoolRate';
import { dicHeroScroll, preHeroScroll } from './dictionary/DicHeroScroll';
import { ABI_TYPE_TO_STAGE } from "../consts";
export const gameData = {
blurprtCompose: dicBlueprtCompose,
@@ -77,7 +80,10 @@ export const gameData = {
suit: dicSuit,
title: dicTitle,
teraphs: dicTeraph,
school: dicSchool
school: dicSchool,
schoolRate: dicSchoolRate,
heroScroll: dicHeroScroll,
preHeroScroll: preHeroScroll
};
// 在此提供一些原先在gamedata中提供的方法,以便更方便获取gameData数据
@@ -214,3 +220,25 @@ export function getTeraph(id: number, grade: number) {
const teraphInfo = gameData.teraphs.get(id +'_'+ grade);
return teraphInfo;
}
export function getSchoolRateByStar(star: number, colorStar: number, quality: number) {
const schoolRate = gameData.schoolRate.get(`${star}_${colorStar}_${quality}`);
return schoolRate;
}
export function getScollByStar(quality: number, star: number, curQuality: number, colorStar: number) {
const heroScroll = gameData.heroScroll.get(`${quality}_${star}_${curQuality}_${colorStar}`);
return heroScroll;
}
// 根据存在升星表等的stage字段的id对应17维id
export function getFieldByStage(stage: number, jobid: number) {
let targetAttrId = ABI_TYPE_TO_STAGE.get(stage);
if(typeof targetAttrId === 'number') {
return targetAttrId
} else {
const dicJob = gameData.job.get(jobid);
return targetAttrId(dicJob.type);
}
}
@@ -0,0 +1,47 @@
// 武将技能表
import { readJsonFile } from '../util'
import { FILENAME, ABI_STAGE } from '../../consts'
export interface DicHeroScroll {
// id
readonly id: number;
// 初始品质
readonly quality: number;
// 星级
readonly stars: number;
// 当前品质
readonly qualityUp: number;
// 觉醒星级
readonly colorstars: number;
// 每阶升级属性
readonly ceAttr: Map<number, number>
}
const str = readJsonFile(FILENAME.DIC_HERO_SCROLL);
let arr = JSON.parse(str);
export const dicHeroScroll = new Map<string, DicHeroScroll>();
export const preHeroScroll = new Map<number, DicHeroScroll>(); // 前一个
let pre: DicHeroScroll;
arr.forEach(o => {
o.ceAttr = parseCeAttr(o);
dicHeroScroll.set(`${o.quality}_${o.stars}_${o.qualityUp}_${o.colorstars}`, o);
if(pre && pre.quality == o.quality) preHeroScroll.set(o.id, pre);
pre = o;
});
arr = undefined;
pre = undefined;
function parseCeAttr(elem) {
let ceAttr = new Map<number, number>();
ceAttr.set(ABI_STAGE.HP, elem.hp);
ceAttr.set(ABI_STAGE.ATK, elem.atk);
ceAttr.set(ABI_STAGE.DEF, elem.def);
ceAttr.set(ABI_STAGE.MDEF, elem.mdef);
ceAttr.set(ABI_STAGE.AGI, elem.agi);
ceAttr.set(ABI_STAGE.LUK, elem.luk);
return ceAttr;
}
@@ -0,0 +1,31 @@
// 百家学宫列表
import { readJsonFile, parseNumberList } from '../util'
import { FILENAME } from '../../consts'
export interface DicSchoolRate {
// id
readonly id: number;
// 品质
readonly quality: number;
// 星级
readonly stars: number;
// 觉醒星级
readonly colorstars: number;
// 主属性加百分比
readonly mainAttrAPerent: number;
// 次级属性加值
readonly assiAttrAddValue: number;
}
const str = readJsonFile(FILENAME.DIC_SCHOOL_RATE);
let arr = JSON.parse(str);
export const dicSchoolRate = new Map<string, DicSchoolRate>();
arr.forEach(o => {
dicSchoolRate.set(`${o.stars}_${o.colorstars}_${o.quality}`, o);
});
arr = undefined;
+198 -45
View File
@@ -4,22 +4,23 @@
import { HERO_SYSTEM_TYPE, ABI_TYPE, JEWEL_ATTR } from '../consts';
import { deepCopy } from './util';
import { deepCopy, getAllAttrStage } from './util';
import { HeroModel, HeroType } from '../db/Hero';
import { RoleModel } from '../db/Role';
import { CeAttrData, CeAttr, CeAttrNumber } from '../db/generalField';
import { CeAttrData, CeAttr, CeAttrRole, CeAttrNumber, CeAttrDataRole } from '../db/generalField';
import { getAttrNameByJobStage, getAttrCeRatio, getAtrrNameById, ABI_TYPE_TO_STAGE, ABI_STAGE, SEID_TYPE} from '../consts';
import { gameData, getJobByGradeAndClass, getHeroWakeByQuality, getHeroStarByQuality, getFriendShipById } from './data';
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: CeAttr, hero: HeroType, type: number, args: Array<number>) {
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}}
@@ -29,8 +30,8 @@ export function calPlayerCe(globalCeAttr: CeAttr, hero: HeroType, type: number,
if (type == HERO_SYSTEM_TYPE.INIT) {
reIncAttr = calHeroInitIncAttr(hero, addSeidList, removeSeidList); // args: 升的星盘
} else if (type == HERO_SYSTEM_TYPE.STAR) {
reIncAttr = calHeroStarIncAttr(hero, args, 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) {
@@ -51,19 +52,22 @@ export function calPlayerCe(globalCeAttr: CeAttr, hero: HeroType, type: number,
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 {
return incCe;
reIncAttr = hero.ceAttr;
}
addSeidEffect(reIncAttr, hero.ceAttr, addSeidList, removeSeidList); // 处理加值
if(!hero.ceAttr) hero.ceAttr = new CeAttr();
for (let attrName in reIncAttr) {
if(!reIncAttr[attrName]) continue;
if(!reIncAttr[attrName] || attrName == '_id') continue;
let originalAttrData: CeAttrData = hero.ceAttr[attrName]||new CeAttrData();
let originalGlobalAttrData: CeAttrData = globalCeAttr[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; //计算属性
@@ -82,23 +86,31 @@ export async function calPlayerCeAndSave(roleId: string, heros: Array<HeroType>,
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: CeAttr = {}; // role表属性增量
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);
}
for (let attrName in reIncAttr) {
role.globalCeAttr[attrName].fixUp = reIncAttr[attrName].fixUp;
role.globalCeAttr[attrName].ratioUp = reIncAttr[attrName].ratioUp;
} 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,
@@ -106,6 +118,11 @@ export async function calPlayerCeAndSave(roleId: string, heros: Array<HeroType>,
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}
@@ -113,7 +130,7 @@ export async function calPlayerCeAndSave(roleId: string, heros: Array<HeroType>,
// 初始战力
export function calHeroInitIncAttr(hero: HeroType, addSeidList: Array<number>, removeSeidList: Array<number>) {
let res1 = calHeroStarIncAttr(hero, getAllAttrStage(), addSeidList, removeSeidList, true);
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);
@@ -146,7 +163,7 @@ function combineAttrResult(target: CeAttr, origin: CeAttr) {
}
}
export function calRoleInitIncAttr(heros: HeroType[], globalCeAttr: CeAttr) {
export function calRoleInitIncAttr(heros: HeroType[], globalCeAttr: CeAttrRole) {
let args = new Array<number>();
for(let hero of heros) {
for(let skin of hero.skins) {
@@ -175,16 +192,20 @@ function combineHeroCeAttr(originalHero: HeroType, result: CeAttr) {
/**
*
* @param hero HeroType 武将更新后的值
* @param args number[] 参数,表示需要更新多少个维
* @param type number 类型
* @param hid number 当前武将id
* @param args number[] 当升星时,一个参数,0-是否升了一星;当觉醒时,两个参数,0-是否升了一星,1-是否初次觉醒
* @param addSeidList number[] 用于更新被动
* @param removeSeidList number[] 用于更新被动
* @param isInit boolean 是否是初次创建武将
*/
export function calHeroStarIncAttr (hero: HeroType, args: Array<number>, addSeidList: Array<number>, removeSeidList: Array<number>, isInit = false) {
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
@@ -195,7 +216,23 @@ export function calHeroStarIncAttr (hero: HeroType, args: Array<number>, addSeid
}
const dicStar = isWake? getHeroWakeByQuality(quality, originColorStar): getHeroStarByQuality(quality, originStar); // 星级表
for(let stage of args) {
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等
@@ -249,13 +286,6 @@ function getSeidListOfFashion(fashionid: number, originStar: number, originColor
return seidList
}
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: HeroType) {
let res: CeAttr = {};
@@ -495,19 +525,6 @@ export function calRestrengthenIncAttr (hero: HeroType, ePaceId: number, args: A
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 = gameData.job.get(jobid);
return targetAttrId(dicJob.type);
}
}
// 添加技能增加的被动属性
function addSeidEffect(reIncAttr: CeAttr, heroCeAttr: CeAttr,addSeidList: Array<number>, removeSeidList: Array<number>) {
@@ -613,9 +630,9 @@ function calHeroCeWhenJewelOff(hero: HeroType, args: Array<number>) {
}
//全局属性加成
export async function reCalAllHeroCe(roleId: string, type: number, args:Array<number>) {
let reIncAttr: CeAttr = {};
let reIncAttr: CeAttrRole = {};
let role = await RoleModel.findByRoleId(roleId);
if(!role.globalCeAttr) role.globalCeAttr = new CeAttr();
if(!role.globalCeAttr) role.globalCeAttr = new CeAttrRole();
let originalAttr = role.globalCeAttr;
let pushHeros:Array<{hid:number, ce:number, incHeroCe:number}> = []
if (type == 1) {//获得皮肤
@@ -642,8 +659,8 @@ export async function reCalAllHeroCe(roleId: string, type: number, args:Array<nu
return {pushHeros, ce: role.ce}
}
function calHeroAddSkin(args:Array<number>, ceAttr: CeAttr){
let res: CeAttr = {};
function calHeroAddSkin(args:Array<number>, ceAttr: CeAttrRole){
let res: CeAttrRole = {};
for (let arg of args) {
let addSkin = gameData.fashion.get(arg);
let attrName: string;
@@ -656,3 +673,139 @@ function calHeroAddSkin(args:Array<number>, ceAttr: CeAttr){
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;
}
+12 -1
View File
@@ -9,7 +9,8 @@ import Actor from './actor';
import fs = require('fs');
import path = require('path');
import { DicRandomEffectPool } from './dictionary/DicRandomEffectPool';
import { HERO_CE_RATIO } from '../consts';
import { HERO_CE_RATIO, ABI_STAGE } from '../consts';
const _ = require('underscore');
const moment = require('moment');
@@ -546,4 +547,14 @@ export function getRandomArr(allarr, ranNum) {
result.push(arr.splice(ran, 1)[0]);
};
return result;
}
// 获取全部属性
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;
}