Overhaul to how encasing blocks works (#4458)

* Make Encasing utilize Interfaces

* Add Javadoc to IEncasable and IEncased interfaces

* Fix Weird block.block issues (No clue where those came from)

* Final Touch ups for now and made requirement for casing normal Block instead of CasingBlock

* Make requested changes

* Add more parameters for tryEncasing, for use in handleEncasing
Move handleEncasing to Encased Interface for more flexability

* Simplify and organize

- Rename:
  - Encasable -> EncasableBlock
  - Encased -> EncasedBlock
  - EncasableRegistry -> EncasingRegistry
- Remove EncasedBlock#setCasing
- Remove encasedBlock argument from EncasedBlock#handleEncasing
- Add Registrate builder transformer to EncasingRegistry for easy use

---------

Co-authored-by: PepperCode1 <44146161+PepperCode1@users.noreply.github.com>
This commit is contained in:
Cyvack 2023-02-22 13:09:11 -08:00 committed by GitHub
parent 40f96b0038
commit c907454be9
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
10 changed files with 210 additions and 114 deletions

View file

@ -118,6 +118,7 @@ import com.simibubi.create.content.contraptions.relays.belt.BeltModel;
import com.simibubi.create.content.contraptions.relays.elementary.BracketedKineticBlockModel; import com.simibubi.create.content.contraptions.relays.elementary.BracketedKineticBlockModel;
import com.simibubi.create.content.contraptions.relays.elementary.CogWheelBlock; import com.simibubi.create.content.contraptions.relays.elementary.CogWheelBlock;
import com.simibubi.create.content.contraptions.relays.elementary.CogwheelBlockItem; import com.simibubi.create.content.contraptions.relays.elementary.CogwheelBlockItem;
import com.simibubi.create.content.contraptions.relays.elementary.EncasingRegistry;
import com.simibubi.create.content.contraptions.relays.elementary.ShaftBlock; import com.simibubi.create.content.contraptions.relays.elementary.ShaftBlock;
import com.simibubi.create.content.contraptions.relays.encased.AdjustablePulleyBlock; import com.simibubi.create.content.contraptions.relays.encased.AdjustablePulleyBlock;
import com.simibubi.create.content.contraptions.relays.encased.ClutchBlock; import com.simibubi.create.content.contraptions.relays.encased.ClutchBlock;
@ -359,23 +360,26 @@ public class AllBlocks {
.register(); .register();
public static final BlockEntry<EncasedShaftBlock> ANDESITE_ENCASED_SHAFT = public static final BlockEntry<EncasedShaftBlock> ANDESITE_ENCASED_SHAFT =
REGISTRATE.block("andesite_encased_shaft", EncasedShaftBlock::andesite) REGISTRATE.block("andesite_encased_shaft", p -> new EncasedShaftBlock(p, AllBlocks.ANDESITE_CASING::get))
.properties(p -> p.color(MaterialColor.PODZOL)) .properties(p -> p.color(MaterialColor.PODZOL))
.transform(BuilderTransformers.encasedShaft("andesite", () -> AllSpriteShifts.ANDESITE_CASING)) .transform(BuilderTransformers.encasedShaft("andesite", () -> AllSpriteShifts.ANDESITE_CASING))
.transform(EncasingRegistry.addVariantTo(AllBlocks.SHAFT))
.transform(axeOrPickaxe()) .transform(axeOrPickaxe())
.register(); .register();
public static final BlockEntry<EncasedShaftBlock> BRASS_ENCASED_SHAFT = public static final BlockEntry<EncasedShaftBlock> BRASS_ENCASED_SHAFT =
REGISTRATE.block("brass_encased_shaft", EncasedShaftBlock::brass) REGISTRATE.block("brass_encased_shaft", p -> new EncasedShaftBlock(p, AllBlocks.BRASS_CASING::get))
.properties(p -> p.color(MaterialColor.TERRACOTTA_BROWN)) .properties(p -> p.color(MaterialColor.TERRACOTTA_BROWN))
.transform(BuilderTransformers.encasedShaft("brass", () -> AllSpriteShifts.BRASS_CASING)) .transform(BuilderTransformers.encasedShaft("brass", () -> AllSpriteShifts.BRASS_CASING))
.transform(EncasingRegistry.addVariantTo(AllBlocks.SHAFT))
.transform(axeOrPickaxe()) .transform(axeOrPickaxe())
.register(); .register();
public static final BlockEntry<EncasedCogwheelBlock> ANDESITE_ENCASED_COGWHEEL = REGISTRATE public static final BlockEntry<EncasedCogwheelBlock> ANDESITE_ENCASED_COGWHEEL = REGISTRATE
.block("andesite_encased_cogwheel", p -> EncasedCogwheelBlock.andesite(false, p)) .block("andesite_encased_cogwheel", p -> new EncasedCogwheelBlock(p, false, AllBlocks.ANDESITE_CASING::get))
.properties(p -> p.color(MaterialColor.PODZOL)) .properties(p -> p.color(MaterialColor.PODZOL))
.transform(BuilderTransformers.encasedCogwheel("andesite", () -> AllSpriteShifts.ANDESITE_CASING)) .transform(BuilderTransformers.encasedCogwheel("andesite", () -> AllSpriteShifts.ANDESITE_CASING))
.transform(EncasingRegistry.addVariantTo(AllBlocks.COGWHEEL))
.onRegister(CreateRegistrate.connectedTextures(() -> new EncasedCogCTBehaviour(AllSpriteShifts.ANDESITE_CASING, .onRegister(CreateRegistrate.connectedTextures(() -> new EncasedCogCTBehaviour(AllSpriteShifts.ANDESITE_CASING,
Couple.create(AllSpriteShifts.ANDESITE_ENCASED_COGWHEEL_SIDE, Couple.create(AllSpriteShifts.ANDESITE_ENCASED_COGWHEEL_SIDE,
AllSpriteShifts.ANDESITE_ENCASED_COGWHEEL_OTHERSIDE)))) AllSpriteShifts.ANDESITE_ENCASED_COGWHEEL_OTHERSIDE))))
@ -383,9 +387,10 @@ public class AllBlocks {
.register(); .register();
public static final BlockEntry<EncasedCogwheelBlock> BRASS_ENCASED_COGWHEEL = public static final BlockEntry<EncasedCogwheelBlock> BRASS_ENCASED_COGWHEEL =
REGISTRATE.block("brass_encased_cogwheel", p -> EncasedCogwheelBlock.brass(false, p)) REGISTRATE.block("brass_encased_cogwheel", p -> new EncasedCogwheelBlock(p, false, AllBlocks.BRASS_CASING::get))
.properties(p -> p.color(MaterialColor.TERRACOTTA_BROWN)) .properties(p -> p.color(MaterialColor.TERRACOTTA_BROWN))
.transform(BuilderTransformers.encasedCogwheel("brass", () -> AllSpriteShifts.BRASS_CASING)) .transform(BuilderTransformers.encasedCogwheel("brass", () -> AllSpriteShifts.BRASS_CASING))
.transform(EncasingRegistry.addVariantTo(AllBlocks.COGWHEEL))
.onRegister(CreateRegistrate.connectedTextures(() -> new EncasedCogCTBehaviour(AllSpriteShifts.BRASS_CASING, .onRegister(CreateRegistrate.connectedTextures(() -> new EncasedCogCTBehaviour(AllSpriteShifts.BRASS_CASING,
Couple.create(AllSpriteShifts.BRASS_ENCASED_COGWHEEL_SIDE, Couple.create(AllSpriteShifts.BRASS_ENCASED_COGWHEEL_SIDE,
AllSpriteShifts.BRASS_ENCASED_COGWHEEL_OTHERSIDE)))) AllSpriteShifts.BRASS_ENCASED_COGWHEEL_OTHERSIDE))))
@ -393,16 +398,18 @@ public class AllBlocks {
.register(); .register();
public static final BlockEntry<EncasedCogwheelBlock> ANDESITE_ENCASED_LARGE_COGWHEEL = public static final BlockEntry<EncasedCogwheelBlock> ANDESITE_ENCASED_LARGE_COGWHEEL =
REGISTRATE.block("andesite_encased_large_cogwheel", p -> EncasedCogwheelBlock.andesite(true, p)) REGISTRATE.block("andesite_encased_large_cogwheel", p -> new EncasedCogwheelBlock(p, true, AllBlocks.ANDESITE_CASING::get))
.properties(p -> p.color(MaterialColor.PODZOL)) .properties(p -> p.color(MaterialColor.PODZOL))
.transform(BuilderTransformers.encasedLargeCogwheel("andesite", () -> AllSpriteShifts.ANDESITE_CASING)) .transform(BuilderTransformers.encasedLargeCogwheel("andesite", () -> AllSpriteShifts.ANDESITE_CASING))
.transform(EncasingRegistry.addVariantTo(AllBlocks.LARGE_COGWHEEL))
.transform(axeOrPickaxe()) .transform(axeOrPickaxe())
.register(); .register();
public static final BlockEntry<EncasedCogwheelBlock> BRASS_ENCASED_LARGE_COGWHEEL = public static final BlockEntry<EncasedCogwheelBlock> BRASS_ENCASED_LARGE_COGWHEEL =
REGISTRATE.block("brass_encased_large_cogwheel", p -> EncasedCogwheelBlock.brass(true, p)) REGISTRATE.block("brass_encased_large_cogwheel", p -> new EncasedCogwheelBlock(p, true, AllBlocks.BRASS_CASING::get))
.properties(p -> p.color(MaterialColor.TERRACOTTA_BROWN)) .properties(p -> p.color(MaterialColor.TERRACOTTA_BROWN))
.transform(BuilderTransformers.encasedLargeCogwheel("brass", () -> AllSpriteShifts.BRASS_CASING)) .transform(BuilderTransformers.encasedLargeCogwheel("brass", () -> AllSpriteShifts.BRASS_CASING))
.transform(EncasingRegistry.addVariantTo(AllBlocks.LARGE_COGWHEEL))
.transform(axeOrPickaxe()) .transform(axeOrPickaxe())
.register(); .register();
@ -820,7 +827,7 @@ public class AllBlocks {
.register(); .register();
public static final BlockEntry<EncasedPipeBlock> ENCASED_FLUID_PIPE = public static final BlockEntry<EncasedPipeBlock> ENCASED_FLUID_PIPE =
REGISTRATE.block("encased_fluid_pipe", EncasedPipeBlock::new) REGISTRATE.block("encased_fluid_pipe", p -> new EncasedPipeBlock(p, AllBlocks.COPPER_CASING::get))
.initialProperties(SharedProperties::copperMetal) .initialProperties(SharedProperties::copperMetal)
.properties(p -> p.color(MaterialColor.TERRACOTTA_LIGHT_GRAY)) .properties(p -> p.color(MaterialColor.TERRACOTTA_LIGHT_GRAY))
.properties(BlockBehaviour.Properties::noOcclusion) .properties(BlockBehaviour.Properties::noOcclusion)
@ -831,6 +838,7 @@ public class AllBlocks {
(s, f) -> !s.getValue(EncasedPipeBlock.FACING_TO_PROPERTY_MAP.get(f))))) (s, f) -> !s.getValue(EncasedPipeBlock.FACING_TO_PROPERTY_MAP.get(f)))))
.onRegister(CreateRegistrate.blockModel(() -> PipeAttachmentModel::new)) .onRegister(CreateRegistrate.blockModel(() -> PipeAttachmentModel::new))
.loot((p, b) -> p.dropOther(b, FLUID_PIPE.get())) .loot((p, b) -> p.dropOther(b, FLUID_PIPE.get()))
.transform(EncasingRegistry.addVariantTo(AllBlocks.FLUID_PIPE))
.register(); .register();
public static final BlockEntry<GlassFluidPipeBlock> GLASS_FLUID_PIPE = public static final BlockEntry<GlassFluidPipeBlock> GLASS_FLUID_PIPE =

View file

@ -9,11 +9,13 @@ import static net.minecraft.world.level.block.state.properties.BlockStatePropert
import java.util.Map; import java.util.Map;
import java.util.Random; import java.util.Random;
import java.util.function.Supplier;
import com.simibubi.create.AllBlocks; import com.simibubi.create.AllBlocks;
import com.simibubi.create.AllTileEntities; import com.simibubi.create.AllTileEntities;
import com.simibubi.create.content.contraptions.fluids.FluidPropagator; import com.simibubi.create.content.contraptions.fluids.FluidPropagator;
import com.simibubi.create.content.contraptions.fluids.FluidTransportBehaviour; import com.simibubi.create.content.contraptions.fluids.FluidTransportBehaviour;
import com.simibubi.create.content.contraptions.relays.elementary.EncasedBlock;
import com.simibubi.create.content.contraptions.wrench.IWrenchable; import com.simibubi.create.content.contraptions.wrench.IWrenchable;
import com.simibubi.create.content.schematics.ISpecialBlockItemRequirement; import com.simibubi.create.content.schematics.ISpecialBlockItemRequirement;
import com.simibubi.create.content.schematics.ItemRequirement; import com.simibubi.create.content.schematics.ItemRequirement;
@ -25,6 +27,7 @@ import net.minecraft.core.BlockPos;
import net.minecraft.core.Direction; import net.minecraft.core.Direction;
import net.minecraft.network.protocol.game.DebugPackets; import net.minecraft.network.protocol.game.DebugPackets;
import net.minecraft.server.level.ServerLevel; import net.minecraft.server.level.ServerLevel;
import net.minecraft.world.InteractionHand;
import net.minecraft.world.InteractionResult; import net.minecraft.world.InteractionResult;
import net.minecraft.world.entity.LivingEntity; import net.minecraft.world.entity.LivingEntity;
import net.minecraft.world.entity.player.Player; import net.minecraft.world.entity.player.Player;
@ -39,15 +42,18 @@ import net.minecraft.world.level.block.entity.BlockEntityType;
import net.minecraft.world.level.block.state.BlockState; import net.minecraft.world.level.block.state.BlockState;
import net.minecraft.world.level.block.state.StateDefinition.Builder; import net.minecraft.world.level.block.state.StateDefinition.Builder;
import net.minecraft.world.level.block.state.properties.BooleanProperty; import net.minecraft.world.level.block.state.properties.BooleanProperty;
import net.minecraft.world.phys.BlockHitResult;
import net.minecraft.world.phys.HitResult; import net.minecraft.world.phys.HitResult;
import net.minecraft.world.ticks.TickPriority; import net.minecraft.world.ticks.TickPriority;
public class EncasedPipeBlock extends Block implements IWrenchable, ISpecialBlockItemRequirement, ITE<FluidPipeTileEntity> { public class EncasedPipeBlock extends Block implements IWrenchable, ISpecialBlockItemRequirement, ITE<FluidPipeTileEntity>, EncasedBlock {
public static final Map<Direction, BooleanProperty> FACING_TO_PROPERTY_MAP = PipeBlock.PROPERTY_BY_DIRECTION; public static final Map<Direction, BooleanProperty> FACING_TO_PROPERTY_MAP = PipeBlock.PROPERTY_BY_DIRECTION;
public EncasedPipeBlock(Properties p_i48339_1_) { private final Supplier<Block> casing;
super(p_i48339_1_);
public EncasedPipeBlock(Properties properties, Supplier<Block> casing) {
super(properties);
this.casing = casing;
registerDefaultState(defaultBlockState().setValue(NORTH, false) registerDefaultState(defaultBlockState().setValue(NORTH, false)
.setValue(SOUTH, false) .setValue(SOUTH, false)
.setValue(DOWN, false) .setValue(DOWN, false)
@ -154,4 +160,17 @@ public class EncasedPipeBlock extends Block implements IWrenchable, ISpecialBloc
return AllTileEntities.ENCASED_FLUID_PIPE.get(); return AllTileEntities.ENCASED_FLUID_PIPE.get();
} }
@Override
public Block getCasing() {
return casing.get();
}
@Override
public void handleEncasing(BlockState state, Level level, BlockPos pos, ItemStack heldItem, Player player, InteractionHand hand,
BlockHitResult ray) {
FluidTransportBehaviour.cacheFlows(level, pos);
level.setBlockAndUpdate(pos,
EncasedPipeBlock.transferSixWayProperties(state, defaultBlockState()));
FluidTransportBehaviour.loadFlows(level, pos);
}
} }

View file

@ -11,6 +11,7 @@ import com.simibubi.create.AllTileEntities;
import com.simibubi.create.content.contraptions.fluids.FluidPropagator; import com.simibubi.create.content.contraptions.fluids.FluidPropagator;
import com.simibubi.create.content.contraptions.fluids.FluidTransportBehaviour; import com.simibubi.create.content.contraptions.fluids.FluidTransportBehaviour;
import com.simibubi.create.content.contraptions.relays.elementary.BracketedTileEntityBehaviour; import com.simibubi.create.content.contraptions.relays.elementary.BracketedTileEntityBehaviour;
import com.simibubi.create.content.contraptions.relays.elementary.EncasableBlock;
import com.simibubi.create.content.contraptions.wrench.IWrenchableWithBracket; import com.simibubi.create.content.contraptions.wrench.IWrenchableWithBracket;
import com.simibubi.create.foundation.advancement.AdvancementBehaviour; import com.simibubi.create.foundation.advancement.AdvancementBehaviour;
import com.simibubi.create.foundation.advancement.AllAdvancements; import com.simibubi.create.foundation.advancement.AllAdvancements;
@ -50,7 +51,7 @@ import net.minecraft.world.phys.shapes.VoxelShape;
import net.minecraft.world.ticks.TickPriority; import net.minecraft.world.ticks.TickPriority;
public class FluidPipeBlock extends PipeBlock public class FluidPipeBlock extends PipeBlock
implements SimpleWaterloggedBlock, IWrenchableWithBracket, ITE<FluidPipeTileEntity> { implements SimpleWaterloggedBlock, IWrenchableWithBracket, ITE<FluidPipeTileEntity>, EncasableBlock {
private static final VoxelShape OCCLUSION_BOX = Block.box(4, 4, 4, 12, 12, 12); private static final VoxelShape OCCLUSION_BOX = Block.box(4, 4, 4, 12, 12, 12);
@ -113,18 +114,13 @@ public class FluidPipeBlock extends PipeBlock
@Override @Override
public InteractionResult use(BlockState state, Level world, BlockPos pos, Player player, InteractionHand hand, public InteractionResult use(BlockState state, Level world, BlockPos pos, Player player, InteractionHand hand,
BlockHitResult hit) { BlockHitResult ray) {
if (!AllBlocks.COPPER_CASING.isIn(player.getItemInHand(hand))) ItemStack heldItem = player.getItemInHand(hand);
InteractionResult result = tryEncase(state, world, pos, heldItem, player, hand, ray);
if (result.consumesAction())
return result;
return InteractionResult.PASS; return InteractionResult.PASS;
if (world.isClientSide)
return InteractionResult.SUCCESS;
FluidTransportBehaviour.cacheFlows(world, pos);
world.setBlockAndUpdate(pos,
EncasedPipeBlock.transferSixWayProperties(state, AllBlocks.ENCASED_FLUID_PIPE.getDefaultState()));
FluidTransportBehaviour.loadFlows(world, pos);
return InteractionResult.SUCCESS;
} }
public BlockState getAxisState(Axis axis) { public BlockState getAxisState(Axis axis) {
@ -341,5 +337,4 @@ public class FluidPipeBlock extends PipeBlock
public VoxelShape getOcclusionShape(BlockState pState, BlockGetter pLevel, BlockPos pPos) { public VoxelShape getOcclusionShape(BlockState pState, BlockGetter pLevel, BlockPos pPos) {
return OCCLUSION_BOX; return OCCLUSION_BOX;
} }
} }

View file

@ -5,9 +5,7 @@ import javax.annotation.ParametersAreNonnullByDefault;
import com.simibubi.create.AllBlocks; import com.simibubi.create.AllBlocks;
import com.simibubi.create.AllShapes; import com.simibubi.create.AllShapes;
import com.simibubi.create.content.contraptions.base.IRotate; import com.simibubi.create.content.contraptions.base.IRotate;
import com.simibubi.create.content.contraptions.base.KineticTileEntity;
import com.simibubi.create.content.contraptions.relays.advanced.SpeedControllerBlock; import com.simibubi.create.content.contraptions.relays.advanced.SpeedControllerBlock;
import com.simibubi.create.content.contraptions.relays.encased.EncasedCogwheelBlock;
import com.simibubi.create.foundation.advancement.AllAdvancements; import com.simibubi.create.foundation.advancement.AllAdvancements;
import com.simibubi.create.foundation.utility.Iterate; import com.simibubi.create.foundation.utility.Iterate;
@ -35,7 +33,7 @@ import net.minecraft.world.phys.shapes.VoxelShape;
@ParametersAreNonnullByDefault @ParametersAreNonnullByDefault
@MethodsReturnNonnullByDefault @MethodsReturnNonnullByDefault
public class CogWheelBlock extends AbstractSimpleShaftBlock implements ICogWheel { public class CogWheelBlock extends AbstractSimpleShaftBlock implements ICogWheel, EncasableBlock {
boolean isLarge; boolean isLarge;
@ -122,38 +120,9 @@ public class CogWheelBlock extends AbstractSimpleShaftBlock implements ICogWheel
return InteractionResult.PASS; return InteractionResult.PASS;
ItemStack heldItem = player.getItemInHand(hand); ItemStack heldItem = player.getItemInHand(hand);
EncasedCogwheelBlock[] encasedBlocks = isLarge InteractionResult result = tryEncase(state, world, pos, heldItem, player, hand, ray);
? new EncasedCogwheelBlock[] { AllBlocks.ANDESITE_ENCASED_LARGE_COGWHEEL.get(), if (result.consumesAction())
AllBlocks.BRASS_ENCASED_LARGE_COGWHEEL.get() } return result;
: new EncasedCogwheelBlock[] { AllBlocks.ANDESITE_ENCASED_COGWHEEL.get(),
AllBlocks.BRASS_ENCASED_COGWHEEL.get() };
for (EncasedCogwheelBlock encasedCog : encasedBlocks) {
if (!encasedCog.getCasing()
.isIn(heldItem))
continue;
if (world.isClientSide)
return InteractionResult.SUCCESS;
BlockState encasedState = encasedCog.defaultBlockState()
.setValue(AXIS, state.getValue(AXIS));
for (Direction d : Iterate.directionsInAxis(state.getValue(AXIS))) {
BlockState adjacentState = world.getBlockState(pos.relative(d));
if (!(adjacentState.getBlock() instanceof IRotate))
continue;
IRotate def = (IRotate) adjacentState.getBlock();
if (!def.hasShaftTowards(world, pos.relative(d), adjacentState, d.getOpposite()))
continue;
encasedState =
encasedState.cycle(d.getAxisDirection() == AxisDirection.POSITIVE ? EncasedCogwheelBlock.TOP_SHAFT
: EncasedCogwheelBlock.BOTTOM_SHAFT);
}
KineticTileEntity.switchToBlockState(world, pos, encasedState);
return InteractionResult.SUCCESS;
}
return InteractionResult.PASS; return InteractionResult.PASS;
} }

View file

@ -0,0 +1,39 @@
package com.simibubi.create.content.contraptions.relays.elementary;
import java.util.List;
import net.minecraft.core.BlockPos;
import net.minecraft.world.InteractionHand;
import net.minecraft.world.InteractionResult;
import net.minecraft.world.entity.player.Player;
import net.minecraft.world.item.ItemStack;
import net.minecraft.world.level.Level;
import net.minecraft.world.level.block.Block;
import net.minecraft.world.level.block.state.BlockState;
import net.minecraft.world.phys.BlockHitResult;
/**
* Implement this interface to indicate that this block is encasable.
*/
public interface EncasableBlock {
/**
* This method should be called in the {@link Block#use(BlockState, Level, BlockPos, Player, InteractionHand, BlockHitResult)} method.
*/
default InteractionResult tryEncase(BlockState state, Level level, BlockPos pos, ItemStack heldItem, Player player, InteractionHand hand,
BlockHitResult ray) {
List<Block> encasedVariants = EncasingRegistry.getVariants(state.getBlock());
for (Block block : encasedVariants) {
if (block instanceof EncasedBlock encased) {
if (encased.getCasing().asItem() != heldItem.getItem())
continue;
if (level.isClientSide)
return InteractionResult.SUCCESS;
encased.handleEncasing(state, level, pos, heldItem, player, hand, ray);
return InteractionResult.SUCCESS;
}
}
return InteractionResult.PASS;
}
}

View file

@ -0,0 +1,23 @@
package com.simibubi.create.content.contraptions.relays.elementary;
import net.minecraft.core.BlockPos;
import net.minecraft.world.InteractionHand;
import net.minecraft.world.entity.player.Player;
import net.minecraft.world.item.ItemStack;
import net.minecraft.world.level.Level;
import net.minecraft.world.level.block.Block;
import net.minecraft.world.level.block.state.BlockState;
import net.minecraft.world.phys.BlockHitResult;
/**
* Implement this interface to indicate that this block is encased.
*/
public interface EncasedBlock {
Block getCasing();
/**
* Handles how encasing should be done if {@link EncasableBlock#tryEncase(BlockState, Level, BlockPos, ItemStack, Player, InteractionHand, BlockHitResult)} is successful.
*/
default void handleEncasing(BlockState state, Level level, BlockPos pos, ItemStack heldItem, Player player, InteractionHand hand, BlockHitResult ray) {
}
}

View file

@ -0,0 +1,36 @@
package com.simibubi.create.content.contraptions.relays.elementary;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.function.Supplier;
import com.tterrag.registrate.builders.BlockBuilder;
import com.tterrag.registrate.util.nullness.NonNullUnaryOperator;
import net.minecraft.core.Registry;
import net.minecraft.world.level.block.Block;
public class EncasingRegistry {
private static final Map<Block, List<Block>> ENCASED_VARIANTS = new HashMap<>();
/**
* <strong>This method must not be called before block registration is finished.</strong>
*/
public static <B extends Block & EncasableBlock, E extends Block & EncasedBlock, P> void addVariant(B encasable, E encased) {
ENCASED_VARIANTS.computeIfAbsent(encasable, b -> new ArrayList<>()).add(encased);
}
public static List<Block> getVariants(Block block) {
return ENCASED_VARIANTS.getOrDefault(block, Collections.emptyList());
}
public static <B extends Block & EncasedBlock, P, E extends Block & EncasableBlock> NonNullUnaryOperator<BlockBuilder<B, P>> addVariantTo(Supplier<E> encasable) {
return builder -> {
builder.onRegisterAfter(Registry.BLOCK_REGISTRY, b -> addVariant(encasable.get(), b));
return builder;
};
}
}

View file

@ -7,7 +7,6 @@ import com.simibubi.create.AllBlocks;
import com.simibubi.create.AllShapes; import com.simibubi.create.AllShapes;
import com.simibubi.create.content.contraptions.base.KineticTileEntity; import com.simibubi.create.content.contraptions.base.KineticTileEntity;
import com.simibubi.create.content.contraptions.components.steam.PoweredShaftBlock; import com.simibubi.create.content.contraptions.components.steam.PoweredShaftBlock;
import com.simibubi.create.content.contraptions.relays.encased.EncasedShaftBlock;
import com.simibubi.create.content.curiosities.girder.GirderEncasedShaftBlock; import com.simibubi.create.content.curiosities.girder.GirderEncasedShaftBlock;
import com.simibubi.create.foundation.utility.placement.IPlacementHelper; import com.simibubi.create.foundation.utility.placement.IPlacementHelper;
import com.simibubi.create.foundation.utility.placement.PlacementHelpers; import com.simibubi.create.foundation.utility.placement.PlacementHelpers;
@ -31,7 +30,7 @@ import net.minecraft.world.phys.BlockHitResult;
import net.minecraft.world.phys.shapes.CollisionContext; import net.minecraft.world.phys.shapes.CollisionContext;
import net.minecraft.world.phys.shapes.VoxelShape; import net.minecraft.world.phys.shapes.VoxelShape;
public class ShaftBlock extends AbstractSimpleShaftBlock { public class ShaftBlock extends AbstractSimpleShaftBlock implements EncasableBlock {
public static final int placementHelperId = PlacementHelpers.register(new PlacementHelper()); public static final int placementHelperId = PlacementHelpers.register(new PlacementHelper());
@ -77,20 +76,9 @@ public class ShaftBlock extends AbstractSimpleShaftBlock {
return InteractionResult.PASS; return InteractionResult.PASS;
ItemStack heldItem = player.getItemInHand(hand); ItemStack heldItem = player.getItemInHand(hand);
for (EncasedShaftBlock encasedShaft : new EncasedShaftBlock[] { AllBlocks.ANDESITE_ENCASED_SHAFT.get(), InteractionResult result = tryEncase(state, world, pos, heldItem, player, hand, ray);
AllBlocks.BRASS_ENCASED_SHAFT.get() }) { if (result.consumesAction())
return result;
if (!encasedShaft.getCasing()
.isIn(heldItem))
continue;
if (world.isClientSide)
return InteractionResult.SUCCESS;
KineticTileEntity.switchToBlockState(world, pos, encasedShaft.defaultBlockState()
.setValue(AXIS, state.getValue(AXIS)));
return InteractionResult.SUCCESS;
}
if (AllBlocks.METAL_GIRDER.isIn(heldItem) && state.getValue(AXIS) != Axis.Y) { if (AllBlocks.METAL_GIRDER.isIn(heldItem) && state.getValue(AXIS) != Axis.Y) {
KineticTileEntity.switchToBlockState(world, pos, AllBlocks.METAL_GIRDER_ENCASED_SHAFT.getDefaultState() KineticTileEntity.switchToBlockState(world, pos, AllBlocks.METAL_GIRDER_ENCASED_SHAFT.getDefaultState()

View file

@ -1,27 +1,30 @@
package com.simibubi.create.content.contraptions.relays.encased; package com.simibubi.create.content.contraptions.relays.encased;
import java.util.function.Supplier;
import com.simibubi.create.AllBlocks; import com.simibubi.create.AllBlocks;
import com.simibubi.create.AllTileEntities; import com.simibubi.create.AllTileEntities;
import com.simibubi.create.content.contraptions.base.CasingBlock;
import com.simibubi.create.content.contraptions.base.IRotate; import com.simibubi.create.content.contraptions.base.IRotate;
import com.simibubi.create.content.contraptions.base.KineticTileEntity; import com.simibubi.create.content.contraptions.base.KineticTileEntity;
import com.simibubi.create.content.contraptions.base.RotatedPillarKineticBlock; import com.simibubi.create.content.contraptions.base.RotatedPillarKineticBlock;
import com.simibubi.create.content.contraptions.components.structureMovement.ITransformableBlock; import com.simibubi.create.content.contraptions.components.structureMovement.ITransformableBlock;
import com.simibubi.create.content.contraptions.components.structureMovement.StructureTransform; import com.simibubi.create.content.contraptions.components.structureMovement.StructureTransform;
import com.simibubi.create.content.contraptions.relays.elementary.CogWheelBlock; import com.simibubi.create.content.contraptions.relays.elementary.CogWheelBlock;
import com.simibubi.create.content.contraptions.relays.elementary.EncasedBlock;
import com.simibubi.create.content.contraptions.relays.elementary.ICogWheel; import com.simibubi.create.content.contraptions.relays.elementary.ICogWheel;
import com.simibubi.create.content.contraptions.relays.elementary.SimpleKineticTileEntity; import com.simibubi.create.content.contraptions.relays.elementary.SimpleKineticTileEntity;
import com.simibubi.create.content.schematics.ISpecialBlockItemRequirement; import com.simibubi.create.content.schematics.ISpecialBlockItemRequirement;
import com.simibubi.create.content.schematics.ItemRequirement; import com.simibubi.create.content.schematics.ItemRequirement;
import com.simibubi.create.foundation.block.ITE; import com.simibubi.create.foundation.block.ITE;
import com.simibubi.create.foundation.utility.Iterate;
import com.simibubi.create.foundation.utility.VoxelShaper; import com.simibubi.create.foundation.utility.VoxelShaper;
import com.tterrag.registrate.util.entry.BlockEntry;
import net.minecraft.core.BlockPos; import net.minecraft.core.BlockPos;
import net.minecraft.core.Direction; import net.minecraft.core.Direction;
import net.minecraft.core.Direction.Axis; import net.minecraft.core.Direction.Axis;
import net.minecraft.core.Direction.AxisDirection; import net.minecraft.core.Direction.AxisDirection;
import net.minecraft.core.NonNullList; import net.minecraft.core.NonNullList;
import net.minecraft.world.InteractionHand;
import net.minecraft.world.InteractionResult; import net.minecraft.world.InteractionResult;
import net.minecraft.world.entity.player.Player; import net.minecraft.world.entity.player.Player;
import net.minecraft.world.item.CreativeModeTab; import net.minecraft.world.item.CreativeModeTab;
@ -43,23 +46,15 @@ import net.minecraft.world.phys.BlockHitResult;
import net.minecraft.world.phys.HitResult; import net.minecraft.world.phys.HitResult;
public class EncasedCogwheelBlock extends RotatedPillarKineticBlock public class EncasedCogwheelBlock extends RotatedPillarKineticBlock
implements ICogWheel, ITE<SimpleKineticTileEntity>, ISpecialBlockItemRequirement, ITransformableBlock { implements ICogWheel, ITE<SimpleKineticTileEntity>, ISpecialBlockItemRequirement, ITransformableBlock, EncasedBlock {
public static final BooleanProperty TOP_SHAFT = BooleanProperty.create("top_shaft"); public static final BooleanProperty TOP_SHAFT = BooleanProperty.create("top_shaft");
public static final BooleanProperty BOTTOM_SHAFT = BooleanProperty.create("bottom_shaft"); public static final BooleanProperty BOTTOM_SHAFT = BooleanProperty.create("bottom_shaft");
boolean isLarge; protected final boolean isLarge;
private BlockEntry<CasingBlock> casing; private final Supplier<Block> casing;
public static EncasedCogwheelBlock andesite(boolean large, Properties properties) { public EncasedCogwheelBlock(Properties properties, boolean large, Supplier<Block> casing) {
return new EncasedCogwheelBlock(large, properties, AllBlocks.ANDESITE_CASING);
}
public static EncasedCogwheelBlock brass(boolean large, Properties properties) {
return new EncasedCogwheelBlock(large, properties, AllBlocks.BRASS_CASING);
}
public EncasedCogwheelBlock(boolean large, Properties properties, BlockEntry<CasingBlock> casing) {
super(properties); super(properties);
isLarge = large; isLarge = large;
this.casing = casing; this.casing = casing;
@ -81,7 +76,7 @@ public class EncasedCogwheelBlock extends RotatedPillarKineticBlock
return ((BlockHitResult) target).getDirection() return ((BlockHitResult) target).getDirection()
.getAxis() != getRotationAxis(state) .getAxis() != getRotationAxis(state)
? isLarge ? AllBlocks.LARGE_COGWHEEL.asStack() : AllBlocks.COGWHEEL.asStack() ? isLarge ? AllBlocks.LARGE_COGWHEEL.asStack() : AllBlocks.COGWHEEL.asStack()
: getCasing().asStack(); : getCasing().asItem().getDefaultInstance();
return super.getCloneItemStack(state, target, world, pos, player); return super.getCloneItemStack(state, target, world, pos, player);
} }
@ -98,10 +93,6 @@ public class EncasedCogwheelBlock extends RotatedPillarKineticBlock
return stateForPlacement; return stateForPlacement;
} }
public BlockEntry<CasingBlock> getCasing() {
return casing;
}
@Override @Override
public boolean skipRendering(BlockState pState, BlockState pAdjacentBlockState, Direction pDirection) { public boolean skipRendering(BlockState pState, BlockState pAdjacentBlockState, Direction pDirection) {
return pState.getBlock() == pAdjacentBlockState.getBlock() return pState.getBlock() == pAdjacentBlockState.getBlock()
@ -276,4 +267,29 @@ public class EncasedCogwheelBlock extends RotatedPillarKineticBlock
return isLarge ? AllTileEntities.ENCASED_LARGE_COGWHEEL.get() : AllTileEntities.ENCASED_COGWHEEL.get(); return isLarge ? AllTileEntities.ENCASED_LARGE_COGWHEEL.get() : AllTileEntities.ENCASED_COGWHEEL.get();
} }
@Override
public Block getCasing() {
return casing.get();
}
@Override
public void handleEncasing(BlockState state, Level level, BlockPos pos, ItemStack heldItem, Player player, InteractionHand hand,
BlockHitResult ray) {
BlockState encasedState = defaultBlockState()
.setValue(AXIS, state.getValue(AXIS));
for (Direction d : Iterate.directionsInAxis(state.getValue(AXIS))) {
BlockState adjacentState = level.getBlockState(pos.relative(d));
if (!(adjacentState.getBlock() instanceof IRotate))
continue;
IRotate def = (IRotate) adjacentState.getBlock();
if (!def.hasShaftTowards(level, pos.relative(d), adjacentState, d.getOpposite()))
continue;
encasedState =
encasedState.cycle(d.getAxisDirection() == AxisDirection.POSITIVE ? EncasedCogwheelBlock.TOP_SHAFT
: EncasedCogwheelBlock.BOTTOM_SHAFT);
}
KineticTileEntity.switchToBlockState(level, pos, encasedState);
}
} }

View file

@ -1,22 +1,26 @@
package com.simibubi.create.content.contraptions.relays.encased; package com.simibubi.create.content.contraptions.relays.encased;
import java.util.function.Supplier;
import com.simibubi.create.AllBlocks; import com.simibubi.create.AllBlocks;
import com.simibubi.create.AllTileEntities; import com.simibubi.create.AllTileEntities;
import com.simibubi.create.content.contraptions.base.CasingBlock;
import com.simibubi.create.content.contraptions.base.KineticTileEntity; import com.simibubi.create.content.contraptions.base.KineticTileEntity;
import com.simibubi.create.content.contraptions.base.RotatedPillarKineticBlock;
import com.simibubi.create.content.contraptions.relays.elementary.EncasedBlock;
import com.simibubi.create.content.schematics.ISpecialBlockItemRequirement; import com.simibubi.create.content.schematics.ISpecialBlockItemRequirement;
import com.simibubi.create.content.schematics.ItemRequirement; import com.simibubi.create.content.schematics.ItemRequirement;
import com.simibubi.create.foundation.block.ITE; import com.simibubi.create.foundation.block.ITE;
import com.tterrag.registrate.util.entry.BlockEntry;
import net.minecraft.core.BlockPos; import net.minecraft.core.BlockPos;
import net.minecraft.core.NonNullList; import net.minecraft.core.NonNullList;
import net.minecraft.world.InteractionHand;
import net.minecraft.world.InteractionResult; import net.minecraft.world.InteractionResult;
import net.minecraft.world.entity.player.Player; import net.minecraft.world.entity.player.Player;
import net.minecraft.world.item.CreativeModeTab; import net.minecraft.world.item.CreativeModeTab;
import net.minecraft.world.item.ItemStack; import net.minecraft.world.item.ItemStack;
import net.minecraft.world.item.context.UseOnContext; import net.minecraft.world.item.context.UseOnContext;
import net.minecraft.world.level.BlockGetter; import net.minecraft.world.level.BlockGetter;
import net.minecraft.world.level.Level;
import net.minecraft.world.level.block.Block; import net.minecraft.world.level.block.Block;
import net.minecraft.world.level.block.entity.BlockEntity; import net.minecraft.world.level.block.entity.BlockEntity;
import net.minecraft.world.level.block.entity.BlockEntityType; import net.minecraft.world.level.block.entity.BlockEntityType;
@ -25,27 +29,15 @@ import net.minecraft.world.phys.BlockHitResult;
import net.minecraft.world.phys.HitResult; import net.minecraft.world.phys.HitResult;
public class EncasedShaftBlock extends AbstractEncasedShaftBlock public class EncasedShaftBlock extends AbstractEncasedShaftBlock
implements ITE<KineticTileEntity>, ISpecialBlockItemRequirement { implements ITE<KineticTileEntity>, ISpecialBlockItemRequirement, EncasedBlock {
private BlockEntry<CasingBlock> casing; private final Supplier<Block> casing;
public static EncasedShaftBlock andesite(Properties properties) { public EncasedShaftBlock(Properties properties, Supplier<Block> casing) {
return new EncasedShaftBlock(properties, AllBlocks.ANDESITE_CASING);
}
public static EncasedShaftBlock brass(Properties properties) {
return new EncasedShaftBlock(properties, AllBlocks.BRASS_CASING);
}
protected EncasedShaftBlock(Properties properties, BlockEntry<CasingBlock> casing) {
super(properties); super(properties);
this.casing = casing; this.casing = casing;
} }
public BlockEntry<CasingBlock> getCasing() {
return casing;
}
@Override @Override
public void fillItemCategory(CreativeModeTab pTab, NonNullList<ItemStack> pItems) {} public void fillItemCategory(CreativeModeTab pTab, NonNullList<ItemStack> pItems) {}
@ -65,7 +57,7 @@ public class EncasedShaftBlock extends AbstractEncasedShaftBlock
public ItemStack getCloneItemStack(BlockState state, HitResult target, BlockGetter world, BlockPos pos, Player player) { public ItemStack getCloneItemStack(BlockState state, HitResult target, BlockGetter world, BlockPos pos, Player player) {
if (target instanceof BlockHitResult) if (target instanceof BlockHitResult)
return ((BlockHitResult) target).getDirection() return ((BlockHitResult) target).getDirection()
.getAxis() == getRotationAxis(state) ? AllBlocks.SHAFT.asStack() : getCasing().asStack(); .getAxis() == getRotationAxis(state) ? AllBlocks.SHAFT.asStack() : getCasing().asItem().getDefaultInstance();
return super.getCloneItemStack(state, target, world, pos, player); return super.getCloneItemStack(state, target, world, pos, player);
} }
@ -84,4 +76,15 @@ public class EncasedShaftBlock extends AbstractEncasedShaftBlock
return AllTileEntities.ENCASED_SHAFT.get(); return AllTileEntities.ENCASED_SHAFT.get();
} }
@Override
public Block getCasing() {
return casing.get();
}
@Override
public void handleEncasing(BlockState state, Level level, BlockPos pos, ItemStack heldItem, Player player, InteractionHand hand,
BlockHitResult ray) {
KineticTileEntity.switchToBlockState(level, pos, defaultBlockState()
.setValue(RotatedPillarKineticBlock.AXIS, state.getValue(RotatedPillarKineticBlock.AXIS)));
}
} }