武将:职业天赋接口

This commit is contained in:
陆莹
2022-03-22 20:46:17 +08:00
parent 3c24e54350
commit 5d0040b8a8
20 changed files with 2811 additions and 1199 deletions

View File

@@ -1,9 +1,9 @@
import { Application, BackendSession, ChannelService, HandlerService, } from 'pinus';
import { handleCost, addItems, unlockFigure, getCoinObject, getGoldObject } from '../../../services/role/rewardService';
import { calPlayerCeAndSave, calAllHeroCe } from '../../../services/playerCeService';
import { resResult, deepCopy, reduceCe } from '../../../pubUtils/util';
import { resResult, deepCopy, reduceCe, parseGoodStr } from '../../../pubUtils/util';
import { STATUS } from '../../../consts/statusCode';
import { HeroModel, Connect, HeroSkin, HeroUpdate, EPlace } from '../../../db/Hero';
import { HeroModel, Connect, HeroSkin, HeroUpdate, EPlace, Talent } 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';
@@ -16,10 +16,10 @@ import { PvpDefenseModel } from '../../../db/PvpDefense';
import { checkTask, checkTaskInHeroQUalityUp, checkTaskInHeroStarUp, checkTaskInHeroTrain, checkTaskInHeroWakeUp } from '../../../services/task/taskService';
import { isNumber, pick } from 'underscore';
import { updateEplaces } from '../../../services/equipService';
import { addConsumeToHero } from '../../../services/roleService';
import { addConsumeToHero, checkUnlockTalentCondition, initSkinTalent, updateSkinTalent } from '../../../services/roleService';
import { JewelModel, jewelUpdate } from '../../../db/Jewel';
import { CalHeroCe } from '../../../domain/roleField/calCe';
import { REBORN } from '../../../pubUtils/dicParam';
import { HERO, REBORN } from '../../../pubUtils/dicParam';
import { createHero, createHeroes } from '../../../services/role/createHero';
import { CheckMeterial } from '../../../services/role/checkMaterial';
@@ -685,6 +685,100 @@ export class HeroHandler {
return resResult(STATUS.SUCCESS, { curHero: { ...curHero, ce: reduceCe(curHero.ce) }, curJewels, goods });
}
// 解锁天赋
public async unlockTalent(msg: { hid: number, id: number }, session: BackendSession) {
let roleId = session.get('roleId');
let sid = session.get('sid');
let { hid, id } = msg;
let hero = await HeroModel.findByHidAndRole(hid, roleId);
if(!hero) return resResult(STATUS.HERO_NOT_FIND);
let dicHeroTalent = gameData.heroTalent.get(id);
if(!dicHeroTalent) return resResult(STATUS.WRONG_PARMS);
let skins = hero.skins||[];
let curSkin = skins.find(cur => cur.enable);
if(!curSkin) return resResult(STATUS.HERO_SKIN_NOT_FIND);
let talent = curSkin.talent.find(cur => cur.id == id);
if(talent) return resResult(STATUS.TALENT_HAS_UNLOCKED);
let usedTalentPoint = curSkin.usedTalentPoint;
if(!checkUnlockTalentCondition(hid, id, curSkin.talent, usedTalentPoint)) {
return resResult(STATUS.TALENT_CONDITION_NOT_FIT);
}
let totalTalentPoint = gameData.talentPointOfJob.get(hero.job);
let needTalentPoint = dicHeroTalent.level.find(cur => cur.lv == 1)?.cost||0;
if(totalTalentPoint - usedTalentPoint - needTalentPoint < 0) {
return resResult(STATUS.TALENT_POINT_NOT_ENOUGH);
}
let { newSkins, newTalents } = updateSkinTalent(skins, new Talent(id), usedTalentPoint + needTalentPoint);
hero = await calPlayerCeAndSave(HERO_SYSTEM_TYPE.TALENT, sid, roleId, hero, { skins: newSkins });
return resResult(STATUS.SUCCESS, { curHero: {...pick(hero, ['hid', 'skins', 'skinId']) }});
}
// 升级天赋
public async upgradeTalent(msg: { hid: number, id: number }, session: BackendSession) {
let roleId = session.get('roleId');
let sid = session.get('sid');
let { hid, id } = msg;
let hero = await HeroModel.findByHidAndRole(hid, roleId);
if(!hero) return resResult(STATUS.HERO_NOT_FIND);
let skins = hero.skins||[];
let curSkin = skins.find(cur => cur.enable);
if(!curSkin) return resResult(STATUS.HERO_SKIN_NOT_FIND);
let talent = curSkin.talent.find(cur => cur.id == id);
if(!talent) return resResult(STATUS.TALENT_NOT_UNLOCKED);
let dicHeroTalent = gameData.heroTalent.get(id);
if(!dicHeroTalent) return resResult(STATUS.WRONG_PARMS);
let usedTalentPoint = curSkin.usedTalentPoint;
let totalTalentPoint = gameData.talentPointOfJob.get(hero.job);
let nextLv = dicHeroTalent.level.find(cur => cur.lv == talent.level + 1);
if(!nextLv) return resResult(STATUS.TALENT_LEVEL_MAX);
let needTalentPoint = nextLv.cost||0;
if(totalTalentPoint - usedTalentPoint - needTalentPoint < 0) {
return resResult(STATUS.TALENT_POINT_NOT_ENOUGH);
}
let { newSkins, newTalents } = updateSkinTalent(skins, new Talent(id, talent.level + 1), usedTalentPoint + needTalentPoint);
hero = await calPlayerCeAndSave(HERO_SYSTEM_TYPE.TALENT, sid, roleId, hero, { skins: newSkins });
return resResult(STATUS.SUCCESS, { curHero: {...pick(hero, ['hid', 'skins', 'skinId']) }});
}
// 洗点
public async resetTalent(msg: { hid: number }, session: BackendSession) {
let roleId = session.get('roleId');
let sid = session.get('sid');
let { hid } = msg;
let hero = await HeroModel.findByHidAndRole(hid, roleId);
if(!hero) return resResult(STATUS.HERO_NOT_FIND);
let skins = hero.skins||[];
let curSkin = skins.find(cur => cur.enable);
if(!curSkin) return resResult(STATUS.HERO_SKIN_NOT_FIND);
let costItem = parseGoodStr(HERO.HERO_TALENTPOINT_RESET);
let consumeResult = await handleCost(roleId, sid, costItem, ITEM_CHANGE_REASON.RESET_TALENT);
if(!consumeResult) return resResult(STATUS.ROLE_MATERIAL_NOT_ENOUGH);
let newSkins = initSkinTalent(skins);
hero = await calPlayerCeAndSave(HERO_SYSTEM_TYPE.TALENT, sid, roleId, hero, { skins: newSkins });
return resResult(STATUS.SUCCESS, { curHero: {...pick(hero, ['hid', 'skins', 'skinId']) }});
}
// ! debug接口 一键全武将
public async debugGetAllHeroes(msg: { magicWord: string }, session: BackendSession) {
let roleId: string = session.get('roleId');

View File

@@ -127,8 +127,6 @@ export class CreateHeroes extends UpdateHeroes {
private resultHeroes: HeroType[] = [];
private heroNum = 0;
// 推送信息
private taskPushMessage: TaskListReturn[] = [];
private activityTaskPushMessage = [];
private figureInfos: { heads: Figure[], frames: Figure[], spines: Figure[] }[] = [];
private skinPushMessages: { heros: {skins: HeroSkin[], hid: number}[], skins: {id: number, hid: number, inc: number, reason: number }[]} = { heros: [], skins: [] };
@@ -138,9 +136,9 @@ export class CreateHeroes extends UpdateHeroes {
let skinInfos = skin.map(cur => ({ id: cur.id, hid, inc: 1, reason: ITEM_CHANGE_REASON.GET_HERO_UNLOCK_SKIN}))
this.skinPushMessages.skins.push(...skinInfos);
if(skin) allSkins.push(...skin);
let skins: { id: number, skin: string, enable: boolean, skinId: number }[] = [];
let skins: HeroSkin[] = [];
for(let skin of allSkins) {
skins.push({ id: skin.id, skin: skin._id, enable: skin.id == initSkinInfo.id, skinId: skin.skinId });
skins.push(new HeroSkin(skin.id, skin.skinId, skin._id, skin.id == initSkinInfo.id));
}
return skins
}

View File

@@ -1,5 +1,5 @@
import { DEFAULT_HEROES, DEFAULT_HERO_LV, FIGURE_UNLOCK_CONDITION, HERO_SYSTEM_TYPE, LINEUP_NUM } from "../../consts";
import { HeroModel, HeroUpdate } from "../../db/Hero";
import { HeroModel, HeroSkin, HeroUpdate } from "../../db/Hero";
import { RoleModel, RoleUpdate } from "../../db/Role";
import { SkinModel, SkinUpdate } from "../../db/Skin";
import { TopHero } from "../../domain/dbGeneral";
@@ -29,7 +29,7 @@ export function getInitRoleInfo() {
initSkins.push(skinInfo);
// 武将
let hero = new HeroModel();
let heroInfo = {...hero.toJSON(), hid, star, quality, hName, job, skins: [{ id: initialSkin, skin: skinInfo._id, enable: true, skinId: skinInfo.skinId }], skinId: skinInfo.skinId, lv: DEFAULT_HERO_LV, exp: getHeroExpByLv(DEFAULT_HERO_LV - 1) || 0 };
let heroInfo = {...hero.toJSON(), hid, star, quality, hName, job, skins: [new HeroSkin(initialSkin, skinInfo.skinId, skinInfo._id, true)], skinId: skinInfo.skinId, lv: DEFAULT_HERO_LV, exp: getHeroExpByLv(DEFAULT_HERO_LV - 1) || 0 };
let calHeroCe = new CalHeroCe(hid, heroInfo);
let heroAttr = calHeroCe.cal(HERO_SYSTEM_TYPE.INIT);
let ce = calHeroCe.getCalculatedCe(roleAttr);

View File

@@ -367,7 +367,7 @@ export async function addSkin(roleId: string, roleName: string, sid: string, ski
if (hero) { // 有武将的,将皮肤链接到武将上
let curSkin = hero.skins.find(cur => cur.id == skinId);
if (!curSkin) {
hero.skins.push({ id: skinId, skin: skin._id, enable, skinId: skin.skinId });
hero.skins.push(new HeroSkin(skin.id, skin.skinId, skin._id, enable ));
await HeroModel.updateHeroInfo(roleId, hero.hid, hero);
}
return hero;

View File

@@ -1,14 +1,14 @@
import { ChannelUser } from './../domain/ChannelUser';
import { Channel, pinus } from 'pinus';
import { getRandValueByMinMax, getRandEelm, decodeIdCntArrayStr } from '../pubUtils/util';
import { DEFAULT_HEROES, ROLE_SELECT, TERAPH_RANDOM } from "../consts";
import { DEFAULT_HEROES, ROLE_SELECT, TALENT_RELATION_TYPE, TERAPH_RANDOM } from "../consts";
import { DicTeraph } from '../pubUtils/dictionary/DicTeraph';
import { Teraph, RoleModel, RoleType, RoleUpdate } from '../db/Role';
import { SCHOOL } from '../pubUtils/dicParam';
import { gameData } from '../pubUtils/data';
import { gameData, getHeroInitTalent } from '../pubUtils/data';
import { SchoolModel } from '../db/School';
import { SclResultInter, SclPosInter, RewardInter, ItemInter } from '../pubUtils/interface';
import { HeroUpdate } from '../db/Hero';
import { HeroSkin, HeroUpdate, Talent } from '../db/Hero';
import { SkinUpdate } from '../db/Skin';
import { Figure } from '../domain/dbGeneral';
import { pick } from 'underscore';
@@ -172,4 +172,83 @@ export function addConsumeToHero(oldConsume: Reward[] = [], consumes: ItemInter[
newConsume.push({ id, count });
}
return newConsume;
}
export function checkUnlockTalentCondition(hid: number, id: number, talents: Talent[], usedTalentPoint: number) {
let dicHero = gameData.hero.get(hid);
let dicHeroTalent = gameData.heroTalent.get(id);
if(!dicHeroTalent) return false;
if(dicHero.talentId != dicHeroTalent.talentId) return false;
// 累计消耗n点天赋点
if(dicHeroTalent.preTotalPoint > usedTalentPoint) return false;
// 互斥的天赋没有被解锁
for(let { type, ids } of dicHeroTalent.relation) {
if(type == TALENT_RELATION_TYPE.CONFLICT) {
let hasTalent = talents.find(talent => ids.indexOf(talent.id) != -1);
if(hasTalent) return false;
}
}
// 前置节点
let orFlag = false; // 只要其中一个满足就可以
let maxPrecost = 0; // 前置节点最多的消耗
for(let arr of dicHeroTalent.prepositionId) {
let andFlag = true; // arr内所有节点都需要满足
for(let id of arr) {
let curTalent = talents.find(cur => cur.id == id);
if(curTalent) {
let dic = gameData.heroTalent.get(id);
if(dic) {
let allCost = 0;
for(let { lv, cost } of dic.level) {
if(curTalent.level >= lv) allCost += cost;
}
if(allCost > maxPrecost) maxPrecost = allCost;
}
} else {
andFlag = false;
}
}
if(andFlag) orFlag = true;
}
if(!orFlag) return false;
// 在前置节点中消耗至少n点天赋点在有多个前置节点时取最高的1个
if(dicHeroTalent.preSinglePoint > maxPrecost) return false;
return true;
}
export function updateSkinTalent(skins: HeroSkin[], newTalent: Talent, usedTalentPoint: number) {
let newSkins: HeroSkin[] = [];
let newTalents: Talent[] = [];
for(let skin of skins) {
if(skin.enable) {
let hasNewTalent = false;
for(let talent of skin.talent) {
if(talent.id == newTalent.id) {
newTalents.push(newTalent);
hasNewTalent = true;
} else {
newTalents.push(talent);
}
}
if(!hasNewTalent) newTalents.push(newTalent);
newSkins.push({...skin, talent: newTalents, usedTalentPoint })
} else {
newSkins.push(skin);
}
}
return { newSkins, newTalents };
}
export function initSkinTalent(skins: HeroSkin[]) {
let newSkins: HeroSkin[] = [];
for(let skin of skins) {
if(skin.enable) {
newSkins.push({ ...skin, talent: getHeroInitTalent(skin.skinId), usedTalentPoint: 0 });
} else {
newSkins.push(skin);
}
}
return newSkins
}