diff --git a/common/constant/reliquary_type.go b/common/constant/reliquary_type.go new file mode 100644 index 00000000..d0e3cab3 --- /dev/null +++ b/common/constant/reliquary_type.go @@ -0,0 +1,10 @@ +package constant + +const ( + RELIQUARY_TYPE_NONE int32 = 0 + RELIQUARY_TYPE_FLOWER int32 = 1 // 生之花 + RELIQUARY_TYPE_FEATHER int32 = 2 // 死之羽 + RELIQUARY_TYPE_SAND int32 = 3 // 时之沙 + RELIQUARY_TYPE_CUP int32 = 4 // 空之杯 + RELIQUARY_TYPE_CROWN int32 = 5 // 理之冠 +) diff --git a/gs/game/command_controller.go b/gs/game/command_controller.go index 8b79eabc..f658f4ed 100644 --- a/gs/game/command_controller.go +++ b/gs/game/command_controller.go @@ -143,7 +143,7 @@ func (c *CommandManager) GiveCommand(cmd *CommandMessage) { // 判断是否填写必备参数 if cmd.Args["i"] == "" { - c.SendMessage(player, "参数不足,正确用法:/%v [-u ] [-c <数量>] -i <物品ID|武器ID|角色ID/item/weapon/avatar/all>。", cmd.Name) + c.SendMessage(player, "参数不足,正确用法:/%v [-u ] [-c <数量>] -i <物品ID|武器ID|圣遗物ID|角色ID/item/weapon/reliquary/avatar/all>。", cmd.Name) return } @@ -179,13 +179,13 @@ func (c *CommandManager) GiveCommand(cmd *CommandMessage) { } case "i": switch v { - case "all", "item", "avatar", "weapon": + case "all", "item", "avatar", "weapon", "reliquary": // 将模式修改为参数的值 mode = v default: var id uint64 if id, err = strconv.ParseUint(v, 10, 32); err != nil { - c.SendMessage(player, "参数 -%v 有误,允许内容: 。", k) + c.SendMessage(player, "参数 -%v 有误,允许内容: 。", k) return } itemId = uint32(id) @@ -209,7 +209,7 @@ func (c *CommandManager) GiveCommand(cmd *CommandMessage) { if ok { // 给予玩家物品 c.GMAddUserItem(target.PlayerID, itemId, count) - c.SendMessage(player, "已给予玩家 UID:%v, 物品ID: %v*数量: %v。", target.PlayerID, itemId, count) + c.SendMessage(player, "已给予玩家 UID:%v, 物品ID: %v 数量: %v。", target.PlayerID, itemId, count) return } // 判断是否为武器 @@ -217,16 +217,25 @@ func (c *CommandManager) GiveCommand(cmd *CommandMessage) { if ok { // 给予玩家武器 c.GMAddUserWeapon(target.PlayerID, itemId, count) - c.SendMessage(player, "已给予玩家 UID:%v, 武器ID:%v*数量:%v。", target.PlayerID, itemId, count) + c.SendMessage(player, "已给予玩家 UID:%v, 武器ID:%v 数量:%v。", target.PlayerID, itemId, count) + return + + } + // 判断是否为圣遗物 + _, ok = GAME_MANAGER.GetAllReliquaryDataConfig()[int32(itemId)] + if ok { + // 给予玩家圣遗物 + c.GMAddUserReliquary(target.PlayerID, itemId, count) + c.SendMessage(player, "已给予玩家 UID:%v, 圣遗物ID:%v 数量:%v。", target.PlayerID, itemId, count) return } // 判断是否为角色 _, ok = GAME_MANAGER.GetAllAvatarDataConfig()[int32(itemId)] if ok { - // 给予玩家武器 + // 给予玩家角色 c.GMAddUserAvatar(target.PlayerID, itemId) - c.SendMessage(player, "已给予玩家 UID:%v, 角色ID:%v*数量:%v。", target.PlayerID, itemId, count) + c.SendMessage(player, "已给予玩家 UID:%v, 角色ID:%v 数量:%v。", target.PlayerID, itemId, count) return } // 都执行到这里那肯定是都不匹配 @@ -234,11 +243,15 @@ func (c *CommandManager) GiveCommand(cmd *CommandMessage) { case "item": // 给予玩家所有物品 c.GMAddUserAllItem(target.PlayerID, count) - c.SendMessage(player, "已给予玩家 UID:%v, 所有物品*%v。", target.PlayerID, count) + c.SendMessage(player, "已给予玩家 UID:%v, 所有物品 数量:%v。", target.PlayerID, count) case "weapon": // 给予玩家所有武器 c.GMAddUserAllWeapon(target.PlayerID, count) - c.SendMessage(player, "已给予玩家 UID:%v, 所有武器*%v。", target.PlayerID, count) + c.SendMessage(player, "已给予玩家 UID:%v, 所有武器 数量:%v。", target.PlayerID, count) + case "reliquary": + // 给予玩家所有圣遗物 + c.GMAddUserAllReliquary(target.PlayerID, count) + c.SendMessage(player, "已给予玩家 UID:%v, 所有圣遗物 数量:%v。", target.PlayerID, count) case "avatar": // 给予玩家所有角色 c.GMAddUserAllAvatar(target.PlayerID) diff --git a/gs/game/command_gm.go b/gs/game/command_gm.go index 62d9df7c..825ea3c9 100644 --- a/gs/game/command_gm.go +++ b/gs/game/command_gm.go @@ -39,6 +39,15 @@ func (c *CommandManager) GMAddUserWeapon(userId, itemId, itemCount uint32) { } } +// GMAddUserReliquary 给予玩家圣遗物 +func (c *CommandManager) GMAddUserReliquary(userId, itemId, itemCount uint32) { + // 圣遗物数量 + for i := uint32(0); i < itemCount; i++ { + // 给予武器 + GAME_MANAGER.AddUserReliquary(userId, itemId) + } +} + // GMAddUserAvatar 给予玩家角色 func (c *CommandManager) GMAddUserAvatar(userId, avatarId uint32) { player := USER_MANAGER.GetOnlineUser(userId) @@ -75,6 +84,13 @@ func (c *CommandManager) GMAddUserAllWeapon(userId, itemCount uint32) { } } +// GMAddUserAllReliquary 给予玩家所有圣遗物 +func (c *CommandManager) GMAddUserAllReliquary(userId, itemCount uint32) { + for itemId := range GAME_MANAGER.GetAllReliquaryDataConfig() { + c.GMAddUserReliquary(userId, uint32(itemId), itemCount) + } +} + // GMAddUserAllAvatar 给予玩家所有角色 func (c *CommandManager) GMAddUserAllAvatar(userId uint32) { for avatarId := range GAME_MANAGER.GetAllAvatarDataConfig() { diff --git a/gs/game/player_equip.go b/gs/game/player_equip.go index 67ad69d4..e2a0564c 100644 --- a/gs/game/player_equip.go +++ b/gs/game/player_equip.go @@ -32,7 +32,8 @@ func (g *GameManager) SetEquipLockStateReq(player *model.Player, payloadMsg pb.M case *model.Reliquary: reliquary := equipGameObj.(*model.Reliquary) reliquary.Lock = req.IsLocked - // TODO 更新圣遗物的物品数据 + // 更新圣遗物的物品数据 + g.SendMsg(cmd.StoreItemChangeNotify, player.PlayerID, player.ClientSeq, g.PacketStoreItemChangeNotifyByReliquary(reliquary)) default: logger.Error("equip type error, equipGuid: %v", req.TargetEquipGuid) g.SendError(cmd.SetEquipLockStateRsp, player, &proto.SetEquipLockStateRsp{}) @@ -46,11 +47,44 @@ func (g *GameManager) SetEquipLockStateReq(player *model.Player, payloadMsg pb.M g.SendMsg(cmd.SetEquipLockStateRsp, player.PlayerID, player.ClientSeq, setEquipLockStateRsp) } +// TakeoffEquipReq 装备卸下请求 +func (g *GameManager) TakeoffEquipReq(player *model.Player, payloadMsg pb.Message) { + logger.Debug("user take off equip, uid: %v", player.PlayerID) + req := payloadMsg.(*proto.TakeoffEquipReq) + + // 获取目标角色 + avatar, ok := player.AvatarMap[player.GetAvatarIdByGuid(req.AvatarGuid)] + if !ok { + logger.Error("avatar error, avatarGuid: %v", req.AvatarGuid) + g.SendError(cmd.TakeoffEquipRsp, player, &proto.TakeoffEquipRsp{}, proto.Retcode_RET_CAN_NOT_FIND_AVATAR) + return + } + // 确保角色已装备指定位置的圣遗物 + reliquary, ok := avatar.EquipReliquaryMap[uint8(req.Slot)] + if !ok { + logger.Error("avatar not wear reliquary, slot: %v", req.Slot) + g.SendError(cmd.TakeoffEquipRsp, player, &proto.TakeoffEquipRsp{}) + return + } + // 卸下圣遗物 + player.TakeOffReliquary(avatar.AvatarId, reliquary.ReliquaryId) + // 更新玩家装备 + avatarEquipChangeNotify := g.PacketAvatarEquipChangeNotifyByReliquary(avatar, reliquary) + g.SendMsg(cmd.AvatarEquipChangeNotify, player.PlayerID, player.ClientSeq, avatarEquipChangeNotify) + + takeoffEquipRsp := &proto.TakeoffEquipRsp{ + AvatarGuid: req.AvatarGuid, + Slot: req.Slot, + } + g.SendMsg(cmd.TakeoffEquipRsp, player.PlayerID, player.ClientSeq, takeoffEquipRsp) +} + // WearEquipReq 穿戴装备请求 func (g *GameManager) WearEquipReq(player *model.Player, payloadMsg pb.Message) { logger.Debug("user wear equip, uid: %v", player.PlayerID) req := payloadMsg.(*proto.WearEquipReq) + // 获取目标角色 avatar, ok := player.AvatarMap[player.GetAvatarIdByGuid(req.AvatarGuid)] if !ok { logger.Error("avatar error, avatarGuid: %v", req.AvatarGuid) @@ -69,7 +103,8 @@ func (g *GameManager) WearEquipReq(player *model.Player, payloadMsg pb.Message) weapon := equipGameObj.(*model.Weapon) g.WearUserAvatarWeapon(player.PlayerID, avatar.AvatarId, weapon.WeaponId) case *model.Reliquary: - // 暂时不写 + reliquary := equipGameObj.(*model.Reliquary) + g.WearUserAvatarReliquary(player.PlayerID, avatar.AvatarId, reliquary.ReliquaryId) default: logger.Error("equip type error, equipGuid: %v", req.EquipGuid) g.SendError(cmd.WearEquipRsp, player, &proto.WearEquipRsp{}) @@ -83,6 +118,51 @@ func (g *GameManager) WearEquipReq(player *model.Player, payloadMsg pb.Message) g.SendMsg(cmd.WearEquipRsp, player.PlayerID, player.ClientSeq, wearEquipRsp) } +// WearUserAvatarReliquary 玩家角色装备圣遗物 +func (g *GameManager) WearUserAvatarReliquary(userId uint32, avatarId uint32, reliquaryId uint64) { + player := USER_MANAGER.GetOnlineUser(userId) + if player == nil { + logger.Error("player is nil, uid: %v", userId) + return + } + avatar := player.AvatarMap[avatarId] + reliquary := player.ReliquaryMap[reliquaryId] + + // 获取圣遗物配置表 + reliquaryConfig := gdconf.GetItemDataById(int32(reliquary.ItemId)) + if reliquaryConfig == nil { + logger.Error("reliquary config error, itemId: %v", reliquary.ItemId) + return + } + // 角色已装备的圣遗物 + avatarCurReliquary := avatar.EquipReliquaryMap[uint8(reliquaryConfig.ReliquaryType)] + + if reliquary.AvatarId != 0 { + // 圣遗物在别的角色身上 + weakAvatarId := reliquary.AvatarId + weakReliquaryId := reliquaryId + strongAvatarId := avatarId + strongReliquaryId := avatarCurReliquary.ReliquaryId + player.TakeOffReliquary(weakAvatarId, weakReliquaryId) + player.TakeOffReliquary(strongAvatarId, strongReliquaryId) + player.WearReliquary(weakAvatarId, strongReliquaryId) + player.WearReliquary(strongAvatarId, weakReliquaryId) + + weakAvatar := player.AvatarMap[weakAvatarId] + weakReliquary := weakAvatar.EquipReliquaryMap[uint8(reliquaryConfig.ReliquaryType)] + + avatarEquipChangeNotify := g.PacketAvatarEquipChangeNotifyByReliquary(weakAvatar, weakReliquary) + g.SendMsg(cmd.AvatarEquipChangeNotify, userId, player.ClientSeq, avatarEquipChangeNotify) + } else if avatarCurReliquary != nil { + // 角色当前有圣遗物 + player.TakeOffReliquary(avatarId, avatarCurReliquary.ReliquaryId) + player.WearReliquary(avatarId, reliquaryId) + } + + avatarEquipChangeNotify := g.PacketAvatarEquipChangeNotifyByReliquary(avatar, reliquary) + g.SendMsg(cmd.AvatarEquipChangeNotify, userId, player.ClientSeq, avatarEquipChangeNotify) +} + // WearUserAvatarWeapon 玩家角色装备武器 func (g *GameManager) WearUserAvatarWeapon(userId uint32, avatarId uint32, weaponId uint64) { player := USER_MANAGER.GetOnlineUser(userId) @@ -108,15 +188,15 @@ func (g *GameManager) WearUserAvatarWeapon(userId uint32, avatarId uint32, weapo player.WearWeapon(strongAvatarId, weakWeaponId) weakAvatar := player.AvatarMap[weakAvatarId] - weakWeapon := player.WeaponMap[weakAvatar.EquipWeapon.WeaponId] + weakWeapon := weakAvatar.EquipWeapon weakWorldAvatar := world.GetPlayerWorldAvatar(player, weakAvatarId) if weakWorldAvatar != nil { weakWorldAvatar.SetWeaponEntityId(scene.CreateEntityWeapon()) - avatarEquipChangeNotify := g.PacketAvatarEquipChangeNotify(weakAvatar, weakWeapon, weakWorldAvatar.GetWeaponEntityId()) + avatarEquipChangeNotify := g.PacketAvatarEquipChangeNotifyByWeapon(weakAvatar, weakWeapon, weakWorldAvatar.GetWeaponEntityId()) g.SendMsg(cmd.AvatarEquipChangeNotify, userId, player.ClientSeq, avatarEquipChangeNotify) } else { - avatarEquipChangeNotify := g.PacketAvatarEquipChangeNotify(weakAvatar, weakWeapon, 0) + avatarEquipChangeNotify := g.PacketAvatarEquipChangeNotifyByWeapon(weakAvatar, weakWeapon, 0) g.SendMsg(cmd.AvatarEquipChangeNotify, userId, player.ClientSeq, avatarEquipChangeNotify) } } else if avatar.EquipWeapon != nil { @@ -131,38 +211,60 @@ func (g *GameManager) WearUserAvatarWeapon(userId uint32, avatarId uint32, weapo worldAvatar := world.GetPlayerWorldAvatar(player, avatarId) if worldAvatar != nil { worldAvatar.SetWeaponEntityId(scene.CreateEntityWeapon()) - avatarEquipChangeNotify := g.PacketAvatarEquipChangeNotify(avatar, weapon, worldAvatar.GetWeaponEntityId()) + avatarEquipChangeNotify := g.PacketAvatarEquipChangeNotifyByWeapon(avatar, weapon, worldAvatar.GetWeaponEntityId()) g.SendMsg(cmd.AvatarEquipChangeNotify, userId, player.ClientSeq, avatarEquipChangeNotify) } else { - avatarEquipChangeNotify := g.PacketAvatarEquipChangeNotify(avatar, weapon, 0) + avatarEquipChangeNotify := g.PacketAvatarEquipChangeNotifyByWeapon(avatar, weapon, 0) g.SendMsg(cmd.AvatarEquipChangeNotify, userId, player.ClientSeq, avatarEquipChangeNotify) } } -func (g *GameManager) PacketAvatarEquipChangeNotify(avatar *model.Avatar, weapon *model.Weapon, entityId uint32) *proto.AvatarEquipChangeNotify { - itemDataConfig := gdconf.GetItemDataById(int32(weapon.ItemId)) - if itemDataConfig == nil { - logger.Error("item data config error, itemId: %v", weapon.ItemId) +func (g *GameManager) PacketAvatarEquipChangeNotifyByReliquary(avatar *model.Avatar, reliquary *model.Reliquary) *proto.AvatarEquipChangeNotify { + reliquaryConfig := gdconf.GetItemDataById(int32(reliquary.ItemId)) + if reliquaryConfig == nil { + logger.Error("reliquary config error, itemId: %v", reliquary.ItemId) return new(proto.AvatarEquipChangeNotify) } + avatarEquipChangeNotify := &proto.AvatarEquipChangeNotify{ + AvatarGuid: avatar.Guid, + ItemId: reliquary.ItemId, + EquipGuid: reliquary.Guid, + EquipType: uint32(reliquaryConfig.ReliquaryType), + Reliquary: &proto.SceneReliquaryInfo{ + ItemId: reliquary.ItemId, + Guid: reliquary.Guid, + Level: uint32(reliquary.Level), + PromoteLevel: uint32(reliquary.Promote), + }, + } + return avatarEquipChangeNotify +} + +func (g *GameManager) PacketAvatarEquipChangeNotifyByWeapon(avatar *model.Avatar, weapon *model.Weapon, entityId uint32) *proto.AvatarEquipChangeNotify { + weaponConfig := gdconf.GetItemDataById(int32(weapon.ItemId)) + if weaponConfig == nil { + logger.Error("weapon config error, itemId: %v", weapon.ItemId) + return new(proto.AvatarEquipChangeNotify) + } + affixMap := make(map[uint32]uint32) + for _, affixId := range weapon.AffixIdList { + affixMap[affixId] = uint32(weapon.Refinement) + } avatarEquipChangeNotify := &proto.AvatarEquipChangeNotify{ AvatarGuid: avatar.Guid, ItemId: weapon.ItemId, EquipGuid: weapon.Guid, - } - switch itemDataConfig.Type { - case int32(constant.ITEM_TYPE_WEAPON): - avatarEquipChangeNotify.EquipType = uint32(constant.EQUIP_TYPE_WEAPON) - case int32(constant.ITEM_TYPE_RELIQUARY): - avatarEquipChangeNotify.EquipType = uint32(itemDataConfig.ReliquaryType) - } - avatarEquipChangeNotify.Weapon = &proto.SceneWeaponInfo{ - EntityId: entityId, - GadgetId: uint32(itemDataConfig.GadgetId), - ItemId: weapon.ItemId, - Guid: weapon.Guid, - Level: uint32(weapon.Level), - AbilityInfo: new(proto.AbilitySyncStateInfo), + EquipType: uint32(constant.EQUIP_TYPE_WEAPON), + Weapon: &proto.SceneWeaponInfo{ + EntityId: entityId, + GadgetId: uint32(weaponConfig.GadgetId), + ItemId: weapon.ItemId, + Guid: weapon.Guid, + Level: uint32(weapon.Level), + PromoteLevel: uint32(weapon.Promote), + AbilityInfo: new(proto.AbilitySyncStateInfo), + AffixMap: affixMap, + }, } return avatarEquipChangeNotify } diff --git a/gs/game/player_login.go b/gs/game/player_login.go index d3534d56..b0cb81e0 100644 --- a/gs/game/player_login.go +++ b/gs/game/player_login.go @@ -254,7 +254,7 @@ func (g *GameManager) PacketPlayerStoreNotify(player *model.Player) *proto.Playe Exp: reliquary.Exp, PromoteLevel: uint32(reliquary.Promote), MainPropId: reliquary.MainPropId, - AppendPropIdList: reliquary.AffixIdList, + AppendPropIdList: reliquary.AppendPropIdList, }, }, IsLocked: reliquary.Lock, @@ -413,8 +413,6 @@ func (g *GameManager) CreatePlayer(userId uint32, nickName string, mainCharAvata // 角色装上初始武器 player.WearWeapon(mainCharAvatarId, weaponId) - player.AddReliquary(24825, uint64(g.snowflake.GenId()), 15007) - player.TeamConfig = model.NewTeamInfo() player.TeamConfig.GetActiveTeam().SetAvatarIdList([]uint32{mainCharAvatarId}) diff --git a/gs/game/player_reliquary.go b/gs/game/player_reliquary.go new file mode 100644 index 00000000..1c071e69 --- /dev/null +++ b/gs/game/player_reliquary.go @@ -0,0 +1,98 @@ +package game + +import ( + "hk4e/common/constant" + "hk4e/gdconf" + "hk4e/gs/model" + "hk4e/pkg/logger" + "hk4e/protocol/cmd" + "hk4e/protocol/proto" +) + +func (g *GameManager) GetAllReliquaryDataConfig() map[int32]*gdconf.ItemData { + allReliquaryDataConfig := make(map[int32]*gdconf.ItemData) + for itemId, itemData := range gdconf.GetItemDataMap() { + if uint16(itemData.Type) != constant.ITEM_TYPE_RELIQUARY { + continue + } + if (itemId >= 20002 && itemId <= 20004) || + itemId == 23334 || + (itemId >= 23300 && itemId <= 23340) { + // 跳过无效圣遗物 + continue + } + allReliquaryDataConfig[itemId] = itemData + } + return allReliquaryDataConfig +} + +func (g *GameManager) AddUserReliquary(userId uint32, itemId uint32) uint64 { + player := USER_MANAGER.GetOnlineUser(userId) + if player == nil { + logger.Error("player is nil, uid: %v", userId) + return 0 + } + reliquaryConfig := gdconf.GetItemDataById(int32(itemId)) + if reliquaryConfig == nil { + logger.Error("reliquary config error, itemId: %v", itemId) + return 0 + } + reliquaryId := uint64(g.snowflake.GenId()) + // player.AddReliquary(24825, uint64(g.snowflake.GenId()), 15007) + player.AddReliquary(itemId, reliquaryId, 15007) // TODO 随机主属性库 + reliquary := player.GetReliquary(reliquaryId) + if reliquary == nil { + logger.Error("reliquary is nil, itemId: %v, reliquaryId: %v", itemId, reliquaryId) + return 0 + } + g.SendMsg(cmd.StoreItemChangeNotify, userId, player.ClientSeq, g.PacketStoreItemChangeNotifyByReliquary(reliquary)) + return reliquaryId +} + +func (g *GameManager) CostUserReliquary(userId uint32, reliquaryIdList []uint64) { + player := USER_MANAGER.GetOnlineUser(userId) + if player == nil { + logger.Error("player is nil, uid: %v", userId) + return + } + storeItemDelNotify := &proto.StoreItemDelNotify{ + GuidList: make([]uint64, 0, len(reliquaryIdList)), + StoreType: proto.StoreType_STORE_PACK, + } + for _, reliquaryId := range reliquaryIdList { + reliquaryGuid := player.CostReliquary(reliquaryId) + if reliquaryGuid == 0 { + logger.Error("reliquary cost error, reliquaryId: %v", reliquaryId) + return + } + storeItemDelNotify.GuidList = append(storeItemDelNotify.GuidList, reliquaryId) + } + g.SendMsg(cmd.StoreItemDelNotify, userId, player.ClientSeq, storeItemDelNotify) +} + +func (g *GameManager) PacketStoreItemChangeNotifyByReliquary(reliquary *model.Reliquary) *proto.StoreItemChangeNotify { + storeItemChangeNotify := &proto.StoreItemChangeNotify{ + StoreType: proto.StoreType_STORE_PACK, + ItemList: make([]*proto.Item, 0), + } + pbItem := &proto.Item{ + ItemId: reliquary.ItemId, + Guid: reliquary.Guid, + Detail: &proto.Item_Equip{ + Equip: &proto.Equip{ + Detail: &proto.Equip_Reliquary{ + Reliquary: &proto.Reliquary{ + Level: uint32(reliquary.Level), + Exp: reliquary.Exp, + PromoteLevel: uint32(reliquary.Promote), + MainPropId: reliquary.MainPropId, + AppendPropIdList: reliquary.AppendPropIdList, + }, + }, + IsLocked: reliquary.Lock, + }, + }, + } + storeItemChangeNotify.ItemList = append(storeItemChangeNotify.ItemList, pbItem) + return storeItemChangeNotify +} diff --git a/gs/game/player_scene.go b/gs/game/player_scene.go index adfa85c4..c002fdb1 100644 --- a/gs/game/player_scene.go +++ b/gs/game/player_scene.go @@ -873,33 +873,46 @@ func (g *GameManager) PacketSceneEntityInfoGadget(scene *Scene, entityId uint32) } func (g *GameManager) PacketSceneAvatarInfo(scene *Scene, player *model.Player, avatarId uint32) *proto.SceneAvatarInfo { - equipIdList := make([]uint32, 0) - weapon := player.AvatarMap[avatarId].EquipWeapon - equipIdList = append(equipIdList, weapon.ItemId) - for _, reliquary := range player.AvatarMap[avatarId].EquipReliquaryList { + avatar, ok := player.AvatarMap[avatarId] + if !ok { + logger.Error("avatar error, avatarId: %v", avatarId) + return new(proto.SceneAvatarInfo) + } + equipIdList := make([]uint32, len(avatar.EquipReliquaryMap)+1) + for _, reliquary := range avatar.EquipReliquaryMap { equipIdList = append(equipIdList, reliquary.ItemId) } + equipIdList = append(equipIdList, avatar.EquipWeapon.ItemId) + reliquaryList := make([]*proto.SceneReliquaryInfo, 0, len(avatar.EquipReliquaryMap)) + for _, reliquary := range avatar.EquipReliquaryMap { + reliquaryList = append(reliquaryList, &proto.SceneReliquaryInfo{ + ItemId: reliquary.ItemId, + Guid: reliquary.Guid, + Level: uint32(reliquary.Level), + PromoteLevel: uint32(reliquary.Promote), + }) + } world := WORLD_MANAGER.GetWorldByID(player.WorldId) sceneAvatarInfo := &proto.SceneAvatarInfo{ Uid: player.PlayerID, AvatarId: avatarId, - Guid: player.AvatarMap[avatarId].Guid, + Guid: avatar.Guid, PeerId: world.GetPlayerPeerId(player), EquipIdList: equipIdList, - SkillDepotId: player.AvatarMap[avatarId].SkillDepotId, + SkillDepotId: avatar.SkillDepotId, Weapon: &proto.SceneWeaponInfo{ EntityId: scene.GetWorld().GetPlayerWorldAvatarWeaponEntityId(player, avatarId), - GadgetId: uint32(gdconf.GetItemDataById(int32(weapon.ItemId)).GadgetId), - ItemId: weapon.ItemId, - Guid: weapon.Guid, - Level: uint32(weapon.Level), + GadgetId: uint32(gdconf.GetItemDataById(int32(avatar.EquipWeapon.ItemId)).GadgetId), + ItemId: avatar.EquipWeapon.ItemId, + Guid: avatar.EquipWeapon.Guid, + Level: uint32(avatar.EquipWeapon.Level), AbilityInfo: new(proto.AbilitySyncStateInfo), }, - ReliquaryList: nil, - SkillLevelMap: player.AvatarMap[avatarId].SkillLevelMap, - WearingFlycloakId: player.AvatarMap[avatarId].FlyCloak, - CostumeId: player.AvatarMap[avatarId].Costume, - BornTime: uint32(player.AvatarMap[avatarId].BornTime), + ReliquaryList: reliquaryList, + SkillLevelMap: avatar.SkillLevelMap, + WearingFlycloakId: avatar.FlyCloak, + CostumeId: avatar.Costume, + BornTime: uint32(avatar.BornTime), TeamResonanceList: make([]uint32, 0), } // for id := range player.TeamConfig.TeamResonances { diff --git a/gs/game/player_team.go b/gs/game/player_team.go index ba6833c4..54bbfaee 100644 --- a/gs/game/player_team.go +++ b/gs/game/player_team.go @@ -215,7 +215,7 @@ func (g *GameManager) PacketSceneTeamUpdateNotify(world *World) *proto.SceneTeam equipIdList := make([]uint32, 0) weapon := worldPlayerAvatar.EquipWeapon equipIdList = append(equipIdList, weapon.ItemId) - for _, reliquary := range worldPlayerAvatar.EquipReliquaryList { + for _, reliquary := range worldPlayerAvatar.EquipReliquaryMap { equipIdList = append(equipIdList, reliquary.ItemId) } sceneTeamAvatar := &proto.SceneTeamAvatar{ diff --git a/gs/game/route_manager.go b/gs/game/route_manager.go index a43e21ed..658b203d 100644 --- a/gs/game/route_manager.go +++ b/gs/game/route_manager.go @@ -137,6 +137,7 @@ func (r *RouteManager) initRoute() { r.registerRouter(cmd.WeaponAwakenReq, GAME_MANAGER.WeaponAwakenReq) r.registerRouter(cmd.AvatarPromoteGetRewardReq, GAME_MANAGER.AvatarPromoteGetRewardReq) r.registerRouter(cmd.SetEquipLockStateReq, GAME_MANAGER.SetEquipLockStateReq) + r.registerRouter(cmd.TakeoffEquipReq, GAME_MANAGER.TakeoffEquipReq) } func (r *RouteManager) RouteHandle(netMsg *mq.NetMsg) { diff --git a/gs/model/avatar.go b/gs/model/avatar.go index 882e5bed..9b794d30 100644 --- a/gs/model/avatar.go +++ b/gs/model/avatar.go @@ -9,30 +9,30 @@ import ( ) type Avatar struct { - AvatarId uint32 // 角色id - LifeState uint16 // 存活状态 - Level uint8 // 等级 - Exp uint32 // 经验值 - Promote uint8 // 突破等阶 - Satiation uint32 // 饱食度 - SatiationPenalty uint32 // 饱食度溢出 - CurrHP float64 // 当前生命值 - CurrEnergy float64 // 当前元素能量值 - FetterList []uint32 // 资料解锁条目 - SkillLevelMap map[uint32]uint32 // 技能等级数据 - SkillDepotId uint32 // 技能库id - FlyCloak uint32 // 当前风之翼 - Costume uint32 // 当前衣装 - BornTime int64 // 获得时间 - FetterLevel uint8 // 好感度等级 - FetterExp uint32 // 好感度经验 - PromoteRewardMap map[uint32]bool // 突破奖励 map[突破等级]是否已被领取 - Guid uint64 `bson:"-" msgpack:"-"` - EquipGuidMap map[uint64]uint64 `bson:"-" msgpack:"-"` - EquipWeapon *Weapon `bson:"-" msgpack:"-"` - EquipReliquaryList []*Reliquary `bson:"-" msgpack:"-"` - FightPropMap map[uint32]float32 `bson:"-" msgpack:"-"` - ExtraAbilityEmbryos map[string]bool `bson:"-" msgpack:"-"` + AvatarId uint32 // 角色id + LifeState uint16 // 存活状态 + Level uint8 // 等级 + Exp uint32 // 经验值 + Promote uint8 // 突破等阶 + Satiation uint32 // 饱食度 + SatiationPenalty uint32 // 饱食度溢出 + CurrHP float64 // 当前生命值 + CurrEnergy float64 // 当前元素能量值 + FetterList []uint32 // 资料解锁条目 + SkillLevelMap map[uint32]uint32 // 技能等级数据 + SkillDepotId uint32 // 技能库id + FlyCloak uint32 // 当前风之翼 + Costume uint32 // 当前衣装 + BornTime int64 // 获得时间 + FetterLevel uint8 // 好感度等级 + FetterExp uint32 // 好感度经验 + PromoteRewardMap map[uint32]bool // 突破奖励 map[突破等级]是否已被领取 + Guid uint64 `bson:"-" msgpack:"-"` + EquipGuidMap map[uint64]uint64 `bson:"-" msgpack:"-"` + EquipWeapon *Weapon `bson:"-" msgpack:"-"` + EquipReliquaryMap map[uint8]*Reliquary `bson:"-" msgpack:"-"` + FightPropMap map[uint32]float32 `bson:"-" msgpack:"-"` + ExtraAbilityEmbryos map[string]bool `bson:"-" msgpack:"-"` } func (p *Player) InitAllAvatar() { @@ -129,7 +129,7 @@ func (p *Player) AddAvatar(avatarId uint32) { Guid: 0, EquipGuidMap: nil, EquipWeapon: nil, - EquipReliquaryList: nil, + EquipReliquaryMap: nil, FightPropMap: nil, ExtraAbilityEmbryos: make(map[string]bool), PromoteRewardMap: make(map[uint32]bool, len(avatarDataConfig.PromoteRewardMap)), @@ -183,6 +183,32 @@ func (p *Player) SetCurrEnergy(avatar *Avatar, value float64, max bool) { } } +func (p *Player) WearReliquary(avatarId uint32, reliquaryId uint64) { + avatar := p.AvatarMap[avatarId] + reliquary := p.ReliquaryMap[reliquaryId] + reliquaryConfig := gdconf.GetItemDataById(int32(reliquary.ItemId)) + if reliquaryConfig == nil { + logger.Error("reliquary config error, itemId: %v", reliquary.ItemId) + return + } + avatar.EquipReliquaryMap[uint8(reliquaryConfig.ReliquaryType)] = reliquary + reliquary.AvatarId = avatarId + avatar.EquipGuidMap[reliquary.Guid] = reliquary.Guid +} + +func (p *Player) TakeOffReliquary(avatarId uint32, reliquaryId uint64) { + avatar := p.AvatarMap[avatarId] + reliquary := p.ReliquaryMap[reliquaryId] + reliquaryConfig := gdconf.GetItemDataById(int32(reliquary.ItemId)) + if reliquaryConfig == nil { + logger.Error("reliquary config error, itemId: %v", reliquary.ItemId) + return + } + delete(avatar.EquipReliquaryMap, uint8(reliquaryConfig.ReliquaryType)) + reliquary.AvatarId = 0 + delete(avatar.EquipGuidMap, reliquary.Guid) +} + func (p *Player) WearWeapon(avatarId uint32, weaponId uint64) { avatar := p.AvatarMap[avatarId] weapon := p.WeaponMap[weaponId] diff --git a/gs/model/reliquary.go b/gs/model/reliquary.go index 3d587218..373e34e3 100644 --- a/gs/model/reliquary.go +++ b/gs/model/reliquary.go @@ -6,26 +6,32 @@ import ( ) type Reliquary struct { - ReliquaryId uint64 // 圣遗物的唯一id - ItemId uint32 // 圣遗物的道具id - Level uint8 // 等级 - Exp uint32 // 当前经验值 - Promote uint8 // 突破等阶 - Lock bool // 锁定状态 - AffixIdList []uint32 // 词缀 - MainPropId uint32 // 主词条id - AvatarId uint32 // 装备角色id - Guid uint64 `bson:"-" msgpack:"-"` + ReliquaryId uint64 // 圣遗物的唯一id + ItemId uint32 // 圣遗物的道具id + Level uint8 // 等级 + Exp uint32 // 当前经验值 + Promote uint8 // 突破等阶 + Lock bool // 锁定状态 + AppendPropIdList []uint32 // 追加词条id + MainPropId uint32 // 主词条id + AvatarId uint32 // 装备角色id + Guid uint64 `bson:"-" msgpack:"-"` } func (p *Player) InitReliquary(reliquary *Reliquary) { + // 获取圣遗物配置表 + reliquaryConfig := gdconf.GetItemDataById(int32(reliquary.ItemId)) + if reliquaryConfig == nil { + logger.Error("reliquary config error, itemId: %v", reliquary.ItemId) + return + } reliquary.Guid = p.GetNextGameObjectGuid() p.GameObjectGuidMap[reliquary.Guid] = GameObject(reliquary) p.ReliquaryMap[reliquary.ReliquaryId] = reliquary if reliquary.AvatarId != 0 { avatar := p.AvatarMap[reliquary.AvatarId] avatar.EquipGuidMap[reliquary.Guid] = reliquary.Guid - avatar.EquipReliquaryList = append(avatar.EquipReliquaryList, reliquary) + avatar.EquipReliquaryMap[uint8(reliquaryConfig.ReliquaryType)] = reliquary } } @@ -35,18 +41,39 @@ func (p *Player) InitAllReliquary() { } } +func (p *Player) GetReliquaryGuid(reliquaryId uint64) uint64 { + reliquaryInfo := p.ReliquaryMap[reliquaryId] + if reliquaryInfo == nil { + return 0 + } + return reliquaryInfo.Guid +} + +func (p *Player) GetReliquaryIdByGuid(guid uint64) uint64 { + for reliquaryId, reliquary := range p.ReliquaryMap { + if guid == reliquary.Guid { + return reliquaryId + } + } + return 0 +} + +func (p *Player) GetReliquary(reliquaryId uint64) *Reliquary { + return p.ReliquaryMap[reliquaryId] +} + func (p *Player) AddReliquary(itemId uint32, reliquaryId uint64, mainPropId uint32) { reliquary := &Reliquary{ - ReliquaryId: reliquaryId, - ItemId: itemId, - Level: 1, - Exp: 0, - Promote: 0, - Lock: false, - AffixIdList: make([]uint32, 0), - MainPropId: mainPropId, - AvatarId: 0, - Guid: 0, + ReliquaryId: reliquaryId, + ItemId: itemId, + Level: 1, + Exp: 0, + Promote: 0, + Lock: false, + AppendPropIdList: make([]uint32, 0), + MainPropId: mainPropId, + AvatarId: 0, + Guid: 0, } itemDataConfig := gdconf.GetItemDataById(int32(itemId)) if itemDataConfig == nil { @@ -57,3 +84,12 @@ func (p *Player) AddReliquary(itemId uint32, reliquaryId uint64, mainPropId uint p.InitReliquary(reliquary) p.ReliquaryMap[reliquaryId] = reliquary } + +func (p *Player) CostReliquary(reliquaryId uint64) uint64 { + reliquary := p.ReliquaryMap[reliquaryId] + if reliquary == nil { + return 0 + } + delete(p.ReliquaryMap, reliquaryId) + return reliquary.Guid +} diff --git a/protocol/cmd/cmd_id_proto_obj_map.go b/protocol/cmd/cmd_id_proto_obj_map.go index b3a672a5..a60c123b 100644 --- a/protocol/cmd/cmd_id_proto_obj_map.go +++ b/protocol/cmd/cmd_id_proto_obj_map.go @@ -250,6 +250,8 @@ func (c *CmdProtoMap) registerAllMessage() { c.registerMessage(WeaponAwakenRsp, &proto.WeaponAwakenRsp{}) // 武器精炼响应 c.registerMessage(SetEquipLockStateReq, &proto.SetEquipLockStateReq{}) // 设置装备上锁状态请求 c.registerMessage(SetEquipLockStateRsp, &proto.SetEquipLockStateRsp{}) // 设置装备上锁状态响应 + c.registerMessage(TakeoffEquipReq, &proto.TakeoffEquipReq{}) // 装备卸下请求 + c.registerMessage(TakeoffEquipRsp, &proto.TakeoffEquipRsp{}) // 装备卸下响应 // 商店 c.registerMessage(GetShopmallDataReq, &proto.GetShopmallDataReq{}) // 商店信息请求