feat(玉石一键合成): 新增玉石一键合成
This commit is contained in:
@@ -1,5 +1,5 @@
|
|||||||
import { Application, BackendSession, HandlerService, } from "pinus";
|
import { Application, BackendSession, HandlerService, } from "pinus";
|
||||||
import { STATUS, HERO_SYSTEM_TYPE, ITEM_CHANGE_REASON, TASK_TYPE } from "../../../consts";
|
import { STATUS, HERO_SYSTEM_TYPE, ITEM_CHANGE_REASON, TASK_TYPE, CONSUME_TYPE } from "../../../consts";
|
||||||
import { ItemInter, RewardInter } from "../../../pubUtils/interface";
|
import { ItemInter, RewardInter } from "../../../pubUtils/interface";
|
||||||
|
|
||||||
import { resResult, parseGoodStr } from "../../../pubUtils/util";
|
import { resResult, parseGoodStr } from "../../../pubUtils/util";
|
||||||
@@ -9,14 +9,17 @@ import { gameData, getEquipByJobClassAndEPlace, getNextEquipQuality, getEquipSta
|
|||||||
import { BAG, EQUIP } from "../../../pubUtils/dicParam";
|
import { BAG, EQUIP } from "../../../pubUtils/dicParam";
|
||||||
import { getRandSeResult, updateEplace, updateEplaces, checkJewelCanPutOnEquip, updateStone, checkStoneCanPutOnEquip, isLocked } from "../../../services/equipService";
|
import { getRandSeResult, updateEplace, updateEplaces, checkJewelCanPutOnEquip, updateStone, checkStoneCanPutOnEquip, isLocked } from "../../../services/equipService";
|
||||||
|
|
||||||
import { isNumber, pick } from 'underscore';
|
import { clone, isNumber, max, min, pick } from 'underscore';
|
||||||
import { JewelModel, RandSe } from "../../../db/Jewel";
|
import { JewelModel, RandSe } from "../../../db/Jewel";
|
||||||
import { checkTaskInComposeEquip, checkTaskInEquipLvUp, checkTaskInComposeStone, checkTaskInEquipReset, checkTaskInEquipQuench, checkTaskInEquipQualityUp, checkTaskInEquipStarUp, checkTaskInPutJewel, checkTaskInPutStone } from '../../../services/task/taskService';
|
import { checkTaskInComposeEquip, checkTaskInEquipLvUp, checkTaskInComposeStone, checkTaskInEquipReset, checkTaskInEquipQuench, checkTaskInEquipQualityUp, checkTaskInEquipStarUp, checkTaskInPutJewel, checkTaskInPutStone } from '../../../services/task/taskService';
|
||||||
import { pushEquipQualityMax, pushEquipStarMax } from "../../../services/sysChatService";
|
import { pushEquipQualityMax, pushEquipStarMax } from "../../../services/sysChatService";
|
||||||
import { addConsumeToHero } from "../../../services/roleService";
|
import { addConsumeToHero } from "../../../services/roleService";
|
||||||
import { CheckMeterial } from "../../../services/role/checkMaterial";
|
import { CheckMeterial, getComposeStoneCostAndAdd, getCurItem } from "../../../services/role/checkMaterial";
|
||||||
import { combineItems } from "../../../services/role/util";
|
import { combineItems } from "../../../services/role/util";
|
||||||
import { calculateCeWithHero } from "../../../services/playerCeService";
|
import { calculateCeWithHero } from "../../../services/playerCeService";
|
||||||
|
import { ItemModel } from "../../../db/Item";
|
||||||
|
import { index } from "typegoose";
|
||||||
|
import { all } from "bluebird";
|
||||||
|
|
||||||
export default function (app: Application) {
|
export default function (app: Application) {
|
||||||
new HandlerService(app, {});
|
new HandlerService(app, {});
|
||||||
@@ -735,6 +738,43 @@ export class EquipHandler {
|
|||||||
return resResult(STATUS.SUCCESS, { goods });
|
return resResult(STATUS.SUCCESS, { goods });
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public async composeStoneByItId(msg: { itId: number }, session: BackendSession) {
|
||||||
|
let { itId } = msg;
|
||||||
|
let roleId: string = session.get('roleId');
|
||||||
|
let roleName: string = session.get('roleName');
|
||||||
|
let sid: string = session.get('sid');
|
||||||
|
let serverId: number = session.get('serverId');
|
||||||
|
|
||||||
|
let curItem = await getCurItem(roleId, itId);
|
||||||
|
if (curItem.size == 0) {
|
||||||
|
// console.log("---composeStoneByItId-- curItem=%s", curItem);
|
||||||
|
return resResult(STATUS.ROLE_MATERIAL_NOT_ENOUGH);
|
||||||
|
}
|
||||||
|
|
||||||
|
let { allCostItem, allAddItem } = await getComposeStoneCostAndAdd(curItem, itId)
|
||||||
|
if (allCostItem.size == 0 || allAddItem.size == 0) {
|
||||||
|
// console.log("---composeStoneByItId-- allCostItem=%s, allAddItem=%s", allCostItem, allAddItem);
|
||||||
|
return resResult(STATUS.ROLE_MATERIAL_NOT_ENOUGH);
|
||||||
|
}
|
||||||
|
|
||||||
|
let costResult = await handleCost(roleId, sid, [...allCostItem].map(([id, count]) => ({ id, count })), ITEM_CHANGE_REASON.COMPOSE_STONE);
|
||||||
|
if (!costResult) return resResult(STATUS.ROLE_MATERIAL_NOT_ENOUGH);
|
||||||
|
|
||||||
|
let arrAddItem = [];
|
||||||
|
let total = 0;
|
||||||
|
for (const [id, count] of allAddItem) {
|
||||||
|
if (count == 0) continue;
|
||||||
|
arrAddItem.push({ id, count });
|
||||||
|
total += count;
|
||||||
|
}
|
||||||
|
let goods = await addItems(roleId, roleName, sid, arrAddItem, ITEM_CHANGE_REASON.COMPOSE_STONE);
|
||||||
|
|
||||||
|
await checkTaskInComposeStone(serverId, roleId, sid, total);
|
||||||
|
return resResult(STATUS.SUCCESS, { goods });
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
public async inheritJewel(msg: { originJewel: number, targetJewel: number }, session: BackendSession) {
|
public async inheritJewel(msg: { originJewel: number, targetJewel: number }, session: BackendSession) {
|
||||||
let { originJewel: originJewelId, targetJewel: targetJewelId } = msg;
|
let { originJewel: originJewelId, targetJewel: targetJewelId } = msg;
|
||||||
let roleId: string = session.get('roleId');
|
let roleId: string = session.get('roleId');
|
||||||
|
|||||||
@@ -1689,6 +1689,11 @@ export function checkRouteParam(route: string, msg: any) {
|
|||||||
if (!checkNaturalNumbers(msg.id, msg.count)) return false;
|
if (!checkNaturalNumbers(msg.id, msg.count)) return false;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
case "role.equipHandler.composeStoneByItId":
|
||||||
|
{
|
||||||
|
if (!checkNaturalNumbers(msg.itId)) return false;
|
||||||
|
break;
|
||||||
|
}
|
||||||
case "role.equipHandler.inheritJewel":
|
case "role.equipHandler.inheritJewel":
|
||||||
{
|
{
|
||||||
if (!checkNaturalNumbers(msg.originJewel, msg.targetJewel)) return false;
|
if (!checkNaturalNumbers(msg.originJewel, msg.targetJewel)) return false;
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
import { CURRENCY_TYPE, HANDLE_REWARD_TYPE, CURRENCY_BY_TYPE } from '../../consts';
|
import { CURRENCY_TYPE, HANDLE_REWARD_TYPE, CURRENCY_BY_TYPE, CONSUME_TYPE, ITID_STONE_LIMIT } from '../../consts';
|
||||||
import { RoleModel, RoleType } from '../../db/Role';
|
import { RoleModel, RoleType } from '../../db/Role';
|
||||||
import { ItemModel, ItemType } from '../../db/Item';
|
import { ItemModel, ItemType } from '../../db/Item';
|
||||||
import { ItemInter, RewardInter, } from '../../pubUtils/interface';
|
import { ItemInter, RewardInter, } from '../../pubUtils/interface';
|
||||||
@@ -210,4 +210,130 @@ export class CheckMeterial {
|
|||||||
public getConsume() {
|
public getConsume() {
|
||||||
return this.consumes;
|
return this.consumes;
|
||||||
}
|
}
|
||||||
}
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取升品所需消耗
|
||||||
|
* @param id
|
||||||
|
* @returns
|
||||||
|
*/
|
||||||
|
export async function getComposeStoneNeedCost(id: number) {
|
||||||
|
let dicStone = gameData.stone.get(id);
|
||||||
|
if (!dicStone || dicStone.composeMaterial.length <= 0) return false;
|
||||||
|
return dicStone.composeMaterial;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取当前类型6品以下玉石升级相关道具
|
||||||
|
* @param roleId
|
||||||
|
* @param itId
|
||||||
|
* @returns
|
||||||
|
*/
|
||||||
|
export async function getCurItem(roleId: string, itId: number) {
|
||||||
|
//记录升品所需要的当前已有道具
|
||||||
|
let curItem = new Map<number, number>();
|
||||||
|
let stoneLvId = new Map<number, number>();
|
||||||
|
let stoneItId = gameData.stoneItId.get(itId);
|
||||||
|
for (const { good_id, lv } of stoneItId) {
|
||||||
|
// stoneLvId.set(lv, good_id);
|
||||||
|
if (lv >= ITID_STONE_LIMIT) continue;
|
||||||
|
let nextLvMaterial = await getComposeStoneNeedCost(good_id);
|
||||||
|
if (!nextLvMaterial) continue;
|
||||||
|
for (let material of nextLvMaterial) {
|
||||||
|
if (curItem.get(material.id)) continue;
|
||||||
|
const item = await ItemModel.findbyRoleAndGid(roleId, material.id)
|
||||||
|
if (!item || item.count == 0) continue;
|
||||||
|
curItem.set(material.id, item.count);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// console.log('---------------- curItem', curItem);
|
||||||
|
// console.log('---------------- stoneLvId', stoneLvId);
|
||||||
|
|
||||||
|
return curItem;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 计算玉石一键升品总产出与消耗
|
||||||
|
* @param initialJewel
|
||||||
|
* @param curItem
|
||||||
|
* @returns
|
||||||
|
*/
|
||||||
|
export async function getComposeStoneCostAndAdd(curItem, itId) {
|
||||||
|
let allAddItem = new Map<number, number>();//Array<ItemInter> = [];//总产出
|
||||||
|
let allCostItem = new Map<number, number>();//Array<ItemInter> = [];//总消耗
|
||||||
|
|
||||||
|
//计算升品所需消耗
|
||||||
|
for (let lv = ITID_STONE_LIMIT - 1; lv >= 1; lv--) {
|
||||||
|
for (let indexLv = lv; indexLv < ITID_STONE_LIMIT; indexLv++) {
|
||||||
|
|
||||||
|
let id = gameData.stoneItIdLv.get(`${itId}_${indexLv}`);
|
||||||
|
// console.log("------- id", id);
|
||||||
|
let tempItem1 = curItem.get(id) ? curItem.get(id) : 0;
|
||||||
|
let tempItem2 = allAddItem.get(id) ? allAddItem.get(id) : 0
|
||||||
|
let count = tempItem1 + tempItem2;
|
||||||
|
if (count == 0) continue;//当前品没有,无法进行升下一品
|
||||||
|
|
||||||
|
let nextLvId = gameData.stoneItIdLv.get(`${itId}_${indexLv + 1}`); //stoneLvId.get(indexLv + 1);
|
||||||
|
// console.log("------- nextLvId", nextLvId);
|
||||||
|
|
||||||
|
if (!nextLvId) continue; //不存在下一品
|
||||||
|
|
||||||
|
// console.log("-x-x-x-x-x-x-x--x-x- nextLvId", nextLvId)
|
||||||
|
//计算升到下一阶消耗
|
||||||
|
let nextLvMaterial = await getComposeStoneNeedCost(nextLvId);
|
||||||
|
// console.log("x-x-x-x-x--x-x-x-x-x-x-- nextLvMaterial", nextLvMaterial)
|
||||||
|
if (!nextLvMaterial || nextLvMaterial.length == 0) {
|
||||||
|
//升下一品不存在消耗
|
||||||
|
//产出
|
||||||
|
let addCount = allAddItem.get(nextLvId) ? allAddItem.get(nextLvId) : 0
|
||||||
|
allAddItem.set(nextLvId, addCount + count);
|
||||||
|
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 计算能升品的下一品新增数量
|
||||||
|
let nextLvCount = nextLvMaterial[0].count ? nextLvMaterial[0].count : 0;
|
||||||
|
for (let material of nextLvMaterial) {
|
||||||
|
let tempCount1 = curItem.get(material.id) ? curItem.get(material.id) : 0;
|
||||||
|
let tempCount2 = allAddItem.get(material.id) ? allAddItem.get(material.id) : 0;
|
||||||
|
nextLvCount = Math.min(nextLvCount, Math.floor((tempCount1 + tempCount2) / material.count));
|
||||||
|
}
|
||||||
|
console.log("x-x--x-x-x-x-x-x-x-x- nextLvCount", nextLvCount)
|
||||||
|
if (nextLvCount == 0) continue;// 不能升品
|
||||||
|
|
||||||
|
// 消耗
|
||||||
|
for (let material of nextLvMaterial) {
|
||||||
|
let costCount = nextLvCount * material.count;
|
||||||
|
let tempCostCount = allCostItem.get(material.id) ? allCostItem.get(material.id) : 0;
|
||||||
|
allCostItem.set(material.id, tempCostCount + costCount);
|
||||||
|
|
||||||
|
let tempCount1 = curItem.get(material.id);
|
||||||
|
let tempCount2 = allAddItem.get(material.id);
|
||||||
|
if (tempCount1) {
|
||||||
|
if (tempCount1 > costCount) {
|
||||||
|
curItem.set(material.id, tempCount1 - costCount);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
curItem.delete(material.id);
|
||||||
|
allAddItem.set(material.id, (tempCount2 - (costCount - tempCount1)));
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
allAddItem.set(material.id, tempCount2 - costCount);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 产出
|
||||||
|
let addCount = allAddItem.get(nextLvId) ? allAddItem.get(nextLvId) : 0
|
||||||
|
allAddItem.set(nextLvId, addCount + nextLvCount);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// console.log('---------------- allCostItem', allCostItem);
|
||||||
|
// console.log('---------------- allAddItem', allAddItem);
|
||||||
|
|
||||||
|
return { allCostItem, allAddItem };
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -88,4 +88,45 @@ describe('全局养成测试', function () {
|
|||||||
done();
|
done();
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
describe('玉石养成测试', function () {
|
||||||
|
let pinusClient: PinusWSClient;
|
||||||
|
let roleInfo;
|
||||||
|
|
||||||
|
before(function (done) {
|
||||||
|
const c = new Client();
|
||||||
|
const timer = setInterval(() => {
|
||||||
|
if (c.client) {
|
||||||
|
pinusClient = c.client;
|
||||||
|
roleInfo = c.roleInfo;
|
||||||
|
clearInterval(timer);
|
||||||
|
done();
|
||||||
|
}
|
||||||
|
}, 500);
|
||||||
|
});
|
||||||
|
|
||||||
|
after(function (done) {
|
||||||
|
pinusClient.disconnect();
|
||||||
|
// disconnect 后等待 500ms,供服务器清理环境、退出频道等
|
||||||
|
setTimeout(() => {
|
||||||
|
done();
|
||||||
|
}, 500);
|
||||||
|
});
|
||||||
|
// { roleId: 'EAmqtKscfy', roleName: 'kYEXBWNk', serverId: 1, values: { reward: addItem }
|
||||||
|
it('宝石一键合成', function (done) {
|
||||||
|
// pinusClient.request('role.heroHandler.addItem', { id: 60001, count: 10 }, (res) => {
|
||||||
|
// console.log("--------------------添加道具", res)
|
||||||
|
// done();
|
||||||
|
// })
|
||||||
|
pinusClient.request('role.equipHandler.composeStoneByItId', { itId: 42 }, (res) => {
|
||||||
|
console.log("-------------------- res", res)
|
||||||
|
done();
|
||||||
|
})
|
||||||
|
})
|
||||||
|
});
|
||||||
|
|
||||||
|
// function addItem() {
|
||||||
|
// let rewardInter;
|
||||||
|
// rewardInter.push({ id: 60001, count: 10 });
|
||||||
|
// }
|
||||||
@@ -30,6 +30,8 @@ export const CHECT_BATTLE_TYPE = 200; //非异常战斗类型
|
|||||||
export const CHECT_BATTLE_TYPE_ATK_LIMIT = 201; // 我方武将最高攻小于地方最低防
|
export const CHECT_BATTLE_TYPE_ATK_LIMIT = 201; // 我方武将最高攻小于地方最低防
|
||||||
export const CHECT_BATTLE_TYPE_HIDE = 202; // 隐藏武将
|
export const CHECT_BATTLE_TYPE_HIDE = 202; // 隐藏武将
|
||||||
|
|
||||||
|
export const ITID_STONE_LIMIT = 6; //玉石一键合成等级限制
|
||||||
|
|
||||||
export enum TIME_OUTPUT_TYPE {
|
export enum TIME_OUTPUT_TYPE {
|
||||||
DATE = 1,
|
DATE = 1,
|
||||||
STAMP_10 = 2,
|
STAMP_10 = 2,
|
||||||
|
|||||||
@@ -90,7 +90,7 @@ import { dicServerConst, loadServerConst } from './dictionary/DicServerConst';
|
|||||||
const _ = require("underscore");
|
const _ = require("underscore");
|
||||||
import { dicEquipById, dicEquipIdByJobClassAndEplace, loadEquip } from "./dictionary/DicEquip";
|
import { dicEquipById, dicEquipIdByJobClassAndEplace, loadEquip } from "./dictionary/DicEquip";
|
||||||
import { dicBlueprt, dicBlueprtByLv, dicJewel, loadJewel } from "./dictionary/DicJewel";
|
import { dicBlueprt, dicBlueprtByLv, dicJewel, loadJewel } from "./dictionary/DicJewel";
|
||||||
import { dicStone, loadStone } from './dictionary/DicStone';
|
import { dicStone, dicStoneItId, dicStoneItIdLv, loadStone } from './dictionary/DicStone';
|
||||||
import { dicEquipStrength, loadEquipStrength } from "./dictionary/DicEquipStrength";
|
import { dicEquipStrength, loadEquipStrength } from "./dictionary/DicEquipStrength";
|
||||||
import { dicEquipQuality, dicEquipQualityIdByEquipIdAndPoint, loadEquipQuality } from "./dictionary/DicEquipQuality";
|
import { dicEquipQuality, dicEquipQualityIdByEquipIdAndPoint, loadEquipQuality } from "./dictionary/DicEquipQuality";
|
||||||
import { dicEquipStar, dicEquipStarIdByEquipId, loadEquipStar } from './dictionary/DicEquipStar';
|
import { dicEquipStar, dicEquipStarIdByEquipId, loadEquipStar } from './dictionary/DicEquipStar';
|
||||||
@@ -281,6 +281,8 @@ export const gameData = {
|
|||||||
equipIdByJobAndEPlace: dicEquipIdByJobClassAndEplace,
|
equipIdByJobAndEPlace: dicEquipIdByJobClassAndEplace,
|
||||||
jewel: dicJewel,
|
jewel: dicJewel,
|
||||||
stone: dicStone,
|
stone: dicStone,
|
||||||
|
stoneItId: dicStoneItId,
|
||||||
|
stoneItIdLv: dicStoneItIdLv,
|
||||||
equipStrengthenCost: dicEquipStrength,
|
equipStrengthenCost: dicEquipStrength,
|
||||||
equipQuality: dicEquipQuality,
|
equipQuality: dicEquipQuality,
|
||||||
equipQualityIdByEquipIdAndPoint: dicEquipQualityIdByEquipIdAndPoint,
|
equipQualityIdByEquipIdAndPoint: dicEquipQualityIdByEquipIdAndPoint,
|
||||||
|
|||||||
@@ -10,8 +10,8 @@ export interface DicStone {
|
|||||||
readonly name: string;
|
readonly name: string;
|
||||||
// 装备栏id
|
// 装备栏id
|
||||||
readonly eplaceId: number;
|
readonly eplaceId: number;
|
||||||
// itid
|
// itId
|
||||||
readonly itid: number;
|
readonly itId: number;
|
||||||
// 地玉石阶
|
// 地玉石阶
|
||||||
readonly lv: number;
|
readonly lv: number;
|
||||||
// 地玉石品质
|
// 地玉石品质
|
||||||
@@ -24,8 +24,12 @@ export interface DicStone {
|
|||||||
|
|
||||||
|
|
||||||
export const dicStone = new Map<number, DicStone>();
|
export const dicStone = new Map<number, DicStone>();
|
||||||
|
export const dicStoneItId = new Map<number, DicStone[]>();
|
||||||
|
export const dicStoneItIdLv = new Map<string, number>();
|
||||||
export function loadStone() {
|
export function loadStone() {
|
||||||
dicStone.clear();
|
dicStone.clear();
|
||||||
|
dicStoneItId.clear();
|
||||||
|
dicStoneItIdLv.clear();
|
||||||
|
|
||||||
let arr = readFileAndParse(FILENAME.DIC_STONE);
|
let arr = readFileAndParse(FILENAME.DIC_STONE);
|
||||||
|
|
||||||
@@ -33,6 +37,14 @@ export function loadStone() {
|
|||||||
o.composeMaterial = parseGoodStr(o.composeMaterial);
|
o.composeMaterial = parseGoodStr(o.composeMaterial);
|
||||||
o.attribute = parseAttr(o.attribute);
|
o.attribute = parseAttr(o.attribute);
|
||||||
dicStone.set(o.good_id, o);
|
dicStone.set(o.good_id, o);
|
||||||
|
|
||||||
|
if (!dicStoneItId.has(o.itId)) {
|
||||||
|
dicStoneItId.set(o.itId, new Array<DicStone>());
|
||||||
|
}
|
||||||
|
dicStoneItId.get(o.itId).push(o);
|
||||||
|
|
||||||
|
|
||||||
|
dicStoneItIdLv.set(`${o.itId}_${o.lv}`, o.good_id);
|
||||||
});
|
});
|
||||||
arr = undefined;
|
arr = undefined;
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user