mirror of
https://github.com/SquidDev-CC/CC-Tweaked
synced 2025-11-02 22:53:15 +00:00
Compare commits
5 Commits
v1.19.3-1.
...
v1.19.3-1.
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
f561572509 | ||
|
|
edb21f33be | ||
|
|
02b68b259e | ||
|
|
28a55349a9 | ||
|
|
2457a31728 |
@@ -6,7 +6,7 @@ kotlin.jvm.target.validation.mode=error
|
||||
|
||||
# Mod properties
|
||||
isUnstable=true
|
||||
modVersion=1.102.1
|
||||
modVersion=1.102.2
|
||||
|
||||
# Minecraft properties: We want to configure this here so we can read it in settings.gradle
|
||||
mcVersion=1.19.3
|
||||
|
||||
@@ -6,6 +6,7 @@
|
||||
package dan200.computercraft.shared.peripheral.diskdrive;
|
||||
|
||||
import com.google.errorprone.annotations.concurrent.GuardedBy;
|
||||
import dan200.computercraft.api.filesystem.Mount;
|
||||
import dan200.computercraft.api.filesystem.WritableMount;
|
||||
import dan200.computercraft.api.peripheral.IComputerAccess;
|
||||
import dan200.computercraft.api.peripheral.IPeripheral;
|
||||
@@ -47,11 +48,14 @@ public final class DiskDriveBlockEntity extends AbstractContainerBlockEntity {
|
||||
private final NonNullList<ItemStack> inventory = NonNullList.withSize(1, ItemStack.EMPTY);
|
||||
|
||||
private MediaStack media = MediaStack.EMPTY;
|
||||
private @Nullable Mount mount;
|
||||
|
||||
private boolean recordPlaying = false;
|
||||
// In order to avoid main-thread calls in the peripheral, we set flags to mark which operation should be performed,
|
||||
// then read them when ticking.
|
||||
private final AtomicReference<RecordCommand> recordQueued = new AtomicReference<>(null);
|
||||
private final AtomicBoolean ejectQueued = new AtomicBoolean(false);
|
||||
private final AtomicBoolean mountQueued = new AtomicBoolean(false);
|
||||
|
||||
public DiskDriveBlockEntity(BlockEntityType<DiskDriveBlockEntity> type, BlockPos pos, BlockState state) {
|
||||
super(type, pos, state);
|
||||
@@ -109,6 +113,12 @@ public final class DiskDriveBlockEntity extends AbstractContainerBlockEntity {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (mountQueued.get()) {
|
||||
synchronized (this) {
|
||||
mountAll();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -124,9 +134,9 @@ public final class DiskDriveBlockEntity extends AbstractContainerBlockEntity {
|
||||
|
||||
private void updateItem() {
|
||||
var newDisk = getDiskStack();
|
||||
if (ItemStack.isSame(newDisk, media.stack)) return;
|
||||
if (ItemStack.isSameItemSameTags(newDisk, media.stack)) return;
|
||||
|
||||
var media = new MediaStack(newDisk.copy());
|
||||
var media = MediaStack.of(newDisk);
|
||||
|
||||
if (newDisk.isEmpty()) {
|
||||
updateBlockState(DiskDriveState.EMPTY);
|
||||
@@ -146,12 +156,10 @@ public final class DiskDriveBlockEntity extends AbstractContainerBlockEntity {
|
||||
recordPlaying = false;
|
||||
}
|
||||
|
||||
mount = null;
|
||||
this.media = media;
|
||||
|
||||
// Mount new disk
|
||||
if (!this.media.stack.isEmpty()) {
|
||||
for (var computer : computers.entrySet()) mountDisk(computer.getKey(), computer.getValue(), this.media);
|
||||
}
|
||||
mountAll();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -163,11 +171,30 @@ public final class DiskDriveBlockEntity extends AbstractContainerBlockEntity {
|
||||
return media;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the current disk stack, mounting/unmounting if needed.
|
||||
*
|
||||
* @param stack The new disk stack.
|
||||
*/
|
||||
void setDiskStack(ItemStack stack) {
|
||||
setItem(0, stack);
|
||||
setChanged();
|
||||
}
|
||||
|
||||
/**
|
||||
* Update the current disk stack, assuming the underlying item does not change. Unlike
|
||||
* {@link #setDiskStack(ItemStack)} this will not change any mounts.
|
||||
*
|
||||
* @param stack The new disk stack.
|
||||
*/
|
||||
void updateDiskStack(ItemStack stack) {
|
||||
setItem(0, stack);
|
||||
if (!ItemStack.isSameItemSameTags(stack, media.stack)) {
|
||||
media = MediaStack.of(stack);
|
||||
super.setChanged();
|
||||
}
|
||||
}
|
||||
|
||||
@Nullable
|
||||
String getDiskMountPath(IComputerAccess computer) {
|
||||
synchronized (this) {
|
||||
@@ -176,15 +203,21 @@ public final class DiskDriveBlockEntity extends AbstractContainerBlockEntity {
|
||||
}
|
||||
}
|
||||
|
||||
void mount(IComputerAccess computer) {
|
||||
/**
|
||||
* Attach a computer to this disk drive. This sets up the {@link MountInfo} map and flags us to mount next tick. We
|
||||
* don't mount here, as that might require mutating the current stack.
|
||||
*
|
||||
* @param computer The computer to attach.
|
||||
*/
|
||||
void attach(IComputerAccess computer) {
|
||||
synchronized (this) {
|
||||
var info = new MountInfo();
|
||||
computers.put(computer, info);
|
||||
mountDisk(computer, info, media);
|
||||
mountQueued.set(true);
|
||||
}
|
||||
}
|
||||
|
||||
void unmount(IComputerAccess computer) {
|
||||
void detach(IComputerAccess computer) {
|
||||
synchronized (this) {
|
||||
unmountDisk(computer, computers.remove(computer));
|
||||
}
|
||||
@@ -202,10 +235,35 @@ public final class DiskDriveBlockEntity extends AbstractContainerBlockEntity {
|
||||
ejectQueued.set(true);
|
||||
}
|
||||
|
||||
/**
|
||||
* Add our mount to all computers.
|
||||
*/
|
||||
@GuardedBy("this")
|
||||
private void mountDisk(IComputerAccess computer, MountInfo info, MediaStack disk) {
|
||||
var mount = disk.getMount((ServerLevel) getLevel());
|
||||
if (mount != null) {
|
||||
private void mountAll() {
|
||||
doMountAll();
|
||||
mountQueued.set(false);
|
||||
}
|
||||
|
||||
/**
|
||||
* The worker for {@link #mountAll()}. This is responsible for creating the mount and placing it on all computers.
|
||||
*/
|
||||
@GuardedBy("this")
|
||||
private void doMountAll() {
|
||||
if (computers.isEmpty() || media.media == null) return;
|
||||
|
||||
if (mount == null) {
|
||||
var stack = getDiskStack();
|
||||
mount = media.media.createDataMount(stack, (ServerLevel) level);
|
||||
setDiskStack(stack);
|
||||
}
|
||||
|
||||
if (mount == null) return;
|
||||
|
||||
for (var entry : computers.entrySet()) {
|
||||
var computer = entry.getKey();
|
||||
var info = entry.getValue();
|
||||
if (info.mountPath != null) continue;
|
||||
|
||||
if (mount instanceof WritableMount writable) {
|
||||
// Try mounting at the lowest numbered "disk" name we can
|
||||
var n = 1;
|
||||
@@ -221,11 +279,9 @@ public final class DiskDriveBlockEntity extends AbstractContainerBlockEntity {
|
||||
n++;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
info.mountPath = null;
|
||||
}
|
||||
|
||||
computer.queueEvent("disk", computer.getAttachmentName());
|
||||
computer.queueEvent("disk", computer.getAttachmentName());
|
||||
}
|
||||
}
|
||||
|
||||
private static void unmountDisk(IComputerAccess computer, MountInfo info) {
|
||||
|
||||
@@ -84,11 +84,12 @@ public class DiskDrivePeripheral implements IPeripheral {
|
||||
var media = diskDrive.getMedia();
|
||||
if (media.media == null) return;
|
||||
|
||||
var stack = media.stack.copy();
|
||||
// We're on the main thread so the stack and media should be in sync.
|
||||
var stack = diskDrive.getDiskStack();
|
||||
if (!media.media.setLabel(stack, label.map(StringUtil::normaliseLabel).orElse(null))) {
|
||||
throw new LuaException("Disk label cannot be changed");
|
||||
}
|
||||
diskDrive.setDiskStack(stack);
|
||||
diskDrive.updateDiskStack(stack);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -178,12 +179,12 @@ public class DiskDrivePeripheral implements IPeripheral {
|
||||
|
||||
@Override
|
||||
public void attach(IComputerAccess computer) {
|
||||
diskDrive.mount(computer);
|
||||
diskDrive.attach(computer);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void detach(IComputerAccess computer) {
|
||||
diskDrive.unmount(computer);
|
||||
diskDrive.detach(computer);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -5,10 +5,8 @@
|
||||
*/
|
||||
package dan200.computercraft.shared.peripheral.diskdrive;
|
||||
|
||||
import dan200.computercraft.api.filesystem.Mount;
|
||||
import dan200.computercraft.api.media.IMedia;
|
||||
import dan200.computercraft.impl.MediaProviders;
|
||||
import net.minecraft.server.level.ServerLevel;
|
||||
import net.minecraft.sounds.SoundEvent;
|
||||
import net.minecraft.world.item.ItemStack;
|
||||
|
||||
@@ -17,18 +15,22 @@ import javax.annotation.Nullable;
|
||||
/**
|
||||
* An immutable snapshot of the current disk. This allows us to read the stack in a thread-safe manner.
|
||||
*/
|
||||
class MediaStack {
|
||||
static final MediaStack EMPTY = new MediaStack(ItemStack.EMPTY);
|
||||
final class MediaStack {
|
||||
static final MediaStack EMPTY = new MediaStack(ItemStack.EMPTY, null);
|
||||
|
||||
final ItemStack stack;
|
||||
final @Nullable IMedia media;
|
||||
|
||||
@Nullable
|
||||
private Mount mount;
|
||||
|
||||
MediaStack(ItemStack stack) {
|
||||
private MediaStack(ItemStack stack, @Nullable IMedia media) {
|
||||
this.stack = stack;
|
||||
media = MediaProviders.get(stack);
|
||||
this.media = media;
|
||||
}
|
||||
|
||||
public static MediaStack of(ItemStack stack) {
|
||||
if (stack.isEmpty()) return EMPTY;
|
||||
|
||||
var freshStack = stack.copy();
|
||||
return new MediaStack(freshStack, MediaProviders.get(freshStack));
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@@ -40,12 +42,4 @@ class MediaStack {
|
||||
String getAudioTitle() {
|
||||
return media != null ? media.getAudioTitle(stack) : null;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public Mount getMount(ServerLevel level) {
|
||||
if (media == null) return null;
|
||||
|
||||
if (mount == null) mount = media.createDataMount(stack, level);
|
||||
return mount;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -8,6 +8,7 @@ package dan200.computercraft.gametest.core;
|
||||
import com.mojang.brigadier.CommandDispatcher;
|
||||
import dan200.computercraft.api.ComputerCraftAPI;
|
||||
import dan200.computercraft.mixin.gametest.TestCommandAccessor;
|
||||
import dan200.computercraft.shared.ModRegistry;
|
||||
import net.minecraft.ChatFormatting;
|
||||
import net.minecraft.commands.CommandSourceStack;
|
||||
import net.minecraft.gametest.framework.GameTestRegistry;
|
||||
@@ -81,6 +82,27 @@ class CCTestCommand {
|
||||
player.getLevel().addFreshEntity(armorStand);
|
||||
return 0;
|
||||
}))
|
||||
|
||||
.then(literal("give-computer").executes(context -> {
|
||||
var player = context.getSource().getPlayerOrException();
|
||||
var pos = StructureUtils.findNearestStructureBlock(player.blockPosition(), 15, player.getLevel());
|
||||
if (pos == null) return error(context.getSource(), "No nearby test");
|
||||
|
||||
var structureBlock = (StructureBlockEntity) player.getLevel().getBlockEntity(pos);
|
||||
if (structureBlock == null) return error(context.getSource(), "No nearby structure block");
|
||||
var info = GameTestRegistry.getTestFunction(structureBlock.getStructurePath());
|
||||
|
||||
var item = ModRegistry.Items.COMPUTER_ADVANCED.get().create(1, info.getTestName());
|
||||
if (!player.getInventory().add(item)) {
|
||||
var itemEntity = player.drop(item, false);
|
||||
if (itemEntity != null) {
|
||||
itemEntity.setNoPickUpDelay();
|
||||
itemEntity.setOwner(player.getUUID());
|
||||
}
|
||||
}
|
||||
|
||||
return 1;
|
||||
}))
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
@@ -8,6 +8,7 @@ package dan200.computercraft.gametest
|
||||
import dan200.computercraft.core.apis.FSAPI
|
||||
import dan200.computercraft.gametest.api.*
|
||||
import dan200.computercraft.shared.ModRegistry
|
||||
import dan200.computercraft.shared.media.items.DiskItem
|
||||
import dan200.computercraft.shared.peripheral.diskdrive.DiskDriveBlock
|
||||
import dan200.computercraft.shared.peripheral.diskdrive.DiskDriveState
|
||||
import dan200.computercraft.test.core.assertArrayEquals
|
||||
@@ -45,10 +46,14 @@ class Disk_Drive_Test {
|
||||
thenWaitUntil { helper.assertItemEntityPresent(Items.MUSIC_DISC_13, stackAt, 0.0) }
|
||||
}
|
||||
|
||||
/**
|
||||
* A mount is initially attached, and then removed when the disk is ejected.
|
||||
*/
|
||||
@GameTest
|
||||
fun Adds_removes_mount(helper: GameTestHelper) = helper.sequence {
|
||||
thenIdle(2)
|
||||
thenOnComputer {
|
||||
thenOnComputer { } // Wait for the computer to start up
|
||||
thenIdle(2) // Let the disk drive tick once to create the mount
|
||||
thenOnComputer { // Then actually assert things!
|
||||
getApi<FSAPI>().getDrive("disk").assertArrayEquals("right")
|
||||
callPeripheral("right", "ejectDisk")
|
||||
}
|
||||
@@ -56,6 +61,18 @@ class Disk_Drive_Test {
|
||||
thenOnComputer { assertEquals(null, getApi<FSAPI>().getDrive("disk")) }
|
||||
}
|
||||
|
||||
/**
|
||||
* When creating a new mount, the item is with a new disk ID.
|
||||
*/
|
||||
@GameTest
|
||||
fun Creates_disk_id(helper: GameTestHelper) = helper.sequence {
|
||||
val drivePos = BlockPos(2, 2, 2)
|
||||
thenWaitUntil {
|
||||
val drive = helper.getBlockEntity(drivePos, ModRegistry.BlockEntities.DISK_DRIVE.get())
|
||||
if (DiskItem.getDiskID(drive.getItem(0)) == -1) helper.fail("Disk has no item", drivePos)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Check comparators can read the contents of the disk drive
|
||||
*/
|
||||
|
||||
@@ -63,7 +63,7 @@ class Monitor_Test {
|
||||
}
|
||||
|
||||
/**
|
||||
* Test
|
||||
* Test monitors render correctly
|
||||
*/
|
||||
@GameTestGenerator
|
||||
fun Render_monitor_tests(): List<TestFunction> {
|
||||
@@ -72,7 +72,7 @@ class Monitor_Test {
|
||||
fun addTest(label: String, renderer: MonitorRenderer, time: Long = Times.NOON, tag: String = TestTags.CLIENT) {
|
||||
if (!TestTags.isEnabled(tag)) return
|
||||
|
||||
val className = Monitor_Test::class.java.simpleName.lowercase()
|
||||
val className = this::class.java.simpleName.lowercase()
|
||||
val testName = "$className.render_monitor"
|
||||
|
||||
tests.add(
|
||||
|
||||
@@ -0,0 +1,53 @@
|
||||
package dan200.computercraft.gametest
|
||||
|
||||
import dan200.computercraft.gametest.api.*
|
||||
import net.minecraft.gametest.framework.GameTestGenerator
|
||||
import net.minecraft.gametest.framework.GameTestHelper
|
||||
import net.minecraft.gametest.framework.TestFunction
|
||||
|
||||
class Printout_Test {
|
||||
/**
|
||||
* Test printouts render correctly
|
||||
*/
|
||||
@GameTestGenerator
|
||||
fun Render_in_frame(): List<TestFunction> {
|
||||
val tests = mutableListOf<TestFunction>()
|
||||
|
||||
fun addTest(label: String, time: Long = Times.NOON, tag: String = TestTags.CLIENT) {
|
||||
if (!TestTags.isEnabled(tag)) return
|
||||
|
||||
val className = this::class.java.simpleName.lowercase()
|
||||
val testName = "$className.render_in_frame"
|
||||
|
||||
tests.add(
|
||||
TestFunction(
|
||||
"$testName.$label",
|
||||
"$testName.$label",
|
||||
testName,
|
||||
Timeouts.DEFAULT,
|
||||
0,
|
||||
true,
|
||||
) { renderPrintout(it, time) },
|
||||
)
|
||||
}
|
||||
|
||||
addTest("noon", Times.NOON)
|
||||
addTest("midnight", Times.MIDNIGHT)
|
||||
|
||||
addTest("sodium", tag = "sodium")
|
||||
|
||||
addTest("iris_noon", Times.NOON, tag = "iris")
|
||||
addTest("iris_midnight", Times.MIDNIGHT, tag = "iris")
|
||||
|
||||
return tests
|
||||
}
|
||||
|
||||
private fun renderPrintout(helper: GameTestHelper, time: Long) = helper.sequence {
|
||||
thenExecute {
|
||||
helper.level.dayTime = time
|
||||
helper.positionAtArmorStand()
|
||||
}
|
||||
|
||||
thenScreenshot()
|
||||
}
|
||||
}
|
||||
@@ -80,6 +80,7 @@ object TestHooks {
|
||||
Monitor_Test::class.java,
|
||||
Pocket_Computer_Test::class.java,
|
||||
Printer_Test::class.java,
|
||||
Printout_Test::class.java,
|
||||
Recipe_Test::class.java,
|
||||
Turtle_Test::class.java,
|
||||
)
|
||||
|
||||
138
projects/common/src/testMod/resources/data/cctest/structures/disk_drive_test.creates_disk_id.snbt
generated
Normal file
138
projects/common/src/testMod/resources/data/cctest/structures/disk_drive_test.creates_disk_id.snbt
generated
Normal file
@@ -0,0 +1,138 @@
|
||||
{
|
||||
DataVersion: 3218,
|
||||
size: [5, 5, 5],
|
||||
data: [
|
||||
{pos: [0, 0, 0], state: "minecraft:polished_andesite"},
|
||||
{pos: [0, 0, 1], state: "minecraft:polished_andesite"},
|
||||
{pos: [0, 0, 2], state: "minecraft:polished_andesite"},
|
||||
{pos: [0, 0, 3], state: "minecraft:polished_andesite"},
|
||||
{pos: [0, 0, 4], state: "minecraft:polished_andesite"},
|
||||
{pos: [1, 0, 0], state: "minecraft:polished_andesite"},
|
||||
{pos: [1, 0, 1], state: "minecraft:polished_andesite"},
|
||||
{pos: [1, 0, 2], state: "minecraft:polished_andesite"},
|
||||
{pos: [1, 0, 3], state: "minecraft:polished_andesite"},
|
||||
{pos: [1, 0, 4], state: "minecraft:polished_andesite"},
|
||||
{pos: [2, 0, 0], state: "minecraft:polished_andesite"},
|
||||
{pos: [2, 0, 1], state: "minecraft:polished_andesite"},
|
||||
{pos: [2, 0, 2], state: "minecraft:polished_andesite"},
|
||||
{pos: [2, 0, 3], state: "minecraft:polished_andesite"},
|
||||
{pos: [2, 0, 4], state: "minecraft:polished_andesite"},
|
||||
{pos: [3, 0, 0], state: "minecraft:polished_andesite"},
|
||||
{pos: [3, 0, 1], state: "minecraft:polished_andesite"},
|
||||
{pos: [3, 0, 2], state: "minecraft:polished_andesite"},
|
||||
{pos: [3, 0, 3], state: "minecraft:polished_andesite"},
|
||||
{pos: [3, 0, 4], state: "minecraft:polished_andesite"},
|
||||
{pos: [4, 0, 0], state: "minecraft:polished_andesite"},
|
||||
{pos: [4, 0, 1], state: "minecraft:polished_andesite"},
|
||||
{pos: [4, 0, 2], state: "minecraft:polished_andesite"},
|
||||
{pos: [4, 0, 3], state: "minecraft:polished_andesite"},
|
||||
{pos: [4, 0, 4], state: "minecraft:polished_andesite"},
|
||||
{pos: [0, 1, 0], state: "minecraft:air"},
|
||||
{pos: [0, 1, 1], state: "minecraft:air"},
|
||||
{pos: [0, 1, 2], state: "minecraft:air"},
|
||||
{pos: [0, 1, 3], state: "minecraft:air"},
|
||||
{pos: [0, 1, 4], state: "minecraft:air"},
|
||||
{pos: [1, 1, 0], state: "minecraft:air"},
|
||||
{pos: [1, 1, 1], state: "minecraft:air"},
|
||||
{pos: [1, 1, 2], state: "computercraft:computer_advanced{facing:north,state:on}", nbt: {ComputerId: 1, Label: "disk_drive_test.creates_disk_id", On: 1b, id: "computercraft:computer_advanced"}},
|
||||
{pos: [1, 1, 3], state: "minecraft:air"},
|
||||
{pos: [1, 1, 4], state: "minecraft:air"},
|
||||
{pos: [2, 1, 0], state: "minecraft:air"},
|
||||
{pos: [2, 1, 1], state: "minecraft:air"},
|
||||
{pos: [2, 1, 2], state: "computercraft:disk_drive{facing:north,state:full}", nbt: {Item: {Count: 1b, id: "computercraft:disk", tag: {Color: 1118481}}, id: "computercraft:disk_drive"}},
|
||||
{pos: [2, 1, 3], state: "minecraft:air"},
|
||||
{pos: [2, 1, 4], state: "minecraft:air"},
|
||||
{pos: [3, 1, 0], state: "minecraft:air"},
|
||||
{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:air"},
|
||||
{pos: [4, 1, 0], state: "minecraft:air"},
|
||||
{pos: [4, 1, 1], state: "minecraft:air"},
|
||||
{pos: [4, 1, 2], state: "minecraft:air"},
|
||||
{pos: [4, 1, 3], state: "minecraft:air"},
|
||||
{pos: [4, 1, 4], state: "minecraft:air"},
|
||||
{pos: [0, 2, 0], state: "minecraft:air"},
|
||||
{pos: [0, 2, 1], state: "minecraft:air"},
|
||||
{pos: [0, 2, 2], state: "minecraft:air"},
|
||||
{pos: [0, 2, 3], state: "minecraft:air"},
|
||||
{pos: [0, 2, 4], state: "minecraft:air"},
|
||||
{pos: [1, 2, 0], state: "minecraft:air"},
|
||||
{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:air"},
|
||||
{pos: [2, 2, 0], state: "minecraft:air"},
|
||||
{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:air"},
|
||||
{pos: [3, 2, 0], state: "minecraft:air"},
|
||||
{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:air"},
|
||||
{pos: [4, 2, 0], state: "minecraft:air"},
|
||||
{pos: [4, 2, 1], state: "minecraft:air"},
|
||||
{pos: [4, 2, 2], state: "minecraft:air"},
|
||||
{pos: [4, 2, 3], state: "minecraft:air"},
|
||||
{pos: [4, 2, 4], state: "minecraft:air"},
|
||||
{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:polished_andesite",
|
||||
"minecraft:air",
|
||||
"computercraft:computer_advanced{facing:north,state:on}",
|
||||
"computercraft:disk_drive{facing:north,state:full}"
|
||||
]
|
||||
}
|
||||
139
projects/common/src/testMod/resources/data/cctest/structures/printout_test.render_in_frame.snbt
generated
Normal file
139
projects/common/src/testMod/resources/data/cctest/structures/printout_test.render_in_frame.snbt
generated
Normal file
@@ -0,0 +1,139 @@
|
||||
{
|
||||
DataVersion: 3218,
|
||||
size: [5, 5, 5],
|
||||
data: [
|
||||
{pos: [0, 0, 0], state: "minecraft:polished_andesite"},
|
||||
{pos: [0, 0, 1], state: "minecraft:polished_andesite"},
|
||||
{pos: [0, 0, 2], state: "minecraft:polished_andesite"},
|
||||
{pos: [0, 0, 3], state: "minecraft:polished_andesite"},
|
||||
{pos: [0, 0, 4], state: "minecraft:polished_andesite"},
|
||||
{pos: [1, 0, 0], state: "minecraft:polished_andesite"},
|
||||
{pos: [1, 0, 1], state: "minecraft:polished_andesite"},
|
||||
{pos: [1, 0, 2], state: "minecraft:polished_andesite"},
|
||||
{pos: [1, 0, 3], state: "minecraft:polished_andesite"},
|
||||
{pos: [1, 0, 4], state: "minecraft:polished_andesite"},
|
||||
{pos: [2, 0, 0], state: "minecraft:polished_andesite"},
|
||||
{pos: [2, 0, 1], state: "minecraft:polished_andesite"},
|
||||
{pos: [2, 0, 2], state: "minecraft:polished_andesite"},
|
||||
{pos: [2, 0, 3], state: "minecraft:polished_andesite"},
|
||||
{pos: [2, 0, 4], state: "minecraft:polished_andesite"},
|
||||
{pos: [3, 0, 0], state: "minecraft:polished_andesite"},
|
||||
{pos: [3, 0, 1], state: "minecraft:polished_andesite"},
|
||||
{pos: [3, 0, 2], state: "minecraft:polished_andesite"},
|
||||
{pos: [3, 0, 3], state: "minecraft:polished_andesite"},
|
||||
{pos: [3, 0, 4], state: "minecraft:polished_andesite"},
|
||||
{pos: [4, 0, 0], state: "minecraft:polished_andesite"},
|
||||
{pos: [4, 0, 1], state: "minecraft:polished_andesite"},
|
||||
{pos: [4, 0, 2], state: "minecraft:polished_andesite"},
|
||||
{pos: [4, 0, 3], state: "minecraft:polished_andesite"},
|
||||
{pos: [4, 0, 4], state: "minecraft:polished_andesite"},
|
||||
{pos: [0, 1, 0], state: "minecraft:air"},
|
||||
{pos: [0, 1, 1], state: "minecraft:air"},
|
||||
{pos: [0, 1, 2], state: "minecraft:air"},
|
||||
{pos: [0, 1, 3], state: "minecraft:air"},
|
||||
{pos: [0, 1, 4], state: "minecraft:air"},
|
||||
{pos: [1, 1, 0], state: "minecraft:air"},
|
||||
{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:air"},
|
||||
{pos: [2, 1, 0], state: "minecraft:air"},
|
||||
{pos: [2, 1, 1], state: "minecraft:air"},
|
||||
{pos: [2, 1, 2], state: "minecraft:air"},
|
||||
{pos: [2, 1, 3], state: "minecraft:air"},
|
||||
{pos: [2, 1, 4], state: "minecraft:polished_andesite"},
|
||||
{pos: [3, 1, 0], state: "minecraft:air"},
|
||||
{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:air"},
|
||||
{pos: [4, 1, 0], state: "minecraft:air"},
|
||||
{pos: [4, 1, 1], state: "minecraft:air"},
|
||||
{pos: [4, 1, 2], state: "minecraft:air"},
|
||||
{pos: [4, 1, 3], state: "minecraft:air"},
|
||||
{pos: [4, 1, 4], state: "minecraft:air"},
|
||||
{pos: [0, 2, 0], state: "minecraft:air"},
|
||||
{pos: [0, 2, 1], state: "minecraft:air"},
|
||||
{pos: [0, 2, 2], state: "minecraft:air"},
|
||||
{pos: [0, 2, 3], state: "minecraft:air"},
|
||||
{pos: [0, 2, 4], state: "minecraft:air"},
|
||||
{pos: [1, 2, 0], state: "minecraft:air"},
|
||||
{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:air"},
|
||||
{pos: [2, 2, 0], state: "minecraft:air"},
|
||||
{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:polished_andesite"},
|
||||
{pos: [3, 2, 0], state: "minecraft:air"},
|
||||
{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:air"},
|
||||
{pos: [4, 2, 0], state: "minecraft:air"},
|
||||
{pos: [4, 2, 1], state: "minecraft:air"},
|
||||
{pos: [4, 2, 2], state: "minecraft:air"},
|
||||
{pos: [4, 2, 3], state: "minecraft:air"},
|
||||
{pos: [4, 2, 4], state: "minecraft:air"},
|
||||
{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: [
|
||||
{blockPos: [2, 1, 2], pos: [2.583196949396921d, 1.0d, 2.608974919959593d], nbt: {AbsorptionAmount: 0.0f, Air: 300s, ArmorItems: [{}, {}, {}, {}], Attributes: [{Base: 0.699999988079071d, Name: "minecraft:generic.movement_speed"}], Brain: {memories: {}}, CustomName: '{"text":"printouttest.in_frame_at_night"}', DeathTime: 0s, DisabledSlots: 0, FallDistance: 0.0f, FallFlying: 0b, Fire: -1s, HandItems: [{}, {}], Health: 20.0f, HurtByTimestamp: 0, HurtTime: 0s, Invisible: 1b, Invulnerable: 0b, Marker: 1b, Motion: [0.0d, 0.0d, 0.0d], NoBasePlate: 0b, OnGround: 0b, PortalCooldown: 0, Pos: [221.58319694939692d, -58.0d, 92.60897491995959d], Pose: {}, Rotation: [1.3504658f, 6.7031174f], ShowArms: 0b, Small: 0b, UUID: [I; 1854159985, -991539606, -1317309541, 1483112386], id: "minecraft:armor_stand"}},
|
||||
{blockPos: [2, 2, 3], pos: [2.5d, 2.5d, 3.96875d], nbt: {Air: 300s, Facing: 2b, FallDistance: 0.0f, Fire: -1s, Fixed: 0b, Invisible: 0b, Invulnerable: 0b, Item: {Count: 1b, id: "computercraft:printed_page", tag: {Color0: "eeeeeeeeeeeeeeeeeeeeeeeee", Color1: "eeeeeeeeeeeeeeeeeeeeeeeee", Color10: "eeeeeeeeeeeeeeeeeeeeeeeee", Color11: "eeeeeeeeeeeeeeeeeeeeeeeee", Color12: "eeeeeeeeeeeeeeeeeeeeeeeee", Color13: "eeeeeeeeeeeeeeeeeeeeeeeee", Color14: "eeeeeeeeeeeeeeeeeeeeeeeee", Color15: "eeeeeeeeeeeeeeeeeeeeeeeee", Color16: "eeeeeeeeeeeeeeeeeeeeeeeee", Color17: "eeeeeeeeeeeeeeeeeeeeeeeee", Color18: "eeeeeeeeeeeeeeeeeeeeeeeee", Color19: "eeeeeeeeeeeeeeeeeeeeeeeee", Color2: "eeeeeeeeeeeeeeeeeeeeeeeee", Color20: "eeeeeeeeeeeeeeeeeeeeeeeee", Color3: "eeeeeeeeeeeeeeeeeeeeeeeee", Color4: "eeeeeeeeeeeeeeeeeeeeeeeee", Color5: "eeeeeeeeeeeeeeeeeeeeeeeee", Color6: "eeeeeeeeeeeeeeeeeeeeeeeee", Color7: "eeeeeeeeeeeeeeeeeeeeeeeee", Color8: "eeeeeeeeeeeeeeeeeeeeeeeee", Color9: "eeeeeeeeeeeeeeeeeeeeeeeee", Pages: 1, Text0: "If you're reading this, ", Text1: "the test failed. ", Text10: " ", Text11: " ", Text12: " ", Text13: " ", Text14: " ", Text15: " ", Text16: " ", Text17: " ", Text18: " ", Text19: " ", Text2: " ", Text20: " ", Text3: " ", Text4: " ", Text5: " ", Text6: " ", Text7: " ", Text8: " ", Text9: " ", Title: "a.lua"}}, ItemDropChance: 1.0f, ItemRotation: 0b, Motion: [0.0d, 0.0d, 0.0d], OnGround: 0b, PortalCooldown: 0, Pos: [221.5d, -56.5d, 93.96875d], Rotation: [-540.0f, 0.0f], TileX: 221, TileY: -57, TileZ: 93, UUID: [I; 1972443954, 193152445, -1823446000, -1684171214], id: "minecraft:item_frame"}}
|
||||
],
|
||||
palette: [
|
||||
"minecraft:polished_andesite",
|
||||
"minecraft:air"
|
||||
]
|
||||
}
|
||||
@@ -1,140 +0,0 @@
|
||||
{
|
||||
DataVersion: 2730,
|
||||
size: [5, 5, 5],
|
||||
data: [
|
||||
{pos: [0, 0, 0], state: "minecraft:polished_andesite"},
|
||||
{pos: [0, 0, 1], state: "minecraft:polished_andesite"},
|
||||
{pos: [0, 0, 2], state: "minecraft:polished_andesite"},
|
||||
{pos: [0, 0, 3], state: "minecraft:polished_andesite"},
|
||||
{pos: [0, 0, 4], state: "minecraft:polished_andesite"},
|
||||
{pos: [1, 0, 0], state: "minecraft:polished_andesite"},
|
||||
{pos: [1, 0, 1], state: "minecraft:polished_andesite"},
|
||||
{pos: [1, 0, 2], state: "minecraft:polished_andesite"},
|
||||
{pos: [1, 0, 3], state: "minecraft:polished_andesite"},
|
||||
{pos: [1, 0, 4], state: "minecraft:polished_andesite"},
|
||||
{pos: [2, 0, 0], state: "minecraft:polished_andesite"},
|
||||
{pos: [2, 0, 1], state: "minecraft:polished_andesite"},
|
||||
{pos: [2, 0, 2], state: "minecraft:polished_andesite"},
|
||||
{pos: [2, 0, 3], state: "minecraft:polished_andesite"},
|
||||
{pos: [2, 0, 4], state: "minecraft:polished_andesite"},
|
||||
{pos: [3, 0, 0], state: "minecraft:polished_andesite"},
|
||||
{pos: [3, 0, 1], state: "minecraft:polished_andesite"},
|
||||
{pos: [3, 0, 2], state: "minecraft:polished_andesite"},
|
||||
{pos: [3, 0, 3], state: "minecraft:polished_andesite"},
|
||||
{pos: [3, 0, 4], state: "minecraft:polished_andesite"},
|
||||
{pos: [4, 0, 0], state: "minecraft:polished_andesite"},
|
||||
{pos: [4, 0, 1], state: "minecraft:polished_andesite"},
|
||||
{pos: [4, 0, 2], state: "minecraft:polished_andesite"},
|
||||
{pos: [4, 0, 3], state: "minecraft:polished_andesite"},
|
||||
{pos: [4, 0, 4], state: "minecraft:polished_andesite"},
|
||||
{pos: [0, 1, 0], state: "minecraft:white_concrete"},
|
||||
{pos: [0, 1, 1], state: "minecraft:white_concrete"},
|
||||
{pos: [0, 1, 2], state: "minecraft:white_concrete"},
|
||||
{pos: [0, 1, 3], state: "minecraft:white_concrete"},
|
||||
{pos: [0, 1, 4], state: "minecraft:white_concrete"},
|
||||
{pos: [1, 1, 0], state: "minecraft:white_concrete"},
|
||||
{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:white_concrete"},
|
||||
{pos: [2, 1, 0], state: "minecraft:white_concrete"},
|
||||
{pos: [2, 1, 1], state: "minecraft:air"},
|
||||
{pos: [2, 1, 2], state: "minecraft:air"},
|
||||
{pos: [2, 1, 3], state: "minecraft:air"},
|
||||
{pos: [2, 1, 4], state: "minecraft:white_concrete"},
|
||||
{pos: [3, 1, 0], state: "minecraft:white_concrete"},
|
||||
{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:white_concrete"},
|
||||
{pos: [4, 1, 0], state: "minecraft:white_concrete"},
|
||||
{pos: [4, 1, 1], state: "minecraft:white_concrete"},
|
||||
{pos: [4, 1, 2], state: "minecraft:white_concrete"},
|
||||
{pos: [4, 1, 3], state: "minecraft:white_concrete"},
|
||||
{pos: [4, 1, 4], state: "minecraft:white_concrete"},
|
||||
{pos: [0, 2, 0], state: "minecraft:white_concrete"},
|
||||
{pos: [0, 2, 1], state: "minecraft:white_concrete"},
|
||||
{pos: [0, 2, 2], state: "minecraft:white_concrete"},
|
||||
{pos: [0, 2, 3], state: "minecraft:white_concrete"},
|
||||
{pos: [0, 2, 4], state: "minecraft:white_concrete"},
|
||||
{pos: [1, 2, 0], state: "minecraft:white_concrete"},
|
||||
{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:white_concrete"},
|
||||
{pos: [2, 2, 0], state: "minecraft:white_concrete"},
|
||||
{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:white_concrete"},
|
||||
{pos: [3, 2, 0], state: "minecraft:white_concrete"},
|
||||
{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:white_concrete"},
|
||||
{pos: [4, 2, 0], state: "minecraft:white_concrete"},
|
||||
{pos: [4, 2, 1], state: "minecraft:white_concrete"},
|
||||
{pos: [4, 2, 2], state: "minecraft:white_concrete"},
|
||||
{pos: [4, 2, 3], state: "minecraft:white_concrete"},
|
||||
{pos: [4, 2, 4], state: "minecraft:white_concrete"},
|
||||
{pos: [0, 3, 0], state: "minecraft:white_concrete"},
|
||||
{pos: [0, 3, 1], state: "minecraft:white_concrete"},
|
||||
{pos: [0, 3, 2], state: "minecraft:white_concrete"},
|
||||
{pos: [0, 3, 3], state: "minecraft:white_concrete"},
|
||||
{pos: [0, 3, 4], state: "minecraft:white_concrete"},
|
||||
{pos: [1, 3, 0], state: "minecraft:white_concrete"},
|
||||
{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:white_concrete"},
|
||||
{pos: [2, 3, 0], state: "minecraft:white_concrete"},
|
||||
{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:white_concrete"},
|
||||
{pos: [3, 3, 0], state: "minecraft:white_concrete"},
|
||||
{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:white_concrete"},
|
||||
{pos: [4, 3, 0], state: "minecraft:white_concrete"},
|
||||
{pos: [4, 3, 1], state: "minecraft:white_concrete"},
|
||||
{pos: [4, 3, 2], state: "minecraft:white_concrete"},
|
||||
{pos: [4, 3, 3], state: "minecraft:white_concrete"},
|
||||
{pos: [4, 3, 4], state: "minecraft:white_concrete"},
|
||||
{pos: [0, 4, 0], state: "minecraft:white_concrete"},
|
||||
{pos: [0, 4, 1], state: "minecraft:white_concrete"},
|
||||
{pos: [0, 4, 2], state: "minecraft:white_concrete"},
|
||||
{pos: [0, 4, 3], state: "minecraft:white_concrete"},
|
||||
{pos: [0, 4, 4], state: "minecraft:white_concrete"},
|
||||
{pos: [1, 4, 0], state: "minecraft:white_concrete"},
|
||||
{pos: [1, 4, 1], state: "minecraft:white_concrete"},
|
||||
{pos: [1, 4, 2], state: "minecraft:white_concrete"},
|
||||
{pos: [1, 4, 3], state: "minecraft:white_concrete"},
|
||||
{pos: [1, 4, 4], state: "minecraft:white_concrete"},
|
||||
{pos: [2, 4, 0], state: "minecraft:white_concrete"},
|
||||
{pos: [2, 4, 1], state: "minecraft:white_concrete"},
|
||||
{pos: [2, 4, 2], state: "minecraft:white_concrete"},
|
||||
{pos: [2, 4, 3], state: "minecraft:white_concrete"},
|
||||
{pos: [2, 4, 4], state: "minecraft:white_concrete"},
|
||||
{pos: [3, 4, 0], state: "minecraft:white_concrete"},
|
||||
{pos: [3, 4, 1], state: "minecraft:white_concrete"},
|
||||
{pos: [3, 4, 2], state: "minecraft:white_concrete"},
|
||||
{pos: [3, 4, 3], state: "minecraft:white_concrete"},
|
||||
{pos: [3, 4, 4], state: "minecraft:white_concrete"},
|
||||
{pos: [4, 4, 0], state: "minecraft:white_concrete"},
|
||||
{pos: [4, 4, 1], state: "minecraft:white_concrete"},
|
||||
{pos: [4, 4, 2], state: "minecraft:white_concrete"},
|
||||
{pos: [4, 4, 3], state: "minecraft:white_concrete"},
|
||||
{pos: [4, 4, 4], state: "minecraft:white_concrete"}
|
||||
],
|
||||
entities: [
|
||||
{blockPos: [2, 2, 3], pos: [2.5d, 2.5d, 3.96875d], nbt: {Air: 300s, CanUpdate: 1b, Facing: 2b, FallDistance: 0.0f, Fire: -1s, Fixed: 0b, Invisible: 0b, Invulnerable: 0b, Item: {Count: 1b, id: "computercraft:printed_page", tag: {Color0: "eeeeeeeeeeeeeeeeeeeeeeeee", Color1: "eeeeeeeeeeeeeeeeeeeeeeeee", Color10: "eeeeeeeeeeeeeeeeeeeeeeeee", Color11: "eeeeeeeeeeeeeeeeeeeeeeeee", Color12: "eeeeeeeeeeeeeeeeeeeeeeeee", Color13: "eeeeeeeeeeeeeeeeeeeeeeeee", Color14: "eeeeeeeeeeeeeeeeeeeeeeeee", Color15: "eeeeeeeeeeeeeeeeeeeeeeeee", Color16: "eeeeeeeeeeeeeeeeeeeeeeeee", Color17: "eeeeeeeeeeeeeeeeeeeeeeeee", Color18: "eeeeeeeeeeeeeeeeeeeeeeeee", Color19: "eeeeeeeeeeeeeeeeeeeeeeeee", Color2: "eeeeeeeeeeeeeeeeeeeeeeeee", Color20: "eeeeeeeeeeeeeeeeeeeeeeeee", Color3: "eeeeeeeeeeeeeeeeeeeeeeeee", Color4: "eeeeeeeeeeeeeeeeeeeeeeeee", Color5: "eeeeeeeeeeeeeeeeeeeeeeeee", Color6: "eeeeeeeeeeeeeeeeeeeeeeeee", Color7: "eeeeeeeeeeeeeeeeeeeeeeeee", Color8: "eeeeeeeeeeeeeeeeeeeeeeeee", Color9: "eeeeeeeeeeeeeeeeeeeeeeeee", Pages: 1, Text0: "If you're reading this, ", Text1: "the test failed. ", Text10: " ", Text11: " ", Text12: " ", Text13: " ", Text14: " ", Text15: " ", Text16: " ", Text17: " ", Text18: " ", Text19: " ", Text2: " ", Text20: " ", Text3: " ", Text4: " ", Text5: " ", Text6: " ", Text7: " ", Text8: " ", Text9: " ", Title: "a.lua"}}, ItemDropChance: 1.0f, ItemRotation: 0b, Motion: [0.0d, 0.0d, 0.0d], OnGround: 0b, PortalCooldown: 0, Pos: [10.5d, 7.5d, 44.96875d], Rotation: [180.0f, 0.0f], TileX: 10, TileY: 7, TileZ: 44, UUID: [I; 1043973837, -2076424529, -1762893135, -165665834], id: "minecraft:item_frame"}},
|
||||
{blockPos: [2, 1, 2], pos: [2.583196949396914d, 1.0d, 2.6089749199596d], nbt: {AbsorptionAmount: 0.0f, Air: 300s, ArmorItems: [{}, {}, {}, {}], Attributes: [{Base: 0.699999988079071d, Name: "minecraft:generic.movement_speed"}], Brain: {memories: {}}, CanUpdate: 1b, CustomName: '{"text":"printouttest.in_frame_at_night"}', DeathTime: 0s, DisabledSlots: 0, FallDistance: 0.0f, FallFlying: 0b, Fire: -1s, HandItems: [{}, {}], Health: 20.0f, HurtByTimestamp: 0, HurtTime: 0s, Invisible: 1b, Invulnerable: 0b, Marker: 1b, Motion: [0.0d, 0.0d, 0.0d], NoBasePlate: 0b, OnGround: 0b, PortalCooldown: 0, Pos: [10.583196949396914d, 6.0d, 43.6089749199596d], Pose: {}, Rotation: [1.3504658f, 6.7031174f], ShowArms: 0b, Small: 0b, UUID: [I; -1917933016, 1390888530, -2109873447, -2136052677], id: "minecraft:armor_stand"}}
|
||||
],
|
||||
palette: [
|
||||
"minecraft:polished_andesite",
|
||||
"minecraft:white_concrete",
|
||||
"minecraft:air"
|
||||
]
|
||||
}
|
||||
@@ -217,9 +217,10 @@ end
|
||||
channel. The message will be received by every device listening to rednet.
|
||||
|
||||
@param message The message to send. This should not contain coroutines or
|
||||
functions, as they will be converted to @{nil}. @tparam[opt] string protocol
|
||||
The "protocol" to send this message under. When using @{rednet.receive} one can
|
||||
filter to only receive messages sent under a particular protocol.
|
||||
functions, as they will be converted to @{nil}.
|
||||
@tparam[opt] string protocol The "protocol" to send this message under. When
|
||||
using @{rednet.receive} one can filter to only receive messages sent under a
|
||||
particular protocol.
|
||||
@see rednet.receive
|
||||
@changed 1.6 Added protocol parameter.
|
||||
@usage Broadcast the words "Hello, world!" to every computer using rednet.
|
||||
|
||||
@@ -1,3 +1,9 @@
|
||||
# New features in CC: Tweaked 1.102.2
|
||||
|
||||
Several bug fixes:
|
||||
* Fix printouts crashing in item frames
|
||||
* Fix disks not being assigned an ID when placed in a disk drive.
|
||||
|
||||
# New features in CC: Tweaked 1.102.1
|
||||
|
||||
Several bug fixes:
|
||||
|
||||
@@ -1,18 +1,7 @@
|
||||
New features in CC: Tweaked 1.102.1
|
||||
New features in CC: Tweaked 1.102.2
|
||||
|
||||
Several bug fixes:
|
||||
* Fix crash on Fabric when refuelling with a non-fuel item (emmachase).
|
||||
* Fix crash when calling `pocket.equipBack()` with a wireless modem.
|
||||
* Fix turtles dropping their inventory when moving (emmachase).
|
||||
* Fix crash when inserting items into a full inventory (emmachase).
|
||||
* Simplify wired cable breaking code, fixing items sometimes not dropping.
|
||||
* Correctly handle double chests being treated as single threads under Fabric.
|
||||
* Fix `mouse_up` not being fired under Fabric.
|
||||
* Fix full-block Wired modems not connecting to adjacent cables when placed.
|
||||
* Hide the search tab from the `itemGroups` item details.
|
||||
* Fix speakers playing too loudly.
|
||||
* Change where turtles drop items from, reducing the chance that items clip through blocks.
|
||||
* Fix the `computer_threads` config option not applying under Fabric.
|
||||
* Fix stack overflow in logging code.
|
||||
* Fix printouts crashing in item frames
|
||||
* Fix disks not being assigned an ID when placed in a disk drive.
|
||||
|
||||
Type "help changelog" to see the full version history.
|
||||
|
||||
@@ -12,20 +12,32 @@ import dan200.computercraft.api.lua.LuaFunction;
|
||||
import dan200.computercraft.api.peripheral.IPeripheral;
|
||||
import dan200.computercraft.core.computer.Computer;
|
||||
import dan200.computercraft.core.computer.ComputerSide;
|
||||
import dan200.computercraft.core.computer.ComputerThread;
|
||||
import dan200.computercraft.core.computer.mainthread.NoWorkMainThreadScheduler;
|
||||
import dan200.computercraft.core.filesystem.FileSystemException;
|
||||
import dan200.computercraft.core.filesystem.WritableFileMount;
|
||||
import dan200.computercraft.core.lua.CobaltLuaMachine;
|
||||
import dan200.computercraft.core.lua.MachineEnvironment;
|
||||
import dan200.computercraft.core.lua.MachineResult;
|
||||
import dan200.computercraft.core.terminal.Terminal;
|
||||
import dan200.computercraft.test.core.computer.BasicEnvironment;
|
||||
import it.unimi.dsi.fastutil.ints.Int2IntArrayMap;
|
||||
import org.junit.jupiter.api.*;
|
||||
import org.junit.jupiter.api.function.Executable;
|
||||
import org.opentest4j.AssertionFailedError;
|
||||
import org.opentest4j.TestAbortedException;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.squiddev.cobalt.*;
|
||||
import org.squiddev.cobalt.debug.DebugFrame;
|
||||
import org.squiddev.cobalt.debug.DebugHook;
|
||||
import org.squiddev.cobalt.debug.DebugState;
|
||||
import org.squiddev.cobalt.function.OneArgFunction;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.net.URI;
|
||||
import java.nio.channels.Channels;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
@@ -36,6 +48,7 @@ import java.util.concurrent.TimeUnit;
|
||||
import java.util.concurrent.locks.Condition;
|
||||
import java.util.concurrent.locks.ReentrantLock;
|
||||
import java.util.regex.Pattern;
|
||||
import java.util.stream.Collectors;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
/**
|
||||
@@ -78,7 +91,7 @@ public class ComputerTestDelegate {
|
||||
|
||||
private final Condition hasFinished = lock.newCondition();
|
||||
private boolean finished = false;
|
||||
private Map<String, Map<Double, Double>> finishedWith;
|
||||
private final Map<LuaString, Int2IntArrayMap> coverage = new HashMap<>();
|
||||
|
||||
@BeforeEach
|
||||
public void before() throws IOException {
|
||||
@@ -99,7 +112,7 @@ public class ComputerTestDelegate {
|
||||
}
|
||||
|
||||
var environment = new BasicEnvironment(mount);
|
||||
context = new ComputerContext(environment, 1, new NoWorkMainThreadScheduler());
|
||||
context = new ComputerContext(environment, new ComputerThread(1), new NoWorkMainThreadScheduler(), CoverageLuaMachine::new);
|
||||
computer = new Computer(context, environment, term, 0);
|
||||
computer.getEnvironment().setPeripheral(ComputerSide.TOP, new FakeModem());
|
||||
computer.getEnvironment().setPeripheral(ComputerSide.BOTTOM, new FakePeripheralHub());
|
||||
@@ -137,10 +150,12 @@ public class ComputerTestDelegate {
|
||||
computer.shutdown();
|
||||
}
|
||||
|
||||
if (finishedWith != null) {
|
||||
if (!coverage.isEmpty()) {
|
||||
Files.createDirectories(REPORT_PATH.getParent());
|
||||
try (var writer = Files.newBufferedWriter(REPORT_PATH)) {
|
||||
new LuaCoverage(finishedWith).write(writer);
|
||||
new LuaCoverage(coverage.entrySet().stream().collect(Collectors.toMap(
|
||||
x -> x.getKey().substring(1).toString(), Map.Entry::getValue
|
||||
))).write(writer);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -414,7 +429,9 @@ public class ComputerTestDelegate {
|
||||
|
||||
switch (status) {
|
||||
case "ok":
|
||||
break;
|
||||
case "pending":
|
||||
runResult = new TestAbortedException("Test is pending");
|
||||
break;
|
||||
case "fail":
|
||||
runResult = new AssertionFailedError(wholeMessage.toString());
|
||||
@@ -432,9 +449,7 @@ public class ComputerTestDelegate {
|
||||
}
|
||||
|
||||
@LuaFunction
|
||||
public final void finish(Optional<Map<?, ?>> result) {
|
||||
@SuppressWarnings("unchecked")
|
||||
var finishedResult = (Map<String, Map<Double, Double>>) result.orElse(null);
|
||||
public final void finish() {
|
||||
LOG.info("Finished");
|
||||
|
||||
// Signal to after that execution has finished
|
||||
@@ -445,7 +460,6 @@ public class ComputerTestDelegate {
|
||||
}
|
||||
try {
|
||||
finished = true;
|
||||
if (finishedResult != null) finishedWith = finishedResult;
|
||||
|
||||
hasFinished.signal();
|
||||
} finally {
|
||||
@@ -453,4 +467,73 @@ public class ComputerTestDelegate {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* A subclass of {@link CobaltLuaMachine} which tracks coverage for executed files.
|
||||
* <p>
|
||||
* This is a super nasty hack, but is also an order of magnitude faster than tracking this in Lua.
|
||||
*/
|
||||
private class CoverageLuaMachine extends CobaltLuaMachine {
|
||||
CoverageLuaMachine(MachineEnvironment environment) {
|
||||
super(environment);
|
||||
}
|
||||
|
||||
@Override
|
||||
public MachineResult loadBios(InputStream bios) {
|
||||
var result = super.loadBios(bios);
|
||||
if (result != MachineResult.OK) return result;
|
||||
|
||||
LuaTable globals;
|
||||
LuaThread mainRoutine;
|
||||
try {
|
||||
var globalField = CobaltLuaMachine.class.getDeclaredField("globals");
|
||||
globalField.setAccessible(true);
|
||||
globals = (LuaTable) globalField.get(this);
|
||||
|
||||
var threadField = CobaltLuaMachine.class.getDeclaredField("mainRoutine");
|
||||
threadField.setAccessible(true);
|
||||
mainRoutine = (LuaThread) threadField.get(this);
|
||||
} catch (ReflectiveOperationException e) {
|
||||
throw new RuntimeException("Cannot get internal Cobalt state", e);
|
||||
}
|
||||
|
||||
var coverage = ComputerTestDelegate.this.coverage;
|
||||
var hook = new DebugHook() {
|
||||
@Override
|
||||
public void onCall(LuaState state, DebugState ds, DebugFrame frame) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onReturn(LuaState state, DebugState ds, DebugFrame frame) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onCount(LuaState state, DebugState ds, DebugFrame frame) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onLine(LuaState state, DebugState ds, DebugFrame frame, int newLine) {
|
||||
if (frame.closure == null) return;
|
||||
|
||||
var proto = frame.closure.getPrototype();
|
||||
if (!proto.source.startsWith('@')) return;
|
||||
|
||||
var map = coverage.computeIfAbsent(proto.source, x -> new Int2IntArrayMap());
|
||||
map.put(newLine, map.get(newLine) + 1);
|
||||
}
|
||||
};
|
||||
|
||||
((LuaTable) globals.rawget("coroutine")).rawset("create", new OneArgFunction() {
|
||||
@Override
|
||||
public LuaValue call(LuaState state, LuaValue arg) throws LuaError {
|
||||
var thread = new LuaThread(state, arg.checkFunction(), state.getCurrentThread().getfenv());
|
||||
thread.getDebugState().setHook(hook, false, true, false, 0);
|
||||
return thread;
|
||||
}
|
||||
});
|
||||
mainRoutine.getDebugState().setHook(hook, false, true, false, 0);
|
||||
|
||||
return MachineResult.OK;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
*/
|
||||
package dan200.computercraft.core;
|
||||
|
||||
import com.google.common.base.Strings;
|
||||
import it.unimi.dsi.fastutil.ints.Int2IntMap;
|
||||
import it.unimi.dsi.fastutil.ints.IntOpenHashSet;
|
||||
import it.unimi.dsi.fastutil.ints.IntSet;
|
||||
import org.slf4j.Logger;
|
||||
@@ -26,24 +26,25 @@ class LuaCoverage {
|
||||
private static final Path ROOT = new File("src/main/resources/data/computercraft/lua").toPath();
|
||||
private static final Path BIOS = ROOT.resolve("bios.lua");
|
||||
private static final Path APIS = ROOT.resolve("rom/apis");
|
||||
private static final Path STARTUP = ROOT.resolve("rom/startup.lua");
|
||||
private static final Path SHELL = ROOT.resolve("rom/programs/shell.lua");
|
||||
private static final Path MULTISHELL = ROOT.resolve("rom/programs/advanced/multishell.lua");
|
||||
private static final Path TREASURE = ROOT.resolve("treasure");
|
||||
|
||||
private final Map<String, Map<Double, Double>> coverage;
|
||||
private final Map<String, Int2IntMap> coverage;
|
||||
private final String blank;
|
||||
private final String zero;
|
||||
private final String countFormat;
|
||||
|
||||
LuaCoverage(Map<String, Map<Double, Double>> coverage) {
|
||||
LuaCoverage(Map<String, Int2IntMap> coverage) {
|
||||
this.coverage = coverage;
|
||||
|
||||
var max = (int) coverage.values().stream()
|
||||
.flatMapToDouble(x -> x.values().stream().mapToDouble(y -> y))
|
||||
var max = coverage.values().stream()
|
||||
.flatMapToInt(x -> x.values().intStream())
|
||||
.max().orElse(0);
|
||||
var maxLen = Math.max(1, (int) Math.ceil(Math.log10(max)));
|
||||
blank = Strings.repeat(" ", maxLen + 1);
|
||||
zero = Strings.repeat("*", maxLen) + "0";
|
||||
blank = " ".repeat(maxLen + 1);
|
||||
zero = "*".repeat(maxLen) + "0";
|
||||
countFormat = "%" + (maxLen + 1) + "d";
|
||||
}
|
||||
|
||||
@@ -56,14 +57,15 @@ class LuaCoverage {
|
||||
var possiblePaths = Stream.of(
|
||||
coverage.remove("/" + full),
|
||||
path.equals(BIOS) ? coverage.remove("bios.lua") : null,
|
||||
path.equals(STARTUP) ? coverage.remove("startup.lua") : null,
|
||||
path.equals(SHELL) ? coverage.remove("shell.lua") : null,
|
||||
path.equals(MULTISHELL) ? coverage.remove("multishell.lua") : null,
|
||||
path.startsWith(APIS) ? coverage.remove(path.getFileName().toString()) : null
|
||||
);
|
||||
var files = possiblePaths
|
||||
.filter(Objects::nonNull)
|
||||
.flatMap(x -> x.entrySet().stream())
|
||||
.collect(Collectors.toUnmodifiableMap(Map.Entry::getKey, Map.Entry::getValue, Double::sum));
|
||||
.flatMap(x -> x.int2IntEntrySet().stream())
|
||||
.collect(Collectors.toUnmodifiableMap(Map.Entry::getKey, Map.Entry::getValue, Integer::sum));
|
||||
|
||||
try {
|
||||
writeCoverageFor(out, path, files);
|
||||
@@ -78,7 +80,7 @@ class LuaCoverage {
|
||||
}
|
||||
}
|
||||
|
||||
private void writeCoverageFor(Writer out, Path fullName, Map<Double, Double> visitedLines) throws IOException {
|
||||
private void writeCoverageFor(Writer out, Path fullName, Map<Integer, Integer> visitedLines) throws IOException {
|
||||
if (!Files.exists(fullName)) {
|
||||
LOG.error("Cannot locate file {}", fullName);
|
||||
return;
|
||||
@@ -96,9 +98,9 @@ class LuaCoverage {
|
||||
var lineNo = 0;
|
||||
while ((line = reader.readLine()) != null) {
|
||||
lineNo++;
|
||||
var count = visitedLines.get((double) lineNo);
|
||||
var count = visitedLines.get(lineNo);
|
||||
if (count != null) {
|
||||
out.write(String.format(countFormat, count.intValue()));
|
||||
out.write(String.format(countFormat, count));
|
||||
} else if (activeLines.contains(lineNo)) {
|
||||
out.write(zero);
|
||||
} else {
|
||||
|
||||
@@ -518,26 +518,9 @@ local function before_each(body)
|
||||
before_each_fns[n], before_each_fns.n = body, n
|
||||
end
|
||||
|
||||
local native_co_create, native_loadfile = coroutine.create, loadfile
|
||||
local native_loadfile = loadfile
|
||||
local line_counts = {}
|
||||
if cct_test then
|
||||
local string_sub, debug_getinfo = string.sub, debug.getinfo
|
||||
local function debug_hook(_, line_nr)
|
||||
local name = debug_getinfo(2, "S").source
|
||||
if string_sub(name, 1, 1) ~= "@" then return end
|
||||
name = string_sub(name, 2)
|
||||
|
||||
local file = line_counts[name]
|
||||
if not file then file = {} line_counts[name] = file end
|
||||
file[line_nr] = (file[line_nr] or 0) + 1
|
||||
end
|
||||
|
||||
coroutine.create = function(...)
|
||||
local co = native_co_create(...)
|
||||
debug.sethook(co, debug_hook, "l")
|
||||
return co
|
||||
end
|
||||
|
||||
local expect = require "cc.expect".expect
|
||||
_G.native_loadfile = native_loadfile
|
||||
_G.loadfile = function(filename, mode, env)
|
||||
@@ -557,8 +540,6 @@ if cct_test then
|
||||
file.close()
|
||||
return func, err
|
||||
end
|
||||
|
||||
debug.sethook(debug_hook, "l")
|
||||
end
|
||||
|
||||
local arg = ...
|
||||
@@ -736,8 +717,6 @@ end
|
||||
term.setTextColour(colours.white) io.write(info .. "\n")
|
||||
|
||||
-- Restore hook stubs
|
||||
debug.sethook(nil, "l")
|
||||
coroutine.create = native_co_create
|
||||
_G.loadfile = native_loadfile
|
||||
|
||||
if cct_test then cct_test.finish(line_counts) end
|
||||
|
||||
@@ -25,6 +25,9 @@ class ItemFrameRendererMixin {
|
||||
)
|
||||
@SuppressWarnings("UnusedMethod")
|
||||
private void render(ItemFrame entity, float yaw, float partialTicks, PoseStack pose, MultiBufferSource buffers, int light, CallbackInfo ci) {
|
||||
if (ClientHooks.onRenderItemFrame(pose, buffers, entity, entity.getItem(), light)) ci.cancel();
|
||||
if (ClientHooks.onRenderItemFrame(pose, buffers, entity, entity.getItem(), light)) {
|
||||
ci.cancel();
|
||||
pose.popPose();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user