98 lines
5.0 KiB
Go
98 lines
5.0 KiB
Go
package routers
|
||
|
||
import (
|
||
"context"
|
||
"sync"
|
||
)
|
||
|
||
var _ = sync.Mutex{}
|
||
var _ = context.Background
|
||
|
||
//
|
||
// 敌人警戒状态机 —— 敌人 HUD(血条 + 挂它上面的警戒条)什么时候出现。
|
||
// 移植自捐赠端 7k-v0.5 的 Drmk.Handlers/Game/GameRouter.EnemyWarning.cs(2026-09-26)。
|
||
// 为什么需要它:客户端的 EnemyHUDCtrl 把潜行警戒条绑在 unitDataSet.detectionState 上
|
||
// (:85 → OnShowDetectionEffect),而 detectionState 只由
|
||
// SyncEnemyDetectStatus(68126766) 写。我们原来在 EngageSpawnedEnemyAsync 里
|
||
// 一 engage 就发 Fight(4),于是敌人一生成警戒条就在那;
|
||
// 捐赠端是先注册 Idle(1),靠距离推进到 Alert(3) / Fight(4)。
|
||
// ⛑⛑⛑ 2026-09-26 02:1x 订正(重要):这套动不了血条。
|
||
// 血条的判据是 EnemyHUDCtrl.lua:551 RefreshHpVisible:
|
||
// canShowHp = cfg.ShowHPBar(模板配置,服务端改不了),
|
||
// shouldShowHp = ... and not HasState(unit, UnitStateConfig.HideHp) and ...。
|
||
// 整条链上没有任何一处读 detectionState。
|
||
// ⇒ "血条默认不显示、打了才显示" 要走 GameRouter.EnemyHpBar.cs(HideHp 10266)。
|
||
// 实测「改了状态机血条还是一直挂着」就是这个原因,不是状态机没生效。
|
||
// 设计要点(照抄捐赠端,别自创):
|
||
// · 状态不变不发包:每 2 s 才允许重估一次,且状态相同就直接跳过。
|
||
// · 注册后两拍必须重发(Warmup=2):模型/occur 重建会把早期那份 HUD 快照丢掉,
|
||
// 只发一次的话血条就永远绑不上。
|
||
// · 单轮最多 8 个:一次 tick 里不能给几十个敌人刷包。
|
||
// · stealthValue 跟 state 走:Fight=100 / Alert=50 / 其余 0(捐赠端原值)。
|
||
// · 死亡/清账必须 clear:留在 Fight 上的尸体会一直挂着一根空血条。
|
||
// ⛑⛑ 这套只改 HUD 显示时机,不碰战斗激活:engage 那五件套
|
||
// (LockTarget / FightEdict / DisarmState / BattleAiS / SyncEnemyDetect)原样不动,
|
||
// 敌人会不会打人跟这里无关。关掉开关就整体回到"一生成就有血条"。
|
||
//
|
||
//
|
||
// 距离平方。用账本里记的敌人坐标(LocalEnemyRecord.Position)对
|
||
// 玩家最后上报的坐标;任一侧没有有效坐标时按"够远"处理(回落到 Idle)。
|
||
//
|
||
func GameRouter_EnemyWarning_LocalEnemyWarningDistanceSquared(ctx context.Context, record any, state any) float32 {
|
||
// Router implementation for GameRouter_EnemyWarning_LocalEnemyWarningDistanceSquared
|
||
return 0
|
||
}
|
||
|
||
//
|
||
// 当前该显示的 detectionState。0 = 不参与(死人/已被骇成友军/坐标没就绪)。
|
||
// 2026-09-26 Wave 4:25 m 内按 AttackRange 分 Alert(3) / Fight(4),
|
||
// 移植 7K EnemyWantsCloseCombat(GameRouter.EnemyAiActions.cs:23-25)的判据:
|
||
// 有攻击技能且距离² ≤ AttackRange² ⇒ Fight,否则 Alert(stealthValue=50)。
|
||
// AttackRange 随 Wave 2 的目录列进来(近战 2.8 / 远程 18)——「远程单位站 20 m 外
|
||
// 开枪是 Alert 不是 Fight」现在能表达了。距离用 LocalEnemyRecord.AiPosition
|
||
// 估算(追击中的敌人会贴近才升 Fight);未接敌时 = 出生点,与旧值一致。
|
||
//
|
||
func GameRouter_EnemyWarning_SelectLocalEnemyWarningState(ctx context.Context, record any, state any) byte {
|
||
// Router implementation for GameRouter_EnemyWarning_SelectLocalEnemyWarningState
|
||
return 0
|
||
}
|
||
|
||
// 同 LocalEnemyWarningDistanceSquared,但用 AI 估算位置
|
||
// (追击中的敌人 LocalEnemyRecord.AiPosition 会被 worker 逐步推向玩家)。
|
||
func GameRouter_EnemyWarning_LocalEnemyWarningAiDistanceSquared(ctx context.Context, record any, state any) float32 {
|
||
// Router implementation for GameRouter_EnemyWarning_LocalEnemyWarningAiDistanceSquared
|
||
return 0
|
||
}
|
||
|
||
func GameRouter_EnemyWarning_SendLocalEnemyWarningStateAsync(ctx context.Context, session *GameSession, id uint64, warningState byte) any {
|
||
// Router implementation for GameRouter_EnemyWarning_SendLocalEnemyWarningStateAsync
|
||
var zero any; return zero
|
||
}
|
||
|
||
//
|
||
// 注册一个敌人进状态机(spawn 之后调一次)。发 SyncEnemyDetect + Idle(1)。
|
||
// 幂等:已经注册过就直接返回。
|
||
//
|
||
func GameRouter_EnemyWarning_PrimeLocalEnemyWarningAsync(ctx context.Context, session *GameSession, uid uint64) any {
|
||
// Router implementation for GameRouter_EnemyWarning_PrimeLocalEnemyWarningAsync
|
||
var zero any; return zero
|
||
}
|
||
|
||
//
|
||
// 周期重估。挂在 RunEnemyAttackAiAsync 的 tick 上(100 ms 一次,内部自己节流到 2 s)。
|
||
//
|
||
func GameRouter_EnemyWarning_RefreshLocalEnemyWarningsAsync(ctx context.Context, session *GameSession, state any, now int64) any {
|
||
// Router implementation for GameRouter_EnemyWarning_RefreshLocalEnemyWarningsAsync
|
||
var zero any; return zero
|
||
}
|
||
|
||
//
|
||
// 死亡 / 拆账本时清掉警戒状态:发 None(0),血条收起。
|
||
// 不清的话尸体上会一直挂一根空血条。
|
||
//
|
||
func GameRouter_EnemyWarning_ClearLocalEnemyWarningAsync(ctx context.Context, session *GameSession, uid uint64) any {
|
||
// Router implementation for GameRouter_EnemyWarning_ClearLocalEnemyWarningAsync
|
||
var zero any; return zero
|
||
}
|
||
|