添加远征匹配玩家方法
This commit is contained in:
@@ -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);
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
|
||||
|
||||
|
||||
};
|
||||
|
||||
@@ -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
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,5 +2,11 @@ import { EggAppConfig, PowerPartial } from 'egg';
|
||||
|
||||
export default () => {
|
||||
const config: PowerPartial<EggAppConfig> = {};
|
||||
|
||||
config.cluster = {
|
||||
listen: {
|
||||
port: 7500
|
||||
}
|
||||
};
|
||||
return config;
|
||||
};
|
||||
|
||||
@@ -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: '该守阵没有该武将' }
|
||||
}
|
||||
|
||||
@@ -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
81
shared/db/PvpDefense.ts
Normal 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);
|
||||
@@ -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"
|
||||
}
|
||||
]
|
||||
Reference in New Issue
Block a user