diff --git a/game-server/app/servers/role/handler/heroHandler.ts b/game-server/app/servers/role/handler/heroHandler.ts index ee42d0f0a..44bb3cdab 100644 --- a/game-server/app/servers/role/handler/heroHandler.ts +++ b/game-server/app/servers/role/handler/heroHandler.ts @@ -7,7 +7,7 @@ import { HeroModel, Connect, HeroSkin, HeroUpdate, EPlace } from '../../../db/He 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, getEquipByJobClassAndEPlace } from '../../../pubUtils/data'; +import { gameData, getHeroExpByLv, getHeroStarByQuality, getHeroWakeByQuality, getHeroLvByExp, getMaxGradeByjobClass, getJobByGradeAndClass, getFriendShipById, getFavourLvByExp, reloadDicParam, getEquipByJobClassAndEPlace, getScollByStar } 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'; @@ -17,7 +17,10 @@ import { checkTaskWithHero, checkTask, checkActivityTask } from '../../../servic import { pick } from 'underscore'; import { updateEplaces } from '../../../services/equipService'; import { addConsumeToHero } from '../../../services/roleService'; -import { getCoinObject } from '../../../pubUtils/itemUtils'; +import { getCoinObject, getGoldObject } from '../../../pubUtils/itemUtils'; +import { JewelModel, jewelUpdate } from '../../../db/Jewel'; +import { CalHeroCe } from '../../../domain/roleField/calCe'; +import { REBORN } from '../../../pubUtils/dicParam'; export default function (app: Application) { new HandlerService(app, {}); @@ -629,6 +632,68 @@ export class HeroHandler { return resResult(STATUS.SUCCESS, { curHero: {...pick(hero, ['hid', 'skins', 'skinId', 'job']), ePlace: newEplace }}); } + public async previewRebirth(msg: { hid: number }, session: BackendSession) { + let roleId: string = session.get('roleId'); + let { hid } = msg; + + let hero = await HeroModel.findByHidAndRole(hid, roleId, 'consumes'); + if(!hero) return resResult(STATUS.HERO_NOT_FIND); + let consumes = hero.consumes||[]; + + return resResult(STATUS.SUCCESS, { previewGoods: consumes }); + } + + public async rebirth(msg: { hid: number }, session: BackendSession) { + let roleId: string = session.get('roleId'); + let roleName: string = session.get('roleName'); + 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 cost = [getGoldObject(REBORN.REBORON_HERO)]; + let costResult = await handleCost(roleId, sid, cost, ITEM_CHANGE_REASON.REBIRTH); + if(!costResult) return resResult(STATUS.BATTLE_GOLD_NOT_ENOUGH); + + // 皮肤处理 + let { skins, skinId, consumes, ce } = hero; + let dicHero = gameData.hero.get(skinId); + let dicJob = getJobByGradeAndClass(dicHero.jobClass, 0); + + let dicHeroScroll = getScollByStar(dicHero.quality, dicHero.initialStars, dicHero.quality, 0); + let initInfo = HeroModel.getInitInfo({ + job: dicJob.jobid, skins, skinId, ce, + star: dicHero.initialStars, quality: dicHero.quality, + scrollActive: true, scrollId: dicHeroScroll.id, scrollStar: dicHeroScroll.stars, scrollQuality: dicHeroScroll.quality, scrollColorStar: dicHeroScroll.colorstars + }); + let calHeroCe = new CalHeroCe(hid, initInfo); + let heroAttr = calHeroCe.cal(HERO_SYSTEM_TYPE.REBIRTH); + await HeroModel.updateHeroInfo(roleId, hid, { ...initInfo, attr: heroAttr }); + + // 天晶石 + let curJewels: jewelUpdate[] = []; + for(let { jewel, id } of hero.ePlace) { + if(jewel > 0) { + let jewelInfo = await JewelModel.putOnOrOff(jewel, hid, id); + curJewels.push({ + seqId: jewelInfo.seqId, + id: jewelInfo.id, + hid: jewelInfo.hid, + }); + } + } + + let { heros } = await calAllHeroCe(HERO_SYSTEM_TYPE.REBIRTH, sid, roleId, {}, [hid], { originHero: hero, heroUpdate: initInfo }); + let curHeo = heros.find(cur => cur.hid == hid); + + let goods = await addItems(roleId, roleName, sid, consumes, ITEM_CHANGE_REASON.REBIRTH); + + return resResult(STATUS.SUCCESS, { curHeo, curJewels, goods }); + } + // ! debug接口 一键全武将 public async debugGetAllHeroes(msg: { magicWord: string }, session: BackendSession) { let roleId: string = session.get('roleId'); diff --git a/game-server/app/services/playerCeService.ts b/game-server/app/services/playerCeService.ts index 25af0dcdf..7e934c156 100644 --- a/game-server/app/services/playerCeService.ts +++ b/game-server/app/services/playerCeService.ts @@ -47,8 +47,8 @@ export async function pushCalPlayerCe(roleId: string, sid: string, calResult: ca } // 修改全局战力并下发 -export async function calAllHeroCe(type:number, sid: string, roleId: string, update: RoleUpdate, args?:Array) { - let result = await reCalAllHeroCe(type, roleId, update, args); +export async function calAllHeroCe(type:number, sid: string, roleId: string, update: RoleUpdate, args?:Array, params?: any) { + let result = await reCalAllHeroCe(type, roleId, update, args, params); if(result.pushHeros.length > 0) { return await pushCalAllHeroCe(roleId, sid, result); } else { diff --git a/shared/consts/constModules/heroConst.ts b/shared/consts/constModules/heroConst.ts index 49214b332..3210e752d 100644 --- a/shared/consts/constModules/heroConst.ts +++ b/shared/consts/constModules/heroConst.ts @@ -29,6 +29,7 @@ export enum HERO_SYSTEM_TYPE { EQUIP_STONE = 26, // 装备装上or卸下地玉石 JEWEL_RESET_RANDSE = 27, // 天晶石洗练 JEWEL_QUENCH = 28, // 天晶石淬炼 + REBIRTH = 29, // 武将重生 }; // 武将上限 diff --git a/shared/consts/constModules/sysConst.ts b/shared/consts/constModules/sysConst.ts index 57fbe8773..c279d7a21 100644 --- a/shared/consts/constModules/sysConst.ts +++ b/shared/consts/constModules/sysConst.ts @@ -959,6 +959,7 @@ export enum ITEM_CHANGE_REASON { EQUIP_QUALITYUP = 137, // 装备升品 EQUIP_STARUP = 138, // 装备升星 COMPOSE_STONE = 139, // 合成地玉石 + REBIRTH = 140, // 武将重生 } export enum TA_EVENT { diff --git a/shared/db/Hero.ts b/shared/db/Hero.ts index d7896f567..723967d0f 100644 --- a/shared/db/Hero.ts +++ b/shared/db/Hero.ts @@ -248,11 +248,16 @@ export default class Hero extends BaseModel { return hero; } - public static async createHero(heroInfo: HeroUpdate, lean = true) { + public static getInitInfo(heroInfo: HeroUpdate = {}): HeroUpdate { const doc = new HeroModel(); - const seqId = await CounterModel.getNewCounter(COUNTER.HID) || -1; - const update = Object.assign(doc.toJSON(), heroInfo, { seqId }); + const update = { ...doc.toJSON(), ...heroInfo}; delete update._id; + return update + } + + public static async createHero(heroInfo: HeroUpdate, lean = true) { + const seqId = await CounterModel.getNewCounter(COUNTER.HID) || -1; + const update = this.getInitInfo({ ...heroInfo, seqId }); const hero: HeroType = await HeroModel.findOneAndUpdate({ roleId: heroInfo.roleId, hid: heroInfo.hid }, update, { upsert: true, new: true }).lean(lean); return hero; } diff --git a/shared/domain/roleField/calCe.ts b/shared/domain/roleField/calCe.ts index 2921b3b1e..585f219e9 100644 --- a/shared/domain/roleField/calCe.ts +++ b/shared/domain/roleField/calCe.ts @@ -92,6 +92,7 @@ export class CalHeroCe { public cal(type: HERO_SYSTEM_TYPE) { switch (type) { case HERO_SYSTEM_TYPE.INIT: + case HERO_SYSTEM_TYPE.REBIRTH: this.calBaseAbility(); this.calSkinSeid(); this.calJobAbility(); diff --git a/shared/pubUtils/dicParam.ts b/shared/pubUtils/dicParam.ts index 8c98f2156..84fc5a31d 100644 --- a/shared/pubUtils/dicParam.ts +++ b/shared/pubUtils/dicParam.ts @@ -1,14 +1,11 @@ export const EQUIP = { - EQUIP_ONE_HOLE: '17043&1', // 装备孔1号位消耗 - EQUIP_TWO_HOLE: '17043&2', // 装备孔2号位消耗 - EQUIP_THREE_HOLE: '17043&4', // 装备孔3号位消耗 - EQUIP_ONE_REFORGED: '17044&1', // 装备位洗练四条词条消耗 - EQUIP_TWO_REFORGED: '17044&2', // 装备位洗练三条词条消耗 - EQUIP_THREE_REFORGED: '17044&4', // 装备位洗练二条词条消耗 - EQUIP_FOUR_REFORGED: '17044&8', // 装备位洗练一条词条消耗 - EQUIP_ONE_LOCKED: '17045&1', // 装备锁定第一条词条锁消耗 - EQUIP_TWO_LOCKED: '17045&2', // 装备锁定第二条词条锁消耗 - EQUIP_THREE_LOCKED: '17045&4', // 装备锁定第三条词条锁消耗 + EQUIP_ONE_REFORGED: '17044&1', // 天晶无锁定词条洗炼消耗 + EQUIP_TWO_REFORGED: '17044&2', // 天晶锁定1条词条洗炼消耗 + EQUIP_THREE_REFORGED: '17044&4', // 天晶锁定2条词条洗炼消耗 + EQUIP_FOUR_REFORGED: '17044&8', // 天晶锁定3条词条洗炼消耗 + EQUIP_ONE_LOCKED: '17045&1', // 天晶锁定第一条词条锁消耗 + EQUIP_TWO_LOCKED: '17045&2', // 天晶锁定第二条词条锁消耗 + EQUIP_THREE_LOCKED: '17045&4', // 天晶锁定第三条词条锁消耗 EQUIP_LEVEL_LOCKED: '1&1|2&1|3&20|4&41|5&61', // 装备养成功能玩家等级解锁限制 }; export const JOB = { @@ -18,8 +15,8 @@ export const JOB = { JOB_CLASS_4: '弓兵', // 大兵种名称 JOB_CLASS_5: '游侠', // 大兵种名称 JOB_CLASS_6: '策士', // 大兵种名称 - JOB_CLASS_7: '道士', // 大兵种名称 - JOB_CLASS_8: '医者', // 大兵种名称 + JOB_CLASS_7: '医者', // 大兵种名称 + JOB_CLASS_8: '道士', // 大兵种名称 }; export const SCHOOL = { SCHOOL_POSITION: '1&1|2&1|3&1|4&0|5&0', // 百家学宫位置锁定 @@ -99,7 +96,7 @@ export const CHAT_SYSTEM = { export const GUILDACTIVITY = { GATEACTIVITY_CHALLENGE_TIMES: 1, // 蛮夷入侵每天可以挑战次的次数 GATEACTIVITY_HONOUR_RATIO: 0.5, // 功勋/积分的系数 - GATEACTIVITY_ENEMYCE: 2000, // 蛮夷入侵敌军2000战力模板 + GATEACTIVITY_ENEMYCE: 10000, // 敌军10000战力基础属性模板 GATEACTIVITY_ROUNDSTANDARD: 20, // 蛮夷入侵和基准战力相当的回合 CITYACTIVITY_CHALLENGE_CD: 300, // 诸侯混战每次战斗之后的cd间隔 CITYACTIVITY_CD_COST: 100, // 诸侯混战取消cd需要消耗的元宝数 @@ -110,11 +107,12 @@ export const GUILDACTIVITY = { GATEACTIVITY_GATEHP: 2000000, // 城门血量 GATEACTIVITY_BOSS_DIFFICULT: '1&1.2|2&1.5', // boss类型&难度系数|boss类型&难度系数(1:小boss,2:大boss) RACEACTIVITY_DURABILITY_REWARD: 2, // 每剩余1%耐久度给予X点功勋 - RACEACTIVITY_NORMAL_ITEMS: '1&8&15|3&5&10|5&0&1', // 粮草先行普通道具 + RACEACTIVITY_NORMAL_ITEMS: '1&50&5|3&70&10|5&100&15', // 粮草先行普通道具 RACEACTIVITY_EVENT_MEMBERCNT: 3, // 粮草先行随机道具获得人数 RACEACTIVITY_EVENT_ITEMS: '2&1|4&1|6&1', // 粮草先行根据事件随机人可获得道具 RACE_INIT_SPEED: 3, // 粮草先行军团初始速度 RACE_PER_SPEED: 0.1, // 粮草先行军团每人参加增速 + GATEACTIVITY_GATEHP_N: 20, // 城门血量倍率 }; export const GUILD_AUCTION = { DIVIDEND_RATE: 1, // 总金额分红比例,1表示总金额 100% 分红 @@ -254,3 +252,6 @@ export const BATTLE_SPEED = { export const LINK = { OUT_LINK: 'https://www.wjx.cn/vj/OSxaldE.aspx', // 外链 }; +export const REBORN = { + REBORON_HERO: 500, // 武将重生元宝数量 +}; diff --git a/shared/pubUtils/playerCe.ts b/shared/pubUtils/playerCe.ts index 02f763f03..400f8f80e 100644 --- a/shared/pubUtils/playerCe.ts +++ b/shared/pubUtils/playerCe.ts @@ -61,11 +61,11 @@ export async function calPlayerCeAndSave(type: number, roleId: string, originHer } //全局属性加成 -export async function reCalAllHeroCe(type: number, roleId: string, update: RoleUpdate, args?: Array) { +export async function reCalAllHeroCe(type: number, roleId: string, update: RoleUpdate, args?: Array, params?: any) { let role = await RoleModel.findByRoleId(roleId); let heros = await HeroModel.findByRole(roleId); - let roleAttrs = await reCalRoleAttr(type, heros, role, update, args); + let roleAttrs = await reCalRoleAttr(type, heros, role, update, args, params); if(!roleAttrs) return {role, pushHeros: [], ce: role.ce, topLineupCe: role.topLineupCe, serverId: role.serverId, heros }; // 无加成 let pushHeros = new Array<{ hid: number, ce: number, incHeroCe: number }>(); @@ -105,7 +105,7 @@ export async function reCalAllHeroCe(type: number, roleId: string, update: RoleU } // 计算武将全局战力 -async function reCalRoleAttr(type: number, heros: Array, role: RoleType, update: RoleUpdate, args: Array) { +async function reCalRoleAttr(type: number, heros: Array, role: RoleType, update: RoleUpdate, args: Array, params: any) { let { attr: roleAttrs } = role; switch (type) { case HERO_SYSTEM_TYPE.ADD_SKIN: @@ -131,6 +131,9 @@ async function reCalRoleAttr(type: number, heros: Array, role: RoleTyp case HERO_SYSTEM_TYPE.TERAPH_UP: roleAttrs = calTeraphAssistAttr(role, update, args[0]); break; + case HERO_SYSTEM_TYPE.REBIRTH: + roleAttrs = await calHeroRebirth(role, params.originHero, params.heroUpdate); + break; } return roleAttrs; @@ -1062,5 +1065,45 @@ function calTeraphAssistAttr(role: RoleType, update: RoleUpdate, id: number) { let fixUp = (val - oldVal) * HERO_CE_RATIO; updateRoleAttr(roleAttrs, attrId, { inc: { fixUp } }); }); + return roleAttrs; +} + +async function calHeroRebirth(role: RoleType, originHero: HeroType, updateHero: HeroUpdate) { + let { roleId, attr: roleAttrs } = role; + // 1. 名将谱 + let dicHero = gameData.hero.get(originHero.hid); + let dicHeroScroll = getScollByStar(dicHero.quality, updateHero.star, updateHero.quality, updateHero.colorStar); + let dicPreScroll = getScollByStar(dicHero.quality, originHero.star, originHero.quality, originHero.colorStar); + + if(dicHeroScroll) { + for(let [attrId, value] of dicHeroScroll.ceAttr) { + updateRoleAttr(roleAttrs, attrId, { inc: { fixUp: value * HERO_CE_RATIO } }); + } + } + if(dicPreScroll) { + for(let [attrId, value] of dicPreScroll.ceAttr) { + updateRoleAttr(roleAttrs, attrId, { inc: { fixUp: -value * HERO_CE_RATIO } }); + } + } + + // 2. 百家学宫 + let school = await SchoolModel.findByHid(roleId, originHero.hid); + if(school) { + let dicSchool = gameData.school.get(school.schoolId); + let preRate = getSchoolRateByStar(originHero.star, originHero.colorStar, originHero.quality); + let curRate = getSchoolRateByStar(updateHero.star, updateHero.colorStar, updateHero.quality); + console.log('####', updateHero.star, updateHero.colorStar, updateHero.quality) + + for (let attrId of dicSchool.upAttribute) { + if(ABI_TYPE_MAIN.includes(attrId)) { // 主属性 + let ratioUp = (curRate?.mainAttrAPerent||0) - (preRate?.mainAttrAPerent||0); + updateRoleAttr(roleAttrs, attrId, { inc: { ratioUp } }); + } else { + let fixUp = ((curRate?.assiAttrAddValue||0) - (preRate?.assiAttrAddValue||0)) * HERO_CE_RATIO; + updateRoleAttr(roleAttrs, attrId, { inc: { fixUp } }); + } + } + } + return roleAttrs; } \ No newline at end of file