Files
ZYZ/game-server/app/services/guildBossService.ts
2022-04-09 10:28:21 +08:00

212 lines
8.4 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.
import { BossInstanceType, BossInstanceModel } from '../db/BossInstance';
import { lockData } from '../services/redLockService';
import { findIndex, pick } from 'underscore';
import { sismemberAsync, smembersAsync, saddAsync, delAsync, getRoleOnlineInfo } from '../services/redisService';
import { pinus } from 'pinus';
import { STATUS } from '../consts/statusCode';
import { resResult, shouldRefresh } from '../pubUtils/util';
import { BattleRecordModel } from '../db/BattleRecord';
import { getArmyBossRank, gameData, getAuctionRewardByPoolId } from '../pubUtils/data';
import { sendMailToGuildByContent } from '../services/mailService';
import { MAIL_TYPE, AUCTION_SOURCE, ABI_TYPE, PUSH_ROUTE } from '../consts';
import { GUILD_BOSS_STATUS } from '../consts/constModules/guildConst';
import { genAuction } from './auctionService';
import { GuildModel, GuildType } from '../db/Guild';
import { UserGuildModel, UserGuildType } from '../db/UserGuild';
import { nowSeconds } from '../pubUtils/timeUtil';
import { GUILDACTIVITY } from '../pubUtils/dicParam';
import { ServerRecordModel } from '../db/ServerRecords';
import { sendMessageToGuildWithSuc, sendMessageToUsersWithSuc } from './pushService';
/**
* 获得boss界面
* @param bossInstance
* @param roleId
*/
export async function getBossInstanceInfo(userGuild: UserGuildType, guild?: GuildType) {
let bossInstance = await BossInstanceModel.findBossInstance(userGuild.guildCode);
if(!bossInstance) {
bossInstance = await BossInstanceModel.findLastOverBossInstance(userGuild.guildCode);
}
return await getBossInstanceInfoByData(bossInstance, userGuild, guild);
}
export async function getBossInstanceInfoByData(bossInstance: BossInstanceType, userGuild: UserGuildType, guild?: GuildType) {
if(!guild) guild = await GuildModel.findByCode(userGuild.guildCode, null, 'code refOpenBossTime openBossCnt');
let refObj = await getRefBossCnt(guild, userGuild); // 刷新次数
let status = bossInstance? bossInstance.status: GUILD_BOSS_STATUS.WAIT_OPEN;
if(status == GUILD_BOSS_STATUS.CLEAR) status = GUILD_BOSS_STATUS.WAIT_OPEN;
let bossInfo = null;
if(bossInstance) {
let { code, warId, ranks, bossHp, bossTotalHp, bossLv, encourageCnt } = bossInstance;
let dicBossBase = gameData.bossBaseByBossLv.get(bossLv);
let rankInfo = getRanks(ranks, userGuild.roleId);
bossInfo = { bossCode: code, warId, ...rankInfo, bossHp, bossTotalHp, bossLv, encourageCnt, encourageMax: dicBossBase.encourageSum };
}
return { status, bossInfo, ...refObj }
}
export async function pushBossStatus(guildCode: string, result: any) {
await sendMessageToGuildWithSuc(guildCode, PUSH_ROUTE.GUILD_BOSS_OPEN, pick(result, ['status', 'bossInfo', 'leaderOpenCnt']));
}
async function getRefBossCnt(guild: GuildType, userGuild: UserGuildType) {
let guildCnt = await refreshGuildOfBoss(guild);
let userGuildCnt = await refreshUserGuildOfBoss(userGuild);
return { ...guildCnt, ...userGuildCnt }
}
export async function refreshGuildOfBoss(guild: GuildType, inc: number = 0) {
let { refOpenBossTime, openBossCnt, code } = guild;
if(shouldRefresh(refOpenBossTime, new Date())) {
openBossCnt = 0;
}
if(inc != 0) {
guild = await GuildModel.updateInfo(code, { refOpenBossTime: new Date(), openBossCnt: openBossCnt + inc });
openBossCnt = guild.openBossCnt;
}
return { leaderOpenCnt: openBossCnt }
}
export async function refreshUserGuildOfBoss(userGuild: UserGuildType, incEncourage = 0, incChallenge = 0) {
let { refBossTime, encourageCnt, bossChallengeCnt } = userGuild;
if(shouldRefresh(refBossTime, new Date())) {
encourageCnt = 0, bossChallengeCnt = 0;
}
if(incEncourage != 0 || incChallenge != 0) {
userGuild = await UserGuildModel.updateInfo(userGuild.roleId, { refBossTime: new Date(), encourageCnt: encourageCnt + incEncourage, bossChallengeCnt: bossChallengeCnt + incChallenge }, {});
encourageCnt = userGuild.encourageCnt;
bossChallengeCnt = userGuild.bossChallengeCnt;
}
return { myChallengeCnt: bossChallengeCnt, myEncourageCnt: encourageCnt }
}
export function getRanks(ranks: {roleId: string; score: number; time: number; job: number;}[], roleId: string ) {
ranks.sort(function(a, b) {
return b.score - a.score + a.time - b.time;
});
let myRank = {};
let lastRanks = ranks.map(({roleId: battleRoleId, score }, index) => {
if (roleId == battleRoleId) {
myRank = { roleId, score, rankLv: index + 1 };
}
return {roleId: battleRoleId, score, rankLv: index + 1};
});
return { ranks: lastRanks, myRank }
}
/**
* 获得排名区间奖励
* @param rankLv
*/
export function getArmyBossRankReward(rankLv: number) {
let armybossRankReward = getArmyBossRank();
for (let item of armybossRankReward) {
if (item.rankMin <= rankLv && (rankLv <= item.rankMax || item.rankMax == -1)) {
return item.reward;
}
}
}
/**
* 将玩家加入到正在挑战boss队列中
* @param code
* @param serverId
* @param roleId
*/
export async function addBossInstance(code: string, serverId:number, roleId: string) {
let hisOnlineInfo = await getRoleOnlineInfo(roleId);
if(hisOnlineInfo.isOnline) {
let key = 'serverId_' + serverId + 'guildCode_' + code;
let value = roleId+ '|' + hisOnlineInfo.sid;
await saddAsync(key, [value]);
}
}
/**
* 给当前正在挑战的玩家下发血量同步信息
* @param code
* @param serverId
* @param bossHp
* @param isDelKey
*/
export async function pushBossHpMessage(code: string, serverId:number, bossHp:number, isDelKey?: boolean ) {
let key = 'serverId_' + serverId + 'guildCode_' + code;
let members = await smembersAsync(key);
let uids = members.map(member=>{
let arr = member.split('|');
let uid = arr[0];
let sid = arr[1];
return {uid, sid};
});
sendMessageToUsersWithSuc(PUSH_ROUTE.BOSS_HP_UPDATE, { bossHp }, uids);
if (isDelKey) {
delAsync(key);
}
}
/**
* 检查该玩家当前是否正在挑战boss的队列中
* @param code
* @param serverId
* @param roleId
* @param battleCode
*/
export async function checkBossBattleMemberExists(code: string, serverId:number, roleId: string, battleCode:string ) {
let hisOnlineInfo = await getRoleOnlineInfo(roleId);
let key = 'serverId_' + serverId + 'guildCode_' + code ;
let value = roleId+ '|' + hisOnlineInfo.sid;
let flag = await sismemberAsync(key, value);
if (!flag) {
const battleRecord = await BattleRecordModel.getBattleRecordByCode(battleCode, true);
if(!battleRecord || battleRecord.status != 0 || roleId != battleRecord.roleId) {
return false;
}
await addBossInstance(code, serverId, roleId);
flag = true;
}
return flag;
}
/**
* 成员退出删除boss关排行信息
* @param guildCode
* @param roleId
*/
export async function removeBossRank(guildCode: string, roleId: string) {
await BossInstanceModel.removeBossRank(guildCode, roleId);
}
export async function getBossHp(serverId: number, guildCode: string, dicBossBaseWar: {warId: number, bossHp: number, bossHpRatio: number }) {
let { warId, bossHp: minBossHp, bossHpRatio } = dicBossBaseWar;
let serverRecord = await ServerRecordModel.findTodayData(serverId);
if(!serverRecord) return minBossHp;
let dicWarJson = gameData.warJson.get(warId);
let actorId = gameData.heroIdByWar.get(warId);
let dicBoss = dicWarJson.find(cur => cur.actorId == actorId);
let attribute = dicBoss?.attribute||[];
let hp = attribute.find(cur => cur.id == ABI_TYPE.ABI_HP)?.val||0;
console.log(`getBossHp warId ${warId} hp ${hp}`);
let activeGuilds = serverRecord.activeGuilds||[];
let myGuild = activeGuilds.find(cur => cur.guildCode == guildCode);
let activeCe = 0;
if(myGuild) {
let activePlayers = myGuild.players||[];
activePlayers.sort((a, b) => b.ce - a.ce);
for(let i = 0; i < 10; i++) {
if(!activePlayers[i]) break;
activeCe += activePlayers[i].topLineupCe;
}
}
console.log(`getBossHp activeCe ${activeCe}`);
let B = activeCe/6/GUILDACTIVITY.GATEACTIVITY_ENEMYCE;
console.log(`getBossHp B ${B}`);
let bossBaseHp = B * hp;
let bossHp = Math.floor(bossBaseHp * bossHpRatio);
if(bossHp == 0) return minBossHp;
return bossHp;
}