diff --git a/assets/script/game/common/GameDataSyncManager.ts b/assets/script/game/common/GameDataSyncManager.ts index 53747355..88c52872 100644 --- a/assets/script/game/common/GameDataSyncManager.ts +++ b/assets/script/game/common/GameDataSyncManager.ts @@ -79,11 +79,11 @@ export class GameDataSyncManager { * @param fightHeros 出战英雄配置对象 * @returns 是否成功 */ - async updateFightHeros(fightHeros: any): Promise { + async updateFightHeros(fightHero: any): Promise { try { // console.log(`[GameDataSyncManager]: 批量更新出战英雄配置:`, fightHeros); - const result = await WxCloudApi.updateFightHeros(fightHeros); + const result = await WxCloudApi.updateFightHeros(fightHero); if (result.result.code === 200) { // 远程修改成功,同步本地数据 diff --git a/assets/script/game/common/SingletonModuleComp.ts b/assets/script/game/common/SingletonModuleComp.ts index c04be678..512a325a 100644 --- a/assets/script/game/common/SingletonModuleComp.ts +++ b/assets/script/game/common/SingletonModuleComp.ts @@ -38,30 +38,18 @@ export class SingletonModuleComp extends ecs.Comp { exp:0, task:0, } - shop:any={ - daily:[1001,1004,1002,1005], - weekly:[], - monthly:[], - special:[], - goods_count:[1,1,3,3,10,10,10,10,10,10,10,10], - - } - fight_heros:any={ 0:5001, 1:5005, 2:0, 3:0, 4:0, } + + fight_hero: number = 5001; // 单个出战英雄 heros:any = { 5001:{uuid:5001,lv:1}, 5005:{uuid:5005,lv:1}, }; - items:any={ - } - tals:any={ - } - equips:any={ - } monsters:any = []; sk_info:any = [] monsters_dead:any = [] heros_dead:any = [] enhancements:any=[] + items: any = {}; // 物品数据 vmdata: any = { game_over:false, game_pause:false, @@ -121,57 +109,23 @@ export class SingletonModuleComp extends ecs.Comp { return true } - setFightHero(position:number,heroId:number,autoSave:boolean=true){ - this.fight_heros[position] = heroId; - if(this.isWxClient()){ - this.updateFightHeros() + // 设置单个出战英雄 + setFightHero(heroId: number, autoSave: boolean = true) { + this.fight_hero = heroId; + if (this.isWxClient()) { + this.gameDataSyncManager.updateFightHeros({ 0: heroId }); // 适配原有接口 } } - updateFightHeros(){ - this.gameDataSyncManager.updateFightHeros(this.fight_heros); - } - resetFightHeros(){ - this.gameDataSyncManager.resetFightHeros(); - } - getHasHeroUUID(){ - let heros=this.heros - let heros_uuid=[] - for(let key in heros){ - heros_uuid.push(heros[key].uuid) - } - return heros_uuid - } - - levelUpHero(heroId:number){ - if(this.isWxClient()){ - let result=this.gameDataSyncManager.levelUpHero(heroId); - if(result){ - this.heros[heroId].lv++; - return true - } - return false - } - else{ - this.heros[heroId].lv++; - return true - } + // 获取出战英雄 + getFightHero(): number { + return this.fight_hero; } error(){ oops.gui.toast("数据处理异常,请重试或重新登录") } - addExp(exp:number,autoSave:boolean=true){ - if(this.isWxClient()){ - if(this.gameDataSyncManager.addGameProperty("exp",exp)){ - this.data.exp+=exp - return true - } - return false - } - this.data.exp+=exp - return true - } + addGold(gold:number,autoSave:boolean=true){ if(this.isWxClient()){ if(this.gameDataSyncManager.addGameProperty("gold",gold)){ @@ -187,45 +141,6 @@ export class SingletonModuleComp extends ecs.Comp { return true } - addDiamond(diamond:number,autoSave:boolean=true){ - if(this.isWxClient()){ - if(this.gameDataSyncManager.addGameProperty("diamond",diamond)){ - this.data.diamond+=diamond - oops.message.dispatchEvent(GameEvent.DIAMOND_UPDATE) - return true - } - return false - } - this.data.diamond+=diamond - oops.message.dispatchEvent(GameEvent.DIAMOND_UPDATE) - return true - } - - addMission(mission:number,autoSave:boolean=true){ - if(this.isWxClient()){ - if(this.gameDataSyncManager.addGameProperty("mission",mission)){ - this.data.mission+=mission - oops.message.dispatchEvent(GameEvent.MISSION_UPDATE) - return true - } - return false - } - this.data.mission+=mission - oops.message.dispatchEvent(GameEvent.MISSION_UPDATE) - return true - } - - spendExp(exp:number,autoSave:boolean=true){ - if(this.isWxClient()){ - if(this.gameDataSyncManager.spendGameProperty("exp",exp)){ - this.data.exp-=exp - return true - } - return false - } - this.data.exp-=exp - return true - } spendGold(gold:number,autoSave:boolean=true){ if(this.isWxClient()){ if(this.gameDataSyncManager.spendGameProperty("gold",gold)){ @@ -239,78 +154,6 @@ export class SingletonModuleComp extends ecs.Comp { oops.message.dispatchEvent(GameEvent.GOLD_UPDATE) return true } - spendDiamond(diamond:number,autoSave:boolean=true){ - if(this.isWxClient()){ - if(this.gameDataSyncManager.spendGameProperty("diamond",diamond)){ - this.data.diamond-=diamond - oops.message.dispatchEvent(GameEvent.DIAMOND_UPDATE) - return true - } - return false - } - this.data.diamond-=diamond - oops.message.dispatchEvent(GameEvent.DIAMOND_UPDATE) - return true - } - - /** - * 消耗游戏数据属性(统一接口) - * 处理多个字段:spendGameProperty({ gold: 10, exp: 5 }) - */ - async spendGameProperty(property: Record, autoSave: boolean = true): Promise { - if(this.isWxClient()){ - if(this.gameDataSyncManager.spendGameProperty(property)){ - return true - } - return false - } - // 多字段扣除(原子性:全部满足才扣) - const deductions = property as Record; - // 1) 校验是否全部满足 - for (const key in deductions) { - if (!Object.prototype.hasOwnProperty.call(deductions, key)) continue; - const need = deductions[key] ?? 0; - const current = this.data[key] || 0; - if (current < need) { - console.warn(`[SMC]: ${key} 不足,当前: ${current}, 需要: ${need}`); - oops.gui.toast(`${key} 不足,当前: ${current}, 需要: ${need}`) - return false; - } - } - // 2) 统一扣减 - for (const key in deductions) { - if (!Object.prototype.hasOwnProperty.call(deductions, key)) continue; - const need = deductions[key] ?? 0; - const current = this.data[key] || 0; - const next = current - need; - this.data[key] = next; - // console.log(`[SMC]: 消耗游戏数据 ${key} = ${need}, 当前值: ${next}`); - } - return true; - } - - addItem(item_uuid:number,count:number,autoSave:boolean=true){ - if(this.isWxClient()){ - if(this.gameDataSyncManager.addItem(item_uuid,count)){ - this.items[item_uuid] = (this.items[item_uuid] || 0) + count; - return true - } - return false - } - this.items[item_uuid] = (this.items[item_uuid] || 0) + count; - return true - } - spendItem(item_uuid:number,count:number,autoSave:boolean=true){ - if(this.isWxClient()){ - if(this.gameDataSyncManager.consumeItem(item_uuid,count)){ - this.items[item_uuid] = (this.items[item_uuid] || 0) - count; - return true - } - return false - } - this.items[item_uuid] = (this.items[item_uuid] || 0) - count; - return true - } } diff --git a/assets/script/game/common/config/heroSet.ts b/assets/script/game/common/config/heroSet.ts index 6cc149eb..5a969aa2 100644 --- a/assets/script/game/common/config/heroSet.ts +++ b/assets/script/game/common/config/heroSet.ts @@ -1,5 +1,5 @@ import { v3 } from "cc" -import { FacSet, QualitySet } from "./BoxSet" +import { FacSet } from "./BoxSet" import { smc } from "../SingletonModuleComp" import { BuffConf, DbuffConf } from "./SkillSet" import { debuff } from "../../skills/debuff" @@ -37,7 +37,7 @@ export const getHeroList = (quality:number=0)=>{ return [...ownedHeros, ...unownedHeros].map(item => item.uuid); } //fac:FacSet.MON -export const getMonList = (quality:number=0)=>{ +export const getMonList = ()=>{ return Object.values(HeroInfo).filter(item=>{ const facMatch = item.fac === FacSet.MON; return facMatch ; @@ -71,7 +71,7 @@ export enum HeroUpSet { } export interface heroInfo{ - uuid:number, name:string, path:string,fac:FacSet,kind:QualitySet,type:HType, hp:number,mp:number,map:number, def:number, ap:number,dis:number, cd:number,speed:number, + uuid:number, name:string, path:string,fac:FacSet,kind:number,type:HType, hp:number,mp:number,map:number, def:number, ap:number,dis:number, cd:number,speed:number, lv:number,skills:number[], buff:BuffConf[], debuff:DbuffConf[], info:string } @@ -175,5 +175,4 @@ export const HeroInfo: Record = { // type:HType.warrior,lv:1,hp:45,mp:100,map:100,def:5,ap:12,dis:300,cd:2,speed:100,skills:[6001,6005], // buff:[],debuff:[],info:"精英怪物-战士型"}, - }; - + }; \ No newline at end of file diff --git a/assets/script/game/hero/Mon.ts b/assets/script/game/hero/Mon.ts index ee5787b9..696149a3 100644 --- a/assets/script/game/hero/Mon.ts +++ b/assets/script/game/hero/Mon.ts @@ -30,7 +30,7 @@ export class Monster extends ecs.Entity { } /** 加载角色 */ - load(pos: Vec3 = Vec3.ZERO,scale:number = 1,uuid:number=1001,is_boss:boolean=false,is_call:boolean=false) { + load(pos: Vec3 = Vec3.ZERO,scale:number = 1,uuid:number=1001,is_boss:boolean=false,is_call:boolean=false, strengthMultiplier: number = 1.0) { scale=-1 let box_group=BoxSet.MONSTER // console.log("mon load",uuid) @@ -45,7 +45,7 @@ export class Monster extends ecs.Entity { const collider = node.getComponent(BoxCollider2D); if (collider) collider.enabled = false; // 先禁用 // 延迟一帧启用碰撞体 node.setPosition(pos) - this.hero_init(uuid,node,scale,box_group,is_boss,is_call) + this.hero_init(uuid,node,scale,box_group,is_boss,is_call, strengthMultiplier) oops.message.dispatchEvent("monster_load",this) // 初始化移动参数 @@ -62,7 +62,7 @@ export class Monster extends ecs.Entity { node.parent = scene.entityLayer!.node! node.setPosition(pos) } - hero_init(uuid:number=1001,node:Node,scale:number=1,box_group=BoxSet.HERO,is_boss:boolean=false,is_call:boolean=false) { + hero_init(uuid:number=1001,node:Node,scale:number=1,box_group=BoxSet.HERO,is_boss:boolean=false,is_call:boolean=false, strengthMultiplier: number = 1.0) { var hv = node.getComponent(HeroViewComp)!; @@ -80,9 +80,10 @@ export class Monster extends ecs.Entity { hv.hero_uuid= uuid; hv.hero_name= hero.name; - // 初始化基础属性 - const baseHp = hero.hp; - const baseAp = hero.ap; + // 初始化基础属性,并根据强度倍率调整 + const baseHp = Math.floor(hero.hp * strengthMultiplier); + const baseAp = Math.floor(hero.ap * strengthMultiplier); + const baseDef = Math.floor(hero.def * strengthMultiplier); for(let i=0;i = []; private isSpawning: boolean = false;// 是否正在生成怪物 private spawnInterval: number = 0.1; // 每个怪物生成间隔时间 @@ -32,6 +35,8 @@ export class MissionMonCompComp extends CCComp { private spawnCount: number = 0; // 召唤计数器 private pauseInterval: number = 5.0; // 暂停间隔时间(5秒) private isPausing: boolean = false; // 是否正在暂停 + private currentEvent: EventType | null = null; // 当前关卡的随机事件 + private eventProcessed: boolean = false; // 事件是否已处理 onLoad(){ @@ -54,6 +59,12 @@ export class MissionMonCompComp extends CCComp { protected update(dt: number): void { if(!smc.mission.play||smc.mission.pause) return + // 处理随机事件 + if (this.currentEvent && !this.eventProcessed) { + this.processRandomEvent(); + this.eventProcessed = true; + } + // 处理刷怪队列 if (this.monsterQueue.length > 0 && !this.isSpawning) { this.spawnTimer += dt; @@ -90,16 +101,51 @@ export class MissionMonCompComp extends CCComp { this.spawnCount = 0; this.isPausing = false; this.spawnTimer = 0; + this.eventProcessed = false; const currentStage = smc.data.mission; // 使用新的肉鸽关卡配置 let level=smc.vmdata.mission_data.level const stageType = getStageType(currentStage,level); + + // 检查是否为事件关卡 + if (stageType === "event") { + this.currentEvent = getRandomEvent(); + } else { + this.currentEvent = null; + } + const monsterConfigs = getStageMonsterConfigs(currentStage,level); // console.log(`[MissionMonComp]:第${currentStage}关 - ${stageType}类型,怪物数量: ${monsterConfigs.length}`); this.generateMonstersFromStageConfig(monsterConfigs); } + // 处理随机事件 + private processRandomEvent() { + if (!this.currentEvent) return; + + switch (this.currentEvent) { + case EventType.TREASURE: + // 发送获得奖励事件 + smc.vmdata.mission_data.gold += 50; // 增加50金币 + // 可以触发UI提示 + // oops.message.dispatchEvent("event_treasure"); + break; + case EventType.TRAP: + // 对玩家造成伤害 + // 这里可以实现对玩家英雄造成伤害的逻辑 + // oops.message.dispatchEvent("event_trap"); + break; + case EventType.BUFF: + // 给玩家增加临时增益效果 + // oops.message.dispatchEvent("event_buff"); + break; + case EventType.DEBUFF: + // 给玩家增加临时减益效果 + // oops.message.dispatchEvent("event_debuff"); + break; + } + } // 根据新的关卡配置生成怪物 private generateMonstersFromStageConfig(monsterConfigs: any[]) { @@ -114,7 +160,7 @@ export class MissionMonCompComp extends CCComp { // 为每个怪物配置生成怪物 monsterConfigs.forEach((monsterConfig: any, index: number) => { - const { uuid, type } = monsterConfig; + const { uuid, type, strengthMultiplier } = monsterConfig; // 位置循环使用 (0-4) const position = index % 5; @@ -123,7 +169,8 @@ export class MissionMonCompComp extends CCComp { uuid, position, type, - 1 // 默认等级1 + 1, // 默认等级1 + strengthMultiplier // 强度倍率 ); }); @@ -135,13 +182,15 @@ export class MissionMonCompComp extends CCComp { uuid: number, position: number, type: MonsterType, - level: number = 1 + level: number = 1, + strengthMultiplier: number = 1.0 ) { this.monsterQueue.push({ uuid: uuid, position: position, type: type, - level: level + level: level, + strengthMultiplier: strengthMultiplier }); } @@ -158,7 +207,8 @@ export class MissionMonCompComp extends CCComp { monsterData.position, isBoss, false, - monsterData.level + monsterData.level, + monsterData.strengthMultiplier ); // 增加召唤计数 @@ -172,14 +222,15 @@ export class MissionMonCompComp extends CCComp { i: number = 0, is_boss: boolean = false, is_call: boolean = false, - lv: number = 1 + lv: number = 1, + strengthMultiplier: number = 1.0 ) { let mon = ecs.getEntity(Monster); let scale = -1; let pos: Vec3 = v3(MonSet[i].pos); // 生成怪物 - mon.load(pos,scale,uuid,is_boss,is_call); + mon.load(pos,scale,uuid,is_boss,is_call,strengthMultiplier); } /** 视图对象通过 ecs.Entity.remove(ModuleViewComp) 删除组件是触发组件处理自定义释放逻辑 */ diff --git a/assets/script/game/map/RogueConfig.ts b/assets/script/game/map/RogueConfig.ts index bdb5a13c..2cbeabf4 100644 --- a/assets/script/game/map/RogueConfig.ts +++ b/assets/script/game/map/RogueConfig.ts @@ -1,16 +1,33 @@ /** - * 肉鸽模式配置脚本 - 简化版 + * 肉鸽模式配置脚本 - 增强版 * * 功能说明: * - 提供基础的刷怪配置:刷什么怪,刷多少怪 + * - 支持程序化关卡生成逻辑,每一关的怪物组合、数量和强度应随关卡进度递增而变化 + * - 支持随机事件系统 * * @author 游戏开发团队 - * @version 1.0 简化版 + * @version 2.0 增强版 * @date 2025-10-19 */ -import { QualitySet } from "../common/config/BoxSet"; -import { getMonList } from "../common/config/heroSet"; +import { getMonList, HeroInfo } from "../common/config/heroSet"; +import { Attrs } from "../common/config/SkillSet"; + +// 精英怪物配置表 +export const EliteMonsterList = [ + 5201, // 兽人战士 + 5202, // 兽人刺客 + 5203, // 兽人护卫 + // 可以添加更多精英怪物UUID +]; + +// Boss怪物配置表 +export const BossMonsterList = [ + 5201, // 兽人战士 + 5202, // 兽人刺客 + // 可以添加更多Boss怪物UUID +]; /** * 怪物类型枚举 @@ -27,18 +44,29 @@ export enum MonsterType { export enum StageType { NORMAL = "normal", // 普通关卡 ELITE = "elite", // 精英关卡 - BOSS = "boss" // Boss关卡 + BOSS = "boss", // Boss关卡 + EVENT = "event" // 事件关卡 } /** - * 关卡配置规则 - 只保留刷怪类型和数量 + * 随机事件类型枚举 + */ +export enum EventType { + TREASURE = "treasure", // 额外奖励 + TRAP = "trap", // 陷阱伤害 + BUFF = "buff", // 临时增益效果 + DEBUFF = "debuff" // 临时减益效果 +} + +/** + * 关卡配置规则 - 增强版,支持怪物数量和强度随关卡递增 */ export const StageConfigRules = { // 普通关卡 [StageType.NORMAL]: { description: "普通关卡", monsters: [ - { type: MonsterType.NORMAL, count: 1 } // 5个普通怪物 + { type: MonsterType.NORMAL, count: 3, minCount: 2, maxCount: 6 } // 普通怪物数量随关卡递增 ] }, @@ -46,8 +74,8 @@ export const StageConfigRules = { [StageType.ELITE]: { description: "精英关卡", monsters: [ - { type: MonsterType.ELITE, count: 1 }, // 2个精英怪物 - { type: MonsterType.NORMAL, count: 1 } // 3个普通怪物 + { type: MonsterType.ELITE, count: 2, minCount: 1, maxCount: 4 }, // 精英怪物 + { type: MonsterType.NORMAL, count: 3, minCount: 2, maxCount: 5 } // 普通怪物 ] }, @@ -55,10 +83,44 @@ export const StageConfigRules = { [StageType.BOSS]: { description: "Boss关卡", monsters: [ - { type: MonsterType.BOSS, count: 1 }, // 1个Boss怪物 - { type: MonsterType.ELITE, count: 1 }, // 2个精英怪物 - { type: MonsterType.NORMAL, count: 1 } // 2个普通怪物 + { type: MonsterType.BOSS, count: 1, minCount: 1, maxCount: 1 }, // 1个Boss怪物 + { type: MonsterType.ELITE, count: 2, minCount: 1, maxCount: 3 }, // 精英怪物 + { type: MonsterType.NORMAL, count: 2, minCount: 1, maxCount: 4 } // 普通怪物 ] + }, + + // 事件关卡 + [StageType.EVENT]: { + description: "事件关卡", + monsters: [ + { type: MonsterType.NORMAL, count: 2, minCount: 1, maxCount: 4 } // 少量普通怪物 + ] + } +}; + +/** + * 随机事件配置 + */ +export const EventConfig = { + [EventType.TREASURE]: { + description: "宝箱事件", + probability: 0.3, // 30%概率触发 + effect: "获得额外奖励" + }, + [EventType.TRAP]: { + description: "陷阱事件", + probability: 0.25, // 25%概率触发 + effect: "受到一定伤害" + }, + [EventType.BUFF]: { + description: "增益事件", + probability: 0.25, // 25%概率触发 + effect: "获得临时增益效果" + }, + [EventType.DEBUFF]: { + description: "减益事件", + probability: 0.2, // 20%概率触发 + effect: "受到临时减益效果" } }; @@ -69,6 +131,11 @@ export const StageConfigRules = { * @returns 关卡类型 */ export function getStageType(stageNumber: number, level: number = 1): StageType { + // 每隔5关设置特殊事件关卡 + if (stageNumber % 5 === 0 && level === 3) { + return StageType.EVENT; + } + // 第10关的特殊规则 if (stageNumber % 10 === 0) { if (level === 5) { @@ -89,6 +156,39 @@ export function getStageType(stageNumber: number, level: number = 1): StageType } } +/** + * 计算怪物数量,随关卡进度递增 + * @param stageNumber 关卡号 + * @param baseCount 基础数量 + * @param minCount 最小数量 + * @param maxCount 最大数量 + * @returns 实际怪物数量 + */ +export function calculateMonsterCount(stageNumber: number, baseCount: number, minCount: number, maxCount: number): number { + // 随关卡递增,每5关增加1个怪物,最多不超过最大数量 + const increment = Math.floor(stageNumber / 5); + let count = baseCount + increment; + + // 确保在最小和最大数量之间 + count = Math.max(minCount, Math.min(maxCount, count)); + + return count; +} + +/** + * 计算怪物强度倍率,随关卡进度递增 + * @param stageNumber 关卡号 + * @param level 等级 + * @returns 强度倍率 + */ +export function calculateMonsterStrengthMultiplier(stageNumber: number, level: number): number { + // 基础倍率基于关卡号和等级 + const stageMultiplier = 1 + (stageNumber - 1) * 0.1; // 每关增加10% + const levelMultiplier = 1 + (level - 1) * 0.05; // 每级增加5% + + return stageMultiplier * levelMultiplier; +} + /** * 生成关卡配置 * @param stageNumber 关卡号(从1开始) @@ -102,7 +202,15 @@ export function generateStageConfig(stageNumber: number, level: number = 1): Mon // 根据配置生成怪物类型数组 rule.monsters.forEach(monsterGroup => { - for (let i = 0; i < monsterGroup.count; i++) { + // 计算实际怪物数量 + const actualCount = calculateMonsterCount( + stageNumber, + monsterGroup.count, + monsterGroup.minCount, + monsterGroup.maxCount + ); + + for (let i = 0; i < actualCount; i++) { monsterArray.push(monsterGroup.type); } }); @@ -111,21 +219,21 @@ export function generateStageConfig(stageNumber: number, level: number = 1): Mon } /** - * 根据怪物类型获取对应品质的怪物UUID数组 + * 根据怪物类型获取对应配置表中的怪物UUID数组 * @param monsterType 怪物类型 * @returns 怪物UUID数组 */ export function getMonsterUUIDsByType(monsterType: MonsterType): number[] { switch (monsterType) { case MonsterType.NORMAL: - return getMonList(QualitySet.GREEN); // 绿色品质为普通怪物 + // 普通怪物使用原有的getMonList方法 + return getMonList(); case MonsterType.ELITE: - return getMonList(QualitySet.BLUE); // 蓝色品质为精英怪物 + // 精英怪物使用精英配置表 + return EliteMonsterList; case MonsterType.BOSS: - // 紫色及以上品质为Boss怪物 - const purpleMonsters = getMonList(QualitySet.PURPLE); - const orangeMonsters = getMonList(QualitySet.ORANGE); - return [...purpleMonsters, ...orangeMonsters]; + // Boss怪物使用Boss配置表 + return BossMonsterList; default: return []; } @@ -154,7 +262,7 @@ export function getStageMonsterUUIDs(stageNumber: number, level: number = 1): nu } /** - * 获取关卡怪物配置(只包含UUID) + * 获取关卡怪物配置(包含UUID和强度信息) * @param stageNumber 关卡号 * @param level 等级(1-5) * @returns 怪物配置数组 @@ -163,6 +271,9 @@ export function getStageMonsterConfigs(stageNumber: number, level: number = 1) { const monsterTypes = generateStageConfig(stageNumber, level); const monsterConfigs = []; + // 计算强度倍率 + const strengthMultiplier = calculateMonsterStrengthMultiplier(stageNumber, level); + monsterTypes.forEach((monsterType, index) => { const availableUUIDs = getMonsterUUIDsByType(monsterType); if (availableUUIDs.length > 0) { @@ -172,10 +283,29 @@ export function getStageMonsterConfigs(stageNumber: number, level: number = 1) { uuid: randomUUID, type: monsterType, stageNumber: stageNumber, - level: level + level: level, + strengthMultiplier: strengthMultiplier // 强度倍率 }); } }); return monsterConfigs; } + +/** + * 随机决定是否触发事件 + * @returns 事件类型或null + */ +export function getRandomEvent(): EventType | null { + const random = Math.random(); + let cumulativeProbability = 0; + + for (const eventType in EventConfig) { + cumulativeProbability += EventConfig[eventType].probability; + if (random <= cumulativeProbability) { + return eventType as EventType; + } + } + + return null; // 不触发事件 +} \ No newline at end of file