武将:职业天赋接口
This commit is contained in:
@@ -5,7 +5,7 @@ import { dicEvent, dicEventList, loadEvent } from "./dictionary/DicEvent";
|
||||
import { dicExpedition, DicExpedition, loadExpedition } from "./dictionary/DicExpedition";
|
||||
import { dicExpeditionPoint, loadExpeditionPoint } from "./dictionary/DicExpeditionPoint";
|
||||
import { dicHeroSkill, loadHeroSkill } from "./dictionary/DicHeroSkill";
|
||||
import { dicJob, jobClassAndgrades, jobClassMaxGrades, loadJob } from "./dictionary/DicJob";
|
||||
import { dicJob, jobClassAndgrades, jobClassMaxGrades, loadJob, talentPointOfJob } from "./dictionary/DicJob";
|
||||
import { dicKingExp, maxPlayerLv, loadKingExp } from "./dictionary/DicKingExp";
|
||||
import { dicCharExp, loadCharExp } from "./dictionary/DicCharExp";
|
||||
import { dicQuestion, loadQuestion } from "./dictionary/DicQuestion";
|
||||
@@ -101,6 +101,8 @@ import { dicEquipQualityExtra, loadEquipQualityExtra } from './dictionary/DicEqu
|
||||
import { dicEquipSuit, dicEquipSuitByJobClass, loadEquipSuit } from "./dictionary/DicEquipSuit";
|
||||
import { dicJewelCondition, loadJewelCondition } from './dictionary/DicJewelCondition';
|
||||
import { dicMainStarBox, dicMainStarBoxByChapter, loadMainStarBox } from './dictionary/DicMainStarBox';
|
||||
import { dicHeroTalent, initTalents, loadHeroTalent } from './dictionary/DicHeroTalent';
|
||||
import { Talent } from "../db/Hero";
|
||||
|
||||
export const gameData = {
|
||||
daily: dicDaily,
|
||||
@@ -252,6 +254,9 @@ export const gameData = {
|
||||
heroIdByWar: dicHeroIdByWar,
|
||||
mainBox: dicMainStarBox,
|
||||
mainBoxByChapter: dicMainStarBoxByChapter,
|
||||
heroTalent: dicHeroTalent,
|
||||
initTalents: initTalents,
|
||||
talentPointOfJob: talentPointOfJob,
|
||||
};
|
||||
|
||||
// 在此提供一些原先在gamedata中提供的方法,以便更方便获取gameData数据
|
||||
@@ -869,6 +874,14 @@ export function getRandEffectByGroupAndLevel(group: number, level: number) {
|
||||
return gameData.randomEffectPool.get(id);
|
||||
}
|
||||
|
||||
// 根据皮肤获得他的初始天赋id
|
||||
export function getHeroInitTalent(skinId: number) {
|
||||
let dicHero = gameData.hero.get(skinId);
|
||||
if(!dicHero) return [];
|
||||
let ids = gameData.initTalents.get(dicHero.talentId)||[];
|
||||
return ids.map(id => (new Talent(id)));
|
||||
}
|
||||
|
||||
// 初始加载
|
||||
function initDatas() {
|
||||
parseDicParam();
|
||||
@@ -1035,6 +1048,7 @@ function loadDatas() {
|
||||
loadStone();
|
||||
loadJewelCondition();
|
||||
loadMainStarBox();
|
||||
loadHeroTalent();
|
||||
}
|
||||
|
||||
// 重载dicParam
|
||||
|
||||
@@ -86,8 +86,8 @@ export const EXTERIOR = {
|
||||
EXTERIOR_APPEARANCE: 11419, // 默认形象id
|
||||
};
|
||||
export const HTTPMANAGE = {
|
||||
ADDRESSTYPE: 1, // 1:开发服(dev),2:正式服(official),3:测试服(alpha),4:版号服(isbn) 5: 37测试服(sq1)
|
||||
SERVERTYPE: 2, // ADDRESSTYPE下服务器的筛选:1:正式服(official),2:开发服(develop) 3. 测试服(alpha)
|
||||
ADDRESSTYPE: 3, // 1:开发服(dev),2:正式服(official),3:测试服(alpha),4:版号服(isbn) 5: 37测试服(sq1)
|
||||
SERVERTYPE: 3, // ADDRESSTYPE下服务器的筛选:1:正式服(official),2:开发服(develop) 3. 测试服(alpha)
|
||||
};
|
||||
export const CHAT_SYSTEM = {
|
||||
RECENT_GROUP_MSGS_CNT: 10, // 群消息获取条数
|
||||
@@ -262,9 +262,15 @@ export const VIP = {
|
||||
VIP_TOWER_TASK_CAN_SEND_AT_ONCE_WITHOUT_VIP: 0, // 镇念没有月卡是否可以被一键悬赏
|
||||
VIP_TOWER_TASK_CAN_SEND_AT_ONCE_WITH_VIP: 1, // 镇念塔有月卡是否可以被一键悬赏
|
||||
VIP_TOWER_HUNG_UP_RATIO: 1.2, // 镇念塔挂机奖励加成倍率,在dic_zyz_tower的rewardOfcollect基础上直接乘以这个倍数
|
||||
VIP_REGRET_CNT_WITHOUT_VIP: 10, // 没有月卡时候的悔棋次数
|
||||
VIP_REGRET_CNT_WITH_VIP: 11, // 有月卡时候的悔棋次数
|
||||
VIP_REGRET_CNT_WITHOUT_VIP: 0, // 没有月卡时候的悔棋次数
|
||||
VIP_REGRET_CNT_WITH_VIP: 1, // 有月卡时候的悔棋次数
|
||||
VIP_PVP_CHALLENGE_COUNTS_ADD: 2, // pvp上限增加,如果有月卡,在PVP.PVP_CHALLENGE_COUNTS的基础上增加X次
|
||||
VIP_DAILY_TIMERS_PER_DAY_ADD: 2, // 每日任务免费次数增加,如果有月卡,在dic_daily的timesPerDay的基础上增加多少次
|
||||
VIP_DUNGEON_CONST_FREE_ADD: 2, // 秘境免费次数增加,如果有月卡,在DUNGEON_CONST.DUNGEON_CONST_FREE的基础上加多少次
|
||||
};
|
||||
export const PUBLIC_NOTICE_PERIOD = {
|
||||
PUBLIC_NOTICE_PERIOD_TIME: 24, // 活动公示期时间
|
||||
};
|
||||
export const HERO = {
|
||||
HERO_TALENTPOINT_RESET: '31002&100', // 天赋点重置花费
|
||||
};
|
||||
|
||||
@@ -33,10 +33,12 @@ export interface DicHero {
|
||||
readonly recruit: boolean;
|
||||
// 武将图标id
|
||||
readonly face_id: string;
|
||||
// 天赋树id
|
||||
readonly talentId: number;
|
||||
}
|
||||
|
||||
type KeysEnum<T> = { [P in keyof Required<T>]: true };
|
||||
const DicHeroKeys: KeysEnum<DicHero> = {heroId: true, name: true, quality: true, camp: true, jobClass: true, jobid: true, skill: true, pieceId: true, initialStars: true, pieceCount: true, baseAbilityArr: true, baseAbilityUpArr: true, initialSkin: true, recruit: true, face_id: true};
|
||||
const DicHeroKeys: KeysEnum<DicHero> = {heroId: true, name: true, quality: true, camp: true, jobClass: true, jobid: true, skill: true, pieceId: true, initialStars: true, pieceCount: true, baseAbilityArr: true, baseAbilityUpArr: true, initialSkin: true, recruit: true, face_id: true, talentId: true};
|
||||
export const dicHero = new Map<number, DicHero>();
|
||||
export function loadHero() {
|
||||
dicHero.clear();
|
||||
|
||||
81
shared/pubUtils/dictionary/DicHeroTalent.ts
Normal file
81
shared/pubUtils/dictionary/DicHeroTalent.ts
Normal file
@@ -0,0 +1,81 @@
|
||||
// 武将升星表
|
||||
import { decodeArrayListStr, parseNumberList, readFileAndParse } from '../util'
|
||||
import { FILENAME } from '../../consts';
|
||||
const _ = require('lodash');
|
||||
|
||||
export interface DicHeroTalent {
|
||||
// 唯一id
|
||||
readonly id: number;
|
||||
// 天赋组id
|
||||
readonly talentId: number;
|
||||
// 节点层数
|
||||
readonly nodeSort: number;
|
||||
// 和其他节点关系
|
||||
readonly relation: [{ type: number, ids?: number[] }];
|
||||
// 节点等级数
|
||||
readonly level: [{ lv: number, seid: number, cost: number }];
|
||||
// 前置节点
|
||||
readonly prepositionId: number[][];
|
||||
// 需要满足在天赋树中累计消耗n点天赋点
|
||||
readonly preTotalPoint: number;
|
||||
// 在前置节点中消耗至少n点天赋点(在有多个前置节点时,取最高的1个)
|
||||
readonly preSinglePoint: number;
|
||||
}
|
||||
|
||||
|
||||
type KeysEnum<T> = { [P in keyof Required<T>]: true };
|
||||
const DicHeroTalentKeys: KeysEnum<DicHeroTalent> = {id: true, talentId: true, nodeSort: true, relation: true, level: true, prepositionId: true, preTotalPoint: true, preSinglePoint: true};
|
||||
|
||||
export const dicHeroTalent = new Map<number, DicHeroTalent>();
|
||||
export const initTalents = new Map<number, number[]>();
|
||||
export function loadHeroTalent() {
|
||||
dicHeroTalent.clear();
|
||||
|
||||
let arr = readFileAndParse(FILENAME.DIC_HERO_TALENT);
|
||||
|
||||
arr.forEach(o => {
|
||||
o.relation = parseRelation(o.type, o.relationId);
|
||||
o.level = parseLevel(o.levelCount, o.levelSeid, o.levelConsume);
|
||||
o.prepositionId = parsePrePositionId(o.prepositionId);
|
||||
dicHeroTalent.set(o.id, _.pick(o, Object.keys(DicHeroTalentKeys)));
|
||||
if(o.prepositionId.length == 0 && o.levelConsume == '&') {
|
||||
if(!initTalents.has(o.talentId)) {
|
||||
initTalents.set(o.talentId, []);
|
||||
}
|
||||
initTalents.get(o.talentId).push(o.id);
|
||||
}
|
||||
});
|
||||
arr = undefined;
|
||||
}
|
||||
|
||||
function parseRelation(type: string, relationId: string) {
|
||||
let relation: {type: number, ids?: number[]}[] = [];
|
||||
let types = parseNumberList(type);
|
||||
let relations = decodeArrayListStr(relationId);
|
||||
for(let i = 0; i < types.length; i++) {
|
||||
if(relations[i]) {
|
||||
relation.push({
|
||||
type: types[i],
|
||||
ids: relations[i].map(id => parseInt(id))
|
||||
});
|
||||
}
|
||||
}
|
||||
return relation;
|
||||
}
|
||||
|
||||
function parseLevel(levelCount: number, levelSeid: string, levelConsume: string) {
|
||||
let levelSeids = parseNumberList(levelSeid);
|
||||
let levelConsumes = parseNumberList(levelConsume);
|
||||
let level: { lv: number, seid: number, cost: number }[] = [];
|
||||
for(let i = 0; i < levelCount; i++) {
|
||||
level.push({ lv: i + 1, seid: levelSeids[i]||0, cost: levelConsumes[i]||0});
|
||||
}
|
||||
return level;
|
||||
}
|
||||
|
||||
function parsePrePositionId(str: string) {
|
||||
let arr = decodeArrayListStr(str);
|
||||
return arr.map(arr1 => {
|
||||
return arr1.map(str => parseInt(str));
|
||||
});
|
||||
}
|
||||
@@ -17,8 +17,8 @@ export interface DicJob {
|
||||
readonly job_class: number;
|
||||
// 职业类别
|
||||
readonly type: number;
|
||||
// 特性
|
||||
readonly seid: Array<number>;
|
||||
// // 特性
|
||||
// readonly seid: Array<number>;
|
||||
// 训练消耗
|
||||
readonly trainingConsume: Array<RewardInter>;
|
||||
// 升阶消耗
|
||||
@@ -27,15 +27,17 @@ export interface DicJob {
|
||||
readonly ceAttr: Map<number, {id: number, attr: number}>;
|
||||
// 一共有多少阶升级
|
||||
readonly maxStage: number;
|
||||
|
||||
// 到这一阶能获得多少天赋点
|
||||
readonly talentPoint: number;
|
||||
}
|
||||
|
||||
type KeysEnum<T> = { [P in keyof Required<T>]: true };
|
||||
const DicJobKeys: KeysEnum<DicJob> = {jobid: true, name: true, grade: true, unlockLevel: true, job_class: true, type: true, seid: true,trainingConsume: true, upGradeConsume: true, ceAttr: true, maxStage: true};
|
||||
const DicJobKeys: KeysEnum<DicJob> = {jobid: true, name: true, grade: true, unlockLevel: true, job_class: true, type: true, trainingConsume: true, upGradeConsume: true, ceAttr: true, maxStage: true, talentPoint: true};
|
||||
|
||||
export const dicJob = new Map<number, DicJob>();
|
||||
export const jobClassMaxGrades = new Map<number, {grade:number, jobid:number}>();
|
||||
export const jobClassAndgrades = new Map<string, {jobid:number, unlockLevel:number}>();
|
||||
export const talentPointOfJob = new Map<number, number>();
|
||||
|
||||
export function loadJob() {
|
||||
dicJob.clear();
|
||||
@@ -43,6 +45,7 @@ export function loadJob() {
|
||||
jobClassAndgrades.clear();
|
||||
|
||||
let arr = readFileAndParse(FILENAME.DIC_JOB);
|
||||
let jobByJobClass = new Map<number, number[]>(); // jobClass => jobid[]
|
||||
|
||||
arr.forEach(o => {
|
||||
if(o.isPlayer) {
|
||||
@@ -56,9 +59,25 @@ export function loadJob() {
|
||||
if (!jobClass || jobClass.grade < o.grade) {
|
||||
jobClassMaxGrades.set(o.job_class, {grade: o.grade,jobid: o.jobid});
|
||||
}
|
||||
jobClassAndgrades.set(o.job_class+'_'+o.grade,{unlockLevel:o.unlockLevel, jobid:o.jobid});
|
||||
jobClassAndgrades.set(o.job_class+'_'+o.grade,{unlockLevel:o.unlockLevel, jobid:o.jobid});
|
||||
if(!jobByJobClass.has(o.job_class)) {
|
||||
jobByJobClass.set(o.job_class, []);
|
||||
}
|
||||
jobByJobClass.get(o.job_class).push(o.jobid);
|
||||
}
|
||||
});
|
||||
for(let [_, { job_class, talentPoint }] of dicJob) {
|
||||
let jobs = jobByJobClass.get(job_class)||[];
|
||||
for(let jobid of jobs) {
|
||||
if(!talentPointOfJob.has(jobid)) {
|
||||
talentPointOfJob.set(jobid, talentPoint);
|
||||
} else {
|
||||
talentPointOfJob.set(jobid, talentPointOfJob.get(jobid) + talentPoint);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
jobByJobClass = undefined;
|
||||
arr = undefined;
|
||||
}
|
||||
|
||||
|
||||
@@ -2,10 +2,10 @@
|
||||
* 体力系统
|
||||
*/
|
||||
|
||||
import { HERO_SYSTEM_TYPE, ABI_TYPE, HERO_CE_RATIO, LINEUP_NUM } from '../consts';
|
||||
import { HERO_SYSTEM_TYPE, ABI_TYPE, HERO_CE_RATIO, LINEUP_NUM, TALENT_RELATION_TYPE } from '../consts';
|
||||
|
||||
import { cal, deepCopy, getAllAttrStage, reduceCe } from './util';
|
||||
import { HeroModel, HeroType, HeroUpdate, CeAttrData, EPlace, Stone } from '../db/Hero';
|
||||
import { HeroModel, HeroType, HeroUpdate, CeAttrData, EPlace, Stone, Talent } from '../db/Hero';
|
||||
import { RoleModel, RoleType, RoleUpdate, CeAttrDataRole } from '../db/Role';
|
||||
import { AttributeCal } from '../domain/roleField/attribute';
|
||||
import { ABI_STAGE, SEID_TYPE } from '../consts';
|
||||
@@ -20,6 +20,7 @@ import { GuildModel } from '../db/Guild';
|
||||
import { DicJob } from './dictionary/DicJob';
|
||||
import { saveCeChangeLog } from './logUtil';
|
||||
import { JewelType } from '../db/Jewel';
|
||||
import { type } from 'os';
|
||||
|
||||
// 修改并下发战力
|
||||
export async function calPlayerCeAndSave(type: number, roleId: string, originHero: HeroType, update: HeroUpdate, args?: Array<number>, params?: any) {
|
||||
@@ -161,7 +162,7 @@ export async function calPlayerCe(hero: HeroType, update: HeroUpdate, type: numb
|
||||
heroAttrs = calHeroTrainIncAttr(hero, update);
|
||||
break;
|
||||
case HERO_SYSTEM_TYPE.STAGEUP:
|
||||
heroAttrs = calHeroJobStageUpIncAttr(hero, update, addSeidList, removeSeidList);
|
||||
// heroAttrs = calHeroJobStageUpIncAttr(hero, update, addSeidList, removeSeidList);
|
||||
break;
|
||||
case HERO_SYSTEM_TYPE.SKIN:
|
||||
heroAttrs = calHeroWearSkinIncAttr(hero, update, addSeidList, removeSeidList);
|
||||
@@ -197,6 +198,9 @@ export async function calPlayerCe(hero: HeroType, update: HeroUpdate, type: numb
|
||||
case HERO_SYSTEM_TYPE.SCROLL:
|
||||
heroAttrs = calHeroCeScrollIncAttr(hero, update);
|
||||
break;
|
||||
case HERO_SYSTEM_TYPE.TALENT:
|
||||
heroAttrs = calHeroTalent(hero, update, addSeidList, removeSeidList);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
@@ -460,29 +464,29 @@ export function calHeroTrainIncAttr(originHero: HeroType, update: HeroUpdate) {
|
||||
* @param {number[]} addSeidList 用于更新被动
|
||||
* @param {number[]} removeSeidList 用于更新被动
|
||||
*/
|
||||
export function calHeroJobStageUpIncAttr(originHero: HeroType, update: HeroUpdate, addSeidList: Array<number>, removeSeidList: Array<number>) {
|
||||
let { job: oldJob, attr: heroAttrs } = originHero;
|
||||
let { job = oldJob } = update;
|
||||
// export function calHeroJobStageUpIncAttr(originHero: HeroType, update: HeroUpdate, addSeidList: Array<number>, removeSeidList: Array<number>) {
|
||||
// let { job: oldJob, attr: heroAttrs } = originHero;
|
||||
// let { job = oldJob } = update;
|
||||
|
||||
let lastJob = gameData.job.get(oldJob);
|
||||
let currentJob = gameData.job.get(job);
|
||||
let lastSeids = lastJob?.seid||new Array<number>();
|
||||
let curSeids = currentJob?.seid||new Array<number>();
|
||||
// let lastJob = gameData.job.get(oldJob);
|
||||
// let currentJob = gameData.job.get(job);
|
||||
// let lastSeids = lastJob?.seid||new Array<number>();
|
||||
// let curSeids = currentJob?.seid||new Array<number>();
|
||||
|
||||
for (let seid of curSeids) {
|
||||
let index = findIndex(lastSeids, seid);
|
||||
if (index < 0) {
|
||||
addSeidList.push(seid, 0);
|
||||
}
|
||||
}
|
||||
for (let seid of lastSeids) {
|
||||
let index = findIndex(curSeids, seid);
|
||||
if (index < 0) {
|
||||
removeSeidList.push(seid, 0);
|
||||
}
|
||||
}
|
||||
return heroAttrs;
|
||||
}
|
||||
// for (let seid of curSeids) {
|
||||
// let index = findIndex(lastSeids, seid);
|
||||
// if (index < 0) {
|
||||
// addSeidList.push(seid, 0);
|
||||
// }
|
||||
// }
|
||||
// for (let seid of lastSeids) {
|
||||
// let index = findIndex(curSeids, seid);
|
||||
// if (index < 0) {
|
||||
// removeSeidList.push(seid, 0);
|
||||
// }
|
||||
// }
|
||||
// return heroAttrs;
|
||||
// }
|
||||
|
||||
/**
|
||||
* 初始计算兵种属性
|
||||
@@ -515,7 +519,7 @@ export function calHeroJobAttr(originHero: HeroType, hero: HeroUpdate, addSeidLi
|
||||
};
|
||||
|
||||
originHero.attr = heroAttrs;
|
||||
heroAttrs = calHeroJobStageUpIncAttr(originHero, hero, addSeidList, removeSeidList);
|
||||
// heroAttrs = calHeroJobStageUpIncAttr(originHero, hero, addSeidList, removeSeidList);
|
||||
return heroAttrs;
|
||||
}
|
||||
|
||||
@@ -552,6 +556,8 @@ export function calHeroWearSkinIncAttr(originHero: HeroType, update: HeroUpdate,
|
||||
calEquipStrengthIncAttr(originHero, update, eplaceIds);
|
||||
calEquipQualityIncAttr(originHero, update, eplaceIds);
|
||||
calEquipStarIncAttr(originHero, update, eplaceIds, addSeidList, removeSeidList);
|
||||
// 天赋点
|
||||
calHeroTalent(originHero, update, addSeidList, removeSeidList);
|
||||
|
||||
return heroAttrs;
|
||||
}
|
||||
@@ -990,6 +996,43 @@ function calHeroCeScrollIncAttr(originHero: HeroType, update: HeroUpdate) {
|
||||
return heroAttrs;
|
||||
}
|
||||
|
||||
function calHeroTalent(originHero: HeroType, update: HeroUpdate, addSeidList: number[], removeSeidList: number[]) {
|
||||
let { attr: heroAttrs, skins: oldSkins } = originHero;
|
||||
let { skins } = update;
|
||||
let oldSkin = oldSkins.find(cur => cur.enable);
|
||||
let newSkin = skins.find(cur => cur.enable);
|
||||
let oldSeids = getTalentSeid(oldSkin.talent);
|
||||
let newSeids = getTalentSeid(newSkin.talent);
|
||||
for(let seid of newSeids) addSeidList.push(seid);
|
||||
for(let seid of oldSeids) removeSeidList.push(seid);
|
||||
return heroAttrs
|
||||
}
|
||||
|
||||
function getTalentSeid(talent: Talent[]) {
|
||||
let seids = new Map<number, number[]>(); // id, seids
|
||||
for(let { id, level } of talent) {
|
||||
let dicHeroTalent = gameData.heroTalent.get(id);
|
||||
for(let { type, ids} of dicHeroTalent.relation) {
|
||||
if(type == TALENT_RELATION_TYPE.REPLACE) {
|
||||
for(let id of ids) {
|
||||
seids.delete(id);
|
||||
}
|
||||
}
|
||||
}
|
||||
for(let { lv, seid } of dicHeroTalent.level) {
|
||||
if(level >= lv) {
|
||||
if(!seids.has(id)) seids.set(id, []);
|
||||
seids.get(id).push(seid);
|
||||
}
|
||||
}
|
||||
}
|
||||
let result: number[] = [];
|
||||
for(let [_, ids] of seids) {
|
||||
result.push(...ids);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* 升爵位
|
||||
* @param role 角色数据
|
||||
|
||||
Reference in New Issue
Block a user