/** * 体力系统 */ import { ActionPointModel } from '../db/ActionPoint'; import { TASK_TYPE, STATUS } from '../consts'; import { checkActivityTask, checkTask } from './taskService'; import { getDicApByLv } from '../pubUtils/data'; import { pinus } from 'pinus'; import { resResult } from '../pubUtils/util'; import { RoleModel } from '../db/Role'; /** * 获取当前体力 * @param roleId 玩家id * @param lv 玩家等级 */ export async function getAp(roleId: string, lv: number) { const now = Date.now(); const dicAp = getDicApByLv(lv); let dataAp = await ActionPointModel.getAp(roleId); const maxAp = dicAp.maxAp; // 最大体力值 const per = dicAp.perApRestoreTime * 1000; // 恢复时间(ms) let { ap, refTime } = dataAp; if (ap >= maxAp) { // 体力溢出不需要做时间的处理 return { ap, maxAp, refTime: now, apRemainTime: 0, apMaxRemainTime: 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, apMaxRemainTime: 0, isOver: true } } else { refTime += n * per; // 更新refTime到离现在最近的一个整的时间点 let apRemainTime = Math.floor((refTime + per - now) / 1000); // 恢复下一点需要多少时间 let apMaxRemainTime = (maxAp - ap - 1) * dicAp.perApRestoreTime + apRemainTime; return { ap, maxAp, refTime, apRemainTime, apMaxRemainTime, isOver: false } } } } /** * 增加或减少体力 * @param roleId 玩家id * @param lv 玩家等级 * @param changeAp 体力变化,正是加,负是减 * @param sid * @param funcs 开启的功能 */ export async function setAp(roleId: string, lv: number, changeAp: number, sid: string, funcs: number[]) { const now = Date.now(); const dicAp = getDicApByLv(lv); let ApResult = await getAp(roleId, lv); let { ap, maxAp, refTime, apRemainTime, apMaxRemainTime, isOver } = ApResult; // 更新ap ap += changeAp; if (ap >= maxAp) { // 溢出 refTime = now; apRemainTime = 0; apMaxRemainTime = 0; } if (ap < 0) return null // 体力不足 await ActionPointModel.saveAp(roleId, ap, refTime); if (isOver && ap < maxAp) { // 特殊处理,溢出之后做减少体力的操作时 apRemainTime = dicAp.perApRestoreTime; apMaxRemainTime = (maxAp - ap) * dicAp.perApRestoreTime; } if (changeAp < 0) { await checkTask(roleId, sid, funcs, TASK_TYPE.BATTLE_COST_AP, -1 * changeAp, true, {}); let { serverId } = await RoleModel.findByRoleId(roleId); await checkActivityTask(serverId, sid, funcs, roleId, TASK_TYPE.BATTLE_COST_AP, -1 * changeAp,); } let apJson = { ap, maxAp, refTime, apMaxRemainTime, apRemainTime }; if (changeAp != 0) { let uids = [{ uid: roleId, sid }]; pinus.app.get('channelService').pushMessageByUids('onApUpdate', resResult(STATUS.SUCCESS, { apJson }), uids); } return apJson }