From 720e98c30b61c670426862759ec25bff7a13c74b Mon Sep 17 00:00:00 2001 From: quat1024 Date: Mon, 3 Jul 2023 03:35:07 -0400 Subject: [PATCH] Redo a lot of redstone/glowstone logic --- .../cottonmc/templates/block/SlopeBlock.java | 4 +- .../templates/block/TemplateBlock.java | 136 +++++++++--------- .../block/entity/TemplateEntity.java | 73 +++++----- .../templates/model/TemplateAppearance.java | 4 - 4 files changed, 105 insertions(+), 112 deletions(-) diff --git a/src/main/java/io/github/cottonmc/templates/block/SlopeBlock.java b/src/main/java/io/github/cottonmc/templates/block/SlopeBlock.java index 52489c7..921d691 100644 --- a/src/main/java/io/github/cottonmc/templates/block/SlopeBlock.java +++ b/src/main/java/io/github/cottonmc/templates/block/SlopeBlock.java @@ -32,12 +32,12 @@ public class SlopeBlock extends TemplateBlock { super(TemplateBlock.configureSettings(Settings.create()) .sounds(BlockSoundGroup.WOOD) .hardness(0.2f)); //TODO: Material.WOOD - this.setDefaultState(this.getStateManager().getDefaultState().with(FACING, Direction.NORTH).with(LIGHT, 0).with(REDSTONE, false)); + setDefaultState(getDefaultState().with(FACING, Direction.NORTH)); } @Override protected void appendProperties(StateManager.Builder builder) { - builder.add(FACING, LIGHT, REDSTONE); + super.appendProperties(builder.add(FACING)); } @Override 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 36f7d68..4b8dcdf 100644 --- a/src/main/java/io/github/cottonmc/templates/block/TemplateBlock.java +++ b/src/main/java/io/github/cottonmc/templates/block/TemplateBlock.java @@ -1,23 +1,25 @@ package io.github.cottonmc.templates.block; -import io.github.cottonmc.templates.Templates; import io.github.cottonmc.templates.block.entity.TemplateEntity; import net.minecraft.block.Block; import net.minecraft.block.BlockEntityProvider; import net.minecraft.block.BlockState; import net.minecraft.block.Blocks; -import net.minecraft.block.entity.BlockEntity; -import net.minecraft.entity.ItemEntity; import net.minecraft.entity.player.PlayerEntity; import net.minecraft.item.BlockItem; import net.minecraft.item.ItemPlacementContext; import net.minecraft.item.ItemStack; import net.minecraft.item.ItemUsageContext; import net.minecraft.item.Items; +import net.minecraft.sound.SoundCategory; +import net.minecraft.sound.SoundEvents; +import net.minecraft.state.StateManager; import net.minecraft.state.property.BooleanProperty; import net.minecraft.state.property.IntProperty; import net.minecraft.util.ActionResult; import net.minecraft.util.Hand; +import net.minecraft.util.ItemScatterer; +import net.minecraft.util.collection.DefaultedList; import net.minecraft.util.hit.BlockHitResult; import net.minecraft.util.math.BlockPos; import net.minecraft.util.math.Direction; @@ -30,6 +32,8 @@ public abstract class TemplateBlock extends Block implements BlockEntityProvider public TemplateBlock(Settings settings) { super(settings); + + setDefaultState(getDefaultState().with(LIGHT, 0).with(REDSTONE, false)); } public static Settings configureSettings(Settings s) { @@ -38,69 +42,75 @@ public abstract class TemplateBlock extends Block implements BlockEntityProvider .nonOpaque(); } + @Override + protected void appendProperties(StateManager.Builder builder) { + super.appendProperties(builder.add(LIGHT, REDSTONE)); + } + @Override public ActionResult onUse(BlockState state, World world, BlockPos pos, PlayerEntity player, Hand hand, BlockHitResult hit) { - if(world.isClient || !(world.getBlockEntity(pos) instanceof TemplateEntity be)) return ActionResult.SUCCESS; + if(!state.isOf(this) || !(world.getBlockEntity(pos) instanceof TemplateEntity be)) return ActionResult.PASS; //shouldn't happen + if(!player.canModifyBlocks() || !world.canPlayerModifyAt(player, pos)) return ActionResult.PASS; - ItemStack stack = player.getStackInHand(hand); - if(stack.getItem() instanceof BlockItem) { - Block block = ((BlockItem) stack.getItem()).getBlock(); - if(block == Blocks.REDSTONE_TORCH) { - be.setRedstone(true); - if(!player.isCreative()) stack.decrement(1); - } + ItemStack held = player.getStackInHand(hand); + + //Glowstone + if(held.getItem() == Items.GLOWSTONE_DUST && state.get(LIGHT) != 15 && !be.hasSpentGlowstoneDust()) { + world.setBlockState(pos, state.with(LIGHT, 15)); + be.spentGlowstoneDust(); + + if(!player.isCreative()) held.decrement(1); + world.playSound(player, pos, SoundEvents.BLOCK_GLASS_HIT, SoundCategory.BLOCKS, 1f, 1f); + return ActionResult.SUCCESS; + } + + //Redstone + if(held.getItem() == Blocks.REDSTONE_TORCH.asItem() && !state.get(REDSTONE) && !be.hasSpentRedstoneTorch()) { + world.setBlockState(pos, state.with(REDSTONE, true)); + be.spentRedstoneTorch(); + + if(!player.isCreative()) held.decrement(1); + world.playSound(player, pos, SoundEvents.BLOCK_LEVER_CLICK, SoundCategory.BLOCKS, 1f, 1f); + return ActionResult.SUCCESS; + } + + //Changing the theme + if(held.getItem() instanceof BlockItem bi && be.getRenderedState().getBlock() == Blocks.AIR) { + Block block = bi.getBlock(); ItemPlacementContext ctx = new ItemPlacementContext(new ItemUsageContext(player, hand, hit)); BlockState placementState = block.getPlacementState(ctx); - if(placementState != null && - Block.isShapeFullCube(placementState.getCollisionShape(world, pos)) && - !(block instanceof BlockEntityProvider) && - be.getRenderedState().getBlock() == Blocks.AIR) - { - be.setRenderedState(placementState); - if(!player.isCreative()) stack.decrement(1); + if(placementState != null && Block.isShapeFullCube(placementState.getCollisionShape(world, pos)) && !(block instanceof BlockEntityProvider)) { + if(!world.isClient) be.setRenderedState(placementState); + + //Even if the block does not glow, this'll do a block update when adding a redstoney block + int newLuminance = be.hasSpentGlowstoneDust() ? 15 : placementState.getLuminance(); + world.setBlockState(pos, state.with(LIGHT, newLuminance)); + + if(!player.isCreative()) held.decrement(1); + world.playSound(player, pos, state.getSoundGroup().getPlaceSound(), SoundCategory.BLOCKS, 1f, 1f); + return ActionResult.SUCCESS; } - } else if(stack.getItem() == Items.GLOWSTONE_DUST) { - be.setGlowstone(true); - if(!player.isCreative()) stack.decrement(1); } - return ActionResult.SUCCESS; + + return ActionResult.PASS; } @Override public void onStateReplaced(BlockState state, World world, BlockPos pos, BlockState newState, boolean moved) { - if(newState.getBlock() == Templates.SLOPE) return; - BlockEntity be = world.getBlockEntity(pos); - if(be instanceof TemplateEntity) { - TemplateEntity template = (TemplateEntity) be; - if(template.getRenderedState().getBlock() != Blocks.AIR) { - ItemStack stack = new ItemStack(template.getRenderedState().getBlock()); - ItemEntity entity = new ItemEntity(world, pos.getX(), pos.getY(), pos.getZ(), stack); - world.spawnEntity(entity); - } - if(template.hasRedstone()) { - ItemStack stack = new ItemStack(Items.REDSTONE_TORCH); - ItemEntity entity = new ItemEntity(world, pos.getX(), pos.getY(), pos.getZ(), stack); - world.spawnEntity(entity); - } - if(template.hasGlowstone()) { - ItemStack stack = new ItemStack(Items.GLOWSTONE_DUST); - ItemEntity entity = new ItemEntity(world, pos.getX(), pos.getY(), pos.getZ(), stack); - world.spawnEntity(entity); - } + if(!state.isOf(newState.getBlock()) && world.getBlockEntity(pos) instanceof TemplateEntity template) { + DefaultedList drops = DefaultedList.of(); + + Block theme = template.getRenderedState().getBlock(); + if(theme != Blocks.AIR) drops.add(new ItemStack(theme)); + if(template.hasSpentRedstoneTorch()) drops.add(new ItemStack(Items.REDSTONE_TORCH)); + if(template.hasSpentGlowstoneDust()) drops.add(new ItemStack(Items.GLOWSTONE_DUST)); + + ItemScatterer.spawn(world, pos, drops); } + super.onStateReplaced(state, world, pos, newState, moved); } - @Override - public void neighborUpdate(BlockState state, World world, BlockPos pos, Block block, BlockPos posFrom, boolean bool) { - BlockEntity be = world.getBlockEntity(pos); - if(be instanceof TemplateEntity) { - TemplateEntity template = (TemplateEntity) be; - BlockState beState = template.getRenderedState(); - world.setBlockState(pos, state.with(LIGHT, template.hasGlowstone() ? 15 : beState.getLuminance()).with(REDSTONE, template.hasRedstone() || beState.emitsRedstonePower())); - } - } - @Override public boolean emitsRedstonePower(BlockState state) { return state.get(REDSTONE); @@ -108,30 +118,18 @@ public abstract class TemplateBlock extends Block implements BlockEntityProvider @Override public int getWeakRedstonePower(BlockState state, BlockView view, BlockPos pos, Direction dir) { - BlockEntity be = view.getBlockEntity(pos); - if(be instanceof TemplateEntity) { - TemplateEntity template = (TemplateEntity) be; - if(template.hasRedstone()) return 15; - BlockState beState = template.getRenderedState(); - return beState.getWeakRedstonePower(view, pos, dir); - } - return 0; + if(state.get(REDSTONE)) return 15; + else if(view.getBlockEntity(pos) instanceof TemplateEntity template) return template.getRenderedState().getWeakRedstonePower(view, pos, dir); + else return 0; } @Override public int getStrongRedstonePower(BlockState state, BlockView view, BlockPos pos, Direction dir) { - BlockEntity be = view.getBlockEntity(pos); - if(be instanceof TemplateEntity) { - TemplateEntity template = (TemplateEntity) be; - if(template.hasRedstone()) return 15; - BlockState beState = template.getRenderedState(); - return beState.getStrongRedstonePower(view, pos, dir); - } - return 0; + if(state.get(REDSTONE)) return 15; + else if(view.getBlockEntity(pos) instanceof TemplateEntity template) return template.getRenderedState().getStrongRedstonePower(view, pos, dir); + else return 0; } - //TODO: pass to Block.Settings - // "Cannot reference 'TemplateBlock.luminance' before supertype constructor has been called" public int luminance(BlockState state) { return state.get(LIGHT); } diff --git a/src/main/java/io/github/cottonmc/templates/block/entity/TemplateEntity.java b/src/main/java/io/github/cottonmc/templates/block/entity/TemplateEntity.java index abdf717..566e3df 100644 --- a/src/main/java/io/github/cottonmc/templates/block/entity/TemplateEntity.java +++ b/src/main/java/io/github/cottonmc/templates/block/entity/TemplateEntity.java @@ -20,8 +20,14 @@ import java.util.Objects; public class TemplateEntity extends BlockEntity implements RenderAttachmentBlockEntity { protected BlockState renderedState = Blocks.AIR.getDefaultState(); - protected boolean glowstone = false; - protected boolean redstone = false; + + //Whether the player has manually spent a redstone/glowstone item to upgrade the template. + //It's possible to get templates that, e.g. glow, without manually spending a glowstone on them + //(put a froglight in a template!) Same for redstone activation. We need to separately store + //whether a redstone/glowstone should be refunded when the player breaks the template, and wasting a + //blockstate for it is a little silly, so, here you go. + protected boolean spentGlowstoneDust = false; + protected boolean spentRedstoneTorch = false; public TemplateEntity(BlockEntityType type, BlockPos pos, BlockState state) { super(type, pos, state); @@ -34,10 +40,10 @@ public class TemplateEntity extends BlockEntity implements RenderAttachmentBlock BlockState lastRenderedState = renderedState; renderedState = NbtHelper.toBlockState(Registries.BLOCK.getReadOnlyWrapper(), tag.getCompound("BlockState")); - glowstone = tag.getBoolean("Glowstone"); - redstone = tag.getBoolean("Redstone"); + spentGlowstoneDust = tag.getBoolean("Glowstone"); + spentRedstoneTorch = tag.getBoolean("Redstone"); - //Force a chunk remesh on the client, if the displayed blockstate has changed + //Force a chunk remesh on the client if the displayed blockstate has changed if(world != null && world.isClient && !Objects.equals(lastRenderedState, renderedState)) { Templates.chunkRerenderProxy.accept(world, pos); } @@ -47,8 +53,8 @@ public class TemplateEntity extends BlockEntity implements RenderAttachmentBlock public void writeNbt(NbtCompound tag) { super.writeNbt(tag); tag.put("BlockState", NbtHelper.fromBlockState(renderedState)); - tag.putBoolean("Glowstone", glowstone); - tag.putBoolean("Redstone", redstone); + tag.putBoolean("Glowstone", spentGlowstoneDust); + tag.putBoolean("Redstone", spentRedstoneTorch); } @Nullable @@ -59,6 +65,7 @@ public class TemplateEntity extends BlockEntity implements RenderAttachmentBlock @Override public NbtCompound toInitialChunkDataNbt() { + //TERRIBLE yarn name, this is "getUpdateTag", it's the nbt that will be sent to clients return createNbt(); } @@ -67,41 +74,33 @@ public class TemplateEntity extends BlockEntity implements RenderAttachmentBlock return renderedState; } - public void change() { - markDirty(); - if(world instanceof ServerWorld sworld) sworld.getChunkManager().markForUpdate(pos); //dispatch to clients - } - public BlockState getRenderedState() { return renderedState; } public void setRenderedState(BlockState newState) { - BlockState lastState = renderedState; - renderedState = newState; - if(!Objects.equals(lastState, newState)) change(); - } - - public boolean hasGlowstone() { - return glowstone; - } - - public void setGlowstone(boolean newGlowstone) { - boolean lastGlowstone = glowstone; - glowstone = newGlowstone; - if(lastGlowstone != newGlowstone) change(); - } - - public boolean hasRedstone() { - return redstone; - } - - public void setRedstone(boolean newRedstone) { - boolean lastRedstone = redstone; - redstone = newRedstone; - if(lastRedstone != newRedstone) { - world.updateNeighbors(pos, getCachedState().getBlock()); - change(); + if(!Objects.equals(renderedState, newState)) { + renderedState = newState; + markDirty(); + if(world instanceof ServerWorld sworld) sworld.getChunkManager().markForUpdate(pos); //dispatch to clients } } + + public boolean hasSpentGlowstoneDust() { + return spentGlowstoneDust; + } + + public void spentGlowstoneDust() { + spentGlowstoneDust = true; + markDirty(); + } + + public boolean hasSpentRedstoneTorch() { + return spentRedstoneTorch; + } + + public void spentRedstoneTorch() { + spentRedstoneTorch = true; + markDirty(); + } } diff --git a/src/main/java/io/github/cottonmc/templates/model/TemplateAppearance.java b/src/main/java/io/github/cottonmc/templates/model/TemplateAppearance.java index dc78121..cdbb4f5 100644 --- a/src/main/java/io/github/cottonmc/templates/model/TemplateAppearance.java +++ b/src/main/java/io/github/cottonmc/templates/model/TemplateAppearance.java @@ -5,14 +5,10 @@ import net.minecraft.client.texture.Sprite; import net.minecraft.util.math.Direction; import org.jetbrains.annotations.NotNull; -import java.util.Objects; - public interface TemplateAppearance { @NotNull Sprite getParticleSprite(); //TODO: plug this in @NotNull RenderMaterial getRenderMaterial(); @NotNull Sprite getSprite(Direction dir); boolean hasColor(Direction dir); - - }