This commit is contained in:
2022-09-15 19:17:32 -04:00
commit d8e39b9dc9
28 changed files with 1300 additions and 0 deletions
@@ -0,0 +1,20 @@
package me.parsell.dmBlock.Common;
import net.minecraft.block.Block;
import net.minecraft.block.BlockEntityProvider;
import net.minecraft.block.BlockState;
import net.minecraft.block.entity.BlockEntity;
import net.minecraft.util.math.BlockPos;
public class MultiBlockFacadeBlock extends Block implements BlockEntityProvider {
public MultiBlockFacadeBlock(Settings settings) {
super(settings);
}
@Override
public BlockEntity createBlockEntity(BlockPos pos, BlockState state) {
return new MultiBlockFacadeBlockEntity(pos, state);
}
}
@@ -0,0 +1,23 @@
package me.parsell.dmBlock.Common;
import me.parsell.dmBlock.dmBlock;
import net.minecraft.block.BlockState;
import net.minecraft.block.entity.BlockEntity;
import net.minecraft.nbt.NbtCompound;
import net.minecraft.util.math.BlockPos;
public class MultiBlockFacadeBlockEntity extends BlockEntity {
public MultiBlockFacadeBlockEntity(BlockPos pos, BlockState state) {
super(dmBlock.MULTIBLOCKFACADE_BLOCKENTITY, pos, state);
}
@Override
public void writeNbt(NbtCompound nbt) {
// Save the current value of the number to the nbt
//nbt.putInt("number", number);
super.writeNbt(nbt);
}
}
@@ -0,0 +1,37 @@
package me.parsell.dmBlock.Common;
import net.minecraft.client.MinecraftClient;
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;
public class MultiBlockFacadeBlockEntityRenderer implements BlockEntityRenderer<MultiBlockFacadeBlockEntity> {
private static ItemStack stack = new ItemStack(Items.JUKEBOX, 1);
public MultiBlockFacadeBlockEntityRenderer(BlockEntityRendererFactory.Context ctx) {
}
@Override
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);
matrices.pop();
}
}
@@ -0,0 +1,177 @@
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;
}
}
@@ -0,0 +1,206 @@
package me.parsell.dmBlock.Common;
import java.nio.FloatBuffer;
import java.util.Map;
import java.util.Set;
import org.lwjgl.system.MemoryUtil;
import net.minecraft.block.Block;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.Matrix3f;
import net.minecraft.util.math.Vec3i;
import net.minecraft.world.World;
public abstract class MultiBlockStructure {
public class MultiBlockInstance{
public Vec3i mutliBlockEntry;
public RotationDirection rotation;
public MultiBlockInstance(Vec3i entry, RotationDirection rotation){
mutliBlockEntry = entry;
this.rotation = rotation;
}
}
protected enum RotationDirection{
x0, x90, x180, x270,
y0, y90, y180, y270,
z0, z90, z180, z270
}
protected final RotationDirection[] ALL_ROTATION_DIRECTIONS = {RotationDirection.x0, RotationDirection.x90, RotationDirection.x180, RotationDirection.x270,
RotationDirection.y0, RotationDirection.y90, RotationDirection.y180, RotationDirection.y270,
RotationDirection.z0, RotationDirection.z90, RotationDirection.z180, RotationDirection.z270};
protected final RotationDirection[] NO_ROTATION_DIRECTIONS = {RotationDirection.x0, RotationDirection.y0, RotationDirection.z0};
protected final RotationDirection[] ALL_X_ROTATION_DIRECTONS = {RotationDirection.x0, RotationDirection.x90, RotationDirection.x180, RotationDirection.x270};
protected final RotationDirection[] ALL_Y_ROTATION_DIRECTONS = {RotationDirection.y0, RotationDirection.y90, RotationDirection.y180, RotationDirection.y270};
protected final RotationDirection[] ALL_Z_ROTATION_DIRECTONS = {RotationDirection.z0, RotationDirection.z90, RotationDirection.z180, RotationDirection.z270};
public abstract Map<Vec3i, Block> getStructure();
public abstract Set<RotationDirection> getValidRotationDirections();
public MultiBlockInstance verifyStructure(World world, BlockPos activation){
Map<Vec3i, Block> structureTemplate = getStructure();
for(Map.Entry<Vec3i, Block> startEntry: structureTemplate.entrySet()){ // Iterate through all blocks in the structure so we can determine where on the structure the player activated
if(world.getBlockState(activation).isOf(startEntry.getValue())){ // Ensure that the block we're checking is the block the player activated on
// Block in template is same the player activated on, this is our entry block for this formation check
Vec3i startPos = startEntry.getKey(); // Get the relative position in the structure
for(RotationDirection rotation : getValidRotationDirections()){ // Iterate through all possible rotations of the structure as well
boolean wasRotationVerified = true; // To determine if the structure can be formed given this entry block and this rotation
for(Map.Entry<Vec3i, Block> entry: structureTemplate.entrySet()){ // Iterate through all remaining blocks in the structure
if(entry.getKey().equals(startPos)) // if its one we already checked, skip
continue;
Vec3i offset = applyRotationMatrix(startPos, entry.getKey(), rotation); // Modify the relative position we are checking by the entry position's location
BlockPos checkPosition = activation.add(offset); // Offset the actual blockpos with the relative one, corrected for the entry blockpos
if(!(world.getBlockState(checkPosition).isOf(entry.getValue()))){ // Check block against structure block
wasRotationVerified = false; // If the block was not the block in the structure, then this rotation was impossible and continue to check other rotations
break;
}
}
if (wasRotationVerified){ // If one of the rotations passed, this means formation is possible
return new MultiBlockInstance(startPos, rotation);
}
}
}
}
return null; // No formation was possible
}
// This implements a 3d rotation matrix to modify our relative blockpos for the structure
public static Vec3i applyRotationMatrix(Vec3i origin, Vec3i destination, RotationDirection rotation){
FloatBuffer marcusFloats = MemoryUtil.memAllocFloat(9);
rotationToMatrix(rotation).writeColumnMajor(marcusFloats);
Vec3i rawOffset = destination.subtract(origin); // It's fucking raw
float x = (float)rawOffset.getX();
float y = (float)rawOffset.getY();
float z = (float)rawOffset.getZ();
Vec3i finalOffset = new Vec3i(x * marcusFloats.get(0) + y * marcusFloats.get(1) + z * marcusFloats.get(2),
x * marcusFloats.get(3) + y * marcusFloats.get(4) + z * marcusFloats.get(5),
x * marcusFloats.get(6) + y * marcusFloats.get(7) + z * marcusFloats.get(8)); //Cooked up with some crack
return finalOffset;
}
// This allows us to take human-readable rotations and convert it to the correct matrix
// This cannot be a HashMap or the likes due to Matrix3f not allowing intilization with data in a simple way, thanks mojang
public static Matrix3f rotationToMatrix(RotationDirection rotation){
Matrix3f rotMat = new Matrix3f();
switch(rotation) {
case x0:
case y0:
case z0:
rotMat.set(0, 0, 1);
rotMat.set(0, 1, 0);
rotMat.set(0, 2, 0);
rotMat.set(1, 0, 0);
rotMat.set(1, 1, 1);
rotMat.set(1, 2, 0);
rotMat.set(2, 0, 0);
rotMat.set(2, 1, 0);
rotMat.set(2, 2, 1);
return rotMat;
case x90:
rotMat.set(0, 0, 1);
rotMat.set(0, 1, 0);
rotMat.set(0, 2, 0);
rotMat.set(1, 0, 0);
rotMat.set(1, 1, 0);
rotMat.set(1, 2, -1);
rotMat.set(2, 0, 0);
rotMat.set(2, 1, 1);
rotMat.set(2, 2, 0);
return rotMat;
case x180:
rotMat.set(0, 0, 1);
rotMat.set(0, 1, 0);
rotMat.set(0, 2, 0);
rotMat.set(1, 0, 0);
rotMat.set(1, 1, -1);
rotMat.set(1, 2, 0);
rotMat.set(2, 0, 0);
rotMat.set(2, 1, 0);
rotMat.set(2, 2, -1);
return rotMat;
case x270:
rotMat.set(0, 0, 1);
rotMat.set(0, 1, 0);
rotMat.set(0, 2, 0);
rotMat.set(1, 0, 0);
rotMat.set(1, 1, 0);
rotMat.set(1, 2, 1);
rotMat.set(2, 0, 0);
rotMat.set(2, 1, -1);
rotMat.set(2, 2, 0);
return rotMat;
case y90:
rotMat.set(0, 0, 0);
rotMat.set(0, 1, 0);
rotMat.set(0, 2, 1);
rotMat.set(1, 0, 0);
rotMat.set(1, 1, 1);
rotMat.set(1, 2, 0);
rotMat.set(2, 0, -1);
rotMat.set(2, 1, 0);
rotMat.set(2, 2, 0);
return rotMat;
case y180:
rotMat.set(0, 0, -1);
rotMat.set(0, 1, 0);
rotMat.set(0, 2, 0);
rotMat.set(1, 0, 0);
rotMat.set(1, 1, 1);
rotMat.set(1, 2, 0);
rotMat.set(2, 0, 0);
rotMat.set(2, 1, 0);
rotMat.set(2, 2, -1);
return rotMat;
case y270:
rotMat.set(0, 0, -1);
rotMat.set(0, 1, 0);
rotMat.set(0, 2, 0);
rotMat.set(1, 0, 0);
rotMat.set(1, 1, 1);
rotMat.set(1, 2, 0);
rotMat.set(2, 0, 1);
rotMat.set(2, 1, 0);
rotMat.set(2, 2, 0);
return rotMat;
case z90:
rotMat.set(0, 0, 0);
rotMat.set(0, 1, -1);
rotMat.set(0, 2, 0);
rotMat.set(1, 0, 1);
rotMat.set(1, 1, 0);
rotMat.set(1, 2, 0);
rotMat.set(2, 0, 0);
rotMat.set(2, 1, 0);
rotMat.set(2, 2, 1);
return rotMat;
case z180:;
rotMat.set(0, 0, -1);
rotMat.set(0, 1, 0);
rotMat.set(0, 2, 0);
rotMat.set(1, 0, 0);
rotMat.set(1, 1, -1);
rotMat.set(1, 2, 0);
rotMat.set(2, 0, 0);
rotMat.set(2, 1, 0);
rotMat.set(2, 2, 1);
return rotMat;
case z270:
rotMat.set(0, 0, 0);
rotMat.set(0, 1, 1);
rotMat.set(0, 2, 0);
rotMat.set(1, 0, -1);
rotMat.set(1, 1, 0);
rotMat.set(1, 2, 0);
rotMat.set(2, 0, 0);
rotMat.set(2, 1, 0);
rotMat.set(2, 2, 1);
return rotMat;
default:
return null; // Something fucked up bad here, blame someone
}
}
}
@@ -0,0 +1,30 @@
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;
}
}
@@ -0,0 +1,27 @@
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;
}
}
}
@@ -0,0 +1,41 @@
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;
public class dmBlock implements ModInitializer {
// This logger is used to write text to the console and the log file.
// It is considered best practice to use your mod id as the logger's name.
// That way, it's clear which mod wrote info, warnings, and errors.
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);
}
}
@@ -0,0 +1,19 @@
package me.parsell.dmBlock;
import me.parsell.dmBlock.Core.MultiBlockAPIModelProvider;
import net.fabricmc.api.ClientModInitializer;
import net.fabricmc.api.EnvType;
import net.fabricmc.api.Environment;
import net.fabricmc.fabric.api.client.model.ModelLoadingRegistry;
@Environment(EnvType.CLIENT)
public class dmBlockClient implements ClientModInitializer {
@Override
public void onInitializeClient() {
ModelLoadingRegistry.INSTANCE.registerResourceProvider(rm -> new MultiBlockAPIModelProvider());
// BlockEntityRendererRegistry.register(ScratchMod.MULTIBLOCKFACADE_BLOCKENTITY,
// MultiBlockFacadeBlockEntityRenderer::new);
}
}
@@ -0,0 +1,16 @@
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!");
}
}
@@ -0,0 +1,5 @@
{
"variants": {
"" : { "model": "dmblock:block/multiblockfacade_block" }
}
}
Binary file not shown.

After

Width:  |  Height:  |  Size: 453 B

@@ -0,0 +1,6 @@
{
"parent": "block/cube_all",
"textures": {
"all": "dmblock:block/multiblockfacade_block"
}
}
@@ -0,0 +1,3 @@
{
"parent": "dmblock:block/multiblockfacade_block"
}
Binary file not shown.

After

Width:  |  Height:  |  Size: 247 B

+12
View File
@@ -0,0 +1,12 @@
{
"required": true,
"minVersion": "0.8",
"package": "me.parsell.MultiBlock.mixin",
"compatibilityLevel": "JAVA_17",
"mixins": [
],
"injectors": {
"defaultRequire": 1
}
}
+44
View File
@@ -0,0 +1,44 @@
{
"schemaVersion": 1,
"id": "dmblock",
"version": "0.0.1a",
"name": "dmBlock",
"description": "Dynamic Multiblock",
"authors": [
"Ganku",
"Pinyateh"
],
"contact": {
"homepage": "https://fabricmc.net/",
"sources": "https://github.com/FabricMC/fabric-example-mod"
},
"license": "CC0-1.0",
"icon": "assets/dmBlock/icon.png",
"environment": "*",
"entrypoints": {
"main": [
"me.parsell.dmBlock.dmBlock"
],
"client": [
{
"value": "me.parsell.dmBlock.dmBlockClient"
}
]
},
"mixins": [
"dmBlock.mixins.json"
],
"depends": {
"fabricloader": ">=0.14.6",
"fabric": "*",
"minecraft": "~1.19",
"java": ">=17"
},
"suggests": {
"another-mod": "*"
}
}