diff --git a/game-server/app/servers/role/handler/equipHandler.ts b/game-server/app/servers/role/handler/equipHandler.ts index b9e722390..6d3651249 100644 --- a/game-server/app/servers/role/handler/equipHandler.ts +++ b/game-server/app/servers/role/handler/equipHandler.ts @@ -8,12 +8,12 @@ import { EquipModel, EquipType } from "../../../db/Equip"; import { HeroModel, EPlace, HeroType } from "../../../db/Hero"; import Role from "../../../db/Role"; import { calPlayerCeAndSave } from "../../../services/playerCeService"; -import { getGoodById, gameData } from "../../../pubUtils/data"; +import { getGoodById, gameData, getEquipByJobClassAndEPlace } from "../../../pubUtils/data"; import { BAG, EQUIP } from "../../../pubUtils/dicParam"; import { ITID, QUALITY_TYPE, equipTypeToSortAttr, IT_TYPE, QUENCH_TYPE, REFINE_TYPE } from "../../../consts"; import { checkMaterialEnough, checkEquipCanPut, quenchOnce, checkQuenchMaxByQualityAndGrade, getRandSeResult, refineOnce, checkRefineReachNextLv, calEquipCe } from "../../../services/equipService"; -import { findIndex, pick } from 'underscore'; +import { findIndex, isNumber, pick } from 'underscore'; import { pushEquipRefineSucMsg, pushNormalEquipMsg, pushNormalItemMsg } from "../../../services/chatService"; import { checkTaskWithHero, checkTaskWithEquip, checkTask, checkTaskWithArgs, checkActivityTask } from "../../../services/taskService"; import { QuenchLogParam } from "../../../domain/roleField/equip"; @@ -29,72 +29,38 @@ export class EquipHandler { constructor(private app: Application) { } + public async composeEquip(msg: { hid: number, eplaceId: number }, session: BackendSession) { + let roleId: string = session.get('roleId'); + let sid: string = session.get('sid'); + let { hid, eplaceId } = msg; + if(!isNumber(eplaceId) || eplaceId > 4 || eplaceId < 1) return resResult(STATUS.WRONG_PARMS); - // // test接口添加任意道具 - // public async addItem(msg: { id: number, count: number }, session: BackendSession) { - // let roleId: string = session.get('roleId'); - // let roleName: string = session.get('roleName'); - // let sid: string = session.get('sid'); - // let { id, count } = msg; - // let goods = await addItems(roleId, roleName, sid, [{ id, count }], ITEM_CHANGE_REASON.DEBUG); - // return resResult(STATUS.SUCCESS, { goods }); - // } + let hero = await HeroModel.findByHidAndRole(hid, roleId); + if(!hero) return resResult(STATUS.HERO_NOT_FIND); - // // 合成装备 - // public async composeEquip(msg: { gid: number, originalEquip: number[] }, session: BackendSession) { - // let roleId: string = session.get('roleId'); - // let roleName: string = session.get('roleName'); - // let sid: string = session.get('sid'); - // const serverId: number = session.get('serverId'); - // // 消耗材料 - // // 获得装备 - // let { gid, originalEquip } = msg; + let curEquip = hero.ePlace?.find(equip => equip.id == eplaceId ); + if(curEquip) return resResult(STATUS.EQUIP_HAS_COMPOSE); + let dicHero = gameData.hero.get(hid); + let dicEquip = getEquipByJobClassAndEPlace(dicHero?.jobClass, eplaceId); + if(!dicEquip) return resResult(STATUS.DIC_DATA_NOT_FOUND); - // let targetGood = gameData.goods.get(gid); - // if (!targetGood) return resResult(STATUS.DIC_DATA_NOT_FOUND); + let consumeResult = await handleCost(roleId, sid, dicEquip.composeMaterial, ITEM_CHANGE_REASON.EQUIP_COMPOSE); + if(!consumeResult) return resResult(STATUS.BATTLE_CONSUMES_NOT_ENOUGH); - // let cost: ItemInter[] = []; - // let jewels: ItemInter[] = []; // 需要返还的镶嵌在装备上的宝石 - // if (targetGood.suitId > 0) { // 套装 - // cost = cost.concat(targetGood.composeMaterial); - // let specialMaterial = targetGood.specialMaterial; - // let costCount = 0; - // let equips = await EquipModel.getEquips(roleId, originalEquip); - // for (let equip of equips) { - // let { id, seqId, holes } = equip; - // if (specialMaterial.ids.includes(id)) { - // costCount++; - // cost.push({ id, seqId, count: 1 }); - // for (let { jewel } of holes) { - // if (jewel > 0) jewels.push({ id: jewel, count: 1 }); - // } - // } - // } - // if (specialMaterial.count > costCount) { - // return resResult(STATUS.ROLE_MATERIAL_NOT_ENOUGH); - // } + let newEquip = new EPlace(eplaceId, dicEquip.id); + let newEplace = hero.ePlace? [...hero.ePlace, newEquip]: [newEquip]; - // } else { // 普通装备 - // cost.push({ - // id: targetGood.pieceId, - // count: targetGood.pieces - // }); - // } - // let result = await handleCost(roleId, sid, cost, ITEM_CHANGE_REASON.EQUIP_COMPOSE); - // if (!result) return resResult(STATUS.ROLE_MATERIAL_NOT_ENOUGH); + hero = await calPlayerCeAndSave(HERO_SYSTEM_TYPE.COMPOSE_EQUIP, sid, roleId, hero, { ePlace: newEplace }, [eplaceId]); - // await addItems(roleId, roleName, sid, jewels, ITEM_CHANGE_REASON.EQUIP_DEL_RETURN_JEWEL); // 宝石返还 - // let items = [{ id: gid, count: 1 }]; - // let goods = await addItems(roleId, roleName, sid, items, ITEM_CHANGE_REASON.EQUIP_COMPOSE); - // if (targetGood.suitId) { - // pushNormalEquipMsg(roleId, roleName, serverId, MSG_SOURCE.EQUIP_COMPOSE_SUIT, gid, targetGood.name, targetGood.quality); - // } - // if (targetGood.quality >= QUALITY_TYPE.ORANGE) { - // pushNormalEquipMsg(roleId, roleName, serverId, MSG_SOURCE.EQUIP_COMPOSE_ORANGE, gid, targetGood.name, targetGood.quality); - // } - // return resResult(STATUS.SUCCESS, { goods }); - // } + return resResult(STATUS.SUCCESS, { + curHero: { + hid: hero.hid, + ePlace: [newEquip] + } + }) + } + // // 装备栏强化 // public async strengthen(msg: { hid: number, ePlaceId: number, type: number }, session: BackendSession) { diff --git a/game-server/app/servers/role/handler/heroHandler.ts b/game-server/app/servers/role/handler/heroHandler.ts index 641b44da2..6f56fd79d 100644 --- a/game-server/app/servers/role/handler/heroHandler.ts +++ b/game-server/app/servers/role/handler/heroHandler.ts @@ -567,7 +567,7 @@ export class HeroHandler { let dicSkin = gameData.fashion.get(id); // console.log('*****', id, dicSkin) if (!dicSkin) return resResult(STATUS.HERO_SKIN_NOT_FIND); - let hero = await HeroModel.findByHidAndRoleWithEquip(dicSkin.actorId, roleId); + let hero = await HeroModel.findByHidAndRole(dicSkin.actorId, roleId); if (!hero) return resResult(STATUS.HERO_NOT_FIND); let newHeroSkins: HeroSkin[] = []; diff --git a/game-server/app/servers/role/handler/mailHandler.ts b/game-server/app/servers/role/handler/mailHandler.ts index 8152c6bd2..5fc5e49a8 100644 --- a/game-server/app/servers/role/handler/mailHandler.ts +++ b/game-server/app/servers/role/handler/mailHandler.ts @@ -110,7 +110,7 @@ export class MailHandler { let sid: string = session.get('sid'); let serverId: number = session.get('serverId'); let { id, type, mailType } = msg; - let { equipCount } = await RoleModel.findByRoleId(roleId, 'equipCount'); + let { jewelCount } = await RoleModel.findByRoleId(roleId, 'jewelCount'); let originMails: {mailType: GM_MAIL_TYPE, mail: MailType|GroupMailType|ServerMailType}[] = [] @@ -156,7 +156,7 @@ export class MailHandler { let mailGoods: ItemInter[] = [], mails: MailParam[] = []; for(let { mail, mailType } of originMails) { - let { isEquipOver, equipCount: newEquipCount } = checkMailGoods(mail, equipCount); + let { isEquipOver, jewelCount: newEquipCount } = checkMailGoods(mail, jewelCount); if(isEquipOver) { if(type == RECEIVE_MAIL_TYPE.SINGLE) { return resResult(STATUS.EQUIP_IS_OVER); @@ -164,7 +164,7 @@ export class MailHandler { continue; // 如果有装备数量超过,那么一键领取这条邮件就不领了 } } - equipCount = newEquipCount; + jewelCount = newEquipCount; if(mailType == GM_MAIL_TYPE.SINGLE) { mail = await MailModel.updateStatusWithCondition(mail._id, MAIL_STATUS.RECEIVED); diff --git a/game-server/app/services/equipService.ts b/game-server/app/services/equipService.ts index 821408a46..a04d5f81b 100644 --- a/game-server/app/services/equipService.ts +++ b/game-server/app/services/equipService.ts @@ -1,7 +1,7 @@ import { mergeSameGoods, getRandEelm, getRandValueByMinMax } from '../pubUtils/util'; import { EquipModel, RandMain, RandSe } from "../db/Equip"; import { HeroModel, HeroType } from "../db/Hero"; -import { getGoodById, gameData, getJewelById, getQuenchGradeByValue, getQuenchConsume, getQuenchByQualityAndGrade } from "../pubUtils/data"; +import { getGoodById, gameData, getQuenchGradeByValue, getQuenchConsume, getQuenchByQualityAndGrade } from "../pubUtils/data"; import { calPlayerCeAndSave } from "./playerCeService"; import { CONSUME_TYPE, HERO_SYSTEM_TYPE, ITID, TASK_TYPE } from "../consts"; import { dicGoods, DicGoods } from '../pubUtils/dictionary/DicGoods'; diff --git a/game-server/app/services/mailService.ts b/game-server/app/services/mailService.ts index 9f3f4a243..520078a4a 100644 --- a/game-server/app/services/mailService.ts +++ b/game-server/app/services/mailService.ts @@ -244,13 +244,13 @@ export class SendMailFun { } } -export function checkMailGoods(mail: MailType | GroupMailType | ServerMailType, equipCount: number) { +export function checkMailGoods(mail: MailType | GroupMailType | ServerMailType, jewelCount: number) { let isEquipOver = false; for (let good of mail.goods) { let dicGoods = gameData.goods.get(good.id); let dicItid = ITID.get(dicGoods.itid); - if (dicItid.table == 'equip') { // 装备 - if (++equipCount > BAG.BAG_EQUIP_UPLIMITED) { + if (dicItid.table == 'jewel') { // 装备 + if (++jewelCount > BAG.BAG_EQUIP_UPLIMITED) { isEquipOver = true; break; } @@ -258,6 +258,6 @@ export function checkMailGoods(mail: MailType | GroupMailType | ServerMailType, } return { - isEquipOver, equipCount + isEquipOver, jewelCount } } \ No newline at end of file diff --git a/game-server/app/services/rewardService.ts b/game-server/app/services/rewardService.ts index 83d5baa72..c953d482c 100644 --- a/game-server/app/services/rewardService.ts +++ b/game-server/app/services/rewardService.ts @@ -7,7 +7,7 @@ import { pushCalPlayerCe, pushCalAllHeroCe, calPlayerCeAndSave } from './playerC import { ItemModel, ItemType } from '../db/Item'; import { STATUS } from '../consts/statusCode'; import { pinus } from 'pinus'; -import { addEquips, addBags, addSkin, addFigure, unlockFigure as pubUnlockFigure, transPiece, getGoldObject, getCoinObject, getApObject } from '../pubUtils/itemUtils'; +import { addJewels, addBags, addSkin, addFigure, unlockFigure as pubUnlockFigure, transPiece, getGoldObject, getCoinObject, getApObject } from '../pubUtils/itemUtils'; import { ItemInter, RewardInter, } from '../pubUtils/interface'; import { gameData } from '../pubUtils/data'; import { uniq } from 'underscore'; @@ -27,6 +27,7 @@ import { getInitHeroById } from './roleService'; import { getActivities } from './activity/activityService'; import { reportTAEvent, reportTAUserSet } from './sdkService'; import { saveCoinChangeLog, saveFigureInfoLog, saveGoldChangeLog, saveItemChangeLog } from '../pubUtils/logUtil'; +import { JewelModel, JewelType } from '../db/Jewel'; export class CheckMeterial { private roleId: string; @@ -98,9 +99,9 @@ export class CheckMeterial { export async function handleCost(roleId: string, sid: string, goods: Array, reason: ITEM_CHANGE_REASON) { let uids = [{ uid: roleId, sid }]; - let { items, equips, gold, coin } = sortItems(goods, HANDLE_REWARD_TYPE.COST); - let equipSeqIds = equips.map(cur => cur.seqId); - let resEquips: EquipType[] = []; + let { items, jewels, gold, coin } = sortItems(goods, HANDLE_REWARD_TYPE.COST); + let jewelSeqIds = jewels.map(cur => cur.seqId); + let resJewels: JewelType[] = []; // 检查货币是否充足 let role = await RoleModel.findByRoleId(roleId); @@ -111,9 +112,9 @@ export async function handleCost(roleId: string, sid: string, goods: Array 0) { - resEquips = await EquipModel.getEquips(roleId, equipSeqIds); - if (resEquips.length < equips.length) + if (jewels.length > 0) { + resJewels = await JewelModel.findbySeqIds(jewelSeqIds); + if (resJewels.length < jewels.length) return false; } //检查并修改道具 @@ -125,33 +126,31 @@ export async function handleCost(roleId: string, sid: string, goods: Array 0) { - // let heroMap = new Map(); - // for(let equip of resEquips) { - // if(equip.hid > 0) { - // if(!heroMap.has(equip.hid)) { - // let hero = await HeroModel.findByHidAndRoleWithEquip(equip.hid, roleId); - // heroMap.set(equip.hid, { hero, equips: [] }); - // } - // heroMap.get(equip.hid).equips.push(equip); - // } - // } - // for(let [_hid, {hero, equips} ] of heroMap) { - // let oldCount = hero.ePlace.filter(cur => cur.equip).length; - // let args = calEquipSeids(hero); - // for(let equip of equips) { - // hero = await HeroModel.removeEquip(roleId, hero.hid, equip.ePlaceId, equip._id); - // } + if (resJewels.length > 0) { + let heroMap = new Map(); + for(let jewel of resJewels) { + if(jewel.hid > 0) { + if(!heroMap.has(jewel.hid)) { + let hero = await HeroModel.findByHidAndRole(jewel.hid, roleId); + heroMap.set(jewel.hid, { hero, jewels: [] }); + } + heroMap.get(jewel.hid).jewels.push(jewel); + } + } + for(let [_hid, {hero, jewels} ] of heroMap) { + // TODO 脱下天晶石 + // for(let equip of jewels) { + // hero = await HeroModel.putOffJewel(roleId, hero.hid, equip.ePlaceId, equip._id); + // } - // await calPlayerCeAndSave(HERO_SYSTEM_TYPE.EQUIP, sid, roleId, hero, {}, args); - // await checkTaskWithHero(roleId, sid, TASK_TYPE.EQUIP_BY_HERO, hero, [-1, oldCount]); - // } + // await calPlayerCeAndSave(HERO_SYSTEM_TYPE.EQUIP, sid, roleId, hero, {}, args); + } - // let equips = await EquipModel.deleteEquips(roleId, equipSeqIds); - // saveItemChangeLog(roleId, equips.map(equip => ({ id: equip.id, count: equip.count, inc: -1 })), reason); - // pinus.app.get('channelService').pushMessageByUids('onEquipDel', resResult(STATUS.SUCCESS, { equipInfos: equips.map(equip => ({ seqId: equip.seqId, id: equip.id, inc: -1, reason })) }), uids); - // } + let jewels = await JewelModel.deleteBySeqIds(roleId, jewelSeqIds); + saveItemChangeLog(roleId, jewels.map(jewel => ({ id: jewel.id, count: 1, inc: -1 })), reason); + pinus.app.get('channelService').pushMessageByUids('onJewelDel', resResult(STATUS.SUCCESS, { jewels: jewels.map(jewel => ({ seqId: jewel.seqId, id: jewel.id, inc: -1, reason })) }), uids); + } //消耗玩家货币 if (gold.length > 0 || coin.length > 0) { @@ -181,41 +180,39 @@ export async function handleCost(roleId: string, sid: string, goods: Array, reason: ITEM_CHANGE_REASON) { let uids = [{ uid: roleId, sid }]; - let { items, equips, gold, coin, ap, skins, figures } = sortItems(goods, HANDLE_REWARD_TYPE.RECEIVE); + let { items, jewels, gold, coin, ap, skins, figures } = sortItems(goods, HANDLE_REWARD_TYPE.RECEIVE); let showItems: { id: number, seqId?: number, count: number, isBag?: boolean }[] = []; let role = await RoleModel.findByRoleId(roleId); // 1. 装备处理 - if(equips.length > 0) { - let { equipCount = 0 } = role; - let incEquips = equips, mailEquips: { id?: number, hid?: number, seqId?: number }[] = []; - if(equips.length + equipCount > BAG.BAG_EQUIP_UPLIMITED) { // 装备上限 - let inc = BAG.BAG_EQUIP_UPLIMITED - equipCount; + if(jewels.length > 0) { + let { jewelCount = 0 } = role; + let incJewels = jewels, mailJewels: { id?: number, hid?: number, seqId?: number }[] = []; + if(jewels.length + jewelCount > BAG.BAG_EQUIP_UPLIMITED) { // 装备上限 + let inc = BAG.BAG_EQUIP_UPLIMITED - jewelCount; if(inc < 0) inc = 0; - incEquips = equips.slice(0, inc); - mailEquips = equips.slice(inc); + incJewels = jewels.slice(0, inc); + mailJewels = jewels.slice(inc); } // 直接加的 - let { equips: equipInfos, pushMessages } = await addEquips(roleId, roleName, <{id: number, hid?: number}[]>incEquips, reason); - for (let equip of equipInfos) { - showItems.push({ seqId: equip.seqId, id: equip.id, count: 1, isBag: true }); + let { jewels: jewelInfos, pushMessages } = await addJewels(roleId, roleName, <{id: number, hid?: number}[]>incJewels, reason); + for (let jewel of jewelInfos) { + showItems.push({ seqId: jewel.seqId, id: jewel.id, count: 1, isBag: true }); } - for(let equip of combineItems(mailEquips)) { - showItems.push({ id: equip.id, count: equip.count, isBag: false }); + for(let jewel of combineItems(mailJewels)) { + showItems.push({ id: jewel.id, count: jewel.count, isBag: false }); } //装备推送 - if (!!equipInfos.length) - pinus.app.get('channelService').pushMessageByUids('onEquipAdd', resResult(STATUS.SUCCESS, { equipInfos }), uids); + if (!!jewelInfos.length) + pinus.app.get('channelService').pushMessageByUids('onJewelAdd', resResult(STATUS.SUCCESS, { jewelInfos }), uids); pushTaskUpdate(roleId, sid, pushMessages); //统计装备 - if (equipInfos.length > 0) { - let { serverId } = await RoleModel.findByRoleId(roleId); - await checkActivityTask(serverId, sid, roleId, TASK_TYPE.EQUIP_QUALITY_COUNT, equipInfos.length, { equips: equipInfos.map(obj => { return { quality: obj.quality } }) }) - saveItemChangeLog(roleId, equipInfos, reason); + if (jewelInfos.length > 0) { + saveItemChangeLog(roleId, jewelInfos, reason); } // 发邮件的 - if(mailEquips.length > 0) { - await sendMailByContent(MAIL_TYPE.EQUIP_OVER, roleId, { goods: combineItems(mailEquips) }); + if(mailJewels.length > 0) { + await sendMailByContent(MAIL_TYPE.EQUIP_OVER, roleId, { goods: combineItems(mailJewels) }); } } @@ -335,12 +332,12 @@ export function combineItems(items: { id?: number, count?: number }[]) { return result; } -export function combineItemAndEquips(items: { id?: number, count?: number }[]) { +export function combineItemAndJewels(items: { id?: number, count?: number }[]) { let result: { id: number, count: number }[] = []; for(let { id, count = 1 } of items) { let dicGoods = gameData.goods.get(id); let dicItid = ITID.get(dicGoods.itid); - if(dicItid.table != 'equip') { + if(dicItid.table != 'jewel') { let index = result.findIndex(cur => cur.id == id); if(index == -1) { result.push({ id, count }); @@ -356,7 +353,7 @@ export function combineItemAndEquips(items: { id?: number, count?: number }[]) { function sortItems(goods: ItemInter[], handleType: HANDLE_REWARD_TYPE) { let items: { id: number, count: number }[] = []; // 可叠加道具 - let equips: { seqId?: number, id?: number, hid?: number }[] = []; // 不可叠加装备 + let jewels: { seqId?: number, id?: number, hid?: number }[] = []; // 不可叠加装备 let gold: { count: number, isPay: boolean }[] = []; // 金币 let coin: number[] = []; let ap: number = 0; @@ -376,14 +373,14 @@ function sortItems(goods: ItemInter[], handleType: HANDLE_REWARD_TYPE) { continue; } let { type, table, isCurrency } = dicItid; - if(table == ITEM_TABLE.EQUIP) { // 装备 + if(table == ITEM_TABLE.JEWEL) { // 装备 if(handleType == HANDLE_REWARD_TYPE.RECEIVE) { for(let i = 0; i < good.count; i++) { - equips.push({ id: good.id, hid: good.hid }) + jewels.push({ id: good.id, hid: good.hid }) } } else { if(!!good.seqId) { - equips.push({ seqId: good.seqId }); + jewels.push({ seqId: good.seqId }); } } } else if (table == ITEM_TABLE.ITEM) { // 可叠加道具 @@ -429,11 +426,11 @@ function sortItems(goods: ItemInter[], handleType: HANDLE_REWARD_TYPE) { } - return { items, equips, gold, coin, ap, skins, figures } + return { items, jewels, gold, coin, ap, skins, figures } } export async function checkGoods(roleId: string, goodIds: Array) { - let equipIds: Array = []; + let jewelSeqIds: Array = []; let itemIds: Array = []; let hids: Array = []; goodIds = uniq(goodIds); @@ -442,7 +439,7 @@ export async function checkGoods(roleId: string, goodIds: Array) { if (!!goodInfo) { let { table } = ITID.get(goodInfo.itid); if (table == ITEM_TABLE.EQUIP) { - equipIds.push(goodId); + jewelSeqIds.push(goodId); } else if (table == ITEM_TABLE.ITEM) { itemIds.push(goodId); } @@ -450,12 +447,12 @@ export async function checkGoods(roleId: string, goodIds: Array) { } //检查装备是否存在 - if (!!equipIds.length) { - let resEquips = await EquipModel.getEquipsByIds(roleId, equipIds); - resEquips = uniq(resEquips, function (resEquip) { + if (!!jewelSeqIds.length) { + let resJewels = await JewelModel.findbySeqIds(jewelSeqIds); + resJewels = uniq(resJewels, function (resEquip) { return resEquip.id; }); - if (resEquips.length < equipIds.length) + if (resJewels.length < jewelSeqIds.length) return false; } //检查并修改道具 diff --git a/game-server/app/services/warRewardService.ts b/game-server/app/services/warRewardService.ts index 44dfb01b9..f672ba8e0 100644 --- a/game-server/app/services/warRewardService.ts +++ b/game-server/app/services/warRewardService.ts @@ -6,7 +6,7 @@ import { BattleDropModel } from '../db/BattleDrop'; import { getRandEelmWithWeight, getRandSingleEelm, getReasonByWarType } from '../pubUtils/util'; import { BATTLE_REWARD_TYPE, BLUEPRT_CONST } from '../consts'; -import { addItems, combineItemAndEquips } from './rewardService'; +import { addItems, combineItemAndJewels } from './rewardService'; import { BattleBlueprtDropModel } from '../db/BattleBlueprtDrop' import { RoleModel } from '../db/Role'; import { gameData } from '../pubUtils/data'; @@ -184,7 +184,7 @@ export class WarReward { let rewards = this.rewards; if(combine) { - rewards = combineItemAndEquips(rewards); + rewards = combineItemAndJewels(rewards); } await addItems(this.roleId, this.roleName, this.sid, rewards, getReasonByWarType(this.warInfo.warType)); return rewards; diff --git a/game-server/config/clientProtos.ts b/game-server/config/clientProtos.ts index 99e084b45..766d0d59f 100644 --- a/game-server/config/clientProtos.ts +++ b/game-server/config/clientProtos.ts @@ -11,10 +11,10 @@ module.exports = { "required string from": 3, "required string target": 4 }, - "role.equipHandler.composeEquip": { - "required uInt32 gid": 1, - "repeated uInt32 originalEquip": 2 - }, + // "role.equipHandler.composeEquip": { + // "required uInt32 hid": 1, + // "repeated uInt32 eplaceId": 2 + // }, "role.equipHandler.decomposeEquip": { "repeated uInt32 originalEquip": 1 }, diff --git a/game-server/config/serverProtos.ts b/game-server/config/serverProtos.ts index bedf61923..385a939cb 100644 --- a/game-server/config/serverProtos.ts +++ b/game-server/config/serverProtos.ts @@ -116,7 +116,7 @@ module.exports = { // 'required uInt32 code': 2, // 'required Data data': 3 // }, - // 'onEquipAdd': { + // 'onJewelAdd': { // 'message Data': { // "message EquipInfo": { // "message RandSe": { @@ -147,7 +147,7 @@ module.exports = { // 'required uInt32 code': 2, // 'required Data data': 3 // }, - // 'onEquipDel': { + // 'onJewelDel': { // 'message Data': { // 'repeated uInt32 equips': 1 // }, diff --git a/game-server/test/auction.test.ts b/game-server/test/auction.test.ts index 941bb118b..29a1736ae 100644 --- a/game-server/test/auction.test.ts +++ b/game-server/test/auction.test.ts @@ -105,7 +105,7 @@ describe('拍卖行测试', function () { it('出价,竞价和一口价', function (done) { let gid = null; - pinusClient.on('onEquipAdd', (res) => { + pinusClient.on('onJewelAdd', (res) => { checkSuccessResponse(res); expect(res.data.equipInfos).to.be.an('array'); for (let info of res.data.equipInfos) { diff --git a/shared/consts/constModules/heroConst.ts b/shared/consts/constModules/heroConst.ts index ec2637542..1119aa201 100644 --- a/shared/consts/constModules/heroConst.ts +++ b/shared/consts/constModules/heroConst.ts @@ -21,6 +21,7 @@ export enum HERO_SYSTEM_TYPE { TITLE = 18, // 爵位 TERAPH = 19, // 神像强化 TERAPH_UP = 20, // 神像升级 + COMPOSE_EQUIP = 21, // 合成装备 }; // 武将上限 diff --git a/shared/consts/constModules/itemConst.ts b/shared/consts/constModules/itemConst.ts index c66ae08ff..d79673c2e 100644 --- a/shared/consts/constModules/itemConst.ts +++ b/shared/consts/constModules/itemConst.ts @@ -92,16 +92,17 @@ export const ITEM_TABLE = { ITEM: 'item', ROLE: 'role', HERO: 'hero', - SKIN: 'skin' + SKIN: 'skin', + JEWEL: 'jewel', } const itid_array = [ - { id: 1, name: '神兵', table: 'equip', type: EQUIP_TYPE.WEAPON, equipJewel: JEWEL_TYPE.WEAPON }, - { id: 2, name: '宝甲', table: 'equip', type: EQUIP_TYPE.CLOTHES, equipJewel: JEWEL_TYPE.CLOTHES }, - { id: 3, name: '冠冕', table: 'equip', type: EQUIP_TYPE.SHOES, equipJewel: JEWEL_TYPE.CAP }, - { id: 4, name: '行具', table: 'equip', type: EQUIP_TYPE.CAP, equipJewel: JEWEL_TYPE.SHOES }, - { id: 5, name: '典籍', table: 'equip', type: EQUIP_TYPE.BOOK, equipJewel: JEWEL_TYPE.BOOK }, - { id: 6, name: '饰品', table: 'equip', type: EQUIP_TYPE.ACCESSORY, equipJewel: JEWEL_TYPE.ACCESSORY }, + { id: 1, name: '神兵', table: 'equip', type: EQUIP_TYPE.WEAPON, equipJewel: JEWEL_TYPE.WEAPON }, // + { id: 2, name: '宝甲', table: 'equip', type: EQUIP_TYPE.CLOTHES, equipJewel: JEWEL_TYPE.CLOTHES }, // + { id: 3, name: '冠冕', table: 'equip', type: EQUIP_TYPE.SHOES, equipJewel: JEWEL_TYPE.CAP }, // + { id: 4, name: '行具', table: 'equip', type: EQUIP_TYPE.CAP, equipJewel: JEWEL_TYPE.SHOES }, // + { id: 5, name: '典籍', table: 'equip', type: EQUIP_TYPE.BOOK, equipJewel: JEWEL_TYPE.BOOK }, // + { id: 6, name: '饰品', table: 'equip', type: EQUIP_TYPE.ACCESSORY, equipJewel: JEWEL_TYPE.ACCESSORY }, // { id: 24, name: '消耗品', table: 'item', type: CONSUME_TYPE.CONSUME }, @@ -117,11 +118,11 @@ const itid_array = [ { id: 27, name: '货币', table: 'role', isCurrency: true }, { id: 28, name: '藏宝图', table: 'item', type: CONSUME_TYPE.BLUEPRT }, - { id: 29, name: '礼器', table: 'equip', type: EQUIP_TYPE.ACCESSORY }, - { id: 30, name: '宝甲', table: 'equip', type: EQUIP_TYPE.CLOTHES }, - { id: 31, name: '名驹', table: 'equip', type: EQUIP_TYPE.SHOES }, - { id: 32, name: '典籍', table: 'equip', type: EQUIP_TYPE.BOOK }, - { id: 33, name: '神兵', table: 'equip', type: EQUIP_TYPE.WEAPON }, + { id: 29, name: '礼器', table: 'equip', type: EQUIP_TYPE.ACCESSORY }, // + { id: 30, name: '宝甲', table: 'equip', type: EQUIP_TYPE.CLOTHES }, // + { id: 31, name: '名驹', table: 'equip', type: EQUIP_TYPE.SHOES }, // + { id: 32, name: '典籍', table: 'equip', type: EQUIP_TYPE.BOOK }, // + { id: 33, name: '神兵', table: 'equip', type: EQUIP_TYPE.WEAPON }, // { id: 34, name: '代币', table: 'item', type: CONSUME_TYPE.POINT }, { id: 53, name: '武将招募券', table: 'item', type: CONSUME_TYPE.POINT }, { id: 39, name: '时装', table: 'skin', type: CONSUME_TYPE.SKIN }, @@ -131,8 +132,8 @@ const itid_array = [ { id: 43, name: '宝甲宝石', table: 'item', type: CONSUME_TYPE.JEWEL }, { id: 44, name: '免冠宝石', table: 'item', type: CONSUME_TYPE.JEWEL }, { id: 45, name: '足具宝石', table: 'item', type: CONSUME_TYPE.JEWEL }, - { id: 46, name: '礼器宝石', table: 'item', type: CONSUME_TYPE.JEWEL }, - { id: 47, name: '典籍宝石', table: 'item', type: CONSUME_TYPE.JEWEL }, + { id: 46, name: '礼器宝石', table: 'item', type: CONSUME_TYPE.JEWEL }, // + { id: 47, name: '典籍宝石', table: 'item', type: CONSUME_TYPE.JEWEL }, // { id: 48, name: '灵玄石', table: 'item', type: CONSUME_TYPE.JEWEL }, { id: 49, name: '玩家好感道具', table: 'item', type: CONSUME_TYPE.FRIEND_FAVOUR }, { id: 50, name: '形象', table: 'role', type: CONSUME_TYPE.HEAD }, @@ -141,6 +142,10 @@ const itid_array = [ { id: 55, name: '回复体力道具', table: 'item', type: CONSUME_TYPE.AP }, { id: 56, name: '骰子', table: 'item', type: CONSUME_TYPE.DICE }, { id: 58, name: '主公经验', table: 'role' }, + { id: 59, name: '武器天晶石', table: 'jewel' }, + { id: 60, name: '头饰天晶石', table: 'jewel' }, + { id: 61, name: '衣服天晶石', table: 'jewel' }, + { id: 62, name: '鞋子天晶石', table: 'jewel' }, ]; export const ITID = new Map(); @@ -205,15 +210,6 @@ export enum QUALITY_TYPE { export const GOOD_QUALITY = [QUALITY_TYPE.BLUE, QUALITY_TYPE.PURPLE, QUALITY_TYPE.ORANGE, QUALITY_TYPE.RED, QUALITY_TYPE.GOLD]; export const COM_BTL_QUALITY = [QUALITY_TYPE.BLUE, QUALITY_TYPE.PURPLE, QUALITY_TYPE.ORANGE, QUALITY_TYPE.RED]; -// 各品质随机属性条数 quality => number -export const RANDOM_SE_COUNT = new Map([ - [QUALITY_TYPE.BLUE, 0], - [QUALITY_TYPE.PURPLE, 1], - [QUALITY_TYPE.ORANGE, 2], - [QUALITY_TYPE.RED, 3], - [QUALITY_TYPE.GOLD, 4] -]); - export enum HERO_QUALITY_TYPE { BLUE = 1, // 蓝将 diff --git a/shared/consts/constModules/sysConst.ts b/shared/consts/constModules/sysConst.ts index 00b3de3d7..eefa21497 100644 --- a/shared/consts/constModules/sysConst.ts +++ b/shared/consts/constModules/sysConst.ts @@ -38,6 +38,7 @@ export const COUNTER = { GM_GROUP: { name: 'gmgroup', def: 1 }, HID: { name: 'hid', def: 10000 }, EID: { name: 'eid', def: 1 }, + JEWEL_ID: { name: 'jid', def: 1 }, ROLE: { name: 'role', def: 1 }, ACTIVITY: { name: 'aid', def: 1 }, ACTIVITY_GROUP: { name: 'agid', def: 1 }, @@ -485,6 +486,10 @@ export const FILENAME = { DIC_GUILD_WISH_REWARD: 'dic_army_wishReward', DIC_API: 'dic_api', DIC_SERVER_CONST: 'server_const', + DIC_EQUIP: 'dic_zyz_equip', + DIC_EQUIP_SUIT: 'dic_zyz_equipSuit', + DIC_EQUIP_STRENGTH: 'dic_zyz_equipStrenth', + DIC_JEWEL: 'dic_jewel', } export const WAR_RELATE_TABLES = [ diff --git a/shared/consts/statusCode.ts b/shared/consts/statusCode.ts index 46ba42af8..b6b0559b2 100644 --- a/shared/consts/statusCode.ts +++ b/shared/consts/statusCode.ts @@ -310,6 +310,8 @@ export const STATUS = { EQUIP_RESTRENGTHEN_NOT_PREVIEW: { code: 30514, simStr: '该装备未预览洗练值' }, EQUIP_QUENCH_MAX: { code: 30515, simStr: '该装备不能再淬火' }, EQUIP_DECOMPOSE_IS_UPLIMIT: { code: 30516, simStr: '装备分解数量已达上限' }, + EQUIP_HAS_COMPOSE: { code: 30517, simStr: '该装备已合成' }, + //全局养成30600-30699 ROLE_REACH_MAX_TITLE_LEVEL: { code: 30600, simStr: '玩家已达到最高的爵位' }, ROLE_TERAPH_NOT_STRENGTHEN: { code: 30601, simStr: '材料不足或玩家神像不能强化' }, diff --git a/shared/db/Equip.ts b/shared/db/Equip.ts index 51e63630a..659e9a2e3 100644 --- a/shared/db/Equip.ts +++ b/shared/db/Equip.ts @@ -106,7 +106,7 @@ export default class Equip extends BaseModel { let equip = await this.createEquip(equipInfo); result.push(equip); } - await RoleModel.increaseEquip(roleId, result.length); + await RoleModel.increaseJewel(roleId, result.length); return result; } diff --git a/shared/db/Hero.ts b/shared/db/Hero.ts index 9ff2c7d72..c1c67003b 100644 --- a/shared/db/Hero.ts +++ b/shared/db/Hero.ts @@ -82,19 +82,35 @@ export class EPlace { @prop({ required: true }) id: number; @prop({ required: true }) - lv: number; + equipId: number; @prop({ required: true }) - quality: number; + lv: number = 0; @prop({ required: true }) - qualityStage: number; + quality: number = 0; @prop({ required: true }) - star: number; + qualityStage: number = 0; @prop({ required: true }) - starStage: number; + star: number = 0; + @prop({ required: true }) + starStage: number = 0; @prop({ required: true, type: Stone, _id: false }) stones: Stone[]; @prop({ required: true }) - jewel: number; + jewel: number = 0; + + private getInitialStone () { + let result: Stone[] = []; + for(let id = 1; id <= 3; id++) { + result.push({ id, stone: 0 }); + } + return result; + } + + constructor(id: number, equipId: number) { + this.id = id; + this.equipId = equipId; + this.stones = this.getInitialStone(); + } } @index({ roleId: 1, hid: 1 }) @@ -207,11 +223,6 @@ export default class Hero extends BaseModel { return hero; } - public static async findByHidAndRoleWithEquip(hid: number, roleId: string, lean = true) { - const hero: HeroType = await HeroModel.findOne({ hid, roleId }).populate('ePlace.equip').lean(lean); - return hero; - } - public static async addEquip(roleId: string, hid: number, ePlaceId: number, equipId: string) { const hero: HeroType = await HeroModel.findOneAndUpdate( { roleId, hid, 'ePlace.id': ePlaceId }, diff --git a/shared/db/Jewel.ts b/shared/db/Jewel.ts index 95b6820b2..db5c848e5 100644 --- a/shared/db/Jewel.ts +++ b/shared/db/Jewel.ts @@ -3,6 +3,10 @@ import { index, getModelForClass, prop, DocumentType, modelOptions } from '@type // import { COUNTER } from '../consts'; // import { CounterModel } from './Counter'; import { SearchJewelParam } from '../domain/backEndField/search'; +import { RoleModel } from './Role'; +import { CounterModel } from './Counter'; +import { COUNTER } from '../consts'; +import { HeroModel } from './Hero'; export class RandSe { @prop({ required: true }) @@ -12,13 +16,23 @@ export class RandSe { @prop({ required: true }) rand: number; // 随机属性内需要随机的值 @prop({ required: true }) - locked: boolean; // 洗炼是否锁定 + locked: boolean = false; // 洗炼是否锁定 + + @prop({ required: false, default: false }) + quenched: boolean = false; // 是否淬炼了 + + constructor(id: number, seid: number, rand: number) { + this.id = id; + this.seid = seid; + this.rand = rand; + } + } @index({ roleId: 1, hid: 1, id: 1 }) @index({ seqId: 1 }) @modelOptions({ schemaOptions: { id: false } }) -export default class Equip extends BaseModel { +export default class Jewel extends BaseModel { @prop({ required: true }) roleId: string; // 角色 id @@ -36,18 +50,11 @@ export default class Equip extends BaseModel { @prop({ required: false, default: 0 }) ePlaceId: number; // 武将装备的部位 - - @prop({ required: false, default: 0 }) - quenchId: number; // 选择淬炼的那一条,未选择时为0 - @prop({ required: false, default: 0 }) - quenchCnt: number; // 淬火成功次数,到了保底就绝对成功 - @prop({ required: false, type: RandSe, default: [], _id: false }) randSe: RandSe[]; // 强化随机属性 @prop({ required: false, type: RandSe, default: [], _id: false }) previewRandSe: RandSe[]; // 强化随机属性预览 - public static async findbyRole(roleId: string, lean = true) { const jewels: JewelType[] = await JewelModel.find({ roleId }).lean(lean); return jewels; @@ -58,6 +65,42 @@ export default class Equip extends BaseModel { return jewel; } + public static async findbySeqIds(seqIds: number[], select?: string ) { + const jewel: JewelType[] = await JewelModel.find({ seqId: { $in: seqIds } }).select(select).lean(); + return jewel; + } + + public static async createJewel(jewelInfo: jewelUpdate) { + const seqId = await CounterModel.getNewCounter(COUNTER.JEWEL_ID); + + const doc = new JewelModel(); + const update = Object.assign(doc.toJSON(), seqId, jewelInfo); + const jewel: JewelType = await JewelModel.findOneAndUpdate({ seqId }, update, { upsert: true, new: true }).lean(); + if (jewelInfo.hid > 0) { + await HeroModel.findOneAndUpdate( + { roleId: jewelInfo.roleId, hid: jewelInfo.hid, 'ePlace.id': jewelInfo.ePlaceId }, + { $set: { 'ePlace.$.jewel': seqId } }, + { new: true }).lean(); + } + return jewel; + } + + public static async createJewels(roleId: string, jewelInfos: jewelUpdate[]) { + let result: JewelType[] = []; + for(let jewelInfo of jewelInfos) { + let jewel = await this.createJewel(jewelInfo); + result.push(jewel); + } + await RoleModel.increaseJewel(roleId, result.length); + return result; + } + + public static async deleteBySeqIds(roleId: string, seqIds: number[]) { + let jewels = await JewelModel.findbySeqIds(seqIds); + await JewelModel.deleteMany({ roleId, seqId: { $in: seqIds } }); + await RoleModel.increaseJewel(roleId, -1 * seqIds.length); + return jewels; + } public static async deleteAccount(roleId: string) { let result = await JewelModel.deleteMany({ roleId }); @@ -96,9 +139,9 @@ export default class Equip extends BaseModel { } } -export const JewelModel = getModelForClass(Equip); +export const JewelModel = getModelForClass(Jewel); -export interface JewelType extends Pick, keyof Equip> { +export interface JewelType extends Pick, keyof Jewel> { id: number; }; export type jewelUpdate = Partial; // 将所有字段变成可选项 \ No newline at end of file diff --git a/shared/db/Role.ts b/shared/db/Role.ts index 0e243f6a2..6f690cb03 100644 --- a/shared/db/Role.ts +++ b/shared/db/Role.ts @@ -215,7 +215,7 @@ export default class Role extends BaseModel { @prop({ required: true, default: [] }) payRecord: PayRecord[]; // 支付记录 @prop({ required: true, default: 0 }) - equipCount: number; // 装备数量 + jewelCount: number; // 装备数量 @prop({ required: true, default: 0 }) coin: number; // 总铜钱 @@ -710,12 +710,11 @@ export default class Role extends BaseModel { } // 装备上限 - public static async increaseEquip(roleId: string, count: number) { - const role: RoleType = await RoleModel.findOneAndUpdate({ roleId }, { $inc: { equipCount: count } }, { new: true }).lean(); + public static async increaseJewel(roleId: string, count: number) { + const role: RoleType = await RoleModel.findOneAndUpdate({ roleId }, { $inc: { jewelCount: count } }, { new: true }).lean(); return role; } - // 支付记录 public static async increaseTotalPay(roleId: string, price: number) { const role: RoleType = await RoleModel.findOneAndUpdate({ roleId }, { $inc: { totalPay: price } }, { new: true }).lean(); diff --git a/shared/pubUtils/data.ts b/shared/pubUtils/data.ts index 6aad89c32..fa058ea7d 100644 --- a/shared/pubUtils/data.ts +++ b/shared/pubUtils/data.ts @@ -1,5 +1,5 @@ import { dicHero, dicMyHeroes, loadHero } from "./dictionary/DicHero"; -import { dicGoods, blueprtWithQuality, blueprtWithQualityAndStar, dicJewel, figureCondition, loadGoods } from "./dictionary/DicGoods"; +import { dicGoods, blueprtWithQuality, blueprtWithQualityAndStar, figureCondition, loadGoods } from "./dictionary/DicGoods"; import { dicBlueprtCompose, loadBlueprtCompose } from "./dictionary/DicBlueprtCompose"; import { dicBlueprtPossibility, loadBlueprtPossibility } from "./dictionary/DicBlueprtPossibility"; import { dicDaily, loadDaily } from "./dictionary/DicDaily"; @@ -100,6 +100,8 @@ import { dicApiById, dicApiByUrl, loadApi } from './dictionary/DicApi'; import { dicServerConst, loadServerConst } from './dictionary/DicServerConst'; import { pick } from "underscore"; import _ = require("underscore"); +import { dicEquipById, dicEquipIdByJobClassAndEplace, loadEquip } from "./dictionary/DicEquip"; +import { dicJewel, loadJewel } from "./dictionary/DicJewel"; export const gameData = { blurprtCompose: dicBlueprtCompose, @@ -144,7 +146,6 @@ export const gameData = { randomEffectPool: dicRandomEffectPool, strengthenCost: dicStrengthenCost, refine: dicRefine, - jewels: dicJewel, dicHeroEquip: dicHeroEquip, suit: dicSuit, suitByTypeAndLv: dicSuitByTypeAndLv, @@ -249,6 +250,9 @@ export const gameData = { apiById: dicApiById, apiByUrl: dicApiByUrl, serverConst: dicServerConst, + equipById: dicEquipById, + equipIdByJobAndEPlace: dicEquipIdByJobClassAndEplace, + jewel: dicJewel, }; // 在此提供一些原先在gamedata中提供的方法,以便更方便获取gameData数据 @@ -409,10 +413,6 @@ export function getGoodById(gid: number) { return gameData.goods.get(gid); } -export function getJewelById(gid: number) { - return gameData.jewels.get(gid); -} - export function getHeroEquipByClassId(classId: number) { return gameData.dicHeroEquip.get(classId); } @@ -834,6 +834,11 @@ function splitTime(str: string) { return { hour: parseInt(arr[0]), minute: parseInt(arr[1]), seconds: parseInt(arr[2]) } } +export function getEquipByJobClassAndEPlace(jobClass: number, eplaceId: number) { + let equipId = gameData.equipIdByJobAndEPlace.get(`${jobClass}_${eplaceId}`); + return gameData.equipById.get(equipId); +} + // 初始加载 function initDatas() { parseDicParam(); @@ -999,6 +1004,8 @@ function loadDatas() { loadGuildWishReward(); loadApi(); loadServerConst(); + loadEquip(); + loadJewel(); } // 重载dicParam diff --git a/shared/pubUtils/dictionary/DicEquip.ts b/shared/pubUtils/dictionary/DicEquip.ts new file mode 100644 index 000000000..2251f0435 --- /dev/null +++ b/shared/pubUtils/dictionary/DicEquip.ts @@ -0,0 +1,54 @@ +// 装备表 +import { readFileAndParse, decodeArrayListStr, parseGoodStr } from '../util' +import { FILENAME } from '../../consts' +import { RewardInter } from '../interface'; + +export interface DicEquip { + // (key) 装备的id + readonly id: number; + // 装备的位置(武器、衣甲、帽冠、行具) + readonly eplaceId: number; + // 装备名 + readonly name: string; + // 匹配的武将的职业的大类 + readonly jobClass: number; + // 套装id + readonly suitId: number; + // 属性提升 + readonly attribute: {id: number, num: number}[]; + // 属性成长加成提升 + readonly attributeUp: {id: number, num: number}[]; + // 合成消耗 + readonly composeMaterial: RewardInter[]; + +} + +export const dicEquipById = new Map(); +export const dicEquipIdByJobClassAndEplace = new Map(); +export function loadEquip() { + dicEquipById.clear(); + dicEquipIdByJobClassAndEplace.clear(); + let arr = readFileAndParse(FILENAME.DIC_EQUIP); + + arr.forEach(o => { + o.attribute = parseAttr(o.attribute); + o.attributeUp = parseAttr(o.attributeUp); + o.composeMaterial = parseGoodStr(o.composeMaterial); + dicEquipById.set(o.id, o); + dicEquipIdByJobClassAndEplace.set(`${o.jobClass}_${o.eplaceId}`, o.id); + }); + arr = undefined; +} + +function parseAttr(str: string) { + let result = new Array<{id: number, num: number}>(); + if(!str) return result; + let decodeArr = decodeArrayListStr(str); + for(let [id, num] of decodeArr) { + if(isNaN(parseInt(id)) || isNaN(parseInt(num))) { + throw new Error('data table format wrong'); + } + result.push({id: parseInt(id), num: parseInt(num)}); + } + return result +} \ No newline at end of file diff --git a/shared/pubUtils/dictionary/DicEquipStrength.ts b/shared/pubUtils/dictionary/DicEquipStrength.ts new file mode 100644 index 000000000..19fbc945a --- /dev/null +++ b/shared/pubUtils/dictionary/DicEquipStrength.ts @@ -0,0 +1,26 @@ +// 装备强化表 +import { readFileAndParse, parseGoodStr } from '../util' +import { FILENAME } from '../../consts' +import { RewardInter } from '../interface'; + +export interface DicEquipStrength { + // id + readonly id: number; + // 等级 + readonly lv: number; + // 消耗 + readonly consume: RewardInter[]; + +} + +export const dicEquipStrength = new Map(); +export function loadEquipStrength() { + dicEquipStrength.clear(); + let arr = readFileAndParse(FILENAME.DIC_EQUIP); + + arr.forEach(o => { + o.consume = parseGoodStr(o.consume); + dicEquipStrength.set(o.lv, o); + }); + arr = undefined; +} \ No newline at end of file diff --git a/shared/pubUtils/dictionary/DicEquipSuit.ts b/shared/pubUtils/dictionary/DicEquipSuit.ts new file mode 100644 index 000000000..bbe7d63ba --- /dev/null +++ b/shared/pubUtils/dictionary/DicEquipSuit.ts @@ -0,0 +1,44 @@ +// 装备套装表 +import { readFileAndParse, parseNumberList, decodeArrayListStr } from '../util' +import { FILENAME } from '../../consts' + +export interface DicEquipSuit { + // id + readonly id: number; + // 匹配的武将的职业的大类 + readonly jobClass: number; + // 套装内含的装备编号 + readonly equips: number[]; + // 按星级可解锁的属性 + readonly effect: { star: number, seid: number }[]; + // 解锁条件索引 + readonly effectCondition: Map +} + +export const dicEquipSuit = new Map(); +export function loadEquipSuit() { + dicEquipSuit.clear(); + let arr = readFileAndParse(FILENAME.DIC_EQUIP); + + arr.forEach(o => { + o.equips = parseNumberList(o.equips); + parseRandomEffect(o, o.effect); + dicEquipSuit.set(o.jobClass, o); + }); + arr = undefined; +} + +function parseRandomEffect(o: any, str: string) { + if (!str) return null; + let decodeArr = decodeArrayListStr(str); + let effect: number[] = [], effectCondition = new Map(); + for (let [star, seid] of decodeArr) { + if (isNaN(parseInt(star)) || isNaN(parseFloat(seid))) { + throw new Error('data table format wrong'); + } + effect.push(parseInt(seid)); + effectCondition.set(parseInt(seid), parseInt(star)); + } + o.effect = effect; + o.effectCondition = effectCondition; +} \ No newline at end of file diff --git a/shared/pubUtils/dictionary/DicGoods.ts b/shared/pubUtils/dictionary/DicGoods.ts index 8d9700d53..fbef2c200 100644 --- a/shared/pubUtils/dictionary/DicGoods.ts +++ b/shared/pubUtils/dictionary/DicGoods.ts @@ -1,6 +1,6 @@ // 物品表 import { decodeArrayListStr, readFileAndParse, parseGoodStr, parseNumberList, decodeArrayStr } from '../util' -import { FILENAME, IT_TYPE, ABI_TYPE, GOOD_TYPE } from '../../consts' +import { FILENAME, IT_TYPE, ABI_TYPE } from '../../consts' import { RewardInter } from '../interface'; const _ = require('lodash'); import { findWhere } from 'underscore'; @@ -108,14 +108,12 @@ const DicGoodsKeys: KeysEnum = { charLimited: true, equipLvl: true } -export const dicJewel = new Map(); export const dicGoods = new Map(); export const blueprtWithQuality = new Map>(); export const blueprtWithQualityAndStar = new Map>(); export const figureCondition = new Map(); // type => {params, id, gid} export function loadGoods() { - dicJewel.clear(); dicGoods.clear(); blueprtWithQuality.clear(); blueprtWithQualityAndStar.clear(); @@ -155,22 +153,6 @@ export function loadGoods() { let arr2 = blueprtWithQuality.get(o.quality) || new Array(); arr.push(o.good_id); blueprtWithQuality.set(o.quality, arr2); - } else if (o.goodType == GOOD_TYPE.JEWEL) { - let material = o.composeMaterial[0]; - if (!!material && !!material.id) { - let lastJewel = findWhere(arr, { good_id: material.id }); - if (!!lastJewel) { - lastJewel.count = material.count; - lastJewel.nextJewelId = o.good_id; - if (!!o.specialMaterial.ids[0]) { - lastJewel.specialCount = o.specialMaterial.count; - lastJewel.nextSpecialId = o.specialMaterial.ids[0]; - } - dicJewel.set(lastJewel.good_id, _.pick(lastJewel, Object.keys(DicGoodsKeys))); - } - } else { - dicJewel.set(o.good_id, _.pick(o, Object.keys(DicGoodsKeys))); - } } }); diff --git a/shared/pubUtils/dictionary/DicJewel.ts b/shared/pubUtils/dictionary/DicJewel.ts new file mode 100644 index 000000000..a24814ac3 --- /dev/null +++ b/shared/pubUtils/dictionary/DicJewel.ts @@ -0,0 +1,42 @@ +// 天晶石表 +import { decodeArrayListStr, readFileAndParse, parseGoodStr, parseNumberList } from '../util' +import { FILENAME } from '../../consts'; +import { RewardInter } from '../interface'; + +export interface DicJewel { + // 物品id + readonly good_id: number; + // 天晶石名 + readonly name: string; + // 装备栏id + readonly eplaceId: number; + // itid + readonly itid: number; + // 天晶石阶 + readonly lv: number; + // 天晶石品质 + readonly quality: number; + // 天晶石属性条数 + readonly effectCount: number; + // 套装效果 + readonly randomEffect: number[]; + // 对应藏宝图id + readonly mapGoodId: number; + // 淬炼消耗 + readonly quenchConsume: RewardInter[]; +} + + +export const dicJewel = new Map(); +export function loadJewel() { + dicJewel.clear(); + + let arr = readFileAndParse(FILENAME.DIC_JEWEL); + + arr.forEach(o => { + o.randomEffect = parseNumberList(o.randomEffect); + o.quenchConsume = parseGoodStr(o.quenchConsume); + dicJewel.set(o.good_id, o); + }); + arr = undefined; +} \ No newline at end of file diff --git a/shared/pubUtils/dictionary/DicSuit.ts b/shared/pubUtils/dictionary/DicSuit.ts index 78b3c75a7..a5544abd5 100644 --- a/shared/pubUtils/dictionary/DicSuit.ts +++ b/shared/pubUtils/dictionary/DicSuit.ts @@ -1,4 +1,4 @@ -// 镇念塔表 +// 套装表 import { decodeArrayListStr, readFileAndParse, parseNumberList } from '../util' import { FILENAME } from '../../consts'; diff --git a/shared/pubUtils/itemUtils.ts b/shared/pubUtils/itemUtils.ts index d41b6a211..f37b5f05b 100644 --- a/shared/pubUtils/itemUtils.ts +++ b/shared/pubUtils/itemUtils.ts @@ -2,9 +2,8 @@ import { HeroModel, HeroType, } from '../db/Hero'; import { ItemModel } from '../db/Item'; -import { EquipModel, RandSe, Holes, RandMain, equipUpdate } from './../db/Equip'; -import { gameData, getQuenchByQualityAndGrade, getQuenchGradeByValue } from './data'; -import { RANDOM_SE_COUNT, ITID, CURRENCY_BY_TYPE, CURRENCY_TYPE, ROLE_SELECT, FIGURE_UNLOCK_CONDITION, CONSUME_TYPE, HERO_SYSTEM_TYPE, TASK_TYPE, ITEM_CHANGE_REASON } from '../consts'; +import { gameData } from './data'; +import { ITID, CURRENCY_BY_TYPE, CURRENCY_TYPE, ROLE_SELECT, FIGURE_UNLOCK_CONDITION, CONSUME_TYPE, HERO_SYSTEM_TYPE, ITEM_CHANGE_REASON } from '../consts'; import { getRandValueByMinMax, getRandEelm } from './util'; import { findWhere } from 'underscore'; @@ -12,10 +11,10 @@ import { RoleModel, RoleType, } from '../db/Role'; import { Figure } from '../domain/dbGeneral'; import { getTimeFun } from './timeUtil'; import { reCalAllHeroCe } from './playerCe'; -import { checkTaskWithEquip } from './taskUtil'; // import { checkTask, checkTaskWithHeroes, checkTaskWithEquip, accomplishTask } from './taskUtil'; import { SkinModel, } from '../db/Skin'; import { TaskListReturn } from '../domain/roleField/task'; +import { JewelModel, jewelUpdate, RandSe, } from '../db/Jewel'; /** * 只插入皮肤,不管那么多的 @@ -80,76 +79,46 @@ export async function addBag(roleId: string, roleName: string, data: { id: numbe } -export async function addEquips(roleId: string, roleName: string, weapons: { id: number, hid?: number }[], reason: number) { - let equipInfos: equipUpdate[] = []; - for(let weapon of weapons) { - let info = await getAddEquipInfo(roleId, roleName, weapon); - equipInfos.push(info); +export async function addJewels(roleId: string, roleName: string, jewels: { id: number, hid?: number }[], reason: number) { + let jewelInfo: jewelUpdate[] = []; + for(let jewel of jewels) { + let info = await getAddJewelInfo(roleId, roleName, jewel); + jewelInfo.push(info); } - const equips = await EquipModel.createEquips(roleId, equipInfos); + const jewelResult = await JewelModel.createJewels(roleId, jewelInfo); let pushMessages: TaskListReturn[] = []; - // 任务 - for(let equip of equips) { - let pushMessage = await checkTaskWithEquip(roleId, TASK_TYPE.EQUIP_SUIT, equip); - if(reason == ITEM_CHANGE_REASON.EQUIP_COMPOSE) { - let pm = await checkTaskWithEquip(roleId, TASK_TYPE.EQUIP_COMPOSE_SUIT, equip); - pushMessages.push(...pm); - } - pushMessages.push(...pushMessage); - } + // TODO 修改任务 + // for(let equip of jewelResult) { + // let pushMessage = await checkTaskWithEquip(roleId, TASK_TYPE.EQUIP_SUIT, equip); + // if(reason == ITEM_CHANGE_REASON.EQUIP_COMPOSE) { + // let pm = await checkTaskWithEquip(roleId, TASK_TYPE.EQUIP_COMPOSE_SUIT, equip); + // pushMessages.push(...pm); + // } + // pushMessages.push(...pushMessage); + // } - return { equips: equips.map(equip => { - return { ...equip, inc: 1, reason } + return { jewels: jewelResult.map(jewel => { + return { ...jewel, count: 1, inc: 1, reason } }), pushMessages } } -export async function getAddEquipInfo(roleId: string, roleName: string, weapon: { id: number, hid?: number }) { - let { id, hid = 0 } = weapon; - let { name, quality, suitId, hole, randomEffect, itid, goodsAbility } = gameData.goods.get(id); - let { type } = ITID.get(itid); +export async function getAddJewelInfo(roleId: string, roleName: string, jewel: { id: number, hid?: number, eplaceId?: number }) { + console.log('#####', jewel) + let { id, hid = 0, eplaceId = 0 } = jewel; + let { name, randomEffect, effectCount } = gameData.jewel.get(id); // 随机属性 - let randomNum = RANDOM_SE_COUNT.get(quality); - let randomResult: number[] = getRandEelm(randomEffect, randomNum); + let randomResult: number[] = getRandEelm(randomEffect, effectCount); - let randSe: Array = randomResult.map((id: number, i: number) => { + let randSe: Array = randomResult.map((id: number, index: number) => { let random = gameData.randomEffectPool.get(id) let rand = 0; if (random.id > 0) rand = getRandValueByMinMax(random.Min, random.Max, 0); - return { - id: i + 1, - seid: random.id, - rand, - locked: false - }; + return new RandSe(index + 1, random.id, rand); }); - let randRange = 0; - - // 淬火品相 - let randMain: RandMain[] = []; - let grade = 0; - for(let [ attrId, attrValue ] of goodsAbility) { - if(attrValue > 0) { - let { randMin, randMax } = getQuenchByQualityAndGrade(quality, grade); - let rand = getRandValueByMinMax(randMin, randMax, 0); - // console.log(quality, grade, rand) - grade = getQuenchGradeByValue(quality, rand); - randMain.push({ - id: attrId, - rand - }); - } - } - - - let holes = new Array(); - for (let i = 0; i < hole; i++) { - holes.push({ id: i + 1, isOpen: false, jewel: 0 }); - } - - return { roleId, roleName, id, name, quality, suitId, randRange, ePlaceId: type, randSe, holes, hid, grade, randMain }; + return { roleId, roleName, id, name, hid, eplaceId, randSe }; } /** diff --git a/shared/pubUtils/playerCe.ts b/shared/pubUtils/playerCe.ts index b404b9931..af1d2e144 100644 --- a/shared/pubUtils/playerCe.ts +++ b/shared/pubUtils/playerCe.ts @@ -9,9 +9,8 @@ import { HeroModel, HeroType, HeroUpdate, CeAttrData } from '../db/Hero'; import { RoleModel, RoleType, RoleUpdate, CeAttrDataRole } from '../db/Role'; import { AttributeCal } from '../domain/roleField/attribute'; import { ABI_STAGE, SEID_TYPE } from '../consts'; -import { gameData, getJobByGradeAndClass, getHeroWakeByQuality, getHeroStarByQuality, getFriendShipById, getSchoolRateByStar, getScollByStar, getTeraph, getDicSuitByTypeAndLv } from './data'; +import { gameData, getJobByGradeAndClass, getHeroWakeByQuality, getHeroStarByQuality, getFriendShipById, getSchoolRateByStar, getScollByStar, getTeraph } from './data'; import { DicSe } from './dictionary/DicSe'; -import { EquipType } from '../db/Equip'; import { DicRandomEffectPool } from './dictionary/DicRandomEffectPool'; import { SchoolModel } from '../db/School'; import { ABI_TYPE_MAIN, ABI_JOB_STAGE, ABI_STAGE_TO_TYPE } from '../consts/constModules/abilityConst' @@ -19,7 +18,6 @@ import { PvpDefenseModel } from '../db/PvpDefense'; import { findIndex } from 'underscore'; import { GuildModel } from '../db/Guild'; import { DicJob } from './dictionary/DicJob'; -import { DicSuit } from './dictionary/DicSuit'; import { saveCeChangeLog } from './logUtil'; // 修改并下发战力 @@ -166,6 +164,9 @@ export function calPlayerCe(hero: HeroType, update: HeroUpdate, type: number, ar case HERO_SYSTEM_TYPE.CONNECT: heroAttrs = calHeroConectIncAttr(hero, update, args[0]); break; + case HERO_SYSTEM_TYPE.COMPOSE_EQUIP: + heroAttrs = calComposeEquipIncAttr(hero, update, args[0]); + break; case HERO_SYSTEM_TYPE.EQUIP: heroAttrs = calEquipPutOnOffIncAttr(hero, args, addSeidList, removeSeidList); break; @@ -603,6 +604,18 @@ export function calHeroFavourUpIncAttr(originHero: HeroType, update: HeroUpdate) return heroAttrs; } +export function calComposeEquipIncAttr(hero: HeroType, update: HeroUpdate, eplaceId: number) { + let { attr: heroAttrs } = hero; + let newEquip = update.ePlace.find(cur => cur.id == eplaceId); + if(newEquip) { + let dicEquip = gameData.equipById.get(newEquip.equipId); + for(let attr of dicEquip.attribute) { + updateHeroAttr(heroAttrs, attr.id, { inc: { fixUp: attr.num * HERO_CE_RATIO } }); + } + } + return heroAttrs; +} + /** * 穿脱, removeSeidList原来身上穿着的所有装备的seid,包括套装的 * @param {HeroType} hero 武将 @@ -687,7 +700,7 @@ export function calEquipSeids(_hero: HeroType) { * @param {HeroType} hero 装备更新过的武将 */ export function calHeroEquipIncAttr(hero: HeroType) { - let { ePlace:_, attr: heroAttrs } = hero; + let { attr: heroAttrs } = hero; // let setMap = new Map(); // for (let { equip, lv, refineLv } of ePlace) { diff --git a/shared/resource/jsons/dic_goods.json b/shared/resource/jsons/dic_goods.json index 210fe1cfe..cc733046e 100644 --- a/shared/resource/jsons/dic_goods.json +++ b/shared/resource/jsons/dic_goods.json @@ -55554,5 +55554,48 @@ "timelimit": 0, "gift": 0, "info": "主公经验" + }, + { + "good_id": 72032, + "name": "天晶石", + "lvLimited": 1, + "equipLvl": 0, + "jobLimited": "0&", + "charLimited": "0&", + "quality": 1, + "image_id": "duiwujingyan", + "itid": 59, + "goodType": 12, + "redPoint": 0, + "pieces": 0, + "pieceId": 0, + "composeMaterial": "&", + "specialMaterial": "&", + "equipId": 0, + "suitId": "&", + "decomposeItem": "&", + "hole": 0, + "randomEffect": "&", + "hid": 0, + "hp": 0, + "atk": 0, + "def": 0, + "mdef": 0, + "hp_up": 0, + "atk_up": 0, + "def_up": 0, + "mdef_up": 0, + "damageIncrease": 0, + "damageDecrease": 0, + "atkDecrease": 0, + "matkDecrease": 0, + "specialAttr": "&", + "getWays": "1&0", + "useWays": "&", + "value": 0, + "condition": 0, + "timelimit": 0, + "gift": 0, + "info": "主公经验" } ] \ No newline at end of file diff --git a/shared/resource/jsons/dic_jewel.json b/shared/resource/jsons/dic_jewel.json new file mode 100644 index 000000000..c801e1f63 --- /dev/null +++ b/shared/resource/jsons/dic_jewel.json @@ -0,0 +1,13 @@ +[{ + "id":1, + "good_id": 72032, + "name": "天晶石1", + "eplaceId": 1, + "itId": 59, + "lv": 1, + "quality": 1, + "effectCount": 3, + "randomEffect": "1&2&3&4&5", + "mapGoodId": 1, + "quenchConsume": "31001&10000" +}] \ No newline at end of file diff --git a/shared/resource/jsons/dic_zyz_equip.json b/shared/resource/jsons/dic_zyz_equip.json new file mode 100644 index 000000000..fcafb3744 --- /dev/null +++ b/shared/resource/jsons/dic_zyz_equip.json @@ -0,0 +1,10 @@ +[{ + "id": 1, + "eplaceId": 1, + "name": "", + "jobClass": 2, + "suitId": 0, + "attribute": "1&1", + "attributeUp": "1&1", + "composeMaterial": "31002&100" +}] \ No newline at end of file