This repository has been archived on 2026-10-31. You can view files and clone it. You cannot open issues or pull requests or push a commit.
Files
Ananta-ps/internal/gameserver/routers/game_router_enemy_warning.go
T

98 lines
5.0 KiB
Go
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
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
}