This commit is contained in:
mamengke01
2020-12-24 16:38:07 +08:00
parent 884e759921
commit 526ed39feb
9 changed files with 418 additions and 324 deletions
@@ -6,7 +6,8 @@ import { EquipModel } from '../../../db/Equip';
import { calculateCE, resResult } from '../../../pubUtils/util'; import { calculateCE, resResult } from '../../../pubUtils/util';
import {Application, BackendSession, createTcpMailBox} from 'pinus'; import {Application, BackendSession, createTcpMailBox} from 'pinus';
import { COUNTER } from '../../../consts'; import { COUNTER } from '../../../consts';
import { handleCost } from '../../../services/rewardService'
import { getTitle } from '../../../pubUtils/data'
export default function(app: Application) { export default function(app: Application) {
return new RoleHandler(app); return new RoleHandler(app);
} }
@@ -68,4 +69,26 @@ export class RoleHandler {
let { roleId, roleName, headHid = 1, ce = 0, topFive, topFiveCe = 0 } = await RoleModel.findByRoleId(targetRoleId); let { roleId, roleName, headHid = 1, ce = 0, topFive, topFiveCe = 0 } = await RoleModel.findByRoleId(targetRoleId);
return resResult(STATUS.SUCCESS, { roleId, roleName, headHid, ce, topFive, topFiveCe }); return resResult(STATUS.SUCCESS, { roleId, roleName, headHid, ce, topFive, topFiveCe });
} }
//爵位
async roleTitleLevelUp(msg: {}, session: BackendSession){
let roleId = session.get('roleId');
let role = await RoleModel.findByRoleId(roleId);
let sid: string = session.get('sid');
let titleInfo = getTitle(role.title);
if (!titleInfo)
return resResult(STATUS.DIC_DATA_NOT_FOUND)
let title = ++role.title;
if (!getTitle(title))
return resResult(STATUS.ROLE_REACH_MAX_TITLE_LEVEL)
if (titleInfo.lvLimited > role.lv)
return resResult(STATUS.COM_BATTLE_LV_NOT_ENOUGH)
let consumes = titleInfo.material;
let result = await handleCost(roleId, sid, consumes);
if (!result)
return resResult(STATUS.BATTLE_CONSUMES_NOT_ENOUGH);
await RoleModel.updateRoleInfo(roleId, { title });
return resResult(STATUS.SUCCESS, { roleId, title });
}
} }
+2 -12
View File
@@ -1,16 +1,6 @@
import { ITID, CONSUME_TYPE, getCurNameById, ITEM_TABLE } from './../consts'; import { mergeSameGoods } from '../pubUtils/util';
import { EquipModel } from './../db/Equip';
import { resResult, deepCopy, mergeSameGoods } from '../pubUtils/util';
import { getGoodById } from '../pubUtils/gamedata'; import { getGoodById } from '../pubUtils/gamedata';
import { RoleModel } from '../db/Role'; import { getJewelById } from '../pubUtils/data';
import { setAp } from './actionPointService';
import { calAllHeroCe } from './playerCeService';
import { ItemModel } from '../db/Item';
import { STATUS } from '../consts/statusCode';
import { pinus } from 'pinus';
import { addEquips, addBags, addSkins } from '../pubUtils/itemUtils';
import { EquipInter, ItemInter, BagInter } from '../pubUtils/interface';
import { gameData, getJewelById } from '../pubUtils/data';
const _ = require('underscore'); const _ = require('underscore');
export function checkMaterialEnough(consumes:Array<{id: number, count: number}>, jewel: number, jewelCount: number) { export function checkMaterialEnough(consumes:Array<{id: number, count: number}>, jewel: number, jewelCount: number) {
+2 -1
View File
@@ -87,7 +87,8 @@ export const FILENAME = {
DIC_STRENGTHEN_COST: 'dic_zyz_enhancementCost', DIC_STRENGTHEN_COST: 'dic_zyz_enhancementCost',
DIC_REFINE: 'dic_zyz_jinglian', DIC_REFINE: 'dic_zyz_jinglian',
DIC_HERO_EQUIP: 'dic_zyz_heroEquip', DIC_HERO_EQUIP: 'dic_zyz_heroEquip',
DIC_SUIT: 'dic_zyz_suit' DIC_SUIT: 'dic_zyz_suit',
DIC_TITLE: 'dic_zyz_title'
} }
export const WAR_RELATE_TABLES = [ export const WAR_RELATE_TABLES = [
+4
View File
@@ -168,6 +168,10 @@ export const STATUS = {
EQUIP_NOT_EQUIPED_HERO: {code: 30507, simStr: '装备不能被该武将穿戴'}, EQUIP_NOT_EQUIPED_HERO: {code: 30507, simStr: '装备不能被该武将穿戴'},
EQUIP_LEVEL_LIMIT: {code: 30508, simStr: '装备穿戴等级限制'}, EQUIP_LEVEL_LIMIT: {code: 30508, simStr: '装备穿戴等级限制'},
EQUIP_NOT_MATCH_JEWEL: {code: 30504, simStr: '装备不能镶嵌该宝石' }, EQUIP_NOT_MATCH_JEWEL: {code: 30504, simStr: '装备不能镶嵌该宝石' },
//全局养成30500-30699
ROLE_REACH_MAX_TITLE_LEVEL: {code: 30500, simStr: '玩家已达到最高的爵位'},
// 社交相关状态 40000 - 49999 // 社交相关状态 40000 - 49999
// 运营模块相关状态 50000 - 59999 // 运营模块相关状态 50000 - 59999
// GM后台相关状态 60000 - 69999 // GM后台相关状态 60000 - 69999
+1 -1
View File
@@ -57,7 +57,7 @@ export default class Item extends BaseModel {
if (!ratio) { if (!ratio) {
rec = await ItemModel.findOneAndUpdate({ roleId, id, count: { $gte: count } }, { $inc: { count: -1 * count } }, { new: true }).lean(lean); rec = await ItemModel.findOneAndUpdate({ roleId, id, count: { $gte: count } }, { $inc: { count: -1 * count } }, { new: true }).lean(lean);
} else { } else {
rec = await ItemModel.findOneAndUpdate({ roleId, id }, { $inc: { count: ratio * count } }, { new: true }).lean(lean); rec = await ItemModel.findOneAndUpdate({ roleId, id }, { $inc: { count: ratio * count } }, { new: true, upsert: true }).lean(lean);
} }
if (!!rec) { if (!!rec) {
let index = _.findIndex(result,{id}) let index = _.findIndex(result,{id})
+7
View File
@@ -13,6 +13,7 @@ interface roleUpdate {
frdCnt?: number; frdCnt?: number;
expeditionPoint?:number; expeditionPoint?:number;
globalCeAttr?:CeAttr; globalCeAttr?:CeAttr;
title?:number;
} }
class TopHero { class TopHero {
@@ -168,6 +169,12 @@ export default class Role extends BaseModel {
@prop({ required: true, type: DungeonHero, default: [] }) @prop({ required: true, type: DungeonHero, default: [] })
dungeonHeroes: Array<DungeonHero>; // 秘境首通使用的武将 dungeonHeroes: Array<DungeonHero>; // 秘境首通使用的武将
// 全局养成
@prop({ required: true, default: 1 })
title: number; //爵位
//神像
public static async findByUid(uid: number, serverId: number, lean = true) { public static async findByUid(uid: number, serverId: number, lean = true) {
const role: RoleType = await RoleModel.findOne({ 'userInfo.uid': uid, serverId }).lean(lean); const role: RoleType = await RoleModel.findOne({ 'userInfo.uid': uid, serverId }).lean(lean);
return role; return role;
+8 -2
View File
@@ -30,7 +30,7 @@ import { dicStrengthenCost } from './dictionary/DicStrengthenCost';
import { dicRefine } from './dictionary/DicRefine'; import { dicRefine } from './dictionary/DicRefine';
import { dicHeroEquip } from './dictionary/DicHeroEquip'; import { dicHeroEquip } from './dictionary/DicHeroEquip';
import { dicSuit } from './dictionary/DicSuit'; import { dicSuit } from './dictionary/DicSuit';
import { dicTitle } from './dictionary/DicTitle'
export const gameData = { export const gameData = {
blurprtCompose: dicBlueprtCompose, blurprtCompose: dicBlueprtCompose,
blueprtPossibility: dicBlueprtPossibility, blueprtPossibility: dicBlueprtPossibility,
@@ -71,7 +71,8 @@ export const gameData = {
refine: dicRefine, refine: dicRefine,
jewels: dicJewel, jewels: dicJewel,
dicHeroEquip: dicHeroEquip, dicHeroEquip: dicHeroEquip,
suit: dicSuit suit: dicSuit,
title: dicTitle
}; };
// 在此提供一些原先在gamedata中提供的方法,以便更方便获取gameData数据 // 在此提供一些原先在gamedata中提供的方法,以便更方便获取gameData数据
@@ -198,3 +199,8 @@ export function getHeroJob(jobId: number) {
const job = gameData.job.get(jobId); const job = gameData.job.get(jobId);
return job; return job;
} }
export function getTitle(titleLv: number) {
const titleInfo = gameData.title.get(titleLv);
return titleInfo;
}
+63
View File
@@ -0,0 +1,63 @@
// 物品表
import { decodeArrayListStr, readJsonFile, parseGoodStr } from '../util'
import { FILENAME} from '../../consts'
const _ = require('lodash');
export interface SpecialMaterial {
readonly ids: number[];
readonly count: number;
}
export interface DicTitle {
// 等级
readonly id: number;
readonly hp: number;
readonly atk: number;
readonly def: number;
readonly mdef: number;
readonly agi: number;
readonly luk: number;
readonly assiAttrValue: Map<number, number>;
// 等级现在
readonly lvLimited: number;
// 升级消耗
readonly material:Array<{id: number, number: number}>;
}
const str = readJsonFile(FILENAME.DIC_TITLE);
let arr = JSON.parse(str);
type KeysEnum<T> = { [P in keyof Required<T>]: true };
const DicTitleKeys: KeysEnum<DicTitle> = {
id: true,
hp: true,
atk: true,
def: true,
mdef: true,
agi: true,
luk: true,
assiAttrValue: true,
lvLimited: true,
material: true
}
export const dicTitle = new Map<number, DicTitle>();
arr.forEach(o => {
o.assiAttrValue = parseAttr(o.assiAttrValue);
o.material = parseGoodStr(o.material);
dicTitle.set(o.id, _.pick(o, Object.keys(DicTitleKeys)));
});
arr = undefined;
function parseAttr(str: string) {
let result = new Array<{id: number, number: number}>();
if(!str) return result;
let decodeArr = decodeArrayListStr(str);
for(let [id, number] of decodeArr) {
if(isNaN(parseInt(id)) || isNaN(parseInt(number))) {
throw new Error('data table format wrong');
}
result.push({id: parseInt(id), number: parseInt(number)});
}
return result
}
+307 -307
View File
@@ -14,126 +14,126 @@ const _ = require('underscore');
const moment = require('moment'); const moment = require('moment');
export function genCode(len) { export function genCode(len) {
const chars = '123456789ABCDEFGHJKLMNPQRSTWXYZabcdefghijklmnopqrstuvwxyz'; const chars = '123456789ABCDEFGHJKLMNPQRSTWXYZabcdefghijklmnopqrstuvwxyz';
const charArr = chars.split(''); const charArr = chars.split('');
let code = ''; let code = '';
for (let i = 0; i < len; i++) { 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; return code;
} }
export function decodeStr(type, str, splitForm='|') { export function decodeStr(type, str, splitForm = '|') {
if(str == '&'|| !str) { if (str == '&' || !str) {
return [] return []
} else { } else {
return str.split(splitForm).map(cur => { return str.split(splitForm).map(cur => {
return decodeStrSingle(type,cur); return decodeStrSingle(type, cur);
}); });
}; };
} }
export function decodeStrSingle(type, str) { //单层,返回对象而不是数组 export function decodeStrSingle(type, str) { //单层,返回对象而不是数组
let last = str.substr(str.length-1, 1); let last = str.substr(str.length - 1, 1);
if(last == '&') str = str.substr(0, str.length - 1); if (last == '&') str = str.substr(0, str.length - 1);
if(str == '&'|| !str) { if (str == '&' || !str) {
return {} return {}
} else { } else {
let arr = str.split('&'); let arr = str.split('&');
let result: any; let result: any;
switch (type) { switch (type) {
case 'fixReward': { case 'fixReward': {
let [id, count] = arr; let [id, count] = arr;
if(isNaN(id) || isNaN(count)) throw new Error('data table format wrong'); if (isNaN(id) || isNaN(count)) throw new Error('data table format wrong');
result = { id: parseInt(id), count: parseInt(count)}; result = { id: parseInt(id), count: parseInt(count) };
break; 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': { return result;
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;
}; };
} }
/** /**
* 将 | 分隔的字符串解析为数组,如:a|b|c 解析为[a, b, c] * 将 | 分隔的字符串解析为数组,如:a|b|c 解析为[a, b, c]
* @param str 要解析的字符串 * @param str 要解析的字符串
*/ */
export function decodeArrayStr(str: string, splitForm='|') { export function decodeArrayStr(str: string, splitForm = '|') {
let last = str.substr(str.length-1, 1); let last = str.substr(str.length - 1, 1);
if(last == '&') str = str.substr(0, str.length - 1); if (last == '&') str = str.substr(0, str.length - 1);
if(str == '') { if (str == '') {
return new Array<string>() return new Array<string>()
} else { } else {
return str.split(splitForm); return str.split(splitForm);
} }
} }
/** /**
@@ -141,7 +141,7 @@ export function decodeArrayStr(str: string, splitForm='|') {
* @param str 要解析的字符串 * @param str 要解析的字符串
*/ */
export function decodeArrayListStr(str: string) { 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 要解析的字符串 * @param str 要解析的字符串
*/ */
export function decodeIdCntArrayStr(str: string, multi: number) { export function decodeIdCntArrayStr(str: string, multi: number) {
const strArr = decodeArrayStr(str); const strArr = decodeArrayStr(str);
console.log('decodeIdCntArrayStr: ', strArr); console.log('decodeIdCntArrayStr: ', strArr);
const strMap = new Map(); const strMap = new Map();
strArr.forEach(item => { strArr.forEach(item => {
const kv = item.split('&'); const kv = item.split('&');
strMap.set(kv[0], multi? Math.ceil(parseInt(kv[1]) * multi): kv[1]); strMap.set(kv[0], multi ? Math.ceil(parseInt(kv[1]) * multi) : kv[1]);
}); });
return strMap; 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; let sum;
if(type == 1) { // 最高num人历史最高战力和 if (type == 1) { // 最高num人历史最高战力和
sum = await HeroModel.sumTopHeroCe(roleId, param.num||0); sum = await HeroModel.sumTopHeroCe(roleId, param.num || 0);
} else if(type == 2) { // 所有人战力和 } else if (type == 2) { // 所有人战力和
sum = await HeroModel.sumHeroCe(roleId); sum = await HeroModel.sumHeroCe(roleId);
} }
return sum; return sum;
} }
// 计算当前武将战力 // 计算当前武将战力
export function calculateCE(heroInfo: {hid: number, lv: number }) { export function calculateCE(heroInfo: { hid: number, lv: number }) {
let { hid, lv } = heroInfo; let { hid, lv } = heroInfo;
// 假设所有属性和等级的关系是简单的线性关系 // 假设所有属性和等级的关系是简单的线性关系
let dicHero = getGamedata('dic_zyz_hero'); 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; let ce = atk + matk + def + mdef + agi + luk;
return ce; return ce;
} }
export function getRandomByLen(arr: Array<number>):number export function getRandomByLen(arr: Array<number>): number
export function getRandomByLen(arr: Array<DicRandomEffectPool>):DicRandomEffectPool export function getRandomByLen(arr: Array<DicRandomEffectPool>): DicRandomEffectPool
export function getRandomByLen(arr: Array<any>): any { export function getRandomByLen(arr: Array<any>): any {
let len = arr.length; let len = arr.length;
return arr[Math.floor(Math.random() * len)] return arr[Math.floor(Math.random() * len)]
} }
export function getRandomWithWeight(randomList: any) { export function getRandomWithWeight(randomList: any) {
let len = randomList.reduce((pre, cur) => { let len = randomList.reduce((pre, cur) => {
return pre + cur.weight||1; return pre + cur.weight || 1;
}, 0); }, 0);
let index = Math.floor(Math.random() * len); let index = Math.floor(Math.random() * len);
let result = { dic: null, index: -1 }; let result = { dic: null, index: -1 };
for(let i = 0; i < randomList.length; i++) { for (let i = 0; i < randomList.length; i++) {
let {weight = 0} = randomList[i]; let { weight = 0 } = randomList[i];
if(index < weight) { if (index < weight) {
result.dic = randomList[i]; result.dic = randomList[i];
result.index = i; result.index = i;
break; break;
} }
index -= weight; index -= weight;
} }
return result return result
} }
/** /**
* 传入两个时间,返回按照时间差计算,第二个时间比第一个晚几天 * 传入两个时间,返回按照时间差计算,第二个时间比第一个晚几天
* @param preTime 之前的时间 * @param preTime 之前的时间
* @param proTime 之后的时间 * @param proTime 之后的时间
*/ */
export function deltaDays(preTime: Date, proTime: Date): number { 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) * @param deltaDay 间隔几天刷新,默认每天刷新(deltaDay = 1)
*/ */
export function shouldRefresh(preTime: Date, now: Date, hour: number, deltaDay = 1): boolean { export function shouldRefresh(preTime: Date, now: Date, hour: number, deltaDay = 1): boolean {
if(!preTime) return true; if (!preTime) return true;
let curTime = new Date(now.getTime()); let curTime = new Date(now.getTime());
let refeshTime = setLocalHours(hour, curTime); let refeshTime = setLocalHours(hour, curTime);
console.log(refeshTime - preTime.getTime(), (deltaDay>=1?deltaDay-1:0) * 24 * 60 * 60 * 1000, curTime.getTime(), refeshTime) 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) { if (refeshTime - preTime.getTime() > (deltaDay >= 1 ? deltaDay - 1 : 0) * 24 * 60 * 60 * 1000 && curTime.getTime() >= refeshTime) {
return true; return true;
} }
return false; return false;
} }
/** /**
@@ -247,21 +247,21 @@ export function shouldRefresh(preTime: Date, now: Date, hour: number, deltaDay =
* @param hour 几点刷新 * @param hour 几点刷新
*/ */
export function getRefTime(now = new Date(), hour: number, day = 0) { export function getRefTime(now = new Date(), hour: number, day = 0) {
let curTime = new Date(now.getTime()); let curTime = new Date(now.getTime());
let offset = curTime.getTimezoneOffset(); // 时差,单位分 let offset = curTime.getTimezoneOffset(); // 时差,单位分
let checkHour = hour - 8 + offset/60; let checkHour = hour - 8 + offset / 60;
if(checkHour < 0) { if (checkHour < 0) {
checkHour = 24 + checkHour; checkHour = 24 + checkHour;
if (curTime.getHours() >= checkHour) { if (curTime.getHours() >= checkHour) {
curTime.setDate(curTime.getDate() + 1); curTime.setDate(curTime.getDate() + 1);
}
} else {
if (curTime.getHours() < checkHour) {
curTime.setDate(curTime.getDate() - 1);
}
} }
} else { let today = setLocalHours(hour, curTime);
if (curTime.getHours() < checkHour) { return new Date(today + day * 24 * 60 * 60 * 1000);
curTime.setDate(curTime.getDate() - 1);
}
}
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 返回随机元素个数 * @param cnt 返回随机元素个数
*/ */
export function getRandEelm(source: Array<any> = [], cnt = 1): Array<any> { export function getRandEelm(source: Array<any> = [], cnt = 1): Array<any> {
if (cnt > source.length || cnt == 0 ) return []; if (cnt > source.length || cnt == 0) return [];
if (cnt === source.length) return source; if (cnt === source.length) return source;
let idxs = new Set(); let idxs = new Set();
while(1) { while (1) {
let rand = Math.floor(Math.random() * source.length); let rand = Math.floor(Math.random() * source.length);
idxs.add(rand); idxs.add(rand);
if (idxs.size >= cnt) { if (idxs.size >= cnt) {
break; 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 返回值保留的小数位数 * @param decimal 返回值保留的小数位数
*/ */
export function getRandValue(base: number, ratio: number, decimal = 2): number { 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 返回值保留的小数位数 * @param decimal 返回值保留的小数位数
*/ */
export function getRandValueByMinMax(min: number, max: number, decimal = 2): number { 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 = '') { export function resResult(status: { code: number, simStr: string }, data = null, customMsg = '') {
const { code, simStr } = status; const { code, simStr } = status;
if (code !== STATUS.SUCCESS.code) { if (code !== STATUS.SUCCESS.code) {
console.log(`normal err, code: ${code}, des: ${customMsg || simStr}`); console.log(`normal err, code: ${code}, des: ${customMsg || simStr}`);
} }
return {code, msg: customMsg || simStr, data}; return { code, msg: customMsg || simStr, data };
} }
// 消除 js 浮点计算bug // 消除 js 浮点计算bug
export const cal = { export const cal = {
add: function(a:number, b:number) { add: function (a: number, b: number) {
var c:number, d:number, e:number; var c: number, d: number, e: number;
try { try {
c = a.toString().split(".")[1].length; c = a.toString().split(".")[1].length;
} catch (f) { } catch (f) {
c = 0; c = 0;
} }
try { try {
d = b.toString().split(".")[1].length; d = b.toString().split(".")[1].length;
} catch (f) { } catch (f) {
d = 0; d = 0;
} }
e = Math.pow(10, Math.max(c, d)); e = Math.pow(10, Math.max(c, d));
return (this.mul(a, e) + this.mul(b, e)) / e; return (this.mul(a, e) + this.mul(b, e)) / e;
}, },
sub: function sub(a:number, b:number) { sub: function sub(a: number, b: number) {
var c:number, d:number, e:number; var c: number, d: number, e: number;
try { try {
c = a.toString().split(".")[1].length; c = a.toString().split(".")[1].length;
} catch (f) { } catch (f) {
c = 0; c = 0;
} }
try { try {
d = b.toString().split(".")[1].length; d = b.toString().split(".")[1].length;
} catch (f) { } catch (f) {
d = 0; d = 0;
} }
e = Math.pow(10, Math.max(c, d)); e = Math.pow(10, Math.max(c, d));
return (this.mul(a, e) - this.mul(b, e)) / e; return (this.mul(a, e) - this.mul(b, e)) / e;
}, },
mul: function mul(a:number, b:number) { mul: function mul(a: number, b: number) {
var c = 0, var c = 0,
d = a.toString(), d = a.toString(),
e = b.toString(); e = b.toString();
try { try {
c += d.split(".")[1].length; c += d.split(".")[1].length;
} catch (f) {} } catch (f) { }
try { try {
c += e.split(".")[1].length; c += e.split(".")[1].length;
} catch (f) {} } catch (f) { }
return Number(d.replace(".", "")) * Number(e.replace(".", "")) / Math.pow(10, c); return Number(d.replace(".", "")) * Number(e.replace(".", "")) / Math.pow(10, c);
}, },
div: function div(a:number, b:number) { div: function div(a: number, b: number) {
var c:number, d:number, e = 0, var c: number, d: number, e = 0,
f = 0; f = 0;
try { try {
e = a.toString().split(".")[1].length; e = a.toString().split(".")[1].length;
} catch (g) {} } catch (g) { }
try { try {
f = b.toString().split(".")[1].length; f = b.toString().split(".")[1].length;
} catch (g) {} } catch (g) { }
c = Number(a.toString().replace(".", "")); c = Number(a.toString().replace(".", ""));
d = Number(b.toString().replace(".", "")); d = Number(b.toString().replace(".", ""));
return this.mul(c / d, Math.pow(10, f - e)); return this.mul(c / d, Math.pow(10, f - e));
} }
}; };
//计算公式 //计算公式
export function calculateNum(ratio: {A: number, B: number}, params: {num: number}, defaultVal = 0) { export function calculateNum(ratio: { A: number, B: number }, params: { num: number }, defaultVal = 0) {
// result = a * num + b // result = a * num + b
try { try {
let {A, B} = ratio; let { A, B } = ratio;
let {num} = params; let { num } = params;
let result = A * num + B; let result = A * num + B;
if(isNaN(result)) { if (isNaN(result)) {
console.error('calculate wrong: ', A, B, num) console.error('calculate wrong: ', A, B, num)
return defaultVal; return defaultVal;
} else { } else {
return result; return result;
}
} catch (e) {
console.error(e);
return defaultVal;
} }
}catch(e) {
console.error(e);
return defaultVal;
}
} }
export function setLocalHours(hour: number, curTime = new Date()) { export function setLocalHours(hour: number, curTime = new Date()) {
// curTime: 格林威治时间 // curTime: 格林威治时间
let offset = curTime.getTimezoneOffset(); // 格林威治时间和本地时间之间的时差(分) let offset = curTime.getTimezoneOffset(); // 格林威治时间和本地时间之间的时差(分)
let localTime = new Date(curTime.getTime() + offset * 60 * 1000 + 8 * 60 * 60 * 1000); // 中国时间 let localTime = new Date(curTime.getTime() + offset * 60 * 1000 + 8 * 60 * 60 * 1000); // 中国时间
localTime.setUTCHours(hour, 0, 0, 0); // 中国的几点 localTime.setUTCHours(hour, 0, 0, 0); // 中国的几点
return localTime.getTime() - 8 * 60 * 60 * 1000; // 回到格林威治时间 return localTime.getTime() - 8 * 60 * 60 * 1000; // 回到格林威治时间
} }
export async function updateCe(roleId: string, hero: any ) { export async function updateCe(roleId: string, hero: any) {
let {hid, ce: oldCe, historyCe} = hero; let { hid, ce: oldCe, historyCe } = hero;
let actor = new Actor(); let actor = new Actor();
actor.initHero(hero); actor.initHero(hero);
let ce = actor.calculateCE(); let ce = actor.calculateCE();
if(ce != oldCe) { if (ce != oldCe) {
// 更新总战力&最强五人战力 // 更新总战力&最强五人战力
await RoleModel.updateSumCe(roleId, hid, ce, oldCe); await RoleModel.updateSumCe(roleId, hid, ce, oldCe);
// 更新pvp防守阵容战力 // 更新pvp防守阵容战力
await PvpDefenseModel.updateCe(roleId, hid, ce, oldCe); await PvpDefenseModel.updateCe(roleId, hid, ce, oldCe);
// 更新武将战力,历史最高战力 // 更新武将战力,历史最高战力
await HeroModel.updateCe(roleId, hid, ce, oldCe, historyCe); await HeroModel.updateCe(roleId, hid, ce, oldCe, historyCe);
} }
} }
export function ratioReward(rewardStr: string, ratio: number): string { export function ratioReward(rewardStr: string, ratio: number): string {
let rewards = decodeIdCntArrayStr(rewardStr, ratio); let rewards = decodeIdCntArrayStr(rewardStr, ratio);
let res = ''; let res = '';
for (let [k, v] of rewards) { for (let [k, v] of rewards) {
res += `${k}&${v}|`; res += `${k}&${v}|`;
} }
return res.substring(0, res.length - 1); return res.substring(0, res.length - 1);
} }
export function getItems(str:string) { export function getItems(str: string) {
let arr = new Array<{id: number, count: number}>(); let arr = new Array<{ id: number, count: number }>();
let strArr = str.split('|'); let strArr = str.split('|');
for (let item of strArr) { for (let item of strArr) {
var itemArr = item.split('&'); var itemArr = item.split('&');
arr.push({ arr.push({
id : parseInt(itemArr[0]), id: parseInt(itemArr[0]),
count : parseInt(itemArr[1]) count: parseInt(itemArr[1])
}); });
} }
return arr; return arr;
} }
export function deepCopy (obj) { export function deepCopy(obj) {
if (typeof obj !== 'object' || obj === null) { if (typeof obj !== 'object' || obj === null) {
return obj; return obj;
} }
@@ -466,65 +466,65 @@ export function deepCopy (obj) {
}; };
export function readJsonFile(fileName: string) { export function readJsonFile(fileName: string) {
const folder = 'jsons'; const folder = 'jsons';
return fs.readFileSync(path.resolve(__dirname, `../resource/${folder}/${fileName}.json`)).toString('utf8').replace(/^\uFEFF/, ''); return fs.readFileSync(path.resolve(__dirname, `../resource/${folder}/${fileName}.json`)).toString('utf8').replace(/^\uFEFF/, '');
} }
export function readWarJsonFileList() { export function readWarJsonFileList() {
const folder = 'warJsons'; const folder = 'warJsons';
return fs.readdirSync(__dirname + `/../resource/${folder}`) return fs.readdirSync(__dirname + `/../resource/${folder}`)
.filter(cur => {return cur.indexOf('.') != 0}) .filter(cur => { return cur.indexOf('.') != 0 })
.map(file => { .map(file => {
return fs.readFileSync(path.resolve(__dirname, `../resource/${folder}/${file}`)).toString('utf8'); return fs.readFileSync(path.resolve(__dirname, `../resource/${folder}/${file}`)).toString('utf8');
}); });
} }
// 字典表常用解析方法 // 字典表常用解析方法
// 解析物品 {"id": number, "count": number} 格式 // 解析物品 {"id": number, "count": number} 格式
export function parseGoodStr(str: string) { export function parseGoodStr(str: string) {
let result = new Array<{id: number, count: number}>(); let result = new Array<{ id: number, count: number }>();
if(!str) return result; if (!str) return result;
let decodeArr = decodeArrayListStr(str); let decodeArr = decodeArrayListStr(str);
for(let [id, count] of decodeArr) { for (let [id, count] of decodeArr) {
if(isNaN(parseInt(id)) || isNaN(parseInt(count))) { if (isNaN(parseInt(id)) || isNaN(parseInt(count))) {
throw new Error('data table format wrong'); throw new Error('data table format wrong');
} }
result.push({id: parseInt(id), count: parseInt(count)}); result.push({ id: parseInt(id), count: parseInt(count) });
} }
return result return result
} }
// 数字列表 // 数字列表
export function parseNumberList(str: string) { export function parseNumberList(str: string) {
let res = new Array<number>(); let res = new Array<number>();
if(!str) return res; if (!str) return res;
let arr = decodeArrayStr(str, '&'); let arr = decodeArrayStr(str, '&');
for(let g of arr) { for (let g of arr) {
if(g === "") continue; if (g === "") continue;
res.push(parseInt(g)); res.push(parseInt(g));
} }
return res; return res;
} }
export function mergeSameGoods(goods: Array<{id: number, count: number}>) { export function mergeSameGoods(goods: Array<{ id: number, count: number }>) {
let resGoods = []; let resGoods = [];
for (let {id, count} of goods) { for (let { id, count } of goods) {
let index = _.findIndex(resGoods, {id}); let index = _.findIndex(resGoods, { id });
if (index > -1) { if (index > -1) {
resGoods[index].count += count; resGoods[index].count += count;
} else { } else {
resGoods.push({id, count}); resGoods.push({ id, count });
} }
} }
return resGoods; return resGoods;
} }
export function returnHeroCeRatio(hero: HeroType) { export function returnHeroCeRatio(hero: HeroType) {
let ce = reduceCe(hero.ce); let ce = reduceCe(hero.ce);
return Object.assign(hero, { ce }); return Object.assign(hero, { ce });
} }
// 缩小战力 // 缩小战力
export function reduceCe(ce: number = 0) { 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)
} }