diff --git a/src/main/java/io/github/cottonmc/templates/api/TemplateInteractionUtil.java b/src/main/java/io/github/cottonmc/templates/api/TemplateInteractionUtil.java index 9c059f0..1e333c3 100644 --- a/src/main/java/io/github/cottonmc/templates/api/TemplateInteractionUtil.java +++ b/src/main/java/io/github/cottonmc/templates/api/TemplateInteractionUtil.java @@ -6,6 +6,7 @@ import net.minecraft.block.Block; import net.minecraft.block.BlockEntityProvider; import net.minecraft.block.BlockState; import net.minecraft.block.Blocks; +import net.minecraft.block.ShapeContext; import net.minecraft.entity.LivingEntity; import net.minecraft.entity.player.PlayerEntity; import net.minecraft.item.BlockItem; @@ -34,11 +35,9 @@ import org.jetbrains.annotations.Nullable; public class TemplateInteractionUtil { public static final BooleanProperty LIGHT = BooleanProperty.of("templates_light"); - public static final BooleanProperty REDSTONE = BooleanProperty.of("templates_redstone"); - public static final BooleanProperty SOLID = BooleanProperty.of("templates_solid"); public static StateManager.Builder appendProperties(StateManager.Builder builder) { - return builder.add(LIGHT, REDSTONE, SOLID); + return builder.add(LIGHT); } public static AbstractBlock.Settings makeSettings() { @@ -51,8 +50,6 @@ public class TemplateInteractionUtil { public static BlockState setDefaultStates(BlockState in) { if(in.contains(LIGHT)) in = in.with(LIGHT, false); - if(in.contains(REDSTONE)) in = in.with(REDSTONE, false); - if(in.contains(SOLID)) in = in.with(SOLID, true); return in; } @@ -73,8 +70,8 @@ public class TemplateInteractionUtil { } //Redstone - if(state.contains(REDSTONE) && held.getItem() == Blocks.REDSTONE_TORCH.asItem() && !state.get(REDSTONE) && !be.hasSpentRedstoneTorch()) { - world.setBlockState(pos, state.with(REDSTONE, true)); + if(held.getItem() == Blocks.REDSTONE_TORCH.asItem() && !be.emitsRedstone() && !be.hasSpentRedstoneTorch()) { + be.setEmitsRedstone(true); be.spentRedstoneTorch(); if(!player.isCreative()) held.decrement(1); @@ -83,8 +80,8 @@ public class TemplateInteractionUtil { } //Popped chorus fruit - if(state.contains(SOLID) && held.getItem() == Items.POPPED_CHORUS_FRUIT && state.get(SOLID) && !be.hasSpentPoppedChorus()) { - world.setBlockState(pos, state.with(SOLID, false)); + if(held.getItem() == Items.POPPED_CHORUS_FRUIT && be.isSolid() && !be.hasSpentPoppedChorus()) { + be.setSolidity(false); be.spentPoppedChorus(); if(!player.isCreative()) held.decrement(1); @@ -100,9 +97,8 @@ public class TemplateInteractionUtil { if(placementState != null && Block.isShapeFullCube(placementState.getCollisionShape(world, pos)) && !(block instanceof BlockEntityProvider)) { if(!world.isClient) be.setRenderedState(placementState); - world.setBlockState(pos, state - .with(LIGHT, be.hasSpentGlowstoneDust() || (placementState.getLuminance() != 0)) - .with(REDSTONE, be.hasSpentRedstoneTorch() || placementState.getWeakRedstonePower(world, pos, Direction.NORTH) != 0)); + world.setBlockState(pos, state.with(LIGHT, be.hasSpentGlowstoneDust() || (placementState.getLuminance() != 0))); + be.setEmitsRedstone(be.hasSpentRedstoneTorch() || placementState.getWeakRedstonePower(world, pos, Direction.NORTH) != 0); if(!player.isCreative()) held.decrement(1); world.playSound(player, pos, placementState.getSoundGroup().getPlaceSound(), SoundCategory.BLOCKS, 1f, 1.1f); @@ -138,20 +134,21 @@ public class TemplateInteractionUtil { } } - public static @Nullable VoxelShape getCollisionShape(BlockState state) { - return state.contains(SOLID) && !state.get(SOLID) ? VoxelShapes.empty() : null; + public static @Nullable VoxelShape getCollisionShape(BlockState state, BlockView view, BlockPos pos, ShapeContext ctx) { + return view.getBlockEntity(pos) instanceof TemplateEntity be && !be.isSolid() ? VoxelShapes.empty() : null; } public static boolean emitsRedstonePower(BlockState state) { - return state.contains(REDSTONE) ? state.get(REDSTONE) : false; + //return state.contains(REDSTONE) ? state.get(REDSTONE) : false; + return false; //TODO, not available after punting this to BlockEntity. Yarn makes this method sound more important than it is, it's just for dust redirection. } public static int getWeakRedstonePower(BlockState state, BlockView view, BlockPos pos, Direction dir) { - return state.contains(REDSTONE) && state.get(REDSTONE) ? 15 : 0; + return view.getBlockEntity(pos) instanceof TemplateEntity be && be.emitsRedstone() ? 15 : 0; } public static int getStrongRedstonePower(BlockState state, BlockView view, BlockPos pos, Direction dir) { - return state.contains(REDSTONE) && state.get(REDSTONE) ? 15 : 0; + return view.getBlockEntity(pos) instanceof TemplateEntity be && be.emitsRedstone() ? 15 : 0; } public static int luminance(BlockState state) { diff --git a/src/main/java/io/github/cottonmc/templates/block/TemplateBlock.java b/src/main/java/io/github/cottonmc/templates/block/TemplateBlock.java index 73891b4..a5045c1 100644 --- a/src/main/java/io/github/cottonmc/templates/block/TemplateBlock.java +++ b/src/main/java/io/github/cottonmc/templates/block/TemplateBlock.java @@ -57,7 +57,7 @@ public class TemplateBlock extends Block implements BlockEntityProvider { @Override public VoxelShape getCollisionShape(BlockState state, BlockView view, BlockPos pos, ShapeContext ctx) { - return MoreObjects.firstNonNull(TemplateInteractionUtil.getCollisionShape(state), super.getCollisionShape(state, view, pos, ctx)); + return MoreObjects.firstNonNull(TemplateInteractionUtil.getCollisionShape(state, view, pos, ctx), super.getCollisionShape(state, view, pos, ctx)); } @Override diff --git a/src/main/java/io/github/cottonmc/templates/block/TemplateEntity.java b/src/main/java/io/github/cottonmc/templates/block/TemplateEntity.java index 50cb905..50ec711 100644 --- a/src/main/java/io/github/cottonmc/templates/block/TemplateEntity.java +++ b/src/main/java/io/github/cottonmc/templates/block/TemplateEntity.java @@ -30,6 +30,9 @@ public class TemplateEntity extends BlockEntity implements ThemeableBlockEntity protected boolean spentRedstoneTorch = false; protected boolean spentPoppedChorus = false; + protected boolean emitsRedstone; + protected boolean isSolid = true; + public TemplateEntity(BlockEntityType type, BlockPos pos, BlockState state) { super(type, pos, state); } @@ -41,9 +44,12 @@ public class TemplateEntity extends BlockEntity implements ThemeableBlockEntity BlockState lastRenderedState = renderedState; renderedState = NbtHelper.toBlockState(Registries.BLOCK.getReadOnlyWrapper(), tag.getCompound("BlockState")); - spentGlowstoneDust = tag.getBoolean("Glowstone"); - spentRedstoneTorch = tag.getBoolean("Redstone"); - spentPoppedChorus = tag.getBoolean("Chorus"); + spentGlowstoneDust = tag.getBoolean("spentglow"); + spentRedstoneTorch = tag.getBoolean("spentredst"); + spentPoppedChorus = tag.getBoolean("spentchor"); + + emitsRedstone = tag.getBoolean("emitsredst"); + isSolid = !tag.contains("solid") || tag.getBoolean("solid"); //default to "true" if it's nonexistent //Force a chunk remesh on the client if the displayed blockstate has changed if(world != null && world.isClient && !Objects.equals(lastRenderedState, renderedState)) { @@ -55,9 +61,12 @@ public class TemplateEntity extends BlockEntity implements ThemeableBlockEntity public void writeNbt(NbtCompound tag) { super.writeNbt(tag); tag.put("BlockState", NbtHelper.fromBlockState(renderedState)); - tag.putBoolean("Glowstone", spentGlowstoneDust); - tag.putBoolean("Redstone", spentRedstoneTorch); - tag.putBoolean("Chorus", spentPoppedChorus); + tag.putBoolean("spentglow", spentGlowstoneDust); + tag.putBoolean("spentredst", spentRedstoneTorch); + tag.putBoolean("spentchor", spentPoppedChorus); + + tag.putBoolean("emitsredst", emitsRedstone); + tag.putBoolean("solid", isSolid); } @Nullable @@ -69,6 +78,7 @@ public class TemplateEntity extends BlockEntity implements ThemeableBlockEntity @Override public NbtCompound toInitialChunkDataNbt() { //TERRIBLE yarn name, this is "getUpdateTag", it's the nbt that will be sent to clients + //and it just calls "writeNbt" return createNbt(); } @@ -77,11 +87,15 @@ public class TemplateEntity extends BlockEntity implements ThemeableBlockEntity return renderedState; } + private void dispatch() { + if(world instanceof ServerWorld sworld) sworld.getChunkManager().markForUpdate(pos); + } + public void setRenderedState(BlockState newState) { if(!Objects.equals(renderedState, newState)) { renderedState = newState; markDirty(); - if(world instanceof ServerWorld sworld) sworld.getChunkManager().markForUpdate(pos); //dispatch to clients + dispatch(); } } @@ -111,4 +125,33 @@ public class TemplateEntity extends BlockEntity implements ThemeableBlockEntity spentPoppedChorus = true; markDirty(); } + + public boolean emitsRedstone() { + return emitsRedstone; + } + + public void setEmitsRedstone(boolean emitsRedstone) { + if(this.emitsRedstone != emitsRedstone) { + this.emitsRedstone = emitsRedstone; + markDirty(); + + if(world != null) world.updateNeighbors(pos, getCachedState().getBlock()); + } + } + + public boolean isSolid() { + return isSolid; + } + + public void setSolidity(boolean isSolid) { + if(this.isSolid != isSolid) { + this.isSolid = isSolid; + markDirty(); + + //do i need to invalidate any shape caches or something + if(world != null) world.setBlockState(pos, getCachedState()); + + dispatch(); + } + } } diff --git a/src/main/java/io/github/cottonmc/templates/block/TemplateFenceBlock.java b/src/main/java/io/github/cottonmc/templates/block/TemplateFenceBlock.java index 3108c50..607b2fc 100644 --- a/src/main/java/io/github/cottonmc/templates/block/TemplateFenceBlock.java +++ b/src/main/java/io/github/cottonmc/templates/block/TemplateFenceBlock.java @@ -58,7 +58,7 @@ public class TemplateFenceBlock extends FenceBlock implements BlockEntityProvide @Override public VoxelShape getCollisionShape(BlockState state, BlockView view, BlockPos pos, ShapeContext ctx) { - return MoreObjects.firstNonNull(TemplateInteractionUtil.getCollisionShape(state), super.getCollisionShape(state, view, pos, ctx)); + return MoreObjects.firstNonNull(TemplateInteractionUtil.getCollisionShape(state, view, pos, ctx), super.getCollisionShape(state, view, pos, ctx)); } @Override diff --git a/src/main/java/io/github/cottonmc/templates/block/TemplatePostBlock.java b/src/main/java/io/github/cottonmc/templates/block/TemplatePostBlock.java index 0bb8de1..b575385 100644 --- a/src/main/java/io/github/cottonmc/templates/block/TemplatePostBlock.java +++ b/src/main/java/io/github/cottonmc/templates/block/TemplatePostBlock.java @@ -47,7 +47,7 @@ public class TemplatePostBlock extends WaterloggableTemplateBlock { @Override public VoxelShape getCollisionShape(BlockState state, BlockView view, BlockPos pos, ShapeContext ctx) { - return MoreObjects.firstNonNull(TemplateInteractionUtil.getCollisionShape(state), shap(state)); + return MoreObjects.firstNonNull(TemplateInteractionUtil.getCollisionShape(state, view, pos, ctx), shap(state)); } @Override diff --git a/src/main/java/io/github/cottonmc/templates/block/TemplateSlabBlock.java b/src/main/java/io/github/cottonmc/templates/block/TemplateSlabBlock.java index ba42095..a85df87 100644 --- a/src/main/java/io/github/cottonmc/templates/block/TemplateSlabBlock.java +++ b/src/main/java/io/github/cottonmc/templates/block/TemplateSlabBlock.java @@ -58,7 +58,7 @@ public class TemplateSlabBlock extends SlabBlock implements BlockEntityProvider @Override public VoxelShape getCollisionShape(BlockState state, BlockView view, BlockPos pos, ShapeContext ctx) { - return MoreObjects.firstNonNull(TemplateInteractionUtil.getCollisionShape(state), super.getCollisionShape(state, view, pos, ctx)); + return MoreObjects.firstNonNull(TemplateInteractionUtil.getCollisionShape(state, view, pos, ctx), super.getCollisionShape(state, view, pos, ctx)); } @Override diff --git a/src/main/java/io/github/cottonmc/templates/block/TemplateWallBlock.java b/src/main/java/io/github/cottonmc/templates/block/TemplateWallBlock.java index b9f0610..9abfd8c 100644 --- a/src/main/java/io/github/cottonmc/templates/block/TemplateWallBlock.java +++ b/src/main/java/io/github/cottonmc/templates/block/TemplateWallBlock.java @@ -66,7 +66,7 @@ public class TemplateWallBlock extends WallBlock implements BlockEntityProvider @Override public VoxelShape getCollisionShape(BlockState state, BlockView view, BlockPos pos, ShapeContext ctx) { - return MoreObjects.firstNonNull(TemplateInteractionUtil.getCollisionShape(state), getNewShape(state, newCollisionShapeMap)); + return MoreObjects.firstNonNull(TemplateInteractionUtil.getCollisionShape(state, view, pos, ctx), getNewShape(state, newCollisionShapeMap)); } @Override