Files
bl/logic/service/player/pet_bag.go
昔念 6f51a2e349
All checks were successful
ci/woodpecker/push/my-first-workflow Pipeline was successful
1
2026-04-15 00:07:36 +08:00

202 lines
4.7 KiB
Go

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
}