refactor: 重构战斗系统支持多单位多动作

This commit is contained in:
xinian
2026-04-04 05:44:02 +08:00
committed by cnb
parent b62b4af628
commit 28d92c1e18
23 changed files with 1652 additions and 311 deletions

View File

@@ -6,12 +6,16 @@ import (
"blazing/logic/service/fight/info"
"blazing/logic/service/fight/input"
"blazing/modules/player/model"
"github.com/jinzhu/copier"
)
// Compare 比较两个1v1战斗动作的执行优先级(核心逻辑)
func (*FightC) Compare(a, b action.BattleActionI) (action.BattleActionI, action.BattleActionI) {
// Compare 比较两个战斗动作的执行优先级
func (f *FightC) Compare(a, b action.BattleActionI) (action.BattleActionI, action.BattleActionI) {
if a == nil {
return b, a
}
if b == nil {
return a, b
}
// 动作本身的优先级比较
p1 := b.Priority() - a.Priority()
if p1 > 0 { // 对手优先级更高
@@ -20,11 +24,22 @@ func (*FightC) Compare(a, b action.BattleActionI) (action.BattleActionI, action.
return a, b
}
if speedA, speedB := f.actionSpeed(a), f.actionSpeed(b); speedA.Cmp(speedB) != 0 {
if speedA.Cmp(speedB) > 0 {
return a, b
}
return b, a
}
if a.GetActorIndex() != b.GetActorIndex() {
if a.GetActorIndex() < b.GetActorIndex() {
return a, b
}
return b, a
}
return a, b // 速度相同时,发起方优先
}
const maxPendingActionsPerPlayer = 2
func (f *FightC) openActionWindow() {
f.actionMu.Lock()
f.acceptActions = true
@@ -58,16 +73,15 @@ func (f *FightC) submitAction(act action.BattleActionI) {
f.actionMu.Unlock()
return
}
count := 0
replaceIndex := -1
for i, pending := range f.pendingActions {
if pending == nil || pending.GetPlayerID() != act.GetPlayerID() {
if pending == nil || actionSlotKeyFromAction(pending) != actionSlotKeyFromAction(act) {
continue
}
count++
replaceIndex = i
break
}
if count >= maxPendingActionsPerPlayer && replaceIndex >= 0 {
if replaceIndex >= 0 {
f.pendingActions[replaceIndex] = act
} else {
f.pendingActions = append(f.pendingActions, act)
@@ -263,21 +277,51 @@ func (f *FightC) ReadyFight(c common.PlayerI) {
// buildFightStartInfo 构建战斗开始时需要发送给双方的信息
func (f *FightC) buildFightStartInfo() info.FightStartOutboundInfo {
var startInfo info.FightStartOutboundInfo
// 复制双方初始宠物信息(取列表第一个宠物)
if len(f.ReadyInfo.OurPetList) > 0 {
_ = copier.Copy(&startInfo.Info1, &f.ReadyInfo.OurPetList[0])
startInfo.Info1.UserID = f.ReadyInfo.OurInfo.UserID
startInfo := info.FightStartOutboundInfo{}
ourInfos := f.collectFightPetInfos(f.Our)
oppInfos := f.collectFightPetInfos(f.Opp)
startInfo.Infos = append(startInfo.Infos, ourInfos...)
startInfo.Infos = append(startInfo.Infos, oppInfos...)
startInfo.InfoLen = uint32(len(startInfo.Infos))
if len(ourInfos) > 0 {
startInfo.Info1 = ourInfos[0]
}
if len(f.ReadyInfo.OpponentPetList) > 0 {
_ = copier.Copy(&startInfo.Info2, &f.ReadyInfo.OpponentPetList[0])
startInfo.Info2.UserID = f.ReadyInfo.OpponentInfo.UserID
if len(oppInfos) > 0 {
startInfo.Info2 = oppInfos[0]
}
return startInfo
}
func (f *FightC) collectFightPetInfos(inputs []*input.Input) []info.FightPetInfo {
infos := make([]info.FightPetInfo, 0, len(inputs))
for actorIndex, fighter := range inputs {
if fighter == nil || fighter.Player == nil {
continue
}
currentPet := fighter.PrimaryCurPet()
if currentPet == nil {
continue
}
fightInfo := info.FightPetInfo{
UserID: fighter.Player.GetInfo().UserID,
ActorIndex: uint32(actorIndex),
ControllerUserID: currentPet.ControllerUserID,
ID: currentPet.Info.ID,
Name: currentPet.Info.Name,
CatchTime: currentPet.Info.CatchTime,
Hp: currentPet.Info.Hp,
MaxHp: currentPet.Info.MaxHp,
Level: currentPet.Info.Level,
Catchable: uint32(fighter.CanCapture),
}
if fighter.AttackValue != nil {
fightInfo.Prop = fighter.AttackValue.Prop
}
infos = append(infos, fightInfo)
}
return infos
}
// checkBothPlayersReady 检查PVP战斗中双方是否都已准备完成
// 参数c为当前准备的玩家返回true表示双方均准备完成
func (f *FightC) checkBothPlayersReady(currentPlayer common.PlayerI) bool {