import { ExpeditionPointModel } from '../db/ExpeditionPoint'; import Role, { RoleModel } from '../db/Role'; import { PvpDefenseModel } from '../db/PvpDefense'; import { getWarJsons, getGamedata, getExpeditionById } from '../pubUtils/gamedata'; import { decodeStr, resResult, setLocalHours, shouldRefresh } from '../pubUtils/util'; import { EXPEDITION_CONST, HERO_CE_RATIO, getAttrCeRatio } from '../consts'; import { getAtrrNameById} from '../consts'; import { ExpeditionWarRecordModel } from '../db/ExpeditionWarRecord'; export async function findOrCreateEnemies(roleId: string, myCe: number, expeditionCode: string, expeditionId: number, battleStatus: number) { let expeditionWarRecord = await ExpeditionWarRecordModel.getRecordByCodeAndId(expeditionCode, expeditionId); if(!expeditionWarRecord) { // 如果没有信息 let curDicExpedition = getExpeditionById(expeditionId); if(curDicExpedition) { let enemyObj = { enemyFrom: 0, enemyId: '', enemies: new Array(), ce: 0 }; // 获取系数和步长 let {scale, range, lv} = await getCEScaleAndRange(roleId, curDicExpedition); // 优先匹配其他玩家 let flag = await matchPlayers(roleId, scale, range, myCe, curDicExpedition.json, enemyObj); // 当数量不够时使用机器人匹配 if(!flag) { flag = await matchRobots(scale, myCe, curDicExpedition.ce, curDicExpedition.json, lv, enemyObj); } if(flag) { // 保存 let {warId} = curDicExpedition; expeditionWarRecord = await ExpeditionWarRecordModel.saveRecord(expeditionCode, expeditionId, { roleId, battleId: warId, ...enemyObj, battleStatus }); } } } // 处理当前血量 let {enemiesCurHpAp, enemies} = expeditionWarRecord; for(let enemy of enemies) { let cur = {"hp": 0, "ap": 0}; let getHp = enemiesCurHpAp && enemiesCurHpAp.find(cur => cur.dataId == enemy.dataId); if(getHp) { cur.hp = getHp.hp; cur.ap = getHp.ap; } else { cur.hp = enemy.attribute.hp; cur.ap = 0; } enemy["cur"] = cur; } return expeditionWarRecord; } // 匹配玩家 export async function matchPlayers(roleId: string, scale: number, range: number, myCe: number, warJsonIndex:any, enemyObj: {enemyFrom: number, enemyId: string, enemies: Array, ce: number }) { let {json: dicWarJson } = getWarJsons(warJsonIndex); let min = myCe * scale * (1 - range/100); let max = myCe * scale * (1 + range/100); let resultRange = await PvpDefenseModel.findByScale(roleId, min, max); if(resultRange.length > 0) { let index = Math.floor(Math.random() * resultRange.length); let result = resultRange[index]; let {roleId, heroes, defCe } = result; enemyObj.enemyFrom = 1; enemyObj.enemyId = roleId; enemyObj.ce = defCe; let heroIndex = 0; for(let enemy of dicWarJson) { if(enemy.relation == 2) { let hero = heroes[heroIndex]; if(hero) { enemyObj.enemies.push({...enemy, ...hero}); heroIndex ++; } } } return true; } else { return false } } // 匹配机器人 export async function matchRobots(scale: number, myCe: number, robotCe: number, warJsonIndex:any, lv: number, enemyObj: {enemyFrom: number, enemyId: string, enemies: Array, ce: number }) { let {json: dicWarJson, fileName } = getWarJsons(warJsonIndex); if(dicWarJson) { enemyObj.enemyFrom = 2; enemyObj.enemyId = fileName + ''; let allCe = 0; let ratio = myCe / HERO_CE_RATIO / HERO_CE_RATIO / robotCe * scale; // 玩家战力/机器人初始战力*系数 for(let enemy of dicWarJson) { if(enemy.relation == 2) { let attribute = decodeWarJsonAttribute(enemy.attribute); // 格式:{'hp':1000, ...} for(let value in attribute) { attribute[value] *= ratio; attribute[value] = Math.round(attribute[value]); } let ce = 0; for(let attrName in attribute) { ce += attribute[attrName] * getAttrCeRatio(attrName)||0; } enemyObj.enemies.push({...enemy, attribute, lv}); allCe += ce; } } console.log(JSON.stringify(enemyObj.enemies)) enemyObj.ce = Math.floor(allCe); 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 = setLocalHours(0, now); 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: string) { let arr = decodeStr('attribute', attribute); // 初始化 let obj = {hp: 0, atk: 0, matk: 0, def: 0, mdef: 0, speed: 0, agi: 0, luk: 0, hit: 0, cri: 0, flee: 0, antCri: 0, damageIncrease: 0, damageDecrease: 0, defIngnore: 0, bloodSuck: 0} for(let {id, value} of arr) { let field = getAtrrNameById(id); if(field) { obj[field] = value; } } return obj } // 远征累计点数获取 export async function getPointRewardStatus(roleId: string, role?: Role) { if(!role) { 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 getResetRemainCnt(curTime: Date, roleId: string, role?: Role, ) { if(!role) { role = await RoleModel.findByRoleId(roleId); } let { expeditionResetCnt, expeditionResetRefTime } = role; let needRefresh = !expeditionResetRefTime || shouldRefresh(expeditionResetRefTime, curTime, EXPEDITION_CONST.REFRESH_TIME); if(needRefresh) { expeditionResetCnt = 0; expeditionResetRefTime = curTime; } let maxCnt = EXPEDITION_CONST.RESET_CNT; return { resetCnt: maxCnt - expeditionResetCnt, needRefresh }; }