feat(gvg): 优化血量继承、实时刷新、遗迹天数、系统播报 6267076fc

This commit is contained in:
luying
2023-10-20 09:55:08 +08:00
parent c2ad7145c1
commit d9f911f520
14 changed files with 371 additions and 98 deletions

View File

@@ -201,7 +201,7 @@ export const PUSH_ROUTE = {
GVG_TASK_UPDATE: 'onGVGTaskUpdate', // GVG任务更新
GVG_TEAM_ATTACKED: 'onTeamAttacked', // 当队伍受到攻击
GVG_MY_TEAM_ATTACKED: 'onMyTeamAttacked', // 当队伍受到攻击
GVG_AREA_SPINE_CHANGE: 'onAreaSpinesChange', // 可见区域内spine的变动每隔5秒会下发
// GVG_AREA_SPINE_CHANGE: 'onAreaSpinesChange', // 可见区域内spine的变动每隔5秒会下发
GVG_AREA_POINT_CHANGE: 'onMyAreaPointChange', // 积分点上的驻守人变更
GVG_PLAYER_AREA_ADD: 'onPlayerAddToArea', // 积分点上的驻守人变更
GVG_PLAYER_LEAVE_AREA: 'onPlayerLeaveArea', // 积分点上的驻守人变更
@@ -216,4 +216,8 @@ export const PUSH_ROUTE = {
ROUGE_CHALLENGE_UPDATE: 'onRougeChallengeUpdate', //更新学宫挑战进度
ROUGE_PASSIVE_CARD_UP_LV:'onRougePassiveCardUpLv', // 升级特性卡
LADDER_OR_GVG_ICON_SHOW: 'onLadderOrGvgIconShow', //名将擂台icon提示
GVG_WIN_STREAK: 'onGVGWinStreak', // 连胜次数
GVG_SPINE_AREA_ADD: 'onSpineAddArea', // 积分点上的驻守人变更
GVG_SPINE_AREA_LEAVE: 'onSpineLeaveArea', // 积分点上的驻守人变更
GVG_SPINE_POINT_CHANGE: 'onSpinePointChange', // 积分点上的驻守人变更
}

View File

@@ -273,31 +273,51 @@ export default class GVGTeam extends BaseModel {
}
// 结算挑战方
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();
public static async battleEndAttack(teamCode: string, hpInc: number, rebirthAreaId: number, reviveCd: number, lineupParam?: { isAllDead: boolean, newLineup: GVGHeroInfo[] }) {
let team: GVGTeamType;
if (lineupParam) {
if (lineupParam.isAllDead) {
team = await GVGTeamModel.findOneAndUpdate({ teamCode }, { $set: { durability: 0, lockTime: 0, lockTeamCode: '', lineup: lineupParam.newLineup } }, { new: true }).lean();
} else {
team = await GVGTeamModel.findOneAndUpdate({ teamCode }, { $inc: { durability: hpInc }, $set: { lockTime: 0, lockTeamCode: '', lineup: lineupParam.newLineup } }, { new: true }).lean();
}
} else {
team = 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 = await GVGTeamModel.teamBreak(teamCode, team.isRobot, team.maxDurability, rebirthAreaId, team.areaId, reviveCd, team.lineup);
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();
public static async battleEndDefense(teamCode: string, hpInc: number, rebirthAreaId: number, defenseCd: number, reviveCd: number, lineupParam?: { isAllDead: boolean, newLineup: GVGHeroInfo[] }) {
let team: GVGTeamType;
if (lineupParam) {
if (lineupParam.isAllDead) {
team = await GVGTeamModel.findOneAndUpdate({ teamCode }, { $set: { defenseTime: nowSeconds() + defenseCd, lockTime: 0, lockTeamCode: '', lineup: lineupParam.newLineup, durability: 0 } }, { new: true }).lean();
} else {
team = await GVGTeamModel.findOneAndUpdate({ teamCode }, { $set: { defenseTime: nowSeconds() + defenseCd, lockTime: 0, lockTeamCode: '', lineup: lineupParam.newLineup }, $inc: { durability: hpInc } }, { new: true }).lean();
}
} else {
team = 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 = await GVGTeamModel.teamBreak(teamCode, team.isRobot, team.maxDurability, rebirthAreaId, team.areaId, reviveCd, team.lineup);
team.originPointId = originPointId;
}
return team;
}
// 队伍进入修整器
public static async teamBreak(teamCode: string, isRobot: boolean, maxDurability: number, areaId: number, fromAreaId: number, reviveCd: number) {
public static async teamBreak(teamCode: string, isRobot: boolean, maxDurability: number, areaId: number, fromAreaId: number, reviveCd: number, lineup: GVGHeroInfo[]) {
if(!isRobot) {
const team: GVGTeamType = await GVGTeamModel.findOneAndUpdate({ teamCode }, { $set: { restartTime: nowSeconds() + reviveCd, stopMoveTime: nowSeconds(), areaId, fromAreaId, durability: maxDurability, pointId: 0 } }, { new: true }).lean();
lineup.forEach(hero => { hero.hp = 'max'; hero.others = ''; })
const team: GVGTeamType = await GVGTeamModel.findOneAndUpdate({ teamCode }, { $set: { restartTime: nowSeconds() + reviveCd, stopMoveTime: nowSeconds(), areaId, fromAreaId, durability: maxDurability, pointId: 0, lineup } }, { new: true }).lean();
team.curTeamBreak = true;
return team;
} else {
@@ -327,7 +347,10 @@ export default class GVGTeam extends BaseModel {
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();
let lineup = team.lineup||[];
lineup.forEach(hero => { hero.hp = 'max'; hero.others = ''; })
team = await GVGTeamModel.findOneAndUpdate({ teamCode }, { $set: { fromAreaId: team.areaId, areaId: rebirthAreaId, pointId: 0, durability: team.maxDurability, restartTime: nowSeconds() + reviveCd, lineup } }, { new: true }).lean();
team.originPointId = originPointId;
team.curTeamBreak = true;
}

View File

@@ -82,6 +82,9 @@ export default class GVGUserData extends BaseModel {
@prop({ required: false })
reviveCnt: number; // 城池id
@prop({ required: false })
winStreak: number; // 连胜
public static async findByRole(configId: number, leagueCode: string, roleId: string) {
const result: GVGUserDataType = await GVGUserDataModel.findOneAndUpdate({ configId, leagueCode, roleId }, {}, { new: true, upsert: true}).lean();
return result;
@@ -145,6 +148,16 @@ export default class GVGUserData extends BaseModel {
const result: GVGUserDataType = await GVGUserDataModel.findOneAndUpdate({ configId, leagueCode, roleId, hasCheckBox: { $exists: false }}, { $set: { hasCheckBox: true } }).lean();
return result;
}
public static async setWinStreak(configId: number, leagueCode: string, roleId: string, isSuccess: boolean) {
if (isSuccess) {
const result: GVGUserDataType = await GVGUserDataModel.findOneAndUpdate({ configId, leagueCode, roleId }, { $inc: { winStreak: 1 } }, { new: true }).lean();
return result;
} else {
const result: GVGUserDataType = await GVGUserDataModel.findOneAndUpdate({ configId, leagueCode, roleId }, { $set: { winStreak: 0 } }, { new: true }).lean();
return result;
}
}
}
export const GVGUserDataModel = getModelForClass(GVGUserData);

View File

@@ -168,6 +168,12 @@ export class GVGHeroInfo extends PvpHeroInfo {
outIndex?: number = 0; // 程序将信息存入数组顺序
@prop({ required: false })
dataId?: number = 0; // 对应出兵表dataId
@prop({ required: false })
hp?: number|"max" = "max"; // 当前血量
@prop({ required: false })
maxHp?: number|"max" = "max"; // 当前血量
@prop({ required: false })
others?: string = ''; // 当前血量
setDataId(dataId: number, order: number) {
this.dataId = dataId;

View File

@@ -16,6 +16,7 @@ import { GVGTeamMem } from "../battleField/gvgBattle";
import { GVGTeamType } from "../../db/GVGTeam";
import { GVGRoleDataType } from "../../db/GVGRoleData";
import { Combo } from "../battleField/pvp";
import { GVGHeroInfo, PvpEnemies } from "../dbGeneral";
class LeagueLeaderInfo {
name: string; // 盟主名
@@ -653,6 +654,41 @@ export class GVGCityMapInfo {
}
}
export class GVGTeamSpineInfo {
spine: number = 0;
roleId: string = '';
roleName: string = '';
serverName: string = '';
startMoveTime: number = 0;
stopMoveTime: number = 0;
moveCdTime: number = 0;
isMoving: boolean = false;
pointId: number = 0;
areaId: number = 0;
fromAreaId: number = 0;
teamCode: string = '';
leagueCode: string = '';
leagueName: string = '';
constructor(obj: GVGTeamType, serverName: string) {
this.spine = obj.spine;
this.roleId = obj.roleId;
this.roleName = obj.roleName;
this.serverName = serverName;
this.startMoveTime = obj.startMoveTime;
this.stopMoveTime = obj.stopMoveTime;
this.moveCdTime = obj.moveCdTime;
this.isMoving = nowSeconds() < this.stopMoveTime;
this.areaId = obj.areaId;
this.pointId = obj.pointId;
this.fromAreaId = obj.fromAreaId;
this.teamCode = obj.teamCode;
this.leagueCode = obj.leagueCode;
this.leagueName = obj.leagueName;
}
}
export class GVGTeamSpineInMap {
spine: number = 0;
roleId: string = '';
@@ -674,7 +710,7 @@ export class GVGTeamSpineInMap {
this.spine = obj.spine;
this.roleId = obj.roleId;
this.roleName = obj.roleName;
if(obj.serverId) this.serverName = serverNames[obj.serverId];
if (obj.serverId) this.serverName = serverNames[obj.serverId];
this.startMoveTime = obj.startMoveTime;
this.stopMoveTime = obj.stopMoveTime;
this.moveCdTime = obj.moveCdTime;
@@ -711,8 +747,10 @@ export class GVGTeamInList {
restartTime: number;
defenseTime: number;
curTeamBreak: boolean;
hpPercent: number;
lineup: GVGLineupInfo[];
constructor(team: GVGTeamType) {
constructor(team: GVGTeamType, needLineup = false) {
if(!team) return;
this.areaId = team.areaId;
this.pointId = team.pointId;
@@ -730,6 +768,22 @@ export class GVGTeamInList {
this.restartTime = team.restartTime;
this.defenseTime = team.defenseTime;
this.curTeamBreak = !!team.curTeamBreak;
this.calHpPercent(team.isRobot, team.lineup);
if(needLineup && team.lineup)
this.lineup = team.lineup.map(cur => new GVGLineupInfo(cur));
}
calHpPercent(isRobot: boolean, lineup: GVGHeroInfo[]) {
if (isRobot) {
this.hpPercent = 100;
return
}
let hpSum = 0, hpNum = 0;
for (let { hp = 'max', maxHp = 'max' } of lineup) {
hpSum += ((hp == 'max'|| maxHp == 'max')? 100: (hp / maxHp * 100));
hpNum ++;
}
this.hpPercent = Math.ceil(hpSum / hpNum);
}
}
@@ -766,18 +820,35 @@ export class GVGTeamInListOnPoint extends GVGTeamInList {
}
}
class GVGLineupInfo {
actorId: number; // 武将
dataId: number; // 出兵表上的位置
order: number; // 行动
subHid: number;
quality: number; // 品质
hp: number|"max" = 'max'; // 血量, 当max时表示满血量由客户端来算他的血条
maxHp: number|"max" = 'max'; // 血量, 当max时表示满血量由客户端来算他的血条
others: string = ''; // 护盾相关
constructor(info: GVGHeroInfo) {
this.actorId = info.actorId;
this.dataId = info.dataId;
this.order = info.outIndex;
this.subHid = info.subActorId;
this.quality = info.quality;
this.hp = info.hp == undefined? 'max': info.hp;
this.maxHp = info.maxHp == undefined? 'max': info.maxHp;
this.others = info.others||'';
}
}
export class MyTeamSimpleInfo {
teamCode: string; // 队伍唯一id
index: number; // 队伍位置
head: number; // 保存头像
frame: number; // 保存相框
spine: number; // 保存形象
lineup: {
actorId: number; // 武将
dataId: number; // 出兵表上的位置
order: number; // 行动
subHid: number;
}[];
lineup: GVGLineupInfo[];
combo: Combo[];
hasConfirm: boolean;
@@ -787,7 +858,7 @@ export class MyTeamSimpleInfo {
this.head = team.head;
this.frame = team.frame;
this.spine = team.spine;
this.lineup = team.lineup.map(({ actorId, dataId, outIndex, subActorId }) => ({ actorId, dataId, order: outIndex, subHid: subActorId }));
this.lineup = team.lineup.map(cur => new GVGLineupInfo(cur));
this.hasConfirm = team.confirmConfigId == configId;
this.combo = team.combo;
}
@@ -802,11 +873,7 @@ export class MyTeamInfo {
spine: number; // 保存形象
title: number; // 爵位
lv: number;
lineup: {
actorId: number; // 武将
dataId: number; // 出兵表上的位置
order: number; // 行动
}[];
lineup: GVGLineupInfo[];
lineupCe: number;
durability: number; // 耐久
maxDurability: number; // 最大耐久
@@ -827,7 +894,7 @@ export class MyTeamInfo {
this.spine = team.spine;
this.title = team.title;
this.lv = team.lv;
if(team.lineup) this.lineup = team.lineup.map(({ actorId, dataId, outIndex }) => ({ actorId, dataId, order: outIndex }));
if(team.lineup) this.lineup = team.lineup.map(cur => new GVGLineupInfo(cur));
this.durability = team.durability;
this.maxDurability = team.maxDurability;
this.restartTime = team.restartTime;
@@ -841,6 +908,26 @@ export class MyTeamInfo {
}
}
export class GVGWinStreakInfo {
roleId: string;
roleName: string;
head: number;
frame: number;
lv: number;
leagueName: string;
winStreak: number;
constructor(team: GVGTeamType, winStreak: number) {
this.roleId = team.roleId;
this.roleName = team.roleName;
this.head = team.head;
this.frame = team.frame;
this.lv = team.lv;
this.leagueName = team.leagueName;
this.winStreak = winStreak;
}
}
// 情报
// 联军排名
export class LeagueRankInInfoPage {
@@ -890,4 +977,16 @@ export class GuardCityInfoPage {
}
this.leagueCe = ce;
}
}
export class GVGEnemies extends PvpEnemies {
hp: number|'max' = 'max';
others: string = '';
// score: 这个武将的军功
constructor(warjson: DicWarJson, heroInfo: GVGHeroInfo) {
super(warjson, heroInfo);
if(heroInfo.hp != undefined) this.hp = heroInfo.hp;
if(heroInfo.others != undefined) this.others = heroInfo.others;
}
}

View File

@@ -11,6 +11,8 @@ export interface DicGVGVestigeType {
readonly mapType: number[];
// 位置
readonly position: string;
// 哪天
readonly openday: number[];
}
export const dicGVGVestigeByType = new Map<number, DicGVGVestigeType[]>(); // 地图类型 => 遗迹id
@@ -21,6 +23,7 @@ export function loadGVGVestigeType() {
let arr = readFileAndParse(FILENAME.DIC_GVG_VESTIGE_TYPE);
arr.forEach(o => {
o.mapType = parseNumberList(o.mapType);
o.openday = parseNumberList(o.openday);
for(let type of o.mapType) {
if(!dicGVGVestigeByType.has(type)) {
dicGVGVestigeByType.set(type, []);

View File

@@ -45,6 +45,13 @@ export interface pvpEndParamInter {
subHid?: number;
}
export interface gvgEndParamInter {
actorId: number;
hp: number;
maxHp: number;
others: string;
}
export interface RougeDamageInter {
charaCode: string;
hp: number;

View File

@@ -11,7 +11,8 @@
"additionValue": "2&",
"content": "枪兵",
"seid": 51102,
"position": "&"
"position": "&",
"openday": "1&2&3&4&5&6&7"
},
{
"id": 2,
@@ -25,7 +26,8 @@
"additionValue": "6&",
"content": "策士",
"seid": 51106,
"position": "&"
"position": "&",
"openday": "1&2&3&4&5&6&7"
},
{
"id": 3,
@@ -39,7 +41,8 @@
"additionValue": "5&",
"content": "游侠",
"seid": 51105,
"position": "&"
"position": "&",
"openday": "1&2&3&4&5&6&7"
},
{
"id": 4,
@@ -53,7 +56,8 @@
"additionValue": "4&",
"content": "弓兵",
"seid": 51104,
"position": "&"
"position": "&",
"openday": "1&2&3&4&5&6&7"
},
{
"id": 5,
@@ -67,7 +71,8 @@
"additionValue": "3&",
"content": "骑兵",
"seid": 51103,
"position": "&"
"position": "&",
"openday": "1&2&3&4&5&6&7"
},
{
"id": 6,
@@ -81,7 +86,8 @@
"additionValue": "1&",
"content": "步兵",
"seid": 51101,
"position": "&"
"position": "&",
"openday": "1&2&3&4&5&6&7"
},
{
"id": 7,
@@ -95,7 +101,8 @@
"additionValue": "1&",
"content": "魏国",
"seid": 51107,
"position": "&"
"position": "&",
"openday": "1&2&3&4&5&6&7"
},
{
"id": 8,
@@ -109,7 +116,8 @@
"additionValue": "2&",
"content": "吴国",
"seid": 51109,
"position": "&"
"position": "&",
"openday": "1&2&3&4&5&6&7"
},
{
"id": 9,
@@ -123,7 +131,8 @@
"additionValue": "3&",
"content": "蜀国",
"seid": 51108,
"position": "&"
"position": "&",
"openday": "1&2&3&4&5&6&7"
},
{
"id": 10,
@@ -137,7 +146,8 @@
"additionValue": "4&",
"content": "群雄",
"seid": 51110,
"position": "&"
"position": "&",
"openday": "1&2&3&4&5&6&7"
},
{
"id": 11,
@@ -151,6 +161,7 @@
"additionValue": "2&",
"content": "女性",
"seid": 51111,
"position": "&"
"position": "&",
"openday": "1&2&3&4&5&6&7"
}
]