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} = 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} }