major overhaul and initial working version

This commit is contained in:
Justin Parsell 2022-10-07 20:27:22 -04:00
parent cf7f8e75dc
commit 6e478ef358
10 changed files with 94 additions and 307 deletions

View File

@ -1,20 +1,41 @@
package me.parsell.dmblock.Common;
import net.minecraft.block.Block;
import net.minecraft.block.BlockEntityProvider;
import java.util.Optional;
import me.parsell.dmblock.Core.dmBlocks;
import net.minecraft.block.BlockRenderType;
import net.minecraft.block.BlockState;
import net.minecraft.block.BlockWithEntity;
import net.minecraft.block.ShapeContext;
import net.minecraft.block.entity.BlockEntity;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.shape.VoxelShape;
import net.minecraft.util.shape.VoxelShapes;
import net.minecraft.world.BlockView;
public class MultiBlockFacadeBlock extends Block implements BlockEntityProvider {
public class MultiBlockFacadeBlock extends BlockWithEntity {
public MultiBlockFacadeBlock(Settings settings) {
super(settings);
super(settings.nonOpaque());
}
@Override
public BlockRenderType getRenderType(BlockState state) {
return BlockRenderType.INVISIBLE;
}
@Override
public VoxelShape getOutlineShape(BlockState state, BlockView world, BlockPos pos, ShapeContext context) {
Optional<MultiBlockFacadeBlockEntity> blockEntity = world.getBlockEntity(pos, dmBlocks.MULTIBLOCKFACADE_BLOCKENTITY);
if(blockEntity.isPresent())
return blockEntity.get().getReplacedBlockState().getOutlineShape(world, pos);
else
return VoxelShapes.fullCube();
}
@Override
public BlockEntity createBlockEntity(BlockPos pos, BlockState state) {
return new MultiBlockFacadeBlockEntity(pos, state);
}
}

View File

@ -1,23 +1,39 @@
package me.parsell.dmblock.Common;
import me.parsell.dmblock.dmBlock;
import me.parsell.dmblock.Core.dmBlocks;
import net.minecraft.block.BlockState;
import net.minecraft.block.Blocks;
import net.minecraft.block.entity.BlockEntity;
import net.minecraft.nbt.NbtCompound;
import net.minecraft.nbt.NbtHelper;
import net.minecraft.util.math.BlockPos;
public class MultiBlockFacadeBlockEntity extends BlockEntity {
BlockState replacedBlock = Blocks.OAK_FENCE.getDefaultState();
public MultiBlockFacadeBlockEntity(BlockPos pos, BlockState state) {
super(dmBlock.MULTIBLOCKFACADE_BLOCKENTITY, pos, state);
super(dmBlocks.MULTIBLOCKFACADE_BLOCKENTITY, pos, state);
}
public void setReplacedBlockState(BlockState state){
replacedBlock = state;
}
public BlockState getReplacedBlockState(){
return replacedBlock;
}
@Override
public void writeNbt(NbtCompound nbt) {
// Save the current value of the number to the nbt
//nbt.putInt("number", number);
nbt.put("replacedBlock", NbtHelper.fromBlockState(replacedBlock));
super.writeNbt(nbt);
}
@Override
public void readNbt(NbtCompound nbt) {
super.readNbt(nbt);
NbtCompound replacedBlockNbt = nbt.getCompound("replacedBlock");
replacedBlock = NbtHelper.toBlockState(replacedBlockNbt);
}
}

View File

@ -1,37 +1,22 @@
package me.parsell.dmblock.Common;
import me.parsell.dmblock.dmBlockClient;
import net.minecraft.client.MinecraftClient;
import net.minecraft.client.render.RenderLayers;
import net.minecraft.client.render.VertexConsumerProvider;
import net.minecraft.client.render.WorldRenderer;
import net.minecraft.client.render.block.entity.BlockEntityRenderer;
import net.minecraft.client.render.block.entity.BlockEntityRendererFactory;
import net.minecraft.client.render.model.json.ModelTransformation;
import net.minecraft.client.util.math.MatrixStack;
import net.minecraft.item.ItemStack;
import net.minecraft.item.Items;
import net.minecraft.util.math.Vec3f;
import net.minecraft.world.BlockRenderView;
public class MultiBlockFacadeBlockEntityRenderer implements BlockEntityRenderer<MultiBlockFacadeBlockEntity> {
public MultiBlockFacadeBlockEntityRenderer(BlockEntityRendererFactory.Context ctx) {}
private static ItemStack stack = new ItemStack(Items.JUKEBOX, 1);
public MultiBlockFacadeBlockEntityRenderer(BlockEntityRendererFactory.Context ctx) {
}
@SuppressWarnings({"resource"})
@Override
public void render(MultiBlockFacadeBlockEntity blockEntity, float tickDelta, MatrixStack matrices,
VertexConsumerProvider vertexConsumers, int light, int overlay) {
public void render(MultiBlockFacadeBlockEntity blockEntity, float tickDelta, MatrixStack matrices, VertexConsumerProvider vertexConsumers, int light, int overlay) {
matrices.push();
double offset = Math.sin((blockEntity.getWorld().getTime() + tickDelta) / 8.0) / 4.0;
matrices.translate(0.5, 1.25 + offset, 0.5);
matrices.multiply(Vec3f.POSITIVE_Y.getDegreesQuaternion((blockEntity.getWorld().getTime() + tickDelta) * 4));
int lightAbove = WorldRenderer.getLightmapCoordinates(blockEntity.getWorld(), blockEntity.getPos().up());
MinecraftClient.getInstance().getItemRenderer().renderItem(stack, ModelTransformation.Mode.GROUND, lightAbove,
overlay, matrices, vertexConsumers, 0);
MinecraftClient.getInstance().getBlockRenderManager().renderBlock(blockEntity.getReplacedBlockState(), blockEntity.getPos(), (BlockRenderView)MinecraftClient.getInstance().world, matrices, vertexConsumers.getBuffer(RenderLayers.getBlockLayer(blockEntity.getReplacedBlockState())), true, dmBlockClient.dmRandom);
matrices.pop();
}
}

View File

@ -1,177 +0,0 @@
package me.parsell.dmblock.Common;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
import java.util.Set;
import java.util.function.Function;
import java.util.function.Supplier;
import com.mojang.datafixers.util.Pair;
import me.parsell.dmblock.dmBlock;
import net.fabricmc.api.EnvType;
import net.fabricmc.api.Environment;
import net.fabricmc.fabric.api.renderer.v1.Renderer;
import net.fabricmc.fabric.api.renderer.v1.RendererAccess;
import net.fabricmc.fabric.api.renderer.v1.mesh.Mesh;
import net.fabricmc.fabric.api.renderer.v1.mesh.MeshBuilder;
import net.fabricmc.fabric.api.renderer.v1.mesh.MutableQuadView;
import net.fabricmc.fabric.api.renderer.v1.mesh.QuadEmitter;
import net.fabricmc.fabric.api.renderer.v1.model.FabricBakedModel;
import net.fabricmc.fabric.api.renderer.v1.render.RenderContext;
import net.minecraft.block.BlockState;
import net.minecraft.client.render.model.BakedModel;
import net.minecraft.client.render.model.BakedQuad;
import net.minecraft.client.render.model.ModelBakeSettings;
import net.minecraft.client.render.model.ModelLoader;
import net.minecraft.client.render.model.UnbakedModel;
import net.minecraft.client.render.model.json.JsonUnbakedModel;
import net.minecraft.client.render.model.json.ModelOverrideList;
import net.minecraft.client.render.model.json.ModelTransformation;
import net.minecraft.client.texture.Sprite;
import net.minecraft.client.util.SpriteIdentifier;
import net.minecraft.item.ItemStack;
import net.minecraft.screen.PlayerScreenHandler;
import net.minecraft.util.Identifier;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.Direction;
import net.minecraft.util.math.random.Random;
import net.minecraft.world.BlockRenderView;
@Environment(EnvType.CLIENT)
public class MultiBlockFacadeBlockModel implements UnbakedModel, BakedModel, FabricBakedModel {
private Mesh mesh;
private static final SpriteIdentifier[] SPRITE_IDS = new SpriteIdentifier[] {
new SpriteIdentifier(PlayerScreenHandler.BLOCK_ATLAS_TEXTURE, new Identifier("minecraft:block/stone")),
new SpriteIdentifier(PlayerScreenHandler.BLOCK_ATLAS_TEXTURE, new Identifier("minecraft:block/andesite")),
new SpriteIdentifier(PlayerScreenHandler.BLOCK_ATLAS_TEXTURE, new Identifier("minecraft:block/diorite"))
};
private Sprite[] SPRITES = new Sprite[3];
private static final Identifier DEFAULT_BLOCK_MODEL = new Identifier("minecraft:block/block");
private ModelTransformation transformation;
@Override
public boolean isVanillaAdapter() {
return false;
}
@Override
public void emitBlockQuads(BlockRenderView blockView, BlockState state, BlockPos pos,
Supplier<Random> randomSupplier, RenderContext context) {
QuadEmitter emitter = context.getEmitter();
int spriteIdx = ((pos.getX() % 3) + (pos.getY() % 3) + (pos.getZ() % 3)) % 3;
spriteIdx = (spriteIdx < 0) ? (spriteIdx + 3) : spriteIdx;
for (Direction direction : Direction.values()) {
// Add a new face to the mesh
emitter.square(direction, 0.0f, 0.0f, 1.0f, 1.0f, 0.0f);
// Set the sprite of the face, must be called after .square()
// We haven't specified any UV coordinates, so we want to use the whole texture.
// BAKE_LOCK_UV does exactly that.
emitter.spriteBake(0, SPRITES[spriteIdx], MutableQuadView.BAKE_LOCK_UV);
// Enable texture usage
emitter.spriteColor(0, -1, -1, -1, -1);
// Add the quad to the mesh
emitter.emit();
}
}
@Override
public void emitItemQuads(ItemStack stack, Supplier<Random> randomSupplier, RenderContext context) {
context.meshConsumer().accept(mesh);
}
@Override
public List<BakedQuad> getQuads(BlockState var1, Direction var2, Random var3) {
return Collections.emptyList();
}
@Override
public boolean useAmbientOcclusion() {
return true;
}
@Override
public boolean hasDepth() {
return false;
}
@Override
public boolean isSideLit() {
return true;
}
@Override
public boolean isBuiltin() {
return false;
}
@Override
public Sprite getParticleSprite() {
return SPRITES[1];
}
@Override
public ModelTransformation getTransformation() {
return transformation;
}
@Override
public ModelOverrideList getOverrides() {
return ModelOverrideList.EMPTY;
}
@Override
public Collection<Identifier> getModelDependencies() {
return Arrays.asList(DEFAULT_BLOCK_MODEL);
}
@Override
public Collection<SpriteIdentifier> getTextureDependencies(Function<Identifier, UnbakedModel> var1,
Set<Pair<String, String>> var2) {
return Arrays.asList(SPRITE_IDS);
}
@Override
public BakedModel bake(ModelLoader loader, Function<SpriteIdentifier, Sprite> textureGetter,
ModelBakeSettings rotationContainer,
Identifier modelId) {
dmBlock.LOGGER.info("Ran the model bake.");
JsonUnbakedModel defaultBlockModel = (JsonUnbakedModel) loader.getOrLoadModel(DEFAULT_BLOCK_MODEL);
transformation = defaultBlockModel.getTransformations();
// Get the sprites
for (int i = 0; i < 3; ++i) {
SPRITES[i] = textureGetter.apply(SPRITE_IDS[i]);
}
// Build the mesh using the Renderer API
Renderer renderer = RendererAccess.INSTANCE.getRenderer();
MeshBuilder builder = renderer.meshBuilder();
QuadEmitter emitter = builder.getEmitter();
for (Direction direction : Direction.values()) {
int spriteIdx = (direction == Direction.UP || direction == Direction.DOWN) ? 2 : ((direction == Direction.NORTH || direction == Direction.SOUTH) ? 1 : 0);
// Add a new face to the mesh
emitter.square(direction, 0.0f, 0.0f, 1.0f, 1.0f, 0.0f);
// Set the sprite of the face, must be called after .square()
// We haven't specified any UV coordinates, so we want to use the whole texture.
// BAKE_LOCK_UV does exactly that.
emitter.spriteBake(0, SPRITES[spriteIdx], MutableQuadView.BAKE_LOCK_UV);
// Enable texture usage
emitter.spriteColor(0, -1, -1, -1, -1);
// Add the quad to the mesh
emitter.emit();
}
mesh = builder.build();
return this;
}
}

View File

@ -1,30 +0,0 @@
package me.parsell.dmblock.Common;
import net.minecraft.block.Block;
import net.minecraft.block.BlockState;
import net.minecraft.block.entity.BlockEntity;
import net.minecraft.entity.player.PlayerEntity;
import net.minecraft.util.ActionResult;
import net.minecraft.util.Hand;
import net.minecraft.util.hit.BlockHitResult;
import net.minecraft.util.math.BlockPos;
import net.minecraft.world.World;
// TODO: Generate generic texture, generate blockentity that would take this over
public class MutliBlockBlock extends Block{
private BlockEntity pointerEntity;
public MutliBlockBlock(Settings settings) {
super(settings);
}
@Override
public ActionResult onUse(BlockState state, World world, BlockPos pos, PlayerEntity player, Hand hand, BlockHitResult hit){
return ActionResult.CONSUME;
// TODO: Needs to open BlockEntity that it's assigned
}
public void setMasterEntity(BlockEntity masterEntity){
pointerEntity = masterEntity;
}
}

View File

@ -1,27 +0,0 @@
package me.parsell.dmblock.Core;
import org.jetbrains.annotations.Nullable;
import me.parsell.dmblock.Common.MultiBlockFacadeBlockModel;
import net.fabricmc.fabric.api.client.model.ModelProviderContext;
import net.fabricmc.fabric.api.client.model.ModelProviderException;
import net.fabricmc.fabric.api.client.model.ModelResourceProvider;
import net.minecraft.client.render.model.UnbakedModel;
import net.minecraft.util.Identifier;
public class MultiBlockAPIModelProvider implements ModelResourceProvider {
public static final MultiBlockFacadeBlockModel MULTIBLOCKFACADE_BLOCK_MODEL = new MultiBlockFacadeBlockModel();
public static final Identifier MULTIBLOCKFACADE_BLOCK_MODEL_BLOCK = new Identifier("dmblock:block/multiblockfacade_block");
public static final Identifier MULTIBLOCKFACADE_BLOCK_MODEL_ITEM = new Identifier("dmblock:item/multiblockfacade_block");
@Override
public @Nullable UnbakedModel loadModelResource(Identifier identifier, ModelProviderContext context)
throws ModelProviderException {
if (identifier.equals(MULTIBLOCKFACADE_BLOCK_MODEL_BLOCK) || identifier.equals(MULTIBLOCKFACADE_BLOCK_MODEL_ITEM)) {
return MULTIBLOCKFACADE_BLOCK_MODEL;
} else {
return null;
}
}
}

View File

@ -0,0 +1,27 @@
package me.parsell.dmblock.Core;
import me.parsell.dmblock.dmBlock;
import me.parsell.dmblock.Common.MultiBlockFacadeBlock;
import me.parsell.dmblock.Common.MultiBlockFacadeBlockEntity;
import net.fabricmc.fabric.api.item.v1.FabricItemSettings;
import net.fabricmc.fabric.api.object.builder.v1.block.FabricBlockSettings;
import net.fabricmc.fabric.api.object.builder.v1.block.entity.FabricBlockEntityTypeBuilder;
import net.minecraft.block.Block;
import net.minecraft.block.Material;
import net.minecraft.block.entity.BlockEntityType;
import net.minecraft.item.BlockItem;
import net.minecraft.item.ItemGroup;
import net.minecraft.util.Identifier;
import net.minecraft.util.registry.Registry;
public class dmBlocks {
public static final Block MULTIBLOCKFACADE_BLOCK = new MultiBlockFacadeBlock(FabricBlockSettings.of(Material.METAL).strength(4.0f));
public static final BlockEntityType<MultiBlockFacadeBlockEntity> MULTIBLOCKFACADE_BLOCKENTITY = FabricBlockEntityTypeBuilder.create(MultiBlockFacadeBlockEntity::new, MULTIBLOCKFACADE_BLOCK).build();
public static void initialize(){
Registry.register(Registry.BLOCK, new Identifier(dmBlock.MODID, "multiblockfacade_block"), MULTIBLOCKFACADE_BLOCK);
Registry.register(Registry.ITEM, new Identifier(dmBlock.MODID, "multiblockfacade_block"), new BlockItem(MULTIBLOCKFACADE_BLOCK, new FabricItemSettings().group(ItemGroup.MISC)));
Registry.register(Registry.BLOCK_ENTITY_TYPE, new Identifier(dmBlock.MODID, "multiblockfacade_blockentity"), MULTIBLOCKFACADE_BLOCKENTITY);
}
}

View File

@ -1,22 +1,11 @@
package me.parsell.dmblock;
import net.fabricmc.api.ModInitializer;
import net.fabricmc.fabric.api.item.v1.FabricItemSettings;
import net.fabricmc.fabric.api.object.builder.v1.block.FabricBlockSettings;
import net.fabricmc.fabric.api.object.builder.v1.block.entity.FabricBlockEntityTypeBuilder;
import net.minecraft.block.Block;
import net.minecraft.block.Material;
import net.minecraft.block.entity.BlockEntityType;
import net.minecraft.item.BlockItem;
import net.minecraft.item.ItemGroup;
import net.minecraft.util.Identifier;
import net.minecraft.util.registry.Registry;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import me.parsell.dmblock.Common.MultiBlockFacadeBlock;
import me.parsell.dmblock.Common.MultiBlockFacadeBlockEntity;
import me.parsell.dmblock.Core.dmBlocks;
public class dmBlock implements ModInitializer {
// This logger is used to write text to the console and the log file.
@ -25,17 +14,13 @@ public class dmBlock implements ModInitializer {
public static final String MODID = "dmblock";
public static final Logger LOGGER = LoggerFactory.getLogger(MODID);
public static final Block MULTIBLOCKFACADE_BLOCK = new MultiBlockFacadeBlock(FabricBlockSettings.of(Material.METAL).strength(4.0f));
public static final BlockEntityType<MultiBlockFacadeBlockEntity> MULTIBLOCKFACADE_BLOCKENTITY = FabricBlockEntityTypeBuilder.create(MultiBlockFacadeBlockEntity::new, MULTIBLOCKFACADE_BLOCK).build();
@Override
public void onInitialize() {
// This code runs as soon as Minecraft is in a mod-load-ready state.
// However, some things (like resources) may still be uninitialized.
// Proceed with mild caution.
Registry.register(Registry.BLOCK, new Identifier(MODID, "multiblockfacade_block"), MULTIBLOCKFACADE_BLOCK);
Registry.register(Registry.ITEM, new Identifier(MODID, "multiblockfacade_block"), new BlockItem(MULTIBLOCKFACADE_BLOCK, new FabricItemSettings().group(ItemGroup.MISC)));
Registry.register(Registry.BLOCK_ENTITY_TYPE, new Identifier(MODID, "multiblockfacade_blockentity"), MULTIBLOCKFACADE_BLOCKENTITY);
dmBlocks.initialize();
}
}

View File

@ -1,19 +1,22 @@
package me.parsell.dmblock;
import me.parsell.dmblock.Core.MultiBlockAPIModelProvider;
import me.parsell.dmblock.Common.MultiBlockFacadeBlockEntityRenderer;
import me.parsell.dmblock.Core.dmBlocks;
import net.fabricmc.api.ClientModInitializer;
import net.fabricmc.api.EnvType;
import net.fabricmc.api.Environment;
import net.fabricmc.fabric.api.client.model.ModelLoadingRegistry;
import net.fabricmc.fabric.api.blockrenderlayer.v1.BlockRenderLayerMap;
import net.fabricmc.fabric.api.client.rendering.v1.BlockEntityRendererRegistry;
import net.minecraft.client.render.RenderLayer;
import net.minecraft.util.math.random.Random;
@Environment(EnvType.CLIENT)
public class dmBlockClient implements ClientModInitializer {
public static Random dmRandom = Random.create();
@Override
public void onInitializeClient() {
ModelLoadingRegistry.INSTANCE.registerResourceProvider(rm -> new MultiBlockAPIModelProvider());
// BlockEntityRendererRegistry.register(ScratchMod.MULTIBLOCKFACADE_BLOCKENTITY,
// MultiBlockFacadeBlockEntityRenderer::new);
BlockRenderLayerMap.INSTANCE.putBlock(dmBlocks.MULTIBLOCKFACADE_BLOCK, RenderLayer.getTranslucent());
BlockEntityRendererRegistry.register(dmBlocks.MULTIBLOCKFACADE_BLOCKENTITY, MultiBlockFacadeBlockEntityRenderer::new);
}
}

View File

@ -1,16 +0,0 @@
package me.parsell.dmblock.mixin;
import net.minecraft.client.gui.screen.TitleScreen;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
@Mixin(TitleScreen.class)
public class MultiBlockAPIMixin {
@Inject(at = @At("HEAD"), method = "init()V")
private void init(CallbackInfo info) {
// ScratchMod.LOGGER.info("This line is printed by an example mod mixin!");
}
}