Sure, why not

This commit is contained in:
quat1024 2023-07-05 23:40:12 -04:00
parent 30a7fae3cb
commit 084861080b
7 changed files with 143 additions and 8 deletions

View File

@ -27,16 +27,19 @@ import net.minecraft.util.collection.DefaultedList;
import net.minecraft.util.hit.BlockHitResult;
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.World;
import org.jetbrains.annotations.Nullable;
public class TemplateInteractionUtil {
public static final IntProperty LIGHT = IntProperty.of("light", 0, 15);
public static final BooleanProperty REDSTONE = BooleanProperty.of("redstone");
public static final IntProperty LIGHT = IntProperty.of("templates_light", 0, 15);
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) {
return builder.add(LIGHT, REDSTONE);
return builder.add(LIGHT, REDSTONE, SOLID);
}
public static AbstractBlock.Settings makeSettings() {
@ -48,7 +51,7 @@ public class TemplateInteractionUtil {
}
public static BlockState setDefaultStates(BlockState in) {
return in.with(LIGHT, 0).with(REDSTONE, false);
return in.with(LIGHT, 0).with(REDSTONE, false).with(SOLID, true);
}
public static ActionResult onUse(BlockState state, World world, BlockPos pos, PlayerEntity player, Hand hand, BlockHitResult hit) {
@ -77,6 +80,16 @@ public class TemplateInteractionUtil {
return ActionResult.SUCCESS;
}
//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));
be.spentPoppedChorus();
if(!player.isCreative()) held.decrement(1);
world.playSound(player, pos, SoundEvents.ITEM_CHORUS_FRUIT_TELEPORT, SoundCategory.BLOCKS, 1f, 1f);
return ActionResult.SUCCESS;
}
//Changing the theme
if(held.getItem() instanceof BlockItem bi && be.getThemeState().getBlock() == Blocks.AIR) {
Block block = bi.getBlock();
@ -108,6 +121,7 @@ public class TemplateInteractionUtil {
if(template.hasSpentRedstoneTorch()) drops.add(new ItemStack(Items.REDSTONE_TORCH));
if(template.hasSpentGlowstoneDust()) drops.add(new ItemStack(Items.GLOWSTONE_DUST));
if(template.hasSpentPoppedChorus()) drops.add(new ItemStack(Items.POPPED_CHORUS_FRUIT));
ItemScatterer.spawn(world, pos, drops);
}
@ -122,6 +136,10 @@ public class TemplateInteractionUtil {
}
}
public static @Nullable VoxelShape getCollisionShape(BlockState state) {
return state.contains(SOLID) && !state.get(SOLID) ? VoxelShapes.empty() : null;
}
public static boolean emitsRedstonePower(BlockState state) {
return state.contains(REDSTONE) ? state.get(REDSTONE) : false;
}

View File

@ -1,9 +1,11 @@
package io.github.cottonmc.templates.block;
import com.google.common.base.MoreObjects;
import io.github.cottonmc.templates.api.TemplateInteractionUtil;
import net.minecraft.block.Block;
import net.minecraft.block.BlockEntityProvider;
import net.minecraft.block.BlockState;
import net.minecraft.block.ShapeContext;
import net.minecraft.block.entity.BlockEntity;
import net.minecraft.entity.LivingEntity;
import net.minecraft.entity.player.PlayerEntity;
@ -14,6 +16,7 @@ import net.minecraft.util.Hand;
import net.minecraft.util.hit.BlockHitResult;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.Direction;
import net.minecraft.util.shape.VoxelShape;
import net.minecraft.world.BlockView;
import net.minecraft.world.World;
import org.jetbrains.annotations.Nullable;
@ -49,6 +52,11 @@ public abstract class TemplateBlock extends Block implements BlockEntityProvider
super.onPlaced(world, pos, state, placer, stack);
}
@Override
public VoxelShape getCollisionShape(BlockState state, BlockView view, BlockPos pos, ShapeContext ctx) {
return MoreObjects.firstNonNull(TemplateInteractionUtil.getCollisionShape(state), super.getCollisionShape(state, view, pos, ctx));
}
@Override
public boolean emitsRedstonePower(BlockState state) {
return TemplateInteractionUtil.emitsRedstonePower(state);

View File

@ -1,10 +1,12 @@
package io.github.cottonmc.templates.block;
import com.google.common.base.MoreObjects;
import io.github.cottonmc.templates.Templates;
import io.github.cottonmc.templates.api.TemplateInteractionUtil;
import net.minecraft.block.Block;
import net.minecraft.block.BlockEntityProvider;
import net.minecraft.block.BlockState;
import net.minecraft.block.ShapeContext;
import net.minecraft.block.SlabBlock;
import net.minecraft.block.entity.BlockEntity;
import net.minecraft.entity.LivingEntity;
@ -16,6 +18,7 @@ import net.minecraft.util.Hand;
import net.minecraft.util.hit.BlockHitResult;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.Direction;
import net.minecraft.util.shape.VoxelShape;
import net.minecraft.world.BlockView;
import net.minecraft.world.World;
import org.jetbrains.annotations.Nullable;
@ -53,6 +56,11 @@ public class TemplateSlabBlock extends SlabBlock implements BlockEntityProvider
TemplateInteractionUtil.onPlaced(world, pos, state, placer, stack);
}
@Override
public VoxelShape getCollisionShape(BlockState state, BlockView view, BlockPos pos, ShapeContext ctx) {
return MoreObjects.firstNonNull(TemplateInteractionUtil.getCollisionShape(state), super.getCollisionShape(state, view, pos, ctx));
}
@Override
public boolean emitsRedstonePower(BlockState state) {
return TemplateInteractionUtil.emitsRedstonePower(state);

View File

@ -1,6 +1,8 @@
package io.github.cottonmc.templates.block;
import com.google.common.base.MoreObjects;
import io.github.cottonmc.templates.Templates;
import io.github.cottonmc.templates.api.TemplateInteractionUtil;
import io.github.cottonmc.templates.util.StairShapeMaker;
import net.minecraft.block.Block;
import net.minecraft.block.BlockState;
@ -67,11 +69,11 @@ public class TemplateSlopeBlock extends TemplateBlock {
@Override
public VoxelShape getCollisionShape(BlockState state, BlockView view, BlockPos pos, ShapeContext ctx) {
return shapes[shapeIndex(state.get(FACING), state.get(HALF))];
return MoreObjects.firstNonNull(super.getCollisionShape(state, view, pos, ctx), shapes[shapeIndex(state.get(FACING), state.get(HALF))]);
}
@Override
public VoxelShape getOutlineShape(BlockState state, BlockView view, BlockPos pos, ShapeContext ctx) {
return getCollisionShape(state, view, pos, ctx);
return shapes[shapeIndex(state.get(FACING), state.get(HALF))];
}
}

View File

@ -28,6 +28,7 @@ public class TemplateEntity extends BlockEntity implements ThemeableBlockEntity
//blockstate for it is a little silly, so, here you go.
protected boolean spentGlowstoneDust = false;
protected boolean spentRedstoneTorch = false;
protected boolean spentPoppedChorus = false;
public TemplateEntity(BlockEntityType<?> type, BlockPos pos, BlockState state) {
super(type, pos, state);
@ -42,6 +43,7 @@ public class TemplateEntity extends BlockEntity implements ThemeableBlockEntity
renderedState = NbtHelper.toBlockState(Registries.BLOCK.getReadOnlyWrapper(), tag.getCompound("BlockState"));
spentGlowstoneDust = tag.getBoolean("Glowstone");
spentRedstoneTorch = tag.getBoolean("Redstone");
spentPoppedChorus = tag.getBoolean("Chorus");
//Force a chunk remesh on the client if the displayed blockstate has changed
if(world != null && world.isClient && !Objects.equals(lastRenderedState, renderedState)) {
@ -55,6 +57,7 @@ public class TemplateEntity extends BlockEntity implements ThemeableBlockEntity
tag.put("BlockState", NbtHelper.fromBlockState(renderedState));
tag.putBoolean("Glowstone", spentGlowstoneDust);
tag.putBoolean("Redstone", spentRedstoneTorch);
tag.putBoolean("Chorus", spentPoppedChorus);
}
@Nullable
@ -99,4 +102,13 @@ public class TemplateEntity extends BlockEntity implements ThemeableBlockEntity
spentRedstoneTorch = true;
markDirty();
}
public boolean hasSpentPoppedChorus() {
return spentPoppedChorus;
}
public void spentPoppedChorus() {
spentPoppedChorus = true;
markDirty();
}
}

View File

@ -1,6 +1,7 @@
package io.github.cottonmc.templates.model;
import io.github.cottonmc.templates.TemplatesClient;
import io.github.cottonmc.templates.util.TattletaleRandom;
import net.fabricmc.fabric.api.renderer.v1.material.BlendMode;
import net.fabricmc.fabric.api.renderer.v1.material.MaterialFinder;
import net.fabricmc.fabric.api.renderer.v1.material.RenderMaterial;
@ -17,7 +18,6 @@ import net.minecraft.client.util.SpriteIdentifier;
import net.minecraft.screen.PlayerScreenHandler;
import net.minecraft.util.Identifier;
import net.minecraft.util.math.Direction;
import net.minecraft.util.math.MathHelper;
import net.minecraft.util.math.random.Random;
import org.jetbrains.annotations.NotNull;
@ -60,7 +60,7 @@ public class TemplateAppearanceManager {
//The results are going to be the same, apart from their serialNumbers differing (= their equals & hashCode differing).
//Tiny amount of wasted space in some caches if TemplateAppearances are used as a map key, then. IMO it's not a critical issue.
private TemplateAppearance computeAppearance(BlockState state) {
Random rand = Random.create();
TattletaleRandom rand = new TattletaleRandom(Random.create());
BakedModel model = MinecraftClient.getInstance().getBlockRenderManager().getModel(state);
//Only for parsing vanilla quads:
@ -128,6 +128,10 @@ public class TemplateAppearanceManager {
if(sprites[i] == null) sprites[i] = defaultAppearance.getParticleSprite();
}
if(rand.wasUsed) {
//System.err.println("State " + state + " makes use of a randomized model");
}
return new ComputedApperance(
sprites,
bakeFlags,

View File

@ -0,0 +1,83 @@
package io.github.cottonmc.templates.util;
import net.minecraft.util.math.random.Random;
import net.minecraft.util.math.random.RandomSplitter;
public class TattletaleRandom implements Random {
public TattletaleRandom(Random delegate) {
this.delegate = delegate;
}
private final Random delegate;
public boolean wasUsed = false;
public Random split() {
wasUsed = true;
return delegate.split();
}
public RandomSplitter nextSplitter() {
wasUsed = true;
return delegate.nextSplitter();
}
public void setSeed(long l) {
wasUsed = true;
delegate.setSeed(l);
}
public int nextInt() {
wasUsed = true;
return delegate.nextInt();
}
public int nextInt(int i) {
wasUsed = true;
return delegate.nextInt(i);
}
public int nextBetween(int i, int j) {
wasUsed = true;
return delegate.nextBetween(i, j);
}
public long nextLong() {
wasUsed = true;
return delegate.nextLong();
}
public boolean nextBoolean() {
wasUsed = true;
return delegate.nextBoolean();
}
public float nextFloat() {
wasUsed = true;
return delegate.nextFloat();
}
public double nextDouble() {
wasUsed = true;
return delegate.nextDouble();
}
public double nextGaussian() {
wasUsed = true;
return delegate.nextGaussian();
}
public double nextTriangular(double d, double e) {
wasUsed = true;
return delegate.nextTriangular(d, e);
}
public void skip(int i) {
wasUsed = true;
delegate.skip(i);
}
public int nextBetweenExclusive(int i, int j) {
wasUsed = true;
return delegate.nextBetweenExclusive(i, j);
}
}