Files
ZYZ/game-server/app/servers/role/handler/heroHandler.ts
2020-12-10 17:05:17 +08:00

435 lines
18 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, createTcpMailBox, ChannelService} from 'pinus';
import { handleCost } from '../../../services/rewardService';
import { calPlayerCeAndSave } from '../../../services/playerCeService';
import { resResult, getItems, decodeStr } from '../../../pubUtils/util';
import { STATUS } from '../../../consts/statusCode';
import {HeroModel} from '../../../db/Hero';
import {CURRENCY_BY_TYPE, CURRENCY_TYPE, ITID, CONSUME_TYPE, HERO_GROW_MAX} from '../../../consts/consts';
import {getJobInfoById, getMaxGradeByjobClass, getHeroInfoById, getGoodById, getHeroExpByLv, getGamedata, getJobByGradeAndClass, getFriendShipById, getFriendShipLevels, getFashionsById} from '../../../pubUtils/gamedata';
import { ABI_STAGE } from '../../../consts/abilityConst';
import { RoleModel } from '../../../db/Role';
const _ = require('underscore');
export default function(app: Application) {
return new HeroHandler(app);
}
export class HeroHandler {
constructor(private app: Application) {
}
private channelService: ChannelService = this.app.get('channelService');
public async test(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}] );
if(!result) {
return resResult(STATUS.BATTLE_CONSUMES_NOT_ENOUGH);
}
return resResult(STATUS.SUCCESS);
}
// 武将碎片合成
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 = getHeroInfoById(hid);
if(!dicHero) return resResult(STATUS.ROLE_INFO_NOT_FOUND);
let {pieceId, quality, initialStars: star, pieceCount, jobid: job, name: hName} = dicHero;
// 碎片数量是否足够
let costResult = await handleCost(roleId, sid, [{id: pieceId, count: pieceCount}]);
if(!costResult) return resResult(STATUS.ROLE_MATERIAL_NOT_ENOUGH);
// createHero
let curHero = await HeroModel.createHero({
roleId, serverId, roleName, hid, hName, star, quality, job
}, false);
await calPlayerCeAndSave(sid, roleId, [curHero]);
return resResult(STATUS.SUCCESS, {curHero});
}
// 武将升级
public async lvUp(msg: { hid: number, type: number, material: Array<{id: number, count: number}>}, session: BackendSession) {
let roleId: string = session.get('roleId');
let sid: string = session.get('sid');
let { hid, type, material } = 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 allExp = 0;
for(let {id, count} of material) {
let dicGoods = getGoodById(id);
if(!dicGoods) return resResult(STATUS.ROLE_INFO_NOT_FOUND);
let dicItid = ITID.get(dicGoods.itid);
if(!dicItid || dicItid.type != CONSUME_TYPE.EXP) {
return resResult(STATUS.ROLE_METERIAL_ERROR);
}
allExp += count * dicGoods.value;
}
// 计算武将可以升的级数
let hero = await HeroModel.findByHidAndRole(hid, roleId, false);
if(!hero) return resResult(STATUS.ROLE_HERO_NOT_EXISTS);
let {lv: playerLv} = await RoleModel.findByRoleId(roleId);
let {lv: oldLv, exp: oldExp} = hero;
if(oldLv + addLv > playerLv ) return resResult(STATUS.ROLE_HERO_LV_OVER);
oldExp += allExp;
let newExp = oldExp + allExp; // 不考虑主公等级,还会剩多少经验
let newLv = oldLv; // 不考虑主公等级,这些经验可以升几级
let curExp = newExp; // 考虑到主公等级,还剩多少经验
for(;;) {
let exp = getHeroExpByLv(newLv);
if(exp < newExp) {
newExp -= exp;
if(newLv < playerLv) curExp -= exp;
newLv ++;
} else {
break;
}
}
if(oldLv + addLv > newLv) {
return resResult(STATUS.ROLE_EXP_NOT_ENOUGH);
}
let costResult = await handleCost(roleId, sid, material);
if(!costResult) return resResult(STATUS.ROLE_MATERIAL_NOT_ENOUGH);
hero.lv = playerLv > newLv?newLv: playerLv;
hero.exp = curExp;
let heros = await calPlayerCeAndSave(sid, roleId, [hero]);
const curHero = {
hid, lv : heros[0].lv, exp : heros[0].exp
}
return resResult(STATUS.SUCCESS, { curHero });
}
// 武将升星
public async starUp(msg: { hid: number, star: number, starStage: number}, session: BackendSession) {
let roleId: string = session.get('roleId');
let sid: string = session.get('sid');
let {hid, star, starStage} = msg;
// 根据dic_hero 获得 1. 碎片id 2. 碎片数量 3. 初始武将星级 4. 初始品质
let dicHero = getHeroInfoById(hid);
if(!dicHero) return resResult(STATUS.ROLE_INFO_NOT_FOUND);
let {pieceId} = dicHero;
let hero = await HeroModel.findByHidAndRole(hid, roleId, false);
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);
}
if(oldStar == HERO_GROW_MAX.STAR) {
return resResult(STATUS.ROLE_STAR_REACH_MAX);
}
// 根据dic_zyz_hero_star 计算需要花的碎片并检查碎片数量
const dicHeroStar = getGamedata('dic_zyz_hero_star');
const curDicHeroStar = dicHeroStar.find(cur => cur.quality == quality && cur.star && oldStar);
if(!curDicHeroStar) return resResult(STATUS.ROLE_INFO_NOT_FOUND);
let costResult = await handleCost(roleId, sid, [{id: pieceId, count: curDicHeroStar.advanceUpFragmentNum}]);
if(!costResult) return resResult(STATUS.ROLE_MATERIAL_NOT_ENOUGH);
let isUpStar = oldStarStage + 1 == ABI_STAGE.END;
hero.star = isUpStar? oldStar + 1: oldStar;
hero.starStage = isUpStar? ABI_STAGE.START: oldStarStage + 1;
let heros = await calPlayerCeAndSave(sid, roleId, [hero]);
const curHero = {
hid,
star : heros[0].star,
starStage : heros[0].starStage,
colorStar: heros[0].colorStar,
colorStarStage: heros[0].colorStarStage
}
return resResult(STATUS.SUCCESS, {isUpStar, curHero});
}
// 武将升品
public async qualityUp(msg: { hid: number, quality: number }, session: BackendSession) {
let roleId: string = session.get('roleId');
let sid: string = session.get('sid');
let {hid, quality} = msg;
let dicHero = getHeroInfoById(hid);
if(!dicHero) return resResult(STATUS.ROLE_INFO_NOT_FOUND);
// 根据dic_hero 获得 碎片id
let {pieceId} = dicHero;
let hero = await HeroModel.findByHidAndRole(hid, roleId, false);
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 获得需要的材料
let dicHeroQualityUp = getGamedata('dic_zyz_hero_quality_up');
const curDicHeroQualityUp = dicHeroQualityUp.find(cur => cur.quality == quality);
if(!curDicHeroQualityUp) return resResult(STATUS.ROLE_INFO_NOT_FOUND);
let {fragmentNum} = curDicHeroQualityUp;
let costResult = await handleCost(roleId, sid, [{id: pieceId, count: fragmentNum}]);
if(!costResult) return resResult(STATUS.ROLE_MATERIAL_NOT_ENOUGH);
hero.quality ++;
let heros = await calPlayerCeAndSave(sid, roleId, [hero]);
const curHero = {
hid,
quality : heros[0].quality
}
return resResult(STATUS.SUCCESS, {curHero});
}
// 武将觉醒
public async wakeUp(msg: { hid: number, colorStar: number, colorStarStage: number}, session: BackendSession) {
// 根据dic_hero 获得 碎片id
// 根据dic_zyz_hero_wake 获得需要花费的碎片和材料
// 特殊处理初次觉醒fireStage传0保存为 colorStar = 1, colorStarStage = 0花费的材料取的0星的
// 检查品质是否是橙色
// 升星阶满6自动升星
// handleCost
let roleId: string = session.get('roleId');
let sid: string = session.get('sid');
let {hid, colorStar, colorStarStage} = msg;
// 根据dic_hero 获得 1. 碎片id 2. 碎片数量 3. 初始武将星级 4. 初始品质
let dicHero = getHeroInfoById(hid);
if(!dicHero) return resResult(STATUS.ROLE_INFO_NOT_FOUND);
let {pieceId} = dicHero;
let hero = await HeroModel.findByHidAndRole(hid, roleId, false);
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 dicHeroStar = getGamedata('dic_zyz_hero_wake');
const curDicHeroStar = dicHeroStar.find(cur => cur.quality == quality && cur.star == oldColorStar);
if(!curDicHeroStar) return resResult(STATUS.ROLE_INFO_NOT_FOUND);
let {fragmentNum, consume} = curDicHeroStar;
let consumeArr = decodeStr('cost', consume);
console.log(JSON.stringify([{id: pieceId, count: fragmentNum}, ...consumeArr]))
let costResult = await handleCost(roleId, sid, [{id: pieceId, count: fragmentNum}, ...consumeArr]);
if(!costResult) return resResult(STATUS.ROLE_MATERIAL_NOT_ENOUGH);
let isUpStar = oldColorStar == 0|| oldColorStarStage + 1 == ABI_STAGE.END;
hero.colorStar = isUpStar? oldColorStar + 1: oldColorStar;
hero.colorStarStage = isUpStar? ABI_STAGE.START: oldColorStarStage + 1;
let heros = await calPlayerCeAndSave(sid, roleId, [hero]);
const curHero = {
hid,
star : heros[0].star,
starStage : heros[0].starStage,
colorStar: heros[0].colorStar,
colorStarStage: heros[0].colorStarStage
}
return resResult(STATUS.SUCCESS, {isUpStar, curHero});
}
//训练
async heroJobTrain (msg: {hid:number}, session: BackendSession) {
let roleId: string = session.get('roleId');
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 heroJob = getJobInfoById(hero.job);
let nextHeroJob = getJobByGradeAndClass(heroJob.job_class, heroJob.grade + 1);
if (nextHeroJob.unlockLevel > hero.lv)
return resResult(STATUS.NOT_REACH_UNLOCK_LEVEL);
if (hero.jobStage >= 6)
return resResult(STATUS.HERO_JOB_STAGE_REACH_MAX_STAGE);
if (hero.job >= getMaxGradeByjobClass(heroJob.job_class))
return resResult(STATUS.HERO_JOB_REACH_MAX_STAGE);
let cousumeGoods = getItems(heroJob.trainingConsume);
let result = await handleCost(roleId, sid, cousumeGoods);
if(!result) {
return resResult(STATUS.BATTLE_CONSUMES_NOT_ENOUGH);
}
hero.jobStage = hero.jobStage ++;
//重算战力并下发
let heros = await calPlayerCeAndSave(sid, roleId, [hero]);
return resResult(STATUS.SUCCESS, { hid : heros[0].hid, job : heros[0].job, jobStage : heros[0].jobStage});
}
//进阶
async heroJobStageUp(msg: {hid:number}, session: BackendSession) {
let roleId: string = session.get('roleId');
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 heroJob = getJobInfoById(hero.job);
let nextHeroJob = getJobByGradeAndClass(heroJob.job_class, heroJob.grade + 1);
if (nextHeroJob.unlockLevel > hero.lv)
return resResult(STATUS.NOT_REACH_UNLOCK_LEVEL);
if (hero.job >= getMaxGradeByjobClass(heroJob.job_class))
return resResult(STATUS.HERO_JOB_REACH_MAX_STAGE);
let cousumeGoods = getItems(heroJob.upGradeConsume);
let result = await handleCost(roleId, sid, cousumeGoods);
if(!result) {
return resResult(STATUS.BATTLE_CONSUMES_NOT_ENOUGH);
}
hero.job = nextHeroJob.jobid;
hero.jobStage = 0;
//重算战力并下发
let heros = await calPlayerCeAndSave(sid, roleId, [hero]);
return resResult(STATUS.SUCCESS, { hid : heros[0].hid, job : heros[0].job, jobStage : heros[0].jobStage});
}
//激活羁绊
async heroConectionActivate(msg: {hid:number, id:number}, session: BackendSession) {
let roleId: string = session.get('roleId');
let sid: string = session.get('sid');
let { hid, id } = msg;
let friendShip = getFriendShipById(id);
if (!friendShip)
return resResult(STATUS.HERO_CONECTION_IS_EXIT);
if (friendShip.actorId != hid)
return resResult(STATUS.WRONG_PARMS);
let hero = await HeroModel.findByHidAndRole(hid, roleId);
if (!hero)
return resResult(STATUS.HERO_NOT_FIND);
if (!!_.findWhere(hero.conections, {id:id}))
return resResult(STATUS.HERO_CONECTION_IS_EXIT);
if (hero.star < friendShip.level)
return resResult(STATUS.NOT_REACH_UNLOCK_LEVEL);
let heroIds = friendShip.memberId.split('|');
for (let heroId of heroIds) {
let member = await HeroModel.findByHidAndRole(heroId, roleId);
if(!member)
return resResult(STATUS.HERO_NOT_FIND);
if (member.star < friendShip.level)
return resResult(STATUS.NOT_REACH_UNLOCK_LEVEL);
}
let result = await handleCost(roleId, sid, [{id: CURRENCY_BY_TYPE.get(CURRENCY_TYPE.COIN), count:5000}]);
if(!result) {
return resResult(STATUS.BATTLE_CONSUMES_NOT_ENOUGH);
}
hero.conections.push({
id : id
});
//重算战力并下发
let heros = await calPlayerCeAndSave(sid, roleId, [hero]);
return resResult(STATUS.SUCCESS, { hid : heros[0].hid, conections : heros[0].conections});
}
//赠送(包括一键赠送)
async heroGiveFavor(msg: {hid:number, items:Array<{id : number,count : number}>}, session: BackendSession) {
let roleId: string = session.get('roleId');
let sid: string = session.get('sid');
let { hid, items } = msg;
let hero = await HeroModel.findByHidAndRole(hid, roleId);
if (!hero)
return resResult(STATUS.HERO_NOT_FIND);
let friendShipLevels = getFriendShipLevels();
if (friendShipLevels[friendShipLevels.length - 1].level <= hero.favourLv)
return resResult(STATUS.HERO_FAVOUR_LEVEL_REACH_MAXT);
//计算消耗物品转化的经验
let exp:number = 0;
for (let item of items) {
let itemInfo = getGoodById(item.id);
if (itemInfo.itid == CONSUME_TYPE.FAVOUR) {
exp += itemInfo.value;
} else {
return resResult(STATUS.WRONG_PARMS);
}
}
hero.favour += exp;
for (let friendShipLevel of friendShipLevels) {
if (friendShipLevel.level < hero.favourLv)
continue;
if (friendShipLevel.exp > hero.favour)
break;
hero.favour -= friendShipLevel.exp;
hero.favourLv++;
}
let result = await handleCost(roleId, sid, items);
if(!result) {
return resResult(STATUS.BATTLE_CONSUMES_NOT_ENOUGH);
}
//重算战力并下发
let heros = await calPlayerCeAndSave(sid, roleId, [hero]);
return resResult(STATUS.SUCCESS, { hid : heros[0].hid, favour : heros[0].favour, favourLv : heros[0].favourLv});
}
//穿带时装
async heroWearSkin(msg: {id:number}, session: BackendSession) {
let roleId: string = session.get('roleId');
let sid: string = session.get('sid');
let { id } = msg;
let skinInfo = getFashionsById(id);
if (!skinInfo)
return resResult(STATUS.HERO_SKIN_NOT_FIND);
let hero = await HeroModel.findByHidAndRole(skinInfo.actorId, roleId);
if (!hero)
return resResult(STATUS.HERO_NOT_FIND);
let result = false;
for (let skin of hero.skins) {
if (skin.id == id) {
skin.enable = true;
result = true;
} else {
skin.enable = false;
}
}
if (!result) {
return resResult(STATUS.HERO_SKIN_NOT_FIND);
}
await calPlayerCeAndSave(sid, roleId, [hero]);
return resResult(STATUS.SUCCESS, { hid : hero.hid, skins : hero.skins});
}
}