装备:淬火

This commit is contained in:
luying
2021-07-29 14:21:51 +08:00
parent dc832da60a
commit 972abb7d07
19 changed files with 805 additions and 68 deletions
+22 -22
View File
@@ -1,26 +1,26 @@
//武将养成系统分类
export const HERO_SYSTEM_TYPE = {
INIT: 0,
STAR: 1,
LVUP: 2,
COLORSTAR: 3,
QUALITY: 4,
TRAIN: 5,
STAGEUP:6,
SKIN:7,
FAVOUR:8,
CONNECT:9,
EQUIP: 10,
EQUIP_BASE: 11,
RESTRENGTHEN: 12,
JEWEL_ON: 13,
JEWEL_OFF: 14,
ADD_SKIN: 15,
SCHOOL: 16,
SCROLL: 17,
TITLE: 18,
TERAPH: 19,
TERAPH_UP: 20
export enum HERO_SYSTEM_TYPE {
INIT = 0, // 初始武将
STAR = 1, // 升星
LVUP = 2, // 升级
COLORSTAR = 3, // 觉醒
QUALITY = 4, // 升品
TRAIN = 5, // (职业)训练
STAGEUP =6, // (职业)升阶
SKIN =7, // 皮肤
FAVOUR =8, // 好感
CONNECT =9, // 羁绊
EQUIP = 10, // 装备穿脱
EQUIP_BASE = 11, // 装备栏升级,装备精炼等
RESTRENGTHEN = 12, // 洗练
JEWEL_ON = 13, // 穿宝石
JEWEL_OFF = 14, // 脱宝石
ADD_SKIN = 15, // 第一次获取皮肤(全局)
SCHOOL = 16, // 百家学宫
SCROLL = 17, // 名将谱
TITLE = 18, // 爵位
TERAPH = 19, // 神像强化
TERAPH_UP = 20, // 神像升级
};
// 武将上限
+6
View File
@@ -273,4 +273,10 @@ export const SPECIAL_ATTR = {
WAR_ID: 1,
TREASURE_ID: 2,
TREASURE_TYPE: 3
}
// 淬火类型
export enum QUENCH_TYPE {
ONCE = 1, // 升一级
ONE_GRADE = 2, // 升一品
}
+4 -1
View File
@@ -458,7 +458,10 @@ export const FILENAME = {
DIC_AP_BUY_COST: 'dic_zyz_daliyAP',
DIC_GK_NEWHERO: 'dic_zyz_gk_newhero',
DIC_TASK_EXP: 'dic_zyz_mainTaskExp',
DIC_GK_PROBATION: 'dic_zyz_gk_probation'
DIC_GK_PROBATION: 'dic_zyz_gk_probation',
DIC_QUENCH: 'dic_zyz_quench',
DIC_QUENCH_QUALITY: 'dic_zyz_quench_quality',
DIC_QUENCH_CONSUME: 'dic_zyz_quench_consume',
}
export const WAR_RELATE_TABLES = [
+1
View File
@@ -277,6 +277,7 @@ export const STATUS = {
EQUIP_NOT_EQUIPED_HERO: { code: 30509, simStr: '装备不能被该武将穿戴' },
EQUIP_LEVEL_LIMIT: { code: 30510, simStr: '装备穿戴等级限制' },
EQUIP_NOT_MATCH_JEWEL: { code: 30511, simStr: '装备不能镶嵌该宝石' },
EQUIP_QUENCH_ERR: { code: 30512, simStr: '该装备不能再淬火或材料不足' },
//全局养成30600-30699
ROLE_REACH_MAX_TITLE_LEVEL: { code: 30600, simStr: '玩家已达到最高的爵位' },
ROLE_TERAPH_NOT_STRENGTHEN: { code: 30601, simStr: '玩家神像不能强化' },
+16 -14
View File
@@ -24,14 +24,11 @@ export class Holes {
jewel: number; // 装备的宝石id
}
interface equipUpdate {
hid?: number;
quality?: number;
wearLv?: number;
_id?: number;
holes?: Array<Holes>;
randSe?: Array<RandSe>;
ePlaceId?: number;
export class RandMain {
@prop({ required: true })
id: number; // 随机属性位置id
@prop({ required: true })
rand: number; // 随机属性内需要随机的值,扩大100倍
}
@index({ roleId: 1, hid: 1, id: 1 })
@@ -51,7 +48,7 @@ export default class Equip extends BaseModel {
@prop({ required: true })
name: string; // 装备名称
@prop({ required: false, default: 0 })
hid: number; // 装备此装备的武将 id
hid: number; // 装备此装备的武将 id
@prop({ required: false, default: 0 })
ePlaceId: number; // 武将装备的部位
@prop({ required: false, default: 1 })
@@ -60,12 +57,16 @@ export default class Equip extends BaseModel {
@prop({ required: true, default: 1 })
quality: number; // 品质
@prop({ required: true, default: 0 })
suitId: number; // 套装id
suitId: number; // 套装id
@prop({ required: true, default: 0 })
randRange: number; // 固定属性随机值
randRange: number; // 固定属性随机值 // TODO 废弃字段,客户端改完之前暂时保留
@prop({ required: false, type: RandMain, default: [], _id: false })
randMain: RandMain[]; // 主属性随机
@prop({ required: true, default: 0 })
grade: number; // 品相等级
@prop({ required: false, type: RandSe, default: [], _id: false })
randSe: RandSe[]; // 强化随机属性
randSe: RandSe[]; // 强化随机属性
@prop({ required: true, type: Holes, default: [], _id: false })
holes: Holes[];
@@ -79,7 +80,7 @@ export default class Equip extends BaseModel {
return equip;
}
public static async createEquip(equipInfo: { roleId: string, roleName: string, id: number, name: string, quality: number, suitId: number, ePlaceId: number, randSe: RandSe[], randRange: number, holes: Holes[], hid?: number }, lean = true) {
public static async createEquip(equipInfo: equipUpdate, lean = true) {
const seqId = await CounterModel.getNewCounter(COUNTER.EID);
const doc = new EquipModel();
@@ -182,4 +183,5 @@ export const EquipModel = getModelForClass(Equip);
export interface EquipType extends Pick<DocumentType<Equip>, keyof Equip> {
id: number;
};
};
export type equipUpdate = Partial<EquipType>; // 将所有字段变成可选项
+25
View File
@@ -0,0 +1,25 @@
interface QuenchAddParam {
id: number; // 属性id
value: number; // 增加的值
}
export class QuenchLogParam {
times: number; // 第几次
isCriticle: boolean; // 是否暴击
add: QuenchAddParam[];
constructor(isCriticle: boolean, add: Map<number, number>) {
this.isCriticle = isCriticle;
let arr: QuenchAddParam[] = [];
for(let [id, value] of add) {
arr.push({ id, value });
}
this.add = arr;
}
setTimes(times: number) {
this.times = times;
}
}
+40 -1
View File
@@ -88,6 +88,9 @@ import { dicServerName, dicServerGroupName, loadServerName } from "./dictionary/
import { dicAp, loadAp, dicApMaxLevel } from './dictionary/DicAp';
import { dicApBuy, dicApMaxBuyTimes, loadApBuy } from "./dictionary/DicApBuy";
import { dicTaskExp, loadTskExp} from './dictionary/DicTaskExp';
import { dicQuench, loadQuench } from './dictionary/DicQuench';
import { dicQuenchByQuality, dicQuenchByQualityAndGrade, loadQuenchQuality } from './dictionary/DicQuenchQuality';
import { dicQuenchConsume, loadQuenchConsume } from './dictionary/DicQuenchConsume';
export const gameData = {
blurprtCompose: dicBlueprtCompose,
@@ -216,7 +219,11 @@ export const gameData = {
apMaxLevel: dicApMaxLevel,
apBuy: dicApBuy,
apMaxBuyTimes: dicApMaxBuyTimes,
taskExp: dicTaskExp
taskExp: dicTaskExp,
quench: dicQuench,
quenchByQuality: dicQuenchByQuality,
quenchByQualityAndGrade: dicQuenchByQualityAndGrade,
quenchConsume: dicQuenchConsume
};
// 在此提供一些原先在gamedata中提供的方法,以便更方便获取gameData数据
@@ -723,6 +730,34 @@ export function getDicSuitByTypeAndLv(suitType: number, starLevel: number) {
return gameData.suitByTypeAndLv.get(`${suitType}_${starLevel}`);
}
export function getQuenchGradeByValue(value: number) {
let grade = 0;
for(let [_grade, { singleRatioMin, singleRatioMax }] of gameData.quench) {
if(value >= singleRatioMin && value < singleRatioMax ) {
grade = _grade;
}
}
return grade;
}
/**
* 根绝品质和品相获得上下限,当grade为0,获取该品质下全阶的上下限
* @param quality 品质
* @param grade 品相
* @returns {{ min: number, max: number }}
*/
export function getQuenchByQualityAndGrade(quality: number, grade: number) {
if(grade == 0) { // 这个品质的上下限
return gameData.quenchByQuality.get(quality);
} else { // 该品质该品相的上下限
return gameData.quenchByQualityAndGrade.get(`${quality}_${grade}`);
}
}
export function getQuenchConsume(lvLimited: number, quality: number) {
return gameData.quenchConsume.get(`${lvLimited}_${quality}`);
}
// 初始加载
function initDatas() {
parseDicParam();
@@ -824,6 +859,10 @@ function loadDatas() {
loadAp();
loadApBuy();
loadTskExp();
loadQuench();
loadQuenchQuality();
loadQuenchConsume();
}
// 重载dicParam
+29
View File
@@ -0,0 +1,29 @@
import { readFileAndParse } from '../util'
import { FILENAME } from '../../consts'
export interface DicQuench {
// id
readonly id: number;
// 品相
readonly grade: number;
// 品相名
readonly name: string;
// 单属性最小值
readonly singleRatioMin: number;
// 单属性最大值
readonly singleRatioMax: number;
// 暴击效果,倍率
readonly critEffect: number;
// 暴击概率
readonly critProbability: number;
}
export const dicQuench = new Map<number, DicQuench>(); // id => dic
export function loadQuench() {
let arr = readFileAndParse(FILENAME.DIC_QUENCH);
arr.forEach(o => {
dicQuench.set(o.grade, o);
});
arr = undefined;
}
@@ -0,0 +1,25 @@
import { readFileAndParse, parseGoodStr } from '../util'
import { FILENAME } from '../../consts'
import { RewardInter } from '../interface';
export interface DicQuenchConsume {
// id
readonly id: number;
// 等级
readonly equipLvl: number;
// 品质
readonly quality: number;
// 淬火一次的消耗
readonly unitConsume: RewardInter[];
}
export const dicQuenchConsume = new Map<string, RewardInter[]>(); // equipLvl&quality => dic
export function loadQuenchConsume() {
let arr = readFileAndParse(FILENAME.DIC_QUENCH_CONSUME);
arr.forEach(o => {
o.unitConsume = parseGoodStr(o.unitconsume);
dicQuenchConsume.set(`${o.equipLvl}_${o.quality}`, o.unitConsume);
});
arr = undefined;
}
@@ -0,0 +1,42 @@
import { readFileAndParse, parseGoodStr } from '../util'
import { FILENAME } from '../../consts'
export interface DicQuenchQuality {
// id
readonly id: number;
// 装备品质
readonly quality: number;
// 品相
readonly grade: number;
// 单属性最小值
readonly singleRatioMin: number;
// 单属性最大值
readonly singleRatioMax: number;
// 初始是否可以随机出
readonly initialAvailable: number;
}
export const dicQuenchByQualityAndGrade = new Map<string, { min: number, max: number }>();
export const dicQuenchByQuality = new Map<number, { min: number, max: number }>(); // quality => {}
export function loadQuenchQuality() {
dicQuenchByQuality.clear();
dicQuenchByQualityAndGrade.clear();
let arr = readFileAndParse(FILENAME.DIC_QUENCH_QUALITY);
arr.forEach(o => {
if(o.initialAvailable == 1) {
if(!dicQuenchByQuality.has(o.quality)) {
dicQuenchByQuality.set(o.quality, { min: o.singleRatioMin, max: o.singleRatioMax });
} else {
if(o.singleRatioMin < dicQuenchByQuality.get(o.quality).min) {
dicQuenchByQuality.get(o.quality).min = o.singleRatioMin;
}
if(o.singleRatioMax > dicQuenchByQuality.get(o.quality).max) {
dicQuenchByQuality.get(o.quality).max = o.singleRatioMax;
}
}
dicQuenchByQualityAndGrade.set(`${o.quality}_${o.grade}`, { min: o.singleRatioMin, max: o.singleRatioMax });
}
});
arr = undefined;
}
-6
View File
@@ -9,12 +9,6 @@ export interface RewardInter {
export interface EquipInter {
id: number;
name: string;
quality: number;
suitId: number;
hole: number;
randomEffect: Array<number>;
itid: number;
hid?: number;
times?: number;
};
+24 -6
View File
@@ -2,9 +2,9 @@
import { HeroModel, HeroType } from '../db/Hero';
import { ItemModel } from '../db/Item';
import { EquipModel, RandSe, Holes } from './../db/Equip';
import { EquipModel, RandSe, Holes, RandMain } from './../db/Equip';
import { BagInter, EquipInter } from './interface';
import { gameData } from './data';
import { gameData, getQuenchByQualityAndGrade, getQuenchGradeByValue } from './data';
import { RANDOM_SE_COUNT, FIX_ATTRIBUTES_RAN, ITID, CURRENCY_BY_TYPE, CURRENCY_TYPE, ROLE_SELECT, FIGURE_UNLOCK_CONDITION, CONSUME_TYPE, HERO_SYSTEM_TYPE, TASK_TYPE } from '../consts';
import { getRandValueByMinMax, getRandEelm } from './util';
@@ -55,9 +55,11 @@ export async function addBags(roleId: string, roleName: string, data: BagInter)
}
export async function addEquips(roleId: string, roleName: string, weapon: EquipInter) {
let { id, name, quality, suitId, hole, randomEffect, itid, hid } = weapon;
let { id, hid = 0 } = weapon;
let { name, quality, suitId, hole, randomEffect, itid, goodsAbility } = gameData.goods.get(id);
let { type } = ITID.get(itid);
// 随机属性
let randomNum = RANDOM_SE_COUNT.get(quality);
let randomResult: number[] = getRandEelm(randomEffect, randomNum);
@@ -73,14 +75,30 @@ export async function addEquips(roleId: string, roleName: string, weapon: EquipI
};
});
let randRange = getRandValueByMinMax(0 - FIX_ATTRIBUTES_RAN, FIX_ATTRIBUTES_RAN, 0);
let randRange = 0;
// 淬火品相
let randMain: RandMain[] = [];
let grade = 0;
for(let [ attrId, attrValue ] of goodsAbility) {
if(attrValue > 0) {
let { min, max } = getQuenchByQualityAndGrade(quality, grade);
let rand = getRandValueByMinMax(min, max, 0);
grade = getQuenchGradeByValue(rand);
randMain.push({
id: attrId,
rand
});
}
}
let holes = new Array<Holes>();
for (let i = 0; i < hole; i++) {
holes.push({ id: i + 1, isOpen: false, jewel: 0 })
holes.push({ id: i + 1, isOpen: false, jewel: 0 });
}
const equip = await EquipModel.createEquip({ roleId, roleName, id, name, quality, suitId, randRange, ePlaceId: type, randSe, holes, hid });
const equip = await EquipModel.createEquip({ roleId, roleName, id, name, quality, suitId, randRange, ePlaceId: type, randSe, holes, hid, grade, randMain });
// 任务
let pushMessage = await checkTaskWithEquip(roleId, TASK_TYPE.EQUIP_SUIT, equip);
+11 -9
View File
@@ -695,11 +695,8 @@ export function calEquipSeids(hero: HeroType) {
}
}
}
console.log('################')
console.log('#####1', JSON.stringify([...suits]));
for(let [ _suitType, map ] of suits) {
console.log('#####2', _suitType, JSON.stringify([...map]));
let effectSeid = new Map<number, { starLevel: number, seid: number }>(); // count => { starLevel, seid }
for(let [ starLevel, { dic: { effect }, count } ] of map) {
for(let { count: effectCount, seid} of effect) {
@@ -713,7 +710,6 @@ export function calEquipSeids(hero: HeroType) {
for(let [_count, { seid }] of effectSeid) {
seids.push(seid, 0);
}
console.log('#####3', _suitType, JSON.stringify([...effectSeid]));
}
return seids;
}
@@ -750,6 +746,10 @@ export function calHeroEquipIncAttr(hero: HeroType) {
}
}
let randMainMap = new Map<number, number>();
for(let {id, rand} of (e.randMain||[])) {
randMainMap.set(id, rand);
}
for (let i = ABI_TYPE.ABI_HP; i < ABI_TYPE.ABI_MAX; i++) {
// console.log('***', i);
let value1 = goodsAbility.get(i) || 0 * (HERO_CE_RATIO + e.randRange);
@@ -757,17 +757,19 @@ export function calHeroEquipIncAttr(hero: HeroType) {
let valueup = goodsAbilityUp.get(i) || 0;
// console.log('成长', lv, valueup);
let valueRefine = dicRefine ? dicRefine.upPercent : 0;
// console.log('refine', dicRefine?dicRefine.upPercent:0 );
// console.log('精炼', dicRefine?dicRefine.upPercent:0 );
let valueJewel = jewel.get(i) || 0;
// console.log('jewel', valueJewel);
let attr = (value1 + lv * valueup) * (HERO_CE_RATIO + valueRefine) + valueJewel * HERO_CE_RATIO;
// console.log('宝石', valueJewel);
let valueGrade = randMainMap.get(i)||0;
// console.log('品相', valueGrade)
let attr = (value1 + lv * valueup) * valueGrade * (HERO_CE_RATIO + valueRefine) + valueJewel * HERO_CE_RATIO * HERO_CE_RATIO;
if(attr >= 0) {
// console.log('装备战力:', i, attr);
if(setMap.has(i)) {
setMap.set(i, setMap.get(i) + attr);
setMap.set(i, setMap.get(i) + Math.floor(attr / HERO_CE_RATIO));
} else {
setMap.set(i, attr);
setMap.set(i, Math.floor(attr / HERO_CE_RATIO));
}
}
}
+98
View File
@@ -0,0 +1,98 @@
[
{
"id": 1,
"grade": 1,
"name": "残品",
"singleRatioMin": 30,
"singleRatioMax": 40,
"quality": "1&",
"unitConsume": 0,
"critEffect": 2,
"critProbability": 20,
"initialAvailable": 1
},
{
"id": 2,
"grade": 2,
"name": "次品",
"singleRatioMin": 40,
"singleRatioMax": 50,
"quality": "1&2",
"unitConsume": 0,
"critEffect": 2,
"critProbability": 20,
"initialAvailable": 1
},
{
"id": 3,
"grade": 3,
"name": "凡品",
"singleRatioMin": 50,
"singleRatioMax": 60,
"quality": "1&2&3",
"unitConsume": 0,
"critEffect": 2,
"critProbability": 20,
"initialAvailable": 1
},
{
"id": 4,
"grade": 4,
"name": "良品",
"singleRatioMin": 60,
"singleRatioMax": 70,
"quality": "2&3&4",
"unitConsume": 0,
"critEffect": 2,
"critProbability": 20,
"initialAvailable": 1
},
{
"id": 5,
"grade": 5,
"name": "精品",
"singleRatioMin": 70,
"singleRatioMax": 80,
"quality": "3&4&5",
"unitConsume": 0,
"critEffect": 2,
"critProbability": 20,
"initialAvailable": 1
},
{
"id": 6,
"grade": 6,
"name": "极品",
"singleRatioMin": 80,
"singleRatioMax": 90,
"quality": "4&5",
"unitConsume": 0,
"critEffect": 2,
"critProbability": 20,
"initialAvailable": 1
},
{
"id": 7,
"grade": 7,
"name": "圣品",
"singleRatioMin": 90,
"singleRatioMax": 100,
"quality": "5&",
"unitConsume": 0,
"critEffect": 2,
"critProbability": 20,
"initialAvailable": 0
},
{
"id": 8,
"grade": 8,
"name": "神品",
"singleRatioMin": 100,
"singleRatioMax": 0,
"quality": "5&",
"unitConsume": 0,
"critEffect": 2,
"critProbability": 20,
"initialAvailable": 0
}
]
@@ -0,0 +1,182 @@
[
{
"id": 1,
"equipLvl": 1,
"quality": 1,
"unitconsume": "17051&1"
},
{
"id": 2,
"equipLvl": 1,
"quality": 2,
"unitconsume": "17051&2"
},
{
"id": 3,
"equipLvl": 1,
"quality": 3,
"unitconsume": "17051&3"
},
{
"id": 4,
"equipLvl": 1,
"quality": 4,
"unitconsume": "17051&4"
},
{
"id": 5,
"equipLvl": 1,
"quality": 5,
"unitconsume": "17051&5"
},
{
"id": 6,
"equipLvl": 2,
"quality": 1,
"unitconsume": "17051&2"
},
{
"id": 7,
"equipLvl": 2,
"quality": 2,
"unitconsume": "17051&4"
},
{
"id": 8,
"equipLvl": 2,
"quality": 3,
"unitconsume": "17051&6"
},
{
"id": 9,
"equipLvl": 2,
"quality": 4,
"unitconsume": "17051&8"
},
{
"id": 10,
"equipLvl": 2,
"quality": 5,
"unitconsume": "17051&10"
},
{
"id": 11,
"equipLvl": 3,
"quality": 1,
"unitconsume": "17051&4"
},
{
"id": 12,
"equipLvl": 3,
"quality": 2,
"unitconsume": "17051&8"
},
{
"id": 13,
"equipLvl": 3,
"quality": 3,
"unitconsume": "17051&12"
},
{
"id": 14,
"equipLvl": 3,
"quality": 4,
"unitconsume": "17051&16"
},
{
"id": 15,
"equipLvl": 3,
"quality": 5,
"unitconsume": "17051&20"
},
{
"id": 16,
"equipLvl": 4,
"quality": 1,
"unitconsume": "17051&8"
},
{
"id": 17,
"equipLvl": 4,
"quality": 2,
"unitconsume": "17051&16"
},
{
"id": 18,
"equipLvl": 4,
"quality": 3,
"unitconsume": "17051&24"
},
{
"id": 19,
"equipLvl": 4,
"quality": 4,
"unitconsume": "17051&32"
},
{
"id": 20,
"equipLvl": 4,
"quality": 5,
"unitconsume": "17051&40"
},
{
"id": 21,
"equipLvl": 5,
"quality": 1,
"unitconsume": "17051&16"
},
{
"id": 22,
"equipLvl": 5,
"quality": 2,
"unitconsume": "17051&32"
},
{
"id": 23,
"equipLvl": 5,
"quality": 3,
"unitconsume": "17051&48"
},
{
"id": 24,
"equipLvl": 5,
"quality": 4,
"unitconsume": "17051&64"
},
{
"id": 25,
"equipLvl": 5,
"quality": 5,
"unitconsume": "17051&80"
},
{
"id": 26,
"equipLvl": 6,
"quality": 1,
"unitconsume": "17051&64"
},
{
"id": 27,
"equipLvl": 6,
"quality": 2,
"unitconsume": "17051&128"
},
{
"id": 28,
"equipLvl": 6,
"quality": 3,
"unitconsume": "17051&192"
},
{
"id": 29,
"equipLvl": 6,
"quality": 4,
"unitconsume": "17051&256"
},
{
"id": 30,
"equipLvl": 6,
"quality": 5,
"unitconsume": "17051&320"
}
]
@@ -0,0 +1,137 @@
[
{
"id": 1,
"quality": 1,
"grade": 1,
"name": "残品",
"singleRatioMin": 30,
"singleRatioMax": 40,
"initialAvailable": 1
},
{
"id": 2,
"quality": 1,
"grade": 2,
"name": "次品",
"singleRatioMin": 40,
"singleRatioMax": 50,
"initialAvailable": 1
},
{
"id": 3,
"quality": 1,
"grade": 3,
"name": "凡品",
"singleRatioMin": 50,
"singleRatioMax": 50,
"initialAvailable": 1
},
{
"id": 4,
"quality": 2,
"grade": 2,
"name": "次品",
"singleRatioMin": 40,
"singleRatioMax": 50,
"initialAvailable": 1
},
{
"id": 5,
"quality": 2,
"grade": 3,
"name": "凡品",
"singleRatioMin": 50,
"singleRatioMax": 60,
"initialAvailable": 1
},
{
"id": 6,
"quality": 2,
"grade": 4,
"name": "良品",
"singleRatioMin": 60,
"singleRatioMax": 60,
"initialAvailable": 1
},
{
"id": 7,
"quality": 3,
"grade": 3,
"name": "凡品",
"singleRatioMin": 50,
"singleRatioMax": 60,
"initialAvailable": 1
},
{
"id": 8,
"quality": 3,
"grade": 4,
"name": "良品",
"singleRatioMin": 60,
"singleRatioMax": 70,
"initialAvailable": 1
},
{
"id": 9,
"quality": 3,
"grade": 5,
"name": "精品",
"singleRatioMin": 70,
"singleRatioMax": 70,
"initialAvailable": 1
},
{
"id": 10,
"quality": 4,
"grade": 4,
"name": "良品",
"singleRatioMin": 60,
"singleRatioMax": 70,
"initialAvailable": 1
},
{
"id": 11,
"quality": 4,
"grade": 5,
"name": "精品",
"singleRatioMin": 70,
"singleRatioMax": 80,
"initialAvailable": 1
},
{
"id": 12,
"quality": 4,
"grade": 6,
"name": "极品",
"singleRatioMin": 80,
"singleRatioMax": 80,
"initialAvailable": 1
},
{
"id": 13,
"quality": 5,
"grade": 6,
"name": "极品",
"singleRatioMin": 80,
"singleRatioMax": 90,
"initialAvailable": 1
},
{
"id": 14,
"quality": 5,
"grade": 7,
"name": "圣品",
"singleRatioMin": 90,
"singleRatioMax": 100,
"initialAvailable": 0
},
{
"id": 15,
"quality": 5,
"grade": 8,
"name": "神品",
"singleRatioMin": 100,
"singleRatioMax": 100,
"initialAvailable": 0
}
]