package player import ( "blazing/common/utils" "blazing/logic/service/pet" "blazing/modules/player/model" ) type PetBagSlot struct { list *[]model.PetInfo index int info model.PetInfo main bool } func (slot PetBagSlot) IsValid() bool { return slot.list != nil && slot.index >= 0 && slot.index < len(*slot.list) } func (slot PetBagSlot) Remove() { *slot.list = append((*slot.list)[:slot.index], (*slot.list)[slot.index+1:]...) } func (slot PetBagSlot) PetInfo() model.PetInfo { return slot.info } func (slot PetBagSlot) PetInfoPtr() *model.PetInfo { if !slot.IsValid() { return nil } return &(*slot.list)[slot.index] } func (slot PetBagSlot) IsMainBag() bool { return slot.main } func buildCatchTimeSet(petLists ...[]model.PetInfo) map[uint32]struct{} { total := 0 for _, petList := range petLists { total += len(petList) } catchTimes := make(map[uint32]struct{}, total) for _, petList := range petLists { for _, petInfo := range petList { catchTimes[petInfo.CatchTime] = struct{}{} } } return catchTimes } func removePetByCatchTime(petList []model.PetInfo, catchTime uint32) []model.PetInfo { for i := range petList { if petList[i].CatchTime == catchTime { return append(petList[:i], petList[i+1:]...) } } return petList } func buildPetInfoMap(petLists ...[]model.PetInfo) map[uint32]*model.PetInfo { total := 0 for _, petList := range petLists { total += len(petList) } petMap := make(map[uint32]*model.PetInfo, total) for _, petList := range petLists { for i := range petList { petMap[petList[i].CatchTime] = &petList[i] } } return petMap } func buildOrderedPetList( catchTimes []uint32, petMap map[uint32]*model.PetInfo, ) []model.PetInfo { result := make([]model.PetInfo, len(catchTimes)) for i, catchTime := range catchTimes { result[i] = *petMap[catchTime] } return result } func validatePetBagOrder( catchTimes []uint32, bagCatchTimes map[uint32]struct{}, used map[uint32]struct{}, ) bool { for _, catchTime := range catchTimes { if catchTime == 0 { return false } if _, exists := bagCatchTimes[catchTime]; !exists { return false } if _, exists := used[catchTime]; exists { return false } used[catchTime] = struct{}{} } return true } func buildLimitedPetList(petList []model.PetInfo, limitlevel uint32) []model.PetInfo { result := make([]model.PetInfo, 0, len(petList)) for _, petInfo := range petList { result = append(result, ApplyPetLevelLimit(petInfo, limitlevel)) } return result } // GetUserBagPetInfo 返回主背包和并列备用精灵列表。 func (p *Player) GetUserBagPetInfo(limitlevel uint32) *pet.GetUserBagPetInfoOutboundInfo { result := &pet.GetUserBagPetInfoOutboundInfo{ PetList: buildLimitedPetList(p.Info.PetList, limitlevel), BackupPetList: buildLimitedPetList(p.Info.BackupPetList, limitlevel), } return result } func (p *Player) FindBackupPet(catchTime uint32) (int, *model.PetInfo, bool) { return utils.FindWithIndex(p.Info.BackupPetList, func(petInfo model.PetInfo) bool { return petInfo.CatchTime == catchTime }) } func (p *Player) FindPetBagSlot(catchTime uint32) (PetBagSlot, bool) { if index, petInfo, ok := p.FindPet(catchTime); ok { return PetBagSlot{ list: &p.Info.PetList, index: index, info: *petInfo, main: true, }, true } if index, petInfo, ok := p.FindBackupPet(catchTime); ok { return PetBagSlot{ list: &p.Info.BackupPetList, index: index, info: *petInfo, main: false, }, true } return PetBagSlot{}, false } func (p *Player) AddPetToAvailableBag(petInfo model.PetInfo) bool { if len(p.Info.PetList) < 6 { p.Info.PetList = append(p.Info.PetList, petInfo) return true } if len(p.Info.BackupPetList) < 6 { p.Info.BackupPetList = append(p.Info.BackupPetList, petInfo) return true } return false } func (p *Player) RemoveBackupPet(catchTime uint32) { p.Info.BackupPetList = removePetByCatchTime(p.Info.BackupPetList, catchTime) } func (p *Player) SavePetBagOrder(petList []uint32, backupPetList []uint32) bool { if len(petList) > 6 || len(backupPetList) > 6 { return false } totalPetCount := len(p.Info.PetList) + len(p.Info.BackupPetList) if len(petList)+len(backupPetList) != totalPetCount { return false } bagCatchTimes := buildCatchTimeSet(p.Info.PetList, p.Info.BackupPetList) used := make(map[uint32]struct{}, totalPetCount) if !validatePetBagOrder(petList, bagCatchTimes, used) { return false } if !validatePetBagOrder(backupPetList, bagCatchTimes, used) { return false } if len(used) != totalPetCount { return false } petMap := buildPetInfoMap(p.Info.PetList, p.Info.BackupPetList) p.Info.PetList = buildOrderedPetList(petList, petMap) p.Info.BackupPetList = buildOrderedPetList(backupPetList, petMap) return true }