Files
ZYZ/shared/pubUtils/dictionary/DicGoods.ts
2021-12-23 10:36:18 +08:00

256 lines
8.4 KiB
TypeScript

// 物品表
import { decodeArrayListStr, readFileAndParse, parseGoodStr, parseNumberList, decodeArrayStr } from '../util'
import { FILENAME, IT_TYPE, ABI_TYPE, GOOD_TYPE } from '../../consts'
import { RewardInter } from '../interface';
const _ = require('lodash');
import { findWhere } from 'underscore';
export interface SpecialMaterial {
readonly ids: number[];
readonly count: number;
}
export interface DicGoods {
// 物品id
readonly good_id: number;
// 物品名
readonly name: string;
// 等级限制
readonly lvLimited: number;
// 星级
readonly equipLvl: number;
// 职业限制
readonly jobLimited: number[];
// 武将限制
readonly charLimited: number[];
// 合成装备需要的碎片数
readonly pieces: number;
// 对应的碎片id
readonly pieceId: number;
// 合成材料
readonly composeMaterial: Array<RewardInter>;
// 特殊材料
readonly specialMaterial: SpecialMaterial;
// 分解所得
readonly decomposeItem: Array<RewardInter>;
// 物品品质
readonly quality: number;
// 洞数
readonly hole: number;
// 随机属性范围
readonly randomEffect: Array<number>;
// 类型id
readonly itid: number;
// 物品类型
readonly goodType: number;
// 将魂对应武将id
readonly hid: number;
// 属性
readonly goodsAbility: Map<number, number>;
// 强化属性
readonly goodsAbilityUp: Map<number, number>;
// 套装id
readonly suitId: number;
// 特殊属性
readonly specialAttr: Map<number, number>;
// 属性外加的值,经验,好感
readonly value: number;
readonly count?: number;
readonly nextJewelId?: number;
readonly specialCount?: number;
readonly nextSpecialId?: number;
// 对应的装备id
readonly equipId?: number;
// 解锁条件
readonly condition: { id: number, type: number, params: number[] }[];
// 时间限制
readonly timeLimit: number;
// 图片
readonly image_id: number;
// 礼包id
readonly gift: number;
}
type KeysEnum<T> = { [P in keyof Required<T>]: true };
const DicGoodsKeys: KeysEnum<DicGoods> = {
good_id: true,
name: true,
lvLimited: true,
pieces: true,
composeMaterial: true,
specialMaterial: true,
decomposeItem: true,
quality: true,
hole: true,
randomEffect: true,
itid: true,
goodType: true,
hid: true,
goodsAbility: true,
goodsAbilityUp: true,
suitId: true,
specialAttr: true,
value: true,
pieceId: true,
count: true,
nextJewelId: true,
specialCount: true,
nextSpecialId: true,
equipId: true,
condition: true,
timeLimit: true,
image_id: true,
gift: true,
jobLimited: true,
charLimited: true,
equipLvl: true
}
export const dicJewel = new Map<number, DicGoods>();
export const dicGoods = new Map<number, DicGoods>();
export const blueprtWithQuality = new Map<number, Array<number>>();
export const blueprtWithQualityAndStar = new Map<string, Array<number>>();
export const figureCondition = new Map<number, { params: number[], id: number, gid: number }[]>(); // type => {params, id, gid}
export function loadGoods() {
dicJewel.clear();
dicGoods.clear();
blueprtWithQuality.clear();
blueprtWithQualityAndStar.clear();
figureCondition.clear();
let arr = readFileAndParse(FILENAME.DIC_GOODS);
arr.forEach(o => {
o.goodsAbility = parseAbility(o);
o.goodsAbilityUp = parseAbilityUp(o);
o.composeMaterial = parseGoodStr(o.composeMaterial);
o.decomposeItem = parseGoodStr(o.decomposeItem);
o.specialAttr = parseSpecialAttr(o.specialAttr);
o.specialMaterial = parseSpecialMaterial(o.specialMaterial);
o.randomEffect = parseNumberList(o.randomEffect);
o.timeLimit = o.timelimit;
if (o.goodType == IT_TYPE.EQUIP_PIECE) {
let good = findWhere(arr, { pieceId: o.good_id });
if (!!good)
o.equipId = good.good_id;
}
let condition = parseConditionStr(o.condition);
for (let { id, type, params } of condition) {
let mapArr = figureCondition.get(type) || new Array<{ params: number[], id: number, gid: number }>();
mapArr.push({ params, id: id, gid: o.good_id });
figureCondition.set(type, mapArr);
}
o.condition = condition;
o.jobLimited = parseNumberList(o.jobLimited);
o.charLimited = parseNumberList(o.charLimited);
dicGoods.set(o.good_id, _.pick(o, Object.keys(DicGoodsKeys)));
if (o.itid == IT_TYPE.BLUEPRT) {
let arr = blueprtWithQualityAndStar.get(`${o.quality}_${o.equipLvl}`) || new Array<number>();
arr.push(o.good_id);
blueprtWithQualityAndStar.set(`${o.quality}_${o.equipLvl}`, arr);
let arr2 = blueprtWithQuality.get(o.quality) || new Array<number>();
arr.push(o.good_id);
blueprtWithQuality.set(o.quality, arr2);
} else if (o.goodType == GOOD_TYPE.JEWEL) {
let material = o.composeMaterial[0];
if (!!material && !!material.id) {
let lastJewel = findWhere(arr, { good_id: material.id });
if (!!lastJewel) {
lastJewel.count = material.count;
lastJewel.nextJewelId = o.good_id;
if (!!o.specialMaterial.ids[0]) {
lastJewel.specialCount = o.specialMaterial.count;
lastJewel.nextSpecialId = o.specialMaterial.ids[0];
}
dicJewel.set(lastJewel.good_id, _.pick(lastJewel, Object.keys(DicGoodsKeys)));
}
} else {
dicJewel.set(o.good_id, _.pick(o, Object.keys(DicGoodsKeys)));
}
}
});
arr = undefined;
}
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_DEF, json.def || 0);
map.set(ABI_TYPE.ABI_MDEF, json.mdef || 0);
map.set(ABI_TYPE.ABI_DAMAGE_INCREASE, json.damageIncrease || 0);
map.set(ABI_TYPE.ABI_DAMAGE_DECREASE, json.damageDecrease || 0);
map.set(ABI_TYPE.ABI_PHYSICAL_DAMAGE_DECREASE, json.atkDecrease || 0);
map.set(ABI_TYPE.ABI_MAGIC_DAMAGE_DECREASE, json.matkDecrease || 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_DEF, json.def_up || 0);
map.set(ABI_TYPE.ABI_MDEF, json.mdef_up || 0);
map.set(ABI_TYPE.ABI_DAMAGE_INCREASE, json.damageIncrease_up || 0);
map.set(ABI_TYPE.ABI_DAMAGE_DECREASE, json.damageDecrease_up || 0);
return map
}
function parseSpecialMaterial(str: string) {
let specialAttr = { ids: new Array<number>(), count: 0 }
if (!str) return specialAttr;
let decodeArr = decodeArrayStr(str);
if (decodeArr.length >= 2) {
let ids = parseNumberList(decodeArr[0]);
let count = parseInt(decodeArr[1]);
if (isNaN(count)) return specialAttr;
specialAttr.ids = ids;
specialAttr.count = count;
}
return specialAttr;
}
// 解析物品 {"type": number, "param": number} 格式
export function parseConditionStr(str: string) {
let result = new Array<{ id: number, type: number, params: number[] }>();
if (!str) return result;
let decodeArr = decodeArrayListStr(str);
for (let i = 0; i < decodeArr.length; i++) {
let [type, ...params] = decodeArr[i];
if (isNaN(parseInt(type))) {
throw new Error('data table format wrong');
}
let parsedParam = new Array<number>();
for (let param of params) {
if (isNaN(parseInt(param))) {
throw new Error('data table format wrong');
}
parsedParam.push(parseInt(param))
}
result.push({ id: i + 1, type: parseInt(type), params: parsedParam });
}
return result
}