pvp: 更改pvpdefense结构

This commit is contained in:
luying
2021-10-26 11:23:08 +08:00
parent 4a5e23969b
commit e39b120af4
31 changed files with 1542 additions and 1137 deletions

View File

@@ -1,64 +1,10 @@
import BaseModel from './BaseModel';
import { index, getModelForClass, prop, DocumentType, Ref, mongoose } from '@typegoose/typegoose';
import Hero, { } from './Hero';
import Role, { } from './Role';
import { PVP_PLAYER_POS, PVP_HERO_POS } from '../consts';
import PvpHistoryOpp from './PvpHistoryOpp';
import { reduceCe } from '../pubUtils/util';
export class Heroes {
@prop({ required: true })
actorId: number; // 武将id
@prop({ ref: 'Hero', type: mongoose.Schema.Types.ObjectId })
hero: Ref<Hero>;
@prop({ required: true })
ce: number; // 战斗力
@prop({ required: true })
dataId: number;
@prop({ required: true })
order: number;
}
// 初始化
function getInitialOppPlayers() {
let players = new Array<OppPlayers>();
for(let i = PVP_PLAYER_POS.START; i <= PVP_PLAYER_POS.END; i++) {
let p = new OppPlayers();
p.pos = i;
players.push(p);
}
return players;
}
// 初始化
function getInitialOppHeros() {
let heros = new Array<Heroes>();
for(let i = PVP_HERO_POS.START; i <= PVP_HERO_POS.END; i++) {
let p = new Heroes();
p.dataId = i;
p.order = i;
heros.push(p);
}
return heros;
}
export class OppPlayers {
@prop({ required: true })
roleId: string;
@prop({ ref: 'PvpHistoryOpp', type: mongoose.Schema.Types.ObjectId })
oppDef: Ref<PvpHistoryOpp>;
@prop({ required: true })
pos: number;
@prop({ required: true })
isRobot: boolean;
}
export class HeroScores {
@prop({ required: true })
hid: number;
@prop({ required: true })
score: number;
}
import { Defense, Attack, LineupCe, OppPlayer, HeroScore, } from '../domain/battleField/pvp';
import { CounterModel } from './Counter';
import { COUNTER } from '../consts';
import { PVP } from '../pubUtils/dicParam';
@index({ roleId: 1 })
export default class PvpDefense extends BaseModel {
@@ -68,38 +14,43 @@ export default class PvpDefense extends BaseModel {
roleName: string; // 角色名称
@prop({ ref: 'Role', type: mongoose.Schema.Types.ObjectId })
role: Ref<Role>;
@prop({ required: true, type: Heroes, default: getInitialOppHeros(), _id: false })
heroes: Array<Heroes>;
@prop({ required: true, default: null, _id: false })
defense: Defense;
@prop({ required: true, default: null, _id: false })
attack: Attack;
@prop({ required: true, type: () => LineupCe, default: [], _id: false })
lineupCe: LineupCe[];
@prop({ required: true, type: () => OppPlayer, default: [], _id: false })
oppPlayers: OppPlayer[];
@prop({ required: true, type: () => HeroScore, default: [], _id: false })
heroScores: HeroScore[];
@prop({ required: true, default: 0 })
score: number;
@prop({ required: true, default: 1 })
pLv: number;
@prop({ required: true, default: 0 })
hisScore: number; //历史最高积分
@prop({ required: true, default: 0 })
winStreakNum: number; //连胜次数
@prop({ required: true, default: 0, get: (val: number) => reduceCe(val), set: (val: number) => val })
defCe: number; //防守ce
@prop({ required: true, type: OppPlayers, default: getInitialOppPlayers(), _id: false })
oppPlayers: Array<OppPlayers>;
@prop({ required: true, type: HeroScores, default: [], _id: false })
heroScores: Array<HeroScores>;
@prop({ required: true, default: true })
isDefaultHero: boolean;
@prop({ required: true, default: () => { return new Date() } })
refDaily: Date; // 每日刷新控制refOppCnt和setAttackCnt
@prop({ required: true, default: 0 })
refOppCnt: number; // 刷新对手总次数,消耗可根据消耗表算出
@prop({ required: true, default: new Date() })
refOppTime: Date; // 刷新对手时间
@prop({ required: true, default: 0 })
challengeCnt: number; // 可挑战次数
setAttackCnt: number; // 设置挑战阵容次数
@prop({ required: true, default: 0 })
challengeCnt: number; // 可挑战次数每2小时回复一次
@prop({ required: true, default: 0 })
challengeRefTime: number; // 上一次刷新的时间
@prop({ required: true, type: Number, default: [] })
receivedBox: Array<number>;
@prop({ required: true, default: 0 })
seasonNum: number;
@prop({ required: true, default: true })
isFirstEntry: boolean;
public static async findByRoleId(roleId: string, getters = false) {
const result: PvpDefenseType = await PvpDefenseModel.findOne({ roleId }).lean({ getters});
return result;
@@ -114,18 +65,12 @@ export default class PvpDefense extends BaseModel {
}
public static async createPvpDefense(params: pvpUpdateInter) {
let seasonNum = await CounterModel.getCounter(COUNTER.PVP_SEASON_NUM);
const doc = new PvpDefenseModel();
const update = Object.assign(doc.toJSON(), params);
const defense: PvpDefenseType = await PvpDefenseModel.findOneAndUpdate({ roleId: params.roleId }, update, { upsert: true, new: true }).lean();
return defense;
}
public static async createPvpDefenseAndPopulate(params: pvpUpdateInter) {
const doc = new PvpDefenseModel();
const update = Object.assign(doc.toJSON(), params);
const update = Object.assign(doc.toJSON(), params, { seasonNum, challengeCnt: PVP.PVP_CHALLENGE_COUNTS });
const defense: PvpDefenseType = await PvpDefenseModel.findOneAndUpdate({ roleId: params.roleId }, update, { upsert: true, new: true })
.populate('oppPlayers.oppDef', 'oppRoleId pos roleName head frame spine heads frames spines rankLv pLv title lv defCe heroes')
.populate('role')
.lean();
return defense;
@@ -163,15 +108,15 @@ export default class PvpDefense extends BaseModel {
const result: PvpDefenseType = await PvpDefenseModel.findOne({ roleId })
.populate('role', 'head frame spine topLineupCe roleId roleName lv globalCeAttr')
.populate('heroes.hero')
.populate('oppPlayers.oppDef', 'oppRoleId pos roleName head frame spine heads frames spines rankLv title lv pLv defCe heroes').lean({ getters: true, virtuals: true });
.populate('oppPlayer.oppDef', 'oppRoleId pos roleName head frame spine heads frames spines rankLv title lv pLv defCe heroes').lean({ getters: true, virtuals: true });
return result;
}
public static async findByTeamLv(seasonNum: number, min: number, max: number) {
const result: PvpDefenseType[] = await PvpDefenseModel.find({ seasonNum, pLv: { $gte: min, $lte: max } })
const result: PvpDefenseType[] = await PvpDefenseModel.find({ seasonNum, 'defense.pLv': { $gte: min, $lte: max } })
.populate('role', 'head frame spine heads frames spines topLineupCe roleId roleName lv globalCeAttr')
.populate('heroes.hero')
.populate('oppPlayers.oppDef', 'oppRoleId pos roleName head frame spine heads frames spines rankLv pLv title lv defCe heroes')
.populate('oppPlayer.oppDef', 'oppRoleId pos roleName head frame spine heads frames spines rankLv pLv title lv defCe heroes')
.lean({ getters: true, virtuals: true });
return result;
}
@@ -180,7 +125,7 @@ export default class PvpDefense extends BaseModel {
delete update._id;
let result: PvpDefenseType = await PvpDefenseModel.findOneAndUpdate({roleId}, {$set:update}, {new: true})
.populate('role', 'head frame spine heads frames spines topLineupCe roleId roleName lv')
.populate('oppPlayers.oppDef', 'oppRoleId pos roleName head frame spine heads frames spines rankLv pLv title lv defCe heroes').lean({ getters: true, virtuals: true });
.populate('oppPlayer.oppDef', 'oppRoleId pos roleName head frame spine heads frames spines rankLv pLv title lv defCe heroes').lean({ getters: true, virtuals: true });
return result;
}
public static async updateInfo(roleId: string, update: pvpUpdateInter, lean = true) {
@@ -201,6 +146,11 @@ export default class PvpDefense extends BaseModel {
return ranks;
}
public static async resetScores(roleId: string, newSeasonNum: number, newScore: number, newHeroScores: HeroScore[]) {
let result: PvpDefenseType = await PvpDefenseModel.findOneAndUpdate({roleId}, {$set: { seasonNum: newSeasonNum, score: newScore, heroScores: newHeroScores, challengeCnt: PVP.PVP_CHALLENGE_COUNTS, challengeRefTime: 0, winStreakNum: 0 }}, {new: true}).lean();
return result;
}
public static async deleteHero(roleId: string, hid: number) {
let result:PvpDefenseType = await PvpDefenseModel.findOneAndUpdate({roleId}, {$pull:{heroes: {actorId:hid}}}, {new: true}).lean();
return result;

View File

@@ -1,94 +1,54 @@
import BaseModel from './BaseModel';
import { index, getModelForClass, prop, DocumentType } from '@typegoose/typegoose';
class Reward {
@prop({ required: true })
id: number;
@prop({ required: true })
count: number;
}
import { Reward, HeroReward, HeroScore } from '../domain/battleField/pvp';
class HeroReward {
@index({ roleId: 1, seasonNum: 1 })
export default class PvpSeasonResult extends BaseModel {
@prop({ required: true })
hid: number;
@prop({ required: true })
id: number;
@prop({ required: true })
count: number;
}
export class HeroScores {
@prop({ required: true })
hid: number;
@prop({ required: true })
score: number;
@prop({ required: true })
goodId: number;
@prop({ required: true })
count: number;
}
export interface pvpUpdate {
rankGoods?:Array<Reward>;
oldSeasonData?: SeasonData;
show?: boolean;
heroGoods?:Array<HeroReward>;
}
class SeasonData {
@prop({ required: true })
score: number;
@prop({ required: true })
pLv: number;
@prop({ required: true, type:HeroScores, default:[] })
heroScores: HeroScores[];
roleId: string;
@prop({ required: true })
seasonNum: number;
@prop({ required: true })
challengeCnt: number;
@prop({ required: true })
challengeRefTime: number;
@prop({ required: true })
seasonEndTime: number;
@prop({ required: true })
score: number;
@prop({ required: true, type: () => HeroScore, default:[] })
heroScores: HeroScore[];
@prop({ required: true })
rankLv: number;
@prop({ required: true })
refOppCnt:number;
}
@index({ roleId: 1 })
export default class PvpSeasonResult extends BaseModel {
@prop({ required: true })
roleId: string;
@prop({ required: true, type: SeasonData, _id: false})
oldSeasonData: SeasonData;
@prop({ required: true, default: true })
show: boolean;
@prop({ required: true, type: HeroReward, default: [], _id: false})
heroGoods: Array<HeroReward>;
@prop({ required: true, type: () => HeroReward, default: [], _id: false})
heroGoods: HeroReward[];
@prop({ required: true, type: Reward, default: [], _id: false})
rankGoods: Array<Reward>;
rankGoods: Reward[];
public static async updatePvpSeasonResult(roleId: string, update: pvpUpdate , lean = true) {
let result: PvpSeasonResultType = await PvpSeasonResultModel.findOneAndUpdate({roleId}, {$set: update}, {upsert: true, new: true}).lean(lean);
@prop({ required: true })
newScore: number;
@prop({ required: true, type: () => HeroScore, default:[] })
newHeroScores: HeroScore[];
public static async updatePvpSeasonResult(roleId: string, seasonNum: number, update: PvpSeasonResultUpdate , lean = true) {
let result: PvpSeasonResultType = await PvpSeasonResultModel.findOneAndUpdate({roleId, seasonNum}, {$set: update}, {upsert: true, new: true}).lean(lean);
return result;
}
public static async getPvpSeasonResult(roleId: string, lean = true) {
let result: PvpSeasonResultType = await PvpSeasonResultModel.findOne({roleId}).lean(lean);
public static async getPvpSeasonResult(roleId: string, seasonNum: number, lean = true) {
let result: PvpSeasonResultType = await PvpSeasonResultModel.findOne({ roleId, seasonNum }).lean(lean);
return result;
}
}
export const PvpSeasonResultModel = getModelForClass(PvpSeasonResult);
export interface PvpSeasonResultType extends Pick<DocumentType<PvpSeasonResult>, keyof PvpSeasonResult> { };
export interface PvpSeasonResultType extends Pick<DocumentType<PvpSeasonResult>, keyof PvpSeasonResult> { };
export type PvpSeasonResultUpdate = Partial<PvpSeasonResultType>;

View File

@@ -732,6 +732,14 @@ export default class Role extends BaseModel {
const role: RoleType = await RoleModel.findOneAndUpdate({ roleId }, { $addToSet: { guide: { $each: ids } } }, { new: true }).lean();
return role;
}
// 用于远征匹配
public static async findByCeScale(min: number, max: number) {
const result: RoleType[] = await RoleModel.find({ topLineupCe: { $lte: max, $gte: min } })
.populate('topLineup.hero')
.sort({ updatedAt: -1 }).limit(100).lean({ getters: true, virtuals: true });
return result;
}
}
export const RoleModel = getModelForClass(Role);

View File

@@ -6,17 +6,23 @@ import { COUNTER } from '../consts';
@index({ id: 1 })
@index({ seasonNum: 1 })
export default class PVPConfig extends BaseModel {
@prop({ required: true, default: 1 })
id: number;
@prop({ required: true })
warId: number; // 地图
@prop({ required: true, default: 1 })
seasonNum: number; // 赛季
@prop({ required: true })
seasonEndTime: number; //赛季结束的时间
@prop({ required: false })
settleGuildWeeklyTime: number;
@prop({ required: true })
seasonStartTime: number; // 赛季开始时间
@prop({ required: true })
seasonRewardTime: number; // 结算奖励时间
@prop({ required: true })
seasonEndTime: number; // 赛季结束的时间
@prop({ required: true })
hasSettleReward: boolean; // 赛季结束的时间
public static async findCurPVPConfig() {
let seasonNum = await CounterModel.getCounter(COUNTER.PVP_SEASON_NUM);
const result: PVPConfigType = await PVPConfigModel.findOne({ seasonNum }).lean(true);
@@ -28,13 +34,19 @@ export default class PVPConfig extends BaseModel {
return result;
}
public static async createPVPConfig(seasonNum: number, seasonEndTime: number, warId: number) {
const result: PVPConfigType = await PVPConfigModel.findOneAndUpdate({ seasonNum }, { warId, seasonEndTime }, { upsert: true, new: true }).lean(true);
public static async createPVPConfig(seasonNum: number, seasonStartTime: number, seasonRewardTime: number, seasonEndTime: number) {
const result: PVPConfigType = await PVPConfigModel.findOneAndUpdate({ seasonNum }, { seasonStartTime, seasonRewardTime, seasonEndTime, hasSettleReward: false }, { upsert: true, new: true }).lean(true);
return result;
}
public static async updatePVPConfig(seasonNum: number, update: { warId?: number, settleGuildWeeklyTime?: number }) {
const result: PVPConfigType = await PVPConfigModel.findOneAndUpdate({ seasonNum }, update, { new: true }).lean(true);
public static async setReward(seasonNum: number) {
const result: PVPConfigType = await PVPConfigModel.findOneAndUpdate({ seasonNum }, { hasSettleReward: true }, { new: true }).lean(true);
return result;
}
public static async setCurPvpConfig(update: PVPConfigUpdate) {
let seasonNum = await CounterModel.getCounter(COUNTER.PVP_SEASON_NUM);
const result: PVPConfigType = await PVPConfigModel.findOneAndUpdate({ seasonNum }, update).lean(true);
return result;
}
}
@@ -43,4 +55,5 @@ export const PVPConfigModel = getModelForClass(PVPConfig);
export interface PVPConfigType extends Pick<DocumentType<PVPConfig>, keyof PVPConfig> {
id: number;
};
};
export type PVPConfigUpdate = Partial<PVPConfigType>; // 将所有字段变成可选项