Use separate blocks for ticking/non-ticking containers
This commit is contained in:
parent
42413ebfae
commit
6d0a8f22bf
|
@ -31,12 +31,14 @@ public class SimpleMultipart implements ModInitializer {
|
||||||
public static final LootContextType MULTIPART_LOOT_CONTEXT = createMultipartLootContextType();
|
public static final LootContextType MULTIPART_LOOT_CONTEXT = createMultipartLootContextType();
|
||||||
|
|
||||||
public static final ContainerBlock containerBlock = new ContainerBlock();
|
public static final ContainerBlock containerBlock = new ContainerBlock();
|
||||||
|
public static final TickableContainerBlock tickableContainerBlock = new TickableContainerBlock();
|
||||||
public static final BlockEntityType<ContainerBlockEntity> containerBlockEntity = createBlockEntityType("container", ContainerBlockEntity::new);
|
public static final BlockEntityType<ContainerBlockEntity> containerBlockEntity = createBlockEntityType("container", ContainerBlockEntity::new);
|
||||||
public static final BlockEntityType<TickableContainerBlockEntity> tickableContainerBlockEntity = createBlockEntityType("tickable_container", TickableContainerBlockEntity::new);
|
public static final BlockEntityType<TickableContainerBlockEntity> tickableContainerBlockEntity = createBlockEntityType("tickable_container", TickableContainerBlockEntity::new);
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onInitialize() {
|
public void onInitialize() {
|
||||||
Registry.register(Registry.BLOCK, new Identifier(MODID, "container"), containerBlock);
|
Registry.register(Registry.BLOCK, new Identifier(MODID, "container"), containerBlock);
|
||||||
|
Registry.register(Registry.BLOCK, new Identifier(MODID, "tickable_container"), tickableContainerBlock);
|
||||||
|
|
||||||
ContainerEventHandler.register();
|
ContainerEventHandler.register();
|
||||||
}
|
}
|
||||||
|
|
|
@ -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<MultipartView> 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);
|
||||||
|
}
|
|
@ -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 hasTickableParts = parts.stream().anyMatch(e -> e.getEntity() != null && e.getEntity() instanceof Tickable);
|
||||||
boolean currentlyTickable = this instanceof Tickable;
|
boolean currentlyTickable = this instanceof Tickable;
|
||||||
if (hasTickableParts != currentlyTickable) {
|
if (hasTickableParts != currentlyTickable) {
|
||||||
AbstractContainerBlockEntity newContainer = hasTickableParts ? new TickableContainerBlockEntity() : new ContainerBlockEntity();
|
Block newBlock = hasTickableParts ? SimpleMultipart.tickableContainerBlock : SimpleMultipart.containerBlock;
|
||||||
world.setBlockEntity(pos, newContainer);
|
world.setBlockState(pos, newBlock.getDefaultState(), 3);
|
||||||
|
AbstractContainerBlockEntity newContainer = (AbstractContainerBlockEntity)world.getBlockEntity(pos);
|
||||||
newContainer.parts = parts.stream()
|
newContainer.parts = parts.stream()
|
||||||
.map(e -> new Entry(newContainer, e.state, e.entity))
|
.map(e -> new Entry(newContainer, e.state, e.entity))
|
||||||
.collect(Collectors.toSet());
|
.collect(Collectors.toSet());
|
||||||
|
newContainer.parts.stream().filter(e -> e.entity != null).forEach(e -> e.entity.container = newContainer);
|
||||||
}
|
}
|
||||||
|
|
||||||
world.markDirty(pos, world.getBlockEntity(pos));
|
world.markDirty(pos, world.getBlockEntity(pos));
|
||||||
|
|
|
@ -1,77 +1,15 @@
|
||||||
package net.shadowfacts.simplemultipart.container;
|
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.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
|
* @author shadowfacts
|
||||||
*/
|
*/
|
||||||
public class ContainerBlock extends Block implements BlockEntityProvider, RenderStateProvider {
|
public class ContainerBlock extends AbstractContainerBlock {
|
||||||
|
|
||||||
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<MultipartView> 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
|
@Override
|
||||||
public AbstractContainerBlockEntity createBlockEntity(BlockView world) {
|
public AbstractContainerBlockEntity createBlockEntity(BlockView world) {
|
||||||
return new ContainerBlockEntity();
|
return new ContainerBlockEntity();
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -23,7 +23,12 @@ public class ContainerEventHandler {
|
||||||
}
|
}
|
||||||
|
|
||||||
private static ActionResult handleBlockAttack(PlayerEntity player, World world, Hand hand, BlockPos pos, Direction direction) {
|
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;
|
return ActionResult.PASS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -28,6 +28,7 @@ public abstract class MixinModelLoader {
|
||||||
@Inject(method = "<init>", at = @At("RETURN"))
|
@Inject(method = "<init>", at = @At("RETURN"))
|
||||||
public void addMultipartModel(ResourceManager manager, SpriteAtlasTexture texture, CallbackInfo info) {
|
public void addMultipartModel(ResourceManager manager, SpriteAtlasTexture texture, CallbackInfo info) {
|
||||||
bakedModels.put(new ModelIdentifier("simplemultipart:container#"), new MultipartContainerBakedModel());
|
bakedModels.put(new ModelIdentifier("simplemultipart:container#"), new MultipartContainerBakedModel());
|
||||||
|
bakedModels.put(new ModelIdentifier("simplemultipart:tickable_container#"), new MultipartContainerBakedModel());
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,5 @@
|
||||||
|
{
|
||||||
|
"variants": {
|
||||||
|
"": { "model": "block/air" }
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue