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_extraction_weapons.go
T

144 lines
7.7 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
//
// 搜打撤「武器轮盘」的武器实体化 —— 把轮盘 bag 里的枪变成 gWeaponManager 认得的武器。
// 为什么必须有这一层:搜打撤里有两套互不相干的武器系统。
// · 轮盘 bag(99952004)= 物品存储。客户端 BackCircleAnantarkovStore 用
// gExtractionShooterManager:GetItemInfoBySlot(slotIndex, wheel) 读它,只负责「画格子」。
// · 实体化武器 = gWeaponManager.CurrWeaponSlots,由 SyncSpiritWeaponDetail /
// SyncSpiritAddWeaponAction 灌进来,只管「切枪」。
// 把物品挪进轮盘 bag 只动了第一套。Tab / 滚轮切枪走的是
// WeaponManager:GetNextCircleWeapon → 只遍历 CurrWeaponSlots,
// 而且 BackCircleAnantarkovStore.OnCircleButtonClick 是空的(点格子不切枪),
// 所以第二套没跟上时,不管往轮盘里放了多少把枪,Tab 永远只在拳头和角色自带那把之间转。
// 下标口径(三处证据一致,见 ExtractionShooterRuntime4229938.WheelHomeOffset4229938):
// CurrWeaponSlots 下标 0 = 拳头、1 = 私有武器、2 + k = 轮盘 CellX k。
// 下发策略:整表(SyncSpiritWeaponDetail)最稳、增量(Add/RemoveWeaponAction)最省,
// 两种都留着并由配置切换(world.content.extraction.wheelSync)。
// 增量一旦发现「当前武器要被摘掉」就自动退回整表,免得客户端 OnSwitchCurrentWeapon
// 找不到人而打 "Not Find Current Weapon"。
//
//
// 让 gWeaponManager 跟上轮盘 bag 的当前内容。轮盘 bag 每变动一次、进图、切角色都要调。
// 静默跳过的三种情况(都不是错误):
// · 模式为 Off;
// · state.Ready 还没置起 —— 世界还没起,客户端 gWeaponManager 还没建,
// 这时候发过去会被丢掉,等世界就绪时那次调用才是有效的;
// · 当前不在搜打撤图里 —— 轮盘 bag 属于搜打撤玩法,主城里没有这套 UI,
// 乱发 SyncSpiritWeaponDetail 会把城镇的 16 槽武器盘覆盖成搜打撤的 9 槽。
//
func GameRouter_ExtractionWeapons_PushExtractionWheelSyncAsync(ctx context.Context, session *GameSession, state any, phase string) any {
// Router implementation for GameRouter_ExtractionWeapons_PushExtractionWheelSyncAsync
var zero any; return zero
}
//
// 整表重发:SyncSpiritWeaponDetail(68255545)。客户端把它整体灌进
// CurrWeaponSlots 并按 CurrentWeaponUid 切当前武器,所以顺带就能自愈
// 「客户端已经把 WeaponManager 重建过」这类状态漂移。
//
func GameRouter_ExtractionWeapons_PushExtractionWheelSnapshotAsync(ctx context.Context, session *GameSession, state any, phase string) any {
// Router implementation for GameRouter_ExtractionWeapons_PushExtractionWheelSnapshotAsync
var zero any; return zero
}
//
// 把「此刻轮盘的内容」记成增量基线。整表下发之后必须调一次,否则下一次增量会拿着
// 过期的镜像做差,把已经变过的格当成没变。
//
func GameRouter_ExtractionWeapons_RecordExtractionWheelPublished(ctx context.Context, session *GameSession, state any) any {
// Router implementation for GameRouter_ExtractionWeapons_RecordExtractionWheelPublished
var zero any; return zero
}
//
// 搜打撤版的武器表:[拳头, 私有武器, 轮盘 CellX 0..N-1]。
// 城镇的 CombatCodec.SpiritWeaponSnapshot 用的是角色 16 槽配装,进图后要换成这一张 ——
// PublishWeaponSnapshot(切场景后首次移动也会走一次)必须按同一口径发,
// 否则城镇那张 16 槽表会把刚补好的轮盘覆盖掉,轮盘枪又从 CurrWeaponSlots 里消失。
//
func GameRouter_ExtractionWeapons_BuildExtractionWheelSnapshot(ctx context.Context, session *GameSession, state any, unitId uint64, templateId uint32, currentWeaponInstanceId uint64) any {
// Router implementation for GameRouter_ExtractionWeapons_BuildExtractionWheelSnapshot
var zero any; return zero
}
//
// 搜打撤里 AskSwitchWeapon(index) 的解析:下标 0/1 取角色配装的拳头 / 私有武器,
// 下标 ≥ 2 取轮盘 bag 里 CellX = index - 2 那把。
// 只有这一条路径能把轮盘枪切成手上这把 —— 客户端轮盘界面的点击是空的
// (BackCircleAnantarkovStore.OnCircleButtonClick 什么都不做),切枪全靠
// Tab / 滚轮走 GetNextCircleWeapon 遍历 CurrWeaponSlots 后发这条请求,
// 所以这里必须能把它按位置还原成袋子里那把枪。
//
func GameRouter_ExtractionWeapons_ExtractionSwitchWeaponAt(ctx context.Context, session *GameSession, state any, index int32) any {
// Router implementation for GameRouter_ExtractionWeapons_ExtractionSwitchWeaponAt
var zero any; return zero
}
//
// 增量:把「服务端镜像」和「轮盘 bag 现状」做差,只发变了的格。
// 有一个必须退整表的情形:当前武器被摘掉了。增量只发 Remove 的话客户端会把那一格置空,
// 但手上还拿着已不存在的 instance,之后所有技能请求都会解析失败。
// 整表里带着合法的 CurrentWeaponUid,客户端自己会切过去,所以这里直接改走整表。
//
func GameRouter_ExtractionWeapons_PushExtractionWheelDeltaAsync(ctx context.Context, session *GameSession, state any, phase string) any {
// Router implementation for GameRouter_ExtractionWeapons_PushExtractionWheelDeltaAsync
var zero any; return zero
}
// 把轮盘 bag 的现状按 CurrWeaponSlots 下标排成表。
func GameRouter_ExtractionWeapons_WheelWeaponsByIndex(ctx context.Context, session *GameSession) map[string]any {
// Router implementation for GameRouter_ExtractionWeapons_WheelWeaponsByIndex
return nil
}
// 一次快照下发要用到的三件东西:角色模板、单位 id、当前武器实例。
func GameRouter_ExtractionWeapons_WheelSyncTarget(ctx context.Context, state any) any {
// Router implementation for GameRouter_ExtractionWeapons_WheelSyncTarget
var zero any; return zero
}
//
// CurrWeaponSlots[0](拳头)和 [1](私有武器)—— 这两个位置不属于轮盘,
// 直接取角色自己的配装 Slots[0] / Slots[1],它们的流派 / 技能是作者配好的。
//
func GameRouter_ExtractionWeapons_WheelHeadWeapons(ctx context.Context, state any, templateId uint32) any {
// Router implementation for GameRouter_ExtractionWeapons_WheelHeadWeapons
var zero any; return zero
}
//
// 序列化前给一件实体化武器盖上真实的弹药 / 耐久 / 流派 / 子弹。
// 轮盘武器的这些值活在 WorldEntryState(Handler 层)里,和城镇
// PublishWeaponSnapshot 用的是同一套状态,所以两边口径天然一致:
// 一把枪在城镇打完的弹量,进图后接着算,不会因为换了条下发路径就回满。
// ⚠️ 用账号军械库查(CombatCatalogRepository.Weapon(instanceId))而不是只在角色配装里查:
// 轮盘里的枪是账号军械库的(PersonalWeapons 之外),查错会静默跳过 ⇒
// 下发出去的枪 Durability/MagazineAmmo 全是模板默认值。
//
func GameRouter_ExtractionWeapons_PrepareWheelWeaponDetail(ctx context.Context, state any, templateId uint32, detail any) any {
// Router implementation for GameRouter_ExtractionWeapons_PrepareWheelWeaponDetail
var zero any; return zero
}
// 轮盘武器实体化的下发方式。
type ExtractionWheelSyncMode4229938 int32
const (
// 完全不下发(排障用,等价于修复前的行为)。
ExtractionWheelSyncMode4229938_Off ExtractionWheelSyncMode4229938 = iota
// 只发变化的格(SyncSpiritAddWeaponAction / SyncSpiritRemoveWeaponAction)。
ExtractionWheelSyncMode4229938_Incremental
// 每次变动重发整表(SyncSpiritWeaponDetail)。默认。
ExtractionWheelSyncMode4229938_Full
)