diff --git a/gs/game/player_fight_sync.go b/gs/game/player_fight_sync.go index 14d9d09d..25e32a3f 100644 --- a/gs/game/player_fight_sync.go +++ b/gs/game/player_fight_sync.go @@ -327,7 +327,10 @@ func (g *GameManager) AoiPlayerMove(player *model.Player, oldPos *model.Vector, for _, entity := range group.GetAllEntity() { delEntityIdList = append(delEntityIdList, entity.GetId()) } - g.RemoveGroup(scene, groupConfig) + if !world.GetMultiplayer() { + // 处理多人世界不同玩家不同位置的group卸载情况 + g.RemoveGroup(scene, groupConfig) + } } // 出现的场景实体 addEntityIdList := make([]uint32, 0) @@ -339,6 +342,9 @@ func (g *GameManager) AoiPlayerMove(player *model.Player, oldPos *model.Vector, // 新有旧没有的group即为出现的 g.AddSceneGroup(scene, groupConfig) group := scene.GetGroupById(groupId) + if group == nil { + continue + } for _, entity := range group.GetAllEntity() { addEntityIdList = append(addEntityIdList, entity.GetId()) } diff --git a/gs/game/player_scene.go b/gs/game/player_scene.go index f21ef1ed..c0718104 100644 --- a/gs/game/player_scene.go +++ b/gs/game/player_scene.go @@ -10,7 +10,6 @@ import ( "hk4e/gs/model" "hk4e/pkg/logger" "hk4e/pkg/object" - "hk4e/pkg/random" "hk4e/protocol/cmd" "hk4e/protocol/proto" @@ -23,24 +22,59 @@ const ( ) func (g *GameManager) EnterSceneReadyReq(player *model.Player, payloadMsg pb.Message) { + req := payloadMsg.(*proto.EnterSceneReadyReq) logger.Debug("player enter scene ready, uid: %v", player.PlayerID) world := WORLD_MANAGER.GetWorldByID(player.WorldId) + enterSceneContext := world.GetEnterSceneContextByToken(req.EnterSceneToken) + aoiManager, exist := WORLD_MANAGER.GetSceneBlockAoiMap()[enterSceneContext.OldSceneId] + if !exist { + logger.Error("player scene not exist in aoi, sceneId: %v, uid: %v", enterSceneContext.OldSceneId, player.PlayerID) + return + } + objectList := aoiManager.GetObjectListByPos(float32(enterSceneContext.OldPos.X), 0.0, float32(enterSceneContext.OldPos.Z)) + delEntityIdList := make([]uint32, 0) + oldScene := world.GetSceneById(enterSceneContext.OldSceneId) + for _, groupAny := range objectList { + groupConfig := groupAny.(*gdconf.Group) + distance2D := math.Sqrt((player.Pos.X-float64(groupConfig.Pos.X))*(player.Pos.X-float64(groupConfig.Pos.X)) + + (player.Pos.Z-float64(groupConfig.Pos.Z))*(player.Pos.Z-float64(groupConfig.Pos.Z))) + if distance2D > ENTITY_LOD { + continue + } + if groupConfig.DynamicLoad { + continue + } + group := oldScene.GetGroupById(uint32(groupConfig.Id)) + if group == nil { + continue + } + for _, entity := range group.GetAllEntity() { + delEntityIdList = append(delEntityIdList, entity.GetId()) + } + if !world.GetMultiplayer() { + // 处理多人世界不同玩家不同位置的group卸载情况 + g.RemoveGroup(oldScene, groupConfig) + } + } + g.RemoveSceneEntityNotifyToPlayer(player, proto.VisionType_VISION_MISS, delEntityIdList) + enterScenePeerNotify := &proto.EnterScenePeerNotify{ DestSceneId: player.SceneId, PeerId: world.GetPlayerPeerId(player), HostPeerId: world.GetPlayerPeerId(world.GetOwner()), - EnterSceneToken: player.EnterSceneToken, + EnterSceneToken: req.EnterSceneToken, } g.SendMsg(cmd.EnterScenePeerNotify, player.PlayerID, player.ClientSeq, enterScenePeerNotify) enterSceneReadyRsp := &proto.EnterSceneReadyRsp{ - EnterSceneToken: player.EnterSceneToken, + EnterSceneToken: req.EnterSceneToken, } g.SendMsg(cmd.EnterSceneReadyRsp, player.PlayerID, player.ClientSeq, enterSceneReadyRsp) } func (g *GameManager) SceneInitFinishReq(player *model.Player, payloadMsg pb.Message) { + req := payloadMsg.(*proto.SceneInitFinishReq) logger.Debug("player scene init finish, uid: %v", player.PlayerID) world := WORLD_MANAGER.GetWorldByID(player.WorldId) scene := world.GetSceneById(player.SceneId) @@ -136,7 +170,7 @@ func (g *GameManager) SceneInitFinishReq(player *model.Player, payloadMsg pb.Mes activeAvatarId := world.GetPlayerActiveAvatarId(player) playerEnterSceneInfoNotify := &proto.PlayerEnterSceneInfoNotify{ CurAvatarEntityId: world.GetPlayerWorldAvatarEntityId(player, activeAvatarId), - EnterSceneToken: player.EnterSceneToken, + EnterSceneToken: req.EnterSceneToken, TeamEnterInfo: &proto.TeamEnterSceneInfo{ TeamEntityId: world.GetPlayerTeamEntityId(player), TeamAbilityInfo: empty, @@ -235,30 +269,15 @@ func (g *GameManager) SceneInitFinishReq(player *model.Player, payloadMsg pb.Mes g.SendMsg(cmd.DungeonDataNotify, player.PlayerID, player.ClientSeq, &proto.DungeonDataNotify{}) SceneInitFinishRsp := &proto.SceneInitFinishRsp{ - EnterSceneToken: player.EnterSceneToken, + EnterSceneToken: req.EnterSceneToken, } g.SendMsg(cmd.SceneInitFinishRsp, player.PlayerID, player.ClientSeq, SceneInitFinishRsp) player.SceneLoadState = model.SceneInitFinish } -func (g *GameManager) AddSceneGroup(scene *Scene, groupConfig *gdconf.Group) { - initSuiteId := int(groupConfig.GroupInitConfig.Suite) - if initSuiteId > len(groupConfig.SuiteList) { - logger.Error("invalid init suite id: %v", initSuiteId) - return - } - scene.AddGroupSuite(uint32(groupConfig.Id), uint8(initSuiteId)) -} - -func (g *GameManager) RemoveGroup(scene *Scene, groupConfig *gdconf.Group) { - group := scene.GetGroupById(uint32(groupConfig.Id)) - for suiteId := range group.GetAllSuite() { - scene.RemoveGroupSuite(uint32(groupConfig.Id), suiteId) - } -} - func (g *GameManager) EnterSceneDoneReq(player *model.Player, payloadMsg pb.Message) { + req := payloadMsg.(*proto.EnterSceneDoneReq) logger.Debug("player enter scene done, uid: %v", player.PlayerID) world := WORLD_MANAGER.GetWorldByID(player.WorldId) scene := world.GetSceneById(player.SceneId) @@ -288,39 +307,35 @@ func (g *GameManager) EnterSceneDoneReq(player *model.Player, payloadMsg pb.Mess // 加载附近的group aoiManager, exist := WORLD_MANAGER.GetSceneBlockAoiMap()[scene.GetId()] - addEntityIdList := make([]uint32, 0) - if exist { - objectList := aoiManager.GetObjectListByPos(float32(player.Pos.X), 0.0, float32(player.Pos.Z)) - for _, groupAny := range objectList { - groupConfig := groupAny.(*gdconf.Group) - distance2D := math.Sqrt((player.Pos.X-float64(groupConfig.Pos.X))*(player.Pos.X-float64(groupConfig.Pos.X)) + - (player.Pos.Z-float64(groupConfig.Pos.Z))*(player.Pos.Z-float64(groupConfig.Pos.Z))) - if distance2D > ENTITY_LOD { - continue - } - if groupConfig.DynamicLoad { - continue - } - g.AddSceneGroup(scene, groupConfig) - group := scene.GetGroupById(uint32(groupConfig.Id)) - for _, entity := range group.GetAllEntity() { - addEntityIdList = append(addEntityIdList, entity.GetId()) - } - } + if !exist { + logger.Error("player scene not exist in aoi, sceneId: %v, uid: %v", scene.GetId(), player.PlayerID) + return + } + objectList := aoiManager.GetObjectListByPos(float32(player.Pos.X), 0.0, float32(player.Pos.Z)) + for _, groupAny := range objectList { + groupConfig := groupAny.(*gdconf.Group) + distance2D := math.Sqrt((player.Pos.X-float64(groupConfig.Pos.X))*(player.Pos.X-float64(groupConfig.Pos.X)) + + (player.Pos.Z-float64(groupConfig.Pos.Z))*(player.Pos.Z-float64(groupConfig.Pos.Z))) + if distance2D > ENTITY_LOD { + continue + } + if groupConfig.DynamicLoad { + continue + } + g.AddSceneGroup(scene, groupConfig) } - entityIdList := make([]uint32, 0) if player.SceneJump { visionType = proto.VisionType_VISION_MEET - entityMap := scene.GetAllEntity() - for _, entity := range entityMap { - if entity.GetId() == activeAvatarEntityId { - continue - } - entityIdList = append(entityIdList, entity.GetId()) - } } else { visionType = proto.VisionType_VISION_TRANSPORT - entityIdList = addEntityIdList + } + entityIdList := make([]uint32, 0) + entityMap := scene.GetAllEntity() + for _, entity := range entityMap { + if entity.GetId() == activeAvatarEntityId { + continue + } + entityIdList = append(entityIdList, entity.GetId()) } g.AddSceneEntityNotify(player, visionType, entityIdList, false, false) @@ -331,7 +346,7 @@ func (g *GameManager) EnterSceneDoneReq(player *model.Player, payloadMsg pb.Mess g.SendMsg(cmd.SceneAreaWeatherNotify, player.PlayerID, player.ClientSeq, sceneAreaWeatherNotify) enterSceneDoneRsp := &proto.EnterSceneDoneRsp{ - EnterSceneToken: player.EnterSceneToken, + EnterSceneToken: req.EnterSceneToken, } g.SendMsg(cmd.EnterSceneDoneRsp, player.PlayerID, player.ClientSeq, enterSceneDoneRsp) @@ -351,10 +366,11 @@ func (g *GameManager) EnterSceneDoneReq(player *model.Player, payloadMsg pb.Mess } func (g *GameManager) PostEnterSceneReq(player *model.Player, payloadMsg pb.Message) { + req := payloadMsg.(*proto.PostEnterSceneReq) logger.Debug("player post enter scene, uid: %v", player.PlayerID) postEnterSceneRsp := &proto.PostEnterSceneRsp{ - EnterSceneToken: player.EnterSceneToken, + EnterSceneToken: req.EnterSceneToken, } g.SendMsg(cmd.PostEnterSceneRsp, player.PlayerID, player.ClientSeq, postEnterSceneRsp) } @@ -384,7 +400,6 @@ func (g *GameManager) ChangeGameTimeReq(player *model.Player, payloadMsg pb.Mess g.SendMsg(cmd.ChangeGameTimeRsp, player.PlayerID, player.ClientSeq, changeGameTimeRsp) } -// SceneEntityDrownReq 实体溺水请求 func (g *GameManager) SceneEntityDrownReq(player *model.Player, payloadMsg pb.Message) { req := payloadMsg.(*proto.SceneEntityDrownReq) @@ -401,6 +416,18 @@ func (g *GameManager) SceneEntityDrownReq(player *model.Player, payloadMsg pb.Me g.SendMsg(cmd.SceneEntityDrownRsp, player.PlayerID, player.ClientSeq, sceneEntityDrownRsp) } +func (g *GameManager) NpcTalkReq(player *model.Player, payloadMsg pb.Message) { + req := payloadMsg.(*proto.NpcTalkReq) + rsp := &proto.NpcTalkRsp{ + CurTalkId: req.TalkId, + NpcEntityId: req.NpcEntityId, + EntityId: req.EntityId, + } + g.SendMsg(cmd.EnterSceneReadyRsp, player.PlayerID, player.ClientSeq, rsp) +} + +var SceneTransactionSeq uint32 = 0 + func (g *GameManager) PacketPlayerEnterSceneNotifyLogin(player *model.Player, enterType proto.EnterType) *proto.PlayerEnterSceneNotify { world := WORLD_MANAGER.GetWorldByID(player.WorldId) scene := world.GetSceneById(player.SceneId) @@ -408,24 +435,24 @@ func (g *GameManager) PacketPlayerEnterSceneNotifyLogin(player *model.Player, en logger.Error("scene is nil, sceneId: %v", player.SceneId) return new(proto.PlayerEnterSceneNotify) } - player.EnterSceneToken = uint32(random.GetRandomInt32(5000, 50000)) playerEnterSceneNotify := &proto.PlayerEnterSceneNotify{ SceneId: player.SceneId, Pos: &proto.Vector{X: float32(player.Pos.X), Y: float32(player.Pos.Y), Z: float32(player.Pos.Z)}, SceneBeginTime: uint64(scene.GetSceneCreateTime()), Type: enterType, TargetUid: player.PlayerID, - EnterSceneToken: player.EnterSceneToken, + EnterSceneToken: world.enterSceneToken, WorldLevel: player.PropertiesMap[constant.PLAYER_PROP_PLAYER_WORLD_LEVEL], EnterReason: uint32(proto.EnterReason_ENTER_REASON_LOGIN), IsFirstLoginEnterScene: true, WorldType: 1, SceneTagIdList: make([]uint32, 0), } + SceneTransactionSeq++ playerEnterSceneNotify.SceneTransaction = strconv.Itoa(int(player.SceneId)) + "-" + strconv.Itoa(int(player.PlayerID)) + "-" + strconv.Itoa(int(time.Now().Unix())) + "-" + - "296359" + strconv.Itoa(int(SceneTransactionSeq)) for _, sceneTagDataConfig := range gdconf.GetSceneTagDataMap() { if uint32(sceneTagDataConfig.SceneId) == player.SceneId { playerEnterSceneNotify.SceneTagIdList = append(playerEnterSceneNotify.SceneTagIdList, uint32(sceneTagDataConfig.SceneTagId)) @@ -460,7 +487,14 @@ func (g *GameManager) PacketPlayerEnterSceneNotifyMp( logger.Error("scene is nil, sceneId: %v", player.SceneId) return new(proto.PlayerEnterSceneNotify) } - player.EnterSceneToken = uint32(random.GetRandomInt32(5000, 50000)) + enterSceneToken := world.AddEnterSceneContext(&EnterSceneContext{ + OldSceneId: prevSceneId, + OldPos: &model.Vector{ + X: prevPos.X, + Y: prevPos.Y, + Z: prevPos.Z, + }, + }) playerEnterSceneNotify := &proto.PlayerEnterSceneNotify{ PrevSceneId: prevSceneId, PrevPos: &proto.Vector{X: float32(prevPos.X), Y: float32(prevPos.Y), Z: float32(prevPos.Z)}, @@ -469,17 +503,18 @@ func (g *GameManager) PacketPlayerEnterSceneNotifyMp( SceneBeginTime: uint64(scene.GetSceneCreateTime()), Type: enterType, TargetUid: targetPlayer.PlayerID, - EnterSceneToken: player.EnterSceneToken, + EnterSceneToken: enterSceneToken, WorldLevel: targetPlayer.PropertiesMap[constant.PLAYER_PROP_PLAYER_WORLD_LEVEL], EnterReason: enterReason, WorldType: 1, DungeonId: dungeonId, SceneTagIdList: make([]uint32, 0), } + SceneTransactionSeq++ playerEnterSceneNotify.SceneTransaction = strconv.Itoa(int(player.SceneId)) + "-" + strconv.Itoa(int(targetPlayer.PlayerID)) + "-" + strconv.Itoa(int(time.Now().Unix())) + "-" + - "296359" + strconv.Itoa(int(SceneTransactionSeq)) for _, sceneTagDataConfig := range gdconf.GetSceneTagDataMap() { if uint32(sceneTagDataConfig.SceneId) == player.SceneId { playerEnterSceneNotify.SceneTagIdList = append(playerEnterSceneNotify.SceneTagIdList, uint32(sceneTagDataConfig.SceneTagId)) @@ -488,6 +523,26 @@ func (g *GameManager) PacketPlayerEnterSceneNotifyMp( return playerEnterSceneNotify } +func (g *GameManager) AddSceneGroup(scene *Scene, groupConfig *gdconf.Group) { + initSuiteId := int(groupConfig.GroupInitConfig.Suite) + if initSuiteId < 1 || initSuiteId > len(groupConfig.SuiteList) { + logger.Error("invalid init suite id: %v", initSuiteId) + return + } + scene.AddGroupSuite(uint32(groupConfig.Id), uint8(initSuiteId)) +} + +func (g *GameManager) RemoveGroup(scene *Scene, groupConfig *gdconf.Group) { + group := scene.GetGroupById(uint32(groupConfig.Id)) + if group == nil { + logger.Error("group not exist, groupId: %v", groupConfig.Id) + return + } + for suiteId := range group.GetAllSuite() { + scene.RemoveGroupSuite(uint32(groupConfig.Id), suiteId) + } +} + func (g *GameManager) AddSceneEntityNotifyToPlayer(player *model.Player, visionType proto.VisionType, entityList []*proto.SceneEntityInfo) { sceneEntityAppearNotify := &proto.SceneEntityAppearNotify{ AppearType: visionType, diff --git a/gs/game/route_manager.go b/gs/game/route_manager.go index bd72faa0..962b9a3f 100644 --- a/gs/game/route_manager.go +++ b/gs/game/route_manager.go @@ -140,6 +140,7 @@ func (r *RouteManager) initRoute() { r.registerRouter(cmd.SetEquipLockStateReq, GAME_MANAGER.SetEquipLockStateReq) r.registerRouter(cmd.TakeoffEquipReq, GAME_MANAGER.TakeoffEquipReq) r.registerRouter(cmd.AddQuestContentProgressReq, GAME_MANAGER.AddQuestContentProgressReq) + r.registerRouter(cmd.NpcTalkReq, GAME_MANAGER.NpcTalkReq) } func (r *RouteManager) RouteHandle(netMsg *mq.NetMsg) { diff --git a/gs/game/world_manager.go b/gs/game/world_manager.go index b1c9c049..81c2befb 100644 --- a/gs/game/world_manager.go +++ b/gs/game/world_manager.go @@ -8,6 +8,7 @@ import ( "hk4e/gs/model" "hk4e/pkg/alg" "hk4e/pkg/logger" + "hk4e/pkg/random" "hk4e/protocol/proto" ) @@ -47,19 +48,21 @@ func (w *WorldManager) GetAllWorld() map[uint32]*World { func (w *WorldManager) CreateWorld(owner *model.Player) *World { worldId := uint32(w.snowflake.GenId()) world := &World{ - id: worldId, - owner: owner, - playerMap: make(map[uint32]*model.Player), - sceneMap: make(map[uint32]*Scene), - entityIdCounter: 0, - worldLevel: 0, - multiplayer: false, - mpLevelEntityId: 0, - chatMsgList: make([]*proto.ChatInfo, 0), - playerFirstEnterMap: make(map[uint32]int64), - waitEnterPlayerMap: make(map[uint32]int64), - multiplayerTeam: CreateMultiplayerTeam(), - peerList: make([]*model.Player, 0), + id: worldId, + owner: owner, + playerMap: make(map[uint32]*model.Player), + sceneMap: make(map[uint32]*Scene), + enterSceneToken: uint32(random.GetRandomInt32(5000, 50000)), + enterSceneContextMap: make(map[uint32]*EnterSceneContext), + entityIdCounter: 0, + worldLevel: 0, + multiplayer: false, + mpLevelEntityId: 0, + chatMsgList: make([]*proto.ChatInfo, 0), + playerFirstEnterMap: make(map[uint32]int64), + waitEnterPlayerMap: make(map[uint32]int64), + multiplayerTeam: CreateMultiplayerTeam(), + peerList: make([]*model.Player, 0), } world.mpLevelEntityId = world.GetNextWorldEntityId(constant.ENTITY_TYPE_MP_LEVEL) w.worldMap[worldId] = world @@ -200,21 +203,29 @@ func (w *WorldManager) GetMultiplayerWorldNum() uint32 { return w.multiplayerWorldNum } +// EnterSceneContext 场景切换上下文数据结构 +type EnterSceneContext struct { + OldSceneId uint32 + OldPos *model.Vector +} + // World 世界数据结构 type World struct { - id uint32 - owner *model.Player - playerMap map[uint32]*model.Player - sceneMap map[uint32]*Scene - entityIdCounter uint32 // 世界的实体id生成计数器 - worldLevel uint8 // 世界等级 - multiplayer bool // 是否多人世界 - mpLevelEntityId uint32 - chatMsgList []*proto.ChatInfo // 世界聊天消息列表 - playerFirstEnterMap map[uint32]int64 // 玩家第一次进入世界的时间 key:uid value:进入时间 - waitEnterPlayerMap map[uint32]int64 // 进入世界的玩家等待列表 key:uid value:开始时间 - multiplayerTeam *MultiplayerTeam - peerList []*model.Player // 玩家编号列表 + id uint32 + owner *model.Player + playerMap map[uint32]*model.Player + sceneMap map[uint32]*Scene + enterSceneToken uint32 + enterSceneContextMap map[uint32]*EnterSceneContext // 场景切换上下文 key:EnterSceneToken value:EnterSceneContext + entityIdCounter uint32 // 世界的实体id生成计数器 + worldLevel uint8 // 世界等级 + multiplayer bool // 是否多人世界 + mpLevelEntityId uint32 // 多人世界等级实体id + chatMsgList []*proto.ChatInfo // 世界聊天消息列表 + playerFirstEnterMap map[uint32]int64 // 玩家第一次进入世界的时间 key:uid value:进入时间 + waitEnterPlayerMap map[uint32]int64 // 进入世界的玩家等待列表 key:uid value:开始时间 + multiplayerTeam *MultiplayerTeam // 多人队伍 + peerList []*model.Player // 玩家编号列表 } func (w *World) GetId() uint32 { @@ -233,6 +244,20 @@ func (w *World) GetAllScene() map[uint32]*Scene { return w.sceneMap } +func (w *World) GetEnterSceneToken() uint32 { + return w.enterSceneToken +} + +func (w *World) GetEnterSceneContextByToken(token uint32) *EnterSceneContext { + return w.enterSceneContextMap[token] +} + +func (w *World) AddEnterSceneContext(ctx *EnterSceneContext) uint32 { + w.enterSceneToken += 100 + w.enterSceneContextMap[w.enterSceneToken] = ctx + return w.enterSceneToken +} + func (w *World) GetWorldLevel() uint8 { return w.worldLevel } diff --git a/gs/game/world_scene.go b/gs/game/world_scene.go index f8766096..24a9ece9 100644 --- a/gs/game/world_scene.go +++ b/gs/game/world_scene.go @@ -397,7 +397,12 @@ func (s *Scene) AddGroupSuite(groupId uint32, suiteId uint8) { logger.Error("get scene group config is nil, groupId: %v", groupId) return } - suiteConfig := groupConfig.SuiteList[suiteId-1] + suiteIndex := suiteId - 1 + if int(suiteIndex) >= len(groupConfig.SuiteList) { + logger.Error("invalid suiteId: %v", suiteId) + return + } + suiteConfig := groupConfig.SuiteList[suiteIndex] suite := &Suite{ entityMap: make(map[uint32]*Entity), } @@ -431,6 +436,7 @@ func (s *Scene) AddGroupSuite(groupId uint32, suiteId uint8) { group = &Group{ suiteMap: make(map[uint8]*Suite), } + s.groupMap[groupId] = group } group.suiteMap[suiteId] = suite } diff --git a/gs/model/player.go b/gs/model/player.go index 36f16259..5740d853 100644 --- a/gs/model/player.go +++ b/gs/model/player.go @@ -56,7 +56,6 @@ type Player struct { DbWorld *DbWorld // 大世界 // 在线数据 请随意 记得加忽略字段的tag LastSaveTime uint32 `bson:"-" msgpack:"-"` // 上一次保存时间 - EnterSceneToken uint32 `bson:"-" msgpack:"-"` // 世界进入令牌 DbState int `bson:"-" msgpack:"-"` // 数据库存档状态 WorldId uint32 `bson:"-" msgpack:"-"` // 所在的世界id GameObjectGuidCounter uint64 `bson:"-" msgpack:"-"` // 游戏对象guid计数器 diff --git a/protocol/cmd/cmd_id_proto_obj_map.go b/protocol/cmd/cmd_id_proto_obj_map.go index 435021aa..eef53177 100644 --- a/protocol/cmd/cmd_id_proto_obj_map.go +++ b/protocol/cmd/cmd_id_proto_obj_map.go @@ -116,6 +116,8 @@ func (c *CmdProtoMap) registerAllMessage() { c.regMsg(DungeonDataNotify, func() any { return new(proto.DungeonDataNotify) }) // 地牢副本相关 c.regMsg(SceneAudioNotify, func() any { return new(proto.SceneAudioNotify) }) // 场景风物之琴音乐同步通知 c.regMsg(BeginCameraSceneLookNotify, func() any { return new(proto.BeginCameraSceneLookNotify) }) // 场景镜头注目通知 + c.regMsg(NpcTalkReq, func() any { return new(proto.NpcTalkReq) }) // NPC对话请求 + c.regMsg(NpcTalkRsp, func() any { return new(proto.NpcTalkRsp) }) // NPC对话响应 // 战斗与同步 c.regMsg(AvatarFightPropNotify, func() any { return new(proto.AvatarFightPropNotify) }) // 角色战斗属性通知 @@ -222,24 +224,25 @@ func (c *CmdProtoMap) registerAllMessage() { c.regMsg(DoGachaRsp, func() any { return new(proto.DoGachaRsp) }) // 抽卡响应 // 角色 - c.regMsg(AvatarDataNotify, func() any { return new(proto.AvatarDataNotify) }) // 角色信息通知 - c.regMsg(AvatarAddNotify, func() any { return new(proto.AvatarAddNotify) }) // 角色新增通知 - c.regMsg(AvatarLifeStateChangeNotify, func() any { return new(proto.AvatarLifeStateChangeNotify) }) // 角色存活状态改变通知 - c.regMsg(AvatarUpgradeReq, func() any { return new(proto.AvatarUpgradeReq) }) // 角色升级请求 - c.regMsg(AvatarUpgradeRsp, func() any { return new(proto.AvatarUpgradeRsp) }) // 角色升级通知 - c.regMsg(AvatarPropNotify, func() any { return new(proto.AvatarPropNotify) }) // 角色属性表更新通知 - c.regMsg(AvatarPromoteReq, func() any { return new(proto.AvatarPromoteReq) }) // 角色突破请求 - c.regMsg(AvatarPromoteRsp, func() any { return new(proto.AvatarPromoteRsp) }) // 角色突破响应 - c.regMsg(AvatarPromoteGetRewardReq, func() any { return new(proto.AvatarPromoteGetRewardReq) }) // 角色突破获取奖励请求 - c.regMsg(AvatarPromoteGetRewardRsp, func() any { return new(proto.AvatarPromoteGetRewardRsp) }) // 角色突破获取奖励响应 - c.regMsg(AvatarChangeCostumeReq, func() any { return new(proto.AvatarChangeCostumeReq) }) // 角色换装请求 - c.regMsg(AvatarChangeCostumeRsp, func() any { return new(proto.AvatarChangeCostumeRsp) }) // 角色换装响应 - c.regMsg(AvatarChangeCostumeNotify, func() any { return new(proto.AvatarChangeCostumeNotify) }) // 角色换装通知 - c.regMsg(AvatarGainCostumeNotify, func() any { return new(proto.AvatarGainCostumeNotify) }) // 角色获得时装通知 - c.regMsg(AvatarWearFlycloakReq, func() any { return new(proto.AvatarWearFlycloakReq) }) // 角色换风之翼请求 - c.regMsg(AvatarWearFlycloakRsp, func() any { return new(proto.AvatarWearFlycloakRsp) }) // 角色换风之翼响应 - c.regMsg(AvatarFlycloakChangeNotify, func() any { return new(proto.AvatarFlycloakChangeNotify) }) // 角色换风之翼通知 - c.regMsg(AvatarGainFlycloakNotify, func() any { return new(proto.AvatarGainFlycloakNotify) }) // 角色获得风之翼通知 + c.regMsg(AvatarDataNotify, func() any { return new(proto.AvatarDataNotify) }) // 角色信息通知 + c.regMsg(AvatarAddNotify, func() any { return new(proto.AvatarAddNotify) }) // 角色新增通知 + c.regMsg(AvatarLifeStateChangeNotify, func() any { return new(proto.AvatarLifeStateChangeNotify) }) // 角色存活状态改变通知 + c.regMsg(AvatarUpgradeReq, func() any { return new(proto.AvatarUpgradeReq) }) // 角色升级请求 + c.regMsg(AvatarUpgradeRsp, func() any { return new(proto.AvatarUpgradeRsp) }) // 角色升级通知 + c.regMsg(AvatarPropNotify, func() any { return new(proto.AvatarPropNotify) }) // 角色属性表更新通知 + c.regMsg(AvatarPromoteReq, func() any { return new(proto.AvatarPromoteReq) }) // 角色突破请求 + c.regMsg(AvatarPromoteRsp, func() any { return new(proto.AvatarPromoteRsp) }) // 角色突破响应 + c.regMsg(AvatarPromoteGetRewardReq, func() any { return new(proto.AvatarPromoteGetRewardReq) }) // 角色突破获取奖励请求 + c.regMsg(AvatarPromoteGetRewardRsp, func() any { return new(proto.AvatarPromoteGetRewardRsp) }) // 角色突破获取奖励响应 + c.regMsg(AvatarChangeCostumeReq, func() any { return new(proto.AvatarChangeCostumeReq) }) // 角色换装请求 + c.regMsg(AvatarChangeCostumeRsp, func() any { return new(proto.AvatarChangeCostumeRsp) }) // 角色换装响应 + c.regMsg(AvatarChangeCostumeNotify, func() any { return new(proto.AvatarChangeCostumeNotify) }) // 角色换装通知 + c.regMsg(AvatarGainCostumeNotify, func() any { return new(proto.AvatarGainCostumeNotify) }) // 角色获得时装通知 + c.regMsg(AvatarWearFlycloakReq, func() any { return new(proto.AvatarWearFlycloakReq) }) // 角色换风之翼请求 + c.regMsg(AvatarWearFlycloakRsp, func() any { return new(proto.AvatarWearFlycloakRsp) }) // 角色换风之翼响应 + c.regMsg(AvatarFlycloakChangeNotify, func() any { return new(proto.AvatarFlycloakChangeNotify) }) // 角色换风之翼通知 + c.regMsg(AvatarGainFlycloakNotify, func() any { return new(proto.AvatarGainFlycloakNotify) }) // 角色获得风之翼通知 + c.regMsg(AvatarSkillDepotChangeNotify, func() any { return new(proto.AvatarSkillDepotChangeNotify) }) // 角色技能库切换通知 主角切元素 // 背包与道具 c.regMsg(PlayerStoreNotify, func() any { return new(proto.PlayerStoreNotify) }) // 玩家背包数据通知