Files
bl/logic/service/fight/cmd_unified.go
xinian f433a26a6d
All checks were successful
ci/woodpecker/push/my-first-workflow Pipeline was successful
refactor: 重构战斗系统为统一动作包结构
2026-04-06 00:58:23 +08:00

139 lines
4.5 KiB
Go

package fight
import (
"blazing/logic/service/common"
"blazing/modules/player/model"
)
// FightActionType 表示统一动作包里的动作类型。
type FightActionType string
const (
// FightActionTypeSkill 表示使用技能。
FightActionTypeSkill FightActionType = "skill"
// FightActionTypeItem 表示使用道具。
FightActionTypeItem FightActionType = "item"
// FightActionTypeChange 表示主动切宠。
FightActionTypeChange FightActionType = "change"
// FightActionTypeEscape 表示逃跑。
FightActionTypeEscape FightActionType = "escape"
// FightActionTypeChat 表示战斗内聊天。
FightActionTypeChat FightActionType = "chat"
)
// FightActionEnvelope 是统一入站动作结构。
// 约定:
// 1. actorIndex 始终表示发起方所在的我方槽位。
// 2. targetIndex 始终表示目标在所属阵营内的槽位。
// 3. targetRelation 用来区分 targetIndex 属于敌方、自己还是队友。
type FightActionEnvelope struct {
ActionType FightActionType `json:"actionType"`
ActorIndex int `json:"actorIndex"`
TargetIndex int `json:"targetIndex"`
TargetRelation uint8 `json:"targetRelation,omitempty"`
SkillID uint32 `json:"skillId,omitempty"`
ItemID uint32 `json:"itemId,omitempty"`
CatchTime uint32 `json:"catchTime,omitempty"`
Escape bool `json:"escape,omitempty"`
Chat string `json:"chat,omitempty"`
AtkType uint8 `json:"atkType,omitempty"`
}
// NewSkillActionEnvelope 构造技能动作 envelope。
func NewSkillActionEnvelope(skillID uint32, actorIndex, targetIndex int, targetRelation, atkType uint8) FightActionEnvelope {
return FightActionEnvelope{
ActionType: FightActionTypeSkill,
ActorIndex: actorIndex,
TargetIndex: targetIndex,
TargetRelation: targetRelation,
SkillID: skillID,
AtkType: atkType,
}
}
// NewItemActionEnvelope 构造道具动作 envelope。
func NewItemActionEnvelope(catchTime, itemID uint32, actorIndex, targetIndex int, targetRelation uint8) FightActionEnvelope {
return FightActionEnvelope{
ActionType: FightActionTypeItem,
ActorIndex: actorIndex,
TargetIndex: targetIndex,
TargetRelation: targetRelation,
ItemID: itemID,
CatchTime: catchTime,
}
}
// NewChangeActionEnvelope 构造切宠动作 envelope。
func NewChangeActionEnvelope(catchTime uint32, actorIndex int) FightActionEnvelope {
return FightActionEnvelope{
ActionType: FightActionTypeChange,
ActorIndex: actorIndex,
CatchTime: catchTime,
}
}
// NewEscapeActionEnvelope 构造逃跑动作 envelope。
func NewEscapeActionEnvelope() FightActionEnvelope {
return FightActionEnvelope{
ActionType: FightActionTypeEscape,
Escape: true,
}
}
// NewChatActionEnvelope 构造聊天动作 envelope。
func NewChatActionEnvelope(chat string) FightActionEnvelope {
return FightActionEnvelope{
ActionType: FightActionTypeChat,
Chat: chat,
}
}
// normalizedTargetRelation 根据 TargetRelation 和 AtkType 兜底出最终目标关系。
func (e FightActionEnvelope) normalizedTargetRelation() uint8 {
if e.TargetRelation <= SkillTargetAlly {
return e.TargetRelation
}
switch e.AtkType {
case 3:
return SkillTargetSelf
case 1:
return SkillTargetAlly
default:
return SkillTargetOpponent
}
}
// EncodedTargetIndex 把统一结构里的目标信息编码成现有 FightC 内部使用的目标格式。
func (e FightActionEnvelope) EncodedTargetIndex() int {
targetIndex := e.TargetIndex
switch e.normalizedTargetRelation() {
case SkillTargetSelf:
targetIndex = e.ActorIndex
return EncodeTargetIndex(targetIndex, false)
case SkillTargetAlly:
return EncodeTargetIndex(targetIndex, false)
default:
return EncodeTargetIndex(targetIndex, true)
}
}
// HandleActionEnvelope 把统一动作结构派发到现有 FightC 的 indexed 接口上。
func (f *FightC) HandleActionEnvelope(c common.PlayerI, envelope FightActionEnvelope) {
if f == nil || c == nil {
return
}
switch envelope.ActionType {
case FightActionTypeSkill:
f.UseSkillAt(c, envelope.SkillID, envelope.ActorIndex, envelope.EncodedTargetIndex())
case FightActionTypeItem:
f.UseItemAt(c, envelope.CatchTime, envelope.ItemID, envelope.ActorIndex, envelope.EncodedTargetIndex())
case FightActionTypeChange:
f.ChangePetAt(c, envelope.CatchTime, envelope.ActorIndex)
case FightActionTypeEscape:
f.Over(c, model.BattleOverReason.PlayerEscape)
case FightActionTypeChat:
f.Chat(c, envelope.Chat)
}
}