92 lines
5.2 KiB
Go
92 lines
5.2 KiB
Go
package routers
|
||
|
||
import (
|
||
"context"
|
||
"sync"
|
||
)
|
||
|
||
var _ = sync.Mutex{}
|
||
var _ = context.Background
|
||
|
||
//
|
||
// 白靖(Bai Jing,spirit 15021039)的原生能力 —— 斯安威斯坦(Sandevistan / 子弹时间)。
|
||
// 取证(2026-09-26 03:1x 只读调研 + 2026-09-27 复核捐赠端 7k-v0.5 的同名实现):
|
||
// · BuffConfig 52959495「可以激活斯安威斯坦」Duration -1、IsHidden、Description
|
||
// 「职业标记buff」⇒ 这是能力门闸,由 CharacterCapabilities 作为常驻 buff 下发给白靖。
|
||
// · BuffConfig 52959496「斯安威斯坦」Duration 5 s、Description「子弹时间」、
|
||
// EffectIds [53500525]、IsClientDecide=true ⇒ 真正生效那一份,5 秒到期自己掉。
|
||
// · SkillResourcesConfig Id=4「赛车手职业时缓次数」Max 1 / Default 1 / Interval 30
|
||
// ⇒ 原生就是「一点能量、30 秒回满」,本文件的 5 s / 30 s 与之对齐,不是自造数值。
|
||
// · 白靖的原生职业 = 赛车手(class 11300002 / job 4 Racer)。
|
||
// 触发:只剩原生那一条(2026-09-27 用户拍板)。
|
||
// 客户端按下职业技能按钮 ⇒ AskAddClientBuff(unitId, 52959496) ⇒ 本文件
|
||
// TryStartBaiJingTime4229938;客户端收起(或 buff 自然到期后再次上报摘除)⇒
|
||
// AskRemoveClientBuff(52959496) ⇒ StopBaiJingTime4229938。
|
||
// ⛔ 移植时刻意删掉了捐赠端的第二条触发(挂到当前流派 ActiveSkill 上、reason="active-skill"):
|
||
// 那会让玩家每放一次 E 顺带进一次子弹时间,与原生语义不符 —— 原生是职业技能,不是战技。
|
||
// 按钮到底怎么出来的(2026-09-27 二次取证,推翻上一次的判断):
|
||
// · 真正管用的是驾驶 HUD:DriveControlDriverStore.lua
|
||
// InitButtonValidCheck ⇒ BTN_VALID.PROFESSION_SKILL = self:ShowProfessionSkillButton()
|
||
// 而 ShowProfessionSkillButton 只有一行:
|
||
// return PlayerUnit and gBuffUtils.HasBuff(Pid, BuffConfig.TimeScaleBadgeBuff)
|
||
// ⇒ 骑上载具后按钮出不出来,只取决于玩家身上有没有那个门闸 buff,不查职业。
|
||
// · 按下 ⇒ BattleMgr.lua:580 ClickProfessionSkill() ⇒
|
||
// AskAddClientBuff(Pid, 52959496)(id 在 lua 里是硬编码的,跟我们的常量一致)。
|
||
// · 服务端回 SyncSandevistanStart(68982241) ⇒ 客户端
|
||
// GameSceneToClientImpl.lua:1317 做两件事:
|
||
// CostFightResource(DriveTimeScaleEnergy, 1) + StartGamePlayPause_ChangeOthersTimeSpeed(speed)。
|
||
// ⛑ 别再拿 BattleMgr.lua:414 CheckShowJobSpecialBtn 当判据 —— 那是步行 HUD 那条,
|
||
// 它的两个调用点(CoreHudCharacterControlStore.lua:286 / :3161)都是无参调用,
|
||
// enable==nil ⇒ show 恒 nil ⇒ 只会下发 nil。它不是骑乘这条路。
|
||
// 为什么服务端必须参与:IsClientDecide=true 只说明客户端自己会摘 buff,
|
||
// 世界时间缩放 freezes 与收发制 empirically 由服务端这两条 S2C 决定:
|
||
// · SyncSandevistanStart(68982241) = 单个 float「speed」—— 填 0.2 表示把
|
||
// 世界单位 / 车流降到 0.2 倍、同时清掉受控玩家自身的 pause ⇒ 视觉上「我变快、周围变慢」。
|
||
// 0.2 是本服调参,dump 里没有白靖的原始倍率。
|
||
// · SyncSandevistanEnd(68549031) 无参数。
|
||
// ⛑ 结束必须成对发,否则玩家会永久卡在慢世界里。
|
||
//
|
||
// 会话是否还活着。本仓 TcpSession 没有 ClosedToken,只能用连接状态判断。
|
||
func GameRouter_BaiJingTime_SessionAlive4229938(ctx context.Context, session *GameSession) bool {
|
||
// Router implementation for GameRouter_BaiJingTime_SessionAlive4229938
|
||
return true
|
||
}
|
||
|
||
//
|
||
// 起一次斯安威斯坦。 必须是当前实际操控单位,
|
||
// 角色不对 / 单位不对 / 冷却没到 / 正在切人切场景 ⇒ 一律不生效(返回 false)。
|
||
//
|
||
func GameRouter_BaiJingTime_TryStartBaiJingTime4229938(ctx context.Context, session *GameSession, unitId uint64, reason string) bool {
|
||
// Router implementation for GameRouter_BaiJingTime_TryStartBaiJingTime4229938
|
||
return true
|
||
}
|
||
|
||
//
|
||
// 5 秒到点了自己收(reason=expired);期间只要世界/角色变了立刻收(reason=world-transition)。
|
||
// 短周期 watchdog 是为了覆盖那些不走标准切人/切场景入口的路径。
|
||
//
|
||
func GameRouter_BaiJingTime_RunBaiJingTimeLifecycle4229938(ctx context.Context, session *GameSession, runtime any, serial int64, generation int32, endAt int64, readyAt int64) any {
|
||
// Router implementation for GameRouter_BaiJingTime_RunBaiJingTimeLifecycle4229938
|
||
var zero any; return zero
|
||
}
|
||
|
||
// 对外统一的停止入口(切人 / 切场景 / 客户端摘 buff / 出错清理)。
|
||
func GameRouter_BaiJingTime_StopBaiJingTime4229938(ctx context.Context, session *GameSession, reason string) any {
|
||
// Router implementation for GameRouter_BaiJingTime_StopBaiJingTime4229938
|
||
var zero any; return zero
|
||
}
|
||
|
||
func GameRouter_BaiJingTime_EndBaiJingTimeUnderGate4229938(ctx context.Context, session *GameSession, runtime any, reason string) any {
|
||
// Router implementation for GameRouter_BaiJingTime_EndBaiJingTimeUnderGate4229938
|
||
var zero any; return zero
|
||
}
|
||
|
||
type BaiJingTimeRuntime4229938 struct {
|
||
Gate *sync.Mutex `json:"gate"`
|
||
UnitId uint64 `json:"unitId"`
|
||
BuffInstanceId uint32 `json:"buffInstanceId"`
|
||
Serial int64 `json:"serial"`
|
||
NextReadyAt int64 `json:"nextReadyAt"`
|
||
}
|
||
|