|
|
|
@@ -14,126 +14,126 @@ const _ = require('underscore');
|
|
|
|
|
|
|
|
|
|
const moment = require('moment');
|
|
|
|
|
|
|
|
|
|
export function genCode(len) {
|
|
|
|
|
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)];
|
|
|
|
|
code += charArr[Math.floor(Math.random() * charArr.length)];
|
|
|
|
|
}
|
|
|
|
|
return code;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export function decodeStr(type, str, splitForm='|') {
|
|
|
|
|
if(str == '&'|| !str) {
|
|
|
|
|
return []
|
|
|
|
|
export function decodeStr(type, str, splitForm = '|') {
|
|
|
|
|
if (str == '&' || !str) {
|
|
|
|
|
return []
|
|
|
|
|
} else {
|
|
|
|
|
return str.split(splitForm).map(cur => {
|
|
|
|
|
return decodeStrSingle(type,cur);
|
|
|
|
|
});
|
|
|
|
|
return str.split(splitForm).map(cur => {
|
|
|
|
|
return decodeStrSingle(type, cur);
|
|
|
|
|
});
|
|
|
|
|
};
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export function decodeStrSingle(type, str) { //单层,返回对象而不是数组
|
|
|
|
|
let last = str.substr(str.length-1, 1);
|
|
|
|
|
if(last == '&') str = str.substr(0, str.length - 1);
|
|
|
|
|
if(str == '&'|| !str) {
|
|
|
|
|
return {}
|
|
|
|
|
export function decodeStrSingle(type, str) { //单层,返回对象而不是数组
|
|
|
|
|
let last = str.substr(str.length - 1, 1);
|
|
|
|
|
if (last == '&') str = str.substr(0, str.length - 1);
|
|
|
|
|
if (str == '&' || !str) {
|
|
|
|
|
return {}
|
|
|
|
|
} else {
|
|
|
|
|
let arr = str.split('&');
|
|
|
|
|
let result: any;
|
|
|
|
|
switch (type) {
|
|
|
|
|
case 'fixReward': {
|
|
|
|
|
let [id, count] = arr;
|
|
|
|
|
if(isNaN(id) || isNaN(count)) throw new Error('data table format wrong');
|
|
|
|
|
result = { id: parseInt(id), count: parseInt(count)};
|
|
|
|
|
break;
|
|
|
|
|
let arr = str.split('&');
|
|
|
|
|
let result: any;
|
|
|
|
|
switch (type) {
|
|
|
|
|
case 'fixReward': {
|
|
|
|
|
let [id, count] = arr;
|
|
|
|
|
if (isNaN(id) || isNaN(count)) throw new Error('data table format wrong');
|
|
|
|
|
result = { id: parseInt(id), count: parseInt(count) };
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
case 'conditionReward': {
|
|
|
|
|
let [id, count, condition] = arr;
|
|
|
|
|
if (isNaN(id) || isNaN(count)) throw new Error('data table format wrong');
|
|
|
|
|
result = { id: parseInt(id), count: parseInt(count), condition: parseInt(condition) };
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
case 'randomReward': {
|
|
|
|
|
let [id, count, frequency] = arr;
|
|
|
|
|
if (isNaN(id) || isNaN(count)) throw new Error('data table format wrong');
|
|
|
|
|
result = { id: parseInt(id), count: parseInt(count), frequency: parseInt(frequency) };
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
case 'suitLevel': {
|
|
|
|
|
let [min, max] = arr;
|
|
|
|
|
if (isNaN(min) || isNaN(max)) throw new Error('data table format wrong');
|
|
|
|
|
result = { min: parseInt(min), max: parseInt(max) };
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
case 'suitLevelSingle': {
|
|
|
|
|
let [min, max] = arr;
|
|
|
|
|
console.log(min, max)
|
|
|
|
|
if (max) {
|
|
|
|
|
if (isNaN(min) || isNaN(max)) throw new Error('data table format wrong');
|
|
|
|
|
result = { min: parseInt(min), max: parseInt(max) };
|
|
|
|
|
break;
|
|
|
|
|
} else {
|
|
|
|
|
if (isNaN(min)) throw new Error('data table format wrong');
|
|
|
|
|
result = { min: parseInt(min) };
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
case 'attribute': {
|
|
|
|
|
let [id, value] = arr;
|
|
|
|
|
if (isNaN(id) || isNaN(value)) throw new Error('data table format wrong');
|
|
|
|
|
result = { id: parseInt(id), value: parseInt(value) };
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
case 'point': {
|
|
|
|
|
let [x] = arr;
|
|
|
|
|
if (isNaN(x)) throw new Error('data table format wrong');
|
|
|
|
|
result = x;
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
case 'decimalReward': {
|
|
|
|
|
let [id, count] = arr;
|
|
|
|
|
if (isNaN(id) || isNaN(count)) throw new Error('data table format wrong');
|
|
|
|
|
result = { id: parseInt(id), count: parseFloat(count) };
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
case 'towerTaskCondition': {
|
|
|
|
|
let [type, param, cnt] = arr;
|
|
|
|
|
if (isNaN(type) || isNaN(param) || isNaN(cnt)) throw new Error('data table format wrong');
|
|
|
|
|
result = { type: parseInt(type), param: parseInt(param), cnt: parseInt(cnt) };
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
case 'possibility': {
|
|
|
|
|
let [id, weight] = arr;
|
|
|
|
|
if (isNaN(id) || isNaN(weight)) throw new Error('data table format wrong');
|
|
|
|
|
result = { id: parseInt(id), weight: parseInt(weight) };
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
case 'cost': {
|
|
|
|
|
let [id, count] = arr;
|
|
|
|
|
if (isNaN(id) || isNaN(count)) throw new Error('data table format wrong');
|
|
|
|
|
result = { id: parseInt(id), count: parseInt(count) };
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
case 'conditionReward': {
|
|
|
|
|
let [id, count, condition] = arr;
|
|
|
|
|
if(isNaN(id) || isNaN(count)) throw new Error('data table format wrong');
|
|
|
|
|
result = { id: parseInt(id), count: parseInt(count), condition: parseInt(condition) };
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
case 'randomReward': {
|
|
|
|
|
let [id, count, frequency] = arr;
|
|
|
|
|
if(isNaN(id) || isNaN(count)) throw new Error('data table format wrong');
|
|
|
|
|
result = { id: parseInt(id), count: parseInt(count), frequency: parseInt(frequency) };
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
case 'suitLevel': {
|
|
|
|
|
let [min, max] = arr;
|
|
|
|
|
if(isNaN(min) || isNaN(max)) throw new Error('data table format wrong');
|
|
|
|
|
result = { min: parseInt(min), max: parseInt(max) };
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
case 'suitLevelSingle': {
|
|
|
|
|
let [min, max] = arr;
|
|
|
|
|
console.log(min, max)
|
|
|
|
|
if(max) {
|
|
|
|
|
if(isNaN(min) || isNaN(max)) throw new Error('data table format wrong');
|
|
|
|
|
result = { min: parseInt(min), max: parseInt(max) };
|
|
|
|
|
break;
|
|
|
|
|
} else {
|
|
|
|
|
if(isNaN(min)) throw new Error('data table format wrong');
|
|
|
|
|
result = { min: parseInt(min) };
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
case 'attribute': {
|
|
|
|
|
let [id, value] = arr;
|
|
|
|
|
if(isNaN(id) || isNaN(value)) throw new Error('data table format wrong');
|
|
|
|
|
result = { id: parseInt(id), value: parseInt(value) };
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
case 'point': {
|
|
|
|
|
let [x] = arr;
|
|
|
|
|
if(isNaN(x)) throw new Error('data table format wrong');
|
|
|
|
|
result = x;
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
case 'decimalReward': {
|
|
|
|
|
let [id, count] = arr;
|
|
|
|
|
if(isNaN(id) || isNaN(count)) throw new Error('data table format wrong');
|
|
|
|
|
result = { id: parseInt(id), count: parseFloat(count) };
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
case 'towerTaskCondition': {
|
|
|
|
|
let [type, param, cnt] = arr;
|
|
|
|
|
if(isNaN(type) || isNaN(param)|| isNaN(cnt)) throw new Error('data table format wrong');
|
|
|
|
|
result = { type: parseInt(type), param: parseInt(param), cnt: parseInt(cnt) };
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
case 'possibility': {
|
|
|
|
|
let [id, weight] = arr;
|
|
|
|
|
if(isNaN(id) || isNaN(weight)) throw new Error('data table format wrong');
|
|
|
|
|
result = { id: parseInt(id), weight: parseInt(weight) };
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
case 'cost': {
|
|
|
|
|
let [id, count] = arr;
|
|
|
|
|
if(isNaN(id) || isNaN(count)) throw new Error('data table format wrong');
|
|
|
|
|
result = { id: parseInt(id), count: parseInt(count)};
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
return result;
|
|
|
|
|
return result;
|
|
|
|
|
};
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* 将 | 分隔的字符串解析为数组,如: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);
|
|
|
|
|
}
|
|
|
|
|
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);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
@@ -141,7 +141,7 @@ export function decodeArrayStr(str: string, splitForm='|') {
|
|
|
|
|
* @param str 要解析的字符串
|
|
|
|
|
*/
|
|
|
|
|
export function decodeArrayListStr(str: string) {
|
|
|
|
|
return decodeArrayStr(str).map(cur => decodeArrayStr(cur, '&'));
|
|
|
|
|
return decodeArrayStr(str).map(cur => decodeArrayStr(cur, '&'));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
@@ -149,28 +149,28 @@ export function decodeArrayListStr(str: string) {
|
|
|
|
|
* @param str 要解析的字符串
|
|
|
|
|
*/
|
|
|
|
|
export function decodeIdCntArrayStr(str: string, multi: number) {
|
|
|
|
|
const strArr = decodeArrayStr(str);
|
|
|
|
|
console.log('decodeIdCntArrayStr: ', strArr);
|
|
|
|
|
const strMap = new Map();
|
|
|
|
|
strArr.forEach(item => {
|
|
|
|
|
const kv = item.split('&');
|
|
|
|
|
strMap.set(kv[0], multi? Math.ceil(parseInt(kv[1]) * multi): kv[1]);
|
|
|
|
|
});
|
|
|
|
|
return strMap;
|
|
|
|
|
const strArr = decodeArrayStr(str);
|
|
|
|
|
console.log('decodeIdCntArrayStr: ', strArr);
|
|
|
|
|
const strMap = new Map();
|
|
|
|
|
strArr.forEach(item => {
|
|
|
|
|
const kv = item.split('&');
|
|
|
|
|
strMap.set(kv[0], multi ? Math.ceil(parseInt(kv[1]) * multi) : kv[1]);
|
|
|
|
|
});
|
|
|
|
|
return strMap;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 计算当前武将战力
|
|
|
|
|
export async function calculateSumCE(roleId: string, type: number, param: { num?: number, heroes?: Array<number> }) {
|
|
|
|
|
// 计算当前武将战力
|
|
|
|
|
export async function calculateSumCE(roleId: string, type: number, param: { num?: number, heroes?: Array<number> }) {
|
|
|
|
|
let sum;
|
|
|
|
|
if(type == 1) { // 最高num人历史最高战力和
|
|
|
|
|
sum = await HeroModel.sumTopHeroCe(roleId, param.num||0);
|
|
|
|
|
} else if(type == 2) { // 所有人战力和
|
|
|
|
|
sum = await HeroModel.sumHeroCe(roleId);
|
|
|
|
|
if (type == 1) { // 最高num人历史最高战力和
|
|
|
|
|
sum = await HeroModel.sumTopHeroCe(roleId, param.num || 0);
|
|
|
|
|
} else if (type == 2) { // 所有人战力和
|
|
|
|
|
sum = await HeroModel.sumHeroCe(roleId);
|
|
|
|
|
}
|
|
|
|
|
return sum;
|
|
|
|
|
}
|
|
|
|
|
// 计算当前武将战力
|
|
|
|
|
export function calculateCE(heroInfo: {hid: number, lv: number }) {
|
|
|
|
|
}
|
|
|
|
|
// 计算当前武将战力
|
|
|
|
|
export function calculateCE(heroInfo: { hid: number, lv: number }) {
|
|
|
|
|
let { hid, lv } = heroInfo;
|
|
|
|
|
// 假设所有属性和等级的关系是简单的线性关系
|
|
|
|
|
let dicHero = getGamedata('dic_zyz_hero');
|
|
|
|
@@ -188,39 +188,39 @@ export function decodeIdCntArrayStr(str: string, multi: number) {
|
|
|
|
|
|
|
|
|
|
let ce = atk + matk + def + mdef + agi + luk;
|
|
|
|
|
return ce;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export function getRandomByLen(arr: Array<number>):number
|
|
|
|
|
export function getRandomByLen(arr: Array<DicRandomEffectPool>):DicRandomEffectPool
|
|
|
|
|
export function getRandomByLen(arr: Array<any>): any {
|
|
|
|
|
export function getRandomByLen(arr: Array<number>): number
|
|
|
|
|
export function getRandomByLen(arr: Array<DicRandomEffectPool>): DicRandomEffectPool
|
|
|
|
|
export function getRandomByLen(arr: Array<any>): any {
|
|
|
|
|
let len = arr.length;
|
|
|
|
|
return arr[Math.floor(Math.random() * len)]
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export function getRandomWithWeight(randomList: any) {
|
|
|
|
|
export function getRandomWithWeight(randomList: any) {
|
|
|
|
|
let len = randomList.reduce((pre, cur) => {
|
|
|
|
|
return pre + cur.weight||1;
|
|
|
|
|
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;
|
|
|
|
|
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 preTime 之前的时间
|
|
|
|
|
* @param proTime 之后的时间
|
|
|
|
|
*/
|
|
|
|
|
export function deltaDays(preTime: Date, proTime: Date): number {
|
|
|
|
|
return moment(proTime).diff(moment(preTime), "days");
|
|
|
|
|
return moment(proTime).diff(moment(preTime), "days");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
@@ -231,14 +231,14 @@ export function deltaDays(preTime: Date, proTime: Date): number {
|
|
|
|
|
* @param deltaDay 间隔几天刷新,默认每天刷新(deltaDay = 1)
|
|
|
|
|
*/
|
|
|
|
|
export function shouldRefresh(preTime: Date, now: Date, hour: number, deltaDay = 1): boolean {
|
|
|
|
|
if(!preTime) return true;
|
|
|
|
|
let curTime = new Date(now.getTime());
|
|
|
|
|
let refeshTime = setLocalHours(hour, curTime);
|
|
|
|
|
console.log(refeshTime - preTime.getTime(), (deltaDay>=1?deltaDay-1:0) * 24 * 60 * 60 * 1000, curTime.getTime(), refeshTime)
|
|
|
|
|
if (refeshTime - preTime.getTime() > (deltaDay>=1?deltaDay-1:0) * 24 * 60 * 60 * 1000 && curTime.getTime() >= refeshTime) {
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
return false;
|
|
|
|
|
if (!preTime) return true;
|
|
|
|
|
let curTime = new Date(now.getTime());
|
|
|
|
|
let refeshTime = setLocalHours(hour, curTime);
|
|
|
|
|
console.log(refeshTime - preTime.getTime(), (deltaDay >= 1 ? deltaDay - 1 : 0) * 24 * 60 * 60 * 1000, curTime.getTime(), refeshTime)
|
|
|
|
|
if (refeshTime - preTime.getTime() > (deltaDay >= 1 ? deltaDay - 1 : 0) * 24 * 60 * 60 * 1000 && curTime.getTime() >= refeshTime) {
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
@@ -247,21 +247,21 @@ export function shouldRefresh(preTime: Date, now: Date, hour: number, deltaDay =
|
|
|
|
|
* @param hour 几点刷新
|
|
|
|
|
*/
|
|
|
|
|
export function getRefTime(now = new Date(), hour: number, day = 0) {
|
|
|
|
|
let curTime = new Date(now.getTime());
|
|
|
|
|
let offset = curTime.getTimezoneOffset(); // 时差,单位分
|
|
|
|
|
let checkHour = hour - 8 + offset/60;
|
|
|
|
|
if(checkHour < 0) {
|
|
|
|
|
checkHour = 24 + checkHour;
|
|
|
|
|
if (curTime.getHours() >= checkHour) {
|
|
|
|
|
curTime.setDate(curTime.getDate() + 1);
|
|
|
|
|
let curTime = new Date(now.getTime());
|
|
|
|
|
let offset = curTime.getTimezoneOffset(); // 时差,单位分
|
|
|
|
|
let checkHour = hour - 8 + offset / 60;
|
|
|
|
|
if (checkHour < 0) {
|
|
|
|
|
checkHour = 24 + checkHour;
|
|
|
|
|
if (curTime.getHours() >= checkHour) {
|
|
|
|
|
curTime.setDate(curTime.getDate() + 1);
|
|
|
|
|
}
|
|
|
|
|
} else {
|
|
|
|
|
if (curTime.getHours() < checkHour) {
|
|
|
|
|
curTime.setDate(curTime.getDate() - 1);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
} else {
|
|
|
|
|
if (curTime.getHours() < checkHour) {
|
|
|
|
|
curTime.setDate(curTime.getDate() - 1);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
let today = setLocalHours(hour, curTime);
|
|
|
|
|
return new Date(today + day * 24 * 60 * 60 * 1000);
|
|
|
|
|
let today = setLocalHours(hour, curTime);
|
|
|
|
|
return new Date(today + day * 24 * 60 * 60 * 1000);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
@@ -270,19 +270,19 @@ export function getRefTime(now = new Date(), hour: number, day = 0) {
|
|
|
|
|
* @param cnt 返回随机元素个数
|
|
|
|
|
*/
|
|
|
|
|
export function getRandEelm(source: Array<any> = [], cnt = 1): Array<any> {
|
|
|
|
|
if (cnt > source.length || cnt == 0 ) return [];
|
|
|
|
|
if (cnt === source.length) return source;
|
|
|
|
|
let idxs = new Set();
|
|
|
|
|
if (cnt > source.length || cnt == 0) return [];
|
|
|
|
|
if (cnt === source.length) return source;
|
|
|
|
|
let idxs = new Set();
|
|
|
|
|
|
|
|
|
|
while(1) {
|
|
|
|
|
let rand = Math.floor(Math.random() * source.length);
|
|
|
|
|
idxs.add(rand);
|
|
|
|
|
if (idxs.size >= cnt) {
|
|
|
|
|
break;
|
|
|
|
|
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));
|
|
|
|
|
return source.filter((_item, idx) => idxs.has(idx));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
@@ -292,7 +292,7 @@ export function getRandEelm(source: Array<any> = [], cnt = 1): Array<any> {
|
|
|
|
|
* @param decimal 返回值保留的小数位数
|
|
|
|
|
*/
|
|
|
|
|
export function getRandValue(base: number, ratio: number, decimal = 2): number {
|
|
|
|
|
return parseFloat((base * (1 - ratio + Math.random() * ratio * 2)).toFixed(decimal));
|
|
|
|
|
return parseFloat((base * (1 - ratio + Math.random() * ratio * 2)).toFixed(decimal));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@@ -303,145 +303,145 @@ export function getRandValue(base: number, ratio: number, decimal = 2): number {
|
|
|
|
|
* @param decimal 返回值保留的小数位数
|
|
|
|
|
*/
|
|
|
|
|
export function getRandValueByMinMax(min: number, max: number, decimal = 2): number {
|
|
|
|
|
return parseFloat((min + (max - min) * Math.random()).toFixed(decimal));
|
|
|
|
|
|
|
|
|
|
return parseFloat((min + (max - min) * Math.random()).toFixed(decimal));
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
export function resResult(status: {code: number, simStr: string}, data = null, customMsg = '') {
|
|
|
|
|
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 resResult(status: { code: number, simStr: string }, data = null, customMsg = '') {
|
|
|
|
|
const { code, simStr } = status;
|
|
|
|
|
if (code !== STATUS.SUCCESS.code) {
|
|
|
|
|
console.log(`normal err, code: ${code}, des: ${customMsg || simStr}`);
|
|
|
|
|
}
|
|
|
|
|
return { code, msg: customMsg || simStr, data };
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 消除 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));
|
|
|
|
|
}
|
|
|
|
|
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 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;
|
|
|
|
|
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;
|
|
|
|
|
}
|
|
|
|
|
}catch(e) {
|
|
|
|
|
console.error(e);
|
|
|
|
|
return defaultVal;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
export function setLocalHours(hour: number, curTime = new Date()) {
|
|
|
|
|
// curTime: 格林威治时间
|
|
|
|
|
let offset = curTime.getTimezoneOffset(); // 格林威治时间和本地时间之间的时差(分)
|
|
|
|
|
let localTime = new Date(curTime.getTime() + offset * 60 * 1000 + 8 * 60 * 60 * 1000); // 中国时间
|
|
|
|
|
localTime.setUTCHours(hour, 0, 0, 0); // 中国的几点
|
|
|
|
|
return localTime.getTime() - 8 * 60 * 60 * 1000; // 回到格林威治时间
|
|
|
|
|
// curTime: 格林威治时间
|
|
|
|
|
let offset = curTime.getTimezoneOffset(); // 格林威治时间和本地时间之间的时差(分)
|
|
|
|
|
let localTime = new Date(curTime.getTime() + offset * 60 * 1000 + 8 * 60 * 60 * 1000); // 中国时间
|
|
|
|
|
localTime.setUTCHours(hour, 0, 0, 0); // 中国的几点
|
|
|
|
|
return localTime.getTime() - 8 * 60 * 60 * 1000; // 回到格林威治时间
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export async function updateCe(roleId: string, hero: any ) {
|
|
|
|
|
let {hid, ce: oldCe, historyCe} = hero;
|
|
|
|
|
let actor = new Actor();
|
|
|
|
|
actor.initHero(hero);
|
|
|
|
|
let ce = actor.calculateCE();
|
|
|
|
|
if(ce != oldCe) {
|
|
|
|
|
// 更新总战力&最强五人战力
|
|
|
|
|
await RoleModel.updateSumCe(roleId, hid, ce, oldCe);
|
|
|
|
|
// 更新pvp防守阵容战力
|
|
|
|
|
await PvpDefenseModel.updateCe(roleId, hid, ce, oldCe);
|
|
|
|
|
// 更新武将战力,历史最高战力
|
|
|
|
|
await HeroModel.updateCe(roleId, hid, ce, oldCe, historyCe);
|
|
|
|
|
}
|
|
|
|
|
export async function updateCe(roleId: string, hero: any) {
|
|
|
|
|
let { hid, ce: oldCe, historyCe } = hero;
|
|
|
|
|
let actor = new Actor();
|
|
|
|
|
actor.initHero(hero);
|
|
|
|
|
let ce = actor.calculateCE();
|
|
|
|
|
if (ce != oldCe) {
|
|
|
|
|
// 更新总战力&最强五人战力
|
|
|
|
|
await RoleModel.updateSumCe(roleId, hid, ce, oldCe);
|
|
|
|
|
// 更新pvp防守阵容战力
|
|
|
|
|
await PvpDefenseModel.updateCe(roleId, hid, ce, oldCe);
|
|
|
|
|
// 更新武将战力,历史最高战力
|
|
|
|
|
await HeroModel.updateCe(roleId, hid, ce, oldCe, historyCe);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export function ratioReward(rewardStr: string, ratio: number): string {
|
|
|
|
|
let rewards = decodeIdCntArrayStr(rewardStr, ratio);
|
|
|
|
|
let res = '';
|
|
|
|
|
for (let [k, v] of rewards) {
|
|
|
|
|
res += `${k}&${v}|`;
|
|
|
|
|
}
|
|
|
|
|
return res.substring(0, res.length - 1);
|
|
|
|
|
let rewards = decodeIdCntArrayStr(rewardStr, ratio);
|
|
|
|
|
let res = '';
|
|
|
|
|
for (let [k, v] of rewards) {
|
|
|
|
|
res += `${k}&${v}|`;
|
|
|
|
|
}
|
|
|
|
|
return res.substring(0, res.length - 1);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export function getItems(str:string) {
|
|
|
|
|
let arr = new Array<{id: number, count: number}>();
|
|
|
|
|
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])
|
|
|
|
|
id: parseInt(itemArr[0]),
|
|
|
|
|
count: parseInt(itemArr[1])
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
return arr;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export function deepCopy (obj) {
|
|
|
|
|
export function deepCopy(obj) {
|
|
|
|
|
if (typeof obj !== 'object' || obj === null) {
|
|
|
|
|
return obj;
|
|
|
|
|
}
|
|
|
|
@@ -466,65 +466,65 @@ export function deepCopy (obj) {
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
export function readJsonFile(fileName: string) {
|
|
|
|
|
const folder = 'jsons';
|
|
|
|
|
return fs.readFileSync(path.resolve(__dirname, `../resource/${folder}/${fileName}.json`)).toString('utf8').replace(/^\uFEFF/, '');
|
|
|
|
|
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 fs.readFileSync(path.resolve(__dirname, `../resource/${folder}/${file}`)).toString('utf8');
|
|
|
|
|
});
|
|
|
|
|
const folder = 'warJsons';
|
|
|
|
|
return fs.readdirSync(__dirname + `/../resource/${folder}`)
|
|
|
|
|
.filter(cur => { return cur.indexOf('.') != 0 })
|
|
|
|
|
.map(file => {
|
|
|
|
|
return fs.readFileSync(path.resolve(__dirname, `../resource/${folder}/${file}`)).toString('utf8');
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 字典表常用解析方法
|
|
|
|
|
// 解析物品 {"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
|
|
|
|
|
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
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 数字列表
|
|
|
|
|
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(parseInt(g));
|
|
|
|
|
}
|
|
|
|
|
return res;
|
|
|
|
|
let res = new Array<number>();
|
|
|
|
|
if (!str) return res;
|
|
|
|
|
let arr = decodeArrayStr(str, '&');
|
|
|
|
|
for (let g of arr) {
|
|
|
|
|
if (g === "") continue;
|
|
|
|
|
res.push(parseInt(g));
|
|
|
|
|
}
|
|
|
|
|
return res;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export function mergeSameGoods(goods: Array<{id: number, count: number}>) {
|
|
|
|
|
export function mergeSameGoods(goods: Array<{ id: number, count: number }>) {
|
|
|
|
|
let resGoods = [];
|
|
|
|
|
for (let {id, count} of goods) {
|
|
|
|
|
let index = _.findIndex(resGoods, {id});
|
|
|
|
|
for (let { id, count } of goods) {
|
|
|
|
|
let index = _.findIndex(resGoods, { id });
|
|
|
|
|
if (index > -1) {
|
|
|
|
|
resGoods[index].count += count;
|
|
|
|
|
} else {
|
|
|
|
|
resGoods.push({id, count});
|
|
|
|
|
resGoods.push({ id, count });
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
return resGoods;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export function returnHeroCeRatio(hero: HeroType) {
|
|
|
|
|
let ce = reduceCe(hero.ce);
|
|
|
|
|
return Object.assign(hero, { ce });
|
|
|
|
|
let ce = reduceCe(hero.ce);
|
|
|
|
|
return Object.assign(hero, { ce });
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 缩小战力
|
|
|
|
|
export function reduceCe(ce: number = 0) {
|
|
|
|
|
return Math.floor(ce/HERO_CE_RATIO/HERO_CE_RATIO)
|
|
|
|
|
return Math.floor(ce / HERO_CE_RATIO / HERO_CE_RATIO)
|
|
|
|
|
}
|