Files
ZYZ/game-server/app/services/normalBattleService.ts
2022-07-14 13:57:59 +08:00

264 lines
10 KiB
TypeScript

import { HeroModel, HeroType } from '../db/Hero';
import Role, { RoleModel, RoleType, WarCount } from '../db/Role'
import { getLvByExp, getExpByLv, gameData, getDicApByLv } from '../pubUtils/data';
import { updateRoleOnlineInfo, updateUserInfo } from './redisService';
// import { switchOnFunc } from './funcSwitchService';
import { FUNC_OPT_TYPE, TASK_TYPE, WAR_TYPE, STATUS, KING_EXP_RATIO_TYPE, ITEM_CHANGE_REASON, POP_UP_SHOP_CONDITION_TYPE, HERO_SYSTEM_TYPE, PUSH_ROUTE } from '../consts';
import { BackendSession, pinus } from 'pinus';
import { REDIS_KEY } from '../consts';
import { Rank } from './rankService';
import { checkTask } from './task/taskService';
import { RScriptRecordModel } from '../db/RScriptRecord';
import { setAp } from './actionPointService';
import { resResult, shouldRefresh } from '../pubUtils/util';
import { GuildLeader, LineupParam } from '../domain/rank';
import { WarStar } from '../domain/dbGeneral';
import { uniq } from 'underscore';
import { checkPopUpCondition } from './activity/popUpShopService';
import { calculateCeWithRole } from './playerCeService';
import { sendMessageToUserWithSuc } from './pushService';
import { ActionPointModel } from '../db/ActionPoint';
import { GK_MAIN, GK_MAINELITE } from '../pubUtils/dicParam';
export async function roleLevelup(type: KING_EXP_RATIO_TYPE, roleId: string, kingExp: number = 0, session: BackendSession) {
const serverId = session.get('serverId');
const sid = session.get('sid');
const ip = session.get('ip');
let role = await RoleModel.findByRoleId(roleId);
let { lv = 1, exp = 0 } = role;
let canGetExp = lv < gameData.maxPlayerLv.max; // 当主公超过最大级后,挑战结算不再获得经验值
let ratio = gameData.kingExpRaio.get(lv)?.get(type)||0;
let newExp = canGetExp ? exp + Math.floor(kingExp * ratio) : exp;
let newLv = getLvByExp(newExp);
role = await RoleModel.levelup(roleId, newLv, newExp);
if (newLv > lv) { // 升级
// await switchOnFunc(roleId, FUNC_OPT_TYPE.LEVEL_UP, newLv, session);
await updateUserInfo(REDIS_KEY.USER_INFO, roleId, [{ field: 'lv', value: newLv }]);
if(role.isGuildLeader) {
await updateUserInfo(REDIS_KEY.GUILD_INFO, role.guildCode, [{ field: 'leader', value: new GuildLeader(role) }]);
}
let r = new Rank(REDIS_KEY.USER_LV, { serverId: role.serverId });
await r.setRankWithRoleInfo(roleId, newLv, Date.now(), role);
// 任务
await checkTask(serverId, roleId, session.get('sid'), TASK_TYPE.ROLE_LV, { oldLv: lv, lv: newLv });
// 弹出礼包
await checkPopUpCondition(serverId, roleId, POP_UP_SHOP_CONDITION_TYPE.LV_TO, { oldLv: lv, newLv })
// await calculateCeWithRole(HERO_SYSTEM_TYPE.ROLE_LV, roleId, serverId, sid, { lv: newLv });
await updateRoleOnlineInfo(roleId, { lv: newLv });
}
let actordata: { lv: number, exp: number, getExp: number, mostExp: number }[] = [];
for (let i = lv; i <= newLv; i++) {
let lvObj = getExpByLv(i);
if (!lvObj) break;
let { sum, cur } = lvObj;
let lastSum = sum - cur;
// console.log(sum, cur, lastSum, exp, newExp);
let startExp = exp > lastSum ? exp - lastSum : 0;
let getExp = newExp > sum ? cur - startExp : newExp - lastSum - startExp;
actordata.push({
lv: i,
exp: startExp, // 升级前经验
getExp: getExp > 0 ? getExp : 0, // 获得的经验
mostExp: cur
});
if(i != lv) { // 升级加体力
let dicAp = getDicApByLv(i);
let { ap, apBefore } = await setAp(serverId, roleId, ip, i, dicAp.restoreAp, sid, ITEM_CHANGE_REASON.LV_UP);
await ActionPointModel.setLvRecord(roleId, i, ap, apBefore);
}
}
// 推送
if(canGetExp && kingExp >= 0) {
sendMessageToUserWithSuc(roleId, PUSH_ROUTE.PLAYER_EXP_CHANGE, { isLvUp: newLv > lv, lv: newLv, exp: newExp }, sid);
}
return { actordata, lv: newLv, exp: newExp, kingExp: newExp - exp };
}
export async function checkBattleHeroes(roleId: string, seqIds: Array<number> = []) {
let hids: number[] = [], lineup: LineupParam[] = [], heroes: HeroType[] = [];
let flag = true;
// if (seqIds.length <= 0) flag = false;
const findHeroes = await HeroModel.findBySeqIdRange(seqIds, roleId);
if (findHeroes.length != seqIds.length) flag = false;
for (let seqId of seqIds) {
let hero = findHeroes.find(cur => cur.seqId == seqId);
if (!hero) {
flag = false; break;
}
hids.push(hero.hid);
lineup.push(new LineupParam(hero));
heroes.push(hero);
}
return { isOK: flag, hids, heroes, seqIds, lineup };
}
export async function checkBattleHeroesByHid(roleId: string, heroes: Array<number> = []) {
let flag = true;
// if (heroes.length <= 0) flag = false;
const findHeroes = await HeroModel.findByHidRange(heroes, roleId);
if (findHeroes.length != heroes.length) flag = false;
for (let hid of heroes) {
let hero = findHeroes.find(cur => cur.hid == hid);
if (!hero) flag = false;
}
return { isOK: flag, heroes: findHeroes };
}
export function calculateWarStar(warStar: WarStar[] = [], battleId: number, stars: number[] = []) {
let newWarStars: WarStar[] = [];
let newStars: number[] = [], newStar = 0;
let hasFound = false;
for(let curWarStar of warStar) {
if(curWarStar.id == battleId) {
let oldStars = curWarStar.stars||[];
newStars = uniq([...stars, ...oldStars]);
newStar = newStars.filter(cur => cur > 0).length;
newWarStars.push({...curWarStar, star: newStar, stars: newStars});
hasFound = true;
} else {
newWarStars.push(curWarStar);
}
}
if(!hasFound) {
newStar = stars.filter(cur => cur > 0).length;
newStars = stars;
let dicWar = gameData.war.get(battleId);
newWarStars.push({ id: battleId, warType: dicWar.warType, star: newStar, stars: newStars});
}
return { newWarStars, newStars, newStar };
}
export async function getBattleListOfMain(role: RoleType) {
let types = [ WAR_TYPE.NORMAL, WAR_TYPE.VESTIGE, WAR_TYPE.MAIN_ELITE, WAR_TYPE.TOWER, WAR_TYPE.MYSTERY, WAR_TYPE.MYSTERY_ELITE ];
return await getBattleListOfTypes(role, types);
}
export async function getBattleListOfTypes(role: RoleType, types: number[]) {
let result = [];
for(let type of types) {
let list = await getBattleList(role, type);
result.push({ type, list });
}
return result
}
export async function getBattleList(role: RoleType, type: number) {
let { roleId, warStar, warCount = [], refWarCount } = role;
if(shouldRefresh(refWarCount, new Date())) {
warCount = [];
}
let scripts = await RScriptRecordModel.findbyRole(roleId, type);
let result = []; // 去重
for (let { battleId, scriptBefore = '', scriptAfter = '' } of scripts) {
result.push({
battleId,
status: 0,
star: 0,
stars: [],
scriptBefore,
scriptAfter
});
}
for (let { id, star, stars = [], warType } of warStar) {
if (warType == type) {
let curResult = result.find(cur => cur.battleId == id);
if (curResult) {
curResult.status = 1;
curResult.star = star;
curResult.stars = stars;
} else {
result.push({
battleId: id,
status: 1,
star,
stars,
scriptBefore: '',
scriptAfter: ''
});
}
}
}
if(type == WAR_TYPE.NORMAL || type == WAR_TYPE.MAIN_ELITE) {
for(let data of result) {
let curWarCount = warCount.find(cur => cur.warId == data.battleId);
data.count = curWarCount? curWarCount.count: 0;
}
}
result = result.sort((a, b) => { return a.battleId - b.battleId });
return result;
}
export async function checkWarCountAndInc(warId: number, inc: number, role: RoleType, needRefresh: boolean) {
let { roleId, warCount, refWarCount } = role;
let dicWar = gameData.war.get(warId);
let max = dicWar.warType == WAR_TYPE.NORMAL? GK_MAIN.GK_MAIN_SWEEP_TIMES: GK_MAINELITE.GK_MAINELITE_SWEEP_TIMES;
if(needRefresh && shouldRefresh(refWarCount, new Date())) {
let role = await RoleModel.updateRoleInfo(roleId, { refWarCount: new Date(), warCount: [] });
warCount = role.warCount;
}
let curWarCount = warCount.find(cur => cur.warId == warId);
let count = curWarCount? curWarCount.count: 0;
if(inc <= 0) { // checkBattle
if(count >= max) return resResult(STATUS.BATTLE_OR_SWEEP_CNT_NOT_ENOUGH);
} else { // battleEnd & battleSweep
if(count + inc > max) return resResult(STATUS.BATTLE_OR_SWEEP_CNT_NOT_ENOUGH);
}
if(inc > 0) {
if(curWarCount) {
curWarCount.count += inc;
} else {
warCount.push({ warId, count: inc });
}
await RoleModel.updateRoleInfo(roleId, { warCount });
}
return resResult(STATUS.SUCCESS);
}
export function getStarOfChapter(warStar: WarStar[], warTye: number, chapter: number) {
let starOfChapter = 0
for(let { id, star } of warStar ) {
let dicWar = gameData.war.get(id);
if(dicWar.warType == warTye && star > 0) {
starOfChapter += star;
}
}
return starOfChapter;
}
export function getMainChapter(role: RoleType) {
let chapterArr: { chapter: number, star: number, warType: number }[] = [];
for(let { id, star } of role.warStar ) {
let dicWar = gameData.war.get(id);
if((dicWar.warType == WAR_TYPE.NORMAL || dicWar.warType == WAR_TYPE.MAIN_ELITE) && star > 0) {
let curChapter = chapterArr.find(cur => cur.warType == dicWar.warType && cur.chapter == dicWar.chapter);
if(!curChapter) {
chapterArr.push({ chapter: dicWar.chapter, star, warType: dicWar.warType });
} else {
curChapter.star += star;
}
}
}
return {
star: chapterArr,
receivedBox: role.receivedBox||[],
receivedWarIds: role.receivedWarIds||[],
}
}