diff --git a/game-server/app/servers/battle/handler/comBattleHandler.ts b/game-server/app/servers/battle/handler/comBattleHandler.ts index 991a17e49..77cf8404a 100644 --- a/game-server/app/servers/battle/handler/comBattleHandler.ts +++ b/game-server/app/servers/battle/handler/comBattleHandler.ts @@ -1,12 +1,14 @@ -import { IT_TYPE } from '../../../consts/consts'; -import { getGoodById, getBossHpByBlueprtId, getComBtlSetByQuality } from '../../../pubUtils/gamedata'; +import { IT_TYPE, GOLD_COST_RATIO, CURRENCY_BY_TYPE, CURRENCY_TYPE } from '../../../consts/consts'; +import { getGoodById, getBossHpByBlueprtId, getComBtlSetByQuality, getBlueprtComposeByQuality, getBluePrtByQuality } from '../../../pubUtils/gamedata'; import { COM_TEAM_STATUS, COM_TEAM_ENABLE_LV } from '../../../consts/consts'; import { ComBattleTeamModel } from '../../../db/ComBattleTeam'; import Role, { RoleModel } from '../../../db/Role'; import { STATUS } from '../../../consts/statusCode'; import { Application, BackendSession, BlackListFunction } from 'pinus'; -import { resResult } from '../../../pubUtils/util'; +import { resResult, getRandomByLen, calculateNum } from '../../../pubUtils/util'; import { RoleStatus } from '../../../db/ComBattleTeam'; +import { ItemModel } from '../../../db/Item'; +import { handleReward } from '../../../services/rewardService'; export default function(app: Application) { return new ComBattleHandler(app); @@ -52,9 +54,10 @@ export class ComBattleHandler { if (!goodData || goodData.itid !== IT_TYPE.BLUEPRT) return resResult(STATUS.COM_BATTLE_BLUEPRT_INVALID); // 检查藏宝图是否足够 - let { consumeGoods, lv, headHid, topFiveCe, sHid } = await RoleModel.findByRoleId(roleId); + let { lv, headHid, topFiveCe, sHid } = await RoleModel.findByRoleId(roleId); if (lv < COM_TEAM_ENABLE_LV) return resResult(STATUS.COM_BATTLE_LV_NOT_ENOUGH); - let blueprt = consumeGoods.find(good => good.id === blueprtId && good.count >= 1); + + let blueprt = await ItemModel.findbyRoleAndGidAndCount(roleId, blueprtId, 1); if (!blueprt) return resResult(STATUS.COM_BATTLE_BLUEPRT_NOT_FOUND); // 检查是否有已创建未结束的寻宝,预先占用一张藏宝图 let teams = await ComBattleTeamModel.getTeamByCapAndStatus(roleId, COM_TEAM_STATUS.FIGHTING); @@ -410,4 +413,60 @@ export class ComBattleHandler { // return resResult(STATUS.SUCCESS, { bossHp: this.bossHp}); // } + + + + async composeBlueprt(msg: {original: Array<{id: number, count: number}>}, session: BackendSession) { + const roleId = session.get('roleId'); + const roleName = session.get('roleName'); + const { original } = msg; + + // 原材料检查 + let originalQuality: number, originalSum: number; + for(let {id, count} of original) { + const goodInfo = getGoodById(id); + if(!originalQuality) originalQuality = goodInfo.quality; + if(originalQuality != goodInfo.quality) { + return resResult(STATUS.COM_BLUEPRT_QUALITY_ERROR); + } + + if(goodInfo.itid == IT_TYPE.BLUEPRT) { + originalSum += count; + } + } + + const dicCompose = getBlueprtComposeByQuality(originalQuality); + if(!dicCompose) { + return resResult(STATUS.COM_BLUEPRT_QUALITY_CANNOT_COMPOSE); + } + if(originalSum != dicCompose.blueprtNum) { + return resResult(STATUS.COM_BLUEPRT_COUNT_ERROR); + } + // 检查元宝 + const role = await RoleModel.findByRoleId(roleId); + const costGold = calculateNum(GOLD_COST_RATIO.BLUEPRT_COMPOSE_COST, {num: originalQuality}, 1000); + if(!role || role.gold < costGold) { + return resResult(STATUS.TOWER_GOLD_NOT_ENOUGH); + } + // 添加寻宝币 + original.push({ + id: CURRENCY_BY_TYPE[CURRENCY_TYPE.TREASURE_POINT], + count: dicCompose.coinNum + }); + // 消耗藏宝图和寻宝币 + const rec = await ItemModel.decreaseItems(roleId, original); + if(!rec) { + return resResult(STATUS.BATTLE_CONSUMES_NOT_ENOUGH); + } + // 消耗元宝 + await RoleModel.costGold(roleId, costGold); + + const targetList = getBluePrtByQuality(dicCompose.targetQuality); + const target = getRandomByLen(targetList); + const reward = [{gid: target, count: 1}]; + const goods = await handleReward(roleId, roleName, reward); + + + return resResult(STATUS.SUCCESS, { goods }); + } } diff --git a/game-server/app/servers/connector/handler/entryHandler.ts b/game-server/app/servers/connector/handler/entryHandler.ts index e501fa1ec..5e551c1e2 100644 --- a/game-server/app/servers/connector/handler/entryHandler.ts +++ b/game-server/app/servers/connector/handler/entryHandler.ts @@ -11,6 +11,7 @@ import { startEvent } from '../../../services/eventSercive'; import { EVENT_START_LV } from '../../../consts/consts'; import { getAp } from '../../../services/actionPointService'; import Actor from '../../../pubUtils/actor'; +import { ItemModel } from '../../../db/Item'; export default function (app: Application) { return new EntryHandler(app); @@ -82,6 +83,7 @@ export class EntryHandler { // let users = await self.app.rpc.chat.chatRemote.add.route(session)(role.roleId, self.app.get('serverId'), rid, true); let heros = await HeroModel.findByRole(role.roleId); let equips = await EquipModel.findbyRole(role.roleId); + let items = await ItemModel.findbyRole(role.roleId); for(let hero of heros) { let actor = new Actor(); @@ -91,6 +93,7 @@ export class EntryHandler { role['heros'] = heros; role['equips'] = equips; + role['consumeGoods'] = items; let apJson = await getAp(Date.now(), role.roleId); role['apJson'] = apJson; return resResult(STATUS.SUCCESS, { role }); diff --git a/game-server/app/services/redisService.ts b/game-server/app/services/redisService.ts index 43d3e5882..11cba92e1 100644 --- a/game-server/app/services/redisService.ts +++ b/game-server/app/services/redisService.ts @@ -38,7 +38,7 @@ export async function initRank(serverId: number) { let ranks = await RoleModel.getRank('tower', serverId, ['roleId', 'roleName', 'towerLv', 'lv', 'vLv']); for(let {towerLv, roleId, roleName, lv, vLv, towerUpTime} of ranks) { - console.log(roleId); + // console.log(roleId); await redisZadd(getKeyName(REDIS_KEY.TOWER_RANK, serverId), encodeScoreWithTime(towerLv, towerUpTime?towerUpTime.getTime():0), roleId); await redisUserInfoAdd(roleId, {roleName, lv, vLv, guildName:"", head: "zhaoyun"}); } diff --git a/game-server/app/services/rewardService.ts b/game-server/app/services/rewardService.ts index 74eb12d4b..f0e1ff6d8 100644 --- a/game-server/app/services/rewardService.ts +++ b/game-server/app/services/rewardService.ts @@ -5,6 +5,7 @@ import { decodeStr } from '../pubUtils/util'; import { getGoodById } from '../pubUtils/gamedata'; import { RoleModel } from '../db/Role'; import { setAp } from './actionPointService'; +import { ItemModel } from '../db/Item'; export async function handleFixedReward(roleId: string, roleName: string, rewardStr: string, multi: number) { let reward = decodeStr('fixReward', rewardStr); @@ -15,7 +16,7 @@ export async function handleFixedReward(roleId: string, roleName: string, reward return result; } -export async function handleReward(roleId: string, roleName: string, rewards: Array<{type: number, gid: number, count: number, times: number}>) { +export async function handleReward(roleId: string, roleName: string, rewards: Array<{type?: number, gid: number, count: number, times?: number}>) { let returnGoods = new Array(), getGold = 0, getCoin = 0, getAp = 0; for(let goods of rewards) { @@ -24,11 +25,11 @@ export async function handleReward(roleId: string, roleName: string, rewards: Ar if(goodInfo.goodType == GOOD_TYPE.EQUIP) { // 装备 result = await rewardWeapons(roleId, roleName, goodInfo, {id: goods.gid, cnt: goods.count }); } else if(goodInfo.goodType == GOOD_TYPE.CONSUMES|| goodInfo.goodType == GOOD_TYPE.SCRIPT) { // 消耗品 - let {field, isCurrency} = ITID.get(goodInfo.itid); + let {type, isCurrency} = ITID.get(goodInfo.itid); if(isCurrency) { // 货币 result = await rewardCurrency(roleId, goodInfo, {id: goods.gid, cnt: goods.count }); } else { - result = await rewardItems(roleId, goodInfo, field, {id: goods.gid, cnt: goods.count }); + result = await rewardItems(roleId, roleName, goodInfo, type, {id: goods.gid, cnt: goods.count }); } } @@ -76,20 +77,22 @@ async function rewardWeapons (roleId: string, roleName: string, dicGood: any, w } // 消耗品 -async function rewardItems (roleId: string, dicGood: any, field: string, data: {id:number,cnt:number }) { +async function rewardItems (roleId: string, roleName: string, dicGood: any, type: number, data: {id:number,cnt:number }) { let goods = new Array(); let {id, cnt} = data; - let result = await RoleModel.addItems(roleId, field, id, cnt); + let result = await ItemModel.increaseItem(roleId, id, cnt, {roleId, roleName, itemName: dicGood.name, id, type, hid: dicGood.hid||0}); - goods.push({ - id: id, - name: dicGood.name, - count: cnt, - type: dicGood.goodType, - isCurrency: false - }); + if(result) { + goods.push({ + id: id, + name: dicGood.name, + count: cnt, + type: dicGood.goodType, + isCurrency: false + }); + } return goods; } diff --git a/game-server/app/services/warRewardService.ts b/game-server/app/services/warRewardService.ts index 08308068d..b13357188 100644 --- a/game-server/app/services/warRewardService.ts +++ b/game-server/app/services/warRewardService.ts @@ -4,9 +4,9 @@ */ import { BattleDropModel } from '../db/BattleDrop'; -import { getWarById, getBluePrtByQuality } from '../pubUtils/gamedata'; +import { getWarById, getBluePrtByQuality, getGamedata } from '../pubUtils/gamedata'; import { decodeStr, getRefTime, getRandomWithWeight, getRandomByLen } from '../pubUtils/util'; -import { BATTLE_REWARD_TYPE, BLUEPRT_CONST, BLUEPRT_CHANCE } from '../consts/consts'; +import { BATTLE_REWARD_TYPE, BLUEPRT_CONST } from '../consts/consts'; import { handleReward } from './rewardService'; import { BattleBlueprtDropModel } from '../db/BattleBlueprtDrop' import { RoleModel } from '../db/Role'; @@ -127,7 +127,6 @@ export class WarReward { } private async handlerBlueprtReward(num: number) { - const refTime = getRefTime(new Date(), BLUEPRT_CONST.REFRESH_TIME); const battleBlueprtDrop = await BattleBlueprtDropModel.findByTime(this.roleId, refTime); if(battleBlueprtDrop) { @@ -164,10 +163,12 @@ export class WarReward { private async randomBlueprt() { const { lv } = await RoleModel.findByRoleId(this.roleId); - const result = BLUEPRT_CHANCE.find(cur => {return cur.min <= lv && cur.max >= lv}); + const dicPossibility = getGamedata('dic_blueprt_possibility'); + + const result = dicPossibility.find(cur => {return cur.min <= lv && cur.max >= lv}); if(result) { - const dicOdds = decodeStr('possibility', result.chance); + const dicOdds = decodeStr('possibility', result.possibility); const {dic: {id}} = getRandomWithWeight(dicOdds); const blueprtList = getBluePrtByQuality(id); diff --git a/gm-server/app/service/users.ts b/gm-server/app/service/users.ts index 9716f8744..3acb8d989 100644 --- a/gm-server/app/service/users.ts +++ b/gm-server/app/service/users.ts @@ -22,9 +22,9 @@ import { PvpDefenseModel } from '@db/PvpDefense'; import { Service } from 'egg'; import Counter from '@db/Counter'; import { STATUS } from '@consts/statusCode'; -import { getGoodById } from '@pubUtils/gamedata'; import { ITID, COUNTER } from '@consts/consts'; import Actor from '@pubUtils/actor'; +import { ItemModel } from '@db/Item'; /** * Test Service @@ -160,7 +160,7 @@ export default class GMUsers extends Service { for(let role of roles) { let heroCount = await HeroModel.count({roleId: role.roleId}).lean(); let equipCount = await EquipModel.count({roleId: role.roleId}).lean(); - let itemCount = (role.consumeGoods?role.consumeGoods.length: 0) + (role.souls?role.souls.length:0); + let itemCount = await ItemModel.count({roleId: role.roleId}).lean(); let defense = await PvpDefenseModel.findByRoleId(role.roleId); let {roleId, roleName, serverId, lv, vLv, gold, coin} = role; @@ -276,16 +276,28 @@ export default class GMUsers extends Service { let itemid = parseInt(_itemid); let itemcount = parseInt(_itemcount); if(isNaN(itemid) || isNaN(itemcount)) return ctx.service.utils.resResult(STATUS.WRONG_PARMS); - let dicGoods = getGoodById(itemid); + let dicGoods = ctx.service.utils.getGoodById(itemid); let itidObj = ITID.get(dicGoods.itid); - let flag = 0; - for(let roleId of uids) { - await RoleModel.addItems(roleId, itidObj?itidObj.field||'':'', itemid, itemcount); + let flag = 0, msg = '创建失败'; + if(!dicGoods) { + flag = 1, msg = "未找到道具" + itemid; + } else if(!itidObj){ + flag = 1, msg = "未找到道具" + itemid; + } else { + for(let roleId of uids) { + let role = await RoleModel.findByRoleId(roleId); + if(role) { + let dicItem = ctx.service.utils.getGoodById(itemid); + await ItemModel.increaseItem(roleId, itemid, itemcount, {roleId, roleName:role.roleName, id: itemid, itemName: dicItem.name, type: itidObj.type||0}); + } else { + flag = 1, msg = '未找到角色' + roleId; + } + } } if (flag) { - return ctx.service.utils.resResult(STATUS.GM_CREATE_ERROR); + return ctx.service.utils.resResult(STATUS.GM_CREATE_ERROR, null, msg); } else { return ctx.service.utils.resResult(STATUS.SUCCESS, { uids }); } diff --git a/shared/consts/consts.ts b/shared/consts/consts.ts index 5fe5d5a12..a5e70eb8c 100644 --- a/shared/consts/consts.ts +++ b/shared/consts/consts.ts @@ -32,12 +32,21 @@ export const IT_TYPE = { BLUEPRT: 28 } +// 大类型,区分存到哪张表里 export const GOOD_TYPE = { EQUIP: 1, CONSUMES: 2, SCRIPT: 3 }; +// 存到消耗品表内显示的类型 +export const CONSUME_TYPE = { + CONSUME: 1, // 消耗品 + SOUL: 2, // 将魂 + BLUEPRT: 3, // 藏宝图 + POINT: 4 // 远征币等 +}; + const itid_array = [ { id: 1, name: '剑', goodType: GOOD_TYPE.EQUIP }, { id: 2, name: '枪', goodType: GOOD_TYPE.EQUIP }, @@ -60,20 +69,21 @@ const itid_array = [ { id: 19, name: '战靴', goodType: GOOD_TYPE.EQUIP }, { id: 20, name: '布鞋', goodType: GOOD_TYPE.EQUIP }, { id: 21, name: '饰品', goodType: GOOD_TYPE.EQUIP }, - { id: 22, name: '消耗类物品(图纸类)', goodType: GOOD_TYPE.CONSUMES, field: "consumeGoods" }, - { id: 23, name: '消耗类物品(材料类)', goodType: GOOD_TYPE.CONSUMES, field: "consumeGoods" }, - { id: 24, name: '消耗类物品(宝箱类)', goodType: GOOD_TYPE.CONSUMES, field: "consumeGoods" }, - { id: 26, name: '武将碎片', goodType: GOOD_TYPE.CONSUMES, field: "souls" }, - { id: 27, name: '货币', goodType: GOOD_TYPE.CONSUMES, field: "currency", isCurrency: true }, - { id: 28, name: '藏宝图', goodType: GOOD_TYPE.CONSUMES, field: "consumeGoods" }, + { id: 22, name: '消耗类物品(图纸类)', goodType: GOOD_TYPE.CONSUMES, type: CONSUME_TYPE.CONSUME }, + { id: 23, name: '消耗类物品(材料类)', goodType: GOOD_TYPE.CONSUMES, type: CONSUME_TYPE.CONSUME }, + { id: 24, name: '消耗类物品(宝箱类)', goodType: GOOD_TYPE.CONSUMES, type: CONSUME_TYPE.CONSUME }, + { id: 26, name: '武将碎片', goodType: GOOD_TYPE.CONSUMES, type: CONSUME_TYPE.SOUL }, + { id: 27, name: '货币', goodType: GOOD_TYPE.CONSUMES, isCurrency: true }, + { id: 28, name: '藏宝图', goodType: GOOD_TYPE.CONSUMES, type: CONSUME_TYPE.BLUEPRT }, { id: 29, name: '礼器', goodType: GOOD_TYPE.EQUIP }, { id: 30, name: '宝甲', goodType: GOOD_TYPE.EQUIP }, { id: 31, name: '名驹', goodType: GOOD_TYPE.EQUIP }, { id: 32, name: '典籍', goodType: GOOD_TYPE.EQUIP }, - { id: 33, name: '神兵', goodType: GOOD_TYPE.EQUIP } + { id: 33, name: '神兵', goodType: GOOD_TYPE.EQUIP }, + { id: 34, name: '代币', goodType: GOOD_TYPE.CONSUMES, type: CONSUME_TYPE.POINT } ]; -export const ITID = new Map(); +export const ITID = new Map(); for(let obj of itid_array) { ITID.set(obj.id, obj); } @@ -81,17 +91,25 @@ for(let obj of itid_array) { export const CURRENCY_TYPE = { GOLD: "gold", COIN: "coin", - ACTION_POINT: "ap" + ACTION_POINT: "ap", + TREASURE_POINT: "treasurePoint", + EXPEDITION_POINT: "expeditionPoint", + DUNGEON_POINT: "dungeonPoint" } const currencyArr = [ { "gid": 31001, "name": "铜钱", "type": CURRENCY_TYPE.COIN }, { "gid": 31002, "name": "元宝", "type": CURRENCY_TYPE.GOLD }, { "gid": 31003, "name": "体力", "type": CURRENCY_TYPE.ACTION_POINT }, + { "gid": 40001, "name": "远征币", "type": CURRENCY_TYPE.EXPEDITION_POINT }, + { "gid": 40002, "name": "寻宝币", "type": CURRENCY_TYPE.TREASURE_POINT }, + { "gid": 40003, "name": "秘境币", "type": CURRENCY_TYPE.DUNGEON_POINT }, ]; export const CURRENCY = new Map(); +export const CURRENCY_BY_TYPE = new Map(); for(let obj of currencyArr) { CURRENCY.set(obj.gid, obj); + CURRENCY_BY_TYPE.set(obj.type, obj.gid); } export const WAR_TYPE = { @@ -117,14 +135,6 @@ export const BLUEPRT_CONST = { PER_AP: 15 // 每多少体力掉落1张藏宝图 }; -// 藏宝图概率 -export const BLUEPRT_CHANCE = [ - {min: 20, max: 40, chance: "1&100"}, - {min: 41, max: 60, chance: "1&70|2&30"}, - {min: 61, max: 80, chance: "2&70|3&30"}, - {min: 81, max: 100, chance: "2&60|3&40"} -]; - // 事件,是否开启保存随机记录方式 export const EVENT_RANDOM_TYPE_ONE_OPEN = false; // 奇遇事件每次刷新几个 @@ -243,7 +253,8 @@ export const GOLD_COST_RATIO = { "TOWER_HANG_SPDUP": { "A": 0, "B": 50 }, // 天梯挂机加速花费 "TOWER_TASK_REF": { "A": 0, "B": 50 }, // 天梯派遣刷新花费 "DAILY_REF_NUM": { "A": 50, "B": 0 }, // 每日购买次数花费 - "DUNGRON_BUY_NUM": { "A": 0, "B": 50 } // 秘境购买次数花费 + "DUNGRON_BUY_NUM": { "A": 0, "B": 50 }, // 秘境购买次数花费 + "BLUEPRT_COMPOSE_COST": { "A": 0, "B": 1000 } // 寻宝合成花费 } export const EXPRESSION = { diff --git a/shared/consts/statusCode.ts b/shared/consts/statusCode.ts index 423b60904..9e3a0def8 100644 --- a/shared/consts/statusCode.ts +++ b/shared/consts/statusCode.ts @@ -21,6 +21,7 @@ export const STATUS = { BATTLE_ID_NOT_MATCH: { code: 20004, simStr: '战斗数据错误' }, BATTLE_STATUS_WRONG: { code: 20005, simStr: '关卡状态错误' }, BATTLE_HERO_NOT_FOUND: { code: 20006, simStr: '使用的武将不存在' }, + BATTLE_CONSUMES_NOT_ENOUGH: { code: 20007, simStr: '道具不足' }, // 主线 20100 - 20199 BATTLE_INFO_VALIDATE_ERR: { code: 20101, simStr: '关卡信息不同' }, @@ -96,6 +97,11 @@ export const STATUS = { COM_BATTLE_DISSMISS_ERR: { code: 20623, simStr: '解散队伍异常' }, COM_BATTLE_NO_RECENT_REC: { code: 20624, simStr: '没有最近的寻宝记录' }, + // 共斗藏宝图合成 + COM_BLUEPRT_QUALITY_CANNOT_COMPOSE: { code: 20630, simStr: '该品质藏宝图不可合成' }, + COM_BLUEPRT_COUNT_ERROR: { code: 20631, simStr: '材料数量不足' }, + COM_BLUEPRT_QUALITY_ERROR: { code: 20632, simStr: '品质错误' }, + // 秘境 20700 - 20799 DUNGEON_REFRESH_TIMES_LACK: { code: 20701, simStr: '购买次数不足' }, DUNGEON_TIMES_LACK: { code: 20701, simStr: '挑战次数不足' }, diff --git a/shared/db/HeroSoul.ts b/shared/db/HeroSoul.ts deleted file mode 100644 index 96b18d690..000000000 --- a/shared/db/HeroSoul.ts +++ /dev/null @@ -1,55 +0,0 @@ -import BaseModel from './BaseModel'; -import { index, getModelForClass, prop } from '@typegoose/typegoose'; - - -@index({ roleId: 1, hid: 1 }) -@index({ seqId: 1 }) -export default class HeroSoul extends BaseModel { - @prop({ required: true }) - roleId: string; // 角色 id - @prop({ required: true }) - roleName: string; // 角色名称 - - @prop({ required: true }) - soulid: number; // 道具 id - @prop({ required: true }) - soulName: string; // 道具名称 - @prop({ required: true }) - hid: number; // 武将 id - @prop({ required: true }) - hName: string; // 武将名称 - @prop({ required: true }) - seqId: number; // 将魂表自增 id - @prop({ required: true, default: 0 }) - count: number; // 道具数量 - - - public static async findbyRole(roleId: string, lean = true) { - const items = await HeroSoulModel.find({ roleId }).lean(lean); - return items; - } - - public static async findbyItemid(itemid: number, roleId: string, lean = true) { - const equips = await HeroSoulModel.findOne({ itemid, roleId }).lean(lean); - return equips; - } - - public static async changeItemCount(seqId: number, count: number, lean = true) { - const equips = await HeroSoulModel.findOneAndUpdate({ seqId }, {$inc:{count}}).lean(lean); - return equips; - } - - public static async createItem(itemInfo: {roleId: string, roleName: string, soulid: number, seqId: number, soulName: string, count: number, hid: number, hName: string}, lean = true) { - const doc = new HeroSoulModel(); - const update = Object.assign(doc.toJSON(), itemInfo); - const item = await HeroSoulModel.findOneAndUpdate({ seqId: itemInfo.seqId }, update, {upsert: true, new: true}).lean(lean); - return item; - } - - public static async deleteAccount(roleId: string, lean = true) { - let result = await HeroSoulModel.deleteMany({roleId}).lean(lean); - return result||{}; - } -} - -export const HeroSoulModel = getModelForClass(HeroSoul); diff --git a/shared/db/Item.ts b/shared/db/Item.ts index 94c359a68..2362db7f2 100644 --- a/shared/db/Item.ts +++ b/shared/db/Item.ts @@ -1,47 +1,59 @@ import BaseModel from './BaseModel'; import { index, getModelForClass, prop } from '@typegoose/typegoose'; - -@index({ roleId: 1, itemid: 1 }) +@index({ roleId: 1, id: 1 }) @index({ seqId: 1 }) export default class Item extends BaseModel { - @prop({ required: true }) + @prop({ required: true, default: '' }) roleId: string; // 角色 id - @prop({ required: true }) + @prop({ required: true, default: '' }) roleName: string; // 角色名称 - @prop({ required: true }) - itemid: number; // 道具 id - @prop({ required: true }) - type: number; // 装备类型 - @prop({ required: true }) - itemName: string; // 道具名称 - @prop({ required: true }) - seqId: number; // 道具表自增 id + @prop({ required: true, default: '' }) + id: number; // 道具 id + @prop({ required: true, default: '' }) + type: number; // 道具类型 + @prop({ required: true, default: '' }) + itemName: string; // 道具名称 @prop({ required: true, default: 0 }) - count: number; // 道具数量 + hid: number; // 将魂:武将id,其他:0 + @prop({ required: true }) + count: number; // 道具数量 public static async findbyRole(roleId: string, lean = true) { - const items = await ItemModel.find({ roleId }).lean(lean); + const items = await ItemModel.find({ roleId }).select('id count type').lean(lean); return items; } - public static async findbyItemid(itemid: number, roleId: string, lean = true) { - const equips = await ItemModel.findOne({ itemid, roleId }).lean(lean); - return equips; + public static async findbyRoleAndGidAndCount(roleId: string, id: number, count: number, lean = true) { + const items = await ItemModel.findOne({ roleId, id, $gte: {count} }).select('id count type').lean(lean); + return items; } - public static async changeItemCount(seqId: number, count: number, lean = true) { - const equips = await ItemModel.findOneAndUpdate({ seqId }, {$inc:{count}}, {upsert: true, new: true}).lean(lean); - return equips; - } - - public static async createItem(itemInfo: {roleId: string, roleName: string, itemid: number, seqId: number, itemName: string, count: number, type: number}, lean = true) { + public static async increaseItem(roleId: string, id: number, count: number, itemInfo: {roleId: string, roleName: string, id: number, itemName: string, type: number, hid?: number }, lean = true) { const doc = new ItemModel(); - const update = Object.assign(doc.toJSON(), itemInfo); - const item = await ItemModel.findOneAndUpdate({ seqId: itemInfo.seqId }, update, {upsert: true, new: true}).lean(lean); - return item; + const setOnInsert = Object.assign(doc.toJSON(), itemInfo); + const equips = await ItemModel.findOneAndUpdate({roleId, id },{$setOnInsert: setOnInsert, $inc: { count }}, {new: true, upsert: true}).lean(lean); + return equips; + } + + public static async decreaseItems(roleId: string, items: Array<{id: number, count: number}>, lean = true) { + let wrongItems = new Array<{id: number, count: number}>(); + for(let {id, count} of items) { + const rec = await ItemModel.findOneAndUpdate({roleId, id, count: {$gte: count} },{ $inc: { count: -1 * count }}, {new: true}).lean(lean); + if(!rec) { + wrongItems.push({id, count}); break; + } + } + if(wrongItems.length > 0) { // 数量不足 + for(let {id, count} of wrongItems) { + await ItemModel.findOneAndUpdate({roleId, id },{ $inc: { count }}, {new: true}).lean(lean); + } + return false + } else { + return true + } } public static async deleteAccount(roleId: string, lean = true) { diff --git a/shared/db/Role.ts b/shared/db/Role.ts index f98426ec6..3192825cf 100644 --- a/shared/db/Role.ts +++ b/shared/db/Role.ts @@ -89,11 +89,6 @@ export default class Role extends BaseModel { @prop({ required: true, default: 0 }) frdCnt: number; // 情谊点 - @prop({ required: true, default: [] }) - consumeGoods: [{ // 消耗品 - id: number; // id - count: number; // 数量 - }]; @prop({ required: true, default: [] }) souls: [{ // 将魂 id: number; // 武将 id @@ -233,32 +228,7 @@ export default class Role extends BaseModel { let result = await RoleModel.deleteMany({roleId}).lean(lean); return result||{}; } - - - public static async addItems(roleId: string, field: string, id: number, cnt: number, lean = true) { - try { - let role = await RoleModel.findOne({roleId}).lean(lean); - let item = role?role[field]:[]; - let curItem = item.find(cur => cur.id == id); - if(!curItem) { - let addToSet = {}; - addToSet[field] = {id, count: cnt}; - let result = await RoleModel.findOneAndUpdate({roleId}, { $addToSet: addToSet }, { "new": true, "upsert": true}).lean(lean); - return result; - } else { - let condition = { roleId }; - condition[`${field}.id`] = id; - let update = {}; - update[`${field}.$.count`] = cnt; - - let result = await RoleModel.findOneAndUpdate(condition, { $inc: update }, { "new": true, "upsert": true}).lean(lean); - return result; - } - }catch(e) { - console.error(e) - } - } - + public static async addCoin(roleId: string, cnt: number, lean = true) { let result = await RoleModel.findOneAndUpdate({roleId}, { $inc: {coin: cnt} }, { "new": true, "upsert": true}).lean(lean); return result; diff --git a/shared/db/ScriptItem.ts b/shared/db/ScriptItem.ts deleted file mode 100644 index 1bd8c9d1c..000000000 --- a/shared/db/ScriptItem.ts +++ /dev/null @@ -1,54 +0,0 @@ -import BaseModel from './BaseModel'; -import { index, getModelForClass, prop } from '@typegoose/typegoose'; - - -@index({ roleId: 1, itemid: 1 }) -@index({ seqId: 1 }) -export default class ScriptItem extends BaseModel { - @prop({ required: true }) - roleId: string; // 角色 id - @prop({ required: true }) - roleName: string; // 角色名称 - - @prop({ required: true }) - itemid: number; // 道具 id - @prop({ required: true }) - type: number; // 装备类型 - @prop({ required: true }) - itemName: string; // 道具名称 - @prop({ required: true }) - seqId: number; // 道具表自增 id - @prop({ required: true, default: 0 }) - count: number; // 道具数量 - - - public static async findbyRole(roleId: string, lean = true) { - const items = await ScriptItemModel.find({ roleId }).lean(lean); - return items; - } - - public static async findbyItemid(itemid: number, roleId: string, lean = true) { - const equips = await ScriptItemModel.findOne({ itemid, roleId }).lean(lean); - return equips; - } - - public static async changeItemCount(seqId: number, count: number, lean = true) { - const equips = await ScriptItemModel.findOneAndUpdate({ seqId }, {$inc:{count}}, {upsert: true, new: true}).lean(lean); - return equips; - } - - public static async createItem(itemInfo: {roleId: string, roleName: string, itemid: number, seqId: number, itemName: string, count: number, type: number}, lean = true) { - const doc = new ScriptItemModel(); - const update = Object.assign(doc.toJSON(), itemInfo); - const item = await ScriptItemModel.findOneAndUpdate({ seqId: itemInfo.seqId }, update, {upsert: true, new: true}).lean(lean); - return item; - } - - public static async deleteAccount(roleId: string, lean = true) { - let result = await ScriptItemModel.deleteMany({roleId}).lean(lean); - return result||{}; - } - -} - -export const ScriptItemModel = getModelForClass(ScriptItem); diff --git a/shared/pubUtils/gamedata.ts b/shared/pubUtils/gamedata.ts index bea00b41d..eef54b921 100644 --- a/shared/pubUtils/gamedata.ts +++ b/shared/pubUtils/gamedata.ts @@ -22,6 +22,7 @@ const btlBossHp = new Map(); const blueprtBossHp = new Map(); const goodInfo = new Map(); const blueprt = new Map>(); +const blueprtCompose = new Map(); function parseWarData() { let result = null; @@ -208,6 +209,16 @@ function parseGood() { }); } +function parseBlueprtCompose() { + const file = 'dic_blueprt_compose'; + const data = gamedata['jsons'][file] || []; + data.forEach(elem => { + if (elem && elem.quality) { + blueprtCompose.set(elem.quality, elem); + } + }); +} + function initData (folder: string) { if(!gamedata.hasOwnProperty(folder)) { gamedata[folder] = {}; @@ -246,6 +257,7 @@ function parseData() { parseExpedition(); parseComBtlData(); parseGood(); + parseBlueprtCompose(); } initData('jsons'); // 加载一般json @@ -372,4 +384,8 @@ export function getBossHpByBlueprtId(blueprtId: number) { } export function hasExpeditionById(id: number) { return expeditionInfo.has(id); +} + +export function getBlueprtComposeByQuality(quality: number) { + return blueprtCompose.get(quality); } \ No newline at end of file diff --git a/shared/pubUtils/util.ts b/shared/pubUtils/util.ts index a6dcbf968..b5e0657b4 100644 --- a/shared/pubUtils/util.ts +++ b/shared/pubUtils/util.ts @@ -169,7 +169,8 @@ export function decodeIdCntArrayStr(str: string, multi: number) { return ce; } - export function getRandomByLen(arr: Array) { + export function getRandomByLen(arr: Array):number + export function getRandomByLen(arr: Array): any { let len = arr.length; return arr[Math.floor(Math.random() * len)] } diff --git a/shared/resource/jsons/dic_blueprt_compose.json b/shared/resource/jsons/dic_blueprt_compose.json new file mode 100644 index 000000000..32dff20e8 --- /dev/null +++ b/shared/resource/jsons/dic_blueprt_compose.json @@ -0,0 +1,26 @@ +[ + { + "quality": 1, + "coinNum": 10, + "blueprtNum": 3, + "targetQuality": 2 + }, + { + "quality": 2, + "coinNum": 20, + "blueprtNum": 3, + "targetQuality": 3 + }, + { + "quality": 3, + "coinNum": 30, + "blueprtNum": 3, + "targetQuality": 4 + }, + { + "quality": 4, + "coinNum": 40, + "blueprtNum": 3, + "targetQuality": 5 + } +] \ No newline at end of file diff --git a/shared/resource/jsons/dic_blueprt_possibility.json b/shared/resource/jsons/dic_blueprt_possibility.json new file mode 100644 index 000000000..e23cadd6e --- /dev/null +++ b/shared/resource/jsons/dic_blueprt_possibility.json @@ -0,0 +1,22 @@ +[ + { + "min": 20, + "max": 39, + "possibility": "1&100" + }, + { + "min": 40, + "max": 69, + "possibility": "1&70|2&30" + }, + { + "min": 60, + "max": 79, + "possibility": "2&70|3&30" + }, + { + "min": 80, + "max": 100, + "possibility": "2&60|3&40" + } +] \ No newline at end of file diff --git a/shared/resource/jsons/dic_goods.json b/shared/resource/jsons/dic_goods.json index 8ed04d4c7..bd2b8f342 100644 --- a/shared/resource/jsons/dic_goods.json +++ b/shared/resource/jsons/dic_goods.json @@ -23152,5 +23152,39 @@ "specialAttr": 0, "__EMPTY": 0, "__EMPTY_1": 0 + }, + { + "good_id": 40002, + "name": "寻宝币", + "lvLimted": 1, + "quality": 1, + "image_id": 0, + "itid": 34, + "goodType": 2, + "hid": 0, + "hp": 0, + "atk": 0, + "matk": 0, + "def": 0, + "mdef": 0, + "agi": 0, + "luk": 0, + "hp_up": 0, + "atk_up": 0, + "matk_up": 0, + "def_up": 0, + "mdef_up": 0, + "agi_up": 0, + "luk_up": 0, + "hp_up2": 0, + "atk_up2": 0, + "matk_up2": 0, + "def_up2": 0, + "mdef_up2": 0, + "agi_up2": 0, + "luk_up2": 0, + "specialAttr": 0, + "__EMPTY": 0, + "__EMPTY_1": 0 } ] \ No newline at end of file