diff --git a/game-server/app/servers/role/handler/shopHandler.ts b/game-server/app/servers/role/handler/shopHandler.ts index 181ca4f8c..5369d7ea0 100644 --- a/game-server/app/servers/role/handler/shopHandler.ts +++ b/game-server/app/servers/role/handler/shopHandler.ts @@ -5,7 +5,7 @@ import { STATUS, GUILD_STRUCTURE, ITID, CONSUME_TYPE, HERO_QUALITY_TYPE, HERO_GR import { UserShopModel } from "../../../db/UserShop"; import { handleCost, addItems } from "../../../services/role/rewardService"; import { SHOP } from "../../../pubUtils/dicParam"; -import { HeroModel } from "../../../db/Hero"; +import { HeroModel, HeroType } from "../../../db/Hero"; import { checkShopInPurchase, getShopDicById, getShopListByType, getShopPrice } from "../../../services/shopService"; import { RewardInter, recycleSoulFastPara } from "../../../pubUtils/interface"; import { UserShopTypeModel } from "../../../db/UserShopType"; @@ -172,35 +172,44 @@ export class ShopHandler { let roleId = session.get('roleId'); let roleName = session.get('roleName'); let sid = session.get('sid'); - let { recycleSoulFastPara } = msg; - // 检测参数,防止hid、goodsId重复 + let { recycleSoulFastPara } = msg; + // 检测参数,防止hid重复 let checkHid = new Map(); - let checkGoodsId = new Map(); - for (let { hid, goodsId, count } of recycleSoulFastPara) { - if (checkHid.get(hid) || checkGoodsId.get(goodsId)) return resResult(STATUS.WRONG_PARMS); + for (let { hid, count } of recycleSoulFastPara) { + if (checkHid.get(hid)) return resResult(STATUS.WRONG_PARMS); checkHid.set(hid, 1); - checkGoodsId.set(goodsId, count); } - let items = await ItemModel.find({ roleId, id: { $in: recycleSoulFastPara.map(obj => obj.goodsId) } }); - if (!items || items.length == 0) return resResult(STATUS.ROLE_MATERIAL_NOT_ENOUGH); + // 从db获取所有武将数据 + const dbHeros = await HeroModel.findByHidsAndRole(roleId, recycleSoulFastPara.map(obj => obj.hid)) as HeroType[]; + let heroesMap = new Map(); + let items = [] + for (const val of dbHeros) { + let hid = val.hid + heroesMap.set(hid, val); - const itemsMap = arrToMap(items, obj => obj.id); + let dicHero = gameData.hero.get(hid); + if (!dicHero || !dicHero.pieceId) continue; + items.push(dicHero.pieceId); + } + // 从db获取相关碎片道具数据 + if (!items || items.length == 0) return resResult(STATUS.ROLE_MATERIAL_NOT_ENOUGH); + const dbItems = await ItemModel.findbyRoleAndIds(roleId, items); + if (!dbItems || dbItems.length == 0) return resResult(STATUS.ROLE_MATERIAL_NOT_ENOUGH); + const itemsMap = arrToMap(dbItems, obj => obj.id); let allAddItem = []; let allCostItem = []; - for (let { hid, goodsId, count } of recycleSoulFastPara) { - let dicGoods = gameData.goods.get(goodsId); - if (!dicGoods) return resResult(STATUS.WRONG_PARMS); - if (hid != dicGoods.hid) return resResult(STATUS.WRONG_PARMS);//校验一下hid和goodsId是否对应 - + for (let { hid, count } of recycleSoulFastPara) { let residueFragment = 0; + let goodsId = gameData.hero.get(hid)?.pieceId || 0; const curItemCount = itemsMap.get(goodsId)?.count || 0; if (curItemCount <= 0) return resResult(STATUS.ROLE_MATERIAL_NOT_ENOUGH); - let hero = await HeroModel.findByHidAndRole(hid, roleId); + let hero = heroesMap.get(hid); if (!hero) return resResult(STATUS.HERO_IS_HIDDEN); + if (hero.colorStar != HERO_GROW_MAX.COLORSTAR) { residueFragment = await calUpSixColorsResidueFragment(roleId, hero, hid, curItemCount); if (!residueFragment || count > residueFragment) return resResult(STATUS.ROLE_MATERIAL_NOT_ENOUGH); @@ -208,17 +217,21 @@ export class ShopHandler { allCostItem.push({ id: goodsId, count: count }); + let dicGoods = gameData.goods.get(goodsId); + if (!dicGoods) return resResult(STATUS.DIC_DATA_NOT_FOUND) + + let reward: RewardInter[] = []; switch (dicGoods.quality) { case HERO_QUALITY_TYPE.BLUE: - allAddItem.push(...parseGoodStr(SHOP.HERO_SOUL_BULE)); break + reward = parseGoodStr(SHOP.HERO_SOUL_BULE); break; case HERO_QUALITY_TYPE.PURPLE: - allAddItem.push(...parseGoodStr(SHOP.HERO_SOUL_PURPLE)); break; + reward = parseGoodStr(SHOP.HERO_SOUL_PURPLE); break; case HERO_QUALITY_TYPE.GOLD: - allAddItem.push(...parseGoodStr(SHOP.HERO_SOUL_GOLDEN)); break; + reward = parseGoodStr(SHOP.HERO_SOUL_GOLDEN); break; case HERO_QUALITY_TYPE.UR: - allAddItem.push(...parseGoodStr(SHOP.HERO_SOUL_UR)); break; + reward = parseGoodStr(SHOP.HERO_SOUL_UR); break; } - allAddItem.map(cur => { return { id: cur.id, count: cur.count * count } }) + allAddItem.push(...reward.map(cur => { return { id: cur.id, count: cur.count * count } })); } let costResult = await handleCost(roleId, sid, allCostItem, ITEM_CHANGE_REASON.RECYCLE_SOUL); @@ -230,7 +243,7 @@ export class ShopHandler { } - + // !测试接口。 去除限购次数 async debugClearPurchaseLimit(msg: {}, session: BackendSession) { let roleId = session.get('roleId'); diff --git a/game-server/app/services/checkParam.ts b/game-server/app/services/checkParam.ts index c0890bf98..93ebe811f 100644 --- a/game-server/app/services/checkParam.ts +++ b/game-server/app/services/checkParam.ts @@ -1983,8 +1983,8 @@ export function checkRouteParam(route: string, msg: any) { case "role.shopHandler.recycleSoulFast": { if (!checkNaturalArray(msg.recycleSoulFastPara)) return false; - for (let { hid, goodsId, count } of msg.recycleSoulFastPara) { - if (!checkNaturalNumbers(hid, goodsId, count)) return false; + for (let { hid, count } of msg.recycleSoulFastPara) { + if (!checkNaturalNumbers(hid, count)) return false; } break; } diff --git a/game-server/app/services/role/checkMaterial.ts b/game-server/app/services/role/checkMaterial.ts index 9c6521ba1..53db59292 100644 --- a/game-server/app/services/role/checkMaterial.ts +++ b/game-server/app/services/role/checkMaterial.ts @@ -362,8 +362,6 @@ export async function getComposeStoneCostAndAdd(curItem, itId) { export async function calUpSixColorsResidueFragment(roleId: string, hero: HeroType, hid: number, count?: number) { let needFragment = 0; - // if (isHeroHidden(hid)) return; - let dicHero = gameData.hero.get(hid); if (!dicHero) return; let { pieceId, jobid } = dicHero; @@ -371,9 +369,6 @@ export async function calUpSixColorsResidueFragment(roleId: string, hero: HeroTy let dicJob = gameData.job.get(jobid); if (!dicJob) return; - // let hero = await HeroModel.findByHidAndRole(hid, roleId); - // if (!hero) return; - let curItemCount = count; if (!count) { let item = await ItemModel.findbyRoleAndGid(roleId, pieceId); @@ -387,7 +382,11 @@ export async function calUpSixColorsResidueFragment(roleId: string, hero: HeroTy if (oldStar < HERO_GROW_MAX.STAR) { for (let starIndex = oldStar; starIndex < HERO_GROW_MAX.STAR; starIndex++) { const curDicHeroStar = getHeroStarByQuality(dicJob.job_class, oldQuality, starIndex); - needFragment += (curDicHeroStar?.advanceUpFragmentNum || 0) * (ABI_STAGE.END - oldStarStage); + if (starIndex == oldStar) { + needFragment += (curDicHeroStar?.advanceUpFragmentNum || 0) * (ABI_STAGE.END - oldStarStage); + continue; + } + needFragment += (curDicHeroStar?.advanceUpFragmentNum || 0) * ABI_STAGE.END; } } if (curItemCount < needFragment) return; @@ -396,7 +395,7 @@ export async function calUpSixColorsResidueFragment(roleId: string, hero: HeroTy if (oldQuality < HERO_GROW_MAX.QUALITY) { for (let qualityIndex = oldQuality; qualityIndex < HERO_GROW_MAX.QUALITY; qualityIndex++) { const curDicHeroQualityUp = gameData.heroQualityUp.get(qualityIndex); - needFragment += curDicHeroQualityUp?.fragmentNum || 0 + needFragment += curDicHeroQualityUp?.fragmentNum || 0; } } if (curItemCount < needFragment) return; @@ -409,7 +408,11 @@ export async function calUpSixColorsResidueFragment(roleId: string, hero: HeroTy needFragment += curDicHeroStar?.fragmentNum || 0; continue; } - needFragment += (curDicHeroStar?.fragmentNum || 0) * (ABI_STAGE.END - oldColorStarStage) + if (colorStarIndex == oldColorStar) { + needFragment += (curDicHeroStar?.fragmentNum || 0) * (ABI_STAGE.END - oldColorStarStage); + continue; + } + needFragment += (curDicHeroStar?.fragmentNum || 0) * ABI_STAGE.END; } } diff --git a/shared/db/Hero.ts b/shared/db/Hero.ts index 1072bca9b..7e867a6bd 100644 --- a/shared/db/Hero.ts +++ b/shared/db/Hero.ts @@ -45,7 +45,7 @@ export class HeroSkin { talent: Talent[]; // 天赋树 @prop({ required: true }) usedTalentPoint: number; // 已使用的天赋点数 - + constructor(skin: SkinUpdate, enable = true) { this.id = skin.id; this.skinId = skin.skinId; @@ -83,9 +83,9 @@ export class EPlace { @prop({ required: true }) jewel: number = 0; - getInitialStone? () { + getInitialStone?() { let result: Stone[] = []; - for(let id = 1; id <= 3; id++) { + for (let id = 1; id <= 3; id++) { result.push({ id, stone: 0 }); } return result; @@ -95,7 +95,7 @@ export class EPlace { this.id = id; this.equipId = equipId; this.stones = this.getInitialStone(); - } + } } @index({ seqId: 1 }) @@ -166,7 +166,7 @@ export default class Hero extends BaseModel { consumes: Reward[]; // 消耗 @prop({ required: true, default: 0 }) - artifact: number|string; // 宝物 + artifact: number | string; // 宝物 @prop({ required: true, default: 0 }) subHid: number; // 副将 @@ -221,6 +221,11 @@ export default class Hero extends BaseModel { return hero; } + public static async findByHidsAndRole(roleId: string, hids: Array, select?: string, getters = false) { + const heros: HeroType[] = await HeroModel.find({ roleId, hid: { $in: hids } }).select(select).lean({ getters }); + return heros; + } + public static async findSubHero(roleId: string, subHid: number) { const hero: HeroType = await HeroModel.findOne({ roleId, subHid }).lean(); return hero; @@ -228,9 +233,9 @@ export default class Hero extends BaseModel { // 设置副将 public static async setSubHero(roleId: string, hid: number, subSkinId: number, subActorId: number) { - const preHero = subActorId > 0? await HeroModel.findOneAndUpdate({ roleId, subActorId }, { $set: { subActorId: 0, subHid: 0 } }, { new: true }).lean(): null; + const preHero = subActorId > 0 ? await HeroModel.findOneAndUpdate({ roleId, subActorId }, { $set: { subActorId: 0, subHid: 0 } }, { new: true }).lean() : null; const curHero: HeroType = await HeroModel.findOneAndUpdate({ roleId, hid }, { $set: { subHid: subSkinId, subActorId } }, { new: true }).lean(); - return { preHid: preHero?.hid||0, curHero }; + return { preHid: preHero?.hid || 0, curHero }; } public static async addEquip(roleId: string, hid: number, ePlaceId: number, equipId: string) { @@ -253,7 +258,7 @@ export default class Hero extends BaseModel { let dicHero = gameData.hero.get(hid) let { quality, initialStar: star, initialColorStar: colorStar, jobid: job, name: hName } = dicHero; const doc = new HeroModel(); - const update = { ...doc.toJSON(), hid, skinId: hid, hName, star, colorStar, quality, job, lv: DEFAULT_HERO_LV, exp: getHeroExpByLv(DEFAULT_HERO_LV - 1) || 0, ...heroInfo}; + const update = { ...doc.toJSON(), hid, skinId: hid, hName, star, colorStar, quality, job, lv: DEFAULT_HERO_LV, exp: getHeroExpByLv(DEFAULT_HERO_LV - 1) || 0, ...heroInfo }; delete update._id; return update } @@ -329,18 +334,18 @@ export default class Hero extends BaseModel { private static getSearchObj(form: SearchHeroParam) { let searchObj = {}; - if(form.roleId) searchObj['roleId'] = form.roleId; - if(form.roleName) searchObj['roleName'] = { $regex: new RegExp(form.roleName.toString(), 'i') }; - if(form.hid) searchObj['hid'] = form.hid; + if (form.roleId) searchObj['roleId'] = form.roleId; + if (form.roleName) searchObj['roleName'] = { $regex: new RegExp(form.roleName.toString(), 'i') }; + if (form.hid) searchObj['hid'] = form.hid; return searchObj - } - - public static async findByCondition(page: number, pageSize: number, sortField: string = 'updatedAt', sortOrder: string = 'descend', form: SearchHeroParam = {}) { - + } + + public static async findByCondition(page: number, pageSize: number, sortField: string = 'updatedAt', sortOrder: string = 'descend', form: SearchHeroParam = {}) { + let searchObj = this.getSearchObj(form); let sort = {}; - if(sortField && sortOrder) { - if(sortOrder == 'ascend') { + if (sortField && sortOrder) { + if (sortOrder == 'ascend') { sort[sortField] = 1; } else if (sortOrder == 'descend') { sort[sortField] = -1; @@ -348,15 +353,15 @@ export default class Hero extends BaseModel { } const result: HeroType[] = await HeroModel.find(searchObj).limit(pageSize).skip((page - 1) * pageSize).sort(sort).lean({ getters: true, virtuals: true }); return result; - - } - - public static async countByCondition(form: SearchHeroParam = {}) { - - let searchObj = this.getSearchObj(form); - const result = await HeroModel.count(searchObj); - return result; - } + + } + + public static async countByCondition(form: SearchHeroParam = {}) { + + let searchObj = this.getSearchObj(form); + const result = await HeroModel.count(searchObj); + return result; + } } export const HeroModel = getModelForClass(Hero); diff --git a/shared/pubUtils/interface.ts b/shared/pubUtils/interface.ts index 8c23e135d..0c2eae130 100644 --- a/shared/pubUtils/interface.ts +++ b/shared/pubUtils/interface.ts @@ -68,6 +68,5 @@ export interface guildInter { export interface recycleSoulFastPara { hid: number; - goodsId: number; count: number; } \ No newline at end of file