Files
ZYZ/shared/pubUtils/util.ts
2022-07-26 20:47:01 +08:00

809 lines
26 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
import { STATUS } from './../consts/statusCode';
import { isNumber } from 'underscore';
const csprng = require('csprng');
const fs = require('fs');
const path = require('path');
import { ABI_STAGE, REFRESH_TIME, ROBOT_SYS_TYPE, ITEM_CHANGE_REASON, WAR_TYPE, SHOP_REFRESH_TYPE, GACHA_TYPE, GACHA_FLOOR_TYPE } from '../consts';
import { findIndex } from 'underscore';
import { getZeroPointD } from './timeUtil';
import { Floor } from '../domain/activityField/gachaField';
import { RewardInter } from './interface';
import { gameData } from './data';
const randomName = require("chinese-random-name");
const moment = require('moment');
const crypto = require('crypto');
export function aesEncrypt(data, key, iv) {
const cipher = crypto.createCipheriv('aes-192-cbc', key, iv);
let crypted = cipher.update(data, 'utf8', 'hex');
crypted += cipher.final('hex');
return crypted;
}
export function aesDecrypt(data, key, iv) {
const decipher = crypto.createDecipheriv('aes-192-cbc', key, iv);
let decrypted = decipher.update(data, 'hex', 'utf8');
decrypted += decipher.final('utf8');
return decrypted;
}
export function aesEncryptcfb(data, key, iv) {
const cipher = crypto.createCipheriv('aes-192-cfb', key, iv);
let crypted = cipher.update(data, 'utf8', 'hex');
crypted += cipher.final('hex');
// console.log('****aesEncryptcfb', data, crypted)
return crypted;
}
export function aesDecryptcfb(data, key, iv) {
if (data) {
const decipher = crypto.createDecipheriv('aes-192-cfb', key, iv);
let decrypted = decipher.update(data, 'hex', 'utf8');
decrypted += decipher.final('utf8');
return decrypted;
} else {
return ''
}
}
export function genCode(len) {
const chars = '123456789ABCDEFGHJKLMNPQRSTWXYZabcdefghijklmnopqrstuvwxyz';
const charArr = chars.split('');
let code = '';
for (let i = 0; i < len; i++) {
code += charArr[Math.floor(Math.random() * charArr.length)];
}
return code;
}
/**
* 生成 len 长度的随机字符串
* @param len 长度
* @param radix 基数
*/
export function generateStr(len: number, radix = 36) {
return `${csprng(len, radix)}`;
}
export function generateNum(len: number) {
let code = '';
for (let i = 0; i < len; i++) {
code += parseInt(`${Math.random() * 10}`);
}
return code;
}
/**
* 将 | 分隔的字符串解析为数组a|b|c 解析为[a, b, c]
* @param str 要解析的字符串
*/
export function decodeArrayStr(str: string, splitForm = '|') {
let last = str.substr(str.length - 1, 1);
if (last == '&') str = str.substr(0, str.length - 1);
if (str == '') {
return new Array<string>()
} else {
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}
* @param str 要解析的字符串
*/
export function decodeIdCntArrayStr(str: string, multi: number) {
const strArr = decodeArrayStr(str);
// console.log('decodeIdCntArrayStr: ', strArr);
const strMap = new Map<string, number>();
strArr.forEach(item => {
const kv = item.split('&');
strMap.set(kv[0], multi ? Math.ceil(parseInt(kv[1]) * multi) : parseInt(kv[1]));
});
return strMap;
}
/**
* 传入两个时间,返回按照时间差计算,第二个时间比第一个晚几天
* @param preTime 之前的时间
* @param proTime 之后的时间
*/
export function deltaDays(preTime: Date, proTime: Date): number {
return moment(proTime).diff(moment(preTime), "days");
}
/**
* 计算按照每 x 天 y 点刷新一次,是否应该刷新
* @param preTime 基准时间
* @param curTime 当前时间
* @param hour 几点刷新
* @param deltaDay 间隔几天刷新,默认每天刷新(deltaDay = 1)
*/
export function shouldRefresh(preTime: Date, now: Date, hour: number = REFRESH_TIME, deltaDay = 1): boolean {
if (!preTime) return true;
let curTime = new Date(now.getTime());
let refreshTime = getZeroPointD(SHOP_REFRESH_TYPE.DAILY, hour);
let refeshTime = refreshTime.getTime();
if (refeshTime - preTime.getTime() > (deltaDay >= 1 ? deltaDay - 1 : 0) * 24 * 60 * 60 * 1000 && curTime.getTime() >= refeshTime) {
return true;
}
return false;
}
/**
* 计算按照每 x 天 y 点刷新一次,是否应该刷新
* @param preTime 基准时间
* @param curTime 当前时间
* @param day 周几刷新
* @param hour 几点刷新
* @param deltaDay 间隔几天刷新,默认每天刷新(deltaDay = 1)
*/
export function shouldRefreshWeek(preTime: Date, now: Date, hour: number = REFRESH_TIME, deltaWeek = 1): boolean {
if (!preTime) return true;
let curTime = new Date(now.getTime());
let refreshTime = getZeroPointD(SHOP_REFRESH_TYPE.WEEKLY, hour);
let refeshTime = refreshTime.getTime();
if (refeshTime - preTime.getTime() > (deltaWeek >= 1 ? deltaWeek - 1 : 0) * 7 * 24 * 60 * 60 * 1000 && curTime.getTime() >= refeshTime) {
return true;
}
return false;
}
/**
* 从一个数组中随机返回不重复的 cnt 个元素数组
* @param source 原数组
* @param cnt 返回随机元素个数
*/
export function getRandEelm<T>(source: Array<T> = [], cnt = 1): Array<T> {
if (cnt == 0) return [];
if (cnt >= source.length) return sortArrRandom(source);
let idxs = new Set();
while (1) {
let rand = Math.floor(Math.random() * source.length);
idxs.add(rand);
if (idxs.size >= cnt) {
break;
}
}
return source.filter((_item, idx) => idxs.has(idx));
}
/**
* 从一个数组中随机返回1元素
* @param source
*/
export function getRandSingleEelm<T>(source: Array<T>): T {
let len = source.length;
return source[Math.floor(Math.random() * len)]
}
/**
* 随机数组中一个index
* @param len
*/
export function getRandSingleIndex(len: number) {
return Math.floor(Math.random() * len);
}
/**
* 从一个数组根据权重随机一个元素
* @param randomList
*/
export function getRandEelmWithWeight<T extends { weight: number }>(randomList: T[]): { dic: T, index: number } {
let len = randomList.reduce((pre, cur) => {
return pre + cur.weight || 1;
}, 0);
let index = Math.floor(Math.random() * len);
let result = { dic: null, index: -1 };
for (let i = 0; i < randomList.length; i++) {
let { weight = 0 } = randomList[i];
if (index < weight) {
result.dic = randomList[i];
result.index = i;
break;
}
index -= weight;
}
return result
}
/**
* 不改变原数组长度,将内部元素打乱
* @param source
*/
export function sortArrRandom<T>(source: T[] = []): T[] {
let newArr: T[] = [...source];
return newArr.sort(() => { return Math.random() - 0.5; });
}
/**
* 在给定数值的浮动范围中随机一个值
* @param base 基础数值
* @param ratio 随机范围base 值上下浮动 ratio(小于 1 的整数)
* @param decimal 返回值保留的小数位数
*/
export function getRandValue(base: number, ratio: number, decimal = 2): number {
return parseFloat((base * (1 - ratio + Math.random() * ratio * 2)).toFixed(decimal));
}
/**
* 在给定最大最小值中随机一个值
* @param min 最小
* @param max 最大
* @param decimal 返回值保留的小数位数
*/
export function getRandValueByMinMax(min: number, max: number, decimal = 2): number {
let pow = Math.pow(10, decimal);
return Math.floor((min + (max - min) * Math.random()) * pow)/pow;
}
export function resResult<T>(status: { code: number, simStr: string }, data: T = <T>{}, customMsg = ''): { code: number, msg: string, data: T } {
const { code, simStr } = status;
if (code !== STATUS.SUCCESS.code) {
console.log(`normal err, code: ${code}, des: ${customMsg || simStr}`);
}
return { code, msg: customMsg || simStr, data };
}
export function getResStr(status: { code: number, simStr: string }) {
return status.simStr;
}
// 消除 js 浮点计算bug
export const cal = {
add: function (a: number, b: number) {
var c: number, d: number, e: number;
try {
c = a.toString().split(".")[1].length;
} catch (f) {
c = 0;
}
try {
d = b.toString().split(".")[1].length;
} catch (f) {
d = 0;
}
e = Math.pow(10, Math.max(c, d));
return (this.mul(a, e) + this.mul(b, e)) / e;
},
sub: function sub(a: number, b: number) {
var c: number, d: number, e: number;
try {
c = a.toString().split(".")[1].length;
} catch (f) {
c = 0;
}
try {
d = b.toString().split(".")[1].length;
} catch (f) {
d = 0;
}
e = Math.pow(10, Math.max(c, d));
return (this.mul(a, e) - this.mul(b, e)) / e;
},
mul: function mul(a: number, b: number) {
var c = 0,
d = a.toString(),
e = b.toString();
try {
c += d.split(".")[1].length;
} catch (f) { }
try {
c += e.split(".")[1].length;
} catch (f) { }
return Number(d.replace(".", "")) * Number(e.replace(".", "")) / Math.pow(10, c);
},
div: function div(a: number, b: number) {
var c: number, d: number, e = 0,
f = 0;
try {
e = a.toString().split(".")[1].length;
} catch (g) { }
try {
f = b.toString().split(".")[1].length;
} catch (g) { }
c = Number(a.toString().replace(".", ""));
d = Number(b.toString().replace(".", ""));
return this.mul(c / d, Math.pow(10, f - e));
}
};
export function getDecimalCnt(num: number) {
let str = num.toString();
return str.split('.')[1]? str.split('.')[1].length: 0;
}
//计算公式
// export function calculateNum(ratio: { A: number, B: number }, params: { num: number }, defaultVal = 0) {
// // result = a * num + b
// try {
// let { A, B } = ratio;
// let { num } = params;
// let result = A * num + B;
// if (isNaN(result)) {
// console.error('calculate wrong: ', A, B, num)
// return defaultVal;
// } else {
// return result;
// }
// } catch (e) {
// console.error(e);
// return defaultVal;
// }
// }
export function ratioReward(reward: {id: number, count: number}[], ratio: number): {id: number, count: number}[] {
return reward.map(cur => {
return {id: cur.id, count: cur.count * ratio}
});
}
export function getItems(str: string) {
let arr = new Array<{ id: number, count: number }>();
let strArr = str.split('|');
for (let item of strArr) {
var itemArr = item.split('&');
arr.push({
id: parseInt(itemArr[0]),
count: parseInt(itemArr[1])
});
}
return arr;
}
export function deepCopy(obj) {
if (typeof obj !== 'object' || obj === null) {
return obj;
}
var target;
if (obj instanceof Array) {
target = [];
obj.forEach(element => {
target.push(deepCopy(element));
});
} else {
target = {};
for (const key in obj) {
if (obj.hasOwnProperty(key)) {
const element = obj[key];
if (!!element || element == 0) {
target[key] = deepCopy(element);
}
}
}
}
return target;
};
export function readFile(addr: string) {
return fs.readFileSync(path.resolve(__dirname, `${addr}`)).toString('utf8').replace(/^\uFEFF/, '');
}
export function writeFile(addr: string, data: string) {
return fs.writeFileSync(addr, data);
}
export function readFileAndParseJson(path: string) {
try {
let readResult = readFile(path);
return JSON.parse(readResult);
} catch(e) {
throw new Error(`connectors.json 格式错误:${(<Error>e).message}`);
}
}
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}`)
.filter(cur => { return cur.indexOf('.') != 0 })
.map(file => {
return {
name: file,
str: fs.readFileSync(path.resolve(__dirname, `../resource/${folder}/${file}`)).toString('utf8')
}
});
}
export function readWordTxt(fileName: string) {
try {
let file = fs.readFileSync(path.resolve(__dirname, `../resource/${fileName}.txt`)).toString('utf8').replace(/^\uFEFF/, '');
return file;
} catch(e) {
console.log(e)
return null
}
}
export function writeWordTxt(fileName: string, words: string) {
try {
let file = fs.writeFileSync(path.resolve(__dirname, `../resource/${fileName}.txt`), words);
return file;
} catch(e) {
return null
}
}
export function readTsFile(fileName: string) {
try {
let file = fs.readFileSync(path.resolve(__dirname, `../pubUtils/${fileName}.js`)).toString('utf8').replace(/^\uFEFF/, '');
return file;
} catch(e) {
return null
}
}
export function readFileAndParse(fileName: string) {
try {
let readResult = readJsonFile(fileName);
return JSON.parse(readResult);
} catch(e) {
throw new Error(`${fileName}格式错误:${(<Error>e).message}`);
}
}
export function readWarJsonFileAndParse() {
let warJsons = readWarJsonFileList();
let result = [];
for(let { name, str } of warJsons) {
try {
let json = JSON.parse(str);
result.push(json);
} catch(e) {
throw new Error(`${name}格式错误:${(<Error>e).message}`);
}
}
return result;
}
// 字典表常用解析方法
// 解析物品 {"id": number, "count": number} 格式
export function parseGoodStr(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
}
// 根据类型解析物品 {"type":number, "id": number, "count": number} 格式
//type 1.英雄2.物品
export function parseGoodStrWithType(str: string) {
let result = new Array<{ type: number, id: number, count: number }>();
if (!str) return result;
let decodeArr = decodeArrayListStr(str);
for (let [type, id, count] of decodeArr) {
if (isNaN(parseInt(type)) || isNaN(parseInt(id)) || isNaN(parseInt(count))) {
throw new Error('data table format wrong');
}
result.push({ type: parseInt(type), id: parseInt(id), count: parseInt(count) });
}
return result
}
// 根据类型解析物品 {"type":number, "hid": number, "count": number} 格式
//type 1.英雄2.物品
export function parseHeroStrWithType(str: string) {
let result = new Array<{ type: number, hid: number, count: number }>();
if (!str) return result;
let decodeArr = decodeArrayListStr(str);
for (let [type, hid, count] of decodeArr) {
if (isNaN(parseInt(type)) || isNaN(parseInt(hid)) || isNaN(parseInt(count))) {
throw new Error('data table format wrong');
}
result.push({ type: parseInt(type), hid: parseInt(hid), count: parseInt(count) });
}
return result
}
// 根据类型解析物品 {"type":number, "id": number, "count": number} 格式
//type 1.英雄2.物品, 3.RMB
export function parseResStr(str: string) {
let result = new Array<{ type: number, id: number, count: number }>();
if (!str) return result;
let decodeArr = decodeArrayListStr(str);
for (let [type, id, count] of decodeArr) {
if (isNaN(parseInt(type)) || isNaN(parseInt(id)) || isNaN(parseInt(count))) {
throw new Error('data table format wrong');
}
result.push({ type: parseInt(type), 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(parseFloat(g));
}
return res;
}
export function mergeSameGoods(goods: Array<{ id: number, count: number }>) {
let resGoods = [];
for (let { id, count } of goods) {
let index = findIndex(resGoods, { id });
if (index > -1) {
resGoods[index].count += count;
} else {
resGoods.push({ id, count });
}
}
return resGoods;
}
// 获取全部属性
export function getAllAttrStage() {
let attrs = new Array<number>(); // 有升级的属性 1-hp 2-atk 3-def 4-mdef 5-agi 6-luk
for (let stage = ABI_STAGE.START + 1; stage <= ABI_STAGE.END; stage++) {
attrs.push(stage)
};
return attrs;
}
export function getChineseName() {
return randomName.generate()
}
export function getRobotInfo(sysType?: ROBOT_SYS_TYPE) {
return {
robotRoleName: getChineseName(),
robotRoleId: makeRobotId(genCode(8), sysType),
}
}
// 根据roleId判断是不是机器人
export function checkRoleIsRobot(roleId: string) {
return !!roleId.match(/_r/);
}
// 将一般的roleId转为带_r的
export function makeRobotId(roleId: string, sysType?: ROBOT_SYS_TYPE) {
if(sysType) {
return `${sysType}|${roleId}_r`;
} else {
return `${roleId}_r`;
}
}
// 获取来源系统
export function getRobotSysType(roleId: string) {
let type = roleId.split('|')[0];
if(isNaN(parseInt(type))) {
return 0
} else {
return parseInt(type);
}
}
// 将一般的roleId去掉_r
export function robotIdComBack(robotRoleId: string) {
return robotRoleId.replace(/_r/, '')
}
export function splitString(dataString: string, key: string) {
if (!dataString) {
return [];
}
let array = dataString.split(key).filter(obj => { return obj && obj != '' });
let numberArray = [];
for (let num of array) {
numberArray.push(Number(num));
}
return numberArray;
}
export function isTimestamp(time: number, len = 10) {
if(!isNumber(time)) return false;
if(time.toString().length != len) return false;
return true;
}
export function getReasonByWarType(warType: number) {
switch(warType) {
case WAR_TYPE.NORMAL:
return ITEM_CHANGE_REASON.NORMAL_BATTLE_END;
case WAR_TYPE.VESTIGE:
return ITEM_CHANGE_REASON.VESTIGE_BATTLE_END;
case WAR_TYPE.EVENT:
return ITEM_CHANGE_REASON.EVENT_BATTLE_END;
case WAR_TYPE.DAILY:
return ITEM_CHANGE_REASON.DAILY_BATTLE_END;
case WAR_TYPE.EXPEDITION:
return ITEM_CHANGE_REASON.EXPEDITION_BATTLE_END;
case WAR_TYPE.MYSTERY:
return ITEM_CHANGE_REASON.MYSTERY_BATTLE_END;
case WAR_TYPE.WARLOARDS:
return ITEM_CHANGE_REASON.WARLOARDS_BATTLE_END;
case WAR_TYPE.TOWER:
return ITEM_CHANGE_REASON.TOWER_BATTLE_END;
case WAR_TYPE.PVP:
return ITEM_CHANGE_REASON.PVP_BATTLE_END;
// case WAR_TYPE.GUILD_ACTIVITY:
// return ITEM_CHANGE_REASON.GUILD_ACTIVITY_BATTLE_END;
case WAR_TYPE.GUILD_TRAIN:
return ITEM_CHANGE_REASON.TRAIN_BATTLE_END;
case WAR_TYPE.MAIN_ELITE:
return ITEM_CHANGE_REASON.MAIN_ELITE_BATTLE_END;
// case WAR_TYPE.MYSTERY_ELITE:
// return ITEM_CHANGE_REASON.MYSTERY_ELITE_BATTLE_END;
case WAR_TYPE.BRANCH:
return ITEM_CHANGE_REASON.BRANCH_BATTLE_END;
case WAR_TYPE.ACT_TREASURE_HUNT:
return ITEM_CHANGE_REASON.ACT_TREASURE_HUNT_BATTLE_END;
case WAR_TYPE.ACT_SELF_SHOP:
return ITEM_CHANGE_REASON.ACT_SELF_SHOP_BATTLE_END;
case WAR_TYPE.ACT_DAILY_GK:
return ITEM_CHANGE_REASON.ACT_DAILY_GK_BATTLE_END;
case WAR_TYPE.ACT_NEW_HERO_GK:
return ITEM_CHANGE_REASON.ACT_NEW_HERO_GK_BATTLE_END;
case WAR_TYPE.TRY:
return ITEM_CHANGE_REASON.TRY_BATTLE_END;
case WAR_TYPE.BOSS:
return ITEM_CHANGE_REASON.BOSS_BATTLE_END;
case WAR_TYPE.LADDER:
return ITEM_CHANGE_REASON.LADDER_BATTLE_REWARD;
default:
return ITEM_CHANGE_REASON.NORMAL_BATTLE_END;
}
}
export function getWarTypeName(warType: number) {
switch(warType) {
case WAR_TYPE.NORMAL: return '主线';
case WAR_TYPE.VESTIGE: return '支线';
case WAR_TYPE.EVENT: return '事件';
case WAR_TYPE.DAILY: return '每日';
case WAR_TYPE.EXPEDITION: return '远征';
case WAR_TYPE.MYSTERY: return '秘境';
case WAR_TYPE.WARLOARDS: return '群雄';
case WAR_TYPE.TOWER: return '镇念塔';
case WAR_TYPE.PVP: return '竞技';
case WAR_TYPE.GUILD_ACTIVITY: return '军团活动';
case WAR_TYPE.GUILD_TRAIN: return '训练场';
case WAR_TYPE.MAIN_ELITE: return '主线精英';
case WAR_TYPE.MYSTERY_ELITE: return '秘境精英';
case WAR_TYPE.BRANCH: return '支线';
case WAR_TYPE.ACT_TREASURE_HUNT: return '运营活动-神州探秘';
case WAR_TYPE.ACT_SELF_SHOP: return '运营活动-糜家商队';
case WAR_TYPE.ACT_DAILY_GK: return '运营活动-节日活动';
case WAR_TYPE.ACT_NEW_HERO_GK: return '新武将活动关卡';
case WAR_TYPE.TRY: return '试用关卡';
case WAR_TYPE.BOSS: return '演武台';
}
}
/**
* 一群人分总数固定的东西
* @param total 总数
* @param max 每个人能拿到的最大数量
* @param memberCnt 人数
*/
export function getRandResultByMember(total: number, max: number, memberCnt: number) {
let arr: number[] = [];
for(let i = 1; i <= memberCnt; i++) {
let randMax = total > max? max: total;
let randMin = total - (memberCnt - i) * max;
if(randMin < 0) randMin = 0;
if(randMin > max) randMin = max;
let rand = getRandValueByMinMax(randMin, randMax + 1, 0);
arr.push(rand);
total -= rand;
}
return { arr, remain: total }
}
//数据格式转换'id&数量|id&数量|' ->> Array<RewardInter> 老资源格式
export function stringToRewardInter(rewardStr: string): Array<RewardInter> {
let result = new Array<{ id: number, count: number }>();
if (!rewardStr) return result;
let decodeArr = decodeArrayListStr(rewardStr);
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 addToMap<T>(map: Map<T, number>, id: T, value: number) {
if(!map.has(id)) {
map.set(id, value);
} else {
map.set(id, map.get(id) + value);
}
}
// /**
// * 计算最强阵容战力
// * @param role
// * @param hid
// * @param ce
// * @param heroId
// */
// export async function calculatetopLineup(role: RoleType, hid?: number, ce?: number, heroId?: string) {
// let topLineup = role?.topLineup || new Array();
// if(!hid) { // 直接重新排
// let heroes = await HeroModel.getTopHero(role.roleId, LINEUP_NUM);
// topLineup = heroes.map(cur => { return { hid: cur.hid, ce: cur.ce, hero: cur._id } });
// } else {
// topLineup.sort((a, b) => { return b.ce - a.ce }); // 0-6最大-最小
// let index = topLineup.findIndex(cur => cur.hid == hid);
// if(index != -1 && !heroId) {
// let heroes = await HeroModel.getTopHero(role.roleId, LINEUP_NUM);
// topLineup = heroes.map(cur => { return { hid: cur.hid, ce: cur.ce, hero: cur._id } });
// } else {
// if (index == -1) { // 不在最强列表
// if (topLineup.length < LINEUP_NUM) { // 不满6人
// topLineup.push({ hid, ce, hero: heroId });
// } else if (topLineup.length == LINEUP_NUM) {
// if (ce > topLineup[topLineup.length - 1].ce) { // 跻身最强6人
// topLineup.pop();
// topLineup.push({ hid, ce, hero: heroId });
// }
// } else {
// topLineup.splice(LINEUP_NUM, topLineup.length - LINEUP_NUM);
// }
// } else { // 原来就是最强6人
// if (ce < topLineup[topLineup.length - 1].ce) { // 滑出最强
// let heroes = await HeroModel.getTopHero(role.roleId, LINEUP_NUM);
// topLineup = heroes.map(cur => { return { hid: cur.hid, ce: cur.ce, hero: cur._id } });
// } else {
// topLineup[index].ce = ce;
// }
// }
// }
// }
// let topLineupCe = topLineup.reduce((pre, cur) => {
// return pre + cur.ce
// }, 0);
// return { topLineup, topLineupCe };
// }
export function getGachaRemainFloor(gachaId: number, userFloor: Floor[]) {
let dicGacha = gameData.gacha.get(gachaId);
if(dicGacha.gachaType != GACHA_TYPE.NORMAL) return 0;
for(let floorId of dicGacha.floor) {
let dicGachaFloor = gameData.gachaFloor.get(floorId);
console.log('##### floorId', floorId, dicGachaFloor)
if(dicGachaFloor && dicGachaFloor.floorType == GACHA_FLOOR_TYPE.MAIN_FLOOR) {
let myFloor = userFloor.find(cur => cur.id == floorId);
console.log('#### dicGacha#', gachaId, dicGachaFloor.param, (myFloor?.count||0))
return dicGachaFloor.param - (myFloor?.count||0);
}
}
return 0
}