More pottable plants & config save/load

This commit is contained in:
paulevsGitch 2021-07-11 23:05:07 +03:00
parent e41fd592c7
commit 797db9d2d4
17 changed files with 310 additions and 28 deletions

View file

@ -2,13 +2,15 @@ package ru.betterend.blocks;
import net.minecraft.core.BlockPos; import net.minecraft.core.BlockPos;
import net.minecraft.world.level.LevelReader; import net.minecraft.world.level.LevelReader;
import net.minecraft.world.level.block.Block;
import net.minecraft.world.level.block.state.BlockState; import net.minecraft.world.level.block.state.BlockState;
import net.minecraft.world.level.levelgen.feature.Feature; import net.minecraft.world.level.levelgen.feature.Feature;
import ru.bclib.blocks.FeatureSaplingBlock; import ru.bclib.blocks.FeatureSaplingBlock;
import ru.betterend.blocks.basis.PottableFeatureSapling;
import ru.betterend.registry.EndBlocks; import ru.betterend.registry.EndBlocks;
import ru.betterend.registry.EndFeatures; import ru.betterend.registry.EndFeatures;
public class DragonTreeSaplingBlock extends FeatureSaplingBlock { public class DragonTreeSaplingBlock extends PottableFeatureSapling {
public DragonTreeSaplingBlock() { public DragonTreeSaplingBlock() {
super(); super();
} }
@ -22,4 +24,9 @@ public class DragonTreeSaplingBlock extends FeatureSaplingBlock {
public boolean canSurvive(BlockState state, LevelReader world, BlockPos pos) { public boolean canSurvive(BlockState state, LevelReader world, BlockPos pos) {
return world.getBlockState(pos.below()).is(EndBlocks.SHADOW_GRASS); return world.getBlockState(pos.below()).is(EndBlocks.SHADOW_GRASS);
} }
@Override
public boolean canPlantOn(Block block) {
return block == EndBlocks.SHADOW_GRASS;
}
} }

View file

@ -14,7 +14,7 @@ public class EndBlockProperties extends BlockProperties {
public static final EnumProperty<CactusBottom> CACTUS_BOTTOM = EnumProperty.create("bottom", CactusBottom.class); public static final EnumProperty<CactusBottom> CACTUS_BOTTOM = EnumProperty.create("bottom", CactusBottom.class);
public static final IntegerProperty PORTAL = IntegerProperty.create("portal", 0, EndPortals.getCount()); public static final IntegerProperty PORTAL = IntegerProperty.create("portal", 0, EndPortals.getCount());
public static final IntegerProperty PLANT_ID = IntegerProperty.create("plant_id", 0, 31); public static final IntegerProperty PLANT_ID = IntegerProperty.create("plant_id", 0, 127);
public static final IntegerProperty SOIL_ID = IntegerProperty.create("soil_id", 0, 10); public static final IntegerProperty SOIL_ID = IntegerProperty.create("soil_id", 0, 10);
public static final BooleanProperty HAS_ITEM = BooleanProperty.create("has_item"); public static final BooleanProperty HAS_ITEM = BooleanProperty.create("has_item");

View file

@ -1,6 +1,8 @@
package ru.betterend.blocks; package ru.betterend.blocks;
import com.google.common.collect.Lists; import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import com.google.common.collect.Sets;
import com.google.gson.JsonElement; import com.google.gson.JsonElement;
import com.google.gson.JsonObject; import com.google.gson.JsonObject;
import com.mojang.math.Transformation; import com.mojang.math.Transformation;
@ -8,6 +10,7 @@ import com.mojang.math.Vector3f;
import net.fabricmc.api.EnvType; import net.fabricmc.api.EnvType;
import net.fabricmc.api.Environment; import net.fabricmc.api.Environment;
import net.fabricmc.fabric.api.object.builder.v1.block.FabricBlockSettings; import net.fabricmc.fabric.api.object.builder.v1.block.FabricBlockSettings;
import net.fabricmc.loader.api.FabricLoader;
import net.minecraft.client.Minecraft; import net.minecraft.client.Minecraft;
import net.minecraft.client.renderer.block.model.BlockModel; import net.minecraft.client.renderer.block.model.BlockModel;
import net.minecraft.client.resources.model.ModelResourceLocation; import net.minecraft.client.resources.model.ModelResourceLocation;
@ -25,6 +28,8 @@ import net.minecraft.world.item.ItemStack;
import net.minecraft.world.level.BlockGetter; import net.minecraft.world.level.BlockGetter;
import net.minecraft.world.level.Level; import net.minecraft.world.level.Level;
import net.minecraft.world.level.block.Block; import net.minecraft.world.level.block.Block;
import net.minecraft.world.level.block.LeavesBlock;
import net.minecraft.world.level.block.SaplingBlock;
import net.minecraft.world.level.block.state.BlockState; import net.minecraft.world.level.block.state.BlockState;
import net.minecraft.world.level.block.state.StateDefinition; import net.minecraft.world.level.block.state.StateDefinition;
import net.minecraft.world.level.block.state.properties.IntegerProperty; import net.minecraft.world.level.block.state.properties.IntegerProperty;
@ -33,6 +38,8 @@ import net.minecraft.world.phys.shapes.CollisionContext;
import net.minecraft.world.phys.shapes.Shapes; import net.minecraft.world.phys.shapes.Shapes;
import net.minecraft.world.phys.shapes.VoxelShape; import net.minecraft.world.phys.shapes.VoxelShape;
import ru.bclib.blocks.BaseBlockNotFull; import ru.bclib.blocks.BaseBlockNotFull;
import ru.bclib.client.models.BasePatterns;
import ru.bclib.client.models.BlockModelProvider;
import ru.bclib.client.models.ModelsHelper; import ru.bclib.client.models.ModelsHelper;
import ru.bclib.client.models.ModelsHelper.MultiPartBuilder; import ru.bclib.client.models.ModelsHelper.MultiPartBuilder;
import ru.bclib.client.models.PatternsHelper; import ru.bclib.client.models.PatternsHelper;
@ -44,13 +51,20 @@ import ru.bclib.util.BlocksHelper;
import ru.bclib.util.JsonFactory; import ru.bclib.util.JsonFactory;
import ru.betterend.BetterEnd; import ru.betterend.BetterEnd;
import ru.betterend.blocks.basis.EndTerrainBlock; import ru.betterend.blocks.basis.EndTerrainBlock;
import ru.betterend.blocks.basis.PottableLeavesBlock;
import ru.betterend.client.models.Patterns; import ru.betterend.client.models.Patterns;
import ru.betterend.config.Configs;
import ru.betterend.interfaces.PottablePlant; import ru.betterend.interfaces.PottablePlant;
import ru.betterend.registry.EndBlocks; import ru.betterend.registry.EndBlocks;
import java.io.File;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.Optional; import java.util.Optional;
import java.util.Set;
import java.util.SplittableRandom;
public class FlowerPotBlock extends BaseBlockNotFull implements IRenderTyped, IPostInit { public class FlowerPotBlock extends BaseBlockNotFull implements IRenderTyped, IPostInit {
private static final IntegerProperty PLANT_ID = EndBlockProperties.PLANT_ID; private static final IntegerProperty PLANT_ID = EndBlockProperties.PLANT_ID;
@ -76,20 +90,47 @@ public class FlowerPotBlock extends BaseBlockNotFull implements IRenderTyped, IP
if (FlowerPotBlock.plants != null) { if (FlowerPotBlock.plants != null) {
return; return;
} }
List<Block> soils = Lists.newArrayList();
List<Block> plants = Lists.newArrayList(); Block[] plants = new Block[128];
Block[] soils = new Block[16];
Map<String, Integer> reservedPlantsIDs = Maps.newHashMap();
Map<String, Integer> reservedSoilIDs = Maps.newHashMap();
JsonObject obj = JsonFactory.getJsonObject(new File(FabricLoader.getInstance().getConfigDir().toFile(), BetterEnd.MOD_ID + "/blocks.json"));
if (obj.get("flower_pots") != null) {
JsonElement plantsObj = obj.get("flower_pots").getAsJsonObject().get("plants");
JsonElement soilsObj = obj.get("flower_pots").getAsJsonObject().get("soils");
if (plantsObj != null) {
plantsObj.getAsJsonObject().entrySet().forEach(entry -> {
String name = entry.getKey().substring(0, entry.getKey().indexOf(' '));
reservedPlantsIDs.put(name, entry.getValue().getAsInt());
});
}
if (soilsObj != null) {
soilsObj.getAsJsonObject().entrySet().forEach(entry -> {
String name = entry.getKey().substring(0, entry.getKey().indexOf(' '));
reservedSoilIDs.put(name, entry.getValue().getAsInt());
});
}
}
EndBlocks.getModBlocks().forEach(block -> { EndBlocks.getModBlocks().forEach(block -> {
if (block instanceof PottablePlant && block.getStateDefinition().getProperties().isEmpty()) { if (block instanceof PottablePlant && canBeAdded(block)) {
if (!(block instanceof ISpetialItem) || !((ISpetialItem) block).canPlaceOnWater()) { processBlock(plants, block, "flower_pots.plants", reservedPlantsIDs);
plants.add(block);
}
} }
else if (block instanceof EndTerrainBlock) { else if (block instanceof EndTerrainBlock) {
soils.add(block); processBlock(soils, block, "flower_pots.soils", reservedSoilIDs);
} }
}); });
FlowerPotBlock.plants = plants.toArray(new Block[] {}); Configs.BLOCK_CONFIG.saveChanges();
FlowerPotBlock.soils = soils.toArray(new Block[] {});
FlowerPotBlock.plants = new Block[maxNotNull(plants) + 1];
System.arraycopy(plants, 0, FlowerPotBlock.plants, 0, FlowerPotBlock.plants.length);
FlowerPotBlock.soils = new Block[maxNotNull(soils) + 1];
System.arraycopy(soils, 0, FlowerPotBlock.soils, 0, FlowerPotBlock.soils.length);
if (PLANT_ID.getValue(Integer.toString(FlowerPotBlock.plants.length)).isEmpty()) { if (PLANT_ID.getValue(Integer.toString(FlowerPotBlock.plants.length)).isEmpty()) {
throw new RuntimeException("There are too much plant ID values!"); throw new RuntimeException("There are too much plant ID values!");
} }
@ -98,6 +139,49 @@ public class FlowerPotBlock extends BaseBlockNotFull implements IRenderTyped, IP
} }
} }
private int maxNotNull(Block[] array) {
int max = 0;
for (int i = 0; i < array.length; i++) {
if (array[i] != null) {
max = i;
}
}
return max;
}
private boolean canBeAdded(Block block) {
if (block instanceof SaplingBlock) {
return true;
}
else if (block instanceof PottableLeavesBlock) {
return true;
}
else if (block instanceof ISpetialItem) {
return !((ISpetialItem) block).canPlaceOnWater();
}
else if (block.getStateDefinition().getProperties().isEmpty()) {
return true;
}
return false;
}
private void processBlock(Block[] target, Block block, String path, Map<String, Integer> idMap) {
ResourceLocation location = Registry.BLOCK.getKey(block);
if (idMap.containsKey(location.getPath())) {
target[idMap.get(location.getPath())] = block;
}
else {
for (int i = 0; i < target.length; i++) {
if (!idMap.values().contains(i)) {
target[i] = block;
idMap.put(location.getPath(), i);
Configs.BLOCK_CONFIG.getInt(path, location.getPath(), i);
break;
}
}
}
}
@Override @Override
public InteractionResult use(BlockState state, Level level, BlockPos pos, Player player, InteractionHand hand, BlockHitResult hit) { public InteractionResult use(BlockState state, Level level, BlockPos pos, Player player, InteractionHand hand, BlockHitResult hit) {
if (level.isClientSide) { if (level.isClientSide) {
@ -105,7 +189,7 @@ public class FlowerPotBlock extends BaseBlockNotFull implements IRenderTyped, IP
} }
ItemStack itemStack = player.getItemInHand(hand); ItemStack itemStack = player.getItemInHand(hand);
int soilID = state.getValue(SOIL_ID); int soilID = state.getValue(SOIL_ID);
if (soilID == 0) { if (soilID == 0 || soils[soilID - 1] == null) {
if (!(itemStack.getItem() instanceof BlockItem)) { if (!(itemStack.getItem() instanceof BlockItem)) {
return InteractionResult.PASS; return InteractionResult.PASS;
} }
@ -170,6 +254,10 @@ public class FlowerPotBlock extends BaseBlockNotFull implements IRenderTyped, IP
Transformation offset = new Transformation(new Vector3f(0, 7.5F / 16F, 0), null, null, null); Transformation offset = new Transformation(new Vector3f(0, 7.5F / 16F, 0), null, null, null);
for (int i = 0; i < plants.length; i++) { for (int i = 0; i < plants.length; i++) {
if (plants[i] == null) {
continue;
}
final int compareID = i + 1; final int compareID = i + 1;
ResourceLocation modelPath = Registry.BLOCK.getKey(plants[i]); ResourceLocation modelPath = Registry.BLOCK.getKey(plants[i]);
ResourceLocation objSource = new ResourceLocation(modelPath.getNamespace(), "block/potted_" + modelPath.getPath() + ".json"); ResourceLocation objSource = new ResourceLocation(modelPath.getNamespace(), "block/potted_" + modelPath.getPath() + ".json");
@ -178,6 +266,32 @@ public class FlowerPotBlock extends BaseBlockNotFull implements IRenderTyped, IP
model.part(objSource).setTransformation(offset).setCondition(state -> state.getValue(PLANT_ID) == compareID).add(); model.part(objSource).setTransformation(offset).setCondition(state -> state.getValue(PLANT_ID) == compareID).add();
continue; continue;
} }
else if (plants[i] instanceof SaplingBlock) {
ResourceLocation loc = Registry.BLOCK.getKey(plants[i]);
modelPath = new ResourceLocation(loc.getNamespace(), "block/" + loc.getPath());
Map<String, String> textures = Maps.newHashMap();
textures.put("%modid%", loc.getNamespace());
textures.put("%texture%", loc.getPath());
Optional<String> pattern = Patterns.createJson(BasePatterns.BLOCK_CROSS, textures);
UnbakedModel unbakedModel = ModelsHelper.fromPattern(pattern);
modelCache.put(modelPath, unbakedModel);
model.part(modelPath).setTransformation(offset).setCondition(state -> state.getValue(PLANT_ID) == compareID).add();
continue;
}
else if (plants[i] instanceof PottableLeavesBlock) {
ResourceLocation loc = Registry.BLOCK.getKey(plants[i]);
modelPath = new ResourceLocation(loc.getNamespace(), "block/" + loc.getPath());
Map<String, String> textures = Maps.newHashMap();
textures.put("%leaves%", loc.getPath().contains("lucernia") ? loc.getPath() + "_1" : loc.getPath());
textures.put("%stem%", loc.getPath().replace("_leaves", "_log_side"));
Optional<String> pattern = Patterns.createJson(Patterns.BLOCK_POTTED_LEAVES, textures);
UnbakedModel unbakedModel = ModelsHelper.fromPattern(pattern);
modelCache.put(modelPath, unbakedModel);
model.part(modelPath).setTransformation(offset).setCondition(state -> state.getValue(PLANT_ID) == compareID).add();
continue;
}
objSource = new ResourceLocation(modelPath.getNamespace(), "blockstates/" + modelPath.getPath() + ".json"); objSource = new ResourceLocation(modelPath.getNamespace(), "blockstates/" + modelPath.getPath() + ".json");
JsonObject obj = JsonFactory.getJsonObject(objSource); JsonObject obj = JsonFactory.getJsonObject(objSource);
if (obj != null) { if (obj != null) {
@ -191,9 +305,21 @@ public class FlowerPotBlock extends BaseBlockNotFull implements IRenderTyped, IP
} }
model.part(new ResourceLocation(path)).setTransformation(offset).setCondition(state -> state.getValue(PLANT_ID) == compareID).add(); model.part(new ResourceLocation(path)).setTransformation(offset).setCondition(state -> state.getValue(PLANT_ID) == compareID).add();
} }
else {
for (ResourceLocation location: modelCache.keySet()) {
if (location.getPath().equals(modelPath.getPath())) {
model.part(location).setTransformation(offset).setCondition(state -> state.getValue(PLANT_ID) == compareID).add();
break;
}
}
}
} }
for (int i = 0; i < soils.length; i++) { for (int i = 0; i < soils.length; i++) {
if (soils[i] == null) {
continue;
}
ResourceLocation soilLoc = BetterEnd.makeID("flower_pot_soil_" + i); ResourceLocation soilLoc = BetterEnd.makeID("flower_pot_soil_" + i);
if (!modelCache.containsKey(soilLoc)) { if (!modelCache.containsKey(soilLoc)) {
String texture = Registry.BLOCK.getKey(soils[i]).getPath() + "_top"; String texture = Registry.BLOCK.getKey(soils[i]).getPath() + "_top";

View file

@ -1,12 +1,28 @@
package ru.betterend.blocks; package ru.betterend.blocks;
import net.minecraft.core.BlockPos;
import net.minecraft.world.level.LevelReader;
import net.minecraft.world.level.block.Block;
import net.minecraft.world.level.block.state.BlockState;
import net.minecraft.world.level.levelgen.feature.Feature; import net.minecraft.world.level.levelgen.feature.Feature;
import ru.bclib.blocks.FeatureSaplingBlock; import ru.bclib.blocks.FeatureSaplingBlock;
import ru.betterend.blocks.basis.PottableFeatureSapling;
import ru.betterend.registry.EndBlocks;
import ru.betterend.registry.EndFeatures; import ru.betterend.registry.EndFeatures;
public class HelixTreeSaplingBlock extends FeatureSaplingBlock { public class HelixTreeSaplingBlock extends PottableFeatureSapling {
@Override @Override
protected Feature<?> getFeature() { protected Feature<?> getFeature() {
return EndFeatures.HELIX_TREE.getFeature(); return EndFeatures.HELIX_TREE.getFeature();
} }
@Override
public boolean canSurvive(BlockState state, LevelReader world, BlockPos pos) {
return world.getBlockState(pos.below()).is(EndBlocks.AMBER_MOSS);
}
@Override
public boolean canPlantOn(Block block) {
return block == EndBlocks.AMBER_MOSS;
}
} }

View file

@ -2,13 +2,15 @@ package ru.betterend.blocks;
import net.minecraft.core.BlockPos; import net.minecraft.core.BlockPos;
import net.minecraft.world.level.LevelReader; import net.minecraft.world.level.LevelReader;
import net.minecraft.world.level.block.Block;
import net.minecraft.world.level.block.state.BlockState; import net.minecraft.world.level.block.state.BlockState;
import net.minecraft.world.level.levelgen.feature.Feature; import net.minecraft.world.level.levelgen.feature.Feature;
import ru.bclib.blocks.FeatureSaplingBlock; import ru.bclib.blocks.FeatureSaplingBlock;
import ru.betterend.blocks.basis.PottableFeatureSapling;
import ru.betterend.registry.EndBlocks; import ru.betterend.registry.EndBlocks;
import ru.betterend.registry.EndFeatures; import ru.betterend.registry.EndFeatures;
public class LacugroveSaplingBlock extends FeatureSaplingBlock { public class LacugroveSaplingBlock extends PottableFeatureSapling {
public LacugroveSaplingBlock() { public LacugroveSaplingBlock() {
super(); super();
} }
@ -22,4 +24,9 @@ public class LacugroveSaplingBlock extends FeatureSaplingBlock {
public boolean canSurvive(BlockState state, LevelReader world, BlockPos pos) { public boolean canSurvive(BlockState state, LevelReader world, BlockPos pos) {
return world.getBlockState(pos.below()).is(EndBlocks.END_MOSS) || world.getBlockState(pos.below()).is(EndBlocks.ENDSTONE_DUST); return world.getBlockState(pos.below()).is(EndBlocks.END_MOSS) || world.getBlockState(pos.below()).is(EndBlocks.ENDSTONE_DUST);
} }
@Override
public boolean canPlantOn(Block block) {
return block == EndBlocks.END_MOSS;
}
} }

View file

@ -2,13 +2,15 @@ package ru.betterend.blocks;
import net.minecraft.core.BlockPos; import net.minecraft.core.BlockPos;
import net.minecraft.world.level.LevelReader; import net.minecraft.world.level.LevelReader;
import net.minecraft.world.level.block.Block;
import net.minecraft.world.level.block.state.BlockState; import net.minecraft.world.level.block.state.BlockState;
import net.minecraft.world.level.levelgen.feature.Feature; import net.minecraft.world.level.levelgen.feature.Feature;
import ru.bclib.blocks.FeatureSaplingBlock; import ru.bclib.blocks.FeatureSaplingBlock;
import ru.betterend.blocks.basis.PottableFeatureSapling;
import ru.betterend.registry.EndBlocks; import ru.betterend.registry.EndBlocks;
import ru.betterend.registry.EndFeatures; import ru.betterend.registry.EndFeatures;
public class LucerniaSaplingBlock extends FeatureSaplingBlock { public class LucerniaSaplingBlock extends PottableFeatureSapling {
public LucerniaSaplingBlock() { public LucerniaSaplingBlock() {
super(); super();
} }
@ -22,4 +24,9 @@ public class LucerniaSaplingBlock extends FeatureSaplingBlock {
public boolean canSurvive(BlockState state, LevelReader world, BlockPos pos) { public boolean canSurvive(BlockState state, LevelReader world, BlockPos pos) {
return world.getBlockState(pos.below()).is(EndBlocks.RUTISCUS); return world.getBlockState(pos.below()).is(EndBlocks.RUTISCUS);
} }
@Override
public boolean canPlantOn(Block block) {
return false;
}
} }

View file

@ -2,14 +2,15 @@ package ru.betterend.blocks;
import net.minecraft.core.BlockPos; import net.minecraft.core.BlockPos;
import net.minecraft.world.level.LevelReader; import net.minecraft.world.level.LevelReader;
import net.minecraft.world.level.block.Block;
import net.minecraft.world.level.block.state.BlockState; import net.minecraft.world.level.block.state.BlockState;
import net.minecraft.world.level.levelgen.feature.Feature; import net.minecraft.world.level.levelgen.feature.Feature;
import ru.bclib.blocks.FeatureSaplingBlock; import ru.bclib.blocks.FeatureSaplingBlock;
import ru.betterend.blocks.basis.PottableFeatureSapling;
import ru.betterend.registry.EndBlocks; import ru.betterend.registry.EndBlocks;
import ru.betterend.registry.EndFeatures; import ru.betterend.registry.EndFeatures;
public class MossyGlowshroomSaplingBlock extends FeatureSaplingBlock { public class MossyGlowshroomSaplingBlock extends PottableFeatureSapling {
public MossyGlowshroomSaplingBlock() { public MossyGlowshroomSaplingBlock() {
super(7); super(7);
} }
@ -23,4 +24,9 @@ public class MossyGlowshroomSaplingBlock extends FeatureSaplingBlock {
public boolean canSurvive(BlockState state, LevelReader world, BlockPos pos) { public boolean canSurvive(BlockState state, LevelReader world, BlockPos pos) {
return world.getBlockState(pos.below()).is(EndBlocks.END_MOSS) || world.getBlockState(pos.below()).is(EndBlocks.END_MYCELIUM); return world.getBlockState(pos.below()).is(EndBlocks.END_MOSS) || world.getBlockState(pos.below()).is(EndBlocks.END_MYCELIUM);
} }
@Override
public boolean canPlantOn(Block block) {
return block == EndBlocks.END_MOSS || block == EndBlocks.END_MYCELIUM;
}
} }

View file

@ -41,6 +41,7 @@ import ru.bclib.interfaces.IRenderTyped;
import ru.bclib.util.BlocksHelper; import ru.bclib.util.BlocksHelper;
import ru.bclib.util.MHelper; import ru.bclib.util.MHelper;
import ru.betterend.blocks.EndBlockProperties.CactusBottom; import ru.betterend.blocks.EndBlockProperties.CactusBottom;
import ru.betterend.interfaces.PottablePlant;
import ru.betterend.registry.EndBlocks; import ru.betterend.registry.EndBlocks;
import java.util.EnumMap; import java.util.EnumMap;
@ -48,7 +49,7 @@ import java.util.List;
import java.util.Random; import java.util.Random;
@SuppressWarnings("deprecation") @SuppressWarnings("deprecation")
public class NeonCactusPlantBlock extends BaseBlockNotFull implements SimpleWaterloggedBlock, IRenderTyped { public class NeonCactusPlantBlock extends BaseBlockNotFull implements SimpleWaterloggedBlock, IRenderTyped, PottablePlant {
public static final EnumProperty<TripleShape> SHAPE = BlockProperties.TRIPLE_SHAPE; public static final EnumProperty<TripleShape> SHAPE = BlockProperties.TRIPLE_SHAPE;
public static final EnumProperty<CactusBottom> CACTUS_BOTTOM = EndBlockProperties.CACTUS_BOTTOM; public static final EnumProperty<CactusBottom> CACTUS_BOTTOM = EndBlockProperties.CACTUS_BOTTOM;
public static final BooleanProperty WATERLOGGED = BlockStateProperties.WATERLOGGED; public static final BooleanProperty WATERLOGGED = BlockStateProperties.WATERLOGGED;
@ -395,4 +396,9 @@ public class NeonCactusPlantBlock extends BaseBlockNotFull implements SimpleWate
SMALL_SHAPES_OPEN.put(Direction.WEST, Block.box(4, 4, 4, 16, 12, 12)); SMALL_SHAPES_OPEN.put(Direction.WEST, Block.box(4, 4, 4, 16, 12, 12));
SMALL_SHAPES_OPEN.put(Direction.EAST, Block.box(0, 4, 4, 12, 12, 12)); SMALL_SHAPES_OPEN.put(Direction.EAST, Block.box(0, 4, 4, 12, 12, 12));
} }
@Override
public boolean canPlantOn(Block block) {
return true;
}
} }

View file

@ -2,13 +2,15 @@ package ru.betterend.blocks;
import net.minecraft.core.BlockPos; import net.minecraft.core.BlockPos;
import net.minecraft.world.level.LevelReader; import net.minecraft.world.level.LevelReader;
import net.minecraft.world.level.block.Block;
import net.minecraft.world.level.block.state.BlockState; import net.minecraft.world.level.block.state.BlockState;
import net.minecraft.world.level.levelgen.feature.Feature; import net.minecraft.world.level.levelgen.feature.Feature;
import ru.bclib.blocks.FeatureSaplingBlock; import ru.bclib.blocks.FeatureSaplingBlock;
import ru.betterend.blocks.basis.PottableFeatureSapling;
import ru.betterend.registry.EndBlocks; import ru.betterend.registry.EndBlocks;
import ru.betterend.registry.EndFeatures; import ru.betterend.registry.EndFeatures;
public class PythadendronSaplingBlock extends FeatureSaplingBlock { public class PythadendronSaplingBlock extends PottableFeatureSapling {
public PythadendronSaplingBlock() { public PythadendronSaplingBlock() {
super(); super();
} }
@ -22,4 +24,9 @@ public class PythadendronSaplingBlock extends FeatureSaplingBlock {
public boolean canSurvive(BlockState state, LevelReader world, BlockPos pos) { public boolean canSurvive(BlockState state, LevelReader world, BlockPos pos) {
return world.getBlockState(pos.below()).is(EndBlocks.CHORUS_NYLIUM); return world.getBlockState(pos.below()).is(EndBlocks.CHORUS_NYLIUM);
} }
@Override
public boolean canPlantOn(Block block) {
return block == EndBlocks.CHORUS_NYLIUM;
}
} }

View file

@ -30,13 +30,14 @@ import ru.bclib.blocks.BaseAttachedBlock;
import ru.bclib.client.render.BCLRenderLayer; import ru.bclib.client.render.BCLRenderLayer;
import ru.bclib.interfaces.IRenderTyped; import ru.bclib.interfaces.IRenderTyped;
import ru.bclib.util.BlocksHelper; import ru.bclib.util.BlocksHelper;
import ru.betterend.interfaces.PottablePlant;
import ru.betterend.registry.EndFeatures; import ru.betterend.registry.EndFeatures;
import java.util.EnumMap; import java.util.EnumMap;
import java.util.List; import java.util.List;
import java.util.Random; import java.util.Random;
public class SmallJellyshroomBlock extends BaseAttachedBlock implements IRenderTyped, BonemealableBlock { public class SmallJellyshroomBlock extends BaseAttachedBlock implements IRenderTyped, BonemealableBlock, PottablePlant {
private static final EnumMap<Direction, VoxelShape> BOUNDING_SHAPES = Maps.newEnumMap(Direction.class); private static final EnumMap<Direction, VoxelShape> BOUNDING_SHAPES = Maps.newEnumMap(Direction.class);
public SmallJellyshroomBlock() { public SmallJellyshroomBlock() {
@ -97,4 +98,9 @@ public class SmallJellyshroomBlock extends BaseAttachedBlock implements IRenderT
BlocksHelper.setWithUpdate(world, pos, Blocks.AIR); BlocksHelper.setWithUpdate(world, pos, Blocks.AIR);
EndFeatures.JELLYSHROOM.getFeature().place(new FeaturePlaceContext<>(world, null, random, pos, null)); EndFeatures.JELLYSHROOM.getFeature().place(new FeaturePlaceContext<>(world, null, random, pos, null));
} }
@Override
public boolean canPlantOn(Block block) {
return true;
}
} }

View file

@ -2,13 +2,15 @@ package ru.betterend.blocks;
import net.minecraft.core.BlockPos; import net.minecraft.core.BlockPos;
import net.minecraft.world.level.LevelReader; import net.minecraft.world.level.LevelReader;
import net.minecraft.world.level.block.Block;
import net.minecraft.world.level.block.state.BlockState; import net.minecraft.world.level.block.state.BlockState;
import net.minecraft.world.level.levelgen.feature.Feature; import net.minecraft.world.level.levelgen.feature.Feature;
import ru.bclib.blocks.FeatureSaplingBlock; import ru.bclib.blocks.FeatureSaplingBlock;
import ru.betterend.blocks.basis.PottableFeatureSapling;
import ru.betterend.registry.EndBlocks; import ru.betterend.registry.EndBlocks;
import ru.betterend.registry.EndFeatures; import ru.betterend.registry.EndFeatures;
public class TenaneaSaplingBlock extends FeatureSaplingBlock { public class TenaneaSaplingBlock extends PottableFeatureSapling {
public TenaneaSaplingBlock() { public TenaneaSaplingBlock() {
super(); super();
} }
@ -22,4 +24,9 @@ public class TenaneaSaplingBlock extends FeatureSaplingBlock {
public boolean canSurvive(BlockState state, LevelReader world, BlockPos pos) { public boolean canSurvive(BlockState state, LevelReader world, BlockPos pos) {
return world.getBlockState(pos.below()).is(EndBlocks.PINK_MOSS); return world.getBlockState(pos.below()).is(EndBlocks.PINK_MOSS);
} }
@Override
public boolean canPlantOn(Block block) {
return block == EndBlocks.PINK_MOSS;
}
} }

View file

@ -2,14 +2,16 @@ package ru.betterend.blocks;
import net.minecraft.core.BlockPos; import net.minecraft.core.BlockPos;
import net.minecraft.world.level.LevelReader; import net.minecraft.world.level.LevelReader;
import net.minecraft.world.level.block.Block;
import net.minecraft.world.level.block.state.BlockState; import net.minecraft.world.level.block.state.BlockState;
import net.minecraft.world.level.levelgen.feature.Feature; import net.minecraft.world.level.levelgen.feature.Feature;
import ru.bclib.blocks.FeatureSaplingBlock; import ru.bclib.blocks.FeatureSaplingBlock;
import ru.bclib.client.render.BCLRenderLayer; import ru.bclib.client.render.BCLRenderLayer;
import ru.betterend.blocks.basis.PottableFeatureSapling;
import ru.betterend.registry.EndBlocks; import ru.betterend.registry.EndBlocks;
import ru.betterend.registry.EndFeatures; import ru.betterend.registry.EndFeatures;
public class UmbrellaTreeSaplingBlock extends FeatureSaplingBlock { public class UmbrellaTreeSaplingBlock extends PottableFeatureSapling {
public UmbrellaTreeSaplingBlock() { public UmbrellaTreeSaplingBlock() {
super(); super();
} }
@ -28,4 +30,9 @@ public class UmbrellaTreeSaplingBlock extends FeatureSaplingBlock {
public BCLRenderLayer getRenderLayer() { public BCLRenderLayer getRenderLayer() {
return BCLRenderLayer.TRANSLUCENT; return BCLRenderLayer.TRANSLUCENT;
} }
@Override
public boolean canPlantOn(Block block) {
return block == EndBlocks.JUNGLE_MOSS;
}
} }

View file

@ -0,0 +1,16 @@
package ru.betterend.blocks.basis;
import net.minecraft.world.level.block.Block;
import net.minecraft.world.level.levelgen.feature.Feature;
import ru.bclib.blocks.FeatureSaplingBlock;
import ru.betterend.interfaces.PottablePlant;
public abstract class PottableFeatureSapling extends FeatureSaplingBlock implements PottablePlant {
public PottableFeatureSapling() {
super();
}
public PottableFeatureSapling(int light) {
super(light);
}
}

View file

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

View file

@ -76,6 +76,7 @@ public class Patterns {
public final static ResourceLocation BLOCK_PATH = BetterEnd.makeID("patterns/block/path.json"); public final static ResourceLocation BLOCK_PATH = BetterEnd.makeID("patterns/block/path.json");
public final static ResourceLocation BLOCK_FLOWER_POT = BetterEnd.makeID("patterns/block/flower_pot.json"); public final static ResourceLocation BLOCK_FLOWER_POT = BetterEnd.makeID("patterns/block/flower_pot.json");
public final static ResourceLocation BLOCK_FLOWER_POT_SOIL = BetterEnd.makeID("patterns/block/flower_pot_soil.json"); public final static ResourceLocation BLOCK_FLOWER_POT_SOIL = BetterEnd.makeID("patterns/block/flower_pot_soil.json");
public final static ResourceLocation BLOCK_POTTED_LEAVES = BetterEnd.makeID("patterns/block/potted_leaves.json");
//Item Models //Item Models
public final static ResourceLocation ITEM_WALL = BetterEnd.makeID("patterns/item/pattern_wall.json"); public final static ResourceLocation ITEM_WALL = BetterEnd.makeID("patterns/item/pattern_wall.json");

View file

@ -12,7 +12,6 @@ import ru.bclib.blocks.BaseBarrelBlock;
import ru.bclib.blocks.BaseChestBlock; import ru.bclib.blocks.BaseChestBlock;
import ru.bclib.blocks.BaseCropBlock; import ru.bclib.blocks.BaseCropBlock;
import ru.bclib.blocks.BaseFurnaceBlock; import ru.bclib.blocks.BaseFurnaceBlock;
import ru.bclib.blocks.BaseLeavesBlock;
import ru.bclib.blocks.BaseOreBlock; import ru.bclib.blocks.BaseOreBlock;
import ru.bclib.blocks.BasePathBlock; import ru.bclib.blocks.BasePathBlock;
import ru.bclib.blocks.BaseRotatedPillarBlock; import ru.bclib.blocks.BaseRotatedPillarBlock;
@ -133,6 +132,7 @@ import ru.betterend.blocks.basis.EndUnderwaterWallPlantBlock;
import ru.betterend.blocks.basis.EndWallMushroom; import ru.betterend.blocks.basis.EndWallMushroom;
import ru.betterend.blocks.basis.EndWallPlantBlock; import ru.betterend.blocks.basis.EndWallPlantBlock;
import ru.betterend.blocks.basis.FurBlock; import ru.betterend.blocks.basis.FurBlock;
import ru.betterend.blocks.basis.PottableLeavesBlock;
import ru.betterend.blocks.basis.StoneLanternBlock; import ru.betterend.blocks.basis.StoneLanternBlock;
import ru.betterend.blocks.complex.ColoredMaterial; import ru.betterend.blocks.complex.ColoredMaterial;
import ru.betterend.blocks.complex.CrystalSubblocksMaterial; import ru.betterend.blocks.complex.CrystalSubblocksMaterial;
@ -221,7 +221,7 @@ public class EndBlocks extends BlocksRegistry {
public static final WoodenMaterial MOSSY_GLOWSHROOM = new WoodenMaterial("mossy_glowshroom", MaterialColor.COLOR_GRAY, MaterialColor.WOOD); public static final WoodenMaterial MOSSY_GLOWSHROOM = new WoodenMaterial("mossy_glowshroom", MaterialColor.COLOR_GRAY, MaterialColor.WOOD);
public static final Block PYTHADENDRON_SAPLING = registerBlock("pythadendron_sapling", new PythadendronSaplingBlock()); public static final Block PYTHADENDRON_SAPLING = registerBlock("pythadendron_sapling", new PythadendronSaplingBlock());
public static final Block PYTHADENDRON_LEAVES = registerBlock("pythadendron_leaves", new BaseLeavesBlock(PYTHADENDRON_SAPLING, MaterialColor.COLOR_MAGENTA)); public static final Block PYTHADENDRON_LEAVES = registerBlock("pythadendron_leaves", new PottableLeavesBlock(PYTHADENDRON_SAPLING, MaterialColor.COLOR_MAGENTA));
public static final WoodenMaterial PYTHADENDRON = new WoodenMaterial("pythadendron", MaterialColor.COLOR_MAGENTA, MaterialColor.COLOR_PURPLE); public static final WoodenMaterial PYTHADENDRON = new WoodenMaterial("pythadendron", MaterialColor.COLOR_MAGENTA, MaterialColor.COLOR_PURPLE);
public static final Block END_LOTUS_SEED = registerBlock("end_lotus_seed", new EndLotusSeedBlock()); public static final Block END_LOTUS_SEED = registerBlock("end_lotus_seed", new EndLotusSeedBlock());
@ -231,15 +231,15 @@ public class EndBlocks extends BlocksRegistry {
public static final WoodenMaterial END_LOTUS = new WoodenMaterial("end_lotus", MaterialColor.COLOR_LIGHT_BLUE, MaterialColor.COLOR_CYAN); public static final WoodenMaterial END_LOTUS = new WoodenMaterial("end_lotus", MaterialColor.COLOR_LIGHT_BLUE, MaterialColor.COLOR_CYAN);
public static final Block LACUGROVE_SAPLING = registerBlock("lacugrove_sapling", new LacugroveSaplingBlock()); public static final Block LACUGROVE_SAPLING = registerBlock("lacugrove_sapling", new LacugroveSaplingBlock());
public static final Block LACUGROVE_LEAVES = registerBlock("lacugrove_leaves", new BaseLeavesBlock(LACUGROVE_SAPLING, MaterialColor.COLOR_CYAN)); public static final Block LACUGROVE_LEAVES = registerBlock("lacugrove_leaves", new PottableLeavesBlock(LACUGROVE_SAPLING, MaterialColor.COLOR_CYAN));
public static final WoodenMaterial LACUGROVE = new WoodenMaterial("lacugrove", MaterialColor.COLOR_BROWN, MaterialColor.COLOR_YELLOW); public static final WoodenMaterial LACUGROVE = new WoodenMaterial("lacugrove", MaterialColor.COLOR_BROWN, MaterialColor.COLOR_YELLOW);
public static final Block DRAGON_TREE_SAPLING = registerBlock("dragon_tree_sapling", new DragonTreeSaplingBlock()); public static final Block DRAGON_TREE_SAPLING = registerBlock("dragon_tree_sapling", new DragonTreeSaplingBlock());
public static final Block DRAGON_TREE_LEAVES = registerBlock("dragon_tree_leaves", new BaseLeavesBlock(DRAGON_TREE_SAPLING, MaterialColor.COLOR_MAGENTA)); public static final Block DRAGON_TREE_LEAVES = registerBlock("dragon_tree_leaves", new PottableLeavesBlock(DRAGON_TREE_SAPLING, MaterialColor.COLOR_MAGENTA));
public static final WoodenMaterial DRAGON_TREE = new WoodenMaterial("dragon_tree", MaterialColor.COLOR_BLACK, MaterialColor.COLOR_MAGENTA); public static final WoodenMaterial DRAGON_TREE = new WoodenMaterial("dragon_tree", MaterialColor.COLOR_BLACK, MaterialColor.COLOR_MAGENTA);
public static final Block TENANEA_SAPLING = registerBlock("tenanea_sapling", new TenaneaSaplingBlock()); public static final Block TENANEA_SAPLING = registerBlock("tenanea_sapling", new TenaneaSaplingBlock());
public static final Block TENANEA_LEAVES = registerBlock("tenanea_leaves", new BaseLeavesBlock(TENANEA_SAPLING, MaterialColor.COLOR_PINK)); public static final Block TENANEA_LEAVES = registerBlock("tenanea_leaves", new PottableLeavesBlock(TENANEA_SAPLING, MaterialColor.COLOR_PINK));
public static final Block TENANEA_FLOWERS = registerBlock("tenanea_flowers", new TenaneaFlowersBlock()); public static final Block TENANEA_FLOWERS = registerBlock("tenanea_flowers", new TenaneaFlowersBlock());
public static final Block TENANEA_OUTER_LEAVES = registerBlock("tenanea_outer_leaves", new FurBlock(TENANEA_SAPLING, 32)); public static final Block TENANEA_OUTER_LEAVES = registerBlock("tenanea_outer_leaves", new FurBlock(TENANEA_SAPLING, 32));
public static final WoodenMaterial TENANEA = new WoodenMaterial("tenanea", MaterialColor.COLOR_BROWN, MaterialColor.COLOR_PINK); public static final WoodenMaterial TENANEA = new WoodenMaterial("tenanea", MaterialColor.COLOR_BROWN, MaterialColor.COLOR_PINK);
@ -258,7 +258,7 @@ public class EndBlocks extends BlocksRegistry {
public static final WoodenMaterial JELLYSHROOM = new WoodenMaterial("jellyshroom", MaterialColor.COLOR_PURPLE, MaterialColor.COLOR_LIGHT_BLUE); public static final WoodenMaterial JELLYSHROOM = new WoodenMaterial("jellyshroom", MaterialColor.COLOR_PURPLE, MaterialColor.COLOR_LIGHT_BLUE);
public static final Block LUCERNIA_SAPLING = registerBlock("lucernia_sapling", new LucerniaSaplingBlock()); public static final Block LUCERNIA_SAPLING = registerBlock("lucernia_sapling", new LucerniaSaplingBlock());
public static final Block LUCERNIA_LEAVES = registerBlock("lucernia_leaves", new BaseLeavesBlock(LUCERNIA_SAPLING, MaterialColor.COLOR_ORANGE)); public static final Block LUCERNIA_LEAVES = registerBlock("lucernia_leaves", new PottableLeavesBlock(LUCERNIA_SAPLING, MaterialColor.COLOR_ORANGE));
public static final Block LUCERNIA_OUTER_LEAVES = registerBlock("lucernia_outer_leaves", new FurBlock(LUCERNIA_SAPLING, 32)); public static final Block LUCERNIA_OUTER_LEAVES = registerBlock("lucernia_outer_leaves", new FurBlock(LUCERNIA_SAPLING, 32));
public static final WoodenMaterial LUCERNIA = new WoodenMaterial("lucernia", MaterialColor.COLOR_ORANGE, MaterialColor.COLOR_ORANGE); public static final WoodenMaterial LUCERNIA = new WoodenMaterial("lucernia", MaterialColor.COLOR_ORANGE, MaterialColor.COLOR_ORANGE);

View file

@ -0,0 +1,35 @@
{
"__comment": "Designed by Paulevs with Cubik Studio - https://cubik.studio",
"textures": {
"particle": "betterend:block/%leaves%",
"stem": "betterend:block/%stem%",
"leaves": "betterend:block/%leaves%"
},
"elements": [
{
"__comment": "Box1",
"from": [ 3, 2, 3 ],
"to": [ 13, 12, 13 ],
"faces": {
"down": { "uv": [ 3, 3, 13, 13 ], "texture": "#leaves" },
"up": { "uv": [ 3, 3, 13, 13 ], "texture": "#leaves" },
"north": { "uv": [ 3, 3, 13, 13 ], "texture": "#leaves" },
"south": { "uv": [ 3, 3, 13, 13 ], "texture": "#leaves" },
"west": { "uv": [ 3, 3, 13, 13 ], "texture": "#leaves" },
"east": { "uv": [ 3, 3, 13, 13 ], "texture": "#leaves" }
}
},
{
"__comment": "Box1",
"from": [ 7, 0, 7 ],
"to": [ 9, 8, 9 ],
"faces": {
"up": { "uv": [ 7, 7, 9, 9 ], "texture": "#stem" },
"north": { "uv": [ 7, 8, 9, 16 ], "texture": "#stem" },
"south": { "uv": [ 7, 8, 9, 16 ], "texture": "#stem" },
"west": { "uv": [ 7, 8, 9, 16 ], "texture": "#stem" },
"east": { "uv": [ 7, 8, 9, 16 ], "texture": "#stem" }
}
}
]
}