From a830ae040ed19de02e1c7540b5359487a98c929f Mon Sep 17 00:00:00 2001 From: luying Date: Mon, 19 Sep 2022 15:15:16 +0800 Subject: [PATCH] =?UTF-8?q?=E9=95=87=E5=BF=B5=E5=A1=94=EF=BC=9A=E6=94=AF?= =?UTF-8?q?=E6=8C=81=E5=A4=9A=E5=B1=82=E7=A2=BE=E5=8E=8B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../battle/handler/towerBattleHandler.ts | 61 ++++++++++--------- game-server/app/services/battleService.ts | 36 +++++++++-- game-server/app/services/checkParam.ts | 6 +- shared/db/Role.ts | 5 ++ shared/db/TowerRecord.ts | 22 ++++--- 5 files changed, 86 insertions(+), 44 deletions(-) diff --git a/game-server/app/servers/battle/handler/towerBattleHandler.ts b/game-server/app/servers/battle/handler/towerBattleHandler.ts index 356ae7d35..415d7f6b1 100644 --- a/game-server/app/servers/battle/handler/towerBattleHandler.ts +++ b/game-server/app/servers/battle/handler/towerBattleHandler.ts @@ -4,10 +4,10 @@ import { TaskHero, TowerTaskRecModel, TowerTaskRecType } from './../../../db/Tow import { HangUpSpdUpRecModel } from './../../../db/HangUpSpdUpRec'; import { HangUpRecordModel } from './../../../db/HangUpRecord'; import { RoleModel } from './../../../db/Role'; -import { TowerRecordModel } from './../../../db/TowerRecord'; +import { TowerRecordModel, WarStatus } from './../../../db/TowerRecord'; import { Application, BackendSession } from 'pinus'; import { resResult, genCode, shouldRefresh } from '../../../pubUtils/util'; -import { calcuHangUpReward, refreshTasks, treatTask, getRemainTime, getTowerStatus, getHungupRewards, getTasks, checkTaskRewards, getTowerTaskCostGold, getManyHangSpdUpCostGold, getTaskStatus, checkForbiddenChar, checkAndStartHungUp, createNewTowerRecord, getTowerRecByLv } from '../../../services/battleService'; +import { calcuHangUpReward, refreshTasks, treatTask, getRemainTime, getTowerStatus, getHungupRewards, getTasks, checkTaskRewards, getTowerTaskCostGold, getManyHangSpdUpCostGold, getTaskStatus, checkForbiddenChar, checkAndStartHungUp, createNewTowerRecord, getTowerRecByLv, getTowerStatusByWarId, getTowerHeroCe, getWarStatusByLv } from '../../../services/battleService'; import { addItems, getGoldObject, handleCost } from '../../../services/role/rewardService'; import { checkBattleHeroes } from '../../../services/normalBattleService'; import { gameData } from '../../../pubUtils/data'; @@ -16,7 +16,7 @@ import { HeroModel } from '../../../db/Hero'; import { vipCanSkipTower } from '../../../services/activity/monthlyTicketService'; import { pushTowerMsg } from '../../../services/sysChatService'; import { WarStar } from '../../../domain/dbGeneral'; -import { RewardInter } from '../../../pubUtils/interface'; +import { ItemInter, RewardInter } from '../../../pubUtils/interface'; import { combineItems } from '../../../services/role/util'; import { checkTaskInSkipTower } from '../../../services/task/taskService'; import { Rank } from '../../../services/rankService'; @@ -291,7 +291,9 @@ export class TowerBattleHandler { return resResult(STATUS.SUCCESS, { curTasks: treatTask(curTasks, curTime), goods, refRemainTime, nextCostGold: costGold }); } - async skipTower(msg: { }, session: BackendSession) { + async skipTower(msg: { toLv: number }, session: BackendSession) { + const { toLv } = msg; + let roleId = session.get('roleId'); let roleName = session.get('roleName'); let serverId = session.get('serverId'); @@ -304,40 +306,39 @@ export class TowerBattleHandler { return resResult(STATUS.TOWER_CANNOT_SKIP); } - let { warStatus, heroes: recHeroes } = await getTowerRecByLv(roleId, oldTowerLv); - // 检查战力是否足够 + let towerRec = await TowerRecordModel.getRecordByLv(roleId, oldTowerLv); let heroes = await HeroModel.findByRole(roleId, [{ field: 'ce', sortBy: -1 }], 'hid ce job', true); - let recommendCeSum = 0, heroesCeSum = 0; - let newWarStar: WarStar[] = []; - for(let { warId, status } of warStatus) { - if(!status) { - let dicWar = gameData.war.get(warId); - recommendCeSum += dicWar.recommendedPower; - let heroNum = 0; - for(let hero of heroes) { - if(recHeroes.indexOf(hero.hid) == -1 && !checkForbiddenChar(hero.hid, hero.job, dicWar.fobiddenCharactor)) { - heroNum++; - recHeroes.push(hero.hid); - heroesCeSum += hero.ce; - } - if(heroNum >= dicWar.minHeroNum) break; + let newWarStar: WarStar[] = [], resultGoods: { towerLv: number, goods: { id: number, count: number }[] }[] = [], rewards: ItemInter[] = []; + + for(let lv = oldTowerLv; lv < toLv; lv++) { + let dicTower = gameData.tower.get(lv); + let warArray = dicTower?.warArray||[]; + + let recommendCeSum = 0, heroesCeSum = 0; + for(let warId of warArray) { + if(!getTowerStatusByWarId(warId, towerRec?.warStatus)) { + let dicWar = gameData.war.get(warId); + recommendCeSum += dicWar.recommendedPower; + heroesCeSum += getTowerHeroCe(warId, heroes, towerRec.heroes); + newWarStar.push({ id: warId, warType: dicWar.warType, star: 0, stars: [] }) } - newWarStar.push({ id: warId, warType: dicWar.warType, star: 0, stars: [] }) } - } - if(!vipCanSkipTower(recommendCeSum, heroesCeSum, role.vipStartTime)) { - return resResult(STATUS.TOWER_SKIP_POWER_NOT_ENOUGH) + if(!vipCanSkipTower(recommendCeSum, heroesCeSum, role.vipStartTime)) { + return resResult(STATUS.TOWER_SKIP_POWER_NOT_ENOUGH) + } + resultGoods.push({ towerLv: lv, goods: dicTower.reward }); + rewards.push(...dicTower.reward); } - // 更新玩家表 - role = await RoleModel.towerLvUp(roleId, newWarStar); // 更新towerRecord - await TowerRecordModel.skipTower(roleId, role.towerLv - 1, recHeroes); - await createNewTowerRecord(roleId, role.towerLv); + let warStatus: WarStatus[] = getWarStatusByLv(toLv); + await TowerRecordModel.skipTower(roleId, role.towerLv, toLv, warStatus); await checkAndStartHungUp(roleId, roleName, role.towerLv); + // 更新玩家表 + role = await RoleModel.setTowerLv(roleId, toLv, newWarStar); - let goods = await addItems(roleId, roleName, sid, dicTower.reward, ITEM_CHANGE_REASON.TOWER_BATTLE_END); + await addItems(roleId, roleName, sid, dicTower.reward, ITEM_CHANGE_REASON.TOWER_BATTLE_END); pushTowerMsg(roleId, roleName, serverId, MSG_SOURCE.TOWER_SUC, role.towerLv - 1); let data = await getTowerStatus(role); @@ -348,7 +349,7 @@ export class TowerBattleHandler { await checkTaskInSkipTower(serverId, roleId, sid, role.towerLv); await checkPopUpCondition(serverId, roleId, POP_UP_SHOP_CONDITION_TYPE.TOWER, { oldLv: oldTowerLv - 1, newLv: role.towerLv - 1 }) - return resResult(STATUS.SUCCESS, { ...data, battleGoods: goods }); + return resResult(STATUS.SUCCESS, { ...data, resultGoods }); } /** diff --git a/game-server/app/services/battleService.ts b/game-server/app/services/battleService.ts index 43f1b0732..ae2e7f0e1 100644 --- a/game-server/app/services/battleService.ts +++ b/game-server/app/services/battleService.ts @@ -2,7 +2,7 @@ import { HeroModel, HeroType } from './../db/Hero'; import { HangUpRecordModel } from './../db/HangUpRecord'; import { HANG_UP_CONSTS, REDIS_KEY, TASK_TYPE, TOWER_FORBIDDEN_CHARA_TYPE, TOWER_TASK_STATUS, MAIL_TYPE, MSG_SOURCE, POP_UP_SHOP_CONDITION_TYPE } from './../consts'; import { BattleRecordModel } from './../db/BattleRecord'; -import { TowerRecordModel } from './../db/TowerRecord'; +import { TowerRecordModel, WarStatus } from './../db/TowerRecord'; import { RoleModel, RoleType } from './../db/Role'; import { shouldRefresh, resResult, cal, getRandEelmWithWeight, genCode, } from '../pubUtils/util'; import { STATUS } from '../consts/statusCode'; @@ -48,17 +48,41 @@ export async function getTowerRecByLv(roleId: string, towerLv: number) { let towerRec = await TowerRecordModel.getRecordByLv(roleId, towerLv); if (!towerRec) { - const towerInfo = gameData.tower.get(towerLv); - const { warArray } = towerInfo; - const sts = warArray.map(id => { - return {warId: id, status: false}; - }); + const sts = getWarStatusByLv(towerLv); towerRec = await TowerRecordModel.createRecord({roleId, lv: towerLv, warStatus: sts}); // return { code: 201, data: '天梯记录异常' }; } return towerRec; } +export function getTowerStatusByWarId(warId: number, warStatus: WarStatus[] = []) { + let curWarStatus = warStatus.find(cur => cur.warId == warId); + return curWarStatus? curWarStatus.status: false; +} + +export function getWarStatusByLv(towerLv: number) { + let dicWar = gameData.tower.get(towerLv); + if(!dicWar) return []; + + const { warArray } = dicWar; + return warArray.map(id => { + return {warId: id, status: false}; + }); +} + +export function getTowerHeroCe(warId: number, heroes: HeroType[], recHeroes: number[] = []) { + let dicWar = gameData.war.get(warId); + let heroNum = 0, heroesCeSum = 0; + for(let hero of heroes) { + if(recHeroes.indexOf(hero.hid) == -1 && !checkForbiddenChar(hero.hid, hero.job, dicWar.fobiddenCharactor)) { + heroNum++; + heroesCeSum += hero.ce; + } + if(heroNum >= dicWar.minHeroNum) break; + } + return heroesCeSum; +} + /** * 获取镇念塔挂机收益 * @param roleId diff --git a/game-server/app/services/checkParam.ts b/game-server/app/services/checkParam.ts index 3ffc1f2cd..1c2c28507 100644 --- a/game-server/app/services/checkParam.ts +++ b/game-server/app/services/checkParam.ts @@ -35,7 +35,6 @@ export function checkRouteParam(route: string, msg: any) { case "battle.towerBattleHandler.recHangUpRewards": case "battle.towerBattleHandler.getTasks": case "battle.towerBattleHandler.refreshTasks": - case "battle.towerBattleHandler.skipTower": case "chat.chatHandler.getRecentPrivateChats": case "chat.chatHandler.getGroupMessages": case "connector.entryHandler.getData": @@ -736,6 +735,11 @@ export function checkRouteParam(route: string, msg: any) { if(!checkNaturalNumbers(msg.towerLv)) return false; break; } + case "battle.towerBattleHandler.skipTower": + { + if(!checkNaturalNumbers(msg.toLv)) return false; + break; + } case "battle.towerBattleHandler.hangUpSpeedUp": { if(!checkNaturalNumbers(msg.speedUpCnt)) return false; diff --git a/shared/db/Role.ts b/shared/db/Role.ts index 54d8417de..92eae1151 100644 --- a/shared/db/Role.ts +++ b/shared/db/Role.ts @@ -404,6 +404,11 @@ export default class Role extends BaseModel { return role; } + public static async setTowerLv(roleId: string, towerLv: number, newWarStar: WarStar[] = []) { + let role: RoleType = await RoleModel.findOneAndUpdate({ roleId }, { $set: { towerLv }, $push: { warStar: { $each: newWarStar }}, towerUpTime: new Date() }, { new: true }).lean({ getters: true, virtuals: true }); + return role; + } + public static async receiveTowerBox(roleId: string, ids: number[] = []) { let role: RoleType = await RoleModel.findOneAndUpdate({ roleId }, { $push: { towerReceived: { $each: ids }} }, { new: true }).lean(); return role; diff --git a/shared/db/TowerRecord.ts b/shared/db/TowerRecord.ts index ff6484580..1cbac83cc 100644 --- a/shared/db/TowerRecord.ts +++ b/shared/db/TowerRecord.ts @@ -2,7 +2,7 @@ import BaseModel from './BaseModel'; import { index, getModelForClass, prop, DocumentType } from '@typegoose/typegoose'; import { gameData } from '../pubUtils/data'; -class WarStatus { +export class WarStatus { @prop({ required: true }) warId: number; // 策划表中战斗编号 @prop({ required: false }) @@ -21,6 +21,8 @@ export default class TowerRecord extends BaseModel { roleId: string; // 角色 id @prop({ required: true, default: 1 }) lv: number; // 天梯层数 + @prop({ required: true, default: 0 }) + skipFrom: number; // 从哪层跳过来的天梯层数 @prop({ required: true, default: [], type: Number }) heroes: Array; // 本层已使用武将 @prop({ required: true, type: WarStatus, default: [], _id: false }) @@ -34,13 +36,13 @@ export default class TowerRecord extends BaseModel { @prop({ required: true, default: false }) passed: boolean; // 此层是否通过,true-通过,false-未通过 - public static async createRecord(towerInfo: {roleId: string, lv: number, warStatus: Array}, lean = true) { + public static async createRecord(towerInfo: {roleId: string, lv: number, warStatus: Array}) { const recDoc = new TowerRecordModel(); const update = Object.assign(recDoc.toJSON(), towerInfo ); delete update._id; const { roleId, lv } = towerInfo; // console.log(JSON.stringify(towerInfo)) - let rec: TowerRecordType = await TowerRecordModel.findOneAndUpdate({roleId, lv}, {$set: update}, {upsert: true, new: true}).lean(lean); + let rec: TowerRecordType = await TowerRecordModel.findOneAndUpdate({roleId, lv}, {$set: update}, {upsert: true, new: true}).lean(); return rec; } @@ -74,10 +76,16 @@ export default class TowerRecord extends BaseModel { } // 跳过当前层 - public static async skipTower(roleId: string, curLv: number, heroes: number[]) { - let rec: TowerRecordType = await TowerRecordModel.findOneAndUpdate({ roleId, lv: curLv, 'warStatus.status': false }, { - $set: { 'warStatus.$.status': true, heroes, passed: true }, - }, { new: true }).lean() + public static async skipTower(roleId: string, fromLv: number, curLv: number, warStatus: WarStatus[]) { + console.log('######## skipTower', roleId, fromLv, curLv) + + await TowerRecordModel.findOneAndUpdate({ roleId, lv: fromLv }, { $set: { passed: true } }, { new: true }); + + const recDoc = new TowerRecordModel(); + const update = Object.assign(recDoc.toJSON(), { roleId, lv: curLv, skipFrom: fromLv, passed: true, warStatus } ); + delete update._id; + + let rec: TowerRecordType = await TowerRecordModel.findOneAndUpdate({ roleId, lv: curLv }, { $setOnInsert: update }, { new: true, upsert: true }).lean(); return rec; }