From 1bdace30f9064b4995056ead624a0836c20bb8e7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E9=99=86=E8=8E=B9?= Date: Fri, 25 Mar 2022 14:14:36 +0800 Subject: [PATCH 01/12] =?UTF-8?q?=E5=88=9B=E5=BB=BA=E6=AD=A6=E5=B0=86?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../app/servers/chat/remote/guildRemote.ts | 1 - .../app/servers/gm/handler/gmRoleHandler.ts | 2 +- .../app/servers/role/handler/heroHandler.ts | 7 +- .../app/servers/role/handler/roleHandler.ts | 18 +- .../app/servers/role/remote/roleRemote.ts | 83 +--- game-server/app/services/pvpService.ts | 1 - .../app/services/role/_calCe.ts | 2 +- game-server/app/services/role/calCe.ts | 465 ++++++++++++++++++ game-server/app/services/role/createHero.ts | 216 ++++---- .../app/services/role/initRoleService.ts | 61 --- .../app/services/role/rewardService.ts | 2 +- game-server/app/services/roleService.ts | 6 +- shared/db/Hero.ts | 24 +- shared/db/RoleCe.ts | 98 ++++ shared/db/Skin.ts | 10 + shared/pubUtils/playerCe.ts | 49 +- shared/pubUtils/util.ts | 59 ++- 17 files changed, 747 insertions(+), 357 deletions(-) rename shared/domain/roleField/calCe.ts => game-server/app/services/role/_calCe.ts (99%) create mode 100644 game-server/app/services/role/calCe.ts delete mode 100644 game-server/app/services/role/initRoleService.ts create mode 100644 shared/db/RoleCe.ts diff --git a/game-server/app/servers/chat/remote/guildRemote.ts b/game-server/app/servers/chat/remote/guildRemote.ts index a5cc1cada..c297ba571 100644 --- a/game-server/app/servers/chat/remote/guildRemote.ts +++ b/game-server/app/servers/chat/remote/guildRemote.ts @@ -92,7 +92,6 @@ export class GuildRemote { */ private pushMessage(guildCode: string, path: string, message: any) { let channel = this.getChannel(guildCode); - console.log('##### channel', guildCode, channel) if (!!channel) { channel.pushMessage(path, resResult(STATUS.SUCCESS, message)); } diff --git a/game-server/app/servers/gm/handler/gmRoleHandler.ts b/game-server/app/servers/gm/handler/gmRoleHandler.ts index f1d783bef..cccf9f17a 100644 --- a/game-server/app/servers/gm/handler/gmRoleHandler.ts +++ b/game-server/app/servers/gm/handler/gmRoleHandler.ts @@ -21,7 +21,7 @@ import { HeroModel } from '../../../db/Hero'; import { calAllHeroCe, calPlayerCeAndSave } from '../../../services/playerCeService'; import { SkinModel } from '../../../db/Skin'; import { PvpDefenseModel } from '../../../db/PvpDefense'; -import { calculatetopLineup } from '../../../pubUtils/playerCe'; +import { calculatetopLineup } from '../../../pubUtils/util'; import { createHeroes } from '../../../services/role/createHero'; let timer: NodeJS.Timer; diff --git a/game-server/app/servers/role/handler/heroHandler.ts b/game-server/app/servers/role/handler/heroHandler.ts index 2b8035e82..01fa865fb 100644 --- a/game-server/app/servers/role/handler/heroHandler.ts +++ b/game-server/app/servers/role/handler/heroHandler.ts @@ -11,14 +11,14 @@ import { gameData, getHeroExpByLv, getHeroStarByQuality, getHeroWakeByQuality, g import { ItemInter, RewardInter } from '../../../pubUtils/interface'; import { getDropItems, FIGURE_UNLOCK_CONDITION } from '../../../consts/constModules/itemConst' import { pushComposeOrangeHero, pushHeroQualityUpMsg, pushHeroStarMax, pushHeroWakeUp } from '../../../services/chatService'; -import { calculatetopLineup } from '../../../pubUtils/playerCe'; +import { calculatetopLineup } from '../../../pubUtils/util'; import { PvpDefenseModel } from '../../../db/PvpDefense'; import { checkTask, checkTaskInHeroQUalityUp, checkTaskInHeroStarUp, checkTaskInHeroTrain, checkTaskInHeroWakeUp } from '../../../services/task/taskService'; import { isNumber, pick } from 'underscore'; import { updateEplaces } from '../../../services/equipService'; import { addConsumeToHero, checkUnlockTalentCondition, initSkinTalent, updateSkinTalent } from '../../../services/roleService'; import { JewelModel, jewelUpdate } from '../../../db/Jewel'; -import { CalHeroCe } from '../../../domain/roleField/calCe'; +import { CalHeroCe } from '../../../services/role/_calCe'; import { HERO, REBORN } from '../../../pubUtils/dicParam'; import { createHero, createHeroes } from '../../../services/role/createHero'; import { CheckMeterial } from '../../../services/role/checkMaterial'; @@ -654,9 +654,8 @@ export class HeroHandler { let newSkins = initSkinTalent(skins); let dicHeroScroll = getScollByStar(dicHero.quality, dicHero.initialStars, dicHero.quality, 0); - let initInfo = HeroModel.getInitInfo({ + let initInfo = HeroModel.getInitInfo(hid, { job: dicJob.jobid, skins: newSkins, skinId, ce, - star: dicHero.initialStars, quality: dicHero.quality, scrollActive: scrollActive, scrollId: scrollActive? dicHeroScroll.id: 0, scrollStar: scrollActive? dicHeroScroll.stars: 0, diff --git a/game-server/app/servers/role/handler/roleHandler.ts b/game-server/app/servers/role/handler/roleHandler.ts index ba0d7e60d..02584462b 100644 --- a/game-server/app/servers/role/handler/roleHandler.ts +++ b/game-server/app/servers/role/handler/roleHandler.ts @@ -25,7 +25,7 @@ import * as dicParam from '../../../pubUtils/dicParam'; import Counter from '../../../db/Counter'; import { UserModel } from '../../../db/User'; import { checkFilterWords, reportTAEvent, treatRoleName } from '../../../services/sdkService'; -import { CreateHeroes } from '../../../services/role/createHero'; +import { createHeroes, CreateHeroes } from '../../../services/role/createHero'; export default function (app: Application) { new HandlerService(app, {}); @@ -50,20 +50,8 @@ export class RoleHandler { let checkName = await RoleModel.checkName(roleName, serverId); if (checkName) return resResult(STATUS.NAME_HAS_USED); - let initInfos: { role: RoleUpdate, initInfos: {heroInfo: HeroUpdate, skinInfo: SkinUpdate}[], figureInfo: { heads: Figure[], frames: Figure[], spines: Figure[] }} - = this.app.get('initRoleInfos'); - role = await RoleModel.updateRoleInfo(roleId, {...initInfos.role, roleName, hasInit: true}); - let createHero = new CreateHeroes(roleId, roleName, serverId); - - let infos = new Map(); - for(let {heroInfo, skinInfo} of initInfos.initInfos) { - infos.set(heroInfo.hid, { heroInfo, skinInfo }); - } - await createHero.createWithInitInfo(infos, initInfos.figureInfo); - await createHero.pushMessage(sid); - await createHero.updateRedisRank(); - let heroes = createHero.getResultHeroes(); - + let { resultHeroes: heroes } = await createHeroes(roleId, roleName, sid, serverId, DEFAULT_HEROES.map(hid => ({hid, count: 1}))); + role = await RoleModel.updateRoleInfo(roleId, { roleName, hasInit: true }); session.set('roleName', roleName); session.push('roleName', () => { }); diff --git a/game-server/app/servers/role/remote/roleRemote.ts b/game-server/app/servers/role/remote/roleRemote.ts index 06a58e6f8..eb705dfe4 100644 --- a/game-server/app/servers/role/remote/roleRemote.ts +++ b/game-server/app/servers/role/remote/roleRemote.ts @@ -5,14 +5,11 @@ import { HeroUpdate } from '../../../db/Hero'; import { RoleUpdate } from '../../../db/Role'; import { SkinUpdate } from '../../../db/Skin'; import { RankFirstModel, RankFirstType } from '../../../db/RankFirst'; -import { DEFAULT_HEROES } from '../../../consts'; import { Figure } from '../../../domain/dbGeneral'; -import { getDefaultRoleInfo } from '../../../services/roleService'; import { PVPConfigModel, PVPConfigType } from '../../../db/SystemConfig'; import { treatRoleName, taflush } from '../../../services/sdkService'; import { getServerMainten, setServerMainten, stopServerMainten } from '../../../services/gmService'; import { errlogger } from '../../../util/logger'; -import { getInitRoleInfo } from '../../../services/role/initRoleService'; export default function (app: Application) { new HandlerService(app, {}); @@ -23,16 +20,12 @@ export class RoleRemote { constructor(private app: Application) { this.app = app; - this.channelService = app.get('channelService'); - this.setInitRole(); + // this.channelService = app.get('channelService'); this.loadRankFirst(); this.initPvpSeasonNum(); } - private channelService: ChannelService; - private initHeroes: Map = new Map(); // hid => hero - private initRole: RoleUpdate = {}; - private initSkins: Map = new Map(); // hid => skin - private figureInfo: {heads: Figure[], frames: Figure[], spines: Figure[]}; + // private channelService: ChannelService; + private rankFirstRewards: Map> = new Map(); private async loadRankFirst() { @@ -68,76 +61,6 @@ export class RoleRemote { } } - public setInitRole() { - try { - let result = getInitRoleInfo(); - let { role, heroes, skins, figureInfo } = result; - for(let hero of heroes) { - this.initHeroes.set(hero.hid, hero); - } - for(let skin of skins) { - this.initSkins.set(skin.hid, skin); - } - this.initRole = role; - this.figureInfo = figureInfo; - const initRoleInfos = getDefaultRoleInfo(this.initHeroes, this.initSkins, this.initRole, this.figureInfo); - this.app.set('initRoleInfos', initRoleInfos); - this.app.set('initHeroes', this.initHeroes); - this.app.set('initSkins', this.initSkins); - } catch(e) { - errlogger.error(`remote ${__filename} \n ${e.stack}`); - } - } - - public getInitRoleInfos() { - try { - let initRoleInfos = this.app.get('initRoleInfos'); - if (!initRoleInfos) { - initRoleInfos = getDefaultRoleInfo(this.initHeroes, this.initSkins, this.initRole, this.figureInfo); - this.app.set('initRoleInfos', initRoleInfos); - } - return initRoleInfos; - } catch(e) { - errlogger.error(`remote ${__filename} \n ${e.stack}`); - } - } - - public getInitHeroes() { - try { - let result: HeroUpdate[] = []; - for(let hid of DEFAULT_HEROES) { - result.push(this.initHeroes.get(hid)); - } - return result; - } catch(e) { - errlogger.error(`remote ${__filename} \n ${e.stack}`); - } - } - - public getInitSkins() { - try { - let result: SkinUpdate[] = []; - for(let hid of DEFAULT_HEROES) { - result.push(this.initSkins.get(hid)); - } - return result; - } catch(e) { - errlogger.error(`remote ${__filename} \n ${e.stack}`); - } - } - - public getInitHeroById(hid: number) { - try { - return { - heroInfo: this.initHeroes.get(hid), - skinInfo: this.initSkins.get(hid) - } - } catch(e) { - errlogger.error(`remote ${__filename} \n ${e.stack}`); - } - } - - /** * 重载json资源 */ diff --git a/game-server/app/services/pvpService.ts b/game-server/app/services/pvpService.ts index b86abcd26..e94976c74 100644 --- a/game-server/app/services/pvpService.ts +++ b/game-server/app/services/pvpService.ts @@ -61,7 +61,6 @@ export async function getEnemies(oppPlayers: OppPlayer[], winStreakNum: number) * @param pLv 我的排名 */ export async function refreshEnemies(role: RoleType, seasonNum: number, sumScore: number, score: number, pLv: number) { - console.log('#####',seasonNum, sumScore, score, pLv) let { roleId } = role; let chosenOpps: string[] = []; let pvpHistoryOppParam: PvpOppCreateParam[] = []; diff --git a/shared/domain/roleField/calCe.ts b/game-server/app/services/role/_calCe.ts similarity index 99% rename from shared/domain/roleField/calCe.ts rename to game-server/app/services/role/_calCe.ts index 5257f336d..4c9c69ce1 100644 --- a/shared/domain/roleField/calCe.ts +++ b/game-server/app/services/role/_calCe.ts @@ -5,7 +5,7 @@ import { gameData, getHeroStarByQuality, getHeroWakeByQuality } from "../../pubU import { DicRandomEffectPool } from "../../pubUtils/dictionary/DicRandomEffectPool"; import { DicSe } from "../../pubUtils/dictionary/DicSe"; import { deepCopy } from "../../pubUtils/util"; -import { AttributeCal } from "./attribute"; +import { AttributeCal } from "../../domain/roleField/attribute"; export class CalRoleCe { private roleInfo: RoleUpdate; diff --git a/game-server/app/services/role/calCe.ts b/game-server/app/services/role/calCe.ts new file mode 100644 index 000000000..7dc7aaf2b --- /dev/null +++ b/game-server/app/services/role/calCe.ts @@ -0,0 +1,465 @@ +import { ABI_STAGE, ABI_STAGE_TO_TYPE, ABI_TYPE_MAIN, SEID_TYPE } from "../../consts"; +import { HeroUpdate } from "../../db/Hero"; +import { RoleUpdate, Teraph } from "../../db/Role"; +import { GlobalAttr, HeroAttr, HeroAttrCell, RoleCeType } from "../../db/RoleCe"; +import { AttributeCal } from "../../domain/roleField/attribute"; +import { gameData, getHeroStarByQuality, getHeroWakeByQuality, getTeraph } from "../../pubUtils/data"; +import { DicRandomEffectPool } from "../../pubUtils/dictionary/DicRandomEffectPool"; +import { DicSe } from "../../pubUtils/dictionary/DicSe"; +import { addToMap, deepCopy } from "../../pubUtils/util"; + +class RoleCe { + roleId: string; + globalAttrs: Map = new Map(); // attrId => GlobalCe + heroAttrs: Map = new Map(); // hid+attrId => HeroCe + heroAttrsByHid: Map = new Map(); // hid => [hid+attrId] + heroLv: Map = new Map(); + + setRoleCe(roleCe: RoleCeType) { + this.roleId = roleCe.roleId; + for(let globalAttr of roleCe.globalAttrs) { + let obj = this.getGlobalAttrById(globalAttr.attrId); + obj.setByRoleCe(globalAttr); + } + for(let {hid, lv, attrs} of roleCe.heroAttrs) { + this.heroLv.set(hid, lv); + for(let cell of attrs) { + let obj = this.getHeroAttrByHidAndId(hid, cell.attrId); + obj.setByRoleCe(cell); + } + } + } + + public getGlobalAttrById(attrId: number) { + if(!this.globalAttrs.has(attrId)) { + if(ABI_TYPE_MAIN.indexOf(attrId) != -1) { + let obj = new GlobalMainAttr(attrId); + this.globalAttrs.set(attrId, obj); + } else { + let obj = new GlobalSubAttr(attrId); + this.globalAttrs.set(attrId, obj); + } + } + return this.globalAttrs.get(attrId); + } + + public getHeroAttrByHidAndId(hid: number, attrId: number) { + let key = `${hid}_${attrId}`; + if(!this.heroAttrs.has(key)) { + if(ABI_TYPE_MAIN.indexOf(attrId) != -1) { + let obj = new HeroMainAttr(hid, attrId); + this.heroAttrs.set(key, obj); + } else { + let obj = new HeroSubAttr(hid, attrId); + this.heroAttrs.set(key, obj); + } + + if(!this.heroAttrsByHid.has(hid)) { + this.heroAttrsByHid.set(hid, []); + } + this.heroAttrsByHid.get(hid).push(key); + } + return this.heroAttrs.get(key); + } + + public calHeroCe() { + let ces = new Map(); // hid => [{attrId, val}] + for(let [hid, keys] of this.heroAttrsByHid) { + let lv = this.heroLv.get(hid)||1; + for(let key of keys) { + let { attrId, base, baseUp, starUp, skillRatio, skill, job } = this.heroAttrs.get(key); + let { schoolRatio, title, teraph } = this.getGlobalAttrById(attrId); + let val = ( base + lv * ( baseUp + starUp ) + skill + job) * (1 + skillRatio + schoolRatio ) + teraph + title; + if(!ces.has(hid)) ces.set(hid, []); + ces.get(hid).push({ id: attrId, val }); + } + } + let result = new Map(); + for(let [hid, arr] of ces) { + let obj = new AttributeCal(); + obj.setByWarJson(arr); + result.set(hid, obj.calCe()); + } + return result; + } + + public getRoleCeTable() { + let globalAttrs: GlobalAttr[] = []; + for(let [_, globalAttr] of this.globalAttrs) { + globalAttrs.push(globalAttr.getGlobalAttr()); + } + let heroAttrs: HeroAttr[] = []; + for(let [hid, keys] of this.heroAttrsByHid) { + let lv = this.heroLv.get(hid); + let attrs: HeroAttrCell[] = []; + for(let key of keys) { + let heroAttr = this.heroAttrs.get(key); + attrs.push(heroAttr.getHeroAttrCell()); + } + heroAttrs.push({ + hid, lv, attrs + }); + } + return { + roleId: this.roleId, globalAttrs, heroAttrs + } + } +} + +// 计算函数 +export class CalCe extends RoleCe { + public setInitHero(role: RoleUpdate, heroes: HeroUpdate[]) { + for(let { hid, skinId, lv, quality, star, starStage, colorStar, colorStarStage, job, jobStage, } of heroes) { + this.setHeroBase(hid, skinId); + this.setHeroLv(hid, lv); + this.setHeroStar(hid, job, quality, star, starStage, colorStar, colorStarStage); + this.setSkill(hid, skinId, star, colorStar); + this.setJob(hid, job, jobStage); + } + this.setTitle(role.title); + this.setTeraph(role.teraphs); + } + + // 武将基础&成长 + public setHeroBase(hid: number, skinId: number) { + let dicHero = gameData.hero.get(skinId); + for(let [attrId, value] of dicHero.baseAbilityArr) { + let heroAttr = this.getHeroAttrByHidAndId(hid, attrId); + heroAttr.base = value; + } + for(let [attrId, value] of dicHero.baseAbilityUpArr) { + let heroAttr = this.getHeroAttrByHidAndId(hid, attrId); + heroAttr.baseUp = value; + } + } + + // 武将等级 + public setHeroLv(hid: number, lv: number) { + this.heroLv.set(hid, lv); + } + + // 星级相关 + public setHeroStar(hid: number, job: number, quality: number, star: number, starStage: number, colorStar: number, colorStarStage: number) { + let dicJob = gameData.job.get(job); + let jobClass = dicJob.job_class; + const isWake = colorStar > 0; // 是否觉醒,只要激活了觉醒,彩星就会 > 1 + const dicStar = isWake ? getHeroWakeByQuality(jobClass, quality, colorStar) : getHeroStarByQuality(jobClass, quality, star); // 星级表 + const dicPreStar = isWake? getHeroWakeByQuality(jobClass, quality, colorStar - 1): getHeroStarByQuality(jobClass, quality, star - 1); + let curStage = isWake? colorStarStage: starStage; + + for (let stage = ABI_STAGE.START + 1; stage <= ABI_STAGE.END; stage++) { + let attrId = ABI_STAGE_TO_TYPE.get(stage); + let value = 0; // 星级成长 + if(curStage >= stage) { + value = dicStar?.ceAttr.get(stage)||0; + } else { + value = dicPreStar?.ceAttr.get(stage)||0; + } + let heroAttr = this.getHeroAttrByHidAndId(hid, attrId); + heroAttr.starUp = value; + }; + + } + + // 武将星级解锁被动技能计算 + public setSkill(hid: number, skinId: number, _star: number, _colorStar: number) { + let seidList = new Map(); // type => seid + let dicHero = gameData.hero.get(skinId); + let { starSeidArr, colorStarSeidArr } = gameData.heroSkill.get(dicHero.skill); + for (let { star, value, type } of starSeidArr) { + if (_star >= star) seidList.set(type, value); + } + for (let { star, value, type } of colorStarSeidArr) { + if (_colorStar >= star) seidList.set(type, value); + } + let list: number[] = []; + for(let [_type, value] of seidList) list.push(value); + let { fixUp, ratioUp } = this.addSeidEffect(list); + for(let [attrId, value] of fixUp) { + let heroAttr = this.getHeroAttrByHidAndId(hid, attrId); + heroAttr.skill = value; + } + for(let [attrId, value] of ratioUp) { + let heroAttr = this.getHeroAttrByHidAndId(hid, attrId); + heroAttr.skillRatio = value; + } + } + + // 职业基础 + public setJob(hid: number, job: number, jobStage: number) { + const dicJob = gameData.job.get(job); + for(let i = 1; i <= dicJob.maxStage; i++) { + if(jobStage >= i) { + let { id, attr } = dicJob.ceAttr.get(i); + let heroAttr = this.getHeroAttrByHidAndId(hid, id); + heroAttr.job = attr; + } + } + } + + // 爵位 + public setTitle(title: number) { + let dicTitle = gameData.title.get(title)||{ mainAttrValue: new Map(), assiAttrValue: new Map() }; + for(let [attrId, value] of dicTitle.mainAttrValue) { + let globalAttr = this.getGlobalAttrById(attrId); + globalAttr.title = value; + } + for(let [attrId, value] of dicTitle.assiAttrValue) { + let globalAttr = this.getGlobalAttrById(attrId); + globalAttr.title = value; + } + } + + // 神像相关 + public setTeraph(teraphs: Teraph[]) { + let teraphOfAttrId = new Map(); + for(let teraph of teraphs) { + for(let [attrId, value] of teraph.attr) { // 主属性 + addToMap(teraphOfAttrId, attrId, value); + } + let dicTeraph = getTeraph(teraph.id, teraph.grade); + for(let [attrId, value] of dicTeraph.assiAttrValue) { // 次属性 + addToMap(teraphOfAttrId, attrId, value); + } + } + for(let [attrId, value] of teraphOfAttrId) { + let globalAttr = this.getGlobalAttrById(attrId); + globalAttr.teraph = value; + } + } + + // 添加技能增加的被动属性 + private addSeidEffect(seidList: number[]) { + let fixUp = new Map(), ratioUp = new Map(); + let effectList: DicSe[] = []; // any: dic_zyz_se表内容 + + for (let ii = 0; ii < seidList.length; ii += 2) { + let seid = seidList[ii]; + let rand = seidList[ii + 1] || 0; + let dicSeid: DicSe | DicRandomEffectPool = gameData.se.get(seid); + if (!dicSeid) dicSeid = gameData.randomEffectPool.get(seid); + if (dicSeid && dicSeid.id > 0) { + this.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) { // 加值 + addToMap(fixUp, ability, value); + } else if (type == SEID_TYPE.TYPE103) { // 主属性加百分比 + if(ABI_TYPE_MAIN.includes(ability)) { + addToMap(ratioUp, ability, value / 1000); + } + } else if (type == SEID_TYPE.TYPE104) { // 次级属性加百分比 + if(!ABI_TYPE_MAIN.includes(ability)) { + addToMap(ratioUp, ability, value * 100); + } + } + + } + return { fixUp, ratioUp }; + } + + // 获取dic_zyz_se内容 + private addSeid(effectList: (DicSe | DicRandomEffectPool)[], seidId: number, rand: number, seidValue: 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++) { + this.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); + } +} + +abstract class GlobalAllAttr { + attrId: number; + schoolRatio: number = 0; + title: number = 0; + teraph: number = 0; + + constructor(attrId: number) { + this.attrId = attrId; + } + + abstract setByRoleCe(data: GlobalAttr): void; + abstract getValues(): number[]; + + public getGlobalAttr() { + return { + attrId: this.attrId, + values: this.getValues() + } + } +} + +class GlobalMainAttr extends GlobalAllAttr { + + public setByRoleCe(globalAttr: GlobalAttr) { + for(let i = 0; i < globalAttr.values.length; i++) { + let value = globalAttr.values[i]; + if(value != undefined) { + switch(i) { + case GLOBAL_ATTR_INDEX.SCHOOL: + this.schoolRatio = value; break; + case GLOBAL_ATTR_INDEX.TITLE: + this.title = value; break; + case GLOBAL_ATTR_INDEX.TERAPH: + this.teraph = value; break; + } + } + } + } + + public getValues() { + let values: number[] = []; + for(let i = GLOBAL_ATTR_INDEX.START; i < GLOBAL_ATTR_INDEX.END; i++) { + switch(i) { + case GLOBAL_ATTR_INDEX.SCHOOL: + values.push(this.schoolRatio); break; + case GLOBAL_ATTR_INDEX.TITLE: + values.push(this.title); break; + case GLOBAL_ATTR_INDEX.TERAPH: + values.push(this.teraph); break; + } + } + return values; + } +} + +class GlobalSubAttr extends GlobalAllAttr { + + public setByRoleCe(globalAttr: GlobalAttr) { + for(let i = 0; i < globalAttr.values.length; i++) { + let value = globalAttr.values[i]; + if(value != undefined) { + switch(i) { + case GLOBAL_ATTR_INDEX.SCHOOL: + this.schoolRatio = value; break; + case GLOBAL_ATTR_INDEX.TITLE: + this.title = value; break; + case GLOBAL_ATTR_INDEX.TERAPH: + this.teraph = value; break; + } + } + } + } + + public getValues() { + let values: number[] = []; + for(let i = GLOBAL_ATTR_INDEX.START; i < GLOBAL_ATTR_INDEX.END; i++) { + switch(i) { + case GLOBAL_ATTR_INDEX.SCHOOL: + values.push(this.schoolRatio); break; + case GLOBAL_ATTR_INDEX.TITLE: + values.push(this.title); break; + case GLOBAL_ATTR_INDEX.TERAPH: + values.push(this.teraph); break; + } + } + return values; + } +} + +abstract class HeroAllAttr { + hid: number; + attrId: number; + base: number = 0; + lv: number = 0; + baseUp: number = 0; + starUp: number = 0; + skillRatio: number = 0; + skill: number = 0; + job: number = 0; + + constructor(hid: number, attrId: number, ) { + this.hid = hid; + this.attrId = attrId; + + } + + abstract setByRoleCe(data: GlobalAttr): void; + abstract getValues(): number[]; + + public getHeroAttrCell() { + return { + attrId: this.attrId, + values: this.getValues() + } + } +} + +class HeroMainAttr extends HeroAllAttr { + public setByRoleCe(heroAttr: HeroAttrCell) { + for(let i = 0; i < heroAttr.values.length; i++) { + let value = heroAttr.values[i]; + if(value != undefined) { + switch(i) { + case HERO_ATTR_INDEX.BASE: + this.base = value; + } + } + } + } + + public getValues() { + let values: number[] = []; + for(let i = HERO_ATTR_INDEX.START; i < HERO_ATTR_INDEX.END; i++) { + switch(i) { + case HERO_ATTR_INDEX.BASE: + values.push(this.base); break; + } + } + return values; + } +} + +class HeroSubAttr extends HeroAllAttr { + public setByRoleCe(heroAttr: HeroAttrCell) { + for(let i = 0; i < heroAttr.values.length; i++) { + let value = heroAttr.values[i]; + if(value != undefined) { + switch(i) { + case HERO_ATTR_INDEX.BASE: + this.base = value; + } + } + } + } + + public getValues() { + let values: number[] = []; + for(let i = HERO_ATTR_INDEX.START; i < HERO_ATTR_INDEX.END; i++) { + switch(i) { + case HERO_ATTR_INDEX.BASE: + values.push(this.base); break; + } + } + return values; + } +} + +enum GLOBAL_ATTR_INDEX { + START, + SCHOOL = 0, + TITLE = 1, + TERAPH = 2, + END +} + +enum HERO_ATTR_INDEX { + START, + BASE = 0, // 角色基础属性(dic_zyz_hero的hp) + BASE_UP = 1, + END +} \ No newline at end of file diff --git a/game-server/app/services/role/createHero.ts b/game-server/app/services/role/createHero.ts index a3942cec1..4bcf77620 100644 --- a/game-server/app/services/role/createHero.ts +++ b/game-server/app/services/role/createHero.ts @@ -1,4 +1,4 @@ -import { FIGURE_UNLOCK_CONDITION, ITEM_CHANGE_REASON, REDIS_KEY, STATUS, TASK_TYPE, HERO_SYSTEM_TYPE } from "../../consts"; +import { FIGURE_UNLOCK_CONDITION, ITEM_CHANGE_REASON, REDIS_KEY, STATUS, TASK_TYPE, HERO_SYSTEM_TYPE, LINEUP_NUM } from "../../consts"; import { SkinModel } from "../../db/Skin"; import { HeroModel, HeroSkin, HeroType, HeroUpdate } from "../../db/Hero"; import { RoleModel, RoleType, RoleUpdate } from "../../db/Role"; @@ -8,7 +8,7 @@ import { TaskListReturn } from "../../domain/roleField/task"; import { GuildModel, GuildType } from "../../db/Guild"; import { PvpDefenseModel } from "../../db/PvpDefense"; import { pick } from "underscore"; -import { calculatetopLineup } from "../../pubUtils/playerCe"; +import { calculatetopLineup } from "../../pubUtils/util"; import { nowSeconds } from "../../pubUtils/timeUtil"; import { saveCeChangeLog } from "../../pubUtils/logUtil"; import { getRandSingleEelm, reduceCe, resResult } from "../../pubUtils/util"; @@ -20,18 +20,28 @@ import { checkTaskInCreateHero } from "../task/taskService"; import { ItemInter, RewardInter } from "../../pubUtils/interface"; import { transPiece } from "./util"; import { getInitHeroById } from "../roleService"; -import { addItems, combineFigureInfo, unlockFigureWithoutSave } from "./rewardService"; +import { addItems, combineFigureInfo, unlockFigure, unlockFigureWithoutSave } from "./rewardService"; +import { gameData } from "../../pubUtils/data"; +import { CalCe } from "./calCe"; +import { RoleCeUpdate } from "../../db/RoleCe"; -export class UpdateHeroes { - roleId: string; - roleName: string; - serverId: number; - incHeroNum: number = 0; - incRoleCe: number = 0; - pushHeroes: {hid: number, incHeroCe: number, ce: number, hero: HeroUpdate}[] = []; - roleUpdate: RoleUpdate; - role: RoleType; - guild: GuildType; +export class CreateHeroes { + private roleId: string; + private roleName: string; + private serverId: number; + private incHeroNum: number = 0; + private incRoleCe: number = 0; + private role: RoleType; + private guild: GuildType; + + // 推送信息 + private figureConditions: { type: FIGURE_UNLOCK_CONDITION, paramHid: number }[] = []; + private skins: SkinUpdate[] = []; + private heroes: HeroUpdate[] = []; + private roleCe: RoleCeUpdate = {}; + private resultHeroes: HeroType[] = []; + private topLineup: TopHero[] = []; + private topLineupCe: number = 0; constructor(roleId: string, roleName: string, serverId: number) { this.roleId = roleId; @@ -46,43 +56,66 @@ export class UpdateHeroes { public async getRole() { if(!this.role) { this.role = await RoleModel.findByRoleId(this.roleId); + this.topLineup = this.role.topLineup; + this.topLineupCe = this.role.topLineupCe; } return this.role; } - public addRoleUpdateParam(param: RoleUpdate) { - this.roleUpdate = {...this.roleUpdate, ...param}; + public async createHeroes(hids: number[]) { + let { roleId, roleName } = this; + for(let hid of hids) { + let initSkin = SkinModel.getInitInfo(hid); + let initHero = HeroModel.getInitInfo(hid, { roleId, roleName, skins: [new HeroSkin(initSkin)] }); + this.heroes.push(initHero); + this.skins.push(initSkin); + this.figureConditions.push({ type: FIGURE_UNLOCK_CONDITION.GET_HERO, paramHid: hid }); + this.incHeroNum ++; + } + await this.calCe(); // 计算战力 + await this.saveCeToDb(); } - public async updateDbCe(isCreate: boolean, heroInfo: HeroUpdate, originCe = 0) { + private async calCe() { let role = await this.getRole(); - if(isCreate) this.incHeroNum ++; - if(heroInfo != originCe) this.incRoleCe += heroInfo.ce - originCe; - this.addRoleUpdateParam(await calculatetopLineup(role, heroInfo.hid, heroInfo.ce, heroInfo._id )); - this.pushHeroes.push({ hid: heroInfo.hid, incHeroCe: heroInfo.ce - originCe, ce: heroInfo.ce, hero: heroInfo }); + let calCe = new CalCe(); + calCe.setInitHero(role, this.heroes); // 设置武将初始信息 + let ces = calCe.calHeroCe(); // 战力 + for(let hero of this.heroes) { + hero.ce = ces.get(hero.hid)||0; + hero.historyCe = hero.ce; + this.incRoleCe += hero.ce; + } + this.roleCe = calCe.getRoleCeTable(); } // 更新战力相关的各个表 - public async saveCeToDb() { + private async saveCeToDb() { let role = await this.getRole(); + // 更新武将表 + for(let hero of this.heroes) { + let resultHero = await HeroModel.createHero(hero); + this.resultHeroes.push(resultHero); + await calculatetopLineup(role, resultHero.hid, resultHero.ce, resultHero._id); + } + this.heroes = []; // 更新role表 - this.role = await RoleModel.updateRoleInfo(this.roleId, { - heroNum: this.incHeroNum + role.heroNum, ce: this.incRoleCe + role.ce, heroNumUpdatedAt: nowSeconds(), ...this.roleUpdate - }); - + role = await RoleModel.incRoleInfo(this.roleId, { heroNum: this.incHeroNum, ce: this.incRoleCe }, { heroNumUpdatedAt: nowSeconds(), }); + this.setRole(role); + // 更新皮肤表 + await SkinModel.insertSkins(this.roleId, this.roleName, this.skins) // 更新guild表 if(role.hasGuild) { this.guild = await GuildModel.updateCe(this.roleId, this.incRoleCe, true); // 公会更新战力 } - for(let { hid, incHeroCe } of this.pushHeroes) { - await PvpDefenseModel.updateCe(this.roleId, hid, incHeroCe); // 更新pvp防守阵战力 + for(let { hid, ce } of this.resultHeroes) { + await PvpDefenseModel.updateCe(this.roleId, hid, ce); // 更新pvp防守阵战力 } - saveCeChangeLog(this.role, this.incRoleCe, this.role.ce, HERO_SYSTEM_TYPE.INIT, this.pushHeroes.map(cur => cur.hid)); + saveCeChangeLog(role, this.incRoleCe, role.ce, HERO_SYSTEM_TYPE.INIT, this.resultHeroes.map(cur => cur.hid)); } public async updateRedisRank() { - let role = await this.getRole(); - let { serverId, roleId, pushHeroes } = this; + let { serverId, roleId, resultHeroes, role } = this; // 更新军团信息 if(this.guild) { let r = new Rank(REDIS_KEY.GUILD_INFO, { guildCode: this.guild.code }); @@ -99,12 +132,12 @@ export class UpdateHeroes { await r.setRankWithRoleInfo(roleId, reduceCe(role.topLineupCe), 0, role); // 最强武将 - for(let { hid, ce, hero } of pushHeroes) { + for(let hero of resultHeroes) { let r2 = new Rank(REDIS_KEY.TOP_HERO_RANK, { serverId }); - await r2.setRankWithHeroInfo(roleId, hid, reduceCe(ce), 0, hero); + await r2.setRankWithHeroInfo(roleId, hero.hid, hero.ce, 0, hero); - let r4 = new Rank(REDIS_KEY.HERO_RANK, { serverId, hid }); - await r4.setRankWithHeroInfo(roleId, hid, reduceCe(ce), 0, hero); + let r4 = new Rank(REDIS_KEY.HERO_RANK, { serverId, hid: hero.hid }); + await r4.setRankWithHeroInfo(roleId, hero.hid, hero.ce, 0, hero); } // 总战力 let r3 = new Rank(REDIS_KEY.SUM_CE_RANK, { serverId }); @@ -115,90 +148,26 @@ export class UpdateHeroes { await r5.generParamAndSet(REDIS_KEY.TOP_LINEUP_INFO, { roleId }, { role }); } - public async pushMessage(pinus: any, sid: string) { - let role = await this.getRole(); - let uids = [{ uid: this.roleId, sid }]; - pinus.app.get('channelService').pushMessageByUids('onPlayerCeUpdate', resResult(STATUS.SUCCESS, { ce: reduceCe(role.ce) , heros: this.pushHeroes.map(cur => { return {...cur, ce: reduceCe(cur.ce), incHeroCe: reduceCe(cur.incHeroCe) }}), topLineupCe: reduceCe(role.topLineupCe) }), uids); - } - -} - -export class CreateHeroes extends UpdateHeroes { - private resultHeroes: HeroType[] = []; - private heroNum = 0; - // 推送信息 - private figureInfos: { heads: Figure[], frames: Figure[], spines: Figure[] }[] = []; - private skinPushMessages: { heros: {skins: HeroSkin[], hid: number}[], skins: {id: number, hid: number, inc: number, reason: number }[]} = { heros: [], skins: [] }; - - private async getSkinsOfThisHero(hid: number, initSkinInfo: SkinUpdate, isInit: boolean) { - let allSkins = isInit? []: await SkinModel.findbyRoleAndHid(this.roleId, hid); - let skin = await SkinModel.insertSkins(this.roleId, this.roleName, [initSkinInfo]); - let skinInfos = skin.map(cur => ({ id: cur.id, hid, inc: 1, reason: ITEM_CHANGE_REASON.GET_HERO_UNLOCK_SKIN})) - this.skinPushMessages.skins.push(...skinInfos); - if(skin) allSkins.push(...skin); - let skins: HeroSkin[] = []; - for(let skin of allSkins) { - skins.push(new HeroSkin(skin.id, skin.skinId, skin._id, skin.id == initSkinInfo.id)); - } - return skins - } - - // game-server里面创建武将 - public async createWithHeroInfo(infos: Map) { - let role = await this.getRole(); - // 数据处理 - let conditions = new Array<{ type: number, paramHid?: number, paramFavourLv?: number, paramSkinId?: number }>(); // 解锁头像条件 - let initHeroInfos: HeroUpdate[] = []; - for (let [ hid, { heroInfo, skinInfo }] of infos) { - conditions.push({ type: FIGURE_UNLOCK_CONDITION.GET_HERO, paramHid: heroInfo.hid }); - this.updateDbCe(true, heroInfo); - // 皮肤使用初始加载进内存的数据 - let skins = await this.getSkinsOfThisHero(hid, { ...skinInfo, _id: new SkinModel()._id }, false); - let newAttr = new AttributeCal(); - newAttr.setLv(heroInfo.lv); - newAttr.setByDbData(role.attr, heroInfo.attr); - let heroCe = newAttr.calCe(); // 计算最终战力 - initHeroInfos.push({ ...heroInfo, skins, _id: new HeroModel()._id, ce: heroCe }); - this.heroNum ++; - } - // 武将使用初始加载数据插入 - this.resultHeroes = await HeroModel.insertHeroes(this.roleId, this.roleName, this.serverId, initHeroInfos); - let heroSkins = this.resultHeroes.map(cur => { return pick(cur, ['hid', 'skins']) }); - - this.skinPushMessages.heros.push(...heroSkins); - // 头像解锁 - let { figureInfo, frames, heads, spines } = unlockFigureWithoutSave(conditions, role); - this.figureInfos.push(figureInfo); - this.addRoleUpdateParam({ frames, heads, spines }); - // 更新战力 - await this.saveCeToDb(); - } - - // 创建初始账号时候的初始 - public async createWithInitInfo(infos: Map, figureInfo: { heads: Figure[], frames: Figure[], spines: Figure[] }) { - this.figureInfos.push(figureInfo); - let heroeInfos: HeroUpdate[] = []; - for (let [ hid, { heroInfo, skinInfo }] of infos) { - this.updateDbCe(true, heroInfo); - let model = new SkinModel(); - let skins = await this.getSkinsOfThisHero(hid, { ...skinInfo, _id: model._id }, true); - heroeInfos.push({ ...heroInfo, skins, _id: new HeroModel()._id}); - this.heroNum ++; - } - this.resultHeroes = await HeroModel.insertHeroes(this.roleId, this.roleName, this.serverId, heroeInfos); - } - public async pushMessage(sid: string) { let role = await this.getRole(); let uids = [{ uid: this.roleId, sid }]; - pinus.app.get('channelService').pushMessageByUids('onPlayerCeUpdate', resResult(STATUS.SUCCESS, { ce: reduceCe(role.ce) , heros: this.pushHeroes.map(cur => { return {...cur, ce: reduceCe(cur.ce), incHeroCe: reduceCe(cur.incHeroCe) }}), topLineupCe: reduceCe(role.topLineupCe) }), uids); - let figureInfo = combineFigureInfo(this.figureInfos); - if (!!figureInfo && (figureInfo.heads.length > 0 || figureInfo.frames.length > 0 || figureInfo.spines.length > 0)) { - pinus.app.get('channelService').pushMessageByUids('onHeadChange', resResult(STATUS.SUCCESS, { ...figureInfo }), uids); - } - pinus.app.get('channelService').pushMessageByUids('onHeroSkinChange', resResult(STATUS.SUCCESS, this.skinPushMessages), uids); + pinus.app.get('channelService').pushMessageByUids('onPlayerCeUpdate', resResult(STATUS.SUCCESS, { ce: role.ce, heros: this.resultHeroes.map(({ hid, ce }) => ({ hid, ce, incHeroCe: ce})), topLineupCe: role.topLineupCe}), uids); + + pinus.app.get('channelService').pushMessageByUids('onHeroSkinChange', resResult(STATUS.SUCCESS, this.getSkinPushMsg()), uids); pinus.app.get('channelService').pushMessageByUids('onHeroUpdate', resResult(STATUS.SUCCESS, { heroes: this.getResultHeroes() }), uids); - checkTaskInCreateHero(this.serverId, this.roleId, sid, this.heroNum, this.resultHeroes) + checkTaskInCreateHero(this.serverId, this.roleId, sid, this.incHeroNum, this.resultHeroes); + await unlockFigure(sid, this.roleId, this.figureConditions); + } + + private getSkinPushMsg() { + let skinPushMessages: {heros: {skins: HeroSkin[], hid: number}[], skins: {id: number, hid: number, inc: number, reason: number }[]} = { heros: [], skins:[] }; // 皮肤推送信息 + for(let { hid, skins } of this.resultHeroes) { + skinPushMessages.heros.push({ hid, skins }); + } + for(let { id, hid } of this.skins) { + skinPushMessages.skins.push({ id, hid, inc: 1, reason: ITEM_CHANGE_REASON.GET_HERO_UNLOCK_SKIN }) + } + return skinPushMessages; } public getResultHeroes() { @@ -225,25 +194,14 @@ export class CreateHeroes extends UpdateHeroes { let hids = heroInfo.map(cur => cur.hid); let userHeroesMap = await HeroModel.findMapByHidRange(hids, roleId); - let infos: Map = new Map(), pieces: ItemInter[] = []; + let createHids: number[] = [], pieces: ItemInter[] = []; for (let h of heroInfo) { let heroCount = h.count || 1; if (userHeroesMap.has(h.hid)) { let { pieceId, count } = transPiece(h.hid); pieces.push({ id: pieceId, count: count * heroCount }); } else { - let initInfo: { heroInfo: HeroUpdate, skinInfo: SkinUpdate }; - if(pinus.app.getServerType() == 'role') { - initInfo = getInitHeroById(h.hid); - } else { - let roleServers = pinus.app.getServersByType('role'); - let server = getRandSingleEelm(roleServers); - initInfo = await pinus.app.rpc.role.roleRemote.getInitHeroById.toServer(server.id, h.hid); - } - - initInfo.heroInfo = { ...initInfo.heroInfo, ...h }; - - infos.set(h.hid, initInfo); + createHids.push(h.hid); userHeroesMap.set(h.hid, null); if (heroCount > 1) { let { pieceId, count } = transPiece(h.hid); @@ -253,9 +211,9 @@ export class CreateHeroes extends UpdateHeroes { } let resultHeroes: HeroType[] = [], resultItems: RewardInter[] = [], heroes: HeroShowParam[] = []; - if (infos.size > 0) { + if (createHids.length > 0) { let createHero = new CreateHeroes(roleId, roleName, serverId); - await createHero.createWithHeroInfo(infos); + await createHero.createHeroes(createHids); await createHero.pushMessage(sid); await createHero.updateRedisRank(); heroes = createHero.getShowHeroes(); diff --git a/game-server/app/services/role/initRoleService.ts b/game-server/app/services/role/initRoleService.ts deleted file mode 100644 index dc086cf86..000000000 --- a/game-server/app/services/role/initRoleService.ts +++ /dev/null @@ -1,61 +0,0 @@ -import { DEFAULT_HEROES, DEFAULT_HERO_LV, FIGURE_UNLOCK_CONDITION, HERO_SYSTEM_TYPE, LINEUP_NUM } from "../../consts"; -import { HeroModel, HeroSkin, HeroUpdate } from "../../db/Hero"; -import { RoleModel, RoleUpdate } from "../../db/Role"; -import { SkinModel, SkinUpdate } from "../../db/Skin"; -import { TopHero } from "../../domain/dbGeneral"; -import { CalHeroCe, CalRoleCe } from "../../domain/roleField/calCe"; -import { gameData, getHeroExpByLv } from "../../pubUtils/data"; -import { unlockFigureWithoutSave } from "./rewardService"; - -// 储存在内存中的初始数据 -export function getInitRoleInfo() { - let topLineup: TopHero[] = [], topLineupCe = 0, allCe = 0, - heroes: HeroUpdate[] = [], initHeroes: HeroUpdate[] = [], initSkins: SkinUpdate[] = [], heroNum = 0, - conditions: {type: FIGURE_UNLOCK_CONDITION, paramHid: number }[] = []; - let role = new RoleModel(); - let calRoleCe = new CalRoleCe(role); - let roleAttr = calRoleCe.cal(HERO_SYSTEM_TYPE.INIT); - - for(let { actorId: hid } of gameData.recruit) { - let { quality, initialStars: star, jobid: job, name: hName, initialSkin } = gameData.hero.get(hid); - // 皮肤 - let skin = new SkinModel(); - let dicFashion = gameData.fashion.get(initialSkin); - if(!dicFashion) { - console.log(`not found skin: ${initialSkin} of ${hid}`); - continue; - } - let skinInfo = { ...skin.toJSON(), id: initialSkin, hid, skinName: dicFashion.name, skinId: dicFashion.heroId }; - initSkins.push(skinInfo); - // 武将 - let hero = new HeroModel(); - let heroInfo = {...hero.toJSON(), hid, star, quality, hName, job, skins: [new HeroSkin(initialSkin, skinInfo.skinId, skinInfo._id, true)], skinId: skinInfo.skinId, lv: DEFAULT_HERO_LV, exp: getHeroExpByLv(DEFAULT_HERO_LV - 1) || 0 }; - let calHeroCe = new CalHeroCe(hid, heroInfo); - let heroAttr = calHeroCe.cal(HERO_SYSTEM_TYPE.INIT); - let ce = calHeroCe.getCalculatedCe(roleAttr); - heroes.push({ ...heroInfo, attr: heroAttr, ce, historyCe: ce }); - // 更新role表 - if(DEFAULT_HEROES.includes(hid)) { - // 头像 - conditions.push({ type: FIGURE_UNLOCK_CONDITION.GET_HERO, paramHid: hid }); - allCe += ce; - heroNum++; - initHeroes.push({ ...heroInfo, attr: heroAttr, ce, historyCe: ce }); - } - } - let { figureInfo, heads, frames, spines } = unlockFigureWithoutSave(conditions, role); - // 最强阵容 - initHeroes.sort((a, b) => { return b.ce - a.ce }); - for(let i = 0; i < LINEUP_NUM; i++) { - if(initHeroes[i]) { - let { hid, ce, _id } = initHeroes[i]; - topLineup.push({ hid, ce, hero: _id }); - topLineupCe += ce; - } - } - - let initRole: RoleUpdate = { topLineupCe, topLineup, attr: roleAttr, ce: allCe, heroNum, heroNumUpdatedAt: Date.now(), heads, frames, spines }; - return { - role: initRole, heroes, skins: initSkins, figureInfo - } -} \ No newline at end of file diff --git a/game-server/app/services/role/rewardService.ts b/game-server/app/services/role/rewardService.ts index 4702ce9b2..88baa19ee 100644 --- a/game-server/app/services/role/rewardService.ts +++ b/game-server/app/services/role/rewardService.ts @@ -367,7 +367,7 @@ export async function addSkin(roleId: string, roleName: string, sid: string, ski if (hero) { // 有武将的,将皮肤链接到武将上 let curSkin = hero.skins.find(cur => cur.id == skinId); if (!curSkin) { - hero.skins.push(new HeroSkin(skin.id, skin.skinId, skin._id, enable )); + hero.skins.push(new HeroSkin(skin, enable)); await HeroModel.updateHeroInfo(roleId, hero.hid, hero); } return hero; diff --git a/game-server/app/services/roleService.ts b/game-server/app/services/roleService.ts index ac51365fd..7af0e6390 100644 --- a/game-server/app/services/roleService.ts +++ b/game-server/app/services/roleService.ts @@ -1,14 +1,14 @@ import { ChannelUser } from './../domain/ChannelUser'; import { Channel, pinus } from 'pinus'; import { getRandValueByMinMax, getRandEelm, decodeIdCntArrayStr } from '../pubUtils/util'; -import { DEFAULT_HEROES, ROLE_SELECT, TALENT_RELATION_TYPE, TERAPH_RANDOM } from "../consts"; +import { DEFAULT_HEROES, LINEUP_NUM, ROLE_SELECT, TALENT_RELATION_TYPE, TERAPH_RANDOM } from "../consts"; import { DicTeraph } from '../pubUtils/dictionary/DicTeraph'; import { Teraph, RoleModel, RoleType, RoleUpdate } from '../db/Role'; import { SCHOOL } from '../pubUtils/dicParam'; import { gameData, getHeroInitTalent } from '../pubUtils/data'; import { SchoolModel } from '../db/School'; import { SclResultInter, SclPosInter, RewardInter, ItemInter } from '../pubUtils/interface'; -import { HeroSkin, HeroUpdate, Talent } from '../db/Hero'; +import { HeroModel, HeroSkin, HeroUpdate, Talent } from '../db/Hero'; import { SkinUpdate } from '../db/Skin'; import { Figure } from '../domain/dbGeneral'; import { pick } from 'underscore'; @@ -251,4 +251,4 @@ export function initSkinTalent(skins: HeroSkin[], isAll = false) { } } return newSkins -} \ No newline at end of file +} diff --git a/shared/db/Hero.ts b/shared/db/Hero.ts index e98d12233..a41a73341 100644 --- a/shared/db/Hero.ts +++ b/shared/db/Hero.ts @@ -2,12 +2,12 @@ import BaseModel from './BaseModel'; import { index, getModelForClass, prop, Ref, mongoose, DocumentType } from '@typegoose/typegoose'; // import Equip, { } from './Equip'; import { CounterModel } from './Counter'; -import { COUNTER, HERO_CE_RATIO } from '../consts'; +import { COUNTER, DEFAULT_HERO_LV, HERO_CE_RATIO } from '../consts'; import { reduceCe } from '../pubUtils/util'; -import Skin from './Skin'; +import Skin, { SkinUpdate } from './Skin'; import { SearchHeroParam } from '../domain/backEndField/search'; import { Reward } from '../domain/battleField/pvp'; -import { getHeroInitTalent } from '../pubUtils/data'; +import { gameData, getHeroExpByLv, getHeroInitTalent } from '../pubUtils/data'; type CeAttrUpdate = Partial; export class CeAttrData { @@ -88,12 +88,12 @@ export class HeroSkin { @prop({ required: true }) usedTalentPoint: number; // 已使用的天赋点数 - constructor(id: number, skinId: number, skin: string, enable: boolean) { - this.id = id; - this.skinId = skinId; - this.skin = skin; + constructor(skin: SkinUpdate, enable = true) { + this.id = skin.id; + this.skinId = skin.skinId; + this.skin = skin._id; this.enable = enable; - this.talent = getHeroInitTalent(skinId); + this.talent = getHeroInitTalent(skin.skinId); this.usedTalentPoint = 0; } } @@ -274,16 +274,18 @@ export default class Hero extends BaseModel { return hero; } - public static getInitInfo(heroInfo: HeroUpdate = {}): HeroUpdate { + public static getInitInfo(hid: number, heroInfo: HeroUpdate = {}): HeroUpdate { + let dicHero = gameData.hero.get(hid) + let { quality, initialStars: star, jobid: job, name: hName } = dicHero; const doc = new HeroModel(); - const update = { ...doc.toJSON(), ...heroInfo}; + const update = { ...doc.toJSON(), hid, skinId: hid, hName, star, quality, job, lv: DEFAULT_HERO_LV, exp: getHeroExpByLv(DEFAULT_HERO_LV - 1) || 0, ...heroInfo}; delete update._id; return update } public static async createHero(heroInfo: HeroUpdate, lean = true) { const seqId = await CounterModel.getNewCounter(COUNTER.HID) || -1; - const update = this.getInitInfo({ ...heroInfo, seqId }); + const update = this.getInitInfo(heroInfo.hid, { ...heroInfo, seqId }); const hero: HeroType = await HeroModel.findOneAndUpdate({ roleId: heroInfo.roleId, hid: heroInfo.hid }, update, { upsert: true, new: true }).lean(lean); return hero; } diff --git a/shared/db/RoleCe.ts b/shared/db/RoleCe.ts new file mode 100644 index 000000000..5fd8bb26c --- /dev/null +++ b/shared/db/RoleCe.ts @@ -0,0 +1,98 @@ +import BaseModel from './BaseModel'; +import { index, getModelForClass, prop, DocumentType } from '@typegoose/typegoose'; + +// 全局加成 +export class GlobalAttr { + @prop({ required: true }) + attrId: number; // 属性id + @prop({ required: true }) + values: number[]; // 战力公式中的全局加成的数据,查表后的结果 +} + +// 单武将加成 +export class HeroAttr { + @prop({ required: true }) + hid: number; // 武将id + @prop({ required: true }) + lv: number; + @prop({ required: true, type: () => HeroAttrCell, _id: false }) + attrs: HeroAttrCell[]; +} + +export class HeroAttrCell { + @prop({ required: true }) + attrId: number; // 属性id + @prop({ required: true }) + values: number[]; // 战力公式中的武将加成的数据,查表后的结果 +} + +// 装备加成 +class EquipAttr { + @prop({ required: true }) + hid: number; // 武将id + @prop({ required: true }) + eplaceId: number; // 装备位置 + @prop({ required: true }) + attrId: number; // 属性id + @prop({ required: true }) + values: number[]; // 战力公式中的武将加成的数据,查表后的结果 +} + +// 百家学宫加成 +class SchoolAttr { + @prop({ required: true }) + hid: number; // 武将id + @prop({ required: true }) + attrId: number; // 属性id + @prop({ required: true }) + value: number; // 百家学宫有多个武将,单独拎出来方便计算,计算之后结果存到globaAttrs的global1 +} + +// 名将谱加成 +class ScrollAttr { + @prop({ required: true }) + hid: number; // 武将id + @prop({ required: true }) + attrId: number; // 属性id + @prop({ required: true }) + value: number; // 百家学宫有多个武将,单独拎出来方便计算,计算之后结果存到globaAttrs的global1 +} + +/** + * 属性表 +*/ + +@index({ roleId: 1 }) +@index({ roleId: 1 }) + +export default class RoleCe extends BaseModel { + + @prop({ required: true }) + roleId: string; // 角色 id + + @prop({ required: true, type: GlobalAttr, _id: false }) + globalAttrs: GlobalAttr[] + + @prop({ required: true, type: HeroAttr, _id: false }) + heroAttrs: HeroAttr[] + + @prop({ required: true, type: EquipAttr, _id: false }) + equipAttrs: EquipAttr[] + + @prop({ required: true, type: SchoolAttr, _id: false }) + schoolAttr: SchoolAttr[]; + + @prop({ required: true, type: ScrollAttr, _id: false }) + scrollAttrs: ScrollAttr[]; + + public static async findByRoleId(roleId: string) { + let result: RoleCeType[] = await RoleCeModel.find({ roleId }).lean(); + return result; + } + +} + +export const RoleCeModel = getModelForClass(RoleCe); + +export interface RoleCeType extends Pick, keyof RoleCe> { }; +export type RoleCeUpdate = Partial; \ No newline at end of file diff --git a/shared/db/Skin.ts b/shared/db/Skin.ts index e8bb3c54b..62f2201ad 100644 --- a/shared/db/Skin.ts +++ b/shared/db/Skin.ts @@ -1,5 +1,6 @@ import BaseModel from './BaseModel'; import { index, getModelForClass, prop, DocumentType, modelOptions } from '@typegoose/typegoose'; +import { gameData } from '../pubUtils/data'; @index({ roleId: 1, id: 1 }) @index({ seqId: 1 }) @modelOptions({ schemaOptions: { id: false } }) @@ -28,6 +29,15 @@ export default class Skin extends BaseModel { return rec; } + public static getInitInfo(hid: number): SkinUpdate { + let dicHero = gameData.hero.get(hid); + let dicFashion = gameData.fashion.get(dicHero.initialSkin) + const doc = new SkinModel(); + const update = { ...doc.toJSON(), id: dicFashion.id, skinId: dicFashion.heroId, skinName: dicFashion.name, hid}; + delete update._id; + return update + } + public static async insertSkins(roleId: string, roleName: string, skinInfos: SkinUpdate[]) { let insertInfos: SkinUpdate[] = []; for(let skinInfo of skinInfos) { diff --git a/shared/pubUtils/playerCe.ts b/shared/pubUtils/playerCe.ts index f67f9e374..53732b10a 100644 --- a/shared/pubUtils/playerCe.ts +++ b/shared/pubUtils/playerCe.ts @@ -4,7 +4,7 @@ import { HERO_SYSTEM_TYPE, ABI_TYPE, HERO_CE_RATIO, LINEUP_NUM, TALENT_RELATION_TYPE } from '../consts'; -import { cal, deepCopy, getAllAttrStage, reduceCe } from './util'; +import { cal, calculatetopLineup, 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'; @@ -209,53 +209,6 @@ export async function calPlayerCe(hero: HeroType, update: HeroUpdate, type: numb 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 }; -} /** * 添加皮肤全局加成 diff --git a/shared/pubUtils/util.ts b/shared/pubUtils/util.ts index c221dd410..ee094136f 100644 --- a/shared/pubUtils/util.ts +++ b/shared/pubUtils/util.ts @@ -6,13 +6,14 @@ import { isNumber } from 'underscore'; const csprng = require('csprng'); import fs = require('fs'); import path = require('path'); -import { HERO_CE_RATIO, ABI_STAGE, GACHA_TO_FLOOR, REFRESH_TIME, ROBOT_SYS_TYPE, ITEM_CHANGE_REASON, WAR_TYPE } from '../consts'; +import { HERO_CE_RATIO, ABI_STAGE, GACHA_TO_FLOOR, REFRESH_TIME, ROBOT_SYS_TYPE, ITEM_CHANGE_REASON, WAR_TYPE, LINEUP_NUM } from '../consts'; import { findIndex } from 'underscore'; import { getTimeFunM } from './timeUtil'; import { Floor } from '../domain/activityField/gachaField'; import { WhiteListModel } from '../db/RegionWhiteList'; import { RewardInter } from './interface'; +import { RoleType } from '../db/Role'; const randomName = require("chinese-random-name"); const moment = require('moment'); const crypto = require('crypto'); @@ -788,3 +789,59 @@ export function stringToRewardInter(rewardStr: string): Array { } return result } + +export function addToMap(map: Map, id: T, value: number) { + if(!map.has(id)) { + map.set(id, value); + } else { + map.set(id, map.get(id) + value); + } +} + +/** + * 计算最强阵容战力 + * @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 }; +} From 68e4d2232d6ca4a84cffa82eb7e2cd273f3e303a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E9=99=86=E8=8E=B9?= Date: Fri, 25 Mar 2022 20:10:07 +0800 Subject: [PATCH 02/12] =?UTF-8?q?=E6=88=98=E5=8A=9B=EF=BC=9A=E8=A1=A5?= =?UTF-8?q?=E5=85=85=E6=95=B0=E6=8D=AE=E7=BB=93=E6=9E=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../services/activity/monthlyTicketService.ts | 2 - game-server/app/services/role/calCe.ts | 446 ++++++++++++++---- game-server/app/services/role/createHero.ts | 4 +- shared/db/RoleCe.ts | 42 +- 4 files changed, 376 insertions(+), 118 deletions(-) diff --git a/game-server/app/services/activity/monthlyTicketService.ts b/game-server/app/services/activity/monthlyTicketService.ts index e3a16faab..09ebc2ba7 100644 --- a/game-server/app/services/activity/monthlyTicketService.ts +++ b/game-server/app/services/activity/monthlyTicketService.ts @@ -222,8 +222,6 @@ export function getVipRegretCnt(vipStartTime: number) { } export function vipCanSkipTower(recommendCeSum: number, heroesCeSum: number, vipStartTime: number) { - console.log('####', recommendCeSum, heroesCeSum, vipStartTime, ); let ratio = vipStartTime > 0? VIP.VIP_TOWER_SKIP_CE_RATIO_WITH_VIP: VIP.VIP_TOWER_SKIP_CE_RATIO_WITHOUT_VIP; - console.log('#####', VIP.VIP_TOWER_SKIP_CE_RATIO_WITH_VIP, VIP.VIP_TOWER_SKIP_CE_RATIO_WITHOUT_VIP, ratio) return heroesCeSum > recommendCeSum * ratio; } \ No newline at end of file diff --git a/game-server/app/services/role/calCe.ts b/game-server/app/services/role/calCe.ts index 7dc7aaf2b..de2c9ff53 100644 --- a/game-server/app/services/role/calCe.ts +++ b/game-server/app/services/role/calCe.ts @@ -1,7 +1,7 @@ import { ABI_STAGE, ABI_STAGE_TO_TYPE, ABI_TYPE_MAIN, SEID_TYPE } from "../../consts"; import { HeroUpdate } from "../../db/Hero"; import { RoleUpdate, Teraph } from "../../db/Role"; -import { GlobalAttr, HeroAttr, HeroAttrCell, RoleCeType } from "../../db/RoleCe"; +import { AttrCell, EquipAttr, HeroAttr, RoleCeType } from "../../db/RoleCe"; import { AttributeCal } from "../../domain/roleField/attribute"; import { gameData, getHeroStarByQuality, getHeroWakeByQuality, getTeraph } from "../../pubUtils/data"; import { DicRandomEffectPool } from "../../pubUtils/dictionary/DicRandomEffectPool"; @@ -10,10 +10,14 @@ import { addToMap, deepCopy } from "../../pubUtils/util"; class RoleCe { roleId: string; - globalAttrs: Map = new Map(); // attrId => GlobalCe - heroAttrs: Map = new Map(); // hid+attrId => HeroCe + globalAttrs: Map = new Map(); // attrId => GlobalAttr + heroAttrs: Map = new Map(); // hid+attrId => HeroAttr heroAttrsByHid: Map = new Map(); // hid => [hid+attrId] + equipAttrs: Map = new Map(); // hid+eplaceId+attrId => EquipAttr + equipAttrsByHid: Map = new Map(); // hid => [hid+eplaceId+attrId] + equipAttrsByHidAndEplace: Map = new Map(); // hid+eplaceId =>+eplaceId+attrId] heroLv: Map = new Map(); + equipLv: Map = new Map(); // hid+eplaceId => lv setRoleCe(roleCe: RoleCeType) { this.roleId = roleCe.roleId; @@ -28,6 +32,13 @@ class RoleCe { obj.setByRoleCe(cell); } } + for(let { hid, eplaceId, lv, attrs } of roleCe.equipAttrs) { + this.equipLv.set(`${hid}_${eplaceId}`, lv); + for(let cell of attrs) { + let obj = this.getEquipAttrByHidAndId(hid, eplaceId, cell.attrId); + obj.setByRoleCe(cell); + } + } } public getGlobalAttrById(attrId: number) { @@ -62,14 +73,44 @@ class RoleCe { return this.heroAttrs.get(key); } + public getEquipAttrByHidAndId(hid: number, eplaceId: number, attrId: number) { + let key = `${hid}_${eplaceId}_${attrId}`; + if(!this.equipAttrs.has(key)) { + if(ABI_TYPE_MAIN.indexOf(attrId) != -1) { + let obj = new EquipMainAttr(hid, attrId); + this.equipAttrs.set(key, obj); + } else { + let obj = new EquipSubAttr(hid, attrId); + this.equipAttrs.set(key, obj); + } + + if(!this.equipAttrsByHid.has(hid)) { + this.equipAttrsByHid.set(hid, []); + } + this.equipAttrsByHid.get(hid).push(key); + let key2 = `${hid}_${eplaceId}`; + if(!this.equipAttrsByHidAndEplace.has(key2)) { + this.equipAttrsByHidAndEplace.set(key2, { hid, eplaceId, keys: []}); + } + this.equipAttrsByHidAndEplace.get(key2).keys.push(key); + } + return this.equipAttrs.get(key); + } + public calHeroCe() { let ces = new Map(); // hid => [{attrId, val}] for(let [hid, keys] of this.heroAttrsByHid) { let lv = this.heroLv.get(hid)||1; for(let key of keys) { - let { attrId, base, baseUp, starUp, skillRatio, skill, job } = this.heroAttrs.get(key); - let { schoolRatio, title, teraph } = this.getGlobalAttrById(attrId); - let val = ( base + lv * ( baseUp + starUp ) + skill + job) * (1 + skillRatio + schoolRatio ) + teraph + title; + let { attrId, base = 0, job = 0, starUp = 0, connect = 0, favour = 0, talent = 0, equip = 0, equipUp = 0, equipStone = 0 } = this.heroAttrs.get(key); + let { school = 0, teraph = 0, title = 0, scroll = 0, skin = 0 } = this.getGlobalAttrById(attrId); + let val = 0; + if(ABI_TYPE_MAIN.indexOf(attrId)) { + // {[hp1 + lv * hp2 + hp3 * ( 1 + hp4 )] * (1 + hp5 ) + [( hp6+hp7)*(1+hp8)] } * ( 1 + hp9 ) + hp10 + hp11 + val = ((base + job + lv * starUp + connect * ( 1 + favour )) * ( 1 + school + talent ) + equip ) * ( 1 + equipUp ) + equipStone + teraph + title + scroll + skin; + } else { + val = base + job + talent + teraph + school + title + equip + skin; + } if(!ces.has(hid)) ces.set(hid, []); ces.get(hid).push({ id: attrId, val }); } @@ -84,14 +125,14 @@ class RoleCe { } public getRoleCeTable() { - let globalAttrs: GlobalAttr[] = []; + let globalAttrs: AttrCell[] = []; for(let [_, globalAttr] of this.globalAttrs) { globalAttrs.push(globalAttr.getGlobalAttr()); } let heroAttrs: HeroAttr[] = []; for(let [hid, keys] of this.heroAttrsByHid) { let lv = this.heroLv.get(hid); - let attrs: HeroAttrCell[] = []; + let attrs: AttrCell[] = []; for(let key of keys) { let heroAttr = this.heroAttrs.get(key); attrs.push(heroAttr.getHeroAttrCell()); @@ -100,8 +141,20 @@ class RoleCe { hid, lv, attrs }); } + let equipAttrs: EquipAttr[] = []; + for(let [key2, { hid, eplaceId, keys }] of this.equipAttrsByHidAndEplace) { + let lv = this.equipLv.get(key2); + let attrs: AttrCell[] = []; + for(let key of keys) { + let equipAttr = this.equipAttrs.get(key); + attrs.push(equipAttr.getEquipAttrCell()); + } + equipAttrs.push({ + hid, eplaceId, lv, attrs + }); + } return { - roleId: this.roleId, globalAttrs, heroAttrs + roleId: this.roleId, globalAttrs, heroAttrs, equipAttrs } } } @@ -109,11 +162,11 @@ class RoleCe { // 计算函数 export class CalCe extends RoleCe { public setInitHero(role: RoleUpdate, heroes: HeroUpdate[]) { + this.roleId = role.roleId; for(let { hid, skinId, lv, quality, star, starStage, colorStar, colorStarStage, job, jobStage, } of heroes) { this.setHeroBase(hid, skinId); this.setHeroLv(hid, lv); this.setHeroStar(hid, job, quality, star, starStage, colorStar, colorStarStage); - this.setSkill(hid, skinId, star, colorStar); this.setJob(hid, job, jobStage); } this.setTitle(role.title); @@ -127,10 +180,6 @@ export class CalCe extends RoleCe { let heroAttr = this.getHeroAttrByHidAndId(hid, attrId); heroAttr.base = value; } - for(let [attrId, value] of dicHero.baseAbilityUpArr) { - let heroAttr = this.getHeroAttrByHidAndId(hid, attrId); - heroAttr.baseUp = value; - } } // 武将等级 @@ -161,30 +210,6 @@ export class CalCe extends RoleCe { } - // 武将星级解锁被动技能计算 - public setSkill(hid: number, skinId: number, _star: number, _colorStar: number) { - let seidList = new Map(); // type => seid - let dicHero = gameData.hero.get(skinId); - let { starSeidArr, colorStarSeidArr } = gameData.heroSkill.get(dicHero.skill); - for (let { star, value, type } of starSeidArr) { - if (_star >= star) seidList.set(type, value); - } - for (let { star, value, type } of colorStarSeidArr) { - if (_colorStar >= star) seidList.set(type, value); - } - let list: number[] = []; - for(let [_type, value] of seidList) list.push(value); - let { fixUp, ratioUp } = this.addSeidEffect(list); - for(let [attrId, value] of fixUp) { - let heroAttr = this.getHeroAttrByHidAndId(hid, attrId); - heroAttr.skill = value; - } - for(let [attrId, value] of ratioUp) { - let heroAttr = this.getHeroAttrByHidAndId(hid, attrId); - heroAttr.skillRatio = value; - } - } - // 职业基础 public setJob(hid: number, job: number, jobStage: number) { const dicJob = gameData.job.get(job); @@ -284,15 +309,17 @@ export class CalCe extends RoleCe { abstract class GlobalAllAttr { attrId: number; - schoolRatio: number = 0; - title: number = 0; + school: number = 0; teraph: number = 0; + title: number = 0; + scroll: number = 0; + skin: number = 0; constructor(attrId: number) { this.attrId = attrId; } - abstract setByRoleCe(data: GlobalAttr): void; + abstract setByRoleCe(data: AttrCell): void; abstract getValues(): number[]; public getGlobalAttr() { @@ -305,17 +332,21 @@ abstract class GlobalAllAttr { class GlobalMainAttr extends GlobalAllAttr { - public setByRoleCe(globalAttr: GlobalAttr) { + public setByRoleCe(globalAttr: AttrCell) { for(let i = 0; i < globalAttr.values.length; i++) { let value = globalAttr.values[i]; if(value != undefined) { switch(i) { - case GLOBAL_ATTR_INDEX.SCHOOL: - this.schoolRatio = value; break; - case GLOBAL_ATTR_INDEX.TITLE: - this.title = value; break; - case GLOBAL_ATTR_INDEX.TERAPH: + case GLOBAL_MAIN_ATTR_INDEX.SCHOOL: + this.school = value; break; + case GLOBAL_MAIN_ATTR_INDEX.TERAPH: this.teraph = value; break; + case GLOBAL_MAIN_ATTR_INDEX.TITLE: + this.title = value; break; + case GLOBAL_MAIN_ATTR_INDEX.SCROLL: + this.scroll = value; break; + case GLOBAL_MAIN_ATTR_INDEX.SKIN: + this.skin = value; break; } } } @@ -323,14 +354,23 @@ class GlobalMainAttr extends GlobalAllAttr { public getValues() { let values: number[] = []; - for(let i = GLOBAL_ATTR_INDEX.START; i < GLOBAL_ATTR_INDEX.END; i++) { + for(let i = GLOBAL_MAIN_ATTR_INDEX.START; i < GLOBAL_MAIN_ATTR_INDEX.END; i++) { switch(i) { - case GLOBAL_ATTR_INDEX.SCHOOL: - values.push(this.schoolRatio); break; - case GLOBAL_ATTR_INDEX.TITLE: - values.push(this.title); break; - case GLOBAL_ATTR_INDEX.TERAPH: - values.push(this.teraph); break; + case GLOBAL_MAIN_ATTR_INDEX.SCHOOL: + if(this.school) values[i] = this.school; + break; + case GLOBAL_MAIN_ATTR_INDEX.TERAPH: + if(this.teraph) values[i] = this.teraph; + break; + case GLOBAL_MAIN_ATTR_INDEX.TITLE: + if(this.title) values[i] = this.title; + break; + case GLOBAL_MAIN_ATTR_INDEX.SCROLL: + if(this.scroll) values[i] = this.scroll; + break; + case GLOBAL_MAIN_ATTR_INDEX.SKIN: + if(this.skin) values[i] = this.skin; + break; } } return values; @@ -339,17 +379,19 @@ class GlobalMainAttr extends GlobalAllAttr { class GlobalSubAttr extends GlobalAllAttr { - public setByRoleCe(globalAttr: GlobalAttr) { + public setByRoleCe(globalAttr: AttrCell) { for(let i = 0; i < globalAttr.values.length; i++) { let value = globalAttr.values[i]; if(value != undefined) { switch(i) { - case GLOBAL_ATTR_INDEX.SCHOOL: - this.schoolRatio = value; break; - case GLOBAL_ATTR_INDEX.TITLE: - this.title = value; break; - case GLOBAL_ATTR_INDEX.TERAPH: + case GLOBAL_SUB_ATTR_INDEX.SCHOOL: + this.school = value; break; + case GLOBAL_MAIN_ATTR_INDEX.TERAPH: this.teraph = value; break; + case GLOBAL_MAIN_ATTR_INDEX.TITLE: + this.title = value; break; + case GLOBAL_MAIN_ATTR_INDEX.SKIN: + this.skin = value; break; } } } @@ -357,14 +399,20 @@ class GlobalSubAttr extends GlobalAllAttr { public getValues() { let values: number[] = []; - for(let i = GLOBAL_ATTR_INDEX.START; i < GLOBAL_ATTR_INDEX.END; i++) { + for(let i = GLOBAL_MAIN_ATTR_INDEX.START; i < GLOBAL_MAIN_ATTR_INDEX.END; i++) { switch(i) { - case GLOBAL_ATTR_INDEX.SCHOOL: - values.push(this.schoolRatio); break; - case GLOBAL_ATTR_INDEX.TITLE: - values.push(this.title); break; - case GLOBAL_ATTR_INDEX.TERAPH: - values.push(this.teraph); break; + case GLOBAL_MAIN_ATTR_INDEX.SCHOOL: + if(this.school) values[i] = this.school; + break; + case GLOBAL_MAIN_ATTR_INDEX.TERAPH: + if(this.teraph) values[i] = this.teraph; + break; + case GLOBAL_MAIN_ATTR_INDEX.TITLE: + if(this.title) values[i] = this.title; + break; + case GLOBAL_MAIN_ATTR_INDEX.SKIN: + if(this.skin) values[i] = this.skin; + break; } } return values; @@ -375,12 +423,14 @@ abstract class HeroAllAttr { hid: number; attrId: number; base: number = 0; - lv: number = 0; - baseUp: number = 0; - starUp: number = 0; - skillRatio: number = 0; - skill: number = 0; job: number = 0; + starUp: number = 0; + connect: number = 0; + favour: number = 0; + talent: number = 0; + equip: number = 0; + equipUp: number = 0; + equipStone: number = 0; constructor(hid: number, attrId: number, ) { this.hid = hid; @@ -388,7 +438,7 @@ abstract class HeroAllAttr { } - abstract setByRoleCe(data: GlobalAttr): void; + abstract setByRoleCe(data: AttrCell): void; abstract getValues(): number[]; public getHeroAttrCell() { @@ -400,13 +450,29 @@ abstract class HeroAllAttr { } class HeroMainAttr extends HeroAllAttr { - public setByRoleCe(heroAttr: HeroAttrCell) { + public setByRoleCe(heroAttr: AttrCell) { for(let i = 0; i < heroAttr.values.length; i++) { let value = heroAttr.values[i]; if(value != undefined) { switch(i) { - case HERO_ATTR_INDEX.BASE: - this.base = value; + case HERO_MAIN_ATTR_INDEX.BASE: + this.base = value; break; + case HERO_MAIN_ATTR_INDEX.JOB: + this.job = value; break; + case HERO_MAIN_ATTR_INDEX.STAR_UP: + this.starUp = value; break; + case HERO_MAIN_ATTR_INDEX.CONNECT: + this.connect = value; break; + case HERO_MAIN_ATTR_INDEX.FAVOUR: + this.favour = value; break; + case HERO_MAIN_ATTR_INDEX.TALENT: + this.talent = value; break; + case HERO_MAIN_ATTR_INDEX.EQUIP: + this.equip = value; break; + case HERO_MAIN_ATTR_INDEX.EQUIP_UP: + this.equipUp = value; break; + case HERO_MAIN_ATTR_INDEX.EQUIP_STONE: + this.equipStone = value; break; } } } @@ -414,10 +480,35 @@ class HeroMainAttr extends HeroAllAttr { public getValues() { let values: number[] = []; - for(let i = HERO_ATTR_INDEX.START; i < HERO_ATTR_INDEX.END; i++) { + for(let i = HERO_MAIN_ATTR_INDEX.START; i < HERO_MAIN_ATTR_INDEX.END; i++) { switch(i) { - case HERO_ATTR_INDEX.BASE: - values.push(this.base); break; + case HERO_MAIN_ATTR_INDEX.BASE: + if(this.base) values[i] = this.base; + break; + case HERO_MAIN_ATTR_INDEX.JOB: + if(this.job) values[i] = this.job; + break; + case HERO_MAIN_ATTR_INDEX.STAR_UP: + if(this.starUp) values[i] = this.starUp; + break; + case HERO_MAIN_ATTR_INDEX.CONNECT: + if(this.connect) values[i] = this.connect; + break; + case HERO_MAIN_ATTR_INDEX.FAVOUR: + if(this.favour) values[i] = this.favour; + break; + case HERO_MAIN_ATTR_INDEX.TALENT: + if(this.talent) values[i] = this.talent; + break; + case HERO_MAIN_ATTR_INDEX.EQUIP: + if(this.equip) values[i] = this.equip; + break; + case HERO_MAIN_ATTR_INDEX.EQUIP_UP: + if(this.equipUp) values[i] = this.equipUp; + break; + case HERO_MAIN_ATTR_INDEX.EQUIP_STONE: + if(this.equipStone) values[i] = this.equipStone; + break; } } return values; @@ -425,13 +516,19 @@ class HeroMainAttr extends HeroAllAttr { } class HeroSubAttr extends HeroAllAttr { - public setByRoleCe(heroAttr: HeroAttrCell) { + public setByRoleCe(heroAttr: AttrCell) { for(let i = 0; i < heroAttr.values.length; i++) { let value = heroAttr.values[i]; if(value != undefined) { switch(i) { - case HERO_ATTR_INDEX.BASE: - this.base = value; + case HERO_SUB_ATTR_INDEX.BASE: + this.base = value; break; + case HERO_SUB_ATTR_INDEX.JOB: + this.job = value; break; + case HERO_SUB_ATTR_INDEX.TALENT: + this.talent = value; break; + case HERO_SUB_ATTR_INDEX.EQUIP: + this.equip = value; break; } } } @@ -439,27 +536,192 @@ class HeroSubAttr extends HeroAllAttr { public getValues() { let values: number[] = []; - for(let i = HERO_ATTR_INDEX.START; i < HERO_ATTR_INDEX.END; i++) { + for(let i = HERO_SUB_ATTR_INDEX.START; i < HERO_SUB_ATTR_INDEX.END; i++) { switch(i) { - case HERO_ATTR_INDEX.BASE: - values.push(this.base); break; + case HERO_SUB_ATTR_INDEX.BASE: + if(this.base) values[i] = this.base; + break; + case HERO_SUB_ATTR_INDEX.JOB: + if(this.job) values[i] = this.job; + break; + case HERO_SUB_ATTR_INDEX.TALENT: + if(this.talent) values[i] = this.talent; + break; + case HERO_SUB_ATTR_INDEX.EQUIP: + if(this.equip) values[i] = this.equip; + break; } } return values; } } -enum GLOBAL_ATTR_INDEX { +abstract class EquipAllAttr { + hid: number; + eplaceId: number; + attrId: number; + equipQuality: number = 0; + equipStrengthen: number = 0; + equipStar: number = 0; + equipSuit: number = 0; + jewel: number = 0; + stone: number = 0; + + constructor(hid: number, attrId: number, ) { + this.hid = hid; + this.attrId = attrId; + + } + + abstract setByRoleCe(data: AttrCell): void; + abstract getValues(): number[]; + + public getEquipAttrCell() { + return { + attrId: this.attrId, + values: this.getValues() + } + } +} + +class EquipMainAttr extends EquipAllAttr { + public setByRoleCe(equipAttr: AttrCell) { + for(let i = 0; i < equipAttr.values.length; i++) { + let value = equipAttr.values[i]; + if(value != undefined) { + switch(i) { + case EQUIP_MAIN_ATTR_INDEX.EQUIP_QUALITY: + this.equipQuality = value; break; + case EQUIP_MAIN_ATTR_INDEX.EQUIP_STRENGTH: + this.equipStrengthen = value; break; + case EQUIP_MAIN_ATTR_INDEX.EQUIP_STAR: + this.equipStar = value; break; + case EQUIP_MAIN_ATTR_INDEX.EQUIP_SUIT: + this.equipSuit = value; break; + case EQUIP_MAIN_ATTR_INDEX.JEWEL: + this.jewel = value; break; + case EQUIP_MAIN_ATTR_INDEX.STONE: + this.stone = value; break; + } + } + } + } + + public getValues() { + let values: number[] = []; + for(let i = EQUIP_MAIN_ATTR_INDEX.START; i < EQUIP_MAIN_ATTR_INDEX.END; i++) { + switch(i) { + case EQUIP_MAIN_ATTR_INDEX.EQUIP_QUALITY: + if(this.equipQuality) values[i] = this.equipQuality; + break; + case EQUIP_MAIN_ATTR_INDEX.EQUIP_STRENGTH: + if(this.equipStrengthen) values[i] = this.equipStrengthen; + break; + case EQUIP_MAIN_ATTR_INDEX.EQUIP_STAR: + if(this.equipStar) values[i] = this.equipStar; + break; + case EQUIP_MAIN_ATTR_INDEX.EQUIP_SUIT: + if(this.equipSuit) values[i] = this.equipSuit; + break; + case EQUIP_MAIN_ATTR_INDEX.JEWEL: + if(this.jewel) values[i] = this.jewel; + break; + case EQUIP_MAIN_ATTR_INDEX.STONE: + if(this.stone) values[i] = this.stone; + break; + } + } + return values; + } +} + +class EquipSubAttr extends EquipAllAttr { + public setByRoleCe(equipAttr: AttrCell) { + for(let i = 0; i < equipAttr.values.length; i++) { + let value = equipAttr.values[i]; + if(value != undefined) { + switch(i) { + case EQUIP_SUB_ATTR_INDEX.EQUIP_STAR: + this.equipStar = value; break; + case EQUIP_SUB_ATTR_INDEX.JEWEL: + this.jewel = value; break; + } + } + } + } + + public getValues() { + let values: number[] = []; + for(let i = EQUIP_SUB_ATTR_INDEX.START; i < EQUIP_SUB_ATTR_INDEX.END; i++) { + switch(i) { + case EQUIP_SUB_ATTR_INDEX.EQUIP_STAR: + if(this.equipStar) values[i] = this.equipStar; + break; + case EQUIP_SUB_ATTR_INDEX.JEWEL: + if(this.jewel) values[i] = this.jewel; + break; + } + } + return values; + } +} + +enum GLOBAL_MAIN_ATTR_INDEX { START, - SCHOOL = 0, - TITLE = 1, - TERAPH = 2, + SCHOOL = 0, // hp5,百家学宫百分比加成(dic_zyz_schoolRate的mainAttrApercent) + TERAPH = 1, // hp11, 神像加成(直接读数据库teraph字段的值) + TITLE = 2, // hp11, 爵位加成(dic_zyz_title的hp) + SCROLL = 3, // hp11,名将谱加成(dic_zyz_heroScroll的hp) + SKIN = 4, // hp12, 皮肤加成(dic_zyz_fashion的actorAttr) END } -enum HERO_ATTR_INDEX { +enum GLOBAL_SUB_ATTR_INDEX { START, - BASE = 0, // 角色基础属性(dic_zyz_hero的hp) - BASE_UP = 1, + SCHOOL = 0, // attr5, 百家学宫(根据dic_zyz_school中的upAttribute决定书院加的是那些次级属性,具体值读取dic_zyz_schoolRate中的assiAttrAddValue一列) + TERAPH = 1, // attr4, 神像加成(dic_zyz_teraph中的assistAttrValue) + TITLE = 2, // attr6, 爵位(dic_zyz_title中的pdi、mdi) + SKIN = 3, // attr8, 皮肤 + END +} + +enum HERO_MAIN_ATTR_INDEX { + START, + BASE = 0, // hp1, 角色基础属性(dic_zyz_hero的hp) + JOB = 1, // hp1, 职业属性(dic_zyz_job的attr) + STAR_UP = 2, // hp2, 角色升星成长(dic_zyz_hero_star的hp或dic_zyz_hero_wake的hp) + CONNECT = 3, // hp3, 角色羁绊固定值(dic_zyz_friend_ship的attribute) + FAVOUR = 4, // hp4, 声望加成(dic_zyz_friend_ship_level的add) + TALENT = 5, // hp5, 天赋树百分比加成(dic_zyz_hero_talent的levelSeid,然后对应到dic_zyz_se) + EQUIP = 6, // (hp6+hp7)*(1+hp8) 装备,equipAttr加成之后加到这里 + EQUIP_UP = 7, // hp9, 天晶洗练处的主属性百分比加成,equipAttr中计算好加和加入 + EQUIP_STONE = 8, // hp10, 地玉石增加的固定值,equipAttr中计算好和加入 + END +} + +enum HERO_SUB_ATTR_INDEX { + START, + BASE = 0, // attr1,系统参数表中所有人 + JOB = 1, // attr2, 职业的attr + TALENT = 2, // attr3, 天赋树百分比加成 (dic_zyz_hero_talent的levelSeid,然后对应到dic_zyz_se) + EQUIP = 3, // attr7+attr9, 天晶加成和精炼加成,equipAttr加起来 + END +} + +enum EQUIP_MAIN_ATTR_INDEX { + START, + EQUIP_QUALITY = 0, // hp6, 装备升品基础值加成(dic_zyz_equipQuality) + EQUIP_STRENGTH = 1,// hp7, 装备强化值(需改表,改为键值对) + EQUIP_STAR = 2, // hp8, 装备(dic_zyz_equipStar) + EQUIP_SUIT = 3, // hp8, 装备套装加成(dic_zyz_equipSuit) + JEWEL = 4, // hp9, 天晶洗练出的主属性百分比加成,equipAttr加起来 + STONE = 5, // hp10,地玉石增加的固定值,equipAttr加起来 + END +} + +enum EQUIP_SUB_ATTR_INDEX { + START, + JEWEL = 0, // attr7, 天晶随机属性(随机出来的值在dic_zyz_randomEffectPool中读最终值) + EQUIP_STAR = 1, // attr8, 精炼次级属性(dic_zyz_equipStar的subAttr) END } \ No newline at end of file diff --git a/game-server/app/services/role/createHero.ts b/game-server/app/services/role/createHero.ts index 4bcf77620..fae782b4b 100644 --- a/game-server/app/services/role/createHero.ts +++ b/game-server/app/services/role/createHero.ts @@ -23,7 +23,7 @@ import { getInitHeroById } from "../roleService"; import { addItems, combineFigureInfo, unlockFigure, unlockFigureWithoutSave } from "./rewardService"; import { gameData } from "../../pubUtils/data"; import { CalCe } from "./calCe"; -import { RoleCeUpdate } from "../../db/RoleCe"; +import RoleCe, { RoleCeModel, RoleCeUpdate } from "../../db/RoleCe"; export class CreateHeroes { private roleId: string; @@ -102,6 +102,8 @@ export class CreateHeroes { // 更新role表 role = await RoleModel.incRoleInfo(this.roleId, { heroNum: this.incHeroNum, ce: this.incRoleCe }, { heroNumUpdatedAt: nowSeconds(), }); this.setRole(role); + // 更新roleCe表 + await RoleCeModel.updateRoleCe(this.roleId, this.roleCe); // 更新皮肤表 await SkinModel.insertSkins(this.roleId, this.roleName, this.skins) // 更新guild表 diff --git a/shared/db/RoleCe.ts b/shared/db/RoleCe.ts index 5fd8bb26c..792ce74b2 100644 --- a/shared/db/RoleCe.ts +++ b/shared/db/RoleCe.ts @@ -2,7 +2,7 @@ import BaseModel from './BaseModel'; import { index, getModelForClass, prop, DocumentType } from '@typegoose/typegoose'; // 全局加成 -export class GlobalAttr { +export class AttrCell { @prop({ required: true }) attrId: number; // 属性id @prop({ required: true }) @@ -15,27 +15,19 @@ export class HeroAttr { hid: number; // 武将id @prop({ required: true }) lv: number; - @prop({ required: true, type: () => HeroAttrCell, _id: false }) - attrs: HeroAttrCell[]; + @prop({ required: true, type: () => AttrCell, _id: false }) + attrs: AttrCell[]; } -export class HeroAttrCell { - @prop({ required: true }) - attrId: number; // 属性id - @prop({ required: true }) - values: number[]; // 战力公式中的武将加成的数据,查表后的结果 -} - -// 装备加成 -class EquipAttr { - @prop({ required: true }) - hid: number; // 武将id - @prop({ required: true }) - eplaceId: number; // 装备位置 - @prop({ required: true }) - attrId: number; // 属性id - @prop({ required: true }) - values: number[]; // 战力公式中的武将加成的数据,查表后的结果 +export class EquipAttr { + @prop({ required: true }) + hid: number; // 武将id + @prop({ required: true }) + eplaceId: number; // 装备位置 + @prop({ required: true }) + lv: number; + @prop({ required: true, type: () => AttrCell, _id: false }) + attrs: AttrCell[]; } // 百家学宫加成 @@ -70,8 +62,8 @@ export default class RoleCe extends BaseModel { @prop({ required: true }) roleId: string; // 角色 id - @prop({ required: true, type: GlobalAttr, _id: false }) - globalAttrs: GlobalAttr[] + @prop({ required: true, type: AttrCell, _id: false }) + globalAttrs: AttrCell[] @prop({ required: true, type: HeroAttr, _id: false }) heroAttrs: HeroAttr[] @@ -86,10 +78,14 @@ export default class RoleCe extends BaseModel { scrollAttrs: ScrollAttr[]; public static async findByRoleId(roleId: string) { - let result: RoleCeType[] = await RoleCeModel.find({ roleId }).lean(); + let result: RoleCeType = await RoleCeModel.findOne({ roleId }).lean(); return result; } + public static async updateRoleCe(roleId: string, update: RoleCeUpdate) { + let result: RoleCeType = await RoleCeModel.findOneAndUpdate({ roleId }, { $set: update }, { new: true, upsert: true }).lean(); + return result; + } } export const RoleCeModel = getModelForClass(RoleCe); From f35af70adcd006ff20df8a7392fc28eb1e3f798d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E9=99=86=E8=8E=B9?= Date: Sat, 26 Mar 2022 19:19:51 +0800 Subject: [PATCH 03/12] =?UTF-8?q?=E6=88=98=E5=8A=9B=EF=BC=9A=E6=9B=BF?= =?UTF-8?q?=E6=8D=A2=E6=96=B0=E6=96=B9=E6=B3=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../battle/handler/expeditionBattleHandler.ts | 7 +- .../app/servers/gm/handler/gmRoleHandler.ts | 18 +- .../app/servers/role/handler/equipHandler.ts | 39 +- .../app/servers/role/handler/heroHandler.ts | 145 +- .../app/servers/role/handler/roleHandler.ts | 19 +- game-server/app/services/expeditionService.ts | 5 +- game-server/app/services/playerCeService.ts | 144 +- game-server/app/services/role/calCe.ts | 130 +- game-server/app/services/role/createHero.ts | 1 - .../app/services/role/rewardService.ts | 8 +- game-server/test/CheckPatten.ts | 1 - shared/consts/constModules/heroConst.ts | 4 +- shared/db/Hero.ts | 19 - shared/db/RoleCe.ts | 6 +- shared/domain/roleField/hero.ts | 3 - shared/pubUtils/playerCe.ts | 1926 ++++++++--------- shared/pubUtils/util.ts | 14 +- shared/resource/jsons/dic_zyz_gk_branch.json | 54 +- 18 files changed, 1294 insertions(+), 1249 deletions(-) diff --git a/game-server/app/servers/battle/handler/expeditionBattleHandler.ts b/game-server/app/servers/battle/handler/expeditionBattleHandler.ts index ae52159ee..8c529afbd 100644 --- a/game-server/app/servers/battle/handler/expeditionBattleHandler.ts +++ b/game-server/app/servers/battle/handler/expeditionBattleHandler.ts @@ -4,7 +4,7 @@ import { ExpeditionRecordModel } from '../../../db/ExpeditionRecord'; import { ExpeditionWarRecordModel } from '../../../db/ExpeditionWarRecord'; import { ExpeditionPointModel } from '../../../db/ExpeditionPoint'; import { RoleModel } from '../../../db/Role'; -import { calculateSumCE, genCode, getWarTypeName } from '../../../pubUtils/util'; +import { genCode, getWarTypeName } from '../../../pubUtils/util'; import { getPointRewardStatus, getResetRemainCnt, findOrCreateEnemies, getExpeditionStatus } from '../../../services/expeditionService'; import { DEBUG_MAGIC_WORD, EXPEDITION_WAR_RECORD_STATUS, ITEM_CHANGE_REASON, KING_EXP_RATIO_TYPE, LINEUP_NUM, TASK_TYPE, TA_EVENT } from '../../../consts'; import { WarReward } from '../../../services/warRewardService'; @@ -18,6 +18,7 @@ import { gameData } from '../../../pubUtils/data'; import * as dicParam from '../../../pubUtils/dicParam'; import { getSeconds, nowSeconds } from '../../../pubUtils/timeUtil'; import { reportTAEvent } from '../../../services/sdkService'; +import { getSumCe } from '../../../services/playerCeService'; export default function (app: Application) { new HandlerService(app, {}); @@ -58,8 +59,8 @@ export class ExpeditionBattleHandler { await ExpeditionRecordModel.hideRecord(roleId); // 刷掉旧关卡 - // 我方战力(暂定) - let myCe = await calculateSumCE(roleId, 1, { num: LINEUP_NUM }); + // 我方战力 + let myCe = await getSumCe(roleId, LINEUP_NUM); // 每一关的挑战状态 let { expeditionCode, heroes } = await ExpeditionRecordModel.createRecord({ roleId, roleName, heroes: [], myCe diff --git a/game-server/app/servers/gm/handler/gmRoleHandler.ts b/game-server/app/servers/gm/handler/gmRoleHandler.ts index cccf9f17a..d5633081d 100644 --- a/game-server/app/servers/gm/handler/gmRoleHandler.ts +++ b/game-server/app/servers/gm/handler/gmRoleHandler.ts @@ -18,11 +18,11 @@ import { reportTAEvent } from '../../../services/sdkService'; import { sendMailByContent } from '../../../services/mailService'; import { GuildLeader } from '../../../domain/rank'; import { HeroModel } from '../../../db/Hero'; -import { calAllHeroCe, calPlayerCeAndSave } from '../../../services/playerCeService'; import { SkinModel } from '../../../db/Skin'; import { PvpDefenseModel } from '../../../db/PvpDefense'; import { calculatetopLineup } from '../../../pubUtils/util'; import { createHeroes } from '../../../services/role/createHero'; +import { calculateCe } from '../../../services/playerCeService'; let timer: NodeJS.Timer; export default function (app: Application) { @@ -95,14 +95,16 @@ export class GmRoleHandler { param.lv = newLv; param['exp'] = exp; } - hero = await calPlayerCeAndSave(HERO_SYSTEM_TYPE.STAR, sid, roleId, hero, param); - if(param.job > 0) { - hero = await calPlayerCeAndSave(HERO_SYSTEM_TYPE.STAGEUP, sid, roleId, hero, { job: param.job, jobStage: 0 }); - } + await calculateCe(HERO_SYSTEM_TYPE.INIT, roleId, hero.serverId, sid, param, {}, { hid }); + // if(param.job > 0) { + // await calculateCe(HERO_SYSTEM_TYPE.STAGEUP, roleId, hero.serverId, sid, param, {}, { hid }); - if (hero.star != param.star) { - await calAllHeroCe(HERO_SYSTEM_TYPE.STAR, sid, roleId, {}, [hid, 1]); // 升星可能影响到百家学院全局加成 - } + // hero = await calPlayerCeAndSave(HERO_SYSTEM_TYPE.STAGEUP, sid, roleId, hero, { job: param.job, jobStage: 0 }); + // } + + // if (hero.star != param.star) { + // await calAllHeroCe(HERO_SYSTEM_TYPE.STAR, sid, roleId, {}, [hid, 1]); // 升星可能影响到百家学院全局加成 + // } return resResult(STATUS.SUCCESS); } diff --git a/game-server/app/servers/role/handler/equipHandler.ts b/game-server/app/servers/role/handler/equipHandler.ts index a9265758c..9ac687b38 100644 --- a/game-server/app/servers/role/handler/equipHandler.ts +++ b/game-server/app/servers/role/handler/equipHandler.ts @@ -5,7 +5,6 @@ import { ItemInter, RewardInter } from "../../../pubUtils/interface"; import { resResult, parseGoodStr } from "../../../pubUtils/util"; import { addItems, getJewelRandSe, handleCost } from "../../../services/role/rewardService"; import { HeroModel, EPlace } from "../../../db/Hero"; -import { calPlayerCeAndSave } from "../../../services/playerCeService"; import { gameData, getEquipByJobClassAndEPlace, getNextEquipQuality, getEquipStarIdByEquipId, getNextEquipStar } from "../../../pubUtils/data"; import { BAG, EQUIP } from "../../../pubUtils/dicParam"; import { getRandSeResult, updateEplace, updateEplaces, checkJewelCanPutOnEquip, updateStone, checkStoneCanPutOnEquip, isLocked } from "../../../services/equipService"; @@ -17,6 +16,7 @@ import { pushEquipQualityMax, pushEquipStarMax } from "../../../services/sysChat import { addConsumeToHero } from "../../../services/roleService"; import { CheckMeterial } from "../../../services/role/checkMaterial"; import { combineItems } from "../../../services/role/util"; +import { calculateCe } from "../../../services/playerCeService"; export default function (app: Application) { new HandlerService(app, {}); @@ -57,15 +57,15 @@ export class EquipHandler { ePlace: newEplace, consumes: addConsumeToHero(hero.consumes, dicEquip.composeMaterial), } - hero = await calPlayerCeAndSave(HERO_SYSTEM_TYPE.COMPOSE_EQUIP, sid, roleId, hero, update, [ePlaceId]); + + await calculateCe(HERO_SYSTEM_TYPE.COMPOSE_EQUIP, roleId, serverId, sid, update, {}, { hid, ePlaceId }); await checkTaskInComposeEquip(serverId, roleId, sid, oldEplace, newEplace); - return resResult(STATUS.SUCCESS, { - curHero: { - hid: hero.hid, - ePlace: [newEquip] - } - }) + let curHero = { + hid, + ePlace: [newEquip] + } + return resResult(STATUS.SUCCESS, { curHero }); } // 装备栏强化 @@ -105,7 +105,7 @@ export class EquipHandler { ePlace: newEplace, consumes: addConsumeToHero(hero.consumes, consumes) } - hero = await calPlayerCeAndSave(HERO_SYSTEM_TYPE.EQUIP_STRENGTH, sid, roleId, hero, update, [ePlaceId]); + await calculateCe(HERO_SYSTEM_TYPE.EQUIP_STRENGTH, roleId, serverId, sid, update, {}, { hid, ePlaceId }); await checkTaskInEquipLvUp(serverId, roleId, sid, oldEplace, newEplace, [ePlaceId]); const curHero = { @@ -156,7 +156,7 @@ export class EquipHandler { ePlace: newEplace, consumes: addConsumeToHero(hero.consumes, consumes), } - await calPlayerCeAndSave(HERO_SYSTEM_TYPE.EQUIP_STRENGTH, sid, roleId, hero, update, [...eplaceIds.keys()]); + await calculateCe(HERO_SYSTEM_TYPE.EQUIP_STRENGTH, roleId, serverId, sid, update, {}, { hid, ePlaceIds: [...eplaceIds.keys()] }); await checkTaskInEquipLvUp(serverId, roleId, sid, ePlace, newEplace, [...eplaceIds.keys()]); const curHero = { @@ -223,7 +223,7 @@ export class EquipHandler { ePlace: newEplace, consumes: addConsumeToHero(hero.consumes, consumes), } - hero = await calPlayerCeAndSave(HERO_SYSTEM_TYPE.EQUIP_QUALITY, sid, roleId, hero, update, [ePlaceId]); + await calculateCe(HERO_SYSTEM_TYPE.EQUIP_QUALITY, roleId, serverId, sid, update, {}, { hid, ePlaceId }); await checkTaskInEquipQualityUp(serverId, roleId, sid, oldEplace, newEplace, ePlaceId, hid, isUpQuality); pushEquipQualityMax(roleId, roleName, serverId, hid, newEquip, isUpQuality); @@ -298,7 +298,7 @@ export class EquipHandler { ePlace: newEplace, consumes: addConsumeToHero(hero.consumes, consumes) } - hero = await calPlayerCeAndSave(HERO_SYSTEM_TYPE.EQUIP_STAR, sid, roleId, hero, update, [ePlaceId]); + await calculateCe(HERO_SYSTEM_TYPE.EQUIP_STAR, roleId, serverId, sid, update, {}, { hid, ePlaceId }); await checkTaskInEquipStarUp(serverId, roleId, sid, oldEplace, newEplace, ePlaceId, hid, isUpStar); pushEquipStarMax(roleId, roleName, serverId, hid, newEquip, isUpStar); @@ -343,7 +343,7 @@ export class EquipHandler { let canChange = originJewel && checkJewelCanPutOnEquip(originEquip, originJewel); if(canChange) canSentMineToOrigin = true; let { newEplace, updatedEplace } = updateEplace(originEplace, ePlaceId, { jewel: canChange? originJewel.seqId: 0 }); - await calPlayerCeAndSave(HERO_SYSTEM_TYPE.EQUIP_JEWEL, sid, roleId, originHero, { ePlace: newEplace }, [ePlaceId], { oldJewel: jewel, newJewel: canChange? originJewel:null }); + await calculateCe(HERO_SYSTEM_TYPE.EQUIP_JEWEL, roleId, serverId, sid, { ePlace: newEplace }, {}, { hid, ePlaceId, oldJewel: jewel, newJewel: canChange? originJewel:null }); await checkTaskInPutJewel(serverId, roleId, sid, originEplace, newEplace, ePlaceId, jewel, canChange? originJewel:null); originHeroResult = { hid: originHero.hid, ePlace: updatedEplace }; @@ -356,7 +356,7 @@ export class EquipHandler { // 目标镶嵌上 let curJewel = await JewelModel.putOnOrOff(seqId, hid, ePlaceId); let { newEplace, updatedEplace } = updateEplace(oldEplace, ePlaceId, { jewel: seqId }); - await calPlayerCeAndSave(HERO_SYSTEM_TYPE.EQUIP_JEWEL, sid, roleId, hero, { ePlace: newEplace }, [ePlaceId], { oldJewel: originJewel, newJewel: curJewel }); + await calculateCe(HERO_SYSTEM_TYPE.EQUIP_JEWEL, roleId, serverId, sid, { ePlace: newEplace }, {}, { hid, ePlaceId, oldJewel: originJewel, newJewel: curJewel }); await checkTaskInPutJewel(serverId, roleId, sid, oldEplace, newEplace, ePlaceId, originJewel, curJewel); let curHero = { @@ -384,7 +384,7 @@ export class EquipHandler { let curJewel = await JewelModel.putOnOrOff(curEquip.jewel, 0, 0); let { newEplace, updatedEplace } = updateEplace(oldEplace, ePlaceId, { jewel: 0 }); - await calPlayerCeAndSave(HERO_SYSTEM_TYPE.EQUIP_JEWEL, sid, roleId, hero, { ePlace: newEplace }, [ePlaceId], { oldJewel: curJewel }); + await calculateCe(HERO_SYSTEM_TYPE.EQUIP_JEWEL, roleId, serverId, sid, { ePlace: newEplace }, {}, { hid, ePlaceId, oldJewel: curJewel }); await checkTaskInPutJewel(serverId, roleId, sid, oldEplace, newEplace, ePlaceId, null, curJewel); let curHero = { @@ -437,7 +437,7 @@ export class EquipHandler { ePlace: newEplace, consumes: updateConsumes, } - await calPlayerCeAndSave(HERO_SYSTEM_TYPE.EQUIP_STONE, sid, roleId, hero, update, [ePlaceId], { jewel }); + await calculateCe(HERO_SYSTEM_TYPE.EQUIP_STONE, roleId, serverId, sid, update, {}, { hid, ePlaceId, jewel }); await checkTaskInPutStone(serverId, roleId, sid, oldEplace, newEplace, ePlaceId, jewel); let curHero = { @@ -557,7 +557,7 @@ export class EquipHandler { // 更新战力 if(hid > 0) { const hero = await HeroModel.findByHidAndRole(hid, roleId); - await calPlayerCeAndSave(HERO_SYSTEM_TYPE.JEWEL_RESET_RANDSE, sid, roleId, hero, {}, [ePlaceId], { oldJewel: jewel, newJewel }); + await calculateCe(HERO_SYSTEM_TYPE.JEWEL_RESET_RANDSE, roleId, serverId, sid, {}, {}, { hid, ePlaceId, oldJewel: jewel, newJewel, hero }); } await checkTaskInEquipReset(serverId, roleId, sid); @@ -639,7 +639,7 @@ export class EquipHandler { // 更新战力 if(isSuccess && hid > 0) { const hero = await HeroModel.findByHidAndRole(hid, roleId); - await calPlayerCeAndSave(HERO_SYSTEM_TYPE.JEWEL_QUENCH, sid, roleId, hero, {}, [ePlaceId], { oldJewel: jewel, newJewel }); + await calculateCe(HERO_SYSTEM_TYPE.JEWEL_QUENCH, roleId, serverId, sid, {}, {}, { hid, ePlaceId, oldJewel: jewel, newJewel, hero }); } await checkTaskInEquipQuench(serverId, roleId, sid, isSuccess); @@ -759,7 +759,8 @@ export class EquipHandler { // 更新战力 if(targetJewel.hid > 0) { const hero = await HeroModel.findByHidAndRole(targetJewel.hid, roleId); - await calPlayerCeAndSave(HERO_SYSTEM_TYPE.JEWEL_RESET_RANDSE, sid, roleId, hero, {}, [targetJewel.ePlaceId], { oldJewel: originJewel, newJewel }); + await calculateCe(HERO_SYSTEM_TYPE.JEWEL_RESET_RANDSE, roleId, serverId, sid, {}, {}, { hid: targetJewel.ePlaceId, ePlaceId: targetJewel.ePlaceId, oldJewel: originJewel, newJewel, hero }); + } await checkTaskInEquipReset(serverId, roleId, sid); diff --git a/game-server/app/servers/role/handler/heroHandler.ts b/game-server/app/servers/role/handler/heroHandler.ts index 01fa865fb..c34958b06 100644 --- a/game-server/app/servers/role/handler/heroHandler.ts +++ b/game-server/app/servers/role/handler/heroHandler.ts @@ -1,7 +1,6 @@ import { Application, BackendSession, ChannelService, HandlerService, } from 'pinus'; import { handleCost, addItems, unlockFigure, getCoinObject, getGoldObject } from '../../../services/role/rewardService'; -import { calPlayerCeAndSave, calAllHeroCe } from '../../../services/playerCeService'; -import { resResult, deepCopy, reduceCe, parseGoodStr } from '../../../pubUtils/util'; +import { resResult, deepCopy, parseGoodStr } from '../../../pubUtils/util'; import { STATUS } from '../../../consts/statusCode'; import { HeroModel, Connect, HeroSkin, HeroUpdate, EPlace, Talent } from '../../../db/Hero'; import { CURRENCY_BY_TYPE, CURRENCY_TYPE, CONSUME_TYPE, HERO_GROW_MAX, HERO_SYSTEM_TYPE, ABI_STAGE, DEBUG_MAGIC_WORD, HERO_INITIAL_QUALITY, REDIS_KEY, TASK_TYPE, ITEM_CHANGE_REASON } from '../../../consts'; @@ -23,6 +22,7 @@ import { HERO, REBORN } from '../../../pubUtils/dicParam'; import { createHero, createHeroes } from '../../../services/role/createHero'; import { CheckMeterial } from '../../../services/role/checkMaterial'; import { HeroParam } from '../../../domain/roleField/hero'; +import { calculateCe } from '../../../services/playerCeService'; export default function (app: Application) { new HandlerService(app, {}); @@ -127,15 +127,11 @@ export class HeroHandler { consumes: addConsumeToHero(hero.consumes, material) } - hero = await calPlayerCeAndSave(HERO_SYSTEM_TYPE.LVUP, sid, roleId, hero, update); + let { curHero } = await calculateCe(HERO_SYSTEM_TYPE.LVUP, roleId, serverId, sid, update, {}, { hid }); // 任务 - await checkTask(serverId, roleId, sid, TASK_TYPE.HERO_LV, { oldLv, hero }); - - const curHero = { - hid, lv: hero.lv, exp: hero.exp - } - return resResult(STATUS.SUCCESS, { curHero, cost: material }); + await checkTask(serverId, roleId, sid, TASK_TYPE.HERO_LV, { oldLv, hero: curHero }); + return resResult(STATUS.SUCCESS, { curHero: pick(curHero, ['hid', 'lv', 'exp']), cost: material }); } @@ -191,21 +187,12 @@ export class HeroHandler { consumes: addConsumeToHero(hero.consumes, consumes) } - hero = await calPlayerCeAndSave(HERO_SYSTEM_TYPE.STAR, sid, roleId, hero, update); - if (isUpStar) { - await calAllHeroCe(HERO_SYSTEM_TYPE.STAR, sid, roleId, {}, [hid, isUpStar ? 1 : 0]); // 升星可能影响到百家学院全局加成 - // 任务 - await checkTaskInHeroStarUp(serverId, roleId, sid, hero, oldStar); - } - const curHero = { - hid, - star: hero.star, - starStage: hero.starStage, - colorStar: hero.colorStar, - colorStarStage: hero.colorStarStage + let { curHero } = await calculateCe(HERO_SYSTEM_TYPE.STAR, roleId, serverId, sid, update, {}, { hid, hero, isUpStar }); + if (isUpStar) { + await checkTaskInHeroStarUp(serverId, roleId, sid, curHero, oldStar); // 任务 } - return resResult(STATUS.SUCCESS, { isUpStar, curHero }); + return resResult(STATUS.SUCCESS, { isUpStar, curHero: pick(curHero, ['hid', 'star', 'starStage', 'colorStar', 'colorStarStage']) }); } // 武将升品 @@ -248,16 +235,11 @@ export class HeroHandler { quality: hero.quality + 1, consumes: addConsumeToHero(hero.consumes, material) } - hero = await calPlayerCeAndSave(HERO_SYSTEM_TYPE.QUALITY, sid, roleId, hero, update); - await calAllHeroCe(HERO_SYSTEM_TYPE.QUALITY, sid, roleId, {}, [hid, 0]); // 升品可能影响到百家学院全局加成 - await checkTaskInHeroQUalityUp(serverId, roleId, sid, hero); - const curHero = { - hid, - quality: hero.quality - } - pushHeroQualityUpMsg(roleId, roleName, serverId, hero); - return resResult(STATUS.SUCCESS, { curHero }); + let { curHero } = await calculateCe(HERO_SYSTEM_TYPE.QUALITY, roleId, serverId, sid, update, {}, { hid, hero }); + await checkTaskInHeroQUalityUp(serverId, roleId, sid, curHero); + pushHeroQualityUpMsg(roleId, roleName, serverId, curHero); + return resResult(STATUS.SUCCESS, { curHero: pick(curHero, ['hid', 'quality']) }); } // 武将觉醒 @@ -319,25 +301,13 @@ export class HeroHandler { consumes: addConsumeToHero(hero.consumes, consumes) } - hero = await calPlayerCeAndSave(HERO_SYSTEM_TYPE.COLORSTAR, sid, roleId, hero, update); + let { curHero } = await calculateCe(HERO_SYSTEM_TYPE.COLORSTAR, roleId, serverId, sid, update, {}, { hid, hero, isUpStar }); if (isUpStar) { - await calAllHeroCe(HERO_SYSTEM_TYPE.COLORSTAR, sid, roleId, {}, [hid, isUpStar ? 1 : 0]); // 升星可能影响到百家学院全局加成 - - // 任务 - await checkTaskInHeroWakeUp(serverId, roleId, sid, hero, oldColorStar); - + await checkTaskInHeroWakeUp(serverId, roleId, sid, curHero, oldColorStar); // 任务 } - const curHero = { - hid, - quality: hero.quality, - star: hero.star, - starStage: hero.starStage, - colorStar: hero.colorStar, - colorStarStage: hero.colorStarStage - } - if (isWakeUp) pushHeroWakeUp(roleId, roleName, serverId, hero); // 第一次觉醒 - pushHeroStarMax(roleId, roleName, serverId, hero); - return resResult(STATUS.SUCCESS, { isUpStar, curHero }); + if (isWakeUp) pushHeroWakeUp(roleId, roleName, serverId, curHero); // 第一次觉醒 + pushHeroStarMax(roleId, roleName, serverId, curHero); + return resResult(STATUS.SUCCESS, { isUpStar, curHero: pick(curHero, ['hid', 'quality', 'star', 'starStage', 'colorStar', 'colorStarStage']) }); } //训练 @@ -383,11 +353,9 @@ export class HeroHandler { jobStage: newJobStage, consumes: addConsumeToHero(hero.consumes, consumes) } - hero = await calPlayerCeAndSave(HERO_SYSTEM_TYPE.TRAIN, sid, roleId, hero, update); - // 任务 - await checkTaskInHeroTrain(serverId, roleId, sid, hero, trainCount); - - return resResult(STATUS.SUCCESS, { curHero: { hid: hero.hid, job: hero.job, jobStage: hero.jobStage } }); + let { curHero } = await calculateCe(HERO_SYSTEM_TYPE.TRAIN, roleId, serverId, sid, update, {}, { hid, hero }); + await checkTaskInHeroTrain(serverId, roleId, sid, curHero, trainCount); // 任务 + return resResult(STATUS.SUCCESS, { curHero: pick(curHero, ['hid', 'job', 'jobStage'])}); } //进阶 @@ -420,11 +388,10 @@ export class HeroHandler { jobStage: 0, consumes: addConsumeToHero(hero.consumes, consumes) } - hero = await calPlayerCeAndSave(HERO_SYSTEM_TYPE.STAGEUP, sid, roleId, hero, update); - // 任务 - await checkTask(serverId, roleId, sid, TASK_TYPE.HERO_STAGE_UP, { hero, stageUpCnt: 1 }) - const heroResult = new HeroParam(hero); + let { curHero } = await calculateCe(HERO_SYSTEM_TYPE.STAGEUP, roleId, serverId, sid, update, {}, { hid, hero }); + await checkTask(serverId, roleId, sid, TASK_TYPE.HERO_STAGE_UP, { hero: curHero, stageUpCnt: 1 }); // 任务 + const heroResult = new HeroParam(curHero); return resResult(STATUS.SUCCESS, { curHero: {...pick(heroResult, ['hid', 'job', 'jobStage', 'totalTalentPoint']) }}); } @@ -477,11 +444,10 @@ export class HeroHandler { consumes: addConsumeToHero(hero.consumes, consumes) } //重算战力并下发 - hero = await calPlayerCeAndSave(HERO_SYSTEM_TYPE.CONNECT, sid, roleId, hero, update, [shipId]); - + let { curHero } = await calculateCe(HERO_SYSTEM_TYPE.CONNECT, roleId, serverId, sid, update, {}, { hid: hero.hid, shipId }); // 任务 await checkTask(serverId, roleId, sid, TASK_TYPE.HERO_CONNECT, { connectLv: level }) - return resResult(STATUS.SUCCESS, { curHero: { hid: hero.hid, connections: hero.connections } }); + return resResult(STATUS.SUCCESS, { curHero: pick(curHero, ['hid', 'connections']) }); } //赠送(包括一键赠送) @@ -554,17 +520,23 @@ export class HeroHandler { consumes: updateConsume } - //重算战力并下发 - if (oldLv != newLv) { - await unlockFigure(sid, roleId, [{ type: FIGURE_UNLOCK_CONDITION.HERO_FAVOR, paramHid: hero.hid, paramFavourLv: hero.favourLv }]); - hero = await calPlayerCeAndSave(HERO_SYSTEM_TYPE.FAVOUR, sid, roleId, hero, update, [oldLv]); + let isFavourLvUp = oldLv == newLv; + // //重算战力并下发 + // if (oldLv != newLv) { + // await unlockFigure(sid, roleId, [{ type: FIGURE_UNLOCK_CONDITION.HERO_FAVOR, paramHid: hero.hid, paramFavourLv: hero.favourLv }]); + // hero = await calPlayerCeAndSave(HERO_SYSTEM_TYPE.FAVOUR, sid, roleId, hero, update, [oldLv]); - // 任务 - await checkTask(serverId, roleId, sid, TASK_TYPE.HERO_FAVOUR_LV, { hero, oldFavourLv: oldLv }); - } else { - hero = await HeroModel.updateHeroInfo(roleId, hero.hid, update); + // // 任务 + // await checkTask(serverId, roleId, sid, TASK_TYPE.HERO_FAVOUR_LV, { hero, oldFavourLv: oldLv }); + // } else { + // hero = await HeroModel.updateHeroInfo(roleId, hero.hid, update); + // } + let { curHero } = await calculateCe(HERO_SYSTEM_TYPE.FAVOUR, roleId, serverId, sid, update, {}, { hid: hero.hid, isFavourLvUp }); + if(isFavourLvUp) { + await unlockFigure(sid, roleId, [{ type: FIGURE_UNLOCK_CONDITION.HERO_FAVOR, paramHid: curHero.hid, paramFavourLv: curHero.favourLv }]); + await checkTask(serverId, roleId, sid, TASK_TYPE.HERO_FAVOUR_LV, { hero: curHero, oldFavourLv: oldLv }); // 任务 } - return resResult(STATUS.SUCCESS, { curHero: { hid: hero.hid, favour: hero.favour, favourLv: hero.favourLv, cost: material } }); + return resResult(STATUS.SUCCESS, { curHero: { ...pick(curHero, ['hid', 'favour', 'favourLv']), cost: material } }); } //穿带时装 @@ -613,9 +585,14 @@ export class HeroHandler { } let { newEplace } = updateEplaces(oldEplace, eplaceIds); - - hero = await calPlayerCeAndSave(HERO_SYSTEM_TYPE.SKIN, sid, roleId, hero, { skins: newHeroSkins, skinId: dicSkin.heroId, job: dicNewJob.jobid, ePlace: newEplace }); - let resultHero = new HeroParam(hero); + let update = { + skins: newHeroSkins, + skinId: dicSkin.heroId, + job: dicNewJob.jobid, + ePlace: newEplace + } + let { curHero } = await calculateCe(HERO_SYSTEM_TYPE.SKIN, roleId, serverId, sid, update, {}, { hid: hero.hid }); + let resultHero = new HeroParam(curHero); return resResult(STATUS.SUCCESS, { curHero: {...pick(resultHero, ['hid', 'skins', 'skinId', 'job', 'talent', 'usedTalentPoint']), ePlace: newEplace }}); } @@ -634,6 +611,7 @@ export class HeroHandler { let roleId: string = session.get('roleId'); let roleName: string = session.get('roleName'); let sid: string = session.get('sid'); + let serverId: number = session.get('serverId'); let { hid } = msg; if(!isNumber(hid) && !hid) return resResult(STATUS.WRONG_PARMS); @@ -665,7 +643,7 @@ export class HeroHandler { let calHeroCe = new CalHeroCe(hid, initInfo); let heroAttr = calHeroCe.cal(HERO_SYSTEM_TYPE.REBIRTH); - await HeroModel.updateHeroInfo(roleId, hid, { ...initInfo, attr: heroAttr }); + // await HeroModel.updateHeroInfo(roleId, hid, { ...initInfo, attr: heroAttr }); // 天晶石 let curJewels: jewelUpdate[] = []; @@ -680,9 +658,7 @@ export class HeroHandler { } } - let { heros } = await calAllHeroCe(HERO_SYSTEM_TYPE.REBIRTH, sid, roleId, {}, [hid], { originHero: hero, heroUpdate: initInfo }); - let curHero = heros.find(cur => cur.hid == hid); - + let { curHero } = await calculateCe(HERO_SYSTEM_TYPE.REBIRTH, roleId, serverId, sid, {...initInfo, attr: heroAttr}, {}, { hid }); let goods = await addItems(roleId, roleName, sid, consumes, ITEM_CHANGE_REASON.REBIRTH); const heroResult = new HeroParam(curHero); @@ -693,6 +669,7 @@ export class HeroHandler { public async unlockTalent(msg: { hid: number, id: number }, session: BackendSession) { let roleId = session.get('roleId'); let sid = session.get('sid'); + let serverId = session.get('serverId'); let { hid, id } = msg; let hero = await HeroModel.findByHidAndRole(hid, roleId); @@ -721,9 +698,8 @@ export class HeroHandler { let { newSkins } = updateSkinTalent(skins, new Talent(id), usedTalentPoint + needTalentPoint); - hero = await calPlayerCeAndSave(HERO_SYSTEM_TYPE.TALENT, sid, roleId, hero, { skins: newSkins }); - - const heroResult = new HeroParam(hero); + let { curHero } = await calculateCe(HERO_SYSTEM_TYPE.TALENT, roleId, serverId, sid, { skins: newSkins }, {}, { hid }); + const heroResult = new HeroParam(curHero); return resResult(STATUS.SUCCESS, { curHero: {...pick(heroResult, ['hid', 'talent', 'usedTalentPoint', 'totalTalentPoint']) }}); } @@ -732,6 +708,7 @@ export class HeroHandler { public async upgradeTalent(msg: { hid: number, id: number }, session: BackendSession) { let roleId = session.get('roleId'); let sid = session.get('sid'); + let serverId = session.get('serverId'); let { hid, id } = msg; let hero = await HeroModel.findByHidAndRole(hid, roleId); @@ -758,9 +735,8 @@ export class HeroHandler { let { newSkins } = updateSkinTalent(skins, new Talent(id, talent.level + 1), usedTalentPoint + needTalentPoint); - hero = await calPlayerCeAndSave(HERO_SYSTEM_TYPE.TALENT, sid, roleId, hero, { skins: newSkins }); - - const heroResult = new HeroParam(hero); + let { curHero } = await calculateCe(HERO_SYSTEM_TYPE.TALENT, roleId, serverId, sid, { skins: newSkins }, {}, { hid }); + const heroResult = new HeroParam(curHero); return resResult(STATUS.SUCCESS, { curHero: {...pick(heroResult, ['hid', 'talent', 'usedTalentPoint', 'totalTalentPoint']) }}); } @@ -768,6 +744,7 @@ export class HeroHandler { public async resetTalent(msg: { hid: number }, session: BackendSession) { let roleId = session.get('roleId'); let sid = session.get('sid'); + let serverId = session.get('serverId'); let { hid } = msg; let hero = await HeroModel.findByHidAndRole(hid, roleId); @@ -783,9 +760,9 @@ export class HeroHandler { let newSkins = initSkinTalent(skins); - hero = await calPlayerCeAndSave(HERO_SYSTEM_TYPE.TALENT, sid, roleId, hero, { skins: newSkins }); + let { curHero } = await calculateCe(HERO_SYSTEM_TYPE.TALENT, roleId, serverId, sid, { skins: newSkins }, {}, { hid }); - const heroResult = new HeroParam(hero); + const heroResult = new HeroParam(curHero); return resResult(STATUS.SUCCESS, { curHero: {...pick(heroResult, ['hid', 'talent', 'usedTalentPoint', 'totalTalentPoint']) }}); } diff --git a/game-server/app/servers/role/handler/roleHandler.ts b/game-server/app/servers/role/handler/roleHandler.ts index 02584462b..97b7c3ac1 100644 --- a/game-server/app/servers/role/handler/roleHandler.ts +++ b/game-server/app/servers/role/handler/roleHandler.ts @@ -11,7 +11,6 @@ import { findIndex } from 'underscore'; import { SclResultInter, SclPosInter } from '../../../pubUtils/interface'; import { SchoolModel } from '../../../db/School'; import { getTeraphStrengthenResult, getSchoolList } from '../../../services/roleService' -import { calPlayerCeAndSave, calAllHeroCe } from '../../../services/playerCeService'; import { HERO_SYSTEM_TYPE, LINEUP_NUM, ROLE_SELECT, REDIS_KEY, TASK_TYPE, DEFAULT_HEROES, DEFAULT_HERO_LV, DEFAULT_ITEMS, DEFAULT_EQUIPS, DEFAULT_GOLD, DEFAULT_COIN, DEBUG_MAGIC_WORD, COUNTER, DEFAULT_LV, ITEM_CHANGE_REASON } from '../../../consts'; import { checkBattleHeroesByHid, roleLevelup } from '../../../services/normalBattleService'; import { Rank } from '../../../services/rankService'; @@ -26,6 +25,7 @@ import Counter from '../../../db/Counter'; import { UserModel } from '../../../db/User'; import { checkFilterWords, reportTAEvent, treatRoleName } from '../../../services/sdkService'; import { createHeroes, CreateHeroes } from '../../../services/role/createHero'; +import { calculateCe } from '../../../services/playerCeService'; export default function (app: Application) { new HandlerService(app, {}); @@ -95,11 +95,11 @@ export class RoleHandler { return resResult(STATUS.BATTLE_CONSUMES_NOT_ENOUGH); let update = { title: title + 1 } - let calResult = await calAllHeroCe(HERO_SYSTEM_TYPE.TITLE, sid, roleId, update); + let { curRole } = await calculateCe(HERO_SYSTEM_TYPE.TITLE, roleId, serverId, sid, {}, update, {}); // 任务 await checkTask(serverId, roleId, sid, TASK_TYPE.ROLE_TITLE, { oldTitle: title, title: update.title }); - return resResult(STATUS.SUCCESS, { roleId: calResult.role, title: role.title }); + return resResult(STATUS.SUCCESS, { roleId, title: curRole.title }); } //神像强化 @@ -128,12 +128,12 @@ export class RoleHandler { if (!result) return resResult(STATUS.BATTLE_CONSUMES_NOT_ENOUGH); - let calResult = await calAllHeroCe(HERO_SYSTEM_TYPE.TERAPH, sid, roleId, { teraphs }, [id]); + let { curRole } = await calculateCe(HERO_SYSTEM_TYPE.TERAPH, roleId, serverId, sid, {}, { teraphs }, { teraphId: id }); // 任务 await checkTask(serverId, roleId, sid, TASK_TYPE.ROLE_TERAPH_STRENGTHEN, { count }); - return resResult(STATUS.SUCCESS, { roleId, teraphs: calResult.role.teraphs, criAttr }); + return resResult(STATUS.SUCCESS, { roleId, teraphs: curRole.teraphs, criAttr }); } //神像进阶 @@ -171,13 +171,12 @@ export class RoleHandler { let result = await handleCost(roleId, sid, consumes, ITEM_CHANGE_REASON.TERAPH_QUALITY_UP); if (!result) return resResult(STATUS.BATTLE_CONSUMES_NOT_ENOUGH); - - let calResult = await calAllHeroCe(HERO_SYSTEM_TYPE.TERAPH_UP, sid, roleId, { teraphs }, [id]); + let { curRole } = await calculateCe(HERO_SYSTEM_TYPE.TERAPH_UP, roleId, serverId, sid, {}, { teraphs }, { teraphId: id }); // 神像进阶,进阶一次就触发一次礼包弹框 await checkTask(serverId, roleId, sid, TASK_TYPE.ROLE_TERAPH_STAGE_UP); - return resResult(STATUS.SUCCESS, { roleId, teraphs: calResult.role.teraphs }); + return resResult(STATUS.SUCCESS, { roleId, teraphs: curRole.teraphs }); } // 获得百家学宫 @@ -229,7 +228,7 @@ export class RoleHandler { } await SchoolModel.updateBySclAndPos(roleId, schoolId, positionId, { hid, isOpen }) - await calAllHeroCe(HERO_SYSTEM_TYPE.SCHOOL, sid, roleId, {}, [schoolId, hid, preHid]); + await calculateCe(HERO_SYSTEM_TYPE.SCHOOL, roleId, serverId, sid, {}, {}, { schoolId, schoolHid: hid, preSchoolHid: preHid }); // 任务 await checkTask(serverId, roleId, sid, TASK_TYPE.ROLE_SCHOOL_PUT_HERO, { hid, preHid }); @@ -320,7 +319,7 @@ export class RoleHandler { update.scrollId = dicHeroScroll ? dicHeroScroll.id : 0; let hero = await HeroModel.updateHeroInfo(roleId, hid, update); - await calAllHeroCe(HERO_SYSTEM_TYPE.SCROLL, sid, roleId, {}, [hid]); // 全局增加战力 + await calculateCe(HERO_SYSTEM_TYPE.SCROLL, roleId, serverId, sid, update, {}, { hid }); // 任务 await checkTaskInActiveScroll(serverId, roleId, sid, scrollActive, hero); diff --git a/game-server/app/services/expeditionService.ts b/game-server/app/services/expeditionService.ts index b047aa4cd..923dce455 100644 --- a/game-server/app/services/expeditionService.ts +++ b/game-server/app/services/expeditionService.ts @@ -1,7 +1,7 @@ import { ExpeditionPointModel } from '../db/ExpeditionPoint'; import Role, { CeAttrDataRole, RoleModel } from '../db/Role'; -import { shouldRefresh, calculateSumCE, getRandSingleEelm } from '../pubUtils/util'; +import { shouldRefresh, getRandSingleEelm } from '../pubUtils/util'; import { LINEUP_NUM, EXPEDITION_WAR_RECORD_STATUS } from '../consts'; import { ExpeditionWarRecordModel } from '../db/ExpeditionWarRecord'; import { CeAttrData, HeroType } from '../db/Hero'; @@ -10,6 +10,7 @@ import { getTimeFunD } from '../pubUtils/timeUtil'; import { ExpeditionRecordModel } from '../db/ExpeditionRecord'; import { Attribute, AttributeCal } from '../domain/roleField/attribute'; import * as dicParam from '../pubUtils/dicParam'; +import { getSumCe } from './playerCeService'; /** * 获取远征关卡列表 @@ -24,7 +25,7 @@ export async function getExpeditionStatus(roleId: string, roleName: string) { let expeditionRecord = await ExpeditionRecordModel.getCurRecord(roleId); if (!expeditionRecord) { // 首次新建一条记录 // 我方战力 - let myCe = await calculateSumCE(roleId, 1, { num: LINEUP_NUM }); + let myCe = await getSumCe(roleId, LINEUP_NUM); expeditionRecord = await ExpeditionRecordModel.createRecord({ roleId, roleName, heroes: [], myCe }); diff --git a/game-server/app/services/playerCeService.ts b/game-server/app/services/playerCeService.ts index 7e934c156..5b9b775c2 100644 --- a/game-server/app/services/playerCeService.ts +++ b/game-server/app/services/playerCeService.ts @@ -5,74 +5,92 @@ import { pinus } from 'pinus'; import { STATUS } from '../consts/statusCode'; -import { resResult, reduceCe } from '../pubUtils/util'; -import { calPlayerCeAndSave as pubCalPlayerCeAndSave, reCalAllHeroCe } from '../pubUtils/playerCe'; -import { HeroType, HeroUpdate } from '../db/Hero'; +import { resResult, reduceCe, calculatetopLineup } from '../pubUtils/util'; +import { HeroModel, HeroType, HeroUpdate } from '../db/Hero'; -import { RoleUpdate, RoleType } from '../db/Role'; +import { RoleUpdate, RoleType, RoleModel } from '../db/Role'; import { Rank } from './rankService'; -import { REDIS_KEY } from '../consts'; +import { HERO_SYSTEM_TYPE, REDIS_KEY } from '../consts'; import { updateUserInfo } from './redisService'; -import { GuildType } from '../db/Guild'; +import { GuildModel, GuildType } from '../db/Guild'; +import { CalCe } from './role/calCe'; +import { RoleCeModel } from '../db/RoleCe'; +import { PvpDefenseModel } from '../db/PvpDefense'; +import { saveCeChangeLog } from '../pubUtils/logUtil'; +import { JewelType } from '../db/Jewel'; -interface calPlayerReturn { - serverId: number; - role: RoleType; - guild?: GuildType; - hero?: HeroType; - pushHeros: {hid: number, ce: number, incHeroCe: number}[]; - topLineupCe: number; - heros?: HeroType[] +interface Param { + hid?: number, + hero?: HeroType, + isUpStar?: boolean, + shipId?: number, + isFavourLvUp?: boolean, + ePlaceId?: number, + ePlaceIds?: number[], + oldJewel?: JewelType, + newJewel?: JewelType, + jewel?: JewelType, + teraphId?: number, + schoolId?: number, + schoolHid?: number, + preSchoolHid?: number, + skinId?: number, } -//修改并下发战力 -export async function calPlayerCeAndSave(type: number, sid: string, roleId: string, originHero: HeroType, update: HeroUpdate, args?: Array, params?: any) { - let result = await pubCalPlayerCeAndSave(type, roleId, originHero, update, args, params); - return await pushCalPlayerCe(roleId, sid, result); -} +export async function calculateCe(type: HERO_SYSTEM_TYPE, roleId: string, serverId: number, sid: string, heroUpdate: HeroUpdate, roleUpdate: RoleUpdate, param: Param) { + let calCe = new CalCe(); + let roleCe = await RoleCeModel.findByRoleId(roleId); + calCe.setRoleCe(roleCe); + switch (type) { + case HERO_SYSTEM_TYPE.LVUP: // 升级 + { + calCe.setHeroLv(param.hid, heroUpdate.lv); + break; + } + case HERO_SYSTEM_TYPE.STAR: // 升星 + { + let { star, starStage, colorStar, colorStarStage } = heroUpdate; + let { hid, hero: { quality, job } } = param; + calCe.setHeroStar(hid, job, quality, star, starStage, colorStar, colorStarStage); + break; + } + } + let { heroCe, roleInc } = calCe.getCeInc(); // 计算战力,获得有变化的武将战力 + let pushHeros = new Array<{ hid: number, ce: number, incHeroCe: number }>(); + let heroes: HeroType[] = [], curHero: HeroType; + for(let [ hid, { ce, inc } ] of heroCe) { + let hero: HeroType; + if(hid == param.hid) { // 更新的那一个武将 + hero = await HeroModel.updateHeroInfo(roleId, hid, { ...heroUpdate, ce }); + curHero = hero; + } else { // 由于百家学宫等问题牵扯到的其他武将 + hero = await HeroModel.updateHeroInfo(roleId, hid, { ce }); + } + calCe.setResultHero(hero); + heroes.push(hero); + await PvpDefenseModel.updateCe(roleId, hid, inc); // 更新pvp防守阵战力 + pushHeros.push({ hid, ce, incHeroCe: inc }) + } + if(!heroCe.has(param.hid)) { + curHero = await HeroModel.updateHeroInfo(roleId, param.hid, heroUpdate); + } + let { topLineup, topLineupCe } = calCe.getTopLineup(); + let role = await RoleModel.incRoleInfo(roleId, { ce: roleInc }, { ...roleUpdate, topLineup, topLineupCe }); + let guild = await GuildModel.updateCe(roleId, roleInc); // 公会更新战力 + + saveCeChangeLog(role, roleInc, role.ce, type, [...heroCe.keys()]); + updateRank(roleId, serverId, topLineupCe, role, pushHeros, guild); -// 修改后战力的推送 -export async function pushCalPlayerCe(roleId: string, sid: string, calResult: calPlayerReturn) { - let {role, pushHeros, topLineupCe, hero, guild, serverId} = calResult; - // console.log(JSON.stringify(pushHeros)) - //下发战力 let uids = [{ uid: roleId, sid }]; - pinus.app.get('channelService').pushMessageByUids('onPlayerCeUpdate', resResult(STATUS.SUCCESS, { ce: reduceCe(role.ce) , heros: pushHeros, topLineupCe: reduceCe(topLineupCe) }), uids); + pinus.app.get('channelService').pushMessageByUids('onPlayerCeUpdate', resResult(STATUS.SUCCESS, { ce: role.ce, heros: pushHeros, topLineupCe }), uids); if(guild) { await updateUserInfo(REDIS_KEY.GUILD_INFO, guild.code, [{ field: 'guildCe', value: guild.guildCe }]); } - updateRank(roleId, serverId, topLineupCe, role, pushHeros); - - return hero; + return { heroes, curHero, curRole: role } } -// 修改全局战力并下发 -export async function calAllHeroCe(type:number, sid: string, roleId: string, update: RoleUpdate, args?:Array, params?: any) { - let result = await reCalAllHeroCe(type, roleId, update, args, params); - if(result.pushHeros.length > 0) { - return await pushCalAllHeroCe(roleId, sid, result); - } else { - return result; - } -} - -// 修改全局战力的推送 -export async function pushCalAllHeroCe(roleId: string, sid: string, calResult: calPlayerReturn) { - let {role, pushHeros, topLineupCe, guild, serverId } = calResult; - let uids = [{ uid: roleId, sid }]; - pinus.app.get('channelService').pushMessageByUids('onPlayerCeUpdate', resResult(STATUS.SUCCESS, { ce: reduceCe(role.ce), heros: pushHeros, topLineupCe: reduceCe(topLineupCe) }), uids); - - if(guild) { - await updateUserInfo(REDIS_KEY.GUILD_INFO, guild.code, [{ field: 'guildCe', value: guild.guildCe }]); - } - updateRank(roleId, serverId, topLineupCe, role, pushHeros); - - return calResult; -} - - // 更新排行榜数据 -async function updateRank(roleId: string, serverId: number, topLineupCe: number, role: RoleType, pushHeros: {hid: number, ce: number}[]) { +async function updateRank(roleId: string, serverId: number, topLineupCe: number, role: RoleType, pushHeros: {hid: number, ce: number}[], guild?: GuildType) { // 最强阵容 let r = new Rank(REDIS_KEY.TOP_LINEUP_RANK, { serverId }); @@ -94,4 +112,22 @@ async function updateRank(roleId: string, serverId: number, topLineupCe: number, // 更新最强五人阵容信息 let r5 = new Rank(REDIS_KEY.TOP_LINEUP_INFO, { serverId }); await r5.generParamAndSet(REDIS_KEY.TOP_LINEUP_INFO, { roleId }, { role }); + + if(guild) { + await updateUserInfo(REDIS_KEY.GUILD_INFO, guild.code, [{ field: 'guildCe', value: guild.guildCe }]); + } +} + +export async function getSumCe(roleId: string, num: number) { + let roleCe = await RoleCeModel.findByRoleId(roleId); + let calCe = new CalCe(); + calCe.setRoleCe(roleCe); + let arr = calCe.getResultCeArr(); + let ce = 0; + for(let i = 0; i < num; i++) { + if(arr[i]) { + ce += arr[i].ce; + } + } + return ce; } \ No newline at end of file diff --git a/game-server/app/services/role/calCe.ts b/game-server/app/services/role/calCe.ts index de2c9ff53..826f85d18 100644 --- a/game-server/app/services/role/calCe.ts +++ b/game-server/app/services/role/calCe.ts @@ -1,14 +1,15 @@ -import { ABI_STAGE, ABI_STAGE_TO_TYPE, ABI_TYPE_MAIN, SEID_TYPE } from "../../consts"; -import { HeroUpdate } from "../../db/Hero"; +import { ABI_STAGE, ABI_STAGE_TO_TYPE, ABI_TYPE_MAIN, LINEUP_NUM, SEID_TYPE } from "../../consts"; +import { HeroType, HeroUpdate } from "../../db/Hero"; import { RoleUpdate, Teraph } from "../../db/Role"; import { AttrCell, EquipAttr, HeroAttr, RoleCeType } from "../../db/RoleCe"; +import { TopHero } from "../../domain/dbGeneral"; import { AttributeCal } from "../../domain/roleField/attribute"; import { gameData, getHeroStarByQuality, getHeroWakeByQuality, getTeraph } from "../../pubUtils/data"; import { DicRandomEffectPool } from "../../pubUtils/dictionary/DicRandomEffectPool"; import { DicSe } from "../../pubUtils/dictionary/DicSe"; import { addToMap, deepCopy } from "../../pubUtils/util"; -class RoleCe { +export class CalCe { roleId: string; globalAttrs: Map = new Map(); // attrId => GlobalAttr heroAttrs: Map = new Map(); // hid+attrId => HeroAttr @@ -17,31 +18,13 @@ class RoleCe { equipAttrsByHid: Map = new Map(); // hid => [hid+eplaceId+attrId] equipAttrsByHidAndEplace: Map = new Map(); // hid+eplaceId =>+eplaceId+attrId] heroLv: Map = new Map(); + heroHistoryCe: Map = new Map(); + heroObjectId: Map = new Map(); equipLv: Map = new Map(); // hid+eplaceId => lv - - setRoleCe(roleCe: RoleCeType) { - this.roleId = roleCe.roleId; - for(let globalAttr of roleCe.globalAttrs) { - let obj = this.getGlobalAttrById(globalAttr.attrId); - obj.setByRoleCe(globalAttr); - } - for(let {hid, lv, attrs} of roleCe.heroAttrs) { - this.heroLv.set(hid, lv); - for(let cell of attrs) { - let obj = this.getHeroAttrByHidAndId(hid, cell.attrId); - obj.setByRoleCe(cell); - } - } - for(let { hid, eplaceId, lv, attrs } of roleCe.equipAttrs) { - this.equipLv.set(`${hid}_${eplaceId}`, lv); - for(let cell of attrs) { - let obj = this.getEquipAttrByHidAndId(hid, eplaceId, cell.attrId); - obj.setByRoleCe(cell); - } - } - } + originCes: Map = new Map(); // hid => ce + resultCes: Map = new Map(); // hid => ce - public getGlobalAttrById(attrId: number) { + private getGlobalAttrById(attrId: number) { if(!this.globalAttrs.has(attrId)) { if(ABI_TYPE_MAIN.indexOf(attrId) != -1) { let obj = new GlobalMainAttr(attrId); @@ -54,7 +37,7 @@ class RoleCe { return this.globalAttrs.get(attrId); } - public getHeroAttrByHidAndId(hid: number, attrId: number) { + private getHeroAttrByHidAndId(hid: number, attrId: number) { let key = `${hid}_${attrId}`; if(!this.heroAttrs.has(key)) { if(ABI_TYPE_MAIN.indexOf(attrId) != -1) { @@ -73,7 +56,7 @@ class RoleCe { return this.heroAttrs.get(key); } - public getEquipAttrByHidAndId(hid: number, eplaceId: number, attrId: number) { + private getEquipAttrByHidAndId(hid: number, eplaceId: number, attrId: number) { let key = `${hid}_${eplaceId}_${attrId}`; if(!this.equipAttrs.has(key)) { if(ABI_TYPE_MAIN.indexOf(attrId) != -1) { @@ -115,13 +98,35 @@ class RoleCe { ces.get(hid).push({ id: attrId, val }); } } - let result = new Map(); for(let [hid, arr] of ces) { let obj = new AttributeCal(); obj.setByWarJson(arr); - result.set(hid, obj.calCe()); + let ce = obj.calCe(); + this.resultCes.set(hid, ce); + } + return this.resultCes; + } + + public getCeInc() { + let ceResult = this.calHeroCe(); + let heroCe = new Map(); + let roleInc = 0; + for(let [hid, ce] of ceResult) { + let originCe = this.originCes.get(hid)||0; + if(ce != originCe) { + heroCe.set(hid, { inc: ce - originCe, origin: originCe, ce }); + roleInc += ce - originCe; + this.setHistoryCe(hid, ce); + } + } + return { heroCe, roleInc } + } + + private setHistoryCe(hid: number, ce: number) { + let historyCe = this.heroHistoryCe.get(hid)||0; + if(ce > historyCe) { + this.heroHistoryCe.set(hid, ce); } - return result; } public getRoleCeTable() { @@ -132,13 +137,15 @@ class RoleCe { let heroAttrs: HeroAttr[] = []; for(let [hid, keys] of this.heroAttrsByHid) { let lv = this.heroLv.get(hid); + let historyCe = this.heroHistoryCe.get(hid); + let objectId = this.heroObjectId.get(hid); let attrs: AttrCell[] = []; for(let key of keys) { let heroAttr = this.heroAttrs.get(key); attrs.push(heroAttr.getHeroAttrCell()); } heroAttrs.push({ - hid, lv, attrs + hid, lv, attrs, historyCe, objectId }); } let equipAttrs: EquipAttr[] = []; @@ -157,10 +164,34 @@ class RoleCe { roleId: this.roleId, globalAttrs, heroAttrs, equipAttrs } } -} -// 计算函数 -export class CalCe extends RoleCe { + public setRoleCe(roleCe: RoleCeType) { + this.roleId = roleCe.roleId; + if(roleCe) { + for(let globalAttr of roleCe.globalAttrs) { + let obj = this.getGlobalAttrById(globalAttr.attrId); + obj.setByRoleCe(globalAttr); + } + for(let {hid, lv, attrs, historyCe, objectId } of roleCe.heroAttrs) { + this.heroLv.set(hid, lv); + this.heroHistoryCe.set(hid, historyCe); + this.heroObjectId.set(hid, objectId); + for(let cell of attrs) { + let obj = this.getHeroAttrByHidAndId(hid, cell.attrId); + obj.setByRoleCe(cell); + } + } + for(let { hid, eplaceId, lv, attrs } of roleCe.equipAttrs) { + this.equipLv.set(`${hid}_${eplaceId}`, lv); + for(let cell of attrs) { + let obj = this.getEquipAttrByHidAndId(hid, eplaceId, cell.attrId); + obj.setByRoleCe(cell); + } + } + } + this.originCes = this.calHeroCe(); + } + public setInitHero(role: RoleUpdate, heroes: HeroUpdate[]) { this.roleId = role.roleId; for(let { hid, skinId, lv, quality, star, starStage, colorStar, colorStarStage, job, jobStage, } of heroes) { @@ -173,6 +204,35 @@ export class CalCe extends RoleCe { this.setTeraph(role.teraphs); } + + public setResultHero(hero: HeroType) { + this.heroObjectId.set(hero.hid, hero._id); + } + + public getResultCeArr() { + let arr: { hid: number, ce: number }[] = []; + for(let [ hid, ce ] of this.resultCes) { + arr.push({ hid, ce }); + } + arr.sort((a, b) => b.ce - a.ce); + return arr; + } + + public getTopLineup() { + let topLineup: TopHero[] = [], topLineupCe = 0; + let arr = this.getResultCeArr(); + for(let i = 0; i < LINEUP_NUM; i++) { + if(arr[i]) { + let { hid, ce } = arr[i]; + topLineup.push({ + hid, ce, hero: this.heroObjectId.get(hid) + }); + topLineupCe += ce; + } + } + return { topLineup, topLineupCe }; + } + // 武将基础&成长 public setHeroBase(hid: number, skinId: number) { let dicHero = gameData.hero.get(skinId); diff --git a/game-server/app/services/role/createHero.ts b/game-server/app/services/role/createHero.ts index fae782b4b..1fef3f2af 100644 --- a/game-server/app/services/role/createHero.ts +++ b/game-server/app/services/role/createHero.ts @@ -83,7 +83,6 @@ export class CreateHeroes { let ces = calCe.calHeroCe(); // 战力 for(let hero of this.heroes) { hero.ce = ces.get(hero.hid)||0; - hero.historyCe = hero.ce; this.incRoleCe += hero.ce; } this.roleCe = calCe.getRoleCeTable(); diff --git a/game-server/app/services/role/rewardService.ts b/game-server/app/services/role/rewardService.ts index 88baa19ee..adfaab0d6 100644 --- a/game-server/app/services/role/rewardService.ts +++ b/game-server/app/services/role/rewardService.ts @@ -2,7 +2,6 @@ import { ITID, CONSUME_TYPE, ITEM_TABLE, CURRENCY, CURRENCY_TYPE, MAIL_TYPE, HAN import { getDecimalCnt, getRandEelm, getRandEelmWithWeight, getRandSingleEelm, getRandValueByMinMax, resResult } from '../../pubUtils/util'; import { RoleModel, RoleType } from '../../db/Role'; import { setAp } from '../actionPointService'; -import { pushCalAllHeroCe, calPlayerCeAndSave, calAllHeroCe } from '../playerCeService'; import { ItemModel, ItemType } from '../../db/Item'; import { STATUS } from '../../consts/statusCode'; import { pinus } from 'pinus'; @@ -27,6 +26,7 @@ import { checkPopUpConditionInCreateHero } from '../activity/popUpShopService'; import { CreateHeroes } from './createHero'; import { combineItems, getCoinEventProperties, getGoldEventProperties, sortItems } from './util'; import { nowSeconds } from '../../pubUtils/timeUtil'; +import { calculateCe } from '../playerCeService'; @@ -82,7 +82,7 @@ export async function handleCost(roleId: string, sid: string, goods: Array cur.id == skinId); diff --git a/game-server/test/CheckPatten.ts b/game-server/test/CheckPatten.ts index 19b6c361b..e2f52a30c 100644 --- a/game-server/test/CheckPatten.ts +++ b/game-server/test/CheckPatten.ts @@ -177,7 +177,6 @@ function checkRoleHero(heros) { expect(hero.exp).to.be.a('number'); expect(hero.lv).to.be.a('number'); expect(hero.ce).to.be.a('number'); - expect(hero.historyCe).to.be.a('number'); expect(hero.star).to.be.a('number'); expect(hero.starStage).to.be.a('number'); expect(hero.colorStar).to.be.a('number'); diff --git a/shared/consts/constModules/heroConst.ts b/shared/consts/constModules/heroConst.ts index eafc4a2b4..866d86a9f 100644 --- a/shared/consts/constModules/heroConst.ts +++ b/shared/consts/constModules/heroConst.ts @@ -1,8 +1,8 @@ //武将养成系统分类 export enum HERO_SYSTEM_TYPE { INIT = 0, // 初始武将 - STAR = 1, // 升星 - LVUP = 2, // 升级 + LVUP = 1, // 升级 + STAR = 2, // 升星 COLORSTAR = 3, // 觉醒 QUALITY = 4, // 升品 TRAIN = 5, // (职业)训练 diff --git a/shared/db/Hero.ts b/shared/db/Hero.ts index a41a73341..b3a4ba1ad 100644 --- a/shared/db/Hero.ts +++ b/shared/db/Hero.ts @@ -166,8 +166,6 @@ export default class Hero extends BaseModel { ce: number; // 武将战力 @prop({ required: false, set: (val: boolean) => val, get: () => true }) isReducedCe: boolean; // 如果战力没有缩过就会返回false,缩过了就会返回true - @prop({ required: true, default: 0 }) - historyCe: number; // 武将历史最高战力 @prop({ required: true, type: CeAttrData, default: [], _id: false }) attr: CeAttrData[]; // 影响战力的属性 @@ -300,16 +298,6 @@ export default class Hero extends BaseModel { return insertInfos; } - public static async sumTopHeroCe(roleId: string, num: number) { - let ce: Array<{ historyCe: number }> = await HeroModel.aggregate([ - { $match: { roleId } }, - { $sort: { historyCe: -1 } }, - { $limit: num }, - { $group: { _id: null, historyCe: { $sum: '$historyCe' } } } - ]); - return ce.length > 0 ? ce[0].historyCe : 0; - } - public static async sumHeroCe(roleId: string) { let ce: Array<{ ce: number }> = await HeroModel.aggregate([ { $match: { roleId } }, @@ -323,13 +311,6 @@ export default class Hero extends BaseModel { return heroes; } - public static async updateCe(roleId: string, hid: number, ce: number, oldCe: number, historyCe: number, lean = true) { - let distance = ce - oldCe; - let historyDistance = ce > historyCe ? ce - historyCe : 0; - let result: HeroType = await HeroModel.findOneAndUpdate({ roleId, hid }, { $inc: { ce: distance, historyCe: historyDistance } }).lean(lean); - return result; - } - public static async deleteAccount(roleId: string) { let result = await HeroModel.deleteMany({ roleId }); return result; diff --git a/shared/db/RoleCe.ts b/shared/db/RoleCe.ts index 792ce74b2..c137bcd57 100644 --- a/shared/db/RoleCe.ts +++ b/shared/db/RoleCe.ts @@ -17,6 +17,10 @@ export class HeroAttr { lv: number; @prop({ required: true, type: () => AttrCell, _id: false }) attrs: AttrCell[]; + @prop({ required: true }) + historyCe: number; + @prop({ required: true }) + objectId: string; } export class EquipAttr { @@ -78,7 +82,7 @@ export default class RoleCe extends BaseModel { scrollAttrs: ScrollAttr[]; public static async findByRoleId(roleId: string) { - let result: RoleCeType = await RoleCeModel.findOne({ roleId }).lean(); + let result: RoleCeType = await RoleCeModel.findOneAndUpdate({ roleId }).lean(); return result; } diff --git a/shared/domain/roleField/hero.ts b/shared/domain/roleField/hero.ts index cf82ac277..c083e6640 100644 --- a/shared/domain/roleField/hero.ts +++ b/shared/domain/roleField/hero.ts @@ -41,7 +41,6 @@ export class HeroParam { exp: number; // 经验值 lv: number; // 武将等级 ce: number; // 武将战力 - historyCe: number; // 武将历史最高战力 star: number; // 星级 starStage: number; // 星级六维阶段 colorStar: number; // 觉醒, 彩星 @@ -76,10 +75,8 @@ export class HeroParam { this.lv = hero.lv; if(hero.isReducedCe) { this.ce = hero.ce; - this.historyCe = hero.historyCe; } else { this.ce = reduceCe(hero.ce); - this.historyCe = reduceCe(hero.historyCe); } this.star = hero.star; this.starStage = hero.starStage; diff --git a/shared/pubUtils/playerCe.ts b/shared/pubUtils/playerCe.ts index 53732b10a..cf605f469 100644 --- a/shared/pubUtils/playerCe.ts +++ b/shared/pubUtils/playerCe.ts @@ -1,6 +1,6 @@ -/** - * 体力系统 - */ +// /** +// * 体力系统 +// */ import { HERO_SYSTEM_TYPE, ABI_TYPE, HERO_CE_RATIO, LINEUP_NUM, TALENT_RELATION_TYPE } from '../consts'; @@ -20,694 +20,694 @@ import { GuildModel } from '../db/Guild'; import { DicJob } from './dictionary/DicJob'; import { saveCeChangeLog } from './logUtil'; import { JewelType } from '../db/Jewel'; -import { type } from 'os'; +// import { type } from 'os'; -// 修改并下发战力 -export async function calPlayerCeAndSave(type: number, roleId: string, originHero: HeroType, update: HeroUpdate, args?: Array, params?: any) { - let role = await RoleModel.findByRoleId(roleId); +// // 修改并下发战力 +// export async function calPlayerCeAndSave(type: number, roleId: string, originHero: HeroType, update: HeroUpdate, args?: Array, params?: any) { +// let role = await RoleModel.findByRoleId(roleId); - let { attr: roleAttrs = [], serverId } = role; +// let { attr: roleAttrs = [], serverId } = role; - let heroAttrs = await calPlayerCe(originHero, update, type, args, params); // 根据操作计算attr的增加 +// 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; +// 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); // 更新武将 返回是战力缩过的 +// // 更新到武将 +// 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 }); +// // 更新到角色 +// 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); // 公会更新战力 +// 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), - }); +// 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]); +// saveCeChangeLog(role, incCe, role.ce, type, [originHero.hid]); - return { pushHeros, role, topLineupCe, hero, guild, serverId } -} +// return { pushHeros, role, topLineupCe, hero, guild, serverId } +// } -//全局属性加成 -export async function reCalAllHeroCe(type: number, roleId: string, update: RoleUpdate, args?: Array, params?: any) { - let role = await RoleModel.findByRoleId(roleId); - let heros = await HeroModel.findByRole(roleId); +// //全局属性加成 +// export async function reCalAllHeroCe(type: number, roleId: string, update: RoleUpdate, args?: Array, 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 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 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 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); // 计算更新最强五人战力 +// } +// let { topLineup, topLineupCe } = await calculatetopLineup(role); // 计算更新最强五人战力 - if(allIncCe != 0) { - update.attr = roleAttrs; - update.topLineup = topLineup; - update.topLineupCe = topLineupCe; - } +// 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); +// // console.log('************ roleAttr', update.attr) +// role = await RoleModel.incRoleInfo(roleId, { ce: allIncCe },update); - let guild = await GuildModel.updateCe(roleId, allIncCe); // 公会更新战力 +// 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 } +// 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, role: RoleType, update: RoleUpdate, args: Array, 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; - } +// // 计算武将全局战力 +// async function reCalRoleAttr(type: number, heros: Array, role: RoleType, update: RoleUpdate, args: Array, 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; -} +// return roleAttrs; +// } -// 计算单个武将战力 -export async function calPlayerCe(hero: HeroType, update: HeroUpdate, type: number, args: Array = [], params) { - let heroAttrs: CeAttrData[] = []; // {"hp": {"base": number, "fixUp": number, "ratioUp": number}} +// // 计算单个武将战力 +// export async function calPlayerCe(hero: HeroType, update: HeroUpdate, type: number, args: Array = [], params) { +// let heroAttrs: CeAttrData[] = []; // {"hp": {"base": number, "fixUp": number, "ratioUp": number}} - let addSeidList = new Array(); - let removeSeidList = new Array(); +// let addSeidList = new Array(); +// let removeSeidList = new Array(); - 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); // 处理加值 +// 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; -} +// return heroAttrs; +// } -/** - * 添加皮肤全局加成 - * @param args - * @param ceAttr - */ -function calHeroAddSkin(role: RoleType, skinIds: Array) { - let { attr: roleAttrs } = role; +// /** +// * 添加皮肤全局加成 +// * @param args +// * @param ceAttr +// */ +// function calHeroAddSkin(role: RoleType, skinIds: Array) { +// 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, removeSeidList: Array) { - 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(); // 需要升级的阶 - 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; -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; -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(); // 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, removeSeidList: Array) { -// 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(); -// let curSeids = currentJob?.seid||new Array(); - -// for (let seid of curSeids) { -// let index = findIndex(lastSeids, seid); -// if (index < 0) { -// addSeidList.push(seid, 0); +// 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 } }); // } // } -// for (let seid of lastSeids) { -// let index = findIndex(curSeids, seid); -// if (index < 0) { +// 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, removeSeidList: Array) { +// 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(); // 需要升级的阶 +// 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; +// 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; +// 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(); // 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} hero 更新后的武将 - * @param {number[]} addSeidList 用于更新被动 - * @param {number[]} removeSeidList 用于更新被动 - */ -export function calHeroJobAttr(originHero: HeroType, hero: HeroUpdate, addSeidList: Array, removeSeidList: Array) { - 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); - } +// /** +// * 兵种进阶 +// * @param {HeroType} originHero 原始武将 +// * @param {HeroUpdate} update 更新内容 +// * @param {number[]} addSeidList 用于更新被动 +// * @param {number[]} removeSeidList 用于更新被动 +// */ +// // export function calHeroJobStageUpIncAttr(originHero: HeroType, update: HeroUpdate, addSeidList: Array, removeSeidList: Array) { +// // let { job: oldJob, attr: heroAttrs } = originHero; +// // let { job = oldJob } = update; - 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 } }); - } - } - }; +// // let lastJob = gameData.job.get(oldJob); +// // let currentJob = gameData.job.get(job); +// // let lastSeids = lastJob?.seid||new Array(); +// // let curSeids = currentJob?.seid||new Array(); - originHero.attr = heroAttrs; - // heroAttrs = calHeroJobStageUpIncAttr(originHero, hero, addSeidList, removeSeidList); - return heroAttrs; -} +// // 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 {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); +// /** +// * 初始计算兵种属性 +// * @param {HeroType} originHero 原始武将 +// * @param {HeroUpdate} hero 更新后的武将 +// * @param {number[]} addSeidList 用于更新被动 +// * @param {number[]} removeSeidList 用于更新被动 +// */ +// export function calHeroJobAttr(originHero: HeroType, hero: HeroUpdate, addSeidList: Array, removeSeidList: Array) { +// 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); +// } - let addSkin = gameData.fashionBySkinId.get(skinId); - let delSkin = gameData.fashionBySkinId.get(originSkinId); +// 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 } }); +// } +// } +// }; - 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; +// originHero.attr = heroAttrs; +// // heroAttrs = calHeroJobStageUpIncAttr(originHero, hero, addSeidList, removeSeidList); +// return 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); +// /** +// * 穿戴时装的单武将加成 +// * @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); - return heroAttrs; -} +// let addSkin = gameData.fashionBySkinId.get(skinId); +// let delSkin = gameData.fashionBySkinId.get(originSkinId); -/** - * 羁绊解锁 - * @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; +// 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 oldConnect = oldConnections.find(cur => cur.shipId == shipId); - let connect = connections.find(cur => cur.shipId == shipId); +// 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); - let oldLevel = oldConnect?.level||0; - let level = connect?.level||0; +// return heroAttrs; +// } - 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 更新数据 +// * @param {number} shipId 解锁的那个id +// */ +// export function calHeroConectIncAttr(originHero: HeroType, update: HeroUpdate, shipId: number) { +// let { connections: oldConnections = [], favourLv, attr: heroAttrs } = originHero; +// let { connections = oldConnections } = update; -/** - * 好感度升级,影响羁绊加成 - * - * @param {HeroType} originHero 原始武将数据 - * @param {HeroUpdate} update 更新的数据 - */ -export function calHeroFavourUpIncAttr(originHero: HeroType, update: HeroUpdate) { - let { favourLv: oldFavourLv, attr: heroAttrs } = originHero; - let { favourLv = oldFavourLv } = 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; - } +// 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; -} +// 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 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 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 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 } }); - } - } - } +// 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; -} +// // 套装属性 +// 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); +// 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); - } -} +// 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); - } +// 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; -} +// 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); - } - } - } -} +// 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); @@ -723,387 +723,387 @@ export function isRandSeUnLock(jewelId: number, randSeId: number, stones: Stone[ 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; -} +// 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 } }); - } - } - } +// 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; -} +// 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, removeSeidList: Array) { +// // 添加技能增加的被动属性 +// function addSeidEffect(heroAttrs: CeAttrData[], addSeidList: Array, removeSeidList: Array) { - // 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(); // any: dic_zyz_se表内容 +// // 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(); // 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 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 } }); - } - } - } - } +// // 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, seidId: number, rand: number, seidValue = new Array()) { - 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; +// // 获取dic_zyz_se内容 +// function addSeid(effectList: Array, seidId: number, rand: number, seidValue = new Array()) { +// 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); -} +// 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; +// /** +// * 全局加成,百家学宫 +// * @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 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; +// 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 } }); - } - } +// 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; -} +// 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; +// /** +// * 升星,觉醒,升品时,百家学宫配置武将会相应修改全局战力 +// * @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; - } +// 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 hero = heros.find(cur => cur.hid == hid); +// if(!hero) return null; - let curHeroInSchool = await SchoolModel.findByHid(roleId, hid); - if (!curHeroInSchool) 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); +// 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 } }); - } - } +// 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; -} +// return roleAttrs; +// } -/** - * 全局加成, 名将谱 - * @param heros 所有武将 - * @param hid 激活的武将 - * @param ceAttr - */ -function calScrollAddAttr(role: RoleType,heros: HeroType[], hid: number) { - let { attr: roleAttrs } = role; - // console.log('********** calScrollAddAttr', hid) +// /** +// * 全局加成, 名将谱 +// * @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 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); +// 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) => { +// 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; -} +// 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; -} +// /** +// * 名将谱激活增加单个武将好感 +// * @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 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(); // 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; -} +// function getTalentSeid(talent: Talent[]) { +// let seids = new Map(); // 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; +// /** +// * 升爵位 +// * @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); +// 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; -} +// 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; +// /** +// * 神像强化,更新主属性加成 +// * @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 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; -} +// 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; +// /** +// * 神像进阶,更新次级属性加成 +// * @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 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; +// 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); - } +// 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; -} +// 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); +// 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 } }); - } - } +// 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) +// // 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 } }); - } - } - } +// 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; -} \ No newline at end of file +// return roleAttrs; +// } \ No newline at end of file diff --git a/shared/pubUtils/util.ts b/shared/pubUtils/util.ts index ee094136f..88746426b 100644 --- a/shared/pubUtils/util.ts +++ b/shared/pubUtils/util.ts @@ -14,6 +14,8 @@ import { Floor } from '../domain/activityField/gachaField'; import { WhiteListModel } from '../db/RegionWhiteList'; import { RewardInter } from './interface'; import { RoleType } from '../db/Role'; +import { RoleCeModel } from '../db/RoleCe'; +import { CalCe } from '../services/role/calCe'; const randomName = require("chinese-random-name"); const moment = require('moment'); const crypto = require('crypto'); @@ -115,18 +117,6 @@ export function decodeIdCntArrayStr(str: string, multi: number) { return strMap; } -// 计算当前武将战力 -export async function calculateSumCE(roleId: string, type: number, param: { num?: number, heroes?: Array }) { - let sum: number; - if (type == 1) { // 最高num人历史最高战力和 - sum = await HeroModel.sumTopHeroCe(roleId, param.num || 0); - } else if (type == 2) { // 所有人战力和 - sum = await HeroModel.sumHeroCe(roleId); - } - sum = reduceCe(sum); - return sum; -} - /** * 传入两个时间,返回按照时间差计算,第二个时间比第一个晚几天 * @param preTime 之前的时间 diff --git a/shared/resource/jsons/dic_zyz_gk_branch.json b/shared/resource/jsons/dic_zyz_gk_branch.json index e03c67187..ee31ab34e 100644 --- a/shared/resource/jsons/dic_zyz_gk_branch.json +++ b/shared/resource/jsons/dic_zyz_gk_branch.json @@ -15,8 +15,8 @@ "turnLimted": 20, "forcedCharactor": "&", "fobiddenCharactor": "&", - "victoryInfoInUI": "1.消灭所有敌军\r\n2.死亡的村民数量≤2\r\n3.剩下的村民都到达洞口", - "loseInfoInUI": "1.我方全部阵亡\r\n2.死亡的村民数量≥3\r\n3.20回合内未能胜利", + "victoryInfoInUI": "1.消灭所有敌军\n2.死亡的村民数量≤2\n3.剩下的村民都到达洞口", + "loseInfoInUI": "1.我方全部阵亡\n2.死亡的村民数量≥3\n3.20回合内未能胜利", "starInfoInUI": "1.在20回合内获得胜利", "cost": 10, "iconInMap": "spine&qingnian", @@ -30,7 +30,7 @@ "needPrepare": 1, "spineInBigMap": "&", "HeroNum": "6&6", - "gkInfo": " 循着不详的气息,赵云一行人来到了一座神秘的小村庄。老人们说,他们是为了躲避连年战乱才来此地。\r\n 想不到即使是在这里,也藏着不为人知的阴谋……\r\n 这些阴兵,究竟由谁招来?山林里还有恶兽蠢蠢欲动……\r\n", + "gkInfo": " 循着不详的气息,赵云一行人来到了一座神秘的小村庄。老人们说,他们是为了躲避连年战乱才来此地。\n 想不到即使是在这里,也藏着不为人知的阴谋……\n 这些阴兵,究竟由谁招来?山林里还有恶兽蠢蠢欲动……\n", "HeroNum_1": "1&6", "progress": "1&0|2&0", "progressDesc": "已逃走的百姓数量&被击杀的百姓数量", @@ -52,8 +52,8 @@ "turnLimted": 20, "forcedCharactor": "&", "fobiddenCharactor": "&", - "victoryInfoInUI": "1.消灭所有敌军\r\n2.解救所有被绑架的村民\r\n", - "loseInfoInUI": "1.我方全部阵亡\r\n2.20回合内未能胜利", + "victoryInfoInUI": "1.消灭所有敌军\n2.解救所有被绑架的村民\n", + "loseInfoInUI": "1.我方全部阵亡\n2.20回合内未能胜利", "starInfoInUI": "1.在20回合内获得胜利", "cost": 10, "iconInMap": "spine&yinbingdao&1", @@ -67,7 +67,7 @@ "needPrepare": 1, "spineInBigMap": "&", "HeroNum": "6&6", - "gkInfo": " 赵云一行人刚将村中的百姓带入山洞避难,一位急急忙忙寻找妻子的青年便找上门来。\r\n 洞内仍有不少以往百姓为了躲避战乱设下的陷阱,可务必要当心!\r\n 也许在这昏暗的洞穴里,点燃火炬一路小心前行,才是上策。", + "gkInfo": " 赵云一行人刚将村中的百姓带入山洞避难,一位急急忙忙寻找妻子的青年便找上门来。\n 洞内仍有不少以往百姓为了躲避战乱设下的陷阱,可务必要当心!\n 也许在这昏暗的洞穴里,点燃火炬一路小心前行,才是上策。", "HeroNum_1": "1&6", "progress": "1&0|6&0", "progressDesc": "已解救的百姓数量&待解救的百姓数量", @@ -104,7 +104,7 @@ "needPrepare": 1, "spineInBigMap": "&", "HeroNum": "6&6", - "gkInfo": " 诡异的阴兵,神秘的阴珠,残忍的血法……从巨鹿废墟到山林小村,一个巨大的阴谋似乎一直笼罩在冀州的上空。\r\n 现在赵云一行人终于来到了最后的祭坛,即将揭开这一切的始作俑者……", + "gkInfo": " 诡异的阴兵,神秘的阴珠,残忍的血法……从巨鹿废墟到山林小村,一个巨大的阴谋似乎一直笼罩在冀州的上空。\n 现在赵云一行人终于来到了最后的祭坛,即将揭开这一切的始作俑者……", "HeroNum_1": "1&6", "progress": "&", "progressDesc": "&", @@ -128,7 +128,7 @@ "fobiddenCharactor": "&", "victoryInfoInUI": "消灭所有敌军", "loseInfoInUI": "我方全部阵亡", - "starInfoInUI": "\r\n1.在20回合内获得胜利", + "starInfoInUI": "\n1.在20回合内获得胜利", "cost": 10, "iconInMap": "spine&qingnian", "iconName": "井底世界", @@ -141,7 +141,7 @@ "needPrepare": 1, "spineInBigMap": "&", "HeroNum": "6&6", - "gkInfo": " 在枯井的周围,一群宫女装扮的幽鬼盘亘。\r\n 原来,这些是洛阳被焚毁时,惨死于皇宫中的宫女,因为长久以来的怨气而化为幽鬼,她们憎恨一切活着的人类。\r\n 小心!她们来了!", + "gkInfo": " 在枯井的周围,一群宫女装扮的幽鬼盘亘。\n 原来,这些是洛阳被焚毁时,惨死于皇宫中的宫女,因为长久以来的怨气而化为幽鬼,她们憎恨一切活着的人类。\n 小心!她们来了!", "HeroNum_1": "1&6", "progress": "&", "progressDesc": "&", @@ -178,7 +178,7 @@ "needPrepare": 1, "spineInBigMap": "&", "HeroNum": "6&6", - "gkInfo": " 枯井的尽头是一条大门,出于好奇,赵云一行人穿越幽暗的隧道,来到大门前。\r\n 吱呀——推开大门,原来这里是一片墓室。\r\n 在昏黄的烛火中,他们看到了一群没有意识的侍卫,还有一个没有头颅的巨大身影……", + "gkInfo": " 枯井的尽头是一条大门,出于好奇,赵云一行人穿越幽暗的隧道,来到大门前。\n 吱呀——推开大门,原来这里是一片墓室。\n 在昏黄的烛火中,他们看到了一群没有意识的侍卫,还有一个没有头颅的巨大身影……", "HeroNum_1": "1&6", "progress": "&", "progressDesc": "&", @@ -202,7 +202,7 @@ "fobiddenCharactor": "&", "victoryInfoInUI": "消灭所有敌军", "loseInfoInUI": "我方全部阵亡", - "starInfoInUI": "1.我方无人阵亡;\r\n2.在30回合内获得胜利", + "starInfoInUI": "1.我方无人阵亡;\n2.在30回合内获得胜利", "cost": 30, "iconInMap": "spine&zhangjiao", "iconName": "何后废陵", @@ -215,7 +215,7 @@ "needPrepare": 1, "spineInBigMap": "&", "HeroNum": "6&6", - "gkInfo": " 何太后身材窈窕,风流妩媚,进宫之后更是凭借自身的心计一步步征服了汉灵帝的心。然其天性善妒,刘协出生后,感到自身地位动摇的何太后用鸩酒毒杀了王美人。\r\n 天道有轮回,外戚与宦官相争,何进身死,董卓进京,何太后也被逼饮下毒酒。\r\n 陵墓尽头,彼岸花开,何太后已超脱生死,可千万别停留在这里!", + "gkInfo": " 何太后身材窈窕,风流妩媚,进宫之后更是凭借自身的心计一步步征服了汉灵帝的心。然其天性善妒,刘协出生后,感到自身地位动摇的何太后用鸩酒毒杀了王美人。\n 天道有轮回,外戚与宦官相争,何进身死,董卓进京,何太后也被逼饮下毒酒。\n 陵墓尽头,彼岸花开,何太后已超脱生死,可千万别停留在这里!", "HeroNum_1": "1&6", "progress": "&", "progressDesc": "&", @@ -239,7 +239,7 @@ "fobiddenCharactor": "&", "victoryInfoInUI": "消灭所有敌军", "loseInfoInUI": "我方全部阵亡", - "starInfoInUI": "1.我方无人阵亡;\r\n2.在5回合内获得胜利", + "starInfoInUI": "1.我方无人阵亡;\n2.在5回合内获得胜利", "cost": 10, "iconInMap": "spine&guanhai", "iconName": 0, @@ -276,7 +276,7 @@ "fobiddenCharactor": "&", "victoryInfoInUI": "消灭所有敌军", "loseInfoInUI": "我方全部阵亡", - "starInfoInUI": "1.我方无人阵亡;\r\n2.在5回合内获得胜利", + "starInfoInUI": "1.我方无人阵亡;\n2.在5回合内获得胜利", "cost": 10, "iconInMap": "spine&caosong", "iconName": 0, @@ -313,7 +313,7 @@ "fobiddenCharactor": "&", "victoryInfoInUI": "消灭所有敌军", "loseInfoInUI": "我方全部阵亡", - "starInfoInUI": "1.我方无人阵亡;\r\n2.在5回合内获得胜利", + "starInfoInUI": "1.我方无人阵亡;\n2.在5回合内获得胜利", "cost": 30, "iconInMap": "spine&zhangrang", "iconName": 0, @@ -350,7 +350,7 @@ "fobiddenCharactor": "&", "victoryInfoInUI": "消灭所有敌军", "loseInfoInUI": "我方全部阵亡", - "starInfoInUI": "1.我方无人阵亡;\r\n2.在5回合内获得胜利", + "starInfoInUI": "1.我方无人阵亡;\n2.在5回合内获得胜利", "cost": 10, "iconInMap": "spine&qingnian", "iconName": 0, @@ -387,7 +387,7 @@ "fobiddenCharactor": "&", "victoryInfoInUI": "消灭所有敌军", "loseInfoInUI": "我方全部阵亡", - "starInfoInUI": "1.我方无人阵亡;\r\n2.在5回合内获得胜利", + "starInfoInUI": "1.我方无人阵亡;\n2.在5回合内获得胜利", "cost": 10, "iconInMap": "spine&yinbingdao", "iconName": 0, @@ -424,7 +424,7 @@ "fobiddenCharactor": "&", "victoryInfoInUI": "消灭所有敌军", "loseInfoInUI": "我方全部阵亡", - "starInfoInUI": "1.我方无人阵亡;\r\n2.在5回合内获得胜利", + "starInfoInUI": "1.我方无人阵亡;\n2.在5回合内获得胜利", "cost": 30, "iconInMap": "spine&zhangjiao", "iconName": 0, @@ -461,7 +461,7 @@ "fobiddenCharactor": "&", "victoryInfoInUI": "消灭所有敌军", "loseInfoInUI": "我方全部阵亡", - "starInfoInUI": "1.我方无人阵亡;\r\n2.在5回合内获得胜利", + "starInfoInUI": "1.我方无人阵亡;\n2.在5回合内获得胜利", "cost": 10, "iconInMap": "spine&qingnian", "iconName": 0, @@ -498,7 +498,7 @@ "fobiddenCharactor": "&", "victoryInfoInUI": "消灭所有敌军", "loseInfoInUI": "我方全部阵亡", - "starInfoInUI": "1.我方无人阵亡;\r\n2.在5回合内获得胜利", + "starInfoInUI": "1.我方无人阵亡;\n2.在5回合内获得胜利", "cost": 10, "iconInMap": "spine&yinbingdao", "iconName": 0, @@ -535,7 +535,7 @@ "fobiddenCharactor": "&", "victoryInfoInUI": "消灭所有敌军", "loseInfoInUI": "我方全部阵亡", - "starInfoInUI": "1.我方无人阵亡;\r\n2.在5回合内获得胜利", + "starInfoInUI": "1.我方无人阵亡;\n2.在5回合内获得胜利", "cost": 30, "iconInMap": "spine&zhangjiao", "iconName": 0, @@ -572,7 +572,7 @@ "fobiddenCharactor": "&", "victoryInfoInUI": "消灭所有敌军", "loseInfoInUI": "我方全部阵亡", - "starInfoInUI": "1.我方无人阵亡;\r\n2.在5回合内获得胜利", + "starInfoInUI": "1.我方无人阵亡;\n2.在5回合内获得胜利", "cost": 10, "iconInMap": "spine&wangcan", "iconName": 0, @@ -609,7 +609,7 @@ "fobiddenCharactor": "&", "victoryInfoInUI": "消灭所有敌军", "loseInfoInUI": "我方全部阵亡", - "starInfoInUI": "1.我方无人阵亡;\r\n2.在5回合内获得胜利", + "starInfoInUI": "1.我方无人阵亡;\n2.在5回合内获得胜利", "cost": 10, "iconInMap": "spine&yanshi", "iconName": 0, @@ -646,7 +646,7 @@ "fobiddenCharactor": "&", "victoryInfoInUI": "消灭所有敌军", "loseInfoInUI": "我方全部阵亡", - "starInfoInUI": "1.我方无人阵亡;\r\n2.在5回合内获得胜利", + "starInfoInUI": "1.我方无人阵亡;\n2.在5回合内获得胜利", "cost": 30, "iconInMap": "spine&sengren", "iconName": 0, @@ -683,7 +683,7 @@ "fobiddenCharactor": "&", "victoryInfoInUI": "消灭所有敌军", "loseInfoInUI": "我方全部阵亡", - "starInfoInUI": "1.我方无人阵亡;\r\n2.在5回合内获得胜利", + "starInfoInUI": "1.我方无人阵亡;\n2.在5回合内获得胜利", "cost": 10, "iconInMap": "spine&qingnian", "iconName": "武陵顽猴", @@ -720,7 +720,7 @@ "fobiddenCharactor": "&", "victoryInfoInUI": "消灭所有敌军", "loseInfoInUI": "我方全部阵亡", - "starInfoInUI": "1.我方无人阵亡;\r\n2.在5回合内获得胜利", + "starInfoInUI": "1.我方无人阵亡;\n2.在5回合内获得胜利", "cost": 10, "iconInMap": "spine&yinbingdao", "iconName": "桃源疫民", @@ -757,7 +757,7 @@ "fobiddenCharactor": "&", "victoryInfoInUI": "消灭所有敌军", "loseInfoInUI": "我方全部阵亡", - "starInfoInUI": "1.我方无人阵亡;\r\n2.在5回合内获得胜利", + "starInfoInUI": "1.我方无人阵亡;\n2.在5回合内获得胜利", "cost": 30, "iconInMap": "spine&zhangjiao", "iconName": "西夷疫魔", From 14b28921aff12c154f5160ad324771aa1b199906 Mon Sep 17 00:00:00 2001 From: luying Date: Mon, 28 Mar 2022 17:44:14 +0800 Subject: [PATCH 04/12] =?UTF-8?q?=E6=88=98=E5=8A=9B=EF=BC=9A=E4=BF=AE?= =?UTF-8?q?=E5=A4=8D=E5=88=9B=E5=BB=BA=E6=AD=A6=E5=B0=86bug?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../app/servers/gm/handler/gmRoleHandler.ts | 8 +- .../app/servers/role/handler/equipHandler.ts | 26 +- .../app/servers/role/handler/heroHandler.ts | 31 ++- .../app/servers/role/handler/roleHandler.ts | 26 +- game-server/app/services/playerCeService.ts | 132 ++++++++-- game-server/app/services/role/calCe.ts | 145 +++++++---- game-server/app/services/role/createHero.ts | 233 ++++-------------- .../app/services/role/rewardService.ts | 10 +- game-server/config/serverProtos.ts | 30 +-- shared/db/Hero.ts | 32 +-- shared/db/RoleCe.ts | 8 +- shared/pubUtils/playerCe.ts | 1 - shared/pubUtils/util.ts | 90 +++---- 13 files changed, 379 insertions(+), 393 deletions(-) diff --git a/game-server/app/servers/gm/handler/gmRoleHandler.ts b/game-server/app/servers/gm/handler/gmRoleHandler.ts index d5633081d..356d7cb1d 100644 --- a/game-server/app/servers/gm/handler/gmRoleHandler.ts +++ b/game-server/app/servers/gm/handler/gmRoleHandler.ts @@ -20,9 +20,8 @@ import { GuildLeader } from '../../../domain/rank'; import { HeroModel } from '../../../db/Hero'; import { SkinModel } from '../../../db/Skin'; import { PvpDefenseModel } from '../../../db/PvpDefense'; -import { calculatetopLineup } from '../../../pubUtils/util'; import { createHeroes } from '../../../services/role/createHero'; -import { calculateCe } from '../../../services/playerCeService'; +import { calculateCeWithHero } from '../../../services/playerCeService'; let timer: NodeJS.Timer; export default function (app: Application) { @@ -95,7 +94,7 @@ export class GmRoleHandler { param.lv = newLv; param['exp'] = exp; } - await calculateCe(HERO_SYSTEM_TYPE.INIT, roleId, hero.serverId, sid, param, {}, { hid }); + await calculateCeWithHero(HERO_SYSTEM_TYPE.INIT, roleId, hero.serverId, sid, hid, param); // if(param.job > 0) { // await calculateCe(HERO_SYSTEM_TYPE.STAGEUP, roleId, hero.serverId, sid, param, {}, { hid }); @@ -118,9 +117,8 @@ export class GmRoleHandler { await HeroModel.deleteHero(roleId, hid); await SkinModel.deleteByHero(roleId, hid); let role = await RoleModel.findByRoleId(roleId); - let { topLineup, topLineupCe } = await calculatetopLineup(role, hid, 0, null); await PvpDefenseModel.deleteHero(roleId, hid); - await RoleModel.updateRoleInfo(roleId, { topLineup, topLineupCe, ce: role.ce - hero.ce }); + await RoleModel.updateRoleInfo(roleId, { topLineup: role.topLineup.filter(cur => cur.hid != hid), topLineupCe: role.topLineupCe - hero.ce, ce: role.ce - hero.ce }); return resResult(STATUS.SUCCESS); } diff --git a/game-server/app/servers/role/handler/equipHandler.ts b/game-server/app/servers/role/handler/equipHandler.ts index 9ac687b38..95330564e 100644 --- a/game-server/app/servers/role/handler/equipHandler.ts +++ b/game-server/app/servers/role/handler/equipHandler.ts @@ -16,7 +16,7 @@ import { pushEquipQualityMax, pushEquipStarMax } from "../../../services/sysChat import { addConsumeToHero } from "../../../services/roleService"; import { CheckMeterial } from "../../../services/role/checkMaterial"; import { combineItems } from "../../../services/role/util"; -import { calculateCe } from "../../../services/playerCeService"; +import { calculateCeWithHero } from "../../../services/playerCeService"; export default function (app: Application) { new HandlerService(app, {}); @@ -58,7 +58,7 @@ export class EquipHandler { consumes: addConsumeToHero(hero.consumes, dicEquip.composeMaterial), } - await calculateCe(HERO_SYSTEM_TYPE.COMPOSE_EQUIP, roleId, serverId, sid, update, {}, { hid, ePlaceId }); + await calculateCeWithHero(HERO_SYSTEM_TYPE.COMPOSE_EQUIP, roleId, serverId, sid, hid, update, { ePlaceId }); await checkTaskInComposeEquip(serverId, roleId, sid, oldEplace, newEplace); let curHero = { @@ -105,7 +105,7 @@ export class EquipHandler { ePlace: newEplace, consumes: addConsumeToHero(hero.consumes, consumes) } - await calculateCe(HERO_SYSTEM_TYPE.EQUIP_STRENGTH, roleId, serverId, sid, update, {}, { hid, ePlaceId }); + await calculateCeWithHero(HERO_SYSTEM_TYPE.EQUIP_STRENGTH, roleId, serverId, sid, hid, update, { ePlaceId }); await checkTaskInEquipLvUp(serverId, roleId, sid, oldEplace, newEplace, [ePlaceId]); const curHero = { @@ -156,7 +156,7 @@ export class EquipHandler { ePlace: newEplace, consumes: addConsumeToHero(hero.consumes, consumes), } - await calculateCe(HERO_SYSTEM_TYPE.EQUIP_STRENGTH, roleId, serverId, sid, update, {}, { hid, ePlaceIds: [...eplaceIds.keys()] }); + await calculateCeWithHero(HERO_SYSTEM_TYPE.EQUIP_STRENGTH, roleId, serverId, sid, hid, update, { ePlaceIds: [...eplaceIds.keys()] }); await checkTaskInEquipLvUp(serverId, roleId, sid, ePlace, newEplace, [...eplaceIds.keys()]); const curHero = { @@ -223,7 +223,7 @@ export class EquipHandler { ePlace: newEplace, consumes: addConsumeToHero(hero.consumes, consumes), } - await calculateCe(HERO_SYSTEM_TYPE.EQUIP_QUALITY, roleId, serverId, sid, update, {}, { hid, ePlaceId }); + await calculateCeWithHero(HERO_SYSTEM_TYPE.EQUIP_QUALITY, roleId, serverId, sid, hid, update, { ePlaceId }); await checkTaskInEquipQualityUp(serverId, roleId, sid, oldEplace, newEplace, ePlaceId, hid, isUpQuality); pushEquipQualityMax(roleId, roleName, serverId, hid, newEquip, isUpQuality); @@ -298,7 +298,7 @@ export class EquipHandler { ePlace: newEplace, consumes: addConsumeToHero(hero.consumes, consumes) } - await calculateCe(HERO_SYSTEM_TYPE.EQUIP_STAR, roleId, serverId, sid, update, {}, { hid, ePlaceId }); + await calculateCeWithHero(HERO_SYSTEM_TYPE.EQUIP_STAR, roleId, serverId, sid, hid, update, { ePlaceId }); await checkTaskInEquipStarUp(serverId, roleId, sid, oldEplace, newEplace, ePlaceId, hid, isUpStar); pushEquipStarMax(roleId, roleName, serverId, hid, newEquip, isUpStar); @@ -343,7 +343,7 @@ export class EquipHandler { let canChange = originJewel && checkJewelCanPutOnEquip(originEquip, originJewel); if(canChange) canSentMineToOrigin = true; let { newEplace, updatedEplace } = updateEplace(originEplace, ePlaceId, { jewel: canChange? originJewel.seqId: 0 }); - await calculateCe(HERO_SYSTEM_TYPE.EQUIP_JEWEL, roleId, serverId, sid, { ePlace: newEplace }, {}, { hid, ePlaceId, oldJewel: jewel, newJewel: canChange? originJewel:null }); + await calculateCeWithHero(HERO_SYSTEM_TYPE.EQUIP_JEWEL, roleId, serverId, sid, hid, { ePlace: newEplace }, { ePlaceId, oldJewel: jewel, newJewel: canChange? originJewel:null }); await checkTaskInPutJewel(serverId, roleId, sid, originEplace, newEplace, ePlaceId, jewel, canChange? originJewel:null); originHeroResult = { hid: originHero.hid, ePlace: updatedEplace }; @@ -356,7 +356,7 @@ export class EquipHandler { // 目标镶嵌上 let curJewel = await JewelModel.putOnOrOff(seqId, hid, ePlaceId); let { newEplace, updatedEplace } = updateEplace(oldEplace, ePlaceId, { jewel: seqId }); - await calculateCe(HERO_SYSTEM_TYPE.EQUIP_JEWEL, roleId, serverId, sid, { ePlace: newEplace }, {}, { hid, ePlaceId, oldJewel: originJewel, newJewel: curJewel }); + await calculateCeWithHero(HERO_SYSTEM_TYPE.EQUIP_JEWEL, roleId, serverId, sid, hid, { ePlace: newEplace }, { ePlaceId, oldJewel: originJewel, newJewel: curJewel }); await checkTaskInPutJewel(serverId, roleId, sid, oldEplace, newEplace, ePlaceId, originJewel, curJewel); let curHero = { @@ -384,7 +384,7 @@ export class EquipHandler { let curJewel = await JewelModel.putOnOrOff(curEquip.jewel, 0, 0); let { newEplace, updatedEplace } = updateEplace(oldEplace, ePlaceId, { jewel: 0 }); - await calculateCe(HERO_SYSTEM_TYPE.EQUIP_JEWEL, roleId, serverId, sid, { ePlace: newEplace }, {}, { hid, ePlaceId, oldJewel: curJewel }); + await calculateCeWithHero(HERO_SYSTEM_TYPE.EQUIP_JEWEL, roleId, serverId, sid, hid, { ePlace: newEplace }, { ePlaceId, oldJewel: curJewel }); await checkTaskInPutJewel(serverId, roleId, sid, oldEplace, newEplace, ePlaceId, null, curJewel); let curHero = { @@ -437,7 +437,7 @@ export class EquipHandler { ePlace: newEplace, consumes: updateConsumes, } - await calculateCe(HERO_SYSTEM_TYPE.EQUIP_STONE, roleId, serverId, sid, update, {}, { hid, ePlaceId, jewel }); + await calculateCeWithHero(HERO_SYSTEM_TYPE.EQUIP_STONE, roleId, serverId, sid, hid, update, { ePlaceId, jewel }); await checkTaskInPutStone(serverId, roleId, sid, oldEplace, newEplace, ePlaceId, jewel); let curHero = { @@ -557,7 +557,7 @@ export class EquipHandler { // 更新战力 if(hid > 0) { const hero = await HeroModel.findByHidAndRole(hid, roleId); - await calculateCe(HERO_SYSTEM_TYPE.JEWEL_RESET_RANDSE, roleId, serverId, sid, {}, {}, { hid, ePlaceId, oldJewel: jewel, newJewel, hero }); + await calculateCeWithHero(HERO_SYSTEM_TYPE.JEWEL_RESET_RANDSE, roleId, serverId, sid, hid, {}, { ePlaceId, oldJewel: jewel, newJewel, hero }); } await checkTaskInEquipReset(serverId, roleId, sid); @@ -639,7 +639,7 @@ export class EquipHandler { // 更新战力 if(isSuccess && hid > 0) { const hero = await HeroModel.findByHidAndRole(hid, roleId); - await calculateCe(HERO_SYSTEM_TYPE.JEWEL_QUENCH, roleId, serverId, sid, {}, {}, { hid, ePlaceId, oldJewel: jewel, newJewel, hero }); + await calculateCeWithHero(HERO_SYSTEM_TYPE.JEWEL_QUENCH, roleId, serverId, sid, hid, {}, { ePlaceId, oldJewel: jewel, newJewel, hero }); } await checkTaskInEquipQuench(serverId, roleId, sid, isSuccess); @@ -759,7 +759,7 @@ export class EquipHandler { // 更新战力 if(targetJewel.hid > 0) { const hero = await HeroModel.findByHidAndRole(targetJewel.hid, roleId); - await calculateCe(HERO_SYSTEM_TYPE.JEWEL_RESET_RANDSE, roleId, serverId, sid, {}, {}, { hid: targetJewel.ePlaceId, ePlaceId: targetJewel.ePlaceId, oldJewel: originJewel, newJewel, hero }); + await calculateCeWithHero(HERO_SYSTEM_TYPE.JEWEL_RESET_RANDSE, roleId, serverId, sid, targetJewel.hid, {}, { hid: targetJewel.ePlaceId, ePlaceId: targetJewel.ePlaceId, oldJewel: originJewel, newJewel, hero }); } diff --git a/game-server/app/servers/role/handler/heroHandler.ts b/game-server/app/servers/role/handler/heroHandler.ts index c34958b06..5a8bbfb0a 100644 --- a/game-server/app/servers/role/handler/heroHandler.ts +++ b/game-server/app/servers/role/handler/heroHandler.ts @@ -10,7 +10,6 @@ import { gameData, getHeroExpByLv, getHeroStarByQuality, getHeroWakeByQuality, g import { ItemInter, RewardInter } from '../../../pubUtils/interface'; import { getDropItems, FIGURE_UNLOCK_CONDITION } from '../../../consts/constModules/itemConst' import { pushComposeOrangeHero, pushHeroQualityUpMsg, pushHeroStarMax, pushHeroWakeUp } from '../../../services/chatService'; -import { calculatetopLineup } from '../../../pubUtils/util'; import { PvpDefenseModel } from '../../../db/PvpDefense'; import { checkTask, checkTaskInHeroQUalityUp, checkTaskInHeroStarUp, checkTaskInHeroTrain, checkTaskInHeroWakeUp } from '../../../services/task/taskService'; import { isNumber, pick } from 'underscore'; @@ -22,7 +21,7 @@ import { HERO, REBORN } from '../../../pubUtils/dicParam'; import { createHero, createHeroes } from '../../../services/role/createHero'; import { CheckMeterial } from '../../../services/role/checkMaterial'; import { HeroParam } from '../../../domain/roleField/hero'; -import { calculateCe } from '../../../services/playerCeService'; +import { calculateCeWithHero } from '../../../services/playerCeService'; export default function (app: Application) { new HandlerService(app, {}); @@ -85,7 +84,6 @@ export class HeroHandler { let { lv: oldLv, exp: oldExp } = hero; if (oldLv >= playerLv) return resResult(STATUS.ROLE_HERO_LV_OVER); if (oldLv + addLv > playerLv) addLv = playerLv - oldLv; - console.log('******* addLv', addLv, oldLv, playerLv); let nextExp = getHeroExpByLv(oldLv + addLv - 1); console.log('nextExp', nextExp, oldLv + addLv - 1, oldExp) @@ -127,7 +125,7 @@ export class HeroHandler { consumes: addConsumeToHero(hero.consumes, material) } - let { curHero } = await calculateCe(HERO_SYSTEM_TYPE.LVUP, roleId, serverId, sid, update, {}, { hid }); + let { curHero } = await calculateCeWithHero(HERO_SYSTEM_TYPE.LVUP, roleId, serverId, sid, hid, update); // 任务 await checkTask(serverId, roleId, sid, TASK_TYPE.HERO_LV, { oldLv, hero: curHero }); @@ -188,7 +186,7 @@ export class HeroHandler { } - let { curHero } = await calculateCe(HERO_SYSTEM_TYPE.STAR, roleId, serverId, sid, update, {}, { hid, hero, isUpStar }); + let { curHero } = await calculateCeWithHero(HERO_SYSTEM_TYPE.STAR, roleId, serverId, sid, hid, update, { hid, hero, isUpStar }); if (isUpStar) { await checkTaskInHeroStarUp(serverId, roleId, sid, curHero, oldStar); // 任务 } @@ -236,7 +234,7 @@ export class HeroHandler { consumes: addConsumeToHero(hero.consumes, material) } - let { curHero } = await calculateCe(HERO_SYSTEM_TYPE.QUALITY, roleId, serverId, sid, update, {}, { hid, hero }); + let { curHero } = await calculateCeWithHero(HERO_SYSTEM_TYPE.QUALITY, roleId, serverId, sid, hid, update, { hero }); await checkTaskInHeroQUalityUp(serverId, roleId, sid, curHero); pushHeroQualityUpMsg(roleId, roleName, serverId, curHero); return resResult(STATUS.SUCCESS, { curHero: pick(curHero, ['hid', 'quality']) }); @@ -301,7 +299,7 @@ export class HeroHandler { consumes: addConsumeToHero(hero.consumes, consumes) } - let { curHero } = await calculateCe(HERO_SYSTEM_TYPE.COLORSTAR, roleId, serverId, sid, update, {}, { hid, hero, isUpStar }); + let { curHero } = await calculateCeWithHero(HERO_SYSTEM_TYPE.COLORSTAR, roleId, serverId, sid, hid, update, { hero, isUpStar }); if (isUpStar) { await checkTaskInHeroWakeUp(serverId, roleId, sid, curHero, oldColorStar); // 任务 } @@ -353,7 +351,7 @@ export class HeroHandler { jobStage: newJobStage, consumes: addConsumeToHero(hero.consumes, consumes) } - let { curHero } = await calculateCe(HERO_SYSTEM_TYPE.TRAIN, roleId, serverId, sid, update, {}, { hid, hero }); + let { curHero } = await calculateCeWithHero(HERO_SYSTEM_TYPE.TRAIN, roleId, serverId, sid, hid, update, { hero }); await checkTaskInHeroTrain(serverId, roleId, sid, curHero, trainCount); // 任务 return resResult(STATUS.SUCCESS, { curHero: pick(curHero, ['hid', 'job', 'jobStage'])}); } @@ -389,7 +387,7 @@ export class HeroHandler { consumes: addConsumeToHero(hero.consumes, consumes) } - let { curHero } = await calculateCe(HERO_SYSTEM_TYPE.STAGEUP, roleId, serverId, sid, update, {}, { hid, hero }); + let { curHero } = await calculateCeWithHero(HERO_SYSTEM_TYPE.STAGEUP, roleId, serverId, sid, hid, update, { hid, hero }); await checkTask(serverId, roleId, sid, TASK_TYPE.HERO_STAGE_UP, { hero: curHero, stageUpCnt: 1 }); // 任务 const heroResult = new HeroParam(curHero); return resResult(STATUS.SUCCESS, { curHero: {...pick(heroResult, ['hid', 'job', 'jobStage', 'totalTalentPoint']) }}); @@ -444,7 +442,7 @@ export class HeroHandler { consumes: addConsumeToHero(hero.consumes, consumes) } //重算战力并下发 - let { curHero } = await calculateCe(HERO_SYSTEM_TYPE.CONNECT, roleId, serverId, sid, update, {}, { hid: hero.hid, shipId }); + let { curHero } = await calculateCeWithHero(HERO_SYSTEM_TYPE.CONNECT, roleId, serverId, sid, hero.hid, update, { shipId }); // 任务 await checkTask(serverId, roleId, sid, TASK_TYPE.HERO_CONNECT, { connectLv: level }) return resResult(STATUS.SUCCESS, { curHero: pick(curHero, ['hid', 'connections']) }); @@ -531,7 +529,7 @@ export class HeroHandler { // } else { // hero = await HeroModel.updateHeroInfo(roleId, hero.hid, update); // } - let { curHero } = await calculateCe(HERO_SYSTEM_TYPE.FAVOUR, roleId, serverId, sid, update, {}, { hid: hero.hid, isFavourLvUp }); + let { curHero } = await calculateCeWithHero(HERO_SYSTEM_TYPE.FAVOUR, roleId, serverId, sid, hero.hid, update, { isFavourLvUp }); if(isFavourLvUp) { await unlockFigure(sid, roleId, [{ type: FIGURE_UNLOCK_CONDITION.HERO_FAVOR, paramHid: curHero.hid, paramFavourLv: curHero.favourLv }]); await checkTask(serverId, roleId, sid, TASK_TYPE.HERO_FAVOUR_LV, { hero: curHero, oldFavourLv: oldLv }); // 任务 @@ -591,7 +589,7 @@ export class HeroHandler { job: dicNewJob.jobid, ePlace: newEplace } - let { curHero } = await calculateCe(HERO_SYSTEM_TYPE.SKIN, roleId, serverId, sid, update, {}, { hid: hero.hid }); + let { curHero } = await calculateCeWithHero(HERO_SYSTEM_TYPE.SKIN, roleId, serverId, sid, hero.hid, update); let resultHero = new HeroParam(curHero); return resResult(STATUS.SUCCESS, { curHero: {...pick(resultHero, ['hid', 'skins', 'skinId', 'job', 'talent', 'usedTalentPoint']), ePlace: newEplace }}); } @@ -658,7 +656,7 @@ export class HeroHandler { } } - let { curHero } = await calculateCe(HERO_SYSTEM_TYPE.REBIRTH, roleId, serverId, sid, {...initInfo, attr: heroAttr}, {}, { hid }); + let { curHero } = await calculateCeWithHero(HERO_SYSTEM_TYPE.REBIRTH, roleId, serverId, sid, hid, {...initInfo, attr: heroAttr}); let goods = await addItems(roleId, roleName, sid, consumes, ITEM_CHANGE_REASON.REBIRTH); const heroResult = new HeroParam(curHero); @@ -698,7 +696,7 @@ export class HeroHandler { let { newSkins } = updateSkinTalent(skins, new Talent(id), usedTalentPoint + needTalentPoint); - let { curHero } = await calculateCe(HERO_SYSTEM_TYPE.TALENT, roleId, serverId, sid, { skins: newSkins }, {}, { hid }); + let { curHero } = await calculateCeWithHero(HERO_SYSTEM_TYPE.TALENT, roleId, serverId, sid, hid, { skins: newSkins }); const heroResult = new HeroParam(curHero); return resResult(STATUS.SUCCESS, { curHero: {...pick(heroResult, ['hid', 'talent', 'usedTalentPoint', 'totalTalentPoint']) }}); @@ -735,7 +733,7 @@ export class HeroHandler { let { newSkins } = updateSkinTalent(skins, new Talent(id, talent.level + 1), usedTalentPoint + needTalentPoint); - let { curHero } = await calculateCe(HERO_SYSTEM_TYPE.TALENT, roleId, serverId, sid, { skins: newSkins }, {}, { hid }); + let { curHero } = await calculateCeWithHero(HERO_SYSTEM_TYPE.TALENT, roleId, serverId, sid, hid, { skins: newSkins }); const heroResult = new HeroParam(curHero); return resResult(STATUS.SUCCESS, { curHero: {...pick(heroResult, ['hid', 'talent', 'usedTalentPoint', 'totalTalentPoint']) }}); } @@ -760,7 +758,7 @@ export class HeroHandler { let newSkins = initSkinTalent(skins); - let { curHero } = await calculateCe(HERO_SYSTEM_TYPE.TALENT, roleId, serverId, sid, { skins: newSkins }, {}, { hid }); + let { curHero } = await calculateCeWithHero(HERO_SYSTEM_TYPE.TALENT, roleId, serverId, sid, hid, { skins: newSkins }); const heroResult = new HeroParam(curHero); return resResult(STATUS.SUCCESS, { curHero: {...pick(heroResult, ['hid', 'talent', 'usedTalentPoint', 'totalTalentPoint']) }}); @@ -820,7 +818,6 @@ export class HeroHandler { await HeroModel.deleteHero(roleId, hid); let role = await RoleModel.findByRoleId(roleId); - await calculatetopLineup(role, hid, 0, null); await PvpDefenseModel.deleteHero(roleId, hid); await RoleModel.updateRoleInfo(roleId, { topLineup: role.topLineup, topLineupCe: role.topLineupCe, ce: role.ce - hero.ce }); return resResult(STATUS.SUCCESS); diff --git a/game-server/app/servers/role/handler/roleHandler.ts b/game-server/app/servers/role/handler/roleHandler.ts index 97b7c3ac1..741e8ebe4 100644 --- a/game-server/app/servers/role/handler/roleHandler.ts +++ b/game-server/app/servers/role/handler/roleHandler.ts @@ -1,6 +1,6 @@ import { STATUS } from '../../../consts/statusCode'; import { RoleModel, RoleUpdate } from './../../../db/Role'; -import { HeroModel, HeroUpdate } from '../../../db/Hero'; +import { HeroModel, HeroType, HeroUpdate } from '../../../db/Hero'; import { resResult, decodeIdCntArrayStr, parseGoodStr, genCode } from '../../../pubUtils/util'; import { Application, BackendSession, pinus, HandlerService, } from 'pinus'; import { handleCost, addItems, getGoldObject, getCoinObject } from '../../../services/role/rewardService'; @@ -24,8 +24,8 @@ import * as dicParam from '../../../pubUtils/dicParam'; import Counter from '../../../db/Counter'; import { UserModel } from '../../../db/User'; import { checkFilterWords, reportTAEvent, treatRoleName } from '../../../services/sdkService'; -import { createHeroes, CreateHeroes } from '../../../services/role/createHero'; -import { calculateCe } from '../../../services/playerCeService'; +import { createHeroes } from '../../../services/role/createHero'; +import { calculateCeWithHero, calculateWithRole } from '../../../services/playerCeService'; export default function (app: Application) { new HandlerService(app, {}); @@ -44,14 +44,14 @@ export class RoleHandler { let { roleName } = msg; - let role = await RoleModel.findByRoleId(roleId, 'roleName hasInit', true); + let role = await RoleModel.findByRoleId(roleId, 'roleName hasInit title teraphs', true); if (role.hasInit) return resResult(STATUS.ROLE_HAS_INIT); let checkName = await RoleModel.checkName(roleName, serverId); if (checkName) return resResult(STATUS.NAME_HAS_USED); - let { resultHeroes: heroes } = await createHeroes(roleId, roleName, sid, serverId, DEFAULT_HEROES.map(hid => ({hid, count: 1}))); - role = await RoleModel.updateRoleInfo(roleId, { roleName, hasInit: true }); + let { resultHeroes: heroes } = await createHeroes(roleId, roleName, sid, serverId, DEFAULT_HEROES.map(hid => ({hid, count: 1})), { roleName, hasInit: true, title: role.title, teraphs: role.teraphs }); + // role = await RoleModel.updateRoleInfo(roleId, { roleName, hasInit: true }); // 在算战力的时候一起更新 session.set('roleName', roleName); session.push('roleName', () => { }); @@ -95,7 +95,7 @@ export class RoleHandler { return resResult(STATUS.BATTLE_CONSUMES_NOT_ENOUGH); let update = { title: title + 1 } - let { curRole } = await calculateCe(HERO_SYSTEM_TYPE.TITLE, roleId, serverId, sid, {}, update, {}); + let { curRole } = await calculateWithRole(HERO_SYSTEM_TYPE.TITLE, roleId, serverId, sid, update); // 任务 await checkTask(serverId, roleId, sid, TASK_TYPE.ROLE_TITLE, { oldTitle: title, title: update.title }); @@ -128,7 +128,7 @@ export class RoleHandler { if (!result) return resResult(STATUS.BATTLE_CONSUMES_NOT_ENOUGH); - let { curRole } = await calculateCe(HERO_SYSTEM_TYPE.TERAPH, roleId, serverId, sid, {}, { teraphs }, { teraphId: id }); + let { curRole } = await calculateWithRole(HERO_SYSTEM_TYPE.TERAPH, roleId, serverId, sid, { teraphs }, { teraphId: id }); // 任务 await checkTask(serverId, roleId, sid, TASK_TYPE.ROLE_TERAPH_STRENGTHEN, { count }); @@ -171,7 +171,7 @@ export class RoleHandler { let result = await handleCost(roleId, sid, consumes, ITEM_CHANGE_REASON.TERAPH_QUALITY_UP); if (!result) return resResult(STATUS.BATTLE_CONSUMES_NOT_ENOUGH); - let { curRole } = await calculateCe(HERO_SYSTEM_TYPE.TERAPH_UP, roleId, serverId, sid, {}, { teraphs }, { teraphId: id }); + let { curRole } = await calculateWithRole(HERO_SYSTEM_TYPE.TERAPH_UP, roleId, serverId, sid, { teraphs }, { teraphId: id }); // 神像进阶,进阶一次就触发一次礼包弹框 await checkTask(serverId, roleId, sid, TASK_TYPE.ROLE_TERAPH_STAGE_UP); @@ -204,14 +204,14 @@ export class RoleHandler { return resResult(STATUS.DIC_DATA_NOT_FOUND); } let isOpen = !!dicPosition.get(positionId.toString()); // 该位置是否解锁 - + let curHero: HeroType = null; if (hid > 0) { let findHero = await SchoolModel.findByHid(roleId, hid); if (!!findHero) { return resResult(STATUS.ROLE_SCHOOL_HERO_USED); } - let curHero = await HeroModel.findByHidAndRole(hid, roleId); + curHero = await HeroModel.findByHidAndRole(hid, roleId); if (!curHero) return resResult(STATUS.HERO_NOT_FIND); } @@ -228,7 +228,7 @@ export class RoleHandler { } await SchoolModel.updateBySclAndPos(roleId, schoolId, positionId, { hid, isOpen }) - await calculateCe(HERO_SYSTEM_TYPE.SCHOOL, roleId, serverId, sid, {}, {}, { schoolId, schoolHid: hid, preSchoolHid: preHid }); + await calculateWithRole(HERO_SYSTEM_TYPE.SCHOOL, roleId, serverId, sid, {}, { schoolId, hero: curHero, schoolHid: hid, preSchoolHid: preHid }); // 任务 await checkTask(serverId, roleId, sid, TASK_TYPE.ROLE_SCHOOL_PUT_HERO, { hid, preHid }); @@ -319,7 +319,7 @@ export class RoleHandler { update.scrollId = dicHeroScroll ? dicHeroScroll.id : 0; let hero = await HeroModel.updateHeroInfo(roleId, hid, update); - await calculateCe(HERO_SYSTEM_TYPE.SCROLL, roleId, serverId, sid, update, {}, { hid }); + await calculateCeWithHero(HERO_SYSTEM_TYPE.SCROLL, roleId, serverId, sid, hid, update); // 任务 await checkTaskInActiveScroll(serverId, roleId, sid, scrollActive, hero); diff --git a/game-server/app/services/playerCeService.ts b/game-server/app/services/playerCeService.ts index 5b9b775c2..bfb83c7bb 100644 --- a/game-server/app/services/playerCeService.ts +++ b/game-server/app/services/playerCeService.ts @@ -5,7 +5,7 @@ import { pinus } from 'pinus'; import { STATUS } from '../consts/statusCode'; -import { resResult, reduceCe, calculatetopLineup } from '../pubUtils/util'; +import { resResult, reduceCe } from '../pubUtils/util'; import { HeroModel, HeroType, HeroUpdate } from '../db/Hero'; import { RoleUpdate, RoleType, RoleModel } from '../db/Role'; @@ -18,8 +18,11 @@ import { RoleCeModel } from '../db/RoleCe'; import { PvpDefenseModel } from '../db/PvpDefense'; import { saveCeChangeLog } from '../pubUtils/logUtil'; import { JewelType } from '../db/Jewel'; +import { SchoolModel } from '../db/School'; +import { HasJustId } from 'mongoose'; interface Param { + isInitRole?: boolean, hid?: number, hero?: HeroType, isUpStar?: boolean, @@ -37,56 +40,135 @@ interface Param { skinId?: number, } -export async function calculateCe(type: HERO_SYSTEM_TYPE, roleId: string, serverId: number, sid: string, heroUpdate: HeroUpdate, roleUpdate: RoleUpdate, param: Param) { +export async function calculateCeWithHero(type: HERO_SYSTEM_TYPE, roleId: string, serverId: number, sid: string, hid: number, heroUpdate: HeroUpdate, param: Param = {}) { + let heroUpdates = new Map(); + heroUpdates.set(hid, heroUpdate); + let { heroes, curRole } = await calculateCes(type, roleId, serverId, sid, heroUpdates, {}, {}, param); + let curHero = heroes.find(cur => cur.hid == hid); + return { heroes, curHero, curRole } +} + +export async function calculateWithRole(type: HERO_SYSTEM_TYPE, roleId: string, serverId: number, sid: string, roleUpdate: RoleUpdate, param: Param = {}) { + let { heroes, curRole } = await calculateCes(type, roleId, serverId, sid, new Map(), roleUpdate, {}, param); + return { heroes, curRole }; +} + +export async function calculateCes(type: HERO_SYSTEM_TYPE, roleId: string, serverId: number, sid: string, heroUpdates: Map, roleUpdate: RoleUpdate, roleIncUpdate: RoleUpdate, param: Param = {}) { let calCe = new CalCe(); let roleCe = await RoleCeModel.findByRoleId(roleId); calCe.setRoleCe(roleCe); switch (type) { - case HERO_SYSTEM_TYPE.LVUP: // 升级 + case HERO_SYSTEM_TYPE.INIT: { - calCe.setHeroLv(param.hid, heroUpdate.lv); + for(let [hid, { skinId, lv, quality, star, starStage, colorStar, colorStarStage, job, jobStage, }] of heroUpdates) { + calCe.setHeroBase(hid, skinId); + calCe.setHeroLv(hid, lv); + calCe.setHeroStar(hid, job, quality, star, starStage, colorStar, colorStarStage); + calCe.setJob(hid, job, jobStage); + } + if(param.isInitRole) { + let { title, teraphs } = roleUpdate; + calCe.setTitle(title); + calCe.setTeraph(teraphs); + } break; } - case HERO_SYSTEM_TYPE.STAR: // 升星 + case HERO_SYSTEM_TYPE.LVUP: // 1. 升级 { - let { star, starStage, colorStar, colorStarStage } = heroUpdate; - let { hid, hero: { quality, job } } = param; - calCe.setHeroStar(hid, job, quality, star, starStage, colorStar, colorStarStage); + for(let [hid, { lv }] of heroUpdates) { + calCe.setHeroLv(hid, lv); + } + break; + } + case HERO_SYSTEM_TYPE.STAR: // 2. 升星 + { + for(let [hid, { star, starStage }] of heroUpdates) { + let { hero: { quality, job, colorStar, colorStarStage }, isUpStar } = param; + await treatHeroStar(calCe, roleId, hid, star, starStage, quality, colorStar, colorStarStage, job, isUpStar); + } + break; + } + case HERO_SYSTEM_TYPE.QUALITY: // 3. 升品 + { + for(let [hid, { quality }] of heroUpdates) { + let { hero: { star, starStage, colorStar, colorStarStage, job } } = param; + await treatHeroStar(calCe, roleId, hid, star, starStage, quality, colorStar, colorStarStage, job, true); + } + break; + } + case HERO_SYSTEM_TYPE.COLORSTAR: // 4. 觉醒 + { + for(let [hid, { colorStar, colorStarStage }] of heroUpdates) { + let { hero: { star, starStage, quality, job }, isUpStar } = param; + await treatHeroStar(calCe, roleId, hid, star, starStage, quality, colorStar, colorStarStage, job, isUpStar); + } + break; + } + case HERO_SYSTEM_TYPE.SCHOOL: // 放百家学宫 + { + let { schoolId, schoolHid, preSchoolHid, hero } = param; + if(preSchoolHid) { + calCe.setSchool(false, preSchoolHid, schoolId, 0, 0, 0); + } + if(schoolHid) { + let { star, colorStar, quality } = hero; + calCe.setSchool(true, schoolHid, schoolId, star, colorStar, quality); + } break; } } let { heroCe, roleInc } = calCe.getCeInc(); // 计算战力,获得有变化的武将战力 + let changeHids: number[] = []; let pushHeros = new Array<{ hid: number, ce: number, incHeroCe: number }>(); - let heroes: HeroType[] = [], curHero: HeroType; - for(let [ hid, { ce, inc } ] of heroCe) { - let hero: HeroType; - if(hid == param.hid) { // 更新的那一个武将 - hero = await HeroModel.updateHeroInfo(roleId, hid, { ...heroUpdate, ce }); - curHero = hero; - } else { // 由于百家学宫等问题牵扯到的其他武将 - hero = await HeroModel.updateHeroInfo(roleId, hid, { ce }); + let heroes: HeroType[] = []; + + for(let [hid, heroUpdate] of heroUpdates) { + if(heroCe.has(hid)) { + let { ce, inc } = heroCe.get(hid); + let heroUpdate = heroUpdates.get(hid)||{}; + let hero = await HeroModel.updateHeroInfo(roleId, hid, { ...heroUpdate, ce }); + calCe.setResultHero(hero); + heroes.push(hero); + await PvpDefenseModel.updateCe(roleId, hid, inc); // 更新pvp防守阵战力 + pushHeros.push({ hid, ce, incHeroCe: inc }); + changeHids.push(hid); + } else { + let hero = await HeroModel.updateHeroInfo(roleId, param.hid, heroUpdate); + heroes.push(hero); } - calCe.setResultHero(hero); - heroes.push(hero); - await PvpDefenseModel.updateCe(roleId, hid, inc); // 更新pvp防守阵战力 - pushHeros.push({ hid, ce, incHeroCe: inc }) } - if(!heroCe.has(param.hid)) { - curHero = await HeroModel.updateHeroInfo(roleId, param.hid, heroUpdate); + for(let [hid, { ce, inc }] of heroCe) { + if(changeHids.indexOf(hid) == -1) { + let hero = await HeroModel.updateHeroInfo(roleId, hid, { ce }); + pushHeros.push({ hid, ce: hero.ce, incHeroCe: inc }); + changeHids.push(hid); + } } + let { topLineup, topLineupCe } = calCe.getTopLineup(); - let role = await RoleModel.incRoleInfo(roleId, { ce: roleInc }, { ...roleUpdate, topLineup, topLineupCe }); + let roleCeUpdate = calCe.getRoleCeTable(); + roleCe = await RoleCeModel.updateRoleCe(roleId, roleCeUpdate); + let role = await RoleModel.incRoleInfo(roleId, { ...roleIncUpdate, ce: roleInc }, { ...roleUpdate, topLineup, topLineupCe }); let guild = await GuildModel.updateCe(roleId, roleInc); // 公会更新战力 - saveCeChangeLog(role, roleInc, role.ce, type, [...heroCe.keys()]); + saveCeChangeLog(role, roleInc, role.ce, type, changeHids); updateRank(roleId, serverId, topLineupCe, role, pushHeros, guild); let uids = [{ uid: roleId, sid }]; pinus.app.get('channelService').pushMessageByUids('onPlayerCeUpdate', resResult(STATUS.SUCCESS, { ce: role.ce, heros: pushHeros, topLineupCe }), uids); + if(guild) { await updateUserInfo(REDIS_KEY.GUILD_INFO, guild.code, [{ field: 'guildCe', value: guild.guildCe }]); } - return { heroes, curHero, curRole: role } + return { heroes, curRole: role } +} + +async function treatHeroStar(calCe: CalCe, roleId: string, hid: number, star: number, starStage: number, quality: number, colorStar: number, colorStarStage: number, job: number, isUpStar: boolean) { + calCe.setHeroStar(hid, job, quality, star, starStage, colorStar, colorStarStage); + if(isUpStar) { + let school = await SchoolModel.findByHid(roleId, hid); + if(school) calCe.setSchool(true, hid, school.schoolId, star, colorStar, quality); + } } // 更新排行榜数据 diff --git a/game-server/app/services/role/calCe.ts b/game-server/app/services/role/calCe.ts index 826f85d18..04bf89412 100644 --- a/game-server/app/services/role/calCe.ts +++ b/game-server/app/services/role/calCe.ts @@ -1,10 +1,10 @@ import { ABI_STAGE, ABI_STAGE_TO_TYPE, ABI_TYPE_MAIN, LINEUP_NUM, SEID_TYPE } from "../../consts"; import { HeroType, HeroUpdate } from "../../db/Hero"; import { RoleUpdate, Teraph } from "../../db/Role"; -import { AttrCell, EquipAttr, HeroAttr, RoleCeType } from "../../db/RoleCe"; +import { AttrCell, EquipAttr, HeroAttr, RoleCeType, SchoolAttr } from "../../db/RoleCe"; import { TopHero } from "../../domain/dbGeneral"; import { AttributeCal } from "../../domain/roleField/attribute"; -import { gameData, getHeroStarByQuality, getHeroWakeByQuality, getTeraph } from "../../pubUtils/data"; +import { gameData, getHeroStarByQuality, getHeroWakeByQuality, getSchoolRateByStar, getTeraph } from "../../pubUtils/data"; import { DicRandomEffectPool } from "../../pubUtils/dictionary/DicRandomEffectPool"; import { DicSe } from "../../pubUtils/dictionary/DicSe"; import { addToMap, deepCopy } from "../../pubUtils/util"; @@ -23,6 +23,8 @@ export class CalCe { equipLv: Map = new Map(); // hid+eplaceId => lv originCes: Map = new Map(); // hid => ce resultCes: Map = new Map(); // hid => ce + schoolAttrs: Map = new Map(); // hid + attr => ratio + schoolAttrsByAttrId: Map = new Map(); // attrId => hid + attr private getGlobalAttrById(attrId: number) { if(!this.globalAttrs.has(attrId)) { @@ -39,6 +41,7 @@ export class CalCe { private getHeroAttrByHidAndId(hid: number, attrId: number) { let key = `${hid}_${attrId}`; + console.log('$$$$$$$$ getHeroAttrByHidAndId', hid, attrId) if(!this.heroAttrs.has(key)) { if(ABI_TYPE_MAIN.indexOf(attrId) != -1) { let obj = new HeroMainAttr(hid, attrId); @@ -53,6 +56,7 @@ export class CalCe { } this.heroAttrsByHid.get(hid).push(key); } + console.log('$$$$$$$$ heroAttrsByHid', this.heroAttrsByHid) return this.heroAttrs.get(key); } @@ -80,6 +84,30 @@ export class CalCe { return this.equipAttrs.get(key); } + private setSchoolRate(hid: number, attrId: number, value: number) { + let key = `${hid}_${attrId}`; + if(!this.schoolAttrs.has(key)) { + this.schoolAttrs.set(key, { hid, attrId, ce: value }); + if(!this.schoolAttrsByAttrId.has(attrId)) { + this.schoolAttrsByAttrId.set(attrId, []); + } + this.schoolAttrsByAttrId.get(attrId).push(key); + } else { + this.schoolAttrs.get(key).ce = value; + } + } + + private calSchoolAttrsToGlobal(attrId: number) { + let keys = this.schoolAttrsByAttrId.get(attrId)||[]; + let schoolResult = 0; + for(let key of keys) { + let { ce } = this.schoolAttrs.get(key); + schoolResult += ce; + } + let globalAttr = this.getGlobalAttrById(attrId); + globalAttr.school = schoolResult; + } + public calHeroCe() { let ces = new Map(); // hid => [{attrId, val}] for(let [hid, keys] of this.heroAttrsByHid) { @@ -98,17 +126,20 @@ export class CalCe { ces.get(hid).push({ id: attrId, val }); } } + let result = new Map(); for(let [hid, arr] of ces) { let obj = new AttributeCal(); obj.setByWarJson(arr); let ce = obj.calCe(); this.resultCes.set(hid, ce); + result.set(hid, ce); } - return this.resultCes; + return result; } public getCeInc() { let ceResult = this.calHeroCe(); + console.log('##### ceResult', ceResult, 'originCes', this.originCes) let heroCe = new Map(); let roleInc = 0; for(let [hid, ce] of ceResult) { @@ -137,7 +168,7 @@ export class CalCe { let heroAttrs: HeroAttr[] = []; for(let [hid, keys] of this.heroAttrsByHid) { let lv = this.heroLv.get(hid); - let historyCe = this.heroHistoryCe.get(hid); + let historyCe = this.heroHistoryCe.get(hid)||0; let objectId = this.heroObjectId.get(hid); let attrs: AttrCell[] = []; for(let key of keys) { @@ -160,12 +191,18 @@ export class CalCe { hid, eplaceId, lv, attrs }); } + let schoolAttrs: SchoolAttr[] = []; + for(let [_, { hid, attrId, ce }] of this.schoolAttrs) { + schoolAttrs.push({ hid, attrId, value: ce }); + } return { - roleId: this.roleId, globalAttrs, heroAttrs, equipAttrs + roleId: this.roleId, globalAttrs, heroAttrs, equipAttrs, schoolAttrs } } public setRoleCe(roleCe: RoleCeType) { + console.log('&&&&&&&& setRoleCe', roleCe) + this.roleId = roleCe.roleId; if(roleCe) { for(let globalAttr of roleCe.globalAttrs) { @@ -188,23 +225,14 @@ export class CalCe { obj.setByRoleCe(cell); } } + for(let { hid, attrId, value } of roleCe.schoolAttrs) { + this.setSchoolRate(hid, attrId, value); + } } this.originCes = this.calHeroCe(); + console.log('############ setRoleCe', this.originCes) } - public setInitHero(role: RoleUpdate, heroes: HeroUpdate[]) { - this.roleId = role.roleId; - for(let { hid, skinId, lv, quality, star, starStage, colorStar, colorStarStage, job, jobStage, } of heroes) { - this.setHeroBase(hid, skinId); - this.setHeroLv(hid, lv); - this.setHeroStar(hid, job, quality, star, starStage, colorStar, colorStarStage); - this.setJob(hid, job, jobStage); - } - this.setTitle(role.title); - this.setTeraph(role.teraphs); - } - - public setResultHero(hero: HeroType) { this.heroObjectId.set(hero.hid, hero._id); } @@ -267,7 +295,6 @@ export class CalCe { let heroAttr = this.getHeroAttrByHidAndId(hid, attrId); heroAttr.starUp = value; }; - } // 职业基础 @@ -313,6 +340,23 @@ export class CalCe { } } + // 百家学宫 + public setSchool(isPutOn: boolean, hid: number, schoolId: number, star: number, colorStar: number, quality: number) { + + let dicSchool = gameData.school.get(schoolId); + let dicSchoolRate = getSchoolRateByStar(star, colorStar, quality); + console.log('#### setSchool', star, colorStar, quality, dicSchoolRate) + + for (let attrId of dicSchool.upAttribute) { + if(ABI_TYPE_MAIN.includes(attrId)) { // 主属性 + this.setSchoolRate(hid, attrId, isPutOn?dicSchoolRate.mainAttrAPerent: 0); + } else { + this.setSchoolRate(hid, attrId, isPutOn?dicSchoolRate.assiAttrAddValue: 0); + } + this.calSchoolAttrsToGlobal(attrId); + } + } + // 添加技能增加的被动属性 private addSeidEffect(seidList: number[]) { let fixUp = new Map(), ratioUp = new Map(); @@ -383,9 +427,10 @@ abstract class GlobalAllAttr { abstract getValues(): number[]; public getGlobalAttr() { + let values = this.getValues().map(cur => (cur||0)); return { attrId: this.attrId, - values: this.getValues() + values } } } @@ -417,19 +462,19 @@ class GlobalMainAttr extends GlobalAllAttr { for(let i = GLOBAL_MAIN_ATTR_INDEX.START; i < GLOBAL_MAIN_ATTR_INDEX.END; i++) { switch(i) { case GLOBAL_MAIN_ATTR_INDEX.SCHOOL: - if(this.school) values[i] = this.school; + values.push(this.school); break; case GLOBAL_MAIN_ATTR_INDEX.TERAPH: - if(this.teraph) values[i] = this.teraph; + values.push(this.teraph); break; case GLOBAL_MAIN_ATTR_INDEX.TITLE: - if(this.title) values[i] = this.title; + values.push(this.title); break; case GLOBAL_MAIN_ATTR_INDEX.SCROLL: - if(this.scroll) values[i] = this.scroll; + values.push(this.scroll); break; case GLOBAL_MAIN_ATTR_INDEX.SKIN: - if(this.skin) values[i] = this.skin; + values.push(this.skin); break; } } @@ -462,16 +507,16 @@ class GlobalSubAttr extends GlobalAllAttr { for(let i = GLOBAL_MAIN_ATTR_INDEX.START; i < GLOBAL_MAIN_ATTR_INDEX.END; i++) { switch(i) { case GLOBAL_MAIN_ATTR_INDEX.SCHOOL: - if(this.school) values[i] = this.school; + values.push(this.school); break; case GLOBAL_MAIN_ATTR_INDEX.TERAPH: - if(this.teraph) values[i] = this.teraph; + values.push(this.teraph); break; case GLOBAL_MAIN_ATTR_INDEX.TITLE: - if(this.title) values[i] = this.title; + values.push(this.title); break; case GLOBAL_MAIN_ATTR_INDEX.SKIN: - if(this.skin) values[i] = this.skin; + values.push(this.skin); break; } } @@ -543,31 +588,31 @@ class HeroMainAttr extends HeroAllAttr { for(let i = HERO_MAIN_ATTR_INDEX.START; i < HERO_MAIN_ATTR_INDEX.END; i++) { switch(i) { case HERO_MAIN_ATTR_INDEX.BASE: - if(this.base) values[i] = this.base; + values.push(this.base); break; case HERO_MAIN_ATTR_INDEX.JOB: - if(this.job) values[i] = this.job; + values.push(this.job); break; case HERO_MAIN_ATTR_INDEX.STAR_UP: - if(this.starUp) values[i] = this.starUp; + values.push(this.starUp); break; case HERO_MAIN_ATTR_INDEX.CONNECT: - if(this.connect) values[i] = this.connect; + values.push(this.connect); break; case HERO_MAIN_ATTR_INDEX.FAVOUR: - if(this.favour) values[i] = this.favour; + values.push(this.favour); break; case HERO_MAIN_ATTR_INDEX.TALENT: - if(this.talent) values[i] = this.talent; + values.push(this.talent); break; case HERO_MAIN_ATTR_INDEX.EQUIP: - if(this.equip) values[i] = this.equip; + values.push(this.equip); break; case HERO_MAIN_ATTR_INDEX.EQUIP_UP: - if(this.equipUp) values[i] = this.equipUp; + values.push(this.equipUp); break; case HERO_MAIN_ATTR_INDEX.EQUIP_STONE: - if(this.equipStone) values[i] = this.equipStone; + values.push(this.equipStone); break; } } @@ -599,16 +644,16 @@ class HeroSubAttr extends HeroAllAttr { for(let i = HERO_SUB_ATTR_INDEX.START; i < HERO_SUB_ATTR_INDEX.END; i++) { switch(i) { case HERO_SUB_ATTR_INDEX.BASE: - if(this.base) values[i] = this.base; + values.push(this.base); break; case HERO_SUB_ATTR_INDEX.JOB: - if(this.job) values[i] = this.job; + values.push(this.job); break; case HERO_SUB_ATTR_INDEX.TALENT: - if(this.talent) values[i] = this.talent; + values.push(this.talent); break; case HERO_SUB_ATTR_INDEX.EQUIP: - if(this.equip) values[i] = this.equip; + values.push(this.equip); break; } } @@ -672,22 +717,22 @@ class EquipMainAttr extends EquipAllAttr { for(let i = EQUIP_MAIN_ATTR_INDEX.START; i < EQUIP_MAIN_ATTR_INDEX.END; i++) { switch(i) { case EQUIP_MAIN_ATTR_INDEX.EQUIP_QUALITY: - if(this.equipQuality) values[i] = this.equipQuality; + values.push(this.equipQuality); break; case EQUIP_MAIN_ATTR_INDEX.EQUIP_STRENGTH: - if(this.equipStrengthen) values[i] = this.equipStrengthen; + values.push(this.equipStrengthen); break; case EQUIP_MAIN_ATTR_INDEX.EQUIP_STAR: - if(this.equipStar) values[i] = this.equipStar; + values.push(this.equipStar); break; case EQUIP_MAIN_ATTR_INDEX.EQUIP_SUIT: - if(this.equipSuit) values[i] = this.equipSuit; + values.push(this.equipSuit); break; case EQUIP_MAIN_ATTR_INDEX.JEWEL: - if(this.jewel) values[i] = this.jewel; + values.push(this.jewel); break; case EQUIP_MAIN_ATTR_INDEX.STONE: - if(this.stone) values[i] = this.stone; + values.push(this.stone); break; } } @@ -715,10 +760,10 @@ class EquipSubAttr extends EquipAllAttr { for(let i = EQUIP_SUB_ATTR_INDEX.START; i < EQUIP_SUB_ATTR_INDEX.END; i++) { switch(i) { case EQUIP_SUB_ATTR_INDEX.EQUIP_STAR: - if(this.equipStar) values[i] = this.equipStar; + values.push(this.equipStar); break; case EQUIP_SUB_ATTR_INDEX.JEWEL: - if(this.jewel) values[i] = this.jewel; + values.push(this.jewel); break; } } diff --git a/game-server/app/services/role/createHero.ts b/game-server/app/services/role/createHero.ts index 1fef3f2af..83b651f04 100644 --- a/game-server/app/services/role/createHero.ts +++ b/game-server/app/services/role/createHero.ts @@ -1,188 +1,19 @@ -import { FIGURE_UNLOCK_CONDITION, ITEM_CHANGE_REASON, REDIS_KEY, STATUS, TASK_TYPE, HERO_SYSTEM_TYPE, LINEUP_NUM } from "../../consts"; +import { FIGURE_UNLOCK_CONDITION, ITEM_CHANGE_REASON, REDIS_KEY, STATUS, TASK_TYPE, HERO_SYSTEM_TYPE, LINEUP_NUM, COUNTER } from "../../consts"; import { SkinModel } from "../../db/Skin"; import { HeroModel, HeroSkin, HeroType, HeroUpdate } from "../../db/Hero"; -import { RoleModel, RoleType, RoleUpdate } from "../../db/Role"; import { SkinUpdate } from "../../db/Skin"; -import { Figure, TopHero } from "../../domain/dbGeneral"; -import { TaskListReturn } from "../../domain/roleField/task"; -import { GuildModel, GuildType } from "../../db/Guild"; -import { PvpDefenseModel } from "../../db/PvpDefense"; -import { pick } from "underscore"; -import { calculatetopLineup } from "../../pubUtils/util"; import { nowSeconds } from "../../pubUtils/timeUtil"; -import { saveCeChangeLog } from "../../pubUtils/logUtil"; import { getRandSingleEelm, reduceCe, resResult } from "../../pubUtils/util"; -import { AttributeCal } from "../../domain/roleField/attribute"; import { CreateHeroParam, HeroParam, HeroShowParam } from "../../domain/roleField/hero"; import { pinus } from "pinus"; import { Rank } from "../rankService"; import { checkTaskInCreateHero } from "../task/taskService"; import { ItemInter, RewardInter } from "../../pubUtils/interface"; import { transPiece } from "./util"; -import { getInitHeroById } from "../roleService"; -import { addItems, combineFigureInfo, unlockFigure, unlockFigureWithoutSave } from "./rewardService"; -import { gameData } from "../../pubUtils/data"; -import { CalCe } from "./calCe"; -import RoleCe, { RoleCeModel, RoleCeUpdate } from "../../db/RoleCe"; - -export class CreateHeroes { - private roleId: string; - private roleName: string; - private serverId: number; - private incHeroNum: number = 0; - private incRoleCe: number = 0; - private role: RoleType; - private guild: GuildType; - - // 推送信息 - private figureConditions: { type: FIGURE_UNLOCK_CONDITION, paramHid: number }[] = []; - private skins: SkinUpdate[] = []; - private heroes: HeroUpdate[] = []; - private roleCe: RoleCeUpdate = {}; - private resultHeroes: HeroType[] = []; - private topLineup: TopHero[] = []; - private topLineupCe: number = 0; - - constructor(roleId: string, roleName: string, serverId: number) { - this.roleId = roleId; - this.roleName = roleName; - this.serverId = serverId; - } - - public setRole(role: RoleType) { - this.role = role; - } - - public async getRole() { - if(!this.role) { - this.role = await RoleModel.findByRoleId(this.roleId); - this.topLineup = this.role.topLineup; - this.topLineupCe = this.role.topLineupCe; - } - return this.role; - } - - public async createHeroes(hids: number[]) { - let { roleId, roleName } = this; - for(let hid of hids) { - let initSkin = SkinModel.getInitInfo(hid); - let initHero = HeroModel.getInitInfo(hid, { roleId, roleName, skins: [new HeroSkin(initSkin)] }); - this.heroes.push(initHero); - this.skins.push(initSkin); - this.figureConditions.push({ type: FIGURE_UNLOCK_CONDITION.GET_HERO, paramHid: hid }); - this.incHeroNum ++; - } - await this.calCe(); // 计算战力 - await this.saveCeToDb(); - } - - private async calCe() { - let role = await this.getRole(); - let calCe = new CalCe(); - calCe.setInitHero(role, this.heroes); // 设置武将初始信息 - let ces = calCe.calHeroCe(); // 战力 - for(let hero of this.heroes) { - hero.ce = ces.get(hero.hid)||0; - this.incRoleCe += hero.ce; - } - this.roleCe = calCe.getRoleCeTable(); - } - - // 更新战力相关的各个表 - private async saveCeToDb() { - let role = await this.getRole(); - // 更新武将表 - for(let hero of this.heroes) { - let resultHero = await HeroModel.createHero(hero); - this.resultHeroes.push(resultHero); - await calculatetopLineup(role, resultHero.hid, resultHero.ce, resultHero._id); - } - this.heroes = []; - // 更新role表 - role = await RoleModel.incRoleInfo(this.roleId, { heroNum: this.incHeroNum, ce: this.incRoleCe }, { heroNumUpdatedAt: nowSeconds(), }); - this.setRole(role); - // 更新roleCe表 - await RoleCeModel.updateRoleCe(this.roleId, this.roleCe); - // 更新皮肤表 - await SkinModel.insertSkins(this.roleId, this.roleName, this.skins) - // 更新guild表 - if(role.hasGuild) { - this.guild = await GuildModel.updateCe(this.roleId, this.incRoleCe, true); // 公会更新战力 - } - for(let { hid, ce } of this.resultHeroes) { - await PvpDefenseModel.updateCe(this.roleId, hid, ce); // 更新pvp防守阵战力 - } - saveCeChangeLog(role, this.incRoleCe, role.ce, HERO_SYSTEM_TYPE.INIT, this.resultHeroes.map(cur => cur.hid)); - } - - public async updateRedisRank() { - let { serverId, roleId, resultHeroes, role } = this; - // 更新军团信息 - if(this.guild) { - let r = new Rank(REDIS_KEY.GUILD_INFO, { guildCode: this.guild.code }); - await r.generParamAndSet(REDIS_KEY.GUILD_INFO, { guildCode: this.guild.code }, { guild: this.guild }); - } - // 武将数量 - if(this.incHeroNum > 0) { - let r = new Rank(REDIS_KEY.HERO_NUM_RANK, { serverId }); - await r.setRankWithRoleInfo(roleId, role.heroNum, role.heroNumUpdatedAt, role); - } - - // 最强阵容 - let r = new Rank(REDIS_KEY.TOP_LINEUP_RANK, { serverId }); - await r.setRankWithRoleInfo(roleId, reduceCe(role.topLineupCe), 0, role); - - // 最强武将 - for(let hero of resultHeroes) { - let r2 = new Rank(REDIS_KEY.TOP_HERO_RANK, { serverId }); - await r2.setRankWithHeroInfo(roleId, hero.hid, hero.ce, 0, hero); - - let r4 = new Rank(REDIS_KEY.HERO_RANK, { serverId, hid: hero.hid }); - await r4.setRankWithHeroInfo(roleId, hero.hid, hero.ce, 0, hero); - } - // 总战力 - let r3 = new Rank(REDIS_KEY.SUM_CE_RANK, { serverId }); - await r3.setRankWithRoleInfo(roleId, reduceCe(role.ce), 0, role); - - // 更新最强五人阵容信息 - let r5 = new Rank(REDIS_KEY.TOP_LINEUP_INFO, { serverId }); - await r5.generParamAndSet(REDIS_KEY.TOP_LINEUP_INFO, { roleId }, { role }); - } - - public async pushMessage(sid: string) { - let role = await this.getRole(); - let uids = [{ uid: this.roleId, sid }]; - pinus.app.get('channelService').pushMessageByUids('onPlayerCeUpdate', resResult(STATUS.SUCCESS, { ce: role.ce, heros: this.resultHeroes.map(({ hid, ce }) => ({ hid, ce, incHeroCe: ce})), topLineupCe: role.topLineupCe}), uids); - - pinus.app.get('channelService').pushMessageByUids('onHeroSkinChange', resResult(STATUS.SUCCESS, this.getSkinPushMsg()), uids); - pinus.app.get('channelService').pushMessageByUids('onHeroUpdate', resResult(STATUS.SUCCESS, { heroes: this.getResultHeroes() }), uids); - checkTaskInCreateHero(this.serverId, this.roleId, sid, this.incHeroNum, this.resultHeroes); - await unlockFigure(sid, this.roleId, this.figureConditions); - } - - private getSkinPushMsg() { - let skinPushMessages: {heros: {skins: HeroSkin[], hid: number}[], skins: {id: number, hid: number, inc: number, reason: number }[]} = { heros: [], skins:[] }; // 皮肤推送信息 - for(let { hid, skins } of this.resultHeroes) { - skinPushMessages.heros.push({ hid, skins }); - } - for(let { id, hid } of this.skins) { - skinPushMessages.skins.push({ id, hid, inc: 1, reason: ITEM_CHANGE_REASON.GET_HERO_UNLOCK_SKIN }) - } - return skinPushMessages; - } - - public getResultHeroes() { - return this.resultHeroes; - } - - public getShowHeroes() { - return this.resultHeroes.map(cur => { - let hero = new HeroShowParam(cur); - return { ...hero, ce: reduceCe(cur.ce)} - }); - } -} - +import { addItems, combineFigureInfo, unlockFigure, } from "./rewardService"; +import { CounterModel } from "../../db/Counter"; +import { calculateCes } from "../playerCeService"; +import { RoleUpdate } from "../../db/Role"; /** * 创建多个武将 @@ -191,7 +22,7 @@ export class CreateHeroes { * @param serverId * @param heroInfo */ - export async function createHeroes(roleId: string, roleName: string, sid: string, serverId: number, heroInfo: CreateHeroParam[]) { + export async function createHeroes(roleId: string, roleName: string, sid: string, serverId: number, heroInfo: CreateHeroParam[], initRoleInfos?: RoleUpdate) { let hids = heroInfo.map(cur => cur.hid); let userHeroesMap = await HeroModel.findMapByHidRange(hids, roleId); @@ -211,24 +42,60 @@ export class CreateHeroes { } } - let resultHeroes: HeroType[] = [], resultItems: RewardInter[] = [], heroes: HeroShowParam[] = []; + let resultHeroes: HeroType[] = [], resultItems: RewardInter[] = [], showHeroes: HeroShowParam[] = []; + let figureConditions: { type: FIGURE_UNLOCK_CONDITION, paramHid: number }[] = []; + let incHeroNum = 0; + let skins: SkinUpdate[] = []; if (createHids.length > 0) { - let createHero = new CreateHeroes(roleId, roleName, serverId); - await createHero.createHeroes(createHids); - await createHero.pushMessage(sid); - await createHero.updateRedisRank(); - heroes = createHero.getShowHeroes(); - resultHeroes = createHero.getResultHeroes(); + let heroInfos = new Map(); + for(let hid of createHids) { + let initSkin = SkinModel.getInitInfo(hid); + skins.push(initSkin); // 初始皮肤 + let seqId = await CounterModel.getNewCounter(COUNTER.HID) || -1; + let initHero = HeroModel.getInitInfo(hid, { seqId, roleId, roleName, skins: [new HeroSkin(initSkin)] }); + heroInfos.set(hid, initHero); + figureConditions.push({ type: FIGURE_UNLOCK_CONDITION.GET_HERO, paramHid: hid }); + incHeroNum ++; + } + await unlockFigure(sid, roleId, figureConditions); + + let roleUpdata: RoleUpdate = { heroNumUpdatedAt: nowSeconds() }; + if(initRoleInfos) { + roleUpdata = { ...initRoleInfos, ...roleUpdata } + } + let { heroes } = await calculateCes(HERO_SYSTEM_TYPE.INIT, roleId, serverId, sid, heroInfos, roleUpdata, { heroNum: incHeroNum }); + for(let hero of heroes) { + showHeroes.push(new HeroShowParam(hero)); + resultHeroes.push(hero); + } + + let uids = [{ uid: roleId, sid }]; + await SkinModel.insertSkins(roleId, roleName, skins); + pinus.app.get('channelService').pushMessageByUids('onHeroSkinChange', resResult(STATUS.SUCCESS, getSkinPushMsg(resultHeroes, skins)), uids); + pinus.app.get('channelService').pushMessageByUids('onHeroUpdate', resResult(STATUS.SUCCESS, { heroes }), uids); + } if (pieces.length > 0) { let goods = await addItems(roleId, roleName, sid, pieces, ITEM_CHANGE_REASON.HERO_TRANSFER_PIECE); resultItems = goods; } - return { heroes, resultHeroes, goods: resultItems } + return { heroes: showHeroes, resultHeroes, goods: resultItems } } export async function createHero(roleId: string, roleName: string, sid: string, serverId: number, heroInfo: CreateHeroParam) { let result = await createHeroes(roleId, roleName, sid, serverId, [heroInfo]); return result; +} + + +function getSkinPushMsg(resultHeroes: HeroType[], skins: SkinUpdate[]) { + let skinPushMessages: {heros: {skins: HeroSkin[], hid: number}[], skins: {id: number, hid: number, inc: number, reason: number }[]} = { heros: [], skins:[] }; // 皮肤推送信息 + for(let { hid, skins } of resultHeroes) { + skinPushMessages.heros.push({ hid, skins }); + } + for(let { id, hid } of skins) { + skinPushMessages.skins.push({ id, hid, inc: 1, reason: ITEM_CHANGE_REASON.GET_HERO_UNLOCK_SKIN }) + } + return skinPushMessages; } \ No newline at end of file diff --git a/game-server/app/services/role/rewardService.ts b/game-server/app/services/role/rewardService.ts index adfaab0d6..099631081 100644 --- a/game-server/app/services/role/rewardService.ts +++ b/game-server/app/services/role/rewardService.ts @@ -22,11 +22,9 @@ import { reportTAEvent, reportTAUserSet } from '../sdkService'; import { saveCoinChangeLog, saveFigureInfoLog, saveGoldChangeLog, saveItemChangeLog } from '../../pubUtils/logUtil'; import { JewelModel, JewelType, jewelUpdate, RandSe } from '../../db/Jewel'; import { updateEplaces } from '../equipService'; -import { checkPopUpConditionInCreateHero } from '../activity/popUpShopService'; -import { CreateHeroes } from './createHero'; import { combineItems, getCoinEventProperties, getGoldEventProperties, sortItems } from './util'; import { nowSeconds } from '../../pubUtils/timeUtil'; -import { calculateCe } from '../playerCeService'; +import { calculateCeWithHero } from '../playerCeService'; @@ -71,7 +69,7 @@ export async function handleCost(roleId: string, sid: string, goods: Array>(); for(let jewel of jewels) { @@ -82,7 +80,7 @@ export async function handleCost(roleId: string, sid: string, goods: Array cur.id == skinId); diff --git a/game-server/config/serverProtos.ts b/game-server/config/serverProtos.ts index 385a939cb..5834e862d 100644 --- a/game-server/config/serverProtos.ts +++ b/game-server/config/serverProtos.ts @@ -64,21 +64,21 @@ module.exports = { 'required uInt32 code': 2, 'required Data data': 3 }, - 'onPlayerCeUpdate': { - 'message Data': { - "message Hero": { - 'required uInt32 hid': 1, - 'required uInt32 ce': 2, - 'required sInt32 incHeroCe': 3, - }, - 'required sInt32 ce': 1, - 'repeated Hero heros': 2, - 'required uInt32 topLineupCe': 3 - }, - 'required string msg': 1, - 'required uInt32 code': 2, - 'required Data data': 3 - }, + // 'onPlayerCeUpdate': { + // 'message Data': { + // "message Hero": { + // 'required uInt32 hid': 1, + // 'required uInt32 ce': 2, + // 'required sInt32 incHeroCe': 3, + // }, + // 'required sInt32 ce': 1, + // 'repeated Hero heros': 2, + // 'required uInt32 topLineupCe': 3 + // }, + // 'required string msg': 1, + // 'required uInt32 code': 2, + // 'required Data data': 3 + // }, 'onPlayerDataChange': { 'message Data': { 'optional uInt32 coin': 1, diff --git a/shared/db/Hero.ts b/shared/db/Hero.ts index b3a4ba1ad..4bbbae9a0 100644 --- a/shared/db/Hero.ts +++ b/shared/db/Hero.ts @@ -281,22 +281,22 @@ export default class Hero extends BaseModel { return update } - public static async createHero(heroInfo: HeroUpdate, lean = true) { - const seqId = await CounterModel.getNewCounter(COUNTER.HID) || -1; - const update = this.getInitInfo(heroInfo.hid, { ...heroInfo, seqId }); - const hero: HeroType = await HeroModel.findOneAndUpdate({ roleId: heroInfo.roleId, hid: heroInfo.hid }, update, { upsert: true, new: true }).lean(lean); - return hero; - } + // public static async createHero(heroInfo: HeroUpdate, lean = true) { + // const seqId = await CounterModel.getNewCounter(COUNTER.HID) || -1; + // const update = this.getInitInfo(heroInfo.hid, { ...heroInfo, seqId }); + // const hero: HeroType = await HeroModel.findOneAndUpdate({ roleId: heroInfo.roleId, hid: heroInfo.hid }, update, { upsert: true, new: true }).lean(lean); + // return hero; + // } - public static async insertHeroes(roleId: string, roleName: string, serverId: number, heroInfos: HeroUpdate[]) { - let insertInfos: HeroUpdate[] = []; - for(let hero of heroInfos) { - const seqId = await CounterModel.getNewCounter(COUNTER.HID) || -1; - insertInfos.push({ ...hero, seqId, roleId, roleName, serverId }) - } - await HeroModel.insertMany(insertInfos); - return insertInfos; - } + // public static async insertHeroes(roleId: string, roleName: string, serverId: number, heroInfos: HeroUpdate[]) { + // let insertInfos: HeroUpdate[] = []; + // for(let hero of heroInfos) { + // const seqId = await CounterModel.getNewCounter(COUNTER.HID) || -1; + // insertInfos.push({ ...hero, seqId, roleId, roleName, serverId }) + // } + // await HeroModel.insertMany(insertInfos); + // return insertInfos; + // } public static async sumHeroCe(roleId: string) { let ce: Array<{ ce: number }> = await HeroModel.aggregate([ @@ -323,7 +323,7 @@ export default class Hero extends BaseModel { public static async updateHeroInfo(roleId: string, hid: number, heroUpdate: HeroUpdate, select?: string, getters = false) { delete heroUpdate._id; - let result: HeroType = await HeroModel.findOneAndUpdate({ roleId, hid }, { $set: heroUpdate }, { new: true }).select(select).lean({ getters }); + let result: HeroType = await HeroModel.findOneAndUpdate({ roleId, hid }, { $set: heroUpdate }, { new: true, upsert: true }).select(select).lean({ getters }); return result; } diff --git a/shared/db/RoleCe.ts b/shared/db/RoleCe.ts index c137bcd57..59f1b627d 100644 --- a/shared/db/RoleCe.ts +++ b/shared/db/RoleCe.ts @@ -5,7 +5,7 @@ import { index, getModelForClass, prop, DocumentType } from '@typegoose/typegoos export class AttrCell { @prop({ required: true }) attrId: number; // 属性id - @prop({ required: true }) + @prop({ required: true, type: Number }) values: number[]; // 战力公式中的全局加成的数据,查表后的结果 } @@ -35,7 +35,7 @@ export class EquipAttr { } // 百家学宫加成 -class SchoolAttr { +export class SchoolAttr { @prop({ required: true }) hid: number; // 武将id @prop({ required: true }) @@ -76,13 +76,13 @@ export default class RoleCe extends BaseModel { equipAttrs: EquipAttr[] @prop({ required: true, type: SchoolAttr, _id: false }) - schoolAttr: SchoolAttr[]; + schoolAttrs: SchoolAttr[]; @prop({ required: true, type: ScrollAttr, _id: false }) scrollAttrs: ScrollAttr[]; public static async findByRoleId(roleId: string) { - let result: RoleCeType = await RoleCeModel.findOneAndUpdate({ roleId }).lean(); + let result: RoleCeType = await RoleCeModel.findOne({ roleId }).lean(); return result; } diff --git a/shared/pubUtils/playerCe.ts b/shared/pubUtils/playerCe.ts index cf605f469..2e6109a4a 100644 --- a/shared/pubUtils/playerCe.ts +++ b/shared/pubUtils/playerCe.ts @@ -4,7 +4,6 @@ import { HERO_SYSTEM_TYPE, ABI_TYPE, HERO_CE_RATIO, LINEUP_NUM, TALENT_RELATION_TYPE } from '../consts'; -import { cal, calculatetopLineup, 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'; diff --git a/shared/pubUtils/util.ts b/shared/pubUtils/util.ts index 88746426b..1b1d77ecf 100644 --- a/shared/pubUtils/util.ts +++ b/shared/pubUtils/util.ts @@ -788,50 +788,50 @@ export function addToMap(map: Map, id: T, value: number) { } } -/** - * 计算最强阵容战力 - * @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; - } - } - } - } +// /** +// * 计算最强阵容战力 +// * @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); +// let topLineupCe = topLineup.reduce((pre, cur) => { +// return pre + cur.ce +// }, 0); - return { topLineup, topLineupCe }; -} +// return { topLineup, topLineupCe }; +// } From 1ccb66e3ebd1dce792a71e5a525e157ac4f333ca Mon Sep 17 00:00:00 2001 From: luying Date: Mon, 28 Mar 2022 20:28:47 +0800 Subject: [PATCH 05/12] =?UTF-8?q?=E6=88=98=E5=8A=9B=EF=BC=9A=E6=93=8D?= =?UTF-8?q?=E4=BD=9C=E7=BB=86=E8=8A=82?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../app/servers/role/handler/heroHandler.ts | 20 +-- .../app/servers/role/handler/roleHandler.ts | 22 +-- game-server/app/services/playerCeService.ts | 100 +++++++++++- game-server/app/services/role/calCe.ts | 152 ++++++++++++++++-- .../app/services/role/rewardService.ts | 4 +- shared/consts/constModules/heroConst.ts | 10 +- shared/pubUtils/dictionary/DicJob.ts | 22 ++- 7 files changed, 267 insertions(+), 63 deletions(-) diff --git a/game-server/app/servers/role/handler/heroHandler.ts b/game-server/app/servers/role/handler/heroHandler.ts index 5a8bbfb0a..adfe95257 100644 --- a/game-server/app/servers/role/handler/heroHandler.ts +++ b/game-server/app/servers/role/handler/heroHandler.ts @@ -348,6 +348,7 @@ export class HeroHandler { //重算战力并下发 let update = { + job: hero.job, jobStage: newJobStage, consumes: addConsumeToHero(hero.consumes, consumes) } @@ -442,7 +443,7 @@ export class HeroHandler { consumes: addConsumeToHero(hero.consumes, consumes) } //重算战力并下发 - let { curHero } = await calculateCeWithHero(HERO_SYSTEM_TYPE.CONNECT, roleId, serverId, sid, hero.hid, update, { shipId }); + let { curHero } = await calculateCeWithHero(HERO_SYSTEM_TYPE.CONNECT, roleId, serverId, sid, hero.hid, update, { shipId, hero }); // 任务 await checkTask(serverId, roleId, sid, TASK_TYPE.HERO_CONNECT, { connectLv: level }) return resResult(STATUS.SUCCESS, { curHero: pick(curHero, ['hid', 'connections']) }); @@ -519,17 +520,8 @@ export class HeroHandler { } let isFavourLvUp = oldLv == newLv; - // //重算战力并下发 - // if (oldLv != newLv) { - // await unlockFigure(sid, roleId, [{ type: FIGURE_UNLOCK_CONDITION.HERO_FAVOR, paramHid: hero.hid, paramFavourLv: hero.favourLv }]); - // hero = await calPlayerCeAndSave(HERO_SYSTEM_TYPE.FAVOUR, sid, roleId, hero, update, [oldLv]); - // // 任务 - // await checkTask(serverId, roleId, sid, TASK_TYPE.HERO_FAVOUR_LV, { hero, oldFavourLv: oldLv }); - // } else { - // hero = await HeroModel.updateHeroInfo(roleId, hero.hid, update); - // } - let { curHero } = await calculateCeWithHero(HERO_SYSTEM_TYPE.FAVOUR, roleId, serverId, sid, hero.hid, update, { isFavourLvUp }); + let { curHero } = await calculateCeWithHero(HERO_SYSTEM_TYPE.FAVOUR, roleId, serverId, sid, hero.hid, update, { isFavourLvUp, hero }); if(isFavourLvUp) { await unlockFigure(sid, roleId, [{ type: FIGURE_UNLOCK_CONDITION.HERO_FAVOR, paramHid: curHero.hid, paramFavourLv: curHero.favourLv }]); await checkTask(serverId, roleId, sid, TASK_TYPE.HERO_FAVOUR_LV, { hero: curHero, oldFavourLv: oldLv }); // 任务 @@ -639,10 +631,6 @@ export class HeroHandler { scrollColorStar: scrollActive? dicHeroScroll.colorstars: 0, }); - let calHeroCe = new CalHeroCe(hid, initInfo); - let heroAttr = calHeroCe.cal(HERO_SYSTEM_TYPE.REBIRTH); - // await HeroModel.updateHeroInfo(roleId, hid, { ...initInfo, attr: heroAttr }); - // 天晶石 let curJewels: jewelUpdate[] = []; for(let { jewel, id } of hero.ePlace) { @@ -656,7 +644,7 @@ export class HeroHandler { } } - let { curHero } = await calculateCeWithHero(HERO_SYSTEM_TYPE.REBIRTH, roleId, serverId, sid, hid, {...initInfo, attr: heroAttr}); + let { curHero } = await calculateCeWithHero(HERO_SYSTEM_TYPE.REBIRTH, roleId, serverId, sid, hid, initInfo, { }); let goods = await addItems(roleId, roleName, sid, consumes, ITEM_CHANGE_REASON.REBIRTH); const heroResult = new HeroParam(curHero); diff --git a/game-server/app/servers/role/handler/roleHandler.ts b/game-server/app/servers/role/handler/roleHandler.ts index 741e8ebe4..f4a38ced1 100644 --- a/game-server/app/servers/role/handler/roleHandler.ts +++ b/game-server/app/servers/role/handler/roleHandler.ts @@ -7,7 +7,7 @@ import { handleCost, addItems, getGoldObject, getCoinObject } from '../../../ser import { getTitle, getTeraph, gameData, getScollByStar, getFriendLvByExp, getHeroExpByLv, getExpByLv } from '../../../pubUtils/data'; import { SCHOOL, SCROLL, EXTERIOR, SCRIPT } from '../../../pubUtils/dicParam'; import { getAtrrNameById } from '../../../consts/constModules/abilityConst' -import { findIndex } from 'underscore'; +import { findIndex, pick } from 'underscore'; import { SclResultInter, SclPosInter } from '../../../pubUtils/interface'; import { SchoolModel } from '../../../db/School'; import { getTeraphStrengthenResult, getSchoolList } from '../../../services/roleService' @@ -285,13 +285,13 @@ export class RoleHandler { let { hid } = msg; - let curHero = await HeroModel.findByHidAndRole(hid, roleId, 'hid lv star colorStar quality scrollId scrollActive scrollStar scrollColorStar scrollQuality favour favourLv connections attr ce'); - if (!curHero) return resResult(STATUS.HERO_NOT_FIND); + let hero = await HeroModel.findByHidAndRole(hid, roleId, 'hid lv star colorStar quality scrollId scrollActive scrollStar scrollColorStar scrollQuality favour favourLv connections attr ce'); + if (!hero) return resResult(STATUS.HERO_NOT_FIND); let dicHero = gameData.hero.get(hid); if (!dicHero) return resResult(STATUS.DIC_DATA_NOT_FOUND); - let { star, colorStar, quality, scrollId, scrollActive, scrollStar, scrollColorStar, scrollQuality, favour, favourLv } = curHero; + let { star, colorStar, quality, scrollId, scrollActive, scrollStar, scrollColorStar, scrollQuality, favour, favourLv } = hero; let update = { scrollActive, scrollId, scrollStar, scrollColorStar, scrollQuality, favour, favourLv @@ -318,23 +318,13 @@ export class RoleHandler { let dicHeroScroll = getScollByStar(dicHero.quality, update.scrollStar, update.scrollQuality, update.scrollColorStar); update.scrollId = dicHeroScroll ? dicHeroScroll.id : 0; - let hero = await HeroModel.updateHeroInfo(roleId, hid, update); - await calculateCeWithHero(HERO_SYSTEM_TYPE.SCROLL, roleId, serverId, sid, hid, update); + let { curHero } = await calculateCeWithHero(HERO_SYSTEM_TYPE.SCROLL, roleId, serverId, sid, hid, update); // 任务 await checkTaskInActiveScroll(serverId, roleId, sid, scrollActive, hero); return resResult(STATUS.SUCCESS, { - curHero: { - hid: hero.hid, - scrollActive: hero.scrollActive, - scrollId: hero.scrollId, - scrollStar: hero.scrollStar, - scrollColorStar: hero.scrollColorStar, - scrollQuality: hero.scrollQuality, - favour: hero.favour, - favourLv: hero.favourLv, - } + curHero: pick(curHero, ['hid', 'scrollActive', 'scrollId', 'scrollStar', 'scrollColorStar', 'scrollQuality', 'favour', 'favourLv']) }); } diff --git a/game-server/app/services/playerCeService.ts b/game-server/app/services/playerCeService.ts index bfb83c7bb..5b49b18e3 100644 --- a/game-server/app/services/playerCeService.ts +++ b/game-server/app/services/playerCeService.ts @@ -19,7 +19,6 @@ import { PvpDefenseModel } from '../db/PvpDefense'; import { saveCeChangeLog } from '../pubUtils/logUtil'; import { JewelType } from '../db/Jewel'; import { SchoolModel } from '../db/School'; -import { HasJustId } from 'mongoose'; interface Param { isInitRole?: boolean, @@ -54,7 +53,7 @@ export async function calculateWithRole(type: HERO_SYSTEM_TYPE, roleId: string, } export async function calculateCes(type: HERO_SYSTEM_TYPE, roleId: string, serverId: number, sid: string, heroUpdates: Map, roleUpdate: RoleUpdate, roleIncUpdate: RoleUpdate, param: Param = {}) { - let calCe = new CalCe(); + let calCe = new CalCe(roleId); let roleCe = await RoleCeModel.findByRoleId(roleId); calCe.setRoleCe(roleCe); switch (type) { @@ -98,13 +97,62 @@ export async function calculateCes(type: HERO_SYSTEM_TYPE, roleId: string, serve } case HERO_SYSTEM_TYPE.COLORSTAR: // 4. 觉醒 { - for(let [hid, { colorStar, colorStarStage }] of heroUpdates) { - let { hero: { star, starStage, quality, job }, isUpStar } = param; + for(let [hid, { quality, colorStar, colorStarStage }] of heroUpdates) { + let { hero: { star, starStage, job }, isUpStar } = param; await treatHeroStar(calCe, roleId, hid, star, starStage, quality, colorStar, colorStarStage, job, isUpStar); } break; } - case HERO_SYSTEM_TYPE.SCHOOL: // 放百家学宫 + case HERO_SYSTEM_TYPE.TRAIN: // 5. 训练 + case HERO_SYSTEM_TYPE.STAGEUP: // 6. 职业进阶 + { + for(let [hid, { job, jobStage }] of heroUpdates) { + calCe.setJob(hid, job, jobStage); + } + break; + } + case HERO_SYSTEM_TYPE.SKIN: // 7. 穿皮肤 + { + let { hero: { quality, star, starStage, colorStar, colorStarStage } } = param; + for(let [hid, { skinId, job, ePlace }] of heroUpdates) { + calCe.setHeroBase(hid, skinId); + calCe.setHeroStar(hid, job, quality, star, starStage, colorStar, colorStarStage); + + // 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); + } + // TODO 装备 + break; + } + case HERO_SYSTEM_TYPE.FAVOUR: // 8. 好感度 + { + let { hero: { connections }, isFavourLvUp } = param; + if(isFavourLvUp) { + for(let [hid, { favourLv }] of heroUpdates) { + calCe.setFavour(hid, favourLv, connections); + } + } + break; + } + case HERO_SYSTEM_TYPE.CONNECT: // 9. 羁绊 + { + for(let [ hid, { connections } ] of heroUpdates) { + let { shipId } = param; + calCe.setConnection(hid, shipId, connections); + } + break; + } + case HERO_SYSTEM_TYPE.ADD_SKIN: // 15. 第一次获得皮肤 + { + let { skinId } = param; + calCe.setAddSkin(skinId); + break; + } + case HERO_SYSTEM_TYPE.SCHOOL: // 16. 放百家学宫 { let { schoolId, schoolHid, preSchoolHid, hero } = param; if(preSchoolHid) { @@ -116,6 +164,44 @@ export async function calculateCes(type: HERO_SYSTEM_TYPE, roleId: string, serve } break; } + case HERO_SYSTEM_TYPE.SCROLL: // 17. 名将谱 + { + for(let [hid, { scrollStar, scrollQuality, scrollColorStar }] of heroUpdates) { + calCe.setScroll(hid, scrollStar, scrollQuality, scrollColorStar); + } + break; + } + case HERO_SYSTEM_TYPE.TITLE: // 18. 爵位 + { + let { title } = roleUpdate; + calCe.setTitle(title); + break; + } + case HERO_SYSTEM_TYPE.TERAPH: // 19. 神像 + case HERO_SYSTEM_TYPE.TERAPH_UP: // 20. 神像进阶 + { + let { teraphs } = roleUpdate; + calCe.setTeraph(teraphs); + break; + } + case HERO_SYSTEM_TYPE.REBIRTH: // 29. 重生 + { + for(let [hid, { skinId, lv, quality, star, starStage, colorStar, colorStarStage, job, jobStage, }] of heroUpdates) { + calCe.setHeroBase(hid, skinId); + calCe.setHeroLv(hid, lv); + calCe.setHeroStar(hid, job, quality, star, starStage, colorStar, colorStarStage); + calCe.setJob(hid, job, jobStage); + // TODO 装备 + } + break; + } + case HERO_SYSTEM_TYPE.TALENT: // 30. 天赋 + { + for(let [hid, { skins }] of heroUpdates) { + calCe.setTalent(hid, skins); + } + break; + } } let { heroCe, roleInc } = calCe.getCeInc(); // 计算战力,获得有变化的武将战力 let changeHids: number[] = []; @@ -133,7 +219,7 @@ export async function calculateCes(type: HERO_SYSTEM_TYPE, roleId: string, serve pushHeros.push({ hid, ce, incHeroCe: inc }); changeHids.push(hid); } else { - let hero = await HeroModel.updateHeroInfo(roleId, param.hid, heroUpdate); + let hero = await HeroModel.updateHeroInfo(roleId, hid, heroUpdate); heroes.push(hero); } } @@ -202,7 +288,7 @@ async function updateRank(roleId: string, serverId: number, topLineupCe: number, export async function getSumCe(roleId: string, num: number) { let roleCe = await RoleCeModel.findByRoleId(roleId); - let calCe = new CalCe(); + let calCe = new CalCe(roleId); calCe.setRoleCe(roleCe); let arr = calCe.getResultCeArr(); let ce = 0; diff --git a/game-server/app/services/role/calCe.ts b/game-server/app/services/role/calCe.ts index 04bf89412..00771ee45 100644 --- a/game-server/app/services/role/calCe.ts +++ b/game-server/app/services/role/calCe.ts @@ -1,10 +1,10 @@ -import { ABI_STAGE, ABI_STAGE_TO_TYPE, ABI_TYPE_MAIN, LINEUP_NUM, SEID_TYPE } from "../../consts"; -import { HeroType, HeroUpdate } from "../../db/Hero"; +import { ABI_STAGE, ABI_STAGE_TO_TYPE, ABI_TYPE_MAIN, LINEUP_NUM, SEID_TYPE, TALENT_RELATION_TYPE } from "../../consts"; +import { Connect, HeroSkin, HeroType, HeroUpdate, Talent } from "../../db/Hero"; import { RoleUpdate, Teraph } from "../../db/Role"; import { AttrCell, EquipAttr, HeroAttr, RoleCeType, SchoolAttr } from "../../db/RoleCe"; import { TopHero } from "../../domain/dbGeneral"; import { AttributeCal } from "../../domain/roleField/attribute"; -import { gameData, getHeroStarByQuality, getHeroWakeByQuality, getSchoolRateByStar, getTeraph } from "../../pubUtils/data"; +import { gameData, getFriendShipById, getHeroStarByQuality, getHeroWakeByQuality, getJobByGradeAndClass, getSchoolRateByStar, getScollByStar, getTeraph } from "../../pubUtils/data"; import { DicRandomEffectPool } from "../../pubUtils/dictionary/DicRandomEffectPool"; import { DicSe } from "../../pubUtils/dictionary/DicSe"; import { addToMap, deepCopy } from "../../pubUtils/util"; @@ -25,6 +25,12 @@ export class CalCe { resultCes: Map = new Map(); // hid => ce schoolAttrs: Map = new Map(); // hid + attr => ratio schoolAttrsByAttrId: Map = new Map(); // attrId => hid + attr + scrollAttrs: Map = new Map(); // hid + attr => ratio + scrollAttrsByAttrId: Map = new Map(); // attrId => hid + attr + + constructor(roleId: string) { + this.roleId = roleId; + } private getGlobalAttrById(attrId: number) { if(!this.globalAttrs.has(attrId)) { @@ -41,7 +47,6 @@ export class CalCe { private getHeroAttrByHidAndId(hid: number, attrId: number) { let key = `${hid}_${attrId}`; - console.log('$$$$$$$$ getHeroAttrByHidAndId', hid, attrId) if(!this.heroAttrs.has(key)) { if(ABI_TYPE_MAIN.indexOf(attrId) != -1) { let obj = new HeroMainAttr(hid, attrId); @@ -56,7 +61,6 @@ export class CalCe { } this.heroAttrsByHid.get(hid).push(key); } - console.log('$$$$$$$$ heroAttrsByHid', this.heroAttrsByHid) return this.heroAttrs.get(key); } @@ -84,7 +88,7 @@ export class CalCe { return this.equipAttrs.get(key); } - private setSchoolRate(hid: number, attrId: number, value: number) { + private setSchoolAttrs(hid: number, attrId: number, value: number) { let key = `${hid}_${attrId}`; if(!this.schoolAttrs.has(key)) { this.schoolAttrs.set(key, { hid, attrId, ce: value }); @@ -108,6 +112,30 @@ export class CalCe { globalAttr.school = schoolResult; } + private setScrollAttrs(hid: number, attrId: number, value: number) { + let key = `${hid}_${attrId}`; + if(!this.scrollAttrs.has(key)) { + this.scrollAttrs.set(key, { hid, attrId, ce: value }); + if(!this.scrollAttrsByAttrId.has(attrId)) { + this.scrollAttrsByAttrId.set(attrId, []); + } + this.scrollAttrsByAttrId.get(attrId).push(key); + } else { + this.scrollAttrs.get(key).ce = value; + } + } + + private calScrollAttrsToGlobal(attrId: number) { + let keys = this.scrollAttrsByAttrId.get(attrId)||[]; + let result = 0; + for(let key of keys) { + let { ce } = this.scrollAttrs.get(key); + result += ce; + } + let globalAttr = this.getGlobalAttrById(attrId); + globalAttr.scroll = result; + } + public calHeroCe() { let ces = new Map(); // hid => [{attrId, val}] for(let [hid, keys] of this.heroAttrsByHid) { @@ -201,9 +229,6 @@ export class CalCe { } public setRoleCe(roleCe: RoleCeType) { - console.log('&&&&&&&& setRoleCe', roleCe) - - this.roleId = roleCe.roleId; if(roleCe) { for(let globalAttr of roleCe.globalAttrs) { let obj = this.getGlobalAttrById(globalAttr.attrId); @@ -226,11 +251,13 @@ export class CalCe { } } for(let { hid, attrId, value } of roleCe.schoolAttrs) { - this.setSchoolRate(hid, attrId, value); + this.setSchoolAttrs(hid, attrId, value); + } + for(let { hid, attrId, value } of roleCe.scrollAttrs) { + this.setScrollAttrs(hid, attrId, value); } } this.originCes = this.calHeroCe(); - console.log('############ setRoleCe', this.originCes) } public setResultHero(hero: HeroType) { @@ -300,13 +327,98 @@ export class CalCe { // 职业基础 public setJob(hid: number, job: number, jobStage: number) { const 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(jobStage >= i) { let { id, attr } = dicJob.ceAttr.get(i); let heroAttr = this.getHeroAttrByHidAndId(hid, id); heroAttr.job = attr; + } else { + if(dicLastJob) { + let { id, attr } = dicLastJob.ceAttr.get(i); + let heroAttr = this.getHeroAttrByHidAndId(hid, id); + heroAttr.job = attr; + } } } + for(let { id, val } of dicJob.baseSubAttr) { + let heroAttr = this.getHeroAttrByHidAndId(hid, id); + heroAttr.base = val; + } + } + + // 好感度 + public setFavour(hid: number, favourLv: number, connections: Connect[]) { + let currentFiendShipLevel = gameData.friendShipLevelMap.get(favourLv); + let add = currentFiendShipLevel.add; + + for (let {shipId, level} of connections) { + let dicHeroFriendShip = getFriendShipById(shipId, level); + for (let { id } of dicHeroFriendShip.attributes) { + let heroAttr = this.getHeroAttrByHidAndId(hid, id); + heroAttr.favour = add; + } + } + } + + // 羁绊 + public setConnection(hid: number, shipId: number, connections: Connect[]) { + let connect = connections.find(cur => cur.shipId == shipId); + let level = connect?.level||0; + + let currentShip = getFriendShipById(shipId, level); + if (currentShip) { + for (let { id, number: val } of currentShip.attributes) { + let heroAttr = this.getHeroAttrByHidAndId(hid, id); + heroAttr.connect = val; + } + } + } + + // 第一次获得皮肤 + public setAddSkin(skinId: number) { + let addSkin = gameData.fashion.get(skinId); + for (let { id, number: val } of addSkin.globalAttr) { + let globalAttr = this.getGlobalAttrById(id); + globalAttr.skin += val; + } + } + + // 天赋 + public setTalent(hid: number, skins: HeroSkin[]) { + let skin = skins.find(cur => cur.enable); + let seids = this.getTalentSeid(skin.talent); + let { ratioUp } = this.addSeidEffect(seids); + for(let [attrId, val] of ratioUp) { + let heroAttr = this.getHeroAttrByHidAndId(hid, attrId); + heroAttr.talent = val; + } + } + + private getTalentSeid(talent: Talent[]) { + let seids = new Map(); // 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; } // 爵位 @@ -340,18 +452,30 @@ export class CalCe { } } + // 名将谱 + public setScroll(hid: number, scrollStar: number, scrollQuality: number, scrollColorStar: number) { + let dicHero =gameData.hero.get(hid); + let dicHeroScroll = getScollByStar(dicHero.quality, scrollStar, scrollQuality, scrollColorStar); + + if(dicHeroScroll) { + for(let [attrId, value] of dicHeroScroll.ceAttr) { + this.setScrollAttrs(hid, attrId, value); + this.calScrollAttrsToGlobal(attrId); + } + } + } + // 百家学宫 public setSchool(isPutOn: boolean, hid: number, schoolId: number, star: number, colorStar: number, quality: number) { let dicSchool = gameData.school.get(schoolId); let dicSchoolRate = getSchoolRateByStar(star, colorStar, quality); - console.log('#### setSchool', star, colorStar, quality, dicSchoolRate) for (let attrId of dicSchool.upAttribute) { if(ABI_TYPE_MAIN.includes(attrId)) { // 主属性 - this.setSchoolRate(hid, attrId, isPutOn?dicSchoolRate.mainAttrAPerent: 0); + this.setSchoolAttrs(hid, attrId, isPutOn?dicSchoolRate.mainAttrAPerent: 0); } else { - this.setSchoolRate(hid, attrId, isPutOn?dicSchoolRate.assiAttrAddValue: 0); + this.setSchoolAttrs(hid, attrId, isPutOn?dicSchoolRate.assiAttrAddValue: 0); } this.calSchoolAttrsToGlobal(attrId); } diff --git a/game-server/app/services/role/rewardService.ts b/game-server/app/services/role/rewardService.ts index 099631081..eef4db82c 100644 --- a/game-server/app/services/role/rewardService.ts +++ b/game-server/app/services/role/rewardService.ts @@ -24,7 +24,7 @@ import { JewelModel, JewelType, jewelUpdate, RandSe } from '../../db/Jewel'; import { updateEplaces } from '../equipService'; import { combineItems, getCoinEventProperties, getGoldEventProperties, sortItems } from './util'; import { nowSeconds } from '../../pubUtils/timeUtil'; -import { calculateCeWithHero } from '../playerCeService'; +import { calculateCeWithHero, calculateWithRole } from '../playerCeService'; @@ -358,7 +358,7 @@ export async function addSkin(roleId: string, roleName: string, sid: string, ski if(skin.hid && !hero) hero = await HeroModel.findByHidAndRole(skin.hid, roleId); let condition = { type: FIGURE_UNLOCK_CONDITION.GET_SKIN, paramSkinId: skinId }; await unlockFigure(sid, roleId, [condition]); // 解锁头像 - await calculateCeWithHero(HERO_SYSTEM_TYPE.ADD_SKIN, roleId, hero.serverId, sid, skin.hid, {}, { skinId }); // 全局加成 + await calculateWithRole(HERO_SYSTEM_TYPE.ADD_SKIN, roleId, hero.serverId, sid, {}, { skinId }); // 全局加成 if (hero) { // 有武将的,将皮肤链接到武将上 let curSkin = hero.skins.find(cur => cur.id == skinId); diff --git a/shared/consts/constModules/heroConst.ts b/shared/consts/constModules/heroConst.ts index 866d86a9f..c1ff1c2b7 100644 --- a/shared/consts/constModules/heroConst.ts +++ b/shared/consts/constModules/heroConst.ts @@ -10,11 +10,11 @@ export enum HERO_SYSTEM_TYPE { SKIN =7, // 皮肤 FAVOUR =8, // 好感 CONNECT =9, // 羁绊 - EQUIP = 10, // 装备穿脱 - EQUIP_BASE = 11, // 装备栏升级,装备精炼等 - RESTRENGTHEN = 12, // 洗练 - JEWEL_ON = 13, // 穿宝石 - JEWEL_OFF = 14, // 脱宝石 + // EQUIP = 10, // 装备穿脱 + // EQUIP_BASE = 11, // 装备栏升级,装备精炼等 + // RESTRENGTHEN = 12, // 洗练 + // JEWEL_ON = 13, // 穿宝石 + // JEWEL_OFF = 14, // 脱宝石 ADD_SKIN = 15, // 第一次获取皮肤(全局) SCHOOL = 16, // 百家学宫 SCROLL = 17, // 名将谱 diff --git a/shared/pubUtils/dictionary/DicJob.ts b/shared/pubUtils/dictionary/DicJob.ts index 5e5cbf501..31a8305fe 100644 --- a/shared/pubUtils/dictionary/DicJob.ts +++ b/shared/pubUtils/dictionary/DicJob.ts @@ -23,8 +23,10 @@ export interface DicJob { readonly trainingConsume: Array; // 升阶消耗 readonly upGradeConsume: Array; - // 每阶升级属性 + // 每阶升级属性 stage => {} readonly ceAttr: Map; + // 次级属性基础 attr => value attr1 + readonly baseSubAttr: {id: number, val: number}[]; // 一共有多少阶升级 readonly maxStage: number; // 到这一阶能获得多少天赋点 @@ -32,7 +34,7 @@ export interface DicJob { } type KeysEnum = { [P in keyof Required]: true }; -const DicJobKeys: KeysEnum = {jobid: true, name: true, grade: true, unlockLevel: true, job_class: true, type: true, trainingConsume: true, upGradeConsume: true, ceAttr: true, maxStage: true, talentPoint: true}; +const DicJobKeys: KeysEnum = {jobid: true, name: true, grade: true, unlockLevel: true, job_class: true, type: true, trainingConsume: true, upGradeConsume: true, ceAttr: true, maxStage: true, talentPoint: true, baseSubAttr: true}; export const dicJob = new Map(); export const jobClassMaxGrades = new Map(); @@ -54,6 +56,7 @@ export function loadJob() { o.maxStage = o.trainingConsume.length; o.upGradeConsume = parseGoodStr(o.upGradeConsume); o.ceAttr = parseCeAttr(o.maxStage, o.attr); + o.baseSubAttr = parseAttribute(o.baseSecondAttr||''); dicJob.set(o.jobid, _.pick(o, Object.keys(DicJobKeys))); let jobClass = jobClassMaxGrades.get(o.job_class); if (!jobClass || jobClass.grade < o.grade) { @@ -93,4 +96,17 @@ function parseCeAttr(maxStage: number, str: string) { result.set(i, { id: parseInt(id), attr: parseFloat(attr) }); } return result -} \ No newline at end of file +} + +function parseAttribute(str: string) { + let result = new Array<{ id: number, val: number }>(); + if (!str) return result; + let decodeArr = decodeArrayListStr(str); + for (let [id, val] of decodeArr) { + if (isNaN(parseInt(id)) || isNaN(parseInt(val))) { + throw new Error('data table format wrong'); + } + result.push({ id: parseInt(id), val: parseInt(val) }); + } + return result +} From 3496d664e8531f0616dc2cc71b83030b1a14d4a1 Mon Sep 17 00:00:00 2001 From: luying Date: Tue, 29 Mar 2022 17:32:48 +0800 Subject: [PATCH 06/12] =?UTF-8?q?=E6=88=98=E5=8A=9B=EF=BC=9A=E5=88=9D?= =?UTF-8?q?=E6=AD=A5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../app/servers/role/handler/equipHandler.ts | 14 +- game-server/app/services/playerCeService.ts | 110 +- game-server/app/services/role/calCe.ts | 330 +- shared/consts/constModules/sysConst.ts | 1 + shared/db/Hero.ts | 2 +- shared/pubUtils/data.ts | 8 + .../dictionary/DicEquipStrengthAttr.ts | 39 + shared/resource/jsons/dic_zyz_equip.json | 56 - .../jsons/dic_zyz_equipStrengthAttr.json | 14002 ++++++++++++++++ 9 files changed, 14430 insertions(+), 132 deletions(-) create mode 100644 shared/pubUtils/dictionary/DicEquipStrengthAttr.ts create mode 100644 shared/resource/jsons/dic_zyz_equipStrengthAttr.json diff --git a/game-server/app/servers/role/handler/equipHandler.ts b/game-server/app/servers/role/handler/equipHandler.ts index 95330564e..c7e1a1323 100644 --- a/game-server/app/servers/role/handler/equipHandler.ts +++ b/game-server/app/servers/role/handler/equipHandler.ts @@ -105,7 +105,7 @@ export class EquipHandler { ePlace: newEplace, consumes: addConsumeToHero(hero.consumes, consumes) } - await calculateCeWithHero(HERO_SYSTEM_TYPE.EQUIP_STRENGTH, roleId, serverId, sid, hid, update, { ePlaceId }); + await calculateCeWithHero(HERO_SYSTEM_TYPE.EQUIP_STRENGTH, roleId, serverId, sid, hid, update, { ePlaceIds: [ePlaceId] }); await checkTaskInEquipLvUp(serverId, roleId, sid, oldEplace, newEplace, [ePlaceId]); const curHero = { @@ -343,7 +343,7 @@ export class EquipHandler { let canChange = originJewel && checkJewelCanPutOnEquip(originEquip, originJewel); if(canChange) canSentMineToOrigin = true; let { newEplace, updatedEplace } = updateEplace(originEplace, ePlaceId, { jewel: canChange? originJewel.seqId: 0 }); - await calculateCeWithHero(HERO_SYSTEM_TYPE.EQUIP_JEWEL, roleId, serverId, sid, hid, { ePlace: newEplace }, { ePlaceId, oldJewel: jewel, newJewel: canChange? originJewel:null }); + await calculateCeWithHero(HERO_SYSTEM_TYPE.EQUIP_JEWEL, roleId, serverId, sid, jewel.hid, { ePlace: newEplace }, { ePlaceId, jewel: canChange? originJewel: null }); await checkTaskInPutJewel(serverId, roleId, sid, originEplace, newEplace, ePlaceId, jewel, canChange? originJewel:null); originHeroResult = { hid: originHero.hid, ePlace: updatedEplace }; @@ -356,7 +356,7 @@ export class EquipHandler { // 目标镶嵌上 let curJewel = await JewelModel.putOnOrOff(seqId, hid, ePlaceId); let { newEplace, updatedEplace } = updateEplace(oldEplace, ePlaceId, { jewel: seqId }); - await calculateCeWithHero(HERO_SYSTEM_TYPE.EQUIP_JEWEL, roleId, serverId, sid, hid, { ePlace: newEplace }, { ePlaceId, oldJewel: originJewel, newJewel: curJewel }); + await calculateCeWithHero(HERO_SYSTEM_TYPE.EQUIP_JEWEL, roleId, serverId, sid, hid, { ePlace: newEplace }, { ePlaceIds: [ePlaceId], jewels: [curJewel] }); await checkTaskInPutJewel(serverId, roleId, sid, oldEplace, newEplace, ePlaceId, originJewel, curJewel); let curHero = { @@ -384,7 +384,7 @@ export class EquipHandler { let curJewel = await JewelModel.putOnOrOff(curEquip.jewel, 0, 0); let { newEplace, updatedEplace } = updateEplace(oldEplace, ePlaceId, { jewel: 0 }); - await calculateCeWithHero(HERO_SYSTEM_TYPE.EQUIP_JEWEL, roleId, serverId, sid, hid, { ePlace: newEplace }, { ePlaceId, oldJewel: curJewel }); + await calculateCeWithHero(HERO_SYSTEM_TYPE.EQUIP_JEWEL, roleId, serverId, sid, hid, { ePlace: newEplace }, { ePlaceIds: [ePlaceId], jewels: [] }); await checkTaskInPutJewel(serverId, roleId, sid, oldEplace, newEplace, ePlaceId, null, curJewel); let curHero = { @@ -557,7 +557,7 @@ export class EquipHandler { // 更新战力 if(hid > 0) { const hero = await HeroModel.findByHidAndRole(hid, roleId); - await calculateCeWithHero(HERO_SYSTEM_TYPE.JEWEL_RESET_RANDSE, roleId, serverId, sid, hid, {}, { ePlaceId, oldJewel: jewel, newJewel, hero }); + await calculateCeWithHero(HERO_SYSTEM_TYPE.JEWEL_RESET_RANDSE, roleId, serverId, sid, hid, { ePlace: hero.ePlace }, { ePlaceId, jewel: newJewel }); } await checkTaskInEquipReset(serverId, roleId, sid); @@ -639,7 +639,7 @@ export class EquipHandler { // 更新战力 if(isSuccess && hid > 0) { const hero = await HeroModel.findByHidAndRole(hid, roleId); - await calculateCeWithHero(HERO_SYSTEM_TYPE.JEWEL_QUENCH, roleId, serverId, sid, hid, {}, { ePlaceId, oldJewel: jewel, newJewel, hero }); + await calculateCeWithHero(HERO_SYSTEM_TYPE.JEWEL_QUENCH, roleId, serverId, sid, hid, { ePlace: hero.ePlace }, { ePlaceId, jewel: newJewel }); } await checkTaskInEquipQuench(serverId, roleId, sid, isSuccess); @@ -759,7 +759,7 @@ export class EquipHandler { // 更新战力 if(targetJewel.hid > 0) { const hero = await HeroModel.findByHidAndRole(targetJewel.hid, roleId); - await calculateCeWithHero(HERO_SYSTEM_TYPE.JEWEL_RESET_RANDSE, roleId, serverId, sid, targetJewel.hid, {}, { hid: targetJewel.ePlaceId, ePlaceId: targetJewel.ePlaceId, oldJewel: originJewel, newJewel, hero }); + await calculateCeWithHero(HERO_SYSTEM_TYPE.JEWEL_RESET_RANDSE, roleId, serverId, sid, targetJewel.hid, { ePlace: hero.ePlace }, { ePlaceId: targetJewel.ePlaceId, jewel: newJewel }); } diff --git a/game-server/app/services/playerCeService.ts b/game-server/app/services/playerCeService.ts index 5b49b18e3..b7393e36e 100644 --- a/game-server/app/services/playerCeService.ts +++ b/game-server/app/services/playerCeService.ts @@ -29,8 +29,7 @@ interface Param { isFavourLvUp?: boolean, ePlaceId?: number, ePlaceIds?: number[], - oldJewel?: JewelType, - newJewel?: JewelType, + jewels?: JewelType[], jewel?: JewelType, teraphId?: number, schoolId?: number, @@ -113,19 +112,17 @@ export async function calculateCes(type: HERO_SYSTEM_TYPE, roleId: string, serve } case HERO_SYSTEM_TYPE.SKIN: // 7. 穿皮肤 { - let { hero: { quality, star, starStage, colorStar, colorStarStage } } = param; + let { hero: { quality, star, starStage, colorStar, colorStarStage, skins } } = param; for(let [hid, { skinId, job, ePlace }] of heroUpdates) { calCe.setHeroBase(hid, skinId); calCe.setHeroStar(hid, job, quality, star, starStage, colorStar, colorStarStage); - - // 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); + for(let { id, equipId, quality, qualityStage, lv, star, starStage } of ePlace) { + calCe.setEquipQuality(hid, id, equipId, quality, qualityStage); + calCe.setEquipStrength(hid, id, equipId, lv); + calCe.setEquipStar(hid, id, equipId, star, starStage); + } + calCe.setTalent(hid, skins); } - // TODO 装备 break; } case HERO_SYSTEM_TYPE.FAVOUR: // 8. 好感度 @@ -184,14 +181,101 @@ export async function calculateCes(type: HERO_SYSTEM_TYPE, roleId: string, serve calCe.setTeraph(teraphs); break; } + case HERO_SYSTEM_TYPE.COMPOSE_EQUIP: // 21. 合成装备 + { + let { ePlaceId } = param; + for(let [hid, { ePlace = [] }] of heroUpdates) { + for(let { id, equipId, quality, qualityStage, lv, star, starStage } of ePlace) { + if(ePlaceId == id) { + calCe.setEquipQuality(hid, id, equipId, quality, qualityStage); + calCe.setEquipStrength(hid, id, equipId, lv); + calCe.setEquipStar(hid, id, equipId, star, starStage); + } + } + calCe.setEquipSuit(hid, ePlace); + } + break; + } + case HERO_SYSTEM_TYPE.EQUIP_STRENGTH: // 22. 装备强化 + { + let { ePlaceIds } = param; + for(let [hid, { ePlace = [] }] of heroUpdates) { + for(let { id, equipId, lv } of ePlace) { + if(ePlaceIds.indexOf(id) != -1) { + calCe.setEquipStrength(hid, id, equipId, lv); + } + } + } + break; + } + case HERO_SYSTEM_TYPE.EQUIP_QUALITY: // 23. 装备升品 + { + let { ePlaceId } = param; + for(let [hid, { ePlace = [] }] of heroUpdates) { + for(let { id, equipId, quality, qualityStage } of ePlace) { + if(ePlaceId == id) { + calCe.setEquipQuality(hid, id, equipId, quality, qualityStage); + } + } + } + break; + } + case HERO_SYSTEM_TYPE.EQUIP_STAR: // 24. 装备升星 + { + let { ePlaceId } = param; + for(let [hid, { ePlace = [] }] of heroUpdates) { + for(let { id, equipId, star, starStage } of ePlace) { + if(ePlaceId == id) { + calCe.setEquipStar(hid, id, equipId, star, starStage); + } + } + calCe.setEquipSuit(hid, ePlace); + } + break; + } + case HERO_SYSTEM_TYPE.EQUIP_JEWEL: // 25. 装备天晶 + case HERO_SYSTEM_TYPE.JEWEL_RESET_RANDSE: // 27. 洗练 + case HERO_SYSTEM_TYPE.JEWEL_QUENCH: // 28. 淬炼 + { + let { ePlaceId, jewel: curJewel } = param; + for(let [hid, { ePlace = [] }] of heroUpdates) { + for(let { id, stones } of ePlace) { + if(ePlaceId == id) { + calCe.setJewel(hid, id, stones, curJewel); + } + } + calCe.setEquipSuit(hid, ePlace); + } + break; + } + case HERO_SYSTEM_TYPE.EQUIP_STONE: // 26. 装备地玉 + { + let { ePlaceId, jewel: curJewel } = param; + for(let [hid, { ePlace = [] }] of heroUpdates) { + for(let { id, stones } of ePlace) { + if(ePlaceId == id) { + calCe.setJewel(hid, id, stones, curJewel); + } + } + calCe.setEquipSuit(hid, ePlace); + } + break; + } case HERO_SYSTEM_TYPE.REBIRTH: // 29. 重生 { - for(let [hid, { skinId, lv, quality, star, starStage, colorStar, colorStarStage, job, jobStage, }] of heroUpdates) { + for(let [hid, { skinId, lv, quality, star, starStage, colorStar, colorStarStage, job, jobStage, skins, ePlace, scrollStar, scrollQuality, scrollColorStar }] of heroUpdates) { calCe.setHeroBase(hid, skinId); calCe.setHeroLv(hid, lv); calCe.setHeroStar(hid, job, quality, star, starStage, colorStar, colorStarStage); calCe.setJob(hid, job, jobStage); - // TODO 装备 + + for(let { id, equipId, quality, qualityStage, lv, star, starStage } of ePlace) { + calCe.setEquipQuality(hid, id, equipId, quality, qualityStage); + calCe.setEquipStrength(hid, id, equipId, lv); + calCe.setEquipStar(hid, id, equipId, star, starStage); + } + calCe.setTalent(hid, skins); + calCe.setScroll(hid, scrollStar, scrollQuality, scrollColorStar); } break; } diff --git a/game-server/app/services/role/calCe.ts b/game-server/app/services/role/calCe.ts index 00771ee45..127271d3f 100644 --- a/game-server/app/services/role/calCe.ts +++ b/game-server/app/services/role/calCe.ts @@ -1,10 +1,11 @@ import { ABI_STAGE, ABI_STAGE_TO_TYPE, ABI_TYPE_MAIN, LINEUP_NUM, SEID_TYPE, TALENT_RELATION_TYPE } from "../../consts"; -import { Connect, HeroSkin, HeroType, HeroUpdate, Talent } from "../../db/Hero"; +import { Connect, EPlace, HeroSkin, HeroType, HeroUpdate, Stone, Talent } from "../../db/Hero"; +import { JewelType } from "../../db/Jewel"; import { RoleUpdate, Teraph } from "../../db/Role"; import { AttrCell, EquipAttr, HeroAttr, RoleCeType, SchoolAttr } from "../../db/RoleCe"; import { TopHero } from "../../domain/dbGeneral"; import { AttributeCal } from "../../domain/roleField/attribute"; -import { gameData, getFriendShipById, getHeroStarByQuality, getHeroWakeByQuality, getJobByGradeAndClass, getSchoolRateByStar, getScollByStar, getTeraph } from "../../pubUtils/data"; +import { gameData, getEquipQualityIdByEquipIdAndPoint, getEquipStarAttrByStage, getEquipStrenthenAttr, getEquipSuitByHero, getFriendShipById, getHeroStarByQuality, getHeroWakeByQuality, getJewelConditionByLvAndSeId, getJobByGradeAndClass, getSchoolRateByStar, getScollByStar, getTeraph } from "../../pubUtils/data"; import { DicRandomEffectPool } from "../../pubUtils/dictionary/DicRandomEffectPool"; import { DicSe } from "../../pubUtils/dictionary/DicSe"; import { addToMap, deepCopy } from "../../pubUtils/util"; @@ -16,7 +17,8 @@ export class CalCe { heroAttrsByHid: Map = new Map(); // hid => [hid+attrId] equipAttrs: Map = new Map(); // hid+eplaceId+attrId => EquipAttr equipAttrsByHid: Map = new Map(); // hid => [hid+eplaceId+attrId] - equipAttrsByHidAndEplace: Map = new Map(); // hid+eplaceId =>+eplaceId+attrId] + equipAttrsByHidAndEplace: Map = new Map(); // hid+eplaceId =>[hid+eplaceId+attrId] + equipAttrsByHidAndAttrId: Map = new Map(); // hid+attrId =>[hid+eplaceId+attrId] heroLv: Map = new Map(); heroHistoryCe: Map = new Map(); heroObjectId: Map = new Map(); @@ -25,8 +27,10 @@ export class CalCe { resultCes: Map = new Map(); // hid => ce schoolAttrs: Map = new Map(); // hid + attr => ratio schoolAttrsByAttrId: Map = new Map(); // attrId => hid + attr + schoolAttrsByHid: Map = new Map(); // hid => hid + attr scrollAttrs: Map = new Map(); // hid + attr => ratio scrollAttrsByAttrId: Map = new Map(); // attrId => hid + attr + scrollAttrsByHid: Map = new Map(); // hid => hid + attr constructor(roleId: string) { this.roleId = roleId; @@ -45,6 +49,11 @@ export class CalCe { return this.globalAttrs.get(attrId); } + private getHeroAttrsByHid(hid: number) { + let keys = this.heroAttrsByHid.get(hid); + return keys.map(key => this.heroAttrs.get(key)); + } + private getHeroAttrByHidAndId(hid: number, attrId: number) { let key = `${hid}_${attrId}`; if(!this.heroAttrs.has(key)) { @@ -88,6 +97,13 @@ export class CalCe { return this.equipAttrs.get(key); } + private getEquipAttrsByHidAndEplace(hid: number, eplaceId: number) { + let key2 = `${hid}_${eplaceId}`; + if(!this.equipAttrsByHidAndEplace.has(key2)) return [] + let { keys } = this.equipAttrsByHidAndEplace.get(key2); + return keys.map(key => this.equipAttrs.get(key)); + } + private setSchoolAttrs(hid: number, attrId: number, value: number) { let key = `${hid}_${attrId}`; if(!this.schoolAttrs.has(key)) { @@ -96,11 +112,20 @@ export class CalCe { this.schoolAttrsByAttrId.set(attrId, []); } this.schoolAttrsByAttrId.get(attrId).push(key); + if(!this.schoolAttrsByHid.has(attrId)) { + this.schoolAttrsByHid.set(hid, []); + } + this.schoolAttrsByHid.get(hid).push(key); } else { this.schoolAttrs.get(key).ce = value; } } + private getSchoolAttrsByHid(hid: number) { + let keys = this.schoolAttrsByHid.get(hid)||[]; + return keys.map(key => this.schoolAttrs.get(key)); + } + private calSchoolAttrsToGlobal(attrId: number) { let keys = this.schoolAttrsByAttrId.get(attrId)||[]; let schoolResult = 0; @@ -120,11 +145,20 @@ export class CalCe { this.scrollAttrsByAttrId.set(attrId, []); } this.scrollAttrsByAttrId.get(attrId).push(key); + if(!this.scrollAttrsByHid.has(attrId)) { + this.scrollAttrsByHid.set(hid, []); + } + this.scrollAttrsByHid.get(hid).push(key); } else { this.scrollAttrs.get(key).ce = value; } } + private getScrollAttrsByHid(hid: number) { + let keys = this.scrollAttrsByHid.get(hid)||[]; + return keys.map(key => this.scrollAttrs.get(key)); + } + private calScrollAttrsToGlobal(attrId: number) { let keys = this.scrollAttrsByAttrId.get(attrId)||[]; let result = 0; @@ -141,14 +175,15 @@ export class CalCe { for(let [hid, keys] of this.heroAttrsByHid) { let lv = this.heroLv.get(hid)||1; for(let key of keys) { - let { attrId, base = 0, job = 0, starUp = 0, connect = 0, favour = 0, talent = 0, equip = 0, equipUp = 0, equipStone = 0 } = this.heroAttrs.get(key); + let { attrId, mainBase = 0, subBase = 0, job = 0, starUp = 0, connect = 0, favour = 0, talent = 0, equipQuality = 0, equipStrength = 0, equipStar = 0, equipSuit = 0, jewel = 0, stone = 0 } = this.heroAttrs.get(key); let { school = 0, teraph = 0, title = 0, scroll = 0, skin = 0 } = this.getGlobalAttrById(attrId); let val = 0; if(ABI_TYPE_MAIN.indexOf(attrId)) { - // {[hp1 + lv * hp2 + hp3 * ( 1 + hp4 )] * (1 + hp5 ) + [( hp6+hp7)*(1+hp8)] } * ( 1 + hp9 ) + hp10 + hp11 - val = ((base + job + lv * starUp + connect * ( 1 + favour )) * ( 1 + school + talent ) + equip ) * ( 1 + equipUp ) + equipStone + teraph + title + scroll + skin; + // {[hp1 + lv * hp2 + hp3 * ( 1 + hp4 )] * (1 + hp5 ) + [( hp6 + hp7 ) * ( 1 + hp8 )] } * ( 1 + hp9 ) + hp10 + hp11 + val = ((mainBase + job + lv * starUp + connect * ( 1 + favour )) * ( 1 + school + talent ) + (( equipQuality + equipStrength ) * ( 1 + ( equipStar + equipSuit ))) ) * ( 1 + jewel ) + stone + teraph + title + scroll + skin; } else { - val = base + job + talent + teraph + school + title + equip + skin; + // attr1 + attr2 + attr3 + attr4 + attr5 + attr6 + attr7 + attr8 + attr9 + val = subBase + job + talent + teraph + school + title + jewel + skin + equipStar; } if(!ces.has(hid)) ces.set(hid, []); ces.get(hid).push({ id: attrId, val }); @@ -288,12 +323,55 @@ export class CalCe { return { topLineup, topLineupCe }; } + private clearRoleAttr(field: string) { + for(let globalAttr of this.globalAttrs) { + globalAttr[field] = 0; + } + } + + private clearHeroAttrByHid(hid: number, field: string) { + let heroAttrs = this.getHeroAttrsByHid(hid); + for(let heroAttr of heroAttrs) { + heroAttr[field] = 0; + } + } + + private clearEquipAttrByHidAndEplace(hid: number, eplaceId: number, field: string) { + let equipAttrs = this.getEquipAttrsByHidAndEplace(hid, eplaceId); + for(let equipAttr of equipAttrs) { + let originNum = equipAttr[field]||0; + let heroAttr = this.getHeroAttrByHidAndId(hid, equipAttr.attrId); + if(heroAttr && heroAttr[field]) { + heroAttr[field] -= originNum; + } + equipAttr[field] = 0; + } + } + + private clearSchoolAttr(hid: number) { + let schoolAttrs = this.getSchoolAttrsByHid(hid); + for(let schoolAttr of schoolAttrs) { + schoolAttr.ce = 0; + this.calSchoolAttrsToGlobal(schoolAttr.attrId); + } + } + + private clearScrollAttr(hid: number) { + let scrollAttrs = this.getScrollAttrsByHid(hid); + for(let scrollAttr of scrollAttrs) { + scrollAttr.ce = 0; + this.calScrollAttrsToGlobal(scrollAttr.attrId); + } + } + // 武将基础&成长 public setHeroBase(hid: number, skinId: number) { + this.clearHeroAttrByHid(hid, 'mainBase'); let dicHero = gameData.hero.get(skinId); + for(let [attrId, value] of dicHero.baseAbilityArr) { let heroAttr = this.getHeroAttrByHidAndId(hid, attrId); - heroAttr.base = value; + heroAttr.mainBase = value; } } @@ -304,6 +382,7 @@ export class CalCe { // 星级相关 public setHeroStar(hid: number, job: number, quality: number, star: number, starStage: number, colorStar: number, colorStarStage: number) { + this.clearHeroAttrByHid(hid, 'starUp'); let dicJob = gameData.job.get(job); let jobClass = dicJob.job_class; const isWake = colorStar > 0; // 是否觉醒,只要激活了觉醒,彩星就会 > 1 @@ -326,6 +405,8 @@ export class CalCe { // 职业基础 public setJob(hid: number, job: number, jobStage: number) { + this.clearHeroAttrByHid(hid, 'job'); + this.clearHeroAttrByHid(hid, 'subBase'); const dicJob = gameData.job.get(job); let lastJob = getJobByGradeAndClass(dicJob.job_class, dicJob.grade - 1); let dicLastJob = lastJob? gameData.job.get(lastJob.jobid): null; @@ -344,12 +425,13 @@ export class CalCe { } for(let { id, val } of dicJob.baseSubAttr) { let heroAttr = this.getHeroAttrByHidAndId(hid, id); - heroAttr.base = val; + heroAttr.subBase = val; } } // 好感度 public setFavour(hid: number, favourLv: number, connections: Connect[]) { + this.clearHeroAttrByHid(hid, 'favour'); let currentFiendShipLevel = gameData.friendShipLevelMap.get(favourLv); let add = currentFiendShipLevel.add; @@ -364,6 +446,7 @@ export class CalCe { // 羁绊 public setConnection(hid: number, shipId: number, connections: Connect[]) { + this.clearHeroAttrByHid(hid, 'connect'); let connect = connections.find(cur => cur.shipId == shipId); let level = connect?.level||0; @@ -387,6 +470,7 @@ export class CalCe { // 天赋 public setTalent(hid: number, skins: HeroSkin[]) { + this.clearHeroAttrByHid(hid, 'talent'); let skin = skins.find(cur => cur.enable); let seids = this.getTalentSeid(skin.talent); let { ratioUp } = this.addSeidEffect(seids); @@ -421,8 +505,122 @@ export class CalCe { return result; } + // 装备升品 + public setEquipQuality(hid: number, eplaceId: number, equipId: number, quality: number, qualityStage: number) { + this.clearEquipAttrByHidAndEplace(hid, eplaceId, 'equipQuality'); + let dicEquipQuality = getEquipQualityIdByEquipIdAndPoint(equipId, quality, qualityStage); + for(let { id, num } of dicEquipQuality.attribute) { + let equipAttr = this.getEquipAttrByHidAndId(hid, eplaceId, id); + let heroAttr = this.getHeroAttrByHidAndId(hid, id); + heroAttr.equipQuality += num - equipAttr.equipQuality; + equipAttr.equipQuality = num; + } + } + + // 装备强化 + public setEquipStrength(hid: number, eplaceId: number, equipId: number, lv: number) { + this.clearEquipAttrByHidAndEplace(hid, eplaceId, 'equipStrengthen'); + let dicEquipStrenth = getEquipStrenthenAttr(equipId, lv); + for(let { id, num } of dicEquipStrenth.attr) { + let equipAttr = this.getEquipAttrByHidAndId(hid, eplaceId, id); + let heroAttr = this.getHeroAttrByHidAndId(hid, id); + heroAttr.equipStrength = num - equipAttr.equipStrengthen; + equipAttr.equipStrengthen = num; + } + } + + // 装备精炼(升星) + public setEquipStar(hid: number, eplaceId: number, equipId: number, star: number, starStage: number) { + this.clearEquipAttrByHidAndEplace(hid, eplaceId, 'equipStar'); + let dicEquipStar = getEquipStarAttrByStage(equipId, star, starStage); + if(dicEquipStar) { + let { mainAttr, subAttr } = dicEquipStar; + for(let { id, num } of [...mainAttr, ...subAttr]) { + let equipAttr = this.getEquipAttrByHidAndId(hid, eplaceId, id); + let heroAttr = this.getHeroAttrByHidAndId(hid, id); + heroAttr.equipStar = num - equipAttr.equipStar; + equipAttr.equipStar = num; + } + } + } + + // 装备套装 + public setEquipSuit(hid: number, ePlace: EPlace[]) { + this.clearHeroAttrByHid(hid, 'equipSuit'); + let dicEquipSuit = getEquipSuitByHero(hid); + let suitStars: number[] = []; + for(let equipId of dicEquipSuit.equips) { + let equip = ePlace.find(cur => cur.equipId == equipId); + suitStars.push(equip? equip.star: 0); + } + let minStar = Math.min(...suitStars); + + let seids: number[] = []; + for(let { star, seid } of dicEquipSuit.effect) { + if(minStar >= star) seids.push(seid); + } + + let { ratioUp } = this.addSeidEffect(seids); + for(let [attrId, val] of ratioUp) { + let heroAttr = this.getHeroAttrByHidAndId(hid, attrId); + heroAttr.equipSuit = val; + } + } + + // 天晶 + public setJewel(hid: number, eplaceId: number, stones: Stone[], jewel: JewelType) { + this.clearEquipAttrByHidAndEplace(hid, eplaceId, 'jewel'); + let seids: number[] = []; + if(jewel) { + for(let { id, seid, rand } of jewel.randSe) { + if(this.isRandSeUnLock(jewel.id, id, stones)) { + seids.push(seid, rand); + } + } + } + let { ratioUp } = this.addSeidEffect(seids); + for(let [attrId, val] of ratioUp) { + let equipAttr = this.getEquipAttrByHidAndId(hid, eplaceId, attrId); + let heroAttr = this.getHeroAttrByHidAndId(hid, attrId); + heroAttr.jewel += val - equipAttr.jewel; + equipAttr.jewel = val; + } + } + + private 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; + } + + // 地玉 + public setStone(hid: number, eplaceId: number, stones: Stone[]) { + this.clearEquipAttrByHidAndEplace(hid, eplaceId, 'stone'); + for(let { stone } of stones) { + let dicStone = gameData.stone.get(stone); + if(dicStone) { + for(let { id, num } of dicStone.attribute) { + let equipAttr = this.getEquipAttrByHidAndId(hid, eplaceId, id); + let heroAttr = this.getHeroAttrByHidAndId(hid, id); + heroAttr.stone += num - equipAttr.stone; + equipAttr.stone = num; + } + } + } + } + + // 爵位 public setTitle(title: number) { + this.clearRoleAttr('title'); let dicTitle = gameData.title.get(title)||{ mainAttrValue: new Map(), assiAttrValue: new Map() }; for(let [attrId, value] of dicTitle.mainAttrValue) { let globalAttr = this.getGlobalAttrById(attrId); @@ -436,6 +634,7 @@ export class CalCe { // 神像相关 public setTeraph(teraphs: Teraph[]) { + this.clearRoleAttr('teraph'); let teraphOfAttrId = new Map(); for(let teraph of teraphs) { for(let [attrId, value] of teraph.attr) { // 主属性 @@ -454,6 +653,7 @@ export class CalCe { // 名将谱 public setScroll(hid: number, scrollStar: number, scrollQuality: number, scrollColorStar: number) { + this.clearScrollAttr(hid); let dicHero =gameData.hero.get(hid); let dicHeroScroll = getScollByStar(dicHero.quality, scrollStar, scrollQuality, scrollColorStar); @@ -467,7 +667,7 @@ export class CalCe { // 百家学宫 public setSchool(isPutOn: boolean, hid: number, schoolId: number, star: number, colorStar: number, quality: number) { - + this.clearSchoolAttr(hid); let dicSchool = gameData.school.get(schoolId); let dicSchoolRate = getSchoolRateByStar(star, colorStar, quality); @@ -651,15 +851,19 @@ class GlobalSubAttr extends GlobalAllAttr { abstract class HeroAllAttr { hid: number; attrId: number; - base: number = 0; - job: number = 0; - starUp: number = 0; - connect: number = 0; - favour: number = 0; - talent: number = 0; - equip: number = 0; - equipUp: number = 0; - equipStone: number = 0; + mainBase: number = 0; // hp1,武将基础属性(dic_zyz_hero的hp) + subBase: number = 0; // attr1,职业基础(dic_zyz_job的baseSubAttr字段) + job: number = 0; // hp1 & attr2, 职业属性(dic_zyz_job的attr) + starUp: number = 0; // hp2, 角色升星成长(dic_zyz_hero_star的hp或dic_zyz_hero_wake的hp) + connect: number = 0; // hp3, 角色羁绊固定值(dic_zyz_friend_ship的attribute) + favour: number = 0; // hp4, 声望加成(dic_zyz_friend_ship_level的add) + talent: number = 0; // hp5 & attr3, 天赋树百分比加成(dic_zyz_hero_talent的levelSeid,然后对应到dic_zyz_se) + equipQuality: number = 0; // hp6, 装备品质基础值(dic_zyz_equipQuality的attribute) + equipStrength: number = 0; // hp7, 装备强化值(dic_zyz_equipStrenthAttr的attr) + equipStar: number = 0; // hp8 & attr9,装备升星(dic_zyz_equipStar的mainAttr和subAttr) + equipSuit: number = 0; // hp8,套装(dic_zyz_equipSuit的effect,然后对应dic_zyz_se) + jewel: number = 0; // hp9 & attr7,天晶随机属性值(jewel的ranSe,对应dic_zyz_randomEffectPool) + stone: number = 0; // hp10, 地玉增加的固定值(dic_zyz_stone的attribute) constructor(hid: number, attrId: number, ) { this.hid = hid; @@ -685,7 +889,7 @@ class HeroMainAttr extends HeroAllAttr { if(value != undefined) { switch(i) { case HERO_MAIN_ATTR_INDEX.BASE: - this.base = value; break; + this.mainBase = value; break; case HERO_MAIN_ATTR_INDEX.JOB: this.job = value; break; case HERO_MAIN_ATTR_INDEX.STAR_UP: @@ -696,12 +900,18 @@ class HeroMainAttr extends HeroAllAttr { this.favour = value; break; case HERO_MAIN_ATTR_INDEX.TALENT: this.talent = value; break; - case HERO_MAIN_ATTR_INDEX.EQUIP: - this.equip = value; break; - case HERO_MAIN_ATTR_INDEX.EQUIP_UP: - this.equipUp = value; break; - case HERO_MAIN_ATTR_INDEX.EQUIP_STONE: - this.equipStone = value; break; + case HERO_MAIN_ATTR_INDEX.EQUIP_QUALITY: + this.equipQuality = value; break; + case HERO_MAIN_ATTR_INDEX.EQUIP_STRENGTH: + this.equipStrength = value; break; + case HERO_MAIN_ATTR_INDEX.EQUIP_STAR: + this.equipStar = value; break; + case HERO_MAIN_ATTR_INDEX.EQUIP_SUIT: + this.equipSuit = value; break; + case HERO_MAIN_ATTR_INDEX.JEWEL: + this.jewel = value; break; + case HERO_MAIN_ATTR_INDEX.STONE: + this.stone = value; break; } } } @@ -712,7 +922,7 @@ class HeroMainAttr extends HeroAllAttr { for(let i = HERO_MAIN_ATTR_INDEX.START; i < HERO_MAIN_ATTR_INDEX.END; i++) { switch(i) { case HERO_MAIN_ATTR_INDEX.BASE: - values.push(this.base); + values.push(this.mainBase); break; case HERO_MAIN_ATTR_INDEX.JOB: values.push(this.job); @@ -729,14 +939,23 @@ class HeroMainAttr extends HeroAllAttr { case HERO_MAIN_ATTR_INDEX.TALENT: values.push(this.talent); break; - case HERO_MAIN_ATTR_INDEX.EQUIP: - values.push(this.equip); + case HERO_MAIN_ATTR_INDEX.EQUIP_QUALITY: + values.push(this.equipQuality); break; - case HERO_MAIN_ATTR_INDEX.EQUIP_UP: - values.push(this.equipUp); + case HERO_MAIN_ATTR_INDEX.EQUIP_STRENGTH: + values.push(this.equipStrength); break; - case HERO_MAIN_ATTR_INDEX.EQUIP_STONE: - values.push(this.equipStone); + case HERO_MAIN_ATTR_INDEX.EQUIP_STAR: + values.push(this.equipStar); + break; + case HERO_MAIN_ATTR_INDEX.EQUIP_SUIT: + values.push(this.equipSuit); + break; + case HERO_MAIN_ATTR_INDEX.JEWEL: + values.push(this.jewel); + break; + case HERO_MAIN_ATTR_INDEX.STONE: + values.push(this.stone); break; } } @@ -751,13 +970,15 @@ class HeroSubAttr extends HeroAllAttr { if(value != undefined) { switch(i) { case HERO_SUB_ATTR_INDEX.BASE: - this.base = value; break; + this.subBase = value; break; case HERO_SUB_ATTR_INDEX.JOB: this.job = value; break; case HERO_SUB_ATTR_INDEX.TALENT: this.talent = value; break; - case HERO_SUB_ATTR_INDEX.EQUIP: - this.equip = value; break; + case HERO_SUB_ATTR_INDEX.JEWEL: + this.jewel = value; break; + case HERO_SUB_ATTR_INDEX.EQUIP_STAR: + this.equipStar = value; break; } } } @@ -768,7 +989,7 @@ class HeroSubAttr extends HeroAllAttr { for(let i = HERO_SUB_ATTR_INDEX.START; i < HERO_SUB_ATTR_INDEX.END; i++) { switch(i) { case HERO_SUB_ATTR_INDEX.BASE: - values.push(this.base); + values.push(this.subBase); break; case HERO_SUB_ATTR_INDEX.JOB: values.push(this.job); @@ -776,8 +997,11 @@ class HeroSubAttr extends HeroAllAttr { case HERO_SUB_ATTR_INDEX.TALENT: values.push(this.talent); break; - case HERO_SUB_ATTR_INDEX.EQUIP: - values.push(this.equip); + case HERO_SUB_ATTR_INDEX.JEWEL: + values.push(this.jewel); + break; + case HERO_SUB_ATTR_INDEX.EQUIP_STAR: + values.push(this.equipStar); break; } } @@ -792,14 +1016,12 @@ abstract class EquipAllAttr { equipQuality: number = 0; equipStrengthen: number = 0; equipStar: number = 0; - equipSuit: number = 0; jewel: number = 0; stone: number = 0; - constructor(hid: number, attrId: number, ) { + constructor(hid: number, attrId: number) { this.hid = hid; this.attrId = attrId; - } abstract setByRoleCe(data: AttrCell): void; @@ -825,8 +1047,6 @@ class EquipMainAttr extends EquipAllAttr { this.equipStrengthen = value; break; case EQUIP_MAIN_ATTR_INDEX.EQUIP_STAR: this.equipStar = value; break; - case EQUIP_MAIN_ATTR_INDEX.EQUIP_SUIT: - this.equipSuit = value; break; case EQUIP_MAIN_ATTR_INDEX.JEWEL: this.jewel = value; break; case EQUIP_MAIN_ATTR_INDEX.STONE: @@ -849,9 +1069,6 @@ class EquipMainAttr extends EquipAllAttr { case EQUIP_MAIN_ATTR_INDEX.EQUIP_STAR: values.push(this.equipStar); break; - case EQUIP_MAIN_ATTR_INDEX.EQUIP_SUIT: - values.push(this.equipSuit); - break; case EQUIP_MAIN_ATTR_INDEX.JEWEL: values.push(this.jewel); break; @@ -922,9 +1139,12 @@ enum HERO_MAIN_ATTR_INDEX { CONNECT = 3, // hp3, 角色羁绊固定值(dic_zyz_friend_ship的attribute) FAVOUR = 4, // hp4, 声望加成(dic_zyz_friend_ship_level的add) TALENT = 5, // hp5, 天赋树百分比加成(dic_zyz_hero_talent的levelSeid,然后对应到dic_zyz_se) - EQUIP = 6, // (hp6+hp7)*(1+hp8) 装备,equipAttr加成之后加到这里 - EQUIP_UP = 7, // hp9, 天晶洗练处的主属性百分比加成,equipAttr中计算好加和加入 - EQUIP_STONE = 8, // hp10, 地玉石增加的固定值,equipAttr中计算好和加入 + EQUIP_QUALITY = 6, // hp6, 装备品质基础值(dic_zyz_equipQuality的attribute) + EQUIP_STRENGTH = 7, // hp7, 装备强化值(dic_zyz_equipStrenthAttr的attr) + EQUIP_STAR = 8, // hp8,装备升星(dic_zyz_equipStar的mainAttr) + EQUIP_SUIT = 9, // hp8,套装(dic_zyz_equipSuit的effect,然后对应dic_zyz_se) + JEWEL = 10, // hp9,天晶随机属性值(jewel的ranSe,对应dic_zyz_randomEffectPool) + STONE = 11, // hp10, 地玉增加的固定值(dic_zyz_stone的attribute) END } @@ -933,7 +1153,8 @@ enum HERO_SUB_ATTR_INDEX { BASE = 0, // attr1,系统参数表中所有人 JOB = 1, // attr2, 职业的attr TALENT = 2, // attr3, 天赋树百分比加成 (dic_zyz_hero_talent的levelSeid,然后对应到dic_zyz_se) - EQUIP = 3, // attr7+attr9, 天晶加成和精炼加成,equipAttr加起来 + JEWEL = 3, // attr7, 天晶随机属性(随机出来的值在dic_zyz_randomEffectPool中读最终值) + EQUIP_STAR = 4, // attr9, 精炼次级属性(dic_zyz_equipStar的subAttr) END } @@ -942,15 +1163,14 @@ enum EQUIP_MAIN_ATTR_INDEX { EQUIP_QUALITY = 0, // hp6, 装备升品基础值加成(dic_zyz_equipQuality) EQUIP_STRENGTH = 1,// hp7, 装备强化值(需改表,改为键值对) EQUIP_STAR = 2, // hp8, 装备(dic_zyz_equipStar) - EQUIP_SUIT = 3, // hp8, 装备套装加成(dic_zyz_equipSuit) - JEWEL = 4, // hp9, 天晶洗练出的主属性百分比加成,equipAttr加起来 - STONE = 5, // hp10,地玉石增加的固定值,equipAttr加起来 + JEWEL = 3, // hp9, 天晶洗练出的主属性百分比加成,equipAttr加起来 + STONE = 4, // hp10,地玉石增加的固定值,equipAttr加起来 END } enum EQUIP_SUB_ATTR_INDEX { START, JEWEL = 0, // attr7, 天晶随机属性(随机出来的值在dic_zyz_randomEffectPool中读最终值) - EQUIP_STAR = 1, // attr8, 精炼次级属性(dic_zyz_equipStar的subAttr) + EQUIP_STAR = 1, // attr9, 精炼次级属性(dic_zyz_equipStar的subAttr) END } \ No newline at end of file diff --git a/shared/consts/constModules/sysConst.ts b/shared/consts/constModules/sysConst.ts index 8d715bee7..c544a9d8e 100644 --- a/shared/consts/constModules/sysConst.ts +++ b/shared/consts/constModules/sysConst.ts @@ -540,6 +540,7 @@ export const FILENAME = { DIC_STONE: 'dic_zyz_stone', DIC_JEWEL_CONDITION: 'dic_zyz_jewel_condition', DIC_MAIN_STAR_BOX: 'dic_zyz_main_star_reward', + DIC_EQUIP_STRENGTH_ATTR: 'dic_zyz_equipStrengthAttr', } export const WAR_RELATE_TABLES = [ diff --git a/shared/db/Hero.ts b/shared/db/Hero.ts index 4bbbae9a0..825eb8687 100644 --- a/shared/db/Hero.ts +++ b/shared/db/Hero.ts @@ -111,7 +111,7 @@ export class EPlace { @prop({ required: true }) equipId: number; @prop({ required: true }) - lv: number = 1; + lv: number = 0; @prop({ required: true }) quality: number = 1; @prop({ required: true }) diff --git a/shared/pubUtils/data.ts b/shared/pubUtils/data.ts index b0ced450a..45198af9d 100644 --- a/shared/pubUtils/data.ts +++ b/shared/pubUtils/data.ts @@ -103,6 +103,7 @@ import { dicJewelCondition, loadJewelCondition } from './dictionary/DicJewelCond import { dicMainStarBox, dicMainStarBoxByChapter, loadMainStarBox } from './dictionary/DicMainStarBox'; import { dicHeroTalent, initTalents, loadHeroTalent } from './dictionary/DicHeroTalent'; import { Talent } from "../db/Hero"; +import { dicEquipStrengthAttr, loadEquipStrengthAttr } from './dictionary/DicEquipStrengthAttr'; export const gameData = { daily: dicDaily, @@ -257,6 +258,7 @@ export const gameData = { heroTalent: dicHeroTalent, initTalents: initTalents, talentPointOfJob: talentPointOfJob, + equipStrengthAttr: dicEquipStrengthAttr }; // 在此提供一些原先在gamedata中提供的方法,以便更方便获取gameData数据 @@ -882,6 +884,11 @@ export function getHeroInitTalent(skinId: number) { return ids.map(id => (new Talent(id))); } +export function getEquipStrenthenAttr(equipId: number, lv: number) { + let result = gameData.equipStrengthAttr.get(`${equipId}_${lv}`); + return result +} + // 初始加载 function initDatas() { parseDicParam(); @@ -1049,6 +1056,7 @@ function loadDatas() { loadJewelCondition(); loadMainStarBox(); loadHeroTalent(); + loadEquipStrengthAttr(); } // 重载dicParam diff --git a/shared/pubUtils/dictionary/DicEquipStrengthAttr.ts b/shared/pubUtils/dictionary/DicEquipStrengthAttr.ts new file mode 100644 index 000000000..cca1f991a --- /dev/null +++ b/shared/pubUtils/dictionary/DicEquipStrengthAttr.ts @@ -0,0 +1,39 @@ +// 装备强化表 +import { readFileAndParse, parseGoodStr, decodeArrayListStr } from '../util' +import { FILENAME } from '../../consts' + +export interface DicEquipStrengthAttr { + // id + readonly id: number; + // 装备id + readonly equipId: number; + // 等级 + readonly lv: number; + // 属性 + readonly attr: {id: number, num: number}[]; +} + +export const dicEquipStrengthAttr = new Map(); +export function loadEquipStrengthAttr() { + dicEquipStrengthAttr.clear(); + let arr = readFileAndParse(FILENAME.DIC_EQUIP_STRENGTH_ATTR); + + arr.forEach(o => { + o.attr = parseAttr(o.attr); + dicEquipStrengthAttr.set(`${o.equipId}_${o.lv}`, o); + }); + arr = undefined; +} + +function parseAttr(str: string) { + let result = new Array<{id: number, num: number}>(); + if(!str) return result; + let decodeArr = decodeArrayListStr(str); + for(let [id, num] of decodeArr) { + if(isNaN(parseInt(id)) || isNaN(parseInt(num))) { + throw new Error('data table format wrong'); + } + result.push({id: parseInt(id), num: parseInt(num)}); + } + return result +} \ No newline at end of file diff --git a/shared/resource/jsons/dic_zyz_equip.json b/shared/resource/jsons/dic_zyz_equip.json index 2599bdd9d..3334d80f4 100644 --- a/shared/resource/jsons/dic_zyz_equip.json +++ b/shared/resource/jsons/dic_zyz_equip.json @@ -5,8 +5,6 @@ "jobClass": 1, "eplaceId": 1, "suitId": 1, - "attribute": "2&10", - "attributeUp": "2&10", "composeMaterial": "50001&2", "imageId": "qingtongjian&bintiejian&wenshijian&jinggangjian&songwenjian" }, @@ -16,8 +14,6 @@ "jobClass": 1, "eplaceId": 2, "suitId": 1, - "attribute": "4&20", - "attributeUp": "4&20", "composeMaterial": "50001&2", "imageId": "qingtongjian&bintiejian&wenshijian&jinggangjian&songwenjian" }, @@ -27,8 +23,6 @@ "jobClass": 1, "eplaceId": 3, "suitId": 1, - "attribute": "5&20", - "attributeUp": "5&20", "composeMaterial": "50001&2", "imageId": "qingtongjian&bintiejian&wenshijian&jinggangjian&songwenjian" }, @@ -38,8 +32,6 @@ "jobClass": 1, "eplaceId": 4, "suitId": 1, - "attribute": "1&50", - "attributeUp": "1&50", "composeMaterial": "50001&2", "imageId": "qingtongjian&bintiejian&wenshijian&jinggangjian&songwenjian" }, @@ -49,8 +41,6 @@ "jobClass": 2, "eplaceId": 1, "suitId": 2, - "attribute": "2&10", - "attributeUp": "2&10", "composeMaterial": "50001&2", "imageId": "qingtongjian&bintiejian&wenshijian&jinggangjian&songwenjian" }, @@ -60,8 +50,6 @@ "jobClass": 2, "eplaceId": 2, "suitId": 2, - "attribute": "4&20", - "attributeUp": "4&20", "composeMaterial": "50001&2", "imageId": "qingtongjian&bintiejian&wenshijian&jinggangjian&songwenjian" }, @@ -71,8 +59,6 @@ "jobClass": 2, "eplaceId": 3, "suitId": 2, - "attribute": "5&20", - "attributeUp": "5&20", "composeMaterial": "50001&2", "imageId": "qingtongjian&bintiejian&wenshijian&jinggangjian&songwenjian" }, @@ -82,8 +68,6 @@ "jobClass": 2, "eplaceId": 4, "suitId": 2, - "attribute": "1&50", - "attributeUp": "1&50", "composeMaterial": "50001&2", "imageId": "qingtongjian&bintiejian&wenshijian&jinggangjian&songwenjian" }, @@ -93,8 +77,6 @@ "jobClass": 3, "eplaceId": 1, "suitId": 3, - "attribute": "2&10", - "attributeUp": "2&10", "composeMaterial": "50001&2", "imageId": "qingtongjian&bintiejian&wenshijian&jinggangjian&songwenjian" }, @@ -104,8 +86,6 @@ "jobClass": 3, "eplaceId": 2, "suitId": 3, - "attribute": "4&20", - "attributeUp": "4&20", "composeMaterial": "50001&2", "imageId": "qingtongjian&bintiejian&wenshijian&jinggangjian&songwenjian" }, @@ -115,8 +95,6 @@ "jobClass": 3, "eplaceId": 3, "suitId": 3, - "attribute": "5&20", - "attributeUp": "5&20", "composeMaterial": "50001&2", "imageId": "qingtongjian&bintiejian&wenshijian&jinggangjian&songwenjian" }, @@ -126,8 +104,6 @@ "jobClass": 3, "eplaceId": 4, "suitId": 3, - "attribute": "1&50", - "attributeUp": "1&50", "composeMaterial": "50001&2", "imageId": "qingtongjian&bintiejian&wenshijian&jinggangjian&songwenjian" }, @@ -137,8 +113,6 @@ "jobClass": 4, "eplaceId": 1, "suitId": 4, - "attribute": "2&10", - "attributeUp": "2&10", "composeMaterial": "50001&2", "imageId": "qingtongjian&bintiejian&wenshijian&jinggangjian&songwenjian" }, @@ -148,8 +122,6 @@ "jobClass": 4, "eplaceId": 2, "suitId": 4, - "attribute": "4&20", - "attributeUp": "4&20", "composeMaterial": "50001&2", "imageId": "qingtongjian&bintiejian&wenshijian&jinggangjian&songwenjian" }, @@ -159,8 +131,6 @@ "jobClass": 4, "eplaceId": 3, "suitId": 4, - "attribute": "5&20", - "attributeUp": "5&20", "composeMaterial": "50001&2", "imageId": "qingtongjian&bintiejian&wenshijian&jinggangjian&songwenjian" }, @@ -170,8 +140,6 @@ "jobClass": 4, "eplaceId": 4, "suitId": 4, - "attribute": "1&50", - "attributeUp": "1&50", "composeMaterial": "50001&2", "imageId": "qingtongjian&bintiejian&wenshijian&jinggangjian&songwenjian" }, @@ -181,8 +149,6 @@ "jobClass": 5, "eplaceId": 1, "suitId": 5, - "attribute": "2&10", - "attributeUp": "2&10", "composeMaterial": "50001&2", "imageId": "qingtongjian&bintiejian&wenshijian&jinggangjian&songwenjian" }, @@ -192,8 +158,6 @@ "jobClass": 5, "eplaceId": 2, "suitId": 5, - "attribute": "4&20", - "attributeUp": "4&20", "composeMaterial": "50001&2", "imageId": "qingtongjian&bintiejian&wenshijian&jinggangjian&songwenjian" }, @@ -203,8 +167,6 @@ "jobClass": 5, "eplaceId": 3, "suitId": 5, - "attribute": "5&20", - "attributeUp": "5&20", "composeMaterial": "50001&2", "imageId": "qingtongjian&bintiejian&wenshijian&jinggangjian&songwenjian" }, @@ -214,8 +176,6 @@ "jobClass": 5, "eplaceId": 4, "suitId": 5, - "attribute": "1&50", - "attributeUp": "1&50", "composeMaterial": "50001&2", "imageId": "qingtongjian&bintiejian&wenshijian&jinggangjian&songwenjian" }, @@ -225,8 +185,6 @@ "jobClass": 6, "eplaceId": 1, "suitId": 6, - "attribute": "2&10", - "attributeUp": "2&10", "composeMaterial": "50001&2", "imageId": "qingtongjian&bintiejian&wenshijian&jinggangjian&songwenjian" }, @@ -236,8 +194,6 @@ "jobClass": 6, "eplaceId": 2, "suitId": 6, - "attribute": "4&20", - "attributeUp": "4&20", "composeMaterial": "50001&2", "imageId": "qingtongjian&bintiejian&wenshijian&jinggangjian&songwenjian" }, @@ -247,8 +203,6 @@ "jobClass": 6, "eplaceId": 3, "suitId": 6, - "attribute": "5&20", - "attributeUp": "5&20", "composeMaterial": "50001&2", "imageId": "qingtongjian&bintiejian&wenshijian&jinggangjian&songwenjian" }, @@ -258,8 +212,6 @@ "jobClass": 6, "eplaceId": 4, "suitId": 6, - "attribute": "1&50", - "attributeUp": "1&50", "composeMaterial": "50001&2", "imageId": "qingtongjian&bintiejian&wenshijian&jinggangjian&songwenjian" }, @@ -269,8 +221,6 @@ "jobClass": 7, "eplaceId": 1, "suitId": 7, - "attribute": "2&10", - "attributeUp": "2&10", "composeMaterial": "50001&2", "imageId": "qingtongjian&bintiejian&wenshijian&jinggangjian&songwenjian" }, @@ -280,8 +230,6 @@ "jobClass": 7, "eplaceId": 2, "suitId": 7, - "attribute": "4&20", - "attributeUp": "4&20", "composeMaterial": "50001&2", "imageId": "qingtongjian&bintiejian&wenshijian&jinggangjian&songwenjian" }, @@ -291,8 +239,6 @@ "jobClass": 7, "eplaceId": 3, "suitId": 7, - "attribute": "5&20", - "attributeUp": "5&20", "composeMaterial": "50001&2", "imageId": "qingtongjian&bintiejian&wenshijian&jinggangjian&songwenjian" }, @@ -302,8 +248,6 @@ "jobClass": 7, "eplaceId": 4, "suitId": 7, - "attribute": "1&50", - "attributeUp": "1&50", "composeMaterial": "50001&2", "imageId": "qingtongjian&bintiejian&wenshijian&jinggangjian&songwenjian" } diff --git a/shared/resource/jsons/dic_zyz_equipStrengthAttr.json b/shared/resource/jsons/dic_zyz_equipStrengthAttr.json new file mode 100644 index 000000000..78a2f5324 --- /dev/null +++ b/shared/resource/jsons/dic_zyz_equipStrengthAttr.json @@ -0,0 +1,14002 @@ +[ + { + "id": 1, + "lv": 1, + "attr": "2&10" + }, + { + "id": 1, + "lv": 2, + "attr": "2&11" + }, + { + "id": 1, + "lv": 3, + "attr": "2&12" + }, + { + "id": 1, + "lv": 4, + "attr": "2&13" + }, + { + "id": 1, + "lv": 5, + "attr": "2&14" + }, + { + "id": 1, + "lv": 6, + "attr": "2&15" + }, + { + "id": 1, + "lv": 7, + "attr": "2&16" + }, + { + "id": 1, + "lv": 8, + "attr": "2&17" + }, + { + "id": 1, + "lv": 9, + "attr": "2&18" + }, + { + "id": 1, + "lv": 10, + "attr": "2&19" + }, + { + "id": 1, + "lv": 11, + "attr": "2&20" + }, + { + "id": 1, + "lv": 12, + "attr": "2&21" + }, + { + "id": 1, + "lv": 13, + "attr": "2&22" + }, + { + "id": 1, + "lv": 14, + "attr": "2&23" + }, + { + "id": 1, + "lv": 15, + "attr": "2&24" + }, + { + "id": 1, + "lv": 16, + "attr": "2&25" + }, + { + "id": 1, + "lv": 17, + "attr": "2&26" + }, + { + "id": 1, + "lv": 18, + "attr": "2&27" + }, + { + "id": 1, + "lv": 19, + "attr": "2&28" + }, + { + "id": 1, + "lv": 20, + "attr": "2&29" + }, + { + "id": 1, + "lv": 21, + "attr": "2&30" + }, + { + "id": 1, + "lv": 22, + "attr": "2&31" + }, + { + "id": 1, + "lv": 23, + "attr": "2&32" + }, + { + "id": 1, + "lv": 24, + "attr": "2&33" + }, + { + "id": 1, + "lv": 25, + "attr": "2&34" + }, + { + "id": 1, + "lv": 26, + "attr": "2&35" + }, + { + "id": 1, + "lv": 27, + "attr": "2&36" + }, + { + "id": 1, + "lv": 28, + "attr": "2&37" + }, + { + "id": 1, + "lv": 29, + "attr": "2&38" + }, + { + "id": 1, + "lv": 30, + "attr": "2&39" + }, + { + "id": 1, + "lv": 31, + "attr": "2&40" + }, + { + "id": 1, + "lv": 32, + "attr": "2&41" + }, + { + "id": 1, + "lv": 33, + "attr": "2&42" + }, + { + "id": 1, + "lv": 34, + "attr": "2&43" + }, + { + "id": 1, + "lv": 35, + "attr": "2&44" + }, + { + "id": 1, + "lv": 36, + "attr": "2&45" + }, + { + "id": 1, + "lv": 37, + "attr": "2&46" + }, + { + "id": 1, + "lv": 38, + "attr": "2&47" + }, + { + "id": 1, + "lv": 39, + "attr": "2&48" + }, + { + "id": 1, + "lv": 40, + "attr": "2&49" + }, + { + "id": 1, + "lv": 41, + "attr": "2&50" + }, + { + "id": 1, + "lv": 42, + "attr": "2&51" + }, + { + "id": 1, + "lv": 43, + "attr": "2&52" + }, + { + "id": 1, + "lv": 44, + "attr": "2&53" + }, + { + "id": 1, + "lv": 45, + "attr": "2&54" + }, + { + "id": 1, + "lv": 46, + "attr": "2&55" + }, + { + "id": 1, + "lv": 47, + "attr": "2&56" + }, + { + "id": 1, + "lv": 48, + "attr": "2&57" + }, + { + "id": 1, + "lv": 49, + "attr": "2&58" + }, + { + "id": 1, + "lv": 50, + "attr": "2&59" + }, + { + "id": 1, + "lv": 51, + "attr": "2&60" + }, + { + "id": 1, + "lv": 52, + "attr": "2&61" + }, + { + "id": 1, + "lv": 53, + "attr": "2&62" + }, + { + "id": 1, + "lv": 54, + "attr": "2&63" + }, + { + "id": 1, + "lv": 55, + "attr": "2&64" + }, + { + "id": 1, + "lv": 56, + "attr": "2&65" + }, + { + "id": 1, + "lv": 57, + "attr": "2&66" + }, + { + "id": 1, + "lv": 58, + "attr": "2&67" + }, + { + "id": 1, + "lv": 59, + "attr": "2&68" + }, + { + "id": 1, + "lv": 60, + "attr": "2&69" + }, + { + "id": 1, + "lv": 61, + "attr": "2&70" + }, + { + "id": 1, + "lv": 62, + "attr": "2&71" + }, + { + "id": 1, + "lv": 63, + "attr": "2&72" + }, + { + "id": 1, + "lv": 64, + "attr": "2&73" + }, + { + "id": 1, + "lv": 65, + "attr": "2&74" + }, + { + "id": 1, + "lv": 66, + "attr": "2&75" + }, + { + "id": 1, + "lv": 67, + "attr": "2&76" + }, + { + "id": 1, + "lv": 68, + "attr": "2&77" + }, + { + "id": 1, + "lv": 69, + "attr": "2&78" + }, + { + "id": 1, + "lv": 70, + "attr": "2&79" + }, + { + "id": 1, + "lv": 71, + "attr": "2&80" + }, + { + "id": 1, + "lv": 72, + "attr": "2&81" + }, + { + "id": 1, + "lv": 73, + "attr": "2&82" + }, + { + "id": 1, + "lv": 74, + "attr": "2&83" + }, + { + "id": 1, + "lv": 75, + "attr": "2&84" + }, + { + "id": 1, + "lv": 76, + "attr": "2&85" + }, + { + "id": 1, + "lv": 77, + "attr": "2&86" + }, + { + "id": 1, + "lv": 78, + "attr": "2&87" + }, + { + "id": 1, + "lv": 79, + "attr": "2&88" + }, + { + "id": 1, + "lv": 80, + "attr": "2&89" + }, + { + "id": 1, + "lv": 81, + "attr": "2&90" + }, + { + "id": 1, + "lv": 82, + "attr": "2&91" + }, + { + "id": 1, + "lv": 83, + "attr": "2&92" + }, + { + "id": 1, + "lv": 84, + "attr": "2&93" + }, + { + "id": 1, + "lv": 85, + "attr": "2&94" + }, + { + "id": 1, + "lv": 86, + "attr": "2&95" + }, + { + "id": 1, + "lv": 87, + "attr": "2&96" + }, + { + "id": 1, + "lv": 88, + "attr": "2&97" + }, + { + "id": 1, + "lv": 89, + "attr": "2&98" + }, + { + "id": 1, + "lv": 90, + "attr": "2&99" + }, + { + "id": 1, + "lv": 91, + "attr": "2&100" + }, + { + "id": 1, + "lv": 92, + "attr": "2&101" + }, + { + "id": 1, + "lv": 93, + "attr": "2&102" + }, + { + "id": 1, + "lv": 94, + "attr": "2&103" + }, + { + "id": 1, + "lv": 95, + "attr": "2&104" + }, + { + "id": 1, + "lv": 96, + "attr": "2&105" + }, + { + "id": 1, + "lv": 97, + "attr": "2&106" + }, + { + "id": 1, + "lv": 98, + "attr": "2&107" + }, + { + "id": 1, + "lv": 99, + "attr": "2&108" + }, + { + "id": 1, + "lv": 100, + "attr": "2&109" + }, + { + "id": 2, + "lv": 1, + "attr": "4&20" + }, + { + "id": 2, + "lv": 2, + "attr": "4&21" + }, + { + "id": 2, + "lv": 3, + "attr": "4&22" + }, + { + "id": 2, + "lv": 4, + "attr": "4&23" + }, + { + "id": 2, + "lv": 5, + "attr": "4&24" + }, + { + "id": 2, + "lv": 6, + "attr": "4&25" + }, + { + "id": 2, + "lv": 7, + "attr": "4&26" + }, + { + "id": 2, + "lv": 8, + "attr": "4&27" + }, + { + "id": 2, + "lv": 9, + "attr": "4&28" + }, + { + "id": 2, + "lv": 10, + "attr": "4&29" + }, + { + "id": 2, + "lv": 11, + "attr": "4&30" + }, + { + "id": 2, + "lv": 12, + "attr": "4&31" + }, + { + "id": 2, + "lv": 13, + "attr": "4&32" + }, + { + "id": 2, + "lv": 14, + "attr": "4&33" + }, + { + "id": 2, + "lv": 15, + "attr": "4&34" + }, + { + "id": 2, + "lv": 16, + "attr": "4&35" + }, + { + "id": 2, + "lv": 17, + "attr": "4&36" + }, + { + "id": 2, + "lv": 18, + "attr": "4&37" + }, + { + "id": 2, + "lv": 19, + "attr": "4&38" + }, + { + "id": 2, + "lv": 20, + "attr": "4&39" + }, + { + "id": 2, + "lv": 21, + "attr": "4&40" + }, + { + "id": 2, + "lv": 22, + "attr": "4&41" + }, + { + "id": 2, + "lv": 23, + "attr": "4&42" + }, + { + "id": 2, + "lv": 24, + "attr": "4&43" + }, + { + "id": 2, + "lv": 25, + "attr": "4&44" + }, + { + "id": 2, + "lv": 26, + "attr": "4&45" + }, + { + "id": 2, + "lv": 27, + "attr": "4&46" + }, + { + "id": 2, + "lv": 28, + "attr": "4&47" + }, + { + "id": 2, + "lv": 29, + "attr": "4&48" + }, + { + "id": 2, + "lv": 30, + "attr": "4&49" + }, + { + "id": 2, + "lv": 31, + "attr": "4&50" + }, + { + "id": 2, + "lv": 32, + "attr": "4&51" + }, + { + "id": 2, + "lv": 33, + "attr": "4&52" + }, + { + "id": 2, + "lv": 34, + "attr": "4&53" + }, + { + "id": 2, + "lv": 35, + "attr": "4&54" + }, + { + "id": 2, + "lv": 36, + "attr": "4&55" + }, + { + "id": 2, + "lv": 37, + "attr": "4&56" + }, + { + "id": 2, + "lv": 38, + "attr": "4&57" + }, + { + "id": 2, + "lv": 39, + "attr": "4&58" + }, + { + "id": 2, + "lv": 40, + "attr": "4&59" + }, + { + "id": 2, + "lv": 41, + "attr": "4&60" + }, + { + "id": 2, + "lv": 42, + "attr": "4&61" + }, + { + "id": 2, + "lv": 43, + "attr": "4&62" + }, + { + "id": 2, + "lv": 44, + "attr": "4&63" + }, + { + "id": 2, + "lv": 45, + "attr": "4&64" + }, + { + "id": 2, + "lv": 46, + "attr": "4&65" + }, + { + "id": 2, + "lv": 47, + "attr": "4&66" + }, + { + "id": 2, + "lv": 48, + "attr": "4&67" + }, + { + "id": 2, + "lv": 49, + "attr": "4&68" + }, + { + "id": 2, + "lv": 50, + "attr": "4&69" + }, + { + "id": 2, + "lv": 51, + "attr": "4&70" + }, + { + "id": 2, + "lv": 52, + "attr": "4&71" + }, + { + "id": 2, + "lv": 53, + "attr": "4&72" + }, + { + "id": 2, + "lv": 54, + "attr": "4&73" + }, + { + "id": 2, + "lv": 55, + "attr": "4&74" + }, + { + "id": 2, + "lv": 56, + "attr": "4&75" + }, + { + "id": 2, + "lv": 57, + "attr": "4&76" + }, + { + "id": 2, + "lv": 58, + "attr": "4&77" + }, + { + "id": 2, + "lv": 59, + "attr": "4&78" + }, + { + "id": 2, + "lv": 60, + "attr": "4&79" + }, + { + "id": 2, + "lv": 61, + "attr": "4&80" + }, + { + "id": 2, + "lv": 62, + "attr": "4&81" + }, + { + "id": 2, + "lv": 63, + "attr": "4&82" + }, + { + "id": 2, + "lv": 64, + "attr": "4&83" + }, + { + "id": 2, + "lv": 65, + "attr": "4&84" + }, + { + "id": 2, + "lv": 66, + "attr": "4&85" + }, + { + "id": 2, + "lv": 67, + "attr": "4&86" + }, + { + "id": 2, + "lv": 68, + "attr": "4&87" + }, + { + "id": 2, + "lv": 69, + "attr": "4&88" + }, + { + "id": 2, + "lv": 70, + "attr": "4&89" + }, + { + "id": 2, + "lv": 71, + "attr": "4&90" + }, + { + "id": 2, + "lv": 72, + "attr": "4&91" + }, + { + "id": 2, + "lv": 73, + "attr": "4&92" + }, + { + "id": 2, + "lv": 74, + "attr": "4&93" + }, + { + "id": 2, + "lv": 75, + "attr": "4&94" + }, + { + "id": 2, + "lv": 76, + "attr": "4&95" + }, + { + "id": 2, + "lv": 77, + "attr": "4&96" + }, + { + "id": 2, + "lv": 78, + "attr": "4&97" + }, + { + "id": 2, + "lv": 79, + "attr": "4&98" + }, + { + "id": 2, + "lv": 80, + "attr": "4&99" + }, + { + "id": 2, + "lv": 81, + "attr": "4&100" + }, + { + "id": 2, + "lv": 82, + "attr": "4&101" + }, + { + "id": 2, + "lv": 83, + "attr": "4&102" + }, + { + "id": 2, + "lv": 84, + "attr": "4&103" + }, + { + "id": 2, + "lv": 85, + "attr": "4&104" + }, + { + "id": 2, + "lv": 86, + "attr": "4&105" + }, + { + "id": 2, + "lv": 87, + "attr": "4&106" + }, + { + "id": 2, + "lv": 88, + "attr": "4&107" + }, + { + "id": 2, + "lv": 89, + "attr": "4&108" + }, + { + "id": 2, + "lv": 90, + "attr": "4&109" + }, + { + "id": 2, + "lv": 91, + "attr": "4&110" + }, + { + "id": 2, + "lv": 92, + "attr": "4&111" + }, + { + "id": 2, + "lv": 93, + "attr": "4&112" + }, + { + "id": 2, + "lv": 94, + "attr": "4&113" + }, + { + "id": 2, + "lv": 95, + "attr": "4&114" + }, + { + "id": 2, + "lv": 96, + "attr": "4&115" + }, + { + "id": 2, + "lv": 97, + "attr": "4&116" + }, + { + "id": 2, + "lv": 98, + "attr": "4&117" + }, + { + "id": 2, + "lv": 99, + "attr": "4&118" + }, + { + "id": 2, + "lv": 100, + "attr": "4&119" + }, + { + "id": 3, + "lv": 1, + "attr": "5&20" + }, + { + "id": 3, + "lv": 2, + "attr": "5&21" + }, + { + "id": 3, + "lv": 3, + "attr": "5&22" + }, + { + "id": 3, + "lv": 4, + "attr": "5&23" + }, + { + "id": 3, + "lv": 5, + "attr": "5&24" + }, + { + "id": 3, + "lv": 6, + "attr": "5&25" + }, + { + "id": 3, + "lv": 7, + "attr": "5&26" + }, + { + "id": 3, + "lv": 8, + "attr": "5&27" + }, + { + "id": 3, + "lv": 9, + "attr": "5&28" + }, + { + "id": 3, + "lv": 10, + "attr": "5&29" + }, + { + "id": 3, + "lv": 11, + "attr": "5&30" + }, + { + "id": 3, + "lv": 12, + "attr": "5&31" + }, + { + "id": 3, + "lv": 13, + "attr": "5&32" + }, + { + "id": 3, + "lv": 14, + "attr": "5&33" + }, + { + "id": 3, + "lv": 15, + "attr": "5&34" + }, + { + "id": 3, + "lv": 16, + "attr": "5&35" + }, + { + "id": 3, + "lv": 17, + "attr": "5&36" + }, + { + "id": 3, + "lv": 18, + "attr": "5&37" + }, + { + "id": 3, + "lv": 19, + "attr": "5&38" + }, + { + "id": 3, + "lv": 20, + "attr": "5&39" + }, + { + "id": 3, + "lv": 21, + "attr": "5&40" + }, + { + "id": 3, + "lv": 22, + "attr": "5&41" + }, + { + "id": 3, + "lv": 23, + "attr": "5&42" + }, + { + "id": 3, + "lv": 24, + "attr": "5&43" + }, + { + "id": 3, + "lv": 25, + "attr": "5&44" + }, + { + "id": 3, + "lv": 26, + "attr": "5&45" + }, + { + "id": 3, + "lv": 27, + "attr": "5&46" + }, + { + "id": 3, + "lv": 28, + "attr": "5&47" + }, + { + "id": 3, + "lv": 29, + "attr": "5&48" + }, + { + "id": 3, + "lv": 30, + "attr": "5&49" + }, + { + "id": 3, + "lv": 31, + "attr": "5&50" + }, + { + "id": 3, + "lv": 32, + "attr": "5&51" + }, + { + "id": 3, + "lv": 33, + "attr": "5&52" + }, + { + "id": 3, + "lv": 34, + "attr": "5&53" + }, + { + "id": 3, + "lv": 35, + "attr": "5&54" + }, + { + "id": 3, + "lv": 36, + "attr": "5&55" + }, + { + "id": 3, + "lv": 37, + "attr": "5&56" + }, + { + "id": 3, + "lv": 38, + "attr": "5&57" + }, + { + "id": 3, + "lv": 39, + "attr": "5&58" + }, + { + "id": 3, + "lv": 40, + "attr": "5&59" + }, + { + "id": 3, + "lv": 41, + "attr": "5&60" + }, + { + "id": 3, + "lv": 42, + "attr": "5&61" + }, + { + "id": 3, + "lv": 43, + "attr": "5&62" + }, + { + "id": 3, + "lv": 44, + "attr": "5&63" + }, + { + "id": 3, + "lv": 45, + "attr": "5&64" + }, + { + "id": 3, + "lv": 46, + "attr": "5&65" + }, + { + "id": 3, + "lv": 47, + "attr": "5&66" + }, + { + "id": 3, + "lv": 48, + "attr": "5&67" + }, + { + "id": 3, + "lv": 49, + "attr": "5&68" + }, + { + "id": 3, + "lv": 50, + "attr": "5&69" + }, + { + "id": 3, + "lv": 51, + "attr": "5&70" + }, + { + "id": 3, + "lv": 52, + "attr": "5&71" + }, + { + "id": 3, + "lv": 53, + "attr": "5&72" + }, + { + "id": 3, + "lv": 54, + "attr": "5&73" + }, + { + "id": 3, + "lv": 55, + "attr": "5&74" + }, + { + "id": 3, + "lv": 56, + "attr": "5&75" + }, + { + "id": 3, + "lv": 57, + "attr": "5&76" + }, + { + "id": 3, + "lv": 58, + "attr": "5&77" + }, + { + "id": 3, + "lv": 59, + "attr": "5&78" + }, + { + "id": 3, + "lv": 60, + "attr": "5&79" + }, + { + "id": 3, + "lv": 61, + "attr": "5&80" + }, + { + "id": 3, + "lv": 62, + "attr": "5&81" + }, + { + "id": 3, + "lv": 63, + "attr": "5&82" + }, + { + "id": 3, + "lv": 64, + "attr": "5&83" + }, + { + "id": 3, + "lv": 65, + "attr": "5&84" + }, + { + "id": 3, + "lv": 66, + "attr": "5&85" + }, + { + "id": 3, + "lv": 67, + "attr": "5&86" + }, + { + "id": 3, + "lv": 68, + "attr": "5&87" + }, + { + "id": 3, + "lv": 69, + "attr": "5&88" + }, + { + "id": 3, + "lv": 70, + "attr": "5&89" + }, + { + "id": 3, + "lv": 71, + "attr": "5&90" + }, + { + "id": 3, + "lv": 72, + "attr": "5&91" + }, + { + "id": 3, + "lv": 73, + "attr": "5&92" + }, + { + "id": 3, + "lv": 74, + "attr": "5&93" + }, + { + "id": 3, + "lv": 75, + "attr": "5&94" + }, + { + "id": 3, + "lv": 76, + "attr": "5&95" + }, + { + "id": 3, + "lv": 77, + "attr": "5&96" + }, + { + "id": 3, + "lv": 78, + "attr": "5&97" + }, + { + "id": 3, + "lv": 79, + "attr": "5&98" + }, + { + "id": 3, + "lv": 80, + "attr": "5&99" + }, + { + "id": 3, + "lv": 81, + "attr": "5&100" + }, + { + "id": 3, + "lv": 82, + "attr": "5&101" + }, + { + "id": 3, + "lv": 83, + "attr": "5&102" + }, + { + "id": 3, + "lv": 84, + "attr": "5&103" + }, + { + "id": 3, + "lv": 85, + "attr": "5&104" + }, + { + "id": 3, + "lv": 86, + "attr": "5&105" + }, + { + "id": 3, + "lv": 87, + "attr": "5&106" + }, + { + "id": 3, + "lv": 88, + "attr": "5&107" + }, + { + "id": 3, + "lv": 89, + "attr": "5&108" + }, + { + "id": 3, + "lv": 90, + "attr": "5&109" + }, + { + "id": 3, + "lv": 91, + "attr": "5&110" + }, + { + "id": 3, + "lv": 92, + "attr": "5&111" + }, + { + "id": 3, + "lv": 93, + "attr": "5&112" + }, + { + "id": 3, + "lv": 94, + "attr": "5&113" + }, + { + "id": 3, + "lv": 95, + "attr": "5&114" + }, + { + "id": 3, + "lv": 96, + "attr": "5&115" + }, + { + "id": 3, + "lv": 97, + "attr": "5&116" + }, + { + "id": 3, + "lv": 98, + "attr": "5&117" + }, + { + "id": 3, + "lv": 99, + "attr": "5&118" + }, + { + "id": 3, + "lv": 100, + "attr": "5&119" + }, + { + "id": 4, + "lv": 1, + "attr": "1&50" + }, + { + "id": 4, + "lv": 2, + "attr": "1&51" + }, + { + "id": 4, + "lv": 3, + "attr": "1&52" + }, + { + "id": 4, + "lv": 4, + "attr": "1&53" + }, + { + "id": 4, + "lv": 5, + "attr": "1&54" + }, + { + "id": 4, + "lv": 6, + "attr": "1&55" + }, + { + "id": 4, + "lv": 7, + "attr": "1&56" + }, + { + "id": 4, + "lv": 8, + "attr": "1&57" + }, + { + "id": 4, + "lv": 9, + "attr": "1&58" + }, + { + "id": 4, + "lv": 10, + "attr": "1&59" + }, + { + "id": 4, + "lv": 11, + "attr": "1&60" + }, + { + "id": 4, + "lv": 12, + "attr": "1&61" + }, + { + "id": 4, + "lv": 13, + "attr": "1&62" + }, + { + "id": 4, + "lv": 14, + "attr": "1&63" + }, + { + "id": 4, + "lv": 15, + "attr": "1&64" + }, + { + "id": 4, + "lv": 16, + "attr": "1&65" + }, + { + "id": 4, + "lv": 17, + "attr": "1&66" + }, + { + "id": 4, + "lv": 18, + "attr": "1&67" + }, + { + "id": 4, + "lv": 19, + "attr": "1&68" + }, + { + "id": 4, + "lv": 20, + "attr": "1&69" + }, + { + "id": 4, + "lv": 21, + "attr": "1&70" + }, + { + "id": 4, + "lv": 22, + "attr": "1&71" + }, + { + "id": 4, + "lv": 23, + "attr": "1&72" + }, + { + "id": 4, + "lv": 24, + "attr": "1&73" + }, + { + "id": 4, + "lv": 25, + "attr": "1&74" + }, + { + "id": 4, + "lv": 26, + "attr": "1&75" + }, + { + "id": 4, + "lv": 27, + "attr": "1&76" + }, + { + "id": 4, + "lv": 28, + "attr": "1&77" + }, + { + "id": 4, + "lv": 29, + "attr": "1&78" + }, + { + "id": 4, + "lv": 30, + "attr": "1&79" + }, + { + "id": 4, + "lv": 31, + "attr": "1&80" + }, + { + "id": 4, + "lv": 32, + "attr": "1&81" + }, + { + "id": 4, + "lv": 33, + "attr": "1&82" + }, + { + "id": 4, + "lv": 34, + "attr": "1&83" + }, + { + "id": 4, + "lv": 35, + "attr": "1&84" + }, + { + "id": 4, + "lv": 36, + "attr": "1&85" + }, + { + "id": 4, + "lv": 37, + "attr": "1&86" + }, + { + "id": 4, + "lv": 38, + "attr": "1&87" + }, + { + "id": 4, + "lv": 39, + "attr": "1&88" + }, + { + "id": 4, + "lv": 40, + "attr": "1&89" + }, + { + "id": 4, + "lv": 41, + "attr": "1&90" + }, + { + "id": 4, + "lv": 42, + "attr": "1&91" + }, + { + "id": 4, + "lv": 43, + "attr": "1&92" + }, + { + "id": 4, + "lv": 44, + "attr": "1&93" + }, + { + "id": 4, + "lv": 45, + "attr": "1&94" + }, + { + "id": 4, + "lv": 46, + "attr": "1&95" + }, + { + "id": 4, + "lv": 47, + "attr": "1&96" + }, + { + "id": 4, + "lv": 48, + "attr": "1&97" + }, + { + "id": 4, + "lv": 49, + "attr": "1&98" + }, + { + "id": 4, + "lv": 50, + "attr": "1&99" + }, + { + "id": 4, + "lv": 51, + "attr": "1&100" + }, + { + "id": 4, + "lv": 52, + "attr": "1&101" + }, + { + "id": 4, + "lv": 53, + "attr": "1&102" + }, + { + "id": 4, + "lv": 54, + "attr": "1&103" + }, + { + "id": 4, + "lv": 55, + "attr": "1&104" + }, + { + "id": 4, + "lv": 56, + "attr": "1&105" + }, + { + "id": 4, + "lv": 57, + "attr": "1&106" + }, + { + "id": 4, + "lv": 58, + "attr": "1&107" + }, + { + "id": 4, + "lv": 59, + "attr": "1&108" + }, + { + "id": 4, + "lv": 60, + "attr": "1&109" + }, + { + "id": 4, + "lv": 61, + "attr": "1&110" + }, + { + "id": 4, + "lv": 62, + "attr": "1&111" + }, + { + "id": 4, + "lv": 63, + "attr": "1&112" + }, + { + "id": 4, + "lv": 64, + "attr": "1&113" + }, + { + "id": 4, + "lv": 65, + "attr": "1&114" + }, + { + "id": 4, + "lv": 66, + "attr": "1&115" + }, + { + "id": 4, + "lv": 67, + "attr": "1&116" + }, + { + "id": 4, + "lv": 68, + "attr": "1&117" + }, + { + "id": 4, + "lv": 69, + "attr": "1&118" + }, + { + "id": 4, + "lv": 70, + "attr": "1&119" + }, + { + "id": 4, + "lv": 71, + "attr": "1&120" + }, + { + "id": 4, + "lv": 72, + "attr": "1&121" + }, + { + "id": 4, + "lv": 73, + "attr": "1&122" + }, + { + "id": 4, + "lv": 74, + "attr": "1&123" + }, + { + "id": 4, + "lv": 75, + "attr": "1&124" + }, + { + "id": 4, + "lv": 76, + "attr": "1&125" + }, + { + "id": 4, + "lv": 77, + "attr": "1&126" + }, + { + "id": 4, + "lv": 78, + "attr": "1&127" + }, + { + "id": 4, + "lv": 79, + "attr": "1&128" + }, + { + "id": 4, + "lv": 80, + "attr": "1&129" + }, + { + "id": 4, + "lv": 81, + "attr": "1&130" + }, + { + "id": 4, + "lv": 82, + "attr": "1&131" + }, + { + "id": 4, + "lv": 83, + "attr": "1&132" + }, + { + "id": 4, + "lv": 84, + "attr": "1&133" + }, + { + "id": 4, + "lv": 85, + "attr": "1&134" + }, + { + "id": 4, + "lv": 86, + "attr": "1&135" + }, + { + "id": 4, + "lv": 87, + "attr": "1&136" + }, + { + "id": 4, + "lv": 88, + "attr": "1&137" + }, + { + "id": 4, + "lv": 89, + "attr": "1&138" + }, + { + "id": 4, + "lv": 90, + "attr": "1&139" + }, + { + "id": 4, + "lv": 91, + "attr": "1&140" + }, + { + "id": 4, + "lv": 92, + "attr": "1&141" + }, + { + "id": 4, + "lv": 93, + "attr": "1&142" + }, + { + "id": 4, + "lv": 94, + "attr": "1&143" + }, + { + "id": 4, + "lv": 95, + "attr": "1&144" + }, + { + "id": 4, + "lv": 96, + "attr": "1&145" + }, + { + "id": 4, + "lv": 97, + "attr": "1&146" + }, + { + "id": 4, + "lv": 98, + "attr": "1&147" + }, + { + "id": 4, + "lv": 99, + "attr": "1&148" + }, + { + "id": 4, + "lv": 100, + "attr": "1&149" + }, + { + "id": 5, + "lv": 1, + "attr": "2&10" + }, + { + "id": 5, + "lv": 2, + "attr": "2&11" + }, + { + "id": 5, + "lv": 3, + "attr": "2&12" + }, + { + "id": 5, + "lv": 4, + "attr": "2&13" + }, + { + "id": 5, + "lv": 5, + "attr": "2&14" + }, + { + "id": 5, + "lv": 6, + "attr": "2&15" + }, + { + "id": 5, + "lv": 7, + "attr": "2&16" + }, + { + "id": 5, + "lv": 8, + "attr": "2&17" + }, + { + "id": 5, + "lv": 9, + "attr": "2&18" + }, + { + "id": 5, + "lv": 10, + "attr": "2&19" + }, + { + "id": 5, + "lv": 11, + "attr": "2&20" + }, + { + "id": 5, + "lv": 12, + "attr": "2&21" + }, + { + "id": 5, + "lv": 13, + "attr": "2&22" + }, + { + "id": 5, + "lv": 14, + "attr": "2&23" + }, + { + "id": 5, + "lv": 15, + "attr": "2&24" + }, + { + "id": 5, + "lv": 16, + "attr": "2&25" + }, + { + "id": 5, + "lv": 17, + "attr": "2&26" + }, + { + "id": 5, + "lv": 18, + "attr": "2&27" + }, + { + "id": 5, + "lv": 19, + "attr": "2&28" + }, + { + "id": 5, + "lv": 20, + "attr": "2&29" + }, + { + "id": 5, + "lv": 21, + "attr": "2&30" + }, + { + "id": 5, + "lv": 22, + "attr": "2&31" + }, + { + "id": 5, + "lv": 23, + "attr": "2&32" + }, + { + "id": 5, + "lv": 24, + "attr": "2&33" + }, + { + "id": 5, + "lv": 25, + "attr": "2&34" + }, + { + "id": 5, + "lv": 26, + "attr": "2&35" + }, + { + "id": 5, + "lv": 27, + "attr": "2&36" + }, + { + "id": 5, + "lv": 28, + "attr": "2&37" + }, + { + "id": 5, + "lv": 29, + "attr": "2&38" + }, + { + "id": 5, + "lv": 30, + "attr": "2&39" + }, + { + "id": 5, + "lv": 31, + "attr": "2&40" + }, + { + "id": 5, + "lv": 32, + "attr": "2&41" + }, + { + "id": 5, + "lv": 33, + "attr": "2&42" + }, + { + "id": 5, + "lv": 34, + "attr": "2&43" + }, + { + "id": 5, + "lv": 35, + "attr": "2&44" + }, + { + "id": 5, + "lv": 36, + "attr": "2&45" + }, + { + "id": 5, + "lv": 37, + "attr": "2&46" + }, + { + "id": 5, + "lv": 38, + "attr": "2&47" + }, + { + "id": 5, + "lv": 39, + "attr": "2&48" + }, + { + "id": 5, + "lv": 40, + "attr": "2&49" + }, + { + "id": 5, + "lv": 41, + "attr": "2&50" + }, + { + "id": 5, + "lv": 42, + "attr": "2&51" + }, + { + "id": 5, + "lv": 43, + "attr": "2&52" + }, + { + "id": 5, + "lv": 44, + "attr": "2&53" + }, + { + "id": 5, + "lv": 45, + "attr": "2&54" + }, + { + "id": 5, + "lv": 46, + "attr": "2&55" + }, + { + "id": 5, + "lv": 47, + "attr": "2&56" + }, + { + "id": 5, + "lv": 48, + "attr": "2&57" + }, + { + "id": 5, + "lv": 49, + "attr": "2&58" + }, + { + "id": 5, + "lv": 50, + "attr": "2&59" + }, + { + "id": 5, + "lv": 51, + "attr": "2&60" + }, + { + "id": 5, + "lv": 52, + "attr": "2&61" + }, + { + "id": 5, + "lv": 53, + "attr": "2&62" + }, + { + "id": 5, + "lv": 54, + "attr": "2&63" + }, + { + "id": 5, + "lv": 55, + "attr": "2&64" + }, + { + "id": 5, + "lv": 56, + "attr": "2&65" + }, + { + "id": 5, + "lv": 57, + "attr": "2&66" + }, + { + "id": 5, + "lv": 58, + "attr": "2&67" + }, + { + "id": 5, + "lv": 59, + "attr": "2&68" + }, + { + "id": 5, + "lv": 60, + "attr": "2&69" + }, + { + "id": 5, + "lv": 61, + "attr": "2&70" + }, + { + "id": 5, + "lv": 62, + "attr": "2&71" + }, + { + "id": 5, + "lv": 63, + "attr": "2&72" + }, + { + "id": 5, + "lv": 64, + "attr": "2&73" + }, + { + "id": 5, + "lv": 65, + "attr": "2&74" + }, + { + "id": 5, + "lv": 66, + "attr": "2&75" + }, + { + "id": 5, + "lv": 67, + "attr": "2&76" + }, + { + "id": 5, + "lv": 68, + "attr": "2&77" + }, + { + "id": 5, + "lv": 69, + "attr": "2&78" + }, + { + "id": 5, + "lv": 70, + "attr": "2&79" + }, + { + "id": 5, + "lv": 71, + "attr": "2&80" + }, + { + "id": 5, + "lv": 72, + "attr": "2&81" + }, + { + "id": 5, + "lv": 73, + "attr": "2&82" + }, + { + "id": 5, + "lv": 74, + "attr": "2&83" + }, + { + "id": 5, + "lv": 75, + "attr": "2&84" + }, + { + "id": 5, + "lv": 76, + "attr": "2&85" + }, + { + "id": 5, + "lv": 77, + "attr": "2&86" + }, + { + "id": 5, + "lv": 78, + "attr": "2&87" + }, + { + "id": 5, + "lv": 79, + "attr": "2&88" + }, + { + "id": 5, + "lv": 80, + "attr": "2&89" + }, + { + "id": 5, + "lv": 81, + "attr": "2&90" + }, + { + "id": 5, + "lv": 82, + "attr": "2&91" + }, + { + "id": 5, + "lv": 83, + "attr": "2&92" + }, + { + "id": 5, + "lv": 84, + "attr": "2&93" + }, + { + "id": 5, + "lv": 85, + "attr": "2&94" + }, + { + "id": 5, + "lv": 86, + "attr": "2&95" + }, + { + "id": 5, + "lv": 87, + "attr": "2&96" + }, + { + "id": 5, + "lv": 88, + "attr": "2&97" + }, + { + "id": 5, + "lv": 89, + "attr": "2&98" + }, + { + "id": 5, + "lv": 90, + "attr": "2&99" + }, + { + "id": 5, + "lv": 91, + "attr": "2&100" + }, + { + "id": 5, + "lv": 92, + "attr": "2&101" + }, + { + "id": 5, + "lv": 93, + "attr": "2&102" + }, + { + "id": 5, + "lv": 94, + "attr": "2&103" + }, + { + "id": 5, + "lv": 95, + "attr": "2&104" + }, + { + "id": 5, + "lv": 96, + "attr": "2&105" + }, + { + "id": 5, + "lv": 97, + "attr": "2&106" + }, + { + "id": 5, + "lv": 98, + "attr": "2&107" + }, + { + "id": 5, + "lv": 99, + "attr": "2&108" + }, + { + "id": 5, + "lv": 100, + "attr": "2&109" + }, + { + "id": 6, + "lv": 1, + "attr": "4&20" + }, + { + "id": 6, + "lv": 2, + "attr": "4&21" + }, + { + "id": 6, + "lv": 3, + "attr": "4&22" + }, + { + "id": 6, + "lv": 4, + "attr": "4&23" + }, + { + "id": 6, + "lv": 5, + "attr": "4&24" + }, + { + "id": 6, + "lv": 6, + "attr": "4&25" + }, + { + "id": 6, + "lv": 7, + "attr": "4&26" + }, + { + "id": 6, + "lv": 8, + "attr": "4&27" + }, + { + "id": 6, + "lv": 9, + "attr": "4&28" + }, + { + "id": 6, + "lv": 10, + "attr": "4&29" + }, + { + "id": 6, + "lv": 11, + "attr": "4&30" + }, + { + "id": 6, + "lv": 12, + "attr": "4&31" + }, + { + "id": 6, + "lv": 13, + "attr": "4&32" + }, + { + "id": 6, + "lv": 14, + "attr": "4&33" + }, + { + "id": 6, + "lv": 15, + "attr": "4&34" + }, + { + "id": 6, + "lv": 16, + "attr": "4&35" + }, + { + "id": 6, + "lv": 17, + "attr": "4&36" + }, + { + "id": 6, + "lv": 18, + "attr": "4&37" + }, + { + "id": 6, + "lv": 19, + "attr": "4&38" + }, + { + "id": 6, + "lv": 20, + "attr": "4&39" + }, + { + "id": 6, + "lv": 21, + "attr": "4&40" + }, + { + "id": 6, + "lv": 22, + "attr": "4&41" + }, + { + "id": 6, + "lv": 23, + "attr": "4&42" + }, + { + "id": 6, + "lv": 24, + "attr": "4&43" + }, + { + "id": 6, + "lv": 25, + "attr": "4&44" + }, + { + "id": 6, + "lv": 26, + "attr": "4&45" + }, + { + "id": 6, + "lv": 27, + "attr": "4&46" + }, + { + "id": 6, + "lv": 28, + "attr": "4&47" + }, + { + "id": 6, + "lv": 29, + "attr": "4&48" + }, + { + "id": 6, + "lv": 30, + "attr": "4&49" + }, + { + "id": 6, + "lv": 31, + "attr": "4&50" + }, + { + "id": 6, + "lv": 32, + "attr": "4&51" + }, + { + "id": 6, + "lv": 33, + "attr": "4&52" + }, + { + "id": 6, + "lv": 34, + "attr": "4&53" + }, + { + "id": 6, + "lv": 35, + "attr": "4&54" + }, + { + "id": 6, + "lv": 36, + "attr": "4&55" + }, + { + "id": 6, + "lv": 37, + "attr": "4&56" + }, + { + "id": 6, + "lv": 38, + "attr": "4&57" + }, + { + "id": 6, + "lv": 39, + "attr": "4&58" + }, + { + "id": 6, + "lv": 40, + "attr": "4&59" + }, + { + "id": 6, + "lv": 41, + "attr": "4&60" + }, + { + "id": 6, + "lv": 42, + "attr": "4&61" + }, + { + "id": 6, + "lv": 43, + "attr": "4&62" + }, + { + "id": 6, + "lv": 44, + "attr": "4&63" + }, + { + "id": 6, + "lv": 45, + "attr": "4&64" + }, + { + "id": 6, + "lv": 46, + "attr": "4&65" + }, + { + "id": 6, + "lv": 47, + "attr": "4&66" + }, + { + "id": 6, + "lv": 48, + "attr": "4&67" + }, + { + "id": 6, + "lv": 49, + "attr": "4&68" + }, + { + "id": 6, + "lv": 50, + "attr": "4&69" + }, + { + "id": 6, + "lv": 51, + "attr": "4&70" + }, + { + "id": 6, + "lv": 52, + "attr": "4&71" + }, + { + "id": 6, + "lv": 53, + "attr": "4&72" + }, + { + "id": 6, + "lv": 54, + "attr": "4&73" + }, + { + "id": 6, + "lv": 55, + "attr": "4&74" + }, + { + "id": 6, + "lv": 56, + "attr": "4&75" + }, + { + "id": 6, + "lv": 57, + "attr": "4&76" + }, + { + "id": 6, + "lv": 58, + "attr": "4&77" + }, + { + "id": 6, + "lv": 59, + "attr": "4&78" + }, + { + "id": 6, + "lv": 60, + "attr": "4&79" + }, + { + "id": 6, + "lv": 61, + "attr": "4&80" + }, + { + "id": 6, + "lv": 62, + "attr": "4&81" + }, + { + "id": 6, + "lv": 63, + "attr": "4&82" + }, + { + "id": 6, + "lv": 64, + "attr": "4&83" + }, + { + "id": 6, + "lv": 65, + "attr": "4&84" + }, + { + "id": 6, + "lv": 66, + "attr": "4&85" + }, + { + "id": 6, + "lv": 67, + "attr": "4&86" + }, + { + "id": 6, + "lv": 68, + "attr": "4&87" + }, + { + "id": 6, + "lv": 69, + "attr": "4&88" + }, + { + "id": 6, + "lv": 70, + "attr": "4&89" + }, + { + "id": 6, + "lv": 71, + "attr": "4&90" + }, + { + "id": 6, + "lv": 72, + "attr": "4&91" + }, + { + "id": 6, + "lv": 73, + "attr": "4&92" + }, + { + "id": 6, + "lv": 74, + "attr": "4&93" + }, + { + "id": 6, + "lv": 75, + "attr": "4&94" + }, + { + "id": 6, + "lv": 76, + "attr": "4&95" + }, + { + "id": 6, + "lv": 77, + "attr": "4&96" + }, + { + "id": 6, + "lv": 78, + "attr": "4&97" + }, + { + "id": 6, + "lv": 79, + "attr": "4&98" + }, + { + "id": 6, + "lv": 80, + "attr": "4&99" + }, + { + "id": 6, + "lv": 81, + "attr": "4&100" + }, + { + "id": 6, + "lv": 82, + "attr": "4&101" + }, + { + "id": 6, + "lv": 83, + "attr": "4&102" + }, + { + "id": 6, + "lv": 84, + "attr": "4&103" + }, + { + "id": 6, + "lv": 85, + "attr": "4&104" + }, + { + "id": 6, + "lv": 86, + "attr": "4&105" + }, + { + "id": 6, + "lv": 87, + "attr": "4&106" + }, + { + "id": 6, + "lv": 88, + "attr": "4&107" + }, + { + "id": 6, + "lv": 89, + "attr": "4&108" + }, + { + "id": 6, + "lv": 90, + "attr": "4&109" + }, + { + "id": 6, + "lv": 91, + "attr": "4&110" + }, + { + "id": 6, + "lv": 92, + "attr": "4&111" + }, + { + "id": 6, + "lv": 93, + "attr": "4&112" + }, + { + "id": 6, + "lv": 94, + "attr": "4&113" + }, + { + "id": 6, + "lv": 95, + "attr": "4&114" + }, + { + "id": 6, + "lv": 96, + "attr": "4&115" + }, + { + "id": 6, + "lv": 97, + "attr": "4&116" + }, + { + "id": 6, + "lv": 98, + "attr": "4&117" + }, + { + "id": 6, + "lv": 99, + "attr": "4&118" + }, + { + "id": 6, + "lv": 100, + "attr": "4&119" + }, + { + "id": 7, + "lv": 1, + "attr": "5&20" + }, + { + "id": 7, + "lv": 2, + "attr": "5&21" + }, + { + "id": 7, + "lv": 3, + "attr": "5&22" + }, + { + "id": 7, + "lv": 4, + "attr": "5&23" + }, + { + "id": 7, + "lv": 5, + "attr": "5&24" + }, + { + "id": 7, + "lv": 6, + "attr": "5&25" + }, + { + "id": 7, + "lv": 7, + "attr": "5&26" + }, + { + "id": 7, + "lv": 8, + "attr": "5&27" + }, + { + "id": 7, + "lv": 9, + "attr": "5&28" + }, + { + "id": 7, + "lv": 10, + "attr": "5&29" + }, + { + "id": 7, + "lv": 11, + "attr": "5&30" + }, + { + "id": 7, + "lv": 12, + "attr": "5&31" + }, + { + "id": 7, + "lv": 13, + "attr": "5&32" + }, + { + "id": 7, + "lv": 14, + "attr": "5&33" + }, + { + "id": 7, + "lv": 15, + "attr": "5&34" + }, + { + "id": 7, + "lv": 16, + "attr": "5&35" + }, + { + "id": 7, + "lv": 17, + "attr": "5&36" + }, + { + "id": 7, + "lv": 18, + "attr": "5&37" + }, + { + "id": 7, + "lv": 19, + "attr": "5&38" + }, + { + "id": 7, + "lv": 20, + "attr": "5&39" + }, + { + "id": 7, + "lv": 21, + "attr": "5&40" + }, + { + "id": 7, + "lv": 22, + "attr": "5&41" + }, + { + "id": 7, + "lv": 23, + "attr": "5&42" + }, + { + "id": 7, + "lv": 24, + "attr": "5&43" + }, + { + "id": 7, + "lv": 25, + "attr": "5&44" + }, + { + "id": 7, + "lv": 26, + "attr": "5&45" + }, + { + "id": 7, + "lv": 27, + "attr": "5&46" + }, + { + "id": 7, + "lv": 28, + "attr": "5&47" + }, + { + "id": 7, + "lv": 29, + "attr": "5&48" + }, + { + "id": 7, + "lv": 30, + "attr": "5&49" + }, + { + "id": 7, + "lv": 31, + "attr": "5&50" + }, + { + "id": 7, + "lv": 32, + "attr": "5&51" + }, + { + "id": 7, + "lv": 33, + "attr": "5&52" + }, + { + "id": 7, + "lv": 34, + "attr": "5&53" + }, + { + "id": 7, + "lv": 35, + "attr": "5&54" + }, + { + "id": 7, + "lv": 36, + "attr": "5&55" + }, + { + "id": 7, + "lv": 37, + "attr": "5&56" + }, + { + "id": 7, + "lv": 38, + "attr": "5&57" + }, + { + "id": 7, + "lv": 39, + "attr": "5&58" + }, + { + "id": 7, + "lv": 40, + "attr": "5&59" + }, + { + "id": 7, + "lv": 41, + "attr": "5&60" + }, + { + "id": 7, + "lv": 42, + "attr": "5&61" + }, + { + "id": 7, + "lv": 43, + "attr": "5&62" + }, + { + "id": 7, + "lv": 44, + "attr": "5&63" + }, + { + "id": 7, + "lv": 45, + "attr": "5&64" + }, + { + "id": 7, + "lv": 46, + "attr": "5&65" + }, + { + "id": 7, + "lv": 47, + "attr": "5&66" + }, + { + "id": 7, + "lv": 48, + "attr": "5&67" + }, + { + "id": 7, + "lv": 49, + "attr": "5&68" + }, + { + "id": 7, + "lv": 50, + "attr": "5&69" + }, + { + "id": 7, + "lv": 51, + "attr": "5&70" + }, + { + "id": 7, + "lv": 52, + "attr": "5&71" + }, + { + "id": 7, + "lv": 53, + "attr": "5&72" + }, + { + "id": 7, + "lv": 54, + "attr": "5&73" + }, + { + "id": 7, + "lv": 55, + "attr": "5&74" + }, + { + "id": 7, + "lv": 56, + "attr": "5&75" + }, + { + "id": 7, + "lv": 57, + "attr": "5&76" + }, + { + "id": 7, + "lv": 58, + "attr": "5&77" + }, + { + "id": 7, + "lv": 59, + "attr": "5&78" + }, + { + "id": 7, + "lv": 60, + "attr": "5&79" + }, + { + "id": 7, + "lv": 61, + "attr": "5&80" + }, + { + "id": 7, + "lv": 62, + "attr": "5&81" + }, + { + "id": 7, + "lv": 63, + "attr": "5&82" + }, + { + "id": 7, + "lv": 64, + "attr": "5&83" + }, + { + "id": 7, + "lv": 65, + "attr": "5&84" + }, + { + "id": 7, + "lv": 66, + "attr": "5&85" + }, + { + "id": 7, + "lv": 67, + "attr": "5&86" + }, + { + "id": 7, + "lv": 68, + "attr": "5&87" + }, + { + "id": 7, + "lv": 69, + "attr": "5&88" + }, + { + "id": 7, + "lv": 70, + "attr": "5&89" + }, + { + "id": 7, + "lv": 71, + "attr": "5&90" + }, + { + "id": 7, + "lv": 72, + "attr": "5&91" + }, + { + "id": 7, + "lv": 73, + "attr": "5&92" + }, + { + "id": 7, + "lv": 74, + "attr": "5&93" + }, + { + "id": 7, + "lv": 75, + "attr": "5&94" + }, + { + "id": 7, + "lv": 76, + "attr": "5&95" + }, + { + "id": 7, + "lv": 77, + "attr": "5&96" + }, + { + "id": 7, + "lv": 78, + "attr": "5&97" + }, + { + "id": 7, + "lv": 79, + "attr": "5&98" + }, + { + "id": 7, + "lv": 80, + "attr": "5&99" + }, + { + "id": 7, + "lv": 81, + "attr": "5&100" + }, + { + "id": 7, + "lv": 82, + "attr": "5&101" + }, + { + "id": 7, + "lv": 83, + "attr": "5&102" + }, + { + "id": 7, + "lv": 84, + "attr": "5&103" + }, + { + "id": 7, + "lv": 85, + "attr": "5&104" + }, + { + "id": 7, + "lv": 86, + "attr": "5&105" + }, + { + "id": 7, + "lv": 87, + "attr": "5&106" + }, + { + "id": 7, + "lv": 88, + "attr": "5&107" + }, + { + "id": 7, + "lv": 89, + "attr": "5&108" + }, + { + "id": 7, + "lv": 90, + "attr": "5&109" + }, + { + "id": 7, + "lv": 91, + "attr": "5&110" + }, + { + "id": 7, + "lv": 92, + "attr": "5&111" + }, + { + "id": 7, + "lv": 93, + "attr": "5&112" + }, + { + "id": 7, + "lv": 94, + "attr": "5&113" + }, + { + "id": 7, + "lv": 95, + "attr": "5&114" + }, + { + "id": 7, + "lv": 96, + "attr": "5&115" + }, + { + "id": 7, + "lv": 97, + "attr": "5&116" + }, + { + "id": 7, + "lv": 98, + "attr": "5&117" + }, + { + "id": 7, + "lv": 99, + "attr": "5&118" + }, + { + "id": 7, + "lv": 100, + "attr": "5&119" + }, + { + "id": 8, + "lv": 1, + "attr": "1&50" + }, + { + "id": 8, + "lv": 2, + "attr": "1&51" + }, + { + "id": 8, + "lv": 3, + "attr": "1&52" + }, + { + "id": 8, + "lv": 4, + "attr": "1&53" + }, + { + "id": 8, + "lv": 5, + "attr": "1&54" + }, + { + "id": 8, + "lv": 6, + "attr": "1&55" + }, + { + "id": 8, + "lv": 7, + "attr": "1&56" + }, + { + "id": 8, + "lv": 8, + "attr": "1&57" + }, + { + "id": 8, + "lv": 9, + "attr": "1&58" + }, + { + "id": 8, + "lv": 10, + "attr": "1&59" + }, + { + "id": 8, + "lv": 11, + "attr": "1&60" + }, + { + "id": 8, + "lv": 12, + "attr": "1&61" + }, + { + "id": 8, + "lv": 13, + "attr": "1&62" + }, + { + "id": 8, + "lv": 14, + "attr": "1&63" + }, + { + "id": 8, + "lv": 15, + "attr": "1&64" + }, + { + "id": 8, + "lv": 16, + "attr": "1&65" + }, + { + "id": 8, + "lv": 17, + "attr": "1&66" + }, + { + "id": 8, + "lv": 18, + "attr": "1&67" + }, + { + "id": 8, + "lv": 19, + "attr": "1&68" + }, + { + "id": 8, + "lv": 20, + "attr": "1&69" + }, + { + "id": 8, + "lv": 21, + "attr": "1&70" + }, + { + "id": 8, + "lv": 22, + "attr": "1&71" + }, + { + "id": 8, + "lv": 23, + "attr": "1&72" + }, + { + "id": 8, + "lv": 24, + "attr": "1&73" + }, + { + "id": 8, + "lv": 25, + "attr": "1&74" + }, + { + "id": 8, + "lv": 26, + "attr": "1&75" + }, + { + "id": 8, + "lv": 27, + "attr": "1&76" + }, + { + "id": 8, + "lv": 28, + "attr": "1&77" + }, + { + "id": 8, + "lv": 29, + "attr": "1&78" + }, + { + "id": 8, + "lv": 30, + "attr": "1&79" + }, + { + "id": 8, + "lv": 31, + "attr": "1&80" + }, + { + "id": 8, + "lv": 32, + "attr": "1&81" + }, + { + "id": 8, + "lv": 33, + "attr": "1&82" + }, + { + "id": 8, + "lv": 34, + "attr": "1&83" + }, + { + "id": 8, + "lv": 35, + "attr": "1&84" + }, + { + "id": 8, + "lv": 36, + "attr": "1&85" + }, + { + "id": 8, + "lv": 37, + "attr": "1&86" + }, + { + "id": 8, + "lv": 38, + "attr": "1&87" + }, + { + "id": 8, + "lv": 39, + "attr": "1&88" + }, + { + "id": 8, + "lv": 40, + "attr": "1&89" + }, + { + "id": 8, + "lv": 41, + "attr": "1&90" + }, + { + "id": 8, + "lv": 42, + "attr": "1&91" + }, + { + "id": 8, + "lv": 43, + "attr": "1&92" + }, + { + "id": 8, + "lv": 44, + "attr": "1&93" + }, + { + "id": 8, + "lv": 45, + "attr": "1&94" + }, + { + "id": 8, + "lv": 46, + "attr": "1&95" + }, + { + "id": 8, + "lv": 47, + "attr": "1&96" + }, + { + "id": 8, + "lv": 48, + "attr": "1&97" + }, + { + "id": 8, + "lv": 49, + "attr": "1&98" + }, + { + "id": 8, + "lv": 50, + "attr": "1&99" + }, + { + "id": 8, + "lv": 51, + "attr": "1&100" + }, + { + "id": 8, + "lv": 52, + "attr": "1&101" + }, + { + "id": 8, + "lv": 53, + "attr": "1&102" + }, + { + "id": 8, + "lv": 54, + "attr": "1&103" + }, + { + "id": 8, + "lv": 55, + "attr": "1&104" + }, + { + "id": 8, + "lv": 56, + "attr": "1&105" + }, + { + "id": 8, + "lv": 57, + "attr": "1&106" + }, + { + "id": 8, + "lv": 58, + "attr": "1&107" + }, + { + "id": 8, + "lv": 59, + "attr": "1&108" + }, + { + "id": 8, + "lv": 60, + "attr": "1&109" + }, + { + "id": 8, + "lv": 61, + "attr": "1&110" + }, + { + "id": 8, + "lv": 62, + "attr": "1&111" + }, + { + "id": 8, + "lv": 63, + "attr": "1&112" + }, + { + "id": 8, + "lv": 64, + "attr": "1&113" + }, + { + "id": 8, + "lv": 65, + "attr": "1&114" + }, + { + "id": 8, + "lv": 66, + "attr": "1&115" + }, + { + "id": 8, + "lv": 67, + "attr": "1&116" + }, + { + "id": 8, + "lv": 68, + "attr": "1&117" + }, + { + "id": 8, + "lv": 69, + "attr": "1&118" + }, + { + "id": 8, + "lv": 70, + "attr": "1&119" + }, + { + "id": 8, + "lv": 71, + "attr": "1&120" + }, + { + "id": 8, + "lv": 72, + "attr": "1&121" + }, + { + "id": 8, + "lv": 73, + "attr": "1&122" + }, + { + "id": 8, + "lv": 74, + "attr": "1&123" + }, + { + "id": 8, + "lv": 75, + "attr": "1&124" + }, + { + "id": 8, + "lv": 76, + "attr": "1&125" + }, + { + "id": 8, + "lv": 77, + "attr": "1&126" + }, + { + "id": 8, + "lv": 78, + "attr": "1&127" + }, + { + "id": 8, + "lv": 79, + "attr": "1&128" + }, + { + "id": 8, + "lv": 80, + "attr": "1&129" + }, + { + "id": 8, + "lv": 81, + "attr": "1&130" + }, + { + "id": 8, + "lv": 82, + "attr": "1&131" + }, + { + "id": 8, + "lv": 83, + "attr": "1&132" + }, + { + "id": 8, + "lv": 84, + "attr": "1&133" + }, + { + "id": 8, + "lv": 85, + "attr": "1&134" + }, + { + "id": 8, + "lv": 86, + "attr": "1&135" + }, + { + "id": 8, + "lv": 87, + "attr": "1&136" + }, + { + "id": 8, + "lv": 88, + "attr": "1&137" + }, + { + "id": 8, + "lv": 89, + "attr": "1&138" + }, + { + "id": 8, + "lv": 90, + "attr": "1&139" + }, + { + "id": 8, + "lv": 91, + "attr": "1&140" + }, + { + "id": 8, + "lv": 92, + "attr": "1&141" + }, + { + "id": 8, + "lv": 93, + "attr": "1&142" + }, + { + "id": 8, + "lv": 94, + "attr": "1&143" + }, + { + "id": 8, + "lv": 95, + "attr": "1&144" + }, + { + "id": 8, + "lv": 96, + "attr": "1&145" + }, + { + "id": 8, + "lv": 97, + "attr": "1&146" + }, + { + "id": 8, + "lv": 98, + "attr": "1&147" + }, + { + "id": 8, + "lv": 99, + "attr": "1&148" + }, + { + "id": 8, + "lv": 100, + "attr": "1&149" + }, + { + "id": 9, + "lv": 1, + "attr": "2&10" + }, + { + "id": 9, + "lv": 2, + "attr": "2&11" + }, + { + "id": 9, + "lv": 3, + "attr": "2&12" + }, + { + "id": 9, + "lv": 4, + "attr": "2&13" + }, + { + "id": 9, + "lv": 5, + "attr": "2&14" + }, + { + "id": 9, + "lv": 6, + "attr": "2&15" + }, + { + "id": 9, + "lv": 7, + "attr": "2&16" + }, + { + "id": 9, + "lv": 8, + "attr": "2&17" + }, + { + "id": 9, + "lv": 9, + "attr": "2&18" + }, + { + "id": 9, + "lv": 10, + "attr": "2&19" + }, + { + "id": 9, + "lv": 11, + "attr": "2&20" + }, + { + "id": 9, + "lv": 12, + "attr": "2&21" + }, + { + "id": 9, + "lv": 13, + "attr": "2&22" + }, + { + "id": 9, + "lv": 14, + "attr": "2&23" + }, + { + "id": 9, + "lv": 15, + "attr": "2&24" + }, + { + "id": 9, + "lv": 16, + "attr": "2&25" + }, + { + "id": 9, + "lv": 17, + "attr": "2&26" + }, + { + "id": 9, + "lv": 18, + "attr": "2&27" + }, + { + "id": 9, + "lv": 19, + "attr": "2&28" + }, + { + "id": 9, + "lv": 20, + "attr": "2&29" + }, + { + "id": 9, + "lv": 21, + "attr": "2&30" + }, + { + "id": 9, + "lv": 22, + "attr": "2&31" + }, + { + "id": 9, + "lv": 23, + "attr": "2&32" + }, + { + "id": 9, + "lv": 24, + "attr": "2&33" + }, + { + "id": 9, + "lv": 25, + "attr": "2&34" + }, + { + "id": 9, + "lv": 26, + "attr": "2&35" + }, + { + "id": 9, + "lv": 27, + "attr": "2&36" + }, + { + "id": 9, + "lv": 28, + "attr": "2&37" + }, + { + "id": 9, + "lv": 29, + "attr": "2&38" + }, + { + "id": 9, + "lv": 30, + "attr": "2&39" + }, + { + "id": 9, + "lv": 31, + "attr": "2&40" + }, + { + "id": 9, + "lv": 32, + "attr": "2&41" + }, + { + "id": 9, + "lv": 33, + "attr": "2&42" + }, + { + "id": 9, + "lv": 34, + "attr": "2&43" + }, + { + "id": 9, + "lv": 35, + "attr": "2&44" + }, + { + "id": 9, + "lv": 36, + "attr": "2&45" + }, + { + "id": 9, + "lv": 37, + "attr": "2&46" + }, + { + "id": 9, + "lv": 38, + "attr": "2&47" + }, + { + "id": 9, + "lv": 39, + "attr": "2&48" + }, + { + "id": 9, + "lv": 40, + "attr": "2&49" + }, + { + "id": 9, + "lv": 41, + "attr": "2&50" + }, + { + "id": 9, + "lv": 42, + "attr": "2&51" + }, + { + "id": 9, + "lv": 43, + "attr": "2&52" + }, + { + "id": 9, + "lv": 44, + "attr": "2&53" + }, + { + "id": 9, + "lv": 45, + "attr": "2&54" + }, + { + "id": 9, + "lv": 46, + "attr": "2&55" + }, + { + "id": 9, + "lv": 47, + "attr": "2&56" + }, + { + "id": 9, + "lv": 48, + "attr": "2&57" + }, + { + "id": 9, + "lv": 49, + "attr": "2&58" + }, + { + "id": 9, + "lv": 50, + "attr": "2&59" + }, + { + "id": 9, + "lv": 51, + "attr": "2&60" + }, + { + "id": 9, + "lv": 52, + "attr": "2&61" + }, + { + "id": 9, + "lv": 53, + "attr": "2&62" + }, + { + "id": 9, + "lv": 54, + "attr": "2&63" + }, + { + "id": 9, + "lv": 55, + "attr": "2&64" + }, + { + "id": 9, + "lv": 56, + "attr": "2&65" + }, + { + "id": 9, + "lv": 57, + "attr": "2&66" + }, + { + "id": 9, + "lv": 58, + "attr": "2&67" + }, + { + "id": 9, + "lv": 59, + "attr": "2&68" + }, + { + "id": 9, + "lv": 60, + "attr": "2&69" + }, + { + "id": 9, + "lv": 61, + "attr": "2&70" + }, + { + "id": 9, + "lv": 62, + "attr": "2&71" + }, + { + "id": 9, + "lv": 63, + "attr": "2&72" + }, + { + "id": 9, + "lv": 64, + "attr": "2&73" + }, + { + "id": 9, + "lv": 65, + "attr": "2&74" + }, + { + "id": 9, + "lv": 66, + "attr": "2&75" + }, + { + "id": 9, + "lv": 67, + "attr": "2&76" + }, + { + "id": 9, + "lv": 68, + "attr": "2&77" + }, + { + "id": 9, + "lv": 69, + "attr": "2&78" + }, + { + "id": 9, + "lv": 70, + "attr": "2&79" + }, + { + "id": 9, + "lv": 71, + "attr": "2&80" + }, + { + "id": 9, + "lv": 72, + "attr": "2&81" + }, + { + "id": 9, + "lv": 73, + "attr": "2&82" + }, + { + "id": 9, + "lv": 74, + "attr": "2&83" + }, + { + "id": 9, + "lv": 75, + "attr": "2&84" + }, + { + "id": 9, + "lv": 76, + "attr": "2&85" + }, + { + "id": 9, + "lv": 77, + "attr": "2&86" + }, + { + "id": 9, + "lv": 78, + "attr": "2&87" + }, + { + "id": 9, + "lv": 79, + "attr": "2&88" + }, + { + "id": 9, + "lv": 80, + "attr": "2&89" + }, + { + "id": 9, + "lv": 81, + "attr": "2&90" + }, + { + "id": 9, + "lv": 82, + "attr": "2&91" + }, + { + "id": 9, + "lv": 83, + "attr": "2&92" + }, + { + "id": 9, + "lv": 84, + "attr": "2&93" + }, + { + "id": 9, + "lv": 85, + "attr": "2&94" + }, + { + "id": 9, + "lv": 86, + "attr": "2&95" + }, + { + "id": 9, + "lv": 87, + "attr": "2&96" + }, + { + "id": 9, + "lv": 88, + "attr": "2&97" + }, + { + "id": 9, + "lv": 89, + "attr": "2&98" + }, + { + "id": 9, + "lv": 90, + "attr": "2&99" + }, + { + "id": 9, + "lv": 91, + "attr": "2&100" + }, + { + "id": 9, + "lv": 92, + "attr": "2&101" + }, + { + "id": 9, + "lv": 93, + "attr": "2&102" + }, + { + "id": 9, + "lv": 94, + "attr": "2&103" + }, + { + "id": 9, + "lv": 95, + "attr": "2&104" + }, + { + "id": 9, + "lv": 96, + "attr": "2&105" + }, + { + "id": 9, + "lv": 97, + "attr": "2&106" + }, + { + "id": 9, + "lv": 98, + "attr": "2&107" + }, + { + "id": 9, + "lv": 99, + "attr": "2&108" + }, + { + "id": 9, + "lv": 100, + "attr": "2&109" + }, + { + "id": 10, + "lv": 1, + "attr": "4&20" + }, + { + "id": 10, + "lv": 2, + "attr": "4&21" + }, + { + "id": 10, + "lv": 3, + "attr": "4&22" + }, + { + "id": 10, + "lv": 4, + "attr": "4&23" + }, + { + "id": 10, + "lv": 5, + "attr": "4&24" + }, + { + "id": 10, + "lv": 6, + "attr": "4&25" + }, + { + "id": 10, + "lv": 7, + "attr": "4&26" + }, + { + "id": 10, + "lv": 8, + "attr": "4&27" + }, + { + "id": 10, + "lv": 9, + "attr": "4&28" + }, + { + "id": 10, + "lv": 10, + "attr": "4&29" + }, + { + "id": 10, + "lv": 11, + "attr": "4&30" + }, + { + "id": 10, + "lv": 12, + "attr": "4&31" + }, + { + "id": 10, + "lv": 13, + "attr": "4&32" + }, + { + "id": 10, + "lv": 14, + "attr": "4&33" + }, + { + "id": 10, + "lv": 15, + "attr": "4&34" + }, + { + "id": 10, + "lv": 16, + "attr": "4&35" + }, + { + "id": 10, + "lv": 17, + "attr": "4&36" + }, + { + "id": 10, + "lv": 18, + "attr": "4&37" + }, + { + "id": 10, + "lv": 19, + "attr": "4&38" + }, + { + "id": 10, + "lv": 20, + "attr": "4&39" + }, + { + "id": 10, + "lv": 21, + "attr": "4&40" + }, + { + "id": 10, + "lv": 22, + "attr": "4&41" + }, + { + "id": 10, + "lv": 23, + "attr": "4&42" + }, + { + "id": 10, + "lv": 24, + "attr": "4&43" + }, + { + "id": 10, + "lv": 25, + "attr": "4&44" + }, + { + "id": 10, + "lv": 26, + "attr": "4&45" + }, + { + "id": 10, + "lv": 27, + "attr": "4&46" + }, + { + "id": 10, + "lv": 28, + "attr": "4&47" + }, + { + "id": 10, + "lv": 29, + "attr": "4&48" + }, + { + "id": 10, + "lv": 30, + "attr": "4&49" + }, + { + "id": 10, + "lv": 31, + "attr": "4&50" + }, + { + "id": 10, + "lv": 32, + "attr": "4&51" + }, + { + "id": 10, + "lv": 33, + "attr": "4&52" + }, + { + "id": 10, + "lv": 34, + "attr": "4&53" + }, + { + "id": 10, + "lv": 35, + "attr": "4&54" + }, + { + "id": 10, + "lv": 36, + "attr": "4&55" + }, + { + "id": 10, + "lv": 37, + "attr": "4&56" + }, + { + "id": 10, + "lv": 38, + "attr": "4&57" + }, + { + "id": 10, + "lv": 39, + "attr": "4&58" + }, + { + "id": 10, + "lv": 40, + "attr": "4&59" + }, + { + "id": 10, + "lv": 41, + "attr": "4&60" + }, + { + "id": 10, + "lv": 42, + "attr": "4&61" + }, + { + "id": 10, + "lv": 43, + "attr": "4&62" + }, + { + "id": 10, + "lv": 44, + "attr": "4&63" + }, + { + "id": 10, + "lv": 45, + "attr": "4&64" + }, + { + "id": 10, + "lv": 46, + "attr": "4&65" + }, + { + "id": 10, + "lv": 47, + "attr": "4&66" + }, + { + "id": 10, + "lv": 48, + "attr": "4&67" + }, + { + "id": 10, + "lv": 49, + "attr": "4&68" + }, + { + "id": 10, + "lv": 50, + "attr": "4&69" + }, + { + "id": 10, + "lv": 51, + "attr": "4&70" + }, + { + "id": 10, + "lv": 52, + "attr": "4&71" + }, + { + "id": 10, + "lv": 53, + "attr": "4&72" + }, + { + "id": 10, + "lv": 54, + "attr": "4&73" + }, + { + "id": 10, + "lv": 55, + "attr": "4&74" + }, + { + "id": 10, + "lv": 56, + "attr": "4&75" + }, + { + "id": 10, + "lv": 57, + "attr": "4&76" + }, + { + "id": 10, + "lv": 58, + "attr": "4&77" + }, + { + "id": 10, + "lv": 59, + "attr": "4&78" + }, + { + "id": 10, + "lv": 60, + "attr": "4&79" + }, + { + "id": 10, + "lv": 61, + "attr": "4&80" + }, + { + "id": 10, + "lv": 62, + "attr": "4&81" + }, + { + "id": 10, + "lv": 63, + "attr": "4&82" + }, + { + "id": 10, + "lv": 64, + "attr": "4&83" + }, + { + "id": 10, + "lv": 65, + "attr": "4&84" + }, + { + "id": 10, + "lv": 66, + "attr": "4&85" + }, + { + "id": 10, + "lv": 67, + "attr": "4&86" + }, + { + "id": 10, + "lv": 68, + "attr": "4&87" + }, + { + "id": 10, + "lv": 69, + "attr": "4&88" + }, + { + "id": 10, + "lv": 70, + "attr": "4&89" + }, + { + "id": 10, + "lv": 71, + "attr": "4&90" + }, + { + "id": 10, + "lv": 72, + "attr": "4&91" + }, + { + "id": 10, + "lv": 73, + "attr": "4&92" + }, + { + "id": 10, + "lv": 74, + "attr": "4&93" + }, + { + "id": 10, + "lv": 75, + "attr": "4&94" + }, + { + "id": 10, + "lv": 76, + "attr": "4&95" + }, + { + "id": 10, + "lv": 77, + "attr": "4&96" + }, + { + "id": 10, + "lv": 78, + "attr": "4&97" + }, + { + "id": 10, + "lv": 79, + "attr": "4&98" + }, + { + "id": 10, + "lv": 80, + "attr": "4&99" + }, + { + "id": 10, + "lv": 81, + "attr": "4&100" + }, + { + "id": 10, + "lv": 82, + "attr": "4&101" + }, + { + "id": 10, + "lv": 83, + "attr": "4&102" + }, + { + "id": 10, + "lv": 84, + "attr": "4&103" + }, + { + "id": 10, + "lv": 85, + "attr": "4&104" + }, + { + "id": 10, + "lv": 86, + "attr": "4&105" + }, + { + "id": 10, + "lv": 87, + "attr": "4&106" + }, + { + "id": 10, + "lv": 88, + "attr": "4&107" + }, + { + "id": 10, + "lv": 89, + "attr": "4&108" + }, + { + "id": 10, + "lv": 90, + "attr": "4&109" + }, + { + "id": 10, + "lv": 91, + "attr": "4&110" + }, + { + "id": 10, + "lv": 92, + "attr": "4&111" + }, + { + "id": 10, + "lv": 93, + "attr": "4&112" + }, + { + "id": 10, + "lv": 94, + "attr": "4&113" + }, + { + "id": 10, + "lv": 95, + "attr": "4&114" + }, + { + "id": 10, + "lv": 96, + "attr": "4&115" + }, + { + "id": 10, + "lv": 97, + "attr": "4&116" + }, + { + "id": 10, + "lv": 98, + "attr": "4&117" + }, + { + "id": 10, + "lv": 99, + "attr": "4&118" + }, + { + "id": 10, + "lv": 100, + "attr": "4&119" + }, + { + "id": 11, + "lv": 1, + "attr": "5&20" + }, + { + "id": 11, + "lv": 2, + "attr": "5&21" + }, + { + "id": 11, + "lv": 3, + "attr": "5&22" + }, + { + "id": 11, + "lv": 4, + "attr": "5&23" + }, + { + "id": 11, + "lv": 5, + "attr": "5&24" + }, + { + "id": 11, + "lv": 6, + "attr": "5&25" + }, + { + "id": 11, + "lv": 7, + "attr": "5&26" + }, + { + "id": 11, + "lv": 8, + "attr": "5&27" + }, + { + "id": 11, + "lv": 9, + "attr": "5&28" + }, + { + "id": 11, + "lv": 10, + "attr": "5&29" + }, + { + "id": 11, + "lv": 11, + "attr": "5&30" + }, + { + "id": 11, + "lv": 12, + "attr": "5&31" + }, + { + "id": 11, + "lv": 13, + "attr": "5&32" + }, + { + "id": 11, + "lv": 14, + "attr": "5&33" + }, + { + "id": 11, + "lv": 15, + "attr": "5&34" + }, + { + "id": 11, + "lv": 16, + "attr": "5&35" + }, + { + "id": 11, + "lv": 17, + "attr": "5&36" + }, + { + "id": 11, + "lv": 18, + "attr": "5&37" + }, + { + "id": 11, + "lv": 19, + "attr": "5&38" + }, + { + "id": 11, + "lv": 20, + "attr": "5&39" + }, + { + "id": 11, + "lv": 21, + "attr": "5&40" + }, + { + "id": 11, + "lv": 22, + "attr": "5&41" + }, + { + "id": 11, + "lv": 23, + "attr": "5&42" + }, + { + "id": 11, + "lv": 24, + "attr": "5&43" + }, + { + "id": 11, + "lv": 25, + "attr": "5&44" + }, + { + "id": 11, + "lv": 26, + "attr": "5&45" + }, + { + "id": 11, + "lv": 27, + "attr": "5&46" + }, + { + "id": 11, + "lv": 28, + "attr": "5&47" + }, + { + "id": 11, + "lv": 29, + "attr": "5&48" + }, + { + "id": 11, + "lv": 30, + "attr": "5&49" + }, + { + "id": 11, + "lv": 31, + "attr": "5&50" + }, + { + "id": 11, + "lv": 32, + "attr": "5&51" + }, + { + "id": 11, + "lv": 33, + "attr": "5&52" + }, + { + "id": 11, + "lv": 34, + "attr": "5&53" + }, + { + "id": 11, + "lv": 35, + "attr": "5&54" + }, + { + "id": 11, + "lv": 36, + "attr": "5&55" + }, + { + "id": 11, + "lv": 37, + "attr": "5&56" + }, + { + "id": 11, + "lv": 38, + "attr": "5&57" + }, + { + "id": 11, + "lv": 39, + "attr": "5&58" + }, + { + "id": 11, + "lv": 40, + "attr": "5&59" + }, + { + "id": 11, + "lv": 41, + "attr": "5&60" + }, + { + "id": 11, + "lv": 42, + "attr": "5&61" + }, + { + "id": 11, + "lv": 43, + "attr": "5&62" + }, + { + "id": 11, + "lv": 44, + "attr": "5&63" + }, + { + "id": 11, + "lv": 45, + "attr": "5&64" + }, + { + "id": 11, + "lv": 46, + "attr": "5&65" + }, + { + "id": 11, + "lv": 47, + "attr": "5&66" + }, + { + "id": 11, + "lv": 48, + "attr": "5&67" + }, + { + "id": 11, + "lv": 49, + "attr": "5&68" + }, + { + "id": 11, + "lv": 50, + "attr": "5&69" + }, + { + "id": 11, + "lv": 51, + "attr": "5&70" + }, + { + "id": 11, + "lv": 52, + "attr": "5&71" + }, + { + "id": 11, + "lv": 53, + "attr": "5&72" + }, + { + "id": 11, + "lv": 54, + "attr": "5&73" + }, + { + "id": 11, + "lv": 55, + "attr": "5&74" + }, + { + "id": 11, + "lv": 56, + "attr": "5&75" + }, + { + "id": 11, + "lv": 57, + "attr": "5&76" + }, + { + "id": 11, + "lv": 58, + "attr": "5&77" + }, + { + "id": 11, + "lv": 59, + "attr": "5&78" + }, + { + "id": 11, + "lv": 60, + "attr": "5&79" + }, + { + "id": 11, + "lv": 61, + "attr": "5&80" + }, + { + "id": 11, + "lv": 62, + "attr": "5&81" + }, + { + "id": 11, + "lv": 63, + "attr": "5&82" + }, + { + "id": 11, + "lv": 64, + "attr": "5&83" + }, + { + "id": 11, + "lv": 65, + "attr": "5&84" + }, + { + "id": 11, + "lv": 66, + "attr": "5&85" + }, + { + "id": 11, + "lv": 67, + "attr": "5&86" + }, + { + "id": 11, + "lv": 68, + "attr": "5&87" + }, + { + "id": 11, + "lv": 69, + "attr": "5&88" + }, + { + "id": 11, + "lv": 70, + "attr": "5&89" + }, + { + "id": 11, + "lv": 71, + "attr": "5&90" + }, + { + "id": 11, + "lv": 72, + "attr": "5&91" + }, + { + "id": 11, + "lv": 73, + "attr": "5&92" + }, + { + "id": 11, + "lv": 74, + "attr": "5&93" + }, + { + "id": 11, + "lv": 75, + "attr": "5&94" + }, + { + "id": 11, + "lv": 76, + "attr": "5&95" + }, + { + "id": 11, + "lv": 77, + "attr": "5&96" + }, + { + "id": 11, + "lv": 78, + "attr": "5&97" + }, + { + "id": 11, + "lv": 79, + "attr": "5&98" + }, + { + "id": 11, + "lv": 80, + "attr": "5&99" + }, + { + "id": 11, + "lv": 81, + "attr": "5&100" + }, + { + "id": 11, + "lv": 82, + "attr": "5&101" + }, + { + "id": 11, + "lv": 83, + "attr": "5&102" + }, + { + "id": 11, + "lv": 84, + "attr": "5&103" + }, + { + "id": 11, + "lv": 85, + "attr": "5&104" + }, + { + "id": 11, + "lv": 86, + "attr": "5&105" + }, + { + "id": 11, + "lv": 87, + "attr": "5&106" + }, + { + "id": 11, + "lv": 88, + "attr": "5&107" + }, + { + "id": 11, + "lv": 89, + "attr": "5&108" + }, + { + "id": 11, + "lv": 90, + "attr": "5&109" + }, + { + "id": 11, + "lv": 91, + "attr": "5&110" + }, + { + "id": 11, + "lv": 92, + "attr": "5&111" + }, + { + "id": 11, + "lv": 93, + "attr": "5&112" + }, + { + "id": 11, + "lv": 94, + "attr": "5&113" + }, + { + "id": 11, + "lv": 95, + "attr": "5&114" + }, + { + "id": 11, + "lv": 96, + "attr": "5&115" + }, + { + "id": 11, + "lv": 97, + "attr": "5&116" + }, + { + "id": 11, + "lv": 98, + "attr": "5&117" + }, + { + "id": 11, + "lv": 99, + "attr": "5&118" + }, + { + "id": 11, + "lv": 100, + "attr": "5&119" + }, + { + "id": 12, + "lv": 1, + "attr": "1&50" + }, + { + "id": 12, + "lv": 2, + "attr": "1&51" + }, + { + "id": 12, + "lv": 3, + "attr": "1&52" + }, + { + "id": 12, + "lv": 4, + "attr": "1&53" + }, + { + "id": 12, + "lv": 5, + "attr": "1&54" + }, + { + "id": 12, + "lv": 6, + "attr": "1&55" + }, + { + "id": 12, + "lv": 7, + "attr": "1&56" + }, + { + "id": 12, + "lv": 8, + "attr": "1&57" + }, + { + "id": 12, + "lv": 9, + "attr": "1&58" + }, + { + "id": 12, + "lv": 10, + "attr": "1&59" + }, + { + "id": 12, + "lv": 11, + "attr": "1&60" + }, + { + "id": 12, + "lv": 12, + "attr": "1&61" + }, + { + "id": 12, + "lv": 13, + "attr": "1&62" + }, + { + "id": 12, + "lv": 14, + "attr": "1&63" + }, + { + "id": 12, + "lv": 15, + "attr": "1&64" + }, + { + "id": 12, + "lv": 16, + "attr": "1&65" + }, + { + "id": 12, + "lv": 17, + "attr": "1&66" + }, + { + "id": 12, + "lv": 18, + "attr": "1&67" + }, + { + "id": 12, + "lv": 19, + "attr": "1&68" + }, + { + "id": 12, + "lv": 20, + "attr": "1&69" + }, + { + "id": 12, + "lv": 21, + "attr": "1&70" + }, + { + "id": 12, + "lv": 22, + "attr": "1&71" + }, + { + "id": 12, + "lv": 23, + "attr": "1&72" + }, + { + "id": 12, + "lv": 24, + "attr": "1&73" + }, + { + "id": 12, + "lv": 25, + "attr": "1&74" + }, + { + "id": 12, + "lv": 26, + "attr": "1&75" + }, + { + "id": 12, + "lv": 27, + "attr": "1&76" + }, + { + "id": 12, + "lv": 28, + "attr": "1&77" + }, + { + "id": 12, + "lv": 29, + "attr": "1&78" + }, + { + "id": 12, + "lv": 30, + "attr": "1&79" + }, + { + "id": 12, + "lv": 31, + "attr": "1&80" + }, + { + "id": 12, + "lv": 32, + "attr": "1&81" + }, + { + "id": 12, + "lv": 33, + "attr": "1&82" + }, + { + "id": 12, + "lv": 34, + "attr": "1&83" + }, + { + "id": 12, + "lv": 35, + "attr": "1&84" + }, + { + "id": 12, + "lv": 36, + "attr": "1&85" + }, + { + "id": 12, + "lv": 37, + "attr": "1&86" + }, + { + "id": 12, + "lv": 38, + "attr": "1&87" + }, + { + "id": 12, + "lv": 39, + "attr": "1&88" + }, + { + "id": 12, + "lv": 40, + "attr": "1&89" + }, + { + "id": 12, + "lv": 41, + "attr": "1&90" + }, + { + "id": 12, + "lv": 42, + "attr": "1&91" + }, + { + "id": 12, + "lv": 43, + "attr": "1&92" + }, + { + "id": 12, + "lv": 44, + "attr": "1&93" + }, + { + "id": 12, + "lv": 45, + "attr": "1&94" + }, + { + "id": 12, + "lv": 46, + "attr": "1&95" + }, + { + "id": 12, + "lv": 47, + "attr": "1&96" + }, + { + "id": 12, + "lv": 48, + "attr": "1&97" + }, + { + "id": 12, + "lv": 49, + "attr": "1&98" + }, + { + "id": 12, + "lv": 50, + "attr": "1&99" + }, + { + "id": 12, + "lv": 51, + "attr": "1&100" + }, + { + "id": 12, + "lv": 52, + "attr": "1&101" + }, + { + "id": 12, + "lv": 53, + "attr": "1&102" + }, + { + "id": 12, + "lv": 54, + "attr": "1&103" + }, + { + "id": 12, + "lv": 55, + "attr": "1&104" + }, + { + "id": 12, + "lv": 56, + "attr": "1&105" + }, + { + "id": 12, + "lv": 57, + "attr": "1&106" + }, + { + "id": 12, + "lv": 58, + "attr": "1&107" + }, + { + "id": 12, + "lv": 59, + "attr": "1&108" + }, + { + "id": 12, + "lv": 60, + "attr": "1&109" + }, + { + "id": 12, + "lv": 61, + "attr": "1&110" + }, + { + "id": 12, + "lv": 62, + "attr": "1&111" + }, + { + "id": 12, + "lv": 63, + "attr": "1&112" + }, + { + "id": 12, + "lv": 64, + "attr": "1&113" + }, + { + "id": 12, + "lv": 65, + "attr": "1&114" + }, + { + "id": 12, + "lv": 66, + "attr": "1&115" + }, + { + "id": 12, + "lv": 67, + "attr": "1&116" + }, + { + "id": 12, + "lv": 68, + "attr": "1&117" + }, + { + "id": 12, + "lv": 69, + "attr": "1&118" + }, + { + "id": 12, + "lv": 70, + "attr": "1&119" + }, + { + "id": 12, + "lv": 71, + "attr": "1&120" + }, + { + "id": 12, + "lv": 72, + "attr": "1&121" + }, + { + "id": 12, + "lv": 73, + "attr": "1&122" + }, + { + "id": 12, + "lv": 74, + "attr": "1&123" + }, + { + "id": 12, + "lv": 75, + "attr": "1&124" + }, + { + "id": 12, + "lv": 76, + "attr": "1&125" + }, + { + "id": 12, + "lv": 77, + "attr": "1&126" + }, + { + "id": 12, + "lv": 78, + "attr": "1&127" + }, + { + "id": 12, + "lv": 79, + "attr": "1&128" + }, + { + "id": 12, + "lv": 80, + "attr": "1&129" + }, + { + "id": 12, + "lv": 81, + "attr": "1&130" + }, + { + "id": 12, + "lv": 82, + "attr": "1&131" + }, + { + "id": 12, + "lv": 83, + "attr": "1&132" + }, + { + "id": 12, + "lv": 84, + "attr": "1&133" + }, + { + "id": 12, + "lv": 85, + "attr": "1&134" + }, + { + "id": 12, + "lv": 86, + "attr": "1&135" + }, + { + "id": 12, + "lv": 87, + "attr": "1&136" + }, + { + "id": 12, + "lv": 88, + "attr": "1&137" + }, + { + "id": 12, + "lv": 89, + "attr": "1&138" + }, + { + "id": 12, + "lv": 90, + "attr": "1&139" + }, + { + "id": 12, + "lv": 91, + "attr": "1&140" + }, + { + "id": 12, + "lv": 92, + "attr": "1&141" + }, + { + "id": 12, + "lv": 93, + "attr": "1&142" + }, + { + "id": 12, + "lv": 94, + "attr": "1&143" + }, + { + "id": 12, + "lv": 95, + "attr": "1&144" + }, + { + "id": 12, + "lv": 96, + "attr": "1&145" + }, + { + "id": 12, + "lv": 97, + "attr": "1&146" + }, + { + "id": 12, + "lv": 98, + "attr": "1&147" + }, + { + "id": 12, + "lv": 99, + "attr": "1&148" + }, + { + "id": 12, + "lv": 100, + "attr": "1&149" + }, + { + "id": 13, + "lv": 1, + "attr": "2&10" + }, + { + "id": 13, + "lv": 2, + "attr": "2&11" + }, + { + "id": 13, + "lv": 3, + "attr": "2&12" + }, + { + "id": 13, + "lv": 4, + "attr": "2&13" + }, + { + "id": 13, + "lv": 5, + "attr": "2&14" + }, + { + "id": 13, + "lv": 6, + "attr": "2&15" + }, + { + "id": 13, + "lv": 7, + "attr": "2&16" + }, + { + "id": 13, + "lv": 8, + "attr": "2&17" + }, + { + "id": 13, + "lv": 9, + "attr": "2&18" + }, + { + "id": 13, + "lv": 10, + "attr": "2&19" + }, + { + "id": 13, + "lv": 11, + "attr": "2&20" + }, + { + "id": 13, + "lv": 12, + "attr": "2&21" + }, + { + "id": 13, + "lv": 13, + "attr": "2&22" + }, + { + "id": 13, + "lv": 14, + "attr": "2&23" + }, + { + "id": 13, + "lv": 15, + "attr": "2&24" + }, + { + "id": 13, + "lv": 16, + "attr": "2&25" + }, + { + "id": 13, + "lv": 17, + "attr": "2&26" + }, + { + "id": 13, + "lv": 18, + "attr": "2&27" + }, + { + "id": 13, + "lv": 19, + "attr": "2&28" + }, + { + "id": 13, + "lv": 20, + "attr": "2&29" + }, + { + "id": 13, + "lv": 21, + "attr": "2&30" + }, + { + "id": 13, + "lv": 22, + "attr": "2&31" + }, + { + "id": 13, + "lv": 23, + "attr": "2&32" + }, + { + "id": 13, + "lv": 24, + "attr": "2&33" + }, + { + "id": 13, + "lv": 25, + "attr": "2&34" + }, + { + "id": 13, + "lv": 26, + "attr": "2&35" + }, + { + "id": 13, + "lv": 27, + "attr": "2&36" + }, + { + "id": 13, + "lv": 28, + "attr": "2&37" + }, + { + "id": 13, + "lv": 29, + "attr": "2&38" + }, + { + "id": 13, + "lv": 30, + "attr": "2&39" + }, + { + "id": 13, + "lv": 31, + "attr": "2&40" + }, + { + "id": 13, + "lv": 32, + "attr": "2&41" + }, + { + "id": 13, + "lv": 33, + "attr": "2&42" + }, + { + "id": 13, + "lv": 34, + "attr": "2&43" + }, + { + "id": 13, + "lv": 35, + "attr": "2&44" + }, + { + "id": 13, + "lv": 36, + "attr": "2&45" + }, + { + "id": 13, + "lv": 37, + "attr": "2&46" + }, + { + "id": 13, + "lv": 38, + "attr": "2&47" + }, + { + "id": 13, + "lv": 39, + "attr": "2&48" + }, + { + "id": 13, + "lv": 40, + "attr": "2&49" + }, + { + "id": 13, + "lv": 41, + "attr": "2&50" + }, + { + "id": 13, + "lv": 42, + "attr": "2&51" + }, + { + "id": 13, + "lv": 43, + "attr": "2&52" + }, + { + "id": 13, + "lv": 44, + "attr": "2&53" + }, + { + "id": 13, + "lv": 45, + "attr": "2&54" + }, + { + "id": 13, + "lv": 46, + "attr": "2&55" + }, + { + "id": 13, + "lv": 47, + "attr": "2&56" + }, + { + "id": 13, + "lv": 48, + "attr": "2&57" + }, + { + "id": 13, + "lv": 49, + "attr": "2&58" + }, + { + "id": 13, + "lv": 50, + "attr": "2&59" + }, + { + "id": 13, + "lv": 51, + "attr": "2&60" + }, + { + "id": 13, + "lv": 52, + "attr": "2&61" + }, + { + "id": 13, + "lv": 53, + "attr": "2&62" + }, + { + "id": 13, + "lv": 54, + "attr": "2&63" + }, + { + "id": 13, + "lv": 55, + "attr": "2&64" + }, + { + "id": 13, + "lv": 56, + "attr": "2&65" + }, + { + "id": 13, + "lv": 57, + "attr": "2&66" + }, + { + "id": 13, + "lv": 58, + "attr": "2&67" + }, + { + "id": 13, + "lv": 59, + "attr": "2&68" + }, + { + "id": 13, + "lv": 60, + "attr": "2&69" + }, + { + "id": 13, + "lv": 61, + "attr": "2&70" + }, + { + "id": 13, + "lv": 62, + "attr": "2&71" + }, + { + "id": 13, + "lv": 63, + "attr": "2&72" + }, + { + "id": 13, + "lv": 64, + "attr": "2&73" + }, + { + "id": 13, + "lv": 65, + "attr": "2&74" + }, + { + "id": 13, + "lv": 66, + "attr": "2&75" + }, + { + "id": 13, + "lv": 67, + "attr": "2&76" + }, + { + "id": 13, + "lv": 68, + "attr": "2&77" + }, + { + "id": 13, + "lv": 69, + "attr": "2&78" + }, + { + "id": 13, + "lv": 70, + "attr": "2&79" + }, + { + "id": 13, + "lv": 71, + "attr": "2&80" + }, + { + "id": 13, + "lv": 72, + "attr": "2&81" + }, + { + "id": 13, + "lv": 73, + "attr": "2&82" + }, + { + "id": 13, + "lv": 74, + "attr": "2&83" + }, + { + "id": 13, + "lv": 75, + "attr": "2&84" + }, + { + "id": 13, + "lv": 76, + "attr": "2&85" + }, + { + "id": 13, + "lv": 77, + "attr": "2&86" + }, + { + "id": 13, + "lv": 78, + "attr": "2&87" + }, + { + "id": 13, + "lv": 79, + "attr": "2&88" + }, + { + "id": 13, + "lv": 80, + "attr": "2&89" + }, + { + "id": 13, + "lv": 81, + "attr": "2&90" + }, + { + "id": 13, + "lv": 82, + "attr": "2&91" + }, + { + "id": 13, + "lv": 83, + "attr": "2&92" + }, + { + "id": 13, + "lv": 84, + "attr": "2&93" + }, + { + "id": 13, + "lv": 85, + "attr": "2&94" + }, + { + "id": 13, + "lv": 86, + "attr": "2&95" + }, + { + "id": 13, + "lv": 87, + "attr": "2&96" + }, + { + "id": 13, + "lv": 88, + "attr": "2&97" + }, + { + "id": 13, + "lv": 89, + "attr": "2&98" + }, + { + "id": 13, + "lv": 90, + "attr": "2&99" + }, + { + "id": 13, + "lv": 91, + "attr": "2&100" + }, + { + "id": 13, + "lv": 92, + "attr": "2&101" + }, + { + "id": 13, + "lv": 93, + "attr": "2&102" + }, + { + "id": 13, + "lv": 94, + "attr": "2&103" + }, + { + "id": 13, + "lv": 95, + "attr": "2&104" + }, + { + "id": 13, + "lv": 96, + "attr": "2&105" + }, + { + "id": 13, + "lv": 97, + "attr": "2&106" + }, + { + "id": 13, + "lv": 98, + "attr": "2&107" + }, + { + "id": 13, + "lv": 99, + "attr": "2&108" + }, + { + "id": 13, + "lv": 100, + "attr": "2&109" + }, + { + "id": 14, + "lv": 1, + "attr": "4&20" + }, + { + "id": 14, + "lv": 2, + "attr": "4&21" + }, + { + "id": 14, + "lv": 3, + "attr": "4&22" + }, + { + "id": 14, + "lv": 4, + "attr": "4&23" + }, + { + "id": 14, + "lv": 5, + "attr": "4&24" + }, + { + "id": 14, + "lv": 6, + "attr": "4&25" + }, + { + "id": 14, + "lv": 7, + "attr": "4&26" + }, + { + "id": 14, + "lv": 8, + "attr": "4&27" + }, + { + "id": 14, + "lv": 9, + "attr": "4&28" + }, + { + "id": 14, + "lv": 10, + "attr": "4&29" + }, + { + "id": 14, + "lv": 11, + "attr": "4&30" + }, + { + "id": 14, + "lv": 12, + "attr": "4&31" + }, + { + "id": 14, + "lv": 13, + "attr": "4&32" + }, + { + "id": 14, + "lv": 14, + "attr": "4&33" + }, + { + "id": 14, + "lv": 15, + "attr": "4&34" + }, + { + "id": 14, + "lv": 16, + "attr": "4&35" + }, + { + "id": 14, + "lv": 17, + "attr": "4&36" + }, + { + "id": 14, + "lv": 18, + "attr": "4&37" + }, + { + "id": 14, + "lv": 19, + "attr": "4&38" + }, + { + "id": 14, + "lv": 20, + "attr": "4&39" + }, + { + "id": 14, + "lv": 21, + "attr": "4&40" + }, + { + "id": 14, + "lv": 22, + "attr": "4&41" + }, + { + "id": 14, + "lv": 23, + "attr": "4&42" + }, + { + "id": 14, + "lv": 24, + "attr": "4&43" + }, + { + "id": 14, + "lv": 25, + "attr": "4&44" + }, + { + "id": 14, + "lv": 26, + "attr": "4&45" + }, + { + "id": 14, + "lv": 27, + "attr": "4&46" + }, + { + "id": 14, + "lv": 28, + "attr": "4&47" + }, + { + "id": 14, + "lv": 29, + "attr": "4&48" + }, + { + "id": 14, + "lv": 30, + "attr": "4&49" + }, + { + "id": 14, + "lv": 31, + "attr": "4&50" + }, + { + "id": 14, + "lv": 32, + "attr": "4&51" + }, + { + "id": 14, + "lv": 33, + "attr": "4&52" + }, + { + "id": 14, + "lv": 34, + "attr": "4&53" + }, + { + "id": 14, + "lv": 35, + "attr": "4&54" + }, + { + "id": 14, + "lv": 36, + "attr": "4&55" + }, + { + "id": 14, + "lv": 37, + "attr": "4&56" + }, + { + "id": 14, + "lv": 38, + "attr": "4&57" + }, + { + "id": 14, + "lv": 39, + "attr": "4&58" + }, + { + "id": 14, + "lv": 40, + "attr": "4&59" + }, + { + "id": 14, + "lv": 41, + "attr": "4&60" + }, + { + "id": 14, + "lv": 42, + "attr": "4&61" + }, + { + "id": 14, + "lv": 43, + "attr": "4&62" + }, + { + "id": 14, + "lv": 44, + "attr": "4&63" + }, + { + "id": 14, + "lv": 45, + "attr": "4&64" + }, + { + "id": 14, + "lv": 46, + "attr": "4&65" + }, + { + "id": 14, + "lv": 47, + "attr": "4&66" + }, + { + "id": 14, + "lv": 48, + "attr": "4&67" + }, + { + "id": 14, + "lv": 49, + "attr": "4&68" + }, + { + "id": 14, + "lv": 50, + "attr": "4&69" + }, + { + "id": 14, + "lv": 51, + "attr": "4&70" + }, + { + "id": 14, + "lv": 52, + "attr": "4&71" + }, + { + "id": 14, + "lv": 53, + "attr": "4&72" + }, + { + "id": 14, + "lv": 54, + "attr": "4&73" + }, + { + "id": 14, + "lv": 55, + "attr": "4&74" + }, + { + "id": 14, + "lv": 56, + "attr": "4&75" + }, + { + "id": 14, + "lv": 57, + "attr": "4&76" + }, + { + "id": 14, + "lv": 58, + "attr": "4&77" + }, + { + "id": 14, + "lv": 59, + "attr": "4&78" + }, + { + "id": 14, + "lv": 60, + "attr": "4&79" + }, + { + "id": 14, + "lv": 61, + "attr": "4&80" + }, + { + "id": 14, + "lv": 62, + "attr": "4&81" + }, + { + "id": 14, + "lv": 63, + "attr": "4&82" + }, + { + "id": 14, + "lv": 64, + "attr": "4&83" + }, + { + "id": 14, + "lv": 65, + "attr": "4&84" + }, + { + "id": 14, + "lv": 66, + "attr": "4&85" + }, + { + "id": 14, + "lv": 67, + "attr": "4&86" + }, + { + "id": 14, + "lv": 68, + "attr": "4&87" + }, + { + "id": 14, + "lv": 69, + "attr": "4&88" + }, + { + "id": 14, + "lv": 70, + "attr": "4&89" + }, + { + "id": 14, + "lv": 71, + "attr": "4&90" + }, + { + "id": 14, + "lv": 72, + "attr": "4&91" + }, + { + "id": 14, + "lv": 73, + "attr": "4&92" + }, + { + "id": 14, + "lv": 74, + "attr": "4&93" + }, + { + "id": 14, + "lv": 75, + "attr": "4&94" + }, + { + "id": 14, + "lv": 76, + "attr": "4&95" + }, + { + "id": 14, + "lv": 77, + "attr": "4&96" + }, + { + "id": 14, + "lv": 78, + "attr": "4&97" + }, + { + "id": 14, + "lv": 79, + "attr": "4&98" + }, + { + "id": 14, + "lv": 80, + "attr": "4&99" + }, + { + "id": 14, + "lv": 81, + "attr": "4&100" + }, + { + "id": 14, + "lv": 82, + "attr": "4&101" + }, + { + "id": 14, + "lv": 83, + "attr": "4&102" + }, + { + "id": 14, + "lv": 84, + "attr": "4&103" + }, + { + "id": 14, + "lv": 85, + "attr": "4&104" + }, + { + "id": 14, + "lv": 86, + "attr": "4&105" + }, + { + "id": 14, + "lv": 87, + "attr": "4&106" + }, + { + "id": 14, + "lv": 88, + "attr": "4&107" + }, + { + "id": 14, + "lv": 89, + "attr": "4&108" + }, + { + "id": 14, + "lv": 90, + "attr": "4&109" + }, + { + "id": 14, + "lv": 91, + "attr": "4&110" + }, + { + "id": 14, + "lv": 92, + "attr": "4&111" + }, + { + "id": 14, + "lv": 93, + "attr": "4&112" + }, + { + "id": 14, + "lv": 94, + "attr": "4&113" + }, + { + "id": 14, + "lv": 95, + "attr": "4&114" + }, + { + "id": 14, + "lv": 96, + "attr": "4&115" + }, + { + "id": 14, + "lv": 97, + "attr": "4&116" + }, + { + "id": 14, + "lv": 98, + "attr": "4&117" + }, + { + "id": 14, + "lv": 99, + "attr": "4&118" + }, + { + "id": 14, + "lv": 100, + "attr": "4&119" + }, + { + "id": 15, + "lv": 1, + "attr": "5&20" + }, + { + "id": 15, + "lv": 2, + "attr": "5&21" + }, + { + "id": 15, + "lv": 3, + "attr": "5&22" + }, + { + "id": 15, + "lv": 4, + "attr": "5&23" + }, + { + "id": 15, + "lv": 5, + "attr": "5&24" + }, + { + "id": 15, + "lv": 6, + "attr": "5&25" + }, + { + "id": 15, + "lv": 7, + "attr": "5&26" + }, + { + "id": 15, + "lv": 8, + "attr": "5&27" + }, + { + "id": 15, + "lv": 9, + "attr": "5&28" + }, + { + "id": 15, + "lv": 10, + "attr": "5&29" + }, + { + "id": 15, + "lv": 11, + "attr": "5&30" + }, + { + "id": 15, + "lv": 12, + "attr": "5&31" + }, + { + "id": 15, + "lv": 13, + "attr": "5&32" + }, + { + "id": 15, + "lv": 14, + "attr": "5&33" + }, + { + "id": 15, + "lv": 15, + "attr": "5&34" + }, + { + "id": 15, + "lv": 16, + "attr": "5&35" + }, + { + "id": 15, + "lv": 17, + "attr": "5&36" + }, + { + "id": 15, + "lv": 18, + "attr": "5&37" + }, + { + "id": 15, + "lv": 19, + "attr": "5&38" + }, + { + "id": 15, + "lv": 20, + "attr": "5&39" + }, + { + "id": 15, + "lv": 21, + "attr": "5&40" + }, + { + "id": 15, + "lv": 22, + "attr": "5&41" + }, + { + "id": 15, + "lv": 23, + "attr": "5&42" + }, + { + "id": 15, + "lv": 24, + "attr": "5&43" + }, + { + "id": 15, + "lv": 25, + "attr": "5&44" + }, + { + "id": 15, + "lv": 26, + "attr": "5&45" + }, + { + "id": 15, + "lv": 27, + "attr": "5&46" + }, + { + "id": 15, + "lv": 28, + "attr": "5&47" + }, + { + "id": 15, + "lv": 29, + "attr": "5&48" + }, + { + "id": 15, + "lv": 30, + "attr": "5&49" + }, + { + "id": 15, + "lv": 31, + "attr": "5&50" + }, + { + "id": 15, + "lv": 32, + "attr": "5&51" + }, + { + "id": 15, + "lv": 33, + "attr": "5&52" + }, + { + "id": 15, + "lv": 34, + "attr": "5&53" + }, + { + "id": 15, + "lv": 35, + "attr": "5&54" + }, + { + "id": 15, + "lv": 36, + "attr": "5&55" + }, + { + "id": 15, + "lv": 37, + "attr": "5&56" + }, + { + "id": 15, + "lv": 38, + "attr": "5&57" + }, + { + "id": 15, + "lv": 39, + "attr": "5&58" + }, + { + "id": 15, + "lv": 40, + "attr": "5&59" + }, + { + "id": 15, + "lv": 41, + "attr": "5&60" + }, + { + "id": 15, + "lv": 42, + "attr": "5&61" + }, + { + "id": 15, + "lv": 43, + "attr": "5&62" + }, + { + "id": 15, + "lv": 44, + "attr": "5&63" + }, + { + "id": 15, + "lv": 45, + "attr": "5&64" + }, + { + "id": 15, + "lv": 46, + "attr": "5&65" + }, + { + "id": 15, + "lv": 47, + "attr": "5&66" + }, + { + "id": 15, + "lv": 48, + "attr": "5&67" + }, + { + "id": 15, + "lv": 49, + "attr": "5&68" + }, + { + "id": 15, + "lv": 50, + "attr": "5&69" + }, + { + "id": 15, + "lv": 51, + "attr": "5&70" + }, + { + "id": 15, + "lv": 52, + "attr": "5&71" + }, + { + "id": 15, + "lv": 53, + "attr": "5&72" + }, + { + "id": 15, + "lv": 54, + "attr": "5&73" + }, + { + "id": 15, + "lv": 55, + "attr": "5&74" + }, + { + "id": 15, + "lv": 56, + "attr": "5&75" + }, + { + "id": 15, + "lv": 57, + "attr": "5&76" + }, + { + "id": 15, + "lv": 58, + "attr": "5&77" + }, + { + "id": 15, + "lv": 59, + "attr": "5&78" + }, + { + "id": 15, + "lv": 60, + "attr": "5&79" + }, + { + "id": 15, + "lv": 61, + "attr": "5&80" + }, + { + "id": 15, + "lv": 62, + "attr": "5&81" + }, + { + "id": 15, + "lv": 63, + "attr": "5&82" + }, + { + "id": 15, + "lv": 64, + "attr": "5&83" + }, + { + "id": 15, + "lv": 65, + "attr": "5&84" + }, + { + "id": 15, + "lv": 66, + "attr": "5&85" + }, + { + "id": 15, + "lv": 67, + "attr": "5&86" + }, + { + "id": 15, + "lv": 68, + "attr": "5&87" + }, + { + "id": 15, + "lv": 69, + "attr": "5&88" + }, + { + "id": 15, + "lv": 70, + "attr": "5&89" + }, + { + "id": 15, + "lv": 71, + "attr": "5&90" + }, + { + "id": 15, + "lv": 72, + "attr": "5&91" + }, + { + "id": 15, + "lv": 73, + "attr": "5&92" + }, + { + "id": 15, + "lv": 74, + "attr": "5&93" + }, + { + "id": 15, + "lv": 75, + "attr": "5&94" + }, + { + "id": 15, + "lv": 76, + "attr": "5&95" + }, + { + "id": 15, + "lv": 77, + "attr": "5&96" + }, + { + "id": 15, + "lv": 78, + "attr": "5&97" + }, + { + "id": 15, + "lv": 79, + "attr": "5&98" + }, + { + "id": 15, + "lv": 80, + "attr": "5&99" + }, + { + "id": 15, + "lv": 81, + "attr": "5&100" + }, + { + "id": 15, + "lv": 82, + "attr": "5&101" + }, + { + "id": 15, + "lv": 83, + "attr": "5&102" + }, + { + "id": 15, + "lv": 84, + "attr": "5&103" + }, + { + "id": 15, + "lv": 85, + "attr": "5&104" + }, + { + "id": 15, + "lv": 86, + "attr": "5&105" + }, + { + "id": 15, + "lv": 87, + "attr": "5&106" + }, + { + "id": 15, + "lv": 88, + "attr": "5&107" + }, + { + "id": 15, + "lv": 89, + "attr": "5&108" + }, + { + "id": 15, + "lv": 90, + "attr": "5&109" + }, + { + "id": 15, + "lv": 91, + "attr": "5&110" + }, + { + "id": 15, + "lv": 92, + "attr": "5&111" + }, + { + "id": 15, + "lv": 93, + "attr": "5&112" + }, + { + "id": 15, + "lv": 94, + "attr": "5&113" + }, + { + "id": 15, + "lv": 95, + "attr": "5&114" + }, + { + "id": 15, + "lv": 96, + "attr": "5&115" + }, + { + "id": 15, + "lv": 97, + "attr": "5&116" + }, + { + "id": 15, + "lv": 98, + "attr": "5&117" + }, + { + "id": 15, + "lv": 99, + "attr": "5&118" + }, + { + "id": 15, + "lv": 100, + "attr": "5&119" + }, + { + "id": 16, + "lv": 1, + "attr": "1&50" + }, + { + "id": 16, + "lv": 2, + "attr": "1&51" + }, + { + "id": 16, + "lv": 3, + "attr": "1&52" + }, + { + "id": 16, + "lv": 4, + "attr": "1&53" + }, + { + "id": 16, + "lv": 5, + "attr": "1&54" + }, + { + "id": 16, + "lv": 6, + "attr": "1&55" + }, + { + "id": 16, + "lv": 7, + "attr": "1&56" + }, + { + "id": 16, + "lv": 8, + "attr": "1&57" + }, + { + "id": 16, + "lv": 9, + "attr": "1&58" + }, + { + "id": 16, + "lv": 10, + "attr": "1&59" + }, + { + "id": 16, + "lv": 11, + "attr": "1&60" + }, + { + "id": 16, + "lv": 12, + "attr": "1&61" + }, + { + "id": 16, + "lv": 13, + "attr": "1&62" + }, + { + "id": 16, + "lv": 14, + "attr": "1&63" + }, + { + "id": 16, + "lv": 15, + "attr": "1&64" + }, + { + "id": 16, + "lv": 16, + "attr": "1&65" + }, + { + "id": 16, + "lv": 17, + "attr": "1&66" + }, + { + "id": 16, + "lv": 18, + "attr": "1&67" + }, + { + "id": 16, + "lv": 19, + "attr": "1&68" + }, + { + "id": 16, + "lv": 20, + "attr": "1&69" + }, + { + "id": 16, + "lv": 21, + "attr": "1&70" + }, + { + "id": 16, + "lv": 22, + "attr": "1&71" + }, + { + "id": 16, + "lv": 23, + "attr": "1&72" + }, + { + "id": 16, + "lv": 24, + "attr": "1&73" + }, + { + "id": 16, + "lv": 25, + "attr": "1&74" + }, + { + "id": 16, + "lv": 26, + "attr": "1&75" + }, + { + "id": 16, + "lv": 27, + "attr": "1&76" + }, + { + "id": 16, + "lv": 28, + "attr": "1&77" + }, + { + "id": 16, + "lv": 29, + "attr": "1&78" + }, + { + "id": 16, + "lv": 30, + "attr": "1&79" + }, + { + "id": 16, + "lv": 31, + "attr": "1&80" + }, + { + "id": 16, + "lv": 32, + "attr": "1&81" + }, + { + "id": 16, + "lv": 33, + "attr": "1&82" + }, + { + "id": 16, + "lv": 34, + "attr": "1&83" + }, + { + "id": 16, + "lv": 35, + "attr": "1&84" + }, + { + "id": 16, + "lv": 36, + "attr": "1&85" + }, + { + "id": 16, + "lv": 37, + "attr": "1&86" + }, + { + "id": 16, + "lv": 38, + "attr": "1&87" + }, + { + "id": 16, + "lv": 39, + "attr": "1&88" + }, + { + "id": 16, + "lv": 40, + "attr": "1&89" + }, + { + "id": 16, + "lv": 41, + "attr": "1&90" + }, + { + "id": 16, + "lv": 42, + "attr": "1&91" + }, + { + "id": 16, + "lv": 43, + "attr": "1&92" + }, + { + "id": 16, + "lv": 44, + "attr": "1&93" + }, + { + "id": 16, + "lv": 45, + "attr": "1&94" + }, + { + "id": 16, + "lv": 46, + "attr": "1&95" + }, + { + "id": 16, + "lv": 47, + "attr": "1&96" + }, + { + "id": 16, + "lv": 48, + "attr": "1&97" + }, + { + "id": 16, + "lv": 49, + "attr": "1&98" + }, + { + "id": 16, + "lv": 50, + "attr": "1&99" + }, + { + "id": 16, + "lv": 51, + "attr": "1&100" + }, + { + "id": 16, + "lv": 52, + "attr": "1&101" + }, + { + "id": 16, + "lv": 53, + "attr": "1&102" + }, + { + "id": 16, + "lv": 54, + "attr": "1&103" + }, + { + "id": 16, + "lv": 55, + "attr": "1&104" + }, + { + "id": 16, + "lv": 56, + "attr": "1&105" + }, + { + "id": 16, + "lv": 57, + "attr": "1&106" + }, + { + "id": 16, + "lv": 58, + "attr": "1&107" + }, + { + "id": 16, + "lv": 59, + "attr": "1&108" + }, + { + "id": 16, + "lv": 60, + "attr": "1&109" + }, + { + "id": 16, + "lv": 61, + "attr": "1&110" + }, + { + "id": 16, + "lv": 62, + "attr": "1&111" + }, + { + "id": 16, + "lv": 63, + "attr": "1&112" + }, + { + "id": 16, + "lv": 64, + "attr": "1&113" + }, + { + "id": 16, + "lv": 65, + "attr": "1&114" + }, + { + "id": 16, + "lv": 66, + "attr": "1&115" + }, + { + "id": 16, + "lv": 67, + "attr": "1&116" + }, + { + "id": 16, + "lv": 68, + "attr": "1&117" + }, + { + "id": 16, + "lv": 69, + "attr": "1&118" + }, + { + "id": 16, + "lv": 70, + "attr": "1&119" + }, + { + "id": 16, + "lv": 71, + "attr": "1&120" + }, + { + "id": 16, + "lv": 72, + "attr": "1&121" + }, + { + "id": 16, + "lv": 73, + "attr": "1&122" + }, + { + "id": 16, + "lv": 74, + "attr": "1&123" + }, + { + "id": 16, + "lv": 75, + "attr": "1&124" + }, + { + "id": 16, + "lv": 76, + "attr": "1&125" + }, + { + "id": 16, + "lv": 77, + "attr": "1&126" + }, + { + "id": 16, + "lv": 78, + "attr": "1&127" + }, + { + "id": 16, + "lv": 79, + "attr": "1&128" + }, + { + "id": 16, + "lv": 80, + "attr": "1&129" + }, + { + "id": 16, + "lv": 81, + "attr": "1&130" + }, + { + "id": 16, + "lv": 82, + "attr": "1&131" + }, + { + "id": 16, + "lv": 83, + "attr": "1&132" + }, + { + "id": 16, + "lv": 84, + "attr": "1&133" + }, + { + "id": 16, + "lv": 85, + "attr": "1&134" + }, + { + "id": 16, + "lv": 86, + "attr": "1&135" + }, + { + "id": 16, + "lv": 87, + "attr": "1&136" + }, + { + "id": 16, + "lv": 88, + "attr": "1&137" + }, + { + "id": 16, + "lv": 89, + "attr": "1&138" + }, + { + "id": 16, + "lv": 90, + "attr": "1&139" + }, + { + "id": 16, + "lv": 91, + "attr": "1&140" + }, + { + "id": 16, + "lv": 92, + "attr": "1&141" + }, + { + "id": 16, + "lv": 93, + "attr": "1&142" + }, + { + "id": 16, + "lv": 94, + "attr": "1&143" + }, + { + "id": 16, + "lv": 95, + "attr": "1&144" + }, + { + "id": 16, + "lv": 96, + "attr": "1&145" + }, + { + "id": 16, + "lv": 97, + "attr": "1&146" + }, + { + "id": 16, + "lv": 98, + "attr": "1&147" + }, + { + "id": 16, + "lv": 99, + "attr": "1&148" + }, + { + "id": 16, + "lv": 100, + "attr": "1&149" + }, + { + "id": 17, + "lv": 1, + "attr": "2&10" + }, + { + "id": 17, + "lv": 2, + "attr": "2&11" + }, + { + "id": 17, + "lv": 3, + "attr": "2&12" + }, + { + "id": 17, + "lv": 4, + "attr": "2&13" + }, + { + "id": 17, + "lv": 5, + "attr": "2&14" + }, + { + "id": 17, + "lv": 6, + "attr": "2&15" + }, + { + "id": 17, + "lv": 7, + "attr": "2&16" + }, + { + "id": 17, + "lv": 8, + "attr": "2&17" + }, + { + "id": 17, + "lv": 9, + "attr": "2&18" + }, + { + "id": 17, + "lv": 10, + "attr": "2&19" + }, + { + "id": 17, + "lv": 11, + "attr": "2&20" + }, + { + "id": 17, + "lv": 12, + "attr": "2&21" + }, + { + "id": 17, + "lv": 13, + "attr": "2&22" + }, + { + "id": 17, + "lv": 14, + "attr": "2&23" + }, + { + "id": 17, + "lv": 15, + "attr": "2&24" + }, + { + "id": 17, + "lv": 16, + "attr": "2&25" + }, + { + "id": 17, + "lv": 17, + "attr": "2&26" + }, + { + "id": 17, + "lv": 18, + "attr": "2&27" + }, + { + "id": 17, + "lv": 19, + "attr": "2&28" + }, + { + "id": 17, + "lv": 20, + "attr": "2&29" + }, + { + "id": 17, + "lv": 21, + "attr": "2&30" + }, + { + "id": 17, + "lv": 22, + "attr": "2&31" + }, + { + "id": 17, + "lv": 23, + "attr": "2&32" + }, + { + "id": 17, + "lv": 24, + "attr": "2&33" + }, + { + "id": 17, + "lv": 25, + "attr": "2&34" + }, + { + "id": 17, + "lv": 26, + "attr": "2&35" + }, + { + "id": 17, + "lv": 27, + "attr": "2&36" + }, + { + "id": 17, + "lv": 28, + "attr": "2&37" + }, + { + "id": 17, + "lv": 29, + "attr": "2&38" + }, + { + "id": 17, + "lv": 30, + "attr": "2&39" + }, + { + "id": 17, + "lv": 31, + "attr": "2&40" + }, + { + "id": 17, + "lv": 32, + "attr": "2&41" + }, + { + "id": 17, + "lv": 33, + "attr": "2&42" + }, + { + "id": 17, + "lv": 34, + "attr": "2&43" + }, + { + "id": 17, + "lv": 35, + "attr": "2&44" + }, + { + "id": 17, + "lv": 36, + "attr": "2&45" + }, + { + "id": 17, + "lv": 37, + "attr": "2&46" + }, + { + "id": 17, + "lv": 38, + "attr": "2&47" + }, + { + "id": 17, + "lv": 39, + "attr": "2&48" + }, + { + "id": 17, + "lv": 40, + "attr": "2&49" + }, + { + "id": 17, + "lv": 41, + "attr": "2&50" + }, + { + "id": 17, + "lv": 42, + "attr": "2&51" + }, + { + "id": 17, + "lv": 43, + "attr": "2&52" + }, + { + "id": 17, + "lv": 44, + "attr": "2&53" + }, + { + "id": 17, + "lv": 45, + "attr": "2&54" + }, + { + "id": 17, + "lv": 46, + "attr": "2&55" + }, + { + "id": 17, + "lv": 47, + "attr": "2&56" + }, + { + "id": 17, + "lv": 48, + "attr": "2&57" + }, + { + "id": 17, + "lv": 49, + "attr": "2&58" + }, + { + "id": 17, + "lv": 50, + "attr": "2&59" + }, + { + "id": 17, + "lv": 51, + "attr": "2&60" + }, + { + "id": 17, + "lv": 52, + "attr": "2&61" + }, + { + "id": 17, + "lv": 53, + "attr": "2&62" + }, + { + "id": 17, + "lv": 54, + "attr": "2&63" + }, + { + "id": 17, + "lv": 55, + "attr": "2&64" + }, + { + "id": 17, + "lv": 56, + "attr": "2&65" + }, + { + "id": 17, + "lv": 57, + "attr": "2&66" + }, + { + "id": 17, + "lv": 58, + "attr": "2&67" + }, + { + "id": 17, + "lv": 59, + "attr": "2&68" + }, + { + "id": 17, + "lv": 60, + "attr": "2&69" + }, + { + "id": 17, + "lv": 61, + "attr": "2&70" + }, + { + "id": 17, + "lv": 62, + "attr": "2&71" + }, + { + "id": 17, + "lv": 63, + "attr": "2&72" + }, + { + "id": 17, + "lv": 64, + "attr": "2&73" + }, + { + "id": 17, + "lv": 65, + "attr": "2&74" + }, + { + "id": 17, + "lv": 66, + "attr": "2&75" + }, + { + "id": 17, + "lv": 67, + "attr": "2&76" + }, + { + "id": 17, + "lv": 68, + "attr": "2&77" + }, + { + "id": 17, + "lv": 69, + "attr": "2&78" + }, + { + "id": 17, + "lv": 70, + "attr": "2&79" + }, + { + "id": 17, + "lv": 71, + "attr": "2&80" + }, + { + "id": 17, + "lv": 72, + "attr": "2&81" + }, + { + "id": 17, + "lv": 73, + "attr": "2&82" + }, + { + "id": 17, + "lv": 74, + "attr": "2&83" + }, + { + "id": 17, + "lv": 75, + "attr": "2&84" + }, + { + "id": 17, + "lv": 76, + "attr": "2&85" + }, + { + "id": 17, + "lv": 77, + "attr": "2&86" + }, + { + "id": 17, + "lv": 78, + "attr": "2&87" + }, + { + "id": 17, + "lv": 79, + "attr": "2&88" + }, + { + "id": 17, + "lv": 80, + "attr": "2&89" + }, + { + "id": 17, + "lv": 81, + "attr": "2&90" + }, + { + "id": 17, + "lv": 82, + "attr": "2&91" + }, + { + "id": 17, + "lv": 83, + "attr": "2&92" + }, + { + "id": 17, + "lv": 84, + "attr": "2&93" + }, + { + "id": 17, + "lv": 85, + "attr": "2&94" + }, + { + "id": 17, + "lv": 86, + "attr": "2&95" + }, + { + "id": 17, + "lv": 87, + "attr": "2&96" + }, + { + "id": 17, + "lv": 88, + "attr": "2&97" + }, + { + "id": 17, + "lv": 89, + "attr": "2&98" + }, + { + "id": 17, + "lv": 90, + "attr": "2&99" + }, + { + "id": 17, + "lv": 91, + "attr": "2&100" + }, + { + "id": 17, + "lv": 92, + "attr": "2&101" + }, + { + "id": 17, + "lv": 93, + "attr": "2&102" + }, + { + "id": 17, + "lv": 94, + "attr": "2&103" + }, + { + "id": 17, + "lv": 95, + "attr": "2&104" + }, + { + "id": 17, + "lv": 96, + "attr": "2&105" + }, + { + "id": 17, + "lv": 97, + "attr": "2&106" + }, + { + "id": 17, + "lv": 98, + "attr": "2&107" + }, + { + "id": 17, + "lv": 99, + "attr": "2&108" + }, + { + "id": 17, + "lv": 100, + "attr": "2&109" + }, + { + "id": 18, + "lv": 1, + "attr": "4&20" + }, + { + "id": 18, + "lv": 2, + "attr": "4&21" + }, + { + "id": 18, + "lv": 3, + "attr": "4&22" + }, + { + "id": 18, + "lv": 4, + "attr": "4&23" + }, + { + "id": 18, + "lv": 5, + "attr": "4&24" + }, + { + "id": 18, + "lv": 6, + "attr": "4&25" + }, + { + "id": 18, + "lv": 7, + "attr": "4&26" + }, + { + "id": 18, + "lv": 8, + "attr": "4&27" + }, + { + "id": 18, + "lv": 9, + "attr": "4&28" + }, + { + "id": 18, + "lv": 10, + "attr": "4&29" + }, + { + "id": 18, + "lv": 11, + "attr": "4&30" + }, + { + "id": 18, + "lv": 12, + "attr": "4&31" + }, + { + "id": 18, + "lv": 13, + "attr": "4&32" + }, + { + "id": 18, + "lv": 14, + "attr": "4&33" + }, + { + "id": 18, + "lv": 15, + "attr": "4&34" + }, + { + "id": 18, + "lv": 16, + "attr": "4&35" + }, + { + "id": 18, + "lv": 17, + "attr": "4&36" + }, + { + "id": 18, + "lv": 18, + "attr": "4&37" + }, + { + "id": 18, + "lv": 19, + "attr": "4&38" + }, + { + "id": 18, + "lv": 20, + "attr": "4&39" + }, + { + "id": 18, + "lv": 21, + "attr": "4&40" + }, + { + "id": 18, + "lv": 22, + "attr": "4&41" + }, + { + "id": 18, + "lv": 23, + "attr": "4&42" + }, + { + "id": 18, + "lv": 24, + "attr": "4&43" + }, + { + "id": 18, + "lv": 25, + "attr": "4&44" + }, + { + "id": 18, + "lv": 26, + "attr": "4&45" + }, + { + "id": 18, + "lv": 27, + "attr": "4&46" + }, + { + "id": 18, + "lv": 28, + "attr": "4&47" + }, + { + "id": 18, + "lv": 29, + "attr": "4&48" + }, + { + "id": 18, + "lv": 30, + "attr": "4&49" + }, + { + "id": 18, + "lv": 31, + "attr": "4&50" + }, + { + "id": 18, + "lv": 32, + "attr": "4&51" + }, + { + "id": 18, + "lv": 33, + "attr": "4&52" + }, + { + "id": 18, + "lv": 34, + "attr": "4&53" + }, + { + "id": 18, + "lv": 35, + "attr": "4&54" + }, + { + "id": 18, + "lv": 36, + "attr": "4&55" + }, + { + "id": 18, + "lv": 37, + "attr": "4&56" + }, + { + "id": 18, + "lv": 38, + "attr": "4&57" + }, + { + "id": 18, + "lv": 39, + "attr": "4&58" + }, + { + "id": 18, + "lv": 40, + "attr": "4&59" + }, + { + "id": 18, + "lv": 41, + "attr": "4&60" + }, + { + "id": 18, + "lv": 42, + "attr": "4&61" + }, + { + "id": 18, + "lv": 43, + "attr": "4&62" + }, + { + "id": 18, + "lv": 44, + "attr": "4&63" + }, + { + "id": 18, + "lv": 45, + "attr": "4&64" + }, + { + "id": 18, + "lv": 46, + "attr": "4&65" + }, + { + "id": 18, + "lv": 47, + "attr": "4&66" + }, + { + "id": 18, + "lv": 48, + "attr": "4&67" + }, + { + "id": 18, + "lv": 49, + "attr": "4&68" + }, + { + "id": 18, + "lv": 50, + "attr": "4&69" + }, + { + "id": 18, + "lv": 51, + "attr": "4&70" + }, + { + "id": 18, + "lv": 52, + "attr": "4&71" + }, + { + "id": 18, + "lv": 53, + "attr": "4&72" + }, + { + "id": 18, + "lv": 54, + "attr": "4&73" + }, + { + "id": 18, + "lv": 55, + "attr": "4&74" + }, + { + "id": 18, + "lv": 56, + "attr": "4&75" + }, + { + "id": 18, + "lv": 57, + "attr": "4&76" + }, + { + "id": 18, + "lv": 58, + "attr": "4&77" + }, + { + "id": 18, + "lv": 59, + "attr": "4&78" + }, + { + "id": 18, + "lv": 60, + "attr": "4&79" + }, + { + "id": 18, + "lv": 61, + "attr": "4&80" + }, + { + "id": 18, + "lv": 62, + "attr": "4&81" + }, + { + "id": 18, + "lv": 63, + "attr": "4&82" + }, + { + "id": 18, + "lv": 64, + "attr": "4&83" + }, + { + "id": 18, + "lv": 65, + "attr": "4&84" + }, + { + "id": 18, + "lv": 66, + "attr": "4&85" + }, + { + "id": 18, + "lv": 67, + "attr": "4&86" + }, + { + "id": 18, + "lv": 68, + "attr": "4&87" + }, + { + "id": 18, + "lv": 69, + "attr": "4&88" + }, + { + "id": 18, + "lv": 70, + "attr": "4&89" + }, + { + "id": 18, + "lv": 71, + "attr": "4&90" + }, + { + "id": 18, + "lv": 72, + "attr": "4&91" + }, + { + "id": 18, + "lv": 73, + "attr": "4&92" + }, + { + "id": 18, + "lv": 74, + "attr": "4&93" + }, + { + "id": 18, + "lv": 75, + "attr": "4&94" + }, + { + "id": 18, + "lv": 76, + "attr": "4&95" + }, + { + "id": 18, + "lv": 77, + "attr": "4&96" + }, + { + "id": 18, + "lv": 78, + "attr": "4&97" + }, + { + "id": 18, + "lv": 79, + "attr": "4&98" + }, + { + "id": 18, + "lv": 80, + "attr": "4&99" + }, + { + "id": 18, + "lv": 81, + "attr": "4&100" + }, + { + "id": 18, + "lv": 82, + "attr": "4&101" + }, + { + "id": 18, + "lv": 83, + "attr": "4&102" + }, + { + "id": 18, + "lv": 84, + "attr": "4&103" + }, + { + "id": 18, + "lv": 85, + "attr": "4&104" + }, + { + "id": 18, + "lv": 86, + "attr": "4&105" + }, + { + "id": 18, + "lv": 87, + "attr": "4&106" + }, + { + "id": 18, + "lv": 88, + "attr": "4&107" + }, + { + "id": 18, + "lv": 89, + "attr": "4&108" + }, + { + "id": 18, + "lv": 90, + "attr": "4&109" + }, + { + "id": 18, + "lv": 91, + "attr": "4&110" + }, + { + "id": 18, + "lv": 92, + "attr": "4&111" + }, + { + "id": 18, + "lv": 93, + "attr": "4&112" + }, + { + "id": 18, + "lv": 94, + "attr": "4&113" + }, + { + "id": 18, + "lv": 95, + "attr": "4&114" + }, + { + "id": 18, + "lv": 96, + "attr": "4&115" + }, + { + "id": 18, + "lv": 97, + "attr": "4&116" + }, + { + "id": 18, + "lv": 98, + "attr": "4&117" + }, + { + "id": 18, + "lv": 99, + "attr": "4&118" + }, + { + "id": 18, + "lv": 100, + "attr": "4&119" + }, + { + "id": 19, + "lv": 1, + "attr": "5&20" + }, + { + "id": 19, + "lv": 2, + "attr": "5&21" + }, + { + "id": 19, + "lv": 3, + "attr": "5&22" + }, + { + "id": 19, + "lv": 4, + "attr": "5&23" + }, + { + "id": 19, + "lv": 5, + "attr": "5&24" + }, + { + "id": 19, + "lv": 6, + "attr": "5&25" + }, + { + "id": 19, + "lv": 7, + "attr": "5&26" + }, + { + "id": 19, + "lv": 8, + "attr": "5&27" + }, + { + "id": 19, + "lv": 9, + "attr": "5&28" + }, + { + "id": 19, + "lv": 10, + "attr": "5&29" + }, + { + "id": 19, + "lv": 11, + "attr": "5&30" + }, + { + "id": 19, + "lv": 12, + "attr": "5&31" + }, + { + "id": 19, + "lv": 13, + "attr": "5&32" + }, + { + "id": 19, + "lv": 14, + "attr": "5&33" + }, + { + "id": 19, + "lv": 15, + "attr": "5&34" + }, + { + "id": 19, + "lv": 16, + "attr": "5&35" + }, + { + "id": 19, + "lv": 17, + "attr": "5&36" + }, + { + "id": 19, + "lv": 18, + "attr": "5&37" + }, + { + "id": 19, + "lv": 19, + "attr": "5&38" + }, + { + "id": 19, + "lv": 20, + "attr": "5&39" + }, + { + "id": 19, + "lv": 21, + "attr": "5&40" + }, + { + "id": 19, + "lv": 22, + "attr": "5&41" + }, + { + "id": 19, + "lv": 23, + "attr": "5&42" + }, + { + "id": 19, + "lv": 24, + "attr": "5&43" + }, + { + "id": 19, + "lv": 25, + "attr": "5&44" + }, + { + "id": 19, + "lv": 26, + "attr": "5&45" + }, + { + "id": 19, + "lv": 27, + "attr": "5&46" + }, + { + "id": 19, + "lv": 28, + "attr": "5&47" + }, + { + "id": 19, + "lv": 29, + "attr": "5&48" + }, + { + "id": 19, + "lv": 30, + "attr": "5&49" + }, + { + "id": 19, + "lv": 31, + "attr": "5&50" + }, + { + "id": 19, + "lv": 32, + "attr": "5&51" + }, + { + "id": 19, + "lv": 33, + "attr": "5&52" + }, + { + "id": 19, + "lv": 34, + "attr": "5&53" + }, + { + "id": 19, + "lv": 35, + "attr": "5&54" + }, + { + "id": 19, + "lv": 36, + "attr": "5&55" + }, + { + "id": 19, + "lv": 37, + "attr": "5&56" + }, + { + "id": 19, + "lv": 38, + "attr": "5&57" + }, + { + "id": 19, + "lv": 39, + "attr": "5&58" + }, + { + "id": 19, + "lv": 40, + "attr": "5&59" + }, + { + "id": 19, + "lv": 41, + "attr": "5&60" + }, + { + "id": 19, + "lv": 42, + "attr": "5&61" + }, + { + "id": 19, + "lv": 43, + "attr": "5&62" + }, + { + "id": 19, + "lv": 44, + "attr": "5&63" + }, + { + "id": 19, + "lv": 45, + "attr": "5&64" + }, + { + "id": 19, + "lv": 46, + "attr": "5&65" + }, + { + "id": 19, + "lv": 47, + "attr": "5&66" + }, + { + "id": 19, + "lv": 48, + "attr": "5&67" + }, + { + "id": 19, + "lv": 49, + "attr": "5&68" + }, + { + "id": 19, + "lv": 50, + "attr": "5&69" + }, + { + "id": 19, + "lv": 51, + "attr": "5&70" + }, + { + "id": 19, + "lv": 52, + "attr": "5&71" + }, + { + "id": 19, + "lv": 53, + "attr": "5&72" + }, + { + "id": 19, + "lv": 54, + "attr": "5&73" + }, + { + "id": 19, + "lv": 55, + "attr": "5&74" + }, + { + "id": 19, + "lv": 56, + "attr": "5&75" + }, + { + "id": 19, + "lv": 57, + "attr": "5&76" + }, + { + "id": 19, + "lv": 58, + "attr": "5&77" + }, + { + "id": 19, + "lv": 59, + "attr": "5&78" + }, + { + "id": 19, + "lv": 60, + "attr": "5&79" + }, + { + "id": 19, + "lv": 61, + "attr": "5&80" + }, + { + "id": 19, + "lv": 62, + "attr": "5&81" + }, + { + "id": 19, + "lv": 63, + "attr": "5&82" + }, + { + "id": 19, + "lv": 64, + "attr": "5&83" + }, + { + "id": 19, + "lv": 65, + "attr": "5&84" + }, + { + "id": 19, + "lv": 66, + "attr": "5&85" + }, + { + "id": 19, + "lv": 67, + "attr": "5&86" + }, + { + "id": 19, + "lv": 68, + "attr": "5&87" + }, + { + "id": 19, + "lv": 69, + "attr": "5&88" + }, + { + "id": 19, + "lv": 70, + "attr": "5&89" + }, + { + "id": 19, + "lv": 71, + "attr": "5&90" + }, + { + "id": 19, + "lv": 72, + "attr": "5&91" + }, + { + "id": 19, + "lv": 73, + "attr": "5&92" + }, + { + "id": 19, + "lv": 74, + "attr": "5&93" + }, + { + "id": 19, + "lv": 75, + "attr": "5&94" + }, + { + "id": 19, + "lv": 76, + "attr": "5&95" + }, + { + "id": 19, + "lv": 77, + "attr": "5&96" + }, + { + "id": 19, + "lv": 78, + "attr": "5&97" + }, + { + "id": 19, + "lv": 79, + "attr": "5&98" + }, + { + "id": 19, + "lv": 80, + "attr": "5&99" + }, + { + "id": 19, + "lv": 81, + "attr": "5&100" + }, + { + "id": 19, + "lv": 82, + "attr": "5&101" + }, + { + "id": 19, + "lv": 83, + "attr": "5&102" + }, + { + "id": 19, + "lv": 84, + "attr": "5&103" + }, + { + "id": 19, + "lv": 85, + "attr": "5&104" + }, + { + "id": 19, + "lv": 86, + "attr": "5&105" + }, + { + "id": 19, + "lv": 87, + "attr": "5&106" + }, + { + "id": 19, + "lv": 88, + "attr": "5&107" + }, + { + "id": 19, + "lv": 89, + "attr": "5&108" + }, + { + "id": 19, + "lv": 90, + "attr": "5&109" + }, + { + "id": 19, + "lv": 91, + "attr": "5&110" + }, + { + "id": 19, + "lv": 92, + "attr": "5&111" + }, + { + "id": 19, + "lv": 93, + "attr": "5&112" + }, + { + "id": 19, + "lv": 94, + "attr": "5&113" + }, + { + "id": 19, + "lv": 95, + "attr": "5&114" + }, + { + "id": 19, + "lv": 96, + "attr": "5&115" + }, + { + "id": 19, + "lv": 97, + "attr": "5&116" + }, + { + "id": 19, + "lv": 98, + "attr": "5&117" + }, + { + "id": 19, + "lv": 99, + "attr": "5&118" + }, + { + "id": 19, + "lv": 100, + "attr": "5&119" + }, + { + "id": 20, + "lv": 1, + "attr": "1&50" + }, + { + "id": 20, + "lv": 2, + "attr": "1&51" + }, + { + "id": 20, + "lv": 3, + "attr": "1&52" + }, + { + "id": 20, + "lv": 4, + "attr": "1&53" + }, + { + "id": 20, + "lv": 5, + "attr": "1&54" + }, + { + "id": 20, + "lv": 6, + "attr": "1&55" + }, + { + "id": 20, + "lv": 7, + "attr": "1&56" + }, + { + "id": 20, + "lv": 8, + "attr": "1&57" + }, + { + "id": 20, + "lv": 9, + "attr": "1&58" + }, + { + "id": 20, + "lv": 10, + "attr": "1&59" + }, + { + "id": 20, + "lv": 11, + "attr": "1&60" + }, + { + "id": 20, + "lv": 12, + "attr": "1&61" + }, + { + "id": 20, + "lv": 13, + "attr": "1&62" + }, + { + "id": 20, + "lv": 14, + "attr": "1&63" + }, + { + "id": 20, + "lv": 15, + "attr": "1&64" + }, + { + "id": 20, + "lv": 16, + "attr": "1&65" + }, + { + "id": 20, + "lv": 17, + "attr": "1&66" + }, + { + "id": 20, + "lv": 18, + "attr": "1&67" + }, + { + "id": 20, + "lv": 19, + "attr": "1&68" + }, + { + "id": 20, + "lv": 20, + "attr": "1&69" + }, + { + "id": 20, + "lv": 21, + "attr": "1&70" + }, + { + "id": 20, + "lv": 22, + "attr": "1&71" + }, + { + "id": 20, + "lv": 23, + "attr": "1&72" + }, + { + "id": 20, + "lv": 24, + "attr": "1&73" + }, + { + "id": 20, + "lv": 25, + "attr": "1&74" + }, + { + "id": 20, + "lv": 26, + "attr": "1&75" + }, + { + "id": 20, + "lv": 27, + "attr": "1&76" + }, + { + "id": 20, + "lv": 28, + "attr": "1&77" + }, + { + "id": 20, + "lv": 29, + "attr": "1&78" + }, + { + "id": 20, + "lv": 30, + "attr": "1&79" + }, + { + "id": 20, + "lv": 31, + "attr": "1&80" + }, + { + "id": 20, + "lv": 32, + "attr": "1&81" + }, + { + "id": 20, + "lv": 33, + "attr": "1&82" + }, + { + "id": 20, + "lv": 34, + "attr": "1&83" + }, + { + "id": 20, + "lv": 35, + "attr": "1&84" + }, + { + "id": 20, + "lv": 36, + "attr": "1&85" + }, + { + "id": 20, + "lv": 37, + "attr": "1&86" + }, + { + "id": 20, + "lv": 38, + "attr": "1&87" + }, + { + "id": 20, + "lv": 39, + "attr": "1&88" + }, + { + "id": 20, + "lv": 40, + "attr": "1&89" + }, + { + "id": 20, + "lv": 41, + "attr": "1&90" + }, + { + "id": 20, + "lv": 42, + "attr": "1&91" + }, + { + "id": 20, + "lv": 43, + "attr": "1&92" + }, + { + "id": 20, + "lv": 44, + "attr": "1&93" + }, + { + "id": 20, + "lv": 45, + "attr": "1&94" + }, + { + "id": 20, + "lv": 46, + "attr": "1&95" + }, + { + "id": 20, + "lv": 47, + "attr": "1&96" + }, + { + "id": 20, + "lv": 48, + "attr": "1&97" + }, + { + "id": 20, + "lv": 49, + "attr": "1&98" + }, + { + "id": 20, + "lv": 50, + "attr": "1&99" + }, + { + "id": 20, + "lv": 51, + "attr": "1&100" + }, + { + "id": 20, + "lv": 52, + "attr": "1&101" + }, + { + "id": 20, + "lv": 53, + "attr": "1&102" + }, + { + "id": 20, + "lv": 54, + "attr": "1&103" + }, + { + "id": 20, + "lv": 55, + "attr": "1&104" + }, + { + "id": 20, + "lv": 56, + "attr": "1&105" + }, + { + "id": 20, + "lv": 57, + "attr": "1&106" + }, + { + "id": 20, + "lv": 58, + "attr": "1&107" + }, + { + "id": 20, + "lv": 59, + "attr": "1&108" + }, + { + "id": 20, + "lv": 60, + "attr": "1&109" + }, + { + "id": 20, + "lv": 61, + "attr": "1&110" + }, + { + "id": 20, + "lv": 62, + "attr": "1&111" + }, + { + "id": 20, + "lv": 63, + "attr": "1&112" + }, + { + "id": 20, + "lv": 64, + "attr": "1&113" + }, + { + "id": 20, + "lv": 65, + "attr": "1&114" + }, + { + "id": 20, + "lv": 66, + "attr": "1&115" + }, + { + "id": 20, + "lv": 67, + "attr": "1&116" + }, + { + "id": 20, + "lv": 68, + "attr": "1&117" + }, + { + "id": 20, + "lv": 69, + "attr": "1&118" + }, + { + "id": 20, + "lv": 70, + "attr": "1&119" + }, + { + "id": 20, + "lv": 71, + "attr": "1&120" + }, + { + "id": 20, + "lv": 72, + "attr": "1&121" + }, + { + "id": 20, + "lv": 73, + "attr": "1&122" + }, + { + "id": 20, + "lv": 74, + "attr": "1&123" + }, + { + "id": 20, + "lv": 75, + "attr": "1&124" + }, + { + "id": 20, + "lv": 76, + "attr": "1&125" + }, + { + "id": 20, + "lv": 77, + "attr": "1&126" + }, + { + "id": 20, + "lv": 78, + "attr": "1&127" + }, + { + "id": 20, + "lv": 79, + "attr": "1&128" + }, + { + "id": 20, + "lv": 80, + "attr": "1&129" + }, + { + "id": 20, + "lv": 81, + "attr": "1&130" + }, + { + "id": 20, + "lv": 82, + "attr": "1&131" + }, + { + "id": 20, + "lv": 83, + "attr": "1&132" + }, + { + "id": 20, + "lv": 84, + "attr": "1&133" + }, + { + "id": 20, + "lv": 85, + "attr": "1&134" + }, + { + "id": 20, + "lv": 86, + "attr": "1&135" + }, + { + "id": 20, + "lv": 87, + "attr": "1&136" + }, + { + "id": 20, + "lv": 88, + "attr": "1&137" + }, + { + "id": 20, + "lv": 89, + "attr": "1&138" + }, + { + "id": 20, + "lv": 90, + "attr": "1&139" + }, + { + "id": 20, + "lv": 91, + "attr": "1&140" + }, + { + "id": 20, + "lv": 92, + "attr": "1&141" + }, + { + "id": 20, + "lv": 93, + "attr": "1&142" + }, + { + "id": 20, + "lv": 94, + "attr": "1&143" + }, + { + "id": 20, + "lv": 95, + "attr": "1&144" + }, + { + "id": 20, + "lv": 96, + "attr": "1&145" + }, + { + "id": 20, + "lv": 97, + "attr": "1&146" + }, + { + "id": 20, + "lv": 98, + "attr": "1&147" + }, + { + "id": 20, + "lv": 99, + "attr": "1&148" + }, + { + "id": 20, + "lv": 100, + "attr": "1&149" + }, + { + "id": 21, + "lv": 1, + "attr": "2&10" + }, + { + "id": 21, + "lv": 2, + "attr": "2&11" + }, + { + "id": 21, + "lv": 3, + "attr": "2&12" + }, + { + "id": 21, + "lv": 4, + "attr": "2&13" + }, + { + "id": 21, + "lv": 5, + "attr": "2&14" + }, + { + "id": 21, + "lv": 6, + "attr": "2&15" + }, + { + "id": 21, + "lv": 7, + "attr": "2&16" + }, + { + "id": 21, + "lv": 8, + "attr": "2&17" + }, + { + "id": 21, + "lv": 9, + "attr": "2&18" + }, + { + "id": 21, + "lv": 10, + "attr": "2&19" + }, + { + "id": 21, + "lv": 11, + "attr": "2&20" + }, + { + "id": 21, + "lv": 12, + "attr": "2&21" + }, + { + "id": 21, + "lv": 13, + "attr": "2&22" + }, + { + "id": 21, + "lv": 14, + "attr": "2&23" + }, + { + "id": 21, + "lv": 15, + "attr": "2&24" + }, + { + "id": 21, + "lv": 16, + "attr": "2&25" + }, + { + "id": 21, + "lv": 17, + "attr": "2&26" + }, + { + "id": 21, + "lv": 18, + "attr": "2&27" + }, + { + "id": 21, + "lv": 19, + "attr": "2&28" + }, + { + "id": 21, + "lv": 20, + "attr": "2&29" + }, + { + "id": 21, + "lv": 21, + "attr": "2&30" + }, + { + "id": 21, + "lv": 22, + "attr": "2&31" + }, + { + "id": 21, + "lv": 23, + "attr": "2&32" + }, + { + "id": 21, + "lv": 24, + "attr": "2&33" + }, + { + "id": 21, + "lv": 25, + "attr": "2&34" + }, + { + "id": 21, + "lv": 26, + "attr": "2&35" + }, + { + "id": 21, + "lv": 27, + "attr": "2&36" + }, + { + "id": 21, + "lv": 28, + "attr": "2&37" + }, + { + "id": 21, + "lv": 29, + "attr": "2&38" + }, + { + "id": 21, + "lv": 30, + "attr": "2&39" + }, + { + "id": 21, + "lv": 31, + "attr": "2&40" + }, + { + "id": 21, + "lv": 32, + "attr": "2&41" + }, + { + "id": 21, + "lv": 33, + "attr": "2&42" + }, + { + "id": 21, + "lv": 34, + "attr": "2&43" + }, + { + "id": 21, + "lv": 35, + "attr": "2&44" + }, + { + "id": 21, + "lv": 36, + "attr": "2&45" + }, + { + "id": 21, + "lv": 37, + "attr": "2&46" + }, + { + "id": 21, + "lv": 38, + "attr": "2&47" + }, + { + "id": 21, + "lv": 39, + "attr": "2&48" + }, + { + "id": 21, + "lv": 40, + "attr": "2&49" + }, + { + "id": 21, + "lv": 41, + "attr": "2&50" + }, + { + "id": 21, + "lv": 42, + "attr": "2&51" + }, + { + "id": 21, + "lv": 43, + "attr": "2&52" + }, + { + "id": 21, + "lv": 44, + "attr": "2&53" + }, + { + "id": 21, + "lv": 45, + "attr": "2&54" + }, + { + "id": 21, + "lv": 46, + "attr": "2&55" + }, + { + "id": 21, + "lv": 47, + "attr": "2&56" + }, + { + "id": 21, + "lv": 48, + "attr": "2&57" + }, + { + "id": 21, + "lv": 49, + "attr": "2&58" + }, + { + "id": 21, + "lv": 50, + "attr": "2&59" + }, + { + "id": 21, + "lv": 51, + "attr": "2&60" + }, + { + "id": 21, + "lv": 52, + "attr": "2&61" + }, + { + "id": 21, + "lv": 53, + "attr": "2&62" + }, + { + "id": 21, + "lv": 54, + "attr": "2&63" + }, + { + "id": 21, + "lv": 55, + "attr": "2&64" + }, + { + "id": 21, + "lv": 56, + "attr": "2&65" + }, + { + "id": 21, + "lv": 57, + "attr": "2&66" + }, + { + "id": 21, + "lv": 58, + "attr": "2&67" + }, + { + "id": 21, + "lv": 59, + "attr": "2&68" + }, + { + "id": 21, + "lv": 60, + "attr": "2&69" + }, + { + "id": 21, + "lv": 61, + "attr": "2&70" + }, + { + "id": 21, + "lv": 62, + "attr": "2&71" + }, + { + "id": 21, + "lv": 63, + "attr": "2&72" + }, + { + "id": 21, + "lv": 64, + "attr": "2&73" + }, + { + "id": 21, + "lv": 65, + "attr": "2&74" + }, + { + "id": 21, + "lv": 66, + "attr": "2&75" + }, + { + "id": 21, + "lv": 67, + "attr": "2&76" + }, + { + "id": 21, + "lv": 68, + "attr": "2&77" + }, + { + "id": 21, + "lv": 69, + "attr": "2&78" + }, + { + "id": 21, + "lv": 70, + "attr": "2&79" + }, + { + "id": 21, + "lv": 71, + "attr": "2&80" + }, + { + "id": 21, + "lv": 72, + "attr": "2&81" + }, + { + "id": 21, + "lv": 73, + "attr": "2&82" + }, + { + "id": 21, + "lv": 74, + "attr": "2&83" + }, + { + "id": 21, + "lv": 75, + "attr": "2&84" + }, + { + "id": 21, + "lv": 76, + "attr": "2&85" + }, + { + "id": 21, + "lv": 77, + "attr": "2&86" + }, + { + "id": 21, + "lv": 78, + "attr": "2&87" + }, + { + "id": 21, + "lv": 79, + "attr": "2&88" + }, + { + "id": 21, + "lv": 80, + "attr": "2&89" + }, + { + "id": 21, + "lv": 81, + "attr": "2&90" + }, + { + "id": 21, + "lv": 82, + "attr": "2&91" + }, + { + "id": 21, + "lv": 83, + "attr": "2&92" + }, + { + "id": 21, + "lv": 84, + "attr": "2&93" + }, + { + "id": 21, + "lv": 85, + "attr": "2&94" + }, + { + "id": 21, + "lv": 86, + "attr": "2&95" + }, + { + "id": 21, + "lv": 87, + "attr": "2&96" + }, + { + "id": 21, + "lv": 88, + "attr": "2&97" + }, + { + "id": 21, + "lv": 89, + "attr": "2&98" + }, + { + "id": 21, + "lv": 90, + "attr": "2&99" + }, + { + "id": 21, + "lv": 91, + "attr": "2&100" + }, + { + "id": 21, + "lv": 92, + "attr": "2&101" + }, + { + "id": 21, + "lv": 93, + "attr": "2&102" + }, + { + "id": 21, + "lv": 94, + "attr": "2&103" + }, + { + "id": 21, + "lv": 95, + "attr": "2&104" + }, + { + "id": 21, + "lv": 96, + "attr": "2&105" + }, + { + "id": 21, + "lv": 97, + "attr": "2&106" + }, + { + "id": 21, + "lv": 98, + "attr": "2&107" + }, + { + "id": 21, + "lv": 99, + "attr": "2&108" + }, + { + "id": 21, + "lv": 100, + "attr": "2&109" + }, + { + "id": 22, + "lv": 1, + "attr": "4&20" + }, + { + "id": 22, + "lv": 2, + "attr": "4&21" + }, + { + "id": 22, + "lv": 3, + "attr": "4&22" + }, + { + "id": 22, + "lv": 4, + "attr": "4&23" + }, + { + "id": 22, + "lv": 5, + "attr": "4&24" + }, + { + "id": 22, + "lv": 6, + "attr": "4&25" + }, + { + "id": 22, + "lv": 7, + "attr": "4&26" + }, + { + "id": 22, + "lv": 8, + "attr": "4&27" + }, + { + "id": 22, + "lv": 9, + "attr": "4&28" + }, + { + "id": 22, + "lv": 10, + "attr": "4&29" + }, + { + "id": 22, + "lv": 11, + "attr": "4&30" + }, + { + "id": 22, + "lv": 12, + "attr": "4&31" + }, + { + "id": 22, + "lv": 13, + "attr": "4&32" + }, + { + "id": 22, + "lv": 14, + "attr": "4&33" + }, + { + "id": 22, + "lv": 15, + "attr": "4&34" + }, + { + "id": 22, + "lv": 16, + "attr": "4&35" + }, + { + "id": 22, + "lv": 17, + "attr": "4&36" + }, + { + "id": 22, + "lv": 18, + "attr": "4&37" + }, + { + "id": 22, + "lv": 19, + "attr": "4&38" + }, + { + "id": 22, + "lv": 20, + "attr": "4&39" + }, + { + "id": 22, + "lv": 21, + "attr": "4&40" + }, + { + "id": 22, + "lv": 22, + "attr": "4&41" + }, + { + "id": 22, + "lv": 23, + "attr": "4&42" + }, + { + "id": 22, + "lv": 24, + "attr": "4&43" + }, + { + "id": 22, + "lv": 25, + "attr": "4&44" + }, + { + "id": 22, + "lv": 26, + "attr": "4&45" + }, + { + "id": 22, + "lv": 27, + "attr": "4&46" + }, + { + "id": 22, + "lv": 28, + "attr": "4&47" + }, + { + "id": 22, + "lv": 29, + "attr": "4&48" + }, + { + "id": 22, + "lv": 30, + "attr": "4&49" + }, + { + "id": 22, + "lv": 31, + "attr": "4&50" + }, + { + "id": 22, + "lv": 32, + "attr": "4&51" + }, + { + "id": 22, + "lv": 33, + "attr": "4&52" + }, + { + "id": 22, + "lv": 34, + "attr": "4&53" + }, + { + "id": 22, + "lv": 35, + "attr": "4&54" + }, + { + "id": 22, + "lv": 36, + "attr": "4&55" + }, + { + "id": 22, + "lv": 37, + "attr": "4&56" + }, + { + "id": 22, + "lv": 38, + "attr": "4&57" + }, + { + "id": 22, + "lv": 39, + "attr": "4&58" + }, + { + "id": 22, + "lv": 40, + "attr": "4&59" + }, + { + "id": 22, + "lv": 41, + "attr": "4&60" + }, + { + "id": 22, + "lv": 42, + "attr": "4&61" + }, + { + "id": 22, + "lv": 43, + "attr": "4&62" + }, + { + "id": 22, + "lv": 44, + "attr": "4&63" + }, + { + "id": 22, + "lv": 45, + "attr": "4&64" + }, + { + "id": 22, + "lv": 46, + "attr": "4&65" + }, + { + "id": 22, + "lv": 47, + "attr": "4&66" + }, + { + "id": 22, + "lv": 48, + "attr": "4&67" + }, + { + "id": 22, + "lv": 49, + "attr": "4&68" + }, + { + "id": 22, + "lv": 50, + "attr": "4&69" + }, + { + "id": 22, + "lv": 51, + "attr": "4&70" + }, + { + "id": 22, + "lv": 52, + "attr": "4&71" + }, + { + "id": 22, + "lv": 53, + "attr": "4&72" + }, + { + "id": 22, + "lv": 54, + "attr": "4&73" + }, + { + "id": 22, + "lv": 55, + "attr": "4&74" + }, + { + "id": 22, + "lv": 56, + "attr": "4&75" + }, + { + "id": 22, + "lv": 57, + "attr": "4&76" + }, + { + "id": 22, + "lv": 58, + "attr": "4&77" + }, + { + "id": 22, + "lv": 59, + "attr": "4&78" + }, + { + "id": 22, + "lv": 60, + "attr": "4&79" + }, + { + "id": 22, + "lv": 61, + "attr": "4&80" + }, + { + "id": 22, + "lv": 62, + "attr": "4&81" + }, + { + "id": 22, + "lv": 63, + "attr": "4&82" + }, + { + "id": 22, + "lv": 64, + "attr": "4&83" + }, + { + "id": 22, + "lv": 65, + "attr": "4&84" + }, + { + "id": 22, + "lv": 66, + "attr": "4&85" + }, + { + "id": 22, + "lv": 67, + "attr": "4&86" + }, + { + "id": 22, + "lv": 68, + "attr": "4&87" + }, + { + "id": 22, + "lv": 69, + "attr": "4&88" + }, + { + "id": 22, + "lv": 70, + "attr": "4&89" + }, + { + "id": 22, + "lv": 71, + "attr": "4&90" + }, + { + "id": 22, + "lv": 72, + "attr": "4&91" + }, + { + "id": 22, + "lv": 73, + "attr": "4&92" + }, + { + "id": 22, + "lv": 74, + "attr": "4&93" + }, + { + "id": 22, + "lv": 75, + "attr": "4&94" + }, + { + "id": 22, + "lv": 76, + "attr": "4&95" + }, + { + "id": 22, + "lv": 77, + "attr": "4&96" + }, + { + "id": 22, + "lv": 78, + "attr": "4&97" + }, + { + "id": 22, + "lv": 79, + "attr": "4&98" + }, + { + "id": 22, + "lv": 80, + "attr": "4&99" + }, + { + "id": 22, + "lv": 81, + "attr": "4&100" + }, + { + "id": 22, + "lv": 82, + "attr": "4&101" + }, + { + "id": 22, + "lv": 83, + "attr": "4&102" + }, + { + "id": 22, + "lv": 84, + "attr": "4&103" + }, + { + "id": 22, + "lv": 85, + "attr": "4&104" + }, + { + "id": 22, + "lv": 86, + "attr": "4&105" + }, + { + "id": 22, + "lv": 87, + "attr": "4&106" + }, + { + "id": 22, + "lv": 88, + "attr": "4&107" + }, + { + "id": 22, + "lv": 89, + "attr": "4&108" + }, + { + "id": 22, + "lv": 90, + "attr": "4&109" + }, + { + "id": 22, + "lv": 91, + "attr": "4&110" + }, + { + "id": 22, + "lv": 92, + "attr": "4&111" + }, + { + "id": 22, + "lv": 93, + "attr": "4&112" + }, + { + "id": 22, + "lv": 94, + "attr": "4&113" + }, + { + "id": 22, + "lv": 95, + "attr": "4&114" + }, + { + "id": 22, + "lv": 96, + "attr": "4&115" + }, + { + "id": 22, + "lv": 97, + "attr": "4&116" + }, + { + "id": 22, + "lv": 98, + "attr": "4&117" + }, + { + "id": 22, + "lv": 99, + "attr": "4&118" + }, + { + "id": 22, + "lv": 100, + "attr": "4&119" + }, + { + "id": 23, + "lv": 1, + "attr": "5&20" + }, + { + "id": 23, + "lv": 2, + "attr": "5&21" + }, + { + "id": 23, + "lv": 3, + "attr": "5&22" + }, + { + "id": 23, + "lv": 4, + "attr": "5&23" + }, + { + "id": 23, + "lv": 5, + "attr": "5&24" + }, + { + "id": 23, + "lv": 6, + "attr": "5&25" + }, + { + "id": 23, + "lv": 7, + "attr": "5&26" + }, + { + "id": 23, + "lv": 8, + "attr": "5&27" + }, + { + "id": 23, + "lv": 9, + "attr": "5&28" + }, + { + "id": 23, + "lv": 10, + "attr": "5&29" + }, + { + "id": 23, + "lv": 11, + "attr": "5&30" + }, + { + "id": 23, + "lv": 12, + "attr": "5&31" + }, + { + "id": 23, + "lv": 13, + "attr": "5&32" + }, + { + "id": 23, + "lv": 14, + "attr": "5&33" + }, + { + "id": 23, + "lv": 15, + "attr": "5&34" + }, + { + "id": 23, + "lv": 16, + "attr": "5&35" + }, + { + "id": 23, + "lv": 17, + "attr": "5&36" + }, + { + "id": 23, + "lv": 18, + "attr": "5&37" + }, + { + "id": 23, + "lv": 19, + "attr": "5&38" + }, + { + "id": 23, + "lv": 20, + "attr": "5&39" + }, + { + "id": 23, + "lv": 21, + "attr": "5&40" + }, + { + "id": 23, + "lv": 22, + "attr": "5&41" + }, + { + "id": 23, + "lv": 23, + "attr": "5&42" + }, + { + "id": 23, + "lv": 24, + "attr": "5&43" + }, + { + "id": 23, + "lv": 25, + "attr": "5&44" + }, + { + "id": 23, + "lv": 26, + "attr": "5&45" + }, + { + "id": 23, + "lv": 27, + "attr": "5&46" + }, + { + "id": 23, + "lv": 28, + "attr": "5&47" + }, + { + "id": 23, + "lv": 29, + "attr": "5&48" + }, + { + "id": 23, + "lv": 30, + "attr": "5&49" + }, + { + "id": 23, + "lv": 31, + "attr": "5&50" + }, + { + "id": 23, + "lv": 32, + "attr": "5&51" + }, + { + "id": 23, + "lv": 33, + "attr": "5&52" + }, + { + "id": 23, + "lv": 34, + "attr": "5&53" + }, + { + "id": 23, + "lv": 35, + "attr": "5&54" + }, + { + "id": 23, + "lv": 36, + "attr": "5&55" + }, + { + "id": 23, + "lv": 37, + "attr": "5&56" + }, + { + "id": 23, + "lv": 38, + "attr": "5&57" + }, + { + "id": 23, + "lv": 39, + "attr": "5&58" + }, + { + "id": 23, + "lv": 40, + "attr": "5&59" + }, + { + "id": 23, + "lv": 41, + "attr": "5&60" + }, + { + "id": 23, + "lv": 42, + "attr": "5&61" + }, + { + "id": 23, + "lv": 43, + "attr": "5&62" + }, + { + "id": 23, + "lv": 44, + "attr": "5&63" + }, + { + "id": 23, + "lv": 45, + "attr": "5&64" + }, + { + "id": 23, + "lv": 46, + "attr": "5&65" + }, + { + "id": 23, + "lv": 47, + "attr": "5&66" + }, + { + "id": 23, + "lv": 48, + "attr": "5&67" + }, + { + "id": 23, + "lv": 49, + "attr": "5&68" + }, + { + "id": 23, + "lv": 50, + "attr": "5&69" + }, + { + "id": 23, + "lv": 51, + "attr": "5&70" + }, + { + "id": 23, + "lv": 52, + "attr": "5&71" + }, + { + "id": 23, + "lv": 53, + "attr": "5&72" + }, + { + "id": 23, + "lv": 54, + "attr": "5&73" + }, + { + "id": 23, + "lv": 55, + "attr": "5&74" + }, + { + "id": 23, + "lv": 56, + "attr": "5&75" + }, + { + "id": 23, + "lv": 57, + "attr": "5&76" + }, + { + "id": 23, + "lv": 58, + "attr": "5&77" + }, + { + "id": 23, + "lv": 59, + "attr": "5&78" + }, + { + "id": 23, + "lv": 60, + "attr": "5&79" + }, + { + "id": 23, + "lv": 61, + "attr": "5&80" + }, + { + "id": 23, + "lv": 62, + "attr": "5&81" + }, + { + "id": 23, + "lv": 63, + "attr": "5&82" + }, + { + "id": 23, + "lv": 64, + "attr": "5&83" + }, + { + "id": 23, + "lv": 65, + "attr": "5&84" + }, + { + "id": 23, + "lv": 66, + "attr": "5&85" + }, + { + "id": 23, + "lv": 67, + "attr": "5&86" + }, + { + "id": 23, + "lv": 68, + "attr": "5&87" + }, + { + "id": 23, + "lv": 69, + "attr": "5&88" + }, + { + "id": 23, + "lv": 70, + "attr": "5&89" + }, + { + "id": 23, + "lv": 71, + "attr": "5&90" + }, + { + "id": 23, + "lv": 72, + "attr": "5&91" + }, + { + "id": 23, + "lv": 73, + "attr": "5&92" + }, + { + "id": 23, + "lv": 74, + "attr": "5&93" + }, + { + "id": 23, + "lv": 75, + "attr": "5&94" + }, + { + "id": 23, + "lv": 76, + "attr": "5&95" + }, + { + "id": 23, + "lv": 77, + "attr": "5&96" + }, + { + "id": 23, + "lv": 78, + "attr": "5&97" + }, + { + "id": 23, + "lv": 79, + "attr": "5&98" + }, + { + "id": 23, + "lv": 80, + "attr": "5&99" + }, + { + "id": 23, + "lv": 81, + "attr": "5&100" + }, + { + "id": 23, + "lv": 82, + "attr": "5&101" + }, + { + "id": 23, + "lv": 83, + "attr": "5&102" + }, + { + "id": 23, + "lv": 84, + "attr": "5&103" + }, + { + "id": 23, + "lv": 85, + "attr": "5&104" + }, + { + "id": 23, + "lv": 86, + "attr": "5&105" + }, + { + "id": 23, + "lv": 87, + "attr": "5&106" + }, + { + "id": 23, + "lv": 88, + "attr": "5&107" + }, + { + "id": 23, + "lv": 89, + "attr": "5&108" + }, + { + "id": 23, + "lv": 90, + "attr": "5&109" + }, + { + "id": 23, + "lv": 91, + "attr": "5&110" + }, + { + "id": 23, + "lv": 92, + "attr": "5&111" + }, + { + "id": 23, + "lv": 93, + "attr": "5&112" + }, + { + "id": 23, + "lv": 94, + "attr": "5&113" + }, + { + "id": 23, + "lv": 95, + "attr": "5&114" + }, + { + "id": 23, + "lv": 96, + "attr": "5&115" + }, + { + "id": 23, + "lv": 97, + "attr": "5&116" + }, + { + "id": 23, + "lv": 98, + "attr": "5&117" + }, + { + "id": 23, + "lv": 99, + "attr": "5&118" + }, + { + "id": 23, + "lv": 100, + "attr": "5&119" + }, + { + "id": 24, + "lv": 1, + "attr": "1&50" + }, + { + "id": 24, + "lv": 2, + "attr": "1&51" + }, + { + "id": 24, + "lv": 3, + "attr": "1&52" + }, + { + "id": 24, + "lv": 4, + "attr": "1&53" + }, + { + "id": 24, + "lv": 5, + "attr": "1&54" + }, + { + "id": 24, + "lv": 6, + "attr": "1&55" + }, + { + "id": 24, + "lv": 7, + "attr": "1&56" + }, + { + "id": 24, + "lv": 8, + "attr": "1&57" + }, + { + "id": 24, + "lv": 9, + "attr": "1&58" + }, + { + "id": 24, + "lv": 10, + "attr": "1&59" + }, + { + "id": 24, + "lv": 11, + "attr": "1&60" + }, + { + "id": 24, + "lv": 12, + "attr": "1&61" + }, + { + "id": 24, + "lv": 13, + "attr": "1&62" + }, + { + "id": 24, + "lv": 14, + "attr": "1&63" + }, + { + "id": 24, + "lv": 15, + "attr": "1&64" + }, + { + "id": 24, + "lv": 16, + "attr": "1&65" + }, + { + "id": 24, + "lv": 17, + "attr": "1&66" + }, + { + "id": 24, + "lv": 18, + "attr": "1&67" + }, + { + "id": 24, + "lv": 19, + "attr": "1&68" + }, + { + "id": 24, + "lv": 20, + "attr": "1&69" + }, + { + "id": 24, + "lv": 21, + "attr": "1&70" + }, + { + "id": 24, + "lv": 22, + "attr": "1&71" + }, + { + "id": 24, + "lv": 23, + "attr": "1&72" + }, + { + "id": 24, + "lv": 24, + "attr": "1&73" + }, + { + "id": 24, + "lv": 25, + "attr": "1&74" + }, + { + "id": 24, + "lv": 26, + "attr": "1&75" + }, + { + "id": 24, + "lv": 27, + "attr": "1&76" + }, + { + "id": 24, + "lv": 28, + "attr": "1&77" + }, + { + "id": 24, + "lv": 29, + "attr": "1&78" + }, + { + "id": 24, + "lv": 30, + "attr": "1&79" + }, + { + "id": 24, + "lv": 31, + "attr": "1&80" + }, + { + "id": 24, + "lv": 32, + "attr": "1&81" + }, + { + "id": 24, + "lv": 33, + "attr": "1&82" + }, + { + "id": 24, + "lv": 34, + "attr": "1&83" + }, + { + "id": 24, + "lv": 35, + "attr": "1&84" + }, + { + "id": 24, + "lv": 36, + "attr": "1&85" + }, + { + "id": 24, + "lv": 37, + "attr": "1&86" + }, + { + "id": 24, + "lv": 38, + "attr": "1&87" + }, + { + "id": 24, + "lv": 39, + "attr": "1&88" + }, + { + "id": 24, + "lv": 40, + "attr": "1&89" + }, + { + "id": 24, + "lv": 41, + "attr": "1&90" + }, + { + "id": 24, + "lv": 42, + "attr": "1&91" + }, + { + "id": 24, + "lv": 43, + "attr": "1&92" + }, + { + "id": 24, + "lv": 44, + "attr": "1&93" + }, + { + "id": 24, + "lv": 45, + "attr": "1&94" + }, + { + "id": 24, + "lv": 46, + "attr": "1&95" + }, + { + "id": 24, + "lv": 47, + "attr": "1&96" + }, + { + "id": 24, + "lv": 48, + "attr": "1&97" + }, + { + "id": 24, + "lv": 49, + "attr": "1&98" + }, + { + "id": 24, + "lv": 50, + "attr": "1&99" + }, + { + "id": 24, + "lv": 51, + "attr": "1&100" + }, + { + "id": 24, + "lv": 52, + "attr": "1&101" + }, + { + "id": 24, + "lv": 53, + "attr": "1&102" + }, + { + "id": 24, + "lv": 54, + "attr": "1&103" + }, + { + "id": 24, + "lv": 55, + "attr": "1&104" + }, + { + "id": 24, + "lv": 56, + "attr": "1&105" + }, + { + "id": 24, + "lv": 57, + "attr": "1&106" + }, + { + "id": 24, + "lv": 58, + "attr": "1&107" + }, + { + "id": 24, + "lv": 59, + "attr": "1&108" + }, + { + "id": 24, + "lv": 60, + "attr": "1&109" + }, + { + "id": 24, + "lv": 61, + "attr": "1&110" + }, + { + "id": 24, + "lv": 62, + "attr": "1&111" + }, + { + "id": 24, + "lv": 63, + "attr": "1&112" + }, + { + "id": 24, + "lv": 64, + "attr": "1&113" + }, + { + "id": 24, + "lv": 65, + "attr": "1&114" + }, + { + "id": 24, + "lv": 66, + "attr": "1&115" + }, + { + "id": 24, + "lv": 67, + "attr": "1&116" + }, + { + "id": 24, + "lv": 68, + "attr": "1&117" + }, + { + "id": 24, + "lv": 69, + "attr": "1&118" + }, + { + "id": 24, + "lv": 70, + "attr": "1&119" + }, + { + "id": 24, + "lv": 71, + "attr": "1&120" + }, + { + "id": 24, + "lv": 72, + "attr": "1&121" + }, + { + "id": 24, + "lv": 73, + "attr": "1&122" + }, + { + "id": 24, + "lv": 74, + "attr": "1&123" + }, + { + "id": 24, + "lv": 75, + "attr": "1&124" + }, + { + "id": 24, + "lv": 76, + "attr": "1&125" + }, + { + "id": 24, + "lv": 77, + "attr": "1&126" + }, + { + "id": 24, + "lv": 78, + "attr": "1&127" + }, + { + "id": 24, + "lv": 79, + "attr": "1&128" + }, + { + "id": 24, + "lv": 80, + "attr": "1&129" + }, + { + "id": 24, + "lv": 81, + "attr": "1&130" + }, + { + "id": 24, + "lv": 82, + "attr": "1&131" + }, + { + "id": 24, + "lv": 83, + "attr": "1&132" + }, + { + "id": 24, + "lv": 84, + "attr": "1&133" + }, + { + "id": 24, + "lv": 85, + "attr": "1&134" + }, + { + "id": 24, + "lv": 86, + "attr": "1&135" + }, + { + "id": 24, + "lv": 87, + "attr": "1&136" + }, + { + "id": 24, + "lv": 88, + "attr": "1&137" + }, + { + "id": 24, + "lv": 89, + "attr": "1&138" + }, + { + "id": 24, + "lv": 90, + "attr": "1&139" + }, + { + "id": 24, + "lv": 91, + "attr": "1&140" + }, + { + "id": 24, + "lv": 92, + "attr": "1&141" + }, + { + "id": 24, + "lv": 93, + "attr": "1&142" + }, + { + "id": 24, + "lv": 94, + "attr": "1&143" + }, + { + "id": 24, + "lv": 95, + "attr": "1&144" + }, + { + "id": 24, + "lv": 96, + "attr": "1&145" + }, + { + "id": 24, + "lv": 97, + "attr": "1&146" + }, + { + "id": 24, + "lv": 98, + "attr": "1&147" + }, + { + "id": 24, + "lv": 99, + "attr": "1&148" + }, + { + "id": 24, + "lv": 100, + "attr": "1&149" + }, + { + "id": 25, + "lv": 1, + "attr": "2&10" + }, + { + "id": 25, + "lv": 2, + "attr": "2&11" + }, + { + "id": 25, + "lv": 3, + "attr": "2&12" + }, + { + "id": 25, + "lv": 4, + "attr": "2&13" + }, + { + "id": 25, + "lv": 5, + "attr": "2&14" + }, + { + "id": 25, + "lv": 6, + "attr": "2&15" + }, + { + "id": 25, + "lv": 7, + "attr": "2&16" + }, + { + "id": 25, + "lv": 8, + "attr": "2&17" + }, + { + "id": 25, + "lv": 9, + "attr": "2&18" + }, + { + "id": 25, + "lv": 10, + "attr": "2&19" + }, + { + "id": 25, + "lv": 11, + "attr": "2&20" + }, + { + "id": 25, + "lv": 12, + "attr": "2&21" + }, + { + "id": 25, + "lv": 13, + "attr": "2&22" + }, + { + "id": 25, + "lv": 14, + "attr": "2&23" + }, + { + "id": 25, + "lv": 15, + "attr": "2&24" + }, + { + "id": 25, + "lv": 16, + "attr": "2&25" + }, + { + "id": 25, + "lv": 17, + "attr": "2&26" + }, + { + "id": 25, + "lv": 18, + "attr": "2&27" + }, + { + "id": 25, + "lv": 19, + "attr": "2&28" + }, + { + "id": 25, + "lv": 20, + "attr": "2&29" + }, + { + "id": 25, + "lv": 21, + "attr": "2&30" + }, + { + "id": 25, + "lv": 22, + "attr": "2&31" + }, + { + "id": 25, + "lv": 23, + "attr": "2&32" + }, + { + "id": 25, + "lv": 24, + "attr": "2&33" + }, + { + "id": 25, + "lv": 25, + "attr": "2&34" + }, + { + "id": 25, + "lv": 26, + "attr": "2&35" + }, + { + "id": 25, + "lv": 27, + "attr": "2&36" + }, + { + "id": 25, + "lv": 28, + "attr": "2&37" + }, + { + "id": 25, + "lv": 29, + "attr": "2&38" + }, + { + "id": 25, + "lv": 30, + "attr": "2&39" + }, + { + "id": 25, + "lv": 31, + "attr": "2&40" + }, + { + "id": 25, + "lv": 32, + "attr": "2&41" + }, + { + "id": 25, + "lv": 33, + "attr": "2&42" + }, + { + "id": 25, + "lv": 34, + "attr": "2&43" + }, + { + "id": 25, + "lv": 35, + "attr": "2&44" + }, + { + "id": 25, + "lv": 36, + "attr": "2&45" + }, + { + "id": 25, + "lv": 37, + "attr": "2&46" + }, + { + "id": 25, + "lv": 38, + "attr": "2&47" + }, + { + "id": 25, + "lv": 39, + "attr": "2&48" + }, + { + "id": 25, + "lv": 40, + "attr": "2&49" + }, + { + "id": 25, + "lv": 41, + "attr": "2&50" + }, + { + "id": 25, + "lv": 42, + "attr": "2&51" + }, + { + "id": 25, + "lv": 43, + "attr": "2&52" + }, + { + "id": 25, + "lv": 44, + "attr": "2&53" + }, + { + "id": 25, + "lv": 45, + "attr": "2&54" + }, + { + "id": 25, + "lv": 46, + "attr": "2&55" + }, + { + "id": 25, + "lv": 47, + "attr": "2&56" + }, + { + "id": 25, + "lv": 48, + "attr": "2&57" + }, + { + "id": 25, + "lv": 49, + "attr": "2&58" + }, + { + "id": 25, + "lv": 50, + "attr": "2&59" + }, + { + "id": 25, + "lv": 51, + "attr": "2&60" + }, + { + "id": 25, + "lv": 52, + "attr": "2&61" + }, + { + "id": 25, + "lv": 53, + "attr": "2&62" + }, + { + "id": 25, + "lv": 54, + "attr": "2&63" + }, + { + "id": 25, + "lv": 55, + "attr": "2&64" + }, + { + "id": 25, + "lv": 56, + "attr": "2&65" + }, + { + "id": 25, + "lv": 57, + "attr": "2&66" + }, + { + "id": 25, + "lv": 58, + "attr": "2&67" + }, + { + "id": 25, + "lv": 59, + "attr": "2&68" + }, + { + "id": 25, + "lv": 60, + "attr": "2&69" + }, + { + "id": 25, + "lv": 61, + "attr": "2&70" + }, + { + "id": 25, + "lv": 62, + "attr": "2&71" + }, + { + "id": 25, + "lv": 63, + "attr": "2&72" + }, + { + "id": 25, + "lv": 64, + "attr": "2&73" + }, + { + "id": 25, + "lv": 65, + "attr": "2&74" + }, + { + "id": 25, + "lv": 66, + "attr": "2&75" + }, + { + "id": 25, + "lv": 67, + "attr": "2&76" + }, + { + "id": 25, + "lv": 68, + "attr": "2&77" + }, + { + "id": 25, + "lv": 69, + "attr": "2&78" + }, + { + "id": 25, + "lv": 70, + "attr": "2&79" + }, + { + "id": 25, + "lv": 71, + "attr": "2&80" + }, + { + "id": 25, + "lv": 72, + "attr": "2&81" + }, + { + "id": 25, + "lv": 73, + "attr": "2&82" + }, + { + "id": 25, + "lv": 74, + "attr": "2&83" + }, + { + "id": 25, + "lv": 75, + "attr": "2&84" + }, + { + "id": 25, + "lv": 76, + "attr": "2&85" + }, + { + "id": 25, + "lv": 77, + "attr": "2&86" + }, + { + "id": 25, + "lv": 78, + "attr": "2&87" + }, + { + "id": 25, + "lv": 79, + "attr": "2&88" + }, + { + "id": 25, + "lv": 80, + "attr": "2&89" + }, + { + "id": 25, + "lv": 81, + "attr": "2&90" + }, + { + "id": 25, + "lv": 82, + "attr": "2&91" + }, + { + "id": 25, + "lv": 83, + "attr": "2&92" + }, + { + "id": 25, + "lv": 84, + "attr": "2&93" + }, + { + "id": 25, + "lv": 85, + "attr": "2&94" + }, + { + "id": 25, + "lv": 86, + "attr": "2&95" + }, + { + "id": 25, + "lv": 87, + "attr": "2&96" + }, + { + "id": 25, + "lv": 88, + "attr": "2&97" + }, + { + "id": 25, + "lv": 89, + "attr": "2&98" + }, + { + "id": 25, + "lv": 90, + "attr": "2&99" + }, + { + "id": 25, + "lv": 91, + "attr": "2&100" + }, + { + "id": 25, + "lv": 92, + "attr": "2&101" + }, + { + "id": 25, + "lv": 93, + "attr": "2&102" + }, + { + "id": 25, + "lv": 94, + "attr": "2&103" + }, + { + "id": 25, + "lv": 95, + "attr": "2&104" + }, + { + "id": 25, + "lv": 96, + "attr": "2&105" + }, + { + "id": 25, + "lv": 97, + "attr": "2&106" + }, + { + "id": 25, + "lv": 98, + "attr": "2&107" + }, + { + "id": 25, + "lv": 99, + "attr": "2&108" + }, + { + "id": 25, + "lv": 100, + "attr": "2&109" + }, + { + "id": 26, + "lv": 1, + "attr": "4&20" + }, + { + "id": 26, + "lv": 2, + "attr": "4&21" + }, + { + "id": 26, + "lv": 3, + "attr": "4&22" + }, + { + "id": 26, + "lv": 4, + "attr": "4&23" + }, + { + "id": 26, + "lv": 5, + "attr": "4&24" + }, + { + "id": 26, + "lv": 6, + "attr": "4&25" + }, + { + "id": 26, + "lv": 7, + "attr": "4&26" + }, + { + "id": 26, + "lv": 8, + "attr": "4&27" + }, + { + "id": 26, + "lv": 9, + "attr": "4&28" + }, + { + "id": 26, + "lv": 10, + "attr": "4&29" + }, + { + "id": 26, + "lv": 11, + "attr": "4&30" + }, + { + "id": 26, + "lv": 12, + "attr": "4&31" + }, + { + "id": 26, + "lv": 13, + "attr": "4&32" + }, + { + "id": 26, + "lv": 14, + "attr": "4&33" + }, + { + "id": 26, + "lv": 15, + "attr": "4&34" + }, + { + "id": 26, + "lv": 16, + "attr": "4&35" + }, + { + "id": 26, + "lv": 17, + "attr": "4&36" + }, + { + "id": 26, + "lv": 18, + "attr": "4&37" + }, + { + "id": 26, + "lv": 19, + "attr": "4&38" + }, + { + "id": 26, + "lv": 20, + "attr": "4&39" + }, + { + "id": 26, + "lv": 21, + "attr": "4&40" + }, + { + "id": 26, + "lv": 22, + "attr": "4&41" + }, + { + "id": 26, + "lv": 23, + "attr": "4&42" + }, + { + "id": 26, + "lv": 24, + "attr": "4&43" + }, + { + "id": 26, + "lv": 25, + "attr": "4&44" + }, + { + "id": 26, + "lv": 26, + "attr": "4&45" + }, + { + "id": 26, + "lv": 27, + "attr": "4&46" + }, + { + "id": 26, + "lv": 28, + "attr": "4&47" + }, + { + "id": 26, + "lv": 29, + "attr": "4&48" + }, + { + "id": 26, + "lv": 30, + "attr": "4&49" + }, + { + "id": 26, + "lv": 31, + "attr": "4&50" + }, + { + "id": 26, + "lv": 32, + "attr": "4&51" + }, + { + "id": 26, + "lv": 33, + "attr": "4&52" + }, + { + "id": 26, + "lv": 34, + "attr": "4&53" + }, + { + "id": 26, + "lv": 35, + "attr": "4&54" + }, + { + "id": 26, + "lv": 36, + "attr": "4&55" + }, + { + "id": 26, + "lv": 37, + "attr": "4&56" + }, + { + "id": 26, + "lv": 38, + "attr": "4&57" + }, + { + "id": 26, + "lv": 39, + "attr": "4&58" + }, + { + "id": 26, + "lv": 40, + "attr": "4&59" + }, + { + "id": 26, + "lv": 41, + "attr": "4&60" + }, + { + "id": 26, + "lv": 42, + "attr": "4&61" + }, + { + "id": 26, + "lv": 43, + "attr": "4&62" + }, + { + "id": 26, + "lv": 44, + "attr": "4&63" + }, + { + "id": 26, + "lv": 45, + "attr": "4&64" + }, + { + "id": 26, + "lv": 46, + "attr": "4&65" + }, + { + "id": 26, + "lv": 47, + "attr": "4&66" + }, + { + "id": 26, + "lv": 48, + "attr": "4&67" + }, + { + "id": 26, + "lv": 49, + "attr": "4&68" + }, + { + "id": 26, + "lv": 50, + "attr": "4&69" + }, + { + "id": 26, + "lv": 51, + "attr": "4&70" + }, + { + "id": 26, + "lv": 52, + "attr": "4&71" + }, + { + "id": 26, + "lv": 53, + "attr": "4&72" + }, + { + "id": 26, + "lv": 54, + "attr": "4&73" + }, + { + "id": 26, + "lv": 55, + "attr": "4&74" + }, + { + "id": 26, + "lv": 56, + "attr": "4&75" + }, + { + "id": 26, + "lv": 57, + "attr": "4&76" + }, + { + "id": 26, + "lv": 58, + "attr": "4&77" + }, + { + "id": 26, + "lv": 59, + "attr": "4&78" + }, + { + "id": 26, + "lv": 60, + "attr": "4&79" + }, + { + "id": 26, + "lv": 61, + "attr": "4&80" + }, + { + "id": 26, + "lv": 62, + "attr": "4&81" + }, + { + "id": 26, + "lv": 63, + "attr": "4&82" + }, + { + "id": 26, + "lv": 64, + "attr": "4&83" + }, + { + "id": 26, + "lv": 65, + "attr": "4&84" + }, + { + "id": 26, + "lv": 66, + "attr": "4&85" + }, + { + "id": 26, + "lv": 67, + "attr": "4&86" + }, + { + "id": 26, + "lv": 68, + "attr": "4&87" + }, + { + "id": 26, + "lv": 69, + "attr": "4&88" + }, + { + "id": 26, + "lv": 70, + "attr": "4&89" + }, + { + "id": 26, + "lv": 71, + "attr": "4&90" + }, + { + "id": 26, + "lv": 72, + "attr": "4&91" + }, + { + "id": 26, + "lv": 73, + "attr": "4&92" + }, + { + "id": 26, + "lv": 74, + "attr": "4&93" + }, + { + "id": 26, + "lv": 75, + "attr": "4&94" + }, + { + "id": 26, + "lv": 76, + "attr": "4&95" + }, + { + "id": 26, + "lv": 77, + "attr": "4&96" + }, + { + "id": 26, + "lv": 78, + "attr": "4&97" + }, + { + "id": 26, + "lv": 79, + "attr": "4&98" + }, + { + "id": 26, + "lv": 80, + "attr": "4&99" + }, + { + "id": 26, + "lv": 81, + "attr": "4&100" + }, + { + "id": 26, + "lv": 82, + "attr": "4&101" + }, + { + "id": 26, + "lv": 83, + "attr": "4&102" + }, + { + "id": 26, + "lv": 84, + "attr": "4&103" + }, + { + "id": 26, + "lv": 85, + "attr": "4&104" + }, + { + "id": 26, + "lv": 86, + "attr": "4&105" + }, + { + "id": 26, + "lv": 87, + "attr": "4&106" + }, + { + "id": 26, + "lv": 88, + "attr": "4&107" + }, + { + "id": 26, + "lv": 89, + "attr": "4&108" + }, + { + "id": 26, + "lv": 90, + "attr": "4&109" + }, + { + "id": 26, + "lv": 91, + "attr": "4&110" + }, + { + "id": 26, + "lv": 92, + "attr": "4&111" + }, + { + "id": 26, + "lv": 93, + "attr": "4&112" + }, + { + "id": 26, + "lv": 94, + "attr": "4&113" + }, + { + "id": 26, + "lv": 95, + "attr": "4&114" + }, + { + "id": 26, + "lv": 96, + "attr": "4&115" + }, + { + "id": 26, + "lv": 97, + "attr": "4&116" + }, + { + "id": 26, + "lv": 98, + "attr": "4&117" + }, + { + "id": 26, + "lv": 99, + "attr": "4&118" + }, + { + "id": 26, + "lv": 100, + "attr": "4&119" + }, + { + "id": 27, + "lv": 1, + "attr": "5&20" + }, + { + "id": 27, + "lv": 2, + "attr": "5&21" + }, + { + "id": 27, + "lv": 3, + "attr": "5&22" + }, + { + "id": 27, + "lv": 4, + "attr": "5&23" + }, + { + "id": 27, + "lv": 5, + "attr": "5&24" + }, + { + "id": 27, + "lv": 6, + "attr": "5&25" + }, + { + "id": 27, + "lv": 7, + "attr": "5&26" + }, + { + "id": 27, + "lv": 8, + "attr": "5&27" + }, + { + "id": 27, + "lv": 9, + "attr": "5&28" + }, + { + "id": 27, + "lv": 10, + "attr": "5&29" + }, + { + "id": 27, + "lv": 11, + "attr": "5&30" + }, + { + "id": 27, + "lv": 12, + "attr": "5&31" + }, + { + "id": 27, + "lv": 13, + "attr": "5&32" + }, + { + "id": 27, + "lv": 14, + "attr": "5&33" + }, + { + "id": 27, + "lv": 15, + "attr": "5&34" + }, + { + "id": 27, + "lv": 16, + "attr": "5&35" + }, + { + "id": 27, + "lv": 17, + "attr": "5&36" + }, + { + "id": 27, + "lv": 18, + "attr": "5&37" + }, + { + "id": 27, + "lv": 19, + "attr": "5&38" + }, + { + "id": 27, + "lv": 20, + "attr": "5&39" + }, + { + "id": 27, + "lv": 21, + "attr": "5&40" + }, + { + "id": 27, + "lv": 22, + "attr": "5&41" + }, + { + "id": 27, + "lv": 23, + "attr": "5&42" + }, + { + "id": 27, + "lv": 24, + "attr": "5&43" + }, + { + "id": 27, + "lv": 25, + "attr": "5&44" + }, + { + "id": 27, + "lv": 26, + "attr": "5&45" + }, + { + "id": 27, + "lv": 27, + "attr": "5&46" + }, + { + "id": 27, + "lv": 28, + "attr": "5&47" + }, + { + "id": 27, + "lv": 29, + "attr": "5&48" + }, + { + "id": 27, + "lv": 30, + "attr": "5&49" + }, + { + "id": 27, + "lv": 31, + "attr": "5&50" + }, + { + "id": 27, + "lv": 32, + "attr": "5&51" + }, + { + "id": 27, + "lv": 33, + "attr": "5&52" + }, + { + "id": 27, + "lv": 34, + "attr": "5&53" + }, + { + "id": 27, + "lv": 35, + "attr": "5&54" + }, + { + "id": 27, + "lv": 36, + "attr": "5&55" + }, + { + "id": 27, + "lv": 37, + "attr": "5&56" + }, + { + "id": 27, + "lv": 38, + "attr": "5&57" + }, + { + "id": 27, + "lv": 39, + "attr": "5&58" + }, + { + "id": 27, + "lv": 40, + "attr": "5&59" + }, + { + "id": 27, + "lv": 41, + "attr": "5&60" + }, + { + "id": 27, + "lv": 42, + "attr": "5&61" + }, + { + "id": 27, + "lv": 43, + "attr": "5&62" + }, + { + "id": 27, + "lv": 44, + "attr": "5&63" + }, + { + "id": 27, + "lv": 45, + "attr": "5&64" + }, + { + "id": 27, + "lv": 46, + "attr": "5&65" + }, + { + "id": 27, + "lv": 47, + "attr": "5&66" + }, + { + "id": 27, + "lv": 48, + "attr": "5&67" + }, + { + "id": 27, + "lv": 49, + "attr": "5&68" + }, + { + "id": 27, + "lv": 50, + "attr": "5&69" + }, + { + "id": 27, + "lv": 51, + "attr": "5&70" + }, + { + "id": 27, + "lv": 52, + "attr": "5&71" + }, + { + "id": 27, + "lv": 53, + "attr": "5&72" + }, + { + "id": 27, + "lv": 54, + "attr": "5&73" + }, + { + "id": 27, + "lv": 55, + "attr": "5&74" + }, + { + "id": 27, + "lv": 56, + "attr": "5&75" + }, + { + "id": 27, + "lv": 57, + "attr": "5&76" + }, + { + "id": 27, + "lv": 58, + "attr": "5&77" + }, + { + "id": 27, + "lv": 59, + "attr": "5&78" + }, + { + "id": 27, + "lv": 60, + "attr": "5&79" + }, + { + "id": 27, + "lv": 61, + "attr": "5&80" + }, + { + "id": 27, + "lv": 62, + "attr": "5&81" + }, + { + "id": 27, + "lv": 63, + "attr": "5&82" + }, + { + "id": 27, + "lv": 64, + "attr": "5&83" + }, + { + "id": 27, + "lv": 65, + "attr": "5&84" + }, + { + "id": 27, + "lv": 66, + "attr": "5&85" + }, + { + "id": 27, + "lv": 67, + "attr": "5&86" + }, + { + "id": 27, + "lv": 68, + "attr": "5&87" + }, + { + "id": 27, + "lv": 69, + "attr": "5&88" + }, + { + "id": 27, + "lv": 70, + "attr": "5&89" + }, + { + "id": 27, + "lv": 71, + "attr": "5&90" + }, + { + "id": 27, + "lv": 72, + "attr": "5&91" + }, + { + "id": 27, + "lv": 73, + "attr": "5&92" + }, + { + "id": 27, + "lv": 74, + "attr": "5&93" + }, + { + "id": 27, + "lv": 75, + "attr": "5&94" + }, + { + "id": 27, + "lv": 76, + "attr": "5&95" + }, + { + "id": 27, + "lv": 77, + "attr": "5&96" + }, + { + "id": 27, + "lv": 78, + "attr": "5&97" + }, + { + "id": 27, + "lv": 79, + "attr": "5&98" + }, + { + "id": 27, + "lv": 80, + "attr": "5&99" + }, + { + "id": 27, + "lv": 81, + "attr": "5&100" + }, + { + "id": 27, + "lv": 82, + "attr": "5&101" + }, + { + "id": 27, + "lv": 83, + "attr": "5&102" + }, + { + "id": 27, + "lv": 84, + "attr": "5&103" + }, + { + "id": 27, + "lv": 85, + "attr": "5&104" + }, + { + "id": 27, + "lv": 86, + "attr": "5&105" + }, + { + "id": 27, + "lv": 87, + "attr": "5&106" + }, + { + "id": 27, + "lv": 88, + "attr": "5&107" + }, + { + "id": 27, + "lv": 89, + "attr": "5&108" + }, + { + "id": 27, + "lv": 90, + "attr": "5&109" + }, + { + "id": 27, + "lv": 91, + "attr": "5&110" + }, + { + "id": 27, + "lv": 92, + "attr": "5&111" + }, + { + "id": 27, + "lv": 93, + "attr": "5&112" + }, + { + "id": 27, + "lv": 94, + "attr": "5&113" + }, + { + "id": 27, + "lv": 95, + "attr": "5&114" + }, + { + "id": 27, + "lv": 96, + "attr": "5&115" + }, + { + "id": 27, + "lv": 97, + "attr": "5&116" + }, + { + "id": 27, + "lv": 98, + "attr": "5&117" + }, + { + "id": 27, + "lv": 99, + "attr": "5&118" + }, + { + "id": 27, + "lv": 100, + "attr": "5&119" + }, + { + "id": 28, + "lv": 1, + "attr": "1&50" + }, + { + "id": 28, + "lv": 2, + "attr": "1&51" + }, + { + "id": 28, + "lv": 3, + "attr": "1&52" + }, + { + "id": 28, + "lv": 4, + "attr": "1&53" + }, + { + "id": 28, + "lv": 5, + "attr": "1&54" + }, + { + "id": 28, + "lv": 6, + "attr": "1&55" + }, + { + "id": 28, + "lv": 7, + "attr": "1&56" + }, + { + "id": 28, + "lv": 8, + "attr": "1&57" + }, + { + "id": 28, + "lv": 9, + "attr": "1&58" + }, + { + "id": 28, + "lv": 10, + "attr": "1&59" + }, + { + "id": 28, + "lv": 11, + "attr": "1&60" + }, + { + "id": 28, + "lv": 12, + "attr": "1&61" + }, + { + "id": 28, + "lv": 13, + "attr": "1&62" + }, + { + "id": 28, + "lv": 14, + "attr": "1&63" + }, + { + "id": 28, + "lv": 15, + "attr": "1&64" + }, + { + "id": 28, + "lv": 16, + "attr": "1&65" + }, + { + "id": 28, + "lv": 17, + "attr": "1&66" + }, + { + "id": 28, + "lv": 18, + "attr": "1&67" + }, + { + "id": 28, + "lv": 19, + "attr": "1&68" + }, + { + "id": 28, + "lv": 20, + "attr": "1&69" + }, + { + "id": 28, + "lv": 21, + "attr": "1&70" + }, + { + "id": 28, + "lv": 22, + "attr": "1&71" + }, + { + "id": 28, + "lv": 23, + "attr": "1&72" + }, + { + "id": 28, + "lv": 24, + "attr": "1&73" + }, + { + "id": 28, + "lv": 25, + "attr": "1&74" + }, + { + "id": 28, + "lv": 26, + "attr": "1&75" + }, + { + "id": 28, + "lv": 27, + "attr": "1&76" + }, + { + "id": 28, + "lv": 28, + "attr": "1&77" + }, + { + "id": 28, + "lv": 29, + "attr": "1&78" + }, + { + "id": 28, + "lv": 30, + "attr": "1&79" + }, + { + "id": 28, + "lv": 31, + "attr": "1&80" + }, + { + "id": 28, + "lv": 32, + "attr": "1&81" + }, + { + "id": 28, + "lv": 33, + "attr": "1&82" + }, + { + "id": 28, + "lv": 34, + "attr": "1&83" + }, + { + "id": 28, + "lv": 35, + "attr": "1&84" + }, + { + "id": 28, + "lv": 36, + "attr": "1&85" + }, + { + "id": 28, + "lv": 37, + "attr": "1&86" + }, + { + "id": 28, + "lv": 38, + "attr": "1&87" + }, + { + "id": 28, + "lv": 39, + "attr": "1&88" + }, + { + "id": 28, + "lv": 40, + "attr": "1&89" + }, + { + "id": 28, + "lv": 41, + "attr": "1&90" + }, + { + "id": 28, + "lv": 42, + "attr": "1&91" + }, + { + "id": 28, + "lv": 43, + "attr": "1&92" + }, + { + "id": 28, + "lv": 44, + "attr": "1&93" + }, + { + "id": 28, + "lv": 45, + "attr": "1&94" + }, + { + "id": 28, + "lv": 46, + "attr": "1&95" + }, + { + "id": 28, + "lv": 47, + "attr": "1&96" + }, + { + "id": 28, + "lv": 48, + "attr": "1&97" + }, + { + "id": 28, + "lv": 49, + "attr": "1&98" + }, + { + "id": 28, + "lv": 50, + "attr": "1&99" + }, + { + "id": 28, + "lv": 51, + "attr": "1&100" + }, + { + "id": 28, + "lv": 52, + "attr": "1&101" + }, + { + "id": 28, + "lv": 53, + "attr": "1&102" + }, + { + "id": 28, + "lv": 54, + "attr": "1&103" + }, + { + "id": 28, + "lv": 55, + "attr": "1&104" + }, + { + "id": 28, + "lv": 56, + "attr": "1&105" + }, + { + "id": 28, + "lv": 57, + "attr": "1&106" + }, + { + "id": 28, + "lv": 58, + "attr": "1&107" + }, + { + "id": 28, + "lv": 59, + "attr": "1&108" + }, + { + "id": 28, + "lv": 60, + "attr": "1&109" + }, + { + "id": 28, + "lv": 61, + "attr": "1&110" + }, + { + "id": 28, + "lv": 62, + "attr": "1&111" + }, + { + "id": 28, + "lv": 63, + "attr": "1&112" + }, + { + "id": 28, + "lv": 64, + "attr": "1&113" + }, + { + "id": 28, + "lv": 65, + "attr": "1&114" + }, + { + "id": 28, + "lv": 66, + "attr": "1&115" + }, + { + "id": 28, + "lv": 67, + "attr": "1&116" + }, + { + "id": 28, + "lv": 68, + "attr": "1&117" + }, + { + "id": 28, + "lv": 69, + "attr": "1&118" + }, + { + "id": 28, + "lv": 70, + "attr": "1&119" + }, + { + "id": 28, + "lv": 71, + "attr": "1&120" + }, + { + "id": 28, + "lv": 72, + "attr": "1&121" + }, + { + "id": 28, + "lv": 73, + "attr": "1&122" + }, + { + "id": 28, + "lv": 74, + "attr": "1&123" + }, + { + "id": 28, + "lv": 75, + "attr": "1&124" + }, + { + "id": 28, + "lv": 76, + "attr": "1&125" + }, + { + "id": 28, + "lv": 77, + "attr": "1&126" + }, + { + "id": 28, + "lv": 78, + "attr": "1&127" + }, + { + "id": 28, + "lv": 79, + "attr": "1&128" + }, + { + "id": 28, + "lv": 80, + "attr": "1&129" + }, + { + "id": 28, + "lv": 81, + "attr": "1&130" + }, + { + "id": 28, + "lv": 82, + "attr": "1&131" + }, + { + "id": 28, + "lv": 83, + "attr": "1&132" + }, + { + "id": 28, + "lv": 84, + "attr": "1&133" + }, + { + "id": 28, + "lv": 85, + "attr": "1&134" + }, + { + "id": 28, + "lv": 86, + "attr": "1&135" + }, + { + "id": 28, + "lv": 87, + "attr": "1&136" + }, + { + "id": 28, + "lv": 88, + "attr": "1&137" + }, + { + "id": 28, + "lv": 89, + "attr": "1&138" + }, + { + "id": 28, + "lv": 90, + "attr": "1&139" + }, + { + "id": 28, + "lv": 91, + "attr": "1&140" + }, + { + "id": 28, + "lv": 92, + "attr": "1&141" + }, + { + "id": 28, + "lv": 93, + "attr": "1&142" + }, + { + "id": 28, + "lv": 94, + "attr": "1&143" + }, + { + "id": 28, + "lv": 95, + "attr": "1&144" + }, + { + "id": 28, + "lv": 96, + "attr": "1&145" + }, + { + "id": 28, + "lv": 97, + "attr": "1&146" + }, + { + "id": 28, + "lv": 98, + "attr": "1&147" + }, + { + "id": 28, + "lv": 99, + "attr": "1&148" + }, + { + "id": 28, + "lv": 100, + "attr": "1&149" + } +] \ No newline at end of file From ef731fc979136a1d2b052a54a41ae7c2119aeb19 Mon Sep 17 00:00:00 2001 From: luying Date: Tue, 29 Mar 2022 18:08:50 +0800 Subject: [PATCH 07/12] =?UTF-8?q?=E6=88=98=E5=8A=9B=EF=BC=9A=E6=95=B4?= =?UTF-8?q?=E7=90=86?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- game-server/app/services/role/calCe.ts | 667 +++++++++++++------------ 1 file changed, 344 insertions(+), 323 deletions(-) diff --git a/game-server/app/services/role/calCe.ts b/game-server/app/services/role/calCe.ts index 127271d3f..e6ffb73ab 100644 --- a/game-server/app/services/role/calCe.ts +++ b/game-server/app/services/role/calCe.ts @@ -9,174 +9,32 @@ import { gameData, getEquipQualityIdByEquipIdAndPoint, getEquipStarAttrByStage, import { DicRandomEffectPool } from "../../pubUtils/dictionary/DicRandomEffectPool"; import { DicSe } from "../../pubUtils/dictionary/DicSe"; import { addToMap, deepCopy } from "../../pubUtils/util"; - export class CalCe { roleId: string; - globalAttrs: Map = new Map(); // attrId => GlobalAttr - heroAttrs: Map = new Map(); // hid+attrId => HeroAttr - heroAttrsByHid: Map = new Map(); // hid => [hid+attrId] - equipAttrs: Map = new Map(); // hid+eplaceId+attrId => EquipAttr - equipAttrsByHid: Map = new Map(); // hid => [hid+eplaceId+attrId] - equipAttrsByHidAndEplace: Map = new Map(); // hid+eplaceId =>[hid+eplaceId+attrId] - equipAttrsByHidAndAttrId: Map = new Map(); // hid+attrId =>[hid+eplaceId+attrId] - heroLv: Map = new Map(); - heroHistoryCe: Map = new Map(); - heroObjectId: Map = new Map(); - equipLv: Map = new Map(); // hid+eplaceId => lv originCes: Map = new Map(); // hid => ce resultCes: Map = new Map(); // hid => ce - schoolAttrs: Map = new Map(); // hid + attr => ratio - schoolAttrsByAttrId: Map = new Map(); // attrId => hid + attr - schoolAttrsByHid: Map = new Map(); // hid => hid + attr - scrollAttrs: Map = new Map(); // hid + attr => ratio - scrollAttrsByAttrId: Map = new Map(); // attrId => hid + attr - scrollAttrsByHid: Map = new Map(); // hid => hid + attr + data: CalCeData; constructor(roleId: string) { this.roleId = roleId; } - private getGlobalAttrById(attrId: number) { - if(!this.globalAttrs.has(attrId)) { - if(ABI_TYPE_MAIN.indexOf(attrId) != -1) { - let obj = new GlobalMainAttr(attrId); - this.globalAttrs.set(attrId, obj); - } else { - let obj = new GlobalSubAttr(attrId); - this.globalAttrs.set(attrId, obj); - } - } - return this.globalAttrs.get(attrId); + public setRoleCe(roleCe: RoleCeType) { + this.data = new CalCeData(roleCe) + this.originCes = this.calHeroCe(); } - - private getHeroAttrsByHid(hid: number) { - let keys = this.heroAttrsByHid.get(hid); - return keys.map(key => this.heroAttrs.get(key)); - } - - private getHeroAttrByHidAndId(hid: number, attrId: number) { - let key = `${hid}_${attrId}`; - if(!this.heroAttrs.has(key)) { - if(ABI_TYPE_MAIN.indexOf(attrId) != -1) { - let obj = new HeroMainAttr(hid, attrId); - this.heroAttrs.set(key, obj); - } else { - let obj = new HeroSubAttr(hid, attrId); - this.heroAttrs.set(key, obj); - } - - if(!this.heroAttrsByHid.has(hid)) { - this.heroAttrsByHid.set(hid, []); - } - this.heroAttrsByHid.get(hid).push(key); - } - return this.heroAttrs.get(key); - } - - private getEquipAttrByHidAndId(hid: number, eplaceId: number, attrId: number) { - let key = `${hid}_${eplaceId}_${attrId}`; - if(!this.equipAttrs.has(key)) { - if(ABI_TYPE_MAIN.indexOf(attrId) != -1) { - let obj = new EquipMainAttr(hid, attrId); - this.equipAttrs.set(key, obj); - } else { - let obj = new EquipSubAttr(hid, attrId); - this.equipAttrs.set(key, obj); - } - - if(!this.equipAttrsByHid.has(hid)) { - this.equipAttrsByHid.set(hid, []); - } - this.equipAttrsByHid.get(hid).push(key); - let key2 = `${hid}_${eplaceId}`; - if(!this.equipAttrsByHidAndEplace.has(key2)) { - this.equipAttrsByHidAndEplace.set(key2, { hid, eplaceId, keys: []}); - } - this.equipAttrsByHidAndEplace.get(key2).keys.push(key); - } - return this.equipAttrs.get(key); - } - - private getEquipAttrsByHidAndEplace(hid: number, eplaceId: number) { - let key2 = `${hid}_${eplaceId}`; - if(!this.equipAttrsByHidAndEplace.has(key2)) return [] - let { keys } = this.equipAttrsByHidAndEplace.get(key2); - return keys.map(key => this.equipAttrs.get(key)); - } - - private setSchoolAttrs(hid: number, attrId: number, value: number) { - let key = `${hid}_${attrId}`; - if(!this.schoolAttrs.has(key)) { - this.schoolAttrs.set(key, { hid, attrId, ce: value }); - if(!this.schoolAttrsByAttrId.has(attrId)) { - this.schoolAttrsByAttrId.set(attrId, []); - } - this.schoolAttrsByAttrId.get(attrId).push(key); - if(!this.schoolAttrsByHid.has(attrId)) { - this.schoolAttrsByHid.set(hid, []); - } - this.schoolAttrsByHid.get(hid).push(key); - } else { - this.schoolAttrs.get(key).ce = value; - } - } - - private getSchoolAttrsByHid(hid: number) { - let keys = this.schoolAttrsByHid.get(hid)||[]; - return keys.map(key => this.schoolAttrs.get(key)); - } - - private calSchoolAttrsToGlobal(attrId: number) { - let keys = this.schoolAttrsByAttrId.get(attrId)||[]; - let schoolResult = 0; - for(let key of keys) { - let { ce } = this.schoolAttrs.get(key); - schoolResult += ce; - } - let globalAttr = this.getGlobalAttrById(attrId); - globalAttr.school = schoolResult; - } - - private setScrollAttrs(hid: number, attrId: number, value: number) { - let key = `${hid}_${attrId}`; - if(!this.scrollAttrs.has(key)) { - this.scrollAttrs.set(key, { hid, attrId, ce: value }); - if(!this.scrollAttrsByAttrId.has(attrId)) { - this.scrollAttrsByAttrId.set(attrId, []); - } - this.scrollAttrsByAttrId.get(attrId).push(key); - if(!this.scrollAttrsByHid.has(attrId)) { - this.scrollAttrsByHid.set(hid, []); - } - this.scrollAttrsByHid.get(hid).push(key); - } else { - this.scrollAttrs.get(key).ce = value; - } - } - - private getScrollAttrsByHid(hid: number) { - let keys = this.scrollAttrsByHid.get(hid)||[]; - return keys.map(key => this.scrollAttrs.get(key)); - } - - private calScrollAttrsToGlobal(attrId: number) { - let keys = this.scrollAttrsByAttrId.get(attrId)||[]; - let result = 0; - for(let key of keys) { - let { ce } = this.scrollAttrs.get(key); - result += ce; - } - let globalAttr = this.getGlobalAttrById(attrId); - globalAttr.scroll = result; + + public getRoleCeTable() { + return this.data.getRoleCeTable(this.roleId); } public calHeroCe() { let ces = new Map(); // hid => [{attrId, val}] - for(let [hid, keys] of this.heroAttrsByHid) { - let lv = this.heroLv.get(hid)||1; + for(let [hid, keys] of this.data.heroAttrsByHid) { + let lv = this.data.heroLv.get(hid)||1; for(let key of keys) { - let { attrId, mainBase = 0, subBase = 0, job = 0, starUp = 0, connect = 0, favour = 0, talent = 0, equipQuality = 0, equipStrength = 0, equipStar = 0, equipSuit = 0, jewel = 0, stone = 0 } = this.heroAttrs.get(key); - let { school = 0, teraph = 0, title = 0, scroll = 0, skin = 0 } = this.getGlobalAttrById(attrId); + let { attrId, mainBase = 0, subBase = 0, job = 0, starUp = 0, connect = 0, favour = 0, talent = 0, equipQuality = 0, equipStrength = 0, equipStar = 0, equipSuit = 0, jewel = 0, stone = 0 } = this.data.heroAttrs.get(key); + let { school = 0, teraph = 0, title = 0, scroll = 0, skin = 0 } = this.data.getGlobalAttrById(attrId); let val = 0; if(ABI_TYPE_MAIN.indexOf(attrId)) { // {[hp1 + lv * hp2 + hp3 * ( 1 + hp4 )] * (1 + hp5 ) + [( hp6 + hp7 ) * ( 1 + hp8 )] } * ( 1 + hp9 ) + hp10 + hp11 @@ -210,93 +68,14 @@ export class CalCe { if(ce != originCe) { heroCe.set(hid, { inc: ce - originCe, origin: originCe, ce }); roleInc += ce - originCe; - this.setHistoryCe(hid, ce); + this.data.setHistoryCe(hid, ce); } } return { heroCe, roleInc } } - private setHistoryCe(hid: number, ce: number) { - let historyCe = this.heroHistoryCe.get(hid)||0; - if(ce > historyCe) { - this.heroHistoryCe.set(hid, ce); - } - } - - public getRoleCeTable() { - let globalAttrs: AttrCell[] = []; - for(let [_, globalAttr] of this.globalAttrs) { - globalAttrs.push(globalAttr.getGlobalAttr()); - } - let heroAttrs: HeroAttr[] = []; - for(let [hid, keys] of this.heroAttrsByHid) { - let lv = this.heroLv.get(hid); - let historyCe = this.heroHistoryCe.get(hid)||0; - let objectId = this.heroObjectId.get(hid); - let attrs: AttrCell[] = []; - for(let key of keys) { - let heroAttr = this.heroAttrs.get(key); - attrs.push(heroAttr.getHeroAttrCell()); - } - heroAttrs.push({ - hid, lv, attrs, historyCe, objectId - }); - } - let equipAttrs: EquipAttr[] = []; - for(let [key2, { hid, eplaceId, keys }] of this.equipAttrsByHidAndEplace) { - let lv = this.equipLv.get(key2); - let attrs: AttrCell[] = []; - for(let key of keys) { - let equipAttr = this.equipAttrs.get(key); - attrs.push(equipAttr.getEquipAttrCell()); - } - equipAttrs.push({ - hid, eplaceId, lv, attrs - }); - } - let schoolAttrs: SchoolAttr[] = []; - for(let [_, { hid, attrId, ce }] of this.schoolAttrs) { - schoolAttrs.push({ hid, attrId, value: ce }); - } - return { - roleId: this.roleId, globalAttrs, heroAttrs, equipAttrs, schoolAttrs - } - } - - public setRoleCe(roleCe: RoleCeType) { - if(roleCe) { - for(let globalAttr of roleCe.globalAttrs) { - let obj = this.getGlobalAttrById(globalAttr.attrId); - obj.setByRoleCe(globalAttr); - } - for(let {hid, lv, attrs, historyCe, objectId } of roleCe.heroAttrs) { - this.heroLv.set(hid, lv); - this.heroHistoryCe.set(hid, historyCe); - this.heroObjectId.set(hid, objectId); - for(let cell of attrs) { - let obj = this.getHeroAttrByHidAndId(hid, cell.attrId); - obj.setByRoleCe(cell); - } - } - for(let { hid, eplaceId, lv, attrs } of roleCe.equipAttrs) { - this.equipLv.set(`${hid}_${eplaceId}`, lv); - for(let cell of attrs) { - let obj = this.getEquipAttrByHidAndId(hid, eplaceId, cell.attrId); - obj.setByRoleCe(cell); - } - } - for(let { hid, attrId, value } of roleCe.schoolAttrs) { - this.setSchoolAttrs(hid, attrId, value); - } - for(let { hid, attrId, value } of roleCe.scrollAttrs) { - this.setScrollAttrs(hid, attrId, value); - } - } - this.originCes = this.calHeroCe(); - } - public setResultHero(hero: HeroType) { - this.heroObjectId.set(hero.hid, hero._id); + this.data.setResultHero(hero); } public getResultCeArr() { @@ -315,7 +94,7 @@ export class CalCe { if(arr[i]) { let { hid, ce } = arr[i]; topLineup.push({ - hid, ce, hero: this.heroObjectId.get(hid) + hid, ce, hero: this.data.heroObjectId.get(hid) }); topLineupCe += ce; } @@ -323,66 +102,26 @@ export class CalCe { return { topLineup, topLineupCe }; } - private clearRoleAttr(field: string) { - for(let globalAttr of this.globalAttrs) { - globalAttr[field] = 0; - } - } - - private clearHeroAttrByHid(hid: number, field: string) { - let heroAttrs = this.getHeroAttrsByHid(hid); - for(let heroAttr of heroAttrs) { - heroAttr[field] = 0; - } - } - - private clearEquipAttrByHidAndEplace(hid: number, eplaceId: number, field: string) { - let equipAttrs = this.getEquipAttrsByHidAndEplace(hid, eplaceId); - for(let equipAttr of equipAttrs) { - let originNum = equipAttr[field]||0; - let heroAttr = this.getHeroAttrByHidAndId(hid, equipAttr.attrId); - if(heroAttr && heroAttr[field]) { - heroAttr[field] -= originNum; - } - equipAttr[field] = 0; - } - } - - private clearSchoolAttr(hid: number) { - let schoolAttrs = this.getSchoolAttrsByHid(hid); - for(let schoolAttr of schoolAttrs) { - schoolAttr.ce = 0; - this.calSchoolAttrsToGlobal(schoolAttr.attrId); - } - } - - private clearScrollAttr(hid: number) { - let scrollAttrs = this.getScrollAttrsByHid(hid); - for(let scrollAttr of scrollAttrs) { - scrollAttr.ce = 0; - this.calScrollAttrsToGlobal(scrollAttr.attrId); - } - } // 武将基础&成长 public setHeroBase(hid: number, skinId: number) { - this.clearHeroAttrByHid(hid, 'mainBase'); + this.data.clearHeroAttrByHid(hid, 'mainBase'); let dicHero = gameData.hero.get(skinId); for(let [attrId, value] of dicHero.baseAbilityArr) { - let heroAttr = this.getHeroAttrByHidAndId(hid, attrId); + let heroAttr = this.data.getHeroAttrByHidAndId(hid, attrId); heroAttr.mainBase = value; } } // 武将等级 public setHeroLv(hid: number, lv: number) { - this.heroLv.set(hid, lv); + this.data.heroLv.set(hid, lv); } // 星级相关 public setHeroStar(hid: number, job: number, quality: number, star: number, starStage: number, colorStar: number, colorStarStage: number) { - this.clearHeroAttrByHid(hid, 'starUp'); + this.data.clearHeroAttrByHid(hid, 'starUp'); let dicJob = gameData.job.get(job); let jobClass = dicJob.job_class; const isWake = colorStar > 0; // 是否觉醒,只要激活了觉醒,彩星就会 > 1 @@ -398,47 +137,47 @@ export class CalCe { } else { value = dicPreStar?.ceAttr.get(stage)||0; } - let heroAttr = this.getHeroAttrByHidAndId(hid, attrId); + let heroAttr = this.data.getHeroAttrByHidAndId(hid, attrId); heroAttr.starUp = value; }; } // 职业基础 public setJob(hid: number, job: number, jobStage: number) { - this.clearHeroAttrByHid(hid, 'job'); - this.clearHeroAttrByHid(hid, 'subBase'); + this.data.clearHeroAttrByHid(hid, 'job'); + this.data.clearHeroAttrByHid(hid, 'subBase'); const 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(jobStage >= i) { let { id, attr } = dicJob.ceAttr.get(i); - let heroAttr = this.getHeroAttrByHidAndId(hid, id); + let heroAttr = this.data.getHeroAttrByHidAndId(hid, id); heroAttr.job = attr; } else { if(dicLastJob) { let { id, attr } = dicLastJob.ceAttr.get(i); - let heroAttr = this.getHeroAttrByHidAndId(hid, id); + let heroAttr = this.data.getHeroAttrByHidAndId(hid, id); heroAttr.job = attr; } } } for(let { id, val } of dicJob.baseSubAttr) { - let heroAttr = this.getHeroAttrByHidAndId(hid, id); + let heroAttr = this.data.getHeroAttrByHidAndId(hid, id); heroAttr.subBase = val; } } // 好感度 public setFavour(hid: number, favourLv: number, connections: Connect[]) { - this.clearHeroAttrByHid(hid, 'favour'); + this.data.clearHeroAttrByHid(hid, 'favour'); let currentFiendShipLevel = gameData.friendShipLevelMap.get(favourLv); let add = currentFiendShipLevel.add; for (let {shipId, level} of connections) { let dicHeroFriendShip = getFriendShipById(shipId, level); for (let { id } of dicHeroFriendShip.attributes) { - let heroAttr = this.getHeroAttrByHidAndId(hid, id); + let heroAttr = this.data.getHeroAttrByHidAndId(hid, id); heroAttr.favour = add; } } @@ -446,14 +185,14 @@ export class CalCe { // 羁绊 public setConnection(hid: number, shipId: number, connections: Connect[]) { - this.clearHeroAttrByHid(hid, 'connect'); + this.data.clearHeroAttrByHid(hid, 'connect'); let connect = connections.find(cur => cur.shipId == shipId); let level = connect?.level||0; let currentShip = getFriendShipById(shipId, level); if (currentShip) { for (let { id, number: val } of currentShip.attributes) { - let heroAttr = this.getHeroAttrByHidAndId(hid, id); + let heroAttr = this.data.getHeroAttrByHidAndId(hid, id); heroAttr.connect = val; } } @@ -463,24 +202,24 @@ export class CalCe { public setAddSkin(skinId: number) { let addSkin = gameData.fashion.get(skinId); for (let { id, number: val } of addSkin.globalAttr) { - let globalAttr = this.getGlobalAttrById(id); + let globalAttr = this.data.getGlobalAttrById(id); globalAttr.skin += val; } } // 天赋 public setTalent(hid: number, skins: HeroSkin[]) { - this.clearHeroAttrByHid(hid, 'talent'); + this.data.clearHeroAttrByHid(hid, 'talent'); let skin = skins.find(cur => cur.enable); let seids = this.getTalentSeid(skin.talent); let { ratioUp } = this.addSeidEffect(seids); for(let [attrId, val] of ratioUp) { - let heroAttr = this.getHeroAttrByHidAndId(hid, attrId); + let heroAttr = this.data.getHeroAttrByHidAndId(hid, attrId); heroAttr.talent = val; } } - private getTalentSeid(talent: Talent[]) { + public getTalentSeid(talent: Talent[]) { let seids = new Map(); // id, seids for(let { id, level } of talent) { let dicHeroTalent = gameData.heroTalent.get(id); @@ -507,11 +246,11 @@ export class CalCe { // 装备升品 public setEquipQuality(hid: number, eplaceId: number, equipId: number, quality: number, qualityStage: number) { - this.clearEquipAttrByHidAndEplace(hid, eplaceId, 'equipQuality'); + this.data.clearEquipAttrByHidAndEplace(hid, eplaceId, 'equipQuality'); let dicEquipQuality = getEquipQualityIdByEquipIdAndPoint(equipId, quality, qualityStage); for(let { id, num } of dicEquipQuality.attribute) { - let equipAttr = this.getEquipAttrByHidAndId(hid, eplaceId, id); - let heroAttr = this.getHeroAttrByHidAndId(hid, id); + let equipAttr = this.data.getEquipAttrByHidAndId(hid, eplaceId, id); + let heroAttr = this.data.getHeroAttrByHidAndId(hid, id); heroAttr.equipQuality += num - equipAttr.equipQuality; equipAttr.equipQuality = num; } @@ -519,11 +258,11 @@ export class CalCe { // 装备强化 public setEquipStrength(hid: number, eplaceId: number, equipId: number, lv: number) { - this.clearEquipAttrByHidAndEplace(hid, eplaceId, 'equipStrengthen'); + this.data.clearEquipAttrByHidAndEplace(hid, eplaceId, 'equipStrengthen'); let dicEquipStrenth = getEquipStrenthenAttr(equipId, lv); for(let { id, num } of dicEquipStrenth.attr) { - let equipAttr = this.getEquipAttrByHidAndId(hid, eplaceId, id); - let heroAttr = this.getHeroAttrByHidAndId(hid, id); + let equipAttr = this.data.getEquipAttrByHidAndId(hid, eplaceId, id); + let heroAttr = this.data.getHeroAttrByHidAndId(hid, id); heroAttr.equipStrength = num - equipAttr.equipStrengthen; equipAttr.equipStrengthen = num; } @@ -531,13 +270,13 @@ export class CalCe { // 装备精炼(升星) public setEquipStar(hid: number, eplaceId: number, equipId: number, star: number, starStage: number) { - this.clearEquipAttrByHidAndEplace(hid, eplaceId, 'equipStar'); + this.data.clearEquipAttrByHidAndEplace(hid, eplaceId, 'equipStar'); let dicEquipStar = getEquipStarAttrByStage(equipId, star, starStage); if(dicEquipStar) { let { mainAttr, subAttr } = dicEquipStar; for(let { id, num } of [...mainAttr, ...subAttr]) { - let equipAttr = this.getEquipAttrByHidAndId(hid, eplaceId, id); - let heroAttr = this.getHeroAttrByHidAndId(hid, id); + let equipAttr = this.data.getEquipAttrByHidAndId(hid, eplaceId, id); + let heroAttr = this.data.getHeroAttrByHidAndId(hid, id); heroAttr.equipStar = num - equipAttr.equipStar; equipAttr.equipStar = num; } @@ -546,7 +285,7 @@ export class CalCe { // 装备套装 public setEquipSuit(hid: number, ePlace: EPlace[]) { - this.clearHeroAttrByHid(hid, 'equipSuit'); + this.data.clearHeroAttrByHid(hid, 'equipSuit'); let dicEquipSuit = getEquipSuitByHero(hid); let suitStars: number[] = []; for(let equipId of dicEquipSuit.equips) { @@ -562,14 +301,14 @@ export class CalCe { let { ratioUp } = this.addSeidEffect(seids); for(let [attrId, val] of ratioUp) { - let heroAttr = this.getHeroAttrByHidAndId(hid, attrId); + let heroAttr = this.data.getHeroAttrByHidAndId(hid, attrId); heroAttr.equipSuit = val; } } // 天晶 public setJewel(hid: number, eplaceId: number, stones: Stone[], jewel: JewelType) { - this.clearEquipAttrByHidAndEplace(hid, eplaceId, 'jewel'); + this.data.clearEquipAttrByHidAndEplace(hid, eplaceId, 'jewel'); let seids: number[] = []; if(jewel) { for(let { id, seid, rand } of jewel.randSe) { @@ -580,14 +319,14 @@ export class CalCe { } let { ratioUp } = this.addSeidEffect(seids); for(let [attrId, val] of ratioUp) { - let equipAttr = this.getEquipAttrByHidAndId(hid, eplaceId, attrId); - let heroAttr = this.getHeroAttrByHidAndId(hid, attrId); + let equipAttr = this.data.getEquipAttrByHidAndId(hid, eplaceId, attrId); + let heroAttr = this.data.getHeroAttrByHidAndId(hid, attrId); heroAttr.jewel += val - equipAttr.jewel; equipAttr.jewel = val; } } - private isRandSeUnLock(jewelId: number, randSeId: number, stones: Stone[]) { + public isRandSeUnLock(jewelId: number, randSeId: number, stones: Stone[]) { let dicJewel = gameData.jewel.get(jewelId); let dicJewelCondition = getJewelConditionByLvAndSeId(dicJewel.lv, randSeId); let stoneCnt = 0, stoneLv = 0; @@ -603,13 +342,13 @@ export class CalCe { // 地玉 public setStone(hid: number, eplaceId: number, stones: Stone[]) { - this.clearEquipAttrByHidAndEplace(hid, eplaceId, 'stone'); + this.data.clearEquipAttrByHidAndEplace(hid, eplaceId, 'stone'); for(let { stone } of stones) { let dicStone = gameData.stone.get(stone); if(dicStone) { for(let { id, num } of dicStone.attribute) { - let equipAttr = this.getEquipAttrByHidAndId(hid, eplaceId, id); - let heroAttr = this.getHeroAttrByHidAndId(hid, id); + let equipAttr = this.data.getEquipAttrByHidAndId(hid, eplaceId, id); + let heroAttr = this.data.getHeroAttrByHidAndId(hid, id); heroAttr.stone += num - equipAttr.stone; equipAttr.stone = num; } @@ -620,21 +359,21 @@ export class CalCe { // 爵位 public setTitle(title: number) { - this.clearRoleAttr('title'); + this.data.clearRoleAttr('title'); let dicTitle = gameData.title.get(title)||{ mainAttrValue: new Map(), assiAttrValue: new Map() }; for(let [attrId, value] of dicTitle.mainAttrValue) { - let globalAttr = this.getGlobalAttrById(attrId); + let globalAttr = this.data.getGlobalAttrById(attrId); globalAttr.title = value; } for(let [attrId, value] of dicTitle.assiAttrValue) { - let globalAttr = this.getGlobalAttrById(attrId); + let globalAttr = this.data.getGlobalAttrById(attrId); globalAttr.title = value; } } // 神像相关 public setTeraph(teraphs: Teraph[]) { - this.clearRoleAttr('teraph'); + this.data.clearRoleAttr('teraph'); let teraphOfAttrId = new Map(); for(let teraph of teraphs) { for(let [attrId, value] of teraph.attr) { // 主属性 @@ -646,38 +385,38 @@ export class CalCe { } } for(let [attrId, value] of teraphOfAttrId) { - let globalAttr = this.getGlobalAttrById(attrId); + let globalAttr = this.data.getGlobalAttrById(attrId); globalAttr.teraph = value; } } // 名将谱 public setScroll(hid: number, scrollStar: number, scrollQuality: number, scrollColorStar: number) { - this.clearScrollAttr(hid); + this.data.clearScrollAttr(hid); let dicHero =gameData.hero.get(hid); let dicHeroScroll = getScollByStar(dicHero.quality, scrollStar, scrollQuality, scrollColorStar); if(dicHeroScroll) { for(let [attrId, value] of dicHeroScroll.ceAttr) { - this.setScrollAttrs(hid, attrId, value); - this.calScrollAttrsToGlobal(attrId); + this.data.setScrollAttrs(hid, attrId, value); + this.data.calScrollAttrsToGlobal(attrId); } } } // 百家学宫 public setSchool(isPutOn: boolean, hid: number, schoolId: number, star: number, colorStar: number, quality: number) { - this.clearSchoolAttr(hid); + this.data.clearSchoolAttr(hid); let dicSchool = gameData.school.get(schoolId); let dicSchoolRate = getSchoolRateByStar(star, colorStar, quality); for (let attrId of dicSchool.upAttribute) { if(ABI_TYPE_MAIN.includes(attrId)) { // 主属性 - this.setSchoolAttrs(hid, attrId, isPutOn?dicSchoolRate.mainAttrAPerent: 0); + this.data.setSchoolAttrs(hid, attrId, isPutOn?dicSchoolRate.mainAttrAPerent: 0); } else { - this.setSchoolAttrs(hid, attrId, isPutOn?dicSchoolRate.assiAttrAddValue: 0); + this.data.setSchoolAttrs(hid, attrId, isPutOn?dicSchoolRate.assiAttrAddValue: 0); } - this.calSchoolAttrsToGlobal(attrId); + this.data.calSchoolAttrsToGlobal(attrId); } } @@ -735,6 +474,288 @@ export class CalCe { } } +class CalCeData { + // 全局 + globalAttrs: Map = new Map(); // attrId => GlobalAttr + // 武将 + heroAttrs: Map = new Map(); // hid+attrId => HeroAttr + heroAttrsByHid: Map = new Map(); // hid => [hid+attrId] + heroLv: Map = new Map(); + heroHistoryCe: Map = new Map(); + heroObjectId: Map = new Map(); + // 装备 + equipAttrs: Map = new Map(); // hid+eplaceId+attrId => EquipAttr + equipAttrsByHid: Map = new Map(); // hid => [hid+eplaceId+attrId] + equipAttrsByHidAndEplace: Map = new Map(); // hid+eplaceId =>[hid+eplaceId+attrId] + equipAttrsByHidAndAttrId: Map = new Map(); // hid+attrId =>[hid+eplaceId+attrId] + equipLv: Map = new Map(); // hid+eplaceId => lv + // 百家学宫 + schoolAttrs: Map = new Map(); // hid + attr => ratio + schoolAttrsByAttrId: Map = new Map(); // attrId => hid + attr + schoolAttrsByHid: Map = new Map(); // hid => hid + attr + // 名将谱 + scrollAttrs: Map = new Map(); // hid + attr => ratio + scrollAttrsByAttrId: Map = new Map(); // attrId => hid + attr + scrollAttrsByHid: Map = new Map(); // hid => hid + attr + + constructor(roleCe: RoleCeType) { + if(roleCe) { + for(let globalAttr of roleCe.globalAttrs) { + let obj = this.getGlobalAttrById(globalAttr.attrId); + obj.setByRoleCe(globalAttr); + } + for(let {hid, lv, attrs, historyCe, objectId } of roleCe.heroAttrs) { + this.heroLv.set(hid, lv); + this.heroHistoryCe.set(hid, historyCe); + this.heroObjectId.set(hid, objectId); + for(let cell of attrs) { + let obj = this.getHeroAttrByHidAndId(hid, cell.attrId); + obj.setByRoleCe(cell); + } + } + for(let { hid, eplaceId, lv, attrs } of roleCe.equipAttrs) { + this.equipLv.set(`${hid}_${eplaceId}`, lv); + for(let cell of attrs) { + let obj = this.getEquipAttrByHidAndId(hid, eplaceId, cell.attrId); + obj.setByRoleCe(cell); + } + } + for(let { hid, attrId, value } of roleCe.schoolAttrs) { + this.setSchoolAttrs(hid, attrId, value); + } + for(let { hid, attrId, value } of roleCe.scrollAttrs) { + this.setScrollAttrs(hid, attrId, value); + } + } + } + + public getGlobalAttrById(attrId: number) { + if(!this.globalAttrs.has(attrId)) { + if(ABI_TYPE_MAIN.indexOf(attrId) != -1) { + let obj = new GlobalMainAttr(attrId); + this.globalAttrs.set(attrId, obj); + } else { + let obj = new GlobalSubAttr(attrId); + this.globalAttrs.set(attrId, obj); + } + } + return this.globalAttrs.get(attrId); + } + + public clearRoleAttr(field: string) { + for(let globalAttr of this.globalAttrs) { + globalAttr[field] = 0; + } + } + + public getHeroAttrsByHid(hid: number) { + let keys = this.heroAttrsByHid.get(hid); + return keys.map(key => this.heroAttrs.get(key)); + } + + public getHeroAttrByHidAndId(hid: number, attrId: number) { + let key = `${hid}_${attrId}`; + if(!this.heroAttrs.has(key)) { + if(ABI_TYPE_MAIN.indexOf(attrId) != -1) { + let obj = new HeroMainAttr(hid, attrId); + this.heroAttrs.set(key, obj); + } else { + let obj = new HeroSubAttr(hid, attrId); + this.heroAttrs.set(key, obj); + } + + if(!this.heroAttrsByHid.has(hid)) { + this.heroAttrsByHid.set(hid, []); + } + this.heroAttrsByHid.get(hid).push(key); + } + return this.heroAttrs.get(key); + } + + public clearHeroAttrByHid(hid: number, field: string) { + let heroAttrs = this.getHeroAttrsByHid(hid); + for(let heroAttr of heroAttrs) { + heroAttr[field] = 0; + } + } + + public getEquipAttrByHidAndId(hid: number, eplaceId: number, attrId: number) { + let key = `${hid}_${eplaceId}_${attrId}`; + if(!this.equipAttrs.has(key)) { + if(ABI_TYPE_MAIN.indexOf(attrId) != -1) { + let obj = new EquipMainAttr(hid, attrId); + this.equipAttrs.set(key, obj); + } else { + let obj = new EquipSubAttr(hid, attrId); + this.equipAttrs.set(key, obj); + } + + if(!this.equipAttrsByHid.has(hid)) { + this.equipAttrsByHid.set(hid, []); + } + this.equipAttrsByHid.get(hid).push(key); + let key2 = `${hid}_${eplaceId}`; + if(!this.equipAttrsByHidAndEplace.has(key2)) { + this.equipAttrsByHidAndEplace.set(key2, { hid, eplaceId, keys: []}); + } + this.equipAttrsByHidAndEplace.get(key2).keys.push(key); + } + return this.equipAttrs.get(key); + } + + public getEquipAttrsByHidAndEplace(hid: number, eplaceId: number) { + let key2 = `${hid}_${eplaceId}`; + if(!this.equipAttrsByHidAndEplace.has(key2)) return [] + let { keys } = this.equipAttrsByHidAndEplace.get(key2); + return keys.map(key => this.equipAttrs.get(key)); + } + + public clearEquipAttrByHidAndEplace(hid: number, eplaceId: number, field: string) { + let equipAttrs = this.getEquipAttrsByHidAndEplace(hid, eplaceId); + for(let equipAttr of equipAttrs) { + let originNum = equipAttr[field]||0; + let heroAttr = this.getHeroAttrByHidAndId(hid, equipAttr.attrId); + if(heroAttr && heroAttr[field]) { + heroAttr[field] -= originNum; + } + equipAttr[field] = 0; + } + } + + public setSchoolAttrs(hid: number, attrId: number, value: number) { + let key = `${hid}_${attrId}`; + if(!this.schoolAttrs.has(key)) { + this.schoolAttrs.set(key, { hid, attrId, ce: value }); + if(!this.schoolAttrsByAttrId.has(attrId)) { + this.schoolAttrsByAttrId.set(attrId, []); + } + this.schoolAttrsByAttrId.get(attrId).push(key); + if(!this.schoolAttrsByHid.has(attrId)) { + this.schoolAttrsByHid.set(hid, []); + } + this.schoolAttrsByHid.get(hid).push(key); + } else { + this.schoolAttrs.get(key).ce = value; + } + } + + public getSchoolAttrsByHid(hid: number) { + let keys = this.schoolAttrsByHid.get(hid)||[]; + return keys.map(key => this.schoolAttrs.get(key)); + } + + public calSchoolAttrsToGlobal(attrId: number) { + let keys = this.schoolAttrsByAttrId.get(attrId)||[]; + let schoolResult = 0; + for(let key of keys) { + let { ce } = this.schoolAttrs.get(key); + schoolResult += ce; + } + let globalAttr = this.getGlobalAttrById(attrId); + globalAttr.school = schoolResult; + } + + public clearSchoolAttr(hid: number) { + let schoolAttrs = this.getSchoolAttrsByHid(hid); + for(let schoolAttr of schoolAttrs) { + schoolAttr.ce = 0; + this.calSchoolAttrsToGlobal(schoolAttr.attrId); + } + } + + public setScrollAttrs(hid: number, attrId: number, value: number) { + let key = `${hid}_${attrId}`; + if(!this.scrollAttrs.has(key)) { + this.scrollAttrs.set(key, { hid, attrId, ce: value }); + if(!this.scrollAttrsByAttrId.has(attrId)) { + this.scrollAttrsByAttrId.set(attrId, []); + } + this.scrollAttrsByAttrId.get(attrId).push(key); + if(!this.scrollAttrsByHid.has(attrId)) { + this.scrollAttrsByHid.set(hid, []); + } + this.scrollAttrsByHid.get(hid).push(key); + } else { + this.scrollAttrs.get(key).ce = value; + } + } + + public calScrollAttrsToGlobal(attrId: number) { + let keys = this.scrollAttrsByAttrId.get(attrId)||[]; + let result = 0; + for(let key of keys) { + let { ce } = this.scrollAttrs.get(key); + result += ce; + } + let globalAttr = this.getGlobalAttrById(attrId); + globalAttr.scroll = result; + } + + public clearScrollAttr(hid: number) { + let scrollAttrs = this.getScrollAttrsByHid(hid); + for(let scrollAttr of scrollAttrs) { + scrollAttr.ce = 0; + this.calScrollAttrsToGlobal(scrollAttr.attrId); + } + } + + public getScrollAttrsByHid(hid: number) { + let keys = this.scrollAttrsByHid.get(hid)||[]; + return keys.map(key => this.scrollAttrs.get(key)); + } + + public setHistoryCe(hid: number, ce: number) { + let historyCe = this.heroHistoryCe.get(hid)||0; + if(ce > historyCe) { + this.heroHistoryCe.set(hid, ce); + } + } + + public setResultHero(hero: HeroType) { + this.heroObjectId.set(hero.hid, hero._id); + } + + public getRoleCeTable(roleId: string) { + let globalAttrs: AttrCell[] = []; + for(let [_, globalAttr] of this.globalAttrs) { + globalAttrs.push(globalAttr.getGlobalAttr()); + } + let heroAttrs: HeroAttr[] = []; + for(let [hid, keys] of this.heroAttrsByHid) { + let lv = this.heroLv.get(hid); + let historyCe = this.heroHistoryCe.get(hid)||0; + let objectId = this.heroObjectId.get(hid); + let attrs: AttrCell[] = []; + for(let key of keys) { + let heroAttr = this.heroAttrs.get(key); + attrs.push(heroAttr.getHeroAttrCell()); + } + heroAttrs.push({ + hid, lv, attrs, historyCe, objectId + }); + } + let equipAttrs: EquipAttr[] = []; + for(let [key2, { hid, eplaceId, keys }] of this.equipAttrsByHidAndEplace) { + let lv = this.equipLv.get(key2); + let attrs: AttrCell[] = []; + for(let key of keys) { + let equipAttr = this.equipAttrs.get(key); + attrs.push(equipAttr.getEquipAttrCell()); + } + equipAttrs.push({ + hid, eplaceId, lv, attrs + }); + } + let schoolAttrs: SchoolAttr[] = []; + for(let [_, { hid, attrId, ce }] of this.schoolAttrs) { + schoolAttrs.push({ hid, attrId, value: ce }); + } + return { + roleId, globalAttrs, heroAttrs, equipAttrs, schoolAttrs + } + } +} + abstract class GlobalAllAttr { attrId: number; school: number = 0; From 9adbd08d3cb0b30c17b11210975ec5243bed5311 Mon Sep 17 00:00:00 2001 From: luying Date: Wed, 30 Mar 2022 14:22:46 +0800 Subject: [PATCH 08/12] =?UTF-8?q?=E6=88=98=E5=8A=9B=EF=BC=9A=E8=8E=B7?= =?UTF-8?q?=E5=8F=96=E6=98=BE=E7=A4=BA=E6=95=B0=E6=8D=AE?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../app/servers/role/handler/friendHandler.ts | 7 +- .../app/servers/role/handler/heroHandler.ts | 1 - .../app/servers/role/handler/roleHandler.ts | 12 +- game-server/app/services/dungeonService.ts | 2 +- game-server/app/services/equipService.ts | 16 +- game-server/app/services/expeditionService.ts | 37 +- .../guildActivity/guildActivityService.ts | 3 +- game-server/app/services/guildBossService.ts | 4 +- .../app/services/normalBattleService.ts | 4 +- game-server/app/services/playerCeService.ts | 31 +- game-server/app/services/pvpService.ts | 41 +- game-server/app/services/rankService.ts | 34 +- game-server/app/services/role/_calCe.ts | 249 ---- game-server/app/services/role/calCe.ts | 44 +- game-server/app/services/role/createHero.ts | 10 +- .../app/services/role/rewardService.ts | 4 +- game-server/app/services/task/taskObj.ts | 3 +- gm-server/app/service/users.ts | 2 +- shared/consts/constModules/heroConst.ts | 5 +- shared/consts/constModules/selectConst.ts | 6 +- shared/db/Guild.ts | 6 +- shared/db/Hero.ts | 52 +- shared/db/Role.ts | 40 +- shared/db/RoleCe.ts | 26 +- shared/db/User.ts | 9 +- shared/domain/battleField/dungeon.ts | 2 +- shared/domain/rank.ts | 28 +- shared/domain/roleField/attribute.ts | 80 +- shared/domain/roleField/hero.ts | 7 +- shared/pubUtils/data.ts | 2 +- .../dictionary/DicEquipStrengthAttr.ts | 2 +- shared/pubUtils/playerCe.ts | 1108 ----------------- shared/pubUtils/util.ts | 17 +- 33 files changed, 205 insertions(+), 1689 deletions(-) delete mode 100644 game-server/app/services/role/_calCe.ts delete mode 100644 shared/pubUtils/playerCe.ts diff --git a/game-server/app/servers/role/handler/friendHandler.ts b/game-server/app/servers/role/handler/friendHandler.ts index 95428dcdb..0a99bbaaa 100644 --- a/game-server/app/servers/role/handler/friendHandler.ts +++ b/game-server/app/servers/role/handler/friendHandler.ts @@ -15,7 +15,6 @@ import { addItems, getFriendPointObject, handleCost } from "../../../services/ro import { RewardInter } from "../../../pubUtils/interface"; import { FriendPresentLogModel } from '../../../db/FriendPresentLog'; import { HeroModel, EPlace } from "../../../db/Hero"; -import { getPlayerMainAttribute } from "../../../services/pvpService"; import { FRIEND } from "../../../pubUtils/dicParam"; import { PlayerDetail, PlayerDetailHero } from "../../../domain/battleField/guild"; import { createPrivateMsg, pushMsgToRole, pushPresent } from "../../../services/chatService"; @@ -23,6 +22,7 @@ import { Rank } from "../../../services/rankService"; import { checkTaskWithRoles, checkTask } from "../../../services/task/taskService"; import { ComBattleTeamModel } from "../../../db/ComBattleTeam"; import { JewelModel } from "../../../db/Jewel"; +import { getHeroesAttributes } from "../../../services/playerCeService"; export default function (app: Application) { @@ -719,9 +719,12 @@ export class FriendHandler { let jewels = await JewelModel.findMapbyRoleAndHids(hisRoleId, hids); + let attrByHid = await getHeroesAttributes(hisRoleId); let list: HeroDetailParam[] = []; for (let hero of heroList) { - let attributes = getPlayerMainAttribute(hero.attr, role.attr); + let attr = attrByHid.get(hero.hid); + if(!attr) continue; + let attributes = attr.getMainAttributes(); let heroParam = new HeroDetailParam(hero); heroParam.setAttributes(attributes); heroParam.setJewels(jewels); diff --git a/game-server/app/servers/role/handler/heroHandler.ts b/game-server/app/servers/role/handler/heroHandler.ts index adfe95257..b2daaddf6 100644 --- a/game-server/app/servers/role/handler/heroHandler.ts +++ b/game-server/app/servers/role/handler/heroHandler.ts @@ -16,7 +16,6 @@ import { isNumber, pick } from 'underscore'; import { updateEplaces } from '../../../services/equipService'; import { addConsumeToHero, checkUnlockTalentCondition, initSkinTalent, updateSkinTalent } from '../../../services/roleService'; import { JewelModel, jewelUpdate } from '../../../db/Jewel'; -import { CalHeroCe } from '../../../services/role/_calCe'; import { HERO, REBORN } from '../../../pubUtils/dicParam'; import { createHero, createHeroes } from '../../../services/role/createHero'; import { CheckMeterial } from '../../../services/role/checkMaterial'; diff --git a/game-server/app/servers/role/handler/roleHandler.ts b/game-server/app/servers/role/handler/roleHandler.ts index f4a38ced1..33a543ed6 100644 --- a/game-server/app/servers/role/handler/roleHandler.ts +++ b/game-server/app/servers/role/handler/roleHandler.ts @@ -25,7 +25,7 @@ import Counter from '../../../db/Counter'; import { UserModel } from '../../../db/User'; import { checkFilterWords, reportTAEvent, treatRoleName } from '../../../services/sdkService'; import { createHeroes } from '../../../services/role/createHero'; -import { calculateCeWithHero, calculateWithRole } from '../../../services/playerCeService'; +import { calculateCeWithHero, calculateCeWithRole } from '../../../services/playerCeService'; export default function (app: Application) { new HandlerService(app, {}); @@ -50,7 +50,7 @@ export class RoleHandler { let checkName = await RoleModel.checkName(roleName, serverId); if (checkName) return resResult(STATUS.NAME_HAS_USED); - let { resultHeroes: heroes } = await createHeroes(roleId, roleName, sid, serverId, DEFAULT_HEROES.map(hid => ({hid, count: 1})), { roleName, hasInit: true, title: role.title, teraphs: role.teraphs }); + let { resultHeroes: heroes } = await createHeroes(roleId, roleName, sid, serverId, DEFAULT_HEROES.map(hid => ({hid, count: 1})), { roleName, hasInit: true, title: role.title, teraphs: role.teraphs, lv: DEFAULT_LV }); // role = await RoleModel.updateRoleInfo(roleId, { roleName, hasInit: true }); // 在算战力的时候一起更新 session.set('roleName', roleName); session.push('roleName', () => { }); @@ -95,7 +95,7 @@ export class RoleHandler { return resResult(STATUS.BATTLE_CONSUMES_NOT_ENOUGH); let update = { title: title + 1 } - let { curRole } = await calculateWithRole(HERO_SYSTEM_TYPE.TITLE, roleId, serverId, sid, update); + let { curRole } = await calculateCeWithRole(HERO_SYSTEM_TYPE.TITLE, roleId, serverId, sid, update); // 任务 await checkTask(serverId, roleId, sid, TASK_TYPE.ROLE_TITLE, { oldTitle: title, title: update.title }); @@ -128,7 +128,7 @@ export class RoleHandler { if (!result) return resResult(STATUS.BATTLE_CONSUMES_NOT_ENOUGH); - let { curRole } = await calculateWithRole(HERO_SYSTEM_TYPE.TERAPH, roleId, serverId, sid, { teraphs }, { teraphId: id }); + let { curRole } = await calculateCeWithRole(HERO_SYSTEM_TYPE.TERAPH, roleId, serverId, sid, { teraphs }, { teraphId: id }); // 任务 await checkTask(serverId, roleId, sid, TASK_TYPE.ROLE_TERAPH_STRENGTHEN, { count }); @@ -171,7 +171,7 @@ export class RoleHandler { let result = await handleCost(roleId, sid, consumes, ITEM_CHANGE_REASON.TERAPH_QUALITY_UP); if (!result) return resResult(STATUS.BATTLE_CONSUMES_NOT_ENOUGH); - let { curRole } = await calculateWithRole(HERO_SYSTEM_TYPE.TERAPH_UP, roleId, serverId, sid, { teraphs }, { teraphId: id }); + let { curRole } = await calculateCeWithRole(HERO_SYSTEM_TYPE.TERAPH_UP, roleId, serverId, sid, { teraphs }, { teraphId: id }); // 神像进阶,进阶一次就触发一次礼包弹框 await checkTask(serverId, roleId, sid, TASK_TYPE.ROLE_TERAPH_STAGE_UP); @@ -228,7 +228,7 @@ export class RoleHandler { } await SchoolModel.updateBySclAndPos(roleId, schoolId, positionId, { hid, isOpen }) - await calculateWithRole(HERO_SYSTEM_TYPE.SCHOOL, roleId, serverId, sid, {}, { schoolId, hero: curHero, schoolHid: hid, preSchoolHid: preHid }); + await calculateCeWithRole(HERO_SYSTEM_TYPE.SCHOOL, roleId, serverId, sid, {}, { schoolId, hero: curHero, schoolHid: hid, preSchoolHid: preHid }); // 任务 await checkTask(serverId, roleId, sid, TASK_TYPE.ROLE_SCHOOL_PUT_HERO, { hid, preHid }); diff --git a/game-server/app/services/dungeonService.ts b/game-server/app/services/dungeonService.ts index cb3db4088..1d3541bc5 100644 --- a/game-server/app/services/dungeonService.ts +++ b/game-server/app/services/dungeonService.ts @@ -97,7 +97,7 @@ export function getDungeonBuyCountCost(num:number) { } export async function saveDungeonFirst(role: RoleType, warId: number, battleRecord: BattleRecordType) { - let userInfo = new RankParam(role, true); + let userInfo = new RankParam(role); let lineup = battleRecord.record.lineup; let dicWar = gameData.war.get(warId); await DungeonFirstModel.createDungeonFirst(role.serverId, dicWar.movePoint, warId, { diff --git a/game-server/app/services/equipService.ts b/game-server/app/services/equipService.ts index c094a1d9d..c8fb0059f 100644 --- a/game-server/app/services/equipService.ts +++ b/game-server/app/services/equipService.ts @@ -1,6 +1,6 @@ import { getRandEelm, } from '../pubUtils/util'; import { EPlace, Stone } from "../db/Hero"; -import { gameData, getRandEffectByGroupAndLevel } from "../pubUtils/data"; +import { gameData, getJewelConditionByLvAndSeId, getRandEffectByGroupAndLevel } from "../pubUtils/data"; import { JewelType, RandSe } from '../db/Jewel'; import { DicRandomEffectPool } from '../pubUtils/dictionary/DicRandomEffectPool'; import { getJewelRandSe } from './role/rewardService'; @@ -144,4 +144,18 @@ export function getJewelByEquip(oldEquip: EPlace, newEquip: EPlace, jewels: Jewe let oldJewel = jewels.find(cur => cur && cur.seqId == oldEquip.jewel); let newJewel = jewels.find(cur => cur && cur.seqId == newEquip.jewel); return { oldJewel, newJewel } +} + +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; } \ No newline at end of file diff --git a/game-server/app/services/expeditionService.ts b/game-server/app/services/expeditionService.ts index 923dce455..d2ca098d3 100644 --- a/game-server/app/services/expeditionService.ts +++ b/game-server/app/services/expeditionService.ts @@ -1,16 +1,16 @@ import { ExpeditionPointModel } from '../db/ExpeditionPoint'; -import Role, { CeAttrDataRole, RoleModel } from '../db/Role'; +import Role, { RoleModel } from '../db/Role'; import { shouldRefresh, getRandSingleEelm } from '../pubUtils/util'; import { LINEUP_NUM, EXPEDITION_WAR_RECORD_STATUS } from '../consts'; import { ExpeditionWarRecordModel } from '../db/ExpeditionWarRecord'; -import { CeAttrData, HeroType } from '../db/Hero'; +import { HeroType } from '../db/Hero'; import { gameData } from '../pubUtils/data'; import { getTimeFunD } from '../pubUtils/timeUtil'; import { ExpeditionRecordModel } from '../db/ExpeditionRecord'; import { Attribute, AttributeCal } from '../domain/roleField/attribute'; import * as dicParam from '../pubUtils/dicParam'; -import { getSumCe } from './playerCeService'; +import { getHeroesAttributes, getSumCe } from './playerCeService'; /** * 获取远征关卡列表 @@ -137,7 +137,7 @@ export async function matchPlayers(roleId: string, scale: number, range: number, let index = Math.floor(Math.random() * resultRange.length); let role = resultRange[index]; let {roleId, topLineup, topLineupCe } = role; - let { attr: roleAttrs } = role; + let attrByHid = await getHeroesAttributes(roleId); enemyObj.enemyFrom = 1; enemyObj.enemyId = roleId; @@ -150,9 +150,10 @@ export async function matchPlayers(roleId: string, scale: number, range: number, if(hero) { let h = hero.hero; if(h) { - let { star, lv, attr: heroAttrs, ce } = h; + let { star, lv, ce } = h; let dicHero = gameData.hero.get(hero.hid); - let { attribute } = getPlayerAttribute(lv, heroAttrs, roleAttrs); + let attr = attrByHid.get(hero.hid); + let attribute = attr.getAttributesToString(); let heroInfo = { actorId: hero.hid, skinId: h.skinId, @@ -281,32 +282,18 @@ export async function getResetRemainCnt(curTime: Date, roleId: string, role?: Ro let newAttribute = new AttributeCal(); newAttribute.setLv(lv); newAttribute.setByWarJson(subAttrs); // 次级属性 - let subAttrCe = newAttribute.calSubAttrCeAndReduce() * enemyCount; + let subAttrCe = newAttribute.calSubAttrCe() * enemyCount; if(ce * ratio > subAttrCe) { let mainAttrCe = ce * ratio - subAttrCe; newAttribute.setByWarJson(mainAttrs, mainAttrCe / enemyCe); - let attrArr = newAttribute.getReduceAttributesToString(); - let newCe = newAttribute.calCelAndReduce(); + let attrArr = newAttribute.getAttributesToString(); + let newCe = newAttribute.calCe(); return { attribute: attrArr, ce: newCe }; } else { newAttribute = new AttributeCal(); newAttribute.setByWarJson(mainAttrs, ce * ratio / enemyCe); - let attrArr = newAttribute.getReduceAttributesToString(); - let newCe = newAttribute.calCelAndReduce(); + let attrArr = newAttribute.getAttributesToString(); + let newCe = newAttribute.calCe(); return { attribute: attrArr, ce: newCe }; } -} - -/** - * @description 根据玩家数据获取到他的属性 - * @param ceAttr hero表的ceAttr - * @param globalCeAttr role表中的globalCeAttr - */ -export function getPlayerAttribute(lv: number, heroAttrs: CeAttrData[] = [], roleAttrs: CeAttrDataRole[] = []) { - let newAttribute = new AttributeCal(); - newAttribute.setLv(lv); - newAttribute.setByDbData(roleAttrs, heroAttrs); - let attribute = newAttribute.getReduceAttributesToString(); - let ce = newAttribute.calCelAndReduce(); - return { attribute, ce }; } \ No newline at end of file diff --git a/game-server/app/services/guildActivity/guildActivityService.ts b/game-server/app/services/guildActivity/guildActivityService.ts index a183d9e97..7fa0ffe6d 100644 --- a/game-server/app/services/guildActivity/guildActivityService.ts +++ b/game-server/app/services/guildActivity/guildActivityService.ts @@ -1,6 +1,5 @@ import { ServerlistModel } from "../../db/Serverlist"; import { RoleModel } from "../../db/Role"; -import { reduceCe } from "../../pubUtils/util"; import { GUILDACTIVITY } from "../../pubUtils/dicParam"; import { gameData, getGuildAuctionRewards, getCityActivityRewards } from "../../pubUtils/data"; import { getCurDay, nowSeconds, getTimeFun } from "../../pubUtils/timeUtil"; @@ -82,7 +81,7 @@ export async function setPreDayActiveData() { } } - await ServerRecordModel.updateData(server.id, { activePlayerCnt, activePlayerCe: reduceCe(activePlayerCe), activePlayers, activeGuilds }); + await ServerRecordModel.updateData(server.id, { activePlayerCnt, activePlayerCe, activePlayers, activeGuilds }); } return servers; } diff --git a/game-server/app/services/guildBossService.ts b/game-server/app/services/guildBossService.ts index 01d6bcf15..28f76c774 100644 --- a/game-server/app/services/guildBossService.ts +++ b/game-server/app/services/guildBossService.ts @@ -4,7 +4,7 @@ import { findIndex } from 'underscore'; import { sismemberAsync, smembersAsync, saddAsync, delAsync, getRoleOnlineInfo } from '../services/redisService'; import { pinus } from 'pinus'; import { STATUS } from '../consts/statusCode'; -import { reduceCe, resResult, shouldRefresh } from '../pubUtils/util'; +import { resResult, shouldRefresh } from '../pubUtils/util'; import { BattleRecordModel } from '../db/BattleRecord'; import { getArmyBossRank, gameData, getAuctionRewardByPoolId } from '../pubUtils/data'; import { sendMailToGuildByContent } from '../services/mailService'; @@ -197,8 +197,6 @@ export async function getBossHp(serverId: number, guildCode: string, dicBossBase activeCe += activePlayers[i].topLineupCe; } } - activeCe = reduceCe(activeCe); - console.log(`getBossHp activeCe ${activeCe}`); let B = activeCe/6/GUILDACTIVITY.GATEACTIVITY_ENEMYCE; console.log(`getBossHp B ${B}`); diff --git a/game-server/app/services/normalBattleService.ts b/game-server/app/services/normalBattleService.ts index e3936e72c..05ea3947a 100644 --- a/game-server/app/services/normalBattleService.ts +++ b/game-server/app/services/normalBattleService.ts @@ -4,7 +4,7 @@ import Role, { RoleModel, RoleType } from '../db/Role' import { getLvByExp, getExpByLv, gameData, getDicApByLv } from '../pubUtils/data'; import { updateUserInfo } from './redisService'; // import { switchOnFunc } from './funcSwitchService'; -import { FUNC_OPT_TYPE, TASK_TYPE, WAR_TYPE, STATUS, KING_EXP_RATIO_TYPE, ITEM_CHANGE_REASON, POP_UP_SHOP_CONDITION_TYPE } from '../consts'; +import { FUNC_OPT_TYPE, TASK_TYPE, WAR_TYPE, STATUS, KING_EXP_RATIO_TYPE, ITEM_CHANGE_REASON, POP_UP_SHOP_CONDITION_TYPE, HERO_SYSTEM_TYPE } from '../consts'; import { BackendSession, pinus } from 'pinus'; import { REDIS_KEY } from '../consts'; import { Rank } from './rankService'; @@ -16,6 +16,7 @@ import { LineupParam } from '../domain/rank'; import { WarStar } from '../domain/dbGeneral'; import { uniq } from 'underscore'; import { checkPopUpCondition } from './activity/popUpShopService'; +import { calculateCeWithRole } from './playerCeService'; export async function roleLevelup(type: KING_EXP_RATIO_TYPE, roleId: string, kingExp: number = 0, session: BackendSession) { const serverId = session.get('serverId'); @@ -47,6 +48,7 @@ export async function roleLevelup(type: KING_EXP_RATIO_TYPE, roleId: string, kin await checkTask(serverId, roleId, session.get('sid'), TASK_TYPE.ROLE_LV, { oldLv: lv, lv: newLv }); // 弹出礼包 await checkPopUpCondition(serverId, roleId, POP_UP_SHOP_CONDITION_TYPE.LV_TO, { oldLv: lv, newLv }) + await calculateCeWithRole(HERO_SYSTEM_TYPE.ROLE_LV, roleId, serverId, sid, { lv: newLv }); } let actordata: { lv: number, exp: number, getExp: number, mostExp: number }[] = []; diff --git a/game-server/app/services/playerCeService.ts b/game-server/app/services/playerCeService.ts index b7393e36e..2c821b042 100644 --- a/game-server/app/services/playerCeService.ts +++ b/game-server/app/services/playerCeService.ts @@ -5,7 +5,7 @@ import { pinus } from 'pinus'; import { STATUS } from '../consts/statusCode'; -import { resResult, reduceCe } from '../pubUtils/util'; +import { resResult } from '../pubUtils/util'; import { HeroModel, HeroType, HeroUpdate } from '../db/Hero'; import { RoleUpdate, RoleType, RoleModel } from '../db/Role'; @@ -19,6 +19,7 @@ import { PvpDefenseModel } from '../db/PvpDefense'; import { saveCeChangeLog } from '../pubUtils/logUtil'; import { JewelType } from '../db/Jewel'; import { SchoolModel } from '../db/School'; +import { AttributeCal } from '../domain/roleField/attribute'; interface Param { isInitRole?: boolean, @@ -46,7 +47,7 @@ export async function calculateCeWithHero(type: HERO_SYSTEM_TYPE, roleId: string return { heroes, curHero, curRole } } -export async function calculateWithRole(type: HERO_SYSTEM_TYPE, roleId: string, serverId: number, sid: string, roleUpdate: RoleUpdate, param: Param = {}) { +export async function calculateCeWithRole(type: HERO_SYSTEM_TYPE, roleId: string, serverId: number, sid: string, roleUpdate: RoleUpdate, param: Param = {}) { let { heroes, curRole } = await calculateCes(type, roleId, serverId, sid, new Map(), roleUpdate, {}, param); return { heroes, curRole }; } @@ -64,8 +65,10 @@ export async function calculateCes(type: HERO_SYSTEM_TYPE, roleId: string, serve calCe.setHeroStar(hid, job, quality, star, starStage, colorStar, colorStarStage); calCe.setJob(hid, job, jobStage); } + console.log('####### roleUpdate', param.isInitRole, roleUpdate) if(param.isInitRole) { - let { title, teraphs } = roleUpdate; + let { title, teraphs, lv } = roleUpdate; + calCe.setRoleLv(lv) calCe.setTitle(title); calCe.setTeraph(teraphs); } @@ -286,6 +289,12 @@ export async function calculateCes(type: HERO_SYSTEM_TYPE, roleId: string, serve } break; } + case HERO_SYSTEM_TYPE.ROLE_LV: // 31. 玩家等级 + { + let { lv } = roleUpdate; + calCe.setRoleLv(lv); + break; + } } let { heroCe, roleInc } = calCe.getCeInc(); // 计算战力,获得有变化的武将战力 let changeHids: number[] = []; @@ -346,7 +355,7 @@ async function updateRank(roleId: string, serverId: number, topLineupCe: number, // 最强阵容 let r = new Rank(REDIS_KEY.TOP_LINEUP_RANK, { serverId }); - await r.setRankWithRoleInfo(roleId, reduceCe(topLineupCe), 0, role); + await r.setRankWithRoleInfo(roleId, topLineupCe, 0, role); // 最强武将 for(let { hid, ce } of pushHeros) { @@ -359,7 +368,7 @@ async function updateRank(roleId: string, serverId: number, topLineupCe: number, // 总战力 let r3 = new Rank(REDIS_KEY.SUM_CE_RANK, { serverId }); - await r3.setRankWithRoleInfo(roleId, reduceCe(role.ce), 0, role); + await r3.setRankWithRoleInfo(roleId, role.ce, 0, role); // 更新最强五人阵容信息 let r5 = new Rank(REDIS_KEY.TOP_LINEUP_INFO, { serverId }); @@ -382,4 +391,16 @@ export async function getSumCe(roleId: string, num: number) { } } return ce; +} + +export async function getHeroesAttributes(roleId: string) { + let roleCe = await RoleCeModel.findByRoleId(roleId); + let attrByHid = new Map(); + for(let { hid, attrs } of roleCe.attributes||[]) { + let cal = new AttributeCal(); + cal.setLv(roleCe.roleLv); + cal.setByWarJson(attrs); + attrByHid.set(hid, cal); + } + return attrByHid; } \ No newline at end of file diff --git a/game-server/app/services/pvpService.ts b/game-server/app/services/pvpService.ts index e94976c74..4ab840d32 100644 --- a/game-server/app/services/pvpService.ts +++ b/game-server/app/services/pvpService.ts @@ -1,7 +1,7 @@ import { PvpDefenseModel, PvpDefenseType, pvpUpdateInter } from '../db/PvpDefense'; import { Defense, Attack, LineupCe, OppPlayer, HeroScore, HeroReward, OppPlayerReturn, AttackHero, DefenseHero } from '../domain/battleField/pvp'; -import { RoleType, CeAttrDataRole } from '../db/Role'; +import { RoleType } from '../db/Role'; import { PVP_HERO_POS, REDIS_KEY, PVP_CONST, COUNTER, TASK_TYPE, MAIL_TYPE, TA_EVENT } from '../consts'; import { dicPvpOpponent, DicPvpOpponent } from "../pubUtils/dictionary/DicPvpOpponent"; import { getRandSingleIndex, genCode, shouldRefresh, getChineseName, makeRobotId, robotIdComBack, getRandSingleEelm } from '../pubUtils/util'; @@ -11,7 +11,7 @@ import { PVP } from '../pubUtils/dicParam'; import { PVPConfigModel, PVPConfigType } from '../db/SystemConfig' import { nowSeconds, getTimeFun } from '../pubUtils/timeUtil'; import { HeroesRecord, PvpRecordPlayerInfo } from '../db/PvpRecord'; -import { HeroModel, CeAttrData, HeroType } from '../db/Hero'; +import { HeroModel, HeroType } from '../db/Hero'; import { AttributeCal } from '../domain/roleField/attribute'; import { PvpEnemies, PvpHeroInfo, PvpOtherHeroes } from '../domain/dbGeneral'; import { DicWarJson } from '../pubUtils/dictionary/DicWarJson'; @@ -27,6 +27,7 @@ import { sendMailByContent } from './mailService'; import { RoleRankInfo } from '../domain/rank'; import { reportTAEvent } from './sdkService'; import { getVipPvpChallengeMaxCnt } from './activity/monthlyTicketService'; +import { getHeroesAttributes } from './playerCeService'; /** * 返回对手三人信息 @@ -203,6 +204,7 @@ async function generPlayerOppHis(pvpdefense: PvpDefenseType, roleId: string, pos let heroes = new Array(); let otherHeroes = new Array(); // 阵容外的所有武将信息 let defCe = 0; + let attrByHid = await getHeroesAttributes(role.roleId); for (let dbHero of dbHeroes) { let h = defenseHeroes.find(cur => cur.actorId == dbHero.hid); // 阵容里是否有这个武将 let hs = heroScores.find(cur => cur.hid == dbHero.hid); // 这个武将是否有这个得分 @@ -213,7 +215,10 @@ async function generPlayerOppHis(pvpdefense: PvpDefenseType, roleId: string, pos let heroInfo = new PvpHeroInfo(); heroInfo.setHeroInfo(dbHero); // heroInfo.setOutIndex(h.order); - let { attribute, ce } = getPlayerAttribute(dbHero.lv, dbHero.attr, role.attr); + let attr = attrByHid.get(h.actorId); + if(!attr) continue; + let attribute = attr.getAttributesToString(); + let ce = attr.calCe(); heroInfo.setAttribute(attribute); let enemy = new PvpEnemies(warJson, heroInfo, hs ? hs.score : 0, ce); enemy.setOutIndex(h.order); @@ -372,37 +377,11 @@ export function getRobotAttribute(hid: number, posRatio: number, score: number) let newAttribute = new AttributeCal(); newAttribute.setLv(difficultRatio.enemyLv); newAttribute.setByMap(dicHero.baseAbilityArr, difficultRatio.value / 10000 * posRatio); - let attrArr = newAttribute.getReduceAttributesToString(); - let newCe = newAttribute.calCelAndReduce(); + let attrArr = newAttribute.getAttributesToString(); + let newCe = newAttribute.calCe(); return { attribute: attrArr, ce: newCe, lv: difficultRatio.enemyLv }; } -/** - * @description 根据玩家数据获取到他的属性 - * @param ceAttr hero表的ceAttr - * @param globalCeAttr role表中的globalCeAttr - */ -export function getPlayerAttribute(lv: number, heroAttrs: CeAttrData[] = [], roleAttrs: CeAttrDataRole[] = []) { - let newAttribute = new AttributeCal(); - newAttribute.setLv(lv); - newAttribute.setByDbData(roleAttrs, heroAttrs); - let attribute = newAttribute.getReduceAttributesToString(); - let ce = newAttribute.calCelAndReduce(); - return { attribute, ce }; -} - -/** - * @description 根据玩家数据获取到他的主属性 - * @param ceAttr - * @param globalCeAttr - */ -export function getPlayerMainAttribute(heroAttrs: CeAttrData[], roleAttrs: CeAttrDataRole[]) { - let newAttribute = new AttributeCal(); - newAttribute.setByDbData(roleAttrs, heroAttrs); - let mainAttributes = newAttribute.getReduceMainAttributes(); - return mainAttributes; -} - // 获取我方战报记录 export async function generMyRecInfo(pvpDefense: PvpDefenseType, role: RoleType, isSuccess: boolean, pos: number, myHeroes: pvpEndParamInter[]) { let { attack, defense, heroScores, winStreakNum, hisWinStreakNum = 0, score, hisScore } = pvpDefense; diff --git a/game-server/app/services/rankService.ts b/game-server/app/services/rankService.ts index ad52d186e..2dcf54bb9 100644 --- a/game-server/app/services/rankService.ts +++ b/game-server/app/services/rankService.ts @@ -243,13 +243,13 @@ export class Rank { if (!role) { role = await RoleModel.findByRoleId(roleId, ROLE_SELECT.RANK, true); } - let param = new RankParam(role, true); + let param = new RankParam(role); await this.setUserInfo(infoKey, { roleId }, param); } else if (infoKey == REDIS_KEY.GUILD_INFO) { if (!guild) { guild = await GuildModel.findByCode(guildCode, this.keyName.serverId, GUILD_SELECT.RANK) } - let param = new GuildRankParam(guild, true); + let param = new GuildRankParam(guild); await this.setUserInfo(infoKey, { guildCode }, param); } else if (infoKey == REDIS_KEY.TOP_LINEUP_INFO) { if (!role) { @@ -436,13 +436,13 @@ export class Rank { if (!role) { role = await RoleModel.findByRoleId(roleId, ROLE_SELECT.RANK, true); } - param = new RoleRankInfo(role, true); + param = new RoleRankInfo(role); param.setInfo(0, { roleId }, score, time); } else { const info = await redisClient().hgetAsync(this.infoKey, roleId); const userInfo = JSON.parse(info); - param = new RoleRankInfo(userInfo, false); + param = new RoleRankInfo(userInfo); param.setInfo(0, { roleId }, score, time); } @@ -462,12 +462,12 @@ export class Rank { if (!guild) { guild = await GuildModel.findByCode(guildCode, this.keyName.serverId, GUILD_SELECT.RANK); } - param = new GuildRankInfo(guild, true); + param = new GuildRankInfo(guild); param.setInfo(0, { guildCode }, score, time); } else { const info = await redisClient().hgetAsync(this.infoKey, guildCode); const guildInfo = JSON.parse(info); - param = new GuildRankInfo(guildInfo, false); + param = new GuildRankInfo(guildInfo); param.setInfo(0, { guildCode }, score, time); } @@ -487,12 +487,12 @@ export class Rank { if (!guild) { guild = await GuildModel.findByCode(guildCode, this.keyName.serverId, GUILD_SELECT.RANK); } - param = new GuildRankInfo(guild, true); + param = new GuildRankInfo(guild); param.setInfo2(0, { guildCode }, score, time, active); } else { const info = await redisClient().hgetAsync(this.infoKey, guildCode); const guildInfo = JSON.parse(info); - param = new GuildRankInfo(guildInfo, false); + param = new GuildRankInfo(guildInfo); param.setInfo2(0, { guildCode }, score, time, active); } @@ -512,13 +512,13 @@ export class Rank { if (!role) { role = await RoleModel.findByRoleId(roleId, ROLE_SELECT.RANK, true); } - param = new RoleRankInfo(role, true); + param = new RoleRankInfo(role); param.setInfo(0, { roleId, hid }, score, time); } else { const info = await redisClient().hgetAsync(this.infoKey, roleId); const userInfo = JSON.parse(info); - param = new RoleRankInfo(userInfo, false); + param = new RoleRankInfo(userInfo); param.setInfo(0, { roleId, hid }, score, time); } @@ -710,14 +710,14 @@ export class Rank { if (nowSeconds() - userInfo.updatedAt > 2 * 30 * 24 * 60 * 60) { continue; } - param = new RoleRankInfo(userInfo, false); + param = new RoleRankInfo(userInfo); param.setInfo(Math.floor(ii / 2) + 1, myId, scores[0], scores[1]); } else if (this.infoKey == REDIS_KEY.GUILD_INFO) { if(this.key == REDIS_KEY.GUILD_LV_RANK) { - param = new GuildRankInfo(userInfo, false); + param = new GuildRankInfo(userInfo); param.setInfo2(Math.floor(ii / 2) + 1, myId, scores[0], scores[1], scores[2]); } else { - param = new GuildRankInfo(userInfo, false); + param = new GuildRankInfo(userInfo); param.setInfo(Math.floor(ii / 2) + 1, myId, scores[0], scores[1]); } } @@ -759,14 +759,14 @@ export class Rank { if (nowSeconds() - userInfo.updatedAt > 2 * 30 * 24 * 60 * 60) { continue; } - param = new RoleRankInfo(userInfo, false); + param = new RoleRankInfo(userInfo); param.setInfo(Math.floor(ii / 2) + 1, myId, scores[0], scores[1]); } else if (this.infoKey == REDIS_KEY.GUILD_INFO) { if(this.key == REDIS_KEY.GUILD_LV_RANK) { - param = new GuildRankInfo(userInfo, false); + param = new GuildRankInfo(userInfo); param.setInfo2(Math.floor(ii / 2) + 1, myId, scores[0], scores[1], scores[2]); } else { - param = new GuildRankInfo(userInfo, false); + param = new GuildRankInfo(userInfo); param.setInfo(Math.floor(ii / 2) + 1, myId, scores[0], scores[1]); } } @@ -1083,7 +1083,7 @@ export async function getGeneralRank(role: RoleType & { rankReceived: number[] } let r = new Rank(redisKey, { serverId }, false, 1); let ranks = await r.getRankByRange(); // if (ranks.length > 0) { - let param = new GeneralRankParam(id, ranks[0] || new RoleRankInfo({}, false), general, received); + let param = new GeneralRankParam(id, ranks[0] || new RoleRankInfo({}), general, received); result.push({...param, general}); } } diff --git a/game-server/app/services/role/_calCe.ts b/game-server/app/services/role/_calCe.ts deleted file mode 100644 index 4c9c69ce1..000000000 --- a/game-server/app/services/role/_calCe.ts +++ /dev/null @@ -1,249 +0,0 @@ -import { ABI_STAGE, ABI_STAGE_TO_TYPE, ABI_TYPE, ABI_TYPE_MAIN, HERO_CE_RATIO, HERO_SYSTEM_TYPE, SEID_TYPE } from "../../consts"; -import { HeroModel, HeroUpdate, CeAttrData } from "../../db/Hero"; -import { CeAttrDataRole, RoleUpdate } from "../../db/Role"; -import { gameData, getHeroStarByQuality, getHeroWakeByQuality } from "../../pubUtils/data"; -import { DicRandomEffectPool } from "../../pubUtils/dictionary/DicRandomEffectPool"; -import { DicSe } from "../../pubUtils/dictionary/DicSe"; -import { deepCopy } from "../../pubUtils/util"; -import { AttributeCal } from "../../domain/roleField/attribute"; - -export class CalRoleCe { - private roleInfo: RoleUpdate; - private roleCeWithAttr: Map = new Map(); - - constructor(roleInfo?: RoleUpdate) { - this.roleInfo = roleInfo; - } - - public cal(type: HERO_SYSTEM_TYPE) { - switch (type) { - case HERO_SYSTEM_TYPE.INIT: - this.calTitleAbility(); - this.calTeraphMainAttr(); - break; - } - return this.getRoleAttr(); - } - - private calTitleAbility() { - let { title } = this.roleInfo; - - let dicTitle = gameData.title.get(title)||{ mainAttrValue: new Map(), assiAttrValue: new Map() }; - - for (let i = ABI_TYPE.ABI_HP; i < ABI_TYPE.ABI_MAX; i++) { - if (dicTitle.mainAttrValue.has(i)) { - let fixUp = dicTitle.mainAttrValue.get(i) || 0; - this.getSingleAttrObj(i).updateAttr({ inc: { fixUp } }); - } - if (dicTitle.assiAttrValue.has(i)) { - let fixUp = dicTitle.assiAttrValue.get(i) || 0; - this.getSingleAttrObj(i).updateAttr({ inc: { fixUp } }); - } - } - } - - private calTeraphMainAttr(id?: number) { - let { teraphs = [] } = this.roleInfo; - for(let teraph of teraphs) { - if(id == undefined || teraph.id == id) { - for(let [attrId, val] of teraph.attr) { - this.getSingleAttrObj(attrId).updateAttr({ inc: { fixUp: val } }); - } - } - } - } - - // 获取一个CeAttrData对象,没有就新建 - public getSingleAttrObj(attrId: ABI_TYPE) { - if(!this.roleCeWithAttr.has(attrId)) { - let calSingleAttr = new CeAttrDataRole(attrId); - this.roleCeWithAttr.set(attrId, calSingleAttr); - } - return this.roleCeWithAttr.get(attrId); - } - - private getRoleAttr() { - let attr: CeAttrDataRole[] = []; - this.roleCeWithAttr.forEach(value => { - if(value.ratioUp > 0 || value.fixUp > 0) { - attr.push(value); - } - }); - return attr; - } -} - -export class CalHeroCe { - private hid: number; - private heroInfo: HeroUpdate; - private heroCeWithAttr: Map = new Map(); - - constructor(hid: number, heroInfo?: HeroUpdate) { - this.hid = hid; - if(heroInfo) this.heroInfo = heroInfo; - } - - public async setHeroInfoByHid(roleId: string) { - let hero = await HeroModel.findByHidAndRole(this.hid, roleId); - this.heroInfo = hero; - } - - // 主要接口 - public cal(type: HERO_SYSTEM_TYPE) { - switch (type) { - case HERO_SYSTEM_TYPE.INIT: - case HERO_SYSTEM_TYPE.REBIRTH: - this.calBaseAbility(); - this.calSkinSeid(); - this.calJobAbility(); - break; - } - return this.getHeroAttr() - } - - // 计算基础属性 - private calBaseAbility() { - let { star, starStage, quality, colorStar, colorStarStage, lv, skinId } = this.heroInfo; - const dicHero = gameData.hero.get(skinId); - if(!dicHero) { - console.error(`not found hero: ${skinId}`); - return; - } - - for (let stage = ABI_STAGE.START + 1; stage <= ABI_STAGE.END; stage++) { - let attrId = ABI_STAGE_TO_TYPE.get(stage); - - const isWake = colorStar > 0; // 是否觉醒,只要激活了觉醒,彩星就会 > 1 - // console.log('*isUpstar', isUpStar, originStar, star, originColorStar, colorStar) - - const dicStar = isWake ? getHeroWakeByQuality(dicHero.jobClass, dicHero.quality, colorStarStage < stage? colorStar - 1: colorStar) : getHeroStarByQuality(dicHero.jobClass, quality, starStage < stage? star - 1: star); // 星级表 - - let heroAttr = dicHero.baseAbilityArr.get(attrId); // 武将表hp等 - let heroUpAttr = dicHero.baseAbilityUpArr.get(attrId); // 武将表hp_up等 - let starUp = 0; // 星级成长 - if (!!dicStar && !!dicStar.ceAttr) { - starUp = dicStar.ceAttr.get(stage); - } - let base = heroAttr + lv * (heroUpAttr + starUp); - this.getSingleAttrObj(attrId).updateAttr({ set: { base } }); - }; - } - - // 计算职业属性 - private calJobAbility() { - let { job, jobStage } = this.heroInfo; - - const dicJob = gameData.job.get(job); - for(let i = 1; i <= dicJob.maxStage; i++) { - if(jobStage >= i) { - let { id, attr } = dicJob.ceAttr.get(i); - this.getSingleAttrObj(id).updateAttr({ inc: { fixUp: attr } }); - } - } - } - - - // 计算皮肤属性 - private calSkinSeid() { - let { skinId, star: _star, colorStar: _colorStar } = this.heroInfo; - - let seidList = new Map(); // type => seid - let dicHero = gameData.hero.get(skinId); - let { starSeidArr, colorStarSeidArr } = gameData.heroSkill.get(dicHero.skill); - for (let { star, value, type } of starSeidArr) { - if (_star >= star) { - seidList.set(type, value); - } - } - for (let { star, value, type } of colorStarSeidArr) { - if (_colorStar >= star) { - seidList.set(type, value); - } - } - let list: number[] = []; - for(let [_type, value] of seidList) list.push(value); - addSeidEffect.bind(this, list); - } - - public getHeroAttr() { - let attr: CeAttrData[] = []; - this.heroCeWithAttr.forEach(value => { - if(value.base > 0 || value.equipUp > 0 || value.fixUp > 0 || value.ratioUp > 0) { - attr.push(value); - } - }); - return attr; - } - - // 获取一个CeAttrData对象,没有就新建 - public getSingleAttrObj(attrId: ABI_TYPE) { - if(!this.heroCeWithAttr.has(attrId)) { - let calSingleAttr = new CeAttrData(attrId); - this.heroCeWithAttr.set(attrId, calSingleAttr); - } - return this.heroCeWithAttr.get(attrId); - } - - public getCalculatedCe(roleAttr: CeAttrDataRole[]) { - let attrCal = new AttributeCal(); - attrCal.setLv(this.heroInfo.lv); - attrCal.setByDbData(roleAttr, this.getHeroAttr()); - return attrCal.calCe(); - } -} - -// 添加技能增加的被动属性 -function addSeidEffect(this: CalRoleCe|CalHeroCe, seidList: number[]) { - // console.log('******addSeidEffect',this, seidList) - - // console.log('addSeidList', addSeidList.join()) - // console.log('removeSeidList', removeSeidList.join()) - let effectList: DicSe[] = []; // any: dic_zyz_se表内容 - - for (let ii = 0; ii < seidList.length; ii += 2) { - let seid = seidList[ii]; - let rand = seidList[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) { // 加值 - this.getSingleAttrObj(ability).updateAttr({ inc: { fixUp: value } }); - } else if (type == SEID_TYPE.TYPE103) { // 主属性加百分比 - if(ABI_TYPE_MAIN.includes(ability)) { - this.getSingleAttrObj(ability).updateAttr({ inc: {ratioUp: value / 1000} }); - } - } else if (type == SEID_TYPE.TYPE104) { // 次级属性加百分比 - if(!ABI_TYPE_MAIN.includes(ability)) { - this.getSingleAttrObj(ability).updateAttr({ inc: { fixUp: value * 100 * HERO_CE_RATIO } }); - } - } - - } - -} - -// 获取dic_zyz_se内容 -function addSeid(effectList: (DicSe | DicRandomEffectPool)[], seidId: number, rand: number, seidValue: 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); -} \ No newline at end of file diff --git a/game-server/app/services/role/calCe.ts b/game-server/app/services/role/calCe.ts index e6ffb73ab..66fc87053 100644 --- a/game-server/app/services/role/calCe.ts +++ b/game-server/app/services/role/calCe.ts @@ -2,7 +2,7 @@ import { ABI_STAGE, ABI_STAGE_TO_TYPE, ABI_TYPE_MAIN, LINEUP_NUM, SEID_TYPE, TAL import { Connect, EPlace, HeroSkin, HeroType, HeroUpdate, Stone, Talent } from "../../db/Hero"; import { JewelType } from "../../db/Jewel"; import { RoleUpdate, Teraph } from "../../db/Role"; -import { AttrCell, EquipAttr, HeroAttr, RoleCeType, SchoolAttr } from "../../db/RoleCe"; +import { AttrCell, Attribute, EquipAttr, HeroAttr, RoleCeType, SchoolAttr } from "../../db/RoleCe"; import { TopHero } from "../../domain/dbGeneral"; import { AttributeCal } from "../../domain/roleField/attribute"; import { gameData, getEquipQualityIdByEquipIdAndPoint, getEquipStarAttrByStage, getEquipStrenthenAttr, getEquipSuitByHero, getFriendShipById, getHeroStarByQuality, getHeroWakeByQuality, getJewelConditionByLvAndSeId, getJobByGradeAndClass, getSchoolRateByStar, getScollByStar, getTeraph } from "../../pubUtils/data"; @@ -14,6 +14,7 @@ export class CalCe { originCes: Map = new Map(); // hid => ce resultCes: Map = new Map(); // hid => ce data: CalCeData; + attrsByHid: Map = new Map(); constructor(roleId: string) { this.roleId = roleId; @@ -25,35 +26,43 @@ export class CalCe { } public getRoleCeTable() { - return this.data.getRoleCeTable(this.roleId); + let attributes: Attribute[] = []; + for(let [hid, attrs] of this.attrsByHid) { + attributes.push({ hid, attrs }) + } + return this.data.getRoleCeTable(this.roleId, attributes); } public calHeroCe() { - let ces = new Map(); // hid => [{attrId, val}] + let attrs = new Map(); // hid => [{attrId, val}] for(let [hid, keys] of this.data.heroAttrsByHid) { let lv = this.data.heroLv.get(hid)||1; for(let key of keys) { let { attrId, mainBase = 0, subBase = 0, job = 0, starUp = 0, connect = 0, favour = 0, talent = 0, equipQuality = 0, equipStrength = 0, equipStar = 0, equipSuit = 0, jewel = 0, stone = 0 } = this.data.heroAttrs.get(key); let { school = 0, teraph = 0, title = 0, scroll = 0, skin = 0 } = this.data.getGlobalAttrById(attrId); - let val = 0; - if(ABI_TYPE_MAIN.indexOf(attrId)) { - // {[hp1 + lv * hp2 + hp3 * ( 1 + hp4 )] * (1 + hp5 ) + [( hp6 + hp7 ) * ( 1 + hp8 )] } * ( 1 + hp9 ) + hp10 + hp11 + let val = 0, str = ''; + if(ABI_TYPE_MAIN.indexOf(attrId) != -1) { + // {[hp1 + lv * hp2 + hp3 * ( 1 + hp4 )] * (1 + hp5 ) + [( hp6 + hp7 ) * ( 1 + hp8 )] } * ( 1 + hp9 ) + hp10 + hp11 val = ((mainBase + job + lv * starUp + connect * ( 1 + favour )) * ( 1 + school + talent ) + (( equipQuality + equipStrength ) * ( 1 + ( equipStar + equipSuit ))) ) * ( 1 + jewel ) + stone + teraph + title + scroll + skin; + str += `{[${mainBase}+${job}+${lv}*${starUp}+${connect}*(1+${favour})]*(1+${school}+${talent})+[(${equipQuality}+${equipStrength})*(1+${equipStar}+${equipSuit})]}*(1+${jewel})+${stone}+${teraph}+${title}+${scroll}+${skin}`; } else { - // attr1 + attr2 + attr3 + attr4 + attr5 + attr6 + attr7 + attr8 + attr9 + // attr1 + attr2 + attr3 + attr4 + attr5 + attr6 + attr7 + attr8 + attr9 val = subBase + job + talent + teraph + school + title + jewel + skin + equipStar; + str += `${subBase}+${job}+${talent}+${teraph}+${school}+${title}+${jewel}+${skin}+${equipStar}`; } - if(!ces.has(hid)) ces.set(hid, []); - ces.get(hid).push({ id: attrId, val }); + if(!attrs.has(hid)) attrs.set(hid, []); + attrs.get(hid).push({ id: attrId, val, str }); } } let result = new Map(); - for(let [hid, arr] of ces) { + for(let [hid, arr] of attrs) { let obj = new AttributeCal(); + obj.setLv(this.data.roleLv); obj.setByWarJson(arr); let ce = obj.calCe(); this.resultCes.set(hid, ce); result.set(hid, ce); + this.attrsByHid.set(hid, arr); } return result; } @@ -102,6 +111,10 @@ export class CalCe { return { topLineup, topLineupCe }; } + // 玩家等级 + public setRoleLv(lv: number) { + this.data.roleLv = lv; + } // 武将基础&成长 public setHeroBase(hid: number, skinId: number) { @@ -475,6 +488,7 @@ export class CalCe { } class CalCeData { + roleLv: number = 1; // 玩家等级 // 全局 globalAttrs: Map = new Map(); // attrId => GlobalAttr // 武将 @@ -549,7 +563,7 @@ class CalCeData { } public getHeroAttrsByHid(hid: number) { - let keys = this.heroAttrsByHid.get(hid); + let keys = this.heroAttrsByHid.get(hid)||[]; return keys.map(key => this.heroAttrs.get(key)); } @@ -573,7 +587,7 @@ class CalCeData { } public clearHeroAttrByHid(hid: number, field: string) { - let heroAttrs = this.getHeroAttrsByHid(hid); + let heroAttrs = this.getHeroAttrsByHid(hid)||[]; for(let heroAttr of heroAttrs) { heroAttr[field] = 0; } @@ -656,7 +670,7 @@ class CalCeData { } public clearSchoolAttr(hid: number) { - let schoolAttrs = this.getSchoolAttrsByHid(hid); + let schoolAttrs = this.getSchoolAttrsByHid(hid)||[]; for(let schoolAttr of schoolAttrs) { schoolAttr.ce = 0; this.calSchoolAttrsToGlobal(schoolAttr.attrId); @@ -715,7 +729,7 @@ class CalCeData { this.heroObjectId.set(hero.hid, hero._id); } - public getRoleCeTable(roleId: string) { + public getRoleCeTable(roleId: string, attributes: Attribute[]) { let globalAttrs: AttrCell[] = []; for(let [_, globalAttr] of this.globalAttrs) { globalAttrs.push(globalAttr.getGlobalAttr()); @@ -751,7 +765,7 @@ class CalCeData { schoolAttrs.push({ hid, attrId, value: ce }); } return { - roleId, globalAttrs, heroAttrs, equipAttrs, schoolAttrs + roleLv: this.roleLv, roleId, globalAttrs, heroAttrs, equipAttrs, schoolAttrs, attributes } } } diff --git a/game-server/app/services/role/createHero.ts b/game-server/app/services/role/createHero.ts index 83b651f04..2a655bf70 100644 --- a/game-server/app/services/role/createHero.ts +++ b/game-server/app/services/role/createHero.ts @@ -3,14 +3,12 @@ import { SkinModel } from "../../db/Skin"; import { HeroModel, HeroSkin, HeroType, HeroUpdate } from "../../db/Hero"; import { SkinUpdate } from "../../db/Skin"; import { nowSeconds } from "../../pubUtils/timeUtil"; -import { getRandSingleEelm, reduceCe, resResult } from "../../pubUtils/util"; -import { CreateHeroParam, HeroParam, HeroShowParam } from "../../domain/roleField/hero"; +import { resResult } from "../../pubUtils/util"; +import { CreateHeroParam, HeroShowParam } from "../../domain/roleField/hero"; import { pinus } from "pinus"; -import { Rank } from "../rankService"; -import { checkTaskInCreateHero } from "../task/taskService"; import { ItemInter, RewardInter } from "../../pubUtils/interface"; import { transPiece } from "./util"; -import { addItems, combineFigureInfo, unlockFigure, } from "./rewardService"; +import { addItems, unlockFigure, } from "./rewardService"; import { CounterModel } from "../../db/Counter"; import { calculateCes } from "../playerCeService"; import { RoleUpdate } from "../../db/Role"; @@ -63,7 +61,7 @@ import { RoleUpdate } from "../../db/Role"; if(initRoleInfos) { roleUpdata = { ...initRoleInfos, ...roleUpdata } } - let { heroes } = await calculateCes(HERO_SYSTEM_TYPE.INIT, roleId, serverId, sid, heroInfos, roleUpdata, { heroNum: incHeroNum }); + let { heroes } = await calculateCes(HERO_SYSTEM_TYPE.INIT, roleId, serverId, sid, heroInfos, roleUpdata, { heroNum: incHeroNum }, { isInitRole: !!initRoleInfos }); for(let hero of heroes) { showHeroes.push(new HeroShowParam(hero)); resultHeroes.push(hero); diff --git a/game-server/app/services/role/rewardService.ts b/game-server/app/services/role/rewardService.ts index eef4db82c..73f6761b1 100644 --- a/game-server/app/services/role/rewardService.ts +++ b/game-server/app/services/role/rewardService.ts @@ -24,7 +24,7 @@ import { JewelModel, JewelType, jewelUpdate, RandSe } from '../../db/Jewel'; import { updateEplaces } from '../equipService'; import { combineItems, getCoinEventProperties, getGoldEventProperties, sortItems } from './util'; import { nowSeconds } from '../../pubUtils/timeUtil'; -import { calculateCeWithHero, calculateWithRole } from '../playerCeService'; +import { calculateCeWithHero, calculateCeWithRole } from '../playerCeService'; @@ -358,7 +358,7 @@ export async function addSkin(roleId: string, roleName: string, sid: string, ski if(skin.hid && !hero) hero = await HeroModel.findByHidAndRole(skin.hid, roleId); let condition = { type: FIGURE_UNLOCK_CONDITION.GET_SKIN, paramSkinId: skinId }; await unlockFigure(sid, roleId, [condition]); // 解锁头像 - await calculateWithRole(HERO_SYSTEM_TYPE.ADD_SKIN, roleId, hero.serverId, sid, {}, { skinId }); // 全局加成 + await calculateCeWithRole(HERO_SYSTEM_TYPE.ADD_SKIN, roleId, hero.serverId, sid, {}, { skinId }); // 全局加成 if (hero) { // 有武将的,将皮肤链接到武将上 let curSkin = hero.skins.find(cur => cur.id == skinId); diff --git a/game-server/app/services/task/taskObj.ts b/game-server/app/services/task/taskObj.ts index 4790e89d9..ea4346ccd 100644 --- a/game-server/app/services/task/taskObj.ts +++ b/game-server/app/services/task/taskObj.ts @@ -22,8 +22,7 @@ import { getZeroPoint } from "../../pubUtils/timeUtil"; import { resResult } from "../../pubUtils/util"; import { getActivities, getActivitiesByType, getActivityByServerId } from "../activity/activityService"; import { getRoleCreateTime, getRoleOnlineInfo, getServerCreateTime } from "../redisService"; -import { getEquipById, getJewelByEquip } from "../equipService"; -import { isRandSeUnLock } from "../../pubUtils/playerCe"; +import { getEquipById, getJewelByEquip, isRandSeUnLock } from "../equipService"; export class CheckTask { serverId: number; // 区id diff --git a/gm-server/app/service/users.ts b/gm-server/app/service/users.ts index 92c8b6635..93cfb27d2 100644 --- a/gm-server/app/service/users.ts +++ b/gm-server/app/service/users.ts @@ -306,7 +306,7 @@ export default class GMUsers extends Service { let list = heroes.map(cur => { let cal = new AttributeCal(); cal.setByDbData(roleMap.get(cur.roleId), cur.attr); - return {...cur, calculatedAttr: cal.getReduceAttributesToArr(), env: ctx.app.config.realEnv} + return {...cur, calculatedAttr: cal.getAttributesToArr(), env: ctx.app.config.realEnv} }) return ctx.service.utils.resResult(STATUS.SUCCESS, { list, total }) diff --git a/shared/consts/constModules/heroConst.ts b/shared/consts/constModules/heroConst.ts index c1ff1c2b7..8ba9a7b40 100644 --- a/shared/consts/constModules/heroConst.ts +++ b/shared/consts/constModules/heroConst.ts @@ -31,6 +31,7 @@ export enum HERO_SYSTEM_TYPE { JEWEL_QUENCH = 28, // 天晶石淬炼 REBIRTH = 29, // 武将重生 TALENT = 30, // 天赋 + ROLE_LV = 31, // 玩家等级 }; // 武将上限 @@ -47,10 +48,8 @@ export const JOB_TYPE = { MAGIC: 2 } -// 武将战力放大系数 -export const HERO_CE_RATIO = 100; // 次级属性放大系数 -export const HERO_SUB_ATTR_RATIO = 1000 * 100; +export const HERO_SUB_ATTR_RATIO = 1000; export const HERO_INITIAL_QUALITY = { BLUE: 1, diff --git a/shared/consts/constModules/selectConst.ts b/shared/consts/constModules/selectConst.ts index 888077c9d..00b11c993 100644 --- a/shared/consts/constModules/selectConst.ts +++ b/shared/consts/constModules/selectConst.ts @@ -14,14 +14,14 @@ export enum ROLE_SELECT { COM_BATTLE = 'lv head frame spine heads frames spines topLineupCe', GET_HEADS = 'heads head frames frame spines spine', // 排行榜基础数据 - RANK = 'roleId roleName lv vLv head frame spine heads frames spines title guildName ce isReducedCe topLineup towerLv towerUpTime topLineupCe heroNum updatedAt heroNumUpdatedAt dungeonWarId dungeonUpdatedAt dungeonHeroes mainWarId mainUpdatedAt mainEliteWarId mainEliteUpdatedAt showLineup hasGuild', + RANK = 'roleId roleName lv vLv head frame spine heads frames spines title guildName ce topLineup towerLv towerUpTime topLineupCe heroNum updatedAt heroNumUpdatedAt dungeonWarId dungeonUpdatedAt dungeonHeroes mainWarId mainUpdatedAt mainEliteWarId mainEliteUpdatedAt showLineup hasGuild', }; export enum HERO_SELECT { ENTRY = '-_id -attr', - HERO_DETAIL = 'roleId roleName hid hName ce isReducedCe lv star colorStar quality job skins attr ePlace skinId', + HERO_DETAIL = 'roleId roleName hid hName ce lv star colorStar quality job skins attr ePlace skinId', // 排行榜中lineup字段 - RANK_LINEUP = 'seqId roleId hid star colorStar lv quality job ce isReducedCe updatedAt skinId' + RANK_LINEUP = 'seqId roleId hid star colorStar lv quality job ce updatedAt skinId' } export enum EQUIP_SELECT { diff --git a/shared/db/Guild.ts b/shared/db/Guild.ts index 740eb259f..fd469e018 100644 --- a/shared/db/Guild.ts +++ b/shared/db/Guild.ts @@ -3,7 +3,6 @@ import { index, getModelForClass, prop, DocumentType, Ref, mongoose } from '@typ import Role, { RoleType } from './Role'; import { GUILD_STRUCTURE, GUILD_STATUS, GUILD_PER_PAGE, GUILD_SELECT, REDIS_KEY, SHOP_REFRESH_TYPE } from '../consts'; import { getZeroPoint, getZeroPointD, nowSeconds } from '../pubUtils/timeUtil'; -import { reduceCe } from '../pubUtils/util'; import { gameData } from '../pubUtils/data'; import { SearchGuildParam } from '../domain/backEndField/search'; @@ -77,12 +76,9 @@ export default class Guild extends BaseModel { @prop({ required: true, default: new Date(), select: false }) refTimeDaily: Date; - @prop({ required: true, default: 0, get: (val:number) => reduceCe(val), set: (val: number) => val }) + @prop({ required: true, default: 0 }) guildCe: number; // 总战力 - @prop({ required: false, set: (val: boolean) => val, get: () => true }) - isReducedCe: boolean; // 如果战力没有缩过就会返回false,缩过了就会返回true - @prop({ required: true, type: String, default: [], select: false }) members: string[]; // 军团成员的roleId,用于增加战力的时候加入总战力 diff --git a/shared/db/Hero.ts b/shared/db/Hero.ts index 825eb8687..a2c8aaef7 100644 --- a/shared/db/Hero.ts +++ b/shared/db/Hero.ts @@ -1,56 +1,12 @@ import BaseModel from './BaseModel'; import { index, getModelForClass, prop, Ref, mongoose, DocumentType } from '@typegoose/typegoose'; // import Equip, { } from './Equip'; -import { CounterModel } from './Counter'; -import { COUNTER, DEFAULT_HERO_LV, HERO_CE_RATIO } from '../consts'; -import { reduceCe } from '../pubUtils/util'; +import { DEFAULT_HERO_LV } from '../consts'; import Skin, { SkinUpdate } from './Skin'; import { SearchHeroParam } from '../domain/backEndField/search'; import { Reward } from '../domain/battleField/pvp'; import { gameData, getHeroExpByLv, getHeroInitTalent } from '../pubUtils/data'; -type CeAttrUpdate = Partial; -export class CeAttrData { - @prop({ required: true }) - id: number = 0; - @prop({ required: true }) - base: number = 0; - @prop({ required: true }) - ratioUp: number = 0; - @prop({ required: true }) - fixUp: number = 0; - @prop({ required: true }) - equipUp: number = 0; - - constructor(id: number) { - this.id = id; - } - - public copyFromHero(data: CeAttrData) { - this.base = data.base; - this.ratioUp = data.ratioUp; - this.fixUp = data.fixUp; - this.equipUp = data.equipUp; - } - - public updateAttr(update: { inc?: CeAttrUpdate, set?: CeAttrUpdate }) { - if(update.inc) { - let { base, equipUp, fixUp, ratioUp } = update.inc; - if(base != undefined) this.base += base * HERO_CE_RATIO; - if(equipUp != undefined) this.equipUp += equipUp * HERO_CE_RATIO; - if(fixUp != undefined) this.fixUp += fixUp * HERO_CE_RATIO; - if(ratioUp != undefined) this.ratioUp += ratioUp; - } - if(update.set) { - let { base, equipUp, fixUp, ratioUp } = update.set; - if(base != undefined) this.base = base * HERO_CE_RATIO; - if(equipUp != undefined) this.equipUp = equipUp * HERO_CE_RATIO; - if(fixUp != undefined) this.fixUp = fixUp * HERO_CE_RATIO; - if(ratioUp != undefined) this.ratioUp = ratioUp; - } - } -} - /** * 英雄表 */ @@ -162,12 +118,8 @@ export default class Hero extends BaseModel { exp: number; // 经验值 @prop({ required: true, default: 1 }) lv: number; // 武将等级 - @prop({ required: true, default: 0, set: (val: number) => val, get: (val: number) => reduceCe(val) }) + @prop({ required: true, default: 0 }) ce: number; // 武将战力 - @prop({ required: false, set: (val: boolean) => val, get: () => true }) - isReducedCe: boolean; // 如果战力没有缩过就会返回false,缩过了就会返回true - @prop({ required: true, type: CeAttrData, default: [], _id: false }) - attr: CeAttrData[]; // 影响战力的属性 @prop({ required: true, default: 1 }) star: number; // 星级 diff --git a/shared/db/Role.ts b/shared/db/Role.ts index 02b515dd5..01f12b89f 100644 --- a/shared/db/Role.ts +++ b/shared/db/Role.ts @@ -1,42 +1,14 @@ -import { ROLE_TERAPH, ROLE_SELECT, ABI_TYPE, HERO_CE_RATIO, BLOCK_TYPE } from './../consts'; +import { ROLE_TERAPH, ROLE_SELECT, ABI_TYPE, BLOCK_TYPE } from './../consts'; import BaseModel from './BaseModel'; import { index, getModelForClass, prop, DocumentType, Ref, mongoose } from '@typegoose/typegoose'; import User from './User'; -import { shouldRefresh, reduceCe } from '../pubUtils/util'; +import { shouldRefresh } from '../pubUtils/util'; import { nowSeconds, getTimeFunD } from '../pubUtils/timeUtil'; import { Figure } from '../domain/dbGeneral'; import * as dicParam from '../pubUtils/dicParam'; import Hero from './Hero'; import { SearchRoleParam } from '../domain/backEndField/search'; -type CeAttrUpdate = Partial; -// role表属性格式 -export class CeAttrDataRole { - @prop({ required: true }) - id: number = 0; - @prop({ required: true }) - ratioUp: number = 0; - @prop({ required: true }) - fixUp: number = 0; - - constructor(id: number) { - this.id = id; - } - - public updateAttr(update: { inc?: CeAttrUpdate, set?: CeAttrUpdate }) { - if(update.inc) { - let { fixUp, ratioUp } = update.inc; - if(fixUp != undefined) this.fixUp += fixUp * HERO_CE_RATIO; - if(ratioUp != undefined) this.ratioUp += ratioUp; - } - if(update.set) { - let { fixUp, ratioUp } = update.set; - if(fixUp != undefined) this.fixUp = fixUp * HERO_CE_RATIO; - if(ratioUp != undefined) this.ratioUp = ratioUp; - } - } -} - export class TopHero { @prop({ required: true }) hid: number; // 武将id @@ -185,16 +157,12 @@ export default class Role extends BaseModel { exp: number; // 经验值 @prop({ required: true, default: 1 }) lv: number; // 主公等级 - @prop({ required: true, default: 0, set: (val: number) => val, get: (val: number) => reduceCe(val) }) + @prop({ required: true, default: 0 }) ce: number; // 总战力 - @prop({ required: true, type: CeAttrDataRole, default: [], _id: false }) - attr: CeAttrDataRole[]; // 总战力 - @prop({ required: true, default: 0, set: (val: number) => val, get: (val: number) => reduceCe(val) }) + @prop({ required: true, default: 0 }) topLineupCe: number; // 最强x人战力 @prop({ required: true, type: TopHero, default: [], _id: false }) topLineup: Array; // 总战力 - @prop({ required: false, set: (val: boolean) => val, get: () => true }) - isReducedCe: boolean; // 如果战力没有缩过就会返回false,缩过了就会返回true @prop({ required: true, default: 100 }) gold: number; // 总金币 diff --git a/shared/db/RoleCe.ts b/shared/db/RoleCe.ts index 59f1b627d..f604d8a9f 100644 --- a/shared/db/RoleCe.ts +++ b/shared/db/RoleCe.ts @@ -45,7 +45,7 @@ export class SchoolAttr { } // 名将谱加成 -class ScrollAttr { +export class ScrollAttr { @prop({ required: true }) hid: number; // 武将id @prop({ required: true }) @@ -54,6 +54,24 @@ class ScrollAttr { value: number; // 百家学宫有多个武将,单独拎出来方便计算,计算之后结果存到globaAttrs的global1 } + +// 属性结果 +export class SingleAttribute { + @prop({ required: true }) + id: number; // 属性id + @prop({ required: true }) + val: number; // 值 + @prop({ required: true }) + str: string; // 公式 +} + +export class Attribute { + @prop({ required: true }) + hid: number; + @prop({ required: true, type: SingleAttribute, _id: false }) + attrs: SingleAttribute[]; // 属性id +} + /** * 属性表 */ @@ -66,6 +84,9 @@ export default class RoleCe extends BaseModel { @prop({ required: true }) roleId: string; // 角色 id + @prop({ required: true }) + roleLv: number; // 玩家等级 + @prop({ required: true, type: AttrCell, _id: false }) globalAttrs: AttrCell[] @@ -81,6 +102,9 @@ export default class RoleCe extends BaseModel { @prop({ required: true, type: ScrollAttr, _id: false }) scrollAttrs: ScrollAttr[]; + @prop({ required: true, type: Attribute, _id: false }) + attributes: Attribute[]; + public static async findByRoleId(roleId: string) { let result: RoleCeType = await RoleCeModel.findOne({ roleId }).lean(); return result; diff --git a/shared/db/User.ts b/shared/db/User.ts index 2677646f2..33fd4d0d1 100644 --- a/shared/db/User.ts +++ b/shared/db/User.ts @@ -65,10 +65,15 @@ export default class User extends BaseModel { guestTime: number; // 游客体验时间 // 防沉迷相关 - @prop({ required: false, default: false }) + @prop({ required: false, default: true }) hasAuthenticated: boolean; // 是否是已认证 - @prop({ required: false }) + @prop({ required: false, default: '1990-01-01' }) birthday: string; // 生日年月 + // 暂时不使用内部防沉迷 + // @prop({ required: false, default: false }) + // hasAuthenticated: boolean; // 是否是已认证 + // @prop({ required: false }) + // birthday: string; // 生日年月 @prop({ required: false }) pi: string; // 已通过实名认证用户唯一标识 @prop({ required: false, default: 0 }) diff --git a/shared/domain/battleField/dungeon.ts b/shared/domain/battleField/dungeon.ts index f63f9c656..e18955dd7 100644 --- a/shared/domain/battleField/dungeon.ts +++ b/shared/domain/battleField/dungeon.ts @@ -4,7 +4,7 @@ import { DungeonFirstType } from '../../db/DungeonFirst'; class DungeonUserInfo extends RankParam { roleId: string; constructor(roleId: string, userInfo: RankParam) { - super(userInfo, false); + super(userInfo); this.roleId = roleId; } } diff --git a/shared/domain/rank.ts b/shared/domain/rank.ts index 852b0012f..4a95ce2af 100644 --- a/shared/domain/rank.ts +++ b/shared/domain/rank.ts @@ -1,7 +1,6 @@ import { EXTERIOR } from "../pubUtils/dicParam"; import { WoodenHorse } from "./battleField/guildActivity"; import { RoleUpdate, RoleType } from "../db/Role"; -import { reduceCe } from "../pubUtils/util"; import { GuildUpdateParam } from "../db/Guild"; import { HeroUpdate, } from "../db/Hero"; import { getSeconds } from "../pubUtils/timeUtil"; @@ -38,7 +37,7 @@ export class RankParam { @prop({ required: true }) updatedAt?: number = 0; - constructor(role: RoleUpdate|RankParam, fromDb: boolean) { + constructor(role: RoleUpdate|RankParam) { if(role.roleName) this.roleName = role.roleName; if(role.lv) this.lv = role.lv; if(role.head) this.head = role.head; @@ -46,13 +45,7 @@ export class RankParam { if(role.spine) this.spine = role.spine; if(role.title) this.title = role.title; if(role.guildName) this.guildName = role.guildName||""; - if(role.ce) { - if(fromDb && !(role).isReducedCe) { - this.ce = reduceCe(role.ce); - } else { - this.ce = role.ce; - } - } + if(role.ce) this.ce = role.ce; if(role.updatedAt) { if(typeof role.updatedAt == 'number') { this.updatedAt = role.updatedAt; @@ -178,27 +171,14 @@ export class GuildRankParam { @prop({ required: true }) guildCe: number; - constructor(guild: GuildUpdateParam, fromDb: boolean) { + constructor(guild: GuildUpdateParam) { this.icon = guild.icon; this.name = guild.name; this.lv = guild.lv; let leader = guild.leader; let _leader = new GuildLeader(leader); this.leader = _leader; - // console.log('*****', guild.isReducedCe, guild.guildCe, reduceCe(guild.guildCe)) - if(guild.isReducedCe) { - this.guildCe = guild.guildCe; - } else { - this.guildCe = reduceCe(guild.guildCe); - } - - if(fromDb && !(guild).isReducedCe) { - this.guildCe = reduceCe(guild.guildCe); - } else { - this.guildCe = guild.guildCe; - } - - + this.guildCe = guild.guildCe; this.memberCnt = guild.memberCnt; } } diff --git a/shared/domain/roleField/attribute.ts b/shared/domain/roleField/attribute.ts index f7aa55022..9f7dd91bb 100644 --- a/shared/domain/roleField/attribute.ts +++ b/shared/domain/roleField/attribute.ts @@ -1,8 +1,6 @@ -import { HERO_CE_RATIO, getAtrrNameById, ABI_TYPE_MAIN } from '../../consts'; -import { CeAttrDataRole } from '../../db/Role'; -import { CeAttrData } from '../../db/Hero'; +import { getAtrrNameById, ABI_TYPE_MAIN } from '../../consts'; import { gameData } from '../../pubUtils/data'; -import { decodeArrayListStr, reduceCe } from '../../pubUtils/util'; +import { decodeArrayListStr } from '../../pubUtils/util'; import { ATTRIBUTE } from '../../pubUtils/dicParam'; export class AttributeCal { @@ -14,34 +12,12 @@ export class AttributeCal { this.lv = lv; } - public setByDbData(roleAttrs: CeAttrDataRole[], heroAttrs: CeAttrData[]) { - for(let { id, fixUp: roleFix, ratioUp: roleRatio } of roleAttrs) { - let heroAttr = heroAttrs.find(heroAttr => heroAttr.id == id); - if(heroAttr) { - let { fixUp: heroFix, base: heroBase, ratioUp: heroRatio, equipUp: heroEquip } = heroAttr; - let value = this.calAttrValue(roleFix, roleRatio, heroBase, heroFix, heroRatio, heroEquip); - this.attrs.set(id, value); - } else { - let value = this.calAttrValue(roleFix, roleRatio, 0, 0, 0, 0); - this.attrs.set(id, value); - } - } - - for(let { id, base: heroBase, fixUp: heroFix, ratioUp: heroRatio, equipUp: heroEquip } of heroAttrs) { - let roleAttr = roleAttrs.find(roleAttr => roleAttr.id == id); - if(!roleAttr) { - let value = this.calAttrValue(0, 0, heroBase, heroFix, heroRatio, heroEquip); - this.attrs.set(id, value); - } - } - } - public setByWarJson(attributes: {id: number, val: number}[], ratio: number = 1) { for(let {id, val} of attributes) { if(ABI_TYPE_MAIN.includes(id)) { - this.attrs.set(id, Math.floor(val * ratio * HERO_CE_RATIO * HERO_CE_RATIO)); + this.attrs.set(id, Math.floor(val * ratio)); } else { - this.attrs.set(id, Math.floor(val * HERO_CE_RATIO * HERO_CE_RATIO)); + this.attrs.set(id, Math.floor(val)); } } } @@ -49,58 +25,42 @@ export class AttributeCal { public setByMap( attributes: Map, ratio: number = 1 ) { for(let [id, val] of attributes) { if(ABI_TYPE_MAIN.includes(id)) { - this.attrs.set(id, Math.floor(val * ratio * HERO_CE_RATIO * HERO_CE_RATIO)); + this.attrs.set(id, Math.floor(val * ratio)); } else { - this.attrs.set(id, Math.floor(val * HERO_CE_RATIO * HERO_CE_RATIO)); + this.attrs.set(id, Math.floor(val)); } } } - private calAttrValue(roleFix: number = 0, roleRatio: number = 0, heroBase: number = 0, heroFix: number = 0, heroRatio: number = 0, heroEquip: number = 0) { - return (heroFix + heroEquip + roleFix) * HERO_CE_RATIO + heroBase * ( HERO_CE_RATIO + heroRatio + roleRatio ); - } - - // private getRealAttrToMap() { - // let newMap = new Map(); - // for(let [id, val] of this.attrs) { - // if(ABI_TYPE_MAIN.includes(id)) { // 主属性 - // newMap.set(id, val / HERO_CE_RATIO / HERO_CE_RATIO); - // } else { - // newMap.set(id, val / HERO_SUB_ATTR_RATIO / HERO_CE_RATIO / HERO_CE_RATIO); - // } - // } - // return newMap; - // } - - private getReduceAttrMap() { + private getAttrMap() { let newMap = new Map(); for(let [id, val] of this.attrs) { - newMap.set(id, reduceCe(val)); + newMap.set(id, val); } return newMap } - public getReduceAttributes() { + public getAttributes() { let attrs = new Attribute(); - attrs.setByMap(this.getReduceAttrMap()); + attrs.setByMap(this.getAttrMap()); return attrs; } - public getReduceAttributesToArr() { + public getAttributesToArr() { let arr: {id: number, val: number}[] = []; - for(let [id, val] of this.getReduceAttrMap()) { + for(let [id, val] of this.getAttrMap()) { arr.push({ id, val }); } return arr; } - public getReduceAttributesToString() { - let arr = this.getReduceAttributesToArr(); + public getAttributesToString() { + let arr = this.getAttributesToArr(); return arr.map(cur => `${cur.id}&${cur.val}`).join('|'); } - public getReduceMainAttributes() { - let attribute = this.getReduceAttributes(); + public getMainAttributes() { + let attribute = this.getAttributes(); return attribute.getMainAttr(); } @@ -126,12 +86,8 @@ export class AttributeCal { return Math.floor(ce); } - public calSubAttrCeAndReduce() { - return Math.floor(this.calCe(3) / HERO_CE_RATIO / HERO_CE_RATIO); - } - - public calCelAndReduce() { - return Math.floor(this.calCe() / HERO_CE_RATIO / HERO_CE_RATIO); + public calSubAttrCe() { + return Math.floor(this.calCe(3)); } } diff --git a/shared/domain/roleField/hero.ts b/shared/domain/roleField/hero.ts index c083e6640..7ca654a48 100644 --- a/shared/domain/roleField/hero.ts +++ b/shared/domain/roleField/hero.ts @@ -1,7 +1,6 @@ import { Connect, EPlace, HeroSkin, HeroType, HeroUpdate, Talent } from '../../db/Hero'; import { gameData } from '../../pubUtils/data'; -import { reduceCe } from '../../pubUtils/util'; export interface CreateHeroParam extends HeroUpdate { hid: number; count: number; @@ -73,11 +72,7 @@ export class HeroParam { this.hName = hero.hName; this.exp = hero.exp; this.lv = hero.lv; - if(hero.isReducedCe) { - this.ce = hero.ce; - } else { - this.ce = reduceCe(hero.ce); - } + this.ce = hero.ce; this.star = hero.star; this.starStage = hero.starStage; this.colorStar = hero.colorStar; diff --git a/shared/pubUtils/data.ts b/shared/pubUtils/data.ts index 45198af9d..019956af7 100644 --- a/shared/pubUtils/data.ts +++ b/shared/pubUtils/data.ts @@ -335,7 +335,7 @@ export function getBossHpByWarId(warId: number) { if (relation === 2) { let newAttr = new AttributeCal(); newAttr.setByWarJson(attribute, 1); - let attrJson = newAttr.getReduceAttributes(); + let attrJson = newAttr.getAttributes(); const hp = attrJson.hp || 0; if (hp > 0) { diff --git a/shared/pubUtils/dictionary/DicEquipStrengthAttr.ts b/shared/pubUtils/dictionary/DicEquipStrengthAttr.ts index cca1f991a..2fca2c74d 100644 --- a/shared/pubUtils/dictionary/DicEquipStrengthAttr.ts +++ b/shared/pubUtils/dictionary/DicEquipStrengthAttr.ts @@ -1,5 +1,5 @@ // 装备强化表 -import { readFileAndParse, parseGoodStr, decodeArrayListStr } from '../util' +import { readFileAndParse, decodeArrayListStr } from '../util' import { FILENAME } from '../../consts' export interface DicEquipStrengthAttr { diff --git a/shared/pubUtils/playerCe.ts b/shared/pubUtils/playerCe.ts deleted file mode 100644 index 2e6109a4a..000000000 --- a/shared/pubUtils/playerCe.ts +++ /dev/null @@ -1,1108 +0,0 @@ -// /** -// * 体力系统 -// */ - -import { HERO_SYSTEM_TYPE, ABI_TYPE, HERO_CE_RATIO, LINEUP_NUM, TALENT_RELATION_TYPE } from '../consts'; - -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, 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, 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, role: RoleType, update: RoleUpdate, args: Array, 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 = [], params) { -// let heroAttrs: CeAttrData[] = []; // {"hp": {"base": number, "fixUp": number, "ratioUp": number}} - -// let addSeidList = new Array(); -// let removeSeidList = new Array(); - -// 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 args -// * @param ceAttr -// */ -// function calHeroAddSkin(role: RoleType, skinIds: Array) { -// 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, removeSeidList: Array) { -// 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(); // 需要升级的阶 -// 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; -// 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; -// 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(); // 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, removeSeidList: Array) { -// // 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(); -// // let curSeids = currentJob?.seid||new Array(); - -// // 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, removeSeidList: Array) { -// 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, removeSeidList: Array) { - -// // 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(); // 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, seidId: number, rand: number, seidValue = new Array()) { -// 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(); // 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; -// } \ No newline at end of file diff --git a/shared/pubUtils/util.ts b/shared/pubUtils/util.ts index 1b1d77ecf..9869fc3a3 100644 --- a/shared/pubUtils/util.ts +++ b/shared/pubUtils/util.ts @@ -1,21 +1,17 @@ import { STATUS } from './../consts/statusCode'; -import { HeroModel, HeroType } from '../db/Hero'; import { isNumber } from 'underscore'; const csprng = require('csprng'); import fs = require('fs'); import path = require('path'); -import { HERO_CE_RATIO, ABI_STAGE, GACHA_TO_FLOOR, REFRESH_TIME, ROBOT_SYS_TYPE, ITEM_CHANGE_REASON, WAR_TYPE, LINEUP_NUM } from '../consts'; +import { ABI_STAGE, GACHA_TO_FLOOR, REFRESH_TIME, ROBOT_SYS_TYPE, ITEM_CHANGE_REASON, WAR_TYPE } from '../consts'; import { findIndex } from 'underscore'; import { getTimeFunM } from './timeUtil'; import { Floor } from '../domain/activityField/gachaField'; import { WhiteListModel } from '../db/RegionWhiteList'; import { RewardInter } from './interface'; -import { RoleType } from '../db/Role'; -import { RoleCeModel } from '../db/RoleCe'; -import { CalCe } from '../services/role/calCe'; const randomName = require("chinese-random-name"); const moment = require('moment'); const crypto = require('crypto'); @@ -564,17 +560,6 @@ export function mergeSameGoods(goods: Array<{ id: number, count: number }>) { return resGoods; } -export function returnHeroCeRatio(hero: HeroType) { - let ce = reduceCe(hero.ce); - return Object.assign(hero, { ce }); -} - -// 缩小战力 -export function reduceCe(ce: number = 0) { - return Math.floor(ce / HERO_CE_RATIO / HERO_CE_RATIO) -} - - // 获取全部属性 export function getAllAttrStage() { let attrs = new Array(); // 有升级的属性 1-hp 2-atk 3-def 4-mdef 5-agi 6-luk From 83dc9746328dcca10b6c147b13de477e236dd738 Mon Sep 17 00:00:00 2001 From: luying Date: Wed, 30 Mar 2022 18:01:03 +0800 Subject: [PATCH 09/12] =?UTF-8?q?=E6=88=98=E5=8A=9B=EF=BC=9A=E4=BF=AE?= =?UTF-8?q?=E5=A4=8Dbug?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../app/servers/role/handler/heroHandler.ts | 2 +- .../app/servers/role/handler/roleHandler.ts | 2 +- game-server/app/services/playerCeService.ts | 1 + game-server/app/services/role/calCe.ts | 28 +- gm-server/app/service/Activity.ts | 2 +- gm-server/app/service/users.ts | 18 +- shared/consts/constModules/abilityConst.ts | 16 +- .../jsons/dic_zyz_equipStrengthAttr.json | 5740 +++++++++-------- .../jsons/dic_zyz_randomEffectPool.json | 14 - shared/resource/jsons/dic_zyz_se.json | 15 + 10 files changed, 2994 insertions(+), 2844 deletions(-) diff --git a/game-server/app/servers/role/handler/heroHandler.ts b/game-server/app/servers/role/handler/heroHandler.ts index b2daaddf6..bf30c7b68 100644 --- a/game-server/app/servers/role/handler/heroHandler.ts +++ b/game-server/app/servers/role/handler/heroHandler.ts @@ -518,7 +518,7 @@ export class HeroHandler { consumes: updateConsume } - let isFavourLvUp = oldLv == newLv; + let isFavourLvUp = oldLv != newLv; let { curHero } = await calculateCeWithHero(HERO_SYSTEM_TYPE.FAVOUR, roleId, serverId, sid, hero.hid, update, { isFavourLvUp, hero }); if(isFavourLvUp) { diff --git a/game-server/app/servers/role/handler/roleHandler.ts b/game-server/app/servers/role/handler/roleHandler.ts index 33a543ed6..47be820f8 100644 --- a/game-server/app/servers/role/handler/roleHandler.ts +++ b/game-server/app/servers/role/handler/roleHandler.ts @@ -50,7 +50,7 @@ export class RoleHandler { let checkName = await RoleModel.checkName(roleName, serverId); if (checkName) return resResult(STATUS.NAME_HAS_USED); - let { resultHeroes: heroes } = await createHeroes(roleId, roleName, sid, serverId, DEFAULT_HEROES.map(hid => ({hid, count: 1})), { roleName, hasInit: true, title: role.title, teraphs: role.teraphs, lv: DEFAULT_LV }); + let { resultHeroes: heroes } = await createHeroes(roleId, roleName, sid, serverId, DEFAULT_HEROES.map(hid => ({hid, count: 1})), { roleName, hasInit: true, title: role.title, teraphs: role.teraphs, lv: role.lv }); // role = await RoleModel.updateRoleInfo(roleId, { roleName, hasInit: true }); // 在算战力的时候一起更新 session.set('roleName', roleName); session.push('roleName', () => { }); diff --git a/game-server/app/services/playerCeService.ts b/game-server/app/services/playerCeService.ts index 2c821b042..9061eaf49 100644 --- a/game-server/app/services/playerCeService.ts +++ b/game-server/app/services/playerCeService.ts @@ -131,6 +131,7 @@ export async function calculateCes(type: HERO_SYSTEM_TYPE, roleId: string, serve case HERO_SYSTEM_TYPE.FAVOUR: // 8. 好感度 { let { hero: { connections }, isFavourLvUp } = param; + console.log('####', connections, isFavourLvUp, heroUpdates) if(isFavourLvUp) { for(let [hid, { favourLv }] of heroUpdates) { calCe.setFavour(hid, favourLv, connections); diff --git a/game-server/app/services/role/calCe.ts b/game-server/app/services/role/calCe.ts index 66fc87053..e1f54e5bd 100644 --- a/game-server/app/services/role/calCe.ts +++ b/game-server/app/services/role/calCe.ts @@ -2,7 +2,7 @@ import { ABI_STAGE, ABI_STAGE_TO_TYPE, ABI_TYPE_MAIN, LINEUP_NUM, SEID_TYPE, TAL import { Connect, EPlace, HeroSkin, HeroType, HeroUpdate, Stone, Talent } from "../../db/Hero"; import { JewelType } from "../../db/Jewel"; import { RoleUpdate, Teraph } from "../../db/Role"; -import { AttrCell, Attribute, EquipAttr, HeroAttr, RoleCeType, SchoolAttr } from "../../db/RoleCe"; +import { AttrCell, Attribute, EquipAttr, HeroAttr, RoleCeType, SchoolAttr, ScrollAttr } from "../../db/RoleCe"; import { TopHero } from "../../domain/dbGeneral"; import { AttributeCal } from "../../domain/roleField/attribute"; import { gameData, getEquipQualityIdByEquipIdAndPoint, getEquipStarAttrByStage, getEquipStrenthenAttr, getEquipSuitByHero, getFriendShipById, getHeroStarByQuality, getHeroWakeByQuality, getJewelConditionByLvAndSeId, getJobByGradeAndClass, getSchoolRateByStar, getScollByStar, getTeraph } from "../../pubUtils/data"; @@ -43,8 +43,8 @@ export class CalCe { let val = 0, str = ''; if(ABI_TYPE_MAIN.indexOf(attrId) != -1) { // {[hp1 + lv * hp2 + hp3 * ( 1 + hp4 )] * (1 + hp5 ) + [( hp6 + hp7 ) * ( 1 + hp8 )] } * ( 1 + hp9 ) + hp10 + hp11 - val = ((mainBase + job + lv * starUp + connect * ( 1 + favour )) * ( 1 + school + talent ) + (( equipQuality + equipStrength ) * ( 1 + ( equipStar + equipSuit ))) ) * ( 1 + jewel ) + stone + teraph + title + scroll + skin; - str += `{[${mainBase}+${job}+${lv}*${starUp}+${connect}*(1+${favour})]*(1+${school}+${talent})+[(${equipQuality}+${equipStrength})*(1+${equipStar}+${equipSuit})]}*(1+${jewel})+${stone}+${teraph}+${title}+${scroll}+${skin}`; + val = ((mainBase + job + lv * starUp + connect * ( 1 + favour/100 )) * ( 1 + school + talent ) + (( equipQuality + equipStrength ) * ( 1 + ( equipStar/100 + equipSuit/100 ))) ) * ( 1 + jewel ) + stone + teraph + title + scroll + skin; + str += `{[${mainBase}+${job}+${lv}*${starUp}+${connect}*(1+${favour}/100)]*(1+${school}+${talent})+[(${equipQuality}+${equipStrength})*(1+${equipStar}/100+${equipSuit}/100)]}*(1+${jewel})+${stone}+${teraph}+${title}+${scroll}+${skin}`; } else { // attr1 + attr2 + attr3 + attr4 + attr5 + attr6 + attr7 + attr8 + attr9 val = subBase + job + talent + teraph + school + title + jewel + skin + equipStar; @@ -135,11 +135,12 @@ export class CalCe { // 星级相关 public setHeroStar(hid: number, job: number, quality: number, star: number, starStage: number, colorStar: number, colorStarStage: number) { this.data.clearHeroAttrByHid(hid, 'starUp'); + let dicHero = gameData.hero.get(hid); let dicJob = gameData.job.get(job); let jobClass = dicJob.job_class; const isWake = colorStar > 0; // 是否觉醒,只要激活了觉醒,彩星就会 > 1 - const dicStar = isWake ? getHeroWakeByQuality(jobClass, quality, colorStar) : getHeroStarByQuality(jobClass, quality, star); // 星级表 - const dicPreStar = isWake? getHeroWakeByQuality(jobClass, quality, colorStar - 1): getHeroStarByQuality(jobClass, quality, star - 1); + const dicStar = isWake ? getHeroWakeByQuality(jobClass, dicHero.quality, colorStar) : getHeroStarByQuality(jobClass, quality, star); // 星级表 + const dicPreStar = isWake? getHeroWakeByQuality(jobClass, dicHero.quality, colorStar - 1): getHeroStarByQuality(jobClass, quality, star - 1); let curStage = isWake? colorStarStage: starStage; for (let stage = ABI_STAGE.START + 1; stage <= ABI_STAGE.END; stage++) { @@ -162,7 +163,7 @@ export class CalCe { const 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++) { + for(let i = 1; i <= (dicJob.maxStage||dicLastJob.maxStage); i++) { if(jobStage >= i) { let { id, attr } = dicJob.ceAttr.get(i); let heroAttr = this.data.getHeroAttrByHidAndId(hid, id); @@ -186,7 +187,6 @@ export class CalCe { this.data.clearHeroAttrByHid(hid, 'favour'); let currentFiendShipLevel = gameData.friendShipLevelMap.get(favourLv); let add = currentFiendShipLevel.add; - for (let {shipId, level} of connections) { let dicHeroFriendShip = getFriendShipById(shipId, level); for (let { id } of dicHeroFriendShip.attributes) { @@ -450,13 +450,13 @@ export class CalCe { // console.log('effectList', JSON.stringify(effectList)); for (let { type, gainValueArr: [ability, value] } of effectList) { - if (type == SEID_TYPE.TYPE101) { // 加值 + if (type == SEID_TYPE.FIX) { // 加值 addToMap(fixUp, ability, value); - } else if (type == SEID_TYPE.TYPE103) { // 主属性加百分比 + } else if (type == SEID_TYPE.MAIN_RATIO||type == SEID_TYPE.MAIN_RATIO_2) { // 主属性加百分比 if(ABI_TYPE_MAIN.includes(ability)) { addToMap(ratioUp, ability, value / 1000); } - } else if (type == SEID_TYPE.TYPE104) { // 次级属性加百分比 + } else if (type == SEID_TYPE.SUB_RATIO||type == SEID_TYPE.SUB_RATIO_2) { // 次级属性加百分比 if(!ABI_TYPE_MAIN.includes(ability)) { addToMap(ratioUp, ability, value * 100); } @@ -473,7 +473,7 @@ export class CalCe { if (!curSeid) { console.log("seidId not found:" + seidId); return; } if (!seidValue) seidValue = curSeid.gainValueArr; - if (curSeid.type === SEID_TYPE.TYPE999) { + if (curSeid.type === SEID_TYPE.MIX) { for (let i = 0; i < seidValue.length; i++) { this.addSeid(effectList, seidValue[i], rand); } @@ -764,8 +764,12 @@ class CalCeData { for(let [_, { hid, attrId, ce }] of this.schoolAttrs) { schoolAttrs.push({ hid, attrId, value: ce }); } + let scrollAttrs: ScrollAttr[] = []; + for(let [_, { hid, attrId, ce }] of this.scrollAttrs) { + scrollAttrs.push({ hid, attrId, value: ce }); + } return { - roleLv: this.roleLv, roleId, globalAttrs, heroAttrs, equipAttrs, schoolAttrs, attributes + roleLv: this.roleLv, roleId, globalAttrs, heroAttrs, equipAttrs, schoolAttrs, scrollAttrs, attributes } } } diff --git a/gm-server/app/service/Activity.ts b/gm-server/app/service/Activity.ts index 5edc59871..c072e4669 100644 --- a/gm-server/app/service/Activity.ts +++ b/gm-server/app/service/Activity.ts @@ -58,7 +58,7 @@ export default class Activity extends Service { if(activity.type == ACTIVITY_TYPE.SIGN_IN || activity.type == ACTIVITY_TYPE.SIGN_IN_VIP) { // 签到活动的不显示期内也可以编辑 - let signInObj = new SignInData(activity, 0); + let signInObj = new SignInData(activity, 0, 0); if(signInObj.beginTime < now.getTime() && signInObj.endTime > now.getTime() ) { return this.ctx.service.utils.resResult(STATUS.GM_CAN_NOT_EDIT_ACT); } diff --git a/gm-server/app/service/users.ts b/gm-server/app/service/users.ts index 93cfb27d2..502de1a5d 100644 --- a/gm-server/app/service/users.ts +++ b/gm-server/app/service/users.ts @@ -1,12 +1,11 @@ import { UserModel } from '@db/User'; -import { CeAttrDataRole, RoleModel } from '@db/Role'; +import { RoleModel } from '@db/Role'; import { HeroModel } from '@db/Hero'; import { Service } from 'egg'; import { STATUS, REDIS_KEY, WAR_TYPE } from '@consts'; import { ItemModel } from '@db/Item'; import { gameData } from '@pubUtils/data'; -import { AttributeCal } from '@domain/roleField/attribute'; import { smsModel } from '@db/Sms'; import { isString } from 'underscore'; import { GiftCodeModel } from '@db/GiftCode'; @@ -22,6 +21,7 @@ import { RedisClient } from 'redis'; import { UserGuildModel } from '@db/UserGuild'; import { TowerRecordModel } from '@db/TowerRecord'; import { nowSeconds } from '@pubUtils/timeUtil'; +import { RoleCeModel, RoleCeType } from '@db/RoleCe'; // import { resResult } from '@pubUtils/util'; @@ -295,18 +295,18 @@ export default class GMUsers extends Service { const heroes = await HeroModel.findByCondition(page, pageSize, sortField, sortOrder, form); const total = await HeroModel.countByCondition( form ) - - let roleMap = new Map(); + + let roleMap = new Map(); for(let { roleId } of heroes) { if(!roleMap.has(roleId)) { - let role = await RoleModel.findByRoleId(roleId, 'attr'); - roleMap.set(roleId, role.attr); + let roleCe = await RoleCeModel.findByRoleId(roleId); + roleMap.set(roleId, roleCe); } } let list = heroes.map(cur => { - let cal = new AttributeCal(); - cal.setByDbData(roleMap.get(cur.roleId), cur.attr); - return {...cur, calculatedAttr: cal.getAttributesToArr(), env: ctx.app.config.realEnv} + let roleCe = roleMap.get(cur.roleId); + let attr = roleCe.attributes.filter(ccur => ccur.hid == cur.hid); + return {...cur, calculatedAttr: attr, env: ctx.app.config.realEnv} }) return ctx.service.utils.resResult(STATUS.SUCCESS, { list, total }) diff --git a/shared/consts/constModules/abilityConst.ts b/shared/consts/constModules/abilityConst.ts index 812d956e3..e9d4939f1 100644 --- a/shared/consts/constModules/abilityConst.ts +++ b/shared/consts/constModules/abilityConst.ts @@ -99,13 +99,17 @@ export const ABI_TYPE_SUB = [ export enum SEID_TYPE { /**属性固定值加成(数值) */ - TYPE101 = 1, - /**基础属性加百分比,除以1000以后加到ratioUp */ - TYPE103 = 2, - /**次级属性的百分比加成,乘以100后加到fixUp */ - TYPE104 = 3, + FIX = 1, + /**基础属性加百分比,除以1000 */ + MAIN_RATIO = 2, + /**次级属性的百分比加成 */ + SUB_RATIO = 3, + /**基础属性加百分比,除以1000 */ + MAIN_RATIO_2 = 4, + /**次级属性的百分比加成 */ + SUB_RATIO_2 = 5, /**复合属性 */ - TYPE999 = 999, + MIX = 999, } export enum ABI_STAGE { diff --git a/shared/resource/jsons/dic_zyz_equipStrengthAttr.json b/shared/resource/jsons/dic_zyz_equipStrengthAttr.json index 78a2f5324..635f57ae0 100644 --- a/shared/resource/jsons/dic_zyz_equipStrengthAttr.json +++ b/shared/resource/jsons/dic_zyz_equipStrengthAttr.json @@ -1,14001 +1,14141 @@ [ { - "id": 1, + "equipId": 1, + "lv": 0, + "attr": "2&09" + }, + { + "equipId": 1, "lv": 1, "attr": "2&10" }, { - "id": 1, + "equipId": 1, "lv": 2, "attr": "2&11" }, { - "id": 1, + "equipId": 1, "lv": 3, "attr": "2&12" }, { - "id": 1, + "equipId": 1, "lv": 4, "attr": "2&13" }, { - "id": 1, + "equipId": 1, "lv": 5, "attr": "2&14" }, { - "id": 1, + "equipId": 1, "lv": 6, "attr": "2&15" }, { - "id": 1, + "equipId": 1, "lv": 7, "attr": "2&16" }, { - "id": 1, + "equipId": 1, "lv": 8, "attr": "2&17" }, { - "id": 1, + "equipId": 1, "lv": 9, "attr": "2&18" }, { - "id": 1, + "equipId": 1, "lv": 10, "attr": "2&19" }, { - "id": 1, + "equipId": 1, "lv": 11, "attr": "2&20" }, { - "id": 1, + "equipId": 1, "lv": 12, "attr": "2&21" }, { - "id": 1, + "equipId": 1, "lv": 13, "attr": "2&22" }, { - "id": 1, + "equipId": 1, "lv": 14, "attr": "2&23" }, { - "id": 1, + "equipId": 1, "lv": 15, "attr": "2&24" }, { - "id": 1, + "equipId": 1, "lv": 16, "attr": "2&25" }, { - "id": 1, + "equipId": 1, "lv": 17, "attr": "2&26" }, { - "id": 1, + "equipId": 1, "lv": 18, "attr": "2&27" }, { - "id": 1, + "equipId": 1, "lv": 19, "attr": "2&28" }, { - "id": 1, + "equipId": 1, "lv": 20, "attr": "2&29" }, { - "id": 1, + "equipId": 1, "lv": 21, "attr": "2&30" }, { - "id": 1, + "equipId": 1, "lv": 22, "attr": "2&31" }, { - "id": 1, + "equipId": 1, "lv": 23, "attr": "2&32" }, { - "id": 1, + "equipId": 1, "lv": 24, "attr": "2&33" }, { - "id": 1, + "equipId": 1, "lv": 25, "attr": "2&34" }, { - "id": 1, + "equipId": 1, "lv": 26, "attr": "2&35" }, { - "id": 1, + "equipId": 1, "lv": 27, "attr": "2&36" }, { - "id": 1, + "equipId": 1, "lv": 28, "attr": "2&37" }, { - "id": 1, + "equipId": 1, "lv": 29, "attr": "2&38" }, { - "id": 1, + "equipId": 1, "lv": 30, "attr": "2&39" }, { - "id": 1, + "equipId": 1, "lv": 31, "attr": "2&40" }, { - "id": 1, + "equipId": 1, "lv": 32, "attr": "2&41" }, { - "id": 1, + "equipId": 1, "lv": 33, "attr": "2&42" }, { - "id": 1, + "equipId": 1, "lv": 34, "attr": "2&43" }, { - "id": 1, + "equipId": 1, "lv": 35, "attr": "2&44" }, { - "id": 1, + "equipId": 1, "lv": 36, "attr": "2&45" }, { - "id": 1, + "equipId": 1, "lv": 37, "attr": "2&46" }, { - "id": 1, + "equipId": 1, "lv": 38, "attr": "2&47" }, { - "id": 1, + "equipId": 1, "lv": 39, "attr": "2&48" }, { - "id": 1, + "equipId": 1, "lv": 40, "attr": "2&49" }, { - "id": 1, + "equipId": 1, "lv": 41, "attr": "2&50" }, { - "id": 1, + "equipId": 1, "lv": 42, "attr": "2&51" }, { - "id": 1, + "equipId": 1, "lv": 43, "attr": "2&52" }, { - "id": 1, + "equipId": 1, "lv": 44, "attr": "2&53" }, { - "id": 1, + "equipId": 1, "lv": 45, "attr": "2&54" }, { - "id": 1, + "equipId": 1, "lv": 46, "attr": "2&55" }, { - "id": 1, + "equipId": 1, "lv": 47, "attr": "2&56" }, { - "id": 1, + "equipId": 1, "lv": 48, "attr": "2&57" }, { - "id": 1, + "equipId": 1, "lv": 49, "attr": "2&58" }, { - "id": 1, + "equipId": 1, "lv": 50, "attr": "2&59" }, { - "id": 1, + "equipId": 1, "lv": 51, "attr": "2&60" }, { - "id": 1, + "equipId": 1, "lv": 52, "attr": "2&61" }, { - "id": 1, + "equipId": 1, "lv": 53, "attr": "2&62" }, { - "id": 1, + "equipId": 1, "lv": 54, "attr": "2&63" }, { - "id": 1, + "equipId": 1, "lv": 55, "attr": "2&64" }, { - "id": 1, + "equipId": 1, "lv": 56, "attr": "2&65" }, { - "id": 1, + "equipId": 1, "lv": 57, "attr": "2&66" }, { - "id": 1, + "equipId": 1, "lv": 58, "attr": "2&67" }, { - "id": 1, + "equipId": 1, "lv": 59, "attr": "2&68" }, { - "id": 1, + "equipId": 1, "lv": 60, "attr": "2&69" }, { - "id": 1, + "equipId": 1, "lv": 61, "attr": "2&70" }, { - "id": 1, + "equipId": 1, "lv": 62, "attr": "2&71" }, { - "id": 1, + "equipId": 1, "lv": 63, "attr": "2&72" }, { - "id": 1, + "equipId": 1, "lv": 64, "attr": "2&73" }, { - "id": 1, + "equipId": 1, "lv": 65, "attr": "2&74" }, { - "id": 1, + "equipId": 1, "lv": 66, "attr": "2&75" }, { - "id": 1, + "equipId": 1, "lv": 67, "attr": "2&76" }, { - "id": 1, + "equipId": 1, "lv": 68, "attr": "2&77" }, { - "id": 1, + "equipId": 1, "lv": 69, "attr": "2&78" }, { - "id": 1, + "equipId": 1, "lv": 70, "attr": "2&79" }, { - "id": 1, + "equipId": 1, "lv": 71, "attr": "2&80" }, { - "id": 1, + "equipId": 1, "lv": 72, "attr": "2&81" }, { - "id": 1, + "equipId": 1, "lv": 73, "attr": "2&82" }, { - "id": 1, + "equipId": 1, "lv": 74, "attr": "2&83" }, { - "id": 1, + "equipId": 1, "lv": 75, "attr": "2&84" }, { - "id": 1, + "equipId": 1, "lv": 76, "attr": "2&85" }, { - "id": 1, + "equipId": 1, "lv": 77, "attr": "2&86" }, { - "id": 1, + "equipId": 1, "lv": 78, "attr": "2&87" }, { - "id": 1, + "equipId": 1, "lv": 79, "attr": "2&88" }, { - "id": 1, + "equipId": 1, "lv": 80, "attr": "2&89" }, { - "id": 1, + "equipId": 1, "lv": 81, "attr": "2&90" }, { - "id": 1, + "equipId": 1, "lv": 82, "attr": "2&91" }, { - "id": 1, + "equipId": 1, "lv": 83, "attr": "2&92" }, { - "id": 1, + "equipId": 1, "lv": 84, "attr": "2&93" }, { - "id": 1, + "equipId": 1, "lv": 85, "attr": "2&94" }, { - "id": 1, + "equipId": 1, "lv": 86, "attr": "2&95" }, { - "id": 1, + "equipId": 1, "lv": 87, "attr": "2&96" }, { - "id": 1, + "equipId": 1, "lv": 88, "attr": "2&97" }, { - "id": 1, + "equipId": 1, "lv": 89, "attr": "2&98" }, { - "id": 1, + "equipId": 1, "lv": 90, "attr": "2&99" }, { - "id": 1, + "equipId": 1, "lv": 91, "attr": "2&100" }, { - "id": 1, + "equipId": 1, "lv": 92, "attr": "2&101" }, { - "id": 1, + "equipId": 1, "lv": 93, "attr": "2&102" }, { - "id": 1, + "equipId": 1, "lv": 94, "attr": "2&103" }, { - "id": 1, + "equipId": 1, "lv": 95, "attr": "2&104" }, { - "id": 1, + "equipId": 1, "lv": 96, "attr": "2&105" }, { - "id": 1, + "equipId": 1, "lv": 97, "attr": "2&106" }, { - "id": 1, + "equipId": 1, "lv": 98, "attr": "2&107" }, { - "id": 1, + "equipId": 1, "lv": 99, "attr": "2&108" }, { - "id": 1, + "equipId": 1, "lv": 100, "attr": "2&109" }, { - "id": 2, + "equipId": 2, + "lv": 0, + "attr": "4&19" + }, + { + "equipId": 2, "lv": 1, "attr": "4&20" }, { - "id": 2, + "equipId": 2, "lv": 2, "attr": "4&21" }, { - "id": 2, + "equipId": 2, "lv": 3, "attr": "4&22" }, { - "id": 2, + "equipId": 2, "lv": 4, "attr": "4&23" }, { - "id": 2, + "equipId": 2, "lv": 5, "attr": "4&24" }, { - "id": 2, + "equipId": 2, "lv": 6, "attr": "4&25" }, { - "id": 2, + "equipId": 2, "lv": 7, "attr": "4&26" }, { - "id": 2, + "equipId": 2, "lv": 8, "attr": "4&27" }, { - "id": 2, + "equipId": 2, "lv": 9, "attr": "4&28" }, { - "id": 2, + "equipId": 2, "lv": 10, "attr": "4&29" }, { - "id": 2, + "equipId": 2, "lv": 11, "attr": "4&30" }, { - "id": 2, + "equipId": 2, "lv": 12, "attr": "4&31" }, { - "id": 2, + "equipId": 2, "lv": 13, "attr": "4&32" }, { - "id": 2, + "equipId": 2, "lv": 14, "attr": "4&33" }, { - "id": 2, + "equipId": 2, "lv": 15, "attr": "4&34" }, { - "id": 2, + "equipId": 2, "lv": 16, "attr": "4&35" }, { - "id": 2, + "equipId": 2, "lv": 17, "attr": "4&36" }, { - "id": 2, + "equipId": 2, "lv": 18, "attr": "4&37" }, { - "id": 2, + "equipId": 2, "lv": 19, "attr": "4&38" }, { - "id": 2, + "equipId": 2, "lv": 20, "attr": "4&39" }, { - "id": 2, + "equipId": 2, "lv": 21, "attr": "4&40" }, { - "id": 2, + "equipId": 2, "lv": 22, "attr": "4&41" }, { - "id": 2, + "equipId": 2, "lv": 23, "attr": "4&42" }, { - "id": 2, + "equipId": 2, "lv": 24, "attr": "4&43" }, { - "id": 2, + "equipId": 2, "lv": 25, "attr": "4&44" }, { - "id": 2, + "equipId": 2, "lv": 26, "attr": "4&45" }, { - "id": 2, + "equipId": 2, "lv": 27, "attr": "4&46" }, { - "id": 2, + "equipId": 2, "lv": 28, "attr": "4&47" }, { - "id": 2, + "equipId": 2, "lv": 29, "attr": "4&48" }, { - "id": 2, + "equipId": 2, "lv": 30, "attr": "4&49" }, { - "id": 2, + "equipId": 2, "lv": 31, "attr": "4&50" }, { - "id": 2, + "equipId": 2, "lv": 32, "attr": "4&51" }, { - "id": 2, + "equipId": 2, "lv": 33, "attr": "4&52" }, { - "id": 2, + "equipId": 2, "lv": 34, "attr": "4&53" }, { - "id": 2, + "equipId": 2, "lv": 35, "attr": "4&54" }, { - "id": 2, + "equipId": 2, "lv": 36, "attr": "4&55" }, { - "id": 2, + "equipId": 2, "lv": 37, "attr": "4&56" }, { - "id": 2, + "equipId": 2, "lv": 38, "attr": "4&57" }, { - "id": 2, + "equipId": 2, "lv": 39, "attr": "4&58" }, { - "id": 2, + "equipId": 2, "lv": 40, "attr": "4&59" }, { - "id": 2, + "equipId": 2, "lv": 41, "attr": "4&60" }, { - "id": 2, + "equipId": 2, "lv": 42, "attr": "4&61" }, { - "id": 2, + "equipId": 2, "lv": 43, "attr": "4&62" }, { - "id": 2, + "equipId": 2, "lv": 44, "attr": "4&63" }, { - "id": 2, + "equipId": 2, "lv": 45, "attr": "4&64" }, { - "id": 2, + "equipId": 2, "lv": 46, "attr": "4&65" }, { - "id": 2, + "equipId": 2, "lv": 47, "attr": "4&66" }, { - "id": 2, + "equipId": 2, "lv": 48, "attr": "4&67" }, { - "id": 2, + "equipId": 2, "lv": 49, "attr": "4&68" }, { - "id": 2, + "equipId": 2, "lv": 50, "attr": "4&69" }, { - "id": 2, + "equipId": 2, "lv": 51, "attr": "4&70" }, { - "id": 2, + "equipId": 2, "lv": 52, "attr": "4&71" }, { - "id": 2, + "equipId": 2, "lv": 53, "attr": "4&72" }, { - "id": 2, + "equipId": 2, "lv": 54, "attr": "4&73" }, { - "id": 2, + "equipId": 2, "lv": 55, "attr": "4&74" }, { - "id": 2, + "equipId": 2, "lv": 56, "attr": "4&75" }, { - "id": 2, + "equipId": 2, "lv": 57, "attr": "4&76" }, { - "id": 2, + "equipId": 2, "lv": 58, "attr": "4&77" }, { - "id": 2, + "equipId": 2, "lv": 59, "attr": "4&78" }, { - "id": 2, + "equipId": 2, "lv": 60, "attr": "4&79" }, { - "id": 2, + "equipId": 2, "lv": 61, "attr": "4&80" }, { - "id": 2, + "equipId": 2, "lv": 62, "attr": "4&81" }, { - "id": 2, + "equipId": 2, "lv": 63, "attr": "4&82" }, { - "id": 2, + "equipId": 2, "lv": 64, "attr": "4&83" }, { - "id": 2, + "equipId": 2, "lv": 65, "attr": "4&84" }, { - "id": 2, + "equipId": 2, "lv": 66, "attr": "4&85" }, { - "id": 2, + "equipId": 2, "lv": 67, "attr": "4&86" }, { - "id": 2, + "equipId": 2, "lv": 68, "attr": "4&87" }, { - "id": 2, + "equipId": 2, "lv": 69, "attr": "4&88" }, { - "id": 2, + "equipId": 2, "lv": 70, "attr": "4&89" }, { - "id": 2, + "equipId": 2, "lv": 71, "attr": "4&90" }, { - "id": 2, + "equipId": 2, "lv": 72, "attr": "4&91" }, { - "id": 2, + "equipId": 2, "lv": 73, "attr": "4&92" }, { - "id": 2, + "equipId": 2, "lv": 74, "attr": "4&93" }, { - "id": 2, + "equipId": 2, "lv": 75, "attr": "4&94" }, { - "id": 2, + "equipId": 2, "lv": 76, "attr": "4&95" }, { - "id": 2, + "equipId": 2, "lv": 77, "attr": "4&96" }, { - "id": 2, + "equipId": 2, "lv": 78, "attr": "4&97" }, { - "id": 2, + "equipId": 2, "lv": 79, "attr": "4&98" }, { - "id": 2, + "equipId": 2, "lv": 80, "attr": "4&99" }, { - "id": 2, + "equipId": 2, "lv": 81, "attr": "4&100" }, { - "id": 2, + "equipId": 2, "lv": 82, "attr": "4&101" }, { - "id": 2, + "equipId": 2, "lv": 83, "attr": "4&102" }, { - "id": 2, + "equipId": 2, "lv": 84, "attr": "4&103" }, { - "id": 2, + "equipId": 2, "lv": 85, "attr": "4&104" }, { - "id": 2, + "equipId": 2, "lv": 86, "attr": "4&105" }, { - "id": 2, + "equipId": 2, "lv": 87, "attr": "4&106" }, { - "id": 2, + "equipId": 2, "lv": 88, "attr": "4&107" }, { - "id": 2, + "equipId": 2, "lv": 89, "attr": "4&108" }, { - "id": 2, + "equipId": 2, "lv": 90, "attr": "4&109" }, { - "id": 2, + "equipId": 2, "lv": 91, "attr": "4&110" }, { - "id": 2, + "equipId": 2, "lv": 92, "attr": "4&111" }, { - "id": 2, + "equipId": 2, "lv": 93, "attr": "4&112" }, { - "id": 2, + "equipId": 2, "lv": 94, "attr": "4&113" }, { - "id": 2, + "equipId": 2, "lv": 95, "attr": "4&114" }, { - "id": 2, + "equipId": 2, "lv": 96, "attr": "4&115" }, { - "id": 2, + "equipId": 2, "lv": 97, "attr": "4&116" }, { - "id": 2, + "equipId": 2, "lv": 98, "attr": "4&117" }, { - "id": 2, + "equipId": 2, "lv": 99, "attr": "4&118" }, { - "id": 2, + "equipId": 2, "lv": 100, "attr": "4&119" }, { - "id": 3, + "equipId": 3, + "lv": 0, + "attr": "5&19" + }, + { + "equipId": 3, "lv": 1, "attr": "5&20" }, { - "id": 3, + "equipId": 3, "lv": 2, "attr": "5&21" }, { - "id": 3, + "equipId": 3, "lv": 3, "attr": "5&22" }, { - "id": 3, + "equipId": 3, "lv": 4, "attr": "5&23" }, { - "id": 3, + "equipId": 3, "lv": 5, "attr": "5&24" }, { - "id": 3, + "equipId": 3, "lv": 6, "attr": "5&25" }, { - "id": 3, + "equipId": 3, "lv": 7, "attr": "5&26" }, { - "id": 3, + "equipId": 3, "lv": 8, "attr": "5&27" }, { - "id": 3, + "equipId": 3, "lv": 9, "attr": "5&28" }, { - "id": 3, + "equipId": 3, "lv": 10, "attr": "5&29" }, { - "id": 3, + "equipId": 3, "lv": 11, "attr": "5&30" }, { - "id": 3, + "equipId": 3, "lv": 12, "attr": "5&31" }, { - "id": 3, + "equipId": 3, "lv": 13, "attr": "5&32" }, { - "id": 3, + "equipId": 3, "lv": 14, "attr": "5&33" }, { - "id": 3, + "equipId": 3, "lv": 15, "attr": "5&34" }, { - "id": 3, + "equipId": 3, "lv": 16, "attr": "5&35" }, { - "id": 3, + "equipId": 3, "lv": 17, "attr": "5&36" }, { - "id": 3, + "equipId": 3, "lv": 18, "attr": "5&37" }, { - "id": 3, + "equipId": 3, "lv": 19, "attr": "5&38" }, { - "id": 3, + "equipId": 3, "lv": 20, "attr": "5&39" }, { - "id": 3, + "equipId": 3, "lv": 21, "attr": "5&40" }, { - "id": 3, + "equipId": 3, "lv": 22, "attr": "5&41" }, { - "id": 3, + "equipId": 3, "lv": 23, "attr": "5&42" }, { - "id": 3, + "equipId": 3, "lv": 24, "attr": "5&43" }, { - "id": 3, + "equipId": 3, "lv": 25, "attr": "5&44" }, { - "id": 3, + "equipId": 3, "lv": 26, "attr": "5&45" }, { - "id": 3, + "equipId": 3, "lv": 27, "attr": "5&46" }, { - "id": 3, + "equipId": 3, "lv": 28, "attr": "5&47" }, { - "id": 3, + "equipId": 3, "lv": 29, "attr": "5&48" }, { - "id": 3, + "equipId": 3, "lv": 30, "attr": "5&49" }, { - "id": 3, + "equipId": 3, "lv": 31, "attr": "5&50" }, { - "id": 3, + "equipId": 3, "lv": 32, "attr": "5&51" }, { - "id": 3, + "equipId": 3, "lv": 33, "attr": "5&52" }, { - "id": 3, + "equipId": 3, "lv": 34, "attr": "5&53" }, { - "id": 3, + "equipId": 3, "lv": 35, "attr": "5&54" }, { - "id": 3, + "equipId": 3, "lv": 36, "attr": "5&55" }, { - "id": 3, + "equipId": 3, "lv": 37, "attr": "5&56" }, { - "id": 3, + "equipId": 3, "lv": 38, "attr": "5&57" }, { - "id": 3, + "equipId": 3, "lv": 39, "attr": "5&58" }, { - "id": 3, + "equipId": 3, "lv": 40, "attr": "5&59" }, { - "id": 3, + "equipId": 3, "lv": 41, "attr": "5&60" }, { - "id": 3, + "equipId": 3, "lv": 42, "attr": "5&61" }, { - "id": 3, + "equipId": 3, "lv": 43, "attr": "5&62" }, { - "id": 3, + "equipId": 3, "lv": 44, "attr": "5&63" }, { - "id": 3, + "equipId": 3, "lv": 45, "attr": "5&64" }, { - "id": 3, + "equipId": 3, "lv": 46, "attr": "5&65" }, { - "id": 3, + "equipId": 3, "lv": 47, "attr": "5&66" }, { - "id": 3, + "equipId": 3, "lv": 48, "attr": "5&67" }, { - "id": 3, + "equipId": 3, "lv": 49, "attr": "5&68" }, { - "id": 3, + "equipId": 3, "lv": 50, "attr": "5&69" }, { - "id": 3, + "equipId": 3, "lv": 51, "attr": "5&70" }, { - "id": 3, + "equipId": 3, "lv": 52, "attr": "5&71" }, { - "id": 3, + "equipId": 3, "lv": 53, "attr": "5&72" }, { - "id": 3, + "equipId": 3, "lv": 54, "attr": "5&73" }, { - "id": 3, + "equipId": 3, "lv": 55, "attr": "5&74" }, { - "id": 3, + "equipId": 3, "lv": 56, "attr": "5&75" }, { - "id": 3, + "equipId": 3, "lv": 57, "attr": "5&76" }, { - "id": 3, + "equipId": 3, "lv": 58, "attr": "5&77" }, { - "id": 3, + "equipId": 3, "lv": 59, "attr": "5&78" }, { - "id": 3, + "equipId": 3, "lv": 60, "attr": "5&79" }, { - "id": 3, + "equipId": 3, "lv": 61, "attr": "5&80" }, { - "id": 3, + "equipId": 3, "lv": 62, "attr": "5&81" }, { - "id": 3, + "equipId": 3, "lv": 63, "attr": "5&82" }, { - "id": 3, + "equipId": 3, "lv": 64, "attr": "5&83" }, { - "id": 3, + "equipId": 3, "lv": 65, "attr": "5&84" }, { - "id": 3, + "equipId": 3, "lv": 66, "attr": "5&85" }, { - "id": 3, + "equipId": 3, "lv": 67, "attr": "5&86" }, { - "id": 3, + "equipId": 3, "lv": 68, "attr": "5&87" }, { - "id": 3, + "equipId": 3, "lv": 69, "attr": "5&88" }, { - "id": 3, + "equipId": 3, "lv": 70, "attr": "5&89" }, { - "id": 3, + "equipId": 3, "lv": 71, "attr": "5&90" }, { - "id": 3, + "equipId": 3, "lv": 72, "attr": "5&91" }, { - "id": 3, + "equipId": 3, "lv": 73, "attr": "5&92" }, { - "id": 3, + "equipId": 3, "lv": 74, "attr": "5&93" }, { - "id": 3, + "equipId": 3, "lv": 75, "attr": "5&94" }, { - "id": 3, + "equipId": 3, "lv": 76, "attr": "5&95" }, { - "id": 3, + "equipId": 3, "lv": 77, "attr": "5&96" }, { - "id": 3, + "equipId": 3, "lv": 78, "attr": "5&97" }, { - "id": 3, + "equipId": 3, "lv": 79, "attr": "5&98" }, { - "id": 3, + "equipId": 3, "lv": 80, "attr": "5&99" }, { - "id": 3, + "equipId": 3, "lv": 81, "attr": "5&100" }, { - "id": 3, + "equipId": 3, "lv": 82, "attr": "5&101" }, { - "id": 3, + "equipId": 3, "lv": 83, "attr": "5&102" }, { - "id": 3, + "equipId": 3, "lv": 84, "attr": "5&103" }, { - "id": 3, + "equipId": 3, "lv": 85, "attr": "5&104" }, { - "id": 3, + "equipId": 3, "lv": 86, "attr": "5&105" }, { - "id": 3, + "equipId": 3, "lv": 87, "attr": "5&106" }, { - "id": 3, + "equipId": 3, "lv": 88, "attr": "5&107" }, { - "id": 3, + "equipId": 3, "lv": 89, "attr": "5&108" }, { - "id": 3, + "equipId": 3, "lv": 90, "attr": "5&109" }, { - "id": 3, + "equipId": 3, "lv": 91, "attr": "5&110" }, { - "id": 3, + "equipId": 3, "lv": 92, "attr": "5&111" }, { - "id": 3, + "equipId": 3, "lv": 93, "attr": "5&112" }, { - "id": 3, + "equipId": 3, "lv": 94, "attr": "5&113" }, { - "id": 3, + "equipId": 3, "lv": 95, "attr": "5&114" }, { - "id": 3, + "equipId": 3, "lv": 96, "attr": "5&115" }, { - "id": 3, + "equipId": 3, "lv": 97, "attr": "5&116" }, { - "id": 3, + "equipId": 3, "lv": 98, "attr": "5&117" }, { - "id": 3, + "equipId": 3, "lv": 99, "attr": "5&118" }, { - "id": 3, + "equipId": 3, "lv": 100, "attr": "5&119" }, { - "id": 4, + "equipId": 4, + "lv": 0, + "attr": "1&49" + }, + { + "equipId": 4, "lv": 1, "attr": "1&50" }, { - "id": 4, + "equipId": 4, "lv": 2, "attr": "1&51" }, { - "id": 4, + "equipId": 4, "lv": 3, "attr": "1&52" }, { - "id": 4, + "equipId": 4, "lv": 4, "attr": "1&53" }, { - "id": 4, + "equipId": 4, "lv": 5, "attr": "1&54" }, { - "id": 4, + "equipId": 4, "lv": 6, "attr": "1&55" }, { - "id": 4, + "equipId": 4, "lv": 7, "attr": "1&56" }, { - "id": 4, + "equipId": 4, "lv": 8, "attr": "1&57" }, { - "id": 4, + "equipId": 4, "lv": 9, "attr": "1&58" }, { - "id": 4, + "equipId": 4, "lv": 10, "attr": "1&59" }, { - "id": 4, + "equipId": 4, "lv": 11, "attr": "1&60" }, { - "id": 4, + "equipId": 4, "lv": 12, "attr": "1&61" }, { - "id": 4, + "equipId": 4, "lv": 13, "attr": "1&62" }, { - "id": 4, + "equipId": 4, "lv": 14, "attr": "1&63" }, { - "id": 4, + "equipId": 4, "lv": 15, "attr": "1&64" }, { - "id": 4, + "equipId": 4, "lv": 16, "attr": "1&65" }, { - "id": 4, + "equipId": 4, "lv": 17, "attr": "1&66" }, { - "id": 4, + "equipId": 4, "lv": 18, "attr": "1&67" }, { - "id": 4, + "equipId": 4, "lv": 19, "attr": "1&68" }, { - "id": 4, + "equipId": 4, "lv": 20, "attr": "1&69" }, { - "id": 4, + "equipId": 4, "lv": 21, "attr": "1&70" }, { - "id": 4, + "equipId": 4, "lv": 22, "attr": "1&71" }, { - "id": 4, + "equipId": 4, "lv": 23, "attr": "1&72" }, { - "id": 4, + "equipId": 4, "lv": 24, "attr": "1&73" }, { - "id": 4, + "equipId": 4, "lv": 25, "attr": "1&74" }, { - "id": 4, + "equipId": 4, "lv": 26, "attr": "1&75" }, { - "id": 4, + "equipId": 4, "lv": 27, "attr": "1&76" }, { - "id": 4, + "equipId": 4, "lv": 28, "attr": "1&77" }, { - "id": 4, + "equipId": 4, "lv": 29, "attr": "1&78" }, { - "id": 4, + "equipId": 4, "lv": 30, "attr": "1&79" }, { - "id": 4, + "equipId": 4, "lv": 31, "attr": "1&80" }, { - "id": 4, + "equipId": 4, "lv": 32, "attr": "1&81" }, { - "id": 4, + "equipId": 4, "lv": 33, "attr": "1&82" }, { - "id": 4, + "equipId": 4, "lv": 34, "attr": "1&83" }, { - "id": 4, + "equipId": 4, "lv": 35, "attr": "1&84" }, { - "id": 4, + "equipId": 4, "lv": 36, "attr": "1&85" }, { - "id": 4, + "equipId": 4, "lv": 37, "attr": "1&86" }, { - "id": 4, + "equipId": 4, "lv": 38, "attr": "1&87" }, { - "id": 4, + "equipId": 4, "lv": 39, "attr": "1&88" }, { - "id": 4, + "equipId": 4, "lv": 40, "attr": "1&89" }, { - "id": 4, + "equipId": 4, "lv": 41, "attr": "1&90" }, { - "id": 4, + "equipId": 4, "lv": 42, "attr": "1&91" }, { - "id": 4, + "equipId": 4, "lv": 43, "attr": "1&92" }, { - "id": 4, + "equipId": 4, "lv": 44, "attr": "1&93" }, { - "id": 4, + "equipId": 4, "lv": 45, "attr": "1&94" }, { - "id": 4, + "equipId": 4, "lv": 46, "attr": "1&95" }, { - "id": 4, + "equipId": 4, "lv": 47, "attr": "1&96" }, { - "id": 4, + "equipId": 4, "lv": 48, "attr": "1&97" }, { - "id": 4, + "equipId": 4, "lv": 49, "attr": "1&98" }, { - "id": 4, + "equipId": 4, "lv": 50, "attr": "1&99" }, { - "id": 4, + "equipId": 4, "lv": 51, "attr": "1&100" }, { - "id": 4, + "equipId": 4, "lv": 52, "attr": "1&101" }, { - "id": 4, + "equipId": 4, "lv": 53, "attr": "1&102" }, { - "id": 4, + "equipId": 4, "lv": 54, "attr": "1&103" }, { - "id": 4, + "equipId": 4, "lv": 55, "attr": "1&104" }, { - "id": 4, + "equipId": 4, "lv": 56, "attr": "1&105" }, { - "id": 4, + "equipId": 4, "lv": 57, "attr": "1&106" }, { - "id": 4, + "equipId": 4, "lv": 58, "attr": "1&107" }, { - "id": 4, + "equipId": 4, "lv": 59, "attr": "1&108" }, { - "id": 4, + "equipId": 4, "lv": 60, "attr": "1&109" }, { - "id": 4, + "equipId": 4, "lv": 61, "attr": "1&110" }, { - "id": 4, + "equipId": 4, "lv": 62, "attr": "1&111" }, { - "id": 4, + "equipId": 4, "lv": 63, "attr": "1&112" }, { - "id": 4, + "equipId": 4, "lv": 64, "attr": "1&113" }, { - "id": 4, + "equipId": 4, "lv": 65, "attr": "1&114" }, { - "id": 4, + "equipId": 4, "lv": 66, "attr": "1&115" }, { - "id": 4, + "equipId": 4, "lv": 67, "attr": "1&116" }, { - "id": 4, + "equipId": 4, "lv": 68, "attr": "1&117" }, { - "id": 4, + "equipId": 4, "lv": 69, "attr": "1&118" }, { - "id": 4, + "equipId": 4, "lv": 70, "attr": "1&119" }, { - "id": 4, + "equipId": 4, "lv": 71, "attr": "1&120" }, { - "id": 4, + "equipId": 4, "lv": 72, "attr": "1&121" }, { - "id": 4, + "equipId": 4, "lv": 73, "attr": "1&122" }, { - "id": 4, + "equipId": 4, "lv": 74, "attr": "1&123" }, { - "id": 4, + "equipId": 4, "lv": 75, "attr": "1&124" }, { - "id": 4, + "equipId": 4, "lv": 76, "attr": "1&125" }, { - "id": 4, + "equipId": 4, "lv": 77, "attr": "1&126" }, { - "id": 4, + "equipId": 4, "lv": 78, "attr": "1&127" }, { - "id": 4, + "equipId": 4, "lv": 79, "attr": "1&128" }, { - "id": 4, + "equipId": 4, "lv": 80, "attr": "1&129" }, { - "id": 4, + "equipId": 4, "lv": 81, "attr": "1&130" }, { - "id": 4, + "equipId": 4, "lv": 82, "attr": "1&131" }, { - "id": 4, + "equipId": 4, "lv": 83, "attr": "1&132" }, { - "id": 4, + "equipId": 4, "lv": 84, "attr": "1&133" }, { - "id": 4, + "equipId": 4, "lv": 85, "attr": "1&134" }, { - "id": 4, + "equipId": 4, "lv": 86, "attr": "1&135" }, { - "id": 4, + "equipId": 4, "lv": 87, "attr": "1&136" }, { - "id": 4, + "equipId": 4, "lv": 88, "attr": "1&137" }, { - "id": 4, + "equipId": 4, "lv": 89, "attr": "1&138" }, { - "id": 4, + "equipId": 4, "lv": 90, "attr": "1&139" }, { - "id": 4, + "equipId": 4, "lv": 91, "attr": "1&140" }, { - "id": 4, + "equipId": 4, "lv": 92, "attr": "1&141" }, { - "id": 4, + "equipId": 4, "lv": 93, "attr": "1&142" }, { - "id": 4, + "equipId": 4, "lv": 94, "attr": "1&143" }, { - "id": 4, + "equipId": 4, "lv": 95, "attr": "1&144" }, { - "id": 4, + "equipId": 4, "lv": 96, "attr": "1&145" }, { - "id": 4, + "equipId": 4, "lv": 97, "attr": "1&146" }, { - "id": 4, + "equipId": 4, "lv": 98, "attr": "1&147" }, { - "id": 4, + "equipId": 4, "lv": 99, "attr": "1&148" }, { - "id": 4, + "equipId": 4, "lv": 100, "attr": "1&149" }, { - "id": 5, + "equipId": 5, + "lv": 0, + "attr": "2&10" + }, + { + "equipId": 5, "lv": 1, "attr": "2&10" }, { - "id": 5, + "equipId": 5, "lv": 2, "attr": "2&11" }, { - "id": 5, + "equipId": 5, "lv": 3, "attr": "2&12" }, { - "id": 5, + "equipId": 5, "lv": 4, "attr": "2&13" }, { - "id": 5, + "equipId": 5, "lv": 5, "attr": "2&14" }, { - "id": 5, + "equipId": 5, "lv": 6, "attr": "2&15" }, { - "id": 5, + "equipId": 5, "lv": 7, "attr": "2&16" }, { - "id": 5, + "equipId": 5, "lv": 8, "attr": "2&17" }, { - "id": 5, + "equipId": 5, "lv": 9, "attr": "2&18" }, { - "id": 5, + "equipId": 5, "lv": 10, "attr": "2&19" }, { - "id": 5, + "equipId": 5, "lv": 11, "attr": "2&20" }, { - "id": 5, + "equipId": 5, "lv": 12, "attr": "2&21" }, { - "id": 5, + "equipId": 5, "lv": 13, "attr": "2&22" }, { - "id": 5, + "equipId": 5, "lv": 14, "attr": "2&23" }, { - "id": 5, + "equipId": 5, "lv": 15, "attr": "2&24" }, { - "id": 5, + "equipId": 5, "lv": 16, "attr": "2&25" }, { - "id": 5, + "equipId": 5, "lv": 17, "attr": "2&26" }, { - "id": 5, + "equipId": 5, "lv": 18, "attr": "2&27" }, { - "id": 5, + "equipId": 5, "lv": 19, "attr": "2&28" }, { - "id": 5, + "equipId": 5, "lv": 20, "attr": "2&29" }, { - "id": 5, + "equipId": 5, "lv": 21, "attr": "2&30" }, { - "id": 5, + "equipId": 5, "lv": 22, "attr": "2&31" }, { - "id": 5, + "equipId": 5, "lv": 23, "attr": "2&32" }, { - "id": 5, + "equipId": 5, "lv": 24, "attr": "2&33" }, { - "id": 5, + "equipId": 5, "lv": 25, "attr": "2&34" }, { - "id": 5, + "equipId": 5, "lv": 26, "attr": "2&35" }, { - "id": 5, + "equipId": 5, "lv": 27, "attr": "2&36" }, { - "id": 5, + "equipId": 5, "lv": 28, "attr": "2&37" }, { - "id": 5, + "equipId": 5, "lv": 29, "attr": "2&38" }, { - "id": 5, + "equipId": 5, "lv": 30, "attr": "2&39" }, { - "id": 5, + "equipId": 5, "lv": 31, "attr": "2&40" }, { - "id": 5, + "equipId": 5, "lv": 32, "attr": "2&41" }, { - "id": 5, + "equipId": 5, "lv": 33, "attr": "2&42" }, { - "id": 5, + "equipId": 5, "lv": 34, "attr": "2&43" }, { - "id": 5, + "equipId": 5, "lv": 35, "attr": "2&44" }, { - "id": 5, + "equipId": 5, "lv": 36, "attr": "2&45" }, { - "id": 5, + "equipId": 5, "lv": 37, "attr": "2&46" }, { - "id": 5, + "equipId": 5, "lv": 38, "attr": "2&47" }, { - "id": 5, + "equipId": 5, "lv": 39, "attr": "2&48" }, { - "id": 5, + "equipId": 5, "lv": 40, "attr": "2&49" }, { - "id": 5, + "equipId": 5, "lv": 41, "attr": "2&50" }, { - "id": 5, + "equipId": 5, "lv": 42, "attr": "2&51" }, { - "id": 5, + "equipId": 5, "lv": 43, "attr": "2&52" }, { - "id": 5, + "equipId": 5, "lv": 44, "attr": "2&53" }, { - "id": 5, + "equipId": 5, "lv": 45, "attr": "2&54" }, { - "id": 5, + "equipId": 5, "lv": 46, "attr": "2&55" }, { - "id": 5, + "equipId": 5, "lv": 47, "attr": "2&56" }, { - "id": 5, + "equipId": 5, "lv": 48, "attr": "2&57" }, { - "id": 5, + "equipId": 5, "lv": 49, "attr": "2&58" }, { - "id": 5, + "equipId": 5, "lv": 50, "attr": "2&59" }, { - "id": 5, + "equipId": 5, "lv": 51, "attr": "2&60" }, { - "id": 5, + "equipId": 5, "lv": 52, "attr": "2&61" }, { - "id": 5, + "equipId": 5, "lv": 53, "attr": "2&62" }, { - "id": 5, + "equipId": 5, "lv": 54, "attr": "2&63" }, { - "id": 5, + "equipId": 5, "lv": 55, "attr": "2&64" }, { - "id": 5, + "equipId": 5, "lv": 56, "attr": "2&65" }, { - "id": 5, + "equipId": 5, "lv": 57, "attr": "2&66" }, { - "id": 5, + "equipId": 5, "lv": 58, "attr": "2&67" }, { - "id": 5, + "equipId": 5, "lv": 59, "attr": "2&68" }, { - "id": 5, + "equipId": 5, "lv": 60, "attr": "2&69" }, { - "id": 5, + "equipId": 5, "lv": 61, "attr": "2&70" }, { - "id": 5, + "equipId": 5, "lv": 62, "attr": "2&71" }, { - "id": 5, + "equipId": 5, "lv": 63, "attr": "2&72" }, { - "id": 5, + "equipId": 5, "lv": 64, "attr": "2&73" }, { - "id": 5, + "equipId": 5, "lv": 65, "attr": "2&74" }, { - "id": 5, + "equipId": 5, "lv": 66, "attr": "2&75" }, { - "id": 5, + "equipId": 5, "lv": 67, "attr": "2&76" }, { - "id": 5, + "equipId": 5, "lv": 68, "attr": "2&77" }, { - "id": 5, + "equipId": 5, "lv": 69, "attr": "2&78" }, { - "id": 5, + "equipId": 5, "lv": 70, "attr": "2&79" }, { - "id": 5, + "equipId": 5, "lv": 71, "attr": "2&80" }, { - "id": 5, + "equipId": 5, "lv": 72, "attr": "2&81" }, { - "id": 5, + "equipId": 5, "lv": 73, "attr": "2&82" }, { - "id": 5, + "equipId": 5, "lv": 74, "attr": "2&83" }, { - "id": 5, + "equipId": 5, "lv": 75, "attr": "2&84" }, { - "id": 5, + "equipId": 5, "lv": 76, "attr": "2&85" }, { - "id": 5, + "equipId": 5, "lv": 77, "attr": "2&86" }, { - "id": 5, + "equipId": 5, "lv": 78, "attr": "2&87" }, { - "id": 5, + "equipId": 5, "lv": 79, "attr": "2&88" }, { - "id": 5, + "equipId": 5, "lv": 80, "attr": "2&89" }, { - "id": 5, + "equipId": 5, "lv": 81, "attr": "2&90" }, { - "id": 5, + "equipId": 5, "lv": 82, "attr": "2&91" }, { - "id": 5, + "equipId": 5, "lv": 83, "attr": "2&92" }, { - "id": 5, + "equipId": 5, "lv": 84, "attr": "2&93" }, { - "id": 5, + "equipId": 5, "lv": 85, "attr": "2&94" }, { - "id": 5, + "equipId": 5, "lv": 86, "attr": "2&95" }, { - "id": 5, + "equipId": 5, "lv": 87, "attr": "2&96" }, { - "id": 5, + "equipId": 5, "lv": 88, "attr": "2&97" }, { - "id": 5, + "equipId": 5, "lv": 89, "attr": "2&98" }, { - "id": 5, + "equipId": 5, "lv": 90, "attr": "2&99" }, { - "id": 5, + "equipId": 5, "lv": 91, "attr": "2&100" }, { - "id": 5, + "equipId": 5, "lv": 92, "attr": "2&101" }, { - "id": 5, + "equipId": 5, "lv": 93, "attr": "2&102" }, { - "id": 5, + "equipId": 5, "lv": 94, "attr": "2&103" }, { - "id": 5, + "equipId": 5, "lv": 95, "attr": "2&104" }, { - "id": 5, + "equipId": 5, "lv": 96, "attr": "2&105" }, { - "id": 5, + "equipId": 5, "lv": 97, "attr": "2&106" }, { - "id": 5, + "equipId": 5, "lv": 98, "attr": "2&107" }, { - "id": 5, + "equipId": 5, "lv": 99, "attr": "2&108" }, { - "id": 5, + "equipId": 5, "lv": 100, "attr": "2&109" }, { - "id": 6, + "equipId": 6, + "lv": 0, + "attr": "4&20" + }, + { + "equipId": 6, "lv": 1, "attr": "4&20" }, { - "id": 6, + "equipId": 6, "lv": 2, "attr": "4&21" }, { - "id": 6, + "equipId": 6, "lv": 3, "attr": "4&22" }, { - "id": 6, + "equipId": 6, "lv": 4, "attr": "4&23" }, { - "id": 6, + "equipId": 6, "lv": 5, "attr": "4&24" }, { - "id": 6, + "equipId": 6, "lv": 6, "attr": "4&25" }, { - "id": 6, + "equipId": 6, "lv": 7, "attr": "4&26" }, { - "id": 6, + "equipId": 6, "lv": 8, "attr": "4&27" }, { - "id": 6, + "equipId": 6, "lv": 9, "attr": "4&28" }, { - "id": 6, + "equipId": 6, "lv": 10, "attr": "4&29" }, { - "id": 6, + "equipId": 6, "lv": 11, "attr": "4&30" }, { - "id": 6, + "equipId": 6, "lv": 12, "attr": "4&31" }, { - "id": 6, + "equipId": 6, "lv": 13, "attr": "4&32" }, { - "id": 6, + "equipId": 6, "lv": 14, "attr": "4&33" }, { - "id": 6, + "equipId": 6, "lv": 15, "attr": "4&34" }, { - "id": 6, + "equipId": 6, "lv": 16, "attr": "4&35" }, { - "id": 6, + "equipId": 6, "lv": 17, "attr": "4&36" }, { - "id": 6, + "equipId": 6, "lv": 18, "attr": "4&37" }, { - "id": 6, + "equipId": 6, "lv": 19, "attr": "4&38" }, { - "id": 6, + "equipId": 6, "lv": 20, "attr": "4&39" }, { - "id": 6, + "equipId": 6, "lv": 21, "attr": "4&40" }, { - "id": 6, + "equipId": 6, "lv": 22, "attr": "4&41" }, { - "id": 6, + "equipId": 6, "lv": 23, "attr": "4&42" }, { - "id": 6, + "equipId": 6, "lv": 24, "attr": "4&43" }, { - "id": 6, + "equipId": 6, "lv": 25, "attr": "4&44" }, { - "id": 6, + "equipId": 6, "lv": 26, "attr": "4&45" }, { - "id": 6, + "equipId": 6, "lv": 27, "attr": "4&46" }, { - "id": 6, + "equipId": 6, "lv": 28, "attr": "4&47" }, { - "id": 6, + "equipId": 6, "lv": 29, "attr": "4&48" }, { - "id": 6, + "equipId": 6, "lv": 30, "attr": "4&49" }, { - "id": 6, + "equipId": 6, "lv": 31, "attr": "4&50" }, { - "id": 6, + "equipId": 6, "lv": 32, "attr": "4&51" }, { - "id": 6, + "equipId": 6, "lv": 33, "attr": "4&52" }, { - "id": 6, + "equipId": 6, "lv": 34, "attr": "4&53" }, { - "id": 6, + "equipId": 6, "lv": 35, "attr": "4&54" }, { - "id": 6, + "equipId": 6, "lv": 36, "attr": "4&55" }, { - "id": 6, + "equipId": 6, "lv": 37, "attr": "4&56" }, { - "id": 6, + "equipId": 6, "lv": 38, "attr": "4&57" }, { - "id": 6, + "equipId": 6, "lv": 39, "attr": "4&58" }, { - "id": 6, + "equipId": 6, "lv": 40, "attr": "4&59" }, { - "id": 6, + "equipId": 6, "lv": 41, "attr": "4&60" }, { - "id": 6, + "equipId": 6, "lv": 42, "attr": "4&61" }, { - "id": 6, + "equipId": 6, "lv": 43, "attr": "4&62" }, { - "id": 6, + "equipId": 6, "lv": 44, "attr": "4&63" }, { - "id": 6, + "equipId": 6, "lv": 45, "attr": "4&64" }, { - "id": 6, + "equipId": 6, "lv": 46, "attr": "4&65" }, { - "id": 6, + "equipId": 6, "lv": 47, "attr": "4&66" }, { - "id": 6, + "equipId": 6, "lv": 48, "attr": "4&67" }, { - "id": 6, + "equipId": 6, "lv": 49, "attr": "4&68" }, { - "id": 6, + "equipId": 6, "lv": 50, "attr": "4&69" }, { - "id": 6, + "equipId": 6, "lv": 51, "attr": "4&70" }, { - "id": 6, + "equipId": 6, "lv": 52, "attr": "4&71" }, { - "id": 6, + "equipId": 6, "lv": 53, "attr": "4&72" }, { - "id": 6, + "equipId": 6, "lv": 54, "attr": "4&73" }, { - "id": 6, + "equipId": 6, "lv": 55, "attr": "4&74" }, { - "id": 6, + "equipId": 6, "lv": 56, "attr": "4&75" }, { - "id": 6, + "equipId": 6, "lv": 57, "attr": "4&76" }, { - "id": 6, + "equipId": 6, "lv": 58, "attr": "4&77" }, { - "id": 6, + "equipId": 6, "lv": 59, "attr": "4&78" }, { - "id": 6, + "equipId": 6, "lv": 60, "attr": "4&79" }, { - "id": 6, + "equipId": 6, "lv": 61, "attr": "4&80" }, { - "id": 6, + "equipId": 6, "lv": 62, "attr": "4&81" }, { - "id": 6, + "equipId": 6, "lv": 63, "attr": "4&82" }, { - "id": 6, + "equipId": 6, "lv": 64, "attr": "4&83" }, { - "id": 6, + "equipId": 6, "lv": 65, "attr": "4&84" }, { - "id": 6, + "equipId": 6, "lv": 66, "attr": "4&85" }, { - "id": 6, + "equipId": 6, "lv": 67, "attr": "4&86" }, { - "id": 6, + "equipId": 6, "lv": 68, "attr": "4&87" }, { - "id": 6, + "equipId": 6, "lv": 69, "attr": "4&88" }, { - "id": 6, + "equipId": 6, "lv": 70, "attr": "4&89" }, { - "id": 6, + "equipId": 6, "lv": 71, "attr": "4&90" }, { - "id": 6, + "equipId": 6, "lv": 72, "attr": "4&91" }, { - "id": 6, + "equipId": 6, "lv": 73, "attr": "4&92" }, { - "id": 6, + "equipId": 6, "lv": 74, "attr": "4&93" }, { - "id": 6, + "equipId": 6, "lv": 75, "attr": "4&94" }, { - "id": 6, + "equipId": 6, "lv": 76, "attr": "4&95" }, { - "id": 6, + "equipId": 6, "lv": 77, "attr": "4&96" }, { - "id": 6, + "equipId": 6, "lv": 78, "attr": "4&97" }, { - "id": 6, + "equipId": 6, "lv": 79, "attr": "4&98" }, { - "id": 6, + "equipId": 6, "lv": 80, "attr": "4&99" }, { - "id": 6, + "equipId": 6, "lv": 81, "attr": "4&100" }, { - "id": 6, + "equipId": 6, "lv": 82, "attr": "4&101" }, { - "id": 6, + "equipId": 6, "lv": 83, "attr": "4&102" }, { - "id": 6, + "equipId": 6, "lv": 84, "attr": "4&103" }, { - "id": 6, + "equipId": 6, "lv": 85, "attr": "4&104" }, { - "id": 6, + "equipId": 6, "lv": 86, "attr": "4&105" }, { - "id": 6, + "equipId": 6, "lv": 87, "attr": "4&106" }, { - "id": 6, + "equipId": 6, "lv": 88, "attr": "4&107" }, { - "id": 6, + "equipId": 6, "lv": 89, "attr": "4&108" }, { - "id": 6, + "equipId": 6, "lv": 90, "attr": "4&109" }, { - "id": 6, + "equipId": 6, "lv": 91, "attr": "4&110" }, { - "id": 6, + "equipId": 6, "lv": 92, "attr": "4&111" }, { - "id": 6, + "equipId": 6, "lv": 93, "attr": "4&112" }, { - "id": 6, + "equipId": 6, "lv": 94, "attr": "4&113" }, { - "id": 6, + "equipId": 6, "lv": 95, "attr": "4&114" }, { - "id": 6, + "equipId": 6, "lv": 96, "attr": "4&115" }, { - "id": 6, + "equipId": 6, "lv": 97, "attr": "4&116" }, { - "id": 6, + "equipId": 6, "lv": 98, "attr": "4&117" }, { - "id": 6, + "equipId": 6, "lv": 99, "attr": "4&118" }, { - "id": 6, + "equipId": 6, "lv": 100, "attr": "4&119" }, { - "id": 7, + "equipId": 7, + "lv": 0, + "attr": "5&20" + }, + { + "equipId": 7, "lv": 1, "attr": "5&20" }, { - "id": 7, + "equipId": 7, "lv": 2, "attr": "5&21" }, { - "id": 7, + "equipId": 7, "lv": 3, "attr": "5&22" }, { - "id": 7, + "equipId": 7, "lv": 4, "attr": "5&23" }, { - "id": 7, + "equipId": 7, "lv": 5, "attr": "5&24" }, { - "id": 7, + "equipId": 7, "lv": 6, "attr": "5&25" }, { - "id": 7, + "equipId": 7, "lv": 7, "attr": "5&26" }, { - "id": 7, + "equipId": 7, "lv": 8, "attr": "5&27" }, { - "id": 7, + "equipId": 7, "lv": 9, "attr": "5&28" }, { - "id": 7, + "equipId": 7, "lv": 10, "attr": "5&29" }, { - "id": 7, + "equipId": 7, "lv": 11, "attr": "5&30" }, { - "id": 7, + "equipId": 7, "lv": 12, "attr": "5&31" }, { - "id": 7, + "equipId": 7, "lv": 13, "attr": "5&32" }, { - "id": 7, + "equipId": 7, "lv": 14, "attr": "5&33" }, { - "id": 7, + "equipId": 7, "lv": 15, "attr": "5&34" }, { - "id": 7, + "equipId": 7, "lv": 16, "attr": "5&35" }, { - "id": 7, + "equipId": 7, "lv": 17, "attr": "5&36" }, { - "id": 7, + "equipId": 7, "lv": 18, "attr": "5&37" }, { - "id": 7, + "equipId": 7, "lv": 19, "attr": "5&38" }, { - "id": 7, + "equipId": 7, "lv": 20, "attr": "5&39" }, { - "id": 7, + "equipId": 7, "lv": 21, "attr": "5&40" }, { - "id": 7, + "equipId": 7, "lv": 22, "attr": "5&41" }, { - "id": 7, + "equipId": 7, "lv": 23, "attr": "5&42" }, { - "id": 7, + "equipId": 7, "lv": 24, "attr": "5&43" }, { - "id": 7, + "equipId": 7, "lv": 25, "attr": "5&44" }, { - "id": 7, + "equipId": 7, "lv": 26, "attr": "5&45" }, { - "id": 7, + "equipId": 7, "lv": 27, "attr": "5&46" }, { - "id": 7, + "equipId": 7, "lv": 28, "attr": "5&47" }, { - "id": 7, + "equipId": 7, "lv": 29, "attr": "5&48" }, { - "id": 7, + "equipId": 7, "lv": 30, "attr": "5&49" }, { - "id": 7, + "equipId": 7, "lv": 31, "attr": "5&50" }, { - "id": 7, + "equipId": 7, "lv": 32, "attr": "5&51" }, { - "id": 7, + "equipId": 7, "lv": 33, "attr": "5&52" }, { - "id": 7, + "equipId": 7, "lv": 34, "attr": "5&53" }, { - "id": 7, + "equipId": 7, "lv": 35, "attr": "5&54" }, { - "id": 7, + "equipId": 7, "lv": 36, "attr": "5&55" }, { - "id": 7, + "equipId": 7, "lv": 37, "attr": "5&56" }, { - "id": 7, + "equipId": 7, "lv": 38, "attr": "5&57" }, { - "id": 7, + "equipId": 7, "lv": 39, "attr": "5&58" }, { - "id": 7, + "equipId": 7, "lv": 40, "attr": "5&59" }, { - "id": 7, + "equipId": 7, "lv": 41, "attr": "5&60" }, { - "id": 7, + "equipId": 7, "lv": 42, "attr": "5&61" }, { - "id": 7, + "equipId": 7, "lv": 43, "attr": "5&62" }, { - "id": 7, + "equipId": 7, "lv": 44, "attr": "5&63" }, { - "id": 7, + "equipId": 7, "lv": 45, "attr": "5&64" }, { - "id": 7, + "equipId": 7, "lv": 46, "attr": "5&65" }, { - "id": 7, + "equipId": 7, "lv": 47, "attr": "5&66" }, { - "id": 7, + "equipId": 7, "lv": 48, "attr": "5&67" }, { - "id": 7, + "equipId": 7, "lv": 49, "attr": "5&68" }, { - "id": 7, + "equipId": 7, "lv": 50, "attr": "5&69" }, { - "id": 7, + "equipId": 7, "lv": 51, "attr": "5&70" }, { - "id": 7, + "equipId": 7, "lv": 52, "attr": "5&71" }, { - "id": 7, + "equipId": 7, "lv": 53, "attr": "5&72" }, { - "id": 7, + "equipId": 7, "lv": 54, "attr": "5&73" }, { - "id": 7, + "equipId": 7, "lv": 55, "attr": "5&74" }, { - "id": 7, + "equipId": 7, "lv": 56, "attr": "5&75" }, { - "id": 7, + "equipId": 7, "lv": 57, "attr": "5&76" }, { - "id": 7, + "equipId": 7, "lv": 58, "attr": "5&77" }, { - "id": 7, + "equipId": 7, "lv": 59, "attr": "5&78" }, { - "id": 7, + "equipId": 7, "lv": 60, "attr": "5&79" }, { - "id": 7, + "equipId": 7, "lv": 61, "attr": "5&80" }, { - "id": 7, + "equipId": 7, "lv": 62, "attr": "5&81" }, { - "id": 7, + "equipId": 7, "lv": 63, "attr": "5&82" }, { - "id": 7, + "equipId": 7, "lv": 64, "attr": "5&83" }, { - "id": 7, + "equipId": 7, "lv": 65, "attr": "5&84" }, { - "id": 7, + "equipId": 7, "lv": 66, "attr": "5&85" }, { - "id": 7, + "equipId": 7, "lv": 67, "attr": "5&86" }, { - "id": 7, + "equipId": 7, "lv": 68, "attr": "5&87" }, { - "id": 7, + "equipId": 7, "lv": 69, "attr": "5&88" }, { - "id": 7, + "equipId": 7, "lv": 70, "attr": "5&89" }, { - "id": 7, + "equipId": 7, "lv": 71, "attr": "5&90" }, { - "id": 7, + "equipId": 7, "lv": 72, "attr": "5&91" }, { - "id": 7, + "equipId": 7, "lv": 73, "attr": "5&92" }, { - "id": 7, + "equipId": 7, "lv": 74, "attr": "5&93" }, { - "id": 7, + "equipId": 7, "lv": 75, "attr": "5&94" }, { - "id": 7, + "equipId": 7, "lv": 76, "attr": "5&95" }, { - "id": 7, + "equipId": 7, "lv": 77, "attr": "5&96" }, { - "id": 7, + "equipId": 7, "lv": 78, "attr": "5&97" }, { - "id": 7, + "equipId": 7, "lv": 79, "attr": "5&98" }, { - "id": 7, + "equipId": 7, "lv": 80, "attr": "5&99" }, { - "id": 7, + "equipId": 7, "lv": 81, "attr": "5&100" }, { - "id": 7, + "equipId": 7, "lv": 82, "attr": "5&101" }, { - "id": 7, + "equipId": 7, "lv": 83, "attr": "5&102" }, { - "id": 7, + "equipId": 7, "lv": 84, "attr": "5&103" }, { - "id": 7, + "equipId": 7, "lv": 85, "attr": "5&104" }, { - "id": 7, + "equipId": 7, "lv": 86, "attr": "5&105" }, { - "id": 7, + "equipId": 7, "lv": 87, "attr": "5&106" }, { - "id": 7, + "equipId": 7, "lv": 88, "attr": "5&107" }, { - "id": 7, + "equipId": 7, "lv": 89, "attr": "5&108" }, { - "id": 7, + "equipId": 7, "lv": 90, "attr": "5&109" }, { - "id": 7, + "equipId": 7, "lv": 91, "attr": "5&110" }, { - "id": 7, + "equipId": 7, "lv": 92, "attr": "5&111" }, { - "id": 7, + "equipId": 7, "lv": 93, "attr": "5&112" }, { - "id": 7, + "equipId": 7, "lv": 94, "attr": "5&113" }, { - "id": 7, + "equipId": 7, "lv": 95, "attr": "5&114" }, { - "id": 7, + "equipId": 7, "lv": 96, "attr": "5&115" }, { - "id": 7, + "equipId": 7, "lv": 97, "attr": "5&116" }, { - "id": 7, + "equipId": 7, "lv": 98, "attr": "5&117" }, { - "id": 7, + "equipId": 7, "lv": 99, "attr": "5&118" }, { - "id": 7, + "equipId": 7, "lv": 100, "attr": "5&119" }, { - "id": 8, + "equipId": 8, + "lv": 0, + "attr": "1&50" + }, + { + "equipId": 8, "lv": 1, "attr": "1&50" }, { - "id": 8, + "equipId": 8, "lv": 2, "attr": "1&51" }, { - "id": 8, + "equipId": 8, "lv": 3, "attr": "1&52" }, { - "id": 8, + "equipId": 8, "lv": 4, "attr": "1&53" }, { - "id": 8, + "equipId": 8, "lv": 5, "attr": "1&54" }, { - "id": 8, + "equipId": 8, "lv": 6, "attr": "1&55" }, { - "id": 8, + "equipId": 8, "lv": 7, "attr": "1&56" }, { - "id": 8, + "equipId": 8, "lv": 8, "attr": "1&57" }, { - "id": 8, + "equipId": 8, "lv": 9, "attr": "1&58" }, { - "id": 8, + "equipId": 8, "lv": 10, "attr": "1&59" }, { - "id": 8, + "equipId": 8, "lv": 11, "attr": "1&60" }, { - "id": 8, + "equipId": 8, "lv": 12, "attr": "1&61" }, { - "id": 8, + "equipId": 8, "lv": 13, "attr": "1&62" }, { - "id": 8, + "equipId": 8, "lv": 14, "attr": "1&63" }, { - "id": 8, + "equipId": 8, "lv": 15, "attr": "1&64" }, { - "id": 8, + "equipId": 8, "lv": 16, "attr": "1&65" }, { - "id": 8, + "equipId": 8, "lv": 17, "attr": "1&66" }, { - "id": 8, + "equipId": 8, "lv": 18, "attr": "1&67" }, { - "id": 8, + "equipId": 8, "lv": 19, "attr": "1&68" }, { - "id": 8, + "equipId": 8, "lv": 20, "attr": "1&69" }, { - "id": 8, + "equipId": 8, "lv": 21, "attr": "1&70" }, { - "id": 8, + "equipId": 8, "lv": 22, "attr": "1&71" }, { - "id": 8, + "equipId": 8, "lv": 23, "attr": "1&72" }, { - "id": 8, + "equipId": 8, "lv": 24, "attr": "1&73" }, { - "id": 8, + "equipId": 8, "lv": 25, "attr": "1&74" }, { - "id": 8, + "equipId": 8, "lv": 26, "attr": "1&75" }, { - "id": 8, + "equipId": 8, "lv": 27, "attr": "1&76" }, { - "id": 8, + "equipId": 8, "lv": 28, "attr": "1&77" }, { - "id": 8, + "equipId": 8, "lv": 29, "attr": "1&78" }, { - "id": 8, + "equipId": 8, "lv": 30, "attr": "1&79" }, { - "id": 8, + "equipId": 8, "lv": 31, "attr": "1&80" }, { - "id": 8, + "equipId": 8, "lv": 32, "attr": "1&81" }, { - "id": 8, + "equipId": 8, "lv": 33, "attr": "1&82" }, { - "id": 8, + "equipId": 8, "lv": 34, "attr": "1&83" }, { - "id": 8, + "equipId": 8, "lv": 35, "attr": "1&84" }, { - "id": 8, + "equipId": 8, "lv": 36, "attr": "1&85" }, { - "id": 8, + "equipId": 8, "lv": 37, "attr": "1&86" }, { - "id": 8, + "equipId": 8, "lv": 38, "attr": "1&87" }, { - "id": 8, + "equipId": 8, "lv": 39, "attr": "1&88" }, { - "id": 8, + "equipId": 8, "lv": 40, "attr": "1&89" }, { - "id": 8, + "equipId": 8, "lv": 41, "attr": "1&90" }, { - "id": 8, + "equipId": 8, "lv": 42, "attr": "1&91" }, { - "id": 8, + "equipId": 8, "lv": 43, "attr": "1&92" }, { - "id": 8, + "equipId": 8, "lv": 44, "attr": "1&93" }, { - "id": 8, + "equipId": 8, "lv": 45, "attr": "1&94" }, { - "id": 8, + "equipId": 8, "lv": 46, "attr": "1&95" }, { - "id": 8, + "equipId": 8, "lv": 47, "attr": "1&96" }, { - "id": 8, + "equipId": 8, "lv": 48, "attr": "1&97" }, { - "id": 8, + "equipId": 8, "lv": 49, "attr": "1&98" }, { - "id": 8, + "equipId": 8, "lv": 50, "attr": "1&99" }, { - "id": 8, + "equipId": 8, "lv": 51, "attr": "1&100" }, { - "id": 8, + "equipId": 8, "lv": 52, "attr": "1&101" }, { - "id": 8, + "equipId": 8, "lv": 53, "attr": "1&102" }, { - "id": 8, + "equipId": 8, "lv": 54, "attr": "1&103" }, { - "id": 8, + "equipId": 8, "lv": 55, "attr": "1&104" }, { - "id": 8, + "equipId": 8, "lv": 56, "attr": "1&105" }, { - "id": 8, + "equipId": 8, "lv": 57, "attr": "1&106" }, { - "id": 8, + "equipId": 8, "lv": 58, "attr": "1&107" }, { - "id": 8, + "equipId": 8, "lv": 59, "attr": "1&108" }, { - "id": 8, + "equipId": 8, "lv": 60, "attr": "1&109" }, { - "id": 8, + "equipId": 8, "lv": 61, "attr": "1&110" }, { - "id": 8, + "equipId": 8, "lv": 62, "attr": "1&111" }, { - "id": 8, + "equipId": 8, "lv": 63, "attr": "1&112" }, { - "id": 8, + "equipId": 8, "lv": 64, "attr": "1&113" }, { - "id": 8, + "equipId": 8, "lv": 65, "attr": "1&114" }, { - "id": 8, + "equipId": 8, "lv": 66, "attr": "1&115" }, { - "id": 8, + "equipId": 8, "lv": 67, "attr": "1&116" }, { - "id": 8, + "equipId": 8, "lv": 68, "attr": "1&117" }, { - "id": 8, + "equipId": 8, "lv": 69, "attr": "1&118" }, { - "id": 8, + "equipId": 8, "lv": 70, "attr": "1&119" }, { - "id": 8, + "equipId": 8, "lv": 71, "attr": "1&120" }, { - "id": 8, + "equipId": 8, "lv": 72, "attr": "1&121" }, { - "id": 8, + "equipId": 8, "lv": 73, "attr": "1&122" }, { - "id": 8, + "equipId": 8, "lv": 74, "attr": "1&123" }, { - "id": 8, + "equipId": 8, "lv": 75, "attr": "1&124" }, { - "id": 8, + "equipId": 8, "lv": 76, "attr": "1&125" }, { - "id": 8, + "equipId": 8, "lv": 77, "attr": "1&126" }, { - "id": 8, + "equipId": 8, "lv": 78, "attr": "1&127" }, { - "id": 8, + "equipId": 8, "lv": 79, "attr": "1&128" }, { - "id": 8, + "equipId": 8, "lv": 80, "attr": "1&129" }, { - "id": 8, + "equipId": 8, "lv": 81, "attr": "1&130" }, { - "id": 8, + "equipId": 8, "lv": 82, "attr": "1&131" }, { - "id": 8, + "equipId": 8, "lv": 83, "attr": "1&132" }, { - "id": 8, + "equipId": 8, "lv": 84, "attr": "1&133" }, { - "id": 8, + "equipId": 8, "lv": 85, "attr": "1&134" }, { - "id": 8, + "equipId": 8, "lv": 86, "attr": "1&135" }, { - "id": 8, + "equipId": 8, "lv": 87, "attr": "1&136" }, { - "id": 8, + "equipId": 8, "lv": 88, "attr": "1&137" }, { - "id": 8, + "equipId": 8, "lv": 89, "attr": "1&138" }, { - "id": 8, + "equipId": 8, "lv": 90, "attr": "1&139" }, { - "id": 8, + "equipId": 8, "lv": 91, "attr": "1&140" }, { - "id": 8, + "equipId": 8, "lv": 92, "attr": "1&141" }, { - "id": 8, + "equipId": 8, "lv": 93, "attr": "1&142" }, { - "id": 8, + "equipId": 8, "lv": 94, "attr": "1&143" }, { - "id": 8, + "equipId": 8, "lv": 95, "attr": "1&144" }, { - "id": 8, + "equipId": 8, "lv": 96, "attr": "1&145" }, { - "id": 8, + "equipId": 8, "lv": 97, "attr": "1&146" }, { - "id": 8, + "equipId": 8, "lv": 98, "attr": "1&147" }, { - "id": 8, + "equipId": 8, "lv": 99, "attr": "1&148" }, { - "id": 8, + "equipId": 8, "lv": 100, "attr": "1&149" }, { - "id": 9, + "equipId": 9, + "lv": 0, + "attr": "2&10" + }, + { + "equipId": 9, "lv": 1, "attr": "2&10" }, { - "id": 9, + "equipId": 9, "lv": 2, "attr": "2&11" }, { - "id": 9, + "equipId": 9, "lv": 3, "attr": "2&12" }, { - "id": 9, + "equipId": 9, "lv": 4, "attr": "2&13" }, { - "id": 9, + "equipId": 9, "lv": 5, "attr": "2&14" }, { - "id": 9, + "equipId": 9, "lv": 6, "attr": "2&15" }, { - "id": 9, + "equipId": 9, "lv": 7, "attr": "2&16" }, { - "id": 9, + "equipId": 9, "lv": 8, "attr": "2&17" }, { - "id": 9, + "equipId": 9, "lv": 9, "attr": "2&18" }, { - "id": 9, + "equipId": 9, "lv": 10, "attr": "2&19" }, { - "id": 9, + "equipId": 9, "lv": 11, "attr": "2&20" }, { - "id": 9, + "equipId": 9, "lv": 12, "attr": "2&21" }, { - "id": 9, + "equipId": 9, "lv": 13, "attr": "2&22" }, { - "id": 9, + "equipId": 9, "lv": 14, "attr": "2&23" }, { - "id": 9, + "equipId": 9, "lv": 15, "attr": "2&24" }, { - "id": 9, + "equipId": 9, "lv": 16, "attr": "2&25" }, { - "id": 9, + "equipId": 9, "lv": 17, "attr": "2&26" }, { - "id": 9, + "equipId": 9, "lv": 18, "attr": "2&27" }, { - "id": 9, + "equipId": 9, "lv": 19, "attr": "2&28" }, { - "id": 9, + "equipId": 9, "lv": 20, "attr": "2&29" }, { - "id": 9, + "equipId": 9, "lv": 21, "attr": "2&30" }, { - "id": 9, + "equipId": 9, "lv": 22, "attr": "2&31" }, { - "id": 9, + "equipId": 9, "lv": 23, "attr": "2&32" }, { - "id": 9, + "equipId": 9, "lv": 24, "attr": "2&33" }, { - "id": 9, + "equipId": 9, "lv": 25, "attr": "2&34" }, { - "id": 9, + "equipId": 9, "lv": 26, "attr": "2&35" }, { - "id": 9, + "equipId": 9, "lv": 27, "attr": "2&36" }, { - "id": 9, + "equipId": 9, "lv": 28, "attr": "2&37" }, { - "id": 9, + "equipId": 9, "lv": 29, "attr": "2&38" }, { - "id": 9, + "equipId": 9, "lv": 30, "attr": "2&39" }, { - "id": 9, + "equipId": 9, "lv": 31, "attr": "2&40" }, { - "id": 9, + "equipId": 9, "lv": 32, "attr": "2&41" }, { - "id": 9, + "equipId": 9, "lv": 33, "attr": "2&42" }, { - "id": 9, + "equipId": 9, "lv": 34, "attr": "2&43" }, { - "id": 9, + "equipId": 9, "lv": 35, "attr": "2&44" }, { - "id": 9, + "equipId": 9, "lv": 36, "attr": "2&45" }, { - "id": 9, + "equipId": 9, "lv": 37, "attr": "2&46" }, { - "id": 9, + "equipId": 9, "lv": 38, "attr": "2&47" }, { - "id": 9, + "equipId": 9, "lv": 39, "attr": "2&48" }, { - "id": 9, + "equipId": 9, "lv": 40, "attr": "2&49" }, { - "id": 9, + "equipId": 9, "lv": 41, "attr": "2&50" }, { - "id": 9, + "equipId": 9, "lv": 42, "attr": "2&51" }, { - "id": 9, + "equipId": 9, "lv": 43, "attr": "2&52" }, { - "id": 9, + "equipId": 9, "lv": 44, "attr": "2&53" }, { - "id": 9, + "equipId": 9, "lv": 45, "attr": "2&54" }, { - "id": 9, + "equipId": 9, "lv": 46, "attr": "2&55" }, { - "id": 9, + "equipId": 9, "lv": 47, "attr": "2&56" }, { - "id": 9, + "equipId": 9, "lv": 48, "attr": "2&57" }, { - "id": 9, + "equipId": 9, "lv": 49, "attr": "2&58" }, { - "id": 9, + "equipId": 9, "lv": 50, "attr": "2&59" }, { - "id": 9, + "equipId": 9, "lv": 51, "attr": "2&60" }, { - "id": 9, + "equipId": 9, "lv": 52, "attr": "2&61" }, { - "id": 9, + "equipId": 9, "lv": 53, "attr": "2&62" }, { - "id": 9, + "equipId": 9, "lv": 54, "attr": "2&63" }, { - "id": 9, + "equipId": 9, "lv": 55, "attr": "2&64" }, { - "id": 9, + "equipId": 9, "lv": 56, "attr": "2&65" }, { - "id": 9, + "equipId": 9, "lv": 57, "attr": "2&66" }, { - "id": 9, + "equipId": 9, "lv": 58, "attr": "2&67" }, { - "id": 9, + "equipId": 9, "lv": 59, "attr": "2&68" }, { - "id": 9, + "equipId": 9, "lv": 60, "attr": "2&69" }, { - "id": 9, + "equipId": 9, "lv": 61, "attr": "2&70" }, { - "id": 9, + "equipId": 9, "lv": 62, "attr": "2&71" }, { - "id": 9, + "equipId": 9, "lv": 63, "attr": "2&72" }, { - "id": 9, + "equipId": 9, "lv": 64, "attr": "2&73" }, { - "id": 9, + "equipId": 9, "lv": 65, "attr": "2&74" }, { - "id": 9, + "equipId": 9, "lv": 66, "attr": "2&75" }, { - "id": 9, + "equipId": 9, "lv": 67, "attr": "2&76" }, { - "id": 9, + "equipId": 9, "lv": 68, "attr": "2&77" }, { - "id": 9, + "equipId": 9, "lv": 69, "attr": "2&78" }, { - "id": 9, + "equipId": 9, "lv": 70, "attr": "2&79" }, { - "id": 9, + "equipId": 9, "lv": 71, "attr": "2&80" }, { - "id": 9, + "equipId": 9, "lv": 72, "attr": "2&81" }, { - "id": 9, + "equipId": 9, "lv": 73, "attr": "2&82" }, { - "id": 9, + "equipId": 9, "lv": 74, "attr": "2&83" }, { - "id": 9, + "equipId": 9, "lv": 75, "attr": "2&84" }, { - "id": 9, + "equipId": 9, "lv": 76, "attr": "2&85" }, { - "id": 9, + "equipId": 9, "lv": 77, "attr": "2&86" }, { - "id": 9, + "equipId": 9, "lv": 78, "attr": "2&87" }, { - "id": 9, + "equipId": 9, "lv": 79, "attr": "2&88" }, { - "id": 9, + "equipId": 9, "lv": 80, "attr": "2&89" }, { - "id": 9, + "equipId": 9, "lv": 81, "attr": "2&90" }, { - "id": 9, + "equipId": 9, "lv": 82, "attr": "2&91" }, { - "id": 9, + "equipId": 9, "lv": 83, "attr": "2&92" }, { - "id": 9, + "equipId": 9, "lv": 84, "attr": "2&93" }, { - "id": 9, + "equipId": 9, "lv": 85, "attr": "2&94" }, { - "id": 9, + "equipId": 9, "lv": 86, "attr": "2&95" }, { - "id": 9, + "equipId": 9, "lv": 87, "attr": "2&96" }, { - "id": 9, + "equipId": 9, "lv": 88, "attr": "2&97" }, { - "id": 9, + "equipId": 9, "lv": 89, "attr": "2&98" }, { - "id": 9, + "equipId": 9, "lv": 90, "attr": "2&99" }, { - "id": 9, + "equipId": 9, "lv": 91, "attr": "2&100" }, { - "id": 9, + "equipId": 9, "lv": 92, "attr": "2&101" }, { - "id": 9, + "equipId": 9, "lv": 93, "attr": "2&102" }, { - "id": 9, + "equipId": 9, "lv": 94, "attr": "2&103" }, { - "id": 9, + "equipId": 9, "lv": 95, "attr": "2&104" }, { - "id": 9, + "equipId": 9, "lv": 96, "attr": "2&105" }, { - "id": 9, + "equipId": 9, "lv": 97, "attr": "2&106" }, { - "id": 9, + "equipId": 9, "lv": 98, "attr": "2&107" }, { - "id": 9, + "equipId": 9, "lv": 99, "attr": "2&108" }, { - "id": 9, + "equipId": 9, "lv": 100, "attr": "2&109" }, { - "id": 10, + "equipId": 10, + "lv": 0, + "attr": "4&20" + }, + { + "equipId": 10, "lv": 1, "attr": "4&20" }, { - "id": 10, + "equipId": 10, "lv": 2, "attr": "4&21" }, { - "id": 10, + "equipId": 10, "lv": 3, "attr": "4&22" }, { - "id": 10, + "equipId": 10, "lv": 4, "attr": "4&23" }, { - "id": 10, + "equipId": 10, "lv": 5, "attr": "4&24" }, { - "id": 10, + "equipId": 10, "lv": 6, "attr": "4&25" }, { - "id": 10, + "equipId": 10, "lv": 7, "attr": "4&26" }, { - "id": 10, + "equipId": 10, "lv": 8, "attr": "4&27" }, { - "id": 10, + "equipId": 10, "lv": 9, "attr": "4&28" }, { - "id": 10, + "equipId": 10, "lv": 10, "attr": "4&29" }, { - "id": 10, + "equipId": 10, "lv": 11, "attr": "4&30" }, { - "id": 10, + "equipId": 10, "lv": 12, "attr": "4&31" }, { - "id": 10, + "equipId": 10, "lv": 13, "attr": "4&32" }, { - "id": 10, + "equipId": 10, "lv": 14, "attr": "4&33" }, { - "id": 10, + "equipId": 10, "lv": 15, "attr": "4&34" }, { - "id": 10, + "equipId": 10, "lv": 16, "attr": "4&35" }, { - "id": 10, + "equipId": 10, "lv": 17, "attr": "4&36" }, { - "id": 10, + "equipId": 10, "lv": 18, "attr": "4&37" }, { - "id": 10, + "equipId": 10, "lv": 19, "attr": "4&38" }, { - "id": 10, + "equipId": 10, "lv": 20, "attr": "4&39" }, { - "id": 10, + "equipId": 10, "lv": 21, "attr": "4&40" }, { - "id": 10, + "equipId": 10, "lv": 22, "attr": "4&41" }, { - "id": 10, + "equipId": 10, "lv": 23, "attr": "4&42" }, { - "id": 10, + "equipId": 10, "lv": 24, "attr": "4&43" }, { - "id": 10, + "equipId": 10, "lv": 25, "attr": "4&44" }, { - "id": 10, + "equipId": 10, "lv": 26, "attr": "4&45" }, { - "id": 10, + "equipId": 10, "lv": 27, "attr": "4&46" }, { - "id": 10, + "equipId": 10, "lv": 28, "attr": "4&47" }, { - "id": 10, + "equipId": 10, "lv": 29, "attr": "4&48" }, { - "id": 10, + "equipId": 10, "lv": 30, "attr": "4&49" }, { - "id": 10, + "equipId": 10, "lv": 31, "attr": "4&50" }, { - "id": 10, + "equipId": 10, "lv": 32, "attr": "4&51" }, { - "id": 10, + "equipId": 10, "lv": 33, "attr": "4&52" }, { - "id": 10, + "equipId": 10, "lv": 34, "attr": "4&53" }, { - "id": 10, + "equipId": 10, "lv": 35, "attr": "4&54" }, { - "id": 10, + "equipId": 10, "lv": 36, "attr": "4&55" }, { - "id": 10, + "equipId": 10, "lv": 37, "attr": "4&56" }, { - "id": 10, + "equipId": 10, "lv": 38, "attr": "4&57" }, { - "id": 10, + "equipId": 10, "lv": 39, "attr": "4&58" }, { - "id": 10, + "equipId": 10, "lv": 40, "attr": "4&59" }, { - "id": 10, + "equipId": 10, "lv": 41, "attr": "4&60" }, { - "id": 10, + "equipId": 10, "lv": 42, "attr": "4&61" }, { - "id": 10, + "equipId": 10, "lv": 43, "attr": "4&62" }, { - "id": 10, + "equipId": 10, "lv": 44, "attr": "4&63" }, { - "id": 10, + "equipId": 10, "lv": 45, "attr": "4&64" }, { - "id": 10, + "equipId": 10, "lv": 46, "attr": "4&65" }, { - "id": 10, + "equipId": 10, "lv": 47, "attr": "4&66" }, { - "id": 10, + "equipId": 10, "lv": 48, "attr": "4&67" }, { - "id": 10, + "equipId": 10, "lv": 49, "attr": "4&68" }, { - "id": 10, + "equipId": 10, "lv": 50, "attr": "4&69" }, { - "id": 10, + "equipId": 10, "lv": 51, "attr": "4&70" }, { - "id": 10, + "equipId": 10, "lv": 52, "attr": "4&71" }, { - "id": 10, + "equipId": 10, "lv": 53, "attr": "4&72" }, { - "id": 10, + "equipId": 10, "lv": 54, "attr": "4&73" }, { - "id": 10, + "equipId": 10, "lv": 55, "attr": "4&74" }, { - "id": 10, + "equipId": 10, "lv": 56, "attr": "4&75" }, { - "id": 10, + "equipId": 10, "lv": 57, "attr": "4&76" }, { - "id": 10, + "equipId": 10, "lv": 58, "attr": "4&77" }, { - "id": 10, + "equipId": 10, "lv": 59, "attr": "4&78" }, { - "id": 10, + "equipId": 10, "lv": 60, "attr": "4&79" }, { - "id": 10, + "equipId": 10, "lv": 61, "attr": "4&80" }, { - "id": 10, + "equipId": 10, "lv": 62, "attr": "4&81" }, { - "id": 10, + "equipId": 10, "lv": 63, "attr": "4&82" }, { - "id": 10, + "equipId": 10, "lv": 64, "attr": "4&83" }, { - "id": 10, + "equipId": 10, "lv": 65, "attr": "4&84" }, { - "id": 10, + "equipId": 10, "lv": 66, "attr": "4&85" }, { - "id": 10, + "equipId": 10, "lv": 67, "attr": "4&86" }, { - "id": 10, + "equipId": 10, "lv": 68, "attr": "4&87" }, { - "id": 10, + "equipId": 10, "lv": 69, "attr": "4&88" }, { - "id": 10, + "equipId": 10, "lv": 70, "attr": "4&89" }, { - "id": 10, + "equipId": 10, "lv": 71, "attr": "4&90" }, { - "id": 10, + "equipId": 10, "lv": 72, "attr": "4&91" }, { - "id": 10, + "equipId": 10, "lv": 73, "attr": "4&92" }, { - "id": 10, + "equipId": 10, "lv": 74, "attr": "4&93" }, { - "id": 10, + "equipId": 10, "lv": 75, "attr": "4&94" }, { - "id": 10, + "equipId": 10, "lv": 76, "attr": "4&95" }, { - "id": 10, + "equipId": 10, "lv": 77, "attr": "4&96" }, { - "id": 10, + "equipId": 10, "lv": 78, "attr": "4&97" }, { - "id": 10, + "equipId": 10, "lv": 79, "attr": "4&98" }, { - "id": 10, + "equipId": 10, "lv": 80, "attr": "4&99" }, { - "id": 10, + "equipId": 10, "lv": 81, "attr": "4&100" }, { - "id": 10, + "equipId": 10, "lv": 82, "attr": "4&101" }, { - "id": 10, + "equipId": 10, "lv": 83, "attr": "4&102" }, { - "id": 10, + "equipId": 10, "lv": 84, "attr": "4&103" }, { - "id": 10, + "equipId": 10, "lv": 85, "attr": "4&104" }, { - "id": 10, + "equipId": 10, "lv": 86, "attr": "4&105" }, { - "id": 10, + "equipId": 10, "lv": 87, "attr": "4&106" }, { - "id": 10, + "equipId": 10, "lv": 88, "attr": "4&107" }, { - "id": 10, + "equipId": 10, "lv": 89, "attr": "4&108" }, { - "id": 10, + "equipId": 10, "lv": 90, "attr": "4&109" }, { - "id": 10, + "equipId": 10, "lv": 91, "attr": "4&110" }, { - "id": 10, + "equipId": 10, "lv": 92, "attr": "4&111" }, { - "id": 10, + "equipId": 10, "lv": 93, "attr": "4&112" }, { - "id": 10, + "equipId": 10, "lv": 94, "attr": "4&113" }, { - "id": 10, + "equipId": 10, "lv": 95, "attr": "4&114" }, { - "id": 10, + "equipId": 10, "lv": 96, "attr": "4&115" }, { - "id": 10, + "equipId": 10, "lv": 97, "attr": "4&116" }, { - "id": 10, + "equipId": 10, "lv": 98, "attr": "4&117" }, { - "id": 10, + "equipId": 10, "lv": 99, "attr": "4&118" }, { - "id": 10, + "equipId": 10, "lv": 100, "attr": "4&119" }, { - "id": 11, + "equipId": 11, + "lv": 0, + "attr": "5&20" + }, + { + "equipId": 11, "lv": 1, "attr": "5&20" }, { - "id": 11, + "equipId": 11, "lv": 2, "attr": "5&21" }, { - "id": 11, + "equipId": 11, "lv": 3, "attr": "5&22" }, { - "id": 11, + "equipId": 11, "lv": 4, "attr": "5&23" }, { - "id": 11, + "equipId": 11, "lv": 5, "attr": "5&24" }, { - "id": 11, + "equipId": 11, "lv": 6, "attr": "5&25" }, { - "id": 11, + "equipId": 11, "lv": 7, "attr": "5&26" }, { - "id": 11, + "equipId": 11, "lv": 8, "attr": "5&27" }, { - "id": 11, + "equipId": 11, "lv": 9, "attr": "5&28" }, { - "id": 11, + "equipId": 11, "lv": 10, "attr": "5&29" }, { - "id": 11, + "equipId": 11, "lv": 11, "attr": "5&30" }, { - "id": 11, + "equipId": 11, "lv": 12, "attr": "5&31" }, { - "id": 11, + "equipId": 11, "lv": 13, "attr": "5&32" }, { - "id": 11, + "equipId": 11, "lv": 14, "attr": "5&33" }, { - "id": 11, + "equipId": 11, "lv": 15, "attr": "5&34" }, { - "id": 11, + "equipId": 11, "lv": 16, "attr": "5&35" }, { - "id": 11, + "equipId": 11, "lv": 17, "attr": "5&36" }, { - "id": 11, + "equipId": 11, "lv": 18, "attr": "5&37" }, { - "id": 11, + "equipId": 11, "lv": 19, "attr": "5&38" }, { - "id": 11, + "equipId": 11, "lv": 20, "attr": "5&39" }, { - "id": 11, + "equipId": 11, "lv": 21, "attr": "5&40" }, { - "id": 11, + "equipId": 11, "lv": 22, "attr": "5&41" }, { - "id": 11, + "equipId": 11, "lv": 23, "attr": "5&42" }, { - "id": 11, + "equipId": 11, "lv": 24, "attr": "5&43" }, { - "id": 11, + "equipId": 11, "lv": 25, "attr": "5&44" }, { - "id": 11, + "equipId": 11, "lv": 26, "attr": "5&45" }, { - "id": 11, + "equipId": 11, "lv": 27, "attr": "5&46" }, { - "id": 11, + "equipId": 11, "lv": 28, "attr": "5&47" }, { - "id": 11, + "equipId": 11, "lv": 29, "attr": "5&48" }, { - "id": 11, + "equipId": 11, "lv": 30, "attr": "5&49" }, { - "id": 11, + "equipId": 11, "lv": 31, "attr": "5&50" }, { - "id": 11, + "equipId": 11, "lv": 32, "attr": "5&51" }, { - "id": 11, + "equipId": 11, "lv": 33, "attr": "5&52" }, { - "id": 11, + "equipId": 11, "lv": 34, "attr": "5&53" }, { - "id": 11, + "equipId": 11, "lv": 35, "attr": "5&54" }, { - "id": 11, + "equipId": 11, "lv": 36, "attr": "5&55" }, { - "id": 11, + "equipId": 11, "lv": 37, "attr": "5&56" }, { - "id": 11, + "equipId": 11, "lv": 38, "attr": "5&57" }, { - "id": 11, + "equipId": 11, "lv": 39, "attr": "5&58" }, { - "id": 11, + "equipId": 11, "lv": 40, "attr": "5&59" }, { - "id": 11, + "equipId": 11, "lv": 41, "attr": "5&60" }, { - "id": 11, + "equipId": 11, "lv": 42, "attr": "5&61" }, { - "id": 11, + "equipId": 11, "lv": 43, "attr": "5&62" }, { - "id": 11, + "equipId": 11, "lv": 44, "attr": "5&63" }, { - "id": 11, + "equipId": 11, "lv": 45, "attr": "5&64" }, { - "id": 11, + "equipId": 11, "lv": 46, "attr": "5&65" }, { - "id": 11, + "equipId": 11, "lv": 47, "attr": "5&66" }, { - "id": 11, + "equipId": 11, "lv": 48, "attr": "5&67" }, { - "id": 11, + "equipId": 11, "lv": 49, "attr": "5&68" }, { - "id": 11, + "equipId": 11, "lv": 50, "attr": "5&69" }, { - "id": 11, + "equipId": 11, "lv": 51, "attr": "5&70" }, { - "id": 11, + "equipId": 11, "lv": 52, "attr": "5&71" }, { - "id": 11, + "equipId": 11, "lv": 53, "attr": "5&72" }, { - "id": 11, + "equipId": 11, "lv": 54, "attr": "5&73" }, { - "id": 11, + "equipId": 11, "lv": 55, "attr": "5&74" }, { - "id": 11, + "equipId": 11, "lv": 56, "attr": "5&75" }, { - "id": 11, + "equipId": 11, "lv": 57, "attr": "5&76" }, { - "id": 11, + "equipId": 11, "lv": 58, "attr": "5&77" }, { - "id": 11, + "equipId": 11, "lv": 59, "attr": "5&78" }, { - "id": 11, + "equipId": 11, "lv": 60, "attr": "5&79" }, { - "id": 11, + "equipId": 11, "lv": 61, "attr": "5&80" }, { - "id": 11, + "equipId": 11, "lv": 62, "attr": "5&81" }, { - "id": 11, + "equipId": 11, "lv": 63, "attr": "5&82" }, { - "id": 11, + "equipId": 11, "lv": 64, "attr": "5&83" }, { - "id": 11, + "equipId": 11, "lv": 65, "attr": "5&84" }, { - "id": 11, + "equipId": 11, "lv": 66, "attr": "5&85" }, { - "id": 11, + "equipId": 11, "lv": 67, "attr": "5&86" }, { - "id": 11, + "equipId": 11, "lv": 68, "attr": "5&87" }, { - "id": 11, + "equipId": 11, "lv": 69, "attr": "5&88" }, { - "id": 11, + "equipId": 11, "lv": 70, "attr": "5&89" }, { - "id": 11, + "equipId": 11, "lv": 71, "attr": "5&90" }, { - "id": 11, + "equipId": 11, "lv": 72, "attr": "5&91" }, { - "id": 11, + "equipId": 11, "lv": 73, "attr": "5&92" }, { - "id": 11, + "equipId": 11, "lv": 74, "attr": "5&93" }, { - "id": 11, + "equipId": 11, "lv": 75, "attr": "5&94" }, { - "id": 11, + "equipId": 11, "lv": 76, "attr": "5&95" }, { - "id": 11, + "equipId": 11, "lv": 77, "attr": "5&96" }, { - "id": 11, + "equipId": 11, "lv": 78, "attr": "5&97" }, { - "id": 11, + "equipId": 11, "lv": 79, "attr": "5&98" }, { - "id": 11, + "equipId": 11, "lv": 80, "attr": "5&99" }, { - "id": 11, + "equipId": 11, "lv": 81, "attr": "5&100" }, { - "id": 11, + "equipId": 11, "lv": 82, "attr": "5&101" }, { - "id": 11, + "equipId": 11, "lv": 83, "attr": "5&102" }, { - "id": 11, + "equipId": 11, "lv": 84, "attr": "5&103" }, { - "id": 11, + "equipId": 11, "lv": 85, "attr": "5&104" }, { - "id": 11, + "equipId": 11, "lv": 86, "attr": "5&105" }, { - "id": 11, + "equipId": 11, "lv": 87, "attr": "5&106" }, { - "id": 11, + "equipId": 11, "lv": 88, "attr": "5&107" }, { - "id": 11, + "equipId": 11, "lv": 89, "attr": "5&108" }, { - "id": 11, + "equipId": 11, "lv": 90, "attr": "5&109" }, { - "id": 11, + "equipId": 11, "lv": 91, "attr": "5&110" }, { - "id": 11, + "equipId": 11, "lv": 92, "attr": "5&111" }, { - "id": 11, + "equipId": 11, "lv": 93, "attr": "5&112" }, { - "id": 11, + "equipId": 11, "lv": 94, "attr": "5&113" }, { - "id": 11, + "equipId": 11, "lv": 95, "attr": "5&114" }, { - "id": 11, + "equipId": 11, "lv": 96, "attr": "5&115" }, { - "id": 11, + "equipId": 11, "lv": 97, "attr": "5&116" }, { - "id": 11, + "equipId": 11, "lv": 98, "attr": "5&117" }, { - "id": 11, + "equipId": 11, "lv": 99, "attr": "5&118" }, { - "id": 11, + "equipId": 11, "lv": 100, "attr": "5&119" }, { - "id": 12, + "equipId": 12, + "lv": 0, + "attr": "1&50" + }, + { + "equipId": 12, "lv": 1, "attr": "1&50" }, { - "id": 12, + "equipId": 12, "lv": 2, "attr": "1&51" }, { - "id": 12, + "equipId": 12, "lv": 3, "attr": "1&52" }, { - "id": 12, + "equipId": 12, "lv": 4, "attr": "1&53" }, { - "id": 12, + "equipId": 12, "lv": 5, "attr": "1&54" }, { - "id": 12, + "equipId": 12, "lv": 6, "attr": "1&55" }, { - "id": 12, + "equipId": 12, "lv": 7, "attr": "1&56" }, { - "id": 12, + "equipId": 12, "lv": 8, "attr": "1&57" }, { - "id": 12, + "equipId": 12, "lv": 9, "attr": "1&58" }, { - "id": 12, + "equipId": 12, "lv": 10, "attr": "1&59" }, { - "id": 12, + "equipId": 12, "lv": 11, "attr": "1&60" }, { - "id": 12, + "equipId": 12, "lv": 12, "attr": "1&61" }, { - "id": 12, + "equipId": 12, "lv": 13, "attr": "1&62" }, { - "id": 12, + "equipId": 12, "lv": 14, "attr": "1&63" }, { - "id": 12, + "equipId": 12, "lv": 15, "attr": "1&64" }, { - "id": 12, + "equipId": 12, "lv": 16, "attr": "1&65" }, { - "id": 12, + "equipId": 12, "lv": 17, "attr": "1&66" }, { - "id": 12, + "equipId": 12, "lv": 18, "attr": "1&67" }, { - "id": 12, + "equipId": 12, "lv": 19, "attr": "1&68" }, { - "id": 12, + "equipId": 12, "lv": 20, "attr": "1&69" }, { - "id": 12, + "equipId": 12, "lv": 21, "attr": "1&70" }, { - "id": 12, + "equipId": 12, "lv": 22, "attr": "1&71" }, { - "id": 12, + "equipId": 12, "lv": 23, "attr": "1&72" }, { - "id": 12, + "equipId": 12, "lv": 24, "attr": "1&73" }, { - "id": 12, + "equipId": 12, "lv": 25, "attr": "1&74" }, { - "id": 12, + "equipId": 12, "lv": 26, "attr": "1&75" }, { - "id": 12, + "equipId": 12, "lv": 27, "attr": "1&76" }, { - "id": 12, + "equipId": 12, "lv": 28, "attr": "1&77" }, { - "id": 12, + "equipId": 12, "lv": 29, "attr": "1&78" }, { - "id": 12, + "equipId": 12, "lv": 30, "attr": "1&79" }, { - "id": 12, + "equipId": 12, "lv": 31, "attr": "1&80" }, { - "id": 12, + "equipId": 12, "lv": 32, "attr": "1&81" }, { - "id": 12, + "equipId": 12, "lv": 33, "attr": "1&82" }, { - "id": 12, + "equipId": 12, "lv": 34, "attr": "1&83" }, { - "id": 12, + "equipId": 12, "lv": 35, "attr": "1&84" }, { - "id": 12, + "equipId": 12, "lv": 36, "attr": "1&85" }, { - "id": 12, + "equipId": 12, "lv": 37, "attr": "1&86" }, { - "id": 12, + "equipId": 12, "lv": 38, "attr": "1&87" }, { - "id": 12, + "equipId": 12, "lv": 39, "attr": "1&88" }, { - "id": 12, + "equipId": 12, "lv": 40, "attr": "1&89" }, { - "id": 12, + "equipId": 12, "lv": 41, "attr": "1&90" }, { - "id": 12, + "equipId": 12, "lv": 42, "attr": "1&91" }, { - "id": 12, + "equipId": 12, "lv": 43, "attr": "1&92" }, { - "id": 12, + "equipId": 12, "lv": 44, "attr": "1&93" }, { - "id": 12, + "equipId": 12, "lv": 45, "attr": "1&94" }, { - "id": 12, + "equipId": 12, "lv": 46, "attr": "1&95" }, { - "id": 12, + "equipId": 12, "lv": 47, "attr": "1&96" }, { - "id": 12, + "equipId": 12, "lv": 48, "attr": "1&97" }, { - "id": 12, + "equipId": 12, "lv": 49, "attr": "1&98" }, { - "id": 12, + "equipId": 12, "lv": 50, "attr": "1&99" }, { - "id": 12, + "equipId": 12, "lv": 51, "attr": "1&100" }, { - "id": 12, + "equipId": 12, "lv": 52, "attr": "1&101" }, { - "id": 12, + "equipId": 12, "lv": 53, "attr": "1&102" }, { - "id": 12, + "equipId": 12, "lv": 54, "attr": "1&103" }, { - "id": 12, + "equipId": 12, "lv": 55, "attr": "1&104" }, { - "id": 12, + "equipId": 12, "lv": 56, "attr": "1&105" }, { - "id": 12, + "equipId": 12, "lv": 57, "attr": "1&106" }, { - "id": 12, + "equipId": 12, "lv": 58, "attr": "1&107" }, { - "id": 12, + "equipId": 12, "lv": 59, "attr": "1&108" }, { - "id": 12, + "equipId": 12, "lv": 60, "attr": "1&109" }, { - "id": 12, + "equipId": 12, "lv": 61, "attr": "1&110" }, { - "id": 12, + "equipId": 12, "lv": 62, "attr": "1&111" }, { - "id": 12, + "equipId": 12, "lv": 63, "attr": "1&112" }, { - "id": 12, + "equipId": 12, "lv": 64, "attr": "1&113" }, { - "id": 12, + "equipId": 12, "lv": 65, "attr": "1&114" }, { - "id": 12, + "equipId": 12, "lv": 66, "attr": "1&115" }, { - "id": 12, + "equipId": 12, "lv": 67, "attr": "1&116" }, { - "id": 12, + "equipId": 12, "lv": 68, "attr": "1&117" }, { - "id": 12, + "equipId": 12, "lv": 69, "attr": "1&118" }, { - "id": 12, + "equipId": 12, "lv": 70, "attr": "1&119" }, { - "id": 12, + "equipId": 12, "lv": 71, "attr": "1&120" }, { - "id": 12, + "equipId": 12, "lv": 72, "attr": "1&121" }, { - "id": 12, + "equipId": 12, "lv": 73, "attr": "1&122" }, { - "id": 12, + "equipId": 12, "lv": 74, "attr": "1&123" }, { - "id": 12, + "equipId": 12, "lv": 75, "attr": "1&124" }, { - "id": 12, + "equipId": 12, "lv": 76, "attr": "1&125" }, { - "id": 12, + "equipId": 12, "lv": 77, "attr": "1&126" }, { - "id": 12, + "equipId": 12, "lv": 78, "attr": "1&127" }, { - "id": 12, + "equipId": 12, "lv": 79, "attr": "1&128" }, { - "id": 12, + "equipId": 12, "lv": 80, "attr": "1&129" }, { - "id": 12, + "equipId": 12, "lv": 81, "attr": "1&130" }, { - "id": 12, + "equipId": 12, "lv": 82, "attr": "1&131" }, { - "id": 12, + "equipId": 12, "lv": 83, "attr": "1&132" }, { - "id": 12, + "equipId": 12, "lv": 84, "attr": "1&133" }, { - "id": 12, + "equipId": 12, "lv": 85, "attr": "1&134" }, { - "id": 12, + "equipId": 12, "lv": 86, "attr": "1&135" }, { - "id": 12, + "equipId": 12, "lv": 87, "attr": "1&136" }, { - "id": 12, + "equipId": 12, "lv": 88, "attr": "1&137" }, { - "id": 12, + "equipId": 12, "lv": 89, "attr": "1&138" }, { - "id": 12, + "equipId": 12, "lv": 90, "attr": "1&139" }, { - "id": 12, + "equipId": 12, "lv": 91, "attr": "1&140" }, { - "id": 12, + "equipId": 12, "lv": 92, "attr": "1&141" }, { - "id": 12, + "equipId": 12, "lv": 93, "attr": "1&142" }, { - "id": 12, + "equipId": 12, "lv": 94, "attr": "1&143" }, { - "id": 12, + "equipId": 12, "lv": 95, "attr": "1&144" }, { - "id": 12, + "equipId": 12, "lv": 96, "attr": "1&145" }, { - "id": 12, + "equipId": 12, "lv": 97, "attr": "1&146" }, { - "id": 12, + "equipId": 12, "lv": 98, "attr": "1&147" }, { - "id": 12, + "equipId": 12, "lv": 99, "attr": "1&148" }, { - "id": 12, + "equipId": 12, "lv": 100, "attr": "1&149" }, { - "id": 13, + "equipId": 13, + "lv": 0, + "attr": "2&10" + }, + { + "equipId": 13, "lv": 1, "attr": "2&10" }, { - "id": 13, + "equipId": 13, "lv": 2, "attr": "2&11" }, { - "id": 13, + "equipId": 13, "lv": 3, "attr": "2&12" }, { - "id": 13, + "equipId": 13, "lv": 4, "attr": "2&13" }, { - "id": 13, + "equipId": 13, "lv": 5, "attr": "2&14" }, { - "id": 13, + "equipId": 13, "lv": 6, "attr": "2&15" }, { - "id": 13, + "equipId": 13, "lv": 7, "attr": "2&16" }, { - "id": 13, + "equipId": 13, "lv": 8, "attr": "2&17" }, { - "id": 13, + "equipId": 13, "lv": 9, "attr": "2&18" }, { - "id": 13, + "equipId": 13, "lv": 10, "attr": "2&19" }, { - "id": 13, + "equipId": 13, "lv": 11, "attr": "2&20" }, { - "id": 13, + "equipId": 13, "lv": 12, "attr": "2&21" }, { - "id": 13, + "equipId": 13, "lv": 13, "attr": "2&22" }, { - "id": 13, + "equipId": 13, "lv": 14, "attr": "2&23" }, { - "id": 13, + "equipId": 13, "lv": 15, "attr": "2&24" }, { - "id": 13, + "equipId": 13, "lv": 16, "attr": "2&25" }, { - "id": 13, + "equipId": 13, "lv": 17, "attr": "2&26" }, { - "id": 13, + "equipId": 13, "lv": 18, "attr": "2&27" }, { - "id": 13, + "equipId": 13, "lv": 19, "attr": "2&28" }, { - "id": 13, + "equipId": 13, "lv": 20, "attr": "2&29" }, { - "id": 13, + "equipId": 13, "lv": 21, "attr": "2&30" }, { - "id": 13, + "equipId": 13, "lv": 22, "attr": "2&31" }, { - "id": 13, + "equipId": 13, "lv": 23, "attr": "2&32" }, { - "id": 13, + "equipId": 13, "lv": 24, "attr": "2&33" }, { - "id": 13, + "equipId": 13, "lv": 25, "attr": "2&34" }, { - "id": 13, + "equipId": 13, "lv": 26, "attr": "2&35" }, { - "id": 13, + "equipId": 13, "lv": 27, "attr": "2&36" }, { - "id": 13, + "equipId": 13, "lv": 28, "attr": "2&37" }, { - "id": 13, + "equipId": 13, "lv": 29, "attr": "2&38" }, { - "id": 13, + "equipId": 13, "lv": 30, "attr": "2&39" }, { - "id": 13, + "equipId": 13, "lv": 31, "attr": "2&40" }, { - "id": 13, + "equipId": 13, "lv": 32, "attr": "2&41" }, { - "id": 13, + "equipId": 13, "lv": 33, "attr": "2&42" }, { - "id": 13, + "equipId": 13, "lv": 34, "attr": "2&43" }, { - "id": 13, + "equipId": 13, "lv": 35, "attr": "2&44" }, { - "id": 13, + "equipId": 13, "lv": 36, "attr": "2&45" }, { - "id": 13, + "equipId": 13, "lv": 37, "attr": "2&46" }, { - "id": 13, + "equipId": 13, "lv": 38, "attr": "2&47" }, { - "id": 13, + "equipId": 13, "lv": 39, "attr": "2&48" }, { - "id": 13, + "equipId": 13, "lv": 40, "attr": "2&49" }, { - "id": 13, + "equipId": 13, "lv": 41, "attr": "2&50" }, { - "id": 13, + "equipId": 13, "lv": 42, "attr": "2&51" }, { - "id": 13, + "equipId": 13, "lv": 43, "attr": "2&52" }, { - "id": 13, + "equipId": 13, "lv": 44, "attr": "2&53" }, { - "id": 13, + "equipId": 13, "lv": 45, "attr": "2&54" }, { - "id": 13, + "equipId": 13, "lv": 46, "attr": "2&55" }, { - "id": 13, + "equipId": 13, "lv": 47, "attr": "2&56" }, { - "id": 13, + "equipId": 13, "lv": 48, "attr": "2&57" }, { - "id": 13, + "equipId": 13, "lv": 49, "attr": "2&58" }, { - "id": 13, + "equipId": 13, "lv": 50, "attr": "2&59" }, { - "id": 13, + "equipId": 13, "lv": 51, "attr": "2&60" }, { - "id": 13, + "equipId": 13, "lv": 52, "attr": "2&61" }, { - "id": 13, + "equipId": 13, "lv": 53, "attr": "2&62" }, { - "id": 13, + "equipId": 13, "lv": 54, "attr": "2&63" }, { - "id": 13, + "equipId": 13, "lv": 55, "attr": "2&64" }, { - "id": 13, + "equipId": 13, "lv": 56, "attr": "2&65" }, { - "id": 13, + "equipId": 13, "lv": 57, "attr": "2&66" }, { - "id": 13, + "equipId": 13, "lv": 58, "attr": "2&67" }, { - "id": 13, + "equipId": 13, "lv": 59, "attr": "2&68" }, { - "id": 13, + "equipId": 13, "lv": 60, "attr": "2&69" }, { - "id": 13, + "equipId": 13, "lv": 61, "attr": "2&70" }, { - "id": 13, + "equipId": 13, "lv": 62, "attr": "2&71" }, { - "id": 13, + "equipId": 13, "lv": 63, "attr": "2&72" }, { - "id": 13, + "equipId": 13, "lv": 64, "attr": "2&73" }, { - "id": 13, + "equipId": 13, "lv": 65, "attr": "2&74" }, { - "id": 13, + "equipId": 13, "lv": 66, "attr": "2&75" }, { - "id": 13, + "equipId": 13, "lv": 67, "attr": "2&76" }, { - "id": 13, + "equipId": 13, "lv": 68, "attr": "2&77" }, { - "id": 13, + "equipId": 13, "lv": 69, "attr": "2&78" }, { - "id": 13, + "equipId": 13, "lv": 70, "attr": "2&79" }, { - "id": 13, + "equipId": 13, "lv": 71, "attr": "2&80" }, { - "id": 13, + "equipId": 13, "lv": 72, "attr": "2&81" }, { - "id": 13, + "equipId": 13, "lv": 73, "attr": "2&82" }, { - "id": 13, + "equipId": 13, "lv": 74, "attr": "2&83" }, { - "id": 13, + "equipId": 13, "lv": 75, "attr": "2&84" }, { - "id": 13, + "equipId": 13, "lv": 76, "attr": "2&85" }, { - "id": 13, + "equipId": 13, "lv": 77, "attr": "2&86" }, { - "id": 13, + "equipId": 13, "lv": 78, "attr": "2&87" }, { - "id": 13, + "equipId": 13, "lv": 79, "attr": "2&88" }, { - "id": 13, + "equipId": 13, "lv": 80, "attr": "2&89" }, { - "id": 13, + "equipId": 13, "lv": 81, "attr": "2&90" }, { - "id": 13, + "equipId": 13, "lv": 82, "attr": "2&91" }, { - "id": 13, + "equipId": 13, "lv": 83, "attr": "2&92" }, { - "id": 13, + "equipId": 13, "lv": 84, "attr": "2&93" }, { - "id": 13, + "equipId": 13, "lv": 85, "attr": "2&94" }, { - "id": 13, + "equipId": 13, "lv": 86, "attr": "2&95" }, { - "id": 13, + "equipId": 13, "lv": 87, "attr": "2&96" }, { - "id": 13, + "equipId": 13, "lv": 88, "attr": "2&97" }, { - "id": 13, + "equipId": 13, "lv": 89, "attr": "2&98" }, { - "id": 13, + "equipId": 13, "lv": 90, "attr": "2&99" }, { - "id": 13, + "equipId": 13, "lv": 91, "attr": "2&100" }, { - "id": 13, + "equipId": 13, "lv": 92, "attr": "2&101" }, { - "id": 13, + "equipId": 13, "lv": 93, "attr": "2&102" }, { - "id": 13, + "equipId": 13, "lv": 94, "attr": "2&103" }, { - "id": 13, + "equipId": 13, "lv": 95, "attr": "2&104" }, { - "id": 13, + "equipId": 13, "lv": 96, "attr": "2&105" }, { - "id": 13, + "equipId": 13, "lv": 97, "attr": "2&106" }, { - "id": 13, + "equipId": 13, "lv": 98, "attr": "2&107" }, { - "id": 13, + "equipId": 13, "lv": 99, "attr": "2&108" }, { - "id": 13, + "equipId": 13, "lv": 100, "attr": "2&109" }, { - "id": 14, + "equipId": 14, + "lv": 0, + "attr": "4&20" + }, + { + "equipId": 14, "lv": 1, "attr": "4&20" }, { - "id": 14, + "equipId": 14, "lv": 2, "attr": "4&21" }, { - "id": 14, + "equipId": 14, "lv": 3, "attr": "4&22" }, { - "id": 14, + "equipId": 14, "lv": 4, "attr": "4&23" }, { - "id": 14, + "equipId": 14, "lv": 5, "attr": "4&24" }, { - "id": 14, + "equipId": 14, "lv": 6, "attr": "4&25" }, { - "id": 14, + "equipId": 14, "lv": 7, "attr": "4&26" }, { - "id": 14, + "equipId": 14, "lv": 8, "attr": "4&27" }, { - "id": 14, + "equipId": 14, "lv": 9, "attr": "4&28" }, { - "id": 14, + "equipId": 14, "lv": 10, "attr": "4&29" }, { - "id": 14, + "equipId": 14, "lv": 11, "attr": "4&30" }, { - "id": 14, + "equipId": 14, "lv": 12, "attr": "4&31" }, { - "id": 14, + "equipId": 14, "lv": 13, "attr": "4&32" }, { - "id": 14, + "equipId": 14, "lv": 14, "attr": "4&33" }, { - "id": 14, + "equipId": 14, "lv": 15, "attr": "4&34" }, { - "id": 14, + "equipId": 14, "lv": 16, "attr": "4&35" }, { - "id": 14, + "equipId": 14, "lv": 17, "attr": "4&36" }, { - "id": 14, + "equipId": 14, "lv": 18, "attr": "4&37" }, { - "id": 14, + "equipId": 14, "lv": 19, "attr": "4&38" }, { - "id": 14, + "equipId": 14, "lv": 20, "attr": "4&39" }, { - "id": 14, + "equipId": 14, "lv": 21, "attr": "4&40" }, { - "id": 14, + "equipId": 14, "lv": 22, "attr": "4&41" }, { - "id": 14, + "equipId": 14, "lv": 23, "attr": "4&42" }, { - "id": 14, + "equipId": 14, "lv": 24, "attr": "4&43" }, { - "id": 14, + "equipId": 14, "lv": 25, "attr": "4&44" }, { - "id": 14, + "equipId": 14, "lv": 26, "attr": "4&45" }, { - "id": 14, + "equipId": 14, "lv": 27, "attr": "4&46" }, { - "id": 14, + "equipId": 14, "lv": 28, "attr": "4&47" }, { - "id": 14, + "equipId": 14, "lv": 29, "attr": "4&48" }, { - "id": 14, + "equipId": 14, "lv": 30, "attr": "4&49" }, { - "id": 14, + "equipId": 14, "lv": 31, "attr": "4&50" }, { - "id": 14, + "equipId": 14, "lv": 32, "attr": "4&51" }, { - "id": 14, + "equipId": 14, "lv": 33, "attr": "4&52" }, { - "id": 14, + "equipId": 14, "lv": 34, "attr": "4&53" }, { - "id": 14, + "equipId": 14, "lv": 35, "attr": "4&54" }, { - "id": 14, + "equipId": 14, "lv": 36, "attr": "4&55" }, { - "id": 14, + "equipId": 14, "lv": 37, "attr": "4&56" }, { - "id": 14, + "equipId": 14, "lv": 38, "attr": "4&57" }, { - "id": 14, + "equipId": 14, "lv": 39, "attr": "4&58" }, { - "id": 14, + "equipId": 14, "lv": 40, "attr": "4&59" }, { - "id": 14, + "equipId": 14, "lv": 41, "attr": "4&60" }, { - "id": 14, + "equipId": 14, "lv": 42, "attr": "4&61" }, { - "id": 14, + "equipId": 14, "lv": 43, "attr": "4&62" }, { - "id": 14, + "equipId": 14, "lv": 44, "attr": "4&63" }, { - "id": 14, + "equipId": 14, "lv": 45, "attr": "4&64" }, { - "id": 14, + "equipId": 14, "lv": 46, "attr": "4&65" }, { - "id": 14, + "equipId": 14, "lv": 47, "attr": "4&66" }, { - "id": 14, + "equipId": 14, "lv": 48, "attr": "4&67" }, { - "id": 14, + "equipId": 14, "lv": 49, "attr": "4&68" }, { - "id": 14, + "equipId": 14, "lv": 50, "attr": "4&69" }, { - "id": 14, + "equipId": 14, "lv": 51, "attr": "4&70" }, { - "id": 14, + "equipId": 14, "lv": 52, "attr": "4&71" }, { - "id": 14, + "equipId": 14, "lv": 53, "attr": "4&72" }, { - "id": 14, + "equipId": 14, "lv": 54, "attr": "4&73" }, { - "id": 14, + "equipId": 14, "lv": 55, "attr": "4&74" }, { - "id": 14, + "equipId": 14, "lv": 56, "attr": "4&75" }, { - "id": 14, + "equipId": 14, "lv": 57, "attr": "4&76" }, { - "id": 14, + "equipId": 14, "lv": 58, "attr": "4&77" }, { - "id": 14, + "equipId": 14, "lv": 59, "attr": "4&78" }, { - "id": 14, + "equipId": 14, "lv": 60, "attr": "4&79" }, { - "id": 14, + "equipId": 14, "lv": 61, "attr": "4&80" }, { - "id": 14, + "equipId": 14, "lv": 62, "attr": "4&81" }, { - "id": 14, + "equipId": 14, "lv": 63, "attr": "4&82" }, { - "id": 14, + "equipId": 14, "lv": 64, "attr": "4&83" }, { - "id": 14, + "equipId": 14, "lv": 65, "attr": "4&84" }, { - "id": 14, + "equipId": 14, "lv": 66, "attr": "4&85" }, { - "id": 14, + "equipId": 14, "lv": 67, "attr": "4&86" }, { - "id": 14, + "equipId": 14, "lv": 68, "attr": "4&87" }, { - "id": 14, + "equipId": 14, "lv": 69, "attr": "4&88" }, { - "id": 14, + "equipId": 14, "lv": 70, "attr": "4&89" }, { - "id": 14, + "equipId": 14, "lv": 71, "attr": "4&90" }, { - "id": 14, + "equipId": 14, "lv": 72, "attr": "4&91" }, { - "id": 14, + "equipId": 14, "lv": 73, "attr": "4&92" }, { - "id": 14, + "equipId": 14, "lv": 74, "attr": "4&93" }, { - "id": 14, + "equipId": 14, "lv": 75, "attr": "4&94" }, { - "id": 14, + "equipId": 14, "lv": 76, "attr": "4&95" }, { - "id": 14, + "equipId": 14, "lv": 77, "attr": "4&96" }, { - "id": 14, + "equipId": 14, "lv": 78, "attr": "4&97" }, { - "id": 14, + "equipId": 14, "lv": 79, "attr": "4&98" }, { - "id": 14, + "equipId": 14, "lv": 80, "attr": "4&99" }, { - "id": 14, + "equipId": 14, "lv": 81, "attr": "4&100" }, { - "id": 14, + "equipId": 14, "lv": 82, "attr": "4&101" }, { - "id": 14, + "equipId": 14, "lv": 83, "attr": "4&102" }, { - "id": 14, + "equipId": 14, "lv": 84, "attr": "4&103" }, { - "id": 14, + "equipId": 14, "lv": 85, "attr": "4&104" }, { - "id": 14, + "equipId": 14, "lv": 86, "attr": "4&105" }, { - "id": 14, + "equipId": 14, "lv": 87, "attr": "4&106" }, { - "id": 14, + "equipId": 14, "lv": 88, "attr": "4&107" }, { - "id": 14, + "equipId": 14, "lv": 89, "attr": "4&108" }, { - "id": 14, + "equipId": 14, "lv": 90, "attr": "4&109" }, { - "id": 14, + "equipId": 14, "lv": 91, "attr": "4&110" }, { - "id": 14, + "equipId": 14, "lv": 92, "attr": "4&111" }, { - "id": 14, + "equipId": 14, "lv": 93, "attr": "4&112" }, { - "id": 14, + "equipId": 14, "lv": 94, "attr": "4&113" }, { - "id": 14, + "equipId": 14, "lv": 95, "attr": "4&114" }, { - "id": 14, + "equipId": 14, "lv": 96, "attr": "4&115" }, { - "id": 14, + "equipId": 14, "lv": 97, "attr": "4&116" }, { - "id": 14, + "equipId": 14, "lv": 98, "attr": "4&117" }, { - "id": 14, + "equipId": 14, "lv": 99, "attr": "4&118" }, { - "id": 14, + "equipId": 14, "lv": 100, "attr": "4&119" }, { - "id": 15, + "equipId": 15, + "lv": 0, + "attr": "5&20" + }, + { + "equipId": 15, "lv": 1, "attr": "5&20" }, { - "id": 15, + "equipId": 15, "lv": 2, "attr": "5&21" }, { - "id": 15, + "equipId": 15, "lv": 3, "attr": "5&22" }, { - "id": 15, + "equipId": 15, "lv": 4, "attr": "5&23" }, { - "id": 15, + "equipId": 15, "lv": 5, "attr": "5&24" }, { - "id": 15, + "equipId": 15, "lv": 6, "attr": "5&25" }, { - "id": 15, + "equipId": 15, "lv": 7, "attr": "5&26" }, { - "id": 15, + "equipId": 15, "lv": 8, "attr": "5&27" }, { - "id": 15, + "equipId": 15, "lv": 9, "attr": "5&28" }, { - "id": 15, + "equipId": 15, "lv": 10, "attr": "5&29" }, { - "id": 15, + "equipId": 15, "lv": 11, "attr": "5&30" }, { - "id": 15, + "equipId": 15, "lv": 12, "attr": "5&31" }, { - "id": 15, + "equipId": 15, "lv": 13, "attr": "5&32" }, { - "id": 15, + "equipId": 15, "lv": 14, "attr": "5&33" }, { - "id": 15, + "equipId": 15, "lv": 15, "attr": "5&34" }, { - "id": 15, + "equipId": 15, "lv": 16, "attr": "5&35" }, { - "id": 15, + "equipId": 15, "lv": 17, "attr": "5&36" }, { - "id": 15, + "equipId": 15, "lv": 18, "attr": "5&37" }, { - "id": 15, + "equipId": 15, "lv": 19, "attr": "5&38" }, { - "id": 15, + "equipId": 15, "lv": 20, "attr": "5&39" }, { - "id": 15, + "equipId": 15, "lv": 21, "attr": "5&40" }, { - "id": 15, + "equipId": 15, "lv": 22, "attr": "5&41" }, { - "id": 15, + "equipId": 15, "lv": 23, "attr": "5&42" }, { - "id": 15, + "equipId": 15, "lv": 24, "attr": "5&43" }, { - "id": 15, + "equipId": 15, "lv": 25, "attr": "5&44" }, { - "id": 15, + "equipId": 15, "lv": 26, "attr": "5&45" }, { - "id": 15, + "equipId": 15, "lv": 27, "attr": "5&46" }, { - "id": 15, + "equipId": 15, "lv": 28, "attr": "5&47" }, { - "id": 15, + "equipId": 15, "lv": 29, "attr": "5&48" }, { - "id": 15, + "equipId": 15, "lv": 30, "attr": "5&49" }, { - "id": 15, + "equipId": 15, "lv": 31, "attr": "5&50" }, { - "id": 15, + "equipId": 15, "lv": 32, "attr": "5&51" }, { - "id": 15, + "equipId": 15, "lv": 33, "attr": "5&52" }, { - "id": 15, + "equipId": 15, "lv": 34, "attr": "5&53" }, { - "id": 15, + "equipId": 15, "lv": 35, "attr": "5&54" }, { - "id": 15, + "equipId": 15, "lv": 36, "attr": "5&55" }, { - "id": 15, + "equipId": 15, "lv": 37, "attr": "5&56" }, { - "id": 15, + "equipId": 15, "lv": 38, "attr": "5&57" }, { - "id": 15, + "equipId": 15, "lv": 39, "attr": "5&58" }, { - "id": 15, + "equipId": 15, "lv": 40, "attr": "5&59" }, { - "id": 15, + "equipId": 15, "lv": 41, "attr": "5&60" }, { - "id": 15, + "equipId": 15, "lv": 42, "attr": "5&61" }, { - "id": 15, + "equipId": 15, "lv": 43, "attr": "5&62" }, { - "id": 15, + "equipId": 15, "lv": 44, "attr": "5&63" }, { - "id": 15, + "equipId": 15, "lv": 45, "attr": "5&64" }, { - "id": 15, + "equipId": 15, "lv": 46, "attr": "5&65" }, { - "id": 15, + "equipId": 15, "lv": 47, "attr": "5&66" }, { - "id": 15, + "equipId": 15, "lv": 48, "attr": "5&67" }, { - "id": 15, + "equipId": 15, "lv": 49, "attr": "5&68" }, { - "id": 15, + "equipId": 15, "lv": 50, "attr": "5&69" }, { - "id": 15, + "equipId": 15, "lv": 51, "attr": "5&70" }, { - "id": 15, + "equipId": 15, "lv": 52, "attr": "5&71" }, { - "id": 15, + "equipId": 15, "lv": 53, "attr": "5&72" }, { - "id": 15, + "equipId": 15, "lv": 54, "attr": "5&73" }, { - "id": 15, + "equipId": 15, "lv": 55, "attr": "5&74" }, { - "id": 15, + "equipId": 15, "lv": 56, "attr": "5&75" }, { - "id": 15, + "equipId": 15, "lv": 57, "attr": "5&76" }, { - "id": 15, + "equipId": 15, "lv": 58, "attr": "5&77" }, { - "id": 15, + "equipId": 15, "lv": 59, "attr": "5&78" }, { - "id": 15, + "equipId": 15, "lv": 60, "attr": "5&79" }, { - "id": 15, + "equipId": 15, "lv": 61, "attr": "5&80" }, { - "id": 15, + "equipId": 15, "lv": 62, "attr": "5&81" }, { - "id": 15, + "equipId": 15, "lv": 63, "attr": "5&82" }, { - "id": 15, + "equipId": 15, "lv": 64, "attr": "5&83" }, { - "id": 15, + "equipId": 15, "lv": 65, "attr": "5&84" }, { - "id": 15, + "equipId": 15, "lv": 66, "attr": "5&85" }, { - "id": 15, + "equipId": 15, "lv": 67, "attr": "5&86" }, { - "id": 15, + "equipId": 15, "lv": 68, "attr": "5&87" }, { - "id": 15, + "equipId": 15, "lv": 69, "attr": "5&88" }, { - "id": 15, + "equipId": 15, "lv": 70, "attr": "5&89" }, { - "id": 15, + "equipId": 15, "lv": 71, "attr": "5&90" }, { - "id": 15, + "equipId": 15, "lv": 72, "attr": "5&91" }, { - "id": 15, + "equipId": 15, "lv": 73, "attr": "5&92" }, { - "id": 15, + "equipId": 15, "lv": 74, "attr": "5&93" }, { - "id": 15, + "equipId": 15, "lv": 75, "attr": "5&94" }, { - "id": 15, + "equipId": 15, "lv": 76, "attr": "5&95" }, { - "id": 15, + "equipId": 15, "lv": 77, "attr": "5&96" }, { - "id": 15, + "equipId": 15, "lv": 78, "attr": "5&97" }, { - "id": 15, + "equipId": 15, "lv": 79, "attr": "5&98" }, { - "id": 15, + "equipId": 15, "lv": 80, "attr": "5&99" }, { - "id": 15, + "equipId": 15, "lv": 81, "attr": "5&100" }, { - "id": 15, + "equipId": 15, "lv": 82, "attr": "5&101" }, { - "id": 15, + "equipId": 15, "lv": 83, "attr": "5&102" }, { - "id": 15, + "equipId": 15, "lv": 84, "attr": "5&103" }, { - "id": 15, + "equipId": 15, "lv": 85, "attr": "5&104" }, { - "id": 15, + "equipId": 15, "lv": 86, "attr": "5&105" }, { - "id": 15, + "equipId": 15, "lv": 87, "attr": "5&106" }, { - "id": 15, + "equipId": 15, "lv": 88, "attr": "5&107" }, { - "id": 15, + "equipId": 15, "lv": 89, "attr": "5&108" }, { - "id": 15, + "equipId": 15, "lv": 90, "attr": "5&109" }, { - "id": 15, + "equipId": 15, "lv": 91, "attr": "5&110" }, { - "id": 15, + "equipId": 15, "lv": 92, "attr": "5&111" }, { - "id": 15, + "equipId": 15, "lv": 93, "attr": "5&112" }, { - "id": 15, + "equipId": 15, "lv": 94, "attr": "5&113" }, { - "id": 15, + "equipId": 15, "lv": 95, "attr": "5&114" }, { - "id": 15, + "equipId": 15, "lv": 96, "attr": "5&115" }, { - "id": 15, + "equipId": 15, "lv": 97, "attr": "5&116" }, { - "id": 15, + "equipId": 15, "lv": 98, "attr": "5&117" }, { - "id": 15, + "equipId": 15, "lv": 99, "attr": "5&118" }, { - "id": 15, + "equipId": 15, "lv": 100, "attr": "5&119" }, { - "id": 16, + "equipId": 16, + "lv": 0, + "attr": "1&50" + }, + { + "equipId": 16, "lv": 1, "attr": "1&50" }, { - "id": 16, + "equipId": 16, "lv": 2, "attr": "1&51" }, { - "id": 16, + "equipId": 16, "lv": 3, "attr": "1&52" }, { - "id": 16, + "equipId": 16, "lv": 4, "attr": "1&53" }, { - "id": 16, + "equipId": 16, "lv": 5, "attr": "1&54" }, { - "id": 16, + "equipId": 16, "lv": 6, "attr": "1&55" }, { - "id": 16, + "equipId": 16, "lv": 7, "attr": "1&56" }, { - "id": 16, + "equipId": 16, "lv": 8, "attr": "1&57" }, { - "id": 16, + "equipId": 16, "lv": 9, "attr": "1&58" }, { - "id": 16, + "equipId": 16, "lv": 10, "attr": "1&59" }, { - "id": 16, + "equipId": 16, "lv": 11, "attr": "1&60" }, { - "id": 16, + "equipId": 16, "lv": 12, "attr": "1&61" }, { - "id": 16, + "equipId": 16, "lv": 13, "attr": "1&62" }, { - "id": 16, + "equipId": 16, "lv": 14, "attr": "1&63" }, { - "id": 16, + "equipId": 16, "lv": 15, "attr": "1&64" }, { - "id": 16, + "equipId": 16, "lv": 16, "attr": "1&65" }, { - "id": 16, + "equipId": 16, "lv": 17, "attr": "1&66" }, { - "id": 16, + "equipId": 16, "lv": 18, "attr": "1&67" }, { - "id": 16, + "equipId": 16, "lv": 19, "attr": "1&68" }, { - "id": 16, + "equipId": 16, "lv": 20, "attr": "1&69" }, { - "id": 16, + "equipId": 16, "lv": 21, "attr": "1&70" }, { - "id": 16, + "equipId": 16, "lv": 22, "attr": "1&71" }, { - "id": 16, + "equipId": 16, "lv": 23, "attr": "1&72" }, { - "id": 16, + "equipId": 16, "lv": 24, "attr": "1&73" }, { - "id": 16, + "equipId": 16, "lv": 25, "attr": "1&74" }, { - "id": 16, + "equipId": 16, "lv": 26, "attr": "1&75" }, { - "id": 16, + "equipId": 16, "lv": 27, "attr": "1&76" }, { - "id": 16, + "equipId": 16, "lv": 28, "attr": "1&77" }, { - "id": 16, + "equipId": 16, "lv": 29, "attr": "1&78" }, { - "id": 16, + "equipId": 16, "lv": 30, "attr": "1&79" }, { - "id": 16, + "equipId": 16, "lv": 31, "attr": "1&80" }, { - "id": 16, + "equipId": 16, "lv": 32, "attr": "1&81" }, { - "id": 16, + "equipId": 16, "lv": 33, "attr": "1&82" }, { - "id": 16, + "equipId": 16, "lv": 34, "attr": "1&83" }, { - "id": 16, + "equipId": 16, "lv": 35, "attr": "1&84" }, { - "id": 16, + "equipId": 16, "lv": 36, "attr": "1&85" }, { - "id": 16, + "equipId": 16, "lv": 37, "attr": "1&86" }, { - "id": 16, + "equipId": 16, "lv": 38, "attr": "1&87" }, { - "id": 16, + "equipId": 16, "lv": 39, "attr": "1&88" }, { - "id": 16, + "equipId": 16, "lv": 40, "attr": "1&89" }, { - "id": 16, + "equipId": 16, "lv": 41, "attr": "1&90" }, { - "id": 16, + "equipId": 16, "lv": 42, "attr": "1&91" }, { - "id": 16, + "equipId": 16, "lv": 43, "attr": "1&92" }, { - "id": 16, + "equipId": 16, "lv": 44, "attr": "1&93" }, { - "id": 16, + "equipId": 16, "lv": 45, "attr": "1&94" }, { - "id": 16, + "equipId": 16, "lv": 46, "attr": "1&95" }, { - "id": 16, + "equipId": 16, "lv": 47, "attr": "1&96" }, { - "id": 16, + "equipId": 16, "lv": 48, "attr": "1&97" }, { - "id": 16, + "equipId": 16, "lv": 49, "attr": "1&98" }, { - "id": 16, + "equipId": 16, "lv": 50, "attr": "1&99" }, { - "id": 16, + "equipId": 16, "lv": 51, "attr": "1&100" }, { - "id": 16, + "equipId": 16, "lv": 52, "attr": "1&101" }, { - "id": 16, + "equipId": 16, "lv": 53, "attr": "1&102" }, { - "id": 16, + "equipId": 16, "lv": 54, "attr": "1&103" }, { - "id": 16, + "equipId": 16, "lv": 55, "attr": "1&104" }, { - "id": 16, + "equipId": 16, "lv": 56, "attr": "1&105" }, { - "id": 16, + "equipId": 16, "lv": 57, "attr": "1&106" }, { - "id": 16, + "equipId": 16, "lv": 58, "attr": "1&107" }, { - "id": 16, + "equipId": 16, "lv": 59, "attr": "1&108" }, { - "id": 16, + "equipId": 16, "lv": 60, "attr": "1&109" }, { - "id": 16, + "equipId": 16, "lv": 61, "attr": "1&110" }, { - "id": 16, + "equipId": 16, "lv": 62, "attr": "1&111" }, { - "id": 16, + "equipId": 16, "lv": 63, "attr": "1&112" }, { - "id": 16, + "equipId": 16, "lv": 64, "attr": "1&113" }, { - "id": 16, + "equipId": 16, "lv": 65, "attr": "1&114" }, { - "id": 16, + "equipId": 16, "lv": 66, "attr": "1&115" }, { - "id": 16, + "equipId": 16, "lv": 67, "attr": "1&116" }, { - "id": 16, + "equipId": 16, "lv": 68, "attr": "1&117" }, { - "id": 16, + "equipId": 16, "lv": 69, "attr": "1&118" }, { - "id": 16, + "equipId": 16, "lv": 70, "attr": "1&119" }, { - "id": 16, + "equipId": 16, "lv": 71, "attr": "1&120" }, { - "id": 16, + "equipId": 16, "lv": 72, "attr": "1&121" }, { - "id": 16, + "equipId": 16, "lv": 73, "attr": "1&122" }, { - "id": 16, + "equipId": 16, "lv": 74, "attr": "1&123" }, { - "id": 16, + "equipId": 16, "lv": 75, "attr": "1&124" }, { - "id": 16, + "equipId": 16, "lv": 76, "attr": "1&125" }, { - "id": 16, + "equipId": 16, "lv": 77, "attr": "1&126" }, { - "id": 16, + "equipId": 16, "lv": 78, "attr": "1&127" }, { - "id": 16, + "equipId": 16, "lv": 79, "attr": "1&128" }, { - "id": 16, + "equipId": 16, "lv": 80, "attr": "1&129" }, { - "id": 16, + "equipId": 16, "lv": 81, "attr": "1&130" }, { - "id": 16, + "equipId": 16, "lv": 82, "attr": "1&131" }, { - "id": 16, + "equipId": 16, "lv": 83, "attr": "1&132" }, { - "id": 16, + "equipId": 16, "lv": 84, "attr": "1&133" }, { - "id": 16, + "equipId": 16, "lv": 85, "attr": "1&134" }, { - "id": 16, + "equipId": 16, "lv": 86, "attr": "1&135" }, { - "id": 16, + "equipId": 16, "lv": 87, "attr": "1&136" }, { - "id": 16, + "equipId": 16, "lv": 88, "attr": "1&137" }, { - "id": 16, + "equipId": 16, "lv": 89, "attr": "1&138" }, { - "id": 16, + "equipId": 16, "lv": 90, "attr": "1&139" }, { - "id": 16, + "equipId": 16, "lv": 91, "attr": "1&140" }, { - "id": 16, + "equipId": 16, "lv": 92, "attr": "1&141" }, { - "id": 16, + "equipId": 16, "lv": 93, "attr": "1&142" }, { - "id": 16, + "equipId": 16, "lv": 94, "attr": "1&143" }, { - "id": 16, + "equipId": 16, "lv": 95, "attr": "1&144" }, { - "id": 16, + "equipId": 16, "lv": 96, "attr": "1&145" }, { - "id": 16, + "equipId": 16, "lv": 97, "attr": "1&146" }, { - "id": 16, + "equipId": 16, "lv": 98, "attr": "1&147" }, { - "id": 16, + "equipId": 16, "lv": 99, "attr": "1&148" }, { - "id": 16, + "equipId": 16, "lv": 100, "attr": "1&149" }, { - "id": 17, + "equipId": 17, + "lv": 0, + "attr": "2&10" + }, + { + "equipId": 17, "lv": 1, "attr": "2&10" }, { - "id": 17, + "equipId": 17, "lv": 2, "attr": "2&11" }, { - "id": 17, + "equipId": 17, "lv": 3, "attr": "2&12" }, { - "id": 17, + "equipId": 17, "lv": 4, "attr": "2&13" }, { - "id": 17, + "equipId": 17, "lv": 5, "attr": "2&14" }, { - "id": 17, + "equipId": 17, "lv": 6, "attr": "2&15" }, { - "id": 17, + "equipId": 17, "lv": 7, "attr": "2&16" }, { - "id": 17, + "equipId": 17, "lv": 8, "attr": "2&17" }, { - "id": 17, + "equipId": 17, "lv": 9, "attr": "2&18" }, { - "id": 17, + "equipId": 17, "lv": 10, "attr": "2&19" }, { - "id": 17, + "equipId": 17, "lv": 11, "attr": "2&20" }, { - "id": 17, + "equipId": 17, "lv": 12, "attr": "2&21" }, { - "id": 17, + "equipId": 17, "lv": 13, "attr": "2&22" }, { - "id": 17, + "equipId": 17, "lv": 14, "attr": "2&23" }, { - "id": 17, + "equipId": 17, "lv": 15, "attr": "2&24" }, { - "id": 17, + "equipId": 17, "lv": 16, "attr": "2&25" }, { - "id": 17, + "equipId": 17, "lv": 17, "attr": "2&26" }, { - "id": 17, + "equipId": 17, "lv": 18, "attr": "2&27" }, { - "id": 17, + "equipId": 17, "lv": 19, "attr": "2&28" }, { - "id": 17, + "equipId": 17, "lv": 20, "attr": "2&29" }, { - "id": 17, + "equipId": 17, "lv": 21, "attr": "2&30" }, { - "id": 17, + "equipId": 17, "lv": 22, "attr": "2&31" }, { - "id": 17, + "equipId": 17, "lv": 23, "attr": "2&32" }, { - "id": 17, + "equipId": 17, "lv": 24, "attr": "2&33" }, { - "id": 17, + "equipId": 17, "lv": 25, "attr": "2&34" }, { - "id": 17, + "equipId": 17, "lv": 26, "attr": "2&35" }, { - "id": 17, + "equipId": 17, "lv": 27, "attr": "2&36" }, { - "id": 17, + "equipId": 17, "lv": 28, "attr": "2&37" }, { - "id": 17, + "equipId": 17, "lv": 29, "attr": "2&38" }, { - "id": 17, + "equipId": 17, "lv": 30, "attr": "2&39" }, { - "id": 17, + "equipId": 17, "lv": 31, "attr": "2&40" }, { - "id": 17, + "equipId": 17, "lv": 32, "attr": "2&41" }, { - "id": 17, + "equipId": 17, "lv": 33, "attr": "2&42" }, { - "id": 17, + "equipId": 17, "lv": 34, "attr": "2&43" }, { - "id": 17, + "equipId": 17, "lv": 35, "attr": "2&44" }, { - "id": 17, + "equipId": 17, "lv": 36, "attr": "2&45" }, { - "id": 17, + "equipId": 17, "lv": 37, "attr": "2&46" }, { - "id": 17, + "equipId": 17, "lv": 38, "attr": "2&47" }, { - "id": 17, + "equipId": 17, "lv": 39, "attr": "2&48" }, { - "id": 17, + "equipId": 17, "lv": 40, "attr": "2&49" }, { - "id": 17, + "equipId": 17, "lv": 41, "attr": "2&50" }, { - "id": 17, + "equipId": 17, "lv": 42, "attr": "2&51" }, { - "id": 17, + "equipId": 17, "lv": 43, "attr": "2&52" }, { - "id": 17, + "equipId": 17, "lv": 44, "attr": "2&53" }, { - "id": 17, + "equipId": 17, "lv": 45, "attr": "2&54" }, { - "id": 17, + "equipId": 17, "lv": 46, "attr": "2&55" }, { - "id": 17, + "equipId": 17, "lv": 47, "attr": "2&56" }, { - "id": 17, + "equipId": 17, "lv": 48, "attr": "2&57" }, { - "id": 17, + "equipId": 17, "lv": 49, "attr": "2&58" }, { - "id": 17, + "equipId": 17, "lv": 50, "attr": "2&59" }, { - "id": 17, + "equipId": 17, "lv": 51, "attr": "2&60" }, { - "id": 17, + "equipId": 17, "lv": 52, "attr": "2&61" }, { - "id": 17, + "equipId": 17, "lv": 53, "attr": "2&62" }, { - "id": 17, + "equipId": 17, "lv": 54, "attr": "2&63" }, { - "id": 17, + "equipId": 17, "lv": 55, "attr": "2&64" }, { - "id": 17, + "equipId": 17, "lv": 56, "attr": "2&65" }, { - "id": 17, + "equipId": 17, "lv": 57, "attr": "2&66" }, { - "id": 17, + "equipId": 17, "lv": 58, "attr": "2&67" }, { - "id": 17, + "equipId": 17, "lv": 59, "attr": "2&68" }, { - "id": 17, + "equipId": 17, "lv": 60, "attr": "2&69" }, { - "id": 17, + "equipId": 17, "lv": 61, "attr": "2&70" }, { - "id": 17, + "equipId": 17, "lv": 62, "attr": "2&71" }, { - "id": 17, + "equipId": 17, "lv": 63, "attr": "2&72" }, { - "id": 17, + "equipId": 17, "lv": 64, "attr": "2&73" }, { - "id": 17, + "equipId": 17, "lv": 65, "attr": "2&74" }, { - "id": 17, + "equipId": 17, "lv": 66, "attr": "2&75" }, { - "id": 17, + "equipId": 17, "lv": 67, "attr": "2&76" }, { - "id": 17, + "equipId": 17, "lv": 68, "attr": "2&77" }, { - "id": 17, + "equipId": 17, "lv": 69, "attr": "2&78" }, { - "id": 17, + "equipId": 17, "lv": 70, "attr": "2&79" }, { - "id": 17, + "equipId": 17, "lv": 71, "attr": "2&80" }, { - "id": 17, + "equipId": 17, "lv": 72, "attr": "2&81" }, { - "id": 17, + "equipId": 17, "lv": 73, "attr": "2&82" }, { - "id": 17, + "equipId": 17, "lv": 74, "attr": "2&83" }, { - "id": 17, + "equipId": 17, "lv": 75, "attr": "2&84" }, { - "id": 17, + "equipId": 17, "lv": 76, "attr": "2&85" }, { - "id": 17, + "equipId": 17, "lv": 77, "attr": "2&86" }, { - "id": 17, + "equipId": 17, "lv": 78, "attr": "2&87" }, { - "id": 17, + "equipId": 17, "lv": 79, "attr": "2&88" }, { - "id": 17, + "equipId": 17, "lv": 80, "attr": "2&89" }, { - "id": 17, + "equipId": 17, "lv": 81, "attr": "2&90" }, { - "id": 17, + "equipId": 17, "lv": 82, "attr": "2&91" }, { - "id": 17, + "equipId": 17, "lv": 83, "attr": "2&92" }, { - "id": 17, + "equipId": 17, "lv": 84, "attr": "2&93" }, { - "id": 17, + "equipId": 17, "lv": 85, "attr": "2&94" }, { - "id": 17, + "equipId": 17, "lv": 86, "attr": "2&95" }, { - "id": 17, + "equipId": 17, "lv": 87, "attr": "2&96" }, { - "id": 17, + "equipId": 17, "lv": 88, "attr": "2&97" }, { - "id": 17, + "equipId": 17, "lv": 89, "attr": "2&98" }, { - "id": 17, + "equipId": 17, "lv": 90, "attr": "2&99" }, { - "id": 17, + "equipId": 17, "lv": 91, "attr": "2&100" }, { - "id": 17, + "equipId": 17, "lv": 92, "attr": "2&101" }, { - "id": 17, + "equipId": 17, "lv": 93, "attr": "2&102" }, { - "id": 17, + "equipId": 17, "lv": 94, "attr": "2&103" }, { - "id": 17, + "equipId": 17, "lv": 95, "attr": "2&104" }, { - "id": 17, + "equipId": 17, "lv": 96, "attr": "2&105" }, { - "id": 17, + "equipId": 17, "lv": 97, "attr": "2&106" }, { - "id": 17, + "equipId": 17, "lv": 98, "attr": "2&107" }, { - "id": 17, + "equipId": 17, "lv": 99, "attr": "2&108" }, { - "id": 17, + "equipId": 17, "lv": 100, "attr": "2&109" }, { - "id": 18, + "equipId": 18, + "lv": 0, + "attr": "4&20" + }, + { + "equipId": 18, "lv": 1, "attr": "4&20" }, { - "id": 18, + "equipId": 18, "lv": 2, "attr": "4&21" }, { - "id": 18, + "equipId": 18, "lv": 3, "attr": "4&22" }, { - "id": 18, + "equipId": 18, "lv": 4, "attr": "4&23" }, { - "id": 18, + "equipId": 18, "lv": 5, "attr": "4&24" }, { - "id": 18, + "equipId": 18, "lv": 6, "attr": "4&25" }, { - "id": 18, + "equipId": 18, "lv": 7, "attr": "4&26" }, { - "id": 18, + "equipId": 18, "lv": 8, "attr": "4&27" }, { - "id": 18, + "equipId": 18, "lv": 9, "attr": "4&28" }, { - "id": 18, + "equipId": 18, "lv": 10, "attr": "4&29" }, { - "id": 18, + "equipId": 18, "lv": 11, "attr": "4&30" }, { - "id": 18, + "equipId": 18, "lv": 12, "attr": "4&31" }, { - "id": 18, + "equipId": 18, "lv": 13, "attr": "4&32" }, { - "id": 18, + "equipId": 18, "lv": 14, "attr": "4&33" }, { - "id": 18, + "equipId": 18, "lv": 15, "attr": "4&34" }, { - "id": 18, + "equipId": 18, "lv": 16, "attr": "4&35" }, { - "id": 18, + "equipId": 18, "lv": 17, "attr": "4&36" }, { - "id": 18, + "equipId": 18, "lv": 18, "attr": "4&37" }, { - "id": 18, + "equipId": 18, "lv": 19, "attr": "4&38" }, { - "id": 18, + "equipId": 18, "lv": 20, "attr": "4&39" }, { - "id": 18, + "equipId": 18, "lv": 21, "attr": "4&40" }, { - "id": 18, + "equipId": 18, "lv": 22, "attr": "4&41" }, { - "id": 18, + "equipId": 18, "lv": 23, "attr": "4&42" }, { - "id": 18, + "equipId": 18, "lv": 24, "attr": "4&43" }, { - "id": 18, + "equipId": 18, "lv": 25, "attr": "4&44" }, { - "id": 18, + "equipId": 18, "lv": 26, "attr": "4&45" }, { - "id": 18, + "equipId": 18, "lv": 27, "attr": "4&46" }, { - "id": 18, + "equipId": 18, "lv": 28, "attr": "4&47" }, { - "id": 18, + "equipId": 18, "lv": 29, "attr": "4&48" }, { - "id": 18, + "equipId": 18, "lv": 30, "attr": "4&49" }, { - "id": 18, + "equipId": 18, "lv": 31, "attr": "4&50" }, { - "id": 18, + "equipId": 18, "lv": 32, "attr": "4&51" }, { - "id": 18, + "equipId": 18, "lv": 33, "attr": "4&52" }, { - "id": 18, + "equipId": 18, "lv": 34, "attr": "4&53" }, { - "id": 18, + "equipId": 18, "lv": 35, "attr": "4&54" }, { - "id": 18, + "equipId": 18, "lv": 36, "attr": "4&55" }, { - "id": 18, + "equipId": 18, "lv": 37, "attr": "4&56" }, { - "id": 18, + "equipId": 18, "lv": 38, "attr": "4&57" }, { - "id": 18, + "equipId": 18, "lv": 39, "attr": "4&58" }, { - "id": 18, + "equipId": 18, "lv": 40, "attr": "4&59" }, { - "id": 18, + "equipId": 18, "lv": 41, "attr": "4&60" }, { - "id": 18, + "equipId": 18, "lv": 42, "attr": "4&61" }, { - "id": 18, + "equipId": 18, "lv": 43, "attr": "4&62" }, { - "id": 18, + "equipId": 18, "lv": 44, "attr": "4&63" }, { - "id": 18, + "equipId": 18, "lv": 45, "attr": "4&64" }, { - "id": 18, + "equipId": 18, "lv": 46, "attr": "4&65" }, { - "id": 18, + "equipId": 18, "lv": 47, "attr": "4&66" }, { - "id": 18, + "equipId": 18, "lv": 48, "attr": "4&67" }, { - "id": 18, + "equipId": 18, "lv": 49, "attr": "4&68" }, { - "id": 18, + "equipId": 18, "lv": 50, "attr": "4&69" }, { - "id": 18, + "equipId": 18, "lv": 51, "attr": "4&70" }, { - "id": 18, + "equipId": 18, "lv": 52, "attr": "4&71" }, { - "id": 18, + "equipId": 18, "lv": 53, "attr": "4&72" }, { - "id": 18, + "equipId": 18, "lv": 54, "attr": "4&73" }, { - "id": 18, + "equipId": 18, "lv": 55, "attr": "4&74" }, { - "id": 18, + "equipId": 18, "lv": 56, "attr": "4&75" }, { - "id": 18, + "equipId": 18, "lv": 57, "attr": "4&76" }, { - "id": 18, + "equipId": 18, "lv": 58, "attr": "4&77" }, { - "id": 18, + "equipId": 18, "lv": 59, "attr": "4&78" }, { - "id": 18, + "equipId": 18, "lv": 60, "attr": "4&79" }, { - "id": 18, + "equipId": 18, "lv": 61, "attr": "4&80" }, { - "id": 18, + "equipId": 18, "lv": 62, "attr": "4&81" }, { - "id": 18, + "equipId": 18, "lv": 63, "attr": "4&82" }, { - "id": 18, + "equipId": 18, "lv": 64, "attr": "4&83" }, { - "id": 18, + "equipId": 18, "lv": 65, "attr": "4&84" }, { - "id": 18, + "equipId": 18, "lv": 66, "attr": "4&85" }, { - "id": 18, + "equipId": 18, "lv": 67, "attr": "4&86" }, { - "id": 18, + "equipId": 18, "lv": 68, "attr": "4&87" }, { - "id": 18, + "equipId": 18, "lv": 69, "attr": "4&88" }, { - "id": 18, + "equipId": 18, "lv": 70, "attr": "4&89" }, { - "id": 18, + "equipId": 18, "lv": 71, "attr": "4&90" }, { - "id": 18, + "equipId": 18, "lv": 72, "attr": "4&91" }, { - "id": 18, + "equipId": 18, "lv": 73, "attr": "4&92" }, { - "id": 18, + "equipId": 18, "lv": 74, "attr": "4&93" }, { - "id": 18, + "equipId": 18, "lv": 75, "attr": "4&94" }, { - "id": 18, + "equipId": 18, "lv": 76, "attr": "4&95" }, { - "id": 18, + "equipId": 18, "lv": 77, "attr": "4&96" }, { - "id": 18, + "equipId": 18, "lv": 78, "attr": "4&97" }, { - "id": 18, + "equipId": 18, "lv": 79, "attr": "4&98" }, { - "id": 18, + "equipId": 18, "lv": 80, "attr": "4&99" }, { - "id": 18, + "equipId": 18, "lv": 81, "attr": "4&100" }, { - "id": 18, + "equipId": 18, "lv": 82, "attr": "4&101" }, { - "id": 18, + "equipId": 18, "lv": 83, "attr": "4&102" }, { - "id": 18, + "equipId": 18, "lv": 84, "attr": "4&103" }, { - "id": 18, + "equipId": 18, "lv": 85, "attr": "4&104" }, { - "id": 18, + "equipId": 18, "lv": 86, "attr": "4&105" }, { - "id": 18, + "equipId": 18, "lv": 87, "attr": "4&106" }, { - "id": 18, + "equipId": 18, "lv": 88, "attr": "4&107" }, { - "id": 18, + "equipId": 18, "lv": 89, "attr": "4&108" }, { - "id": 18, + "equipId": 18, "lv": 90, "attr": "4&109" }, { - "id": 18, + "equipId": 18, "lv": 91, "attr": "4&110" }, { - "id": 18, + "equipId": 18, "lv": 92, "attr": "4&111" }, { - "id": 18, + "equipId": 18, "lv": 93, "attr": "4&112" }, { - "id": 18, + "equipId": 18, "lv": 94, "attr": "4&113" }, { - "id": 18, + "equipId": 18, "lv": 95, "attr": "4&114" }, { - "id": 18, + "equipId": 18, "lv": 96, "attr": "4&115" }, { - "id": 18, + "equipId": 18, "lv": 97, "attr": "4&116" }, { - "id": 18, + "equipId": 18, "lv": 98, "attr": "4&117" }, { - "id": 18, + "equipId": 18, "lv": 99, "attr": "4&118" }, { - "id": 18, + "equipId": 18, "lv": 100, "attr": "4&119" }, { - "id": 19, + "equipId": 19, + "lv": 0, + "attr": "5&20" + }, + { + "equipId": 19, "lv": 1, "attr": "5&20" }, { - "id": 19, + "equipId": 19, "lv": 2, "attr": "5&21" }, { - "id": 19, + "equipId": 19, "lv": 3, "attr": "5&22" }, { - "id": 19, + "equipId": 19, "lv": 4, "attr": "5&23" }, { - "id": 19, + "equipId": 19, "lv": 5, "attr": "5&24" }, { - "id": 19, + "equipId": 19, "lv": 6, "attr": "5&25" }, { - "id": 19, + "equipId": 19, "lv": 7, "attr": "5&26" }, { - "id": 19, + "equipId": 19, "lv": 8, "attr": "5&27" }, { - "id": 19, + "equipId": 19, "lv": 9, "attr": "5&28" }, { - "id": 19, + "equipId": 19, "lv": 10, "attr": "5&29" }, { - "id": 19, + "equipId": 19, "lv": 11, "attr": "5&30" }, { - "id": 19, + "equipId": 19, "lv": 12, "attr": "5&31" }, { - "id": 19, + "equipId": 19, "lv": 13, "attr": "5&32" }, { - "id": 19, + "equipId": 19, "lv": 14, "attr": "5&33" }, { - "id": 19, + "equipId": 19, "lv": 15, "attr": "5&34" }, { - "id": 19, + "equipId": 19, "lv": 16, "attr": "5&35" }, { - "id": 19, + "equipId": 19, "lv": 17, "attr": "5&36" }, { - "id": 19, + "equipId": 19, "lv": 18, "attr": "5&37" }, { - "id": 19, + "equipId": 19, "lv": 19, "attr": "5&38" }, { - "id": 19, + "equipId": 19, "lv": 20, "attr": "5&39" }, { - "id": 19, + "equipId": 19, "lv": 21, "attr": "5&40" }, { - "id": 19, + "equipId": 19, "lv": 22, "attr": "5&41" }, { - "id": 19, + "equipId": 19, "lv": 23, "attr": "5&42" }, { - "id": 19, + "equipId": 19, "lv": 24, "attr": "5&43" }, { - "id": 19, + "equipId": 19, "lv": 25, "attr": "5&44" }, { - "id": 19, + "equipId": 19, "lv": 26, "attr": "5&45" }, { - "id": 19, + "equipId": 19, "lv": 27, "attr": "5&46" }, { - "id": 19, + "equipId": 19, "lv": 28, "attr": "5&47" }, { - "id": 19, + "equipId": 19, "lv": 29, "attr": "5&48" }, { - "id": 19, + "equipId": 19, "lv": 30, "attr": "5&49" }, { - "id": 19, + "equipId": 19, "lv": 31, "attr": "5&50" }, { - "id": 19, + "equipId": 19, "lv": 32, "attr": "5&51" }, { - "id": 19, + "equipId": 19, "lv": 33, "attr": "5&52" }, { - "id": 19, + "equipId": 19, "lv": 34, "attr": "5&53" }, { - "id": 19, + "equipId": 19, "lv": 35, "attr": "5&54" }, { - "id": 19, + "equipId": 19, "lv": 36, "attr": "5&55" }, { - "id": 19, + "equipId": 19, "lv": 37, "attr": "5&56" }, { - "id": 19, + "equipId": 19, "lv": 38, "attr": "5&57" }, { - "id": 19, + "equipId": 19, "lv": 39, "attr": "5&58" }, { - "id": 19, + "equipId": 19, "lv": 40, "attr": "5&59" }, { - "id": 19, + "equipId": 19, "lv": 41, "attr": "5&60" }, { - "id": 19, + "equipId": 19, "lv": 42, "attr": "5&61" }, { - "id": 19, + "equipId": 19, "lv": 43, "attr": "5&62" }, { - "id": 19, + "equipId": 19, "lv": 44, "attr": "5&63" }, { - "id": 19, + "equipId": 19, "lv": 45, "attr": "5&64" }, { - "id": 19, + "equipId": 19, "lv": 46, "attr": "5&65" }, { - "id": 19, + "equipId": 19, "lv": 47, "attr": "5&66" }, { - "id": 19, + "equipId": 19, "lv": 48, "attr": "5&67" }, { - "id": 19, + "equipId": 19, "lv": 49, "attr": "5&68" }, { - "id": 19, + "equipId": 19, "lv": 50, "attr": "5&69" }, { - "id": 19, + "equipId": 19, "lv": 51, "attr": "5&70" }, { - "id": 19, + "equipId": 19, "lv": 52, "attr": "5&71" }, { - "id": 19, + "equipId": 19, "lv": 53, "attr": "5&72" }, { - "id": 19, + "equipId": 19, "lv": 54, "attr": "5&73" }, { - "id": 19, + "equipId": 19, "lv": 55, "attr": "5&74" }, { - "id": 19, + "equipId": 19, "lv": 56, "attr": "5&75" }, { - "id": 19, + "equipId": 19, "lv": 57, "attr": "5&76" }, { - "id": 19, + "equipId": 19, "lv": 58, "attr": "5&77" }, { - "id": 19, + "equipId": 19, "lv": 59, "attr": "5&78" }, { - "id": 19, + "equipId": 19, "lv": 60, "attr": "5&79" }, { - "id": 19, + "equipId": 19, "lv": 61, "attr": "5&80" }, { - "id": 19, + "equipId": 19, "lv": 62, "attr": "5&81" }, { - "id": 19, + "equipId": 19, "lv": 63, "attr": "5&82" }, { - "id": 19, + "equipId": 19, "lv": 64, "attr": "5&83" }, { - "id": 19, + "equipId": 19, "lv": 65, "attr": "5&84" }, { - "id": 19, + "equipId": 19, "lv": 66, "attr": "5&85" }, { - "id": 19, + "equipId": 19, "lv": 67, "attr": "5&86" }, { - "id": 19, + "equipId": 19, "lv": 68, "attr": "5&87" }, { - "id": 19, + "equipId": 19, "lv": 69, "attr": "5&88" }, { - "id": 19, + "equipId": 19, "lv": 70, "attr": "5&89" }, { - "id": 19, + "equipId": 19, "lv": 71, "attr": "5&90" }, { - "id": 19, + "equipId": 19, "lv": 72, "attr": "5&91" }, { - "id": 19, + "equipId": 19, "lv": 73, "attr": "5&92" }, { - "id": 19, + "equipId": 19, "lv": 74, "attr": "5&93" }, { - "id": 19, + "equipId": 19, "lv": 75, "attr": "5&94" }, { - "id": 19, + "equipId": 19, "lv": 76, "attr": "5&95" }, { - "id": 19, + "equipId": 19, "lv": 77, "attr": "5&96" }, { - "id": 19, + "equipId": 19, "lv": 78, "attr": "5&97" }, { - "id": 19, + "equipId": 19, "lv": 79, "attr": "5&98" }, { - "id": 19, + "equipId": 19, "lv": 80, "attr": "5&99" }, { - "id": 19, + "equipId": 19, "lv": 81, "attr": "5&100" }, { - "id": 19, + "equipId": 19, "lv": 82, "attr": "5&101" }, { - "id": 19, + "equipId": 19, "lv": 83, "attr": "5&102" }, { - "id": 19, + "equipId": 19, "lv": 84, "attr": "5&103" }, { - "id": 19, + "equipId": 19, "lv": 85, "attr": "5&104" }, { - "id": 19, + "equipId": 19, "lv": 86, "attr": "5&105" }, { - "id": 19, + "equipId": 19, "lv": 87, "attr": "5&106" }, { - "id": 19, + "equipId": 19, "lv": 88, "attr": "5&107" }, { - "id": 19, + "equipId": 19, "lv": 89, "attr": "5&108" }, { - "id": 19, + "equipId": 19, "lv": 90, "attr": "5&109" }, { - "id": 19, + "equipId": 19, "lv": 91, "attr": "5&110" }, { - "id": 19, + "equipId": 19, "lv": 92, "attr": "5&111" }, { - "id": 19, + "equipId": 19, "lv": 93, "attr": "5&112" }, { - "id": 19, + "equipId": 19, "lv": 94, "attr": "5&113" }, { - "id": 19, + "equipId": 19, "lv": 95, "attr": "5&114" }, { - "id": 19, + "equipId": 19, "lv": 96, "attr": "5&115" }, { - "id": 19, + "equipId": 19, "lv": 97, "attr": "5&116" }, { - "id": 19, + "equipId": 19, "lv": 98, "attr": "5&117" }, { - "id": 19, + "equipId": 19, "lv": 99, "attr": "5&118" }, { - "id": 19, + "equipId": 19, "lv": 100, "attr": "5&119" }, { - "id": 20, + "equipId": 20, + "lv": 0, + "attr": "1&50" + }, + { + "equipId": 20, "lv": 1, "attr": "1&50" }, { - "id": 20, + "equipId": 20, "lv": 2, "attr": "1&51" }, { - "id": 20, + "equipId": 20, "lv": 3, "attr": "1&52" }, { - "id": 20, + "equipId": 20, "lv": 4, "attr": "1&53" }, { - "id": 20, + "equipId": 20, "lv": 5, "attr": "1&54" }, { - "id": 20, + "equipId": 20, "lv": 6, "attr": "1&55" }, { - "id": 20, + "equipId": 20, "lv": 7, "attr": "1&56" }, { - "id": 20, + "equipId": 20, "lv": 8, "attr": "1&57" }, { - "id": 20, + "equipId": 20, "lv": 9, "attr": "1&58" }, { - "id": 20, + "equipId": 20, "lv": 10, "attr": "1&59" }, { - "id": 20, + "equipId": 20, "lv": 11, "attr": "1&60" }, { - "id": 20, + "equipId": 20, "lv": 12, "attr": "1&61" }, { - "id": 20, + "equipId": 20, "lv": 13, "attr": "1&62" }, { - "id": 20, + "equipId": 20, "lv": 14, "attr": "1&63" }, { - "id": 20, + "equipId": 20, "lv": 15, "attr": "1&64" }, { - "id": 20, + "equipId": 20, "lv": 16, "attr": "1&65" }, { - "id": 20, + "equipId": 20, "lv": 17, "attr": "1&66" }, { - "id": 20, + "equipId": 20, "lv": 18, "attr": "1&67" }, { - "id": 20, + "equipId": 20, "lv": 19, "attr": "1&68" }, { - "id": 20, + "equipId": 20, "lv": 20, "attr": "1&69" }, { - "id": 20, + "equipId": 20, "lv": 21, "attr": "1&70" }, { - "id": 20, + "equipId": 20, "lv": 22, "attr": "1&71" }, { - "id": 20, + "equipId": 20, "lv": 23, "attr": "1&72" }, { - "id": 20, + "equipId": 20, "lv": 24, "attr": "1&73" }, { - "id": 20, + "equipId": 20, "lv": 25, "attr": "1&74" }, { - "id": 20, + "equipId": 20, "lv": 26, "attr": "1&75" }, { - "id": 20, + "equipId": 20, "lv": 27, "attr": "1&76" }, { - "id": 20, + "equipId": 20, "lv": 28, "attr": "1&77" }, { - "id": 20, + "equipId": 20, "lv": 29, "attr": "1&78" }, { - "id": 20, + "equipId": 20, "lv": 30, "attr": "1&79" }, { - "id": 20, + "equipId": 20, "lv": 31, "attr": "1&80" }, { - "id": 20, + "equipId": 20, "lv": 32, "attr": "1&81" }, { - "id": 20, + "equipId": 20, "lv": 33, "attr": "1&82" }, { - "id": 20, + "equipId": 20, "lv": 34, "attr": "1&83" }, { - "id": 20, + "equipId": 20, "lv": 35, "attr": "1&84" }, { - "id": 20, + "equipId": 20, "lv": 36, "attr": "1&85" }, { - "id": 20, + "equipId": 20, "lv": 37, "attr": "1&86" }, { - "id": 20, + "equipId": 20, "lv": 38, "attr": "1&87" }, { - "id": 20, + "equipId": 20, "lv": 39, "attr": "1&88" }, { - "id": 20, + "equipId": 20, "lv": 40, "attr": "1&89" }, { - "id": 20, + "equipId": 20, "lv": 41, "attr": "1&90" }, { - "id": 20, + "equipId": 20, "lv": 42, "attr": "1&91" }, { - "id": 20, + "equipId": 20, "lv": 43, "attr": "1&92" }, { - "id": 20, + "equipId": 20, "lv": 44, "attr": "1&93" }, { - "id": 20, + "equipId": 20, "lv": 45, "attr": "1&94" }, { - "id": 20, + "equipId": 20, "lv": 46, "attr": "1&95" }, { - "id": 20, + "equipId": 20, "lv": 47, "attr": "1&96" }, { - "id": 20, + "equipId": 20, "lv": 48, "attr": "1&97" }, { - "id": 20, + "equipId": 20, "lv": 49, "attr": "1&98" }, { - "id": 20, + "equipId": 20, "lv": 50, "attr": "1&99" }, { - "id": 20, + "equipId": 20, "lv": 51, "attr": "1&100" }, { - "id": 20, + "equipId": 20, "lv": 52, "attr": "1&101" }, { - "id": 20, + "equipId": 20, "lv": 53, "attr": "1&102" }, { - "id": 20, + "equipId": 20, "lv": 54, "attr": "1&103" }, { - "id": 20, + "equipId": 20, "lv": 55, "attr": "1&104" }, { - "id": 20, + "equipId": 20, "lv": 56, "attr": "1&105" }, { - "id": 20, + "equipId": 20, "lv": 57, "attr": "1&106" }, { - "id": 20, + "equipId": 20, "lv": 58, "attr": "1&107" }, { - "id": 20, + "equipId": 20, "lv": 59, "attr": "1&108" }, { - "id": 20, + "equipId": 20, "lv": 60, "attr": "1&109" }, { - "id": 20, + "equipId": 20, "lv": 61, "attr": "1&110" }, { - "id": 20, + "equipId": 20, "lv": 62, "attr": "1&111" }, { - "id": 20, + "equipId": 20, "lv": 63, "attr": "1&112" }, { - "id": 20, + "equipId": 20, "lv": 64, "attr": "1&113" }, { - "id": 20, + "equipId": 20, "lv": 65, "attr": "1&114" }, { - "id": 20, + "equipId": 20, "lv": 66, "attr": "1&115" }, { - "id": 20, + "equipId": 20, "lv": 67, "attr": "1&116" }, { - "id": 20, + "equipId": 20, "lv": 68, "attr": "1&117" }, { - "id": 20, + "equipId": 20, "lv": 69, "attr": "1&118" }, { - "id": 20, + "equipId": 20, "lv": 70, "attr": "1&119" }, { - "id": 20, + "equipId": 20, "lv": 71, "attr": "1&120" }, { - "id": 20, + "equipId": 20, "lv": 72, "attr": "1&121" }, { - "id": 20, + "equipId": 20, "lv": 73, "attr": "1&122" }, { - "id": 20, + "equipId": 20, "lv": 74, "attr": "1&123" }, { - "id": 20, + "equipId": 20, "lv": 75, "attr": "1&124" }, { - "id": 20, + "equipId": 20, "lv": 76, "attr": "1&125" }, { - "id": 20, + "equipId": 20, "lv": 77, "attr": "1&126" }, { - "id": 20, + "equipId": 20, "lv": 78, "attr": "1&127" }, { - "id": 20, + "equipId": 20, "lv": 79, "attr": "1&128" }, { - "id": 20, + "equipId": 20, "lv": 80, "attr": "1&129" }, { - "id": 20, + "equipId": 20, "lv": 81, "attr": "1&130" }, { - "id": 20, + "equipId": 20, "lv": 82, "attr": "1&131" }, { - "id": 20, + "equipId": 20, "lv": 83, "attr": "1&132" }, { - "id": 20, + "equipId": 20, "lv": 84, "attr": "1&133" }, { - "id": 20, + "equipId": 20, "lv": 85, "attr": "1&134" }, { - "id": 20, + "equipId": 20, "lv": 86, "attr": "1&135" }, { - "id": 20, + "equipId": 20, "lv": 87, "attr": "1&136" }, { - "id": 20, + "equipId": 20, "lv": 88, "attr": "1&137" }, { - "id": 20, + "equipId": 20, "lv": 89, "attr": "1&138" }, { - "id": 20, + "equipId": 20, "lv": 90, "attr": "1&139" }, { - "id": 20, + "equipId": 20, "lv": 91, "attr": "1&140" }, { - "id": 20, + "equipId": 20, "lv": 92, "attr": "1&141" }, { - "id": 20, + "equipId": 20, "lv": 93, "attr": "1&142" }, { - "id": 20, + "equipId": 20, "lv": 94, "attr": "1&143" }, { - "id": 20, + "equipId": 20, "lv": 95, "attr": "1&144" }, { - "id": 20, + "equipId": 20, "lv": 96, "attr": "1&145" }, { - "id": 20, + "equipId": 20, "lv": 97, "attr": "1&146" }, { - "id": 20, + "equipId": 20, "lv": 98, "attr": "1&147" }, { - "id": 20, + "equipId": 20, "lv": 99, "attr": "1&148" }, { - "id": 20, + "equipId": 20, "lv": 100, "attr": "1&149" }, { - "id": 21, + "equipId": 21, + "lv": 0, + "attr": "2&10" + }, + { + "equipId": 21, "lv": 1, "attr": "2&10" }, { - "id": 21, + "equipId": 21, "lv": 2, "attr": "2&11" }, { - "id": 21, + "equipId": 21, "lv": 3, "attr": "2&12" }, { - "id": 21, + "equipId": 21, "lv": 4, "attr": "2&13" }, { - "id": 21, + "equipId": 21, "lv": 5, "attr": "2&14" }, { - "id": 21, + "equipId": 21, "lv": 6, "attr": "2&15" }, { - "id": 21, + "equipId": 21, "lv": 7, "attr": "2&16" }, { - "id": 21, + "equipId": 21, "lv": 8, "attr": "2&17" }, { - "id": 21, + "equipId": 21, "lv": 9, "attr": "2&18" }, { - "id": 21, + "equipId": 21, "lv": 10, "attr": "2&19" }, { - "id": 21, + "equipId": 21, "lv": 11, "attr": "2&20" }, { - "id": 21, + "equipId": 21, "lv": 12, "attr": "2&21" }, { - "id": 21, + "equipId": 21, "lv": 13, "attr": "2&22" }, { - "id": 21, + "equipId": 21, "lv": 14, "attr": "2&23" }, { - "id": 21, + "equipId": 21, "lv": 15, "attr": "2&24" }, { - "id": 21, + "equipId": 21, "lv": 16, "attr": "2&25" }, { - "id": 21, + "equipId": 21, "lv": 17, "attr": "2&26" }, { - "id": 21, + "equipId": 21, "lv": 18, "attr": "2&27" }, { - "id": 21, + "equipId": 21, "lv": 19, "attr": "2&28" }, { - "id": 21, + "equipId": 21, "lv": 20, "attr": "2&29" }, { - "id": 21, + "equipId": 21, "lv": 21, "attr": "2&30" }, { - "id": 21, + "equipId": 21, "lv": 22, "attr": "2&31" }, { - "id": 21, + "equipId": 21, "lv": 23, "attr": "2&32" }, { - "id": 21, + "equipId": 21, "lv": 24, "attr": "2&33" }, { - "id": 21, + "equipId": 21, "lv": 25, "attr": "2&34" }, { - "id": 21, + "equipId": 21, "lv": 26, "attr": "2&35" }, { - "id": 21, + "equipId": 21, "lv": 27, "attr": "2&36" }, { - "id": 21, + "equipId": 21, "lv": 28, "attr": "2&37" }, { - "id": 21, + "equipId": 21, "lv": 29, "attr": "2&38" }, { - "id": 21, + "equipId": 21, "lv": 30, "attr": "2&39" }, { - "id": 21, + "equipId": 21, "lv": 31, "attr": "2&40" }, { - "id": 21, + "equipId": 21, "lv": 32, "attr": "2&41" }, { - "id": 21, + "equipId": 21, "lv": 33, "attr": "2&42" }, { - "id": 21, + "equipId": 21, "lv": 34, "attr": "2&43" }, { - "id": 21, + "equipId": 21, "lv": 35, "attr": "2&44" }, { - "id": 21, + "equipId": 21, "lv": 36, "attr": "2&45" }, { - "id": 21, + "equipId": 21, "lv": 37, "attr": "2&46" }, { - "id": 21, + "equipId": 21, "lv": 38, "attr": "2&47" }, { - "id": 21, + "equipId": 21, "lv": 39, "attr": "2&48" }, { - "id": 21, + "equipId": 21, "lv": 40, "attr": "2&49" }, { - "id": 21, + "equipId": 21, "lv": 41, "attr": "2&50" }, { - "id": 21, + "equipId": 21, "lv": 42, "attr": "2&51" }, { - "id": 21, + "equipId": 21, "lv": 43, "attr": "2&52" }, { - "id": 21, + "equipId": 21, "lv": 44, "attr": "2&53" }, { - "id": 21, + "equipId": 21, "lv": 45, "attr": "2&54" }, { - "id": 21, + "equipId": 21, "lv": 46, "attr": "2&55" }, { - "id": 21, + "equipId": 21, "lv": 47, "attr": "2&56" }, { - "id": 21, + "equipId": 21, "lv": 48, "attr": "2&57" }, { - "id": 21, + "equipId": 21, "lv": 49, "attr": "2&58" }, { - "id": 21, + "equipId": 21, "lv": 50, "attr": "2&59" }, { - "id": 21, + "equipId": 21, "lv": 51, "attr": "2&60" }, { - "id": 21, + "equipId": 21, "lv": 52, "attr": "2&61" }, { - "id": 21, + "equipId": 21, "lv": 53, "attr": "2&62" }, { - "id": 21, + "equipId": 21, "lv": 54, "attr": "2&63" }, { - "id": 21, + "equipId": 21, "lv": 55, "attr": "2&64" }, { - "id": 21, + "equipId": 21, "lv": 56, "attr": "2&65" }, { - "id": 21, + "equipId": 21, "lv": 57, "attr": "2&66" }, { - "id": 21, + "equipId": 21, "lv": 58, "attr": "2&67" }, { - "id": 21, + "equipId": 21, "lv": 59, "attr": "2&68" }, { - "id": 21, + "equipId": 21, "lv": 60, "attr": "2&69" }, { - "id": 21, + "equipId": 21, "lv": 61, "attr": "2&70" }, { - "id": 21, + "equipId": 21, "lv": 62, "attr": "2&71" }, { - "id": 21, + "equipId": 21, "lv": 63, "attr": "2&72" }, { - "id": 21, + "equipId": 21, "lv": 64, "attr": "2&73" }, { - "id": 21, + "equipId": 21, "lv": 65, "attr": "2&74" }, { - "id": 21, + "equipId": 21, "lv": 66, "attr": "2&75" }, { - "id": 21, + "equipId": 21, "lv": 67, "attr": "2&76" }, { - "id": 21, + "equipId": 21, "lv": 68, "attr": "2&77" }, { - "id": 21, + "equipId": 21, "lv": 69, "attr": "2&78" }, { - "id": 21, + "equipId": 21, "lv": 70, "attr": "2&79" }, { - "id": 21, + "equipId": 21, "lv": 71, "attr": "2&80" }, { - "id": 21, + "equipId": 21, "lv": 72, "attr": "2&81" }, { - "id": 21, + "equipId": 21, "lv": 73, "attr": "2&82" }, { - "id": 21, + "equipId": 21, "lv": 74, "attr": "2&83" }, { - "id": 21, + "equipId": 21, "lv": 75, "attr": "2&84" }, { - "id": 21, + "equipId": 21, "lv": 76, "attr": "2&85" }, { - "id": 21, + "equipId": 21, "lv": 77, "attr": "2&86" }, { - "id": 21, + "equipId": 21, "lv": 78, "attr": "2&87" }, { - "id": 21, + "equipId": 21, "lv": 79, "attr": "2&88" }, { - "id": 21, + "equipId": 21, "lv": 80, "attr": "2&89" }, { - "id": 21, + "equipId": 21, "lv": 81, "attr": "2&90" }, { - "id": 21, + "equipId": 21, "lv": 82, "attr": "2&91" }, { - "id": 21, + "equipId": 21, "lv": 83, "attr": "2&92" }, { - "id": 21, + "equipId": 21, "lv": 84, "attr": "2&93" }, { - "id": 21, + "equipId": 21, "lv": 85, "attr": "2&94" }, { - "id": 21, + "equipId": 21, "lv": 86, "attr": "2&95" }, { - "id": 21, + "equipId": 21, "lv": 87, "attr": "2&96" }, { - "id": 21, + "equipId": 21, "lv": 88, "attr": "2&97" }, { - "id": 21, + "equipId": 21, "lv": 89, "attr": "2&98" }, { - "id": 21, + "equipId": 21, "lv": 90, "attr": "2&99" }, { - "id": 21, + "equipId": 21, "lv": 91, "attr": "2&100" }, { - "id": 21, + "equipId": 21, "lv": 92, "attr": "2&101" }, { - "id": 21, + "equipId": 21, "lv": 93, "attr": "2&102" }, { - "id": 21, + "equipId": 21, "lv": 94, "attr": "2&103" }, { - "id": 21, + "equipId": 21, "lv": 95, "attr": "2&104" }, { - "id": 21, + "equipId": 21, "lv": 96, "attr": "2&105" }, { - "id": 21, + "equipId": 21, "lv": 97, "attr": "2&106" }, { - "id": 21, + "equipId": 21, "lv": 98, "attr": "2&107" }, { - "id": 21, + "equipId": 21, "lv": 99, "attr": "2&108" }, { - "id": 21, + "equipId": 21, "lv": 100, "attr": "2&109" }, { - "id": 22, + "equipId": 22, + "lv": 0, + "attr": "4&20" + }, + { + "equipId": 22, "lv": 1, "attr": "4&20" }, { - "id": 22, + "equipId": 22, "lv": 2, "attr": "4&21" }, { - "id": 22, + "equipId": 22, "lv": 3, "attr": "4&22" }, { - "id": 22, + "equipId": 22, "lv": 4, "attr": "4&23" }, { - "id": 22, + "equipId": 22, "lv": 5, "attr": "4&24" }, { - "id": 22, + "equipId": 22, "lv": 6, "attr": "4&25" }, { - "id": 22, + "equipId": 22, "lv": 7, "attr": "4&26" }, { - "id": 22, + "equipId": 22, "lv": 8, "attr": "4&27" }, { - "id": 22, + "equipId": 22, "lv": 9, "attr": "4&28" }, { - "id": 22, + "equipId": 22, "lv": 10, "attr": "4&29" }, { - "id": 22, + "equipId": 22, "lv": 11, "attr": "4&30" }, { - "id": 22, + "equipId": 22, "lv": 12, "attr": "4&31" }, { - "id": 22, + "equipId": 22, "lv": 13, "attr": "4&32" }, { - "id": 22, + "equipId": 22, "lv": 14, "attr": "4&33" }, { - "id": 22, + "equipId": 22, "lv": 15, "attr": "4&34" }, { - "id": 22, + "equipId": 22, "lv": 16, "attr": "4&35" }, { - "id": 22, + "equipId": 22, "lv": 17, "attr": "4&36" }, { - "id": 22, + "equipId": 22, "lv": 18, "attr": "4&37" }, { - "id": 22, + "equipId": 22, "lv": 19, "attr": "4&38" }, { - "id": 22, + "equipId": 22, "lv": 20, "attr": "4&39" }, { - "id": 22, + "equipId": 22, "lv": 21, "attr": "4&40" }, { - "id": 22, + "equipId": 22, "lv": 22, "attr": "4&41" }, { - "id": 22, + "equipId": 22, "lv": 23, "attr": "4&42" }, { - "id": 22, + "equipId": 22, "lv": 24, "attr": "4&43" }, { - "id": 22, + "equipId": 22, "lv": 25, "attr": "4&44" }, { - "id": 22, + "equipId": 22, "lv": 26, "attr": "4&45" }, { - "id": 22, + "equipId": 22, "lv": 27, "attr": "4&46" }, { - "id": 22, + "equipId": 22, "lv": 28, "attr": "4&47" }, { - "id": 22, + "equipId": 22, "lv": 29, "attr": "4&48" }, { - "id": 22, + "equipId": 22, "lv": 30, "attr": "4&49" }, { - "id": 22, + "equipId": 22, "lv": 31, "attr": "4&50" }, { - "id": 22, + "equipId": 22, "lv": 32, "attr": "4&51" }, { - "id": 22, + "equipId": 22, "lv": 33, "attr": "4&52" }, { - "id": 22, + "equipId": 22, "lv": 34, "attr": "4&53" }, { - "id": 22, + "equipId": 22, "lv": 35, "attr": "4&54" }, { - "id": 22, + "equipId": 22, "lv": 36, "attr": "4&55" }, { - "id": 22, + "equipId": 22, "lv": 37, "attr": "4&56" }, { - "id": 22, + "equipId": 22, "lv": 38, "attr": "4&57" }, { - "id": 22, + "equipId": 22, "lv": 39, "attr": "4&58" }, { - "id": 22, + "equipId": 22, "lv": 40, "attr": "4&59" }, { - "id": 22, + "equipId": 22, "lv": 41, "attr": "4&60" }, { - "id": 22, + "equipId": 22, "lv": 42, "attr": "4&61" }, { - "id": 22, + "equipId": 22, "lv": 43, "attr": "4&62" }, { - "id": 22, + "equipId": 22, "lv": 44, "attr": "4&63" }, { - "id": 22, + "equipId": 22, "lv": 45, "attr": "4&64" }, { - "id": 22, + "equipId": 22, "lv": 46, "attr": "4&65" }, { - "id": 22, + "equipId": 22, "lv": 47, "attr": "4&66" }, { - "id": 22, + "equipId": 22, "lv": 48, "attr": "4&67" }, { - "id": 22, + "equipId": 22, "lv": 49, "attr": "4&68" }, { - "id": 22, + "equipId": 22, "lv": 50, "attr": "4&69" }, { - "id": 22, + "equipId": 22, "lv": 51, "attr": "4&70" }, { - "id": 22, + "equipId": 22, "lv": 52, "attr": "4&71" }, { - "id": 22, + "equipId": 22, "lv": 53, "attr": "4&72" }, { - "id": 22, + "equipId": 22, "lv": 54, "attr": "4&73" }, { - "id": 22, + "equipId": 22, "lv": 55, "attr": "4&74" }, { - "id": 22, + "equipId": 22, "lv": 56, "attr": "4&75" }, { - "id": 22, + "equipId": 22, "lv": 57, "attr": "4&76" }, { - "id": 22, + "equipId": 22, "lv": 58, "attr": "4&77" }, { - "id": 22, + "equipId": 22, "lv": 59, "attr": "4&78" }, { - "id": 22, + "equipId": 22, "lv": 60, "attr": "4&79" }, { - "id": 22, + "equipId": 22, "lv": 61, "attr": "4&80" }, { - "id": 22, + "equipId": 22, "lv": 62, "attr": "4&81" }, { - "id": 22, + "equipId": 22, "lv": 63, "attr": "4&82" }, { - "id": 22, + "equipId": 22, "lv": 64, "attr": "4&83" }, { - "id": 22, + "equipId": 22, "lv": 65, "attr": "4&84" }, { - "id": 22, + "equipId": 22, "lv": 66, "attr": "4&85" }, { - "id": 22, + "equipId": 22, "lv": 67, "attr": "4&86" }, { - "id": 22, + "equipId": 22, "lv": 68, "attr": "4&87" }, { - "id": 22, + "equipId": 22, "lv": 69, "attr": "4&88" }, { - "id": 22, + "equipId": 22, "lv": 70, "attr": "4&89" }, { - "id": 22, + "equipId": 22, "lv": 71, "attr": "4&90" }, { - "id": 22, + "equipId": 22, "lv": 72, "attr": "4&91" }, { - "id": 22, + "equipId": 22, "lv": 73, "attr": "4&92" }, { - "id": 22, + "equipId": 22, "lv": 74, "attr": "4&93" }, { - "id": 22, + "equipId": 22, "lv": 75, "attr": "4&94" }, { - "id": 22, + "equipId": 22, "lv": 76, "attr": "4&95" }, { - "id": 22, + "equipId": 22, "lv": 77, "attr": "4&96" }, { - "id": 22, + "equipId": 22, "lv": 78, "attr": "4&97" }, { - "id": 22, + "equipId": 22, "lv": 79, "attr": "4&98" }, { - "id": 22, + "equipId": 22, "lv": 80, "attr": "4&99" }, { - "id": 22, + "equipId": 22, "lv": 81, "attr": "4&100" }, { - "id": 22, + "equipId": 22, "lv": 82, "attr": "4&101" }, { - "id": 22, + "equipId": 22, "lv": 83, "attr": "4&102" }, { - "id": 22, + "equipId": 22, "lv": 84, "attr": "4&103" }, { - "id": 22, + "equipId": 22, "lv": 85, "attr": "4&104" }, { - "id": 22, + "equipId": 22, "lv": 86, "attr": "4&105" }, { - "id": 22, + "equipId": 22, "lv": 87, "attr": "4&106" }, { - "id": 22, + "equipId": 22, "lv": 88, "attr": "4&107" }, { - "id": 22, + "equipId": 22, "lv": 89, "attr": "4&108" }, { - "id": 22, + "equipId": 22, "lv": 90, "attr": "4&109" }, { - "id": 22, + "equipId": 22, "lv": 91, "attr": "4&110" }, { - "id": 22, + "equipId": 22, "lv": 92, "attr": "4&111" }, { - "id": 22, + "equipId": 22, "lv": 93, "attr": "4&112" }, { - "id": 22, + "equipId": 22, "lv": 94, "attr": "4&113" }, { - "id": 22, + "equipId": 22, "lv": 95, "attr": "4&114" }, { - "id": 22, + "equipId": 22, "lv": 96, "attr": "4&115" }, { - "id": 22, + "equipId": 22, "lv": 97, "attr": "4&116" }, { - "id": 22, + "equipId": 22, "lv": 98, "attr": "4&117" }, { - "id": 22, + "equipId": 22, "lv": 99, "attr": "4&118" }, { - "id": 22, + "equipId": 22, "lv": 100, "attr": "4&119" }, { - "id": 23, + "equipId": 23, + "lv": 0, + "attr": "5&20" + }, + { + "equipId": 23, "lv": 1, "attr": "5&20" }, { - "id": 23, + "equipId": 23, "lv": 2, "attr": "5&21" }, { - "id": 23, + "equipId": 23, "lv": 3, "attr": "5&22" }, { - "id": 23, + "equipId": 23, "lv": 4, "attr": "5&23" }, { - "id": 23, + "equipId": 23, "lv": 5, "attr": "5&24" }, { - "id": 23, + "equipId": 23, "lv": 6, "attr": "5&25" }, { - "id": 23, + "equipId": 23, "lv": 7, "attr": "5&26" }, { - "id": 23, + "equipId": 23, "lv": 8, "attr": "5&27" }, { - "id": 23, + "equipId": 23, "lv": 9, "attr": "5&28" }, { - "id": 23, + "equipId": 23, "lv": 10, "attr": "5&29" }, { - "id": 23, + "equipId": 23, "lv": 11, "attr": "5&30" }, { - "id": 23, + "equipId": 23, "lv": 12, "attr": "5&31" }, { - "id": 23, + "equipId": 23, "lv": 13, "attr": "5&32" }, { - "id": 23, + "equipId": 23, "lv": 14, "attr": "5&33" }, { - "id": 23, + "equipId": 23, "lv": 15, "attr": "5&34" }, { - "id": 23, + "equipId": 23, "lv": 16, "attr": "5&35" }, { - "id": 23, + "equipId": 23, "lv": 17, "attr": "5&36" }, { - "id": 23, + "equipId": 23, "lv": 18, "attr": "5&37" }, { - "id": 23, + "equipId": 23, "lv": 19, "attr": "5&38" }, { - "id": 23, + "equipId": 23, "lv": 20, "attr": "5&39" }, { - "id": 23, + "equipId": 23, "lv": 21, "attr": "5&40" }, { - "id": 23, + "equipId": 23, "lv": 22, "attr": "5&41" }, { - "id": 23, + "equipId": 23, "lv": 23, "attr": "5&42" }, { - "id": 23, + "equipId": 23, "lv": 24, "attr": "5&43" }, { - "id": 23, + "equipId": 23, "lv": 25, "attr": "5&44" }, { - "id": 23, + "equipId": 23, "lv": 26, "attr": "5&45" }, { - "id": 23, + "equipId": 23, "lv": 27, "attr": "5&46" }, { - "id": 23, + "equipId": 23, "lv": 28, "attr": "5&47" }, { - "id": 23, + "equipId": 23, "lv": 29, "attr": "5&48" }, { - "id": 23, + "equipId": 23, "lv": 30, "attr": "5&49" }, { - "id": 23, + "equipId": 23, "lv": 31, "attr": "5&50" }, { - "id": 23, + "equipId": 23, "lv": 32, "attr": "5&51" }, { - "id": 23, + "equipId": 23, "lv": 33, "attr": "5&52" }, { - "id": 23, + "equipId": 23, "lv": 34, "attr": "5&53" }, { - "id": 23, + "equipId": 23, "lv": 35, "attr": "5&54" }, { - "id": 23, + "equipId": 23, "lv": 36, "attr": "5&55" }, { - "id": 23, + "equipId": 23, "lv": 37, "attr": "5&56" }, { - "id": 23, + "equipId": 23, "lv": 38, "attr": "5&57" }, { - "id": 23, + "equipId": 23, "lv": 39, "attr": "5&58" }, { - "id": 23, + "equipId": 23, "lv": 40, "attr": "5&59" }, { - "id": 23, + "equipId": 23, "lv": 41, "attr": "5&60" }, { - "id": 23, + "equipId": 23, "lv": 42, "attr": "5&61" }, { - "id": 23, + "equipId": 23, "lv": 43, "attr": "5&62" }, { - "id": 23, + "equipId": 23, "lv": 44, "attr": "5&63" }, { - "id": 23, + "equipId": 23, "lv": 45, "attr": "5&64" }, { - "id": 23, + "equipId": 23, "lv": 46, "attr": "5&65" }, { - "id": 23, + "equipId": 23, "lv": 47, "attr": "5&66" }, { - "id": 23, + "equipId": 23, "lv": 48, "attr": "5&67" }, { - "id": 23, + "equipId": 23, "lv": 49, "attr": "5&68" }, { - "id": 23, + "equipId": 23, "lv": 50, "attr": "5&69" }, { - "id": 23, + "equipId": 23, "lv": 51, "attr": "5&70" }, { - "id": 23, + "equipId": 23, "lv": 52, "attr": "5&71" }, { - "id": 23, + "equipId": 23, "lv": 53, "attr": "5&72" }, { - "id": 23, + "equipId": 23, "lv": 54, "attr": "5&73" }, { - "id": 23, + "equipId": 23, "lv": 55, "attr": "5&74" }, { - "id": 23, + "equipId": 23, "lv": 56, "attr": "5&75" }, { - "id": 23, + "equipId": 23, "lv": 57, "attr": "5&76" }, { - "id": 23, + "equipId": 23, "lv": 58, "attr": "5&77" }, { - "id": 23, + "equipId": 23, "lv": 59, "attr": "5&78" }, { - "id": 23, + "equipId": 23, "lv": 60, "attr": "5&79" }, { - "id": 23, + "equipId": 23, "lv": 61, "attr": "5&80" }, { - "id": 23, + "equipId": 23, "lv": 62, "attr": "5&81" }, { - "id": 23, + "equipId": 23, "lv": 63, "attr": "5&82" }, { - "id": 23, + "equipId": 23, "lv": 64, "attr": "5&83" }, { - "id": 23, + "equipId": 23, "lv": 65, "attr": "5&84" }, { - "id": 23, + "equipId": 23, "lv": 66, "attr": "5&85" }, { - "id": 23, + "equipId": 23, "lv": 67, "attr": "5&86" }, { - "id": 23, + "equipId": 23, "lv": 68, "attr": "5&87" }, { - "id": 23, + "equipId": 23, "lv": 69, "attr": "5&88" }, { - "id": 23, + "equipId": 23, "lv": 70, "attr": "5&89" }, { - "id": 23, + "equipId": 23, "lv": 71, "attr": "5&90" }, { - "id": 23, + "equipId": 23, "lv": 72, "attr": "5&91" }, { - "id": 23, + "equipId": 23, "lv": 73, "attr": "5&92" }, { - "id": 23, + "equipId": 23, "lv": 74, "attr": "5&93" }, { - "id": 23, + "equipId": 23, "lv": 75, "attr": "5&94" }, { - "id": 23, + "equipId": 23, "lv": 76, "attr": "5&95" }, { - "id": 23, + "equipId": 23, "lv": 77, "attr": "5&96" }, { - "id": 23, + "equipId": 23, "lv": 78, "attr": "5&97" }, { - "id": 23, + "equipId": 23, "lv": 79, "attr": "5&98" }, { - "id": 23, + "equipId": 23, "lv": 80, "attr": "5&99" }, { - "id": 23, + "equipId": 23, "lv": 81, "attr": "5&100" }, { - "id": 23, + "equipId": 23, "lv": 82, "attr": "5&101" }, { - "id": 23, + "equipId": 23, "lv": 83, "attr": "5&102" }, { - "id": 23, + "equipId": 23, "lv": 84, "attr": "5&103" }, { - "id": 23, + "equipId": 23, "lv": 85, "attr": "5&104" }, { - "id": 23, + "equipId": 23, "lv": 86, "attr": "5&105" }, { - "id": 23, + "equipId": 23, "lv": 87, "attr": "5&106" }, { - "id": 23, + "equipId": 23, "lv": 88, "attr": "5&107" }, { - "id": 23, + "equipId": 23, "lv": 89, "attr": "5&108" }, { - "id": 23, + "equipId": 23, "lv": 90, "attr": "5&109" }, { - "id": 23, + "equipId": 23, "lv": 91, "attr": "5&110" }, { - "id": 23, + "equipId": 23, "lv": 92, "attr": "5&111" }, { - "id": 23, + "equipId": 23, "lv": 93, "attr": "5&112" }, { - "id": 23, + "equipId": 23, "lv": 94, "attr": "5&113" }, { - "id": 23, + "equipId": 23, "lv": 95, "attr": "5&114" }, { - "id": 23, + "equipId": 23, "lv": 96, "attr": "5&115" }, { - "id": 23, + "equipId": 23, "lv": 97, "attr": "5&116" }, { - "id": 23, + "equipId": 23, "lv": 98, "attr": "5&117" }, { - "id": 23, + "equipId": 23, "lv": 99, "attr": "5&118" }, { - "id": 23, + "equipId": 23, "lv": 100, "attr": "5&119" }, { - "id": 24, + "equipId": 24, + "lv": 0, + "attr": "1&50" + }, + { + "equipId": 24, "lv": 1, "attr": "1&50" }, { - "id": 24, + "equipId": 24, "lv": 2, "attr": "1&51" }, { - "id": 24, + "equipId": 24, "lv": 3, "attr": "1&52" }, { - "id": 24, + "equipId": 24, "lv": 4, "attr": "1&53" }, { - "id": 24, + "equipId": 24, "lv": 5, "attr": "1&54" }, { - "id": 24, + "equipId": 24, "lv": 6, "attr": "1&55" }, { - "id": 24, + "equipId": 24, "lv": 7, "attr": "1&56" }, { - "id": 24, + "equipId": 24, "lv": 8, "attr": "1&57" }, { - "id": 24, + "equipId": 24, "lv": 9, "attr": "1&58" }, { - "id": 24, + "equipId": 24, "lv": 10, "attr": "1&59" }, { - "id": 24, + "equipId": 24, "lv": 11, "attr": "1&60" }, { - "id": 24, + "equipId": 24, "lv": 12, "attr": "1&61" }, { - "id": 24, + "equipId": 24, "lv": 13, "attr": "1&62" }, { - "id": 24, + "equipId": 24, "lv": 14, "attr": "1&63" }, { - "id": 24, + "equipId": 24, "lv": 15, "attr": "1&64" }, { - "id": 24, + "equipId": 24, "lv": 16, "attr": "1&65" }, { - "id": 24, + "equipId": 24, "lv": 17, "attr": "1&66" }, { - "id": 24, + "equipId": 24, "lv": 18, "attr": "1&67" }, { - "id": 24, + "equipId": 24, "lv": 19, "attr": "1&68" }, { - "id": 24, + "equipId": 24, "lv": 20, "attr": "1&69" }, { - "id": 24, + "equipId": 24, "lv": 21, "attr": "1&70" }, { - "id": 24, + "equipId": 24, "lv": 22, "attr": "1&71" }, { - "id": 24, + "equipId": 24, "lv": 23, "attr": "1&72" }, { - "id": 24, + "equipId": 24, "lv": 24, "attr": "1&73" }, { - "id": 24, + "equipId": 24, "lv": 25, "attr": "1&74" }, { - "id": 24, + "equipId": 24, "lv": 26, "attr": "1&75" }, { - "id": 24, + "equipId": 24, "lv": 27, "attr": "1&76" }, { - "id": 24, + "equipId": 24, "lv": 28, "attr": "1&77" }, { - "id": 24, + "equipId": 24, "lv": 29, "attr": "1&78" }, { - "id": 24, + "equipId": 24, "lv": 30, "attr": "1&79" }, { - "id": 24, + "equipId": 24, "lv": 31, "attr": "1&80" }, { - "id": 24, + "equipId": 24, "lv": 32, "attr": "1&81" }, { - "id": 24, + "equipId": 24, "lv": 33, "attr": "1&82" }, { - "id": 24, + "equipId": 24, "lv": 34, "attr": "1&83" }, { - "id": 24, + "equipId": 24, "lv": 35, "attr": "1&84" }, { - "id": 24, + "equipId": 24, "lv": 36, "attr": "1&85" }, { - "id": 24, + "equipId": 24, "lv": 37, "attr": "1&86" }, { - "id": 24, + "equipId": 24, "lv": 38, "attr": "1&87" }, { - "id": 24, + "equipId": 24, "lv": 39, "attr": "1&88" }, { - "id": 24, + "equipId": 24, "lv": 40, "attr": "1&89" }, { - "id": 24, + "equipId": 24, "lv": 41, "attr": "1&90" }, { - "id": 24, + "equipId": 24, "lv": 42, "attr": "1&91" }, { - "id": 24, + "equipId": 24, "lv": 43, "attr": "1&92" }, { - "id": 24, + "equipId": 24, "lv": 44, "attr": "1&93" }, { - "id": 24, + "equipId": 24, "lv": 45, "attr": "1&94" }, { - "id": 24, + "equipId": 24, "lv": 46, "attr": "1&95" }, { - "id": 24, + "equipId": 24, "lv": 47, "attr": "1&96" }, { - "id": 24, + "equipId": 24, "lv": 48, "attr": "1&97" }, { - "id": 24, + "equipId": 24, "lv": 49, "attr": "1&98" }, { - "id": 24, + "equipId": 24, "lv": 50, "attr": "1&99" }, { - "id": 24, + "equipId": 24, "lv": 51, "attr": "1&100" }, { - "id": 24, + "equipId": 24, "lv": 52, "attr": "1&101" }, { - "id": 24, + "equipId": 24, "lv": 53, "attr": "1&102" }, { - "id": 24, + "equipId": 24, "lv": 54, "attr": "1&103" }, { - "id": 24, + "equipId": 24, "lv": 55, "attr": "1&104" }, { - "id": 24, + "equipId": 24, "lv": 56, "attr": "1&105" }, { - "id": 24, + "equipId": 24, "lv": 57, "attr": "1&106" }, { - "id": 24, + "equipId": 24, "lv": 58, "attr": "1&107" }, { - "id": 24, + "equipId": 24, "lv": 59, "attr": "1&108" }, { - "id": 24, + "equipId": 24, "lv": 60, "attr": "1&109" }, { - "id": 24, + "equipId": 24, "lv": 61, "attr": "1&110" }, { - "id": 24, + "equipId": 24, "lv": 62, "attr": "1&111" }, { - "id": 24, + "equipId": 24, "lv": 63, "attr": "1&112" }, { - "id": 24, + "equipId": 24, "lv": 64, "attr": "1&113" }, { - "id": 24, + "equipId": 24, "lv": 65, "attr": "1&114" }, { - "id": 24, + "equipId": 24, "lv": 66, "attr": "1&115" }, { - "id": 24, + "equipId": 24, "lv": 67, "attr": "1&116" }, { - "id": 24, + "equipId": 24, "lv": 68, "attr": "1&117" }, { - "id": 24, + "equipId": 24, "lv": 69, "attr": "1&118" }, { - "id": 24, + "equipId": 24, "lv": 70, "attr": "1&119" }, { - "id": 24, + "equipId": 24, "lv": 71, "attr": "1&120" }, { - "id": 24, + "equipId": 24, "lv": 72, "attr": "1&121" }, { - "id": 24, + "equipId": 24, "lv": 73, "attr": "1&122" }, { - "id": 24, + "equipId": 24, "lv": 74, "attr": "1&123" }, { - "id": 24, + "equipId": 24, "lv": 75, "attr": "1&124" }, { - "id": 24, + "equipId": 24, "lv": 76, "attr": "1&125" }, { - "id": 24, + "equipId": 24, "lv": 77, "attr": "1&126" }, { - "id": 24, + "equipId": 24, "lv": 78, "attr": "1&127" }, { - "id": 24, + "equipId": 24, "lv": 79, "attr": "1&128" }, { - "id": 24, + "equipId": 24, "lv": 80, "attr": "1&129" }, { - "id": 24, + "equipId": 24, "lv": 81, "attr": "1&130" }, { - "id": 24, + "equipId": 24, "lv": 82, "attr": "1&131" }, { - "id": 24, + "equipId": 24, "lv": 83, "attr": "1&132" }, { - "id": 24, + "equipId": 24, "lv": 84, "attr": "1&133" }, { - "id": 24, + "equipId": 24, "lv": 85, "attr": "1&134" }, { - "id": 24, + "equipId": 24, "lv": 86, "attr": "1&135" }, { - "id": 24, + "equipId": 24, "lv": 87, "attr": "1&136" }, { - "id": 24, + "equipId": 24, "lv": 88, "attr": "1&137" }, { - "id": 24, + "equipId": 24, "lv": 89, "attr": "1&138" }, { - "id": 24, + "equipId": 24, "lv": 90, "attr": "1&139" }, { - "id": 24, + "equipId": 24, "lv": 91, "attr": "1&140" }, { - "id": 24, + "equipId": 24, "lv": 92, "attr": "1&141" }, { - "id": 24, + "equipId": 24, "lv": 93, "attr": "1&142" }, { - "id": 24, + "equipId": 24, "lv": 94, "attr": "1&143" }, { - "id": 24, + "equipId": 24, "lv": 95, "attr": "1&144" }, { - "id": 24, + "equipId": 24, "lv": 96, "attr": "1&145" }, { - "id": 24, + "equipId": 24, "lv": 97, "attr": "1&146" }, { - "id": 24, + "equipId": 24, "lv": 98, "attr": "1&147" }, { - "id": 24, + "equipId": 24, "lv": 99, "attr": "1&148" }, { - "id": 24, + "equipId": 24, "lv": 100, "attr": "1&149" }, { - "id": 25, + "equipId": 25, + "lv": 0, + "attr": "2&10" + }, + { + "equipId": 25, "lv": 1, "attr": "2&10" }, { - "id": 25, + "equipId": 25, "lv": 2, "attr": "2&11" }, { - "id": 25, + "equipId": 25, "lv": 3, "attr": "2&12" }, { - "id": 25, + "equipId": 25, "lv": 4, "attr": "2&13" }, { - "id": 25, + "equipId": 25, "lv": 5, "attr": "2&14" }, { - "id": 25, + "equipId": 25, "lv": 6, "attr": "2&15" }, { - "id": 25, + "equipId": 25, "lv": 7, "attr": "2&16" }, { - "id": 25, + "equipId": 25, "lv": 8, "attr": "2&17" }, { - "id": 25, + "equipId": 25, "lv": 9, "attr": "2&18" }, { - "id": 25, + "equipId": 25, "lv": 10, "attr": "2&19" }, { - "id": 25, + "equipId": 25, "lv": 11, "attr": "2&20" }, { - "id": 25, + "equipId": 25, "lv": 12, "attr": "2&21" }, { - "id": 25, + "equipId": 25, "lv": 13, "attr": "2&22" }, { - "id": 25, + "equipId": 25, "lv": 14, "attr": "2&23" }, { - "id": 25, + "equipId": 25, "lv": 15, "attr": "2&24" }, { - "id": 25, + "equipId": 25, "lv": 16, "attr": "2&25" }, { - "id": 25, + "equipId": 25, "lv": 17, "attr": "2&26" }, { - "id": 25, + "equipId": 25, "lv": 18, "attr": "2&27" }, { - "id": 25, + "equipId": 25, "lv": 19, "attr": "2&28" }, { - "id": 25, + "equipId": 25, "lv": 20, "attr": "2&29" }, { - "id": 25, + "equipId": 25, "lv": 21, "attr": "2&30" }, { - "id": 25, + "equipId": 25, "lv": 22, "attr": "2&31" }, { - "id": 25, + "equipId": 25, "lv": 23, "attr": "2&32" }, { - "id": 25, + "equipId": 25, "lv": 24, "attr": "2&33" }, { - "id": 25, + "equipId": 25, "lv": 25, "attr": "2&34" }, { - "id": 25, + "equipId": 25, "lv": 26, "attr": "2&35" }, { - "id": 25, + "equipId": 25, "lv": 27, "attr": "2&36" }, { - "id": 25, + "equipId": 25, "lv": 28, "attr": "2&37" }, { - "id": 25, + "equipId": 25, "lv": 29, "attr": "2&38" }, { - "id": 25, + "equipId": 25, "lv": 30, "attr": "2&39" }, { - "id": 25, + "equipId": 25, "lv": 31, "attr": "2&40" }, { - "id": 25, + "equipId": 25, "lv": 32, "attr": "2&41" }, { - "id": 25, + "equipId": 25, "lv": 33, "attr": "2&42" }, { - "id": 25, + "equipId": 25, "lv": 34, "attr": "2&43" }, { - "id": 25, + "equipId": 25, "lv": 35, "attr": "2&44" }, { - "id": 25, + "equipId": 25, "lv": 36, "attr": "2&45" }, { - "id": 25, + "equipId": 25, "lv": 37, "attr": "2&46" }, { - "id": 25, + "equipId": 25, "lv": 38, "attr": "2&47" }, { - "id": 25, + "equipId": 25, "lv": 39, "attr": "2&48" }, { - "id": 25, + "equipId": 25, "lv": 40, "attr": "2&49" }, { - "id": 25, + "equipId": 25, "lv": 41, "attr": "2&50" }, { - "id": 25, + "equipId": 25, "lv": 42, "attr": "2&51" }, { - "id": 25, + "equipId": 25, "lv": 43, "attr": "2&52" }, { - "id": 25, + "equipId": 25, "lv": 44, "attr": "2&53" }, { - "id": 25, + "equipId": 25, "lv": 45, "attr": "2&54" }, { - "id": 25, + "equipId": 25, "lv": 46, "attr": "2&55" }, { - "id": 25, + "equipId": 25, "lv": 47, "attr": "2&56" }, { - "id": 25, + "equipId": 25, "lv": 48, "attr": "2&57" }, { - "id": 25, + "equipId": 25, "lv": 49, "attr": "2&58" }, { - "id": 25, + "equipId": 25, "lv": 50, "attr": "2&59" }, { - "id": 25, + "equipId": 25, "lv": 51, "attr": "2&60" }, { - "id": 25, + "equipId": 25, "lv": 52, "attr": "2&61" }, { - "id": 25, + "equipId": 25, "lv": 53, "attr": "2&62" }, { - "id": 25, + "equipId": 25, "lv": 54, "attr": "2&63" }, { - "id": 25, + "equipId": 25, "lv": 55, "attr": "2&64" }, { - "id": 25, + "equipId": 25, "lv": 56, "attr": "2&65" }, { - "id": 25, + "equipId": 25, "lv": 57, "attr": "2&66" }, { - "id": 25, + "equipId": 25, "lv": 58, "attr": "2&67" }, { - "id": 25, + "equipId": 25, "lv": 59, "attr": "2&68" }, { - "id": 25, + "equipId": 25, "lv": 60, "attr": "2&69" }, { - "id": 25, + "equipId": 25, "lv": 61, "attr": "2&70" }, { - "id": 25, + "equipId": 25, "lv": 62, "attr": "2&71" }, { - "id": 25, + "equipId": 25, "lv": 63, "attr": "2&72" }, { - "id": 25, + "equipId": 25, "lv": 64, "attr": "2&73" }, { - "id": 25, + "equipId": 25, "lv": 65, "attr": "2&74" }, { - "id": 25, + "equipId": 25, "lv": 66, "attr": "2&75" }, { - "id": 25, + "equipId": 25, "lv": 67, "attr": "2&76" }, { - "id": 25, + "equipId": 25, "lv": 68, "attr": "2&77" }, { - "id": 25, + "equipId": 25, "lv": 69, "attr": "2&78" }, { - "id": 25, + "equipId": 25, "lv": 70, "attr": "2&79" }, { - "id": 25, + "equipId": 25, "lv": 71, "attr": "2&80" }, { - "id": 25, + "equipId": 25, "lv": 72, "attr": "2&81" }, { - "id": 25, + "equipId": 25, "lv": 73, "attr": "2&82" }, { - "id": 25, + "equipId": 25, "lv": 74, "attr": "2&83" }, { - "id": 25, + "equipId": 25, "lv": 75, "attr": "2&84" }, { - "id": 25, + "equipId": 25, "lv": 76, "attr": "2&85" }, { - "id": 25, + "equipId": 25, "lv": 77, "attr": "2&86" }, { - "id": 25, + "equipId": 25, "lv": 78, "attr": "2&87" }, { - "id": 25, + "equipId": 25, "lv": 79, "attr": "2&88" }, { - "id": 25, + "equipId": 25, "lv": 80, "attr": "2&89" }, { - "id": 25, + "equipId": 25, "lv": 81, "attr": "2&90" }, { - "id": 25, + "equipId": 25, "lv": 82, "attr": "2&91" }, { - "id": 25, + "equipId": 25, "lv": 83, "attr": "2&92" }, { - "id": 25, + "equipId": 25, "lv": 84, "attr": "2&93" }, { - "id": 25, + "equipId": 25, "lv": 85, "attr": "2&94" }, { - "id": 25, + "equipId": 25, "lv": 86, "attr": "2&95" }, { - "id": 25, + "equipId": 25, "lv": 87, "attr": "2&96" }, { - "id": 25, + "equipId": 25, "lv": 88, "attr": "2&97" }, { - "id": 25, + "equipId": 25, "lv": 89, "attr": "2&98" }, { - "id": 25, + "equipId": 25, "lv": 90, "attr": "2&99" }, { - "id": 25, + "equipId": 25, "lv": 91, "attr": "2&100" }, { - "id": 25, + "equipId": 25, "lv": 92, "attr": "2&101" }, { - "id": 25, + "equipId": 25, "lv": 93, "attr": "2&102" }, { - "id": 25, + "equipId": 25, "lv": 94, "attr": "2&103" }, { - "id": 25, + "equipId": 25, "lv": 95, "attr": "2&104" }, { - "id": 25, + "equipId": 25, "lv": 96, "attr": "2&105" }, { - "id": 25, + "equipId": 25, "lv": 97, "attr": "2&106" }, { - "id": 25, + "equipId": 25, "lv": 98, "attr": "2&107" }, { - "id": 25, + "equipId": 25, "lv": 99, "attr": "2&108" }, { - "id": 25, + "equipId": 25, "lv": 100, "attr": "2&109" }, { - "id": 26, + "equipId": 26, + "lv": 0, + "attr": "4&20" + }, + { + "equipId": 26, "lv": 1, "attr": "4&20" }, { - "id": 26, + "equipId": 26, "lv": 2, "attr": "4&21" }, { - "id": 26, + "equipId": 26, "lv": 3, "attr": "4&22" }, { - "id": 26, + "equipId": 26, "lv": 4, "attr": "4&23" }, { - "id": 26, + "equipId": 26, "lv": 5, "attr": "4&24" }, { - "id": 26, + "equipId": 26, "lv": 6, "attr": "4&25" }, { - "id": 26, + "equipId": 26, "lv": 7, "attr": "4&26" }, { - "id": 26, + "equipId": 26, "lv": 8, "attr": "4&27" }, { - "id": 26, + "equipId": 26, "lv": 9, "attr": "4&28" }, { - "id": 26, + "equipId": 26, "lv": 10, "attr": "4&29" }, { - "id": 26, + "equipId": 26, "lv": 11, "attr": "4&30" }, { - "id": 26, + "equipId": 26, "lv": 12, "attr": "4&31" }, { - "id": 26, + "equipId": 26, "lv": 13, "attr": "4&32" }, { - "id": 26, + "equipId": 26, "lv": 14, "attr": "4&33" }, { - "id": 26, + "equipId": 26, "lv": 15, "attr": "4&34" }, { - "id": 26, + "equipId": 26, "lv": 16, "attr": "4&35" }, { - "id": 26, + "equipId": 26, "lv": 17, "attr": "4&36" }, { - "id": 26, + "equipId": 26, "lv": 18, "attr": "4&37" }, { - "id": 26, + "equipId": 26, "lv": 19, "attr": "4&38" }, { - "id": 26, + "equipId": 26, "lv": 20, "attr": "4&39" }, { - "id": 26, + "equipId": 26, "lv": 21, "attr": "4&40" }, { - "id": 26, + "equipId": 26, "lv": 22, "attr": "4&41" }, { - "id": 26, + "equipId": 26, "lv": 23, "attr": "4&42" }, { - "id": 26, + "equipId": 26, "lv": 24, "attr": "4&43" }, { - "id": 26, + "equipId": 26, "lv": 25, "attr": "4&44" }, { - "id": 26, + "equipId": 26, "lv": 26, "attr": "4&45" }, { - "id": 26, + "equipId": 26, "lv": 27, "attr": "4&46" }, { - "id": 26, + "equipId": 26, "lv": 28, "attr": "4&47" }, { - "id": 26, + "equipId": 26, "lv": 29, "attr": "4&48" }, { - "id": 26, + "equipId": 26, "lv": 30, "attr": "4&49" }, { - "id": 26, + "equipId": 26, "lv": 31, "attr": "4&50" }, { - "id": 26, + "equipId": 26, "lv": 32, "attr": "4&51" }, { - "id": 26, + "equipId": 26, "lv": 33, "attr": "4&52" }, { - "id": 26, + "equipId": 26, "lv": 34, "attr": "4&53" }, { - "id": 26, + "equipId": 26, "lv": 35, "attr": "4&54" }, { - "id": 26, + "equipId": 26, "lv": 36, "attr": "4&55" }, { - "id": 26, + "equipId": 26, "lv": 37, "attr": "4&56" }, { - "id": 26, + "equipId": 26, "lv": 38, "attr": "4&57" }, { - "id": 26, + "equipId": 26, "lv": 39, "attr": "4&58" }, { - "id": 26, + "equipId": 26, "lv": 40, "attr": "4&59" }, { - "id": 26, + "equipId": 26, "lv": 41, "attr": "4&60" }, { - "id": 26, + "equipId": 26, "lv": 42, "attr": "4&61" }, { - "id": 26, + "equipId": 26, "lv": 43, "attr": "4&62" }, { - "id": 26, + "equipId": 26, "lv": 44, "attr": "4&63" }, { - "id": 26, + "equipId": 26, "lv": 45, "attr": "4&64" }, { - "id": 26, + "equipId": 26, "lv": 46, "attr": "4&65" }, { - "id": 26, + "equipId": 26, "lv": 47, "attr": "4&66" }, { - "id": 26, + "equipId": 26, "lv": 48, "attr": "4&67" }, { - "id": 26, + "equipId": 26, "lv": 49, "attr": "4&68" }, { - "id": 26, + "equipId": 26, "lv": 50, "attr": "4&69" }, { - "id": 26, + "equipId": 26, "lv": 51, "attr": "4&70" }, { - "id": 26, + "equipId": 26, "lv": 52, "attr": "4&71" }, { - "id": 26, + "equipId": 26, "lv": 53, "attr": "4&72" }, { - "id": 26, + "equipId": 26, "lv": 54, "attr": "4&73" }, { - "id": 26, + "equipId": 26, "lv": 55, "attr": "4&74" }, { - "id": 26, + "equipId": 26, "lv": 56, "attr": "4&75" }, { - "id": 26, + "equipId": 26, "lv": 57, "attr": "4&76" }, { - "id": 26, + "equipId": 26, "lv": 58, "attr": "4&77" }, { - "id": 26, + "equipId": 26, "lv": 59, "attr": "4&78" }, { - "id": 26, + "equipId": 26, "lv": 60, "attr": "4&79" }, { - "id": 26, + "equipId": 26, "lv": 61, "attr": "4&80" }, { - "id": 26, + "equipId": 26, "lv": 62, "attr": "4&81" }, { - "id": 26, + "equipId": 26, "lv": 63, "attr": "4&82" }, { - "id": 26, + "equipId": 26, "lv": 64, "attr": "4&83" }, { - "id": 26, + "equipId": 26, "lv": 65, "attr": "4&84" }, { - "id": 26, + "equipId": 26, "lv": 66, "attr": "4&85" }, { - "id": 26, + "equipId": 26, "lv": 67, "attr": "4&86" }, { - "id": 26, + "equipId": 26, "lv": 68, "attr": "4&87" }, { - "id": 26, + "equipId": 26, "lv": 69, "attr": "4&88" }, { - "id": 26, + "equipId": 26, "lv": 70, "attr": "4&89" }, { - "id": 26, + "equipId": 26, "lv": 71, "attr": "4&90" }, { - "id": 26, + "equipId": 26, "lv": 72, "attr": "4&91" }, { - "id": 26, + "equipId": 26, "lv": 73, "attr": "4&92" }, { - "id": 26, + "equipId": 26, "lv": 74, "attr": "4&93" }, { - "id": 26, + "equipId": 26, "lv": 75, "attr": "4&94" }, { - "id": 26, + "equipId": 26, "lv": 76, "attr": "4&95" }, { - "id": 26, + "equipId": 26, "lv": 77, "attr": "4&96" }, { - "id": 26, + "equipId": 26, "lv": 78, "attr": "4&97" }, { - "id": 26, + "equipId": 26, "lv": 79, "attr": "4&98" }, { - "id": 26, + "equipId": 26, "lv": 80, "attr": "4&99" }, { - "id": 26, + "equipId": 26, "lv": 81, "attr": "4&100" }, { - "id": 26, + "equipId": 26, "lv": 82, "attr": "4&101" }, { - "id": 26, + "equipId": 26, "lv": 83, "attr": "4&102" }, { - "id": 26, + "equipId": 26, "lv": 84, "attr": "4&103" }, { - "id": 26, + "equipId": 26, "lv": 85, "attr": "4&104" }, { - "id": 26, + "equipId": 26, "lv": 86, "attr": "4&105" }, { - "id": 26, + "equipId": 26, "lv": 87, "attr": "4&106" }, { - "id": 26, + "equipId": 26, "lv": 88, "attr": "4&107" }, { - "id": 26, + "equipId": 26, "lv": 89, "attr": "4&108" }, { - "id": 26, + "equipId": 26, "lv": 90, "attr": "4&109" }, { - "id": 26, + "equipId": 26, "lv": 91, "attr": "4&110" }, { - "id": 26, + "equipId": 26, "lv": 92, "attr": "4&111" }, { - "id": 26, + "equipId": 26, "lv": 93, "attr": "4&112" }, { - "id": 26, + "equipId": 26, "lv": 94, "attr": "4&113" }, { - "id": 26, + "equipId": 26, "lv": 95, "attr": "4&114" }, { - "id": 26, + "equipId": 26, "lv": 96, "attr": "4&115" }, { - "id": 26, + "equipId": 26, "lv": 97, "attr": "4&116" }, { - "id": 26, + "equipId": 26, "lv": 98, "attr": "4&117" }, { - "id": 26, + "equipId": 26, "lv": 99, "attr": "4&118" }, { - "id": 26, + "equipId": 26, "lv": 100, "attr": "4&119" }, { - "id": 27, + "equipId": 27, + "lv": 0, + "attr": "5&20" + }, + { + "equipId": 27, "lv": 1, "attr": "5&20" }, { - "id": 27, + "equipId": 27, "lv": 2, "attr": "5&21" }, { - "id": 27, + "equipId": 27, "lv": 3, "attr": "5&22" }, { - "id": 27, + "equipId": 27, "lv": 4, "attr": "5&23" }, { - "id": 27, + "equipId": 27, "lv": 5, "attr": "5&24" }, { - "id": 27, + "equipId": 27, "lv": 6, "attr": "5&25" }, { - "id": 27, + "equipId": 27, "lv": 7, "attr": "5&26" }, { - "id": 27, + "equipId": 27, "lv": 8, "attr": "5&27" }, { - "id": 27, + "equipId": 27, "lv": 9, "attr": "5&28" }, { - "id": 27, + "equipId": 27, "lv": 10, "attr": "5&29" }, { - "id": 27, + "equipId": 27, "lv": 11, "attr": "5&30" }, { - "id": 27, + "equipId": 27, "lv": 12, "attr": "5&31" }, { - "id": 27, + "equipId": 27, "lv": 13, "attr": "5&32" }, { - "id": 27, + "equipId": 27, "lv": 14, "attr": "5&33" }, { - "id": 27, + "equipId": 27, "lv": 15, "attr": "5&34" }, { - "id": 27, + "equipId": 27, "lv": 16, "attr": "5&35" }, { - "id": 27, + "equipId": 27, "lv": 17, "attr": "5&36" }, { - "id": 27, + "equipId": 27, "lv": 18, "attr": "5&37" }, { - "id": 27, + "equipId": 27, "lv": 19, "attr": "5&38" }, { - "id": 27, + "equipId": 27, "lv": 20, "attr": "5&39" }, { - "id": 27, + "equipId": 27, "lv": 21, "attr": "5&40" }, { - "id": 27, + "equipId": 27, "lv": 22, "attr": "5&41" }, { - "id": 27, + "equipId": 27, "lv": 23, "attr": "5&42" }, { - "id": 27, + "equipId": 27, "lv": 24, "attr": "5&43" }, { - "id": 27, + "equipId": 27, "lv": 25, "attr": "5&44" }, { - "id": 27, + "equipId": 27, "lv": 26, "attr": "5&45" }, { - "id": 27, + "equipId": 27, "lv": 27, "attr": "5&46" }, { - "id": 27, + "equipId": 27, "lv": 28, "attr": "5&47" }, { - "id": 27, + "equipId": 27, "lv": 29, "attr": "5&48" }, { - "id": 27, + "equipId": 27, "lv": 30, "attr": "5&49" }, { - "id": 27, + "equipId": 27, "lv": 31, "attr": "5&50" }, { - "id": 27, + "equipId": 27, "lv": 32, "attr": "5&51" }, { - "id": 27, + "equipId": 27, "lv": 33, "attr": "5&52" }, { - "id": 27, + "equipId": 27, "lv": 34, "attr": "5&53" }, { - "id": 27, + "equipId": 27, "lv": 35, "attr": "5&54" }, { - "id": 27, + "equipId": 27, "lv": 36, "attr": "5&55" }, { - "id": 27, + "equipId": 27, "lv": 37, "attr": "5&56" }, { - "id": 27, + "equipId": 27, "lv": 38, "attr": "5&57" }, { - "id": 27, + "equipId": 27, "lv": 39, "attr": "5&58" }, { - "id": 27, + "equipId": 27, "lv": 40, "attr": "5&59" }, { - "id": 27, + "equipId": 27, "lv": 41, "attr": "5&60" }, { - "id": 27, + "equipId": 27, "lv": 42, "attr": "5&61" }, { - "id": 27, + "equipId": 27, "lv": 43, "attr": "5&62" }, { - "id": 27, + "equipId": 27, "lv": 44, "attr": "5&63" }, { - "id": 27, + "equipId": 27, "lv": 45, "attr": "5&64" }, { - "id": 27, + "equipId": 27, "lv": 46, "attr": "5&65" }, { - "id": 27, + "equipId": 27, "lv": 47, "attr": "5&66" }, { - "id": 27, + "equipId": 27, "lv": 48, "attr": "5&67" }, { - "id": 27, + "equipId": 27, "lv": 49, "attr": "5&68" }, { - "id": 27, + "equipId": 27, "lv": 50, "attr": "5&69" }, { - "id": 27, + "equipId": 27, "lv": 51, "attr": "5&70" }, { - "id": 27, + "equipId": 27, "lv": 52, "attr": "5&71" }, { - "id": 27, + "equipId": 27, "lv": 53, "attr": "5&72" }, { - "id": 27, + "equipId": 27, "lv": 54, "attr": "5&73" }, { - "id": 27, + "equipId": 27, "lv": 55, "attr": "5&74" }, { - "id": 27, + "equipId": 27, "lv": 56, "attr": "5&75" }, { - "id": 27, + "equipId": 27, "lv": 57, "attr": "5&76" }, { - "id": 27, + "equipId": 27, "lv": 58, "attr": "5&77" }, { - "id": 27, + "equipId": 27, "lv": 59, "attr": "5&78" }, { - "id": 27, + "equipId": 27, "lv": 60, "attr": "5&79" }, { - "id": 27, + "equipId": 27, "lv": 61, "attr": "5&80" }, { - "id": 27, + "equipId": 27, "lv": 62, "attr": "5&81" }, { - "id": 27, + "equipId": 27, "lv": 63, "attr": "5&82" }, { - "id": 27, + "equipId": 27, "lv": 64, "attr": "5&83" }, { - "id": 27, + "equipId": 27, "lv": 65, "attr": "5&84" }, { - "id": 27, + "equipId": 27, "lv": 66, "attr": "5&85" }, { - "id": 27, + "equipId": 27, "lv": 67, "attr": "5&86" }, { - "id": 27, + "equipId": 27, "lv": 68, "attr": "5&87" }, { - "id": 27, + "equipId": 27, "lv": 69, "attr": "5&88" }, { - "id": 27, + "equipId": 27, "lv": 70, "attr": "5&89" }, { - "id": 27, + "equipId": 27, "lv": 71, "attr": "5&90" }, { - "id": 27, + "equipId": 27, "lv": 72, "attr": "5&91" }, { - "id": 27, + "equipId": 27, "lv": 73, "attr": "5&92" }, { - "id": 27, + "equipId": 27, "lv": 74, "attr": "5&93" }, { - "id": 27, + "equipId": 27, "lv": 75, "attr": "5&94" }, { - "id": 27, + "equipId": 27, "lv": 76, "attr": "5&95" }, { - "id": 27, + "equipId": 27, "lv": 77, "attr": "5&96" }, { - "id": 27, + "equipId": 27, "lv": 78, "attr": "5&97" }, { - "id": 27, + "equipId": 27, "lv": 79, "attr": "5&98" }, { - "id": 27, + "equipId": 27, "lv": 80, "attr": "5&99" }, { - "id": 27, + "equipId": 27, "lv": 81, "attr": "5&100" }, { - "id": 27, + "equipId": 27, "lv": 82, "attr": "5&101" }, { - "id": 27, + "equipId": 27, "lv": 83, "attr": "5&102" }, { - "id": 27, + "equipId": 27, "lv": 84, "attr": "5&103" }, { - "id": 27, + "equipId": 27, "lv": 85, "attr": "5&104" }, { - "id": 27, + "equipId": 27, "lv": 86, "attr": "5&105" }, { - "id": 27, + "equipId": 27, "lv": 87, "attr": "5&106" }, { - "id": 27, + "equipId": 27, "lv": 88, "attr": "5&107" }, { - "id": 27, + "equipId": 27, "lv": 89, "attr": "5&108" }, { - "id": 27, + "equipId": 27, "lv": 90, "attr": "5&109" }, { - "id": 27, + "equipId": 27, "lv": 91, "attr": "5&110" }, { - "id": 27, + "equipId": 27, "lv": 92, "attr": "5&111" }, { - "id": 27, + "equipId": 27, "lv": 93, "attr": "5&112" }, { - "id": 27, + "equipId": 27, "lv": 94, "attr": "5&113" }, { - "id": 27, + "equipId": 27, "lv": 95, "attr": "5&114" }, { - "id": 27, + "equipId": 27, "lv": 96, "attr": "5&115" }, { - "id": 27, + "equipId": 27, "lv": 97, "attr": "5&116" }, { - "id": 27, + "equipId": 27, "lv": 98, "attr": "5&117" }, { - "id": 27, + "equipId": 27, "lv": 99, "attr": "5&118" }, { - "id": 27, + "equipId": 27, "lv": 100, "attr": "5&119" }, { - "id": 28, + "equipId": 28, + "lv": 0, + "attr": "1&50" + }, + { + "equipId": 28, "lv": 1, "attr": "1&50" }, { - "id": 28, + "equipId": 28, "lv": 2, "attr": "1&51" }, { - "id": 28, + "equipId": 28, "lv": 3, "attr": "1&52" }, { - "id": 28, + "equipId": 28, "lv": 4, "attr": "1&53" }, { - "id": 28, + "equipId": 28, "lv": 5, "attr": "1&54" }, { - "id": 28, + "equipId": 28, "lv": 6, "attr": "1&55" }, { - "id": 28, + "equipId": 28, "lv": 7, "attr": "1&56" }, { - "id": 28, + "equipId": 28, "lv": 8, "attr": "1&57" }, { - "id": 28, + "equipId": 28, "lv": 9, "attr": "1&58" }, { - "id": 28, + "equipId": 28, "lv": 10, "attr": "1&59" }, { - "id": 28, + "equipId": 28, "lv": 11, "attr": "1&60" }, { - "id": 28, + "equipId": 28, "lv": 12, "attr": "1&61" }, { - "id": 28, + "equipId": 28, "lv": 13, "attr": "1&62" }, { - "id": 28, + "equipId": 28, "lv": 14, "attr": "1&63" }, { - "id": 28, + "equipId": 28, "lv": 15, "attr": "1&64" }, { - "id": 28, + "equipId": 28, "lv": 16, "attr": "1&65" }, { - "id": 28, + "equipId": 28, "lv": 17, "attr": "1&66" }, { - "id": 28, + "equipId": 28, "lv": 18, "attr": "1&67" }, { - "id": 28, + "equipId": 28, "lv": 19, "attr": "1&68" }, { - "id": 28, + "equipId": 28, "lv": 20, "attr": "1&69" }, { - "id": 28, + "equipId": 28, "lv": 21, "attr": "1&70" }, { - "id": 28, + "equipId": 28, "lv": 22, "attr": "1&71" }, { - "id": 28, + "equipId": 28, "lv": 23, "attr": "1&72" }, { - "id": 28, + "equipId": 28, "lv": 24, "attr": "1&73" }, { - "id": 28, + "equipId": 28, "lv": 25, "attr": "1&74" }, { - "id": 28, + "equipId": 28, "lv": 26, "attr": "1&75" }, { - "id": 28, + "equipId": 28, "lv": 27, "attr": "1&76" }, { - "id": 28, + "equipId": 28, "lv": 28, "attr": "1&77" }, { - "id": 28, + "equipId": 28, "lv": 29, "attr": "1&78" }, { - "id": 28, + "equipId": 28, "lv": 30, "attr": "1&79" }, { - "id": 28, + "equipId": 28, "lv": 31, "attr": "1&80" }, { - "id": 28, + "equipId": 28, "lv": 32, "attr": "1&81" }, { - "id": 28, + "equipId": 28, "lv": 33, "attr": "1&82" }, { - "id": 28, + "equipId": 28, "lv": 34, "attr": "1&83" }, { - "id": 28, + "equipId": 28, "lv": 35, "attr": "1&84" }, { - "id": 28, + "equipId": 28, "lv": 36, "attr": "1&85" }, { - "id": 28, + "equipId": 28, "lv": 37, "attr": "1&86" }, { - "id": 28, + "equipId": 28, "lv": 38, "attr": "1&87" }, { - "id": 28, + "equipId": 28, "lv": 39, "attr": "1&88" }, { - "id": 28, + "equipId": 28, "lv": 40, "attr": "1&89" }, { - "id": 28, + "equipId": 28, "lv": 41, "attr": "1&90" }, { - "id": 28, + "equipId": 28, "lv": 42, "attr": "1&91" }, { - "id": 28, + "equipId": 28, "lv": 43, "attr": "1&92" }, { - "id": 28, + "equipId": 28, "lv": 44, "attr": "1&93" }, { - "id": 28, + "equipId": 28, "lv": 45, "attr": "1&94" }, { - "id": 28, + "equipId": 28, "lv": 46, "attr": "1&95" }, { - "id": 28, + "equipId": 28, "lv": 47, "attr": "1&96" }, { - "id": 28, + "equipId": 28, "lv": 48, "attr": "1&97" }, { - "id": 28, + "equipId": 28, "lv": 49, "attr": "1&98" }, { - "id": 28, + "equipId": 28, "lv": 50, "attr": "1&99" }, { - "id": 28, + "equipId": 28, "lv": 51, "attr": "1&100" }, { - "id": 28, + "equipId": 28, "lv": 52, "attr": "1&101" }, { - "id": 28, + "equipId": 28, "lv": 53, "attr": "1&102" }, { - "id": 28, + "equipId": 28, "lv": 54, "attr": "1&103" }, { - "id": 28, + "equipId": 28, "lv": 55, "attr": "1&104" }, { - "id": 28, + "equipId": 28, "lv": 56, "attr": "1&105" }, { - "id": 28, + "equipId": 28, "lv": 57, "attr": "1&106" }, { - "id": 28, + "equipId": 28, "lv": 58, "attr": "1&107" }, { - "id": 28, + "equipId": 28, "lv": 59, "attr": "1&108" }, { - "id": 28, + "equipId": 28, "lv": 60, "attr": "1&109" }, { - "id": 28, + "equipId": 28, "lv": 61, "attr": "1&110" }, { - "id": 28, + "equipId": 28, "lv": 62, "attr": "1&111" }, { - "id": 28, + "equipId": 28, "lv": 63, "attr": "1&112" }, { - "id": 28, + "equipId": 28, "lv": 64, "attr": "1&113" }, { - "id": 28, + "equipId": 28, "lv": 65, "attr": "1&114" }, { - "id": 28, + "equipId": 28, "lv": 66, "attr": "1&115" }, { - "id": 28, + "equipId": 28, "lv": 67, "attr": "1&116" }, { - "id": 28, + "equipId": 28, "lv": 68, "attr": "1&117" }, { - "id": 28, + "equipId": 28, "lv": 69, "attr": "1&118" }, { - "id": 28, + "equipId": 28, "lv": 70, "attr": "1&119" }, { - "id": 28, + "equipId": 28, "lv": 71, "attr": "1&120" }, { - "id": 28, + "equipId": 28, "lv": 72, "attr": "1&121" }, { - "id": 28, + "equipId": 28, "lv": 73, "attr": "1&122" }, { - "id": 28, + "equipId": 28, "lv": 74, "attr": "1&123" }, { - "id": 28, + "equipId": 28, "lv": 75, "attr": "1&124" }, { - "id": 28, + "equipId": 28, "lv": 76, "attr": "1&125" }, { - "id": 28, + "equipId": 28, "lv": 77, "attr": "1&126" }, { - "id": 28, + "equipId": 28, "lv": 78, "attr": "1&127" }, { - "id": 28, + "equipId": 28, "lv": 79, "attr": "1&128" }, { - "id": 28, + "equipId": 28, "lv": 80, "attr": "1&129" }, { - "id": 28, + "equipId": 28, "lv": 81, "attr": "1&130" }, { - "id": 28, + "equipId": 28, "lv": 82, "attr": "1&131" }, { - "id": 28, + "equipId": 28, "lv": 83, "attr": "1&132" }, { - "id": 28, + "equipId": 28, "lv": 84, "attr": "1&133" }, { - "id": 28, + "equipId": 28, "lv": 85, "attr": "1&134" }, { - "id": 28, + "equipId": 28, "lv": 86, "attr": "1&135" }, { - "id": 28, + "equipId": 28, "lv": 87, "attr": "1&136" }, { - "id": 28, + "equipId": 28, "lv": 88, "attr": "1&137" }, { - "id": 28, + "equipId": 28, "lv": 89, "attr": "1&138" }, { - "id": 28, + "equipId": 28, "lv": 90, "attr": "1&139" }, { - "id": 28, + "equipId": 28, "lv": 91, "attr": "1&140" }, { - "id": 28, + "equipId": 28, "lv": 92, "attr": "1&141" }, { - "id": 28, + "equipId": 28, "lv": 93, "attr": "1&142" }, { - "id": 28, + "equipId": 28, "lv": 94, "attr": "1&143" }, { - "id": 28, + "equipId": 28, "lv": 95, "attr": "1&144" }, { - "id": 28, + "equipId": 28, "lv": 96, "attr": "1&145" }, { - "id": 28, + "equipId": 28, "lv": 97, "attr": "1&146" }, { - "id": 28, + "equipId": 28, "lv": 98, "attr": "1&147" }, { - "id": 28, + "equipId": 28, "lv": 99, "attr": "1&148" }, { - "id": 28, + "equipId": 28, "lv": 100, "attr": "1&149" } diff --git a/shared/resource/jsons/dic_zyz_randomEffectPool.json b/shared/resource/jsons/dic_zyz_randomEffectPool.json index a984d7e43..f25f54c94 100644 --- a/shared/resource/jsons/dic_zyz_randomEffectPool.json +++ b/shared/resource/jsons/dic_zyz_randomEffectPool.json @@ -1189,20 +1189,6 @@ "info": "法防", "comment": "法防提高" }, - { - "id": 20011, - "type": 1, - "group": 10011, - "level": 10, - "gainValue": "1&0", - "index": 2, - "Min": 461, - "Max": 1150, - "gap": 1, - "count": "461&496&30|497&1065&35|1066&1150&35", - "info": "生命", - "comment": "生命值提高" - }, { "id": 20012, "type": 1, diff --git a/shared/resource/jsons/dic_zyz_se.json b/shared/resource/jsons/dic_zyz_se.json index 4ed55f5d3..71cb94e4d 100644 --- a/shared/resource/jsons/dic_zyz_se.json +++ b/shared/resource/jsons/dic_zyz_se.json @@ -39278,5 +39278,20 @@ "rangeSeid": "&", "seidNameImage": "&", "passivespineName": "&" + }, + + { + "id": 20011, + "type": 2, + "group": 10011, + "level": 10, + "gainValue": "1&1000", + "index": 2, + "Min": 461, + "Max": 1150, + "gap": 1, + "count": "461&496&30|497&1065&35|1066&1150&35", + "info": "生命", + "comment": "生命值提高" } ] \ No newline at end of file From 170a1b96bcf030cf8ca7158f58042693629dfa7f Mon Sep 17 00:00:00 2001 From: luying Date: Wed, 30 Mar 2022 19:20:40 +0800 Subject: [PATCH 10/12] =?UTF-8?q?=E6=88=98=E5=8A=9B=EF=BC=9A=E4=BF=AE?= =?UTF-8?q?=E6=94=B9=E5=A5=97=E8=A3=85=E8=AE=A1=E7=AE=97=E6=96=B9=E5=BC=8F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- game-server/app/services/role/calCe.ts | 14 +++++--------- gm-server/app/service/users.ts | 4 ++-- shared/pubUtils/dictionary/DicEquipSuit.ts | 10 +++++----- shared/resource/jsons/dic_zyz_equipSuit.json | 14 +++++++------- .../resource/jsons/dic_zyz_randomEffectPool.json | 14 ++++++++++++++ shared/resource/jsons/dic_zyz_se.json | 15 --------------- 6 files changed, 33 insertions(+), 38 deletions(-) diff --git a/game-server/app/services/role/calCe.ts b/game-server/app/services/role/calCe.ts index e1f54e5bd..b6e1baac7 100644 --- a/game-server/app/services/role/calCe.ts +++ b/game-server/app/services/role/calCe.ts @@ -307,15 +307,11 @@ export class CalCe { } let minStar = Math.min(...suitStars); - let seids: number[] = []; - for(let { star, seid } of dicEquipSuit.effect) { - if(minStar >= star) seids.push(seid); - } - - let { ratioUp } = this.addSeidEffect(seids); - for(let [attrId, val] of ratioUp) { - let heroAttr = this.data.getHeroAttrByHidAndId(hid, attrId); - heroAttr.equipSuit = val; + for(let { star, id, val } of dicEquipSuit.effect) { + if(minStar >= star) { + let heroAttr = this.data.getHeroAttrByHidAndId(hid, id); + heroAttr.equipSuit = val; + } } } diff --git a/gm-server/app/service/users.ts b/gm-server/app/service/users.ts index 502de1a5d..a893fe13b 100644 --- a/gm-server/app/service/users.ts +++ b/gm-server/app/service/users.ts @@ -305,8 +305,8 @@ export default class GMUsers extends Service { } let list = heroes.map(cur => { let roleCe = roleMap.get(cur.roleId); - let attr = roleCe.attributes.filter(ccur => ccur.hid == cur.hid); - return {...cur, calculatedAttr: attr, env: ctx.app.config.realEnv} + let obj = roleCe.attributes.find(ccur => ccur.hid == cur.hid); + return {...cur, calculatedAttr: obj.attrs, env: ctx.app.config.realEnv} }) return ctx.service.utils.resResult(STATUS.SUCCESS, { list, total }) diff --git a/shared/pubUtils/dictionary/DicEquipSuit.ts b/shared/pubUtils/dictionary/DicEquipSuit.ts index b80b299b4..65791c0d2 100644 --- a/shared/pubUtils/dictionary/DicEquipSuit.ts +++ b/shared/pubUtils/dictionary/DicEquipSuit.ts @@ -10,7 +10,7 @@ export interface DicEquipSuit { // 套装内含的装备编号 readonly equips: number[]; // 按星级可解锁的属性 - readonly effect: { star: number, seid: number }[]; + readonly effect: { star: number, id: number, val: number }[]; } export const dicEquipSuit = new Map(); @@ -30,14 +30,14 @@ export function loadEquipSuit() { } function parseEffect(str: string) { - let result = new Array<{star: number, seid: number}>(); + let result = new Array<{star: number, id: number, val: number}>(); if(!str) return result; let decodeArr = decodeArrayListStr(str); - for(let [star, seid] of decodeArr) { - if(isNaN(parseInt(star)) || isNaN(parseInt(seid))) { + for(let [star, id, val] of decodeArr) { + if(isNaN(parseInt(star)) || isNaN(parseInt(id)) || isNaN(parseInt(val))) { throw new Error('data table format wrong'); } - result.push({star: parseInt(star), seid: parseInt(seid)}); + result.push({star: parseInt(star), id: parseInt(id), val: parseInt(val)}); } return result } \ No newline at end of file diff --git a/shared/resource/jsons/dic_zyz_equipSuit.json b/shared/resource/jsons/dic_zyz_equipSuit.json index 6c22313d6..802c1f32f 100644 --- a/shared/resource/jsons/dic_zyz_equipSuit.json +++ b/shared/resource/jsons/dic_zyz_equipSuit.json @@ -3,42 +3,42 @@ "id": 1, "jobClass": 1, "equips": "1&2&3&4", - "effect": "4&10011|8&10013|12&80003" + "effect": "4&1&1|8&2&20|12&3&1" }, { "id": 2, "jobClass": 2, "equips": "5&6&7&8", - "effect": "4&20011|8&10012|12&80023" + "effect": "4&1&1|8&2&20|12&3&1" }, { "id": 3, "jobClass": 3, "equips": "9&10&11&12", - "effect": "4&60032|8&60034|12&80002" + "effect": "4&1&1|8&2&20|12&3&1" }, { "id": 4, "jobClass": 4, "equips": "13&14&15&16", - "effect": "4&10011|8&10013|12&80003" + "effect": "4&1&1|8&2&20|12&3&1" }, { "id": 5, "jobClass": 5, "equips": "17&18&19&20", - "effect": "4&20011|8&10012|12&80023" + "effect": "4&1&1|8&2&20|12&3&1" }, { "id": 6, "jobClass": 6, "equips": "21&22&23&24", - "effect": "4&60032|8&60034|12&80002" + "effect": "4&1&1|8&2&20|12&3&1" }, { "id": 7, "jobClass": 7, "equips": "25&26&27&28", - "effect": "4&60032|8&60034|12&80002" + "effect": "4&1&1|8&2&20|12&3&1" } ] \ No newline at end of file diff --git a/shared/resource/jsons/dic_zyz_randomEffectPool.json b/shared/resource/jsons/dic_zyz_randomEffectPool.json index f25f54c94..a984d7e43 100644 --- a/shared/resource/jsons/dic_zyz_randomEffectPool.json +++ b/shared/resource/jsons/dic_zyz_randomEffectPool.json @@ -1189,6 +1189,20 @@ "info": "法防", "comment": "法防提高" }, + { + "id": 20011, + "type": 1, + "group": 10011, + "level": 10, + "gainValue": "1&0", + "index": 2, + "Min": 461, + "Max": 1150, + "gap": 1, + "count": "461&496&30|497&1065&35|1066&1150&35", + "info": "生命", + "comment": "生命值提高" + }, { "id": 20012, "type": 1, diff --git a/shared/resource/jsons/dic_zyz_se.json b/shared/resource/jsons/dic_zyz_se.json index 71cb94e4d..4ed55f5d3 100644 --- a/shared/resource/jsons/dic_zyz_se.json +++ b/shared/resource/jsons/dic_zyz_se.json @@ -39278,20 +39278,5 @@ "rangeSeid": "&", "seidNameImage": "&", "passivespineName": "&" - }, - - { - "id": 20011, - "type": 2, - "group": 10011, - "level": 10, - "gainValue": "1&1000", - "index": 2, - "Min": 461, - "Max": 1150, - "gap": 1, - "count": "461&496&30|497&1065&35|1066&1150&35", - "info": "生命", - "comment": "生命值提高" } ] \ No newline at end of file From 22b42fd5d67822b1a677999dd5c933ce77b589af Mon Sep 17 00:00:00 2001 From: yzh Date: Wed, 30 Mar 2022 19:14:44 +0800 Subject: [PATCH 11/12] =?UTF-8?q?=E5=A5=97=E8=A3=85=E8=A1=A8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- shared/resource/jsons/dic_zyz_equipSuit.json | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/shared/resource/jsons/dic_zyz_equipSuit.json b/shared/resource/jsons/dic_zyz_equipSuit.json index 802c1f32f..59e873737 100644 --- a/shared/resource/jsons/dic_zyz_equipSuit.json +++ b/shared/resource/jsons/dic_zyz_equipSuit.json @@ -3,42 +3,42 @@ "id": 1, "jobClass": 1, "equips": "1&2&3&4", - "effect": "4&1&1|8&2&20|12&3&1" + "effect": "3&1&10|6&2&10|9&4&10|12&5&10" }, { "id": 2, "jobClass": 2, "equips": "5&6&7&8", - "effect": "4&1&1|8&2&20|12&3&1" + "effect": "3&1&10|6&2&10|9&4&10|12&5&10" }, { "id": 3, "jobClass": 3, "equips": "9&10&11&12", - "effect": "4&1&1|8&2&20|12&3&1" + "effect": "3&1&10|6&2&10|9&4&10|12&5&10" }, { "id": 4, "jobClass": 4, "equips": "13&14&15&16", - "effect": "4&1&1|8&2&20|12&3&1" + "effect": "3&1&10|6&2&10|9&4&10|12&5&10" }, { "id": 5, "jobClass": 5, "equips": "17&18&19&20", - "effect": "4&1&1|8&2&20|12&3&1" + "effect": "3&1&10|6&2&10|9&4&10|12&5&10" }, { "id": 6, "jobClass": 6, "equips": "21&22&23&24", - "effect": "4&1&1|8&2&20|12&3&1" + "effect": "3&1&10|6&2&10|9&4&10|12&5&10" }, { "id": 7, "jobClass": 7, "equips": "25&26&27&28", - "effect": "4&1&1|8&2&20|12&3&1" + "effect": "3&1&10|6&2&10|9&4&10|12&5&10" } ] \ No newline at end of file From b4ac87d8f53b965763919ba525f48a751b46163c Mon Sep 17 00:00:00 2001 From: luying Date: Wed, 30 Mar 2022 21:19:08 +0800 Subject: [PATCH 12/12] =?UTF-8?q?=E6=88=98=E5=8A=9B=EF=BC=9A=E4=BF=AE?= =?UTF-8?q?=E5=A4=8Dbug?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../app/servers/role/handler/equipHandler.ts | 4 ++-- game-server/app/services/role/calCe.ts | 15 ++++++++------ game-server/app/services/task/taskService.ts | 6 +++--- .../dictionary/DicRandomEffectPool.ts | 2 +- shared/pubUtils/dictionary/DicTeraph.ts | 20 +++++++++++++++---- 5 files changed, 31 insertions(+), 16 deletions(-) diff --git a/game-server/app/servers/role/handler/equipHandler.ts b/game-server/app/servers/role/handler/equipHandler.ts index c7e1a1323..bd6e3d58a 100644 --- a/game-server/app/servers/role/handler/equipHandler.ts +++ b/game-server/app/servers/role/handler/equipHandler.ts @@ -356,7 +356,7 @@ export class EquipHandler { // 目标镶嵌上 let curJewel = await JewelModel.putOnOrOff(seqId, hid, ePlaceId); let { newEplace, updatedEplace } = updateEplace(oldEplace, ePlaceId, { jewel: seqId }); - await calculateCeWithHero(HERO_SYSTEM_TYPE.EQUIP_JEWEL, roleId, serverId, sid, hid, { ePlace: newEplace }, { ePlaceIds: [ePlaceId], jewels: [curJewel] }); + await calculateCeWithHero(HERO_SYSTEM_TYPE.EQUIP_JEWEL, roleId, serverId, sid, hid, { ePlace: newEplace }, { ePlaceId, jewel: curJewel }); await checkTaskInPutJewel(serverId, roleId, sid, oldEplace, newEplace, ePlaceId, originJewel, curJewel); let curHero = { @@ -384,7 +384,7 @@ export class EquipHandler { let curJewel = await JewelModel.putOnOrOff(curEquip.jewel, 0, 0); let { newEplace, updatedEplace } = updateEplace(oldEplace, ePlaceId, { jewel: 0 }); - await calculateCeWithHero(HERO_SYSTEM_TYPE.EQUIP_JEWEL, roleId, serverId, sid, hid, { ePlace: newEplace }, { ePlaceIds: [ePlaceId], jewels: [] }); + await calculateCeWithHero(HERO_SYSTEM_TYPE.EQUIP_JEWEL, roleId, serverId, sid, hid, { ePlace: newEplace }, { ePlaceId, jewel: null }); await checkTaskInPutJewel(serverId, roleId, sid, oldEplace, newEplace, ePlaceId, null, curJewel); let curHero = { diff --git a/game-server/app/services/role/calCe.ts b/game-server/app/services/role/calCe.ts index b6e1baac7..e21d1501e 100644 --- a/game-server/app/services/role/calCe.ts +++ b/game-server/app/services/role/calCe.ts @@ -246,7 +246,7 @@ export class CalCe { for(let { lv, seid } of dicHeroTalent.level) { if(level >= lv) { if(!seids.has(id)) seids.set(id, []); - seids.get(id).push(seid); + seids.get(id).push(seid, 0); } } } @@ -382,13 +382,15 @@ export class CalCe { // 神像相关 public setTeraph(teraphs: Teraph[]) { + this.data.clearRoleAttr('teraph'); let teraphOfAttrId = new Map(); for(let teraph of teraphs) { - for(let [attrId, value] of teraph.attr) { // 主属性 - addToMap(teraphOfAttrId, attrId, value); - } let dicTeraph = getTeraph(teraph.id, teraph.grade); + for(let [attrId, value] of teraph.attr) { // 主属性 + let basic = dicTeraph.basicAttrValue.get(attrId)||0; + addToMap(teraphOfAttrId, attrId, value + basic); + } for(let [attrId, value] of dicTeraph.assiAttrValue) { // 次属性 addToMap(teraphOfAttrId, attrId, value); } @@ -445,7 +447,8 @@ export class CalCe { } // console.log('effectList', JSON.stringify(effectList)); - for (let { type, gainValueArr: [ability, value] } of effectList) { + for (let { type, id, gainValueArr: [ability, value] } of effectList) { + // console.log('##### addToMap type', type, 'id', id, 'ability', ability, 'value', value) if (type == SEID_TYPE.FIX) { // 加值 addToMap(fixUp, ability, value); } else if (type == SEID_TYPE.MAIN_RATIO||type == SEID_TYPE.MAIN_RATIO_2) { // 主属性加百分比 @@ -454,7 +457,7 @@ export class CalCe { } } else if (type == SEID_TYPE.SUB_RATIO||type == SEID_TYPE.SUB_RATIO_2) { // 次级属性加百分比 if(!ABI_TYPE_MAIN.includes(ability)) { - addToMap(ratioUp, ability, value * 100); + addToMap(ratioUp, ability, value); } } diff --git a/game-server/app/services/task/taskService.ts b/game-server/app/services/task/taskService.ts index f620fcf06..040e395fd 100644 --- a/game-server/app/services/task/taskService.ts +++ b/game-server/app/services/task/taskService.ts @@ -189,9 +189,9 @@ export async function checkTaskInEquipLvUp(serverId: number, roleId: string, sid export async function checkTaskInPutJewel(serverId: number, roleId: string, sid: string, oldEplace: EPlace[], newEplace: EPlace[], ePlaceId: number, originJewel: JewelType, curJewel: JewelType) { let { oldEquip, newEquip } = getEquipById(oldEplace, newEplace, ePlaceId); let task = new CheckTask(serverId, roleId); - task.setParam(TASK_TYPE.EQUIP_PUT_JEWEL, { oldEquip, newEplace, jewels: [originJewel, curJewel ] }); + task.setParam(TASK_TYPE.EQUIP_PUT_JEWEL, { oldEquip, newEquip, jewels: [originJewel, curJewel ] }); task.setParam(TASK_TYPE.EQUIP_PUT_JEWEL_CNT, { oldEquip, newEquip }); - task.setParam(TASK_TYPE.EQUIP_JEWEL_RANDSE_CNT, { oldEquip, newEplace, jewels: [originJewel, curJewel ] }); + task.setParam(TASK_TYPE.EQUIP_JEWEL_RANDSE_CNT, { oldEquip, newEquip, jewels: [originJewel, curJewel ] }); await task.saveAndPush(sid); } @@ -202,7 +202,7 @@ export async function checkTaskInPutStone(serverId: number, roleId: string, sid: task.setParam(TASK_TYPE.EQUIP_PUT_STONE_CNT, { oldEquip, newEquip }); task.setParam(TASK_TYPE.EQUIP_STONE_CNT, { oldEquip, newEquip }); task.setParam(TASK_TYPE.EQUIP_STONE_CNT_LV, { oldEquip, newEquip }); - task.setParam(TASK_TYPE.EQUIP_JEWEL_RANDSE_CNT, { oldEquip, newEplace, jewels: [jewel ] }); + task.setParam(TASK_TYPE.EQUIP_JEWEL_RANDSE_CNT, { oldEquip, newEquip, jewels: [jewel ] }); await task.saveAndPush(sid); } diff --git a/shared/pubUtils/dictionary/DicRandomEffectPool.ts b/shared/pubUtils/dictionary/DicRandomEffectPool.ts index be62eed74..acba2f841 100644 --- a/shared/pubUtils/dictionary/DicRandomEffectPool.ts +++ b/shared/pubUtils/dictionary/DicRandomEffectPool.ts @@ -36,7 +36,7 @@ export function loadRandomEffectPool() { arr.forEach(o => { o.rate = parseRate(o.count); - o.gainValueArr = parseNumberList(o.gainvalue); + o.gainValueArr = parseNumberList(o.gainValue); dicRandomEffectPool.set(o.id, o); dicRandomEffectPoolByGroupAndLv.set(`${o.group}_${o.level}`, o.id); }); diff --git a/shared/pubUtils/dictionary/DicTeraph.ts b/shared/pubUtils/dictionary/DicTeraph.ts index d6d43aaf2..86a19a919 100644 --- a/shared/pubUtils/dictionary/DicTeraph.ts +++ b/shared/pubUtils/dictionary/DicTeraph.ts @@ -23,6 +23,7 @@ export interface DicTeraph { readonly upMaterial:Array; readonly assiAttrValue:Map; // 次级属性 + readonly basicAttrValue:Map; // 主属性 readonly upGradeMaterial:Array; } export const dicTeraph = new Map(); @@ -42,6 +43,7 @@ export function loadTeraph() { criEffect: true, upMaterial: true, assiAttrValue: true, + basicAttrValue: true, upGradeMaterial: true, } @@ -51,6 +53,7 @@ export function loadTeraph() { o.upMaterial = parseGoodStr(o.upMaterial); o.mainAttrMax = parseMainAttrMax(o); o.mainAttrUp = parseMainAttrUp(o); + o.basicAttrValue = parseBasicAttr(o); dicTeraph.set(o.index + '_' + o.grade, _.pick(o, Object.keys(DicTeraphKeys))); }); @@ -72,10 +75,10 @@ function parseAttr(str: string) { function parseMainAttrMax(elem) { let result = new Map(); - result.set(ABI_TYPE.ABI_HP, elem.hpMax); - result.set(ABI_TYPE.ABI_ATK, elem.atkMax); - result.set(ABI_TYPE.ABI_DEF, elem.defMax); - result.set(ABI_TYPE.ABI_MDEF, elem.mdefMax); + result.set(ABI_TYPE.ABI_HP, elem.hpMax - elem.hpBasis); + result.set(ABI_TYPE.ABI_ATK, elem.atkMax - elem.atkBasis); + result.set(ABI_TYPE.ABI_DEF, elem.defMax - elem.defBasis); + result.set(ABI_TYPE.ABI_MDEF, elem.mdefMax - elem.mdefBasis); return result } @@ -86,4 +89,13 @@ function parseMainAttrUp(elem) { result.set(ABI_TYPE.ABI_DEF, elem.defUp); result.set(ABI_TYPE.ABI_MDEF, elem.mdefUp); return result +} + +function parseBasicAttr(elem) { + let result = new Map(); + result.set(ABI_TYPE.ABI_HP, elem.hpBasis); + result.set(ABI_TYPE.ABI_ATK, elem.atkBasis); + result.set(ABI_TYPE.ABI_DEF, elem.defBasis); + result.set(ABI_TYPE.ABI_MDEF, elem.mdefBasis); + return result } \ No newline at end of file