Files
ZYZ/game-server/app/services/equipService.ts

133 lines
6.5 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
import { mergeSameGoods, deepCopy } from '../pubUtils/util';
import { EquipModel } from "../db/Equip";
import { HeroModel, EPlace, HeroType } from "../db/Hero";
import { getHeroJob, getGoodById, gameData, getJewelById, getHeroEquipByClassId } from "../pubUtils/data";
import { calPlayerCeAndSave } from "./playerCeService";
import { HERO_SYSTEM_TYPE, TASK_TYPE } from "../consts";
import { EquipType } from "../db/Equip";
import { calEquipSeids } from '../pubUtils/playerCe';
import { indexOf, findIndex } from 'underscore';
import { checkTask, checkTaskWithHero, checkTaskWithEquip } from './taskService';
import { accomplishTask } from '../pubUtils/taskUtil';
/**
* 校验前端传入的消耗数量是否准确并返回消耗的道具并加上特殊材料needConsumes
* @param consumes
* @param jewel
* @param jewelCount
*/
export function checkMaterialEnough(consumes: Array<{ id: number, count: number }>, jewel: number, jewelCount: number) {
let comJewelMap = {};
consumes = mergeSameGoods(consumes);
let needConsumes: Array<{ id: number, count: number }> = [];
let gidJewelInfo = getGoodById(jewel);//目标宝石信息
for (let { id, count } of consumes) {
let jewelInfo = getJewelById(id);
if (!jewelInfo || !jewelInfo.count) //筛选出特殊材料特殊材料没有合成下一级需要的count数量
continue;
needConsumes.push({ id, count });//将该宝石加入消耗中
comJewelMap[id] = count + (comJewelMap[id] || 0);
for (let i = jewelInfo.lvLimited; i < gidJewelInfo.lvLimited; i++) {//当前消耗的宝石升级到目标宝石的消耗
if (((comJewelMap[id] || 0) % jewelInfo.count != 0)) {//jewelInfo的count表示宝石id合成下一级需要的数量
break;//数量有余,跳出循环,等待下次合成
}
let comcount = Math.floor(((comJewelMap[id] || 0)) / jewelInfo.count);
if (comcount < 1) {
break;//不能合成,跳出循环,等待下次合成
}
comJewelMap[jewelInfo.nextJewelId] = comcount + (comJewelMap[jewelInfo.nextJewelId] || 0);//jewelInfo的nextJewelId表示宝石id合成下一级的宝石good_id
delete comJewelMap[id];
if (!!jewelInfo.specialCount)
needConsumes.push({ count: jewelInfo.specialCount * comcount, id: jewelInfo.nextSpecialId });//消耗中曾加合成下一级需要的特殊消耗物品的数量
jewelInfo = getJewelById(jewelInfo.nextJewelId);
}
}
if (comJewelMap[jewel] != jewelCount || Object.keys(comJewelMap).length != 1)//检查最终是否可以合成目标宝石jewel以及对应的数量jewelCount
return false;
return needConsumes;
}
/**
* 将装备卸载下来,并检查是否有替换装备的武将,若有则替换
* 武将A装备A&武将B装备B ==> 武将A装备B&武将B装备A
* 武将A装备A& 装备B ==> 武将A装备B& 装备A
* @param roleId 玩家id
* @param sid
* @param equip 目标武将要卸下的装备装备A
* @param hid 要装上的装备备原来装备着的武将id 武将B
* @param id 装备类型
* @param seqId 要装上的装备的唯一id 装备B
*/
export async function changeEquip(roleId: string, sid: string, equipA: EquipType, hid: number, id: number, equipB: EquipType, funcs: number[]) {
let heroB: HeroType;
if (!!hid) //需要卸下或者替换的武将
heroB = await HeroModel.findByHidAndRoleWithEquip(hid, roleId);//需要替换的武将
if (!!equipA) {//需要卸下的装备
if (!!heroB) {
let goodInfo = getGoodById(equipA.id);
if (goodInfo.lvLimited > heroB.lv) {
let res = await takeOffEquipAndCalPlayerCe(roleId, sid, heroB, equipB, id, funcs);//卸下装备并重算战力
return res;
}
let { jobid } = gameData.hero.get(hid);
let { job_class } = getHeroJob(jobid);
let { classId } = getHeroEquipByClassId(goodInfo.itid);
if (indexOf(classId, job_class) < 0) {
let res = await takeOffEquipAndCalPlayerCe(roleId, sid, heroB, equipB, id, funcs);//卸下装备并重算战力
return res;
}
let res = await dressEquip(roleId, sid, heroB, equipA, funcs);//替换给武将,并计算战力
return res;
} else {
let res = await takeOffEquipAndCalPlayerCe(roleId, sid, null, equipA, id, funcs);//卸下装备并重算战力
return res;
}
} else if (!!heroB) {//从穿戴装备的武将上卸下装备
let res = await takeOffEquipAndCalPlayerCe(roleId, sid, heroB, equipB, id, funcs);//卸下装备并重算战力
return res
}
}
/**
* 从穿戴装备的武将上卸下装备,并重算战力
* @param roleId
* @param sid
* @param seqId
* @param hero
* @param id
*/
export async function takeOffEquipAndCalPlayerCe(roleId: string, sid: string, hero: HeroType, equip: EquipType, id: number, funcs: number[]) {
console.log(roleId, sid, hero, equip, id)
if (hero) {
let args = calEquipSeids(hero);
hero = await HeroModel.removeEquip(roleId, hero.hid, id, equip._id);
await calPlayerCeAndSave(HERO_SYSTEM_TYPE.EQUIP, sid, roleId, hero, {}, args);
await checkTaskWithHero(roleId, sid, funcs, TASK_TYPE.EQUIP_BY_HERO, hero, [-1]);
} else {
await EquipModel.putOnOrOff(equip._id, 0);
}
// 任务
await checkTask(roleId, sid, funcs, TASK_TYPE.EQUIP_SUM, -1, true, {});
await checkTaskWithEquip(roleId, sid, funcs, TASK_TYPE.EQUIP_QUALITY, equip, [-1]);
return { seqId: equip.seqId, hid: 0 };
}
/**
* 穿戴装备并重算战力
* @param roleId
* @param sid
* @param hero
* @param equip
*/
export async function dressEquip(roleId: string, sid: string, hero: HeroType, equip: EquipType, funcs: number[]) {
let args = calEquipSeids(hero);
hero = await HeroModel.addEquip(roleId, hero.hid, equip.ePlaceId, equip._id);
await calPlayerCeAndSave(HERO_SYSTEM_TYPE.EQUIP, sid, roleId, hero, {}, args);
// 任务
await checkTask(roleId, sid, funcs, TASK_TYPE.EQUIP_SUM, 1, true, {});
await checkTaskWithHero(roleId, sid, funcs, TASK_TYPE.EQUIP_BY_HERO, hero, [1]);
await checkTaskWithEquip(roleId, sid, funcs, TASK_TYPE.EQUIP_QUALITY, equip, [1]);
await accomplishTask(roleId, TASK_TYPE.EQUIP_QUALITY, 1, { quality: equip.quality })
return { seqId: equip.seqId, hid: hero.hid };
}