Files
ZYZ/game-server/app/services/rewardService.ts
2022-02-17 16:20:27 +08:00

637 lines
27 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 { ITID, CONSUME_TYPE, ITEM_TABLE, REDIS_KEY, TASK_TYPE, CURRENCY, CURRENCY_TYPE, MAIL_TYPE, HANDLE_REWARD_TYPE, HERO_SYSTEM_TYPE, CURRENCY_BY_TYPE, ITEM_CHANGE_REASON, TA_USERSET_TYPE, TA_EVENT } from './../consts';
import { EquipModel, EquipType } from './../db/Equip';
import { getRandSingleEelm, resResult } from '../pubUtils/util';
import { RoleModel, RoleType } from '../db/Role';
import { setAp } from './actionPointService';
import { pushCalPlayerCe, 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 { checkActivityTask, checkTaskWithHero, pushActivityUpdate, 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 { calEquipSeids } from '../pubUtils/playerCe';
import { CreateHeroes } from '../pubUtils/roleUtil';
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';
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;
}
}
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;
}
}
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 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(pinus, sid);
await createHero.updateRedisRank(Rank);
heroes = createHero.getShowHeroes();
resultHeroes = createHero.getResultHeroes();
}
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);
}
}