133 lines
6.5 KiB
TypeScript
133 lines
6.5 KiB
TypeScript
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 };
|
||
} |