15 Commits

Author SHA1 Message Date
ac2f7def0c Merge pull request '1.5.8 cache fix' (#13) from dev into master
All checks were successful
deploy / deploy (push) Successful in 5m13s
Reviewed-on: #13
2024-04-16 19:21:50 +02:00
fa44408836 Updated to v1.5.8 2024-04-16 19:20:52 +02:00
78b8b6f607 cleanup + fixed wall collision when using chorus 2024-04-16 00:24:16 +02:00
6318fdece0 improved caching to use less per-model space and changed cache class for retextured elements 2024-04-16 00:10:53 +02:00
44f03b2c96 Merge pull request 'New minor version with fix for caching on dynamic models' (#12) from dev into master
All checks were successful
deploy / deploy (push) Successful in 5m25s
Reviewed-on: #12
2024-04-15 20:58:47 +02:00
c3e0ab16b7 fixed cache issue with dynamic models from continuity and athena. Finished wall logic + updated to minor version 1.5.7 2024-04-15 20:57:03 +02:00
d8e4153754 added all wall models 2024-04-12 19:23:35 +02:00
572182e9f0 imports cleanup 2024-04-12 01:06:11 +02:00
6f394bbe6f wip wall logic and models + moved generation for block into separate classes for better readability 2024-04-12 01:03:47 +02:00
b05c0ebd42 removed unused imports 2024-04-11 00:06:22 +02:00
4309310c02 added missing receipe cleaned up model names creating W.I.P. wall + typo 2024-04-11 00:05:47 +02:00
74a290fd16 improved additivity of blocks and added pillar 2024-03-28 19:01:33 +01:00
a430a8e62b moved tools to tool crafting tab 2024-03-27 23:24:33 +01:00
3afee9e501 added continuity to optional modrinth dependencies + made blocks addition possible by placing correct shape on existing frame 2024-03-27 23:14:24 +01:00
319d247e4c added continuity to optional modrinth dependencies 2024-03-25 17:12:05 +01:00
101 changed files with 4650 additions and 1094 deletions

View File

@@ -210,6 +210,7 @@ modrinth {
required.project "fabric-api"
optional.version "b1ZV3DIJ", "${project.athena_version}"
optional.version "Orvt0mRa", "${project.indium_version}+mc${project.minecraft_version}"
optional.version "1IjD5062", "${project.continuity_version}"
}
}

View File

@@ -9,7 +9,7 @@ loader_version=0.15.6
# Mod Properties
modrinth_id = jCpoCBpn
mod_version = 1.5.6
mod_version = 1.5.8
maven_group = fr.adrien1106
archives_base_name = ReFramed
mod_id = reframed

View File

@@ -28,17 +28,16 @@ import java.util.stream.Stream;
import static fr.adrien1106.reframed.util.blocks.BlockProperties.LIGHT;
/**
* TODO make block pairable by right click -> for v1.6
* TODO Dynamic Ambient Occlusion -> for v1.6
* TODO add minecraft models like wall fence etc -> for v1.6
* TODO better connected textures -> maybe v1.6 ?
* TODO support continuity overlays -> not scheduled
* TODO Dynamic Ambient Occlusion -> for v1.6
* TODO add minecraft models like wall fence etc -> for v1.6
* TODO better connected textures -> maybe v1.6 ?
* TODO support continuity overlays -> not scheduled
*/
public class ReFramed implements ModInitializer {
public static final String MODID = "reframed";
public static final ArrayList<Block> BLOCKS = new ArrayList<>();
public static Block CUBE, SMALL_CUBE, SMALL_CUBES_STEP, STAIR, HALF_STAIR, STAIRS_CUBE, HALF_STAIRS_SLAB, HALF_STAIRS_STAIR, SLAB, SLABS_CUBE, STEP, STEPS_SLAB, LAYER;
public static Block CUBE, SMALL_CUBE, SMALL_CUBES_STEP, STAIR, HALF_STAIR, STAIRS_CUBE, HALF_STAIRS_SLAB, HALF_STAIRS_STAIR, SLAB, SLABS_CUBE, STEP, STEPS_SLAB, LAYER, PILLAR, WALL;
public static final ArrayList<Item> ITEMS = new ArrayList<>();
public static Item HAMMER, SCREWDRIVER, BLUEPRINT, BLUEPRINT_WRITTEN;
@@ -65,6 +64,8 @@ public class ReFramed implements ModInitializer {
SLABS_CUBE = registerBlock("slabs_cube" , new ReFramedSlabsCubeBlock(cp(Blocks.OAK_SLAB)));
STEP = registerBlock("step" , new ReFramedStepBlock(cp(Blocks.OAK_SLAB)));
STEPS_SLAB = registerBlock("steps_slab" , new ReFramedStepsSlabBlock(cp(Blocks.OAK_SLAB)));
PILLAR = registerBlock("pillar" , new ReFramedPillarBlock(cp(Blocks.OAK_FENCE)));
WALL = registerBlock("wall" , new ReframedWallBlock(cp(Blocks.OAK_FENCE)));
HAMMER = registerItem("hammer" , new ReFramedHammerItem(new Item.Settings().maxCount(1)));
SCREWDRIVER = registerItem("screwdriver" , new ReFramedScrewdriverItem(new Item.Settings().maxCount(1)));

View File

@@ -1,13 +1,9 @@
package fr.adrien1106.reframed.block;
import fr.adrien1106.reframed.ReFramed;
import fr.adrien1106.reframed.generator.RecipeSetter;
import fr.adrien1106.reframed.util.blocks.BlockHelper;
import net.fabricmc.fabric.api.datagen.v1.provider.FabricRecipeProvider;
import net.minecraft.block.*;
import net.minecraft.block.entity.BlockEntity;
import net.minecraft.data.server.recipe.RecipeExporter;
import net.minecraft.data.server.recipe.ShapedRecipeJsonBuilder;
import net.minecraft.entity.LivingEntity;
import net.minecraft.entity.player.PlayerEntity;
import net.minecraft.item.BlockItem;
@@ -15,7 +11,8 @@ import net.minecraft.item.ItemPlacementContext;
import net.minecraft.item.ItemStack;
import net.minecraft.item.Items;
import net.minecraft.nbt.NbtCompound;
import net.minecraft.recipe.book.RecipeCategory;
import net.minecraft.nbt.NbtHelper;
import net.minecraft.registry.Registries;
import net.minecraft.state.StateManager;
import net.minecraft.util.ActionResult;
import net.minecraft.util.Hand;
@@ -31,11 +28,15 @@ import net.minecraft.world.GameRules;
import net.minecraft.world.World;
import org.jetbrains.annotations.Nullable;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.stream.IntStream;
import static fr.adrien1106.reframed.block.ReFramedEntity.BLOCKSTATE_KEY;
import static fr.adrien1106.reframed.util.blocks.BlockProperties.LIGHT;
public class ReFramedBlock extends Block implements BlockEntityProvider, RecipeSetter {
public class ReFramedBlock extends Block implements BlockEntityProvider {
public ReFramedBlock(Settings settings) {
super(settings);
@@ -51,13 +52,6 @@ public class ReFramedBlock extends Block implements BlockEntityProvider, RecipeS
public Object getModelCacheKey(BlockState state) {
return "";
}
/**
* @return the amount of models the block can have prevents allocating too much space for a model
*/
public int getModelStateCount() {
return 1;
}
//For addon devs: override this so your blocks don't end up trying to place my block entity, my BlockEntityType only handles blocks internal to the mod
//Just make your own BlockEntityType, it's fine, you can even use the same ReFramedEntity class
@@ -97,7 +91,7 @@ public class ReFramedBlock extends Block implements BlockEntityProvider, RecipeS
@Override
public void onStateReplaced(BlockState state, World world, BlockPos pos, BlockState newState, boolean moved) {
if(!state.isOf(newState.getBlock()) &&
if(!(newState.getBlock() instanceof ReFramedBlock) &&
world.getBlockEntity(pos) instanceof ReFramedEntity frame_entity &&
world.getGameRules().getBoolean(GameRules.DO_TILE_DROPS)
) {
@@ -122,14 +116,52 @@ public class ReFramedBlock extends Block implements BlockEntityProvider, RecipeS
}
super.onStateReplaced(state, world, pos, newState, moved);
}
@Override
public void onPlaced(World world, BlockPos pos, BlockState state, @Nullable LivingEntity placer, ItemStack stack) {
if(world.isClient && world.getBlockEntity(pos) instanceof ReFramedEntity be) {
NbtCompound tag = BlockItem.getBlockEntityNbt(stack);
if(tag != null) be.readNbt(tag);
public void onPlaced(World world, BlockPos pos, BlockState state, @Nullable LivingEntity placer, ItemStack stack, BlockState old_state, BlockEntity old_entity) {
if (!(world.getBlockEntity(pos) instanceof ReFramedEntity frame_entity)) {
onPlaced(world, pos, state, placer, stack);
return;
}
super.onPlaced(world, pos, state, placer, stack);
// apply state change keeping the old information
if (old_state.getBlock() instanceof ReFramedBlock old_frame_block
&& old_entity instanceof ReFramedEntity old_frame_entity) {
Map<Integer, Integer> theme_map = old_frame_block.getThemeMap(old_state, state);
theme_map.forEach((self, other) ->
frame_entity.setTheme(old_frame_entity.getTheme(self), other)
);
// apply any changes needed to keep previous properties
if (old_frame_entity.emitsLight() && !frame_entity.emitsLight()) {
frame_entity.toggleLight();
world.setBlockState(pos, state.with(LIGHT, true));
}
if (old_frame_entity.emitsRedstone() && !frame_entity.emitsRedstone()) {
frame_entity.toggleRedstone();
world.updateNeighbors(pos, this);
}
if (old_frame_entity.isSolid() && !frame_entity.isSolid()) frame_entity.toggleSolidity();
// apply themes from item
NbtCompound tag = BlockItem.getBlockEntityNbt(stack);
if(tag != null) {
// determine a list of themes than can be used
Iterator<Integer> free_themes = IntStream
.rangeClosed(1, frame_entity.getThemes().size())
.filter(value -> !theme_map.containsValue(value))
.iterator();
// apply all the themes possible from item
for (int i = 1; tag.contains(BLOCKSTATE_KEY + i) && free_themes.hasNext(); i++) {
BlockState theme = NbtHelper.toBlockState(Registries.BLOCK.getReadOnlyWrapper(), tag.getCompound(BLOCKSTATE_KEY + i));
if (theme == null || theme.getBlock() == Blocks.AIR) continue;
frame_entity.setTheme(theme, free_themes.next());
}
}
} else if(world.isClient) { // prevents flashing with default texture before server sends the update
NbtCompound tag = BlockItem.getBlockEntityNbt(stack);
if(tag != null) frame_entity.readNbt(tag);
}
onPlaced(world, pos, state, placer, stack);
}
@Override
@@ -165,21 +197,20 @@ public class ReFramedBlock extends Block implements BlockEntityProvider, RecipeS
return getWeakRedstonePower(state, view, pos, dir);
}
/**
* @param state - the block state to get the top theme index from
* @return the index of the top theme to use for the block
*/
public int getTopThemeIndex(BlockState state) {
return 1;
}
@Override
public void setRecipe(RecipeExporter exporter) {
ShapedRecipeJsonBuilder
.create(RecipeCategory.BUILDING_BLOCKS, this)
.pattern("III")
.pattern("I~I")
.pattern("III")
.input('I', Items.BAMBOO)
.input('~', Items.STRING)
.criterion(FabricRecipeProvider.hasItem(Items.BAMBOO), FabricRecipeProvider.conditionsFromItem(Items.BAMBOO))
.criterion(FabricRecipeProvider.hasItem(this), FabricRecipeProvider.conditionsFromItem(this))
.offerTo(exporter);
/**
* @param state - the block state of the block that is being replaced
* @param new_state - the block state of the block that is replacing the block
* @return a map of the theme indexes to map when changing state so that the themes are preserved
*/
public Map<Integer, Integer> getThemeMap(BlockState state, BlockState new_state) {
return Map.of();
}
}

View File

@@ -49,6 +49,14 @@ public abstract class ReFramedDoubleBlock extends ReFramedBlock {
return 0;
}
public boolean matchesShape(Vec3d hit, BlockPos pos, BlockState state, int i) {
Vec3d rel = BlockHelper.getRelativePos(hit, pos);
return BlockHelper.cursorMatchesFace(
getShape(state, i),
rel
);
}
@Override
public boolean isTransparent(BlockState state, BlockView world, BlockPos pos) {
return world.getBlockEntity(pos) instanceof ThemeableBlockEntity framed_entity

View File

@@ -1,38 +1,31 @@
package fr.adrien1106.reframed.block;
import fr.adrien1106.reframed.ReFramed;
import fr.adrien1106.reframed.generator.BlockStateProvider;
import fr.adrien1106.reframed.generator.GBlockstate;
import fr.adrien1106.reframed.util.VoxelHelper;
import fr.adrien1106.reframed.util.blocks.BlockHelper;
import fr.adrien1106.reframed.util.blocks.Corner;
import net.fabricmc.fabric.api.datagen.v1.provider.FabricRecipeProvider;
import net.minecraft.block.Block;
import net.minecraft.block.BlockState;
import net.minecraft.block.ShapeContext;
import net.minecraft.data.client.BlockStateSupplier;
import net.minecraft.data.client.MultipartBlockStateSupplier;
import net.minecraft.data.server.recipe.RecipeExporter;
import net.minecraft.data.server.recipe.RecipeProvider;
import net.minecraft.data.server.recipe.ShapedRecipeJsonBuilder;
import net.minecraft.item.BlockItem;
import net.minecraft.item.ItemPlacementContext;
import net.minecraft.recipe.book.RecipeCategory;
import net.minecraft.state.StateManager;
import net.minecraft.util.Identifier;
import net.minecraft.util.function.BooleanBiFunction;
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 org.jetbrains.annotations.Nullable;
import static fr.adrien1106.reframed.util.VoxelHelper.VoxelListBuilder;
import static fr.adrien1106.reframed.util.blocks.BlockProperties.CORNER;
import static fr.adrien1106.reframed.util.blocks.BlockProperties.CORNER_FACE;
import static fr.adrien1106.reframed.util.blocks.Corner.*;
import static net.minecraft.data.client.VariantSettings.Rotation.*;
import java.util.Map;
public class ReFramedHalfStairBlock extends WaterloggableReFramedBlock implements BlockStateProvider {
import static fr.adrien1106.reframed.util.VoxelHelper.VoxelListBuilder;
import static fr.adrien1106.reframed.util.blocks.BlockProperties.*;
import static fr.adrien1106.reframed.util.blocks.Corner.*;
import static net.minecraft.state.property.Properties.WATERLOGGED;
public class ReFramedHalfStairBlock extends WaterloggableReFramedBlock {
public static final VoxelShape[] HALF_STAIR_VOXELS;
@@ -48,18 +41,62 @@ public class ReFramedHalfStairBlock extends WaterloggableReFramedBlock implement
return new ModelCacheKey(state.get(CORNER), state.get(CORNER_FACE));
}
@Override
public int getModelStateCount() {
return 24;
}
@Override
protected void appendProperties(StateManager.Builder<Block, BlockState> builder) {
super.appendProperties(builder.add(CORNER,CORNER_FACE));
}
@Override
public boolean canReplace(BlockState state, ItemPlacementContext context) {
Direction dir = state.get(CORNER).getDirection(state.get(CORNER_FACE));
return !(
context.getPlayer().isSneaking()
|| !(context.getStack().getItem() instanceof BlockItem block_item)
|| (
!(
block_item.getBlock() == this
&& ((ReFramedHalfStairsStairBlock) ReFramed.HALF_STAIRS_STAIR)
.matchesShape(
context.getHitPos(),
context.getBlockPos(),
ReFramed.HALF_STAIRS_STAIR.getDefaultState()
.with(EDGE, state.get(CORNER).getEdge(dir)),
dir.getDirection() == Direction.AxisDirection.POSITIVE ? 1 : 2
)
)
&& !(
block_item.getBlock() == ReFramed.SMALL_CUBE
&& BlockHelper.cursorMatchesFace(
ReFramed.SMALL_CUBE.getOutlineShape(
ReFramed.SMALL_CUBE.getDefaultState()
.with(CORNER, state.get(CORNER).getOpposite(state.get(CORNER_FACE))),
context.getWorld(),
context.getBlockPos(),
ShapeContext.absent()
),
BlockHelper.getRelativePos(context.getHitPos(), context.getBlockPos())
)
)
)
);
}
@Override
public @Nullable BlockState getPlacementState(ItemPlacementContext ctx) {
BlockState current_state = ctx.getWorld().getBlockState(ctx.getBlockPos());
if (current_state.isOf(ReFramed.SMALL_CUBE)) {
Corner corner = current_state.get(CORNER).getOpposite(ctx.getSide().getOpposite());
return ReFramed.HALF_STAIRS_SLAB.getDefaultState()
.with(CORNER, corner)
.with(CORNER_FACE, corner.getDirectionIndex(ctx.getSide().getOpposite()))
.with(WATERLOGGED, current_state.get(WATERLOGGED));
}
if (current_state.isOf(this))
return ReFramed.HALF_STAIRS_STAIR.getDefaultState()
.with(EDGE, current_state.get(CORNER).getEdge(current_state.get(CORNER).getDirection(current_state.get(CORNER_FACE))))
.with(WATERLOGGED, current_state.get(WATERLOGGED));
Corner corner = BlockHelper.getPlacementCorner(ctx);
return super.getPlacementState(ctx)
.with(CORNER, corner)
@@ -72,84 +109,16 @@ public class ReFramedHalfStairBlock extends WaterloggableReFramedBlock implement
}
@Override
public BlockStateSupplier getMultipart() {
return getHalfStairMultipart(
this,
ReFramed.id("half_stair_down_special"),
ReFramed.id("half_stair_side_special")
);
}
public static BlockStateSupplier getHalfStairMultipart(Block block, Identifier model_down, Identifier model_side) {
return MultipartBlockStateSupplier.create(block)
.with(GBlockstate.when(CORNER, NORTH_EAST_DOWN, CORNER_FACE, 1),
GBlockstate.variant(model_side, true, R0, R0))
.with(GBlockstate.when(CORNER, NORTH_EAST_DOWN, CORNER_FACE, 0),
GBlockstate.variant(model_side, true, R90, R270))
.with(GBlockstate.when(CORNER, NORTH_EAST_DOWN, CORNER_FACE, 2),
GBlockstate.variant(model_down, true, R0, R0))
.with(GBlockstate.when(CORNER, EAST_SOUTH_DOWN, CORNER_FACE, 1),
GBlockstate.variant(model_side, true, R0, R90))
.with(GBlockstate.when(CORNER, EAST_SOUTH_DOWN, CORNER_FACE, 0),
GBlockstate.variant(model_side, true, R90, R0))
.with(GBlockstate.when(CORNER, EAST_SOUTH_DOWN, CORNER_FACE, 2),
GBlockstate.variant(model_down, true, R0, R90))
.with(GBlockstate.when(CORNER, SOUTH_WEST_DOWN, CORNER_FACE, 1),
GBlockstate.variant(model_side, true, R0, R180))
.with(GBlockstate.when(CORNER, SOUTH_WEST_DOWN, CORNER_FACE, 0),
GBlockstate.variant(model_side, true, R90, R90))
.with(GBlockstate.when(CORNER, SOUTH_WEST_DOWN, CORNER_FACE, 2),
GBlockstate.variant(model_down, true, R0, R180))
.with(GBlockstate.when(CORNER, WEST_NORTH_DOWN, CORNER_FACE, 1),
GBlockstate.variant(model_side, true, R0, R270))
.with(GBlockstate.when(CORNER, WEST_NORTH_DOWN, CORNER_FACE, 0),
GBlockstate.variant(model_side, true, R90, R180))
.with(GBlockstate.when(CORNER, WEST_NORTH_DOWN, CORNER_FACE, 2),
GBlockstate.variant(model_down, true, R0, R270))
.with(GBlockstate.when(CORNER, EAST_SOUTH_UP, CORNER_FACE, 0),
GBlockstate.variant(model_side, true, R180, R0))
.with(GBlockstate.when(CORNER, EAST_SOUTH_UP, CORNER_FACE, 1),
GBlockstate.variant(model_side, true, R270, R90))
.with(GBlockstate.when(CORNER, EAST_SOUTH_UP, CORNER_FACE, 2),
GBlockstate.variant(model_down, true, R180, R0))
.with(GBlockstate.when(CORNER, SOUTH_WEST_UP, CORNER_FACE, 0),
GBlockstate.variant(model_side, true, R180, R90))
.with(GBlockstate.when(CORNER, SOUTH_WEST_UP, CORNER_FACE, 1),
GBlockstate.variant(model_side, true, R270, R180))
.with(GBlockstate.when(CORNER, SOUTH_WEST_UP, CORNER_FACE, 2),
GBlockstate.variant(model_down, true, R180, R90))
.with(GBlockstate.when(CORNER, WEST_NORTH_UP, CORNER_FACE, 0),
GBlockstate.variant(model_side, true, R180, R180))
.with(GBlockstate.when(CORNER, WEST_NORTH_UP, CORNER_FACE, 1),
GBlockstate.variant(model_side, true, R270, R270))
.with(GBlockstate.when(CORNER, WEST_NORTH_UP, CORNER_FACE, 2),
GBlockstate.variant(model_down, true, R180, R180))
.with(GBlockstate.when(CORNER, NORTH_EAST_UP, CORNER_FACE, 0),
GBlockstate.variant(model_side, true, R180, R270))
.with(GBlockstate.when(CORNER, NORTH_EAST_UP, CORNER_FACE, 1),
GBlockstate.variant(model_side, true, R270, R0))
.with(GBlockstate.when(CORNER, NORTH_EAST_UP, CORNER_FACE, 2),
GBlockstate.variant(model_down, true, R180, R270));
}
@Override
public void setRecipe(RecipeExporter exporter) {
RecipeProvider.offerStonecuttingRecipe(exporter, RecipeCategory.BUILDING_BLOCKS, this, ReFramed.CUBE, 2);
ShapedRecipeJsonBuilder
.create(RecipeCategory.BUILDING_BLOCKS, this, 4)
.pattern("I ")
.pattern("II ")
.input('I', ReFramed.CUBE)
.criterion(FabricRecipeProvider.hasItem(ReFramed.CUBE), FabricRecipeProvider.conditionsFromItem(ReFramed.CUBE))
.criterion(FabricRecipeProvider.hasItem(this), FabricRecipeProvider.conditionsFromItem(this))
.offerTo(exporter);
public Map<Integer, Integer> getThemeMap(BlockState state, BlockState new_state) {
if (new_state.isOf(ReFramed.HALF_STAIRS_SLAB)) return Map.of(1, 1);
if (new_state.isOf(ReFramed.HALF_STAIRS_STAIR))
return Map.of(
1,
state.get(CORNER)
.getDirection(state.get(CORNER_FACE))
.getDirection() == Direction.AxisDirection.POSITIVE ? 2 : 1
);
return super.getThemeMap(state, new_state);
}
static {

View File

@@ -1,19 +1,11 @@
package fr.adrien1106.reframed.block;
import fr.adrien1106.reframed.ReFramed;
import fr.adrien1106.reframed.generator.BlockStateProvider;
import fr.adrien1106.reframed.util.blocks.BlockHelper;
import fr.adrien1106.reframed.util.blocks.Corner;
import net.fabricmc.fabric.api.datagen.v1.provider.FabricRecipeProvider;
import net.minecraft.block.Block;
import net.minecraft.block.BlockState;
import net.minecraft.block.ShapeContext;
import net.minecraft.data.client.BlockStateSupplier;
import net.minecraft.data.server.recipe.RecipeExporter;
import net.minecraft.data.server.recipe.RecipeProvider;
import net.minecraft.data.server.recipe.ShapelessRecipeJsonBuilder;
import net.minecraft.item.ItemPlacementContext;
import net.minecraft.recipe.book.RecipeCategory;
import net.minecraft.state.StateManager;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.shape.VoxelShape;
@@ -21,7 +13,6 @@ import net.minecraft.world.BlockView;
import org.jetbrains.annotations.Nullable;
import static fr.adrien1106.reframed.block.ReFramedHalfStairBlock.HALF_STAIR_VOXELS;
import static fr.adrien1106.reframed.block.ReFramedHalfStairBlock.getHalfStairMultipart;
import static fr.adrien1106.reframed.block.ReFramedSlabBlock.getSlabShape;
import static fr.adrien1106.reframed.block.ReFramedSmallCubeBlock.SMALL_CUBE_VOXELS;
import static fr.adrien1106.reframed.util.blocks.BlockProperties.CORNER;
@@ -29,7 +20,7 @@ import static fr.adrien1106.reframed.util.blocks.BlockProperties.CORNER_FACE;
import static fr.adrien1106.reframed.util.blocks.Corner.NORTH_EAST_DOWN;
import static net.minecraft.util.shape.VoxelShapes.empty;
public class ReFramedHalfStairsSlabBlock extends WaterloggableReFramedDoubleBlock implements BlockStateProvider {
public class ReFramedHalfStairsSlabBlock extends WaterloggableReFramedDoubleBlock {
private record ModelCacheKey(Corner corner, int face) {}
@@ -43,11 +34,6 @@ public class ReFramedHalfStairsSlabBlock extends WaterloggableReFramedDoubleBloc
return new ModelCacheKey(state.get(CORNER), state.get(CORNER_FACE));
}
@Override
public int getModelStateCount() {
return 24;
}
@Override
protected void appendProperties(StateManager.Builder<Block, BlockState> builder) {
super.appendProperties(builder.add(CORNER,CORNER_FACE));
@@ -79,25 +65,4 @@ public class ReFramedHalfStairsSlabBlock extends WaterloggableReFramedDoubleBloc
? SMALL_CUBE_VOXELS[corner.getOpposite(face).getID()]
: HALF_STAIR_VOXELS[face + corner.getID() * 3];
}
@Override
public BlockStateSupplier getMultipart() {
return getHalfStairMultipart(
this,
ReFramed.id("half_stairs_slab_down_special"),
ReFramed.id("half_stairs_slab_side_special")
);
}
@Override
public void setRecipe(RecipeExporter exporter) {
RecipeProvider.offerStonecuttingRecipe(exporter, RecipeCategory.BUILDING_BLOCKS, this, ReFramed.CUBE, 2);
ShapelessRecipeJsonBuilder
.create(RecipeCategory.BUILDING_BLOCKS, this)
.input(ReFramed.HALF_STAIR)
.input(ReFramed.SMALL_CUBE)
.criterion(FabricRecipeProvider.hasItem(ReFramed.CUBE), FabricRecipeProvider.conditionsFromItem(ReFramed.CUBE))
.criterion(FabricRecipeProvider.hasItem(this), FabricRecipeProvider.conditionsFromItem(this))
.offerTo(exporter);
}
}

View File

@@ -1,25 +1,14 @@
package fr.adrien1106.reframed.block;
import fr.adrien1106.reframed.ReFramed;
import fr.adrien1106.reframed.generator.BlockStateProvider;
import fr.adrien1106.reframed.generator.GBlockstate;
import fr.adrien1106.reframed.util.blocks.BlockHelper;
import fr.adrien1106.reframed.util.blocks.Corner;
import fr.adrien1106.reframed.util.blocks.Edge;
import fr.adrien1106.reframed.util.blocks.StairShape;
import net.fabricmc.fabric.api.datagen.v1.provider.FabricRecipeProvider;
import net.minecraft.block.Block;
import net.minecraft.block.BlockState;
import net.minecraft.block.ShapeContext;
import net.minecraft.data.client.BlockStateSupplier;
import net.minecraft.data.client.MultipartBlockStateSupplier;
import net.minecraft.data.server.recipe.RecipeExporter;
import net.minecraft.data.server.recipe.RecipeProvider;
import net.minecraft.data.server.recipe.ShapelessRecipeJsonBuilder;
import net.minecraft.item.ItemPlacementContext;
import net.minecraft.recipe.book.RecipeCategory;
import net.minecraft.state.StateManager;
import net.minecraft.util.Identifier;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.Direction;
import net.minecraft.util.shape.VoxelShape;
@@ -30,10 +19,9 @@ import static fr.adrien1106.reframed.block.ReFramedHalfStairBlock.HALF_STAIR_VOX
import static fr.adrien1106.reframed.block.ReFramedStairBlock.getStairShape;
import static fr.adrien1106.reframed.util.blocks.BlockProperties.EDGE;
import static fr.adrien1106.reframed.util.blocks.Edge.*;
import static net.minecraft.data.client.VariantSettings.Rotation.*;
import static net.minecraft.util.shape.VoxelShapes.empty;
public class ReFramedHalfStairsStairBlock extends WaterloggableReFramedDoubleBlock implements BlockStateProvider {
public class ReFramedHalfStairsStairBlock extends WaterloggableReFramedDoubleBlock {
public ReFramedHalfStairsStairBlock(Settings settings) {
super(settings);
setDefaultState(getDefaultState().with(EDGE, NORTH_DOWN));
@@ -44,11 +32,6 @@ public class ReFramedHalfStairsStairBlock extends WaterloggableReFramedDoubleBlo
return state.get(EDGE);
}
@Override
public int getModelStateCount() {
return 12;
}
@Override
protected void appendProperties(StateManager.Builder<Block, BlockState> builder) {
super.appendProperties(builder.add(EDGE));
@@ -89,50 +72,4 @@ public class ReFramedHalfStairsStairBlock extends WaterloggableReFramedDoubleBlo
public int getTopThemeIndex(BlockState state) {
return 2;
}
@Override
public BlockStateSupplier getMultipart() {
Identifier model_id = ReFramed.id("half_stairs_stair_down_special");
Identifier side_model_id = ReFramed.id("half_stairs_stair_side_special");
Identifier reverse_model_id = ReFramed.id("half_stairs_stair_reverse_special");
return MultipartBlockStateSupplier.create(this)
/* X AXIS */
.with(GBlockstate.when(EDGE, NORTH_DOWN),
GBlockstate.variant(side_model_id, true, R90, R180))
.with(GBlockstate.when(EDGE, DOWN_SOUTH),
GBlockstate.variant(side_model_id, true, R0, R180))
.with(GBlockstate.when(EDGE, SOUTH_UP),
GBlockstate.variant(side_model_id, true, R270, R180))
.with(GBlockstate.when(EDGE, UP_NORTH),
GBlockstate.variant(side_model_id, true, R180, R180))
/* Y AXIS */
.with(GBlockstate.when(EDGE, NORTH_EAST),
GBlockstate.variant(model_id, true, R0, R0))
.with(GBlockstate.when(EDGE, EAST_SOUTH),
GBlockstate.variant(model_id, true, R0, R90))
.with(GBlockstate.when(EDGE, SOUTH_WEST),
GBlockstate.variant(model_id, true, R0, R180))
.with(GBlockstate.when(EDGE, WEST_NORTH),
GBlockstate.variant(model_id, true, R0, R270))
/* Z AXIS */
.with(GBlockstate.when(EDGE, DOWN_EAST),
GBlockstate.variant(side_model_id, true, R0, R90))
.with(GBlockstate.when(EDGE, EAST_UP),
GBlockstate.variant(reverse_model_id, true, R180, R270))
.with(GBlockstate.when(EDGE, UP_WEST),
GBlockstate.variant(side_model_id, true, R180, R90))
.with(GBlockstate.when(EDGE, WEST_DOWN),
GBlockstate.variant(reverse_model_id, true, R0, R270));
}
@Override
public void setRecipe(RecipeExporter exporter) {
RecipeProvider.offerStonecuttingRecipe(exporter, RecipeCategory.BUILDING_BLOCKS, this, ReFramed.CUBE, 2);
ShapelessRecipeJsonBuilder
.create(RecipeCategory.BUILDING_BLOCKS, this)
.input(ReFramed.HALF_STAIR, 2)
.criterion(FabricRecipeProvider.hasItem(ReFramed.CUBE), FabricRecipeProvider.conditionsFromItem(ReFramed.CUBE))
.criterion(FabricRecipeProvider.hasItem(this), FabricRecipeProvider.conditionsFromItem(this))
.offerTo(exporter);
}
}

View File

@@ -1,15 +1,12 @@
package fr.adrien1106.reframed.block;
import fr.adrien1106.reframed.ReFramed;
import fr.adrien1106.reframed.generator.GBlockstate;
import fr.adrien1106.reframed.util.VoxelHelper;
import net.minecraft.block.Block;
import net.minecraft.block.BlockState;
import net.minecraft.block.ShapeContext;
import net.minecraft.data.client.MultipartBlockStateSupplier;
import net.minecraft.item.BlockItem;
import net.minecraft.item.ItemPlacementContext;
import net.minecraft.state.StateManager;
import net.minecraft.util.Identifier;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.Direction;
import net.minecraft.util.shape.VoxelShape;
@@ -17,7 +14,6 @@ import net.minecraft.world.BlockView;
import org.jetbrains.annotations.Nullable;
import static fr.adrien1106.reframed.util.VoxelHelper.VoxelListBuilder;
import static net.minecraft.data.client.VariantSettings.Rotation.*;
import static net.minecraft.state.property.Properties.FACING;
import static net.minecraft.state.property.Properties.LAYERS;
@@ -36,11 +32,6 @@ public class ReFramedLayerBlock extends ReFramedSlabBlock {
return new ModelCacheKey(state.get(FACING), state.get(LAYERS));
}
@Override
public int getModelStateCount() {
return 48;
}
@Override
protected void appendProperties(StateManager.Builder<Block, BlockState> builder) {
super.appendProperties(builder.add(LAYERS));
@@ -52,8 +43,12 @@ public class ReFramedLayerBlock extends ReFramedSlabBlock {
}
@Override
public boolean canReplace(BlockState state, ItemPlacementContext ctx) {
return !(!state.isOf(this) || ctx.getPlayer().isSneaking() || state.get(LAYERS) == 8);
public boolean canReplace(BlockState state, ItemPlacementContext context) {
return !(
context.getPlayer().isSneaking()
|| !(context.getStack().getItem() instanceof BlockItem block_item)
|| !(block_item.getBlock() == this && state.get(LAYERS) < 8)
);
}
@Override
@@ -63,29 +58,6 @@ public class ReFramedLayerBlock extends ReFramedSlabBlock {
return previous.with(LAYERS, previous.get(LAYERS) + 1);
}
@Override
public MultipartBlockStateSupplier getMultipart() {
String model_pattern = "layer_x_special";
MultipartBlockStateSupplier supplier = MultipartBlockStateSupplier.create(this);
for (int i = 1; i <= 8; i++) {
Identifier model = ReFramed.id(model_pattern.replace("x", i + ""));
supplier
.with(GBlockstate.when(FACING, Direction.DOWN, LAYERS, i),
GBlockstate.variant(model, true, R0, R0))
.with(GBlockstate.when(FACING, Direction.SOUTH, LAYERS, i),
GBlockstate.variant(model, true, R90, R0))
.with(GBlockstate.when(FACING, Direction.UP, LAYERS, i),
GBlockstate.variant(model, true, R180, R0))
.with(GBlockstate.when(FACING, Direction.NORTH, LAYERS, i),
GBlockstate.variant(model, true, R270, R0))
.with(GBlockstate.when(FACING, Direction.WEST, LAYERS, i),
GBlockstate.variant(model, true, R90, R90))
.with(GBlockstate.when(FACING, Direction.EAST, LAYERS, i),
GBlockstate.variant(model, true, R90, R270));
}
return supplier;
}
static {
VoxelListBuilder builder = VoxelListBuilder.create(createCuboidShape(0, 0, 0, 16, 2, 16), 48)
.add(createCuboidShape(0, 0, 0, 16, 4, 16))

View File

@@ -0,0 +1,78 @@
package fr.adrien1106.reframed.block;
import fr.adrien1106.reframed.util.VoxelHelper;
import net.minecraft.block.Block;
import net.minecraft.block.BlockState;
import net.minecraft.block.ShapeContext;
import net.minecraft.item.BlockItem;
import net.minecraft.item.ItemPlacementContext;
import net.minecraft.state.StateManager;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.Direction;
import net.minecraft.util.shape.VoxelShape;
import net.minecraft.world.BlockView;
import org.jetbrains.annotations.Nullable;
import java.util.Map;
import static net.minecraft.state.property.Properties.AXIS;
public class ReFramedPillarBlock extends WaterloggableReFramedBlock {
public static final VoxelShape[] PILLAR_VOXELS;
public ReFramedPillarBlock(Settings settings) {
super(settings);
setDefaultState(getDefaultState().with(AXIS, Direction.Axis.Y));
}
@Override
public Object getModelCacheKey(BlockState state) {
return state.get(AXIS);
}
@Override
protected void appendProperties(StateManager.Builder<Block, BlockState> builder) {
super.appendProperties(builder.add(AXIS));
}
@Override
public boolean canReplace(BlockState state, ItemPlacementContext context) {
return !(context.getPlayer().isSneaking()
|| !(context.getStack().getItem() instanceof BlockItem block_item)
|| !(
block_item.getBlock() == this
&& state.get(AXIS) != context.getSide().getAxis()
)
);
}
@Override
public @Nullable BlockState getPlacementState(ItemPlacementContext ctx) {
// TODO: PILLARS WALL
return super.getPlacementState(ctx).with(AXIS, ctx.getSide().getAxis());
}
@Override
public VoxelShape getOutlineShape(BlockState state, BlockView world, BlockPos pos, ShapeContext context) {
return getPillarShape(state.get(AXIS));
}
public static VoxelShape getPillarShape(Direction.Axis axis) {
return PILLAR_VOXELS[axis.ordinal()];
}
@Override
public Map<Integer, Integer> getThemeMap(BlockState state, BlockState new_state) {
// if (new_state.getBlock() == ReFramed.PILLARS_WALL) return Map.of(1, 1); // TODO: PILLARS WALL
return super.getThemeMap(state, new_state);
}
static {
final VoxelShape PILLAR = createCuboidShape(0, 4, 4, 16, 12, 12);
PILLAR_VOXELS = VoxelHelper.VoxelListBuilder.create(PILLAR, 3)
.add(VoxelHelper::rotateZ)
.add(VoxelHelper::rotateX)
.build();
}
}

View File

@@ -1,20 +1,12 @@
package fr.adrien1106.reframed.block;
import fr.adrien1106.reframed.ReFramed;
import fr.adrien1106.reframed.generator.BlockStateProvider;
import fr.adrien1106.reframed.generator.GBlockstate;
import net.fabricmc.fabric.api.datagen.v1.provider.FabricRecipeProvider;
import net.minecraft.block.Block;
import net.minecraft.block.BlockState;
import net.minecraft.block.ShapeContext;
import net.minecraft.data.client.MultipartBlockStateSupplier;
import net.minecraft.data.server.recipe.RecipeExporter;
import net.minecraft.data.server.recipe.RecipeProvider;
import net.minecraft.data.server.recipe.ShapedRecipeJsonBuilder;
import net.minecraft.item.BlockItem;
import net.minecraft.item.ItemPlacementContext;
import net.minecraft.recipe.book.RecipeCategory;
import net.minecraft.state.StateManager;
import net.minecraft.util.Identifier;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.Direction;
import net.minecraft.util.shape.VoxelShape;
@@ -22,10 +14,12 @@ import net.minecraft.util.shape.VoxelShapes;
import net.minecraft.world.BlockView;
import org.jetbrains.annotations.Nullable;
import static net.minecraft.data.client.VariantSettings.Rotation.*;
import java.util.Map;
import static net.minecraft.state.property.Properties.AXIS;
import static net.minecraft.state.property.Properties.FACING;
public class ReFramedSlabBlock extends WaterloggableReFramedBlock implements BlockStateProvider {
public class ReFramedSlabBlock extends WaterloggableReFramedBlock {
protected static final VoxelShape DOWN = VoxelShapes.cuboid(0f, 0f, 0f, 1f, 0.5f, 1f);
protected static final VoxelShape UP = VoxelShapes.cuboid(0f, 0.5f, 0f, 1f, 1f, 1f);
@@ -43,20 +37,38 @@ public class ReFramedSlabBlock extends WaterloggableReFramedBlock implements Blo
public Object getModelCacheKey(BlockState state) {
return state.get(FACING);
}
@Override
public int getModelStateCount() {
return 6;
}
@Override
protected void appendProperties(StateManager.Builder<Block, BlockState> builder) {
super.appendProperties(builder.add(FACING));
}
@Override
public boolean canReplace(BlockState state, ItemPlacementContext context) {
return !(
context.getPlayer().isSneaking()
|| !(context.getStack().getItem() instanceof BlockItem block_item)
|| !(
block_item.getBlock() == this
&& ((ReFramedSlabsCubeBlock) ReFramed.SLABS_CUBE)
.matchesShape(
context.getHitPos(),
context.getBlockPos(),
ReFramed.SLABS_CUBE.getDefaultState().with(AXIS, state.get(FACING).getAxis()),
state.get(FACING).getDirection() == Direction.AxisDirection.POSITIVE ? 1 : 2
)
)
);
}
@Nullable
@Override
public BlockState getPlacementState(ItemPlacementContext ctx) {
BlockState current_state = ctx.getWorld().getBlockState(ctx.getBlockPos());
if (current_state.isOf(this))
return ReFramed.SLABS_CUBE.getDefaultState()
.with(AXIS, current_state.get(FACING).getAxis());
return super.getPlacementState(ctx).with(FACING, ctx.getSide().getOpposite());
}
@@ -77,32 +89,8 @@ public class ReFramedSlabBlock extends WaterloggableReFramedBlock implements Blo
}
@Override
public MultipartBlockStateSupplier getMultipart() {
Identifier model_id = ReFramed.id("slab_special");
return MultipartBlockStateSupplier.create(this)
.with(GBlockstate.when(FACING, Direction.DOWN),
GBlockstate.variant(model_id, true, R0, R0))
.with(GBlockstate.when(FACING, Direction.SOUTH),
GBlockstate.variant(model_id, true, R90, R0))
.with(GBlockstate.when(FACING, Direction.UP),
GBlockstate.variant(model_id, true, R180, R0))
.with(GBlockstate.when(FACING, Direction.NORTH),
GBlockstate.variant(model_id, true, R270, R0))
.with(GBlockstate.when(FACING, Direction.WEST),
GBlockstate.variant(model_id, true, R90, R90))
.with(GBlockstate.when(FACING, Direction.EAST),
GBlockstate.variant(model_id, true, R90, R270));
}
@Override
public void setRecipe(RecipeExporter exporter) {
RecipeProvider.offerStonecuttingRecipe(exporter, RecipeCategory.BUILDING_BLOCKS, this, ReFramed.CUBE, 2);
ShapedRecipeJsonBuilder
.create(RecipeCategory.BUILDING_BLOCKS, this, 6)
.pattern("III")
.input('I', ReFramed.CUBE)
.criterion(FabricRecipeProvider.hasItem(ReFramed.CUBE), FabricRecipeProvider.conditionsFromItem(ReFramed.CUBE))
.criterion(FabricRecipeProvider.hasItem(this), FabricRecipeProvider.conditionsFromItem(this))
.offerTo(exporter);
public Map<Integer, Integer> getThemeMap(BlockState state, BlockState new_state) {
if (new_state.isOf(ReFramed.SLABS_CUBE)) return Map.of(1, state.get(FACING).getDirection() == Direction.AxisDirection.POSITIVE ? 2 : 1);
return super.getThemeMap(state, new_state);
}
}

View File

@@ -1,29 +1,17 @@
package fr.adrien1106.reframed.block;
import fr.adrien1106.reframed.ReFramed;
import fr.adrien1106.reframed.generator.BlockStateProvider;
import fr.adrien1106.reframed.generator.GBlockstate;
import net.fabricmc.fabric.api.datagen.v1.provider.FabricRecipeProvider;
import net.minecraft.block.Block;
import net.minecraft.block.BlockState;
import net.minecraft.data.client.MultipartBlockStateSupplier;
import net.minecraft.data.server.recipe.RecipeExporter;
import net.minecraft.data.server.recipe.RecipeProvider;
import net.minecraft.data.server.recipe.ShapelessRecipeJsonBuilder;
import net.minecraft.item.ItemPlacementContext;
import net.minecraft.recipe.book.RecipeCategory;
import net.minecraft.state.StateManager;
import net.minecraft.util.Identifier;
import net.minecraft.util.math.Direction;
import net.minecraft.util.shape.VoxelShape;
import org.jetbrains.annotations.Nullable;
import static fr.adrien1106.reframed.block.ReFramedSlabBlock.*;
import static net.minecraft.data.client.VariantSettings.Rotation.R0;
import static net.minecraft.data.client.VariantSettings.Rotation.R90;
import static net.minecraft.state.property.Properties.AXIS;
public class ReFramedSlabsCubeBlock extends ReFramedDoubleBlock implements BlockStateProvider {
public class ReFramedSlabsCubeBlock extends ReFramedDoubleBlock {
public ReFramedSlabsCubeBlock(Settings settings) {
super(settings);
@@ -35,11 +23,6 @@ public class ReFramedSlabsCubeBlock extends ReFramedDoubleBlock implements Block
return state.get(AXIS);
}
@Override
public int getModelStateCount() {
return 3;
}
@Override
protected void appendProperties(StateManager.Builder<Block, BlockState> builder) {
super.appendProperties(builder.add(AXIS));
@@ -55,37 +38,13 @@ public class ReFramedSlabsCubeBlock extends ReFramedDoubleBlock implements Block
public VoxelShape getShape(BlockState state, int i) {
return switch (state.get(AXIS)) {
case Y -> i == 2 ? UP : DOWN;
case Z -> i == 2 ? NORTH : SOUTH;
case Z -> i == 2 ? SOUTH : NORTH;
case X -> i == 2 ? EAST : WEST;
};
}
@Override
public int getTopThemeIndex(BlockState state) {
// when the side is shared just return one
return state.get(AXIS) == Direction.Axis.Y ? 2: super.getTopThemeIndex(state);
}
@Override
public MultipartBlockStateSupplier getMultipart() {
Identifier model_id = ReFramed.id("double_slab_special");
return MultipartBlockStateSupplier.create(this)
.with(GBlockstate.when(AXIS, Direction.Axis.Y),
GBlockstate.variant(model_id, true, R0, R0))
.with(GBlockstate.when(AXIS, Direction.Axis.Z),
GBlockstate.variant(model_id, true, R90, R0))
.with(GBlockstate.when(AXIS, Direction.Axis.X),
GBlockstate.variant(model_id, true, R90, R90));
}
@Override
public void setRecipe(RecipeExporter exporter) {
RecipeProvider.offerStonecuttingRecipe(exporter, RecipeCategory.BUILDING_BLOCKS, this, ReFramed.CUBE);
ShapelessRecipeJsonBuilder
.create(RecipeCategory.BUILDING_BLOCKS, this)
.input(ReFramed.SLAB, 2)
.criterion(FabricRecipeProvider.hasItem(ReFramed.CUBE), FabricRecipeProvider.conditionsFromItem(ReFramed.CUBE))
.criterion(FabricRecipeProvider.hasItem(this), FabricRecipeProvider.conditionsFromItem(this))
.offerTo(exporter);
return 2;
}
}

View File

@@ -1,35 +1,31 @@
package fr.adrien1106.reframed.block;
import fr.adrien1106.reframed.ReFramed;
import fr.adrien1106.reframed.generator.BlockStateProvider;
import fr.adrien1106.reframed.generator.GBlockstate;
import fr.adrien1106.reframed.util.VoxelHelper;
import fr.adrien1106.reframed.util.blocks.BlockHelper;
import net.fabricmc.fabric.api.datagen.v1.provider.FabricRecipeProvider;
import fr.adrien1106.reframed.util.blocks.Corner;
import net.minecraft.block.Block;
import net.minecraft.block.BlockState;
import net.minecraft.block.ShapeContext;
import net.minecraft.data.client.BlockStateSupplier;
import net.minecraft.data.client.MultipartBlockStateSupplier;
import net.minecraft.data.server.recipe.RecipeExporter;
import net.minecraft.data.server.recipe.RecipeProvider;
import net.minecraft.data.server.recipe.ShapelessRecipeJsonBuilder;
import net.minecraft.item.BlockItem;
import net.minecraft.item.ItemPlacementContext;
import net.minecraft.recipe.book.RecipeCategory;
import net.minecraft.state.StateManager;
import net.minecraft.util.Identifier;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.Direction;
import net.minecraft.util.math.Vec3d;
import net.minecraft.util.shape.VoxelShape;
import net.minecraft.util.shape.VoxelShapes;
import net.minecraft.world.BlockView;
import org.jetbrains.annotations.Nullable;
import static fr.adrien1106.reframed.util.VoxelHelper.VoxelListBuilder;
import static fr.adrien1106.reframed.util.blocks.BlockProperties.CORNER;
import static fr.adrien1106.reframed.util.blocks.Corner.*;
import static net.minecraft.data.client.VariantSettings.Rotation.*;
import java.util.Map;
public class ReFramedSmallCubeBlock extends WaterloggableReFramedBlock implements BlockStateProvider {
import static fr.adrien1106.reframed.util.VoxelHelper.VoxelListBuilder;
import static fr.adrien1106.reframed.util.blocks.BlockProperties.*;
import static fr.adrien1106.reframed.util.blocks.Corner.*;
import static net.minecraft.state.property.Properties.WATERLOGGED;
public class ReFramedSmallCubeBlock extends WaterloggableReFramedBlock {
public static final VoxelShape[] SMALL_CUBE_VOXELS;
@@ -43,18 +39,89 @@ public class ReFramedSmallCubeBlock extends WaterloggableReFramedBlock implement
return state.get(CORNER);
}
@Override
public int getModelStateCount() {
return 8;
}
@Override
protected void appendProperties(StateManager.Builder<Block, BlockState> builder) {
super.appendProperties(builder.add(CORNER));
}
@Override
public boolean canReplace(BlockState state, ItemPlacementContext context) {
Corner corner = state.get(CORNER);
return !(
context.getPlayer().isSneaking()
|| !(context.getStack().getItem() instanceof BlockItem block_item)
|| (
!(
block_item.getBlock() == ReFramed.HALF_STAIR
&& !(corner.hasDirection(context.getSide())
|| (corner.hasDirection(context.getSide().getOpposite())
&& BlockHelper.cursorMatchesFace(
getOutlineShape(state, context.getWorld(), context.getBlockPos(), null),
BlockHelper.getRelativePos(context.getHitPos(), context.getBlockPos())
)
)
)
)
&& !(
block_item.getBlock() == this
&& (
((ReFramedSmallCubesStepBlock) ReFramed.SMALL_CUBES_STEP)
.matchesShape(
context.getHitPos(),
context.getBlockPos(),
ReFramed.SMALL_CUBES_STEP.getDefaultState().with(EDGE, corner.getEdge(corner.getFirstDirection())),
corner.getFirstDirection().getDirection() == Direction.AxisDirection.POSITIVE ? 1 : 2
)
|| ((ReFramedSmallCubesStepBlock) ReFramed.SMALL_CUBES_STEP)
.matchesShape(
context.getHitPos(),
context.getBlockPos(),
ReFramed.SMALL_CUBES_STEP.getDefaultState().with(EDGE, corner.getEdge(corner.getSecondDirection())),
corner.getSecondDirection().getDirection() == Direction.AxisDirection.POSITIVE ? 1 : 2
)
|| ((ReFramedSmallCubesStepBlock) ReFramed.SMALL_CUBES_STEP)
.matchesShape(
context.getHitPos(),
context.getBlockPos(),
ReFramed.SMALL_CUBES_STEP.getDefaultState().with(EDGE, corner.getEdge(corner.getThirdDirection())),
corner.getThirdDirection().getDirection() == Direction.AxisDirection.POSITIVE ? 1 : 2
)
)
)
)
);
}
@Override
public @Nullable BlockState getPlacementState(ItemPlacementContext ctx) {
BlockPos pos = ctx.getBlockPos();
BlockState current_state = ctx.getWorld().getBlockState(pos);
if (current_state.isOf(ReFramed.HALF_STAIR))
return ReFramed.HALF_STAIRS_SLAB.getDefaultState()
.with(CORNER, current_state.get(CORNER))
.with(CORNER_FACE, current_state.get(CORNER_FACE))
.with(WATERLOGGED, current_state.get(WATERLOGGED));
if (current_state.isOf(this)) {
Vec3d hit = ctx.getHitPos();
Corner corner = current_state.get(CORNER);
ReFramedSmallCubesStepBlock block = ((ReFramedSmallCubesStepBlock) ReFramed.SMALL_CUBES_STEP);
BlockState state = block.getDefaultState()
.with(EDGE, corner.getEdge(corner.getFirstDirection()))
.with(WATERLOGGED, current_state.get(WATERLOGGED));
if (block.matchesShape(
hit, pos, state,
corner.getFirstDirection().getDirection() == Direction.AxisDirection.POSITIVE ? 1 : 2
)) return state;
state = state.with(EDGE, corner.getEdge(corner.getSecondDirection()));
if (block.matchesShape(
hit, pos, state,
corner.getSecondDirection().getDirection() == Direction.AxisDirection.POSITIVE ? 1 : 2
)) return state;
return state.with(EDGE, corner.getEdge(corner.getThirdDirection()));
}
return super.getPlacementState(ctx).with(CORNER, BlockHelper.getPlacementCorner(ctx));
}
@@ -64,36 +131,16 @@ public class ReFramedSmallCubeBlock extends WaterloggableReFramedBlock implement
}
@Override
public BlockStateSupplier getMultipart() {
Identifier small_cube_id = ReFramed.id("small_cube_special");
return MultipartBlockStateSupplier.create(this)
.with(GBlockstate.when(CORNER, NORTH_EAST_DOWN),
GBlockstate.variant(small_cube_id, true, R0, R0))
.with(GBlockstate.when(CORNER, EAST_SOUTH_DOWN),
GBlockstate.variant(small_cube_id, true, R0, R90))
.with(GBlockstate.when(CORNER, SOUTH_WEST_DOWN),
GBlockstate.variant(small_cube_id, true, R0, R180))
.with(GBlockstate.when(CORNER, WEST_NORTH_DOWN),
GBlockstate.variant(small_cube_id, true, R0, R270))
.with(GBlockstate.when(CORNER, EAST_SOUTH_UP),
GBlockstate.variant(small_cube_id, true, R180, R0))
.with(GBlockstate.when(CORNER, SOUTH_WEST_UP),
GBlockstate.variant(small_cube_id, true, R180, R90))
.with(GBlockstate.when(CORNER, WEST_NORTH_UP),
GBlockstate.variant(small_cube_id, true, R180, R180))
.with(GBlockstate.when(CORNER, NORTH_EAST_UP),
GBlockstate.variant(small_cube_id, true, R180, R270));
}
@Override
public void setRecipe(RecipeExporter exporter) {
RecipeProvider.offerStonecuttingRecipe(exporter, RecipeCategory.BUILDING_BLOCKS, this, ReFramed.CUBE, 8);
ShapelessRecipeJsonBuilder
.create(RecipeCategory.BUILDING_BLOCKS, this, 8)
.input(ReFramed.CUBE)
.criterion(FabricRecipeProvider.hasItem(ReFramed.CUBE), FabricRecipeProvider.conditionsFromItem(ReFramed.CUBE))
.criterion(FabricRecipeProvider.hasItem(this), FabricRecipeProvider.conditionsFromItem(this))
.offerTo(exporter);
public Map<Integer, Integer> getThemeMap(BlockState state, BlockState new_state) {
if (new_state.isOf(ReFramed.HALF_STAIRS_SLAB)) return Map.of(1, 2);
if (new_state.isOf(ReFramed.SMALL_CUBES_STEP))
return Map.of(
1,
state.get(CORNER)
.getOtherDirection(new_state.get(EDGE))
.getDirection() == Direction.AxisDirection.POSITIVE ? 2 : 1
);
return super.getThemeMap(state, new_state);
}
static {

View File

@@ -1,24 +1,13 @@
package fr.adrien1106.reframed.block;
import fr.adrien1106.reframed.ReFramed;
import fr.adrien1106.reframed.generator.BlockStateProvider;
import fr.adrien1106.reframed.generator.GBlockstate;
import fr.adrien1106.reframed.util.blocks.BlockHelper;
import fr.adrien1106.reframed.util.blocks.Corner;
import fr.adrien1106.reframed.util.blocks.Edge;
import net.fabricmc.fabric.api.datagen.v1.provider.FabricRecipeProvider;
import net.minecraft.block.Block;
import net.minecraft.block.BlockState;
import net.minecraft.block.ShapeContext;
import net.minecraft.data.client.BlockStateSupplier;
import net.minecraft.data.client.MultipartBlockStateSupplier;
import net.minecraft.data.server.recipe.RecipeExporter;
import net.minecraft.data.server.recipe.RecipeProvider;
import net.minecraft.data.server.recipe.ShapelessRecipeJsonBuilder;
import net.minecraft.item.ItemPlacementContext;
import net.minecraft.recipe.book.RecipeCategory;
import net.minecraft.state.StateManager;
import net.minecraft.util.Identifier;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.shape.VoxelShape;
import net.minecraft.world.BlockView;
@@ -27,11 +16,9 @@ import org.jetbrains.annotations.Nullable;
import static fr.adrien1106.reframed.block.ReFramedSmallCubeBlock.SMALL_CUBE_VOXELS;
import static fr.adrien1106.reframed.block.ReFramedStepBlock.getStepShape;
import static fr.adrien1106.reframed.util.blocks.BlockProperties.EDGE;
import static fr.adrien1106.reframed.util.blocks.Edge.*;
import static net.minecraft.data.client.VariantSettings.Rotation.*;
import static net.minecraft.util.shape.VoxelShapes.empty;
public class ReFramedSmallCubesStepBlock extends WaterloggableReFramedDoubleBlock implements BlockStateProvider {
public class ReFramedSmallCubesStepBlock extends WaterloggableReFramedDoubleBlock {
public ReFramedSmallCubesStepBlock(Settings settings) {
super(settings);
@@ -43,11 +30,6 @@ public class ReFramedSmallCubesStepBlock extends WaterloggableReFramedDoubleBloc
return state.get(EDGE);
}
@Override
public int getModelStateCount() {
return 12;
}
@Override
protected void appendProperties(StateManager.Builder<Block, BlockState> builder) {
super.appendProperties(builder.add(EDGE));
@@ -85,49 +67,4 @@ public class ReFramedSmallCubesStepBlock extends WaterloggableReFramedDoubleBloc
public int getTopThemeIndex(BlockState state) {
return 2;
}
@Override
public BlockStateSupplier getMultipart() {
Identifier model_id = ReFramed.id("small_cubes_step_special");
Identifier reverse_model_id = ReFramed.id("small_cubes_step_reverse_special");
return MultipartBlockStateSupplier.create(this)
/* X AXIS */
.with(GBlockstate.when(EDGE, DOWN_EAST),
GBlockstate.variant(reverse_model_id, true, R0, R0))
.with(GBlockstate.when(EDGE, EAST_UP),
GBlockstate.variant(model_id, true, R180, R0))
.with(GBlockstate.when(EDGE, UP_WEST),
GBlockstate.variant(reverse_model_id, true, R180, R180))
.with(GBlockstate.when(EDGE, WEST_DOWN),
GBlockstate.variant(model_id, true, R0, R180))
/* Y AXIS */
.with(GBlockstate.when(EDGE, EAST_SOUTH),
GBlockstate.variant(model_id, true, R90, R0))
.with(GBlockstate.when(EDGE, SOUTH_WEST),
GBlockstate.variant(model_id, true, R90, R90))
.with(GBlockstate.when(EDGE, WEST_NORTH),
GBlockstate.variant(model_id, true, R90, R180))
.with(GBlockstate.when(EDGE, NORTH_EAST),
GBlockstate.variant(model_id, true, R90, R270))
/* Z AXIS */
.with(GBlockstate.when(EDGE, DOWN_SOUTH),
GBlockstate.variant(reverse_model_id, true, R0, R90))
.with(GBlockstate.when(EDGE, NORTH_DOWN),
GBlockstate.variant(model_id, true, R0, R270))
.with(GBlockstate.when(EDGE, UP_NORTH),
GBlockstate.variant(reverse_model_id, true, R180, R270))
.with(GBlockstate.when(EDGE, SOUTH_UP),
GBlockstate.variant(model_id, true, R180, R90));
}
@Override
public void setRecipe(RecipeExporter exporter) {
RecipeProvider.offerStonecuttingRecipe(exporter, RecipeCategory.BUILDING_BLOCKS, this, ReFramed.CUBE, 4);
ShapelessRecipeJsonBuilder
.create(RecipeCategory.BUILDING_BLOCKS, this)
.input(ReFramed.SMALL_CUBE, 2)
.criterion(FabricRecipeProvider.hasItem(ReFramed.CUBE), FabricRecipeProvider.conditionsFromItem(ReFramed.CUBE))
.criterion(FabricRecipeProvider.hasItem(this), FabricRecipeProvider.conditionsFromItem(this))
.offerTo(exporter);
}
}

View File

@@ -1,25 +1,16 @@
package fr.adrien1106.reframed.block;
import fr.adrien1106.reframed.ReFramed;
import fr.adrien1106.reframed.generator.BlockStateProvider;
import fr.adrien1106.reframed.generator.GBlockstate;
import fr.adrien1106.reframed.util.VoxelHelper;
import fr.adrien1106.reframed.util.blocks.BlockHelper;
import fr.adrien1106.reframed.util.blocks.Edge;
import fr.adrien1106.reframed.util.blocks.StairShape;
import net.fabricmc.fabric.api.datagen.v1.provider.FabricRecipeProvider;
import net.minecraft.block.Block;
import net.minecraft.block.BlockState;
import net.minecraft.block.ShapeContext;
import net.minecraft.data.client.MultipartBlockStateSupplier;
import net.minecraft.data.client.When;
import net.minecraft.data.server.recipe.RecipeExporter;
import net.minecraft.data.server.recipe.RecipeProvider;
import net.minecraft.data.server.recipe.ShapedRecipeJsonBuilder;
import net.minecraft.item.BlockItem;
import net.minecraft.item.ItemPlacementContext;
import net.minecraft.recipe.book.RecipeCategory;
import net.minecraft.state.StateManager;
import net.minecraft.util.Identifier;
import net.minecraft.util.function.BooleanBiFunction;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.Direction;
@@ -30,16 +21,15 @@ import net.minecraft.world.World;
import net.minecraft.world.WorldAccess;
import org.jetbrains.annotations.Nullable;
import java.util.Map;
import java.util.stream.Stream;
import static fr.adrien1106.reframed.util.VoxelHelper.VoxelListBuilder;
import static fr.adrien1106.reframed.util.blocks.BlockProperties.EDGE;
import static fr.adrien1106.reframed.util.blocks.BlockProperties.STAIR_SHAPE;
import static fr.adrien1106.reframed.util.blocks.Edge.*;
import static fr.adrien1106.reframed.util.blocks.StairShape.*;
import static net.minecraft.data.client.VariantSettings.Rotation.*;
public class ReFramedStairBlock extends WaterloggableReFramedBlock implements BlockStateProvider {
public class ReFramedStairBlock extends WaterloggableReFramedBlock {
public static final VoxelShape[] STAIR_VOXELS;
private record ModelCacheKey(Edge edge, StairShape shape) {}
@@ -52,17 +42,30 @@ public class ReFramedStairBlock extends WaterloggableReFramedBlock implements Bl
public Object getModelCacheKey(BlockState state) {
return new ModelCacheKey(state.get(EDGE), state.get(STAIR_SHAPE));
}
@Override
public int getModelStateCount() {
return 108; // Has 12 * 9 state combination and 52 models still reduces cache size
}
@Override
protected void appendProperties(StateManager.Builder<Block, BlockState> builder) {
super.appendProperties(builder.add(EDGE, STAIR_SHAPE));
}
@Override
public boolean canReplace(BlockState state, ItemPlacementContext context) {
return !(
context.getPlayer().isSneaking()
|| !(context.getStack().getItem() instanceof BlockItem block_item)
|| !(
block_item.getBlock() == ReFramed.STEP
&& ((ReFramedStairsCubeBlock) ReFramed.STAIRS_CUBE)
.matchesShape(
context.getHitPos(),
context.getBlockPos(),
state,
2
)
)
);
}
@Override
public BlockState getStateForNeighborUpdate(BlockState state, Direction direction, BlockState neighbor_state, WorldAccess world, BlockPos pos, BlockPos moved) {
return super.getStateForNeighborUpdate(state, direction, neighbor_state, world, pos, moved)
@@ -70,11 +73,20 @@ public class ReFramedStairBlock extends WaterloggableReFramedBlock implements Bl
}
@Nullable
@Override // Pretty happy of how clean it is (also got it on first try :) )
@Override
public BlockState getPlacementState(ItemPlacementContext ctx) {
Edge face = BlockHelper.getPlacementEdge(ctx);
StairShape shape = BlockHelper.getStairsShape(face, ctx.getWorld(), ctx.getBlockPos());
return super.getPlacementState(ctx).with(EDGE, face).with(STAIR_SHAPE, shape);
BlockState current_state = ctx.getWorld().getBlockState(ctx.getBlockPos());
if (current_state.isOf(ReFramed.STEP)) {
Edge edge = current_state.get(EDGE).opposite();
StairShape shape = BlockHelper.getStairsShape(edge, ctx.getWorld(), ctx.getBlockPos());
return ReFramed.STAIRS_CUBE.getDefaultState()
.with(EDGE, edge)
.with(STAIR_SHAPE, shape);
}
Edge edge = BlockHelper.getPlacementEdge(ctx);
StairShape shape = BlockHelper.getStairsShape(edge, ctx.getWorld(), ctx.getBlockPos());
return super.getPlacementState(ctx).with(EDGE, edge).with(STAIR_SHAPE, shape);
}
@Override
@@ -94,245 +106,9 @@ public class ReFramedStairBlock extends WaterloggableReFramedBlock implements Bl
}
@Override
public MultipartBlockStateSupplier getMultipart() {
return getStairMultipart(this, false);
}
public static MultipartBlockStateSupplier getStairMultipart(Block block, boolean is_double) {
String infix = is_double ? "s_cube" : "";
Identifier straight_id = ReFramed.id("stair" + infix + "_special");
Identifier double_outer_id = ReFramed.id("outers_stair" + infix + "_special");
Identifier inner_id = ReFramed.id("inner_stair" + infix + "_special");
Identifier outer_id = ReFramed.id("outer_stair" + infix + "_special");
Identifier outer_side_id = ReFramed.id("outer_side_stair" + infix + "_special");
return MultipartBlockStateSupplier.create(block)
/* STRAIGHT X AXIS */
.with(GBlockstate.when(EDGE, DOWN_EAST, STAIR_SHAPE, STRAIGHT),
GBlockstate.variant(straight_id, true, R0, R0))
.with(GBlockstate.when(EDGE, EAST_UP, STAIR_SHAPE, STRAIGHT),
GBlockstate.variant(straight_id, true, R180, R0))
.with(GBlockstate.when(EDGE, UP_WEST, STAIR_SHAPE, STRAIGHT),
GBlockstate.variant(straight_id, true, R180, R180))
.with(GBlockstate.when(EDGE, WEST_DOWN, STAIR_SHAPE, STRAIGHT),
GBlockstate.variant(straight_id, true, R0, R180))
/* STRAIGHT Y AXIS */
.with(GBlockstate.when(EDGE, EAST_SOUTH, STAIR_SHAPE, STRAIGHT),
GBlockstate.variant(straight_id, true, R90, R0))
.with(GBlockstate.when(EDGE, SOUTH_WEST, STAIR_SHAPE, STRAIGHT),
GBlockstate.variant(straight_id, true, R90, R90))
.with(GBlockstate.when(EDGE, WEST_NORTH, STAIR_SHAPE, STRAIGHT),
GBlockstate.variant(straight_id, true, R90, R180))
.with(GBlockstate.when(EDGE, NORTH_EAST, STAIR_SHAPE, STRAIGHT),
GBlockstate.variant(straight_id, true, R90, R270))
/* STRAIGHT Z AXIS */
.with(GBlockstate.when(EDGE, DOWN_SOUTH, STAIR_SHAPE, STRAIGHT),
GBlockstate.variant(straight_id, true, R0, R90))
.with(GBlockstate.when(EDGE, NORTH_DOWN, STAIR_SHAPE, STRAIGHT),
GBlockstate.variant(straight_id, true, R0, R270))
.with(GBlockstate.when(EDGE, UP_NORTH, STAIR_SHAPE, STRAIGHT),
GBlockstate.variant(straight_id, true, R180, R270))
.with(GBlockstate.when(EDGE, SOUTH_UP, STAIR_SHAPE, STRAIGHT),
GBlockstate.variant(straight_id, true, R180, R90))
/* INNER BOTTOM */
.with(When.anyOf(
GBlockstate.when(EDGE, NORTH_DOWN, STAIR_SHAPE, INNER_RIGHT),
GBlockstate.when(EDGE, WEST_NORTH, STAIR_SHAPE, INNER_RIGHT),
GBlockstate.when(EDGE, WEST_DOWN, STAIR_SHAPE, INNER_LEFT)),
GBlockstate.variant(inner_id, true, R0, R180))
.with(When.anyOf(
GBlockstate.when(EDGE, NORTH_DOWN, STAIR_SHAPE, INNER_LEFT),
GBlockstate.when(EDGE, NORTH_EAST, STAIR_SHAPE, INNER_RIGHT),
GBlockstate.when(EDGE, DOWN_EAST, STAIR_SHAPE, INNER_LEFT)),
GBlockstate.variant(inner_id, true, R0, R270))
.with(When.anyOf(
GBlockstate.when(EDGE, DOWN_SOUTH, STAIR_SHAPE, INNER_LEFT),
GBlockstate.when(EDGE, EAST_SOUTH, STAIR_SHAPE, INNER_RIGHT),
GBlockstate.when(EDGE, DOWN_EAST, STAIR_SHAPE, INNER_RIGHT)),
GBlockstate.variant(inner_id, true, R0, R0))
.with(When.anyOf(
GBlockstate.when(EDGE, DOWN_SOUTH, STAIR_SHAPE, INNER_RIGHT),
GBlockstate.when(EDGE, SOUTH_WEST, STAIR_SHAPE, INNER_RIGHT),
GBlockstate.when(EDGE, WEST_DOWN, STAIR_SHAPE, INNER_RIGHT)),
GBlockstate.variant(inner_id, true, R0, R90))
/* INNER TOP */
.with(When.anyOf(
GBlockstate.when(EDGE, EAST_UP, STAIR_SHAPE, INNER_LEFT),
GBlockstate.when(EDGE, NORTH_EAST, STAIR_SHAPE, INNER_LEFT),
GBlockstate.when(EDGE, UP_NORTH, STAIR_SHAPE, INNER_LEFT)),
GBlockstate.variant(inner_id, true, R180, R0))
.with(When.anyOf(
GBlockstate.when(EDGE, EAST_UP, STAIR_SHAPE, INNER_RIGHT),
GBlockstate.when(EDGE, EAST_SOUTH, STAIR_SHAPE, INNER_LEFT),
GBlockstate.when(EDGE, SOUTH_UP, STAIR_SHAPE, INNER_LEFT)),
GBlockstate.variant(inner_id, true, R180, R90))
.with(When.anyOf(
GBlockstate.when(EDGE, SOUTH_UP, STAIR_SHAPE, INNER_RIGHT),
GBlockstate.when(EDGE, SOUTH_WEST, STAIR_SHAPE, INNER_LEFT),
GBlockstate.when(EDGE, UP_WEST, STAIR_SHAPE, INNER_RIGHT)),
GBlockstate.variant(inner_id, true, R180, R180))
.with(When.anyOf(
GBlockstate.when(EDGE, UP_NORTH, STAIR_SHAPE, INNER_RIGHT),
GBlockstate.when(EDGE, WEST_NORTH, STAIR_SHAPE, INNER_LEFT),
GBlockstate.when(EDGE, UP_WEST, STAIR_SHAPE, INNER_LEFT)),
GBlockstate.variant(inner_id, true, R180, R270))
/* OUTER BOTTOM */
.with(When.anyOf(
GBlockstate.when(EDGE, DOWN_SOUTH, STAIR_SHAPE, SECOND_OUTER_LEFT),
GBlockstate.when(EDGE, DOWN_EAST, STAIR_SHAPE, SECOND_OUTER_RIGHT)),
GBlockstate.variant(outer_id, true, R0, R0))
.with(When.anyOf(
GBlockstate.when(EDGE, DOWN_SOUTH, STAIR_SHAPE, SECOND_OUTER_RIGHT),
GBlockstate.when(EDGE, WEST_DOWN, STAIR_SHAPE, FIRST_OUTER_RIGHT)),
GBlockstate.variant(outer_id, true, R0, R90))
.with(When.anyOf(
GBlockstate.when(EDGE, NORTH_DOWN, STAIR_SHAPE, FIRST_OUTER_RIGHT),
GBlockstate.when(EDGE, WEST_DOWN, STAIR_SHAPE, FIRST_OUTER_LEFT)),
GBlockstate.variant(outer_id, true, R0, R180))
.with(When.anyOf(
GBlockstate.when(EDGE, NORTH_DOWN, STAIR_SHAPE, FIRST_OUTER_LEFT),
GBlockstate.when(EDGE, DOWN_EAST, STAIR_SHAPE, SECOND_OUTER_LEFT)),
GBlockstate.variant(outer_id, true, R0, R270))
/* OUTER TOP */
.with(When.anyOf(
GBlockstate.when(EDGE, UP_NORTH, STAIR_SHAPE, SECOND_OUTER_LEFT),
GBlockstate.when(EDGE, EAST_UP, STAIR_SHAPE, FIRST_OUTER_LEFT)),
GBlockstate.variant(outer_id, true, R180, R0))
.with(When.anyOf(
GBlockstate.when(EDGE, SOUTH_UP, STAIR_SHAPE, FIRST_OUTER_LEFT),
GBlockstate.when(EDGE, EAST_UP, STAIR_SHAPE, FIRST_OUTER_RIGHT)),
GBlockstate.variant(outer_id, true, R180, R90))
.with(When.anyOf(
GBlockstate.when(EDGE, SOUTH_UP, STAIR_SHAPE, FIRST_OUTER_RIGHT),
GBlockstate.when(EDGE, UP_WEST, STAIR_SHAPE, SECOND_OUTER_RIGHT)),
GBlockstate.variant(outer_id, true, R180, R180))
.with(When.anyOf(
GBlockstate.when(EDGE, UP_NORTH, STAIR_SHAPE, SECOND_OUTER_RIGHT),
GBlockstate.when(EDGE, UP_WEST, STAIR_SHAPE, SECOND_OUTER_LEFT)),
GBlockstate.variant(outer_id, true, R180, R270))
/* OUTER EAST */
.with(When.anyOf(
GBlockstate.when(EDGE, EAST_SOUTH, STAIR_SHAPE, SECOND_OUTER_RIGHT),
GBlockstate.when(EDGE, DOWN_EAST, STAIR_SHAPE, FIRST_OUTER_RIGHT)),
GBlockstate.variant(outer_side_id, true, R0, R0))
.with(When.anyOf(
GBlockstate.when(EDGE, EAST_SOUTH, STAIR_SHAPE, SECOND_OUTER_LEFT),
GBlockstate.when(EDGE, EAST_UP, STAIR_SHAPE, SECOND_OUTER_RIGHT)),
GBlockstate.variant(outer_side_id, true, R90, R0))
.with(When.anyOf(
GBlockstate.when(EDGE, NORTH_EAST, STAIR_SHAPE, FIRST_OUTER_LEFT),
GBlockstate.when(EDGE, EAST_UP, STAIR_SHAPE, SECOND_OUTER_LEFT)),
GBlockstate.variant(outer_side_id, true, R180, R0))
.with(When.anyOf(
GBlockstate.when(EDGE, NORTH_EAST, STAIR_SHAPE, FIRST_OUTER_RIGHT),
GBlockstate.when(EDGE, DOWN_EAST, STAIR_SHAPE, FIRST_OUTER_LEFT)),
GBlockstate.variant(outer_side_id, true, R270, R0))
/* OUTER SOUTH */
.with(When.anyOf(
GBlockstate.when(EDGE, SOUTH_WEST, STAIR_SHAPE, SECOND_OUTER_RIGHT),
GBlockstate.when(EDGE, DOWN_SOUTH, STAIR_SHAPE, FIRST_OUTER_RIGHT)),
GBlockstate.variant(outer_side_id, true, R0, R90))
.with(When.anyOf(
GBlockstate.when(EDGE, SOUTH_WEST, STAIR_SHAPE, SECOND_OUTER_LEFT),
GBlockstate.when(EDGE, SOUTH_UP, STAIR_SHAPE, SECOND_OUTER_RIGHT)),
GBlockstate.variant(outer_side_id, true, R90, R90))
.with(When.anyOf(
GBlockstate.when(EDGE, EAST_SOUTH, STAIR_SHAPE, FIRST_OUTER_LEFT),
GBlockstate.when(EDGE, SOUTH_UP, STAIR_SHAPE, SECOND_OUTER_LEFT)),
GBlockstate.variant(outer_side_id, true, R180, R90))
.with(When.anyOf(
GBlockstate.when(EDGE, EAST_SOUTH, STAIR_SHAPE, FIRST_OUTER_RIGHT),
GBlockstate.when(EDGE, DOWN_SOUTH, STAIR_SHAPE, FIRST_OUTER_LEFT)),
GBlockstate.variant(outer_side_id, true, R270, R90))
/* OUTER WEST */
.with(When.anyOf(
GBlockstate.when(EDGE, WEST_NORTH, STAIR_SHAPE, SECOND_OUTER_RIGHT),
GBlockstate.when(EDGE, WEST_DOWN, STAIR_SHAPE, SECOND_OUTER_LEFT)),
GBlockstate.variant(outer_side_id, true, R0, R180))
.with(When.anyOf(
GBlockstate.when(EDGE, WEST_NORTH, STAIR_SHAPE, SECOND_OUTER_LEFT),
GBlockstate.when(EDGE, UP_WEST, STAIR_SHAPE, FIRST_OUTER_LEFT)),
GBlockstate.variant(outer_side_id, true, R90, R180))
.with(When.anyOf(
GBlockstate.when(EDGE, SOUTH_WEST, STAIR_SHAPE, FIRST_OUTER_LEFT),
GBlockstate.when(EDGE, UP_WEST, STAIR_SHAPE, FIRST_OUTER_RIGHT)),
GBlockstate.variant(outer_side_id, true, R180, R180))
.with(When.anyOf(
GBlockstate.when(EDGE, SOUTH_WEST, STAIR_SHAPE, FIRST_OUTER_RIGHT),
GBlockstate.when(EDGE, WEST_DOWN, STAIR_SHAPE, SECOND_OUTER_RIGHT)),
GBlockstate.variant(outer_side_id, true, R270, R180))
/* OUTER NORTH */
.with(When.anyOf(
GBlockstate.when(EDGE, NORTH_EAST, STAIR_SHAPE, SECOND_OUTER_RIGHT),
GBlockstate.when(EDGE, NORTH_DOWN, STAIR_SHAPE, SECOND_OUTER_LEFT)),
GBlockstate.variant(outer_side_id, true, R0, R270))
.with(When.anyOf(
GBlockstate.when(EDGE, NORTH_EAST, STAIR_SHAPE, SECOND_OUTER_LEFT),
GBlockstate.when(EDGE, UP_NORTH, STAIR_SHAPE, FIRST_OUTER_LEFT)),
GBlockstate.variant(outer_side_id, true, R90, R270))
.with(When.anyOf(
GBlockstate.when(EDGE, WEST_NORTH, STAIR_SHAPE, FIRST_OUTER_LEFT),
GBlockstate.when(EDGE, UP_NORTH, STAIR_SHAPE, FIRST_OUTER_RIGHT)),
GBlockstate.variant(outer_side_id, true, R180, R270))
.with(When.anyOf(
GBlockstate.when(EDGE, WEST_NORTH, STAIR_SHAPE, FIRST_OUTER_RIGHT),
GBlockstate.when(EDGE, NORTH_DOWN, STAIR_SHAPE, SECOND_OUTER_RIGHT)),
GBlockstate.variant(outer_side_id, true, R270, R270))
/* OUTER BOTTOM */
.with(When.anyOf(
GBlockstate.when(EDGE, DOWN_SOUTH, STAIR_SHAPE, OUTER_LEFT),
GBlockstate.when(EDGE, DOWN_EAST, STAIR_SHAPE, OUTER_RIGHT),
GBlockstate.when(EDGE, EAST_SOUTH, STAIR_SHAPE, OUTER_RIGHT)),
GBlockstate.variant(double_outer_id, true, R0, R0))
.with(When.anyOf(
GBlockstate.when(EDGE, DOWN_SOUTH, STAIR_SHAPE, OUTER_RIGHT),
GBlockstate.when(EDGE, WEST_DOWN, STAIR_SHAPE, OUTER_RIGHT),
GBlockstate.when(EDGE, SOUTH_WEST, STAIR_SHAPE, OUTER_RIGHT)),
GBlockstate.variant(double_outer_id, true, R0, R90))
.with(When.anyOf(
GBlockstate.when(EDGE, NORTH_DOWN, STAIR_SHAPE, OUTER_RIGHT),
GBlockstate.when(EDGE, WEST_DOWN, STAIR_SHAPE, OUTER_LEFT),
GBlockstate.when(EDGE, WEST_NORTH, STAIR_SHAPE, OUTER_RIGHT)),
GBlockstate.variant(double_outer_id, true, R0, R180))
.with(When.anyOf(
GBlockstate.when(EDGE, NORTH_DOWN, STAIR_SHAPE, OUTER_LEFT),
GBlockstate.when(EDGE, DOWN_EAST, STAIR_SHAPE, OUTER_LEFT),
GBlockstate.when(EDGE, NORTH_EAST, STAIR_SHAPE, OUTER_RIGHT)),
GBlockstate.variant(double_outer_id, true, R0, R270))
/* OUTER TOP */
.with(When.anyOf(
GBlockstate.when(EDGE, UP_NORTH, STAIR_SHAPE, OUTER_LEFT),
GBlockstate.when(EDGE, EAST_UP, STAIR_SHAPE, OUTER_LEFT),
GBlockstate.when(EDGE, NORTH_EAST, STAIR_SHAPE, OUTER_LEFT)),
GBlockstate.variant(double_outer_id, true, R180, R0))
.with(When.anyOf(
GBlockstate.when(EDGE, SOUTH_UP, STAIR_SHAPE, OUTER_LEFT),
GBlockstate.when(EDGE, EAST_UP, STAIR_SHAPE, OUTER_RIGHT),
GBlockstate.when(EDGE, EAST_SOUTH, STAIR_SHAPE, OUTER_LEFT)),
GBlockstate.variant(double_outer_id, true, R180, R90))
.with(When.anyOf(
GBlockstate.when(EDGE, SOUTH_UP, STAIR_SHAPE, OUTER_RIGHT),
GBlockstate.when(EDGE, UP_WEST, STAIR_SHAPE, OUTER_RIGHT),
GBlockstate.when(EDGE, SOUTH_WEST, STAIR_SHAPE, OUTER_LEFT)),
GBlockstate.variant(double_outer_id, true, R180, R180))
.with(When.anyOf(
GBlockstate.when(EDGE, UP_NORTH, STAIR_SHAPE, OUTER_RIGHT),
GBlockstate.when(EDGE, UP_WEST, STAIR_SHAPE, OUTER_LEFT),
GBlockstate.when(EDGE, WEST_NORTH, STAIR_SHAPE, OUTER_LEFT)),
GBlockstate.variant(double_outer_id, true, R180, R270));
}
@Override
public void setRecipe(RecipeExporter exporter) {
RecipeProvider.offerStonecuttingRecipe(exporter, RecipeCategory.BUILDING_BLOCKS, this, ReFramed.CUBE);
ShapedRecipeJsonBuilder
.create(RecipeCategory.BUILDING_BLOCKS, this, 4)
.pattern("I ")
.pattern("II ")
.pattern("III")
.input('I', ReFramed.CUBE)
.criterion(FabricRecipeProvider.hasItem(ReFramed.CUBE), FabricRecipeProvider.conditionsFromItem(ReFramed.CUBE))
.criterion(FabricRecipeProvider.hasItem(this), FabricRecipeProvider.conditionsFromItem(this))
.offerTo(exporter);
public Map<Integer, Integer> getThemeMap(BlockState state, BlockState new_state) {
if (new_state.isOf(ReFramed.STAIRS_CUBE)) return Map.of(1, 1);
return super.getThemeMap(state, new_state);
}
static {
@@ -382,51 +158,51 @@ public class ReFramedStairBlock extends WaterloggableReFramedBlock implements Bl
.add(25, VoxelHelper::rotateCX).add(26, VoxelHelper::rotateCX)
// WEST_DOWN
.add(0, VoxelHelper::rotateCY)
.add(10).add(1)
.add(12).add(3)
.add(16).add(5)
.add(7, VoxelHelper::rotateCY).add(8, VoxelHelper::rotateCY)
.add(1).add(10)
.add(3).add(12)
.add(5).add(16)
.add(8, VoxelHelper::rotateCY).add(7, VoxelHelper::rotateCY)
// DOWN_EAST
.add(36, VoxelHelper::rotateZ)
.add(11).add(2)
.add(13).add(4)
.add(2).add(11)
.add(4).add(13)
.add(41, VoxelHelper::rotateZ).add(42, VoxelHelper::rotateZ)
.add(17).add(6)
.add(6).add(17)
// EAST_UP
.add(45, VoxelHelper::rotateZ)
.add(20).add(29)
.add(22).add(31)
.add(24).add(35)
.add(29).add(20)
.add(31).add(22)
.add(35).add(24)
.add(52, VoxelHelper::rotateZ).add(53, VoxelHelper::rotateZ)
// UP_WEST
.add(54, VoxelHelper::rotateZ)
.add(19).add(28)
.add(21).add(30)
.add(28).add(19)
.add(30).add(21)
.add(59, VoxelHelper::rotateZ).add(60, VoxelHelper::rotateZ)
.add(23).add(34)
.add(34).add(23)
// WEST_NORTH
.add(0, VoxelHelper::rotateCZ)
.add(1).add(28)
.add(3).add(30)
.add(7).add(32)
.add(44).add(69)
.add(43).add(68)
// NORTH_EAST
.add(72, VoxelHelper::rotateY)
.add(2).add(29)
.add(4).add(31)
.add(51).add(62)
.add(50).add(61)
.add(8).add(33)
// EAST_SOUTH
.add(81, VoxelHelper::rotateY)
.add(11).add(20)
.add(13).add(22)
.add(15).add(26)
.add(50).add(61)
.add(51).add(62)
// SOUTH_WEST
.add(90, VoxelHelper::rotateY)
.add(10).add(19)
.add(12).add(21)
.add(43).add(68)
.add(44).add(69)
.add(14).add(25)
.build();
}

View File

@@ -1,19 +1,11 @@
package fr.adrien1106.reframed.block;
import fr.adrien1106.reframed.ReFramed;
import fr.adrien1106.reframed.generator.BlockStateProvider;
import fr.adrien1106.reframed.util.blocks.BlockHelper;
import fr.adrien1106.reframed.util.blocks.Edge;
import fr.adrien1106.reframed.util.blocks.StairShape;
import net.fabricmc.fabric.api.datagen.v1.provider.FabricRecipeProvider;
import net.minecraft.block.Block;
import net.minecraft.block.BlockState;
import net.minecraft.data.client.MultipartBlockStateSupplier;
import net.minecraft.data.server.recipe.RecipeExporter;
import net.minecraft.data.server.recipe.RecipeProvider;
import net.minecraft.data.server.recipe.ShapelessRecipeJsonBuilder;
import net.minecraft.item.ItemPlacementContext;
import net.minecraft.recipe.book.RecipeCategory;
import net.minecraft.state.StateManager;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.Direction;
@@ -27,7 +19,7 @@ import static fr.adrien1106.reframed.util.VoxelHelper.VoxelListBuilder;
import static fr.adrien1106.reframed.util.blocks.BlockProperties.EDGE;
import static fr.adrien1106.reframed.util.blocks.BlockProperties.STAIR_SHAPE;
public class ReFramedStairsCubeBlock extends ReFramedDoubleBlock implements BlockStateProvider {
public class ReFramedStairsCubeBlock extends ReFramedDoubleBlock {
private static final VoxelShape[] STAIRS_CUBE_VOXELS = VoxelListBuilder.buildFrom(STAIR_VOXELS);
private record ModelCacheKey(Edge edge, StairShape shape) {}
@@ -42,11 +34,6 @@ public class ReFramedStairsCubeBlock extends ReFramedDoubleBlock implements Bloc
return new ModelCacheKey(state.get(EDGE), state.get(STAIR_SHAPE));
}
@Override
public int getModelStateCount() {
return 108; // Has 12 * 9 state combination and 52 models still reduces cache size
}
@Override
protected void appendProperties(StateManager.Builder<Block, BlockState> builder) {
super.appendProperties(builder.add(EDGE, STAIR_SHAPE));
@@ -80,21 +67,4 @@ public class ReFramedStairsCubeBlock extends ReFramedDoubleBlock implements Bloc
StairShape shape = state.get(STAIR_SHAPE);
return i == 2 ? STAIRS_CUBE_VOXELS[edge.getID() * 9 + shape.getID()] : getStairShape(edge, shape);
}
@Override
public MultipartBlockStateSupplier getMultipart() {
return getStairMultipart(this, true);
}
@Override
public void setRecipe(RecipeExporter exporter) {
RecipeProvider.offerStonecuttingRecipe(exporter, RecipeCategory.BUILDING_BLOCKS, this, ReFramed.CUBE);
ShapelessRecipeJsonBuilder
.create(RecipeCategory.BUILDING_BLOCKS, this)
.input(ReFramed.STAIR)
.input(ReFramed.STEP)
.criterion(FabricRecipeProvider.hasItem(ReFramed.CUBE), FabricRecipeProvider.conditionsFromItem(ReFramed.CUBE))
.criterion(FabricRecipeProvider.hasItem(this), FabricRecipeProvider.conditionsFromItem(this))
.offerTo(exporter);
}
}

View File

@@ -1,35 +1,31 @@
package fr.adrien1106.reframed.block;
import fr.adrien1106.reframed.ReFramed;
import fr.adrien1106.reframed.generator.BlockStateProvider;
import fr.adrien1106.reframed.generator.GBlockstate;
import fr.adrien1106.reframed.util.VoxelHelper;
import fr.adrien1106.reframed.util.blocks.BlockHelper;
import fr.adrien1106.reframed.util.blocks.Edge;
import net.fabricmc.fabric.api.datagen.v1.provider.FabricRecipeProvider;
import net.minecraft.block.Block;
import net.minecraft.block.BlockState;
import net.minecraft.block.ShapeContext;
import net.minecraft.data.client.BlockStateSupplier;
import net.minecraft.data.client.MultipartBlockStateSupplier;
import net.minecraft.data.server.recipe.RecipeExporter;
import net.minecraft.data.server.recipe.RecipeProvider;
import net.minecraft.data.server.recipe.ShapedRecipeJsonBuilder;
import net.minecraft.item.BlockItem;
import net.minecraft.item.ItemPlacementContext;
import net.minecraft.recipe.book.RecipeCategory;
import net.minecraft.state.StateManager;
import net.minecraft.util.Identifier;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.Direction;
import net.minecraft.util.math.Vec3d;
import net.minecraft.util.shape.VoxelShape;
import net.minecraft.world.BlockView;
import org.jetbrains.annotations.Nullable;
import java.util.Map;
import static fr.adrien1106.reframed.util.VoxelHelper.VoxelListBuilder;
import static fr.adrien1106.reframed.util.blocks.BlockProperties.EDGE;
import static fr.adrien1106.reframed.util.blocks.Edge.*;
import static net.minecraft.data.client.VariantSettings.Rotation.*;
import static fr.adrien1106.reframed.util.blocks.BlockProperties.STAIR_SHAPE;
import static net.minecraft.state.property.Properties.*;
import static net.minecraft.state.property.Properties.WATERLOGGED;
public class ReFramedStepBlock extends WaterloggableReFramedBlock implements BlockStateProvider {
public class ReFramedStepBlock extends WaterloggableReFramedBlock {
public static final VoxelShape[] STEP_VOXELS;
@@ -44,18 +40,88 @@ public class ReFramedStepBlock extends WaterloggableReFramedBlock implements Blo
}
@Override
public int getModelStateCount() {
return 12;
protected void appendProperties(StateManager.Builder<Block, BlockState> builder) {
super.appendProperties(builder.add(EDGE));
}
@Override
protected void appendProperties(StateManager.Builder<Block, BlockState> builder) {
super.appendProperties(builder.add(EDGE));
public boolean canReplace(BlockState state, ItemPlacementContext context) {
Edge edge = state.get(EDGE);
return !(
context.getPlayer().isSneaking()
|| !(context.getStack().getItem() instanceof BlockItem block_item)
|| (
!(
block_item.getBlock() == ReFramed.STAIR
&& ((ReFramedStairsCubeBlock) ReFramed.STAIRS_CUBE)
.matchesShape(
context.getHitPos(),
context.getBlockPos(),
ReFramed.STAIRS_CUBE.getDefaultState().with(EDGE, edge.opposite()),
1
)
)
&& !(
block_item.getBlock() == this
&& (
((ReFramedStepsSlabBlock) ReFramed.STEPS_SLAB)
.matchesShape(
context.getHitPos(),
context.getBlockPos(),
ReFramed.STEPS_SLAB.getDefaultState()
.with(FACING, edge.getFirstDirection())
.with(AXIS, edge.getSecondDirection().getAxis()),
edge.getSecondDirection().getDirection() == Direction.AxisDirection.POSITIVE ? 1 : 2
)
|| ((ReFramedStepsSlabBlock) ReFramed.STEPS_SLAB)
.matchesShape(
context.getHitPos(),
context.getBlockPos(),
ReFramed.STEPS_SLAB.getDefaultState()
.with(FACING, edge.getSecondDirection())
.with(AXIS, edge.getFirstDirection().getAxis()),
edge.getFirstDirection().getDirection() == Direction.AxisDirection.POSITIVE ? 1 : 2
)
)
)
)
);
}
@Nullable
@Override
public BlockState getPlacementState(ItemPlacementContext ctx) {
BlockPos pos = ctx.getBlockPos();
BlockState current_state = ctx.getWorld().getBlockState(pos);
if (current_state.isOf(ReFramed.STAIR))
return ReFramed.STAIRS_CUBE.getDefaultState()
.with(EDGE, current_state.get(EDGE))
.with(STAIR_SHAPE, current_state.get(STAIR_SHAPE));
if (current_state.isOf(this)) {
Vec3d hit = ctx.getHitPos();
Edge edge = current_state.get(EDGE);
Direction dir = edge.getFirstDirection();
ReFramedStepsSlabBlock block = ((ReFramedStepsSlabBlock) ReFramed.STEPS_SLAB);
BlockState state = block.getDefaultState()
.with(FACING, dir)
.with(AXIS, edge.getOtherDirection(dir).getAxis())
.with(WATERLOGGED, current_state.get(WATERLOGGED));
if (!block.matchesShape(
hit, pos,
state,
edge.getOtherDirection(dir).getDirection() == Direction.AxisDirection.POSITIVE ? 1 : 2
)) {
dir = edge.getSecondDirection();
state = state
.with(FACING, dir)
.with(AXIS, edge.getOtherDirection(dir).getAxis());
}
return state;
}
return super.getPlacementState(ctx).with(EDGE, BlockHelper.getPlacementEdge(ctx));
}
@@ -69,48 +135,16 @@ public class ReFramedStepBlock extends WaterloggableReFramedBlock implements Blo
}
@Override
public BlockStateSupplier getMultipart() {
Identifier model_id = ReFramed.id("step_special");
return MultipartBlockStateSupplier.create(this)
/* X AXIS */
.with(GBlockstate.when(EDGE, DOWN_EAST),
GBlockstate.variant(model_id, true, R0, R0))
.with(GBlockstate.when(EDGE, EAST_UP),
GBlockstate.variant(model_id, true, R180, R0))
.with(GBlockstate.when(EDGE, UP_WEST),
GBlockstate.variant(model_id, true, R180, R180))
.with(GBlockstate.when(EDGE, WEST_DOWN),
GBlockstate.variant(model_id, true, R0, R180))
/* Y AXIS */
.with(GBlockstate.when(EDGE, EAST_SOUTH),
GBlockstate.variant(model_id, true, R90, R0))
.with(GBlockstate.when(EDGE, SOUTH_WEST),
GBlockstate.variant(model_id, true, R90, R90))
.with(GBlockstate.when(EDGE, WEST_NORTH),
GBlockstate.variant(model_id, true, R90, R180))
.with(GBlockstate.when(EDGE, NORTH_EAST),
GBlockstate.variant(model_id, true, R90, R270))
/* Z AXIS */
.with(GBlockstate.when(EDGE, DOWN_SOUTH),
GBlockstate.variant(model_id, true, R0, R90))
.with(GBlockstate.when(EDGE, NORTH_DOWN),
GBlockstate.variant(model_id, true, R0, R270))
.with(GBlockstate.when(EDGE, UP_NORTH),
GBlockstate.variant(model_id, true, R180, R270))
.with(GBlockstate.when(EDGE, SOUTH_UP),
GBlockstate.variant(model_id, true, R180, R90));
}
@Override
public void setRecipe(RecipeExporter exporter) {
RecipeProvider.offerStonecuttingRecipe(exporter, RecipeCategory.BUILDING_BLOCKS, this, ReFramed.CUBE, 4);
ShapedRecipeJsonBuilder
.create(RecipeCategory.BUILDING_BLOCKS, this, 8)
.pattern("II")
.input('I', ReFramed.CUBE)
.criterion(FabricRecipeProvider.hasItem(ReFramed.CUBE), FabricRecipeProvider.conditionsFromItem(ReFramed.CUBE))
.criterion(FabricRecipeProvider.hasItem(this), FabricRecipeProvider.conditionsFromItem(this))
.offerTo(exporter);
public Map<Integer, Integer> getThemeMap(BlockState state, BlockState new_state) {
if (new_state.isOf(ReFramed.STAIRS_CUBE)) return Map.of(1, 2);
if (new_state.isOf(ReFramed.STEPS_SLAB))
return Map.of(
1,
state.get(EDGE)
.getOtherDirection(new_state.get(FACING))
.getDirection() == Direction.AxisDirection.POSITIVE ? 2 : 1
);
return super.getThemeMap(state, new_state);
}
static {

View File

@@ -1,22 +1,12 @@
package fr.adrien1106.reframed.block;
import fr.adrien1106.reframed.ReFramed;
import fr.adrien1106.reframed.generator.BlockStateProvider;
import fr.adrien1106.reframed.generator.GBlockstate;
import fr.adrien1106.reframed.util.blocks.BlockHelper;
import fr.adrien1106.reframed.util.blocks.Edge;
import net.fabricmc.fabric.api.datagen.v1.provider.FabricRecipeProvider;
import net.minecraft.block.Block;
import net.minecraft.block.BlockState;
import net.minecraft.block.ShapeContext;
import net.minecraft.data.client.MultipartBlockStateSupplier;
import net.minecraft.data.server.recipe.RecipeExporter;
import net.minecraft.data.server.recipe.RecipeProvider;
import net.minecraft.data.server.recipe.ShapelessRecipeJsonBuilder;
import net.minecraft.item.ItemPlacementContext;
import net.minecraft.recipe.book.RecipeCategory;
import net.minecraft.state.StateManager;
import net.minecraft.util.Identifier;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.Direction;
import net.minecraft.util.math.Direction.Axis;
@@ -27,12 +17,11 @@ import org.jetbrains.annotations.Nullable;
import static fr.adrien1106.reframed.block.ReFramedSlabBlock.getSlabShape;
import static fr.adrien1106.reframed.block.ReFramedStepBlock.getStepShape;
import static net.minecraft.data.client.VariantSettings.Rotation.*;
import static net.minecraft.state.property.Properties.AXIS;
import static net.minecraft.state.property.Properties.FACING;
import static net.minecraft.util.shape.VoxelShapes.empty;
public class ReFramedStepsSlabBlock extends WaterloggableReFramedDoubleBlock implements BlockStateProvider {
public class ReFramedStepsSlabBlock extends WaterloggableReFramedDoubleBlock {
private record ModelCacheKey(Direction facing, Axis axis) {}
public ReFramedStepsSlabBlock(Settings settings) {
@@ -45,11 +34,6 @@ public class ReFramedStepsSlabBlock extends WaterloggableReFramedDoubleBlock imp
return new ModelCacheKey(state.get(FACING), state.get(AXIS));
}
@Override
public int getModelStateCount() {
return 18;
}
@Override
protected void appendProperties(StateManager.Builder<Block, BlockState> builder) {
super.appendProperties(builder.add(FACING, AXIS));
@@ -81,7 +65,7 @@ public class ReFramedStepsSlabBlock extends WaterloggableReFramedDoubleBlock imp
switch (axis) {
case X -> i == 1 ? Direction.WEST : Direction.EAST;
case Y -> i == 1 ? Direction.DOWN : Direction.UP;
case Z -> i == 1 ? Direction.SOUTH : Direction.NORTH;
case Z -> i == 1 ? Direction.NORTH : Direction.SOUTH;
}
));
}
@@ -90,47 +74,4 @@ public class ReFramedStepsSlabBlock extends WaterloggableReFramedDoubleBlock imp
public int getTopThemeIndex(BlockState state) {
return 2;
}
@Override
public MultipartBlockStateSupplier getMultipart() {
Identifier step_id = ReFramed.id("steps_slab_special");
Identifier step_side_id = ReFramed.id("steps_slab_side_special");
return MultipartBlockStateSupplier.create(this)
.with(GBlockstate.when(FACING, Direction.DOWN, AXIS, Axis.X),
GBlockstate.variant(step_id, true, R0, R180))
.with(GBlockstate.when(FACING, Direction.DOWN, AXIS, Axis.Z),
GBlockstate.variant(step_id, true, R0, R90))
.with(GBlockstate.when(FACING, Direction.UP, AXIS, Axis.X),
GBlockstate.variant(step_id, true, R180, R180))
.with(GBlockstate.when(FACING, Direction.UP, AXIS, Axis.Z),
GBlockstate.variant(step_id, true, R180, R90))
.with(GBlockstate.when(FACING, Direction.EAST, AXIS, Axis.Z),
GBlockstate.variant(step_side_id, true, R180, R0))
.with(GBlockstate.when(FACING, Direction.EAST, AXIS, Axis.Y),
GBlockstate.variant(step_side_id, true, R90, R0))
.with(GBlockstate.when(FACING, Direction.SOUTH, AXIS, Axis.X),
GBlockstate.variant(step_side_id, true, R180, R90))
.with(GBlockstate.when(FACING, Direction.SOUTH, AXIS, Axis.Y),
GBlockstate.variant(step_side_id, true, R90, R90))
.with(GBlockstate.when(FACING, Direction.WEST, AXIS, Axis.Z),
GBlockstate.variant(step_side_id, true, R0, R180))
.with(GBlockstate.when(FACING, Direction.WEST, AXIS, Axis.Y),
GBlockstate.variant(step_side_id, true, R90, R180))
.with(GBlockstate.when(FACING, Direction.NORTH, AXIS, Axis.X),
GBlockstate.variant(step_side_id, true, R0, R270))
.with(GBlockstate.when(FACING, Direction.NORTH, AXIS, Axis.Y),
GBlockstate.variant(step_side_id, true, R90, R270));
}
@Override
public void setRecipe(RecipeExporter exporter) {
RecipeProvider.offerStonecuttingRecipe(exporter, RecipeCategory.BUILDING_BLOCKS, this, ReFramed.CUBE, 2);
ShapelessRecipeJsonBuilder
.create(RecipeCategory.BUILDING_BLOCKS, this)
.input(ReFramed.STEP, 2)
.criterion(FabricRecipeProvider.hasItem(ReFramed.CUBE), FabricRecipeProvider.conditionsFromItem(ReFramed.CUBE))
.criterion(FabricRecipeProvider.hasItem(this), FabricRecipeProvider.conditionsFromItem(this))
.offerTo(exporter);
}
}

View File

@@ -0,0 +1,219 @@
package fr.adrien1106.reframed.block;
import fr.adrien1106.reframed.util.VoxelHelper;
import net.minecraft.block.*;
import net.minecraft.block.enums.WallShape;
import net.minecraft.item.ItemPlacementContext;
import net.minecraft.registry.tag.BlockTags;
import net.minecraft.state.StateManager;
import net.minecraft.state.property.Property;
import net.minecraft.util.function.BooleanBiFunction;
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 net.minecraft.world.WorldAccess;
import org.jetbrains.annotations.Nullable;
import java.util.stream.Stream;
import static net.minecraft.state.property.Properties.*;
public class ReframedWallBlock extends WaterloggableReFramedBlock {
public static final VoxelShape[] WALL_VOXELS;
private record ModelCacheKey(boolean up, WallShape east, WallShape north, WallShape west, WallShape south) {}
public ReframedWallBlock(Settings settings) {
super(settings);
setDefaultState(getDefaultState()
.with(UP, true)
.with(EAST_WALL_SHAPE, WallShape.NONE)
.with(NORTH_WALL_SHAPE, WallShape.NONE)
.with(WEST_WALL_SHAPE, WallShape.NONE)
.with(SOUTH_WALL_SHAPE, WallShape.NONE)
);
}
@Override
public Object getModelCacheKey(BlockState state) {
return new ModelCacheKey(
state.get(UP),
state.get(EAST_WALL_SHAPE),
state.get(NORTH_WALL_SHAPE),
state.get(WEST_WALL_SHAPE),
state.get(SOUTH_WALL_SHAPE)
);
}
@Override
protected void appendProperties(StateManager.Builder<Block, BlockState> builder) {
super.appendProperties(builder.add(UP, EAST_WALL_SHAPE, NORTH_WALL_SHAPE, SOUTH_WALL_SHAPE, WEST_WALL_SHAPE));
}
@Override
public BlockState getStateForNeighborUpdate(BlockState state, Direction dir, BlockState other_state, WorldAccess world, BlockPos pos, BlockPos moved) {
BlockState new_state = super.getStateForNeighborUpdate(state, dir, other_state, world, pos, moved);
if (dir == Direction.DOWN) return new_state;
BlockState top_state = dir == Direction.UP? other_state: world.getBlockState(pos.up());
boolean fs = top_state.isSideSolidFullSquare(world, pos.up(), Direction.DOWN);
VoxelShape top_shape = fs ? null : top_state.getCollisionShape(world, pos.up()).getFace(Direction.DOWN);
if (dir == Direction.UP) {
for (Direction d : Direction.Type.HORIZONTAL) {
Property<WallShape> wall_shape = getWallShape(d);
if (state.get(wall_shape) == WallShape.NONE) continue;
new_state = new_state.with(
wall_shape,
fs
|| (top_state.contains(wall_shape) && top_state.get(wall_shape) != WallShape.NONE)
|| shouldUseTall(WALL_VOXELS[dir.ordinal() + 3], top_shape)
? WallShape.TALL
: WallShape.LOW
);
}
return new_state.with(UP, shouldHavePost(new_state, top_state, top_shape));
}
boolean side_full = other_state.isSideSolidFullSquare(world, moved, dir.getOpposite());
if (shouldConnectTo(other_state, side_full, dir.getOpposite())) {
Property<WallShape> wall_shape = getWallShape(dir);
new_state = new_state.with(
wall_shape,
fs
|| (top_state.contains(wall_shape) && top_state.get(wall_shape) != WallShape.NONE)
|| shouldUseTall(WALL_VOXELS[dir.ordinal() + 3], top_shape)
? WallShape.TALL
: WallShape.LOW
);
} else new_state = new_state.with(getWallShape(dir), WallShape.NONE);
return new_state.with(UP, shouldHavePost(new_state, top_state, top_shape));
}
@Override
public @Nullable BlockState getPlacementState(ItemPlacementContext ctx) {
BlockState state = super.getPlacementState(ctx);
World world = ctx.getWorld();
BlockPos pos = ctx.getBlockPos();
BlockState top_state = world.getBlockState(pos.up());
boolean fs = top_state.isSideSolidFullSquare(world, pos.up(), Direction.DOWN);
VoxelShape top_shape = fs ? null : top_state.getCollisionShape(world, pos.up()).getFace(Direction.DOWN);
for (Direction dir : Direction.Type.HORIZONTAL) {
BlockPos offset = pos.offset(dir);
BlockState neighbor = world.getBlockState(offset);
boolean side_full = neighbor.isSideSolidFullSquare(world, offset, dir.getOpposite());
if (shouldConnectTo(neighbor, side_full, dir.getOpposite())) {
Property<WallShape> wall_shape = getWallShape(dir);
state = state.with(
wall_shape,
fs
|| (top_state.contains(wall_shape) && top_state.get(wall_shape) != WallShape.NONE)
|| shouldUseTall(WALL_VOXELS[dir.ordinal() + 3], top_shape)
? WallShape.TALL
: WallShape.LOW
);
}
}
return state.with(UP, shouldHavePost(state, top_state, top_shape));
}
@Override
public void onStateReplaced(BlockState state, World world, BlockPos pos, BlockState new_state, boolean moved) {
super.onStateReplaced(state, world, pos, new_state, moved);
if(!state.isOf(new_state.getBlock())) world.removeBlockEntity(pos);
}
@Override
public VoxelShape getOutlineShape(BlockState state, BlockView world, BlockPos pos, ShapeContext context) {
VoxelShape shape = state.get(UP) ? WALL_VOXELS[0]: VoxelShapes.empty();
for (Direction dir : Direction.Type.HORIZONTAL) {
WallShape wall_shape = state.get(getWallShape(dir));
if (wall_shape != WallShape.NONE)
shape = VoxelShapes.union(shape, WALL_VOXELS[1 + (wall_shape.ordinal()-1) * 4 + (dir.ordinal() - 2)]);
}
return shape;
}
@Override
public VoxelShape getCollisionShape(BlockState state, BlockView view, BlockPos pos, ShapeContext ctx) {
if (isGhost(view, pos)) return VoxelShapes.empty();
VoxelShape shape = state.get(UP) ? WALL_VOXELS[9]: VoxelShapes.empty();
for (Direction dir : Direction.Type.HORIZONTAL) {
if (state.get(getWallShape(dir)) != WallShape.NONE)
shape = VoxelShapes.union(shape, WALL_VOXELS[8 + dir.ordinal()]);
}
return shape;
}
private static boolean shouldHavePost(BlockState state, BlockState top_state, VoxelShape top_shape) {
// above has post
if (top_state.contains(NORTH_WALL_SHAPE) && top_state.get(UP)) return true;
if (Stream.of(Direction.SOUTH, Direction.EAST) // Opposites are different
.anyMatch(dir -> state.get(getWallShape(dir)) != state.get(getWallShape(dir.getOpposite())))
) return true;
// no sides
if (Direction.Type.HORIZONTAL.stream().allMatch(dir -> state.get(getWallShape(dir)) == WallShape.NONE))
return true;
// tall Matching sides
if (Stream.of(Direction.SOUTH, Direction.EAST)
.anyMatch(dir ->
state.get(getWallShape(dir)) == WallShape.TALL
&& state.get(getWallShape(dir.getOpposite())) == WallShape.TALL
)) return false;
return top_state.isIn(BlockTags.WALL_POST_OVERRIDE) || top_shape == null || shouldUseTall(WALL_VOXELS[0], top_shape);
}
private static boolean shouldConnectTo(BlockState state, boolean side_full, Direction side) {
Block block = state.getBlock();
boolean bl = block instanceof FenceGateBlock && FenceGateBlock.canWallConnect(state, side);
return state.isIn(BlockTags.WALLS) || !WallBlock.cannotConnect(state) && side_full || block instanceof PaneBlock || bl;
}
private static boolean shouldUseTall(VoxelShape self_shape, VoxelShape other_shape) {
return !VoxelShapes.matchesAnywhere(
self_shape,
other_shape,
BooleanBiFunction.ONLY_FIRST
);
}
private static Property<WallShape> getWallShape(Direction dir) {
return switch (dir) {
case EAST -> EAST_WALL_SHAPE;
case NORTH -> NORTH_WALL_SHAPE;
case WEST -> WEST_WALL_SHAPE;
case SOUTH -> SOUTH_WALL_SHAPE;
default -> null;
};
}
static {
VoxelShape POST = createCuboidShape(4, 0, 4, 12, 16, 12);
VoxelShape POST_COLLISION = createCuboidShape(4, 0, 4, 12, 24, 12);
VoxelShape LOW = createCuboidShape(5, 0, 0, 11, 14, 8);
VoxelShape TALL = createCuboidShape(5, 0, 0, 11, 16, 8);
VoxelShape SIDE_COLLISION = createCuboidShape(5, 0, 0, 11, 24, 8);
WALL_VOXELS = VoxelHelper.VoxelListBuilder.create(POST, 14)
.add(LOW)
.add(VoxelHelper::mirrorZ)
.add(VoxelHelper::rotateY)
.add(VoxelHelper::mirrorX)
.add(TALL)
.add(VoxelHelper::mirrorZ)
.add(VoxelHelper::rotateY)
.add(VoxelHelper::mirrorX)
.add(POST_COLLISION)
.add(SIDE_COLLISION)
.add(VoxelHelper::mirrorZ)
.add(VoxelHelper::rotateY)
.add(VoxelHelper::mirrorX)
.build();
}
}

View File

@@ -16,6 +16,7 @@ import org.jetbrains.annotations.Nullable;
public class WaterloggableReFramedDoubleBlock extends ReFramedDoubleBlock implements Waterloggable {
public WaterloggableReFramedDoubleBlock(Settings settings) {
super(settings);
setDefaultState(getDefaultState().with(Properties.WATERLOGGED, false));
}
@Override

View File

@@ -14,6 +14,10 @@ import net.minecraft.resource.ResourceType;
import net.minecraft.util.Identifier;
import net.minecraft.util.math.ChunkSectionPos;
import static fr.adrien1106.reframed.util.blocks.BlockProperties.*;
import static fr.adrien1106.reframed.util.blocks.BlockProperties.STAIR_SHAPE;
import static net.minecraft.state.property.Properties.*;
public class ReFramedClient implements ClientModInitializer {
public static final ReFramedModelProvider PROVIDER = new ReFramedModelProvider();
@@ -27,67 +31,110 @@ public class ReFramedClient implements ClientModInitializer {
BlockRenderLayerMap.INSTANCE.putBlocks(RenderLayer.getCutout(), ReFramed.BLOCKS.toArray(new Block[0]));
// CUBE
HELPER.addReFramedModel("cube_special" , HELPER.auto(new Identifier("block/cube")));
HELPER.addReFramedModel("cube" , HELPER.auto(new Identifier("block/cube"), 2));
// SMALL_CUBE
HELPER.addReFramedModel("small_cube_special" , HELPER.auto(ReFramed.id("block/small_cube/base")));
HELPER.addReFramedModel("small_cube" , HELPER.auto(ReFramed.id("block/small_cube/base"), 9, CORNER));
// SMALL_CUBES_STEP
HELPER.addReFramedModel("small_cubes_step_special" , HELPER.autoDouble(ReFramed.id("block/small_cube/base"), ReFramed.id("block/small_cube/step/base")));
HELPER.addReFramedModel("small_cubes_step_reverse_special" , HELPER.autoDouble(ReFramed.id("block/small_cube/step/base"), ReFramed.id("block/small_cube/base")));
HELPER.addReFramedModel("small_cubes_step" , HELPER.autoDouble(ReFramed.id("block/small_cube/base"), ReFramed.id("block/small_cube/step/base"), 9, EDGE));
HELPER.addReFramedModel("small_cubes_step_reverse" , HELPER.autoDouble(ReFramed.id("block/small_cube/step/base"), ReFramed.id("block/small_cube/base"), 4, EDGE));
// SLAB
HELPER.addReFramedModel("slab_special" , HELPER.auto(new Identifier("block/slab")));
HELPER.addReFramedModel("slab" , HELPER.auto(new Identifier("block/slab"), 7, FACING));
// SLAB_CUBE
HELPER.addReFramedModel("double_slab_special" , HELPER.autoDouble(new Identifier("block/slab"), new Identifier("block/slab_top")));
HELPER.addReFramedModel("double_slab" , HELPER.autoDouble(new Identifier("block/slab"), new Identifier("block/slab_top"), 4, AXIS));
// STAIR
HELPER.addReFramedModel("stair_special" , HELPER.auto(ReFramed.id("block/stair/straight")));
HELPER.addReFramedModel("outers_stair_special" , HELPER.auto(ReFramed.id("block/stair/double_outer")));
HELPER.addReFramedModel("inner_stair_special" , HELPER.auto(ReFramed.id("block/stair/inner")));
HELPER.addReFramedModel("outer_stair_special" , HELPER.auto(ReFramed.id("block/stair/outer")));
HELPER.addReFramedModel("outer_side_stair_special" , HELPER.auto(ReFramed.id("block/stair/outer_side")));
HELPER.addReFramedModel("stair" , HELPER.auto(ReFramed.id("block/stair/straight"), 13, EDGE));
HELPER.addReFramedModel("outers_stair" , HELPER.auto(ReFramed.id("block/stair/double_outer"), 24, EDGE, STAIR_SHAPE));
HELPER.addReFramedModel("inner_stair" , HELPER.auto(ReFramed.id("block/stair/inner"), 24, EDGE, STAIR_SHAPE));
HELPER.addReFramedModel("outer_stair" , HELPER.auto(ReFramed.id("block/stair/outer"), 16, EDGE, STAIR_SHAPE));
HELPER.addReFramedModel("outer_side_stair" , HELPER.auto(ReFramed.id("block/stair/outer_side"), 32, EDGE, STAIR_SHAPE));
// STAIRS_CUBE
HELPER.addReFramedModel("stairs_cube_special" , HELPER.autoDouble(ReFramed.id("block/stair/straight"), ReFramed.id("block/stair/cube/straight")));
HELPER.addReFramedModel("outers_stairs_cube_special" , HELPER.autoDouble(ReFramed.id("block/stair/double_outer"), ReFramed.id("block/stair/cube/double_outer")));
HELPER.addReFramedModel("inner_stairs_cube_special" , HELPER.autoDouble(ReFramed.id("block/stair/inner"), ReFramed.id("block/stair/cube/inner")));
HELPER.addReFramedModel("outer_stairs_cube_special" , HELPER.autoDouble(ReFramed.id("block/stair/outer"), ReFramed.id("block/stair/cube/outer")));
HELPER.addReFramedModel("outer_side_stairs_cube_special" , HELPER.autoDouble(ReFramed.id("block/stair/outer_side"), ReFramed.id("block/stair/cube/outer_side")));
HELPER.addReFramedModel("stairs_cube" , HELPER.autoDouble(ReFramed.id("block/stair/straight"), ReFramed.id("block/stair/cube/straight"), 13, EDGE));
HELPER.addReFramedModel("outers_stairs_cube" , HELPER.autoDouble(ReFramed.id("block/stair/double_outer"), ReFramed.id("block/stair/cube/double_outer"), 24, EDGE, STAIR_SHAPE));
HELPER.addReFramedModel("inner_stairs_cube" , HELPER.autoDouble(ReFramed.id("block/stair/inner"), ReFramed.id("block/stair/cube/inner"), 24, EDGE, STAIR_SHAPE));
HELPER.addReFramedModel("outer_stairs_cube" , HELPER.autoDouble(ReFramed.id("block/stair/outer"), ReFramed.id("block/stair/cube/outer"), 16, EDGE, STAIR_SHAPE));
HELPER.addReFramedModel("outer_side_stairs_cube" , HELPER.autoDouble(ReFramed.id("block/stair/outer_side"), ReFramed.id("block/stair/cube/outer_side"), 32, EDGE, STAIR_SHAPE));
// HALF_STAIR
HELPER.addReFramedModel("half_stair_down_special" , HELPER.auto(ReFramed.id("block/half_stair/down")));
HELPER.addReFramedModel("half_stair_side_special" , HELPER.auto(ReFramed.id("block/half_stair/side")));
HELPER.addReFramedModel("half_stair_down" , HELPER.auto(ReFramed.id("block/half_stair/down"), 9, CORNER, CORNER_FACE));
HELPER.addReFramedModel("half_stair_side" , HELPER.auto(ReFramed.id("block/half_stair/side"), 16, CORNER, CORNER_FACE));
// HALF_STAIRS_SLAB
HELPER.addReFramedModel("half_stairs_slab_down_special" , HELPER.autoDouble(ReFramed.id("block/half_stair/down"), ReFramed.id("block/half_stair/slab/down")));
HELPER.addReFramedModel("half_stairs_slab_side_special" , HELPER.autoDouble(ReFramed.id("block/half_stair/side"), ReFramed.id("block/half_stair/slab/side")));
HELPER.addReFramedModel("half_stairs_slab_down" , HELPER.autoDouble(ReFramed.id("block/half_stair/down"), ReFramed.id("block/half_stair/slab/down"), 9, CORNER, CORNER_FACE));
HELPER.addReFramedModel("half_stairs_slab_side" , HELPER.autoDouble(ReFramed.id("block/half_stair/side"), ReFramed.id("block/half_stair/slab/side"), 16, CORNER, CORNER_FACE));
// HALF_STAIRS_STAIR
HELPER.addReFramedModel("half_stairs_stair_down_special" , HELPER.autoDouble(ReFramed.id("block/half_stair/down"), ReFramed.id("block/half_stair/stair/down")));
HELPER.addReFramedModel("half_stairs_stair_side_special" , HELPER.autoDouble(ReFramed.id("block/half_stair/side"), ReFramed.id("block/half_stair/stair/side")));
HELPER.addReFramedModel("half_stairs_stair_reverse_special" , HELPER.autoDouble(ReFramed.id("block/half_stair/stair/side"), ReFramed.id("block/half_stair/side")));
HELPER.addReFramedModel("half_stairs_stair_down" , HELPER.autoDouble(ReFramed.id("block/half_stair/down"), ReFramed.id("block/half_stair/stair/down"), 5, EDGE));
HELPER.addReFramedModel("half_stairs_stair_side" , HELPER.autoDouble(ReFramed.id("block/half_stair/side"), ReFramed.id("block/half_stair/stair/side"), 6, EDGE));
HELPER.addReFramedModel("half_stairs_stair_reverse" , HELPER.autoDouble(ReFramed.id("block/half_stair/stair/side"), ReFramed.id("block/half_stair/side"), 2, EDGE));
// STEP
HELPER.addReFramedModel("step_special" , HELPER.auto(ReFramed.id("block/step/down")));
HELPER.addReFramedModel("step" , HELPER.auto(ReFramed.id("block/step/down"), 13, EDGE));
// STEPS_SLAB
HELPER.addReFramedModel("steps_slab_special" , HELPER.autoDouble(ReFramed.id("block/step/down"), ReFramed.id("block/step/slab/down")));
HELPER.addReFramedModel("steps_slab_side_special" , HELPER.autoDouble(ReFramed.id("block/step/side"), ReFramed.id("block/step/slab/side")));
HELPER.addReFramedModel("steps_slab" , HELPER.autoDouble(ReFramed.id("block/step/down"), ReFramed.id("block/step/slab/down"), 5, FACING, AXIS));
HELPER.addReFramedModel("steps_slab_side" , HELPER.autoDouble(ReFramed.id("block/step/side"), ReFramed.id("block/step/slab/side"), 8, FACING, AXIS));
// LAYER
HELPER.addReFramedModel("layer_1_special" , HELPER.auto(new Identifier("block/snow_height2")));
HELPER.addReFramedModel("layer_2_special" , HELPER.auto(new Identifier("block/snow_height4")));
HELPER.addReFramedModel("layer_3_special" , HELPER.auto(new Identifier("block/snow_height6")));
HELPER.addReFramedModel("layer_4_special" , HELPER.auto(new Identifier("block/snow_height8")));
HELPER.addReFramedModel("layer_5_special" , HELPER.auto(new Identifier("block/snow_height10")));
HELPER.addReFramedModel("layer_6_special" , HELPER.auto(new Identifier("block/snow_height12")));
HELPER.addReFramedModel("layer_7_special" , HELPER.auto(new Identifier("block/snow_height14")));
HELPER.addReFramedModel("layer_8_special" , HELPER.auto(new Identifier("block/cube")));
HELPER.addReFramedModel("layer_1" , HELPER.auto(new Identifier("block/snow_height2"), 7, FACING));
HELPER.addReFramedModel("layer_2" , HELPER.auto(new Identifier("block/snow_height4"), 6, FACING));
HELPER.addReFramedModel("layer_3" , HELPER.auto(new Identifier("block/snow_height6"), 6, FACING));
HELPER.addReFramedModel("layer_4" , HELPER.auto(new Identifier("block/snow_height8"), 6, FACING));
HELPER.addReFramedModel("layer_5" , HELPER.auto(new Identifier("block/snow_height10"), 6, FACING));
HELPER.addReFramedModel("layer_6" , HELPER.auto(new Identifier("block/snow_height12"), 6, FACING));
HELPER.addReFramedModel("layer_7" , HELPER.auto(new Identifier("block/snow_height14"), 6, FACING));
HELPER.addReFramedModel("layer_8" , HELPER.auto(new Identifier("block/cube"), 1));
// PILLAR
HELPER.addReFramedModel("pillar" , HELPER.auto(ReFramed.id("block/pillar"), 4, AXIS));
// WALL
HELPER.addReFramedModel("wall_inventory" , HELPER.auto(ReFramed.id("block/wall/inventory/default"), 1));
// --------------------- pillar
HELPER.addReFramedModel("wall_core" , HELPER.auto(ReFramed.id("block/wall/pillar/core"), 1, UP));
HELPER.addReFramedModel("wall_pillar_low" , HELPER.auto(ReFramed.id("block/wall/pillar/low"), 4, NORTH_WALL_SHAPE, EAST_WALL_SHAPE, SOUTH_WALL_SHAPE, WEST_WALL_SHAPE));
HELPER.addReFramedModel("wall_pillar_tall" , HELPER.auto(ReFramed.id("block/wall/pillar/tall"), 4, NORTH_WALL_SHAPE, EAST_WALL_SHAPE, SOUTH_WALL_SHAPE, WEST_WALL_SHAPE));
HELPER.addReFramedModel("wall_pillar_none" , HELPER.auto(ReFramed.id("block/wall/pillar/none"), 4, NORTH_WALL_SHAPE, EAST_WALL_SHAPE, SOUTH_WALL_SHAPE, WEST_WALL_SHAPE));
// --------------------- side
HELPER.addReFramedModel("wall_side_low" , HELPER.auto(ReFramed.id("block/wall/side/low"), 92, NORTH_WALL_SHAPE, EAST_WALL_SHAPE, SOUTH_WALL_SHAPE, WEST_WALL_SHAPE));
HELPER.addReFramedModel("wall_side_tall" , HELPER.auto(ReFramed.id("block/wall/side/tall"), 92, NORTH_WALL_SHAPE, EAST_WALL_SHAPE, SOUTH_WALL_SHAPE, WEST_WALL_SHAPE));
// --------------------- junction
HELPER.addReFramedModel("wall_low_e" , HELPER.auto(ReFramed.id("block/wall/junction/low"), 4, NORTH_WALL_SHAPE, EAST_WALL_SHAPE, SOUTH_WALL_SHAPE, WEST_WALL_SHAPE));
HELPER.addReFramedModel("wall_tall_e" , HELPER.auto(ReFramed.id("block/wall/junction/tall"), 4, NORTH_WALL_SHAPE, EAST_WALL_SHAPE, SOUTH_WALL_SHAPE, WEST_WALL_SHAPE));
// --------------------- junction_i
HELPER.addReFramedModel("wall_low_i" , HELPER.auto(ReFramed.id("block/wall/junction/low_i"), 4, NORTH_WALL_SHAPE, EAST_WALL_SHAPE, SOUTH_WALL_SHAPE, WEST_WALL_SHAPE));
HELPER.addReFramedModel("wall_tall_i" , HELPER.auto(ReFramed.id("block/wall/junction/tall_i"), 4, NORTH_WALL_SHAPE, EAST_WALL_SHAPE, SOUTH_WALL_SHAPE, WEST_WALL_SHAPE));
HELPER.addReFramedModel("wall_low_tall_i" , HELPER.auto(ReFramed.id("block/wall/junction/low_tall_i"), 4, NORTH_WALL_SHAPE, EAST_WALL_SHAPE, SOUTH_WALL_SHAPE, WEST_WALL_SHAPE));
// --------------------- junction_c
HELPER.addReFramedModel("wall_low_c" , HELPER.auto(ReFramed.id("block/wall/junction/low_c"), 4, NORTH_WALL_SHAPE, EAST_WALL_SHAPE, SOUTH_WALL_SHAPE, WEST_WALL_SHAPE));
HELPER.addReFramedModel("wall_tall_c" , HELPER.auto(ReFramed.id("block/wall/junction/tall_c"), 4, NORTH_WALL_SHAPE, EAST_WALL_SHAPE, SOUTH_WALL_SHAPE, WEST_WALL_SHAPE));
HELPER.addReFramedModel("wall_low_tall_c" , HELPER.auto(ReFramed.id("block/wall/junction/low_tall_c"), 4, NORTH_WALL_SHAPE, EAST_WALL_SHAPE, SOUTH_WALL_SHAPE, WEST_WALL_SHAPE));
HELPER.addReFramedModel("wall_tall_low_c" , HELPER.auto(ReFramed.id("block/wall/junction/tall_low_c"), 4, NORTH_WALL_SHAPE, EAST_WALL_SHAPE, SOUTH_WALL_SHAPE, WEST_WALL_SHAPE));
// --------------------- junction_t
HELPER.addReFramedModel("wall_low_t" , HELPER.auto(ReFramed.id("block/wall/junction/low_t"), 4, NORTH_WALL_SHAPE, EAST_WALL_SHAPE, SOUTH_WALL_SHAPE, WEST_WALL_SHAPE));
HELPER.addReFramedModel("wall_tall_t" , HELPER.auto(ReFramed.id("block/wall/junction/tall_t"), 4, NORTH_WALL_SHAPE, EAST_WALL_SHAPE, SOUTH_WALL_SHAPE, WEST_WALL_SHAPE));
HELPER.addReFramedModel("wall_tall_low_c_t" , HELPER.auto(ReFramed.id("block/wall/junction/tall_low_c_t"), 4, NORTH_WALL_SHAPE, EAST_WALL_SHAPE, SOUTH_WALL_SHAPE, WEST_WALL_SHAPE));
HELPER.addReFramedModel("wall_tall_i_low_t" , HELPER.auto(ReFramed.id("block/wall/junction/tall_i_low_t"), 4, NORTH_WALL_SHAPE, EAST_WALL_SHAPE, SOUTH_WALL_SHAPE, WEST_WALL_SHAPE));
HELPER.addReFramedModel("wall_low_i_tall_t" , HELPER.auto(ReFramed.id("block/wall/junction/low_i_tall_t"), 4, NORTH_WALL_SHAPE, EAST_WALL_SHAPE, SOUTH_WALL_SHAPE, WEST_WALL_SHAPE));
HELPER.addReFramedModel("wall_low_tall_c_t" , HELPER.auto(ReFramed.id("block/wall/junction/low_tall_c_t"), 4, NORTH_WALL_SHAPE, EAST_WALL_SHAPE, SOUTH_WALL_SHAPE, WEST_WALL_SHAPE));
HELPER.addReFramedModel("wall_low_c_tall_t" , HELPER.auto(ReFramed.id("block/wall/junction/low_c_tall_t"), 4, NORTH_WALL_SHAPE, EAST_WALL_SHAPE, SOUTH_WALL_SHAPE, WEST_WALL_SHAPE));
HELPER.addReFramedModel("wall_tall_c_low_t" , HELPER.auto(ReFramed.id("block/wall/junction/tall_c_low_t"), 4, NORTH_WALL_SHAPE, EAST_WALL_SHAPE, SOUTH_WALL_SHAPE, WEST_WALL_SHAPE));
// --------------------- junction_x
HELPER.addReFramedModel("wall_low_x" , HELPER.auto(ReFramed.id("block/wall/junction/low_x"), 4, NORTH_WALL_SHAPE, EAST_WALL_SHAPE, SOUTH_WALL_SHAPE, WEST_WALL_SHAPE));
HELPER.addReFramedModel("wall_tall_x" , HELPER.auto(ReFramed.id("block/wall/junction/tall_x"), 4, NORTH_WALL_SHAPE, EAST_WALL_SHAPE, SOUTH_WALL_SHAPE, WEST_WALL_SHAPE));
HELPER.addReFramedModel("wall_tall_i_low_i_x" , HELPER.auto(ReFramed.id("block/wall/junction/tall_i_low_i_x"), 4, NORTH_WALL_SHAPE, EAST_WALL_SHAPE, SOUTH_WALL_SHAPE, WEST_WALL_SHAPE));
HELPER.addReFramedModel("wall_tall_low_t_x" , HELPER.auto(ReFramed.id("block/wall/junction/tall_low_t_x"), 4, NORTH_WALL_SHAPE, EAST_WALL_SHAPE, SOUTH_WALL_SHAPE, WEST_WALL_SHAPE));
HELPER.addReFramedModel("wall_tall_c_low_c_x" , HELPER.auto(ReFramed.id("block/wall/junction/tall_c_low_c_x"), 4, NORTH_WALL_SHAPE, EAST_WALL_SHAPE, SOUTH_WALL_SHAPE, WEST_WALL_SHAPE));
HELPER.addReFramedModel("wall_tall_t_low_x" , HELPER.auto(ReFramed.id("block/wall/junction/tall_t_low_x"), 4, NORTH_WALL_SHAPE, EAST_WALL_SHAPE, SOUTH_WALL_SHAPE, WEST_WALL_SHAPE));
//item model assignments (in lieu of models/item/___.json)
HELPER.assignItemModel("cube_special" , ReFramed.CUBE);
HELPER.assignItemModel("small_cube_special" , ReFramed.SMALL_CUBE);
HELPER.assignItemModel("small_cubes_step_special" , ReFramed.SMALL_CUBES_STEP);
HELPER.assignItemModel("slab_special" , ReFramed.SLAB);
HELPER.assignItemModel("double_slab_special" , ReFramed.SLABS_CUBE);
HELPER.assignItemModel("stair_special" , ReFramed.STAIR);
HELPER.assignItemModel("stairs_cube_special" , ReFramed.STAIRS_CUBE);
HELPER.assignItemModel("half_stair_down_special" , ReFramed.HALF_STAIR);
HELPER.assignItemModel("half_stairs_slab_down_special" , ReFramed.HALF_STAIRS_SLAB);
HELPER.assignItemModel("half_stairs_stair_down_special", ReFramed.HALF_STAIRS_STAIR);
HELPER.assignItemModel("step_special" , ReFramed.STEP);
HELPER.assignItemModel("steps_slab_special" , ReFramed.STEPS_SLAB);
HELPER.assignItemModel("layer_1_special" , ReFramed.LAYER);
HELPER.assignItemModel("cube" , ReFramed.CUBE);
HELPER.assignItemModel("small_cube" , ReFramed.SMALL_CUBE);
HELPER.assignItemModel("small_cubes_step" , ReFramed.SMALL_CUBES_STEP);
HELPER.assignItemModel("slab" , ReFramed.SLAB);
HELPER.assignItemModel("double_slab" , ReFramed.SLABS_CUBE);
HELPER.assignItemModel("stair" , ReFramed.STAIR);
HELPER.assignItemModel("stairs_cube" , ReFramed.STAIRS_CUBE);
HELPER.assignItemModel("half_stair_down" , ReFramed.HALF_STAIR);
HELPER.assignItemModel("half_stairs_slab_down" , ReFramed.HALF_STAIRS_SLAB);
HELPER.assignItemModel("half_stairs_stair_down", ReFramed.HALF_STAIRS_STAIR);
HELPER.assignItemModel("step" , ReFramed.STEP);
HELPER.assignItemModel("steps_slab" , ReFramed.STEPS_SLAB);
HELPER.assignItemModel("layer_1" , ReFramed.LAYER);
HELPER.assignItemModel("pillar" , ReFramed.PILLAR);
HELPER.assignItemModel("wall_inventory" , ReFramed.WALL);
}
private void privateInit() {

View File

@@ -13,6 +13,7 @@ import net.minecraft.client.render.model.UnbakedModel;
import net.minecraft.client.texture.Sprite;
import net.minecraft.client.util.SpriteIdentifier;
import net.minecraft.item.ItemConvertible;
import net.minecraft.state.property.Property;
import net.minecraft.util.Identifier;
import org.jetbrains.annotations.NotNull;
@@ -27,28 +28,31 @@ public class ReFramedClientHelper {
private final ReFramedModelProvider prov;
public UnbakedRetexturedModel auto(Identifier parent) {
return new UnbakedAutoRetexturedModel(parent);
public UnbakedRetexturedModel auto(Identifier parent, int model_count, Property<?>... properties) {
return new UnbakedAutoRetexturedModel(parent, model_count, properties);
}
public UnbakedRetexturedModel json(Identifier parent) {
return new UnbakedJsonRetexturedModel(parent);
public UnbakedRetexturedModel json(Identifier parent, int model_count, Property<?>... properties) {
return new UnbakedJsonRetexturedModel(parent, model_count, properties);
}
public UnbakedModel autoDouble(Identifier first, Identifier second) {
return new UnbakedDoubleRetexturedModel(auto(first), auto(second));
public UnbakedModel autoDouble(Identifier first, Identifier second, int model_count, Property<?>... properties) {
return new UnbakedDoubleRetexturedModel(
auto(first, model_count, properties),
auto(second, model_count, properties)
);
}
public void addReFramedModel(String id, UnbakedModel unbaked) {
prov.addReFramedModel(ReFramed.id(id), unbaked);
prov.addReFramedModel(ReFramed.id(id + "_special"), unbaked);
}
public void assignItemModel(String id, ItemConvertible... item_convertibles) {
prov.assignItemModel(ReFramed.id(id), item_convertibles);
prov.assignItemModel(ReFramed.id(id + "_special"), item_convertibles);
}
public CamoAppearanceManager getCamoApperanceManager(Function<SpriteIdentifier, Sprite> spriteLookup) {
return prov.getCamoApperanceManager(spriteLookup);
public CamoAppearanceManager getCamoAppearanceManager(Function<SpriteIdentifier, Sprite> spriteLookup) {
return prov.getCamoAppearanceManager(spriteLookup);
}
public @NotNull Renderer getFabricRenderer() {

View File

@@ -44,7 +44,7 @@ public class ReFramedModelProvider implements ModelResourceProvider, ModelVarian
/// camo appearance manager cache
public CamoAppearanceManager getCamoApperanceManager(Function<SpriteIdentifier, Sprite> spriteLookup) {
public CamoAppearanceManager getCamoAppearanceManager(Function<SpriteIdentifier, Sprite> spriteLookup) {
//This is kind of needlessly sketchy using the "volatile double checked locking" pattern.
//I'd like all frame models to use the same CamoApperanceManager, despite the model
//baking process happening concurrently on several threads, but I also don't want to

View File

@@ -1,6 +1,7 @@
package fr.adrien1106.reframed.client.model;
import fr.adrien1106.reframed.block.ReFramedBlock;
import com.google.common.cache.Cache;
import com.google.common.cache.CacheBuilder;
import fr.adrien1106.reframed.block.ReFramedEntity;
import fr.adrien1106.reframed.client.ReFramedClient;
import fr.adrien1106.reframed.mixin.MinecraftAccessor;
@@ -19,27 +20,28 @@ import net.minecraft.client.render.model.BakedModel;
import net.minecraft.client.render.model.ModelBakeSettings;
import net.minecraft.client.texture.Sprite;
import net.minecraft.item.ItemStack;
import net.minecraft.state.property.Property;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.Direction;
import net.minecraft.util.math.random.Random;
import net.minecraft.world.BlockRenderView;
import java.util.List;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.function.Supplier;
import java.util.stream.Stream;
public abstract class RetexturingBakedModel extends ForwardingBakedModel {
public RetexturingBakedModel(BakedModel base_model, CamoAppearanceManager tam, int theme_index, ModelBakeSettings settings, BlockState item_state, boolean ao) {
public RetexturingBakedModel(BakedModel base_model, CamoAppearanceManager tam, int theme_index, ModelBakeSettings settings, BlockState item_state, int model_count, Property<?>... properties) {
this.wrapped = base_model; //field from the superclass; vanilla getQuads etc. will delegate through to this
this.appearance_manager = tam;
this.theme_index = theme_index;
this.uv_lock = settings.isUvLocked();
this.item_state = item_state;
this.ao = ao;
this.properties = properties;
int cache_size = 64; // default is 64 why don't ask me and it should get overwritten
if (item_state.getBlock() instanceof ReFramedBlock frame_block) cache_size = frame_block.getModelStateCount() + 1;
BASE_MESH_CACHE = new Object2ObjectLinkedOpenHashMap<>(cache_size, 0.25f) {
BASE_MESH_CACHE = new Object2ObjectLinkedOpenHashMap<>(model_count, 0.25f) {
@Override
protected void rehash(int v) {}
};
@@ -48,16 +50,13 @@ public abstract class RetexturingBakedModel extends ForwardingBakedModel {
protected final CamoAppearanceManager appearance_manager;
protected final int theme_index;
protected final boolean uv_lock;
protected final boolean ao;
protected final BlockState item_state;
protected final Property<?>[] properties;
protected record MeshCacheKey(Object state_key, CamoAppearance appearance, int model_id) {}
/** cache that store retextured models */
protected final Object2ObjectLinkedOpenHashMap<MeshCacheKey, Mesh> RETEXTURED_MESH_CACHE =
new Object2ObjectLinkedOpenHashMap<>(128, 0.25f) {
@Override
protected void rehash(int v) {}
};
// self culling cache of the models not made thread local so that it is only computed once
protected final Cache<MeshCacheKey, Mesh> RETEXTURED_MESH_CACHE = CacheBuilder.newBuilder().maximumSize(256).build();
/** cache that stores the base meshes which has the size of the amount of models */
protected final Object2ObjectLinkedOpenHashMap<Object, Mesh> BASE_MESH_CACHE;
@@ -91,14 +90,13 @@ public abstract class RetexturingBakedModel extends ForwardingBakedModel {
@Override
public void emitBlockQuads(BlockRenderView world, BlockState state, BlockPos pos, Supplier<Random> randomSupplier, RenderContext context) {
// skip render if block not a frame (which should always be the case
if (!(state.getBlock() instanceof ReFramedBlock frame_block)) return;
BlockState theme = (world.getBlockEntity(pos) instanceof ThemeableBlockEntity s) ? s.getTheme(theme_index) : null;
QuadEmitter quad_emitter = context.getEmitter();
List<?> model_key = Stream.of(properties).map(state::get).toList();
if(theme == null || theme.isAir()) {
getRetexturedMesh(
new MeshCacheKey(
frame_block.getModelCacheKey(state),
model_key,
appearance_manager.getDefaultAppearance(theme_index),
0
),
@@ -114,7 +112,9 @@ public abstract class RetexturingBakedModel extends ForwardingBakedModel {
if (camo instanceof WeightedComputedAppearance wca) model_id = wca.getAppearanceIndex(seed);
int tint = 0xFF000000 | MinecraftClient.getInstance().getBlockColors().getColor(theme, world, pos, 0);
Mesh untintedMesh = getRetexturedMesh(new MeshCacheKey(frame_block.getModelCacheKey(state), camo, model_id), state);
MeshCacheKey key = new MeshCacheKey(model_key, camo, model_id);
// do not clutter the cache with single-use meshes
Mesh untintedMesh = camo.hashCode() == -1 ? transformMesh(key, state) : getRetexturedMesh(key, state);
//The specific tint might vary a lot; imagine grass color smoothly changing. Trying to bake the tint into
//the cached mesh will pollute it with a ton of single-use meshes with only slightly different colors.
@@ -155,9 +155,9 @@ public abstract class RetexturingBakedModel extends ForwardingBakedModel {
}
protected Mesh getRetexturedMesh(MeshCacheKey key, BlockState state) {
if (RETEXTURED_MESH_CACHE.containsKey(key)) return RETEXTURED_MESH_CACHE.getAndMoveToFirst(key);
if (RETEXTURED_MESH_CACHE.asMap().containsKey(key)) return RETEXTURED_MESH_CACHE.getIfPresent(key);
Mesh mesh = transformMesh(key, state);
RETEXTURED_MESH_CACHE.putAndMoveToFirst(key, mesh);
RETEXTURED_MESH_CACHE.put(key, mesh);
return mesh;
}
@@ -170,7 +170,7 @@ public abstract class RetexturingBakedModel extends ForwardingBakedModel {
int i = -1;
do {
emitter.copyFrom(quad);
i = key.appearance.transformQuad(emitter, i, quad_index.get(), key.model_id, ao, uv_lock);
i = key.appearance.transformQuad(emitter, i, quad_index.get(), key.model_id, uv_lock);
} while (i > 0);
// kinda weird to do it like that but other directions don't use the quad_index so it doesn't matter
if (quad.cullFace() == null) quad_index.getAndIncrement();

View File

@@ -14,6 +14,7 @@ import net.minecraft.client.render.model.Baker;
import net.minecraft.client.render.model.ModelBakeSettings;
import net.minecraft.client.texture.Sprite;
import net.minecraft.client.util.SpriteIdentifier;
import net.minecraft.state.property.Property;
import net.minecraft.util.Identifier;
import net.minecraft.util.math.Direction;
import net.minecraft.util.math.random.Random;
@@ -23,8 +24,8 @@ import java.util.function.Function;
public class UnbakedAutoRetexturedModel extends UnbakedRetexturedModel {
public UnbakedAutoRetexturedModel(Identifier parent) {
super(parent);
public UnbakedAutoRetexturedModel(Identifier parent, int state_count, Property<?>... properties) {
super(parent, state_count, properties);
item_state = Blocks.AIR.getDefaultState();
}
@@ -33,11 +34,12 @@ public class UnbakedAutoRetexturedModel extends UnbakedRetexturedModel {
public BakedModel bake(Baker baker, Function<SpriteIdentifier, Sprite> texture_getter, ModelBakeSettings bake_settings, Identifier identifier) {
return new RetexturingBakedModel(
baker.bake(parent, bake_settings),
ReFramedClient.HELPER.getCamoApperanceManager(texture_getter),
ReFramedClient.HELPER.getCamoAppearanceManager(texture_getter),
theme_index,
bake_settings,
item_state,
ao
state_count,
properties
) {
protected Mesh convertModel(BlockState state) {
Renderer r = ReFramedClient.HELPER.getFabricRenderer();

View File

@@ -15,6 +15,7 @@ import net.minecraft.client.render.model.ModelBakeSettings;
import net.minecraft.client.texture.Sprite;
import net.minecraft.client.util.SpriteIdentifier;
import net.minecraft.screen.PlayerScreenHandler;
import net.minecraft.state.property.Property;
import net.minecraft.util.Identifier;
import net.minecraft.util.math.Direction;
import net.minecraft.util.math.random.Random;
@@ -24,8 +25,8 @@ import java.util.Objects;
import java.util.function.Function;
public class UnbakedJsonRetexturedModel extends UnbakedRetexturedModel {
public UnbakedJsonRetexturedModel(Identifier parent) {
super(parent);
public UnbakedJsonRetexturedModel(Identifier parent, int state_count, Property<?>... properties) {
super(parent, state_count, properties);
}
@Nullable
@@ -41,11 +42,12 @@ public class UnbakedJsonRetexturedModel extends UnbakedRetexturedModel {
return new RetexturingBakedModel(
baker.bake(parent, bake_settings),
ReFramedClient.HELPER.getCamoApperanceManager(spriteLookup),
ReFramedClient.HELPER.getCamoAppearanceManager(spriteLookup),
theme_index,
bake_settings,
item_state,
ao
state_count,
properties
) {
protected Mesh convertModel(BlockState state) {
Renderer r = ReFramedClient.HELPER.getFabricRenderer();

View File

@@ -2,6 +2,7 @@ package fr.adrien1106.reframed.client.model;
import net.minecraft.block.BlockState;
import net.minecraft.client.render.model.UnbakedModel;
import net.minecraft.state.property.Property;
import net.minecraft.util.Identifier;
import java.util.Collection;
@@ -14,14 +15,18 @@ public abstract class UnbakedRetexturedModel implements UnbakedModel {
protected int theme_index = 1;
protected BlockState item_state;
protected final boolean ao = true;
protected final int state_count;
protected final Property<?>[] properties;
public UnbakedRetexturedModel(Identifier parent) {
public UnbakedRetexturedModel(Identifier parent, int state_count, Property<?>... properties) {
this.parent = parent;
this.state_count = state_count;
this.properties = properties;
}
public void setThemeIndex(int theme_index) {
public UnbakedRetexturedModel setThemeIndex(int theme_index) {
this.theme_index = theme_index;
return this;
}
@Override

View File

@@ -5,4 +5,4 @@ import net.minecraft.util.math.Direction;
import java.util.List;
import java.util.Map;
public record Appearance(Map<Direction, List<SpriteProperties>> sprites) {}
public record Appearance(Map<Direction, List<SpriteProperties>> sprites, boolean use_ao) {}

View File

@@ -26,12 +26,13 @@ public abstract class CamoAppearance {
public abstract @NotNull List<SpriteProperties> getSprites(Direction dir, int model_id);
public abstract boolean hasColor(Direction dir, int model_id, int index);
public abstract boolean getAO(int model_id);
public @NotNull RenderMaterial getRenderMaterial(boolean ao) {
return ao && ao_material != null? ao_material : material;
}
public int transformQuad(QuadEmitter quad, int i, int quad_index, int model_id, boolean ao, boolean uv_lock) {
public int transformQuad(QuadEmitter quad, int i, int quad_index, int model_id, boolean uv_lock) {
if(quad.tag() == 0) return 0; // Pass the quad through unmodified.
Direction direction = quad.nominalFace();
@@ -44,7 +45,7 @@ public abstract class CamoAppearance {
QuadPosBounds bounds = properties.bounds();
if (bounds == null) { // sprite applies anywhere e.g. default behaviour
quad.material(getRenderMaterial(ao));
quad.material(getRenderMaterial(getAO(model_id)));
quad.spriteBake(
properties.sprite(),
MutableQuadView.BAKE_NORMALIZED
@@ -61,7 +62,7 @@ public abstract class CamoAppearance {
if (!bounds.matches(origin_bounds)) return i;
// apply new quad shape
quad.material(getRenderMaterial(ao));
quad.material(getRenderMaterial(getAO(model_id)));
bounds.intersection(origin_bounds, direction.getAxis()).apply(quad, origin_bounds);
quad.spriteBake( // seems to work without the flags and break with it
properties.sprite(),

View File

@@ -64,12 +64,12 @@ public class CamoAppearanceManager {
this.accent_appearance = new SingleSpriteAppearance(sprite, materials.get(BlendMode.CUTOUT), serial_number.getAndIncrement());
sprite = spriteLookup.apply(BARRIER_SPRITE_ID);
this.barrierItemAppearance = new SingleSpriteAppearance(sprite, materials.get(BlendMode.CUTOUT), serial_number.getAndIncrement());
this.barrier_appearance = new SingleSpriteAppearance(sprite, materials.get(BlendMode.CUTOUT), serial_number.getAndIncrement());
}
private final CamoAppearance default_appearance;
private final CamoAppearance accent_appearance;
private final CamoAppearance barrierItemAppearance;
private final CamoAppearance barrier_appearance;
private final AtomicInteger serial_number = new AtomicInteger(0); //Mutable
@@ -95,7 +95,7 @@ public class CamoAppearanceManager {
model = dynamic_model.computeQuads(world, state, pos, theme_index);
// if model isn't rebaked its just wrapped (i.e. not dynamic and may be cached)
if (model instanceof RebakedModel) {
CamoAppearance appearance = computeAppearance(model, state);
CamoAppearance appearance = computeAppearance(model, state, !item);
if (item) APPEARANCE_CACHE.put(state, appearance);
return appearance;
}
@@ -104,7 +104,7 @@ public class CamoAppearanceManager {
// refresh cache
if (APPEARANCE_CACHE.asMap().containsKey(state)) return APPEARANCE_CACHE.getIfPresent(state);
CamoAppearance appearance = computeAppearance(model, state);
CamoAppearance appearance = computeAppearance(model, state, false);
APPEARANCE_CACHE.put(state, appearance);
return appearance;
}
@@ -118,15 +118,15 @@ public class CamoAppearanceManager {
// The computeIfAbsent map update will work without corrupting the map, but there will be some "wasted effort" computing the value twice.
// 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 CamoAppearances are used as a map key, then. IMO it's not a critical issue.
private CamoAppearance computeAppearance(BakedModel model, BlockState state) {
if(state.getBlock() == Blocks.BARRIER) return barrierItemAppearance;
private CamoAppearance computeAppearance(BakedModel model, BlockState state, boolean is_dynamic) {
if(state.getBlock() == Blocks.BARRIER) return barrier_appearance;
if (!(model instanceof WeightedBakedModelAccessor weighted_model)) {
return new ComputedAppearance(
getAppearance(model),
getCachedMaterial(state, true),
getCachedMaterial(state, false),
serial_number.getAndIncrement()
is_dynamic ? -1 : serial_number.getAndIncrement()
);
}
List<Weighted.Present<Appearance>> appearances = weighted_model.getModels().stream()
@@ -137,7 +137,7 @@ public class CamoAppearanceManager {
appearances,
getCachedMaterial(state, true),
getCachedMaterial(state, false),
serial_number.getAndIncrement()
is_dynamic ? -1 : serial_number.getAndIncrement()
);
}
@@ -175,7 +175,7 @@ public class CamoAppearanceManager {
});
});
return new Appearance(sprites);
return new Appearance(sprites, model.useAmbientOcclusion());
}
private static int getBakeFlags(QuadEmitter emitter, Sprite sprite) {

View File

@@ -16,7 +16,6 @@ public class ComputedAppearance extends CamoAppearance {
super(ao_material, material, id);
this.appearance = appearance;
}
@Override
public @NotNull List<SpriteProperties> getSprites(Direction dir, int model_id) {
return appearance.sprites().get(dir);
@@ -29,6 +28,12 @@ public class ComputedAppearance extends CamoAppearance {
return properties.get(index).has_colors();
}
@Override
public boolean getAO(int model_id) {
return appearance.use_ao();
}
@Override
public boolean equals(Object o) {
if(this == o) return true;

View File

@@ -35,6 +35,12 @@ public class SingleSpriteAppearance extends CamoAppearance {
return id == that.id;
}
@Override
public boolean getAO(int model_id) {
return false;
}
@Override
public String toString() {
return "SingleSpriteAppearance[defaultSprite=%s, mat=%s, id=%d]".formatted(defaultSprite, material, id);

View File

@@ -46,6 +46,12 @@ public class WeightedComputedAppearance extends CamoAppearance {
return properties.get(index).has_colors();
}
@Override
public boolean getAO(int model_id) {
return getAppearance(model_id).use_ao();
}
@Override
public boolean equals(Object o) {
if(this == o) return true;

View File

@@ -31,7 +31,6 @@ import static net.minecraft.util.shape.VoxelShapes.combine;
@Environment(EnvType.CLIENT)
public class RenderHelper {
// self culling cache of the models not made thread local so that it is only computed once
private static final Cache<CullElement, Integer[]> INNER_CULL_MAP = CacheBuilder.newBuilder().maximumSize(1024).build();
private record CullElement(Block block, Object state_key, int model) {}

View File

@@ -1,7 +1,8 @@
package fr.adrien1106.reframed.generator;
import net.minecraft.block.Block;
import net.minecraft.data.client.BlockStateSupplier;
public interface BlockStateProvider {
BlockStateSupplier getMultipart();
BlockStateSupplier getMultipart(Block block);
}

View File

@@ -1,14 +1,23 @@
package fr.adrien1106.reframed.generator;
import fr.adrien1106.reframed.ReFramed;
import fr.adrien1106.reframed.block.*;
import fr.adrien1106.reframed.generator.block.*;
import net.fabricmc.fabric.api.datagen.v1.FabricDataOutput;
import net.fabricmc.fabric.api.datagen.v1.provider.FabricTagProvider.BlockTagProvider;
import net.minecraft.block.Block;
import net.minecraft.registry.RegistryWrapper.WrapperLookup;
import net.minecraft.registry.tag.BlockTags;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.CompletableFuture;
public class GBlockTag extends BlockTagProvider {
private static final Map<Class<? extends Block>, TagGetter> providers = new HashMap<>();
static {
providers.put(ReframedWallBlock.class, new Wall());
}
public GBlockTag(FabricDataOutput output, CompletableFuture<WrapperLookup> registries) {
super(output, registries);
@@ -17,6 +26,10 @@ public class GBlockTag extends BlockTagProvider {
@Override
protected void configure(WrapperLookup arg) {
FabricTagBuilder builder = getOrCreateTagBuilder(BlockTags.AXE_MINEABLE);
ReFramed.BLOCKS.forEach(builder::add);
ReFramed.BLOCKS.forEach((block) -> {
if (providers.containsKey(block.getClass()))
providers.get(block.getClass()).getTags().forEach((tag) -> getOrCreateTagBuilder(tag).add(block));
builder.add(block);
});
}
}

View File

@@ -1,17 +1,39 @@
package fr.adrien1106.reframed.generator;
import fr.adrien1106.reframed.ReFramed;
import fr.adrien1106.reframed.block.*;
import fr.adrien1106.reframed.generator.block.*;
import net.fabricmc.fabric.api.datagen.v1.FabricDataOutput;
import net.fabricmc.fabric.api.datagen.v1.provider.FabricModelProvider;
import net.minecraft.block.Block;
import net.minecraft.data.client.*;
import net.minecraft.state.property.Property;
import net.minecraft.util.Identifier;
import java.util.HashMap;
import java.util.Map;
import java.util.Objects;
import static net.minecraft.data.client.VariantSettings.Rotation.R0;
public class GBlockstate extends FabricModelProvider {
private static final Map<Class<? extends Block>, BlockStateProvider> providers = new HashMap<>();
static {
providers.put(ReFramedHalfStairBlock.class, new HalfStair());
providers.put(ReFramedHalfStairsSlabBlock.class, new HalfStairsSlab());
providers.put(ReFramedHalfStairsStairBlock.class, new HalfStairsStair());
providers.put(ReFramedLayerBlock.class, new Layer());
providers.put(ReFramedPillarBlock.class, new Pillar());
providers.put(ReFramedSlabBlock.class, new Slab());
providers.put(ReFramedSlabsCubeBlock.class, new SlabsCube());
providers.put(ReFramedSmallCubeBlock.class, new SmallCube());
providers.put(ReFramedSmallCubesStepBlock.class, new SmallCubesStep());
providers.put(ReFramedStairBlock.class, new Stair());
providers.put(ReFramedStairsCubeBlock.class, new StairsCube());
providers.put(ReFramedStepBlock.class, new Step());
providers.put(ReFramedStepsSlabBlock.class, new StepsSlab());
providers.put(ReframedWallBlock.class, new Wall());
}
public GBlockstate(FabricDataOutput output) {
super(output);
@@ -23,7 +45,7 @@ public class GBlockstate extends FabricModelProvider {
.forEach(model_generator::excludeFromSimpleItemModelGeneration);
ReFramed.BLOCKS.stream()
.map(block -> {
if (block instanceof BlockStateProvider multipart_block) return multipart_block.getMultipart();
if (providers.containsKey(block.getClass())) return providers.get(block.getClass()).getMultipart(block);
return VariantsBlockStateSupplier.create(
block,
GBlockstate.variant(
@@ -54,11 +76,57 @@ public class GBlockstate extends FabricModelProvider {
return When.create().set(property_1, value_1);
}
public static <T extends Comparable<T>, U extends Comparable<U>> When when(Property<T> property_1, T value_1, Property<U> property_2, U value_2) {
return When.allOf(when(property_1, value_1), when(property_2, value_2));
public static <T extends Comparable<T>,
U extends Comparable<U>> When when(Property<T> property_1, T value_1,
Property<U> property_2, U value_2) {
return When.allOf(
when(property_1, value_1),
when(property_2, value_2)
);
}
public static <T extends Comparable<T>, U extends Comparable<U>, V extends Comparable<V>> When when(Property<T> property_1, T value_1, Property<U> property_2, U value_2, Property<V> property_3, V value_3) {
return When.allOf(when(property_1, value_1), when(property_2, value_2), when(property_3, value_3));
public static <T extends Comparable<T>,
U extends Comparable<U>,
V extends Comparable<V>> When when(Property<T> property_1, T value_1,
Property<U> property_2, U value_2,
Property<V> property_3, V value_3) {
return When.allOf(
when(property_1, value_1),
when(property_2, value_2),
when(property_3, value_3)
);
}
public static <T extends Comparable<T>,
U extends Comparable<U>,
V extends Comparable<V>,
W extends Comparable<W>> When when(Property<T> property_1, T value_1,
Property<U> property_2, U value_2,
Property<V> property_3, V value_3,
Property<W> property_4, W value_4) {
return When.allOf(
when(property_1, value_1),
when(property_2, value_2),
when(property_3, value_3),
when(property_4, value_4)
);
}
public static <T extends Comparable<T>,
U extends Comparable<U>,
V extends Comparable<V>,
W extends Comparable<W>,
X extends Comparable<X>> When when(Property<T> property_1, T value_1,
Property<U> property_2, U value_2,
Property<V> property_3, V value_3,
Property<W> property_4, W value_4,
Property<X> property_5, X value_5) {
return When.allOf(
when(property_1, value_1),
when(property_2, value_2),
when(property_3, value_3),
when(property_4, value_4),
when(property_5, value_5)
);
}
}

View File

@@ -1,11 +1,45 @@
package fr.adrien1106.reframed.generator;
import fr.adrien1106.reframed.ReFramed;
import fr.adrien1106.reframed.block.*;
import fr.adrien1106.reframed.generator.block.*;
import fr.adrien1106.reframed.generator.item.Blueprint;
import fr.adrien1106.reframed.generator.item.Hammer;
import fr.adrien1106.reframed.generator.item.Screwdriver;
import fr.adrien1106.reframed.item.ReFramedBlueprintItem;
import fr.adrien1106.reframed.item.ReFramedHammerItem;
import fr.adrien1106.reframed.item.ReFramedScrewdriverItem;
import net.fabricmc.fabric.api.datagen.v1.FabricDataOutput;
import net.fabricmc.fabric.api.datagen.v1.provider.FabricRecipeProvider;
import net.minecraft.data.server.recipe.RecipeExporter;
import net.minecraft.item.ItemConvertible;
import java.util.HashMap;
import java.util.Map;
public class GRecipe extends FabricRecipeProvider {
private static final Map<Class<? extends ItemConvertible>, RecipeSetter> providers = new HashMap<>();
static {
providers.put(ReFramedBlock.class, new Cube());
providers.put(ReFramedHalfStairBlock.class, new HalfStair());
providers.put(ReFramedHalfStairsSlabBlock.class, new HalfStairsSlab());
providers.put(ReFramedHalfStairsStairBlock.class, new HalfStairsStair());
providers.put(ReFramedLayerBlock.class, new Layer());
providers.put(ReFramedPillarBlock.class, new Pillar());
providers.put(ReFramedSlabBlock.class, new Slab());
providers.put(ReFramedSlabsCubeBlock.class, new SlabsCube());
providers.put(ReFramedSmallCubeBlock.class, new SmallCube());
providers.put(ReFramedSmallCubesStepBlock.class, new SmallCubesStep());
providers.put(ReFramedStairBlock.class, new Stair());
providers.put(ReFramedStairsCubeBlock.class, new StairsCube());
providers.put(ReFramedStepBlock.class, new Step());
providers.put(ReFramedStepsSlabBlock.class, new StepsSlab());
providers.put(ReframedWallBlock.class, new Wall());
providers.put(ReFramedBlueprintItem.class, new Blueprint());
providers.put(ReFramedHammerItem.class, new Hammer());
providers.put(ReFramedScrewdriverItem.class, new Screwdriver());
}
public GRecipe(FabricDataOutput output) {
super(output);
}
@@ -13,10 +47,10 @@ public class GRecipe extends FabricRecipeProvider {
@Override
public void generate(RecipeExporter exporter) {
ReFramed.BLOCKS.forEach(block -> {
if (block instanceof RecipeSetter provider) provider.setRecipe(exporter);
if (providers.containsKey(block.getClass())) providers.get(block.getClass()).setRecipe(exporter, block);
});
ReFramed.ITEMS.forEach(item -> {
if (item instanceof RecipeSetter provider) provider.setRecipe(exporter);
if (providers.containsKey(item.getClass())) providers.get(item.getClass()).setRecipe(exporter, item);
});
}
}

View File

@@ -1,8 +1,9 @@
package fr.adrien1106.reframed.generator;
import net.minecraft.data.server.recipe.RecipeExporter;
import net.minecraft.item.ItemConvertible;
public interface RecipeSetter {
void setRecipe(RecipeExporter exporter);
void setRecipe(RecipeExporter exporter, ItemConvertible convertible);
}

View File

@@ -0,0 +1,11 @@
package fr.adrien1106.reframed.generator;
import net.minecraft.block.Block;
import net.minecraft.registry.tag.TagKey;
import java.util.List;
public interface TagGetter {
List<TagKey<Block>> getTags();
}

View File

@@ -0,0 +1,26 @@
package fr.adrien1106.reframed.generator.block;
import fr.adrien1106.reframed.generator.RecipeSetter;
import net.fabricmc.fabric.api.datagen.v1.provider.FabricRecipeProvider;
import net.minecraft.data.server.recipe.RecipeExporter;
import net.minecraft.data.server.recipe.ShapedRecipeJsonBuilder;
import net.minecraft.item.ItemConvertible;
import net.minecraft.item.Items;
import net.minecraft.recipe.book.RecipeCategory;
public class Cube implements RecipeSetter {
@Override
public void setRecipe(RecipeExporter exporter, ItemConvertible convertible) {
ShapedRecipeJsonBuilder
.create(RecipeCategory.BUILDING_BLOCKS, convertible)
.pattern("III")
.pattern("I~I")
.pattern("III")
.input('I', Items.BAMBOO)
.input('~', Items.STRING)
.criterion(FabricRecipeProvider.hasItem(Items.BAMBOO), FabricRecipeProvider.conditionsFromItem(Items.BAMBOO))
.criterion(FabricRecipeProvider.hasItem(convertible), FabricRecipeProvider.conditionsFromItem(convertible))
.offerTo(exporter);
}
}

View File

@@ -0,0 +1,106 @@
package fr.adrien1106.reframed.generator.block;
import fr.adrien1106.reframed.ReFramed;
import fr.adrien1106.reframed.generator.BlockStateProvider;
import fr.adrien1106.reframed.generator.GBlockstate;
import fr.adrien1106.reframed.generator.RecipeSetter;
import net.fabricmc.fabric.api.datagen.v1.provider.FabricRecipeProvider;
import net.minecraft.block.Block;
import net.minecraft.data.client.BlockStateSupplier;
import net.minecraft.data.client.MultipartBlockStateSupplier;
import net.minecraft.data.server.recipe.RecipeExporter;
import net.minecraft.data.server.recipe.RecipeProvider;
import net.minecraft.data.server.recipe.ShapedRecipeJsonBuilder;
import net.minecraft.item.ItemConvertible;
import net.minecraft.recipe.book.RecipeCategory;
import net.minecraft.util.Identifier;
import static fr.adrien1106.reframed.util.blocks.BlockProperties.CORNER;
import static fr.adrien1106.reframed.util.blocks.BlockProperties.CORNER_FACE;
import static fr.adrien1106.reframed.util.blocks.Corner.*;
import static fr.adrien1106.reframed.util.blocks.Corner.NORTH_EAST_UP;
import static net.minecraft.data.client.VariantSettings.Rotation.*;
public class HalfStair implements RecipeSetter, BlockStateProvider {
@Override
public void setRecipe(RecipeExporter exporter, ItemConvertible convertible) {
RecipeProvider.offerStonecuttingRecipe(exporter, RecipeCategory.BUILDING_BLOCKS, convertible, ReFramed.CUBE, 2);
ShapedRecipeJsonBuilder
.create(RecipeCategory.BUILDING_BLOCKS, convertible, 4)
.pattern("I ")
.pattern("II")
.input('I', ReFramed.CUBE)
.criterion(FabricRecipeProvider.hasItem(ReFramed.CUBE), FabricRecipeProvider.conditionsFromItem(ReFramed.CUBE))
.criterion(FabricRecipeProvider.hasItem(convertible), FabricRecipeProvider.conditionsFromItem(convertible))
.offerTo(exporter);
}
@Override
public BlockStateSupplier getMultipart(Block block) {
return getMultipart(
block,
ReFramed.id("half_stair_down_special"),
ReFramed.id("half_stair_side_special")
);
}
public static BlockStateSupplier getMultipart(Block block, Identifier model_down, Identifier model_side) {
return MultipartBlockStateSupplier.create(block)
.with(GBlockstate.when(CORNER, NORTH_EAST_DOWN, CORNER_FACE, 1),
GBlockstate.variant(model_side, true, R0, R0))
.with(GBlockstate.when(CORNER, NORTH_EAST_DOWN, CORNER_FACE, 0),
GBlockstate.variant(model_side, true, R90, R270))
.with(GBlockstate.when(CORNER, NORTH_EAST_DOWN, CORNER_FACE, 2),
GBlockstate.variant(model_down, true, R0, R0))
.with(GBlockstate.when(CORNER, EAST_SOUTH_DOWN, CORNER_FACE, 1),
GBlockstate.variant(model_side, true, R0, R90))
.with(GBlockstate.when(CORNER, EAST_SOUTH_DOWN, CORNER_FACE, 0),
GBlockstate.variant(model_side, true, R90, R0))
.with(GBlockstate.when(CORNER, EAST_SOUTH_DOWN, CORNER_FACE, 2),
GBlockstate.variant(model_down, true, R0, R90))
.with(GBlockstate.when(CORNER, SOUTH_WEST_DOWN, CORNER_FACE, 1),
GBlockstate.variant(model_side, true, R0, R180))
.with(GBlockstate.when(CORNER, SOUTH_WEST_DOWN, CORNER_FACE, 0),
GBlockstate.variant(model_side, true, R90, R90))
.with(GBlockstate.when(CORNER, SOUTH_WEST_DOWN, CORNER_FACE, 2),
GBlockstate.variant(model_down, true, R0, R180))
.with(GBlockstate.when(CORNER, WEST_NORTH_DOWN, CORNER_FACE, 1),
GBlockstate.variant(model_side, true, R0, R270))
.with(GBlockstate.when(CORNER, WEST_NORTH_DOWN, CORNER_FACE, 0),
GBlockstate.variant(model_side, true, R90, R180))
.with(GBlockstate.when(CORNER, WEST_NORTH_DOWN, CORNER_FACE, 2),
GBlockstate.variant(model_down, true, R0, R270))
.with(GBlockstate.when(CORNER, EAST_SOUTH_UP, CORNER_FACE, 0),
GBlockstate.variant(model_side, true, R180, R0))
.with(GBlockstate.when(CORNER, EAST_SOUTH_UP, CORNER_FACE, 1),
GBlockstate.variant(model_side, true, R270, R90))
.with(GBlockstate.when(CORNER, EAST_SOUTH_UP, CORNER_FACE, 2),
GBlockstate.variant(model_down, true, R180, R0))
.with(GBlockstate.when(CORNER, SOUTH_WEST_UP, CORNER_FACE, 0),
GBlockstate.variant(model_side, true, R180, R90))
.with(GBlockstate.when(CORNER, SOUTH_WEST_UP, CORNER_FACE, 1),
GBlockstate.variant(model_side, true, R270, R180))
.with(GBlockstate.when(CORNER, SOUTH_WEST_UP, CORNER_FACE, 2),
GBlockstate.variant(model_down, true, R180, R90))
.with(GBlockstate.when(CORNER, WEST_NORTH_UP, CORNER_FACE, 0),
GBlockstate.variant(model_side, true, R180, R180))
.with(GBlockstate.when(CORNER, WEST_NORTH_UP, CORNER_FACE, 1),
GBlockstate.variant(model_side, true, R270, R270))
.with(GBlockstate.when(CORNER, WEST_NORTH_UP, CORNER_FACE, 2),
GBlockstate.variant(model_down, true, R180, R180))
.with(GBlockstate.when(CORNER, NORTH_EAST_UP, CORNER_FACE, 0),
GBlockstate.variant(model_side, true, R180, R270))
.with(GBlockstate.when(CORNER, NORTH_EAST_UP, CORNER_FACE, 1),
GBlockstate.variant(model_side, true, R270, R0))
.with(GBlockstate.when(CORNER, NORTH_EAST_UP, CORNER_FACE, 2),
GBlockstate.variant(model_down, true, R180, R270));
}
}

View File

@@ -0,0 +1,37 @@
package fr.adrien1106.reframed.generator.block;
import fr.adrien1106.reframed.ReFramed;
import fr.adrien1106.reframed.generator.BlockStateProvider;
import fr.adrien1106.reframed.generator.RecipeSetter;
import net.fabricmc.fabric.api.datagen.v1.provider.FabricRecipeProvider;
import net.minecraft.block.Block;
import net.minecraft.data.client.BlockStateSupplier;
import net.minecraft.data.server.recipe.RecipeExporter;
import net.minecraft.data.server.recipe.RecipeProvider;
import net.minecraft.data.server.recipe.ShapelessRecipeJsonBuilder;
import net.minecraft.item.ItemConvertible;
import net.minecraft.recipe.book.RecipeCategory;
public class HalfStairsSlab implements RecipeSetter, BlockStateProvider {
@Override
public void setRecipe(RecipeExporter exporter, ItemConvertible convertible) {
RecipeProvider.offerStonecuttingRecipe(exporter, RecipeCategory.BUILDING_BLOCKS, convertible, ReFramed.CUBE, 2);
ShapelessRecipeJsonBuilder
.create(RecipeCategory.BUILDING_BLOCKS, convertible)
.input(ReFramed.HALF_STAIR)
.input(ReFramed.SMALL_CUBE)
.criterion(FabricRecipeProvider.hasItem(ReFramed.CUBE), FabricRecipeProvider.conditionsFromItem(ReFramed.CUBE))
.criterion(FabricRecipeProvider.hasItem(convertible), FabricRecipeProvider.conditionsFromItem(convertible))
.offerTo(exporter);
}
@Override
public BlockStateSupplier getMultipart(Block block) {
return HalfStair.getMultipart(
block,
ReFramed.id("half_stairs_slab_down_special"),
ReFramed.id("half_stairs_slab_side_special")
);
}
}

View File

@@ -0,0 +1,70 @@
package fr.adrien1106.reframed.generator.block;
import fr.adrien1106.reframed.ReFramed;
import fr.adrien1106.reframed.generator.BlockStateProvider;
import fr.adrien1106.reframed.generator.GBlockstate;
import fr.adrien1106.reframed.generator.RecipeSetter;
import net.fabricmc.fabric.api.datagen.v1.provider.FabricRecipeProvider;
import net.minecraft.block.Block;
import net.minecraft.data.client.BlockStateSupplier;
import net.minecraft.data.client.MultipartBlockStateSupplier;
import net.minecraft.data.server.recipe.RecipeExporter;
import net.minecraft.data.server.recipe.RecipeProvider;
import net.minecraft.data.server.recipe.ShapelessRecipeJsonBuilder;
import net.minecraft.item.ItemConvertible;
import net.minecraft.recipe.book.RecipeCategory;
import net.minecraft.util.Identifier;
import static fr.adrien1106.reframed.util.blocks.BlockProperties.EDGE;
import static fr.adrien1106.reframed.util.blocks.Edge.*;
import static fr.adrien1106.reframed.util.blocks.Edge.WEST_DOWN;
import static net.minecraft.data.client.VariantSettings.Rotation.*;
public class HalfStairsStair implements RecipeSetter, BlockStateProvider {
@Override
public void setRecipe(RecipeExporter exporter, ItemConvertible convertible) {
RecipeProvider.offerStonecuttingRecipe(exporter, RecipeCategory.BUILDING_BLOCKS, convertible, ReFramed.CUBE, 2);
ShapelessRecipeJsonBuilder
.create(RecipeCategory.BUILDING_BLOCKS, convertible)
.input(ReFramed.HALF_STAIR, 2)
.criterion(FabricRecipeProvider.hasItem(ReFramed.CUBE), FabricRecipeProvider.conditionsFromItem(ReFramed.CUBE))
.criterion(FabricRecipeProvider.hasItem(convertible), FabricRecipeProvider.conditionsFromItem(convertible))
.offerTo(exporter);
}
@Override
public BlockStateSupplier getMultipart(Block block) {
Identifier model_id = ReFramed.id("half_stairs_stair_down_special");
Identifier side_model_id = ReFramed.id("half_stairs_stair_side_special");
Identifier reverse_model_id = ReFramed.id("half_stairs_stair_reverse_special");
return MultipartBlockStateSupplier.create(block)
/* X AXIS */
.with(GBlockstate.when(EDGE, NORTH_DOWN),
GBlockstate.variant(side_model_id, true, R90, R180))
.with(GBlockstate.when(EDGE, DOWN_SOUTH),
GBlockstate.variant(side_model_id, true, R0, R180))
.with(GBlockstate.when(EDGE, SOUTH_UP),
GBlockstate.variant(side_model_id, true, R270, R180))
.with(GBlockstate.when(EDGE, UP_NORTH),
GBlockstate.variant(side_model_id, true, R180, R180))
/* Y AXIS */
.with(GBlockstate.when(EDGE, NORTH_EAST),
GBlockstate.variant(model_id, true, R0, R0))
.with(GBlockstate.when(EDGE, EAST_SOUTH),
GBlockstate.variant(model_id, true, R0, R90))
.with(GBlockstate.when(EDGE, SOUTH_WEST),
GBlockstate.variant(model_id, true, R0, R180))
.with(GBlockstate.when(EDGE, WEST_NORTH),
GBlockstate.variant(model_id, true, R0, R270))
/* Z AXIS */
.with(GBlockstate.when(EDGE, DOWN_EAST),
GBlockstate.variant(reverse_model_id, true, R0, R90))
.with(GBlockstate.when(EDGE, EAST_UP),
GBlockstate.variant(side_model_id, true, R180, R270))
.with(GBlockstate.when(EDGE, UP_WEST),
GBlockstate.variant(reverse_model_id, true, R180, R90))
.with(GBlockstate.when(EDGE, WEST_DOWN),
GBlockstate.variant(side_model_id, true, R0, R270));
}
}

View File

@@ -0,0 +1,58 @@
package fr.adrien1106.reframed.generator.block;
import fr.adrien1106.reframed.ReFramed;
import fr.adrien1106.reframed.generator.BlockStateProvider;
import fr.adrien1106.reframed.generator.GBlockstate;
import fr.adrien1106.reframed.generator.RecipeSetter;
import net.fabricmc.fabric.api.datagen.v1.provider.FabricRecipeProvider;
import net.minecraft.block.Block;
import net.minecraft.data.client.MultipartBlockStateSupplier;
import net.minecraft.data.server.recipe.RecipeExporter;
import net.minecraft.data.server.recipe.RecipeProvider;
import net.minecraft.data.server.recipe.ShapedRecipeJsonBuilder;
import net.minecraft.item.ItemConvertible;
import net.minecraft.recipe.book.RecipeCategory;
import net.minecraft.util.Identifier;
import net.minecraft.util.math.Direction;
import static net.minecraft.data.client.VariantSettings.Rotation.*;
import static net.minecraft.state.property.Properties.FACING;
import static net.minecraft.state.property.Properties.LAYERS;
public class Layer implements RecipeSetter, BlockStateProvider {
@Override
public void setRecipe(RecipeExporter exporter, ItemConvertible convertible) {
RecipeProvider.offerStonecuttingRecipe(exporter, RecipeCategory.BUILDING_BLOCKS, convertible, ReFramed.CUBE, 8);
ShapedRecipeJsonBuilder
.create(RecipeCategory.BUILDING_BLOCKS, convertible, 16)
.pattern("II")
.input('I', ReFramed.CUBE)
.criterion(FabricRecipeProvider.hasItem(ReFramed.CUBE), FabricRecipeProvider.conditionsFromItem(ReFramed.CUBE))
.criterion(FabricRecipeProvider.hasItem(convertible), FabricRecipeProvider.conditionsFromItem(convertible))
.offerTo(exporter);
}
@Override
public MultipartBlockStateSupplier getMultipart(Block block) {
String model_pattern = "layer_x_special";
MultipartBlockStateSupplier supplier = MultipartBlockStateSupplier.create(block);
for (int i = 1; i <= 8; i++) {
Identifier model = ReFramed.id(model_pattern.replace("x", i + ""));
supplier
.with(GBlockstate.when(FACING, Direction.DOWN, LAYERS, i),
GBlockstate.variant(model, true, R0, R0))
.with(GBlockstate.when(FACING, Direction.SOUTH, LAYERS, i),
GBlockstate.variant(model, true, R90, R0))
.with(GBlockstate.when(FACING, Direction.UP, LAYERS, i),
GBlockstate.variant(model, true, R180, R0))
.with(GBlockstate.when(FACING, Direction.NORTH, LAYERS, i),
GBlockstate.variant(model, true, R270, R0))
.with(GBlockstate.when(FACING, Direction.WEST, LAYERS, i),
GBlockstate.variant(model, true, R90, R90))
.with(GBlockstate.when(FACING, Direction.EAST, LAYERS, i),
GBlockstate.variant(model, true, R90, R270));
}
return supplier;
}
}

View File

@@ -0,0 +1,49 @@
package fr.adrien1106.reframed.generator.block;
import fr.adrien1106.reframed.ReFramed;
import fr.adrien1106.reframed.generator.BlockStateProvider;
import fr.adrien1106.reframed.generator.GBlockstate;
import fr.adrien1106.reframed.generator.RecipeSetter;
import net.fabricmc.fabric.api.datagen.v1.provider.FabricRecipeProvider;
import net.minecraft.block.Block;
import net.minecraft.data.client.BlockStateSupplier;
import net.minecraft.data.client.MultipartBlockStateSupplier;
import net.minecraft.data.server.recipe.RecipeExporter;
import net.minecraft.data.server.recipe.RecipeProvider;
import net.minecraft.data.server.recipe.ShapedRecipeJsonBuilder;
import net.minecraft.item.ItemConvertible;
import net.minecraft.recipe.book.RecipeCategory;
import net.minecraft.util.Identifier;
import net.minecraft.util.math.Direction;
import static net.minecraft.data.client.VariantSettings.Rotation.R0;
import static net.minecraft.data.client.VariantSettings.Rotation.R90;
import static net.minecraft.state.property.Properties.AXIS;
public class Pillar implements RecipeSetter, BlockStateProvider {
@Override
public void setRecipe(RecipeExporter exporter, ItemConvertible convertible) {
RecipeProvider.offerStonecuttingRecipe(exporter, RecipeCategory.BUILDING_BLOCKS, convertible, ReFramed.CUBE, 4);
ShapedRecipeJsonBuilder
.create(RecipeCategory.BUILDING_BLOCKS, convertible, 8)
.pattern("I")
.pattern("I")
.input('I', ReFramed.CUBE)
.criterion(FabricRecipeProvider.hasItem(ReFramed.CUBE), FabricRecipeProvider.conditionsFromItem(ReFramed.CUBE))
.criterion(FabricRecipeProvider.hasItem(convertible), FabricRecipeProvider.conditionsFromItem(convertible))
.offerTo(exporter);
}
@Override
public BlockStateSupplier getMultipart(Block block) {
Identifier model_id = ReFramed.id("pillar_special");
return MultipartBlockStateSupplier.create(block)
.with(GBlockstate.when(AXIS, Direction.Axis.X),
GBlockstate.variant(model_id, true, R90, R90))
.with(GBlockstate.when(AXIS, Direction.Axis.Y),
GBlockstate.variant(model_id, true, R0, R0))
.with(GBlockstate.when(AXIS, Direction.Axis.Z),
GBlockstate.variant(model_id, true, R90, R0));
}
}

View File

@@ -0,0 +1,52 @@
package fr.adrien1106.reframed.generator.block;
import fr.adrien1106.reframed.ReFramed;
import fr.adrien1106.reframed.generator.BlockStateProvider;
import fr.adrien1106.reframed.generator.GBlockstate;
import fr.adrien1106.reframed.generator.RecipeSetter;
import net.fabricmc.fabric.api.datagen.v1.provider.FabricRecipeProvider;
import net.minecraft.block.Block;
import net.minecraft.data.client.MultipartBlockStateSupplier;
import net.minecraft.data.server.recipe.RecipeExporter;
import net.minecraft.data.server.recipe.RecipeProvider;
import net.minecraft.data.server.recipe.ShapedRecipeJsonBuilder;
import net.minecraft.item.ItemConvertible;
import net.minecraft.recipe.book.RecipeCategory;
import net.minecraft.util.Identifier;
import net.minecraft.util.math.Direction;
import static net.minecraft.data.client.VariantSettings.Rotation.*;
import static net.minecraft.state.property.Properties.FACING;
public class Slab implements RecipeSetter, BlockStateProvider {
@Override
public void setRecipe(RecipeExporter exporter, ItemConvertible convertible) {
RecipeProvider.offerStonecuttingRecipe(exporter, RecipeCategory.BUILDING_BLOCKS, convertible, ReFramed.CUBE, 2);
ShapedRecipeJsonBuilder
.create(RecipeCategory.BUILDING_BLOCKS, convertible, 6)
.pattern("III")
.input('I', ReFramed.CUBE)
.criterion(FabricRecipeProvider.hasItem(ReFramed.CUBE), FabricRecipeProvider.conditionsFromItem(ReFramed.CUBE))
.criterion(FabricRecipeProvider.hasItem(convertible), FabricRecipeProvider.conditionsFromItem(convertible))
.offerTo(exporter);
}
@Override
public MultipartBlockStateSupplier getMultipart(Block block) {
Identifier model_id = ReFramed.id("slab_special");
return MultipartBlockStateSupplier.create(block)
.with(GBlockstate.when(FACING, Direction.DOWN),
GBlockstate.variant(model_id, true, R0, R0))
.with(GBlockstate.when(FACING, Direction.SOUTH),
GBlockstate.variant(model_id, true, R90, R0))
.with(GBlockstate.when(FACING, Direction.UP),
GBlockstate.variant(model_id, true, R180, R0))
.with(GBlockstate.when(FACING, Direction.NORTH),
GBlockstate.variant(model_id, true, R270, R0))
.with(GBlockstate.when(FACING, Direction.WEST),
GBlockstate.variant(model_id, true, R90, R90))
.with(GBlockstate.when(FACING, Direction.EAST),
GBlockstate.variant(model_id, true, R90, R270));
}
}

View File

@@ -0,0 +1,46 @@
package fr.adrien1106.reframed.generator.block;
import fr.adrien1106.reframed.ReFramed;
import fr.adrien1106.reframed.generator.BlockStateProvider;
import fr.adrien1106.reframed.generator.GBlockstate;
import fr.adrien1106.reframed.generator.RecipeSetter;
import net.fabricmc.fabric.api.datagen.v1.provider.FabricRecipeProvider;
import net.minecraft.block.Block;
import net.minecraft.data.client.MultipartBlockStateSupplier;
import net.minecraft.data.server.recipe.RecipeExporter;
import net.minecraft.data.server.recipe.RecipeProvider;
import net.minecraft.data.server.recipe.ShapelessRecipeJsonBuilder;
import net.minecraft.item.ItemConvertible;
import net.minecraft.recipe.book.RecipeCategory;
import net.minecraft.util.Identifier;
import net.minecraft.util.math.Direction;
import static net.minecraft.data.client.VariantSettings.Rotation.*;
import static net.minecraft.data.client.VariantSettings.Rotation.R90;
import static net.minecraft.state.property.Properties.AXIS;
public class SlabsCube implements RecipeSetter, BlockStateProvider {
@Override
public void setRecipe(RecipeExporter exporter, ItemConvertible convertible) {
RecipeProvider.offerStonecuttingRecipe(exporter, RecipeCategory.BUILDING_BLOCKS, convertible, ReFramed.CUBE);
ShapelessRecipeJsonBuilder
.create(RecipeCategory.BUILDING_BLOCKS, convertible)
.input(ReFramed.SLAB, 2)
.criterion(FabricRecipeProvider.hasItem(ReFramed.CUBE), FabricRecipeProvider.conditionsFromItem(ReFramed.CUBE))
.criterion(FabricRecipeProvider.hasItem(convertible), FabricRecipeProvider.conditionsFromItem(convertible))
.offerTo(exporter);
}
@Override
public MultipartBlockStateSupplier getMultipart(Block block) {
Identifier model_id = ReFramed.id("double_slab_special");
return MultipartBlockStateSupplier.create(block)
.with(GBlockstate.when(AXIS, Direction.Axis.Y),
GBlockstate.variant(model_id, true, R0, R0))
.with(GBlockstate.when(AXIS, Direction.Axis.Z),
GBlockstate.variant(model_id, true, R270, R0))
.with(GBlockstate.when(AXIS, Direction.Axis.X),
GBlockstate.variant(model_id, true, R90, R90));
}
}

View File

@@ -0,0 +1,57 @@
package fr.adrien1106.reframed.generator.block;
import fr.adrien1106.reframed.ReFramed;
import fr.adrien1106.reframed.generator.BlockStateProvider;
import fr.adrien1106.reframed.generator.GBlockstate;
import fr.adrien1106.reframed.generator.RecipeSetter;
import net.fabricmc.fabric.api.datagen.v1.provider.FabricRecipeProvider;
import net.minecraft.block.Block;
import net.minecraft.data.client.BlockStateSupplier;
import net.minecraft.data.client.MultipartBlockStateSupplier;
import net.minecraft.data.server.recipe.RecipeExporter;
import net.minecraft.data.server.recipe.RecipeProvider;
import net.minecraft.data.server.recipe.ShapelessRecipeJsonBuilder;
import net.minecraft.item.ItemConvertible;
import net.minecraft.recipe.book.RecipeCategory;
import net.minecraft.util.Identifier;
import static fr.adrien1106.reframed.util.blocks.BlockProperties.CORNER;
import static fr.adrien1106.reframed.util.blocks.Corner.*;
import static fr.adrien1106.reframed.util.blocks.Corner.NORTH_EAST_UP;
import static net.minecraft.data.client.VariantSettings.Rotation.*;
public class SmallCube implements RecipeSetter, BlockStateProvider {
@Override
public void setRecipe(RecipeExporter exporter, ItemConvertible convertible) {
RecipeProvider.offerStonecuttingRecipe(exporter, RecipeCategory.BUILDING_BLOCKS, convertible, ReFramed.CUBE, 8);
ShapelessRecipeJsonBuilder
.create(RecipeCategory.BUILDING_BLOCKS, convertible, 8)
.input(ReFramed.CUBE)
.criterion(FabricRecipeProvider.hasItem(ReFramed.CUBE), FabricRecipeProvider.conditionsFromItem(ReFramed.CUBE))
.criterion(FabricRecipeProvider.hasItem(convertible), FabricRecipeProvider.conditionsFromItem(convertible))
.offerTo(exporter);
}
@Override
public BlockStateSupplier getMultipart(Block block) {
Identifier small_cube_id = ReFramed.id("small_cube_special");
return MultipartBlockStateSupplier.create(block)
.with(GBlockstate.when(CORNER, NORTH_EAST_DOWN),
GBlockstate.variant(small_cube_id, true, R0, R0))
.with(GBlockstate.when(CORNER, EAST_SOUTH_DOWN),
GBlockstate.variant(small_cube_id, true, R0, R90))
.with(GBlockstate.when(CORNER, SOUTH_WEST_DOWN),
GBlockstate.variant(small_cube_id, true, R0, R180))
.with(GBlockstate.when(CORNER, WEST_NORTH_DOWN),
GBlockstate.variant(small_cube_id, true, R0, R270))
.with(GBlockstate.when(CORNER, EAST_SOUTH_UP),
GBlockstate.variant(small_cube_id, true, R180, R0))
.with(GBlockstate.when(CORNER, SOUTH_WEST_UP),
GBlockstate.variant(small_cube_id, true, R180, R90))
.with(GBlockstate.when(CORNER, WEST_NORTH_UP),
GBlockstate.variant(small_cube_id, true, R180, R180))
.with(GBlockstate.when(CORNER, NORTH_EAST_UP),
GBlockstate.variant(small_cube_id, true, R180, R270));
}
}

View File

@@ -0,0 +1,69 @@
package fr.adrien1106.reframed.generator.block;
import fr.adrien1106.reframed.ReFramed;
import fr.adrien1106.reframed.generator.BlockStateProvider;
import fr.adrien1106.reframed.generator.GBlockstate;
import fr.adrien1106.reframed.generator.RecipeSetter;
import net.fabricmc.fabric.api.datagen.v1.provider.FabricRecipeProvider;
import net.minecraft.block.Block;
import net.minecraft.data.client.BlockStateSupplier;
import net.minecraft.data.client.MultipartBlockStateSupplier;
import net.minecraft.data.server.recipe.RecipeExporter;
import net.minecraft.data.server.recipe.RecipeProvider;
import net.minecraft.data.server.recipe.ShapelessRecipeJsonBuilder;
import net.minecraft.item.ItemConvertible;
import net.minecraft.recipe.book.RecipeCategory;
import net.minecraft.util.Identifier;
import static fr.adrien1106.reframed.util.blocks.BlockProperties.EDGE;
import static fr.adrien1106.reframed.util.blocks.Edge.*;
import static fr.adrien1106.reframed.util.blocks.Edge.SOUTH_UP;
import static net.minecraft.data.client.VariantSettings.Rotation.*;
public class SmallCubesStep implements RecipeSetter, BlockStateProvider {
@Override
public void setRecipe(RecipeExporter exporter, ItemConvertible convertible) {
RecipeProvider.offerStonecuttingRecipe(exporter, RecipeCategory.BUILDING_BLOCKS, convertible, ReFramed.CUBE, 4);
ShapelessRecipeJsonBuilder
.create(RecipeCategory.BUILDING_BLOCKS, convertible)
.input(ReFramed.SMALL_CUBE, 2)
.criterion(FabricRecipeProvider.hasItem(ReFramed.CUBE), FabricRecipeProvider.conditionsFromItem(ReFramed.CUBE))
.criterion(FabricRecipeProvider.hasItem(convertible), FabricRecipeProvider.conditionsFromItem(convertible))
.offerTo(exporter);
}
@Override
public BlockStateSupplier getMultipart(Block block) {
Identifier model_id = ReFramed.id("small_cubes_step_special");
Identifier reverse_model_id = ReFramed.id("small_cubes_step_reverse_special");
return MultipartBlockStateSupplier.create(block)
/* X AXIS */
.with(GBlockstate.when(EDGE, DOWN_EAST),
GBlockstate.variant(model_id, true, R0, R0))
.with(GBlockstate.when(EDGE, EAST_UP),
GBlockstate.variant(reverse_model_id, true, R180, R0))
.with(GBlockstate.when(EDGE, UP_WEST),
GBlockstate.variant(model_id, true, R180, R180))
.with(GBlockstate.when(EDGE, WEST_DOWN),
GBlockstate.variant(reverse_model_id, true, R0, R180))
/* Y AXIS */
.with(GBlockstate.when(EDGE, EAST_SOUTH),
GBlockstate.variant(model_id, true, R90, R0))
.with(GBlockstate.when(EDGE, SOUTH_WEST),
GBlockstate.variant(model_id, true, R90, R90))
.with(GBlockstate.when(EDGE, WEST_NORTH),
GBlockstate.variant(model_id, true, R90, R180))
.with(GBlockstate.when(EDGE, NORTH_EAST),
GBlockstate.variant(model_id, true, R90, R270))
/* Z AXIS */
.with(GBlockstate.when(EDGE, DOWN_SOUTH),
GBlockstate.variant(reverse_model_id, true, R0, R90))
.with(GBlockstate.when(EDGE, NORTH_DOWN),
GBlockstate.variant(model_id, true, R0, R270))
.with(GBlockstate.when(EDGE, UP_NORTH),
GBlockstate.variant(reverse_model_id, true, R180, R270))
.with(GBlockstate.when(EDGE, SOUTH_UP),
GBlockstate.variant(model_id, true, R180, R90));
}
}

View File

@@ -0,0 +1,267 @@
package fr.adrien1106.reframed.generator.block;
import fr.adrien1106.reframed.ReFramed;
import fr.adrien1106.reframed.generator.BlockStateProvider;
import fr.adrien1106.reframed.generator.GBlockstate;
import fr.adrien1106.reframed.generator.RecipeSetter;
import net.fabricmc.fabric.api.datagen.v1.provider.FabricRecipeProvider;
import net.minecraft.block.Block;
import net.minecraft.data.client.MultipartBlockStateSupplier;
import net.minecraft.data.client.When;
import net.minecraft.data.server.recipe.RecipeExporter;
import net.minecraft.data.server.recipe.RecipeProvider;
import net.minecraft.data.server.recipe.ShapedRecipeJsonBuilder;
import net.minecraft.item.ItemConvertible;
import net.minecraft.recipe.book.RecipeCategory;
import net.minecraft.util.Identifier;
import static fr.adrien1106.reframed.util.blocks.BlockProperties.EDGE;
import static fr.adrien1106.reframed.util.blocks.BlockProperties.STAIR_SHAPE;
import static fr.adrien1106.reframed.util.blocks.Edge.*;
import static fr.adrien1106.reframed.util.blocks.StairShape.*;
import static net.minecraft.data.client.VariantSettings.Rotation.*;
public class Stair implements RecipeSetter, BlockStateProvider {
@Override
public void setRecipe(RecipeExporter exporter, ItemConvertible convertible) {
RecipeProvider.offerStonecuttingRecipe(exporter, RecipeCategory.BUILDING_BLOCKS, convertible, ReFramed.CUBE);
ShapedRecipeJsonBuilder
.create(RecipeCategory.BUILDING_BLOCKS, convertible, 4)
.pattern("I ")
.pattern("II ")
.pattern("III")
.input('I', ReFramed.CUBE)
.criterion(FabricRecipeProvider.hasItem(ReFramed.CUBE), FabricRecipeProvider.conditionsFromItem(ReFramed.CUBE))
.criterion(FabricRecipeProvider.hasItem(convertible), FabricRecipeProvider.conditionsFromItem(convertible))
.offerTo(exporter);
}
@Override
public MultipartBlockStateSupplier getMultipart(Block block) {
return getMultipart(block, false);
}
public static MultipartBlockStateSupplier getMultipart(Block block, boolean is_double) {
String infix = is_double ? "s_cube" : "";
Identifier straight_id = ReFramed.id("stair" + infix + "_special");
Identifier double_outer_id = ReFramed.id("outers_stair" + infix + "_special");
Identifier inner_id = ReFramed.id("inner_stair" + infix + "_special");
Identifier outer_id = ReFramed.id("outer_stair" + infix + "_special");
Identifier outer_side_id = ReFramed.id("outer_side_stair" + infix + "_special");
return MultipartBlockStateSupplier.create(block)
/* STRAIGHT X AXIS */
.with(GBlockstate.when(EDGE, DOWN_EAST, STAIR_SHAPE, STRAIGHT),
GBlockstate.variant(straight_id, true, R0, R0))
.with(GBlockstate.when(EDGE, EAST_UP, STAIR_SHAPE, STRAIGHT),
GBlockstate.variant(straight_id, true, R180, R0))
.with(GBlockstate.when(EDGE, UP_WEST, STAIR_SHAPE, STRAIGHT),
GBlockstate.variant(straight_id, true, R180, R180))
.with(GBlockstate.when(EDGE, WEST_DOWN, STAIR_SHAPE, STRAIGHT),
GBlockstate.variant(straight_id, true, R0, R180))
/* STRAIGHT Y AXIS */
.with(GBlockstate.when(EDGE, EAST_SOUTH, STAIR_SHAPE, STRAIGHT),
GBlockstate.variant(straight_id, true, R90, R0))
.with(GBlockstate.when(EDGE, SOUTH_WEST, STAIR_SHAPE, STRAIGHT),
GBlockstate.variant(straight_id, true, R90, R90))
.with(GBlockstate.when(EDGE, WEST_NORTH, STAIR_SHAPE, STRAIGHT),
GBlockstate.variant(straight_id, true, R90, R180))
.with(GBlockstate.when(EDGE, NORTH_EAST, STAIR_SHAPE, STRAIGHT),
GBlockstate.variant(straight_id, true, R90, R270))
/* STRAIGHT Z AXIS */
.with(GBlockstate.when(EDGE, DOWN_SOUTH, STAIR_SHAPE, STRAIGHT),
GBlockstate.variant(straight_id, true, R0, R90))
.with(GBlockstate.when(EDGE, NORTH_DOWN, STAIR_SHAPE, STRAIGHT),
GBlockstate.variant(straight_id, true, R0, R270))
.with(GBlockstate.when(EDGE, UP_NORTH, STAIR_SHAPE, STRAIGHT),
GBlockstate.variant(straight_id, true, R180, R270))
.with(GBlockstate.when(EDGE, SOUTH_UP, STAIR_SHAPE, STRAIGHT),
GBlockstate.variant(straight_id, true, R180, R90))
/* INNER BOTTOM */
.with(When.anyOf(
GBlockstate.when(EDGE, NORTH_DOWN, STAIR_SHAPE, INNER_RIGHT),
GBlockstate.when(EDGE, WEST_NORTH, STAIR_SHAPE, INNER_RIGHT),
GBlockstate.when(EDGE, WEST_DOWN, STAIR_SHAPE, INNER_RIGHT)),
GBlockstate.variant(inner_id, true, R0, R180))
.with(When.anyOf(
GBlockstate.when(EDGE, NORTH_DOWN, STAIR_SHAPE, INNER_LEFT),
GBlockstate.when(EDGE, NORTH_EAST, STAIR_SHAPE, INNER_RIGHT),
GBlockstate.when(EDGE, DOWN_EAST, STAIR_SHAPE, INNER_RIGHT)),
GBlockstate.variant(inner_id, true, R0, R270))
.with(When.anyOf(
GBlockstate.when(EDGE, DOWN_SOUTH, STAIR_SHAPE, INNER_LEFT),
GBlockstate.when(EDGE, EAST_SOUTH, STAIR_SHAPE, INNER_RIGHT),
GBlockstate.when(EDGE, DOWN_EAST, STAIR_SHAPE, INNER_LEFT)),
GBlockstate.variant(inner_id, true, R0, R0))
.with(When.anyOf(
GBlockstate.when(EDGE, DOWN_SOUTH, STAIR_SHAPE, INNER_RIGHT),
GBlockstate.when(EDGE, SOUTH_WEST, STAIR_SHAPE, INNER_RIGHT),
GBlockstate.when(EDGE, WEST_DOWN, STAIR_SHAPE, INNER_LEFT)),
GBlockstate.variant(inner_id, true, R0, R90))
/* INNER TOP */
.with(When.anyOf(
GBlockstate.when(EDGE, EAST_UP, STAIR_SHAPE, INNER_RIGHT),
GBlockstate.when(EDGE, NORTH_EAST, STAIR_SHAPE, INNER_LEFT),
GBlockstate.when(EDGE, UP_NORTH, STAIR_SHAPE, INNER_LEFT)),
GBlockstate.variant(inner_id, true, R180, R0))
.with(When.anyOf(
GBlockstate.when(EDGE, EAST_UP, STAIR_SHAPE, INNER_LEFT),
GBlockstate.when(EDGE, EAST_SOUTH, STAIR_SHAPE, INNER_LEFT),
GBlockstate.when(EDGE, SOUTH_UP, STAIR_SHAPE, INNER_LEFT)),
GBlockstate.variant(inner_id, true, R180, R90))
.with(When.anyOf(
GBlockstate.when(EDGE, SOUTH_UP, STAIR_SHAPE, INNER_RIGHT),
GBlockstate.when(EDGE, SOUTH_WEST, STAIR_SHAPE, INNER_LEFT),
GBlockstate.when(EDGE, UP_WEST, STAIR_SHAPE, INNER_LEFT)),
GBlockstate.variant(inner_id, true, R180, R180))
.with(When.anyOf(
GBlockstate.when(EDGE, UP_NORTH, STAIR_SHAPE, INNER_RIGHT),
GBlockstate.when(EDGE, WEST_NORTH, STAIR_SHAPE, INNER_LEFT),
GBlockstate.when(EDGE, UP_WEST, STAIR_SHAPE, INNER_RIGHT)),
GBlockstate.variant(inner_id, true, R180, R270))
/* OUTER BOTTOM */
.with(When.anyOf(
GBlockstate.when(EDGE, DOWN_SOUTH, STAIR_SHAPE, SECOND_OUTER_LEFT),
GBlockstate.when(EDGE, DOWN_EAST, STAIR_SHAPE, SECOND_OUTER_LEFT)),
GBlockstate.variant(outer_id, true, R0, R0))
.with(When.anyOf(
GBlockstate.when(EDGE, DOWN_SOUTH, STAIR_SHAPE, SECOND_OUTER_RIGHT),
GBlockstate.when(EDGE, WEST_DOWN, STAIR_SHAPE, FIRST_OUTER_LEFT)),
GBlockstate.variant(outer_id, true, R0, R90))
.with(When.anyOf(
GBlockstate.when(EDGE, NORTH_DOWN, STAIR_SHAPE, FIRST_OUTER_RIGHT),
GBlockstate.when(EDGE, WEST_DOWN, STAIR_SHAPE, FIRST_OUTER_RIGHT)),
GBlockstate.variant(outer_id, true, R0, R180))
.with(When.anyOf(
GBlockstate.when(EDGE, NORTH_DOWN, STAIR_SHAPE, FIRST_OUTER_LEFT),
GBlockstate.when(EDGE, DOWN_EAST, STAIR_SHAPE, SECOND_OUTER_RIGHT)),
GBlockstate.variant(outer_id, true, R0, R270))
/* OUTER TOP */
.with(When.anyOf(
GBlockstate.when(EDGE, UP_NORTH, STAIR_SHAPE, SECOND_OUTER_LEFT),
GBlockstate.when(EDGE, EAST_UP, STAIR_SHAPE, FIRST_OUTER_RIGHT)),
GBlockstate.variant(outer_id, true, R180, R0))
.with(When.anyOf(
GBlockstate.when(EDGE, SOUTH_UP, STAIR_SHAPE, FIRST_OUTER_LEFT),
GBlockstate.when(EDGE, EAST_UP, STAIR_SHAPE, FIRST_OUTER_LEFT)),
GBlockstate.variant(outer_id, true, R180, R90))
.with(When.anyOf(
GBlockstate.when(EDGE, SOUTH_UP, STAIR_SHAPE, FIRST_OUTER_RIGHT),
GBlockstate.when(EDGE, UP_WEST, STAIR_SHAPE, SECOND_OUTER_LEFT)),
GBlockstate.variant(outer_id, true, R180, R180))
.with(When.anyOf(
GBlockstate.when(EDGE, UP_NORTH, STAIR_SHAPE, SECOND_OUTER_RIGHT),
GBlockstate.when(EDGE, UP_WEST, STAIR_SHAPE, SECOND_OUTER_RIGHT)),
GBlockstate.variant(outer_id, true, R180, R270))
/* OUTER EAST */
.with(When.anyOf(
GBlockstate.when(EDGE, EAST_SOUTH, STAIR_SHAPE, SECOND_OUTER_RIGHT),
GBlockstate.when(EDGE, DOWN_EAST, STAIR_SHAPE, FIRST_OUTER_LEFT)),
GBlockstate.variant(outer_side_id, true, R0, R0))
.with(When.anyOf(
GBlockstate.when(EDGE, EAST_SOUTH, STAIR_SHAPE, SECOND_OUTER_LEFT),
GBlockstate.when(EDGE, EAST_UP, STAIR_SHAPE, SECOND_OUTER_LEFT)),
GBlockstate.variant(outer_side_id, true, R90, R0))
.with(When.anyOf(
GBlockstate.when(EDGE, NORTH_EAST, STAIR_SHAPE, FIRST_OUTER_LEFT),
GBlockstate.when(EDGE, EAST_UP, STAIR_SHAPE, SECOND_OUTER_RIGHT)),
GBlockstate.variant(outer_side_id, true, R180, R0))
.with(When.anyOf(
GBlockstate.when(EDGE, NORTH_EAST, STAIR_SHAPE, FIRST_OUTER_RIGHT),
GBlockstate.when(EDGE, DOWN_EAST, STAIR_SHAPE, FIRST_OUTER_RIGHT)),
GBlockstate.variant(outer_side_id, true, R270, R0))
/* OUTER SOUTH */
.with(When.anyOf(
GBlockstate.when(EDGE, SOUTH_WEST, STAIR_SHAPE, SECOND_OUTER_RIGHT),
GBlockstate.when(EDGE, DOWN_SOUTH, STAIR_SHAPE, FIRST_OUTER_RIGHT)),
GBlockstate.variant(outer_side_id, true, R0, R90))
.with(When.anyOf(
GBlockstate.when(EDGE, SOUTH_WEST, STAIR_SHAPE, SECOND_OUTER_LEFT),
GBlockstate.when(EDGE, SOUTH_UP, STAIR_SHAPE, SECOND_OUTER_RIGHT)),
GBlockstate.variant(outer_side_id, true, R90, R90))
.with(When.anyOf(
GBlockstate.when(EDGE, EAST_SOUTH, STAIR_SHAPE, FIRST_OUTER_LEFT),
GBlockstate.when(EDGE, SOUTH_UP, STAIR_SHAPE, SECOND_OUTER_LEFT)),
GBlockstate.variant(outer_side_id, true, R180, R90))
.with(When.anyOf(
GBlockstate.when(EDGE, EAST_SOUTH, STAIR_SHAPE, FIRST_OUTER_RIGHT),
GBlockstate.when(EDGE, DOWN_SOUTH, STAIR_SHAPE, FIRST_OUTER_LEFT)),
GBlockstate.variant(outer_side_id, true, R270, R90))
/* OUTER WEST */
.with(When.anyOf(
GBlockstate.when(EDGE, WEST_NORTH, STAIR_SHAPE, SECOND_OUTER_RIGHT),
GBlockstate.when(EDGE, WEST_DOWN, STAIR_SHAPE, SECOND_OUTER_RIGHT)),
GBlockstate.variant(outer_side_id, true, R0, R180))
.with(When.anyOf(
GBlockstate.when(EDGE, WEST_NORTH, STAIR_SHAPE, SECOND_OUTER_LEFT),
GBlockstate.when(EDGE, UP_WEST, STAIR_SHAPE, FIRST_OUTER_RIGHT)),
GBlockstate.variant(outer_side_id, true, R90, R180))
.with(When.anyOf(
GBlockstate.when(EDGE, SOUTH_WEST, STAIR_SHAPE, FIRST_OUTER_LEFT),
GBlockstate.when(EDGE, UP_WEST, STAIR_SHAPE, FIRST_OUTER_LEFT)),
GBlockstate.variant(outer_side_id, true, R180, R180))
.with(When.anyOf(
GBlockstate.when(EDGE, SOUTH_WEST, STAIR_SHAPE, FIRST_OUTER_RIGHT),
GBlockstate.when(EDGE, WEST_DOWN, STAIR_SHAPE, SECOND_OUTER_LEFT)),
GBlockstate.variant(outer_side_id, true, R270, R180))
/* OUTER NORTH */
.with(When.anyOf(
GBlockstate.when(EDGE, NORTH_EAST, STAIR_SHAPE, SECOND_OUTER_RIGHT),
GBlockstate.when(EDGE, NORTH_DOWN, STAIR_SHAPE, SECOND_OUTER_LEFT)),
GBlockstate.variant(outer_side_id, true, R0, R270))
.with(When.anyOf(
GBlockstate.when(EDGE, NORTH_EAST, STAIR_SHAPE, SECOND_OUTER_LEFT),
GBlockstate.when(EDGE, UP_NORTH, STAIR_SHAPE, FIRST_OUTER_LEFT)),
GBlockstate.variant(outer_side_id, true, R90, R270))
.with(When.anyOf(
GBlockstate.when(EDGE, WEST_NORTH, STAIR_SHAPE, FIRST_OUTER_LEFT),
GBlockstate.when(EDGE, UP_NORTH, STAIR_SHAPE, FIRST_OUTER_RIGHT)),
GBlockstate.variant(outer_side_id, true, R180, R270))
.with(When.anyOf(
GBlockstate.when(EDGE, WEST_NORTH, STAIR_SHAPE, FIRST_OUTER_RIGHT),
GBlockstate.when(EDGE, NORTH_DOWN, STAIR_SHAPE, SECOND_OUTER_RIGHT)),
GBlockstate.variant(outer_side_id, true, R270, R270))
/* OUTER BOTTOM */
.with(When.anyOf(
GBlockstate.when(EDGE, DOWN_SOUTH, STAIR_SHAPE, OUTER_LEFT),
GBlockstate.when(EDGE, DOWN_EAST, STAIR_SHAPE, OUTER_LEFT),
GBlockstate.when(EDGE, EAST_SOUTH, STAIR_SHAPE, OUTER_RIGHT)),
GBlockstate.variant(double_outer_id, true, R0, R0))
.with(When.anyOf(
GBlockstate.when(EDGE, DOWN_SOUTH, STAIR_SHAPE, OUTER_RIGHT),
GBlockstate.when(EDGE, WEST_DOWN, STAIR_SHAPE, OUTER_LEFT),
GBlockstate.when(EDGE, SOUTH_WEST, STAIR_SHAPE, OUTER_RIGHT)),
GBlockstate.variant(double_outer_id, true, R0, R90))
.with(When.anyOf(
GBlockstate.when(EDGE, NORTH_DOWN, STAIR_SHAPE, OUTER_RIGHT),
GBlockstate.when(EDGE, WEST_DOWN, STAIR_SHAPE, OUTER_RIGHT),
GBlockstate.when(EDGE, WEST_NORTH, STAIR_SHAPE, OUTER_RIGHT)),
GBlockstate.variant(double_outer_id, true, R0, R180))
.with(When.anyOf(
GBlockstate.when(EDGE, NORTH_DOWN, STAIR_SHAPE, OUTER_LEFT),
GBlockstate.when(EDGE, DOWN_EAST, STAIR_SHAPE, OUTER_RIGHT),
GBlockstate.when(EDGE, NORTH_EAST, STAIR_SHAPE, OUTER_RIGHT)),
GBlockstate.variant(double_outer_id, true, R0, R270))
/* OUTER TOP */
.with(When.anyOf(
GBlockstate.when(EDGE, UP_NORTH, STAIR_SHAPE, OUTER_LEFT),
GBlockstate.when(EDGE, EAST_UP, STAIR_SHAPE, OUTER_RIGHT),
GBlockstate.when(EDGE, NORTH_EAST, STAIR_SHAPE, OUTER_LEFT)),
GBlockstate.variant(double_outer_id, true, R180, R0))
.with(When.anyOf(
GBlockstate.when(EDGE, SOUTH_UP, STAIR_SHAPE, OUTER_LEFT),
GBlockstate.when(EDGE, EAST_UP, STAIR_SHAPE, OUTER_LEFT),
GBlockstate.when(EDGE, EAST_SOUTH, STAIR_SHAPE, OUTER_LEFT)),
GBlockstate.variant(double_outer_id, true, R180, R90))
.with(When.anyOf(
GBlockstate.when(EDGE, SOUTH_UP, STAIR_SHAPE, OUTER_RIGHT),
GBlockstate.when(EDGE, UP_WEST, STAIR_SHAPE, OUTER_LEFT),
GBlockstate.when(EDGE, SOUTH_WEST, STAIR_SHAPE, OUTER_LEFT)),
GBlockstate.variant(double_outer_id, true, R180, R180))
.with(When.anyOf(
GBlockstate.when(EDGE, UP_NORTH, STAIR_SHAPE, OUTER_RIGHT),
GBlockstate.when(EDGE, UP_WEST, STAIR_SHAPE, OUTER_RIGHT),
GBlockstate.when(EDGE, WEST_NORTH, STAIR_SHAPE, OUTER_LEFT)),
GBlockstate.variant(double_outer_id, true, R180, R270));
}
}

View File

@@ -0,0 +1,33 @@
package fr.adrien1106.reframed.generator.block;
import fr.adrien1106.reframed.ReFramed;
import fr.adrien1106.reframed.generator.BlockStateProvider;
import fr.adrien1106.reframed.generator.RecipeSetter;
import net.fabricmc.fabric.api.datagen.v1.provider.FabricRecipeProvider;
import net.minecraft.block.Block;
import net.minecraft.data.client.MultipartBlockStateSupplier;
import net.minecraft.data.server.recipe.RecipeExporter;
import net.minecraft.data.server.recipe.RecipeProvider;
import net.minecraft.data.server.recipe.ShapelessRecipeJsonBuilder;
import net.minecraft.item.ItemConvertible;
import net.minecraft.recipe.book.RecipeCategory;
public class StairsCube implements RecipeSetter, BlockStateProvider {
@Override
public void setRecipe(RecipeExporter exporter, ItemConvertible convertible) {
RecipeProvider.offerStonecuttingRecipe(exporter, RecipeCategory.BUILDING_BLOCKS, convertible, ReFramed.CUBE);
ShapelessRecipeJsonBuilder
.create(RecipeCategory.BUILDING_BLOCKS, convertible)
.input(ReFramed.STAIR)
.input(ReFramed.STEP)
.criterion(FabricRecipeProvider.hasItem(ReFramed.CUBE), FabricRecipeProvider.conditionsFromItem(ReFramed.CUBE))
.criterion(FabricRecipeProvider.hasItem(convertible), FabricRecipeProvider.conditionsFromItem(convertible))
.offerTo(exporter);
}
@Override
public MultipartBlockStateSupplier getMultipart(Block block) {
return Stair.getMultipart(block, true);
}
}

View File

@@ -0,0 +1,69 @@
package fr.adrien1106.reframed.generator.block;
import fr.adrien1106.reframed.ReFramed;
import fr.adrien1106.reframed.generator.BlockStateProvider;
import fr.adrien1106.reframed.generator.GBlockstate;
import fr.adrien1106.reframed.generator.RecipeSetter;
import net.fabricmc.fabric.api.datagen.v1.provider.FabricRecipeProvider;
import net.minecraft.block.Block;
import net.minecraft.data.client.BlockStateSupplier;
import net.minecraft.data.client.MultipartBlockStateSupplier;
import net.minecraft.data.server.recipe.RecipeExporter;
import net.minecraft.data.server.recipe.RecipeProvider;
import net.minecraft.data.server.recipe.ShapedRecipeJsonBuilder;
import net.minecraft.item.ItemConvertible;
import net.minecraft.recipe.book.RecipeCategory;
import net.minecraft.util.Identifier;
import static fr.adrien1106.reframed.util.blocks.BlockProperties.EDGE;
import static fr.adrien1106.reframed.util.blocks.Edge.*;
import static fr.adrien1106.reframed.util.blocks.Edge.SOUTH_UP;
import static net.minecraft.data.client.VariantSettings.Rotation.*;
public class Step implements RecipeSetter, BlockStateProvider {
@Override
public void setRecipe(RecipeExporter exporter, ItemConvertible convertible) {
RecipeProvider.offerStonecuttingRecipe(exporter, RecipeCategory.BUILDING_BLOCKS, convertible, ReFramed.CUBE, 4);
ShapedRecipeJsonBuilder
.create(RecipeCategory.BUILDING_BLOCKS, convertible, 8)
.pattern("II")
.input('I', ReFramed.CUBE)
.criterion(FabricRecipeProvider.hasItem(ReFramed.CUBE), FabricRecipeProvider.conditionsFromItem(ReFramed.CUBE))
.criterion(FabricRecipeProvider.hasItem(convertible), FabricRecipeProvider.conditionsFromItem(convertible))
.offerTo(exporter);
}
@Override
public BlockStateSupplier getMultipart(Block block) {
Identifier model_id = ReFramed.id("step_special");
return MultipartBlockStateSupplier.create(block)
/* X AXIS */
.with(GBlockstate.when(EDGE, DOWN_EAST),
GBlockstate.variant(model_id, true, R0, R0))
.with(GBlockstate.when(EDGE, EAST_UP),
GBlockstate.variant(model_id, true, R180, R0))
.with(GBlockstate.when(EDGE, UP_WEST),
GBlockstate.variant(model_id, true, R180, R180))
.with(GBlockstate.when(EDGE, WEST_DOWN),
GBlockstate.variant(model_id, true, R0, R180))
/* Y AXIS */
.with(GBlockstate.when(EDGE, EAST_SOUTH),
GBlockstate.variant(model_id, true, R90, R0))
.with(GBlockstate.when(EDGE, SOUTH_WEST),
GBlockstate.variant(model_id, true, R90, R90))
.with(GBlockstate.when(EDGE, WEST_NORTH),
GBlockstate.variant(model_id, true, R90, R180))
.with(GBlockstate.when(EDGE, NORTH_EAST),
GBlockstate.variant(model_id, true, R90, R270))
/* Z AXIS */
.with(GBlockstate.when(EDGE, DOWN_SOUTH),
GBlockstate.variant(model_id, true, R0, R90))
.with(GBlockstate.when(EDGE, NORTH_DOWN),
GBlockstate.variant(model_id, true, R0, R270))
.with(GBlockstate.when(EDGE, UP_NORTH),
GBlockstate.variant(model_id, true, R180, R270))
.with(GBlockstate.when(EDGE, SOUTH_UP),
GBlockstate.variant(model_id, true, R180, R90));
}
}

View File

@@ -0,0 +1,66 @@
package fr.adrien1106.reframed.generator.block;
import fr.adrien1106.reframed.ReFramed;
import fr.adrien1106.reframed.generator.BlockStateProvider;
import fr.adrien1106.reframed.generator.GBlockstate;
import fr.adrien1106.reframed.generator.RecipeSetter;
import net.fabricmc.fabric.api.datagen.v1.provider.FabricRecipeProvider;
import net.minecraft.block.Block;
import net.minecraft.data.client.MultipartBlockStateSupplier;
import net.minecraft.data.server.recipe.RecipeExporter;
import net.minecraft.data.server.recipe.RecipeProvider;
import net.minecraft.data.server.recipe.ShapelessRecipeJsonBuilder;
import net.minecraft.item.ItemConvertible;
import net.minecraft.recipe.book.RecipeCategory;
import net.minecraft.util.Identifier;
import net.minecraft.util.math.Direction;
import static net.minecraft.data.client.VariantSettings.Rotation.*;
import static net.minecraft.data.client.VariantSettings.Rotation.R270;
import static net.minecraft.state.property.Properties.AXIS;
import static net.minecraft.state.property.Properties.FACING;
public class StepsSlab implements RecipeSetter, BlockStateProvider {
@Override
public void setRecipe(RecipeExporter exporter, ItemConvertible convertible) {
RecipeProvider.offerStonecuttingRecipe(exporter, RecipeCategory.BUILDING_BLOCKS, convertible, ReFramed.CUBE, 2);
ShapelessRecipeJsonBuilder
.create(RecipeCategory.BUILDING_BLOCKS, convertible)
.input(ReFramed.STEP, 2)
.criterion(FabricRecipeProvider.hasItem(ReFramed.CUBE), FabricRecipeProvider.conditionsFromItem(ReFramed.CUBE))
.criterion(FabricRecipeProvider.hasItem(convertible), FabricRecipeProvider.conditionsFromItem(convertible))
.offerTo(exporter);
}
@Override
public MultipartBlockStateSupplier getMultipart(Block block) {
Identifier step_id = ReFramed.id("steps_slab_special");
Identifier step_side_id = ReFramed.id("steps_slab_side_special");
return MultipartBlockStateSupplier.create(block)
.with(GBlockstate.when(FACING, Direction.DOWN, AXIS, Direction.Axis.X),
GBlockstate.variant(step_id, true, R0, R180))
.with(GBlockstate.when(FACING, Direction.DOWN, AXIS, Direction.Axis.Z),
GBlockstate.variant(step_id, true, R0, R270))
.with(GBlockstate.when(FACING, Direction.UP, AXIS, Direction.Axis.X),
GBlockstate.variant(step_id, true, R180, R180))
.with(GBlockstate.when(FACING, Direction.UP, AXIS, Direction.Axis.Z),
GBlockstate.variant(step_id, true, R180, R270))
.with(GBlockstate.when(FACING, Direction.EAST, AXIS, Direction.Axis.Z),
GBlockstate.variant(step_side_id, true, R0, R0))
.with(GBlockstate.when(FACING, Direction.EAST, AXIS, Direction.Axis.Y),
GBlockstate.variant(step_side_id, true, R90, R0))
.with(GBlockstate.when(FACING, Direction.SOUTH, AXIS, Direction.Axis.X),
GBlockstate.variant(step_side_id, true, R180, R90))
.with(GBlockstate.when(FACING, Direction.SOUTH, AXIS, Direction.Axis.Y),
GBlockstate.variant(step_side_id, true, R90, R90))
.with(GBlockstate.when(FACING, Direction.WEST, AXIS, Direction.Axis.Z),
GBlockstate.variant(step_side_id, true, R180, R180))
.with(GBlockstate.when(FACING, Direction.WEST, AXIS, Direction.Axis.Y),
GBlockstate.variant(step_side_id, true, R90, R180))
.with(GBlockstate.when(FACING, Direction.NORTH, AXIS, Direction.Axis.X),
GBlockstate.variant(step_side_id, true, R0, R270))
.with(GBlockstate.when(FACING, Direction.NORTH, AXIS, Direction.Axis.Y),
GBlockstate.variant(step_side_id, true, R90, R270));
}
}

View File

@@ -0,0 +1,788 @@
package fr.adrien1106.reframed.generator.block;
import fr.adrien1106.reframed.ReFramed;
import fr.adrien1106.reframed.generator.BlockStateProvider;
import fr.adrien1106.reframed.generator.GBlockstate;
import fr.adrien1106.reframed.generator.RecipeSetter;
import fr.adrien1106.reframed.generator.TagGetter;
import net.fabricmc.fabric.api.datagen.v1.provider.FabricRecipeProvider;
import net.minecraft.block.Block;
import net.minecraft.data.client.BlockStateSupplier;
import net.minecraft.data.client.MultipartBlockStateSupplier;
import net.minecraft.data.server.recipe.RecipeExporter;
import net.minecraft.data.server.recipe.RecipeProvider;
import net.minecraft.data.server.recipe.ShapedRecipeJsonBuilder;
import net.minecraft.item.ItemConvertible;
import net.minecraft.recipe.book.RecipeCategory;
import net.minecraft.registry.tag.BlockTags;
import net.minecraft.registry.tag.TagKey;
import net.minecraft.util.Identifier;
import java.util.List;
import static net.minecraft.block.enums.WallShape.*;
import static net.minecraft.data.client.VariantSettings.Rotation.*;
import static net.minecraft.state.property.Properties.*;
public class Wall implements RecipeSetter, TagGetter, BlockStateProvider {
@Override
public void setRecipe(RecipeExporter exporter, ItemConvertible convertible) {
RecipeProvider.offerStonecuttingRecipe(exporter, RecipeCategory.BUILDING_BLOCKS, convertible, ReFramed.CUBE, 1);
ShapedRecipeJsonBuilder
.create(RecipeCategory.BUILDING_BLOCKS, convertible, 4)
.pattern("III")
.pattern("III")
.input('I', ReFramed.CUBE)
.criterion(FabricRecipeProvider.hasItem(ReFramed.CUBE), FabricRecipeProvider.conditionsFromItem(ReFramed.CUBE))
.criterion(FabricRecipeProvider.hasItem(convertible), FabricRecipeProvider.conditionsFromItem(convertible))
.offerTo(exporter);
}
@Override
public List<TagKey<Block>> getTags() {
return List.of(BlockTags.WALLS);
}
@Override
public BlockStateSupplier getMultipart(Block block) {
Identifier
side_low = ReFramed.id("wall_side_low_special"),
side_tall = ReFramed.id("wall_side_tall_special"),
pillar_low = ReFramed.id("wall_pillar_low_special"),
pillar_tall = ReFramed.id("wall_pillar_tall_special"),
pillar_none = ReFramed.id("wall_pillar_none_special"),
low_e = ReFramed.id("wall_low_e_special"),
tall_e = ReFramed.id("wall_tall_e_special"),
low_i = ReFramed.id("wall_low_i_special"),
tall_i = ReFramed.id("wall_tall_i_special"),
low_tall_i = ReFramed.id("wall_low_tall_i_special"),
low_c = ReFramed.id("wall_low_c_special"),
tall_c = ReFramed.id("wall_tall_c_special"),
low_tall_c = ReFramed.id("wall_low_tall_c_special"),
tall_low_c = ReFramed.id("wall_tall_low_c_special"),
low_t = ReFramed.id("wall_low_t_special"),
tall_t = ReFramed.id("wall_tall_t_special"),
tall_low_c_t = ReFramed.id("wall_tall_low_c_t_special"),
tall_i_low_t = ReFramed.id("wall_tall_i_low_t_special"),
low_i_tall_t = ReFramed.id("wall_low_i_tall_t_special"),
low_tall_c_t = ReFramed.id("wall_low_tall_c_t_special"),
low_c_tall_t = ReFramed.id("wall_low_c_tall_t_special"),
tall_c_low_t = ReFramed.id("wall_tall_c_low_t_special"),
tall_i_low_i_x = ReFramed.id("wall_tall_i_low_i_x_special"),
tall_low_t_x = ReFramed.id("wall_tall_low_t_x_special"),
tall_c_low_c_x = ReFramed.id("wall_tall_c_low_c_x_special"),
tall_t_low_x = ReFramed.id("wall_tall_t_low_x_special");
return MultipartBlockStateSupplier.create(block)
// PILLAR CORE
.with(GBlockstate.when(UP, true),
GBlockstate.variant(ReFramed.id("wall_core_special"), true, R0, R0))
// LOW
.with(GBlockstate.when(NORTH_WALL_SHAPE, LOW),
GBlockstate.variant(side_low, true, R0, R0))
.with(GBlockstate.when(EAST_WALL_SHAPE, LOW),
GBlockstate.variant(side_low, true, R0, R90))
.with(GBlockstate.when(SOUTH_WALL_SHAPE, LOW),
GBlockstate.variant(side_low, true, R0, R180))
.with(GBlockstate.when(WEST_WALL_SHAPE, LOW),
GBlockstate.variant(side_low, true, R0, R270))
// TALL
.with(GBlockstate.when(NORTH_WALL_SHAPE, TALL),
GBlockstate.variant(side_tall, true, R0, R0))
.with(GBlockstate.when(EAST_WALL_SHAPE, TALL),
GBlockstate.variant(side_tall, true, R0, R90))
.with(GBlockstate.when(SOUTH_WALL_SHAPE, TALL),
GBlockstate.variant(side_tall, true, R0, R180))
.with(GBlockstate.when(WEST_WALL_SHAPE, TALL),
GBlockstate.variant(side_tall, true, R0, R270))
// PILLAR LOW
.with(GBlockstate.when(NORTH_WALL_SHAPE, LOW, UP, true),
GBlockstate.variant(pillar_low, true, R0, R0))
.with(GBlockstate.when(EAST_WALL_SHAPE, LOW, UP, true),
GBlockstate.variant(pillar_low, true, R0, R90))
.with(GBlockstate.when(SOUTH_WALL_SHAPE, LOW, UP, true),
GBlockstate.variant(pillar_low, true, R0, R180))
.with(GBlockstate.when(WEST_WALL_SHAPE, LOW, UP, true),
GBlockstate.variant(pillar_low, true, R0, R270))
// PILLAR TALL
.with(GBlockstate.when(NORTH_WALL_SHAPE, TALL, UP, true),
GBlockstate.variant(pillar_tall, true, R0, R0))
.with(GBlockstate.when(EAST_WALL_SHAPE, TALL, UP, true),
GBlockstate.variant(pillar_tall, true, R0, R90))
.with(GBlockstate.when(SOUTH_WALL_SHAPE, TALL, UP, true),
GBlockstate.variant(pillar_tall, true, R0, R180))
.with(GBlockstate.when(WEST_WALL_SHAPE, TALL, UP, true),
GBlockstate.variant(pillar_tall, true, R0, R270))
// PILLAR NONE
.with(GBlockstate.when(NORTH_WALL_SHAPE, NONE, UP, true),
GBlockstate.variant(pillar_none, true, R0, R0))
.with(GBlockstate.when(EAST_WALL_SHAPE, NONE, UP, true),
GBlockstate.variant(pillar_none, true, R0, R90))
.with(GBlockstate.when(SOUTH_WALL_SHAPE, NONE, UP, true),
GBlockstate.variant(pillar_none, true, R0, R180))
.with(GBlockstate.when(WEST_WALL_SHAPE, NONE, UP, true),
GBlockstate.variant(pillar_none, true, R0, R270))
// JUNCTION LOW
.with(GBlockstate.when(
NORTH_WALL_SHAPE, LOW,
EAST_WALL_SHAPE, NONE,
SOUTH_WALL_SHAPE, NONE,
WEST_WALL_SHAPE, NONE,
UP, false
),
GBlockstate.variant(low_e, true, R0, R0))
.with(GBlockstate.when(
NORTH_WALL_SHAPE, NONE,
EAST_WALL_SHAPE, LOW,
SOUTH_WALL_SHAPE, NONE,
WEST_WALL_SHAPE, NONE,
UP, false
),
GBlockstate.variant(low_e, true, R0, R90))
.with(GBlockstate.when(
NORTH_WALL_SHAPE, NONE,
EAST_WALL_SHAPE, NONE,
SOUTH_WALL_SHAPE, LOW,
WEST_WALL_SHAPE, NONE,
UP, false
),
GBlockstate.variant(low_e, true, R0, R180))
.with(GBlockstate.when(
NORTH_WALL_SHAPE, NONE,
EAST_WALL_SHAPE, NONE,
SOUTH_WALL_SHAPE, NONE,
WEST_WALL_SHAPE, LOW,
UP, false
),
GBlockstate.variant(low_e, true, R0, R270))
// JUNCTION TALL
.with(GBlockstate.when(
NORTH_WALL_SHAPE, TALL,
EAST_WALL_SHAPE, NONE,
SOUTH_WALL_SHAPE, NONE,
WEST_WALL_SHAPE, NONE,
UP, false
),
GBlockstate.variant(tall_e, true, R0, R0))
.with(GBlockstate.when(
NORTH_WALL_SHAPE, NONE,
EAST_WALL_SHAPE, TALL,
SOUTH_WALL_SHAPE, NONE,
WEST_WALL_SHAPE, NONE,
UP, false
),
GBlockstate.variant(tall_e, true, R0, R90))
.with(GBlockstate.when(
NORTH_WALL_SHAPE, NONE,
EAST_WALL_SHAPE, NONE,
SOUTH_WALL_SHAPE, TALL,
WEST_WALL_SHAPE, NONE,
UP, false
),
GBlockstate.variant(tall_e, true, R0, R180))
.with(GBlockstate.when(
NORTH_WALL_SHAPE, NONE,
EAST_WALL_SHAPE, NONE,
SOUTH_WALL_SHAPE, NONE,
WEST_WALL_SHAPE, TALL,
UP, false
),
GBlockstate.variant(tall_e, true, R0, R270))
// JUNCTION LOW I
.with(GBlockstate.when(
NORTH_WALL_SHAPE, LOW,
EAST_WALL_SHAPE, NONE,
SOUTH_WALL_SHAPE, LOW,
WEST_WALL_SHAPE, NONE,
UP, false
),
GBlockstate.variant(low_i, true, R0, R0))
.with(GBlockstate.when(
NORTH_WALL_SHAPE, NONE,
EAST_WALL_SHAPE, LOW,
SOUTH_WALL_SHAPE, NONE,
WEST_WALL_SHAPE, LOW,
UP, false
),
GBlockstate.variant(low_i, true, R0, R90))
// JUNCTION TALL I
.with(GBlockstate.when(
NORTH_WALL_SHAPE, TALL,
EAST_WALL_SHAPE, NONE,
SOUTH_WALL_SHAPE, TALL,
WEST_WALL_SHAPE, NONE,
UP, false
),
GBlockstate.variant(tall_i, true, R0, R0))
.with(GBlockstate.when(
NORTH_WALL_SHAPE, NONE,
EAST_WALL_SHAPE, TALL,
SOUTH_WALL_SHAPE, NONE,
WEST_WALL_SHAPE, TALL,
UP, false
),
GBlockstate.variant(tall_i, true, R0, R90))
// JUNCTION LOW TALL I
.with(GBlockstate.when(
NORTH_WALL_SHAPE, LOW,
EAST_WALL_SHAPE, NONE,
SOUTH_WALL_SHAPE, TALL,
WEST_WALL_SHAPE, NONE,
UP, false
),
GBlockstate.variant(low_tall_i, true, R0, R0))
.with(GBlockstate.when(
NORTH_WALL_SHAPE, NONE,
EAST_WALL_SHAPE, LOW,
SOUTH_WALL_SHAPE, NONE,
WEST_WALL_SHAPE, TALL,
UP, false
),
GBlockstate.variant(low_tall_i, true, R0, R90))
.with(GBlockstate.when(
NORTH_WALL_SHAPE, TALL,
EAST_WALL_SHAPE, NONE,
SOUTH_WALL_SHAPE, LOW,
WEST_WALL_SHAPE, NONE,
UP, false
),
GBlockstate.variant(low_tall_i, true, R0, R180))
.with(GBlockstate.when(
NORTH_WALL_SHAPE, NONE,
EAST_WALL_SHAPE, TALL,
SOUTH_WALL_SHAPE, NONE,
WEST_WALL_SHAPE, LOW,
UP, false
),
GBlockstate.variant(low_tall_i, true, R0, R270))
// JUNCTION LOW C
.with(GBlockstate.when(
NORTH_WALL_SHAPE, LOW,
EAST_WALL_SHAPE, NONE,
SOUTH_WALL_SHAPE, NONE,
WEST_WALL_SHAPE, LOW,
UP, false
),
GBlockstate.variant(low_c, true, R0, R0))
.with(GBlockstate.when(
NORTH_WALL_SHAPE, LOW,
EAST_WALL_SHAPE, LOW,
SOUTH_WALL_SHAPE, NONE,
WEST_WALL_SHAPE, NONE,
UP, false
),
GBlockstate.variant(low_c, true, R0, R90))
.with(GBlockstate.when(
NORTH_WALL_SHAPE, NONE,
EAST_WALL_SHAPE, LOW,
SOUTH_WALL_SHAPE, LOW,
WEST_WALL_SHAPE, NONE,
UP, false
),
GBlockstate.variant(low_c, true, R0, R180))
.with(GBlockstate.when(
NORTH_WALL_SHAPE, NONE,
EAST_WALL_SHAPE, NONE,
SOUTH_WALL_SHAPE, LOW,
WEST_WALL_SHAPE, LOW,
UP, false
),
GBlockstate.variant(low_c, true, R0, R270))
// JUNCTION TALL C
.with(GBlockstate.when(
NORTH_WALL_SHAPE, TALL,
EAST_WALL_SHAPE, NONE,
SOUTH_WALL_SHAPE, NONE,
WEST_WALL_SHAPE, TALL,
UP, false
),
GBlockstate.variant(tall_c, true, R0, R0))
.with(GBlockstate.when(
NORTH_WALL_SHAPE, TALL,
EAST_WALL_SHAPE, TALL,
SOUTH_WALL_SHAPE, NONE,
WEST_WALL_SHAPE, NONE,
UP, false
),
GBlockstate.variant(tall_c, true, R0, R90))
.with(GBlockstate.when(
NORTH_WALL_SHAPE, NONE,
EAST_WALL_SHAPE, TALL,
SOUTH_WALL_SHAPE, TALL,
WEST_WALL_SHAPE, NONE,
UP, false
),
GBlockstate.variant(tall_c, true, R0, R180))
.with(GBlockstate.when(
NORTH_WALL_SHAPE, NONE,
EAST_WALL_SHAPE, NONE,
SOUTH_WALL_SHAPE, TALL,
WEST_WALL_SHAPE, TALL,
UP, false
),
GBlockstate.variant(tall_c, true, R0, R270))
// JUNCTION LOW TALL C
.with(GBlockstate.when(
NORTH_WALL_SHAPE, LOW,
EAST_WALL_SHAPE, NONE,
SOUTH_WALL_SHAPE, NONE,
WEST_WALL_SHAPE, TALL,
UP, false
),
GBlockstate.variant(low_tall_c, true, R0, R0))
.with(GBlockstate.when(
NORTH_WALL_SHAPE, TALL,
EAST_WALL_SHAPE, LOW,
SOUTH_WALL_SHAPE, NONE,
WEST_WALL_SHAPE, NONE,
UP, false
),
GBlockstate.variant(low_tall_c, true, R0, R90))
.with(GBlockstate.when(
NORTH_WALL_SHAPE, NONE,
EAST_WALL_SHAPE, TALL,
SOUTH_WALL_SHAPE, LOW,
WEST_WALL_SHAPE, NONE,
UP, false
),
GBlockstate.variant(low_tall_c, true, R0, R180))
.with(GBlockstate.when(
NORTH_WALL_SHAPE, NONE,
EAST_WALL_SHAPE, NONE,
SOUTH_WALL_SHAPE, TALL,
WEST_WALL_SHAPE, LOW,
UP, false
),
GBlockstate.variant(low_tall_c, true, R0, R270))
// JUNCTION TALL LOW C
.with(GBlockstate.when(
NORTH_WALL_SHAPE, TALL,
EAST_WALL_SHAPE, NONE,
SOUTH_WALL_SHAPE, NONE,
WEST_WALL_SHAPE, LOW,
UP, false
),
GBlockstate.variant(tall_low_c, true, R0, R0))
.with(GBlockstate.when(
NORTH_WALL_SHAPE, LOW,
EAST_WALL_SHAPE, TALL,
SOUTH_WALL_SHAPE, NONE,
WEST_WALL_SHAPE, NONE,
UP, false
),
GBlockstate.variant(tall_low_c, true, R0, R90))
.with(GBlockstate.when(
NORTH_WALL_SHAPE, NONE,
EAST_WALL_SHAPE, LOW,
SOUTH_WALL_SHAPE, TALL,
WEST_WALL_SHAPE, NONE,
UP, false
),
GBlockstate.variant(tall_low_c, true, R0, R180))
.with(GBlockstate.when(
NORTH_WALL_SHAPE, NONE,
EAST_WALL_SHAPE, NONE,
SOUTH_WALL_SHAPE, LOW,
WEST_WALL_SHAPE, TALL,
UP, false
),
GBlockstate.variant(tall_low_c, true, R0, R270))
// JUNCTION LOW T
.with(GBlockstate.when(
NORTH_WALL_SHAPE, LOW,
EAST_WALL_SHAPE, LOW,
SOUTH_WALL_SHAPE, NONE,
WEST_WALL_SHAPE, LOW,
UP, false
),
GBlockstate.variant(low_t, true, R0, R0))
.with(GBlockstate.when(
NORTH_WALL_SHAPE, LOW,
EAST_WALL_SHAPE, LOW,
SOUTH_WALL_SHAPE, LOW,
WEST_WALL_SHAPE, NONE,
UP, false
),
GBlockstate.variant(low_t, true, R0, R90))
.with(GBlockstate.when(
NORTH_WALL_SHAPE, NONE,
EAST_WALL_SHAPE, LOW,
SOUTH_WALL_SHAPE, LOW,
WEST_WALL_SHAPE, LOW,
UP, false
),
GBlockstate.variant(low_t, true, R0, R180))
.with(GBlockstate.when(
NORTH_WALL_SHAPE, LOW,
EAST_WALL_SHAPE, NONE,
SOUTH_WALL_SHAPE, LOW,
WEST_WALL_SHAPE, LOW,
UP, false
),
GBlockstate.variant(low_t, true, R0, R270))
// JUNCTION TALL T
.with(GBlockstate.when(
NORTH_WALL_SHAPE, TALL,
EAST_WALL_SHAPE, TALL,
SOUTH_WALL_SHAPE, NONE,
WEST_WALL_SHAPE, TALL,
UP, false
),
GBlockstate.variant(tall_t, true, R0, R0))
.with(GBlockstate.when(
NORTH_WALL_SHAPE, TALL,
EAST_WALL_SHAPE, TALL,
SOUTH_WALL_SHAPE, TALL,
WEST_WALL_SHAPE, NONE,
UP, false
),
GBlockstate.variant(tall_t, true, R0, R90))
.with(GBlockstate.when(
NORTH_WALL_SHAPE, NONE,
EAST_WALL_SHAPE, TALL,
SOUTH_WALL_SHAPE, TALL,
WEST_WALL_SHAPE, TALL,
UP, false
),
GBlockstate.variant(tall_t, true, R0, R180))
.with(GBlockstate.when(
NORTH_WALL_SHAPE, TALL,
EAST_WALL_SHAPE, NONE,
SOUTH_WALL_SHAPE, TALL,
WEST_WALL_SHAPE, TALL,
UP, false
),
GBlockstate.variant(tall_t, true, R0, R270))
// JUNCTION TALL LOW C T
.with(GBlockstate.when(
NORTH_WALL_SHAPE, LOW,
EAST_WALL_SHAPE, TALL,
SOUTH_WALL_SHAPE, NONE,
WEST_WALL_SHAPE, LOW,
UP, false
),
GBlockstate.variant(tall_low_c_t, true, R0, R0))
.with(GBlockstate.when(
NORTH_WALL_SHAPE, LOW,
EAST_WALL_SHAPE, LOW,
SOUTH_WALL_SHAPE, TALL,
WEST_WALL_SHAPE, NONE,
UP, false
),
GBlockstate.variant(tall_low_c_t, true, R0, R90))
.with(GBlockstate.when(
NORTH_WALL_SHAPE, NONE,
EAST_WALL_SHAPE, LOW,
SOUTH_WALL_SHAPE, LOW,
WEST_WALL_SHAPE, TALL,
UP, false
),
GBlockstate.variant(tall_low_c_t, true, R0, R180))
.with(GBlockstate.when(
NORTH_WALL_SHAPE, TALL,
EAST_WALL_SHAPE, NONE,
SOUTH_WALL_SHAPE, LOW,
WEST_WALL_SHAPE, LOW,
UP, false
),
GBlockstate.variant(tall_low_c_t, true, R0, R270))
// JUNCTION TALL I LOW T
.with(GBlockstate.when(
NORTH_WALL_SHAPE, LOW,
EAST_WALL_SHAPE, TALL,
SOUTH_WALL_SHAPE, NONE,
WEST_WALL_SHAPE, TALL,
UP, false
),
GBlockstate.variant(tall_i_low_t, true, R0, R0))
.with(GBlockstate.when(
NORTH_WALL_SHAPE, TALL,
EAST_WALL_SHAPE, LOW,
SOUTH_WALL_SHAPE, TALL,
WEST_WALL_SHAPE, NONE,
UP, false
),
GBlockstate.variant(tall_i_low_t, true, R0, R90))
.with(GBlockstate.when(
NORTH_WALL_SHAPE, NONE,
EAST_WALL_SHAPE, TALL,
SOUTH_WALL_SHAPE, LOW,
WEST_WALL_SHAPE, TALL,
UP, false
),
GBlockstate.variant(tall_i_low_t, true, R0, R180))
.with(GBlockstate.when(
NORTH_WALL_SHAPE, TALL,
EAST_WALL_SHAPE, NONE,
SOUTH_WALL_SHAPE, TALL,
WEST_WALL_SHAPE, LOW,
UP, false
),
GBlockstate.variant(tall_i_low_t, true, R0, R270))
// JUNCTION LOW I TALL T
.with(GBlockstate.when(
NORTH_WALL_SHAPE, TALL,
EAST_WALL_SHAPE, LOW,
SOUTH_WALL_SHAPE, NONE,
WEST_WALL_SHAPE, LOW,
UP, false
),
GBlockstate.variant(low_i_tall_t, true, R0, R0))
.with(GBlockstate.when(
NORTH_WALL_SHAPE, LOW,
EAST_WALL_SHAPE, TALL,
SOUTH_WALL_SHAPE, LOW,
WEST_WALL_SHAPE, NONE,
UP, false
),
GBlockstate.variant(low_i_tall_t, true, R0, R90))
.with(GBlockstate.when(
NORTH_WALL_SHAPE, NONE,
EAST_WALL_SHAPE, LOW,
SOUTH_WALL_SHAPE, TALL,
WEST_WALL_SHAPE, LOW,
UP, false
),
GBlockstate.variant(low_i_tall_t, true, R0, R180))
.with(GBlockstate.when(
NORTH_WALL_SHAPE, LOW,
EAST_WALL_SHAPE, NONE,
SOUTH_WALL_SHAPE, LOW,
WEST_WALL_SHAPE, TALL,
UP, false
),
GBlockstate.variant(low_i_tall_t, true, R0, R270))
// JUNCTION LOW TALL C T
.with(GBlockstate.when(
NORTH_WALL_SHAPE, TALL,
EAST_WALL_SHAPE, LOW,
SOUTH_WALL_SHAPE, NONE,
WEST_WALL_SHAPE, TALL,
UP, false
),
GBlockstate.variant(low_tall_c_t, true, R0, R0))
.with(GBlockstate.when(
NORTH_WALL_SHAPE, TALL,
EAST_WALL_SHAPE, TALL,
SOUTH_WALL_SHAPE, LOW,
WEST_WALL_SHAPE, NONE,
UP, false
),
GBlockstate.variant(low_tall_c_t, true, R0, R90))
.with(GBlockstate.when(
NORTH_WALL_SHAPE, NONE,
EAST_WALL_SHAPE, TALL,
SOUTH_WALL_SHAPE, TALL,
WEST_WALL_SHAPE, LOW,
UP, false
),
GBlockstate.variant(low_tall_c_t, true, R0, R180))
.with(GBlockstate.when(
NORTH_WALL_SHAPE, LOW,
EAST_WALL_SHAPE, NONE,
SOUTH_WALL_SHAPE, TALL,
WEST_WALL_SHAPE, TALL,
UP, false
),
GBlockstate.variant(low_tall_c_t, true, R0, R270))
// JUNCTION LOW C TALL T
.with(GBlockstate.when(
NORTH_WALL_SHAPE, LOW,
EAST_WALL_SHAPE, LOW,
SOUTH_WALL_SHAPE, NONE,
WEST_WALL_SHAPE, TALL,
UP, false
),
GBlockstate.variant(low_c_tall_t, true, R0, R0))
.with(GBlockstate.when(
NORTH_WALL_SHAPE, TALL,
EAST_WALL_SHAPE, LOW,
SOUTH_WALL_SHAPE, LOW,
WEST_WALL_SHAPE, NONE,
UP, false
),
GBlockstate.variant(low_c_tall_t, true, R0, R90))
.with(GBlockstate.when(
NORTH_WALL_SHAPE, NONE,
EAST_WALL_SHAPE, TALL,
SOUTH_WALL_SHAPE, LOW,
WEST_WALL_SHAPE, LOW,
UP, false
),
GBlockstate.variant(low_c_tall_t, true, R0, R180))
.with(GBlockstate.when(
NORTH_WALL_SHAPE, LOW,
EAST_WALL_SHAPE, NONE,
SOUTH_WALL_SHAPE, TALL,
WEST_WALL_SHAPE, LOW,
UP, false
),
GBlockstate.variant(low_c_tall_t, true, R0, R270))
// JUNCTION TALL C LOW T
.with(GBlockstate.when(
NORTH_WALL_SHAPE, TALL,
EAST_WALL_SHAPE, TALL,
SOUTH_WALL_SHAPE, NONE,
WEST_WALL_SHAPE, LOW,
UP, false
),
GBlockstate.variant(tall_c_low_t, true, R0, R0))
.with(GBlockstate.when(
NORTH_WALL_SHAPE, LOW,
EAST_WALL_SHAPE, TALL,
SOUTH_WALL_SHAPE, TALL,
WEST_WALL_SHAPE, NONE,
UP, false
),
GBlockstate.variant(tall_c_low_t, true, R0, R90))
.with(GBlockstate.when(
NORTH_WALL_SHAPE, NONE,
EAST_WALL_SHAPE, LOW,
SOUTH_WALL_SHAPE, TALL,
WEST_WALL_SHAPE, TALL,
UP, false
),
GBlockstate.variant(tall_c_low_t, true, R0, R180))
.with(GBlockstate.when(
NORTH_WALL_SHAPE, TALL,
EAST_WALL_SHAPE, NONE,
SOUTH_WALL_SHAPE, LOW,
WEST_WALL_SHAPE, TALL,
UP, false
),
GBlockstate.variant(tall_c_low_t, true, R0, R270))
// JUNCTION X
.with(GBlockstate.when(
NORTH_WALL_SHAPE, LOW,
EAST_WALL_SHAPE, LOW,
SOUTH_WALL_SHAPE, LOW,
WEST_WALL_SHAPE, LOW,
UP, false
),
GBlockstate.variant(ReFramed.id("wall_low_x_special"), true, R0, R0))
.with(GBlockstate.when(
NORTH_WALL_SHAPE, TALL,
EAST_WALL_SHAPE, TALL,
SOUTH_WALL_SHAPE, TALL,
WEST_WALL_SHAPE, TALL,
UP, false
),
GBlockstate.variant(ReFramed.id("wall_tall_x_special"), true, R0, R0))
// JUNCTION I X
.with(GBlockstate.when(
NORTH_WALL_SHAPE, LOW,
EAST_WALL_SHAPE, TALL,
SOUTH_WALL_SHAPE, LOW,
WEST_WALL_SHAPE, TALL,
UP, false
),
GBlockstate.variant(tall_i_low_i_x, true, R0, R0))
.with(GBlockstate.when(
NORTH_WALL_SHAPE, TALL,
EAST_WALL_SHAPE, LOW,
SOUTH_WALL_SHAPE, TALL,
WEST_WALL_SHAPE, LOW,
UP, false
),
GBlockstate.variant(tall_i_low_i_x, true, R0, R90))
// JUNCTION TALL LOW T X
.with(GBlockstate.when(
NORTH_WALL_SHAPE, LOW,
EAST_WALL_SHAPE, TALL,
SOUTH_WALL_SHAPE, LOW,
WEST_WALL_SHAPE, LOW,
UP, false
),
GBlockstate.variant(tall_low_t_x, true, R0, R0))
.with(GBlockstate.when(
NORTH_WALL_SHAPE, LOW,
EAST_WALL_SHAPE, LOW,
SOUTH_WALL_SHAPE, TALL,
WEST_WALL_SHAPE, LOW,
UP, false
),
GBlockstate.variant(tall_low_t_x, true, R0, R90))
.with(GBlockstate.when(
NORTH_WALL_SHAPE, LOW,
EAST_WALL_SHAPE, LOW,
SOUTH_WALL_SHAPE, LOW,
WEST_WALL_SHAPE, TALL,
UP, false
),
GBlockstate.variant(tall_low_t_x, true, R0, R180))
.with(GBlockstate.when(
NORTH_WALL_SHAPE, TALL,
EAST_WALL_SHAPE, LOW,
SOUTH_WALL_SHAPE, LOW,
WEST_WALL_SHAPE, LOW,
UP, false
),
GBlockstate.variant(tall_low_t_x, true, R0, R270))
// JUNCTION TALL C LOW C X
.with(GBlockstate.when(
NORTH_WALL_SHAPE, TALL,
EAST_WALL_SHAPE, TALL,
SOUTH_WALL_SHAPE, LOW,
WEST_WALL_SHAPE, LOW,
UP, false
),
GBlockstate.variant(tall_c_low_c_x, true, R0, R0))
.with(GBlockstate.when(
NORTH_WALL_SHAPE, LOW,
EAST_WALL_SHAPE, TALL,
SOUTH_WALL_SHAPE, TALL,
WEST_WALL_SHAPE, LOW,
UP, false
),
GBlockstate.variant(tall_c_low_c_x, true, R0, R90))
.with(GBlockstate.when(
NORTH_WALL_SHAPE, LOW,
EAST_WALL_SHAPE, LOW,
SOUTH_WALL_SHAPE, TALL,
WEST_WALL_SHAPE, TALL,
UP, false
),
GBlockstate.variant(tall_c_low_c_x, true, R0, R180))
.with(GBlockstate.when(
NORTH_WALL_SHAPE, TALL,
EAST_WALL_SHAPE, LOW,
SOUTH_WALL_SHAPE, LOW,
WEST_WALL_SHAPE, TALL,
UP, false
),
GBlockstate.variant(tall_c_low_c_x, true, R0, R270))
// JUNCTION TALL C LOW C X
.with(GBlockstate.when(
NORTH_WALL_SHAPE, TALL,
EAST_WALL_SHAPE, TALL,
SOUTH_WALL_SHAPE, LOW,
WEST_WALL_SHAPE, TALL,
UP, false
),
GBlockstate.variant(tall_t_low_x, true, R0, R0))
.with(GBlockstate.when(
NORTH_WALL_SHAPE, TALL,
EAST_WALL_SHAPE, TALL,
SOUTH_WALL_SHAPE, TALL,
WEST_WALL_SHAPE, LOW,
UP, false
),
GBlockstate.variant(tall_t_low_x, true, R0, R90))
.with(GBlockstate.when(
NORTH_WALL_SHAPE, LOW,
EAST_WALL_SHAPE, TALL,
SOUTH_WALL_SHAPE, TALL,
WEST_WALL_SHAPE, TALL,
UP, false
),
GBlockstate.variant(tall_t_low_x, true, R0, R180))
.with(GBlockstate.when(
NORTH_WALL_SHAPE, TALL,
EAST_WALL_SHAPE, LOW,
SOUTH_WALL_SHAPE, TALL,
WEST_WALL_SHAPE, TALL,
UP, false
),
GBlockstate.variant(tall_t_low_x, true, R0, R270));
}
}

View File

@@ -0,0 +1,25 @@
package fr.adrien1106.reframed.generator.item;
import fr.adrien1106.reframed.generator.RecipeSetter;
import net.fabricmc.fabric.api.datagen.v1.provider.FabricRecipeProvider;
import net.minecraft.data.server.recipe.RecipeExporter;
import net.minecraft.data.server.recipe.ShapedRecipeJsonBuilder;
import net.minecraft.item.ItemConvertible;
import net.minecraft.item.Items;
import net.minecraft.recipe.book.RecipeCategory;
public class Blueprint implements RecipeSetter {
@Override
public void setRecipe(RecipeExporter exporter, ItemConvertible convertible) {
ShapedRecipeJsonBuilder
.create(RecipeCategory.TOOLS, convertible, 3)
.pattern("PI")
.pattern("PP")
.input('P', Items.PAPER)
.input('I', Items.INK_SAC)
.criterion(FabricRecipeProvider.hasItem(Items.PAPER), FabricRecipeProvider.conditionsFromItem(Items.PAPER))
.criterion(FabricRecipeProvider.hasItem(convertible), FabricRecipeProvider.conditionsFromItem(convertible))
.offerTo(exporter);
}
}

View File

@@ -0,0 +1,28 @@
package fr.adrien1106.reframed.generator.item;
import fr.adrien1106.reframed.ReFramed;
import fr.adrien1106.reframed.generator.RecipeSetter;
import net.fabricmc.fabric.api.datagen.v1.provider.FabricRecipeProvider;
import net.minecraft.data.server.recipe.RecipeExporter;
import net.minecraft.data.server.recipe.ShapedRecipeJsonBuilder;
import net.minecraft.item.ItemConvertible;
import net.minecraft.item.Items;
import net.minecraft.recipe.book.RecipeCategory;
public class Hammer implements RecipeSetter {
@Override
public void setRecipe(RecipeExporter exporter, ItemConvertible convertible) {
ShapedRecipeJsonBuilder
.create(RecipeCategory.TOOLS, convertible)
.pattern(" CI")
.pattern(" ~C")
.pattern("~ ")
.input('I', Items.IRON_INGOT)
.input('C', ReFramed.CUBE)
.input('~', Items.STICK)
.criterion(FabricRecipeProvider.hasItem(ReFramed.CUBE), FabricRecipeProvider.conditionsFromItem(ReFramed.CUBE))
.criterion(FabricRecipeProvider.hasItem(convertible), FabricRecipeProvider.conditionsFromItem(convertible))
.offerTo(exporter);
}
}

View File

@@ -0,0 +1,27 @@
package fr.adrien1106.reframed.generator.item;
import fr.adrien1106.reframed.ReFramed;
import fr.adrien1106.reframed.generator.RecipeSetter;
import net.fabricmc.fabric.api.datagen.v1.provider.FabricRecipeProvider;
import net.minecraft.data.server.recipe.RecipeExporter;
import net.minecraft.data.server.recipe.ShapedRecipeJsonBuilder;
import net.minecraft.item.ItemConvertible;
import net.minecraft.item.Items;
import net.minecraft.recipe.book.RecipeCategory;
public class Screwdriver implements RecipeSetter {
@Override
public void setRecipe(RecipeExporter exporter, ItemConvertible convertible) {
ShapedRecipeJsonBuilder
.create(RecipeCategory.TOOLS, convertible)
.pattern(" I")
.pattern(" I ")
.pattern("C ")
.input('I', Items.IRON_INGOT)
.input('C', ReFramed.CUBE)
.criterion(FabricRecipeProvider.hasItem(ReFramed.CUBE), FabricRecipeProvider.conditionsFromItem(ReFramed.CUBE))
.criterion(FabricRecipeProvider.hasItem(convertible), FabricRecipeProvider.conditionsFromItem(convertible))
.offerTo(exporter);
}
}

View File

@@ -2,23 +2,17 @@ package fr.adrien1106.reframed.item;
import fr.adrien1106.reframed.ReFramed;
import fr.adrien1106.reframed.block.ReFramedEntity;
import fr.adrien1106.reframed.generator.RecipeSetter;
import net.fabricmc.fabric.api.datagen.v1.provider.FabricRecipeProvider;
import net.minecraft.block.Blocks;
import net.minecraft.data.server.recipe.RecipeExporter;
import net.minecraft.data.server.recipe.ShapedRecipeJsonBuilder;
import net.minecraft.item.Item;
import net.minecraft.item.ItemStack;
import net.minecraft.item.ItemUsageContext;
import net.minecraft.item.Items;
import net.minecraft.recipe.book.RecipeCategory;
import net.minecraft.sound.SoundCategory;
import net.minecraft.sound.SoundEvents;
import net.minecraft.util.ActionResult;
import net.minecraft.util.math.BlockPos;
import net.minecraft.world.World;
public class ReFramedBlueprintItem extends Item implements RecipeSetter {
public class ReFramedBlueprintItem extends Item {
public ReFramedBlueprintItem(Settings settings) {
super(settings);
}
@@ -39,17 +33,4 @@ public class ReFramedBlueprintItem extends Item implements RecipeSetter {
return ActionResult.SUCCESS;
}
@Override
public void setRecipe(RecipeExporter exporter) {
ShapedRecipeJsonBuilder
.create(RecipeCategory.BUILDING_BLOCKS, this, 3)
.pattern("PI")
.pattern("PP")
.input('P', Items.PAPER)
.input('I', Items.INK_SAC)
.criterion(FabricRecipeProvider.hasItem(Items.PAPER), FabricRecipeProvider.conditionsFromItem(Items.PAPER))
.criterion(FabricRecipeProvider.hasItem(this), FabricRecipeProvider.conditionsFromItem(this))
.offerTo(exporter);
}
}

View File

@@ -2,26 +2,20 @@ package fr.adrien1106.reframed.item;
import fr.adrien1106.reframed.ReFramed;
import fr.adrien1106.reframed.block.ReFramedDoubleBlock;
import fr.adrien1106.reframed.generator.RecipeSetter;
import fr.adrien1106.reframed.util.blocks.ThemeableBlockEntity;
import net.fabricmc.fabric.api.datagen.v1.provider.FabricRecipeProvider;
import net.minecraft.block.BlockState;
import net.minecraft.block.Blocks;
import net.minecraft.data.server.recipe.RecipeExporter;
import net.minecraft.data.server.recipe.ShapedRecipeJsonBuilder;
import net.minecraft.entity.player.PlayerEntity;
import net.minecraft.item.Item;
import net.minecraft.item.ItemStack;
import net.minecraft.item.ItemUsageContext;
import net.minecraft.item.Items;
import net.minecraft.recipe.book.RecipeCategory;
import net.minecraft.sound.SoundCategory;
import net.minecraft.sound.SoundEvents;
import net.minecraft.util.ActionResult;
import net.minecraft.util.math.BlockPos;
import net.minecraft.world.World;
public class ReFramedHammerItem extends Item implements RecipeSetter {
public class ReFramedHammerItem extends Item {
public ReFramedHammerItem(Settings settings) {
super(settings);
}
@@ -52,19 +46,4 @@ public class ReFramedHammerItem extends Item implements RecipeSetter {
ReFramed.chunkRerenderProxy.accept(world, pos);
return ActionResult.SUCCESS;
}
@Override
public void setRecipe(RecipeExporter exporter) {
ShapedRecipeJsonBuilder
.create(RecipeCategory.BUILDING_BLOCKS, this)
.pattern(" CI")
.pattern(" ~C")
.pattern("~ ")
.input('I', Items.IRON_INGOT)
.input('C', ReFramed.CUBE)
.input('~', Items.STICK)
.criterion(FabricRecipeProvider.hasItem(ReFramed.CUBE), FabricRecipeProvider.conditionsFromItem(ReFramed.CUBE))
.criterion(FabricRecipeProvider.hasItem(this), FabricRecipeProvider.conditionsFromItem(this))
.offerTo(exporter);
}
}

View File

@@ -2,17 +2,11 @@ package fr.adrien1106.reframed.item;
import fr.adrien1106.reframed.ReFramed;
import fr.adrien1106.reframed.block.ReFramedDoubleBlock;
import fr.adrien1106.reframed.generator.RecipeSetter;
import fr.adrien1106.reframed.util.blocks.ThemeableBlockEntity;
import net.fabricmc.fabric.api.datagen.v1.provider.FabricRecipeProvider;
import net.minecraft.block.BlockState;
import net.minecraft.data.server.recipe.RecipeExporter;
import net.minecraft.data.server.recipe.ShapedRecipeJsonBuilder;
import net.minecraft.entity.player.PlayerEntity;
import net.minecraft.item.Item;
import net.minecraft.item.ItemUsageContext;
import net.minecraft.item.Items;
import net.minecraft.recipe.book.RecipeCategory;
import net.minecraft.sound.BlockSoundGroup;
import net.minecraft.sound.SoundCategory;
import net.minecraft.state.property.Properties;
@@ -21,7 +15,7 @@ import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.Direction;
import net.minecraft.world.World;
public class ReFramedScrewdriverItem extends Item implements RecipeSetter {
public class ReFramedScrewdriverItem extends Item {
public ReFramedScrewdriverItem(Settings settings) {
super(settings);
@@ -61,18 +55,4 @@ public class ReFramedScrewdriverItem extends Item implements RecipeSetter {
ReFramed.chunkRerenderProxy.accept(world, pos);
return ActionResult.SUCCESS;
}
@Override
public void setRecipe(RecipeExporter exporter) {
ShapedRecipeJsonBuilder
.create(RecipeCategory.BUILDING_BLOCKS, this)
.pattern(" I")
.pattern(" I ")
.pattern("C ")
.input('I', Items.IRON_INGOT)
.input('C', ReFramed.CUBE)
.criterion(FabricRecipeProvider.hasItem(ReFramed.CUBE), FabricRecipeProvider.conditionsFromItem(ReFramed.CUBE))
.criterion(FabricRecipeProvider.hasItem(this), FabricRecipeProvider.conditionsFromItem(this))
.offerTo(exporter);
}
}

View File

@@ -0,0 +1,57 @@
package fr.adrien1106.reframed.mixin.logic;
import fr.adrien1106.reframed.block.ReFramedBlock;
import net.minecraft.block.Block;
import net.minecraft.block.BlockState;
import net.minecraft.block.entity.BlockEntity;
import net.minecraft.entity.LivingEntity;
import net.minecraft.item.BlockItem;
import net.minecraft.item.ItemPlacementContext;
import net.minecraft.item.ItemStack;
import net.minecraft.util.ActionResult;
import net.minecraft.util.math.BlockPos;
import net.minecraft.world.World;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Unique;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.Redirect;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
@Mixin(BlockItem.class)
public class BlockItemMixin {
@Unique private final ThreadLocal<BlockState> old_state = new ThreadLocal<>();
@Unique private final ThreadLocal<BlockEntity> old_entity = new ThreadLocal<>();
@Redirect(
method = "place(Lnet/minecraft/item/ItemPlacementContext;)Lnet/minecraft/util/ActionResult;",
at = @At(
value = "INVOKE",
target = "Lnet/minecraft/block/Block;onPlaced(Lnet/minecraft/world/World;Lnet/minecraft/util/math/BlockPos;Lnet/minecraft/block/BlockState;Lnet/minecraft/entity/LivingEntity;Lnet/minecraft/item/ItemStack;)V"
)
)
private void placeMoreInfo(Block block, World world, BlockPos pos, BlockState state, LivingEntity placer, ItemStack itemStack) {
if (!(block instanceof ReFramedBlock frame_block)) {
block.onPlaced(world, pos, state, placer, itemStack);
return;
}
frame_block.onPlaced(world, pos, state, placer, itemStack, old_state.get(), old_entity.get());
}
@Inject(
method = "place(Lnet/minecraft/item/ItemPlacementContext;)Lnet/minecraft/util/ActionResult;",
at = @At(
value = "INVOKE",
target = "Lnet/minecraft/item/BlockItem;place(Lnet/minecraft/item/ItemPlacementContext;Lnet/minecraft/block/BlockState;)Z",
shift = At.Shift.BEFORE
)
)
private void savePreviousInfo(ItemPlacementContext context, CallbackInfoReturnable<ActionResult> cir) {
World world = context.getWorld();
BlockPos pos = context.getBlockPos();
old_state.set(world.getBlockState(pos));
old_entity.set(world.getBlockEntity(pos));
}
}

View File

@@ -130,14 +130,14 @@ public class BlockHelper {
return shape;
}
public static String getNeighborPos(Edge face, Direction direction, Boolean reverse, Direction reference, BlockView world, BlockPos pos) {
public static String getNeighborPos(Edge edge, Direction direction, Boolean reverse, Direction reference, BlockView world, BlockPos pos) {
BlockState block_state = world.getBlockState(
pos.offset(reverse ? direction.getOpposite() : direction)
);
if (isStair(block_state) && block_state.get(EDGE).hasDirection(reference)) {
if (block_state.get(EDGE).hasDirection(face.getLeftDirection())) return "left";
else if (block_state.get(EDGE).hasDirection(face.getRightDirection())) return "right";
if (block_state.get(EDGE).hasDirection(edge.getLeftDirection())) return "left";
else if (block_state.get(EDGE).hasDirection(edge.getRightDirection())) return "right";
}
return "";
}

View File

@@ -37,6 +37,18 @@ public enum Corner implements StringIdentifiable {
return asString();
}
public Direction getFirstDirection() {
return first_direction;
}
public Direction getSecondDirection() {
return second_direction;
}
public Direction getThirdDirection() {
return third_direction;
}
public boolean hasDirection(Direction direction) {
return this.first_direction.equals(direction)
|| this.second_direction.equals(direction)
@@ -94,4 +106,17 @@ public enum Corner implements StringIdentifiable {
Direction other_2 = second_direction == direction || first_direction == direction ? third_direction : second_direction;
return getByDirections(direction, other_1.getOpposite(), other_2.getOpposite());
}
public Edge getEdge(Direction direction) {
return Edge.getByDirections(
first_direction == direction ? second_direction : first_direction,
second_direction == direction || first_direction == direction ? third_direction : second_direction
);
}
public Direction getOtherDirection(Edge edge) {
if (edge.getFirstDirection() != second_direction && edge.getSecondDirection() != second_direction) return second_direction;
if (edge.getFirstDirection() != third_direction && edge.getSecondDirection() != third_direction) return third_direction;
return first_direction;
}
}

View File

@@ -49,18 +49,10 @@ public enum Edge implements StringIdentifiable {
return second_direction;
}
public Direction getRightDirection() {
return switch (axis) {
case X -> Direction.WEST;
case Y -> Direction.DOWN;
case Z -> Direction.SOUTH;
};
return Direction.from(axis, Direction.AxisDirection.NEGATIVE);
}
public Direction getLeftDirection() {
return switch (axis) {
case X -> Direction.EAST;
case Y -> Direction.UP;
case Z -> Direction.NORTH;
};
return Direction.from(axis, Direction.AxisDirection.POSITIVE);
}
public boolean hasDirection(Direction direction) {
@@ -68,16 +60,32 @@ public enum Edge implements StringIdentifiable {
|| this.second_direction.equals(direction);
}
public Direction.Axis getAxis() {
return this.axis;
}
public int getID() {
return this.ID;
}
public Edge opposite() {
return getByDirections(first_direction.getOpposite(), second_direction.getOpposite());
}
public static Edge getByDirections(Direction direction_1, Direction direction_2) {
return Arrays.stream(Edge.values())
.filter(value -> value.hasDirection(direction_1) && value.hasDirection(direction_2))
.findFirst().orElse(Edge.NORTH_DOWN);
}
public boolean isSide(Direction side) {
return getRightDirection() == side || getLeftDirection() == side;
}
public Direction getOtherDirection(Direction direction) {
return first_direction == direction ? second_direction : first_direction;
}
public static Edge fromId(int id) {
return Arrays.stream(Edge.values())
.filter(value -> value.getID() == id)

View File

@@ -0,0 +1,21 @@
{
"credit": "Made with Blockbench",
"parent": "block/block",
"textures": {
"particle": "#side"
},
"elements": [
{
"from": [4, 0, 4],
"to": [12, 16, 12],
"faces": {
"north": {"uv": [4, 0, 12, 16], "texture": "#side"},
"east": {"uv": [4, 0, 12, 16], "texture": "#side"},
"south": {"uv": [4, 0, 12, 16], "texture": "#side"},
"west": {"uv": [4, 0, 12, 16], "texture": "#side"},
"up": {"uv": [4, 4, 12, 12], "texture": "#top", "cullface": "up"},
"down": {"uv": [4, 4, 12, 12], "texture": "#bottom", "cullface": "down"}
}
}
]
}

View File

@@ -0,0 +1,35 @@
{
"credit": "Made with Blockbench",
"parent": "block/block",
"textures": {
"particle": "#side"
},
"elements": [
{
"from": [4, 0, 4],
"to": [5, 14, 5],
"faces": {
"north": {"uv": [11, 2, 12, 16], "texture": "#side"},
"west": {"uv": [4, 2, 5, 16], "texture": "#side"},
"down": {"uv": [4, 11, 5, 12], "texture": "#bottom", "cullface": "down"}
}
},
{
"from": [5, 0, 4],
"to": [11, 14, 5],
"faces": {
"north": {"uv": [5, 2, 11, 16], "texture": "#side"},
"down": {"uv": [5, 11, 11, 12], "texture": "#bottom", "cullface": "down"}
}
},
{
"from": [4, 14, 4],
"to": [11, 16, 5],
"faces": {
"north": {"uv": [5, 0, 12, 2], "texture": "#side"},
"west": {"uv": [4, 0, 5, 2], "texture": "#side"},
"up": {"uv": [5, 4, 12, 5], "texture": "#top", "cullface": "up"}
}
}
]
}

View File

@@ -0,0 +1,28 @@
{
"credit": "Made with Blockbench",
"parent": "block/block",
"textures": {
"particle": "#side"
},
"elements": [
{
"from": [4, 0, 4],
"to": [5, 16, 5],
"faces": {
"north": {"uv": [11, 0, 12, 16], "texture": "#side"},
"west": {"uv": [4, 0, 5, 16], "texture": "#side"},
"up": {"uv": [4, 4, 5, 5], "texture": "#top", "cullface": "up"},
"down": {"uv": [4, 11, 5, 12], "texture": "#bottom", "cullface": "down"}
}
},
{
"from": [5, 0, 4],
"to": [11, 16, 5],
"faces": {
"north": {"uv": [5, 0, 11, 16], "texture": "#side"},
"up": {"uv": [5, 4, 11, 5], "texture": "#top", "cullface": "up"},
"down": {"uv": [5, 11, 11, 12], "texture": "#bottom", "cullface": "down"}
}
}
]
}

View File

@@ -0,0 +1,21 @@
{
"credit": "Made with Blockbench",
"parent": "block/block",
"textures": {
"particle": "#side"
},
"elements": [
{
"from": [5, 0, 0],
"to": [11, 14, 4],
"faces": {
"north": {"uv": [5, 2, 11, 16], "texture": "#side", "cullface": "north"},
"east": {"uv": [12, 2, 16, 16], "texture": "#side"},
"south": {"uv": [5, 2, 11, 16], "texture": "#side"},
"west": {"uv": [0, 2, 4, 16], "texture": "#side"},
"up": {"uv": [5, 0, 11, 4], "texture": "#top"},
"down": {"uv": [5, 12, 11, 16], "texture": "#bottom", "cullface": "down"}
}
}
]
}

View File

@@ -0,0 +1,21 @@
{
"credit": "Made with Blockbench",
"parent": "block/block",
"textures": {
"particle": "#side"
},
"elements": [
{
"from": [5, 0, 0],
"to": [11, 16, 4],
"faces": {
"north": {"uv": [5, 0, 11, 16], "texture": "#side", "cullface": "north"},
"east": {"uv": [12, 0, 16, 16], "texture": "#side"},
"south": {"uv": [5, 0, 11, 16], "texture": "#side"},
"west": {"uv": [0, 0, 4, 16], "texture": "#side"},
"up": {"uv": [5, 0, 11, 4], "texture": "#top", "cullface": "up"},
"down": {"uv": [5, 12, 11, 16], "texture": "#bottom", "cullface": "down"}
}
}
]
}

View File

@@ -0,0 +1,43 @@
{
"credit": "Made with Blockbench",
"parent": "block/block",
"textures": {
"particle": "#side"
},
"elements": [
{
"from": [5, 0, 0],
"to": [11, 14, 4],
"faces": {
"north": {"uv": [5, 2, 11, 16], "texture": "#side", "cullface": "north"},
"east": {"uv": [12, 2, 16, 16], "texture": "#side"},
"west": {"uv": [0, 2, 4, 16], "texture": "#side"},
"up": {"uv": [5, 0, 11, 4], "texture": "#top"},
"down": {"uv": [5, 12, 11, 16], "texture": "#bottom"}
}
},
{
"from": [5, 0, 12],
"to": [11, 14, 16],
"faces": {
"east": {"uv": [0, 2, 4, 16], "texture": "#side"},
"south": {"uv": [5, 2, 11, 16], "texture": "#side", "cullface": "south"},
"west": {"uv": [12, 2, 16, 16], "texture": "#side"},
"up": {"uv": [5, 12, 11, 16], "texture": "#top"},
"down": {"uv": [5, 0, 11, 4], "texture": "#bottom"}
}
},
{
"from": [4, 0, 4],
"to": [12, 16, 12],
"faces": {
"north": {"uv": [4, 0, 12, 16], "texture": "#side"},
"east": {"uv": [4, 0, 12, 16], "texture": "#side"},
"south": {"uv": [4, 0, 12, 16], "texture": "#side", "cullface": "south"},
"west": {"uv": [4, 0, 12, 16], "texture": "#side"},
"up": {"uv": [4, 4, 12, 12], "texture": "#top"},
"down": {"uv": [4, 4, 12, 12], "texture": "#bottom"}
}
}
]
}

View File

@@ -0,0 +1,20 @@
{
"credit": "Made with Blockbench",
"parent": "block/block",
"textures": {
"particle": "#side"
},
"elements": [
{
"from": [5, 0, 4],
"to": [11, 14, 8],
"faces": {
"east": {"uv": [8, 2, 12, 16], "texture": "#side"},
"south": {"uv": [5, 2, 11, 16], "texture": "#side"},
"west": {"uv": [4, 2, 8, 16], "texture": "#side"},
"up": {"uv": [5, 4, 11, 8], "texture": "#top"},
"down": {"uv": [5, 8, 11, 12], "texture": "#bottom", "cullface": "down"}
}
}
]
}

View File

@@ -0,0 +1,57 @@
{
"credit": "Made with Blockbench",
"parent": "block/block",
"textures": {
"particle": "#side"
},
"elements": [
{
"from": [5, 0, 4],
"to": [11, 14, 5],
"faces": {
"east": {"uv": [11, 2, 12, 16], "texture": "#side"},
"west": {"uv": [4, 2, 5, 16], "texture": "#side"},
"up": {"uv": [5, 4, 11, 5], "texture": "#top"},
"down": {"uv": [5, 11, 11, 12], "texture": "#bottom", "cullface": "down"}
}
},
{
"from": [8, 0, 5],
"to": [11, 14, 8],
"faces": {
"east": {"uv": [8, 2, 11, 16], "texture": "#side"},
"south": {"uv": [8, 2, 11, 16], "texture": "#side"},
"up": {"uv": [8, 5, 11, 8], "texture": "#top"},
"down": {"uv": [8, 8, 11, 11], "texture": "#bottom", "cullface": "down"}
}
},
{
"from": [5, 0, 8],
"to": [8, 14, 11],
"faces": {
"east": {"uv": [5, 2, 8, 16], "texture": "#side"},
"south": {"uv": [5, 2, 8, 16], "texture": "#side"},
"up": {"uv": [5, 8, 8, 11], "texture": "#top"},
"down": {"uv": [5, 5, 8, 8], "texture": "#bottom", "cullface": "down"}
}
},
{
"from": [5, 0, 5],
"to": [8, 14, 8],
"faces": {
"up": {"uv": [5, 5, 8, 8], "texture": "#top"},
"down": {"uv": [5, 8, 8, 11], "texture": "#bottom", "cullface": "down"}
}
},
{
"from": [4, 0, 5],
"to": [5, 14, 11],
"faces": {
"north": {"uv": [11, 2, 12, 16], "texture": "#side"},
"south": {"uv": [4, 2, 5, 16], "texture": "#side"},
"up": {"uv": [4, 5, 5, 11], "texture": "#top"},
"down": {"uv": [4, 5, 5, 11], "texture": "#bottom", "cullface": "down"}
}
}
]
}

View File

@@ -0,0 +1,66 @@
{
"credit": "Made with Blockbench",
"parent": "block/block",
"textures": {
"particle": "#side"
},
"elements": [
{
"from": [5, 0, 4],
"to": [11, 14, 5],
"faces": {
"east": {"uv": [11, 2, 12, 16], "texture": "#side"},
"west": {"uv": [4, 2, 5, 16], "texture": "#side"},
"up": {"uv": [5, 4, 11, 5], "texture": "#top"},
"down": {"uv": [5, 11, 11, 12], "texture": "#bottom", "cullface": "down"}
}
},
{
"from": [8, 0, 5],
"to": [11, 14, 11],
"faces": {
"south": {"uv": [8, 2, 11, 16], "texture": "#side"},
"up": {"uv": [8, 5, 11, 11], "texture": "#top"},
"down": {"uv": [8, 5, 11, 11], "texture": "#bottom", "cullface": "down"}
}
},
{
"from": [5, 14, 5],
"to": [8, 16, 11],
"faces": {
"north": {"uv": [8, 0, 11, 2], "texture": "#side"},
"east": {"uv": [5, 0, 11, 2], "texture": "#side"},
"south": {"uv": [5, 0, 8, 2], "texture": "#side"},
"up": {"uv": [5, 5, 8, 11], "texture": "#top", "cullface": "up"}
}
},
{
"from": [5, 0, 5],
"to": [8, 14, 11],
"faces": {
"south": {"uv": [5, 2, 8, 16], "texture": "#side"},
"down": {"uv": [5, 5, 8, 11], "texture": "#bottom", "cullface": "down"}
}
},
{
"from": [11, 0, 5],
"to": [12, 14, 11],
"faces": {
"north": {"uv": [4, 2, 5, 16], "texture": "#side"},
"south": {"uv": [11, 2, 12, 16], "texture": "#side"},
"up": {"uv": [11, 5, 12, 11], "texture": "#top"},
"down": {"uv": [11, 5, 12, 11], "texture": "#bottom", "cullface": "down"}
}
},
{
"from": [4, 0, 5],
"to": [5, 16, 11],
"faces": {
"north": {"uv": [11, 0, 12, 16], "texture": "#side"},
"south": {"uv": [4, 0, 5, 16], "texture": "#side"},
"up": {"uv": [4, 5, 5, 11], "texture": "#top", "cullface": "up"},
"down": {"uv": [4, 5, 5, 11], "texture": "#bottom", "cullface": "down"}
}
}
]
}

View File

@@ -0,0 +1,19 @@
{
"credit": "Made with Blockbench",
"parent": "block/block",
"textures": {
"particle": "#side"
},
"elements": [
{
"from": [5, 0, 4],
"to": [11, 14, 12],
"faces": {
"east": {"uv": [4, 2, 12, 16], "texture": "#side"},
"west": {"uv": [4, 2, 12, 16], "texture": "#side"},
"up": {"uv": [5, 4, 11, 12], "texture": "#top"},
"down": {"uv": [5, 4, 11, 12], "texture": "#bottom", "cullface": "down"}
}
}
]
}

View File

@@ -0,0 +1,65 @@
{
"credit": "Made with Blockbench",
"parent": "block/block",
"textures": {
"particle": "#side"
},
"elements": [
{
"from": [5, 0, 4],
"to": [11, 16, 5],
"faces": {
"east": {"uv": [11, 0, 12, 16], "texture": "#side"},
"west": {"uv": [4, 0, 5, 16], "texture": "#side"},
"up": {"uv": [5, 4, 11, 5], "texture": "#top", "cullface": "up"},
"down": {"uv": [5, 11, 11, 12], "texture": "#bottom", "cullface": "down"}
}
},
{
"from": [5, 0, 8],
"to": [11, 14, 11],
"faces": {
"south": {"uv": [5, 2, 11, 16], "texture": "#side"},
"up": {"uv": [5, 8, 11, 11], "texture": "#top"},
"down": {"uv": [5, 5, 11, 8], "texture": "#bottom", "cullface": "down"}
}
},
{
"from": [5, 14, 5],
"to": [11, 16, 8],
"faces": {
"east": {"uv": [8, 0, 11, 2], "texture": "#side"},
"south": {"uv": [5, 0, 11, 2], "texture": "#side"},
"west": {"uv": [5, 0, 8, 2], "texture": "#side"},
"up": {"uv": [5, 5, 11, 8], "texture": "#top", "cullface": "up"}
}
},
{
"from": [5, 0, 5],
"to": [11, 14, 8],
"faces": {
"down": {"uv": [5, 8, 11, 11], "texture": "#bottom", "cullface": "down"}
}
},
{
"from": [4, 0, 5],
"to": [5, 14, 11],
"faces": {
"north": {"uv": [11, 2, 12, 16], "texture": "#side"},
"south": {"uv": [4, 2, 5, 16], "texture": "#side"},
"up": {"uv": [4, 5, 5, 11], "texture": "#top"},
"down": {"uv": [4, 5, 5, 11], "texture": "#bottom", "cullface": "down"}
}
},
{
"from": [11, 0, 5],
"to": [12, 14, 11],
"faces": {
"north": {"uv": [4, 2, 5, 16], "texture": "#side"},
"south": {"uv": [11, 2, 12, 16], "texture": "#side"},
"up": {"uv": [11, 5, 12, 11], "texture": "#top"},
"down": {"uv": [11, 5, 12, 11], "texture": "#bottom", "cullface": "down"}
}
}
]
}

View File

@@ -0,0 +1,48 @@
{
"credit": "Made with Blockbench",
"parent": "block/block",
"textures": {
"particle": "#side"
},
"elements": [
{
"from": [5, 0, 4],
"to": [11, 14, 5],
"faces": {
"east": {"uv": [11, 2, 12, 16], "texture": "#side"},
"west": {"uv": [4, 2, 5, 16], "texture": "#side"},
"up": {"uv": [5, 4, 11, 5], "texture": "#top"},
"down": {"uv": [5, 11, 11, 12], "texture": "#bottom", "cullface": "down"}
}
},
{
"from": [5, 0, 5],
"to": [11, 14, 11],
"faces": {
"south": {"uv": [5, 2, 11, 16], "texture": "#side"},
"up": {"uv": [5, 5, 11, 11], "texture": "#top"},
"down": {"uv": [5, 5, 11, 11], "texture": "#bottom", "cullface": "down"}
}
},
{
"from": [4, 0, 5],
"to": [5, 14, 11],
"faces": {
"north": {"uv": [11, 2, 12, 16], "texture": "#side"},
"south": {"uv": [4, 2, 5, 16], "texture": "#side"},
"up": {"uv": [4, 5, 5, 11], "texture": "#top"},
"down": {"uv": [4, 5, 5, 11], "texture": "#bottom", "cullface": "down"}
}
},
{
"from": [11, 0, 5],
"to": [12, 14, 11],
"faces": {
"north": {"uv": [4, 2, 5, 16], "texture": "#side"},
"south": {"uv": [11, 2, 12, 16], "texture": "#side"},
"up": {"uv": [11, 5, 12, 11], "texture": "#top"},
"down": {"uv": [11, 5, 12, 11], "texture": "#bottom", "cullface": "down"}
}
}
]
}

View File

@@ -0,0 +1,65 @@
{
"credit": "Made with Blockbench",
"parent": "block/block",
"textures": {
"particle": "#side"
},
"elements": [
{
"from": [5, 0, 4],
"to": [11, 14, 5],
"faces": {
"east": {"uv": [11, 2, 12, 16], "texture": "#side"},
"west": {"uv": [4, 2, 5, 16], "texture": "#side"},
"up": {"uv": [5, 4, 11, 5], "texture": "#top"},
"down": {"uv": [5, 11, 11, 12], "texture": "#bottom", "cullface": "down"}
}
},
{
"from": [8, 0, 5],
"to": [11, 14, 8],
"faces": {
"east": {"uv": [8, 2, 11, 16], "texture": "#side"},
"south": {"uv": [8, 2, 11, 16], "texture": "#side"},
"up": {"uv": [8, 5, 11, 8], "texture": "#top"},
"down": {"uv": [8, 8, 11, 11], "texture": "#bottom", "cullface": "down"}
}
},
{
"from": [5, 14, 5],
"to": [8, 16, 8],
"faces": {
"north": {"uv": [8, 0, 11, 2], "texture": "#side"},
"east": {"uv": [8, 0, 11, 2], "texture": "#side"},
"up": {"uv": [5, 5, 8, 8], "texture": "#top", "cullface": "up"}
}
},
{
"from": [5, 0, 8],
"to": [8, 16, 11],
"faces": {
"east": {"uv": [5, 0, 8, 16], "texture": "#side"},
"south": {"uv": [5, 0, 8, 16], "texture": "#side"},
"up": {"uv": [5, 8, 8, 11], "texture": "#top", "cullface": "up"},
"down": {"uv": [5, 5, 8, 8], "texture": "#bottom", "cullface": "down"}
}
},
{
"from": [5, 0, 5],
"to": [8, 14, 8],
"faces": {
"down": {"uv": [5, 8, 8, 11], "texture": "#bottom", "cullface": "down"}
}
},
{
"from": [4, 0, 5],
"to": [5, 16, 11],
"faces": {
"north": {"uv": [11, 0, 12, 16], "texture": "#side"},
"south": {"uv": [4, 0, 5, 16], "texture": "#side"},
"up": {"uv": [4, 5, 5, 11], "texture": "#top", "cullface": "up"},
"down": {"uv": [4, 5, 5, 11], "texture": "#bottom", "cullface": "down"}
}
}
]
}

View File

@@ -0,0 +1,88 @@
{
"credit": "Made with Blockbench",
"parent": "block/block",
"textures": {
"particle": "#side"
},
"elements": [
{
"from": [5, 0, 4],
"to": [11, 16, 5],
"faces": {
"east": {"uv": [11, 0, 12, 16], "texture": "#side"},
"west": {"uv": [4, 0, 5, 16], "texture": "#side"},
"up": {"uv": [5, 4, 11, 5], "texture": "#top", "cullface": "up"},
"down": {"uv": [5, 11, 11, 12], "texture": "#bottom", "cullface": "down"}
}
},
{
"from": [8, 0, 8],
"to": [11, 14, 11],
"faces": {
"south": {"uv": [8, 2, 11, 16], "texture": "#side"},
"up": {"uv": [8, 8, 11, 11], "texture": "#top"},
"down": {"uv": [8, 5, 11, 8], "texture": "#bottom", "cullface": "down"}
}
},
{
"from": [8, 14, 5],
"to": [11, 16, 8],
"faces": {
"east": {"uv": [8, 0, 11, 2], "texture": "#side"},
"south": {"uv": [8, 0, 11, 2], "texture": "#side"},
"up": {"uv": [8, 5, 11, 8], "texture": "#top", "cullface": "up"}
}
},
{
"from": [5, 14, 8],
"to": [8, 16, 11],
"faces": {
"east": {"uv": [5, 0, 8, 2], "texture": "#side"},
"south": {"uv": [5, 0, 8, 2], "texture": "#side"},
"up": {"uv": [5, 8, 8, 11], "texture": "#top", "cullface": "up"}
}
},
{
"from": [5, 14, 5],
"to": [8, 16, 8],
"faces": {
"up": {"uv": [5, 5, 8, 8], "texture": "#top", "cullface": "up"}
}
},
{
"from": [5, 0, 5],
"to": [11, 14, 8],
"faces": {
"down": {"uv": [5, 8, 11, 11], "texture": "#bottom", "cullface": "down"}
}
},
{
"from": [5, 0, 8],
"to": [8, 14, 11],
"faces": {
"south": {"uv": [5, 2, 8, 16], "texture": "#side"},
"down": {"uv": [5, 5, 8, 8], "texture": "#bottom", "cullface": "down"}
}
},
{
"from": [4, 0, 5],
"to": [5, 16, 11],
"faces": {
"north": {"uv": [11, 0, 12, 16], "texture": "#side"},
"south": {"uv": [4, 0, 5, 16], "texture": "#side"},
"up": {"uv": [4, 5, 5, 11], "texture": "#top", "cullface": "up"},
"down": {"uv": [4, 5, 5, 11], "texture": "#bottom", "cullface": "down"}
}
},
{
"from": [11, 0, 5],
"to": [12, 14, 11],
"faces": {
"north": {"uv": [4, 2, 5, 16], "texture": "#side"},
"south": {"uv": [11, 2, 12, 16], "texture": "#side"},
"up": {"uv": [11, 5, 12, 11], "texture": "#top"},
"down": {"uv": [11, 5, 12, 11], "texture": "#bottom", "cullface": "down"}
}
}
]
}

View File

@@ -0,0 +1,38 @@
{
"credit": "Made with Blockbench",
"parent": "block/block",
"textures": {
"particle": "#side"
},
"elements": [
{
"from": [5, 0, 4],
"to": [11, 14, 8],
"faces": {
"east": {"uv": [8, 2, 12, 16], "texture": "#side"},
"west": {"uv": [4, 2, 8, 16], "texture": "#side"},
"up": {"uv": [5, 4, 11, 8], "texture": "#top"},
"down": {"uv": [5, 8, 11, 12], "texture": "#bottom", "cullface": "down"}
}
},
{
"from": [5, 14, 8],
"to": [11, 16, 12],
"faces": {
"north": {"uv": [5, 0, 11, 2], "texture": "#side"},
"east": {"uv": [4, 0, 8, 2], "texture": "#side"},
"west": {"uv": [8, 0, 12, 2], "texture": "#side"},
"up": {"uv": [5, 8, 11, 12], "texture": "#top", "cullface": "up"}
}
},
{
"from": [5, 0, 8],
"to": [11, 14, 12],
"faces": {
"east": {"uv": [4, 2, 8, 16], "texture": "#side"},
"west": {"uv": [8, 2, 12, 16], "texture": "#side"},
"down": {"uv": [5, 4, 11, 8], "texture": "#bottom", "cullface": "down"}
}
}
]
}

View File

@@ -0,0 +1,57 @@
{
"credit": "Made with Blockbench",
"parent": "block/block",
"textures": {
"particle": "#side"
},
"elements": [
{
"from": [5, 0, 4],
"to": [11, 14, 5],
"faces": {
"east": {"uv": [11, 2, 12, 16], "texture": "#side"},
"west": {"uv": [4, 2, 5, 16], "texture": "#side"},
"up": {"uv": [5, 4, 11, 5], "texture": "#top"},
"down": {"uv": [5, 11, 11, 12], "texture": "#bottom", "cullface": "down"}
}
},
{
"from": [5, 0, 11],
"to": [11, 14, 12],
"faces": {
"east": {"uv": [4, 2, 5, 16], "texture": "#side"},
"west": {"uv": [11, 2, 12, 16], "texture": "#side"},
"up": {"uv": [5, 11, 11, 12], "texture": "#top"},
"down": {"uv": [5, 4, 11, 5], "texture": "#bottom", "cullface": "down"}
}
},
{
"from": [5, 0, 5],
"to": [11, 14, 11],
"faces": {
"up": {"uv": [5, 5, 11, 11], "texture": "#top"},
"down": {"uv": [5, 5, 11, 11], "texture": "#bottom", "cullface": "down"}
}
},
{
"from": [4, 0, 5],
"to": [5, 14, 11],
"faces": {
"north": {"uv": [11, 2, 12, 16], "texture": "#side"},
"south": {"uv": [4, 2, 5, 16], "texture": "#side"},
"up": {"uv": [4, 5, 5, 11], "texture": "#top"},
"down": {"uv": [4, 5, 5, 11], "texture": "#bottom", "cullface": "down"}
}
},
{
"from": [11, 0, 5],
"to": [12, 14, 11],
"faces": {
"north": {"uv": [4, 2, 5, 16], "texture": "#side"},
"south": {"uv": [11, 2, 12, 16], "texture": "#side"},
"up": {"uv": [11, 5, 12, 11], "texture": "#top"},
"down": {"uv": [11, 5, 12, 11], "texture": "#bottom", "cullface": "down"}
}
}
]
}

View File

@@ -0,0 +1,20 @@
{
"credit": "Made with Blockbench",
"parent": "block/block",
"textures": {
"particle": "#side"
},
"elements": [
{
"from": [5, 0, 4],
"to": [11, 16, 8],
"faces": {
"east": {"uv": [8, 0, 12, 16], "texture": "#side"},
"south": {"uv": [5, 0, 11, 16], "texture": "#side"},
"west": {"uv": [4, 0, 8, 16], "texture": "#side"},
"up": {"uv": [5, 4, 11, 8], "texture": "#top", "cullface": "up"},
"down": {"uv": [5, 8, 11, 12], "texture": "#bottom", "cullface": "down"}
}
}
]
}

View File

@@ -0,0 +1,57 @@
{
"credit": "Made with Blockbench",
"parent": "block/block",
"textures": {
"particle": "#side"
},
"elements": [
{
"from": [5, 0, 4],
"to": [11, 16, 5],
"faces": {
"east": {"uv": [11, 0, 12, 16], "texture": "#side"},
"west": {"uv": [4, 0, 5, 16], "texture": "#side"},
"up": {"uv": [5, 4, 11, 5], "texture": "#top", "cullface": "up"},
"down": {"uv": [5, 11, 11, 12], "texture": "#bottom", "cullface": "down"}
}
},
{
"from": [8, 0, 5],
"to": [11, 16, 8],
"faces": {
"east": {"uv": [8, 0, 11, 16], "texture": "#side"},
"south": {"uv": [8, 0, 11, 16], "texture": "#side"},
"up": {"uv": [8, 5, 11, 8], "texture": "#top", "cullface": "up"},
"down": {"uv": [8, 8, 11, 11], "texture": "#bottom", "cullface": "down"}
}
},
{
"from": [5, 0, 8],
"to": [8, 16, 11],
"faces": {
"east": {"uv": [5, 0, 8, 16], "texture": "#side"},
"south": {"uv": [5, 0, 8, 16], "texture": "#side"},
"up": {"uv": [5, 8, 8, 11], "texture": "#top", "cullface": "up"},
"down": {"uv": [5, 5, 8, 8], "texture": "#bottom", "cullface": "down"}
}
},
{
"from": [5, 0, 5],
"to": [8, 16, 8],
"faces": {
"up": {"uv": [5, 5, 8, 8], "texture": "#top", "cullface": "up"},
"down": {"uv": [5, 8, 8, 11], "texture": "#bottom", "cullface": "down"}
}
},
{
"from": [4, 0, 5],
"to": [5, 16, 11],
"faces": {
"north": {"uv": [11, 0, 12, 16], "texture": "#side"},
"south": {"uv": [4, 0, 5, 16], "texture": "#side"},
"up": {"uv": [4, 5, 5, 11], "texture": "#top", "cullface": "up"},
"down": {"uv": [4, 5, 5, 11], "texture": "#bottom", "cullface": "down"}
}
}
]
}

View File

@@ -0,0 +1,96 @@
{
"credit": "Made with Blockbench",
"parent": "block/block",
"textures": {
"particle": "#side"
},
"elements": [
{
"from": [5, 0, 4],
"to": [11, 16, 5],
"faces": {
"east": {"uv": [11, 0, 12, 16], "texture": "#side"},
"west": {"uv": [4, 0, 5, 16], "texture": "#side"},
"up": {"uv": [5, 4, 11, 5], "texture": "#top", "cullface": "up"},
"down": {"uv": [5, 11, 11, 12], "texture": "#bottom", "cullface": "down"}
}
},
{
"from": [5, 0, 11],
"to": [11, 14, 12],
"faces": {
"east": {"uv": [4, 2, 5, 16], "texture": "#side"},
"west": {"uv": [11, 2, 12, 16], "texture": "#side"},
"up": {"uv": [5, 11, 11, 12], "texture": "#top"},
"down": {"uv": [5, 4, 11, 5], "texture": "#bottom", "cullface": "down"}
}
},
{
"from": [5, 0, 8],
"to": [8, 14, 11],
"faces": {
"up": {"uv": [5, 8, 8, 11], "texture": "#top"},
"down": {"uv": [5, 5, 8, 8], "texture": "#bottom", "cullface": "down"}
}
},
{
"from": [8, 14, 8],
"to": [11, 16, 11],
"faces": {
"south": {"uv": [8, 0, 11, 2], "texture": "#side"},
"west": {"uv": [8, 0, 11, 2], "texture": "#side"},
"up": {"uv": [8, 8, 11, 11], "texture": "#top", "cullface": "up"}
}
},
{
"from": [8, 14, 5],
"to": [11, 16, 8],
"faces": {
"up": {"uv": [8, 5, 11, 8], "texture": "#top", "cullface": "up"}
}
},
{
"from": [5, 14, 5],
"to": [8, 16, 8],
"faces": {
"south": {"uv": [5, 0, 8, 2], "texture": "#side"},
"west": {"uv": [5, 0, 8, 2], "texture": "#side"},
"up": {"uv": [5, 5, 8, 8], "texture": "#top", "cullface": "up"}
}
},
{
"from": [8, 0, 5],
"to": [11, 14, 11],
"faces": {
"down": {"uv": [8, 5, 11, 11], "texture": "#bottom", "cullface": "down"}
}
},
{
"from": [5, 0, 5],
"to": [8, 14, 8],
"faces": {
"down": {"uv": [5, 8, 8, 11], "texture": "#bottom", "cullface": "down"}
}
},
{
"from": [4, 0, 5],
"to": [5, 14, 11],
"faces": {
"north": {"uv": [11, 2, 12, 16], "texture": "#side"},
"south": {"uv": [4, 2, 5, 16], "texture": "#side"},
"up": {"uv": [4, 5, 5, 11], "texture": "#top"},
"down": {"uv": [4, 5, 5, 11], "texture": "#bottom", "cullface": "down"}
}
},
{
"from": [11, 0, 5],
"to": [12, 16, 11],
"faces": {
"north": {"uv": [4, 0, 5, 16], "texture": "#side"},
"south": {"uv": [11, 0, 12, 16], "texture": "#side"},
"up": {"uv": [11, 5, 12, 11], "texture": "#top", "cullface": "up"},
"down": {"uv": [11, 5, 12, 11], "texture": "#bottom", "cullface": "down"}
}
}
]
}

View File

@@ -0,0 +1,88 @@
{
"credit": "Made with Blockbench",
"parent": "block/block",
"textures": {
"particle": "#side"
},
"elements": [
{
"from": [5, 0, 4],
"to": [11, 16, 5],
"faces": {
"east": {"uv": [11, 0, 12, 16], "texture": "#side"},
"west": {"uv": [4, 0, 5, 16], "texture": "#side"},
"up": {"uv": [5, 4, 11, 5], "texture": "#top", "cullface": "up"},
"down": {"uv": [5, 11, 11, 12], "texture": "#bottom", "cullface": "down"}
}
},
{
"from": [5, 0, 8],
"to": [8, 14, 11],
"faces": {
"south": {"uv": [5, 2, 8, 16], "texture": "#side"},
"up": {"uv": [5, 8, 8, 11], "texture": "#top"},
"down": {"uv": [5, 5, 8, 8], "texture": "#bottom", "cullface": "down"}
}
},
{
"from": [5, 14, 5],
"to": [8, 16, 8],
"faces": {
"south": {"uv": [5, 0, 8, 2], "texture": "#side"},
"west": {"uv": [5, 0, 8, 2], "texture": "#side"},
"up": {"uv": [5, 5, 8, 8], "texture": "#top", "cullface": "up"}
}
},
{
"from": [8, 14, 8],
"to": [11, 16, 11],
"faces": {
"south": {"uv": [8, 0, 11, 2], "texture": "#side"},
"west": {"uv": [8, 0, 11, 2], "texture": "#side"},
"up": {"uv": [8, 8, 11, 11], "texture": "#top", "cullface": "up"}
}
},
{
"from": [8, 14, 5],
"to": [11, 16, 8],
"faces": {
"up": {"uv": [8, 5, 11, 8], "texture": "#top", "cullface": "up"}
}
},
{
"from": [5, 0, 5],
"to": [11, 14, 8],
"faces": {
"down": {"uv": [5, 8, 11, 11], "texture": "#bottom", "cullface": "down"}
}
},
{
"from": [8, 0, 8],
"to": [11, 14, 11],
"faces": {
"south": {"uv": [8, 2, 11, 16], "texture": "#side"},
"down": {"uv": [8, 5, 11, 8], "texture": "#bottom", "cullface": "down"}
}
},
{
"from": [11, 0, 5],
"to": [12, 16, 11],
"faces": {
"north": {"uv": [4, 0, 5, 16], "texture": "#side"},
"south": {"uv": [11, 0, 12, 16], "texture": "#side"},
"up": {"uv": [11, 5, 12, 11], "texture": "#top", "cullface": "up"},
"down": {"uv": [11, 5, 12, 11], "texture": "#bottom", "cullface": "down"}
}
},
{
"from": [4, 0, 5],
"to": [5, 14, 11],
"faces": {
"north": {"uv": [11, 2, 12, 16], "texture": "#side"},
"south": {"uv": [4, 2, 5, 16], "texture": "#side"},
"up": {"uv": [4, 5, 5, 11], "texture": "#top"},
"down": {"uv": [4, 5, 5, 11], "texture": "#bottom", "cullface": "down"}
}
}
]
}

View File

@@ -0,0 +1,19 @@
{
"credit": "Made with Blockbench",
"parent": "block/block",
"textures": {
"particle": "#side"
},
"elements": [
{
"from": [5, 0, 4],
"to": [11, 16, 12],
"faces": {
"east": {"uv": [4, 0, 12, 16], "texture": "#side"},
"west": {"uv": [4, 0, 12, 16], "texture": "#side"},
"up": {"uv": [5, 4, 11, 12], "texture": "#top", "cullface": "up"},
"down": {"uv": [5, 4, 11, 12], "texture": "#bottom", "cullface": "down"}
}
}
]
}

View File

@@ -0,0 +1,65 @@
{
"credit": "Made with Blockbench",
"parent": "block/block",
"textures": {
"particle": "#side"
},
"elements": [
{
"from": [5, 0, 4],
"to": [11, 14, 5],
"faces": {
"east": {"uv": [11, 0, 12, 16], "texture": "#side"},
"west": {"uv": [4, 0, 5, 16], "texture": "#side"},
"up": {"uv": [5, 4, 11, 5], "texture": "#top"},
"down": {"uv": [5, 11, 11, 12], "texture": "#bottom", "cullface": "down"}
}
},
{
"from": [5, 0, 11],
"to": [11, 14, 12],
"faces": {
"east": {"uv": [4, 2, 5, 16], "texture": "#side"},
"west": {"uv": [11, 2, 12, 16], "texture": "#side"},
"up": {"uv": [5, 11, 11, 12], "texture": "#top"},
"down": {"uv": [5, 4, 11, 5], "texture": "#bottom", "cullface": "down"}
}
},
{
"from": [5, 14, 5],
"to": [11, 16, 11],
"faces": {
"north": {"uv": [5, 0, 11, 2], "texture": "#side"},
"south": {"uv": [5, 0, 11, 2], "texture": "#side"},
"up": {"uv": [5, 5, 11, 11], "texture": "#top", "cullface": "up"}
}
},
{
"from": [5, 0, 5],
"to": [11, 14, 11],
"faces": {
"down": {"uv": [5, 5, 11, 11], "texture": "#bottom", "cullface": "down"}
}
},
{
"from": [4, 0, 5],
"to": [5, 16, 11],
"faces": {
"north": {"uv": [11, 0, 12, 16], "texture": "#side"},
"south": {"uv": [4, 0, 5, 16], "texture": "#side"},
"up": {"uv": [4, 5, 5, 11], "texture": "#top", "cullface": "up"},
"down": {"uv": [4, 5, 5, 11], "texture": "#bottom", "cullface": "down"}
}
},
{
"from": [11, 0, 5],
"to": [12, 16, 11],
"faces": {
"north": {"uv": [4, 0, 5, 16], "texture": "#side"},
"south": {"uv": [11, 0, 12, 16], "texture": "#side"},
"up": {"uv": [11, 5, 12, 11], "texture": "#top", "cullface": "up"},
"down": {"uv": [11, 5, 12, 11], "texture": "#bottom", "cullface": "down"}
}
}
]
}

View File

@@ -0,0 +1,56 @@
{
"credit": "Made with Blockbench",
"parent": "block/block",
"textures": {
"particle": "#side"
},
"elements": [
{
"from": [5, 0, 4],
"to": [11, 14, 5],
"faces": {
"east": {"uv": [11, 2, 12, 16], "texture": "#side"},
"west": {"uv": [4, 2, 5, 16], "texture": "#side"},
"up": {"uv": [5, 4, 11, 5], "texture": "#top"},
"down": {"uv": [5, 11, 11, 12], "texture": "#bottom", "cullface": "down"}
}
},
{
"from": [5, 14, 5],
"to": [11, 16, 11],
"faces": {
"north": {"uv": [5, 0, 11, 2], "texture": "#side"},
"south": {"uv": [5, 0, 11, 2], "texture": "#side"},
"up": {"uv": [5, 5, 11, 11], "texture": "#top", "cullface": "up"}
}
},
{
"from": [5, 0, 5],
"to": [11, 14, 11],
"faces": {
"south": {"uv": [5, 2, 11, 16], "texture": "#side"},
"down": {"uv": [5, 5, 11, 11], "texture": "#bottom", "cullface": "down"}
}
},
{
"from": [4, 0, 5],
"to": [5, 16, 11],
"faces": {
"north": {"uv": [11, 0, 12, 16], "texture": "#side"},
"south": {"uv": [4, 0, 5, 16], "texture": "#side"},
"up": {"uv": [4, 5, 5, 11], "texture": "#top", "cullface": "up"},
"down": {"uv": [4, 5, 5, 11], "texture": "#bottom", "cullface": "down"}
}
},
{
"from": [11, 0, 5],
"to": [12, 16, 11],
"faces": {
"north": {"uv": [4, 0, 5, 16], "texture": "#side"},
"south": {"uv": [11, 0, 12, 16], "texture": "#side"},
"up": {"uv": [11, 5, 12, 11], "texture": "#top", "cullface": "up"},
"down": {"uv": [11, 5, 12, 11], "texture": "#bottom", "cullface": "down"}
}
}
]
}

View File

@@ -0,0 +1,65 @@
{
"credit": "Made with Blockbench",
"parent": "block/block",
"textures": {
"particle": "#side"
},
"elements": [
{
"from": [5, 0, 4],
"to": [11, 16, 5],
"faces": {
"east": {"uv": [11, 0, 12, 16], "texture": "#side"},
"west": {"uv": [4, 0, 5, 16], "texture": "#side"},
"up": {"uv": [5, 4, 11, 5], "texture": "#top", "cullface": "up"},
"down": {"uv": [5, 11, 11, 12], "texture": "#bottom", "cullface": "down"}
}
},
{
"from": [5, 0, 8],
"to": [8, 14, 11],
"faces": {
"east": {"uv": [5, 2, 8, 16], "texture": "#side"},
"south": {"uv": [5, 2, 8, 16], "texture": "#side"},
"up": {"uv": [5, 8, 8, 11], "texture": "#top"},
"down": {"uv": [5, 5, 8, 8], "texture": "#bottom", "cullface": "down"}
}
},
{
"from": [5, 14, 5],
"to": [8, 16, 8],
"faces": {
"south": {"uv": [5, 0, 8, 2], "texture": "#side"},
"west": {"uv": [5, 0, 8, 2], "texture": "#side"},
"up": {"uv": [5, 5, 8, 8], "texture": "#top", "cullface": "up"}
}
},
{
"from": [8, 0, 5],
"to": [11, 16, 8],
"faces": {
"east": {"uv": [8, 0, 11, 16], "texture": "#side"},
"south": {"uv": [8, 0, 11, 16], "texture": "#side"},
"up": {"uv": [8, 5, 11, 8], "texture": "#top", "cullface": "up"},
"down": {"uv": [8, 8, 11, 11], "texture": "#bottom", "cullface": "down"}
}
},
{
"from": [5, 0, 5],
"to": [8, 14, 8],
"faces": {
"down": {"uv": [5, 8, 8, 11], "texture": "#bottom", "cullface": "down"}
}
},
{
"from": [4, 0, 5],
"to": [5, 14, 11],
"faces": {
"north": {"uv": [11, 2, 12, 16], "texture": "#side"},
"south": {"uv": [4, 2, 5, 16], "texture": "#side"},
"up": {"uv": [4, 5, 5, 11], "texture": "#top"},
"down": {"uv": [4, 5, 5, 11], "texture": "#bottom", "cullface": "down"}
}
}
]
}

View File

@@ -0,0 +1,66 @@
{
"credit": "Made with Blockbench",
"parent": "block/block",
"textures": {
"particle": "#side"
},
"elements": [
{
"from": [5, 0, 4],
"to": [11, 14, 5],
"faces": {
"east": {"uv": [11, 2, 12, 16], "texture": "#side"},
"west": {"uv": [4, 2, 5, 16], "texture": "#side"},
"up": {"uv": [5, 4, 11, 5], "texture": "#top"},
"down": {"uv": [5, 11, 11, 12], "texture": "#bottom", "cullface": "down"}
}
},
{
"from": [5, 0, 5],
"to": [8, 14, 11],
"faces": {
"south": {"uv": [5, 2, 8, 16], "texture": "#side"},
"up": {"uv": [5, 5, 8, 11], "texture": "#top"},
"down": {"uv": [5, 5, 8, 11], "texture": "#bottom", "cullface": "down"}
}
},
{
"from": [8, 14, 5],
"to": [11, 16, 11],
"faces": {
"north": {"uv": [5, 0, 8, 2], "texture": "#side"},
"south": {"uv": [8, 0, 11, 2], "texture": "#side"},
"west": {"uv": [5, 0, 11, 2], "texture": "#side"},
"up": {"uv": [8, 5, 11, 11], "texture": "#top", "cullface": "up"}
}
},
{
"from": [8, 0, 5],
"to": [11, 14, 11],
"faces": {
"south": {"uv": [8, 2, 11, 16], "texture": "#side"},
"down": {"uv": [8, 5, 11, 11], "texture": "#bottom", "cullface": "down"}
}
},
{
"from": [4, 0, 5],
"to": [5, 14, 11],
"faces": {
"north": {"uv": [11, 2, 12, 16], "texture": "#side"},
"south": {"uv": [4, 2, 5, 16], "texture": "#side"},
"up": {"uv": [4, 5, 5, 11], "texture": "#top"},
"down": {"uv": [4, 5, 5, 11], "texture": "#bottom", "cullface": "down"}
}
},
{
"from": [11, 0, 5],
"to": [12, 16, 11],
"faces": {
"north": {"uv": [4, 0, 5, 16], "texture": "#side"},
"south": {"uv": [11, 0, 12, 16], "texture": "#side"},
"up": {"uv": [11, 5, 12, 11], "texture": "#top", "cullface": "up"},
"down": {"uv": [11, 5, 12, 11], "texture": "#bottom", "cullface": "down"}
}
}
]
}

View File

@@ -0,0 +1,74 @@
{
"credit": "Made with Blockbench",
"parent": "block/block",
"textures": {
"particle": "#side"
},
"elements": [
{
"from": [5, 0, 4],
"to": [11, 14, 5],
"faces": {
"east": {"uv": [11, 2, 12, 16], "texture": "#side"},
"west": {"uv": [4, 2, 5, 16], "texture": "#side"},
"up": {"uv": [5, 4, 11, 5], "texture": "#top"},
"down": {"uv": [5, 11, 11, 12], "texture": "#bottom", "cullface": "down"}
}
},
{
"from": [5, 0, 11],
"to": [11, 14, 12],
"faces": {
"east": {"uv": [4, 2, 5, 16], "texture": "#side"},
"west": {"uv": [11, 2, 12, 16], "texture": "#side"},
"up": {"uv": [5, 11, 11, 12], "texture": "#top"},
"down": {"uv": [5, 4, 11, 5], "texture": "#bottom", "cullface": "down"}
}
},
{
"from": [5, 0, 5],
"to": [8, 14, 11],
"faces": {
"up": {"uv": [5, 5, 8, 11], "texture": "#top"},
"down": {"uv": [5, 5, 8, 11], "texture": "#bottom", "cullface": "down"}
}
},
{
"from": [8, 14, 5],
"to": [11, 16, 11],
"faces": {
"north": {"uv": [5, 0, 8, 2], "texture": "#side"},
"south": {"uv": [8, 0, 11, 2], "texture": "#side"},
"west": {"uv": [5, 0, 11, 2], "texture": "#side"},
"up": {"uv": [8, 5, 11, 11], "texture": "#top", "cullface": "up"}
}
},
{
"from": [8, 0, 5],
"to": [11, 14, 11],
"faces": {
"down": {"uv": [8, 5, 11, 11], "texture": "#bottom", "cullface": "down"}
}
},
{
"from": [4, 0, 5],
"to": [5, 14, 11],
"faces": {
"north": {"uv": [11, 2, 12, 16], "texture": "#side"},
"south": {"uv": [4, 2, 5, 16], "texture": "#side"},
"up": {"uv": [4, 5, 5, 11], "texture": "#top"},
"down": {"uv": [4, 5, 5, 11], "texture": "#bottom", "cullface": "down"}
}
},
{
"from": [11, 0, 5],
"to": [12, 16, 11],
"faces": {
"north": {"uv": [4, 0, 5, 16], "texture": "#side"},
"south": {"uv": [11, 0, 12, 16], "texture": "#side"},
"up": {"uv": [11, 5, 12, 11], "texture": "#top", "cullface": "up"},
"down": {"uv": [11, 5, 12, 11], "texture": "#bottom", "cullface": "down"}
}
}
]
}

View File

@@ -0,0 +1,48 @@
{
"credit": "Made with Blockbench",
"parent": "block/block",
"textures": {
"particle": "#side"
},
"elements": [
{
"from": [5, 0, 4],
"to": [11, 16, 5],
"faces": {
"east": {"uv": [11, 0, 12, 16], "texture": "#side"},
"west": {"uv": [4, 0, 5, 16], "texture": "#side"},
"up": {"uv": [5, 4, 11, 5], "texture": "#top", "cullface": "up"},
"down": {"uv": [5, 11, 11, 12], "texture": "#bottom", "cullface": "down"}
}
},
{
"from": [5, 0, 5],
"to": [11, 16, 11],
"faces": {
"south": {"uv": [5, 0, 11, 16], "texture": "#side"},
"up": {"uv": [5, 5, 11, 11], "texture": "#top", "cullface": "up"},
"down": {"uv": [5, 5, 11, 11], "texture": "#bottom", "cullface": "down"}
}
},
{
"from": [4, 0, 5],
"to": [5, 16, 11],
"faces": {
"north": {"uv": [11, 0, 12, 16], "texture": "#side"},
"south": {"uv": [4, 0, 5, 16], "texture": "#side"},
"up": {"uv": [4, 5, 5, 11], "texture": "#top", "cullface": "up"},
"down": {"uv": [4, 5, 5, 11], "texture": "#bottom", "cullface": "down"}
}
},
{
"from": [11, 0, 5],
"to": [12, 16, 11],
"faces": {
"north": {"uv": [4, 0, 5, 16], "texture": "#side"},
"south": {"uv": [11, 0, 12, 16], "texture": "#side"},
"up": {"uv": [11, 5, 12, 11], "texture": "#top", "cullface": "up"},
"down": {"uv": [11, 5, 12, 11], "texture": "#bottom", "cullface": "down"}
}
}
]
}

View File

@@ -0,0 +1,64 @@
{
"credit": "Made with Blockbench",
"parent": "block/block",
"textures": {
"particle": "#side"
},
"elements": [
{
"from": [5, 0, 4],
"to": [11, 16, 5],
"faces": {
"east": {"uv": [11, 0, 12, 16], "texture": "#side"},
"west": {"uv": [4, 0, 5, 16], "texture": "#side"},
"up": {"uv": [5, 4, 11, 5], "texture": "#top", "cullface": "up"},
"down": {"uv": [5, 11, 11, 12], "texture": "#bottom", "cullface": "down"}
}
},
{
"from": [5, 0, 11],
"to": [11, 14, 12],
"faces": {
"east": {"uv": [4, 2, 5, 16], "texture": "#side"},
"west": {"uv": [11, 2, 12, 16], "texture": "#side"},
"up": {"uv": [5, 11, 11, 12], "texture": "#top"},
"down": {"uv": [5, 4, 11, 5], "texture": "#bottom", "cullface": "down"}
}
},
{
"from": [5, 14, 5],
"to": [11, 16, 11],
"faces": {
"south": {"uv": [5, 0, 11, 2], "texture": "#side"},
"up": {"uv": [5, 5, 11, 11], "texture": "#top", "cullface": "up"}
}
},
{
"from": [5, 0, 5],
"to": [11, 14, 11],
"faces": {
"down": {"uv": [5, 5, 11, 11], "texture": "#bottom", "cullface": "down"}
}
},
{
"from": [4, 0, 5],
"to": [5, 16, 11],
"faces": {
"north": {"uv": [11, 0, 12, 16], "texture": "#side"},
"south": {"uv": [4, 0, 5, 16], "texture": "#side"},
"up": {"uv": [4, 5, 5, 11], "texture": "#top", "cullface": "up"},
"down": {"uv": [4, 5, 5, 11], "texture": "#bottom", "cullface": "down"}
}
},
{
"from": [11, 0, 5],
"to": [12, 16, 11],
"faces": {
"north": {"uv": [4, 0, 5, 16], "texture": "#side"},
"south": {"uv": [11, 0, 12, 16], "texture": "#side"},
"up": {"uv": [11, 5, 12, 11], "texture": "#top", "cullface": "up"},
"down": {"uv": [11, 5, 12, 11], "texture": "#bottom", "cullface": "down"}
}
}
]
}

View File

@@ -0,0 +1,57 @@
{
"credit": "Made with Blockbench",
"parent": "block/block",
"textures": {
"particle": "#side"
},
"elements": [
{
"from": [5, 0, 4],
"to": [11, 16, 5],
"faces": {
"east": {"uv": [11, 0, 12, 16], "texture": "#side"},
"west": {"uv": [4, 0, 5, 16], "texture": "#side"},
"up": {"uv": [5, 4, 11, 5], "texture": "#top", "cullface": "up"},
"down": {"uv": [5, 11, 11, 12], "texture": "#bottom", "cullface": "down"}
}
},
{
"from": [5, 0, 11],
"to": [11, 16, 12],
"faces": {
"east": {"uv": [4, 0, 5, 16], "texture": "#side"},
"west": {"uv": [11, 0, 12, 16], "texture": "#side"},
"up": {"uv": [5, 11, 11, 12], "texture": "#top", "cullface": "up"},
"down": {"uv": [5, 4, 11, 5], "texture": "#bottom", "cullface": "down"}
}
},
{
"from": [5, 0, 5],
"to": [11, 16, 11],
"faces": {
"up": {"uv": [5, 5, 11, 11], "texture": "#top", "cullface": "up"},
"down": {"uv": [5, 5, 11, 11], "texture": "#bottom", "cullface": "down"}
}
},
{
"from": [4, 0, 5],
"to": [5, 16, 11],
"faces": {
"north": {"uv": [11, 0, 12, 16], "texture": "#side"},
"south": {"uv": [4, 0, 5, 16], "texture": "#side"},
"up": {"uv": [4, 5, 5, 11], "texture": "#top", "cullface": "up"},
"down": {"uv": [4, 5, 5, 11], "texture": "#bottom", "cullface": "down"}
}
},
{
"from": [11, 0, 5],
"to": [12, 16, 11],
"faces": {
"north": {"uv": [4, 0, 5, 16], "texture": "#side"},
"south": {"uv": [11, 0, 12, 16], "texture": "#side"},
"up": {"uv": [11, 5, 12, 11], "texture": "#top", "cullface": "up"},
"down": {"uv": [11, 5, 12, 11], "texture": "#bottom", "cullface": "down"}
}
}
]
}

View File

@@ -0,0 +1,17 @@
{
"credit": "Made with Blockbench",
"parent": "block/block",
"textures": {
"particle": "#side"
},
"elements": [
{
"from": [5, 0, 5],
"to": [11, 16, 11],
"faces": {
"up": {"uv": [5, 5, 11, 11], "texture": "#top", "cullface": "up"},
"down": {"uv": [5, 5, 11, 11], "texture": "#bottom", "cullface": "down"}
}
}
]
}

View File

@@ -0,0 +1,34 @@
{
"credit": "Made with Blockbench",
"parent": "block/block",
"textures": {
"particle": "#side"
},
"elements": [
{
"from": [4, 0, 4],
"to": [5, 14, 5],
"faces": {
"north": {"uv": [11, 2, 12, 16], "texture": "#side"},
"west": {"uv": [4, 2, 5, 16], "texture": "#side"},
"down": {"uv": [4, 11, 5, 12], "texture": "#bottom", "cullface": "down"}
}
},
{
"from": [5, 0, 4],
"to": [11, 14, 5],
"faces": {
"down": {"uv": [5, 11, 11, 12], "texture": "#bottom", "cullface": "down"}
}
},
{
"from": [4, 14, 4],
"to": [11, 16, 5],
"faces": {
"north": {"uv": [5, 0, 12, 2], "texture": "#side"},
"west": {"uv": [4, 0, 5, 2], "texture": "#side"},
"up": {"uv": [5, 4, 12, 5], "texture": "#top", "cullface": "up"}
}
}
]
}

View File

@@ -0,0 +1,28 @@
{
"credit": "Made with Blockbench",
"parent": "block/block",
"textures": {
"particle": "#side"
},
"elements": [
{
"from": [4, 0, 4],
"to": [5, 16, 5],
"faces": {
"north": {"uv": [11, 0, 12, 16], "texture": "#side"},
"west": {"uv": [4, 0, 5, 16], "texture": "#side"},
"up": {"uv": [4, 4, 5, 5], "texture": "#top", "cullface": "up"},
"down": {"uv": [4, 11, 5, 12], "texture": "#bottom", "cullface": "down"}
}
},
{
"from": [5, 0, 4],
"to": [11, 16, 5],
"faces": {
"north": {"uv": [5, 0, 11, 16], "texture": "#side"},
"up": {"uv": [5, 4, 11, 5], "texture": "#top", "cullface": "up"},
"down": {"uv": [5, 11, 11, 12], "texture": "#bottom", "cullface": "down"}
}
}
]
}

View File

@@ -0,0 +1,27 @@
{
"credit": "Made with Blockbench",
"parent": "block/block",
"textures": {
"particle": "#side"
},
"elements": [
{
"from": [4, 0, 4],
"to": [5, 16, 5],
"faces": {
"north": {"uv": [11, 0, 12, 16], "texture": "#side"},
"west": {"uv": [4, 0, 5, 16], "texture": "#side"},
"up": {"uv": [4, 4, 5, 5], "texture": "#top", "cullface": "up"},
"down": {"uv": [4, 11, 5, 12], "texture": "#bottom", "cullface": "down"}
}
},
{
"from": [5, 0, 4],
"to": [11, 16, 5],
"faces": {
"up": {"uv": [5, 4, 11, 5], "texture": "#top", "cullface": "up"},
"down": {"uv": [5, 11, 11, 12], "texture": "#bottom", "cullface": "down"}
}
}
]
}

View File

@@ -0,0 +1,20 @@
{
"credit": "Made with Blockbench",
"parent": "block/block",
"textures": {
"particle": "#side"
},
"elements": [
{
"from": [5, 0, 0],
"to": [11, 14, 4],
"faces": {
"north": {"uv": [5, 2, 11, 16], "texture": "#side", "cullface": "north"},
"east": {"uv": [12, 2, 16, 16], "texture": "#side"},
"west": {"uv": [0, 2, 4, 16], "texture": "#side"},
"up": {"uv": [5, 0, 11, 4], "texture": "#top"},
"down": {"uv": [5, 12, 11, 16], "texture": "#bottom", "cullface": "down"}
}
}
]
}

View File

@@ -0,0 +1,20 @@
{
"credit": "Made with Blockbench",
"parent": "block/block",
"textures": {
"particle": "#side"
},
"elements": [
{
"from": [5, 0, 0],
"to": [11, 16, 4],
"faces": {
"north": {"uv": [5, 0, 11, 16], "texture": "#side", "cullface": "north"},
"east": {"uv": [12, 0, 16, 16], "texture": "#side"},
"west": {"uv": [0, 0, 4, 16], "texture": "#side"},
"up": {"uv": [5, 0, 11, 4], "texture": "#top", "cullface": "up"},
"down": {"uv": [5, 12, 11, 16], "texture": "#bottom", "cullface": "down"}
}
}
]
}

Some files were not shown because too many files have changed in this diff Show More