Files
bl/logic/service/fight/input/team.go
xinian ca96be3905
All checks were successful
ci/woodpecker/push/my-first-workflow Pipeline was successful
refactor: 统一战斗报文发送逻辑
2026-04-08 12:26:37 +08:00

181 lines
3.8 KiB
Go

package input
import "github.com/gogf/gf/v2/util/grand"
// TeamSlots 返回当前输入所在阵营的全部有效战斗位视图。
func (our *Input) TeamSlots() []*Input {
if our == nil {
return nil
}
if len(our.Team) == 0 {
return []*Input{our}
}
slots := make([]*Input, 0, len(our.Team))
for _, teammate := range our.Team {
if teammate == nil {
continue
}
slots = append(slots, teammate)
}
return slots
}
// TeamSlotIndex 返回当前输入在本阵营中的原始站位下标。
func (our *Input) TeamSlotIndex() int {
if our == nil || len(our.Team) == 0 {
return 0
}
for idx, teammate := range our.Team {
if teammate == our {
return idx
}
}
return 0
}
// Teammates 返回队友列表,不包含自己。
func (our *Input) Teammates() []*Input {
if our == nil {
return nil
}
teammates := make([]*Input, 0, len(our.Team))
for _, teammate := range our.TeamSlots() {
if teammate == nil || teammate == our {
continue
}
teammates = append(teammates, teammate)
}
return teammates
}
// LivingTeammates 返回当前仍有存活出战精灵的队友列表。
func (our *Input) LivingTeammates() []*Input {
if our == nil {
return nil
}
teammates := make([]*Input, 0, len(our.Team))
for _, teammate := range our.Teammates() {
currentPet := teammate.CurrentPet()
if currentPet == nil || currentPet.Info.Hp == 0 {
continue
}
teammates = append(teammates, teammate)
}
return teammates
}
// HasLivingTeammate 用于快速判断当前战斗位是否还有存活队友。
func (our *Input) HasLivingTeammate() bool {
return len(our.LivingTeammates()) > 0
}
// TeamSlotAt 返回指定己方站位。
func (our *Input) TeamSlotAt(index int) *Input {
if our == nil {
return nil
}
if index >= 0 && index < len(our.Team) {
return our.Team[index]
}
if index == 0 {
return our
}
return nil
}
// OpponentSlotAt 返回指定敌方站位。
func (our *Input) OpponentSlotAt(index int) *Input {
if our == nil {
return nil
}
if index >= 0 && index < len(our.OppTeam) {
return our.OppTeam[index]
}
if index == 0 {
return our.Opp
}
return nil
}
func nextLivingSlotIndex(slots []*Input, start int) int {
if len(slots) == 0 {
return -1
}
if start < 0 {
start = 0
}
if start >= len(slots) {
start = 0
}
availableIndex := -1
for offset := 0; offset < len(slots); offset++ {
idx := (start + offset) % len(slots)
slot := slots[idx]
if slot == nil {
continue
}
if availableIndex < 0 {
availableIndex = idx
}
current := slot.CurrentPet()
if current != nil && current.Info.Hp > 0 {
return idx
}
}
return availableIndex
}
// OpponentSlotAtOrNextLiving 返回指定敌方站位;若该目标已死亡,则顺延到下一只存活精灵。
func (our *Input) OpponentSlotAtOrNextLiving(index int) (*Input, int) {
if our == nil {
return nil, -1
}
if len(our.OppTeam) == 0 {
return our.OpponentSlotAt(index), index
}
resolvedIndex := nextLivingSlotIndex(our.OppTeam, index)
if resolvedIndex < 0 {
return nil, -1
}
return our.OppTeam[resolvedIndex], resolvedIndex
}
// RandomOpponentSlotIndex 返回一个可用的敌方站位下标,优先从存活站位中随机。
func (our *Input) RandomOpponentSlotIndex() int {
if our == nil {
return 0
}
if len(our.OppTeam) == 0 {
if our.Opp != nil {
return 0
}
return 0
}
living := make([]int, 0, len(our.OppTeam))
available := make([]int, 0, len(our.OppTeam))
for idx, opponent := range our.OppTeam {
if opponent == nil {
continue
}
available = append(available, idx)
current := opponent.CurrentPet()
if current != nil && current.Info.Hp > 0 {
living = append(living, idx)
}
}
candidates := living
if len(candidates) == 0 {
candidates = available
}
if len(candidates) == 0 {
return 0
}
if len(candidates) == 1 {
return candidates[0]
}
return candidates[grand.Intn(len(candidates))]
}