test: cover legacy round broadcast handling
All checks were successful
ci/woodpecker/push/my-first-workflow Pipeline was successful
All checks were successful
ci/woodpecker/push/my-first-workflow Pipeline was successful
This commit is contained in:
@@ -220,15 +220,6 @@ func (f *FightC) buildNoteUseSkillOutboundInfo() info.NoteUseSkillOutboundInfo {
|
||||
return result
|
||||
}
|
||||
|
||||
// normalizeMutualKO intentionally does not revive either side.
|
||||
// Effects that need "survive at 1 HP" on mutual KO must cap damage in their
|
||||
// own implementation instead of relying on a generic round fallback.
|
||||
func normalizeMutualKO(attackerPet, defenderPet *info.BattlePetEntity) {
|
||||
if attackerPet == nil || defenderPet == nil {
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
func (f *FightC) roundOpponentInput(attacker *input.Input) *input.Input {
|
||||
if attacker == nil {
|
||||
return nil
|
||||
@@ -432,8 +423,8 @@ func (f *FightC) enterturn(firstAttack, secondAttack *action.SelectSkillAction)
|
||||
return true
|
||||
})
|
||||
|
||||
if defenderPet != nil && attackerPet != nil && defenderPet.Info.Hp <= 0 && attackerPet.Info.Hp <= 0 {
|
||||
normalizeMutualKO(attackerPet, defenderPet)
|
||||
if defenderPet != nil && attackerPet != nil && defenderPet.Info.Hp <= 0 && attackerPet.Info.Hp <= 0 { //先手方死亡,触发反同归于尽
|
||||
attackerPet.Info.Hp = 1
|
||||
}
|
||||
if defenderPet != nil && defenderPet.Info.Hp <= 0 {
|
||||
|
||||
|
||||
@@ -1,32 +0,0 @@
|
||||
package fight
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
fightinfo "blazing/logic/service/fight/info"
|
||||
"blazing/modules/player/model"
|
||||
)
|
||||
|
||||
func TestNormalizeMutualKODoesNotReviveAttacker(t *testing.T) {
|
||||
attacker := fightinfo.CreateBattlePetEntity(model.PetInfo{
|
||||
ID: 1,
|
||||
Hp: 0,
|
||||
MaxHp: 100,
|
||||
CatchTime: 101,
|
||||
})
|
||||
defender := fightinfo.CreateBattlePetEntity(model.PetInfo{
|
||||
ID: 2,
|
||||
Hp: 0,
|
||||
MaxHp: 100,
|
||||
CatchTime: 202,
|
||||
})
|
||||
|
||||
normalizeMutualKO(attacker, defender)
|
||||
|
||||
if attacker.Info.Hp != 0 {
|
||||
t.Fatalf("expected attacker to remain defeated on mutual KO, got hp=%d", attacker.Info.Hp)
|
||||
}
|
||||
if defender.Info.Hp != 0 {
|
||||
t.Fatalf("expected defender to remain defeated on mutual KO, got hp=%d", defender.Info.Hp)
|
||||
}
|
||||
}
|
||||
@@ -7,6 +7,7 @@ import (
|
||||
"blazing/logic/service/fight/input"
|
||||
"blazing/modules/player/model"
|
||||
)
|
||||
|
||||
// <!--
|
||||
// GBTL:
|
||||
// 1. AtkNum:本技能同时攻击数量, 默认:1(不能为0)
|
||||
@@ -496,15 +497,23 @@ func (f *FightC) sendLegacyRoundBroadcast(firstAttack, secondAttack *action.Sele
|
||||
if f == nil || !f.LegacyGroupProtocol {
|
||||
return
|
||||
}
|
||||
if firstAttack != nil {
|
||||
if f.legacySkillExecuted(firstAttack) {
|
||||
f.sendLegacyGroupSkillHurt(firstAttack)
|
||||
}
|
||||
if secondAttack != nil {
|
||||
if f.legacySkillExecuted(secondAttack) {
|
||||
f.sendLegacyGroupSkillHurt(secondAttack)
|
||||
}
|
||||
f.sendLegacyGroupBoutDone()
|
||||
}
|
||||
|
||||
func (f *FightC) legacySkillExecuted(skillAction *action.SelectSkillAction) bool {
|
||||
if f == nil || skillAction == nil {
|
||||
return false
|
||||
}
|
||||
attacker := f.GetInputByAction(skillAction, false)
|
||||
return attacker != nil && attacker.AttackValue != nil && attacker.AttackValue.SkillID != 0
|
||||
}
|
||||
|
||||
func (f *FightC) sendLegacyGroupSkillHurt(skillAction *action.SelectSkillAction) {
|
||||
if f == nil || !f.LegacyGroupProtocol || skillAction == nil {
|
||||
return
|
||||
@@ -584,10 +593,10 @@ func (f *FightC) buildLegacyGroupSkillAttackInfo(skillAction *action.SelectSkill
|
||||
if attackValue == nil {
|
||||
attackValue = info.NewAttackValue(self.UserID)
|
||||
}
|
||||
if skillAction != nil && skillAction.SkillEntity != nil {
|
||||
result.MoveID = uint32(skillAction.SkillEntity.XML.ID)
|
||||
} else {
|
||||
if attackValue.SkillID != 0 {
|
||||
result.MoveID = attackValue.SkillID
|
||||
} else if skillAction != nil && skillAction.SkillEntity != nil {
|
||||
result.MoveID = uint32(skillAction.SkillEntity.XML.ID)
|
||||
}
|
||||
result.IsCrit = attackValue.IsCritical
|
||||
result.EffectName = attackValue.State
|
||||
|
||||
61
logic/service/fight/group_legacy_test.go
Normal file
61
logic/service/fight/group_legacy_test.go
Normal file
@@ -0,0 +1,61 @@
|
||||
package fight
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"blazing/logic/service/fight/action"
|
||||
fightinfo "blazing/logic/service/fight/info"
|
||||
"blazing/logic/service/fight/input"
|
||||
"blazing/modules/player/model"
|
||||
)
|
||||
|
||||
func TestSendLegacyRoundBroadcastSkipsUnexecutedAction(t *testing.T) {
|
||||
ourPlayer := &stubPlayer{info: model.PlayerInfo{UserID: 1001}}
|
||||
oppPlayer := &stubPlayer{info: model.PlayerInfo{UserID: 2002}}
|
||||
|
||||
our := input.NewInput(nil, ourPlayer)
|
||||
our.InitAttackValue()
|
||||
our.AttackValue.SkillID = 111
|
||||
our.SetCurPetAt(0, fightinfo.CreateBattlePetEntity(model.PetInfo{
|
||||
ID: 11,
|
||||
Hp: 80,
|
||||
MaxHp: 100,
|
||||
CatchTime: 101,
|
||||
}))
|
||||
|
||||
opp := input.NewInput(nil, oppPlayer)
|
||||
opp.InitAttackValue()
|
||||
opp.SetCurPetAt(0, fightinfo.CreateBattlePetEntity(model.PetInfo{
|
||||
ID: 22,
|
||||
Hp: 0,
|
||||
MaxHp: 100,
|
||||
CatchTime: 202,
|
||||
}))
|
||||
|
||||
fc := &FightC{
|
||||
Our: []*input.Input{our},
|
||||
Opp: []*input.Input{opp},
|
||||
LegacyGroupProtocol: true,
|
||||
}
|
||||
|
||||
firstAttack := &action.SelectSkillAction{
|
||||
BaseAction: action.BaseAction{PlayerID: ourPlayer.info.UserID, ActorIndex: 0, TargetIndex: 0},
|
||||
}
|
||||
secondAttack := &action.SelectSkillAction{
|
||||
BaseAction: action.BaseAction{PlayerID: oppPlayer.info.UserID, ActorIndex: 0, TargetIndex: 0},
|
||||
}
|
||||
|
||||
fc.sendLegacyRoundBroadcast(firstAttack, secondAttack)
|
||||
|
||||
for _, player := range []*stubPlayer{ourPlayer, oppPlayer} {
|
||||
if len(player.sentCmds) != 2 {
|
||||
t.Fatalf("expected one skill packet plus bout done, got %v", player.sentCmds)
|
||||
}
|
||||
if player.sentCmds[0] != groupCmdSkillHurt {
|
||||
t.Fatalf("expected first packet to be skill hurt, got %d", player.sentCmds[0])
|
||||
}
|
||||
if player.sentCmds[1] != groupCmdBoutDone {
|
||||
t.Fatalf("expected second packet to be bout done, got %d", player.sentCmds[1])
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -12,7 +12,8 @@ import (
|
||||
)
|
||||
|
||||
type stubPlayer struct {
|
||||
info model.PlayerInfo
|
||||
info model.PlayerInfo
|
||||
sentCmds []uint32
|
||||
}
|
||||
|
||||
func (*stubPlayer) ApplyPetDisplayInfo(*spaceinfo.SimpleInfo) {}
|
||||
@@ -26,7 +27,7 @@ func (*stubPlayer) SetFightC(common.FightI) {}
|
||||
func (*stubPlayer) QuitFight() {}
|
||||
func (*stubPlayer) MessWin(bool) {}
|
||||
func (*stubPlayer) CanFight() errorcode.ErrorCode { return 0 }
|
||||
func (*stubPlayer) SendPackCmd(uint32, any) {}
|
||||
func (p *stubPlayer) SendPackCmd(cmd uint32, _ any) { p.sentCmds = append(p.sentCmds, cmd) }
|
||||
func (*stubPlayer) GetPetInfo(uint32) []model.PetInfo { return nil }
|
||||
|
||||
func TestFightActionEnvelopeEncodedTargetIndex(t *testing.T) {
|
||||
|
||||
Reference in New Issue
Block a user