import { ITID, CONSUME_TYPE, ITEM_TABLE, 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, ROLE_SELECT, FIGURE_UNLOCK_CONDITION, PUSH_ROUTE, ACTIVITY_TYPE } from '../../consts'; import { getDecimalCnt, getRandEelm, getRandEelmWithWeight, getRandValueByMinMax, } from '../../pubUtils/util'; import { RoleModel, RoleType } from '../../db/Role'; import { setAp } from '../actionPointService'; import { ItemModel, } from '../../db/Item'; import { ItemInter, } from '../../pubUtils/interface'; import { gameData, getDefArtifactByGid } from '../../pubUtils/data'; import { uniq } from 'underscore'; import { EPlace, HeroModel, HeroType, } from '../../db/Hero'; import { Figure } from '../../domain/dbGeneral'; import { ArtifactParam, JewelParam } from '../../domain/roleField/hero'; import { HeroSkin } from '../../db/Hero'; import { BAG } from '../../pubUtils/dicParam'; import { sendMailByContent } from '../mailService'; import { SkinModel, } from '../../db/Skin'; import { reportTAEvent, reportTAUserSet } from '../sdkService'; import { saveCoinChangeLog, saveFigureInfoLog, saveGoldChangeLog, saveItemChangeLog } from '../../pubUtils/logUtil'; import { JewelModel, JewelType, jewelUpdate, RandSe } from '../../db/Jewel'; import { updateEplaces } from '../equipService'; import { combineItems, getCoinEventProperties, getGoldEventProperties, sortItems } from './util'; import { nowSeconds } from '../../pubUtils/timeUtil'; import { calculateCeWithHero, calculateCeWithRole } from '../playerCeService'; import { sendMessageToUserWithSuc } from '../pushService'; import { filterGoods } from '../dataService'; import { ArtifactModel, ArtifactModelType, ArtifactModelUpdate } from '../../db/Artifact'; import { ActivityItemModel } from '../../db/ActivityItem'; import { getActivitiesByType } from '../activity/activityService'; import { ActivityModelType } from '../../db/Activity'; import { ForgeData } from '../../domain/activityField/forgeField'; import { getRoleCreateTime, getServerCreateTime } from '../redisService'; export async function handleCost(roleId: string, sid: string, goods: Array, reason: ITEM_CHANGE_REASON) { let { items, jewels, gold, coin, artifacts, activityItems } = sortItems(goods, HANDLE_REWARD_TYPE.COST); let jewelSeqIds = jewels.map(cur => cur.seqId); let resJewels: JewelType[] = []; let artifactSeqIds = artifacts.map(cur => cur.seqId); let resArtifacts: ArtifactModelType[] = []; // 检查货币是否充足 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 (artifacts.length > 0) { resArtifacts = await ArtifactModel.findbySeqIds(roleId, artifactSeqIds); if (resArtifacts.length < artifacts.length) return false; } //检查并修改道具 if (items.length > 0) { let { hasError, result } = await ItemModel.decreaseItems(roleId, items); if (hasError) return false; sendMessageToUserWithSuc(roleId, PUSH_ROUTE.ITEM_UPDATE, { goods: result.map(cur => ({...cur, reason })) }, sid); saveItemChangeLog(roleId, result, reason); } //检查并修改道具 if (activityItems.length > 0) { let { hasError, result } = await ActivityItemModel.decreaseActivityItems(roleId, activityItems); if (hasError) return false; sendMessageToUserWithSuc(roleId, PUSH_ROUTE.ACTIVITY_ITEM_UPDATE, { goods: result.map(cur => ({...cur, reason })) }, sid); saveItemChangeLog(roleId, result, reason); } //删除装备 if (resJewels.length > 0) { let heroMap = new Map(); 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>(); 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 calculateCeWithHero(HERO_SYSTEM_TYPE.EQUIP_STRENGTH, roleId, role.serverId, sid, hid, { ePlace: newEplace }, { ePlaceIds: [...update.keys()] }); } let jewels = await JewelModel.deleteBySeqIds(roleId, jewelSeqIds); saveItemChangeLog(roleId, jewels.map(jewel => ({ id: jewel.id, count: 1, inc: -1 })), reason); sendMessageToUserWithSuc(roleId, PUSH_ROUTE.JEWEL_DEL, { jewels: jewels.map(jewel => ({ seqId: jewel.seqId, id: jewel.id, inc: -1, reason })) }, sid); } //删除宝物 if (resArtifacts.length > 0) { let heroMap = new Map(); for(let artifact of resArtifacts) { if(artifact.hid > 0) { heroMap.set(artifact.hid, { artifact }); } } for(let [hid, { artifact } ] of heroMap) { // 脱下天晶石 await ArtifactModel.putOnOrOff(roleId, artifact.id, 0); await calculateCeWithHero(HERO_SYSTEM_TYPE.PUT_ARTIFACT, roleId, role.serverId, sid, hid, { artifact: 0 }); } let artifacts = await ArtifactModel.deleteBySeqIds(roleId, artifactSeqIds); saveItemChangeLog(roleId, artifacts.map(artifact => ({ id: artifact.id, count: 1, inc: -1 })), reason); sendMessageToUserWithSuc(roleId, PUSH_ROUTE.ARTIFACT_DEL, { artifacts: artifacts.map(artifact => ({ seqId: artifact.seqId, id: artifact.id, inc: -1, reason })) }, sid); } //消耗玩家货币 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); sendMessageToUserWithSuc(roleId, PUSH_ROUTE.PLAYER_DATA_CHANGE, { gold: role.gold, coin: role.coin, totalCost: role.totalCost }, sid); 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; } export async function addItems(roleId: string, roleName: string, sid: string, goods: Array, reason: ITEM_CHANGE_REASON) { goods = filterGoods(goods, obj => obj.id, roleId, reason); let { items, jewels, gold, coin, ap, skins, figures, artifacts, activityItems } = sortItems(goods, HANDLE_REWARD_TYPE.RECEIVE); let showItems: { id: number, seqId?: number|string, count: number, isBag?: boolean, expireTime?: number }[] = []; let role = await RoleModel.findByRoleId(roleId, '-warCount -topLineup'); // 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 } = await addJewels(roleId, roleName, <{id: 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) sendMessageToUserWithSuc(roleId, PUSH_ROUTE.JEWEL_ADD, { jewelInfos }, sid); //统计装备 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) { sendMessageToUserWithSuc(roleId, PUSH_ROUTE.ITEM_UPDATE, { goods: itemInfos }, sid); saveItemChangeLog(roleId, itemInfos, reason); } } // 3. 货币推送 if(gold.length > 0 || coin.length > 0 || ap > 0) { await setAp(role.serverId, 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); sendMessageToUserWithSuc(roleId, PUSH_ROUTE.PLAYER_DATA_CHANGE, { gold: role.gold, coin: role.coin }, sid); 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 hero = await addSkin(roleId, roleName, role.serverId, sid, skinId, false); skinInfos.push({ id: skinId, hid: hero? hero.hid: 0, count: 1, inc: 1, reason }) showItems.push({ id: skinId, count: 1 }); if(hero) heroskins.push({ skins: hero.skins, hid: hero.hid }); } if (!!skinInfos.length) { pushHeroSkinMsg(heroskins, skinInfos, roleId, sid); // 推送onHeroSkinChange saveItemChangeLog(roleId, skinInfos, reason); } } // 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) { sendMessageToUserWithSuc(roleId, PUSH_ROUTE.HEAD_CHANGE, { ...figureInfo }, sid); saveFigureInfoLog(roleId, figureInfo, reason) } } // 6. 宝物处理 if(artifacts.length > 0) { let { artifactCount = 0 } = role; let incArtifacts = artifacts, mailArtifacts: { id?: number, seqId?: number|string }[] = []; if(artifacts.length + artifactCount > BAG.BAG_ARTIFACT_UPLIMITED) { // 装备上限 let inc = BAG.BAG_ARTIFACT_UPLIMITED - artifactCount; if(inc < 0) inc = 0; incArtifacts = artifacts.slice(0, inc); mailArtifacts = artifacts.slice(inc); } // 直接加的 let { artifacts: artifactInfos } = await addArtifacts(roleId, roleName, <{id: number}[]>incArtifacts, reason); for (let artifact of artifactInfos) { showItems.push({ seqId: artifact.seqId, id: artifact.id, count: 1, isBag: true }); } for(let artifact of combineItems(mailArtifacts)) { showItems.push({ id: artifact.id, count: artifact.count, isBag: false }); } //装备推送 if (!!artifactInfos.length) sendMessageToUserWithSuc(roleId, PUSH_ROUTE.ARTIFACT_ADD, { artifacts: artifactInfos }, sid); //统计装备 if (artifactInfos.length > 0) { saveItemChangeLog(roleId, artifactInfos, reason); } // 发邮件的 if(mailArtifacts.length > 0) { await sendMailByContent(MAIL_TYPE.ARTIFACT_OVER, roleId, { goods: combineItems(mailArtifacts) }); } } // 7. 活动道具处理 if(activityItems.length > 0) { let { items: itemInfos } = await addActivityItems(role, activityItems, reason); for (let item of itemInfos) { showItems.push({ id: item.id, count: item.inc, expireTime: item.expireTime }); } //背包除去装备推送 if (!!itemInfos.length) { sendMessageToUserWithSuc(roleId, PUSH_ROUTE.ACTIVITY_ITEM_UPDATE, { goods: itemInfos }, sid); saveItemChangeLog(roleId, itemInfos, reason); } } return showItems; } export async function checkGoods(roleId: string, goodIds: Array) { let jewelSeqIds: Array = []; let itemIds: Array = []; let hids: Array = []; 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); } /** * 解锁头像/相框 * @param roleId 玩家id * @param conditions 解锁条件 * @param role 如果已查询过role表就直接可以使用 */ export async function unlockFigure(sid: string, roleId: string, conditions: { type: number, paramHid?: number, paramFavourLv?: number, paramSkinId?: number, paramWinStreakNum?: number }[], role?: RoleType) { if (!role || !role.heads || !role.frames) { role = await RoleModel.findByRoleId(roleId, ROLE_SELECT.GET_HEADS); } let { figureInfo, heads, frames, spines } = unlockFigureWithoutSave(conditions, role); role = await RoleModel.updateRoleInfo(roleId, { heads, frames, spines }); if (!!figureInfo && (figureInfo.heads.length > 0 || figureInfo.frames.length > 0 || figureInfo.spines.length > 0)) { sendMessageToUserWithSuc(roleId, PUSH_ROUTE.HEAD_CHANGE, { ...figureInfo }, sid); } } /** * 皮肤数据变化去重、推送 * @param heroskins 推送的皮肤 * @param roleId 玩家 */ function pushHeroSkinMsg(heroskins: {skins: HeroSkin[], hid: number}[], skinInfos: {id: number, hid: number }[], roleId: 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) { sendMessageToUserWithSuc(roleId, PUSH_ROUTE.HERO_SKIN_CHANGE, { heros: heroskins, skins: skinInfos }, sid); } } /** * 只插入皮肤,不管那么多的 * @param roleId * @param roleName * @param skinId * @returns */ export async function increaseSkin(roleId:string, roleName: string, skinId: number) { let dicSkin = gameData.fashion.get(skinId); if (!dicSkin) return false; let skin = await SkinModel.increaseSkin(roleId, skinId, { roleId, roleName, id: skinId, skinName: dicSkin.name, hid: dicSkin.actorId, skinId: dicSkin.heroId }); if(!skin) return false; // 插入失败 return skin } /** * 添加皮肤 * @param roleId 玩家id * @param roleName 玩家名 * @param id 皮肤id * @param hero 武将,如果已经查询过这个武将就不用再查询一次,主意要select skins字段 * @returns {{ hero, figureInfo, calAllHeroResult }} hero:添加皮肤后的武将 figureInfo: 触发头像添加信息 calAllHeroResult:全局战力加成后结果 */ export async function addSkin(roleId: string, roleName: string, serverId: number, sid: string, skinId: number, enable: boolean, hero?: HeroType) { let skin = await increaseSkin(roleId, roleName, skinId); if(!skin) return false; if(skin.hid && !hero) hero = await HeroModel.findByHidAndRole(skin.hid, roleId); let condition = { type: FIGURE_UNLOCK_CONDITION.GET_SKIN, paramSkinId: skinId }; await unlockFigure(sid, roleId, [condition]); // 解锁头像 await calculateCeWithRole(HERO_SYSTEM_TYPE.ADD_SKIN, roleId, serverId, sid, {}, { skinId }); // 全局加成 if (hero) { // 有武将的,将皮肤链接到武将上 let curSkin = hero.skins.find(cur => cur.id == skinId); if (!curSkin) { hero.skins.push(new HeroSkin(skin, enable)); await HeroModel.updateHeroInfo(roleId, hero.hid, hero); } return hero; } else { return null } } export async function addBags(roleId: string, roleName: string, datas: { id: number, count: number }[], reason: number) { let items: { id: number, count: number, inc: number }[] = []; for(let data of datas) { let item = await addBag(roleId, roleName, data, reason); items.push(item) } return { items } } export async function addBag(roleId: string, roleName: string, data: { id: number, count: number }, reason: number) { let { id, count } = data; let { name: itemName, itid, hid } = gameData.goods.get(id); let { type } = ITID.get(itid); let item = await ItemModel.increaseItem(roleId, id, count, { roleId, roleName, itemName, id, type, hid }); return { id: item.id, count: item.count, inc: count, reason }; } export async function addActivityItems(role: RoleType, datas: { id: number, count: number }[], reason: number) { let serverTime = await getServerCreateTime(role.serverId); let createTime = await getRoleCreateTime(role.roleId, role); let items: { id: number, count: number, inc: number, expireTime: number }[] = []; for(let data of datas) { let item = await addActivityItem(role.serverId, role.roleId, role.roleName, data, reason, createTime, serverTime); if(item) items.push(item) } return { items } } export async function addActivityItem(serverId: number, roleId: string, roleName: string, data: { id: number, count: number }, reason: number, createTime: number, serverTime: number) { let { id, count } = data; let { name: itemName, activityType } = gameData.goods.get(id); let activities = await getActivitiesByType(serverId, activityType); for(let activity of activities) { let activityData = getActivityData(activity, createTime, serverTime); if(!activityData || !activityData.canShow()) continue; let item = await ActivityItemModel.increaseActivityItem(roleId, id, count, { roleId, roleName, itemName, id, expireTime: Math.floor(activityData.nextRefreshTime/1000) }); return { id: item.id, count: item.count, inc: count, expireTime: item.expireTime, reason }; } } function getActivityData(activity: ActivityModelType, createTime: number, serverTime: number) { switch(activity.type) { case ACTIVITY_TYPE.FORGE: return new ForgeData(activity, createTime, serverTime) default: return null } } export async function addJewels(roleId: string, roleName: string, jewels: { id: number, }[], reason: number) { let jewelInfo: jewelUpdate[] = []; for(let jewel of jewels) { let info = await getAddJewelInfo(roleId, roleName, jewel); jewelInfo.push(info); } const jewelResult = await JewelModel.createJewels(roleId, jewelInfo); return { jewels: jewelResult.map(jewel => new JewelParam(jewel, true, reason))} } export async function getAddJewelInfo(roleId: string, roleName: string, jewel: { id: number, }) { let { id, } = jewel; let { name, randomEffect, effectCount, rareEffect } = gameData.jewel.get(id); // 随机属性 let randomResult: number[] = getRandEelm(randomEffect, effectCount); let rareResult: number[] = getRandEelm(rareEffect, 1); let randSe: Array = randomResult.map((id: number, index: number) => { return getJewelRandSe(index + 1, id); }); let rareSe: Array = rareResult.map((id: number, index: number) => { return getJewelRandSe(index + 1, id); }); return { roleId, roleName, id, name, randSe, rareSe }; } /** * 天晶石已知词条随机值 * @param id 词条位置,第几条 * @param seid 词条id * @returns */ export function getJewelRandSe(id: number, seid: number) { let dicRandom = gameData.randomEffectPool.get(seid) // console.log('#### dicRandom', dicRandom) let rand = 0; let planPool = gameData.randomEffectPoolPlan.get(dicRandom.planId); if(planPool && planPool.length > 0) { let result = getRandEelmWithWeight(planPool); if(result) rand = Math.round(result.dic.num * 100)/100; } else { let randResult = getRandValueByMinMax(dicRandom.Min, dicRandom.Max, getDecimalCnt(dicRandom.gap)); let n = Math.floor((randResult - dicRandom.Min)/dicRandom.gap); rand = Math.round(dicRandom.Min + n * dicRandom.gap * 100)/100; } return new RandSe(id, dicRandom.id, rand); } export async function addArtifacts(roleId: string, roleName: string, artifacts: { id: number, }[], reason: number) { let artifactInfos: ArtifactModelUpdate[] = []; for(let { id } of artifacts) { let dicArtifact = getDefArtifactByGid(id); if(dicArtifact) { let { goodId, artifactId, quality, qualityStage } = dicArtifact; artifactInfos.push({ roleId, roleName, id: goodId, artifactId, quality, qualityStage }); } } const artifactResult = await ArtifactModel.createArtifacts(roleId, artifactInfos); return { artifacts: artifactResult.map(artifact => new ArtifactParam(artifact, true, reason))} } export function getGoldId() { return CURRENCY_BY_TYPE.get(CURRENCY_TYPE.GOLD); } /** * @description 获取元宝物品 { id, count } * @param count 元宝数量 */ export function getGoldObject(count: number) { return { id: CURRENCY_BY_TYPE.get(CURRENCY_TYPE.GOLD), count }; } /** * @description 获取金币物品 { id, count } * @param count 元宝数量 */ export function getCoinObject(count: number) { return { id: CURRENCY_BY_TYPE.get(CURRENCY_TYPE.COIN), count }; } /** * @description 获取体力物品 { id, count } * @param count 体力数量 */ export function getApObject(count: number) { return { id: CURRENCY_BY_TYPE.get(CURRENCY_TYPE.ACTION_POINT), count }; } /** * @description 获取友情点物品 { id, count } * @param count 友情点数量 */ export function getFriendPointObject(count: number) { return { id: CURRENCY_BY_TYPE.get(CURRENCY_TYPE.FRIEND_POINT), count }; } /** * @description 获取功勋物品 { id, count } * @param count 功勋数量 */ export function getHonourObject(count: number) { return { id: CURRENCY_BY_TYPE.get(CURRENCY_TYPE.HONOUR), count }; } /** * @description 获取代金券物品 { id, count } * @param count 元宝数量 */ export function getVoucherObject(count: number) { return { id: CURRENCY_BY_TYPE.get(CURRENCY_TYPE.VOUCHER), count }; } export function getVoucherCoinObject(count: number) { return { id: CURRENCY_BY_TYPE.get(CURRENCY_TYPE.VOUCHER_COIN), count }; } export function checkVoucherId(id: number) { let voucher = CURRENCY_BY_TYPE.get(CURRENCY_TYPE.VOUCHER); let voucherCoin = CURRENCY_BY_TYPE.get(CURRENCY_TYPE.VOUCHER_COIN); return id == voucher || id == voucherCoin; } /** * 返回 解锁头像/相框 * @param conditions 解锁条件 * @param role 如果已查询过role表就直接可以使用 */ export function unlockFigureWithoutSave(conditions: { type: number, paramHid?: number, paramFavourLv?: number, paramSkinId?: number, paramWinStreakNum?: number }[], role: RoleType) { let { heads, frames, spines, roleId } = role; let figureInfo = { heads: new Array
(), frames: new Array
(), spines: new Array
() }; for (let { type, paramHid, paramFavourLv, paramSkinId, paramWinStreakNum } of conditions) { let canUnLockList = gameData.figureCondition.get(type); if (canUnLockList) { canUnLockList = filterGoods(canUnLockList, obj => obj.gid, roleId, ITEM_CHANGE_REASON.GET_HERO_UNLOCK_FIGURE); let reason = 0; for (let { id, params, gid } of canUnLockList) { let flag = false; // 是否达成条件 if (type == FIGURE_UNLOCK_CONDITION.GET_HERO) { let [hid] = params; if (paramHid == hid) flag = true; reason = ITEM_CHANGE_REASON.GET_HERO_UNLOCK_FIGURE; } else if (type == FIGURE_UNLOCK_CONDITION.HERO_FAVOR) { let [hid, favourLv] = params; if (paramHid == hid && paramFavourLv >= favourLv) flag = true; reason = ITEM_CHANGE_REASON.HERO_FAVOR_UNLOCK_FIGURE; } else if (type == FIGURE_UNLOCK_CONDITION.GET_SKIN) { let [id] = params; if (paramSkinId == id) flag = true; reason = ITEM_CHANGE_REASON.ADD_SKIN_UNLOCK_FIGURE; } else if (type == FIGURE_UNLOCK_CONDITION.PVP_WIN_SERIES) { let [winStreakNum] = params; if (paramWinStreakNum >= winStreakNum) flag = true; reason = ITEM_CHANGE_REASON.PVP_SERIES_UNLOCK_FIGURE; } if (!flag) continue; let dicGood = gameData.goods.get(gid); if (!dicGood) continue; let dicItid = ITID.get(dicGood.itid); if (!dicItid) continue; if (dicItid.type == CONSUME_TYPE.HEAD) { let figure = unlockSingleFigure(heads, gid, reason, false, id); if (figure && figure.unlocked) figureInfo.heads.push(figure); } else if (dicItid.type == CONSUME_TYPE.FRAME) { let figure = unlockSingleFigure(frames, gid, reason, false, id); if (figure && figure.unlocked) figureInfo.frames.push(figure); } else if (dicItid.type == CONSUME_TYPE.SPINE) { let figure = unlockSingleFigure(spines, gid, reason, false, id); if (figure && figure.unlocked) figureInfo.spines.push(figure); } else { continue; } } } } return { figureInfo, heads, frames, spines }; } // 直接获得形象/相框 export async function addFigure(roleId: string, ids: number[], reason: number) { let role = await RoleModel.findByRoleId(roleId, ROLE_SELECT.GET_HEADS); if (!role) return false; let { heads, frames, spines } = role; let figureInfo = { heads: [], frames: [], spines: [] }; for (let gid of ids) { let dicGoods = gameData.goods.get(gid); if (!dicGoods) continue; let dicItid = ITID.get(dicGoods.itid); if (!dicItid) continue; if (dicItid.type == CONSUME_TYPE.HEAD) { let figure = unlockSingleFigure(heads, gid, reason, true); if (figure && figure.unlocked) figureInfo.heads.push(figure); } else if (dicItid.type == CONSUME_TYPE.FRAME) { let figure = unlockSingleFigure(frames, gid, reason, true); if (figure && figure.unlocked) figureInfo.frames.push(figure); } else if (dicItid.type == CONSUME_TYPE.SPINE) { let figure = unlockSingleFigure(spines, gid, reason, true); if (figure && figure.unlocked) figureInfo.spines.push(figure); } else { continue; } } role = await RoleModel.updateRoleInfo(roleId, { heads, frames, spines }); return figureInfo; } /** * 根据物品id解锁/获得玩家数据 * @param dbFigures 数据库内字段 * @param id 物品id * @param unlockDirect 是否不计算解锁条件直接解锁 * @param conditionId 条件id */ function unlockSingleFigure(dbFigures: Figure[], id: number, reason: number, unlockDirect = false, conditionId?: number) { let index = dbFigures.findIndex(cur => cur.id == id); let figure = dbFigures[index]; if (index == -1) { figure = new Figure(id, false); dbFigures.push(figure); index = dbFigures.length - 1; } if (figure.unlocked) return; // 已解锁过 if (!figure.unlockedId) figure.unlockedId = new Array(); let dicGoods = gameData.goods.get(id); let hasUnlockedAll = true; if (!unlockDirect) { // 不能直接获得,需要通过type解锁 if (figure.unlockedId.includes(conditionId)) return; figure.unlockedId.push(conditionId); for (let { id: cid } of dicGoods.condition) { if (!figure.unlockedId.includes(cid)) { hasUnlockedAll = false; break; } } } if (hasUnlockedAll) { figure.unlocked = true; delete figure.unlockedId; if (dicGoods.timeLimit) { figure.time = nowSeconds() + dicGoods.timeLimit * 86400 } } figure.inc = 1; figure.reason = reason; dbFigures[index] = figure; return figure } // async function getSkinsOfThisHero(roleId: string, roleName: string, hid: number, initialSkin: number, allSkins?: SkinType[]) { // if(!allSkins) allSkins = await SkinModel.findbyRoleAndHid(roleId, hid); // let skin = await increaseSkin(roleId, roleName, initialSkin); // if(skin) allSkins.push(skin); // let skins: { id: number, skin: string, enable: boolean }[] = []; // for(let skin of allSkins) { // skins.push({ id: skin.id, skin: skin._id, enable: skin.id == initialSkin }); // } // return skins // } export function combineFigureInfo(figureInfos: { heads: Figure[], frames: Figure[], spines: Figure[] }[]) { let figureInfo = { heads: new Array
(), frames: new Array
(), spines: new Array
() }; for(let {heads, frames, spines} of figureInfos) { for(let head of heads) { figureInfo.heads.push(head); } for(let frame of frames) { figureInfo.frames.push(frame); } for(let spine of spines) { figureInfo.spines.push(spine); } } return figureInfo; } // export class CreateHero { // roleId: string; // roleName: string; // serverId: number; // constructor(roleId: string, roleName: string, serverId: number) { // } // }