diff --git a/game-server/app/servers/battle/handler/pvpHandler.ts b/game-server/app/servers/battle/handler/pvpHandler.ts index 6240fc258..60819cdc7 100644 --- a/game-server/app/servers/battle/handler/pvpHandler.ts +++ b/game-server/app/servers/battle/handler/pvpHandler.ts @@ -3,10 +3,10 @@ import { WAR_TYPE } from './../../../consts/constModules/battleConst'; import { Application, BackendSession, pinus, HandlerService, } from 'pinus'; import { findIndex } from 'underscore'; import { gameData, getPvpBoxBySeasonNumAndIndex } from '../../../pubUtils/data'; -import { refreshEnemies, getEnemies, refChallengeCnt, generPVPOppRecInfo, generMyRecInfo, sendLastSeasonRewardIfNotSent, refreshRefOppCnt, generPvpLineupCe, calLineupScore, checkPvpSeasonIsStart, checkPvpSeasonIsSummit, getPvpSeasonStatus, checkPvpSeasonIsWaiting } from '../../../services/pvpService'; +import { refreshEnemies, getEnemies, refChallengeCnt, generPVPOppRecInfo, generMyRecInfo, sendLastSeasonRewardIfNotSent, refreshRefOppCnt, generPvpLineupCe, calLineupScore, checkPvpSeasonIsStart, checkPvpSeasonIsSummit, getPvpSeasonStatus, checkPvpSeasonIsWaiting, refreshBuyChallengeCnt } from '../../../services/pvpService'; import { RoleModel, RoleType } from '../../../db/Role'; import { STATUS } from '../../../consts/statusCode'; -import { resResult, genCode, checkRoleIsRobot, robotIdComBack } from '../../../pubUtils/util'; +import { resResult, genCode, checkRoleIsRobot, robotIdComBack, parseGoodStr } from '../../../pubUtils/util'; import { PvpDefenseModel, pvpUpdateInter } from '../../../db/PvpDefense'; import { PvpSeasonResultModel } from '../../../db/PvpSeasonResult'; import { Rank } from '../../../services/rankService'; @@ -17,7 +17,7 @@ import { PVP } from '../../../pubUtils/dicParam'; import { addItems, getGoldObject, handleCost, unlockFigure } from '../../../services/role/rewardService'; import { pick } from "underscore"; import { HeroModel } from '../../../db/Hero'; -import PvpHistoryOpp, { PvpHistoryOppModel } from '../../../db/PvpHistoryOpp'; +import PvpHistoryOpp, { PvpHistoryOppModel, PvpHistoryOppType } from '../../../db/PvpHistoryOpp'; import { BattleRecordModel } from '../../../db/BattleRecord'; import { PvpRecordModel, PvpRecordParam, PvpRecordType } from '../../../db/PvpRecord'; import { pvpEndParamInter } from '../../../pubUtils/interface'; @@ -77,6 +77,10 @@ export class PvpHandler { update = { ...update, ...refOppObj } } + if (refreshBuyChallengeCnt(pvpDefense.buyChallengeTime)) { + update = { ...update, buyChallengeCnt: 0, buyChallengeTime: Date.now() }; + } + if(Object.keys(update).length > 0) { pvpDefense = await PvpDefenseModel.updateInfoAndInclude(roleId, update); } @@ -695,6 +699,144 @@ export class PvpHandler { }); } + + async buyChallengeCnt(msg: { count: number }, session: BackendSession) { + let { count } = msg; + let roleId = session.get('roleId'); + let sid: string = session.get('sid'); + + let seasonEndTime: number = this.app.get('pvpSeasonEndTime'); + + let pvpDefense = await PvpDefenseModel.findByRoleId(roleId); + if (!pvpDefense) return resResult(STATUS.PVP_NOT_OPEN); + let isRefreshBuyChallengeCnt = refreshBuyChallengeCnt(pvpDefense.buyChallengeTime); + if (isRefreshBuyChallengeCnt) pvpDefense.buyChallengeCnt = 0; + + if (count + pvpDefense.buyChallengeCnt > PVP.PVP_CHALLENGE_COST_TIMES) { + return resResult(STATUS.PVP_CAN_NOT_BUY_CHALLENGE_CAT); + } + let cost = parseGoodStr(PVP.PVP_CHALLENGE_BUY_TIMES_COST); + for (let cur of cost) { + cur.count = cur.count * count; + } + let costResult = await handleCost(roleId, sid, cost, ITEM_CHANGE_REASON.PVP_BUY_CHALLENGE_CNT); + if (!costResult) return resResult(STATUS.ROLE_MATERIAL_NOT_ENOUGH); + + // 刷新次数 + let refChallengeObj = await refChallengeCnt(pvpDefense.challengeCnt, pvpDefense.challengeRefTime, seasonEndTime, roleId, session.get('vipStartTime')); + let challengeCnt = refChallengeObj.challengeCnt + count; + + pvpDefense = await PvpDefenseModel.updateInfoAndInclude(roleId, { challengeCnt, buyChallengeCnt: pvpDefense.buyChallengeCnt + count, buyChallengeTime: Date.now() }); + if (!pvpDefense) return resResult(STATUS.PVP_BUY_CHALLENGE_FAIL) + return resResult(STATUS.SUCCESS, { challengeCnt: pvpDefense.challengeCnt, buyChallengeCnt: pvpDefense.buyChallengeCnt }) + } + + async sweep(msg: { warId: number, oppRoleId: string }, session: BackendSession) { + let roleId = session.get('roleId'); + let roleName = session.get('roleName'); + let sid = session.get('sid'); + const serverId = session.get('serverId'); + + const { warId, oppRoleId } = msg; + let warInfo = gameData.war.get(warId); + if (!warInfo) { + return resResult(STATUS.BATTLE_MISS_INFO); + } + const role = await RoleModel.findByRoleId(roleId, null, true); + if (!role || role.lv < 50) return resResult(STATUS.PVP_NOT_OPEN); + + let pvpDefense = await PvpDefenseModel.findByRoleId(roleId); + if (!pvpDefense) return resResult(STATUS.PVP_NOT_OPEN); + let { hisWinStreakNum = 0 } = pvpDefense; + + // 检查挑战次数 + let seasonNum: number = this.app.get('pvpSeasonNum'); + let seasonEndTime: number = this.app.get('pvpSeasonEndTime'); + let { challengeCnt, challengeRefTime } = await refChallengeCnt(pvpDefense.challengeCnt, pvpDefense.challengeRefTime, seasonEndTime, roleId, session.get('vipStartTime')); + if (challengeCnt == 0) { + return resResult(STATUS.PVP_CHALLENGE_TIMES_NOT_ENOUGH); + } + + let { attackCe } = PvpDataReturn.getAttackAndDefenseCe(pvpDefense); + let curOpp = pvpDefense.oppPlayers.find(cur => cur.roleId == oppRoleId); + if (!curOpp) return resResult(STATUS.PVP_ROLE_NOT_FOUND); + let oppDef = curOpp.oppDef; + // 战力检测 + console.log('xxxxxxxxxxxxxxxxxxxxxxxxx attackCe',attackCe) + console.log('xxxxxxxxxxxxxxxxxxxxxxxxx oppDef',oppDef) + + if (attackCe <= oppDef.defCe) return resResult(STATUS.PVP_SWEEP_NOT_CE); + + // 对手记录更新 + await PvpHistoryOppModel.setStatus(curOpp.oppDef.toString(), 1); + + // 战斗记录 + const battleCode = genCode(8) + '_sweep'; // 关卡唯一值 + let heroes = pvpDefense.attack.heroes.map(cur => cur.actorId); + await BattleRecordModel.updateBattleRecordByCode(battleCode, { + $set: { + roleId, roleName, battleId: warId, + status: 0, + warName: warInfo.gk_name, + warType: warInfo.warType, + record: { heroes, pos: curOpp.pos, oppRoleId, pvpSeasonNum: seasonNum } + } + }, true); + + let update: pvpUpdateInter = {}; + const myHeroes: pvpEndParamInter[] = heroes.map(hid => { return { hid, damage: 0, heal: 0, underDamage: 0 } }) + const myRecInfo = await generMyRecInfo(pvpDefense, role, true, curOpp.pos, myHeroes); + let { attackInfo, showHeroScores, updateParam } = myRecInfo + update = { ...update, ...updateParam }; + + const oppHeroes: pvpEndParamInter[] = oppDef.heroes.map(cur => { return { hid: cur.actorId, damage: 0, heal: 0, underDamage: 0 } }) + const defenseInfo = await generPVPOppRecInfo(true, curOpp, oppHeroes, serverId); + + + update = { ...update, oppBeforePlayers: pvpDefense.oppPlayers }; + + // 刷新对手 + let oppPlayers = await refreshEnemies(role, seasonNum, pvpDefense.score, pvpDefense.attack.score, pvpDefense.attack.pLv || 1); + update.oppPlayers = oppPlayers; + + // 减少挑战次数 + let refChallengeObj = await refChallengeCnt(pvpDefense.challengeCnt, pvpDefense.challengeRefTime, seasonEndTime, roleId, session.get('vipStartTime')); + refChallengeObj.challengeCnt--; + update = { ...update, ...refChallengeObj }; + + pvpDefense = await PvpDefenseModel.updateInfoAndInclude(roleId, update); + + let result = new PvpDataReturn(); // 返回对象 + result.setPvpDefense(pvpDefense); + + // 加入排行榜 + let groupId = await getPVPGroupIdOfServer(serverId); + let r = new Rank(REDIS_KEY.PVP_RANK, { seasonNum, groupId }); + await r.setRankWithRoleInfo(roleId, pvpDefense.score, pvpDefense.updatedAt.getTime(), role); + if (defenseInfo && defenseInfo.score > 0) await r.setRankWithRoleInfo(defenseInfo.roleId, defenseInfo.score, pvpDefense.updatedAt.getTime(), null, true); + + let myRank = await r.getMyRank({ roleId }); + result.setMyRank(myRank); + + let oppPlayersReturn = await getEnemies(r, pvpDefense.oppPlayers, pvpDefense.winStreakNum); + result.setOppPlayers(oppPlayersReturn); + + await checkTaskInPvpEnd(serverId, roleId, sid, true, pvpDefense.heroScores, pvpDefense.seasonWinNum); + if (hisWinStreakNum < pvpDefense.hisWinStreakNum) { + await unlockFigure(sid, roleId, [{ type: FIGURE_UNLOCK_CONDITION.PVP_WIN_SERIES, paramWinStreakNum: pvpDefense.hisWinStreakNum }]); + } + + return resResult(STATUS.SUCCESS, { + battleCode, isSuccess: true, + heroScores: showHeroScores, + createdAt: getSeconds(new Date()), + ...pick(result, ['score', 'myRank', 'winStreakNum', 'attack', 'oppPlayers', 'challengeCnt', 'challengeRefTime', 'seasonWinNum']) + }); + + } + + + // debug接口 diff --git a/game-server/app/services/checkParam.ts b/game-server/app/services/checkParam.ts index 3c5698270..7cbd205e5 100644 --- a/game-server/app/services/checkParam.ts +++ b/game-server/app/services/checkParam.ts @@ -769,6 +769,17 @@ export function checkRouteParam(route: string, msg: any) { if (!checkNaturalNumbers(msg.id)) return false; break; } + case "battle.pvpHandler.buyChallengeCnt": + { + if (!checkNaturalNumbers(msg.count)) return false; + break; + } + case "battle.pvpHandler.sweep": + { + if (!checkNaturalNumbers(msg.warId)) return false; + if (!checkNaturalStrings(msg.oppRoleId)) return false; + break; + } case "battle.ladderHandler.getOppLineup": { if (!checkNaturalStrings(msg.roleId)) return false; diff --git a/game-server/app/services/pvpService.ts b/game-server/app/services/pvpService.ts index 3041cb910..c0c66016a 100644 --- a/game-server/app/services/pvpService.ts +++ b/game-server/app/services/pvpService.ts @@ -2,14 +2,14 @@ import { PvpDefenseModel, PvpDefenseType, pvpUpdateInter } from '../db/PvpDefense'; import { Defense, Attack, LineupCe, OppPlayer, HeroScore, HeroReward, OppPlayerReturn, AttackHero, DefenseHero } from '../domain/battleField/pvp'; import { RoleType } from '../db/Role'; -import { REDIS_KEY, TASK_TYPE, MAIL_TYPE, TA_EVENT, ITID, getHeadItid, getFrameItid, getSpineItid, PVP_SEASON_STATUS } from '../consts'; +import { REDIS_KEY, TASK_TYPE, MAIL_TYPE, TA_EVENT, ITID, getHeadItid, getFrameItid, getSpineItid, PVP_SEASON_STATUS, SHOP_REFRESH_TYPE } from '../consts'; import { dicPvpOpponent, DicPvpOpponent } from "../pubUtils/dictionary/DicPvpOpponent"; import { getRandSingleIndex, genCode, shouldRefresh, getChineseName, makeRobotId, robotIdComBack, getRandSingleEelm } from '../pubUtils/util'; import { pvpEndParamInter, RewardInter } from '../pubUtils/interface'; import { gameData, getPLvByScore, getPvpHeroRewardsByScore, getPvpRankRewardsByRank, getPvpDifficultByScore, getPlvAndScore, getPvpBoxsBySeasonNum, getPvpRankMaxRewardsBySeasonNum, randomGoodsByItid } from "../pubUtils/data"; import { EXTERIOR, PVP } from '../pubUtils/dicParam'; import { PVPConfigModel } from '../db/PvpConfig' -import { nowSeconds, getTimeFun } from '../pubUtils/timeUtil'; +import { nowSeconds, getTimeFun, getZeroPointD } from '../pubUtils/timeUtil'; import { HeroesRecord, PvpRecordPlayerInfo } from '../db/PvpRecord'; import { HeroModel, HeroType } from '../db/Hero'; import { AttributeCal } from '../domain/roleField/attribute'; @@ -539,36 +539,36 @@ export async function generPVPOppRecInfo(isSuccess: boolean, curOpp: OppPlayer, } let addSumScore = 0; let pvpDefense = curOpp.isRobot? null: await PvpDefenseModel.findByRoleId(robotIdComBack(curOpp.roleId)); - if(pvpDefense && !isSuccess) { - if(pvpDefense && pvpDefense.defense) { - let { attack, defense, heroScores, score, defenseScoreCnt, refDefenseScore } = pvpDefense; - if(shouldRefresh(refDefenseScore, new Date())) { - defenseScoreCnt = 0; refDefenseScore = new Date(); - } - if(defenseScoreCnt < PVP.PVP_DEFENSE_SUCCESS_REWARD_MAX_CNT) { - for(let { actorId } of defense.heroes) { - let hs = heroScores.find(cur => cur.hid == actorId); - const dicOpp = gameData.pvpOpponent.get(curOpp.pos); - let addScore = PVP.PVP_DEFENSE_SUCCESS_REWARD - dicOpp.score; - if(hs) { - hs.score += addScore; - } else { - heroScores.push({ hid: actorId, score: addScore }) - } - addSumScore += addScore; - } + // if(pvpDefense && !isSuccess) { + // if(pvpDefense && pvpDefense.defense) { + // let { attack, defense, heroScores, score, defenseScoreCnt, refDefenseScore } = pvpDefense; + // if(shouldRefresh(refDefenseScore, new Date())) { + // defenseScoreCnt = 0; refDefenseScore = new Date(); + // } + // if(defenseScoreCnt < PVP.PVP_DEFENSE_SUCCESS_REWARD_MAX_CNT) { + // for(let { actorId } of defense.heroes) { + // let hs = heroScores.find(cur => cur.hid == actorId); + // const dicOpp = gameData.pvpOpponent.get(curOpp.pos); + // let addScore = PVP.PVP_DEFENSE_SUCCESS_REWARD - dicOpp.score; + // if(hs) { + // hs.score += addScore; + // } else { + // heroScores.push({ hid: actorId, score: addScore }) + // } + // addSumScore += addScore; + // } - let newAttack = calLineupScore(attack, heroScores); - let newDefense = calLineupScore(defense, heroScores); + // let newAttack = calLineupScore(attack, heroScores); + // let newDefense = calLineupScore(defense, heroScores); - await PvpDefenseModel.updateInfo(pvpDefense.roleId, { attack: newAttack, defense: newDefense, heroScores, score: score + addSumScore, defenseScoreCnt: defenseScoreCnt + 1, refDefenseScore }); + // await PvpDefenseModel.updateInfo(pvpDefense.roleId, { attack: newAttack, defense: newDefense, heroScores, score: score + addSumScore, defenseScoreCnt: defenseScoreCnt + 1, refDefenseScore }); - } else { - await PvpDefenseModel.updateInfo(pvpDefense.roleId, { defenseScoreCnt: defenseScoreCnt + 1, refDefenseScore }); - } - } - } + // } else { + // await PvpDefenseModel.updateInfo(pvpDefense.roleId, { defenseScoreCnt: defenseScoreCnt + 1, refDefenseScore }); + // } + // } + // } let defenseInfo = new PvpRecordPlayerInfo(); defenseInfo.setByHistoryOpp(oppRole, oppHeroRecords, !isSuccess, isSuccess ? 0 : addSumScore, pvpDefense?.serverId||serverId) @@ -697,8 +697,8 @@ export async function savePvpSeasonResult(pvpDefense: PvpDefenseType, seasonNum: } newScore += pvpHeroReward.heroscore; } else { - newHeroScores.push(heroScore); - newScore += heroScore.score; + newHeroScores.push({...heroScore, score:0}); + // newScore += heroScore.score; } } @@ -793,4 +793,12 @@ export function checkPvpSeasonIsSummit() { export function checkPvpSeasonIsWaiting() { let status = getPvpSeasonStatus(); return status == PVP_SEASON_STATUS.WAITING; +} + +export function refreshBuyChallengeCnt(buyChallengeTime:number = 0){ + let refTime = getZeroPointD(SHOP_REFRESH_TYPE.DAILY); + if(refTime.getTime() > buyChallengeTime){ + return true + } + return false; } \ No newline at end of file diff --git a/shared/consts/constModules/sysConst.ts b/shared/consts/constModules/sysConst.ts index d3271e8b3..1533ef579 100644 --- a/shared/consts/constModules/sysConst.ts +++ b/shared/consts/constModules/sysConst.ts @@ -1288,6 +1288,7 @@ export enum ITEM_CHANGE_REASON { NOVEMBER_COST = 208, // 辜月集会购买消耗 EXCHANGE_SPIRIT = 209, // 将灵合成 RESONANCE_LOCK_POSITION = 210, // 共鸣解锁阵位消耗 + PVP_BUY_CHALLENGE_CNT = 211, // 巅峰演武购买挑战次数消耗 } export enum TA_EVENT { diff --git a/shared/consts/statusCode.ts b/shared/consts/statusCode.ts index 46d385ed0..f6b125eb1 100644 --- a/shared/consts/statusCode.ts +++ b/shared/consts/statusCode.ts @@ -195,6 +195,11 @@ export const STATUS = { PVP_SEASON_NOT_OPEN: { code: 20809, simStr: 'pvp赛季未开启' }, PVP_CAN_NOT_SAVE_DEFENSE: { code: 20810, simStr: '结算期不可保存防守阵容' }, PVP_CAN_NOT_CHANGE_HERO: { code: 20811, simStr: '只可用于设置副将不可变更武将' }, + PVP_CAN_NOT_BUY_CHALLENGE_CAT: { code: 20812, simStr: '超过当日可购买次数, 不可购买' }, + PVP_BUY_CHALLENGE_FAIL: { code: 20813, simStr: '购买失败' }, + PVP_SWEEP_NOT_CE: { code: 20814, simStr: '碾压战力不足' }, + + // 军团 20900-20999 GUILD_AUTH_NOT_ENOUGH: { code: 20900, simStr: '权限不足' }, @@ -845,9 +850,9 @@ export const STATUS = { RESONANCE_PUT_NOT_POSITION: { code: 81012, simStr: '武将数量不足,不可上阵' }, RESONANCE_NOT_PUT_POSITION: { code: 81013, simStr: '该武将未在阵中' }, RESONANCE_OFF_POSITION_FAIL: { code: 81014, simStr: '该武将下阵失败' }, - RESONANCE__HID_NOT_CAN: { code: 81015, simStr: '共鸣武将不可养成' }, - RESONANCE__HID_NOT_REBIRTH: { code: 81015, simStr: '共鸣武将不可重生' }, - RESONANCE__HID_NOT_REBORN: { code: 81015, simStr: '共鸣武将不可传承' }, + RESONANCE__HID_NOT_CAN: { code: 81016, simStr: '共鸣武将不可养成' }, + RESONANCE__HID_NOT_REBIRTH: { code: 81017, simStr: '共鸣武将不可重生' }, + RESONANCE__HID_NOT_REBORN: { code: 81018, simStr: '共鸣武将不可传承' }, @@ -855,6 +860,7 @@ export const STATUS = { + } export const PAY_37_CALLBACK_CODE = { diff --git a/shared/db/PvpDefense.ts b/shared/db/PvpDefense.ts index 3fd59a986..6b03f6d07 100644 --- a/shared/db/PvpDefense.ts +++ b/shared/db/PvpDefense.ts @@ -68,6 +68,11 @@ export default class PvpDefense extends BaseModel { @prop({ required: true }) refDefenseScore: Date; + @prop({required: true, default : 0}) + buyChallengeCnt:number; // 每日已购买次数 + @prop({ required: true, default: 0 }) + buyChallengeTime: number; // 上一次购买时间 + public static async findByRoleId(roleId: string, getters = false) { const result: PvpDefenseType = await PvpDefenseModel.findOne({ roleId }).lean({ getters}); return result; diff --git a/shared/domain/battleField/pvp.ts b/shared/domain/battleField/pvp.ts index 42ab6e5a2..f5d11f70d 100644 --- a/shared/domain/battleField/pvp.ts +++ b/shared/domain/battleField/pvp.ts @@ -277,6 +277,7 @@ export class PvpDataReturn { heroScores: HeroScoreReturn[] = []; hasSaveDefense: boolean = false; resultRecord: PvpSeasonResultRecord; + buyChallengeCnt: number = 0; setPvpDefense(pvpDefense: PvpDefenseType) { this.score = pvpDefense.score; @@ -296,7 +297,7 @@ export class PvpDataReturn { if(pvpDefense.defense) this.defense = new DefenseLineupReturn(pvpDefense.defense, defenseCe); this.heroScores = pvpDefense.heroScores.map(cur => new HeroScoreReturn(cur, pvpDefense.defense)); - + this.buyChallengeCnt = pvpDefense.buyChallengeCnt; } static getAttackAndDefenseCe(pvpDefense: PvpDefenseType) { diff --git a/shared/pubUtils/data.ts b/shared/pubUtils/data.ts index 552ca3cbd..9b403ceee 100644 --- a/shared/pubUtils/data.ts +++ b/shared/pubUtils/data.ts @@ -639,7 +639,13 @@ export function getPLvByScore(score: number) { export function getPlvAndScore(scores: number[] = []) { if (scores.length <= 0) scores = [0]; - let maxScore = Math.max(...scores); // 等级:军功最高者的军功*6 + // let maxScore = Math.max(...scores); // 等级:军功最高者的军功*6 + scores = scores.sort((a, b) => { + if (a !== b) { + return b - a; + } + }); + let maxScore = scores.slice(0, 6).reduce((acc, curr) => acc + curr, 0); let score = scores.reduce((pre, cur) => pre + cur, 0); return { score, pLv: getPLvByScore(maxScore * param.PVP.PVP_LINEUP_HEROS) }; } diff --git a/shared/pubUtils/dicParam.ts b/shared/pubUtils/dicParam.ts index 12d0d05c2..202733fd8 100644 --- a/shared/pubUtils/dicParam.ts +++ b/shared/pubUtils/dicParam.ts @@ -44,6 +44,8 @@ export const PVP = { PVP_MATCH_ROBOT: 1500, // 巅峰演武多少分以下匹配的全是机器人(该分以上及其该分优先匹配真人) PVP_RECORD_SOCRE: 1500, // 巅峰演武达到多少分可以查看战报 PVP_NEWSEASON_SHOWTIME: 259200, // 巅峰演武新赛季开启动画显示的秒数 + PVP_CHALLENGE_COST_TIMES: 5, // 巅峰演武每天购买挑战次数上限 + PVP_CHALLENGE_BUY_TIMES_COST: '31002&100&2|31002&150&3', // 名将擂台每天购买挑战次数花费 物品id&数量&购买次数 }; export const ARMY = { ARMY_CREAT_COST: 500, // 创建军团需要的元宝 @@ -379,7 +381,7 @@ export const ACTIVITY = { ACTIVITY_JUMP_TIME: 90, // 登高总时长 ACTIVITY_JUMP_SCORE: '0&1|1&1|2&2', // 云类型&登高分数 ACTIVITY_THROWING_COUNT: 10, // 投壶次数 - ACTIVITY_THROWING_SCORE: '0&4|1&3|2&2|3&1', // 投壶分数 + ACTIVITY_THROWING_SCORE: '0&2|1&3|2&4|3&2', // 投壶分数 }; export const BATTLE_PREPARING = { CHANGE_ORDER_OPEN: 109, // 出兵界面行动顺序按钮开启关卡