diff --git a/common/constant/constant.go b/common/constant/constant.go index 7823060c..62f2ca23 100644 --- a/common/constant/constant.go +++ b/common/constant/constant.go @@ -21,4 +21,5 @@ func InitConstant() { InitStaminaCostConst() InitWeaponTypeConst() InitGCGTokenConst() + InitItemConstantConst() } diff --git a/common/constant/item_constant.go b/common/constant/item_constant.go new file mode 100644 index 00000000..cb4cee02 --- /dev/null +++ b/common/constant/item_constant.go @@ -0,0 +1,23 @@ +package constant + +var ItemConstantConst *ItemConstant + +type ItemConstant struct { + HCOIN uint32 // 原石 201 + SCOIN uint32 // 摩拉 202 + MCOIN uint32 // 创世结晶 203 + RESIN uint32 // 树脂 106 + LEGENDARY_KEY uint32 // 传说任务钥匙 107 + HOME_COIN uint32 // 洞天宝钱 204 +} + +func InitItemConstantConst() { + ItemConstantConst = new(ItemConstant) + + ItemConstantConst.HCOIN = 201 + ItemConstantConst.SCOIN = 202 + ItemConstantConst.MCOIN = 203 + ItemConstantConst.RESIN = 106 + ItemConstantConst.LEGENDARY_KEY = 207 + ItemConstantConst.HOME_COIN = 204 +} diff --git a/gdconf/item_data.go b/gdconf/item_data.go index 4955e9dc..de7cd450 100644 --- a/gdconf/item_data.go +++ b/gdconf/item_data.go @@ -17,7 +17,8 @@ type ItemData struct { GadgetId int32 `csv:"GadgetId,omitempty"` // 物件ID Name string `csv:"Name,omitempty"` // 数值用类型 // 材料 - MaterialType int32 `csv:"MaterialType,omitempty"` // 材料类型 + MaterialType int32 `csv:"MaterialType,omitempty"` // 材料类型 + Use1Param1 string `csv:"Use1Param1,omitempty"` // [使用]1参数1 // 武器 EquipType int32 `csv:"EquipType,omitempty"` // 武器种类 EquipLevel int32 `csv:"EquipLevel,omitempty"` // 武器阶数 diff --git a/gdconf/table_struct_mapping.json b/gdconf/table_struct_mapping.json index c618d1e4..056a9a30 100644 --- a/gdconf/table_struct_mapping.json +++ b/gdconf/table_struct_mapping.json @@ -456,6 +456,11 @@ "field_name": "MaterialType", "field_type": "int32", "origin_name": "材料类型" + }, + { + "field_name": "Use1Param1", + "field_type": "string", + "origin_name": "[使用]1参数1" } ] }, diff --git a/gs/game/player_avatar.go b/gs/game/player_avatar.go index 7e0c274c..d8ae1eaa 100644 --- a/gs/game/player_avatar.go +++ b/gs/game/player_avatar.go @@ -8,6 +8,7 @@ import ( "hk4e/pkg/object" "hk4e/protocol/cmd" "hk4e/protocol/proto" + "strconv" pb "google.golang.org/protobuf/proto" ) @@ -79,11 +80,32 @@ func (g *GameManager) AvatarUpgradeReq(player *model.Player, payloadMsg pb.Messa } // 经验书数量是否足够 if player.GetItemCount(req.ItemId) < req.Count { - logger.Error("item count not enough, itemCount: %v", req.Count) + logger.Error("item count not enough, itemId: %v", req.ItemId) g.CommonRetError(cmd.AvatarUpgradeRsp, player, &proto.AvatarUpgradeRsp{}, proto.Retcode_RET_ITEM_COUNT_NOT_ENOUGH) return } - // TODO 摩拉数量是否足够 + // 获取经验书物品配置表 + itemDataConfig, ok := gdconf.CONF.ItemDataMap[int32(req.ItemId)] + if !ok { + logger.Error("item data config error, itemId: %v", constant.ItemConstantConst.SCOIN) + g.CommonRetError(cmd.AvatarUpgradeRsp, player, &proto.AvatarUpgradeRsp{}, proto.Retcode_RET_ITEM_NOT_EXIST) + return + } + // 经验书将给予的经验数 + itemParam, err := strconv.Atoi(itemDataConfig.Use1Param1) + if err != nil { + logger.Error("parse item param error: %v", err) + g.CommonRetError(cmd.AvatarUpgradeRsp, player, &proto.AvatarUpgradeRsp{}) + return + } + // 角色获得的经验 + expCount := uint32(itemParam) * req.Count + // 摩拉数量是否足够 + if player.GetItemCount(constant.ItemConstantConst.SCOIN) < expCount/5 { + logger.Error("item count not enough, itemId: %v", constant.ItemConstantConst.SCOIN) + g.CommonRetError(cmd.AvatarUpgradeRsp, player, &proto.AvatarUpgradeRsp{}, proto.Retcode_RET_SCOIN_NOT_ENOUGH) + return + } // 获取角色突破配置表 avatarPromoteConfig, ok := gdconf.CONF.AvatarPromoteDataMap[int32(avatar.Promote)] if !ok { @@ -94,15 +116,19 @@ func (g *GameManager) AvatarUpgradeReq(player *model.Player, payloadMsg pb.Messa // 角色等级是否达到限制 if avatar.Level >= uint8(avatarPromoteConfig.LevelLimit) { logger.Error("avatar promote config error, promoteLevel: %v", avatar.Promote) - g.CommonRetError(cmd.AvatarUpgradeRsp, player, &proto.AvatarUpgradeRsp{}) + g.CommonRetError(cmd.AvatarUpgradeRsp, player, &proto.AvatarUpgradeRsp{}, proto.Retcode_RET_AVATAR_LIMIT_LEVEL_ERROR) return } - // 消耗升级材料并升级角色 + // 消耗升级材料以及摩拉 GAME_MANAGER.CostUserItem(player.PlayerID, []*UserItem{ { ItemId: req.ItemId, ChangeCount: req.Count, }, + { + ItemId: constant.ItemConstantConst.SCOIN, + ChangeCount: expCount / 5, + }, }) // 角色升级前的信息 oldLevel := avatar.Level @@ -110,8 +136,39 @@ func (g *GameManager) AvatarUpgradeReq(player *model.Player, payloadMsg pb.Messa for propType, propValue := range avatar.FightPropMap { oldFightPropMap[propType] = propValue } + // 角色添加经验 + g.UpgradeUserAvatar(player.PlayerID, avatar.AvatarId, expCount) + avatarUpgradeRsp := &proto.AvatarUpgradeRsp{ + CurLevel: uint32(avatar.Level), + OldLevel: uint32(oldLevel), + OldFightPropMap: oldFightPropMap, + CurFightPropMap: avatar.FightPropMap, + AvatarGuid: req.AvatarGuid, + } + g.SendMsg(cmd.AvatarUpgradeRsp, player.PlayerID, player.ClientSeq, avatarUpgradeRsp) +} + +// UpgradeUserAvatar 用户角色升级 +func (g *GameManager) UpgradeUserAvatar(userId uint32, avatarId uint32, expCount uint32) { + player := USER_MANAGER.GetOnlineUser(userId) + if player == nil { + logger.Error("player is nil, uid: %v", userId) + return + } + avatar, ok := player.AvatarMap[avatarId] + if !ok { + logger.Error("avatar error, avatarId: %v", avatarId) + return + } + // 获取角色突破配置表 + avatarPromoteConfig, ok := gdconf.CONF.AvatarPromoteDataMap[int32(avatar.Promote)] + if !ok { + logger.Error("avatar promote config error, promoteLevel: %v", avatar.Promote) + g.CommonRetError(cmd.AvatarUpgradeRsp, player, &proto.AvatarUpgradeRsp{}) + return + } // 角色增加经验 - avatar.Exp += req.Count * 20000 // TODO 根据物品id给予相应的经验 + avatar.Exp += expCount // 角色升级 for { // 获取角色等级配置表 @@ -121,12 +178,15 @@ func (g *GameManager) AvatarUpgradeReq(player *model.Player, payloadMsg pb.Messa g.CommonRetError(cmd.AvatarUpgradeRsp, player, &proto.AvatarUpgradeRsp{}) return } - // 角色当前等级未突破则跳出循环 - if avatar.Level >= uint8(avatarPromoteConfig.LevelLimit) { - break - } // 角色经验小于升级所需的经验则跳出循环 - if avatar.Exp < uint32(avatarLevelConfig.Exp) { + if avatar.Exp > uint32(avatarLevelConfig.Exp) { + // 角色当前等级未突破则跳出循环 + if avatar.Level >= uint8(avatarPromoteConfig.LevelLimit) { + // 角色未突破溢出的经验处理 + avatar.Exp = uint32(avatarLevelConfig.Exp) + break + } + } else { break } // 角色等级提升 @@ -137,14 +197,6 @@ func (g *GameManager) AvatarUpgradeReq(player *model.Player, payloadMsg pb.Messa player.InitAvatarFightProp(avatar) // 角色属性表更新通知 g.SendMsg(cmd.AvatarPropNotify, player.PlayerID, player.ClientSeq, g.PacketAvatarPropNotify(avatar)) - avatarUpgradeRsp := &proto.AvatarUpgradeRsp{ - CurLevel: uint32(avatar.Level), - OldLevel: uint32(oldLevel), - OldFightPropMap: oldFightPropMap, - CurFightPropMap: avatar.FightPropMap, - AvatarGuid: req.AvatarGuid, - } - g.SendMsg(cmd.AvatarUpgradeRsp, player.PlayerID, player.ClientSeq, avatarUpgradeRsp) } // PacketAvatarPropNotify 角色属性表更新通知