添加远征匹配玩家方法

This commit is contained in:
luying
2020-10-28 19:29:59 +08:00
parent 3377e0f99c
commit 222b9c6e12
11 changed files with 282 additions and 27 deletions

View File

@@ -77,6 +77,7 @@ export class ExpeditionBattleHandler {
// 计算我方战斗力(最高五人)
let myCe = await calculateSumCE(roleId, 1, { num: 5 });
console.log(myCe);
let enemyObj = {
enemyFrom: 0,
enemyId: '',
@@ -88,7 +89,7 @@ export class ExpeditionBattleHandler {
// 获取系数和步长
let {scale, range, lv} = await getCEScaleAndRange(roleId, curDicExpedition);
// 优先匹配其他玩家
let flag = await matchPlayers(scale, range, myCe, enemyObj);
let flag = await matchPlayers(roleId, scale, range, myCe, curDicExpedition.json, enemyObj);
// 当数量不够时使用机器人匹配
if(!flag) {
flag = await matchRobots(scale, myCe, curDicExpedition.ce, curDicExpedition.json, lv, enemyObj);

View File

@@ -3,7 +3,7 @@ import { BattleRecordModel } from '../../../db/BattleRecord';
import { BattleSweepRecordModel } from '../../../db/BattleSweepRecord';
import { getWarById, } from '../../../pubUtils/gamedata';
import { genCode } from '../../../pubUtils/util';
import { WAR_TYPE } from '../../../consts/consts';
import { WAR_TYPE, EVENT_STATUS } from '../../../consts/consts';
import { checkDaily, checkDailyAndIncrease } from '../../../services/dailyBattleService';
import { checkTowerWar, towerBattleEnd } from '../../../services/battleService';
import { WarReward } from '../../../services/warRewardService';
@@ -70,7 +70,8 @@ export class NormalBattleHandler {
towerData = Object.assign(towerData, checkResult.data);
} else if (warInfo.warType == WAR_TYPE.EVENT) {
// 记录事件状态
let checkResult = await checkEventBattle( roleId, session.get('eventStatus'), battleId, battleCode);
let eventStatus = session.get('eventStatus')||EVENT_STATUS.WAITING;
let checkResult = await checkEventBattle( roleId, eventStatus, battleId, battleCode);
if(checkResult.status == -1) {
return checkResult.resResult
}

View File

@@ -1,20 +1,44 @@
import { ExpeditionPointModel } from '../db/ExpeditionPoint';
import { RoleModel } from '../db/Role';
import { PvpDefenseModel } from '../db/PvpDefense';
import { getWarJsons, getGamedata } from '../pubUtils/gamedata';
import { decodeStr } from '../pubUtils/util';
import { decodeStr, resResult } from '../pubUtils/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<any> }) {
export async function matchPlayers(roleId: string, scale: number, range: number, myCe: number, warJsonIndex:any, enemyObj: {enemyFrom: number, enemyId: string, enemies: Array<any> }) {
let {json: dicWarJson } = getWarJsons(warJsonIndex);
let min = myCe * scale * (1 - range/100);
let max = myCe * scale * (1 + range/100);
console.log(min, max, enemyObj);
return false
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 } = result;
enemyObj.enemyFrom = 1;
enemyObj.enemyId = roleId;
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
}
}
// 匹配机器人
@@ -26,12 +50,14 @@ export async function matchRobots(scale: number, myCe: number, robotCe: number,
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]);
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]);
}
enemyObj.enemies.push({...enemy, attribute, lv});
}
enemyObj.enemies.push({...enemy, attribute, lv});
}
return true
@@ -55,7 +81,10 @@ export async function getCEScaleAndRange(roleId: string, curDicExpedition: any)
// 远征表属性解码
export function decodeWarJsonAttribute(attribute) {
let arr = decodeStr('attribute', attribute);
let obj = {};
let obj = {}
for(let key in WAR_JSON_ATTRIBUTE_TYPE) {
obj[WAR_JSON_ATTRIBUTE_TYPE[key]] = 0; // 初始化
}
for(let {id, value} of arr) {
let field = WAR_JSON_ATTRIBUTE_TYPE[id];
if(field) {

View File

@@ -30,7 +30,6 @@ export default class UserController extends Controller {
public async createRoleData() {
const { ctx } = this;
console.log(ctx.request.body)
const { hid, hlv, eid, elv, ecount, ehid, itemid, itemcount, selectedRowKeys: uids, optType } = ctx.request.body;
if(optType == 'hero') {
ctx.body = await ctx.service.users.createHero(uids, hid, hlv);
@@ -42,4 +41,28 @@ export default class UserController extends Controller {
ctx.body = ctx.service.utils.resResult(STATUS.WRONG_PARMS);
}
}
public async getPveDefense() {
const { ctx } = this;
const { roleId } = ctx.request.body;
ctx.body = await ctx.service.users.getPvpDefense(roleId);
}
public async getHeroList() {
const { ctx } = this;
const { roleId } = ctx.request.body;
ctx.body = await ctx.service.users.getHeroList(roleId);
}
public async saveHeroToDefense() {
const { ctx } = this;
const { roleId, roleName, hid } = ctx.request.body;
ctx.body = await ctx.service.users.saveHeroToDefense(roleId, roleName, hid);
}
public async removeHeroFromDefense() {
const { ctx } = this;
const { roleId, hid } = ctx.request.body;
ctx.body = await ctx.service.users.removeHeroFromDefense(roleId, hid);
}
}

View File

@@ -28,5 +28,11 @@ export default (app: Application) => {
router.post('/api/users/deleterole',tokenParser, controller.users.deleteRole);
router.post('/api/users/getrolelist',tokenParser, controller.users.getrolelist);
router.post('/api/users/createroledata',tokenParser, controller.users.createRoleData);
router.post('/api/users/getpvpdefense',tokenParser, controller.users.getPveDefense);
router.post('/api/users/getherolist',tokenParser, controller.users.getHeroList);
router.post('/api/users/saveherotodefense',tokenParser, controller.users.saveHeroToDefense);
router.post('/api/users/removeherofromdefense',tokenParser, controller.users.removeHeroFromDefense);
};

View File

@@ -1,6 +1,6 @@
import { UserModel } from '@db/User';
import { RoleModel } from '@db/Role';
import { HeroModel } from '@db/Hero';
import Hero, { HeroModel } from '@db/Hero';
import { EquipModel } from '@db/Equip';
import { CounterModel } from '@db/Counter';
import { ActionPointModel } from '@db/ActionPoint';
@@ -17,6 +17,7 @@ import { HangUpSpdUpRecModel } from '@db/HangUpSpdUpRec';
import { SearchRecordModel } from '@db/SearchRecord';
import { TowerRecordModel } from '@db/TowerRecord';
import { TowerTaskRecModel } from '@db/TowerTaskRec';
import { PvpDefenseModel } from '@db/PvpDefense';
import { Service } from 'egg';
import Counter from '@db/Counter';
@@ -110,6 +111,7 @@ export default class GMUsers extends Service {
await SearchRecordModel.deleteAccount(roleId);
await TowerTaskRecModel.deleteAccount(roleId);
await TowerRecordModel.deleteAccount(roleId);
await PvpDefenseModel.deleteAccount(roleId);
return ctx.service.utils.resResult(STATUS.SUCCESS);
}
@@ -158,10 +160,13 @@ export default class GMUsers extends Service {
let heroCount = await HeroModel.count({roleId: role.roleId}).lean();
let equipCount = await EquipModel.count({roleId: role.roleId}).lean();
let itemCount = (role.consumeGoods?role.consumeGoods.length: 0) + (role.souls?role.souls.length:0);
let defense = await PvpDefenseModel.findByRoleId(role.roleId);
let {roleId, roleName, serverId, lv, vLv, gold, coin} = role;
let {uid, tel} = role.userInfo;
result.push({
key: roleId, roleId, roleName, serverId, lv, vLv, uid, tel, heroCount, equipCount, itemCount, gold, coin
key: roleId, roleId, roleName, serverId, lv, vLv, uid, tel, heroCount, equipCount, itemCount, gold, coin,
hasDefense: defense?'是':'否', defCe: defense?defense.ce:0
});
}
return ctx.service.utils.resResult(STATUS.SUCCESS, { list: result });
@@ -284,4 +289,104 @@ export default class GMUsers extends Service {
return ctx.service.utils.resResult(STATUS.SUCCESS, { uids });
}
}
public async getPvpDefense(roleId: string) {
const {ctx} = this;
let result = await PvpDefenseModel.findByRoleId(roleId);
return ctx.service.utils.resResult(STATUS.SUCCESS, {
hasDefense: !!result, defense: result
})
}
public async getHeroList(roleId: string) {
const {ctx} = this;
let herolist = await HeroModel.findByRole(roleId);
let defense = await PvpDefenseModel.findByRoleId(roleId);
let result = Array<Hero>();
for(let hero of herolist) {
if(defense) {
let {heroes = []} = defense;
let curHero = heroes.find(cur => cur.actorId == hero.hid);
if(!curHero) {
result.push(hero);
}
} else{
result.push(hero);
}
}
return ctx.service.utils.resResult(STATUS.SUCCESS, {
heroes: result
})
}
public async saveHeroToDefense(roleId: string, roleName: string, hid: number) {
const {ctx} = this;
let hero = await HeroModel.findByHidAndRole(hid, roleId);
if(!hero) {
return ctx.service.utils.resResult(STATUS.GM_HERO_NOT_FOUND);
}
let { lv } = hero;
let dicHero = ctx.service.utils.getHeroById(hid);
let { hp, hp_up, atk, atk_up, matk, matk_up, def, def_up, mdef, mdef_up } = dicHero;
let ce = ctx.service.utils.calculateCE({hid, lv});
let heroInfo = {
actorId: dicHero.heroId,
actorName: dicHero.name,
attribute: {
hp: hp + lv * hp_up,
atk: atk + lv * atk_up,
matk: matk + lv * matk_up,
def: def + lv * def_up,
mdef: mdef + lv * mdef_up,
agi: 0,
luk: 0,
speed: 0,
hit: 0,
cri: 0,
flee: 0,
antCri: 0,
damageIncrease: 0,
damageDecrease: 0,
defIgnore: 0,
bloodSuck: 0,
ap: 0
},
lv,
ce
};
let defense = await PvpDefenseModel.findByRoleId(roleId);
if(!defense) {
defense = await PvpDefenseModel.createPvpDefense({roleId, roleName, heroes: [heroInfo], ce});
} else {
defense = await PvpDefenseModel.addHeroToDefense(roleId, heroInfo, ce);
}
return ctx.service.utils.resResult(STATUS.SUCCESS, {
defense
});
}
public async removeHeroFromDefense(roleId: string, hid: number) {
const {ctx} = this;
let defense = await PvpDefenseModel.findByRoleId(roleId);
if(!defense) {
return ctx.service.utils.resResult(STATUS.GM_PVP_DEFENSE_NOT_FOUND);
}
let {heroes} = defense;
let curHero = heroes.find(cur => cur.actorId == hid);
if(!curHero) {
return ctx.service.utils.resResult(STATUS.GM_PVP_DEFENSE_HERO_NOT_FOUND);
}
defense = await PvpDefenseModel.removeHeroFromDefense(roleId, hid, curHero.ce);
return ctx.service.utils.resResult(STATUS.SUCCESS, {
defense
});
}
}

View File

@@ -2,5 +2,11 @@ import { EggAppConfig, PowerPartial } from 'egg';
export default () => {
const config: PowerPartial<EggAppConfig> = {};
config.cluster = {
listen: {
port: 7500
}
};
return config;
};

View File

@@ -77,5 +77,8 @@ export const STATUS = {
GM_DUPLICATE_API: { code: 60007, simStr: '该接口已存在' },
GM_DUPLICATE_GROUP: { code: 60008, simStr: '该用户组已存在' },
GM_CREATE_ERROR: { code: 60009, simStr: '创建失败' },
GM_ROLE_NOT_FOUND: { code: 60010, simStr: '未找到该玩家' }
GM_ROLE_NOT_FOUND: { code: 60010, simStr: '未找到该玩家' },
GM_HERO_NOT_FOUND: { code: 60011, simStr: '未找到武将' },
GM_PVP_DEFENSE_NOT_FOUND: { code: 60012, simStr: '该玩家未保存防守阵' },
GM_PVP_DEFENSE_HERO_NOT_FOUND: { code: 60013, simStr: '该守阵没有该武将' }
}

View File

@@ -86,7 +86,7 @@ export default class EventRecord extends BaseModel {
}
public static async setStatusByCode(roleId: string, eventCode: string, status: number , lean=true ) {
let result = await EventRecordModel.findOneAndUpdate({ roleId, eventCode }, {$set:{ status }}).lean(lean);
let result = await EventRecordModel.findOneAndUpdate({ roleId, eventCode }, {$set:{ status }}, {new: true, upsert: true}).lean(lean);
return result;
}

81
shared/db/PvpDefense.ts Normal file
View File

@@ -0,0 +1,81 @@
import BaseModel from './BaseModel';
import { index, getModelForClass, prop } from '@typegoose/typegoose';
class Heroes {
@prop({ required: true })
actorId: number; // 武将id
@prop({ required: true })
actorName: string; // 武将名
@prop({ required: true })
attribute: {hp: number, atk: number, matk: number, def: number, mdef: number, agi: number, luk: number, speed: number, hit: number, cri: number, flee: number, antCri: number, damageIncrease: number, damageDecrease: number, defIgnore: number, bloodSuck: number, ap: number}; // 属性
@prop({ required: true })
lv: number; // 角色等级
@prop({ required: true })
ce: number; // 战斗力
@prop({ required: false })
skill: string; // 技能
@prop({ required: false })
seid: string; // 技能
@prop({ required: false })
star: number; // 角色星级
}
@index({ roleId: 1 })
@index({ ce: 1 })
export default class PvpDefense extends BaseModel {
@prop({ required: true })
roleId: string; // 角色 id
@prop({ required: true })
roleName: string; // 角色名称
@prop({ required: true, type: Heroes, default: []})
heroes: Array<Heroes>;
@prop({ required: true, default: 0})
ce: number;
public static async findByRoleId(roleId: string, lean = true) {
const result = await PvpDefenseModel.findOne({ roleId }).lean(lean);
return result;
}
public static async findByScale(roleId: string, min: number, max: number, lean = true) {
console.log(min, max);
const result = await PvpDefenseModel.find({ roleId: {$ne: roleId}, ce: { $lte: max, $gte: min } }).sort({updatedAt: -1}).limit(100).lean(lean);
return result;
}
public static async createPvpDefense(params: {roleId: string, roleName: string, heroes: Array<any>, ce: number}, lean=true) {
const doc = new PvpDefenseModel();
const update = Object.assign(doc.toJSON(), params);
const defense = await PvpDefenseModel.findOneAndUpdate({ roleId: params.roleId }, update, {upsert: true, new: true}).lean(lean);
return defense;
}
public static async addHeroToDefense(roleId: string, heroInfo: any, ce: number, lean=true) {
const defense = await PvpDefenseModel.findOneAndUpdate({ roleId: roleId }, {
$inc: {ce},
$push: { heroes: heroInfo }
}, {upsert: true, new: true}).lean(lean);
return defense;
}
public static async removeHeroFromDefense(roleId: string, hid: number, ce: number, lean=true) {
const defense = await PvpDefenseModel.findOneAndUpdate({ roleId: roleId }, {
$inc: {ce: -1 * ce},
$pull: { heroes: { actorId: hid }}
}, {upsert: true, new: true}).lean(lean);
return defense;
}
public static async deleteAccount(roleId: string, lean = true) {
let result = await PvpDefenseModel.deleteMany({roleId}).lean(lean);
return result||{};
}
}
export const PvpDefenseModel = getModelForClass(PvpDefense);

View File

@@ -1,9 +1,9 @@
[
{
"IsTestService":true,
"OpenIosAliPay":false,
"GuideSwitch":true,
"GENERAL_EQUIPMENT_DEFAULT_LEVEL":7,
"ServiceSign":"guanfu"
}
]
[
{
"IsTestService":true,
"OpenIosAliPay":false,
"GuideSwitch":true,
"GENERAL_EQUIPMENT_DEFAULT_LEVEL":7,
"ServiceSign":"guanfu"
}
]