VERY TALL AND SHORT AND BIG
also made rainbow ant rare in elythia sniffer died fyling squireal anim overhual
No files matched your search
@@ -0,0 +1,255 @@
|
||||
package com.craisinlord.antarchy.content.block;
|
||||
|
||||
import com.craisinlord.antarchy.Antarchy;
|
||||
import com.mojang.serialization.MapCodec;
|
||||
import net.minecraft.core.BlockPos;
|
||||
import net.minecraft.core.Direction;
|
||||
import net.minecraft.core.registries.BuiltInRegistries;
|
||||
import net.minecraft.resources.ResourceLocation;
|
||||
import net.minecraft.server.level.ServerLevel;
|
||||
import net.minecraft.util.RandomSource;
|
||||
import net.minecraft.world.level.BlockGetter;
|
||||
import net.minecraft.world.level.Level;
|
||||
import net.minecraft.world.level.LevelAccessor;
|
||||
import net.minecraft.world.level.LevelReader;
|
||||
import net.minecraft.world.level.block.Block;
|
||||
import net.minecraft.world.level.block.Blocks;
|
||||
import net.minecraft.world.level.block.BonemealableBlock;
|
||||
import net.minecraft.world.level.block.BushBlock;
|
||||
import net.minecraft.world.level.block.state.BlockBehaviour;
|
||||
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.block.state.properties.DirectionProperty;
|
||||
import net.minecraft.world.level.block.state.properties.IntegerProperty;
|
||||
import net.minecraft.world.phys.shapes.CollisionContext;
|
||||
import net.minecraft.world.phys.shapes.Shapes;
|
||||
import net.minecraft.world.phys.shapes.VoxelShape;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
* Multiblock bush grown with bonemeal. The origin block (this one) carries the
|
||||
* loot/age; the rest of the footprint is filled with invisible
|
||||
* {@link BigBushPartBlock}s.
|
||||
*
|
||||
* age 0: single block (1x1x1)
|
||||
* age 1: 2x2x2 footprint; FACING + FACING.getClockWise() pick the horizontal quadrant
|
||||
* age 2: 3x3x3 footprint centered on the origin column
|
||||
*
|
||||
* Grown stages require a sturdy support block under every column of their
|
||||
* footprint. Growing from 2x2 to 3x3 may relocate the origin to any of the four
|
||||
* occupied columns to find room.
|
||||
*/
|
||||
public class BigBushBlock extends BushBlock implements BonemealableBlock {
|
||||
public static final MapCodec<BigBushBlock> CODEC = Block.simpleCodec(BigBushBlock::new);
|
||||
|
||||
public static final IntegerProperty AGE = BlockStateProperties.AGE_2;
|
||||
public static final DirectionProperty FACING = BlockStateProperties.HORIZONTAL_FACING;
|
||||
|
||||
private static final VoxelShape SMALL_SHAPE = Block.box(2.0, 0.0, 2.0, 14.0, 13.0, 14.0);
|
||||
|
||||
public BigBushBlock(BlockBehaviour.Properties properties) {
|
||||
super(properties);
|
||||
this.registerDefaultState(this.stateDefinition.any()
|
||||
.setValue(AGE, 0)
|
||||
.setValue(FACING, Direction.EAST));
|
||||
}
|
||||
|
||||
@Override
|
||||
public MapCodec<BigBushBlock> codec() {
|
||||
return CODEC;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void createBlockStateDefinition(StateDefinition.Builder<Block, BlockState> builder) {
|
||||
builder.add(AGE, FACING);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected VoxelShape getShape(BlockState state, BlockGetter level, BlockPos pos, CollisionContext context) {
|
||||
return state.getValue(AGE) == 0 ? SMALL_SHAPE : Shapes.block();
|
||||
}
|
||||
|
||||
/** All part positions belonging to a bush with the given origin state/pos (origin itself excluded). */
|
||||
public static List<BlockPos> partPositions(BlockState state, BlockPos origin) {
|
||||
List<BlockPos> positions = new ArrayList<>();
|
||||
int age = state.getValue(AGE);
|
||||
if (age == 1) {
|
||||
Direction forward = state.getValue(FACING);
|
||||
Direction side = forward.getClockWise();
|
||||
for (int dy = 0; dy <= 1; dy++) {
|
||||
for (BlockPos column : new BlockPos[]{
|
||||
origin, origin.relative(forward), origin.relative(side), origin.relative(forward).relative(side)}) {
|
||||
BlockPos pos = column.above(dy);
|
||||
if (!pos.equals(origin)) {
|
||||
positions.add(pos);
|
||||
}
|
||||
}
|
||||
}
|
||||
} else if (age == 2) {
|
||||
for (int dx = -1; dx <= 1; dx++) {
|
||||
for (int dy = 0; dy <= 2; dy++) {
|
||||
for (int dz = -1; dz <= 1; dz++) {
|
||||
if (dx == 0 && dy == 0 && dz == 0) {
|
||||
continue;
|
||||
}
|
||||
positions.add(origin.offset(dx, dy, dz));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return positions;
|
||||
}
|
||||
|
||||
/** Ground-level columns of the footprint; each needs a sturdy block below it. */
|
||||
public static List<BlockPos> supportColumns(BlockState state, BlockPos origin) {
|
||||
List<BlockPos> columns = new ArrayList<>();
|
||||
int age = state.getValue(AGE);
|
||||
if (age == 1) {
|
||||
Direction forward = state.getValue(FACING);
|
||||
Direction side = forward.getClockWise();
|
||||
columns.add(origin);
|
||||
columns.add(origin.relative(forward));
|
||||
columns.add(origin.relative(side));
|
||||
columns.add(origin.relative(forward).relative(side));
|
||||
} else if (age == 2) {
|
||||
for (int dx = -1; dx <= 1; dx++) {
|
||||
for (int dz = -1; dz <= 1; dz++) {
|
||||
columns.add(origin.offset(dx, 0, dz));
|
||||
}
|
||||
}
|
||||
} else {
|
||||
columns.add(origin);
|
||||
}
|
||||
return columns;
|
||||
}
|
||||
|
||||
public static boolean hasFullSupport(BlockState state, LevelReader level, BlockPos origin) {
|
||||
for (BlockPos column : supportColumns(state, origin)) {
|
||||
BlockPos below = column.below();
|
||||
if (!level.getBlockState(below).isFaceSturdy(level, below, Direction.UP)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean canSurvive(BlockState state, LevelReader level, BlockPos pos) {
|
||||
if (state.getValue(AGE) == 0) {
|
||||
return super.canSurvive(state, level, pos);
|
||||
}
|
||||
return hasFullSupport(state, level, pos);
|
||||
}
|
||||
|
||||
private static Block partBlock() {
|
||||
return BuiltInRegistries.BLOCK.get(ResourceLocation.fromNamespaceAndPath(Antarchy.MODID, "big_bush_part"));
|
||||
}
|
||||
|
||||
private record GrowthTarget(BlockPos origin, BlockState state) {}
|
||||
|
||||
@Nullable
|
||||
private GrowthTarget findGrowthTarget(LevelReader level, BlockPos pos, BlockState state, RandomSource random) {
|
||||
int age = state.getValue(AGE);
|
||||
if (age == 0) {
|
||||
List<Direction> facings = new ArrayList<>(Direction.Plane.HORIZONTAL.stream().toList());
|
||||
for (int i = facings.size() - 1; i > 0; i--) {
|
||||
Direction swap = facings.set(random.nextInt(i + 1), facings.get(i));
|
||||
facings.set(i, swap);
|
||||
}
|
||||
for (Direction facing : facings) {
|
||||
BlockState grown = state.setValue(AGE, 1).setValue(FACING, facing);
|
||||
if (canGrowTo(level, pos, grown, Set.of(pos))) {
|
||||
return new GrowthTarget(pos, grown);
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
if (age == 1) {
|
||||
Direction forward = state.getValue(FACING);
|
||||
Direction side = forward.getClockWise();
|
||||
Set<BlockPos> owned = new HashSet<>(partPositions(state, pos));
|
||||
owned.add(pos);
|
||||
BlockState grown = state.setValue(AGE, 2);
|
||||
// Any of the four occupied columns can become the new center of the 3x3.
|
||||
for (BlockPos candidate : new BlockPos[]{
|
||||
pos, pos.relative(forward).relative(side), pos.relative(forward), pos.relative(side)}) {
|
||||
if (canGrowTo(level, candidate, grown, owned)) {
|
||||
return new GrowthTarget(candidate, grown);
|
||||
}
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private boolean canGrowTo(LevelReader level, BlockPos newOrigin, BlockState grownState, Set<BlockPos> owned) {
|
||||
if (!hasFullSupport(grownState, level, newOrigin)) {
|
||||
return false;
|
||||
}
|
||||
List<BlockPos> positions = new ArrayList<>(partPositions(grownState, newOrigin));
|
||||
positions.add(newOrigin);
|
||||
for (BlockPos pos : positions) {
|
||||
if (owned.contains(pos)) {
|
||||
continue;
|
||||
}
|
||||
if (!level.getBlockState(pos).canBeReplaced()) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
public static void placeBushBlocks(LevelAccessor level, BlockPos origin, BlockState grownState, int flags) {
|
||||
level.setBlock(origin, grownState, flags);
|
||||
Block part = partBlock();
|
||||
BlockPos capPos = grownState.getValue(AGE) == 2 ? origin.above(2) : null;
|
||||
for (BlockPos pos : partPositions(grownState, origin)) {
|
||||
level.setBlock(pos, part.defaultBlockState()
|
||||
.setValue(BigBushPartBlock.CAP, pos.equals(capPos)), flags);
|
||||
}
|
||||
}
|
||||
|
||||
private void placeStage(ServerLevel level, BlockPos origin, BlockState grownState) {
|
||||
placeBushBlocks(level, origin, grownState, 3);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onRemove(BlockState state, Level level, BlockPos pos, BlockState newState, boolean movedByPiston) {
|
||||
if (!state.is(newState.getBlock())) {
|
||||
for (BlockPos partPos : partPositions(state, pos)) {
|
||||
if (level.getBlockState(partPos).getBlock() instanceof BigBushPartBlock) {
|
||||
level.setBlock(partPos, Blocks.AIR.defaultBlockState(), 35);
|
||||
}
|
||||
}
|
||||
}
|
||||
super.onRemove(state, level, pos, newState, movedByPiston);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isValidBonemealTarget(LevelReader level, BlockPos pos, BlockState state) {
|
||||
return state.getValue(AGE) < 2;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isBonemealSuccess(Level level, RandomSource random, BlockPos pos, BlockState state) {
|
||||
return findGrowthTarget(level, pos, state, random) != null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void performBonemeal(ServerLevel level, RandomSource random, BlockPos pos, BlockState state) {
|
||||
GrowthTarget target = findGrowthTarget(level, pos, state, random);
|
||||
if (target == null) {
|
||||
return;
|
||||
}
|
||||
if (!target.origin().equals(pos)) {
|
||||
// Relocating the origin: removing it cascades and clears the old parts.
|
||||
level.removeBlock(pos, false);
|
||||
}
|
||||
placeStage(level, target.origin(), target.state());
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,132 @@
|
||||
package com.craisinlord.antarchy.content.block;
|
||||
|
||||
import com.mojang.serialization.MapCodec;
|
||||
import net.minecraft.core.BlockPos;
|
||||
import net.minecraft.core.Direction;
|
||||
import net.minecraft.server.level.ServerLevel;
|
||||
import net.minecraft.util.RandomSource;
|
||||
import net.minecraft.world.entity.player.Player;
|
||||
import net.minecraft.world.item.ItemStack;
|
||||
import net.minecraft.world.level.BlockGetter;
|
||||
import net.minecraft.world.level.Level;
|
||||
import net.minecraft.world.level.LevelAccessor;
|
||||
import net.minecraft.world.level.LevelReader;
|
||||
import net.minecraft.world.level.block.Block;
|
||||
import net.minecraft.world.level.block.state.BlockBehaviour;
|
||||
import net.minecraft.world.level.block.state.BlockState;
|
||||
import net.minecraft.world.level.block.state.StateDefinition;
|
||||
import net.minecraft.world.level.block.state.properties.BooleanProperty;
|
||||
import net.minecraft.world.phys.shapes.CollisionContext;
|
||||
import net.minecraft.world.phys.shapes.Shapes;
|
||||
import net.minecraft.world.phys.shapes.VoxelShape;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
/**
|
||||
* Invisible filler block for the grown {@link BigBushBlock} footprint. Breaking a
|
||||
* part destroys the whole bush (drops come from the origin's loot table). The one
|
||||
* part directly two above the origin of a stage-3 bush renders the top slice of
|
||||
* the oversized cross model (CAP=true).
|
||||
*/
|
||||
public class BigBushPartBlock extends Block {
|
||||
public static final MapCodec<BigBushPartBlock> CODEC = Block.simpleCodec(BigBushPartBlock::new);
|
||||
|
||||
public static final BooleanProperty CAP = BooleanProperty.create("cap");
|
||||
|
||||
public BigBushPartBlock(BlockBehaviour.Properties properties) {
|
||||
super(properties);
|
||||
this.registerDefaultState(this.stateDefinition.any().setValue(CAP, false));
|
||||
}
|
||||
|
||||
@Override
|
||||
public MapCodec<BigBushPartBlock> codec() {
|
||||
return CODEC;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void createBlockStateDefinition(StateDefinition.Builder<Block, BlockState> builder) {
|
||||
builder.add(CAP);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected VoxelShape getShape(BlockState state, BlockGetter level, BlockPos pos, CollisionContext context) {
|
||||
return Shapes.block();
|
||||
}
|
||||
|
||||
/** Finds the origin bush this part belongs to, or null if orphaned. */
|
||||
@Nullable
|
||||
public static BlockPos findOrigin(LevelReader level, BlockPos partPos) {
|
||||
for (int dx = -1; dx <= 1; dx++) {
|
||||
for (int dy = -2; dy <= 0; dy++) {
|
||||
for (int dz = -1; dz <= 1; dz++) {
|
||||
if (dx == 0 && dy == 0 && dz == 0) {
|
||||
continue;
|
||||
}
|
||||
BlockPos candidate = partPos.offset(dx, dy, dz);
|
||||
BlockState state = level.getBlockState(candidate);
|
||||
if (state.getBlock() instanceof BigBushBlock
|
||||
&& BigBushBlock.partPositions(state, candidate).contains(partPos)) {
|
||||
return candidate;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public BlockState playerWillDestroy(Level level, BlockPos pos, BlockState state, Player player) {
|
||||
if (!level.isClientSide) {
|
||||
BlockPos origin = findOrigin(level, pos);
|
||||
if (origin != null) {
|
||||
BlockState originState = level.getBlockState(origin);
|
||||
if (!player.getAbilities().instabuild) {
|
||||
Block.dropResources(originState, level, origin, null, player, player.getMainHandItem());
|
||||
}
|
||||
level.destroyBlock(origin, false);
|
||||
}
|
||||
}
|
||||
return super.playerWillDestroy(level, pos, state, player);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onRemove(BlockState state, Level level, BlockPos pos, BlockState newState, boolean movedByPiston) {
|
||||
if (!state.is(newState.getBlock()) && !level.isClientSide) {
|
||||
BlockPos origin = findOrigin(level, pos);
|
||||
if (origin != null) {
|
||||
level.destroyBlock(origin, true);
|
||||
}
|
||||
}
|
||||
super.onRemove(state, level, pos, newState, movedByPiston);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected BlockState updateShape(BlockState state, Direction direction, BlockState neighborState,
|
||||
LevelAccessor level, BlockPos pos, BlockPos neighborPos) {
|
||||
level.scheduleTick(pos, this, 1);
|
||||
return super.updateShape(state, direction, neighborState, level, pos, neighborPos);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void tick(BlockState state, ServerLevel level, BlockPos pos, RandomSource random) {
|
||||
BlockPos origin = findOrigin(level, pos);
|
||||
if (origin == null) {
|
||||
level.removeBlock(pos, false);
|
||||
return;
|
||||
}
|
||||
// Grown bushes need sturdy support under the whole footprint; break with
|
||||
// drops if any of it is gone (mirrors plants popping when their dirt breaks).
|
||||
BlockState originState = level.getBlockState(origin);
|
||||
if (!originState.canSurvive(level, origin)) {
|
||||
level.destroyBlock(origin, true);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public ItemStack getCloneItemStack(LevelReader level, BlockPos pos, BlockState state) {
|
||||
BlockPos origin = findOrigin(level, pos);
|
||||
if (origin != null) {
|
||||
return new ItemStack(level.getBlockState(origin).getBlock());
|
||||
}
|
||||
return ItemStack.EMPTY;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,52 @@
|
||||
package com.craisinlord.antarchy.content.block;
|
||||
|
||||
import com.mojang.serialization.MapCodec;
|
||||
import net.minecraft.core.BlockPos;
|
||||
import net.minecraft.server.level.ServerLevel;
|
||||
import net.minecraft.util.RandomSource;
|
||||
import net.minecraft.world.level.BlockGetter;
|
||||
import net.minecraft.world.level.Level;
|
||||
import net.minecraft.world.level.LevelReader;
|
||||
import net.minecraft.world.level.block.Block;
|
||||
import net.minecraft.world.level.block.Blocks;
|
||||
import net.minecraft.world.level.block.BonemealableBlock;
|
||||
import net.minecraft.world.level.block.BushBlock;
|
||||
import net.minecraft.world.level.block.state.BlockBehaviour;
|
||||
import net.minecraft.world.level.block.state.BlockState;
|
||||
import net.minecraft.world.phys.shapes.CollisionContext;
|
||||
import net.minecraft.world.phys.shapes.VoxelShape;
|
||||
|
||||
public class VeryShortGrassBlock extends BushBlock implements BonemealableBlock {
|
||||
public static final MapCodec<VeryShortGrassBlock> CODEC = Block.simpleCodec(VeryShortGrassBlock::new);
|
||||
|
||||
private static final VoxelShape SHAPE = Block.box(2.0, 0.0, 2.0, 14.0, 8.0, 14.0);
|
||||
|
||||
public VeryShortGrassBlock(BlockBehaviour.Properties properties) {
|
||||
super(properties);
|
||||
}
|
||||
|
||||
@Override
|
||||
public MapCodec<VeryShortGrassBlock> codec() {
|
||||
return CODEC;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected VoxelShape getShape(BlockState state, BlockGetter level, BlockPos pos, CollisionContext context) {
|
||||
return SHAPE;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isValidBonemealTarget(LevelReader level, BlockPos pos, BlockState state) {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isBonemealSuccess(Level level, RandomSource random, BlockPos pos, BlockState state) {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void performBonemeal(ServerLevel level, RandomSource random, BlockPos pos, BlockState state) {
|
||||
level.setBlock(pos, Blocks.SHORT_GRASS.defaultBlockState(), 3);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,56 @@
|
||||
package com.craisinlord.antarchy.content.client;
|
||||
|
||||
import com.craisinlord.antarchy.content.block.BigBushBlock;
|
||||
import com.craisinlord.antarchy.content.block.BigBushPartBlock;
|
||||
import net.minecraft.client.Minecraft;
|
||||
import net.minecraft.core.BlockPos;
|
||||
import net.minecraft.world.level.block.state.BlockState;
|
||||
import net.minecraft.world.phys.Vec3;
|
||||
|
||||
import java.util.Objects;
|
||||
|
||||
public final class BigBushCameraHider {
|
||||
private static BlockPos hiddenOrigin;
|
||||
|
||||
private BigBushCameraHider() {
|
||||
}
|
||||
|
||||
public static void update(Minecraft mc) {
|
||||
BlockPos newOrigin = null;
|
||||
if (mc.level != null && mc.player != null) {
|
||||
Vec3 cameraPos = mc.gameRenderer.getMainCamera().getPosition();
|
||||
BlockPos pos = BlockPos.containing(cameraPos);
|
||||
BlockState state = mc.level.getBlockState(pos);
|
||||
if (state.getBlock() instanceof BigBushBlock && state.getValue(BigBushBlock.AGE) > 0) {
|
||||
newOrigin = pos;
|
||||
} else if (state.getBlock() instanceof BigBushPartBlock) {
|
||||
newOrigin = BigBushPartBlock.findOrigin(mc.level, pos);
|
||||
}
|
||||
}
|
||||
if (!Objects.equals(newOrigin, hiddenOrigin)) {
|
||||
BlockPos previous = hiddenOrigin;
|
||||
hiddenOrigin = newOrigin;
|
||||
markDirty(mc, previous);
|
||||
markDirty(mc, newOrigin);
|
||||
}
|
||||
}
|
||||
|
||||
private static void markDirty(Minecraft mc, BlockPos origin) {
|
||||
if (origin != null && mc.levelRenderer != null) {
|
||||
mc.levelRenderer.setBlocksDirty(
|
||||
origin.getX() - 2, origin.getY() - 1, origin.getZ() - 2,
|
||||
origin.getX() + 2, origin.getY() + 3, origin.getZ() + 2);
|
||||
}
|
||||
}
|
||||
|
||||
public static boolean shouldFade(BlockPos pos) {
|
||||
BlockPos origin = hiddenOrigin;
|
||||
if (origin == null) {
|
||||
return false;
|
||||
}
|
||||
return Math.abs(pos.getX() - origin.getX()) <= 1
|
||||
&& Math.abs(pos.getZ() - origin.getZ()) <= 1
|
||||
&& pos.getY() >= origin.getY()
|
||||
&& pos.getY() <= origin.getY() + 2;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,26 @@
|
||||
package com.craisinlord.antarchy.content.client;
|
||||
|
||||
import com.craisinlord.antarchy.content.block.BigBushBlock;
|
||||
import com.craisinlord.antarchy.content.block.BigBushPartBlock;
|
||||
import net.minecraft.core.BlockPos;
|
||||
import net.minecraft.world.entity.LivingEntity;
|
||||
import net.minecraft.world.level.Level;
|
||||
import net.minecraft.world.level.block.state.BlockState;
|
||||
|
||||
public final class BigBushRenderHelper {
|
||||
private BigBushRenderHelper() {
|
||||
}
|
||||
|
||||
public static boolean isInsideBigBush(LivingEntity entity) {
|
||||
Level level = entity.level();
|
||||
return isBush(level, entity.blockPosition()) || isBush(level, BlockPos.containing(entity.getEyePosition()));
|
||||
}
|
||||
|
||||
private static boolean isBush(Level level, BlockPos pos) {
|
||||
BlockState state = level.getBlockState(pos);
|
||||
if (state.getBlock() instanceof BigBushPartBlock) {
|
||||
return true;
|
||||
}
|
||||
return state.getBlock() instanceof BigBushBlock && state.getValue(BigBushBlock.AGE) > 0;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,23 @@
|
||||
package com.craisinlord.antarchy.content.item;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import net.minecraft.ChatFormatting;
|
||||
import net.minecraft.network.chat.Component;
|
||||
import net.minecraft.world.item.BlockItem;
|
||||
import net.minecraft.world.item.Item;
|
||||
import net.minecraft.world.item.ItemStack;
|
||||
import net.minecraft.world.item.TooltipFlag;
|
||||
import net.minecraft.world.level.block.Block;
|
||||
|
||||
public class BigBushBlockItem extends BlockItem {
|
||||
public BigBushBlockItem(Block block, Properties properties) {
|
||||
super(block, properties);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void appendHoverText(ItemStack stack, Item.TooltipContext context, List<Component> tooltipComponents, TooltipFlag tooltipFlag) {
|
||||
tooltipComponents.add(Component.translatable("item.antarchy.big_bush.tooltip").withStyle(ChatFormatting.GRAY));
|
||||
super.appendHoverText(stack, context, tooltipComponents, tooltipFlag);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,25 @@
|
||||
package com.craisinlord.antarchy.mixins.client;
|
||||
|
||||
import com.craisinlord.antarchy.content.block.BigBushBlock;
|
||||
import com.craisinlord.antarchy.content.block.BigBushPartBlock;
|
||||
import com.craisinlord.antarchy.content.client.AlphaVertexConsumerProxy;
|
||||
import com.craisinlord.antarchy.content.client.BigBushCameraHider;
|
||||
import com.mojang.blaze3d.vertex.VertexConsumer;
|
||||
import net.minecraft.client.renderer.block.BlockRenderDispatcher;
|
||||
import net.minecraft.core.BlockPos;
|
||||
import net.minecraft.world.level.block.state.BlockState;
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
import org.spongepowered.asm.mixin.injection.At;
|
||||
import org.spongepowered.asm.mixin.injection.ModifyVariable;
|
||||
|
||||
@Mixin(BlockRenderDispatcher.class)
|
||||
public abstract class BlockRenderDispatcherBigBushMixin {
|
||||
@ModifyVariable(method = "renderBatched", at = @At("HEAD"), argsOnly = true)
|
||||
private VertexConsumer antarchy$fadeBigBushAroundCamera(VertexConsumer consumer, BlockState state, BlockPos pos) {
|
||||
if ((state.getBlock() instanceof BigBushBlock || state.getBlock() instanceof BigBushPartBlock)
|
||||
&& BigBushCameraHider.shouldFade(pos)) {
|
||||
return AlphaVertexConsumerProxy.wrap(consumer, 0.35F);
|
||||
}
|
||||
return consumer;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,54 @@
|
||||
package com.craisinlord.antarchy.mixins.client;
|
||||
|
||||
import com.craisinlord.antarchy.content.client.BigBushRenderHelper;
|
||||
import com.mojang.blaze3d.vertex.PoseStack;
|
||||
import net.minecraft.client.renderer.MultiBufferSource;
|
||||
import net.minecraft.client.renderer.RenderType;
|
||||
import net.minecraft.client.renderer.entity.EntityRenderer;
|
||||
import net.minecraft.client.renderer.entity.LivingEntityRenderer;
|
||||
import net.minecraft.world.entity.LivingEntity;
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
import org.spongepowered.asm.mixin.Unique;
|
||||
import org.spongepowered.asm.mixin.injection.At;
|
||||
import org.spongepowered.asm.mixin.injection.Inject;
|
||||
import org.spongepowered.asm.mixin.injection.ModifyArg;
|
||||
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
|
||||
import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
|
||||
|
||||
@Mixin(LivingEntityRenderer.class)
|
||||
public abstract class LivingEntityRendererBigBushMixin {
|
||||
@Unique
|
||||
private boolean antarchy$inBigBush;
|
||||
|
||||
@Inject(
|
||||
method = "render(Lnet/minecraft/world/entity/LivingEntity;FFLcom/mojang/blaze3d/vertex/PoseStack;Lnet/minecraft/client/renderer/MultiBufferSource;I)V",
|
||||
at = @At("HEAD")
|
||||
)
|
||||
private void antarchy$checkBigBush(LivingEntity entity, float entityYaw, float partialTicks, PoseStack poseStack, MultiBufferSource buffer, int packedLight, CallbackInfo ci) {
|
||||
this.antarchy$inBigBush = BigBushRenderHelper.isInsideBigBush(entity);
|
||||
}
|
||||
|
||||
@SuppressWarnings({"unchecked", "rawtypes"})
|
||||
@Inject(method = "getRenderType", at = @At("HEAD"), cancellable = true)
|
||||
private void antarchy$bigBushRenderType(LivingEntity entity, boolean bodyVisible, boolean translucent, boolean glowing, CallbackInfoReturnable<RenderType> cir) {
|
||||
if (bodyVisible && !translucent && !glowing && BigBushRenderHelper.isInsideBigBush(entity)) {
|
||||
cir.setReturnValue(RenderType.itemEntityTranslucentCull(((EntityRenderer) (Object) this).getTextureLocation(entity)));
|
||||
}
|
||||
}
|
||||
|
||||
@Inject(method = "shouldShowName(Lnet/minecraft/world/entity/LivingEntity;)Z", at = @At("HEAD"), cancellable = true)
|
||||
private void antarchy$hideBigBushNameTag(LivingEntity entity, CallbackInfoReturnable<Boolean> cir) {
|
||||
if (BigBushRenderHelper.isInsideBigBush(entity)) {
|
||||
cir.setReturnValue(false);
|
||||
}
|
||||
}
|
||||
|
||||
@ModifyArg(
|
||||
method = "render(Lnet/minecraft/world/entity/LivingEntity;FFLcom/mojang/blaze3d/vertex/PoseStack;Lnet/minecraft/client/renderer/MultiBufferSource;I)V",
|
||||
at = @At(value = "INVOKE", target = "Lnet/minecraft/client/model/EntityModel;renderToBuffer(Lcom/mojang/blaze3d/vertex/PoseStack;Lcom/mojang/blaze3d/vertex/VertexConsumer;III)V"),
|
||||
index = 4
|
||||
)
|
||||
private int antarchy$bigBushAlpha(int color) {
|
||||
return this.antarchy$inBigBush && color == -1 ? 0x99FFFFFF : color;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
{
|
||||
"variants": {
|
||||
"age=0,facing=north": { "model": "antarchy:block/big_bush_stage1" },
|
||||
"age=0,facing=east": { "model": "antarchy:block/big_bush_stage1" },
|
||||
"age=0,facing=south": { "model": "antarchy:block/big_bush_stage1" },
|
||||
"age=0,facing=west": { "model": "antarchy:block/big_bush_stage1" },
|
||||
"age=1,facing=east": { "model": "antarchy:block/big_bush_stage2" },
|
||||
"age=1,facing=south": { "model": "antarchy:block/big_bush_stage2", "y": 90 },
|
||||
"age=1,facing=west": { "model": "antarchy:block/big_bush_stage2", "y": 180 },
|
||||
"age=1,facing=north": { "model": "antarchy:block/big_bush_stage2", "y": 270 },
|
||||
"age=2,facing=north": { "model": "antarchy:block/big_bush_stage3_bottom" },
|
||||
"age=2,facing=east": { "model": "antarchy:block/big_bush_stage3_bottom" },
|
||||
"age=2,facing=south": { "model": "antarchy:block/big_bush_stage3_bottom" },
|
||||
"age=2,facing=west": { "model": "antarchy:block/big_bush_stage3_bottom" }
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,6 @@
|
||||
{
|
||||
"variants": {
|
||||
"cap=false": { "model": "antarchy:block/big_bush_part" },
|
||||
"cap=true": { "model": "antarchy:block/big_bush_stage3_top" }
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,5 @@
|
||||
{
|
||||
"variants": {
|
||||
"": { "model": "antarchy:block/very_short_grass" }
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,5 @@
|
||||
{
|
||||
"textures": {
|
||||
"particle": "antarchy:block/big_bush/big_bush_stage3"
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,6 @@
|
||||
{
|
||||
"parent": "minecraft:block/tinted_cross",
|
||||
"textures": {
|
||||
"cross": "antarchy:block/big_bush/big_bush_stage1"
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,29 @@
|
||||
{
|
||||
"ambientocclusion": false,
|
||||
"textures": {
|
||||
"particle": "antarchy:block/big_bush/big_bush_stage2",
|
||||
"cross": "antarchy:block/big_bush/big_bush_stage2"
|
||||
},
|
||||
"elements": [
|
||||
{
|
||||
"from": [1.6, 0, 16],
|
||||
"to": [30.4, 32, 16],
|
||||
"rotation": { "origin": [16, 16, 16], "axis": "y", "angle": 45, "rescale": true },
|
||||
"shade": false,
|
||||
"faces": {
|
||||
"north": { "uv": [0, 0, 16, 16], "texture": "#cross", "tintindex": 0 },
|
||||
"south": { "uv": [0, 0, 16, 16], "texture": "#cross", "tintindex": 0 }
|
||||
}
|
||||
},
|
||||
{
|
||||
"from": [16, 0, 1.6],
|
||||
"to": [16, 32, 30.4],
|
||||
"rotation": { "origin": [16, 16, 16], "axis": "y", "angle": 45, "rescale": true },
|
||||
"shade": false,
|
||||
"faces": {
|
||||
"west": { "uv": [0, 0, 16, 16], "texture": "#cross", "tintindex": 0 },
|
||||
"east": { "uv": [0, 0, 16, 16], "texture": "#cross", "tintindex": 0 }
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,29 @@
|
||||
{
|
||||
"ambientocclusion": false,
|
||||
"textures": {
|
||||
"particle": "antarchy:block/big_bush/big_bush_stage3",
|
||||
"cross": "antarchy:block/big_bush/big_bush_stage3"
|
||||
},
|
||||
"elements": [
|
||||
{
|
||||
"from": [-13.6, 0, 8],
|
||||
"to": [29.6, 32, 8],
|
||||
"rotation": { "origin": [8, 16, 8], "axis": "y", "angle": 45, "rescale": true },
|
||||
"shade": false,
|
||||
"faces": {
|
||||
"north": { "uv": [0, 5.3333, 16, 16], "texture": "#cross", "tintindex": 0 },
|
||||
"south": { "uv": [0, 5.3333, 16, 16], "texture": "#cross", "tintindex": 0 }
|
||||
}
|
||||
},
|
||||
{
|
||||
"from": [8, 0, -13.6],
|
||||
"to": [8, 32, 29.6],
|
||||
"rotation": { "origin": [8, 16, 8], "axis": "y", "angle": 45, "rescale": true },
|
||||
"shade": false,
|
||||
"faces": {
|
||||
"west": { "uv": [0, 5.3333, 16, 16], "texture": "#cross", "tintindex": 0 },
|
||||
"east": { "uv": [0, 5.3333, 16, 16], "texture": "#cross", "tintindex": 0 }
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,29 @@
|
||||
{
|
||||
"ambientocclusion": false,
|
||||
"textures": {
|
||||
"particle": "antarchy:block/big_bush/big_bush_stage3",
|
||||
"cross": "antarchy:block/big_bush/big_bush_stage3"
|
||||
},
|
||||
"elements": [
|
||||
{
|
||||
"from": [-13.6, 0, 8],
|
||||
"to": [29.6, 16, 8],
|
||||
"rotation": { "origin": [8, 8, 8], "axis": "y", "angle": 45, "rescale": true },
|
||||
"shade": false,
|
||||
"faces": {
|
||||
"north": { "uv": [0, 0, 16, 5.3333], "texture": "#cross", "tintindex": 0 },
|
||||
"south": { "uv": [0, 0, 16, 5.3333], "texture": "#cross", "tintindex": 0 }
|
||||
}
|
||||
},
|
||||
{
|
||||
"from": [8, 0, -13.6],
|
||||
"to": [8, 16, 29.6],
|
||||
"rotation": { "origin": [8, 8, 8], "axis": "y", "angle": 45, "rescale": true },
|
||||
"shade": false,
|
||||
"faces": {
|
||||
"west": { "uv": [0, 0, 16, 5.3333], "texture": "#cross", "tintindex": 0 },
|
||||
"east": { "uv": [0, 0, 16, 5.3333], "texture": "#cross", "tintindex": 0 }
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,6 @@
|
||||
{
|
||||
"parent": "minecraft:block/tinted_cross",
|
||||
"textures": {
|
||||
"cross": "antarchy:block/very_short_grass"
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,6 @@
|
||||
{
|
||||
"parent": "minecraft:item/generated",
|
||||
"textures": {
|
||||
"layer0": "antarchy:block/big_bush/big_bush_stage1"
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,6 @@
|
||||
{
|
||||
"parent": "minecraft:item/generated",
|
||||
"textures": {
|
||||
"layer0": "antarchy:block/very_short_grass"
|
||||
}
|
||||
}
|
||||
|
After Width: | Height: | Size: 524 B |
|
After Width: | Height: | Size: 1.1 KiB |
|
After Width: | Height: | Size: 2.4 KiB |
|
After Width: | Height: | Size: 263 B |
|
After Width: | Height: | Size: 407 B |
|
After Width: | Height: | Size: 380 B |
|
After Width: | Height: | Size: 329 B |
@@ -0,0 +1,66 @@
|
||||
{
|
||||
"type": "minecraft:block",
|
||||
"pools": [
|
||||
{
|
||||
"conditions": [
|
||||
{
|
||||
"condition": "minecraft:match_tool",
|
||||
"predicate": {
|
||||
"items": "minecraft:shears"
|
||||
}
|
||||
}
|
||||
],
|
||||
"entries": [
|
||||
{
|
||||
"type": "minecraft:alternatives",
|
||||
"children": [
|
||||
{
|
||||
"type": "minecraft:item",
|
||||
"name": "antarchy:big_bush",
|
||||
"conditions": [
|
||||
{
|
||||
"condition": "minecraft:block_state_property",
|
||||
"block": "antarchy:big_bush",
|
||||
"properties": {
|
||||
"age": "2"
|
||||
}
|
||||
}
|
||||
],
|
||||
"functions": [
|
||||
{
|
||||
"function": "minecraft:set_count",
|
||||
"count": 3.0
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"type": "minecraft:item",
|
||||
"name": "antarchy:big_bush",
|
||||
"conditions": [
|
||||
{
|
||||
"condition": "minecraft:block_state_property",
|
||||
"block": "antarchy:big_bush",
|
||||
"properties": {
|
||||
"age": "1"
|
||||
}
|
||||
}
|
||||
],
|
||||
"functions": [
|
||||
{
|
||||
"function": "minecraft:set_count",
|
||||
"count": 2.0
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"type": "minecraft:item",
|
||||
"name": "antarchy:big_bush"
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"rolls": 1.0
|
||||
}
|
||||
],
|
||||
"random_sequence": "antarchy:blocks/big_bush"
|
||||
}
|
||||
@@ -0,0 +1,49 @@
|
||||
{
|
||||
"type": "minecraft:block",
|
||||
"pools": [
|
||||
{
|
||||
"conditions": [
|
||||
{
|
||||
"condition": "minecraft:match_tool",
|
||||
"predicate": {
|
||||
"items": "minecraft:shears"
|
||||
}
|
||||
}
|
||||
],
|
||||
"entries": [
|
||||
{
|
||||
"type": "minecraft:item",
|
||||
"name": "antarchy:very_short_grass"
|
||||
}
|
||||
],
|
||||
"rolls": 1.0
|
||||
},
|
||||
{
|
||||
"entries": [
|
||||
{
|
||||
"type": "minecraft:item",
|
||||
"name": "minecraft:wheat_seeds",
|
||||
"conditions": [
|
||||
{
|
||||
"condition": "minecraft:table_bonus",
|
||||
"enchantment": "minecraft:fortune",
|
||||
"chances": [
|
||||
0.125,
|
||||
0.14285715,
|
||||
0.16666667,
|
||||
0.2
|
||||
]
|
||||
}
|
||||
],
|
||||
"functions": [
|
||||
{
|
||||
"function": "minecraft:explosion_decay"
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"rolls": 1.0
|
||||
}
|
||||
],
|
||||
"random_sequence": "antarchy:blocks/very_short_grass"
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
{
|
||||
"replace": false,
|
||||
"values": [
|
||||
"antarchy:big_bush",
|
||||
"antarchy:big_bush_part",
|
||||
"antarchy:very_short_grass"
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,20 @@
|
||||
package com.craisinlord.antarchy.neoforge.client;
|
||||
|
||||
import com.craisinlord.antarchy.Antarchy;
|
||||
import com.craisinlord.antarchy.content.client.BigBushCameraHider;
|
||||
import net.minecraft.client.Minecraft;
|
||||
import net.neoforged.api.distmarker.Dist;
|
||||
import net.neoforged.bus.api.SubscribeEvent;
|
||||
import net.neoforged.fml.common.EventBusSubscriber;
|
||||
import net.neoforged.neoforge.client.event.ClientTickEvent;
|
||||
|
||||
@EventBusSubscriber(modid = Antarchy.MODID, value = Dist.CLIENT, bus = EventBusSubscriber.Bus.GAME)
|
||||
public final class BigBushHideHandler {
|
||||
private BigBushHideHandler() {
|
||||
}
|
||||
|
||||
@SubscribeEvent
|
||||
public static void onClientTick(ClientTickEvent.Post event) {
|
||||
BigBushCameraHider.update(Minecraft.getInstance());
|
||||
}
|
||||
}
|
||||