diff --git a/logic/controller/item_use_test.go b/logic/controller/item_use_test.go index 38407443..5acfd0a4 100644 --- a/logic/controller/item_use_test.go +++ b/logic/controller/item_use_test.go @@ -46,6 +46,50 @@ func TestUsePetItemOutOfFightAppliesToBackupPetInMemory(t *testing.T) { } } +func TestUsePetItemOutOfFightPersistsEnergyOrbEffectInfo(t *testing.T) { + petID := firstPetIDForControllerTest(t) + petInfo := playermodel.GenPetInfo(petID, 31, 0, 0, 50, nil, 0) + if petInfo == nil { + t.Fatal("failed to generate test pet") + } + + testPlayer := player.NewPlayer(nil) + testPlayer.Info = &playermodel.PlayerInfo{ + UserID: 10001, + PetList: []playermodel.PetInfo{*petInfo}, + } + testPlayer.Service = blservice.NewUserService(testPlayer.Info.UserID) + + itemID, effectCfg := firstEnergyOrbItemForControllerTest(t) + if err := testPlayer.Service.Item.UPDATE(itemID, 1); err != nil { + t.Fatalf("failed to seed energy orb item %d: %v", itemID, err) + } + + _, err := (Controller{}).UsePetItemOutOfFight(&C2S_USE_PET_ITEM_OUT_OF_FIGHT{ + CatchTime: petInfo.CatchTime, + ItemID: int32(itemID), + }, testPlayer) + if err != 0 { + t.Fatalf("expected energy orb use to succeed, got err=%d", err) + } + + storedPet := testPlayer.Info.PetList[0] + if len(storedPet.EffectInfo) == 0 { + t.Fatalf("expected pet effect info to persist after using item %d", itemID) + } + + last := storedPet.EffectInfo[len(storedPet.EffectInfo)-1] + if last.ItemID != itemID { + t.Fatalf("expected stored item id %d, got %d", itemID, last.ItemID) + } + if last.Status != 2 { + t.Fatalf("expected energy orb status 2, got %d", last.Status) + } + if last.EID != uint16(atoiOrZero(effectCfg.Eid)) { + t.Fatalf("expected effect id %s, got %d", effectCfg.Eid, last.EID) + } +} + func firstRecoverHPItemForControllerTest(t *testing.T) (uint32, int) { t.Helper() @@ -58,3 +102,36 @@ func firstRecoverHPItemForControllerTest(t *testing.T) (uint32, int) { t.Fatal("xmlres.ItemsMAP has no HP recovery item") return 0, 0 } + +func firstEnergyOrbItemForControllerTest(t *testing.T) (uint32, xmlres.NewSeIdx) { + t.Helper() + + for id, itemCfg := range xmlres.ItemsMAP { + if itemCfg.NewSeIdx == 0 { + continue + } + + effectCfg, ok := xmlres.EffectMAP[itemCfg.NewSeIdx] + if !ok { + continue + } + + if effectCfg.Stat == "2" && effectCfg.ItemId != nil { + return uint32(id), effectCfg + } + } + + t.Fatal("xmlres.ItemsMAP has no energy orb item") + return 0, xmlres.NewSeIdx{} +} + +func atoiOrZero(value string) int { + result := 0 + for _, ch := range value { + if ch < '0' || ch > '9' { + return result + } + result = result*10 + int(ch-'0') + } + return result +} diff --git a/logic/service/item/petuse.go b/logic/service/item/petuse.go index 79cc0c27..572950df 100644 --- a/logic/service/item/petuse.go +++ b/logic/service/item/petuse.go @@ -27,6 +27,17 @@ type SetHandler struct { Handler PetItemHandler } +var energyOrbItemIDs = []uint32{ + 300030, 300031, 300032, 300033, 300034, + 300045, 300046, 300047, 300048, 300049, 300050, + 300055, 300056, 300057, 300058, 300059, 300060, 300061, 300064, + 300102, 300103, 300106, 300107, + 300121, 300125, 300126, + 300130, 300131, 300132, 300133, 300134, 300135, 300139, + 300601, 300606, 300607, 300608, 300609, + 300663, 300741, 300854, +} + var fallbackPetItemNewSeIdx = map[uint32]int{ 300741: 1103, // 瞬杀能量珠 300854: 1103, // 瞬杀能量珠Ω @@ -235,6 +246,10 @@ func init() { //特判转换 PetItemRegistry.RegisterSet([]uint32{300119, 300120}, nvfunc) + PetItemRegistry.RegisterSet(energyOrbItemIDs, func(itemid uint32, onpet *model.PetInfo) bool { + return handleNewSeIdxPetItem(itemid, onpet) == 0 + }) + PetItemRegistry.RegisterExact(300790, func(itemid uint32, onpet *model.PetInfo) bool { if onpet.Dv >= 31 { return false