- 将Design4.csv从旧版配置迁移为新版uuid格式 - 更新怪物属性数值以匹配新的威胁点数池算法 - 调整英雄配置信息以配合新的怪物设计 - 移除旧版怪物配置文档,更新为新的设计文档
189 lines
6.0 KiB
TypeScript
189 lines
6.0 KiB
TypeScript
/**
|
||
* 肉鸽模式配置脚本 - 增强版
|
||
*
|
||
* 功能说明:
|
||
* - 提供基础的刷怪配置:刷什么怪,刷多少怪
|
||
* - 支持程序化关卡生成逻辑,每一关的怪物组合、数量和强度应随关卡进度递增而变化
|
||
* - 支持随机事件系统
|
||
*
|
||
*
|
||
* 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;
|
||
}
|