Files
ZYZ/game-server/app/servers/role/handler/heroHandler.ts
2022-01-04 14:22:47 +08:00

732 lines
32 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 { Application, BackendSession, ChannelService, HandlerService, } from 'pinus';
import { handleCost, addItems, unlockFigure, createHeroes, createHero, CheckMeterial } from '../../../services/rewardService';
import { calPlayerCeAndSave, calAllHeroCe } from '../../../services/playerCeService';
import { resResult, deepCopy } from '../../../pubUtils/util';
import { STATUS } from '../../../consts/statusCode';
import { HeroModel, Connect, HeroSkin, HeroUpdate, EPlace } from '../../../db/Hero';
import { CURRENCY_BY_TYPE, CURRENCY_TYPE, CONSUME_TYPE, HERO_GROW_MAX, HERO_SYSTEM_TYPE, ABI_STAGE, DEBUG_MAGIC_WORD, HERO_INITIAL_QUALITY, REDIS_KEY, TASK_TYPE, ITEM_CHANGE_REASON } from '../../../consts';
import { RoleModel } from '../../../db/Role';
import { ItemModel } from '../../../db/Item';
import { gameData, getHeroExpByLv, getHeroStarByQuality, getHeroWakeByQuality, getHeroLvByExp, getMaxGradeByjobClass, getJobByGradeAndClass, getFriendShipById, getFavourLvByExp, reloadDicParam } from '../../../pubUtils/data';
import { ItemInter, RewardInter } from '../../../pubUtils/interface';
import { getDropItems, FIGURE_UNLOCK_CONDITION } from '../../../consts/constModules/itemConst'
import { pushComposeOrangeHero, pushHeroQualityUpMsg, pushHeroStarMax, pushHeroWakeUp } from '../../../services/chatService';
import { calculatetopLineup, calEquipSeids } from '../../../pubUtils/playerCe';
import { PvpDefenseModel } from '../../../db/PvpDefense';
import { checkTaskWithHero, checkTask, checkActivityTask } from '../../../services/taskService';
import { EquipModel, EquipType } from '../../../db/Equip';
import { checkEquipCanPut } from '../../../services/equipService';
import { pick } from 'underscore';
export default function (app: Application) {
new HandlerService(app, {});
return new HeroHandler(app);
}
export class HeroHandler {
constructor(private app: Application) {
}
// 武将碎片合成
public async compose(msg: { hid: number }, session: BackendSession) {
let roleId: string = session.get('roleId');
let roleName: string = session.get('roleName');
let sid: string = session.get('sid');
let serverId: number = session.get('serverId');
let { hid } = msg;
// 检查是否存在武将
let hasHero = await HeroModel.findByHidAndRole(hid, roleId);
if (hasHero) return resResult(STATUS.ROLE_HERO_EXISTS);
// 根据dic_hero 获得 1. 碎片id 2. 碎片数量 3. 初始武将星级 4. 初始品质
let dicHero = gameData.hero.get(hid);
if (!dicHero) return resResult(STATUS.DIC_DATA_NOT_FOUND);
let { pieceId, quality, pieceCount } = dicHero;
// 碎片数量是否足够
let costResult = await handleCost(roleId, sid, [{ id: pieceId, count: pieceCount }], ITEM_CHANGE_REASON.COMPOSE_HERO);
if (!costResult) return resResult(STATUS.ROLE_MATERIAL_NOT_ENOUGH);
// createHero
let { heroes, resultHeroes } = await createHero(roleId, roleName, sid, serverId, { hid, count: 1 });
pushComposeOrangeHero(roleId, roleName, serverId, resultHeroes[0]);
return resResult(STATUS.SUCCESS, { curHero: resultHeroes[0], addHeros: heroes });
}
// 武将升级
public async lvUp(msg: { hid: number, type: number }, session: BackendSession) {
let roleId: string = session.get('roleId');
let sid: string = session.get('sid');
const serverId = session.get('serverId');
let { hid, type } = msg;
let addLv = 0;
if (type == 1) {
addLv = 1;
} else if (type == 5) {
addLv = 5;
} else {
return resResult(STATUS.ROLE_HERO_LV_TYPE_ERROR);
}
// 计算武将可以升的级数
let hero = await HeroModel.findByHidAndRole(hid, roleId);
if (!hero) return resResult(STATUS.ROLE_HERO_NOT_EXISTS);
let { lv: playerLv } = await RoleModel.findByRoleId(roleId);
let { lv: oldLv, exp: oldExp } = hero;
if (oldLv >= playerLv) return resResult(STATUS.ROLE_HERO_LV_OVER);
if (oldLv + addLv > playerLv) addLv = playerLv - oldLv;
console.log('******* addLv', addLv, oldLv, playerLv);
let nextExp = getHeroExpByLv(oldLv + addLv - 1);
console.log('nextExp', nextExp, oldLv + addLv - 1, oldExp)
let needExp = nextExp - oldExp;
let newExp = oldExp;
// 计算得材料可转换的经验
let originalConsumes = await ItemModel.findByRoleAndType(roleId, CONSUME_TYPE.EXP);
let material = new Array<RewardInter>();
for (let { id, count } of originalConsumes) {
let dicGoods = gameData.goods.get(id);
if (!dicGoods) return resResult(STATUS.DIC_DATA_NOT_FOUND);
if(needExp < 0) break;
let _count = Math.ceil(needExp / dicGoods.value);
if (_count < count) {
material.push({ id, count: _count });
newExp += dicGoods.value * _count;
needExp -= dicGoods.value * _count;
break;
} else {
material.push({ id, count });
newExp += dicGoods.value * count;
needExp -= dicGoods.value * count;
}
}
if (newExp == oldExp) {
return resResult(STATUS.ROLE_EXP_NOT_ENOUGH);
}
let newLv = getHeroLvByExp(newExp);
let costResult = await handleCost(roleId, sid, material, ITEM_CHANGE_REASON.HERO_LV_UP);
if (!costResult) return resResult(STATUS.ROLE_MATERIAL_NOT_ENOUGH);
let update = {
lv: newLv,
exp: newExp
}
hero = await calPlayerCeAndSave(HERO_SYSTEM_TYPE.LVUP, sid, roleId, hero, update);
// 任务
await checkTaskWithHero(roleId, sid, TASK_TYPE.HERO_LV, hero, [oldLv]);
await checkActivityTask(serverId, sid, roleId, TASK_TYPE.HERO_LV, 1, { hid, lv: update.lv });
const curHero = {
hid, lv: hero.lv, exp: hero.exp
}
return resResult(STATUS.SUCCESS, { curHero, cost: material });
}
// 武将升星
public async starUp(msg: { hid: number, star: number, starStage: number, isOneClick: boolean }, session: BackendSession) {
let roleId: string = session.get('roleId');
const serverId = session.get('serverId');
let sid: string = session.get('sid');
let { hid, star, starStage, isOneClick } = msg;
// 根据dic_hero 获得 1. 碎片id 2. 碎片数量 3. 初始武将星级 4. 初始品质
let dicHero = gameData.hero.get(hid);
if (!dicHero) return resResult(STATUS.DIC_DATA_NOT_FOUND);
let { pieceId, jobid } = dicHero;
let dicJob = gameData.job.get(jobid);
if (!dicJob) return resResult(STATUS.DIC_DATA_NOT_FOUND);
let hero = await HeroModel.findByHidAndRole(hid, roleId);
if (!hero) return resResult(STATUS.ROLE_HERO_NOT_EXISTS);
let { star: oldStar, starStage: oldStarStage, quality } = hero;
if (oldStar != star || oldStarStage != starStage) {
return resResult(STATUS.WRONG_PARMS, { oldStarStage, oldStar, star, starStage });
}
if (oldStar == HERO_GROW_MAX.STAR) {
return resResult(STATUS.ROLE_STAR_REACH_MAX);
}
// 根据dic_zyz_hero_star 计算需要花的碎片并检查碎片数量
const curDicHeroStar = getHeroStarByQuality(dicJob.job_class, quality, oldStar);
if (!curDicHeroStar) return resResult(STATUS.DIC_DATA_NOT_FOUND);
let newStarStage = oldStarStage;
let max = isOneClick ? ABI_STAGE.END : oldStarStage + 1;
let check = new CheckMeterial(roleId);
for (let i = oldStarStage; i < max; i++) {
let isEnough = await check.decrease([{ id: pieceId, count: curDicHeroStar.advanceUpFragmentNum }]);
if(!isEnough) break; // 消耗不足
newStarStage++;
}
if (newStarStage == oldStarStage) return resResult(STATUS.ROLE_MATERIAL_NOT_ENOUGH);
let consumes = check.getConsume();
let result = await handleCost(roleId, sid, consumes, ITEM_CHANGE_REASON.HERO_STAR_UP);
if (!result)
return resResult(STATUS.BATTLE_CONSUMES_NOT_ENOUGH);
let isUpStar = newStarStage == ABI_STAGE.END;
let update = {
star: isUpStar ? oldStar + 1 : oldStar,
starStage: isUpStar ? ABI_STAGE.START : newStarStage
}
hero = await calPlayerCeAndSave(HERO_SYSTEM_TYPE.STAR, sid, roleId, hero, update);
if (isUpStar) {
await calAllHeroCe(HERO_SYSTEM_TYPE.STAR, sid, roleId, {}, [hid, isUpStar ? 1 : 0]); // 升星可能影响到百家学院全局加成
// 任务
await checkTaskWithHero(roleId, sid, TASK_TYPE.HERO_STAR_UP, hero);
await checkActivityTask(serverId, sid, roleId, TASK_TYPE.HERO_STAR_UP, 1);
await checkTaskWithHero(roleId, sid, TASK_TYPE.HERO_QUALITY_STAR_UP, hero);
//成长任务
await checkActivityTask(serverId, sid, roleId, TASK_TYPE.HERO_QUALITY_STAR_UP, 1, { quality: dicHero.quality, star: hero.star });
}
const curHero = {
hid,
star: hero.star,
starStage: hero.starStage,
colorStar: hero.colorStar,
colorStarStage: hero.colorStarStage
}
return resResult(STATUS.SUCCESS, { isUpStar, curHero });
}
// 武将升品
public async qualityUp(msg: { hid: number, quality: number }, session: BackendSession) {
let roleId: string = session.get('roleId');
let roleName: string = session.get('roleName');
let sid: string = session.get('sid');
let serverId: number = session.get('serverId');
let { hid, quality } = msg;
let dicHero = gameData.hero.get(hid);
if (!dicHero) return resResult(STATUS.DIC_DATA_NOT_FOUND);
// 根据dic_hero 获得 碎片id
let { pieceId } = dicHero;
let hero = await HeroModel.findByHidAndRole(hid, roleId);
if (!hero) return resResult(STATUS.ROLE_HERO_NOT_EXISTS);
let { quality: oldQuality, star } = hero;
if (quality != oldQuality) {
return resResult(STATUS.WRONG_PARMS);
}
if (oldQuality == HERO_GROW_MAX.QUALITY) {
return resResult(STATUS.ROLE_QUALITY_REACH_MAX);
}
if (star != HERO_GROW_MAX.STAR) {
return resResult(STATUS.ROLE_STAR_NOT_ENOUGH);
}
// 根据dic_zyz_hero_quality_up 获得需要的材料
const curDicHeroQualityUp = gameData.heroQualityUp.get(quality);
if (!curDicHeroQualityUp) return resResult(STATUS.DIC_DATA_NOT_FOUND);
let { fragmentNum } = curDicHeroQualityUp;
let costResult = await handleCost(roleId, sid, [{ id: pieceId, count: fragmentNum }], ITEM_CHANGE_REASON.HERO_QUALITY_UP);
if (!costResult) return resResult(STATUS.ROLE_MATERIAL_NOT_ENOUGH);
hero = await calPlayerCeAndSave(HERO_SYSTEM_TYPE.QUALITY, sid, roleId, hero, {
quality: hero.quality + 1
});
await calAllHeroCe(HERO_SYSTEM_TYPE.QUALITY, sid, roleId, {}, [hid, 0]); // 升品可能影响到百家学院全局加成
// 任务
await checkTaskWithHero(roleId, sid, TASK_TYPE.HERO_QUALITY_UP, hero);
// 任务
await checkActivityTask(serverId, sid, roleId, TASK_TYPE.HERO_QUALITY_TO_QUALITY_COUNT, 1, { oldQuality: dicHero.quality, quality: hero.quality });
const curHero = {
hid,
quality: hero.quality
}
pushHeroQualityUpMsg(roleId, roleName, serverId, hero);
return resResult(STATUS.SUCCESS, { curHero });
}
// 武将觉醒
public async wakeUp(msg: { hid: number, colorStar: number, colorStarStage: number, isOneClick: boolean }, session: BackendSession) {
let roleId: string = session.get('roleId');
let sid: string = session.get('sid');
let roleName: string = session.get('roleName');
const serverId = session.get('serverId');
let { hid, colorStar, colorStarStage, isOneClick } = msg;
// 根据dic_hero 获得 1. 碎片id 2. 碎片数量 3. 初始武将星级 4. 初始品质
let dicHero = gameData.hero.get(hid);
if (!dicHero) return resResult(STATUS.DIC_DATA_NOT_FOUND);
let { pieceId, jobid } = dicHero;
let dicJob = gameData.job.get(jobid);
if (!dicJob) return resResult(STATUS.DIC_DATA_NOT_FOUND);
let hero = await HeroModel.findByHidAndRole(hid, roleId);
if (!hero) return resResult(STATUS.ROLE_HERO_NOT_EXISTS);
let { colorStar: oldColorStar, colorStarStage: oldColorStarStage, star, quality } = hero;
if (colorStar != oldColorStar || colorStarStage != oldColorStarStage) {
return resResult(STATUS.WRONG_PARMS);
}
if (star != HERO_GROW_MAX.STAR) {
return resResult(STATUS.ROLE_WAKE_STAR_NOT_ENOUGH);
}
if (quality < HERO_GROW_MAX.QUALITY) {
return resResult(STATUS.ROLE_QUALITY_NOT_ENOUGH);
}
// 根据dic_zyz_hero_wake 计算需要花的碎片并检查碎片数量
const curDicHeroStar = getHeroWakeByQuality(dicJob.job_class, dicHero.quality, oldColorStar)
if (!curDicHeroStar) return resResult(STATUS.DIC_DATA_NOT_FOUND);
let newColorStarStage = oldColorStarStage;
let max = isOneClick ? ABI_STAGE.END : oldColorStarStage + 1;
let check = new CheckMeterial(roleId);
for (let i = oldColorStarStage; i < max; i++) {
let { fragmentNum, consume } = curDicHeroStar;
let isEnough = await check.decrease([{ id: pieceId, count: fragmentNum }, ...consume]);
if(!isEnough) break; // 消耗不足
newColorStarStage++;
}
if (newColorStarStage == oldColorStarStage) return resResult(STATUS.ROLE_MATERIAL_NOT_ENOUGH);
let consumes = check.getConsume();
let result = await handleCost(roleId, sid, consumes, ITEM_CHANGE_REASON.HERO_WAKE_UP);
if (!result)
return resResult(STATUS.BATTLE_CONSUMES_NOT_ENOUGH);
let isWakeUp = oldColorStar == 0;
let isUpStar = isWakeUp || newColorStarStage == ABI_STAGE.END;
let update = {
quality: isWakeUp? quality + 1: quality,
colorStar: isUpStar ? oldColorStar + 1 : oldColorStar,
colorStarStage: isUpStar ? ABI_STAGE.START : newColorStarStage
}
hero = await calPlayerCeAndSave(HERO_SYSTEM_TYPE.COLORSTAR, sid, roleId, hero, update);
if (isUpStar) {
await calAllHeroCe(HERO_SYSTEM_TYPE.COLORSTAR, sid, roleId, {}, [hid, isUpStar ? 1 : 0]); // 升星可能影响到百家学院全局加成
;
// 任务
await checkTaskWithHero(roleId, sid, TASK_TYPE.HERO_STAR_UP, hero);
await checkActivityTask(serverId, sid, roleId, TASK_TYPE.HERO_STAR_UP, 1);
await checkTask(roleId, sid, TASK_TYPE.HERO_WAKE_UP, 1, true, {});
await checkActivityTask(serverId, sid, roleId, TASK_TYPE.HERO_QUALITY_WAKE_UP_COUNT, 1, { quality: hero.quality });
await checkActivityTask(serverId, sid, roleId, TASK_TYPE.HERO_WAKE_UP_COUNT, 1, { hid: hid });
await checkActivityTask(serverId, sid, roleId, TASK_TYPE.HERO_WAKE_UP_STAR_UP_COUNT, 1, { quality: dicHero.quality, colorStar: update.colorStar });
}
const curHero = {
hid,
quality: hero.quality,
star: hero.star,
starStage: hero.starStage,
colorStar: hero.colorStar,
colorStarStage: hero.colorStarStage
}
if (isWakeUp) pushHeroWakeUp(roleId, roleName, serverId, hero); // 第一次觉醒
pushHeroStarMax(roleId, roleName, serverId, hero);
return resResult(STATUS.SUCCESS, { isUpStar, curHero });
}
//训练
async heroJobTrain(msg: { hid: number, isOneClick: boolean }, session: BackendSession) {
let roleId: string = session.get('roleId');
let sid: string = session.get('sid');
const serverId = session.get('serverId');
let { hid, isOneClick } = msg;
let hero = await HeroModel.findByHidAndRole(hid, roleId);
if (!hero) return resResult(STATUS.HERO_NOT_FIND);
let dicJob = gameData.job.get(hero.job);
if (!dicJob) return resResult(STATUS.DIC_DATA_NOT_FOUND);
if (hero.jobStage >= dicJob.maxStage)
return resResult(STATUS.HERO_JOB_STAGE_REACH_MAX_STAGE);
if (hero.job >= getMaxGradeByjobClass(dicJob.job_class))
return resResult(STATUS.HERO_JOB_REACH_MAX_STAGE);
let newJobStage = hero.jobStage;
let oldJobStage = hero.jobStage, oldJob = hero.job;
let max = isOneClick ? dicJob.maxStage: hero.jobStage + 1;
let check = new CheckMeterial(roleId);
for(let i = hero.jobStage; i < max; i++) {
let singleConsume = dicJob.trainingConsume[i];
if(!singleConsume) break; // 每天消耗不可训练
let isEnough = await check.decrease([singleConsume]);
if(!isEnough) break; // 消耗不足
newJobStage ++;
}
if (newJobStage == hero.jobStage) return resResult(STATUS.ROLE_MATERIAL_NOT_ENOUGH);
let consumes = check.getConsume();
let result = await handleCost(roleId, sid, consumes, ITEM_CHANGE_REASON.HERO_JOB_TRAIN);
if (!result)
return resResult(STATUS.BATTLE_CONSUMES_NOT_ENOUGH);
//重算战力并下发
hero = await calPlayerCeAndSave(HERO_SYSTEM_TYPE.TRAIN, sid, roleId, hero, {
jobStage: newJobStage
});
// 任务
await checkTaskWithHero(roleId, sid, TASK_TYPE.HERO_TRAIN, hero, [oldJob, oldJobStage]);
await checkTask(roleId, sid, TASK_TYPE.HERO_TRAIN_SUM, 1, true, {});
//活动统计
await checkActivityTask(serverId, sid, roleId, TASK_TYPE.HERO_TRAIN_SUM, 1)
await checkActivityTask(serverId, sid, roleId, TASK_TYPE.HERO_TRAIN, 1, { hid })
return resResult(STATUS.SUCCESS, { curHero: { hid: hero.hid, job: hero.job, jobStage: hero.jobStage } });
}
//进阶
async heroJobStageUp(msg: { hid: number }, session: BackendSession) {
let roleId: string = session.get('roleId');
const serverId = session.get('serverId');
let sid: string = session.get('sid');
let { hid } = msg;
let hero = await HeroModel.findByHidAndRole(hid, roleId);
if (!hero)
return resResult(STATUS.HERO_NOT_FIND);
let curJob = hero.job;
let heroJob = gameData.job.get(curJob);
if (heroJob.unlockLevel > hero.lv)
return resResult(STATUS.NOT_REACH_UNLOCK_LEVEL);
if (curJob >= getMaxGradeByjobClass(heroJob.job_class))
return resResult(STATUS.HERO_JOB_REACH_MAX_STAGE);
let result = await handleCost(roleId, sid, heroJob.upGradeConsume, ITEM_CHANGE_REASON.HERO_JOB_STAGEUP);
if (!result) {
return resResult(STATUS.BATTLE_CONSUMES_NOT_ENOUGH);
}
let nextHeroJob = getJobByGradeAndClass(heroJob.job_class, heroJob.grade + 1);
if (!nextHeroJob) return resResult(STATUS.DIC_DATA_NOT_FOUND);
//重算战力并下发
let update = {
job: nextHeroJob.jobid,
jobStage: 0
}
hero = await calPlayerCeAndSave(HERO_SYSTEM_TYPE.STAGEUP, sid, roleId, hero, update);
// 任务
await checkTaskWithHero(roleId, sid, TASK_TYPE.HERO_STAGE_UP, hero);
await checkActivityTask(serverId, sid, roleId, TASK_TYPE.HERO_STAGE_UP, 1, { job: hero.job });
return resResult(STATUS.SUCCESS, { curHero: { hid: hero.hid, job: hero.job, jobStage: hero.jobStage } });
}
//激活羁绊
async heroConectionActivate(msg: { shipId: number }, session: BackendSession) {
let roleId: string = session.get('roleId');
let sid: string = session.get('sid');
let { shipId } = msg;
let shipHidAndLevel = gameData.friendShipHidAandIds.get(shipId);
if (!shipHidAndLevel) return resResult(STATUS.HERO_CONECTION_IS_NOT_EXIT);
let hero = await HeroModel.findByHidAndRole(shipHidAndLevel.actorId, roleId);
if (!hero) return resResult(STATUS.HERO_NOT_FIND);
let heroConnections: Connect[] = deepCopy(hero.connections);
let curConnect = heroConnections.find(cur => cur.shipId == shipId);
if (!curConnect) {
curConnect = { shipId, level: 0 };
heroConnections.push(curConnect);
}
if (curConnect.level >= shipHidAndLevel.level) {
return resResult(STATUS.HERO_CONECTION_IS_MAX_LEVEL);
}
curConnect.level++;
let level = curConnect.level;
let friendShip = getFriendShipById(shipId, level);
if (hero.star + hero.colorStar < friendShip.level)
return resResult(STATUS.NOT_REACH_UNLOCK_LEVEL);
let hids = friendShip.hids;
for (let hid of hids) {
if (hid == shipHidAndLevel.actorId)
continue;
let member = await HeroModel.findByHidAndRole(hid, roleId);
if (!member)
return resResult(STATUS.ROLE_SHORT_HERO_CONECTION);
if (member.star + member.colorStar < friendShip.level)
return resResult(STATUS.NOT_REACH_UNLOCK_LEVEL);
}
let result = await handleCost(roleId, sid, [{ id: CURRENCY_BY_TYPE.get(CURRENCY_TYPE.COIN), count: friendShip.costCoin }], ITEM_CHANGE_REASON.HERO_CONNECT_ACTIVE);
if (!result) {
return resResult(STATUS.BATTLE_CONSUMES_NOT_ENOUGH);
}
//重算战力并下发
hero = await calPlayerCeAndSave(HERO_SYSTEM_TYPE.CONNECT, sid, roleId, hero, { connections: heroConnections }, [shipId]);
// 任务
await checkTask(roleId, sid, TASK_TYPE.HERO_CONNECT, 1, true, { connectLv: level })
return resResult(STATUS.SUCCESS, { curHero: { hid: hero.hid, connections: hero.connections } });
}
//赠送(包括一键赠送)
async heroGiveFavor(msg: { hid: number, type: number }, session: BackendSession) {
let roleId: string = session.get('roleId');
let sid: string = session.get('sid');
let serverId: number = session.get('serverId');
let { hid, type } = msg;
let addLv = 0;
if (type == 1) {
addLv = 1;
} else if (type == 5) {
addLv = 5;
} else {
return resResult(STATUS.WRONG_PARMS);
}
let hero = await HeroModel.findByHidAndRole(hid, roleId);
if (!hero) return resResult(STATUS.ROLE_HERO_NOT_EXISTS);
let { favourLv: oldLv, favour: oldExp, lv } = hero;
let maxLv = lv > gameData.maxFriendShipLv.max ? gameData.maxFriendShipLv.max : lv; // 好感度最大等级
if (maxLv <= oldLv)
return resResult(STATUS.HERO_FAVOUR_LEVEL_REACH_MAXT);
// 计算武将可以升的级数
if (oldLv + addLv > maxLv) addLv = maxLv - oldLv;
let nextObj = gameData.friendShipLevelMap.get(oldLv + addLv - 1);
if (!nextObj) return resResult(STATUS.HERO_FAVOUR_LEVEL_REACH_MAXT);
let nextExp = nextObj.expSum;
let needExp = nextExp - oldExp;
let newExp = oldExp;
// 计算得材料可转换的经验
let originalConsumes = await ItemModel.findByRoleAndType(roleId, CONSUME_TYPE.FAVOUR);
let material = new Array<RewardInter>();
for (let { id, count } of originalConsumes) {
let dicGoods = gameData.goods.get(id);
if (!dicGoods) return resResult(STATUS.DIC_DATA_NOT_FOUND);
let _count = Math.ceil(needExp / dicGoods.value);
if (_count < count) {
material.push({ id, count: _count });
newExp += dicGoods.value * _count;
break;
} else {
material.push({ id, count });
newExp += dicGoods.value * count;
}
}
if (newExp == oldExp) {
return resResult(STATUS.BATTLE_CONSUMES_NOT_ENOUGH);
}
let newLv = getFavourLvByExp(newExp);
let result = await handleCost(roleId, sid, material, ITEM_CHANGE_REASON.HERO_GIVE_FAVOR);
if (!result) {
return resResult(STATUS.BATTLE_CONSUMES_NOT_ENOUGH);
}
//重算战力并下发
if (oldLv != newLv) {
await unlockFigure(sid, roleId, [{ type: FIGURE_UNLOCK_CONDITION.HERO_FAVOR, paramHid: hero.hid, paramFavourLv: hero.favourLv }]);
hero = await calPlayerCeAndSave(HERO_SYSTEM_TYPE.FAVOUR, sid, roleId, hero, {
favour: newExp, favourLv: newLv
}, [oldLv]);
// 任务
await checkTaskWithHero(roleId, sid, TASK_TYPE.HERO_FAVOUR_LV, hero, [oldLv]);
await checkActivityTask(serverId, sid, roleId, TASK_TYPE.HERO_FAVOUR_LV, 1, { lv: newLv, oldLv });
} else {
hero = await HeroModel.updateHeroInfo(roleId, hero.hid, { favour: newExp, favourLv: newLv });
}
return resResult(STATUS.SUCCESS, { curHero: { hid: hero.hid, favour: hero.favour, favourLv: hero.favourLv, cost: material } });
}
//穿带时装
async heroWearSkin(msg: { id: number }, session: BackendSession) {
let roleId: string = session.get('roleId');
let sid: string = session.get('sid');
let serverId: number = session.get('serverId');
let { id } = msg;
let dicSkin = gameData.fashion.get(id);
// console.log('*****', id, dicSkin)
if (!dicSkin) return resResult(STATUS.HERO_SKIN_NOT_FIND);
let hero = await HeroModel.findByHidAndRoleWithEquip(dicSkin.actorId, roleId);
if (!hero) return resResult(STATUS.HERO_NOT_FIND);
let oldCount = hero.ePlace.filter(cur => cur.equip).length;
let newHeroSkins: HeroSkin[] = [];
let result = false;
let lastSkinId: number;
for (let skin of hero.skins) {
if (skin.id == id) {
if (!!skin.enable) {
return resResult(STATUS.HERO_SKIN_IS_EQUIPED);
}
newHeroSkins.push({ ...skin, enable: true });
result = true;
} else {
if (!!skin.enable) {
lastSkinId = skin.skinId;
}
newHeroSkins.push({ ...skin, enable: false });
}
}
if (!result) {
return resResult(STATUS.HERO_SKIN_NOT_FIND);
}
let oldEquipSeids = calEquipSeids(hero);
let dicHero = gameData.hero.get(dicSkin.heroId);
let dicMyJob = gameData.job.get(hero.job);
let dicNewJob = getJobByGradeAndClass(dicHero.jobClass, dicMyJob.grade);
let newEplace: EPlace[] = [], heroPutNum = 0, curEquips: {seqId: number, id: number, hid: number, ePlaceId: number}[] = [];
for(let { id, equip, lv, refineLv } of hero.ePlace) {
let e = <EquipType>equip;
if(equip && !checkEquipCanPut({...hero, skinId: dicSkin.heroId}, e.id)) {
await EquipModel.putOnOrOff(e._id, 0);
heroPutNum -= 1;
newEplace.push({ id, equip: null, lv, refineLv});
curEquips.push({ seqId: e.seqId, id: e.id, hid: 0, ePlaceId: id });
} else {
newEplace.push({ id, equip: e?e._id: null, lv, refineLv});
}
}
if(heroPutNum < 0) {
hero = await calPlayerCeAndSave(HERO_SYSTEM_TYPE.EQUIP, sid, roleId, hero, {}, oldEquipSeids);
await checkTask(roleId, sid, TASK_TYPE.EQUIP_SUM, heroPutNum, true, {});
await checkActivityTask(serverId, sid, roleId, TASK_TYPE.EQUIP_SUM, heroPutNum);
await checkTaskWithHero(roleId, sid, TASK_TYPE.EQUIP_BY_HERO, hero, [heroPutNum, oldCount]);
}
hero = await calPlayerCeAndSave(HERO_SYSTEM_TYPE.SKIN, sid, roleId, hero, { skins: newHeroSkins, skinId: dicSkin.heroId, job: dicNewJob.jobid, ePlace: newEplace });
return resResult(STATUS.SUCCESS, { curHero: pick(hero, ['hid', 'skins', 'skinId', 'job']), curEquips });
}
// ! debug接口 一键全武将
public async debugGetAllHeroes(msg: { magicWord: string }, session: BackendSession) {
let roleId: string = session.get('roleId');
let roleName: string = session.get('roleName');
let sid: string = session.get('sid');
let serverId: number = session.get('serverId');
const { magicWord } = msg;
if (magicWord !== DEBUG_MAGIC_WORD) {
return resResult(STATUS.TOKEN_ERR);
}
let heroes = await HeroModel.findByRole(roleId);
let heroInfos = [];
for(let { actorId } of gameData.recruit) {
let dicHero = gameData.hero.get(actorId);
if(!dicHero) continue;
let hasHero = heroes.findIndex(cur => cur.hid == actorId);
if(hasHero == -1) {
heroInfos.push({
hid: actorId, star: 6, colorStar: 6, quality: 4
});
}
}
let resultHeroes = await createHeroes(roleId, roleName, sid, serverId, heroInfos);
return resResult(STATUS.SUCCESS, resultHeroes);
}
// ! 测试接口用来测试前清理并初始化某个武将代码抄自gm-server/app/service/users.ts deleteHero
public async testCleanUp(msg: { magicWord: string, hid: number }, session: BackendSession) {
let roleId: string = session.get('roleId');
let roleName: string = session.get('roleName');
let sid: string = session.get('sid');
const { magicWord, hid } = msg;
if (magicWord !== DEBUG_MAGIC_WORD) {
return resResult(STATUS.TOKEN_ERR);
}
let dicHero = gameData.hero.get(hid);
if (!dicHero) return resResult(STATUS.HERO_NOT_FIND);
await addItems(roleId, roleName, sid, [{
id: dicHero.pieceId, count: dicHero.pieceCount * HERO_GROW_MAX.STAR * ABI_STAGE.END
}], ITEM_CHANGE_REASON.DEBUG);
let hero = await HeroModel.findByHidAndRole(hid, roleId);
if (!hero) return resResult(STATUS.HERO_NOT_FIND);
await HeroModel.deleteHero(roleId, hid);
let role = await RoleModel.findByRoleId(roleId);
await calculatetopLineup(role, hid, 0, null);
await PvpDefenseModel.deleteHero(roleId, hid);
await RoleModel.updateRoleInfo(roleId, { topLineup: role.topLineup, topLineupCe: role.topLineupCe, ce: role.ce - hero.ce });
return resResult(STATUS.SUCCESS);
}
public async addItem(msg: { id: number, count: number }, session: BackendSession) {
let roleId: string = session.get('roleId');
let roleName: string = session.get('roleName');
let sid: string = session.get('sid');
let { id, count } = msg;
//let result = await handleCost(roleId, sid, [{id, count}] );
let items = [{ id, count }];
let role = await RoleModel.findByRoleId(roleId);
if (id == 999999) {
items = getDropItems();
if (role.lv < 60) {
role.lv = 60;
let roleLvInfo = gameData.kingexp.get(role.lv - 1);
role.exp = roleLvInfo.sum;
await RoleModel.updateRoleInfo(roleId, role);
}
}
let result = await addItems(roleId, roleName, sid, items, ITEM_CHANGE_REASON.DEBUG);
if (!result) {
return resResult(STATUS.BATTLE_CONSUMES_NOT_ENOUGH);
}
return resResult(STATUS.SUCCESS, { goods: result, lv: role.lv, exp: role.exp });
}
public async debugSetHero(msg: { magicWord: string, hid: number, params: HeroUpdate }, session: BackendSession) {
let roleId: string = session.get('roleId');
let roleName: string = session.get('roleName');
let sid: string = session.get('sid');
let serverId: number = session.get('serverId');
let { magicWord, hid, params } = msg;
if (magicWord !== DEBUG_MAGIC_WORD) {
return resResult(STATUS.TOKEN_ERR);
}
let hero = await HeroModel.findByHidAndRole(hid, roleId);
if(!hero) {
let { resultHeroes } = await createHero(roleId, roleName, sid, serverId, { hid, count: 1, ...params });
hero = resultHeroes[0];
}
hero = await HeroModel.updateHeroInfo(roleId, hid, params);
return resResult(STATUS.SUCCESS, { hero });
}
}