diff --git a/src/main/java/ivorius/psychedelicraft/block/BottleRackBlock.java b/src/main/java/ivorius/psychedelicraft/block/BottleRackBlock.java index 31a2c28e..57dcf00f 100644 --- a/src/main/java/ivorius/psychedelicraft/block/BottleRackBlock.java +++ b/src/main/java/ivorius/psychedelicraft/block/BottleRackBlock.java @@ -2,13 +2,13 @@ import ivorius.psychedelicraft.block.entity.PSBlockEntities; import ivorius.psychedelicraft.client.render.blocks.VoxelShapeUtil; +import ivorius.psychedelicraft.mixin.MixinAbstractBlockSettings; -import java.util.Arrays; -import java.util.Map; import java.util.function.Function; -import java.util.stream.Collectors; +import com.mojang.serialization.Codec; import com.mojang.serialization.MapCodec; +import com.mojang.serialization.codecs.RecordCodecBuilder; import ivorius.psychedelicraft.block.entity.BottleRackBlockEntity; import net.minecraft.block.*; @@ -23,7 +23,7 @@ import net.minecraft.util.hit.BlockHitResult; import net.minecraft.util.math.BlockPos; import net.minecraft.util.math.Direction; -import net.minecraft.util.math.Direction.Axis; +import net.minecraft.util.math.Vec3d; import net.minecraft.util.shape.VoxelShape; import net.minecraft.util.shape.VoxelShapes; import net.minecraft.world.*; @@ -32,28 +32,48 @@ * Created by lukas on 16.11.14. */ public class BottleRackBlock extends BlockWithEntity { - public static final MapCodec CODEC = createCodec(BottleRackBlock::new); + public static final MapCodec CODEC = RecordCodecBuilder.mapCodec( + instance -> instance.group( + Codec.INT.fieldOf("z_offset").forGetter(BottleRackBlock::getZOffset), + createSettingsCodec() + ).apply(instance, BottleRackBlock::new)); public static final DirectionProperty FACING = Properties.HORIZONTAL_FACING; - private static final Map SHAPES = Arrays.stream(Direction.values()) - .filter(d -> d.getAxis() != Axis.Y) - .collect(Collectors.toMap( - Function.identity(), - VoxelShapeUtil.rotator(VoxelShapes.union( - Block.createCuboidShape(0, 0, 3, 1, 16, 11), - Block.createCuboidShape(5, 0, 3, 6, 16, 11), - Block.createCuboidShape(10, 0, 3, 11, 16, 11), - Block.createCuboidShape(15, 0, 3, 16, 16, 11), - - Block.createCuboidShape(1, 0, 2.75F, 15, 1, 12.35F), - Block.createCuboidShape(1, 5, 2.75F, 15, 6, 12.35F), - Block.createCuboidShape(1, 10, 2.75F, 15, 11, 12.35F), - Block.createCuboidShape(1, 15, 2.75F, 15, 16, 12.35F) - ))) - ); - - public BottleRackBlock(Settings settings) { - super(settings.nonOpaque()); + private static final VoxelShape BASE_SHAPE = VoxelShapes.union( + Block.createCuboidShape(0, 0, 3, 1, 16, 11), + Block.createCuboidShape(5, 0, 3, 6, 16, 11), + Block.createCuboidShape(10, 0, 3, 11, 16, 11), + Block.createCuboidShape(15, 0, 3, 16, 16, 11), + + Block.createCuboidShape(1, 0, 2.75F, 15, 1, 12.35F), + Block.createCuboidShape(1, 5, 2.75F, 15, 6, 12.35F), + Block.createCuboidShape(1, 10, 2.75F, 15, 11, 12.35F), + Block.createCuboidShape(1, 15, 2.75F, 15, 16, 12.35F) + ); + + private final int zOffset; + private final Function shapes; + + public BottleRackBlock(int zOffset, Settings settings) { + this(zOffset, settings, + Util.memoize(direction -> VoxelShapeUtil.rotate(new Vec3d(0, 0, -zOffset / 16D), direction)), + Util.memoize(VoxelShapeUtil.rotator(BASE_SHAPE.offset(0, 0, zOffset / 16D))) + ); + } + + public BottleRackBlock(int zOffset, Settings settings, + Function offsets, + Function shapes) { + super(Util.make(settings, s -> { + if (zOffset != 0) { + ((MixinAbstractBlockSettings)s).setOffsetter((state, world, pos) -> { + offsets.apply(state.get(FACING)); + return VoxelShapeUtil.rotate(new Vec3d(0, 0, -3 / 16D), state.get(FACING)); + }); + } + }).nonOpaque().dynamicBounds()); + this.shapes = shapes; + this.zOffset = zOffset; } @Override @@ -66,6 +86,10 @@ protected BlockRenderType getRenderType(BlockState state) { return BlockRenderType.MODEL; } + public int getZOffset() { + return zOffset; + } + @Override protected void appendProperties(StateManager.Builder builder) { super.appendProperties(builder); @@ -80,7 +104,7 @@ public BlockState getPlacementState(ItemPlacementContext ctx) { @Override @Deprecated protected VoxelShape getOutlineShape(BlockState state, BlockView world, BlockPos pos, ShapeContext context) { - return SHAPES.getOrDefault(state.get(FACING), VoxelShapes.fullCube()); + return shapes.apply(state.get(FACING)); } @Override diff --git a/src/main/java/ivorius/psychedelicraft/block/PSBlocks.java b/src/main/java/ivorius/psychedelicraft/block/PSBlocks.java index a4bf05b1..37b7f0d9 100644 --- a/src/main/java/ivorius/psychedelicraft/block/PSBlocks.java +++ b/src/main/java/ivorius/psychedelicraft/block/PSBlocks.java @@ -47,7 +47,8 @@ public interface PSBlocks { Block FLASK = register("flask", new FlaskBlock(Settings.create().sounds(BlockSoundGroup.COPPER).hardness(1).pistonBehavior(PistonBehavior.BLOCK))); Block DISTILLERY = register("distillery", new DistilleryBlock(Settings.create().sounds(BlockSoundGroup.COPPER).hardness(1).pistonBehavior(PistonBehavior.BLOCK))); - Block BOTTLE_RACK = register("bottle_rack", new BottleRackBlock(Settings.create().mapColor(MapColor.OAK_TAN).sounds(BlockSoundGroup.WOOD).hardness(0.5F).burnable())); + Block BOTTLE_RACK = register("bottle_rack", new BottleRackBlock(0, Settings.create().mapColor(MapColor.OAK_TAN).sounds(BlockSoundGroup.WOOD).hardness(0.5F).burnable())); + Block WALL_BOTTLE_RACK = register("wall_bottle_rack", new BottleRackBlock(-3, Settings.create().mapColor(MapColor.OAK_TAN).sounds(BlockSoundGroup.WOOD).hardness(0.5F).burnable())); Block DRYING_TABLE = register("drying_table", new DryingTableBlock(Settings.create().mapColor(MapColor.OAK_TAN).solid().sounds(BlockSoundGroup.WOOD).hardness(2).burnable())); Block IRON_DRYING_TABLE = register("iron_drying_table", new DryingTableBlock(Settings.create().mapColor(MapColor.IRON_GRAY).sounds(BlockSoundGroup.METAL).hardness(5))); diff --git a/src/main/java/ivorius/psychedelicraft/block/entity/PSBlockEntities.java b/src/main/java/ivorius/psychedelicraft/block/entity/PSBlockEntities.java index 9577e362..76de8413 100644 --- a/src/main/java/ivorius/psychedelicraft/block/entity/PSBlockEntities.java +++ b/src/main/java/ivorius/psychedelicraft/block/entity/PSBlockEntities.java @@ -15,7 +15,7 @@ public interface PSBlockEntities { BlockEntityType RIFT_JAR = create("rift_jar", BlockEntityType.Builder.create(RiftJarBlockEntity::new, PSBlocks.RIFT_JAR)); BlockEntityType PEYOTE = create("peyote", BlockEntityType.Builder.create(PeyoteBlockEntity::new, PSBlocks.PEYOTE)); BlockEntityType DISTILLERY = create("distillery", BlockEntityType.Builder.create(DistilleryBlockEntity::new, PSBlocks.DISTILLERY)); - BlockEntityType BOTTLE_RACK = create("bottle_rack", BlockEntityType.Builder.create(BottleRackBlockEntity::new, PSBlocks.BOTTLE_RACK)); + BlockEntityType BOTTLE_RACK = create("bottle_rack", BlockEntityType.Builder.create(BottleRackBlockEntity::new, PSBlocks.BOTTLE_RACK, PSBlocks.WALL_BOTTLE_RACK)); BlockEntityType FLASK = create("flask", BlockEntityType.Builder.create(FlaskBlockEntity::new, PSBlocks.FLASK)); BlockEntityType BARREL = create("barrel", BlockEntityType.Builder.create(BarrelBlockEntity::new, PSBlocks.OAK_BARREL, PSBlocks.SPRUCE_BARREL, diff --git a/src/main/java/ivorius/psychedelicraft/client/render/blocks/BottleRackBlockEntityRenderer.java b/src/main/java/ivorius/psychedelicraft/client/render/blocks/BottleRackBlockEntityRenderer.java index fcfca106..8442092b 100644 --- a/src/main/java/ivorius/psychedelicraft/client/render/blocks/BottleRackBlockEntityRenderer.java +++ b/src/main/java/ivorius/psychedelicraft/client/render/blocks/BottleRackBlockEntityRenderer.java @@ -35,7 +35,10 @@ public void render(BottleRackBlockEntity entity, float tickDelta, MatrixStack ma float facing = direction.asRotation() + 90; matrices.multiply(RotationAxis.POSITIVE_Y.rotationDegrees(facing)); - matrices.translate(0.14F, -0.55F, -0.8F); + + double offset = ((BottleRackBlock)entity.getCachedState().getBlock()).getZOffset() / 16D; + + matrices.translate(0.14F - offset, -0.55F, -0.8F); matrices.multiply(RotationAxis.NEGATIVE_Z.rotationDegrees(-90)); Random rng = RenderUtil.random(entity.getPos().asLong()); diff --git a/src/main/java/ivorius/psychedelicraft/client/render/blocks/VoxelShapeUtil.java b/src/main/java/ivorius/psychedelicraft/client/render/blocks/VoxelShapeUtil.java index 2de4a9a4..7024dc2a 100644 --- a/src/main/java/ivorius/psychedelicraft/client/render/blocks/VoxelShapeUtil.java +++ b/src/main/java/ivorius/psychedelicraft/client/render/blocks/VoxelShapeUtil.java @@ -43,6 +43,17 @@ static VoxelShape rotate(VoxelShape shape, Direction direction) { .toArray(VoxelShape[]::new)); } + static Vec3d rotate(Vec3d vector, Direction direction) { + if (direction.asRotation() == 0) { + return vector; + } + if (direction.getAxis() == Axis.X) { + direction = direction.getOpposite(); + } + float angle = (direction.asRotation()) * MathHelper.RADIANS_PER_DEGREE; + return vector.rotateY(angle); + } + static Vec3d rotate(double x, double z, float angle) { return new Vec3d(x, 0, z).subtract(CENTER).rotateY(angle).add(CENTER); } diff --git a/src/main/java/ivorius/psychedelicraft/datagen/providers/PSModelProvider.java b/src/main/java/ivorius/psychedelicraft/datagen/providers/PSModelProvider.java index e591e97f..77c37033 100644 --- a/src/main/java/ivorius/psychedelicraft/datagen/providers/PSModelProvider.java +++ b/src/main/java/ivorius/psychedelicraft/datagen/providers/PSModelProvider.java @@ -108,9 +108,11 @@ public void generateBlockStateModels(BlockStateModelGenerator generator) { BlockModels.registerDryingTable(generator, PSBlocks.DRYING_TABLE); BlockModels.registerDryingTable(generator, PSBlocks.IRON_DRYING_TABLE); - generator.blockStateCollector.accept(VariantsBlockStateSupplier.create(PSBlocks.BOTTLE_RACK, BlockStateVariant.create() - .put(VariantSettings.MODEL, ModelIds.getBlockModelId(PSBlocks.BOTTLE_RACK))) - .coordinate(BlockStateModelGenerator.createNorthDefaultHorizontalRotationStates())); + List.of(PSBlocks.BOTTLE_RACK, PSBlocks.WALL_BOTTLE_RACK).forEach(block -> { + generator.blockStateCollector.accept(VariantsBlockStateSupplier.create(block, BlockStateVariant.create() + .put(VariantSettings.MODEL, ModelIds.getBlockModelId(PSBlocks.BOTTLE_RACK))) + .coordinate(BlockStateModelGenerator.createNorthDefaultHorizontalRotationStates())); + }); generator.blockStateCollector.accept(BlockStateModelGenerator.createSingletonBlockState(PSBlocks.FLASK, ModelIds.getBlockModelId(PSBlocks.FLASK))); generator.registerStateWithModelReference(PSBlocks.FLAMMABLE_GAS, Blocks.AIR); diff --git a/src/main/java/ivorius/psychedelicraft/datagen/providers/loot/PSBlockLootTableProvider.java b/src/main/java/ivorius/psychedelicraft/datagen/providers/loot/PSBlockLootTableProvider.java index cd135969..c09dbc1f 100644 --- a/src/main/java/ivorius/psychedelicraft/datagen/providers/loot/PSBlockLootTableProvider.java +++ b/src/main/java/ivorius/psychedelicraft/datagen/providers/loot/PSBlockLootTableProvider.java @@ -83,6 +83,7 @@ public void generate() { PSBlocks.TRAY, PSBlocks.BOTTLE_RACK ).forEach(this::addDrop); + addDrop(PSBlocks.WALL_BOTTLE_RACK, PSItems.BOTTLE_RACK); addDrop(PSBlocks.JUNIPER_LEAVES, block -> fruitLeavesDrop(block, PSBlocks.JUNIPER_SAPLING, PSItems.JUNIPER_BERRIES, SAPLING_DROP_CHANCE)); addDrop(PSBlocks.FRUITING_JUNIPER_LEAVES, block -> matureFruitLeavesDrop(block, PSBlocks.JUNIPER_SAPLING, PSItems.JUNIPER_BERRIES, SAPLING_DROP_CHANCE)); diff --git a/src/main/java/ivorius/psychedelicraft/item/PSItems.java b/src/main/java/ivorius/psychedelicraft/item/PSItems.java index d7ceef42..ae0bcd69 100644 --- a/src/main/java/ivorius/psychedelicraft/item/PSItems.java +++ b/src/main/java/ivorius/psychedelicraft/item/PSItems.java @@ -35,6 +35,7 @@ import net.minecraft.registry.Registries; import net.minecraft.registry.Registry; import net.minecraft.util.Colors; +import net.minecraft.util.math.Direction; /** * Created by lukas on 25.04.14. @@ -206,7 +207,7 @@ public interface PSItems { Item LATTICE = register("lattice", PSBlocks.LATTICE); Item WINE_GRAPE_LATTICE = register("wine_grape_lattice", PSBlocks.WINE_GRAPE_LATTICE); Item MORNING_GLORY_LATTICE = register("morning_glory_lattice", PSBlocks.MORNING_GLORY_LATTICE); - Item BOTTLE_RACK = register("bottle_rack", PSBlocks.BOTTLE_RACK); + Item BOTTLE_RACK = register("bottle_rack", new VerticallyAttachableBlockItem(PSBlocks.BOTTLE_RACK, PSBlocks.WALL_BOTTLE_RACK, new Settings(), Direction.DOWN)); Item DRYING_TABLE = register("drying_table", PSBlocks.DRYING_TABLE); Item IRON_DRYING_TABLE = register("iron_drying_table", PSBlocks.IRON_DRYING_TABLE); diff --git a/src/main/java/ivorius/psychedelicraft/mixin/MixinAbstractBlockSettings.java b/src/main/java/ivorius/psychedelicraft/mixin/MixinAbstractBlockSettings.java new file mode 100644 index 00000000..b96192ca --- /dev/null +++ b/src/main/java/ivorius/psychedelicraft/mixin/MixinAbstractBlockSettings.java @@ -0,0 +1,12 @@ +package ivorius.psychedelicraft.mixin; + +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.gen.Accessor; + +import net.minecraft.block.AbstractBlock; + +@Mixin(AbstractBlock.Settings.class) +public interface MixinAbstractBlockSettings { + @Accessor + void setOffsetter(AbstractBlock.Offsetter offsetter); +} diff --git a/src/main/resources/psychedelicraft.mixin.json b/src/main/resources/psychedelicraft.mixin.json index 39e29166..97f3b0a0 100644 --- a/src/main/resources/psychedelicraft.mixin.json +++ b/src/main/resources/psychedelicraft.mixin.json @@ -6,6 +6,7 @@ "refmap": "psychedelicraft.mixin.refmap.json", "compatibilityLevel": "JAVA_16", "mixins": [ + "MixinAbstractBlockSettings", "MixinAbstractFurnaceBlockEntity", "MixinEntity", "MixinLivingEntity",