diff --git a/game-server/app/servers/battle/handler/towerBattleHandler.ts b/game-server/app/servers/battle/handler/towerBattleHandler.ts index 4461c7bc8..fb79dc1ae 100644 --- a/game-server/app/servers/battle/handler/towerBattleHandler.ts +++ b/game-server/app/servers/battle/handler/towerBattleHandler.ts @@ -5,9 +5,9 @@ import { HangUpRecordModel } from './../../../db/HangUpRecord'; import { RoleModel } from './../../../db/Role'; import { TowerRecordModel } from './../../../db/TowerRecord'; import { Application, BackendSession } from 'pinus'; -import { getTaskIdByQuality, getTowerDataByLv } from '../../../util/gamedata'; +import { getTaskById, getTaskIdByQuality, getTowerDataByLv } from '../../../util/gamedata'; import { decodeArrayStr, decodeIdCntArrayStr, getRandEelm } from '../../../util/util'; -import { calcuHangUpReward } from '../../../services/battleService'; +import { calcuHangUpReward, checkTaskConditions } from '../../../services/battleService'; import { handleFixedReward } from '../../../services/rewardService'; export default function(app: Application) { @@ -154,23 +154,110 @@ export class TowerBattleHandler { }; } - async getTask(msg: {}, session: BackendSession) { + async getTasks(msg: {}, session: BackendSession) { let roleId = session.get('roleId'); let roleName = session.get('roleName'); - let curTask = await TowerTaskRecModel.getCurTask(roleId); - if (!curTask) { + let curTasks = await TowerTaskRecModel.getCurTasks(roleId); + if (!curTasks || curTasks.length == 0) { let taskIds = []; - TOWER_TASK_CONST.RAND_CNT.forEach(qualityId => { - const ids = getTaskIdByQuality(qualityId); - taskIds.concat(getRandEelm(ids, 1)); + TOWER_TASK_CONST.RAND_CNT.forEach((cnt, idx) => { + const ids = getTaskIdByQuality(idx + 1); + const tmp = getRandEelm(ids, cnt); + taskIds = taskIds.concat(getRandEelm(ids, cnt)); }) - curTask = await TowerTaskRecModel.createTask(roleId, roleName, taskIds); + curTasks = await TowerTaskRecModel.createTasks(roleId, roleName, taskIds); } return { code: 200, data: { msg: '成功', - curTask + curTasks + } + } + } + + async sendTaskHero(msg: {batchCode: string, tasks: Array<{taskCode: string, heroes: Array}>}, session: BackendSession) { + let roleId = session.get('roleId'); + const curTasks = await TowerTaskRecModel.getCurTasks(roleId); + if (!curTasks || curTasks.length == 0) { + return { code: 201, data: {msg: '没有可用派遣任务'}}; + } + let usedHeroes = []; + const tasksCode = []; + curTasks.forEach(task => { + usedHeroes = usedHeroes.concat(task.heroes); + tasksCode.push(task.taskCode); + }); + for (let task of msg.tasks) { + if (task.heroes.length > TOWER_TASK_CONST.MAX_HEROES_NUM) { + return { code: 201, data: {msg: '一个任务最多派遣三个武将'}}; + } + if (usedHeroes.length > 0) { + let used = false; + task.heroes.forEach(hid => { + if (usedHeroes.indexOf(hid) !== -1) { + used = true; + } + }) + if (used) { + return { code: 201, data: {msg: '武将已经派遣到其他任务'}}; + } + } + if (tasksCode.indexOf(task.taskCode) === -1) { + return { code: 201, data: {msg: '未找到此任务编号'}}; + } + } + const curTime = new Date(); + const recs = await TowerTaskRecModel.sendHeroes(roleId, msg.batchCode, msg.tasks, curTime); + if (!recs || recs.length === 0) { + return { code: 201, data: {msg: '任务更新失败,请检查任务编号'}}; + } + return { + code: 200, + data: { + msg: '派遣成功', + tasks: recs + } + } + } + + async settleTask(msg: {batchCode: string, taskCode: string}, session: BackendSession) { + let roleId = session.get('roleId'); + let roleName = session.get('roleName'); + + let allFlag = !msg.taskCode; + + const curTime = new Date(); + const curTasks = await TowerTaskRecModel.getCurTasks(roleId); + if (!curTasks || curTasks.length == 0) { + return { code: 201, data: {msg: '没有可用派遣任务'}}; + } + const compTasks = []; + let goods = []; + for (let task of curTasks) { + if (task.batchCode !== msg.batchCode) { + return { code: 201, data: {msg: '派遣编码错误'}}; + } + if ((allFlag || task.taskCode === msg.taskCode) && task.status === 1) { + let {completeTime, reward, bonusCondition, bonus} = getTaskById(task.taskId); + if (task.sendTime && task.sendTime.getTime() + completeTime * 1000 < curTime.getTime()) { + compTasks.push(task.taskCode); + const rewardGoods = await handleFixedReward(roleId, roleName, reward, 1); + goods = goods.concat(rewardGoods); + if(bonusCondition) { + const res = checkTaskConditions(roleId, task.heroes, bonusCondition); + const bonusGoods = await handleFixedReward(roleId, roleName, bonus, 1); + goods = goods.concat(bonusGoods); + } + } + } + } + await TowerTaskRecModel.finishTask(msg.batchCode, compTasks); + return { + code: 200, + data: { + msg: '成功', + compTasks, goods } } } diff --git a/game-server/app/services/battleService.ts b/game-server/app/services/battleService.ts index c60553550..13e4bd255 100644 --- a/game-server/app/services/battleService.ts +++ b/game-server/app/services/battleService.ts @@ -1,10 +1,11 @@ +import { HeroModel } from './../db/Hero'; import { HangUpRecordModel } from './../db/HangUpRecord'; import { ChannelService } from 'pinus'; import { HANG_UP_CONSTS } from './../consts/consts'; import { BattleRecordModel } from './../db/BattleRecord'; import { TowerRecordModel } from './../db/TowerRecord'; import { RoleModel } from './../db/Role'; -import { getTowerDataByLv } from "../util/gamedata" +import { getHeroInfoById, getJobInfoById, getTowerDataByLv } from "../util/gamedata" import { decodeArrayStr, shouldRefresh } from '../util/util'; import { handleFixedReward } from './rewardService'; @@ -119,4 +120,59 @@ export async function calcuHangUpReward(roleId: string, speedUp = false, speedUp timeReward: towerInfo.timeReward, multi }; +} + +async function checkCond(roleId: string, heroes, type: number, parm: number, cnt: number) { + let heroCnt = 0; + + switch (type) { + case 1: + for(let hid of heroes) { + const rec = await HeroModel.findByHidAndRole(hid, roleId); + if (rec.star >= parm) { + heroCnt++; + } + } + break; + case 2: + for(let hid of heroes) { + const hInfo = getHeroInfoById(hid); + if (hInfo.camp === parm) { + heroCnt++; + } + } + break; + case 3: + for(let hid of heroes) { + const hInfo = getHeroInfoById(hid); + if (getJobInfoById(hInfo.jobid) === parm) { + heroCnt++; + } + } + break; + default: + break; + } + if (heroCnt >= cnt) { + return true; + } + return false; +} + +export async function checkTaskConditions(roleId: string, heroes: Array, conditionsStr: string) { + const condArr = conditionsStr.split('|'); + if (condArr.length < 1) return false; + + let res = true; + for (let cond of condArr) { + const condDetail = cond.split('&'); + if (condDetail && condDetail.length === 3) { + const checkRes = await checkCond(roleId, heroes, parseInt(condDetail[0]), parseInt(condDetail[1]), parseInt(condDetail[2])) + if (!checkRes) { + res = false; + break; + } + } + } + return res; } \ No newline at end of file diff --git a/game-server/app/util/gamedata.ts b/game-server/app/util/gamedata.ts index f9c728496..db431af4d 100644 --- a/game-server/app/util/gamedata.ts +++ b/game-server/app/util/gamedata.ts @@ -7,6 +7,8 @@ const allWarInfos = new Map(); const towerInfos = new Map(); const towerTaskInfos = new Map(); const towerTasksByQuality = new Map>(); +const heroInfos = new Map(); +const jobInfos = new Map(); function parseWarData() { let result = null; @@ -44,6 +46,26 @@ function parseTowerTaskData() { }); } +function parseHeroData() { + const heroFile = 'dic_zyz_hero'; + const heroesData = gamedata['jsons'][heroFile] || []; + heroesData.forEach(elem => { + if (elem && elem.heroId) { + heroInfos.set(elem.heroId, elem); + } + }); +} + +function parseJobData() { + const jobFile = 'dic_zyz_job'; + const jobsData = gamedata['jsons'][jobFile] || []; + jobsData.forEach(elem => { + if (elem && elem.jobid) { + heroInfos.set(elem.jobid, elem); + } + }); +} + function initData (folder) { if(!gamedata.hasOwnProperty(folder)) { gamedata[folder] = {}; @@ -71,6 +93,8 @@ function parseData() { parseWarData(); parseTowerData(); parseTowerTaskData(); + parseHeroData(); + parseJobData(); } initData('jsons'); // 加载一般json @@ -116,4 +140,14 @@ export function getTaskById(tid: number) { export function getTaskIdByQuality(quality: number) { const taskIds = towerTasksByQuality.get(quality); return taskIds; +} + +export function getHeroInfoById(hid: number) { + const heroInfo = heroInfos.get(hid); + return heroInfo; +} + +export function getJobInfoById(jid: number) { + const jobInfo = jobInfos.get(jid); + return jobInfo; } \ No newline at end of file diff --git a/game-server/app/util/util.ts b/game-server/app/util/util.ts index 3a4f8eebb..38a3296ff 100644 --- a/game-server/app/util/util.ts +++ b/game-server/app/util/util.ts @@ -174,7 +174,7 @@ export function getRandEelm(source: Array = [], cnt = 1): Array { if (cnt > source.length) return null; if (cnt === source.length) return source; let idxs = new Set(); - for (let i = 1; i < cnt; ++i) { + for (let i = 0; i < cnt; ++i) { let rand = Math.floor(Math.random() * source.length); idxs.add(rand); if (idxs.size == cnt) { diff --git a/shared/consts/consts.ts b/shared/consts/consts.ts index 72c974730..7aeef4d85 100644 --- a/shared/consts/consts.ts +++ b/shared/consts/consts.ts @@ -78,6 +78,7 @@ export const HANG_UP_CONSTS = { export const TOWER_TASK_CONST = { REFRESH_TIME: 5, RAND_CNT: [1, 1, 1, 1, 1], + MAX_HEROES_NUM: 3 } export const WAR_JSON_ATTRIBUTE_TYPE = { diff --git a/shared/db/TowerTaskRec.ts b/shared/db/TowerTaskRec.ts index 00b798c07..910e694bb 100644 --- a/shared/db/TowerTaskRec.ts +++ b/shared/db/TowerTaskRec.ts @@ -22,6 +22,14 @@ function genCodeTmp(len) { return code; } +function getRefTime(curTime = new Date()) { + if (curTime.getHours() < 5) { + curTime.setDate(curTime.getDate() - 1); + } + curTime.setHours(5, 0, 0, 0); + return curTime; +} + /** * 天梯派遣记录表 */ @@ -29,59 +37,73 @@ function genCodeTmp(len) { @index({ batchCode: 1 }) export default class TowerTaskRec extends BaseModel { @prop({ required: true }) - roleId: string; // 角色 id + roleId: string; // 角色 id @prop({ required: true }) roleName: string; // 角色名 @prop({ required: true}) batchCode: string; // 本批派遣任务唯一标识 @prop({ required: true, default: 0}) - status: number; // 本批任务是否完成,0-未完成,1-已完成,2-已领取 - @prop({ required: true, type: TowerTask, default: [] }) - tasks: Array; // 本批次任务列表 + status: number; // 派遣任务当前状态,0-可派遣,1-已派遣,2-已完成,3-已领取 @prop({ required: true, type: Number, default: [] }) heroes: Array; // 此批派遣使用的全部武将 - public static async getCurTask(roleId: string, lean = true) { - const curTime = new Date(); - curTime.setHours(5, 0, 0, 0); - const rec = await TowerTaskRecModel.findOne({roleId, createdAt: {$gte: curTime}}).lean(lean); - return rec; + @prop({ required: true}) + taskId: number; // 任务唯一 Id,来自任务表 + @prop({ required: true }) + taskCode: string; // 服务器生成的任务唯一编号 + @prop({ required: false }) + sendTime: Date; // 派遣时间 + + public static async getCurTasks(roleId: string, lean = true) { + const refTime = getRefTime(); + const recs = await TowerTaskRecModel.find({roleId, createdAt: {$gte: refTime}}).lean(lean); + return recs; } - public static async createTask(roleId: string, roleName: string, taskIds: Array, lean = true) { + public static async createTasks(roleId: string, roleName: string, taskIds: Array, lean = true) { const batchCode = genCodeTmp(8); const tasksData = taskIds.map(id => { + const taskModel = new TowerTaskRecModel(); const taskCode = genCodeTmp(6); - const taskData = Object.assign(new TowerTask(), {id, taskCode}); + const taskData = Object.assign(taskModel.toJSON(), {batchCode, taskId: id, taskCode, roleId, roleName}); return taskData; }); - const recDoc = new TowerTaskRecModel(); - const update = Object.assign(recDoc.toJSON(), {tasks: tasksData, roleId, roleName}); - const rec = await TowerTaskRecModel.findOneAndUpdate({roleId, batchCode}, update, {upsert: true, new: true}).lean(lean); - return rec; + const recs = await TowerTaskRecModel.insertMany(tasksData, {ordered: false}); + return recs; } - public static async updateTask(roleId: string, batchCode: string, tasks: Array<{taskCode:string, heroes: Array}>, lean = true) { - let allHeroes = []; - tasks.forEach(task => { - allHeroes.concat(task.heroes); - }) - const curRec = await TowerTaskRecModel.findOne({batchCode, heroes: {$nin: allHeroes}}).lean(lean); - if (!curRec) return null; + public static async getTasksByCode(batchCode: string, lean = true) { + const recs = await TowerTaskRecModel.find({batchCode}).lean(lean); + return recs; + } - let {status, tasks: recTasks, heroes: recHeroes} = curRec; - if (status == 2 || status == 1) return curRec; + public static async sendHeroes(roleId: string, batchCode: string, tasks: Array<{taskCode:string, heroes: Array}>, sendTime: Date, lean = true) { + let recs = []; + const refTime = getRefTime(); for (let task of tasks) { - for (let recTask of recTasks) { - if (task.taskCode == recTask.taskCode) { - recTask.heroes = task.heroes; - recHeroes.concat(task.heroes); - } - } + const rec = await TowerTaskRecModel.findOneAndUpdate( + {batchCode, taskCode: task.taskCode, createdAt: {$gte: refTime}}, + {heroes: task.heroes, status: 1, sendTime}, + {new: true}).lean(lean); + + recs.push(rec); } - const newRec = await TowerTaskRecModel.findOneAndUpdate({batchCode}, {heroes: recHeroes, tasks: recTasks}, {new: true}).lean(lean); - return newRec; + return recs; + } + + public static async finishTask(batchCode: string, tasks: Array, lean = true) { + let recs = []; + const refTime = getRefTime(); + for (let task of tasks) { + const rec = await TowerTaskRecModel.findOneAndUpdate( + {batchCode, taskCode: task}, + {status: 3}, + {new: true}).lean(lean); + + recs.push(rec); + } + return recs; } } diff --git a/shared/resource/jsons/dic_zyz_tower_tasks.json b/shared/resource/jsons/dic_zyz_tower_tasks.json index 07cd7f845..13db3c28a 100644 --- a/shared/resource/jsons/dic_zyz_tower_tasks.json +++ b/shared/resource/jsons/dic_zyz_tower_tasks.json @@ -17,7 +17,7 @@ "bonus": "3&2|4&1", "bonusCondition": "1&5&2", "actorCnt": 2, - "completeTime": 40 + "completeTime": 120 }, { "taskId": 3,