From f56dbc29de0d14e11d688be2c1b6bf2b3f41a4c3 Mon Sep 17 00:00:00 2001 From: luying Date: Fri, 15 Jul 2022 15:31:08 +0800 Subject: [PATCH] =?UTF-8?q?=E5=90=8D=E5=B0=86=E6=93=82=E5=8F=B0=EF=BC=9A?= =?UTF-8?q?=E8=8E=B7=E5=8F=96=E5=AF=B9=E6=89=8B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../servers/battle/handler/ladderHandler.ts | 163 +++++++++- .../servers/systimer/remote/systimerRemote.ts | 19 +- game-server/app/services/ladderService.ts | 106 ++++++- game-server/app/services/timeTaskService.ts | 21 +- shared/consts/constModules/battleConst.ts | 11 +- shared/consts/constModules/chatConst.ts | 3 + shared/consts/statusCode.ts | 2 + shared/db/LadderMatch.ts | 27 +- shared/db/LadderMatchRec.ts | 34 ++- shared/domain/battleField/ladder.ts | 175 ++++++++--- shared/resource/warJsons/4601.json | 278 ++++++++++++++++++ shared/resource/warJsons/4602.json | 278 ++++++++++++++++++ shared/resource/warJsons/4603.json | 278 ++++++++++++++++++ shared/resource/warJsons/4604.json | 278 ++++++++++++++++++ shared/resource/warJsons/4605.json | 278 ++++++++++++++++++ 15 files changed, 1881 insertions(+), 70 deletions(-) create mode 100644 shared/resource/warJsons/4601.json create mode 100644 shared/resource/warJsons/4602.json create mode 100644 shared/resource/warJsons/4603.json create mode 100644 shared/resource/warJsons/4604.json create mode 100644 shared/resource/warJsons/4605.json diff --git a/game-server/app/servers/battle/handler/ladderHandler.ts b/game-server/app/servers/battle/handler/ladderHandler.ts index bb47b5c76..b18ce2ef2 100644 --- a/game-server/app/servers/battle/handler/ladderHandler.ts +++ b/game-server/app/servers/battle/handler/ladderHandler.ts @@ -1,18 +1,18 @@ import { Application, BackendSession, pinus, HandlerService, } from 'pinus'; import { uniq, findWhere, findIndex, pick } from 'underscore'; -import { gameData, getPvpBoxBySeasonNumAndIndex } from '../../../pubUtils/data'; +import { gameData, getDicLadderMatchByMyRank, getPvpBoxBySeasonNumAndIndex } from '../../../pubUtils/data'; import { RoleModel, RoleType } from '../../../db/Role'; import { STATUS } from '../../../consts/statusCode'; import { resResult, genCode, checkRoleIsRobot, robotIdComBack } from '../../../pubUtils/util'; import { LadderMatchModel, LadderUpdateInter } from '../../../db/LadderMatch'; -import { getBuyCntCost, getLadderData, refreshLadderDaily } from '../../../services/ladderService'; -import { LadderDataReturn, LadderDefense, LadderDefenseHero } from '../../../domain/battleField/ladder'; +import { checkRank, generateInitRecInfo, getBuyCntCost, getLadderData, getLadderOppStatus, refreshLadderDaily, refreshLadderEnemies } from '../../../services/ladderService'; +import { LadderDataReturn, LadderDefense, LadderDefenseHero, LadderOppLineupReturn, LadderOppPlayerInfo } from '../../../domain/battleField/ladder'; import { LadderMatchRecModel } from '../../../db/LadderMatchRec'; import { HeroModel, HeroType } from '../../../db/Hero'; import { LADDER } from '../../../pubUtils/dicParam'; import { handleCost } from '../../../services/role/rewardService'; -import { ITEM_CHANGE_REASON } from '../../../consts'; +import { ITEM_CHANGE_REASON, LADDER_CHECK_STOP_TIME, LADDER_OPP_STATUS, LADDER_STATUS } from '../../../consts'; export default function (app: Application) { new HandlerService(app, {}); @@ -23,7 +23,7 @@ export class LadderHandler { constructor(private app: Application) { } - //1获取主界面 + // 1. 获取主界面 async getData(msg: {}, session: BackendSession) { let roleId = session.get('roleId'); @@ -31,7 +31,132 @@ export class LadderHandler { return resResult(STATUS.SUCCESS, result); } - // 8. 设置防守阵容 + // 2. 获取对手阵容信息 + async getOppLineup(msg: { roleId: string, rank: number }, session: BackendSession) { + let roleId = session.get('roleId'); + let { roleId: targetRoleId, rank } = msg; + + let ladderData = await LadderMatchModel.findByRoleId(roleId); + if(!ladderData) return resResult(STATUS.LADDER_NOT_OPEN); + if(!checkRank(ladderData.rank, rank)) return resResult(STATUS.LADDER_RANK_ERROR); + + let { oppPlayers = [] } = ladderData; + let curOppPlayer = oppPlayers.find(cur => cur.roleId == targetRoleId); + let isRobot = curOppPlayer? curOppPlayer.isRobot: false; + let result = new LadderOppLineupReturn(); + result.setMyRank(ladderData.rank); + if(isRobot) { + let dicLadderDifficultRatio = gameData.ladderDifficultRatio.get(rank); + let dicWarJson = gameData.warJson.get(dicLadderDifficultRatio.gkId); + result.setRobot(dicLadderDifficultRatio, dicWarJson); + } else { + let hisLadderData = await LadderMatchModel.findByRoleIdAndInclude(targetRoleId); + result.setPlayer(hisLadderData); + } + return resResult(STATUS.SUCCESS, result); + } + + // 3. 点击挑战 + async chooseOpp(msg: { roleId: string, rank: number, myRank: number }, session: BackendSession) { + let roleId = session.get('roleId'); + let serverId = session.get('serverId'); + let { roleId: targetRoleId, rank, myRank } = msg; + // 检查双方排名等,不行的刷新对手回去 + let ladderData = await LadderMatchModel.findByRoleIdAndInclude(roleId); + if(!ladderData) return resResult(STATUS.LADDER_NOT_OPEN); + + let { status, isRobot, hisLadderData } = await getLadderOppStatus(ladderData, targetRoleId, myRank, rank); + if(status != LADDER_OPP_STATUS.BATTLE) { + let oppPlayers = await refreshLadderEnemies(ladderData); + return resResult(STATUS.SUCCESS, { + status, oppPlayers + }); + } + + // 创建ladderMatchRec,发行battleCode + let attackInfo = generateInitRecInfo(false, false, ladderData.rank, ladderData); + let defenseInfo = generateInitRecInfo(isRobot, true, rank, hisLadderData); + let rec = await LadderMatchRecModel.createRec(serverId, roleId, targetRoleId, hisLadderData?.defense, attackInfo, defenseInfo); + + // 倒计时,倒计时结束没有check设为失败并发失败通知 + pinus.app.rpc.systimer.systimerRemote.setLadderCountDown.broadcast(rec.battleCode, rec.checkTime, LADDER_STATUS.CHECK); + + return resResult(STATUS.SUCCESS, { + time: rec.checkTime + LADDER_CHECK_STOP_TIME, + battleCode: rec.battleCode + }); + } + + // 4. 出战撤退 + async giveupCheck(msg: { battleCode: string }, session: BackendSession) { + let roleId = session.get('roleId'); + let { battleCode } = msg; + // 更新ladderMatchRec + let rec = await LadderMatchRecModel.giveup(battleCode); + if(rec) { + pinus.app.rpc.systimer.systimerRemote.cancelLadderCountDown.broadcast(rec.battleCode); + } + + return resResult(STATUS.SUCCESS, { status: 0, time: 0 }); + } + + // 5. 获取对手具体战场数据 + async getOppData(msg: { battleCode: string }, session: BackendSession) { + let roleId = session.get('roleId'); + let { battleCode } = msg; + + // 判断是机器人还是真人 + + // 真人根据ladderMatch的defense,和warId对应的出兵表生成heroes + + return resResult(STATUS.SUCCESS); + } + + // 6. 布完阵开始挑战 + async checkBattle(msg: { battleCode: string, heroes: { actorId: number, order: number }[] }, session: BackendSession) { + let roleId = session.get('roleId'); + let { battleCode, heroes } = msg; + + // 检查挑战次数 + // 取消 chooseOpp 的倒计时 + // 更新ladderMatchRec状态,记录下出阵时候玩家选择的顺序 + // 开始倒计时,当时间到了还没battleEnd的时候算失败并发通知 + + return resResult(STATUS.SUCCESS) + } + + // 7. 挑战结算 + async battleEnd(msg: { battleCode: string, isSuccess: boolean }, session: BackendSession) { + let roleId = session.get('roleId'); + let { battleCode, isSuccess } = msg; + + // 取消 checkBattle 的倒计时 + + // 交换双方排名, transaction + // 更新redis + + // 更新ladderMatchRec状态,并记录信息 + + // 刷新双方的对手并发通知 + // 扣挑战次数 + // 获取奖励 + + return resResult(STATUS.SUCCESS) + } + + // 8. 战5次(扫荡) + async battleSweep(msg: { roleId: string, rank: number, count: number }, session: BackendSession) { + let roleId = session.get('roleId'); + let { roleId: targetRoleId, rank, count } = msg; + + // 检查是否可以扫荡对手 + // 扣挑战次数 + // 获取奖励 + + return resResult(STATUS.SUCCESS) + } + + // 9. 设置防守阵容 async saveDefense(msg: { warId: number, heroes: { actorId: number, ai: number, dataId: number, order: number }[] }, session: BackendSession) { let { warId, heroes } = msg; let roleId = session.get('roleId'); @@ -55,6 +180,30 @@ export class LadderHandler { return resResult(STATUS.SUCCESS, pick(result, 'defense')); } + // 10. 刷新对手 + async refreshOppPlayers(msg: {}, session: BackendSession) { + let roleId = session.get('roleId'); + let sid = session.get('sid'); + + let ladderData = await LadderMatchModel.findByRoleId(roleId); + if(!ladderData) return resResult(STATUS.LADDER_NOT_OPEN); + + let update: LadderUpdateInter = {}; + // 刷新次数 + let refOppObj = refreshLadderDaily(ladderData); + if(refOppObj.shouldRefOpp) { + update = { ...refOppObj }; + } + + if(refOppObj.refOppCnt + 1 > LADDER.LADDER_REFRESH_TIMES) { + return resResult(STATUS.LADDER_REFRESH_CNT_MAX); + } + update.refOppCnt = refOppObj.refOppCnt + 1; + let oppPlayers = await refreshLadderEnemies(ladderData, update); + + // 返回 + return resResult(STATUS.SUCCESS, { refOppCnt: update.refOppCnt, oppPlayers }); + } // 11. 购买次数 async buyCnt(msg: { count: number }, session: BackendSession) { @@ -86,6 +235,6 @@ export class LadderHandler { // 返回 let result = new LadderDataReturn(); result.setLadderData(ladderData); - return resResult(STATUS.SUCCESS, pick(result, 'buyCnt', 'challengeCnt')); + return resResult(STATUS.SUCCESS, pick(result, ['buyCnt', 'challengeCnt'])); } } \ No newline at end of file diff --git a/game-server/app/servers/systimer/remote/systimerRemote.ts b/game-server/app/servers/systimer/remote/systimerRemote.ts index 93902c3c8..4a0eff63d 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, guildActivityStart, gateActivityEnd, cityActivityEnd, raceActivityEnd, guildActivitySchedule, auctionSchedule, initMaintenance, stopMaintenance, initAutoCreateServer, addMailsToSchedule, updateTimeLimitRank } from '../../../services/timeTaskService'; +import { resetPvpSeasonTime, guildActivityStart, gateActivityEnd, cityActivityEnd, raceActivityEnd, guildActivitySchedule, auctionSchedule, initMaintenance, stopMaintenance, initAutoCreateServer, addMailsToSchedule, updateTimeLimitRank, setLadderCountDown, cancelLadderCountDown } from '../../../services/timeTaskService'; import PvpDefenseType from '../../../db/PvpDefense'; import { DicGuildActivity } from '../../../pubUtils/dictionary/DicGuildActivity'; import { reloadResources } from '../../../pubUtils/data'; @@ -15,6 +15,7 @@ import { MailType } from '../../../db/Mail'; import { GroupMailType } from '../../../db/GroupMail'; import { ServerMailType } from '../../../db/ServerMail'; import { ActivityModelType } from '../../../db/Activity'; +import { LADDER_STATUS } from '../../../consts'; export default function (app: Application) { return new SystimerRemote(app); @@ -198,4 +199,20 @@ export class SystimerRemote { errlogger.error(`remote ${__filename} \n ${e.stack}`); } } + + public async setLadderCountDown(battleCode: string, time: number, status: LADDER_STATUS) { + try { + await setLadderCountDown(battleCode, time, status); + } catch(e) { + errlogger.error(`remote ${__filename} \n ${e.stack}`); + } + } + + public async cancelLadderCountDown(battleCode: string) { + try { + await cancelLadderCountDown(battleCode); + } catch(e) { + errlogger.error(`remote ${__filename} \n ${e.stack}`); + } + } } diff --git a/game-server/app/services/ladderService.ts b/game-server/app/services/ladderService.ts index 1178dcb0e..2adc48638 100644 --- a/game-server/app/services/ladderService.ts +++ b/game-server/app/services/ladderService.ts @@ -1,12 +1,14 @@ -import { REDIS_KEY } from "../consts"; -import { LadderMatchModel, LadderMatchType } from "../db/LadderMatch"; +import { LADDER_OPP_STATUS, LADDER_STATUS, PUSH_ROUTE, REDIS_KEY } from "../consts"; +import { HeroType } from "../db/Hero"; +import { LadderMatchModel, LadderMatchType, LadderUpdateInter } from "../db/LadderMatch"; import { LadderMatchRecModel } from "../db/LadderMatchRec"; -import { RoleModel } from "../db/Role"; -import { LadderDataReturn, LadderOppPlayerInDB, LadderOppPlayerReturn } from "../domain/battleField/ladder"; +import { RoleModel, RoleType } from "../db/Role"; +import { LadderDataReturn, LadderDefense, LadderOppPlayerHeroInfo, LadderOppPlayerInDB, LadderOppPlayerInfo, LadderOppPlayerReturn } from "../domain/battleField/ladder"; import { RoleRankInfo } from "../domain/rank"; import { gameData, getDicLadderMatchByMyRank } from "../pubUtils/data"; import { ItemInter } from "../pubUtils/interface"; import { getRandValueByMinMax, shouldRefresh } from "../pubUtils/util"; +import { sendMessageToUserWithSuc } from "./pushService"; import { Rank } from "./rankService"; import { combineItems } from "./role/util"; @@ -93,7 +95,7 @@ export async function getLadderMatchByRank(serverId: number, from: number, to: n return rawResults.map(cur => ({ rank: cur.scores[0], roleId: cur.field })) } -export async function refreshLadderEnemies(ladderData: LadderMatchType) { +export async function refreshLadderEnemies(ladderData: LadderMatchType, update: LadderUpdateInter = {}) { let rankNumbers = randOppRankNumbers(ladderData.rank); // 随机出想要的排名 let min = rankNumbers[0], max = rankNumbers[rankNumbers.length - 1]; @@ -105,7 +107,7 @@ export async function refreshLadderEnemies(ladderData: LadderMatchType) { oppPlayersSave.push({ rank, roleId: player.roleId, isRobot: player.isRobot }); oppPlayers.push(player); } - await LadderMatchModel.updateByRoleId(ladderData.roleId, { oppPlayers: oppPlayersSave }); + await LadderMatchModel.updateByRoleId(ladderData.roleId, { ...update, oppPlayers: oppPlayersSave }); return oppPlayers } @@ -170,4 +172,94 @@ function isOver(isBefore: boolean, myRank: number, range: number, result: number console.log('after', myRank + range > result) return result > myRank + range; } -} \ No newline at end of file +} + +export function checkRank(myRank: number, targetRank: number) { + let dicLadderMatch = getDicLadderMatchByMyRank(myRank); + if(!dicLadderMatch && myRank != 0 && targetRank != 3001) return false; + if(myRank < targetRank) { // 向后打 + if(myRank + dicLadderMatch.rangeAfterMax < targetRank) return false; + } else { // 向前打 + if(myRank - dicLadderMatch.rangeBeforeMax > targetRank) return false; + } + return true; +} + +export async function getLadderOppStatus(ladderData: LadderMatchType, targetRoleId: string, myRank: number, rank: number) { + if(ladderData.rank != myRank) return { status: LADDER_OPP_STATUS.MY_RANK_CHANGE }; + let { oppPlayers } = ladderData; + let curOppPlayer = oppPlayers.find(cur => cur.roleId == targetRoleId); + if(!curOppPlayer|| curOppPlayer.rank != rank) return { status: LADDER_OPP_STATUS.OPP_RANK_CHANGE }; + + if(curOppPlayer.isRobot) { + let hisLadderData = await LadderMatchModel.checkByRank(rank); + if(hisLadderData) return { status: LADDER_OPP_STATUS.OPP_RANK_CHANGE }; + + return { status: LADDER_OPP_STATUS.BATTLE, isRobot: true }; + } else { + let hisLadderData = await LadderMatchModel.lock(targetRoleId, rank); + if(!hisLadderData) return { status: LADDER_OPP_STATUS.OPP_IS_LOCKED }; + + return { status: LADDER_OPP_STATUS.BATTLE, isRobot: false, hisLadderData }; + } +} + +/** + * + * @param isRobot 是否是机器 + * @param isDefense 是攻还是守方 + * @param rank 排名 + * @param ladderData 需要populate过的ladderMatch表 + * @returns + */ +export function generateInitRecInfo(isRobot: boolean, isDefense: boolean, rank: number, ladderData: LadderMatchType) { + if(isRobot) { + let dicLadderDifficultRatio = gameData.ladderDifficultRatio.get(rank); + let dicWarJson = gameData.warJson.get(dicLadderDifficultRatio.gkId)||[]; + + let heroes: LadderOppPlayerHeroInfo[] = []; + for(let json of dicWarJson) { + if(json.relation == 2) { + let hero = new LadderOppPlayerHeroInfo(); + hero.setByWarJson(json); + heroes.push(hero); + } + } + let info = new LadderOppPlayerInfo(); + info.initByRobot(dicLadderDifficultRatio, heroes, isDefense); + return info; + } else { + let defCe = calculateDefCeByDefense(ladderData.defense); + let role = ladderData.role; + let heroes: LadderOppPlayerHeroInfo[] = []; + if(isDefense) { // 防守方可以将武将也存入,攻方要等出战 + let defenseHeroes = ladderData.defense?.heroes||[]; + for(let defenseHero of defenseHeroes) { + let hero = new LadderOppPlayerHeroInfo(); + hero.setByDefenseHero(defenseHero.hero); + heroes.push(hero); + } + } + let info = new LadderOppPlayerInfo(); + info.initByPlayer(rank, role, heroes, defCe, isDefense); + return info; + } +} + +function calculateDefCeByDefense(defense: LadderDefense) { + if(!defense) return 0; + let ce = 0; + for(let hero of defense.heroes) { + ce += hero.ce; + } + return ce; +} + +export async function ladderTimeout(battleCode: string, status: LADDER_STATUS) { + let rec = await LadderMatchRecModel.timeout(battleCode); + if(status == LADDER_STATUS.CHECK) { + await sendMessageToUserWithSuc(rec.roleId1, PUSH_ROUTE.LADDER_CHECK_STOP, { battleCode }); + } else if (status == LADDER_STATUS.BATTLE) { + await sendMessageToUserWithSuc(rec.roleId1, PUSH_ROUTE.LADDER_BATTLE_STOP, { battleCode }); + } +} diff --git a/game-server/app/services/timeTaskService.ts b/game-server/app/services/timeTaskService.ts index 5442c10fd..5152e0699 100644 --- a/game-server/app/services/timeTaskService.ts +++ b/game-server/app/services/timeTaskService.ts @@ -5,7 +5,7 @@ import { nowSeconds, getTimeFun, getSeconds } from '../pubUtils/timeUtil'; import { getTodayGuildActivity, gameData } from '../pubUtils/data'; import { pvpSeasonEnd } from './pvpService'; import { getAllOnlineRoles, getAllServers, delGuildActivityRank, getServerCreateTime } from './redisService'; -import { GUILD_ACTIVITY_TYPE, REFRESH_TIME, COUNTER, AUCTION_TIME, GM_MAIL_TYPE, SERVER_TIMER, ACTIVITY_TYPE, PUSH_ROUTE, STATUS } from '../consts'; +import { GUILD_ACTIVITY_TYPE, REFRESH_TIME, COUNTER, AUCTION_TIME, GM_MAIL_TYPE, SERVER_TIMER, ACTIVITY_TYPE, PUSH_ROUTE, STATUS, LADDER_STATUS, LADDER_CHECK_STOP_TIME, LADDER_BATTLE_STOP_TIME, LADDER_SERVER_GAP_TIME } from '../consts'; import { pinus } from 'pinus'; import { settleGuildWeekly } from './guildService'; import { SendMailFun, sendMailsByGmMail, } from './mailService'; @@ -39,6 +39,7 @@ import { resResult } from '../pubUtils/util'; import { checkPopUpConditionWhenGuildActivityEnd } from './activity/popUpShopService'; import { pushRefreshTime } from './connectorService'; import { sendUnReceivedActivityDailyCoin } from './activity/dailyCoinService'; +import { ladderTimeout } from './ladderService'; const PER_SECOND = 1 * 1000; const PER_DAY = 24 * 60 * 60; @@ -734,4 +735,20 @@ async function setTakeRankSnapshotSchedule(activityId: number, serverId: number, await takeSnapshot(data, serverId); }) } -// —————————————— 活动 end —————————————— // \ No newline at end of file +// —————————————— 活动 end —————————————— // + +// —————————————— 名将擂台 start —————————————— // +export async function setLadderCountDown(battleCode: string, time: number, status: LADDER_STATUS) { + let endTime = time + (status == LADDER_STATUS.CHECK? LADDER_CHECK_STOP_TIME: LADDER_BATTLE_STOP_TIME) + LADDER_SERVER_GAP_TIME; + scheduleJob(`ladder${battleCode}`, endTime * 1000, async () => { + await ladderTimeout(battleCode, status); + }) +} + +export async function cancelLadderCountDown(battleCode: string) { + if(scheduledJobs[`ladder${battleCode}`]) { + scheduledJobs[`ladder${battleCode}`].cancel(); + } +} + +// —————————————— 名将擂台 end —————————————— // \ No newline at end of file diff --git a/shared/consts/constModules/battleConst.ts b/shared/consts/constModules/battleConst.ts index ac7ac8b23..937bcad09 100644 --- a/shared/consts/constModules/battleConst.ts +++ b/shared/consts/constModules/battleConst.ts @@ -162,7 +162,16 @@ export enum LADDER_STATUS { NO = 0, // 无战场 CHECK = 1, // 出兵中 BATTLE = 2, // 战斗中 + COMPLETE = 3, // 战斗结束 } export const LADDER_CHECK_STOP_TIME = 2 * 60; -export const LADDER_BATTLE_STOP_TIME = 5 * 60; \ No newline at end of file +export const LADDER_BATTLE_STOP_TIME = 5 * 60; +export const LADDER_SERVER_GAP_TIME = 5; // 服务器比客户端晚5秒 + +export enum LADDER_OPP_STATUS { + BATTLE = 1, // 可以挑战 + OPP_IS_LOCKED = 2, // 对手被挑战 + OPP_RANK_CHANGE = 3, // 对手排名变化 + MY_RANK_CHANGE = 4, // 自己排名变化 +} \ No newline at end of file diff --git a/shared/consts/constModules/chatConst.ts b/shared/consts/constModules/chatConst.ts index 1daa52df7..3f3f9bbdc 100644 --- a/shared/consts/constModules/chatConst.ts +++ b/shared/consts/constModules/chatConst.ts @@ -160,4 +160,7 @@ export const PUSH_ROUTE = { TASK_BOX_REFRESH: 'onTaskBoxRefresh', UPDATE_SURVEY: 'onUpdateSurvey', DELETE_SURVEY: 'onDeleteSurvey', + LADDER_CHECK_STOP: 'onLadderCheckStop', + LADDER_BATTLE_STOP: 'onLadderBattleStop', + LADDER_RANK_UPDATE: 'onLadderRankUpdate', } \ No newline at end of file diff --git a/shared/consts/statusCode.ts b/shared/consts/statusCode.ts index 80e44c2c1..b10cbcced 100644 --- a/shared/consts/statusCode.ts +++ b/shared/consts/statusCode.ts @@ -261,6 +261,8 @@ export const STATUS = { // 名将擂台 LADDER_NOT_OPEN: { code: 21200, simStr: '名将擂台未开放' }, LADDER_BUY_MAX: { code: 21201, simStr: '名将擂台购买次数达到上限' }, + LADDER_RANK_ERROR: { code: 21202, simStr: '该排名玩家不可挑战' }, + LADDER_REFRESH_CNT_MAX: { code: 21203, simStr: '刷新次数达到上限' }, // 通用 30000 - 30099 DIC_DATA_NOT_FOUND: { code: 30000, simStr: '数据表未找到' }, diff --git a/shared/db/LadderMatch.ts b/shared/db/LadderMatch.ts index 680249cc0..ab7f1d09e 100644 --- a/shared/db/LadderMatch.ts +++ b/shared/db/LadderMatch.ts @@ -15,7 +15,10 @@ export default class LadderMatch extends BaseModel { rank: number; // 排名 @prop({ required: true, default: 0 }) historyRank: number; // 历史最高排名 - + + @prop({ required: true, default: 0 }) + locked: number; // 是否被挑战 + @prop({ required: true, default: null, _id: false }) defense: LadderDefense; @@ -31,8 +34,21 @@ export default class LadderMatch extends BaseModel { @prop({ required: true, default: 0 }) refOppCnt: number; // 刷新对手次数 - public static async findByRoleId(roleId: string, getters = false) { - const result: LadderMatchType = await LadderMatchModel.findOne({ roleId }).lean({ getters}); + public static async findByRoleId(roleId: string) { + const result: LadderMatchType = await LadderMatchModel.findOne({ roleId }).lean(); + return result; + } + + public static async checkByRank(rank: number) { + const result = await LadderMatchModel.exists({ rank }); + return result; + } + + public static async findByRoleIdAndInclude(roleId: string) { + const result: LadderMatchType = await LadderMatchModel.findOne({ roleId }) + .populate('role', 'roleId roleName head frame spine heads frames spines title lv updatedAt') + .populate('defense.hero', 'hid skinId quality star colorStar lv') + .lean(); return result; } @@ -62,6 +78,11 @@ export default class LadderMatch extends BaseModel { } return result } + + public static async lock(roleId: string, rank: number) { + const defense: LadderMatchType = await LadderMatchModel.findOneAndUpdate({ roleId, rank, locked: 0 }, { $set: { locked: 1 }}, { new: true }).lean(); + return defense; + } } export const LadderMatchModel = getModelForClass(LadderMatch); diff --git a/shared/db/LadderMatchRec.ts b/shared/db/LadderMatchRec.ts index 589874828..7aef04d44 100644 --- a/shared/db/LadderMatchRec.ts +++ b/shared/db/LadderMatchRec.ts @@ -6,6 +6,8 @@ import { CounterModel } from './Counter'; import { COUNTER, LADDER_STATUS } from '../consts'; import { EXTERIOR, PVP } from '../pubUtils/dicParam'; import { LadderDefense, LadderOppPlayerInfo } from '../domain/battleField/ladder'; +import { genCode } from '../pubUtils/util'; +import { nowSeconds } from '../pubUtils/timeUtil'; @index({ battleCode: 1 }) @@ -21,17 +23,19 @@ export default class LadderMatchRec extends BaseModel { @prop({ required: true }) status: LADDER_STATUS; // 1-出兵中 2-挑战中 3-挑战完毕 @prop({ required: true }) + timeout: boolean; // 是否超时 + @prop({ required: true }) checkTime: number; // 开始出兵的时间,10位时间戳 @prop({ required: true }) battleTime: number; // 开始挑战的时间,10位时间 @prop({ required: true }) endTime: number; // 结束时间 - @prop({ required: true, type: LadderOppPlayerInfo, default: {}, _id: false }) - attackInfo: () => LadderOppPlayerInfo; // 攻方信息 - @prop({ required: true, type: LadderOppPlayerInfo, default: {}, _id: false }) - defenseInfo: () => LadderOppPlayerInfo; // 守方信息 - @prop({ required: true, type: LadderDefense, default: {}, _id: false }) - defense: () => LadderDefense; // 守方信息 + @prop({ required: true, type: () => LadderOppPlayerInfo, default: {}, _id: false }) + attackInfo: LadderOppPlayerInfo; // 攻方信息 + @prop({ required: true, type: () => LadderOppPlayerInfo, default: {}, _id: false }) + defenseInfo: LadderOppPlayerInfo; // 守方信息 + @prop({ required: true, type: () => LadderDefense, default: {}, _id: false }) + defense: LadderDefense; // 守方信息 public static async findByRoleId(roleId: string, getters = false) { const result: LadderMatchRecType = await LadderMatchRecModel.findOne({ roleId1: roleId }).lean({ getters}); @@ -42,6 +46,24 @@ export default class LadderMatchRec extends BaseModel { const result: LadderMatchRecType = await LadderMatchRecModel.findOne({ roleId1: roleId, status: { $in: [ LADDER_STATUS.BATTLE, LADDER_STATUS.CHECK ] } }).lean({ getters}); return result; } + + public static async createRec(serverId: number, roleId1: string, roleId2: string, defense: LadderDefense, attackInfo: LadderOppPlayerInfo, defenseInfo: LadderOppPlayerInfo) { + const battleCode = genCode(10); + const result: LadderMatchRecType = await LadderMatchRecModel.findOneAndUpdate({ battleCode }, { + $set: { roleId1, roleId2, serverId, defense, status: LADDER_STATUS.CHECK, checkTime: nowSeconds(), attackInfo, defenseInfo } + }, { new: true, upsert: true }).lean(); + return result; + } + + public static async timeout(battleCode: string) { + const result: LadderMatchRecType = await LadderMatchRecModel.findOneAndUpdate({ battleCode }, { $set: { status: LADDER_STATUS.COMPLETE, timeout: true } }).lean(); + return result; + } + + public static async giveup(battleCode: string) { + const result: LadderMatchRecType = await LadderMatchRecModel.findOneAndUpdate({ battleCode }, { $set: { status: LADDER_STATUS.NO } }).lean(); + return result; + } } export const LadderMatchRecModel = getModelForClass(LadderMatchRec); diff --git a/shared/domain/battleField/ladder.ts b/shared/domain/battleField/ladder.ts index fdb540b61..0c9858c57 100644 --- a/shared/domain/battleField/ladder.ts +++ b/shared/domain/battleField/ladder.ts @@ -1,11 +1,13 @@ import { mongoose, prop, Ref } from "@typegoose/typegoose"; import { LADDER_BATTLE_STOP_TIME, LADDER_CHECK_STOP_TIME, LADDER_STATUS } from "../../consts"; -import Hero from '../../db/Hero'; +import Hero, { HeroType } from '../../db/Hero'; import { LadderMatchType } from "../../db/LadderMatch"; import { LadderMatchRecType } from "../../db/LadderMatchRec"; import { RoleType } from "../../db/Role"; +import { gameData } from "../../pubUtils/data"; import { EXTERIOR, LADDER } from "../../pubUtils/dicParam"; import { DicLadderDifficultRatio } from "../../pubUtils/dictionary/DicLadderDifficultRatio"; +import { DicWarJson } from "../../pubUtils/dictionary/DicWarJson"; import { RoleRankInfo } from "../rank"; // ladderMatch表 @@ -33,6 +35,7 @@ export class LadderDefenseHero { } } +// ladderMatch表 export class LadderDefense { @prop({ required: true }) @@ -47,6 +50,16 @@ export class LadderDefense { } +// LadderMatch表 +export class LadderOppPlayerInDB { + @prop({ required: true }) + rank: number; + @prop({ required: true }) + roleId: string; + @prop({ required: true }) + isRobot: boolean; +} + // ladderMatchRec export class LadderOppPlayerHeroInfo { @prop({ required: true }) @@ -54,44 +67,66 @@ export class LadderOppPlayerHeroInfo { @prop({ required: true }) skinId: number; // 皮肤id @prop({ required: true }) - quality: number; // 皮肤id + quality: number; // 品质 @prop({ required: true }) - star: number; // 皮肤id + star: number; // 星级 @prop({ required: true }) - colorStar: number; // 皮肤id + colorStar: number; // 彩星 @prop({ required: true }) - lv: number; // 皮肤id + lv: number; // 等级 + + setByWarJson(warJson: DicWarJson) { + this.hid = warJson.actorId; + this.skinId = warJson.actorId; + this.star = warJson.star; + this.colorStar = 0; + this.lv = warJson.lv; + let dicHero = gameData.hero.get(warJson.actorId); + if(dicHero) this.quality = dicHero.quality; + } + + setByDefenseHero(hero: HeroType) { + this.hid = hero.hid; + this.skinId = hero.skinId; + this.quality = hero.quality; + this.star = hero.star; + this.colorStar = hero.colorStar; + this.lv = hero.lv; + } } +// ladderMatchRec export class LadderOppPlayerInfo { @prop({ required: true }) - oldRank: number; // 原排名 + oldRank: number = 0; // 原排名 @prop({ required: true }) - newRank: number; // 交换后的排名 + newRank: number = 0; // 交换后的排名 @prop({ required: true }) - roleId: string; // 角色 id + roleId: string = ''; // 角色 id @prop({ required: true }) - roleName: string; // 角色 名 + roleName: string = LADDER.LADDER_ROBOT_NAME; // 角色 名 @prop({ required: true, default: 0 }) - lv: number; // 等级 + lv: number = 1; // 等级 @prop({ required: true, default: EXTERIOR.EXTERIOR_FACE }) - head: number; // 头像 + head: number = EXTERIOR.EXTERIOR_FACE; // 头像 @prop({ required: true, default: EXTERIOR.EXTERIOR_FACECASE }) - frame: number; // 相框 + frame: number = EXTERIOR.EXTERIOR_FACECASE; // 相框 @prop({ required: true, default: EXTERIOR.EXTERIOR_APPEARANCE }) - spine: number; // 形象 + spine: number = EXTERIOR.EXTERIOR_APPEARANCE; // 形象 @prop({ required: true, default: 0 }) - title: number; // 爵位 + title: number = 1; // 爵位 @prop({ required: true, default: 0 }) - ce: number; // 最高五人战力 + ce: number = 0; // 防守战力 @prop({ required: true, default: false }) - isSuccess: boolean; // 是否胜利 - @prop({ required: true, default: 0 }) - score: number; // 获得的总积分 + isSuccess: boolean = false; // 是否胜利 @prop({ required: true, default: [], type: LadderOppPlayerHeroInfo, _id: false }) - heroes: LadderOppPlayerHeroInfo[]; // 获得的总积分 + heroes: LadderOppPlayerHeroInfo[] = []; // 武将 + @prop({ required: true }) + isRobot: boolean = false; // 原排名 - constructor(role: RoleType, heroes: LadderOppPlayerHeroInfo[], defCe: number, isSuccess: boolean ) { + initByPlayer(rank: number, role: RoleType, heroes: LadderOppPlayerHeroInfo[], defCe: number, isSuccess: boolean ) { + this.oldRank = rank; + this.newRank = rank; this.roleId = role.roleId; this.roleName = role.roleName; this.head = role.head; @@ -103,9 +138,21 @@ export class LadderOppPlayerInfo { this.isSuccess = isSuccess; this.heroes = heroes; } + + initByRobot(dicLadderDifficultRatio: DicLadderDifficultRatio, heroes: LadderOppPlayerHeroInfo[], isSuccess: boolean) { + this.oldRank = dicLadderDifficultRatio.rank; + this.newRank = dicLadderDifficultRatio.rank; + this.roleId = `robot${this.oldRank}`; + this.head = dicLadderDifficultRatio.head; + this.spine = dicLadderDifficultRatio.spine; + this.ce = dicLadderDifficultRatio.ce; + this.lv = dicLadderDifficultRatio.level; + this.isSuccess = isSuccess; + this.heroes = heroes; + } } -// 接口返回 +// defense字段 接口返回 export class LadderDefenseHeroReturn { actorId: number; // 武将id ai: number; // ai逻辑,1-进攻型 2-防守型 @@ -120,6 +167,7 @@ export class LadderDefenseHeroReturn { } } +// defense字段 接口返回 export class LadderDefenseReturn { warId: number; defCe: number = 0; @@ -135,21 +183,23 @@ export class LadderDefenseReturn { } } +// oppPlayers字段接口返回 export class LadderOppPlayerReturn { - rank: number; // 对手排名 - roleId: string; // 对手玩家id - roleName: string; // 对手玩家名 - head: number; // 头像 - frame: number; // 相框 - spine: number; // 形象 - lv: number; // 对手玩家等级 - title: number; // 对手爵位 - defCe: number; // 对手防守阵容战力 - isRobot: boolean; // 是否是机器人 + rank: number = 0; // 对手排名 + roleId: string = ''; // 对手玩家id + roleName: string = LADDER.LADDER_ROBOT_NAME; // 对手玩家名 + head: number = EXTERIOR.EXTERIOR_FACE; // 头像 + frame: number = EXTERIOR.EXTERIOR_FACECASE; // 相框 + spine: number = EXTERIOR.EXTERIOR_APPEARANCE; // 形象 + lv: number = 1; // 对手玩家等级 + title: number = 1; // 对手爵位 + defCe: number = 0; // 对手防守阵容战力 + isRobot: boolean = true; // 是否是机器人 constructor(rank: number, isRobot: boolean) { this.rank = rank; this.isRobot = isRobot; + if(isRobot) this.roleId = `robot${this.rank}`; } setByRedis(param: RoleRankInfo, defCe: number) { @@ -164,17 +214,14 @@ export class LadderOppPlayerReturn { } setByRobot(ladderDifficultRatio: DicLadderDifficultRatio) { - this.roleId = `robot${this.rank}`; - this.roleName = LADDER.LADDER_ROBOT_NAME; - this.frame = EXTERIOR.EXTERIOR_FACECASE; this.head = ladderDifficultRatio.head; this.spine = ladderDifficultRatio.spine; this.lv = ladderDifficultRatio.level; - this.title = 1; this.defCe = ladderDifficultRatio.ce; } } +// getData总体返回 export class LadderDataReturn { rank: number = 0; historyRank: number = 0; @@ -182,7 +229,7 @@ export class LadderDataReturn { buyCnt: number = 0; refOppCnt: number = 0; defense: LadderDefenseReturn = null; - status: LADDER_STATUS; + status: LADDER_STATUS = LADDER_STATUS.NO; time: number = 0; oppPlayers: LadderOppPlayerReturn[] = [] @@ -211,11 +258,53 @@ export class LadderDataReturn { } -export class LadderOppPlayerInDB { - @prop({ required: true }) - rank: number; - @prop({ required: true }) - roleId: string; - @prop({ required: true }) - isRobot: boolean; +// getOppLineup返回 +export class LadderOppLineupReturn { + myRank: number = 0; + isRobot: boolean = true; + rank: number = 0; + roleId: string = ''; + roleName: string = LADDER.LADDER_ROBOT_NAME; + title: number = 1; + guildName: string = ''; + defCe: number = 0; + heroes: LadderOppPlayerHeroInfo[] = [] + + setMyRank(myRank: number) { + this.myRank = myRank; + } + + setRobot(ladderDifficultRatio: DicLadderDifficultRatio, warJsons: DicWarJson[]) { + this.isRobot = true; + this.rank = ladderDifficultRatio.rank; + this.roleId = `robot${this.rank}`; + this.defCe = ladderDifficultRatio.ce; + for(let warJson of warJsons) { + if(warJson.relation == 2) { + let hero = new LadderOppPlayerHeroInfo(); + hero.setByWarJson(warJson); + this.heroes.push(hero); + } + } + } + + /** + * + * @param ladderMatch 需要是populate过role和defense.hero + */ + setPlayer(ladderMatch: LadderMatchType) { + this.isRobot = false; + this.rank = ladderMatch.rank; + this.roleId = ladderMatch.roleId; + let role = ladderMatch.role; + this.roleName = role.roleName; + this.title = role.title; + this.guildName = role.guildName; + for(let defenseHero of (ladderMatch.defense?.heroes||[])) { + this.defCe += defenseHero.ce; + let hero = new LadderOppPlayerHeroInfo(); + hero.setByDefenseHero(defenseHero.hero); + this.heroes.push(hero); + } + } } \ No newline at end of file diff --git a/shared/resource/warJsons/4601.json b/shared/resource/warJsons/4601.json new file mode 100644 index 000000000..7782016d3 --- /dev/null +++ b/shared/resource/warJsons/4601.json @@ -0,0 +1,278 @@ +[ + { + "warId": 4601, + "actorName": "我军", + "actorId": 0, + "dataId": 0, + "relation": 0, + "outIndex": 0, + "dirction": 1, + "x": 6, + "y": 7, + "var": 501, + "lv": 1, + "hide": 0, + "initial_ai": 1, + "bossid": 0, + "attribute": "&", + "skill": "&", + "seid": "&", + "star": 0, + "quality": 0, + "jobLv": 0, + "spine": 0 + }, + { + "warId": 4601, + "actorName": "我军", + "actorId": 0, + "dataId": 0, + "relation": 0, + "outIndex": 1, + "dirction": 1, + "x": 6, + "y": 6, + "var": 502, + "lv": 1, + "hide": 0, + "initial_ai": 1, + "bossid": 0, + "attribute": "&", + "skill": "&", + "seid": "&", + "star": 0, + "quality": 0, + "jobLv": 0, + "spine": 0 + }, + { + "warId": 4601, + "actorName": "我军", + "actorId": 0, + "dataId": 0, + "relation": 0, + "outIndex": 2, + "dirction": 1, + "x": 5, + "y": 8, + "var": 503, + "lv": 1, + "hide": 0, + "initial_ai": 1, + "bossid": 0, + "attribute": "&", + "skill": "&", + "seid": "&", + "star": 0, + "quality": 0, + "jobLv": 0, + "spine": 0 + }, + { + "warId": 4601, + "actorName": "我军", + "actorId": 0, + "dataId": 0, + "relation": 0, + "outIndex": 3, + "dirction": 1, + "x": 5, + "y": 5, + "var": 504, + "lv": 1, + "hide": 0, + "initial_ai": 1, + "bossid": 0, + "attribute": "&", + "skill": "&", + "seid": "&", + "star": 0, + "quality": 0, + "jobLv": 0, + "spine": 0 + }, + { + "warId": 4601, + "actorName": "我军", + "actorId": 0, + "dataId": 0, + "relation": 0, + "outIndex": 4, + "dirction": 1, + "x": 4, + "y": 8, + "var": 505, + "lv": 1, + "hide": 0, + "initial_ai": 1, + "bossid": 0, + "attribute": "&", + "skill": "&", + "seid": "&", + "star": 0, + "quality": 0, + "jobLv": 0, + "spine": 0 + }, + { + "warId": 4601, + "actorName": "我军", + "actorId": 0, + "dataId": 0, + "relation": 0, + "outIndex": 5, + "dirction": 1, + "x": 4, + "y": 5, + "var": 506, + "lv": 1, + "hide": 0, + "initial_ai": 1, + "bossid": 0, + "attribute": "&", + "skill": "&", + "seid": "&", + "star": 0, + "quality": 0, + "jobLv": 0, + "spine": 0 + }, + { + "warId": 4601, + "actorName": "典韦", + "actorId": 307, + "dataId": 2001, + "relation": 2, + "outIndex": 0, + "dirction": 0, + "x": 11, + "y": 7, + "var": 2001, + "lv": 1, + "hide": 0, + "initial_ai": 1, + "bossid": 0, + "attribute": "&", + "skill": "&", + "seid": "&", + "star": 0, + "quality": 0, + "jobLv": 0, + "spine": 0 + }, + { + "warId": 4601, + "actorName": "文丑", + "actorId": 355, + "dataId": 2002, + "relation": 2, + "outIndex": 1, + "dirction": 0, + "x": 11, + "y": 6, + "var": 2002, + "lv": 1, + "hide": 0, + "initial_ai": 1, + "bossid": 0, + "attribute": "&", + "skill": "&", + "seid": "&", + "star": 0, + "quality": 0, + "jobLv": 0, + "spine": 0 + }, + { + "warId": 4601, + "actorName": "颜良", + "actorId": 354, + "dataId": 2003, + "relation": 2, + "outIndex": 2, + "dirction": 0, + "x": 12, + "y": 8, + "var": 2003, + "lv": 1, + "hide": 0, + "initial_ai": 1, + "bossid": 0, + "attribute": "&", + "skill": "&", + "seid": "&", + "star": 0, + "quality": 0, + "jobLv": 0, + "spine": 0 + }, + { + "warId": 4601, + "actorName": "孙乾", + "actorId": 331, + "dataId": 2004, + "relation": 2, + "outIndex": 3, + "dirction": 0, + "x": 12, + "y": 5, + "var": 2004, + "lv": 1, + "hide": 0, + "initial_ai": 1, + "bossid": 0, + "attribute": "&", + "skill": "&", + "seid": "&", + "star": 0, + "quality": 0, + "jobLv": 0, + "spine": 0 + }, + { + "warId": 4601, + "actorName": "蔡琰", + "actorId": 313, + "dataId": 2005, + "relation": 2, + "outIndex": 4, + "dirction": 0, + "x": 13, + "y": 8, + "var": 2005, + "lv": 1, + "hide": 0, + "initial_ai": 1, + "bossid": 0, + "attribute": "&", + "skill": "&", + "seid": "&", + "star": 0, + "quality": 0, + "jobLv": 0, + "spine": 0 + }, + { + "warId": 4601, + "actorName": "麹义", + "actorId": 350, + "dataId": 2006, + "relation": 2, + "outIndex": 5, + "dirction": 0, + "x": 13, + "y": 5, + "var": 2006, + "lv": 1, + "hide": 0, + "initial_ai": 1, + "bossid": 0, + "attribute": "&", + "skill": "&", + "seid": "&", + "star": 0, + "quality": 0, + "jobLv": 0, + "spine": 0 + } +] \ No newline at end of file diff --git a/shared/resource/warJsons/4602.json b/shared/resource/warJsons/4602.json new file mode 100644 index 000000000..b968ad8b7 --- /dev/null +++ b/shared/resource/warJsons/4602.json @@ -0,0 +1,278 @@ +[ + { + "warId": 4602, + "actorName": "我军", + "actorId": 0, + "dataId": 0, + "relation": 0, + "outIndex": 0, + "dirction": 1, + "x": 6, + "y": 7, + "var": 501, + "lv": 1, + "hide": 0, + "initial_ai": 1, + "bossid": 0, + "attribute": "&", + "skill": "&", + "seid": "&", + "star": 0, + "quality": 0, + "jobLv": 0, + "spine": 0 + }, + { + "warId": 4602, + "actorName": "我军", + "actorId": 0, + "dataId": 0, + "relation": 0, + "outIndex": 1, + "dirction": 1, + "x": 6, + "y": 6, + "var": 502, + "lv": 1, + "hide": 0, + "initial_ai": 1, + "bossid": 0, + "attribute": "&", + "skill": "&", + "seid": "&", + "star": 0, + "quality": 0, + "jobLv": 0, + "spine": 0 + }, + { + "warId": 4602, + "actorName": "我军", + "actorId": 0, + "dataId": 0, + "relation": 0, + "outIndex": 2, + "dirction": 1, + "x": 5, + "y": 8, + "var": 503, + "lv": 1, + "hide": 0, + "initial_ai": 1, + "bossid": 0, + "attribute": "&", + "skill": "&", + "seid": "&", + "star": 0, + "quality": 0, + "jobLv": 0, + "spine": 0 + }, + { + "warId": 4602, + "actorName": "我军", + "actorId": 0, + "dataId": 0, + "relation": 0, + "outIndex": 3, + "dirction": 1, + "x": 5, + "y": 5, + "var": 504, + "lv": 1, + "hide": 0, + "initial_ai": 1, + "bossid": 0, + "attribute": "&", + "skill": "&", + "seid": "&", + "star": 0, + "quality": 0, + "jobLv": 0, + "spine": 0 + }, + { + "warId": 4602, + "actorName": "我军", + "actorId": 0, + "dataId": 0, + "relation": 0, + "outIndex": 4, + "dirction": 1, + "x": 4, + "y": 8, + "var": 505, + "lv": 1, + "hide": 0, + "initial_ai": 1, + "bossid": 0, + "attribute": "&", + "skill": "&", + "seid": "&", + "star": 0, + "quality": 0, + "jobLv": 0, + "spine": 0 + }, + { + "warId": 4602, + "actorName": "我军", + "actorId": 0, + "dataId": 0, + "relation": 0, + "outIndex": 5, + "dirction": 1, + "x": 4, + "y": 5, + "var": 506, + "lv": 1, + "hide": 0, + "initial_ai": 1, + "bossid": 0, + "attribute": "&", + "skill": "&", + "seid": "&", + "star": 0, + "quality": 0, + "jobLv": 0, + "spine": 0 + }, + { + "warId": 4602, + "actorName": "潘璋", + "actorId": 360, + "dataId": 2001, + "relation": 2, + "outIndex": 0, + "dirction": 0, + "x": 11, + "y": 7, + "var": 2001, + "lv": 1, + "hide": 0, + "initial_ai": 1, + "bossid": 0, + "attribute": "&", + "skill": "&", + "seid": "&", + "star": 0, + "quality": 0, + "jobLv": 0, + "spine": 0 + }, + { + "warId": 4602, + "actorName": "乐进", + "actorId": 316, + "dataId": 2002, + "relation": 2, + "outIndex": 1, + "dirction": 0, + "x": 11, + "y": 6, + "var": 2002, + "lv": 1, + "hide": 0, + "initial_ai": 1, + "bossid": 0, + "attribute": "&", + "skill": "&", + "seid": "&", + "star": 0, + "quality": 0, + "jobLv": 0, + "spine": 0 + }, + { + "warId": 4602, + "actorName": "凌统", + "actorId": 361, + "dataId": 2003, + "relation": 2, + "outIndex": 2, + "dirction": 0, + "x": 12, + "y": 8, + "var": 2003, + "lv": 1, + "hide": 0, + "initial_ai": 1, + "bossid": 0, + "attribute": "&", + "skill": "&", + "seid": "&", + "star": 0, + "quality": 0, + "jobLv": 0, + "spine": 0 + }, + { + "warId": 4602, + "actorName": "郭嘉", + "actorId": 305, + "dataId": 2004, + "relation": 2, + "outIndex": 3, + "dirction": 0, + "x": 12, + "y": 5, + "var": 2004, + "lv": 1, + "hide": 0, + "initial_ai": 1, + "bossid": 0, + "attribute": "&", + "skill": "&", + "seid": "&", + "star": 0, + "quality": 0, + "jobLv": 0, + "spine": 0 + }, + { + "warId": 4602, + "actorName": "孙权", + "actorId": 336, + "dataId": 2005, + "relation": 2, + "outIndex": 4, + "dirction": 0, + "x": 13, + "y": 8, + "var": 2005, + "lv": 1, + "hide": 0, + "initial_ai": 1, + "bossid": 0, + "attribute": "&", + "skill": "&", + "seid": "&", + "star": 0, + "quality": 0, + "jobLv": 0, + "spine": 0 + }, + { + "warId": 4602, + "actorName": "李典", + "actorId": 312, + "dataId": 2006, + "relation": 2, + "outIndex": 5, + "dirction": 0, + "x": 13, + "y": 5, + "var": 2006, + "lv": 1, + "hide": 0, + "initial_ai": 1, + "bossid": 0, + "attribute": "&", + "skill": "&", + "seid": "&", + "star": 0, + "quality": 0, + "jobLv": 0, + "spine": 0 + } +] \ No newline at end of file diff --git a/shared/resource/warJsons/4603.json b/shared/resource/warJsons/4603.json new file mode 100644 index 000000000..6f1c9c014 --- /dev/null +++ b/shared/resource/warJsons/4603.json @@ -0,0 +1,278 @@ +[ + { + "warId": 4603, + "actorName": "我军", + "actorId": 0, + "dataId": 0, + "relation": 0, + "outIndex": 0, + "dirction": 1, + "x": 6, + "y": 7, + "var": 501, + "lv": 1, + "hide": 0, + "initial_ai": 1, + "bossid": 0, + "attribute": "&", + "skill": "&", + "seid": "&", + "star": 0, + "quality": 0, + "jobLv": 0, + "spine": 0 + }, + { + "warId": 4603, + "actorName": "我军", + "actorId": 0, + "dataId": 0, + "relation": 0, + "outIndex": 1, + "dirction": 1, + "x": 6, + "y": 6, + "var": 502, + "lv": 1, + "hide": 0, + "initial_ai": 1, + "bossid": 0, + "attribute": "&", + "skill": "&", + "seid": "&", + "star": 0, + "quality": 0, + "jobLv": 0, + "spine": 0 + }, + { + "warId": 4603, + "actorName": "我军", + "actorId": 0, + "dataId": 0, + "relation": 0, + "outIndex": 2, + "dirction": 1, + "x": 5, + "y": 8, + "var": 503, + "lv": 1, + "hide": 0, + "initial_ai": 1, + "bossid": 0, + "attribute": "&", + "skill": "&", + "seid": "&", + "star": 0, + "quality": 0, + "jobLv": 0, + "spine": 0 + }, + { + "warId": 4603, + "actorName": "我军", + "actorId": 0, + "dataId": 0, + "relation": 0, + "outIndex": 3, + "dirction": 1, + "x": 5, + "y": 5, + "var": 504, + "lv": 1, + "hide": 0, + "initial_ai": 1, + "bossid": 0, + "attribute": "&", + "skill": "&", + "seid": "&", + "star": 0, + "quality": 0, + "jobLv": 0, + "spine": 0 + }, + { + "warId": 4603, + "actorName": "我军", + "actorId": 0, + "dataId": 0, + "relation": 0, + "outIndex": 4, + "dirction": 1, + "x": 4, + "y": 8, + "var": 505, + "lv": 1, + "hide": 0, + "initial_ai": 1, + "bossid": 0, + "attribute": "&", + "skill": "&", + "seid": "&", + "star": 0, + "quality": 0, + "jobLv": 0, + "spine": 0 + }, + { + "warId": 4603, + "actorName": "我军", + "actorId": 0, + "dataId": 0, + "relation": 0, + "outIndex": 5, + "dirction": 1, + "x": 4, + "y": 5, + "var": 506, + "lv": 1, + "hide": 0, + "initial_ai": 1, + "bossid": 0, + "attribute": "&", + "skill": "&", + "seid": "&", + "star": 0, + "quality": 0, + "jobLv": 0, + "spine": 0 + }, + { + "warId": 4603, + "actorName": "典韦", + "actorId": 307, + "dataId": 2001, + "relation": 2, + "outIndex": 0, + "dirction": 0, + "x": 11, + "y": 7, + "var": 2001, + "lv": 1, + "hide": 0, + "initial_ai": 1, + "bossid": 0, + "attribute": "&", + "skill": "&", + "seid": "&", + "star": 0, + "quality": 0, + "jobLv": 0, + "spine": 0 + }, + { + "warId": 4603, + "actorName": "文丑", + "actorId": 355, + "dataId": 2002, + "relation": 2, + "outIndex": 1, + "dirction": 0, + "x": 11, + "y": 6, + "var": 2002, + "lv": 1, + "hide": 0, + "initial_ai": 1, + "bossid": 0, + "attribute": "&", + "skill": "&", + "seid": "&", + "star": 0, + "quality": 0, + "jobLv": 0, + "spine": 0 + }, + { + "warId": 4603, + "actorName": "颜良", + "actorId": 354, + "dataId": 2003, + "relation": 2, + "outIndex": 2, + "dirction": 0, + "x": 12, + "y": 8, + "var": 2003, + "lv": 1, + "hide": 0, + "initial_ai": 1, + "bossid": 0, + "attribute": "&", + "skill": "&", + "seid": "&", + "star": 0, + "quality": 0, + "jobLv": 0, + "spine": 0 + }, + { + "warId": 4603, + "actorName": "郭嘉", + "actorId": 305, + "dataId": 2004, + "relation": 2, + "outIndex": 3, + "dirction": 0, + "x": 12, + "y": 5, + "var": 2004, + "lv": 1, + "hide": 0, + "initial_ai": 1, + "bossid": 0, + "attribute": "&", + "skill": "&", + "seid": "&", + "star": 0, + "quality": 0, + "jobLv": 0, + "spine": 0 + }, + { + "warId": 4603, + "actorName": "孙权", + "actorId": 333, + "dataId": 2005, + "relation": 2, + "outIndex": 4, + "dirction": 0, + "x": 13, + "y": 8, + "var": 2005, + "lv": 1, + "hide": 0, + "initial_ai": 1, + "bossid": 0, + "attribute": "&", + "skill": "&", + "seid": "&", + "star": 0, + "quality": 0, + "jobLv": 0, + "spine": 0 + }, + { + "warId": 4603, + "actorName": "太史慈", + "actorId": 335, + "dataId": 2006, + "relation": 2, + "outIndex": 5, + "dirction": 0, + "x": 13, + "y": 5, + "var": 2006, + "lv": 1, + "hide": 0, + "initial_ai": 1, + "bossid": 0, + "attribute": "&", + "skill": "&", + "seid": "&", + "star": 0, + "quality": 0, + "jobLv": 0, + "spine": 0 + } +] \ No newline at end of file diff --git a/shared/resource/warJsons/4604.json b/shared/resource/warJsons/4604.json new file mode 100644 index 000000000..043620004 --- /dev/null +++ b/shared/resource/warJsons/4604.json @@ -0,0 +1,278 @@ +[ + { + "warId": 4604, + "actorName": "我军", + "actorId": 0, + "dataId": 0, + "relation": 0, + "outIndex": 0, + "dirction": 1, + "x": 6, + "y": 7, + "var": 501, + "lv": 1, + "hide": 0, + "initial_ai": 1, + "bossid": 0, + "attribute": "&", + "skill": "&", + "seid": "&", + "star": 0, + "quality": 0, + "jobLv": 0, + "spine": 0 + }, + { + "warId": 4604, + "actorName": "我军", + "actorId": 0, + "dataId": 0, + "relation": 0, + "outIndex": 1, + "dirction": 1, + "x": 6, + "y": 6, + "var": 502, + "lv": 1, + "hide": 0, + "initial_ai": 1, + "bossid": 0, + "attribute": "&", + "skill": "&", + "seid": "&", + "star": 0, + "quality": 0, + "jobLv": 0, + "spine": 0 + }, + { + "warId": 4604, + "actorName": "我军", + "actorId": 0, + "dataId": 0, + "relation": 0, + "outIndex": 2, + "dirction": 1, + "x": 5, + "y": 8, + "var": 503, + "lv": 1, + "hide": 0, + "initial_ai": 1, + "bossid": 0, + "attribute": "&", + "skill": "&", + "seid": "&", + "star": 0, + "quality": 0, + "jobLv": 0, + "spine": 0 + }, + { + "warId": 4604, + "actorName": "我军", + "actorId": 0, + "dataId": 0, + "relation": 0, + "outIndex": 3, + "dirction": 1, + "x": 5, + "y": 5, + "var": 504, + "lv": 1, + "hide": 0, + "initial_ai": 1, + "bossid": 0, + "attribute": "&", + "skill": "&", + "seid": "&", + "star": 0, + "quality": 0, + "jobLv": 0, + "spine": 0 + }, + { + "warId": 4604, + "actorName": "我军", + "actorId": 0, + "dataId": 0, + "relation": 0, + "outIndex": 4, + "dirction": 1, + "x": 4, + "y": 8, + "var": 505, + "lv": 1, + "hide": 0, + "initial_ai": 1, + "bossid": 0, + "attribute": "&", + "skill": "&", + "seid": "&", + "star": 0, + "quality": 0, + "jobLv": 0, + "spine": 0 + }, + { + "warId": 4604, + "actorName": "我军", + "actorId": 0, + "dataId": 0, + "relation": 0, + "outIndex": 5, + "dirction": 1, + "x": 4, + "y": 5, + "var": 506, + "lv": 1, + "hide": 0, + "initial_ai": 1, + "bossid": 0, + "attribute": "&", + "skill": "&", + "seid": "&", + "star": 0, + "quality": 0, + "jobLv": 0, + "spine": 0 + }, + { + "warId": 4604, + "actorName": "庞舞", + "actorId": 352, + "dataId": 2001, + "relation": 2, + "outIndex": 0, + "dirction": 0, + "x": 11, + "y": 7, + "var": 2001, + "lv": 1, + "hide": 0, + "initial_ai": 1, + "bossid": 0, + "attribute": "&", + "skill": "&", + "seid": "&", + "star": 0, + "quality": 0, + "jobLv": 0, + "spine": 0 + }, + { + "warId": 4604, + "actorName": "文丑", + "actorId": 354, + "dataId": 2002, + "relation": 2, + "outIndex": 1, + "dirction": 0, + "x": 11, + "y": 6, + "var": 2002, + "lv": 1, + "hide": 0, + "initial_ai": 1, + "bossid": 0, + "attribute": "&", + "skill": "&", + "seid": "&", + "star": 0, + "quality": 0, + "jobLv": 0, + "spine": 0 + }, + { + "warId": 4604, + "actorName": "颜良", + "actorId": 355, + "dataId": 2003, + "relation": 2, + "outIndex": 2, + "dirction": 0, + "x": 12, + "y": 8, + "var": 2003, + "lv": 1, + "hide": 0, + "initial_ai": 1, + "bossid": 0, + "attribute": "&", + "skill": "&", + "seid": "&", + "star": 0, + "quality": 0, + "jobLv": 0, + "spine": 0 + }, + { + "warId": 4604, + "actorName": "郭嘉", + "actorId": 305, + "dataId": 2004, + "relation": 2, + "outIndex": 3, + "dirction": 0, + "x": 12, + "y": 5, + "var": 2004, + "lv": 1, + "hide": 0, + "initial_ai": 1, + "bossid": 0, + "attribute": "&", + "skill": "&", + "seid": "&", + "star": 0, + "quality": 0, + "jobLv": 0, + "spine": 0 + }, + { + "warId": 4604, + "actorName": "华佗", + "actorId": 346, + "dataId": 2005, + "relation": 2, + "outIndex": 4, + "dirction": 0, + "x": 13, + "y": 8, + "var": 2005, + "lv": 1, + "hide": 0, + "initial_ai": 1, + "bossid": 0, + "attribute": "&", + "skill": "&", + "seid": "&", + "star": 0, + "quality": 0, + "jobLv": 0, + "spine": 0 + }, + { + "warId": 4604, + "actorName": "王平", + "actorId": 330, + "dataId": 2006, + "relation": 2, + "outIndex": 5, + "dirction": 0, + "x": 13, + "y": 5, + "var": 2006, + "lv": 1, + "hide": 0, + "initial_ai": 1, + "bossid": 0, + "attribute": "&", + "skill": "&", + "seid": "&", + "star": 0, + "quality": 0, + "jobLv": 0, + "spine": 0 + } +] \ No newline at end of file diff --git a/shared/resource/warJsons/4605.json b/shared/resource/warJsons/4605.json new file mode 100644 index 000000000..b9987d3c4 --- /dev/null +++ b/shared/resource/warJsons/4605.json @@ -0,0 +1,278 @@ +[ + { + "warId": 4605, + "actorName": "我军", + "actorId": 0, + "dataId": 0, + "relation": 0, + "outIndex": 0, + "dirction": 1, + "x": 6, + "y": 7, + "var": 501, + "lv": 1, + "hide": 0, + "initial_ai": 1, + "bossid": 0, + "attribute": "&", + "skill": "&", + "seid": "&", + "star": 0, + "quality": 0, + "jobLv": 0, + "spine": 0 + }, + { + "warId": 4605, + "actorName": "我军", + "actorId": 0, + "dataId": 0, + "relation": 0, + "outIndex": 1, + "dirction": 1, + "x": 6, + "y": 6, + "var": 502, + "lv": 1, + "hide": 0, + "initial_ai": 1, + "bossid": 0, + "attribute": "&", + "skill": "&", + "seid": "&", + "star": 0, + "quality": 0, + "jobLv": 0, + "spine": 0 + }, + { + "warId": 4605, + "actorName": "我军", + "actorId": 0, + "dataId": 0, + "relation": 0, + "outIndex": 2, + "dirction": 1, + "x": 5, + "y": 8, + "var": 503, + "lv": 1, + "hide": 0, + "initial_ai": 1, + "bossid": 0, + "attribute": "&", + "skill": "&", + "seid": "&", + "star": 0, + "quality": 0, + "jobLv": 0, + "spine": 0 + }, + { + "warId": 4605, + "actorName": "我军", + "actorId": 0, + "dataId": 0, + "relation": 0, + "outIndex": 3, + "dirction": 1, + "x": 5, + "y": 5, + "var": 504, + "lv": 1, + "hide": 0, + "initial_ai": 1, + "bossid": 0, + "attribute": "&", + "skill": "&", + "seid": "&", + "star": 0, + "quality": 0, + "jobLv": 0, + "spine": 0 + }, + { + "warId": 4605, + "actorName": "我军", + "actorId": 0, + "dataId": 0, + "relation": 0, + "outIndex": 4, + "dirction": 1, + "x": 4, + "y": 8, + "var": 505, + "lv": 1, + "hide": 0, + "initial_ai": 1, + "bossid": 0, + "attribute": "&", + "skill": "&", + "seid": "&", + "star": 0, + "quality": 0, + "jobLv": 0, + "spine": 0 + }, + { + "warId": 4605, + "actorName": "我军", + "actorId": 0, + "dataId": 0, + "relation": 0, + "outIndex": 5, + "dirction": 1, + "x": 4, + "y": 5, + "var": 506, + "lv": 1, + "hide": 0, + "initial_ai": 1, + "bossid": 0, + "attribute": "&", + "skill": "&", + "seid": "&", + "star": 0, + "quality": 0, + "jobLv": 0, + "spine": 0 + }, + { + "warId": 4605, + "actorName": "黄盖", + "actorId": 362, + "dataId": 2001, + "relation": 2, + "outIndex": 0, + "dirction": 0, + "x": 11, + "y": 7, + "var": 2001, + "lv": 1, + "hide": 0, + "initial_ai": 1, + "bossid": 0, + "attribute": "&", + "skill": "&", + "seid": "&", + "star": 0, + "quality": 0, + "jobLv": 0, + "spine": 0 + }, + { + "warId": 4605, + "actorName": "周泰", + "actorId": 332, + "dataId": 2002, + "relation": 2, + "outIndex": 1, + "dirction": 0, + "x": 11, + "y": 6, + "var": 2002, + "lv": 1, + "hide": 0, + "initial_ai": 1, + "bossid": 0, + "attribute": "&", + "skill": "&", + "seid": "&", + "star": 0, + "quality": 0, + "jobLv": 0, + "spine": 0 + }, + { + "warId": 4605, + "actorName": "马云禄", + "actorId": 327, + "dataId": 2003, + "relation": 2, + "outIndex": 2, + "dirction": 0, + "x": 12, + "y": 8, + "var": 2003, + "lv": 1, + "hide": 0, + "initial_ai": 1, + "bossid": 0, + "attribute": "&", + "skill": "&", + "seid": "&", + "star": 0, + "quality": 0, + "jobLv": 0, + "spine": 0 + }, + { + "warId": 4605, + "actorName": "孙乾", + "actorId": 331, + "dataId": 2004, + "relation": 2, + "outIndex": 3, + "dirction": 0, + "x": 12, + "y": 5, + "var": 2004, + "lv": 1, + "hide": 0, + "initial_ai": 1, + "bossid": 0, + "attribute": "&", + "skill": "&", + "seid": "&", + "star": 0, + "quality": 0, + "jobLv": 0, + "spine": 0 + }, + { + "warId": 4605, + "actorName": "小乔", + "actorId": 340, + "dataId": 2005, + "relation": 2, + "outIndex": 4, + "dirction": 0, + "x": 13, + "y": 8, + "var": 2005, + "lv": 1, + "hide": 0, + "initial_ai": 1, + "bossid": 0, + "attribute": "&", + "skill": "&", + "seid": "&", + "star": 0, + "quality": 0, + "jobLv": 0, + "spine": 0 + }, + { + "warId": 4605, + "actorName": "麹义", + "actorId": 350, + "dataId": 2006, + "relation": 2, + "outIndex": 5, + "dirction": 0, + "x": 13, + "y": 5, + "var": 2006, + "lv": 1, + "hide": 0, + "initial_ai": 1, + "bossid": 0, + "attribute": "&", + "skill": "&", + "seid": "&", + "star": 0, + "quality": 0, + "jobLv": 0, + "spine": 0 + } +] \ No newline at end of file