refactor(logic): 删除战斗系统相关代码
- 移除 battle 目录下的所有文件 - 删除 fight/battle 目录及其内容 - 更新 go.mod 和 go.sum 文件,移除相关依赖
This commit is contained in:
@@ -1,4 +1,4 @@
|
||||
package fight
|
||||
package mode
|
||||
|
||||
import "github.com/tnnmigga/enum"
|
||||
|
||||
140
logic/service/fight/battle/node/def.go
Normal file
140
logic/service/fight/battle/node/def.go
Normal 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()
|
||||
}
|
||||
@@ -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"` // 眩晕状态结束时触发
|
||||
}]()
|
||||
87
logic/service/fight/battle/over/pool.go
Normal file
87
logic/service/fight/battle/over/pool.go
Normal 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
|
||||
}
|
||||
60
logic/service/fight/battle/over/reason.go
Normal file
60
logic/service/fight/battle/over/reason.go
Normal 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
|
||||
}
|
||||
}
|
||||
19
logic/service/fight/battle/skill/effect/base/BurnEffect.go
Normal file
19
logic/service/fight/battle/skill/effect/base/BurnEffect.go
Normal 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() // 继续执行后续效果
|
||||
}
|
||||
1
logic/service/fight/battle/skill/effect/impl/effect1.go
Normal file
1
logic/service/fight/battle/skill/effect/impl/effect1.go
Normal file
@@ -0,0 +1 @@
|
||||
package impl
|
||||
46
logic/service/fight/battle/skill/effect/manger.go
Normal file
46
logic/service/fight/battle/skill/effect/manger.go
Normal 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()
|
||||
}
|
||||
}
|
||||
11
logic/service/fight/battle/skill/skill.go
Normal file
11
logic/service/fight/battle/skill/skill.go
Normal file
@@ -0,0 +1,11 @@
|
||||
package skill
|
||||
|
||||
type Skill struct {
|
||||
Name string
|
||||
Type SkillType
|
||||
Power int
|
||||
IsAttack bool
|
||||
Attacker *BattleUnit
|
||||
Defender *BattleUnit
|
||||
Effects []Effect
|
||||
}
|
||||
70
logic/service/fight/battle/start/start_test.go
Normal file
70
logic/service/fight/battle/start/start_test.go
Normal 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)
|
||||
}
|
||||
Reference in New Issue
Block a user