package game // Regression: the multi-match production menu (craft /mix/construct) // must pass the real lowercase recipe type as PendingSkill. It previously // passed the capitalised display label ("Crafting"), which // handleProductChoice looks up with player.SkillName — a map miss that // resolves to level 1, so every recipe above level 1 was refused even for a // level-50 crafter. import ( "testing" "thehouseoficarus/internal/net" "thehouseoficarus/internal/player" ) const craftMenuIngotYAML = `id: test_ingot name: test ingot stackable: true value: 1 ` const craftMenuSwordYAML = `id: test_iron_sword name: iron sword stackable: false value: 5 craft: - type: crafting ingredients: - items: - test_ingot quantity: 1 level: 1 output_qty: 1 ` const craftMenuPlateYAML = `id: test_iron_plate name: iron plate stackable: false value: 50 craft: - type: crafting ingredients: - items: - test_ingot quantity: 1 level: 40 output_qty: 1 ` func TestCraftMenuResolvesRealSkillForMultiMatch(t *testing.T) { dir := t.TempDir() seedWorld(t, dir) writeDataFile(t, dir, "items", "test_ingot.yaml", craftMenuIngotYAML) writeDataFile(t, dir, "items", "test_iron_sword.yaml", craftMenuSwordYAML) writeDataFile(t, dir, "items", "test_iron_plate.yaml", craftMenuPlateYAML) g := newHardeningGame(t, dir) g.RunOnOwner(func() { p := player.New("alice") p.RoomID = 1 p.Skills[player.Crafting] = player.XPForLevel(50) p.SetInvSlot(0, &player.InventorySlot{ItemID: "test_ingot", Quantity: 1}) conn := newChanConn() sess := &net.Session{Conn: conn, Player: p} sess.SetState(net.StateGame) // "iron" matches both products, forcing the multi-match menu path. g.doCraft(sess, "iron") if sess.PendingSkill != "crafting" { t.Fatalf("PendingSkill = %q, want %q (a display label is not a skill)", sess.PendingSkill, "crafting") } if len(sess.PendingMenu) != 2 { t.Fatalf("menu entries = %d, want 2 (iron sword, iron plate)", len(sess.PendingMenu)) } // Choice 2 is iron plate (level 40, the only row above level 1). g.handleProductChoice(sess, "2") if p.Action == nil { t.Fatalf("level-50 crafter could not start the level-40 recipe; output=%q", conn.Bytes()) } if p.Action.TargetID != "test_iron_plate" { t.Fatalf("started recipe %q, want test_iron_plate; output=%q", p.Action.TargetID, conn.Bytes()) } }) }