package player import ( "f1-game/internal/code" "f1-game/internal/constant" "f1-game/internal/data" "f1-game/internal/enum" "f1-game/internal/event" "f1-game/internal/extend/rand" nameLocal "f1-game/internal/name/local" "f1-game/internal/pb" "f1-game/internal/types" gameFacade "f1-game/nodes/game/internal/facade" "f1-game/nodes/game/player/asset" ao "f1-game/nodes/game/player/asset/origin" "f1-game/nodes/game/player/equip" cproto "github.com/cherry-game/cherry/net/proto" ) func (p *actorPlayer) initEquip() { p.Local().Register(nameLocal.Player_EquipCraft, p.equipCraft) p.Local().Register(nameLocal.Player_EquipRandomCraft, p.equipRandomCraft) p.Local().Register(nameLocal.Player_EquipEnhance, p.equipEnhance) p.Local().Register(nameLocal.Player_EquipDimantle, p.equipDimantle) p.Local().Register(nameLocal.Player_EquipSkillActive, p.equipSkillActive) p.Local().Register(nameLocal.Player_EquipExchangeUnlock, p.equipExchangeUnlock) } // equipCraft 装备打造 func (p *actorPlayer) equipCraft(session *cproto.Session, req *pb.I32) { equipRow, ok := data.Equip.GetByID(req.Value) if !ok { p.ResponseCode(session, code.ConfigNotFound_Equip) return } // 检查材料 errCode := asset.Service().IsAllEnough(p.playerID, equipRow.CraftCosts) if code.IsFail(errCode) { p.ResponseCode(session, errCode) return } // 添加装备 addAssets, errCode := asset.Service().Add(p.playerID, equipRow.ID, 1, ao.None, true) if code.IsFail(errCode) { p.ResponseCode(session, errCode) return } // 扣除材料 _, errCode = asset.Service().Subs(p.playerID, equipRow.CraftCosts, ao.None) if code.IsFail(errCode) { p.Warn("equipCraft error: equipID = %d, errCode = %d", equipRow.ID, errCode) p.ResponseCode(session, errCode) return } // 累计打造次数 equipTable := p.EquipTable() equipTable.EquipExtend.AddCraftQualityCount(int32(equipRow.Quality), 1) equipTable.Save2Queue() // 发送打造事件 p.PostEvent(event.NewEquipCraft(p.playerID, addAssets)) // 返回新获得的装备列表 rsp := addAssets.ToAssetListProto() p.Response(session, &rsp) } // equipCraftNew // TODO 后续和客户端联调时删除上面的装备打造方法,保留当前方法 func (p *actorPlayer) equipCraftNew(session *cproto.Session, req *pb.I32I32) { var ( equipID = req.Key num = int64(req.Value) ) // 锻造数量错误 if num <= 0 { p.ResponseCode(session, code.IllegalArgument) return } equipRow, ok := data.Equip.GetByID(equipID) if !ok { p.ResponseCode(session, code.ConfigNotFound_Equip) return } costs := equipRow.CalEquipCraftCosts(num) // 检查材料 errCode := asset.Service().IsAllEnough(p.playerID, costs) if code.IsFail(errCode) { p.ResponseCode(session, errCode) return } // 添加装备 addAssets, errCode := asset.Service().Add(p.playerID, equipRow.ID, num, ao.None, true) if code.IsFail(errCode) { p.ResponseCode(session, errCode) return } // 扣除材料 _, errCode = asset.Service().Subs(p.playerID, costs, ao.None) if code.IsFail(errCode) { p.Warn("equipCraft error: equipID = %d, errCode = %d", equipRow.ID, errCode) p.ResponseCode(session, errCode) return } // 累计打造次数 equipTable := p.EquipTable() equipTable.EquipExtend.AddCraftQualityCount(int32(equipRow.Quality), req.Value) equipTable.Save2Queue() // 发送打造事件 p.PostEvent(event.NewEquipCraft(p.playerID, addAssets)) // 返回新获得的装备列表 rsp := addAssets.ToAssetListProto() p.Response(session, &rsp) } // equipRandomCraft 装备随机打造 func (p *actorPlayer) equipRandomCraft(session *cproto.Session, _ *pb.None) { // 检查材料 errCode := asset.Service().IsAllEnough(p.playerID, data.Const.EquipRandomCraftCost) if code.IsFail(errCode) { p.ResponseCode(session, errCode) return } // 随机一件装备 itemPoolRow, errCode := data.DropPool.Random(data.Const.EquipRandomCraftPoolID) if code.IsFail(errCode) { p.ResponseCode(session, errCode) return } equipRow, found := data.Equip.GetByID(itemPoolRow.ItemID) if !found { p.ResponseCode(session, code.ConfigNotFound_Equip) return } // 加资产(装备) addAssets, errCode := asset.Service().Add(p.playerID, itemPoolRow.ItemID, itemPoolRow.Num, ao.None, true) if code.IsFail(errCode) { p.ResponseCode(session, errCode) return } // 扣除材料 _, errCode = asset.Service().Subs(p.playerID, data.Const.EquipRandomCraftCost, ao.None) if code.IsFail(errCode) { p.Warn("equipRandomCraft error: errCode = %d", errCode) p.ResponseCode(session, errCode) return } // 累计打造次数 equipTable := p.EquipTable() equipTable.EquipExtend.AddCraftQualityCount(int32(equipRow.Quality), int32(itemPoolRow.Num)) equipTable.Save2Queue() // 发送打造事件 p.PostEvent(event.NewEquipCraft(p.playerID, addAssets)) // 返回新获得的装备列表 rsp := addAssets.ToAssetListProto() p.Response(session, &rsp) } // equipEnhance 装备强化 func (p *actorPlayer) equipEnhance(session *cproto.Session, req *pb.I64Bool) { var ( equipTable = p.EquipTable() equipGUID = req.Key useMOCoin = req.Value equip, ok = equipTable.Equips.Get(equipGUID) ) if !ok { p.ResponseCode(session, code.EquipNotFound) return } if equip.WearHeroGUID > 0 { // 检测英雄是否是出战状态 errCode := p.checkHeroCanUpdateEquip(equip.WearHeroGUID) if code.IsFail(errCode) { p.ResponseCode(session, errCode) return } } equipRow, ok := data.Equip.GetByID(equip.EquipID) if !ok { p.ResponseCode(session, code.ConfigNotFound_Equip) return } equipLevelRow, ok := data.EquipLevel.GetByQualityLevel(equipRow.Quality, equip.Level) if !ok { p.ResponseCode(session, code.ConfigNotFound_EquipLevel) return } // 强化消耗为空,表示已经到了最高级 if equipLevelRow.EnhanceCosts.IsEmpty() { p.ResponseCode(session, code.EquipLevelMax) return } var ( costs types.Assets prob = equipLevelRow.SuccessProb ) costs.AddAssets(equipLevelRow.EnhanceCosts) // 非100%概率使用MO币的情况 if useMOCoin && prob < constant.RatioBase { // 计算增加的概率和消耗的MO币 var ( costAssetID = data.Const.EquipEnhanceAddProbCost.ID curNum = asset.Service().Get(p.playerID, costAssetID) ) addProb, costCoin := data.Const.CalEquipEnhanceAddProb(prob, curNum) if costCoin != nil { costs.AddAssets(costCoin) prob += addProb } else { // 没有使用额外道具提升概率 useMOCoin = false } } // 扣除资源 _, errCode := asset.Service().Subs(p.playerID, costs, ao.None) if code.IsFail(errCode) { p.ResponseCode(session, errCode) return } var success bool // 100% 成功率直接完成 if prob >= constant.RatioBase { success = true } else { success = rand.RangeInt[int32](0, constant.RatioBase) < prob } // 不成功 if !success { // 如果没有使用MO币,返还部分材料 costs := equipLevelRow.EnhanceFailReturn() if useMOCoin { // 如果使用了MO币,返还全部材料 costs = equipLevelRow.EnhanceCosts } asset.Service().Adds(p.playerID, costs, ao.None, true) p.ResponseCode(session, code.EquipEnhanceFail) return } equip.Level++ equipTable.EquipExtend.IncrEnhanceCount() equipTable.EquipExtend.IncrEnhance(equip.Level) equipTable.Save2Queue() // 判断装备是否被穿戴,如果被穿戴需要刷新英雄属性 if equip.WearHeroGUID > 0 { heroTable := p.HeroTable() heroEntity, found := heroTable.Heroes.Get(equip.WearHeroGUID) if found { // 刷新英雄属性 gameFacade.Hero.UpdateAttrs(p.playerID, heroEntity) heroTable.Save2Queue() // 推送变更信息 gameFacade.Hero.ChangePush(p.playerID, nil, heroEntity) } } proto := equip.ToProto() p.PostEvent(event.NewEquipEnhance(p.playerID, proto)) // 发送系统消息 p.PostEvent(event.NewChatSystemMsg(p.playerID, enum.ChatMsgType_equipEnhance, nil, nil, equip.EquipID, equip.Level)) p.Response(session, proto) } // equipDimantle 装备分解 func (p *actorPlayer) equipDimantle(session *cproto.Session, req *pb.I64List) { var ( equipTable = p.EquipTable() rewards types.Assets ) for _, equipGUID := range req.List { equip, ok := equipTable.Equips.Get(equipGUID) if !ok { p.ResponseCode(session, code.EquipNotFound) return } // 穿戴中无法分解 if equip.WearHeroGUID > 0 { p.ResponseCode(session, code.EquipGUIDHasWear) return } equipRow, found := data.Equip.GetByID(equip.EquipID) if !found { p.ResponseCode(session, code.ConfigNotFound_Equip) return } equipLevelRow, found := data.EquipLevel.GetByQualityLevel(equipRow.Quality, equip.Level) if !found { p.ResponseCode(session, code.ConfigNotFound_EquipLevel) return } // 分解奖励 rewards.AddAssets(equipLevelRow.DimantleRewards) } // 加资产 retAssets, errCode := asset.Service().Adds(p.playerID, rewards, ao.None, true) if code.IsFail(errCode) { p.ResponseCode(session, errCode) return } equipTable.Equips.Remove(req.List...) equipDimantleCount := int32(len(req.List)) equipTable.EquipExtend.IncrEquipDimantleCount(equipDimantleCount) equipTable.Save2Queue() equip.Service().ChangePush(p.playerID, req.List) resp := retAssets.ToAssetListProto() p.Response(session, &resp) // 发送分解事件 p.PostEvent(event.NewEquipDimantle(p.playerID, equipDimantleCount)) } // equipSkillActive 装备技能激活 func (p *actorPlayer) equipSkillActive(session *cproto.Session, req *pb.I64) { var ( equipGUID = req.Value equipTable = p.EquipTable() equip, ok = equipTable.Equips.Get(equipGUID) ) if !ok { p.ResponseCode(session, code.EquipNotFound) return } // TODO 可能需要判断其它条件: 比如装备在英雄身上,英雄在场景中等 // 是否有可以解锁的专属技能 errCode := equip.IsSkillUnlockable() if code.IsFail(errCode) { p.ResponseCode(session, errCode) return } // 扣除道具 costItem := data.Const.EquipSpecailSkillUnlockCost _, errCode = asset.Service().Sub(p.playerID, costItem.ID, costItem.Num, ao.None) if code.IsFail(errCode) { p.ResponseCode(session, errCode) return } // 解锁技能 equip.SpecialSkill.Value = 1 equipTable.Save2Queue() proto := equip.ToProto() p.Response(session, proto) } // 上架前对装备进行解锁 func (p *actorPlayer) equipExchangeUnlock(session *cproto.Session, req *pb.I64) { equipGUID := req.Value if equipGUID < 1 { p.ResponseCode(session, code.IllegalArgument) return } dbEquip, errCode := equip.Service().GetEquip(p.playerID, equipGUID) if code.IsFail(errCode) { p.ResponseCode(session, errCode) return } if dbEquip.State != enum.EquipState_Normal { p.ResponseCode(session, code.IllegalArgument) return } exchangeGoodsRow, found := data.ExchangeGoods.GetByID(dbEquip.EquipID) if !found { p.ResponseCode(session, code.ConfigNotFound_ExchangeGoods) return } cost := exchangeGoodsRow.UnbindCost if !cost.IsEmpty() { if errCode := asset.Service().IsAllEnough(p.playerID, cost); code.IsFail(errCode) { p.ResponseCode(session, errCode) return } asset.Service().Subs(p.playerID, cost, ao.ExchangeEqueipUnlockCost) } equip.Service().UpdateEquipStatus(p.playerID, equipGUID, enum.EquipState_Unlock) p.Debug("equipExchangeUnlock success. equipGUID [%d]", equipGUID) p.ResponseCode(session, code.OK) }