feat(gvg): 进驻积分点

This commit is contained in:
luying
2023-02-15 15:12:16 +08:00
parent 6815bf316a
commit 4359bfd9cc
10 changed files with 129 additions and 39 deletions

View File

@@ -8,7 +8,7 @@ import { Application, BackendSession, ChannelService, HandlerService } from "pin
import { resResult, genCode } from "../../../pubUtils/util";
import { GVGLeagueModel } from '../../../db/GVGLeague';
import { checkGVGPeriod, getGroupIdOfServer, getGVGConfig, getGVGPeriodData, getGVGServerType } from '../../../services/gvg/gvgService';
import { calBattleScoreByCe, checkAreaIsInCity, checkMoveStatus, getBirthAreaOfCity, getGVGWarId, getOppHeroes, initRobots, teamBreak } from '../../../services/gvg/gvgBattleService';
import { calBattleScoreByCe, checkAreaIsInCity, checkGVGBattleStart, checkMoveStatus, getBirthAreaOfCity, getGVGWarId, getOppHeroes, initRobots, teamBreak } from '../../../services/gvg/gvgBattleService';
import { getGVGBattleData } from '../../../services/gvg/gvgBattleMemory';
import { nowSeconds } from '../../../pubUtils/timeUtil';
import { GVGBattleRecModel } from '../../../db/GVGBattleRec';
@@ -347,24 +347,55 @@ export class GVGBattleHandler {
let teamObj = getGVGBattleData(groupId, serverType);
teamObj.move(teamCode, areaId, 0, team.startMoveTime, team.stopMoveTime);
return resResult(STATUS.SUCCESS, { areaId, cityId, curTeam: team });
return resResult(STATUS.SUCCESS, { areaId, cityId, curTeam: new MyTeamInfo(team) });
}
// 队伍入驻积分点
async teamSettle(msg: { cityId: number, areaId: number, pointId: number, teamCode: string }, session: BackendSession) {
const roleId = session.get('roleId');
const serverId = session.get('serverId');
const { pointId, teamCode } = msg;
const curTeam = await GVGTeamModel.findOneAndUpdate({ teamCode }, { pointId }).lean();
let { configId, period } = getGVGPeriodData();
// if (period != GVG_PERIOD.BATTLE) return resResult(STATUS.GVG_NOT_BATTLE_PERIOD); // TODO 测试临时注
let groupId = await getGroupIdOfServer(serverId);
let serverType = await getGVGServerType(serverId);
let myTeam = await GVGTeamModel.findByTeamCode(roleId, teamCode);
if(!myTeam) return resResult(STATUS.GVG_TEAM_NOT_FOUND);
let dicAreaPoint = gameData.gvgAreaPoint.get(pointId);
if(dicAreaPoint.areaId != myTeam.areaId) return resResult(STATUS.GVG_POINT_NOT_AREA);
let hasOtherTeam = await GVGTeamModel.checkPoint(configId, groupId, serverType, pointId);
if(hasOtherTeam) return resResult(STATUS.GVG_POINT_HAS_SETTLED);
const curTeam = await GVGTeamModel.settlePoint(teamCode, pointId);
let teamObj = getGVGBattleData(groupId, serverType);
teamObj.teamSettle(teamCode, pointId);
return resResult(STATUS.SUCCESS, { curTeam });
teamObj.teamSettle(roleId, teamCode, pointId);
return resResult(STATUS.SUCCESS, { curTeam: new MyTeamInfo(curTeam) });
}
// 队伍离开积分点
async teamLeave(msg: any, session: BackendSession) {
return resResult(STATUS.SUCCESS);
async teamLeave(msg: { cityId: number, areaId: number, pointId: number, teamCode: string }, session: BackendSession) {
const roleId = session.get('roleId');
const serverId = session.get('serverId');
const { pointId, teamCode } = msg;
let groupId = await getGroupIdOfServer(serverId);
let serverType = await getGVGServerType(serverId);
let myTeam = await GVGTeamModel.findByTeamCode(roleId, teamCode);
if(!myTeam) return resResult(STATUS.GVG_TEAM_NOT_FOUND);
let dicAreaPoint = gameData.gvgAreaPoint.get(pointId);
if(dicAreaPoint.areaId != myTeam.areaId) return resResult(STATUS.GVG_POINT_NOT_AREA);
const curTeam = await GVGTeamModel.settlePoint(teamCode, 0);
let teamObj = getGVGBattleData(groupId, serverType);
teamObj.teamSettle(roleId, teamCode, pointId);
return resResult(STATUS.SUCCESS, { curTeam: new MyTeamInfo(curTeam) });
}
// 队伍开始攻击
@@ -375,18 +406,18 @@ export class GVGBattleHandler {
const serverId = session.get('serverId');
const { teamCode, oppoTeamCode } = msg;
let { configId, period } = getGVGPeriodData();
// if (period != GVG_PERIOD.BATTLE) return resResult(STATUS.GVG_NOT_BATTLE_PERIOD); // TODO 测试临时注
let groupId = await getGroupIdOfServer(serverId);
let serverType = await getGVGServerType(serverId);
let { attackTeam, defenseTeam } = await GVGTeamModel.findBattleTeams(teamCode, oppoTeamCode);
if(!attackTeam || !defenseTeam) return resResult(STATUS.GVG_BATTLE_TEAM_INVALID);
if(attackTeam.attackTime > nowSeconds()) return resResult(STATUS.GVG_TEAM_ATTACKING);
if(defenseTeam.defenseTime > nowSeconds() || defenseTeam.lockTime > nowSeconds()) return resResult(STATUS.GVG_TEAM_DEFENSEING);
if(attackTeam.durability <= 0) return resResult(STATUS.GVG_ATTACK_TEAM_BROKEN);
if(defenseTeam.durability <= 0) return resResult(STATUS.GVG_DEFENSE_TEAM_BROKEN);
let checkStatus = checkGVGBattleStart(roleId, attackTeam, defenseTeam);
if(checkStatus.code != 0) return resResult(checkStatus);
const warId = getGVGWarId(defenseTeam);
const battleRecord = await GVGBattleRecModel.createRec(warId, attackTeam, defenseTeam);
const battleRecord = await GVGBattleRecModel.createRec(configId, groupId, serverType, warId, attackTeam, defenseTeam);
attackTeam = await GVGTeamModel.battleStartLockAttack(teamCode);
defenseTeam = await GVGTeamModel.battleStartLockDefense(oppoTeamCode, teamCode);
@@ -396,7 +427,7 @@ export class GVGBattleHandler {
teamObj.setTime(defenseTeam.teamCode, defenseTeam);
let heroes = getOppHeroes(warId, defenseTeam.isRobot, defenseTeam.lineup)
return resResult(STATUS.SUCCESS, { battleCode: battleRecord.battleCode, warId, isRobot: defenseTeam.isRobot, heroes, curTeam: attackTeam });
return resResult(STATUS.SUCCESS, { battleCode: battleRecord.battleCode, warId, isRobot: defenseTeam.isRobot, heroes, curTeam: new MyTeamInfo(attackTeam) });
}
// 队伍停止攻击
@@ -407,8 +438,9 @@ export class GVGBattleHandler {
let { configId, period } = getGVGPeriodData();
const record = await GVGBattleRecModel.findByBattleCode(battleCode);
if(!record) return resResult(STATUS.GVG_BATTLEREC_NOT_FOUND);
if(record.battleEndTime > 0) return resResult(STATUS.GVG_BATTLEREC_HAS_SUMMIT);
let { attackTeam, defenseTeam } = await GVGTeamModel.findBattleTeams(record.attackTeam.teamCode, record.defenseTeam.teamCode);
if(defenseTeam.attackTeam != attackTeam.teamCode) return resResult(STATUS.GVG_LOCK_TIME_OUT)
if(defenseTeam.lockTeamCode != attackTeam.teamCode) return resResult(STATUS.GVG_LOCK_TIME_OUT)
let groupId = await getGroupIdOfServer(serverId);
let serverType = await getGVGServerType(serverId);
@@ -420,8 +452,16 @@ export class GVGBattleHandler {
attackTeam = await GVGTeamModel.battleEndAttack(attackTeam.teamCode, isSuccess? -win: -fail, calBattleScoreByCe(isSuccess, attackTeam.lineupCe));
defenseTeam = await GVGTeamModel.battleEndDefense(defenseTeam.teamCode, isSuccess? -fail: -win, calBattleScoreByCe(isSuccess, defenseTeam.lineupCe));
if(attackTeam.durability <= 0) attackTeam = await teamBreak(city, attackTeam);
if(defenseTeam.durability <= 0) defenseTeam = await teamBreak(city, defenseTeam);
if(attackTeam.durability <= 0) {
attackTeam = await teamBreak(city, attackTeam);
}
if(defenseTeam.durability <= 0) {
if(defenseTeam.pointId > 0 && attackTeam.durability > 0) { // 打败的对手原来占领着一个位置,现在这个位置是你的了
attackTeam = await GVGTeamModel.settlePoint(attackTeam.teamCode, defenseTeam.pointId);
}
defenseTeam = await teamBreak(city, defenseTeam);
}
// 更新内存
let teamObj = getGVGBattleData(groupId, serverType);
teamObj.battleEnd([attackTeam, defenseTeam]);

View File

@@ -75,6 +75,17 @@ class GVGBattleData {
}
}
private setRolePoints(roleId: string, fromPointId: number, pointId: number) {
if(fromPointId > 0 && pointId == 0) { // 被打得撤离积分点
if(this.rolePoints.has(roleId) && this.rolePoints.get(roleId).has(pointId)) {
this.rolePoints.get(roleId).delete(pointId);
}
} else if (fromPointId == 0 && pointId > 0) {
if(!this.rolePoints.has(roleId)) this.rolePoints.set(roleId, new Set());
this.rolePoints.get(roleId).add(pointId);
}
}
public move(teamCode: string, areaId: number, fromAreaId: number, startMoveTime: number, stopMoveTime: number) {
let team = this.teams.get(teamCode);
if(!team) return;
@@ -90,10 +101,12 @@ class GVGBattleData {
}
// 队伍入驻积分点
public teamSettle(teamCode: string, pointId: number) {
let team = this.teams.get(teamCode);
if(!team) return;
team.pointId = pointId;
public teamSettle(roleId: string, teamCode: string, pointId: number) {
let teamMem = this.teams.get(teamCode);
if(!teamMem) return;
let { pointId: fromPointId } = teamMem;
this.setRolePoints(roleId, fromPointId, pointId);
teamMem.pointId = pointId;
}
// 关卡结算
@@ -105,11 +118,7 @@ class GVGBattleData {
}
let { areaId: fromAreaId, pointId: fromPointId } = teamMem;
teamMem.battleEnd(team);
if(fromPointId > 0 && team.pointId == 0) { // 被打得撤离积分点
if(this.rolePoints.has(team.roleId) && this.rolePoints.get(team.roleId).has(team.pointId)) {
this.rolePoints.get(team.roleId).delete(team.pointId);
}
}
this.setRolePoints(team.roleId, fromPointId, team.pointId);
this.setAreaMap(team.teamCode, fromAreaId, team.areaId);
}
}

View File

@@ -67,7 +67,7 @@ export function checkMoveStatus(team: GVGTeamType, cityId: number, areaId: numbe
if(!team) return STATUS.GVG_BATTLE_TEAM_NOT_FOUND;
if(team.cityId != cityId) return STATUS.GVG_BATTLE_IS_NOT_IN_CITY;
if(team.pointId > 0) return STATUS.GVG_BATTLE_TEAM_IS_SELLTED;
if(team.stopMoveTime > 0 && team.stopMoveTime < nowSeconds()) return STATUS.GVG_BATTLE_IS_MOVING;
if(team.stopMoveTime > nowSeconds()) return STATUS.GVG_BATTLE_IS_MOVING;
let dicArea = gameData.gvgArea.get(areaId);
if(!dicArea) return STATUS.DIC_DATA_NOT_FOUND;
if(dicArea.relateArea.indexOf(team.areaId) == -1) return STATUS.GVG_BATTLE_AREA_NOT_RELATE;
@@ -146,3 +146,18 @@ export function getOppHeroes(warId: number, isRobot: boolean, lineup: GVGHeroInf
}
return heroes
}
export function checkGVGBattleStart(roleId: string, attackTeam: GVGTeamType, defenseTeam: GVGTeamType) {
if(!attackTeam || !defenseTeam) return STATUS.GVG_BATTLE_TEAM_INVALID;
if(attackTeam.roleId != roleId) return STATUS.GVG_TEAM_IS_NOT_MINE;
if(attackTeam.leagueCode == defenseTeam.leagueCode) return STATUS.GVG_SAME_LEAGUE_CANNOT_ATTACK;
if(attackTeam.areaId != defenseTeam.areaId) return STATUS.GVG_TEAM_NOT_SAME_AREA;
if(attackTeam.attackTime > nowSeconds()) return STATUS.GVG_TEAM_ATTACKING;
if(defenseTeam.defenseTime > nowSeconds() || defenseTeam.lockTime > nowSeconds()) return STATUS.GVG_TEAM_DEFENSEING;
if(attackTeam.durability <= 0) return STATUS.GVG_ATTACK_TEAM_BROKEN;
if(defenseTeam.durability <= 0) return STATUS.GVG_DEFENSE_TEAM_BROKEN;
return STATUS.SUCCESS;
}

View File

@@ -372,6 +372,12 @@ export const STATUS = {
GVG_LOCK_TIME_OUT: { code: 21410, simStr: '挑战超时' },
GVG_ATTACK_TEAM_BROKEN: { code: 21411, simStr: '挑战队伍已被击破' },
GVG_DEFENSE_TEAM_BROKEN: { code: 21411, simStr: '对方队伍已被击破' },
GVG_BATTLEREC_HAS_SUMMIT: { code: 21412, simStr: '该记录已结算过' },
GVG_TEAM_IS_NOT_MINE: { code: 21413, simStr: '您不可操作此队伍' },
GVG_SAME_LEAGUE_CANNOT_ATTACK: { code: 21414, simStr: '您不可攻击友军' },
GVG_TEAM_NOT_SAME_AREA: { code: 21415, simStr: '对方不在同一个区域内' },
GVG_POINT_HAS_SETTLED: { code: 21416, simStr: '该据点已经有其他队伍驻守' },
GVG_POINT_NOT_AREA: { code: 21417, simStr: '您不在该积分点所在区域' },
// 通用 30000 - 30099
DIC_DATA_NOT_FOUND: { code: 30000, simStr: '数据表未找到' },

View File

@@ -52,6 +52,15 @@ export default class GVGBattleRec extends BaseModel {
@prop({ required: true })
battleCode: string; // 战斗记录
@prop({ required: true })
configId: number; // 赛季
@prop({ required: true })
groupId: number; // 战区
@prop({ required: true })
serverType: number; // 1-单服 2-跨服
@prop({ required: true })
warId: number; // 关卡id
@@ -67,9 +76,9 @@ export default class GVGBattleRec extends BaseModel {
@prop({ required: true })
battleEndTime: number;
public static async createRec(warId: number, attackTeam: GVGTeamType, defenseTeam: GVGTeamType) {
public static async createRec(configId: number, groupId: number, serverType: number, warId: number, attackTeam: GVGTeamType, defenseTeam: GVGTeamType) {
const battleCode = genCode(8);
const result: GVGBattleRecType = await GVGBattleRecModel.findOneAndUpdate({ battleCode }, { $set: { warId, attackTeam, defenseTeam, isSuccess: false } }, { new: true, upsert: true }).lean();
const result: GVGBattleRecType = await GVGBattleRecModel.findOneAndUpdate({ battleCode }, { $set: { configId, groupId, serverType, warId, attackTeam, defenseTeam, isSuccess: false } }, { new: true, upsert: true }).lean();
return result;
}

View File

@@ -74,7 +74,7 @@ export default class GVGTeam extends BaseModel {
lockTime: number; // 正在被进攻中
@prop({ required: true, default: 0 })
attackTeam: string; // 正在被这支队伍进攻中
lockTeamCode: string; // 正在被这支队伍进攻中
@prop({ required: true, default: 0 })
fromAreaId: number; // 从那个区域移动
@@ -207,8 +207,14 @@ export default class GVGTeam extends BaseModel {
}
// 防守方锁定cd
public static async battleStartLockDefense(teamCode: string, attackTeam: string) {
const team: GVGTeamType = await GVGTeamModel.findOneAndUpdate({ teamCode }, { $set: { lockTime: nowSeconds() + GVG.GVG_DEFAULT_ATTACK_CD, attackTeam } }, { new: true }).lean();
public static async battleStartLockDefense(teamCode: string, lockTeamCode: string) {
const team: GVGTeamType = await GVGTeamModel.findOneAndUpdate({ teamCode }, { $set: { lockTime: nowSeconds() + GVG.GVG_DEFAULT_ATTACK_CD, 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;
}
@@ -220,7 +226,7 @@ export default class GVGTeam extends BaseModel {
// 结算防守方
public static async battleEndDefense(teamCode: string, hpInc: number, playerScoreInc: number) {
const team: GVGTeamType = await GVGTeamModel.findOneAndUpdate({ teamCode }, { $set: { defenseTime: nowSeconds() + GVG.GVG_DEFAULT_DEFENSE_CD }, $inc: { durability: hpInc, playerScore: playerScoreInc } }, { new: true }).lean();
const team: GVGTeamType = await GVGTeamModel.findOneAndUpdate({ teamCode }, { $set: { defenseTime: nowSeconds() + GVG.GVG_DEFAULT_DEFENSE_CD, lockTime: 0, lockTeamCode: '' }, $inc: { durability: hpInc, playerScore: playerScoreInc } }, { new: true }).lean();
return team;
}
@@ -245,6 +251,12 @@ export default class GVGTeam extends BaseModel {
return team;
}
// 这个编队上是否已经有队伍了
public static async checkPoint(configId: number, groupId: number, serverType: number, pointId: number) {
return await GVGTeamModel.exists({ configId, groupId, serverType, pointId });
}
}
export const GVGTeamModel = getModelForClass(GVGTeam);

View File

@@ -8,7 +8,7 @@ import { gameData } from "../../pubUtils/data";
import { EXTERIOR, GVG } from "../../pubUtils/dicParam";
import { DicGVGVestige } from "../../pubUtils/dictionary/DicGVGVestige";
import { DicWarJson } from "../../pubUtils/dictionary/DicWarJson";
import { GVGHeroInfo, PvpHeroInfo } from "../dbGeneral";
import { GVGHeroInfo } from "../dbGeneral";
import { LineupHero } from "../roleField/hero";
export class OppPlayerHeroInfo {

View File

@@ -1,5 +1,4 @@
import { prop } from 'typegoose';
import { prop } from '@typegoose/typegoose';
import { ArtifactModelType } from '../../db/Artifact';
import { Connect, EPlace, HeroSkin, HeroType, HeroUpdate, Talent } from '../../db/Hero';
import { JewelSe, JewelType, RandSe } from '../../db/Jewel';

View File

@@ -1219,7 +1219,7 @@ export function getGVGBattleRankReward(type: number, rank: number) {
function parseGVGDurabilityMinus() {
const range = parseNumberList(param.GVG.GVG_DEFAULT_DURABILITY_MINUS);
gameData.gvgBattleDurabilityMinus.win = range[0];
gameData.gvgBattleDurabilityMinus.fail = range[0];
gameData.gvgBattleDurabilityMinus.fail = range[1];
}
function parseGVGTeamDurability() {

View File

@@ -224,7 +224,7 @@ export default class GameController extends Controller {
if (!battleRec) return ctx.body = ctx.service.utils.resResult(STATUS.BATTLE_NOT_FOUND);
let { warType, roleId } = battleRec;
if (warType !== WAR_TYPE.PVP && warType !== WAR_TYPE.LADDER) return ctx.body = ctx.service.utils.resResult(STATUS.BATTLE_RPL_NOT_SUPPORT);
if (warType !== WAR_TYPE.PVP && warType !== WAR_TYPE.LADDER && warType !== WAR_TYPE.GVG_VESTIGE) return ctx.body = ctx.service.utils.resResult(STATUS.BATTLE_RPL_NOT_SUPPORT);
writePath = getLocalRplUrl(roleId, warType, battleCode);
try {