refactor: 重构战斗系统支持多单位多动作
This commit is contained in:
@@ -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 {
|
||||
|
||||
Reference in New Issue
Block a user