diff --git a/game-server/app/servers/battle/handler/pvpHandler.ts b/game-server/app/servers/battle/handler/pvpHandler.ts index 9235b2c50..0cdd86ac4 100644 --- a/game-server/app/servers/battle/handler/pvpHandler.ts +++ b/game-server/app/servers/battle/handler/pvpHandler.ts @@ -2,11 +2,11 @@ import { Application, BackendSession, pinus, HandlerService, } from 'pinus'; import { uniq, findWhere, findIndex } from 'underscore'; import { gameData, getPvpBoxs, getPLvByScore } from '../../../pubUtils/data'; -import { refreshEnemies, getEnemies, getLvByScore, defaultHeroes, comsumeChallengeCnt, refresh, findPvpDefByRoleId, getRefOppCnt, findPvpDefAllByRoleId, generPVPOppRecInfo, generMyRecInfo, initPvpInfo } from '../../../services/pvpService'; +import { refreshEnemies, getEnemies, getLvByScore, comsumeChallengeCnt, refChallengeCnt, generPVPOppRecInfo, generMyRecInfo, sendLastSeasonRewardIfNotSent, refreshRefOppCnt } from '../../../services/pvpService'; import { RoleModel, RoleType } from '../../../db/Role'; import { STATUS } from '../../../consts/statusCode'; import { resResult, genCode, checkRoleIsRobot, robotIdComBack } from '../../../pubUtils/util'; -import { PvpDefenseModel, OppPlayers } from '../../../db/PvpDefense'; +import { PvpDefenseModel, pvpUpdateInter } from '../../../db/PvpDefense'; import { pvpEndParamInter } from '../../../pubUtils/interface'; import { PlayerDetail, PlayerDetailHero } from '../../../domain/battleField/guild'; import { PVP_HERO_POS, PVP_HERO_ORDER, REDIS_KEY, LINEUP_NUM, TASK_TYPE, COUNTER } from '../../../consts'; @@ -18,12 +18,12 @@ import { BattleRecordModel } from '../../../db/BattleRecord'; import { PvpRecordModel } from '../../../db/PvpRecord'; import { handleCost } from '../../../services/rewardService'; import { nowSeconds, getSeconds } from '../../../pubUtils/timeUtil'; -import { pvpSeasonEnd, resetPvpWarId, createNextPvpSeason } from '../../../services/timeTaskService'; import { PvpSeasonResultModel } from '../../../db/PvpSeasonResult'; import { PvpHistoryOppModel, PvpHistoryOppType } from '../../../db/PvpHistoryOpp'; import { PVPConfigModel } from '../../../db/SystemConfig'; import { Rank } from '../../../services/rankService'; import { checkActivityTask, checkTask, checkTaskInPvpEnd } from '../../../services/taskService'; +import { PvpDataReturn } from '../../../domain/battleField/pvp'; export default function (app: Application) { new HandlerService(app, {}); @@ -37,48 +37,62 @@ export class PvpHandler { //1获取主界面 async getData(msg: {}, session: BackendSession) { let roleId = session.get('roleId'); - let { pvpDefense, warId, seasonEndTime } = await findPvpDefAllByRoleId(roleId); + + let pvpDefense = await PvpDefenseModel.findByRoleIdIncludeAll(roleId); if(!pvpDefense) { let role = await RoleModel.findByRoleId(roleId); - pvpDefense = await initPvpInfo(role); + pvpDefense = await PvpDefenseModel.createPvpDefense({ roleId: role.roleId, roleName: role.roleName, role: role._id }); } - let oppPlayers = await getEnemies(pvpDefense.oppPlayers, pvpDefense.winStreakNum); - let { isDefaultHero, heroes, score, pLv, winStreakNum, refOppCnt, challengeCnt, challengeRefTime, receivedBox, hisScore, heroScores, isFirstEntry, seasonNum } = pvpDefense; - if (isFirstEntry) { - await PvpDefenseModel.updateInfo(roleId, { isFirstEntry: false }); + pvpDefense = await sendLastSeasonRewardIfNotSent(pvpDefense); + let { seasonNum, seasonEndTime } = await PVPConfigModel.findCurPVPConfig(); + + + let refChallengeObj = refChallengeCnt(pvpDefense.challengeCnt, pvpDefense.challengeRefTime, seasonEndTime); + let refOppObj = refreshRefOppCnt(pvpDefense.refOppCnt, pvpDefense.refDaily); + + let update: pvpUpdateInter = { ...refChallengeObj, ...refOppObj}; + + let result = new PvpDataReturn(pvpDefense); // 返回对象 + + if(refOppObj.shouldRefOpp) { + let role = pvpDefense.role; + let oppPlayers = await refreshEnemies(role, seasonNum, pvpDefense.score, pvpDefense.attack.pLv); + update.oppPlayers = oppPlayers; + let oppPlayersReturn = await getEnemies(oppPlayers||[], pvpDefense.winStreakNum); + result.setOppPlayers(oppPlayersReturn); + } else { + let oppPlayersReturn = await getEnemies(pvpDefense.oppPlayers||[], pvpDefense.winStreakNum); + result.setOppPlayers(oppPlayersReturn); } - let pvpSeasonResult = await PvpSeasonResultModel.getPvpSeasonResult(roleId); - let flag = false; - if (!!pvpSeasonResult) { - var { oldSeasonData, show, heroGoods, rankGoods } = pvpSeasonResult; - if (oldSeasonData.seasonEndTime > nowSeconds()) {//结算中锁定玩家信息,结算结束后统一展示修改完成的信息 - seasonEndTime = oldSeasonData.seasonEndTime; - heroScores = oldSeasonData.heroScores; - score = oldSeasonData.score; - refOppCnt = oldSeasonData.refOppCnt; - challengeCnt = oldSeasonData.challengeCnt; - challengeRefTime = oldSeasonData.challengeRefTime; - } else if (show) {//是否需要弹出结算奖励界面 - await PvpSeasonResultModel.updatePvpSeasonResult(roleId, { show: false }); - flag = true; - } + + let { score, winStreakNum, refOppCnt, challengeCnt, challengeRefTime, receivedBox, hisScore, heroScores, isFirstEntry } = pvpDefense; + if (pvpDefense.isFirstEntry) { + update.isFirstEntry = false; + } + let pvpSeasonResult = await PvpSeasonResultModel.getPvpSeasonResult(roleId, pvpDefense.seasonNum); + + result.setPvpConfig(seasonNum, seasonEndTime); + + if (!!pvpSeasonResult && !!pvpSeasonResult.show) { + result.setPvpSeasonResult(pvpSeasonResult); + await PvpSeasonResultModel.updatePvpSeasonResult(roleId, pvpSeasonResult.seasonNum, { show: false }); } let r = new Rank(REDIS_KEY.PVP_RANK, {}); let myRank = await r.getMyRank({ roleId });//去redis中获取排名 + result.setMyRank(myRank); - let data: any = { - warId, seasonNum, seasonEndTime, myRank, oppPlayers, heroes: heroes.map(cur => { - let { actorId, dataId, order } = cur; - return { actorId, dataId, order } - }), score, pLv, winStreakNum, refOppCnt, challengeCnt, challengeRefTime, receivedBox, hisScore, heroScores, isFirstEntry, isDefaultHero - } - if (flag) {//弹出结赛季结算奖励 - data.resultRecord = { oldSeasonData, heroGoods, rankGoods } - } - return resResult(STATUS.SUCCESS, data); + // let data: any = { + // warId, seasonNum, seasonEndTime, myRank, oppPlayers, heroes: heroes.map(cur => { + // let { actorId, dataId, order } = cur; + // return { actorId, dataId, order } + // }), score, pLv, winStreakNum, refOppCnt, challengeCnt, challengeRefTime, receivedBox, hisScore, heroScores, isFirstEntry, isDefaultHero + // } + + return resResult(STATUS.SUCCESS, result); } + /* // 刷新对手 async refreshOppPlayer(msg: {}, session: BackendSession) { let roleId = session.get('roleId'); @@ -140,7 +154,7 @@ export class PvpHandler { if (!pvpDefense) return resResult(STATUS.PVP_NOT_OPEN); // 检查挑战次数 let { seasonEndTime } = await PVPConfigModel.findCurPVPConfig(); - let { challengeCnt, challengeRefTime } = refresh(pvpDefense.challengeCnt, pvpDefense.challengeRefTime, seasonEndTime); + let { challengeCnt, challengeRefTime } = refChallengeCnt(pvpDefense.challengeCnt, pvpDefense.challengeRefTime, seasonEndTime); if (challengeCnt == 0) { return resResult(STATUS.PVP_CHALLENGE_TIMES_NOT_ENOUGH); } @@ -273,7 +287,7 @@ export class PvpHandler { let { seasonEndTime } = await PVPConfigModel.findCurPVPConfig(); let { heroes: defHeros, challengeCnt: lastChallengeCnt, challengeRefTime: lastChallengeRefTime } = await PvpDefenseModel.findByRoleId(roleId); let defCe = 0; - let { challengeCnt, challengeRefTime } = refresh(lastChallengeCnt, lastChallengeRefTime, seasonEndTime); + let { challengeCnt, challengeRefTime } = refChallengeCnt(lastChallengeCnt, lastChallengeRefTime, seasonEndTime); if (!!isDefaultHero) { let { topLineup } = await RoleModel.findByRoleId(roleId); @@ -430,7 +444,7 @@ export class PvpHandler { return resResult(STATUS.PVP_BOX_IS_GOT); } receivedBox.push(id); - let { challengeCnt, challengeRefTime } = refresh(lastChallengeCnt, lastChallengeRefTime, seasonEndTime); + let { challengeCnt, challengeRefTime } = refChallengeCnt(lastChallengeCnt, lastChallengeRefTime, seasonEndTime); await PvpDefenseModel.updateInfo(roleId, { receivedBox, challengeCnt, challengeRefTime }); let result = await addItems(roleId, roleName, sid, pvpBox.reward); // 任务 @@ -514,4 +528,6 @@ export class PvpHandler { let { challengeRefTime } = await PvpDefenseModel.updateInfoAndInclude(roleId, { challengeCnt, challengeRefTime: nowSeconds(), refOppCnt: 0 }); return resResult(STATUS.SUCCESS, { challengeCnt, challengeRefTime }); } + + */ } diff --git a/game-server/app/servers/systimer/remote/systimerRemote.ts b/game-server/app/servers/systimer/remote/systimerRemote.ts index f5dddd54d..854669712 100644 --- a/game-server/app/servers/systimer/remote/systimerRemote.ts +++ b/game-server/app/servers/systimer/remote/systimerRemote.ts @@ -1,5 +1,5 @@ import { Application, ChannelService } from 'pinus'; -import { resetPvpSeasonTime, setPvpDefResult, guildActivityStart, gateActivityEnd, cityActivityEnd, raceActivityEnd, guildActivitySchedule, auctionSchedule } from '../../../services/timeTaskService'; +import { resetPvpSeasonTime, guildActivityStart, gateActivityEnd, cityActivityEnd, raceActivityEnd, guildActivitySchedule, auctionSchedule } from '../../../services/timeTaskService'; import PvpDefenseType from '../../../db/PvpDefense'; import { DicGuildActivity } from '../../../pubUtils/dictionary/DicGuildActivity'; import { reloadResources } from '../../../pubUtils/data'; @@ -23,10 +23,6 @@ export class SystimerRemote { return await resetPvpSeasonTime(day); } - public async setPvpDefResult(pvpDefense: PvpDefenseType, seasonNum: number, seasonEndTime:number) { - return await setPvpDefResult(pvpDefense, seasonNum, seasonEndTime); - } - public async guildActivityStart(dicGuildActivity: DicGuildActivity) { return await guildActivityStart(dicGuildActivity); } diff --git a/game-server/app/services/connectorService.ts b/game-server/app/services/connectorService.ts index f95cdaedb..730f0472d 100644 --- a/game-server/app/services/connectorService.ts +++ b/game-server/app/services/connectorService.ts @@ -35,7 +35,6 @@ import { setMedianCe, getAllGuildActivityStatus } from './guildActivityService'; import { getAllOnlineRoles } from './redisService'; import Item from '../db/Item'; import { PvpDefenseModel } from '../db/PvpDefense'; -import { findPvpDefAllByRoleId } from './pvpService'; import { getDonation } from './donateService'; export async function pushData(role: RoleType, session: FrontendOrBackendSession, pushType: 'entry' | 'refresh' = 'entry') { @@ -189,10 +188,10 @@ async function getTowerEntryData(role: RoleType) { async function getPvpEntryData(roleId: string) { let pvpDefense = await PvpDefenseModel.findByRoleIdIncludeAll(roleId); if (pvpDefense) { - let { pvpDefense, } = await findPvpDefAllByRoleId(roleId); - let { challengeCnt, receivedBox, score, hisScore } = pvpDefense; + // let { pvpDefense, } = await findPvpDefAllByRoleId(roleId); + // let { challengeCnt, receivedBox, score, hisScore } = pvpDefense; - return { challengeCnt, score, hisScore, receivedBox } + // return { challengeCnt, score, hisScore, receivedBox } } else { return null } diff --git a/game-server/app/services/expeditionService.ts b/game-server/app/services/expeditionService.ts index 3bfcd2e41..b047aa4cd 100644 --- a/game-server/app/services/expeditionService.ts +++ b/game-server/app/services/expeditionService.ts @@ -1,17 +1,14 @@ import { ExpeditionPointModel } from '../db/ExpeditionPoint'; -import Role, { RoleModel, RoleType } from '../db/Role'; -import { PvpDefenseModel } from '../db/PvpDefense'; - +import Role, { CeAttrDataRole, RoleModel } from '../db/Role'; import { shouldRefresh, calculateSumCE, getRandSingleEelm } from '../pubUtils/util'; -import { LINEUP_NUM, EXPEDITION_WAR_RECORD_STATUS, ABI_TYPE } from '../consts'; +import { LINEUP_NUM, EXPEDITION_WAR_RECORD_STATUS } from '../consts'; import { ExpeditionWarRecordModel } from '../db/ExpeditionWarRecord'; -import { HeroType } from '../db/Hero'; +import { CeAttrData, HeroType } from '../db/Hero'; import { gameData } from '../pubUtils/data'; -import { getPlayerAttribute, getRobotAttribute } from './pvpService'; import { getTimeFunD } from '../pubUtils/timeUtil'; import { ExpeditionRecordModel } from '../db/ExpeditionRecord'; -import { Attribute } from '../domain/roleField/attribute'; +import { Attribute, AttributeCal } from '../domain/roleField/attribute'; import * as dicParam from '../pubUtils/dicParam'; /** @@ -80,7 +77,7 @@ export async function findOrCreateEnemies(roleId: string, myCe: number, expediti }; // 获取系数和步长 - let {scale, range, lv} = await getCEScaleAndRange(roleId, curDicExpedition); + let { scale, range, lv } = await getCEScaleAndRange(roleId, curDicExpedition); // 优先匹配其他玩家 let flag = await matchPlayers(roleId, scale, range, myCe, curDicExpedition.json, enemyObj); // 当数量不够时使用机器人匹配 @@ -133,30 +130,30 @@ export async function matchPlayers(roleId: string, scale: number, range: number, let min = myCe * scale * (1 - range/100); let max = myCe * scale * (1 + range/100); - let resultRange = await PvpDefenseModel.findByScale(roleId, min, max); + let resultRange = await RoleModel.findByCeScale(min, max); + resultRange = resultRange.filter(cur => cur.roleId != roleId); if(resultRange.length > 0) { let index = Math.floor(Math.random() * resultRange.length); - let result = resultRange[index]; - let {roleId, heroes, defCe } = result; - let role = result.role; + let role = resultRange[index]; + let {roleId, topLineup, topLineupCe } = role; let { attr: roleAttrs } = role; enemyObj.enemyFrom = 1; enemyObj.enemyId = roleId; - enemyObj.ce = defCe; + enemyObj.ce = topLineupCe; let heroIndex = 0; for(let json of dicWarJson) { if(json.relation == 2) { - let hero = heroes[heroIndex]; + let hero = topLineup[heroIndex]; if(hero) { let h = hero.hero; if(h) { let { star, lv, attr: heroAttrs, ce } = h; - let dicHero = gameData.hero.get(hero.actorId); + let dicHero = gameData.hero.get(hero.hid); let { attribute } = getPlayerAttribute(lv, heroAttrs, roleAttrs); let heroInfo = { - actorId: hero.actorId, + actorId: hero.hid, skinId: h.skinId, actorName: dicHero.name, skill:0, @@ -269,4 +266,46 @@ export async function getResetRemainCnt(curTime: Date, roleId: string, role?: Ro resetCnt: maxCnt - expeditionResetCnt, needRefresh }; +} + +/** + * 根据比例计算机器人属性 + * @param attribute 出兵表中的属性字段 + * @param ce 我的战力 + * @param enemyCe 出兵表对手战力 + * @param ratio 系数 + */ + export function getRobotAttribute(mainAttrs: { id: number, val: number }[], enemyCount: number, subAttrs: {id: number, val: number}[], lv: number, ce: number, enemyCe: number, ratio: number) { + + let newAttribute = new AttributeCal(); + newAttribute.setLv(lv); + newAttribute.setByWarJson(subAttrs); // 次级属性 + let subAttrCe = newAttribute.calSubAttrCeAndReduce() * enemyCount; + if(ce * ratio > subAttrCe) { + let mainAttrCe = ce * ratio - subAttrCe; + newAttribute.setByWarJson(mainAttrs, mainAttrCe / enemyCe); + let attrArr = newAttribute.getReduceAttributesToString(); + let newCe = newAttribute.calCelAndReduce(); + return { attribute: attrArr, ce: newCe }; + } else { + newAttribute = new AttributeCal(); + newAttribute.setByWarJson(mainAttrs, ce * ratio / enemyCe); + let attrArr = newAttribute.getReduceAttributesToString(); + let newCe = newAttribute.calCelAndReduce(); + return { attribute: attrArr, ce: newCe }; + } +} + +/** + * @description 根据玩家数据获取到他的属性 + * @param ceAttr hero表的ceAttr + * @param globalCeAttr role表中的globalCeAttr + */ +export function getPlayerAttribute(lv: number, heroAttrs: CeAttrData[] = [], roleAttrs: CeAttrDataRole[] = []) { + let newAttribute = new AttributeCal(); + newAttribute.setLv(lv); + newAttribute.setByDbData(roleAttrs, heroAttrs); + let attribute = newAttribute.getReduceAttributesToString(); + let ce = newAttribute.calCelAndReduce(); + return { attribute, ce }; } \ No newline at end of file diff --git a/game-server/app/services/guildService.ts b/game-server/app/services/guildService.ts index a935766f1..dafa45533 100644 --- a/game-server/app/services/guildService.ts +++ b/game-server/app/services/guildService.ts @@ -316,7 +316,6 @@ export async function settleGuildWeekly() { await initSingleRank(REDIS_KEY.GUILD_ACTIVE_RANK); await initSingleRank(REDIS_KEY.GUILD_LV_RANK); let curSeasonNum = await CounterModel.getCounter(COUNTER.PVP_SEASON_NUM); - await PVPConfigModel.updatePVPConfig(curSeasonNum, { settleGuildWeeklyTime: nowSeconds() }); // 记录一下,不知道原作者有什么用处... console.log('————— settleGuildWeekly结束 —————'); } diff --git a/game-server/app/services/playerCeService.ts b/game-server/app/services/playerCeService.ts index de585f4c0..aaffd5cd2 100644 --- a/game-server/app/services/playerCeService.ts +++ b/game-server/app/services/playerCeService.ts @@ -8,7 +8,6 @@ import { STATUS } from '../consts/statusCode'; import { resResult, reduceCe } from '../pubUtils/util'; import { calPlayerCeAndSave as pubCalPlayerCeAndSave, reCalAllHeroCe } from '../pubUtils/playerCe'; import { HeroType, HeroUpdate } from '../db/Hero'; -import { defaultHeroes } from './pvpService'; import { RoleUpdate, RoleType } from '../db/Role'; import { Rank } from './rankService'; @@ -39,7 +38,6 @@ export async function pushCalPlayerCe(roleId: string, sid: string, calResult: ca //下发战力 let uids = [{ uid: roleId, sid }]; pinus.app.get('channelService').pushMessageByUids('onPlayerCeUpdate', resResult(STATUS.SUCCESS, { ce: reduceCe(role.ce) , heros: pushHeros, topLineupCe: reduceCe(topLineupCe) }), uids); - defaultHeroes(role); if(guild) { await updateUserInfo(REDIS_KEY.GUILD_INFO, guild.code, [{ field: 'guildCe', value: guild.guildCe }]); } diff --git a/game-server/app/services/playerEventService.ts b/game-server/app/services/playerEventService.ts index eb614693e..34cb55fd3 100644 --- a/game-server/app/services/playerEventService.ts +++ b/game-server/app/services/playerEventService.ts @@ -1,5 +1,4 @@ -import { findPvpDefByRoleId } from '../services/pvpService' import { getFuncsSwitch, gameData } from '../pubUtils/data'; import { FUNCS_ID, FUNC_OPT_TYPE } from '../consts/constModules/sysConst'; import { RoleModel } from '../db/Role'; @@ -22,8 +21,4 @@ export async function eventOnPlayerLvUp(roleId: string, lv: number, addFuncs: Ar } } -} - -export async function loginRefresh(roleId: string) { - await findPvpDefByRoleId(roleId); } \ No newline at end of file diff --git a/game-server/app/services/pvpService.ts b/game-server/app/services/pvpService.ts index ea10eb2df..e9d7dffc2 100644 --- a/game-server/app/services/pvpService.ts +++ b/game-server/app/services/pvpService.ts @@ -1,14 +1,14 @@ -import { PvpDefenseModel, Heroes, OppPlayers, PvpDefenseType, HeroScores, pvpUpdateInter } from '../db/PvpDefense'; +import { PvpDefenseModel, PvpDefenseType, pvpUpdateInter } from '../db/PvpDefense'; +import { Defense, Attack, LineupCe, OppPlayer, HeroScore, HeroReward, OppPlayerReturn } from '../domain/battleField/pvp'; import { RoleType, CeAttrDataRole } from '../db/Role'; -import { PVP_HERO_POS, REDIS_KEY, PVP_CONST, COUNTER } from '../consts'; -import { setPvpDefResult } from '../services/timeTaskService'; +import { PVP_HERO_POS, REDIS_KEY, PVP_CONST, COUNTER, TASK_TYPE, MAIL_TYPE } from '../consts'; import { dicPvpOpponent, DicPvpOpponent } from "../pubUtils/dictionary/DicPvpOpponent"; -import { getRandSingleIndex, genCode, shouldRefresh, getChineseName, makeRobotId, robotIdComBack } from '../pubUtils/util'; -import { oppPlayersInter, pvpEndParamInter } from '../pubUtils/interface'; -import { gameData, getPLvByScore } from "../pubUtils/data"; +import { getRandSingleIndex, genCode, shouldRefresh, getChineseName, makeRobotId, robotIdComBack, getRandSingleEelm } from '../pubUtils/util'; +import { pvpEndParamInter, RewardInter } from '../pubUtils/interface'; +import { gameData, getPLvByScore, getPvpHeroRewardsByScore, getPvpRankRewardsByRank } from "../pubUtils/data"; import { PVP } from '../pubUtils/dicParam'; -import { PVPConfigModel } from '../db/SystemConfig' +import { PVPConfigModel, PVPConfigType } from '../db/SystemConfig' import { nowSeconds, getTimeFun } from '../pubUtils/timeUtil'; import { HeroesRecord } from '../db/PvpRecord'; import { HeroModel, CeAttrData } from '../db/Hero'; @@ -20,50 +20,10 @@ import { pinus } from 'pinus'; import { PvpHistoryOppModel, PvpHistoryOppType } from '../db/PvpHistoryOpp'; import { Rank } from './rankService'; import { CounterModel } from '../db/Counter'; - -export async function getPvpData() { - -} - - -export async function initPvpInfo(role: RoleType) { - let heroes: Array = []; - //初始化最强5人阵容 - let defCe = 0; - for (let i = PVP_HERO_POS.START; i <= PVP_HERO_POS.END; i++) { - let index = i - PVP_HERO_POS.START; - let item = role.topLineup[index]; - if (item) defCe += item.ce; - heroes.push({ - actorId: item?.hid || 0, - hero: item?.hero || null, - ce: item?.ce || 0, - dataId: i, - order: index + 1, - }); - } - //初始化对手人阵容 - let oppPlayers: Array = await refreshEnemies(role, 0, 1); - let { seasonNum } = await PVPConfigModel.findCurPVPConfig(); - let challengeCnt = PVP.PVP_CHALLENGE_COUNTS; - let result = await PvpDefenseModel.createPvpDefenseAndPopulate({ roleId: role.roleId, roleName: role.roleName, role: role._id, heroes, oppPlayers, defCe, seasonNum, challengeCnt }); - - //加入排行榜 - let r = new Rank(REDIS_KEY.PVP_RANK, {}); - await r.setRankWithRoleInfo(REDIS_KEY.PVP_RANK, result.score, result.updatedAt.getTime(), role, false); - - return result; -} - -export async function checkPvp(role: RoleType) { - if (role.hasInit) { - let result = await PvpDefenseModel.findByRoleId(role.roleId, true); - if (!!result) - return result; - result = await initPvpInfo(role); - return result; - } -} +import { DicRankRewads } from '../pubUtils/dictionary/DicPvpRankReward'; +import { PvpSeasonResultModel } from '../db/PvpSeasonResult'; +import { checkTask } from '../services/taskService'; +import { sendMailByContent } from './mailService'; /** * 返回对手三人信息 @@ -71,9 +31,9 @@ export async function checkPvp(role: RoleType) { * @param oppPlayers pvpDefense表中的oppPlayers字段,需要populate过的 * @param pLv 玩家本人的队伍等级 */ -export async function getEnemies(oppPlayers: OppPlayers[], winStreakNum: number) { +export async function getEnemies(oppPlayers: OppPlayer[], winStreakNum: number) { - let result = new Array(); + let result = new Array(); for (let oppPlayer of oppPlayers) { let dicOpponent = dicPvpOpponent.get(oppPlayer.pos); let oppDef = oppPlayer.oppDef; // select 'oppRoleId pos roleName head frame spine rankLv pLv defCe' @@ -96,21 +56,18 @@ export async function getEnemies(oppPlayers: OppPlayers[], winStreakNum: number) * @param score 我的军功 * @param pLv 我的排名 */ -export async function refreshEnemies(role: RoleType, score: number, pLv: number) { - let system = await PVPConfigModel.findCurPVPConfig(); - let mapWarJson = gameData.warJson.get(system.warId); - +export async function refreshEnemies(role: RoleType, seasonNum: number, score: number, pLv: number) { let { roleId } = role; - let oppPlayers = new Array(); + let oppPlayers: OppPlayer[] = []; let opp = dicPvpOpponent.values() for (let dicOpp of opp) { let flag = false; // 是否筛选成功 if (score >= PVP_CONST.SCORE_LINE) { // 将这个放到const - flag = await matchPlayer(system.seasonNum, oppPlayers, mapWarJson, roleId, pLv, dicOpp); // 按照等级匹配对手 - if (!flag) flag = await matchPlayerByRank(system.seasonNum, oppPlayers, mapWarJson, roleId, dicOpp.id); // 当前后分数段没有时,返回前一名的玩家 - if (!flag) flag = await matchRobot(oppPlayers, mapWarJson, role, pLv, dicOpp); + flag = await matchPlayer(seasonNum, oppPlayers, roleId, pLv, dicOpp); // 按照等级匹配对手 + if (!flag) flag = await matchPlayerByRank(seasonNum, oppPlayers, roleId, dicOpp.id); // 当前后分数段没有时,返回前一名的玩家 + if (!flag) flag = await matchRobot(oppPlayers, role, pLv, dicOpp); } else { - flag = await matchRobot(oppPlayers, mapWarJson, role, pLv, dicOpp); + flag = await matchRobot(oppPlayers, role, pLv, dicOpp); } if (!flag) continue; } @@ -118,7 +75,7 @@ export async function refreshEnemies(role: RoleType, score: number, pLv: number) return oppPlayers; } -export async function matchPlayerByRank(seasonNum: number, oppPlayers: OppPlayers[], mapWarJson: DicWarJson[], roleId: string, pos: number) { +export async function matchPlayerByRank(seasonNum: number, oppPlayers: OppPlayer[], roleId: string, pos: number) { // console.log('matchPlayerByRank', JSON.stringify(oppPlayers)) let r = new Rank(REDIS_KEY.PVP_RANK, {}); let ridRanks = new Array(); // 已经被使用了的排名 @@ -172,7 +129,7 @@ export async function matchPlayerByRank(seasonNum: number, oppPlayers: OppPlayer let pvpdefense = await PvpDefenseModel.findByRoleIdIncludeAll(oppRoleId); if (!pvpdefense || pvpdefense.seasonNum != seasonNum) return false; - let pvpHistoryOpp = await generPlayerOppHis(pvpdefense, mapWarJson, roleId, pos); + let pvpHistoryOpp = await generPlayerOppHis(pvpdefense, roleId, pos); if (!pvpHistoryOpp) return false; oppPlayers.push({ @@ -184,7 +141,7 @@ export async function matchPlayerByRank(seasonNum: number, oppPlayers: OppPlayer return true } -async function matchPlayer(seasonNum: number, oppPlayers: OppPlayers[], mapWarJson: DicWarJson[], roleId: string, pLv: number, dicOpp: DicPvpOpponent) { +async function matchPlayer(seasonNum: number, oppPlayers: OppPlayer[], roleId: string, pLv: number, dicOpp: DicPvpOpponent) { // console.log('matchPlayer', JSON.stringify(oppPlayers)) let { id: pos, minLv, maxLv } = dicOpp @@ -203,7 +160,7 @@ async function matchPlayer(seasonNum: number, oppPlayers: OppPlayers[], mapWarJs index = getRandSingleIndex(range.length); result = range[index]; } - let pvpHistoryOpp = await generPlayerOppHis(result, mapWarJson, roleId, pos); + let pvpHistoryOpp = await generPlayerOppHis(result, roleId, pos); if (!pvpHistoryOpp) return false; oppPlayers.push({ roleId: pvpHistoryOpp.oppRoleId, @@ -217,12 +174,13 @@ async function matchPlayer(seasonNum: number, oppPlayers: OppPlayers[], mapWarJs /** * @description 对手是玩家时,生成并返回pvpHistoryOpp * @param result 随机出的对手pvpDefense - * @param mapWarJson 本周地图出兵表 * @param roleId 自己的玩家id * @param pos 刷新这个对手的位置 */ -async function generPlayerOppHis(pvpdefense: PvpDefenseType, mapWarJson: DicWarJson[], roleId: string, pos: number) { - let { heroScores, heroes: defenseHeroes } = pvpdefense; +async function generPlayerOppHis(pvpdefense: PvpDefenseType, roleId: string, pos: number) { + let { heroScores, defense } = pvpdefense; + if(!defense) return false; + let { warId, heroes: defenseHeroes } = defense; let role = pvpdefense.role; let r = new Rank(REDIS_KEY.PVP_RANK, {}); let rankLv = await r.getMyRank({ roleId: role.roleId }); @@ -233,6 +191,7 @@ async function generPlayerOppHis(pvpdefense: PvpDefenseType, mapWarJson: DicWarJ let h = defenseHeroes.find(cur => cur.actorId == dbHero.hid); // 阵容里是否有这个武将 let hs = heroScores.find(cur => cur.hid == dbHero.hid); // 这个武将是否有这个得分 if (!!h) { + let mapWarJson = gameData.warJson.get(warId); let warJson = mapWarJson.find(cur => cur.dataId == h.dataId); if (warJson && warJson.relation == 2) { let heroInfo = new PvpHeroInfo(); @@ -258,7 +217,7 @@ async function generPlayerOppHis(pvpdefense: PvpDefenseType, mapWarJson: DicWarJ return pvpHistoryOpp; } -async function matchRobot(oppPlayers: OppPlayers[], mapWarJson: DicWarJson[], role: RoleType, pLv: number, dicOpp: DicPvpOpponent) { +async function matchRobot(oppPlayers: OppPlayer[], role: RoleType, pLv: number, dicOpp: DicPvpOpponent) { // console.log('matchRobot', JSON.stringify(oppPlayers)) let { lv: myLv, topLineupCe: myCe, roleId } = role; @@ -271,23 +230,21 @@ async function matchRobot(oppPlayers: OppPlayers[], mapWarJson: DicWarJson[], ro if (!result) return false; let robotWarjson = gameData.warJson.get(result.war_id); - if (!robotWarjson) { /* TODO 判空处理 */ } - let heroes = new Array(); + if (!robotWarjson) return false + let heroes: PvpEnemies[] = []; let defCe = 0; - for (let warJson of mapWarJson) { - if (warJson.relation == 1) continue; - let h = robotWarjson.find(cur => cur.dataId == warJson.dataId); - if (h) { - let dicHero = gameData.hero.get(h.actorId); - if (!dicHero) continue; - let heroInfo = new PvpHeroInfo(); - heroInfo.setRobotInfo(h, myLv, dicHero.initialStars, dicHero.quality); - let { attribute, ce } = getRobotAttribute(h.attribute, h.enemyCount, [], pLv, myCe, PVP_CONST.ENEMY_CE, ratio); - defCe += ce; - heroInfo.setAttribute(attribute); - let enemy = new PvpEnemies(warJson, heroInfo, 0, ce); - heroes.push(enemy); - } + for (let h of robotWarjson) { + if (h.relation == 1) continue; + let actorId = h.randomEnemy.length > 0? getRandSingleEelm(h.randomEnemy): 0; + let dicHero = gameData.hero.get(actorId); + if (!dicHero) continue; + let heroInfo = new PvpHeroInfo(); + heroInfo.setRobotInfo(h, actorId, myLv, dicHero.initialStars, dicHero.quality); + let { attribute, ce } = getRobotAttribute(h.attribute, h.enemyCount, [], pLv, myCe, PVP_CONST.ENEMY_CE, ratio); + defCe += ce; + heroInfo.setAttribute(attribute); + let enemy = new PvpEnemies(h, heroInfo, 0, ce); + heroes.push(enemy); } let oppRoleId = generateRobotRoleId(); @@ -321,7 +278,7 @@ export function getPlusScore(win: number) { return result; } -export function getLvByScore(heroScores: HeroScores[]) { +export function getLvByScore(heroScores: HeroScore[]) { heroScores.sort((a, b) => b.score - a.score); let score = 0; for (let i = 0; i < 5; i++) { @@ -331,71 +288,7 @@ export function getLvByScore(heroScores: HeroScores[]) { return getPLvByScore(score); } -export async function defaultHeroes(role: RoleType, challengeCnt?: number, challengeRefTime?: number, isUpdate?: boolean) { - let pvpDefense = await PvpDefenseModel.findByRoleId(role.roleId); - if (!pvpDefense) return; - let { heroes, isDefaultHero } = pvpDefense; - if (!isUpdate && !isDefaultHero) { - return; - } - let orders = [1, 2, 3, 4, 5, 6]; - role.topLineup.sort(function (a, b) { - return b.ce - a.ce; - }); - heroes.sort(function (a, b) { - return b.ce - b.dataId - a.ce + a.dataId; - }); - for (let hero of heroes) { - if (!!hero.order && !!hero.hero && findIndex(role.topLineup, { hid: hero.actorId }) != -1) { - let index = orders.indexOf(hero.order); - orders.splice(index, 1); - } - } - let defCe = 0; - let num = 0; - for (let i = 0; i < role.topLineup.length; i++) { - let item = role.topLineup[i]; - let index = findIndex(heroes, { actorId: item.hid }); - if (index == -1) { - for (let j = num; j < heroes.length; j++) { - let hero = heroes[j]; - if (num >= 6) { - break; - } - if (!!findWhere(role.topLineup, { hid: hero.actorId })) { - continue; - } - if (!orders[0]) { - break; - } - hero.actorId = item.hid; - hero.hero = item.hero; - hero.ce = item.ce; - hero.order = orders[0]; - num = j; - orders.splice(0, 1); - break; - } - } else { - heroes[index].ce = item.ce; - heroes[index].hero = item.hero; - if (!heroes[index].order) { - heroes[index].order = orders[0]; - orders.splice(0, 1); - } - } - defCe += item.ce; - } - if (!!challengeCnt && !!challengeRefTime) { - let { heroes: resHeroes } = await PvpDefenseModel.updateInfo(role.roleId, { defCe, heroes, challengeCnt, challengeRefTime, isDefaultHero: true }); - return { resHeroes }; - } else { - let { heroes: resHeroes } = await PvpDefenseModel.updateInfo(role.roleId, { defCe, heroes, isDefaultHero: true }); - return { resHeroes }; - } -} - -export function refresh(challengeCnt: number, challengeRefTime: number, seasonEndTime: number) { +export function refChallengeCnt(challengeCnt: number, challengeRefTime: number, seasonEndTime: number) { if (challengeCnt >= PVP.PVP_CHALLENGE_COUNTS) { return { challengeCnt, challengeRefTime }; } @@ -422,89 +315,32 @@ export function comsumeChallengeCnt(challengeCnt: number, challengeRefTime: numb challengeRefTime = nowSeconds(); return { challengeCnt, challengeRefTime }; } - return refresh(challengeCnt, challengeRefTime, seasonEndTime); + return refChallengeCnt(challengeCnt, challengeRefTime, seasonEndTime); } -export async function findPvpDefByRoleId(roleId: string) { - let pvpDefense = await PvpDefenseModel.findByRoleIdIncludeAll(roleId); - let { warId, seasonNum, seasonEndTime } = await PVPConfigModel.findCurPVPConfig(); - if(!pvpDefense) return { pvpDefense, warId } - let oldSeasonNum = await CounterModel.getCounter(COUNTER.PVP_SEASON_NUM); - let { seasonEndTime: oldSeasonEndTime } = await PVPConfigModel.findPVPConfig(oldSeasonNum); - if (pvpDefense.seasonNum !== seasonNum && oldSeasonEndTime < nowSeconds()) { - let newPvpDefense = await setPvpDefResult(pvpDefense, seasonNum, oldSeasonEndTime); - return { pvpDefense: newPvpDefense, warId }; +export async function sendLastSeasonRewardIfNotSent(pvpDefense: PvpDefenseType) { + let pvpConfig = await PVPConfigModel.findCurPVPConfig(); // 当前的pvp赛季 + if(pvpDefense.seasonNum != pvpConfig.seasonNum && pvpConfig.seasonEndTime < nowSeconds()) { + let oldPvpCongig = await PVPConfigModel.findPVPConfig(pvpDefense.seasonNum); + pvpDefense = await sendPVPRewardToUser(pvpDefense, pvpDefense.seasonNum, oldPvpCongig.seasonEndTime); } - let { challengeCnt, challengeRefTime } = refresh(pvpDefense.challengeCnt, pvpDefense.challengeRefTime, seasonEndTime); - let { refOppCnt, refOppTime, shouldRefOpp } = getRefOppCnt(pvpDefense.refOppCnt, pvpDefense.refOppTime); // 刷新次数 - if (challengeCnt != pvpDefense.challengeCnt || refOppCnt != pvpDefense.refOppCnt) { - await PvpDefenseModel.updateInfo(roleId, { challengeCnt, challengeRefTime, refOppCnt }); - pvpDefense.challengeCnt = challengeCnt; - pvpDefense.challengeRefTime = challengeRefTime; - pvpDefense.refOppCnt = refOppCnt; - pvpDefense.refOppTime = refOppTime; - } - return { pvpDefense, warId, shouldRefOpp }; + return pvpDefense; } // 获取刷新对手次数及消耗 -export function getRefOppCnt(refOppCnt: number, refOppTime: Date) { +export function refreshRefOppCnt(refOppCnt: number, refDaily: Date) { let curTime = new Date(); - let shouldRefOpp = shouldRefresh(refOppTime, curTime); + let shouldRefOpp = shouldRefresh(refDaily, curTime); if (shouldRefOpp) { - refOppCnt = 0; refOppTime = curTime; + refOppCnt = 0; refDaily = curTime; } return { shouldRefOpp, - refOppCnt, refOppTime, + refOppCnt, refDaily, consume: gameData.pvpRefreshConsume.get(refOppCnt + 1) } } -/** - * 获得玩家pvp信息,并检查是否在pvp赛季结算中结算过,未结算的进行结算 - * @param roleId - */ -export async function findPvpDefAllByRoleId(roleId: string) { - let pvpDefense = await PvpDefenseModel.findByRoleIdIncludeAll(roleId); - let { warId, seasonNum, seasonEndTime } = await PVPConfigModel.findCurPVPConfig(); - if(!pvpDefense) return { pvpDefense, warId } - let oldSeasonNum = await CounterModel.getCounter(COUNTER.PVP_SEASON_NUM); - let { seasonEndTime: oldSeasonEndTime } = await PVPConfigModel.findPVPConfig(oldSeasonNum); - - if (pvpDefense.seasonNum != seasonNum && oldSeasonEndTime < nowSeconds()) {//检查玩家是否在pvp赛季结算中结算过 - let { score, pLv, winStreakNum, heroScores, challengeCnt, challengeRefTime } = await pinus.app.rpc.systimer.systimerRemote.setPvpDefResult.toServer('systimer-server-1', pvpDefense, seasonNum, oldSeasonEndTime); - pvpDefense.score = score; - pvpDefense.pLv = pLv; - pvpDefense.winStreakNum = winStreakNum; - pvpDefense.heroScores = heroScores; - pvpDefense.challengeCnt = challengeCnt; - pvpDefense.challengeRefTime = challengeRefTime; - } - pvpDefense.seasonNum = seasonNum; - let { challengeCnt, challengeRefTime } = refresh(pvpDefense.challengeCnt, pvpDefense.challengeRefTime, seasonEndTime); - let { refOppCnt, refOppTime, shouldRefOpp } = getRefOppCnt(pvpDefense.refOppCnt, pvpDefense.refOppTime); // 刷新次数 - if (challengeCnt != pvpDefense.challengeCnt || refOppCnt != pvpDefense.refOppCnt || shouldRefOpp) { - let update: pvpUpdateInter = { - challengeCnt, challengeRefTime, refOppCnt, refOppTime - }; - - if (shouldRefOpp) { - let role = pvpDefense.role; - let oppPlayers = await refreshEnemies(role, pvpDefense.score, pvpDefense.pLv); - update.oppPlayers = oppPlayers; - } - - let updateResult = await PvpDefenseModel.updateInfoAndInclude(roleId, update); - pvpDefense.oppPlayers = updateResult.oppPlayers; - pvpDefense.challengeCnt = challengeCnt; - pvpDefense.challengeRefTime = challengeRefTime; - pvpDefense.refOppCnt = refOppCnt; - pvpDefense.refOppTime = refOppTime; - } - - return { pvpDefense, warId, shouldRefOpp, seasonEndTime, oldSeasonEndTime }; -} /** * 根据比例计算机器人属性 @@ -561,7 +397,7 @@ export function getPlayerMainAttribute(heroAttrs: CeAttrData[], roleAttrs: CeAtt } // 获取我方战报记录 -export async function generMyRecInfo(heroScores: HeroScores[], winStreakNum: number, role: RoleType, isSuccess: boolean, pos: number, myHeroes: pvpEndParamInter[]) { +export async function generMyRecInfo(heroScores: HeroScore[], winStreakNum: number, role: RoleType, isSuccess: boolean, pos: number, myHeroes: pvpEndParamInter[]) { let { roleId, roleName } = role; @@ -618,7 +454,7 @@ export async function generMyRecInfo(heroScores: HeroScores[], winStreakNum: num } // 获取对手战报记录 -export async function generPVPOppRecInfo(isSuccess: boolean, curOpp: OppPlayers, oppHeroes: pvpEndParamInter[], myLv: number) { +export async function generPVPOppRecInfo(isSuccess: boolean, curOpp: OppPlayer, oppHeroes: pvpEndParamInter[], myLv: number) { let oppHeroRecords = new Array(); let oppRole = curOpp.oppDef; if (!oppRole) { console.error('opp role not found') } @@ -643,3 +479,102 @@ export async function generPVPOppRecInfo(isSuccess: boolean, curOpp: OppPlayers, score: 0 } } + +/** + * pvp定时任务赛季结算 + * @param obj + */ + export async function pvpSeasonEnd(pvpConfig: PVPConfigType) { + const pageNum = 500; + console.log('exce pvpSeasonEnd' + pvpConfig?.seasonNum); + let systemConfig = await PVPConfigModel.findCurPVPConfig(); + let resultMaxRank = gameData.pvpRankMax.max;//根据排行榜的奖励表,获得最大排名挡位的最小值,其余不在结算中结算的玩家按照最大排名挡位在登录或进入pvp时结算 + let maxPage = (resultMaxRank.min + 1000) / pageNum; //保底结算玩家数量 + let lastPageNum = resultMaxRank.min % pageNum; + for (let page = 0; page < maxPage + 1; page++) { + let pvpDefenses = await PvpDefenseModel.getPvpDef(pageNum, page == maxPage ? lastPageNum : page); + for (let pvpDefense of pvpDefenses) { + if (pvpDefense.seasonNum !== systemConfig.seasonNum) { + await sendPVPRewardToUser(pvpDefense, systemConfig.seasonNum, systemConfig.seasonEndTime); + } + } + } + await PVPConfigModel.setReward(pvpConfig.seasonNum); +} + +/** + * pvp定时任务结算获得添加邮件信息 + * @param pvpDefense + * @param seasonNum + * @param oldSeasonEndTime + */ +export async function sendPVPRewardToUser(pvpDefense: PvpDefenseType, seasonNum: number, seasonEndTime: number, notPush?: boolean) { + //检查并返回排名结算以及武将功勋结算 + let pvpSeasonResult = await savePvpSeasonResult(pvpDefense, seasonNum, seasonEndTime); + let { rankGoods, heroGoods, rankLv } = pvpSeasonResult; + //下发邮件 + if (!!rankGoods.length) //排名奖励 + await sendMailByContent(MAIL_TYPE.PVP_RANK_REWARD, pvpDefense.roleId, { + params: [JSON.stringify(seasonNum), (rankLv > 1000 ? '999+' : JSON.stringify(rankLv))], + goods: rankGoods, endTime: seasonEndTime, notPush + }); + if (!!heroGoods.length) //武将功勋奖励 + await sendMailByContent(MAIL_TYPE.PVP_RESULT, pvpDefense.roleId, { + params: [JSON.stringify(seasonNum)], + goods: heroGoods, endTime: seasonEndTime, notPush + }); + + pvpDefense = await PvpDefenseModel.resetScores(pvpDefense.roleId, seasonNum + 1, pvpSeasonResult.newScore, pvpSeasonResult.newHeroScores); + return pvpDefense; +} + +/** + * 检查并返回排名结算以及武将功勋结算 + * @param pvpDefense + * @param seasonNum + * @param oldSeasonEndTime + * @param rankLv + */ +export async function savePvpSeasonResult(pvpDefense: PvpDefenseType, seasonNum: number, seasonEndTime: number, rankLv?: number) { + if (!rankLv) { + let r = new Rank(REDIS_KEY.PVP_RANK, {}); + rankLv = await r.getMyRank({ roleId: pvpDefense.roleId });// 获得排行榜排名 + } + let pvpRankReward: DicRankRewads = getPvpRankRewardsByRank(rankLv); + let rankGoods: RewardInter[] = []; + if (pvpRankReward) { + rankGoods = pvpRankReward.reward;//排名奖励 + } + let heroGoods: HeroReward[] = []; + let newHeroScores: HeroScore[] = [], newScore = 0; + for (let heroScore of pvpDefense.heroScores) { + let pvpHeroReward = getPvpHeroRewardsByScore(heroScore.score); //获得武将功勋奖励 + if (pvpHeroReward) { + newHeroScores.push({...heroScore, score: pvpHeroReward.heroscore }); + for(let { id, count } of pvpHeroReward.reward) { + heroGoods.push({ + hid: heroScore.hid, id, count + }); + } + } + newScore += heroScore.score; + } + + //pvp锁定的信息存入赛季结算表中 + let pvpSeasonResult = await PvpSeasonResultModel.updatePvpSeasonResult(pvpDefense.roleId, seasonNum, { + ...pvpDefense, rankLv, heroGoods, rankGoods, show: true, newScore, newHeroScores, seasonEndTime + });//结算修改玩家pvp信息 + + // 更新任务 + await checkTask(pvpDefense.roleId, null, TASK_TYPE.PVP_HERO_SCORE, 0, false, { heroScores: pvpDefense.heroScores }); + await checkTask(pvpDefense.roleId, null, TASK_TYPE.PVP_RANK, 1, false, { rankLv }); + return pvpSeasonResult; +} + +function getScore(arr, score) { + for (let item of arr) { + if ((item.max >= score || item.max == -1) && score >= item.min) { + return item; + } + } +} \ No newline at end of file diff --git a/game-server/app/services/redisService.ts b/game-server/app/services/redisService.ts index 11657d8d4..e15753620 100644 --- a/game-server/app/services/redisService.ts +++ b/game-server/app/services/redisService.ts @@ -34,6 +34,10 @@ export async function initAllRank() { await delKeys(REDIS_KEY.MAIN_ELITE_RANK); await delKeys(REDIS_KEY.HERO_RANK); await delKeys(REDIS_KEY.SHOW_LINEUP); + await delKeys(REDIS_KEY.PVP_RANK); + + await setRankRedisFromDb(REDIS_KEY.PVP_RANK, {}); + for(let {id} of serverList) { await initRank(id); } diff --git a/game-server/app/services/timeTaskService.ts b/game-server/app/services/timeTaskService.ts index 7fab01c76..6aef41509 100644 --- a/game-server/app/services/timeTaskService.ts +++ b/game-server/app/services/timeTaskService.ts @@ -1,14 +1,11 @@ import { scheduleJob, Job, } from 'node-schedule'; -import { PVPConfigModel } from '../db/SystemConfig'; -import PvpDefenseType, { PvpDefenseModel } from '../db/PvpDefense'; -import { PVP, SERVER_DEBUG_MODE } from '../pubUtils/dicParam'; -import { nowSeconds, getTimeFun } from '../pubUtils/timeUtil'; -import { getPvpGkWarIds, getPvpRankRewards, getPvpHeroRewards, getResultMaxRank, getTodayGuildActivity, gameData } from '../pubUtils/data'; -import { deepCopy, getRandSingleEelm } from '../pubUtils/util'; -import { getLvByScore } from './pvpService'; -import { getAllOnlineRoles, getAllServers, initSingleRank, delGuildActivityRank } from './redisService'; -import { MAIL_TYPE, REDIS_KEY, GUILD_ACTIVITY_STATUS, GUILD_ACTIVITY_TYPE, TASK_TYPE, TIME_OUTPUT_TYPE, REFRESH_TIME, SEND_NAME, SERVER_OPEN_TIME, COUNTER, AUCTION_TIME } from '../consts'; +import { PVPConfigModel, PVPConfigType } from '../db/SystemConfig'; +import { nowSeconds, getTimeFun, getZeroPoint } from '../pubUtils/timeUtil'; +import { getTodayGuildActivity, gameData } from '../pubUtils/data'; +import { pvpSeasonEnd } from './pvpService'; +import { getAllOnlineRoles, getAllServers, delGuildActivityRank } from './redisService'; +import { GUILD_ACTIVITY_TYPE, REFRESH_TIME, SEND_NAME, SERVER_OPEN_TIME, COUNTER, AUCTION_TIME } from '../consts'; import { RoleModel } from '../db/Role'; import { pinus } from 'pinus'; import { indexOf } from 'underscore'; @@ -29,8 +26,7 @@ import { reportOneOnline } from './authenticateService'; const PER_SECOND = 1 * 1000; const PER_DAY = 24 * 60 * 60; -const SETTLE_DIFF = 29 * 60; -const pageNum = 500; +const SETTLE_DIFF_SECONDS = 29 * 60; const PER_MINUTE = 1 * 60; var seasonMakeRewardTimJobId: Job; var warJobId: Job; @@ -46,22 +42,9 @@ let pvpRefreshInterval = null; * 服务器启动即开启定时任务,结算时常是23-24点,实际结算的时间点是23:31分钟 */ export async function init() { - let systemConfig = await PVPConfigModel.findCurPVPConfig(); - let seasonEndTime = systemConfig ? systemConfig.seasonEndTime : getTimeFun(moment(SERVER_OPEN_TIME).startOf('d').add(-1, 'minute').toDate()).getAfterDay(PVP.PVP_SEASON_DAYS); - if (nowSeconds() > seasonEndTime) {//停服太长,数据配置问题导致数据太老,需要刷新赛季数据 - while (nowSeconds() > seasonEndTime) { - seasonEndTime = getTimeFun(seasonEndTime).getAfterDay(PVP.PVP_SEASON_DAYS); - } - } - if (!systemConfig || seasonEndTime != systemConfig.seasonEndTime) { - systemConfig = await createNewPvpSeasonData(seasonEndTime) - } - - await resetPVPTimer(seasonEndTime); - - warJobId = scheduleJob("0 0 0 * * 1", resetPvpWarId);//每周1零点重置地图 - await resetPvpRanks();//服务器重启,重置排行榜的信息 + // pvp赛季 + await setPvpSeason(); // 周功勋结算任务 guildWeeklyJobId = scheduleJob('settleGuildWeekly', '0 0 0 * * 1', settleGuildWeekly); @@ -86,248 +69,67 @@ export async function init() { await initMaintenance(); } -async function resetPVPTimer(seasonEndTime: number) { +function getSeasonContinueDay(seasonNum: number) { + const pvpSeasonDuring = [{seasonNum: 1, day: 7},{seasonNum: 2, day: 15},{seasonNum: 3, day: 30},]; + + let maxDay = 0; + for(let {seasonNum: dicSeasonNum, day } of pvpSeasonDuring) { + if(seasonNum == dicSeasonNum) return day; + if(maxDay < day) maxDay = day; + } + return maxDay; +} + +async function setPvpSeason() { + let pvpConfig = await PVPConfigModel.findCurPVPConfig(); + if(!pvpConfig || pvpConfig.seasonEndTime <= nowSeconds() ) { + if(!pvpConfig.hasSettleReward) { + await pvpSeasonEnd(pvpConfig); + } + + let lastSeasonNum = pvpConfig? pvpConfig.seasonNum: 0; + let lastSeasonEndTime = pvpConfig? pvpConfig.seasonEndTime: 0; + + let newSeasonStartTime = lastSeasonEndTime; + let during = getSeasonContinueDay(lastSeasonNum + 1) * PER_DAY; + let rewardTime = SETTLE_DIFF_SECONDS; + if(nowSeconds() - lastSeasonEndTime > during) { + newSeasonStartTime = getZeroPoint(); + } + pvpConfig = await PVPConfigModel.createPVPConfig(lastSeasonNum + 1, newSeasonStartTime, newSeasonStartTime + during - rewardTime, newSeasonStartTime + during - PER_MINUTE); + } + await setPvpSeasonMakeRewardJob(pvpConfig); + await setNextSeasonJob(pvpConfig); +} + +async function setPvpSeasonMakeRewardJob(pvpConfig: PVPConfigType) { if (!!seasonMakeRewardTimJobId) { seasonMakeRewardTimJobId.cancel(); - clearInterval(pvpMakeRewardInterval); } + if(pvpConfig.seasonRewardTime < nowSeconds() && !pvpConfig.hasSettleReward) { // 未发奖励 + await pvpSeasonEnd(pvpConfig); + } else { + seasonMakeRewardTimJobId = scheduleJob('seasonMakeRewardTimJobId', pvpConfig.seasonRewardTime, async () => { + await pvpSeasonEnd(pvpConfig); + }); + } +} + +async function setNextSeasonJob(pvpConfig: PVPConfigType) { if (!!seasonRefreshTimeJobId) { seasonRefreshTimeJobId.cancel(); - clearInterval(pvpRefreshInterval); } - if (seasonEndTime - SETTLE_DIFF - nowSeconds() < 0) {//23:30-24:00之间,已经过了结算时间,还未开启新赛季 - console.log('立刻结算奖励:', nowSeconds()); - await pvpSeasonEnd(); - //定时结算奖励 - seasonMakeRewardTimJobId = scheduleJob('seasonMakeRewardTimJobId', (seasonEndTime - SETTLE_DIFF - nowSeconds()) * PER_SECOND + PVP.PVP_SEASON_DAYS * PER_DAY * PER_SECOND, pvpMakeRewardTimer);// - } else { - //定时结算奖励 - seasonMakeRewardTimJobId = scheduleJob('seasonMakeRewardTimJobId', (seasonEndTime - SETTLE_DIFF - nowSeconds()) * PER_SECOND, pvpMakeRewardTimer);// - }; - //定时开启新赛季 - seasonRefreshTimeJobId = scheduleJob('seasonRefreshTimeJobId', (seasonEndTime - nowSeconds()) * PER_SECOND, pvpRefreshTimer);// + //定时开启新赛季,比seasonEndTime多定一分钟,保证定时器时间没错 + seasonRefreshTimeJobId = scheduleJob('seasonRefreshTimeJobId', pvpConfig.seasonEndTime + PER_MINUTE, setPvpSeason); } -//pvp结算奖励定时器 -async function pvpMakeRewardTimer() { - pvpMakeRewardInterval = setInterval(async () => { - console.log('定时结算奖励:', nowSeconds()); - await pvpSeasonEnd() - }, PVP.PVP_SEASON_DAYS * PER_DAY * PER_SECOND) -} - -//pvp刷新开始新赛季定时器 -async function pvpRefreshTimer() { - pvpRefreshInterval = setInterval(async () => { - console.log('定时开启新赛季:', nowSeconds()); - await createNextPvpSeason(); - }, PVP.PVP_SEASON_DAYS * PER_DAY * PER_SECOND) -} - -//创建下个新赛季 -export async function createNextPvpSeason() { - let systemConfig = await PVPConfigModel.findCurPVPConfig(); - let seasonEndTime = systemConfig ? systemConfig.seasonEndTime : getTimeFun(moment(SERVER_OPEN_TIME).startOf('d').add(-1, 'minute').toDate()).getAfterDay(PVP.PVP_SEASON_DAYS); - if (nowSeconds() > seasonEndTime) {//停服太长,数据配置问题导致数据太老,需要刷新赛季数据 - while (nowSeconds() > seasonEndTime) { - seasonEndTime = getTimeFun(seasonEndTime).getAfterDay(PVP.PVP_SEASON_DAYS); - } - } - systemConfig = await createNewPvpSeasonData(seasonEndTime) - await resetPvpRanks() - return systemConfig; -} - -/** - * pvp定时任务赛季结算 - * @param obj - */ -export async function pvpSeasonEnd(obj?: { name: string, notSetNext?: boolean, notPush?: boolean }) { - console.log('exce pvpSeasonEnd' + obj?.name); - let systemConfig = await PVPConfigModel.findCurPVPConfig(); - let resultMaxRank = getResultMaxRank();//根据排行榜的奖励表,获得最大排名挡位的最小值,其余不在结算中结算的玩家按照最大排名挡位在登录或进入pvp时结算 - let maxPage = (resultMaxRank.min + 1000) / pageNum; //保底结算玩家数量 - let lastPageNum = resultMaxRank.min % pageNum; - for (let page = 0; page < maxPage + 1; page++) { - let pvpDefenses = await PvpDefenseModel.getPvpDef(pageNum, page == maxPage ? lastPageNum : page); - for (let pvpDefense of pvpDefenses) { - if (pvpDefense.seasonNum !== systemConfig.seasonNum) { - await setPvpDefResultOnTime(pvpDefense, systemConfig.seasonNum, systemConfig.seasonEndTime, obj?.notPush); - } - } - } -} -/** - * pvp定时任务结算获得添加邮件信息 - * @param pvpDefense - * @param seasonNum - * @param oldSeasonEndTime - */ -export async function setPvpDefResultOnTime(pvpDefense: PvpDefenseType, seasonNum: number, oldSeasonEndTime: number, notPush?: boolean) { - //检查并返回排名结算以及武将功勋结算 - let { score, pLv, heroScores, challengeCnt, challengeRefTime, rankGoods, heroGoods, rankLv } = await checkResult(pvpDefense, seasonNum, oldSeasonEndTime); - pvpDefense = await PvpDefenseModel.updateInfo(pvpDefense.roleId, { score, pLv, heroScores, seasonNum, challengeCnt, challengeRefTime }); - //下发邮件 - if (!!rankGoods.length) //排名奖励 - await sendMailByContent(MAIL_TYPE.PVP_RANK_REWARD, pvpDefense.roleId, { - params: [JSON.stringify(seasonNum), (rankLv > 1000 ? '999+' : JSON.stringify(rankLv))], - goods: rankGoods, endTime: oldSeasonEndTime, notPush - }); - if (!!heroGoods.length) //武将功勋奖励 - await sendMailByContent(MAIL_TYPE.PVP_RESULT, pvpDefense.roleId, { - params: [JSON.stringify(seasonNum)], - goods: heroGoods, endTime: oldSeasonEndTime, notPush - }); - return pvpDefense; -} -/** - * 检查并返回排名结算以及武将功勋结算 - * @param pvpDefense - * @param seasonNum - * @param oldSeasonEndTime - * @param rankLv - */ -export async function checkResult(pvpDefense: PvpDefenseType, seasonNum: number, oldSeasonEndTime: number, rankLv?: number) { - let pvpRankRewards = getPvpRankRewards(); - let pvpHeroRewards = getPvpHeroRewards(); - if (!rankLv) { - let r = new Rank(REDIS_KEY.PVP_RANK, {}); - rankLv = await r.getMyRank({ roleId: pvpDefense.roleId });// 获得排行榜排名 - } - let oldPLv = getLvByScore(pvpDefense.heroScores);//结算前玩家的pvp等级 - let { challengeCnt, challengeRefTime } = pvpDefense; - let pvpRankReward; - if (!!rankLv) { - pvpRankReward = getScore(pvpRankRewards, rankLv);//获得排名挡位信息 - } else { - pvpRankReward = getResultMaxRank();//最大排名等级挡位信息 - } - let rankGoods = []; - if (pvpRankReward) { - rankGoods = pvpRankReward.reward;//排名奖励 - } - let heroGoods = []; - let score = 0; - let oldHeroScores = deepCopy(pvpDefense.heroScores) - for (let i = 0; i < pvpDefense.heroScores.length; i++) { - let heroScore = pvpDefense.heroScores[i]; - let pvpHeroReward = getScore(pvpHeroRewards, heroScore.score);//获得武将功勋奖励 - if (pvpHeroReward) { - heroScore.score = pvpHeroReward.heroscore; - if (!!pvpHeroReward.reward[0]) { - heroGoods.push({ - hid: heroScore.hid, - id: pvpHeroReward.reward[0].id, - count: pvpHeroReward.reward[0].count, - }); - } - } - score += heroScore.score; - } - let pLv = getLvByScore(pvpDefense.heroScores); - //pvp锁定的信息存入赛季结算表中 - await PvpSeasonResultModel.updatePvpSeasonResult(pvpDefense.roleId, { - oldSeasonData: { - refOppCnt: pvpDefense.refOppCnt, rankLv, score: pvpDefense.score, pLv: oldPLv, heroScores: oldHeroScores, - seasonNum: pvpDefense.seasonNum, challengeCnt, challengeRefTime, seasonEndTime: oldSeasonEndTime - }, heroGoods, rankGoods, show: true - });//结算修改玩家pvp信息 - // 更新任务 - await checkTask(pvpDefense.roleId, null, TASK_TYPE.PVP_HERO_SCORE, 0, false, { heroScores: pvpDefense.heroScores }); - await checkTask(pvpDefense.roleId, null, TASK_TYPE.PVP_RANK, 1, false, { rankLv }); - return { - rankLv, score, pLv, heroScores: pvpDefense.heroScores, seasonNum, challengeCnt: PVP.PVP_CHALLENGE_COUNTS, challengeRefTime: 0, oldSeasonEndTime, heroGoods: heroGoods.map(({ id, count }) => { - return { id, count }; - }), rankGoods - }; -} -/** - * 个人pvp结算,结算中未结算的,都按照最大排名挡位结算 - * @param pvpDefense - * @param seasonNum - * @param oldSeasonEndTime - */ -export async function setPvpDefResult(pvpDefense: PvpDefenseType, seasonNum: number, oldSeasonEndTime: number) { - let role = await RoleModel.findByRoleId(pvpDefense.roleId); - if (!role) { - return; - } - let resultMaxRank = getResultMaxRank(); - let rankLv = resultMaxRank.min; //最大排名挡位结算 - let { score, pLv, heroScores, challengeCnt, challengeRefTime, rankGoods, heroGoods } = await checkResult(pvpDefense, seasonNum, oldSeasonEndTime, rankLv); - pvpDefense = await PvpDefenseModel.updateInfoAndInclude(pvpDefense.roleId, { score, pLv, heroScores, seasonNum, challengeCnt, challengeRefTime }); - let { roleId } = role; - let r = new Rank(REDIS_KEY.PVP_RANK, {}); - r.setRankWithRoleInfo(pvpDefense.roleId, pvpDefense.score, pvpDefense.updatedAt.getTime(), role, true); - //下发邮件 - if (!!rankGoods.length) - await sendMailByContent(MAIL_TYPE.PVP_RANK_REWARD, roleId, { params: [JSON.stringify(seasonNum), '999+'], goods: rankGoods, endTime: oldSeasonEndTime }); - if (!!heroGoods.length) - await sendMailByContent(MAIL_TYPE.PVP_RESULT, roleId, { params: [JSON.stringify(seasonNum)], goods: heroGoods, endTime: oldSeasonEndTime }); - return pvpDefense; -} - -/** - * 新pvp赛季数据 - */ -export async function createNewPvpSeasonData(seasonEndTime: number) { - console.log('createNewPvpSeasonData'); - let seasonNum = await CounterModel.getNewCounter(COUNTER.PVP_SEASON_NUM); - // let seasonEndTime: number = getTimeFun(oldEndTime).getAfterDay(PVP.PVP_SEASON_DAYS); - let warId = getPvpWarId(-1); - let systemConfig = await PVPConfigModel.createPVPConfig(seasonNum, seasonEndTime, warId); - return systemConfig; -} - -/** - * 随机地图Id - */ -function getPvpWarId(oldWarId: number): number { - let warIds: number[] = deepCopy(getPvpGkWarIds()); - let index = indexOf(warIds, oldWarId); - if (index != -1) { - warIds.splice(index, 1); - } - let warId = getRandSingleEelm(warIds); - console.log('getPvpWarId', oldWarId, warId); - return warId; -} - -/** - * 每周重置地图 - */ -export async function resetPvpWarId() { - let systemConfig = await PVPConfigModel.findCurPVPConfig(); - let warId = getPvpWarId(systemConfig.warId) - return await PVPConfigModel.updatePVPConfig(systemConfig.seasonNum, { warId }); -} - -function getScore(arr, score) { - for (let item of arr) { - if ((item.max >= score || item.max == -1) && score >= item.min) { - return item; - } - } -} /** * debug接口 * @param hour */ export async function resetPvpSeasonTime(hour: number) { - let systemConfig = await PVPConfigModel.findCurPVPConfig(); - - let seasonEndTime = getTimeFun().getTimeWithHour(REFRESH_TIME - hour); - systemConfig = await createNewPvpSeasonData(seasonEndTime); - await resetPVPTimer(seasonEndTime); - await resetPvpRanks(); - console.log('settleTime = ' + systemConfig.seasonNum) - - return { seasonEndTime, seasonNum: systemConfig.seasonNum }; -} - - -export async function resetPvpRanks() { - await initSingleRank(REDIS_KEY.PVP_RANK); + await PVPConfigModel.setCurPvpConfig({ seasonEndTime: getZeroPoint() }); + return await setPvpSeason(); } export async function reportOnlineSchedule() { diff --git a/gm-server/app/controller/users.ts b/gm-server/app/controller/users.ts index 9fc8fa370..03e6a717d 100644 --- a/gm-server/app/controller/users.ts +++ b/gm-server/app/controller/users.ts @@ -100,17 +100,17 @@ export default class UserController extends Controller { ctx.body = await ctx.service.users.setHeroJob(roleIdAndHids, job); } - public async saveHeroToDefense() { - const { ctx } = this; - const { roleId, roleName, hid } = ctx.request.body; - ctx.body = await ctx.service.users.saveHeroToDefense(roleId, roleName, hid); - } + // public async saveHeroToDefense() { + // const { ctx } = this; + // const { roleId, roleName, hid } = ctx.request.body; + // ctx.body = await ctx.service.users.saveHeroToDefense(roleId, roleName, hid); + // } - public async removeHeroFromDefense() { - const { ctx } = this; - const { roleId, hid } = ctx.request.body; - ctx.body = await ctx.service.users.removeHeroFromDefense(roleId, hid); - } + // public async removeHeroFromDefense() { + // const { ctx } = this; + // const { roleId, hid } = ctx.request.body; + // ctx.body = await ctx.service.users.removeHeroFromDefense(roleId, hid); + // } public async getEquipList() { const { ctx } = this; diff --git a/gm-server/app/router.ts b/gm-server/app/router.ts index 15818c491..7aee4e084 100644 --- a/gm-server/app/router.ts +++ b/gm-server/app/router.ts @@ -37,8 +37,8 @@ export default (app: Application) => { router.post('/api/users/setherolv', tokenParser, controller.users.setHeroLv); router.post('/api/users/setheroparam', controller.users.setHeroParam); router.post('/api/users/setherojob', controller.users.setHeroJob); - router.post('/api/users/saveherotodefense',tokenParser, controller.users.saveHeroToDefense); - router.post('/api/users/removeherofromdefense',tokenParser, controller.users.removeHeroFromDefense); + // router.post('/api/users/saveherotodefense',tokenParser, controller.users.saveHeroToDefense); + // router.post('/api/users/removeherofromdefense',tokenParser, controller.users.removeHeroFromDefense); router.post('/api/users/getequiplist', tokenParser, controller.users.getEquipList); router.post('/api/users/getitemlist', tokenParser, controller.users.getItemList); router.post('/api/users/deleteequip', tokenParser, controller.users.deleteEquip); diff --git a/gm-server/app/service/users.ts b/gm-server/app/service/users.ts index 451f2bb01..4196b4ed1 100644 --- a/gm-server/app/service/users.ts +++ b/gm-server/app/service/users.ts @@ -193,7 +193,7 @@ export default class GMUsers extends Service { let { uid, tel } = role.userInfo; result.push({ key: roleId, roleId, roleName, serverId, lv, vLv, uid, tel, heroCount, equipCount, itemCount, gold, coin, - hasDefense: defense ? '是' : '否', defCe: defense ? defense.defCe : 0 + hasDefense: defense ? '是' : '否', defCe: 0 }); } return ctx.service.utils.resResult(STATUS.SUCCESS, { list: result }); @@ -394,59 +394,59 @@ export default class GMUsers extends Service { // }) // } - public async saveHeroToDefense(roleId: string, _roleName: string, hid: number) { - const { ctx } = this; - let hero = await HeroModel.findByHidAndRole(hid, roleId); - let role = await RoleModel.findByRoleId(roleId); - if (!hero || !role) { - return ctx.service.utils.resResult(STATUS.GM_HERO_NOT_FOUND); - } - let { lv, ce, attr: heroAttrs } = hero; - let { attr: roleAttrs } = role; + // public async saveHeroToDefense(roleId: string, _roleName: string, hid: number) { + // const { ctx } = this; + // let hero = await HeroModel.findByHidAndRole(hid, roleId); + // let role = await RoleModel.findByRoleId(roleId); + // if (!hero || !role) { + // return ctx.service.utils.resResult(STATUS.GM_HERO_NOT_FOUND); + // } + // let { lv, ce, attr: heroAttrs } = hero; + // let { attr: roleAttrs } = role; - let dicHero = gameData.hero.get(hid); + // let dicHero = gameData.hero.get(hid); - let attribute = new AttributeCal(); - attribute.setByDbData(roleAttrs, heroAttrs); + // let attribute = new AttributeCal(); + // attribute.setByDbData(roleAttrs, heroAttrs); - let heroInfo = { - actorId: dicHero.heroId, - actorName: dicHero.name, - attribute, lv, - ce - }; + // let heroInfo = { + // actorId: dicHero.heroId, + // actorName: dicHero.name, + // attribute, lv, + // ce + // }; - let defense = await PvpDefenseModel.findByRoleId(roleId); - if (!defense) { - // defense = await PvpDefenseModel.createPvpDefense({roleId, roleName, heroes: [], defCe:ce}); - } else { - defense = await PvpDefenseModel.addHeroToDefense(roleId, heroInfo, ce); - } - return ctx.service.utils.resResult(STATUS.SUCCESS, { - defense - }); - } + // let defense = await PvpDefenseModel.findByRoleId(roleId); + // if (!defense) { + // // defense = await PvpDefenseModel.createPvpDefense({roleId, roleName, heroes: [], defCe:ce}); + // } else { + // defense = await PvpDefenseModel.addHeroToDefense(roleId, heroInfo, ce); + // } + // return ctx.service.utils.resResult(STATUS.SUCCESS, { + // defense + // }); + // } - public async removeHeroFromDefense(roleId: string, hid: number) { - const { ctx } = this; + // public async removeHeroFromDefense(roleId: string, hid: number) { + // const { ctx } = this; - let defense = await PvpDefenseModel.findByRoleId(roleId); - if (!defense) { - return ctx.service.utils.resResult(STATUS.GM_PVP_DEFENSE_NOT_FOUND); - } - let { heroes } = defense; - let curHero = heroes.find(cur => cur.actorId == hid); - if (!curHero) { - return ctx.service.utils.resResult(STATUS.GM_PVP_DEFENSE_HERO_NOT_FOUND); - } - defense = await PvpDefenseModel.removeHeroFromDefense(roleId, hid, curHero.ce); + // let defense = await PvpDefenseModel.findByRoleId(roleId); + // if (!defense) { + // return ctx.service.utils.resResult(STATUS.GM_PVP_DEFENSE_NOT_FOUND); + // } + // let { heroes } = defense; + // let curHero = heroes.find(cur => cur.actorId == hid); + // if (!curHero) { + // return ctx.service.utils.resResult(STATUS.GM_PVP_DEFENSE_HERO_NOT_FOUND); + // } + // defense = await PvpDefenseModel.removeHeroFromDefense(roleId, hid, curHero.ce); - return ctx.service.utils.resResult(STATUS.SUCCESS, { - defense - }); - } + // return ctx.service.utils.resResult(STATUS.SUCCESS, { + // defense + // }); + // } /** * 根据类型等搜索玩家 diff --git a/shared/db/PvpDefense.ts b/shared/db/PvpDefense.ts index 6cdeb2282..2a9b040e6 100644 --- a/shared/db/PvpDefense.ts +++ b/shared/db/PvpDefense.ts @@ -1,64 +1,10 @@ import BaseModel from './BaseModel'; import { index, getModelForClass, prop, DocumentType, Ref, mongoose } from '@typegoose/typegoose'; -import Hero, { } from './Hero'; import Role, { } from './Role'; -import { PVP_PLAYER_POS, PVP_HERO_POS } from '../consts'; -import PvpHistoryOpp from './PvpHistoryOpp'; -import { reduceCe } from '../pubUtils/util'; - -export class Heroes { - @prop({ required: true }) - actorId: number; // 武将id - @prop({ ref: 'Hero', type: mongoose.Schema.Types.ObjectId }) - hero: Ref; - @prop({ required: true }) - ce: number; // 战斗力 - @prop({ required: true }) - dataId: number; - @prop({ required: true }) - order: number; -} - -// 初始化 -function getInitialOppPlayers() { - let players = new Array(); - for(let i = PVP_PLAYER_POS.START; i <= PVP_PLAYER_POS.END; i++) { - let p = new OppPlayers(); - p.pos = i; - players.push(p); - } - return players; -} - -// 初始化 -function getInitialOppHeros() { - let heros = new Array(); - for(let i = PVP_HERO_POS.START; i <= PVP_HERO_POS.END; i++) { - let p = new Heroes(); - p.dataId = i; - p.order = i; - heros.push(p); - } - return heros; -} - -export class OppPlayers { - @prop({ required: true }) - roleId: string; - @prop({ ref: 'PvpHistoryOpp', type: mongoose.Schema.Types.ObjectId }) - oppDef: Ref; - @prop({ required: true }) - pos: number; - @prop({ required: true }) - isRobot: boolean; -} - -export class HeroScores { - @prop({ required: true }) - hid: number; - @prop({ required: true }) - score: number; -} +import { Defense, Attack, LineupCe, OppPlayer, HeroScore, } from '../domain/battleField/pvp'; +import { CounterModel } from './Counter'; +import { COUNTER } from '../consts'; +import { PVP } from '../pubUtils/dicParam'; @index({ roleId: 1 }) export default class PvpDefense extends BaseModel { @@ -68,38 +14,43 @@ export default class PvpDefense extends BaseModel { roleName: string; // 角色名称 @prop({ ref: 'Role', type: mongoose.Schema.Types.ObjectId }) role: Ref; - @prop({ required: true, type: Heroes, default: getInitialOppHeros(), _id: false }) - heroes: Array; + @prop({ required: true, default: null, _id: false }) + defense: Defense; + @prop({ required: true, default: null, _id: false }) + attack: Attack; + @prop({ required: true, type: () => LineupCe, default: [], _id: false }) + lineupCe: LineupCe[]; + @prop({ required: true, type: () => OppPlayer, default: [], _id: false }) + oppPlayers: OppPlayer[]; + @prop({ required: true, type: () => HeroScore, default: [], _id: false }) + heroScores: HeroScore[]; + @prop({ required: true, default: 0 }) score: number; - @prop({ required: true, default: 1 }) - pLv: number; @prop({ required: true, default: 0 }) hisScore: number; //历史最高积分 @prop({ required: true, default: 0 }) winStreakNum: number; //连胜次数 - @prop({ required: true, default: 0, get: (val: number) => reduceCe(val), set: (val: number) => val }) - defCe: number; //防守ce - @prop({ required: true, type: OppPlayers, default: getInitialOppPlayers(), _id: false }) - oppPlayers: Array; - @prop({ required: true, type: HeroScores, default: [], _id: false }) - heroScores: Array; - @prop({ required: true, default: true }) - isDefaultHero: boolean; + + @prop({ required: true, default: () => { return new Date() } }) + refDaily: Date; // 每日刷新,控制refOppCnt和setAttackCnt @prop({ required: true, default: 0 }) refOppCnt: number; // 刷新对手总次数,消耗可根据消耗表算出 - @prop({ required: true, default: new Date() }) - refOppTime: Date; // 刷新对手时间 @prop({ required: true, default: 0 }) - challengeCnt: number; // 可挑战次数 + setAttackCnt: number; // 设置挑战阵容次数 + + @prop({ required: true, default: 0 }) + challengeCnt: number; // 可挑战次数,每2小时回复一次 @prop({ required: true, default: 0 }) challengeRefTime: number; // 上一次刷新的时间 + @prop({ required: true, type: Number, default: [] }) receivedBox: Array; @prop({ required: true, default: 0 }) seasonNum: number; @prop({ required: true, default: true }) isFirstEntry: boolean; + public static async findByRoleId(roleId: string, getters = false) { const result: PvpDefenseType = await PvpDefenseModel.findOne({ roleId }).lean({ getters}); return result; @@ -114,18 +65,12 @@ export default class PvpDefense extends BaseModel { } public static async createPvpDefense(params: pvpUpdateInter) { + let seasonNum = await CounterModel.getCounter(COUNTER.PVP_SEASON_NUM); const doc = new PvpDefenseModel(); - const update = Object.assign(doc.toJSON(), params); - const defense: PvpDefenseType = await PvpDefenseModel.findOneAndUpdate({ roleId: params.roleId }, update, { upsert: true, new: true }).lean(); - return defense; - } - - public static async createPvpDefenseAndPopulate(params: pvpUpdateInter) { - const doc = new PvpDefenseModel(); - const update = Object.assign(doc.toJSON(), params); + const update = Object.assign(doc.toJSON(), params, { seasonNum, challengeCnt: PVP.PVP_CHALLENGE_COUNTS }); const defense: PvpDefenseType = await PvpDefenseModel.findOneAndUpdate({ roleId: params.roleId }, update, { upsert: true, new: true }) - .populate('oppPlayers.oppDef', 'oppRoleId pos roleName head frame spine heads frames spines rankLv pLv title lv defCe heroes') + .populate('role') .lean(); return defense; @@ -163,15 +108,15 @@ export default class PvpDefense extends BaseModel { const result: PvpDefenseType = await PvpDefenseModel.findOne({ roleId }) .populate('role', 'head frame spine topLineupCe roleId roleName lv globalCeAttr') .populate('heroes.hero') - .populate('oppPlayers.oppDef', 'oppRoleId pos roleName head frame spine heads frames spines rankLv title lv pLv defCe heroes').lean({ getters: true, virtuals: true }); + .populate('oppPlayer.oppDef', 'oppRoleId pos roleName head frame spine heads frames spines rankLv title lv pLv defCe heroes').lean({ getters: true, virtuals: true }); return result; } public static async findByTeamLv(seasonNum: number, min: number, max: number) { - const result: PvpDefenseType[] = await PvpDefenseModel.find({ seasonNum, pLv: { $gte: min, $lte: max } }) + const result: PvpDefenseType[] = await PvpDefenseModel.find({ seasonNum, 'defense.pLv': { $gte: min, $lte: max } }) .populate('role', 'head frame spine heads frames spines topLineupCe roleId roleName lv globalCeAttr') .populate('heroes.hero') - .populate('oppPlayers.oppDef', 'oppRoleId pos roleName head frame spine heads frames spines rankLv pLv title lv defCe heroes') + .populate('oppPlayer.oppDef', 'oppRoleId pos roleName head frame spine heads frames spines rankLv pLv title lv defCe heroes') .lean({ getters: true, virtuals: true }); return result; } @@ -180,7 +125,7 @@ export default class PvpDefense extends BaseModel { delete update._id; let result: PvpDefenseType = await PvpDefenseModel.findOneAndUpdate({roleId}, {$set:update}, {new: true}) .populate('role', 'head frame spine heads frames spines topLineupCe roleId roleName lv') - .populate('oppPlayers.oppDef', 'oppRoleId pos roleName head frame spine heads frames spines rankLv pLv title lv defCe heroes').lean({ getters: true, virtuals: true }); + .populate('oppPlayer.oppDef', 'oppRoleId pos roleName head frame spine heads frames spines rankLv pLv title lv defCe heroes').lean({ getters: true, virtuals: true }); return result; } public static async updateInfo(roleId: string, update: pvpUpdateInter, lean = true) { @@ -201,6 +146,11 @@ export default class PvpDefense extends BaseModel { return ranks; } + public static async resetScores(roleId: string, newSeasonNum: number, newScore: number, newHeroScores: HeroScore[]) { + let result: PvpDefenseType = await PvpDefenseModel.findOneAndUpdate({roleId}, {$set: { seasonNum: newSeasonNum, score: newScore, heroScores: newHeroScores, challengeCnt: PVP.PVP_CHALLENGE_COUNTS, challengeRefTime: 0, winStreakNum: 0 }}, {new: true}).lean(); + return result; + } + public static async deleteHero(roleId: string, hid: number) { let result:PvpDefenseType = await PvpDefenseModel.findOneAndUpdate({roleId}, {$pull:{heroes: {actorId:hid}}}, {new: true}).lean(); return result; diff --git a/shared/db/PvpSeasonResult.ts b/shared/db/PvpSeasonResult.ts index 8323da385..79e65e696 100644 --- a/shared/db/PvpSeasonResult.ts +++ b/shared/db/PvpSeasonResult.ts @@ -1,94 +1,54 @@ import BaseModel from './BaseModel'; import { index, getModelForClass, prop, DocumentType } from '@typegoose/typegoose'; -class Reward { - @prop({ required: true }) - id: number; - @prop({ required: true }) - count: number; -} +import { Reward, HeroReward, HeroScore } from '../domain/battleField/pvp'; -class HeroReward { +@index({ roleId: 1, seasonNum: 1 }) +export default class PvpSeasonResult extends BaseModel { + @prop({ required: true }) - hid: number; - @prop({ required: true }) - id: number; - @prop({ required: true }) - count: number; -} -export class HeroScores { - @prop({ required: true }) - hid: number; - @prop({ required: true }) - score: number; - @prop({ required: true }) - goodId: number; - @prop({ required: true }) - count: number; -} - -export interface pvpUpdate { - rankGoods?:Array; - oldSeasonData?: SeasonData; - show?: boolean; - heroGoods?:Array; -} - -class SeasonData { - @prop({ required: true }) - score: number; - - @prop({ required: true }) - pLv: number; - - @prop({ required: true, type:HeroScores, default:[] }) - heroScores: HeroScores[]; + roleId: string; @prop({ required: true }) seasonNum: number; - - @prop({ required: true }) - challengeCnt: number; - - @prop({ required: true }) - challengeRefTime: number; - + @prop({ required: true }) seasonEndTime: number; + @prop({ required: true }) + score: number; + + @prop({ required: true, type: () => HeroScore, default:[] }) + heroScores: HeroScore[]; + @prop({ required: true }) rankLv: number; - - @prop({ required: true }) - refOppCnt:number; -} - -@index({ roleId: 1 }) -export default class PvpSeasonResult extends BaseModel { - @prop({ required: true }) - roleId: string; - - @prop({ required: true, type: SeasonData, _id: false}) - oldSeasonData: SeasonData; @prop({ required: true, default: true }) show: boolean; - @prop({ required: true, type: HeroReward, default: [], _id: false}) - heroGoods: Array; + @prop({ required: true, type: () => HeroReward, default: [], _id: false}) + heroGoods: HeroReward[]; @prop({ required: true, type: Reward, default: [], _id: false}) - rankGoods: Array; + rankGoods: Reward[]; - public static async updatePvpSeasonResult(roleId: string, update: pvpUpdate , lean = true) { - let result: PvpSeasonResultType = await PvpSeasonResultModel.findOneAndUpdate({roleId}, {$set: update}, {upsert: true, new: true}).lean(lean); + @prop({ required: true }) + newScore: number; + + @prop({ required: true, type: () => HeroScore, default:[] }) + newHeroScores: HeroScore[]; + + public static async updatePvpSeasonResult(roleId: string, seasonNum: number, update: PvpSeasonResultUpdate , lean = true) { + let result: PvpSeasonResultType = await PvpSeasonResultModel.findOneAndUpdate({roleId, seasonNum}, {$set: update}, {upsert: true, new: true}).lean(lean); return result; } - public static async getPvpSeasonResult(roleId: string, lean = true) { - let result: PvpSeasonResultType = await PvpSeasonResultModel.findOne({roleId}).lean(lean); + public static async getPvpSeasonResult(roleId: string, seasonNum: number, lean = true) { + let result: PvpSeasonResultType = await PvpSeasonResultModel.findOne({ roleId, seasonNum }).lean(lean); return result; } } export const PvpSeasonResultModel = getModelForClass(PvpSeasonResult); -export interface PvpSeasonResultType extends Pick, keyof PvpSeasonResult> { }; \ No newline at end of file +export interface PvpSeasonResultType extends Pick, keyof PvpSeasonResult> { }; +export type PvpSeasonResultUpdate = Partial; \ No newline at end of file diff --git a/shared/db/Role.ts b/shared/db/Role.ts index fb247ec0d..78343427f 100644 --- a/shared/db/Role.ts +++ b/shared/db/Role.ts @@ -732,6 +732,14 @@ export default class Role extends BaseModel { const role: RoleType = await RoleModel.findOneAndUpdate({ roleId }, { $addToSet: { guide: { $each: ids } } }, { new: true }).lean(); return role; } + + // 用于远征匹配 + public static async findByCeScale(min: number, max: number) { + const result: RoleType[] = await RoleModel.find({ topLineupCe: { $lte: max, $gte: min } }) + .populate('topLineup.hero') + .sort({ updatedAt: -1 }).limit(100).lean({ getters: true, virtuals: true }); + return result; + } } export const RoleModel = getModelForClass(Role); diff --git a/shared/db/SystemConfig.ts b/shared/db/SystemConfig.ts index a1f6d8b5b..2fe9746f2 100644 --- a/shared/db/SystemConfig.ts +++ b/shared/db/SystemConfig.ts @@ -6,17 +6,23 @@ import { COUNTER } from '../consts'; @index({ id: 1 }) @index({ seasonNum: 1 }) export default class PVPConfig extends BaseModel { - @prop({ required: true, default: 1 }) - id: number; - @prop({ required: true }) - warId: number; // 地图 + @prop({ required: true, default: 1 }) seasonNum: number; // 赛季 - @prop({ required: true }) - seasonEndTime: number; //赛季结束的时间 - @prop({ required: false }) - settleGuildWeeklyTime: number; + @prop({ required: true }) + seasonStartTime: number; // 赛季开始时间 + + @prop({ required: true }) + seasonRewardTime: number; // 结算奖励时间 + + @prop({ required: true }) + seasonEndTime: number; // 赛季结束的时间 + + @prop({ required: true }) + hasSettleReward: boolean; // 赛季结束的时间 + + public static async findCurPVPConfig() { let seasonNum = await CounterModel.getCounter(COUNTER.PVP_SEASON_NUM); const result: PVPConfigType = await PVPConfigModel.findOne({ seasonNum }).lean(true); @@ -28,13 +34,19 @@ export default class PVPConfig extends BaseModel { return result; } - public static async createPVPConfig(seasonNum: number, seasonEndTime: number, warId: number) { - const result: PVPConfigType = await PVPConfigModel.findOneAndUpdate({ seasonNum }, { warId, seasonEndTime }, { upsert: true, new: true }).lean(true); + public static async createPVPConfig(seasonNum: number, seasonStartTime: number, seasonRewardTime: number, seasonEndTime: number) { + const result: PVPConfigType = await PVPConfigModel.findOneAndUpdate({ seasonNum }, { seasonStartTime, seasonRewardTime, seasonEndTime, hasSettleReward: false }, { upsert: true, new: true }).lean(true); return result; } - public static async updatePVPConfig(seasonNum: number, update: { warId?: number, settleGuildWeeklyTime?: number }) { - const result: PVPConfigType = await PVPConfigModel.findOneAndUpdate({ seasonNum }, update, { new: true }).lean(true); + public static async setReward(seasonNum: number) { + const result: PVPConfigType = await PVPConfigModel.findOneAndUpdate({ seasonNum }, { hasSettleReward: true }, { new: true }).lean(true); + return result; + } + + public static async setCurPvpConfig(update: PVPConfigUpdate) { + let seasonNum = await CounterModel.getCounter(COUNTER.PVP_SEASON_NUM); + const result: PVPConfigType = await PVPConfigModel.findOneAndUpdate({ seasonNum }, update).lean(true); return result; } } @@ -43,4 +55,5 @@ export const PVPConfigModel = getModelForClass(PVPConfig); export interface PVPConfigType extends Pick, keyof PVPConfig> { id: number; -}; \ No newline at end of file +}; +export type PVPConfigUpdate = Partial; // 将所有字段变成可选项 diff --git a/shared/domain/battleField/pvp.ts b/shared/domain/battleField/pvp.ts new file mode 100644 index 000000000..bc167795b --- /dev/null +++ b/shared/domain/battleField/pvp.ts @@ -0,0 +1,214 @@ +import { prop, Ref, mongoose } from '@typegoose/typegoose'; +import Hero, { } from '../../db/Hero'; +import { PvpDefenseType } from '../../db/PvpDefense'; +import PvpHistoryOpp from '../../db/PvpHistoryOpp'; +import { PvpSeasonResultType } from '../../db/PvpSeasonResult'; +import { RewardInter } from '../../pubUtils/interface'; + + +// 防守阵容武将 +export class DefenseHero { + @prop({ required: true }) + actorId: number; // 武将id + @prop({ required: true }) + ai: number; // ai逻辑,1-进攻型 2-防守型 + @prop({ required: true }) + dataId: number; + @prop({ required: true }) + order: number; + @prop({ ref: 'Hero', type: mongoose.Schema.Types.ObjectId }) + hero: Ref; +} + +// 防守阵容 +export class Defense { + @prop({ required: true }) + warId: number; + @prop({ required: true }) + buff: number; + @prop({ required: true, type: DefenseHero, _id: false }) + heroes: DefenseHero[]; + @prop({ required: true }) + score: number; // 防守阵容的总军功 + @prop({ required: true }) + pLv: number; // 防守阵容的等级 +} + +// 挑战阵容武将 +export class AttackHero { + @prop({ required: true }) + actorId: number; // 武将id + @prop({ required: true }) + order: number; +} + +// 挑战阵容 +export class Attack { + @prop({ required: true, type: AttackHero, _id: false }) + heroes: AttackHero[]; + @prop({ required: true }) + score: number; // 防守阵容的总军功 + @prop({ required: true }) + pLv: number; // 防守阵容的等级 +} + +// 两个阵容中的武将的分别的战力 +export class LineupCe { + @prop({ required: true }) + hid: number; // 武将id + @prop({ required: true }) + ce: number; // 战力 +} + +export class OppPlayer { + @prop({ required: true }) + roleId: string; + @prop({ ref: 'PvpHistoryOpp', type: mongoose.Schema.Types.ObjectId }) + oppDef: Ref; + @prop({ required: true }) + pos: number; + @prop({ required: true }) + isRobot: boolean; +} + +export class HeroScore { + @prop({ required: true }) + hid: number; + @prop({ required: true }) + score: number; +} + +export class Reward { + @prop({ required: true }) + id: number; + @prop({ required: true }) + count: number; +} + +export class HeroReward { + @prop({ required: true }) + hid: number; + @prop({ required: true }) + id: number; + @prop({ required: true }) + count: number; +} + +export class OppPlayerReturn { + pos: number; + roleId: string; + roleName: string; + head: number; + frame: number; + spine: number; + lv: number; + pLv: number; + defCe: number; + rankLv: number; + addScore: number; + plusScore: number; +} + +// 防守阵容武将 +export class DefenseHeroReturn { + actorId: number; // 武将id + ai: number; // ai逻辑,1-进攻型 2-防守型 + dataId: number; + order: number; +} + +export class DefenseLineupReturn { + warId: number; + buff: number; + heroes: DefenseHeroReturn[]; + score: number; + pLv: number; + ce: number; +} + +export class AttackLineupReturn { + warId: number; + buff: number; + heroes: AttackHero[]; + score: number; + pLv: number; + ce: number; +} + +export class heroScoreReturn extends HeroScore { + isDefense: boolean; +} + +export class SeasonDataReturn { + score: number; + heroScores: HeroScore[]; + seasonNum: number; + seasonEndTime: number; + rankLv: number; + + constructor(pvpSeasonResult: PvpSeasonResultType) { + this.score = pvpSeasonResult.score; + this.heroScores = pvpSeasonResult.heroScores; + this.seasonNum = pvpSeasonResult.seasonNum; + this.seasonEndTime = pvpSeasonResult.seasonEndTime; + this.rankLv = pvpSeasonResult.rankLv; + } +} + +export class PvpSeasonResultRecord { + oldSeasonData: SeasonDataReturn; + heroGoods: HeroReward[]; + rankGoods: RewardInter[]; + constructor(pvpSeasonResult: PvpSeasonResultType) { + this.oldSeasonData = new SeasonDataReturn(pvpSeasonResult); + this.heroGoods = pvpSeasonResult.heroGoods; + this.rankGoods = pvpSeasonResult.rankGoods; + } +} + +export class PvpDataReturn { + seasonNum: number; + seasonEndTime: number; + myRank: number = 0; + oppPlayers: OppPlayerReturn[] = []; + defense: DefenseLineupReturn = null; + attack: AttackLineupReturn = null; + score: number = 0; + winStreakNum: number = 0; + refOppCnt: number; + setAttackCnt: number; + challengeCnt: number; + challengeRefTime: number; + receiveBox: number[] = []; + hisScore: number = 0; + heroScores: heroScoreReturn[] = []; + isFirstEntry: boolean = false; + resultRecord: PvpSeasonResultRecord; + + constructor(pvpDefense: PvpDefenseType) { + this.score = pvpDefense.score; + this.winStreakNum = pvpDefense.winStreakNum; + this.receiveBox = pvpDefense.receivedBox; + this.hisScore = pvpDefense.hisScore; + // this.oppPlayers + // this.heroScores + + } + + setOppPlayers(oppPlayers: OppPlayerReturn[]) { + this.oppPlayers = oppPlayers; + } + + setMyRank(rankLv: number) { + this.myRank = rankLv; + } + + setPvpConfig(seasonNum: number, seasonEndTime: number) { + this.seasonNum = seasonNum; + this.seasonEndTime = seasonEndTime; + } + + setPvpSeasonResult(pvpSeasonResult: PvpSeasonResultType) { + this.resultRecord = new PvpSeasonResultRecord(pvpSeasonResult); + } +} \ No newline at end of file diff --git a/shared/domain/dbGeneral.ts b/shared/domain/dbGeneral.ts index 1d1f40c12..f657bd1f8 100644 --- a/shared/domain/dbGeneral.ts +++ b/shared/domain/dbGeneral.ts @@ -41,8 +41,8 @@ export class PvpHeroInfo { this.quality = hero.quality; } - setRobotInfo(warjson: DicWarJson, lv: number, initialStar: number, quality: number) { - this.actorId = warjson.actorId; + setRobotInfo(warjson: DicWarJson, actorId: number, lv: number, initialStar: number, quality: number) { + this.actorId = actorId; this.skinId = warjson.actorId; this.actorName = warjson.actorName; this.star = initialStar; diff --git a/shared/domain/roleField/task.ts b/shared/domain/roleField/task.ts index 1db7bd313..1d0921870 100644 --- a/shared/domain/roleField/task.ts +++ b/shared/domain/roleField/task.ts @@ -1,4 +1,4 @@ -import { HeroScores } from "../../db/PvpHistoryOpp"; +import { HeroScore } from "../../domain/battleField/pvp"; export class TaskParam { star?: number; @@ -17,7 +17,7 @@ export class TaskParam { dailyType?: number; point?: number; gid?: number; - heroScores?: HeroScores[]; + heroScores?: HeroScore[]; rankLv?: number; title?: number; job?: number; diff --git a/shared/pubUtils/data.ts b/shared/pubUtils/data.ts index f641a19f3..3e7c9248f 100644 --- a/shared/pubUtils/data.ts +++ b/shared/pubUtils/data.ts @@ -38,7 +38,6 @@ import { dicHeroScroll, preHeroScroll, loadHeroScroll } from './dictionary/DicHe import { dicPvpOpponent, loadPvpOpponent } from './dictionary/DicPvpOpponent'; import { dicPvpTeamLevel, loadPvpTeamLevel } from './dictionary/DicPvpTeamLevel'; import { dicPvpRefreshConsume, maxPvpRefreshCnt, loadPvpRefreshConsume } from './dictionary/DicPvpRefreshConsume'; -import { dicGkPvp, dicGkPvps, loadGkPvp } from './dictionary/DicGkPvp'; import { dicHeroRewads, loadPvpHeroReward } from './dictionary/DicPvpHeroReward'; import { dicRankRewads, dicRankMax, loadPvpRankReward } from './dictionary/DicPvpRankReward'; import { dicPvpBoxs, loadPvpBox } from './dictionary/DicPvpBox'; @@ -153,8 +152,6 @@ export const gameData = { pvpWar: dicWarPvp, pvpRefreshConsume: dicPvpRefreshConsume, maxPvpRefreshCnt: maxPvpRefreshCnt, - pvpGk: dicGkPvp, - pvpGks: dicGkPvps, pvpHeroRewards: dicHeroRewads, pvpRankRewards: dicRankRewads, pvpBoxs: dicPvpBoxs, @@ -450,21 +447,22 @@ export function getPLvByScore(score: number) { return lv; } -export function getPvpGkByWarId(warId: number) { - return gameData.pvpGk.get(warId); +export function getPvpHeroRewardsByScore(score: number) { + for (let item of gameData.pvpHeroRewards) { + if ((item.max >= score || item.max == -1) && score >= item.min) { + return item; + } + } + return null } -export function getPvpGkWarIds() { - let warIds = gameData.pvpGks; - return warIds; -} - -export function getPvpHeroRewards() { - return gameData.pvpHeroRewards; -} - -export function getPvpRankRewards() { - return gameData.pvpRankRewards; +export function getPvpRankRewardsByRank(rankLv: number) { + for (let item of gameData.pvpRankRewards) { + if ((item.max >= rankLv || item.max == -1) && rankLv >= item.min) { + return item; + } + } + return gameData.pvpRankMax.max; } export function getPvpBoxs() { @@ -876,7 +874,6 @@ function loadDatas() { loadPvpOpponent(); loadPvpTeamLevel(); loadPvpRefreshConsume(); - loadGkPvp(); loadPvpHeroReward(); loadPvpRankReward(); loadPvpBox(); diff --git a/shared/pubUtils/dictionary/DicGkPvp.ts b/shared/pubUtils/dictionary/DicGkPvp.ts deleted file mode 100644 index 01122c7b6..000000000 --- a/shared/pubUtils/dictionary/DicGkPvp.ts +++ /dev/null @@ -1,23 +0,0 @@ -import { readFileAndParse } from '../util' -import { FILENAME } from '../../consts' - -export interface DicGkPvp { - readonly war_id: number; - readonly dispatchJsonId: number; - readonly bg_img_id: number; - readonly warType: number; -} - -export const dicGkPvp = new Map(); -export const dicGkPvps = new Array(); -export function loadGkPvp() { - dicGkPvp.clear(); - dicGkPvps.splice(0, dicGkPvps.length); - let arr = readFileAndParse(FILENAME.DIC_GK_PVP); - - arr.forEach(o => { - dicGkPvp.set(o.war_id, o); - dicGkPvps.push(o.war_id); - }); - arr = undefined; -} diff --git a/shared/pubUtils/dictionary/DicWarJson.ts b/shared/pubUtils/dictionary/DicWarJson.ts index 6dc023743..986664213 100644 --- a/shared/pubUtils/dictionary/DicWarJson.ts +++ b/shared/pubUtils/dictionary/DicWarJson.ts @@ -1,5 +1,5 @@ // 关卡表 -import {decodeArrayListStr, readWarJsonFileAndParse} from '../util' +import {decodeArrayListStr, parseNumberList, readWarJsonFileAndParse} from '../util' export interface DicWarJson { @@ -47,6 +47,8 @@ export interface DicWarJson { readonly callSkillData: string; // 敌军数量 readonly enemyCount: number; + // pvp中随机敌军 + readonly randomEnemy: number[]; } export const dicWarJson = new Map>(); @@ -63,6 +65,7 @@ export function loadWarJson() { if(o.relation == 2) enemyCount++; }); arr.forEach(o => { + o.randomEnemy = parseNumberList(o.randomEnemy); o.enemyCount = enemyCount; warjson.push(o); }); diff --git a/shared/pubUtils/interface.ts b/shared/pubUtils/interface.ts index 83ca9555f..ee4d8e5f2 100644 --- a/shared/pubUtils/interface.ts +++ b/shared/pubUtils/interface.ts @@ -29,20 +29,6 @@ export interface SclResultInter { position: SclPosInter[] } -// pvp对手返回 -export interface oppPlayersInter { - pos: number; // 对手位置 - roleId: string; // 对手玩家id - roleName: string; // 对手玩家名 - head: number; // 头像 - frame: number; // 相框 - spine: number; // 形象 - pLv: number; // 对手队伍等级 - defCe: number; // 防守阵容战力 - addScore: number; // 战胜后可获军功 - plusScore: number; // 连胜加成军功 - rankLv: number; -} export interface pvpEndParamInter { hid: number; diff --git a/shared/resource/jsons/dic_zyz_pvp_difficultRatio.json b/shared/resource/jsons/dic_zyz_pvp_difficultRatio.json new file mode 100644 index 000000000..38e994cc8 --- /dev/null +++ b/shared/resource/jsons/dic_zyz_pvp_difficultRatio.json @@ -0,0 +1,44 @@ +[ + { + "id": 1, + "teamLineupMin": 0, + "teamLineupMax": 500, + "value": 10000, + "enemyLv": 10 + }, + { + "id": 2, + "teamLineupMin": 501, + "teamLineupMax": 1020, + "value": 15000, + "enemyLv": 15 + }, + { + "id": 3, + "teamLineupMin": 1021, + "teamLineupMax": 1560, + "value": 20000, + "enemyLv": 20 + }, + { + "id": 4, + "teamLineupMin": 1561, + "teamLineupMax": 2120, + "value": 25000, + "enemyLv": 25 + }, + { + "id": 5, + "teamLineupMin": 2121, + "teamLineupMax": 2700, + "value": 30000, + "enemyLv": 30 + }, + { + "id": 6, + "teamLineupMin": 2701, + "teamLineupMax": 3000, + "value": 35000, + "enemyLv": 35 + } +] \ No newline at end of file diff --git a/shared/resource/warJsons/4501.json b/shared/resource/warJsons/4501.json index 96e403610..22850dae5 100644 --- a/shared/resource/warJsons/4501.json +++ b/shared/resource/warJsons/4501.json @@ -17,7 +17,8 @@ "skill": 0, "seid": "&", "star": 0, - "spine": 0 + "spine": 0, + "randomEnemy": "&" }, { "warId": 4501, @@ -37,7 +38,8 @@ "skill": 0, "seid": "&", "star": 0, - "spine": 0 + "spine": 0, + "randomEnemy": "&" }, { "warId": 4501, @@ -57,7 +59,8 @@ "skill": 0, "seid": "&", "star": 0, - "spine": 0 + "spine": 0, + "randomEnemy": "&" }, { "warId": 4501, @@ -77,7 +80,8 @@ "skill": 0, "seid": "&", "star": 0, - "spine": 0 + "spine": 0, + "randomEnemy": "&" }, { "warId": 4501, @@ -97,7 +101,8 @@ "skill": 0, "seid": "&", "star": 0, - "spine": 0 + "spine": 0, + "randomEnemy": "&" }, { "warId": 4501, @@ -117,7 +122,8 @@ "skill": 0, "seid": "&", "star": 0, - "spine": 0 + "spine": 0, + "randomEnemy": "&" }, { "warId": 4501, @@ -137,7 +143,8 @@ "skill": 0, "seid": "&", "star": 0, - "spine": 0 + "spine": 0, + "randomEnemy": "&" }, { "warId": 4501, @@ -157,7 +164,8 @@ "skill": 0, "seid": "&", "star": 0, - "spine": 0 + "spine": 0, + "randomEnemy": "&" }, { "warId": 4501, @@ -177,12 +185,13 @@ "skill": 0, "seid": "&", "star": 0, - "spine": 0 + "spine": 0, + "randomEnemy": "&" }, { "warId": 4501, - "actorName": "曹操", - "actorId": 301, + "actorName": "敌军", + "actorId": 0, "dataId": 2001, "relation": 2, "outIndex": 0, @@ -193,16 +202,17 @@ "lv": 0, "hide": 0, "initial_ai": 1, - "attribute": "1&3000|2&600|4&250|5&250|9&0|10&25000|11&20000|12&0|13&10000|14&10000|18&0", + "attribute": "&", "skill": 0, "seid": "&", "star": 0, - "spine": 0 + "spine": 0, + "randomEnemy": "301&306&307" }, { "warId": 4501, - "actorName": "郭嘉", - "actorId": 305, + "actorName": "敌军", + "actorId": 0, "dataId": 2002, "relation": 2, "outIndex": 1, @@ -213,16 +223,17 @@ "lv": 0, "hide": 0, "initial_ai": 1, - "attribute": "1&5000|2&400|4&600|5&600|9&0|10&10000|11&30000|12&10000|13&0|14&20000|18&0", + "attribute": "&", "skill": 0, "seid": "&", "star": 0, - "spine": 0 + "spine": 0, + "randomEnemy": "305&312" }, { "warId": 4501, - "actorName": "张飞", - "actorId": 317, + "actorName": "敌军", + "actorId": 0, "dataId": 2003, "relation": 2, "outIndex": 2, @@ -233,16 +244,17 @@ "lv": 0, "hide": 0, "initial_ai": 1, - "attribute": "1&2500|2&700|4&200|5&200|9&0|10&20000|11&10000|12&0|13&10000|14&0|18&0", + "attribute": "&", "skill": 0, "seid": "&", "star": 0, - "spine": 0 + "spine": 0, + "randomEnemy": "317&314&318&320&321" }, { "warId": 4501, - "actorName": "黄忠", - "actorId": 321, + "actorName": "敌军", + "actorId": 0, "dataId": 2004, "relation": 2, "outIndex": 3, @@ -253,16 +265,17 @@ "lv": 0, "hide": 0, "initial_ai": 1, - "attribute": "1&4000|2&500|4&300|5&300|9&10000|10&0|11&0|12&0|13&5000|14&0|18&0", + "attribute": "&", "skill": 0, "seid": "&", "star": 0, - "spine": 0 + "spine": 0, + "randomEnemy": "321&333&334&335" }, { "warId": 4501, - "actorName": "华佗", - "actorId": 346, + "actorName": "敌军", + "actorId": 0, "dataId": 2005, "relation": 2, "outIndex": 4, @@ -273,11 +286,12 @@ "lv": 0, "hide": 0, "initial_ai": 1, - "attribute": "1&3500|2&500|4&400|5&400|9&0|10&0|11&0|12&0|13&0|14&10000|18&0", + "attribute": "&", "skill": 0, "seid": "&", "star": 0, - "spine": 0 + "spine": 0, + "randomEnemy": "346&" }, { "warId": 4501, @@ -297,7 +311,8 @@ "skill": 0, "seid": "&", "star": 0, - "spine": 0 + "spine": 0, + "randomEnemy": "&" }, { "warId": 4501, @@ -317,7 +332,8 @@ "skill": 0, "seid": "&", "star": 0, - "spine": 0 + "spine": 0, + "randomEnemy": "&" }, { "warId": 4501, @@ -337,7 +353,8 @@ "skill": 0, "seid": "&", "star": 0, - "spine": 0 + "spine": 0, + "randomEnemy": "340&341&342" }, { "warId": 4501, @@ -357,6 +374,7 @@ "skill": 0, "seid": "&", "star": 0, - "spine": 0 + "spine": 0, + "randomEnemy": "&" } ] \ No newline at end of file diff --git a/shared/resource/warJsons/4502.json b/shared/resource/warJsons/4502.json index e375bfb10..214f47bab 100644 --- a/shared/resource/warJsons/4502.json +++ b/shared/resource/warJsons/4502.json @@ -7,9 +7,9 @@ "relation": 0, "outIndex": 0, "dirction": 2, - "x": 6, - "y": 8, - "var": 0, + "x": 4, + "y": 6, + "var": 501, "lv": 0, "hide": 0, "initial_ai": 1, @@ -17,7 +17,8 @@ "skill": 0, "seid": "&", "star": 0, - "spine": 0 + "spine": 0, + "randomEnemy": "&" }, { "warId": 4502, @@ -27,9 +28,9 @@ "relation": 0, "outIndex": 1, "dirction": 2, - "x": 7, - "y": 8, - "var": 1, + "x": 5, + "y": 6, + "var": 502, "lv": 0, "hide": 0, "initial_ai": 1, @@ -37,7 +38,8 @@ "skill": 0, "seid": "&", "star": 0, - "spine": 0 + "spine": 0, + "randomEnemy": "&" }, { "warId": 4502, @@ -47,9 +49,9 @@ "relation": 0, "outIndex": 2, "dirction": 2, - "x": 7, - "y": 7, - "var": 2, + "x": 5, + "y": 5, + "var": 503, "lv": 0, "hide": 0, "initial_ai": 1, @@ -57,7 +59,8 @@ "skill": 0, "seid": "&", "star": 0, - "spine": 0 + "spine": 0, + "randomEnemy": "&" }, { "warId": 4502, @@ -67,9 +70,9 @@ "relation": 0, "outIndex": 3, "dirction": 2, - "x": 6, - "y": 6, - "var": 3, + "x": 4, + "y": 4, + "var": 504, "lv": 0, "hide": 0, "initial_ai": 1, @@ -77,7 +80,8 @@ "skill": 0, "seid": "&", "star": 0, - "spine": 0 + "spine": 0, + "randomEnemy": "&" }, { "warId": 4502, @@ -87,9 +91,9 @@ "relation": 0, "outIndex": 4, "dirction": 2, - "x": 7, - "y": 6, - "var": 4, + "x": 5, + "y": 4, + "var": 505, "lv": 0, "hide": 0, "initial_ai": 1, @@ -97,7 +101,8 @@ "skill": 0, "seid": "&", "star": 0, - "spine": 0 + "spine": 0, + "randomEnemy": "&" }, { "warId": 4502, @@ -107,9 +112,9 @@ "relation": 0, "outIndex": 5, "dirction": 2, - "x": 5, - "y": 8, - "var": 5, + "x": 3, + "y": 6, + "var": 506, "lv": 0, "hide": 0, "initial_ai": 1, @@ -117,7 +122,8 @@ "skill": 0, "seid": "&", "star": 0, - "spine": 0 + "spine": 0, + "randomEnemy": "&" }, { "warId": 4502, @@ -127,9 +133,9 @@ "relation": 0, "outIndex": 6, "dirction": 2, - "x": 5, - "y": 7, - "var": 6, + "x": 3, + "y": 5, + "var": 507, "lv": 0, "hide": 0, "initial_ai": 1, @@ -137,7 +143,8 @@ "skill": 0, "seid": "&", "star": 0, - "spine": 0 + "spine": 0, + "randomEnemy": "&" }, { "warId": 4502, @@ -147,9 +154,9 @@ "relation": 0, "outIndex": 7, "dirction": 2, - "x": 6, - "y": 7, - "var": 7, + "x": 4, + "y": 5, + "var": 508, "lv": 0, "hide": 0, "initial_ai": 1, @@ -157,7 +164,8 @@ "skill": 0, "seid": "&", "star": 0, - "spine": 0 + "spine": 0, + "randomEnemy": "&" }, { "warId": 4502, @@ -167,9 +175,9 @@ "relation": 0, "outIndex": 8, "dirction": 2, - "x": 5, - "y": 6, - "var": 8, + "x": 3, + "y": 4, + "var": 509, "lv": 0, "hide": 0, "initial_ai": 1, @@ -177,107 +185,113 @@ "skill": 0, "seid": "&", "star": 0, - "spine": 0 + "spine": 0, + "randomEnemy": "&" }, { "warId": 4502, - "actorName": "曹操", - "actorId": 301, + "actorName": "敌军", + "actorId": 0, "dataId": 2001, "relation": 2, "outIndex": 0, "dirction": 1, - "x": 13, - "y": 8, - "var": 2001, + "x": 12, + "y": 6, + "var": 1501, "lv": 0, "hide": 0, "initial_ai": 1, - "attribute": "1&3000|2&600|4&250|5&250|9&0|10&25000|11&20000|12&0|13&10000|14&10000|18&0", + "attribute": "&", "skill": 0, "seid": "&", "star": 0, - "spine": 0 + "spine": 0, + "randomEnemy": "&" }, { "warId": 4502, - "actorName": "郭嘉", - "actorId": 305, + "actorName": "敌军", + "actorId": 0, "dataId": 2002, "relation": 2, "outIndex": 1, "dirction": 1, - "x": 14, - "y": 8, - "var": 2002, + "x": 13, + "y": 6, + "var": 1502, "lv": 0, "hide": 0, "initial_ai": 1, - "attribute": "1&5000|2&400|4&600|5&600|9&0|10&10000|11&30000|12&10000|13&0|14&20000|18&0", + "attribute": "&", "skill": 0, "seid": "&", "star": 0, - "spine": 0 + "spine": 0, + "randomEnemy": "305&312" }, { "warId": 4502, - "actorName": "张飞", - "actorId": 317, + "actorName": "敌军", + "actorId": 0, "dataId": 2003, "relation": 2, "outIndex": 2, "dirction": 1, "x": 13, - "y": 7, - "var": 2003, + "y": 5, + "var": 1503, "lv": 0, "hide": 0, "initial_ai": 1, - "attribute": "1&2500|2&700|4&200|5&200|9&0|10&20000|11&10000|12&0|13&10000|14&0|18&0", + "attribute": "&", "skill": 0, "seid": "&", "star": 0, - "spine": 0 + "spine": 0, + "randomEnemy": "317&314&318&320&321" }, { "warId": 4502, - "actorName": "黄忠", - "actorId": 321, + "actorName": "敌军", + "actorId": 0, "dataId": 2004, "relation": 2, "outIndex": 3, "dirction": 1, - "x": 12, - "y": 6, - "var": 2004, + "x": 11, + "y": 4, + "var": 1504, "lv": 0, "hide": 0, "initial_ai": 1, - "attribute": "1&4000|2&500|4&300|5&300|9&10000|10&0|11&0|12&0|13&5000|14&0|18&0", + "attribute": "&", "skill": 0, "seid": "&", "star": 0, - "spine": 0 + "spine": 0, + "randomEnemy": "321&333&334&335" }, { "warId": 4502, - "actorName": "华佗", - "actorId": 346, + "actorName": "敌军", + "actorId": 0, "dataId": 2005, "relation": 2, "outIndex": 4, "dirction": 1, - "x": 13, - "y": 6, - "var": 2005, + "x": 12, + "y": 4, + "var": 1505, "lv": 0, "hide": 0, "initial_ai": 1, - "attribute": "1&3500|2&500|4&400|5&400|9&0|10&0|11&0|12&0|13&0|14&10000|18&0", + "attribute": "&", "skill": 0, "seid": "&", "star": 0, - "spine": 0 + "spine": 0, + "randomEnemy": "&" }, { "warId": 4502, @@ -287,9 +301,9 @@ "relation": 2, "outIndex": 5, "dirction": 1, - "x": 12, - "y": 8, - "var": 2006, + "x": 13, + "y": 4, + "var": 1506, "lv": 0, "hide": 0, "initial_ai": 1, @@ -297,7 +311,8 @@ "skill": 0, "seid": "&", "star": 0, - "spine": 0 + "spine": 0, + "randomEnemy": "321&333&334&335" }, { "warId": 4502, @@ -307,9 +322,9 @@ "relation": 2, "outIndex": 6, "dirction": 1, - "x": 12, - "y": 7, - "var": 2007, + "x": 11, + "y": 6, + "var": 1507, "lv": 0, "hide": 0, "initial_ai": 1, @@ -317,7 +332,8 @@ "skill": 0, "seid": "&", "star": 0, - "spine": 0 + "spine": 0, + "randomEnemy": "&" }, { "warId": 4502, @@ -327,9 +343,9 @@ "relation": 2, "outIndex": 7, "dirction": 1, - "x": 14, - "y": 7, - "var": 2008, + "x": 11, + "y": 5, + "var": 1508, "lv": 0, "hide": 0, "initial_ai": 1, @@ -337,7 +353,8 @@ "skill": 0, "seid": "&", "star": 0, - "spine": 0 + "spine": 0, + "randomEnemy": "340&341&342" }, { "warId": 4502, @@ -347,9 +364,9 @@ "relation": 2, "outIndex": 8, "dirction": 1, - "x": 14, - "y": 6, - "var": 2009, + "x": 12, + "y": 5, + "var": 1509, "lv": 0, "hide": 0, "initial_ai": 1, @@ -357,6 +374,7 @@ "skill": 0, "seid": "&", "star": 0, - "spine": 0 + "spine": 0, + "randomEnemy": "301&306&307" } ] \ No newline at end of file diff --git a/shared/resource/warJsons/4503.json b/shared/resource/warJsons/4503.json index 8ec2d62da..965383fe7 100644 --- a/shared/resource/warJsons/4503.json +++ b/shared/resource/warJsons/4503.json @@ -7,8 +7,8 @@ "relation": 0, "outIndex": 0, "dirction": 2, - "x": 2, - "y": 6, + "x": 6, + "y": 8, "var": 0, "lv": 0, "hide": 0, @@ -17,7 +17,8 @@ "skill": 0, "seid": "&", "star": 0, - "spine": 0 + "spine": 0, + "randomEnemy": "&" }, { "warId": 4503, @@ -27,8 +28,8 @@ "relation": 0, "outIndex": 1, "dirction": 2, - "x": 3, - "y": 6, + "x": 7, + "y": 8, "var": 1, "lv": 0, "hide": 0, @@ -37,7 +38,8 @@ "skill": 0, "seid": "&", "star": 0, - "spine": 0 + "spine": 0, + "randomEnemy": "&" }, { "warId": 4503, @@ -47,8 +49,8 @@ "relation": 0, "outIndex": 2, "dirction": 2, - "x": 4, - "y": 6, + "x": 7, + "y": 7, "var": 2, "lv": 0, "hide": 0, @@ -57,7 +59,8 @@ "skill": 0, "seid": "&", "star": 0, - "spine": 0 + "spine": 0, + "randomEnemy": "&" }, { "warId": 4503, @@ -67,8 +70,8 @@ "relation": 0, "outIndex": 3, "dirction": 2, - "x": 2, - "y": 5, + "x": 6, + "y": 6, "var": 3, "lv": 0, "hide": 0, @@ -77,7 +80,8 @@ "skill": 0, "seid": "&", "star": 0, - "spine": 0 + "spine": 0, + "randomEnemy": "&" }, { "warId": 4503, @@ -87,8 +91,8 @@ "relation": 0, "outIndex": 4, "dirction": 2, - "x": 3, - "y": 5, + "x": 7, + "y": 6, "var": 4, "lv": 0, "hide": 0, @@ -97,7 +101,8 @@ "skill": 0, "seid": "&", "star": 0, - "spine": 0 + "spine": 0, + "randomEnemy": "&" }, { "warId": 4503, @@ -107,8 +112,8 @@ "relation": 0, "outIndex": 5, "dirction": 2, - "x": 4, - "y": 5, + "x": 5, + "y": 8, "var": 5, "lv": 0, "hide": 0, @@ -117,7 +122,8 @@ "skill": 0, "seid": "&", "star": 0, - "spine": 0 + "spine": 0, + "randomEnemy": "&" }, { "warId": 4503, @@ -127,8 +133,8 @@ "relation": 0, "outIndex": 6, "dirction": 2, - "x": 2, - "y": 4, + "x": 5, + "y": 7, "var": 6, "lv": 0, "hide": 0, @@ -137,7 +143,8 @@ "skill": 0, "seid": "&", "star": 0, - "spine": 0 + "spine": 0, + "randomEnemy": "&" }, { "warId": 4503, @@ -147,8 +154,8 @@ "relation": 0, "outIndex": 7, "dirction": 2, - "x": 3, - "y": 4, + "x": 6, + "y": 7, "var": 7, "lv": 0, "hide": 0, @@ -157,7 +164,8 @@ "skill": 0, "seid": "&", "star": 0, - "spine": 0 + "spine": 0, + "randomEnemy": "&" }, { "warId": 4503, @@ -167,8 +175,8 @@ "relation": 0, "outIndex": 8, "dirction": 2, - "x": 4, - "y": 4, + "x": 5, + "y": 6, "var": 8, "lv": 0, "hide": 0, @@ -177,107 +185,113 @@ "skill": 0, "seid": "&", "star": 0, - "spine": 0 + "spine": 0, + "randomEnemy": "&" }, { "warId": 4503, - "actorName": "曹操", - "actorId": 301, + "actorName": "敌军", + "actorId": 0, "dataId": 2001, "relation": 2, "outIndex": 0, "dirction": 1, - "x": 11, - "y": 6, + "x": 13, + "y": 8, "var": 2001, "lv": 0, "hide": 0, "initial_ai": 1, - "attribute": "1&3000|2&600|4&250|5&250|9&0|10&25000|11&20000|12&0|13&10000|14&10000|18&0", + "attribute": "&", "skill": 0, "seid": "&", "star": 0, - "spine": 0 + "spine": 0, + "randomEnemy": "301&306&307" }, { "warId": 4503, - "actorName": "郭嘉", - "actorId": 305, + "actorName": "敌军", + "actorId": 0, "dataId": 2002, "relation": 2, "outIndex": 1, "dirction": 1, - "x": 12, - "y": 6, + "x": 14, + "y": 8, "var": 2002, "lv": 0, "hide": 0, "initial_ai": 1, - "attribute": "1&5000|2&400|4&600|5&600|9&0|10&10000|11&30000|12&10000|13&0|14&20000|18&0", + "attribute": "&", "skill": 0, "seid": "&", "star": 0, - "spine": 0 + "spine": 0, + "randomEnemy": "305&312" }, { "warId": 4503, - "actorName": "张飞", - "actorId": 317, + "actorName": "敌军", + "actorId": 0, "dataId": 2003, "relation": 2, "outIndex": 2, "dirction": 1, "x": 13, - "y": 6, + "y": 7, "var": 2003, "lv": 0, "hide": 0, "initial_ai": 1, - "attribute": "1&2500|2&700|4&200|5&200|9&0|10&20000|11&10000|12&0|13&10000|14&0|18&0", + "attribute": "&", "skill": 0, "seid": "&", "star": 0, - "spine": 0 + "spine": 0, + "randomEnemy": "317&314&318&320&321" }, { "warId": 4503, - "actorName": "黄忠", - "actorId": 321, + "actorName": "敌军", + "actorId": 0, "dataId": 2004, "relation": 2, "outIndex": 3, "dirction": 1, - "x": 11, - "y": 5, + "x": 12, + "y": 6, "var": 2004, "lv": 0, "hide": 0, "initial_ai": 1, - "attribute": "1&4000|2&500|4&300|5&300|9&10000|10&0|11&0|12&0|13&5000|14&0|18&0", + "attribute": "&", "skill": 0, "seid": "&", "star": 0, - "spine": 0 + "spine": 0, + "randomEnemy": "321&333&334&335" }, { "warId": 4503, - "actorName": "华佗", - "actorId": 346, + "actorName": "敌军", + "actorId": 0, "dataId": 2005, "relation": 2, "outIndex": 4, "dirction": 1, - "x": 12, - "y": 5, + "x": 13, + "y": 6, "var": 2005, "lv": 0, "hide": 0, "initial_ai": 1, - "attribute": "1&3500|2&500|4&400|5&400|9&0|10&0|11&0|12&0|13&0|14&10000|18&0", + "attribute": "&", "skill": 0, "seid": "&", "star": 0, - "spine": 0 + "spine": 0, + "randomEnemy": "346&" }, { "warId": 4503, @@ -287,8 +301,8 @@ "relation": 2, "outIndex": 5, "dirction": 1, - "x": 13, - "y": 5, + "x": 12, + "y": 8, "var": 2006, "lv": 0, "hide": 0, @@ -297,7 +311,8 @@ "skill": 0, "seid": "&", "star": 0, - "spine": 0 + "spine": 0, + "randomEnemy": "&" }, { "warId": 4503, @@ -307,8 +322,8 @@ "relation": 2, "outIndex": 6, "dirction": 1, - "x": 11, - "y": 4, + "x": 12, + "y": 7, "var": 2007, "lv": 0, "hide": 0, @@ -317,7 +332,8 @@ "skill": 0, "seid": "&", "star": 0, - "spine": 0 + "spine": 0, + "randomEnemy": "&" }, { "warId": 4503, @@ -327,8 +343,8 @@ "relation": 2, "outIndex": 7, "dirction": 1, - "x": 12, - "y": 4, + "x": 14, + "y": 7, "var": 2008, "lv": 0, "hide": 0, @@ -337,7 +353,8 @@ "skill": 0, "seid": "&", "star": 0, - "spine": 0 + "spine": 0, + "randomEnemy": "340&341&342" }, { "warId": 4503, @@ -347,8 +364,8 @@ "relation": 2, "outIndex": 8, "dirction": 1, - "x": 13, - "y": 4, + "x": 14, + "y": 6, "var": 2009, "lv": 0, "hide": 0, @@ -357,6 +374,7 @@ "skill": 0, "seid": "&", "star": 0, - "spine": 0 + "spine": 0, + "randomEnemy": "&" } ] \ No newline at end of file diff --git a/shared/resource/warJsons/4504.json b/shared/resource/warJsons/4504.json index e5dca4d01..17b588e6e 100644 --- a/shared/resource/warJsons/4504.json +++ b/shared/resource/warJsons/4504.json @@ -7,8 +7,8 @@ "relation": 0, "outIndex": 0, "dirction": 2, - "x": 4, - "y": 7, + "x": 6, + "y": 8, "var": 0, "lv": 0, "hide": 0, @@ -17,7 +17,8 @@ "skill": 0, "seid": "&", "star": 0, - "spine": 0 + "spine": 0, + "randomEnemy": "&" }, { "warId": 4504, @@ -27,8 +28,8 @@ "relation": 0, "outIndex": 1, "dirction": 2, - "x": 5, - "y": 7, + "x": 7, + "y": 8, "var": 1, "lv": 0, "hide": 0, @@ -37,7 +38,8 @@ "skill": 0, "seid": "&", "star": 0, - "spine": 0 + "spine": 0, + "randomEnemy": "&" }, { "warId": 4504, @@ -47,8 +49,8 @@ "relation": 0, "outIndex": 2, "dirction": 2, - "x": 5, - "y": 6, + "x": 7, + "y": 7, "var": 2, "lv": 0, "hide": 0, @@ -57,7 +59,8 @@ "skill": 0, "seid": "&", "star": 0, - "spine": 0 + "spine": 0, + "randomEnemy": "&" }, { "warId": 4504, @@ -67,8 +70,8 @@ "relation": 0, "outIndex": 3, "dirction": 2, - "x": 4, - "y": 5, + "x": 6, + "y": 6, "var": 3, "lv": 0, "hide": 0, @@ -77,7 +80,8 @@ "skill": 0, "seid": "&", "star": 0, - "spine": 0 + "spine": 0, + "randomEnemy": "&" }, { "warId": 4504, @@ -87,8 +91,8 @@ "relation": 0, "outIndex": 4, "dirction": 2, - "x": 5, - "y": 5, + "x": 7, + "y": 6, "var": 4, "lv": 0, "hide": 0, @@ -97,7 +101,8 @@ "skill": 0, "seid": "&", "star": 0, - "spine": 0 + "spine": 0, + "randomEnemy": "&" }, { "warId": 4504, @@ -107,8 +112,8 @@ "relation": 0, "outIndex": 5, "dirction": 2, - "x": 3, - "y": 6, + "x": 5, + "y": 8, "var": 5, "lv": 0, "hide": 0, @@ -117,7 +122,8 @@ "skill": 0, "seid": "&", "star": 0, - "spine": 0 + "spine": 0, + "randomEnemy": "&" }, { "warId": 4504, @@ -127,8 +133,8 @@ "relation": 0, "outIndex": 6, "dirction": 2, - "x": 4, - "y": 6, + "x": 5, + "y": 7, "var": 6, "lv": 0, "hide": 0, @@ -137,7 +143,8 @@ "skill": 0, "seid": "&", "star": 0, - "spine": 0 + "spine": 0, + "randomEnemy": "&" }, { "warId": 4504, @@ -147,7 +154,7 @@ "relation": 0, "outIndex": 7, "dirction": 2, - "x": 3, + "x": 6, "y": 7, "var": 7, "lv": 0, @@ -157,7 +164,8 @@ "skill": 0, "seid": "&", "star": 0, - "spine": 0 + "spine": 0, + "randomEnemy": "&" }, { "warId": 4504, @@ -167,8 +175,8 @@ "relation": 0, "outIndex": 8, "dirction": 2, - "x": 3, - "y": 5, + "x": 5, + "y": 6, "var": 8, "lv": 0, "hide": 0, @@ -177,107 +185,113 @@ "skill": 0, "seid": "&", "star": 0, - "spine": 0 + "spine": 0, + "randomEnemy": "&" }, { "warId": 4504, - "actorName": "曹操", - "actorId": 301, + "actorName": "敌军", + "actorId": 0, "dataId": 2001, "relation": 2, "outIndex": 0, "dirction": 1, "x": 13, - "y": 7, + "y": 8, "var": 2001, "lv": 0, "hide": 0, "initial_ai": 1, - "attribute": "1&3000|2&600|4&250|5&250|9&0|10&25000|11&20000|12&0|13&10000|14&10000|18&0", + "attribute": "&", "skill": 0, "seid": "&", "star": 0, - "spine": 0 + "spine": 0, + "randomEnemy": "&" }, { "warId": 4504, - "actorName": "郭嘉", - "actorId": 305, + "actorName": "敌军", + "actorId": 0, "dataId": 2002, "relation": 2, "outIndex": 1, "dirction": 1, "x": 14, - "y": 7, + "y": 8, "var": 2002, "lv": 0, "hide": 0, "initial_ai": 1, - "attribute": "1&5000|2&400|4&600|5&600|9&0|10&10000|11&30000|12&10000|13&0|14&20000|18&0", + "attribute": "&", "skill": 0, "seid": "&", "star": 0, - "spine": 0 + "spine": 0, + "randomEnemy": "305&312" }, { "warId": 4504, - "actorName": "张飞", - "actorId": 317, + "actorName": "敌军", + "actorId": 0, "dataId": 2003, "relation": 2, "outIndex": 2, "dirction": 1, - "x": 14, - "y": 6, + "x": 13, + "y": 7, "var": 2003, "lv": 0, "hide": 0, "initial_ai": 1, - "attribute": "1&2500|2&700|4&200|5&200|9&0|10&20000|11&10000|12&0|13&10000|14&0|18&0", + "attribute": "&", "skill": 0, "seid": "&", "star": 0, - "spine": 0 + "spine": 0, + "randomEnemy": "317&314&318&320&321" }, { "warId": 4504, - "actorName": "黄忠", - "actorId": 321, + "actorName": "敌军", + "actorId": 0, "dataId": 2004, "relation": 2, "outIndex": 3, "dirction": 1, - "x": 13, - "y": 5, + "x": 12, + "y": 6, "var": 2004, "lv": 0, "hide": 0, "initial_ai": 1, - "attribute": "1&4000|2&500|4&300|5&300|9&10000|10&0|11&0|12&0|13&5000|14&0|18&0", + "attribute": "&", "skill": 0, "seid": "&", "star": 0, - "spine": 0 + "spine": 0, + "randomEnemy": "321&333&334&335" }, { "warId": 4504, - "actorName": "华佗", - "actorId": 346, + "actorName": "敌军", + "actorId": 0, "dataId": 2005, "relation": 2, "outIndex": 4, "dirction": 1, - "x": 12, - "y": 5, + "x": 13, + "y": 6, "var": 2005, "lv": 0, "hide": 0, "initial_ai": 1, - "attribute": "1&3500|2&500|4&400|5&400|9&0|10&0|11&0|12&0|13&0|14&10000|18&0", + "attribute": "&", "skill": 0, "seid": "&", "star": 0, - "spine": 0 + "spine": 0, + "randomEnemy": "&" }, { "warId": 4504, @@ -288,7 +302,7 @@ "outIndex": 5, "dirction": 1, "x": 12, - "y": 7, + "y": 8, "var": 2006, "lv": 0, "hide": 0, @@ -297,7 +311,8 @@ "skill": 0, "seid": "&", "star": 0, - "spine": 0 + "spine": 0, + "randomEnemy": "321&333&334&335" }, { "warId": 4504, @@ -308,7 +323,7 @@ "outIndex": 6, "dirction": 1, "x": 12, - "y": 6, + "y": 7, "var": 2007, "lv": 0, "hide": 0, @@ -317,7 +332,8 @@ "skill": 0, "seid": "&", "star": 0, - "spine": 0 + "spine": 0, + "randomEnemy": "&" }, { "warId": 4504, @@ -327,8 +343,8 @@ "relation": 2, "outIndex": 7, "dirction": 1, - "x": 13, - "y": 6, + "x": 14, + "y": 7, "var": 2008, "lv": 0, "hide": 0, @@ -337,7 +353,8 @@ "skill": 0, "seid": "&", "star": 0, - "spine": 0 + "spine": 0, + "randomEnemy": "340&341&342" }, { "warId": 4504, @@ -348,7 +365,7 @@ "outIndex": 8, "dirction": 1, "x": 14, - "y": 5, + "y": 6, "var": 2009, "lv": 0, "hide": 0, @@ -357,6 +374,7 @@ "skill": 0, "seid": "&", "star": 0, - "spine": 0 + "spine": 0, + "randomEnemy": "301&306&307" } ] \ No newline at end of file diff --git a/shared/resource/warJsons/4505.json b/shared/resource/warJsons/4505.json index c702f5d0c..33226a33a 100644 --- a/shared/resource/warJsons/4505.json +++ b/shared/resource/warJsons/4505.json @@ -7,7 +7,7 @@ "relation": 0, "outIndex": 0, "dirction": 2, - "x": 3, + "x": 2, "y": 6, "var": 0, "lv": 0, @@ -17,7 +17,8 @@ "skill": 0, "seid": "&", "star": 0, - "spine": 0 + "spine": 0, + "randomEnemy": "&" }, { "warId": 4505, @@ -27,7 +28,7 @@ "relation": 0, "outIndex": 1, "dirction": 2, - "x": 4, + "x": 3, "y": 6, "var": 1, "lv": 0, @@ -37,7 +38,8 @@ "skill": 0, "seid": "&", "star": 0, - "spine": 0 + "spine": 0, + "randomEnemy": "&" }, { "warId": 4505, @@ -48,7 +50,7 @@ "outIndex": 2, "dirction": 2, "x": 4, - "y": 5, + "y": 6, "var": 2, "lv": 0, "hide": 0, @@ -57,7 +59,8 @@ "skill": 0, "seid": "&", "star": 0, - "spine": 0 + "spine": 0, + "randomEnemy": "&" }, { "warId": 4505, @@ -67,8 +70,8 @@ "relation": 0, "outIndex": 3, "dirction": 2, - "x": 3, - "y": 4, + "x": 2, + "y": 5, "var": 3, "lv": 0, "hide": 0, @@ -77,7 +80,8 @@ "skill": 0, "seid": "&", "star": 0, - "spine": 0 + "spine": 0, + "randomEnemy": "&" }, { "warId": 4505, @@ -87,8 +91,8 @@ "relation": 0, "outIndex": 4, "dirction": 2, - "x": 4, - "y": 4, + "x": 3, + "y": 5, "var": 4, "lv": 0, "hide": 0, @@ -97,7 +101,8 @@ "skill": 0, "seid": "&", "star": 0, - "spine": 0 + "spine": 0, + "randomEnemy": "&" }, { "warId": 4505, @@ -107,8 +112,8 @@ "relation": 0, "outIndex": 5, "dirction": 2, - "x": 2, - "y": 6, + "x": 4, + "y": 5, "var": 5, "lv": 0, "hide": 0, @@ -117,7 +122,8 @@ "skill": 0, "seid": "&", "star": 0, - "spine": 0 + "spine": 0, + "randomEnemy": "&" }, { "warId": 4505, @@ -128,7 +134,7 @@ "outIndex": 6, "dirction": 2, "x": 2, - "y": 5, + "y": 4, "var": 6, "lv": 0, "hide": 0, @@ -137,7 +143,8 @@ "skill": 0, "seid": "&", "star": 0, - "spine": 0 + "spine": 0, + "randomEnemy": "&" }, { "warId": 4505, @@ -148,7 +155,7 @@ "outIndex": 7, "dirction": 2, "x": 3, - "y": 5, + "y": 4, "var": 7, "lv": 0, "hide": 0, @@ -157,7 +164,8 @@ "skill": 0, "seid": "&", "star": 0, - "spine": 0 + "spine": 0, + "randomEnemy": "&" }, { "warId": 4505, @@ -167,7 +175,7 @@ "relation": 0, "outIndex": 8, "dirction": 2, - "x": 2, + "x": 4, "y": 4, "var": 8, "lv": 0, @@ -177,107 +185,113 @@ "skill": 0, "seid": "&", "star": 0, - "spine": 0 + "spine": 0, + "randomEnemy": "&" }, { "warId": 4505, - "actorName": "曹操", - "actorId": 301, + "actorName": "敌军", + "actorId": 0, "dataId": 2001, "relation": 2, "outIndex": 0, "dirction": 1, - "x": 14, + "x": 11, "y": 6, "var": 2001, "lv": 0, "hide": 0, "initial_ai": 1, - "attribute": "1&3000|2&600|4&250|5&250|9&0|10&25000|11&20000|12&0|13&10000|14&10000|18&0", + "attribute": "&", "skill": 0, "seid": "&", "star": 0, - "spine": 0 + "spine": 0, + "randomEnemy": "301&306&307" }, { "warId": 4505, - "actorName": "郭嘉", - "actorId": 305, + "actorName": "敌军", + "actorId": 0, "dataId": 2002, "relation": 2, "outIndex": 1, "dirction": 1, - "x": 15, + "x": 12, "y": 6, "var": 2002, "lv": 0, "hide": 0, "initial_ai": 1, - "attribute": "1&5000|2&400|4&600|5&600|9&0|10&10000|11&30000|12&10000|13&0|14&20000|18&0", + "attribute": "&", "skill": 0, "seid": "&", "star": 0, - "spine": 0 + "spine": 0, + "randomEnemy": "305&312" }, { "warId": 4505, - "actorName": "张飞", - "actorId": 317, + "actorName": "敌军", + "actorId": 0, "dataId": 2003, "relation": 2, "outIndex": 2, "dirction": 1, - "x": 15, - "y": 5, + "x": 13, + "y": 6, "var": 2003, "lv": 0, "hide": 0, "initial_ai": 1, - "attribute": "1&2500|2&700|4&200|5&200|9&0|10&20000|11&10000|12&0|13&10000|14&0|18&0", + "attribute": "&", "skill": 0, "seid": "&", "star": 0, - "spine": 0 + "spine": 0, + "randomEnemy": "317&314&318&320&321" }, { "warId": 4505, - "actorName": "黄忠", - "actorId": 321, + "actorName": "敌军", + "actorId": 0, "dataId": 2004, "relation": 2, "outIndex": 3, "dirction": 1, - "x": 14, - "y": 4, + "x": 11, + "y": 5, "var": 2004, "lv": 0, "hide": 0, "initial_ai": 1, - "attribute": "1&4000|2&500|4&300|5&300|9&10000|10&0|11&0|12&0|13&5000|14&0|18&0", + "attribute": "&", "skill": 0, "seid": "&", "star": 0, - "spine": 0 + "spine": 0, + "randomEnemy": "321&333&334&335" }, { "warId": 4505, - "actorName": "华佗", - "actorId": 346, + "actorName": "敌军", + "actorId": 0, "dataId": 2005, "relation": 2, "outIndex": 4, "dirction": 1, - "x": 15, - "y": 4, + "x": 12, + "y": 5, "var": 2005, "lv": 0, "hide": 0, "initial_ai": 1, - "attribute": "1&3500|2&500|4&400|5&400|9&0|10&0|11&0|12&0|13&0|14&10000|18&0", + "attribute": "&", "skill": 0, "seid": "&", "star": 0, - "spine": 0 + "spine": 0, + "randomEnemy": "346&" }, { "warId": 4505, @@ -288,7 +302,7 @@ "outIndex": 5, "dirction": 1, "x": 13, - "y": 6, + "y": 5, "var": 2006, "lv": 0, "hide": 0, @@ -297,7 +311,8 @@ "skill": 0, "seid": "&", "star": 0, - "spine": 0 + "spine": 0, + "randomEnemy": "&" }, { "warId": 4505, @@ -307,8 +322,8 @@ "relation": 2, "outIndex": 6, "dirction": 1, - "x": 13, - "y": 5, + "x": 11, + "y": 4, "var": 2007, "lv": 0, "hide": 0, @@ -317,7 +332,8 @@ "skill": 0, "seid": "&", "star": 0, - "spine": 0 + "spine": 0, + "randomEnemy": "&" }, { "warId": 4505, @@ -327,8 +343,8 @@ "relation": 2, "outIndex": 7, "dirction": 1, - "x": 14, - "y": 5, + "x": 12, + "y": 4, "var": 2008, "lv": 0, "hide": 0, @@ -337,7 +353,8 @@ "skill": 0, "seid": "&", "star": 0, - "spine": 0 + "spine": 0, + "randomEnemy": "340&341&342" }, { "warId": 4505, @@ -357,6 +374,7 @@ "skill": 0, "seid": "&", "star": 0, - "spine": 0 + "spine": 0, + "randomEnemy": "&" } ] \ No newline at end of file diff --git a/shared/resource/warJsons/4506.json b/shared/resource/warJsons/4506.json new file mode 100644 index 000000000..68dcf200e --- /dev/null +++ b/shared/resource/warJsons/4506.json @@ -0,0 +1,380 @@ +[ + { + "warId": 4506, + "actorName": "我军", + "actorId": 0, + "dataId": 0, + "relation": 0, + "outIndex": 0, + "dirction": 2, + "x": 2, + "y": 6, + "var": 0, + "lv": 0, + "hide": 0, + "initial_ai": 1, + "attribute": "&", + "skill": 0, + "seid": "&", + "star": 0, + "spine": 0, + "randomEnemy": "&" + }, + { + "warId": 4506, + "actorName": "我军", + "actorId": 0, + "dataId": 0, + "relation": 0, + "outIndex": 1, + "dirction": 2, + "x": 3, + "y": 6, + "var": 1, + "lv": 0, + "hide": 0, + "initial_ai": 1, + "attribute": "&", + "skill": 0, + "seid": "&", + "star": 0, + "spine": 0, + "randomEnemy": "&" + }, + { + "warId": 4506, + "actorName": "我军", + "actorId": 0, + "dataId": 0, + "relation": 0, + "outIndex": 2, + "dirction": 2, + "x": 4, + "y": 6, + "var": 2, + "lv": 0, + "hide": 0, + "initial_ai": 1, + "attribute": "&", + "skill": 0, + "seid": "&", + "star": 0, + "spine": 0, + "randomEnemy": "&" + }, + { + "warId": 4506, + "actorName": "我军", + "actorId": 0, + "dataId": 0, + "relation": 0, + "outIndex": 3, + "dirction": 2, + "x": 2, + "y": 5, + "var": 3, + "lv": 0, + "hide": 0, + "initial_ai": 1, + "attribute": "&", + "skill": 0, + "seid": "&", + "star": 0, + "spine": 0, + "randomEnemy": "&" + }, + { + "warId": 4506, + "actorName": "我军", + "actorId": 0, + "dataId": 0, + "relation": 0, + "outIndex": 4, + "dirction": 2, + "x": 3, + "y": 5, + "var": 4, + "lv": 0, + "hide": 0, + "initial_ai": 1, + "attribute": "&", + "skill": 0, + "seid": "&", + "star": 0, + "spine": 0, + "randomEnemy": "&" + }, + { + "warId": 4506, + "actorName": "我军", + "actorId": 0, + "dataId": 0, + "relation": 0, + "outIndex": 5, + "dirction": 2, + "x": 4, + "y": 5, + "var": 5, + "lv": 0, + "hide": 0, + "initial_ai": 1, + "attribute": "&", + "skill": 0, + "seid": "&", + "star": 0, + "spine": 0, + "randomEnemy": "&" + }, + { + "warId": 4506, + "actorName": "我军", + "actorId": 0, + "dataId": 0, + "relation": 0, + "outIndex": 6, + "dirction": 2, + "x": 2, + "y": 4, + "var": 6, + "lv": 0, + "hide": 0, + "initial_ai": 1, + "attribute": "&", + "skill": 0, + "seid": "&", + "star": 0, + "spine": 0, + "randomEnemy": "&" + }, + { + "warId": 4506, + "actorName": "我军", + "actorId": 0, + "dataId": 0, + "relation": 0, + "outIndex": 7, + "dirction": 2, + "x": 3, + "y": 4, + "var": 7, + "lv": 0, + "hide": 0, + "initial_ai": 1, + "attribute": "&", + "skill": 0, + "seid": "&", + "star": 0, + "spine": 0, + "randomEnemy": "&" + }, + { + "warId": 4506, + "actorName": "我军", + "actorId": 0, + "dataId": 0, + "relation": 0, + "outIndex": 8, + "dirction": 2, + "x": 4, + "y": 4, + "var": 8, + "lv": 0, + "hide": 0, + "initial_ai": 1, + "attribute": "&", + "skill": 0, + "seid": "&", + "star": 0, + "spine": 0, + "randomEnemy": "&" + }, + { + "warId": 4506, + "actorName": "敌军", + "actorId": 0, + "dataId": 2001, + "relation": 2, + "outIndex": 0, + "dirction": 1, + "x": 11, + "y": 6, + "var": 2001, + "lv": 0, + "hide": 0, + "initial_ai": 1, + "attribute": "&", + "skill": 0, + "seid": "&", + "star": 0, + "spine": 0, + "randomEnemy": "&" + }, + { + "warId": 4506, + "actorName": "敌军", + "actorId": 0, + "dataId": 2002, + "relation": 2, + "outIndex": 1, + "dirction": 1, + "x": 12, + "y": 6, + "var": 2002, + "lv": 0, + "hide": 0, + "initial_ai": 1, + "attribute": "&", + "skill": 0, + "seid": "&", + "star": 0, + "spine": 0, + "randomEnemy": "305&312" + }, + { + "warId": 4506, + "actorName": "敌军", + "actorId": 0, + "dataId": 2003, + "relation": 2, + "outIndex": 2, + "dirction": 1, + "x": 13, + "y": 6, + "var": 2003, + "lv": 0, + "hide": 0, + "initial_ai": 1, + "attribute": "&", + "skill": 0, + "seid": "&", + "star": 0, + "spine": 0, + "randomEnemy": "317&314&318&320&321" + }, + { + "warId": 4506, + "actorName": "敌军", + "actorId": 0, + "dataId": 2004, + "relation": 2, + "outIndex": 3, + "dirction": 1, + "x": 11, + "y": 5, + "var": 2004, + "lv": 0, + "hide": 0, + "initial_ai": 1, + "attribute": "&", + "skill": 0, + "seid": "&", + "star": 0, + "spine": 0, + "randomEnemy": "321&333&334&335" + }, + { + "warId": 4506, + "actorName": "敌军", + "actorId": 0, + "dataId": 2005, + "relation": 2, + "outIndex": 4, + "dirction": 1, + "x": 12, + "y": 5, + "var": 2005, + "lv": 0, + "hide": 0, + "initial_ai": 1, + "attribute": "&", + "skill": 0, + "seid": "&", + "star": 0, + "spine": 0, + "randomEnemy": "&" + }, + { + "warId": 4506, + "actorName": "敌军", + "actorId": 0, + "dataId": 2006, + "relation": 2, + "outIndex": 5, + "dirction": 1, + "x": 13, + "y": 5, + "var": 2006, + "lv": 0, + "hide": 0, + "initial_ai": 1, + "attribute": "&", + "skill": 0, + "seid": "&", + "star": 0, + "spine": 0, + "randomEnemy": "321&333&334&335" + }, + { + "warId": 4506, + "actorName": "敌军", + "actorId": 0, + "dataId": 2007, + "relation": 2, + "outIndex": 6, + "dirction": 1, + "x": 11, + "y": 4, + "var": 2007, + "lv": 0, + "hide": 0, + "initial_ai": 1, + "attribute": "&", + "skill": 0, + "seid": "&", + "star": 0, + "spine": 0, + "randomEnemy": "&" + }, + { + "warId": 4506, + "actorName": "敌军", + "actorId": 0, + "dataId": 2008, + "relation": 2, + "outIndex": 7, + "dirction": 1, + "x": 12, + "y": 4, + "var": 2008, + "lv": 0, + "hide": 0, + "initial_ai": 1, + "attribute": "&", + "skill": 0, + "seid": "&", + "star": 0, + "spine": 0, + "randomEnemy": "340&341&342" + }, + { + "warId": 4506, + "actorName": "敌军", + "actorId": 0, + "dataId": 2009, + "relation": 2, + "outIndex": 8, + "dirction": 1, + "x": 13, + "y": 4, + "var": 2009, + "lv": 0, + "hide": 0, + "initial_ai": 1, + "attribute": "&", + "skill": 0, + "seid": "&", + "star": 0, + "spine": 0, + "randomEnemy": "301&306&307" + } +] \ No newline at end of file