import { HeroModel, HeroType } from '../db/Hero'; import Role, { RoleModel, RoleType } from '../db/Role' import { getLvByExp, getExpByLv, gameData, getDicApByLv } from '../pubUtils/data'; import { 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 } from '../pubUtils/util'; import { 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'; 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); // 等级超过最高级之后,经验依然可以稍微溢出一些,以备下一次提升等级 // let nextExpObj = getExpByLv(newLv + 1); // let curExpObj = getExpByLv(newLv); // if(curExpObj && !nextExpObj && newExp > curExpObj.sum) { // newExp = curExpObj.sum; // } 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 }]); 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 }); } 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); await setAp(serverId, roleId, ip, i, dicAp.restoreAp, sid, ITEM_CHANGE_REASON.LV_UP); } } // 推送 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 = []) { 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 = []) { 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 } = role; 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: '' }); } } } result = result.sort((a, b) => { return a.battleId - b.battleId }); return result; } 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||[], } }