/** * 肉鸽模式配置脚本 - 增强版 * * 功能说明: * - 提供基础的刷怪配置:刷什么怪,刷多少怪 * - 支持程序化关卡生成逻辑,每一关的怪物组合、数量和强度应随关卡进度递增而变化 * - 支持随机事件系统 * * * 3. 全局动态 Scaling 算法既然是 15 分钟单局,属性不应一成不变。 * 建议引入 Wave_Factor (波次因子): * 公式建议: Current_Stat = Base_Stat * (1 + (time / 60) * 0.15) ^ Growth_Type * •HP 成长: 设为指数级 (Growth_Type = 1.2)。后期怪物血量会呈几何倍数增加,适配『神装英雄』。 * •AP 成长: 设为线性 (Growth_Type = 1.0)。保证怪物能击穿后期护盾,但不会一击必杀。 * •Speed 成长: 设为对数级 (Growth_Type = 0.5)。防止后期怪物速度过快导致画面瞬移。 * * @author 游戏开发团队 * @version 2.0 增强版 * @date 2025-10-19 */ import { HeroInfo } from "../common/config/heroSet"; // 精英怪物配置表 export const EliteMons = [ 5201, 5202, 5203, 5213 ]; // Boss怪物配置表 export const BossMons = [ 5201, 5202, ]; export enum IMons{ ORC=1, HUMAN=2, ELF=3,} export const Mons={ [IMons.ORC]:[5201,5202], [IMons.HUMAN]:[5201,5202], [IMons.ELF]:[5201,5202] } /** * 怪物类型枚举 */ export enum MonType { NORMAL = 0, // 普通怪物 ELITE = 1, // 精英怪物 BOSS = 2 // Boss怪物 } /** * 怪物配置接口 */ export interface IMonsConfig { uuid: number; // 怪物ID type: MonType; // 怪物类型 level: number; // 等级 position?: number; // 位置(可选) buffs?: any[]; // buff列表(可选) } /** * 怪物属性接口 */ export interface MonAttrs { hp: number; mp: number; ap: number; def: number; speed: number; } /** * 成长类型枚举 */ enum GrowthType { EXPONENTIAL = 1.2, // 指数级 - HP LINEAR = 1.0, // 线性 - AP LOGARITHMIC = 0.5 // 对数级 - Speed } /** * 计算波次因子 * @param stage 当前波次 * @param timeInSeconds 游戏进行时间(秒) * @returns 波次因子 (0-1之间,15分钟时达到最大) */ function calculateWaveFactor(stage: number, timeInSeconds: number = 0): number { const MAX_GAME_TIME = 15 * 60; // 15分钟 = 900秒 const effectiveTime = timeInSeconds || (stage * 30); // 如果没有时间数据,用波次估算(每波30秒) const factor = Math.min(effectiveTime / MAX_GAME_TIME, 1.0); return factor; } /** * 应用成长公式到基础属性 * @param baseStat 基础属性值 * @param waveFactor 波次因子 (0-1) * @param growthType 成长类型 * @returns 成长后的属性值 */ function applyGrowthFormula(baseStat: number, waveFactor: number, growthType: GrowthType): number { // 公式: Current_Stat = Base_Stat * (1 + waveFactor * 0.15) ^ Growth_Type const growthMultiplier = Math.pow(1 + waveFactor * 0.15, growthType); return Math.floor(baseStat * growthMultiplier); } /** * 获取怪物动态成长属性 * @param stage 当前波次 * @param uuid 怪物ID * @param monType 怪物类型 * @param timeInSeconds 游戏进行时间(秒) * @returns 怪物属性 */ export function getMonAttr(stage: number, uuid: number, monType: MonType = MonType.NORMAL, timeInSeconds: number = 0): MonAttrs { const baseMonster = HeroInfo[uuid]; if (!baseMonster) { console.warn(`[RogueConfig] 未找到怪物ID: ${uuid}`); return { hp: 100, mp: 100, ap: 10, def: 0, speed: 100 }; } // 计算波次因子 const waveFactor = calculateWaveFactor(stage, timeInSeconds); // 根据怪物类型应用额外的倍率 let typeMultiplier = 1.0; if (monType === MonType.ELITE) { typeMultiplier = 2.0; // 精英怪2倍属性 } else if (monType === MonType.BOSS) { typeMultiplier = 5.0; // Boss 5倍属性 } // 应用不同的成长类型 const hp = applyGrowthFormula(baseMonster.hp, waveFactor, GrowthType.EXPONENTIAL) * typeMultiplier; const ap = applyGrowthFormula(baseMonster.ap, waveFactor, GrowthType.LINEAR) * typeMultiplier; const speed = applyGrowthFormula(baseMonster.speed, waveFactor, GrowthType.LOGARITHMIC); // MP和DEF使用线性成长 const mp = applyGrowthFormula(baseMonster.mp, waveFactor, GrowthType.LINEAR); const def = applyGrowthFormula(baseMonster.def, waveFactor, GrowthType.LINEAR) * typeMultiplier; return { hp: Math.floor(hp), mp: Math.floor(mp), ap: Math.floor(ap), def: Math.floor(def), speed: Math.floor(speed) }; } /** * 根据波次生成怪物配置 * @param stage 当前波次 * @returns IMonsConfig数组 */ export function getStageMonConfigs(stage: number): IMonsConfig[] { const monsterConfigs: IMonsConfig[] = []; // 基础怪物列表(从heroset.ts中获取) const normalMons = [5201, 5301, 5401, 5501, 5601, 5602, 5603, 5604]; const eliteMons = [5701]; // 根据波次生成怪物配置 // 波次越高,怪物数量越多,精英怪物出现概率越高 const baseCount = 5 + Math.floor(stage / 2); // 基础数量每2波增加1 const eliteChance = Math.min(stage * 0.05, 0.3); // 精英怪概率最高30% const bossWave = stage % 10 === 0; // 每10波出Boss if (bossWave && stage > 0) { // Boss波 monsterConfigs.push({ uuid: 5701, type: MonType.BOSS, level: stage }); } else { // 普通波 for (let i = 0; i < baseCount; i++) { // 随机决定是否生成精英怪 const isElite = Math.random() < eliteChance; const monList = isElite ? eliteMons : normalMons; const randomUuid = monList[Math.floor(Math.random() * monList.length)]; monsterConfigs.push({ uuid: randomUuid, type: isElite ? MonType.ELITE : MonType.NORMAL, level: stage, position: i % 5 }); } } return monsterConfigs; }