refactor(missionMon): 调整怪物登场排布逻辑
将怪物从按X轴均匀分布改为按类型分三排登场,匹配英雄编队镜像布局,高优先级怪物自动占据前排
This commit is contained in:
@@ -7,7 +7,7 @@
|
|||||||
* 2. 战斗开始:PhasePrepareEnd 时恢复怪物行动(in_fight 前怪物仅原地待命,不会推进/索敌)。
|
* 2. 战斗开始:PhasePrepareEnd 时恢复怪物行动(in_fight 前怪物仅原地待命,不会推进/索敌)。
|
||||||
*
|
*
|
||||||
* 关键设计:
|
* 关键设计:
|
||||||
* - 5 只怪在 X∈[100,320] 内按登场序号均匀铺开,Boss/小怪同时登场,玩家看清阵容后三选一。
|
* - 怪物按类型落排(近战/Boss→前排、远程/刺客→中排、辅助/召唤→后排),与英雄三排镜像对应。
|
||||||
* - 实际推进由统一 MoveComp 在战斗中向敌人移动自然形成,不再使用固定网格点。
|
* - 实际推进由统一 MoveComp 在战斗中向敌人移动自然形成,不再使用固定网格点。
|
||||||
* - 槽位索引仅用于 monGrid 寻路与 SCastSystem 索敌定位。
|
* - 槽位索引仅用于 monGrid 寻路与 SCastSystem 索敌定位。
|
||||||
*/
|
*/
|
||||||
@@ -19,8 +19,9 @@ import { oops } from "../../../../extensions/oops-plugin-framework/assets/core/O
|
|||||||
import { Monster } from "../hero/Mon";
|
import { Monster } from "../hero/Mon";
|
||||||
import { smc } from "../common/SingletonModuleComp";
|
import { smc } from "../common/SingletonModuleComp";
|
||||||
import { GameEvent } from "../common/config/GameEvent";
|
import { GameEvent } from "../common/config/GameEvent";
|
||||||
import { BoxSet } from "../common/config/GameSet";
|
import { BoxSet, FightSet } from "../common/config/GameSet";
|
||||||
import { spawningEngine, GeneratedMonster, TestModeConfig, BOSS_COUNT, MINION_COUNT } from "./RogueConfig";
|
import { MonType } from "../common/config/heroSet";
|
||||||
|
import { spawningEngine, GeneratedMonster, TestModeConfig } from "./RogueConfig";
|
||||||
import { HeroAttrsComp } from "../hero/HeroAttrsComp";
|
import { HeroAttrsComp } from "../hero/HeroAttrsComp";
|
||||||
import { MoveComp } from "../hero/MoveComp";
|
import { MoveComp } from "../hero/MoveComp";
|
||||||
|
|
||||||
@@ -33,10 +34,23 @@ export class MissionMonCompComp extends CCComp {
|
|||||||
|
|
||||||
/** 怪物出生掉落高度 */
|
/** 怪物出生掉落高度 */
|
||||||
private static readonly MON_DROP_HEIGHT = 0;
|
private static readonly MON_DROP_HEIGHT = 0;
|
||||||
/** 怪物登场 X 范围下限(靠近英雄侧) */
|
|
||||||
private static readonly SPAWN_X_MIN = 100;
|
/**
|
||||||
/** 怪物登场 X 范围上限(靠近右侧) */
|
* 怪物类型 → 编队优先级(与英雄 HRole 枚举值升序一致):
|
||||||
private static readonly SPAWN_X_MAX = 320;
|
* 近战/重型/近战Boss → 0(最优先,占前排),
|
||||||
|
* 远程/刺客/远程Boss → 1(占中排),
|
||||||
|
* 辅助/召唤师 → 2(占后排)。
|
||||||
|
*/
|
||||||
|
private static readonly MON_TYPE_PRIORITY: Record<number, number> = {
|
||||||
|
[MonType.Melee]: 0,
|
||||||
|
[MonType.Heavy]: 0,
|
||||||
|
[MonType.MeleeBoss]: 0,
|
||||||
|
[MonType.Long]: 1,
|
||||||
|
[MonType.Assassin]: 1,
|
||||||
|
[MonType.LongBoss]: 1,
|
||||||
|
[MonType.Support]: 2,
|
||||||
|
[MonType.Summoner]: 2,
|
||||||
|
};
|
||||||
|
|
||||||
/** 槽位基准 Y(3行×4列结构仅供 monGrid 寻路与 SCastSystem 索敌定位) */
|
/** 槽位基准 Y(3行×4列结构仅供 monGrid 寻路与 SCastSystem 索敌定位) */
|
||||||
public static readonly MON_POSITIONS: Vec3[] = [
|
public static readonly MON_POSITIONS: Vec3[] = [
|
||||||
@@ -104,11 +118,16 @@ export class MissionMonCompComp extends CCComp {
|
|||||||
smc.vmdata.mission_data.pending_mon_num = this.waveTargetCount;
|
smc.vmdata.mission_data.pending_mon_num = this.waveTargetCount;
|
||||||
|
|
||||||
// 怪物先行登场:玩家侦查 Boss 组合后再做英雄三选一(in_fight 前怪物原地待命,不推进不索敌)
|
// 怪物先行登场:玩家侦查 Boss 组合后再做英雄三选一(in_fight 前怪物原地待命,不推进不索敌)
|
||||||
const squad = this.spawnQueue;
|
// 按编队优先级排序后依次登场:近战/Boss(0) → 远程/刺客(1) → 辅助/召唤(2)
|
||||||
|
const squad = [...this.spawnQueue].sort((a, b) => {
|
||||||
|
const pa = MissionMonCompComp.MON_TYPE_PRIORITY[a.type] ?? 1;
|
||||||
|
const pb = MissionMonCompComp.MON_TYPE_PRIORITY[b.type] ?? 1;
|
||||||
|
return pa - pb;
|
||||||
|
});
|
||||||
this.spawnQueue = [];
|
this.spawnQueue = [];
|
||||||
smc.vmdata.mission_data.pending_mon_num = 0;
|
smc.vmdata.mission_data.pending_mon_num = 0;
|
||||||
for (const monData of squad) {
|
for (let i = 0; i < squad.length; i++) {
|
||||||
this.addMonsterAtGrid(this.waveSpawnedCount, monData, this.currentWave);
|
this.addMonsterAtGrid(i, squad[i], this.currentWave);
|
||||||
this.waveSpawnedCount++;
|
this.waveSpawnedCount++;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -126,9 +145,24 @@ export class MissionMonCompComp extends CCComp {
|
|||||||
|
|
||||||
// ======================== 怪物生成 ========================
|
// ======================== 怪物生成 ========================
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 解析怪物出生 X:按编队优先级名次映射三排锚点(与英雄编队排队逻辑一致)。
|
||||||
|
* 名次映射:rank0→前排(MON_ROW_FRONT_X)、rank1→中排(MON_ROW_MID_X)、rank≥2→后排(MON_ROW_BACK_X)。
|
||||||
|
* 效果:高优先级类型永远占据更靠前的排;当更高优先级类型插入时,低优先级类型自动向后让位。
|
||||||
|
*
|
||||||
|
* @param index 当前怪物在排序后列表中的索引(名次)
|
||||||
|
* @returns 出生 X 坐标
|
||||||
|
*/
|
||||||
|
private resolveSpawnX(index: number): number {
|
||||||
|
if (index === 0) return FightSet.MON_ROW_FRONT_X;
|
||||||
|
if (index === 1) return FightSet.MON_ROW_MID_X;
|
||||||
|
return FightSet.MON_ROW_BACK_X;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 在指定位置索引处生成一个怪物
|
* 在指定位置索引处生成一个怪物
|
||||||
* 5 只怪在 X∈[100,320] 内按登场序号均匀铺开,Boss/小怪同时登场直接开打
|
* 怪物按编队优先级名次落排(rank0→前排、rank1→中排、rank≥2→后排),
|
||||||
|
* 与英雄编队排队逻辑一致:高优先级类型永远占更靠前的排,低优先级自动让位。
|
||||||
*/
|
*/
|
||||||
private addMonsterAtGrid(
|
private addMonsterAtGrid(
|
||||||
posIndex: number,
|
posIndex: number,
|
||||||
@@ -139,9 +173,7 @@ export class MissionMonCompComp extends CCComp {
|
|||||||
let scale = -1;
|
let scale = -1;
|
||||||
|
|
||||||
const basePos = MissionMonCompComp.MON_POSITIONS[posIndex % MissionMonCompComp.MON_POSITIONS.length];
|
const basePos = MissionMonCompComp.MON_POSITIONS[posIndex % MissionMonCompComp.MON_POSITIONS.length];
|
||||||
const spawnX = MissionMonCompComp.SPAWN_X_MIN
|
const spawnX = this.resolveSpawnX(posIndex);
|
||||||
+ (MissionMonCompComp.SPAWN_X_MAX - MissionMonCompComp.SPAWN_X_MIN)
|
|
||||||
* (posIndex / Math.max(1, BOSS_COUNT + MINION_COUNT - 1));
|
|
||||||
const landingY = basePos.y;
|
const landingY = basePos.y;
|
||||||
const spawnPos: Vec3 = v3(spawnX, landingY + MissionMonCompComp.MON_DROP_HEIGHT, 0);
|
const spawnPos: Vec3 = v3(spawnX, landingY + MissionMonCompComp.MON_DROP_HEIGHT, 0);
|
||||||
this.globalSpawnOrder = (this.globalSpawnOrder + 1) % 999;
|
this.globalSpawnOrder = (this.globalSpawnOrder + 1) % 999;
|
||||||
|
|||||||
Reference in New Issue
Block a user