import { Circle, RougelikeTechModel, RougelikeTechType } from '../../db/RougelikeTech'; import { gameData } from '../../pubUtils/data'; import { HeroModel } from '../../db/Hero'; import { compareNumberArray } from '../../pubUtils/util'; import { ROUGE_EFFECT_TYPE, ROUGE_LIKE_STATUS } from '../../consts'; import { updateMaxHp } from './rougeService'; import { RougelikeRecordModel } from '../../db/RougelikeRecord'; /** * 首页获得的科技树数据 * @param techData * @returns */ export async function getTechData(roleId: string) { let techData = await RougelikeTechModel.findByRoleId(roleId); if(!techData) return { techTrees: [], sumTechScore: 0 }; let { unlockedTech = [], circles = [] } = techData; circles = await calCircleCe(roleId, unlockedTech, circles); let techTrees = unlockedTech.map(techId => getSingleTechData(techId, circles)); return { techTrees } } /** * 从首页重新进入,重新计算他的战力 * @param roleId * @param circles * @returns */ async function calCircleCe(roleId: string, unlockedTech: number[], circles: Circle[]) { let hids: number[] = circles.map(circle => circle.hid).filter(hid => hid > 0); if(hids.length <= 0) return circles let heroes = await HeroModel.findByHidRange(hids, roleId); let newCircle = circles.map(circle => { if(circle.hid == 0) return circle; let hero = heroes.find(cur => cur.hid == circle.hid); return { ...circle, ce: hero?.ce||0 } }); let effectIds = getTechEffectIds(unlockedTech, circles) await RougelikeTechModel.updateCircle(roleId, newCircle, effectIds); return newCircle; } export async function updateEffectId(techData: RougelikeTechType) { let effectIds = getTechEffectIdsByData(techData); if(!compareNumberArray(effectIds, techData.effectIds||[])) { await RougelikeTechModel.updateEffectId(techData.roleId, effectIds); if (hasMaxHpUpdate(effectIds, techData.effectIds||[])) { const dbRecord = await RougelikeRecordModel.findByRoleIdAndStatus(techData.roleId, ROUGE_LIKE_STATUS.SUCCESS) if(dbRecord) await updateMaxHp(techData.roleId, dbRecord.gameCode, dbRecord.type, dbRecord.grade) } } } function hasMaxHpUpdate(effectIds: number[], oldEffectIds: number[]) { let newEffectIds: number[] = []; for(let effectId of effectIds) { if (!oldEffectIds.includes(effectId)) newEffectIds.push(effectId); } for(let effectId of newEffectIds) { let dicRougeEffect = gameData.rougeEffect.get(effectId); if(dicRougeEffect && dicRougeEffect.effectType == ROUGE_EFFECT_TYPE.TECH_CHARA_MAIN_ATTR_UP) { return true; } } return false; } /** * 处理后单个科技点的数据 * @param techData * @param techId * @returns */ export function getCurTechData(techData: RougelikeTechType, techId: number) { if(!techData || !techId) return { curTechTree: { techId, circles: [] } } let { circles = [] } = techData; return { curTechTree: getSingleTechData(techId, circles) } } /** * 获取单片科技树数据 * @param techId * @param circles * @returns */ function getSingleTechData(techId: number, circles: Circle[]) { let result: { circleId: number, hid: number, ce: number }[] = []; for(let { techId: curTechId, hid, circleId, ce } of circles) { if(curTechId == techId) result.push({ hid, circleId, ce }); } return { techId, circles: result }; } /** * 检查前置科技点是否解锁 * @param techId * @param unlockedTech * @returns */ export function checkPreRougeTech(techId: number, unlockedTech: number[]) { let dicTech = gameData.rougeTech.get(techId); let preTechId = dicTech?.preTechId||[]; for(let techId of preTechId) { if(!unlockedTech.includes(techId)) return false; } return true; } /** * 获取科技树带来的type加成 * @param roleId * @returns [{ type: number, param: number[] }] */ export function getTechEffectIdsByData(techData: RougelikeTechType) { if(!techData) return []; return getTechEffectIds(techData.unlockedTech, techData.circles); } export function getTechEffectIds(unlockedTech: number[], circles: Circle[]) { let result: number[] = []; let techMap = new Map(); for(let techId of unlockedTech) { techMap.set(techId, 0); } for(let { techId, ce } of circles) { let oldCe = techMap.get(techId)||0; techMap.set(techId, oldCe + ce); } for(let [techId, ce] of techMap) { let levelDatas = gameData.rougeTechLevel.get(techId)||[]; let effectIds: number[] = []; for(let { techEffectIds, ce: targetCe } of levelDatas) { if(ce >= targetCe) effectIds = techEffectIds; } result.push(...effectIds); } return result; }