1
0
mirror of https://github.com/SquidDev-CC/CC-Tweaked synced 2025-05-28 12:14:12 +00:00

Fix printout crafting

Introduced by the previous commit — I'd made one of the checks too lax.
Add some tests for this, so it doesn't happen again, though this code
does get a complete rewrite in 1.21 anyway >_>.
This commit is contained in:
Jonathan Coates 2025-03-09 12:19:59 +00:00
parent 749b3df227
commit 63ba3fe274
No known key found for this signature in database
GPG Key ID: B9E431FF07C98D06
5 changed files with 96 additions and 13 deletions

View File

@ -58,7 +58,7 @@ public final class PrintoutRecipe extends CustomRecipe {
for (var x = 0; x < inventory.getWidth(); x++) {
var stack = inventory.getItem(x + y * inventory.getWidth());
if (!stack.isEmpty()) {
if (!stack.is(ModRegistry.Items.PRINTED_BOOK.get())) {
if (stack.is(ModRegistry.Items.PRINTED_PAGE.get()) || stack.is(ModRegistry.Items.PRINTED_PAGES.get())) {
if (printouts == null) printouts = new ItemStack[9];
printouts[numPrintouts] = stack;
numPages += PrintoutItem.getPageCount(stack);

View File

@ -27,6 +27,11 @@ public class ItemStackMatcher extends TypeSafeMatcher<ItemStack> {
description.appendValue(stack).appendValue(stack.getTag());
}
@Override
protected void describeMismatchSafely(ItemStack item, Description description) {
description.appendText("was ").appendValue(stack).appendValue(stack.getTag());
}
public static Matcher<ItemStack> isStack(ItemStack stack) {
return new ItemStackMatcher(stack);
}

View File

@ -5,9 +5,17 @@
package dan200.computercraft.gametest
import dan200.computercraft.gametest.api.*
import dan200.computercraft.shared.ModRegistry
import dan200.computercraft.shared.media.items.PrintoutItem
import dan200.computercraft.test.shared.ItemStackMatcher.isStack
import net.minecraft.gametest.framework.GameTest
import net.minecraft.gametest.framework.GameTestGenerator
import net.minecraft.gametest.framework.GameTestHelper
import net.minecraft.gametest.framework.TestFunction
import net.minecraft.world.item.ItemStack
import net.minecraft.world.item.Items
import org.hamcrest.MatcherAssert.assertThat
import org.junit.jupiter.api.Assertions.assertEquals
class Printout_Test {
/**
@ -56,4 +64,52 @@ class Printout_Test {
thenExecute { helper.level.dayTime = Times.NOON }
}
@GameTest(template = "default")
fun Craft_pages(helper: GameTestHelper) = helper.immediate {
// Assert that crafting with only one page fails
helper.assertNotCraftable(ItemStack(ModRegistry.Items.PRINTED_PAGE.get()), ItemStack(Items.STRING))
// Assert that crafting with no pages fails
helper.assertNotCraftable(ItemStack(Items.PAPER), ItemStack(Items.PAPER), ItemStack(Items.STRING))
// Assert that crafting with a book fails
helper.assertNotCraftable(ItemStack(ModRegistry.Items.PRINTED_PAGE.get()), ItemStack(ModRegistry.Items.PRINTED_BOOK.get()), ItemStack(Items.STRING))
assertThat(
helper.craftItem(
PrintoutItem.createSingleFromTitleAndText("First", createPagesOf(' '), createPagesOf('b')),
PrintoutItem.createMultipleFromTitleAndText("Second", createPagesOf(' '), createPagesOf('b')),
ItemStack(Items.STRING),
),
isStack(PrintoutItem.createMultipleFromTitleAndText("First", createPagesOf(' ', 2), createPagesOf('b', 2))),
)
}
@GameTest(template = "default")
fun Craft_book(helper: GameTestHelper) = helper.immediate {
// Assert that crafting with no pages fails
helper.assertNotCraftable(ItemStack(Items.PAPER), ItemStack(Items.PAPER), ItemStack(Items.STRING), ItemStack(Items.LEATHER))
// Assert that crafting with only one page works
assertEquals(
ModRegistry.Items.PRINTED_BOOK.get(),
helper.craftItem(ItemStack(ModRegistry.Items.PRINTED_PAGE.get()), ItemStack(Items.STRING), ItemStack(Items.LEATHER)).item,
)
assertThat(
helper.craftItem(
PrintoutItem.createSingleFromTitleAndText("First", createPagesOf(' '), createPagesOf('b')),
PrintoutItem.createMultipleFromTitleAndText("Second", createPagesOf(' '), createPagesOf('b')),
ItemStack(Items.STRING),
ItemStack(Items.LEATHER),
),
isStack(PrintoutItem.createBookFromTitleAndText("First", createPagesOf(' ', 2), createPagesOf('b', 2))),
)
}
private fun createPagesOf(c: Char, pages: Int = 1): Array<String> {
val line = c.toString().repeat(PrintoutItem.LINE_MAX_LENGTH)
return Array(PrintoutItem.LINES_PER_PAGE * pages) { line }
}
}

View File

@ -6,20 +6,18 @@ package dan200.computercraft.gametest
import com.mojang.authlib.GameProfile
import dan200.computercraft.gametest.api.Structures
import dan200.computercraft.gametest.api.craftItem
import dan200.computercraft.gametest.api.sequence
import dan200.computercraft.shared.ModRegistry
import net.minecraft.gametest.framework.GameTest
import net.minecraft.gametest.framework.GameTestAssertException
import net.minecraft.gametest.framework.GameTestHelper
import net.minecraft.nbt.CompoundTag
import net.minecraft.nbt.NbtUtils
import net.minecraft.world.entity.player.Player
import net.minecraft.world.inventory.AbstractContainerMenu
import net.minecraft.world.inventory.MenuType
import net.minecraft.world.inventory.TransientCraftingContainer
import net.minecraft.world.item.ItemStack
import net.minecraft.world.item.Items
import net.minecraft.world.item.crafting.RecipeType
import org.junit.jupiter.api.Assertions.assertEquals
import java.util.*
@ -32,15 +30,10 @@ class Recipe_Test {
@GameTest(template = Structures.DEFAULT)
fun Craft_result_has_nbt(context: GameTestHelper) = context.sequence {
thenExecute {
val container = TransientCraftingContainer(DummyMenu, 3, 3)
container.setItem(0, ItemStack(Items.SKELETON_SKULL))
container.setItem(1, ItemStack(ModRegistry.Items.COMPUTER_ADVANCED.get()))
val recipe = context.level.server.recipeManager
.getRecipeFor(RecipeType.CRAFTING, container, context.level)
.orElseThrow { GameTestAssertException("No recipe matches") }
val result = recipe.assemble(container, context.level.registryAccess())
val result = context.craftItem(
ItemStack(Items.SKELETON_SKULL),
ItemStack(ModRegistry.Items.COMPUTER_ADVANCED.get()),
)
val profile = GameProfile(UUID.fromString("f3c8d69b-0776-4512-8434-d1b2165909eb"), "dan200")

View File

@ -5,6 +5,7 @@
package dan200.computercraft.gametest.api
import dan200.computercraft.api.peripheral.IPeripheral
import dan200.computercraft.gametest.Recipe_Test.DummyMenu
import dan200.computercraft.gametest.core.ManagedComputers
import dan200.computercraft.mixin.gametest.GameTestHelperAccessor
import dan200.computercraft.mixin.gametest.GameTestInfoAccessor
@ -22,9 +23,11 @@ import net.minecraft.world.Container
import net.minecraft.world.InteractionHand
import net.minecraft.world.entity.Entity
import net.minecraft.world.entity.EntityType
import net.minecraft.world.inventory.TransientCraftingContainer
import net.minecraft.world.item.Item
import net.minecraft.world.item.ItemStack
import net.minecraft.world.item.context.UseOnContext
import net.minecraft.world.item.crafting.RecipeType
import net.minecraft.world.level.block.Blocks
import net.minecraft.world.level.block.entity.BarrelBlockEntity
import net.minecraft.world.level.block.entity.BlockEntity
@ -343,6 +346,32 @@ fun GameTestHelper.placeItemAt(stack: ItemStack, pos: BlockPos, direction: Direc
stack.useOn(UseOnContext(player, InteractionHand.MAIN_HAND, hit))
}
/**
* Assert a recipe is not craftable.
*/
fun GameTestHelper.assertNotCraftable(vararg items: ItemStack) {
val container = TransientCraftingContainer(DummyMenu, 3, 3)
for ((i, item) in items.withIndex()) container.setItem(i, item)
val recipe = level.server.recipeManager.getRecipeFor(RecipeType.CRAFTING, container, level)
if (recipe.isPresent) fail("Expected no recipe to match $items")
}
/**
* Attempt to craft an item.
*/
fun GameTestHelper.craftItem(vararg items: ItemStack): ItemStack {
val container = TransientCraftingContainer(DummyMenu, 3, 3)
for ((i, item) in items.withIndex()) container.setItem(i, item)
val recipe = level.server.recipeManager
.getRecipeFor(RecipeType.CRAFTING, container, level)
.orElseThrow { GameTestAssertException("No recipe matches $items") }
return recipe.assemble(container, level.registryAccess())
}
/**
* Run a function multiple times until it succeeds.
*/