移动rewardService的位置
This commit is contained in:
@@ -0,0 +1,644 @@
|
||||
import { ITID, CONSUME_TYPE, ITEM_TABLE, CURRENCY, CURRENCY_TYPE, MAIL_TYPE, HANDLE_REWARD_TYPE, HERO_SYSTEM_TYPE, CURRENCY_BY_TYPE, ITEM_CHANGE_REASON, TA_USERSET_TYPE, TA_EVENT, POP_UP_SHOP_CONDITION_TYPE } from '../../consts';
|
||||
import { getRandSingleEelm, resResult } from '../../pubUtils/util';
|
||||
import { RoleModel, RoleType } from '../../db/Role';
|
||||
import { setAp } from '../actionPointService';
|
||||
import { pushCalAllHeroCe, calPlayerCeAndSave } from '../playerCeService';
|
||||
import { ItemModel, ItemType } from '../../db/Item';
|
||||
import { STATUS } from '../../consts/statusCode';
|
||||
import { pinus } from 'pinus';
|
||||
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';
|
||||
import { EPlace, HeroModel, HeroType, HeroUpdate } from '../../db/Hero';
|
||||
import { Figure } from '../../domain/dbGeneral';
|
||||
import { Rank } from '../rankService';
|
||||
import { pushTaskUpdate } from '../taskService';
|
||||
import { CreateHeroParam, HeroShowParam } from '../../domain/roleField/hero';
|
||||
import { HeroSkin } from '../../db/Hero';
|
||||
import { errlogger } from '../../util/logger';
|
||||
import { BAG } from '../../pubUtils/dicParam';
|
||||
import { sendMailByContent } from '../mailService';
|
||||
import { SkinUpdate } from '../../db/Skin';
|
||||
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';
|
||||
import { updateEplaces } from '../equipService';
|
||||
import { checkPopUpConditionInCreateHero } from '../activity/popUpShopService';
|
||||
import { CreateHeroes } from './createHero';
|
||||
|
||||
export class CheckMeterial {
|
||||
private roleId: string;
|
||||
private itemsIndb: Map<number, number> = new Map(); // 玩家已有的东西
|
||||
private notEnoughItems: Map<number, number> = new Map(); // 缺少的数量
|
||||
private consumes: ItemInter[] = []; // 消耗,正向数
|
||||
|
||||
private goldId = CURRENCY_BY_TYPE.get(CURRENCY_TYPE.GOLD);
|
||||
private coinId = CURRENCY_BY_TYPE.get(CURRENCY_TYPE.COIN);
|
||||
|
||||
constructor(roleId: string, role?: RoleType, items?: ItemType[]) {
|
||||
this.roleId = roleId;
|
||||
if(role) {
|
||||
this.itemsIndb.set(this.goldId, role.gold);
|
||||
this.itemsIndb.set(this.coinId, role.coin);
|
||||
}
|
||||
if(items && items.length) {
|
||||
for(let {id, count} of items) {
|
||||
this.itemsIndb.set(id, count);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private pushToNotEnoughItems(id: number, count: number) {
|
||||
if(!this.notEnoughItems.has(id)) {
|
||||
this.notEnoughItems.set(id, 0);
|
||||
}
|
||||
this.notEnoughItems.set(id, this.notEnoughItems.get(id) + count);
|
||||
}
|
||||
|
||||
private getNotEnoughItems() {
|
||||
let map = new Map<number, number>();
|
||||
for(let [ id, count ] of this.notEnoughItems) {
|
||||
map.set(id, count);
|
||||
}
|
||||
return map;
|
||||
}
|
||||
|
||||
public async decrease(goods: {id: number, count: number}[]) {
|
||||
this.notEnoughItems.clear();
|
||||
let { items, gold, coin } = sortItems(goods, HANDLE_REWARD_TYPE.COST);
|
||||
let isEnough = true;
|
||||
for(let { id, count} of items) {
|
||||
if(!this.itemsIndb.has(id)) {
|
||||
let item = await ItemModel.findbyRoleAndGid(this.roleId, id);
|
||||
if(!item) {
|
||||
this.pushToNotEnoughItems(id, count);
|
||||
isEnough = false; break;
|
||||
}
|
||||
this.itemsIndb.set(id, item.count);
|
||||
}
|
||||
if(this.itemsIndb.get(id) < count) {
|
||||
this.pushToNotEnoughItems(id, count - this.itemsIndb.get(id));
|
||||
isEnough = false; break;
|
||||
}
|
||||
this.itemsIndb.set(id, this.itemsIndb.get(id) - count);
|
||||
}
|
||||
|
||||
if(gold.length > 0) {
|
||||
if(!this.itemsIndb.has(this.goldId)) {
|
||||
let role = await RoleModel.findByRoleId(this.roleId, 'gold coin');
|
||||
this.itemsIndb.set(this.goldId, role.gold);
|
||||
this.itemsIndb.set(this.coinId, role.coin);
|
||||
}
|
||||
let goldCost = gold.reduce((pre, cur) => { return pre + cur.count }, 0);
|
||||
if(this.itemsIndb.get(this.goldId) < goldCost) {
|
||||
this.pushToNotEnoughItems(this.goldId, goldCost - this.itemsIndb.get(this.goldId));
|
||||
isEnough = false;
|
||||
}
|
||||
this.itemsIndb.set(this.goldId, this.itemsIndb.get(this.goldId) - goldCost);
|
||||
}
|
||||
if(isEnough && coin.length > 0) {
|
||||
if(!this.itemsIndb.has(this.coinId)) {
|
||||
let role = await RoleModel.findByRoleId(this.roleId, 'gold coin');
|
||||
this.itemsIndb.set(this.goldId, role.gold);
|
||||
this.itemsIndb.set(this.coinId, role.coin);
|
||||
}
|
||||
let coinCost = coin.reduce((pre, cur) => pre + cur, 0);
|
||||
if(this.itemsIndb.get(this.coinId) < coinCost) {
|
||||
this.pushToNotEnoughItems(this.coinId, coinCost - this.itemsIndb.get(this.coinId));
|
||||
isEnough = false;
|
||||
}
|
||||
this.itemsIndb.set(this.coinId, this.itemsIndb.get(this.coinId) - coinCost);
|
||||
}
|
||||
|
||||
if(isEnough) this.consumes.push(...goods);
|
||||
return isEnough;
|
||||
}
|
||||
|
||||
private getMaterialEnough(materials: RewardInter[], notEnoughItems: Map<number, number>) {
|
||||
let newMaterials: RewardInter[] = [];
|
||||
for(let {id, count} of materials) {
|
||||
if(notEnoughItems.has(id)) {
|
||||
newMaterials.push({ id, count: count - notEnoughItems.get(id) });
|
||||
} else {
|
||||
newMaterials.push({ id, count });
|
||||
}
|
||||
}
|
||||
return newMaterials;
|
||||
}
|
||||
|
||||
// 检查地玉石是否可以合成
|
||||
public async composeStone(id: number, count: number) {
|
||||
let dicStone = gameData.stone.get(id);
|
||||
if(!dicStone || dicStone.composeMaterial.length <= 0) return false; // 1阶石头不能再从下合成返回不行
|
||||
let materials = dicStone.composeMaterial.map(cur => ({...cur, count: cur.count * count }));
|
||||
let isEnough = await this.decrease(materials);
|
||||
if(!isEnough) {
|
||||
let notEnoughItems = this.getNotEnoughItems();
|
||||
let newMaterials = this.getMaterialEnough(materials, notEnoughItems);
|
||||
let isEnough = await this.decrease(newMaterials); // 消耗掉除了不足的部分以外的其他部分
|
||||
if(!isEnough) return false;
|
||||
|
||||
let isAllOK = true; // 如果有石头不足,向下补充,isAllOK标识不足的都能补充上
|
||||
for(let [id, count] of notEnoughItems) {
|
||||
let isEnough = await this.composeStone(id, count);
|
||||
if(!isEnough) {
|
||||
isAllOK = false; break;
|
||||
}
|
||||
}
|
||||
return isAllOK;
|
||||
} else {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
public getConsume() {
|
||||
return this.consumes;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
export async function handleCost(roleId: string, sid: string, goods: Array<ItemInter>, reason: ITEM_CHANGE_REASON) {
|
||||
|
||||
let uids = [{ uid: roleId, sid }];
|
||||
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);
|
||||
if (gold.length > 0 || coin.length > 0) {
|
||||
let { gold: originGold, coin: originCoin } = role;
|
||||
for(let {count} of gold) { originGold -= count };
|
||||
for(let count of coin) { originCoin -= count };
|
||||
if(originGold < 0 || originCoin < 0) return false;
|
||||
}
|
||||
//检查装备是否存在
|
||||
if (jewels.length > 0) {
|
||||
resJewels = await JewelModel.findbySeqIds(jewelSeqIds);
|
||||
if (resJewels.length < jewels.length)
|
||||
return false;
|
||||
}
|
||||
//检查并修改道具
|
||||
if (items.length > 0) {
|
||||
let { hasError, result } = await ItemModel.decreaseItems(roleId, items);
|
||||
if (hasError) return false;
|
||||
pinus.app.get('channelService').pushMessageByUids('onItemUpdate', resResult(STATUS.SUCCESS, { goods: result.map(cur => ({...cur, reason })) }), uids);
|
||||
saveItemChangeLog(roleId, result, reason);
|
||||
}
|
||||
|
||||
//删除装备
|
||||
if (resJewels.length > 0) {
|
||||
let heroMap = new Map<number, { hero: HeroType, jewels: JewelType[]}>();
|
||||
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) {
|
||||
// 脱下天晶石
|
||||
let update = new Map<number, Partial<EPlace>>();
|
||||
for(let jewel of jewels) {
|
||||
await JewelModel.putOnOrOff(jewel.id, 0, 0);
|
||||
let curEquip = hero.ePlace.find(cur => cur.jewel == jewel.id);
|
||||
if(!!curEquip) {
|
||||
update.set(curEquip.id, { jewel: 0 });
|
||||
}
|
||||
}
|
||||
let { newEplace } = updateEplaces(hero.ePlace, update);
|
||||
await calPlayerCeAndSave(HERO_SYSTEM_TYPE.EQUIP_STRENGTH, sid, roleId, hero, { ePlace: newEplace }, [...update.keys()]);
|
||||
}
|
||||
|
||||
|
||||
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) {
|
||||
let costGold = gold.reduce((pre, cur) => pre + cur.count, 0);
|
||||
let costCoin = coin.reduce((pre, cur) => pre + cur, 0);
|
||||
role = await RoleModel.decreaseGoldAndCoin(roleId, gold, costCoin);
|
||||
pinus.app.get('channelService').pushMessageByUids('onPlayerDataChange', resResult(STATUS.SUCCESS, {
|
||||
gold: role.gold, coin: role.coin, totalCost: role.totalCost
|
||||
}), uids);
|
||||
|
||||
if(costGold > 0) {
|
||||
reportTAEvent(roleId, TA_EVENT.ITEM_CONSUME, getGoldEventProperties(costGold, role.gold, reason));
|
||||
reportTAUserSet(TA_USERSET_TYPE.SET, roleId, { current_gold: role.gold });
|
||||
saveGoldChangeLog(roleId, role.gold, -1 * costGold, reason);
|
||||
}
|
||||
if(costCoin > 0) {
|
||||
reportTAEvent(roleId, TA_EVENT.ITEM_CONSUME, getCoinEventProperties(costCoin, role.coin, reason));
|
||||
reportTAUserSet(TA_USERSET_TYPE.SET, roleId, { current_coin: role.coin });
|
||||
saveCoinChangeLog(roleId, role.coin, -1 * costCoin, reason);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
// TODO: sid 在方法内部获取,且不一定存在
|
||||
export async function addItems(roleId: string, roleName: string, sid: string, goods: Array<ItemInter>, reason: ITEM_CHANGE_REASON) {
|
||||
let uids = [{ uid: roleId, sid }];
|
||||
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(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;
|
||||
incJewels = jewels.slice(0, inc);
|
||||
mailJewels = jewels.slice(inc);
|
||||
}
|
||||
|
||||
// 直接加的
|
||||
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 jewel of combineItems(mailJewels)) {
|
||||
showItems.push({ id: jewel.id, count: jewel.count, isBag: false });
|
||||
}
|
||||
//装备推送
|
||||
if (!!jewelInfos.length)
|
||||
pinus.app.get('channelService').pushMessageByUids('onJewelAdd', resResult(STATUS.SUCCESS, { jewelInfos }), uids);
|
||||
pushTaskUpdate(roleId, sid, pushMessages);
|
||||
//统计装备
|
||||
if (jewelInfos.length > 0) {
|
||||
saveItemChangeLog(roleId, jewelInfos, reason);
|
||||
}
|
||||
// 发邮件的
|
||||
if(mailJewels.length > 0) {
|
||||
await sendMailByContent(MAIL_TYPE.EQUIP_OVER, roleId, { goods: combineItems(mailJewels) });
|
||||
}
|
||||
}
|
||||
|
||||
// 2. 道具处理
|
||||
if(items.length > 0) {
|
||||
let { items: itemInfos } = await addBags(roleId, roleName, items, reason);
|
||||
for (let item of items) {
|
||||
showItems.push({ id: item.id, count: item.count });
|
||||
}
|
||||
//背包除去装备推送
|
||||
if (!!itemInfos.length) {
|
||||
pinus.app.get('channelService').pushMessageByUids('onItemUpdate', resResult(STATUS.SUCCESS, { goods: itemInfos }), uids);
|
||||
saveItemChangeLog(roleId, itemInfos, reason);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// 3. 货币推送
|
||||
if(gold.length > 0 || coin.length > 0 || ap > 0) {
|
||||
await setAp(roleId, null, role.lv, ap, sid, reason);
|
||||
let incCoin = coin.reduce((pre, cur) => pre + cur, 0);
|
||||
let incGold = gold.reduce((pre, cur) => pre + cur.count, 0);
|
||||
role = await RoleModel.increaseGoldAndCoin(roleId, gold, incCoin);
|
||||
pinus.app.get('channelService').pushMessageByUids('onPlayerDataChange', resResult(STATUS.SUCCESS, {
|
||||
gold: role.gold, coin: role.coin
|
||||
}), uids);
|
||||
if(gold.length > 0) {
|
||||
gold.forEach(({ count }) => {
|
||||
showItems.push(getGoldObject(count));
|
||||
});
|
||||
reportTAEvent(roleId, TA_EVENT.ITEM_GET, getGoldEventProperties(incGold, role.gold, reason));
|
||||
reportTAUserSet(TA_USERSET_TYPE.SET, roleId, { current_gold: role.gold });
|
||||
saveGoldChangeLog(roleId, role.gold, incGold, reason );
|
||||
}
|
||||
if(coin.length > 0) {
|
||||
coin.forEach(count => {
|
||||
showItems.push(getCoinObject(count));
|
||||
});
|
||||
reportTAEvent(roleId, TA_EVENT.ITEM_GET, getCoinEventProperties(incCoin, role.coin, reason));
|
||||
reportTAUserSet(TA_USERSET_TYPE.SET, roleId, { current_coin: role.coin });
|
||||
saveCoinChangeLog(roleId, role.coin, incCoin, reason);
|
||||
}
|
||||
if(ap > 0) {
|
||||
showItems.push(getApObject(ap));
|
||||
}
|
||||
}
|
||||
|
||||
// 4. 皮肤处理
|
||||
let figureInfos:{ heads: Figure[], frames: Figure[], spines: Figure[] }[] = []; // 头像变化推送信息
|
||||
if(skins.length > 0) {
|
||||
let heroskins: {skins: HeroSkin[], hid: number}[] = []; // 皮肤推送信息
|
||||
let skinInfos: {id: number, hid: number, count: number, inc: number, reason: number }[] = [];
|
||||
let calAllHeroResult = undefined; // 全局战力变化推送
|
||||
|
||||
for (let skinId of skins) {//皮肤推送
|
||||
let result = await addSkin(roleId, roleName, skinId, false);
|
||||
if (!!result) {
|
||||
showItems.push({ id: skinId, count: 1 });
|
||||
figureInfos.push(result.figureInfo);
|
||||
if(result.hero) {
|
||||
heroskins.push({ skins: result.hero.skins, hid: result.hero.hid });
|
||||
if(result.calAllHeroResult) calAllHeroResult = result.calAllHeroResult;
|
||||
}
|
||||
skinInfos.push({ id: skinId, hid: result.hero?.hid||0, count: 1, inc: 1, reason })
|
||||
}
|
||||
}
|
||||
if (!!skinInfos.length) {
|
||||
pushHeroSkinMsg(heroskins, skinInfos, uids); // 推送onHeroSkinChange
|
||||
saveItemChangeLog(roleId, skinInfos, reason);
|
||||
}
|
||||
// 推送全局加成信息
|
||||
if(calAllHeroResult) await pushCalAllHeroCe(roleId, sid, calAllHeroResult);
|
||||
}
|
||||
|
||||
// 5. 获得头像和相框等
|
||||
if(figures.length > 0) {
|
||||
let figureInfo = await addFigure(roleId, figures, reason);
|
||||
if(figureInfo) figureInfos.push(figureInfo);
|
||||
for (let id of figures) {//皮肤推送
|
||||
showItems.push({ id, count: 1 });
|
||||
}
|
||||
}
|
||||
|
||||
// 获得头像或相框或形象推送
|
||||
if(!!figureInfos && figureInfos.length > 0) {
|
||||
for(let figureInfo of figureInfos) {
|
||||
pinus.app.get('channelService').pushMessageByUids('onHeadChange', resResult(STATUS.SUCCESS, { ...figureInfo }), uids);
|
||||
saveFigureInfoLog(roleId, figureInfo, reason)
|
||||
}
|
||||
}
|
||||
|
||||
return showItems;
|
||||
}
|
||||
|
||||
function getGoldEventProperties(inc: number, count: number, reason: ITEM_CHANGE_REASON) {
|
||||
let id = CURRENCY_BY_TYPE.get(CURRENCY_TYPE.GOLD);
|
||||
let dicGoods = gameData.goods.get(id);
|
||||
return { item_id: id, item_name: dicGoods.name, item_itid: dicGoods.itid, change_count: inc, change_after: count, change_reason: reason }
|
||||
}
|
||||
|
||||
function getCoinEventProperties(inc: number, count: number, reason: ITEM_CHANGE_REASON) {
|
||||
let id = CURRENCY_BY_TYPE.get(CURRENCY_TYPE.COIN);
|
||||
let dicGoods = gameData.goods.get(id);
|
||||
return { item_id: id, item_name: dicGoods.name, item_itid: dicGoods.itid, change_count: inc, change_after: count, change_reason: reason }
|
||||
}
|
||||
|
||||
export function combineItems(items: { id?: number, count?: number }[]) {
|
||||
let result: { id: number, count: number }[] = [];
|
||||
for(let { id, count = 1 } of items) {
|
||||
let index = result.findIndex(cur => cur.id == id);
|
||||
if(index == -1) {
|
||||
result.push({ id, count });
|
||||
} else {
|
||||
result[index].count += count;
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
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 != 'jewel') {
|
||||
let index = result.findIndex(cur => cur.id == id);
|
||||
if(index == -1) {
|
||||
result.push({ id, count });
|
||||
} else {
|
||||
result[index].count += count;
|
||||
}
|
||||
} else {
|
||||
result.push({ id, count });
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
function sortItems(goods: ItemInter[], handleType: HANDLE_REWARD_TYPE) {
|
||||
let items: { id: number, count: number }[] = []; // 可叠加道具
|
||||
let jewels: { seqId?: number, id?: number, hid?: number }[] = []; // 不可叠加装备
|
||||
let gold: { count: number, isPay: boolean }[] = []; // 金币
|
||||
let coin: number[] = [];
|
||||
let ap: number = 0;
|
||||
let skins: number[] = [];
|
||||
let figures: number[] = [];
|
||||
|
||||
for(let good of goods) {
|
||||
if(good.count == 0) continue;
|
||||
let dicGood = gameData.goods.get(good.id);
|
||||
if(!dicGood) {
|
||||
errlogger.error(`物品 ${good.id} 未配置`);
|
||||
continue;
|
||||
}
|
||||
let dicItid = ITID.get(dicGood.itid);
|
||||
if(!dicItid) {
|
||||
errlogger.error(`itid ${dicGood.itid} 未配置`);
|
||||
continue;
|
||||
}
|
||||
let { type, table, isCurrency } = dicItid;
|
||||
if(table == ITEM_TABLE.JEWEL) { // 装备
|
||||
if(handleType == HANDLE_REWARD_TYPE.RECEIVE) {
|
||||
for(let i = 0; i < good.count; i++) {
|
||||
jewels.push({ id: good.id, hid: good.hid })
|
||||
}
|
||||
} else {
|
||||
if(!!good.seqId) {
|
||||
jewels.push({ seqId: good.seqId });
|
||||
}
|
||||
}
|
||||
} else if (table == ITEM_TABLE.ITEM) { // 可叠加道具
|
||||
let index = items.findIndex(cur => cur.id == good.id);
|
||||
if(index > 0) {
|
||||
items[index].count += good.count;
|
||||
} else {
|
||||
items.push({ id: good.id, count: good.count });
|
||||
}
|
||||
} else if (table == ITEM_TABLE.SKIN) { // 皮肤,不可重复获得,不可删
|
||||
if(handleType == HANDLE_REWARD_TYPE.RECEIVE) {
|
||||
let index = skins.indexOf(good.id);
|
||||
if (index == -1) {
|
||||
skins.push(good.id);
|
||||
}
|
||||
}
|
||||
} else if (table == ITEM_TABLE.ROLE) {
|
||||
if(isCurrency) { // 3种货币
|
||||
let dicCurrency = CURRENCY.get(good.id);
|
||||
if(dicCurrency) {
|
||||
if(dicCurrency.type == CURRENCY_TYPE.GOLD) { // 金币,区分付费和免费,默认免费
|
||||
let index = gold.findIndex(cur => cur.isPay == !!good.isPay);
|
||||
if(index > 0) {
|
||||
gold[index].count += good.count;
|
||||
} else {
|
||||
gold.push({ count: good.count, isPay: !!good.isPay });
|
||||
}
|
||||
} else if (dicCurrency.type == CURRENCY_TYPE.COIN) { // 铜钱
|
||||
coin.push(good.count);
|
||||
} else if (dicCurrency.type == CURRENCY_TYPE.ACTION_POINT) { // 体力
|
||||
ap += good.count;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (type == CONSUME_TYPE.HEAD || type == CONSUME_TYPE.FRAME || type == CONSUME_TYPE.SPINE) { // 头像等,不可重复获得,不可删
|
||||
let index = figures.indexOf(good.id);
|
||||
if (index == -1) {
|
||||
figures.push(good.id);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return { items, jewels, gold, coin, ap, skins, figures }
|
||||
}
|
||||
|
||||
export async function checkGoods(roleId: string, goodIds: Array<number>) {
|
||||
let jewelSeqIds: Array<number> = [];
|
||||
let itemIds: Array<number> = [];
|
||||
let hids: Array<number> = [];
|
||||
goodIds = uniq(goodIds);
|
||||
for (let goodId of goodIds) {
|
||||
let goodInfo = gameData.goods.get(goodId);
|
||||
if (!!goodInfo) {
|
||||
let { table } = ITID.get(goodInfo.itid);
|
||||
if (table == ITEM_TABLE.EQUIP) {
|
||||
jewelSeqIds.push(goodId);
|
||||
} else if (table == ITEM_TABLE.ITEM) {
|
||||
itemIds.push(goodId);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//检查装备是否存在
|
||||
if (!!jewelSeqIds.length) {
|
||||
let resJewels = await JewelModel.findbySeqIds(jewelSeqIds);
|
||||
resJewels = uniq(resJewels, function (resEquip) {
|
||||
return resEquip.id;
|
||||
});
|
||||
if (resJewels.length < jewelSeqIds.length)
|
||||
return false;
|
||||
}
|
||||
//检查并修改道具
|
||||
if (itemIds.length > 0) {
|
||||
let items = await ItemModel.findbyRoleAndIds(roleId, itemIds);
|
||||
if (items.length < itemIds.length)
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
export async function checkHeroes(roleId: string, hids: number[]) {
|
||||
if (!!hids.length) {
|
||||
let heros = await HeroModel.findByHidRange(hids, roleId);
|
||||
if (heros.length < hids.length)
|
||||
return false;
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
export async function checkHeroEquips(roleId: string, quality: number) {
|
||||
return await HeroModel.checkEquipByQuality(roleId, quality);
|
||||
}
|
||||
|
||||
export async function unlockFigure(sid: string, roleId: string, conditions: { type: number, paramHid?: number, paramFavourLv?: number, paramSkinId?: number, paramWinStreakNum?: number }[], role?: RoleType) {
|
||||
let figureInfo = await pubUnlockFigure(roleId, conditions, role);
|
||||
await pushFigureUpdate(roleId, sid, figureInfo);
|
||||
}
|
||||
|
||||
export async function pushFigureUpdate(roleId: string, sid: string, figureInfo: { heads: Figure[], frames: Figure[], spines: Figure[] }) {
|
||||
if (!!figureInfo && (figureInfo.heads.length > 0 || figureInfo.frames.length > 0 || figureInfo.spines.length > 0)) {
|
||||
let uids = [{ uid: roleId, sid }];
|
||||
pinus.app.get('channelService').pushMessageByUids('onHeadChange', resResult(STATUS.SUCCESS, { ...figureInfo }), uids);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 创建多个武将
|
||||
* @param roleId
|
||||
* @param sid
|
||||
* @param serverId
|
||||
* @param heroInfo
|
||||
*/
|
||||
export async function createHeroes(roleId: string, roleName: string, sid: string, serverId: number, heroInfo: CreateHeroParam[]) {
|
||||
let hids = heroInfo.map(cur => cur.hid);
|
||||
let userHeroesMap = await HeroModel.findMapByHidRange(hids, roleId);
|
||||
|
||||
let infos: Map<number, { heroInfo: HeroUpdate, skinInfo: SkinUpdate }> = new Map(), pieces: ItemInter[] = [];
|
||||
for (let h of heroInfo) {
|
||||
let heroCount = h.count || 1;
|
||||
if (userHeroesMap.has(h.hid)) {
|
||||
let { pieceId, count } = transPiece(h.hid);
|
||||
pieces.push({ id: pieceId, count: count * heroCount });
|
||||
} else {
|
||||
let initInfo: { heroInfo: HeroUpdate, skinInfo: SkinUpdate };
|
||||
if(pinus.app.getServerType() == 'role') {
|
||||
initInfo = getInitHeroById(h.hid);
|
||||
} else {
|
||||
let roleServers = pinus.app.getServersByType('role');
|
||||
let server = getRandSingleEelm(roleServers);
|
||||
initInfo = await pinus.app.rpc.role.roleRemote.getInitHeroById.toServer(server.id, h.hid);
|
||||
}
|
||||
|
||||
initInfo.heroInfo = { ...initInfo.heroInfo, ...h };
|
||||
|
||||
infos.set(h.hid, initInfo);
|
||||
userHeroesMap.set(h.hid, null);
|
||||
if (heroCount > 1) {
|
||||
let { pieceId, count } = transPiece(h.hid);
|
||||
pieces.push({ id: pieceId, count: count * (heroCount - 1) });
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
let resultHeroes: HeroType[] = [], resultItems: RewardInter[] = [], heroes: HeroShowParam[] = [];
|
||||
if (infos.size > 0) {
|
||||
let createHero = new CreateHeroes(roleId, roleName, serverId);
|
||||
await createHero.createWithHeroInfo(infos);
|
||||
await createHero.clearTask(await getActivities())
|
||||
await createHero.pushMessage(sid);
|
||||
await createHero.updateRedisRank();
|
||||
heroes = createHero.getShowHeroes();
|
||||
resultHeroes = createHero.getResultHeroes();
|
||||
|
||||
await checkPopUpConditionInCreateHero(serverId, roleId, resultHeroes);
|
||||
}
|
||||
|
||||
if (pieces.length > 0) {
|
||||
let goods = await addItems(roleId, roleName, sid, pieces, ITEM_CHANGE_REASON.HERO_TRANSFER_PIECE);
|
||||
resultItems = goods;
|
||||
}
|
||||
return { heroes, resultHeroes, goods: resultItems }
|
||||
}
|
||||
|
||||
export async function createHero(roleId: string, roleName: string, sid: string, serverId: number, heroInfo: CreateHeroParam) {
|
||||
let result = await createHeroes(roleId, roleName, sid, serverId, [heroInfo]);
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* 皮肤数据变化去重、推送
|
||||
* @param heroskins 推送的皮肤
|
||||
* @param uids 玩家
|
||||
*/
|
||||
function pushHeroSkinMsg(heroskins: {skins: HeroSkin[], hid: number}[], skinInfos: {id: number, hid: number }[], uids: {uid: string, sid: string}[]) {
|
||||
let pushSkinInfos: {skins: HeroSkin[], hid: number}[] = []; // 可能会有重复的
|
||||
for(let { skins, hid } of heroskins) {
|
||||
let index = pushSkinInfos.findIndex(cur => cur.hid == hid);
|
||||
if(index == -1) {
|
||||
pushSkinInfos.push({skins, hid});
|
||||
} else {
|
||||
if(skins.length > pushSkinInfos[index].skins.length) {
|
||||
pushSkinInfos[index] = {skins, hid};
|
||||
}
|
||||
}
|
||||
}
|
||||
if(pushSkinInfos.length > 0 || skinInfos.length > 0) {
|
||||
pinus.app.get('channelService').pushMessageByUids('onHeroSkinChange', resResult(STATUS.SUCCESS, { heros: heroskins, skins: skinInfos }), uids);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user