✨ 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;
|
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.gameStart':
|
||||||
case 'activity.dragonBoatHandler.gameEnd':
|
case 'activity.dragonBoatHandler.gameEnd':
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -61,6 +61,7 @@ import { getVestigeRecStatus } from './gvg/gvgFightService';
|
|||||||
import { getRemoteRplPrefix } from '../pubUtils/battleUtils';
|
import { getRemoteRplPrefix } from '../pubUtils/battleUtils';
|
||||||
import { calculateCeWithRole } from './playerCeService';
|
import { calculateCeWithRole } from './playerCeService';
|
||||||
import { SchoolModel } from '../db/School';
|
import { SchoolModel } from '../db/School';
|
||||||
|
import { getResonanceDataMap } from './role/resonanceService';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* init: 初始的时候是否推送 true-推 false-不推
|
* 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 artifacts = await ArtifactModel.findbyRole(role.roleId, ARTIFACT_SELECT.ENTRY);
|
||||||
let activityItems = await ActivityItemModel.findbyRole(role.roleId, ACTIVITYITEM_SELECT.ENTRY);
|
let activityItems = await ActivityItemModel.findbyRole(role.roleId, ACTIVITYITEM_SELECT.ENTRY);
|
||||||
let link = await LinkModel.findByType(SNS_LINK_TYPE.CUSTOMER);
|
let link = await LinkModel.findByType(SNS_LINK_TYPE.CUSTOMER);
|
||||||
|
|
||||||
await reCalJewel(role, heros, jewels, skins, artifacts);
|
await reCalJewel(role, heros, jewels, skins, artifacts);
|
||||||
|
let { dbResonanceMap } = await getResonanceDataMap(role.roleId);
|
||||||
|
|
||||||
role['heros'] = heros.map(hero => new HeroParam(hero));
|
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['jewels'] = jewels;
|
||||||
role['consumeGoods'] = items;
|
role['consumeGoods'] = items;
|
||||||
role['skins'] = skins;
|
role['skins'] = skins;
|
||||||
|
|||||||
@@ -486,6 +486,34 @@ export async function calculateCes(type: HERO_SYSTEM_TYPE, roleId: string, serve
|
|||||||
ceChangeTxt.push(`重生武将重新计算, 重生武将hids:${hids}`);
|
ceChangeTxt.push(`重生武将重新计算, 重生武将hids:${hids}`);
|
||||||
break;
|
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 { heroCe, roleInc } = calCe.getCeInc(); // 计算战力,获得有变化的武将战力
|
||||||
let changeHids: number[] = [];
|
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);
|
||||||
|
}
|
||||||
@@ -43,6 +43,7 @@ export enum HERO_SYSTEM_TYPE {
|
|||||||
AUTHOR_BOOK_STAR = 40, // 诸子列传升星
|
AUTHOR_BOOK_STAR = 40, // 诸子列传升星
|
||||||
AUTHOR_BOOK_SUB_RESET = 41, // 诸子列传重置
|
AUTHOR_BOOK_SUB_RESET = 41, // 诸子列传重置
|
||||||
REBORN_CAL = 42, //重生计算
|
REBORN_CAL = 42, //重生计算
|
||||||
|
RESONANCE_CAL = 43, //共鸣重新计算战力
|
||||||
};
|
};
|
||||||
|
|
||||||
// 武将上限
|
// 武将上限
|
||||||
|
|||||||
@@ -695,6 +695,7 @@ export const FILENAME = {
|
|||||||
DIC_ROUGE_TECH_LEVEL: "dic_rougeTechLevel",
|
DIC_ROUGE_TECH_LEVEL: "dic_rougeTechLevel",
|
||||||
DIC_GUILD_HP_RATIO: "dic_army_hpRatio",
|
DIC_GUILD_HP_RATIO: "dic_army_hpRatio",
|
||||||
DIC_SPIRIT_COMPOSE: "dic_zyz_spiritCompose",
|
DIC_SPIRIT_COMPOSE: "dic_zyz_spiritCompose",
|
||||||
|
DIC_RESONANCE: "dic_zyz_resonance",
|
||||||
}
|
}
|
||||||
|
|
||||||
export const WAR_RELATE_TABLES = [
|
export const WAR_RELATE_TABLES = [
|
||||||
@@ -1286,6 +1287,7 @@ export enum ITEM_CHANGE_REASON {
|
|||||||
NOVEMBER_REWARD = 207, // 辜月集会奖励
|
NOVEMBER_REWARD = 207, // 辜月集会奖励
|
||||||
NOVEMBER_COST = 208, // 辜月集会购买消耗
|
NOVEMBER_COST = 208, // 辜月集会购买消耗
|
||||||
EXCHANGE_SPIRIT = 209, // 将灵合成
|
EXCHANGE_SPIRIT = 209, // 将灵合成
|
||||||
|
RESONANCE_LOCK_POSITION = 210, // 共鸣解锁阵位消耗
|
||||||
}
|
}
|
||||||
|
|
||||||
export enum TA_EVENT {
|
export enum TA_EVENT {
|
||||||
@@ -1432,3 +1434,33 @@ export enum BOSS_HP_RATIO_TYPE {
|
|||||||
CITY_RATIO = 2, // 诸侯混战按开服天数
|
CITY_RATIO = 2, // 诸侯混战按开服天数
|
||||||
CITY_PLAYER_RATIO = 3, // 最低玩家人数
|
CITY_PLAYER_RATIO = 3, // 最低玩家人数
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export enum RESONANCE_SORT_TYPE {
|
||||||
|
LV = 1, //先等级后后战力
|
||||||
|
JOBSTAGE = 2, //职阶
|
||||||
|
CONNECT = 3, //羁绊
|
||||||
|
EQUIP_LV = 4, //装备强化
|
||||||
|
EQUIP_QUALITY = 5, //装备升品
|
||||||
|
EQUIP_STAR = 6, //装备精炼
|
||||||
|
JEWEL = 7, //天晶
|
||||||
|
STONE = 8, //地玉
|
||||||
|
}
|
||||||
|
|
||||||
|
export enum FRIENDSHIP_INDEX {
|
||||||
|
ONE = 1, // 羁绊1
|
||||||
|
TWO = 2, // 羁绊2
|
||||||
|
THREE = 3, // 羁绊3
|
||||||
|
}
|
||||||
|
|
||||||
|
export enum EQUIP_EPLACEID {
|
||||||
|
WEAPON_ID = 1, // 武器id
|
||||||
|
CLOTHES_ID = 2, // 衣甲
|
||||||
|
HAT_ID = 3, // 帽子
|
||||||
|
SHOE_ID = 4, // 鞋子
|
||||||
|
}
|
||||||
|
|
||||||
|
export enum EQUIP_STONE {
|
||||||
|
ONE = 1, // 1
|
||||||
|
TWO = 2, // 2
|
||||||
|
THREE = 3, // 3
|
||||||
|
}
|
||||||
@@ -789,7 +789,7 @@ export const STATUS = {
|
|||||||
ORDER_STATUS_ERROR: { code: 70018, simStr: '订单状态错误' },
|
ORDER_STATUS_ERROR: { code: 70018, simStr: '订单状态错误' },
|
||||||
PAY_NOT_OPEN: { code: 70019, simStr: '支付功能暂未开启' },
|
PAY_NOT_OPEN: { code: 70019, simStr: '支付功能暂未开启' },
|
||||||
|
|
||||||
// 稷下学宫 相关状态 80000 - 89999
|
// 稷下学宫 相关状态 80000 - 81000
|
||||||
SHOP_NO_BUY: { code: 80001, simStr: '商店不可购买' },
|
SHOP_NO_BUY: { code: 80001, simStr: '商店不可购买' },
|
||||||
COIN_NOT_ENOUGH: { code: 80002, simStr: '试炼币不足' },
|
COIN_NOT_ENOUGH: { code: 80002, simStr: '试炼币不足' },
|
||||||
REWARD_NO_CHOOSE: { code: 80003, simStr: '奖励不可选择' },
|
REWARD_NO_CHOOSE: { code: 80003, simStr: '奖励不可选择' },
|
||||||
@@ -827,6 +827,28 @@ export const STATUS = {
|
|||||||
ROUGE_SCORE_HAS_RECEIVED: { code: 80107, simStr: '已领取' },
|
ROUGE_SCORE_HAS_RECEIVED: { code: 80107, simStr: '已领取' },
|
||||||
ROUGE_COLLECT_NOT_ENOUGH: { code: 80108, simStr: '该图鉴条件未达成' },
|
ROUGE_COLLECT_NOT_ENOUGH: { code: 80108, simStr: '该图鉴条件未达成' },
|
||||||
ROUGE_TECH_NOT_UNLOCKED: { code: 80109, simStr: '对应科技点未解锁' },
|
ROUGE_TECH_NOT_UNLOCKED: { code: 80109, simStr: '对应科技点未解锁' },
|
||||||
|
|
||||||
|
// 共鸣系统 相关状态 81000 - 81100
|
||||||
|
RESONANCE_NO_START: { code: 81000, simStr: '共鸣系统未开启' },
|
||||||
|
RESONANCE_POSITION_LOCK: { code: 81001, simStr: '该阵位已开启' },
|
||||||
|
RESONANCE_POSITION_NOT_FOUND: { code: 81002, simStr: '该阵位不存在' },
|
||||||
|
RESONANCE_POSITION_LV_NOT_ENOUGH: { code: 81003, simStr: '解锁该阵位等级不足' },
|
||||||
|
RESONANCE_POSITION_LOCK_FAIL: { code: 81004, simStr: '解锁该阵位失败' },
|
||||||
|
RESONANCE_POSITION_UNLOCK: { code: 81005, simStr: '该阵位未解锁' },
|
||||||
|
RESONANCE_POSITION_EXIST_HID: { code: 81006, simStr: '该阵位已有武将' },
|
||||||
|
RESONANCE_PUT_POSITION_EXIST_LV: { code: 81007, simStr: '武将存在等级养成维度,请先重生' },
|
||||||
|
RESONANCE_PUT_POSITION_EXIST_JOBSTAGE: { code: 81008, simStr: '武将存在职阶养成维度,请先重生' },
|
||||||
|
RESONANCE_PUT_POSITION_EXIST_TALENT: { code: 81009, simStr: '武将存在天赋养成维度,请先重生' },
|
||||||
|
RESONANCE_PUT_POSITION_EXIST_CONNECT: { code: 81009, simStr: '武将存在羁绊养成维度,请先重生' },
|
||||||
|
RESONANCE_PUT_POSITION_EXIST_EQUIP: { code: 81010, simStr: '武将存在装备养成维度,请先重生' },
|
||||||
|
RESONANCE_PUT_POSITION_FAIL: { code: 81011, simStr: '武将上阵失败' },
|
||||||
|
RESONANCE_PUT_NOT_POSITION: { code: 81011, simStr: '武将数量不足,不可上阵' },
|
||||||
|
RESONANCE_NOT_PUT_POSITION: { code: 81011, simStr: '该武将未在阵中' },
|
||||||
|
RESONANCE_OFF_POSITION_FAIL: { code: 81011, simStr: '该武将下阵失败' },
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export const PAY_37_CALLBACK_CODE = {
|
export const PAY_37_CALLBACK_CODE = {
|
||||||
|
|||||||
@@ -362,6 +362,20 @@ export default class Hero extends BaseModel {
|
|||||||
const result = await HeroModel.count(searchObj);
|
const result = await HeroModel.count(searchObj);
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static async bulkWriteUpdate(updateArr: HeroUpdate[]) {
|
||||||
|
if (updateArr.length == 0) return;
|
||||||
|
await HeroModel.bulkWrite(updateArr.map((param) => {
|
||||||
|
const { roleId, hid } = param;
|
||||||
|
return { updateOne: { filter: { roleId, hid }, update: { $set: param }, upsert: true } }
|
||||||
|
}))
|
||||||
|
}
|
||||||
|
|
||||||
|
public static async getHidCountByRoleId(roleId:string){
|
||||||
|
let result: number = await HeroModel.countDocuments({roleId});
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export const HeroModel = getModelForClass(Hero);
|
export const HeroModel = getModelForClass(Hero);
|
||||||
|
|||||||
122
shared/db/Resonance.ts
Normal file
122
shared/db/Resonance.ts
Normal file
@@ -0,0 +1,122 @@
|
|||||||
|
|
||||||
|
import BaseModel from './BaseModel';
|
||||||
|
import { getModelForClass, prop, DocumentType, index } from '@typegoose/typegoose';
|
||||||
|
import { HeroSkin } from './Hero';
|
||||||
|
|
||||||
|
|
||||||
|
export class ResonanceEplaceStone {
|
||||||
|
@prop({ required: true })
|
||||||
|
id: number; // 孔的id
|
||||||
|
@prop({ required: true })
|
||||||
|
stone: number; // 装备的宝石id,未装备为0
|
||||||
|
}
|
||||||
|
export class ResonanceEplace {
|
||||||
|
@prop({ required: true })
|
||||||
|
id: number; // 装备栏id,id固定部位
|
||||||
|
@prop({ required: true })
|
||||||
|
equipId: number; // 装备表id
|
||||||
|
@prop({ required: true })
|
||||||
|
lv: number; // 强化等级
|
||||||
|
@prop({ required: true })
|
||||||
|
quality: number; // 品质
|
||||||
|
@prop({ required: true })
|
||||||
|
qualityStage: number; // 升品之前的小点
|
||||||
|
@prop({ required: true })
|
||||||
|
star: number; // 星级
|
||||||
|
@prop({ required: true })
|
||||||
|
starStage: number; // 升星级之前的小点
|
||||||
|
@prop({ required: true, type: ResonanceEplaceStone, _id: false })
|
||||||
|
stones: ResonanceEplaceStone[]; // 地玉石,初始的时候就有3个槽,是否解锁靠star判断
|
||||||
|
@prop({ required: true })
|
||||||
|
jewel: number; // 天晶石的seqId,具体状态去jewel表查
|
||||||
|
}
|
||||||
|
|
||||||
|
export class ResonanceConnection {
|
||||||
|
@prop({ required: true })
|
||||||
|
shipId: number; // 羁绊编号
|
||||||
|
@prop({ required: true })
|
||||||
|
level: number;
|
||||||
|
@prop({ required: true })
|
||||||
|
exp: number;
|
||||||
|
}
|
||||||
|
|
||||||
|
export class ResonanceTalent {
|
||||||
|
@prop({ required: true })
|
||||||
|
id: number; // 天赋表id
|
||||||
|
@prop({ required: true })
|
||||||
|
level: number; // 天赋等级
|
||||||
|
}
|
||||||
|
|
||||||
|
@index({ roleId: 1, position: 1, hid: 1 })
|
||||||
|
export default class Resonance extends BaseModel {
|
||||||
|
@prop({ required: true })
|
||||||
|
roleId: string;
|
||||||
|
|
||||||
|
@prop({ required: true })
|
||||||
|
position: number; // 上阵位置,前6(6是鸣主配在系统参数表)不存通过计算获得,已解锁未上阵仅有positon
|
||||||
|
|
||||||
|
@prop({ required: true })
|
||||||
|
hid: number; // 武将id
|
||||||
|
|
||||||
|
@prop({ required: true })
|
||||||
|
seqId: number; // 武将表自增id
|
||||||
|
|
||||||
|
@prop({ required: true })
|
||||||
|
lv: number; //武将等级
|
||||||
|
|
||||||
|
@prop({ required: true })
|
||||||
|
exp: number; //
|
||||||
|
|
||||||
|
@prop({ required: true })
|
||||||
|
jobStage: number; // 职阶
|
||||||
|
|
||||||
|
// @prop({ required: true, type: ResonanceTalent, _id: false })
|
||||||
|
// talent: ResonanceTalent[] // 天赋
|
||||||
|
|
||||||
|
// @prop({ required: true })
|
||||||
|
// usedTalentPoint: number; // 已使用的天赋点数
|
||||||
|
|
||||||
|
@prop({ required: true })
|
||||||
|
skinId: number; // 当前皮肤id,fashions表的heroId字段
|
||||||
|
|
||||||
|
@prop({ required: true, type: HeroSkin, default: [], _id: false })
|
||||||
|
skins: HeroSkin[]; // 皮肤
|
||||||
|
|
||||||
|
@prop({ required: true, type: ResonanceConnection, _id: false })
|
||||||
|
connections: ResonanceConnection[] // 羁绊
|
||||||
|
|
||||||
|
@prop({ required: true, type: ResonanceEplace, _id: false })
|
||||||
|
ePlace: ResonanceEplace[] // 所有装备栏
|
||||||
|
|
||||||
|
@prop({ required: true })
|
||||||
|
ce: number // 战力
|
||||||
|
|
||||||
|
public static async findByRoleId(roleId: string, lean = true) {
|
||||||
|
let result: ResonanceType[] = await ResonanceModel.find({ roleId }).lean(lean);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static async findByPosition(roleId: string, position: number, lean = true) {
|
||||||
|
let result: ResonanceType = await ResonanceModel.findOne({ roleId, position }).lean(lean);
|
||||||
|
return result
|
||||||
|
}
|
||||||
|
|
||||||
|
public static async findByPositionAndHid(roleId: string, position: number, hid: number, lean = true) {
|
||||||
|
let result: ResonanceType = await ResonanceModel.findOne({ roleId, position, hid }).lean(lean);
|
||||||
|
return result
|
||||||
|
}
|
||||||
|
|
||||||
|
public static async updateByPosition(roleId: string, position: number, param: ResonancePara, lean = true) {
|
||||||
|
let result: ResonanceType = await ResonanceModel.findOneAndUpdate({ roleId, position }, { $set: param }, { new: true, upsert: true }).lean(lean);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static async deletePosition(roleId: string, position: number) {
|
||||||
|
let result = await ResonanceModel.deleteMany({ roleId, position });
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export const ResonanceModel = getModelForClass(Resonance);
|
||||||
|
export interface ResonanceType extends Pick<DocumentType<Resonance>, keyof Resonance> { };
|
||||||
|
export type ResonancePara = Partial<ResonanceType>; // 将所有字段变成可选项
|
||||||
114
shared/db/ResonanceHistory.ts
Normal file
114
shared/db/ResonanceHistory.ts
Normal file
@@ -0,0 +1,114 @@
|
|||||||
|
|
||||||
|
import BaseModel from './BaseModel';
|
||||||
|
import { getModelForClass, prop, DocumentType, index } from '@typegoose/typegoose';
|
||||||
|
import { HeroSkin } from './Hero';
|
||||||
|
|
||||||
|
|
||||||
|
export class ResonanceHistoryEplaceStone {
|
||||||
|
@prop({ required: true })
|
||||||
|
id: number; // 孔的id
|
||||||
|
@prop({ required: true })
|
||||||
|
stone: number; // 装备的宝石id,未装备为0
|
||||||
|
}
|
||||||
|
export class ResonanceHistoryEplace {
|
||||||
|
@prop({ required: true })
|
||||||
|
id: number; // 装备栏id,id固定部位
|
||||||
|
@prop({ required: true })
|
||||||
|
equipId: number; // 装备表id
|
||||||
|
@prop({ required: true })
|
||||||
|
lv: number; // 强化等级
|
||||||
|
@prop({ required: true })
|
||||||
|
quality: number; // 品质
|
||||||
|
@prop({ required: true })
|
||||||
|
qualityStage: number; // 升品之前需要的次数
|
||||||
|
@prop({ required: true })
|
||||||
|
star: number; // 星级
|
||||||
|
@prop({ required: true })
|
||||||
|
starStage: number; // 升星级之前的小点
|
||||||
|
@prop({ required: true, type: ResonanceHistoryEplaceStone, _id: false })
|
||||||
|
stones: ResonanceHistoryEplaceStone[]; // 地玉石,初始的时候就有3个槽,是否解锁靠star判断
|
||||||
|
@prop({ required: true })
|
||||||
|
jewel: number; // 天晶石的seqId,具体状态去jewel表查
|
||||||
|
}
|
||||||
|
|
||||||
|
export class ResonanceHistoryConnection {
|
||||||
|
@prop({ required: true })
|
||||||
|
shipId: number; // 羁绊编号
|
||||||
|
@prop({ required: true })
|
||||||
|
level: number;
|
||||||
|
@prop({ required: true })
|
||||||
|
exp: number;
|
||||||
|
}
|
||||||
|
|
||||||
|
@index({ roleId: 1, position: 1, hid: 1, time: 1 })
|
||||||
|
export default class ResonanceHistory extends BaseModel {
|
||||||
|
@prop({ required: true })
|
||||||
|
roleId: string;
|
||||||
|
|
||||||
|
@prop({ required: true })
|
||||||
|
position: number; // 上阵位置,前6(6是鸣主配在系统参数表)不存通过计算获得,已解锁未上阵仅有positon
|
||||||
|
|
||||||
|
@prop({ required: true })
|
||||||
|
hid: number; // 武将id
|
||||||
|
|
||||||
|
@prop({ required: true })
|
||||||
|
seqId: number; // 武将表自增id
|
||||||
|
|
||||||
|
@prop({ required: true })
|
||||||
|
lv: number; //武将等级
|
||||||
|
|
||||||
|
@prop({ required: true })
|
||||||
|
exp: number; //
|
||||||
|
|
||||||
|
@prop({ required: true })
|
||||||
|
jobStage: number; // 职阶
|
||||||
|
|
||||||
|
@prop({ required: true })
|
||||||
|
skinId: number; // 当前皮肤id,fashions表的heroId字段
|
||||||
|
|
||||||
|
@prop({ required: true, type: HeroSkin, default: [], _id: false })
|
||||||
|
skins: HeroSkin[]; // 皮肤
|
||||||
|
|
||||||
|
@prop({ required: true, type: ResonanceHistoryConnection, _id: false })
|
||||||
|
connections: ResonanceHistoryConnection[] // 羁绊
|
||||||
|
|
||||||
|
@prop({ required: true, type: ResonanceHistoryEplace, _id: false })
|
||||||
|
ePlace: ResonanceHistoryEplace[] // 所有装备栏
|
||||||
|
|
||||||
|
@prop({ required: true })
|
||||||
|
ce: number // 战力
|
||||||
|
|
||||||
|
@prop({ required: true, default: () => new Date() })
|
||||||
|
time: Date;
|
||||||
|
|
||||||
|
// public static async findByRoleId(roleId: string, lean = true) {
|
||||||
|
// let result: ResonanceHistoryType[] = await ResonanceHistoryModel.find({ roleId }).select({ '_id': -1 }).lean(lean);
|
||||||
|
// return result;
|
||||||
|
// }
|
||||||
|
|
||||||
|
// public static async findByPosition(roleId: string, position: number, lean = true) {
|
||||||
|
// let result: ResonanceHistoryType = await ResonanceHistoryModel.findOne({ roleId, position }).select({ '_id': -1 }).lean(lean);
|
||||||
|
// return result
|
||||||
|
// }
|
||||||
|
|
||||||
|
// public static async findByPositionAndHid(roleId: string, position: number, hid: number, lean = true) {
|
||||||
|
// let result: ResonanceHistoryType = await ResonanceHistoryModel.findOne({ roleId, position, hid }).select({ '_id': -1 }).lean(lean);
|
||||||
|
// return result
|
||||||
|
// }
|
||||||
|
|
||||||
|
public static async updateByPosition(roleId: string, position: number, param: ResonanceHistoryPara, lean = true) {
|
||||||
|
delete param._id;
|
||||||
|
let result: ResonanceHistoryType = await ResonanceHistoryModel.findOneAndUpdate({ roleId, position }, { $set: param }, { new: true, upsert: true }).lean(lean);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
// public static async deletePosition(roleId: string, position: number) {
|
||||||
|
// let result = await ResonanceHistoryModel.deleteMany({ roleId, position });
|
||||||
|
// return result;
|
||||||
|
// }
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
export const ResonanceHistoryModel = getModelForClass(ResonanceHistory);
|
||||||
|
export interface ResonanceHistoryType extends Pick<DocumentType<ResonanceHistory>, keyof ResonanceHistory> { };
|
||||||
|
export type ResonanceHistoryPara = Partial<ResonanceHistoryType>; // 将所有字段变成可选项
|
||||||
35
shared/domain/roleField/resonanceField.ts
Normal file
35
shared/domain/roleField/resonanceField.ts
Normal file
@@ -0,0 +1,35 @@
|
|||||||
|
|
||||||
|
// import { ResonanceConnection, ResonanceEplace, ResonancePara, ResonanceTalent } from "../../db/Resonance";
|
||||||
|
// import { gameData } from "../../pubUtils/data";
|
||||||
|
|
||||||
|
// export class ReturnResonanceParam {
|
||||||
|
// positon: number; // 上阵位置,从1开始(6为鸣主配系统参数表),已解锁未上阵仅有positon
|
||||||
|
// hid: number; // 武将id
|
||||||
|
// seqId: number; // 武将表自增 id
|
||||||
|
// lv: number; //武将等级
|
||||||
|
// jobStage: number; // 职阶
|
||||||
|
|
||||||
|
// skinId: number
|
||||||
|
// talent: ResonanceTalent[]; // 天赋
|
||||||
|
// usedTalentPoint: number;
|
||||||
|
// totalTalentPoint: number;
|
||||||
|
|
||||||
|
// connections: ResonanceConnection[]; // 羁绊
|
||||||
|
|
||||||
|
// ePlace: ResonanceEplace[];
|
||||||
|
// ce: number; //战力
|
||||||
|
|
||||||
|
// constructor(hero: ResonancePara, job: number) {
|
||||||
|
// this.positon = hero.positon;
|
||||||
|
// this.hid = hero.hid;
|
||||||
|
// this.seqId = hero.seqId;
|
||||||
|
// this.lv = hero.lv;
|
||||||
|
// this.ePlace = hero.ePlace;
|
||||||
|
// this.jobStage = hero.jobStage;
|
||||||
|
// this.totalTalentPoint = gameData.talentPointOfJob.get(job) || 0;
|
||||||
|
// this.connections = hero.connections;
|
||||||
|
// this.talent = hero.talent || [];
|
||||||
|
// this.usedTalentPoint = hero.usedTalentPoint || 0;
|
||||||
|
// this.ce = hero.ce;
|
||||||
|
// }
|
||||||
|
// }
|
||||||
@@ -15,7 +15,7 @@ import { dicWar, dicWarPvp, dicDailyWarByType, loadWar, dicHeroIdByWar, dicComBa
|
|||||||
import { dicWarJson, loadWarJson } from "./dictionary/DicWarJson";
|
import { dicWarJson, loadWarJson } from "./dictionary/DicWarJson";
|
||||||
import { AUCTION_TIME, BOSS_HP_RATIO_TYPE } from "../consts";
|
import { AUCTION_TIME, BOSS_HP_RATIO_TYPE } from "../consts";
|
||||||
import { dicFashions, dicFashionsByHeroId, loadFashions } from "./dictionary/DicFashions";
|
import { dicFashions, dicFashionsByHeroId, loadFashions } from "./dictionary/DicFashions";
|
||||||
import { friendShips, friendShipsByLv, friendShipsMax, loadFriendShip } from "./dictionary/DicFriendShip";
|
import { friendShipByIndex, friendShips, friendShipsByLv, friendShipsMax, loadFriendShip } from "./dictionary/DicFriendShip";
|
||||||
import { dicHeroQualityUp, loadHeroQualityUp } from "./dictionary/DicHeroQualityUp";
|
import { dicHeroQualityUp, loadHeroQualityUp } from "./dictionary/DicHeroQualityUp";
|
||||||
import { dicHeroStar, loadHeroStar } from "./dictionary/DicHeroStar";
|
import { dicHeroStar, loadHeroStar } from "./dictionary/DicHeroStar";
|
||||||
import { dicHeroWake, loadHeroWake } from "./dictionary/DicHeroWake";
|
import { dicHeroWake, loadHeroWake } from "./dictionary/DicHeroWake";
|
||||||
@@ -174,6 +174,7 @@ import { dicRougeCharaCardPlan, loadRougeCharaCardPlan } from "./dictionary/DicR
|
|||||||
import { dicRougeHolyCardPlan, loadRougeHolyCardPlan } from "./dictionary/DicRougeHolyCardPlan";
|
import { dicRougeHolyCardPlan, loadRougeHolyCardPlan } from "./dictionary/DicRougeHolyCardPlan";
|
||||||
import { dicBossHpRatio, loadBossHpRatio } from "./dictionary/DicBossHpRatio";
|
import { dicBossHpRatio, loadBossHpRatio } from "./dictionary/DicBossHpRatio";
|
||||||
import { dicSpiritCompose, loadSpiritCompose } from "./dictionary/DicSpiritCompose";
|
import { dicSpiritCompose, loadSpiritCompose } from "./dictionary/DicSpiritCompose";
|
||||||
|
import { dicResonance, loadResonance } from "./dictionary/DicResonance";
|
||||||
|
|
||||||
export const gameData = {
|
export const gameData = {
|
||||||
daily: dicDaily,
|
daily: dicDaily,
|
||||||
@@ -207,6 +208,7 @@ export const gameData = {
|
|||||||
friendShips: friendShips,
|
friendShips: friendShips,
|
||||||
friendShipsByLv: friendShipsByLv,
|
friendShipsByLv: friendShipsByLv,
|
||||||
friendShipsMax: friendShipsMax,
|
friendShipsMax: friendShipsMax,
|
||||||
|
friendShipByIndex: friendShipByIndex,
|
||||||
randomEffectPool: dicRandomEffectPool,
|
randomEffectPool: dicRandomEffectPool,
|
||||||
randomEffectPoolByGroupAndLv: dicRandomEffectPoolByGroupAndLv,
|
randomEffectPoolByGroupAndLv: dicRandomEffectPoolByGroupAndLv,
|
||||||
title: dicTitle,
|
title: dicTitle,
|
||||||
@@ -436,6 +438,8 @@ export const gameData = {
|
|||||||
bossHpRatio: dicBossHpRatio,
|
bossHpRatio: dicBossHpRatio,
|
||||||
spiritCompose: dicSpiritCompose,
|
spiritCompose: dicSpiritCompose,
|
||||||
spiritByQuality: dicSpiritByQuality,
|
spiritByQuality: dicSpiritByQuality,
|
||||||
|
|
||||||
|
resonance: dicResonance,
|
||||||
};
|
};
|
||||||
|
|
||||||
// 在此提供一些原先在gamedata中提供的方法,以便更方便获取gameData数据
|
// 在此提供一些原先在gamedata中提供的方法,以便更方便获取gameData数据
|
||||||
@@ -1384,9 +1388,9 @@ export function getRougeEffectTypeKind(effectTypes: number[]) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export function getBossHpRatio(type: BOSS_HP_RATIO_TYPE, day: number) {
|
export function getBossHpRatio(type: BOSS_HP_RATIO_TYPE, day: number) {
|
||||||
let arr = gameData.bossHpRatio.get(type)||[];
|
let arr = gameData.bossHpRatio.get(type) || [];
|
||||||
let bossHpRatio = 1;
|
let bossHpRatio = 1;
|
||||||
for(let { serverOpen, ratio } of arr) {
|
for (let { serverOpen, ratio } of arr) {
|
||||||
bossHpRatio = ratio;
|
bossHpRatio = ratio;
|
||||||
if (serverOpen != -1 && serverOpen >= day) break;
|
if (serverOpen != -1 && serverOpen >= day) break;
|
||||||
}
|
}
|
||||||
@@ -1807,6 +1811,7 @@ function loadDatas(type?: string) {
|
|||||||
if (type == undefined || type == 'loadRougeTechLevel') loadRougeTechLevel();
|
if (type == undefined || type == 'loadRougeTechLevel') loadRougeTechLevel();
|
||||||
if (type == undefined || type == 'loadBossHpRatio') loadBossHpRatio();
|
if (type == undefined || type == 'loadBossHpRatio') loadBossHpRatio();
|
||||||
if (type == undefined || type == 'loadSpiritCompose') loadSpiritCompose();
|
if (type == undefined || type == 'loadSpiritCompose') loadSpiritCompose();
|
||||||
|
if (type == undefined || type == 'loadResonance') loadResonance();
|
||||||
|
|
||||||
console.log('loadDatas type: ', type || 'all');
|
console.log('loadDatas type: ', type || 'all');
|
||||||
|
|
||||||
|
|||||||
@@ -478,3 +478,10 @@ export const ROUGELIKE = {
|
|||||||
SELECT_HOLLYCARD_WEIGHT: 30, // 选择的圣物卡后该特性卡权重减少比例(%)
|
SELECT_HOLLYCARD_WEIGHT: 30, // 选择的圣物卡后该特性卡权重减少比例(%)
|
||||||
RANDOM_HOLLYCARD_WEIGHT: 10, // 随机出的圣物卡后该特性卡权重减少比例(%)
|
RANDOM_HOLLYCARD_WEIGHT: 10, // 随机出的圣物卡后该特性卡权重减少比例(%)
|
||||||
};
|
};
|
||||||
|
|
||||||
|
export const RESONANCE = {
|
||||||
|
START_MAIN_WARId: 301, //共鸣系统开启
|
||||||
|
HOSTER: 6, //鸣主
|
||||||
|
JEWEL: 1,// 共灵阵是否包括共灵天晶镶嵌(1:包括 0:不包括)
|
||||||
|
STONE: 1, // 共灵阵是否包括共灵地玉镶嵌(1:包括 0:不包括)
|
||||||
|
}
|
||||||
@@ -16,16 +16,21 @@ export interface DicFriendShip {
|
|||||||
// 羁绊武将ID
|
// 羁绊武将ID
|
||||||
readonly hids: Array<number>;
|
readonly hids: Array<number>;
|
||||||
// 属性加成
|
// 属性加成
|
||||||
readonly attributes: Array<{id: number, number: number}>
|
readonly attributes: Array<{ id: number, number: number }>
|
||||||
// 升到这一级所需的羁绊值
|
// 升到这一级所需的羁绊值
|
||||||
readonly shipExp: number;
|
readonly shipExp: number;
|
||||||
|
|
||||||
|
readonly index: number;
|
||||||
}
|
}
|
||||||
|
|
||||||
export const friendShips = new Map<string, { level: number, shipExp: number }[]>();
|
export const friendShips = new Map<string, { level: number, shipExp: number }[]>();
|
||||||
export const friendShipsByLv = new Map<string, DicFriendShip>();
|
export const friendShipsByLv = new Map<string, DicFriendShip>();
|
||||||
export const friendShipsMax = new Map<string, number>();
|
export const friendShipsMax = new Map<string, number>();
|
||||||
|
export const friendShipByIndex = new Map<string, number>();
|
||||||
export function loadFriendShip() {
|
export function loadFriendShip() {
|
||||||
friendShips.clear();
|
friendShips.clear();
|
||||||
|
friendShipByIndex.clear();
|
||||||
|
|
||||||
let arr = readFileAndParse(FILENAME.DIC_FRIEND_SHIP);
|
let arr = readFileAndParse(FILENAME.DIC_FRIEND_SHIP);
|
||||||
|
|
||||||
arr.forEach(o => {
|
arr.forEach(o => {
|
||||||
@@ -33,32 +38,35 @@ export function loadFriendShip() {
|
|||||||
o.hids = parseNumberList(o.memberId);
|
o.hids = parseNumberList(o.memberId);
|
||||||
let key1 = `${o.actorId}_${o.shipId}`;
|
let key1 = `${o.actorId}_${o.shipId}`;
|
||||||
let shipSumValue = 0;
|
let shipSumValue = 0;
|
||||||
if(!friendShips.has(key1)) {
|
if (!friendShips.has(key1)) {
|
||||||
friendShips.set(key1, []);
|
friendShips.set(key1, []);
|
||||||
shipSumValue = 0;
|
shipSumValue = 0;
|
||||||
}
|
}
|
||||||
shipSumValue += o.shipExp;
|
shipSumValue += o.shipExp;
|
||||||
friendShips.get(key1).push({ level: o.level, shipExp: shipSumValue });
|
friendShips.get(key1).push({ level: o.level, shipExp: shipSumValue });
|
||||||
|
|
||||||
if(!friendShipsMax.has(key1) || friendShipsMax.get(key1) < o.level) {
|
if (!friendShipsMax.has(key1) || friendShipsMax.get(key1) < o.level) {
|
||||||
friendShipsMax.set(key1, o.level);
|
friendShipsMax.set(key1, o.level);
|
||||||
}
|
}
|
||||||
|
|
||||||
let key2 = `${o.actorId}_${o.shipId}_${o.level}`;
|
let key2 = `${o.actorId}_${o.shipId}_${o.level}`;
|
||||||
friendShipsByLv.set(key2, o);
|
friendShipsByLv.set(key2, o);
|
||||||
|
|
||||||
|
let newKey = `${o.actorId}_${o.index}`;
|
||||||
|
if (!friendShipByIndex.has(newKey)) friendShipByIndex.set(newKey, o.shipId);
|
||||||
});
|
});
|
||||||
arr = undefined;
|
arr = undefined;
|
||||||
}
|
}
|
||||||
|
|
||||||
function parseAttribute(str: string) {
|
function parseAttribute(str: string) {
|
||||||
let result = new Array<{id: number, number: number}>();
|
let result = new Array<{ id: number, number: number }>();
|
||||||
if(!str) return result;
|
if (!str) return result;
|
||||||
let decodeArr = decodeArrayListStr(str);
|
let decodeArr = decodeArrayListStr(str);
|
||||||
for(let [id, number] of decodeArr) {
|
for (let [id, number] of decodeArr) {
|
||||||
if(isNaN(parseInt(id)) || isNaN(parseInt(number))) {
|
if (isNaN(parseInt(id)) || isNaN(parseInt(number))) {
|
||||||
throw new Error('data table format wrong');
|
throw new Error('data table format wrong');
|
||||||
}
|
}
|
||||||
result.push({id: parseInt(id), number: parseInt(number)});
|
result.push({ id: parseInt(id), number: parseInt(number) });
|
||||||
}
|
}
|
||||||
return result
|
return result
|
||||||
}
|
}
|
||||||
26
shared/pubUtils/dictionary/DicResonance.ts
Normal file
26
shared/pubUtils/dictionary/DicResonance.ts
Normal file
@@ -0,0 +1,26 @@
|
|||||||
|
|
||||||
|
import { parseGoodStr, readFileAndParse } from '../util'
|
||||||
|
import { FILENAME } from '../../consts'
|
||||||
|
import { RewardInter } from '../interface';
|
||||||
|
|
||||||
|
export interface DicResonance {
|
||||||
|
readonly id: number;
|
||||||
|
readonly name: string;
|
||||||
|
readonly openLimit: number;
|
||||||
|
readonly openConsume: RewardInter[];
|
||||||
|
}
|
||||||
|
export const dicResonance = new Map<number, DicResonance>();
|
||||||
|
|
||||||
|
export function loadResonance() {
|
||||||
|
dicResonance.clear();
|
||||||
|
|
||||||
|
let arr = readFileAndParse(FILENAME.DIC_RESONANCE);
|
||||||
|
|
||||||
|
arr.forEach(o => {
|
||||||
|
|
||||||
|
o.openConsume = parseGoodStr(o.openConsume);
|
||||||
|
dicResonance.set(o.id, o);
|
||||||
|
|
||||||
|
});
|
||||||
|
arr = undefined;
|
||||||
|
}
|
||||||
@@ -1,5 +1,6 @@
|
|||||||
// 一些通用的interface定义
|
// 一些通用的interface定义
|
||||||
|
|
||||||
|
import { ResonanceConnection, ResonanceEplace, ResonanceTalent } from "../db/Resonance";
|
||||||
import { RougelikeCardPara } from "../db/RougelikeCard";
|
import { RougelikeCardPara } from "../db/RougelikeCard";
|
||||||
import { RougelikeCharaPara } from "../db/RougelikeChara";
|
import { RougelikeCharaPara } from "../db/RougelikeChara";
|
||||||
import { RougelikeCollectionType } from "../db/RougelikeCollection";
|
import { RougelikeCollectionType } from "../db/RougelikeCollection";
|
||||||
@@ -207,3 +208,18 @@ export interface SlotCard {
|
|||||||
index: number; //卡槽标记
|
index: number; //卡槽标记
|
||||||
cardCode: string; //安装的特性卡唯一code
|
cardCode: string; //安装的特性卡唯一code
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export interface ReturnResonanceParam {
|
||||||
|
positon: number; // 上阵位置,从1开始(6为鸣主配系统参数表),已解锁未上阵仅有positon
|
||||||
|
hid?: number; // 武将id
|
||||||
|
seqId?: number; // 武将表自增 id
|
||||||
|
lv?: number; //武将等级
|
||||||
|
exp?: number;
|
||||||
|
jobStage?: number; // 职阶
|
||||||
|
talent?: ResonanceTalent[]; // 天赋
|
||||||
|
usedTalentPoint?: number;
|
||||||
|
totalTalentPoint?: number;
|
||||||
|
connections?: ResonanceConnection[]; // 羁绊
|
||||||
|
ePlace?: ResonanceEplace[];
|
||||||
|
ce?: number; //战力
|
||||||
|
}
|
||||||
122
shared/resource/jsons/dic_zyz_resonance.json
Normal file
122
shared/resource/jsons/dic_zyz_resonance.json
Normal file
@@ -0,0 +1,122 @@
|
|||||||
|
[
|
||||||
|
{
|
||||||
|
"id": 1,
|
||||||
|
"name": "共鸣阵1",
|
||||||
|
"openLimit": 60,
|
||||||
|
"openConsume": "31002&50"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": 2,
|
||||||
|
"name": "共鸣阵2",
|
||||||
|
"openLimit": 61,
|
||||||
|
"openConsume": "31002&50"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": 3,
|
||||||
|
"name": "共鸣阵3",
|
||||||
|
"openLimit": 62,
|
||||||
|
"openConsume": "31002&50"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": 4,
|
||||||
|
"name": "共鸣阵4",
|
||||||
|
"openLimit": 63,
|
||||||
|
"openConsume": "31002&50"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": 5,
|
||||||
|
"name": "共鸣阵5",
|
||||||
|
"openLimit": 64,
|
||||||
|
"openConsume": "31002&50"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": 6,
|
||||||
|
"name": "共鸣阵6",
|
||||||
|
"openLimit": 65,
|
||||||
|
"openConsume": "31002&50"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": 7,
|
||||||
|
"name": "共鸣阵7",
|
||||||
|
"openLimit": 66,
|
||||||
|
"openConsume": "31002&50"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": 8,
|
||||||
|
"name": "共鸣阵8",
|
||||||
|
"openLimit": 67,
|
||||||
|
"openConsume": "31002&50"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": 9,
|
||||||
|
"name": "共鸣阵9",
|
||||||
|
"openLimit": 68,
|
||||||
|
"openConsume": "31002&50"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": 10,
|
||||||
|
"name": "共鸣阵10",
|
||||||
|
"openLimit": 69,
|
||||||
|
"openConsume": "31002&50"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": 11,
|
||||||
|
"name": "共鸣阵11",
|
||||||
|
"openLimit": 70,
|
||||||
|
"openConsume": "31002&50"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": 12,
|
||||||
|
"name": "共鸣阵12",
|
||||||
|
"openLimit": 71,
|
||||||
|
"openConsume": "31002&50"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": 13,
|
||||||
|
"name": "共鸣阵13",
|
||||||
|
"openLimit": 72,
|
||||||
|
"openConsume": "31002&50"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": 14,
|
||||||
|
"name": "共鸣阵14",
|
||||||
|
"openLimit": 73,
|
||||||
|
"openConsume": "31002&50"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": 15,
|
||||||
|
"name": "共鸣阵15",
|
||||||
|
"openLimit": 74,
|
||||||
|
"openConsume": "31002&50"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": 16,
|
||||||
|
"name": "共鸣阵16",
|
||||||
|
"openLimit": 75,
|
||||||
|
"openConsume": "31002&50"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": 17,
|
||||||
|
"name": "共鸣阵17",
|
||||||
|
"openLimit": 76,
|
||||||
|
"openConsume": "31002&50"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": 18,
|
||||||
|
"name": "共鸣阵18",
|
||||||
|
"openLimit": 77,
|
||||||
|
"openConsume": "31002&50"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": 19,
|
||||||
|
"name": "共鸣阵19",
|
||||||
|
"openLimit": 78,
|
||||||
|
"openConsume": "31002&50"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": 20,
|
||||||
|
"name": "共鸣阵20",
|
||||||
|
"openLimit": 79,
|
||||||
|
"openConsume": "31002&50"
|
||||||
|
}
|
||||||
|
]
|
||||||
Reference in New Issue
Block a user