演武台:鼓舞,次数限制,掉落修改,结构修改

This commit is contained in:
luying
2021-09-23 20:17:22 +08:00
parent 15dc3029d9
commit 1501630d47
13 changed files with 403 additions and 281 deletions
@@ -38,6 +38,7 @@ export class GuildRemote {
private GUILD_RACE_EVENT = 'onRaceEventUpdate'; /// 更新木牛流马
private GUILD_POP_UP_ACTIVITY = 'onActivityUpdate'; /// 向军团成员发送弹窗礼包
private GUILD_TRAIN_RESET = 'onGuildTainReset'; // 试炼场重置
private GUILD_BOSS_ENCOURAGE = 'onGuildBossEncourage'; // 鼓舞
/**
* 封装,军团相关channel名: 'guild'+guildCode
@@ -310,4 +311,7 @@ export class GuildRemote {
this.pushMessage(guildCode, this.GUILD_TRAIN_RESET, {});
}
public async pushEncourage(guildCode: string, param: {encourageCnt: number; encourageMax: number; myEncourageCnt: number;}) {
this.pushMessage(guildCode, this.GUILD_BOSS_ENCOURAGE, param);
}
}
@@ -4,18 +4,22 @@ import { STATUS, TASK_TYPE } from '../../../consts';
import { BossInstanceModel } from '../../../db/BossInstance';
import { BattleRecordModel } from '../../../db/BattleRecord';
import { nowSeconds, getZeroPoint } from '../../../pubUtils/timeUtil';
import { getBossInstanceInfo, bossResult, checkBossBattleMemberExists, pushBossHpMessage, getBossInstanceWhenEnd, addBossInstance } from '../../../services/guildBossService';
import { getBossInstanceInfo, checkBossResult, checkBossBattleMemberExists, pushBossHpMessage, addBossInstance, refreshUserGuildOfBoss, refreshGuildOfBoss } from '../../../services/guildBossService';
import { findWhere } from 'underscore'
import { GUILD_STRUCTURE, GUILD_BOSS_STATUS, GUILD_POINT_WAYS } from '../../../consts/constModules/guildConst';
import { DATA_NAME } from '../../../consts/dataName';
import { UserGuildModel } from '../../../db/UserGuild';
import { addActive } from '../../../services/guildService';
import { GuildModel } from '../../../db/Guild';
import { getBossByLv } from '../../../pubUtils/data';
import { gameData, getBossByLv } from '../../../pubUtils/data';
import { lockData } from '../../../services/redLockService';
import { pushGuildBossSucMsg, getGuildChannelSid } from '../../../services/chatService';
import { checkTask } from '../../../services/taskService';
import { guildInter } from '../../../pubUtils/interface';
import { addItems, handleCost } from '../../../services/rewardService';
import * as dicParam from '../../../pubUtils/dicParam';
import { getGoldObject } from '../../../pubUtils/itemUtils';
import { RoleModel } from '../../../db/Role';
export default function (app: Application) {
new HandlerService(app, {});
@@ -26,6 +30,196 @@ export class GuildHandler {
constructor(private app: Application) {
}
// 获得boss关卡
async getBossInstance(msg: guildInter & {}, session: BackendSession) {
const roleId: string = session.get('roleId');
let { myUserGuild: userGuild } = msg;
const { guildCode: code } = userGuild;
let result = await getBossInstanceInfo(code, roleId, userGuild);
return resResult(STATUS.SUCCESS, result);
}
//开启演武场
async openBossInstance(msg: guildInter & {}, session: BackendSession) {
const serverId: number = parseInt(session.get('serverId'));
const { myUserGuild: userGuild } = msg;
const { guildCode: code } = userGuild;
let res: any = await lockData(serverId, DATA_NAME.BOSS_SCRIPT, code);//加锁
if (!!res.err)
return resResult(STATUS.REDLOCK_ERR);
const guild = await GuildModel.findByCode(code, serverId, 'lv structure');
if (!guild) {
res.releaseCallback();
return resResult(STATUS.GUILD_NOT_FOUND);
}
const { structure } = guild;
const curStructure = structure.find(cur => cur.id == GUILD_STRUCTURE.BOSS);
if (!curStructure) {
res.releaseCallback();
return resResult(STATUS.GUILD_STRUCTURE_NOT_FOUND);
}
let bossBase = getBossByLv(curStructure.lv);
let { bossHp, warId } = getRandSingleEelm(bossBase.wars);
let resGuild = await GuildModel.costFund(code, bossBase.opencost);
if (!resGuild) {
res.releaseCallback();
return resResult(STATUS.GUILD_FUND_NOT_ENOUGH);
}
let bossInstance = await BossInstanceModel.findBossInstance(code);
if (!!bossInstance && bossInstance.status == GUILD_BOSS_STATUS.OPEN) {
res.releaseCallback();
return resResult(STATUS.GUILD_SCRIPT_IS_OPENED_TODAY);
}
// 每天开启一次
let { leaderOpenCnt } = await refreshGuildOfBoss(guild);
if(leaderOpenCnt >= dicParam.GUILD_BOSS.GUILD_BOSS_OPEN_COUNT) {
res.releaseCallback();
return resResult(STATUS.GUILD_SCRIPT_IS_OPENED_TODAY);
}
leaderOpenCnt = (await refreshGuildOfBoss(guild, 1)).leaderOpenCnt;
let { myChallengeCnt } = await refreshUserGuildOfBoss(userGuild);
await BossInstanceModel.openBossInstance(code, bossHp, warId, bossBase.bossLevel);
res.releaseCallback();
let result = { warId, ranks: [], myRank: {}, bossHp, status: 3, bossLv: bossBase.bossLevel, leaderOpenCnt };
let chatSid = await getGuildChannelSid(code);
pinus.app.rpc.chat.guildRemote.pushBossOpen.toServer(chatSid, code, warId, bossHp, result.status);
return resResult(STATUS.SUCCESS, {...result, leaderOpenCnt, myChallengeCnt});
}
async battleBoss(msg: guildInter & {}, session: BackendSession) {
const roleId: string = session.get('roleId');
const roleName: string = session.get('roleName');
const { myUserGuild: userGuild } = msg;
const { guildCode } = userGuild;
let bossInstance = await BossInstanceModel.findBossInstance(guildCode);
if (!bossInstance)
return resResult(STATUS.GUILD_SCRIPT_NOT_OPENED);
if (bossInstance.bossHp <= 0)
return resResult(STATUS.GUILD_SCRIPT_IS_COMPLETE);
let myRank = findWhere(bossInstance.ranks, { roleId });
if (!!myRank && myRank.time > getZeroPoint())
return resResult(STATUS.GUILD_SCRIPT_IS_BATTLED);
let { code: bossCode, warId, ranks, bossHp } = bossInstance;
const battleCode = genCode(8); // 关卡唯一值
await BattleRecordModel.updateBattleRecordByCode(battleCode, {
$set: {
roleId, roleName, battleId: warId,
status: 0,
record: { heroes: [], bossInstanceCode: bossCode, bossHp: bossHp },
}
}, true);
const serverId: number = parseInt(session.get('serverId'));
await addBossInstance(guildCode, serverId, roleId);
if (!findWhere(ranks, { roleId })) {
await BossInstanceModel.pushRanks(bossCode, { roleId, score: 0, time: nowSeconds(), job: userGuild.job });
} else {
await BossInstanceModel.updateRank(bossCode, roleId);
}
let { myChallengeCnt } = await refreshUserGuildOfBoss(userGuild, 0, 1);
return resResult(STATUS.SUCCESS, { battleCode, bossCode: bossInstance.code, myChallengeCnt });
}
async action(msg: guildInter & { bossCode: string, damage: number, battleCode: string }, session: BackendSession) {
const { battleCode, damage, myUserGuild: userGuild, bossCode } = msg;
const roleId: string = session.get('roleId');
const roleName: string = session.get('roleName');
const serverId: number = parseInt(session.get('serverId'));
const { guildCode } = userGuild;
let flag = await checkBossBattleMemberExists(guildCode, serverId, roleId, battleCode);
if (!flag) {
return resResult(STATUS.REDLOCK_ERR);
}
//记录伤害
let bossInstance = await BossInstanceModel.updateBossHp(bossCode, damage, roleId);
await BattleRecordModel.incBossDamage(battleCode, damage, bossInstance?.bossHp);
if (!bossInstance || bossInstance.bossHp == 0) {//进入结算
let flag = await checkBossResult(bossCode, guildCode, serverId, DATA_NAME.BOSS_SCRIPT, roleId, damage);
if (!flag) {
return resResult(STATUS.WRONG_PARMS);
}
pushGuildBossSucMsg(roleId, roleName, guildCode, bossInstance);
return resResult(STATUS.SUCCESS, { bossHp: 0 });
} else {
pushBossHpMessage(guildCode, serverId, bossInstance.bossHp);
return resResult(STATUS.SUCCESS, { bossHp: bossInstance.bossHp });
}
}
async battleBossEnd(msg: guildInter & { bossCode: string, battleCode: string }, session: BackendSession) {
const { battleCode, myUserGuild: userGuild, bossCode } = msg;
const roleId = session.get('roleId');
const roleName = session.get('roleName');
const sid = session.get('sid');
const serverId: number = parseInt(session.get('serverId'));
const { guildCode } = userGuild;
let bossInstance = await BossInstanceModel.findByCode(bossCode);
if(!bossInstance) return resResult(STATUS.WRONG_PARMS);
let battleRecord = await BattleRecordModel.updateBattleRecordByCode(battleCode, {
$set: { status: 1 }//战斗结束统一设置成1
}, true);
let { bossDamage } = battleRecord.record; // 伤害奖励
let dicBossBase = gameData.bossBaseByBossLv.get(bossInstance.bossLv);
let reward = dicBossBase.damageReward.map(({id, count}) => {
return { id, count: Math.floor(count * bossDamage * dicBossBase.ratio / 1000 ) }
});
let battleGoods = await addItems(roleId, roleName, sid, reward);
await addActive(roleId, serverId, GUILD_POINT_WAYS.BOSS_WAR);//获得活跃值
// 任务
await checkTask(roleId, sid, TASK_TYPE.GUILD_BOSS, 1, true, {});
let result = await getBossInstanceInfo(guildCode, roleId, userGuild);
return resResult(STATUS.SUCCESS, { ...result, battleGoods });
}
async encourage(msg: guildInter & { count: number }, session: BackendSession) {
const { count, myUserGuild: userGuild } = msg;
const roleId: string = session.get('roleId');
const sid: string = session.get('sid');
if(!count || count < 0) return resResult(STATUS.WRONG_PARMS);
let bossInstance = await BossInstanceModel.findBossInstance(userGuild.guildCode);
if(!bossInstance) return resResult(STATUS.GUILD_SCRIPT_NOT_OPENED);
let { myEncourageCnt } = await refreshUserGuildOfBoss(userGuild);
let costGold = (myEncourageCnt + count - dicParam.GUILD_BOSS.GUILD_BOSS_ENCOURAGE_FREECOUNT) * dicParam.GUILD_BOSS.GUILD_BOSS_ENCOURAGE_COST;
if(costGold < 0) costGold = 0;
let { gold } = await RoleModel.findByRoleId(roleId, 'gold');
if(gold < costGold) return resResult(STATUS.BATTLE_GOLD_NOT_ENOUGH);
let { code, bossLv } = bossInstance;
let dicBossBase = gameData.bossBaseByBossLv.get(bossLv);
bossInstance = await BossInstanceModel.encourage(code, count, dicBossBase.encourageSum); // 军团次数
if(!bossInstance) return resResult(STATUS.GUILD_SCRIPT_ENCOURGE_NOT_ENOUGH);
let consume = getGoldObject(costGold);
let costResult = await handleCost(roleId, sid, [consume]);
if(!costResult) return resResult(STATUS.BATTLE_GOLD_NOT_ENOUGH);
let { myEncourageCnt: myEncourageCntResult } = await refreshUserGuildOfBoss(userGuild, count);
let result = {
encourageCnt: bossInstance.encourageCnt,
encourageMax: dicBossBase.encourageSum,
myEncourageCnt: myEncourageCntResult
}
let chatSid = await getGuildChannelSid(code);
pinus.app.rpc.chat.guildRemote.pushEncourage.toServer(chatSid, code, result);
return resResult(STATUS.SUCCESS, result);
}
async debugAddBattleTimes(msg: {}, session: BackendSession) {
const roleId: string = session.get('roleId');
let userGuild = await UserGuildModel.getMyGuild(roleId, 'guildCode');
@@ -43,140 +237,4 @@ export class GuildHandler {
let { ranks: resRanks } = await BossInstanceModel.updateBossInstance(code, { ranks });
return resResult(STATUS.SUCCESS, { ranks: resRanks });
}
// 获得boss关卡
async getBossInstance(msg: guildInter & {}, session: BackendSession) {
const roleId: string = session.get('roleId');
let { myUserGuild: userGuild } = msg;
const { guildCode: code } = userGuild;
let bossInstance = await BossInstanceModel.findBossInstance(code);
if (!bossInstance) {
return resResult(STATUS.SUCCESS, { status: GUILD_BOSS_STATUS.WAIT_OPEN });//等待团长开启
}
let result = await getBossInstanceInfo(bossInstance, roleId);
return resResult(STATUS.SUCCESS, result);
}
//开启演武场
async openBossInstance(msg: guildInter & {}, session: BackendSession) {
const serverId: number = parseInt(session.get('serverId'));
const { myUserGuild: userGuild } = msg;
const { guildCode: code } = userGuild;
let res: any = await lockData(serverId, DATA_NAME.BOSS_SCRIPT, code);//加锁
if (!!res.err)
return resResult(STATUS.REDLOCK_ERR);
let bossInstance = await BossInstanceModel.findBossInstance(code);
if (!!bossInstance && (bossInstance.bossHp > 0 || bossInstance.startTime >= getZeroPoint())) {
res.releaseCallback();
return resResult(STATUS.GUILD_SCRIPT_IS_OPENED_TODAY);
}
const guild = await GuildModel.findByCode(code, serverId, 'lv structure');
if (!guild) {
res.releaseCallback();
return resResult(STATUS.GUILD_NOT_FOUND);
}
const { structure } = guild;
const curStructure = structure.find(cur => cur.id == GUILD_STRUCTURE.BOSS);
if (!curStructure) {
res.releaseCallback();
return resResult(STATUS.GUILD_STRUCTURE_NOT_FOUND);
}
let bossBase = getBossByLv(curStructure.lv);
let { bossHp, warId } = getRandSingleEelm(bossBase.wars);
let resGuild = await GuildModel.costFund(code, bossBase.opencost);
if (!resGuild) {
res.releaseCallback();
return resResult(STATUS.GUILD_FUND_NOT_ENOUGH);
}
await BossInstanceModel.openBossInstance(code, bossHp, warId, bossBase.bossLevel);
res.releaseCallback();
let result = { warId, ranks: [], myRank: {}, bossHp, status: 3, bossLv: bossBase.bossLevel, isBattled: false };
let chatSid = await getGuildChannelSid(code);
pinus.app.rpc.chat.guildRemote.pushBossOpen.toServer(chatSid, code, warId, bossHp, result.status);
return resResult(STATUS.SUCCESS, result);
}
async battleBoss(msg: guildInter & {}, session: BackendSession) {
const roleId: string = session.get('roleId');
const roleName: string = session.get('roleName');
const { myUserGuild: userGuild } = msg;
const { guildCode: code } = userGuild;
let bossInstance = await BossInstanceModel.findBossInstance(code);
if (!bossInstance)
return resResult(STATUS.GUILD_SCRIPT_NOT_OPENED);
if (bossInstance.bossHp <= 0)
return resResult(STATUS.GUILD_SCRIPT_IS_COMPLETE);
let myRank = findWhere(bossInstance.ranks, { roleId });
if (!!myRank && myRank.time > getZeroPoint())
return resResult(STATUS.GUILD_SCRIPT_IS_BATTLED);
let { warId, ranks } = bossInstance;
const battleCode = genCode(8); // 关卡唯一值
await BattleRecordModel.updateBattleRecordByCode(battleCode, {
$set: {
roleId, roleName, battleId: warId,
status: 0,
record: { heroes: [], recordNum: bossInstance.num, bossHp: bossInstance.bossHp },
}
}, true);
const serverId: number = parseInt(session.get('serverId'));
await addBossInstance(code, serverId, roleId);
if (!findWhere(ranks, { roleId })) {
await BossInstanceModel.pushRanks(code, { roleId, score: 0, time: nowSeconds(), job: userGuild.job });
} else {
await BossInstanceModel.updateRank(code, roleId);
}
return resResult(STATUS.SUCCESS, { battleCode });
}
async action(msg: guildInter & { damage: number, battleCode: string }, session: BackendSession) {
const { battleCode, damage, myUserGuild: userGuild } = msg;
const roleId: string = session.get('roleId');
const roleName: string = session.get('roleName');
const serverId: number = parseInt(session.get('serverId'));
const { guildCode: code } = userGuild;
let flag = await checkBossBattleMemberExists(code, serverId, roleId, battleCode);
if (!flag) {
return resResult(STATUS.REDLOCK_ERR);
}
//记录伤害
let bossInstance = await BossInstanceModel.updateBossHp(code, damage, roleId);
if (!bossInstance || bossInstance.bossHp == 0) {//进入结算
let flag = await bossResult(code, serverId, DATA_NAME.BOSS_SCRIPT, roleId, damage);
if (!flag) {
return resResult(STATUS.WRONG_PARMS);
}
pushGuildBossSucMsg(roleId, roleName, code, bossInstance);
return resResult(STATUS.SUCCESS, { bossHp: 0 });
} else {
pushBossHpMessage(code, serverId, bossInstance.bossHp);
return resResult(STATUS.SUCCESS, { bossHp: bossInstance.bossHp });
}
}
async battleBossEnd(msg: guildInter & { battleCode: string }, session: BackendSession) {
const { battleCode, myUserGuild: userGuild } = msg;
const roleId = session.get('roleId');
const sid = session.get('sid');
const serverId: number = parseInt(session.get('serverId'));
const { guildCode: code } = userGuild;
const battleRecord = await BattleRecordModel.getBattleRecordByCode(battleCode, true);
if (!battleRecord || battleRecord.status != 0 || roleId != battleRecord.roleId) {
return resResult(STATUS.WRONG_PARMS);
}
await BattleRecordModel.updateBattleRecordByCode(battleCode, {
$set: { status: 1 }//战斗结束统一设置成1
}, true);
let bossInstance = await BossInstanceModel.findBossInstance(code);
let result = await getBossInstanceWhenEnd(bossInstance, roleId, battleRecord.record.recordNum);
await addActive(roleId, serverId, GUILD_POINT_WAYS.BOSS_WAR);//获得活跃值
// 任务
await checkTask(roleId, sid, TASK_TYPE.GUILD_BOSS, 1, true, {});
return resResult(STATUS.SUCCESS, result);
}
}
@@ -59,7 +59,7 @@ export class GuildRefineHandler {
for (let scienceTree of scienceTrees) {
if (scienceTree.endTime < nowSeconds()) {
let developConsume = getArmyDevelopConsumeById(scienceTree.id);
if (developConsume.quality && developConsume.levelMax >= pieceInfo.lvLimited && pieceInfo.lvLimited <= developConsume.levelMin) {
if (developConsume.quality && developConsume.levelMax >= pieceInfo.lvLimited && pieceInfo.lvLimited <= developConsume.levelMin) { // TODO 改成星级
findDevelopConsume = developConsume;
break;
}
+1 -4
View File
@@ -117,10 +117,7 @@ async function getModuleData(type: string, data: { role: RoleType, session: Fron
}
case 'boss':
if (hasGuild) {
const bossInstance = await BossInstanceModel.findBossInstance(guild.code);
if (bossInstance) {
return await getBossInstanceInfo(bossInstance, roleId);
}
return await getBossInstanceInfo(guildCode, roleId, userGuild, guild);
}
return null;
case 'wishPool':
+88 -88
View File
@@ -1,94 +1,101 @@
import { BossInstanceType, BossInstanceModel } from '../db/BossInstance';
import { getZeroPoint } from '../pubUtils/timeUtil';
import { lockData } from '../services/redLockService';
import { findIndex } from 'underscore';
import { MailType } from '../db/Mail';
import { sismemberAsync, smembersAsync, saddAsync, delAsync, getRoleOnlineInfo } from '../services/redisService';
import { pinus } from 'pinus';
import { STATUS } from '../consts/statusCode';
import { deepCopy, resResult } from '../pubUtils/util';
import { resResult, shouldRefresh } from '../pubUtils/util';
import { BattleRecordModel } from '../db/BattleRecord';
import { getArmyBossRank, gameData, getAuctionRewardByPoolId } from '../pubUtils/data';
import { sendMailByContent } from '../services/mailService';
import { pushMail } from '../pubUtils/interface';
import { sendMailToGuildByContent } from '../services/mailService';
import { MAIL_TYPE, AUCTION_SOURCE } 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';
/**
* 获得boss界面
* @param bossInstance
* @param roleId
*/
export async function getBossInstanceInfo(bossInstance: BossInstanceType, roleId:string) {
let { warId, ranks, bossHp, bossLv, winWarId, winTime, roleIdRecords, guildCode, startTime, winBossLv } = bossInstance;
export async function getBossInstanceInfo(guildCode: string, roleId:string, userGuild: UserGuildType, guild?: GuildType) {
let bossInstance = await BossInstanceModel.findBossInstance(guildCode);
if(!guild) guild = await GuildModel.findByCode(guildCode, null, 'code refOpenBossTime openBossCnt');
let refObj = await getRefBossCnt(guild, userGuild); // 刷新次数
let showParamObj = await getLastBossInstance(bossInstance, guildCode, roleId);
if(bossInstance) {
let { warId, ranks, bossHp, bossLv, status, encourageCnt } = bossInstance;
let dicBossBase = gameData.bossBaseByBossLv.get(bossLv);
let rankInfo = getRanks(ranks, roleId);
// 此处showParamObj一定要放在最前
return { ...showParamObj, warId, ...rankInfo, bossHp, status, bossLv, encourageCnt, encourageMax: dicBossBase.encourageSum,...refObj };
} else {
return showParamObj;
}
}
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 } = guild;
if(shouldRefresh(refOpenBossTime, new Date())) {
openBossCnt = 0;
}
if(inc != 0) {
guild = await GuildModel.updateInfo(guild.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 result:any = {};
if (!!winWarId && winTime > getZeroPoint() && roleIdRecords.indexOf(roleId) == -1) {
//今日通关过,且首次点开boss界面,提示某某boss已通关
result = { showParam: { winWarId, winBossLv } };
await BossInstanceModel.recordRoleIdWhenCheck(guildCode, roleId);
}
if ( bossHp <= 0 ) {
result = { warId };
if (startTime < getZeroPoint()) {
//今日未开启过boss,等待开启
result.status = GUILD_BOSS_STATUS.WAIT_OPEN;
return result;
} else {
//今日已开启,且boss通关
result.status = GUILD_BOSS_STATUS.OPENED;
return result;
}
}
let isBattled = false;
let myRank = {};
let lastRanks = ranks.map(({roleId: battleRoleId, score, time}, index) => {
let lastRanks = ranks.map(({roleId: battleRoleId, score }, index) => {
if (roleId == battleRoleId) {
myRank = { roleId, score, rankLv: index + 1 };
if (time >= getZeroPoint())
isBattled = true;
}
return {roleId, score, rankLv: index + 1};
});
return { warId, ranks: lastRanks, myRank, bossHp, status: GUILD_BOSS_STATUS.OPEN, isBattled, bossLv };
return { ranks: lastRanks, myRank }
}
/**
* 战斗结束返回
* @param bossInstance
* @param roleId
* @param battleNum
*/
export async function getBossInstanceWhenEnd(bossInstance: BossInstanceType, roleId:string, battleNum:number) {
let { warId, ranks, bossHp, winWarId, guildCode, recordRanks, winNum, bossLv, winBossLv } = bossInstance;
let pushRanks;
let result:any = {};
if (battleNum == winNum) { //检查当前战斗回调是否是上一次战斗的回调,若是返回上次排名的结果
pushRanks = deepCopy(recordRanks);
result = {warId: winWarId, bossHp: 0, bossLv: winBossLv, status: GUILD_BOSS_STATUS.OPEN};
await BossInstanceModel.recordRoleIdWhenCheck(guildCode, roleId);
} else {
pushRanks = deepCopy(ranks);
result = {warId, bossHp, bossLv, status: GUILD_BOSS_STATUS.OPEN};
}
pushRanks.sort(function(a, b) {
return b.score - a.score + a.time - b.time;
});
let isBattled = false;
let myRank = {};
pushRanks.forEach(({roleId: battleRoleId, score, time}, index) => {
if (roleId == battleRoleId) {
myRank = {roleId, score, rankLv: index + 1};
if (time >= getZeroPoint())
isBattled = true;
export async function getLastBossInstance(bossInstance: BossInstanceType, guildCode: string, roleId: string) {
if(bossInstance && bossInstance.status == GUILD_BOSS_STATUS.OPEN) return {}
let lastBossInstance = await BossInstanceModel.findLastOverBossInstance(guildCode);
if(lastBossInstance) {
if(lastBossInstance.roleIdRecords.indexOf(roleId) == -1) {
await BossInstanceModel.recordRoleIdWhenCheck(lastBossInstance.code, roleId);
return { status: GUILD_BOSS_STATUS.CLEAR, showParam: { winWarId: lastBossInstance.warId, winBossLv: lastBossInstance.bossLv } }
} else {
return { status: GUILD_BOSS_STATUS.CLEAR }
}
return {roleId, score, rankLv: index + 1};
});
result.myRank = myRank;
result.ranks = pushRanks;
result.isBattled = isBattled;
return result;
} else {
return { status: GUILD_BOSS_STATUS.WAIT_OPEN }
}
}
/**
@@ -99,47 +106,40 @@ export async function getBossInstanceWhenEnd(bossInstance: BossInstanceType, rol
* @param damage
* @param roleId
*/
export async function bossResult(code: string, serverId: number, dataName: string, roleId: string, damage: number) {
let res:any = await lockData(serverId, dataName, code);//加锁
export async function checkBossResult(bossCode: string, guildCode: string, serverId: number, dataName: string, roleId: string, damage: number) {
let res:any = await lockData(serverId, dataName, guildCode);//加锁
if (!!res.err)
return true;
let {winSettled, ranks, num, warId, bossHp, bossLv, code: bossCode } = await BossInstanceModel.findBossInstance(code);//锁定关卡信息
if (winSettled) {
let {status, ranks, warId, bossHp, bossLv } = await BossInstanceModel.findByCode(bossCode);//锁定关卡信息
if (status == GUILD_BOSS_STATUS.CLEAR) { // 已经被打败了
res.releaseCallback();//解锁
await BossInstanceModel.recordRoleIdWhenCheck(code, roleId);
await BossInstanceModel.recordRoleIdWhenCheck(bossCode, roleId);
return true;
}
let index = findIndex(ranks, {roleId});
if (index == -1) {
if (index == -1) { // 没有调用过battleBoss
res.releaseCallback();//解锁
return false;
}
ranks[index].score += bossHp;
ranks[index].score += bossHp; // 可能会把hp扣成负的,然后排行榜多加了,这里矫正回来
if (bossHp > damage) {//检查造成的伤害是否会让boss死亡
res.releaseCallback();//解锁
return true;
}
let { recordRanks } = await BossInstanceModel.updateBossInstance(code, { bossHp: 0, winSettled: true, ranks, recordRanks: ranks, winNum: num, winWarId: warId, winBossLv: bossLv, roleIdRecords:[roleId]}, );
await pushBossHpMessage(code, serverId, 0, true);
await BossInstanceModel.updateBossInstance(bossCode, { bossHp: 0, status: GUILD_BOSS_STATUS.CLEAR, ranks, roleIdRecords:[roleId]}, );
await pushBossHpMessage(guildCode, serverId, 0, true);
res.releaseCallback();//数据修改解锁
recordRanks.sort(function(a, b) {
return b.score - a.score + a.time - b.time;
});
//下发邮件奖励
recordRanks.forEach(async function({ roleId }, index){
let rankLv = index + 1;
let goods = getArmyBossRankReward(rankLv);
if (!goods || !goods.length)
return;
await sendMailByContent(MAIL_TYPE.GUILD_BOSS_REWARD, roleId, {
params: [JSON.stringify(rankLv)], goods
})
});
// 加入拍卖行
// 击杀奖励&伤害奖励
let dicBossBase = gameData.bossBaseByBossLv.get(bossLv);
let dicWar = gameData.war.get(warId);
await sendMailToGuildByContent(MAIL_TYPE.GUILD_BOSS_REWARD, roleId, {
params: [`${dicWar.gk_name}`], goods: dicBossBase.killReward
});
// 加入拍卖行
if(dicBossBase) {
let rewards = getAuctionRewardByPoolId(dicBossBase.rewards);
await genAuction(code, AUCTION_SOURCE.BOSS, bossCode, serverId, rewards);
await genAuction(guildCode, AUCTION_SOURCE.BOSS, bossCode, serverId, rewards);
}
return true;
+10
View File
@@ -14,6 +14,7 @@ import { GMMailType, GMMailModel } from "../db/GMMail";
import { getGuildChannelSid, getWorldChannelSid } from "./chatChannelService";
import { GMMailRecordModel } from "../db/GMMailRecord";
import { BAG } from "../pubUtils/dicParam";
import { GuildModel, GuildType } from "../db/Guild";
/**
* 获取邮件信息
@@ -57,6 +58,15 @@ export async function sendMailByContent(contentId: MAIL_TYPE, hisRoleId: string,
await f.sendToUsers(GM_MAIL_TYPE.SINGLE, [hisRoleId]);
}
export async function sendMailToGuildByContent(contentId: MAIL_TYPE, guildCode: string, params: { sendName?: string, endTime?: number, params?: string[], goods?: RewardInter[], notPush?: boolean }, guild?: GuildType) {
if(!guild) guild = await GuildModel.findByCode(guildCode);
if(!guild) return false;
let f = new SendMailFun();
f.setWithContentId(contentId, params);
await f.sendToGuild(guildCode, guild.members);
return true;
}
/**
* 发送邮件方法类
*/
+3 -2
View File
@@ -162,6 +162,7 @@ export const GUILD_ROUTE_OPERATE = [
{ route: 'guild.raceActivityHandler.getRace', operate: GUILD_OPERATE.RACE_ACTIVITY, type: GUILD_AUTH_CHECK_TYPE.CHECK_SELF_WITH_SESSION },
{ route: 'guild.raceActivityHandler.useItem', operate: GUILD_OPERATE.RACE_ACTIVITY, type: GUILD_AUTH_CHECK_TYPE.CHECK_SELF_WITH_SESSION },
{ route: 'guild.raceActivityHandler.battleEnd', operate: GUILD_OPERATE.RACE_ACTIVITY, type: GUILD_AUTH_CHECK_TYPE.CHECK_SELF_WITH_SESSION },
{ route: 'guild.guildBossHandler.encou', operate: GUILD_OPERATE.BOSS_BATTLE, type: GUILD_AUTH_CHECK_TYPE.CHECK_SELF },
];
@@ -217,10 +218,10 @@ export enum GUILD_REC_TYPE {
IMPEACH = 11, // 弹劾 roleName roleName
}
//1:等待团长开启,2:今日已开启,且boss通关,3:开启中
//1:等待团长开启,2:boss已通关,3:开启中
export enum GUILD_BOSS_STATUS {
WAIT_OPEN = 1,
OPENED = 2,
CLEAR = 2,
OPEN = 3,//开启中
}
+1
View File
@@ -201,6 +201,7 @@ export const STATUS = {
GUILD_TRAIN_BOX_IS_OVER_TIME: { code: 20971, simStr: '军团宝箱超时' },
GUILD_TRAIN_BOX_INDEX_IS_GOT: { code: 20972, simStr: '该位置试炼宝箱已经领取过,请重新选择' },
GUILD_TRAIN_BOX_IS_GOT: { code: 20973, simStr: '玩家已经领取该试炼宝箱' },
GUILD_SCRIPT_ENCOURGE_NOT_ENOUGH: { code: 20974, simStr: '鼓舞次数达到上限' },
GUILD_LOT_NOT_FOUND: { code: 21001, simStr: '拍品未找到' },
LOT_OFFER_SERIAL: { code: 21002, simStr: '不能连续出价' },
+16 -4
View File
@@ -20,10 +20,6 @@ class Record {
@prop({ required: false })
pos?: number; // pvp位置
@prop({ required: false })
recordNum?: number;
@prop({ required: false })
bossHp?: number;
@prop({ required: false })
trainId?:number;
@prop({ required: false })
trainLv?:number;
@@ -33,6 +29,12 @@ class Record {
guildCode?: string;
@prop({ required: false })
difficulty?: number;
@prop({ required: false })
bossInstanceCode?: string;
@prop({ required: false })
bossHp?: number;
@prop({ required: false })
bossDamage?: number; // boss本造成的伤害
}
export default class BattleRecord extends BaseModel {
@@ -57,6 +59,8 @@ export default class BattleRecord extends BaseModel {
@prop({ required: true, _id: false })
record: Record; // 使用的武将等记录
public static async getBattleRecordByCode(battleCode: string, lean = true) {
const result: BattleRecordType = await BattleRecordModel.findOne({ battleCode }).lean(lean);
return result;
@@ -81,6 +85,14 @@ export default class BattleRecord extends BaseModel {
let result = await BattleRecordModel.deleteMany({ roleId });
return result || {};
}
public static async incBossDamage(battleCode: string, damage: number, bossHp: number) {
if(bossHp < 0) { // 最后一击,被扣到负了
damage += bossHp;
}
let result: BattleRecordType = await BattleRecordModel.findOneAndUpdate({ battleCode }, { $inc: { 'record.bossDamage': damage } }, { new: true }).lean();
return result;
}
}
export const BattleRecordModel = getModelForClass(BattleRecord);
+45 -37
View File
@@ -1,7 +1,8 @@
import BaseModel from './BaseModel';
import { index, getModelForClass, prop, DocumentType } from '@typegoose/typegoose';
import { nowSeconds } from '../pubUtils/timeUtil';
import { getZeroPoint, nowSeconds } from '../pubUtils/timeUtil';
import { genCode } from '../pubUtils/util';
import { GUILD_BOSS_STATUS } from '../consts';
class Rank {
@prop({ required: true })
@@ -34,71 +35,73 @@ export default class BossInstance extends BaseModel {
@prop({ required: true, type: Rank, default:[]})
ranks:Array<Rank>;
@prop({ required: true })
@prop({ required: true, default: nowSeconds })
startTime: number;
@prop({ required: true, default: 0})
num: number; //重置次数
@prop({ required: true, default: 0 })
killTime: number;
@prop({ required: true, default: 0 })
encourageCnt: number; // 鼓舞次数
@prop({ required: true, default:[], type: String, _id: false})
roleIdRecords: Array<string>; //记录提示过胜利boss关的玩家
@prop({ required: true })
winWarId: number; //记录上一次通关的关卡,boss被压制成功后,首次点开boss界面会提示文字,boss已被压制
status: GUILD_BOSS_STATUS; // 状态 1:等待团长开启,2:今日已开启,且boss通关,3:开启中
@prop({ required: true })
winBossLv: number; //记录上一次通关的boss等级
@prop({ required: true })
winTime: number; //记录上一次通关的时间
@prop({ required: true, default: 0})
winNum: number; //记录上一次重置次数
@prop({ required: true, type: Rank, default:[]})
recordRanks:Array<Rank>;//上一场排名信息
@prop({ required: true, default: false })
winSettled: boolean; //胜利是否结算过
public static async findBossInstance(guildCode: string, lean = true) {
const bossInstance: BossInstanceType = await BossInstanceModel.findOne({ guildCode }).lean(lean);
public static async findByCode(code: string) {
const bossInstance: BossInstanceType = await BossInstanceModel.findOne({ code }).lean();
return bossInstance;
}
public static async openBossInstance(guildCode: string, bossHp: number, warId: number, bossLv: number, lean = true) {
public static async findBossInstance(guildCode: string) {
const bossInstance: BossInstanceType = await BossInstanceModel.findOne({ guildCode, status: GUILD_BOSS_STATUS.OPEN }).lean();
return bossInstance;
}
public static async findLastOverBossInstance(guildCode: string) {
let today = getZeroPoint();
const bossInstance: BossInstanceType = await BossInstanceModel.findOne({ guildCode, status: GUILD_BOSS_STATUS.CLEAR, killTime: { $gt: today } }).sort({ _id: -1 }).lean();
return bossInstance;
}
public static async openBossInstance(guildCode: string, bossHp: number, warId: number, bossLv: number) {
let code = genCode(10);
const bossInstance: BossInstanceType = await BossInstanceModel.findOneAndUpdate({ guildCode },{ $setOnInsert: { code }, ranks:[], time: nowSeconds(), bossHp, bossLv, warId, $inc: { num: 1 }}, {new: true, upsert: true}).lean(lean);
let doc = new BossInstanceModel();
let update = Object.assign(doc.toJSON(), { guildCode, bossHp, bossLv, warId });
const bossInstance: BossInstanceType = await BossInstanceModel.findOneAndUpdate({ code },{ $set: update }, {new: true, upsert: true}).lean();
return bossInstance;
}
//记录玩家boss通关后首次查看boss关卡
public static async recordRoleIdWhenCheck(guildCode: string, roleId: string, lean = true) {
const bossInstance: BossInstanceType = await BossInstanceModel.findOneAndUpdate({ guildCode }, { $push:{ roleIdRecords: roleId } }, { new: true }).lean(lean);
public static async recordRoleIdWhenCheck(code: string, roleId: string, lean = true) {
const bossInstance: BossInstanceType = await BossInstanceModel.findOneAndUpdate({ code }, { $push:{ roleIdRecords: roleId } }, { new: true }).lean(lean);
return bossInstance;
}
public static async pushRecordRanks(guildCode: string, recordRank: Rank, lean = true) {
const bossInstance: BossInstanceType = await BossInstanceModel.findOneAndUpdate({ guildCode }, { $push:{ recordRanks: recordRank } }, { new: true }).lean(lean);
public static async pushRecordRanks(code: string, recordRank: Rank, lean = true) {
const bossInstance: BossInstanceType = await BossInstanceModel.findOneAndUpdate({ code }, { $push:{ recordRanks: recordRank } }, { new: true }).lean(lean);
return bossInstance;
}
public static async pushRanks(guildCode: string, rank: Rank, lean = true) {
const bossInstance: BossInstanceType = await BossInstanceModel.findOneAndUpdate({ guildCode }, { $push:{ ranks: rank } }, { new: true }).lean(lean);
public static async pushRanks(code: string, rank: Rank, lean = true) {
const bossInstance: BossInstanceType = await BossInstanceModel.findOneAndUpdate({ code }, { $push:{ ranks: rank } }, { new: true }).lean(lean);
return bossInstance;
}
public static async updateBossInstance(guildCode: string, update:BossInstanceTypeParam, lean = true) {
const bossInstance: BossInstanceType = await BossInstanceModel.findOneAndUpdate({ guildCode }, { $set:update }, { new: true }).lean(lean);
public static async updateBossInstance(code: string, update:BossInstanceTypeParam, lean = true) {
const bossInstance: BossInstanceType = await BossInstanceModel.findOneAndUpdate({ code }, { $set:update }, { new: true }).lean(lean);
return bossInstance;
}
public static async updateBossHp(guildCode: string, hp: number, roleId: string, lean = true) {
const bossInstance: BossInstanceType = await BossInstanceModel.findOneAndUpdate({ guildCode, 'ranks.roleId': roleId, bossHp: { $gte: hp } }, { $inc: { bossHp: - hp ,'ranks.$.score': hp}, }, { new: true }).lean(lean);
public static async updateBossHp(code: string, hp: number, roleId: string, lean = true) {
const bossInstance: BossInstanceType = await BossInstanceModel.findOneAndUpdate({ code, 'ranks.roleId': roleId, bossHp: { $gte: hp } }, { $inc: { bossHp: - hp ,'ranks.$.score': hp}, }, { new: true }).lean(lean);
return bossInstance;
}
public static async updateRank(guildCode: string, roleId: string, lean = true) {
const bossInstance: BossInstanceType = await BossInstanceModel.findOneAndUpdate({ guildCode, 'ranks.roleId': roleId }, { $set:{ 'ranks.$.time': nowSeconds() } }, { new: true }).lean(lean);
public static async updateRank(code: string, roleId: string, lean = true) {
const bossInstance: BossInstanceType = await BossInstanceModel.findOneAndUpdate({ code, 'ranks.roleId': roleId }, { $set:{ 'ranks.$.time': nowSeconds() } }, { new: true }).lean(lean);
return bossInstance;
}
@@ -109,9 +112,14 @@ export default class BossInstance extends BaseModel {
}
public static async findBySourceCode(guildCode: string, sourceCode: string) {
const rec = await BossInstanceModel.findOne({ guildCode, code: sourceCode }).select('ranks').lean();
const rec: BossInstanceType = await BossInstanceModel.findOne({ guildCode, code: sourceCode }).select('ranks').lean();
return rec;
}
public static async encourage(code: string, count: number, maxCount: number) {
const rec: BossInstanceType = await BossInstanceModel.findOneAndUpdate({ code, encourageCnt: { $lte: maxCount - count } }, { $inc: { encourageCnt: count } }).lean();
return rec
}
}
export const BossInstanceModel = getModelForClass(BossInstance);
+10 -2
View File
@@ -103,6 +103,12 @@ export default class Guild extends BaseModel {
@prop({ required: true, default: () => { return getZeroPoint(SHOP_REFRESH_TYPE.WEEKLY) } })
resetTrainTime: number;//上次刷新挑战训练场次数的时间
@prop({ required: true, default: getZeroPoint })
refOpenBossTime: Date; // 开启boss本刷新时间
@prop({ required: true, default: 0 })
openBossCnt: number; // 开启boss本次数
public static async createGuild(params: { name: string, icon: number, notice: string }, role: RoleType, serverId: number) {
const doc = new GuildModel();
const update = Object.assign(doc.toJSON(), params, { leader: role._id, members: [role.roleId], guildCe: role.ce, serverId, lvUpdateTime: nowSeconds() });
@@ -162,8 +168,10 @@ export default class Guild extends BaseModel {
return guildList;
}
public static async findByCode(code: string, serverId: number, select?: string) {
const result: GuildType = await GuildModel.findOne({ code, status: GUILD_STATUS.RUNNING, serverId })
public static async findByCode(code: string, serverId?: number, select?: string) {
let condition: any = { code, status: GUILD_STATUS.RUNNING };
if(serverId) condition.serverId = serverId;
const result: GuildType = await GuildModel.findOne(condition)
.select(select)
.populate('leader', {roleId: 1, roleName: 1, frame: 1, head: 1, spine: 1, lv: 1, quitTime: 1, ce: 1, title: 1, _id: 0}, 'Role')
.lean({ getters: true, virtuals: true });
+11 -2
View File
@@ -91,6 +91,15 @@ export default class UserGuild extends BaseModel {
@prop({ required: true, default: 0 })
wishDntCnt: number;//今天许愿池捐献次数
@prop({ required: true, default: new Date(), select: false })
refBossTime: Date;
@prop({ required: true, default: 0 })
encourageCnt: number; //今天鼓舞次数
@prop({ required: true, default: 0 })
bossChallengeCnt: number;//今天挑战演舞台次数
public static async getMyGuild(roleId: string, select?: string) {
const myGuild: UserGuildType = await UserGuildModel.findOne({ roleId, status: USER_GUILD_STATUS.ON })
@@ -118,12 +127,12 @@ export default class UserGuild extends BaseModel {
public static async createUserGuild(guildCode: string, role: RoleType, isLeader: boolean) {
const lastGuild = await UserGuildModel.findMyLastGuild(role.roleId);
let { receiveBoxs = [], donateCnt = 0, receivedActive = [] } = lastGuild||{};
let { receiveBoxs = [], donateCnt = 0, receivedActive = [], encourageCnt = 0, bossChallengeCnt = 0 } = lastGuild||{};
const doc = new UserGuildModel();
let job = isLeader? GUILD_JOB.DAJIANGJUN: GUILD_JOB.SHIBING;
let auth = isLeader? GUILD_AUTH.LEADER: GUILD_AUTH.MEMBER;
const update = Object.assign(doc.toJSON(), { guildCode, roleId: role.roleId, role: role._id, job, auth, receiveBoxs, donateCnt, receivedActive });
const update = Object.assign(doc.toJSON(), { guildCode, roleId: role.roleId, role: role._id, job, auth, receiveBoxs, donateCnt, receivedActive, encourageCnt, bossChallengeCnt });
delete update._id;
const result: UserGuildType = await UserGuildModel.findOneAndUpdate({ roleId: role.roleId, guildCode, status: USER_GUILD_STATUS.ON }, update, { upsert: true, new: true })
.select('activeDaily activeRecord activeWeekly activeUpdateTime job auth receivedActive guildCode')
+17 -3
View File
@@ -55,10 +55,18 @@ export interface DicBossBase {
readonly wars: Array<{warId:number, bossHp:number}>;
// 掉落的拍卖行奖励
readonly rewards: number;
//
readonly consume: number;
// 团长开启的奖励
readonly opencost: number;
// 击杀奖励
readonly killReward: RewardInter[];
// 伤害加成奖励
readonly damageReward: RewardInter[];
// 伤害加成系数
readonly ratio: number;
// 鼓舞次数
readonly encourageSum: number;
}
const DicBossKeys: KeysEnum<DicBossBase> = {
@@ -68,7 +76,11 @@ const DicBossKeys: KeysEnum<DicBossBase> = {
wars: true,
rewards: true,
consume: true,
opencost: true
opencost: true,
killReward: true,
damageReward: true,
ratio: true,
encourageSum: true
};
// 练兵场
@@ -191,6 +203,8 @@ export function loadStructure() {
let warArr = warStrs.split('&');
return { warId: parseInt(warArr[0]), bossHp: parseInt(warArr[1])}
});
o.killReward = parseGoodStr(o.killReward);
o.damageReward = parseGoodStr(o.damageReward);
dicBossBase.set(o.level, _.pick(o, Object.keys(DicBossKeys)));
dicBossBaseByBossLv.set(o.bossLevel, _.pick(o, Object.keys(DicBossKeys)));
});