From e161e3626fc927bd832491ac60caaf128bebf363 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=98=94=E5=BF=B5?= <12574910+72wo@users.noreply.github.com> Date: Mon, 13 Apr 2026 09:59:09 +0800 Subject: [PATCH] =?UTF-8?q?```=20fix(fight):=20=E4=BF=AE=E5=A4=8D=E5=8D=95?= =?UTF-8?q?=E8=BE=93=E5=85=A5=E6=88=98=E6=96=97=E4=B8=AD=E6=95=88=E6=9E=9C?= =?UTF-8?q?=E5=A4=84=E7=90=86=E9=80=BB=E8=BE=91=E9=94=99=E8=AF=AF?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 在Effect201的OnSkill方法中调整了多输入战斗检查的位置, 确保单输入战斗中的单目标效果被正确忽略 - 添加了针对单输入战斗中单目标效果的测试用例 - 移除了重复的多输入战斗检查代码 feat(fight): 添加战斗初始化时捕获标识 --- logic/service/fight/effect/none.go | 8 ++-- logic/service/fight/effect/none_test.go | 21 +++++++++++ logic/service/fight/input.go | 3 ++ logic/service/fight/new.go | 6 +-- logic/service/player/Monster.go | 3 ++ logic/service/player/Monster_test.go | 49 +++++++++++++++++++++++++ modules/player/model/pvp.go | 1 + 7 files changed, 84 insertions(+), 7 deletions(-) create mode 100644 logic/service/player/Monster_test.go diff --git a/logic/service/fight/effect/none.go b/logic/service/fight/effect/none.go index 75cc909be..7eb66c3da 100644 --- a/logic/service/fight/effect/none.go +++ b/logic/service/fight/effect/none.go @@ -83,6 +83,10 @@ func (e *Effect201) OnSkill() bool { return true } + if !carrier.IsMultiInputBattle() { + return true + } + divisorIndex := len(args) - 1 if len(args) > 1 { divisorIndex = 1 @@ -110,10 +114,6 @@ func (e *Effect201) OnSkill() bool { return true } - if !carrier.IsMultiInputBattle() { - return true - } - team := carrier.Team if len(team) == 0 { team = []*input.Input{carrier} diff --git a/logic/service/fight/effect/none_test.go b/logic/service/fight/effect/none_test.go index bd5fab3f4..fb699e3d8 100644 --- a/logic/service/fight/effect/none_test.go +++ b/logic/service/fight/effect/none_test.go @@ -42,6 +42,27 @@ func TestEffect201HealAllIgnoredInSingleInputBattle(t *testing.T) { } } +func TestEffect201SingleTargetIgnoredInSingleInputBattle(t *testing.T) { + carrier := newEffect201TestInput(40, 100) + opponent := newEffect201TestInput(60, 100) + carrier.Team = []*input.Input{carrier} + carrier.OppTeam = []*input.Input{opponent} + + eff := &Effect201{} + eff.SetArgs(carrier, 2) + eff.EffectNode.EffectContextHolder.Ctx = input.Ctx{ + LegacySides: input.LegacySides{Our: carrier, Opp: opponent}, + EffectBinding: input.EffectBinding{Carrier: carrier, Source: carrier}, + } + + if !eff.OnSkill() { + t.Fatalf("expected effect to finish successfully") + } + if got := carrier.CurrentPet().Info.Hp; got != 40 { + t.Fatalf("expected single-input single-target heal to be ignored, got hp %d", got) + } +} + func TestEffect201HealAllWorksInMultiInputBattle(t *testing.T) { carrier := newEffect201TestInput(40, 100) ally := newEffect201TestInput(10, 80) diff --git a/logic/service/fight/input.go b/logic/service/fight/input.go index 88e167564..97a0c033e 100644 --- a/logic/service/fight/input.go +++ b/logic/service/fight/input.go @@ -484,6 +484,9 @@ func initfightready(in *input.Input) (model.FightUserInfo, []model.ReadyFightPet if err != nil { panic(err) } + if i == 0 && in.CanCapture > 0 { + t[i].IsCapture = uint32(in.CanCapture) + } } return userindo, t diff --git a/logic/service/fight/new.go b/logic/service/fight/new.go index ec6885663..22fd85c11 100644 --- a/logic/service/fight/new.go +++ b/logic/service/fight/new.go @@ -297,9 +297,6 @@ func buildFight(opts *fightBuildOptions) (*FightC, errorcode.ErrorCode) { f.bindInputFightContext(f.Our, f.Opp) f.linkTeamViews() - f.ReadyInfo.OurInfo, f.ReadyInfo.OurPetList = initfightready(f.primaryOur()) - f.ReadyInfo.OpponentInfo, f.ReadyInfo.OpponentPetList = initfightready(f.primaryOpp()) - loadtime := 120 * time.Second if f.Info.Status == info.BattleMode.FIGHT_WITH_NPC { if opp := f.primaryOpp(); opp != nil { @@ -313,6 +310,9 @@ func buildFight(opts *fightBuildOptions) (*FightC, errorcode.ErrorCode) { } } } + + f.ReadyInfo.OurInfo, f.ReadyInfo.OurPetList = initfightready(f.primaryOur()) + f.ReadyInfo.OpponentInfo, f.ReadyInfo.OpponentPetList = initfightready(f.primaryOpp()) f.FightStartOutboundInfo = f.buildFightStartInfo() f.BroadcastPlayers(func(p common.PlayerI) { diff --git a/logic/service/player/Monster.go b/logic/service/player/Monster.go index c5f779d57..56802a1e0 100644 --- a/logic/service/player/Monster.go +++ b/logic/service/player/Monster.go @@ -51,6 +51,9 @@ func (p *Player) IsMatch(t configmodel.Event) bool { if len(p.Info.PetList) == 0 { return false } + if p.Info.PetList[0].Hp == 0 { + return false + } firstPetID := int32(p.Info.PetList[0].ID) _, ok := lo.Find(t.FirstSprites, func(item int32) bool { diff --git a/logic/service/player/Monster_test.go b/logic/service/player/Monster_test.go new file mode 100644 index 000000000..052ce7237 --- /dev/null +++ b/logic/service/player/Monster_test.go @@ -0,0 +1,49 @@ +package player + +import ( + configmodel "blazing/modules/config/model" + playermodel "blazing/modules/player/model" + "testing" +) + +func TestIsMatchFirstSpritesRequiresLivingLeadPet(t *testing.T) { + player := &Player{ + baseplayer: baseplayer{ + Info: &playermodel.PlayerInfo{ + PetList: []playermodel.PetInfo{ + {ID: 1001, Hp: 0}, + {ID: 2002, Hp: 100}, + }, + }, + }, + } + + event := configmodel.Event{ + FirstSprites: []int32{1001}, + } + + if player.IsMatch(event) { + t.Fatalf("expected dead lead pet to fail FirstSprites match") + } +} + +func TestIsMatchFirstSpritesAcceptsLivingLeadPet(t *testing.T) { + player := &Player{ + baseplayer: baseplayer{ + Info: &playermodel.PlayerInfo{ + PetList: []playermodel.PetInfo{ + {ID: 1001, Hp: 100}, + {ID: 2002, Hp: 100}, + }, + }, + }, + } + + event := configmodel.Event{ + FirstSprites: []int32{1001}, + } + + if !player.IsMatch(event) { + t.Fatalf("expected living lead pet to pass FirstSprites match") + } +} diff --git a/modules/player/model/pvp.go b/modules/player/model/pvp.go index 78250cfba..bbf86649a 100644 --- a/modules/player/model/pvp.go +++ b/modules/player/model/pvp.go @@ -119,6 +119,7 @@ type ReadyFightPetInfo struct { SkinID uint32 `fieldDesc:"精灵皮肤ID" ` ShinyLen uint32 `json:"-" struc:"sizeof=ShinyInfo"` ShinyInfo []data.GlowFilter `json:"ShinyInfo,omitempty"` + IsCapture uint32 `json:"isCapture"` } type FightOverInfo struct { //0 正常结束