✨ feat(共鸣系统): 新增
This commit is contained in:
147
game-server/app/servers/role/handler/resonanceHandler.ts
Normal file
147
game-server/app/servers/role/handler/resonanceHandler.ts
Normal file
@@ -0,0 +1,147 @@
|
||||
import { Application, BackendSession, HandlerService, } from 'pinus';
|
||||
import { getJewelDataMap, getResonanceDataMap, getStartLimt, refreshResonanceData } from '../../../services/role/resonanceService';
|
||||
import { resResult } from '../../../pubUtils/util'
|
||||
import { HERO_SYSTEM_TYPE, ITEM_CHANGE_REASON, STATUS } from '../../../consts';
|
||||
import { ResonanceModel } from '../../../db/Resonance';
|
||||
import { gameData } from '../../../pubUtils/data';
|
||||
import { RoleModel } from '../../../db/Role';
|
||||
import { handleCost } from '../../../services/role/rewardService';
|
||||
import { HeroModel } from '../../../db/Hero';
|
||||
import { ArtifactModel, ArtifactModelType } from '../../../db/Artifact';
|
||||
import { calculateCeWithHero } from '../../../services/playerCeService';
|
||||
import { HeroParam } from '../../../domain/roleField/hero';
|
||||
import { pick } from 'underscore';
|
||||
import { ResonanceHistoryModel } from '../../../db/ResonanceHistory';
|
||||
import { RESONANCE } from '../../../pubUtils/dicParam';
|
||||
;
|
||||
|
||||
export default function (app: Application) {
|
||||
new HandlerService(app, {});
|
||||
return new HeroHandler(app);
|
||||
}
|
||||
|
||||
export class HeroHandler {
|
||||
constructor(private app: Application) {
|
||||
}
|
||||
|
||||
async getData(msg: {}, session: BackendSession) {
|
||||
const roleId: string = session.get('roleId');
|
||||
const sid: string = session.get('sid');
|
||||
const serverId: number = session.get('serverId');
|
||||
|
||||
if (!await getStartLimt(roleId)) return resResult(STATUS.RESONANCE_NO_START);
|
||||
const resonances = await refreshResonanceData(roleId, serverId, sid);
|
||||
|
||||
return resResult(STATUS.SUCCESS, { resonanceDatas: resonances })
|
||||
}
|
||||
|
||||
async unlockPosition(msg: { position: number }, session: BackendSession) {
|
||||
const { position } = msg;
|
||||
const roleId: string = session.get('roleId');
|
||||
const sid: string = session.get('sid');
|
||||
|
||||
if (!await getStartLimt(roleId)) return resResult(STATUS.RESONANCE_NO_START);
|
||||
|
||||
let dbResonance = await ResonanceModel.findByPosition(roleId, position);
|
||||
if (dbResonance) return resResult(STATUS.RESONANCE_POSITION_LOCK);
|
||||
|
||||
const dicResonance = gameData.resonance.get(position);
|
||||
if (!dicResonance) return resResult(STATUS.RESONANCE_POSITION_NOT_FOUND);
|
||||
|
||||
const role = await RoleModel.findByRoleId(roleId);
|
||||
if (!role || !role.mainWarId || role.mainWarId < (dicResonance?.openLimit || 0)) return resResult(STATUS.RESONANCE_POSITION_LV_NOT_ENOUGH);
|
||||
|
||||
let costResult = await handleCost(roleId, sid, dicResonance.openConsume, ITEM_CHANGE_REASON.RESONANCE_LOCK_POSITION);
|
||||
if (!costResult) return resResult(STATUS.ROLE_MATERIAL_NOT_ENOUGH);
|
||||
|
||||
let result = await ResonanceModel.updateByPosition(roleId, position, {});
|
||||
|
||||
if (!result || !result.position) return resResult(STATUS.RESONANCE_POSITION_LOCK_FAIL);
|
||||
|
||||
return resResult(STATUS.SUCCESS, { position: result.position });
|
||||
}
|
||||
|
||||
async heroPutPosition(msg: { position: number, hid: number }, session: BackendSession) {
|
||||
const { position, hid } = msg;
|
||||
const roleId: string = session.get('roleId');
|
||||
const sid: string = session.get('sid');
|
||||
const serverId: number = session.get('serverId');
|
||||
|
||||
if (!await getStartLimt(roleId)) return resResult(STATUS.RESONANCE_NO_START);
|
||||
let { dbResonanceMap } = await getResonanceDataMap(roleId);
|
||||
let heroCount = await HeroModel.getHidCountByRoleId(roleId);
|
||||
if (dbResonanceMap.size + RESONANCE.HOSTER >= heroCount) return resResult(STATUS.RESONANCE_PUT_NOT_POSITION)
|
||||
|
||||
let dbResonance = await ResonanceModel.findByPosition(roleId, position);
|
||||
if (!dbResonance) return resResult(STATUS.RESONANCE_POSITION_UNLOCK);
|
||||
if (dbResonance.hid) return resResult(STATUS.RESONANCE_POSITION_EXIST_HID);
|
||||
|
||||
let dbHeroes = await HeroModel.findByHidAndRole(hid, roleId);
|
||||
if (!dbHeroes) return resResult(STATUS.ROLE_HERO_NOT_EXISTS);
|
||||
|
||||
let { lv = 1, exp = 0, jobStage = 0, skinId, skins = [], connections = [], ePlace = [], seqId, ce } = dbHeroes;
|
||||
|
||||
//检测养成维度
|
||||
if (lv > 1) return resResult(STATUS.RESONANCE_PUT_POSITION_EXIST_LV);
|
||||
if (jobStage) return resResult(STATUS.RESONANCE_PUT_POSITION_EXIST_JOBSTAGE);
|
||||
if (skins.find(cur => (cur?.usedTalentPoint || 0) > 0)) return resResult(STATUS.RESONANCE_PUT_POSITION_EXIST_TALENT);
|
||||
if (connections.length > 0) return resResult(STATUS.RESONANCE_PUT_POSITION_EXIST_CONNECT);
|
||||
if (ePlace.length > 0) return resResult(STATUS.RESONANCE_PUT_POSITION_EXIST_EQUIP);
|
||||
|
||||
let result = await ResonanceModel.updateByPosition(roleId, position, { hid, seqId, lv, exp, jobStage, skinId, skins, connections, ePlace, ce });
|
||||
if (!result) return resResult(STATUS.RESONANCE_PUT_POSITION_FAIL);
|
||||
|
||||
const resonances = await refreshResonanceData(roleId, serverId, sid);
|
||||
|
||||
return resResult(STATUS.SUCCESS, { resonanceDatas: resonances })
|
||||
}
|
||||
|
||||
async heroOffPosition(msg: { position: number, hid: number }, session: BackendSession) {
|
||||
const { position, hid } = msg;
|
||||
const roleId: string = session.get('roleId');
|
||||
const sid: string = session.get('sid');
|
||||
const serverId: number = session.get('serverId');
|
||||
|
||||
let dbResonance = await ResonanceModel.findByPositionAndHid(roleId, position, hid);
|
||||
if (!dbResonance) return resResult(STATUS.RESONANCE_NOT_PUT_POSITION);
|
||||
|
||||
let dbHero = await HeroModel.findByHidAndRole(hid, roleId);
|
||||
if (!dbHero) return resResult(STATUS.ROLE_HERO_NOT_EXISTS);
|
||||
|
||||
let { lv = 1, exp = 0, jobStage = 0, skinId, skins = [], connections = [], ePlace = [], seqId } = dbResonance;
|
||||
for (let obj of dbHero.skins) {
|
||||
let newSkin = skins.find(cur => cur.id == obj.id);
|
||||
if (newSkin) {
|
||||
obj.skinId = newSkin.skinId;
|
||||
obj.enable = newSkin.enable;
|
||||
obj.talent = newSkin.talent;
|
||||
obj.usedTalentPoint = newSkin.usedTalentPoint;
|
||||
}
|
||||
}
|
||||
let heroResult = await HeroModel.updateHeroInfo(roleId, hid, { lv, exp, jobStage, skinId, skins: dbHero.skins, connections, ePlace });
|
||||
if (!heroResult) return resResult(STATUS.RESONANCE_OFF_POSITION_FAIL);
|
||||
|
||||
// 重新计算战力
|
||||
let dbJewelMap = await getJewelDataMap([heroResult]);
|
||||
let artifact = await ArtifactModel.findbySeqId(roleId, seqId);
|
||||
let artifacts: ArtifactModelType[] = [];
|
||||
if (artifact) {
|
||||
artifacts = [artifact]
|
||||
}
|
||||
let { curHero } = await calculateCeWithHero(HERO_SYSTEM_TYPE.RESONANCE_CAL, roleId, serverId, sid, hid, heroResult, { jewels: [...dbJewelMap.values()], heroes: [heroResult], artifacts });
|
||||
|
||||
|
||||
await ResonanceModel.deletePosition(roleId, position);
|
||||
let result = await ResonanceModel.updateByPosition(roleId, position, {});
|
||||
if (!result || result.hid) return resResult(STATUS.RESONANCE_OFF_POSITION_FAIL);
|
||||
await ResonanceHistoryModel.updateByPosition(roleId, position, { ...dbResonance, time: new Date() });
|
||||
|
||||
const resonances = await refreshResonanceData(roleId, serverId, sid);
|
||||
|
||||
return resResult(STATUS.SUCCESS, {
|
||||
curHero: { ...pick(new HeroParam(curHero), ['hid', 'seqId', 'lv', 'exp', 'jobStage', 'skinId', 'skins', 'talent', 'usedTalentPoint', 'totalTalentPoint', 'connections', 'ePlace', 'ce']) },
|
||||
resonanceDatas: resonances,
|
||||
})
|
||||
}
|
||||
|
||||
}
|
||||
@@ -2250,6 +2250,25 @@ export function checkRouteParam(route: string, msg: any) {
|
||||
}
|
||||
break;
|
||||
}
|
||||
case "role.resonanceHandler.getData":
|
||||
{
|
||||
break;
|
||||
}
|
||||
case "role.resonanceHandler.unlockPosition":
|
||||
{
|
||||
if (!checkNaturalNumbers(msg.position)) return false;
|
||||
break;
|
||||
}
|
||||
case "role.resonanceHandler.heroPutPosition":
|
||||
{
|
||||
if (!checkNaturalNumbers(msg.position, msg.hid)) return false;
|
||||
break;
|
||||
}
|
||||
case "role.resonanceHandler.heroOffPosition":
|
||||
{
|
||||
if (!checkNaturalNumbers(msg.position, msg.hid)) return false;
|
||||
break;
|
||||
}
|
||||
case 'activity.dragonBoatHandler.gameStart':
|
||||
case 'activity.dragonBoatHandler.gameEnd':
|
||||
{
|
||||
|
||||
@@ -61,6 +61,7 @@ import { getVestigeRecStatus } from './gvg/gvgFightService';
|
||||
import { getRemoteRplPrefix } from '../pubUtils/battleUtils';
|
||||
import { calculateCeWithRole } from './playerCeService';
|
||||
import { SchoolModel } from '../db/School';
|
||||
import { getResonanceDataMap } from './role/resonanceService';
|
||||
|
||||
/**
|
||||
* init: 初始的时候是否推送 true-推 false-不推
|
||||
@@ -140,8 +141,17 @@ export async function getModuleData(type: string, data: { role: RoleType, sessio
|
||||
let artifacts = await ArtifactModel.findbyRole(role.roleId, ARTIFACT_SELECT.ENTRY);
|
||||
let activityItems = await ActivityItemModel.findbyRole(role.roleId, ACTIVITYITEM_SELECT.ENTRY);
|
||||
let link = await LinkModel.findByType(SNS_LINK_TYPE.CUSTOMER);
|
||||
|
||||
await reCalJewel(role, heros, jewels, skins, artifacts);
|
||||
let { dbResonanceMap } = await getResonanceDataMap(role.roleId);
|
||||
|
||||
role['heros'] = heros.map(hero => new HeroParam(hero));
|
||||
for(let hero of role['heros']){
|
||||
if(dbResonanceMap.has(hero.hid)){
|
||||
hero.isResonance = true;
|
||||
}
|
||||
}
|
||||
|
||||
role['jewels'] = jewels;
|
||||
role['consumeGoods'] = items;
|
||||
role['skins'] = skins;
|
||||
|
||||
@@ -486,6 +486,34 @@ export async function calculateCes(type: HERO_SYSTEM_TYPE, roleId: string, serve
|
||||
ceChangeTxt.push(`重生武将重新计算, 重生武将hids:${hids}`);
|
||||
break;
|
||||
}
|
||||
case HERO_SYSTEM_TYPE.RESONANCE_CAL: // 43. 共鸣
|
||||
{
|
||||
let hids = [];
|
||||
let { jewels, heroes, artifacts } = param;
|
||||
for (let { hid, skinId, lv, quality, star, starStage, colorStar, colorStarStage, job, jobStage, connections, skins, ePlace } of heroes) {
|
||||
calCe.setHeroBase(hid, skinId);
|
||||
calCe.setHeroLv(hid, lv);
|
||||
calCe.setHeroStar(hid, job, quality, star, starStage, colorStar, colorStarStage);
|
||||
calCe.setJob(hid, job, jobStage);
|
||||
calCe.setConnection(hid, connections);
|
||||
calCe.setTalent(hid, skins);
|
||||
calCe.clearEquip(hid);
|
||||
for (let { id, equipId, star, starStage, quality, qualityStage, lv: equipLv, stones, jewel } of ePlace) {
|
||||
calCe.setEquipQuality(hid, id, equipId, quality, qualityStage);
|
||||
calCe.setEquipStrength(hid, id, equipId, equipLv);
|
||||
calCe.setEquipStar(hid, id, equipId, star, starStage);
|
||||
let curJewel = jewels.find(cur => cur.seqId == jewel);
|
||||
calCe.setJewel(hid, id, stones, curJewel);
|
||||
calCe.setStone(hid, id, stones);
|
||||
}
|
||||
let artifact = artifacts.find(cur => cur.hid == hid);
|
||||
if (artifact) calCe.setPutArtifact(hid, skinId, job, artifact);
|
||||
calCe.setEquipSuit(hid, skinId, ePlace);
|
||||
hids.push(hid);
|
||||
}
|
||||
ceChangeTxt.push(`共鸣系统武将重新计算, 重生武将hids:${hids}`);
|
||||
break;
|
||||
}
|
||||
}
|
||||
let { heroCe, roleInc } = calCe.getCeInc(); // 计算战力,获得有变化的武将战力
|
||||
let changeHids: number[] = [];
|
||||
|
||||
453
game-server/app/services/role/resonanceService.ts
Normal file
453
game-server/app/services/role/resonanceService.ts
Normal file
@@ -0,0 +1,453 @@
|
||||
import { EQUIP_EPLACEID, EQUIP_STONE, FRIENDSHIP_INDEX, HERO_SYSTEM_TYPE, RESONANCE_SORT_TYPE } from "../../consts";
|
||||
import { ArtifactModel } from "../../db/Artifact";
|
||||
import { EPlace, HeroModel, HeroType, HeroUpdate } from "../../db/Hero";
|
||||
import { JewelModel, JewelType } from "../../db/Jewel";
|
||||
import { ResonanceModel, ResonanceType } from "../../db/Resonance";
|
||||
import { RoleModel } from "../../db/Role";
|
||||
import { HeroParam } from "../../domain/roleField/hero";
|
||||
import { gameData, getEquipByJobClassAndEPlace } from "../../pubUtils/data";
|
||||
import { RESONANCE } from "../../pubUtils/dicParam";
|
||||
import { ReturnResonanceParam } from "../../pubUtils/interface";
|
||||
import { calculateCeWithHeroes } from "../playerCeService";
|
||||
import { initSkinTalent } from "../roleService";
|
||||
import { pick } from 'underscore';
|
||||
import * as util from 'util';
|
||||
|
||||
export async function getStartLimt(roleId: string) {
|
||||
const role = await RoleModel.findByRoleId(roleId);
|
||||
if (!role || !role.mainWarId || role.mainWarId < RESONANCE.START_MAIN_WARId) return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
export async function refreshResonanceData(roleId: string, serverId: number, sid: string) {
|
||||
let resonances: ReturnResonanceParam[] = [];
|
||||
|
||||
let dbHeroes: HeroType[] = await HeroModel.findByRole(roleId, [{ field: 'ce', sortBy: -1 }]);
|
||||
if (dbHeroes.length < RESONANCE.HOSTER) return resonances;
|
||||
|
||||
|
||||
let { dbResonanceMap, newPositionArr } = await getResonanceDataMap(roleId);
|
||||
for (let positon of newPositionArr) {
|
||||
resonances.push({ positon });
|
||||
}
|
||||
if (dbResonanceMap.size == 0) return resonances;
|
||||
|
||||
let dbJewelMap = await getJewelDataMap(dbHeroes);
|
||||
|
||||
// 武将等级
|
||||
let topLineHero: HeroType = sortData(dbResonanceMap, dbHeroes, RESONANCE_SORT_TYPE.LV);
|
||||
for (let [hid] of dbResonanceMap) {
|
||||
let hero = dbHeroes.find(cur => cur.hid == hid);
|
||||
hero.lv = topLineHero.lv;
|
||||
hero.exp = topLineHero.exp;
|
||||
}
|
||||
|
||||
// 职业(职阶、天赋)
|
||||
topLineHero = sortData(dbResonanceMap, dbHeroes, RESONANCE_SORT_TYPE.JOBSTAGE);
|
||||
for (let [hid] of dbResonanceMap) {
|
||||
let hero = dbHeroes.find(cur => cur.hid == hid);
|
||||
let preJobStage = hero.jobStage;
|
||||
hero.jobStage = topLineHero.jobStage;
|
||||
|
||||
if (preJobStage != hero.jobStage) {
|
||||
//天赋树置空
|
||||
hero.skins = initSkinTalent(hero.skins || []);
|
||||
}
|
||||
}
|
||||
|
||||
// 羁绊1, 2, 3
|
||||
for (let index = 1; index <= FRIENDSHIP_INDEX.THREE; index++) {
|
||||
topLineHero = sortData(dbResonanceMap, dbHeroes, RESONANCE_SORT_TYPE.CONNECT, index);
|
||||
for (let [hid] of dbResonanceMap) {
|
||||
let hero = dbHeroes.find(cur => cur.hid == hid);
|
||||
const topDicShipId = gameData.friendShipByIndex.get(`${topLineHero.hid}_${index}`);
|
||||
const topShipData = topLineHero.connections.find(cur => cur.shipId == topDicShipId);
|
||||
if (!topShipData) continue;
|
||||
const dicShipId = gameData.friendShipByIndex.get(`${hero.hid}_${index}`)
|
||||
let shipData = hero.connections.find(cur => cur.shipId == dicShipId);
|
||||
|
||||
if (!shipData) hero.connections.push({ shipId: dicShipId, level: topShipData.level, exp: topShipData.exp });
|
||||
else {
|
||||
shipData.exp = topShipData.exp;
|
||||
shipData.level = topShipData.level;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 装备 1武器,2衣甲,3帽子,4鞋子
|
||||
for (let id = 1; id <= EQUIP_EPLACEID.SHOE_ID; id++) {
|
||||
|
||||
//装备强化
|
||||
topLineHero = sortData(dbResonanceMap, dbHeroes, RESONANCE_SORT_TYPE.EQUIP_LV, id);
|
||||
for (let [hid] of dbResonanceMap) {
|
||||
let hero = dbHeroes.find(cur => cur.hid == hid);
|
||||
const topLineHeroEplace = topLineHero.ePlace.find(cur => cur.id == id);
|
||||
if (!topLineHeroEplace || !topLineHeroEplace.lv) continue;
|
||||
|
||||
let ePlaceData = hero.ePlace.find(cur => cur.id == id);
|
||||
if (!ePlaceData) {
|
||||
ePlaceData = await getInitEplace(id, hero.skinId);
|
||||
hero.ePlace.push({ ...ePlaceData });
|
||||
}
|
||||
ePlaceData.lv = topLineHeroEplace.lv;
|
||||
}
|
||||
|
||||
//装备升品
|
||||
topLineHero = sortData(dbResonanceMap, dbHeroes, RESONANCE_SORT_TYPE.EQUIP_QUALITY, id);
|
||||
for (let [hid] of dbResonanceMap) {
|
||||
let hero = dbHeroes.find(cur => cur.hid == hid);
|
||||
const topLineHeroEplace = topLineHero.ePlace.find(cur => cur.id == id);
|
||||
if (!topLineHeroEplace || !topLineHeroEplace.quality) continue;
|
||||
|
||||
let ePlaceData = hero.ePlace.find(cur => cur.id == id);
|
||||
if (!ePlaceData) {
|
||||
ePlaceData = await getInitEplace(id, hero.skinId);
|
||||
hero.ePlace.push({ ...ePlaceData });
|
||||
};
|
||||
ePlaceData.quality = topLineHeroEplace.quality;
|
||||
ePlaceData.qualityStage = topLineHeroEplace.qualityStage;
|
||||
}
|
||||
|
||||
//装备精练
|
||||
topLineHero = sortData(dbResonanceMap, dbHeroes, RESONANCE_SORT_TYPE.EQUIP_STAR, id);
|
||||
for (let [hid] of dbResonanceMap) {
|
||||
let hero = dbHeroes.find(cur => cur.hid == hid);
|
||||
const topLineHeroEplace = topLineHero.ePlace.find(cur => cur.id == id);
|
||||
if (!topLineHeroEplace || !topLineHeroEplace.star) continue;
|
||||
|
||||
let ePlaceData = hero.ePlace.find(cur => cur.id == id);
|
||||
if (!ePlaceData) {
|
||||
ePlaceData = await getInitEplace(id, hero.skinId);
|
||||
hero.ePlace.push({ ...ePlaceData });
|
||||
};
|
||||
ePlaceData.star = topLineHeroEplace.star;
|
||||
ePlaceData.starStage = topLineHeroEplace.starStage;
|
||||
}
|
||||
|
||||
//天晶
|
||||
if (RESONANCE.JEWEL) {
|
||||
topLineHero = sortData(dbResonanceMap, dbHeroes, RESONANCE_SORT_TYPE.JEWEL, id, dbJewelMap);
|
||||
//破,御,护,命
|
||||
for (let [hid] of dbResonanceMap) {
|
||||
let hero = dbHeroes.find(cur => cur.hid == hid);
|
||||
const topLineHeroEplace = topLineHero.ePlace.find(cur => cur.id == id);
|
||||
if (!topLineHeroEplace || !topLineHeroEplace.jewel) continue;
|
||||
|
||||
let ePlaceData = hero.ePlace.find(cur => cur.id == id);
|
||||
if (!ePlaceData) {
|
||||
ePlaceData = await getInitEplace(id, hero.skinId);
|
||||
hero.ePlace.push({ ...ePlaceData });
|
||||
};
|
||||
ePlaceData.jewel = topLineHeroEplace.jewel;
|
||||
}
|
||||
}
|
||||
|
||||
//地玉
|
||||
if (RESONANCE.STONE) {
|
||||
//破,御,护,命 1,2,3
|
||||
for (let index = 1; index <= EQUIP_STONE.THREE; index++) {
|
||||
topLineHero = sortData(dbResonanceMap, dbHeroes, RESONANCE_SORT_TYPE.STONE, id, null, index);
|
||||
for (let [hid] of dbResonanceMap) {
|
||||
let hero = dbHeroes.find(cur => cur.hid == hid);
|
||||
const topLineHeroEplace = topLineHero.ePlace.find(cur => cur.id == id);
|
||||
if (!topLineHeroEplace || !topLineHeroEplace.stones) continue;
|
||||
const topLineHeroStone = topLineHeroEplace.stones.find(cur => cur.id == index);
|
||||
if (!topLineHeroStone || !topLineHeroStone.stone) continue;
|
||||
|
||||
let ePlaceData = hero.ePlace.find(cur => cur.id == id);
|
||||
if (!ePlaceData) {
|
||||
ePlaceData = await getInitEplace(id, hero.skinId);
|
||||
hero.ePlace.push({ ...ePlaceData });
|
||||
};
|
||||
ePlaceData.stones.find(cur => cur.id == index).stone = topLineHeroStone.stone;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
let updateHeroes: HeroUpdate[] = [], newHeroes: HeroType[] = [], newHeroIds: number[] = [];
|
||||
for (let [hid] of dbResonanceMap) {
|
||||
let hero = dbHeroes.find(cur => cur.hid == hid);
|
||||
// console.log('-x-x--x-x-x-x-x-x-x-x-x-55 hero', util.inspect(hero, { depth: null }));
|
||||
updateHeroes.push({ ...pick(hero, ['roleId', 'hid', 'lv', 'exp', 'jobStage', 'connections', 'skins', 'jobStage', 'ePlace']) })
|
||||
newHeroes.push(hero);
|
||||
newHeroIds.push(hid);
|
||||
}
|
||||
await HeroModel.bulkWriteUpdate(updateHeroes)
|
||||
|
||||
// 重新计算战力
|
||||
let artifacts = await ArtifactModel.findbyHids(roleId, newHeroIds);
|
||||
let { heroes } = await calculateCeWithHeroes(HERO_SYSTEM_TYPE.REBORN_CAL, roleId, serverId, sid, newHeroes, { jewels: [...dbJewelMap.values()], heroes: newHeroes, artifacts });
|
||||
|
||||
for (let hero of (heroes || [])) {
|
||||
const { hid } = hero;
|
||||
const heroResult = new HeroParam(hero);
|
||||
if (!dbResonanceMap.has(hid)) continue;
|
||||
resonances.push({ positon: dbResonanceMap.get(hid).position, ...pick(heroResult, ['hid', 'seqId', 'lv', 'exp', 'jobStage', 'talent', 'usedTalentPoint', 'totalTalentPoint', 'connections', 'ePlace', 'ce']) });
|
||||
}
|
||||
|
||||
return resonances;
|
||||
}
|
||||
|
||||
|
||||
export function sortData(dbResonanceMap: Map<number, ResonanceType>, heroes: HeroType[], sortType: number, findType?: number, jewelMap?: Map<number, JewelType>, extendValue?: number) {
|
||||
switch (sortType) {
|
||||
case RESONANCE_SORT_TYPE.LV:
|
||||
{
|
||||
heroes.sort((a, b) => {
|
||||
if (a.lv !== b.lv) {
|
||||
return b.lv - a.lv;
|
||||
} else {
|
||||
return b.ce - a.ce;
|
||||
}
|
||||
});
|
||||
break;
|
||||
}
|
||||
case RESONANCE_SORT_TYPE.JOBSTAGE:
|
||||
{
|
||||
heroes.sort((a, b) => {
|
||||
if (a.jobStage !== b.jobStage) {
|
||||
return b.jobStage - a.jobStage;
|
||||
} else {
|
||||
return b.ce - a.ce;
|
||||
}
|
||||
});
|
||||
break;
|
||||
}
|
||||
case RESONANCE_SORT_TYPE.CONNECT:
|
||||
{
|
||||
heroes = sortByConnect(heroes, findType)
|
||||
break;
|
||||
}
|
||||
|
||||
case RESONANCE_SORT_TYPE.EQUIP_LV:
|
||||
{
|
||||
heroes = sortByEquipLv(heroes, findType);
|
||||
break;
|
||||
}
|
||||
case RESONANCE_SORT_TYPE.EQUIP_QUALITY:
|
||||
{
|
||||
heroes = sortByEquipQuality(heroes, findType);
|
||||
break;
|
||||
}
|
||||
case RESONANCE_SORT_TYPE.EQUIP_STAR:
|
||||
{
|
||||
heroes = sortByEquipStar(heroes, findType);
|
||||
break;
|
||||
}
|
||||
case RESONANCE_SORT_TYPE.JEWEL:
|
||||
{
|
||||
heroes = sortByEquipJewel(heroes, findType, jewelMap);
|
||||
break;
|
||||
}
|
||||
case RESONANCE_SORT_TYPE.STONE:
|
||||
{
|
||||
heroes = sortByEquipStone(heroes, findType, extendValue);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
let topLineHeroes: HeroType[] = [];
|
||||
for (let hero of heroes) {
|
||||
const { hid } = hero;
|
||||
if (!dbResonanceMap.has(hid) && topLineHeroes.length < RESONANCE.HOSTER) {
|
||||
topLineHeroes.push(hero);
|
||||
}
|
||||
}
|
||||
|
||||
return topLineHeroes[RESONANCE.HOSTER - 1];
|
||||
}
|
||||
|
||||
export function sortByConnect(heroes: HeroType[], index: number) {
|
||||
heroes.sort((a, b) => {
|
||||
const dicShipIdA = gameData.friendShipByIndex.get(`${a.hid}_${index}`)
|
||||
const valA = a.connections.find(obj => obj.shipId === dicShipIdA)?.level || 0;
|
||||
const dicShipIdB = gameData.friendShipByIndex.get(`${b.hid}_${index}`)
|
||||
const valB = b.connections.find(obj => obj.shipId === dicShipIdB)?.level || 0;
|
||||
if (valA != valB) {
|
||||
return valB - valA;
|
||||
} else {
|
||||
return b.ce - a.ce;
|
||||
}
|
||||
});
|
||||
|
||||
return heroes
|
||||
}
|
||||
|
||||
export function sortByEquipLv(heroes: HeroType[], id: number) {
|
||||
heroes.sort((a, b) => {
|
||||
const valA = a.ePlace.find(obj => obj.id == id)?.lv || 0
|
||||
const valB = b.ePlace.find(obj => obj.id == id)?.lv || 0;
|
||||
if (valA != valB) {
|
||||
return valB - valA;
|
||||
} else {
|
||||
return b.ce - a.ce;
|
||||
}
|
||||
});
|
||||
return heroes;
|
||||
}
|
||||
|
||||
export function sortByEquipQuality(heroes: HeroType[], id: number) {
|
||||
heroes.sort((a, b) => {
|
||||
const valA = a.ePlace.find(obj => obj.id == id)?.quality || 0;
|
||||
const valStageA = a.ePlace.find(obj => obj.id == id)?.qualityStage || 0;
|
||||
const valB = b.ePlace.find(obj => obj.id == id)?.quality || 0;
|
||||
const valStageB = b.ePlace.find(obj => obj.id == id)?.qualityStage || 0;
|
||||
|
||||
if (valA != valB) {
|
||||
return valB - valA;
|
||||
}
|
||||
else if (valStageA != valStageB) {
|
||||
return valStageB - valStageA;
|
||||
}
|
||||
else {
|
||||
return b.ce - a.ce;
|
||||
}
|
||||
});
|
||||
return heroes;
|
||||
}
|
||||
|
||||
export function sortByEquipStar(heroes: HeroType[], id: number) {
|
||||
heroes.sort((a, b) => {
|
||||
const valA = a.ePlace.find(obj => obj.id == id)?.star || 0;
|
||||
const valStageA = a.ePlace.find(obj => obj.id == id)?.starStage || 0;
|
||||
const valB = b.ePlace.find(obj => obj.id == id)?.star || 0;
|
||||
const valStageB = b.ePlace.find(obj => obj.id == id)?.starStage || 0;
|
||||
|
||||
if (valA != valB) {
|
||||
return valB - valA;
|
||||
}
|
||||
else if (valStageA != valStageB) {
|
||||
return valStageB - valStageA;
|
||||
}
|
||||
else {
|
||||
return b.ce - a.ce;
|
||||
}
|
||||
});
|
||||
return heroes;
|
||||
}
|
||||
|
||||
export function sortByEquipJewel(heroes: HeroType[], eplaceId: number, jewelMap: Map<number, JewelType>) {
|
||||
heroes.sort((a, b) => {
|
||||
const jewelA = a.ePlace.find(obj => obj.id == eplaceId)?.jewel || 0
|
||||
let jewelAData = jewelMap.get(jewelA);
|
||||
const dicJewelALv = gameData.jewel.get(jewelAData?.id || 0)?.lv || 0;
|
||||
let valA = 0;
|
||||
if (jewelAData) {
|
||||
if (jewelAData.randSe && jewelAData.randSe.length > 0) {
|
||||
for (let { seid, rand } of jewelAData.randSe) {
|
||||
let dicRandomEffectPool = gameData.randomEffectPool.get(seid);
|
||||
if (!dicRandomEffectPool) continue;
|
||||
if (!dicRandomEffectPool.Max) dicRandomEffectPool = gameData.randomEffectPool.get(1);
|
||||
if (!dicRandomEffectPool || (dicRandomEffectPool?.Max || 0 == 0)) continue;
|
||||
valA += rand / (dicRandomEffectPool.Max);
|
||||
}
|
||||
}
|
||||
if (jewelAData.rareSe && jewelAData.rareSe.length > 0) {
|
||||
for (let { seid, rand } of jewelAData.rareSe) {
|
||||
let dicRandomEffectPool = gameData.randomEffectPool.get(seid);
|
||||
if (!dicRandomEffectPool) continue;
|
||||
if (!dicRandomEffectPool.Max) dicRandomEffectPool = gameData.randomEffectPool.get(1);
|
||||
if (!dicRandomEffectPool || (dicRandomEffectPool?.Max || 0 == 0)) continue;
|
||||
valA += rand / (dicRandomEffectPool.Max);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const jewelB = b.ePlace.find(obj => obj.id == eplaceId)?.jewel || 0
|
||||
let jewelBData = jewelMap.get(jewelB);
|
||||
const dicJewelBLv = gameData.jewel.get(jewelBData?.id || 0)?.lv || 0;
|
||||
let valB = 0;
|
||||
if (jewelBData) {
|
||||
if (jewelBData.randSe && jewelBData.randSe.length > 0) {
|
||||
for (let { seid, rand } of jewelBData.randSe) {
|
||||
let dicRandomEffectPool = gameData.randomEffectPool.get(seid);
|
||||
if (!dicRandomEffectPool) continue;
|
||||
if (!dicRandomEffectPool.Max) dicRandomEffectPool = gameData.randomEffectPool.get(1);
|
||||
if (!dicRandomEffectPool || (dicRandomEffectPool?.Max || 0 == 0)) continue;
|
||||
valB += rand / (dicRandomEffectPool.Max);
|
||||
}
|
||||
}
|
||||
if (jewelBData.rareSe && jewelBData.rareSe.length > 0) {
|
||||
for (let { seid, rand } of jewelBData.rareSe) {
|
||||
let dicRandomEffectPool = gameData.randomEffectPool.get(seid);
|
||||
if (!dicRandomEffectPool) continue;
|
||||
if (!dicRandomEffectPool.Max) dicRandomEffectPool = gameData.randomEffectPool.get(1);
|
||||
if (!dicRandomEffectPool || (dicRandomEffectPool?.Max || 0 == 0)) continue;
|
||||
valB += rand / (dicRandomEffectPool.Max);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (dicJewelALv != dicJewelBLv) {
|
||||
return dicJewelBLv - dicJewelALv;
|
||||
}
|
||||
else if (valA != valB) {
|
||||
return valB - valA;
|
||||
} else {
|
||||
return b.ce - a.ce;
|
||||
}
|
||||
});
|
||||
|
||||
return heroes;
|
||||
}
|
||||
|
||||
export function sortByEquipStone(heroes: HeroType[], id: number, extendValue: number) {
|
||||
heroes.sort((a, b) => {
|
||||
const stoneA = a.ePlace.find(obj => obj.id == id)?.stones || [];
|
||||
const stoneIdA = stoneA.find(obj => obj.id == extendValue)?.stone || 0;
|
||||
const valA = gameData.stone.get(stoneIdA)?.lv || 0;
|
||||
const stoneB = b.ePlace.find(obj => obj.id == id)?.stones || [];
|
||||
const stoneIdB = stoneB.find(obj => obj.id == extendValue)?.stone || 0;
|
||||
const valB = gameData.stone.get(stoneIdB)?.lv || 0;
|
||||
|
||||
if (valA != valB) {
|
||||
return valB - valA;
|
||||
} else {
|
||||
return b.ce - a.ce;
|
||||
}
|
||||
});
|
||||
return heroes;
|
||||
}
|
||||
|
||||
|
||||
export async function getResonanceDataMap(roleId: string) {
|
||||
let dbResonance = await ResonanceModel.findByRoleId(roleId);
|
||||
let dbResonanceMap = new Map<number, ResonanceType>();
|
||||
let newPositionArr: number[] = [];
|
||||
for (let obj of dbResonance) {
|
||||
if (obj.hid) dbResonanceMap.set(obj.hid, obj);
|
||||
else newPositionArr.push(obj.position);
|
||||
|
||||
}
|
||||
return { dbResonanceMap, newPositionArr };
|
||||
}
|
||||
|
||||
export async function getJewelDataMap(heroes: HeroType[]) {
|
||||
let dbJewelMap = new Map<number, JewelType>();
|
||||
let seqIds = [];
|
||||
for (let hero of heroes) {
|
||||
const { ePlace } = hero;
|
||||
if (!ePlace || ePlace.length == 0) continue;
|
||||
for (let { jewel } of ePlace) {
|
||||
if (jewel == 0) continue;
|
||||
seqIds.push(jewel);
|
||||
}
|
||||
}
|
||||
if (seqIds.length > 0) {
|
||||
let dbJewels = await JewelModel.findbySeqIds(seqIds);
|
||||
if (dbJewels.length > 0) {
|
||||
for (let obj of dbJewels) {
|
||||
dbJewelMap.set(obj.seqId, obj);
|
||||
}
|
||||
}
|
||||
}
|
||||
return dbJewelMap;
|
||||
}
|
||||
|
||||
export async function getInitEplace(id: number, skinId: number) {
|
||||
const dicHero = gameData.hero.get(skinId)
|
||||
const dicEquip = getEquipByJobClassAndEPlace(dicHero?.jobClass, id);
|
||||
return new EPlace(id, dicEquip.id);
|
||||
}
|
||||
Reference in New Issue
Block a user