diff --git a/game-server/app/servers/activity/handler/gachaHandler.ts b/game-server/app/servers/activity/handler/gachaHandler.ts index 9d59905c1..f71e0ec8d 100644 --- a/game-server/app/servers/activity/handler/gachaHandler.ts +++ b/game-server/app/servers/activity/handler/gachaHandler.ts @@ -1,10 +1,17 @@ import { Application, BackendSession } from "pinus"; -import { resResult } from "../../../pubUtils/util"; -import { STATUS, GACHA_ID } from "../../../consts"; +import { resResult, getRandomWithWeight } from "../../../pubUtils/util"; +import { STATUS, GACHA_ID, GACHA_CONTENT_TYPE, GACHA_OCCUPY_HID } from "../../../consts"; import { gameData } from "../../../pubUtils/data"; -import { GachaListReturn } from "../../../domain/activityField/gachaField"; +import { GachaListReturn, Floor, Hope, GachaResult } from "../../../domain/activityField/gachaField"; import { UserGachaModel } from "../../../db/UserGacha"; -import { refreshFreeCount } from "../../../services/gachaService"; +import { refreshGacha, getFloorResult, getResultFromContentId, transPiece } from "../../../services/gachaService"; +import { RoleModel } from "../../../db/Role"; +import { HeroModel, HeroUpdate } from "../../../db/Hero"; +import { RewardInter } from "../../../pubUtils/interface"; +import { handleCost, createHeroes, addItems } from "../../../services/rewardService"; +import { CounterModel } from "../../../db/Counter"; +import { getNextTime, getAfterDateByDay } from "../../../pubUtils/timeUtil"; +import { UserGachaRecModel } from "../../../db/UserGachaRec"; export default function (app: Application) { @@ -31,7 +38,8 @@ export class GachaHandler { if(id == GACHA_ID.TIMELIMIT) continue; // 不包括限时 let userGacha = userGachaList.find(cur => cur.gachaId == id); - userGacha = await refreshFreeCount(dicGacha, userGacha); + userGacha = await refreshGacha(dicGacha, userGacha); + console.log(JSON.stringify(userGacha)) let param = new GachaListReturn(dicGacha, userGacha); list.push(param); } @@ -47,9 +55,81 @@ export class GachaHandler { */ async pull(msg: { gachaId: number, activityId: number, count: number }, session: BackendSession) { const { gachaId, activityId, count } = msg; + if(gachaId == undefined|| activityId == undefined || count == undefined) return resResult(STATUS.WRONG_PARMS); const roleId: string = session.get('roleId'); + const roleName: string = session.get('roleName'); + const sid: string = session.get('sid'); + const serverId: number = session.get('serverId'); - return resResult(STATUS.SUCCESS); + let { lv } = await RoleModel.findByRoleId(roleId); + + let dicGacha = gameData.gacha.get(gachaId); + if(!dicGacha) return resResult(STATUS.DIC_DATA_NOT_FOUND); + if(!dicGacha.count.includes(count)) return resResult(STATUS.WRONG_PARMS); + + let userGacha = await UserGachaModel.findByRole(roleId, gachaId, activityId); + let { floor, freeCount, hope, point, pickHero, refFreeTime } = await refreshGacha(dicGacha, userGacha); + if((gachaId == GACHA_ID.ASSIGN|| gachaId == GACHA_ID.TIMELIMIT) && pickHero) return resResult(STATUS.GACHA_NOT_ASSIGN); + + let userHeroes = await HeroModel.findByRole(roleId); + + let items: RewardInter[] = [], heroInfo: HeroUpdate[] = [], resultList: GachaResult[] = []; + for(let i = 0; i < count; i++) { + // 按照一般概率抽出 + let { dic: { id: base } } = getRandomWithWeight(dicGacha.percent); + let contentId = getFloorResult(gachaId, base, floor); + if(contentId == false) return resResult(STATUS.DIC_DATA_NOT_FOUND); + let result = getResultFromContentId(contentId, lv, hope); + + if(result.hid > 0) { + result.setSetPickHero(pickHero); + let hasHero = userHeroes.find(cur => cur.hid == result.hid); + if(hasHero) { // 已有转换为碎片 + let { pieceId, count } = transPiece(result.hid); + result.transferToPiece(pieceId, count); + items.push({ id: pieceId, count }); + } else { + let { heroId: hid, name: hName, initialStars: star, quality, jobid: job, initialSkin } = gameData.hero.get(result.hid); + heroInfo.push({ roleId, serverId, roleName, hid, hName, star, quality, job, skins:[{id: initialSkin, enable: true}] }) + } + } else { + items.push({ id: result.id, count }); + } + resultList.push(result); + } +console.log('***', dicGacha.free.count, dicGacha.free.day, freeCount, count); + let costNum = count; + if(dicGacha.free.count > 0) { + if(count > dicGacha.free.count - freeCount) { + costNum = count - dicGacha.free.count + freeCount; + freeCount = dicGacha.free.count; + } else { + costNum = 0; + freeCount += count; + } + } + // 消耗东西 + if(costNum > 0) { + let cost = dicGacha.cost.map(cur => { return { id: cur.id, count: cur.count * costNum }}); + let costResult = await handleCost(roleId, sid, cost); + if(!costResult) return resResult(STATUS.GACHA_COST_NOT_ENOUGH); + } + // 给东西 + let heroes = await createHeroes(roleId, sid, serverId, heroInfo); + await addItems(roleId, roleName, sid, items); + // 更新数据 + point += count; + userGacha = await UserGachaModel.updateInfo(roleId, gachaId, activityId, { + freeCount, hope, floor, count, point + }); + + await UserGachaRecModel.createRec(roleId, gachaId, activityId, count, resultList); + + return resResult(STATUS.SUCCESS, { + gachaId, activityId, + freeCount, refFreeTime: getAfterDateByDay(refFreeTime, dicGacha.free.day), count, point, floor, + heroes, result: resultList + }); } /** diff --git a/game-server/app/servers/battle/handler/wishPoolHandler.ts b/game-server/app/servers/battle/handler/wishPoolHandler.ts index 1f497187b..8eb9b20e3 100644 --- a/game-server/app/servers/battle/handler/wishPoolHandler.ts +++ b/game-server/app/servers/battle/handler/wishPoolHandler.ts @@ -47,18 +47,18 @@ export class WishPoolHandler { let goodInfo = getGoodById(goodId) if (!goodInfo) return resResult(STATUS.WRONG_PARMS); - if (!(goodInfo.goodType == IT_TYPE.HERO_PIECE && type == 2 ) && !(goodInfo.goodType == IT_TYPE.EQUIP_PIECE && type == 1 )) + if (!(goodInfo.itid == IT_TYPE.HERO_PIECE && type == 2 ) && !(goodInfo.itid == IT_TYPE.EQUIP_PIECE && type == 1 )) return resResult(STATUS.WRONG_PARMS); let userGuild = await getUserGuildWithRefActive(roleId, ' wishDntCnt wishGoods guildCode wishGoods'); if (!userGuild) return resResult(STATUS.WRONG_PARMS); let result = await checkGoods(roleId, [goodId]); if (!result) { - if (goodInfo.goodType == IT_TYPE.HERO_PIECE ) { + if (goodInfo.itid == IT_TYPE.HERO_PIECE ) { result = await checkGoods(roleId, [goodInfo.hid]); if (!result) return resResult(STATUS.GUILD_WISH_POOL_NOT_OWN_HERO); - } else if (goodInfo.goodType == IT_TYPE.EQUIP_PIECE ) { + } else if (goodInfo.itid == IT_TYPE.EQUIP_PIECE ) { result = await checkGoods(roleId, [goodInfo.equipId]); if (!result) return resResult(STATUS.GUILD_WISH_POOL_NOT_OWN_EQUIP); diff --git a/game-server/app/servers/role/handler/roleHandler.ts b/game-server/app/servers/role/handler/roleHandler.ts index 57198e9a8..231a1c8aa 100644 --- a/game-server/app/servers/role/handler/roleHandler.ts +++ b/game-server/app/servers/role/handler/roleHandler.ts @@ -200,8 +200,8 @@ export class RoleHandler { let school = new Array(); gameData.school.forEach((dicSchool) => { let position = new Array(); - dicPosition.forEach((isOpen, id) => { - id = parseInt(id); + dicPosition.forEach((isOpen, dicId) => { + let id = parseInt(dicId); let userSchool = userSchoolList.find(cur => cur.schoolId == dicSchool.id && cur.positionId == id); if (userSchool) { diff --git a/game-server/app/services/battleService.ts b/game-server/app/services/battleService.ts index f083704af..9ab6218ec 100644 --- a/game-server/app/services/battleService.ts +++ b/game-server/app/services/battleService.ts @@ -5,7 +5,7 @@ import { HANG_UP_CONSTS, TOWER_TASK_CONST, REDIS_KEY, TASK_TYPE } from './../con import { BattleRecordModel } from './../db/BattleRecord'; import { TowerRecordModel } from './../db/TowerRecord'; import { RoleModel } from './../db/Role'; -import { getHeroInfoById, getJobInfoById, getTowerDataByLv, getTaskById, getGamedata, getRandExpedition, getWarById, getWarJsons } from "../pubUtils/gamedata" +import { getHeroInfoById, getJobInfoById, getTowerDataByLv, getTaskById, getGamedata, getWarJsons } from "../pubUtils/gamedata" import { decodeArrayStr, shouldRefresh, resResult, decodeStr, cal, getRandomWithWeight, getRefTime, decodeStrSingle, genCode } from '../pubUtils/util'; import { STATUS } from '../consts/statusCode'; import { HangUpSpdUpRecModel } from '../db/HangUpSpdUpRec'; @@ -13,6 +13,7 @@ import { TowerTaskRecModel } from '../db/TowerTaskRec'; import { cloneDeep } from 'lodash'; import { Rank } from './rankService'; import { checkTask } from './taskService'; +import { getRandExpedition } from '../pubUtils/data'; export async function checkTowerWar(roleId: string, battleId: number, heroes: Array) { const battleIdStr = `${battleId}`; diff --git a/game-server/app/services/comBattleService.ts b/game-server/app/services/comBattleService.ts index 53f046d51..34045e7f1 100644 --- a/game-server/app/services/comBattleService.ts +++ b/game-server/app/services/comBattleService.ts @@ -432,7 +432,8 @@ export function randEquipPrintId(warInfo) { if (!warInfo || !warInfo['jackpotReward']) { return null; } - const result = getRandomWithWeight(decodeStr('possibility', warInfo['jackpotReward'])); + let jackpotReward: { id: number, weight: number}[] = decodeStr('possibility', warInfo['jackpotReward']); + const result = getRandomWithWeight(jackpotReward); if (!result || !result.dic || !result.dic.id) { return null; } diff --git a/game-server/app/services/eventSercive.ts b/game-server/app/services/eventSercive.ts index 64acdd6c8..09adfda01 100644 --- a/game-server/app/services/eventSercive.ts +++ b/game-server/app/services/eventSercive.ts @@ -6,6 +6,7 @@ import { genCode, decodeStrSingle, decodeStr, getRandomWithWeight, resResult } f import { EVENT_STATUS, EVENT_RECORD_STATUS, EVENT_TYPE, EVENT_RANDOM_TYPE_ONE_OPEN, EVENT_QUIZ_NUM, EVENT_ANSWER_STATUS, FUNCS_ID } from '../consts'; import { EVENT_REFRESH_NUM } from '../consts'; import { STATUS } from '../consts/statusCode'; +import { gameData } from '../pubUtils/data'; /** * 从检查接口调用,检查是否有这么个战斗,顺便保存一下battleCode @@ -193,7 +194,7 @@ export async function refreshEvent(num: number, roleId: string, roleName: string }).map(cur => cur.point); let event = new Array(); - let dicEvent = getGamedata('dic_zyz_event'); + let dicEvent = gameData.eventList; let role = await RoleModel.findByRoleId(roleId); dicEvent = dicEvent.filter(cur => { // 筛选适合等级 let { suitLevel } = cur; @@ -268,8 +269,7 @@ export async function refreshEvent(num: number, roleId: string, roleName: string * * @param positionStr */ -function randomPosition(positionStr: string, prePoint: Array, curPoint: Array) { - let positionArr = decodeStr('point', positionStr, '&'); +function randomPosition(positionArr: number[], prePoint: Array, curPoint: Array) { let range = positionArr.filter(point => {return !prePoint.includes(point) && !curPoint.includes(point)}); if(range.length == 0) { // 如果位置总数不够,就不管prePoint里的 range = positionArr.filter(point => {return !curPoint.includes(point)}); diff --git a/game-server/app/services/gachaService.ts b/game-server/app/services/gachaService.ts index 69d54c55f..53c787e23 100644 --- a/game-server/app/services/gachaService.ts +++ b/game-server/app/services/gachaService.ts @@ -1,10 +1,12 @@ -import { GachaData, Floor } from "../domain/activityField/gachaField";; +import { GachaData, Floor, GachaResult, Hope } from "../domain/activityField/gachaField";; import { ActivityModelType, ActivityModel } from "../db/Activity"; import { DicGacha } from "../pubUtils/dictionary/DicGacha"; import { UserGachaType, UserGachaModel } from "../db/UserGacha"; -import { shouldRefresh } from "../pubUtils/util"; -import { REFRESH_HOUR, GACHA_ID, GACHA_TO_FLOOR } from "../consts"; -import { getNextDayByGap } from "../pubUtils/timeUtil"; +import { shouldRefresh, getRandEelm, decodeArrayListStr, getRandomWithWeight, decodeIdCntArrayStr } from "../pubUtils/util"; +import { REFRESH_HOUR, GACHA_ID, GACHA_TO_FLOOR, GACHA_FLOOR_TYPE, GACHA_CONTENT_TYPE, HERO_QUALITY_TYPE, GACHA_OCCUPY_HID, IT_TYPE, ITID, CONSUME_TYPE, SPECIAL_ATTR } from "../consts"; +import { getNextDayByGap, getTodayZeroDate } from "../pubUtils/timeUtil"; +import { gameData, getDicGachaFloor } from "../pubUtils/data"; +import { RECRUIT } from "../pubUtils/dicParam"; /** * 获取活动页签里的限时卡池 @@ -39,35 +41,269 @@ export async function getLimitGacha(activityId: number) { * @param dicGacha * @param userGacha */ -export async function refreshFreeCount(dicGacha: DicGacha, userGacha: UserGachaType) { +export async function refreshGacha(dicGacha: DicGacha, userGacha: UserGachaType) { let { day, count } = dicGacha.free; - if(count > 0) { + + if(count <= 0) { return userGacha; } - let { roleId, gachaId, refFreeTime } = userGacha; + let { roleId, gachaId, refFreeTime, refHopeTime } = userGacha; if(shouldRefresh(refFreeTime, new Date(), REFRESH_HOUR, day)) { let ref = getNextDayByGap(refFreeTime, new Date(), day); userGacha = await UserGachaModel.refreshFreeCount(roleId, gachaId, 0, ref); } + if(shouldRefresh(refHopeTime, new Date(), REFRESH_HOUR)) { + let ref = getTodayZeroDate(REFRESH_HOUR); + userGacha = await UserGachaModel.refreshHopeCount(roleId, gachaId, 0, ref); + } return userGacha } /** * @description 获取保底状态 - * @param type 招募类型 + * @param gachaId 招募类型 * @param floor 玩家保底 */ -export function getFloorStatus(type: number, floor: Floor[]) { +export function getFloorStatus(gachaId: number, floor: Floor[]) { let floorMap = new Map(); for(let { id, count } of floor) { floorMap.set(id, count); } - let dicFloorType = GACHA_TO_FLOOR.get(type); + let dicFloorType = GACHA_TO_FLOOR.get(gachaId); return dicFloorType.map(id => { return { id, count: floorMap.get(id)||0 } }); +} + +/** + * @description 获得保底结果 + * @param gachaId 招募表id + * @param base 按普通概率获得的东西 内容参考gachaContent + * @param floor 玩家保底数据 + */ +export function getFloorResult(gachaId: number, base: number, floor: Floor[]) { + let dicGachaContent = gameData.gachaContent.get(base); // 普通随机得出的结果是哪一类; + if(!dicGachaContent) { + console.error('dic_zyz_gachaContent error'); + return false; // DIC_NOT_FOUND 直接报错 + } + + let touchedFloor = 0, touchedHeroQuality: number; // 触发的保底的id + let dicFloorType = GACHA_TO_FLOOR.get(gachaId); + for(let id of dicFloorType) { + let { type, param } = dicGachaContent; + let heroQuality = getHeroQuality(id); + if(heroQuality == false) continue; + + let isTarget = type == GACHA_CONTENT_TYPE.HERO && param[0] == heroQuality; + if(!isTarget) { // 触发保底 + let percent = countFloorPercent(id, floor); + let rand = Math.random(); + if(rand < percent) { // 可以替换为保底 + if(touchedFloor > 0 && touchedFloor < id) { // 如果已经触发过保底了 + // 更新被覆盖掉的那个保底数量 + updateUserFloor(floor, touchedFloor, false); + } + touchedFloor = id; + touchedHeroQuality = heroQuality; + } else { + updateUserFloor(floor, id, false); + } + } else { + updateUserFloor(floor, id, true); + } + } + + if(touchedFloor > 0) { + updateUserFloor(floor, touchedFloor, true); + return gameData.gachaContentHero.get(touchedHeroQuality); + } else { + return base; + } +} + +/** + * @description 更新玩家保底数据 + * @param floor 玩家保底数据 + * @param id 更新的保底类型 + * @param needReset 是否重置保底 + */ +function updateUserFloor(floor: Floor[], id: number, needReset: boolean) { + let curFloor = floor.find(cur => cur.id == id); + if(!curFloor) { + curFloor = { id, count: 0 }; + floor.push(curFloor); + } + if(needReset) { + curFloor.count = 0; + } else { + curFloor.count ++; + } +} + +/** + * 计算保底概率 + * @param id 保底类型 + * @param floor 玩家保底数据 + */ +function countFloorPercent(id: number, floor: Floor[]) { + let curFloor = floor.find(cur => cur.id == id); + let count = curFloor?curFloor.count: 0; + // 保底概率,暂时使用线性公式,由策划使用后选择 + let floorCount = getDicGachaFloor(id); + return count / floorCount; +} + +/** + * 获取保底武将的品质 + * @param id 保底类型id in GACHA_FLOOR_TYPE + */ +function getHeroQuality(id: number) { + if(id == GACHA_FLOOR_TYPE.PURPLE) { + return HERO_QUALITY_TYPE.PURPLE; + } else if (GACHA_FLOOR_TYPE.GOLD) { + return HERO_QUALITY_TYPE.GOLD; + } else if (GACHA_FLOOR_TYPE.ASSIGN) { + return 0 + } else { + return false; + } +} + +/** + * 根据contentId获得抽卡结果(包括心愿单) + * @param contentId dic_zyz_gachaContent的id + * @param lv 玩家等级 + * @param hope 玩家心愿单 + */ +export function getResultFromContentId(contentId: number, lv: number, hope: Hope[]) { + let dic = gameData.gachaContent.get(contentId); + let { type, param, count } = dic; + if(type == GACHA_CONTENT_TYPE.HERO) { + let pool: number[] = getPoolByHope(hope, param[0]); + + let hero = getRandEelm(pool); + let result = new GachaResult(contentId); + result.setHero(hero[0]); + return result + } else { + let pool: number[] = []; + if(type == GACHA_CONTENT_TYPE.HERO_PIECE) { + pool = getAllItemByQuality(IT_TYPE.HERO_PIECE, param[0], lv); + } else if (type == GACHA_CONTENT_TYPE.BLUEPRT) { + pool = getAllItemByQuality(IT_TYPE.BLUEPRT, param[0], lv); + } else if (type == GACHA_CONTENT_TYPE.JEWEL) { + pool = getAllJewelByLv(param[0]); + } else if (type == GACHA_CONTENT_TYPE.TERAPH_MATERIAL) { + pool = param; + } else if (type == GACHA_CONTENT_TYPE.SUIT_PAPER) { + pool = getSuitPaper(lv); + } + let item = getRandEelm(pool); + let result = new GachaResult(contentId); + result.setItem(item[0], count); + return result; + } +} + +/** + * 心愿 + * @param hope 玩家数据里的心愿单 + * @param qualtiy 武将品质 + */ +function getPoolByHope(hope: Hope[], qualtiy: number) { + if(qualtiy == HERO_QUALITY_TYPE.GOLD) { + let hopeMap = new Map(); + let hasGetHope: number[] = []; + for(let h of hope) { + hopeMap.set(h.id, h); + if(h.hasGet) hasGetHope.push(h.id); + } + + let list = decodeArrayListStr(RECRUIT.RECRUIT_WISH_LIST).map(cur => { + let curHope = hopeMap.get(parseInt(cur[0])); + return { id: parseInt(cur[0]), hasGet: curHope?.hasGet||false, weight: parseInt(cur[1]) } + }); + let { dic: { id, hasGet } } = getRandomWithWeight(list); + if(id == 0 || hasGet) { + return getAllHeroByQuality(qualtiy).filter(cur => !hasGetHope.includes(cur) ); + } else { + if(hopeMap.has(id)) { + let curHope = hopeMap.get(id); + curHope.hasGet = true; + return [curHope.hid]; + } else { + return getAllHeroByQuality(qualtiy).filter(cur => !hasGetHope.includes(cur) ); + } + } + } else { + return getAllHeroByQuality(qualtiy); + } +} + +/** + * 根据品质获得武将池 + * @param quality 品质 + */ +function getAllHeroByQuality(quality: number) { + if(quality == 0) return [ GACHA_OCCUPY_HID ]; + + let allHero: number[] = []; + for(let [id, dicHero] of gameData.hero) { + if(dicHero.recruit && dicHero.quality == quality) { + allHero.push(id); + } + } + return allHero; +} + +function getAllItemByQuality(itid: number, quality: number, lv: number) { + let allPiece: number[] = []; + for(let [ id, dicGoods ] of gameData.goods) { + if(dicGoods.itid == itid) { + if((quality == 0 || dicGoods.quality == quality) || dicGoods.lvLimited <= lv) { + allPiece.push(id); + } + } + } + return allPiece; +} + +function getAllJewelByLv(lv: number) { + let itids: number[] = []; + for(let [ id, { type } ] of ITID) { + if(type == CONSUME_TYPE.JEWEL) itids.push(id); + } + let items: number[] = []; + for(let [ id, dicGoods ] of gameData.goods) { + if(itids.includes(dicGoods.itid)) { + if(lv == 0 || dicGoods.lvLimited == lv) { + items.push(id); + } + } + } + return items; +} + +function getSuitPaper(lv: number) { + let items: number[] = []; + for(let [ id, dicGoods ] of gameData.goods) { + if(dicGoods.itid == IT_TYPE.PAPER) { + if(dicGoods.lvLimited <= lv) { + items.push(id); + } + } + } + return items; +} + +export function transPiece(hid: number) { + let dicHero = gameData.hero.get(hid); + let { pieceId, quality } = dicHero; + let dicPiece = decodeIdCntArrayStr(RECRUIT.RECRUIT_CHANGE_SHARD, 1); // 多少品质对应多少碎片 + return { pieceId, count: dicPiece.get(quality.toString()) } } \ No newline at end of file diff --git a/game-server/app/services/rewardService.ts b/game-server/app/services/rewardService.ts index b1c9bc2e9..0c668ba0f 100644 --- a/game-server/app/services/rewardService.ts +++ b/game-server/app/services/rewardService.ts @@ -8,11 +8,11 @@ import { calAllHeroCe, pushCalPlayerCe, pushCalAllHeroCe } from './playerCeServi import { ItemModel } from '../db/Item'; import { STATUS } from '../consts/statusCode'; import { pinus } from 'pinus'; -import { addEquips, addBags, addSkins, addFigure, unlockFigure as pubUnlockFigure, createHero as pubCreateHero } from '../pubUtils/itemUtils'; +import { addEquips, addBags, addSkins, addFigure, unlockFigure as pubUnlockFigure, createHero as pubCreateHero, createHeroes as pubCreateHeroes } from '../pubUtils/itemUtils'; import { EquipInter, ItemInter, BagInter } from '../pubUtils/interface'; import { gameData } from '../pubUtils/data'; import { uniq, indexOf, findIndex } from 'underscore'; -import { HeroModel } from '../db/Hero'; +import { HeroModel, HeroUpdate } from '../db/Hero'; import { Figure } from '../domain/dbGeneral'; import { Rank } from './rankService'; import { pushTaskUpdate } from './taskService'; @@ -304,7 +304,34 @@ export async function pushFigureUpdate(roleId: string, sid: string, figureInfo: } } -export async function createHero(roleId: string, sid: string, serverId: number, heroInfo) { +/** + * 创建多个武将 + * @param roleId + * @param sid + * @param serverId + * @param heroInfo + */ +export async function createHeroes(roleId: string, sid: string, serverId: number, heroInfo: HeroUpdate[]) { + let { heroes, role, figureInfo, calHeroResults, calAllHeroResults, taskPushMessage } = await pubCreateHeroes(roleId, heroInfo); + + let r = new Rank(REDIS_KEY.HERO_NUM_RANK, { serverId }); + await r.setRankWithRoleInfo(roleId, role.heroNum, role.heroNumUpdatedAt, role); + + await pushFigureUpdate(roleId, sid, figureInfo); + + for(let calHeroResult of calHeroResults) { + await pushCalPlayerCe(roleId, sid, calHeroResult); + } + for(let calAllHeroResult of calAllHeroResults) { + await pushCalAllHeroCe(roleId, sid, calAllHeroResult); + } + + pushTaskUpdate(roleId, sid, null, taskPushMessage); + + return heroes; +} + +export async function createHero(roleId: string, sid: string, serverId: number, heroInfo: HeroUpdate) { let { hero, role, figureInfo, calHeroResult, calAllHeroResult, taskPushMessage } = await pubCreateHero(roleId, heroInfo); let r = new Rank(REDIS_KEY.HERO_NUM_RANK, { serverId }); @@ -312,7 +339,7 @@ export async function createHero(roleId: string, sid: string, serverId: number, await pushFigureUpdate(roleId, sid, figureInfo); - hero = await pushCalPlayerCe(roleId, sid, calHeroResult); + await pushCalPlayerCe(roleId, sid, calHeroResult); await pushCalAllHeroCe(roleId, sid, calAllHeroResult); pushTaskUpdate(roleId, sid, null, taskPushMessage); diff --git a/game-server/app/services/warRewardService.ts b/game-server/app/services/warRewardService.ts index 94cf8b66d..2012ef5b1 100644 --- a/game-server/app/services/warRewardService.ts +++ b/game-server/app/services/warRewardService.ts @@ -10,6 +10,7 @@ import { BATTLE_REWARD_TYPE, BLUEPRT_CONST } from '../consts'; import { addItems } from './rewardService'; import { BattleBlueprtDropModel } from '../db/BattleBlueprtDrop' import { RoleModel } from '../db/Role'; +import { gameData } from '../pubUtils/data'; export class WarReward { private roleId: string; @@ -169,13 +170,12 @@ export class WarReward { private async randomBlueprt() { const { lv } = await RoleModel.findByRoleId(this.roleId); - const dicPossibility = getGamedata('dic_blueprt_possibility'); + const dicPossibility = gameData.blueprtPossibility; const result = dicPossibility.find(cur => {return cur.min <= lv && cur.max >= lv}); if(result) { - const dicOdds = decodeStr('possibility', result.possibility); - const {dic: {id}} = getRandomWithWeight(dicOdds); + const {dic: {id}} = getRandomWithWeight(result.possibility); const blueprtList = getBluePrtByQuality(id); const gid = getRandomByLen(blueprtList); diff --git a/shared/consts/constModules/itemConst.ts b/shared/consts/constModules/itemConst.ts index cb6a15399..9fea24d97 100644 --- a/shared/consts/constModules/itemConst.ts +++ b/shared/consts/constModules/itemConst.ts @@ -1,8 +1,8 @@ export const IT_TYPE = { - BLUEPRT: 28, - EQUIP_PIECE: 3, - EQUIP: 2, - HERO_PIECE: 7, + BLUEPRT: 28, + EQUIP_PIECE: 40, + HERO_PIECE: 25, + PAPER: 41, } diff --git a/shared/consts/constModules/sysConst.ts b/shared/consts/constModules/sysConst.ts index 249e16a3b..131a886b5 100644 --- a/shared/consts/constModules/sysConst.ts +++ b/shared/consts/constModules/sysConst.ts @@ -680,5 +680,12 @@ export const GACHA_TO_FLOOR = new Map([ // 抽卡里的卡池道具类型 export enum GACHA_CONTENT_TYPE { + HERO = 1, // 武将 param为武将品质 + HERO_PIECE = 2, // 武将碎片 武将品质 + BLUEPRT = 3, // 藏宝图 藏宝图品质 + JEWEL = 4, // 宝石 宝石等级 + TERAPH_MATERIAL = 5, // 强化神像用的材料 材料物品id + SUIT_PAPER = 6, // 套装图纸 +} -} \ No newline at end of file +export const GACHA_OCCUPY_HID = 99; // 抽卡里占位的武将 \ No newline at end of file diff --git a/shared/consts/statusCode.ts b/shared/consts/statusCode.ts index 312d3a137..36974fd45 100644 --- a/shared/consts/statusCode.ts +++ b/shared/consts/statusCode.ts @@ -315,13 +315,15 @@ export const STATUS = { HERO_NOT_MAX: { code: 30904, simStr: '该武将未升满星' }, // 任务相关 31001-31100 - TASK_NOT_REACH_CONDITION: { code: 30900, simStr: '任务不满足条件' }, - TASK_HAS_RECEIVED: { code: 30901, simStr: '奖励已领取' }, - TASK_NOT_ALL_RECEIVED: { code: 30902, simStr: '任务未领取完' }, - TASK_ACTIVE_NOT_ENOUGH: { code: 30903, simStr: '活跃不足' }, - TASK_POINT_NOT_ENOUGH: { code: 30904, simStr: '积分不足' }, - TASK_BOX_HAS_RECEIVED: { code: 30905, simStr: '奖励已领取' }, - + TASK_NOT_REACH_CONDITION: { code: 31001, simStr: '任务不满足条件' }, + TASK_HAS_RECEIVED: { code: 31002, simStr: '奖励已领取' }, + TASK_NOT_ALL_RECEIVED: { code: 31003, simStr: '任务未领取完' }, + TASK_ACTIVE_NOT_ENOUGH: { code: 31004, simStr: '活跃不足' }, + TASK_POINT_NOT_ENOUGH: { code: 31005, simStr: '积分不足' }, + TASK_BOX_HAS_RECEIVED: { code: 31006, simStr: '奖励已领取' }, + // 抽卡相关 31101-31200 + GACHA_COST_NOT_ENOUGH: { code: 31101, simStr: '招募券不足' }, + GACHA_NOT_ASSIGN: { code: 31102, simStr: '请选择武将' }, // 社交相关状态 40000 - 49999 SYS_CHANNEL_AUTH_NOT_ENOUGH: { code: 40000, simStr: '无法在系统频道发送消息' }, UPDATE_PRIVATE_MSG_READ_TIME_ERR: { code: 40001, simStr: '更新私聊阅读时间失败' }, diff --git a/shared/db/UserGacha.ts b/shared/db/UserGacha.ts index 16eb035a8..109eaec13 100644 --- a/shared/db/UserGacha.ts +++ b/shared/db/UserGacha.ts @@ -1,9 +1,39 @@ import BaseModel from './BaseModel'; import { index, getModelForClass, prop, DocumentType, modelOptions } from '@typegoose/typegoose'; -import { getCurWeekDate, getTodayZeroDate } from '../pubUtils/timeUtil'; -import { Floor, Hope, Turntable } from '../domain/activityField/gachaField'; +import { getTodayZeroDate } from '../pubUtils/timeUtil'; import { REFRESH_HOUR } from '../consts'; +class Floor { + @prop({ required: true }) + id: number; // 保底类型 1-紫将保底 2-金将保底 3-指定将保底 + @prop({ required: true }) + count: number; // 抽卡次数 +} + +/** +* @description 心愿单 +* @memberof UserGacha +*/ +class Hope { + @prop({ required: true }) + id: number; // 位置 + @prop({ required: true }) + hid: number; // 武将id + @prop({ required: true }) + hasGet: boolean; // 是否得到 +} + +/** +* @description 转盘记录 +* @memberof UserGacha +*/ +class Turntable { + @prop({ required: true }) + quality: number; // 品质 + @prop({ required: true }) + hasGet: boolean; // 是否得到 +} + /** * 玩家抽卡表 **/ @@ -19,12 +49,12 @@ export default class UserGacha extends BaseModel { gachaId: number; // 抽卡id 1-元宝 2-友情 3-指定 4-限时 @prop({ required: true, default: 0 }) - aid: number; // 限时抽卡对应活动id + activityId: number; // 限时抽卡对应活动id @prop({ required: true, default: 0 }) count: number; // 已抽卡次数 - @prop({ required: true, type: (() => Floor)(), default: [] }) + @prop({ required: true, type: Floor, default: [], _id: false }) floor: Floor[]; // 已抽卡次数 @prop({ required: true, default: 0 }) @@ -33,13 +63,16 @@ export default class UserGacha extends BaseModel { @prop({ required: true, default: () => { return getTodayZeroDate(REFRESH_HOUR) } }) refFreeTime: Date; // 免费次数刷新时间 - @prop({ required: true, type: (() => Hope)(), default: [] }) + @prop({ required: true, type: () => Hope, default: [], _id: false }) hope: Hope[]; // 心愿单 + @prop({ required: true, default: () => { return getTodayZeroDate(REFRESH_HOUR) } }) + refHopeTime: Date; // 心愿单刷新时间 + @prop({ required: true, default: 0 }) point: number; // 积分 - @prop({ required: true, type: (() => Turntable)(), default: [] }) + @prop({ required: true, type: Turntable, default: [], _id: false }) turntable: Turntable[]; // 转盘 @prop({ required: true, default: 0 }) @@ -50,13 +83,31 @@ export default class UserGacha extends BaseModel { return rec; } + public static async findByRole(roleId: string, gachaId: number, activityId: number = 0) { + const doc = new UserGachaModel(); + const update = Object.assign(doc.toJSON(), { roleId, gachaId, activityId }); + delete update._id; + let rec: UserGachaType = await UserGachaModel.findOneAndUpdate({ roleId, gachaId, activityId }, { $setOnInsert: update }, { new: true, upsert: true }).lean(); + return rec; + } + + public static async updateInfo(roleId: string, gachaId: number, activityId: number, update: UserGachaParam) { + let rec: UserGachaType = await UserGachaModel.findOneAndUpdate({ roleId, gachaId, activityId }, { $set: update }, { new: true }).lean(); + return rec; + } + public static async refreshFreeCount(roleId: string, gachaId: number, aid: number, refFreeTime: Date) { let rec: UserGachaType = await UserGachaModel.findOneAndUpdate({ roleId, gachaId, aid }, { $set: { freeCount: 0, refFreeTime } }, { new: true }).lean(); return rec; } + + public static async refreshHopeCount(roleId: string, gachaId: number, aid: number, refHopeTime: Date) { + let rec: UserGachaType = await UserGachaModel.findOneAndUpdate({ roleId, gachaId, aid }, { $set: { 'hope.$.hasGet': false, refHopeTime } }, { new: true }).lean(); + return rec; + } } export const UserGachaModel = getModelForClass(UserGacha); export interface UserGachaType extends Pick, keyof UserGacha> { } -export type UserGachaParam = Partial; \ No newline at end of file +export type UserGachaParam = Partial; diff --git a/shared/db/UserGachaRec.ts b/shared/db/UserGachaRec.ts new file mode 100644 index 000000000..963a4c292 --- /dev/null +++ b/shared/db/UserGachaRec.ts @@ -0,0 +1,42 @@ +import BaseModel from './BaseModel'; +import { index, getModelForClass, prop, DocumentType, modelOptions } from '@typegoose/typegoose'; +import { GachaResult } from '../domain/activityField/gachaField'; +import { genCode } from '../pubUtils/util'; + +/** + * 玩家抽卡表 +**/ +@modelOptions({ schemaOptions: { id: false } }) +@index({ code: 1 }) + +export default class UserGachaRec extends BaseModel { + + @prop({ required: true }) + code: string; // 玩家id + + @prop({ required: true }) + roleId: string; // 玩家id + + @prop({ required: true }) + gachaId: number; // 抽卡id 1-元宝 2-友情 3-指定 4-限时 + + @prop({ required: true, default: 0 }) + activityId: number; // 限时抽卡对应活动id + + @prop({ required: true, default: 0 }) + count: number; // 抽卡次数 + + @prop({ required: true, type: GachaResult, default: [], _id: false }) + result: GachaResult[]; // 结果 + + public static async createRec(roleId: string, gachaId: number, activityId: number, count: number, result: GachaResult[]) { + let code = genCode(8); + const rec = await UserGachaRecModel.findOneAndUpdate({ code }, { $set: { roleId, gachaId, activityId, count, result } }, { new: true, upsert: true }); + return rec; + } +} + +export const UserGachaRecModel = getModelForClass(UserGachaRec); + +export interface UserGachaRecType extends Pick, keyof UserGachaRec> { } +export type UserGachaRecParam = Partial; \ No newline at end of file diff --git a/shared/domain/activityField/gachaField.ts b/shared/domain/activityField/gachaField.ts index f4eda0639..d44f291d8 100644 --- a/shared/domain/activityField/gachaField.ts +++ b/shared/domain/activityField/gachaField.ts @@ -5,6 +5,7 @@ import { UserGachaType } from '../../db/UserGacha'; import { getSeconds } from '../../pubUtils/timeUtil'; import { DicGacha } from '../../pubUtils/dictionary/DicGacha'; import { getFloorStatus } from '../../services/gachaService'; +import { GACHA_OCCUPY_HID } from '../../consts'; // 抽卡数据 @@ -76,7 +77,7 @@ export class GachaListReturn { this.gachaId = dicGacha.id; if(userGacha) { - this.freeCount = dicGacha.free.count - userGacha.freeCount; + this.freeCount = userGacha.freeCount; this.refFreeTime = getSeconds(userGacha.refFreeTime); this.count = userGacha.count; this.floor = getFloorStatus(dicGacha.id, userGacha.floor); @@ -88,4 +89,43 @@ export class GachaListReturn { this.floor = getFloorStatus(dicGacha.id, []); } } +} + +export class GachaResult { + @prop({ required: true }) + contentId: number; // 抽卡内容id + @prop({ required: true }) + hid: number = 0; // 武将id + @prop({ required: true }) + isTransfer: boolean = false; // 是否转换为碎片 + @prop({ required: true }) + id: number = 0; // 道具id + @prop({ required: true }) + count: number = 0; // 道具数量 + + constructor(contentId: number) { + this.contentId = contentId; + } + + setSetPickHero(hid: number) { + if(hid > 0 && this.hid == GACHA_OCCUPY_HID) { + this.hid = hid; + } + } + + setHero(hid: number) { + this.hid = hid; + this.count = 1; + } + + setItem(id: number, count: number) { + this.id = id; + this.count = count; + } + + transferToPiece(id: number, count: number) { + this.isTransfer = true; + this.id = id; + this.count = count; + } } \ No newline at end of file diff --git a/shared/pubUtils/data.ts b/shared/pubUtils/data.ts index e061555a1..1bd0e1e92 100644 --- a/shared/pubUtils/data.ts +++ b/shared/pubUtils/data.ts @@ -3,8 +3,8 @@ import { dicGoods, blueprt, dicJewel, figureCondition } from "./dictionary/DicGo import { dicBlueprtCompose } from "./dictionary/DicBlueprtCompose"; import { dicBlueprtPossibility } from "./dictionary/DicBlueprtPossibility"; import { dicDaily } from "./dictionary/DicDaily"; -import { dicEvent } from "./dictionary/DicEvent"; -import { dicExpedition } from "./dictionary/DicExpedition"; +import { dicEvent, dicEventList } from "./dictionary/DicEvent"; +import { dicExpedition, DicExpedition } from "./dictionary/DicExpedition"; import { dicExpeditionPoint } from "./dictionary/DicExpeditionPoint"; import { dicFuncSwitch } from "./dictionary/DicFuncSwitch"; import { dicHeroSkill } from "./dictionary/DicHeroSkill"; @@ -66,8 +66,8 @@ import { dicCityActivity } from "./dictionary/DicCityActivity"; import { dicChatAccuse } from "./dictionary/DicChatAccuse"; import { dicCityActivityReward } from "./dictionary/DicCityActivityReward"; import { dicRaceActivity, dicRaceTypes } from './dictionary/DicRaceActivity'; -import { GUILDACTIVITY } from "./dicParam"; -import { decodeIdCntArrayStr, parseGoodStr, decodeArrayListStr, getRandValueByMinMax } from "./util"; +import { GUILDACTIVITY, RECRUIT } from "./dicParam"; +import { decodeIdCntArrayStr, parseGoodStr, decodeArrayListStr, getRandValueByMinMax, getRandEelm } from "./util"; import { RACE_EVENT_TYPE } from "../consts"; import { dicShop, dicShopItem } from "./dictionary/DicShop"; import { dicShopList } from "./dictionary/DicShopList"; @@ -77,13 +77,14 @@ import { dicTaskType, taskMap, dicMainTask, dicDailyTask, dicAchievement } from import { dicMainTaskStage } from "./dictionary/DicMainTaskStage"; import { dicTaskBox } from './dictionary/DicTaskBox'; import { dicGacha } from "./dictionary/DicGacha"; -import { dicGachaContent } from "./dictionary/DicGachaContent"; +import { dicGachaContent, dicGachaContentHero } from "./dictionary/DicGachaContent"; export const gameData = { blurprtCompose: dicBlueprtCompose, blueprtPossibility: dicBlueprtPossibility, daily: dicDaily, event: dicEvent, + eventList: dicEventList, expedition: dicExpedition, expeditionPoint: dicExpeditionPoint, funcsSwitch: dicFuncSwitch, @@ -186,6 +187,7 @@ export const gameData = { taskBox: dicTaskBox, gacha: dicGacha, gachaContent: dicGachaContent, + gachaContentHero: dicGachaContentHero }; // 在此提供一些原先在gamedata中提供的方法,以便更方便获取gameData数据 @@ -532,7 +534,7 @@ function decodeRaceActivityEncounter() { let eventNum = 0; for(let [key, value] of map) { if(value == RACE_EVENT_TYPE.EVENT) eventNum ++; - newMap.set(parseInt(key), parseInt(value)); + newMap.set(parseInt(key), value); } return { events: newMap, eventNum }; } @@ -565,4 +567,19 @@ export function getRaceEventItems() { result.push({ id, count }); } return result; +} + +// 根据保底类型获得保底数量 +export function getDicGachaFloor(id: number) { + let map = decodeIdCntArrayStr(RECRUIT.RECRUIT_MUST, 1); + return map.get(id.toString()) +} + + +export function getRandExpedition(cnt = 1) { + let arr: DicExpedition[] = []; + for(let [_id, dicExpedition] of gameData.expedition) { + arr.push(dicExpedition); + } + return getRandEelm(arr, cnt); } \ No newline at end of file diff --git a/shared/pubUtils/dictionary/DicEvent.ts b/shared/pubUtils/dictionary/DicEvent.ts index e667e6ff3..46e7fdbf2 100644 --- a/shared/pubUtils/dictionary/DicEvent.ts +++ b/shared/pubUtils/dictionary/DicEvent.ts @@ -36,12 +36,13 @@ const str = readJsonFile(FILENAME.DIC_EVENT); let arr = JSON.parse(str); export const dicEvent = new Map(); +export const dicEventList = new Array(); arr.forEach(o => { o.winReward = parseGoodStr(o.winReward); o.loseReward = parseGoodStr(o.loseReward); o.suitLevel = parseSuitLevel(o.suitLevel); o.movePointArray = parseNumberList(o.movePointArray); - + dicEventList.push(o); dicEvent.set(o.eventID, o); }); diff --git a/shared/pubUtils/dictionary/DicGacha.ts b/shared/pubUtils/dictionary/DicGacha.ts index d80b20cc1..7d81aff3b 100644 --- a/shared/pubUtils/dictionary/DicGacha.ts +++ b/shared/pubUtils/dictionary/DicGacha.ts @@ -12,13 +12,13 @@ export interface DicGacha { // 消耗的招募券 readonly cost: RewardInter[]; // 概率 - readonly percent: { id: number, percent: number }[]; + readonly percent: { id: number, weight: number }[]; } const str = readJsonFile(FILENAME.DIC_GACHA); let arr = JSON.parse(str); -export const dicGacha = new Map(); +export const dicGacha = new Map(); // id => dic arr.forEach(o => { o.count = parseNumberList(o.count); o.free = parseFree(o.free); @@ -41,14 +41,14 @@ function parseFree(str: string) { } function parsePercent(str: string) { - let result = new Array<{ id: number, percent: number }>(); + let result = new Array<{ id: number, weight: number }>(); if (!str) return result; let decodeArr = decodeArrayListStr(str); - for (let [id, percent] of decodeArr) { - if (isNaN(parseInt(id)) || isNaN(parseInt(percent))) { + for (let [id, weight] of decodeArr) { + if (isNaN(parseInt(id)) || isNaN(parseInt(weight))) { throw new Error('data table format wrong'); } - result.push({ id: parseInt(id), percent: parseInt(percent) }); + result.push({ id: parseInt(id), weight: parseInt(weight) }); } return result } \ No newline at end of file diff --git a/shared/pubUtils/dictionary/DicGachaContent.ts b/shared/pubUtils/dictionary/DicGachaContent.ts index 4019d8be1..900fd16d4 100644 --- a/shared/pubUtils/dictionary/DicGachaContent.ts +++ b/shared/pubUtils/dictionary/DicGachaContent.ts @@ -1,5 +1,5 @@ import { readJsonFile, parseNumberList } from '../util' -import { FILENAME } from '../../consts' +import { FILENAME, GACHA_CONTENT_TYPE } from '../../consts' export interface DicGachaContent { // 内容id @@ -15,9 +15,14 @@ export interface DicGachaContent { const str = readJsonFile(FILENAME.DIC_GACHA_CONTENT); let arr = JSON.parse(str); -export const dicGachaContent = new Map(); +export const dicGachaContent = new Map(); // id => dic +export const dicGachaContentHero = new Map(); // quality => dic arr.forEach(o => { o.param = parseNumberList(o.param); + if(o.type == GACHA_CONTENT_TYPE.HERO) { + dicGachaContentHero.set(o.param[0], o.id); + } dicGachaContent.set(o.id, o); }); +arr = undefined; \ No newline at end of file diff --git a/shared/pubUtils/dictionary/DicHero.ts b/shared/pubUtils/dictionary/DicHero.ts index b3fc2980b..209c51169 100644 --- a/shared/pubUtils/dictionary/DicHero.ts +++ b/shared/pubUtils/dictionary/DicHero.ts @@ -27,13 +27,15 @@ export interface DicHero { readonly baseAbilityArr:Map; readonly baseAbilityUpArr:Map; readonly initialSkin: number; + // 是否可招募 + readonly recruit: boolean; } const str = readJsonFile(FILENAME.DIC_HERO); let arr = JSON.parse(str); type KeysEnum = { [P in keyof Required]: true }; -const DicHeroKeys: KeysEnum = {heroId: true, name: true, quality: true, camp: true, jobid: true, skill: true, pieceId: true, initialStars: true, pieceCount: true, baseAbilityArr: true, baseAbilityUpArr: true, initialSkin: true}; +const DicHeroKeys: KeysEnum = {heroId: true, name: true, quality: true, camp: true, jobid: true, skill: true, pieceId: true, initialStars: true, pieceCount: true, baseAbilityArr: true, baseAbilityUpArr: true, initialSkin: true, recruit: true}; export const dicMyHeroes = new Array(); export const dicHero = new Map(); arr.forEach(o => { @@ -42,7 +44,7 @@ arr.forEach(o => { } o.baseAbilityArr = parseBaseAbilityArr(o); o.baseAbilityUpArr = parseBaseAbilityUpArr(o); - + o.recruit = parseInt(o.recruit) == 1; dicHero.set(o.heroId, _.pick(o, Object.keys(DicHeroKeys))); }); diff --git a/shared/pubUtils/gamedata.ts b/shared/pubUtils/gamedata.ts index c01b94e0d..0052ccfd6 100644 --- a/shared/pubUtils/gamedata.ts +++ b/shared/pubUtils/gamedata.ts @@ -330,12 +330,6 @@ export function getExpeditionById(id: number) { return expeditionInfo.get(id); } -export function getRandExpedition(cnt = 1) { - const file = 'dic_expedition'; - const data = gamedata['jsons'][file] || []; - return getRandEelm(data, cnt); -} - export function getComBtlSetByQuality(quality: number) { return comBtlInfo.get(quality); } @@ -366,7 +360,7 @@ export function getBossHpByWarId(warId: number) { let { attribute, dataId, relation, actorId } = hero; if (relation === 2) { let attriData = decodeIdCntArrayStr(attribute, 1); - const hp = parseInt(attriData.get('1')); + const hp = attriData.get('1'); if (hp > 0) { bossHpArr.push({dataId, hp, actorId}); bossHpSum += hp; @@ -385,7 +379,7 @@ export function getWarIdByBlueprtId(blueprtId: number) { if (!warId) { const { specialAttr } = getGoodById(blueprtId); const attrData = decodeIdCntArrayStr(specialAttr, 1); - warId = parseInt(attrData.get('1')); + warId = attrData.get('1'); blueprtToWar.set(blueprtId, warId); } return warId; diff --git a/shared/pubUtils/itemUtils.ts b/shared/pubUtils/itemUtils.ts index bed2b50e8..ee66465dc 100644 --- a/shared/pubUtils/itemUtils.ts +++ b/shared/pubUtils/itemUtils.ts @@ -1,6 +1,6 @@ -import { HeroModel, HeroUpdate } from '../db/Hero'; +import { HeroModel, HeroUpdate, HeroType } from '../db/Hero'; import { ItemModel } from '../db/Item'; import { EquipModel, RandSe, Holes } from './../db/Equip'; import { BagInter, EquipInter } from './interface'; @@ -231,7 +231,7 @@ export async function createHeroes(roleId: string, heroInfos: HeroUpdate[]) { let heroNum = 0; let skinIds = new Array(); let conditions = new Array<{type: number, paramHid?: number, paramFavourLv?: number, paramSkinId?: number }>(); - let heroes = [], calHeroResults = [], calAllHeroResults = []; + let heroes: HeroType[] = [], calHeroResults = [], calAllHeroResults = []; for(let heroInfo of heroInfos) { let curHero = await HeroModel.createHero(heroInfo); heroes.push(curHero); diff --git a/shared/pubUtils/util.ts b/shared/pubUtils/util.ts index 04cdd4e90..0e73fa8dd 100644 --- a/shared/pubUtils/util.ts +++ b/shared/pubUtils/util.ts @@ -189,11 +189,11 @@ export function decodeArrayListStr(str: string) { */ export function decodeIdCntArrayStr(str: string, multi: number) { const strArr = decodeArrayStr(str); - console.log('decodeIdCntArrayStr: ', strArr); - const strMap = new Map(); + // 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]); + strMap.set(kv[0], multi ? Math.ceil(parseInt(kv[1]) * multi) : parseInt(kv[1])); }); return strMap; } @@ -219,7 +219,7 @@ export function getRandomIndexByLen(len: number) { return Math.floor(Math.random() * len); } -export function getRandomWithWeight(randomList: any) { +export function getRandomWithWeight(randomList: T[]): { dic: T, index: number } { let len = randomList.reduce((pre, cur) => { return pre + cur.weight || 1; }, 0); @@ -312,7 +312,7 @@ export function getRefTime(now = new Date(), checkHour: number, day = 0) { * @param source 原数组 * @param cnt 返回随机元素个数 */ -export function getRandEelm(source: Array = [], cnt = 1): Array { +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();