添加字典表解析

This commit is contained in:
luying
2020-12-15 15:00:41 +08:00
parent 2a268b2158
commit 87cdd7a80f
33 changed files with 1462 additions and 47 deletions

View File

@@ -4,11 +4,13 @@ import { calPlayerCeAndSave, getAllAttrStage } from '../../../services/playerCeS
import { resResult, getItems, decodeStr } from '../../../pubUtils/util'; import { resResult, getItems, decodeStr } from '../../../pubUtils/util';
import { STATUS } from '../../../consts/statusCode'; import { STATUS } from '../../../consts/statusCode';
import {HeroModel} from '../../../db/Hero'; import {HeroModel} from '../../../db/Hero';
import {CURRENCY_BY_TYPE, CURRENCY_TYPE, ITID, CONSUME_TYPE, HERO_GROW_MAX, HERO_SYSTEM_TYPE} from '../../../consts/consts'; import {CURRENCY_BY_TYPE, CURRENCY_TYPE, CONSUME_TYPE, HERO_GROW_MAX, HERO_SYSTEM_TYPE, ITID} from '../../../consts/consts';
import {getJobInfoById, getMaxGradeByjobClass, getHidAndLevelByShipId, getHeroInfoById, getGoodById, getHeroExpByLv, getGamedata, getJobByGradeAndClass, getFriendShipById, getFriendShipLevels, getFashionsById, getHeroLvByExp, getExpByLv} from '../../../pubUtils/gamedata'; import {getJobInfoById, getMaxGradeByjobClass, getHidAndLevelByShipId, getGoodById, getJobByGradeAndClass, getFriendShipById, getFriendShipLevels, getFashionsById} from '../../../pubUtils/gamedata';
import { ABI_STAGE } from '../../../consts/abilityConst'; import { ABI_STAGE } from '../../../consts/abilityConst';
import { RoleModel } from '../../../db/Role'; import { RoleModel } from '../../../db/Role';
import Item, { ItemModel } from '../../../db/Item'; import { ItemModel } from '../../../db/Item';
import { gameData, getHeroExpByLv, getHeroStarByQuality, getHeroWakeByQuality, getHeroLvByExp } from '../../../pubUtils/data';
import { RewardInter } from '../../../pubUtils/interface';
const _ = require('underscore'); const _ = require('underscore');
@@ -50,7 +52,7 @@ export class HeroHandler {
let hasHero = await HeroModel.findByHidAndRole(hid, roleId); let hasHero = await HeroModel.findByHidAndRole(hid, roleId);
if(hasHero) return resResult(STATUS.ROLE_HERO_EXISTS); if(hasHero) return resResult(STATUS.ROLE_HERO_EXISTS);
// 根据dic_hero 获得 1. 碎片id 2. 碎片数量 3. 初始武将星级 4. 初始品质 // 根据dic_hero 获得 1. 碎片id 2. 碎片数量 3. 初始武将星级 4. 初始品质
let dicHero = getHeroInfoById(hid); let dicHero = gameData.hero.get(hid);
if(!dicHero) return resResult(STATUS.ROLE_INFO_NOT_FOUND); if(!dicHero) return resResult(STATUS.ROLE_INFO_NOT_FOUND);
let {pieceId, quality, initialStars: star, pieceCount, jobid: job, name: hName} = dicHero; let {pieceId, quality, initialStars: star, pieceCount, jobid: job, name: hName} = dicHero;
// 碎片数量是否足够 // 碎片数量是否足够
@@ -91,9 +93,9 @@ export class HeroHandler {
// 计算得材料可转换的经验 // 计算得材料可转换的经验
let originalConsumes: Array<any> = await ItemModel.findByRoleAndType(roleId, CONSUME_TYPE.EXP); let originalConsumes: Array<any> = await ItemModel.findByRoleAndType(roleId, CONSUME_TYPE.EXP);
let material = new Array<{id: number, count: number}>(); let material = new Array<RewardInter>();
for(let {id, count} of originalConsumes) { for(let {id, count} of originalConsumes) {
let dicGoods = getGoodById(id); let dicGoods = gameData.goods.get(id);
if(!dicGoods) return resResult(STATUS.ROLE_INFO_NOT_FOUND); if(!dicGoods) return resResult(STATUS.ROLE_INFO_NOT_FOUND);
let _count = Math.ceil(needExp/dicGoods.value); let _count = Math.ceil(needExp/dicGoods.value);
if(_count < count) { if(_count < count) {
@@ -132,7 +134,7 @@ export class HeroHandler {
let {hid, star, starStage} = msg; let {hid, star, starStage} = msg;
// 根据dic_hero 获得 1. 碎片id 2. 碎片数量 3. 初始武将星级 4. 初始品质 // 根据dic_hero 获得 1. 碎片id 2. 碎片数量 3. 初始武将星级 4. 初始品质
let dicHero = getHeroInfoById(hid); let dicHero = gameData.hero.get(hid);
if(!dicHero) return resResult(STATUS.ROLE_INFO_NOT_FOUND); if(!dicHero) return resResult(STATUS.ROLE_INFO_NOT_FOUND);
let {pieceId} = dicHero; let {pieceId} = dicHero;
@@ -147,8 +149,7 @@ export class HeroHandler {
return resResult(STATUS.ROLE_STAR_REACH_MAX); return resResult(STATUS.ROLE_STAR_REACH_MAX);
} }
// 根据dic_zyz_hero_star 计算需要花的碎片并检查碎片数量 // 根据dic_zyz_hero_star 计算需要花的碎片并检查碎片数量
const dicHeroStar = getGamedata('dic_zyz_hero_star'); const curDicHeroStar = getHeroStarByQuality(quality, oldStar);
const curDicHeroStar = dicHeroStar.find(cur => cur.quality == quality && cur.star && oldStar);
if(!curDicHeroStar) return resResult(STATUS.ROLE_INFO_NOT_FOUND); if(!curDicHeroStar) return resResult(STATUS.ROLE_INFO_NOT_FOUND);
let costResult = await handleCost(roleId, sid, [{id: pieceId, count: curDicHeroStar.advanceUpFragmentNum}]); let costResult = await handleCost(roleId, sid, [{id: pieceId, count: curDicHeroStar.advanceUpFragmentNum}]);
@@ -175,7 +176,7 @@ export class HeroHandler {
let sid: string = session.get('sid'); let sid: string = session.get('sid');
let {hid, quality} = msg; let {hid, quality} = msg;
let dicHero = getHeroInfoById(hid); let dicHero = gameData.hero.get(hid);
if(!dicHero) return resResult(STATUS.ROLE_INFO_NOT_FOUND); if(!dicHero) return resResult(STATUS.ROLE_INFO_NOT_FOUND);
// 根据dic_hero 获得 碎片id // 根据dic_hero 获得 碎片id
let {pieceId} = dicHero; let {pieceId} = dicHero;
@@ -194,8 +195,7 @@ export class HeroHandler {
} }
// 根据dic_zyz_hero_quality_up 获得需要的材料 // 根据dic_zyz_hero_quality_up 获得需要的材料
let dicHeroQualityUp = getGamedata('dic_zyz_hero_quality_up'); const curDicHeroQualityUp = gameData.heroQualityUp.get(quality);
const curDicHeroQualityUp = dicHeroQualityUp.find(cur => cur.quality == quality);
if(!curDicHeroQualityUp) return resResult(STATUS.ROLE_INFO_NOT_FOUND); if(!curDicHeroQualityUp) return resResult(STATUS.ROLE_INFO_NOT_FOUND);
let {fragmentNum} = curDicHeroQualityUp; let {fragmentNum} = curDicHeroQualityUp;
@@ -219,7 +219,7 @@ export class HeroHandler {
let {hid, colorStar, colorStarStage} = msg; let {hid, colorStar, colorStarStage} = msg;
// 根据dic_hero 获得 1. 碎片id 2. 碎片数量 3. 初始武将星级 4. 初始品质 // 根据dic_hero 获得 1. 碎片id 2. 碎片数量 3. 初始武将星级 4. 初始品质
let dicHero = getHeroInfoById(hid); let dicHero = gameData.hero.get(hid);
if(!dicHero) return resResult(STATUS.ROLE_INFO_NOT_FOUND); if(!dicHero) return resResult(STATUS.ROLE_INFO_NOT_FOUND);
let {pieceId} = dicHero; let {pieceId} = dicHero;
@@ -237,16 +237,13 @@ export class HeroHandler {
return resResult(STATUS.ROLE_QUALITY_NOT_ENOUGH); return resResult(STATUS.ROLE_QUALITY_NOT_ENOUGH);
} }
// 根据dic_zyz_hero_wake 计算需要花的碎片并检查碎片数量 // 根据dic_zyz_hero_wake 计算需要花的碎片并检查碎片数量
const dicHeroStar = getGamedata('dic_zyz_hero_wake'); const curDicHeroStar = getHeroWakeByQuality(quality, oldColorStar)
const curDicHeroStar = dicHeroStar.find(cur => cur.quality == quality && cur.star == oldColorStar);
if(!curDicHeroStar) return resResult(STATUS.ROLE_INFO_NOT_FOUND); if(!curDicHeroStar) return resResult(STATUS.ROLE_INFO_NOT_FOUND);
let {fragmentNum, consume} = curDicHeroStar; let {fragmentNum, consume} = curDicHeroStar;
let consumeArr = decodeStr('cost', consume);
// console.log(JSON.stringify([{id: pieceId, count: fragmentNum}, ...consumeArr])) // console.log(JSON.stringify([{id: pieceId, count: fragmentNum}, ...consumeArr]))
let costResult = await handleCost(roleId, sid, [{id: pieceId, count: fragmentNum}, ...consumeArr]); let costResult = await handleCost(roleId, sid, [{id: pieceId, count: fragmentNum}, ...consume]);
if(!costResult) return resResult(STATUS.ROLE_MATERIAL_NOT_ENOUGH); if(!costResult) return resResult(STATUS.ROLE_MATERIAL_NOT_ENOUGH);
let isUpStar = oldColorStar == 0|| oldColorStarStage + 1 == ABI_STAGE.END; let isUpStar = oldColorStar == 0|| oldColorStarStage + 1 == ABI_STAGE.END;
@@ -389,8 +386,9 @@ export class HeroHandler {
//计算消耗物品转化的经验 //计算消耗物品转化的经验
let exp:number = 0; let exp:number = 0;
for (let item of items) { for (let item of items) {
let itemInfo = getGoodById(item.id); let itemInfo = gameData.goods.get(item.id);
if (itemInfo.itid == CONSUME_TYPE.FAVOUR) { let dicItid = ITID.get(itemInfo.itid);
if (dicItid.type == CONSUME_TYPE.FAVOUR) {
exp += itemInfo.value; exp += itemInfo.value;
} else { } else {
return resResult(STATUS.WRONG_PARMS); return resResult(STATUS.WRONG_PARMS);

View File

@@ -12,7 +12,7 @@ import { RoleModel } from '../db/Role';
import { CeAttrData, CeAttr } from '../db/BaseModel'; import { CeAttrData, CeAttr } from '../db/BaseModel';
import { getFashionsById, getJobInfoById, getJobByGradeAndClass, getHeroInfoById, getHeroStar, getHeroWake, getFiendShipLevel, getFriendShipById, getHeroSkillById, getSeidById } from '../pubUtils/gamedata'; import { getFashionsById, getJobInfoById, getJobByGradeAndClass, getHeroInfoById, getHeroStar, getHeroWake, getFiendShipLevel, getFriendShipById, getHeroSkillById, getSeidById } from '../pubUtils/gamedata';
import { getAttrNameByJobStage, getAttrCeRatio, getAtrrNameById, ABI_TYPE_TO_STAGE, ABI_STAGE, SEID_TYPE, HERO_ATTR} from '../consts/abilityConst'; import { getAttrNameByJobStage, getAttrCeRatio, getAtrrNameById, ABI_TYPE_TO_STAGE, ABI_STAGE, SEID_TYPE, HERO_ATTR} from '../consts/abilityConst';
import { SSL_OP_SSLEAY_080_CLIENT_DH_BUG } from 'constants';
const HERO_CE_RATIO = 100; const HERO_CE_RATIO = 100;
const _ = require('underscore'); const _ = require('underscore');
//战力计算TODO //战力计算TODO
@@ -62,7 +62,6 @@ export async function calPlayerCeAndSave(sid: string, roleId: string, heros: Arr
for (let hero of heros) { for (let hero of heros) {
let incHeroCe = calPlayerCe(hero, type, args); let incHeroCe = calPlayerCe(hero, type, args);
incPlayerCe += incHeroCe; incPlayerCe += incHeroCe;
console.log('*******', JSON.stringify(hero))
await hero.save(); await hero.save();
pushHeros.push({ pushHeros.push({
hid: hero.hid, hid: hero.hid,

View File

@@ -328,4 +328,62 @@ export const HERO_GROW_MAX = {
export const JOB_TYPE = { export const JOB_TYPE = {
PHYSIC: 1, PHYSIC: 1,
MAGIC: 2 MAGIC: 2
} }
export const SPECIAL_ATTR = {
WAR_ID: 1,
TREASURE_ID: 2,
TREASURE_TYPE: 3
}
export const FILENAME = {
DIC_BLUEPRT_COMPOSE: 'dic_blueprt_compose',
DIC_BLUEPRT_POSSIBILITY: 'dic_blueprt_possibility',
DIC_EXPEDITION: 'dic_expedition',
DIC_EXPEDITION_POINT: 'dic_expedition_point',
DIC_FUNC_SWITCH: 'dic_func_switch',
DIC_GOODS: 'dic_goods',
DIC_CHAREXP: 'dic_zyz_charexp',
DIC_DAILY: 'dic_zyz_daily',
DIC_EVENT: 'dic_zyz_event',
DIC_FASHIONS: 'dic_zyz_fashions',
DIC_FRIEND_SHIP: 'dic_zyz_friend_ship',
DIC_FRIEND_SHIP_LEVEL: 'dic_zyz_friend_ship_level',
DIC_GACHA: 'dic_gacha',
DIC_GK_BRANCH: 'dic_zyz_gk_branch',
DIC_GK_DAILY: 'dic_zyz_gk_daily',
DIC_GK_DUNGEON: 'dic_zyz_gk_dungeon',
DIC_GK_DUNGEON_ELITE: 'dic_zyz_gk_dungeonElite',
DIC_GK_EVENT: 'dic_zyz_gk_event',
DIC_GK_EXPEDITION: 'dic_zyz_gk_expedition',
DIC_GK_MAIN: 'dic_zyz_gk_main',
DIC_GK_MAIN_ELITE: 'dic_zyz_gk_mainElite',
DIC_GK_TOWER: 'dic_zyz_gk_tower',
DIC_GK_TREASURE: 'dic_zyz_gk_Treasure',
DIC_HERO: 'dic_zyz_hero',
DIC_HERO_QUALITY_UP: 'dic_zyz_hero_quality_up',
DIC_HERO_STAR: 'dic_zyz_hero_star',
DIC_HERO_WAKE: 'dic_zyz_hero_wake',
DIC_HERO_SKILL: 'dic_zyz_heroskill',
DIC_JOB: 'dic_zyz_job',
DIC_KING_EXP: 'dic_zyz_kingexp',
DIC_CHAR_EXP: 'dic_zyz_charexp',
DIC_SE: 'dic_zyz_se',
DIC_TOWER_TASK: 'dic_zyz_search',
DIC_TOWER: 'dic_zyz_tower',
DIC_XUNBAO: 'dic_zyz_xunbao',
DIC_QUESTION: 'Questions',
}
export const WAR_RELATE_TABLES = [
FILENAME.DIC_GK_BRANCH,
FILENAME.DIC_GK_DAILY,
FILENAME.DIC_GK_DUNGEON,
FILENAME.DIC_GK_DUNGEON_ELITE,
FILENAME.DIC_GK_EVENT,
FILENAME.DIC_GK_EXPEDITION,
FILENAME.DIC_GK_MAIN,
FILENAME.DIC_GK_MAIN_ELITE,
FILENAME.DIC_GK_TOWER,
FILENAME.DIC_GK_TREASURE
]

140
shared/pubUtils/data.ts Normal file
View File

@@ -0,0 +1,140 @@
import { dicHero } from "./dictionary/DicHero";
import { dicGoods, blueprt } from "./dictionary/DicGoods";
import { dicBlueprtCompose } from "./dictionary/DicBlueprtCompose";
import { dicBlueprtPossibility } from "./dictionary/DicBlueprtPossibility";
import { dicDaily } from "./dictionary/DicDaily";
import { dicEvent } from "./dictionary/DicEvent";
import { dicExpedition } from "./dictionary/DicExpedition";
import { dicExpeditionPoint } from "./dictionary/DicExpeditionPoint";
import { dicFuncSwitch } from "./dictionary/DicFuncSwitch";
import { dicHeroSkill } from "./dictionary/DicHeroSkill";
import { dicJob, jobClassAndgrades, jobClassMaxGrades } from "./dictionary/DicJob";
import { dicKingExp } from "./dictionary/DicKingExp";
import { dicCharExp } from "./dictionary/DicCharExp";
import { dicQuestion } from "./dictionary/DicQuestion";
import { dicSe } from "./dictionary/DicSe";
import { dicTower } from "./dictionary/DicTower";
import { dicTowerTask } from "./dictionary/DicTowerTask";
import { dicWar } from "./dictionary/DicWar";
import { dicWarJson } from "./dictionary/DicWarJson";
import { dicXunbao } from "./dictionary/DicXunbao";
import { SPECIAL_ATTR } from "../consts/consts";
import { dicFashions } from "./dictionary/DicFashions";
import { friendShips, friendShipHidAandIds } from "./dictionary/DicFriendShip";
import { dicFriendShipLevel } from "./dictionary/DicFriendShipLevel";
import { dicHeroQualityUp } from "./dictionary/DicHeroQualityUp";
import { dicHeroStar } from "./dictionary/DicHeroStar";
import { dicHeroWake } from "./dictionary/DicHeroWake";
export const gameData = {
blurprtCompose: dicBlueprtCompose,
blueprtPossibility: dicBlueprtPossibility,
daily: dicDaily,
event: dicEvent,
expedition: dicExpedition,
expeditionPoint: dicExpeditionPoint,
funcsSwitch: dicFuncSwitch,
goods: dicGoods,
hero: dicHero,
heroQualityUp: dicHeroQualityUp,
heroSkill: dicHeroSkill,
heroStar: dicHeroStar,
heroWake: dicHeroWake,
job: dicJob,
jobClassMaxGrades: jobClassMaxGrades,
jobClassAndgrades: jobClassAndgrades,
kingexp: dicKingExp,
charexp: dicCharExp,
question: dicQuestion,
se: dicSe,
tower: dicTower,
towerTask: dicTowerTask,
war: dicWar,
warJson: dicWarJson,
xunbao: dicXunbao,
btlBossHpSum: new Map<number, number>(),
btlBossHp: new Map<number, Array<{dataId: number, hp: number, actorId: number}>>(),
blueprtToWar: new Map<number, number>(),
blueprt: blueprt,
fashion: dicFashions,
friendShips: friendShips,
friendShipHidAandIds: friendShipHidAandIds,
friendShipLevel: dicFriendShipLevel
};
export function getLvByExp(exp: number) {
let curLv = 0;
let entries = gameData.kingexp.entries();
for (let [lv, {sum}] of entries) {
curLv = lv;
if(exp < sum) break;
}
return curLv;
}
export function getExpByLv(lv: number) {
return gameData.kingexp.get(lv);
}
export function getHeroLvByExp(exp: number) {
let curLv = 0;
let entries = gameData.charexp.entries();
for (let [lv, sum] of entries) {
curLv = lv;
if(exp < sum) break;
}
return curLv;
}
export function getHeroExpByLv(lv: number) {
return gameData.charexp.get(lv);
}
export function getBossHpByWarId(warId: number) {
let bossHpSum = gameData.btlBossHpSum.get(warId) || 0;
let bossHpArr = gameData.btlBossHp.get(warId) || [];
if (!bossHpSum || !bossHpArr) {
const warInfo = dicWarJson.get(warId);
if (warInfo && warInfo.length) {
warInfo.forEach(hero => {
let { attribute, dataId, relation, actorId } = hero;
if (relation === 2) {
const hp = attribute.hp||0;
if (hp > 0) {
bossHpArr.push({dataId, hp, actorId});
bossHpSum += hp;
}
}
})
gameData.btlBossHp.set(warId, bossHpArr);
gameData.btlBossHpSum.set(warId, bossHpSum);
}
}
return { bossHpSum, bossHpArr };
}
export function getWarIdByBlueprtId(blueprtId: number) {
let warId = gameData.blueprtToWar.get(blueprtId);
if (!warId) {
let blueprt = gameData.goods.get(blueprtId);
if(blueprt) {
const { specialAttr } = blueprt;
warId = specialAttr.get(SPECIAL_ATTR.WAR_ID);
if(warId)
gameData.blueprtToWar.set(blueprtId, warId);
}
}
return warId;
}
export function getHeroStarByQuality(quality: number, star: number) {
return gameData.heroStar.get(`${quality}_${star}`);
}
export function getHeroWakeByQuality(quality: number, star: number) {
return gameData.heroWake.get(`${quality}_${star}`);
}

View File

@@ -0,0 +1,24 @@
// 藏宝图合成表
import { readJsonFile } from '../util'
import { FILENAME } from '../../consts/consts'
export interface DicBlueprtCompose {
// 品质
readonly quality: number;
// 消耗的寻宝币数量
readonly coinNum: number;
// 消耗的藏宝图的数量
readonly blueprtNum: number;
// 目标品质
readonly targetQuality: number;
}
const str = readJsonFile(FILENAME.DIC_BLUEPRT_COMPOSE);
let arr = JSON.parse(str);
export const dicBlueprtCompose = new Map<number, DicBlueprtCompose>();
arr.forEach(o => {
dicBlueprtCompose.set(o.quality, o);
});

View File

@@ -0,0 +1,37 @@
// 藏宝图掉落率
import { decodeArrayListStr, readJsonFile } from '../util'
import { FILENAME } from '../../consts/consts'
export interface DicBlueprtPossibility {
// 君主等级下限
readonly min: number;
// 君主等级上限
readonly max: number;
// 掉落概率
readonly possibility: Array<{id: number, weight: number}>;
}
const str = readJsonFile(FILENAME.DIC_BLUEPRT_POSSIBILITY);
let arr = JSON.parse(str);
export const dicBlueprtPossibility = new Array<DicBlueprtPossibility>();
arr.forEach(o => {
o.possibility = parsePossibility(o.possibility);
dicBlueprtPossibility.push(o);
});
function parsePossibility(str: string) {
let result = new Array<{id: number, weight: number}>();
if(!str) return result;
let decodeArr = decodeArrayListStr(str);
for(let [id, weight] of decodeArr) {
if(isNaN(parseInt(id)) || isNaN(parseInt(weight))) {
throw new Error('data table format wrong');
}
result.push({id: parseInt(id), weight: parseInt(weight)});
}
return result
}

View File

@@ -0,0 +1,21 @@
// 主公经验
import {readJsonFile} from '../util'
import { FILENAME } from '../../consts/consts'
export interface DicCharExp {
// 等级
readonly level: number;
// 经验
readonly exp: number;
}
const str = readJsonFile(FILENAME.DIC_CHAR_EXP);
let arr = JSON.parse(str);
export const dicCharExp = new Map<number, number>();
let exp = 0;
arr.forEach(o => {
exp += o.exp;
dicCharExp.set(o.level, exp);
});

View File

@@ -0,0 +1,26 @@
// 每日总表
import { readJsonFile, parseNumberList } from '../util'
import { FILENAME } from '../../consts/consts'
export interface DicDaily {
// 每日类型
readonly dailyType: number;
// 每日类型名称
readonly name: string;
// 每天可以挑战的次数
readonly timesPerDay: number;
// 每天可以购买的次数
readonly timesCanBuy: number;
// 难度
readonly difficultLvl: Array<number>;
}
const str = readJsonFile(FILENAME.DIC_DAILY);
let arr = JSON.parse(str);
export const dicDaily = new Array<DicDaily>();
arr.forEach(o => {
o.difficultLvl = parseNumberList(o.difficultLvl);
dicDaily.push(o);
});

View File

@@ -0,0 +1,56 @@
// 奇遇表
import { parseReward, decodeArrayStr, readJsonFile, parseNumberList } from '../util'
import { FILENAME } from '../../consts/consts'
import { RewardInter } from '../../pubUtils/interface';
interface SuitLevel {
readonly min: number;
readonly max?: number;
}
export interface DicEvent {
// 事件id
readonly eventID: number;
// 事件类型
readonly eventType: number;
// 事件品质
readonly quality: number;
// 事件名
readonly name: string;
// 胜利奖励
readonly winReward: Array<RewardInter>;
// 失败奖励
readonly loseReward: Array<RewardInter>;
// 适用等级
readonly suitLevel: SuitLevel;
// 关联关卡id
readonly warId: number;
// 权重
readonly weight: number;
// 移动点
readonly movePointArray: Array<number>;
}
const str = readJsonFile(FILENAME.DIC_EVENT);
let arr = JSON.parse(str);
export const dicEvent = new Map<number, DicEvent>();
arr.forEach(o => {
o.winReward = parseReward(o.winReward);
o.loseReward = parseReward(o.loseReward);
o.suitLevel = parseSuitLevel(o.suitLevel);
o.movePointArray = parseNumberList(o.movePointArray);
dicEvent.set(o.quality, o);
});
function parseSuitLevel(str: string) {
let decodeArr = decodeArrayStr(str, '&');
let [min, max] = decodeArr;
let suitLevel: SuitLevel;
if(isNaN(parseInt(min)) || isNaN(parseInt(max))) throw new Error('data table format wrong');
suitLevel = ({min: parseInt(min), max: parseInt(max)});
return suitLevel;
}

View File

@@ -0,0 +1,31 @@
// 远征关卡表
import { readJsonFile } from '../util'
import { FILENAME } from '../../consts/consts'
export interface DicExpedition {
// 远征id
readonly id: number;
// 关卡id
readonly warId: number;
// 关卡系数
readonly CEScale: number;
// 关卡系数范围
readonly CERange: number;
// 新手期关卡系数
readonly CEScaleNew: number;
// 新手期关卡系数范围
readonly CERangeNew: number;
// 机器人模板出兵表
readonly json: number;
// 模板战力
readonly ce: number;
}
const str = readJsonFile(FILENAME.DIC_EXPEDITION);
let arr = JSON.parse(str);
export const dicExpedition = new Map<number, DicExpedition>();
arr.forEach(o => {
dicExpedition.set(o.id, o);
});

View File

@@ -0,0 +1,21 @@
// 远征点数奖励表
import { parseReward, readJsonFile } from '../util';
import { FILENAME } from '../../consts/consts';
import { RewardInter } from '../interface';
export interface DicExpeditionPoint {
// 远征点数
readonly point: number;
// 奖励
readonly reward: Array<RewardInter>;
}
const str = readJsonFile(FILENAME.DIC_EXPEDITION_POINT);
let arr = JSON.parse(str);
export const dicExpeditionPoint = new Map<number, DicExpeditionPoint>();
arr.forEach(o => {
o.reward = parseReward(o.reward);
dicExpeditionPoint.set(o.id, o);
});

View File

@@ -0,0 +1,40 @@
// 时装表
import { decodeArrayListStr, readJsonFile, parseNumberList } from '../util';
import { FILENAME } from '../../consts/consts';
export interface DicFashions {
// 时装id
readonly id: number;
// 增加的被动技能
readonly seid: Array<number>;
// 全局加成
readonly globalAttr: Array<{type: number, value: number}>;
// 单体加成
readonly actorAttr: Array<{type: number, value: number}>;
// 角色id
readonly actorId: number;
}
const str = readJsonFile(FILENAME.DIC_FASHIONS);
let arr = JSON.parse(str);
export const dicFashions = new Map<number, DicFashions>();
arr.forEach(o => {
o.seid = parseNumberList(o.seid);
o.globalAttr = parseAttr(o.globalAttr);
o.actorAttr = parseAttr(o.actorAttr);
dicFashions.set(o.id, o);
});
function parseAttr(str: string) {
let result = new Array<{type: number, value: number}>();
if(!str) return result;
let decodeArr = decodeArrayListStr(str);
for(let [type, value] of decodeArr) {
if(isNaN(parseInt(type)) || isNaN(parseInt(value))) {
throw new Error('data table format wrong');
}
result.push({type: parseInt(type), value: parseInt(value)});
}
return result
}

View File

@@ -0,0 +1,49 @@
// 武将羁绊表
import { decodeArrayListStr, readJsonFile, parseNumberList } from '../util';
import { FILENAME } from '../../consts/consts';
export interface DicFriendShip {
// id
readonly id: number;
// 羁绊id
readonly shipId: number;
// 主武将ID
readonly actorId: number;
// 羁绊名称
readonly name: string;
// 羁绊等级
readonly level: number;
// 羁绊武将ID
readonly hids: Array<number>;
// 属性加成
readonly attribute: Array<{id: number, number: number}>
// 消耗铜币
readonly costCoin: number;
}
const str = readJsonFile(FILENAME.DIC_FRIEND_SHIP);
let arr = JSON.parse(str);
export const friendShips = new Map<string, DicFriendShip>();
export const friendShipHidAandIds = new Map<number, {actorId: number, level:number}>();
arr.forEach(o => {
o.attribute = parseAttribute(o.attribute);
o.hids = parseNumberList(o.memberId);
friendShips.set(o.shipId + '_' + o.level, o);
let fiendShipHidAandId = friendShipHidAandIds.get(o.shipId);
if (!fiendShipHidAandId || fiendShipHidAandId.level < o.level)
friendShipHidAandIds.set(o.shipId, {actorId: o.actorId, level: o.level});
});
function parseAttribute(str: string) {
let result = new Array<{id: number, number: number}>();
if(!str) return result;
let decodeArr = decodeArrayListStr(str);
for(let [id, number] of decodeArr) {
if(isNaN(parseInt(id)) || isNaN(parseInt(number))) {
throw new Error('data table format wrong');
}
result.push({id: parseInt(id), number: parseInt(number)});
}
return result
}

View File

@@ -0,0 +1,23 @@
// 武将羁绊好感等级表
import { readJsonFile } from '../util';
import { FILENAME } from '../../consts/consts';
export interface DicFriendShipLevel {
// 等级
readonly level: number;
// 下一级经验
readonly exp: number;
// 加成百分比
readonly add: number;
}
const str = readJsonFile(FILENAME.DIC_FRIEND_SHIP);
let arr = JSON.parse(str);
export const dicFriendShipLevel = new Array<DicFriendShipLevel>();
arr.forEach(o => {
dicFriendShipLevel.push(o);
});
dicFriendShipLevel.sort(function(a, b) {
return a.level - b.level;
});

View File

@@ -0,0 +1,25 @@
// 开启功能表
import { readJsonFile } from '../util';
import { FILENAME } from '../../consts/consts';
export interface DicFuncSwitch {
// 功能id
readonly id: number;
// 描述
readonly desc: string;
// 条件
readonly conditionType: number;
// 参数
readonly param: number;
// 客户端指令
readonly script: string;
}
const str = readJsonFile(FILENAME.DIC_FUNC_SWITCH);
let arr = JSON.parse(str);
export const dicFuncSwitch = new Array<DicFuncSwitch>();
arr.forEach(o => {
dicFuncSwitch.push(o);
});

View File

@@ -0,0 +1,104 @@
// 物品表
import {decodeArrayListStr, readJsonFile, parseReward} from '../util'
import { FILENAME, IT_TYPE } from '../../consts/consts'
import { RewardInter } from '../interface';
import { ABI_TYPE } from '../../consts/abilityConst';
export interface DicGoods {
// 物品id
readonly good_id: number;
// 物品名
readonly name: string;
// 等级限制
readonly lvLimted: number;
// 合成装备需要的碎片数
readonly pieces: number;
// 合成材料
readonly composeMaterial: Array<RewardInter>;
// 分解所得
readonly decomposeItem: Array<RewardInter>;
// 物品品质
readonly quality: number;
// 洞数
readonly hole: number;
// 类型id
readonly itid: number;
// 物品类型
readonly goodType: number;
// 将魂对应武将id
readonly hid: number;
// 属性
readonly goodsAbility:Map<number, number>;
// 强化属性
readonly goodsAbilityUp:Map<number, number>;
// 套装id
readonly setid: number;
// 特殊属性
readonly specialAttr: Map<number, number>;
// 属性外加的值,经验,好感
readonly value: number;
}
const str = readJsonFile(FILENAME.DIC_GOODS);
let arr = JSON.parse(str);
export const dicGoods = new Map<number, DicGoods>();
export const blueprt = new Map<number, Array<number>>();
arr.forEach(o => {
o.goodsAbility = parseAbility(o);
o.goodsAbilityUp = parseAbilityUp(o);
o.composeMaterial = parseReward(o.composeMaterial);
o.decomposeItem = parseReward(o.decomposeItem);
o.specialAttr = parseSpecialAttr(o.specialAttr);
dicGoods.set(o.good_id, o);
if(o.itid == IT_TYPE.BLUEPRT) {
let arr = blueprt.get(o.quality)||new Array<number>();
arr.push(o.good_id);
blueprt.set(o.quality, arr);
}
});
function parseSpecialAttr(str: string) {
let specialAttr = new Map<number, number>();
if(str) {
let decodeArr = decodeArrayListStr(str);
for(let [type, count] of decodeArr) {
if(isNaN(parseInt(type)) || isNaN(parseInt(count))) {
throw new Error('data table format wrong');
}
specialAttr.set(parseInt(type), parseInt(count));
}
}
return specialAttr;
}
function parseAbility(json) {
let map = new Map<number, number>();
map.set(ABI_TYPE.ABI_HP, json.hp||0);
map.set(ABI_TYPE.ABI_ATK, json.atk||0);
map.set(ABI_TYPE.ABI_MATK, json.matk||0);
map.set(ABI_TYPE.ABI_DEF, json.def||0);
map.set(ABI_TYPE.ABI_MDEF, json.mdef||0);
map.set(ABI_TYPE.ABI_AGI, json.agi||0);
map.set(ABI_TYPE.ABI_LUK, json.luk||0);
map.set(ABI_TYPE.ABI_SPEED, json.speed||0);
return map
}
function parseAbilityUp(json) {
let map = new Map<number, number>();
map.set(ABI_TYPE.ABI_HP, json.hp_up||0);
map.set(ABI_TYPE.ABI_ATK, json.atk_up||0);
map.set(ABI_TYPE.ABI_MATK, json.matk_up||0);
map.set(ABI_TYPE.ABI_DEF, json.def_up||0);
map.set(ABI_TYPE.ABI_MDEF, json.mdef_up||0);
map.set(ABI_TYPE.ABI_AGI, json.agi_up||0);
map.set(ABI_TYPE.ABI_LUK, json.luk_up||0);
map.set(ABI_TYPE.ABI_SPEED, json.speed_up||0);
return map
}

View File

@@ -0,0 +1,66 @@
// 武将表
import { ABI_TYPE } from '../../consts/abilityConst'
import { readJsonFile } from '../util'
import { FILENAME } from '../../consts/consts'
export interface DicHero {
// 武将id
readonly heroId: number;
// 武将名
readonly name: string;
// 初始品质
readonly quality: number;
// 阵营
readonly camp: number;
// 兵种
readonly jobid: number;
// 技能
readonly skill: number;
// 武将碎片
readonly pieceId: number;
// 初始星级
readonly initialStars: number;
// 合成碎片数量
readonly pieceCount: number;
// 主属性
readonly baseAbilityArr:Map<number, number>;
readonly baseAbilityUpArr:Map<number, number>;
}
const str = readJsonFile(FILENAME.DIC_HERO);
let arr = JSON.parse(str);
export const dicHero = new Map<number, DicHero>();
arr.forEach(o => {
o.baseAbilityArr = parseBaseAbilityArr(o);
o.baseAbilityUpArr = parseBaseAbilityUpArr(o);
dicHero.set(o.heroId, o);
});
function parseBaseAbilityArr(json) {
let map = new Map<number, number>();
map.set(ABI_TYPE.ABI_HP, json.hp||0);
map.set(ABI_TYPE.ABI_ATK, json.atk||0);
map.set(ABI_TYPE.ABI_MATK, json.matk||0);
map.set(ABI_TYPE.ABI_DEF, json.def||0);
map.set(ABI_TYPE.ABI_MDEF, json.mdef||0);
map.set(ABI_TYPE.ABI_AGI, json.agi||0);
map.set(ABI_TYPE.ABI_LUK, json.luk||0);
map.set(ABI_TYPE.ABI_SPEED, json.speed||0);
return map
}
function parseBaseAbilityUpArr(json) {
let map = new Map<number, number>();
map.set(ABI_TYPE.ABI_HP, json.hp_up||0);
map.set(ABI_TYPE.ABI_ATK, json.atk_up||0);
map.set(ABI_TYPE.ABI_MATK, json.matk_up||0);
map.set(ABI_TYPE.ABI_DEF, json.def_up||0);
map.set(ABI_TYPE.ABI_MDEF, json.mdef_up||0);
map.set(ABI_TYPE.ABI_AGI, json.agi_up||0);
map.set(ABI_TYPE.ABI_LUK, json.luk_up||0);
map.set(ABI_TYPE.ABI_SPEED, json.speed_up||0);
return map
}

View File

@@ -0,0 +1,26 @@
// 武将技能表
import {parseReward, decodeArrayListStr, readJsonFile} from '../util'
import { FILENAME } from '../../consts/consts'
import { RewardInter } from '../interface';
export interface DicHeroQualityUp {
// id
readonly id: number;
// 品质
readonly quality: number;
// 碎片数量
readonly fragmentNum: number;
// 消耗道具
readonly consume: Array<RewardInter>;
}
const str = readJsonFile(FILENAME.DIC_HERO_QUALITY_UP);
let arr = JSON.parse(str);
export const dicHeroQualityUp = new Map<number, DicHeroQualityUp>();
arr.forEach(o => {
o.consume = parseReward(o.consume);
dicHeroQualityUp.set(o.quality, o);
});

View File

@@ -0,0 +1,40 @@
// 武将技能表
import {decodeArrayListStr, readJsonFile} from '../util'
import { FILENAME } from '../../consts/consts'
export interface DicHeroSkill {
// 技能id
readonly skillid: number;
// 技能名
readonly name: string;
// 星级解锁
readonly starSeidArr: Array<{star: number, value: number}>;
// 觉醒解锁
readonly colorStarSeidArr: Array<{star: number, value: number}>;
}
const str = readJsonFile(FILENAME.DIC_HERO_SKILL);
let arr = JSON.parse(str);
export const dicHeroSkill = new Map<number, DicHeroSkill>();
arr.forEach(o => {
o.starSeidArr = parseSeid(o.starSeid);
o.colorStarSeidArr = parseSeid(o.colorStarSeid);
dicHeroSkill.set(o.good_id, o);
});
function parseSeid(str: string) {
let arr = new Array<{star: number, value: number}>();
if(!str) return arr;
let decodeArr = decodeArrayListStr(str);
for(let [star, value] of decodeArr) {
if(isNaN(parseInt(star)) || isNaN(parseInt(value))) {
continue;
}
arr.push({ star: parseInt(star), value: parseInt(value)});
}
return arr;
}

View File

@@ -0,0 +1,39 @@
// 武将升星表
import { readJsonFile } from '../util'
import { FILENAME } from '../../consts/consts'
import { ABI_STAGE } from '../../consts/abilityConst';
export interface DicHeroStar {
// 唯一id
readonly id: number;
// 品质
readonly quality: number;
// 星级
readonly star: number;
// 每小阶碎片数量
readonly advanceUpFragmentNum: number;
// 每阶升级属性
readonly ceAttr: Map<number, number>
}
const str = readJsonFile(FILENAME.DIC_HERO_STAR);
let arr = JSON.parse(str);
export const dicHeroStar = new Map<string, DicHeroStar>();
arr.forEach(o => {
o.ceAttr = parseCeAttr(o);
dicHeroStar.set(`${o.quality}_${o.star}`, o);
});
function parseCeAttr(elem) {
let ceAttr = new Map<number, number>();
ceAttr.set(ABI_STAGE.HP, elem.hp_up);
ceAttr.set(ABI_STAGE.ATK, elem.atk_up);
ceAttr.set(ABI_STAGE.DEF, elem.def_up);
ceAttr.set(ABI_STAGE.MDEF, elem.mdef_up);
ceAttr.set(ABI_STAGE.AGI, elem.agi_up);
ceAttr.set(ABI_STAGE.LUK, elem.luk_up);
return ceAttr;
}

View File

@@ -0,0 +1,43 @@
// 武将觉醒表
import { readJsonFile, parseReward } from '../util'
import { FILENAME } from '../../consts/consts'
import { ABI_STAGE } from '../../consts/abilityConst';
import { RewardInter } from '../interface';
export interface DicHeroWake {
// 唯一id
readonly id: number;
// 品质
readonly quality: number;
// 彩星级
readonly star: number;
// 碎片数量
readonly fragmentNum: number;
// 消耗道具
readonly consume: Array<RewardInter>;
// 每阶升级属性
readonly ceAttr: Map<number, number>
}
const str = readJsonFile(FILENAME.DIC_HERO_WAKE);
let arr = JSON.parse(str);
export const dicHeroWake = new Map<string, DicHeroWake>();
arr.forEach(o => {
o.consume = parseReward(o.consume);
o.ceAttr = parseCeAttr(o);
dicHeroWake.set(`${o.quality}_${o.star}`, o);
});
function parseCeAttr(elem) {
let ceAttr = new Map<number, number>();
ceAttr.set(ABI_STAGE.HP, elem.hp_up);
ceAttr.set(ABI_STAGE.ATK, elem.atk_up);
ceAttr.set(ABI_STAGE.DEF, elem.def_up);
ceAttr.set(ABI_STAGE.MDEF, elem.mdef_up);
ceAttr.set(ABI_STAGE.AGI, elem.agi_up);
ceAttr.set(ABI_STAGE.LUK, elem.luk_up);
return ceAttr;
}

View File

@@ -0,0 +1,51 @@
// 兵种表
import {readJsonFile, parseNumberList} from '../util'
import { FILENAME } from '../../consts/consts'
export interface DicJob {
// 兵种id
readonly jobid: number;
// 兵种名
readonly name: string;
// 该兵种在大兵种中的阶段
readonly grade: number;
// 解锁等级
readonly unlockLevel: number;
// 兵种类别
readonly job_class: number;
// 职业类别
readonly type: number;
// 特性
readonly seid: Array<number>;
// 生命训练提升
readonly hp: number;
// 攻击力训练提升
readonly atk: number;
// 防御力训练提升
readonly def: number;
// 策防训练提升
readonly mdef: number;
// 敏捷训练提升
readonly agi: number;
// 幸运训练提升
readonly luk: number;
}
const str = readJsonFile(FILENAME.DIC_JOB);
let arr = JSON.parse(str);
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}>();
arr.forEach(o => {
o.seid = parseNumberList(o.seid);
dicJob.set(o.jobid, o);
let jobClass = jobClassMaxGrades.get(o.job_class);
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});
});

View File

@@ -0,0 +1,21 @@
// 主公经验
import {readJsonFile} from '../util'
import { FILENAME } from '../../consts/consts'
export interface DicKingExp {
// 等级
readonly level: number;
// 经验
readonly exp: number;
}
const str = readJsonFile(FILENAME.DIC_KING_EXP);
let arr = JSON.parse(str);
export const dicKingExp = new Map<number, {sum: number, cur: number}>();
let exp = 0;
arr.forEach(o => {
exp += o.exp;
dicKingExp.set(o.level, { sum: exp, cur: o.exp });
});

View File

@@ -0,0 +1,34 @@
// 奇遇题库
import {readJsonFile} from '../util'
import { FILENAME } from '../../consts/consts'
export interface DicQuestion {
// 题目id
readonly id: number;
// 题干
readonly question: string;
// 答案
readonly answer: Array<string>;
// 正确答案
readonly correct: number;
}
const str = readJsonFile(FILENAME.DIC_QUESTION);
let arr = JSON.parse(str);
export const dicQuestion = new Map<number, DicQuestion>();
arr.forEach(o => {
o.answer = parseAnswer(o.a1, o.a2, o.a3, o.a4)
dicQuestion.set(o.id, o);
});
function parseAnswer(a1: string, a2: string, a3: string, a4: string) {
let answer = new Array<string>();
if(a1) answer.push(a1);
if(a2) answer.push(a2);
if(a3) answer.push(a3);
if(a4) answer.push(a4);
return answer;
}

View File

@@ -0,0 +1,30 @@
// 武将特技表
import { readJsonFile, parseNumberList } from '../util'
import { FILENAME } from '../../consts/consts'
export interface DicSe {
// 特技id
readonly id: number;
// 特技名
readonly name: string;
// 类型
readonly type: number;
// 是否显示
readonly isShow: number;
// 包含的值
readonly gainValueArr: Array<number>;
// 最大触发数
readonly maxOnlyNum: number;
}
const str = readJsonFile(FILENAME.DIC_SE);
let arr = JSON.parse(str);
export const dicSe = new Map<number, DicSe>();
arr.forEach(o => {
o.gainValueArr = parseNumberList(o.gainvalue)
dicSe.set(o.id, o);
});

View File

@@ -0,0 +1,40 @@
// 镇念塔表
import {parseReward, decodeArrayListStr, readJsonFile, parseNumberList} from '../util'
import { FILENAME } from '../../consts/consts';
import { RewardInter } from '../../pubUtils/interface';
export interface DicTower {
// 镇念塔层数
readonly towerFloor: number;
// 包含关卡
readonly warArray: Array<number>;
// 层数奖励
readonly reward: Array<RewardInter>;
// 收集奖励
readonly rewardOfcollect: Array<RewardInter>;
}
const str = readJsonFile(FILENAME.DIC_TOWER);
let arr = JSON.parse(str);
export const dicTower = new Map<number, DicTower>();
arr.forEach(o => {
o.warArray = parseNumberList(o.warArray);
o.reward = parseReward(o.reward);
o.rewardOfcollect = parseRewardOfCollect(o.rewardOfcollect);
dicTower.set(o.towerFloor, o);
});
function parseRewardOfCollect(str: string) {
let result = new Array<{id: number, count: number}>();
if(!str) return result;
let decodeArr = decodeArrayListStr(str);
for(let [id, count] of decodeArr) {
if(isNaN(parseInt(id)) || isNaN(parseFloat(count))) {
throw new Error('data table format wrong');
}
result.push({id: parseInt(id), count: parseFloat(count)});
}
return result
}

View File

@@ -0,0 +1,72 @@
// 镇念塔派遣任务表
import {parseReward, decodeArrayListStr, decodeArrayStr, readJsonFile} from '../util'
import { FILENAME } from '../../consts/consts';
import { RewardInter } from '../interface';
interface SuitFloor {
min: number;
max?: number;
}
export interface DicTowerTask {
// 任务id
readonly taskId: number;
// 任务名称
readonly taskName: string;
// 任务品质
readonly quality: number;
// 任务奖励
readonly reward: Array<RewardInter>;
// 额外奖励
readonly additionalReward: Array<RewardInter>;
// 达成额外奖励需要的武将条件
readonly termsForAdd: Array<{type: number, param: number, count: number}>;
// 完成任务所需的武将数
readonly actorNeeded: number;
// 完成时间(秒)
readonly completeTime: number;
// 适用层数
readonly suitFloor: SuitFloor;
// 权重
readonly weight: number;
}
const str = readJsonFile(FILENAME.DIC_TOWER_TASK);
let arr = JSON.parse(str);
export const dicTowerTask = new Map<number, DicTowerTask>();
arr.forEach(o => {
o.reward = parseReward(o.reward);
o.additionalReward = parseReward(o.additionalReward);
o.termsForAdd = parseTermsForAdd(o.termsForAdd);
o.suitFloor = parseSuitFloor(o.suitFloor as string);
dicTowerTask.set(o.taskId, o);
});
function parseTermsForAdd(str: string) {
let result = new Array<{type: number, param: number, count: number}>();
if(!str) return result;
let decodeArr = decodeArrayListStr(str);
for(let [type, param, count] of decodeArr) {
if(isNaN(parseInt(type)) || isNaN(parseInt(param)) || isNaN(parseInt(count))) {
throw new Error('data table format wrong');
}
result.push({type: parseInt(type), param: parseInt(param), count: parseInt(count)});
}
return result
}
function parseSuitFloor(str: string) {
if(!str) return {min: 0}
let decodeArr = decodeArrayStr(str, '&');
let [min, max] = decodeArr;
if(max) {
if(isNaN(parseInt(min)) || isNaN(parseInt(max))) throw new Error('data table format wrong');
return {min: parseInt(min), max: parseInt(max)};
} else { // 最大值如果不存在则表示 >= min
if(isNaN(parseInt(min))) throw new Error('data table format wrong');
return {min: parseInt(min)};
}
}

View File

@@ -0,0 +1,83 @@
// 关卡表
import {decodeArrayListStr, readJsonFile} from '../util'
import { WAR_RELATE_TABLES } from '../../consts/consts';
export interface DicWar {
// 关卡id
readonly war_id: number;
// 关卡固定奖励
readonly fixReward: Array<{id: number, count: number}>;
// 关卡条件奖励
readonly conditionReward: Array<{id: number, count: number, condition: number}>;
// 关卡随机奖励
readonly randomReward: Array<{id: number, count: number, frequency: number}>;
// 关卡类型
readonly warType: number;
// 关卡名
readonly gk_name: string;
// 胜利后获得的君主经验
readonly kingExp: number;
// 进入战场所需的最低等级
readonly lvLimited: number;
// 消耗的体力
readonly cost: number;
// 前置关卡
readonly previousGk: number;
// 每日任务下的小类型
readonly dailyType: number;
}
export const dicWar = new Map<number, DicWar>();
for(let filename of WAR_RELATE_TABLES) {
const str = readJsonFile(filename);
let arr = JSON.parse(str);
arr.forEach(o => {
o.fixReward = parseFixReward(o.fixReward);
o.conditionReward = parseConditionReward(o.conditionReward);
o.parseRandomReward = parseRandomReward(o.parseRandomReward);
dicWar.set(o.war_id, o);
});
}
function parseFixReward(str: string) {
let result = new Array<{id: number, count: number}>();
if(!str) return result;
let decodeArr = decodeArrayListStr(str);
for(let [id, count] of decodeArr) {
if(isNaN(parseInt(id)) || isNaN(parseInt(count))) {
throw new Error('data table format wrong');
}
result.push({id: parseInt(id), count: parseInt(count)});
}
return result
}
function parseConditionReward(str: string) {
let result = new Array<{id: number, count: number, condition: number}>();
if(!str) return result;
let decodeArr = decodeArrayListStr(str);
for(let [id, count, condition] of decodeArr) {
if(isNaN(parseInt(id)) || isNaN(parseInt(count)) || isNaN(parseInt(condition))) {
throw new Error('data table format wrong');
}
result.push({id: parseInt(id), count: parseInt(count), condition: parseInt(condition)});
}
return result
}
function parseRandomReward(str: string) {
let result = new Array<{id: number, count: number, frequency: number}>();
if(!str) return result;
let decodeArr = decodeArrayListStr(str);
for(let [id, count, frequency] of decodeArr) {
if(isNaN(parseInt(id)) || isNaN(parseInt(count)) || isNaN(parseInt(frequency))) {
throw new Error('data table format wrong');
}
result.push({id: parseInt(id), count: parseInt(count), frequency: parseInt(frequency)});
}
return result
}

View File

@@ -0,0 +1,116 @@
// 关卡表
import {decodeArrayListStr, readWarJsonFileList} from '../util'
import { ABI_TYPE } from '../../consts/abilityConst';
import { Attributes } from '../interface';
export interface DicWarJson {
// 关卡id
readonly warId: number;
// 武将编号
readonly actorId: number;
// 武将名字
readonly actorName: string;
// 战场中指向该角色的唯一代码
readonly dataId: number;
// 角色属于我方/敌方/友军
readonly relation: number;
// 上阵时的方向
readonly direction: number;
// 客户端存入数组的顺序
readonly outIndex: number;
// x坐标
readonly x: number;
// y坐标
readonly y: number;
// 剧本中调用角色时的变量
readonly var: number;
// 角色等级
readonly lv: number;
// 是否隐藏
readonly hide: number;
// 角色使用的AI类型
readonly initial_ai: number;
// 属性
readonly attribute: Attributes;
// 武将技能
readonly skill: string;
// 武将被动技能
readonly seid: string;
// 角色星级
readonly star: number;
// s动画
readonly spine: string;
// boss阶段
readonly bossStage: number;
// 召唤技能的召唤物
readonly callSkillData: string;
}
export const dicWarJson = new Map<number, Array<DicWarJson>>();
readWarJsonFileList().forEach(str => {
let arr = JSON.parse(str);
let warjson = new Array<DicWarJson>();
let warid = 0;
arr.forEach(o => {
o.attribute = parseAttribute(o.attribute);
warid = o.warId;
warjson.push(o);
});
dicWarJson.set(warid, warjson);
})
function parseAttribute(str: string) {
let attribute: Attributes = {};
if(!str) return attribute;
let arr = decodeArrayListStr(str);
for(let [id, value] of arr) {
if(isNaN(parseInt(id)) || isNaN(parseInt(value))) {
throw new Error('data table format wrong');
}
let _id = parseInt(id), _value = parseInt(value);
switch(_id) {
case ABI_TYPE.ABI_HP:
attribute.hp = _value; break;
case ABI_TYPE.ABI_ATK:
attribute.atk = _value; break;
case ABI_TYPE.ABI_MATK:
attribute.matk = _value; break;
case ABI_TYPE.ABI_DEF:
attribute.def = _value; break;
case ABI_TYPE.ABI_MDEF:
attribute.mdef = _value; break;
case ABI_TYPE.ABI_AGI:
attribute.agi = _value; break;
case ABI_TYPE.ABI_LUK:
attribute.luk = _value; break;
case ABI_TYPE.ABI_SPEED:
attribute.speed = _value; break;
case ABI_TYPE.ABI_HIT:
attribute.hit = _value; break;
case ABI_TYPE.ABI_CRI:
attribute.cri = _value; break;
case ABI_TYPE.ABI_FLEE:
attribute.flee = _value; break;
case ABI_TYPE.ABI_ANT_CRI:
attribute.antCri = _value; break;
case ABI_TYPE.ABI_DAMAGE_INCREASE:
attribute.damageIncrease = _value; break;
case ABI_TYPE.ABI_DAMAGE_DECREASE:
attribute.damageDecrease = _value; break;
case ABI_TYPE.ABI_DEF_IGNORE:
attribute.defIngnore = _value; break;
case ABI_TYPE.ABI_BLOOD_SUCK:
attribute.bloodSuck = _value; break;
case ABI_TYPE.ABI_AP:
attribute.ap = _value; break;
default:
break;
}
}
}

View File

@@ -0,0 +1,23 @@
// 寻宝表
import { readJsonFile } from '../util'
import { FILENAME } from '../../consts/consts'
export interface DicXunbao {
// 品质
readonly quality: number;
// 品质名
readonly name: number;
// 协助次数
readonly assistanceTime: number;
// 最低协助等级
readonly assistanceLevel: number;
}
const str = readJsonFile(FILENAME.DIC_XUNBAO);
let arr = JSON.parse(str);
export const dicXunbao = new Map<number, DicXunbao>();
arr.forEach(o => {
dicXunbao.set(o.quality, o);
});

View File

@@ -0,0 +1,27 @@
// 一些通用的interface定义
export interface RewardInter {
id: number;
count: number;
}
export interface Attributes {
hp?: number;
atk?: number;
matk?: number;
def?: number;
mdef?: number;
agi?: number;
luk?: number;
speed?: number;
hit?: number;
cri?: number;
flee?: number;
antCri?: number;
damageIncrease?: number;
damageDecrease?: number;
defIngnore?: number;
bloodSuck?: number;
ap?: number;
}

View File

@@ -6,6 +6,9 @@ import { RoleModel } from '../db/Role';
import { PvpDefenseModel } from '../db/PvpDefense'; import { PvpDefenseModel } from '../db/PvpDefense';
import Actor from './actor'; import Actor from './actor';
import fs = require('fs');
import path = require('path');
const moment = require('moment'); const moment = require('moment');
export function genCode(len) { export function genCode(len) {
@@ -115,6 +118,7 @@ const moment = require('moment');
}; };
} }
/** /**
* 将 | 分隔的字符串解析为数组a|b|c 解析为[a, b, c] * 将 | 分隔的字符串解析为数组a|b|c 解析为[a, b, c]
* @param str 要解析的字符串 * @param str 要解析的字符串
@@ -123,12 +127,20 @@ export function decodeArrayStr(str: string, splitForm='|') {
let last = str.substr(str.length-1, 1); let last = str.substr(str.length-1, 1);
if(last == '&') str = str.substr(0, str.length - 1); if(last == '&') str = str.substr(0, str.length - 1);
if(str == '') { if(str == '') {
return [] return new Array<string>()
} else { } else {
return str.split(splitForm); return str.split(splitForm);
} }
} }
/**
* 将 | 和 & 分隔的字符串解析为 Mapa&b&c|c&d&f 解析为 [[a,b,c], [c,d,f]]
* @param str 要解析的字符串
*/
export function decodeArrayListStr(str: string) {
return decodeArrayStr(str).map(cur => decodeArrayStr(cur, '&'));
}
/** /**
* 将 | 和 & 分隔的字符串解析为 Mapa&b|c&d|e&f 解析为 Map {a=>b, c=>d, e=>f} * 将 | 和 & 分隔的字符串解析为 Mapa&b|c&d|e&f 解析为 Map {a=>b, c=>d, e=>f}
* @param str 要解析的字符串 * @param str 要解析的字符串
@@ -434,4 +446,44 @@ export function deepCopy (obj) {
} }
} }
return target; return target;
}; };
export function readJsonFile(fileName: string) {
const folder = 'jsons';
return fs.readFileSync(path.resolve(__dirname, `../resource/${folder}/${fileName}.json`)).toString('utf8').replace(/^\uFEFF/, '');
}
export function readWarJsonFileList() {
const folder = 'warJsons';
return fs.readdirSync(__dirname + `/../resource/${folder}`)
.map(file => {
return fs.readFileSync(path.resolve(__dirname, `../resource/${folder}/${file}`)).toString('utf8').replace(/^\uFEFF/, '');
});
}
// 字典表常用解析方法
// 解析物品 {"id": number, "count": number} 格式
export function parseReward(str: string) {
let result = new Array<{id: number, count: number}>();
if(!str) return result;
let decodeArr = decodeArrayListStr(str);
for(let [id, count] of decodeArr) {
if(isNaN(parseInt(id)) || isNaN(parseInt(count))) {
throw new Error('data table format wrong');
}
result.push({id: parseInt(id), count: parseInt(count)});
}
return result
}
// 数字列表
export function parseNumberList(str: string) {
let res = new Array<number>();
if(!str) return res;
let arr = decodeArrayStr(str);
for(let g of arr) {
if(g === "") continue;
res.push(parseInt(g));
}
return res;
}

View File

@@ -5,10 +5,10 @@
"quality": 1, "quality": 1,
"reward": "31001&50|31002&100", "reward": "31001&50|31002&100",
"additionalReward": "10201&5|10202&10", "additionalReward": "10201&5|10202&10",
"termsForAdd": "1&2&2|2&2&1|3&1&1", "termsForAdd": "1&8&2|2&2&1|3&1&1",
"actorNeeded": 2, "actorNeeded": 2,
"completeTime": 60, "completeTime": 60,
"suitFloor": 1, "suitFloor": "1&",
"weight": 1 "weight": 1
}, },
{ {
@@ -20,7 +20,7 @@
"termsForAdd": "2&1&1|3&2&1", "termsForAdd": "2&1&1|3&2&1",
"actorNeeded": 2, "actorNeeded": 2,
"completeTime": 60, "completeTime": 60,
"suitFloor": 1, "suitFloor": "1&",
"weight": 1 "weight": 1
}, },
{ {
@@ -32,7 +32,7 @@
"termsForAdd": "2&3&1|3&3&1", "termsForAdd": "2&3&1|3&3&1",
"actorNeeded": 2, "actorNeeded": 2,
"completeTime": 60, "completeTime": 60,
"suitFloor": 1, "suitFloor": "1&",
"weight": 1 "weight": 1
}, },
{ {
@@ -44,7 +44,7 @@
"termsForAdd": "2&4&1|3&4&1", "termsForAdd": "2&4&1|3&4&1",
"actorNeeded": 2, "actorNeeded": 2,
"completeTime": 60, "completeTime": 60,
"suitFloor": 1, "suitFloor": "1&",
"weight": 1 "weight": 1
}, },
{ {
@@ -53,10 +53,10 @@
"quality": 2, "quality": 2,
"reward": "17007&50|17008&100", "reward": "17007&50|17008&100",
"additionalReward": "10501&5|10502&10", "additionalReward": "10501&5|10502&10",
"termsForAdd": "1&1&1|2&4&1|3&5&1", "termsForAdd": "1&9&1|2&4&1|3&5&1",
"actorNeeded": 2, "actorNeeded": 2,
"completeTime": 60, "completeTime": 60,
"suitFloor": 1, "suitFloor": "1&",
"weight": 1 "weight": 1
}, },
{ {
@@ -68,7 +68,7 @@
"termsForAdd": "3&6&1", "termsForAdd": "3&6&1",
"actorNeeded": 2, "actorNeeded": 2,
"completeTime": 60, "completeTime": 60,
"suitFloor": 1, "suitFloor": "1&",
"weight": 1 "weight": 1
}, },
{ {
@@ -80,7 +80,7 @@
"termsForAdd": "3&7&1", "termsForAdd": "3&7&1",
"actorNeeded": 2, "actorNeeded": 2,
"completeTime": 60, "completeTime": 60,
"suitFloor": 1, "suitFloor": "1&",
"weight": 1 "weight": 1
}, },
{ {
@@ -92,7 +92,7 @@
"termsForAdd": "3&8&2", "termsForAdd": "3&8&2",
"actorNeeded": 3, "actorNeeded": 3,
"completeTime": 60, "completeTime": 60,
"suitFloor": 1, "suitFloor": "10&",
"weight": 1 "weight": 1
}, },
{ {
@@ -104,7 +104,7 @@
"termsForAdd": "1&1&1|2&1&1|3&1&1", "termsForAdd": "1&1&1|2&1&1|3&1&1",
"actorNeeded": 3, "actorNeeded": 3,
"completeTime": 60, "completeTime": 60,
"suitFloor": 1, "suitFloor": "10&",
"weight": 1 "weight": 1
}, },
{ {
@@ -116,7 +116,7 @@
"termsForAdd": "1&2&1|2&2&1|3&2&1", "termsForAdd": "1&2&1|2&2&1|3&2&1",
"actorNeeded": 3, "actorNeeded": 3,
"completeTime": 120, "completeTime": 120,
"suitFloor": 1, "suitFloor": "10&",
"weight": 1 "weight": 1
}, },
{ {
@@ -125,10 +125,10 @@
"quality": 4, "quality": 4,
"reward": "10105&50|10201&100", "reward": "10105&50|10201&100",
"additionalReward": "10703&5|10704&10", "additionalReward": "10703&5|10704&10",
"termsForAdd": "1&1&1|2&3&1|3&3&1", "termsForAdd": "1&3&1|2&3&1|3&3&1",
"actorNeeded": 3, "actorNeeded": 3,
"completeTime": 120, "completeTime": 120,
"suitFloor": 1, "suitFloor": "10&",
"weight": 1 "weight": 1
}, },
{ {
@@ -137,10 +137,10 @@
"quality": 4, "quality": 4,
"reward": "10202&50|10203&100", "reward": "10202&50|10203&100",
"additionalReward": "10705&5|12001&10", "additionalReward": "10705&5|12001&10",
"termsForAdd": "1&2&1|2&4&1|3&4&1", "termsForAdd": "1&4&1|2&4&1|3&4&1",
"actorNeeded": 3, "actorNeeded": 3,
"completeTime": 120, "completeTime": 120,
"suitFloor": 1, "suitFloor": "10&",
"weight": 1 "weight": 1
}, },
{ {
@@ -149,10 +149,10 @@
"quality": 5, "quality": 5,
"reward": "10204&50|10205&100", "reward": "10204&50|10205&100",
"additionalReward": "12002&5|12003&10", "additionalReward": "12002&5|12003&10",
"termsForAdd": "1&1&1|2&1&1|3&5&1", "termsForAdd": "1&5&1|2&1&1|3&5&1",
"actorNeeded": 3, "actorNeeded": 3,
"completeTime": 120, "completeTime": 120,
"suitFloor": 1, "suitFloor": "10&",
"weight": 1 "weight": 1
}, },
{ {
@@ -161,10 +161,10 @@
"quality": 5, "quality": 5,
"reward": "10301&50|10302&100", "reward": "10301&50|10302&100",
"additionalReward": "12004&5|12005&10", "additionalReward": "12004&5|12005&10",
"termsForAdd": "1&2&1|2&2&1|3&6&1", "termsForAdd": "1&6&1|2&2&1|3&6&1",
"actorNeeded": 3, "actorNeeded": 3,
"completeTime": 120, "completeTime": 120,
"suitFloor": 1, "suitFloor": "10&",
"weight": 1 "weight": 1
}, },
{ {
@@ -173,10 +173,10 @@
"quality": 5, "quality": 5,
"reward": "10303&50|10304&100", "reward": "10303&50|10304&100",
"additionalReward": "12006&5|12007&10", "additionalReward": "12006&5|12007&10",
"termsForAdd": "1&1&1|2&3&1|3&7&1", "termsForAdd": "1&7&1|2&3&1|3&7&1",
"actorNeeded": 3, "actorNeeded": 3,
"completeTime": 120, "completeTime": 120,
"suitFloor": 1, "suitFloor": "10&",
"weight": 1 "weight": 1
} }
] ]