Merge branch 'mc1.20.1/feature-dev' into jay/mc1.20.1/attached-registry-refactors

# Conflicts:
#	src/main/java/com/simibubi/create/AllBlocks.java
#	src/main/java/com/simibubi/create/api/contraption/train/TrainConductorHandler.java
#	src/main/java/com/simibubi/create/api/contraption/transformable/ContraptionTransformableRegistry.java
#	src/main/java/com/simibubi/create/api/schematic/requirement/SchematicRequirementsRegistry.java
#	src/main/java/com/simibubi/create/content/contraptions/StructureTransform.java
#	src/main/java/com/simibubi/create/content/schematics/requirement/ItemRequirement.java
#	src/main/java/com/simibubi/create/foundation/utility/BlockHelper.java
#	src/main/java/com/simibubi/create/impl/contraption/transformable/ContraptionTransformableRegistryImpl.java
#	src/main/java/com/simibubi/create/impl/schematic/requirement/SchematicRequirementsRegistryImpl.java
This commit is contained in:
TropheusJ 2025-02-12 08:14:26 -05:00
commit f6f8ea9c73
70 changed files with 426 additions and 292 deletions

View file

@ -17,7 +17,6 @@ import static com.simibubi.create.foundation.data.TagGen.tagBlockAndItem;
import com.simibubi.create.AllTags.AllBlockTags;
import com.simibubi.create.AllTags.AllItemTags;
import com.simibubi.create.api.contraption.train.TrainConductorHandler;
import com.simibubi.create.content.contraptions.actors.contraptionControls.ContraptionControlsBlock;
import com.simibubi.create.content.contraptions.actors.contraptionControls.ContraptionControlsMovement;
import com.simibubi.create.content.contraptions.actors.contraptionControls.ContraptionControlsMovingInteraction;
@ -289,6 +288,7 @@ import com.simibubi.create.foundation.item.ItemDescription;
import com.simibubi.create.foundation.item.UncontainableBlockItem;
import com.simibubi.create.foundation.utility.ColorHandlers;
import com.simibubi.create.foundation.utility.DyeHelper;
import com.simibubi.create.impl.contraption.train.TrainConductorHandlerImpl;
import com.tterrag.registrate.providers.RegistrateRecipeProvider;
import com.tterrag.registrate.providers.loot.RegistrateBlockLootTables;
import com.tterrag.registrate.util.DataIngredient;
@ -768,7 +768,7 @@ public class AllBlocks {
.loot((lt, block) -> lt.add(block, BlazeBurnerBlock.buildLootTable()))
.blockstate((c, p) -> p.simpleBlock(c.getEntry(), AssetLookup.partialBaseModel(c, p)))
.onRegister(movementBehaviour(new BlazeBurnerMovementBehaviour()))
.onRegister(TrainConductorHandler::registerBlazeBurner)
.onRegister(block -> TrainConductorHandlerImpl.registerBlazeBurner())
.item(BlazeBurnerBlockItem::withBlaze)
.model(AssetLookup.customBlockItemModel("blaze_burner", "block_with_blaze"))
.build()

View file

@ -1,16 +1,11 @@
package com.simibubi.create.api.contraption.train;
import java.util.ArrayList;
import java.util.List;
import java.util.function.Consumer;
import java.util.function.Predicate;
import org.jetbrains.annotations.ApiStatus;
import com.simibubi.create.AllBlocks;
import com.simibubi.create.AllInteractionBehaviours;
import com.simibubi.create.content.processing.burner.BlazeBurnerBlock;
import com.simibubi.create.content.processing.burner.BlockBasedTrainConductorInteractionBehaviour;
import com.simibubi.create.impl.contraption.train.TrainConductorHandlerImpl;
import net.minecraft.world.level.block.Block;
import net.minecraft.world.level.block.state.BlockState;
@ -21,13 +16,10 @@ import net.minecraft.world.level.block.state.BlockState;
*/
@FunctionalInterface
public interface TrainConductorHandler {
@ApiStatus.Internal
List<TrainConductorHandler> CONDUCTOR_HANDLERS = new ArrayList<>();
boolean isValidConductor(BlockState state);
private static void registerHandler(TrainConductorHandler handler) {
CONDUCTOR_HANDLERS.add(handler);
TrainConductorHandlerImpl.CONDUCTOR_HANDLERS.add(handler);
}
static void registerConductor(Block block, Predicate<BlockState> isValidConductor, UpdateScheduleCallback updateScheduleCallback) {
@ -36,13 +28,6 @@ public interface TrainConductorHandler {
registerHandler(isValidConductor::test);
}
@ApiStatus.Internal
static void registerBlazeBurner(Block block) {
registerConductor(block, blockState -> AllBlocks.BLAZE_BURNER.has(blockState)
&& blockState.getValue(BlazeBurnerBlock.HEAT_LEVEL) != BlazeBurnerBlock.HeatLevel.NONE, UpdateScheduleCallback.EMPTY);
}
@FunctionalInterface
interface UpdateScheduleCallback {
UpdateScheduleCallback EMPTY = (hasSchedule, blockState, blockStateSetter) -> {};

View file

@ -1,7 +0,0 @@
package com.simibubi.create.api.contraption.transformable;
import com.simibubi.create.content.contraptions.StructureTransform;
public interface ITransformableBlockEntity {
void transform(StructureTransform transform);
}

View file

@ -4,6 +4,7 @@ import com.simibubi.create.content.contraptions.StructureTransform;
import net.minecraft.world.level.block.state.BlockState;
public interface ITransformableBlock {
@FunctionalInterface
public interface TransformableBlock {
BlockState transform(BlockState state, StructureTransform transform);
}

View file

@ -0,0 +1,9 @@
package com.simibubi.create.api.contraption.transformable;
import com.simibubi.create.content.contraptions.StructureTransform;
import net.minecraft.world.level.block.entity.BlockEntity;
public interface TransformableBlockEntity {
void transform(BlockEntity blockEntity, StructureTransform transform);
}

View file

@ -2,7 +2,7 @@ package com.simibubi.create.api.schematic.nbt;
import net.minecraft.nbt.CompoundTag;
public interface IPartialSafeNBT {
public interface PartialSafeNBT {
/**
* This will always be called from the logical server
*/

View file

@ -4,6 +4,6 @@ import com.simibubi.create.content.schematics.requirement.ItemRequirement;
import net.minecraft.world.level.block.state.BlockState;
public interface ISpecialBlockEntityItemRequirement {
public interface SpecialBlockEntityItemRequirement {
ItemRequirement getRequiredItems(BlockState state);
}

View file

@ -1,10 +1,12 @@
package com.simibubi.create.api.schematic.requirement;
import org.jetbrains.annotations.Nullable;
import com.simibubi.create.content.schematics.requirement.ItemRequirement;
import net.minecraft.world.level.block.entity.BlockEntity;
import net.minecraft.world.level.block.state.BlockState;
public interface ISpecialBlockItemRequirement {
ItemRequirement getRequiredItems(BlockState state, BlockEntity blockEntity);
public interface SpecialBlockItemRequirement {
ItemRequirement getRequiredItems(BlockState state, @Nullable BlockEntity blockEntity);
}

View file

@ -2,6 +2,6 @@ package com.simibubi.create.api.schematic.requirement;
import com.simibubi.create.content.schematics.requirement.ItemRequirement;
public interface ISpecialEntityItemRequirement {
public interface SpecialEntityItemRequirement {
ItemRequirement getRequiredItems();
}

View file

@ -20,7 +20,6 @@ public enum Mods {
AETHER,
BETTEREND,
COMPUTERCRAFT,
CONNECTIVITY,
CURIOS,
DYNAMICTREES,
FUNCTIONALSTORAGE,

View file

@ -9,6 +9,7 @@ import com.simibubi.create.infrastructure.config.AllConfigs;
import dev.ftb.mods.ftbchunks.client.gui.LargeMapScreen;
import dev.ftb.mods.ftbchunks.client.gui.RegionMapPanel;
import dev.ftb.mods.ftblibrary.ui.BaseScreen;
import dev.ftb.mods.ftblibrary.ui.ScreenWrapper;
import dev.ftb.mods.ftblibrary.ui.Widget;
import net.minecraft.client.Minecraft;
@ -152,7 +153,7 @@ public class FTBChunksTrainMap {
private static LargeMapScreen getAsLargeMapScreen(Screen screen) {
if (!(screen instanceof ScreenWrapper screenWrapper))
return null;
Object wrapped = ObfuscationReflectionHelper.getPrivateValue(ScreenWrapper.class, screenWrapper, "wrappedGui");
BaseScreen wrapped = screenWrapper.getGui();
if (!(wrapped instanceof LargeMapScreen largeMapScreen))
return null;
return largeMapScreen;

View file

@ -18,13 +18,13 @@ import com.simibubi.create.AllItems;
import com.simibubi.create.AllMovementBehaviours;
import com.simibubi.create.AllPackets;
import com.simibubi.create.AllSoundEvents;
import com.simibubi.create.Create;
import com.simibubi.create.content.contraptions.actors.psi.PortableStorageInterfaceMovement;
import com.simibubi.create.content.contraptions.actors.seat.SeatBlock;
import com.simibubi.create.content.contraptions.actors.seat.SeatEntity;
import com.simibubi.create.content.contraptions.actors.trainControls.ControlsStopControllingPacket;
import com.simibubi.create.content.contraptions.behaviour.MovementBehaviour;
import com.simibubi.create.content.contraptions.behaviour.MovementContext;
import com.simibubi.create.content.contraptions.data.ContraptionSyncLimiting;
import com.simibubi.create.content.contraptions.elevator.ElevatorContraption;
import com.simibubi.create.content.contraptions.glue.SuperGlueEntity;
import com.simibubi.create.content.contraptions.mounted.MountedContraption;
@ -615,11 +615,8 @@ public abstract class AbstractContraptionEntity extends Entity implements IEntit
CompoundTag compound = new CompoundTag();
writeAdditional(compound, true);
if (ContraptionData.isTooLargeForSync(compound)) {
String info = getContraption().getType().id + " @" + position() + " (" + getStringUUID() + ")";
Create.LOGGER.warn("Could not send Contraption Spawn Data (Packet too big): " + info);
compound = null;
}
if (ContraptionSyncLimiting.isTooLargeForSync(compound))
compound = null; // don't sync contraption data
buffer.writeNbt(compound);
}

View file

@ -91,6 +91,7 @@ import net.minecraft.nbt.ListTag;
import net.minecraft.nbt.NbtUtils;
import net.minecraft.nbt.Tag;
import net.minecraft.network.protocol.game.DebugPackets;
import net.minecraft.resources.ResourceLocation;
import net.minecraft.server.level.ServerLevel;
import net.minecraft.world.entity.Entity;
import net.minecraft.world.entity.ai.village.poi.PoiTypes;
@ -106,6 +107,7 @@ import net.minecraft.world.level.block.PressurePlateBlock;
import net.minecraft.world.level.block.Rotation;
import net.minecraft.world.level.block.SimpleWaterloggedBlock;
import net.minecraft.world.level.block.entity.BlockEntity;
import net.minecraft.world.level.block.entity.BlockEntityType;
import net.minecraft.world.level.block.state.BlockState;
import net.minecraft.world.level.block.state.properties.BlockStateProperties;
import net.minecraft.world.level.block.state.properties.ChestType;
@ -138,6 +140,7 @@ public abstract class Contraption {
public boolean disassembled;
protected Map<BlockPos, StructureBlockInfo> blocks;
protected Map<BlockPos, CompoundTag> updateTags;
protected List<MutablePair<StructureBlockInfo, MovementContext>> actors;
protected Map<BlockPos, MovingInteractionBehaviour> interactors;
protected List<ItemStack> disabledActors;
@ -165,6 +168,7 @@ public abstract class Contraption {
public Contraption() {
blocks = new HashMap<>();
updateTags = new HashMap<>();
seats = new ArrayList<>();
actors = new ArrayList<>();
disabledActors = new ArrayList<>();
@ -645,6 +649,15 @@ public abstract class Contraption {
bounds = bounds.minmax(new AABB(localPos));
BlockEntity be = pair.getValue();
if (be != null) {
CompoundTag updateTag = be.getUpdateTag();
// the ID needs to be in the tag so the client can properly add the BlockEntity
ResourceLocation id = Objects.requireNonNull(BlockEntityType.getKey(be.getType()));
updateTag.putString("id", id.toString());
updateTags.put(localPos, updateTag);
}
storage.addBlock(level, state, pos, localPos, be);
captureMultiblock(localPos, structureBlockInfo, be);
@ -787,7 +800,7 @@ public abstract class Contraption {
CompoundTag nbt = new CompoundTag();
nbt.putString("Type", getType().id);
CompoundTag blocksNBT = writeBlocksCompound();
CompoundTag blocksNBT = writeBlocksCompound(spawnPacket);
ListTag multiblocksNBT = new ListTag();
capturedMultiblocks.keySet().forEach(controllerPos -> {
@ -872,7 +885,7 @@ public abstract class Contraption {
storage.write(nbt, spawnPacket);
}
private CompoundTag writeBlocksCompound() {
private CompoundTag writeBlocksCompound(boolean spawnPacket) {
CompoundTag compound = new CompoundTag();
HashMapPalette<BlockState> palette = new HashMapPalette<>(GameData.getBlockStateIDMap(), 16, (i, s) -> {
throw new IllegalStateException("Palette Map index exceeded maximum");
@ -881,11 +894,30 @@ public abstract class Contraption {
for (StructureBlockInfo block : this.blocks.values()) {
int id = palette.idFor(block.state());
BlockPos pos = block.pos();
CompoundTag c = new CompoundTag();
c.putLong("Pos", block.pos().asLong());
c.putLong("Pos", pos.asLong());
c.putInt("State", id);
if (block.nbt() != null)
CompoundTag updateTag = updateTags.get(pos);
if (spawnPacket) {
// for client sync, treat the updateTag as the data
if (updateTag != null) {
c.put("Data", updateTag);
}
// legacy: use full data if update tag is not available
if (updateTag == null && block.nbt() != null) {
c.put("Data", block.nbt());
}
} else {
// otherwise, write actual data as the data, save updateTag on its own
if (block.nbt() != null) {
c.put("Data", block.nbt());
}
if (updateTag != null) {
c.put("UpdateTag", updateTag);
}
}
blockList.add(c);
}
@ -928,6 +960,13 @@ public abstract class Contraption {
this.blocks.put(info.pos(), info);
if (c.contains("UpdateTag", Tag.TAG_COMPOUND)) {
CompoundTag updateTag = c.getCompound("UpdateTag");
if (!updateTag.isEmpty()) {
this.updateTags.put(info.pos(), updateTag);
}
}
if (!world.isClientSide)
return;

View file

@ -1,85 +0,0 @@
package com.simibubi.create.content.contraptions;
import com.simibubi.create.compat.Mods;
import com.simibubi.create.foundation.mixin.accessor.NbtAccounterAccessor;
import com.simibubi.create.infrastructure.config.AllConfigs;
import io.netty.buffer.Unpooled;
import net.minecraft.nbt.CompoundTag;
import net.minecraft.nbt.NbtAccounter;
import net.minecraft.network.FriendlyByteBuf;
import net.minecraft.network.protocol.game.ClientboundContainerSetSlotPacket;
public class ContraptionData {
/**
* A sane, default maximum for contraption data size.
*/
public static final int DEFAULT_LIMIT = 2_000_000;
/**
* Connectivity expands the NBT packet limit to 2 GB.
*/
public static final int CONNECTIVITY_LIMIT = Integer.MAX_VALUE;
/**
* Packet Fixer expands the NBT packet limit to 200 MB.
*/
public static final int PACKET_FIXER_LIMIT = 209_715_200;
/**
* XL Packets expands the NBT packet limit to 2 GB.
*/
public static final int XL_PACKETS_LIMIT = 2_000_000_000;
/**
* Minecart item sizes are limited by the vanilla slot change packet ({@link ClientboundContainerSetSlotPacket}).
* {@link #DEFAULT_LIMIT} is used as the default.
* Connectivity, PacketFixer, and XL Packets expand the size limit.
* If one of these mods is loaded, we take advantage of it and use the higher limit.
*/
public static final int PICKUP_LIMIT;
static {
int limit = DEFAULT_LIMIT;
// Check from largest to smallest to use the smallest limit if multiple mods are loaded.
// It is necessary to use the smallest limit because even if multiple mods are loaded,
// not all of their mixins may be applied. Therefore, it is safest to only assume that
// the mod with the smallest limit is actually active.
if (Mods.CONNECTIVITY.isLoaded()) {
limit = CONNECTIVITY_LIMIT;
}
if (Mods.XLPACKETS.isLoaded()) {
limit = XL_PACKETS_LIMIT;
}
if (Mods.PACKETFIXER.isLoaded()) {
limit = PACKET_FIXER_LIMIT;
}
PICKUP_LIMIT = limit;
}
/**
* @return true if the given NBT is too large for a contraption to be synced to clients.
*/
public static boolean isTooLargeForSync(CompoundTag data) {
int max = AllConfigs.server().kinetics.maxDataSize.get();
return max != 0 && packetSize(data) > max;
}
/**
* @return true if the given NBT is too large for a contraption to be picked up with a wrench.
*/
public static boolean isTooLargeForPickup(CompoundTag data) {
return packetSize(data) > PICKUP_LIMIT;
}
/**
* @return the size of the given NBT when put through a packet, in bytes.
*/
public static long packetSize(CompoundTag data) {
FriendlyByteBuf test = new FriendlyByteBuf(Unpooled.buffer());
test.writeNbt(data);
NbtAccounter sizeTracker = new NbtAccounter(Long.MAX_VALUE);
test.readNbt(sizeTracker);
long size = ((NbtAccounterAccessor) sizeTracker).create$getUsage();
test.release();
return size;
}
}

View file

@ -4,8 +4,8 @@ import static net.minecraft.world.level.block.state.properties.BlockStatePropert
import static net.minecraft.world.level.block.state.properties.BlockStateProperties.FACING;
import static net.minecraft.world.level.block.state.properties.BlockStateProperties.HORIZONTAL_FACING;
import com.simibubi.create.api.contraption.transformable.ITransformableBlock;
import com.simibubi.create.api.contraption.transformable.ITransformableBlockEntity;
import com.simibubi.create.api.contraption.transformable.TransformableBlock;
import com.simibubi.create.api.contraption.transformable.TransformableBlockEntity;
import com.simibubi.create.api.contraption.transformable.MovedBlockTransformerRegistries;
import com.simibubi.create.api.contraption.transformable.MovedBlockTransformerRegistries.BlockEntityTransformer;
import com.simibubi.create.api.contraption.transformable.MovedBlockTransformerRegistries.BlockTransformer;
@ -137,7 +137,7 @@ public class StructureTransform {
BlockEntityTransformer transformer = MovedBlockTransformerRegistries.BLOCK_ENTITY_TRANSFORMERS.get(be.getType());
if (transformer != null) {
transformer.transform(be, this);
} else if (be instanceof ITransformableBlockEntity itbe) {
} else if (be instanceof TransformableBlockEntity itbe) {
itbe.transform(this);
}
}
@ -152,7 +152,7 @@ public class StructureTransform {
BlockTransformer transformer = MovedBlockTransformerRegistries.BLOCK_TRANSFORMERS.get(block);
if (transformer != null) {
return transformer.transform(block, state, this);
} else if (block instanceof ITransformableBlock transformable) {
} else if (block instanceof TransformableBlock transformable) {
return transformable.transform(state, this);
}

View file

@ -3,7 +3,7 @@ package com.simibubi.create.content.contraptions.chassis;
import com.simibubi.create.AllBlockEntityTypes;
import com.simibubi.create.AllItems;
import com.simibubi.create.AllSoundEvents;
import com.simibubi.create.api.contraption.transformable.ITransformableBlock;
import com.simibubi.create.api.contraption.transformable.TransformableBlock;
import com.simibubi.create.content.contraptions.StructureTransform;
import com.simibubi.create.content.equipment.wrench.IWrenchable;
import com.simibubi.create.foundation.block.IBE;
@ -29,7 +29,7 @@ import net.minecraft.world.phys.Vec3;
import net.minecraftforge.common.Tags;
public abstract class AbstractChassisBlock extends RotatedPillarBlock implements IWrenchable, IBE<ChassisBlockEntity>, ITransformableBlock {
public abstract class AbstractChassisBlock extends RotatedPillarBlock implements IWrenchable, IBE<ChassisBlockEntity>, TransformableBlock {
public AbstractChassisBlock(Properties properties) {
super(properties);

View file

@ -0,0 +1,55 @@
package com.simibubi.create.content.contraptions.data;
import com.simibubi.create.compat.Mods;
import com.simibubi.create.foundation.mixin.accessor.NbtAccounterAccessor;
import io.netty.buffer.Unpooled;
import net.minecraft.Util;
import net.minecraft.nbt.CompoundTag;
import net.minecraft.nbt.NbtAccounter;
import net.minecraft.network.FriendlyByteBuf;
public class ContraptionPickupLimiting {
/// The default NBT limit, defined by {@link FriendlyByteBuf#readNbt()}.
public static final int NBT_LIMIT = 2_097_152;
// increased nbt limits provided by other mods.
public static final int PACKET_FIXER_LIMIT = NBT_LIMIT * 100;
public static final int XL_PACKETS_LIMIT = Integer.MAX_VALUE;
// leave some space for the rest of the packet.
public static final int BUFFER = 20_000;
// the actual limit to be used
public static final int LIMIT = Util.make(() -> {
// the smallest limit needs to be used, as we can't guarantee that all mixins are applied if multiple are present.
if (Mods.PACKETFIXER.isLoaded()) {
return PACKET_FIXER_LIMIT;
} else if (Mods.XLPACKETS.isLoaded()) {
return XL_PACKETS_LIMIT;
}
// none are present, use vanilla default
return NBT_LIMIT;
}) - BUFFER;
/**
* @return true if the given NBT is too large for a contraption to be picked up with a wrench.
*/
public static boolean isTooLargeForPickup(CompoundTag data) {
return nbtSize(data) > LIMIT;
}
/**
* @return the size of the given NBT when read by the client according to {@link NbtAccounter}
*/
private static long nbtSize(CompoundTag data) {
FriendlyByteBuf test = new FriendlyByteBuf(Unpooled.buffer());
test.writeNbt(data);
NbtAccounter sizeTracker = new NbtAccounter(Long.MAX_VALUE);
test.readNbt(sizeTracker);
long size = ((NbtAccounterAccessor) sizeTracker).create$getUsage();
test.release();
return size;
}
}

View file

@ -0,0 +1,52 @@
package com.simibubi.create.content.contraptions.data;
import com.simibubi.create.compat.Mods;
import io.netty.buffer.Unpooled;
import net.minecraft.Util;
import net.minecraft.nbt.CompoundTag;
import net.minecraft.network.FriendlyByteBuf;
public class ContraptionSyncLimiting {
/**
* Contraption entity sync is limited by the clientbound custom payload limit, since that's what Forge's
* extended spawn packet uses. The NBT limit is irrelevant since it's bypassed on deserialization.
*/
public static final int SIZE_LIMIT = 1_048_576;
// increased packet limits provided by other mods.
public static final int PACKET_FIXER_LIMIT = SIZE_LIMIT * 100;
public static final int XL_PACKETS_LIMIT = Integer.MAX_VALUE;
// leave some room for the rest of the packet.
public static final int BUFFER = 20_000;
// the actual limit to be used
public static final int LIMIT = Util.make(() -> {
// the smallest limit needs to be used, as we can't guarantee that all mixins are applied if multiple are present.
if (Mods.PACKETFIXER.isLoaded()) {
return PACKET_FIXER_LIMIT;
} else if (Mods.XLPACKETS.isLoaded()) {
return XL_PACKETS_LIMIT;
}
// none are present, use vanilla default
return SIZE_LIMIT;
}) - BUFFER;
/**
* @return true if the given NBT is too large for a contraption to be synced to clients.
*/
public static boolean isTooLargeForSync(CompoundTag data) {
return byteSize(data) > LIMIT;
}
/**
* @return the size of the given NBT when encoded, in bytes
*/
private static long byteSize(CompoundTag data) {
FriendlyByteBuf test = new FriendlyByteBuf(Unpooled.buffer());
test.writeNbt(data);
return test.writerIndex();
}
}

View file

@ -0,0 +1,37 @@
# Data Limiting
This pair of classes prevents clients from getting chunkbanned when contraptions are too large.
This information is up-to-date as of 1.20.1.
There's a few different packet limits in play:
- the NBT limit: `2_097_152`, enforced by `FriendlyByteBuf.readNbt()`
- the clientbound custom payload limit: `1_048_576` bytes, applies to `ClientboundCustomPayloadPacket`
- the serverbound custom payload limit: `32767` bytes, applies to `ServerboundCustomPayloadPacket`
- the packet limit: `8_388_608` bytes, applies to all packets
# NBT Size vs Bytes
There's two units in play as well - NBT Size and Bytes. The NBT limit uses NBT size, while the other
three use bytes. I'm (TropheusJ) not sure what exactly an NBT Size unit is - it's not bits, but it's
close.
Because of this discrepancy, the NBT limit is actually much lower than it seems. It will usually be
the first limit hit.
Bytes are found by writing a tag to a buffer and getting its `writerIndex`. NBT Size is found using
an `NbtAccounter`.
# Sync
Sync is pretty straightforward.
The only limit relevant here is the clientbound custom payload limit. The NBT limit would be relevant, but
client-side deserialization bypasses it.
Sync is much less of an issue compared to pickup, since a lot of data can be skipped when syncing.
# Pickup
Two limits are relevant for pickup: the NBT limit and the packet limit.
The NBT limit is hit way sooner, and is usually the limiting factor. Other mods may increase it, in
which case the packet limit may become relevant.
The custom payload limit is not relevant since item sync goes through the vanilla `ClientboundContainerSetSlotPacket`.

View file

@ -1,16 +1,21 @@
package com.simibubi.create.content.contraptions.elevator;
import java.util.Optional;
import javax.annotation.Nullable;
import com.simibubi.create.AllBlockEntityTypes;
import com.simibubi.create.AllBlocks;
import com.simibubi.create.AllItems;
import com.simibubi.create.api.schematic.requirement.SpecialBlockItemRequirement;
import com.simibubi.create.content.contraptions.elevator.ElevatorColumn.ColumnCoords;
import com.simibubi.create.content.redstone.contact.RedstoneContactBlock;
import com.simibubi.create.content.redstone.diodes.BrassDiodeBlock;
import com.simibubi.create.api.schematic.requirement.ISpecialBlockItemRequirement;
import com.simibubi.create.content.schematics.requirement.ItemRequirement;
import com.simibubi.create.foundation.block.IBE;
import com.simibubi.create.foundation.block.WrenchableDirectionalBlock;
import com.simibubi.create.foundation.utility.BlockHelper;
import net.createmod.catnip.gui.ScreenOpener;
import net.minecraft.client.player.LocalPlayer;
import net.minecraft.core.BlockPos;
@ -35,15 +40,13 @@ import net.minecraft.world.level.block.state.StateDefinition.Builder;
import net.minecraft.world.level.block.state.properties.BlockStateProperties;
import net.minecraft.world.level.block.state.properties.BooleanProperty;
import net.minecraft.world.phys.BlockHitResult;
import net.minecraftforge.api.distmarker.Dist;
import net.minecraftforge.api.distmarker.OnlyIn;
import net.minecraftforge.fml.DistExecutor;
import javax.annotation.Nullable;
import java.util.Optional;
public class ElevatorContactBlock extends WrenchableDirectionalBlock
implements IBE<ElevatorContactBlockEntity>, ISpecialBlockItemRequirement {
implements IBE<ElevatorContactBlockEntity>, SpecialBlockItemRequirement {
public static final BooleanProperty POWERED = BlockStateProperties.POWERED;
public static final BooleanProperty CALLING = BooleanProperty.create("calling");

View file

@ -8,7 +8,7 @@ import com.simibubi.create.AllBlocks;
import com.simibubi.create.AllEntityTypes;
import com.simibubi.create.AllItems;
import com.simibubi.create.AllSoundEvents;
import com.simibubi.create.api.schematic.requirement.ISpecialEntityItemRequirement;
import com.simibubi.create.api.schematic.requirement.SpecialEntityItemRequirement;
import com.simibubi.create.content.contraptions.BlockMovementChecks;
import com.simibubi.create.content.contraptions.bearing.BearingBlock;
import com.simibubi.create.content.contraptions.chassis.AbstractChassisBlock;
@ -56,7 +56,7 @@ import net.minecraft.world.phys.Vec3;
import net.minecraftforge.entity.IEntityAdditionalSpawnData;
import net.minecraftforge.network.NetworkHooks;
public class SuperGlueEntity extends Entity implements IEntityAdditionalSpawnData, ISpecialEntityItemRequirement {
public class SuperGlueEntity extends Entity implements IEntityAdditionalSpawnData, SpecialEntityItemRequirement {
public static AABB span(BlockPos startPos, BlockPos endPos) {
return new AABB(startPos, endPos).expandTowards(1, 1, 1);

View file

@ -1,14 +1,21 @@
package com.simibubi.create.content.contraptions.mounted;
import java.util.ArrayList;
import java.util.List;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
import com.simibubi.create.AllBlockEntityTypes;
import com.simibubi.create.AllBlocks;
import com.simibubi.create.AllShapes;
import com.simibubi.create.api.schematic.requirement.SpecialBlockItemRequirement;
import com.simibubi.create.content.equipment.wrench.IWrenchable;
import com.simibubi.create.content.redstone.rail.ControllerRailBlock;
import com.simibubi.create.api.schematic.requirement.ISpecialBlockItemRequirement;
import com.simibubi.create.content.schematics.requirement.ItemRequirement;
import com.simibubi.create.content.schematics.requirement.ItemRequirement.ItemUseType;
import com.simibubi.create.foundation.block.IBE;
import net.minecraft.core.BlockPos;
import net.minecraft.core.Direction;
import net.minecraft.core.Direction.Axis;
@ -52,13 +59,8 @@ import net.minecraft.world.phys.shapes.EntityCollisionContext;
import net.minecraft.world.phys.shapes.Shapes;
import net.minecraft.world.phys.shapes.VoxelShape;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
import java.util.ArrayList;
import java.util.List;
public class CartAssemblerBlock extends BaseRailBlock
implements IBE<CartAssemblerBlockEntity>, IWrenchable, ISpecialBlockItemRequirement {
implements IBE<CartAssemblerBlockEntity>, IWrenchable, SpecialBlockItemRequirement {
public static final BooleanProperty POWERED = BlockStateProperties.POWERED;
public static final BooleanProperty BACKWARDS = BooleanProperty.create("backwards");

View file

@ -10,11 +10,11 @@ import com.simibubi.create.AllItems;
import com.simibubi.create.AllMovementBehaviours;
import com.simibubi.create.content.contraptions.AbstractContraptionEntity;
import com.simibubi.create.content.contraptions.Contraption;
import com.simibubi.create.content.contraptions.ContraptionData;
import com.simibubi.create.content.contraptions.ContraptionMovementSetting;
import com.simibubi.create.content.contraptions.OrientedContraptionEntity;
import com.simibubi.create.content.contraptions.actors.psi.PortableStorageInterfaceMovement;
import com.simibubi.create.content.contraptions.behaviour.MovementContext;
import com.simibubi.create.content.contraptions.data.ContraptionPickupLimiting;
import com.simibubi.create.content.kinetics.deployer.DeployerFakePlayer;
import com.simibubi.create.foundation.advancement.AllAdvancements;
import com.simibubi.create.foundation.utility.CreateLang;
@ -249,7 +249,7 @@ public class MinecartContraptionItem extends Item {
ItemStack generatedStack = create(type, oce).setHoverName(entity.getCustomName());
if (ContraptionData.isTooLargeForPickup(generatedStack.serializeNBT())) {
if (ContraptionPickupLimiting.isTooLargeForPickup(generatedStack.serializeNBT())) {
MutableComponent message = CreateLang.translateDirect("contraption.minecart_contraption_too_big")
.withStyle(ChatFormatting.RED);
player.displayClientMessage(message, true);

View file

@ -173,7 +173,8 @@ public class RadialWrenchMenu extends AbstractSimiScreen {
@Override
public void tick() {
ticksOpen++;
if (!level.getBlockState(pos).is(state.getBlock()))
Minecraft.getInstance().setScreen(null);
super.tick();
}
@ -184,8 +185,6 @@ public class RadialWrenchMenu extends AbstractSimiScreen {
PoseStack ms = graphics.pose();
LocalPlayer player = Minecraft.getInstance().player;
ms.pushPose();
ms.translate(x, y, 0);
@ -271,6 +270,8 @@ public class RadialWrenchMenu extends AbstractSimiScreen {
.translateY(-(sectorWidth / 2f + innerRadius))
.rotateZDegrees(-i * sectorAngle);
poseStack.translate(0, 0, 100);
try {
GuiGameElement.of(blockState, blockEntity)
.rotateBlock(player.getXRot(), player.getYRot() + 180, 0f)

View file

@ -40,6 +40,9 @@ public class RadialWrenchMenuSubmitPacket extends SimplePacketBase {
ServerPlayer player = context.getSender();
Level level = player.level();
if (!level.getBlockState(blockPos).is(newState.getBlock()))
return;
BlockState updatedState = Block.updateFromNeighbourShapes(newState, level, blockPos);
KineticBlockEntity.switchToBlockState(level, blockPos, updatedState);

View file

@ -3,9 +3,9 @@ package com.simibubi.create.content.decoration.copycat;
import java.util.List;
import com.simibubi.create.AllBlocks;
import com.simibubi.create.api.contraption.transformable.ITransformableBlockEntity;
import com.simibubi.create.api.schematic.nbt.IPartialSafeNBT;
import com.simibubi.create.api.schematic.requirement.ISpecialBlockEntityItemRequirement;
import com.simibubi.create.api.contraption.transformable.TransformableBlockEntity;
import com.simibubi.create.api.schematic.nbt.PartialSafeNBT;
import com.simibubi.create.api.schematic.requirement.SpecialBlockEntityItemRequirement;
import com.simibubi.create.content.contraptions.StructureTransform;
import com.simibubi.create.content.redstone.RoseQuartzLampBlock;
import com.simibubi.create.content.schematics.requirement.ItemRequirement;
@ -20,6 +20,7 @@ import net.minecraft.nbt.CompoundTag;
import net.minecraft.nbt.NbtUtils;
import net.minecraft.world.item.ItemStack;
import net.minecraft.world.level.block.TrapDoorBlock;
import net.minecraft.world.level.block.entity.BlockEntity;
import net.minecraft.world.level.block.entity.BlockEntityType;
import net.minecraft.world.level.block.state.BlockState;
import net.minecraft.world.level.block.state.properties.BlockStateProperties;
@ -28,7 +29,7 @@ import net.minecraftforge.client.model.data.ModelData;
import net.minecraftforge.items.ItemHandlerHelper;
public class CopycatBlockEntity extends SmartBlockEntity
implements ISpecialBlockEntityItemRequirement, ITransformableBlockEntity, IPartialSafeNBT {
implements SpecialBlockEntityItemRequirement, TransformableBlockEntity, PartialSafeNBT {
private BlockState material;
private ItemStack consumedItem;
@ -128,7 +129,7 @@ public class CopycatBlockEntity extends SmartBlockEntity
}
@Override
public void transform(StructureTransform transform) {
public void transform(BlockEntity be, StructureTransform transform) {
material = transform.apply(material);
notifyUpdate();
}

View file

@ -5,10 +5,10 @@ import static net.minecraft.world.level.block.state.properties.BlockStatePropert
import com.simibubi.create.AllBlockEntityTypes;
import com.simibubi.create.AllBlocks;
import com.simibubi.create.AllShapes;
import com.simibubi.create.api.schematic.requirement.SpecialBlockItemRequirement;
import com.simibubi.create.content.equipment.wrench.IWrenchable;
import com.simibubi.create.content.kinetics.base.HorizontalAxisKineticBlock;
import com.simibubi.create.content.kinetics.base.KineticBlockEntity;
import com.simibubi.create.api.schematic.requirement.ISpecialBlockItemRequirement;
import com.simibubi.create.content.schematics.requirement.ItemRequirement;
import com.simibubi.create.foundation.block.IBE;
@ -37,7 +37,7 @@ import net.minecraft.world.phys.shapes.Shapes;
import net.minecraft.world.phys.shapes.VoxelShape;
public class GirderEncasedShaftBlock extends HorizontalAxisKineticBlock
implements IBE<KineticBlockEntity>, SimpleWaterloggedBlock, IWrenchable, ISpecialBlockItemRequirement {
implements IBE<KineticBlockEntity>, SimpleWaterloggedBlock, IWrenchable, SpecialBlockItemRequirement {
public static final BooleanProperty TOP = GirderBlock.TOP;
public static final BooleanProperty BOTTOM = GirderBlock.BOTTOM;

View file

@ -6,10 +6,10 @@ import com.simibubi.create.AllBlockEntityTypes;
import com.simibubi.create.AllBlocks;
import com.simibubi.create.AllShapes;
import com.simibubi.create.AllSoundEvents;
import com.simibubi.create.api.schematic.requirement.SpecialBlockItemRequirement;
import com.simibubi.create.content.equipment.wrench.IWrenchable;
import com.simibubi.create.content.logistics.filter.FilterItem;
import com.simibubi.create.content.logistics.filter.FilterItemStack;
import com.simibubi.create.api.schematic.requirement.ISpecialBlockItemRequirement;
import com.simibubi.create.content.schematics.requirement.ItemRequirement;
import com.simibubi.create.content.schematics.requirement.ItemRequirement.ItemUseType;
import com.simibubi.create.foundation.block.IBE;
@ -41,10 +41,11 @@ import net.minecraft.world.level.material.FluidState;
import net.minecraft.world.phys.BlockHitResult;
import net.minecraft.world.phys.shapes.CollisionContext;
import net.minecraft.world.phys.shapes.VoxelShape;
import net.minecraftforge.items.ItemHandlerHelper;
public class PlacardBlock extends FaceAttachedHorizontalDirectionalBlock
implements ProperWaterloggedBlock, IBE<PlacardBlockEntity>, ISpecialBlockItemRequirement, IWrenchable {
implements ProperWaterloggedBlock, IBE<PlacardBlockEntity>, SpecialBlockItemRequirement, IWrenchable {
public static final BooleanProperty POWERED = BlockStateProperties.POWERED;

View file

@ -6,8 +6,8 @@ import java.util.Optional;
import com.simibubi.create.AllBlockEntityTypes;
import com.simibubi.create.AllEnchantments;
import com.simibubi.create.AllShapes;
import com.simibubi.create.api.schematic.requirement.SpecialBlockItemRequirement;
import com.simibubi.create.content.kinetics.base.HorizontalKineticBlock;
import com.simibubi.create.api.schematic.requirement.ISpecialBlockItemRequirement;
import com.simibubi.create.content.schematics.requirement.ItemRequirement;
import com.simibubi.create.content.schematics.requirement.ItemRequirement.ItemUseType;
import com.simibubi.create.foundation.block.IBE;
@ -46,9 +46,10 @@ import net.minecraft.world.level.storage.loot.parameters.LootContextParams;
import net.minecraft.world.phys.BlockHitResult;
import net.minecraft.world.phys.shapes.CollisionContext;
import net.minecraft.world.phys.shapes.VoxelShape;
import net.minecraftforge.common.util.FakePlayer;
public class BacktankBlock extends HorizontalKineticBlock implements IBE<BacktankBlockEntity>, SimpleWaterloggedBlock, ISpecialBlockItemRequirement {
public class BacktankBlock extends HorizontalKineticBlock implements IBE<BacktankBlockEntity>, SimpleWaterloggedBlock, SpecialBlockItemRequirement {
public BacktankBlock(Properties properties) {
super(properties);

View file

@ -12,8 +12,8 @@ import org.apache.commons.lang3.Validate;
import com.simibubi.create.AllEntityTypes;
import com.simibubi.create.AllItems;
import com.simibubi.create.Create;
import com.simibubi.create.api.schematic.requirement.SpecialEntityItemRequirement;
import com.simibubi.create.content.logistics.filter.FilterItemStack;
import com.simibubi.create.api.schematic.requirement.ISpecialEntityItemRequirement;
import com.simibubi.create.content.schematics.requirement.ItemRequirement;
import com.simibubi.create.content.schematics.requirement.ItemRequirement.ItemUseType;
import com.simibubi.create.foundation.networking.ISyncPersistentData;
@ -59,6 +59,7 @@ import net.minecraft.world.level.block.state.BlockState;
import net.minecraft.world.phys.AABB;
import net.minecraft.world.phys.HitResult;
import net.minecraft.world.phys.Vec3;
import net.minecraftforge.api.distmarker.Dist;
import net.minecraftforge.api.distmarker.OnlyIn;
import net.minecraftforge.common.ForgeHooks;
@ -72,7 +73,7 @@ import net.minecraftforge.items.wrapper.InvWrapper;
import net.minecraftforge.network.NetworkHooks;
public class BlueprintEntity extends HangingEntity
implements IEntityAdditionalSpawnData, ISpecialEntityItemRequirement, ISyncPersistentData, IInteractionChecker {
implements IEntityAdditionalSpawnData, SpecialEntityItemRequirement, ISyncPersistentData, IInteractionChecker {
protected int size;
protected Direction verticalOrientation;

View file

@ -12,13 +12,13 @@ import java.util.function.Supplier;
import com.simibubi.create.AllBlockEntityTypes;
import com.simibubi.create.AllBlocks;
import com.simibubi.create.api.contraption.transformable.ITransformableBlock;
import com.simibubi.create.api.contraption.transformable.TransformableBlock;
import com.simibubi.create.api.schematic.requirement.SpecialBlockItemRequirement;
import com.simibubi.create.content.contraptions.StructureTransform;
import com.simibubi.create.content.decoration.encasing.EncasedBlock;
import com.simibubi.create.content.equipment.wrench.IWrenchable;
import com.simibubi.create.content.fluids.FluidPropagator;
import com.simibubi.create.content.fluids.FluidTransportBehaviour;
import com.simibubi.create.api.schematic.requirement.ISpecialBlockItemRequirement;
import com.simibubi.create.content.schematics.requirement.ItemRequirement;
import com.simibubi.create.foundation.advancement.AdvancementBehaviour;
import com.simibubi.create.foundation.block.IBE;
@ -51,7 +51,7 @@ import net.minecraft.world.phys.HitResult;
import net.minecraft.world.ticks.TickPriority;
public class EncasedPipeBlock extends Block
implements IWrenchable, ISpecialBlockItemRequirement, IBE<FluidPipeBlockEntity>, EncasedBlock, ITransformableBlock {
implements IWrenchable, SpecialBlockItemRequirement, IBE<FluidPipeBlockEntity>, EncasedBlock, TransformableBlock {
public static final Map<Direction, BooleanProperty> FACING_TO_PROPERTY_MAP = PipeBlock.PROPERTY_BY_DIRECTION;
private final Supplier<Block> casing;

View file

@ -7,7 +7,7 @@ import javax.annotation.Nullable;
import com.simibubi.create.AllBlockEntityTypes;
import com.simibubi.create.AllBlocks;
import com.simibubi.create.api.contraption.transformable.ITransformableBlock;
import com.simibubi.create.api.contraption.transformable.TransformableBlock;
import com.simibubi.create.content.contraptions.StructureTransform;
import com.simibubi.create.content.decoration.bracket.BracketedBlockEntityBehaviour;
import com.simibubi.create.content.decoration.encasing.EncasableBlock;
@ -55,7 +55,7 @@ import net.minecraft.world.phys.shapes.VoxelShape;
import net.minecraft.world.ticks.TickPriority;
public class FluidPipeBlock extends PipeBlock implements SimpleWaterloggedBlock, IWrenchableWithBracket,
IBE<FluidPipeBlockEntity>, EncasableBlock, ITransformableBlock {
IBE<FluidPipeBlockEntity>, EncasableBlock, TransformableBlock {
private static final VoxelShape OCCLUSION_BOX = Block.box(4, 4, 4, 12, 12, 12);

View file

@ -2,7 +2,7 @@ package com.simibubi.create.content.fluids.pipes;
import java.util.List;
import com.simibubi.create.api.contraption.transformable.ITransformableBlockEntity;
import com.simibubi.create.api.contraption.transformable.TransformableBlockEntity;
import com.simibubi.create.content.contraptions.StructureTransform;
import com.simibubi.create.content.decoration.bracket.BracketedBlockEntityBehaviour;
import com.simibubi.create.content.fluids.FluidPropagator;
@ -13,10 +13,11 @@ import com.simibubi.create.foundation.blockEntity.behaviour.BlockEntityBehaviour
import net.minecraft.core.BlockPos;
import net.minecraft.core.Direction;
import net.minecraft.world.level.BlockAndTintGetter;
import net.minecraft.world.level.block.entity.BlockEntity;
import net.minecraft.world.level.block.entity.BlockEntityType;
import net.minecraft.world.level.block.state.BlockState;
public class FluidPipeBlockEntity extends SmartBlockEntity implements ITransformableBlockEntity {
public class FluidPipeBlockEntity extends SmartBlockEntity implements TransformableBlockEntity {
public FluidPipeBlockEntity(BlockEntityType<?> type, BlockPos pos, BlockState state) {
super(type, pos, state);
@ -30,7 +31,7 @@ public class FluidPipeBlockEntity extends SmartBlockEntity implements ITransform
}
@Override
public void transform(StructureTransform transform) {
public void transform(BlockEntity be, StructureTransform transform) {
BracketedBlockEntityBehaviour bracketBehaviour = getBehaviour(BracketedBlockEntityBehaviour.TYPE);
if (bracketBehaviour != null) {
bracketBehaviour.transformBracket(transform);

View file

@ -4,8 +4,8 @@ import javax.annotation.ParametersAreNonnullByDefault;
import com.simibubi.create.AllBlockEntityTypes;
import com.simibubi.create.AllBlocks;
import com.simibubi.create.api.schematic.requirement.SpecialBlockItemRequirement;
import com.simibubi.create.content.fluids.FluidTransportBehaviour;
import com.simibubi.create.api.schematic.requirement.ISpecialBlockItemRequirement;
import com.simibubi.create.content.schematics.requirement.ItemRequirement;
import com.simibubi.create.foundation.block.IBE;
@ -30,7 +30,7 @@ import net.minecraft.world.level.pathfinder.PathComputationType;
@MethodsReturnNonnullByDefault
@ParametersAreNonnullByDefault
public class GlassFluidPipeBlock extends AxisPipeBlock implements IBE<StraightPipeBlockEntity>, SimpleWaterloggedBlock, ISpecialBlockItemRequirement {
public class GlassFluidPipeBlock extends AxisPipeBlock implements IBE<StraightPipeBlockEntity>, SimpleWaterloggedBlock, SpecialBlockItemRequirement {
public static final BooleanProperty ALT = BooleanProperty.create("alt");

View file

@ -1,6 +1,6 @@
package com.simibubi.create.content.kinetics.base;
import com.simibubi.create.api.contraption.transformable.ITransformableBlock;
import com.simibubi.create.api.contraption.transformable.TransformableBlock;
import com.simibubi.create.content.contraptions.StructureTransform;
import net.createmod.catnip.data.Iterate;
@ -16,7 +16,7 @@ import net.minecraft.world.level.block.state.BlockState;
import net.minecraft.world.level.block.state.StateDefinition.Builder;
import net.minecraft.world.level.block.state.properties.BooleanProperty;
public abstract class DirectionalAxisKineticBlock extends DirectionalKineticBlock implements ITransformableBlock {
public abstract class DirectionalAxisKineticBlock extends DirectionalKineticBlock implements TransformableBlock {
public static final BooleanProperty AXIS_ALONG_FIRST_COORDINATE = BooleanProperty.create("axis_along_first");

View file

@ -12,8 +12,8 @@ import org.apache.commons.lang3.mutable.MutableBoolean;
import com.simibubi.create.AllBlockEntityTypes;
import com.simibubi.create.AllBlocks;
import com.simibubi.create.AllItems;
import com.simibubi.create.api.contraption.transformable.ITransformableBlock;
import com.simibubi.create.api.schematic.requirement.ISpecialBlockItemRequirement;
import com.simibubi.create.api.contraption.transformable.TransformableBlock;
import com.simibubi.create.api.schematic.requirement.SpecialBlockItemRequirement;
import com.simibubi.create.content.contraptions.StructureTransform;
import com.simibubi.create.content.equipment.armor.DivingBootsItem;
import com.simibubi.create.content.fluids.transfer.GenericItemEmptying;
@ -88,6 +88,7 @@ import net.minecraft.world.phys.shapes.CollisionContext;
import net.minecraft.world.phys.shapes.EntityCollisionContext;
import net.minecraft.world.phys.shapes.Shapes;
import net.minecraft.world.phys.shapes.VoxelShape;
import net.minecraftforge.api.distmarker.Dist;
import net.minecraftforge.api.distmarker.OnlyIn;
import net.minecraftforge.client.extensions.common.IClientBlockExtensions;
@ -96,7 +97,7 @@ import net.minecraftforge.common.capabilities.ForgeCapabilities;
import net.minecraftforge.items.IItemHandler;
public class BeltBlock extends HorizontalKineticBlock
implements IBE<BeltBlockEntity>, ISpecialBlockItemRequirement, ITransformableBlock, ProperWaterloggedBlock {
implements IBE<BeltBlockEntity>, SpecialBlockItemRequirement, TransformableBlock, ProperWaterloggedBlock {
public static final Property<BeltSlope> SLOPE = EnumProperty.create("slope", BeltSlope.class);
public static final Property<BeltPart> PART = EnumProperty.create("part", BeltPart.class);

View file

@ -12,7 +12,7 @@ import java.util.function.Consumer;
import javax.annotation.Nullable;
import com.simibubi.create.api.contraption.transformable.ITransformableBlockEntity;
import com.simibubi.create.api.contraption.transformable.TransformableBlockEntity;
import com.simibubi.create.content.contraptions.StructureTransform;
import com.simibubi.create.content.kinetics.base.IRotate;
import com.simibubi.create.content.kinetics.base.KineticBlockEntity;
@ -28,9 +28,9 @@ import com.simibubi.create.infrastructure.config.AllConfigs;
import dev.engine_room.flywheel.api.visualization.VisualizationManager;
import net.createmod.catnip.data.Iterate;
import net.createmod.catnip.nbt.NBTHelper;
import net.createmod.catnip.math.VecHelper;
import net.createmod.catnip.math.AngleHelper;
import net.createmod.catnip.math.VecHelper;
import net.createmod.catnip.nbt.NBTHelper;
import net.minecraft.core.BlockPos;
import net.minecraft.core.Direction.Axis;
import net.minecraft.core.particles.BlockParticleOption;
@ -48,13 +48,15 @@ import net.minecraft.world.item.ItemStack;
import net.minecraft.world.item.Items;
import net.minecraft.world.level.block.Block;
import net.minecraft.world.level.block.Blocks;
import net.minecraft.world.level.block.entity.BlockEntity;
import net.minecraft.world.level.block.entity.BlockEntityType;
import net.minecraft.world.level.block.state.BlockState;
import net.minecraft.world.phys.AABB;
import net.minecraft.world.phys.Vec3;
import net.minecraftforge.items.ItemHandlerHelper;
public class ChainConveyorBlockEntity extends KineticBlockEntity implements ITransformableBlockEntity {
public class ChainConveyorBlockEntity extends KineticBlockEntity implements TransformableBlockEntity {
public record ConnectionStats(float tangentAngle, float chainLength, Vec3 start, Vec3 end) {
}
@ -782,7 +784,7 @@ public class ChainConveyorBlockEntity extends KineticBlockEntity implements ITra
}
@Override
public void transform(StructureTransform transform) {
public void transform(BlockEntity be, StructureTransform transform) {
if (connections == null || connections.isEmpty())
return;

View file

@ -1,7 +1,7 @@
package com.simibubi.create.content.kinetics.chainDrive;
import com.simibubi.create.AllBlockEntityTypes;
import com.simibubi.create.api.contraption.transformable.ITransformableBlock;
import com.simibubi.create.api.contraption.transformable.TransformableBlock;
import com.simibubi.create.content.contraptions.StructureTransform;
import com.simibubi.create.content.kinetics.base.DirectionalAxisKineticBlock;
import com.simibubi.create.content.kinetics.base.KineticBlockEntity;
@ -33,7 +33,7 @@ import net.minecraft.world.level.block.state.properties.Property;
import net.minecraft.world.level.material.PushReaction;
public class ChainDriveBlock extends RotatedPillarKineticBlock
implements IBE<KineticBlockEntity>, ITransformableBlock {
implements IBE<KineticBlockEntity>, TransformableBlock {
public static final Property<Part> PART = EnumProperty.create("part", Part.class);
public static final BooleanProperty CONNECTED_ALONG_FIRST_COORDINATE =

View file

@ -6,7 +6,7 @@ import java.util.List;
import javax.annotation.Nullable;
import com.simibubi.create.Create;
import com.simibubi.create.api.contraption.transformable.ITransformableBlockEntity;
import com.simibubi.create.api.contraption.transformable.TransformableBlockEntity;
import com.simibubi.create.content.contraptions.StructureTransform;
import com.simibubi.create.content.kinetics.base.KineticBlockEntity;
import com.simibubi.create.content.kinetics.mechanicalArm.AllArmInteractionPointTypes.JukeboxPoint;
@ -22,11 +22,11 @@ import com.simibubi.create.foundation.utility.CreateLang;
import com.simibubi.create.infrastructure.config.AllConfigs;
import dev.engine_room.flywheel.lib.visualization.VisualizationHelper;
import net.createmod.catnip.nbt.NBTHelper;
import net.createmod.catnip.math.VecHelper;
import net.createmod.catnip.animation.LerpedFloat;
import net.createmod.catnip.lang.Lang;
import net.createmod.catnip.math.AngleHelper;
import net.createmod.catnip.math.VecHelper;
import net.createmod.catnip.nbt.NBTHelper;
import net.minecraft.core.BlockPos;
import net.minecraft.core.Direction;
import net.minecraft.core.SectionPos;
@ -42,15 +42,17 @@ import net.minecraft.world.level.Level;
import net.minecraft.world.level.LevelAccessor;
import net.minecraft.world.level.block.Block;
import net.minecraft.world.level.block.JukeboxBlock;
import net.minecraft.world.level.block.entity.BlockEntity;
import net.minecraft.world.level.block.entity.BlockEntityType;
import net.minecraft.world.level.block.state.BlockState;
import net.minecraft.world.level.chunk.ChunkSource;
import net.minecraft.world.phys.AABB;
import net.minecraft.world.phys.Vec3;
import net.minecraftforge.api.distmarker.Dist;
import net.minecraftforge.fml.DistExecutor;
public class ArmBlockEntity extends KineticBlockEntity implements ITransformableBlockEntity {
public class ArmBlockEntity extends KineticBlockEntity implements TransformableBlockEntity {
// Server
List<ArmInteractionPoint> inputs;
@ -419,7 +421,7 @@ public class ArmBlockEntity extends KineticBlockEntity implements ITransformable
}
@Override
public void transform(StructureTransform transform) {
public void transform(BlockEntity be, StructureTransform transform) {
if (interactionPointTag == null)
return;

View file

@ -2,16 +2,17 @@ package com.simibubi.create.content.kinetics.simpleRelays;
import java.util.List;
import com.simibubi.create.api.contraption.transformable.ITransformableBlockEntity;
import com.simibubi.create.api.contraption.transformable.TransformableBlockEntity;
import com.simibubi.create.content.contraptions.StructureTransform;
import com.simibubi.create.content.decoration.bracket.BracketedBlockEntityBehaviour;
import com.simibubi.create.foundation.blockEntity.behaviour.BlockEntityBehaviour;
import net.minecraft.core.BlockPos;
import net.minecraft.world.level.block.entity.BlockEntity;
import net.minecraft.world.level.block.entity.BlockEntityType;
import net.minecraft.world.level.block.state.BlockState;
public class BracketedKineticBlockEntity extends SimpleKineticBlockEntity implements ITransformableBlockEntity {
public class BracketedKineticBlockEntity extends SimpleKineticBlockEntity implements TransformableBlockEntity {
public BracketedKineticBlockEntity(BlockEntityType<?> type, BlockPos pos, BlockState state) {
super(type, pos, state);
@ -25,7 +26,7 @@ public class BracketedKineticBlockEntity extends SimpleKineticBlockEntity implem
}
@Override
public void transform(StructureTransform transform) {
public void transform(BlockEntity be, StructureTransform transform) {
BracketedBlockEntityBehaviour bracketBehaviour = getBehaviour(BracketedBlockEntityBehaviour.TYPE);
if (bracketBehaviour != null) {
bracketBehaviour.transformBracket(transform);

View file

@ -4,7 +4,8 @@ import java.util.function.Supplier;
import com.simibubi.create.AllBlockEntityTypes;
import com.simibubi.create.AllBlocks;
import com.simibubi.create.api.contraption.transformable.ITransformableBlock;
import com.simibubi.create.api.contraption.transformable.TransformableBlock;
import com.simibubi.create.api.schematic.requirement.SpecialBlockItemRequirement;
import com.simibubi.create.content.contraptions.StructureTransform;
import com.simibubi.create.content.decoration.encasing.EncasedBlock;
import com.simibubi.create.content.equipment.wrench.IWrenchable;
@ -14,7 +15,6 @@ import com.simibubi.create.content.kinetics.base.RotatedPillarKineticBlock;
import com.simibubi.create.content.kinetics.simpleRelays.CogWheelBlock;
import com.simibubi.create.content.kinetics.simpleRelays.ICogWheel;
import com.simibubi.create.content.kinetics.simpleRelays.SimpleKineticBlockEntity;
import com.simibubi.create.api.schematic.requirement.ISpecialBlockItemRequirement;
import com.simibubi.create.content.schematics.requirement.ItemRequirement;
import com.simibubi.create.foundation.block.IBE;
@ -45,7 +45,7 @@ import net.minecraft.world.phys.BlockHitResult;
import net.minecraft.world.phys.HitResult;
public class EncasedCogwheelBlock extends RotatedPillarKineticBlock
implements ICogWheel, IBE<SimpleKineticBlockEntity>, ISpecialBlockItemRequirement, ITransformableBlock, EncasedBlock {
implements ICogWheel, IBE<SimpleKineticBlockEntity>, SpecialBlockItemRequirement, TransformableBlock, EncasedBlock {
public static final BooleanProperty TOP_SHAFT = BooleanProperty.create("top_shaft");
public static final BooleanProperty BOTTOM_SHAFT = BooleanProperty.create("bottom_shaft");

View file

@ -4,11 +4,11 @@ import java.util.function.Supplier;
import com.simibubi.create.AllBlockEntityTypes;
import com.simibubi.create.AllBlocks;
import com.simibubi.create.api.schematic.requirement.SpecialBlockItemRequirement;
import com.simibubi.create.content.decoration.encasing.EncasedBlock;
import com.simibubi.create.content.kinetics.base.AbstractEncasedShaftBlock;
import com.simibubi.create.content.kinetics.base.KineticBlockEntity;
import com.simibubi.create.content.kinetics.base.RotatedPillarKineticBlock;
import com.simibubi.create.api.schematic.requirement.ISpecialBlockItemRequirement;
import com.simibubi.create.content.schematics.requirement.ItemRequirement;
import com.simibubi.create.foundation.block.IBE;
@ -28,7 +28,7 @@ import net.minecraft.world.phys.BlockHitResult;
import net.minecraft.world.phys.HitResult;
public class EncasedShaftBlock extends AbstractEncasedShaftBlock
implements IBE<KineticBlockEntity>, ISpecialBlockItemRequirement, EncasedBlock {
implements IBE<KineticBlockEntity>, SpecialBlockItemRequirement, EncasedBlock {
private final Supplier<Block> casing;

View file

@ -26,6 +26,7 @@ public class SteamEngineVisual extends AbstractBlockEntityVisual<SteamEngineBloc
protected final TransformedInstance connector;
private Float lastAngle = Float.NaN;
private Axis lastAxis = null;
public SteamEngineVisual(VisualizationContext context, SteamEngineBlockEntity blockEntity, float partialTick) {
super(context, blockEntity, partialTick);
@ -47,11 +48,18 @@ public class SteamEngineVisual extends AbstractBlockEntityVisual<SteamEngineBloc
private void animate() {
Float angle = blockEntity.getTargetAngle();
Axis axis = Axis.Y;
if (Objects.equals(angle, lastAngle)) {
PoweredShaftBlockEntity shaft = blockEntity.getShaft();
if (shaft != null)
axis = KineticBlockEntityRenderer.getRotationAxisOf(shaft);
if (Objects.equals(angle, lastAngle) && lastAxis == axis) {
return;
}
lastAngle = angle;
lastAxis = axis;
if (angle == null) {
piston.setVisible(false);
@ -66,11 +74,6 @@ public class SteamEngineVisual extends AbstractBlockEntityVisual<SteamEngineBloc
Direction facing = SteamEngineBlock.getFacing(blockState);
Axis facingAxis = facing.getAxis();
Axis axis = Axis.Y;
PoweredShaftBlockEntity shaft = blockEntity.getShaft();
if (shaft != null)
axis = KineticBlockEntityRenderer.getRotationAxisOf(shaft);
boolean roll90 = facingAxis.isHorizontal() && axis == Axis.Y || facingAxis.isVertical() && axis == Axis.Z;
float sine = Mth.sin(angle);

View file

@ -2,7 +2,7 @@ package com.simibubi.create.content.kinetics.transmission.sequencer;
import com.simibubi.create.AllBlockEntityTypes;
import com.simibubi.create.AllItems;
import com.simibubi.create.api.contraption.transformable.ITransformableBlock;
import com.simibubi.create.api.contraption.transformable.TransformableBlock;
import com.simibubi.create.content.contraptions.StructureTransform;
import com.simibubi.create.content.kinetics.base.HorizontalAxisKineticBlock;
import com.simibubi.create.content.kinetics.base.KineticBlock;
@ -33,11 +33,12 @@ import net.minecraft.world.level.block.state.StateDefinition.Builder;
import net.minecraft.world.level.block.state.properties.BooleanProperty;
import net.minecraft.world.level.block.state.properties.IntegerProperty;
import net.minecraft.world.phys.BlockHitResult;
import net.minecraftforge.api.distmarker.Dist;
import net.minecraftforge.api.distmarker.OnlyIn;
import net.minecraftforge.fml.DistExecutor;
public class SequencedGearshiftBlock extends HorizontalAxisKineticBlock implements IBE<SequencedGearshiftBlockEntity>, ITransformableBlock {
public class SequencedGearshiftBlock extends HorizontalAxisKineticBlock implements IBE<SequencedGearshiftBlockEntity>, TransformableBlock {
public static final BooleanProperty VERTICAL = BooleanProperty.create("vertical");
public static final IntegerProperty STATE = IntegerProperty.create("state", 0, 5);

View file

@ -6,7 +6,7 @@ import com.simibubi.create.AllBlockEntityTypes;
import com.simibubi.create.AllBlocks;
import com.simibubi.create.AllShapes;
import com.simibubi.create.AllSoundEvents;
import com.simibubi.create.api.schematic.requirement.ISpecialBlockItemRequirement;
import com.simibubi.create.api.schematic.requirement.SpecialBlockItemRequirement;
import com.simibubi.create.content.equipment.wrench.IWrenchable;
import com.simibubi.create.content.logistics.packagerLink.LogisticallyLinkedBlockItem;
import com.simibubi.create.content.schematics.requirement.ItemRequirement;
@ -51,12 +51,13 @@ import net.minecraft.world.phys.shapes.CollisionContext;
import net.minecraft.world.phys.shapes.EntityCollisionContext;
import net.minecraft.world.phys.shapes.Shapes;
import net.minecraft.world.phys.shapes.VoxelShape;
import net.minecraftforge.common.ForgeMod;
import net.minecraftforge.common.MinecraftForge;
import net.minecraftforge.event.level.BlockEvent;
public class FactoryPanelBlock extends FaceAttachedHorizontalDirectionalBlock
implements ProperWaterloggedBlock, IBE<FactoryPanelBlockEntity>, IWrenchable, ISpecialBlockItemRequirement {
implements ProperWaterloggedBlock, IBE<FactoryPanelBlockEntity>, IWrenchable, SpecialBlockItemRequirement {
public static final BooleanProperty POWERED = BlockStateProperties.POWERED;

View file

@ -2,18 +2,18 @@ package com.simibubi.create.content.logistics.funnel;
import com.simibubi.create.AllBlocks;
import com.simibubi.create.AllShapes;
import com.simibubi.create.api.schematic.requirement.SpecialBlockItemRequirement;
import com.simibubi.create.content.kinetics.belt.BeltBlock;
import com.simibubi.create.content.kinetics.belt.BeltSlope;
import com.simibubi.create.content.kinetics.belt.behaviour.DirectBeltInputBehaviour;
import com.simibubi.create.api.schematic.requirement.ISpecialBlockItemRequirement;
import com.simibubi.create.content.schematics.requirement.ItemRequirement;
import com.simibubi.create.foundation.advancement.AllAdvancements;
import com.simibubi.create.foundation.block.ProperWaterloggedBlock;
import com.simibubi.create.foundation.blockEntity.behaviour.BlockEntityBehaviour;
import com.tterrag.registrate.util.entry.BlockEntry;
import net.createmod.catnip.math.VoxelShaper;
import net.createmod.catnip.lang.Lang;
import net.createmod.catnip.math.VoxelShaper;
import net.minecraft.core.BlockPos;
import net.minecraft.core.Direction;
import net.minecraft.util.StringRepresentable;
@ -37,7 +37,7 @@ import net.minecraft.world.phys.shapes.CollisionContext;
import net.minecraft.world.phys.shapes.EntityCollisionContext;
import net.minecraft.world.phys.shapes.VoxelShape;
public class BeltFunnelBlock extends AbstractHorizontalFunnelBlock implements ISpecialBlockItemRequirement {
public class BeltFunnelBlock extends AbstractHorizontalFunnelBlock implements SpecialBlockItemRequirement {
private BlockEntry<? extends FunnelBlock> parent;

View file

@ -47,6 +47,7 @@ public class ItemVaultBlockEntity extends SmartBlockEntity implements IMultiBloc
protected void onContentsChanged(int slot) {
super.onContentsChanged(slot);
updateComparators();
level.blockEntityChanged(worldPosition);
}
};

View file

@ -2,7 +2,7 @@ package com.simibubi.create.content.redstone;
import javax.annotation.Nullable;
import com.simibubi.create.api.contraption.transformable.ITransformableBlock;
import com.simibubi.create.api.contraption.transformable.TransformableBlock;
import com.simibubi.create.content.contraptions.StructureTransform;
import com.simibubi.create.content.equipment.wrench.IWrenchable;
@ -17,7 +17,7 @@ import net.minecraft.world.level.block.state.StateDefinition.Builder;
import net.minecraft.world.level.block.state.properties.AttachFace;
import net.minecraft.world.level.block.state.properties.EnumProperty;
public class DirectedDirectionalBlock extends HorizontalDirectionalBlock implements IWrenchable, ITransformableBlock {
public class DirectedDirectionalBlock extends HorizontalDirectionalBlock implements IWrenchable, TransformableBlock {
public static final EnumProperty<AttachFace> TARGET = EnumProperty.create("target", AttachFace.class);

View file

@ -5,7 +5,7 @@ import java.util.ArrayList;
import com.simibubi.create.AllBlockEntityTypes;
import com.simibubi.create.AllItems;
import com.simibubi.create.AllSoundEvents;
import com.simibubi.create.api.schematic.requirement.ISpecialBlockItemRequirement;
import com.simibubi.create.api.schematic.requirement.SpecialBlockItemRequirement;
import com.simibubi.create.content.schematics.requirement.ItemRequirement;
import com.simibubi.create.foundation.block.IBE;
@ -25,7 +25,7 @@ import net.minecraft.world.phys.BlockHitResult;
import net.minecraft.world.phys.HitResult;
public class LecternControllerBlock extends LecternBlock
implements IBE<LecternControllerBlockEntity>, ISpecialBlockItemRequirement {
implements IBE<LecternControllerBlockEntity>, SpecialBlockItemRequirement {
public LecternControllerBlock(Properties properties) {
super(properties);

View file

@ -8,9 +8,9 @@ import java.util.function.BiConsumer;
import com.simibubi.create.AllBlockEntityTypes;
import com.simibubi.create.AllBlocks;
import com.simibubi.create.AllShapes;
import com.simibubi.create.api.schematic.requirement.SpecialBlockItemRequirement;
import com.simibubi.create.content.equipment.clipboard.ClipboardEntry;
import com.simibubi.create.content.equipment.wrench.IWrenchable;
import com.simibubi.create.api.schematic.requirement.ISpecialBlockItemRequirement;
import com.simibubi.create.content.schematics.requirement.ItemRequirement;
import com.simibubi.create.content.schematics.requirement.ItemRequirement.ItemUseType;
import com.simibubi.create.foundation.block.IBE;
@ -48,7 +48,7 @@ import net.minecraft.world.phys.shapes.CollisionContext;
import net.minecraft.world.phys.shapes.VoxelShape;
public class NixieTubeBlock extends DoubleFaceAttachedBlock
implements IBE<NixieTubeBlockEntity>, IWrenchable, SimpleWaterloggedBlock, ISpecialBlockItemRequirement {
implements IBE<NixieTubeBlockEntity>, IWrenchable, SimpleWaterloggedBlock, SpecialBlockItemRequirement {
protected final DyeColor color;

View file

@ -98,8 +98,6 @@ public class SchematicHandler implements IGuiOverlay {
if (activeSchematicItem != null && transformation != null)
transformation.tick();
renderers.forEach(SchematicRenderer::tick);
LocalPlayer player = mc.player;
ItemStack stack = findBlueprintInHand(player);
if (stack == null) {

View file

@ -53,20 +53,17 @@ public class SchematicRenderer {
changed = true;
}
public void tick() {
if (!active)
return;
Minecraft mc = Minecraft.getInstance();
if (mc.level == null || mc.player == null || !changed)
return;
redraw();
changed = false;
}
public void render(PoseStack ms, SuperRenderTypeBuffer buffers) {
if (!active)
return;
Minecraft mc = Minecraft.getInstance();
if (mc.level == null || mc.player == null)
return;
if (changed)
redraw();
changed = false;
bufferCache.forEach((layer, buffer) -> {
buffer.renderInto(ms, buffers.getBuffer(layer));
});

View file

@ -8,13 +8,12 @@ import java.util.stream.Stream;
import org.jetbrains.annotations.Nullable;
import com.simibubi.create.api.schematic.requirement.ISpecialBlockEntityItemRequirement;
import com.simibubi.create.api.schematic.requirement.ISpecialBlockItemRequirement;
import com.simibubi.create.api.schematic.requirement.ISpecialEntityItemRequirement;
import com.simibubi.create.api.schematic.requirement.SpecialBlockEntityItemRequirement;
import com.simibubi.create.api.schematic.requirement.SpecialBlockItemRequirement;
import com.simibubi.create.api.schematic.requirement.SpecialEntityItemRequirement;
import com.simibubi.create.api.schematic.requirement.SchematicRequirementRegistries;
import com.simibubi.create.compat.framedblocks.FramedBlocksInSchematics;
import com.simibubi.create.foundation.data.recipe.Mods;
import net.createmod.catnip.nbt.NBTProcessors;
import net.minecraft.world.entity.Entity;
import net.minecraft.world.entity.decoration.ArmorStand;
@ -73,7 +72,7 @@ public class ItemRequirement {
SchematicRequirementRegistries.BlockRequirement blockRequirement = SchematicRequirementRegistries.BLOCKS.get(block);
if (blockRequirement != null) {
requirement = blockRequirement.getRequiredItems(block, state, be);
} else if (block instanceof ISpecialBlockItemRequirement specialBlock) {
} else if (block instanceof SpecialBlockItemRequirement specialBlock) {
requirement = specialBlock.getRequiredItems(state, be);
} else {
requirement = defaultOf(state, be);
@ -83,7 +82,7 @@ public class ItemRequirement {
SchematicRequirementRegistries.BlockEntityRequirement beRequirement = SchematicRequirementRegistries.BLOCK_ENTITIES.get(be.getType());
if (beRequirement != null) {
requirement = requirement.union(beRequirement.getRequiredItems(be, state));
} else if (be instanceof ISpecialBlockEntityItemRequirement specialBE) {
} else if (be instanceof SpecialBlockEntityItemRequirement specialBE) {
requirement = requirement.union(specialBE.getRequiredItems(state));
} else if (com.simibubi.create.compat.Mods.FRAMEDBLOCKS.contains(block)) {
requirement = requirement.union(FramedBlocksInSchematics.getRequiredItems(state, be));
@ -136,7 +135,7 @@ public class ItemRequirement {
SchematicRequirementRegistries.EntityRequirement requirement = SchematicRequirementRegistries.ENTITIES.get(entity.getType());
if (requirement != null) {
return requirement.getRequiredItems(entity);
} else if (entity instanceof ISpecialEntityItemRequirement specialEntity) {
} else if (entity instanceof SpecialEntityItemRequirement specialEntity) {
return specialEntity.getRequiredItems();
}

View file

@ -16,8 +16,8 @@ import com.google.common.collect.ImmutableSet;
import com.simibubi.create.AllBlocks;
import com.simibubi.create.AllBogeyStyles;
import com.simibubi.create.AllItems;
import com.simibubi.create.api.schematic.requirement.SpecialBlockItemRequirement;
import com.simibubi.create.content.equipment.wrench.IWrenchable;
import com.simibubi.create.api.schematic.requirement.ISpecialBlockItemRequirement;
import com.simibubi.create.content.schematics.requirement.ItemRequirement;
import com.simibubi.create.content.trains.entity.Carriage;
import com.simibubi.create.content.trains.entity.CarriageBogey;
@ -28,8 +28,8 @@ import com.simibubi.create.foundation.block.IBE;
import com.simibubi.create.foundation.block.ProperWaterloggedBlock;
import com.simibubi.create.foundation.utility.CreateLang;
import net.createmod.catnip.platform.CatnipServices;
import net.createmod.catnip.data.Iterate;
import net.createmod.catnip.platform.CatnipServices;
import net.minecraft.core.BlockPos;
import net.minecraft.core.Direction;
import net.minecraft.nbt.CompoundTag;
@ -52,9 +52,10 @@ import net.minecraft.world.level.block.state.properties.Property;
import net.minecraft.world.level.material.FluidState;
import net.minecraft.world.phys.BlockHitResult;
import net.minecraft.world.phys.Vec3;
import net.minecraftforge.registries.ForgeRegistries;
public abstract class AbstractBogeyBlock<T extends AbstractBogeyBlockEntity> extends Block implements IBE<T>, ProperWaterloggedBlock, ISpecialBlockItemRequirement, IWrenchable {
public abstract class AbstractBogeyBlock<T extends AbstractBogeyBlockEntity> extends Block implements IBE<T>, ProperWaterloggedBlock, SpecialBlockItemRequirement, IWrenchable {
public static final EnumProperty<Direction.Axis> AXIS = BlockStateProperties.HORIZONTAL_AXIS;
static final List<ResourceLocation> BOGEYS = new ArrayList<>();
public BogeySizes.BogeySize size;

View file

@ -3,7 +3,7 @@ package com.simibubi.create.content.trains.bogey;
import com.simibubi.create.AllBlockEntityTypes;
import com.simibubi.create.AllBlocks;
import com.simibubi.create.AllBogeyStyles;
import com.simibubi.create.api.schematic.requirement.ISpecialBlockItemRequirement;
import com.simibubi.create.api.schematic.requirement.SpecialBlockItemRequirement;
import com.simibubi.create.content.trains.track.TrackMaterial;
import com.simibubi.create.foundation.block.IBE;
import com.simibubi.create.foundation.block.ProperWaterloggedBlock;
@ -18,7 +18,7 @@ import net.minecraft.world.phys.HitResult;
import net.minecraft.world.phys.Vec3;
public class StandardBogeyBlock extends AbstractBogeyBlock<StandardBogeyBlockEntity>
implements IBE<StandardBogeyBlockEntity>, ProperWaterloggedBlock, ISpecialBlockItemRequirement {
implements IBE<StandardBogeyBlockEntity>, ProperWaterloggedBlock, SpecialBlockItemRequirement {
public StandardBogeyBlock(Properties props, BogeySizes.BogeySize size) {
super(props, size);

View file

@ -7,11 +7,10 @@ import java.util.List;
import java.util.Map;
import java.util.Optional;
import com.simibubi.create.api.contraption.train.TrainConductorHandler;
import org.apache.commons.lang3.tuple.Pair;
import com.simibubi.create.AllBlocks;
import com.simibubi.create.api.contraption.train.TrainConductorHandler;
import com.simibubi.create.content.contraptions.AssemblyException;
import com.simibubi.create.content.contraptions.Contraption;
import com.simibubi.create.content.contraptions.ContraptionType;
@ -20,11 +19,12 @@ import com.simibubi.create.content.contraptions.actors.trainControls.ControlsBlo
import com.simibubi.create.content.contraptions.minecart.TrainCargoManager;
import com.simibubi.create.content.trains.bogey.AbstractBogeyBlock;
import com.simibubi.create.foundation.utility.CreateLang;
import com.simibubi.create.impl.contraption.train.TrainConductorHandlerImpl;
import net.createmod.catnip.data.Couple;
import net.createmod.catnip.data.Iterate;
import net.createmod.catnip.nbt.NBTHelper;
import net.createmod.catnip.math.VecHelper;
import net.createmod.catnip.nbt.NBTHelper;
import net.minecraft.core.BlockPos;
import net.minecraft.core.Direction;
import net.minecraft.core.Direction.Axis;
@ -165,8 +165,12 @@ public class CarriageContraption extends Contraption {
captureBE ? world.getBlockEntity(pos) : null);
}
if (TrainConductorHandler.CONDUCTOR_HANDLERS.stream().anyMatch(handler -> handler.isValidConductor(blockState)))
for (TrainConductorHandler handler : TrainConductorHandlerImpl.CONDUCTOR_HANDLERS) {
if (handler.isValidConductor(blockState)) {
assembledBlockConductors.add(toLocalPos(pos));
break;
}
}
if (AllBlocks.TRAIN_CONTROLS.has(blockState)) {
Direction facing = blockState.getValue(ControlsBlock.FACING);

View file

@ -5,7 +5,7 @@ import java.util.List;
import javax.annotation.Nullable;
import com.mojang.blaze3d.vertex.PoseStack;
import com.simibubi.create.api.contraption.transformable.ITransformableBlockEntity;
import com.simibubi.create.api.contraption.transformable.TransformableBlockEntity;
import com.simibubi.create.content.contraptions.StructureTransform;
import com.simibubi.create.content.redstone.displayLink.DisplayLinkBlock;
import com.simibubi.create.content.trains.graph.EdgePointType;
@ -20,12 +20,13 @@ import dev.engine_room.flywheel.lib.transform.TransformStack;
import net.minecraft.core.BlockPos;
import net.minecraft.world.item.ItemStack;
import net.minecraft.world.level.LevelAccessor;
import net.minecraft.world.level.block.entity.BlockEntity;
import net.minecraft.world.level.block.entity.BlockEntityType;
import net.minecraft.world.level.block.state.BlockState;
import net.minecraft.world.phys.AABB;
import net.minecraft.world.phys.Vec3;
public class TrackObserverBlockEntity extends SmartBlockEntity implements ITransformableBlockEntity {
public class TrackObserverBlockEntity extends SmartBlockEntity implements TransformableBlockEntity {
public TrackTargetingBehaviour<TrackObserver> edgePoint;
@ -90,8 +91,8 @@ public class TrackObserverBlockEntity extends SmartBlockEntity implements ITrans
}
@Override
public void transform(StructureTransform transform) {
edgePoint.transform(transform);
public void transform(BlockEntity be, StructureTransform transform) {
edgePoint.transform(be, transform);
}
public FilteringBehaviour createFilter() {

View file

@ -4,7 +4,7 @@ import java.util.List;
import javax.annotation.Nullable;
import com.simibubi.create.api.contraption.transformable.ITransformableBlockEntity;
import com.simibubi.create.api.contraption.transformable.TransformableBlockEntity;
import com.simibubi.create.content.contraptions.StructureTransform;
import com.simibubi.create.content.trains.graph.EdgePointType;
import com.simibubi.create.content.trains.signal.SignalBlock.SignalType;
@ -15,11 +15,12 @@ import com.simibubi.create.foundation.blockEntity.behaviour.BlockEntityBehaviour
import net.createmod.catnip.nbt.NBTHelper;
import net.minecraft.core.BlockPos;
import net.minecraft.nbt.CompoundTag;
import net.minecraft.world.level.block.entity.BlockEntity;
import net.minecraft.world.level.block.entity.BlockEntityType;
import net.minecraft.world.level.block.state.BlockState;
import net.minecraft.world.phys.AABB;
public class SignalBlockEntity extends SmartBlockEntity implements ITransformableBlockEntity {
public class SignalBlockEntity extends SmartBlockEntity implements TransformableBlockEntity {
public static enum OverlayState {
RENDER, SKIP, DUAL
@ -160,8 +161,8 @@ public class SignalBlockEntity extends SmartBlockEntity implements ITransformabl
}
@Override
public void transform(StructureTransform transform) {
edgePoint.transform(transform);
public void transform(BlockEntity be, StructureTransform transform) {
edgePoint.transform(be, transform);
}
}

View file

@ -21,10 +21,10 @@ import com.simibubi.create.AllItems;
import com.simibubi.create.AllPackets;
import com.simibubi.create.AllSoundEvents;
import com.simibubi.create.Create;
import com.simibubi.create.api.contraption.transformable.TransformableBlockEntity;
import com.simibubi.create.compat.computercraft.AbstractComputerBehaviour;
import com.simibubi.create.compat.computercraft.ComputerCraftProxy;
import com.simibubi.create.content.contraptions.AssemblyException;
import com.simibubi.create.api.contraption.transformable.ITransformableBlockEntity;
import com.simibubi.create.content.contraptions.StructureTransform;
import com.simibubi.create.content.decoration.slidingDoor.DoorControlBehaviour;
import com.simibubi.create.content.equipment.wrench.IWrenchable;
@ -60,12 +60,12 @@ import com.simibubi.create.foundation.blockEntity.behaviour.BlockEntityBehaviour
import com.simibubi.create.foundation.utility.CreateLang;
import com.simibubi.create.infrastructure.config.AllConfigs;
import net.createmod.catnip.data.Iterate;
import net.createmod.catnip.nbt.NBTHelper;
import net.createmod.catnip.math.VecHelper;
import net.createmod.catnip.data.WorldAttached;
import net.createmod.catnip.animation.LerpedFloat;
import net.createmod.catnip.animation.LerpedFloat.Chaser;
import net.createmod.catnip.data.Iterate;
import net.createmod.catnip.data.WorldAttached;
import net.createmod.catnip.math.VecHelper;
import net.createmod.catnip.nbt.NBTHelper;
import net.minecraft.ChatFormatting;
import net.minecraft.core.BlockPos;
import net.minecraft.core.BlockPos.MutableBlockPos;
@ -90,13 +90,14 @@ import net.minecraft.world.level.block.state.BlockState;
import net.minecraft.world.level.levelgen.structure.BoundingBox;
import net.minecraft.world.phys.AABB;
import net.minecraft.world.phys.Vec3;
import net.minecraftforge.api.distmarker.Dist;
import net.minecraftforge.api.distmarker.OnlyIn;
import net.minecraftforge.common.capabilities.Capability;
import net.minecraftforge.common.util.LazyOptional;
import net.minecraftforge.network.PacketDistributor;
public class StationBlockEntity extends SmartBlockEntity implements ITransformableBlockEntity {
public class StationBlockEntity extends SmartBlockEntity implements TransformableBlockEntity {
public TrackTargetingBehaviour<GlobalStation> edgePoint;
public DoorControlBehaviour doorControls;
@ -970,8 +971,8 @@ public class StationBlockEntity extends SmartBlockEntity implements ITransformab
}
@Override
public void transform(StructureTransform transform) {
edgePoint.transform(transform);
public void transform(BlockEntity be, StructureTransform transform) {
edgePoint.transform(be, transform);
}
// Package port integration

View file

@ -19,7 +19,6 @@ import java.util.Random;
import java.util.Set;
import java.util.function.Consumer;
import net.minecraft.network.chat.Component;
import org.jetbrains.annotations.Nullable;
import com.google.common.base.Predicates;
@ -29,9 +28,9 @@ import com.simibubi.create.AllBlocks;
import com.simibubi.create.AllPartialModels;
import com.simibubi.create.AllShapes;
import com.simibubi.create.AllTags;
import com.simibubi.create.api.schematic.requirement.SpecialBlockItemRequirement;
import com.simibubi.create.content.decoration.girder.GirderBlock;
import com.simibubi.create.content.equipment.wrench.IWrenchable;
import com.simibubi.create.api.schematic.requirement.ISpecialBlockItemRequirement;
import com.simibubi.create.content.schematics.requirement.ItemRequirement;
import com.simibubi.create.content.schematics.requirement.ItemRequirement.ItemUseType;
import com.simibubi.create.content.trains.CubeParticleData;
@ -50,17 +49,18 @@ import dev.engine_room.flywheel.lib.model.baked.PartialModel;
import dev.engine_room.flywheel.lib.transform.TransformStack;
import it.unimi.dsi.fastutil.objects.Object2IntArrayMap;
import it.unimi.dsi.fastutil.objects.Object2IntMap;
import net.createmod.catnip.math.BlockFace;
import net.createmod.catnip.data.Iterate;
import net.createmod.catnip.data.Pair;
import net.createmod.catnip.math.VecHelper;
import net.createmod.catnip.math.AngleHelper;
import net.createmod.catnip.math.BlockFace;
import net.createmod.catnip.math.VecHelper;
import net.minecraft.ChatFormatting;
import net.minecraft.client.multiplayer.ClientLevel;
import net.minecraft.core.BlockPos;
import net.minecraft.core.Direction;
import net.minecraft.core.Direction.Axis;
import net.minecraft.core.Direction.AxisDirection;
import net.minecraft.network.chat.Component;
import net.minecraft.network.chat.MutableComponent;
import net.minecraft.resources.ResourceKey;
import net.minecraft.server.level.ServerLevel;
@ -99,12 +99,13 @@ import net.minecraft.world.phys.shapes.CollisionContext;
import net.minecraft.world.phys.shapes.Shapes;
import net.minecraft.world.phys.shapes.VoxelShape;
import net.minecraft.world.ticks.LevelTickAccess;
import net.minecraftforge.api.distmarker.Dist;
import net.minecraftforge.api.distmarker.OnlyIn;
import net.minecraftforge.client.extensions.common.IClientBlockExtensions;
public class TrackBlock extends Block
implements IBE<TrackBlockEntity>, IWrenchable, ITrackBlock, ISpecialBlockItemRequirement, ProperWaterloggedBlock, IHaveBigOutline {
implements IBE<TrackBlockEntity>, IWrenchable, ITrackBlock, SpecialBlockItemRequirement, ProperWaterloggedBlock, IHaveBigOutline {
public static final EnumProperty<TrackShape> SHAPE = EnumProperty.create("shape", TrackShape.class);
public static final BooleanProperty HAS_BE = BooleanProperty.create("turn");

View file

@ -11,7 +11,7 @@ import java.util.Set;
import com.simibubi.create.AllBlocks;
import com.simibubi.create.AllPackets;
import com.simibubi.create.AllTags;
import com.simibubi.create.api.contraption.transformable.ITransformableBlockEntity;
import com.simibubi.create.api.contraption.transformable.TransformableBlockEntity;
import com.simibubi.create.content.contraptions.StructureTransform;
import com.simibubi.create.content.trains.graph.TrackNodeLocation;
import com.simibubi.create.foundation.block.ProperWaterloggedBlock;
@ -41,12 +41,13 @@ import net.minecraft.world.level.material.FluidState;
import net.minecraft.world.level.material.Fluids;
import net.minecraft.world.phys.AABB;
import net.minecraft.world.phys.Vec3;
import net.minecraftforge.api.distmarker.Dist;
import net.minecraftforge.api.distmarker.OnlyIn;
import net.minecraftforge.client.model.data.ModelData;
import net.minecraftforge.fml.DistExecutor;
public class TrackBlockEntity extends SmartBlockEntity implements ITransformableBlockEntity, IMergeableBE {
public class TrackBlockEntity extends SmartBlockEntity implements TransformableBlockEntity, IMergeableBE {
Map<BlockPos, BezierConnection> connections;
boolean cancelDrops;
@ -262,7 +263,7 @@ public class TrackBlockEntity extends SmartBlockEntity implements ITransformable
}
@Override
public void transform(StructureTransform transform) {
public void transform(BlockEntity be, StructureTransform transform) {
Map<BlockPos, BezierConnection> restoredConnections = new HashMap<>();
for (Entry<BlockPos, BezierConnection> entry : connections.entrySet())
restoredConnections.put(entry.getKey(),

View file

@ -23,10 +23,10 @@ import com.simibubi.create.foundation.blockEntity.behaviour.BehaviourType;
import com.simibubi.create.foundation.blockEntity.behaviour.BlockEntityBehaviour;
import dev.engine_room.flywheel.lib.model.baked.PartialModel;
import net.createmod.catnip.render.CachedBuffers;
import net.createmod.catnip.data.Iterate;
import net.createmod.catnip.math.VecHelper;
import net.createmod.catnip.levelWrappers.SchematicLevel;
import net.createmod.catnip.math.VecHelper;
import net.createmod.catnip.render.CachedBuffers;
import net.createmod.ponder.api.level.PonderLevel;
import net.minecraft.client.renderer.LevelRenderer;
import net.minecraft.client.renderer.MultiBufferSource;
@ -41,8 +41,10 @@ import net.minecraft.util.Mth;
import net.minecraft.world.level.Level;
import net.minecraft.world.level.LevelAccessor;
import net.minecraft.world.level.block.Block;
import net.minecraft.world.level.block.entity.BlockEntity;
import net.minecraft.world.level.block.state.BlockState;
import net.minecraft.world.phys.Vec3;
import net.minecraftforge.api.distmarker.Dist;
import net.minecraftforge.api.distmarker.OnlyIn;
@ -332,7 +334,7 @@ public class TrackTargetingBehaviour<T extends TrackEdgePoint> extends BlockEnti
ms.popPose();
}
public void transform(StructureTransform transform) {
public void transform(BlockEntity be, StructureTransform transform) {
id = UUID.randomUUID();
targetTrack = transform.applyWithoutOffset(targetTrack);
if (prevDirection != null)

View file

@ -7,14 +7,14 @@ import java.util.Map;
import java.util.function.Consumer;
import com.simibubi.create.api.event.BlockEntityBehaviourEvent;
import com.simibubi.create.api.schematic.requirement.ISpecialBlockEntityItemRequirement;
import com.simibubi.create.api.schematic.nbt.PartialSafeNBT;
import com.simibubi.create.api.schematic.requirement.SpecialBlockEntityItemRequirement;
import com.simibubi.create.content.schematics.requirement.ItemRequirement;
import com.simibubi.create.foundation.advancement.AdvancementBehaviour;
import com.simibubi.create.foundation.advancement.CreateAdvancement;
import com.simibubi.create.foundation.blockEntity.behaviour.BehaviourType;
import com.simibubi.create.foundation.blockEntity.behaviour.BlockEntityBehaviour;
import com.simibubi.create.foundation.utility.IInteractionChecker;
import com.simibubi.create.api.schematic.nbt.IPartialSafeNBT;
import it.unimi.dsi.fastutil.objects.Reference2ObjectArrayMap;
import net.createmod.ponder.api.VirtualBlockEntity;
@ -24,12 +24,13 @@ import net.minecraft.network.FriendlyByteBuf;
import net.minecraft.world.entity.player.Player;
import net.minecraft.world.level.block.entity.BlockEntityType;
import net.minecraft.world.level.block.state.BlockState;
import net.minecraftforge.common.MinecraftForge;
import net.minecraftforge.common.capabilities.Capability;
import net.minecraftforge.common.capabilities.ForgeCapabilities;
public abstract class SmartBlockEntity extends CachedRenderBBBlockEntity
implements IPartialSafeNBT, IInteractionChecker, ISpecialBlockEntityItemRequirement, VirtualBlockEntity {
implements PartialSafeNBT, IInteractionChecker, SpecialBlockEntityItemRequirement, VirtualBlockEntity {
private final Map<BehaviourType<?>, BlockEntityBehaviour> behaviours = new Reference2ObjectArrayMap<>();
private boolean initialized = false;

View file

@ -7,7 +7,7 @@ import javax.annotation.Nullable;
import com.simibubi.create.AllBlocks;
import com.simibubi.create.AllTags.AllBlockTags;
import com.simibubi.create.api.schematic.nbt.IPartialSafeNBT;
import com.simibubi.create.api.schematic.nbt.PartialSafeNBT;
import com.simibubi.create.api.schematic.nbt.SafeNbtWriterRegistry;
import com.simibubi.create.api.schematic.nbt.SafeNbtWriterRegistry.SafeNbtWriter;
import com.simibubi.create.compat.Mods;
@ -286,7 +286,7 @@ public class BlockHelper {
} else if (writer != null) {
data = new CompoundTag();
writer.writeSafe(blockEntity, data);
} else if (blockEntity instanceof IPartialSafeNBT safeNbtBE) {
} else if (blockEntity instanceof PartialSafeNBT safeNbtBE) {
data = new CompoundTag();
safeNbtBE.writeSafe(data);
} else if (Mods.FRAMEDBLOCKS.contains(blockState.getBlock())) {

View file

@ -0,0 +1,22 @@
package com.simibubi.create.impl.contraption.train;
import java.util.ArrayList;
import java.util.List;
import org.jetbrains.annotations.ApiStatus;
import com.simibubi.create.AllBlocks;
import com.simibubi.create.api.contraption.train.TrainConductorHandler;
import com.simibubi.create.api.contraption.train.TrainConductorHandler.UpdateScheduleCallback;
import com.simibubi.create.content.processing.burner.BlazeBurnerBlock;
@ApiStatus.Internal
public class TrainConductorHandlerImpl {
public static final List<TrainConductorHandler> CONDUCTOR_HANDLERS = new ArrayList<>();
@ApiStatus.Internal
public static void registerBlazeBurner() {
TrainConductorHandler.registerConductor(AllBlocks.BLAZE_BURNER.getId(), blockState -> AllBlocks.BLAZE_BURNER.has(blockState)
&& blockState.getValue(BlazeBurnerBlock.HEAT_LEVEL) != BlazeBurnerBlock.HeatLevel.NONE, UpdateScheduleCallback.EMPTY);
}
}

View file

@ -1,6 +1,5 @@
package com.simibubi.create.infrastructure.config;
import com.simibubi.create.content.contraptions.ContraptionData;
import com.simibubi.create.content.contraptions.ContraptionMovementSetting;
import net.createmod.catnip.config.ConfigBase;
@ -32,8 +31,6 @@ public class CKinetics extends ConfigBase {
public final ConfigGroup contraptions = group(1, "contraptions", "Moving Contraptions");
public final ConfigInt maxBlocksMoved = i(2048, 1, "maxBlocksMoved", Comments.maxBlocksMoved);
public final ConfigInt maxDataSize =
i(ContraptionData.DEFAULT_LIMIT, 0, "maxDataSize", Comments.bytes, Comments.maxDataDisable, Comments.maxDataSize, Comments.maxDataSize2);
public final ConfigInt maxChassisRange = i(16, 1, "maxChassisRange", Comments.maxChassisRange);
public final ConfigInt maxPistonPoles = i(64, 1, "maxPistonPoles", Comments.maxPistonPoles);
public final ConfigInt maxRopeLength = i(384, 1, "maxRopeLength", Comments.maxRopeLength);
@ -86,9 +83,6 @@ public class CKinetics extends ConfigBase {
"multiplier used for calculating exhaustion from speed when a crank is turned.";
static String maxBlocksMoved =
"Maximum amount of blocks in a structure movable by Pistons, Bearings or other means.";
static String maxDataSize = "Maximum amount of data a contraption can have before it can't be synced with players.";
static String maxDataSize2 = "Un-synced contraptions will not be visible and will not have collision.";
static String maxDataDisable = "[0 to disable this limit]";
static String maxChassisRange = "Maximum value of a chassis attachment range.";
static String maxPistonPoles = "Maximum amount of extension poles behind a Mechanical Piston.";
static String maxRopeLength = "Max length of rope available off a Rope Pulley.";

Binary file not shown.

Before

Width:  |  Height:  |  Size: 878 B

After

Width:  |  Height:  |  Size: 870 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.3 KiB

After

Width:  |  Height:  |  Size: 1.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 400 B

After

Width:  |  Height:  |  Size: 768 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 424 B

After

Width:  |  Height:  |  Size: 1 KiB