feat(宝物): 添加宝物系统

This commit is contained in:
luying
2022-12-07 10:55:30 +08:00
parent b684307818
commit a83deeff5f
46 changed files with 15656 additions and 54 deletions

View File

@@ -110,6 +110,13 @@ import { dicLadderMatch, loadLadderMatch } from "./dictionary/DicLadderMatch";
import { dicLadderDifficultRatio, loadLadderDifficultRatio } from "./dictionary/DicLadderDifficultRatio";
import { dicLadderRankReward, loadLadderRankReward } from "./dictionary/DicLadderRankReward";
import { dicGeneralGoods, loadGeneralGoods } from "./dictionary/DicGeneralGoods";
import { dicArtifact, dicArtifactByGid, dicArtifactByGidAndType, dicArtifactsByGroup, loadArtifact } from "./dictionary/DicArtifact";
import { DicArtifactLvPlan, dicArtifactLvPlan, loadArtifactLvPlan } from "./dictionary/DicArtifactLvPlan";
import { dicArtifactQuality, dicArtifactQualityById, loadArtifactQuality } from "./dictionary/DicArtifactQuality";
import { dicArtifactQualityPlan, loadArtifactQualityPlan } from "./dictionary/DicArtifactQualityPlan";
import { dicArtifactSeid, loadArtifactSeid } from "./dictionary/DicArtifactSeid";
import { DicArtifact } from "./dictionary/DicArtifact";
import { DicArtifactQuality } from "./dictionary/DicArtifactQuality";
export const gameData = {
daily: dicDaily,
@@ -277,6 +284,15 @@ export const gameData = {
comBattleRewardTime: new Array<{from: string, to: string}>(),
comBattleReward: dicComBattleReward,
relationGoods: dicGeneralGoods,
artifact: dicArtifact,
artifactByGid: dicArtifactByGid,
artifactByGidAndType: dicArtifactByGidAndType,
artifactLvPlan: dicArtifactLvPlan,
artifactQuality: dicArtifactQuality,
artifactQualityById: dicArtifactQualityById,
artifactQualityPlan: dicArtifactQualityPlan,
artifactSeid: dicArtifactSeid,
artifactByGroupAndQuality: dicArtifactsByGroup,
};
// 在此提供一些原先在gamedata中提供的方法以便更方便获取gameData数据
@@ -991,6 +1007,64 @@ export function getShopType(shop: number, type: number) {
return gameData.shopType.get(key)||null;
}
export function getDefArtifactByGid(gid: number): DicArtifact {
let artifactId = gameData.artifactByGid.get(gid);
return gameData.artifact.get(artifactId);
}
export function getDicArtifactQualityByStage(quality: number, qualityStage: number): DicArtifactQuality {
let uniqId = gameData.artifactQuality.get(`${quality}_${qualityStage}`);
return gameData.artifactQualityById.get(uniqId);
}
export function getNextArtifactQuality(quality: number, qualityStage: number): DicArtifactQuality {
let dicArtifactQuality = getDicArtifactQualityByStage(quality, qualityStage);
if(!dicArtifactQuality) return null;
return gameData.artifactQualityById.get(dicArtifactQuality.nextId);
}
export function getNextArtifact(artifactId: number): (DicArtifact&DicArtifactQuality) {
let dicArtifact = gameData.artifact.get(artifactId);
if(!dicArtifact) return null;
let dicNextArtifactQuality = getNextArtifactQuality(dicArtifact.quality, dicArtifact.qualityStage);
if(!dicNextArtifactQuality) return null;
let dicNextArtifact = getArtifactByGroupAndQuality(dicArtifact.group, dicArtifact.type, dicNextArtifactQuality.quality, dicNextArtifactQuality.qualityStage);
if(!dicNextArtifact) return null;
return {...dicNextArtifact, ...dicNextArtifactQuality}
}
export function getArtifactStageZero(artifactId: number): (DicArtifact&DicArtifactQuality) {
let dicArtifact = getArtifactWithQuality(artifactId);
if(!dicArtifact) return null;
let dicZeroArtifact = gameData.artifactByGroupAndQuality.get(`${dicArtifact.group}_${dicArtifact.type}_${dicArtifact.quality}_${0}`);
if(!dicZeroArtifact) return null;
let dicZeroArtifactQuality = getDicArtifactQualityByStage(dicArtifact.quality, dicArtifact.qualityStage);
if(!dicZeroArtifactQuality) return null;
return {...dicZeroArtifact, ...dicZeroArtifactQuality}
}
export function getArtifactByGroupAndQuality(group: string, type: number, quality: number, qualityStage: number): DicArtifact {
return gameData.artifactByGroupAndQuality.get(`${group}_${type}_${quality}_${qualityStage}`);
}
export function getDicArtifactLvByPlanId(planId: number, lv: number): DicArtifactLvPlan {
let map = gameData.artifactLvPlan.get(planId);
return map?.get(lv);
}
export function getArtifactByGidAndType(goodId: number, type: number): DicArtifact {
let artifactId = gameData.artifactByGidAndType.get(`${goodId}_${type}`);
return gameData.artifact.get(artifactId);
}
export function getArtifactWithQuality(artifactId: number): (DicArtifact&DicArtifactQuality) {
let dicArtifact = gameData.artifact.get(artifactId);
if(!dicArtifact) return null;
let dicArtifactQuality = getDicArtifactQualityByStage(dicArtifact.quality, dicArtifact.qualityStage);
if(!dicArtifactQuality) return null;
return {...dicArtifact, ...dicArtifactQuality}
}
// 初始加载
function initDatas() {
parseDicParam();
@@ -1180,6 +1254,11 @@ function loadDatas() {
loadLadderDifficultRatio();
loadLadderRankReward();
loadGeneralGoods();
loadArtifact();
loadArtifactLvPlan();
loadArtifactQuality();
loadArtifactQualityPlan();
loadArtifactSeid();
}
// 重载dicParam

View File

@@ -178,6 +178,8 @@ export const BAG = {
BAG_EQUIP_UPLIMITED: 500, // 背包中装备数量上限
BAG_GOODS_UPLIMITED: 4294967295, // 背包中可叠加的道具数量上限
BAG_RESOLVE_UPLIMITED: 500, // 背包中一键分解的上限
BAG_ARTIFACT_UPLIMITED: 500, // 背包中宝物数量上限
BAG_ARTIFACT_DECOMPOSE_UPLIMITED: 500, // 背包中宝物一键分解的上限
};
export const ATTRIBUTE = {
ATTRIBUTE_EQUIP_RATIO: '1&1|2&3|4&2|5&2', // 装备的基础属性系数
@@ -358,3 +360,10 @@ export const MINIGAME = {
MINIGAME_ARCHER_RANGE: '0&100|29&80|69&60|104&40|143&20|177&0', // 射箭小游戏圈数积分
MINIGAME_FLIPCARD_TYPE: 'baihe|guyuan|hongdou|huasheng|lianzi|nuomi|yimi|zao', // 翻牌游戏资源
};
export const JEWEL = {
JEWELQUALITY: '0&1|25&2|50&3|75&4|100&5', // 天晶词条颜色修改
};
export const ARTIFACT = {
TRANSFER_COST: '31002&100', // 宝物转换形态消耗
REBUILD_COST: '31002&100', // 宝物重铸消耗
};

View File

@@ -0,0 +1,73 @@
// 物品表
import { readFileAndParse, parseNumberList, } from '../util'
import { FILENAME, } from '../../consts'
const _ = require('lodash');
export interface DicArtifact {
// 宝物idt其中形态1和goodId必须一致
readonly artifactId: number;
// 宝物名
readonly name: string;
// 物品表id不同品质&品阶的同名宝物的物品id不同
readonly goodId: number;
// 同名宝物比如史记可以直接写shiji不过要当心多音词注意唯一性
readonly group: string;
// 形态
readonly type: number;
// 是否是初始形态,用于服务器获取
readonly isDefaultType: boolean;
// 品质每个宝物id直接对应一种品质
readonly quality: number;
// 品阶每个宝物id直接对应一种品阶
readonly qualityStage: number;
// 专属职业
readonly jobClass: number;
// 专属武将
readonly hid: number;
// 词条seid&seid
readonly seids: number[];
// 等级配置方案
readonly lvAttrPlan: number;
// 升品配置方案
readonly qualityAttrPlan: number;
}
type KeysEnum<T> = { [P in keyof Required<T>]: true };
const DicArtifactKeys: KeysEnum<DicArtifact> = {
artifactId: true,
name: true,
goodId: true,
group: true,
type: true,
isDefaultType: true,
quality: true,
qualityStage: true,
jobClass: true,
hid: true,
seids: true,
lvAttrPlan: true,
qualityAttrPlan: true,
}
export const dicArtifact = new Map<number, DicArtifact>();
export const dicArtifactByGid = new Map<number, number>();
export const dicArtifactByGidAndType = new Map<string, number>();
export const dicArtifactsByGroup = new Map<string, DicArtifact>();
export function loadArtifact() {
dicArtifact.clear();
dicArtifactByGid.clear();
dicArtifactByGidAndType.clear();
dicArtifactsByGroup.clear();
let arr = readFileAndParse(FILENAME.DIC_ARTIFACT);
arr.forEach(o => {
o.seids = parseNumberList(o.seids);
if(o.isDefaultType) dicArtifactByGid.set(o.goodId, o.artifactId);
dicArtifactByGidAndType.set(`${o.goodId}_${o.type}`, o.artifactId);
dicArtifact.set(o.artifactId, _.pick(o, Object.keys(DicArtifactKeys)));
dicArtifactsByGroup.set(`${o.group}_${o.type}_${o.quality}_${o.qualityStage}`, o);
});
arr = undefined;
}

View File

@@ -0,0 +1,54 @@
// 物品表
import { readFileAndParse, parseGoodStr, decodeArrayListStr, } from '../util'
import { FILENAME, } from '../../consts'
import { RewardInter } from '../interface';
const _ = require('lodash');
export interface DicArtifactLvPlan {
// 方案id
planId: number;
// 等级
lv: number;
// 升到这级需要消耗什么id&count
consumes: RewardInter[];
// 这级的属性
attr: {id: number, attr: number}[];
}
type KeysEnum<T> = { [P in keyof Required<T>]: true };
const DicArtifactLvPlanKeys: KeysEnum<DicArtifactLvPlan> = {
planId: true,
lv: true,
consumes: true,
attr: true,
}
export const dicArtifactLvPlan = new Map<number, Map<number, DicArtifactLvPlan>>(); // planId => lv => dic
export function loadArtifactLvPlan() {
dicArtifactLvPlan.clear();
let arr = readFileAndParse(FILENAME.DIC_ARTIFACT_LV_PLAN);
arr.forEach(o => {
o.consumes = parseGoodStr(o.consumes);
o.attr = parseAttr(o.attr);
if(!dicArtifactLvPlan.has(o.planId)) {
dicArtifactLvPlan.set(o.planId, new Map());
}
dicArtifactLvPlan.get(o.planId)?.set(o.lv, _.pick(o, Object.keys(DicArtifactLvPlanKeys)));
});
arr = undefined;
}
function parseAttr(str: string) {
let result = new Array<{id: number, attr: number}>();
if(!str) return result;
let decodeArr = decodeArrayListStr(str);
for(let [id, attr] of decodeArr) {
if(isNaN(parseInt(id)) || isNaN(parseInt(attr))) {
throw new Error('data table format wrong');
}
result.push({id: parseInt(id), attr: parseInt(attr)});
}
return result
}

View File

@@ -0,0 +1,66 @@
// 物品表
import { readFileAndParse, parseGoodStr, } from '../util'
import { FILENAME, } from '../../consts'
import { RewardInter } from '../interface';
const _ = require('lodash');
export interface DicArtifactQuality {
// 唯一id品质+品阶=唯一
uniqId: number;
// 品质key1
quality: number;
// 品阶key2
qualityStage: number;
// 这个品质下最大的等级
maxLv: number;
// 合成相关
// 可以合成到他这个品质的uniqId即原料的品质+品阶
previousId: number;
// 下一阶uniqId
nextId: number;
// 作为狗粮的宝物品质uniqId
materialId: number;
// 作为狗粮的宝物的数量
materialCnt: number;
// 作为狗粮的是否需要同名 1-是 0-不是
materialGroup: number;
// 是否可以分解 1-是 0-不是
canDecompose: number;
// 是否可以一键合成 1-是 0-不是
canComposeAll: number;
// 这个品质可以替换的通用道具id&count。分解同样用这个字段不可分解填&
generalItem: RewardInter[];
}
type KeysEnum<T> = { [P in keyof Required<T>]: true };
const DicArtifactQualityKeys: KeysEnum<DicArtifactQuality> = {
uniqId: true,
quality: true,
qualityStage: true,
maxLv: true,
previousId: true,
nextId: true,
materialId: true,
materialCnt: true,
materialGroup: true,
canDecompose: true,
canComposeAll: true,
generalItem: true,
}
export const dicArtifactQuality = new Map<string, number>(); // quality+qualityStage
export const dicArtifactQualityById = new Map<number, DicArtifactQuality>(); // uniqId
export function loadArtifactQuality() {
dicArtifactQuality.clear();
dicArtifactQualityById.clear();
let arr = readFileAndParse(FILENAME.DIC_ARTIFACT_QUALITY);
arr.forEach(o => {
o.generalItem = parseGoodStr(o.generalItem);
dicArtifactQualityById.set(o.uniqId, _.pick(o, Object.keys(DicArtifactQualityKeys)));
dicArtifactQuality.set(`${o.quality}_${o.qualityStage}`, o.uniqId);
});
arr = undefined;
}

View File

@@ -0,0 +1,44 @@
// 物品表
import { readFileAndParse, decodeArrayListStr, } from '../util'
import { FILENAME, } from '../../consts'
const _ = require('lodash');
export interface DicArtifactQualityPlan {
// 方案id
planId: number;
// 这级的属性
attr: {id: number, attr: number}[];
}
type KeysEnum<T> = { [P in keyof Required<T>]: true };
const DicArtifactQualityPlanKeys: KeysEnum<DicArtifactQualityPlan> = {
planId: true,
attr: true,
}
export const dicArtifactQualityPlan = new Map<number, DicArtifactQualityPlan>();
export function loadArtifactQualityPlan() {
dicArtifactQualityPlan.clear();
let arr = readFileAndParse(FILENAME.DIC_ARTIFACT_QUALITY_PLAN);
arr.forEach(o => {
o.attr = parseAttr(o.attr);
dicArtifactQualityPlan.set(o.planId, _.pick(o, Object.keys(DicArtifactQualityPlanKeys)));
});
arr = undefined;
}
function parseAttr(str: string) {
let result = new Array<{id: number, attr: number}>();
if(!str) return result;
let decodeArr = decodeArrayListStr(str);
for(let [id, attr] of decodeArr) {
if(isNaN(parseInt(id)) || isNaN(parseInt(attr))) {
throw new Error('data table format wrong');
}
result.push({id: parseInt(id), attr: parseInt(attr)});
}
return result
}

View File

@@ -0,0 +1,36 @@
// 物品表
import { readFileAndParse, } from '../util'
import { FILENAME, } from '../../consts'
const _ = require('lodash');
export interface DicArtifactQuality {
// 对应的se表的id
seid: number;
// 解锁的品质
quality: number;
// 生效的职业0表示全生效
jobClass: number;
// 生效的武将
hid: number;
}
type KeysEnum<T> = { [P in keyof Required<T>]: true };
const DicArtifactSeidKeys: KeysEnum<DicArtifactQuality> = {
seid: true,
quality: true,
jobClass: true,
hid: true,
}
export const dicArtifactSeid = new Map<number, DicArtifactQuality>(); // seid => dic
export function loadArtifactSeid() {
dicArtifactSeid.clear();
let arr = readFileAndParse(FILENAME.DIC_ARTIFACT_SEID);
arr.forEach(o => {
dicArtifactSeid.set(o.seid, _.pick(o, Object.keys(DicArtifactSeidKeys)));
});
arr = undefined;
}

View File

@@ -745,6 +745,15 @@ export function addToMap<T>(map: Map<T, number>, id: T, value: number) {
}
}
export function arrToMap<T>(arr: T[], getKey: (obj: T) => number): Map<number, T> {
let map = new Map();
for(let obj of arr) {
let key = getKey(obj);
map.set(key, obj);
}
return map;
}
// /**
// * 计算最强阵容战力
// * @param role