1
0
mirror of https://github.com/SquidDev-CC/CC-Tweaked synced 2025-10-22 09:27:39 +00:00

Add a test for exploding turtles

There's been a couple of bug reports in the past where the game would
crash if a turtle is destroyed while breaking a block (typically due to
the block exploding). This commit adds a test, to ensure that this is
handled gracefully.

I'm not entirely sure this is testing the right thing. Looking at the
issues in question, it doesn't look like I ever managed to reproduce the
bug. However, it's hopefully at least a quick sanity test to check we
never break this case.
This commit is contained in:
Jonathan Coates
2024-08-14 22:41:31 +01:00
parent bb97c465d9
commit 87dfad026e
5 changed files with 185 additions and 0 deletions

View File

@@ -693,6 +693,20 @@ class Turtle_Test {
}
}
/**
* Tests a turtle can break a block that explodes, causing the turtle itself to explode.
*
* This attempts to test [#585](https://github.com/cc-tweaked/CC-Tweaked/issues/585) and other similar issues. It's
* not clear if this is a good test case, as that bug does not seem reliably reproducible, but it's at least a good
* sanity check.
*/
@GameTest
fun Breaks_exploding_block(context: GameTestHelper) = context.sequence {
thenOnComputer { turtle.dig(Optional.empty()) }
thenIdle(2)
thenExecute { context.assertItemEntityPresent(ModRegistry.Items.TURTLE_NORMAL.get(), BlockPos(2, 2, 2), 1.0) }
}
/**
* Render turtles as an item.
*/

View File

@@ -13,7 +13,13 @@ import dan200.computercraft.shared.computer.core.ServerContext
import net.minecraft.core.BlockPos
import net.minecraft.gametest.framework.*
import net.minecraft.server.MinecraftServer
import net.minecraft.server.level.ServerLevel
import net.minecraft.world.level.GameRules
import net.minecraft.world.level.Level
import net.minecraft.world.level.LevelAccessor
import net.minecraft.world.level.block.Blocks
import net.minecraft.world.level.block.state.BlockState
import net.minecraft.world.phys.Vec3
import org.slf4j.Logger
import org.slf4j.LoggerFactory
import java.io.File
@@ -173,4 +179,23 @@ object TestHooks {
throw RuntimeException(e)
}
}
/**
* Adds a hook that makes breaking a bone block spawn an explosion.
*
* It would be more Correct to register a custom block, but that's quite a lot of work, and doesn't seem worth it
* for test code.
*
* See also [Turtle_Test.Breaks_exploding_block].
*/
@JvmStatic
fun onBeforeDestroyBlock(level: LevelAccessor, pos: BlockPos, state: BlockState): Boolean {
if (state.block === Blocks.BONE_BLOCK && level is ServerLevel) {
val explosionPos = Vec3.atCenterOf(pos)
level.explode(null, explosionPos.x, explosionPos.y, explosionPos.z, 4.0f, Level.ExplosionInteraction.TNT)
return true
}
return false
}
}

View File

@@ -0,0 +1,139 @@
{
DataVersion: 3465,
size: [5, 5, 5],
data: [
{pos: [0, 0, 0], state: "minecraft:obsidian"},
{pos: [0, 0, 1], state: "minecraft:obsidian"},
{pos: [0, 0, 2], state: "minecraft:obsidian"},
{pos: [0, 0, 3], state: "minecraft:obsidian"},
{pos: [0, 0, 4], state: "minecraft:obsidian"},
{pos: [1, 0, 0], state: "minecraft:obsidian"},
{pos: [1, 0, 1], state: "minecraft:obsidian"},
{pos: [1, 0, 2], state: "minecraft:obsidian"},
{pos: [1, 0, 3], state: "minecraft:obsidian"},
{pos: [1, 0, 4], state: "minecraft:obsidian"},
{pos: [2, 0, 0], state: "minecraft:obsidian"},
{pos: [2, 0, 1], state: "minecraft:obsidian"},
{pos: [2, 0, 2], state: "minecraft:obsidian"},
{pos: [2, 0, 3], state: "minecraft:obsidian"},
{pos: [2, 0, 4], state: "minecraft:obsidian"},
{pos: [3, 0, 0], state: "minecraft:obsidian"},
{pos: [3, 0, 1], state: "minecraft:obsidian"},
{pos: [3, 0, 2], state: "minecraft:obsidian"},
{pos: [3, 0, 3], state: "minecraft:obsidian"},
{pos: [3, 0, 4], state: "minecraft:obsidian"},
{pos: [4, 0, 0], state: "minecraft:obsidian"},
{pos: [4, 0, 1], state: "minecraft:obsidian"},
{pos: [4, 0, 2], state: "minecraft:obsidian"},
{pos: [4, 0, 3], state: "minecraft:obsidian"},
{pos: [4, 0, 4], state: "minecraft:obsidian"},
{pos: [0, 1, 0], state: "minecraft:barrier"},
{pos: [0, 1, 1], state: "minecraft:barrier"},
{pos: [0, 1, 2], state: "minecraft:barrier"},
{pos: [0, 1, 3], state: "minecraft:barrier"},
{pos: [0, 1, 4], state: "minecraft:barrier"},
{pos: [1, 1, 0], state: "minecraft:barrier"},
{pos: [1, 1, 1], state: "minecraft:air"},
{pos: [1, 1, 2], state: "minecraft:air"},
{pos: [1, 1, 3], state: "minecraft:air"},
{pos: [1, 1, 4], state: "minecraft:barrier"},
{pos: [2, 1, 0], state: "minecraft:barrier"},
{pos: [2, 1, 1], state: "minecraft:air"},
{pos: [2, 1, 2], state: "computercraft:turtle_normal{facing:south,waterlogged:false}", nbt: {ComputerId: 1, Fuel: 0, Items: [], Label: "turtle_test.breaks_exploding_block", LeftUpgrade: "minecraft:diamond_pickaxe", LeftUpgradeNbt: {Tag: {Damage: 0}}, On: 1b, Owner: {LowerId: -5670393268852517359L, Name: "Player172", UpperId: 3578583684139923613L}, Slot: 0, id: "computercraft:turtle_normal"}},
{pos: [2, 1, 3], state: "minecraft:bone_block{axis:y}"},
{pos: [2, 1, 4], state: "minecraft:barrier"},
{pos: [3, 1, 0], state: "minecraft:barrier"},
{pos: [3, 1, 1], state: "minecraft:air"},
{pos: [3, 1, 2], state: "minecraft:air"},
{pos: [3, 1, 3], state: "minecraft:air"},
{pos: [3, 1, 4], state: "minecraft:barrier"},
{pos: [4, 1, 0], state: "minecraft:barrier"},
{pos: [4, 1, 1], state: "minecraft:barrier"},
{pos: [4, 1, 2], state: "minecraft:barrier"},
{pos: [4, 1, 3], state: "minecraft:barrier"},
{pos: [4, 1, 4], state: "minecraft:barrier"},
{pos: [0, 2, 0], state: "minecraft:barrier"},
{pos: [0, 2, 1], state: "minecraft:barrier"},
{pos: [0, 2, 2], state: "minecraft:air"},
{pos: [0, 2, 3], state: "minecraft:barrier"},
{pos: [0, 2, 4], state: "minecraft:barrier"},
{pos: [1, 2, 0], state: "minecraft:barrier"},
{pos: [1, 2, 1], state: "minecraft:air"},
{pos: [1, 2, 2], state: "minecraft:air"},
{pos: [1, 2, 3], state: "minecraft:air"},
{pos: [1, 2, 4], state: "minecraft:barrier"},
{pos: [2, 2, 0], state: "minecraft:barrier"},
{pos: [2, 2, 1], state: "minecraft:air"},
{pos: [2, 2, 2], state: "minecraft:air"},
{pos: [2, 2, 3], state: "minecraft:air"},
{pos: [2, 2, 4], state: "minecraft:barrier"},
{pos: [3, 2, 0], state: "minecraft:barrier"},
{pos: [3, 2, 1], state: "minecraft:air"},
{pos: [3, 2, 2], state: "minecraft:air"},
{pos: [3, 2, 3], state: "minecraft:air"},
{pos: [3, 2, 4], state: "minecraft:barrier"},
{pos: [4, 2, 0], state: "minecraft:barrier"},
{pos: [4, 2, 1], state: "minecraft:barrier"},
{pos: [4, 2, 2], state: "minecraft:barrier"},
{pos: [4, 2, 3], state: "minecraft:barrier"},
{pos: [4, 2, 4], state: "minecraft:barrier"},
{pos: [0, 3, 0], state: "minecraft:air"},
{pos: [0, 3, 1], state: "minecraft:air"},
{pos: [0, 3, 2], state: "minecraft:air"},
{pos: [0, 3, 3], state: "minecraft:air"},
{pos: [0, 3, 4], state: "minecraft:air"},
{pos: [1, 3, 0], state: "minecraft:air"},
{pos: [1, 3, 1], state: "minecraft:air"},
{pos: [1, 3, 2], state: "minecraft:air"},
{pos: [1, 3, 3], state: "minecraft:air"},
{pos: [1, 3, 4], state: "minecraft:air"},
{pos: [2, 3, 0], state: "minecraft:air"},
{pos: [2, 3, 1], state: "minecraft:air"},
{pos: [2, 3, 2], state: "minecraft:air"},
{pos: [2, 3, 3], state: "minecraft:air"},
{pos: [2, 3, 4], state: "minecraft:air"},
{pos: [3, 3, 0], state: "minecraft:air"},
{pos: [3, 3, 1], state: "minecraft:air"},
{pos: [3, 3, 2], state: "minecraft:air"},
{pos: [3, 3, 3], state: "minecraft:air"},
{pos: [3, 3, 4], state: "minecraft:air"},
{pos: [4, 3, 0], state: "minecraft:air"},
{pos: [4, 3, 1], state: "minecraft:air"},
{pos: [4, 3, 2], state: "minecraft:air"},
{pos: [4, 3, 3], state: "minecraft:air"},
{pos: [4, 3, 4], state: "minecraft:air"},
{pos: [0, 4, 0], state: "minecraft:air"},
{pos: [0, 4, 1], state: "minecraft:air"},
{pos: [0, 4, 2], state: "minecraft:air"},
{pos: [0, 4, 3], state: "minecraft:air"},
{pos: [0, 4, 4], state: "minecraft:air"},
{pos: [1, 4, 0], state: "minecraft:air"},
{pos: [1, 4, 1], state: "minecraft:air"},
{pos: [1, 4, 2], state: "minecraft:air"},
{pos: [1, 4, 3], state: "minecraft:air"},
{pos: [1, 4, 4], state: "minecraft:air"},
{pos: [2, 4, 0], state: "minecraft:air"},
{pos: [2, 4, 1], state: "minecraft:air"},
{pos: [2, 4, 2], state: "minecraft:air"},
{pos: [2, 4, 3], state: "minecraft:air"},
{pos: [2, 4, 4], state: "minecraft:air"},
{pos: [3, 4, 0], state: "minecraft:air"},
{pos: [3, 4, 1], state: "minecraft:air"},
{pos: [3, 4, 2], state: "minecraft:air"},
{pos: [3, 4, 3], state: "minecraft:air"},
{pos: [3, 4, 4], state: "minecraft:air"},
{pos: [4, 4, 0], state: "minecraft:air"},
{pos: [4, 4, 1], state: "minecraft:air"},
{pos: [4, 4, 2], state: "minecraft:air"},
{pos: [4, 4, 3], state: "minecraft:air"},
{pos: [4, 4, 4], state: "minecraft:air"}
],
entities: [],
palette: [
"minecraft:obsidian",
"minecraft:barrier",
"minecraft:bone_block{axis:y}",
"minecraft:air",
"computercraft:turtle_normal{facing:south,waterlogged:false}"
]
}