diff --git a/game-server/app/servers/activity/handler/newHeroGKHandler.ts b/game-server/app/servers/activity/handler/newHeroGKHandler.ts new file mode 100644 index 000000000..b2df92af7 --- /dev/null +++ b/game-server/app/servers/activity/handler/newHeroGKHandler.ts @@ -0,0 +1,68 @@ +import { Application, BackendSession } from 'pinus'; +import { resResult } from '../../../pubUtils/util'; +import { STATUS } from '../../../consts'; +import { challengeNewHeroGK, getPlayerNewHeroGKData } from '../../../services/activity/newHeroGKService'; +import { NewHeroGKItem } from '../../../domain/activityField/newHeroGKField'; + + +export default function (app: Application) { + return new NewHeroGKHandler(app); +} + +export class NewHeroGKHandler { + constructor(private app: Application) { + } + + /************************新将演绎 (通用每日关卡,分页,自定义每个关卡开放的时间长短);(配置N个武将,每个武将有X个关卡;活动期间,*天(时间自定义)开启每个武将对应的一个关卡,只有第一次通关会获得奖励)****************************/ + + /** + * @description 获取关卡活动数据 + * @param {{ activityId: number}} msg + * @param {BackendSession} session + * @memberof NewHeroGKHandler + */ + async getNewHeroGKActivity(msg: { activityId: number }, session: BackendSession) { + const { activityId } = msg; + const roleId = session.get('roleId'); + const serverId = session.get('serverId'); + + let playerData = await getPlayerNewHeroGKData(activityId, serverId, roleId) + + if (!playerData) return resResult(STATUS.ACTIVITY_MISSING); + + return resResult(STATUS.SUCCESS, playerData); + } + + /** + * @description 获取今日挑战的单个奖励 + * @param {{ activityId: number, pageIndex: number, index:number}} msg + * @param {BackendSession} session + * @memberof NewHeroGKHandler + */ + async getGK(msg: { activityId: number, pageIndex: number, index: number }, session: BackendSession) { + const { activityId, pageIndex, index } = msg; + const roleId = session.get('roleId'); + const serverId = session.get('serverId'); + const sid = session.get('sid'); + const roleName = session.get('roleName'); + const funcs = session.get('funcs'); + + let playerData = await getPlayerNewHeroGKData(activityId, serverId, roleId) + if (!playerData) return resResult(STATUS.ACTIVITY_MISSING); + + let dailyItemData: NewHeroGKItem = playerData.findNewHeroGKItem(pageIndex, index); + if (!dailyItemData) { + return resResult(STATUS.ACTIVITY_DATA_ERROR); + } + + if (dailyItemData.begin > playerData.todayIndex || dailyItemData.end < playerData.todayIndex) { + return resResult(STATUS.ACTIVITY_DAY_INDEX_OVER); + } + await challengeNewHeroGK(serverId, roleId, activityId, pageIndex, dailyItemData.gk) + + return resResult(STATUS.SUCCESS, { + gkId: dailyItemData.gk + }); + } + +} diff --git a/game-server/app/servers/battle/handler/normalBattleHandler.ts b/game-server/app/servers/battle/handler/normalBattleHandler.ts index 4e437f381..60efdd9c1 100644 --- a/game-server/app/servers/battle/handler/normalBattleHandler.ts +++ b/game-server/app/servers/battle/handler/normalBattleHandler.ts @@ -23,6 +23,7 @@ import { checkTaskWithWar, checkTaskInBattleEnd, checkActivityTask } from '../.. import { ActivitySelfServiceModel } from '../../../db/ActivitySelfService'; import { getSelfServiceShopActivityData } from '../../../services/activity/selfServiceShopActivityService'; import { challengeDailyGK } from '../../../services/activity/dailyGKService'; +import { challengeNewHeroGK } from '../../../services/activity/newHeroGKService'; export default function (app: Application) { return new NormalBattleHandler(app); @@ -120,13 +121,15 @@ export class NormalBattleHandler { } // 关卡结算,记录使用的武将,获得奖励 - async battleEnd(msg: { battleCode: string, battleId: number, isSuccess: boolean, star: number, heroes: Array, activityId: number }, session: BackendSession) { - const { battleCode, battleId, isSuccess, heroes = [], star, activityId } = msg; + async battleEnd(msg: { battleCode: string, battleId: number, isSuccess: boolean, star: number, heroes: Array, activityId: number, pageIndex: number }, session: BackendSession) { + const { battleCode, battleId, isSuccess, heroes = [], star, activityId, pageIndex } = msg; let roleId = session.get('roleId'); let roleName = session.get('roleName'); let sid = session.get('sid'); const funcs: number[] = session.get('funcs'); let serverId = session.get('serverId'); + + let skipReward = false;//是否跳过奖励结算 let warInfo = gameData.war.get(battleId); if (!warInfo) { return resResult(STATUS.BATTLE_MISS_INFO); @@ -218,6 +221,11 @@ export class NormalBattleHandler { if (isSuccess) { await challengeDailyGK(serverId, roleId, activityId, battleId) } + } else if (warInfo.warType == WAR_TYPE.ACT_NEW_HERO_GK) { + if (isSuccess) { + let isFirst = await challengeNewHeroGK(serverId, roleId, activityId, pageIndex, battleId) + skipReward = !isFirst; + } } if (isSuccess) { // 挑战胜利 @@ -237,7 +245,10 @@ export class NormalBattleHandler { await updateWarStar(roleId, battleId, warInfo.warType, star); } - let reward = await warReward.saveReward(1); + let reward = null; + if (!skipReward) { + reward = await warReward.saveReward(1); + } const updateResult = await BattleRecordModel.updateBattleRecordByCode(battleCode, { $set: { status: isSuccess ? 1 : 2, star, record: { heroes } } diff --git a/game-server/app/services/activity/newHeroGKService.ts b/game-server/app/services/activity/newHeroGKService.ts new file mode 100644 index 000000000..f00a2b7e7 --- /dev/null +++ b/game-server/app/services/activity/newHeroGKService.ts @@ -0,0 +1,77 @@ +import { ACTIVITY_TYPE } from '../../consts'; +import { ActivityModel, ActivityModelType } from '../../db/Activity'; +import { ActivityNewHeroGKModel, ActivityNewHeroGKModelType } from '../../db/ActivityNewHeroGK'; +import { ServerlistModel } from '../../db/Serverlist'; +import { NewHeroGKData, NewHeroGKItem } from '../../domain/activityField/newHeroGKField'; + + +/** + * 获取活动数据 + * + * @param {number} serverId 区Id + * @param {number} activityId 活动Id + * @param {string} roleId 角色Id + * + */ +export async function newHeroGKActivity(serverId: number, roleId: string) { + let { activityGroupId } = await ServerlistModel.findByServerId(serverId); + let activityDataArray: ActivityModelType[] = await ActivityModel.findOpenActivityByType(activityGroupId, ACTIVITY_TYPE.DAILY_GK, new Date()); + if (activityDataArray.length === 0) { + return null; + } + let activityData: ActivityModelType = activityDataArray[0]; + let playerRecord: ActivityNewHeroGKModelType = await ActivityNewHeroGKModel.findData(serverId, activityData.activityId, roleId); + let playerData = new NewHeroGKData(activityData); + playerData.setPlayerRecords(playerRecord); + return playerData; +} + + +/** + * 玩家玩家活动数据 + * + * @param {number} serverId 区Id + * @param {number} activityId 活动Id + * @param {string} roleId 角色Id + * + */ +export async function getPlayerNewHeroGKData(activityId: number, serverId: number, roleId: string) { + let activityData: ActivityModelType = await ActivityModel.findActivity(activityId); + let playerRecord: ActivityNewHeroGKModelType = await ActivityNewHeroGKModel.findData(serverId, activityId, roleId); + + let playerData = new NewHeroGKData(activityData); + playerData.setPlayerRecords(playerRecord); + + return playerData; +} + +/** + * 挑战每日关卡成功 + * + * @param {number} activityId 活动id + * @param {number} gk 关卡id + * + */ +export async function challengeNewHeroGK(serverId: number, roleId: string, activityId: number, pageIndex: number, gk: number) { + let isFirst = false; + let activityData: ActivityModelType = await ActivityModel.findActivity(activityId); + let playerRecords = await ActivityNewHeroGKModel.findData(serverId, activityId, roleId); + let records = playerRecords && playerRecords.records ? playerRecords.records : []; + let playerData = new NewHeroGKData(activityData); + let item = playerData.findItemByGK(pageIndex, gk); + if (item) { + let index = item.index; + let recordIndex = records.findIndex(obj => { return obj.pageIndex == pageIndex && obj.index == index }); + if (recordIndex == -1) { + isFirst = true; + await ActivityNewHeroGKModel.addRecord(serverId, activityId, roleId, pageIndex, index); + } + } else { + console.log('challengeNewHeroGK没有找到对应关卡活动数据', activityId, gk) + } + return isFirst; +} + + + + diff --git a/shared/consts/constModules/activityConst.ts b/shared/consts/constModules/activityConst.ts index 5acb5d620..7a63e61db 100644 --- a/shared/consts/constModules/activityConst.ts +++ b/shared/consts/constModules/activityConst.ts @@ -50,6 +50,7 @@ export enum ACTIVITY_TYPE { MONOPOLY = 35, //大富翁游戏 COMMON_SIGN_IN = 36, //通用签到 NEW_HERO_GIFTS = 37, //新将好礼(很多红包,用积分兑换一遍结束) + NEW_HERO_GK = 38, //新将演绎 (配置N个武将,每个武将有X个关卡;活动期间,*天(时间自定义)开启每个武将对应的一个关卡,只有第一次通关会获得奖励) } /** diff --git a/shared/consts/constModules/battleConst.ts b/shared/consts/constModules/battleConst.ts index 0288a906b..0a6d4c290 100644 --- a/shared/consts/constModules/battleConst.ts +++ b/shared/consts/constModules/battleConst.ts @@ -27,6 +27,7 @@ export const WAR_TYPE = { ACT_TREASURE_HUNT: 15, // 神州探秘 ACT_SELF_SHOP: 16, // 糜家商队 ACT_DAILY_GK: 17, // 每日关卡活动 + ACT_NEW_HERO_GK: 18, // 新将演绎活动 }; // 藏宝图掉落参数 diff --git a/shared/db/ActivityNewHeroGK.ts b/shared/db/ActivityNewHeroGK.ts new file mode 100644 index 000000000..1ce3d93bc --- /dev/null +++ b/shared/db/ActivityNewHeroGK.ts @@ -0,0 +1,51 @@ +import BaseModel from './BaseModel'; +import { index, getModelForClass, prop, DocumentType } from '@typegoose/typegoose'; + + +export class Record { + @prop({ required: true }) + pageIndex: number; //第几页 + @prop({ required: true }) + index: number; //下标记录 + @prop({ required: true }) + time: Date; //兑换时间 +} + +/** + * 活动系统 - 新将演绎活动 +*/ +@index({ roleId: 1 }) + +export default class Activity_New_Hero_GK extends BaseModel { + @prop({ required: true }) + serverId: number; // 服id + @prop({ required: true }) + activityId: number; // 活动Id + @prop({ required: true }) + roleId: string; // 用户Id + @prop({ required: true }) + records: Record[]; // 通关记录 + + //通关记录 + public static async addRecord(serverId: number, activityId: number, roleId: string, pageIndex: number, index: number) { + let result: ActivityNewHeroGKModelType = await ActivityNewHeroGKModel.findOneAndUpdate({ serverId, roleId, activityId }, + { $push: { records: { pageIndex, index, time: new Date() } } }, { upsert: true, new: true }).lean(true); + return result; + } + + //根据活动id查询活动数据 + public static async findData(serverId: number, activityId: number, roleId: string) { + let result: ActivityNewHeroGKModelType = await ActivityNewHeroGKModel.findOne({ serverId, roleId, activityId }).lean(true); + return result; + } + + //删除活动领取记录 + public static async deleteActivity(serverId: number, activityId: number, roleId: string) { + await ActivityNewHeroGKModel.deleteMany({ serverId, roleId, activityId }); + } +} + +export const ActivityNewHeroGKModel = getModelForClass(Activity_New_Hero_GK); + +export interface ActivityNewHeroGKModelType extends Pick, keyof Activity_New_Hero_GK> { } +export type ActivityNewHeroGKModelTypeParam = Partial; // 将所有字段变成可选项 \ No newline at end of file diff --git a/shared/domain/activityField/newHeroGKField.ts b/shared/domain/activityField/newHeroGKField.ts new file mode 100644 index 000000000..22fe436cc --- /dev/null +++ b/shared/domain/activityField/newHeroGKField.ts @@ -0,0 +1,102 @@ +import { ActivityModelType } from '../../db/Activity'; +import { ActivityNewHeroGKModelType } from '../../db/ActivityNewHeroGK'; +import { ActivityBase } from './activityField'; + + +// 每日配置数据 +export class NewHeroGKItem { + pageIndex: number; + begin: number; // 第几天开始,从1开始,1表示第一天0点开始 + end: number; // 第几天结束,2表示第二天24点结束 + index: number; // 下标 + gk: number; // 关卡 + name: string; // 名称 + reward: string; // 奖励,格式:1&3&1(类型&id&数量) 类型定义:1.英雄,2.物品 + + isSuccess: boolean; //是否成功 + + constructor(data: any, pageIndex: number) { + this.pageIndex = pageIndex; + this.begin = data.begin; + this.end = data.end; + this.index = data.index; + this.gk = data.gk; + this.name = data.name; + this.reward = data.reward; + this.isSuccess = false; + } +} + + +// 每日配置数据 +export class NewHeroGKPage { + items: Array = []; + pageIndex: number; // 页码 + name: string; // 名称 + hid: number; //武将id + + constructor(data: any) { + this.pageIndex = data.pageIndex; + this.name = data.name; + this.hid = data.hid; + this.items = []; + for (let obj of data.items) { + this.items.push(new NewHeroGKItem(obj, this.pageIndex)) + } + } +} + +// 每日关卡活动数据 +export class NewHeroGKData extends ActivityBase { + list: Array = []; + name: string; // 名称 + + public findItemByGK(pageIndex: number, gk: number) { + for (let pageData of this.list) { + if (pageData.pageIndex == pageIndex) { + let index = pageData.items.findIndex(obj => { return obj.gk == gk }) + return (index != -1) ? pageData.items[index] : null; + } + } + return null; + } + + public findNewHeroGKItem(pageIndex: number, dayIndex: number) { + for (let pageData of this.list) { + if (pageData.pageIndex == pageIndex) { + let index = pageData.items.findIndex(obj => { return obj.begin <= dayIndex && obj.end >= dayIndex }) + return (index != -1) ? pageData.items[index] : null; + } + } + return null; + } + + //解析玩家记录 + public setPlayerRecords(data: ActivityNewHeroGKModelType) { + if (!data) + return; + let records = data.records ? data.records : []; + for (let pageData of this.list) { + for (let item of pageData.items) { + let index = records.findIndex(obj => { return pageData.pageIndex == obj.pageIndex && item.index == obj.index }) + if (index != -1) { + item.isSuccess = true + } + } + } + } + + public initData(data: string) { + let dataObj = JSON.parse(data); + this.name = dataObj.name; + let arr = dataObj.data; + for (let obj of arr) { + this.list.push(new NewHeroGKPage(obj)) + } + } + + constructor(activityData: ActivityModelType) { + super(activityData) + this.initData(activityData.data) + } +} \ No newline at end of file