Created
July 31, 2022 17:34
-
-
Save Lanse505/4e077a688e8781ea5df90f4b775f26b0 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package matteroverdrive.core.block; | |
import com.hrznstudio.titanium.block.BasicTileBlock; | |
import com.hrznstudio.titanium.block.tile.BasicTile; | |
import net.minecraft.world.level.block.RenderShape; | |
import net.minecraft.world.level.block.state.BlockState; | |
public abstract class GenericEntityBlock<T extends BasicTile<T>> extends BasicTileBlock<T> { | |
/** | |
* Default Constructor for GenericEntityBlock. | |
* | |
* @param properties The blocks BlockBehaviour Properties. | |
* @param name The "name" of the block (IE. "charger_block") | |
* @param tileClass The BlockEntity Class for the block. | |
*/ | |
protected GenericEntityBlock(Properties properties, String name, Class<T> tileClass) { | |
super(name, properties, tileClass); | |
} | |
/** | |
* Override this to change the RenderShape if we need a TESR. | |
* INVISIBLE: {@link RenderShape#INVISIBLE} = No Rendering | |
* MODEL: {@link RenderShape#MODEL} = Model-based Rendering | |
* ENTITYBLOCK_ANIMATED: {@link RenderShape#ENTITYBLOCK_ANIMATED} = Model + TESR | |
* | |
* We are provided the {@link BlockState} of the block for use to decide if the blocks RenderShape needs to change. | |
* Potential optimisation would be if we add animations to the blocks that only if a "running" state is active. | |
* To use {@link RenderShape#ENTITYBLOCK_ANIMATED} otherwise use {@link RenderShape#MODEL} | |
* @param state The state of the block. | |
* @return returns the {@link RenderShape} of the block, using the state as a variable for the shape. | |
*/ | |
@Override | |
@SuppressWarnings({"deprecation"}) | |
public RenderShape getRenderShape(BlockState state) { | |
return RenderShape.MODEL; | |
} | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package matteroverdrive.core.block; | |
import com.hrznstudio.titanium.block.RotatableBlock.RotationType; | |
import com.hrznstudio.titanium.block.RotationHandler; | |
import com.hrznstudio.titanium.block.tile.BasicTile; | |
import matteroverdrive.core.block.state.StateVariables; | |
import net.minecraft.core.BlockPos; | |
import net.minecraft.core.Direction; | |
import net.minecraft.world.item.context.BlockPlaceContext; | |
import net.minecraft.world.level.Level; | |
import net.minecraft.world.level.LevelAccessor; | |
import net.minecraft.world.level.block.Block; | |
import net.minecraft.world.level.block.Mirror; | |
import net.minecraft.world.level.block.Rotation; | |
import net.minecraft.world.level.block.state.BlockState; | |
import net.minecraft.world.level.block.state.StateDefinition; | |
import net.minecraft.world.level.block.state.properties.BlockStateProperties; | |
import net.minecraft.world.level.material.FluidState; | |
import net.minecraft.world.level.material.Fluids; | |
import org.jetbrains.annotations.Nullable; | |
public abstract class GenericStateVariableBlock<T extends BasicTile<T>> extends GenericEntityBlock<T> { | |
/** | |
* Value set for if the block should be waterloggable, defaults to false. | |
*/ | |
private final boolean isWaterloggable; | |
/** | |
* Value set for if the block has a {@link RotationType}, defaults to {@link RotationType#NONE} | |
*/ | |
private final RotationType rotationType; | |
/** | |
* Default Constructor for GenericStateVariableBlock. | |
* | |
* @param properties The blocks BlockBehaviour Properties. | |
* @param stateVariables The state variables for the block. | |
* @param name The "name" of the block (IE. "charger_block") | |
* @param tileClass The BlockEntity Class for the block. | |
*/ | |
protected GenericStateVariableBlock(Properties properties, StateVariables stateVariables, String name, Class<T> tileClass) { | |
super(properties, name, tileClass); | |
this.isWaterloggable = stateVariables.getIsWaterloggable(); | |
this.rotationType = stateVariables.getRotationType() != null ? stateVariables.getRotationType() : RotationType.NONE; | |
BlockState defaultState = getStateDefinition().any(); | |
if (isWaterloggable) { | |
defaultState.setValue(BlockStateProperties.WATERLOGGED, false); | |
} | |
} | |
/** | |
* Getter for RotationType. | |
* | |
* @return returns the blocks {@link RotationType}. | |
*/ | |
public RotationType getRotationType() { | |
return rotationType; | |
} | |
/** | |
* Logic goes: | |
* 1. Get the Default {@link BlockState} + Modifications by the {@link RotationHandler}. | |
* 2. Get the {@link FluidState} -> If the fluidstate is of type {@link Fluids#WATER} then set the value of {@link BlockStateProperties#WATERLOGGED} to true. | |
* | |
* @param context The context for the block placement. | |
* @return Returns the BlockState of the placed block to use. | |
*/ | |
@Nullable | |
@Override | |
public BlockState getStateForPlacement(BlockPlaceContext context) { | |
BlockState stateWithRotation = this.getRotationType().getHandler().getStateForPlacement(this, context); | |
FluidState fluidState = context.getLevel().getFluidState(context.getClickedPos()); | |
return fluidState.getType() == Fluids.WATER ? stateWithRotation.setValue(BlockStateProperties.WATERLOGGED, true) : stateWithRotation; | |
} | |
/** | |
* Used to update the fluid if need be, by scheduling a fluid tick with a delayed value. | |
* | |
* @param state The {@link BlockState} of the {@link Block} whose shape needs updating. | |
* @param direction The direction of the {@link Block}. | |
* @param neighborState The neighbouring {@link BlockState}. | |
* @param level The {@link Level} of the {@link Block}. | |
* @param currentPos The current {@link BlockPos} of the {@link Block}. | |
* @param neighborPos The neighbouring {@link Block}'s {@link BlockPos}. | |
* @return Returns the blocks state unless modifications occur. | |
*/ | |
@SuppressWarnings("deprecation") | |
@Override | |
public BlockState updateShape(BlockState state, Direction direction, BlockState neighborState, LevelAccessor level, BlockPos currentPos, BlockPos neighborPos) { | |
if (state.getValue(BlockStateProperties.WATERLOGGED)) { | |
level.scheduleTick(currentPos, Fluids.WATER, Fluids.WATER.getTickDelay(level)); | |
} | |
return super.updateShape(state, direction, neighborState, level, currentPos, neighborPos); | |
} | |
/** | |
* Override the default getFluidState method to be able to return the Water fluid if the block is waterlogged. | |
* | |
* @param state The {@link BlockState} of the {@link Block}. | |
* @return Returns the {@link FluidState} of the {@link Block}. | |
*/ | |
@SuppressWarnings("deprecation") | |
@Override | |
public FluidState getFluidState(BlockState state) { | |
return state.getValue(BlockStateProperties.WATERLOGGED) ? Fluids.WATER.getSource(false) : super.getFluidState(state); | |
} | |
/** | |
* Creates our default {@link StateDefinition}. | |
* In our case: | |
* - If {@link #isWaterloggable} is true then it adds the {@link BlockStateProperties#WATERLOGGED} property. | |
* - If our {@link #rotationType)'s "property" list isn't null then we can add the associated properties of our {@link RotationType}. | |
* | |
* @param builder The passed in {@link net.minecraft.world.level.block.state.StateDefinition.Builder} for adding the properties to. | |
*/ | |
@Override | |
protected void createBlockStateDefinition(StateDefinition.Builder<Block, BlockState> builder) { | |
super.createBlockStateDefinition(builder); | |
if (isWaterloggable) { | |
builder.add(BlockStateProperties.WATERLOGGED); | |
} | |
if (this.rotationType.getProperties().length > 0) { | |
builder.add(this.rotationType.getProperties()); | |
} | |
} | |
/** | |
* Rotates our {@link Block} using our blocks provided {@link RotationType} handler. | |
* | |
* @param state The current {@link BlockState} of the {@link Block}. | |
* @param rotation The current {@link Rotation} of the {@link Block}. | |
* @return Returns the new state of the block. | |
*/ | |
@SuppressWarnings("deprecation") | |
@Override | |
public BlockState rotate(BlockState state, Rotation rotation) { | |
if (getRotationType().getProperties().length > 0){ | |
return state.setValue(getRotationType().getProperties()[0], rotation.rotate(state.getValue(getRotationType().getProperties()[0]))); | |
} | |
return super.rotate(state, rotation); | |
} | |
/** | |
* Mirrors our {@link Block} using our blocks provided {@link RotationType} handler. | |
* | |
* @param state The current {@link BlockState} of the {@link Block}. | |
* @param mirror The current {@link Mirror} state of the {@link Block}. | |
* @return Returns the new state of the block. | |
*/ | |
@SuppressWarnings("deprecation") | |
@Override | |
public BlockState mirror(BlockState state, Mirror mirror) { | |
if (getRotationType().getProperties().length > 0){ | |
return state.rotate(mirror.getRotation(state.getValue(getRotationType().getProperties()[0]))); | |
} | |
return super.mirror(state, mirror); | |
} | |
} | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package matteroverdrive.core.block.state; | |
import com.hrznstudio.titanium.block.RotatableBlock; | |
import javax.annotation.Nullable; | |
public class StateVariables { | |
/** | |
* | |
*/ | |
boolean isWaterloggable; | |
/** | |
* | |
*/ | |
@Nullable | |
RotatableBlock.RotationType rotationType; | |
/** | |
* Empty Private Constructor to make it so people don't instantiate new objects directly. | |
*/ | |
private StateVariables() {} | |
/** | |
* @return Returns a new {@link StateVariables} object. | |
*/ | |
public static StateVariables getBuilder() { | |
return new StateVariables(); | |
} | |
/** | |
* Copies another StateVariables object into a new builder object. | |
* | |
* @param variables | |
* @return | |
*/ | |
public static StateVariables copy(StateVariables variables) { | |
StateVariables copy = new StateVariables(); | |
copy.isWaterloggable = variables.isWaterloggable; | |
copy.rotationType = variables.rotationType; | |
return copy; | |
} | |
/** | |
* @return | |
*/ | |
public StateVariables isWaterloggable() { | |
this.isWaterloggable = true; | |
return this; | |
} | |
/** | |
* @param rotationType | |
* @return | |
*/ | |
public StateVariables rotationType(@Nullable RotatableBlock.RotationType rotationType) { | |
this.rotationType = rotationType; | |
return this; | |
} | |
/** | |
* @return | |
*/ | |
public boolean getIsWaterloggable() { | |
return isWaterloggable; | |
} | |
/** | |
* @return | |
*/ | |
@Nullable | |
public RotatableBlock.RotationType getRotationType() { | |
return rotationType; | |
} | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package matteroverdrive.core.block; | |
import com.hrznstudio.titanium.block.BasicTileBlock; | |
import com.hrznstudio.titanium.block.tile.BasicTile; | |
import matteroverdrive.core.block.state.StateVariables; | |
import net.minecraft.core.BlockPos; | |
import net.minecraft.core.Direction; | |
import net.minecraft.world.InteractionHand; | |
import net.minecraft.world.InteractionResult; | |
import net.minecraft.world.entity.player.Player; | |
import net.minecraft.world.level.Level; | |
import net.minecraft.world.level.block.SoundType; | |
import net.minecraft.world.level.block.entity.BlockEntity; | |
import net.minecraft.world.level.block.state.BlockState; | |
import net.minecraft.world.level.material.Material; | |
import net.minecraft.world.phys.BlockHitResult; | |
import org.jetbrains.annotations.Nullable; | |
public abstract class GenericMachineBlock<T extends BasicTile<T>> extends GenericStateVariableEntityBlock<T> { | |
// Defaults | |
/** | |
* Default Machine Block Properties | |
*/ | |
private static final Properties defaultMachineProperties = Properties.of(Material.METAL) | |
.strength(3.5F).sound(SoundType.METAL).noOcclusion().requiresCorrectToolForDrops(); | |
/** | |
* Default Waterloggable StateVariables | |
*/ | |
private static final StateVariables defaultWaterloggableVariables = StateVariables.getBuilder().isWaterloggable(); | |
/** | |
* Constructor that doesn't use the "Default Machine Properties" | |
* Note: This also does not provide a default StateVariable config! | |
* | |
* @param properties The blocks BlockBehaviour Properties. | |
* @param stateVariables The state variables for the block. | |
* @param name The "name" of the block (IE. "charger_block") | |
* @param tileClass The BlockEntity Class for the block. | |
*/ | |
protected GenericMachineBlock(Properties properties, StateVariables stateVariables, String name, Class<T> tileClass) { | |
super(properties, stateVariables, name, tileClass); | |
} | |
/** | |
* Constructor that uses the "Default Machine Properties" | |
* Note: This does not provide a default StateVariable config! | |
* | |
* @param stateVariables The state variables for the block. | |
* @param name The "name" of the block (IE. "charger_block") | |
* @param tileClass The BlockEntity Class for the block. | |
*/ | |
protected GenericMachineBlock(StateVariables stateVariables, String name, Class<T> tileClass) { | |
super(defaultMachineProperties, stateVariables, name, tileClass); | |
} | |
/** | |
* So you might be looking at this in the future asking where the old handling code went? | |
* Well I'll tell you! to consolidate behaviour and handling, this code now exists **ON** the BlockEntity itself. | |
* See the BlockEntity's implementation of {@link BasicTile#onActivated(Player, InteractionHand, Direction, double, double, double)} | |
* Also see {@link BasicTileBlock#use(BlockState, Level, BlockPos, Player, InteractionHand, BlockHitResult)} | |
* For where it's calling the #onActivated on the Tile! | |
*/ | |
@Override | |
public InteractionResult use(BlockState state, Level level, BlockPos pos, Player player, InteractionHand hand, BlockHitResult ray) { | |
if (level.isClientSide()) return InteractionResult.SUCCESS; | |
return super.use(state, level, pos, player, hand, ray); | |
} | |
/** | |
* So this method gets overriden in {@link BasicTileBlock#newBlockEntity(BlockPos, BlockState)} | |
* Which defaults to a new method called {@link BasicTileBlock#getTileEntityFactory()} | |
* This method is what gets overriden on new blocks and where we provide the BlockEntity creation! | |
* | |
* @param pos The position of the block where the BlockEntity is created. | |
* @param state The state of the block which is creating the BlockEntity. | |
* @return Returns the new BlockEntity instance. | |
*/ | |
@Nullable | |
@Override | |
public BlockEntity newBlockEntity(BlockPos pos, BlockState state) { | |
return super.newBlockEntity(pos, state); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment