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 }