Cut me down

This commit is contained in:
quat1024 2023-07-08 02:29:22 -04:00
parent e373b8b933
commit 65b3b97381
7 changed files with 69 additions and 29 deletions

View File

@ -6,6 +6,7 @@ import net.minecraft.block.Block;
import net.minecraft.block.BlockEntityProvider; import net.minecraft.block.BlockEntityProvider;
import net.minecraft.block.BlockState; import net.minecraft.block.BlockState;
import net.minecraft.block.Blocks; import net.minecraft.block.Blocks;
import net.minecraft.block.ShapeContext;
import net.minecraft.entity.LivingEntity; import net.minecraft.entity.LivingEntity;
import net.minecraft.entity.player.PlayerEntity; import net.minecraft.entity.player.PlayerEntity;
import net.minecraft.item.BlockItem; import net.minecraft.item.BlockItem;
@ -34,11 +35,9 @@ import org.jetbrains.annotations.Nullable;
public class TemplateInteractionUtil { public class TemplateInteractionUtil {
public static final BooleanProperty LIGHT = BooleanProperty.of("templates_light"); 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<Block, BlockState> appendProperties(StateManager.Builder<Block, BlockState> builder) { public static StateManager.Builder<Block, BlockState> appendProperties(StateManager.Builder<Block, BlockState> builder) {
return builder.add(LIGHT, REDSTONE, SOLID); return builder.add(LIGHT);
} }
public static AbstractBlock.Settings makeSettings() { public static AbstractBlock.Settings makeSettings() {
@ -51,8 +50,6 @@ public class TemplateInteractionUtil {
public static BlockState setDefaultStates(BlockState in) { public static BlockState setDefaultStates(BlockState in) {
if(in.contains(LIGHT)) in = in.with(LIGHT, false); 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; return in;
} }
@ -73,8 +70,8 @@ public class TemplateInteractionUtil {
} }
//Redstone //Redstone
if(state.contains(REDSTONE) && held.getItem() == Blocks.REDSTONE_TORCH.asItem() && !state.get(REDSTONE) && !be.hasSpentRedstoneTorch()) { if(held.getItem() == Blocks.REDSTONE_TORCH.asItem() && !be.emitsRedstone() && !be.hasSpentRedstoneTorch()) {
world.setBlockState(pos, state.with(REDSTONE, true)); be.setEmitsRedstone(true);
be.spentRedstoneTorch(); be.spentRedstoneTorch();
if(!player.isCreative()) held.decrement(1); if(!player.isCreative()) held.decrement(1);
@ -83,8 +80,8 @@ public class TemplateInteractionUtil {
} }
//Popped chorus fruit //Popped chorus fruit
if(state.contains(SOLID) && held.getItem() == Items.POPPED_CHORUS_FRUIT && state.get(SOLID) && !be.hasSpentPoppedChorus()) { if(held.getItem() == Items.POPPED_CHORUS_FRUIT && be.isSolid() && !be.hasSpentPoppedChorus()) {
world.setBlockState(pos, state.with(SOLID, false)); be.setSolidity(false);
be.spentPoppedChorus(); be.spentPoppedChorus();
if(!player.isCreative()) held.decrement(1); 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(placementState != null && Block.isShapeFullCube(placementState.getCollisionShape(world, pos)) && !(block instanceof BlockEntityProvider)) {
if(!world.isClient) be.setRenderedState(placementState); if(!world.isClient) be.setRenderedState(placementState);
world.setBlockState(pos, state world.setBlockState(pos, state.with(LIGHT, be.hasSpentGlowstoneDust() || (placementState.getLuminance() != 0)));
.with(LIGHT, be.hasSpentGlowstoneDust() || (placementState.getLuminance() != 0)) be.setEmitsRedstone(be.hasSpentRedstoneTorch() || placementState.getWeakRedstonePower(world, pos, Direction.NORTH) != 0);
.with(REDSTONE, be.hasSpentRedstoneTorch() || placementState.getWeakRedstonePower(world, pos, Direction.NORTH) != 0));
if(!player.isCreative()) held.decrement(1); if(!player.isCreative()) held.decrement(1);
world.playSound(player, pos, placementState.getSoundGroup().getPlaceSound(), SoundCategory.BLOCKS, 1f, 1.1f); 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) { public static @Nullable VoxelShape getCollisionShape(BlockState state, BlockView view, BlockPos pos, ShapeContext ctx) {
return state.contains(SOLID) && !state.get(SOLID) ? VoxelShapes.empty() : null; return view.getBlockEntity(pos) instanceof TemplateEntity be && !be.isSolid() ? VoxelShapes.empty() : null;
} }
public static boolean emitsRedstonePower(BlockState state) { 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) { 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) { 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) { public static int luminance(BlockState state) {

View File

@ -57,7 +57,7 @@ public class TemplateBlock extends Block implements BlockEntityProvider {
@Override @Override
public VoxelShape getCollisionShape(BlockState state, BlockView view, BlockPos pos, ShapeContext ctx) { 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 @Override

View File

@ -30,6 +30,9 @@ public class TemplateEntity extends BlockEntity implements ThemeableBlockEntity
protected boolean spentRedstoneTorch = false; protected boolean spentRedstoneTorch = false;
protected boolean spentPoppedChorus = false; protected boolean spentPoppedChorus = false;
protected boolean emitsRedstone;
protected boolean isSolid = true;
public TemplateEntity(BlockEntityType<?> type, BlockPos pos, BlockState state) { public TemplateEntity(BlockEntityType<?> type, BlockPos pos, BlockState state) {
super(type, pos, state); super(type, pos, state);
} }
@ -41,9 +44,12 @@ public class TemplateEntity extends BlockEntity implements ThemeableBlockEntity
BlockState lastRenderedState = renderedState; BlockState lastRenderedState = renderedState;
renderedState = NbtHelper.toBlockState(Registries.BLOCK.getReadOnlyWrapper(), tag.getCompound("BlockState")); renderedState = NbtHelper.toBlockState(Registries.BLOCK.getReadOnlyWrapper(), tag.getCompound("BlockState"));
spentGlowstoneDust = tag.getBoolean("Glowstone"); spentGlowstoneDust = tag.getBoolean("spentglow");
spentRedstoneTorch = tag.getBoolean("Redstone"); spentRedstoneTorch = tag.getBoolean("spentredst");
spentPoppedChorus = tag.getBoolean("Chorus"); 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 //Force a chunk remesh on the client if the displayed blockstate has changed
if(world != null && world.isClient && !Objects.equals(lastRenderedState, renderedState)) { 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) { public void writeNbt(NbtCompound tag) {
super.writeNbt(tag); super.writeNbt(tag);
tag.put("BlockState", NbtHelper.fromBlockState(renderedState)); tag.put("BlockState", NbtHelper.fromBlockState(renderedState));
tag.putBoolean("Glowstone", spentGlowstoneDust); tag.putBoolean("spentglow", spentGlowstoneDust);
tag.putBoolean("Redstone", spentRedstoneTorch); tag.putBoolean("spentredst", spentRedstoneTorch);
tag.putBoolean("Chorus", spentPoppedChorus); tag.putBoolean("spentchor", spentPoppedChorus);
tag.putBoolean("emitsredst", emitsRedstone);
tag.putBoolean("solid", isSolid);
} }
@Nullable @Nullable
@ -69,6 +78,7 @@ public class TemplateEntity extends BlockEntity implements ThemeableBlockEntity
@Override @Override
public NbtCompound toInitialChunkDataNbt() { public NbtCompound toInitialChunkDataNbt() {
//TERRIBLE yarn name, this is "getUpdateTag", it's the nbt that will be sent to clients //TERRIBLE yarn name, this is "getUpdateTag", it's the nbt that will be sent to clients
//and it just calls "writeNbt"
return createNbt(); return createNbt();
} }
@ -77,11 +87,15 @@ public class TemplateEntity extends BlockEntity implements ThemeableBlockEntity
return renderedState; return renderedState;
} }
private void dispatch() {
if(world instanceof ServerWorld sworld) sworld.getChunkManager().markForUpdate(pos);
}
public void setRenderedState(BlockState newState) { public void setRenderedState(BlockState newState) {
if(!Objects.equals(renderedState, newState)) { if(!Objects.equals(renderedState, newState)) {
renderedState = newState; renderedState = newState;
markDirty(); 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; spentPoppedChorus = true;
markDirty(); 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();
}
}
} }

View File

@ -58,7 +58,7 @@ public class TemplateFenceBlock extends FenceBlock implements BlockEntityProvide
@Override @Override
public VoxelShape getCollisionShape(BlockState state, BlockView view, BlockPos pos, ShapeContext ctx) { 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 @Override

View File

@ -47,7 +47,7 @@ public class TemplatePostBlock extends WaterloggableTemplateBlock {
@Override @Override
public VoxelShape getCollisionShape(BlockState state, BlockView view, BlockPos pos, ShapeContext ctx) { 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 @Override

View File

@ -58,7 +58,7 @@ public class TemplateSlabBlock extends SlabBlock implements BlockEntityProvider
@Override @Override
public VoxelShape getCollisionShape(BlockState state, BlockView view, BlockPos pos, ShapeContext ctx) { 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 @Override

View File

@ -66,7 +66,7 @@ public class TemplateWallBlock extends WallBlock implements BlockEntityProvider
@Override @Override
public VoxelShape getCollisionShape(BlockState state, BlockView view, BlockPos pos, ShapeContext ctx) { 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 @Override