// 物品表 import { decodeArrayListStr, readFileAndParse, parseGoodStr, parseNumberList, decodeArrayStr } from '../util' import { FILENAME, IT_TYPE, ABI_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; // 特殊材料 readonly specialMaterial: SpecialMaterial; // 分解所得 readonly decomposeItem: Array; // 物品品质 readonly quality: number; // 洞数 readonly hole: number; // 随机属性范围 readonly randomEffect: Array; // 类型id readonly itid: number; // 物品类型 readonly goodType: number; // 将魂对应武将id readonly hid: number; // 属性 readonly goodsAbility: Map; // 强化属性 readonly goodsAbilityUp: Map; // 套装id readonly suitId: number; // 特殊属性 readonly specialAttr: Map; // 属性外加的值,经验,好感 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 = { [P in keyof Required]: true }; const DicGoodsKeys: KeysEnum = { 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 dicGoods = new Map(); export const blueprtWithQuality = new Map>(); export const blueprtWithQualityAndStar = new Map>(); export const figureCondition = new Map(); // type => {params, id, gid} export function loadGoods() { 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(); arr.push(o.good_id); blueprtWithQualityAndStar.set(`${o.quality}_${o.equipLvl}`, arr); let arr2 = blueprtWithQuality.get(o.quality) || new Array(); arr.push(o.good_id); blueprtWithQuality.set(o.quality, arr2); } }); arr = undefined; } function parseSpecialAttr(str: string) { let specialAttr = new Map(); 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(); 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(); 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(), 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(); 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 }