266 lines
10 KiB
TypeScript
266 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, RECHARGE } from '../pubUtils/dicParam';
|
|
import { updateGVGBattleRoleInfo } from './gvg/gvgTeamService';
|
|
|
|
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 });
|
|
|
|
await updateGVGBattleRoleInfo(serverId, roleId, { lv });
|
|
}
|
|
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);
|
|
if(dicWar) 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.BRANCH_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 && (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||[],
|
|
}
|
|
}
|