diff --git a/game-server/app/servers/battle/filter/checkEventFilter.ts b/game-server/app/servers/battle/filter/checkEventFilter.ts index f10378054..465093d7f 100644 --- a/game-server/app/servers/battle/filter/checkEventFilter.ts +++ b/game-server/app/servers/battle/filter/checkEventFilter.ts @@ -1,5 +1,5 @@ import {Application, RouteRecord, FrontendOrBackendSession, HandlerCallback} from "pinus"; -import {checkEvent} from '../handler/eventBattleHandler'; +import {checkEvent} from '../../../services/eventSercive'; module.exports = function(app: Application) { return new Filter(app); diff --git a/game-server/app/servers/battle/handler/battleUtils.ts b/game-server/app/servers/battle/handler/battleUtils.ts deleted file mode 100644 index a530da1de..000000000 --- a/game-server/app/servers/battle/handler/battleUtils.ts +++ /dev/null @@ -1,213 +0,0 @@ - -import { ActionPointModel } from '../../../db/ActionPoint'; -import { BattleDropModel } from '../../../db/BattleDrop'; -import { ExpeditionPointModel } from '../../../db/ExpeditionPoint'; -import { RoleModel } from '../../../db/Role'; - -import { getWarById, getWarJsons, getGamedata } from '../../../util/gamedata'; -import { decodeStr, Reward } from '../../../util/util'; -import { ACTION_POIN, BATTLE_REWARD_TYPE, WAR_JSON_ATTRIBUTE_TYPE } from '../../../consts/consts'; - -export async function getAp(now: number, roleId: string) { - let dataAp = await ActionPointModel.getAp(roleId); - const maxAp = ACTION_POIN.MAX; // 最大体力值 - const per = ACTION_POIN.PER; // 恢复时间(ms) - let {ap, refTime} = dataAp; - if(ap >= maxAp) { - // 体力溢出不需要做时间的处理 - return { ap, maxAp, refTime: now, apRemainTime:0, isOver: true } - } else { - if(refTime > now) refTime = now; // refTime:每次记录时候最近的一个整的时间点,绝对不会大于now - let n = Math.floor((now - refTime)/per); // 上次记录到现在可以增长多少体力 - ap += n; // 增加上 - if(ap >= maxAp) { // 加上后溢出了 - ap = maxAp; - return { ap, maxAp, refTime: now, apRemainTime:0, isOver: true } - } else { - refTime += n * per; // 更新refTime到离现在最近的一个整的时间点 - let apRemainTime = Math.floor((refTime + per - now)/1000); // 恢复下一点需要多少时间 - - return { ap, maxAp, refTime, apRemainTime, isOver: false } - } - } -} - -export async function setAp(now: number, roleId: string, changeAp: number) { - let ApResult = await getAp(now, roleId); - let { ap, maxAp, refTime, apRemainTime, isOver } = ApResult; // 更新ap - ap += changeAp; - if(ap >= maxAp) { // 溢出 - refTime = now; - apRemainTime = 0; - } - if(ap < 0) return null // 体力不足 - await ActionPointModel.saveAp(roleId, ap, refTime); - - if(isOver && ap < maxAp) apRemainTime = Math.floor(ACTION_POIN.PER / 1000); // 特殊处理 - return {ap, maxAp, refTime, apRemainTime} -} - -export class WarReward { - roleId: string; - roleName: string; - battleId: number; - condition: Map; - warInfo: any; - isSuccess: boolean; - rewards: Array<{type: number, gid: number, count: number}>; - - constructor(roleId: string, roleName: string, battleId: number, isSuccess: boolean) { - this.roleId = roleId; - this.roleName = roleName; - this.battleId = battleId; - this.condition = new Map(); - this.warInfo = getWarById(battleId); - this.isSuccess = isSuccess; - } - - public setCondition(id: number, isOk: boolean) { - this.condition.set(id, isOk); - } - - private handleFixReward(num: number) { - if(this.isSuccess) { // 成功了才给固定奖励 - let {fixReward = ''} = this.warInfo; - let reward = decodeStr('fixReward', fixReward); - for(let obj of reward) this.rewards.push({type: BATTLE_REWARD_TYPE.FIX_REWARD, ...obj, count: obj.count * num}); - } - } - private handleConditionReward(num: number) { - if(this.isSuccess) { - let {conditionReward = ''} = this.warInfo; - let reward = decodeStr('conditionReward', conditionReward); - for(let obj of reward) { - if(this.condition.get(obj.condition)) { - this.rewards.push({type: BATTLE_REWARD_TYPE.CONDITION_REWARD, ...obj, count: obj.count * num}); - } - } - } - } - - private async handleRandomReward(num: number) { - if(this.isSuccess) { - let {RandomReward:randomReward = ''} = this.warInfo; - - let reward = decodeStr('randomReward', randomReward); - for(let obj of reward) { - let { gid, frequency } = obj; - let dropHistory = await BattleDropModel.findByGid(this.roleId, this.battleId, gid); - let { getNum = 0, allNum = 0, getSum = 0, allSum = 0 } = dropHistory; - for(let i = 0; i < num; i ++) { - let flag = false; // 是否可以获得 - if(allNum + 1 > frequency) { - allNum = 0; getNum = 0; - } - allNum++; allSum++; - if(getNum == 0) { - let r = Math.random(); - if(r <= 1/frequency*allNum || (allNum >= frequency) ) { - flag = true; // 独立概率随机 - } - } - if(flag) { - getNum ++; getSum++; - this.rewards.push({type: BATTLE_REWARD_TYPE.RANDOM_REWARD, ...obj}); - } - } - await BattleDropModel.updateByGid(this.roleId, this.battleId, gid, { - getNum, allNum, getSum, allSum - }); - } - } - } - - public async saveReward(num: number) { - this.rewards = new Array(); - let warType = this.warInfo.warType; - - await this.handleFixReward(num); - await this.handleConditionReward(num); - await this.handleRandomReward(num); - - let rewardObject = new Reward(this.roleId, this.roleName, this.rewards); - let returnGoods = await rewardObject.saveReward(); - return returnGoods; - } - -} - -export async function matchPlayers(scale: number, range: number, myCe: number ,enemyObj: {enemyFrom: number, enemyId: string, enemies: Array }) { - - let min = myCe * scale * (1 - range/100); - let max = myCe * scale * (1 + range/100); - console.log(min, max, enemyObj); - - return false -} - -export async function matchRobots(scale: number, myCe: number, robotCe: number, warJsonIndex:any, lv: number, enemyObj: {enemyFrom: number, enemyId: string, enemies: Array }) { - let {json: dicWarJson, fileName } = getWarJsons(warJsonIndex); - if(dicWarJson) { - enemyObj.enemyFrom = 2; - enemyObj.enemyId = fileName; - - let ratio = myCe / robotCe * scale; // 玩家战力/机器人初始战力*系数 - for(let enemy of dicWarJson) { - let attribute = decodeWarJsonAttribute(enemy.attribute); // 格式:{'hp':1000, ...} - for(let value in attribute) { - attribute[value] *= ratio; - attribute[value] = Math.round(attribute[value]); - } - enemyObj.enemies.push({...enemy, attribute, lv}); - } - - return true - } else { - return false - } -} - -export function decodeWarJsonAttribute(attribute) { - let arr = decodeStr('attribute', attribute); - let obj = {}; - for(let {id, value} of arr) { - let field = WAR_JSON_ATTRIBUTE_TYPE[id]; - if(field) { - obj[field] = value; - } - } - return obj - } - - export async function getPointRewardStatus(roleId: string) { - - let role = await RoleModel.findByRoleId(roleId); - let {expeditionPoint = 0} = role; - let dicExpeditionPoint = getGamedata('dic_expedition_point'); - let pointRewards = { - expeditionPoint, - rewards: dicExpeditionPoint.map(cur => { - return { point: cur.point, received: false } - }) - }; - let pointStatusInDatabase = await ExpeditionPointModel.getExpeditionPoint(roleId); - if(pointStatusInDatabase) { - let { rewards = [] } = pointStatusInDatabase; - pointRewards.rewards.forEach(cur => { - let obj = rewards.find(ccur => ccur.point == cur.point); - if(obj) cur.received = obj.received; - }); - } - return pointRewards - } - - export async function getCEScaleAndRange(roleId: string, curDicExpedition: any) { - // 匹配,判断是不是新手期 - const role = await RoleModel.findByRoleId(roleId); - let now = new Date(); - let today = now.setHours(0,0,0,0); - let isNew = today - role.createdAt.getTime() <= 3*24*60*60*1000; - let scale = isNew?curDicExpedition.CEScaleNew:curDicExpedition.CEScale; - let range = isNew?curDicExpedition.CERangeNew:curDicExpedition.CERange; - return {scale, range, lv: role.lv} - } \ No newline at end of file diff --git a/game-server/app/servers/battle/handler/dailyBattleHandler.ts b/game-server/app/servers/battle/handler/dailyBattleHandler.ts index db35c94c8..68bcde0c9 100644 --- a/game-server/app/servers/battle/handler/dailyBattleHandler.ts +++ b/game-server/app/servers/battle/handler/dailyBattleHandler.ts @@ -60,48 +60,4 @@ export class DailyBattleHandler { return { code: 200, data: result } } - -} - -// 检查每日本次数checkBattle使用 -export async function checkDaily(roleId: string, battleId: number, inc: number) { - let dicDaily = getGamedata('dic_zyz_daily'); - let dicDailyWar = getGamedata('dic_zyz_gk_daily'); - let dailyWar = dicDailyWar.find(cur => cur.war_id == battleId); - if(!dailyWar) return { status: -1, msg: '未找到该关卡' }; - let type = dailyWar.dailyType; - - let curDaily = dicDaily.find(cur => cur.dailyType == type); - if(!curDaily) return { status: -1, msg: '未找到该类型' }; - let dailyRecord = await DailyRecordModel.refreshRecord(roleId, type); - let { count } = dailyRecord; - if(count + inc > curDaily.sum ) { - return { status: -1, msg: '次数不足' } - } - return {status: 1, type, count, sum: curDaily.sum}; -} - -// 检查每日本次数warEnd和warSweep使用 -export async function checkDailyAndIncrease(roleId: string, battleId: number, inc: number, isRef: boolean) { - let dicDaily = getGamedata('dic_zyz_daily'); - let dicDailyWar = getGamedata('dic_zyz_gk_daily'); - let dailyWar = dicDailyWar.find(cur => cur.war_id == battleId); - if(!dailyWar) return { status: -1, msg: '未找到该关卡' }; - let type = dailyWar.dailyType; - - let curDaily = dicDaily.find(cur => cur.dailyType == type); - if(!curDaily) return { status: -1, msg: '未找到该类型' }; - - let dailyRecord; - if(isRef) { - dailyRecord = await DailyRecordModel.refreshRecord(roleId, type); - } else { - dailyRecord = await DailyRecordModel.getDailyRecordById(roleId, type); - } - let { count } = dailyRecord; - if(count + inc > curDaily.sum ) { - return { status: -1, msg: '次数不足' } - } - let result = await DailyRecordModel.increseDailyCount(roleId, type, inc); - return {status: 1, type, count: result.count, sum: curDaily.sum}; } \ No newline at end of file diff --git a/game-server/app/servers/battle/handler/eventBattleHandler.ts b/game-server/app/servers/battle/handler/eventBattleHandler.ts index eaa854e81..5dd1ced0b 100644 --- a/game-server/app/servers/battle/handler/eventBattleHandler.ts +++ b/game-server/app/servers/battle/handler/eventBattleHandler.ts @@ -1,9 +1,10 @@ -import { Application, BackendSession, FrontendOrBackendSession } from 'pinus'; +import { Application, BackendSession } from 'pinus'; import { getGamedata } from '../../../util/gamedata'; import { EventRecordModel } from '../../../db/EventRecord'; import { RoleModel } from '../../../db/Role'; -import { genCode, decodeStr, decodeStrSingle, Reward } from '../../../util/util'; import { EVENT_STATUS, EVENT_RECORD_STATUS, EVENT_TYPE } from '../../../consts/consts'; +import { checkEvent } from '../../../services/eventSercive'; +import { handleFixedReward } from '../../../services/rewardService'; export default function(app: Application) { return new EventBattleHandler(app); @@ -53,9 +54,7 @@ export class EventBattleHandler { let result = await EventRecordModel.setStatusByCode(roleId, eventCode, isSuccess?EVENT_RECORD_STATUS.SUCCESS_RECEIVED:EVENT_RECORD_STATUS.FAIL_RECEIVED); // 保存奖励 let rewardStr = isSuccess?curEvent.winReward:curEvent.loseReward; - let rewards = decodeStr('fixReward', rewardStr); - let rewardObject = new Reward(roleId, roleName, rewards); - let goods = await rewardObject.saveReward(); + let goods = await handleFixedReward(roleId, roleName, rewardStr, 1); if(eventStatus == EVENT_STATUS.STARTING) { // 如果是第一次开启的挑战,保存成开启状态 await RoleModel.setEventStatus(roleId, EVENT_STATUS.OPEN); // 第一场时间挑战完,开始正常刷新事件,所以刷新时间也重置起来 @@ -74,151 +73,4 @@ export class EventBattleHandler { } } } -} - -export async function setBattleStatus(app: Application, session: FrontendOrBackendSession, roleId: string, battleId: number , isSuccess: boolean, battleCode: string) { - let now = new Date(); - let eventStatus = session.get('eventStatus'); - let refTime = eventStatus == EVENT_STATUS.OPEN? getEventTime(now): 0; - console.log('***setBattleStatus', eventStatus, refTime) - - - let { BATTLE_SUCCESS, BATTLE_FAIL } = EVENT_RECORD_STATUS; - let result = await EventRecordModel.setBattleStatus(roleId, battleId, refTime, isSuccess?BATTLE_SUCCESS:BATTLE_FAIL, battleCode); - await checkEvent(app, session, true); - return result; -} - -export function getEventTime(now: Date) { - let curTime = Number(now); - let todayA = now.setHours(12, 0, 0, 0); // 每天12点 - let todayB = now.setHours(18, 0, 0, 0); // 每天18点 - let yesterdayA = todayA - 86400000; // 前一天12点 - let t = 0; - if(curTime < todayA) { - t = yesterdayA; - } else if (curTime >= todayA && curTime < todayB) { - t = todayA; - } else if (curTime >= todayB) { - t = todayB; - } - return t -} - -export async function startEvent(app: Application, session: FrontendOrBackendSession) { - - // console.log('*******setEventStatus') - let roleId = session.get('roleId'); - let roleName = session.get('roleName'); - let channelName = roleId; - let event = await refreshEvent(1, roleId, roleName, 0); // 刷新初始的一件 - await RoleModel.setEventStatus(roleId, EVENT_STATUS.STARTING); - session.set('eventStatus', EVENT_STATUS.STARTING); - session.push('eventStatus', () => {}); - pushEventMsg(app, roleId, channelName, { event }); // 推送 - -} - -export async function checkEvent(app: Application, session: FrontendOrBackendSession, isForce:boolean = false) { - - try { - - let roleId = session.get('roleId'); - if(roleId) { - - let roleName = session.get('roleName'); - let channelName = roleId; - let eventStatus = session.get('eventStatus')||EVENT_STATUS.WAITING; - - let eventTime = session.get('getEventTime')||0; - let now = new Date(); - let t = getEventTime(now); - - - let channel = app.get('channelService').getChannel(channelName, false); - console.log('****channel', channelName, !!channel, eventTime, t, eventStatus) - - if(!!channel && (eventTime < t || isForce)) { // 第一次登陆后可以刷新了 - - if (eventStatus == EVENT_STATUS.STARTING) { - let event = await EventRecordModel.getEventRecordByTime(roleId, 0); - pushEventMsg(app, roleId, channelName, { event }); // 推送 - session.set('getEventTime', t); - session.push('getEventTime', () => {}); - } else if( eventStatus == EVENT_STATUS.OPEN ) { - - let event = await EventRecordModel.getEventRecordByTime(roleId, t); - if(event.length == 0) { // 刷新 - const num = 3; // 每次刷3个 - event = await refreshEvent(num, roleId, roleName, t); - } - - console.log(event) - // 推送 - pushEventMsg(app, roleId, channelName, { event }); - session.set('getEventTime', t); - session.push('getEventTime', () => {}); - } - } - } - return; - }catch(err) { - console.log(err.stack); - throw err - } -} - -async function refreshEvent(num: number, roleId: string, roleName: string, t) { - let event = new Array(); - let dicEvent = getGamedata('dic_zyz_event'); - let role = await RoleModel.findByRoleId(roleId); - dicEvent = dicEvent.filter(cur => { // 筛选适合等级 - let { suitLevel } = cur; - suitLevel = decodeStrSingle('eventSuitLevel', suitLevel); - return suitLevel.min <= role.lv && suitLevel.max >= role.lv - }); - let historyRecord = await EventRecordModel.getHostoryEventRecord(roleId); - let {history, turn} = historyRecord; - let randomList = dicEvent.filter(cur => { - return history.find(ccur => { - return ccur.eventId != cur.eventID; - }); - }); - console.log(JSON.stringify(randomList)); - - for(let i = 0; i < num; i++) { - if(randomList.length == 0) { // 一轮刷新过,开始新的一轮,保证所有事件都能刷新一遍 - turn ++; - randomList = [...dicEvent]; - } - if(randomList.length == 0) break; // 如果还是为0,pass - - let index = Math.floor(Math.random() * randomList.length); - let dic = randomList[index]; - let eventCode = genCode(8); - let data = await EventRecordModel.saveEventRecord(eventCode, { - roleId, refTime: t, eventId: dic.eventID, - roleName, turn, type: dic.eventType, battleId: dic.warId||0, quality: dic.quality, - status: EVENT_RECORD_STATUS.WAITING - }); - event.push(data) - randomList.splice(index, 1); - } - return event; -} - -function pushEventMsg(app, roleId, channelName, msg ) { - console.log('***pushEventMsg', channelName) - let channelService = app.get('channelService'); - - let param = { msg }; - let channel = channelService.getChannel(channelName, false); - if(!!channel) { - let tsid = channel.getMember(roleId)['sid']; - - channelService.pushMessageByUids('onSpecialEvent', param, [{ - uid: roleId, - sid: tsid - }]); - } } \ No newline at end of file diff --git a/game-server/app/servers/battle/handler/expeditionBattleHandler.ts b/game-server/app/servers/battle/handler/expeditionBattleHandler.ts index e822e7b03..4315981cd 100644 --- a/game-server/app/servers/battle/handler/expeditionBattleHandler.ts +++ b/game-server/app/servers/battle/handler/expeditionBattleHandler.ts @@ -5,9 +5,12 @@ import { ExpeditionRecordModel } from '../../../db/ExpeditionRecord'; import { ExpeditionWarRecordModel } from '../../../db/ExpeditionWarRecord'; import { ExpeditionPointModel } from '../../../db/ExpeditionPoint'; import { RoleModel } from '../../../db/Role'; -import { calculateSumCE, genCode, Reward, decodeStr } from '../../../util/util'; -import { matchPlayers, matchRobots, getAp, setAp, WarReward, getPointRewardStatus, getCEScaleAndRange } from './battleUtils'; +import { calculateSumCE, genCode } from '../../../util/util'; +import { matchPlayers, matchRobots, getPointRewardStatus, getCEScaleAndRange } from '../../../services/expeditionService'; import { EXPEDITION_INCREASE_POINT } from '../../../consts/consts'; +import { WarReward } from '../../../services/warRewardService'; +import { handleFixedReward } from '../../../services/rewardService'; +import { getAp, setAp } from '../../../services/actionPointService'; export default function(app: Application) { return new ExpeditionBattleHandler(app); @@ -275,9 +278,7 @@ export class ExpeditionBattleHandler { let result = await ExpeditionWarRecordModel.updateBoxStatus(expeditionCode, expeditionId, true, curDicExpedition.reward); let { battleId, battleCode, battleStatus, received } = result; // 获取东西 - let rewards = decodeStr('fixReward', curDicExpedition.reward); - let rewardObject = new Reward(roleId, roleName, rewards); - let goods = await rewardObject.saveReward(); + let goods = await handleFixedReward(roleId, roleName, curDicExpedition.reward, 1); return { code: 200, @@ -323,10 +324,7 @@ export class ExpeditionBattleHandler { // 标记状态 await ExpeditionPointModel.updatePointStatus(roleId, point, curDicExpeditionPoint.reward); let pointRewards = await getPointRewardStatus(roleId); - - let rewards = decodeStr('fixReward', curDicExpeditionPoint.reward); - let rewardObject = new Reward(roleId, roleName, rewards); - let goods = await rewardObject.saveReward(); + let goods = await handleFixedReward(roleId, roleName, curDicExpeditionPoint.reward, 1); return { code: 200, diff --git a/game-server/app/servers/battle/handler/normalBattleHandler.ts b/game-server/app/servers/battle/handler/normalBattleHandler.ts index aca341e81..d0a7ced77 100644 --- a/game-server/app/servers/battle/handler/normalBattleHandler.ts +++ b/game-server/app/servers/battle/handler/normalBattleHandler.ts @@ -3,11 +3,12 @@ import { BattleRecordModel } from '../../../db/BattleRecord'; import { BattleSweepRecordModel } from '../../../db/BattleSweepRecord'; import { getWarById, } from '../../../util/gamedata'; import { genCode } from '../../../util/util'; -import { getAp, setAp, WarReward } from './battleUtils'; import { WAR_TYPE, EVENT_START_BATTLE } from '../../../consts/consts'; -import { checkDaily, checkDailyAndIncrease } from './dailyBattleHandler'; -import { setBattleStatus, startEvent } from './eventBattleHandler'; +import { checkDaily, checkDailyAndIncrease } from '../../../services/dailyBattleService'; import { checkTowerWar, towerBattleEnd } from '../../../services/battleService'; +import { WarReward } from '../../../services/warRewardService'; +import { getAp, setAp } from '../../../services/actionPointService'; +import { setBattleStatus, startEvent } from '../../../services/eventSercive'; export default function(app: Application) { return new NormalBattleHandler(app); @@ -160,16 +161,8 @@ export class NormalBattleHandler { } let warReward = new WarReward(roleId, roleName, battleId, isSuccess); - let params = {}; - if(isSuccess) { // 挑战胜利 - params = { - $set: { - status: 1, - star, - record: { heroes } - } - } + if(isSuccess) { // 挑战胜利 // 是否首通 let condition1 = await BattleRecordModel.getBattleRecordByIdAndStatus(roleId, battleId, 1); if(!condition1) warReward.setCondition(0, true); @@ -178,19 +171,13 @@ export class NormalBattleHandler { let condition2 = await BattleRecordModel.getBattleRecordByIdAndStar(roleId, battleId, 3); if(!condition2) warReward.setCondition(1, true); } - - } else { // 挑战失败 - params = { - $set: { - status: 2, - record: { heroes } - } - } } let reward = await warReward.saveReward(1); - const updateResult = await BattleRecordModel.updateBattleRecordByCode(battleCode, params, true); + const updateResult = await BattleRecordModel.updateBattleRecordByCode(battleCode, { + $set: { status: isSuccess?1:2, star, record: { heroes } } + }, true); let { status } = updateResult; // 主线关卡某个关卡触发事件开启 diff --git a/game-server/app/services/actionPointService.ts b/game-server/app/services/actionPointService.ts new file mode 100644 index 000000000..885119051 --- /dev/null +++ b/game-server/app/services/actionPointService.ts @@ -0,0 +1,45 @@ +/** + * 体力系统 + */ + +import { ActionPointModel } from '../db/ActionPoint'; +import { ACTION_POIN } from '../consts/consts'; + +export async function getAp(now: number, roleId: string) { + let dataAp = await ActionPointModel.getAp(roleId); + const maxAp = ACTION_POIN.MAX; // 最大体力值 + const per = ACTION_POIN.PER; // 恢复时间(ms) + let {ap, refTime} = dataAp; + if(ap >= maxAp) { + // 体力溢出不需要做时间的处理 + return { ap, maxAp, refTime: now, apRemainTime:0, isOver: true } + } else { + if(refTime > now) refTime = now; // refTime:每次记录时候最近的一个整的时间点,绝对不会大于now + let n = Math.floor((now - refTime)/per); // 上次记录到现在可以增长多少体力 + ap += n; // 增加上 + if(ap >= maxAp) { // 加上后溢出了 + ap = maxAp; + return { ap, maxAp, refTime: now, apRemainTime:0, isOver: true } + } else { + refTime += n * per; // 更新refTime到离现在最近的一个整的时间点 + let apRemainTime = Math.floor((refTime + per - now)/1000); // 恢复下一点需要多少时间 + + return { ap, maxAp, refTime, apRemainTime, isOver: false } + } + } +} + +export async function setAp(now: number, roleId: string, changeAp: number) { + let ApResult = await getAp(now, roleId); + let { ap, maxAp, refTime, apRemainTime, isOver } = ApResult; // 更新ap + ap += changeAp; + if(ap >= maxAp) { // 溢出 + refTime = now; + apRemainTime = 0; + } + if(ap < 0) return null // 体力不足 + await ActionPointModel.saveAp(roleId, ap, refTime); + + if(isOver && ap < maxAp) apRemainTime = Math.floor(ACTION_POIN.PER / 1000); // 特殊处理 + return {ap, maxAp, refTime, apRemainTime} +} diff --git a/game-server/app/services/dailyBattleService.ts b/game-server/app/services/dailyBattleService.ts new file mode 100644 index 000000000..b9f0a954e --- /dev/null +++ b/game-server/app/services/dailyBattleService.ts @@ -0,0 +1,49 @@ +/** + * 每日本相关 + */ + +import { DailyRecordModel } from '../db/DailyRecord'; +import { getGamedata } from '../util/gamedata'; + +// 检查每日本次数checkBattle使用 +export async function checkDaily(roleId: string, battleId: number, inc: number) { + let dicDaily = getGamedata('dic_zyz_daily'); + let dicDailyWar = getGamedata('dic_zyz_gk_daily'); + let dailyWar = dicDailyWar.find(cur => cur.war_id == battleId); + if(!dailyWar) return { status: -1, msg: '未找到该关卡' }; + let type = dailyWar.dailyType; + + let curDaily = dicDaily.find(cur => cur.dailyType == type); + if(!curDaily) return { status: -1, msg: '未找到该类型' }; + let dailyRecord = await DailyRecordModel.refreshRecord(roleId, type); + let { count } = dailyRecord; + if(count + inc > curDaily.sum ) { + return { status: -1, msg: '次数不足' } + } + return {status: 1, type, count, sum: curDaily.sum}; +} + +// 检查每日本次数warEnd和warSweep使用 +export async function checkDailyAndIncrease(roleId: string, battleId: number, inc: number, isRef: boolean) { + let dicDaily = getGamedata('dic_zyz_daily'); + let dicDailyWar = getGamedata('dic_zyz_gk_daily'); + let dailyWar = dicDailyWar.find(cur => cur.war_id == battleId); + if(!dailyWar) return { status: -1, msg: '未找到该关卡' }; + let type = dailyWar.dailyType; + + let curDaily = dicDaily.find(cur => cur.dailyType == type); + if(!curDaily) return { status: -1, msg: '未找到该类型' }; + + let dailyRecord: any; + if(isRef) { + dailyRecord = await DailyRecordModel.refreshRecord(roleId, type); + } else { + dailyRecord = await DailyRecordModel.getDailyRecordById(roleId, type); + } + let { count } = dailyRecord; + if(count + inc > curDaily.sum ) { + return { status: -1, msg: '次数不足' } + } + let result = await DailyRecordModel.increseDailyCount(roleId, type, inc); + return {status: 1, type, count: result.count, sum: curDaily.sum}; +} \ No newline at end of file diff --git a/game-server/app/services/eventSercive.ts b/game-server/app/services/eventSercive.ts new file mode 100644 index 000000000..d8bdcda02 --- /dev/null +++ b/game-server/app/services/eventSercive.ts @@ -0,0 +1,154 @@ +import { Application, FrontendOrBackendSession } from 'pinus'; +import { getGamedata } from '../util/gamedata'; +import { EventRecordModel } from '../db/EventRecord'; +import { RoleModel } from '../db/Role'; +import { genCode, decodeStrSingle } from '../util/util'; +import { EVENT_STATUS, EVENT_RECORD_STATUS } from '../consts/consts'; + + +export async function setBattleStatus(app: Application, session: FrontendOrBackendSession, roleId: string, battleId: number , isSuccess: boolean, battleCode: string) { + let now = new Date(); + let eventStatus = session.get('eventStatus'); + let refTime = eventStatus == EVENT_STATUS.OPEN? getEventTime(now): 0; + console.log('***setBattleStatus', eventStatus, refTime) + + + let { BATTLE_SUCCESS, BATTLE_FAIL } = EVENT_RECORD_STATUS; + let result = await EventRecordModel.setBattleStatus(roleId, battleId, refTime, isSuccess?BATTLE_SUCCESS:BATTLE_FAIL, battleCode); + await checkEvent(app, session, true); + return result; +} + +export function getEventTime(now: Date) { + let curTime = Number(now); + let todayA = now.setHours(12, 0, 0, 0); // 每天12点 + let todayB = now.setHours(18, 0, 0, 0); // 每天18点 + let yesterdayA = todayA - 86400000; // 前一天12点 + let t = 0; + if(curTime < todayA) { + t = yesterdayA; + } else if (curTime >= todayA && curTime < todayB) { + t = todayA; + } else if (curTime >= todayB) { + t = todayB; + } + return t +} + +export async function startEvent(app: Application, session: FrontendOrBackendSession) { + + // console.log('*******setEventStatus') + let roleId = session.get('roleId'); + let roleName = session.get('roleName'); + let channelName = roleId; + let event = await refreshEvent(1, roleId, roleName, 0); // 刷新初始的一件 + await RoleModel.setEventStatus(roleId, EVENT_STATUS.STARTING); + session.set('eventStatus', EVENT_STATUS.STARTING); + session.push('eventStatus', () => {}); + pushEventMsg(app, roleId, channelName, { event }); // 推送 + +} + +export async function checkEvent(app: Application, session: FrontendOrBackendSession, isForce:boolean = false) { + + try { + + let roleId = session.get('roleId'); + if(roleId) { + + let roleName = session.get('roleName'); + let channelName = roleId; + let eventStatus = session.get('eventStatus')||EVENT_STATUS.WAITING; + + let eventTime = session.get('getEventTime')||0; + let now = new Date(); + let t = getEventTime(now); + + + let channel = app.get('channelService').getChannel(channelName, false); + console.log('****channel', channelName, !!channel, eventTime, t, eventStatus) + + if(!!channel && (eventTime < t || isForce)) { // 第一次登陆后可以刷新了 + + if (eventStatus == EVENT_STATUS.STARTING) { + let event = await EventRecordModel.getEventRecordByTime(roleId, 0); + pushEventMsg(app, roleId, channelName, { event }); // 推送 + session.set('getEventTime', t); + session.push('getEventTime', () => {}); + } else if( eventStatus == EVENT_STATUS.OPEN ) { + + let event = await EventRecordModel.getEventRecordByTime(roleId, t); + if(event.length == 0) { // 刷新 + const num = 3; // 每次刷3个 + event = await refreshEvent(num, roleId, roleName, t); + } + + console.log(event) + // 推送 + pushEventMsg(app, roleId, channelName, { event }); + session.set('getEventTime', t); + session.push('getEventTime', () => {}); + } + } + } + return; + }catch(err) { + console.log(err.stack); + throw err + } +} + +async function refreshEvent(num: number, roleId: string, roleName: string, t) { + let event = new Array(); + let dicEvent = getGamedata('dic_zyz_event'); + let role = await RoleModel.findByRoleId(roleId); + dicEvent = dicEvent.filter(cur => { // 筛选适合等级 + let { suitLevel } = cur; + suitLevel = decodeStrSingle('eventSuitLevel', suitLevel); + return suitLevel.min <= role.lv && suitLevel.max >= role.lv + }); + let historyRecord = await EventRecordModel.getHostoryEventRecord(roleId); + let {history, turn} = historyRecord; + let randomList = dicEvent.filter(cur => { + return history.find(ccur => { + return ccur.eventId != cur.eventID; + }); + }); + console.log(JSON.stringify(randomList)); + + for(let i = 0; i < num; i++) { + if(randomList.length == 0) { // 一轮刷新过,开始新的一轮,保证所有事件都能刷新一遍 + turn ++; + randomList = [...dicEvent]; + } + if(randomList.length == 0) break; // 如果还是为0,pass + + let index = Math.floor(Math.random() * randomList.length); + let dic = randomList[index]; + let eventCode = genCode(8); + let data = await EventRecordModel.saveEventRecord(eventCode, { + roleId, refTime: t, eventId: dic.eventID, + roleName, turn, type: dic.eventType, battleId: dic.warId||0, quality: dic.quality, + status: EVENT_RECORD_STATUS.WAITING + }); + event.push(data) + randomList.splice(index, 1); + } + return event; +} + +function pushEventMsg(app, roleId, channelName, msg ) { + console.log('***pushEventMsg', channelName) + let channelService = app.get('channelService'); + + let param = { msg }; + let channel = channelService.getChannel(channelName, false); + if(!!channel) { + let tsid = channel.getMember(roleId)['sid']; + + channelService.pushMessageByUids('onSpecialEvent', param, [{ + uid: roleId, + sid: tsid + }]); + } +} \ No newline at end of file diff --git a/game-server/app/services/expeditionService.ts b/game-server/app/services/expeditionService.ts new file mode 100644 index 000000000..08eb7f251 --- /dev/null +++ b/game-server/app/services/expeditionService.ts @@ -0,0 +1,88 @@ + +import { ExpeditionPointModel } from '../db/ExpeditionPoint'; +import { RoleModel } from '../db/Role'; + +import { getWarJsons, getGamedata } from '../util/gamedata'; +import { decodeStr } from '../util/util'; +import { WAR_JSON_ATTRIBUTE_TYPE } from '../consts/consts'; + + +// 匹配玩家 +export async function matchPlayers(scale: number, range: number, myCe: number ,enemyObj: {enemyFrom: number, enemyId: string, enemies: Array }) { + + let min = myCe * scale * (1 - range/100); + let max = myCe * scale * (1 + range/100); + console.log(min, max, enemyObj); + + return false +} + +// 匹配机器人 +export async function matchRobots(scale: number, myCe: number, robotCe: number, warJsonIndex:any, lv: number, enemyObj: {enemyFrom: number, enemyId: string, enemies: Array }) { + let {json: dicWarJson, fileName } = getWarJsons(warJsonIndex); + if(dicWarJson) { + enemyObj.enemyFrom = 2; + enemyObj.enemyId = fileName; + + let ratio = myCe / robotCe * scale; // 玩家战力/机器人初始战力*系数 + for(let enemy of dicWarJson) { + let attribute = decodeWarJsonAttribute(enemy.attribute); // 格式:{'hp':1000, ...} + for(let value in attribute) { + attribute[value] *= ratio; + attribute[value] = Math.round(attribute[value]); + } + enemyObj.enemies.push({...enemy, attribute, lv}); + } + + return true + } else { + return false + } +} + +// 远征匹配系数表 +export async function getCEScaleAndRange(roleId: string, curDicExpedition: any) { + // 匹配,判断是不是新手期 + const role = await RoleModel.findByRoleId(roleId); + let now = new Date(); + let today = now.setHours(0,0,0,0); + let isNew = today - role.createdAt.getTime() <= 3*24*60*60*1000; + let scale = isNew?curDicExpedition.CEScaleNew:curDicExpedition.CEScale; + let range = isNew?curDicExpedition.CERangeNew:curDicExpedition.CERange; + return {scale, range, lv: role.lv} +} + +// 远征表属性解码 +export function decodeWarJsonAttribute(attribute) { + let arr = decodeStr('attribute', attribute); + let obj = {}; + for(let {id, value} of arr) { + let field = WAR_JSON_ATTRIBUTE_TYPE[id]; + if(field) { + obj[field] = value; + } + } + return obj +} + +// 远征累计点数获取 +export async function getPointRewardStatus(roleId: string) { + let role = await RoleModel.findByRoleId(roleId); + let {expeditionPoint = 0} = role; + let dicExpeditionPoint = getGamedata('dic_expedition_point'); + let pointRewards = { + expeditionPoint, + rewards: dicExpeditionPoint.map(cur => { + return { point: cur.point, received: false } + }) + }; + let pointStatusInDatabase = await ExpeditionPointModel.getExpeditionPoint(roleId); + if(pointStatusInDatabase) { + let { rewards = [] } = pointStatusInDatabase; + pointRewards.rewards.forEach(cur => { + let obj = rewards.find(ccur => ccur.point == cur.point); + if(obj) cur.received = obj.received; + }); + } + return pointRewards +} diff --git a/game-server/app/services/rewardService.ts b/game-server/app/services/rewardService.ts index cd46c0349..2ccdcc3da 100644 --- a/game-server/app/services/rewardService.ts +++ b/game-server/app/services/rewardService.ts @@ -1,4 +1,4 @@ -import { BATTLE_REWARD_TYPE, GOOD_TYPE } from './../consts/consts'; +import { GOOD_TYPE } from './../consts/consts'; import { EquipModel } from './../db/Equip'; import { CounterModel } from './../db/Counter'; import { decodeStr } from '../util/util'; @@ -8,13 +8,18 @@ export async function handleFixedReward(roleId: string, roleName: string, reward let reward = decodeStr('fixReward', rewardStr); let rewards = []; for(let obj of reward) - rewards.push({type: BATTLE_REWARD_TYPE.FIX_REWARD, ...obj, count: obj.count}); + rewards.push({ ...obj, count: obj.count * multi}); + const result = await handleReward(roleId, roleName, reward); + return result; +} + +export async function handleReward(roleId: string, roleName: string, rewards: Array<{type: number, gid: number, count: number}>) { let returnGoods = new Array(); for(let goods of rewards) { let goodInfo = getGoodById(goods.gid); if(goodInfo.goodType == GOOD_TYPE.EQUIP) { // 装备 - let result = await rewardWeapons(roleId, roleName, goodInfo, {id: goods.gid, cnt: goods.count * multi }); + let result = await rewardWeapons(roleId, roleName, goodInfo, {id: goods.gid, cnt: goods.count }); for(let obj of result) { returnGoods.push({dropType: goods.type, ...obj}) } diff --git a/game-server/app/services/warRewardService.ts b/game-server/app/services/warRewardService.ts new file mode 100644 index 000000000..0711edefe --- /dev/null +++ b/game-server/app/services/warRewardService.ts @@ -0,0 +1,98 @@ +/** + * 战场奖励发放 对象 + * 支持战场相关的奖励格式,目前包括fixedReward, randomReward, conditionReward + */ + +import { BattleDropModel } from '../db/BattleDrop'; +import { getWarById } from '../util/gamedata'; +import { decodeStr } from '../util/util'; +import { BATTLE_REWARD_TYPE } from '../consts/consts'; +import { handleReward } from './rewardService'; + +export class WarReward { + roleId: string; + roleName: string; + battleId: number; + condition: Map; + warInfo: any; + isSuccess: boolean; + rewards: Array<{type: number, gid: number, count: number}>; + + constructor(roleId: string, roleName: string, battleId: number, isSuccess: boolean) { + this.roleId = roleId; + this.roleName = roleName; + this.battleId = battleId; + this.condition = new Map(); + this.warInfo = getWarById(battleId); + this.isSuccess = isSuccess; + } + + public setCondition(id: number, isOk: boolean) { + this.condition.set(id, isOk); + } + + private handleFixReward(num: number) { + if(this.isSuccess) { // 成功了才给固定奖励 + let {fixReward = ''} = this.warInfo; + let reward = decodeStr('fixReward', fixReward); + for(let obj of reward) this.rewards.push({type: BATTLE_REWARD_TYPE.FIX_REWARD, ...obj, count: obj.count * num}); + } + } + private handleConditionReward(num: number) { + if(this.isSuccess) { + let {conditionReward = ''} = this.warInfo; + let reward = decodeStr('conditionReward', conditionReward); + for(let obj of reward) { + if(this.condition.get(obj.condition)) { + this.rewards.push({type: BATTLE_REWARD_TYPE.CONDITION_REWARD, ...obj, count: obj.count * num}); + } + } + } + } + + private async handleRandomReward(num: number) { + if(this.isSuccess) { + let {RandomReward:randomReward = ''} = this.warInfo; + + let reward = decodeStr('randomReward', randomReward); + for(let obj of reward) { + let { gid, frequency } = obj; + let dropHistory = await BattleDropModel.findByGid(this.roleId, this.battleId, gid); + let { getNum = 0, allNum = 0, getSum = 0, allSum = 0 } = dropHistory; + for(let i = 0; i < num; i ++) { + let flag = false; // 是否可以获得 + if(allNum + 1 > frequency) { + allNum = 0; getNum = 0; + } + allNum++; allSum++; + if(getNum == 0) { + let r = Math.random(); + if(r <= 1/frequency*allNum || (allNum >= frequency) ) { + flag = true; // 独立概率随机 + } + } + if(flag) { + getNum ++; getSum++; + this.rewards.push({type: BATTLE_REWARD_TYPE.RANDOM_REWARD, ...obj}); + } + } + await BattleDropModel.updateByGid(this.roleId, this.battleId, gid, { + getNum, allNum, getSum, allSum + }); + } + } + } + + public async saveReward(num: number) { + this.rewards = new Array(); + // let warType = this.warInfo.warType; + + this.handleFixReward(num); + this.handleConditionReward(num); + await this.handleRandomReward(num); + + let returnGoods = await handleReward(this.roleId, this.roleName, this.rewards); + return returnGoods; + } + +} \ No newline at end of file diff --git a/game-server/app/util/util.ts b/game-server/app/util/util.ts index 8e31f71e2..d942816b5 100644 --- a/game-server/app/util/util.ts +++ b/game-server/app/util/util.ts @@ -68,57 +68,6 @@ const moment = require('moment'); }; } - - // 获取物品 - export class Reward { - roleId: string; - roleName: string; - rewards: Array<{type?: number, gid: number, count: number}>; - - constructor(roleId: string, roleName: string, rewards: Array<{type?: number, gid: number, count: number}>) { - this.roleId = roleId; - this.roleName = roleName; - this.rewards = rewards; - } - - public async saveReward() { - - let returnGoods = new Array(); - for(let goods of this.rewards) { - let goodInfo = getGoodById(goods.gid); - if(goodInfo.goodType == GOOD_TYPE.EQUIP) { // 装备 - let result = await this.rewardWeapons(goodInfo, {id: goods.gid, cnt: goods.count }); - for(let obj of result) { - returnGoods.push({dropType: goods.type, ...obj}) - } - } - } - return returnGoods; - } - - private async rewardWeapons (dicGood: any, weapon: {id:number,cnt:number }) { - - let weaponsData = []; - let cnt = weapon.cnt; - while (cnt > 0) { - const seqId = await CounterModel.getNewCounter('eid'); - const equipInfo = { - roleId: this.roleId, - roleName: this.roleName, - eid: weapon.id, - eName: dicGood.name, - seqId, - quality: dicGood.lv, - type: dicGood.goodType - } - const equip = await EquipModel.createEquip(equipInfo); - cnt -= 1; - weaponsData.push(equip); - } - return weaponsData; - } - } - /** * 将 | 分隔的字符串解析为数组,如:a|b|c 解析为[a, b, c] * @param str 要解析的字符串