diff --git a/game-server/app/servers/role/handler/roleHandler.ts b/game-server/app/servers/role/handler/roleHandler.ts index 14861679e..168989f99 100644 --- a/game-server/app/servers/role/handler/roleHandler.ts +++ b/game-server/app/servers/role/handler/roleHandler.ts @@ -6,7 +6,8 @@ import { EquipModel } from '../../../db/Equip'; import { calculateCE, resResult } from '../../../pubUtils/util'; import {Application, BackendSession, createTcpMailBox} from 'pinus'; import { COUNTER } from '../../../consts'; - +import { handleCost } from '../../../services/rewardService' +import { getTitle } from '../../../pubUtils/data' export default function(app: Application) { 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); 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 }); + } + } diff --git a/game-server/app/services/equipService.ts b/game-server/app/services/equipService.ts index 3ff743047..c28ac5607 100644 --- a/game-server/app/services/equipService.ts +++ b/game-server/app/services/equipService.ts @@ -1,16 +1,6 @@ -import { ITID, CONSUME_TYPE, getCurNameById, ITEM_TABLE } from './../consts'; -import { EquipModel } from './../db/Equip'; -import { resResult, deepCopy, mergeSameGoods } from '../pubUtils/util'; +import { mergeSameGoods } from '../pubUtils/util'; import { getGoodById } from '../pubUtils/gamedata'; -import { RoleModel } from '../db/Role'; -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'; +import { getJewelById } from '../pubUtils/data'; const _ = require('underscore'); export function checkMaterialEnough(consumes:Array<{id: number, count: number}>, jewel: number, jewelCount: number) { diff --git a/shared/consts/constModules/sysConst.ts b/shared/consts/constModules/sysConst.ts index 83b59eda7..a9676328b 100644 --- a/shared/consts/constModules/sysConst.ts +++ b/shared/consts/constModules/sysConst.ts @@ -87,7 +87,8 @@ export const FILENAME = { DIC_STRENGTHEN_COST: 'dic_zyz_enhancementCost', DIC_REFINE: 'dic_zyz_jinglian', 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 = [ diff --git a/shared/consts/statusCode.ts b/shared/consts/statusCode.ts index 07b8bf0a3..f19c0e1b5 100644 --- a/shared/consts/statusCode.ts +++ b/shared/consts/statusCode.ts @@ -168,6 +168,10 @@ export const STATUS = { EQUIP_NOT_EQUIPED_HERO: {code: 30507, simStr: '装备不能被该武将穿戴'}, EQUIP_LEVEL_LIMIT: {code: 30508, simStr: '装备穿戴等级限制'}, EQUIP_NOT_MATCH_JEWEL: {code: 30504, simStr: '装备不能镶嵌该宝石' }, + //全局养成30500-30699 + ROLE_REACH_MAX_TITLE_LEVEL: {code: 30500, simStr: '玩家已达到最高的爵位'}, + + // 社交相关状态 40000 - 49999 // 运营模块相关状态 50000 - 59999 // GM后台相关状态 60000 - 69999 diff --git a/shared/db/Item.ts b/shared/db/Item.ts index 3f84af40b..dbed8c730 100644 --- a/shared/db/Item.ts +++ b/shared/db/Item.ts @@ -57,7 +57,7 @@ export default class Item extends BaseModel { if (!ratio) { rec = await ItemModel.findOneAndUpdate({ roleId, id, count: { $gte: count } }, { $inc: { count: -1 * count } }, { new: true }).lean(lean); } 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) { let index = _.findIndex(result,{id}) diff --git a/shared/db/Role.ts b/shared/db/Role.ts index 155593926..66aa23eea 100644 --- a/shared/db/Role.ts +++ b/shared/db/Role.ts @@ -13,6 +13,7 @@ interface roleUpdate { frdCnt?: number; expeditionPoint?:number; globalCeAttr?:CeAttr; + title?:number; } class TopHero { @@ -168,6 +169,12 @@ export default class Role extends BaseModel { @prop({ required: true, type: DungeonHero, default: [] }) dungeonHeroes: Array; // 秘境首通使用的武将 + // 全局养成 + @prop({ required: true, default: 1 }) + title: number; //爵位 + //神像 + + public static async findByUid(uid: number, serverId: number, lean = true) { const role: RoleType = await RoleModel.findOne({ 'userInfo.uid': uid, serverId }).lean(lean); return role; diff --git a/shared/pubUtils/data.ts b/shared/pubUtils/data.ts index 2c44e8202..7e6854265 100644 --- a/shared/pubUtils/data.ts +++ b/shared/pubUtils/data.ts @@ -30,7 +30,7 @@ import { dicStrengthenCost } from './dictionary/DicStrengthenCost'; import { dicRefine } from './dictionary/DicRefine'; import { dicHeroEquip } from './dictionary/DicHeroEquip'; import { dicSuit } from './dictionary/DicSuit'; - +import { dicTitle } from './dictionary/DicTitle' export const gameData = { blurprtCompose: dicBlueprtCompose, blueprtPossibility: dicBlueprtPossibility, @@ -71,7 +71,8 @@ export const gameData = { refine: dicRefine, jewels: dicJewel, dicHeroEquip: dicHeroEquip, - suit: dicSuit + suit: dicSuit, + title: dicTitle }; // 在此提供一些原先在gamedata中提供的方法,以便更方便获取gameData数据 @@ -198,3 +199,8 @@ export function getHeroJob(jobId: number) { const job = gameData.job.get(jobId); return job; } + +export function getTitle(titleLv: number) { + const titleInfo = gameData.title.get(titleLv); + return titleInfo; +} diff --git a/shared/pubUtils/dictionary/DicTitle.ts b/shared/pubUtils/dictionary/DicTitle.ts new file mode 100644 index 000000000..9fa6efa2f --- /dev/null +++ b/shared/pubUtils/dictionary/DicTitle.ts @@ -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; + // 等级现在 + readonly lvLimited: number; + // 升级消耗 + readonly material:Array<{id: number, number: number}>; +} + +const str = readJsonFile(FILENAME.DIC_TITLE); +let arr = JSON.parse(str); + +type KeysEnum = { [P in keyof Required]: true }; +const DicTitleKeys: KeysEnum = { + 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(); +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 +} diff --git a/shared/pubUtils/util.ts b/shared/pubUtils/util.ts index a1256b5f7..039c861f5 100644 --- a/shared/pubUtils/util.ts +++ b/shared/pubUtils/util.ts @@ -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() - } 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() + } 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 }) { +// 计算当前武将战力 +export async function calculateSumCE(roleId: string, type: number, param: { num?: number, heroes?: Array }) { 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 - export function getRandomByLen(arr: Array):DicRandomEffectPool - export function getRandomByLen(arr: Array): any { +export function getRandomByLen(arr: Array): number +export function getRandomByLen(arr: Array): DicRandomEffectPool +export function getRandomByLen(arr: Array): 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 = [], cnt = 1): Array { - 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 = [], cnt = 1): Array { * @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(); - 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(); + 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) } \ No newline at end of file