refactor(logic): 删除战斗系统相关代码

- 移除 battle 目录下的所有文件
- 删除 fight/battle 目录及其内容
- 更新 go.mod 和 go.sum 文件,移除相关依赖
This commit is contained in:
2025-08-25 01:48:42 +08:00
parent 791a052227
commit d7b4fb88c8
18 changed files with 997 additions and 3 deletions

View File

@@ -1,4 +1,4 @@
package fight
package mode
import "github.com/tnnmigga/enum"

View File

@@ -0,0 +1,140 @@
package node
import "fmt"
// 基础上下文
type EffectContext struct {
Turn int // 当前回合数
Actor string // 当前行动者(谁在出手)
Target string // 当前目标(技能攻击对象)
Skill string // 使用的技能
Extra map[string]interface{} // 临时附加信息(状态、标记、计算中间值等)
}
// 节点类型
type NodeFunc func(ctx *EffectContext, next func())
type EffectNode struct {
Name string
Exec NodeFunc
}
// 节点管理器
type NodeRunner struct {
nodes []*EffectNode
index int
ctx *EffectContext
}
func NewNodeRunner(ctx *EffectContext, nodes []*EffectNode) *NodeRunner {
return &NodeRunner{
nodes: nodes,
index: 0,
ctx: ctx,
}
}
// 执行下一个节点
func (r *NodeRunner) Run() {
if r.index >= len(r.nodes) {
return
}
current := r.nodes[r.index]
r.index++
current.Exec(r.ctx, r.Run)
}
// 跳过当前节点
func (r *NodeRunner) Skip() {
r.index++
r.Run()
}
// ------------------------
// 定义战斗流程节点
// ------------------------
func BuildBattleNodes() []*EffectNode {
return []*EffectNode{
{Name: "战斗开始", Exec: func(ctx *EffectContext, next func()) {
fmt.Println("OnBattleStart")
next()
}},
{Name: "登场/切换", Exec: func(ctx *EffectContext, next func()) {
fmt.Println("OnSwitchIn / OnSwitchOut / OnTransform")
next()
}},
{Name: "回合开始", Exec: func(ctx *EffectContext, next func()) {
fmt.Println("TurnStart")
next()
}},
{Name: "操作阶段", Exec: func(ctx *EffectContext, next func()) {
fmt.Println("选择技能 / 使用道具 / 切换")
next()
}},
{Name: "先手判定", Exec: func(ctx *EffectContext, next func()) {
fmt.Println("先手权判定")
next()
}},
{Name: "先手出手-前置", Exec: func(ctx *EffectContext, next func()) {
fmt.Println("BeforeUseSkillCheck / BeforeHit / OnMiss")
next()
}},
{Name: "先手出手-技能命中", Exec: func(ctx *EffectContext, next func()) {
fmt.Println("技能命中判定 / 初始伤害公式 / 红伤数值计算")
next()
}},
{Name: "先手出手-技能效果结算", Exec: func(ctx *EffectContext, next func()) {
fmt.Println("技能效果结算 / 魂印 / 套装 / 回合类效果")
next()
}},
{Name: "先手出手-伤害结算", Exec: func(ctx *EffectContext, next func()) {
fmt.Println("最终伤害生效 / 体力扣除")
next()
}},
{Name: "先手出手-行动结束", Exec: func(ctx *EffectContext, next func()) {
fmt.Println("行动后效果 / 额外行动 / 机盖弹伤 / 出手结束效果")
next()
}},
{Name: "后手出手", Exec: func(ctx *EffectContext, next func()) {
fmt.Println("后手节点同先手节点")
next()
}},
{Name: "回合结束后①", Exec: func(ctx *EffectContext, next func()) {
fmt.Println("回合结束后通用时点① / 桃园回血 / 回合扣减①")
next()
}},
{Name: "回合结束后②", Exec: func(ctx *EffectContext, next func()) {
fmt.Println("回合结束后通用时点② / 战争猎魔 / 16年魂印续航")
next()
}},
{Name: "死亡判定", Exec: func(ctx *EffectContext, next func()) {
fmt.Println("死亡结算 / 保护机制")
next()
}},
{Name: "击败/未击败判定", Exec: func(ctx *EffectContext, next func()) {
fmt.Println("击败触发效果 / 未击败触发效果")
next()
}},
{Name: "进入下回合", Exec: func(ctx *EffectContext, next func()) {
fmt.Println("进入下回合,流程重新开始")
next()
}},
}
}
// ------------------------
// 测试运行
// ------------------------
func TestBattleFlow() {
ctx := &EffectContext{
Turn: 1,
Actor: "PlayerA",
Target: "PlayerB",
Skill: "火球",
Extra: map[string]interface{}{},
}
nodes := BuildBattleNodes()
runner := NewNodeRunner(ctx, nodes)
runner.Run()
}

View File

@@ -1,10 +1,15 @@
package effect
package node
import "github.com/tnnmigga/enum"
type EnumEffectTrigger string
// EnumEffectTrigger 效果触发时机枚举类型
// 定义了战斗中各种效果的触发时机点
type EnumEffectTrigger int
// EffectTrigger 效果触发时机枚举实例
// 包含战斗过程中所有可能触发效果的关键时间点
var EffectTrigger = enum.New[struct {
// 已有的触发时机
OnBattleStart EnumEffectTrigger `enum:"OnBattleStart"` // 战斗开始时触发
BeforeSort EnumEffectTrigger `enum:"BeforeSort"` // 先手顺序判定前触发
BeforeUseSkillCheck EnumEffectTrigger `enum:"BeforeUseSkillCheck"` // 使用技能前检查PP、状态等
@@ -51,4 +56,48 @@ var EffectTrigger = enum.New[struct {
OnOwnerSwitchOut EnumEffectTrigger `enum:"OnOwnerSwitchOut"` // 所属玩家精灵下场时触发
BeforeEffect EnumEffectTrigger `enum:"BeforeEffect"` // 效果生效前触发
AfterEffect EnumEffectTrigger `enum:"AfterEffect"` // 效果生效后触发
// 补充的触发时机
OnBattleEnd EnumEffectTrigger `enum:"OnBattleEnd"` // 战斗结束时触发
OnRoundNumber EnumEffectTrigger `enum:"OnRoundNumber"` // 特定回合数时触发
OnMaxHPChange EnumEffectTrigger `enum:"OnMaxHPChange"` // 最大生命值变化时触发
OnHPPercentLow EnumEffectTrigger `enum:"OnHPPercentLow"` // 生命值低于特定百分比时触发
OnHPPercentHigh EnumEffectTrigger `enum:"OnHPPercentHigh"` // 生命值高于特定百分比时触发
OnStatusAdd EnumEffectTrigger `enum:"OnStatusAdd"` // 获得状态时触发
OnStatusRemove EnumEffectTrigger `enum:"OnStatusRemove"` // 状态被移除时触发
OnStatusRefresh EnumEffectTrigger `enum:"OnStatusRefresh"` // 状态被刷新时触发
OnStatusDurationEnd EnumEffectTrigger `enum:"OnStatusDurationEnd"` // 状态持续回合结束时触发
OnAlliesDefeated EnumEffectTrigger `enum:"OnAlliesDefeated"` // 友方单位被击败时触发
OnEnemiesDefeated EnumEffectTrigger `enum:"OnEnemiesDefeated"` // 敌方单位被击败时触发
OnSkillTypeUsed EnumEffectTrigger `enum:"OnSkillTypeUsed"` // 特定类型技能被使用时触发
OnSpecificSkillUsed EnumEffectTrigger `enum:"OnSpecificSkillUsed"` // 特定技能被使用时触发
OnDeath EnumEffectTrigger `enum:"OnDeath"` // 自身死亡时触发
OnRevive EnumEffectTrigger `enum:"OnRevive"` // 被复活时触发
OnFullHP EnumEffectTrigger `enum:"OnFullHP"` // 生命值回满时触发
OnZeroHP EnumEffectTrigger `enum:"OnZeroHP"` // 生命值归零时触发
OnMaxRage EnumEffectTrigger `enum:"OnMaxRage"` // 怒气值满时触发
OnZeroRage EnumEffectTrigger `enum:"OnZeroRage"` // 怒气值归零时触发
OnWeatherChange EnumEffectTrigger `enum:"OnWeatherChange"` // 天气变化时触发
OnFieldStateChange EnumEffectTrigger `enum:"OnFieldStateChange"` // 场地状态变化时触发
OnItemUsed EnumEffectTrigger `enum:"OnItemUsed"` // 使用物品时触发
OnBeforeItemUse EnumEffectTrigger `enum:"OnBeforeItemUse"` // 使用物品前触发
OnAfterItemUse EnumEffectTrigger `enum:"OnAfterItemUse"` // 使用物品后触发
OnSwapFailed EnumEffectTrigger `enum:"OnSwapFailed"` // 交换精灵失败时触发
OnAllEnemiesDefeated EnumEffectTrigger `enum:"OnAllEnemiesDefeated"` // 所有敌方单位被击败时触发
OnAllAlliesDefeated EnumEffectTrigger `enum:"OnAllAlliesDefeated"` // 所有友方单位被击败时触发
OnComboHit EnumEffectTrigger `enum:"OnComboHit"` // 连击达到特定次数时触发
OnMissContinuous EnumEffectTrigger `enum:"OnMissContinuous"` // 连续未命中特定次数时触发
OnCritContinuous EnumEffectTrigger `enum:"OnCritContinuous"` // 连续暴击特定次数时触发
OnBeforeFaint EnumEffectTrigger `enum:"OnBeforeFaint"` // 即将昏厥前触发
OnImmuneDamage EnumEffectTrigger `enum:"OnImmuneDamage"` // 免疫伤害时触发
OnDamageReflect EnumEffectTrigger `enum:"OnDamageReflect"` // 反弹伤害时触发
OnAbsorbDamage EnumEffectTrigger `enum:"OnAbsorbDamage"` // 吸收伤害时触发
OnStealHP EnumEffectTrigger `enum:"OnStealHP"` // 偷取生命值时触发
OnCopySkill EnumEffectTrigger `enum:"OnCopySkill"` // 复制技能时触发
OnSkillSealed EnumEffectTrigger `enum:"OnSkillSealed"` // 技能被封印时触发
OnSkillUnsealed EnumEffectTrigger `enum:"OnSkillUnsealed"` // 技能封印解除时触发
OnSilenced EnumEffectTrigger `enum:"OnSilenced"` // 被沉默时触发
OnSilenceEnd EnumEffectTrigger `enum:"OnSilenceEnd"` // 沉默状态结束时触发
OnStunned EnumEffectTrigger `enum:"OnStunned"` // 被眩晕时触发
OnStunEnd EnumEffectTrigger `enum:"OnStunEnd"` // 眩晕状态结束时触发
}]()

View File

@@ -0,0 +1,87 @@
package over
import "sync"
// 战斗结束原因池,用于管理战斗结束的各种原因数据
type BattleOverPool struct {
dataMap map[EnumBattleOverReason]BattleOverData
size int
value BattleOverData
mutex sync.RWMutex // 用于并发安全
}
// 初始化战斗结束原因池
func NewBattleOverPool() *BattleOverPool {
return &BattleOverPool{
dataMap: make(map[EnumBattleOverReason]BattleOverData),
}
}
// 添加战斗结束原因
func (p *BattleOverPool) PushReason(reason EnumBattleOverReason, data BattleOverData) {
p.mutex.Lock()
defer p.mutex.Unlock()
p.dataMap[reason] = data
p.value = data
p.size++
}
// 获取并移除指定的战斗结束原因
func (p *BattleOverPool) PopReason(reason EnumBattleOverReason) BattleOverData {
p.mutex.Lock()
defer p.mutex.Unlock()
data, exists := p.dataMap[reason]
if exists {
delete(p.dataMap, reason)
p.size--
}
return data
}
// 获取并移除所有战斗结束原因
func (p *BattleOverPool) PopReasons() []BattleOverData {
p.mutex.Lock()
defer p.mutex.Unlock()
reasons := make([]BattleOverData, 0, p.size)
for _, data := range p.dataMap {
reasons = append(reasons, data)
}
p.dataMap = make(map[EnumBattleOverReason]BattleOverData)
p.size = 0
p.value = nil
return reasons
}
// 获取最后添加的战斗结束原因
func (p *BattleOverPool) PopReasonLast() BattleOverData {
p.mutex.Lock()
defer p.mutex.Unlock()
data := p.value
p.value = nil
if p.size > 0 {
p.size--
}
// 清空map
if p.size == 0 {
p.dataMap = make(map[EnumBattleOverReason]BattleOverData)
}
return data
}
// 判断战斗是否应该结束
func (p *BattleOverPool) IsShouldOver() bool {
p.mutex.RLock()
defer p.mutex.RUnlock()
return p.size > 0
}
// 获取当前战斗结束原因的数量
func (p *BattleOverPool) Size() int {
p.mutex.RLock()
defer p.mutex.RUnlock()
return p.size
}

View File

@@ -0,0 +1,60 @@
package over
import (
"github.com/tnnmigga/enum"
)
// 战斗结束原因数据接口
type BattleOverData interface{}
// 玩家离线数据
type PlayerOfflineData struct {
// 可以根据需要添加字段
PlayerID int64
}
// 玩家逃脱数据
type PlayerEscapeData struct {
// 可以根据需要添加字段
PlayerID int64
}
// 玩家捕获成功数据
type PlayerCaptureSuccessData struct {
// 可以根据需要添加字段
CaptorID int64
TargetID int64
CaptureTime int64
}
// 默认结束数据
type DefaultEndData struct {
// 可以根据需要添加字段
Reason string
}
// 战斗结束原因枚举
type EnumBattleOverReason int
var BattleOverReason = enum.New[struct {
PlayerOffline EnumBattleOverReason `enum:"1"`
PlayerEscape EnumBattleOverReason `enum:"2"`
PlayerCaptureSuccess EnumBattleOverReason `enum:"3"`
DefaultEnd EnumBattleOverReason `enum:"4"`
}]()
// 获取对应的类型
func (e EnumBattleOverReason) DataType() interface{} {
switch e {
case BattleOverReason.PlayerOffline:
return PlayerOfflineData{}
case BattleOverReason.PlayerEscape:
return PlayerEscapeData{}
case BattleOverReason.PlayerCaptureSuccess:
return PlayerCaptureSuccessData{}
case BattleOverReason.DefaultEnd:
return DefaultEndData{}
default:
return nil
}
}

View File

@@ -0,0 +1,19 @@
package base
import (
"blazing/logic/service/fight/battle/node"
"fmt"
)
// 灼烧效果
type BurnEffect struct{}
func (b *BurnEffect) Trigger() node.EnumEffectTrigger {
return node.EffectTrigger.OnHit
}
func (b *BurnEffect) Apply(ctx *node.EffectContext, next func()) {
fmt.Printf("[%s] 命中 [%s],触发灼烧效果!\n", ctx.Actor, ctx.Target)
ctx.Extra["Burn"] = true
next() // 继续执行后续效果
}

View File

@@ -0,0 +1 @@
package impl

View File

@@ -0,0 +1,46 @@
package effect
import "blazing/logic/service/fight/battle/node"
type EffectManager struct {
effects []Effect
}
func NewEffectManager() *EffectManager {
return &EffectManager{}
}
func (m *EffectManager) Register(e Effect) {
m.effects = append(m.effects, e)
}
// 执行某时点效果
func (m *EffectManager) Apply(trigger node.EnumEffectTrigger, ctx *EffectContext) {
var next func(i int)
next = func(i int) {
if i < len(m.effects) {
if m.effects[i].Trigger() == trigger {
m.effects[i].Apply(ctx, func() { next(i + 1) })
} else {
next(i + 1)
}
}
}
next(0)
// 清理过期效果
var alive []Effect
for _, e := range m.effects {
if e.Alive() {
alive = append(alive, e)
}
}
m.effects = alive
}
// 回合 tick
func (m *EffectManager) Tick() {
for _, e := range m.effects {
e.Tick()
}
}

View File

@@ -0,0 +1,11 @@
package skill
type Skill struct {
Name string
Type SkillType
Power int
IsAttack bool
Attacker *BattleUnit
Defender *BattleUnit
Effects []Effect
}

View File

@@ -0,0 +1,70 @@
package start
import (
"fmt"
"sync"
"time"
)
// 记录A、B是否完成的标志
var (
aFinished bool
bFinished bool
mu sync.Mutex // 保护标志位的互斥锁
)
// 当A完成后调用的函数
func onAFinished() {
fmt.Println("A已完成触发onAFinished")
checkBothFinished() // 检查是否两者都完成
}
// 当B完成后调用的函数
func onBFinished() {
fmt.Println("B已完成触发onBFinished")
checkBothFinished() // 检查是否两者都完成
}
// 当A和B都完成后调用的函数
func onBothFinished() {
fmt.Println("A和B都已完成触发onBothFinished")
}
// 检查A和B是否都完成若都完成则调用onBothFinished
func checkBothFinished() {
mu.Lock()
defer mu.Unlock()
if aFinished && bFinished {
onBothFinished()
}
}
// 模拟A的执行
func doA() {
fmt.Println("A开始执行...")
time.Sleep(2 * time.Second) // 模拟耗时操作
mu.Lock()
aFinished = true
mu.Unlock()
onAFinished() // A完成后调用
}
// 模拟B的执行
func doB() {
fmt.Println("B开始执行...")
time.Sleep(3 * time.Second) // 模拟耗时操作
mu.Lock()
bFinished = true
mu.Unlock()
onBFinished() // B完成后调用
}
func main() {
// 启动A和B的执行
go doA()
go doB()
// 等待一段时间,避免主程序提前退出
time.Sleep(4 * time.Second)
}