Skip to content

Commit

Permalink
feat(block): cattail rewrite
Browse files Browse the repository at this point in the history
  • Loading branch information
CallMeEchoCodes committed Nov 26, 2024
1 parent 95be990 commit f3937b9
Show file tree
Hide file tree
Showing 18 changed files with 254 additions and 168 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,5 @@
],
"rolls": 1.0
}
],
"random_sequence": "hollow:blocks/cattail"
]
}
20 changes: 20 additions & 0 deletions src/main/generated/data/hollow/loot_table/blocks/cattail_stem.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
{
"type": "minecraft:block",
"pools": [
{
"bonus_rolls": 0.0,
"conditions": [
{
"condition": "minecraft:survives_explosion"
}
],
"entries": [
{
"type": "minecraft:item",
"name": "hollow:cattail"
}
],
"rolls": 1.0
}
]
}
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,5 @@
],
"rolls": 1.0
}
],
"random_sequence": "hollow:blocks/twig"
]
}

This file was deleted.

139 changes: 67 additions & 72 deletions src/main/java/dev/spiritstudios/hollow/block/CattailBlock.java
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
package dev.spiritstudios.hollow.block;

import com.llamalad7.mixinextras.sugar.Share;
import com.mojang.serialization.MapCodec;
import dev.spiritstudios.hollow.registry.HollowBlockRegistrar;
import net.minecraft.SharedConstants;
import net.minecraft.block.*;
import net.minecraft.entity.player.PlayerEntity;
import net.minecraft.fluid.Fluid;
Expand All @@ -11,11 +14,10 @@
import net.minecraft.server.world.ServerWorld;
import net.minecraft.state.StateManager;
import net.minecraft.state.property.BooleanProperty;
import net.minecraft.state.property.EnumProperty;
import net.minecraft.state.property.Properties;
import net.minecraft.util.StringIdentifiable;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.Direction;
import net.minecraft.util.math.MathHelper;
import net.minecraft.util.math.random.Random;
import net.minecraft.util.shape.VoxelShape;
import net.minecraft.world.BlockView;
Expand All @@ -24,94 +26,63 @@
import net.minecraft.world.WorldView;
import org.jetbrains.annotations.Nullable;

import java.util.Locale;

public class CattailBlock extends PlantBlock implements Fertilizable, FluidFillable {
public class CattailBlock extends AbstractPlantStemBlock implements FluidFillable {
public static final MapCodec<CattailBlock> CODEC = createCodec(CattailBlock::new);
public static final EnumProperty<Piece> PIECE = EnumProperty.of("reeds_part", Piece.class);
public static final BooleanProperty WATERLOGGED = Properties.WATERLOGGED;

protected static final VoxelShape SHAPE = Block.createCuboidShape(2.0, 0.0, 2.0, 14.0, 16.0, 14.0);

public CattailBlock(AbstractBlock.Settings settings) {
super(settings);

this.setDefaultState(this.stateManager.getDefaultState().with(PIECE, Piece.BASE).with(WATERLOGGED, true));
super(settings, Direction.UP, SHAPE, true, 0.14);
setDefaultState(getDefaultState().with(WATERLOGGED, false));
}

@Override
protected void appendProperties(StateManager.Builder<Block, BlockState> builder) {
builder.add(PIECE);
super.appendProperties(builder);
builder.add(WATERLOGGED);
}

@Override
protected MapCodec<? extends PlantBlock> getCodec() {
return CODEC;
protected int getGrowthLength(Random random) {
return 1;
}


@Override
public boolean canFillWithFluid(@Nullable PlayerEntity player, BlockView world, BlockPos pos, BlockState state, Fluid fluid) {
return false;
protected boolean chooseStemState(BlockState state) {
return true;
}

@Override
public boolean tryFillWithFluid(WorldAccess world, BlockPos pos, BlockState state, FluidState fluidState) {
return false;
protected MapCodec<CattailBlock> getCodec() {
return CODEC;
}

@Nullable
@Override
public BlockState getPlacementState(ItemPlacementContext ctx) {
BlockState belowState = ctx.getWorld().getBlockState(ctx.getBlockPos().down());
FluidState fluidState = ctx.getWorld().getFluidState(ctx.getBlockPos());
if (belowState.isOf(this)) {
return super.getPlacementState(ctx).with(PIECE, Piece.TOP).with(WATERLOGGED, fluidState.isIn(FluidTags.WATER));
}

if (fluidState.isIn(FluidTags.WATER) && fluidState.getLevel() == 8) {
return super.getPlacementState(ctx);
}

return null;
protected Block getPlant() {
return HollowBlockRegistrar.CATTAIL_STEM;
}

@Override
protected boolean canPlaceAt(BlockState state, WorldView world, BlockPos pos) {
boolean canPlace = true;
if (state.get(PIECE) == Piece.BASE) {
FluidState fluidState = world.getFluidState(pos);
if (!fluidState.isIn(FluidTags.WATER) || fluidState.getLevel() != 8) canPlace = false;
protected BlockState getStateForNeighborUpdate(BlockState state, Direction direction, BlockState neighborState, WorldAccess world, BlockPos pos, BlockPos neighborPos) {
BlockState below = world.getBlockState(pos.down());

}
return super.canPlaceAt(state, world, pos) && canPlace;
}

@Override
protected VoxelShape getOutlineShape(BlockState state, BlockView world, BlockPos pos, ShapeContext context) {
return SHAPE;
return super.getStateForNeighborUpdate(state, direction, neighborState, world, pos, neighborPos)
.withIfExists(WATERLOGGED, world.isWater(pos))
.withIfExists(CattailStemBlock.BOTTOM, !below.isOf(this) && !below.isOf(getPlant()));
}

@Nullable
@Override
protected BlockState getStateForNeighborUpdate(
BlockState state, Direction direction, BlockState neighborState, WorldAccess world, BlockPos pos, BlockPos neighborPos
) {
BlockState blockState = super.getStateForNeighborUpdate(state, direction, neighborState, world, pos, neighborPos);
if (!blockState.isAir()) world.scheduleFluidTick(pos, Fluids.WATER, Fluids.WATER.getTickRate(world));

if (direction == Direction.UP && neighborState.isOf(this) && state.get(PIECE) == Piece.TOP)
return blockState.with(PIECE, Piece.MIDDLE);

if (direction == Direction.UP && !neighborState.isOf(this) && state.get(PIECE) == Piece.MIDDLE)
return Blocks.AIR.getDefaultState();
public BlockState getPlacementState(ItemPlacementContext ctx) {
FluidState fluidState = ctx.getWorld().getFluidState(ctx.getBlockPos());
BlockState below = ctx.getWorld().getBlockState(ctx.getBlockPos().down());

return blockState;
}

@Override
protected boolean canPlantOnTop(BlockState floor, BlockView world, BlockPos pos) {
return super.canPlantOnTop(floor, world, pos) || floor.isOf(this);
return (fluidState.isIn(FluidTags.WATER) && fluidState.getLevel() == 8) || below.isOf(this) ?
super.getPlacementState(ctx).with(WATERLOGGED, fluidState.isIn(FluidTags.WATER))
.withIfExists(CattailStemBlock.BOTTOM, !below.isOf(this) && !below.isOf(getPlant()))
:
null;
}

@Override
Expand All @@ -120,26 +91,50 @@ protected FluidState getFluidState(BlockState state) {
}

@Override
public boolean isFertilizable(WorldView world, BlockPos pos, BlockState state) {
return true;
}
protected void randomTick(BlockState state, ServerWorld world, BlockPos pos, Random random) {
if (state.get(AGE) >= 25 || !(random.nextDouble() < 0.14)) return;
int outOfWater = 0;
BlockPos waterPos = pos;
while (!world.isWater(waterPos)) {
waterPos = waterPos.down();
outOfWater++;
if (outOfWater > 3) break;
}

@Override
public boolean canGrow(World world, Random random, BlockPos pos, BlockState state) {
return true;
if (outOfWater > 3) return;

BlockPos blockPos = pos.offset(this.growthDirection);
if (this.chooseStemState(world.getBlockState(blockPos)))
world.setBlockState(
blockPos,
this.age(state, world.random)
.with(WATERLOGGED, world.isWater(blockPos))
);
}

@Override
public void grow(ServerWorld world, Random random, BlockPos pos, BlockState state) {

BlockPos blockPos = pos.offset(this.growthDirection);
int age = Math.min(state.get(AGE) + 1, 25);
int length = this.getGrowthLength(random);

for (int i = 0; i < length && this.chooseStemState(world.getBlockState(blockPos)); i++) {
world.setBlockState(
blockPos,
state.with(AGE, age).with(WATERLOGGED, world.isWater(blockPos))
);
blockPos = blockPos.offset(this.growthDirection);
age = Math.min(age + 1, 25);
}
}

public enum Piece implements StringIdentifiable {
TOP,
MIDDLE,
BASE;
@Override
public boolean canFillWithFluid(@Nullable PlayerEntity player, BlockView world, BlockPos pos, BlockState state, Fluid fluid) {
return false;
}

@Override
public String asString() { return this.name().toLowerCase(Locale.ROOT); }
@Override
public boolean tryFillWithFluid(WorldAccess world, BlockPos pos, BlockState state, FluidState fluidState) {
return false;
}
}
83 changes: 83 additions & 0 deletions src/main/java/dev/spiritstudios/hollow/block/CattailStemBlock.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
package dev.spiritstudios.hollow.block;

import com.mojang.serialization.Codec;
import com.mojang.serialization.MapCodec;
import dev.spiritstudios.hollow.registry.HollowBlockRegistrar;
import net.minecraft.block.*;
import net.minecraft.entity.player.PlayerEntity;
import net.minecraft.fluid.Fluid;
import net.minecraft.fluid.FluidState;
import net.minecraft.fluid.Fluids;
import net.minecraft.item.ItemPlacementContext;
import net.minecraft.registry.tag.FluidTags;
import net.minecraft.state.StateManager;
import net.minecraft.state.property.BooleanProperty;
import net.minecraft.state.property.Properties;
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.util.shape.VoxelShapes;
import net.minecraft.world.*;
import org.jetbrains.annotations.Nullable;

public class CattailStemBlock extends AbstractPlantBlock implements FluidFillable {
public static final MapCodec<CattailStemBlock> CODEC = createCodec(CattailStemBlock::new);
public static final BooleanProperty WATERLOGGED = Properties.WATERLOGGED;
public static final BooleanProperty BOTTOM = Properties.BOTTOM;

public CattailStemBlock(AbstractBlock.Settings settings) {
super(settings, Direction.UP, VoxelShapes.fullCube(), true);
setDefaultState(getDefaultState().with(BOTTOM, false));
}

@Override
protected void appendProperties(StateManager.Builder<Block, BlockState> builder) {
super.appendProperties(builder);
builder.add(WATERLOGGED, BOTTOM);
}

@Override
protected MapCodec<CattailStemBlock> getCodec() {
return CODEC;
}

@Override
protected AbstractPlantStemBlock getStem() {
return HollowBlockRegistrar.CATTAIL;
}

@Nullable
@Override
public BlockState getPlacementState(ItemPlacementContext ctx) {
BlockState below = ctx.getWorld().getBlockState(ctx.getBlockPos().down());

return super.getPlacementState(ctx)
.with(WATERLOGGED, ctx.getWorld().isWater(ctx.getBlockPos()))
.with(BOTTOM, !below.isOf(this) && !below.isOf(getStem()));
}

@Override
protected BlockState getStateForNeighborUpdate(BlockState state, Direction direction, BlockState neighborState, WorldAccess world, BlockPos pos, BlockPos neighborPos) {
if (direction != Direction.DOWN) return super.getStateForNeighborUpdate(state, direction, neighborState, world, pos, neighborPos).withIfExists(WATERLOGGED, world.isWater(pos));

return super.getStateForNeighborUpdate(state, direction, neighborState, world, pos, neighborPos)
.withIfExists(BOTTOM, !neighborState.isOf(this) && !neighborState.isOf(getStem()))
.withIfExists(WATERLOGGED, world.isWater(pos));
}

@Override
protected FluidState getFluidState(BlockState state) {
return state.get(WATERLOGGED) ? Fluids.WATER.getStill(false) : super.getFluidState(state);
}

@Override
public boolean canFillWithFluid(@Nullable PlayerEntity player, BlockView world, BlockPos pos, BlockState state, Fluid fluid) {
return false;
}

@Override
public boolean tryFillWithFluid(WorldAccess world, BlockPos pos, BlockState state, FluidState fluidState) {
return false;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -34,8 +34,8 @@ public EchoingPotBlock(Settings settings) {
}

public static final VoxelShape SHAPE = VoxelShapes.union(
Block.createCuboidShape(1, 0, 1, 15, 13, 15),
Block.createCuboidShape(3, 13, 3, 13, 15, 13)
Block.createCuboidShape(1, 0, 1, 15, 14, 15),
Block.createCuboidShape(4, 14, 4, 12, 16, 12)
);

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,8 @@
import net.minecraft.server.MinecraftServer;
import net.minecraft.server.network.ServerPlayerEntity;
import net.minecraft.server.world.ServerWorld;
import net.minecraft.sound.SoundCategory;
import net.minecraft.sound.SoundEvents;
import net.minecraft.util.Hand;
import net.minecraft.util.ItemActionResult;
import net.minecraft.util.math.BlockPos;
Expand Down Expand Up @@ -84,6 +86,16 @@ public ItemActionResult use(PlayerEntity player, Hand hand, Direction side) {

setStack(slot, player.getStackInHand(hand));
player.setStackInHand(hand, ItemStack.EMPTY);

if (!inventory.isEmpty() && !player.getWorld().isClient()) player.getWorld().playSound(
null,
pos,
SoundEvents.ENTITY_ITEM_PICKUP,
SoundCategory.PLAYERS,
0.2f,
((player.getRandom().nextFloat() - player.getRandom().nextFloat()) * 0.7F + 1.0F) * 2.0F
);

return ItemActionResult.SUCCESS;
}

Expand Down
Loading

0 comments on commit f3937b9

Please sign in to comment.