From 6d0a8f22bf85c751a13195294ae3ba56f95a79e2 Mon Sep 17 00:00:00 2001 From: Shadowfacts Date: Thu, 27 Dec 2018 21:44:50 -0500 Subject: [PATCH] Use separate blocks for ticking/non-ticking containers --- .../simplemultipart/SimpleMultipart.java | 2 + .../container/AbstractContainerBlock.java | 75 +++++++++++++++++++ .../AbstractContainerBlockEntity.java | 6 +- .../container/ContainerBlock.java | 66 +--------------- .../container/ContainerEventHandler.java | 7 +- .../container/TickableContainerBlock.java | 15 ++++ .../mixin/client/MixinModelLoader.java | 1 + .../blockstates/tickable_container.json | 5 ++ 8 files changed, 110 insertions(+), 67 deletions(-) create mode 100644 src/main/java/net/shadowfacts/simplemultipart/container/AbstractContainerBlock.java create mode 100644 src/main/java/net/shadowfacts/simplemultipart/container/TickableContainerBlock.java create mode 100644 src/main/resources/assets/simplemultipart/blockstates/tickable_container.json diff --git a/src/main/java/net/shadowfacts/simplemultipart/SimpleMultipart.java b/src/main/java/net/shadowfacts/simplemultipart/SimpleMultipart.java index 4f995c3..2343cfd 100644 --- a/src/main/java/net/shadowfacts/simplemultipart/SimpleMultipart.java +++ b/src/main/java/net/shadowfacts/simplemultipart/SimpleMultipart.java @@ -31,12 +31,14 @@ public class SimpleMultipart implements ModInitializer { public static final LootContextType MULTIPART_LOOT_CONTEXT = createMultipartLootContextType(); public static final ContainerBlock containerBlock = new ContainerBlock(); + public static final TickableContainerBlock tickableContainerBlock = new TickableContainerBlock(); public static final BlockEntityType containerBlockEntity = createBlockEntityType("container", ContainerBlockEntity::new); public static final BlockEntityType tickableContainerBlockEntity = createBlockEntityType("tickable_container", TickableContainerBlockEntity::new); @Override public void onInitialize() { Registry.register(Registry.BLOCK, new Identifier(MODID, "container"), containerBlock); + Registry.register(Registry.BLOCK, new Identifier(MODID, "tickable_container"), tickableContainerBlock); ContainerEventHandler.register(); } diff --git a/src/main/java/net/shadowfacts/simplemultipart/container/AbstractContainerBlock.java b/src/main/java/net/shadowfacts/simplemultipart/container/AbstractContainerBlock.java new file mode 100644 index 0000000..14eebc2 --- /dev/null +++ b/src/main/java/net/shadowfacts/simplemultipart/container/AbstractContainerBlock.java @@ -0,0 +1,75 @@ +package net.shadowfacts.simplemultipart.container; + +import net.fabricmc.fabric.block.FabricBlockSettings; +import net.minecraft.block.*; +import net.minecraft.entity.player.PlayerEntity; +import net.minecraft.util.Hand; +import net.minecraft.util.math.BlockPos; +import net.minecraft.util.math.Direction; +import net.minecraft.util.shape.VoxelShape; +import net.minecraft.util.shape.VoxelShapes; +import net.minecraft.world.BlockView; +import net.minecraft.world.ExtendedBlockView; +import net.minecraft.world.World; +import net.shadowfacts.simplemultipart.api.MultipartContainer; +import net.shadowfacts.simplemultipart.client.util.RenderStateProvider; +import net.shadowfacts.simplemultipart.util.MultipartHelper; +import net.shadowfacts.simplemultipart.util.MultipartHitResult; +import net.shadowfacts.simplemultipart.api.MultipartView; + +import java.util.Set; + +/** + * @author shadowfacts + */ +public abstract class AbstractContainerBlock extends Block implements BlockEntityProvider, RenderStateProvider { + + public AbstractContainerBlock() { + super(FabricBlockSettings.of(Material.STONE).build()); + } + + @Override + public boolean activate(BlockState state, World world, BlockPos pos, PlayerEntity player, Hand hand, Direction side, float hitX, float hitY, float hitZ) { + MultipartContainer container = (MultipartContainer)world.getBlockEntity(pos); + if (container == null) { + return false; + } + + MultipartHitResult hit = MultipartHelper.rayTrace(container, world, pos, player); + if (hit == null) { + return false; + } + + return hit.view.getState().activate(hit.view, player, hand); + } + + @Override + public BlockState getStateForRendering(BlockState state, BlockPos pos, ExtendedBlockView world) { + MultipartContainer container = (MultipartContainer)world.getBlockEntity(pos); + if (container == null) { + return state; + } + + Set parts = container.getParts(); + return new ContainerBlockState(state, parts); + } + + @Override + @Deprecated + public VoxelShape getBoundingShape(BlockState state, BlockView world, BlockPos pos) { + MultipartContainer container = (MultipartContainer)world.getBlockEntity(pos); + if (container == null) { + return VoxelShapes.empty(); + } + + VoxelShape shape = null; + for (MultipartView view : container.getParts()) { + VoxelShape partShape = view.getState().getBoundingShape(view); + shape = shape == null ? partShape : VoxelShapes.union(shape, partShape); + } + return shape == null ? VoxelShapes.empty() : shape; + } + + @Override + public abstract AbstractContainerBlockEntity createBlockEntity(BlockView world); +} diff --git a/src/main/java/net/shadowfacts/simplemultipart/container/AbstractContainerBlockEntity.java b/src/main/java/net/shadowfacts/simplemultipart/container/AbstractContainerBlockEntity.java index d49b85f..de06f1b 100644 --- a/src/main/java/net/shadowfacts/simplemultipart/container/AbstractContainerBlockEntity.java +++ b/src/main/java/net/shadowfacts/simplemultipart/container/AbstractContainerBlockEntity.java @@ -118,11 +118,13 @@ public abstract class AbstractContainerBlockEntity extends BlockEntity implement boolean hasTickableParts = parts.stream().anyMatch(e -> e.getEntity() != null && e.getEntity() instanceof Tickable); boolean currentlyTickable = this instanceof Tickable; if (hasTickableParts != currentlyTickable) { - AbstractContainerBlockEntity newContainer = hasTickableParts ? new TickableContainerBlockEntity() : new ContainerBlockEntity(); - world.setBlockEntity(pos, newContainer); + Block newBlock = hasTickableParts ? SimpleMultipart.tickableContainerBlock : SimpleMultipart.containerBlock; + world.setBlockState(pos, newBlock.getDefaultState(), 3); + AbstractContainerBlockEntity newContainer = (AbstractContainerBlockEntity)world.getBlockEntity(pos); newContainer.parts = parts.stream() .map(e -> new Entry(newContainer, e.state, e.entity)) .collect(Collectors.toSet()); + newContainer.parts.stream().filter(e -> e.entity != null).forEach(e -> e.entity.container = newContainer); } world.markDirty(pos, world.getBlockEntity(pos)); diff --git a/src/main/java/net/shadowfacts/simplemultipart/container/ContainerBlock.java b/src/main/java/net/shadowfacts/simplemultipart/container/ContainerBlock.java index d068639..c16fc2c 100644 --- a/src/main/java/net/shadowfacts/simplemultipart/container/ContainerBlock.java +++ b/src/main/java/net/shadowfacts/simplemultipart/container/ContainerBlock.java @@ -1,77 +1,15 @@ package net.shadowfacts.simplemultipart.container; -import net.fabricmc.fabric.block.FabricBlockSettings; -import net.minecraft.block.*; -import net.minecraft.entity.player.PlayerEntity; -import net.minecraft.util.Hand; -import net.minecraft.util.math.BlockPos; -import net.minecraft.util.math.Direction; -import net.minecraft.util.shape.VoxelShape; -import net.minecraft.util.shape.VoxelShapes; import net.minecraft.world.BlockView; -import net.minecraft.world.ExtendedBlockView; -import net.minecraft.world.World; -import net.shadowfacts.simplemultipart.api.MultipartContainer; -import net.shadowfacts.simplemultipart.client.util.RenderStateProvider; -import net.shadowfacts.simplemultipart.util.MultipartHelper; -import net.shadowfacts.simplemultipart.util.MultipartHitResult; -import net.shadowfacts.simplemultipart.api.MultipartView; - -import java.util.Set; /** * @author shadowfacts */ -public class ContainerBlock extends Block implements BlockEntityProvider, RenderStateProvider { - - public ContainerBlock() { - super(FabricBlockSettings.of(Material.STONE).build()); - } - - @Override - public boolean activate(BlockState state, World world, BlockPos pos, PlayerEntity player, Hand hand, Direction side, float hitX, float hitY, float hitZ) { - MultipartContainer container = (MultipartContainer)world.getBlockEntity(pos); - if (container == null) { - return false; - } - - MultipartHitResult hit = MultipartHelper.rayTrace(container, world, pos, player); - if (hit == null) { - return false; - } - - return hit.view.getState().activate(hit.view, player, hand); - } - - @Override - public BlockState getStateForRendering(BlockState state, BlockPos pos, ExtendedBlockView world) { - MultipartContainer container = (MultipartContainer)world.getBlockEntity(pos); - if (container == null) { - return state; - } - - Set parts = container.getParts(); - return new ContainerBlockState(state, parts); - } - - @Override - @Deprecated - public VoxelShape getBoundingShape(BlockState state, BlockView world, BlockPos pos) { - MultipartContainer container = (MultipartContainer)world.getBlockEntity(pos); - if (container == null) { - return VoxelShapes.empty(); - } - - VoxelShape shape = null; - for (MultipartView view : container.getParts()) { - VoxelShape partShape = view.getState().getBoundingShape(view); - shape = shape == null ? partShape : VoxelShapes.union(shape, partShape); - } - return shape == null ? VoxelShapes.empty() : shape; - } +public class ContainerBlock extends AbstractContainerBlock { @Override public AbstractContainerBlockEntity createBlockEntity(BlockView world) { return new ContainerBlockEntity(); } + } diff --git a/src/main/java/net/shadowfacts/simplemultipart/container/ContainerEventHandler.java b/src/main/java/net/shadowfacts/simplemultipart/container/ContainerEventHandler.java index 44ab008..e23e449 100644 --- a/src/main/java/net/shadowfacts/simplemultipart/container/ContainerEventHandler.java +++ b/src/main/java/net/shadowfacts/simplemultipart/container/ContainerEventHandler.java @@ -23,7 +23,12 @@ public class ContainerEventHandler { } private static ActionResult handleBlockAttack(PlayerEntity player, World world, Hand hand, BlockPos pos, Direction direction) { - if (world.isClient || world.getBlockState(pos).getBlock() != SimpleMultipart.containerBlock) { + if (world.isClient) { + return ActionResult.PASS; + } + + Block block = world.getBlockState(pos).getBlock(); + if (block != SimpleMultipart.containerBlock && block != SimpleMultipart.tickableContainerBlock) { return ActionResult.PASS; } diff --git a/src/main/java/net/shadowfacts/simplemultipart/container/TickableContainerBlock.java b/src/main/java/net/shadowfacts/simplemultipart/container/TickableContainerBlock.java new file mode 100644 index 0000000..e0d635e --- /dev/null +++ b/src/main/java/net/shadowfacts/simplemultipart/container/TickableContainerBlock.java @@ -0,0 +1,15 @@ +package net.shadowfacts.simplemultipart.container; + +import net.minecraft.world.BlockView; + +/** + * @author shadowfacts + */ +public class TickableContainerBlock extends AbstractContainerBlock { + + @Override + public AbstractContainerBlockEntity createBlockEntity(BlockView world) { + return new TickableContainerBlockEntity(); + } + +} diff --git a/src/main/java/net/shadowfacts/simplemultipart/mixin/client/MixinModelLoader.java b/src/main/java/net/shadowfacts/simplemultipart/mixin/client/MixinModelLoader.java index 9601d63..c45b4e3 100644 --- a/src/main/java/net/shadowfacts/simplemultipart/mixin/client/MixinModelLoader.java +++ b/src/main/java/net/shadowfacts/simplemultipart/mixin/client/MixinModelLoader.java @@ -28,6 +28,7 @@ public abstract class MixinModelLoader { @Inject(method = "", at = @At("RETURN")) public void addMultipartModel(ResourceManager manager, SpriteAtlasTexture texture, CallbackInfo info) { bakedModels.put(new ModelIdentifier("simplemultipart:container#"), new MultipartContainerBakedModel()); + bakedModels.put(new ModelIdentifier("simplemultipart:tickable_container#"), new MultipartContainerBakedModel()); } } diff --git a/src/main/resources/assets/simplemultipart/blockstates/tickable_container.json b/src/main/resources/assets/simplemultipart/blockstates/tickable_container.json new file mode 100644 index 0000000..243ebfb --- /dev/null +++ b/src/main/resources/assets/simplemultipart/blockstates/tickable_container.json @@ -0,0 +1,5 @@ +{ + "variants": { + "": { "model": "block/air" } + } +}