Pot prototype (WIP)
This commit is contained in:
parent
4040597a6d
commit
287e25bbcf
2 changed files with 80 additions and 114 deletions
|
@ -1,44 +1,68 @@
|
||||||
package ru.betterend.blocks;
|
package ru.betterend.blocks;
|
||||||
|
|
||||||
import com.google.common.collect.Lists;
|
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.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.minecraft.client.Minecraft;
|
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.ModelResourceLocation;
|
||||||
import net.minecraft.client.resources.model.UnbakedModel;
|
import net.minecraft.client.resources.model.UnbakedModel;
|
||||||
|
import net.minecraft.core.BlockPos;
|
||||||
import net.minecraft.core.Registry;
|
import net.minecraft.core.Registry;
|
||||||
import net.minecraft.resources.ResourceLocation;
|
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.Block;
|
||||||
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;
|
||||||
|
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.blocks.BaseBlockNotFull;
|
||||||
import ru.bclib.client.models.BlockModelProvider;
|
import ru.bclib.client.models.ModelsHelper;
|
||||||
import ru.betterend.client.models.MergedModel;
|
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.interfaces.PottablePlant;
|
||||||
import ru.betterend.registry.EndBlocks;
|
import ru.betterend.registry.EndBlocks;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.InputStream;
|
||||||
|
import java.io.InputStreamReader;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
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 static final IntegerProperty PLANT_ID = EndBlockProperties.PLANT_ID;
|
||||||
private final Block[] blocks;
|
private final ResourceLocation[] blocks;
|
||||||
|
|
||||||
@Environment(EnvType.CLIENT)
|
@Environment(EnvType.CLIENT)
|
||||||
private UnbakedModel source;
|
private UnbakedModel source;
|
||||||
|
|
||||||
public FlowerPotBlock(Block source) {
|
public FlowerPotBlock(Block source) {
|
||||||
super(FabricBlockSettings.copyOf(source));
|
super(FabricBlockSettings.copyOf(source));
|
||||||
List<Block> blocks = Lists.newArrayList();
|
List<ResourceLocation> blocks = Lists.newArrayList();
|
||||||
EndBlocks.getModBlocks().forEach(block -> {
|
EndBlocks.getModBlocks().forEach(block -> {
|
||||||
if (block instanceof PottablePlant) {
|
if (block instanceof PottablePlant && block.getStateDefinition().getProperties().isEmpty()) {
|
||||||
blocks.add(block);
|
blocks.add(Registry.BLOCK.getKey(block));
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
this.blocks = blocks.toArray(new Block[] {});
|
this.blocks = blocks.toArray(new ResourceLocation[] {});
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -50,27 +74,56 @@ public class FlowerPotBlock extends BaseBlockNotFull {
|
||||||
@Override
|
@Override
|
||||||
@Environment(EnvType.CLIENT)
|
@Environment(EnvType.CLIENT)
|
||||||
public UnbakedModel getModelVariant(ResourceLocation stateId, BlockState blockState, Map<ResourceLocation, UnbakedModel> modelCache) {
|
public UnbakedModel getModelVariant(ResourceLocation stateId, BlockState blockState, Map<ResourceLocation, UnbakedModel> modelCache) {
|
||||||
int id = blockState.getValue(PLANT_ID);
|
ModelResourceLocation key = new ModelResourceLocation(stateId.getNamespace(), stateId.getPath(), "plant_age=0");
|
||||||
if (id == 0 || id > blocks.length) {
|
|
||||||
if (id == 0) {
|
if (modelCache.containsKey(key)) {
|
||||||
source = super.getModelVariant(stateId, blockState, modelCache);
|
return modelCache.get(key);
|
||||||
}
|
|
||||||
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;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void registerModel(ResourceLocation stateId, BlockState blockState, Map<ResourceLocation, UnbakedModel> modelCache) {
|
MultiPartBuilder model = MultiPartBuilder.create(stateDefinition);
|
||||||
ResourceLocation modelId = new ResourceLocation(stateId.getNamespace(), "block/" + stateId.getPath());
|
model.part(new ResourceLocation("block/flower_pot")).add();
|
||||||
registerBlockModel(stateId, modelId, blockState, modelCache);
|
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();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
UnbakedModel result = model.build();
|
||||||
|
modelCache.put(key, result);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
@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;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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<UnbakedModel> 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<ResourceLocation> getDependencies() {
|
|
||||||
Set<ResourceLocation> dependencies = Sets.newHashSet();
|
|
||||||
dependencies.addAll(source.getDependencies());
|
|
||||||
models.forEach(model -> dependencies.addAll(model.getDependencies()));
|
|
||||||
return dependencies;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Collection<Material> getMaterials(Function<ResourceLocation, UnbakedModel> function, Set<Pair<String, String>> set) {
|
|
||||||
Set<Material> 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<Material, TextureAtlasSprite> function, ModelState modelState, ResourceLocation resourceLocation) {
|
|
||||||
Random random = new Random(resourceLocation.toString().hashCode());
|
|
||||||
BakedModel baked = source.bake(modelBakery, function, modelState, resourceLocation);
|
|
||||||
Map<Direction, List<BakedQuad>> map = makeMap();
|
|
||||||
List<BakedQuad> 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<Direction, List<BakedQuad>> makeMap() {
|
|
||||||
Map<Direction, List<BakedQuad>> map = Maps.newEnumMap(Direction.class);
|
|
||||||
for (Direction dir : BlocksHelper.DIRECTIONS) {
|
|
||||||
map.put(dir, Lists.newArrayList());
|
|
||||||
}
|
|
||||||
return map;
|
|
||||||
}
|
|
||||||
|
|
||||||
private void processModel(BakedModel model, Map<Direction, List<BakedQuad>> map, List<BakedQuad> quads, Random random) {
|
|
||||||
for (Direction dir : BlocksHelper.DIRECTIONS) {
|
|
||||||
map.get(dir).addAll(model.getQuads(state, dir, random));
|
|
||||||
}
|
|
||||||
quads.addAll(model.getQuads(state, null, random));
|
|
||||||
}
|
|
||||||
}
|
|
Loading…
Add table
Add a link
Reference in a new issue