Compare commits
40 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| e872fe046c | |||
| fd26f5da4a | |||
| dbcb79f992 | |||
| 8d8a0e3654 | |||
| 5c6fbff52e | |||
| 2f9cf1e57d | |||
| a470724d81 | |||
| b825959626 | |||
| 083d39562a | |||
| e592db1ea2 | |||
| 1fa55064c7 | |||
| e8c06a7fb3 | |||
| d7ae1f646f | |||
| e3dac8a77f | |||
| 5281f84a2a | |||
| eac948bf5d | |||
| 12924579a5 | |||
| 48c7c4e538 | |||
| d325e3c5a5 | |||
| 4d353bab27 | |||
| 6f8304d638 | |||
| 3bf9fc2268 | |||
| 5812812bd9 | |||
| 1e6cab04cc | |||
| d7ad6ed0c1 | |||
| 8a9fbd9109 | |||
| a76714d54d | |||
| b99f315c6f | |||
| 7df46a4b76 | |||
| 42049047f7 | |||
| ddffd45a44 | |||
| fcf02b68e6 | |||
| b88a4abfe5 | |||
| ce650abc76 | |||
| 535fd6151e | |||
| 1061431af7 | |||
| 520430d5bc | |||
| 52fb6840ad | |||
| 5430016be4 | |||
| 15a8f80210 |
@@ -21,12 +21,7 @@ or based on preferences add the person(s) to the project
|
||||
|
||||
### What Shapes are planed to be added
|
||||
Currently, the list of shapes to be added is pretty simple as the mod is still under development:
|
||||
- Fence
|
||||
- Button
|
||||
- Pressure Plate
|
||||
- Carpet (maybe redundant with Layer)
|
||||
- Post
|
||||
- Half Slab (maybe redundant with Layer)
|
||||
- Slabs Stair (a stair with one end being of a second theme, might be done in multiple blocks)
|
||||
|
||||
Any Ideas feel free to make a suggestion [here](https://github.com/DriHut/ReFramed/issues).
|
||||
|
||||
13
build.gradle
13
build.gradle
@@ -4,7 +4,7 @@ import fr.altarik.CreateTag
|
||||
|
||||
plugins {
|
||||
id "com.modrinth.minotaur" version "2.+"
|
||||
id 'fabric-loom' version '1.6-SNAPSHOT'
|
||||
id 'fabric-loom' version "${loom_version}"
|
||||
id 'maven-publish'
|
||||
}
|
||||
|
||||
@@ -36,9 +36,9 @@ base {
|
||||
sourceSets {
|
||||
main {
|
||||
resources {
|
||||
srcDirs += {
|
||||
srcDirs += [
|
||||
'src/generated'
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -84,6 +84,9 @@ repositories {
|
||||
includeGroup "maven.modrinth"
|
||||
}
|
||||
}
|
||||
maven {
|
||||
url = "https://jitpack.io"
|
||||
}
|
||||
mavenCentral()
|
||||
|
||||
// Add repositories to retrieve artifacts from in here.
|
||||
@@ -118,6 +121,10 @@ dependencies {
|
||||
modRuntimeOnly "com.teamresourceful.resourcefullib:resourcefullib-fabric-${project.minecraft_version}:2.4.7"
|
||||
modRuntimeOnly "earth.terrarium.chipped:Chipped-fabric-${project.minecraft_version}:3.1.2"
|
||||
|
||||
// Axiom for blueprint support
|
||||
modCompileOnly "maven.modrinth:N6n5dqoA:YxeYxQyz"
|
||||
modCompileOnly "com.github.moulberry:AxiomClientAPI:1.0.5.3"
|
||||
|
||||
// Fabric API.
|
||||
modImplementation "net.fabricmc.fabric-api:fabric-api:${project.fabric_version}"
|
||||
}
|
||||
|
||||
@@ -5,18 +5,19 @@ org.gradle.jvmargs=-Xmx1G
|
||||
# check these on https://modmuss50.me/fabric.html
|
||||
minecraft_version=1.20.4
|
||||
yarn_mappings=1.20.4+build.3
|
||||
loader_version=0.15.11
|
||||
loader_version=0.17.2
|
||||
|
||||
# Mod Properties
|
||||
modrinth_id = jCpoCBpn
|
||||
mod_version = 1.5.9
|
||||
mod_version = 1.6.9-SNAPSHOT
|
||||
maven_group = fr.adrien1106
|
||||
archives_base_name = ReFramed
|
||||
mod_id = reframed
|
||||
|
||||
# Dependencies
|
||||
# check this on https://modmuss50.me/fabric.html
|
||||
fabric_version=0.97.0+1.20.4
|
||||
fabric_version=0.97.3+1.20.4
|
||||
loom_version=1.11-SNAPSHOT
|
||||
|
||||
git_owner=Altarik
|
||||
git_repo=ReFramed
|
||||
|
||||
2
gradle/wrapper/gradle-wrapper.properties
vendored
2
gradle/wrapper/gradle-wrapper.properties
vendored
@@ -1,6 +1,6 @@
|
||||
distributionBase=GRADLE_USER_HOME
|
||||
distributionPath=wrapper/dists
|
||||
distributionUrl=https\://services.gradle.org/distributions/gradle-8.6-bin.zip
|
||||
distributionUrl=https\://services.gradle.org/distributions/gradle-9.1.0-bin.zip
|
||||
networkTimeout=10000
|
||||
validateDistributionUrl=true
|
||||
zipStoreBase=GRADLE_USER_HOME
|
||||
|
||||
@@ -7,7 +7,6 @@ import fr.adrien1106.reframed.item.ReFramedBlueprintWrittenItem;
|
||||
import fr.adrien1106.reframed.item.ReFramedScrewdriverItem;
|
||||
import net.fabricmc.api.ModInitializer;
|
||||
import net.fabricmc.fabric.api.itemgroup.v1.FabricItemGroup;
|
||||
import net.fabricmc.fabric.api.object.builder.v1.block.entity.FabricBlockEntityTypeBuilder;
|
||||
import net.minecraft.block.AbstractBlock;
|
||||
import net.minecraft.block.Block;
|
||||
import net.minecraft.block.Blocks;
|
||||
@@ -28,16 +27,28 @@ import java.util.stream.Stream;
|
||||
import static fr.adrien1106.reframed.util.blocks.BlockProperties.LIGHT;
|
||||
|
||||
/**
|
||||
* 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 Dynamic Ambient Occlusion -> not scheduled
|
||||
* TODO better connected textures -> not scheduled
|
||||
* TODO support continuity overlays -> not scheduled
|
||||
* TODO slopes -> thinking about it
|
||||
*/
|
||||
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, PILLAR, PILLARS_WALL, WALL, PANE, TRAPDOOR, DOOR;
|
||||
public static ReFramedBlock
|
||||
CUBE,
|
||||
SMALL_CUBE, SMALL_CUBES_STEP,
|
||||
STAIR, STAIRS_CUBE,
|
||||
HALF_STAIR, HALF_STAIRS_SLAB, HALF_STAIRS_STAIR, HALF_STAIRS_CUBE_STAIR, HALF_STAIRS_STEP_STAIR,
|
||||
SLAB, SLABS_CUBE, SLABS_STAIR, SLABS_OUTER_STAIR, SLABS_INNER_STAIR, SLABS_HALF_LAYER, SLABS_LAYER,
|
||||
HALF_SLAB, HALF_SLABS_SLAB,
|
||||
STEP, STEPS_SLAB, STEPS_CROSS, STEPS_HALF_LAYER,
|
||||
LAYER, HALF_LAYER,
|
||||
PILLAR, PILLARS_WALL, WALL,
|
||||
PANE, TRAPDOOR, DOOR,
|
||||
BUTTON,
|
||||
POST, POST_FENCE, FENCE;
|
||||
|
||||
public static final ArrayList<Item> ITEMS = new ArrayList<>();
|
||||
public static Item HAMMER, SCREWDRIVER, BLUEPRINT, BLUEPRINT_WRITTEN;
|
||||
@@ -51,33 +62,50 @@ public class ReFramed implements ModInitializer {
|
||||
|
||||
@Override
|
||||
public void onInitialize() {
|
||||
CUBE = registerBlock("cube" , new ReFramedBlock(cp(Blocks.OAK_PLANKS)));
|
||||
SMALL_CUBE = registerBlock("small_cube" , new ReFramedSmallCubeBlock(cp(Blocks.OAK_PLANKS)));
|
||||
SMALL_CUBES_STEP = registerBlock("small_cubes_step" , new ReFramedSmallCubesStepBlock(cp(Blocks.OAK_PLANKS)));
|
||||
STAIR = registerBlock("stair" , new ReFramedStairBlock(cp(Blocks.OAK_STAIRS)));
|
||||
STAIRS_CUBE = registerBlock("stairs_cube" , new ReFramedStairsCubeBlock(cp(Blocks.OAK_STAIRS)));
|
||||
HALF_STAIR = registerBlock("half_stair" , new ReFramedHalfStairBlock(cp(Blocks.OAK_STAIRS)));
|
||||
HALF_STAIRS_SLAB = registerBlock("half_stairs_slab" , new ReFramedHalfStairsSlabBlock(cp(Blocks.OAK_STAIRS)));
|
||||
HALF_STAIRS_STAIR = registerBlock("half_stairs_stair" , new ReFramedHalfStairsStairBlock(cp(Blocks.OAK_STAIRS)));
|
||||
LAYER = registerBlock("layer" , new ReFramedLayerBlock(cp(Blocks.OAK_SLAB)));
|
||||
SLAB = registerBlock("slab" , new ReFramedSlabBlock(cp(Blocks.OAK_SLAB)));
|
||||
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)));
|
||||
PILLARS_WALL = registerBlock("pillars_wall" , new ReFramedPillarsWallBlock(cp(Blocks.OAK_FENCE)));
|
||||
WALL = registerBlock("wall" , new ReFramedWallBlock(cp(Blocks.OAK_FENCE)));
|
||||
PANE = registerBlock("pane" , new ReFramedPaneBlock(cp(Blocks.OAK_FENCE)));
|
||||
TRAPDOOR = registerBlock("trapdoor" , new ReFramedTrapdoorBlock(cp(Blocks.OAK_TRAPDOOR)));
|
||||
DOOR = registerBlock("door" , new ReFramedDoorBlock(cp(Blocks.OAK_DOOR)));
|
||||
CUBE = registerBlock("cube" , new ReFramedBlock(cp(Blocks.OAK_PLANKS)));
|
||||
SMALL_CUBE = registerBlock("small_cube" , new ReFramedSmallCubeBlock(cp(Blocks.OAK_PLANKS)));
|
||||
SMALL_CUBES_STEP = registerBlock("small_cubes_step" , new ReFramedSmallCubesStepBlock(cp(Blocks.OAK_PLANKS)));
|
||||
STAIR = registerBlock("stair" , new ReFramedStairBlock(cp(Blocks.OAK_STAIRS)));
|
||||
STAIRS_CUBE = registerBlock("stairs_cube" , new ReFramedStairsCubeBlock(cp(Blocks.OAK_STAIRS)));
|
||||
HALF_STAIR = registerBlock("half_stair" , new ReFramedHalfStairBlock(cp(Blocks.OAK_STAIRS)));
|
||||
HALF_STAIRS_SLAB = registerBlock("half_stairs_slab" , new ReFramedHalfStairsSlabBlock(cp(Blocks.OAK_STAIRS)));
|
||||
HALF_STAIRS_STAIR = registerBlock("half_stairs_stair" , new ReFramedHalfStairsStairBlock(cp(Blocks.OAK_STAIRS)));
|
||||
HALF_STAIRS_CUBE_STAIR = registerBlock("half_stairs_cube_stair" , new ReFramedHalfStairsCubeStairBlock(cp(Blocks.OAK_STAIRS)));
|
||||
HALF_STAIRS_STEP_STAIR = registerBlock("half_stairs_step_stair" , new ReFramedHalfStairsStepStairBlock(cp(Blocks.OAK_STAIRS)));
|
||||
LAYER = registerBlock("layer" , new ReFramedLayerBlock(cp(Blocks.OAK_SLAB)));
|
||||
HALF_LAYER = registerBlock("half_layer" , new ReFramedHalfLayerBlock(cp(Blocks.OAK_SLAB)));
|
||||
SLAB = registerBlock("slab" , new ReFramedSlabBlock(cp(Blocks.OAK_SLAB)));
|
||||
SLABS_CUBE = registerBlock("slabs_cube" , new ReFramedSlabsCubeBlock(cp(Blocks.OAK_SLAB)));
|
||||
SLABS_STAIR = registerBlock("slabs_stair" , new ReFramedSlabsStairBlock(cp(Blocks.OAK_STAIRS)));
|
||||
SLABS_OUTER_STAIR = registerBlock("slabs_outer_stair" , new ReFramedSlabsOuterStairBlock(cp(Blocks.OAK_STAIRS)));
|
||||
SLABS_INNER_STAIR = registerBlock("slabs_inner_stair" , new ReFramedSlabsInnerStairBlock(cp(Blocks.OAK_STAIRS)));
|
||||
SLABS_HALF_LAYER = registerBlock("slabs_half_layer" , new ReFramedSlabsHalfLayerBlock(cp(Blocks.OAK_SLAB)));
|
||||
SLABS_LAYER = registerBlock("slabs_layer" , new ReFramedSlabsLayerBlock(cp(Blocks.OAK_SLAB)));
|
||||
HALF_SLAB = registerBlock("half_slab" , new ReFramedHalfSlabBlock(cp(Blocks.OAK_SLAB)));
|
||||
HALF_SLABS_SLAB = registerBlock("half_slabs_slab" , new ReFramedHalfSlabsSlabBlock(cp(Blocks.OAK_SLAB)));
|
||||
STEP = registerBlock("step" , new ReFramedStepBlock(cp(Blocks.OAK_SLAB)));
|
||||
STEPS_SLAB = registerBlock("steps_slab" , new ReFramedStepsSlabBlock(cp(Blocks.OAK_SLAB)));
|
||||
STEPS_CROSS = registerBlock("steps_cross" , new ReFramedStepsCrossBlock(cp(Blocks.OAK_SLAB)));
|
||||
STEPS_HALF_LAYER = registerBlock("steps_half_layer" , new ReFramedStepsHalfLayerBlock(cp(Blocks.OAK_SLAB)));
|
||||
PILLAR = registerBlock("pillar" , new ReFramedPillarBlock(cp(Blocks.OAK_FENCE)));
|
||||
PILLARS_WALL = registerBlock("pillars_wall" , new ReFramedPillarsWallBlock(cp(Blocks.OAK_FENCE)));
|
||||
WALL = registerBlock("wall" , new ReFramedWallBlock(cp(Blocks.OAK_FENCE)));
|
||||
PANE = registerBlock("pane" , new ReFramedPaneBlock(cp(Blocks.OAK_FENCE)));
|
||||
TRAPDOOR = registerBlock("trapdoor" , new ReFramedTrapdoorBlock(cp(Blocks.OAK_TRAPDOOR)));
|
||||
DOOR = registerBlock("door" , new ReFramedDoorBlock(cp(Blocks.OAK_DOOR)));
|
||||
BUTTON = registerBlock("button" , new ReFramedButtonBlock(cp(Blocks.OAK_BUTTON)));
|
||||
POST = registerBlock("post" , new ReFramedPostBlock(cp(Blocks.OAK_FENCE)));
|
||||
FENCE = registerBlock("fence" , new ReFramedFenceBlock(cp(Blocks.OAK_FENCE)));
|
||||
POST_FENCE = registerBlock("post_fence" , new ReFramedPostFenceBlock(cp(Blocks.OAK_FENCE)));
|
||||
|
||||
HAMMER = registerItem("hammer" , new ReFramedHammerItem(new Item.Settings().maxCount(1)));
|
||||
SCREWDRIVER = registerItem("screwdriver" , new ReFramedScrewdriverItem(new Item.Settings().maxCount(1)));
|
||||
BLUEPRINT = registerItem("blueprint" , new ReFramedBlueprintItem(new Item.Settings()));
|
||||
BLUEPRINT_WRITTEN = registerItem("blueprint_written" , new ReFramedBlueprintWrittenItem(new Item.Settings().maxCount(1)));
|
||||
|
||||
HAMMER = registerItem("hammer" , new ReFramedHammerItem(new Item.Settings().maxCount(1)));
|
||||
SCREWDRIVER = registerItem("screwdriver" , new ReFramedScrewdriverItem(new Item.Settings().maxCount(1)));
|
||||
BLUEPRINT = registerItem("blueprint" , new ReFramedBlueprintItem(new Item.Settings()));
|
||||
BLUEPRINT_WRITTEN = registerItem("blueprint_written" , new ReFramedBlueprintWrittenItem(new Item.Settings().maxCount(1)));
|
||||
|
||||
REFRAMED_BLOCK_ENTITY = Registry.register(Registries.BLOCK_ENTITY_TYPE, id("camo"),
|
||||
FabricBlockEntityTypeBuilder.create(
|
||||
BlockEntityType.Builder.create(
|
||||
(pos, state) -> new ReFramedEntity(REFRAMED_BLOCK_ENTITY, pos, state),
|
||||
BLOCKS.stream()
|
||||
.filter(block -> !(block instanceof ReFramedDoubleBlock))
|
||||
@@ -85,7 +113,7 @@ public class ReFramed implements ModInitializer {
|
||||
);
|
||||
|
||||
REFRAMED_DOUBLE_BLOCK_ENTITY = Registry.register(Registries.BLOCK_ENTITY_TYPE, id("double_camo"),
|
||||
FabricBlockEntityTypeBuilder.create(
|
||||
BlockEntityType.Builder.create(
|
||||
(pos, state) -> new ReFramedDoubleEntity(REFRAMED_DOUBLE_BLOCK_ENTITY, pos, state),
|
||||
BLOCKS.stream()
|
||||
.filter(block -> block instanceof ReFramedDoubleBlock)
|
||||
@@ -107,11 +135,11 @@ public class ReFramed implements ModInitializer {
|
||||
private static AbstractBlock.Settings cp(Block base) {
|
||||
return AbstractBlock.Settings.copy(base)
|
||||
.luminance(state -> state.contains(LIGHT) && state.get(LIGHT) ? 15 : 0)
|
||||
.nonOpaque()
|
||||
.sounds(BlockSoundGroup.WOOD)
|
||||
.hardness(0.2f)
|
||||
.suffocates((a,b,c) -> false)
|
||||
.blockVision((a,b,c) -> false);
|
||||
.suffocates(Blocks::never)
|
||||
.solidBlock(Blocks::always);
|
||||
// .blockVision(Blocks::always);
|
||||
}
|
||||
|
||||
private static <I extends Item> I registerItem(String path, I item) {
|
||||
|
||||
@@ -0,0 +1,100 @@
|
||||
package fr.adrien1106.reframed.block;
|
||||
|
||||
import net.minecraft.block.Block;
|
||||
import net.minecraft.block.BlockState;
|
||||
import net.minecraft.block.ShapeContext;
|
||||
import net.minecraft.item.ItemPlacementContext;
|
||||
import net.minecraft.state.StateManager;
|
||||
import net.minecraft.state.property.BooleanProperty;
|
||||
import net.minecraft.util.BlockMirror;
|
||||
import net.minecraft.util.BlockRotation;
|
||||
import net.minecraft.util.math.BlockPos;
|
||||
import net.minecraft.util.math.Direction;
|
||||
import net.minecraft.util.shape.VoxelShape;
|
||||
import net.minecraft.world.BlockView;
|
||||
import net.minecraft.world.World;
|
||||
import net.minecraft.world.WorldAccess;
|
||||
import org.apache.commons.lang3.function.TriFunction;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import static net.minecraft.state.property.Properties.*;
|
||||
import static net.minecraft.state.property.Properties.SOUTH;
|
||||
|
||||
public abstract class ConnectingReFramedBlock extends WaterloggableReFramedBlock {
|
||||
|
||||
public ConnectingReFramedBlock(Settings settings) {
|
||||
super(settings);
|
||||
setDefaultState(getDefaultState()
|
||||
.with(EAST, false)
|
||||
.with(NORTH, false)
|
||||
.with(WEST, false)
|
||||
.with(SOUTH, false)
|
||||
);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void appendProperties(StateManager.Builder<Block, BlockState> builder) {
|
||||
super.appendProperties(builder.add(EAST, NORTH, SOUTH, WEST));
|
||||
}
|
||||
|
||||
@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;
|
||||
|
||||
return placementState(new_state, world, pos, this::connectsTo);
|
||||
}
|
||||
|
||||
@Override
|
||||
public @Nullable BlockState getPlacementState(ItemPlacementContext ctx) {
|
||||
BlockState state = super.getPlacementState(ctx);
|
||||
World world = ctx.getWorld();
|
||||
BlockPos pos = ctx.getBlockPos();
|
||||
|
||||
return placementState(state, world, pos, this::connectsTo);
|
||||
}
|
||||
|
||||
@Override
|
||||
@SuppressWarnings("deprecation")
|
||||
public BlockState rotate(BlockState state, BlockRotation rotation) {
|
||||
return Direction.Type.HORIZONTAL.stream().reduce(state, (s, dir) ->
|
||||
s.with(getConnectionProperty(rotation.rotate(dir)), state.get(getConnectionProperty(dir)))
|
||||
, (prev, next) -> next);
|
||||
}
|
||||
|
||||
@Override
|
||||
@SuppressWarnings("deprecation")
|
||||
public BlockState mirror(BlockState state, BlockMirror mirror) {
|
||||
return Direction.Type.HORIZONTAL.stream().reduce(state, (s, dir) ->
|
||||
s.with(getConnectionProperty(mirror.apply(dir)), state.get(getConnectionProperty(dir)))
|
||||
, (prev, next) -> next);
|
||||
}
|
||||
|
||||
protected abstract boolean connectsTo(BlockState state, boolean fs, Direction dir);
|
||||
|
||||
@Override
|
||||
@SuppressWarnings("deprecation")
|
||||
public abstract VoxelShape getOutlineShape(BlockState state, BlockView world, BlockPos pos, ShapeContext context);
|
||||
|
||||
public static BooleanProperty getConnectionProperty(Direction dir) {
|
||||
return switch (dir) {
|
||||
case NORTH -> NORTH;
|
||||
case EAST -> EAST;
|
||||
case SOUTH -> SOUTH;
|
||||
case WEST -> WEST;
|
||||
default -> null;
|
||||
};
|
||||
}
|
||||
|
||||
public static BlockState placementState(BlockState state, BlockView world, BlockPos pos, TriFunction<BlockState, Boolean, Direction, Boolean> connectsTo) {
|
||||
for (Direction dir: Direction.Type.HORIZONTAL) {
|
||||
BlockState neighbor = world.getBlockState(pos.offset(dir));
|
||||
state = state.with(getConnectionProperty(dir), connectsTo.apply(
|
||||
neighbor,
|
||||
neighbor.isSideSolidFullSquare(world, pos.offset(dir), dir.getOpposite()),
|
||||
dir
|
||||
));
|
||||
}
|
||||
return state;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,70 @@
|
||||
package fr.adrien1106.reframed.block;
|
||||
|
||||
import fr.adrien1106.reframed.util.blocks.BlockHelper;
|
||||
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.item.ItemPlacementContext;
|
||||
import net.minecraft.state.StateManager;
|
||||
import net.minecraft.util.BlockMirror;
|
||||
import net.minecraft.util.BlockRotation;
|
||||
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 static fr.adrien1106.reframed.util.blocks.BlockProperties.CORNER;
|
||||
import static fr.adrien1106.reframed.util.blocks.BlockProperties.CORNER_FACE;
|
||||
|
||||
public abstract class CornerDoubleReFramedBlock extends WaterloggableReFramedDoubleBlock {
|
||||
|
||||
public CornerDoubleReFramedBlock(Settings settings) {
|
||||
super(settings);
|
||||
setDefaultState(getDefaultState().with(CORNER, Corner.NORTH_EAST_DOWN).with(CORNER_FACE, 0));
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void appendProperties(StateManager.Builder<Block, BlockState> builder) {
|
||||
super.appendProperties(builder.add(CORNER,CORNER_FACE));
|
||||
}
|
||||
|
||||
@Override
|
||||
public @Nullable BlockState getPlacementState(ItemPlacementContext ctx) {
|
||||
Corner corner = BlockHelper.getPlacementCorner(ctx);
|
||||
return super.getPlacementState(ctx)
|
||||
.with(CORNER, corner)
|
||||
.with(CORNER_FACE, corner.getDirectionIndex(ctx.getSide().getOpposite()));
|
||||
}
|
||||
|
||||
@Override
|
||||
@SuppressWarnings("deprecation")
|
||||
public abstract VoxelShape getOutlineShape(BlockState state, BlockView world, BlockPos pos, ShapeContext context);
|
||||
|
||||
|
||||
@Override
|
||||
@SuppressWarnings("deprecation")
|
||||
public BlockState rotate(BlockState state, BlockRotation rotation) {
|
||||
Corner corner = state.get(CORNER);
|
||||
Direction face = corner.getDirection(state.get(CORNER_FACE));
|
||||
corner = corner.rotate(rotation);
|
||||
return state
|
||||
.with(CORNER, corner)
|
||||
.with(CORNER_FACE, corner.getDirectionIndex(rotation.rotate(face)));
|
||||
}
|
||||
|
||||
@Override
|
||||
@SuppressWarnings("deprecation")
|
||||
public BlockState mirror(BlockState state, BlockMirror mirror) {
|
||||
Corner corner = state.get(CORNER);
|
||||
Direction face = corner.getDirection(state.get(CORNER_FACE));
|
||||
corner = corner.mirror(mirror);
|
||||
return state
|
||||
.with(CORNER, corner)
|
||||
.with(CORNER_FACE, corner.getDirectionIndex(mirror.apply(face)));
|
||||
}
|
||||
|
||||
@Override
|
||||
public abstract VoxelShape getShape(BlockState state, int i);
|
||||
}
|
||||
@@ -0,0 +1,64 @@
|
||||
package fr.adrien1106.reframed.block;
|
||||
|
||||
import fr.adrien1106.reframed.util.blocks.BlockHelper;
|
||||
import fr.adrien1106.reframed.util.blocks.Edge;
|
||||
import net.minecraft.block.Block;
|
||||
import net.minecraft.block.BlockState;
|
||||
import net.minecraft.block.ShapeContext;
|
||||
import net.minecraft.item.ItemPlacementContext;
|
||||
import net.minecraft.state.StateManager;
|
||||
import net.minecraft.util.BlockMirror;
|
||||
import net.minecraft.util.BlockRotation;
|
||||
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 static fr.adrien1106.reframed.util.blocks.BlockProperties.EDGE;
|
||||
import static fr.adrien1106.reframed.util.blocks.BlockProperties.EDGE_FACE;
|
||||
|
||||
public abstract class EdgeDoubleReFramedBlock extends WaterloggableReFramedDoubleBlock {
|
||||
|
||||
public EdgeDoubleReFramedBlock(Settings settings) {
|
||||
super(settings);
|
||||
setDefaultState(getDefaultState().with(EDGE, Edge.NORTH_DOWN).with(EDGE_FACE, 0));
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void appendProperties(StateManager.Builder<Block, BlockState> builder) {
|
||||
super.appendProperties(builder.add(EDGE, EDGE_FACE));
|
||||
}
|
||||
|
||||
@Override
|
||||
public @Nullable BlockState getPlacementState(ItemPlacementContext ctx) {
|
||||
Edge edge = BlockHelper.getPlacementEdge(ctx);
|
||||
return super.getPlacementState(ctx)
|
||||
.with(EDGE, edge)
|
||||
.with(EDGE_FACE, edge.getDirectionIndex(ctx.getSide().getOpposite()));
|
||||
}
|
||||
|
||||
@Override
|
||||
@SuppressWarnings("deprecation")
|
||||
public abstract VoxelShape getOutlineShape(BlockState state, BlockView world, BlockPos pos, ShapeContext context);
|
||||
|
||||
@Override
|
||||
@SuppressWarnings("deprecation")
|
||||
public BlockState rotate(BlockState state, BlockRotation rotation) {
|
||||
Edge edge = state.get(EDGE).rotate(rotation);
|
||||
Direction face = state.get(EDGE).getDirection(state.get(EDGE_FACE));
|
||||
return state.with(EDGE, edge).with(EDGE_FACE, edge.getDirectionIndex(rotation.rotate(face)));
|
||||
}
|
||||
|
||||
@Override
|
||||
@SuppressWarnings("deprecation")
|
||||
public BlockState mirror(BlockState state, BlockMirror mirror) {
|
||||
Edge edge = state.get(EDGE).mirror(mirror);
|
||||
Direction face = state.get(EDGE).getDirection(state.get(EDGE_FACE));
|
||||
return state.with(EDGE, edge).with(EDGE_FACE, edge.getDirectionIndex(mirror.apply(face)));
|
||||
}
|
||||
|
||||
@Override
|
||||
public abstract VoxelShape getShape(BlockState state, int i);
|
||||
|
||||
}
|
||||
@@ -0,0 +1,57 @@
|
||||
package fr.adrien1106.reframed.block;
|
||||
|
||||
import net.minecraft.block.AbstractBlock;
|
||||
import net.minecraft.block.Block;
|
||||
import net.minecraft.block.BlockState;
|
||||
import net.minecraft.block.ShapeContext;
|
||||
import net.minecraft.item.ItemPlacementContext;
|
||||
import net.minecraft.state.StateManager;
|
||||
import net.minecraft.util.BlockMirror;
|
||||
import net.minecraft.util.BlockRotation;
|
||||
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 static net.minecraft.state.property.Properties.FACING;
|
||||
|
||||
public abstract class FacingDoubleReFramedBlock extends WaterloggableReFramedDoubleBlock {
|
||||
|
||||
public FacingDoubleReFramedBlock(AbstractBlock.Settings settings) {
|
||||
super(settings);
|
||||
setDefaultState(getDefaultState().with(FACING, Direction.DOWN));
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void appendProperties(StateManager.Builder< Block, BlockState > builder) {
|
||||
super.appendProperties(builder.add(FACING));
|
||||
}
|
||||
|
||||
@Override
|
||||
public @Nullable BlockState getPlacementState(ItemPlacementContext ctx) {
|
||||
return super.getPlacementState(ctx)
|
||||
.with(FACING, ctx.getSide().getOpposite());
|
||||
}
|
||||
|
||||
@Override
|
||||
@SuppressWarnings("deprecation")
|
||||
public abstract VoxelShape getOutlineShape(BlockState state, BlockView world, BlockPos pos, ShapeContext context);
|
||||
|
||||
@Override
|
||||
@SuppressWarnings("deprecation")
|
||||
public BlockState rotate(BlockState state, BlockRotation rotation) {
|
||||
return state
|
||||
.with(FACING, rotation.rotate(state.get(FACING)));
|
||||
}
|
||||
|
||||
@Override
|
||||
@SuppressWarnings("deprecation")
|
||||
public BlockState mirror(BlockState state, BlockMirror mirror) {
|
||||
return state.with(FACING, mirror.apply(state.get(FACING)));
|
||||
}
|
||||
|
||||
@Override
|
||||
public abstract VoxelShape getShape(BlockState state, int i);
|
||||
|
||||
}
|
||||
@@ -0,0 +1,46 @@
|
||||
package fr.adrien1106.reframed.block;
|
||||
|
||||
import fr.adrien1106.reframed.ReFramed;
|
||||
import net.minecraft.block.Block;
|
||||
import net.minecraft.block.BlockState;
|
||||
import net.minecraft.item.BlockItem;
|
||||
import net.minecraft.item.ItemPlacementContext;
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.loot.context.LootContextParameterSet;
|
||||
import net.minecraft.state.StateManager;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import static net.minecraft.state.property.Properties.LAYERS;
|
||||
|
||||
public abstract class HalfLayerDoubleReFramedBlock extends EdgeDoubleReFramedBlock {
|
||||
|
||||
public HalfLayerDoubleReFramedBlock(Settings settings) {
|
||||
super(settings);
|
||||
setDefaultState(getDefaultState().with(LAYERS, 1));
|
||||
}
|
||||
|
||||
@Override
|
||||
@SuppressWarnings("deprecation")
|
||||
public List<ItemStack> getDroppedStacks(BlockState state, LootContextParameterSet.Builder builder) {
|
||||
List<ItemStack> drops = super.getDroppedStacks(state, builder);
|
||||
if (state.get(LAYERS) > 1)
|
||||
drops.add(new ItemStack(ReFramed.HALF_LAYER, state.get(LAYERS)-1));
|
||||
return drops;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void appendProperties(StateManager.Builder<Block, BlockState> builder) {
|
||||
super.appendProperties(builder.add(LAYERS));
|
||||
}
|
||||
|
||||
@Override
|
||||
@SuppressWarnings("deprecation")
|
||||
public boolean canReplace(BlockState state, ItemPlacementContext context) {
|
||||
if (context.getPlayer() == null
|
||||
|| context.getPlayer().isSneaking()
|
||||
|| !(context.getStack().getItem() instanceof BlockItem block_item)
|
||||
) return false;
|
||||
return block_item.getBlock() == ReFramed.HALF_LAYER && state.get(LAYERS) < 8;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,64 @@
|
||||
package fr.adrien1106.reframed.block;
|
||||
|
||||
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.item.ItemStack;
|
||||
import net.minecraft.loot.context.LootContextParameterSet;
|
||||
import net.minecraft.state.StateManager;
|
||||
import net.minecraft.util.math.BlockPos;
|
||||
import net.minecraft.util.shape.VoxelShape;
|
||||
import net.minecraft.world.BlockView;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import static net.minecraft.state.property.Properties.LAYERS;
|
||||
|
||||
public abstract class LayeredReFramedBlock extends WaterloggableReFramedBlock {
|
||||
|
||||
public LayeredReFramedBlock(Settings settings) {
|
||||
super(settings);
|
||||
setDefaultState(getDefaultState().with(LAYERS, 1));
|
||||
}
|
||||
|
||||
@Override
|
||||
@SuppressWarnings("deprecation")
|
||||
public List<ItemStack> getDroppedStacks(BlockState state, LootContextParameterSet.Builder builder) {
|
||||
List<ItemStack> drops = super.getDroppedStacks(state, builder);
|
||||
drops.forEach((stack) -> {
|
||||
if (stack.getItem() instanceof BlockItem bi && bi.getBlock() instanceof LayeredReFramedBlock)
|
||||
stack.setCount(state.get(LAYERS));
|
||||
});
|
||||
return drops;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void appendProperties(StateManager.Builder<Block, BlockState> builder) {
|
||||
super.appendProperties(builder.add(LAYERS));
|
||||
}
|
||||
|
||||
@Override
|
||||
@SuppressWarnings("deprecation")
|
||||
public abstract VoxelShape getOutlineShape(BlockState state, BlockView world, BlockPos pos, ShapeContext context);
|
||||
|
||||
@Override
|
||||
@SuppressWarnings("deprecation")
|
||||
public boolean canReplace(BlockState state, ItemPlacementContext context) {
|
||||
if (context.getPlayer() == null) return false;
|
||||
return !(
|
||||
context.getPlayer().isSneaking()
|
||||
|| !(context.getStack().getItem() instanceof BlockItem block_item)
|
||||
|| !(block_item.getBlock() == this && state.get(LAYERS) < 8)
|
||||
);
|
||||
}
|
||||
|
||||
@Override
|
||||
public @Nullable BlockState getPlacementState(ItemPlacementContext ctx) {
|
||||
BlockState previous = ctx.getWorld().getBlockState(ctx.getBlockPos());
|
||||
if (!previous.isOf(this)) return super.getPlacementState(ctx);
|
||||
return previous.with(LAYERS, previous.get(LAYERS) + 1);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,49 @@
|
||||
package fr.adrien1106.reframed.block;
|
||||
|
||||
import net.minecraft.block.Block;
|
||||
import net.minecraft.block.BlockState;
|
||||
import net.minecraft.block.ShapeContext;
|
||||
import net.minecraft.item.ItemPlacementContext;
|
||||
import net.minecraft.state.StateManager;
|
||||
import net.minecraft.util.BlockMirror;
|
||||
import net.minecraft.util.BlockRotation;
|
||||
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 static net.minecraft.state.property.Properties.AXIS;
|
||||
|
||||
public abstract class PillarReFramedBlock extends WaterloggableReFramedBlock {
|
||||
public PillarReFramedBlock(Settings settings) {
|
||||
super(settings);
|
||||
setDefaultState(getDefaultState().with(AXIS, Direction.Axis.Y));
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void appendProperties(StateManager.Builder< Block, BlockState > builder) {
|
||||
super.appendProperties(builder.add(AXIS));
|
||||
}
|
||||
|
||||
@Override
|
||||
public @Nullable BlockState getPlacementState(ItemPlacementContext ctx) {
|
||||
return super.getPlacementState(ctx).with(AXIS, ctx.getSide().getAxis());
|
||||
}
|
||||
|
||||
@Override
|
||||
@SuppressWarnings("deprecation")
|
||||
public abstract VoxelShape getOutlineShape(BlockState state, BlockView world, BlockPos pos, ShapeContext context);
|
||||
|
||||
@Override
|
||||
@SuppressWarnings("deprecation")
|
||||
public BlockState rotate(BlockState state, BlockRotation rotation) {
|
||||
return state.with(AXIS, rotation.rotate(Direction.get(Direction.AxisDirection.POSITIVE, state.get(AXIS))).getAxis());
|
||||
}
|
||||
|
||||
@Override
|
||||
@SuppressWarnings("deprecation")
|
||||
public BlockState mirror(BlockState state, BlockMirror mirror) {
|
||||
return state.with(AXIS, mirror.apply(Direction.get(Direction.AxisDirection.POSITIVE, state.get(AXIS))).getAxis());
|
||||
}
|
||||
}
|
||||
@@ -2,14 +2,15 @@ package fr.adrien1106.reframed.block;
|
||||
|
||||
import fr.adrien1106.reframed.ReFramed;
|
||||
import fr.adrien1106.reframed.util.blocks.BlockHelper;
|
||||
import fr.adrien1106.reframed.util.blocks.ThemeableBlockEntity;
|
||||
import net.minecraft.block.*;
|
||||
import net.minecraft.block.entity.BlockEntity;
|
||||
import net.minecraft.entity.LivingEntity;
|
||||
import net.minecraft.entity.ai.pathing.NavigationType;
|
||||
import net.minecraft.entity.player.PlayerEntity;
|
||||
import net.minecraft.item.BlockItem;
|
||||
import net.minecraft.item.ItemPlacementContext;
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.item.Items;
|
||||
import net.minecraft.nbt.NbtCompound;
|
||||
import net.minecraft.nbt.NbtHelper;
|
||||
import net.minecraft.registry.Registries;
|
||||
@@ -18,9 +19,11 @@ import net.minecraft.util.ActionResult;
|
||||
import net.minecraft.util.Hand;
|
||||
import net.minecraft.util.ItemScatterer;
|
||||
import net.minecraft.util.collection.DefaultedList;
|
||||
import net.minecraft.util.function.BooleanBiFunction;
|
||||
import net.minecraft.util.hit.BlockHitResult;
|
||||
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;
|
||||
@@ -31,6 +34,7 @@ import org.jetbrains.annotations.Nullable;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.atomic.AtomicInteger;
|
||||
import java.util.stream.IntStream;
|
||||
|
||||
import static fr.adrien1106.reframed.block.ReFramedEntity.BLOCKSTATE_KEY;
|
||||
@@ -39,10 +43,26 @@ import static fr.adrien1106.reframed.util.blocks.BlockProperties.LIGHT;
|
||||
public class ReFramedBlock extends Block implements BlockEntityProvider {
|
||||
|
||||
public ReFramedBlock(Settings settings) {
|
||||
super(settings);
|
||||
super(settings.dynamicBounds());
|
||||
setDefaultState(getDefaultState().with(LIGHT, false));
|
||||
}
|
||||
|
||||
@Override
|
||||
@SuppressWarnings("deprecation")
|
||||
public int getOpacity(BlockState state, BlockView world, BlockPos pos) {
|
||||
if (state.get(LIGHT)) return 0;
|
||||
if (!(world.getBlockEntity(pos) instanceof ReFramedEntity frame_entity)
|
||||
|| frame_entity.getTheme(0).isOpaque())
|
||||
return world.getMaxLightLevel();
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
@SuppressWarnings("deprecation")
|
||||
public boolean canPathfindThrough(BlockState state, BlockView world, BlockPos pos, NavigationType type) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public @Nullable BlockEntity createBlockEntity(BlockPos pos, BlockState state) {
|
||||
return ReFramed.REFRAMED_BLOCK_ENTITY.instantiate(pos, state);
|
||||
@@ -60,6 +80,7 @@ public class ReFramedBlock extends Block implements BlockEntityProvider {
|
||||
}
|
||||
|
||||
@Override
|
||||
@SuppressWarnings("deprecation")
|
||||
public ActionResult onUse(BlockState state, World world, BlockPos pos, PlayerEntity player, Hand hand, BlockHitResult hit) {
|
||||
if (!canUse(world, pos, player)) return ActionResult.PASS;
|
||||
ActionResult result = BlockHelper.useUpgrade(state, world, pos, player, hand);
|
||||
@@ -73,8 +94,11 @@ public class ReFramedBlock extends Block implements BlockEntityProvider {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onStateReplaced(BlockState state, World world, BlockPos pos, BlockState newState, boolean moved) {
|
||||
if(!(newState.getBlock() instanceof ReFramedBlock) &&
|
||||
@SuppressWarnings("deprecation")
|
||||
public void onStateReplaced(BlockState state, World world, BlockPos pos, BlockState new_state, boolean moved) {
|
||||
if (!new_state.isOf(state.getBlock())) world.removeBlockEntity(pos);
|
||||
|
||||
if(!(new_state.getBlock() instanceof ReFramedBlock) &&
|
||||
world.getBlockEntity(pos) instanceof ReFramedEntity frame_entity &&
|
||||
world.getGameRules().getBoolean(GameRules.DO_TILE_DROPS)
|
||||
) {
|
||||
@@ -85,19 +109,9 @@ public class ReFramedBlock extends Block implements BlockEntityProvider {
|
||||
if(theme.getBlock() != Blocks.AIR) drops.add(new ItemStack(theme.getBlock()));
|
||||
});
|
||||
|
||||
if(frame_entity.emitsRedstone()
|
||||
&& themes.stream().noneMatch(theme -> theme.getWeakRedstonePower(world, pos, Direction.NORTH) != 0))
|
||||
drops.add(new ItemStack(Items.REDSTONE_TORCH));
|
||||
if(frame_entity.emitsLight()
|
||||
&& themes.stream().noneMatch(theme -> theme.getLuminance() != 0))
|
||||
drops.add(new ItemStack(Items.GLOWSTONE_DUST));
|
||||
if(!frame_entity.isSolid()
|
||||
&& themes.stream().anyMatch(AbstractBlockState::isSolid))
|
||||
drops.add(new ItemStack(Items.POPPED_CHORUS_FRUIT));
|
||||
|
||||
ItemScatterer.spawn(world, pos, drops);
|
||||
}
|
||||
super.onStateReplaced(state, world, pos, newState, moved);
|
||||
super.onStateReplaced(state, world, pos, new_state, moved);
|
||||
}
|
||||
|
||||
public void onPlaced(World world, BlockPos pos, BlockState state, @Nullable LivingEntity placer, ItemStack stack, BlockState old_state, BlockEntity old_entity) {
|
||||
@@ -146,8 +160,22 @@ public class ReFramedBlock extends Block implements BlockEntityProvider {
|
||||
}
|
||||
onPlaced(world, pos, state, placer, stack);
|
||||
}
|
||||
|
||||
public boolean matchesShape(Vec3d hit, BlockPos pos, BlockState state) {
|
||||
return matchesShape(hit, pos, state, 0);
|
||||
}
|
||||
|
||||
public boolean matchesShape(Vec3d hit, BlockPos pos, BlockState state, int i) {
|
||||
Vec3d rel = BlockHelper.getRelativePos(hit, pos);
|
||||
return matchesShape(rel, getShape(state, i));
|
||||
}
|
||||
|
||||
public boolean matchesShape(Vec3d rel_hit, VoxelShape shape) {
|
||||
return BlockHelper.cursorMatchesFace(shape, rel_hit);
|
||||
}
|
||||
|
||||
@Override
|
||||
@SuppressWarnings("deprecation")
|
||||
public VoxelShape getCollisionShape(BlockState state, BlockView view, BlockPos pos, ShapeContext ctx) {
|
||||
return isGhost(view, pos)
|
||||
? VoxelShapes.empty()
|
||||
@@ -155,12 +183,14 @@ public class ReFramedBlock extends Block implements BlockEntityProvider {
|
||||
}
|
||||
|
||||
@Override
|
||||
@SuppressWarnings("deprecation")
|
||||
public VoxelShape getCullingShape(BlockState state, BlockView view, BlockPos pos) {
|
||||
return isGhost(view, pos)
|
||||
? VoxelShapes.empty()
|
||||
: super.getCullingShape(state, view, pos);
|
||||
}
|
||||
|
||||
@SuppressWarnings("deprecation")
|
||||
public VoxelShape getShape(BlockState state, int i) {
|
||||
// assuming the shape don't need the world and position
|
||||
return getOutlineShape(state, null, null, null);
|
||||
@@ -171,11 +201,13 @@ public class ReFramedBlock extends Block implements BlockEntityProvider {
|
||||
}
|
||||
|
||||
@Override
|
||||
@SuppressWarnings("deprecation")
|
||||
public int getWeakRedstonePower(BlockState state, BlockView view, BlockPos pos, Direction dir) {
|
||||
return view.getBlockEntity(pos) instanceof ReFramedEntity be && be.emitsRedstone() ? 15 : 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
@SuppressWarnings("deprecation")
|
||||
public int getStrongRedstonePower(BlockState state, BlockView view, BlockPos pos, Direction dir) {
|
||||
return getWeakRedstonePower(state, view, pos, dir);
|
||||
}
|
||||
@@ -196,4 +228,17 @@ public class ReFramedBlock extends Block implements BlockEntityProvider {
|
||||
public Map<Integer, Integer> getThemeMap(BlockState state, BlockState new_state) {
|
||||
return Map.of();
|
||||
}
|
||||
|
||||
public VoxelShape getShadingShape(BlockState state, BlockView world, BlockPos pos) {
|
||||
if (!(world.getBlockEntity(pos) instanceof ThemeableBlockEntity framed_entity)) return this.getCollisionShape(state, world, pos, ShapeContext.absent());
|
||||
|
||||
AtomicInteger i = new AtomicInteger(1);
|
||||
return framed_entity.getThemes().stream().map((theme) -> {
|
||||
int index = i.getAndIncrement();
|
||||
return theme.isTransparent(world, pos) ? VoxelShapes.empty() : this.getShape(state, index);
|
||||
}).reduce(
|
||||
VoxelShapes.empty(),
|
||||
(prev, current) -> VoxelShapes.combine(prev, current, BooleanBiFunction.OR)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,245 @@
|
||||
package fr.adrien1106.reframed.block;
|
||||
|
||||
import fr.adrien1106.reframed.util.VoxelHelper;
|
||||
import net.minecraft.block.*;
|
||||
import net.minecraft.block.enums.BlockFace;
|
||||
import net.minecraft.entity.Entity;
|
||||
import net.minecraft.entity.player.PlayerEntity;
|
||||
import net.minecraft.entity.projectile.PersistentProjectileEntity;
|
||||
import net.minecraft.item.ItemPlacementContext;
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.server.world.ServerWorld;
|
||||
import net.minecraft.sound.SoundCategory;
|
||||
import net.minecraft.state.StateManager;
|
||||
import net.minecraft.util.ActionResult;
|
||||
import net.minecraft.util.BlockMirror;
|
||||
import net.minecraft.util.BlockRotation;
|
||||
import net.minecraft.util.Hand;
|
||||
import net.minecraft.util.hit.BlockHitResult;
|
||||
import net.minecraft.util.math.BlockPos;
|
||||
import net.minecraft.util.math.Direction;
|
||||
import net.minecraft.util.math.random.Random;
|
||||
import net.minecraft.util.shape.VoxelShape;
|
||||
import net.minecraft.world.BlockView;
|
||||
import net.minecraft.world.World;
|
||||
import net.minecraft.world.WorldAccess;
|
||||
import net.minecraft.world.WorldView;
|
||||
import net.minecraft.world.event.GameEvent;
|
||||
import net.minecraft.world.explosion.Explosion;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.function.BiConsumer;
|
||||
|
||||
import static net.minecraft.state.property.Properties.*;
|
||||
|
||||
public class ReFramedButtonBlock extends WaterloggableReFramedBlock {
|
||||
|
||||
public static final VoxelShape[] BUTTON_VOXELS;
|
||||
|
||||
public ReFramedButtonBlock(Settings settings) {
|
||||
super(settings);
|
||||
setDefaultState(getDefaultState()
|
||||
.with(HORIZONTAL_FACING, Direction.NORTH)
|
||||
.with(BLOCK_FACE, BlockFace.WALL)
|
||||
.with(POWERED, false)
|
||||
);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void appendProperties(StateManager.Builder<Block, BlockState> builder) {
|
||||
super.appendProperties(builder.add(HORIZONTAL_FACING, BLOCK_FACE, POWERED));
|
||||
}
|
||||
|
||||
@Override
|
||||
@SuppressWarnings("deprecation")
|
||||
public boolean canPlaceAt(BlockState state, WorldView world, BlockPos pos) {
|
||||
return canPlaceAt(world, pos, getDirection(state).getOpposite());
|
||||
}
|
||||
|
||||
public static boolean canPlaceAt(WorldView world, BlockPos pos, Direction direction) {
|
||||
BlockPos other_pos = pos.offset(direction);
|
||||
return world.getBlockState(other_pos).isSideSolidFullSquare(world, other_pos, direction.getOpposite());
|
||||
}
|
||||
|
||||
@Override
|
||||
public @Nullable BlockState getPlacementState(ItemPlacementContext ctx) {
|
||||
BlockState state = super.getPlacementState(ctx);
|
||||
Direction side = ctx.getSide();
|
||||
return state
|
||||
.with(HORIZONTAL_FACING, side.getAxis() == Direction.Axis.Y
|
||||
? ctx.getHorizontalPlayerFacing()
|
||||
: side
|
||||
)
|
||||
.with(BLOCK_FACE, side.getAxis() != Direction.Axis.Y
|
||||
? BlockFace.WALL
|
||||
: side == Direction.UP ? BlockFace.FLOOR : BlockFace.CEILING
|
||||
);
|
||||
}
|
||||
|
||||
@Override
|
||||
public BlockState getStateForNeighborUpdate(BlockState state, Direction direction, BlockState other_state, WorldAccess world, BlockPos pos, BlockPos other_pos) {
|
||||
return getDirection(state).getOpposite() == direction && !state.canPlaceAt(world, pos)
|
||||
? Blocks.AIR.getDefaultState()
|
||||
: super.getStateForNeighborUpdate(state, direction, other_state, world, pos, other_pos);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ActionResult onUse(BlockState state, World world, BlockPos pos, PlayerEntity player, Hand hand, BlockHitResult hit) {
|
||||
ActionResult result = super.onUse(state, world, pos, player, hand, hit);
|
||||
if (result.isAccepted()) return result;
|
||||
|
||||
if (state.get(POWERED)) return ActionResult.CONSUME;
|
||||
powerOn(state, world, pos);
|
||||
playClickSound(player, world, pos, true);
|
||||
world.emitGameEvent(player, GameEvent.BLOCK_ACTIVATE, pos);
|
||||
|
||||
return ActionResult.success(world.isClient);
|
||||
}
|
||||
|
||||
@Override
|
||||
@SuppressWarnings("deprecation")
|
||||
public void onExploded(BlockState state, World world, BlockPos pos, Explosion explosion, BiConsumer<ItemStack, BlockPos> stackMerger) {
|
||||
if (explosion.getDestructionType() == Explosion.DestructionType.TRIGGER_BLOCK && !world.isClient() && !(Boolean)state.get(POWERED)) {
|
||||
powerOn(state, world, pos);
|
||||
}
|
||||
|
||||
super.onExploded(state, world, pos, explosion, stackMerger);
|
||||
}
|
||||
|
||||
public void powerOn(BlockState state, World world, BlockPos pos) {
|
||||
world.setBlockState(pos, state.with(POWERED, true), 3);
|
||||
updateNeighbors(state, world, pos);
|
||||
world.scheduleBlockTick(pos, this, 30);
|
||||
}
|
||||
|
||||
protected void playClickSound(@Nullable PlayerEntity player, WorldAccess world, BlockPos pos, boolean powered) {
|
||||
world.playSound(
|
||||
powered ? player : null,
|
||||
pos,
|
||||
powered ? BlockSetType.OAK.buttonClickOn() : BlockSetType.OAK.buttonClickOff(),
|
||||
SoundCategory.BLOCKS
|
||||
);
|
||||
}
|
||||
|
||||
@Override
|
||||
@SuppressWarnings("deprecation")
|
||||
public VoxelShape getOutlineShape(BlockState state, BlockView world, BlockPos pos, ShapeContext context) {
|
||||
return BUTTON_VOXELS[
|
||||
(state.get(POWERED) ? 12 : 0) +
|
||||
(4 * state.get(BLOCK_FACE).ordinal()) +
|
||||
state.get(HORIZONTAL_FACING).ordinal() - 2
|
||||
];
|
||||
}
|
||||
|
||||
@Override
|
||||
@SuppressWarnings("deprecation")
|
||||
public BlockState rotate(BlockState state, BlockRotation rotation) {
|
||||
return state.with(HORIZONTAL_FACING, rotation.rotate(state.get(HORIZONTAL_FACING)));
|
||||
}
|
||||
|
||||
@Override
|
||||
@SuppressWarnings("deprecation")
|
||||
public BlockState mirror(BlockState state, BlockMirror mirror) {
|
||||
return state.with(HORIZONTAL_FACING, mirror.apply(state.get(HORIZONTAL_FACING)));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onStateReplaced(BlockState state, World world, BlockPos pos, BlockState new_state, boolean moved) {
|
||||
super.onStateReplaced(state, world, pos, new_state, false);
|
||||
|
||||
if(!state.isOf(new_state.getBlock())) {
|
||||
if (!moved && state.get(POWERED)) updateNeighbors(state, world, pos);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getWeakRedstonePower(BlockState state, BlockView view, BlockPos pos, Direction dir) {
|
||||
return state.get(POWERED) ? 15 : super.getWeakRedstonePower(state, view, pos, dir);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getStrongRedstonePower(BlockState state, BlockView view, BlockPos pos, Direction dir) {
|
||||
return dir == getDirection(state) ? state.getWeakRedstonePower(view, pos, dir) : 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
@SuppressWarnings("deprecation")
|
||||
public boolean emitsRedstonePower(BlockState state) {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
@SuppressWarnings("deprecation")
|
||||
public void scheduledTick(BlockState state, ServerWorld world, BlockPos pos, Random random) {
|
||||
if (state.get(POWERED)) tryPowerWithProjectiles(state, world, pos);
|
||||
}
|
||||
|
||||
@Override
|
||||
@SuppressWarnings("deprecation")
|
||||
public void onEntityCollision(BlockState state, World world, BlockPos pos, Entity entity) {
|
||||
if (!world.isClient && !state.get(POWERED)) tryPowerWithProjectiles(state, world, pos);
|
||||
}
|
||||
|
||||
protected void tryPowerWithProjectiles(BlockState state, World world, BlockPos pos) {
|
||||
PersistentProjectileEntity projectile = world.getNonSpectatingEntities(
|
||||
PersistentProjectileEntity.class,
|
||||
state.getOutlineShape(world, pos).getBoundingBox().offset(pos)
|
||||
).stream().findFirst().orElse(null);
|
||||
boolean has_projectile = projectile != null;
|
||||
if (has_projectile != state.get(POWERED)) {
|
||||
world.setBlockState(pos, state.with(POWERED, has_projectile), 3);
|
||||
this.updateNeighbors(state, world, pos);
|
||||
this.playClickSound(null, world, pos, has_projectile);
|
||||
world.emitGameEvent(projectile, has_projectile ? GameEvent.BLOCK_ACTIVATE : GameEvent.BLOCK_DEACTIVATE, pos);
|
||||
}
|
||||
|
||||
if (has_projectile) {
|
||||
world.scheduleBlockTick(pos, this, 30);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private void updateNeighbors(BlockState state, World world, BlockPos pos) {
|
||||
world.updateNeighborsAlways(pos, this);
|
||||
world.updateNeighborsAlways(pos.offset(getDirection(state).getOpposite()), this);
|
||||
}
|
||||
|
||||
protected static Direction getDirection(BlockState state) {
|
||||
return switch (state.get(BLOCK_FACE)) {
|
||||
case CEILING -> Direction.DOWN;
|
||||
case FLOOR -> Direction.UP;
|
||||
default -> state.get(HORIZONTAL_FACING);
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
static {
|
||||
VoxelShape SHAPE = createCuboidShape(5, 0, 6, 11, 2, 10);
|
||||
VoxelShape POWERED_SHAPE = createCuboidShape(5, 0, 6, 11, 1, 10);
|
||||
BUTTON_VOXELS = VoxelHelper.VoxelListBuilder.create(SHAPE, 24)
|
||||
.add()
|
||||
.add(0, VoxelHelper::rotateY)
|
||||
.add()
|
||||
.add(VoxelHelper::rotateZ, VoxelHelper::rotateY)
|
||||
.add(VoxelHelper::mirrorZ)
|
||||
.add(VoxelHelper::rotateY)
|
||||
.add(VoxelHelper::mirrorX)
|
||||
.add(0, VoxelHelper::mirrorY)
|
||||
.add()
|
||||
.add(2, VoxelHelper::mirrorY)
|
||||
.add()
|
||||
.add(POWERED_SHAPE)
|
||||
.add()
|
||||
.add(12, VoxelHelper::rotateY)
|
||||
.add()
|
||||
.add(VoxelHelper::rotateZ, VoxelHelper::rotateY)
|
||||
.add(VoxelHelper::mirrorZ)
|
||||
.add(VoxelHelper::rotateY)
|
||||
.add(VoxelHelper::mirrorX)
|
||||
.add(12, VoxelHelper::mirrorY)
|
||||
.add()
|
||||
.add(13, VoxelHelper::mirrorY)
|
||||
.add()
|
||||
.build();
|
||||
}
|
||||
}
|
||||
@@ -57,6 +57,7 @@ public class ReFramedDoorBlock extends WaterloggableReFramedBlock {
|
||||
}
|
||||
|
||||
@Override
|
||||
@SuppressWarnings("deprecation")
|
||||
public boolean canPlaceAt(BlockState state, WorldView world, BlockPos pos) {
|
||||
BlockPos pos_down = pos.down();
|
||||
BlockState state_down = world.getBlockState(pos_down);
|
||||
@@ -64,6 +65,7 @@ public class ReFramedDoorBlock extends WaterloggableReFramedBlock {
|
||||
}
|
||||
|
||||
@Override
|
||||
@SuppressWarnings("deprecation")
|
||||
public void neighborUpdate(BlockState state, World world, BlockPos pos, Block source, BlockPos sourcePos, boolean notify) {
|
||||
if (world.isClient) return;
|
||||
boolean powered = world.isReceivingRedstonePower(pos)
|
||||
@@ -113,7 +115,7 @@ public class ReFramedDoorBlock extends WaterloggableReFramedBlock {
|
||||
|
||||
@Override
|
||||
public BlockState onBreak(World world, BlockPos pos, BlockState state, PlayerEntity player) {
|
||||
if (!world.isClient() && (player.isCreative() || !player.canHarvest(state))) {
|
||||
if (!world.isClient() && (player.isCreative() || player.canHarvest(state))) {
|
||||
DoubleBlockHalf half = state.get(DOUBLE_BLOCK_HALF);
|
||||
BlockPos other_pos = half == DoubleBlockHalf.LOWER ? pos.up() : pos.down();
|
||||
BlockState other_state = world.getBlockState(other_pos);
|
||||
@@ -126,13 +128,6 @@ public class ReFramedDoorBlock extends WaterloggableReFramedBlock {
|
||||
return super.onBreak(world, pos, state, player);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onStateReplaced(BlockState state, World world, BlockPos pos, BlockState newState, boolean moved) {
|
||||
super.onStateReplaced(state, world, pos, newState, moved);
|
||||
|
||||
if(!state.isOf(newState.getBlock())) world.removeBlockEntity(pos);
|
||||
}
|
||||
|
||||
@Override
|
||||
public BlockState getStateForNeighborUpdate(BlockState state, Direction direction, BlockState other, WorldAccess world, BlockPos pos, BlockPos moved) {
|
||||
if (direction.getAxis() == Direction.Axis.Y
|
||||
@@ -162,6 +157,7 @@ public class ReFramedDoorBlock extends WaterloggableReFramedBlock {
|
||||
}
|
||||
|
||||
@Override
|
||||
@SuppressWarnings("deprecation")
|
||||
public boolean canPathfindThrough(BlockState state, BlockView world, BlockPos pos, NavigationType type) {
|
||||
return switch (type) {
|
||||
case LAND, AIR -> state.get(OPEN);
|
||||
@@ -170,6 +166,7 @@ public class ReFramedDoorBlock extends WaterloggableReFramedBlock {
|
||||
}
|
||||
|
||||
@Override
|
||||
@SuppressWarnings("deprecation")
|
||||
public void onExploded(BlockState state, World world, BlockPos pos, Explosion explosion, BiConsumer<ItemStack, BlockPos> stack_merger) {
|
||||
if (explosion.getDestructionType() == Explosion.DestructionType.TRIGGER_BLOCK
|
||||
&& !world.isClient()
|
||||
@@ -192,6 +189,7 @@ public class ReFramedDoorBlock extends WaterloggableReFramedBlock {
|
||||
}
|
||||
|
||||
@Override
|
||||
@SuppressWarnings("deprecation")
|
||||
public VoxelShape getOutlineShape(BlockState state, BlockView world, BlockPos pos, ShapeContext context) {
|
||||
Direction direction = state.get(HORIZONTAL_FACING);
|
||||
if (state.get(OPEN)) direction = switch (state.get(DOOR_HINGE)) {
|
||||
@@ -202,16 +200,19 @@ public class ReFramedDoorBlock extends WaterloggableReFramedBlock {
|
||||
}
|
||||
|
||||
@Override
|
||||
@SuppressWarnings("deprecation")
|
||||
public BlockState rotate(BlockState state, BlockRotation rotation) {
|
||||
return state.with(HORIZONTAL_FACING, rotation.rotate(state.get(HORIZONTAL_FACING)));
|
||||
}
|
||||
|
||||
@Override
|
||||
@SuppressWarnings("deprecation")
|
||||
public BlockState mirror(BlockState state, BlockMirror mirror) {
|
||||
return mirror == BlockMirror.NONE ? state : state.with(HORIZONTAL_FACING, mirror.apply(state.get(HORIZONTAL_FACING))).cycle(DOOR_HINGE);
|
||||
}
|
||||
|
||||
@Override
|
||||
@SuppressWarnings("deprecation")
|
||||
public long getRenderingSeed(BlockState state, BlockPos pos) {
|
||||
return MathHelper.hashCode(pos.getX(), pos.down(state.get(DOUBLE_BLOCK_HALF) == DoubleBlockHalf.LOWER ? 0 : 1).getY(), pos.getZ());
|
||||
}
|
||||
|
||||
@@ -19,7 +19,6 @@ import net.minecraft.world.World;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import static net.minecraft.util.shape.VoxelShapes.empty;
|
||||
import static net.minecraft.util.shape.VoxelShapes.fullCube;
|
||||
|
||||
public abstract class ReFramedDoubleBlock extends ReFramedBlock {
|
||||
public ReFramedDoubleBlock(Settings settings) {
|
||||
@@ -49,14 +48,6 @@ 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
|
||||
@@ -69,7 +60,7 @@ public abstract class ReFramedDoubleBlock extends ReFramedBlock {
|
||||
|
||||
@Override
|
||||
public VoxelShape getCollisionShape(BlockState state, BlockView view, BlockPos pos, ShapeContext ctx) {
|
||||
return isGhost(view, pos) ? empty() : fullCube();
|
||||
return isGhost(view, pos) ? empty() : getOutlineShape(state, view, pos, ctx);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -57,6 +57,6 @@ public class ReFramedDoubleEntity extends ReFramedEntity {
|
||||
public void writeNbt(NbtCompound nbt) {
|
||||
super.writeNbt(nbt);
|
||||
|
||||
if(second_state != Blocks.AIR.getDefaultState()) nbt.put(BLOCKSTATE_KEY + 2, NbtHelper.fromBlockState(second_state));
|
||||
nbt.put(BLOCKSTATE_KEY + 2, NbtHelper.fromBlockState(second_state));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -32,12 +32,12 @@ public class ReFramedEntity extends BlockEntity implements ThemeableBlockEntity
|
||||
protected BlockState first_state = Blocks.AIR.getDefaultState();
|
||||
protected byte bit_field = SOLIDITY_MASK;
|
||||
|
||||
protected static final byte LIGHT_MASK = 0b001;
|
||||
protected static final byte REDSTONE_MASK = 0b010;
|
||||
protected static final byte SOLIDITY_MASK = 0b100;
|
||||
public static final byte LIGHT_MASK = 0b001;
|
||||
public static final byte REDSTONE_MASK = 0b010;
|
||||
public static final byte SOLIDITY_MASK = 0b100;
|
||||
|
||||
public static final String BLOCKSTATE_KEY = "s";
|
||||
protected static final String BITFIELD_KEY = "b";
|
||||
public static final String BITFIELD_KEY = "b";
|
||||
|
||||
public ReFramedEntity(BlockEntityType<?> type, BlockPos pos, BlockState state) {
|
||||
super(type, pos, state);
|
||||
@@ -52,16 +52,15 @@ public class ReFramedEntity extends BlockEntity implements ThemeableBlockEntity
|
||||
if (nbt.contains(BITFIELD_KEY)) bit_field = nbt.getByte(BITFIELD_KEY);
|
||||
|
||||
// Force a chunk remesh on the client if the displayed blockstate has changed
|
||||
if(world != null && world.isClient && !Objects.equals(rendered_state, first_state)) {
|
||||
if(world != null && world.isClient && !Objects.equals(rendered_state, first_state))
|
||||
ReFramed.chunkRerenderProxy.accept(world, pos);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeNbt(NbtCompound nbt) {
|
||||
super.writeNbt(nbt);
|
||||
|
||||
if(first_state != Blocks.AIR.getDefaultState()) nbt.put(BLOCKSTATE_KEY + 1, NbtHelper.fromBlockState(first_state));
|
||||
|
||||
nbt.put(BLOCKSTATE_KEY + 1, NbtHelper.fromBlockState(first_state));
|
||||
if(bit_field != SOLIDITY_MASK) nbt.putByte(BITFIELD_KEY, bit_field);
|
||||
}
|
||||
|
||||
@@ -113,7 +112,7 @@ public class ReFramedEntity extends BlockEntity implements ThemeableBlockEntity
|
||||
}
|
||||
|
||||
public void setTheme(BlockState new_state, int i) {
|
||||
if(!Objects.equals(first_state, new_state)) {
|
||||
if(!Objects.equals(first_state, new_state) && i == 1) {
|
||||
first_state = new_state;
|
||||
markDirtyAndDispatch();
|
||||
}
|
||||
@@ -146,7 +145,10 @@ public class ReFramedEntity extends BlockEntity implements ThemeableBlockEntity
|
||||
if (isSolid()) bit_field &= ~SOLIDITY_MASK;
|
||||
else bit_field |= SOLIDITY_MASK;
|
||||
|
||||
if(world != null) world.setBlockState(pos, getCachedState());
|
||||
if(world != null) {
|
||||
world.setBlockState(pos, getCachedState());
|
||||
ReFramed.chunkRerenderProxy.accept(world, pos);
|
||||
}
|
||||
markDirtyAndDispatch();
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,108 @@
|
||||
package fr.adrien1106.reframed.block;
|
||||
|
||||
import fr.adrien1106.reframed.util.VoxelHelper;
|
||||
import net.minecraft.block.BlockState;
|
||||
import net.minecraft.block.FenceGateBlock;
|
||||
import net.minecraft.block.ShapeContext;
|
||||
import net.minecraft.entity.ai.pathing.NavigationType;
|
||||
import net.minecraft.entity.player.PlayerEntity;
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.item.Items;
|
||||
import net.minecraft.item.LeadItem;
|
||||
import net.minecraft.registry.tag.BlockTags;
|
||||
import net.minecraft.util.ActionResult;
|
||||
import net.minecraft.util.Hand;
|
||||
import net.minecraft.util.function.BooleanBiFunction;
|
||||
import net.minecraft.util.hit.BlockHitResult;
|
||||
import net.minecraft.util.math.BlockPos;
|
||||
import net.minecraft.util.math.Direction;
|
||||
import net.minecraft.util.shape.VoxelShape;
|
||||
import net.minecraft.util.shape.VoxelShapes;
|
||||
import net.minecraft.world.BlockView;
|
||||
import net.minecraft.world.World;
|
||||
|
||||
public class ReFramedFenceBlock extends ConnectingReFramedBlock {
|
||||
|
||||
public static final VoxelShape[] FENCE_VOXELS;
|
||||
|
||||
public ReFramedFenceBlock(Settings settings) {
|
||||
super(settings);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean connectsTo(BlockState state, boolean fs, Direction dir) {
|
||||
return fs || state.isIn(BlockTags.FENCES)
|
||||
|| (state.getBlock() instanceof FenceGateBlock && FenceGateBlock.canWallConnect(state, dir));
|
||||
}
|
||||
|
||||
@Override
|
||||
public VoxelShape getOutlineShape(BlockState state, BlockView world, BlockPos pos, ShapeContext context) {
|
||||
VoxelShape shape = FENCE_VOXELS[0];
|
||||
for (Direction dir: Direction.Type.HORIZONTAL) {
|
||||
if (state.get(getConnectionProperty(dir)))
|
||||
shape = VoxelShapes.union(shape, FENCE_VOXELS[dir.ordinal() - 1]);
|
||||
}
|
||||
return shape;
|
||||
}
|
||||
|
||||
@Override
|
||||
public VoxelShape getCollisionShape(BlockState state, BlockView view, BlockPos pos, ShapeContext ctx) {
|
||||
VoxelShape shape = FENCE_VOXELS[5];
|
||||
for (Direction dir: Direction.Type.HORIZONTAL) {
|
||||
if (state.get(getConnectionProperty(dir)))
|
||||
shape = VoxelShapes.union(shape, FENCE_VOXELS[dir.ordinal() + 4]);
|
||||
}
|
||||
return shape;
|
||||
}
|
||||
|
||||
@Override
|
||||
@SuppressWarnings("deprecation")
|
||||
public VoxelShape getCameraCollisionShape(BlockState state, BlockView world, BlockPos pos, ShapeContext context) {
|
||||
return getOutlineShape(state, world, pos, context);
|
||||
}
|
||||
|
||||
@Override
|
||||
public VoxelShape getCullingShape(BlockState state, BlockView view, BlockPos pos) {
|
||||
return getOutlineShape(state, view, pos, ShapeContext.absent());
|
||||
}
|
||||
|
||||
@Override
|
||||
@SuppressWarnings("deprecation")
|
||||
public boolean canPathfindThrough(BlockState state, BlockView world, BlockPos pos, NavigationType type) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ActionResult onUse(BlockState state, World world, BlockPos pos, PlayerEntity player, Hand hand, BlockHitResult hit) {
|
||||
ActionResult result = super.onUse(state, world, pos, player, hand, hit);
|
||||
if (result.isAccepted()) return result;
|
||||
if (world.isClient) {
|
||||
ItemStack itemStack = player.getStackInHand(hand);
|
||||
return itemStack.isOf(Items.LEAD) ? ActionResult.SUCCESS : ActionResult.PASS;
|
||||
} else {
|
||||
return LeadItem.attachHeldMobsToBlock(player, world, pos);
|
||||
}
|
||||
}
|
||||
|
||||
static {
|
||||
VoxelShape POST = createCuboidShape(6, 0, 6, 10, 16, 10);
|
||||
VoxelShape POST_COLLISION = createCuboidShape(6, 0, 6, 10, 24, 10);
|
||||
VoxelShape SIDE = VoxelShapes.combineAndSimplify(
|
||||
createCuboidShape(7, 12, 0, 9, 15, 6),
|
||||
createCuboidShape(7, 6, 0, 9, 9, 6),
|
||||
BooleanBiFunction.OR
|
||||
);
|
||||
VoxelShape SIDE_COLLISION = createCuboidShape(7, 0, 0, 9, 24, 6);
|
||||
FENCE_VOXELS = VoxelHelper.VoxelListBuilder.create(POST, 5)
|
||||
.add(SIDE)
|
||||
.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();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,188 @@
|
||||
package fr.adrien1106.reframed.block;
|
||||
|
||||
import fr.adrien1106.reframed.ReFramed;
|
||||
import fr.adrien1106.reframed.util.VoxelHelper;
|
||||
import fr.adrien1106.reframed.util.blocks.BlockHelper;
|
||||
import fr.adrien1106.reframed.util.blocks.Edge;
|
||||
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.BlockMirror;
|
||||
import net.minecraft.util.BlockRotation;
|
||||
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 fr.adrien1106.reframed.util.VoxelHelper.VoxelListBuilder;
|
||||
import static fr.adrien1106.reframed.util.blocks.BlockProperties.EDGE;
|
||||
import static fr.adrien1106.reframed.util.blocks.BlockProperties.EDGE_FACE;
|
||||
import static net.minecraft.state.property.Properties.*;
|
||||
|
||||
public class ReFramedHalfLayerBlock extends LayeredReFramedBlock {
|
||||
|
||||
public static final VoxelShape[] HALF_LAYER_VOXELS;
|
||||
|
||||
public ReFramedHalfLayerBlock(Settings settings) {
|
||||
super(settings);
|
||||
setDefaultState(getDefaultState().with(EDGE, Edge.NORTH_DOWN).with(EDGE_FACE, 0));
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void appendProperties(StateManager.Builder<Block, BlockState> builder) {
|
||||
super.appendProperties(builder.add(EDGE, EDGE_FACE));
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean canReplace(BlockState state, ItemPlacementContext context) {
|
||||
if (super.canReplace(state, context)) return true;
|
||||
|
||||
if (context.getPlayer() == null
|
||||
|| context.getPlayer().isSneaking()
|
||||
|| !(context.getStack().getItem() instanceof BlockItem block_item)
|
||||
) return false;
|
||||
|
||||
Edge edge = state.get(EDGE);
|
||||
Direction face = edge.getDirection(state.get(EDGE_FACE));
|
||||
if (block_item.getBlock() == ReFramed.SLAB)
|
||||
return ReFramed.SLAB
|
||||
.matchesShape(
|
||||
context.getHitPos(),
|
||||
context.getBlockPos(),
|
||||
ReFramed.SLAB.getDefaultState().with(FACING, edge.getOtherDirection(face).getOpposite())
|
||||
);
|
||||
|
||||
if (block_item.getBlock() == ReFramed.STEP)
|
||||
return ReFramed.STEP
|
||||
.matchesShape(
|
||||
context.getHitPos(),
|
||||
context.getBlockPos(),
|
||||
ReFramed.STEP.getDefaultState().with(EDGE, edge.getOpposite(face))
|
||||
);
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public VoxelShape getOutlineShape(BlockState state, BlockView world, BlockPos pos, ShapeContext context) {
|
||||
return getHalfLayerShape(
|
||||
state.get(EDGE),
|
||||
state.get(EDGE_FACE),
|
||||
state.get(LAYERS)
|
||||
);
|
||||
}
|
||||
|
||||
@Override
|
||||
public @Nullable BlockState getPlacementState(ItemPlacementContext ctx) {
|
||||
BlockState previous = ctx.getWorld().getBlockState(ctx.getBlockPos());
|
||||
BlockState state = super.getPlacementState(ctx);
|
||||
|
||||
if (previous.isOf(this))
|
||||
return state;
|
||||
|
||||
if (previous.isOf(ReFramed.SLABS_HALF_LAYER) || previous.isOf(ReFramed.STEPS_HALF_LAYER))
|
||||
return previous.with(LAYERS, Math.min(8, previous.get(LAYERS) + 1));
|
||||
|
||||
if (previous.isOf(ReFramed.SLAB)) {
|
||||
Direction face = previous.get(FACING);
|
||||
Edge edge;
|
||||
if (face.getAxis() == ctx.getSide().getAxis()) {
|
||||
edge = BlockHelper.getPlacementEdge(ctx);
|
||||
if (face == ctx.getSide()) edge = edge.getOpposite(edge.getOtherDirection(ctx.getSide()));
|
||||
} else edge = Edge.getByDirections(face, ctx.getSide().getOpposite());
|
||||
|
||||
return ReFramed.SLABS_HALF_LAYER.getDefaultState()
|
||||
.with(EDGE, edge)
|
||||
.with(EDGE_FACE, edge.getDirectionIndex(face))
|
||||
.with(WATERLOGGED, previous.get(WATERLOGGED));
|
||||
}
|
||||
|
||||
if (previous.isOf(ReFramed.STEP)) {
|
||||
int face_index = 0;
|
||||
Edge edge = previous.get(EDGE);
|
||||
if (!ReFramed.STEP.matchesShape(
|
||||
ctx.getHitPos(),
|
||||
ctx.getBlockPos(),
|
||||
ReFramed.STEP.getDefaultState().with(EDGE, edge.getOpposite(1))
|
||||
)) face_index = 1;
|
||||
return ReFramed.STEPS_HALF_LAYER.getDefaultState()
|
||||
.with(EDGE, edge)
|
||||
.with(EDGE_FACE, face_index)
|
||||
.with(WATERLOGGED, previous.get(WATERLOGGED));
|
||||
}
|
||||
|
||||
Edge edge = BlockHelper.getPlacementEdge(ctx);
|
||||
return state.with(EDGE, edge).with(EDGE_FACE, edge.getDirectionIndex(ctx.getSide().getOpposite()));
|
||||
}
|
||||
|
||||
@Override
|
||||
@SuppressWarnings("deprecation")
|
||||
public BlockState rotate(BlockState state, BlockRotation rotation) {
|
||||
Edge edge = state.get(EDGE);
|
||||
Direction face = rotation.rotate(edge.getDirection(state.get(EDGE_FACE)));
|
||||
edge = edge.rotate(rotation);
|
||||
return state.with(EDGE, edge).with(EDGE_FACE, edge.getDirectionIndex(face));
|
||||
}
|
||||
|
||||
@Override
|
||||
@SuppressWarnings("deprecation")
|
||||
public BlockState mirror(BlockState state, BlockMirror mirror) {
|
||||
Edge edge = state.get(EDGE);
|
||||
Direction face = mirror.apply(edge.getDirection(state.get(EDGE_FACE)));
|
||||
edge = edge.mirror(mirror);
|
||||
return state.with(EDGE, edge).with(EDGE_FACE, edge.getDirectionIndex(face));
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<Integer, Integer> getThemeMap(BlockState state, BlockState new_state) {
|
||||
if (new_state.isOf(ReFramed.SLABS_HALF_LAYER)
|
||||
|| new_state.isOf(ReFramed.STEPS_HALF_LAYER)
|
||||
) return Map.of(1, 2);
|
||||
return super.getThemeMap(state, new_state);
|
||||
}
|
||||
|
||||
public static VoxelShape getHalfLayerShape(Edge edge, int face, int layer) {
|
||||
return HALF_LAYER_VOXELS[edge.ordinal() * 16 + face * 8 + layer - 1];
|
||||
}
|
||||
|
||||
static {
|
||||
VoxelListBuilder builder = VoxelListBuilder.create(createCuboidShape(0, 0, 0, 16, 8, 2), 192)
|
||||
.add(createCuboidShape(0, 0, 0, 16, 8, 4))
|
||||
.add(createCuboidShape(0, 0, 0, 16, 8, 6))
|
||||
.add(createCuboidShape(0, 0, 0, 16, 8, 8))
|
||||
.add(createCuboidShape(0, 0, 0, 16, 8, 10))
|
||||
.add(createCuboidShape(0, 0, 0, 16, 8, 12))
|
||||
.add(createCuboidShape(0, 0, 0, 16, 8, 14))
|
||||
.add(createCuboidShape(0, 0, 0, 16, 8, 16));
|
||||
|
||||
for (int i = 0; i < 8; i++) {
|
||||
builder.add(i, VoxelHelper::rotateCX, VoxelHelper::mirrorZ);
|
||||
}
|
||||
for (int i = 0; i < 48; i++) {
|
||||
builder.add(i, VoxelHelper::rotateCX);
|
||||
}
|
||||
for (int i = 0; i < 64; i++) {
|
||||
builder.add(i, VoxelHelper::rotateCY);
|
||||
}
|
||||
for (int i = 64; i < 80; i++) {
|
||||
builder.add(i, VoxelHelper::rotateX);
|
||||
}
|
||||
for (int i = 80; i < 96; i++) {
|
||||
builder.add(i, VoxelHelper::rotateX);
|
||||
}
|
||||
for (int i = 96; i < 112; i++) {
|
||||
builder.add(i, VoxelHelper::rotateX);
|
||||
}
|
||||
for (int i = 112; i < 128; i++) {
|
||||
builder.add(i, VoxelHelper::rotateX);
|
||||
}
|
||||
|
||||
HALF_LAYER_VOXELS = builder.build();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,86 @@
|
||||
package fr.adrien1106.reframed.block;
|
||||
|
||||
import fr.adrien1106.reframed.ReFramed;
|
||||
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.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.*;
|
||||
|
||||
public class ReFramedHalfSlabBlock extends ReFramedSlabBlock {
|
||||
|
||||
public static VoxelShape[] HALF_SLAB_SHAPES;
|
||||
|
||||
public ReFramedHalfSlabBlock(Settings settings) {
|
||||
super(settings);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean canReplace(BlockState state, ItemPlacementContext context) {
|
||||
if (context.getPlayer() == null
|
||||
|| context.getPlayer().isSneaking()
|
||||
|| !(context.getStack().getItem() instanceof BlockItem block_item)
|
||||
) return false;
|
||||
|
||||
// allow replacing with slab, step, small cube and half stair
|
||||
Block block = block_item.getBlock();
|
||||
if (block != this) return false;
|
||||
|
||||
// check if the player is clicking on the inner part of the block
|
||||
return ReFramed.HALF_SLABS_SLAB
|
||||
.matchesShape(
|
||||
context.getHitPos(),
|
||||
context.getBlockPos(),
|
||||
ReFramed.HALF_SLABS_SLAB.getDefaultState().with(FACING, state.get(FACING)),
|
||||
2
|
||||
);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public BlockState getPlacementState(ItemPlacementContext ctx) {
|
||||
BlockState current_state = ctx.getWorld().getBlockState(ctx.getBlockPos());
|
||||
|
||||
if (current_state.isOf(this))
|
||||
return ReFramed.HALF_SLABS_SLAB.getDefaultState()
|
||||
.with(FACING, current_state.get(FACING))
|
||||
.with(WATERLOGGED, current_state.get(WATERLOGGED));
|
||||
|
||||
return super.getPlacementState(ctx).with(FACING, ctx.getSide().getOpposite());
|
||||
}
|
||||
|
||||
@Override
|
||||
public VoxelShape getOutlineShape(BlockState state, BlockView world, BlockPos pos, ShapeContext context) {
|
||||
return getHalfSlabShape(state.get(FACING));
|
||||
}
|
||||
|
||||
public static VoxelShape getHalfSlabShape(Direction direction) {
|
||||
return HALF_SLAB_SHAPES[direction.getId()];
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<Integer, Integer> getThemeMap(BlockState state, BlockState new_state) {
|
||||
if (new_state.isOf(ReFramed.HALF_SLABS_SLAB)) return Map.of(1, 1);
|
||||
return super.getThemeMap(state, new_state);
|
||||
}
|
||||
|
||||
static {
|
||||
HALF_SLAB_SHAPES = VoxelHelper.VoxelListBuilder.create(createCuboidShape(0, 0, 0, 16, 4, 16),6)
|
||||
.add(createCuboidShape(0, 12, 0, 16, 16, 16))
|
||||
.add(createCuboidShape(0, 0, 0, 16, 16, 4))
|
||||
.add(createCuboidShape(0, 0, 12, 16, 16, 16))
|
||||
.add(createCuboidShape(0, 0, 0, 4, 16, 16))
|
||||
.add(createCuboidShape(12, 0, 0, 16, 16, 16))
|
||||
.build();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,45 @@
|
||||
package fr.adrien1106.reframed.block;
|
||||
|
||||
import fr.adrien1106.reframed.util.VoxelHelper;
|
||||
import net.minecraft.block.BlockState;
|
||||
import net.minecraft.block.ShapeContext;
|
||||
import net.minecraft.util.math.BlockPos;
|
||||
import net.minecraft.util.math.Direction;
|
||||
import net.minecraft.util.shape.VoxelShape;
|
||||
import net.minecraft.world.BlockView;
|
||||
|
||||
import static fr.adrien1106.reframed.block.ReFramedHalfSlabBlock.getHalfSlabShape;
|
||||
import static fr.adrien1106.reframed.block.ReFramedSlabBlock.getSlabShape;
|
||||
import static net.minecraft.state.property.Properties.FACING;
|
||||
|
||||
public class ReFramedHalfSlabsSlabBlock extends FacingDoubleReFramedBlock {
|
||||
|
||||
public static VoxelShape[] HALF_SLAB_COMP_SHAPES;
|
||||
|
||||
public ReFramedHalfSlabsSlabBlock(Settings settings) {
|
||||
super(settings);
|
||||
}
|
||||
|
||||
@Override
|
||||
public VoxelShape getOutlineShape(BlockState state, BlockView world, BlockPos pos, ShapeContext context) {
|
||||
return getSlabShape(state.get(FACING));
|
||||
}
|
||||
|
||||
@Override
|
||||
public VoxelShape getShape(BlockState state, int i) {
|
||||
Direction face = state.get(FACING);
|
||||
return i == 2
|
||||
? HALF_SLAB_COMP_SHAPES[face.getId()]
|
||||
: getHalfSlabShape(face);
|
||||
}
|
||||
|
||||
static {
|
||||
HALF_SLAB_COMP_SHAPES = VoxelHelper.VoxelListBuilder.create(createCuboidShape(0, 4, 0, 16, 8, 16),6)
|
||||
.add(createCuboidShape(0, 8, 0, 16, 12, 16))
|
||||
.add(createCuboidShape(0, 0, 4, 16, 16, 8))
|
||||
.add(createCuboidShape(0, 0, 8, 16, 16, 12))
|
||||
.add(createCuboidShape(4, 0, 0, 8, 16, 16))
|
||||
.add(createCuboidShape(8, 0, 0, 12, 16, 16))
|
||||
.build();
|
||||
}
|
||||
}
|
||||
@@ -25,6 +25,7 @@ import java.util.Map;
|
||||
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.FACING;
|
||||
import static net.minecraft.state.property.Properties.WATERLOGGED;
|
||||
|
||||
public class ReFramedHalfStairBlock extends WaterloggableReFramedBlock {
|
||||
@@ -42,38 +43,44 @@ public class ReFramedHalfStairBlock extends WaterloggableReFramedBlock {
|
||||
}
|
||||
|
||||
@Override
|
||||
@SuppressWarnings("deprecation")
|
||||
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())
|
||||
)
|
||||
)
|
||||
)
|
||||
);
|
||||
if (context.getPlayer() == null
|
||||
|| context.getPlayer().isSneaking()
|
||||
|| !(context.getStack().getItem() instanceof BlockItem block_item)
|
||||
) return false;
|
||||
|
||||
// allow replacing with slab, step, small cube and half stair
|
||||
Block block = block_item.getBlock();
|
||||
Corner corner = state.get(CORNER);
|
||||
Direction dir = corner.getDirection(state.get(CORNER_FACE));
|
||||
if (block == this || block == ReFramed.STEP)
|
||||
return ReFramed.HALF_STAIRS_STAIR.matchesShape(
|
||||
context.getHitPos(),
|
||||
context.getBlockPos(),
|
||||
ReFramed.HALF_STAIRS_STAIR.getDefaultState().with(EDGE, corner.getEdge(dir)),
|
||||
dir.getDirection() == Direction.AxisDirection.POSITIVE ? 1 : 2
|
||||
);
|
||||
|
||||
if (block == ReFramed.SMALL_CUBE)
|
||||
return ReFramed.SMALL_CUBE.matchesShape(
|
||||
context.getHitPos(),
|
||||
context.getBlockPos(),
|
||||
ReFramed.SMALL_CUBE.getDefaultState().with(CORNER, corner.change(dir))
|
||||
) || ReFramed.SMALL_CUBE.matchesShape(
|
||||
context.getHitPos(),
|
||||
context.getBlockPos(),
|
||||
ReFramed.SMALL_CUBE.getDefaultState().with(CORNER, corner.getOpposite(dir))
|
||||
);
|
||||
|
||||
if (block == ReFramed.SLAB)
|
||||
return ReFramed.SLAB.matchesShape(
|
||||
context.getHitPos(),
|
||||
context.getBlockPos(),
|
||||
ReFramed.SLAB.getDefaultState().with(FACING, dir.getOpposite())
|
||||
);
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -91,6 +98,15 @@ public class ReFramedHalfStairBlock extends WaterloggableReFramedBlock {
|
||||
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));
|
||||
if (current_state.isOf(ReFramed.SLAB)) {
|
||||
Corner corner = BlockHelper.getPlacementCorner(ctx);
|
||||
Direction face = current_state.get(FACING);
|
||||
if (!corner.hasDirection(face)) corner = corner.change(face.getOpposite());
|
||||
return ReFramed.SLABS_INNER_STAIR.getDefaultState()
|
||||
.with(CORNER, corner)
|
||||
.with(CORNER_FACE, corner.getDirectionIndex(face))
|
||||
.with(WATERLOGGED, current_state.get(WATERLOGGED));
|
||||
}
|
||||
|
||||
Corner corner = BlockHelper.getPlacementCorner(ctx);
|
||||
return super.getPlacementState(ctx)
|
||||
@@ -99,11 +115,13 @@ public class ReFramedHalfStairBlock extends WaterloggableReFramedBlock {
|
||||
}
|
||||
|
||||
@Override
|
||||
@SuppressWarnings("deprecation")
|
||||
public VoxelShape getOutlineShape(BlockState state, BlockView world, BlockPos pos, ShapeContext context) {
|
||||
return HALF_STAIR_VOXELS[state.get(CORNER_FACE) + state.get(CORNER).getID() * 3];
|
||||
return getHalfStairShape(state.get(CORNER), state.get(CORNER_FACE));
|
||||
}
|
||||
|
||||
@Override
|
||||
@SuppressWarnings("deprecation")
|
||||
public BlockState rotate(BlockState state, BlockRotation rotation) {
|
||||
Corner corner = state.get(CORNER).rotate(rotation);
|
||||
Direction face = state.get(CORNER).getDirection(state.get(CORNER_FACE));
|
||||
@@ -111,6 +129,7 @@ public class ReFramedHalfStairBlock extends WaterloggableReFramedBlock {
|
||||
}
|
||||
|
||||
@Override
|
||||
@SuppressWarnings("deprecation")
|
||||
public BlockState mirror(BlockState state, BlockMirror mirror) {
|
||||
Corner corner = state.get(CORNER).mirror(mirror);
|
||||
Direction face = state.get(CORNER).getDirection(state.get(CORNER_FACE));
|
||||
@@ -119,7 +138,11 @@ public class ReFramedHalfStairBlock extends WaterloggableReFramedBlock {
|
||||
|
||||
@Override
|
||||
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_SLAB)
|
||||
|| new_state.isOf(ReFramed.HALF_STAIRS_CUBE_STAIR)
|
||||
|| new_state.isOf(ReFramed.HALF_STAIRS_STEP_STAIR)
|
||||
) return Map.of(1, 1);
|
||||
if (new_state.isOf(ReFramed.SLABS_INNER_STAIR)) return Map.of(1, 2);
|
||||
if (new_state.isOf(ReFramed.HALF_STAIRS_STAIR))
|
||||
return Map.of(
|
||||
1,
|
||||
@@ -130,6 +153,10 @@ public class ReFramedHalfStairBlock extends WaterloggableReFramedBlock {
|
||||
return super.getThemeMap(state, new_state);
|
||||
}
|
||||
|
||||
public static VoxelShape getHalfStairShape(Corner corner, int face) {
|
||||
return HALF_STAIR_VOXELS[face + corner.getID() * 3];
|
||||
}
|
||||
|
||||
static {
|
||||
final VoxelShape HALF_STAIR = VoxelShapes.combineAndSimplify(
|
||||
createCuboidShape(8, 0, 0, 16, 16, 8),
|
||||
|
||||
@@ -0,0 +1,48 @@
|
||||
package fr.adrien1106.reframed.block;
|
||||
|
||||
import fr.adrien1106.reframed.util.blocks.Corner;
|
||||
import fr.adrien1106.reframed.util.blocks.Edge;
|
||||
import fr.adrien1106.reframed.util.blocks.StairShape;
|
||||
import net.minecraft.block.BlockState;
|
||||
import net.minecraft.block.ShapeContext;
|
||||
import net.minecraft.util.math.BlockPos;
|
||||
import net.minecraft.util.math.Direction;
|
||||
import net.minecraft.util.shape.VoxelShape;
|
||||
import net.minecraft.world.BlockView;
|
||||
|
||||
import static fr.adrien1106.reframed.block.ReFramedHalfStairBlock.getHalfStairShape;
|
||||
import static fr.adrien1106.reframed.block.ReFramedSmallCubeBlock.getSmallCubeShape;
|
||||
import static fr.adrien1106.reframed.block.ReFramedStairBlock.getStairShape;
|
||||
import static fr.adrien1106.reframed.util.blocks.BlockProperties.CORNER;
|
||||
import static fr.adrien1106.reframed.util.blocks.BlockProperties.CORNER_FACE;
|
||||
|
||||
public class ReFramedHalfStairsCubeStairBlock extends CornerDoubleReFramedBlock {
|
||||
|
||||
public ReFramedHalfStairsCubeStairBlock(Settings settings) {
|
||||
super(settings);
|
||||
}
|
||||
|
||||
@Override
|
||||
public VoxelShape getOutlineShape(BlockState state, BlockView world, BlockPos pos, ShapeContext context) {
|
||||
Corner corner = state.get(CORNER);
|
||||
Direction face = corner.getDirection(state.get(CORNER_FACE));
|
||||
Edge edge = corner.getEdge(face);
|
||||
return getStairShape(
|
||||
edge,
|
||||
face.getDirection() == Direction.AxisDirection.POSITIVE
|
||||
? StairShape.OUTER_LEFT
|
||||
: StairShape.OUTER_RIGHT
|
||||
);
|
||||
}
|
||||
|
||||
@Override
|
||||
public VoxelShape getShape(BlockState state, int i) {
|
||||
Corner corner = state.get(CORNER);
|
||||
Direction face = corner.getDirection(state.get(CORNER_FACE));
|
||||
if (i == 2) corner = corner.change(face);
|
||||
return i == 2
|
||||
? getSmallCubeShape(corner)
|
||||
: getHalfStairShape(corner, state.get(CORNER_FACE));
|
||||
}
|
||||
|
||||
}
|
||||
@@ -15,13 +15,12 @@ import net.minecraft.util.shape.VoxelShape;
|
||||
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.getHalfStairShape;
|
||||
import static fr.adrien1106.reframed.block.ReFramedSlabBlock.getSlabShape;
|
||||
import static fr.adrien1106.reframed.block.ReFramedSmallCubeBlock.SMALL_CUBE_VOXELS;
|
||||
import static fr.adrien1106.reframed.block.ReFramedSmallCubeBlock.getSmallCubeShape;
|
||||
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.NORTH_EAST_DOWN;
|
||||
import static net.minecraft.util.shape.VoxelShapes.empty;
|
||||
|
||||
public class ReFramedHalfStairsSlabBlock extends WaterloggableReFramedDoubleBlock {
|
||||
|
||||
@@ -44,16 +43,13 @@ public class ReFramedHalfStairsSlabBlock extends WaterloggableReFramedDoubleBloc
|
||||
}
|
||||
|
||||
@Override
|
||||
public VoxelShape getCollisionShape(BlockState state, BlockView view, BlockPos pos, ShapeContext ctx) {
|
||||
return isGhost(view, pos) ? empty(): getSlabShape(state.get(CORNER).getDirection(state.get(CORNER_FACE)));
|
||||
}
|
||||
|
||||
@Override
|
||||
@SuppressWarnings("deprecation")
|
||||
public VoxelShape getOutlineShape(BlockState state, BlockView world, BlockPos pos, ShapeContext context) {
|
||||
return getSlabShape(state.get(CORNER).getDirection(state.get(CORNER_FACE)));
|
||||
}
|
||||
|
||||
@Override
|
||||
@SuppressWarnings("deprecation")
|
||||
public BlockState rotate(BlockState state, BlockRotation rotation) {
|
||||
Corner corner = state.get(CORNER).rotate(rotation);
|
||||
Direction face = state.get(CORNER).getDirection(state.get(CORNER_FACE));
|
||||
@@ -61,6 +57,7 @@ public class ReFramedHalfStairsSlabBlock extends WaterloggableReFramedDoubleBloc
|
||||
}
|
||||
|
||||
@Override
|
||||
@SuppressWarnings("deprecation")
|
||||
public BlockState mirror(BlockState state, BlockMirror mirror) {
|
||||
Corner corner = state.get(CORNER).mirror(mirror);
|
||||
Direction face = state.get(CORNER).getDirection(state.get(CORNER_FACE));
|
||||
@@ -72,7 +69,7 @@ public class ReFramedHalfStairsSlabBlock extends WaterloggableReFramedDoubleBloc
|
||||
Corner corner = state.get(CORNER);
|
||||
int face = state.get(CORNER_FACE);
|
||||
return i == 2
|
||||
? SMALL_CUBE_VOXELS[corner.getOpposite(face).getID()]
|
||||
: HALF_STAIR_VOXELS[face + corner.getID() * 3];
|
||||
? getSmallCubeShape(corner.getOpposite(face))
|
||||
: getHalfStairShape(corner, face);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -17,11 +17,10 @@ import net.minecraft.util.shape.VoxelShape;
|
||||
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.getHalfStairShape;
|
||||
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.util.shape.VoxelShapes.empty;
|
||||
|
||||
public class ReFramedHalfStairsStairBlock extends WaterloggableReFramedDoubleBlock {
|
||||
public ReFramedHalfStairsStairBlock(Settings settings) {
|
||||
@@ -41,21 +40,19 @@ public class ReFramedHalfStairsStairBlock extends WaterloggableReFramedDoubleBlo
|
||||
}
|
||||
|
||||
@Override
|
||||
public VoxelShape getCollisionShape(BlockState state, BlockView view, BlockPos pos, ShapeContext ctx) {
|
||||
return isGhost(view, pos) ? empty(): getStairShape(state.get(EDGE), StairShape.STRAIGHT);
|
||||
}
|
||||
|
||||
@Override
|
||||
@SuppressWarnings("deprecation")
|
||||
public VoxelShape getOutlineShape(BlockState state, BlockView world, BlockPos pos, ShapeContext context) {
|
||||
return getStairShape(state.get(EDGE), StairShape.STRAIGHT);
|
||||
}
|
||||
|
||||
@Override
|
||||
@SuppressWarnings("deprecation")
|
||||
public BlockState rotate(BlockState state, BlockRotation rotation) {
|
||||
return state.with(EDGE, state.get(EDGE).rotate(rotation));
|
||||
}
|
||||
|
||||
@Override
|
||||
@SuppressWarnings("deprecation")
|
||||
public BlockState mirror(BlockState state, BlockMirror mirror) {
|
||||
return state.with(EDGE, state.get(EDGE).mirror(mirror));
|
||||
}
|
||||
@@ -72,7 +69,7 @@ public class ReFramedHalfStairsStairBlock extends WaterloggableReFramedDoubleBlo
|
||||
side
|
||||
|
||||
);
|
||||
return HALF_STAIR_VOXELS[corner.getID() * 3 + corner.getDirectionIndex(side)];
|
||||
return getHalfStairShape(corner, corner.getDirectionIndex(side));
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -0,0 +1,76 @@
|
||||
package fr.adrien1106.reframed.block;
|
||||
|
||||
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.minecraft.block.Block;
|
||||
import net.minecraft.block.BlockState;
|
||||
import net.minecraft.block.ShapeContext;
|
||||
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 static fr.adrien1106.reframed.block.ReFramedHalfStairBlock.getHalfStairShape;
|
||||
import static fr.adrien1106.reframed.block.ReFramedStairBlock.getStairShape;
|
||||
import static fr.adrien1106.reframed.block.ReFramedStepBlock.getStepShape;
|
||||
import static fr.adrien1106.reframed.util.blocks.BlockProperties.*;
|
||||
|
||||
public class ReFramedHalfStairsStepStairBlock extends CornerDoubleReFramedBlock {
|
||||
|
||||
public ReFramedHalfStairsStepStairBlock(Settings settings) {
|
||||
super(settings);
|
||||
setDefaultState(getDefaultState().with(CORNER_FEATURE, 0));
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void appendProperties(StateManager.Builder<Block, BlockState> builder) {
|
||||
super.appendProperties(builder.add(CORNER_FEATURE));
|
||||
}
|
||||
|
||||
@Override
|
||||
public @Nullable BlockState getPlacementState(ItemPlacementContext ctx) {
|
||||
BlockState state = super.getPlacementState(ctx);
|
||||
Corner corner = state.get(CORNER);
|
||||
int face_index = state.get(CORNER_FACE);
|
||||
Direction face = corner.getDirection(face_index);
|
||||
face = BlockHelper.getPlacementEdge(ctx).getOtherDirection(face);
|
||||
int feature_index = corner.getDirectionIndex(face);
|
||||
return state.with(CORNER_FEATURE, feature_index > face_index ? feature_index - 1 : feature_index);
|
||||
}
|
||||
|
||||
@Override
|
||||
public VoxelShape getOutlineShape(BlockState state, BlockView world, BlockPos pos, ShapeContext context) {
|
||||
Corner corner = state.get(CORNER);
|
||||
int feature_index = state.get(CORNER_FEATURE), face_index = state.get(CORNER_FACE);
|
||||
Direction feature_face = corner.getDirection(feature_index >= face_index ? feature_index + 1 : feature_index);
|
||||
Direction face = corner.getDirection(face_index);
|
||||
Edge edge = Edge.getByDirections(feature_face, face);
|
||||
return getStairShape(
|
||||
edge,
|
||||
corner.getOtherDirection(edge).getDirection() == Direction.AxisDirection.POSITIVE
|
||||
? edge.getDirectionIndex(face) == 0
|
||||
? StairShape.FIRST_OUTER_LEFT
|
||||
: StairShape.SECOND_OUTER_LEFT
|
||||
: edge.getDirectionIndex(face) == 0
|
||||
? StairShape.FIRST_OUTER_RIGHT
|
||||
: StairShape.SECOND_OUTER_RIGHT
|
||||
);
|
||||
}
|
||||
|
||||
@Override
|
||||
public VoxelShape getShape(BlockState state, int i) {
|
||||
Corner corner = state.get(CORNER);
|
||||
int feature_index = state.get(CORNER_FEATURE), face_index = state.get(CORNER_FACE);
|
||||
Direction feature_face = corner.getDirection(feature_index >= face_index ? feature_index + 1 : feature_index);
|
||||
Direction face = corner.getDirection(face_index);
|
||||
return i == 2
|
||||
? getStepShape(Edge.getByDirections(face.getOpposite(), feature_face))
|
||||
: getHalfStairShape(corner, face_index);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,64 +1,72 @@
|
||||
package fr.adrien1106.reframed.block;
|
||||
|
||||
import fr.adrien1106.reframed.ReFramed;
|
||||
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.BlockMirror;
|
||||
import net.minecraft.util.BlockRotation;
|
||||
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 static fr.adrien1106.reframed.util.VoxelHelper.VoxelListBuilder;
|
||||
import static net.minecraft.state.property.Properties.FACING;
|
||||
import static net.minecraft.state.property.Properties.LAYERS;
|
||||
import static fr.adrien1106.reframed.util.blocks.BlockProperties.HALF_LAYERS;
|
||||
import static net.minecraft.state.property.Properties.*;
|
||||
|
||||
public class ReFramedLayerBlock extends ReFramedSlabBlock {
|
||||
public class ReFramedLayerBlock extends LayeredReFramedBlock {
|
||||
|
||||
public static final VoxelShape[] LAYER_VOXELS;
|
||||
|
||||
public ReFramedLayerBlock(Settings settings) {
|
||||
super(settings);
|
||||
setDefaultState(getDefaultState().with(LAYERS, 1));
|
||||
setDefaultState(getDefaultState().with(FACING, Direction.DOWN));
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void appendProperties(StateManager.Builder<Block, BlockState> builder) {
|
||||
super.appendProperties(builder.add(LAYERS));
|
||||
super.appendProperties(builder.add(FACING));
|
||||
}
|
||||
|
||||
@Override
|
||||
public VoxelShape getOutlineShape(BlockState state, BlockView world, BlockPos pos, ShapeContext context) {
|
||||
return LAYER_VOXELS[state.get(FACING).getId() * 8 + state.get(LAYERS) - 1];
|
||||
return getLayerShape(state.get(FACING), state.get(LAYERS));
|
||||
}
|
||||
|
||||
@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(LAYERS) < 8)
|
||||
);
|
||||
public static VoxelShape getLayerShape(Direction facing, int layers) {
|
||||
return LAYER_VOXELS[facing.getId() * 8 + layers - 1];
|
||||
}
|
||||
|
||||
@Override
|
||||
public @Nullable BlockState getPlacementState(ItemPlacementContext ctx) {
|
||||
BlockState previous = ctx.getWorld().getBlockState(ctx.getBlockPos());
|
||||
if (!previous.isOf(this)) return super.getPlacementState(ctx);
|
||||
return previous.with(LAYERS, previous.get(LAYERS) + 1);
|
||||
BlockState state = super.getPlacementState(ctx);
|
||||
if (previous.isOf(this)) return state;
|
||||
|
||||
if (previous.isOf(ReFramed.SLAB))
|
||||
return ReFramed.SLABS_LAYER.getDefaultState()
|
||||
.with(FACING, previous.get(FACING))
|
||||
.with(WATERLOGGED, previous.get(WATERLOGGED));
|
||||
|
||||
if (previous.isOf(ReFramed.SLABS_LAYER))
|
||||
return previous.with(HALF_LAYERS, previous.get(HALF_LAYERS) + 1);
|
||||
|
||||
return state.with(FACING, ctx.getSide().getOpposite());
|
||||
}
|
||||
|
||||
@Override
|
||||
@SuppressWarnings("deprecation")
|
||||
public BlockState rotate(BlockState state, BlockRotation rotation) {
|
||||
return state.with(FACING, rotation.rotate(state.get(FACING)));
|
||||
}
|
||||
|
||||
@Override
|
||||
@SuppressWarnings("deprecation")
|
||||
public BlockState mirror(BlockState state, BlockMirror mirror) {
|
||||
return state.with(FACING, mirror.apply(state.get(FACING)));
|
||||
}
|
||||
|
||||
@@ -1,122 +1,39 @@
|
||||
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.PaneBlock;
|
||||
import net.minecraft.block.ShapeContext;
|
||||
import net.minecraft.item.ItemPlacementContext;
|
||||
import net.minecraft.registry.tag.BlockTags;
|
||||
import net.minecraft.state.StateManager;
|
||||
import net.minecraft.state.property.BooleanProperty;
|
||||
import net.minecraft.util.BlockMirror;
|
||||
import net.minecraft.util.BlockRotation;
|
||||
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 static net.minecraft.state.property.Properties.*;
|
||||
|
||||
public class ReFramedPaneBlock extends WaterloggableReFramedBlock {
|
||||
public class ReFramedPaneBlock extends ConnectingReFramedBlock {
|
||||
|
||||
public static final VoxelShape[] PANE_VOXELS;
|
||||
|
||||
public ReFramedPaneBlock(Settings settings) {
|
||||
super(settings);
|
||||
setDefaultState(getDefaultState()
|
||||
.with(EAST, false)
|
||||
.with(NORTH, false)
|
||||
.with(WEST, false)
|
||||
.with(SOUTH, false)
|
||||
);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void appendProperties(StateManager.Builder<Block, BlockState> builder) {
|
||||
super.appendProperties(builder.add(EAST, NORTH, SOUTH, WEST));
|
||||
}
|
||||
|
||||
@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;
|
||||
|
||||
for (Direction side: Direction.Type.HORIZONTAL) {
|
||||
BlockState neighbor = world.getBlockState(pos.offset(side));
|
||||
new_state = new_state.with(getPaneProperty(side), connectsTo(
|
||||
neighbor,
|
||||
neighbor.isSideSolidFullSquare(world, pos.offset(side), side.getOpposite())
|
||||
));
|
||||
}
|
||||
return new_state;
|
||||
}
|
||||
|
||||
@Override
|
||||
public @Nullable BlockState getPlacementState(ItemPlacementContext ctx) {
|
||||
BlockState state = super.getPlacementState(ctx);
|
||||
World world = ctx.getWorld();
|
||||
BlockPos pos = ctx.getBlockPos();
|
||||
|
||||
for (Direction dir: Direction.Type.HORIZONTAL) {
|
||||
BlockState neighbor = world.getBlockState(pos.offset(dir));
|
||||
state = state.with(getPaneProperty(dir), connectsTo(
|
||||
neighbor,
|
||||
neighbor.isSideSolidFullSquare(world, pos.offset(dir), dir.getOpposite())
|
||||
));
|
||||
}
|
||||
return state;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onStateReplaced(BlockState state, World world, BlockPos pos, BlockState newState, boolean moved) {
|
||||
super.onStateReplaced(state, world, pos, newState, moved);
|
||||
|
||||
if(!state.isOf(newState.getBlock())) world.removeBlockEntity(pos);
|
||||
}
|
||||
|
||||
@Override
|
||||
public VoxelShape getOutlineShape(BlockState state, BlockView world, BlockPos pos, ShapeContext context) {
|
||||
VoxelShape shape = PANE_VOXELS[0];
|
||||
for (Direction dir: Direction.Type.HORIZONTAL) {
|
||||
if (state.get(getPaneProperty(dir)))
|
||||
if (state.get(getConnectionProperty(dir)))
|
||||
shape = VoxelShapes.union(shape, PANE_VOXELS[dir.ordinal() - 1]);
|
||||
}
|
||||
return shape;
|
||||
}
|
||||
|
||||
@Override
|
||||
public BlockState rotate(BlockState state, BlockRotation rotation) {
|
||||
return Direction.Type.HORIZONTAL.stream().reduce(state, (s, dir) ->
|
||||
s.with(getPaneProperty(rotation.rotate(dir)), state.get(getPaneProperty(dir)))
|
||||
, (prev, next) -> next);
|
||||
}
|
||||
|
||||
@Override
|
||||
public BlockState mirror(BlockState state, BlockMirror mirror) {
|
||||
return Direction.Type.HORIZONTAL.stream().reduce(state, (s, dir) ->
|
||||
s.with(getPaneProperty(mirror.apply(dir)), state.get(getPaneProperty(dir)))
|
||||
, (prev, next) -> next);
|
||||
}
|
||||
|
||||
public static boolean connectsTo(BlockState state, boolean fs) {
|
||||
protected boolean connectsTo(BlockState state, boolean fs, Direction dir) {
|
||||
return !cannotConnect(state) && fs || state.getBlock() instanceof PaneBlock || state.isIn(BlockTags.WALLS);
|
||||
}
|
||||
|
||||
public static BooleanProperty getPaneProperty(Direction dir) {
|
||||
return switch (dir) {
|
||||
case NORTH -> NORTH;
|
||||
case EAST -> EAST;
|
||||
case SOUTH -> SOUTH;
|
||||
case WEST -> WEST;
|
||||
default -> null;
|
||||
};
|
||||
}
|
||||
|
||||
static {
|
||||
VoxelShape POST = createCuboidShape(7, 0, 7, 9, 16, 9);
|
||||
VoxelShape SIDE = createCuboidShape(7, 0, 0, 9, 16, 7);
|
||||
|
||||
@@ -1,38 +1,21 @@
|
||||
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.ItemPlacementContext;
|
||||
import net.minecraft.state.StateManager;
|
||||
import net.minecraft.util.BlockMirror;
|
||||
import net.minecraft.util.BlockRotation;
|
||||
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 static net.minecraft.state.property.Properties.AXIS;
|
||||
|
||||
public class ReFramedPillarBlock extends WaterloggableReFramedBlock {
|
||||
public class ReFramedPillarBlock extends PillarReFramedBlock {
|
||||
|
||||
public static final VoxelShape[] PILLAR_VOXELS;
|
||||
|
||||
public ReFramedPillarBlock(Settings settings) {
|
||||
super(settings);
|
||||
setDefaultState(getDefaultState().with(AXIS, Direction.Axis.Y));
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void appendProperties(StateManager.Builder<Block, BlockState> builder) {
|
||||
super.appendProperties(builder.add(AXIS));
|
||||
}
|
||||
|
||||
@Override
|
||||
public @Nullable BlockState getPlacementState(ItemPlacementContext ctx) {
|
||||
return super.getPlacementState(ctx).with(AXIS, ctx.getSide().getAxis());
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -44,16 +27,6 @@ public class ReFramedPillarBlock extends WaterloggableReFramedBlock {
|
||||
return PILLAR_VOXELS[axis.ordinal()];
|
||||
}
|
||||
|
||||
@Override
|
||||
public BlockState rotate(BlockState state, BlockRotation rotation) {
|
||||
return state.with(AXIS, rotation.rotate(Direction.get(Direction.AxisDirection.POSITIVE, state.get(AXIS))).getAxis());
|
||||
}
|
||||
|
||||
@Override
|
||||
public BlockState mirror(BlockState state, BlockMirror mirror) {
|
||||
return state.with(AXIS, mirror.apply(Direction.get(Direction.AxisDirection.POSITIVE, state.get(AXIS))).getAxis());
|
||||
}
|
||||
|
||||
static {
|
||||
final VoxelShape PILLAR = createCuboidShape(0, 4, 4, 16, 12, 12);
|
||||
PILLAR_VOXELS = VoxelHelper.VoxelListBuilder.create(PILLAR, 3)
|
||||
|
||||
@@ -71,13 +71,6 @@ public class ReFramedPillarsWallBlock extends WaterloggableReFramedDoubleBlock {
|
||||
return getWallState(state, top_state, neighbors, top_shape, fs, world, pos);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onStateReplaced(BlockState state, World world, BlockPos pos, BlockState newState, boolean moved) {
|
||||
super.onStateReplaced(state, world, pos, newState, moved);
|
||||
|
||||
if(!state.isOf(newState.getBlock())) world.removeBlockEntity(pos);
|
||||
}
|
||||
|
||||
@Override
|
||||
public VoxelShape getCollisionShape(BlockState state, BlockView view, BlockPos pos, ShapeContext ctx) {
|
||||
if (isGhost(view, pos)) return empty();
|
||||
@@ -95,6 +88,7 @@ public class ReFramedPillarsWallBlock extends WaterloggableReFramedDoubleBlock {
|
||||
}
|
||||
|
||||
@Override
|
||||
@SuppressWarnings("deprecation")
|
||||
public VoxelShape getOutlineShape(BlockState state, BlockView world, BlockPos pos, ShapeContext context) {
|
||||
VoxelShape shape = WALL_VOXELS[0];
|
||||
for (Direction dir: Direction.Type.HORIZONTAL) {
|
||||
@@ -106,6 +100,7 @@ public class ReFramedPillarsWallBlock extends WaterloggableReFramedDoubleBlock {
|
||||
}
|
||||
|
||||
@Override
|
||||
@SuppressWarnings("deprecation")
|
||||
public BlockState rotate(BlockState state, BlockRotation rotation) {
|
||||
return Direction.Type.HORIZONTAL.stream().reduce(state, (s, dir) ->
|
||||
s.with(getWallShape(rotation.rotate(dir)), state.get(getWallShape(dir)))
|
||||
@@ -113,6 +108,7 @@ public class ReFramedPillarsWallBlock extends WaterloggableReFramedDoubleBlock {
|
||||
}
|
||||
|
||||
@Override
|
||||
@SuppressWarnings("deprecation")
|
||||
public BlockState mirror(BlockState state, BlockMirror mirror) {
|
||||
return Direction.Type.HORIZONTAL.stream().reduce(state, (s, dir) ->
|
||||
s.with(getWallShape(mirror.apply(dir)), state.get(getWallShape(dir)))
|
||||
|
||||
@@ -0,0 +1,37 @@
|
||||
package fr.adrien1106.reframed.block;
|
||||
|
||||
import fr.adrien1106.reframed.util.VoxelHelper;
|
||||
import net.minecraft.block.BlockState;
|
||||
import net.minecraft.block.ShapeContext;
|
||||
import net.minecraft.util.math.BlockPos;
|
||||
import net.minecraft.util.math.Direction;
|
||||
import net.minecraft.util.shape.VoxelShape;
|
||||
import net.minecraft.world.BlockView;
|
||||
|
||||
import static net.minecraft.state.property.Properties.AXIS;
|
||||
|
||||
public class ReFramedPostBlock extends PillarReFramedBlock {
|
||||
|
||||
public static final VoxelShape[] POST_VOXELS;
|
||||
|
||||
public ReFramedPostBlock(Settings settings) {
|
||||
super(settings);
|
||||
}
|
||||
|
||||
@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 POST_VOXELS[axis.ordinal()];
|
||||
}
|
||||
|
||||
static {
|
||||
final VoxelShape POST = createCuboidShape(0, 6, 6, 16, 10, 10);
|
||||
POST_VOXELS = VoxelHelper.VoxelListBuilder.create(POST, 3)
|
||||
.add(VoxelHelper::rotateZ)
|
||||
.add(VoxelHelper::rotateX)
|
||||
.build();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,150 @@
|
||||
package fr.adrien1106.reframed.block;
|
||||
|
||||
import net.minecraft.block.Block;
|
||||
import net.minecraft.block.BlockState;
|
||||
import net.minecraft.block.FenceGateBlock;
|
||||
import net.minecraft.block.ShapeContext;
|
||||
import net.minecraft.entity.ai.pathing.NavigationType;
|
||||
import net.minecraft.entity.player.PlayerEntity;
|
||||
import net.minecraft.item.ItemPlacementContext;
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.item.Items;
|
||||
import net.minecraft.item.LeadItem;
|
||||
import net.minecraft.registry.tag.BlockTags;
|
||||
import net.minecraft.state.StateManager;
|
||||
import net.minecraft.util.ActionResult;
|
||||
import net.minecraft.util.BlockMirror;
|
||||
import net.minecraft.util.BlockRotation;
|
||||
import net.minecraft.util.Hand;
|
||||
import net.minecraft.util.hit.BlockHitResult;
|
||||
import net.minecraft.util.math.BlockPos;
|
||||
import net.minecraft.util.math.Direction;
|
||||
import net.minecraft.util.shape.VoxelShape;
|
||||
import net.minecraft.util.shape.VoxelShapes;
|
||||
import net.minecraft.world.BlockView;
|
||||
import net.minecraft.world.World;
|
||||
import net.minecraft.world.WorldAccess;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import static fr.adrien1106.reframed.block.ConnectingReFramedBlock.getConnectionProperty;
|
||||
import static fr.adrien1106.reframed.block.ConnectingReFramedBlock.placementState;
|
||||
import static fr.adrien1106.reframed.block.ReFramedFenceBlock.FENCE_VOXELS;
|
||||
import static net.minecraft.state.property.Properties.*;
|
||||
import static net.minecraft.state.property.Properties.WEST;
|
||||
|
||||
public class ReFramedPostFenceBlock extends WaterloggableReFramedDoubleBlock {
|
||||
|
||||
public ReFramedPostFenceBlock(Settings settings) {
|
||||
super(settings);
|
||||
setDefaultState(getDefaultState()
|
||||
.with(EAST, false)
|
||||
.with(NORTH, false)
|
||||
.with(WEST, false)
|
||||
.with(SOUTH, false)
|
||||
);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void appendProperties(StateManager.Builder<Block, BlockState> builder) {
|
||||
super.appendProperties(builder.add(EAST, NORTH, SOUTH, WEST));
|
||||
}
|
||||
|
||||
@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;
|
||||
|
||||
return placementState(new_state, world, pos, this::connectsTo);
|
||||
}
|
||||
|
||||
@Override
|
||||
public @Nullable BlockState getPlacementState(ItemPlacementContext ctx) {
|
||||
BlockState state = super.getPlacementState(ctx);
|
||||
World world = ctx.getWorld();
|
||||
BlockPos pos = ctx.getBlockPos();
|
||||
|
||||
return placementState(state, world, pos, this::connectsTo);
|
||||
}
|
||||
|
||||
@Override
|
||||
@SuppressWarnings("deprecation")
|
||||
public BlockState rotate(BlockState state, BlockRotation rotation) {
|
||||
return Direction.Type.HORIZONTAL.stream().reduce(state, (s, dir) ->
|
||||
s.with(getConnectionProperty(rotation.rotate(dir)), state.get(getConnectionProperty(dir)))
|
||||
, (prev, next) -> next);
|
||||
}
|
||||
|
||||
@Override
|
||||
@SuppressWarnings("deprecation")
|
||||
public BlockState mirror(BlockState state, BlockMirror mirror) {
|
||||
return Direction.Type.HORIZONTAL.stream().reduce(state, (s, dir) ->
|
||||
s.with(getConnectionProperty(mirror.apply(dir)), state.get(getConnectionProperty(dir)))
|
||||
, (prev, next) -> next);
|
||||
}
|
||||
|
||||
private boolean connectsTo(BlockState state, boolean fs, Direction dir) {
|
||||
return fs || state.isIn(BlockTags.FENCES)
|
||||
|| (state.getBlock() instanceof FenceGateBlock && FenceGateBlock.canWallConnect(state, dir));
|
||||
}
|
||||
|
||||
@Override
|
||||
public VoxelShape getShape(BlockState state, int i) {
|
||||
if (i == 1) return FENCE_VOXELS[0];
|
||||
VoxelShape shape = VoxelShapes.empty();
|
||||
for (Direction dir: Direction.Type.HORIZONTAL) {
|
||||
if (state.get(getConnectionProperty(dir)))
|
||||
shape = VoxelShapes.union(shape, FENCE_VOXELS[dir.ordinal() - 1]);
|
||||
}
|
||||
return shape;
|
||||
}
|
||||
|
||||
@Override
|
||||
@SuppressWarnings("deprecation")
|
||||
public VoxelShape getOutlineShape(BlockState state, BlockView world, BlockPos pos, ShapeContext context) {
|
||||
VoxelShape shape = FENCE_VOXELS[0];
|
||||
for (Direction dir: Direction.Type.HORIZONTAL) {
|
||||
if (state.get(getConnectionProperty(dir)))
|
||||
shape = VoxelShapes.union(shape, FENCE_VOXELS[dir.ordinal() - 1]);
|
||||
}
|
||||
return shape;
|
||||
}
|
||||
|
||||
@Override
|
||||
public VoxelShape getCollisionShape(BlockState state, BlockView view, BlockPos pos, ShapeContext ctx) {
|
||||
VoxelShape shape = FENCE_VOXELS[5];
|
||||
for (Direction dir: Direction.Type.HORIZONTAL) {
|
||||
if (state.get(getConnectionProperty(dir)))
|
||||
shape = VoxelShapes.union(shape, FENCE_VOXELS[dir.ordinal() + 4]);
|
||||
}
|
||||
return shape;
|
||||
}
|
||||
|
||||
@Override
|
||||
@SuppressWarnings("deprecation")
|
||||
public VoxelShape getCameraCollisionShape(BlockState state, BlockView world, BlockPos pos, ShapeContext context) {
|
||||
return getOutlineShape(state, world, pos, context);
|
||||
}
|
||||
|
||||
@Override
|
||||
public VoxelShape getCullingShape(BlockState state, BlockView view, BlockPos pos) {
|
||||
return getOutlineShape(state, view, pos, ShapeContext.absent());
|
||||
}
|
||||
|
||||
@Override
|
||||
@SuppressWarnings("deprecation")
|
||||
public boolean canPathfindThrough(BlockState state, BlockView world, BlockPos pos, NavigationType type) {
|
||||
return false;
|
||||
}
|
||||
|
||||
public ActionResult onUse(BlockState state, World world, BlockPos pos, PlayerEntity player, Hand hand, BlockHitResult hit) {
|
||||
ActionResult result = super.onUse(state, world, pos, player, hand, hit);
|
||||
if (result.isAccepted()) return result;
|
||||
if (world.isClient) {
|
||||
ItemStack itemStack = player.getStackInHand(hand);
|
||||
return itemStack.isOf(Items.LEAD) ? ActionResult.SUCCESS : ActionResult.PASS;
|
||||
} else {
|
||||
return LeadItem.attachHeldMobsToBlock(player, world, pos);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,6 +1,9 @@
|
||||
package fr.adrien1106.reframed.block;
|
||||
|
||||
import fr.adrien1106.reframed.ReFramed;
|
||||
import fr.adrien1106.reframed.util.blocks.BlockHelper;
|
||||
import fr.adrien1106.reframed.util.blocks.Corner;
|
||||
import fr.adrien1106.reframed.util.blocks.Edge;
|
||||
import net.minecraft.block.Block;
|
||||
import net.minecraft.block.BlockState;
|
||||
import net.minecraft.block.ShapeContext;
|
||||
@@ -18,8 +21,8 @@ import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
import static net.minecraft.state.property.Properties.AXIS;
|
||||
import static net.minecraft.state.property.Properties.FACING;
|
||||
import static fr.adrien1106.reframed.util.blocks.BlockProperties.*;
|
||||
import static net.minecraft.state.property.Properties.*;
|
||||
|
||||
public class ReFramedSlabBlock extends WaterloggableReFramedBlock {
|
||||
|
||||
@@ -41,45 +44,134 @@ public class ReFramedSlabBlock extends WaterloggableReFramedBlock {
|
||||
}
|
||||
|
||||
@Override
|
||||
@SuppressWarnings("deprecation")
|
||||
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
|
||||
)
|
||||
)
|
||||
);
|
||||
if (context.getPlayer() == null
|
||||
|| context.getPlayer().isSneaking()
|
||||
|| !(context.getStack().getItem() instanceof BlockItem block_item)
|
||||
) return false;
|
||||
|
||||
// allow replacing with slab, step, small cube and half stair
|
||||
Block block = block_item.getBlock();
|
||||
if (block != this
|
||||
&& block != ReFramed.STEP
|
||||
&& block != ReFramed.SMALL_CUBE
|
||||
&& block != ReFramed.HALF_STAIR
|
||||
&& block != ReFramed.HALF_LAYER
|
||||
&& block != ReFramed.LAYER
|
||||
) return false;
|
||||
|
||||
// check if the player is clicking on the inner part of the block
|
||||
return matchesShape(
|
||||
context.getHitPos(),
|
||||
context.getBlockPos(),
|
||||
state.with(FACING, state.get(FACING).getOpposite())
|
||||
);
|
||||
}
|
||||
|
||||
@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());
|
||||
|
||||
if (current_state.isOf(ReFramed.HALF_LAYER)) {
|
||||
Edge edge = current_state.get(EDGE);
|
||||
Direction face = edge.getDirection(current_state.get(EDGE_FACE));
|
||||
edge = edge.getOpposite(face);
|
||||
return ReFramed.SLABS_HALF_LAYER.getDefaultState()
|
||||
.with(EDGE, edge)
|
||||
.with(EDGE_FACE, edge.getDirectionIndex(edge.getOtherDirection(face)))
|
||||
.with(LAYERS, current_state.get(LAYERS))
|
||||
.with(WATERLOGGED, current_state.get(WATERLOGGED));
|
||||
}
|
||||
|
||||
if (current_state.isOf(ReFramed.HALF_STAIR)) {
|
||||
Corner corner = current_state.get(CORNER);
|
||||
Direction face = corner.getDirection(current_state.get(CORNER_FACE));
|
||||
corner = corner.change(face);
|
||||
return ReFramed.SLABS_INNER_STAIR.getDefaultState()
|
||||
.with(CORNER, corner)
|
||||
.with(CORNER_FACE, corner.getDirectionIndex(face.getOpposite()))
|
||||
.with(WATERLOGGED, current_state.get(WATERLOGGED));
|
||||
}
|
||||
|
||||
if (current_state.isOf(ReFramed.STEP)) {
|
||||
Edge edge = current_state.get(EDGE),
|
||||
placed = BlockHelper.getPlacementEdge(ctx),
|
||||
new_edge;
|
||||
Direction face = edge.getFirstDirection(),
|
||||
other = edge.getSecondDirection().getOpposite();
|
||||
|
||||
if (!ReFramed.STEP.matchesShape(
|
||||
ctx.getHitPos(),
|
||||
ctx.getBlockPos(),
|
||||
current_state.with(EDGE, new_edge = edge.getOpposite(face))
|
||||
)
|
||||
&& ctx.getSide() != other.getOpposite()
|
||||
&& (placed.getAxis() == edge.getAxis()
|
||||
|| ctx.getSide() == other
|
||||
|| !placed.hasDirection(other))
|
||||
) {
|
||||
new_edge = edge.getOpposite(edge.getSecondDirection());
|
||||
other = edge.getFirstDirection().getOpposite();
|
||||
}
|
||||
|
||||
return ReFramed.SLABS_STAIR.getDefaultState()
|
||||
.with(EDGE, new_edge)
|
||||
.with(EDGE_FACE, new_edge.getDirectionIndex(other))
|
||||
.with(WATERLOGGED, current_state.get(WATERLOGGED));
|
||||
}
|
||||
|
||||
if (current_state.isOf(ReFramed.SMALL_CUBE)) {
|
||||
Corner corner = current_state.get(CORNER);
|
||||
Edge placed = BlockHelper.getPlacementEdge(ctx);
|
||||
Direction face;
|
||||
Corner new_corner;
|
||||
|
||||
if (!corner.hasDirection(face = ctx.getSide())) {
|
||||
int i = 0;
|
||||
do {
|
||||
face = corner.getDirection(i);
|
||||
new_corner = corner.change(face);
|
||||
} while (!ReFramed.SMALL_CUBE.matchesShape(
|
||||
ctx.getHitPos(),
|
||||
ctx.getBlockPos(),
|
||||
current_state.with(CORNER, new_corner)
|
||||
) && ++i < 3);
|
||||
|
||||
if (i == 3) {
|
||||
face = placed.getOtherDirection(corner.getMatchingDirection(placed)).getOpposite();
|
||||
new_corner = corner.change(face);
|
||||
}
|
||||
} else new_corner = corner.change(face);
|
||||
|
||||
return ReFramed.SLABS_OUTER_STAIR.getDefaultState()
|
||||
.with(CORNER, new_corner)
|
||||
.with(CORNER_FACE, new_corner.getDirectionIndex(face.getOpposite()))
|
||||
.with(WATERLOGGED, current_state.get(WATERLOGGED));
|
||||
}
|
||||
|
||||
return super.getPlacementState(ctx).with(FACING, ctx.getSide().getOpposite());
|
||||
}
|
||||
|
||||
@Override
|
||||
@SuppressWarnings("deprecation")
|
||||
public VoxelShape getOutlineShape(BlockState state, BlockView world, BlockPos pos, ShapeContext context) {
|
||||
return getSlabShape(state.get(FACING));
|
||||
}
|
||||
|
||||
@Override
|
||||
@SuppressWarnings("deprecation")
|
||||
public BlockState rotate(BlockState state, BlockRotation rotation) {
|
||||
return state.with(FACING, rotation.rotate(state.get(FACING)));
|
||||
}
|
||||
|
||||
@Override
|
||||
@SuppressWarnings("deprecation")
|
||||
public BlockState mirror(BlockState state, BlockMirror mirror) {
|
||||
return state.with(FACING, mirror.apply(state.get(FACING)));
|
||||
}
|
||||
@@ -97,6 +189,11 @@ public class ReFramedSlabBlock extends WaterloggableReFramedBlock {
|
||||
|
||||
@Override
|
||||
public Map<Integer, Integer> getThemeMap(BlockState state, BlockState new_state) {
|
||||
if (new_state.isOf(ReFramed.SLABS_STAIR)
|
||||
|| new_state.isOf(ReFramed.SLABS_OUTER_STAIR)
|
||||
|| new_state.isOf(ReFramed.SLABS_INNER_STAIR)
|
||||
|| new_state.isOf(ReFramed.SLABS_HALF_LAYER)
|
||||
) return Map.of(1, 1);
|
||||
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);
|
||||
}
|
||||
|
||||
@@ -11,7 +11,6 @@ import net.minecraft.util.shape.VoxelShape;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import static fr.adrien1106.reframed.block.ReFramedSlabBlock.*;
|
||||
import static fr.adrien1106.reframed.util.blocks.BlockProperties.EDGE;
|
||||
import static net.minecraft.state.property.Properties.AXIS;
|
||||
|
||||
public class ReFramedSlabsCubeBlock extends ReFramedDoubleBlock {
|
||||
@@ -33,11 +32,13 @@ public class ReFramedSlabsCubeBlock extends ReFramedDoubleBlock {
|
||||
}
|
||||
|
||||
@Override
|
||||
@SuppressWarnings("deprecation")
|
||||
public BlockState rotate(BlockState state, BlockRotation rotation) {
|
||||
return state.with(AXIS, rotation.rotate(Direction.get(Direction.AxisDirection.POSITIVE, state.get(AXIS))).getAxis());
|
||||
}
|
||||
|
||||
@Override
|
||||
@SuppressWarnings("deprecation")
|
||||
public BlockState mirror(BlockState state, BlockMirror mirror) {
|
||||
return state.with(AXIS, mirror.apply(Direction.get(Direction.AxisDirection.POSITIVE, state.get(AXIS))).getAxis());
|
||||
}
|
||||
|
||||
@@ -0,0 +1,62 @@
|
||||
package fr.adrien1106.reframed.block;
|
||||
|
||||
import fr.adrien1106.reframed.util.blocks.Edge;
|
||||
import net.minecraft.block.BlockState;
|
||||
import net.minecraft.block.ShapeContext;
|
||||
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 static fr.adrien1106.reframed.block.ReFramedHalfLayerBlock.getHalfLayerShape;
|
||||
import static fr.adrien1106.reframed.block.ReFramedSlabBlock.getSlabShape;
|
||||
import static fr.adrien1106.reframed.util.blocks.BlockProperties.EDGE;
|
||||
import static fr.adrien1106.reframed.util.blocks.BlockProperties.EDGE_FACE;
|
||||
import static net.minecraft.state.property.Properties.LAYERS;
|
||||
|
||||
public class ReFramedSlabsHalfLayerBlock extends HalfLayerDoubleReFramedBlock {
|
||||
|
||||
private static final VoxelShape[] SLABS_HALF_LAYER_VOXELS = new VoxelShape[196];
|
||||
|
||||
public ReFramedSlabsHalfLayerBlock(Settings settings) {
|
||||
super(settings);
|
||||
}
|
||||
|
||||
@Override
|
||||
public VoxelShape getOutlineShape(BlockState state, BlockView world, BlockPos pos, ShapeContext context) {
|
||||
return getSlabsHalfLayerShape(state.get(EDGE), state.get(EDGE_FACE), state.get(LAYERS));
|
||||
}
|
||||
|
||||
public static VoxelShape getSlabsHalfLayerShape(Edge edge, int face, int layers) {
|
||||
int i = edge.ordinal() * 16 + face * 8 + layers - 1;
|
||||
VoxelShape shape = SLABS_HALF_LAYER_VOXELS[i];
|
||||
if (shape == null) {
|
||||
shape = VoxelShapes.combineAndSimplify(
|
||||
getShape(edge, edge.getDirection(face), layers, 1),
|
||||
getShape(edge, edge.getDirection(face), layers, 2),
|
||||
BooleanBiFunction.OR
|
||||
);
|
||||
SLABS_HALF_LAYER_VOXELS[i] = shape;
|
||||
}
|
||||
return shape;
|
||||
}
|
||||
|
||||
@Override
|
||||
public VoxelShape getShape(BlockState state, int i) {
|
||||
Edge edge = state.get(EDGE);
|
||||
Direction face = edge.getDirection(state.get(EDGE_FACE));
|
||||
return getShape(edge, face, state.get(LAYERS), i);
|
||||
}
|
||||
|
||||
private static VoxelShape getShape(Edge edge, Direction face, int layers, int i) {
|
||||
if (i == 2) {
|
||||
face = edge.getOtherDirection(face);
|
||||
edge = edge.getOpposite(face);
|
||||
}
|
||||
return i == 2
|
||||
? getHalfLayerShape(edge, edge.getDirectionIndex(face), layers)
|
||||
: getSlabShape(face);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,48 @@
|
||||
package fr.adrien1106.reframed.block;
|
||||
|
||||
import fr.adrien1106.reframed.util.blocks.Corner;
|
||||
import fr.adrien1106.reframed.util.blocks.Edge;
|
||||
import fr.adrien1106.reframed.util.blocks.StairShape;
|
||||
import net.minecraft.block.BlockState;
|
||||
import net.minecraft.block.ShapeContext;
|
||||
import net.minecraft.util.math.BlockPos;
|
||||
import net.minecraft.util.math.Direction;
|
||||
import net.minecraft.util.shape.VoxelShape;
|
||||
import net.minecraft.world.BlockView;
|
||||
|
||||
import static fr.adrien1106.reframed.block.ReFramedHalfStairBlock.getHalfStairShape;
|
||||
import static fr.adrien1106.reframed.block.ReFramedSlabBlock.getSlabShape;
|
||||
import static fr.adrien1106.reframed.block.ReFramedStairBlock.getStairShape;
|
||||
import static fr.adrien1106.reframed.util.blocks.BlockProperties.CORNER;
|
||||
import static fr.adrien1106.reframed.util.blocks.BlockProperties.CORNER_FACE;
|
||||
|
||||
public class ReFramedSlabsInnerStairBlock extends CornerDoubleReFramedBlock {
|
||||
|
||||
public ReFramedSlabsInnerStairBlock(Settings settings) {
|
||||
super(settings);
|
||||
}
|
||||
|
||||
@Override
|
||||
public VoxelShape getOutlineShape(BlockState state, BlockView world, BlockPos pos, ShapeContext context) {
|
||||
Corner corner = state.get(CORNER);
|
||||
Direction face = corner.getDirection(state.get(CORNER_FACE));
|
||||
Edge edge = corner.getEdge(face);
|
||||
return getStairShape(
|
||||
edge,
|
||||
face.getDirection() == Direction.AxisDirection.POSITIVE
|
||||
? StairShape.INNER_LEFT
|
||||
: StairShape.INNER_RIGHT
|
||||
);
|
||||
}
|
||||
|
||||
@Override
|
||||
public VoxelShape getShape(BlockState state, int i) {
|
||||
Corner corner = state.get(CORNER);
|
||||
Direction face = corner.getDirection(state.get(CORNER_FACE));
|
||||
if (i == 2) corner = corner.change(face);
|
||||
return i == 2
|
||||
? getHalfStairShape(corner, corner.getDirectionIndex(face.getOpposite()))
|
||||
: getSlabShape(face);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,96 @@
|
||||
package fr.adrien1106.reframed.block;
|
||||
|
||||
import fr.adrien1106.reframed.ReFramed;
|
||||
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.item.ItemStack;
|
||||
import net.minecraft.loot.context.LootContextParameterSet;
|
||||
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 java.util.List;
|
||||
|
||||
import static fr.adrien1106.reframed.block.ReFramedLayerBlock.getLayerShape;
|
||||
import static fr.adrien1106.reframed.block.ReFramedSlabBlock.getSlabShape;
|
||||
import static fr.adrien1106.reframed.util.blocks.BlockProperties.HALF_LAYERS;
|
||||
import static net.minecraft.state.property.Properties.FACING;
|
||||
|
||||
public class ReFramedSlabsLayerBlock extends FacingDoubleReFramedBlock {
|
||||
|
||||
public static VoxelShape[] HALF_LAYER_SHAPES;
|
||||
|
||||
public ReFramedSlabsLayerBlock(Settings settings) {
|
||||
super(settings);
|
||||
setDefaultState(getDefaultState().with(HALF_LAYERS, 1));
|
||||
}
|
||||
|
||||
@Override
|
||||
@SuppressWarnings("deprecation")
|
||||
public List<ItemStack> getDroppedStacks(BlockState state, LootContextParameterSet.Builder builder) {
|
||||
List<ItemStack> drops = super.getDroppedStacks(state, builder);
|
||||
if (state.get(HALF_LAYERS) > 1)
|
||||
drops.add(new ItemStack(ReFramed.LAYER, state.get(HALF_LAYERS)-1));
|
||||
return drops;
|
||||
}
|
||||
|
||||
@Override
|
||||
@SuppressWarnings("deprecation")
|
||||
public boolean canReplace(BlockState state, ItemPlacementContext context) {
|
||||
if (context.getPlayer() == null
|
||||
|| context.getPlayer().isSneaking()
|
||||
|| !(context.getStack().getItem() instanceof BlockItem block_item)
|
||||
) return false;
|
||||
|
||||
return block_item.getBlock() == ReFramed.LAYER && state.get(HALF_LAYERS) < 4;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void appendProperties(StateManager.Builder<Block, BlockState> builder) {
|
||||
super.appendProperties(builder.add(HALF_LAYERS));
|
||||
}
|
||||
|
||||
@Override
|
||||
public VoxelShape getOutlineShape(BlockState state, BlockView world, BlockPos pos, ShapeContext context) {
|
||||
return getLayerShape(state.get(FACING), state.get(HALF_LAYERS) + 4);
|
||||
}
|
||||
|
||||
@Override
|
||||
public VoxelShape getShape(BlockState state, int i) {
|
||||
Direction face = state.get(FACING);
|
||||
return i == 2
|
||||
? HALF_LAYER_SHAPES[face.getId() * 4 + state.get(HALF_LAYERS)-1]
|
||||
: getSlabShape(face);
|
||||
}
|
||||
|
||||
static {
|
||||
VoxelHelper.VoxelListBuilder builder = VoxelHelper.VoxelListBuilder.create(createCuboidShape(0, 8, 0, 16, 10, 16), 24)
|
||||
.add(createCuboidShape(0, 8, 0, 16, 12, 16))
|
||||
.add(createCuboidShape(0, 8, 0, 16, 14, 16))
|
||||
.add(createCuboidShape(0, 8, 0, 16, 16, 16));
|
||||
|
||||
for (int i = 0; i < 4; i++) {
|
||||
builder.add(i, VoxelHelper::mirrorY);
|
||||
}
|
||||
for (int i = 0; i < 4; i++) {
|
||||
builder.add(i, VoxelHelper::rotateX);
|
||||
}
|
||||
for (int i = 0; i < 4; i++) {
|
||||
builder.add(i, VoxelHelper::rotateCX);
|
||||
}
|
||||
for (int i = 0; i < 4; i++) {
|
||||
builder.add(i, VoxelHelper::rotateCZ);
|
||||
}
|
||||
for (int i = 0; i < 4; i++) {
|
||||
builder.add(i, VoxelHelper::rotateZ);
|
||||
}
|
||||
|
||||
HALF_LAYER_SHAPES = builder.build();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,51 @@
|
||||
package fr.adrien1106.reframed.block;
|
||||
|
||||
import fr.adrien1106.reframed.util.blocks.Corner;
|
||||
import fr.adrien1106.reframed.util.blocks.Edge;
|
||||
import fr.adrien1106.reframed.util.blocks.StairShape;
|
||||
import net.minecraft.block.BlockState;
|
||||
import net.minecraft.block.ShapeContext;
|
||||
import net.minecraft.util.math.BlockPos;
|
||||
import net.minecraft.util.math.Direction;
|
||||
import net.minecraft.util.shape.VoxelShape;
|
||||
import net.minecraft.world.BlockView;
|
||||
|
||||
import static fr.adrien1106.reframed.block.ReFramedSlabBlock.getSlabShape;
|
||||
import static fr.adrien1106.reframed.block.ReFramedSmallCubeBlock.getSmallCubeShape;
|
||||
import static fr.adrien1106.reframed.block.ReFramedStairBlock.getStairShape;
|
||||
import static fr.adrien1106.reframed.util.blocks.BlockProperties.CORNER;
|
||||
import static fr.adrien1106.reframed.util.blocks.BlockProperties.CORNER_FACE;
|
||||
|
||||
public class ReFramedSlabsOuterStairBlock extends CornerDoubleReFramedBlock {
|
||||
|
||||
public ReFramedSlabsOuterStairBlock(Settings settings) {
|
||||
super(settings);
|
||||
}
|
||||
|
||||
@Override
|
||||
public VoxelShape getOutlineShape(BlockState state, BlockView world, BlockPos pos, ShapeContext context) {
|
||||
Corner corner = state.get(CORNER);
|
||||
Direction face = corner.getDirection(state.get(CORNER_FACE));
|
||||
Edge edge = corner.getEdgeWith(face);
|
||||
return getStairShape(
|
||||
edge,
|
||||
corner.getOtherDirection(edge).getDirection() == Direction.AxisDirection.POSITIVE
|
||||
? edge.getDirectionIndex(face) == 1
|
||||
? StairShape.FIRST_OUTER_LEFT
|
||||
: StairShape.SECOND_OUTER_LEFT
|
||||
: edge.getDirectionIndex(face) == 1
|
||||
? StairShape.FIRST_OUTER_RIGHT
|
||||
: StairShape.SECOND_OUTER_RIGHT
|
||||
);
|
||||
}
|
||||
|
||||
@Override
|
||||
public VoxelShape getShape(BlockState state, int i) {
|
||||
Corner corner = state.get(CORNER);
|
||||
Direction face = corner.getDirection(state.get(CORNER_FACE));
|
||||
return i == 2
|
||||
? getSmallCubeShape(corner.change(face))
|
||||
: getSlabShape(face);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,37 @@
|
||||
package fr.adrien1106.reframed.block;
|
||||
|
||||
import fr.adrien1106.reframed.util.blocks.Edge;
|
||||
import fr.adrien1106.reframed.util.blocks.StairShape;
|
||||
import net.minecraft.block.BlockState;
|
||||
import net.minecraft.block.ShapeContext;
|
||||
import net.minecraft.util.math.BlockPos;
|
||||
import net.minecraft.util.math.Direction;
|
||||
import net.minecraft.util.shape.VoxelShape;
|
||||
import net.minecraft.world.BlockView;
|
||||
|
||||
import static fr.adrien1106.reframed.block.ReFramedSlabBlock.getSlabShape;
|
||||
import static fr.adrien1106.reframed.block.ReFramedStairBlock.getStairShape;
|
||||
import static fr.adrien1106.reframed.block.ReFramedStepBlock.getStepShape;
|
||||
import static fr.adrien1106.reframed.util.blocks.BlockProperties.EDGE;
|
||||
import static fr.adrien1106.reframed.util.blocks.BlockProperties.EDGE_FACE;
|
||||
|
||||
public class ReFramedSlabsStairBlock extends EdgeDoubleReFramedBlock {
|
||||
|
||||
public ReFramedSlabsStairBlock(Settings settings) {
|
||||
super(settings);
|
||||
}
|
||||
|
||||
@Override
|
||||
public VoxelShape getOutlineShape(BlockState state, BlockView world, BlockPos pos, ShapeContext context) {
|
||||
return getStairShape(state.get(EDGE), StairShape.STRAIGHT);
|
||||
}
|
||||
|
||||
@Override
|
||||
public VoxelShape getShape(BlockState state, int i) {
|
||||
Edge edge = state.get(EDGE);
|
||||
Direction face = edge.getDirection(state.get(EDGE_FACE));
|
||||
return i == 2
|
||||
? getStepShape(edge.getOpposite(edge.getOtherDirection(face)))
|
||||
: getSlabShape(face);
|
||||
}
|
||||
}
|
||||
@@ -4,6 +4,8 @@ import fr.adrien1106.reframed.ReFramed;
|
||||
import fr.adrien1106.reframed.util.VoxelHelper;
|
||||
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.minecraft.block.Block;
|
||||
import net.minecraft.block.BlockState;
|
||||
import net.minecraft.block.ShapeContext;
|
||||
@@ -25,6 +27,7 @@ import java.util.Map;
|
||||
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.FACING;
|
||||
import static net.minecraft.state.property.Properties.WATERLOGGED;
|
||||
|
||||
public class ReFramedSmallCubeBlock extends WaterloggableReFramedBlock {
|
||||
@@ -42,63 +45,73 @@ public class ReFramedSmallCubeBlock extends WaterloggableReFramedBlock {
|
||||
}
|
||||
|
||||
@Override
|
||||
@SuppressWarnings("deprecation")
|
||||
public boolean canReplace(BlockState state, ItemPlacementContext context) {
|
||||
if (context.getPlayer() == null
|
||||
|| context.getPlayer().isSneaking()
|
||||
|| !(context.getStack().getItem() instanceof BlockItem block_item)
|
||||
) return false;
|
||||
|
||||
Block block = block_item.getBlock();
|
||||
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())
|
||||
)
|
||||
)
|
||||
)
|
||||
if (block == this)
|
||||
return matchesShape(
|
||||
context.getHitPos(),
|
||||
context.getBlockPos(),
|
||||
getDefaultState().with(CORNER, corner.change(corner.getFirstDirection()))
|
||||
) || matchesShape(
|
||||
context.getHitPos(),
|
||||
context.getBlockPos(),
|
||||
getDefaultState().with(CORNER, corner.change(corner.getSecondDirection()))
|
||||
) || matchesShape(
|
||||
context.getHitPos(),
|
||||
context.getBlockPos(),
|
||||
getDefaultState().with(CORNER, corner.change(corner.getThirdDirection()))
|
||||
);
|
||||
|
||||
if (block == ReFramed.HALF_STAIR || block == ReFramed.SLAB) {
|
||||
corner = corner.getOpposite();
|
||||
Direction face = corner.getFirstDirection();
|
||||
Edge edge = corner.getEdge(face);
|
||||
if (ReFramed.STAIR.matchesShape(
|
||||
context.getHitPos(),
|
||||
context.getBlockPos(),
|
||||
ReFramed.STAIR.getDefaultState()
|
||||
.with(EDGE, edge)
|
||||
.with(
|
||||
STAIR_SHAPE,
|
||||
face.getDirection() == Direction.AxisDirection.POSITIVE
|
||||
? StairShape.INNER_LEFT
|
||||
: StairShape.INNER_RIGHT
|
||||
)
|
||||
&& !(
|
||||
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
|
||||
)
|
||||
)
|
||||
)
|
||||
)
|
||||
);
|
||||
)) return block == ReFramed.SLAB || !matchesShape(
|
||||
context.getHitPos(),
|
||||
context.getBlockPos(),
|
||||
getDefaultState().with(CORNER, corner)
|
||||
);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
@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()
|
||||
|
||||
if (current_state.isOf(ReFramed.HALF_STAIR)) {
|
||||
BlockState new_state;
|
||||
Direction face = current_state.get(CORNER).getDirection(current_state.get(CORNER_FACE));
|
||||
if (matchesShape(
|
||||
ctx.getHitPos(), pos,
|
||||
getDefaultState().with(CORNER, current_state.get(CORNER).change(face))
|
||||
)) new_state = ReFramed.HALF_STAIRS_CUBE_STAIR.getDefaultState();
|
||||
else new_state = ReFramed.HALF_STAIRS_SLAB.getDefaultState();
|
||||
return new_state
|
||||
.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();
|
||||
@@ -119,27 +132,42 @@ public class ReFramedSmallCubeBlock extends WaterloggableReFramedBlock {
|
||||
return state.with(EDGE, corner.getEdge(corner.getThirdDirection()));
|
||||
}
|
||||
|
||||
if (current_state.isOf(ReFramed.SLAB)) {
|
||||
Corner corner = BlockHelper.getPlacementCorner(ctx);
|
||||
Direction face = current_state.get(FACING);
|
||||
if (!corner.hasDirection(face)) corner = corner.change(face.getOpposite());
|
||||
return ReFramed.SLABS_OUTER_STAIR.getDefaultState()
|
||||
.with(CORNER, corner)
|
||||
.with(CORNER_FACE, corner.getDirectionIndex(face))
|
||||
.with(WATERLOGGED, current_state.get(WATERLOGGED));
|
||||
}
|
||||
|
||||
return super.getPlacementState(ctx).with(CORNER, BlockHelper.getPlacementCorner(ctx));
|
||||
}
|
||||
|
||||
@Override
|
||||
@SuppressWarnings("deprecation")
|
||||
public VoxelShape getOutlineShape(BlockState state, BlockView world, BlockPos pos, ShapeContext context) {
|
||||
return SMALL_CUBE_VOXELS[state.get(CORNER).getID()];
|
||||
return getSmallCubeShape(state.get(CORNER));
|
||||
}
|
||||
|
||||
@Override
|
||||
@SuppressWarnings("deprecation")
|
||||
public BlockState rotate(BlockState state, BlockRotation rotation) {
|
||||
return state.with(CORNER, state.get(CORNER).rotate(rotation));
|
||||
}
|
||||
|
||||
@Override
|
||||
@SuppressWarnings("deprecation")
|
||||
public BlockState mirror(BlockState state, BlockMirror mirror) {
|
||||
return state.with(CORNER, state.get(CORNER).mirror(mirror));
|
||||
}
|
||||
|
||||
@Override
|
||||
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.HALF_STAIRS_SLAB)
|
||||
|| new_state.isOf(ReFramed.SLABS_OUTER_STAIR)
|
||||
) return Map.of(1, 2);
|
||||
if (new_state.isOf(ReFramed.SMALL_CUBES_STEP))
|
||||
return Map.of(
|
||||
1,
|
||||
@@ -150,6 +178,10 @@ public class ReFramedSmallCubeBlock extends WaterloggableReFramedBlock {
|
||||
return super.getThemeMap(state, new_state);
|
||||
}
|
||||
|
||||
public static VoxelShape getSmallCubeShape(Corner corner) {
|
||||
return SMALL_CUBE_VOXELS[corner.getID()];
|
||||
}
|
||||
|
||||
static {
|
||||
final VoxelShape SMALL_CUBE = VoxelShapes.cuboid(.5f, 0f, 0f, 1f, .5f, .5f);
|
||||
|
||||
|
||||
@@ -18,7 +18,6 @@ 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 net.minecraft.util.shape.VoxelShapes.empty;
|
||||
|
||||
public class ReFramedSmallCubesStepBlock extends WaterloggableReFramedDoubleBlock {
|
||||
|
||||
@@ -39,21 +38,19 @@ public class ReFramedSmallCubesStepBlock extends WaterloggableReFramedDoubleBloc
|
||||
}
|
||||
|
||||
@Override
|
||||
public VoxelShape getCollisionShape(BlockState state, BlockView view, BlockPos pos, ShapeContext ctx) {
|
||||
return isGhost(view, pos) ? empty(): getStepShape(state.get(EDGE));
|
||||
}
|
||||
|
||||
@Override
|
||||
@SuppressWarnings("deprecation")
|
||||
public VoxelShape getOutlineShape(BlockState state, BlockView world, BlockPos pos, ShapeContext context) {
|
||||
return getStepShape(state.get(EDGE));
|
||||
}
|
||||
|
||||
@Override
|
||||
@SuppressWarnings("deprecation")
|
||||
public BlockState rotate(BlockState state, BlockRotation rotation) {
|
||||
return state.with(EDGE, state.get(EDGE).rotate(rotation));
|
||||
}
|
||||
|
||||
@Override
|
||||
@SuppressWarnings("deprecation")
|
||||
public BlockState mirror(BlockState state, BlockMirror mirror) {
|
||||
return state.with(EDGE, state.get(EDGE).mirror(mirror));
|
||||
}
|
||||
|
||||
@@ -19,7 +19,6 @@ 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;
|
||||
|
||||
@@ -45,13 +44,15 @@ public class ReFramedStairBlock extends WaterloggableReFramedBlock {
|
||||
}
|
||||
|
||||
@Override
|
||||
@SuppressWarnings("deprecation")
|
||||
public boolean canReplace(BlockState state, ItemPlacementContext context) {
|
||||
if (context.getPlayer() == null) return false;
|
||||
return !(
|
||||
context.getPlayer().isSneaking()
|
||||
|| !(context.getStack().getItem() instanceof BlockItem block_item)
|
||||
|| !(
|
||||
block_item.getBlock() == ReFramed.STEP
|
||||
&& ((ReFramedStairsCubeBlock) ReFramed.STAIRS_CUBE)
|
||||
&& ReFramed.STAIRS_CUBE
|
||||
.matchesShape(
|
||||
context.getHitPos(),
|
||||
context.getBlockPos(),
|
||||
@@ -86,18 +87,13 @@ public class ReFramedStairBlock extends WaterloggableReFramedBlock {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onStateReplaced(BlockState state, World world, BlockPos pos, BlockState newState, boolean moved) {
|
||||
super.onStateReplaced(state, world, pos, newState, moved);
|
||||
|
||||
if(!state.isOf(newState.getBlock())) world.removeBlockEntity(pos);
|
||||
}
|
||||
|
||||
@Override
|
||||
@SuppressWarnings("deprecation")
|
||||
public VoxelShape getOutlineShape(BlockState state, BlockView world, BlockPos pos, ShapeContext context) {
|
||||
return getStairShape(state.get(EDGE), state.get(STAIR_SHAPE));
|
||||
}
|
||||
|
||||
@Override
|
||||
@SuppressWarnings("deprecation")
|
||||
public BlockState rotate(BlockState state, BlockRotation rotation) {
|
||||
Edge prev_edge = state.get(EDGE);
|
||||
Edge edge = prev_edge.rotate(rotation);
|
||||
@@ -114,6 +110,7 @@ public class ReFramedStairBlock extends WaterloggableReFramedBlock {
|
||||
}
|
||||
|
||||
@Override
|
||||
@SuppressWarnings("deprecation")
|
||||
public BlockState mirror(BlockState state, BlockMirror mirror) {
|
||||
Edge prev_edge = state.get(EDGE);
|
||||
Edge edge = prev_edge.mirror(mirror);
|
||||
|
||||
@@ -12,7 +12,6 @@ import net.minecraft.util.BlockRotation;
|
||||
import net.minecraft.util.math.BlockPos;
|
||||
import net.minecraft.util.math.Direction;
|
||||
import net.minecraft.util.shape.VoxelShape;
|
||||
import net.minecraft.world.World;
|
||||
import net.minecraft.world.WorldAccess;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
@@ -36,6 +35,7 @@ public class ReFramedStairsCubeBlock extends ReFramedDoubleBlock {
|
||||
}
|
||||
|
||||
@Override
|
||||
@SuppressWarnings("deprecation")
|
||||
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)
|
||||
.with(STAIR_SHAPE, BlockHelper.getStairsShape(state.get(EDGE), world, pos));
|
||||
@@ -52,6 +52,7 @@ public class ReFramedStairsCubeBlock extends ReFramedDoubleBlock {
|
||||
|
||||
|
||||
@Override
|
||||
@SuppressWarnings("deprecation")
|
||||
public BlockState rotate(BlockState state, BlockRotation rotation) {
|
||||
Edge prev_edge = state.get(EDGE);
|
||||
Edge edge = prev_edge.rotate(rotation);
|
||||
@@ -68,6 +69,7 @@ public class ReFramedStairsCubeBlock extends ReFramedDoubleBlock {
|
||||
}
|
||||
|
||||
@Override
|
||||
@SuppressWarnings("deprecation")
|
||||
public BlockState mirror(BlockState state, BlockMirror mirror) {
|
||||
Edge prev_edge = state.get(EDGE);
|
||||
Edge edge = prev_edge.mirror(mirror);
|
||||
@@ -76,13 +78,6 @@ public class ReFramedStairsCubeBlock extends ReFramedDoubleBlock {
|
||||
.with(EDGE, edge);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onStateReplaced(BlockState state, World world, BlockPos pos, BlockState newState, boolean moved) {
|
||||
super.onStateReplaced(state, world, pos, newState, moved);
|
||||
|
||||
if(!state.isOf(newState.getBlock())) world.removeBlockEntity(pos);
|
||||
}
|
||||
|
||||
@Override
|
||||
public VoxelShape getShape(BlockState state, int i) {
|
||||
Edge edge = state.get(EDGE);
|
||||
|
||||
@@ -3,6 +3,7 @@ package fr.adrien1106.reframed.block;
|
||||
import fr.adrien1106.reframed.ReFramed;
|
||||
import fr.adrien1106.reframed.util.VoxelHelper;
|
||||
import fr.adrien1106.reframed.util.blocks.BlockHelper;
|
||||
import fr.adrien1106.reframed.util.blocks.Corner;
|
||||
import fr.adrien1106.reframed.util.blocks.Edge;
|
||||
import net.minecraft.block.Block;
|
||||
import net.minecraft.block.BlockState;
|
||||
@@ -22,10 +23,9 @@ 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.BlockProperties.*;
|
||||
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 {
|
||||
|
||||
@@ -42,48 +42,38 @@ public class ReFramedStepBlock extends WaterloggableReFramedBlock {
|
||||
}
|
||||
|
||||
@Override
|
||||
@SuppressWarnings("deprecation")
|
||||
public boolean canReplace(BlockState state, ItemPlacementContext context) {
|
||||
Edge edge = state.get(EDGE);
|
||||
return !(
|
||||
context.getPlayer().isSneaking()
|
||||
if (context.getPlayer() == null
|
||||
|| 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
|
||||
)
|
||||
) return false;
|
||||
|
||||
)
|
||||
&& !(
|
||||
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
|
||||
)
|
||||
)
|
||||
)
|
||||
)
|
||||
);
|
||||
Block block = block_item.getBlock();
|
||||
Edge edge = state.get(EDGE);
|
||||
if (block == ReFramed.HALF_LAYER)
|
||||
return matchesShape(
|
||||
context.getHitPos(),
|
||||
context.getBlockPos(),
|
||||
getDefaultState().with(EDGE, edge.getOpposite(edge.getFirstDirection()))
|
||||
) || matchesShape(
|
||||
context.getHitPos(),
|
||||
context.getBlockPos(),
|
||||
getDefaultState().with(EDGE, edge.getOpposite(edge.getSecondDirection()))
|
||||
);
|
||||
|
||||
// allow replacing with stair
|
||||
if (block != this
|
||||
&& block != ReFramed.STAIR
|
||||
&& block != ReFramed.SLAB
|
||||
) return false;
|
||||
|
||||
return ReFramed.STAIR
|
||||
.matchesShape(
|
||||
context.getHitPos(),
|
||||
context.getBlockPos(),
|
||||
ReFramed.STAIRS_CUBE.getDefaultState().with(EDGE, edge.opposite())
|
||||
);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@@ -91,6 +81,7 @@ public class ReFramedStepBlock extends WaterloggableReFramedBlock {
|
||||
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))
|
||||
@@ -100,39 +91,91 @@ public class ReFramedStepBlock extends WaterloggableReFramedBlock {
|
||||
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())
|
||||
|
||||
// Steps Slab
|
||||
if (matchesShape(hit, pos,
|
||||
current_state.with(EDGE, edge.getOpposite(edge.getFirstDirection()))
|
||||
)) return ReFramed.STEPS_SLAB.getDefaultState()
|
||||
.with(FACING, edge.getFirstDirection())
|
||||
.with(AXIS, edge.getSecondDirection().getAxis())
|
||||
.with(WATERLOGGED, current_state.get(WATERLOGGED));
|
||||
|
||||
else if (matchesShape(hit, pos,
|
||||
current_state.with(EDGE, edge.getOpposite(edge.getSecondDirection()))
|
||||
)) return ReFramed.STEPS_SLAB.getDefaultState()
|
||||
.with(FACING, edge.getSecondDirection())
|
||||
.with(AXIS, edge.getFirstDirection().getAxis())
|
||||
.with(WATERLOGGED, current_state.get(WATERLOGGED));
|
||||
|
||||
// Steps Cross
|
||||
return ReFramed.STEPS_CROSS.getDefaultState()
|
||||
.with(EDGE, edge)
|
||||
.with(WATERLOGGED, current_state.get(WATERLOGGED));
|
||||
}
|
||||
|
||||
if (current_state.isOf(ReFramed.SLAB)) {
|
||||
Direction facing = current_state.get(FACING);
|
||||
Edge edge;
|
||||
|
||||
// Slabs Stair
|
||||
if (ctx.getSide() == facing || ctx.getSide() == facing.getOpposite())
|
||||
edge = BlockHelper.getPlacementEdge(ctx);
|
||||
else
|
||||
edge = Edge.getByDirections(facing, ctx.getSide().getOpposite());
|
||||
return ReFramed.SLABS_STAIR.getDefaultState()
|
||||
.with(EDGE, edge)
|
||||
.with(EDGE_FACE, edge.getDirectionIndex(facing));
|
||||
|
||||
}
|
||||
|
||||
if (current_state.isOf(ReFramed.HALF_STAIR)) {
|
||||
Corner corner = current_state.get(CORNER);
|
||||
int face_index = current_state.get(CORNER_FACE), feature_index;
|
||||
Direction face = corner.getDirection(current_state.get(CORNER_FACE));
|
||||
Direction side = ctx.getSide().getOpposite();
|
||||
|
||||
if (side.getAxis() == face.getAxis())
|
||||
side = BlockHelper.getPlacementEdge(ctx).getOtherDirection(face == side ? face : face.getOpposite());
|
||||
|
||||
if (side.getAxis() != face.getAxis() && !corner.hasDirection(side))
|
||||
side = corner.getOtherDirection(Edge.getByDirections(face, side.getOpposite()));
|
||||
|
||||
feature_index = corner.getDirectionIndex(side);
|
||||
return ReFramed.HALF_STAIRS_STEP_STAIR.getDefaultState()
|
||||
.with(CORNER, corner)
|
||||
.with(CORNER_FACE, face_index)
|
||||
.with(CORNER_FEATURE, feature_index > face_index ? feature_index - 1 : feature_index)
|
||||
.with(WATERLOGGED, current_state.get(WATERLOGGED));
|
||||
}
|
||||
|
||||
if (current_state.isOf(ReFramed.HALF_LAYER)) {
|
||||
Edge edge = current_state.get(EDGE);
|
||||
Direction face = edge.getDirection(current_state.get(EDGE_FACE));
|
||||
edge = edge.getOpposite(face);
|
||||
return ReFramed.STEPS_HALF_LAYER.getDefaultState()
|
||||
.with(EDGE, edge)
|
||||
.with(EDGE_FACE, edge.getDirectionIndex(edge.getOtherDirection(face)))
|
||||
.with(LAYERS, current_state.get(LAYERS))
|
||||
.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));
|
||||
}
|
||||
|
||||
@Override
|
||||
@SuppressWarnings("deprecation")
|
||||
public VoxelShape getOutlineShape(BlockState state, BlockView world, BlockPos pos, ShapeContext context) {
|
||||
return getStepShape(state.get(EDGE));
|
||||
}
|
||||
|
||||
@Override
|
||||
@SuppressWarnings("deprecation")
|
||||
public BlockState rotate(BlockState state, BlockRotation rotation) {
|
||||
return state.with(EDGE, state.get(EDGE).rotate(rotation));
|
||||
}
|
||||
|
||||
@Override
|
||||
@SuppressWarnings("deprecation")
|
||||
public BlockState mirror(BlockState state, BlockMirror mirror) {
|
||||
return state.with(EDGE, state.get(EDGE).mirror(mirror));
|
||||
}
|
||||
@@ -143,7 +186,11 @@ public class ReFramedStepBlock extends WaterloggableReFramedBlock {
|
||||
|
||||
@Override
|
||||
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_CROSS)
|
||||
|| new_state.isOf(ReFramed.STEPS_HALF_LAYER)
|
||||
) return Map.of(1, 1);
|
||||
if (new_state.isOf(ReFramed.STAIRS_CUBE)
|
||||
|| new_state.isOf(ReFramed.SLABS_STAIR)) return Map.of(1, 2);
|
||||
if (new_state.isOf(ReFramed.STEPS_SLAB))
|
||||
return Map.of(
|
||||
1,
|
||||
|
||||
@@ -0,0 +1,86 @@
|
||||
package fr.adrien1106.reframed.block;
|
||||
|
||||
import fr.adrien1106.reframed.util.VoxelHelper;
|
||||
import fr.adrien1106.reframed.util.blocks.BlockHelper;
|
||||
import fr.adrien1106.reframed.util.blocks.Edge;
|
||||
import net.minecraft.block.Block;
|
||||
import net.minecraft.block.BlockState;
|
||||
import net.minecraft.block.ShapeContext;
|
||||
import net.minecraft.item.ItemPlacementContext;
|
||||
import net.minecraft.state.StateManager;
|
||||
import net.minecraft.util.BlockMirror;
|
||||
import net.minecraft.util.BlockRotation;
|
||||
import net.minecraft.util.function.BooleanBiFunction;
|
||||
import net.minecraft.util.math.BlockPos;
|
||||
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.block.ReFramedStepBlock.getStepShape;
|
||||
import static fr.adrien1106.reframed.util.blocks.BlockProperties.EDGE;
|
||||
|
||||
public class ReFramedStepsCrossBlock extends WaterloggableReFramedDoubleBlock {
|
||||
|
||||
public static VoxelShape[] STEP_CROSS_VOXELS;
|
||||
|
||||
public ReFramedStepsCrossBlock(Settings settings) {
|
||||
super(settings);
|
||||
setDefaultState(getDefaultState().with(EDGE, Edge.NORTH_DOWN));
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void appendProperties(StateManager.Builder<Block, BlockState> builder) {
|
||||
super.appendProperties(builder.add(EDGE));
|
||||
}
|
||||
|
||||
@Override
|
||||
public @Nullable BlockState getPlacementState(ItemPlacementContext ctx) {
|
||||
Edge edge = BlockHelper.getPlacementCorner(ctx).getEdge(ctx.getSide().getOpposite());
|
||||
return super.getPlacementState(ctx).with(EDGE, edge);
|
||||
}
|
||||
|
||||
@Override
|
||||
@SuppressWarnings("deprecation")
|
||||
public VoxelShape getOutlineShape(BlockState state, BlockView world, BlockPos pos, ShapeContext context) {
|
||||
return STEP_CROSS_VOXELS[state.get(EDGE).ordinal()];
|
||||
}
|
||||
|
||||
@Override
|
||||
@SuppressWarnings("deprecation")
|
||||
public BlockState rotate(BlockState state, BlockRotation rotation) {
|
||||
return state.with(EDGE, state.get(EDGE).rotate(rotation));
|
||||
}
|
||||
|
||||
@Override
|
||||
@SuppressWarnings("deprecation")
|
||||
public BlockState mirror(BlockState state, BlockMirror mirror) {
|
||||
return state.with(EDGE, state.get(EDGE).mirror(mirror));
|
||||
}
|
||||
|
||||
@Override
|
||||
public VoxelShape getShape(BlockState state, int i) {
|
||||
return getStepShape(i == 1 ? state.get(EDGE): state.get(EDGE).opposite());
|
||||
}
|
||||
|
||||
static {
|
||||
VoxelShape STEP_CROSS = VoxelShapes.combineAndSimplify(
|
||||
getStepShape(Edge.NORTH_DOWN),
|
||||
getStepShape(Edge.SOUTH_UP),
|
||||
BooleanBiFunction.OR
|
||||
);
|
||||
STEP_CROSS_VOXELS = VoxelHelper.VoxelListBuilder.create(STEP_CROSS, 12)
|
||||
.add(VoxelHelper::rotateX)
|
||||
.add(VoxelHelper::rotateX)
|
||||
.add(VoxelHelper::rotateX)
|
||||
.add(0, VoxelHelper::rotateCY)
|
||||
.add(VoxelHelper::rotateZ)
|
||||
.add(VoxelHelper::rotateZ)
|
||||
.add(VoxelHelper::rotateZ)
|
||||
.add(0, VoxelHelper::rotateCZ)
|
||||
.add(VoxelHelper::rotateY)
|
||||
.add(VoxelHelper::rotateY)
|
||||
.add(VoxelHelper::rotateY)
|
||||
.build();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,62 @@
|
||||
package fr.adrien1106.reframed.block;
|
||||
|
||||
import fr.adrien1106.reframed.util.blocks.Edge;
|
||||
import net.minecraft.block.BlockState;
|
||||
import net.minecraft.block.ShapeContext;
|
||||
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 static fr.adrien1106.reframed.block.ReFramedHalfLayerBlock.getHalfLayerShape;
|
||||
import static fr.adrien1106.reframed.block.ReFramedStepBlock.getStepShape;
|
||||
import static fr.adrien1106.reframed.util.blocks.BlockProperties.EDGE;
|
||||
import static fr.adrien1106.reframed.util.blocks.BlockProperties.EDGE_FACE;
|
||||
import static net.minecraft.state.property.Properties.LAYERS;
|
||||
|
||||
public class ReFramedStepsHalfLayerBlock extends HalfLayerDoubleReFramedBlock {
|
||||
|
||||
private static final VoxelShape[] SLABS_HALF_LAYER_VOXELS = new VoxelShape[196];
|
||||
|
||||
public ReFramedStepsHalfLayerBlock(Settings settings) {
|
||||
super(settings);
|
||||
}
|
||||
|
||||
@Override
|
||||
public VoxelShape getOutlineShape(BlockState state, BlockView world, BlockPos pos, ShapeContext context) {
|
||||
return getStepsHalfLayerShape(state.get(EDGE), state.get(EDGE_FACE), state.get(LAYERS));
|
||||
}
|
||||
|
||||
public static VoxelShape getStepsHalfLayerShape(Edge edge, int face, int layers) {
|
||||
int i = edge.ordinal() * 16 + face * 8 + layers - 1;
|
||||
VoxelShape shape = SLABS_HALF_LAYER_VOXELS[i];
|
||||
if (shape == null) {
|
||||
shape = VoxelShapes.combineAndSimplify(
|
||||
getShape(edge, edge.getDirection(face), layers, 1),
|
||||
getShape(edge, edge.getDirection(face), layers, 2),
|
||||
BooleanBiFunction.OR
|
||||
);
|
||||
SLABS_HALF_LAYER_VOXELS[i] = shape;
|
||||
}
|
||||
return shape;
|
||||
}
|
||||
|
||||
@Override
|
||||
public VoxelShape getShape(BlockState state, int i) {
|
||||
Edge edge = state.get(EDGE);
|
||||
Direction face = edge.getDirection(state.get(EDGE_FACE));
|
||||
return getShape(edge, face, state.get(LAYERS), i);
|
||||
}
|
||||
|
||||
private static VoxelShape getShape(Edge edge, Direction face, int layers, int i) {
|
||||
if (i == 2) {
|
||||
face = edge.getOtherDirection(face);
|
||||
edge = edge.getOpposite(face);
|
||||
}
|
||||
return i == 2
|
||||
? getHalfLayerShape(edge, edge.getDirectionIndex(face), layers)
|
||||
: getStepShape(edge);
|
||||
}
|
||||
}
|
||||
@@ -21,7 +21,6 @@ import static fr.adrien1106.reframed.block.ReFramedSlabBlock.getSlabShape;
|
||||
import static fr.adrien1106.reframed.block.ReFramedStepBlock.getStepShape;
|
||||
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 {
|
||||
|
||||
@@ -44,16 +43,13 @@ public class ReFramedStepsSlabBlock extends WaterloggableReFramedDoubleBlock {
|
||||
}
|
||||
|
||||
@Override
|
||||
public VoxelShape getCollisionShape(BlockState state, BlockView view, BlockPos pos, ShapeContext ctx) {
|
||||
return isGhost(view, pos) ? empty() : getSlabShape(state.get(FACING));
|
||||
}
|
||||
|
||||
@Override
|
||||
@SuppressWarnings("deprecation")
|
||||
public VoxelShape getOutlineShape(BlockState state, BlockView world, BlockPos pos, ShapeContext context) {
|
||||
return getSlabShape(state.get(FACING));
|
||||
}
|
||||
|
||||
@Override
|
||||
@SuppressWarnings("deprecation")
|
||||
public BlockState rotate(BlockState state, BlockRotation rotation) {
|
||||
return state
|
||||
.with(AXIS, rotation.rotate(Direction.get(Direction.AxisDirection.POSITIVE, state.get(AXIS))).getAxis())
|
||||
@@ -61,6 +57,7 @@ public class ReFramedStepsSlabBlock extends WaterloggableReFramedDoubleBlock {
|
||||
}
|
||||
|
||||
@Override
|
||||
@SuppressWarnings("deprecation")
|
||||
public BlockState mirror(BlockState state, BlockMirror mirror) {
|
||||
if (state.get(FACING).getAxis() != Axis.Y)
|
||||
return state.with(FACING, mirror.apply(state.get(FACING)));
|
||||
|
||||
@@ -48,6 +48,7 @@ public class ReFramedTrapdoorBlock extends WaterloggableReFramedBlock {
|
||||
}
|
||||
|
||||
@Override
|
||||
@SuppressWarnings("deprecation")
|
||||
public void neighborUpdate(BlockState state, World world, BlockPos pos, Block source, BlockPos sourcePos, boolean notify) {
|
||||
if (world.isClient) return;
|
||||
boolean powered = world.isReceivingRedstonePower(pos);
|
||||
@@ -83,13 +84,6 @@ public class ReFramedTrapdoorBlock extends WaterloggableReFramedBlock {
|
||||
return state;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onStateReplaced(BlockState state, World world, BlockPos pos, BlockState newState, boolean moved) {
|
||||
super.onStateReplaced(state, world, pos, newState, moved);
|
||||
|
||||
if(!state.isOf(newState.getBlock())) world.removeBlockEntity(pos);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ActionResult onUse(BlockState state, World world, BlockPos pos, PlayerEntity player, Hand hand, BlockHitResult hit) {
|
||||
ActionResult result = super.onUse(state, world, pos, player, hand, hit);
|
||||
@@ -99,6 +93,7 @@ public class ReFramedTrapdoorBlock extends WaterloggableReFramedBlock {
|
||||
}
|
||||
|
||||
@Override
|
||||
@SuppressWarnings("deprecation")
|
||||
public boolean canPathfindThrough(BlockState state, BlockView world, BlockPos pos, NavigationType type) {
|
||||
return switch (type) {
|
||||
case LAND, AIR -> state.get(OPEN);
|
||||
@@ -107,6 +102,7 @@ public class ReFramedTrapdoorBlock extends WaterloggableReFramedBlock {
|
||||
}
|
||||
|
||||
@Override
|
||||
@SuppressWarnings("deprecation")
|
||||
public void onExploded(BlockState state, World world, BlockPos pos, Explosion explosion, BiConsumer<ItemStack, BlockPos> stack_merger) {
|
||||
if (explosion.getDestructionType() == Explosion.DestructionType.TRIGGER_BLOCK
|
||||
&& !world.isClient()
|
||||
@@ -129,6 +125,7 @@ public class ReFramedTrapdoorBlock extends WaterloggableReFramedBlock {
|
||||
}
|
||||
|
||||
@Override
|
||||
@SuppressWarnings("deprecation")
|
||||
public VoxelShape getOutlineShape(BlockState state, BlockView world, BlockPos pos, ShapeContext context) {
|
||||
int index;
|
||||
if (!state.get(OPEN)) index = state.get(BLOCK_HALF) == BlockHalf.BOTTOM ? 0 : 1;
|
||||
@@ -137,11 +134,13 @@ public class ReFramedTrapdoorBlock extends WaterloggableReFramedBlock {
|
||||
}
|
||||
|
||||
@Override
|
||||
@SuppressWarnings("deprecation")
|
||||
public BlockState rotate(BlockState state, BlockRotation rotation) {
|
||||
return state.with(HORIZONTAL_FACING, rotation.rotate(state.get(HORIZONTAL_FACING)));
|
||||
}
|
||||
|
||||
@Override
|
||||
@SuppressWarnings("deprecation")
|
||||
public BlockState mirror(BlockState state, BlockMirror mirror) {
|
||||
return state.with(HORIZONTAL_FACING, mirror.apply(state.get(HORIZONTAL_FACING)));
|
||||
}
|
||||
|
||||
@@ -80,13 +80,7 @@ public class ReFramedWallBlock extends WaterloggableReFramedBlock {
|
||||
}
|
||||
|
||||
@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
|
||||
@SuppressWarnings("deprecation")
|
||||
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) {
|
||||
@@ -109,6 +103,7 @@ public class ReFramedWallBlock extends WaterloggableReFramedBlock {
|
||||
}
|
||||
|
||||
@Override
|
||||
@SuppressWarnings("deprecation")
|
||||
public BlockState rotate(BlockState state, BlockRotation rotation) {
|
||||
return Direction.Type.HORIZONTAL.stream().reduce(state, (s, dir) ->
|
||||
s.with(getWallShape(rotation.rotate(dir)), state.get(getWallShape(dir)))
|
||||
@@ -116,6 +111,7 @@ public class ReFramedWallBlock extends WaterloggableReFramedBlock {
|
||||
}
|
||||
|
||||
@Override
|
||||
@SuppressWarnings("deprecation")
|
||||
public BlockState mirror(BlockState state, BlockMirror mirror) {
|
||||
return Direction.Type.HORIZONTAL.stream().reduce(state, (s, dir) ->
|
||||
s.with(getWallShape(mirror.apply(dir)), state.get(getWallShape(dir)))
|
||||
|
||||
@@ -23,7 +23,13 @@ public class WaterloggableReFramedBlock extends ReFramedBlock implements Waterlo
|
||||
protected void appendProperties(StateManager.Builder<Block, BlockState> builder) {
|
||||
super.appendProperties(builder.add(Properties.WATERLOGGED));
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
@SuppressWarnings("deprecation")
|
||||
public boolean hasSidedTransparency(BlockState state) {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public BlockState getPlacementState(ItemPlacementContext ctx) {
|
||||
@@ -33,10 +39,13 @@ public class WaterloggableReFramedBlock extends ReFramedBlock implements Waterlo
|
||||
}
|
||||
|
||||
@Override
|
||||
@SuppressWarnings("deprecation")
|
||||
public FluidState getFluidState(BlockState state) {
|
||||
return state.get(Properties.WATERLOGGED) ? Fluids.WATER.getStill(false) : super.getFluidState(state);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
@SuppressWarnings("deprecation")
|
||||
public BlockState getStateForNeighborUpdate(BlockState state, Direction direction, BlockState otherState, WorldAccess world, BlockPos pos, BlockPos moved) {
|
||||
if(state.get(Properties.WATERLOGGED)) world.scheduleFluidTick(pos, Fluids.WATER, Fluids.WATER.getTickRate(world));
|
||||
return super.getStateForNeighborUpdate(state, direction, otherState, world, pos, moved);
|
||||
|
||||
@@ -33,10 +33,13 @@ public class WaterloggableReFramedDoubleBlock extends ReFramedDoubleBlock implem
|
||||
}
|
||||
|
||||
@Override
|
||||
@SuppressWarnings("deprecation")
|
||||
public FluidState getFluidState(BlockState state) {
|
||||
return state.get(Properties.WATERLOGGED) ? Fluids.WATER.getStill(false) : super.getFluidState(state);
|
||||
}
|
||||
|
||||
@Override
|
||||
@SuppressWarnings("deprecation")
|
||||
public BlockState getStateForNeighborUpdate(BlockState state, Direction direction, BlockState otherState, WorldAccess world, BlockPos pos, BlockPos moved) {
|
||||
if(state.get(Properties.WATERLOGGED)) world.scheduleFluidTick(pos, Fluids.WATER, Fluids.WATER.getTickRate(world));
|
||||
return super.getStateForNeighborUpdate(state, direction, otherState, world, pos, moved);
|
||||
|
||||
@@ -27,131 +27,231 @@ public class ReFramedClient implements ClientModInitializer {
|
||||
BlockRenderLayerMap.INSTANCE.putBlocks(RenderLayer.getCutout(), ReFramed.BLOCKS.toArray(new Block[0]));
|
||||
|
||||
// CUBE
|
||||
HELPER.addReFramedModel("cube" , HELPER.auto(new Identifier("block/cube")));
|
||||
HELPER.addReFramedModel("cube" , HELPER.auto(new Identifier("block/cube")));
|
||||
// SMALL_CUBE
|
||||
HELPER.addReFramedModel("small_cube" , HELPER.auto(ReFramed.id("block/small_cube/base")));
|
||||
HELPER.addReFramedModel("small_cube" , HELPER.auto(ReFramed.id("block/small_cube/base")));
|
||||
// SMALL_CUBES_STEP
|
||||
HELPER.addReFramedModel("small_cubes_step" , HELPER.autoDouble(ReFramed.id("block/small_cube/base"), ReFramed.id("block/small_cube/step/base")));
|
||||
HELPER.addReFramedModel("small_cubes_step_reverse" , 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")));
|
||||
HELPER.addReFramedModel("small_cubes_step_reverse" , HELPER.autoDouble(ReFramed.id("block/small_cube/step/base"), ReFramed.id("block/small_cube/base")));
|
||||
// SLAB
|
||||
HELPER.addReFramedModel("slab" , HELPER.auto(new Identifier("block/slab")));
|
||||
HELPER.addReFramedModel("slab" , HELPER.auto(new Identifier("block/slab")));
|
||||
// SLAB_CUBE
|
||||
HELPER.addReFramedModel("double_slab" , 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")));
|
||||
// STAIR
|
||||
HELPER.addReFramedModel("stair" , HELPER.auto(ReFramed.id("block/stair/straight")));
|
||||
HELPER.addReFramedModel("outers_stair" , HELPER.auto(ReFramed.id("block/stair/double_outer")));
|
||||
HELPER.addReFramedModel("inner_stair" , HELPER.auto(ReFramed.id("block/stair/inner")));
|
||||
HELPER.addReFramedModel("outer_stair" , HELPER.auto(ReFramed.id("block/stair/outer")));
|
||||
HELPER.addReFramedModel("outer_side_stair" , HELPER.auto(ReFramed.id("block/stair/outer_side")));
|
||||
HELPER.addReFramedModel("stair" , HELPER.auto(ReFramed.id("block/stair/straight")));
|
||||
HELPER.addReFramedModel("outers_stair" , HELPER.auto(ReFramed.id("block/stair/double_outer")));
|
||||
HELPER.addReFramedModel("inner_stair" , HELPER.auto(ReFramed.id("block/stair/inner")));
|
||||
HELPER.addReFramedModel("outer_stair" , HELPER.auto(ReFramed.id("block/stair/outer")));
|
||||
HELPER.addReFramedModel("outer_side_stair" , HELPER.auto(ReFramed.id("block/stair/outer_side")));
|
||||
// STAIRS_CUBE
|
||||
HELPER.addReFramedModel("stairs_cube" , HELPER.autoDouble(ReFramed.id("block/stair/straight"), ReFramed.id("block/stair/cube/straight")));
|
||||
HELPER.addReFramedModel("outers_stairs_cube" , HELPER.autoDouble(ReFramed.id("block/stair/double_outer"), ReFramed.id("block/stair/cube/double_outer")));
|
||||
HELPER.addReFramedModel("inner_stairs_cube" , HELPER.autoDouble(ReFramed.id("block/stair/inner"), ReFramed.id("block/stair/cube/inner")));
|
||||
HELPER.addReFramedModel("outer_stairs_cube" , HELPER.autoDouble(ReFramed.id("block/stair/outer"), ReFramed.id("block/stair/cube/outer")));
|
||||
HELPER.addReFramedModel("outer_side_stairs_cube" , 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")));
|
||||
HELPER.addReFramedModel("outers_stairs_cube" , HELPER.autoDouble(ReFramed.id("block/stair/double_outer"), ReFramed.id("block/stair/cube/double_outer")));
|
||||
HELPER.addReFramedModel("inner_stairs_cube" , HELPER.autoDouble(ReFramed.id("block/stair/inner"), ReFramed.id("block/stair/cube/inner")));
|
||||
HELPER.addReFramedModel("outer_stairs_cube" , HELPER.autoDouble(ReFramed.id("block/stair/outer"), ReFramed.id("block/stair/cube/outer")));
|
||||
HELPER.addReFramedModel("outer_side_stairs_cube" , HELPER.autoDouble(ReFramed.id("block/stair/outer_side"), ReFramed.id("block/stair/cube/outer_side")));
|
||||
// HALF_STAIR
|
||||
HELPER.addReFramedModel("half_stair_down" , HELPER.auto(ReFramed.id("block/half_stair/down")));
|
||||
HELPER.addReFramedModel("half_stair_side" , HELPER.auto(ReFramed.id("block/half_stair/side")));
|
||||
HELPER.addReFramedModel("half_stair_down" , HELPER.auto(ReFramed.id("block/half_stair/down")));
|
||||
HELPER.addReFramedModel("half_stair_side" , HELPER.auto(ReFramed.id("block/half_stair/side")));
|
||||
// HALF_STAIRS_SLAB
|
||||
HELPER.addReFramedModel("half_stairs_slab_down" , HELPER.autoDouble(ReFramed.id("block/half_stair/down"), ReFramed.id("block/half_stair/slab/down")));
|
||||
HELPER.addReFramedModel("half_stairs_slab_side" , 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")));
|
||||
HELPER.addReFramedModel("half_stairs_slab_side" , HELPER.autoDouble(ReFramed.id("block/half_stair/side"), ReFramed.id("block/half_stair/slab/side")));
|
||||
// HALF_STAIRS_STAIR
|
||||
HELPER.addReFramedModel("half_stairs_stair_down" , HELPER.autoDouble(ReFramed.id("block/half_stair/down"), ReFramed.id("block/half_stair/stair/down")));
|
||||
HELPER.addReFramedModel("half_stairs_stair_side" , HELPER.autoDouble(ReFramed.id("block/half_stair/side"), ReFramed.id("block/half_stair/stair/side")));
|
||||
HELPER.addReFramedModel("half_stairs_stair_reverse" , 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")));
|
||||
HELPER.addReFramedModel("half_stairs_stair_side" , HELPER.autoDouble(ReFramed.id("block/half_stair/side"), ReFramed.id("block/half_stair/stair/side")));
|
||||
HELPER.addReFramedModel("half_stairs_stair_reverse" , HELPER.autoDouble(ReFramed.id("block/half_stair/stair/side"), ReFramed.id("block/half_stair/side")));
|
||||
// STEP
|
||||
HELPER.addReFramedModel("step" , HELPER.auto(ReFramed.id("block/step/down")));
|
||||
HELPER.addReFramedModel("step" , HELPER.auto(ReFramed.id("block/step/down")));
|
||||
// STEPS_SLAB
|
||||
HELPER.addReFramedModel("steps_slab" , HELPER.autoDouble(ReFramed.id("block/step/down"), ReFramed.id("block/step/slab/down")));
|
||||
HELPER.addReFramedModel("steps_slab_side" , 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")));
|
||||
HELPER.addReFramedModel("steps_slab_side" , HELPER.autoDouble(ReFramed.id("block/step/side"), ReFramed.id("block/step/slab/side")));
|
||||
// LAYER
|
||||
HELPER.addReFramedModel("layer_1" , HELPER.auto(new Identifier("block/snow_height2")));
|
||||
HELPER.addReFramedModel("layer_2" , HELPER.auto(new Identifier("block/snow_height4")));
|
||||
HELPER.addReFramedModel("layer_3" , HELPER.auto(new Identifier("block/snow_height6")));
|
||||
HELPER.addReFramedModel("layer_4" , HELPER.auto(new Identifier("block/snow_height8")));
|
||||
HELPER.addReFramedModel("layer_5" , HELPER.auto(new Identifier("block/snow_height10")));
|
||||
HELPER.addReFramedModel("layer_6" , HELPER.auto(new Identifier("block/snow_height12")));
|
||||
HELPER.addReFramedModel("layer_7" , HELPER.auto(new Identifier("block/snow_height14")));
|
||||
HELPER.addReFramedModel("layer_8" , HELPER.auto(new Identifier("block/cube")));
|
||||
HELPER.addReFramedModel("layer_1" , HELPER.auto(new Identifier("block/snow_height2")));
|
||||
HELPER.addReFramedModel("layer_2" , HELPER.auto(new Identifier("block/snow_height4")));
|
||||
HELPER.addReFramedModel("layer_3" , HELPER.auto(new Identifier("block/snow_height6")));
|
||||
HELPER.addReFramedModel("layer_4" , HELPER.auto(new Identifier("block/snow_height8")));
|
||||
HELPER.addReFramedModel("layer_5" , HELPER.auto(new Identifier("block/snow_height10")));
|
||||
HELPER.addReFramedModel("layer_6" , HELPER.auto(new Identifier("block/snow_height12")));
|
||||
HELPER.addReFramedModel("layer_7" , HELPER.auto(new Identifier("block/snow_height14")));
|
||||
HELPER.addReFramedModel("layer_8" , HELPER.auto(new Identifier("block/cube")));
|
||||
// PILLAR
|
||||
HELPER.addReFramedModel("pillar" , HELPER.auto(ReFramed.id("block/pillar")));
|
||||
HELPER.addReFramedModel("pillar" , HELPER.auto(ReFramed.id("block/pillar")));
|
||||
// WALL
|
||||
HELPER.addReFramedModel("wall_inventory" , HELPER.auto(ReFramed.id("block/wall/inventory/default")));
|
||||
HELPER.addReFramedModel("wall_inventory" , HELPER.auto(ReFramed.id("block/wall/inventory/default")));
|
||||
// --------------------- pillar
|
||||
HELPER.addReFramedModel("wall_core" , HELPER.auto(ReFramed.id("block/wall/pillar/core")));
|
||||
HELPER.addReFramedModel("wall_pillar_low" , HELPER.auto(ReFramed.id("block/wall/pillar/low")));
|
||||
HELPER.addReFramedModel("wall_pillar_tall" , HELPER.auto(ReFramed.id("block/wall/pillar/tall")));
|
||||
HELPER.addReFramedModel("wall_pillar_none" , HELPER.auto(ReFramed.id("block/wall/pillar/none")));
|
||||
HELPER.addReFramedModel("wall_core" , HELPER.auto(ReFramed.id("block/wall/pillar/core")));
|
||||
HELPER.addReFramedModel("wall_pillar_low" , HELPER.auto(ReFramed.id("block/wall/pillar/low")));
|
||||
HELPER.addReFramedModel("wall_pillar_tall" , HELPER.auto(ReFramed.id("block/wall/pillar/tall")));
|
||||
HELPER.addReFramedModel("wall_pillar_none" , HELPER.auto(ReFramed.id("block/wall/pillar/none")));
|
||||
// --------------------- side
|
||||
HELPER.addReFramedModel("wall_side_low" , HELPER.auto(ReFramed.id("block/wall/side/low")));
|
||||
HELPER.addReFramedModel("wall_side_tall" , HELPER.auto(ReFramed.id("block/wall/side/tall")));
|
||||
HELPER.addReFramedModel("wall_side_low" , HELPER.auto(ReFramed.id("block/wall/side/low")));
|
||||
HELPER.addReFramedModel("wall_side_tall" , HELPER.auto(ReFramed.id("block/wall/side/tall")));
|
||||
// --------------------- junction
|
||||
HELPER.addReFramedModel("wall_low_e" , HELPER.auto(ReFramed.id("block/wall/junction/low")));
|
||||
HELPER.addReFramedModel("wall_tall_e" , HELPER.auto(ReFramed.id("block/wall/junction/tall")));
|
||||
HELPER.addReFramedModel("wall_low_e" , HELPER.auto(ReFramed.id("block/wall/junction/low")));
|
||||
HELPER.addReFramedModel("wall_tall_e" , HELPER.auto(ReFramed.id("block/wall/junction/tall")));
|
||||
// --------------------- junction_i
|
||||
HELPER.addReFramedModel("wall_low_i" , HELPER.auto(ReFramed.id("block/wall/junction/low_i")));
|
||||
HELPER.addReFramedModel("wall_tall_i" , HELPER.auto(ReFramed.id("block/wall/junction/tall_i")));
|
||||
HELPER.addReFramedModel("wall_low_tall_i" , HELPER.auto(ReFramed.id("block/wall/junction/low_tall_i")));
|
||||
HELPER.addReFramedModel("wall_low_i" , HELPER.auto(ReFramed.id("block/wall/junction/low_i")));
|
||||
HELPER.addReFramedModel("wall_tall_i" , HELPER.auto(ReFramed.id("block/wall/junction/tall_i")));
|
||||
HELPER.addReFramedModel("wall_low_tall_i" , HELPER.auto(ReFramed.id("block/wall/junction/low_tall_i")));
|
||||
// --------------------- junction_c
|
||||
HELPER.addReFramedModel("wall_low_c" , HELPER.auto(ReFramed.id("block/wall/junction/low_c")));
|
||||
HELPER.addReFramedModel("wall_tall_c" , HELPER.auto(ReFramed.id("block/wall/junction/tall_c")));
|
||||
HELPER.addReFramedModel("wall_low_tall_c" , HELPER.auto(ReFramed.id("block/wall/junction/low_tall_c")));
|
||||
HELPER.addReFramedModel("wall_tall_low_c" , HELPER.auto(ReFramed.id("block/wall/junction/tall_low_c")));
|
||||
HELPER.addReFramedModel("wall_low_c" , HELPER.auto(ReFramed.id("block/wall/junction/low_c")));
|
||||
HELPER.addReFramedModel("wall_tall_c" , HELPER.auto(ReFramed.id("block/wall/junction/tall_c")));
|
||||
HELPER.addReFramedModel("wall_low_tall_c" , HELPER.auto(ReFramed.id("block/wall/junction/low_tall_c")));
|
||||
HELPER.addReFramedModel("wall_tall_low_c" , HELPER.auto(ReFramed.id("block/wall/junction/tall_low_c")));
|
||||
// --------------------- junction_t
|
||||
HELPER.addReFramedModel("wall_low_t" , HELPER.auto(ReFramed.id("block/wall/junction/low_t")));
|
||||
HELPER.addReFramedModel("wall_tall_t" , HELPER.auto(ReFramed.id("block/wall/junction/tall_t")));
|
||||
HELPER.addReFramedModel("wall_tall_low_c_t" , HELPER.auto(ReFramed.id("block/wall/junction/tall_low_c_t")));
|
||||
HELPER.addReFramedModel("wall_tall_i_low_t" , HELPER.auto(ReFramed.id("block/wall/junction/tall_i_low_t")));
|
||||
HELPER.addReFramedModel("wall_low_i_tall_t" , HELPER.auto(ReFramed.id("block/wall/junction/low_i_tall_t")));
|
||||
HELPER.addReFramedModel("wall_low_tall_c_t" , HELPER.auto(ReFramed.id("block/wall/junction/low_tall_c_t")));
|
||||
HELPER.addReFramedModel("wall_low_c_tall_t" , HELPER.auto(ReFramed.id("block/wall/junction/low_c_tall_t")));
|
||||
HELPER.addReFramedModel("wall_tall_c_low_t" , HELPER.auto(ReFramed.id("block/wall/junction/tall_c_low_t")));
|
||||
HELPER.addReFramedModel("wall_low_t" , HELPER.auto(ReFramed.id("block/wall/junction/low_t")));
|
||||
HELPER.addReFramedModel("wall_tall_t" , HELPER.auto(ReFramed.id("block/wall/junction/tall_t")));
|
||||
HELPER.addReFramedModel("wall_tall_low_c_t" , HELPER.auto(ReFramed.id("block/wall/junction/tall_low_c_t")));
|
||||
HELPER.addReFramedModel("wall_tall_i_low_t" , HELPER.auto(ReFramed.id("block/wall/junction/tall_i_low_t")));
|
||||
HELPER.addReFramedModel("wall_low_i_tall_t" , HELPER.auto(ReFramed.id("block/wall/junction/low_i_tall_t")));
|
||||
HELPER.addReFramedModel("wall_low_tall_c_t" , HELPER.auto(ReFramed.id("block/wall/junction/low_tall_c_t")));
|
||||
HELPER.addReFramedModel("wall_low_c_tall_t" , HELPER.auto(ReFramed.id("block/wall/junction/low_c_tall_t")));
|
||||
HELPER.addReFramedModel("wall_tall_c_low_t" , HELPER.auto(ReFramed.id("block/wall/junction/tall_c_low_t")));
|
||||
// --------------------- junction_x
|
||||
HELPER.addReFramedModel("wall_low_x" , HELPER.auto(ReFramed.id("block/wall/junction/low_x")));
|
||||
HELPER.addReFramedModel("wall_tall_x" , HELPER.auto(ReFramed.id("block/wall/junction/tall_x")));
|
||||
HELPER.addReFramedModel("wall_tall_i_low_i_x" , HELPER.auto(ReFramed.id("block/wall/junction/tall_i_low_i_x")));
|
||||
HELPER.addReFramedModel("wall_tall_low_t_x" , HELPER.auto(ReFramed.id("block/wall/junction/tall_low_t_x")));
|
||||
HELPER.addReFramedModel("wall_tall_c_low_c_x" , HELPER.auto(ReFramed.id("block/wall/junction/tall_c_low_c_x")));
|
||||
HELPER.addReFramedModel("wall_tall_t_low_x" , HELPER.auto(ReFramed.id("block/wall/junction/tall_t_low_x")));
|
||||
HELPER.addReFramedModel("wall_low_x" , HELPER.auto(ReFramed.id("block/wall/junction/low_x")));
|
||||
HELPER.addReFramedModel("wall_tall_x" , HELPER.auto(ReFramed.id("block/wall/junction/tall_x")));
|
||||
HELPER.addReFramedModel("wall_tall_i_low_i_x" , HELPER.auto(ReFramed.id("block/wall/junction/tall_i_low_i_x")));
|
||||
HELPER.addReFramedModel("wall_tall_low_t_x" , HELPER.auto(ReFramed.id("block/wall/junction/tall_low_t_x")));
|
||||
HELPER.addReFramedModel("wall_tall_c_low_c_x" , HELPER.auto(ReFramed.id("block/wall/junction/tall_c_low_c_x")));
|
||||
HELPER.addReFramedModel("wall_tall_t_low_x" , HELPER.auto(ReFramed.id("block/wall/junction/tall_t_low_x")));
|
||||
// PILLAR WALL
|
||||
HELPER.addReFramedModel("pillars_wall_inventory" , HELPER.autoDouble(ReFramed.id("block/pillar"), ReFramed.id("block/wall/full/inventory/sides")));
|
||||
HELPER.addReFramedModel("pillars_wall_low" , HELPER.autoDouble(ReFramed.id("block/wall/full/pillar/low"), ReFramed.id("block/wall/full/side/low")));
|
||||
HELPER.addReFramedModel("pillars_wall_tall" , HELPER.autoDouble(ReFramed.id("block/wall/full/pillar/tall"), ReFramed.id("block/wall/full/side/tall")));
|
||||
HELPER.addReFramedModel("pillars_wall_inventory" , HELPER.autoDouble(ReFramed.id("block/pillar"), ReFramed.id("block/wall/full/inventory/sides")));
|
||||
HELPER.addReFramedModel("pillars_wall_low" , HELPER.autoDouble(ReFramed.id("block/wall/full/pillar/low"), ReFramed.id("block/wall/full/side/low")));
|
||||
HELPER.addReFramedModel("pillars_wall_tall" , HELPER.autoDouble(ReFramed.id("block/wall/full/pillar/tall"), ReFramed.id("block/wall/full/side/tall")));
|
||||
// PANE
|
||||
HELPER.addReFramedModel("pane_inventory" , HELPER.auto(ReFramed.id("block/pane")));
|
||||
HELPER.addReFramedModel("pane_post" , HELPER.auto(new Identifier("block/glass_pane_post")));
|
||||
HELPER.addReFramedModel("pane_side" , HELPER.auto(new Identifier("block/glass_pane_side")));
|
||||
HELPER.addReFramedModel("pane_side_alt" , HELPER.auto(new Identifier("block/glass_pane_side_alt")));
|
||||
HELPER.addReFramedModel("pane_noside" , HELPER.auto(new Identifier("block/glass_pane_noside")));
|
||||
HELPER.addReFramedModel("pane_noside_alt" , HELPER.auto(new Identifier("block/glass_pane_noside_alt")));
|
||||
HELPER.addReFramedModel("pane_inventory" , HELPER.auto(ReFramed.id("block/pane")));
|
||||
HELPER.addReFramedModel("pane_post" , HELPER.auto(new Identifier("block/glass_pane_post")));
|
||||
HELPER.addReFramedModel("pane_side" , HELPER.auto(new Identifier("block/glass_pane_side")));
|
||||
HELPER.addReFramedModel("pane_side_alt" , HELPER.auto(new Identifier("block/glass_pane_side_alt")));
|
||||
HELPER.addReFramedModel("pane_noside" , HELPER.auto(new Identifier("block/glass_pane_noside")));
|
||||
HELPER.addReFramedModel("pane_noside_alt" , HELPER.auto(new Identifier("block/glass_pane_noside_alt")));
|
||||
// TRAPDOOR
|
||||
HELPER.addReFramedModel("trapdoor_open" , HELPER.auto(new Identifier("block/oak_trapdoor_open")));
|
||||
HELPER.addReFramedModel("trapdoor_bottom" , HELPER.auto(new Identifier("block/oak_trapdoor_bottom")));
|
||||
HELPER.addReFramedModel("trapdoor_top" , HELPER.auto(new Identifier("block/oak_trapdoor_top")));
|
||||
HELPER.addReFramedModel("trapdoor_open" , HELPER.auto(new Identifier("block/oak_trapdoor_open")));
|
||||
HELPER.addReFramedModel("trapdoor_bottom" , HELPER.auto(new Identifier("block/oak_trapdoor_bottom")));
|
||||
HELPER.addReFramedModel("trapdoor_top" , HELPER.auto(new Identifier("block/oak_trapdoor_top")));
|
||||
// DOOR
|
||||
HELPER.addReFramedModel("door_inventory" , HELPER.auto(ReFramed.id("block/door")));
|
||||
HELPER.addReFramedModel("door_inventory" , HELPER.auto(ReFramed.id("block/door")));
|
||||
// BUTTON
|
||||
HELPER.addReFramedModel("button_inventory" , HELPER.auto(new Identifier("block/button_inventory")));
|
||||
HELPER.addReFramedModel("button" , HELPER.auto(new Identifier("block/button")));
|
||||
HELPER.addReFramedModel("button_pressed" , HELPER.auto(new Identifier("block/button_pressed")));
|
||||
// POST
|
||||
HELPER.addReFramedModel("post" , HELPER.auto(ReFramed.id("block/post")));
|
||||
// FENCE
|
||||
HELPER.addReFramedModel("fence_inventory" , HELPER.auto(ReFramed.id("block/fence/inventory")));
|
||||
HELPER.addReFramedModel("fence_core" , HELPER.auto(ReFramed.id("block/fence/core")));
|
||||
HELPER.addReFramedModel("fence_side_off" , HELPER.auto(ReFramed.id("block/fence/side_off")));
|
||||
HELPER.addReFramedModel("fence_side_on" , HELPER.auto(ReFramed.id("block/fence/side_on")));
|
||||
// POST FENCE
|
||||
HELPER.addReFramedModel("post_fence_inventory" , HELPER.autoDouble(ReFramed.id("block/post"), ReFramed.id("block/fence/full/inventory")));
|
||||
HELPER.addReFramedModel("post_fence_side" , HELPER.autoDouble(ReFramed.id("block/fence/full/side_core"), ReFramed.id("block/fence/full/side_bars")));
|
||||
// SLABS STAIR
|
||||
HELPER.addReFramedModel("slabs_stair" , HELPER.autoDouble(ReFramed.id("block/slabs_stair/slab"), ReFramed.id("block/slabs_stair/step")));
|
||||
HELPER.addReFramedModel("slabs_stair_side" , HELPER.autoDouble(ReFramed.id("block/slabs_stair/side/slab"), ReFramed.id("block/slabs_stair/side/step")));
|
||||
// SLABS OUTER STAIR
|
||||
HELPER.addReFramedModel("slabs_outer_stair" , HELPER.autoDouble(ReFramed.id("block/slabs_stair/outer/slab"), ReFramed.id("block/slabs_stair/outer/cube")));
|
||||
HELPER.addReFramedModel("slabs_outer_stair_side" , HELPER.autoDouble(ReFramed.id("block/slabs_stair/outer/side/slab"), ReFramed.id("block/slabs_stair/outer/side/cube")));
|
||||
// SLABS OUTER STAIR
|
||||
HELPER.addReFramedModel("slabs_inner_stair" , HELPER.autoDouble(ReFramed.id("block/slabs_stair/inner/slab"), ReFramed.id("block/slabs_stair/inner/half_stair")));
|
||||
HELPER.addReFramedModel("slabs_inner_stair_side" , HELPER.autoDouble(ReFramed.id("block/slabs_stair/inner/side/slab"), ReFramed.id("block/slabs_stair/inner/side/half_stair")));
|
||||
// SLABS OUTER STAIR
|
||||
HELPER.addReFramedModel("steps_cross" , HELPER.autoDouble(ReFramed.id("block/step/down"), ReFramed.id("block/step/cross")));
|
||||
// HALF STAIRS CUBE STAIR
|
||||
HELPER.addReFramedModel("half_stairs_cube_stair" , HELPER.autoDouble(ReFramed.id("block/half_stair/base"), ReFramed.id("block/half_stair/stair/cube")));
|
||||
HELPER.addReFramedModel("half_stairs_cube_stair_side" , HELPER.autoDouble(ReFramed.id("block/half_stair/base_side"), ReFramed.id("block/half_stair/stair/cube_side")));
|
||||
// HALF STAIRS STEP STAIR
|
||||
HELPER.addReFramedModel("half_stairs_step_stair_1" , HELPER.autoDouble(ReFramed.id("block/half_stair/base"), ReFramed.id("block/half_stair/stair/step_1")));
|
||||
HELPER.addReFramedModel("half_stairs_step_stair_side_1", HELPER.autoDouble(ReFramed.id("block/half_stair/base_side"), ReFramed.id("block/half_stair/stair/step_side_1")));
|
||||
HELPER.addReFramedModel("half_stairs_step_stair_2" , HELPER.autoDouble(ReFramed.id("block/half_stair/base"), ReFramed.id("block/half_stair/stair/step_2")));
|
||||
HELPER.addReFramedModel("half_stairs_step_stair_side_2", HELPER.autoDouble(ReFramed.id("block/half_stair/base_side"), ReFramed.id("block/half_stair/stair/step_side_2")));
|
||||
// HALF LAYER
|
||||
// --------------------- east
|
||||
HELPER.addReFramedModel("half_layer_2" , HELPER.auto(ReFramed.id("block/half_layer/east/layer_2")));
|
||||
HELPER.addReFramedModel("half_layer_4" , HELPER.auto(ReFramed.id("block/half_layer/east/layer_4")));
|
||||
HELPER.addReFramedModel("half_layer_6" , HELPER.auto(ReFramed.id("block/half_layer/east/layer_6")));
|
||||
HELPER.addReFramedModel("half_layer_8" , HELPER.auto(ReFramed.id("block/half_layer/east/layer_8")));
|
||||
HELPER.addReFramedModel("half_layer_10" , HELPER.auto(ReFramed.id("block/half_layer/east/layer_10")));
|
||||
HELPER.addReFramedModel("half_layer_12" , HELPER.auto(ReFramed.id("block/half_layer/east/layer_12")));
|
||||
HELPER.addReFramedModel("half_layer_14" , HELPER.auto(ReFramed.id("block/half_layer/east/layer_14")));
|
||||
HELPER.addReFramedModel("half_layer_16" , HELPER.auto(ReFramed.id("block/half_layer/east/layer_16")));
|
||||
// --------------------- side
|
||||
HELPER.addReFramedModel("half_layer_side_2" , HELPER.auto(ReFramed.id("block/half_layer/side/layer_2")));
|
||||
HELPER.addReFramedModel("half_layer_side_4" , HELPER.auto(ReFramed.id("block/half_layer/side/layer_4")));
|
||||
HELPER.addReFramedModel("half_layer_side_6" , HELPER.auto(ReFramed.id("block/half_layer/side/layer_6")));
|
||||
HELPER.addReFramedModel("half_layer_side_8" , HELPER.auto(ReFramed.id("block/half_layer/side/layer_8")));
|
||||
HELPER.addReFramedModel("half_layer_side_10" , HELPER.auto(ReFramed.id("block/half_layer/side/layer_10")));
|
||||
HELPER.addReFramedModel("half_layer_side_12" , HELPER.auto(ReFramed.id("block/half_layer/side/layer_12")));
|
||||
HELPER.addReFramedModel("half_layer_side_14" , HELPER.auto(ReFramed.id("block/half_layer/side/layer_14")));
|
||||
HELPER.addReFramedModel("half_layer_side_16" , HELPER.auto(ReFramed.id("block/half_layer/side/layer_16")));
|
||||
// SLAB HALF LAYER
|
||||
HELPER.addReFramedModel("slabs_half_inventory" , HELPER.autoDouble(new Identifier("block/slab"), ReFramed.id("block/half_layer/slab/east/layer_4")));
|
||||
// STEP HALF LAYER
|
||||
HELPER.addReFramedModel("steps_half_inventory" , HELPER.autoDouble(ReFramed.id("block/step/down"), ReFramed.id("block/half_layer/slab/east/layer_4")));
|
||||
// --------------------- east
|
||||
HELPER.addReFramedModel("second_half_layer_2" , HELPER.auto(ReFramed.id("block/half_layer/slab/east/layer_2")).setThemeIndex(2));
|
||||
HELPER.addReFramedModel("second_half_layer_4" , HELPER.auto(ReFramed.id("block/half_layer/slab/east/layer_4")).setThemeIndex(2));
|
||||
HELPER.addReFramedModel("second_half_layer_6" , HELPER.auto(ReFramed.id("block/half_layer/slab/east/layer_6")).setThemeIndex(2));
|
||||
HELPER.addReFramedModel("second_half_layer_8" , HELPER.auto(ReFramed.id("block/half_layer/slab/east/layer_8")).setThemeIndex(2));
|
||||
HELPER.addReFramedModel("second_half_layer_10" , HELPER.auto(ReFramed.id("block/half_layer/slab/east/layer_10")).setThemeIndex(2));
|
||||
HELPER.addReFramedModel("second_half_layer_12" , HELPER.auto(ReFramed.id("block/half_layer/slab/east/layer_12")).setThemeIndex(2));
|
||||
HELPER.addReFramedModel("second_half_layer_14" , HELPER.auto(ReFramed.id("block/half_layer/slab/east/layer_14")).setThemeIndex(2));
|
||||
HELPER.addReFramedModel("second_half_layer_16" , HELPER.auto(ReFramed.id("block/half_layer/slab/east/layer_16")).setThemeIndex(2));
|
||||
// --------------------- side
|
||||
HELPER.addReFramedModel("second_half_layer_side_2" , HELPER.auto(ReFramed.id("block/half_layer/slab/side/layer_2")).setThemeIndex(2));
|
||||
HELPER.addReFramedModel("second_half_layer_side_4" , HELPER.auto(ReFramed.id("block/half_layer/slab/side/layer_4")).setThemeIndex(2));
|
||||
HELPER.addReFramedModel("second_half_layer_side_6" , HELPER.auto(ReFramed.id("block/half_layer/slab/side/layer_6")).setThemeIndex(2));
|
||||
HELPER.addReFramedModel("second_half_layer_side_8" , HELPER.auto(ReFramed.id("block/half_layer/slab/side/layer_8")).setThemeIndex(2));
|
||||
HELPER.addReFramedModel("second_half_layer_side_10" , HELPER.auto(ReFramed.id("block/half_layer/slab/side/layer_10")).setThemeIndex(2));
|
||||
HELPER.addReFramedModel("second_half_layer_side_12" , HELPER.auto(ReFramed.id("block/half_layer/slab/side/layer_12")).setThemeIndex(2));
|
||||
HELPER.addReFramedModel("second_half_layer_side_14" , HELPER.auto(ReFramed.id("block/half_layer/slab/side/layer_14")).setThemeIndex(2));
|
||||
HELPER.addReFramedModel("second_half_layer_side_16" , HELPER.auto(ReFramed.id("block/half_layer/slab/side/layer_16")).setThemeIndex(2));
|
||||
// HALF SLAB
|
||||
HELPER.addReFramedModel("half_slab" , HELPER.auto(ReFramed.id("block/half_slab/default")));
|
||||
// HALF SLABS SLAB
|
||||
HELPER.addReFramedModel("half_slabs_slab" , HELPER.autoDouble(ReFramed.id("block/half_slab/default"), ReFramed.id("block/half_slab/complement")));
|
||||
// SLABS LAYER
|
||||
HELPER.addReFramedModel("slabs_layer_2" , HELPER.autoDouble(new Identifier("block/slab"), ReFramed.id("block/layer_top/layer_2")));
|
||||
HELPER.addReFramedModel("slabs_layer_4" , HELPER.autoDouble(new Identifier("block/slab"), ReFramed.id("block/layer_top/layer_4")));
|
||||
HELPER.addReFramedModel("slabs_layer_6" , HELPER.autoDouble(new Identifier("block/slab"), ReFramed.id("block/layer_top/layer_6")));
|
||||
HELPER.addReFramedModel("slabs_layer_8" , HELPER.autoDouble(new Identifier("block/slab"), ReFramed.id("block/layer_top/layer_8")));
|
||||
|
||||
|
||||
//item model assignments (in lieu of models/item/___.json)
|
||||
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("pillars_wall_inventory", ReFramed.PILLARS_WALL);
|
||||
HELPER.assignItemModel("wall_inventory" , ReFramed.WALL);
|
||||
HELPER.assignItemModel("pane_inventory" , ReFramed.PANE);
|
||||
HELPER.assignItemModel("trapdoor_bottom" , ReFramed.TRAPDOOR);
|
||||
HELPER.assignItemModel("door_inventory" , ReFramed.DOOR);
|
||||
|
||||
// item model assignments (in lieu of models/item/___.json)
|
||||
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("pillars_wall_inventory" , ReFramed.PILLARS_WALL);
|
||||
HELPER.assignItemModel("wall_inventory" , ReFramed.WALL);
|
||||
HELPER.assignItemModel("pane_inventory" , ReFramed.PANE);
|
||||
HELPER.assignItemModel("trapdoor_bottom" , ReFramed.TRAPDOOR);
|
||||
HELPER.assignItemModel("door_inventory" , ReFramed.DOOR);
|
||||
HELPER.assignItemModel("button_inventory" , ReFramed.BUTTON);
|
||||
HELPER.assignItemModel("post" , ReFramed.POST);
|
||||
HELPER.assignItemModel("fence_inventory" , ReFramed.FENCE);
|
||||
HELPER.assignItemModel("post_fence_inventory" , ReFramed.POST_FENCE);
|
||||
HELPER.assignItemModel("slabs_stair" , ReFramed.SLABS_STAIR);
|
||||
HELPER.assignItemModel("slabs_outer_stair" , ReFramed.SLABS_OUTER_STAIR);
|
||||
HELPER.assignItemModel("slabs_inner_stair" , ReFramed.SLABS_INNER_STAIR);
|
||||
HELPER.assignItemModel("steps_cross" , ReFramed.STEPS_CROSS);
|
||||
HELPER.assignItemModel("half_stairs_cube_stair" , ReFramed.HALF_STAIRS_CUBE_STAIR);
|
||||
HELPER.assignItemModel("half_stairs_step_stair_1", ReFramed.HALF_STAIRS_STEP_STAIR);
|
||||
HELPER.assignItemModel("half_layer_2" , ReFramed.HALF_LAYER);
|
||||
HELPER.assignItemModel("slabs_half_inventory" , ReFramed.SLABS_HALF_LAYER);
|
||||
HELPER.assignItemModel("steps_half_inventory" , ReFramed.STEPS_HALF_LAYER);
|
||||
HELPER.assignItemModel("half_slab" , ReFramed.HALF_SLAB);
|
||||
HELPER.assignItemModel("half_slabs_slab" , ReFramed.HALF_SLABS_SLAB);
|
||||
HELPER.assignItemModel("slabs_layer_2" , ReFramed.SLABS_LAYER);
|
||||
}
|
||||
|
||||
private void privateInit() {
|
||||
|
||||
@@ -5,12 +5,15 @@ import net.fabricmc.api.Environment;
|
||||
import net.fabricmc.fabric.api.renderer.v1.model.ForwardingBakedModel;
|
||||
import net.fabricmc.fabric.api.renderer.v1.render.RenderContext;
|
||||
import net.minecraft.block.BlockState;
|
||||
import net.minecraft.client.render.model.BakedQuad;
|
||||
import net.minecraft.client.texture.Sprite;
|
||||
import net.minecraft.item.ItemStack;
|
||||
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.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.function.Supplier;
|
||||
|
||||
@@ -35,7 +38,17 @@ public class DoubleRetexturingBakedModel extends ForwardingBakedModel implements
|
||||
}
|
||||
|
||||
@Override
|
||||
public void emitBlockQuads(BlockRenderView world, BlockState state, BlockPos pos, Supplier<Random> randomSupplier, RenderContext context) {}
|
||||
public List<BakedQuad> getQuads(BlockState blockState, Direction face, Random rand) {
|
||||
List<BakedQuad> quads = new ArrayList<>(model_1.getQuads(blockState, face, rand));
|
||||
quads.addAll(model_2.getQuads(blockState, face, rand));
|
||||
return quads;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void emitBlockQuads(BlockRenderView world, BlockState state, BlockPos pos, Supplier<Random> randomSupplier, RenderContext context) {
|
||||
model_1.emitBlockQuads(world, state, pos, randomSupplier, context);
|
||||
model_2.emitBlockQuads(world, state, pos, randomSupplier, context);
|
||||
}
|
||||
|
||||
@Override // models are emitted here because no checks are done on items
|
||||
public void emitItemQuads(ItemStack stack, Supplier<Random> randomSupplier, RenderContext context) {
|
||||
|
||||
@@ -12,11 +12,13 @@ import fr.adrien1106.reframed.util.blocks.ThemeableBlockEntity;
|
||||
import it.unimi.dsi.fastutil.objects.Object2ObjectLinkedOpenHashMap;
|
||||
import net.fabricmc.fabric.api.renderer.v1.mesh.*;
|
||||
import net.fabricmc.fabric.api.renderer.v1.model.ForwardingBakedModel;
|
||||
import net.fabricmc.fabric.api.renderer.v1.model.ModelHelper;
|
||||
import net.fabricmc.fabric.api.renderer.v1.render.RenderContext;
|
||||
import net.minecraft.block.BlockState;
|
||||
import net.minecraft.block.Blocks;
|
||||
import net.minecraft.client.MinecraftClient;
|
||||
import net.minecraft.client.render.model.BakedModel;
|
||||
import net.minecraft.client.render.model.BakedQuad;
|
||||
import net.minecraft.client.render.model.ModelBakeSettings;
|
||||
import net.minecraft.client.texture.Sprite;
|
||||
import net.minecraft.item.ItemStack;
|
||||
@@ -25,6 +27,7 @@ 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;
|
||||
|
||||
@@ -62,7 +65,7 @@ public abstract class RetexturingBakedModel extends ForwardingBakedModel {
|
||||
System.arraycopy(values, 0, DIRECTIONS_AND_NULL, 0, values.length);
|
||||
}
|
||||
|
||||
protected Mesh getBaseMesh(Object key, BlockState state) {
|
||||
protected Mesh getBaseMesh(Object key, BlockState state) {
|
||||
//Convert models to re-texturable Meshes lazily, the first time we encounter each blockstate
|
||||
if (BASE_MESH_CACHE.containsKey(key)) return BASE_MESH_CACHE.getAndMoveToFirst(key);
|
||||
Mesh mesh = convertModel(state);
|
||||
@@ -70,7 +73,40 @@ public abstract class RetexturingBakedModel extends ForwardingBakedModel {
|
||||
return mesh;
|
||||
}
|
||||
|
||||
protected abstract Mesh convertModel(BlockState state);
|
||||
private List<BakedQuad>[] quads = null;
|
||||
|
||||
@Override
|
||||
public List<BakedQuad> getQuads(BlockState state, Direction face, Random rand) {
|
||||
if (quads == null) {
|
||||
quads = ModelHelper.toQuadLists(
|
||||
getRetexturedMesh(
|
||||
new MeshCacheKey(
|
||||
hashCode(),
|
||||
appearance_manager.getDefaultAppearance(theme_index),
|
||||
0
|
||||
),
|
||||
state == null ? item_state : state
|
||||
)
|
||||
);
|
||||
}
|
||||
return quads[ModelHelper.toFaceIndex(face)];
|
||||
}
|
||||
|
||||
public void setCamo(BlockRenderView world, BlockState state, BlockPos pos) {
|
||||
if (state == null || state.isAir()) {
|
||||
quads = null;
|
||||
return;
|
||||
}
|
||||
CamoAppearance camo = appearance_manager.getCamoAppearance(world, state, pos, theme_index, false);
|
||||
MeshCacheKey key = new MeshCacheKey(
|
||||
hashCode(),
|
||||
camo,
|
||||
0
|
||||
);
|
||||
quads = ModelHelper.toQuadLists(camo.hashCode() == -1 ? transformMesh(key, state) : getRetexturedMesh(key, state));
|
||||
}
|
||||
|
||||
protected abstract Mesh convertModel(BlockState state);
|
||||
|
||||
@Override
|
||||
public boolean isVanillaAdapter() {
|
||||
@@ -89,6 +125,7 @@ public abstract class RetexturingBakedModel extends ForwardingBakedModel {
|
||||
@Override
|
||||
public void emitBlockQuads(BlockRenderView world, BlockState state, BlockPos pos, Supplier<Random> randomSupplier, RenderContext context) {
|
||||
BlockState theme = (world.getBlockEntity(pos) instanceof ThemeableBlockEntity s) ? s.getTheme(theme_index) : null;
|
||||
|
||||
QuadEmitter quad_emitter = context.getEmitter();
|
||||
if(theme == null || theme.isAir()) {
|
||||
getRetexturedMesh(
|
||||
@@ -153,9 +190,14 @@ public abstract class RetexturingBakedModel extends ForwardingBakedModel {
|
||||
|
||||
public boolean useAmbientOcclusion(BlockRenderView view, BlockPos pos) {
|
||||
if (!(view.getBlockEntity(pos) instanceof ThemeableBlockEntity frame_entity)) return false;
|
||||
BlockState theme = frame_entity.getTheme(theme_index);
|
||||
CamoAppearance appearance = appearance_manager
|
||||
.getCamoAppearance(view, frame_entity.getTheme(theme_index), pos, theme_index, false);
|
||||
return appearance.getAO(theme_index);
|
||||
.getCamoAppearance(view, theme, pos, theme_index, false);
|
||||
|
||||
long seed = theme.getRenderingSeed(pos);
|
||||
int model_id = 0;
|
||||
if (appearance instanceof WeightedComputedAppearance wca) model_id = wca.getAppearanceIndex(seed);
|
||||
return appearance.getAO(model_id);
|
||||
}
|
||||
|
||||
protected Mesh getRetexturedMesh(MeshCacheKey key, BlockState state) {
|
||||
@@ -176,7 +218,7 @@ public abstract class RetexturingBakedModel extends ForwardingBakedModel {
|
||||
emitter.copyFrom(quad);
|
||||
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
|
||||
// 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();
|
||||
});
|
||||
|
||||
|
||||
@@ -51,7 +51,7 @@ public class CamoAppearanceManager {
|
||||
for(BlendMode blend : BlendMode.values()) {
|
||||
finder.clear().disableDiffuse(false).blendMode(blend);
|
||||
|
||||
materials.put(blend, finder.ambientOcclusion(TriState.FALSE).find());
|
||||
materials.put(blend, finder.ambientOcclusion(TriState.TRUE).find());
|
||||
ao_materials.put(blend, finder.ambientOcclusion(TriState.DEFAULT).find()); //not "true" since that *forces* AO, i just want to *allow* AO
|
||||
}
|
||||
|
||||
|
||||
@@ -12,7 +12,6 @@ import net.fabricmc.api.Environment;
|
||||
import net.fabricmc.fabric.api.renderer.v1.Renderer;
|
||||
import net.fabricmc.fabric.api.renderer.v1.material.RenderMaterial;
|
||||
import net.fabricmc.fabric.api.renderer.v1.mesh.QuadEmitter;
|
||||
import net.fabricmc.fabric.api.renderer.v1.model.ForwardingBakedModel;
|
||||
import net.minecraft.block.Block;
|
||||
import net.minecraft.block.BlockState;
|
||||
import net.minecraft.util.function.BooleanBiFunction;
|
||||
@@ -52,8 +51,6 @@ public class RenderHelper {
|
||||
Random random = Random.create();
|
||||
|
||||
List<List<QuadPosBounds>> model_bounds = models.stream()
|
||||
.map(ForwardingBakedModel::getWrappedModel)
|
||||
.filter(Objects::nonNull)
|
||||
.map(wrapped -> wrapped.getQuads(state, null, random))
|
||||
.map(quads -> quads.stream().map(quad -> {
|
||||
quad_emitter.fromVanilla(quad, material, null);
|
||||
@@ -92,18 +89,27 @@ public class RenderHelper {
|
||||
BlockState self_theme = frame_entity.getTheme(theme_index);
|
||||
BlockState other_theme = frame_entity.getTheme(cull_theme);
|
||||
|
||||
if (self_theme.isSideInvisible(other_theme, null)) return false;
|
||||
return !self_theme.isOpaque() || !other_theme.isOpaque();
|
||||
try {
|
||||
if (self_theme.isSideInvisible(other_theme, null)) return false;
|
||||
} catch (NullPointerException e) { // this can happen if mod haven't thought about inner faces
|
||||
return true;
|
||||
}
|
||||
return self_theme.isOpaque() != other_theme.isOpaque() && self_theme.isOpaque();
|
||||
}
|
||||
|
||||
// Doing this method from scratch as it is simpler to do than injecting everywhere
|
||||
public static boolean shouldDrawSide(BlockState self_state, BlockView world, BlockPos pos, Direction side, BlockPos other_pos, int theme_index) {
|
||||
ThemeableBlockEntity self = world.getBlockEntity(pos) instanceof ThemeableBlockEntity e ? e : null;
|
||||
ThemeableBlockEntity other = world.getBlockEntity(other_pos) instanceof ThemeableBlockEntity e ? e : null;
|
||||
BlockState other_state = world.getBlockState(other_pos);
|
||||
ThemeableBlockEntity self = world.getBlockEntity(pos) instanceof ThemeableBlockEntity e
|
||||
&& self_state.getBlock() instanceof ReFramedBlock
|
||||
? e : null;
|
||||
ThemeableBlockEntity other = world.getBlockEntity(other_pos) instanceof ThemeableBlockEntity e
|
||||
&& other_state.getBlock() instanceof ReFramedBlock
|
||||
? e : null;
|
||||
|
||||
// normal behaviour
|
||||
if (self == null && other == null) return Block.shouldDrawSide(self_state, world, pos, side, other_pos);
|
||||
if ((theme_index == 0 && self != null) || (self == null && other == null))
|
||||
return Block.shouldDrawSide(self_state, world, pos, side, other_pos);
|
||||
|
||||
// self is a normal Block
|
||||
if (self == null && other_state.getBlock() instanceof ReFramedBlock other_block) {
|
||||
@@ -114,7 +120,7 @@ public class RenderHelper {
|
||||
VoxelShape other_shape = VoxelShapes.empty();
|
||||
for (BlockState s: other.getThemes()) {
|
||||
i++;
|
||||
if (self_state.isSideInvisible(s, side) || s.isOpaque())
|
||||
if (self_state.isSideInvisible(s, side) || (s.isOpaque() && (other.isSolid() || self_state.isTransparent(world ,pos))))
|
||||
other_shape = combine(
|
||||
other_shape,
|
||||
other_block
|
||||
@@ -158,7 +164,7 @@ public class RenderHelper {
|
||||
VoxelShape other_shape = VoxelShapes.empty();
|
||||
for (BlockState s: other.getThemes()) {
|
||||
i++;
|
||||
if (self_theme.isSideInvisible(s, side) || s.isOpaque())
|
||||
if (self_theme.isSideInvisible(s, side) || (s.isOpaque() && (!self.isSolid() || (other.isSolid() == self.isSolid()))))
|
||||
other_shape = combine(
|
||||
other_shape,
|
||||
other_block
|
||||
|
||||
@@ -19,6 +19,8 @@ public class GBlockTag extends BlockTagProvider {
|
||||
providers.put(ReFramedPillarsWallBlock.class, new PillarsWall());
|
||||
providers.put(ReFramedWallBlock.class, new Wall());
|
||||
providers.put(ReFramedPaneBlock.class, new Pane());
|
||||
providers.put(ReFramedFenceBlock.class, new Fence());
|
||||
providers.put(ReFramedPostFenceBlock.class, new PostFence());
|
||||
}
|
||||
|
||||
public GBlockTag(FabricDataOutput output, CompletableFuture<WrapperLookup> registries) {
|
||||
|
||||
@@ -22,21 +22,37 @@ public class GBlockstate extends FabricModelProvider {
|
||||
providers.put(ReFramedHalfStairBlock.class, new HalfStair());
|
||||
providers.put(ReFramedHalfStairsSlabBlock.class, new HalfStairsSlab());
|
||||
providers.put(ReFramedHalfStairsStairBlock.class, new HalfStairsStair());
|
||||
providers.put(ReFramedHalfStairsCubeStairBlock.class, new HalfStairsCubeStair());
|
||||
providers.put(ReFramedHalfStairsStepStairBlock.class, new HalfStairsStepStair());
|
||||
providers.put(ReFramedLayerBlock.class, new Layer());
|
||||
providers.put(ReFramedHalfLayerBlock.class, new HalfLayer());
|
||||
providers.put(ReFramedPillarBlock.class, new Pillar());
|
||||
providers.put(ReFramedSlabBlock.class, new Slab());
|
||||
providers.put(ReFramedSlabsCubeBlock.class, new SlabsCube());
|
||||
providers.put(ReFramedSlabsStairBlock.class, new SlabsStair());
|
||||
providers.put(ReFramedSlabsOuterStairBlock.class, new SlabsOuterStair());
|
||||
providers.put(ReFramedSlabsInnerStairBlock.class, new SlabsInnerStair());
|
||||
providers.put(ReFramedSlabsHalfLayerBlock.class, new SlabsHalfLayer());
|
||||
providers.put(ReFramedSlabsLayerBlock.class, new SlabsLayer());
|
||||
providers.put(ReFramedHalfSlabBlock.class, new HalfSlab());
|
||||
providers.put(ReFramedHalfSlabsSlabBlock.class, new HalfSlabsSlab());
|
||||
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(ReFramedStepsCrossBlock.class, new StepsCross());
|
||||
providers.put(ReFramedStepsHalfLayerBlock.class, new StepsHalfLayer());
|
||||
providers.put(ReFramedPillarsWallBlock.class, new PillarsWall());
|
||||
providers.put(ReFramedWallBlock.class, new Wall());
|
||||
providers.put(ReFramedPaneBlock.class, new Pane());
|
||||
providers.put(ReFramedTrapdoorBlock.class, new Trapdoor());
|
||||
providers.put(ReFramedDoorBlock.class, new Door());
|
||||
providers.put(ReFramedButtonBlock.class, new Button());
|
||||
providers.put(ReFramedPostBlock.class, new Post());
|
||||
providers.put(ReFramedFenceBlock.class, new Fence());
|
||||
providers.put(ReFramedPostFenceBlock.class, new PostFence());
|
||||
}
|
||||
|
||||
public GBlockstate(FabricDataOutput output) {
|
||||
|
||||
@@ -24,21 +24,37 @@ public class GRecipe extends FabricRecipeProvider {
|
||||
providers.put(ReFramedHalfStairBlock.class, new HalfStair());
|
||||
providers.put(ReFramedHalfStairsSlabBlock.class, new HalfStairsSlab());
|
||||
providers.put(ReFramedHalfStairsStairBlock.class, new HalfStairsStair());
|
||||
providers.put(ReFramedHalfStairsCubeStairBlock.class, new HalfStairsCubeStair());
|
||||
providers.put(ReFramedHalfStairsStepStairBlock.class, new HalfStairsStepStair());
|
||||
providers.put(ReFramedLayerBlock.class, new Layer());
|
||||
providers.put(ReFramedHalfLayerBlock.class, new HalfLayer());
|
||||
providers.put(ReFramedPillarBlock.class, new Pillar());
|
||||
providers.put(ReFramedSlabBlock.class, new Slab());
|
||||
providers.put(ReFramedSlabsCubeBlock.class, new SlabsCube());
|
||||
providers.put(ReFramedSlabsStairBlock.class, new SlabsStair());
|
||||
providers.put(ReFramedSlabsOuterStairBlock.class, new SlabsOuterStair());
|
||||
providers.put(ReFramedSlabsInnerStairBlock.class, new SlabsInnerStair());
|
||||
providers.put(ReFramedSlabsHalfLayerBlock.class, new SlabsHalfLayer());
|
||||
providers.put(ReFramedSlabsLayerBlock.class, new SlabsLayer());
|
||||
providers.put(ReFramedHalfSlabBlock.class, new HalfSlab());
|
||||
providers.put(ReFramedHalfSlabsSlabBlock.class, new HalfSlabsSlab());
|
||||
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(ReFramedStepsCrossBlock.class, new StepsCross());
|
||||
providers.put(ReFramedStepsHalfLayerBlock.class, new StepsHalfLayer());
|
||||
providers.put(ReFramedPillarsWallBlock.class, new PillarsWall());
|
||||
providers.put(ReFramedWallBlock.class, new Wall());
|
||||
providers.put(ReFramedPaneBlock.class, new Pane());
|
||||
providers.put(ReFramedTrapdoorBlock.class, new Trapdoor());
|
||||
providers.put(ReFramedDoorBlock.class, new Door());
|
||||
providers.put(ReFramedButtonBlock.class, new Button());
|
||||
providers.put(ReFramedPostBlock.class, new Post());
|
||||
providers.put(ReFramedFenceBlock.class, new Fence());
|
||||
providers.put(ReFramedPostFenceBlock.class, new PostFence());
|
||||
providers.put(ReFramedBlueprintItem.class, new Blueprint());
|
||||
providers.put(ReFramedHammerItem.class, new Hammer());
|
||||
providers.put(ReFramedScrewdriverItem.class, new Screwdriver());
|
||||
|
||||
@@ -0,0 +1,95 @@
|
||||
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.block.enums.BlockFace;
|
||||
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 net.minecraft.util.math.Direction;
|
||||
|
||||
import static net.minecraft.data.client.VariantSettings.Rotation.*;
|
||||
import static net.minecraft.state.property.Properties.*;
|
||||
|
||||
public class Button 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, 1)
|
||||
.input(ReFramed.CUBE, 1)
|
||||
.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 button = ReFramed.id("button_special");
|
||||
Identifier button_pressed = ReFramed.id("button_pressed_special");
|
||||
return MultipartBlockStateSupplier.create(block)
|
||||
// FLOOR OFF
|
||||
.with(GBlockstate.when(POWERED, false, HORIZONTAL_FACING, Direction.NORTH, BLOCK_FACE, BlockFace.FLOOR),
|
||||
GBlockstate.variant(button, true, R0, R0))
|
||||
.with(GBlockstate.when(POWERED, false, HORIZONTAL_FACING, Direction.EAST, BLOCK_FACE, BlockFace.FLOOR),
|
||||
GBlockstate.variant(button, true, R0, R90))
|
||||
.with(GBlockstate.when(POWERED, false, HORIZONTAL_FACING, Direction.SOUTH, BLOCK_FACE, BlockFace.FLOOR),
|
||||
GBlockstate.variant(button, true, R0, R180))
|
||||
.with(GBlockstate.when(POWERED, false, HORIZONTAL_FACING, Direction.WEST, BLOCK_FACE, BlockFace.FLOOR),
|
||||
GBlockstate.variant(button, true, R0, R270))
|
||||
// CEILING OFF
|
||||
.with(GBlockstate.when(POWERED, false, HORIZONTAL_FACING, Direction.SOUTH, BLOCK_FACE, BlockFace.CEILING),
|
||||
GBlockstate.variant(button, true, R180, R0))
|
||||
.with(GBlockstate.when(POWERED, false, HORIZONTAL_FACING, Direction.WEST, BLOCK_FACE, BlockFace.CEILING),
|
||||
GBlockstate.variant(button, true, R180, R90))
|
||||
.with(GBlockstate.when(POWERED, false, HORIZONTAL_FACING, Direction.NORTH, BLOCK_FACE, BlockFace.CEILING),
|
||||
GBlockstate.variant(button, true, R180, R180))
|
||||
.with(GBlockstate.when(POWERED, false, HORIZONTAL_FACING, Direction.EAST, BLOCK_FACE, BlockFace.CEILING),
|
||||
GBlockstate.variant(button, true, R180, R270))
|
||||
// WALL OFF
|
||||
.with(GBlockstate.when(POWERED, false, HORIZONTAL_FACING, Direction.NORTH, BLOCK_FACE, BlockFace.WALL),
|
||||
GBlockstate.variant(button, true, R90, R0))
|
||||
.with(GBlockstate.when(POWERED, false, HORIZONTAL_FACING, Direction.EAST, BLOCK_FACE, BlockFace.WALL),
|
||||
GBlockstate.variant(button, true, R90, R90))
|
||||
.with(GBlockstate.when(POWERED, false, HORIZONTAL_FACING, Direction.SOUTH, BLOCK_FACE, BlockFace.WALL),
|
||||
GBlockstate.variant(button, true, R90, R180))
|
||||
.with(GBlockstate.when(POWERED, false, HORIZONTAL_FACING, Direction.WEST, BLOCK_FACE, BlockFace.WALL),
|
||||
GBlockstate.variant(button, true, R90, R270))
|
||||
// FLOOR ON
|
||||
.with(GBlockstate.when(POWERED, true, HORIZONTAL_FACING, Direction.NORTH, BLOCK_FACE, BlockFace.FLOOR),
|
||||
GBlockstate.variant(button_pressed, true, R0, R0))
|
||||
.with(GBlockstate.when(POWERED, true, HORIZONTAL_FACING, Direction.EAST, BLOCK_FACE, BlockFace.FLOOR),
|
||||
GBlockstate.variant(button_pressed, true, R0, R90))
|
||||
.with(GBlockstate.when(POWERED, true, HORIZONTAL_FACING, Direction.SOUTH, BLOCK_FACE, BlockFace.FLOOR),
|
||||
GBlockstate.variant(button_pressed, true, R0, R180))
|
||||
.with(GBlockstate.when(POWERED, true, HORIZONTAL_FACING, Direction.WEST, BLOCK_FACE, BlockFace.FLOOR),
|
||||
GBlockstate.variant(button_pressed, true, R0, R270))
|
||||
// CEILING ON
|
||||
.with(GBlockstate.when(POWERED, true, HORIZONTAL_FACING, Direction.SOUTH, BLOCK_FACE, BlockFace.CEILING),
|
||||
GBlockstate.variant(button_pressed, true, R180, R0))
|
||||
.with(GBlockstate.when(POWERED, true, HORIZONTAL_FACING, Direction.WEST, BLOCK_FACE, BlockFace.CEILING),
|
||||
GBlockstate.variant(button_pressed, true, R180, R90))
|
||||
.with(GBlockstate.when(POWERED, true, HORIZONTAL_FACING, Direction.NORTH, BLOCK_FACE, BlockFace.CEILING),
|
||||
GBlockstate.variant(button_pressed, true, R180, R180))
|
||||
.with(GBlockstate.when(POWERED, true, HORIZONTAL_FACING, Direction.EAST, BLOCK_FACE, BlockFace.CEILING),
|
||||
GBlockstate.variant(button_pressed, true, R180, R270))
|
||||
// WALL ON
|
||||
.with(GBlockstate.when(POWERED, true, HORIZONTAL_FACING, Direction.NORTH, BLOCK_FACE, BlockFace.WALL),
|
||||
GBlockstate.variant(button_pressed, true, R90, R0))
|
||||
.with(GBlockstate.when(POWERED, true, HORIZONTAL_FACING, Direction.EAST, BLOCK_FACE, BlockFace.WALL),
|
||||
GBlockstate.variant(button_pressed, true, R90, R90))
|
||||
.with(GBlockstate.when(POWERED, true, HORIZONTAL_FACING, Direction.SOUTH, BLOCK_FACE, BlockFace.WALL),
|
||||
GBlockstate.variant(button_pressed, true, R90, R180))
|
||||
.with(GBlockstate.when(POWERED, true, HORIZONTAL_FACING, Direction.WEST, BLOCK_FACE, BlockFace.WALL),
|
||||
GBlockstate.variant(button_pressed, true, R90, R270));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,77 @@
|
||||
package fr.adrien1106.reframed.generator.block;
|
||||
|
||||
import fr.adrien1106.reframed.ReFramed;
|
||||
import fr.adrien1106.reframed.generator.GBlockstate;
|
||||
import fr.adrien1106.reframed.util.blocks.Corner;
|
||||
import net.minecraft.block.Block;
|
||||
import net.minecraft.data.client.MultipartBlockStateSupplier;
|
||||
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 net.minecraft.data.client.VariantSettings.Rotation.*;
|
||||
|
||||
public class CornerDouble {
|
||||
|
||||
|
||||
public static MultipartBlockStateSupplier getMultipart(Block block, String model_name) {
|
||||
Identifier model_id = ReFramed.id(model_name + "_special");
|
||||
Identifier side_id = ReFramed.id(model_name + "_side_special");
|
||||
return MultipartBlockStateSupplier.create(block)
|
||||
// BOTTOM
|
||||
.with(GBlockstate.when(CORNER, Corner.EAST_SOUTH_DOWN, CORNER_FACE, 2),
|
||||
GBlockstate.variant(model_id, true, R0, R0))
|
||||
.with(GBlockstate.when(CORNER, Corner.SOUTH_WEST_DOWN, CORNER_FACE, 2),
|
||||
GBlockstate.variant(model_id, true, R0, R90))
|
||||
.with(GBlockstate.when(CORNER, Corner.WEST_NORTH_DOWN, CORNER_FACE, 2),
|
||||
GBlockstate.variant(model_id, true, R0, R180))
|
||||
.with(GBlockstate.when(CORNER, Corner.NORTH_EAST_DOWN, CORNER_FACE, 2),
|
||||
GBlockstate.variant(model_id, true, R0, R270))
|
||||
// TOP
|
||||
.with(GBlockstate.when(CORNER, Corner.NORTH_EAST_UP, CORNER_FACE, 2),
|
||||
GBlockstate.variant(model_id, true, R180, R0))
|
||||
.with(GBlockstate.when(CORNER, Corner.EAST_SOUTH_UP, CORNER_FACE, 2),
|
||||
GBlockstate.variant(model_id, true, R180, R90))
|
||||
.with(GBlockstate.when(CORNER, Corner.SOUTH_WEST_UP, CORNER_FACE, 2),
|
||||
GBlockstate.variant(model_id, true, R180, R180))
|
||||
.with(GBlockstate.when(CORNER, Corner.WEST_NORTH_UP, CORNER_FACE, 2),
|
||||
GBlockstate.variant(model_id, true, R180, R270))
|
||||
// EAST
|
||||
.with(GBlockstate.when(CORNER, Corner.EAST_SOUTH_DOWN, CORNER_FACE, 0),
|
||||
GBlockstate.variant(side_id, true, R0, R0))
|
||||
.with(GBlockstate.when(CORNER, Corner.EAST_SOUTH_UP, CORNER_FACE, 0),
|
||||
GBlockstate.variant(side_id, true, R90, R0))
|
||||
.with(GBlockstate.when(CORNER, Corner.NORTH_EAST_UP, CORNER_FACE, 1),
|
||||
GBlockstate.variant(side_id, true, R180, R0))
|
||||
.with(GBlockstate.when(CORNER, Corner.NORTH_EAST_DOWN, CORNER_FACE, 1),
|
||||
GBlockstate.variant(side_id, true, R270, R0))
|
||||
// SOUTH
|
||||
.with(GBlockstate.when(CORNER, Corner.SOUTH_WEST_DOWN, CORNER_FACE, 0),
|
||||
GBlockstate.variant(side_id, true, R0, R90))
|
||||
.with(GBlockstate.when(CORNER, Corner.SOUTH_WEST_UP, CORNER_FACE, 0),
|
||||
GBlockstate.variant(side_id, true, R90, R90))
|
||||
.with(GBlockstate.when(CORNER, Corner.EAST_SOUTH_UP, CORNER_FACE, 1),
|
||||
GBlockstate.variant(side_id, true, R180, R90))
|
||||
.with(GBlockstate.when(CORNER, Corner.EAST_SOUTH_DOWN, CORNER_FACE, 1),
|
||||
GBlockstate.variant(side_id, true, R270, R90))
|
||||
// WEST
|
||||
.with(GBlockstate.when(CORNER, Corner.WEST_NORTH_DOWN, CORNER_FACE, 0),
|
||||
GBlockstate.variant(side_id, true, R0, R180))
|
||||
.with(GBlockstate.when(CORNER, Corner.WEST_NORTH_UP, CORNER_FACE, 0),
|
||||
GBlockstate.variant(side_id, true, R90, R180))
|
||||
.with(GBlockstate.when(CORNER, Corner.SOUTH_WEST_UP, CORNER_FACE, 1),
|
||||
GBlockstate.variant(side_id, true, R180, R180))
|
||||
.with(GBlockstate.when(CORNER, Corner.SOUTH_WEST_DOWN, CORNER_FACE, 1),
|
||||
GBlockstate.variant(side_id, true, R270, R180))
|
||||
// NORTH
|
||||
.with(GBlockstate.when(CORNER, Corner.NORTH_EAST_DOWN, CORNER_FACE, 0),
|
||||
GBlockstate.variant(side_id, true, R0, R270))
|
||||
.with(GBlockstate.when(CORNER, Corner.NORTH_EAST_UP, CORNER_FACE, 0),
|
||||
GBlockstate.variant(side_id, true, R90, R270))
|
||||
.with(GBlockstate.when(CORNER, Corner.WEST_NORTH_UP, CORNER_FACE, 1),
|
||||
GBlockstate.variant(side_id, true, R180, R270))
|
||||
.with(GBlockstate.when(CORNER, Corner.WEST_NORTH_DOWN, CORNER_FACE, 1),
|
||||
GBlockstate.variant(side_id, true, R270, R270))
|
||||
;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,73 @@
|
||||
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.block.Blocks;
|
||||
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.data.client.VariantSettings.Rotation.*;
|
||||
import static net.minecraft.state.property.Properties.*;
|
||||
|
||||
public class Fence implements RecipeSetter, TagGetter, 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, 4)
|
||||
.pattern("I-I")
|
||||
.pattern("I-I")
|
||||
.input('I', ReFramed.CUBE)
|
||||
.input('-', Blocks.BAMBOO)
|
||||
.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.FENCES, BlockTags.WOODEN_FENCES);
|
||||
}
|
||||
|
||||
@Override
|
||||
public BlockStateSupplier getMultipart(Block block) {
|
||||
Identifier side_on = ReFramed.id("fence_side_on_special");
|
||||
Identifier side_off = ReFramed.id("fence_side_off_special");
|
||||
return MultipartBlockStateSupplier.create(block)
|
||||
.with(GBlockstate.variant(ReFramed.id("fence_core_special"), true, R0, R0))
|
||||
// SIDE ON
|
||||
.with(GBlockstate.when(NORTH, true),
|
||||
GBlockstate.variant(side_on, true, R0, R0))
|
||||
.with(GBlockstate.when(EAST, true),
|
||||
GBlockstate.variant(side_on, true, R0, R90))
|
||||
.with(GBlockstate.when(SOUTH, true),
|
||||
GBlockstate.variant(side_on, true, R0, R180))
|
||||
.with(GBlockstate.when(WEST, true),
|
||||
GBlockstate.variant(side_on, true, R0, R270))
|
||||
// SIDE OFF
|
||||
.with(GBlockstate.when(NORTH, false),
|
||||
GBlockstate.variant(side_off, true, R0, R0))
|
||||
.with(GBlockstate.when(EAST, false),
|
||||
GBlockstate.variant(side_off, true, R0, R90))
|
||||
.with(GBlockstate.when(SOUTH, false),
|
||||
GBlockstate.variant(side_off, true, R0, R180))
|
||||
.with(GBlockstate.when(WEST, false),
|
||||
GBlockstate.variant(side_off, true, R0, R270));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,171 @@
|
||||
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.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 java.util.Map;
|
||||
|
||||
import static fr.adrien1106.reframed.generator.GBlockstate.variant;
|
||||
import static fr.adrien1106.reframed.generator.GBlockstate.when;
|
||||
import static fr.adrien1106.reframed.util.blocks.BlockProperties.EDGE;
|
||||
import static fr.adrien1106.reframed.util.blocks.BlockProperties.EDGE_FACE;
|
||||
import static fr.adrien1106.reframed.util.blocks.Edge.*;
|
||||
import static net.minecraft.data.client.VariantSettings.Rotation.*;
|
||||
import static net.minecraft.state.property.Properties.LAYERS;
|
||||
|
||||
public class HalfLayer implements RecipeSetter, BlockStateProvider {
|
||||
|
||||
@Override
|
||||
public void setRecipe(RecipeExporter exporter, ItemConvertible convertible) {
|
||||
RecipeProvider.offerStonecuttingRecipe(exporter, RecipeCategory.BUILDING_BLOCKS, convertible, ReFramed.CUBE, 16);
|
||||
ShapelessRecipeJsonBuilder
|
||||
.create(RecipeCategory.BUILDING_BLOCKS, convertible, 2)
|
||||
.input(ReFramed.LAYER)
|
||||
.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, "half_layer");
|
||||
}
|
||||
|
||||
public static MultipartBlockStateSupplier getMultipart(Block block, String layer) {
|
||||
Map<Integer, Identifier> layer_model = Map.of(
|
||||
1, ReFramed.id(layer + "_2_special"),
|
||||
2, ReFramed.id(layer + "_4_special"),
|
||||
3, ReFramed.id(layer + "_6_special"),
|
||||
4, ReFramed.id(layer + "_8_special"),
|
||||
5, ReFramed.id(layer + "_10_special"),
|
||||
6, ReFramed.id(layer + "_12_special"),
|
||||
7, ReFramed.id(layer + "_14_special"),
|
||||
8, ReFramed.id(layer + "_16_special")
|
||||
);
|
||||
Map<Integer, Identifier> layer_side = Map.of(
|
||||
1, ReFramed.id(layer + "_side_2_special"),
|
||||
2, ReFramed.id(layer + "_side_4_special"),
|
||||
3, ReFramed.id(layer + "_side_6_special"),
|
||||
4, ReFramed.id(layer + "_side_8_special"),
|
||||
5, ReFramed.id(layer + "_side_10_special"),
|
||||
6, ReFramed.id(layer + "_side_12_special"),
|
||||
7, ReFramed.id(layer + "_side_14_special"),
|
||||
8, ReFramed.id(layer + "_side_16_special")
|
||||
);
|
||||
MultipartBlockStateSupplier supplier = MultipartBlockStateSupplier.create(block);
|
||||
// DOWN
|
||||
layer_model.forEach((i, model) ->
|
||||
supplier.with(when(EDGE, DOWN_EAST, EDGE_FACE, 0, LAYERS, i),
|
||||
variant(model, true, R0, R0))
|
||||
);
|
||||
layer_model.forEach((i, model) ->
|
||||
supplier.with(when(EDGE, DOWN_SOUTH, EDGE_FACE, 0, LAYERS, i),
|
||||
variant(model, true, R0, R90))
|
||||
);
|
||||
layer_model.forEach((i, model) ->
|
||||
supplier.with(when(EDGE, WEST_DOWN, EDGE_FACE, 1, LAYERS, i),
|
||||
variant(model, true, R0, R180))
|
||||
);
|
||||
layer_model.forEach((i, model) ->
|
||||
supplier.with(when(EDGE, NORTH_DOWN, EDGE_FACE, 1, LAYERS, i),
|
||||
variant(model, true, R0, R270))
|
||||
);
|
||||
// UP
|
||||
layer_model.forEach((i, model) ->
|
||||
supplier.with(when(EDGE, EAST_UP, EDGE_FACE, 1, LAYERS, i),
|
||||
variant(model, true, R180, R0))
|
||||
);
|
||||
layer_model.forEach((i, model) ->
|
||||
supplier.with(when(EDGE, SOUTH_UP, EDGE_FACE, 1, LAYERS, i),
|
||||
variant(model, true, R180, R90))
|
||||
);
|
||||
layer_model.forEach((i, model) ->
|
||||
supplier.with(when(EDGE, UP_WEST, EDGE_FACE, 0, LAYERS, i),
|
||||
variant(model, true, R180, R180))
|
||||
);
|
||||
layer_model.forEach((i, model) ->
|
||||
supplier.with(when(EDGE, UP_NORTH, EDGE_FACE, 0, LAYERS, i),
|
||||
variant(model, true, R180, R270))
|
||||
);
|
||||
// EAST
|
||||
layer_side.forEach((i, model) ->
|
||||
supplier.with(when(EDGE, EAST_SOUTH, EDGE_FACE, 0, LAYERS, i),
|
||||
variant(model, true, R0, R0))
|
||||
);
|
||||
layer_side.forEach((i, model) ->
|
||||
supplier.with(when(EDGE, EAST_UP, EDGE_FACE, 0, LAYERS, i),
|
||||
variant(model, true, R90, R0))
|
||||
);
|
||||
layer_side.forEach((i, model) ->
|
||||
supplier.with(when(EDGE, NORTH_EAST, EDGE_FACE, 1, LAYERS, i),
|
||||
variant(model, true, R180, R0))
|
||||
);
|
||||
layer_side.forEach((i, model) ->
|
||||
supplier.with(when(EDGE, DOWN_EAST, EDGE_FACE, 1, LAYERS, i),
|
||||
variant(model, true, R270, R0))
|
||||
);
|
||||
// SOUTH
|
||||
layer_side.forEach((i, model) ->
|
||||
supplier.with(when(EDGE, SOUTH_WEST, EDGE_FACE, 0, LAYERS, i),
|
||||
variant(model, true, R0, R90))
|
||||
);
|
||||
layer_side.forEach((i, model) ->
|
||||
supplier.with(when(EDGE, SOUTH_UP, EDGE_FACE, 0, LAYERS, i),
|
||||
variant(model, true, R90, R90))
|
||||
);
|
||||
layer_side.forEach((i, model) ->
|
||||
supplier.with(when(EDGE, EAST_SOUTH, EDGE_FACE, 1, LAYERS, i),
|
||||
variant(model, true, R180, R90))
|
||||
);
|
||||
layer_side.forEach((i, model) ->
|
||||
supplier.with(when(EDGE, DOWN_SOUTH, EDGE_FACE, 1, LAYERS, i),
|
||||
variant(model, true, R270, R90))
|
||||
);
|
||||
// WEST
|
||||
layer_side.forEach((i, model) ->
|
||||
supplier.with(when(EDGE, WEST_NORTH, EDGE_FACE, 0, LAYERS, i),
|
||||
variant(model, true, R0, R180))
|
||||
);
|
||||
layer_side.forEach((i, model) ->
|
||||
supplier.with(when(EDGE, UP_WEST, EDGE_FACE, 1, LAYERS, i),
|
||||
variant(model, true, R90, R180))
|
||||
);
|
||||
layer_side.forEach((i, model) ->
|
||||
supplier.with(when(EDGE, SOUTH_WEST, EDGE_FACE, 1, LAYERS, i),
|
||||
variant(model, true, R180, R180))
|
||||
);
|
||||
layer_side.forEach((i, model) ->
|
||||
supplier.with(when(EDGE, WEST_DOWN, EDGE_FACE, 0, LAYERS, i),
|
||||
variant(model, true, R270, R180))
|
||||
);
|
||||
// NORTH
|
||||
layer_side.forEach((i, model) ->
|
||||
supplier.with(when(EDGE, NORTH_EAST, EDGE_FACE, 0, LAYERS, i),
|
||||
variant(model, true, R0, R270))
|
||||
);
|
||||
layer_side.forEach((i, model) ->
|
||||
supplier.with(when(EDGE, UP_NORTH, EDGE_FACE, 1, LAYERS, i),
|
||||
variant(model, true, R90, R270))
|
||||
);
|
||||
layer_side.forEach((i, model) ->
|
||||
supplier.with(when(EDGE, WEST_NORTH, EDGE_FACE, 1, LAYERS, i),
|
||||
variant(model, true, R180, R270))
|
||||
);
|
||||
layer_side.forEach((i, model) ->
|
||||
supplier.with(when(EDGE, NORTH_DOWN, EDGE_FACE, 0, LAYERS, i),
|
||||
variant(model, true, R270, R270))
|
||||
);
|
||||
return supplier;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,34 @@
|
||||
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 HalfSlab 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, 2)
|
||||
.input(ReFramed.SLAB)
|
||||
.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 Slab.getMultipart(block, "half_slab");
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -0,0 +1,34 @@
|
||||
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 HalfSlabsSlab 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, 1)
|
||||
.input(ReFramed.HALF_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) {
|
||||
return Slab.getMultipart(block, "half_slabs_slab");
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -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 HalfStairsCubeStair 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.SMALL_CUBE)
|
||||
.input(ReFramed.HALF_STAIR)
|
||||
.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 CornerDouble.getMultipart(block, "half_stairs_cube_stair");
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,159 @@
|
||||
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.util.blocks.Corner;
|
||||
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 static fr.adrien1106.reframed.util.blocks.BlockProperties.*;
|
||||
import static net.minecraft.data.client.VariantSettings.Rotation.*;
|
||||
import static net.minecraft.data.client.VariantSettings.Rotation.R270;
|
||||
|
||||
public class HalfStairsStepStair 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.SMALL_CUBE)
|
||||
.input(ReFramed.HALF_STAIR)
|
||||
.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_1_id = ReFramed.id("half_stairs_step_stair_1_special");
|
||||
Identifier side_1_id = ReFramed.id("half_stairs_step_stair_side_1_special");
|
||||
Identifier model_2_id = ReFramed.id("half_stairs_step_stair_2_special");
|
||||
Identifier side_2_id = ReFramed.id("half_stairs_step_stair_side_2_special");
|
||||
return MultipartBlockStateSupplier.create(block)
|
||||
// BOTTOM
|
||||
// --- 1 ---
|
||||
.with(GBlockstate.when(CORNER, Corner.EAST_SOUTH_DOWN, CORNER_FACE, 2, CORNER_FEATURE, 0),
|
||||
GBlockstate.variant(model_1_id, true, R0, R0))
|
||||
.with(GBlockstate.when(CORNER, Corner.SOUTH_WEST_DOWN, CORNER_FACE, 2, CORNER_FEATURE, 0),
|
||||
GBlockstate.variant(model_1_id, true, R0, R90))
|
||||
.with(GBlockstate.when(CORNER, Corner.WEST_NORTH_DOWN, CORNER_FACE, 2, CORNER_FEATURE, 0),
|
||||
GBlockstate.variant(model_1_id, true, R0, R180))
|
||||
.with(GBlockstate.when(CORNER, Corner.NORTH_EAST_DOWN, CORNER_FACE, 2, CORNER_FEATURE, 0),
|
||||
GBlockstate.variant(model_1_id, true, R0, R270))
|
||||
// --- 2 ---
|
||||
.with(GBlockstate.when(CORNER, Corner.EAST_SOUTH_DOWN, CORNER_FACE, 2, CORNER_FEATURE, 1),
|
||||
GBlockstate.variant(model_2_id, true, R0, R0))
|
||||
.with(GBlockstate.when(CORNER, Corner.SOUTH_WEST_DOWN, CORNER_FACE, 2, CORNER_FEATURE, 1),
|
||||
GBlockstate.variant(model_2_id, true, R0, R90))
|
||||
.with(GBlockstate.when(CORNER, Corner.WEST_NORTH_DOWN, CORNER_FACE, 2, CORNER_FEATURE, 1),
|
||||
GBlockstate.variant(model_2_id, true, R0, R180))
|
||||
.with(GBlockstate.when(CORNER, Corner.NORTH_EAST_DOWN, CORNER_FACE, 2, CORNER_FEATURE, 1),
|
||||
GBlockstate.variant(model_2_id, true, R0, R270))
|
||||
// TOP
|
||||
// --- 1 ---
|
||||
.with(GBlockstate.when(CORNER, Corner.NORTH_EAST_UP, CORNER_FACE, 2, CORNER_FEATURE, 1),
|
||||
GBlockstate.variant(model_1_id, true, R180, R0))
|
||||
.with(GBlockstate.when(CORNER, Corner.EAST_SOUTH_UP, CORNER_FACE, 2, CORNER_FEATURE, 1),
|
||||
GBlockstate.variant(model_1_id, true, R180, R90))
|
||||
.with(GBlockstate.when(CORNER, Corner.SOUTH_WEST_UP, CORNER_FACE, 2, CORNER_FEATURE, 1),
|
||||
GBlockstate.variant(model_1_id, true, R180, R180))
|
||||
.with(GBlockstate.when(CORNER, Corner.WEST_NORTH_UP, CORNER_FACE, 2, CORNER_FEATURE, 1),
|
||||
GBlockstate.variant(model_1_id, true, R180, R270))
|
||||
// --- 2 ---
|
||||
.with(GBlockstate.when(CORNER, Corner.NORTH_EAST_UP, CORNER_FACE, 2, CORNER_FEATURE, 0),
|
||||
GBlockstate.variant(model_2_id, true, R180, R0))
|
||||
.with(GBlockstate.when(CORNER, Corner.EAST_SOUTH_UP, CORNER_FACE, 2, CORNER_FEATURE, 0),
|
||||
GBlockstate.variant(model_2_id, true, R180, R90))
|
||||
.with(GBlockstate.when(CORNER, Corner.SOUTH_WEST_UP, CORNER_FACE, 2, CORNER_FEATURE, 0),
|
||||
GBlockstate.variant(model_2_id, true, R180, R180))
|
||||
.with(GBlockstate.when(CORNER, Corner.WEST_NORTH_UP, CORNER_FACE, 2, CORNER_FEATURE, 0),
|
||||
GBlockstate.variant(model_2_id, true, R180, R270))
|
||||
// EAST
|
||||
// --- 1 ---
|
||||
.with(GBlockstate.when(CORNER, Corner.EAST_SOUTH_DOWN, CORNER_FACE, 0, CORNER_FEATURE, 0),
|
||||
GBlockstate.variant(side_1_id, true, R0, R0))
|
||||
.with(GBlockstate.when(CORNER, Corner.EAST_SOUTH_UP, CORNER_FACE, 0, CORNER_FEATURE, 1),
|
||||
GBlockstate.variant(side_1_id, true, R90, R0))
|
||||
.with(GBlockstate.when(CORNER, Corner.NORTH_EAST_UP, CORNER_FACE, 1, CORNER_FEATURE, 0),
|
||||
GBlockstate.variant(side_1_id, true, R180, R0))
|
||||
.with(GBlockstate.when(CORNER, Corner.NORTH_EAST_DOWN, CORNER_FACE, 1, CORNER_FEATURE, 1),
|
||||
GBlockstate.variant(side_1_id, true, R270, R0))
|
||||
// --- 2 ---
|
||||
.with(GBlockstate.when(CORNER, Corner.EAST_SOUTH_DOWN, CORNER_FACE, 0, CORNER_FEATURE, 1),
|
||||
GBlockstate.variant(side_2_id, true, R0, R0))
|
||||
.with(GBlockstate.when(CORNER, Corner.EAST_SOUTH_UP, CORNER_FACE, 0, CORNER_FEATURE, 0),
|
||||
GBlockstate.variant(side_2_id, true, R90, R0))
|
||||
.with(GBlockstate.when(CORNER, Corner.NORTH_EAST_UP, CORNER_FACE, 1, CORNER_FEATURE, 1),
|
||||
GBlockstate.variant(side_2_id, true, R180, R0))
|
||||
.with(GBlockstate.when(CORNER, Corner.NORTH_EAST_DOWN, CORNER_FACE, 1, CORNER_FEATURE, 0),
|
||||
GBlockstate.variant(side_2_id, true, R270, R0))
|
||||
// SOUTH
|
||||
// --- 1 ---
|
||||
.with(GBlockstate.when(CORNER, Corner.SOUTH_WEST_DOWN, CORNER_FACE, 0, CORNER_FEATURE, 0),
|
||||
GBlockstate.variant(side_1_id, true, R0, R90))
|
||||
.with(GBlockstate.when(CORNER, Corner.SOUTH_WEST_UP, CORNER_FACE, 0, CORNER_FEATURE, 1),
|
||||
GBlockstate.variant(side_1_id, true, R90, R90))
|
||||
.with(GBlockstate.when(CORNER, Corner.EAST_SOUTH_UP, CORNER_FACE, 1, CORNER_FEATURE, 0),
|
||||
GBlockstate.variant(side_1_id, true, R180, R90))
|
||||
.with(GBlockstate.when(CORNER, Corner.EAST_SOUTH_DOWN, CORNER_FACE, 1, CORNER_FEATURE, 1),
|
||||
GBlockstate.variant(side_1_id, true, R270, R90))
|
||||
// --- 2 ---
|
||||
.with(GBlockstate.when(CORNER, Corner.SOUTH_WEST_DOWN, CORNER_FACE, 0, CORNER_FEATURE, 1),
|
||||
GBlockstate.variant(side_2_id, true, R0, R90))
|
||||
.with(GBlockstate.when(CORNER, Corner.SOUTH_WEST_UP, CORNER_FACE, 0, CORNER_FEATURE, 0),
|
||||
GBlockstate.variant(side_2_id, true, R90, R90))
|
||||
.with(GBlockstate.when(CORNER, Corner.EAST_SOUTH_UP, CORNER_FACE, 1, CORNER_FEATURE, 1),
|
||||
GBlockstate.variant(side_2_id, true, R180, R90))
|
||||
.with(GBlockstate.when(CORNER, Corner.EAST_SOUTH_DOWN, CORNER_FACE, 1, CORNER_FEATURE, 0),
|
||||
GBlockstate.variant(side_2_id, true, R270, R90))
|
||||
// WEST
|
||||
// --- 1 ---
|
||||
.with(GBlockstate.when(CORNER, Corner.WEST_NORTH_DOWN, CORNER_FACE, 0, CORNER_FEATURE, 0),
|
||||
GBlockstate.variant(side_1_id, true, R0, R180))
|
||||
.with(GBlockstate.when(CORNER, Corner.WEST_NORTH_UP, CORNER_FACE, 0, CORNER_FEATURE, 1),
|
||||
GBlockstate.variant(side_1_id, true, R90, R180))
|
||||
.with(GBlockstate.when(CORNER, Corner.SOUTH_WEST_UP, CORNER_FACE, 1, CORNER_FEATURE, 0),
|
||||
GBlockstate.variant(side_1_id, true, R180, R180))
|
||||
.with(GBlockstate.when(CORNER, Corner.SOUTH_WEST_DOWN, CORNER_FACE, 1, CORNER_FEATURE, 1),
|
||||
GBlockstate.variant(side_1_id, true, R270, R180))
|
||||
// --- 2 ---
|
||||
.with(GBlockstate.when(CORNER, Corner.WEST_NORTH_DOWN, CORNER_FACE, 0, CORNER_FEATURE, 1),
|
||||
GBlockstate.variant(side_2_id, true, R0, R180))
|
||||
.with(GBlockstate.when(CORNER, Corner.WEST_NORTH_UP, CORNER_FACE, 0, CORNER_FEATURE, 0),
|
||||
GBlockstate.variant(side_2_id, true, R90, R180))
|
||||
.with(GBlockstate.when(CORNER, Corner.SOUTH_WEST_UP, CORNER_FACE, 1, CORNER_FEATURE, 1),
|
||||
GBlockstate.variant(side_2_id, true, R180, R180))
|
||||
.with(GBlockstate.when(CORNER, Corner.SOUTH_WEST_DOWN, CORNER_FACE, 1, CORNER_FEATURE, 0),
|
||||
GBlockstate.variant(side_2_id, true, R270, R180))
|
||||
// NORTH
|
||||
// --- 1 ---
|
||||
.with(GBlockstate.when(CORNER, Corner.NORTH_EAST_DOWN, CORNER_FACE, 0, CORNER_FEATURE, 0),
|
||||
GBlockstate.variant(side_1_id, true, R0, R270))
|
||||
.with(GBlockstate.when(CORNER, Corner.NORTH_EAST_UP, CORNER_FACE, 0, CORNER_FEATURE, 1),
|
||||
GBlockstate.variant(side_1_id, true, R90, R270))
|
||||
.with(GBlockstate.when(CORNER, Corner.WEST_NORTH_UP, CORNER_FACE, 1, CORNER_FEATURE, 0),
|
||||
GBlockstate.variant(side_1_id, true, R180, R270))
|
||||
.with(GBlockstate.when(CORNER, Corner.WEST_NORTH_DOWN, CORNER_FACE, 1, CORNER_FEATURE, 1),
|
||||
GBlockstate.variant(side_1_id, true, R270, R270))
|
||||
// --- 2 ---
|
||||
.with(GBlockstate.when(CORNER, Corner.NORTH_EAST_DOWN, CORNER_FACE, 0, CORNER_FEATURE, 1),
|
||||
GBlockstate.variant(side_2_id, true, R0, R270))
|
||||
.with(GBlockstate.when(CORNER, Corner.NORTH_EAST_UP, CORNER_FACE, 0, CORNER_FEATURE, 0),
|
||||
GBlockstate.variant(side_2_id, true, R90, R270))
|
||||
.with(GBlockstate.when(CORNER, Corner.WEST_NORTH_UP, CORNER_FACE, 1, CORNER_FEATURE, 1),
|
||||
GBlockstate.variant(side_2_id, true, R180, R270))
|
||||
.with(GBlockstate.when(CORNER, Corner.WEST_NORTH_DOWN, CORNER_FACE, 1, CORNER_FEATURE, 0),
|
||||
GBlockstate.variant(side_2_id, true, R270, R270))
|
||||
;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,50 @@
|
||||
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 Post implements RecipeSetter, BlockStateProvider {
|
||||
|
||||
@Override
|
||||
public void setRecipe(RecipeExporter exporter, ItemConvertible convertible) {
|
||||
RecipeProvider.offerStonecuttingRecipe(exporter, RecipeCategory.BUILDING_BLOCKS, convertible, ReFramed.CUBE, 6);
|
||||
ShapedRecipeJsonBuilder
|
||||
.create(RecipeCategory.BUILDING_BLOCKS, convertible, 12)
|
||||
.pattern("I")
|
||||
.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("post_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));
|
||||
}
|
||||
}
|
||||
@@ -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 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.ShapelessRecipeJsonBuilder;
|
||||
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.data.client.VariantSettings.Rotation.*;
|
||||
import static net.minecraft.state.property.Properties.*;
|
||||
|
||||
public class PostFence implements RecipeSetter, TagGetter, BlockStateProvider {
|
||||
|
||||
@Override
|
||||
public void setRecipe(RecipeExporter exporter, ItemConvertible convertible) {
|
||||
RecipeProvider.offerStonecuttingRecipe(exporter, RecipeCategory.BUILDING_BLOCKS, convertible, ReFramed.FENCE, 1);
|
||||
ShapelessRecipeJsonBuilder
|
||||
.create(RecipeCategory.BUILDING_BLOCKS, convertible, 2)
|
||||
.input(ReFramed.FENCE, 2)
|
||||
.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.FENCES, BlockTags.WOODEN_FENCES);
|
||||
}
|
||||
|
||||
@Override
|
||||
public BlockStateSupplier getMultipart(Block block) {
|
||||
Identifier side_on = ReFramed.id("post_fence_side_special");
|
||||
Identifier side_off = ReFramed.id("fence_side_off_special");
|
||||
return MultipartBlockStateSupplier.create(block)
|
||||
.with(GBlockstate.variant(ReFramed.id("fence_core_special"), true, R0, R0))
|
||||
// SIDE ON
|
||||
.with(GBlockstate.when(NORTH, true),
|
||||
GBlockstate.variant(side_on, true, R0, R0))
|
||||
.with(GBlockstate.when(EAST, true),
|
||||
GBlockstate.variant(side_on, true, R0, R90))
|
||||
.with(GBlockstate.when(SOUTH, true),
|
||||
GBlockstate.variant(side_on, true, R0, R180))
|
||||
.with(GBlockstate.when(WEST, true),
|
||||
GBlockstate.variant(side_on, true, R0, R270))
|
||||
// SIDE OFF
|
||||
.with(GBlockstate.when(NORTH, false),
|
||||
GBlockstate.variant(side_off, true, R0, R0))
|
||||
.with(GBlockstate.when(EAST, false),
|
||||
GBlockstate.variant(side_off, true, R0, R90))
|
||||
.with(GBlockstate.when(SOUTH, false),
|
||||
GBlockstate.variant(side_off, true, R0, R180))
|
||||
.with(GBlockstate.when(WEST, false),
|
||||
GBlockstate.variant(side_off, true, R0, R270));
|
||||
}
|
||||
}
|
||||
@@ -34,7 +34,11 @@ public class Slab implements RecipeSetter, BlockStateProvider {
|
||||
|
||||
@Override
|
||||
public MultipartBlockStateSupplier getMultipart(Block block) {
|
||||
Identifier model_id = ReFramed.id("slab_special");
|
||||
return getMultipart(block, "slab");
|
||||
}
|
||||
|
||||
public static MultipartBlockStateSupplier getMultipart(Block block, String model_name) {
|
||||
Identifier model_id = ReFramed.id(model_name + "_special");
|
||||
return MultipartBlockStateSupplier.create(block)
|
||||
.with(GBlockstate.when(FACING, Direction.DOWN),
|
||||
GBlockstate.variant(model_id, true, R0, R0))
|
||||
@@ -49,4 +53,6 @@ public class Slab implements RecipeSetter, BlockStateProvider {
|
||||
.with(GBlockstate.when(FACING, Direction.EAST),
|
||||
GBlockstate.variant(model_id, true, R90, R270));
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
@@ -0,0 +1,93 @@
|
||||
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;
|
||||
import net.minecraft.util.Identifier;
|
||||
|
||||
import static fr.adrien1106.reframed.generator.GBlockstate.variant;
|
||||
import static fr.adrien1106.reframed.generator.GBlockstate.when;
|
||||
import static fr.adrien1106.reframed.util.blocks.BlockProperties.EDGE;
|
||||
import static fr.adrien1106.reframed.util.blocks.BlockProperties.EDGE_FACE;
|
||||
import static fr.adrien1106.reframed.util.blocks.Edge.*;
|
||||
import static net.minecraft.data.client.VariantSettings.Rotation.*;
|
||||
import static net.minecraft.data.client.When.anyOf;
|
||||
|
||||
public class SlabsHalfLayer 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_LAYER)
|
||||
.input(ReFramed.SLAB)
|
||||
.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 slab_model = ReFramed.id("slab_special");
|
||||
return HalfLayer.getMultipart(block, "second_half_layer")
|
||||
.with(
|
||||
anyOf(
|
||||
when(EDGE, DOWN_EAST, EDGE_FACE, 0),
|
||||
when(EDGE, DOWN_SOUTH, EDGE_FACE, 0),
|
||||
when(EDGE, WEST_DOWN, EDGE_FACE, 1),
|
||||
when(EDGE, NORTH_DOWN, EDGE_FACE, 1)
|
||||
),
|
||||
variant(slab_model, true, R0, R0))
|
||||
.with(
|
||||
anyOf(
|
||||
when(EDGE, EAST_SOUTH, EDGE_FACE, 1),
|
||||
when(EDGE, DOWN_SOUTH, EDGE_FACE, 1),
|
||||
when(EDGE, SOUTH_WEST, EDGE_FACE, 0),
|
||||
when(EDGE, SOUTH_UP, EDGE_FACE, 0)
|
||||
),
|
||||
variant(slab_model, true, R90, R0))
|
||||
.with(
|
||||
anyOf(
|
||||
when(EDGE, UP_WEST, EDGE_FACE, 0),
|
||||
when(EDGE, UP_NORTH, EDGE_FACE, 0),
|
||||
when(EDGE, EAST_UP, EDGE_FACE, 1),
|
||||
when(EDGE, SOUTH_UP, EDGE_FACE, 1)
|
||||
),
|
||||
variant(slab_model, true, R180, R0))
|
||||
.with(
|
||||
anyOf(
|
||||
when(EDGE, WEST_NORTH, EDGE_FACE, 1),
|
||||
when(EDGE, UP_NORTH, EDGE_FACE, 1),
|
||||
when(EDGE, NORTH_EAST, EDGE_FACE, 0),
|
||||
when(EDGE, NORTH_DOWN, EDGE_FACE, 0)
|
||||
),
|
||||
variant(slab_model, true, R270, R0))
|
||||
.with(
|
||||
anyOf(
|
||||
when(EDGE, SOUTH_WEST, EDGE_FACE, 1),
|
||||
when(EDGE, UP_WEST, EDGE_FACE, 1),
|
||||
when(EDGE, WEST_NORTH, EDGE_FACE, 0),
|
||||
when(EDGE, WEST_DOWN, EDGE_FACE, 0)
|
||||
),
|
||||
variant(slab_model, true, R90, R90))
|
||||
.with(
|
||||
anyOf(
|
||||
when(EDGE, NORTH_EAST, EDGE_FACE, 1),
|
||||
when(EDGE, DOWN_EAST, EDGE_FACE, 1),
|
||||
when(EDGE, EAST_SOUTH, EDGE_FACE, 0),
|
||||
when(EDGE, EAST_UP, EDGE_FACE, 0)
|
||||
),
|
||||
variant(slab_model, true, R90, R270))
|
||||
;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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 SlabsInnerStair 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.HALF_STAIR)
|
||||
.input(ReFramed.SLAB)
|
||||
.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 CornerDouble.getMultipart(block, "slabs_inner_stair");
|
||||
}
|
||||
}
|
||||
@@ -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.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 fr.adrien1106.reframed.util.blocks.BlockProperties.HALF_LAYERS;
|
||||
import static net.minecraft.data.client.VariantSettings.Rotation.*;
|
||||
import static net.minecraft.state.property.Properties.FACING;
|
||||
|
||||
public class SlabsLayer 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, 1)
|
||||
.input(ReFramed.SLAB)
|
||||
.input(ReFramed.LAYER)
|
||||
.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 = "slabs_layer_x_special";
|
||||
MultipartBlockStateSupplier supplier = MultipartBlockStateSupplier.create(block);
|
||||
for (int i = 1; i <= 4; i++) {
|
||||
Identifier model = ReFramed.id(model_pattern.replace("x", i * 2 + ""));
|
||||
supplier
|
||||
.with(GBlockstate.when(FACING, Direction.DOWN, HALF_LAYERS, i),
|
||||
GBlockstate.variant(model, true, R0, R0))
|
||||
.with(GBlockstate.when(FACING, Direction.SOUTH, HALF_LAYERS, i),
|
||||
GBlockstate.variant(model, true, R90, R0))
|
||||
.with(GBlockstate.when(FACING, Direction.UP, HALF_LAYERS, i),
|
||||
GBlockstate.variant(model, true, R180, R0))
|
||||
.with(GBlockstate.when(FACING, Direction.NORTH, HALF_LAYERS, i),
|
||||
GBlockstate.variant(model, true, R270, R0))
|
||||
.with(GBlockstate.when(FACING, Direction.WEST, HALF_LAYERS, i),
|
||||
GBlockstate.variant(model, true, R90, R90))
|
||||
.with(GBlockstate.when(FACING, Direction.EAST, HALF_LAYERS, i),
|
||||
GBlockstate.variant(model, true, R90, R270));
|
||||
}
|
||||
return supplier;
|
||||
}
|
||||
}
|
||||
@@ -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 SlabsOuterStair 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.SMALL_CUBE)
|
||||
.input(ReFramed.SLAB)
|
||||
.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 CornerDouble.getMultipart(block, "slabs_outer_stair");
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,97 @@
|
||||
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.util.blocks.Edge;
|
||||
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 static fr.adrien1106.reframed.util.blocks.BlockProperties.EDGE;
|
||||
import static fr.adrien1106.reframed.util.blocks.BlockProperties.EDGE_FACE;
|
||||
import static net.minecraft.data.client.VariantSettings.Rotation.*;
|
||||
|
||||
public class SlabsStair 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.STEP)
|
||||
.input(ReFramed.SLAB)
|
||||
.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("slabs_stair_special");
|
||||
Identifier side_id = ReFramed.id("slabs_stair_side_special");
|
||||
return MultipartBlockStateSupplier.create(block)
|
||||
// BOTTOM
|
||||
.with(GBlockstate.when(EDGE, Edge.DOWN_EAST, EDGE_FACE, 0),
|
||||
GBlockstate.variant(model_id, true, R0, R0))
|
||||
.with(GBlockstate.when(EDGE, Edge.DOWN_SOUTH, EDGE_FACE, 0),
|
||||
GBlockstate.variant(model_id, true, R0, R90))
|
||||
.with(GBlockstate.when(EDGE, Edge.WEST_DOWN, EDGE_FACE, 1),
|
||||
GBlockstate.variant(model_id, true, R0, R180))
|
||||
.with(GBlockstate.when(EDGE, Edge.NORTH_DOWN, EDGE_FACE, 1),
|
||||
GBlockstate.variant(model_id, true, R0, R270))
|
||||
// TOP
|
||||
.with(GBlockstate.when(EDGE, Edge.EAST_UP, EDGE_FACE, 1),
|
||||
GBlockstate.variant(model_id, true, R180, R0))
|
||||
.with(GBlockstate.when(EDGE, Edge.SOUTH_UP, EDGE_FACE, 1),
|
||||
GBlockstate.variant(model_id, true, R180, R90))
|
||||
.with(GBlockstate.when(EDGE, Edge.UP_WEST, EDGE_FACE, 0),
|
||||
GBlockstate.variant(model_id, true, R180, R180))
|
||||
.with(GBlockstate.when(EDGE, Edge.UP_NORTH, EDGE_FACE, 0),
|
||||
GBlockstate.variant(model_id, true, R180, R270))
|
||||
// EAST
|
||||
.with(GBlockstate.when(EDGE, Edge.EAST_SOUTH, EDGE_FACE, 0),
|
||||
GBlockstate.variant(side_id, true, R0, R0))
|
||||
.with(GBlockstate.when(EDGE, Edge.EAST_UP, EDGE_FACE, 0),
|
||||
GBlockstate.variant(side_id, true, R90, R0))
|
||||
.with(GBlockstate.when(EDGE, Edge.NORTH_EAST, EDGE_FACE, 1),
|
||||
GBlockstate.variant(side_id, true, R180, R0))
|
||||
.with(GBlockstate.when(EDGE, Edge.DOWN_EAST, EDGE_FACE, 1),
|
||||
GBlockstate.variant(side_id, true, R270, R0))
|
||||
// SOUTH
|
||||
.with(GBlockstate.when(EDGE, Edge.SOUTH_WEST, EDGE_FACE, 0),
|
||||
GBlockstate.variant(side_id, true, R0, R90))
|
||||
.with(GBlockstate.when(EDGE, Edge.SOUTH_UP, EDGE_FACE, 0),
|
||||
GBlockstate.variant(side_id, true, R90, R90))
|
||||
.with(GBlockstate.when(EDGE, Edge.EAST_SOUTH, EDGE_FACE, 1),
|
||||
GBlockstate.variant(side_id, true, R180, R90))
|
||||
.with(GBlockstate.when(EDGE, Edge.DOWN_SOUTH, EDGE_FACE, 1),
|
||||
GBlockstate.variant(side_id, true, R270, R90))
|
||||
// WEST
|
||||
.with(GBlockstate.when(EDGE, Edge.WEST_NORTH, EDGE_FACE, 0),
|
||||
GBlockstate.variant(side_id, true, R0, R180))
|
||||
.with(GBlockstate.when(EDGE, Edge.UP_WEST, EDGE_FACE, 1),
|
||||
GBlockstate.variant(side_id, true, R90, R180))
|
||||
.with(GBlockstate.when(EDGE, Edge.SOUTH_WEST, EDGE_FACE, 1),
|
||||
GBlockstate.variant(side_id, true, R180, R180))
|
||||
.with(GBlockstate.when(EDGE, Edge.WEST_DOWN, EDGE_FACE, 0),
|
||||
GBlockstate.variant(side_id, true, R270, R180))
|
||||
// NORTH
|
||||
.with(GBlockstate.when(EDGE, Edge.NORTH_EAST, EDGE_FACE, 0),
|
||||
GBlockstate.variant(side_id, true, R0, R270))
|
||||
.with(GBlockstate.when(EDGE, Edge.UP_NORTH, EDGE_FACE, 1),
|
||||
GBlockstate.variant(side_id, true, R90, R270))
|
||||
.with(GBlockstate.when(EDGE, Edge.WEST_NORTH, EDGE_FACE, 1),
|
||||
GBlockstate.variant(side_id, true, R180, R270))
|
||||
.with(GBlockstate.when(EDGE, Edge.NORTH_DOWN, EDGE_FACE, 0),
|
||||
GBlockstate.variant(side_id, true, R270, R270))
|
||||
;
|
||||
}
|
||||
}
|
||||
@@ -2,23 +2,15 @@ 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 {
|
||||
|
||||
@@ -35,35 +27,6 @@ public class SmallCubesStep implements RecipeSetter, BlockStateProvider {
|
||||
|
||||
@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));
|
||||
return Step.getMultipart(block, "small_cubes_step", "small_cubes_step_reverse");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -36,17 +36,26 @@ public class Step implements RecipeSetter, BlockStateProvider {
|
||||
|
||||
@Override
|
||||
public BlockStateSupplier getMultipart(Block block) {
|
||||
Identifier model_id = ReFramed.id("step_special");
|
||||
return getMultipart(block, "step");
|
||||
}
|
||||
|
||||
public static BlockStateSupplier getMultipart(Block block, String model_name) {
|
||||
return getMultipart(block, model_name, model_name);
|
||||
}
|
||||
|
||||
public static BlockStateSupplier getMultipart(Block block, String model_name, String reverse_model_name) {
|
||||
Identifier model_id = ReFramed.id(model_name + "_special");
|
||||
Identifier reverse_model_id = ReFramed.id(reverse_model_name + "_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))
|
||||
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(model_id, true, R0, R180))
|
||||
GBlockstate.variant(reverse_model_id, true, R0, R180))
|
||||
/* Y AXIS */
|
||||
.with(GBlockstate.when(EDGE, EAST_SOUTH),
|
||||
GBlockstate.variant(model_id, true, R90, R0))
|
||||
@@ -58,11 +67,11 @@ public class Step implements RecipeSetter, BlockStateProvider {
|
||||
GBlockstate.variant(model_id, true, R90, R270))
|
||||
/* Z AXIS */
|
||||
.with(GBlockstate.when(EDGE, DOWN_SOUTH),
|
||||
GBlockstate.variant(model_id, true, R0, R90))
|
||||
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(model_id, true, R180, R270))
|
||||
GBlockstate.variant(reverse_model_id, true, R180, R270))
|
||||
.with(GBlockstate.when(EDGE, SOUTH_UP),
|
||||
GBlockstate.variant(model_id, true, R180, R90));
|
||||
}
|
||||
|
||||
@@ -0,0 +1,34 @@
|
||||
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.ShapedRecipeJsonBuilder;
|
||||
import net.minecraft.item.ItemConvertible;
|
||||
import net.minecraft.recipe.book.RecipeCategory;
|
||||
|
||||
public class StepsCross 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, 8)
|
||||
.pattern(" I")
|
||||
.pattern("I ")
|
||||
.input('I', ReFramed.STEP)
|
||||
.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 Step.getMultipart(block, "steps_cross");
|
||||
}
|
||||
}
|
||||
@@ -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.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 net.minecraft.data.client.VariantSettings.Rotation.*;
|
||||
|
||||
public class StepsHalfLayer 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.HALF_LAYER)
|
||||
.input(ReFramed.STEP)
|
||||
.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 step_model = ReFramed.id("step_special");
|
||||
return HalfLayer.getMultipart(block, "second_half_layer")
|
||||
/* X AXIS */
|
||||
.with(GBlockstate.when(EDGE, DOWN_EAST),
|
||||
GBlockstate.variant(step_model, true, R0, R0))
|
||||
.with(GBlockstate.when(EDGE, EAST_UP),
|
||||
GBlockstate.variant(step_model, true, R180, R0))
|
||||
.with(GBlockstate.when(EDGE, UP_WEST),
|
||||
GBlockstate.variant(step_model, true, R180, R180))
|
||||
.with(GBlockstate.when(EDGE, WEST_DOWN),
|
||||
GBlockstate.variant(step_model, true, R0, R180))
|
||||
/* Y AXIS */
|
||||
.with(GBlockstate.when(EDGE, EAST_SOUTH),
|
||||
GBlockstate.variant(step_model, true, R90, R0))
|
||||
.with(GBlockstate.when(EDGE, SOUTH_WEST),
|
||||
GBlockstate.variant(step_model, true, R90, R90))
|
||||
.with(GBlockstate.when(EDGE, WEST_NORTH),
|
||||
GBlockstate.variant(step_model, true, R90, R180))
|
||||
.with(GBlockstate.when(EDGE, NORTH_EAST),
|
||||
GBlockstate.variant(step_model, true, R90, R270))
|
||||
/* Z AXIS */
|
||||
.with(GBlockstate.when(EDGE, DOWN_SOUTH),
|
||||
GBlockstate.variant(step_model, true, R0, R90))
|
||||
.with(GBlockstate.when(EDGE, NORTH_DOWN),
|
||||
GBlockstate.variant(step_model, true, R0, R270))
|
||||
.with(GBlockstate.when(EDGE, UP_NORTH),
|
||||
GBlockstate.variant(step_model, true, R180, R270))
|
||||
.with(GBlockstate.when(EDGE, SOUTH_UP),
|
||||
GBlockstate.variant(step_model, true, R180, R90))
|
||||
;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -9,7 +9,7 @@ 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.data.server.recipe.ShapedRecipeJsonBuilder;
|
||||
import net.minecraft.item.ItemConvertible;
|
||||
import net.minecraft.recipe.book.RecipeCategory;
|
||||
import net.minecraft.util.Identifier;
|
||||
@@ -25,9 +25,10 @@ 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
|
||||
ShapedRecipeJsonBuilder
|
||||
.create(RecipeCategory.BUILDING_BLOCKS, convertible)
|
||||
.input(ReFramed.STEP, 2)
|
||||
.pattern("II")
|
||||
.input('I', ReFramed.STEP)
|
||||
.criterion(FabricRecipeProvider.hasItem(ReFramed.CUBE), FabricRecipeProvider.conditionsFromItem(ReFramed.CUBE))
|
||||
.criterion(FabricRecipeProvider.hasItem(convertible), FabricRecipeProvider.conditionsFromItem(convertible))
|
||||
.offerTo(exporter);
|
||||
|
||||
@@ -74,7 +74,14 @@ public class ReFramedBlueprintWrittenItem extends Item {
|
||||
stacks.stream().map(inventory::getSlotWithStack).forEach(index -> inventory.removeStack(index, 1));
|
||||
player.playSound(SoundEvents.ENTITY_ITEM_PICKUP, 0.5f, 0.5f);
|
||||
}
|
||||
frame_entity.readNbt(tag);
|
||||
for (int i = 1; tag.contains(BLOCKSTATE_KEY + i); i++) {
|
||||
BlockState state = NbtHelper.toBlockState(
|
||||
Registries.BLOCK.getReadOnlyWrapper(),
|
||||
tag.getCompound(BLOCKSTATE_KEY + i)
|
||||
);
|
||||
frame_entity.setTheme(state, i);
|
||||
}
|
||||
if (world.isClient) ReFramed.chunkRerenderProxy.accept(world, pos);
|
||||
world.playSound(player, player.getBlockPos(), SoundEvents.ITEM_BOOK_PAGE_TURN, SoundCategory.PLAYERS);
|
||||
|
||||
return ActionResult.SUCCESS;
|
||||
|
||||
@@ -43,7 +43,7 @@ public class ReFramedHammerItem extends Item {
|
||||
world.playSound(player, pos, SoundEvents.ENTITY_ITEM_PICKUP, SoundCategory.BLOCKS, 1f, 1.1f);
|
||||
}
|
||||
frame_entity.setTheme(Blocks.AIR.getDefaultState(), theme_index);
|
||||
ReFramed.chunkRerenderProxy.accept(world, pos);
|
||||
if (world.isClient) ReFramed.chunkRerenderProxy.accept(world, pos);
|
||||
return ActionResult.SUCCESS;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -52,7 +52,7 @@ public class ReFramedScrewdriverItem extends Item {
|
||||
case Z -> Direction.Axis.X;
|
||||
}
|
||||
), theme_index);
|
||||
ReFramed.chunkRerenderProxy.accept(world, pos);
|
||||
if (world.isClient) ReFramed.chunkRerenderProxy.accept(world, pos);
|
||||
return ActionResult.SUCCESS;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,6 +2,7 @@ package fr.adrien1106.reframed.mixin;
|
||||
|
||||
import com.llamalad7.mixinextras.sugar.Local;
|
||||
import com.llamalad7.mixinextras.sugar.ref.LocalRef;
|
||||
import fr.adrien1106.reframed.block.ReFramedBlock;
|
||||
import net.minecraft.block.Block;
|
||||
import net.minecraft.block.BlockEntityProvider;
|
||||
import net.minecraft.entity.player.PlayerEntity;
|
||||
@@ -9,6 +10,7 @@ import net.minecraft.item.BlockItem;
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.nbt.NbtCompound;
|
||||
import net.minecraft.nbt.NbtHelper;
|
||||
import net.minecraft.state.property.Properties;
|
||||
import net.minecraft.util.math.BlockPos;
|
||||
import net.minecraft.world.World;
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
@@ -30,10 +32,15 @@ public class BlockItemMixin {
|
||||
)
|
||||
)
|
||||
private static void placeBlockWithOffHandCamo(World world, PlayerEntity player, BlockPos pos, ItemStack stack, CallbackInfoReturnable<Boolean> cir, @Local LocalRef<NbtCompound> compound) {
|
||||
if (compound.get() != null
|
||||
if (player == null
|
||||
|| compound.get() != null
|
||||
|| player.getOffHandStack().isEmpty()
|
||||
|| player.getMainHandStack().isEmpty()
|
||||
|| !(player.getMainHandStack().getItem() instanceof BlockItem frame)
|
||||
|| !(frame.getBlock() instanceof ReFramedBlock)
|
||||
|| !(player.getOffHandStack().getItem() instanceof BlockItem block)
|
||||
|| block.getBlock() instanceof BlockEntityProvider
|
||||
|| (world.getBlockState(pos).contains(Properties.LAYERS) && world.getBlockState(pos).get(Properties.LAYERS) > 1)
|
||||
|| !Block.isShapeFullCube(block.getBlock().getDefaultState().getCollisionShape(world, pos))
|
||||
) return;
|
||||
NbtCompound new_comp = new NbtCompound();
|
||||
|
||||
@@ -17,7 +17,7 @@ public class CompatMixinPlugin implements IMixinConfigPlugin {
|
||||
|
||||
private static final FabricLoader LOADER = FabricLoader.getInstance();
|
||||
private static final Logger LOGGER = LoggerFactory.getLogger("ReFramed MIXIN");
|
||||
private static final List<String> COMPAT_MOD = List.of("athena", "indium", "sodium", "special-model-loader", "continuity");
|
||||
private static final List<String> COMPAT_MOD = List.of("athena", "indium", "sodium", "special-model-loader", "continuity", "axiom");
|
||||
private static final Map<String, Supplier<Boolean>> CONDITIONS = new HashMap<>();
|
||||
static {
|
||||
CONDITIONS.put("fr.adrien1106.reframed.mixin.compat.AthenaBakedModelMixin", () -> LOADER.isModLoaded(COMPAT_MOD.get(0)));
|
||||
@@ -26,13 +26,26 @@ public class CompatMixinPlugin implements IMixinConfigPlugin {
|
||||
CONDITIONS.put("fr.adrien1106.reframed.mixin.render.BlockRenderInfoMixin", () -> !LOADER.isModLoaded(COMPAT_MOD.get(1)));
|
||||
CONDITIONS.put("fr.adrien1106.reframed.mixin.render.AbstractBlockRenderContextMixin", () -> !LOADER.isModLoaded(COMPAT_MOD.get(1)));
|
||||
CONDITIONS.put("fr.adrien1106.reframed.mixin.compat.IndiumTerrainRenderContextMixin", () -> LOADER.isModLoaded(COMPAT_MOD.get(1)));
|
||||
CONDITIONS.put("fr.adrien1106.reframed.mixin.compat.IndiumTerrainBlockRenderInfoMixin", () -> LOADER.isModLoaded(COMPAT_MOD.get(1)));
|
||||
CONDITIONS.put("fr.adrien1106.reframed.mixin.compat.IndiumAbstractBlockRenderContextMixin", () -> LOADER.isModLoaded(COMPAT_MOD.get(1)));
|
||||
CONDITIONS.put("fr.adrien1106.reframed.mixin.compat.IndiumBlockRenderInfoMixin", () -> LOADER.isModLoaded(COMPAT_MOD.get(1)));
|
||||
CONDITIONS.put("fr.adrien1106.reframed.mixin.compat.IndiumNonTerrainBlockRenderContextMixin", () -> LOADER.isModLoaded(COMPAT_MOD.get(1)));
|
||||
CONDITIONS.put("fr.adrien1106.reframed.mixin.render.BlockRenderContextMixin", () -> !LOADER.isModLoaded(COMPAT_MOD.get(1)));
|
||||
CONDITIONS.put("fr.adrien1106.reframed.mixin.compat.SodiumBlockOcclusionCacheMixin", () -> LOADER.isModLoaded(COMPAT_MOD.get(2)));
|
||||
CONDITIONS.put("fr.adrien1106.reframed.mixin.render.FluidRendererMixin", () -> !LOADER.isModLoaded(COMPAT_MOD.get(2)));
|
||||
CONDITIONS.put("fr.adrien1106.reframed.mixin.compat.SodiumFluidRendererMixin", () -> LOADER.isModLoaded(COMPAT_MOD.get(2)));
|
||||
CONDITIONS.put("fr.adrien1106.reframed.mixin.compat.ContinuityConnectionPredicateMixin", () -> LOADER.isModLoaded(COMPAT_MOD.get(4)));
|
||||
CONDITIONS.put("fr.adrien1106.reframed.mixin.compat.ContinuityCTMBakedModelMixin", () -> LOADER.isModLoaded(COMPAT_MOD.get(4)));
|
||||
CONDITIONS.put("fr.adrien1106.reframed.mixin.compat.ContinuityCTMQuadTransformMixin", () -> LOADER.isModLoaded(COMPAT_MOD.get(4)));
|
||||
CONDITIONS.put("fr.adrien1106.reframed.mixin.compat.ContinuityModelWrappingHandlerMixin", () -> LOADER.isModLoaded(COMPAT_MOD.get(4)));
|
||||
CONDITIONS.put("fr.adrien1106.reframed.mixin.compat.AxiomChunkedBlockRegionMixin", () -> LOADER.isModLoaded(COMPAT_MOD.get(5)));
|
||||
CONDITIONS.put("fr.adrien1106.reframed.mixin.compat.AxiomClientBlockEntitySerializerMixin", () -> LOADER.isModLoaded(COMPAT_MOD.get(5)));
|
||||
CONDITIONS.put("fr.adrien1106.reframed.mixin.compat.AxiomClipboardMixin", () -> LOADER.isModLoaded(COMPAT_MOD.get(5)));
|
||||
CONDITIONS.put("fr.adrien1106.reframed.mixin.compat.AxiomCloneBuilderToolMixin", () -> LOADER.isModLoaded(COMPAT_MOD.get(5)));
|
||||
CONDITIONS.put("fr.adrien1106.reframed.mixin.compat.AxiomPlacementMixin", () -> LOADER.isModLoaded(COMPAT_MOD.get(5)));
|
||||
CONDITIONS.put("fr.adrien1106.reframed.mixin.compat.AxiomMappedBlockAndTintGetterMixin", () -> LOADER.isModLoaded(COMPAT_MOD.get(5)));
|
||||
CONDITIONS.put("fr.adrien1106.reframed.mixin.compat.AxiomMoveBuilderToolMixin", () -> LOADER.isModLoaded(COMPAT_MOD.get(5)));
|
||||
CONDITIONS.put("fr.adrien1106.reframed.mixin.compat.AxiomScale3xMixin", () -> LOADER.isModLoaded(COMPAT_MOD.get(5)));
|
||||
CONDITIONS.put("fr.adrien1106.reframed.mixin.compat.AxiomRotSpriteMixin", () -> LOADER.isModLoaded(COMPAT_MOD.get(5)));
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -0,0 +1,166 @@
|
||||
package fr.adrien1106.reframed.mixin.compat;
|
||||
|
||||
import com.llamalad7.mixinextras.sugar.Local;
|
||||
import com.moulberry.axiom.render.regions.ChunkedBlockRegion;
|
||||
import com.moulberry.axiom.utils.IntMatrix;
|
||||
import com.moulberry.axiom.world_modification.CompressedBlockEntity;
|
||||
import fr.adrien1106.reframed.client.model.MultiRetexturableModel;
|
||||
import fr.adrien1106.reframed.client.model.RetexturingBakedModel;
|
||||
import fr.adrien1106.reframed.util.DefaultList;
|
||||
import fr.adrien1106.reframed.util.mixin.IAxiomChunkedBlockRegionMixin;
|
||||
import fr.adrien1106.reframed.util.mixin.IMultipartBakedModelMixin;
|
||||
import fr.adrien1106.reframed.util.mixin.ThemedBlockEntity;
|
||||
import it.unimi.dsi.fastutil.longs.Long2ObjectMap;
|
||||
import net.minecraft.block.BlockState;
|
||||
import net.minecraft.block.Blocks;
|
||||
import net.minecraft.block.entity.BlockEntity;
|
||||
import net.minecraft.client.render.BufferBuilder;
|
||||
import net.minecraft.client.render.Camera;
|
||||
import net.minecraft.client.render.OverlayTexture;
|
||||
import net.minecraft.client.render.block.BlockRenderManager;
|
||||
import net.minecraft.client.render.model.BakedModel;
|
||||
import net.minecraft.client.util.math.MatrixStack;
|
||||
import net.minecraft.nbt.NbtCompound;
|
||||
import net.minecraft.util.math.BlockPos;
|
||||
import net.minecraft.util.math.Direction;
|
||||
import net.minecraft.util.math.Vec3d;
|
||||
import net.minecraft.util.math.random.Random;
|
||||
import net.minecraft.world.BlockRenderView;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.joml.Matrix4f;
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
import org.spongepowered.asm.mixin.Shadow;
|
||||
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.callback.CallbackInfo;
|
||||
import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
import static fr.adrien1106.reframed.block.ReFramedEntity.BLOCKSTATE_KEY;
|
||||
|
||||
@Mixin(ChunkedBlockRegion.class) // TODO: Look here for better rotation/flip support
|
||||
public abstract class AxiomChunkedBlockRegionMixin implements IAxiomChunkedBlockRegionMixin {
|
||||
|
||||
@Shadow public abstract BlockState getBlockState(BlockPos pos);
|
||||
|
||||
@Shadow public abstract @Nullable BlockEntity getBlockEntity(BlockPos pos);
|
||||
|
||||
@Unique
|
||||
private IntMatrix transform;
|
||||
@Unique
|
||||
private IntMatrix inverse_transform;
|
||||
@Unique
|
||||
private Long2ObjectMap<CompressedBlockEntity> block_entities;
|
||||
|
||||
@Unique
|
||||
private static boolean isFrameModel(BakedModel model) {
|
||||
return model instanceof RetexturingBakedModel || model instanceof MultiRetexturableModel;
|
||||
}
|
||||
|
||||
@Unique
|
||||
private static List<BakedModel> getModels(BakedModel model, BlockState state) {
|
||||
if (isFrameModel(model))
|
||||
return List.of(model);
|
||||
else if (model instanceof IMultipartBakedModelMixin mpm)
|
||||
return mpm.getModels(state).stream().filter(AxiomChunkedBlockRegionMixin::isFrameModel).toList();
|
||||
else
|
||||
return List.of();
|
||||
}
|
||||
|
||||
@Inject(
|
||||
method = "renderBlock",
|
||||
at = @At(
|
||||
value = "INVOKE_ASSIGN",
|
||||
target = "Lnet/minecraft/client/render/block/BlockRenderManager;getModel(Lnet/minecraft/block/BlockState;)Lnet/minecraft/client/render/model/BakedModel;",
|
||||
shift = At.Shift.AFTER
|
||||
),
|
||||
cancellable = true)
|
||||
private static void onRenderBlock(BufferBuilder blockBuilder, BlockRenderManager renderer, BlockPos.Mutable pos, Random rand, MatrixStack matrices, BlockRenderView world, Matrix4f currentPoseMatrix, Matrix4f basePoseMatrix, int x, int y, int z, BlockState state, boolean useAmbientOcclusion, CallbackInfo ci, @Local BakedModel model) {
|
||||
List<BakedModel> models;
|
||||
if ((models = getModels(model, state)).isEmpty()) return;
|
||||
|
||||
DefaultList<BlockState> themes = new DefaultList<>(
|
||||
Blocks.AIR.getDefaultState(),
|
||||
world.getBlockEntity(pos) instanceof ThemedBlockEntity themed
|
||||
? themed.getThemes()
|
||||
: List.of()
|
||||
);
|
||||
models.stream().flatMap(m -> m instanceof MultiRetexturableModel mm
|
||||
? mm.models().stream()
|
||||
: Stream.of((RetexturingBakedModel)m)
|
||||
).forEach(m -> {
|
||||
m.setCamo(world, themes.get(m.getThemeIndex() - 1), pos);
|
||||
if (useAmbientOcclusion && state.getLuminance() == 0 && m.useAmbientOcclusion()) renderer.getModelRenderer()
|
||||
.renderSmooth(world, m, state, pos, matrices, blockBuilder, true, rand, state.getRenderingSeed(pos), OverlayTexture.DEFAULT_UV);
|
||||
else renderer.getModelRenderer()
|
||||
.renderFlat(world, m, state, pos, matrices, blockBuilder, true, rand, state.getRenderingSeed(pos), OverlayTexture.DEFAULT_UV);
|
||||
});
|
||||
ci.cancel();
|
||||
}
|
||||
|
||||
@Inject(
|
||||
method = "getBlockEntity",
|
||||
at = @At("HEAD"),
|
||||
cancellable = true
|
||||
)
|
||||
private void onGetBlockEntity(BlockPos pos, CallbackInfoReturnable<BlockEntity> cir) {
|
||||
if (inverse_transform == null || block_entities == null) return;
|
||||
long key = BlockPos.asLong(
|
||||
inverse_transform.transformX(pos.getX(), pos.getY(), pos.getZ()),
|
||||
inverse_transform.transformY(pos.getX(), pos.getY(), pos.getZ()),
|
||||
inverse_transform.transformZ(pos.getX(), pos.getY(), pos.getZ())
|
||||
);
|
||||
NbtCompound compound;
|
||||
if (!block_entities.containsKey(key)
|
||||
|| !(compound = block_entities.get(key).decompress()).contains(BLOCKSTATE_KEY + 1)
|
||||
) return;
|
||||
cir.setReturnValue(new ThemedBlockEntity(compound, pos, getBlockState(pos)));
|
||||
}
|
||||
|
||||
@Inject(
|
||||
method = "uploadDirty",
|
||||
at = @At("HEAD")
|
||||
)
|
||||
private void onUploadDirty(Camera camera, Vec3d translation, boolean canResort, boolean canUseAmbientOcclusion, CallbackInfo ci) {
|
||||
if (transform == null) inverse_transform = new IntMatrix();
|
||||
else inverse_transform = transform.copy();
|
||||
inverse_transform.invert();
|
||||
}
|
||||
|
||||
@Inject(
|
||||
method = "flip",
|
||||
at = @At("RETURN")
|
||||
)
|
||||
private void onFlip(Direction.Axis axis, CallbackInfoReturnable<ChunkedBlockRegion> cir) {
|
||||
((IAxiomChunkedBlockRegionMixin) cir.getReturnValue()).setTransform(transform, block_entities);
|
||||
}
|
||||
|
||||
@Inject(
|
||||
method = "rotate",
|
||||
at = @At("RETURN")
|
||||
)
|
||||
private void onRotate(Direction.Axis axis, int count, CallbackInfoReturnable<ChunkedBlockRegion> cir) {
|
||||
((IAxiomChunkedBlockRegionMixin) cir.getReturnValue()).setTransform(transform, block_entities);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setTransform(IntMatrix transform, Long2ObjectMap<CompressedBlockEntity> block_entities) {
|
||||
this.transform = transform;
|
||||
this.block_entities = block_entities;
|
||||
}
|
||||
|
||||
@Override
|
||||
public IntMatrix getTransform() {
|
||||
return transform;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Long2ObjectMap<CompressedBlockEntity> getBlockEntities() {
|
||||
return block_entities;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -0,0 +1,26 @@
|
||||
package fr.adrien1106.reframed.mixin.compat;
|
||||
|
||||
import com.moulberry.axiom.world_modification.ClientBlockEntitySerializer;
|
||||
import fr.adrien1106.reframed.util.blocks.ThemeableBlockEntity;
|
||||
import net.minecraft.block.entity.BlockEntity;
|
||||
import net.minecraft.nbt.NbtCompound;
|
||||
import net.minecraft.registry.RegistryWrapper;
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
import org.spongepowered.asm.mixin.injection.At;
|
||||
import org.spongepowered.asm.mixin.injection.Inject;
|
||||
import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
|
||||
|
||||
@Mixin(ClientBlockEntitySerializer.class)
|
||||
public class AxiomClientBlockEntitySerializerMixin {
|
||||
|
||||
@Inject(
|
||||
method = "serialize",
|
||||
at = @At("HEAD"),
|
||||
remap = false,
|
||||
cancellable = true
|
||||
)
|
||||
private static void serialize(BlockEntity blockEntity, RegistryWrapper.WrapperLookup provider, CallbackInfoReturnable<NbtCompound> cir) {
|
||||
if (!(blockEntity instanceof ThemeableBlockEntity)) return;
|
||||
cir.setReturnValue(blockEntity.createNbt());
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,25 @@
|
||||
package fr.adrien1106.reframed.mixin.compat;
|
||||
|
||||
import com.moulberry.axiom.clipboard.Clipboard;
|
||||
import com.moulberry.axiom.clipboard.ClipboardObject;
|
||||
import com.moulberry.axiom.utils.IntMatrix;
|
||||
import fr.adrien1106.reframed.util.mixin.IAxiomChunkedBlockRegionMixin;
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
import org.spongepowered.asm.mixin.injection.At;
|
||||
import org.spongepowered.asm.mixin.injection.Inject;
|
||||
import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
|
||||
|
||||
@Mixin(Clipboard.class)
|
||||
public class AxiomClipboardMixin {
|
||||
|
||||
@Inject(
|
||||
method = "setClipboard(Lcom/moulberry/axiom/clipboard/ClipboardObject;)I",
|
||||
at = @At(
|
||||
value = "TAIL"
|
||||
),
|
||||
remap = false
|
||||
)
|
||||
private void onInit(ClipboardObject object, CallbackInfoReturnable<Integer> cir) {
|
||||
((IAxiomChunkedBlockRegionMixin) object.blockRegion()).setTransform(new IntMatrix(), object.blockEntities());
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,38 @@
|
||||
package fr.adrien1106.reframed.mixin.compat;
|
||||
|
||||
import com.moulberry.axiom.buildertools.CloneBuilderTool;
|
||||
import com.moulberry.axiom.clipboard.SelectionBuffer;
|
||||
import com.moulberry.axiom.render.regions.ChunkedBlockRegion;
|
||||
import com.moulberry.axiom.utils.IntMatrix;
|
||||
import com.moulberry.axiom.world_modification.CompressedBlockEntity;
|
||||
import fr.adrien1106.reframed.util.mixin.IAxiomChunkedBlockRegionMixin;
|
||||
import it.unimi.dsi.fastutil.longs.Long2ObjectMap;
|
||||
import org.spongepowered.asm.mixin.Final;
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
import org.spongepowered.asm.mixin.Shadow;
|
||||
import org.spongepowered.asm.mixin.injection.At;
|
||||
import org.spongepowered.asm.mixin.injection.Inject;
|
||||
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
|
||||
|
||||
@Mixin(CloneBuilderTool.class)
|
||||
public class AxiomCloneBuilderToolMixin {
|
||||
|
||||
@Shadow(remap = false) private ChunkedBlockRegion blockRegion;
|
||||
|
||||
@Shadow(remap = false) @Final private IntMatrix transformMatrix;
|
||||
|
||||
@Shadow(remap = false) private Long2ObjectMap<CompressedBlockEntity> blockEntities;
|
||||
|
||||
@Inject(
|
||||
method = "lambda$initiateClone$0",
|
||||
at = @At(
|
||||
value = "INVOKE_ASSIGN",
|
||||
target = "Lcom/moulberry/axiom/clipboard/SelectionBuffer$CopyResult;blockEntities()Lit/unimi/dsi/fastutil/longs/Long2ObjectMap;",
|
||||
shift = At.Shift.AFTER
|
||||
),
|
||||
remap = false
|
||||
)
|
||||
private void onInitiateClone(int copyId, int offsetX, int offsetY, int offsetZ, SelectionBuffer.CopyResult copyResult, CallbackInfo ci) {
|
||||
((IAxiomChunkedBlockRegionMixin) blockRegion).setTransform(transformMatrix, blockEntities);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,31 @@
|
||||
package fr.adrien1106.reframed.mixin.compat;
|
||||
|
||||
import fr.adrien1106.reframed.block.ReFramedEntity;
|
||||
import net.minecraft.block.entity.BlockEntity;
|
||||
import net.minecraft.util.math.BlockPos;
|
||||
import net.minecraft.world.World;
|
||||
import org.spongepowered.asm.mixin.Final;
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
import org.spongepowered.asm.mixin.Shadow;
|
||||
import org.spongepowered.asm.mixin.injection.At;
|
||||
import org.spongepowered.asm.mixin.injection.Inject;
|
||||
import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
|
||||
|
||||
@Mixin(targets = "com.moulberry.axiom.render.ChunkRenderOverrider$MappedBlockAndTintGetter")
|
||||
public class AxiomMappedBlockAndTintGetterMixin {
|
||||
|
||||
@Shadow @Final private World level;
|
||||
|
||||
@Inject(
|
||||
method = "getBlockEntity",
|
||||
at = @At(
|
||||
value = "RETURN"
|
||||
),
|
||||
cancellable = true
|
||||
)
|
||||
private void onGetBlockEntity(BlockPos pos, CallbackInfoReturnable<BlockEntity> cir) {
|
||||
if (!(level.getBlockEntity(pos) instanceof ReFramedEntity frame_entity)) return;
|
||||
cir.setReturnValue(frame_entity);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,38 @@
|
||||
package fr.adrien1106.reframed.mixin.compat;
|
||||
|
||||
import com.moulberry.axiom.buildertools.MoveBuilderTool;
|
||||
import com.moulberry.axiom.clipboard.SelectionBuffer;
|
||||
import com.moulberry.axiom.render.regions.ChunkedBlockRegion;
|
||||
import com.moulberry.axiom.utils.IntMatrix;
|
||||
import com.moulberry.axiom.world_modification.CompressedBlockEntity;
|
||||
import fr.adrien1106.reframed.util.mixin.IAxiomChunkedBlockRegionMixin;
|
||||
import it.unimi.dsi.fastutil.longs.Long2ObjectMap;
|
||||
import org.spongepowered.asm.mixin.Final;
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
import org.spongepowered.asm.mixin.Shadow;
|
||||
import org.spongepowered.asm.mixin.injection.At;
|
||||
import org.spongepowered.asm.mixin.injection.Inject;
|
||||
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
|
||||
|
||||
@Mixin(MoveBuilderTool.class)
|
||||
public class AxiomMoveBuilderToolMixin {
|
||||
|
||||
@Shadow(remap = false) private ChunkedBlockRegion blockRegion;
|
||||
|
||||
@Shadow(remap = false) @Final private IntMatrix transformMatrix;
|
||||
|
||||
@Shadow(remap = false) private Long2ObjectMap<CompressedBlockEntity> blockEntities;
|
||||
|
||||
@Inject(
|
||||
method = "lambda$initiateMovement$1",
|
||||
at = @At(
|
||||
value = "INVOKE_ASSIGN",
|
||||
target = "Lcom/moulberry/axiom/clipboard/SelectionBuffer$CopyResult;blockEntities()Lit/unimi/dsi/fastutil/longs/Long2ObjectMap;",
|
||||
shift = At.Shift.AFTER
|
||||
),
|
||||
remap = false
|
||||
)
|
||||
private void onInitiateClone(int copyId, int offsetX, int offsetY, int offsetZ, SelectionBuffer.CopyResult copyResult, CallbackInfo ci) {
|
||||
((IAxiomChunkedBlockRegionMixin) blockRegion).setTransform(transformMatrix, blockEntities);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,38 @@
|
||||
package fr.adrien1106.reframed.mixin.compat;
|
||||
|
||||
import com.moulberry.axiom.clipboard.Placement;
|
||||
import com.moulberry.axiom.render.regions.ChunkedBlockRegion;
|
||||
import com.moulberry.axiom.utils.IntMatrix;
|
||||
import com.moulberry.axiom.world_modification.CompressedBlockEntity;
|
||||
import fr.adrien1106.reframed.util.mixin.IAxiomChunkedBlockRegionMixin;
|
||||
import it.unimi.dsi.fastutil.longs.Long2ObjectMap;
|
||||
import net.minecraft.util.math.BlockPos;
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
import org.spongepowered.asm.mixin.Shadow;
|
||||
import org.spongepowered.asm.mixin.injection.At;
|
||||
import org.spongepowered.asm.mixin.injection.Inject;
|
||||
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
|
||||
import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
|
||||
|
||||
@Mixin(Placement.class)
|
||||
public class AxiomPlacementMixin {
|
||||
|
||||
@Shadow(remap = false) private Long2ObjectMap<CompressedBlockEntity> blockEntities;
|
||||
|
||||
@Inject(
|
||||
method = "replacePlacement(Lcom/moulberry/axiom/render/regions/ChunkedBlockRegion;Ljava/lang/String;)V",
|
||||
at = @At("HEAD"),
|
||||
remap = false
|
||||
)
|
||||
private void onReplacePlacement(ChunkedBlockRegion region, String description, CallbackInfo ci) {
|
||||
((IAxiomChunkedBlockRegionMixin) region).setTransform(new IntMatrix(), blockEntities);
|
||||
}
|
||||
|
||||
@Inject(
|
||||
method = "startPlacement(Lnet/minecraft/util/math/BlockPos;Lcom/moulberry/axiom/render/regions/ChunkedBlockRegion;Lit/unimi/dsi/fastutil/longs/Long2ObjectMap;Ljava/lang/String;)I",
|
||||
at = @At("HEAD")
|
||||
)
|
||||
private void onStartPlacement(BlockPos target, ChunkedBlockRegion region, Long2ObjectMap<CompressedBlockEntity> entities, String description, CallbackInfoReturnable<Integer> cir) {
|
||||
((IAxiomChunkedBlockRegionMixin) region).setTransform(new IntMatrix(), entities);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,27 @@
|
||||
package fr.adrien1106.reframed.mixin.compat;
|
||||
|
||||
import com.moulberry.axiom.render.regions.ChunkedBlockRegion;
|
||||
import com.moulberry.axiom.scaling.RotSprite;
|
||||
import fr.adrien1106.reframed.util.mixin.IAxiomChunkedBlockRegionMixin;
|
||||
import org.joml.Matrix4f;
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
import org.spongepowered.asm.mixin.injection.At;
|
||||
import org.spongepowered.asm.mixin.injection.Inject;
|
||||
import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
|
||||
|
||||
@Mixin(RotSprite.class)
|
||||
public class AxiomRotSpriteMixin {
|
||||
|
||||
@Inject(
|
||||
method = "rotateCachedWithOutput",
|
||||
at = @At(
|
||||
value = "HEAD"
|
||||
),
|
||||
remap = false
|
||||
)
|
||||
private static void onRotateCachedWithOutput(ChunkedBlockRegion in, Matrix4f matrix4f, ChunkedBlockRegion out, int x, int y, int z, CallbackInfoReturnable<ChunkedBlockRegion> cir) {
|
||||
IAxiomChunkedBlockRegionMixin iin = (IAxiomChunkedBlockRegionMixin) in;
|
||||
((IAxiomChunkedBlockRegionMixin) out).setTransform(iin.getTransform(), iin.getBlockEntities());
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,29 @@
|
||||
package fr.adrien1106.reframed.mixin.compat;
|
||||
|
||||
import com.llamalad7.mixinextras.sugar.Local;
|
||||
import com.moulberry.axiom.render.regions.ChunkedBlockRegion;
|
||||
import com.moulberry.axiom.scaling.Scale3x;
|
||||
import fr.adrien1106.reframed.util.mixin.IAxiomChunkedBlockRegionMixin;
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
import org.spongepowered.asm.mixin.injection.At;
|
||||
import org.spongepowered.asm.mixin.injection.Inject;
|
||||
import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
|
||||
|
||||
@Mixin(Scale3x.class)
|
||||
public class AxiomScale3xMixin {
|
||||
|
||||
@Inject(
|
||||
method = "scale3x",
|
||||
at = @At(
|
||||
value = "INVOKE_ASSIGN",
|
||||
target = "Lcom/moulberry/axiom/render/regions/ChunkedBlockRegion;<init>()V",
|
||||
shift = At.Shift.AFTER
|
||||
),
|
||||
remap = false
|
||||
)
|
||||
private static void onInit(ChunkedBlockRegion in, boolean postProcessing, CallbackInfoReturnable<ChunkedBlockRegion> cir, @Local(ordinal = 1) ChunkedBlockRegion out) {
|
||||
IAxiomChunkedBlockRegionMixin iin = (IAxiomChunkedBlockRegionMixin) in;
|
||||
((IAxiomChunkedBlockRegionMixin) out).setTransform(iin.getTransform(), iin.getBlockEntities());
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,63 @@
|
||||
package fr.adrien1106.reframed.mixin.compat;
|
||||
|
||||
import fr.adrien1106.reframed.client.util.RenderHelper;
|
||||
import fr.adrien1106.reframed.util.blocks.ThemeableBlockEntity;
|
||||
import fr.adrien1106.reframed.util.mixin.IBlockRenderInfoMixin;
|
||||
import link.infra.indium.renderer.render.BlockRenderInfo;
|
||||
import net.minecraft.block.BlockState;
|
||||
import net.minecraft.util.math.BlockPos;
|
||||
import net.minecraft.util.math.Direction;
|
||||
import net.minecraft.world.BlockRenderView;
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
import org.spongepowered.asm.mixin.Shadow;
|
||||
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.callback.CallbackInfoReturnable;
|
||||
|
||||
@Mixin(BlockRenderInfo.class)
|
||||
public abstract class IndiumBlockRenderInfoMixin implements IBlockRenderInfoMixin {
|
||||
|
||||
@Shadow public abstract void prepareForBlock(BlockState blockState, BlockPos blockPos, long seed, boolean modelAo);
|
||||
|
||||
@Shadow public BlockPos blockPos;
|
||||
@Shadow public BlockRenderView blockView;
|
||||
@Shadow public BlockState blockState;
|
||||
|
||||
@Unique private int theme_index = 0;
|
||||
@Unique private int model_hash = 0;
|
||||
|
||||
@Inject(
|
||||
method = "shouldDrawFace",
|
||||
at = @At(
|
||||
value = "INVOKE_ASSIGN",
|
||||
target = "Lnet/minecraft/util/math/Direction;getId()I",
|
||||
shift = At.Shift.AFTER
|
||||
),
|
||||
cancellable = true
|
||||
)
|
||||
private void shouldDrawInnerFace(Direction face, CallbackInfoReturnable<Boolean> cir) {
|
||||
BlockPos other_pos = blockPos.offset(face);
|
||||
if (!(blockView.getBlockEntity(blockPos) instanceof ThemeableBlockEntity
|
||||
|| blockView.getBlockEntity(other_pos) instanceof ThemeableBlockEntity)
|
||||
) return;
|
||||
cir.setReturnValue(RenderHelper.shouldDrawSide(blockState, blockView, blockPos, face, other_pos, theme_index));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void prepareForBlock(BlockState blockState, BlockPos blockPos, long seed, boolean modelAo, int theme_index, int model_hash) {
|
||||
this.theme_index = theme_index;
|
||||
this.model_hash = model_hash;
|
||||
prepareForBlock(blockState, blockPos, seed, modelAo);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getThemeIndex() {
|
||||
return theme_index;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getModelHash() {
|
||||
return model_hash;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,83 @@
|
||||
package fr.adrien1106.reframed.mixin.compat;
|
||||
|
||||
import fr.adrien1106.reframed.client.model.MultiRetexturableModel;
|
||||
import fr.adrien1106.reframed.client.model.RetexturingBakedModel;
|
||||
import fr.adrien1106.reframed.client.util.RenderHelper;
|
||||
import fr.adrien1106.reframed.util.mixin.IBlockRenderInfoMixin;
|
||||
import fr.adrien1106.reframed.util.mixin.IMultipartBakedModelMixin;
|
||||
import link.infra.indium.renderer.aocalc.AoCalculator;
|
||||
import link.infra.indium.renderer.render.AbstractBlockRenderContext;
|
||||
import link.infra.indium.renderer.render.BlockRenderInfo;
|
||||
import link.infra.indium.renderer.render.NonTerrainBlockRenderContext;
|
||||
import link.infra.indium.renderer.render.SingleBlockLightDataCache;
|
||||
import net.fabricmc.fabric.api.renderer.v1.render.RenderContext;
|
||||
import net.minecraft.block.BlockState;
|
||||
import net.minecraft.client.render.VertexConsumer;
|
||||
import net.minecraft.client.render.model.BakedModel;
|
||||
import net.minecraft.client.util.math.MatrixStack;
|
||||
import net.minecraft.util.math.BlockPos;
|
||||
import net.minecraft.util.math.random.Random;
|
||||
import net.minecraft.world.BlockRenderView;
|
||||
import org.spongepowered.asm.mixin.Final;
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
import org.spongepowered.asm.mixin.Shadow;
|
||||
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.callback.CallbackInfo;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@Mixin(NonTerrainBlockRenderContext.class)
|
||||
public abstract class IndiumNonTerrainBlockRenderContextMixin extends AbstractBlockRenderContext {
|
||||
|
||||
@Shadow(remap = false) @Final private SingleBlockLightDataCache lightCache;
|
||||
|
||||
@Shadow private VertexConsumer vertexConsumer;
|
||||
|
||||
@Inject(
|
||||
method = "render",
|
||||
at = @At(
|
||||
value = "INVOKE",
|
||||
target = "Llink/infra/indium/renderer/render/BlockRenderInfo;prepareForWorld(Lnet/minecraft/world/BlockRenderView;Z)V",
|
||||
shift = At.Shift.AFTER
|
||||
),
|
||||
cancellable = true
|
||||
)
|
||||
private void renderMultipleModels(BlockRenderView blockView, BakedModel wrapper, BlockState state, BlockPos pos, MatrixStack matrixStack, VertexConsumer buffer, boolean cull, Random random, long seed, int overlay, CallbackInfo ci) {
|
||||
if (!(wrapper instanceof IMultipartBakedModelMixin wrapped)) return;
|
||||
List<BakedModel> models = wrapped.getModels(state);
|
||||
if (models.stream().noneMatch(bakedModel ->
|
||||
bakedModel instanceof MultiRetexturableModel
|
||||
|| bakedModel instanceof RetexturingBakedModel
|
||||
)) return;
|
||||
|
||||
models.forEach(model -> {
|
||||
if (model instanceof MultiRetexturableModel multi_model) {
|
||||
RenderHelper.computeInnerCull(state, multi_model.models(), model.hashCode());
|
||||
multi_model.models().forEach(rexteruable_model ->
|
||||
renderModel(state, pos, seed, rexteruable_model, aoCalc, blockInfo, this, model.hashCode())
|
||||
);
|
||||
} else if (model instanceof RetexturingBakedModel rexteruable_model)
|
||||
renderModel(state, pos, seed, rexteruable_model, aoCalc, blockInfo, this, model.hashCode());
|
||||
else model.emitBlockQuads(blockInfo.blockView, blockInfo.blockState, blockInfo.blockPos, blockInfo.randomSupplier, this);
|
||||
});
|
||||
|
||||
blockInfo.release();
|
||||
lightCache.release();
|
||||
vertexConsumer = null;
|
||||
ci.cancel();
|
||||
}
|
||||
|
||||
@Unique
|
||||
private static void renderModel(BlockState state, BlockPos pos, long seed, RetexturingBakedModel model, AoCalculator aoCalc, BlockRenderInfo block_info, RenderContext context, int model_hash) {
|
||||
aoCalc.clear();
|
||||
((IBlockRenderInfoMixin) block_info).prepareForBlock(
|
||||
state, pos, seed,
|
||||
model.useAmbientOcclusion(block_info.blockView, pos),
|
||||
model.getThemeIndex(), model_hash
|
||||
);
|
||||
model.emitBlockQuads(block_info.blockView, block_info.blockState, block_info.blockPos, block_info.randomSupplier, context);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,55 +0,0 @@
|
||||
package fr.adrien1106.reframed.mixin.compat;
|
||||
|
||||
import fr.adrien1106.reframed.client.util.RenderHelper;
|
||||
import fr.adrien1106.reframed.util.mixin.IBlockRenderInfoMixin;
|
||||
import fr.adrien1106.reframed.util.blocks.ThemeableBlockEntity;
|
||||
import link.infra.indium.renderer.render.BlockRenderInfo;
|
||||
import link.infra.indium.renderer.render.TerrainBlockRenderInfo;
|
||||
import me.jellysquid.mods.sodium.client.render.chunk.compile.pipeline.BlockOcclusionCache;
|
||||
import net.minecraft.block.BlockState;
|
||||
import net.minecraft.util.math.BlockPos;
|
||||
import net.minecraft.util.math.Direction;
|
||||
import net.minecraft.world.BlockView;
|
||||
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.Redirect;
|
||||
|
||||
@Mixin(TerrainBlockRenderInfo.class)
|
||||
public abstract class IndiumTerrainBlockRenderInfoMixin extends BlockRenderInfo implements IBlockRenderInfoMixin {
|
||||
|
||||
@Unique private int theme_index = 0;
|
||||
@Unique private int model_hash = 0;
|
||||
|
||||
@Redirect(
|
||||
method = "shouldDrawFaceInner",
|
||||
at = @At(
|
||||
value = "INVOKE",
|
||||
target = "Lme/jellysquid/mods/sodium/client/render/chunk/compile/pipeline/BlockOcclusionCache;shouldDrawSide(Lnet/minecraft/block/BlockState;Lnet/minecraft/world/BlockView;Lnet/minecraft/util/math/BlockPos;Lnet/minecraft/util/math/Direction;)Z"
|
||||
)
|
||||
)
|
||||
private boolean shouldDrawCamoSide(BlockOcclusionCache instance, BlockState state, BlockView view, BlockPos pos, Direction face) {
|
||||
BlockPos other_pos = pos.offset(face);
|
||||
if (!(view.getBlockEntity(pos) instanceof ThemeableBlockEntity
|
||||
|| view.getBlockEntity(other_pos) instanceof ThemeableBlockEntity))
|
||||
return instance.shouldDrawSide(state, view, pos, face);
|
||||
return RenderHelper.shouldDrawSide(state, view, pos, face, other_pos, theme_index);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void prepareForBlock(BlockState blockState, BlockPos blockPos, long seed, boolean modelAo, int theme_index, int model_hash) {
|
||||
this.theme_index = theme_index;
|
||||
this.model_hash = model_hash;
|
||||
prepareForBlock(blockState, blockPos, seed, modelAo);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getThemeIndex() {
|
||||
return theme_index;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getModelHash() {
|
||||
return model_hash;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,62 @@
|
||||
package fr.adrien1106.reframed.mixin.compat;
|
||||
|
||||
import com.llamalad7.mixinextras.sugar.Local;
|
||||
import fr.adrien1106.reframed.block.ReFramedBlock;
|
||||
import fr.adrien1106.reframed.util.blocks.ThemeableBlockEntity;
|
||||
import me.jellysquid.mods.sodium.client.render.chunk.compile.pipeline.FluidRenderer;
|
||||
import me.jellysquid.mods.sodium.client.world.WorldSlice;
|
||||
import net.fabricmc.fabric.api.client.render.fluid.v1.FluidRenderHandlerRegistry;
|
||||
import net.minecraft.block.*;
|
||||
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.spongepowered.asm.mixin.Mixin;
|
||||
import org.spongepowered.asm.mixin.injection.At;
|
||||
import org.spongepowered.asm.mixin.injection.Redirect;
|
||||
|
||||
@Mixin(FluidRenderer.class)
|
||||
public abstract class SodiumFluidRendererMixin {
|
||||
|
||||
@Redirect(
|
||||
method = "isSideExposed",
|
||||
at = @At(
|
||||
value = "INVOKE",
|
||||
target = "Lnet/minecraft/block/BlockState;isOpaque()Z"
|
||||
)
|
||||
)
|
||||
private boolean isSideOpaqueExposed(BlockState state) {
|
||||
if (!(state.getBlock() instanceof ReFramedBlock)) return state.isOpaque();
|
||||
return true; // forces to compute correct shape
|
||||
}
|
||||
|
||||
@Redirect(
|
||||
method = "isSideExposed",
|
||||
at = @At(
|
||||
value = "INVOKE",
|
||||
target = "Lnet/minecraft/block/BlockState;getCullingShape(Lnet/minecraft/world/BlockView;Lnet/minecraft/util/math/BlockPos;)Lnet/minecraft/util/shape/VoxelShape;"
|
||||
)
|
||||
)
|
||||
private VoxelShape isSideShapeExposed(BlockState state, BlockView world, BlockPos pos) {
|
||||
if (!(state.getBlock() instanceof ReFramedBlock block)) return state.getCullingShape(world, pos);
|
||||
return block.getShadingShape(state, world, pos);
|
||||
}
|
||||
|
||||
@Redirect(
|
||||
method = "render",
|
||||
at = @At(
|
||||
value = "INVOKE",
|
||||
target = "Lnet/fabricmc/fabric/api/client/render/fluid/v1/FluidRenderHandlerRegistry;isBlockTransparent(Lnet/minecraft/block/Block;)Z"
|
||||
)
|
||||
)
|
||||
private boolean getThemeState(FluidRenderHandlerRegistry fluid_handler, Block block, @Local(argsOnly = true) WorldSlice world, @Local(ordinal = 2) BlockPos pos, @Local BlockState state, @Local Direction dir) {
|
||||
if (!(block instanceof ReFramedBlock rfblock && world.getBlockEntity(pos) instanceof ThemeableBlockEntity framed_entity)) return fluid_handler.isBlockTransparent(block);
|
||||
return !VoxelShapes.isSideCovered(VoxelShapes.fullCube(), rfblock.getShadingShape(state, world, pos), dir)
|
||||
&& framed_entity.getThemes().stream()
|
||||
.anyMatch(s -> s.getBlock() instanceof LeavesBlock
|
||||
|| s.getBlock() instanceof TranslucentBlock
|
||||
|| s.getBlock() instanceof AirBlock
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,27 @@
|
||||
package fr.adrien1106.reframed.mixin.render;
|
||||
|
||||
import fr.adrien1106.reframed.client.util.RenderHelper;
|
||||
import fr.adrien1106.reframed.util.blocks.ThemeableBlockEntity;
|
||||
import net.minecraft.block.Block;
|
||||
import net.minecraft.block.BlockState;
|
||||
import net.minecraft.util.math.BlockPos;
|
||||
import net.minecraft.util.math.Direction;
|
||||
import net.minecraft.world.BlockView;
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
import org.spongepowered.asm.mixin.injection.At;
|
||||
import org.spongepowered.asm.mixin.injection.Inject;
|
||||
import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
|
||||
|
||||
@Mixin(Block.class)
|
||||
public abstract class BlockMixin {
|
||||
|
||||
@Inject(
|
||||
method = "shouldDrawSide",
|
||||
at = @At("HEAD"),
|
||||
cancellable = true
|
||||
) // serves as a safety sometimes mods implements culling cache and hence will break some injections...
|
||||
private static void shouldDrawSide(BlockState state, BlockView world, BlockPos pos, Direction side, BlockPos other_pos, CallbackInfoReturnable<Boolean> cir) {
|
||||
if (!(world.getBlockEntity(other_pos) instanceof ThemeableBlockEntity)) return;
|
||||
cir.setReturnValue(RenderHelper.shouldDrawSide(state, world, pos, side, other_pos, 0));
|
||||
}
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user