| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424 |
- 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.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, req *pb.I32) {
- craftNum := req.Value
- if craftNum <= 0 {
- p.ResponseCode(session, code.IllegalArgument)
- return
- }
- costs := data.Const.GetEquipRandomCraftCost(craftNum)
- // 检查材料
- errCode := asset.Service().IsAllEnough(p.playerID, costs)
- if code.IsFail(errCode) {
- p.ResponseCode(session, errCode)
- return
- }
- // 随机craftNum件装备
- itemPoolRows, errCode := data.DropPool.Random(data.Const.EquipRandomCraftPoolID, craftNum)
- if code.IsFail(errCode) {
- p.ResponseCode(session, errCode)
- return
- }
- var (
- assets = types.Assets{}
- qualityCounts = map[int32]int32{}
- )
- for _, itemPoolRow := range itemPoolRows {
- equipRow, found := data.Equip.GetByID(itemPoolRow.ItemID)
- if !found {
- p.ResponseCode(session, code.ConfigNotFound_Equip)
- return
- }
- assets.Add(itemPoolRow.ItemID, itemPoolRow.Num)
- quality := int32(equipRow.Quality)
- qualityCounts[quality] = qualityCounts[quality] + int32(itemPoolRow.Num)
- }
- // 加资产(装备)
- addAssets, errCode := asset.Service().Adds(p.playerID, assets, 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("equipRandomCraft error: errCode = %d", errCode)
- p.ResponseCode(session, errCode)
- return
- }
- // 累计打造次数
- equipTable := p.EquipTable()
- for quality, num := range qualityCounts {
- equipTable.EquipExtend.AddCraftQualityCount(quality, 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)
- }
|