100 lines
2.9 KiB
Go
100 lines
2.9 KiB
Go
package gameserver
|
|
|
|
import (
|
|
"fmt"
|
|
"gac-hkrpg-go/internal/common"
|
|
pb "gac-hkrpg-go/protocol/proto"
|
|
)
|
|
|
|
func drawLimitedAvatar(s *Session, req *pb.DoGachaCsReq, rsp *pb.DoGachaScRsp, banner common.LimitedGachaBanner) error {
|
|
rsp.Retcode = uint32(pb.Retcode_RET_GACHA_NOT_SUPPORT)
|
|
if _, active := CURRENT_BATTLE.Load(s.Token); active {
|
|
return nil
|
|
}
|
|
player := s.JSON()
|
|
if player == nil {
|
|
return nil
|
|
}
|
|
_, policy, err := common.LoadBrowsableGachaBanners()
|
|
if err != nil {
|
|
return err
|
|
}
|
|
allowed := false
|
|
for _, n := range policy.DrawCounts {
|
|
allowed = allowed || n == req.GachaNum
|
|
}
|
|
if !allowed {
|
|
rsp.Retcode = uint32(pb.Retcode_RET_GACHA_NUM_INVALID)
|
|
return nil
|
|
}
|
|
resources, err := loadEidolonResources()
|
|
if err != nil {
|
|
return err
|
|
}
|
|
costs := map[uint32]map[uint32]uint32{}
|
|
for _, id := range append([]uint32{banner.AvatarID}, banner.FourStarIDs...) {
|
|
avatar, ok := resources.Avatars[id]
|
|
if !ok {
|
|
return fmt.Errorf("missing limited avatar Eidolon resource %d", id)
|
|
}
|
|
first := map[uint32]uint32{}
|
|
for _, rank := range avatar.Ranks {
|
|
if rank.Rank != 1 {
|
|
continue
|
|
}
|
|
for _, cost := range rank.Cost {
|
|
next := uint64(first[cost.ItemID]) + uint64(cost.ItemNum)
|
|
if cost.ItemID == 0 || cost.ItemNum == 0 || next > uint64(^uint32(0)) {
|
|
return fmt.Errorf("invalid limited duplicate cost")
|
|
}
|
|
first[cost.ItemID] = uint32(next)
|
|
}
|
|
}
|
|
if len(first) == 0 {
|
|
return fmt.Errorf("missing first-rank duplicate cost %d", id)
|
|
}
|
|
costs[id] = first
|
|
}
|
|
bag, err := bagMaterials(player)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
baseline := map[uint32]uint32{}
|
|
for _, item := range bag {
|
|
baseline[item.Tid] = item.Num
|
|
}
|
|
result, err := common.DrawLimitedGacha(req.GachaId, req.GachaNum, costs, baseline)
|
|
if err != nil {
|
|
PacketLog("LIMITED_GACHA rejected: " + err.Error())
|
|
return nil
|
|
}
|
|
if player.Materials == nil {
|
|
player.Materials = map[uint32]uint32{}
|
|
}
|
|
sync := &pb.PlayerSyncScNotify{}
|
|
for id, count := range result.Materials {
|
|
player.Materials[id] = count
|
|
sync.MaterialList = append(sync.MaterialList, &pb.Material{Tid: id, Num: count})
|
|
}
|
|
for _, reward := range result.Rewards {
|
|
item := &pb.Item{ItemId: reward.ItemID, Num: 1}
|
|
if reward.Lightcone != nil {
|
|
player.Lightcones = append(player.Lightcones, *reward.Lightcone)
|
|
sync.EquipmentList = append(sync.EquipmentList, reward.Lightcone.ToProtoEquipment())
|
|
item.UniqueId = reward.Lightcone.UniqueID()
|
|
}
|
|
transfer := &pb.ItemList{}
|
|
for id, count := range reward.Materials {
|
|
transfer.ItemList = append(transfer.ItemList, &pb.Item{ItemId: id, Num: count})
|
|
}
|
|
rsp.GachaItemList = append(rsp.GachaItemList, &pb.GachaItem{GachaItem: item, TokenItem: &pb.ItemList{}, TransferItemList: transfer})
|
|
}
|
|
if err = s.Send(sync); err != nil {
|
|
return err
|
|
}
|
|
rsp.Retcode = 0
|
|
rsp.GachaNum = req.GachaNum
|
|
PacketLog(fmt.Sprintf("LIMITED_GACHA banner=%d draws=%d pity5=%d pity4=%d", req.GachaId, req.GachaNum, result.Pity.SinceFiveStar, result.Pity.SinceFourStar))
|
|
return nil
|
|
}
|