diff --git a/src/main/java/ru/betterend/blocks/FlowerPotBlock.java b/src/main/java/ru/betterend/blocks/FlowerPotBlock.java index 95a190ea..c47fadf6 100644 --- a/src/main/java/ru/betterend/blocks/FlowerPotBlock.java +++ b/src/main/java/ru/betterend/blocks/FlowerPotBlock.java @@ -1,44 +1,68 @@ package ru.betterend.blocks; import com.google.common.collect.Lists; +import com.google.gson.JsonElement; +import com.google.gson.JsonObject; +import com.mojang.math.Matrix4f; +import com.mojang.math.Quaternion; +import com.mojang.math.Transformation; +import com.mojang.math.Vector3f; import net.fabricmc.api.EnvType; import net.fabricmc.api.Environment; import net.fabricmc.fabric.api.object.builder.v1.block.FabricBlockSettings; import net.minecraft.client.Minecraft; -import net.minecraft.client.resources.model.BakedModel; +import net.minecraft.client.renderer.block.model.MultiVariant; +import net.minecraft.client.renderer.block.model.Variant; import net.minecraft.client.resources.model.ModelResourceLocation; import net.minecraft.client.resources.model.UnbakedModel; +import net.minecraft.core.BlockPos; import net.minecraft.core.Registry; import net.minecraft.resources.ResourceLocation; +import net.minecraft.server.packs.resources.Resource; +import net.minecraft.server.packs.resources.ResourceManager; +import net.minecraft.util.Mth; +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.level.block.state.StateDefinition; import net.minecraft.world.level.block.state.properties.IntegerProperty; +import net.minecraft.world.phys.shapes.CollisionContext; +import net.minecraft.world.phys.shapes.VoxelShape; +import org.jetbrains.annotations.Nullable; import ru.bclib.blocks.BaseBlockNotFull; -import ru.bclib.client.models.BlockModelProvider; -import ru.betterend.client.models.MergedModel; +import ru.bclib.client.models.ModelsHelper; +import ru.bclib.client.models.ModelsHelper.MultiPartBuilder; +import ru.bclib.client.render.BCLRenderLayer; +import ru.bclib.interfaces.IRenderTyped; +import ru.bclib.util.JsonFactory; +import ru.bclib.util.MHelper; +import ru.betterend.BetterEnd; import ru.betterend.interfaces.PottablePlant; import ru.betterend.registry.EndBlocks; +import java.io.IOException; +import java.io.InputStream; +import java.io.InputStreamReader; import java.util.List; import java.util.Map; -public class FlowerPotBlock extends BaseBlockNotFull { +public class FlowerPotBlock extends BaseBlockNotFull implements IRenderTyped { + private static final VoxelShape SHAPE = Block.box(4, 4, 4, 12, 12, 12); private static final IntegerProperty PLANT_ID = EndBlockProperties.PLANT_ID; - private final Block[] blocks; + private final ResourceLocation[] blocks; @Environment(EnvType.CLIENT) private UnbakedModel source; public FlowerPotBlock(Block source) { super(FabricBlockSettings.copyOf(source)); - List blocks = Lists.newArrayList(); + List blocks = Lists.newArrayList(); EndBlocks.getModBlocks().forEach(block -> { - if (block instanceof PottablePlant) { - blocks.add(block); + if (block instanceof PottablePlant && block.getStateDefinition().getProperties().isEmpty()) { + blocks.add(Registry.BLOCK.getKey(block)); } }); - this.blocks = blocks.toArray(new Block[] {}); + this.blocks = blocks.toArray(new ResourceLocation[] {}); } @Override @@ -50,27 +74,56 @@ public class FlowerPotBlock extends BaseBlockNotFull { @Override @Environment(EnvType.CLIENT) public UnbakedModel getModelVariant(ResourceLocation stateId, BlockState blockState, Map modelCache) { - int id = blockState.getValue(PLANT_ID); - if (id == 0 || id > blocks.length) { - if (id == 0) { - source = super.getModelVariant(stateId, blockState, modelCache); + ModelResourceLocation key = new ModelResourceLocation(stateId.getNamespace(), stateId.getPath(), "plant_age=0"); + + if (modelCache.containsKey(key)) { + return modelCache.get(key); + } + + MultiPartBuilder model = MultiPartBuilder.create(stateDefinition); + model.part(new ResourceLocation("block/flower_pot")).add(); + Transformation offset = new Transformation(new Vector3f(0, 0.5F, 0), null, null, null); + for (int i = 0; i < blocks.length; i++) { + final int compareID = i + 1; + ResourceLocation modelPath = blocks[i]; + ResourceLocation objSource = new ResourceLocation(modelPath.getNamespace(), "block/potted_" + modelPath.getPath() + ".json"); + if (Minecraft.getInstance().getResourceManager().hasResource(objSource)) { + objSource = new ResourceLocation(modelPath.getNamespace(), "block/potted_" + modelPath.getPath()); + model.part(objSource).setTransformation(offset).setCondition(state -> state.getValue(PLANT_ID) == compareID).add(); + continue; + } + objSource = new ResourceLocation(modelPath.getNamespace(), "blockstates/" + modelPath.getPath() + ".json"); + JsonObject obj = JsonFactory.getJsonObject(objSource); + if (obj != null) { + JsonElement variants = obj.get("variants").getAsJsonObject().get(""); + String path = null; + if (variants.isJsonArray()) { + path = variants.getAsJsonArray().get(0).getAsJsonObject().get("model").getAsString(); + } + else { + path = variants.getAsJsonObject().get("model").getAsString(); + } + model.part(new ResourceLocation(path)).setTransformation(offset).setCondition(state -> state.getValue(PLANT_ID) == compareID).add(); } - return source; } - registerModel(stateId, blockState, modelCache); - MergedModel model = new MergedModel(blockState, source); - Block plant = blocks[id - 1]; - if (plant instanceof BlockModelProvider) { - ResourceLocation location = Registry.BLOCK.getKey(plant); - //model.addModel(((BlockModelProvider) plant).getBlockModel(location, plant.defaultBlockState())); - model = new MergedModel(blockState, ((BlockModelProvider) plant).getBlockModel(location, plant.defaultBlockState())); - System.out.println("Plant " + id + " is instance!"); - } - return model; + + UnbakedModel result = model.build(); + modelCache.put(key, result); + return result; } - private void registerModel(ResourceLocation stateId, BlockState blockState, Map modelCache) { - ResourceLocation modelId = new ResourceLocation(stateId.getNamespace(), "block/" + stateId.getPath()); - registerBlockModel(stateId, modelId, blockState, modelCache); + @Override + public VoxelShape getShape(BlockState state, BlockGetter view, BlockPos pos, CollisionContext ePos) { + return SHAPE; + } + + @Override + public VoxelShape getCollisionShape(BlockState state, BlockGetter view, BlockPos pos, CollisionContext ePos) { + return SHAPE; + } + + @Override + public BCLRenderLayer getRenderLayer() { + return BCLRenderLayer.CUTOUT; } } diff --git a/src/main/java/ru/betterend/client/models/MergedModel.java b/src/main/java/ru/betterend/client/models/MergedModel.java deleted file mode 100644 index 36ccdf28..00000000 --- a/src/main/java/ru/betterend/client/models/MergedModel.java +++ /dev/null @@ -1,87 +0,0 @@ -package ru.betterend.client.models; - -import com.google.common.collect.Lists; -import com.google.common.collect.Maps; -import com.google.common.collect.Sets; -import com.mojang.datafixers.util.Pair; -import net.minecraft.client.renderer.block.model.BakedQuad; -import net.minecraft.client.renderer.texture.TextureAtlasSprite; -import net.minecraft.client.resources.model.BakedModel; -import net.minecraft.client.resources.model.Material; -import net.minecraft.client.resources.model.ModelBakery; -import net.minecraft.client.resources.model.ModelState; -import net.minecraft.client.resources.model.SimpleBakedModel; -import net.minecraft.client.resources.model.UnbakedModel; -import net.minecraft.core.Direction; -import net.minecraft.resources.ResourceLocation; -import net.minecraft.world.level.block.state.BlockState; -import org.jetbrains.annotations.Nullable; -import ru.bclib.util.BlocksHelper; - -import java.util.Collection; -import java.util.List; -import java.util.Map; -import java.util.Random; -import java.util.Set; -import java.util.function.Function; - -public class MergedModel implements UnbakedModel { - private final List models = Lists.newArrayList(); - private final UnbakedModel source; - private final BlockState state; - - public MergedModel(BlockState state, UnbakedModel source) { - this.source = source; - this.state = state; - } - - public void addModel(UnbakedModel model) { - models.add(model); - } - - @Override - public Collection getDependencies() { - Set dependencies = Sets.newHashSet(); - dependencies.addAll(source.getDependencies()); - models.forEach(model -> dependencies.addAll(model.getDependencies())); - return dependencies; - } - - @Override - public Collection getMaterials(Function function, Set> set) { - Set material = Sets.newHashSet(); - material.addAll(source.getMaterials(function, set)); - models.forEach(model -> material.addAll(model.getMaterials(function, set))); - return material; - } - - @Nullable - @Override - public BakedModel bake(ModelBakery modelBakery, Function function, ModelState modelState, ResourceLocation resourceLocation) { - Random random = new Random(resourceLocation.toString().hashCode()); - BakedModel baked = source.bake(modelBakery, function, modelState, resourceLocation); - Map> map = makeMap(); - List quads = Lists.newArrayList(); - processModel(baked, map, quads, random); - models.forEach(model -> { - BakedModel baked2 = source.bake(modelBakery, function, modelState, resourceLocation); - processModel(baked2, map, quads, random); - }); - return new SimpleBakedModel(quads, map, baked.useAmbientOcclusion(), baked.usesBlockLight(), baked.isGui3d(), baked.getParticleIcon(), baked.getTransforms(), baked.getOverrides()); - } - - private Map> makeMap() { - Map> map = Maps.newEnumMap(Direction.class); - for (Direction dir : BlocksHelper.DIRECTIONS) { - map.put(dir, Lists.newArrayList()); - } - return map; - } - - private void processModel(BakedModel model, Map> map, List quads, Random random) { - for (Direction dir : BlocksHelper.DIRECTIONS) { - map.get(dir).addAll(model.getQuads(state, dir, random)); - } - quads.addAll(model.getQuads(state, null, random)); - } -}