Files
ZYZ/shared/db/GVGTeam.ts

367 lines
16 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
// GVGTeam 数据库表,存储 GVG 队伍信息
import BaseModel from "./BaseModel";
import { index, getModelForClass, prop, DocumentType } from '@typegoose/typegoose';
import { genCode } from "../pubUtils/util";
import { nowSeconds } from "../pubUtils/timeUtil";
import { EXTERIOR, GVG } from "../pubUtils/dicParam";
import { DicGVGAreaPoint } from "../pubUtils/dictionary/DicGVGAreaPoint";
import { InitTeamParam, SaveTeamUpdateParam } from "../domain/gvgField/gvgDb";
import { GVGHeroInfo } from "../domain/dbGeneral";
import { GVG_BATTLE_PRE_TIME, GVG_CATAPULT, GVG_ROBOT } from "../consts";
@index({ roleId: 1, index: 1 })
@index({ teamCode: 1 })
@index({ cityId: 1, leagueId: 1 })
export default class GVGTeam extends BaseModel {
@prop({ required: true })
configId: number; // 赛季每赛季在enterCity的时候检测如果不一样就更新durability那些东西
@prop({ required: true })
confirmConfigId: number; // 是否确认过
@prop({ required: true })
roleId: string; // 玩家id
@prop({ required: true })
roleName: string; // 玩家名
@prop({ required: true })
serverId: number; // 小区id
@prop({ required: true })
lv: number; // 玩家等级
@prop({ required: true })
title: number; // 爵位
@prop({ required: true })
teamCode: string; // 玩家队伍唯一标识
@prop({ required: true })
index: number; // 队伍id1-3玩家的第几个队伍
@prop({ required: true })
leagueCode: string; // 联军
@prop({ required: true })
leagueName: string; // 联军
@prop({ required: true })
guildCode: string; // 军团
@prop({ required: false })
areaId: number;
@prop({ required: false })
cityId: number;
@prop({ required: false })
pointId: number;
@prop({ required: true })
head: number; // 头像
@prop({ required: true })
spine: number; // 形象
@prop({ required: true })
frame: number; // 相框
@prop({ required: true, default: 0 })
durability: number; // 耐久
@prop({ required: true, default: 0 })
maxDurability: number; // 耐久
@prop({ required: true, default: 0 })
restartTime: number; // 修整期倒计时
@prop({ required: true, default: 0 })
attackTime: number; // 进攻冷却时间
@prop({ required: true, default: 0 })
lockTime: number; // 正在被进攻中
@prop({ required: true, default: 0 })
lockTeamCode: string; // 正在被这支队伍进攻中
@prop({ required: true, default: 0 })
fromAreaId: number; // 从那个区域移动
@prop({ required: true, default: 0 })
startMoveTime: number;
@prop({ required: true, default: 0 })
moveCdTime: number; // 移动冷却时间
@prop({ required: true, default: 0 })
stopMoveTime: number; // 移动时间
@prop({ required: true, default: 0 })
defenseTime: number; // 防守保护时间
@prop({ required: true, default: 0 })
battleScore: number; // 积分
@prop({ required: true, default: 0 })
settleScore: number; // 积分
@prop({ required: true, type: () => GVGHeroInfo, _id: false })
lineup: GVGHeroInfo[];
@prop({ required: true })
lineupCe: number;
@prop({ required: true })
groupKey: string; // 战区
@prop({ required: true, default: false })
isRobot: boolean; // 是否是机器人
@prop({ required: true, default: false })
captapultAtk: number; // 投石车的攻击力
@prop({ required: true, default: false })
isCatapult: boolean; // 是否是投石车
@prop({ required: true, default: false })
isBroken: boolean; // 机器人是否被击破,如果没有被击破,那么这个位置上就还是机器人,如果被击破了,这个位置就空出给玩家
originPointId: number;
curTeamBreak: boolean;
// 创建队伍
public static async saveTeam(roleId: string, index: number, updateParam: SaveTeamUpdateParam, initParam: InitTeamParam) {
const doc = new GVGTeamModel();
const teamCode = genCode(8);
const insert = Object.assign(doc.toJSON(), { ...initParam, teamCode });
delete insert.lineup;
const team: GVGTeamType | null = await GVGTeamModel.findOneAndUpdate({ roleId, index }, { $setOnInsert: insert, $set: updateParam }, { upsert: true, new: true }).lean();
return team;
}
// 玩家切换城池更新队伍信息
public static async enterCity(teamCode: string, cityId: number, areaId: number, groupKey: string) {
let team: GVGTeamType = await GVGTeamModel.findOneAndUpdate({ teamCode }, { $set: { cityId, areaId, fromAreaId: areaId, pointId: 0, groupKey } }, { new: true }).lean();
return team;
}
// 离开队伍
public static async leaveCity(roleId: string) {
let res = await GVGTeamModel.updateMany({ roleId }, { $set: { cityId: 0, areaId: 0, pointId: 0 } });
return !!res["ok"];
}
// 查找角色队伍数
public static async getTeamCntByRole(roleId: string) {
const teams: GVGTeamType[] = await GVGTeamModel.find({ roleId }).select('teamCode').lean();
return teams.length;
}
// 获取我的编队
public static async findByRole(roleId: string, select = '') {
const teams: GVGTeamType[] = await GVGTeamModel.find({ roleId }).select(select).lean();
return teams;
}
// 获取我的编队
public static async findByRoleAndIndex(roleId: string, index: number, select = '') {
const teams: GVGTeamType = await GVGTeamModel.findOne({ roleId, index }).select(select).lean();
return teams;
}
// 获取某个玩家的某个的编队
public static async findMyTeamByCode(roleId: string, teamCode: string, select = '') {
const res: GVGTeamType = await GVGTeamModel.findOne({ roleId, teamCode }).select(select).lean();
return res;
}
// 获取编队
public static async findByCode(teamCode: string, select = '') {
const res: GVGTeamType = await GVGTeamModel.findOne({ teamCode }).select(select).lean();
return res;
}
// 移动
public static async startMove(teamCode: string, areaId: number, fromAreaId: number) {
const res: GVGTeamType = await GVGTeamModel.findOneAndUpdate({ teamCode }, { $set: { areaId, fromAreaId, stopMoveTime: nowSeconds() + GVG.GVG_DEFAULT_MOVE_CD, moveCdTime: nowSeconds() + GVG.GVG_DEFAULT_MOVE_CD } }, { new: true }).lean();
return res;
}
public static async stopMove(teamCode: string, areaId: number) {
const res: GVGTeamType = await GVGTeamModel.findOneAndUpdate({ teamCode }, { $set: { areaId, stopMoveTime: nowSeconds() } }, { new: true }).lean();
return res;
}
// 查询挑战和防守的编队
public static async findBattleTeams(teamCode: string, oppoTeamCode: string) {
const teams: GVGTeamType[] = await GVGTeamModel.find({ teamCode: { $in: [ teamCode, oppoTeamCode ] } }).lean();
let attackTeam: GVGTeamType = null, defenseTeam: GVGTeamType = null;
for(let team of teams) {
if(team.teamCode == teamCode) attackTeam = team;
if(team.teamCode == oppoTeamCode) defenseTeam = team;
}
return { attackTeam, defenseTeam }
}
// 每赛季初刷新自己的耐久等东西
public static async refreshByConfig(teamCode: string, update: GVGTeamUpdate) {
const team: GVGTeamType = await GVGTeamModel.findOneAndUpdate({ teamCode }, { $set: update }, { new: true }).lean();
return team;
}
public static async findRobotTeams(configId: number, groupKey: string, cityId: number) {
const team: GVGTeamType[] = await GVGTeamModel.find({ configId, groupKey, cityId, isRobot: true }).lean();
return team;
}
// 每赛季初刷新机器人
public static async initRobots(configId: number, groupKey: string, cityId: number, dicPoints: DicGVGAreaPoint[], lv: number) {
let teams: GVGTeamType[] = [];
for(let { pointId, areaId, name, head, spine, ce, durability } of dicPoints) {
let team: GVGTeamType = await GVGTeamModel.findOneAndUpdate({ configId, groupKey, cityId, areaId, pointId }, {
$setOnInsert: {teamCode: genCode(8), maxDurability: durability, roleName: name, head, spine, frame: EXTERIOR.EXTERIOR_FACECASE, title: 1, lineupCe: ce, isRobot: true, lv, isBroken: false, startMoveTime: 0, stopMoveTime: 0, guildCode: '', leagueCode: '', leagueName: '', fromAreaId: areaId, roleId: GVG_ROBOT,
}, $set: { durability }
}, { new: true, upsert: true }).lean();
teams.push(team);
}
return teams;
}
public static async findCatapultTeams(groupKey: string, cityId: number) {
const team: GVGTeamType[] = await GVGTeamModel.find({ groupKey, cityId, isRobot: true, isCatapult: true }).lean();
return team;
}
// 生成投石车
public static async initCatapult(configId: number, groupKey: string, cityId: number, dicPoints: DicGVGAreaPoint[], leagueCode: string, leagueName: string, atk: number, durability: number, lv: number) {
const teams: GVGTeamType[] = [];
for(let { pointId, areaId, name, head, spine, ce } of dicPoints) {
let team: GVGTeamType = await GVGTeamModel.findOneAndUpdate({ configId, groupKey, cityId, areaId, pointId }, {
$setOnInsert: {
teamCode: genCode(8), maxDurability: durability, roleName: name, head, spine, frame: EXTERIOR.EXTERIOR_FACECASE, title: 1, lineupCe: ce, lv, leagueCode, leagueName, captapultAtk: atk,
isRobot: true, isCatapult: true, isBroken: false, startMoveTime: 0, stopMoveTime: 0, guildCode: '', fromAreaId: areaId, roleId: GVG_CATAPULT,
}, $set: { durability }
}, { new: true, upsert: true }).lean();
teams.push(team);
}
return teams
}
// 攻击方攻击cd
public static async battleStartLockAttack(teamCode: string) {
const team: GVGTeamType = await GVGTeamModel.findOneAndUpdate({ teamCode }, { $set: { attackTime: nowSeconds() + GVG.GVG_DEFAULT_ATTACK_CD, lockTime: nowSeconds() + GVG.GVG_DEFAULT_BATTLE_CD + GVG_BATTLE_PRE_TIME, lockTeamCode: teamCode } }, { new: true }).lean();
return team;
}
// 防守方锁定cd
public static async battleStartLockDefense(teamCode: string, lockTeamCode: string) {
const team: GVGTeamType = await GVGTeamModel.findOneAndUpdate({ teamCode }, { $set: { lockTime: nowSeconds() + GVG.GVG_DEFAULT_BATTLE_CD + GVG_BATTLE_PRE_TIME, lockTeamCode } }, { new: true }).lean();
return team;
}
// 占领积分点
public static async settlePoint(teamCode: string, pointId: number) {
const team: GVGTeamType = await GVGTeamModel.findOneAndUpdate({ teamCode }, { $set: { pointId } }, { new: true }).lean();
return team;
}
// 结算挑战方
public static async battleEndAttack(teamCode: string, hpInc: number, rebirthAreaId: number, reviveCd: number) {
let team: GVGTeamType = await GVGTeamModel.findOneAndUpdate({ teamCode }, { $inc: { durability: hpInc }, $set: { lockTime: 0, lockTeamCode: '' } }, { new: true }).lean();
if(team.durability <= 0) {
let originPointId = team.pointId;
team = await GVGTeamModel.teamBreak(teamCode, team.isRobot, team.maxDurability, rebirthAreaId, team.areaId, reviveCd);
team.originPointId = originPointId;
}
return team;
}
// 结算防守方
public static async battleEndDefense(teamCode: string, hpInc: number, rebirthAreaId: number, defenseCd: number, reviveCd: number) {
let team: GVGTeamType = await GVGTeamModel.findOneAndUpdate({ teamCode }, { $set: { defenseTime: nowSeconds() + defenseCd, lockTime: 0, lockTeamCode: '' }, $inc: { durability: hpInc } }, { new: true }).lean();
if(team.durability <= 0) {
let originPointId = team.pointId;
team = await GVGTeamModel.teamBreak(teamCode, team.isRobot, team.maxDurability, rebirthAreaId, team.areaId, reviveCd);
team.originPointId = originPointId;
}
return team;
}
// 队伍进入修整器
public static async teamBreak(teamCode: string, isRobot: boolean, maxDurability: number, areaId: number, fromAreaId: number, reviveCd: number) {
if(!isRobot) {
const team: GVGTeamType = await GVGTeamModel.findOneAndUpdate({ teamCode }, { $set: { restartTime: nowSeconds() + reviveCd, stopMoveTime: nowSeconds(), areaId, fromAreaId, durability: maxDurability, pointId: 0 } }, { new: true }).lean();
team.curTeamBreak = true;
return team;
} else {
const team: GVGTeamType = await GVGTeamModel.findOneAndUpdate({ teamCode }, { $set: { fromAreaId, durability: 0, isBroken: true } }, { new: true }).lean();
team.curTeamBreak = true;
return team;
}
}
public static async findByAreaId(configId: number, groupKey: string, cityId: number, areaId: number) {
const team: GVGTeamType[] = await GVGTeamModel.find({ configId, groupKey, cityId, areaId, stopMoveTime: { $lte: nowSeconds() }, isBroken: false }).lean();
return team;
}
public static async findByConfigId(configId: number) {
const team: GVGTeamType[] = await GVGTeamModel.find({ configId, cityId: { $gt: 0 } }).lean();
return team;
}
// 这个编队上是否已经有队伍了
public static async checkPoint(configId: number, groupKey: string, pointId: number) {
return await GVGTeamModel.exists({ configId, groupKey, pointId, isBroken: false });
}
// 投石车伤害
public static async attackByCatapult(teamCode: string, inc: number, rebirthAreaId: number, reviveCd: number) {
let team: GVGTeamType = await GVGTeamModel.findOneAndUpdate({ teamCode }, { $inc: { durability: -inc } }, { new: true }).lean();
let originPointId = team.pointId;
if(team.durability <= 0) {
team = await GVGTeamModel.findOneAndUpdate({ teamCode }, { $set: { fromAreaId: team.areaId, areaId: rebirthAreaId, pointId: 0, durability: team.maxDurability, restartTime: nowSeconds() + reviveCd } }, { new: true }).lean();
team.originPointId = originPointId;
team.curTeamBreak = true;
}
return team;
}
// 加积分
public static async addScore(teamCode: string, battleScore: number, settleScore: number) {
let team: GVGTeamType = await GVGTeamModel.findOneAndUpdate({ teamCode }, { $inc: { battleScore, settleScore } }, { new: true }).lean();
return team;
}
// 复活
public static async reviveTeam(teamCode: string) {
let team: GVGTeamType = await GVGTeamModel.findOneAndUpdate({ teamCode }, { $set: { restartTime: 0 } }, { new: true }).lean();
return team;
}
public static async updateLeagueName(leagueCode: string, leagueName: string) {
await GVGTeamModel.updateMany({ leagueCode }, { $set: { leagueName } });
}
public static async updateRoleInfo(roleId: string, info: { roleName?: string, lv?: number }) {
await GVGTeamModel.updateMany({ roleId }, { $set: info });
}
public static async checkLockTeam(roleId: string, cityId: number) {
return await GVGTeamModel.exists({ roleId, lockTime: { $gt: nowSeconds() }, cityId: { $ne: cityId } })
}
public static async removeBySub(roleId: string, subHid: number, ce: number) {
await GVGTeamModel.updateMany({ roleId, 'lineup.actorId': subHid }, { $pull: { lineup: { actorId: subHid } }, $inc: { lineupCe: -ce } });
}
}
export const GVGTeamModel = getModelForClass(GVGTeam);
export interface GVGTeamType extends Pick<DocumentType<GVGTeam>, keyof GVGTeam> {
id: number;
};
export type GVGTeamUpdate = Partial<GVGTeamType>; // 将所有字段变成可选项