import { _decorator, v3, Vec3 } from "cc"; import { mLogger } from "../common/Logger"; import { ecs } from "../../../../extensions/oops-plugin-framework/assets/libs/ecs/ECS"; import { CCComp } from "../../../../extensions/oops-plugin-framework/assets/module/common/CCComp"; import { Monster } from "../hero/Mon"; import { MonStart } from "../common/config/heroSet"; import { smc } from "../common/SingletonModuleComp"; import { GameEvent } from "../common/config/GameEvent"; // 导入新的肉鸽配置 import { getCurrentWave, MonType, WaveConfig } from "./RogueConfig"; import { BuffConf } from "../common/config/SkillSet"; import { IndexSet, FacSet, BoxSet } from "../common/config/GameSet"; import { HeroAttrsComp } from "../hero/HeroAttrsComp"; import { Attrs } from "../common/config/HeroAttrs"; const { ccclass, property } = _decorator; /** 视图层对象 */ @ccclass('MissionMonCompComp') @ecs.register('MissionMonComp', false) export class MissionMonCompComp extends CCComp { @property({ tooltip: "是否启用调试日志" }) private debugMode: boolean = false; // 刷怪队列 (主要用于特殊事件插队) private MonQueue: Array<{ uuid: number, position: number, type: MonType, level: number, buffs: BuffConf[] }> = []; private spawnCount: number = 0; // 召唤计数器 /** 全局生成顺序计数器,用于层级管理 */ private globalSpawnOrder: number = 0; /** 游戏进行时间(秒) */ private gameTime: number = 0; /** 波次刷怪计时器 */ private waveTimer: number = 0; /** 队列处理计时器 */ private queueTimer: number = 0; onLoad(){ this.on(GameEvent.FightReady,this.fight_ready,this) this.on(GameEvent.NewWave,this.fight_ready,this) // 监听特殊刷怪事件 (精英/Boss) this.on("SpawnSpecialMonster", this.onSpawnSpecialMonster, this); } /** * 处理特殊刷怪事件 * @param event 事件名 * @param args 参数 { uuid, type, level, position?, buffs? } */ private onSpawnSpecialMonster(event: string, args: any) { if (!args) return; console.log(`[MissionMonComp] 收到特殊刷怪指令:`, args); // 插入队列 this.MonQueue.push({ uuid: args.uuid, position: args.position !== undefined ? args.position : 2, // 默认中间 type: args.type, level: args.level, buffs: args.buffs || [] }); // 立即触发一次队列检查 (可选,让 update 尽快处理) this.queueTimer = 1.0; } start() { } fight_ready(){ smc.vmdata.mission_data.mon_num=0 // 重置生成顺序计数器 this.globalSpawnOrder = 0 this.gameTime = 0 this.waveTimer = 0 this.queueTimer = 0 this.MonQueue = [] this.spawnCount = 0 mLogger.log(this.debugMode, 'MissionMonComp', "[MissionMonComp] Starting Wave System (15-min Cycle)"); } protected update(dt: number): void { if(!smc.mission.play) return if(smc.mission.pause) return // 如果英雄死亡(停止怪物行动标志为true),则停止刷怪逻辑 if(smc.mission.stop_mon_action) return; // 累加游戏时间 this.gameTime += dt; // 获取当前波次配置 const currentWave = getCurrentWave(this.gameTime); // 1. 优先处理特殊怪队列 if (this.MonQueue.length > 0) { this.queueTimer += dt; // 队列出怪速度快于普通波次 (0.5秒一只) if (this.queueTimer >= 0.5) { this.spawnNextFromQueue(); this.queueTimer = 0; } } // 2. 处理波次自然刷怪 this.waveTimer += dt; if (this.waveTimer >= currentWave.spawnInterval) { this.waveTimer = 0; // 检查同屏数量限制 if (smc.vmdata.mission_data.mon_num < currentWave.maxActive) { this.spawnWaveMonster(currentWave); } } } /** * 从当前波次配置生成并生成怪物 */ private spawnWaveMonster(wave: WaveConfig) { if (!wave.weights || wave.weights.length === 0) return; // 权重随机算法 const totalWeight = wave.weights.reduce((sum, item) => sum + item.weight, 0); let random = Math.random() * totalWeight; let selectedUuid = wave.weights[0].uuid; let selectedType = wave.weights[0].type || MonType.NORMAL; for (const item of wave.weights) { random -= item.weight; if (random <= 0) { selectedUuid = item.uuid; selectedType = item.type || MonType.NORMAL; break; } } // 随机位置 (0-4) const position = Math.floor(Math.random() * 5); // 等级随时间增长 (每分钟+1级) const level = Math.floor(this.gameTime / 60) + 1; this.addMonster( selectedUuid, position, selectedType, level, [], this.gameTime ); this.spawnCount++; } /** * 从队列中生成下一个怪物 */ private spawnNextFromQueue() { if (this.MonQueue.length === 0) return; const monsterData = this.MonQueue.shift(); if (monsterData) { this.addMonster( monsterData.uuid, monsterData.position, monsterData.type, monsterData.level, monsterData.buffs, this.gameTime ); this.spawnCount++; } } private addMonster( uuid: number = 1001, i: number = 0, monType: number = 0, lv: number = 1, buffs: BuffConf[] = [], gameTime: number = 0 ) { let mon = ecs.getEntity(Monster); let scale = -1; const x = MonStart.START_X + Math.floor(i / 4) * MonStart.START_I; let y = BoxSet.GAME_LINE; let lane = 0; let pos: Vec3 = v3(x, y, 0); // 递增全局生成顺序 - 溢出保护 this.globalSpawnOrder = (this.globalSpawnOrder + 1) % 999; // 生成怪物 mon.load(pos, scale, uuid, lv, monType, buffs, false, lane, this.globalSpawnOrder, gameTime); } /** 视图对象通过 ecs.Entity.remove(ModuleViewComp) 删除组件是触发组件处理自定义释放逻辑 */ reset() { // this.node.destroy(); } }