diff --git a/gdconf/gadget_data.go b/gdconf/gadget_data.go index c4c37143..4e6ec0f9 100644 --- a/gdconf/gadget_data.go +++ b/gdconf/gadget_data.go @@ -9,7 +9,6 @@ type GadgetData struct { GadgetId int32 `csv:"ID"` Type int32 `csv:"类型,omitempty"` DefaultCamp int32 `csv:"默认阵营,omitempty"` - CanInteract int32 `csv:"能否交互,omitempty"` } func (g *GameDataConfig) loadGadgetData() { diff --git a/gs/game/audio_video.go b/gs/game/audio_video.go index ddec19cf..fa54261b 100644 --- a/gs/game/audio_video.go +++ b/gs/game/audio_video.go @@ -326,7 +326,7 @@ func UpdateFrame(rgb bool) { X: leftTopPos.X - float64(w)*SCREEN_DPI, Y: leftTopPos.Y - float64(h)*SCREEN_DPI, Z: leftTopPos.Z, - }, new(model.Vector), uint32(FRAME_COLOR[w][h]), 271003, uint32(constant.GADGET_STATE_DEFAULT), 0) + }, new(model.Vector), uint32(FRAME_COLOR[w][h]), uint32(constant.GADGET_STATE_DEFAULT), nil, 0, 0) SCREEN_ENTITY_ID_LIST = append(SCREEN_ENTITY_ID_LIST, entityId) } else { if !FRAME[w][h] { @@ -334,7 +334,7 @@ func UpdateFrame(rgb bool) { X: leftTopPos.X - float64(w)*SCREEN_DPI, Y: leftTopPos.Y - float64(h)*SCREEN_DPI, Z: leftTopPos.Z, - }, new(model.Vector), uint32(GADGET_ID), 271003, uint32(constant.GADGET_STATE_DEFAULT), 0) + }, new(model.Vector), uint32(GADGET_ID), uint32(constant.GADGET_STATE_DEFAULT), nil, 0, 0) SCREEN_ENTITY_ID_LIST = append(SCREEN_ENTITY_ID_LIST, entityId) } } diff --git a/gs/game/command_gm.go b/gs/game/command_gm.go index 0f038387..dd8684d7 100644 --- a/gs/game/command_gm.go +++ b/gs/game/command_gm.go @@ -182,6 +182,7 @@ func (g *GMCmd) GMForceFinishAllQuest(userId uint32) { GAME_MANAGER.AcceptQuest(player, true) } +// GMUnlockAllPoint 解锁场景全部传送点 func (g *GMCmd) GMUnlockAllPoint(userId uint32, sceneId uint32) { player := USER_MANAGER.GetOnlineUser(userId) if player == nil { @@ -205,6 +206,20 @@ func (g *GMCmd) GMUnlockAllPoint(userId uint32, sceneId uint32) { }) } +// GMCreateGadget 在玩家附近创建物件实体 +func (g *GMCmd) GMCreateGadget(userId uint32, gadgetId uint32, posX, posY, posZ float64, itemId uint32) { + player := USER_MANAGER.GetOnlineUser(userId) + if player == nil { + logger.Error("player is nil, uid: %v", userId) + return + } + GAME_MANAGER.CreateGadget(player, gadgetId, &model.Vector{ + X: posX, + Y: posY, + Z: posZ, + }, itemId) +} + // 系统级GM指令 func (g *GMCmd) ChangePlayerCmdPerm(userId uint32, cmdPerm uint8) { diff --git a/gs/game/lua_trigger.go b/gs/game/lua_trigger.go index 4fc8f634..02356801 100644 --- a/gs/game/lua_trigger.go +++ b/gs/game/lua_trigger.go @@ -21,7 +21,6 @@ func (g *GameManager) SceneRegionTriggerCheck(player *model.Player, scene *Scene for _, regionConfigId := range suiteConfig.RegionConfigIdList { regionConfig := groupConfig.RegionMap[regionConfigId] if regionConfig == nil { - logger.Error("get region config is nil, regionConfigId: %v, uid: %v", regionConfigId, player.PlayerID) continue } shape := alg.NewShape() diff --git a/gs/game/player_fight_sync.go b/gs/game/player_fight_sync.go index e2a04a7f..8769de26 100644 --- a/gs/game/player_fight_sync.go +++ b/gs/game/player_fight_sync.go @@ -262,7 +262,7 @@ func (g *GameManager) AoiPlayerMove(player *model.Player, oldPos *model.Vector, // 旧有新没有的group即为卸载的 if !world.GetMultiplayer() { // 处理多人世界不同玩家不同位置的group卸载情况 - g.RemoveGroup(player, scene, groupConfig) + g.RemoveSceneGroup(player, scene, groupConfig) } } for groupId, groupConfig := range newNeighborGroupMap { diff --git a/gs/game/player_scene.go b/gs/game/player_scene.go index a729b514..9f6862aa 100644 --- a/gs/game/player_scene.go +++ b/gs/game/player_scene.go @@ -41,6 +41,10 @@ func (g *GameManager) EnterSceneReadyReq(player *model.Player, payloadMsg pb.Mes delEntityIdList = append(delEntityIdList, entityId) } g.RemoveSceneEntityNotifyToPlayer(player, proto.VisionType_VISION_MISS, delEntityIdList) + // 卸载旧位置附近的group + for _, groupConfig := range g.GetNeighborGroup(ctx.OldSceneId, ctx.OldPos) { + g.RemoveSceneGroup(player, oldScene, groupConfig) + } } enterScenePeerNotify := &proto.EnterScenePeerNotify{ @@ -543,10 +547,14 @@ func (g *GameManager) KillEntity(player *model.Player, scene *Scene, entityId ui if entity == nil { return } + if entity.GetEntityType() == constant.ENTITY_TYPE_MONSTER { + // 设置血量 + entity.fightProp[constant.FIGHT_PROP_CUR_HP] = 0 + g.EntityFightPropUpdateNotifyBroadcast(scene.world, entity) + // TODO + g.CreateGadget(player, 70600055, entity.pos, 104003) + } entity.lifeState = constant.LIFE_STATE_DEAD - // 设置血量 - entity.fightProp[constant.FIGHT_PROP_CUR_HP] = 0 - g.EntityFightPropUpdateNotifyBroadcast(scene.world, entity) ntf := &proto.LifeStateChangeNotify{ EntityId: entity.id, LifeState: uint32(entity.lifeState), @@ -640,7 +648,7 @@ func (g *GameManager) AddSceneGroup(player *model.Player, scene *Scene, groupCon g.SendMsg(cmd.GroupSuiteNotify, player.PlayerID, player.ClientSeq, ntf) } -func (g *GameManager) RemoveGroup(player *model.Player, scene *Scene, groupConfig *gdconf.Group) { +func (g *GameManager) RemoveSceneGroup(player *model.Player, scene *Scene, groupConfig *gdconf.Group) { group := scene.GetGroupById(uint32(groupConfig.Id)) if group == nil { logger.Error("group not exist, groupId: %v, uid: %v", groupConfig.Id, player.PlayerID) @@ -656,6 +664,24 @@ func (g *GameManager) RemoveGroup(player *model.Player, scene *Scene, groupConfi g.SendMsg(cmd.GroupUnloadNotify, player.PlayerID, player.ClientSeq, ntf) } +func (g *GameManager) CreateGadget(player *model.Player, gadgetId uint32, pos *model.Vector, itemId uint32) { + world := WORLD_MANAGER.GetWorldByID(player.WorldId) + if world == nil { + return + } + scene := world.GetSceneById(player.SceneId) + entityId := scene.CreateEntityGadgetNormal( + pos, new(model.Vector), + gadgetId, + constant.GADGET_STATE_DEFAULT, + &GadgetNormalEntity{ + itemId: itemId, + }, + 0, 0, + ) + g.AddSceneEntityNotify(player, proto.VisionType_VISION_BORN, []uint32{entityId}, true, false) +} + var SceneTransactionSeq uint32 = 0 func (g *GameManager) PacketPlayerEnterSceneNotifyLogin(player *model.Player, enterType proto.EnterType) *proto.PlayerEnterSceneNotify { @@ -1019,10 +1045,6 @@ func (g *GameManager) PacketSceneEntityInfoGadget(scene *Scene, entityId uint32) sceneEntityInfo.Entity = &proto.SceneEntityInfo_Gadget{ Gadget: g.PacketSceneGadgetInfoNormal(entity), } - case GADGET_TYPE_GATHER: - sceneEntityInfo.Entity = &proto.SceneEntityInfo_Gadget{ - Gadget: g.PacketSceneGadgetInfoGather(entity), - } case GADGET_TYPE_CLIENT: sceneEntityInfo.Entity = &proto.SceneEntityInfo_Gadget{ Gadget: g.PacketSceneGadgetInfoClient(gadgetEntity.GetGadgetClientEntity()), @@ -1109,23 +1131,9 @@ func (g *GameManager) PacketSceneNpcInfo(entity *NpcEntity) *proto.SceneNpcInfo func (g *GameManager) PacketSceneGadgetInfoNormal(entity *Entity) *proto.SceneGadgetInfo { gadgetEntity := entity.GetGadgetEntity() - sceneGadgetInfo := &proto.SceneGadgetInfo{ - GadgetId: gadgetEntity.GetGadgetId(), - GroupId: entity.GetGroupId(), - ConfigId: entity.GetConfigId(), - GadgetState: gadgetEntity.GetGadgetState(), - IsEnableInteract: true, - AuthorityPeerId: 1, - } - return sceneGadgetInfo -} - -func (g *GameManager) PacketSceneGadgetInfoGather(entity *Entity) *proto.SceneGadgetInfo { - gadgetEntity := entity.GetGadgetEntity() - gatherEntity := gadgetEntity.GetGadgetGatherEntity() - gatherDataConfig := gdconf.GetGatherDataById(int32(gatherEntity.GetGatherId())) - if gatherDataConfig == nil { - logger.Error("gather data error, gatherId: %v", gatherEntity.GetGatherId()) + gadgetDataConfig := gdconf.GetGadgetDataById(int32(gadgetEntity.GetGadgetId())) + if gadgetDataConfig == nil { + logger.Error("get gadget data config is nil, gadgetId: %v", gadgetEntity.GetGadgetId()) return new(proto.SceneGadgetInfo) } sceneGadgetInfo := &proto.SceneGadgetInfo{ @@ -1135,12 +1143,16 @@ func (g *GameManager) PacketSceneGadgetInfoGather(entity *Entity) *proto.SceneGa GadgetState: gadgetEntity.GetGadgetState(), IsEnableInteract: true, AuthorityPeerId: 1, - Content: &proto.SceneGadgetInfo_GatherGadget{ + } + switch gadgetDataConfig.Type { + case constant.GADGET_TYPE_GATHER_OBJECT: + gadgetNormalEntity := gadgetEntity.GetGadgetNormalEntity() + sceneGadgetInfo.Content = &proto.SceneGadgetInfo_GatherGadget{ GatherGadget: &proto.GatherGadgetInfo{ - ItemId: uint32(gatherDataConfig.ItemId), + ItemId: gadgetNormalEntity.GetItemId(), IsForbidGuest: false, }, - }, + } } return sceneGadgetInfo } diff --git a/gs/game/player_world.go b/gs/game/player_world.go index 326351d8..d751bfd1 100644 --- a/gs/game/player_world.go +++ b/gs/game/player_world.go @@ -307,28 +307,30 @@ func (g *GameManager) GadgetInteractReq(player *model.Player, payloadMsg pb.Mess logger.Error("get gadget data config is nil, gadgetId: %v, uid: %v", gadgetEntity.GetGadgetId(), player.PlayerID) return } - if gadgetDataConfig.CanInteract == 0 { - logger.Error("gadget can not be interact, gadgetId: %v, uid: %v", gadgetEntity.GetGadgetId(), player.PlayerID) - return - } interactType := proto.InteractType_INTERACT_NONE switch gadgetDataConfig.Type { case constant.GADGET_TYPE_GADGET: - logger.Debug("==========GADGET_TYPE_GADGET==========") // 掉落物捡起 interactType = proto.InteractType_INTERACT_PICK_ITEM + gadgetNormalEntity := gadgetEntity.GetGadgetNormalEntity() + g.AddUserItem(player.PlayerID, []*ChangeItem{{ + ItemId: gadgetNormalEntity.GetItemId(), + ChangeCount: 1, + }}, true, 0) g.KillEntity(player, scene, entity.GetId(), proto.PlayerDieType_PLAYER_DIE_NONE) case constant.GADGET_TYPE_ENERGY_BALL: - logger.Debug("==========GADGET_TYPE_ENERGY_BALL==========") - // 元素能量球吸收 + // TODO 元素能量球吸收 interactType = proto.InteractType_INTERACT_PICK_ITEM case constant.GADGET_TYPE_GATHER_OBJECT: - logger.Debug("==========GADGET_TYPE_GATHER_OBJECT==========") // 采集物摘取 interactType = proto.InteractType_INTERACT_GATHER + gadgetNormalEntity := gadgetEntity.GetGadgetNormalEntity() + g.AddUserItem(player.PlayerID, []*ChangeItem{{ + ItemId: gadgetNormalEntity.GetItemId(), + ChangeCount: 1, + }}, true, 0) g.KillEntity(player, scene, entity.GetId(), proto.PlayerDieType_PLAYER_DIE_NONE) case constant.GADGET_TYPE_CHEST: - logger.Debug("==========GADGET_TYPE_CHEST==========") // 宝箱开启 interactType = proto.InteractType_INTERACT_OPEN_CHEST if req.OpType == proto.InterOpType_INTER_OP_FINISH { @@ -338,6 +340,8 @@ func (g *GameManager) GadgetInteractReq(player *model.Player, payloadMsg pb.Mess SceneId: scene.GetId(), ConfigId: entity.GetConfigId(), }) + // TODO + g.CreateGadget(player, 70600055, entity.pos, 104003) g.ChangeGadgetState(player, scene.GetId(), constant.GADGET_STATE_CHEST_OPENED) g.KillEntity(player, scene, entity.GetId(), proto.PlayerDieType_PLAYER_DIE_NONE) } diff --git a/gs/game/world_scene.go b/gs/game/world_scene.go index 765081e4..ce8290c6 100644 --- a/gs/game/world_scene.go +++ b/gs/game/world_scene.go @@ -190,7 +190,7 @@ func (s *Scene) CreateEntityNpc(pos, rot *model.Vector, npcId, roomId, parentQue return entity.id } -func (s *Scene) CreateEntityGadgetNormal(pos, rot *model.Vector, gadgetId, gadgetState, configId, groupId uint32) uint32 { +func (s *Scene) CreateEntityGadgetNormal(pos, rot *model.Vector, gadgetId, gadgetState uint32, gadgetNormalEntity *GadgetNormalEntity, configId, groupId uint32) uint32 { entityId := s.world.GetNextWorldEntityId(constant.ENTITY_TYPE_GADGET) entity := &Entity{ id: entityId, @@ -208,41 +208,10 @@ func (s *Scene) CreateEntityGadgetNormal(pos, rot *model.Vector, gadgetId, gadge }, entityType: constant.ENTITY_TYPE_GADGET, gadgetEntity: &GadgetEntity{ - gadgetId: gadgetId, - gadgetState: gadgetState, - gadgetType: GADGET_TYPE_NORMAL, - }, - configId: configId, - groupId: groupId, - } - s.CreateEntity(entity) - return entity.id -} - -func (s *Scene) CreateEntityGadgetGather(pos, rot *model.Vector, gadgetId, gadgetState, gatherId, configId, groupId uint32) uint32 { - entityId := s.world.GetNextWorldEntityId(constant.ENTITY_TYPE_GADGET) - entity := &Entity{ - id: entityId, - scene: s, - lifeState: constant.LIFE_STATE_ALIVE, - pos: pos, - rot: rot, - moveState: uint16(proto.MotionState_MOTION_NONE), - lastMoveSceneTimeMs: 0, - lastMoveReliableSeq: 0, - fightProp: map[uint32]float32{ - constant.FIGHT_PROP_CUR_HP: math.MaxFloat32, - constant.FIGHT_PROP_MAX_HP: math.MaxFloat32, - constant.FIGHT_PROP_BASE_HP: float32(1), - }, - entityType: constant.ENTITY_TYPE_GADGET, - gadgetEntity: &GadgetEntity{ - gadgetId: gadgetId, - gadgetState: gadgetState, - gadgetType: GADGET_TYPE_GATHER, - gadgetGatherEntity: &GadgetGatherEntity{ - gatherId: gatherId, - }, + gadgetId: gadgetId, + gadgetState: gadgetState, + gadgetType: GADGET_TYPE_NORMAL, + gadgetNormalEntity: gadgetNormalEntity, }, configId: configId, groupId: groupId, @@ -407,26 +376,18 @@ func (s *Scene) createConfigEntity(groupId uint32, entityConfig any) uint32 { switch entityConfig.(type) { case *gdconf.Monster: monster := entityConfig.(*gdconf.Monster) - return s.CreateEntityMonster(&model.Vector{ - X: float64(monster.Pos.X), - Y: float64(monster.Pos.Y), - Z: float64(monster.Pos.Z), - }, &model.Vector{ - X: float64(monster.Rot.X), - Y: float64(monster.Rot.Y), - Z: float64(monster.Rot.Z), - }, uint32(monster.MonsterId), uint8(monster.Level), getTempFightPropMap(), uint32(monster.ConfigId), groupId) + return s.CreateEntityMonster( + &model.Vector{X: float64(monster.Pos.X), Y: float64(monster.Pos.Y), Z: float64(monster.Pos.Z)}, + &model.Vector{X: float64(monster.Rot.X), Y: float64(monster.Rot.Y), Z: float64(monster.Rot.Z)}, + uint32(monster.MonsterId), uint8(monster.Level), getTempFightPropMap(), uint32(monster.ConfigId), groupId, + ) case *gdconf.Npc: npc := entityConfig.(*gdconf.Npc) - return s.CreateEntityNpc(&model.Vector{ - X: float64(npc.Pos.X), - Y: float64(npc.Pos.Y), - Z: float64(npc.Pos.Z), - }, &model.Vector{ - X: float64(npc.Rot.X), - Y: float64(npc.Rot.Y), - Z: float64(npc.Rot.Z), - }, uint32(npc.NpcId), 0, 0, 0, uint32(npc.ConfigId), groupId) + return s.CreateEntityNpc( + &model.Vector{X: float64(npc.Pos.X), Y: float64(npc.Pos.Y), Z: float64(npc.Pos.Z)}, + &model.Vector{X: float64(npc.Rot.X), Y: float64(npc.Rot.Y), Z: float64(npc.Rot.Z)}, + uint32(npc.NpcId), 0, 0, 0, uint32(npc.ConfigId), groupId, + ) case *gdconf.Gadget: gadget := entityConfig.(*gdconf.Gadget) // 70500000并不是实际的物件id 根据节点类型对应采集物配置表 @@ -435,25 +396,27 @@ func (s *Scene) createConfigEntity(groupId uint32, entityConfig any) uint32 { if gatherDataConfig == nil { return 0 } - return s.CreateEntityGadgetGather(&model.Vector{ - X: float64(gadget.Pos.X), - Y: float64(gadget.Pos.Y), - Z: float64(gadget.Pos.Z), - }, &model.Vector{ - X: float64(gadget.Rot.X), - Y: float64(gadget.Rot.Y), - Z: float64(gadget.Rot.Z), - }, uint32(gatherDataConfig.GadgetId), uint32(constant.GADGET_STATE_DEFAULT), uint32(gatherDataConfig.GatherId), uint32(gadget.ConfigId), groupId) + return s.CreateEntityGadgetNormal( + &model.Vector{X: float64(gadget.Pos.X), Y: float64(gadget.Pos.Y), Z: float64(gadget.Pos.Z)}, + &model.Vector{X: float64(gadget.Rot.X), Y: float64(gadget.Rot.Y), Z: float64(gadget.Rot.Z)}, + uint32(gatherDataConfig.GadgetId), + uint32(constant.GADGET_STATE_DEFAULT), + &GadgetNormalEntity{ + itemId: uint32(gatherDataConfig.ItemId), + }, + uint32(gadget.ConfigId), + groupId, + ) } else { - return s.CreateEntityGadgetNormal(&model.Vector{ - X: float64(gadget.Pos.X), - Y: float64(gadget.Pos.Y), - Z: float64(gadget.Pos.Z), - }, &model.Vector{ - X: float64(gadget.Rot.X), - Y: float64(gadget.Rot.Y), - Z: float64(gadget.Rot.Z), - }, uint32(gadget.GadgetId), uint32(gadget.State), uint32(gadget.ConfigId), groupId) + return s.CreateEntityGadgetNormal( + &model.Vector{X: float64(gadget.Pos.X), Y: float64(gadget.Pos.Y), Z: float64(gadget.Pos.Z)}, + &model.Vector{X: float64(gadget.Rot.X), Y: float64(gadget.Rot.Y), Z: float64(gadget.Rot.Z)}, + uint32(gadget.GadgetId), + uint32(gadget.State), + nil, + uint32(gadget.ConfigId), + groupId, + ) } default: return 0 @@ -663,12 +626,18 @@ type NpcEntity struct { BlockId uint32 } +const ( + GADGET_TYPE_NORMAL = iota + GADGET_TYPE_CLIENT + GADGET_TYPE_VEHICLE // 载具 +) + type GadgetEntity struct { gadgetType int gadgetId uint32 gadgetState uint32 + gadgetNormalEntity *GadgetNormalEntity gadgetClientEntity *GadgetClientEntity - gadgetGatherEntity *GadgetGatherEntity gadgetVehicleEntity *GadgetVehicleEntity } @@ -684,28 +653,29 @@ func (g *GadgetEntity) GetGadgetState() uint32 { return g.gadgetState } -func (g *GadgetEntity) SetGadgetState(v uint32) { - g.gadgetState = v +func (g *GadgetEntity) SetGadgetState(state uint32) { + g.gadgetState = state +} + +func (g *GadgetEntity) GetGadgetNormalEntity() *GadgetNormalEntity { + return g.gadgetNormalEntity } func (g *GadgetEntity) GetGadgetClientEntity() *GadgetClientEntity { return g.gadgetClientEntity } -func (g *GadgetEntity) GetGadgetGatherEntity() *GadgetGatherEntity { - return g.gadgetGatherEntity -} - func (g *GadgetEntity) GetGadgetVehicleEntity() *GadgetVehicleEntity { return g.gadgetVehicleEntity } -const ( - GADGET_TYPE_NORMAL = iota - GADGET_TYPE_GATHER - GADGET_TYPE_CLIENT - GADGET_TYPE_VEHICLE // 载具 -) +type GadgetNormalEntity struct { + itemId uint32 +} + +func (g *GadgetNormalEntity) GetItemId() uint32 { + return g.itemId +} type GadgetClientEntity struct { configId uint32 @@ -740,14 +710,6 @@ func (g *GadgetClientEntity) GetPropOwnerEntityId() uint32 { return g.propOwnerEntityId } -type GadgetGatherEntity struct { - gatherId uint32 -} - -func (g *GadgetGatherEntity) GetGatherId() uint32 { - return g.gatherId -} - type GadgetVehicleEntity struct { vehicleId uint32 owner *model.Player