import { HeroModel, HeroType } from '../db/Hero'; import { ItemModel } from '../db/Item'; import { EquipModel, RandSe, Holes, RandMain, equipUpdate } from './../db/Equip'; import { gameData, getQuenchByQualityAndGrade, getQuenchGradeByValue } from './data'; import { RANDOM_SE_COUNT, ITID, CURRENCY_BY_TYPE, CURRENCY_TYPE, ROLE_SELECT, FIGURE_UNLOCK_CONDITION, CONSUME_TYPE, HERO_SYSTEM_TYPE, TASK_TYPE } from '../consts'; import { getRandValueByMinMax, getRandEelm } from './util'; import { findWhere } from 'underscore'; import { RoleModel, RoleType } from '../db/Role'; import { Figure } from '../domain/dbGeneral'; import { getTimeFun, nowSeconds } from './timeUtil'; import { calPlayerCeAndSave, reCalAllHeroCe } from './playerCe'; import { checkTask, checkTaskWithHeroes, checkTaskWithEquip, accomplishTask } from './taskUtil'; import { CreateHeroParam } from '../domain/roleField/hero'; import { SkinModel } from '../db/Skin'; import { TaskListReturn } from '../domain/roleField/task'; /** * 添加皮肤 * @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, skinId: number, enable: boolean, hero?: HeroType) { 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 }); if(!skin) return false; // 插入失败 if(dicSkin.actorId && !hero) hero = await HeroModel.findByHidAndRole(dicSkin.actorId, roleId); let condition = { type: FIGURE_UNLOCK_CONDITION.GET_SKIN, paramSkinId: skinId }; let figureInfo = await unlockFigure(roleId, [condition]); // 解锁头像 let calAllHeroResult = await reCalAllHeroCe(HERO_SYSTEM_TYPE.ADD_SKIN, roleId, {}, [skinId]); // 全局加成 if (hero) { // 有武将的,将皮肤链接到武将上 if (!findWhere(hero.skins, { id: skinId })) { hero.skins.push({ id: skinId, skin: skin._id, enable }); await HeroModel.updateHeroInfo(roleId, hero.hid, hero); } return { hero, figureInfo, calAllHeroResult }; } else { return { hero: null, figureInfo, calAllHeroResult } } } export async function addBags(roleId: string, roleName: string, datas: { id: number, count: number }[]) { let items: { id: number, count: number }[] = []; for(let data of datas) { let item = await addBag(roleId, roleName, data); items.push(item) } return { items } } export async function addBag(roleId: string, roleName: string, data: { id: number, count: 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 }; } export async function addEquips(roleId: string, roleName: string, weapons: { id: number, hid?: number }[]) { let equipInfos: equipUpdate[] = []; for(let weapon of weapons) { let info = await getAddEquipInfo(roleId, roleName, weapon); equipInfos.push(info); } const equips = await EquipModel.createEquips(roleId, equipInfos); let pushMessages: TaskListReturn[] = []; // 任务 for(let equip of equips) { let pushMessage = await checkTaskWithEquip(roleId, TASK_TYPE.EQUIP_SUIT, equip); pushMessages = [...pushMessages, ...pushMessage]; } return { equips, pushMessages } } export async function getAddEquipInfo(roleId: string, roleName: string, weapon: { id: number, hid?: number }) { let { id, hid = 0 } = weapon; let { name, quality, suitId, hole, randomEffect, itid, goodsAbility } = gameData.goods.get(id); let { type } = ITID.get(itid); // 随机属性 let randomNum = RANDOM_SE_COUNT.get(quality); let randomResult: number[] = getRandEelm(randomEffect, randomNum); let randSe: Array = randomResult.map((id: number, i: number) => { let random = gameData.randomEffectPool.get(id) let rand = 0; if (random.id > 0) rand = getRandValueByMinMax(random.Min, random.Max, 0); return { id: i + 1, seid: random.id, rand, locked: false }; }); let randRange = 0; // 淬火品相 let randMain: RandMain[] = []; let grade = 0; for(let [ attrId, attrValue ] of goodsAbility) { if(attrValue > 0) { let { randMin, randMax } = getQuenchByQualityAndGrade(quality, grade); let rand = getRandValueByMinMax(randMin, randMax, 0); console.log(quality, grade, rand) grade = getQuenchGradeByValue(quality, rand); randMain.push({ id: attrId, rand }); } } let holes = new Array(); for (let i = 0; i < hole; i++) { holes.push({ id: i + 1, isOpen: false, jewel: 0 }); } return { roleId, roleName, id, name, quality, suitId, randRange, ePlaceId: type, randSe, holes, hid, grade, randMain }; } /** * @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 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 }; } /** * 解锁头像/相框 * @param roleId 玩家id * @param conditions 解锁条件 * @param role 如果已查询过role表就直接可以使用 */ export async function unlockFigure(roleId: string, conditions: { type: number, paramHid?: number, paramFavourLv?: number, paramSkinId?: number }[], role?: RoleType) { if (!role || !role.heads || !role.frames) { role = await RoleModel.findByRoleId(roleId, ROLE_SELECT.GET_HEADS); } let { heads, frames, spines } = role; let figureInfo = { heads: new Array
(), frames: new Array
(), spines: new Array
() }; for (let { type, paramHid, paramFavourLv, paramSkinId } of conditions) { let canUnLockList = gameData.figureCondition.get(type); if (canUnLockList) { 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; } else if (type == FIGURE_UNLOCK_CONDITION.HERO_FAVOR) { let [hid, favourLv] = params; if (paramHid == hid && paramFavourLv >= favourLv) flag = true; } else if (type == FIGURE_UNLOCK_CONDITION.GET_SKIN) { let [id] = params; if (paramSkinId == id) flag = true; } 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, false, id); if (figure && figure.unlocked) figureInfo.heads.push(figure); } else if (dicItid.type == CONSUME_TYPE.FRAME) { let figure = unlockSingleFigure(frames, gid, false, id); if (figure && figure.unlocked) figureInfo.frames.push(figure); } else if (dicItid.type == CONSUME_TYPE.SPINE) { let figure = unlockSingleFigure(spines, gid, false, id); if (figure && figure.unlocked) figureInfo.spines.push(figure); } else { continue; } } } } role = await RoleModel.updateRoleInfo(roleId, { heads, frames, spines }); return figureInfo; } // 直接获得形象/相框 export async function addFigure(roleId: string, ids: 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, true); if (figure && figure.unlocked) figureInfo.heads.push(figure); } else if (dicItid.type == CONSUME_TYPE.FRAME) { let figure = unlockSingleFigure(frames, gid, true); if (figure && figure.unlocked) figureInfo.frames.push(figure); } else if (dicItid.type == CONSUME_TYPE.SPINE) { let figure = unlockSingleFigure(spines, gid, 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, unlockDirect = false, conditionId?: number) { let figure = dbFigures.find(cur => cur.id == id); if (!figure) { figure = new Figure(id, false); dbFigures.push(figure); } 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 = getTimeFun().getAfterDay(dicGoods.timeLimit); // timeLimit天以后 } } return figure } async function linkOldSkins(roleId: string, hero: HeroType) { let allSkins = await SkinModel.findbyRoleAndHid(roleId, hero.hid); let skins = hero.skins||[]; for(let skin of allSkins) { let index = skins.findIndex(cur => cur.id == skin.id); if(index == -1) { skins.push({ id: skin.id, skin: skin._id, enable: false }); } } return await HeroModel.updateHeroInfo(roleId, hero.hid, { skins }) } /** * 创建武将 * @param roleId 玩家id * @param roleName 玩家名 * @param serverId 服务器id * @param {CreateHeroParam} heroInfo 创建武将所需信息 * @param funcs 玩家开启了的功能,主要用于任务 */ export async function createHero(roleId: string, roleName: string, serverId: number, heroInfo: CreateHeroParam, funcs?: number[]) { let { role, figureInfo, heroes, calHeroResults, calAllHeroResult, taskPushMessage, activityTaskPushMessage } = await createHeroes(roleId, roleName, serverId, [heroInfo], funcs) return { hero: heroes[0], role, figureInfo, calHeroResult: calHeroResults[0], calAllHeroResult, taskPushMessage, activityTaskPushMessage } } export async function createHeroes(roleId: string, roleName: string, serverId: number, heroInfos: CreateHeroParam[], funcs?: number[]) { let heroNum = 0; let conditions = new Array<{ type: number, paramHid?: number, paramFavourLv?: number, paramSkinId?: number }>(); let heroes: HeroType[] = [], calHeroResults = [], calAllHeroResult = undefined; let figureInfos:{ heads: Figure[], frames: Figure[], spines: Figure[] }[] = []; for (let heroInfo of heroInfos) { let dicHero = gameData.hero.get(heroInfo.hid); let { quality, initialStars: star, jobid: job, name: hName, initialSkin } = dicHero; let info = { roleId, roleName, serverId, quality, star, job, hName }; let curHero = await HeroModel.createHero(Object.assign(info, heroInfo)); let addSkinResult = await addSkin(roleId, roleName, initialSkin, true, curHero); // 添加皮肤 curHero = await linkOldSkins(roleId, curHero); if(addSkinResult) { // 处理添加皮肤结果 curHero = addSkinResult.hero; figureInfos.push(addSkinResult.figureInfo); calAllHeroResult = addSkinResult.calAllHeroResult; // 全局加成,所以同一个人的处理都是累加 } // 计算初始战力 let calHeroResult = await calPlayerCeAndSave(HERO_SYSTEM_TYPE.INIT, roleId, curHero, {}); calHeroResults.push(calHeroResult); heroes.push(calHeroResult.hero); conditions.push({ type: FIGURE_UNLOCK_CONDITION.GET_HERO, paramHid: heroInfo.hid }); heroNum++; } figureInfos.push(await unlockFigure(roleId, conditions)); // 解锁头像 let role = await RoleModel.incRoleInfo(roleId, { heroNum }, { heroNumUpdatedAt: nowSeconds() }); // 任务 let m1 = await checkTask(roleId, TASK_TYPE.HERO_NUM, heroNum, true, {}, funcs); let m2 = await checkTaskWithHeroes(roleId, TASK_TYPE.HERO_QUALITY, heroes, funcs); let m3 = await checkTaskWithHeroes(roleId, TASK_TYPE.HERO_QUALITY_STAR_UP, heroes, funcs); let m4 = await checkTaskWithHeroes(roleId, TASK_TYPE.HERO_LV, heroes, funcs); let taskPushMessage = m1.concat(m2, m3, m4); //成长任务 let mm1 = await accomplishTask(serverId, roleId, TASK_TYPE.HERO_NUM, heroNum) let mm2 = await accomplishTask(serverId, roleId, TASK_TYPE.HERO_QUALITY, heroNum, { heroes }) let activityTaskPushMessage = mm1.concat(mm2); return { role, figureInfo: combineFigureInfo(figureInfos), heroes, calHeroResults, calAllHeroResult, taskPushMessage, activityTaskPushMessage } } 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 function transPiece(hid: number) { let dicHero = gameData.hero.get(hid); let count = gameData.heroTransPiece.get(dicHero.quality); return { pieceId: dicHero.pieceId, count } }