Reorganized Imports/Packages

This commit is contained in:
Frank 2022-05-18 23:56:18 +02:00
parent a8beba9196
commit 770a5b4046
854 changed files with 42775 additions and 41811 deletions

View file

@ -0,0 +1,23 @@
package org.betterx.betterend.blocks.basis;
import net.minecraft.world.level.material.MaterialColor;
import org.betterx.bclib.blocks.LeveledAnvilBlock;
import org.betterx.betterend.complexmaterials.MetalMaterial;
public class EndAnvilBlock extends LeveledAnvilBlock {
protected MetalMaterial metalMaterial;
public EndAnvilBlock(MaterialColor color, int level) {
super(color, level);
}
public EndAnvilBlock(MetalMaterial metalMaterial, MaterialColor color, int level) {
super(color, level);
this.metalMaterial = metalMaterial;
}
public int getCraftingLevel() {
return level;
}
}

View file

@ -0,0 +1,136 @@
package org.betterx.betterend.blocks.basis;
import net.minecraft.client.resources.model.UnbakedModel;
import net.minecraft.core.BlockPos;
import net.minecraft.core.Direction;
import net.minecraft.resources.ResourceLocation;
import net.minecraft.world.item.context.BlockPlaceContext;
import net.minecraft.world.level.BlockGetter;
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.LiquidBlockContainer;
import net.minecraft.world.level.block.SimpleWaterloggedBlock;
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.BooleanProperty;
import net.minecraft.world.level.material.Fluid;
import net.minecraft.world.level.material.FluidState;
import net.minecraft.world.level.material.Fluids;
import net.fabricmc.api.EnvType;
import net.fabricmc.api.Environment;
import net.fabricmc.fabric.api.object.builder.v1.block.FabricBlockSettings;
import org.betterx.bclib.blocks.BaseBlockNotFull;
import org.betterx.bclib.blocks.BlockProperties;
import org.betterx.bclib.client.models.ModelsHelper;
import java.util.Map;
@SuppressWarnings("deprecation")
public class EndLanternBlock extends BaseBlockNotFull implements SimpleWaterloggedBlock, LiquidBlockContainer {
public static final BooleanProperty IS_FLOOR = BlockProperties.IS_FLOOR;
public static final BooleanProperty WATERLOGGED = BlockStateProperties.WATERLOGGED;
public EndLanternBlock(Block source) {
this(FabricBlockSettings.copyOf(source).luminance(15).noOcclusion());
}
public EndLanternBlock(Properties settings) {
super(settings.noOcclusion());
}
@Override
protected void createBlockStateDefinition(StateDefinition.Builder<Block, BlockState> stateManager) {
stateManager.add(IS_FLOOR, WATERLOGGED);
}
@Override
public BlockState getStateForPlacement(BlockPlaceContext ctx) {
LevelReader worldView = ctx.getLevel();
BlockPos blockPos = ctx.getClickedPos();
Direction dir = ctx.getClickedFace();
boolean water = worldView.getFluidState(blockPos).getType() == Fluids.WATER;
if (dir != Direction.DOWN && dir != Direction.UP) {
if (canSupportCenter(worldView, blockPos.above(), Direction.DOWN)) {
return defaultBlockState().setValue(IS_FLOOR, false).setValue(WATERLOGGED, water);
} else if (canSupportCenter(worldView, blockPos.below(), Direction.UP)) {
return defaultBlockState().setValue(IS_FLOOR, true).setValue(WATERLOGGED, water);
} else {
return null;
}
} else if (dir == Direction.DOWN) {
if (canSupportCenter(worldView, blockPos.above(), Direction.DOWN)) {
return defaultBlockState().setValue(IS_FLOOR, false).setValue(WATERLOGGED, water);
} else if (canSupportCenter(worldView, blockPos.below(), Direction.UP)) {
return defaultBlockState().setValue(IS_FLOOR, true).setValue(WATERLOGGED, water);
} else {
return null;
}
} else {
if (canSupportCenter(worldView, blockPos.below(), Direction.UP)) {
return defaultBlockState().setValue(IS_FLOOR, true).setValue(WATERLOGGED, water);
} else if (canSupportCenter(worldView, blockPos.above(), Direction.DOWN)) {
return defaultBlockState().setValue(IS_FLOOR, false).setValue(WATERLOGGED, water);
} else {
return null;
}
}
}
@Override
public boolean canSurvive(BlockState state, LevelReader world, BlockPos pos) {
if (state.getValue(IS_FLOOR)) {
return canSupportCenter(world, pos.below(), Direction.UP);
} else {
return canSupportCenter(world, pos.above(), Direction.DOWN);
}
}
@Override
public BlockState updateShape(BlockState state,
Direction facing,
BlockState neighborState,
LevelAccessor world,
BlockPos pos,
BlockPos neighborPos) {
Boolean water = state.getValue(WATERLOGGED);
if (water) {
world.scheduleTick(pos, Fluids.WATER, Fluids.WATER.getTickDelay(world));
}
if (!canSurvive(state, world, pos)) {
return water ? Blocks.WATER.defaultBlockState() : Blocks.AIR.defaultBlockState();
} else {
return state;
}
}
@Override
public boolean canPlaceLiquid(BlockGetter world, BlockPos pos, BlockState state, Fluid fluid) {
return false;
}
@Override
public boolean placeLiquid(LevelAccessor world, BlockPos pos, BlockState state, FluidState fluidState) {
return false;
}
@Override
public FluidState getFluidState(BlockState state) {
return state.getValue(WATERLOGGED) ? Fluids.WATER.getSource(false) : Fluids.EMPTY.defaultFluidState();
}
@Override
@Environment(EnvType.CLIENT)
public UnbakedModel getModelVariant(ResourceLocation stateId,
BlockState blockState,
Map<ResourceLocation, UnbakedModel> modelCache) {
String floor = blockState.getValue(IS_FLOOR) ? "_floor" : "";
ResourceLocation modelId = new ResourceLocation(stateId.getNamespace(), "block/" + stateId.getPath() + floor);
registerBlockModel(stateId, modelId, blockState, modelCache);
return ModelsHelper.createBlockSimple(modelId);
}
}

View file

@ -0,0 +1,59 @@
package org.betterx.betterend.blocks.basis;
import net.minecraft.world.level.block.Block;
import net.minecraft.world.level.block.state.BlockState;
import org.betterx.bclib.api.tag.CommonBlockTags;
import org.betterx.bclib.blocks.BasePlantBlock;
import org.betterx.betterend.interfaces.PottablePlant;
import java.util.function.Function;
public class EndPlantBlock extends BasePlantBlock implements PottablePlant {
public EndPlantBlock() {
this(false, p -> p);
}
public EndPlantBlock(int light) {
this(light, p -> p);
}
public EndPlantBlock(int light, Function<Properties, Properties> propMod) {
this(false, light, propMod);
}
public EndPlantBlock(boolean replaceable) {
super(replaceable);
}
public EndPlantBlock(boolean replaceable, Function<Properties, Properties> propMod) {
super(replaceable, propMod);
}
public EndPlantBlock(boolean replaceable, int light) {
this(replaceable, light, p -> p);
}
public EndPlantBlock(boolean replaceable, int light, Function<Properties, Properties> propMod) {
super(replaceable, light, propMod);
}
public EndPlantBlock(Properties settings) {
super(settings);
}
@Override
protected boolean isTerrain(BlockState state) {
return state.is(CommonBlockTags.END_STONES);
}
@Override
public boolean canPlantOn(Block block) {
return isTerrain(block.defaultBlockState());
}
@Override
public boolean canBePotted() {
return getStateDefinition().getProperties().isEmpty();
}
}

View file

@ -0,0 +1,27 @@
package org.betterx.betterend.blocks.basis;
import net.minecraft.world.level.block.state.BlockState;
import org.betterx.bclib.api.tag.CommonBlockTags;
import org.betterx.bclib.blocks.BasePlantWithAgeBlock;
import java.util.function.Function;
public abstract class EndPlantWithAgeBlock extends BasePlantWithAgeBlock {
public EndPlantWithAgeBlock() {
}
public EndPlantWithAgeBlock(Function<Properties, Properties> propMod) {
super(propMod);
}
public EndPlantWithAgeBlock(Properties settings) {
super(settings);
}
@Override
protected boolean isTerrain(BlockState state) {
return state.is(CommonBlockTags.END_STONES);
}
}

View file

@ -0,0 +1,25 @@
package org.betterx.betterend.blocks.basis;
import net.minecraft.tags.TagKey;
import net.minecraft.world.item.Item;
import net.minecraft.world.level.block.Block;
import net.minecraft.world.level.block.Blocks;
import net.minecraft.world.level.material.MaterialColor;
import org.betterx.bclib.api.tag.CommonBlockTags;
import org.betterx.bclib.blocks.BaseTerrainBlock;
import org.betterx.bclib.interfaces.TagProvider;
import org.betterx.betterend.interfaces.PottableTerrain;
import java.util.List;
public class EndTerrainBlock extends BaseTerrainBlock implements PottableTerrain, TagProvider {
public EndTerrainBlock(MaterialColor color) {
super(Blocks.END_STONE, color);
}
@Override
public void addTags(List<TagKey<Block>> blockTags, List<TagKey<Item>> itemTags) {
blockTags.add(CommonBlockTags.END_STONES);
}
}

View file

@ -0,0 +1,13 @@
package org.betterx.betterend.blocks.basis;
import net.minecraft.world.level.block.Blocks;
import net.minecraft.world.level.material.MaterialColor;
import org.betterx.bclib.blocks.TripleTerrainBlock;
import org.betterx.betterend.interfaces.PottableTerrain;
public class EndTripleTerrain extends TripleTerrainBlock implements PottableTerrain {
public EndTripleTerrain(MaterialColor color) {
super(Blocks.END_STONE, color);
}
}

View file

@ -0,0 +1,27 @@
package org.betterx.betterend.blocks.basis;
import net.minecraft.world.level.block.state.BlockState;
import org.betterx.bclib.api.tag.CommonBlockTags;
import org.betterx.bclib.blocks.UnderwaterPlantBlock;
import java.util.function.Function;
public class EndUnderwaterPlantBlock extends UnderwaterPlantBlock {
public EndUnderwaterPlantBlock() {
}
public EndUnderwaterPlantBlock(int light, Function<Properties, Properties> propMod) {
super(light, propMod);
}
public EndUnderwaterPlantBlock(Properties settings) {
super(settings);
}
@Override
protected boolean isTerrain(BlockState state) {
return state.is(CommonBlockTags.END_STONES);
}
}

View file

@ -0,0 +1,25 @@
package org.betterx.betterend.blocks.basis;
import net.minecraft.world.level.block.state.BlockState;
import org.betterx.bclib.api.tag.CommonBlockTags;
import org.betterx.bclib.blocks.BaseUnderwaterWallPlantBlock;
public class EndUnderwaterWallPlantBlock extends BaseUnderwaterWallPlantBlock {
public EndUnderwaterWallPlantBlock() {
}
public EndUnderwaterWallPlantBlock(int light) {
super(light);
}
public EndUnderwaterWallPlantBlock(Properties settings) {
super(settings);
}
@Override
protected boolean isTerrain(BlockState state) {
return state.is(CommonBlockTags.END_STONES);
}
}

View file

@ -0,0 +1,18 @@
package org.betterx.betterend.blocks.basis;
import net.minecraft.world.level.block.state.BlockState;
import org.betterx.bclib.api.tag.CommonBlockTags;
import org.betterx.bclib.blocks.WallMushroomBlock;
public class EndWallMushroom extends WallMushroomBlock {
public EndWallMushroom(int light) {
super(light);
}
@Override
protected boolean isTerrain(BlockState state) {
return state.is(CommonBlockTags.END_STONES);
}
}

View file

@ -0,0 +1,24 @@
package org.betterx.betterend.blocks.basis;
import net.minecraft.world.level.block.state.BlockState;
import org.betterx.bclib.api.tag.CommonBlockTags;
import org.betterx.bclib.blocks.BaseWallPlantBlock;
public class EndWallPlantBlock extends BaseWallPlantBlock {
public EndWallPlantBlock() {
}
public EndWallPlantBlock(int light) {
super(light);
}
public EndWallPlantBlock(Properties settings) {
super(settings);
}
@Override
protected boolean isTerrain(BlockState state) {
return state.is(CommonBlockTags.END_STONES);
}
}

View file

@ -0,0 +1,94 @@
package org.betterx.betterend.blocks.basis;
import net.minecraft.core.BlockPos;
import net.minecraft.core.Direction;
import net.minecraft.world.item.ItemStack;
import net.minecraft.world.item.enchantment.EnchantmentHelper;
import net.minecraft.world.item.enchantment.Enchantments;
import net.minecraft.world.level.BlockGetter;
import net.minecraft.world.level.ItemLike;
import net.minecraft.world.level.block.SoundType;
import net.minecraft.world.level.block.state.BlockState;
import net.minecraft.world.level.material.Material;
import net.minecraft.world.level.storage.loot.LootContext;
import net.minecraft.world.level.storage.loot.parameters.LootContextParams;
import net.minecraft.world.phys.shapes.CollisionContext;
import net.minecraft.world.phys.shapes.Shapes;
import net.minecraft.world.phys.shapes.VoxelShape;
import net.fabricmc.fabric.api.object.builder.v1.block.FabricBlockSettings;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import org.betterx.bclib.api.tag.NamedBlockTags;
import org.betterx.bclib.api.tag.TagAPI;
import org.betterx.bclib.blocks.BaseAttachedBlock;
import org.betterx.bclib.client.render.BCLRenderLayer;
import org.betterx.bclib.interfaces.RenderLayerProvider;
import org.betterx.bclib.interfaces.tools.AddMineableShears;
import org.betterx.bclib.items.tool.BaseShearsItem;
import org.betterx.bclib.util.MHelper;
import java.util.EnumMap;
import java.util.List;
public class FurBlock extends BaseAttachedBlock implements RenderLayerProvider, AddMineableShears {
private static final EnumMap<Direction, VoxelShape> BOUNDING_SHAPES = Maps.newEnumMap(Direction.class);
private final ItemLike drop;
private final int dropChance;
public FurBlock(ItemLike drop, int light, int dropChance, boolean wet) {
super(FabricBlockSettings.of(Material.REPLACEABLE_PLANT)
.luminance(light)
.sound(wet ? SoundType.WET_GRASS : SoundType.GRASS)
.noCollission());
this.drop = drop;
this.dropChance = dropChance;
TagAPI.addBlockTag(NamedBlockTags.LEAVES, this);
}
public FurBlock(ItemLike drop, int dropChance) {
super(FabricBlockSettings.of(Material.REPLACEABLE_PLANT)
.sound(SoundType.GRASS)
.noCollission());
this.drop = drop;
this.dropChance = dropChance;
TagAPI.addBlockTag(NamedBlockTags.LEAVES, this);
}
@Override
@SuppressWarnings("deprecation")
public VoxelShape getShape(BlockState state, BlockGetter view, BlockPos pos, CollisionContext ePos) {
return BOUNDING_SHAPES.get(state.getValue(FACING));
}
@Override
public List<ItemStack> getDrops(BlockState state, LootContext.Builder builder) {
ItemStack tool = builder.getParameter(LootContextParams.TOOL);
if (tool != null && BaseShearsItem.isShear(tool) || EnchantmentHelper.getItemEnchantmentLevel(
Enchantments.SILK_TOUCH,
tool
) > 0) {
return Lists.newArrayList(new ItemStack(this));
} else if (dropChance < 1 || MHelper.RANDOM.nextInt(dropChance) == 0) {
return Lists.newArrayList(new ItemStack(drop));
} else {
return Lists.newArrayList();
}
}
@Override
public BCLRenderLayer getRenderLayer() {
return BCLRenderLayer.CUTOUT;
}
static {
BOUNDING_SHAPES.put(Direction.UP, Shapes.box(0.0, 0.0, 0.0, 1.0, 0.5, 1.0));
BOUNDING_SHAPES.put(Direction.DOWN, Shapes.box(0.0, 0.5, 0.0, 1.0, 1.0, 1.0));
BOUNDING_SHAPES.put(Direction.NORTH, Shapes.box(0.0, 0.0, 0.5, 1.0, 1.0, 1.0));
BOUNDING_SHAPES.put(Direction.SOUTH, Shapes.box(0.0, 0.0, 0.0, 1.0, 1.0, 0.5));
BOUNDING_SHAPES.put(Direction.WEST, Shapes.box(0.5, 0.0, 0.0, 1.0, 1.0, 1.0));
BOUNDING_SHAPES.put(Direction.EAST, Shapes.box(0.0, 0.0, 0.0, 0.5, 1.0, 1.0));
}
}

View file

@ -0,0 +1,27 @@
package org.betterx.betterend.blocks.basis;
import net.minecraft.client.renderer.block.model.BlockModel;
import net.minecraft.resources.ResourceLocation;
import net.minecraft.world.level.block.state.BlockState;
import net.fabricmc.api.EnvType;
import net.fabricmc.api.Environment;
import org.betterx.bclib.blocks.BaseBlock;
import org.jetbrains.annotations.Nullable;
public class LitBaseBlock extends BaseBlock {
private static final String PATTERN = "{\"parent\":\"betterend:block/cube_noshade\",\"textures\":{\"texture\":\"betterend:block/name\"}}";
public LitBaseBlock(Properties settings) {
super(settings);
}
@Nullable
@Override
@Environment(EnvType.CLIENT)
public BlockModel getBlockModel(ResourceLocation resourceLocation, BlockState blockState) {
return BlockModel.fromString(PATTERN.replace("name", resourceLocation.getPath()));
}
}

View file

@ -0,0 +1,25 @@
package org.betterx.betterend.blocks.basis;
import net.minecraft.resources.ResourceLocation;
import net.fabricmc.api.EnvType;
import net.fabricmc.api.Environment;
import org.betterx.bclib.blocks.BaseRotatedPillarBlock;
import java.util.Optional;
public class LitPillarBlock extends BaseRotatedPillarBlock {
private static final String PATTERN = "{\"parent\":\"betterend:block/pillar_noshade\",\"textures\":{\"end\":\"betterend:block/name_top\",\"side\":\"betterend:block/name_side\"}}";
public LitPillarBlock(Properties settings) {
super(settings);
}
@Override
@Environment(EnvType.CLIENT)
protected Optional<String> createBlockPattern(ResourceLocation blockId) {
String name = blockId.getPath();
return Optional.of(PATTERN.replace("name", name));
}
}

View file

@ -0,0 +1,462 @@
package org.betterx.betterend.blocks.basis;
import net.minecraft.client.renderer.block.model.BlockModel;
import net.minecraft.client.resources.model.UnbakedModel;
import net.minecraft.core.BlockPos;
import net.minecraft.core.BlockPos.MutableBlockPos;
import net.minecraft.core.Direction;
import net.minecraft.core.Registry;
import net.minecraft.resources.ResourceLocation;
import net.minecraft.tags.BlockTags;
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.item.context.BlockPlaceContext;
import net.minecraft.world.level.BlockGetter;
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.EntityBlock;
import net.minecraft.world.level.block.entity.BlockEntity;
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.level.block.state.properties.EnumProperty;
import net.minecraft.world.level.storage.loot.LootContext;
import net.minecraft.world.level.storage.loot.parameters.LootContextParams;
import net.minecraft.world.phys.BlockHitResult;
import net.minecraft.world.phys.shapes.CollisionContext;
import net.minecraft.world.phys.shapes.Shapes;
import net.minecraft.world.phys.shapes.VoxelShape;
import net.fabricmc.api.EnvType;
import net.fabricmc.api.Environment;
import net.fabricmc.fabric.api.object.builder.v1.block.FabricBlockSettings;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import org.betterx.bclib.blocks.BaseBlockNotFull;
import org.betterx.bclib.blocks.BlockProperties;
import org.betterx.bclib.client.models.ModelsHelper;
import org.betterx.betterend.blocks.EndBlockProperties;
import org.betterx.betterend.blocks.EndBlockProperties.PedestalState;
import org.betterx.betterend.blocks.InfusionPedestal;
import org.betterx.betterend.blocks.entities.InfusionPedestalEntity;
import org.betterx.betterend.blocks.entities.PedestalBlockEntity;
import org.betterx.betterend.client.models.Patterns;
import org.betterx.betterend.rituals.InfusionRitual;
import java.awt.*;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.function.ToIntFunction;
import org.jetbrains.annotations.Nullable;
public class PedestalBlock extends BaseBlockNotFull implements EntityBlock {
public final static EnumProperty<PedestalState> STATE = EndBlockProperties.PEDESTAL_STATE;
public static final BooleanProperty HAS_ITEM = EndBlockProperties.HAS_ITEM;
public static final BooleanProperty HAS_LIGHT = BlockProperties.HAS_LIGHT;
private static final VoxelShape SHAPE_DEFAULT;
private static final VoxelShape SHAPE_COLUMN;
private static final VoxelShape SHAPE_PILLAR;
private static final VoxelShape SHAPE_PEDESTAL_TOP;
private static final VoxelShape SHAPE_COLUMN_TOP;
private static final VoxelShape SHAPE_BOTTOM;
protected final Block parent;
protected float height = 1.0F;
public PedestalBlock(Block parent) {
super(FabricBlockSettings.copyOf(parent).luminance(getLuminance(parent.defaultBlockState())));
this.registerDefaultState(
stateDefinition
.any()
.setValue(STATE, PedestalState.DEFAULT)
.setValue(HAS_ITEM, false)
.setValue(HAS_LIGHT, false)
);
this.parent = parent;
}
private static ToIntFunction<BlockState> getLuminance(BlockState parent) {
final int light = parent.getLightEmission();
if (light > 0) {
return state -> light;
}
return state -> state.getValue(HAS_LIGHT) ? 12 : 0;
}
public float getHeight(BlockState state) {
if (state.getBlock() instanceof PedestalBlock && state.getValue(STATE) == PedestalState.PEDESTAL_TOP) {
return this.height - 0.2F;
}
return this.height;
}
@Override
@SuppressWarnings("deprecation")
public InteractionResult use(BlockState state,
Level level,
BlockPos pos,
Player player,
InteractionHand hand,
BlockHitResult hit) {
if (!state.is(this) || !isPlaceable(state)) {
return InteractionResult.PASS;
}
BlockEntity blockEntity = level.getBlockEntity(pos);
if (blockEntity instanceof PedestalBlockEntity) {
PedestalBlockEntity pedestal = (PedestalBlockEntity) blockEntity;
if (pedestal.isEmpty()) {
ItemStack itemStack = player.getItemInHand(hand);
if (itemStack.isEmpty()) return InteractionResult.CONSUME;
pedestal.setItem(0, itemStack);
level.blockEntityChanged(pos);
checkRitual(level, pos);
return InteractionResult.sidedSuccess(level.isClientSide());
} else {
ItemStack itemStack = pedestal.getItem(0);
if (player.addItem(itemStack)) {
pedestal.removeItemNoUpdate(0);
level.blockEntityChanged(pos);
checkRitual(level, pos);
return InteractionResult.sidedSuccess(level.isClientSide());
}
return InteractionResult.FAIL;
}
}
return InteractionResult.PASS;
}
@Override
public void destroy(LevelAccessor levelAccessor, BlockPos blockPos, BlockState blockState) {
MutableBlockPos posMutable = new MutableBlockPos();
for (Point point : InfusionRitual.getMap()) {
posMutable.set(blockPos).move(point.x, 0, point.y);
BlockState state = levelAccessor.getBlockState(posMutable);
if (state.getBlock() instanceof InfusionPedestal) {
BlockEntity blockEntity = levelAccessor.getBlockEntity(posMutable);
if (blockEntity instanceof InfusionPedestalEntity) {
InfusionPedestalEntity pedestal = (InfusionPedestalEntity) blockEntity;
if (pedestal.hasRitual()) {
pedestal.getRitual().setDirty();
}
}
break;
}
}
}
public void checkRitual(Level world, BlockPos pos) {
MutableBlockPos posMutable = new MutableBlockPos();
for (Point point : InfusionRitual.getMap()) {
posMutable.set(pos).move(point.x, 0, point.y);
BlockState state = world.getBlockState(posMutable);
if (state.getBlock() instanceof InfusionPedestal) {
((InfusionPedestal) state.getBlock()).checkRitual(world, posMutable);
break;
}
}
}
@Override
@Nullable
public BlockState getStateForPlacement(BlockPlaceContext context) {
Level world = context.getLevel();
BlockPos pos = context.getClickedPos();
BlockState upState = world.getBlockState(pos.above());
BlockState downState = world.getBlockState(pos.below());
boolean upSideSolid = upState.isFaceSturdy(world, pos.above(), Direction.DOWN) || upState.is(BlockTags.WALLS);
boolean hasPedestalOver = upState.getBlock() instanceof PedestalBlock;
boolean hasPedestalUnder = downState.getBlock() instanceof PedestalBlock;
if (!hasPedestalOver && hasPedestalUnder && upSideSolid) {
return defaultBlockState().setValue(STATE, PedestalState.COLUMN_TOP);
} else if (!hasPedestalOver && !hasPedestalUnder && upSideSolid) {
return defaultBlockState().setValue(STATE, PedestalState.COLUMN);
} else if (hasPedestalUnder && hasPedestalOver) {
return defaultBlockState().setValue(STATE, PedestalState.PILLAR);
} else if (hasPedestalUnder) {
return defaultBlockState().setValue(STATE, PedestalState.PEDESTAL_TOP);
} else if (hasPedestalOver) {
return defaultBlockState().setValue(STATE, PedestalState.BOTTOM);
}
return defaultBlockState();
}
@Override
@SuppressWarnings("deprecation")
public BlockState updateShape(BlockState state,
Direction direction,
BlockState newState,
LevelAccessor world,
BlockPos pos,
BlockPos posFrom) {
BlockState updated = getUpdatedState(state, direction, newState, world, pos, posFrom);
if (!updated.is(this)) return updated;
if (!isPlaceable(updated)) {
moveStoredStack(world, updated, pos);
}
return updated;
}
private BlockState getUpdatedState(BlockState state,
Direction direction,
BlockState newState,
LevelAccessor world,
BlockPos pos,
BlockPos posFrom) {
if (!state.is(this)) return state.updateShape(direction, newState, world, pos, posFrom);
if (direction != Direction.UP && direction != Direction.DOWN) return state;
BlockState upState = world.getBlockState(pos.above());
BlockState downState = world.getBlockState(pos.below());
boolean upSideSolid = upState.isFaceSturdy(world, pos.above(), Direction.DOWN) || upState.is(BlockTags.WALLS);
boolean hasPedestalOver = upState.getBlock() instanceof PedestalBlock;
boolean hasPedestalUnder = downState.getBlock() instanceof PedestalBlock;
if (direction == Direction.UP) {
upSideSolid = newState.isFaceSturdy(world, posFrom, Direction.DOWN) || newState.is(BlockTags.WALLS);
hasPedestalOver = newState.getBlock() instanceof PedestalBlock;
} else {
hasPedestalUnder = newState.getBlock() instanceof PedestalBlock;
}
BlockState updatedState;
if (!hasPedestalOver && hasPedestalUnder && upSideSolid) {
updatedState = state.setValue(STATE, PedestalState.COLUMN_TOP);
} else if (!hasPedestalOver && !hasPedestalUnder && upSideSolid) {
updatedState = state.setValue(STATE, PedestalState.COLUMN);
} else if (hasPedestalUnder && hasPedestalOver) {
updatedState = state.setValue(STATE, PedestalState.PILLAR);
} else if (hasPedestalUnder) {
updatedState = state.setValue(STATE, PedestalState.PEDESTAL_TOP);
} else if (hasPedestalOver) {
updatedState = state.setValue(STATE, PedestalState.BOTTOM);
} else {
updatedState = state.setValue(STATE, PedestalState.DEFAULT);
}
if (!isPlaceable(updatedState)) {
updatedState = updatedState.setValue(HAS_ITEM, false).setValue(HAS_LIGHT, false);
}
return updatedState;
}
@Override
public List<ItemStack> getDrops(BlockState state, LootContext.Builder builder) {
List<ItemStack> drop = Lists.newArrayList(super.getDrops(state, builder));
if (state.is(this)) {
if (isPlaceable(state)) {
BlockEntity blockEntity = builder.getOptionalParameter(LootContextParams.BLOCK_ENTITY);
if (blockEntity instanceof PedestalBlockEntity) {
PedestalBlockEntity pedestal = (PedestalBlockEntity) blockEntity;
if (!pedestal.isEmpty()) {
drop.add(pedestal.getItem(0));
}
}
} else {
return drop;
}
}
return drop;
}
private void moveStoredStack(LevelAccessor world, BlockState state, BlockPos pos) {
BlockEntity blockEntity = world.getBlockEntity(pos);
if (blockEntity instanceof PedestalBlockEntity && state.is(this)) {
PedestalBlockEntity pedestal = (PedestalBlockEntity) blockEntity;
ItemStack stack = pedestal.removeItemNoUpdate(0);
if (!stack.isEmpty()) {
moveStoredStack(blockEntity, world, stack, pos.above());
}
}
}
private void moveStoredStack(BlockEntity blockEntity, LevelAccessor world, ItemStack stack, BlockPos pos) {
BlockState state = world.getBlockState(pos);
if (!state.is(this)) {
dropStoredStack(blockEntity, stack, pos);
} else if (state.getValue(STATE).equals(PedestalState.PILLAR)) {
moveStoredStack(blockEntity, world, stack, pos.above());
} else if (!isPlaceable(state)) {
dropStoredStack(blockEntity, stack, pos);
} else if (blockEntity instanceof PedestalBlockEntity) {
PedestalBlockEntity pedestal = (PedestalBlockEntity) blockEntity;
if (pedestal.isEmpty()) {
pedestal.setItem(0, stack);
} else {
dropStoredStack(blockEntity, stack, pos);
}
} else {
dropStoredStack(blockEntity, stack, pos);
}
}
private void dropStoredStack(BlockEntity blockEntity, ItemStack stack, BlockPos pos) {
if (blockEntity != null && blockEntity.getLevel() != null) {
Level world = blockEntity.getLevel();
Block.popResource(world, getDropPos(world, pos), stack);
}
}
private BlockPos getDropPos(LevelAccessor world, BlockPos pos) {
BlockPos dropPos;
if (world.getBlockState(pos).isAir()) {
return pos;
}
if (world.getBlockState(pos.above()).isAir()) {
return pos.above();
}
for (int i = 2; i < Direction.values().length; i++) {
dropPos = pos.relative(Direction.from3DDataValue(i));
if (world.getBlockState(dropPos).isAir()) {
return dropPos.immutable();
}
}
return getDropPos(world, pos.above());
}
public boolean isPlaceable(BlockState state) {
if (!state.is(this)) return false;
PedestalState currentState = state.getValue(STATE);
return currentState == PedestalState.DEFAULT || currentState == PedestalState.PEDESTAL_TOP;
}
@Override
@SuppressWarnings("deprecation")
public VoxelShape getShape(BlockState state, BlockGetter world, BlockPos pos, CollisionContext context) {
if (state.is(this)) {
switch (state.getValue(STATE)) {
case BOTTOM: {
return SHAPE_BOTTOM;
}
case PEDESTAL_TOP: {
return SHAPE_PEDESTAL_TOP;
}
case COLUMN_TOP: {
return SHAPE_COLUMN_TOP;
}
case PILLAR: {
return SHAPE_PILLAR;
}
case COLUMN: {
return SHAPE_COLUMN;
}
default: {
return SHAPE_DEFAULT;
}
}
}
return super.getShape(state, world, pos, context);
}
@Override
protected void createBlockStateDefinition(StateDefinition.Builder<Block, BlockState> stateManager) {
stateManager.add(STATE, HAS_ITEM, HAS_LIGHT);
}
@Override
public BlockEntity newBlockEntity(BlockPos blockPos, BlockState blockState) {
return new PedestalBlockEntity(blockPos, blockState);
}
public boolean hasUniqueEntity() {
return false;
}
@Override
@SuppressWarnings("deprecation")
public boolean hasAnalogOutputSignal(BlockState state) {
return state.getBlock() instanceof PedestalBlock;
}
@Override
@SuppressWarnings("deprecation")
public int getAnalogOutputSignal(BlockState state, Level world, BlockPos pos) {
return state.getValue(HAS_ITEM) ? 15 : 0;
}
@Override
@Environment(EnvType.CLIENT)
public BlockModel getItemModel(ResourceLocation blockId) {
return getBlockModel(blockId, defaultBlockState());
}
@Override
@Environment(EnvType.CLIENT)
public @Nullable BlockModel getBlockModel(ResourceLocation resourceLocation, BlockState blockState) {
Map<String, String> textures = createTexturesMap();
PedestalState state = blockState.getValue(STATE);
Optional<String> pattern = Patterns.createJson(Patterns.BLOCK_PEDESTAL_DEFAULT, textures);
switch (state) {
case COLUMN_TOP:
pattern = Patterns.createJson(Patterns.BLOCK_PEDESTAL_COLUMN_TOP, textures);
break;
case COLUMN:
pattern = Patterns.createJson(Patterns.BLOKC_PEDESTAL_COLUMN, textures);
break;
case PEDESTAL_TOP:
pattern = Patterns.createJson(Patterns.BLOCK_PEDESTAL_TOP, textures);
break;
case BOTTOM:
pattern = Patterns.createJson(Patterns.BLOCK_PEDESTAL_BOTTOM, textures);
break;
case PILLAR:
pattern = Patterns.createJson(Patterns.BLOCK_PEDESTAL_PILLAR, textures);
break;
default:
break;
}
return ModelsHelper.fromPattern(pattern);
}
@Override
@Environment(EnvType.CLIENT)
public UnbakedModel getModelVariant(ResourceLocation stateId,
BlockState blockState,
Map<ResourceLocation, UnbakedModel> modelCache) {
PedestalState state = blockState.getValue(STATE);
ResourceLocation modelId = new ResourceLocation(
stateId.getNamespace(),
"block/" + stateId.getPath() + "_" + state
);
registerBlockModel(stateId, modelId, blockState, modelCache);
return ModelsHelper.createBlockSimple(modelId);
}
protected Map<String, String> createTexturesMap() {
ResourceLocation blockId = Registry.BLOCK.getKey(parent);
String name = blockId.getPath();
Map<String, String> textures = Maps.newHashMap();
textures.put("%mod%", blockId.getNamespace());
textures.put("%top%", name + "_top");
textures.put("%base%", name + "_base");
textures.put("%pillar%", name + "_pillar");
textures.put("%bottom%", name + "_bottom");
return textures;
}
static {
VoxelShape basinUp = Block.box(2, 3, 2, 14, 4, 14);
VoxelShape basinDown = Block.box(0, 0, 0, 16, 3, 16);
VoxelShape columnTopUp = Block.box(1, 14, 1, 15, 16, 15);
VoxelShape columnTopDown = Block.box(2, 13, 2, 14, 14, 14);
VoxelShape pedestalTop = Block.box(1, 8, 1, 15, 10, 15);
VoxelShape pedestalDefault = Block.box(1, 12, 1, 15, 14, 15);
VoxelShape pillar = Block.box(3, 0, 3, 13, 8, 13);
VoxelShape pillarDefault = Block.box(3, 0, 3, 13, 12, 13);
VoxelShape columnTop = Shapes.or(columnTopDown, columnTopUp);
VoxelShape basin = Shapes.or(basinDown, basinUp);
SHAPE_PILLAR = Block.box(3, 0, 3, 13, 16, 13);
SHAPE_DEFAULT = Shapes.or(basin, pillarDefault, pedestalDefault);
SHAPE_PEDESTAL_TOP = Shapes.or(pillar, pedestalTop);
SHAPE_COLUMN_TOP = Shapes.or(SHAPE_PILLAR, columnTop);
SHAPE_COLUMN = Shapes.or(basin, SHAPE_PILLAR, columnTop);
SHAPE_BOTTOM = Shapes.or(basin, SHAPE_PILLAR);
}
/*@Override
@Nullable
public <T extends BlockEntity> BlockEntityTicker<T> getTicker(Level level, BlockState blockState, BlockEntityType<T> blockEntityType) {
return level.isClientSide() ? PedestalBlockEntity::tick : null;
}*/
}

View file

@ -0,0 +1,31 @@
package org.betterx.betterend.blocks.basis;
import net.minecraft.world.item.Item;
import net.minecraft.world.level.block.Block;
import org.betterx.bclib.blocks.BaseCropBlock;
import org.betterx.betterend.interfaces.PottablePlant;
public class PottableCropBlock extends BaseCropBlock implements PottablePlant {
private final Block[] terrain;
public PottableCropBlock(Item drop, Block... terrain) {
super(drop, terrain);
this.terrain = terrain;
}
@Override
public boolean canPlantOn(Block block) {
for (Block ter : terrain) {
if (block == ter) {
return true;
}
}
return false;
}
@Override
public String getPottedState() {
return "age=3";
}
}

View file

@ -0,0 +1,19 @@
package org.betterx.betterend.blocks.basis;
import net.minecraft.world.level.block.state.BlockState;
import net.minecraft.world.level.levelgen.feature.Feature;
import org.betterx.bclib.blocks.FeatureSaplingBlock;
import org.betterx.betterend.interfaces.PottablePlant;
import java.util.function.Function;
public abstract class PottableFeatureSapling extends FeatureSaplingBlock implements PottablePlant {
public PottableFeatureSapling(Function<BlockState, Feature<?>> featureSupplier) {
super(featureSupplier);
}
public PottableFeatureSapling(int light, Function<BlockState, Feature<?>> featureSupplier) {
super(light, featureSupplier);
}
}

View file

@ -0,0 +1,26 @@
package org.betterx.betterend.blocks.basis;
import net.minecraft.world.level.block.Block;
import net.minecraft.world.level.material.MaterialColor;
import org.betterx.bclib.blocks.BaseLeavesBlock;
import org.betterx.betterend.interfaces.PottablePlant;
public class PottableLeavesBlock extends BaseLeavesBlock implements PottablePlant {
public PottableLeavesBlock(Block sapling, MaterialColor color) {
super(sapling, color);
}
public PottableLeavesBlock(Block sapling, MaterialColor color, int light) {
super(sapling, color, light);
}
@Override
public boolean canPlantOn(Block block) {
if (sapling instanceof PottablePlant) {
return ((PottablePlant) sapling).canPlantOn(block);
}
return true;
}
}

View file

@ -0,0 +1,63 @@
package org.betterx.betterend.blocks.basis;
import net.minecraft.client.color.block.BlockColor;
import net.minecraft.client.color.item.ItemColor;
import net.minecraft.client.renderer.block.model.BlockModel;
import net.minecraft.core.BlockPos;
import net.minecraft.resources.ResourceLocation;
import net.minecraft.world.level.BlockGetter;
import net.minecraft.world.level.block.Block;
import net.minecraft.world.level.block.state.BlockState;
import net.minecraft.world.phys.shapes.CollisionContext;
import net.minecraft.world.phys.shapes.VoxelShape;
import net.fabricmc.api.EnvType;
import net.fabricmc.api.Environment;
import net.fabricmc.fabric.api.object.builder.v1.block.FabricBlockSettings;
import org.betterx.bclib.client.models.ModelsHelper;
import org.betterx.bclib.interfaces.CustomColorProvider;
import org.betterx.betterend.client.models.Patterns;
import org.betterx.betterend.registry.EndBlocks;
import java.util.Optional;
import org.jetbrains.annotations.Nullable;
public class StoneLanternBlock extends EndLanternBlock implements CustomColorProvider {
private static final VoxelShape SHAPE_CEIL = box(3, 1, 3, 13, 16, 13);
private static final VoxelShape SHAPE_FLOOR = box(3, 0, 3, 13, 15, 13);
public StoneLanternBlock(Block source) {
super(FabricBlockSettings.copyOf(source).luminance(15));
}
@Override
public BlockColor getProvider() {
return ((CustomColorProvider) EndBlocks.AURORA_CRYSTAL).getProvider();
}
@Override
public ItemColor getItemProvider() {
return ((CustomColorProvider) EndBlocks.AURORA_CRYSTAL).getItemProvider();
}
@Override
@SuppressWarnings("deprecation")
public VoxelShape getShape(BlockState state, BlockGetter view, BlockPos pos, CollisionContext ePos) {
return state.getValue(IS_FLOOR) ? SHAPE_FLOOR : SHAPE_CEIL;
}
@Override
@Environment(EnvType.CLIENT)
public @Nullable BlockModel getBlockModel(ResourceLocation resourceLocation, BlockState blockState) {
String blockName = resourceLocation.getPath();
Optional<String> pattern = blockState.getValue(IS_FLOOR)
? Patterns.createJson(
Patterns.BLOCK_STONE_LANTERN_FLOOR,
blockName,
blockName
)
: Patterns.createJson(Patterns.BLOCK_STONE_LANTERN_CEIL, blockName, blockName);
return ModelsHelper.fromPattern(pattern);
}
}