Probably overzealous formatting commit

This commit is contained in:
quat1024 2023-06-15 01:59:48 -04:00
parent 735e79ea78
commit 5b369ab95e
18 changed files with 693 additions and 685 deletions

View File

@ -6,35 +6,38 @@ import net.fabricmc.api.ModInitializer;
import net.minecraft.block.Block; import net.minecraft.block.Block;
import net.minecraft.block.entity.BlockEntity; import net.minecraft.block.entity.BlockEntity;
import net.minecraft.block.entity.BlockEntityType; import net.minecraft.block.entity.BlockEntityType;
import net.minecraft.item.*; import net.minecraft.item.BlockItem;
import net.minecraft.item.Item;
import net.minecraft.item.ItemGroup;
import net.minecraft.util.Identifier; import net.minecraft.util.Identifier;
import net.minecraft.util.registry.Registry; import net.minecraft.util.registry.Registry;
import java.util.function.Supplier; import java.util.function.Supplier;
public class Templates implements ModInitializer { public class Templates implements ModInitializer {
public static final String MODID = "templates"; public static final String MODID = "templates";
public static final Block SLOPE = register("slope", new SlopeBlock(), ItemGroup.DECORATIONS); public static final Block SLOPE = register("slope", new SlopeBlock(), ItemGroup.DECORATIONS);
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
public static final BlockEntityType<SlopeEntity> SLOPE_ENTITY = register("slope", SlopeEntity::new, SLOPE); public static final BlockEntityType<SlopeEntity> SLOPE_ENTITY = register("slope", SlopeEntity::new, SLOPE);
@Override @Override
public void onInitialize() { public void onInitialize() {
} }
public static Block register(String name, Block block, ItemGroup tab) { public static Block register(String name, Block block, ItemGroup tab) {
Registry.register(Registry.BLOCK, new Identifier(MODID, name), block); Registry.register(Registry.BLOCK, new Identifier(MODID, name), block);
BlockItem item = new BlockItem(block, new Item.Settings().group(tab)); BlockItem item = new BlockItem(block, new Item.Settings().group(tab));
register(name, item); register(name, item);
return block; return block;
} }
@SuppressWarnings("rawtypes") @SuppressWarnings("rawtypes")
public static BlockEntityType register(String name, Supplier<BlockEntity> be, Block...blocks) { public static BlockEntityType register(String name, Supplier<BlockEntity> be, Block... blocks) {
return Registry.register(Registry.BLOCK_ENTITY, new Identifier(MODID, name), BlockEntityType.Builder.create(be, blocks).build(null)); return Registry.register(Registry.BLOCK_ENTITY, new Identifier(MODID, name), BlockEntityType.Builder.create(be, blocks).build(null));
} }
public static Item register(String name, Item item) { public static Item register(String name, Item item) {
Registry.register(Registry.ITEM, new Identifier(MODID, name), item); Registry.register(Registry.ITEM, new Identifier(MODID, name), item);
return item; return item;

View File

@ -9,9 +9,10 @@ import net.minecraft.util.math.Direction;
public class TemplatesClient implements ClientModInitializer { public class TemplatesClient implements ClientModInitializer {
public static TemplateModelVariantProvider provider = new TemplateModelVariantProvider(); public static TemplateModelVariantProvider provider = new TemplateModelVariantProvider();
@Override @Override
public void onInitializeClient() { public void onInitializeClient() {
ModelLoadingRegistry.INSTANCE.registerVariantProvider(rm -> provider); ModelLoadingRegistry.INSTANCE.registerVariantProvider(rm -> provider);
provider.registerTemplateModels(Templates.SLOPE, Templates.SLOPE.getDefaultState().with(SlopeBlock.FACING, Direction.SOUTH), SlopeModel::new); provider.registerTemplateModels(Templates.SLOPE, Templates.SLOPE.getDefaultState().with(SlopeBlock.FACING, Direction.SOUTH), SlopeModel::new);
} }
} }

View File

@ -2,10 +2,12 @@ package io.github.cottonmc.templates.block;
import io.github.cottonmc.templates.block.entity.SlopeEntity; import io.github.cottonmc.templates.block.entity.SlopeEntity;
import net.fabricmc.fabric.api.object.builder.v1.block.FabricBlockSettings; import net.fabricmc.fabric.api.object.builder.v1.block.FabricBlockSettings;
import net.minecraft.block.*; import net.minecraft.block.Block;
import net.minecraft.block.BlockState;
import net.minecraft.block.Material;
import net.minecraft.block.entity.BlockEntity; import net.minecraft.block.entity.BlockEntity;
import net.minecraft.entity.EntityContext; import net.minecraft.entity.EntityContext;
import net.minecraft.item.*; import net.minecraft.item.ItemPlacementContext;
import net.minecraft.state.StateManager; import net.minecraft.state.StateManager;
import net.minecraft.state.property.DirectionProperty; import net.minecraft.state.property.DirectionProperty;
import net.minecraft.state.property.Properties; import net.minecraft.state.property.Properties;
@ -19,35 +21,35 @@ import javax.annotation.Nullable;
public class SlopeBlock extends TemplateBlock { public class SlopeBlock extends TemplateBlock {
public static final DirectionProperty FACING = Properties.HORIZONTAL_FACING; public static final DirectionProperty FACING = Properties.HORIZONTAL_FACING;
public static final VoxelShape BASE = VoxelShapes.cuboid(0f, 0f, 0f, 1f, 0.5f, 1f); public static final VoxelShape BASE = VoxelShapes.cuboid(0f, 0f, 0f, 1f, 0.5f, 1f);
public static final VoxelShape NORTH = VoxelShapes.cuboid(0f, 0.5f, 0f, 1f, 1f, 0.5f); public static final VoxelShape NORTH = VoxelShapes.cuboid(0f, 0.5f, 0f, 1f, 1f, 0.5f);
public static final VoxelShape SOUTH = VoxelShapes.cuboid(0f, 0.5f, 0.5f, 1f, 1f, 1f); public static final VoxelShape SOUTH = VoxelShapes.cuboid(0f, 0.5f, 0.5f, 1f, 1f, 1f);
public static final VoxelShape EAST = VoxelShapes.cuboid(0.5f, 0.5f, 0f, 1f, 1f, 1f); public static final VoxelShape EAST = VoxelShapes.cuboid(0.5f, 0.5f, 0f, 1f, 1f, 1f);
public static final VoxelShape WEST = VoxelShapes.cuboid(0f, 0.5f, 0f, 0.5f, 1f, 1f); public static final VoxelShape WEST = VoxelShapes.cuboid(0f, 0.5f, 0f, 0.5f, 1f, 1f);
public SlopeBlock() { public SlopeBlock() {
super(FabricBlockSettings.of(Material.WOOD)); super(FabricBlockSettings.of(Material.WOOD));
this.setDefaultState(this.getStateManager().getDefaultState().with(FACING, Direction.NORTH).with(LIGHT, 0).with(REDSTONE, false)); this.setDefaultState(this.getStateManager().getDefaultState().with(FACING, Direction.NORTH).with(LIGHT, 0).with(REDSTONE, false));
} }
@Override @Override
protected void appendProperties(StateManager.Builder<Block, BlockState> builder) { protected void appendProperties(StateManager.Builder<Block, BlockState> builder) {
builder.add(FACING, LIGHT, REDSTONE); builder.add(FACING, LIGHT, REDSTONE);
} }
@Nullable @Nullable
@Override @Override
public BlockEntity createBlockEntity(BlockView blockView) { public BlockEntity createBlockEntity(BlockView blockView) {
return new SlopeEntity(); return new SlopeEntity();
} }
@Nullable @Nullable
@Override @Override
public BlockState getPlacementState(ItemPlacementContext ctx) { public BlockState getPlacementState(ItemPlacementContext ctx) {
return getDefaultState().with(FACING, ctx.getPlayerFacing()); return getDefaultState().with(FACING, ctx.getPlayerFacing());
} }
@Override @Override
public VoxelShape getCollisionShape(BlockState state, BlockView view, BlockPos pos, EntityContext ctx) { public VoxelShape getCollisionShape(BlockState state, BlockView view, BlockPos pos, EntityContext ctx) {
Direction dir = state.get(FACING); Direction dir = state.get(FACING);
@ -64,7 +66,7 @@ public class SlopeBlock extends TemplateBlock {
return VoxelShapes.fullCube(); return VoxelShapes.fullCube();
} }
} }
@Override @Override
public VoxelShape getOutlineShape(BlockState state, BlockView view, BlockPos pos, EntityContext ctx) { public VoxelShape getOutlineShape(BlockState state, BlockView view, BlockPos pos, EntityContext ctx) {
return getCollisionShape(state, view, pos, ctx); return getCollisionShape(state, view, pos, ctx);

View File

@ -10,7 +10,11 @@ import net.minecraft.block.Blocks;
import net.minecraft.block.entity.BlockEntity; import net.minecraft.block.entity.BlockEntity;
import net.minecraft.entity.ItemEntity; import net.minecraft.entity.ItemEntity;
import net.minecraft.entity.player.PlayerEntity; import net.minecraft.entity.player.PlayerEntity;
import net.minecraft.item.*; import net.minecraft.item.BlockItem;
import net.minecraft.item.ItemPlacementContext;
import net.minecraft.item.ItemStack;
import net.minecraft.item.ItemUsageContext;
import net.minecraft.item.Items;
import net.minecraft.state.property.BooleanProperty; import net.minecraft.state.property.BooleanProperty;
import net.minecraft.state.property.IntProperty; import net.minecraft.state.property.IntProperty;
import net.minecraft.util.Hand; import net.minecraft.util.Hand;
@ -23,64 +27,64 @@ import net.minecraft.world.World;
public abstract class TemplateBlock extends Block implements BlockEntityProvider, StateContainer { public abstract class TemplateBlock extends Block implements BlockEntityProvider, StateContainer {
public static final IntProperty LIGHT = IntProperty.of("light", 0, 15); public static final IntProperty LIGHT = IntProperty.of("light", 0, 15);
public static final BooleanProperty REDSTONE = BooleanProperty.of("redstone"); public static final BooleanProperty REDSTONE = BooleanProperty.of("redstone");
public TemplateBlock(Settings settings) { public TemplateBlock(Settings settings) {
super(settings); super(settings);
} }
@Override @Override
public boolean activate(BlockState state, World world, BlockPos pos, PlayerEntity player, Hand hand, BlockHitResult hit) { public boolean activate(BlockState state, World world, BlockPos pos, PlayerEntity player, Hand hand, BlockHitResult hit) {
if (world.isClient || !(world.getBlockEntity(pos) instanceof TemplateEntity)) return true; if(world.isClient || !(world.getBlockEntity(pos) instanceof TemplateEntity)) return true;
TemplateEntity be = (TemplateEntity) world.getBlockEntity(pos); TemplateEntity be = (TemplateEntity) world.getBlockEntity(pos);
ItemStack stack = player.getStackInHand(hand); ItemStack stack = player.getStackInHand(hand);
if (stack.getItem() instanceof BlockItem) { if(stack.getItem() instanceof BlockItem) {
Block block = ((BlockItem)stack.getItem()).getBlock(); Block block = ((BlockItem) stack.getItem()).getBlock();
if (block == Blocks.REDSTONE_TORCH) { if(block == Blocks.REDSTONE_TORCH) {
be.addRedstone(); be.addRedstone();
if (!player.abilities.creativeMode) stack.decrement(1); if(!player.abilities.creativeMode) stack.decrement(1);
} }
ItemPlacementContext ctx = new ItemPlacementContext(new ItemUsageContext(player, hand, hit)); ItemPlacementContext ctx = new ItemPlacementContext(new ItemUsageContext(player, hand, hit));
BlockState placementState = block.getPlacementState(ctx); BlockState placementState = block.getPlacementState(ctx);
if (Block.isShapeFullCube(placementState.getCollisionShape(world, pos)) && !(block instanceof BlockEntityProvider)) { if(Block.isShapeFullCube(placementState.getCollisionShape(world, pos)) && !(block instanceof BlockEntityProvider)) {
if (be.getRenderedState().getBlock() == Blocks.AIR) { if(be.getRenderedState().getBlock() == Blocks.AIR) {
be.setRenderedState(placementState); be.setRenderedState(placementState);
if (!player.abilities.creativeMode) stack.decrement(1); if(!player.abilities.creativeMode) stack.decrement(1);
} }
} }
} else if (stack.getItem() == Items.GLOWSTONE_DUST) { } else if(stack.getItem() == Items.GLOWSTONE_DUST) {
be.addGlowstone(); be.addGlowstone();
if (!player.abilities.creativeMode) stack.decrement(1); if(!player.abilities.creativeMode) stack.decrement(1);
} }
return true; return true;
} }
@Override @Override
public boolean isOpaque(BlockState state) { public boolean isOpaque(BlockState state) {
return false; return false;
} }
@Override @Override
public boolean isSimpleFullBlock(BlockState state, BlockView view, BlockPos pos) { public boolean isSimpleFullBlock(BlockState state, BlockView view, BlockPos pos) {
return false; return false;
} }
@Override @Override
public void onBlockRemoved(BlockState state, World world, BlockPos pos, BlockState newState, boolean bool) { public void onBlockRemoved(BlockState state, World world, BlockPos pos, BlockState newState, boolean bool) {
if (newState.getBlock() == Templates.SLOPE) return; if(newState.getBlock() == Templates.SLOPE) return;
BlockEntity be = world.getBlockEntity(pos); BlockEntity be = world.getBlockEntity(pos);
if (be instanceof TemplateEntity) { if(be instanceof TemplateEntity) {
TemplateEntity template = (TemplateEntity)be; TemplateEntity template = (TemplateEntity) be;
if (template.getRenderedState().getBlock() != Blocks.AIR) { if(template.getRenderedState().getBlock() != Blocks.AIR) {
ItemStack stack = new ItemStack(template.getRenderedState().getBlock()); ItemStack stack = new ItemStack(template.getRenderedState().getBlock());
ItemEntity entity = new ItemEntity(world, pos.getX(), pos.getY(), pos.getZ(), stack); ItemEntity entity = new ItemEntity(world, pos.getX(), pos.getY(), pos.getZ(), stack);
world.spawnEntity(entity); world.spawnEntity(entity);
} }
if (template.hasRedstone()) { if(template.hasRedstone()) {
ItemStack stack = new ItemStack(Items.REDSTONE_TORCH); ItemStack stack = new ItemStack(Items.REDSTONE_TORCH);
ItemEntity entity = new ItemEntity(world, pos.getX(), pos.getY(), pos.getZ(), stack); ItemEntity entity = new ItemEntity(world, pos.getX(), pos.getY(), pos.getZ(), stack);
world.spawnEntity(entity); world.spawnEntity(entity);
} }
if (template.hasGlowstone()) { if(template.hasGlowstone()) {
ItemStack stack = new ItemStack(Items.GLOWSTONE_DUST); ItemStack stack = new ItemStack(Items.GLOWSTONE_DUST);
ItemEntity entity = new ItemEntity(world, pos.getX(), pos.getY(), pos.getZ(), stack); ItemEntity entity = new ItemEntity(world, pos.getX(), pos.getY(), pos.getZ(), stack);
world.spawnEntity(entity); world.spawnEntity(entity);
@ -88,61 +92,61 @@ public abstract class TemplateBlock extends Block implements BlockEntityProvider
} }
super.onBlockRemoved(state, world, pos, newState, bool); super.onBlockRemoved(state, world, pos, newState, bool);
} }
@Override @Override
public void neighborUpdate(BlockState state, World world, BlockPos pos, Block block, BlockPos posFrom, boolean bool) { public void neighborUpdate(BlockState state, World world, BlockPos pos, Block block, BlockPos posFrom, boolean bool) {
BlockEntity be = world.getBlockEntity(pos); BlockEntity be = world.getBlockEntity(pos);
if (be instanceof TemplateEntity) { if(be instanceof TemplateEntity) {
TemplateEntity template = (TemplateEntity)be; TemplateEntity template = (TemplateEntity) be;
BlockState beState = template.getRenderedState(); BlockState beState = template.getRenderedState();
world.setBlockState(pos, state.with(LIGHT, template.hasGlowstone()? 15 : beState.getLuminance()).with(REDSTONE, template.hasRedstone() || beState.emitsRedstonePower())); world.setBlockState(pos, state.with(LIGHT, template.hasGlowstone() ? 15 : beState.getLuminance()).with(REDSTONE, template.hasRedstone() || beState.emitsRedstonePower()));
} }
} }
@Override @Override
public int getLuminance(BlockState state) { public int getLuminance(BlockState state) {
return state.get(LIGHT); return state.get(LIGHT);
} }
@Override @Override
public boolean emitsRedstonePower(BlockState state) { public boolean emitsRedstonePower(BlockState state) {
return state.get(REDSTONE); return state.get(REDSTONE);
} }
@Override @Override
public int getWeakRedstonePower(BlockState state, BlockView view, BlockPos pos, Direction dir) { public int getWeakRedstonePower(BlockState state, BlockView view, BlockPos pos, Direction dir) {
BlockEntity be = view.getBlockEntity(pos); BlockEntity be = view.getBlockEntity(pos);
if (be instanceof TemplateEntity) { if(be instanceof TemplateEntity) {
TemplateEntity template = (TemplateEntity)be; TemplateEntity template = (TemplateEntity) be;
if (template.hasRedstone()) return 15; if(template.hasRedstone()) return 15;
BlockState beState = template.getRenderedState(); BlockState beState = template.getRenderedState();
return beState.getWeakRedstonePower(view, pos, dir); return beState.getWeakRedstonePower(view, pos, dir);
} }
return 0; return 0;
} }
@Override @Override
public int getStrongRedstonePower(BlockState state, BlockView view, BlockPos pos, Direction dir) { public int getStrongRedstonePower(BlockState state, BlockView view, BlockPos pos, Direction dir) {
BlockEntity be = view.getBlockEntity(pos); BlockEntity be = view.getBlockEntity(pos);
if (be instanceof TemplateEntity) { if(be instanceof TemplateEntity) {
TemplateEntity template = (TemplateEntity)be; TemplateEntity template = (TemplateEntity) be;
if (template.hasRedstone()) return 15; if(template.hasRedstone()) return 15;
BlockState beState = template.getRenderedState(); BlockState beState = template.getRenderedState();
return beState.getStrongRedstonePower(view, pos, dir); return beState.getStrongRedstonePower(view, pos, dir);
} }
return 0; return 0;
} }
@Override @Override
public BlockState getContainedState(World world, BlockPos pos) { public BlockState getContainedState(World world, BlockPos pos) {
BlockEntity be = world.getBlockEntity(pos); BlockEntity be = world.getBlockEntity(pos);
if (be instanceof TemplateEntity) return ((TemplateEntity)be).getRenderedState(); if(be instanceof TemplateEntity) return ((TemplateEntity) be).getRenderedState();
return Blocks.AIR.getDefaultState(); return Blocks.AIR.getDefaultState();
} }
@Override @Override
public void setContainedState(World world, BlockPos pos, BlockState state) { public void setContainedState(World world, BlockPos pos, BlockState state) {
BlockEntity be = world.getBlockEntity(pos); BlockEntity be = world.getBlockEntity(pos);
if (be instanceof TemplateEntity) ((TemplateEntity)be).setRenderedState(state); if(be instanceof TemplateEntity) ((TemplateEntity) be).setRenderedState(state);
} }
} }

View File

@ -19,35 +19,35 @@ public abstract class TemplateEntity extends BlockEntity implements BlockEntityC
protected boolean glowstone = false; protected boolean glowstone = false;
protected boolean redstone = false; protected boolean redstone = false;
private final Block baseBlock; private final Block baseBlock;
public TemplateEntity(BlockEntityType<?> type, Block baseBlock) { public TemplateEntity(BlockEntityType<?> type, Block baseBlock) {
super(type); super(type);
this.baseBlock = baseBlock; this.baseBlock = baseBlock;
} }
public BlockState getRenderedState() { public BlockState getRenderedState() {
return renderedState; return renderedState;
} }
public void setRenderedState(BlockState state) { public void setRenderedState(BlockState state) {
this.renderedState = state; this.renderedState = state;
markDirty(); markDirty();
} }
@Override @Override
public void fromTag(CompoundTag tag) { public void fromTag(CompoundTag tag) {
super.fromTag(tag); super.fromTag(tag);
renderedState = NbtHelper.toBlockState(tag.getCompound("BlockState")); renderedState = NbtHelper.toBlockState(tag.getCompound("BlockState"));
glowstone = tag.getBoolean("Glowstone"); glowstone = tag.getBoolean("Glowstone");
redstone = tag.getBoolean("Redstone"); redstone = tag.getBoolean("Redstone");
if (world != null && world.isClient) { if(world != null && world.isClient) {
//TODO probably unsafe, i think the method was removed in 1.14.4 or something though //TODO probably unsafe, i think the method was removed in 1.14.4 or something though
// i cant find any relevant method that takes only 1 blockpos argument // i cant find any relevant method that takes only 1 blockpos argument
((ClientWorld)world).scheduleBlockRenders(pos.getX(), pos.getY(), pos.getZ()); ((ClientWorld) world).scheduleBlockRenders(pos.getX(), pos.getY(), pos.getZ());
//world.scheduleBlockRender(pos); //world.scheduleBlockRender(pos);
} }
} }
@Override @Override
public CompoundTag toTag(CompoundTag tag) { public CompoundTag toTag(CompoundTag tag) {
super.toTag(tag); super.toTag(tag);
@ -56,21 +56,21 @@ public abstract class TemplateEntity extends BlockEntity implements BlockEntityC
tag.putBoolean("Redstone", redstone); tag.putBoolean("Redstone", redstone);
return tag; return tag;
} }
@Override @Override
public void fromClientTag(CompoundTag tag) { public void fromClientTag(CompoundTag tag) {
fromTag(tag); fromTag(tag);
} }
@Override @Override
public CompoundTag toClientTag(CompoundTag tag) { public CompoundTag toClientTag(CompoundTag tag) {
return toTag(tag); return toTag(tag);
} }
@Override @Override
public void markDirty() { public void markDirty() {
super.markDirty(); super.markDirty();
if (world != null && !world.isClient) { if(world != null && !world.isClient) {
for(ServerPlayerEntity player : PlayerLookup.tracking(this)) { for(ServerPlayerEntity player : PlayerLookup.tracking(this)) {
player.networkHandler.sendPacket(this.toUpdatePacket()); player.networkHandler.sendPacket(this.toUpdatePacket());
} }
@ -79,25 +79,25 @@ public abstract class TemplateEntity extends BlockEntity implements BlockEntityC
world.updateListeners(pos, state, state, 1); world.updateListeners(pos, state, state, 1);
} }
} }
@Override @Override
public BlockState getRenderAttachmentData() { public BlockState getRenderAttachmentData() {
return renderedState; return renderedState;
} }
public boolean hasGlowstone() { public boolean hasGlowstone() {
return glowstone; return glowstone;
} }
public void addGlowstone() { public void addGlowstone() {
glowstone = true; glowstone = true;
markDirty(); markDirty();
} }
public boolean hasRedstone() { public boolean hasRedstone() {
return redstone; return redstone;
} }
public void addRedstone() { public void addRedstone() {
redstone = true; redstone = true;
markDirty(); markDirty();

View File

@ -8,40 +8,40 @@ import net.minecraft.client.render.model.json.ModelTransformation;
import net.minecraft.client.texture.Sprite; import net.minecraft.client.texture.Sprite;
public abstract class AbstractModel implements BakedModel, FabricBakedModel { public abstract class AbstractModel implements BakedModel, FabricBakedModel {
protected static final Renderer RENDERER = RendererAccess.INSTANCE.getRenderer(); protected static final Renderer RENDERER = RendererAccess.INSTANCE.getRenderer();
protected final Sprite modelSprite; protected final Sprite modelSprite;
protected final ModelTransformation transformation; protected final ModelTransformation transformation;
protected AbstractModel( protected AbstractModel(
Sprite sprite, Sprite sprite,
ModelTransformation transformation) { ModelTransformation transformation) {
this.modelSprite = sprite; this.modelSprite = sprite;
this.transformation = transformation; this.transformation = transformation;
} }
@Override @Override
public boolean useAmbientOcclusion() { public boolean useAmbientOcclusion() {
return true; return true;
} }
@Override @Override
public boolean hasDepth() { public boolean hasDepth() {
return true; return true;
} }
@Override @Override
public boolean isBuiltin() { public boolean isBuiltin() {
return false; return false;
} }
@Override @Override
public Sprite getSprite() { public Sprite getSprite() {
return modelSprite; return modelSprite;
} }
@Override @Override
public ModelTransformation getTransformation() { public ModelTransformation getTransformation() {
return transformation; return transformation;
} }
} }

View File

@ -1,16 +1,16 @@
package io.github.cottonmc.templates.model; package io.github.cottonmc.templates.model;
import java.util.Random;
import java.util.function.Supplier;
import net.fabricmc.fabric.api.renderer.v1.render.RenderContext.QuadTransform; import net.fabricmc.fabric.api.renderer.v1.render.RenderContext.QuadTransform;
import net.minecraft.block.BlockState; import net.minecraft.block.BlockState;
import net.minecraft.item.ItemStack; import net.minecraft.item.ItemStack;
import net.minecraft.util.math.BlockPos; import net.minecraft.util.math.BlockPos;
import net.minecraft.world.BlockRenderView; import net.minecraft.world.BlockRenderView;
import java.util.Random;
import java.util.function.Supplier;
public interface MeshTransformer extends QuadTransform { public interface MeshTransformer extends QuadTransform {
MeshTransformer prepare(BlockRenderView blockView, BlockState state, BlockPos pos, Supplier<Random> randomSupplier); MeshTransformer prepare(BlockRenderView blockView, BlockState state, BlockPos pos, Supplier<Random> randomSupplier);
MeshTransformer prepare(ItemStack stack, Supplier<Random> randomSupplier); MeshTransformer prepare(ItemStack stack, Supplier<Random> randomSupplier);
} }

View File

@ -1,13 +1,6 @@
package io.github.cottonmc.templates.model; package io.github.cottonmc.templates.model;
import java.lang.ref.WeakReference;
import java.util.Collections;
import java.util.List;
import java.util.Random;
import java.util.function.Supplier;
import com.google.common.collect.ImmutableList; import com.google.common.collect.ImmutableList;
import net.fabricmc.fabric.api.renderer.v1.mesh.Mesh; import net.fabricmc.fabric.api.renderer.v1.mesh.Mesh;
import net.fabricmc.fabric.api.renderer.v1.model.ModelHelper; import net.fabricmc.fabric.api.renderer.v1.model.ModelHelper;
import net.fabricmc.fabric.api.renderer.v1.render.RenderContext; import net.fabricmc.fabric.api.renderer.v1.render.RenderContext;
@ -24,82 +17,88 @@ import net.minecraft.util.math.Direction;
import net.minecraft.world.BlockRenderView; import net.minecraft.world.BlockRenderView;
import net.minecraft.world.World; import net.minecraft.world.World;
import java.lang.ref.WeakReference;
import java.util.Collections;
import java.util.List;
import java.util.Random;
import java.util.function.Supplier;
/** /**
* Simple baked model supporting the Fabric Render API features.<p> * Simple baked model supporting the Fabric Render API features.<p>
*/ */
public class SimpleModel extends AbstractModel { public class SimpleModel extends AbstractModel {
protected final Mesh mesh; protected final Mesh mesh;
protected final Supplier<MeshTransformer> transformerFactory; protected final Supplier<MeshTransformer> transformerFactory;
protected WeakReference<List<BakedQuad>[]> quadLists = null; protected WeakReference<List<BakedQuad>[]> quadLists = null;
protected final ItemProxy itemProxy = new ItemProxy(); protected final ItemProxy itemProxy = new ItemProxy();
public SimpleModel( public SimpleModel(
Mesh mesh, Mesh mesh,
Supplier<MeshTransformer> transformerFactory, Supplier<MeshTransformer> transformerFactory,
Sprite sprite, Sprite sprite,
ModelTransformation transformation) { ModelTransformation transformation) {
super(sprite, transformation); super(sprite, transformation);
this.mesh = mesh; this.mesh = mesh;
this.transformerFactory = transformerFactory; this.transformerFactory = transformerFactory;
} }
@Override @Override
public boolean isVanillaAdapter() { public boolean isVanillaAdapter() {
return false; return false;
} }
@Override @Override
public List<BakedQuad> getQuads(BlockState state, Direction face, Random rand) { public List<BakedQuad> getQuads(BlockState state, Direction face, Random rand) {
List<BakedQuad>[] lists = quadLists == null ? null : quadLists.get(); List<BakedQuad>[] lists = quadLists == null ? null : quadLists.get();
if(lists == null) { if(lists == null) {
lists = ModelHelper.toQuadLists(this.mesh); lists = ModelHelper.toQuadLists(this.mesh);
quadLists = new WeakReference<>(lists); quadLists = new WeakReference<>(lists);
} }
List<BakedQuad> result = lists[face == null ? 6 : face.getId()]; List<BakedQuad> result = lists[face == null ? 6 : face.getId()];
return result == null ? ImmutableList.of() : result; return result == null ? ImmutableList.of() : result;
} }
@Override @Override
public void emitBlockQuads(BlockRenderView blockView, BlockState state, BlockPos pos, Supplier<Random> randomSupplier, RenderContext context) { public void emitBlockQuads(BlockRenderView blockView, BlockState state, BlockPos pos, Supplier<Random> randomSupplier, RenderContext context) {
final MeshTransformer transform = transformerFactory == null ? null : transformerFactory.get().prepare(blockView, state, pos, randomSupplier); final MeshTransformer transform = transformerFactory == null ? null : transformerFactory.get().prepare(blockView, state, pos, randomSupplier);
if(transform != null) { if(transform != null) {
context.pushTransform(transform); context.pushTransform(transform);
} }
if(mesh != null) { if(mesh != null) {
context.meshConsumer().accept(mesh); context.meshConsumer().accept(mesh);
} }
if(transform != null) { if(transform != null) {
context.popTransform(); context.popTransform();
} }
} }
@Override @Override
public ModelItemPropertyOverrideList getItemPropertyOverrides() { public ModelItemPropertyOverrideList getItemPropertyOverrides() {
return itemProxy; return itemProxy;
} }
protected class ItemProxy extends ModelItemPropertyOverrideList { protected class ItemProxy extends ModelItemPropertyOverrideList {
public ItemProxy() { public ItemProxy() {
super(null, null, null, Collections.emptyList()); super(null, null, null, Collections.emptyList());
} }
@Override @Override
public BakedModel apply(BakedModel bakedModel_1, ItemStack itemStack_1, World world_1, LivingEntity livingEntity_1) { public BakedModel apply(BakedModel bakedModel_1, ItemStack itemStack_1, World world_1, LivingEntity livingEntity_1) {
return SimpleModel.this; return SimpleModel.this;
} }
} }
@Override @Override
public void emitItemQuads(ItemStack stack, Supplier<Random> randomSupplier, RenderContext context) { public void emitItemQuads(ItemStack stack, Supplier<Random> randomSupplier, RenderContext context) {
final MeshTransformer transform = transformerFactory == null ? null : transformerFactory.get().prepare(stack, randomSupplier); final MeshTransformer transform = transformerFactory == null ? null : transformerFactory.get().prepare(stack, randomSupplier);
if(transform != null) { if(transform != null) {
context.pushTransform(transform); context.pushTransform(transform);
} }
if(mesh != null) { if(mesh != null) {
context.meshConsumer().accept(mesh); context.meshConsumer().accept(mesh);
} }
if(transform != null) { if(transform != null) {
context.popTransform(); context.popTransform();
} }
} }
} }

View File

@ -1,10 +1,5 @@
package io.github.cottonmc.templates.model; package io.github.cottonmc.templates.model;
import java.util.Collection;
import java.util.Collections;
import java.util.Set;
import java.util.function.Function;
import net.minecraft.client.render.model.BakedModel; import net.minecraft.client.render.model.BakedModel;
import net.minecraft.client.render.model.ModelBakeSettings; import net.minecraft.client.render.model.ModelBakeSettings;
import net.minecraft.client.render.model.ModelLoader; import net.minecraft.client.render.model.ModelLoader;
@ -12,22 +7,27 @@ import net.minecraft.client.render.model.UnbakedModel;
import net.minecraft.client.texture.Sprite; import net.minecraft.client.texture.Sprite;
import net.minecraft.util.Identifier; import net.minecraft.util.Identifier;
import java.util.Collection;
import java.util.Collections;
import java.util.Set;
import java.util.function.Function;
@FunctionalInterface @FunctionalInterface
public interface SimpleUnbakedModel extends UnbakedModel { public interface SimpleUnbakedModel extends UnbakedModel {
BakedModel bake(); BakedModel bake();
@Override @Override
default Collection<Identifier> getModelDependencies() { default Collection<Identifier> getModelDependencies() {
return Collections.emptyList(); return Collections.emptyList();
} }
@Override @Override
default Collection<Identifier> getTextureDependencies(Function<Identifier, UnbakedModel> var1, Set<String> var2) { default Collection<Identifier> getTextureDependencies(Function<Identifier, UnbakedModel> var1, Set<String> var2) {
return Collections.emptyList(); return Collections.emptyList();
} }
@Override @Override
default BakedModel bake(ModelLoader loader, Function<Identifier, Sprite> spriteFunc, ModelBakeSettings settings) { default BakedModel bake(ModelLoader loader, Function<Identifier, Sprite> spriteFunc, ModelBakeSettings settings) {
return bake(); return bake();
} }
} }

View File

@ -1,12 +1,5 @@
package io.github.cottonmc.templates.model; package io.github.cottonmc.templates.model;
import java.util.Random;
import java.util.function.Supplier;
import net.minecraft.client.render.RenderLayer;
import net.minecraft.world.BlockRenderView;
import org.apache.commons.lang3.ObjectUtils;
import io.github.cottonmc.templates.util.SpriteSet; import io.github.cottonmc.templates.util.SpriteSet;
import net.fabricmc.fabric.api.client.render.ColorProviderRegistry; import net.fabricmc.fabric.api.client.render.ColorProviderRegistry;
import net.fabricmc.fabric.api.renderer.v1.material.MaterialFinder; import net.fabricmc.fabric.api.renderer.v1.material.MaterialFinder;
@ -22,6 +15,7 @@ import net.minecraft.block.BlockState;
import net.minecraft.block.Blocks; import net.minecraft.block.Blocks;
import net.minecraft.client.MinecraftClient; import net.minecraft.client.MinecraftClient;
import net.minecraft.client.color.block.BlockColorProvider; import net.minecraft.client.color.block.BlockColorProvider;
import net.minecraft.client.render.RenderLayer;
import net.minecraft.client.render.model.BakedModel; import net.minecraft.client.render.model.BakedModel;
import net.minecraft.client.texture.MissingSprite; import net.minecraft.client.texture.MissingSprite;
import net.minecraft.client.texture.Sprite; import net.minecraft.client.texture.Sprite;
@ -29,329 +23,334 @@ import net.minecraft.item.ItemStack;
import net.minecraft.state.property.Properties; import net.minecraft.state.property.Properties;
import net.minecraft.util.math.BlockPos; import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.Direction; import net.minecraft.util.math.Direction;
import net.minecraft.world.BlockRenderView;
import org.apache.commons.lang3.ObjectUtils;
import java.util.Random;
import java.util.function.Supplier;
public class SlopeModel extends SimpleModel { public class SlopeModel extends SimpleModel {
private static final ThreadLocal<Transformer> TRANSFORMERS = ThreadLocal.withInitial(Transformer::new); private static final ThreadLocal<Transformer> TRANSFORMERS = ThreadLocal.withInitial(Transformer::new);
public SlopeModel(BlockState blockState) { public SlopeModel(BlockState blockState) {
super(baseMesh(blockState), TRANSFORMERS::get, MissingSprite.getMissingSprite(), ModelHelper.MODEL_TRANSFORM_BLOCK); super(baseMesh(blockState), TRANSFORMERS::get, MissingSprite.getMissingSprite(), ModelHelper.MODEL_TRANSFORM_BLOCK);
} }
private static Mesh baseMesh(BlockState state) { private static Mesh baseMesh(BlockState state) {
final MeshBuilder builder = RENDERER.meshBuilder(); final MeshBuilder builder = RENDERER.meshBuilder();
final QuadEmitter quad = builder.getEmitter(); final QuadEmitter quad = builder.getEmitter();
final Direction dir = state.get(Properties.HORIZONTAL_FACING); final Direction dir = state.get(Properties.HORIZONTAL_FACING);
drawSlope(quad.spriteColor(0, -1, -1, -1, -1), dir); drawSlope(quad.spriteColor(0, -1, -1, -1, -1), dir);
drawLeftSide(quad.spriteColor(0, -1, -1, -1, -1), dir); drawLeftSide(quad.spriteColor(0, -1, -1, -1, -1), dir);
drawRightSide(quad.spriteColor(0, -1, -1, -1, -1), dir); drawRightSide(quad.spriteColor(0, -1, -1, -1, -1), dir);
drawBack(quad.spriteColor(0, -1, -1, -1, -1), dir); drawBack(quad.spriteColor(0, -1, -1, -1, -1), dir);
drawBottom(quad.spriteColor(0, -1, -1, -1, -1)); drawBottom(quad.spriteColor(0, -1, -1, -1, -1));
return builder.build(); return builder.build();
} }
private static final int TAG_SLOPE = 0; private static final int TAG_SLOPE = 0;
private static final int TAG_LEFT = 1; private static final int TAG_LEFT = 1;
private static final int TAG_RIGHT = 2; private static final int TAG_RIGHT = 2;
private static final int TAG_BACK = 3; private static final int TAG_BACK = 3;
private static final int TAG_BOTTOM = 4; private static final int TAG_BOTTOM = 4;
private static void drawSlope(QuadEmitter quad, Direction dir) { private static void drawSlope(QuadEmitter quad, Direction dir) {
quad.tag(TAG_SLOPE); quad.tag(TAG_SLOPE);
switch (dir) { switch(dir) {
case NORTH: case NORTH:
quad.pos(0, 0f, 1f, 0f).pos(1, 0f, 0f, 1f).pos(2, 1f, 0f, 1f).pos(3, 1f, 1f, 0f).emit(); quad.pos(0, 0f, 1f, 0f).pos(1, 0f, 0f, 1f).pos(2, 1f, 0f, 1f).pos(3, 1f, 1f, 0f).emit();
break; break;
case SOUTH: case SOUTH:
quad.pos(0, 0f, 0f, 0f).pos(1, 0f, 1f, 1f).pos(2, 1f, 1f, 1f).pos(3, 1f, 0f, 0f).emit(); quad.pos(0, 0f, 0f, 0f).pos(1, 0f, 1f, 1f).pos(2, 1f, 1f, 1f).pos(3, 1f, 0f, 0f).emit();
break; break;
case EAST: case EAST:
quad.pos(0, 0f, 0f, 0f).pos(1, 0f, 0f, 1f).pos(2, 1f, 1f, 1f).pos(3, 1f, 1f, 0f).emit(); quad.pos(0, 0f, 0f, 0f).pos(1, 0f, 0f, 1f).pos(2, 1f, 1f, 1f).pos(3, 1f, 1f, 0f).emit();
break; break;
case WEST: case WEST:
quad.pos(0, 0f, 1f, 0f).pos(1, 0f, 1f, 1f).pos(2, 1f, 0f, 1f).pos(3, 1f, 0f, 0f).emit(); quad.pos(0, 0f, 1f, 0f).pos(1, 0f, 1f, 1f).pos(2, 1f, 0f, 1f).pos(3, 1f, 0f, 0f).emit();
default: default:
break; break;
} }
} }
private static void drawLeftSide(QuadEmitter quad, Direction dir) { private static void drawLeftSide(QuadEmitter quad, Direction dir) {
switch(dir) { switch(dir) {
case NORTH: case NORTH:
quad.tag(TAG_LEFT).pos(0, 0f, 0f, 0f).pos(1, 0f, 0f, 1f).pos(2, 0f, 0f, 1f).pos(3, 0f, 1f, 0f).emit(); quad.tag(TAG_LEFT).pos(0, 0f, 0f, 0f).pos(1, 0f, 0f, 1f).pos(2, 0f, 0f, 1f).pos(3, 0f, 1f, 0f).emit();
break; break;
case SOUTH: case SOUTH:
quad.tag(TAG_LEFT).pos(0, 1f, 0f, 0f).pos(1, 1f, 1f, 1f).pos(2, 1f, 0f, 1f).pos(3, 1f, 0f, 1f).emit(); quad.tag(TAG_LEFT).pos(0, 1f, 0f, 0f).pos(1, 1f, 1f, 1f).pos(2, 1f, 0f, 1f).pos(3, 1f, 0f, 1f).emit();
break; break;
case EAST: case EAST:
quad.tag(TAG_LEFT).pos(0, 1f, 0f, 0f).pos(1, 0f, 0f, 0f).pos(2, 0f, 0f, 0f).pos(3, 1f, 1f, 0f).emit(); quad.tag(TAG_LEFT).pos(0, 1f, 0f, 0f).pos(1, 0f, 0f, 0f).pos(2, 0f, 0f, 0f).pos(3, 1f, 1f, 0f).emit();
break; break;
case WEST: case WEST:
quad.tag(TAG_LEFT).pos(0, 0f, 0f, 1f).pos(1, 1f, 0f, 1f).pos(2, 1f, 0f, 1f).pos(3, 0f, 1f, 1f).emit(); quad.tag(TAG_LEFT).pos(0, 0f, 0f, 1f).pos(1, 1f, 0f, 1f).pos(2, 1f, 0f, 1f).pos(3, 0f, 1f, 1f).emit();
default: default:
break; break;
} }
} }
private static void drawRightSide(QuadEmitter quad, Direction dir) { private static void drawRightSide(QuadEmitter quad, Direction dir) {
switch(dir) { switch(dir) {
case NORTH: case NORTH:
quad.tag(TAG_RIGHT).pos(0, 1f, 0f, 0f).pos(1, 1f, 1f, 0f).pos(2, 1f, 0f, 1f).pos(3, 1f, 0f, 1f).emit(); quad.tag(TAG_RIGHT).pos(0, 1f, 0f, 0f).pos(1, 1f, 1f, 0f).pos(2, 1f, 0f, 1f).pos(3, 1f, 0f, 1f).emit();
break; break;
case SOUTH: case SOUTH:
quad.tag(TAG_RIGHT).pos(0, 0f, 0f, 0f).pos(1, 0f, 0f, 0f).pos(2, 0f, 0f, 1f).pos(3, 0f, 1f, 1f).emit(); quad.tag(TAG_RIGHT).pos(0, 0f, 0f, 0f).pos(1, 0f, 0f, 0f).pos(2, 0f, 0f, 1f).pos(3, 0f, 1f, 1f).emit();
break; break;
case EAST: case EAST:
quad.tag(TAG_RIGHT).pos(0, 0f, 0f, 1f).pos(1, 0f, 0f, 1f).pos(2, 1f, 0f, 1f).pos(3, 1f, 1f, 1f).emit(); quad.tag(TAG_RIGHT).pos(0, 0f, 0f, 1f).pos(1, 0f, 0f, 1f).pos(2, 1f, 0f, 1f).pos(3, 1f, 1f, 1f).emit();
break; break;
case WEST: case WEST:
quad.tag(TAG_RIGHT).pos(0, 0f, 0f, 0f).pos(1, 0f, 1f, 0f).pos(2, 1f, 0f, 0f).pos(3, 1f, 0f, 0f).emit(); quad.tag(TAG_RIGHT).pos(0, 0f, 0f, 0f).pos(1, 0f, 1f, 0f).pos(2, 1f, 0f, 0f).pos(3, 1f, 0f, 0f).emit();
default: default:
break; break;
} }
} }
private static void drawBack(QuadEmitter quad, Direction dir) { private static void drawBack(QuadEmitter quad, Direction dir) {
switch(dir) { switch(dir) {
case NORTH: case NORTH:
quad.tag(TAG_BACK).pos(0, 0f, 0f, 0f).pos(1, 0f, 1f, 0f).pos(2, 1f, 1f, 0f).pos(3, 1f, 0f, 0f).emit(); quad.tag(TAG_BACK).pos(0, 0f, 0f, 0f).pos(1, 0f, 1f, 0f).pos(2, 1f, 1f, 0f).pos(3, 1f, 0f, 0f).emit();
break; break;
case SOUTH: case SOUTH:
quad.tag(TAG_BACK).pos(0, 0f, 0f, 1f).pos(1, 1f, 0f, 1f).pos(2, 1f, 1f, 1f).pos(3, 0f, 1f, 1f).emit(); quad.tag(TAG_BACK).pos(0, 0f, 0f, 1f).pos(1, 1f, 0f, 1f).pos(2, 1f, 1f, 1f).pos(3, 0f, 1f, 1f).emit();
break; break;
case EAST: case EAST:
quad.tag(TAG_BACK).pos(0, 1f, 0f, 0f).pos(1, 1f, 1f, 0f).pos(2, 1f, 1f, 1f).pos(3, 1f, 0f, 1f).emit(); quad.tag(TAG_BACK).pos(0, 1f, 0f, 0f).pos(1, 1f, 1f, 0f).pos(2, 1f, 1f, 1f).pos(3, 1f, 0f, 1f).emit();
break; break;
case WEST: case WEST:
quad.tag(TAG_BACK).pos(0, 0f, 0f, 0f).pos(1, 0f, 0f, 1f).pos(2, 0f, 1f, 1f).pos(3, 0f, 1f, 0f).emit(); quad.tag(TAG_BACK).pos(0, 0f, 0f, 0f).pos(1, 0f, 0f, 1f).pos(2, 0f, 1f, 1f).pos(3, 0f, 1f, 0f).emit();
default: default:
break; break;
} }
} }
private static void drawBottom(QuadEmitter quad) { private static void drawBottom(QuadEmitter quad) {
quad.tag(TAG_BOTTOM).pos(0, 0f, 0f, 0f).pos(1, 1f, 0f, 0f).pos(2, 1f, 0f, 1f).pos(3, 0f, 0f, 1f).emit(); quad.tag(TAG_BOTTOM).pos(0, 0f, 0f, 0f).pos(1, 1f, 0f, 0f).pos(2, 1f, 0f, 1f).pos(3, 0f, 0f, 1f).emit();
} }
private static class Transformer implements MeshTransformer { private static class Transformer implements MeshTransformer {
private final MinecraftClient minecraft = MinecraftClient.getInstance(); private final MinecraftClient minecraft = MinecraftClient.getInstance();
private final SpriteSet sprites = new SpriteSet(); private final SpriteSet sprites = new SpriteSet();
private final MaterialFinder finder = RENDERER.materialFinder(); private final MaterialFinder finder = RENDERER.materialFinder();
private int color; private int color;
private Direction dir; private Direction dir;
private RenderMaterial material; private RenderMaterial material;
@Override @Override
public MeshTransformer prepare(BlockRenderView blockView, BlockState state, BlockPos pos, Supplier<Random> randomSupplier) { public MeshTransformer prepare(BlockRenderView blockView, BlockState state, BlockPos pos, Supplier<Random> randomSupplier) {
dir = state.get(Properties.HORIZONTAL_FACING); dir = state.get(Properties.HORIZONTAL_FACING);
color = 0xffffff; color = 0xffffff;
final BlockState template = ObjectUtils.defaultIfNull((BlockState) ((RenderAttachedBlockView)blockView).getBlockEntityRenderAttachment(pos), Blocks.AIR.getDefaultState()); final BlockState template = ObjectUtils.defaultIfNull((BlockState) ((RenderAttachedBlockView) blockView).getBlockEntityRenderAttachment(pos), Blocks.AIR.getDefaultState());
final Block block = template.getBlock(); final Block block = template.getBlock();
if(block == Blocks.AIR) { if(block == Blocks.AIR) {
sprites.clear(); sprites.clear();
material = finder.clear().blendMode(0, RenderLayer.CUTOUT).find(); material = finder.clear().blendMode(0, RenderLayer.CUTOUT).find();
} else { } else {
material = finder.clear().disableDiffuse(0, false).disableAo(0, false).blendMode(0, block.getRenderLayer()).find(); material = finder.clear().disableDiffuse(0, false).disableAo(0, false).blendMode(0, block.getRenderLayer()).find();
BakedModel model = minecraft.getBlockRenderManager().getModel(template); BakedModel model = minecraft.getBlockRenderManager().getModel(template);
sprites.prepare(model, randomSupplier.get()); sprites.prepare(model, randomSupplier.get());
BlockColorProvider blockColor = ColorProviderRegistry.BLOCK.get(block); BlockColorProvider blockColor = ColorProviderRegistry.BLOCK.get(block);
if (blockColor != null) { if(blockColor != null) {
color = 0xff000000 | blockColor.getColor(template, blockView, pos, 1); color = 0xff000000 | blockColor.getColor(template, blockView, pos, 1);
} }
} }
return this; return this;
} }
@Override @Override
public MeshTransformer prepare(ItemStack stack, Supplier<Random> randomSupplier) { public MeshTransformer prepare(ItemStack stack, Supplier<Random> randomSupplier) {
dir = Direction.NORTH; dir = Direction.NORTH;
color = 0xffffff; color = 0xffffff;
sprites.clear(); sprites.clear();
material = finder.clear().find(); material = finder.clear().find();
return this; return this;
} }
@Override @Override
public boolean transform(MutableQuadView quad) { public boolean transform(MutableQuadView quad) {
quad.material(material); quad.material(material);
final SpriteSet sprites = this.sprites; final SpriteSet sprites = this.sprites;
switch(quad.tag()) { switch(quad.tag()) {
case TAG_SLOPE: case TAG_SLOPE:
if(sprites.hasColor(Direction.UP)) { if(sprites.hasColor(Direction.UP)) {
quad.spriteColor(0, color, color, color, color); quad.spriteColor(0, color, color, color, color);
} }
paintSlope(quad, dir, sprites.getSprite(Direction.UP)); paintSlope(quad, dir, sprites.getSprite(Direction.UP));
break; break;
case TAG_LEFT: case TAG_LEFT:
final Direction leftDir = this.dir.rotateYCounterclockwise(); final Direction leftDir = this.dir.rotateYCounterclockwise();
if(sprites.hasColor(leftDir)) { if(sprites.hasColor(leftDir)) {
quad.spriteColor(0, color, color, color, color); quad.spriteColor(0, color, color, color, color);
} }
paintLeftSide(quad, dir, sprites.getSprite(leftDir)); paintLeftSide(quad, dir, sprites.getSprite(leftDir));
break; break;
case TAG_RIGHT: { case TAG_RIGHT: {
final Direction rightDir = this.dir.rotateYClockwise(); final Direction rightDir = this.dir.rotateYClockwise();
if(sprites.hasColor(rightDir)) { if(sprites.hasColor(rightDir)) {
quad.spriteColor(0, color, color, color, color); quad.spriteColor(0, color, color, color, color);
} }
paintRightSide(quad, dir, sprites.getSprite(rightDir)); paintRightSide(quad, dir, sprites.getSprite(rightDir));
break; break;
} }
case TAG_BACK: { case TAG_BACK: {
if(sprites.hasColor(dir)) { if(sprites.hasColor(dir)) {
quad.spriteColor(0, color, color, color, color); quad.spriteColor(0, color, color, color, color);
} }
paintBack(quad, dir, sprites.getSprite(dir)); paintBack(quad, dir, sprites.getSprite(dir));
break; break;
} }
case TAG_BOTTOM: { case TAG_BOTTOM: {
if(sprites.hasColor(Direction.DOWN)) { if(sprites.hasColor(Direction.DOWN)) {
quad.spriteColor(0, color, color, color, color); quad.spriteColor(0, color, color, color, color);
} }
paintBottom(quad, sprites.getSprite(Direction.DOWN)); paintBottom(quad, sprites.getSprite(Direction.DOWN));
break; break;
} }
default: default:
} }
return true; return true;
} }
private static void paintSlope(MutableQuadView quad, Direction dir, Sprite sprite) { private static void paintSlope(MutableQuadView quad, Direction dir, Sprite sprite) {
switch (dir) { switch(dir) {
case NORTH: case NORTH:
quad.sprite(0, 0, sprite.getMinU(), sprite.getMinV()) quad.sprite(0, 0, sprite.getMinU(), sprite.getMinV())
.sprite(1, 0, sprite.getMinU(), sprite.getMaxV()) .sprite(1, 0, sprite.getMinU(), sprite.getMaxV())
.sprite(2, 0, sprite.getMaxU(), sprite.getMaxV()) .sprite(2, 0, sprite.getMaxU(), sprite.getMaxV())
.sprite(3, 0, sprite.getMaxU(), sprite.getMinV()); .sprite(3, 0, sprite.getMaxU(), sprite.getMinV());
break; break;
case SOUTH: case SOUTH:
quad.sprite(0, 0, sprite.getMaxU(), sprite.getMaxV()) quad.sprite(0, 0, sprite.getMaxU(), sprite.getMaxV())
.sprite(1, 0, sprite.getMaxU(), sprite.getMinV()) .sprite(1, 0, sprite.getMaxU(), sprite.getMinV())
.sprite(2, 0, sprite.getMinU(), sprite.getMinV()) .sprite(2, 0, sprite.getMinU(), sprite.getMinV())
.sprite(3, 0, sprite.getMinU(), sprite.getMaxV()); .sprite(3, 0, sprite.getMinU(), sprite.getMaxV());
break; break;
case EAST: case EAST:
quad.sprite(0, 0, sprite.getMinU(), sprite.getMaxV()) quad.sprite(0, 0, sprite.getMinU(), sprite.getMaxV())
.sprite(1, 0, sprite.getMaxU(), sprite.getMaxV()) .sprite(1, 0, sprite.getMaxU(), sprite.getMaxV())
.sprite(2, 0, sprite.getMaxU(), sprite.getMinV()) .sprite(2, 0, sprite.getMaxU(), sprite.getMinV())
.sprite(3, 0, sprite.getMinU(), sprite.getMinV()); .sprite(3, 0, sprite.getMinU(), sprite.getMinV());
break; break;
case WEST: case WEST:
quad.sprite(0, 0, sprite.getMaxU(), sprite.getMinV()) quad.sprite(0, 0, sprite.getMaxU(), sprite.getMinV())
.sprite(1, 0, sprite.getMinU(), sprite.getMinV()) .sprite(1, 0, sprite.getMinU(), sprite.getMinV())
.sprite(2, 0, sprite.getMinU(), sprite.getMaxV()) .sprite(2, 0, sprite.getMinU(), sprite.getMaxV())
.sprite(3, 0, sprite.getMaxU(), sprite.getMaxV()); .sprite(3, 0, sprite.getMaxU(), sprite.getMaxV());
default: default:
break; break;
} }
} }
private static void paintLeftSide(MutableQuadView quad, Direction dir, Sprite sprite) { private static void paintLeftSide(MutableQuadView quad, Direction dir, Sprite sprite) {
switch(dir) { switch(dir) {
case NORTH: case NORTH:
quad.sprite(0, 0, sprite.getMinU(), sprite.getMaxV()) quad.sprite(0, 0, sprite.getMinU(), sprite.getMaxV())
.sprite(1, 0, sprite.getMaxU(), sprite.getMaxV()) .sprite(1, 0, sprite.getMaxU(), sprite.getMaxV())
.sprite(2, 0, sprite.getMaxU(), sprite.getMinV()) .sprite(2, 0, sprite.getMaxU(), sprite.getMinV())
.sprite(3, 0, sprite.getMinU(), sprite.getMinV()); .sprite(3, 0, sprite.getMinU(), sprite.getMinV());
break; break;
case SOUTH: case SOUTH:
quad.sprite(0, 0, sprite.getMaxU(), sprite.getMinV()) quad.sprite(0, 0, sprite.getMaxU(), sprite.getMinV())
.sprite(1, 0, sprite.getMinU(), sprite.getMinV()) .sprite(1, 0, sprite.getMinU(), sprite.getMinV())
.sprite(2, 0, sprite.getMinU(), sprite.getMaxV()) .sprite(2, 0, sprite.getMinU(), sprite.getMaxV())
.sprite(3, 0, sprite.getMaxU(), sprite.getMaxV()); .sprite(3, 0, sprite.getMaxU(), sprite.getMaxV());
break; break;
case EAST: case EAST:
quad.sprite(0, 0, sprite.getMinU(), sprite.getMaxV()) quad.sprite(0, 0, sprite.getMinU(), sprite.getMaxV())
.sprite(1, 0, sprite.getMaxU(), sprite.getMaxV()) .sprite(1, 0, sprite.getMaxU(), sprite.getMaxV())
.sprite(2, 0, sprite.getMaxU(), sprite.getMinV()) .sprite(2, 0, sprite.getMaxU(), sprite.getMinV())
.sprite(3, 0, sprite.getMinU(), sprite.getMinV()); .sprite(3, 0, sprite.getMinU(), sprite.getMinV());
break; break;
case WEST: case WEST:
quad.sprite(0, 0, sprite.getMinU(), sprite.getMaxV()) quad.sprite(0, 0, sprite.getMinU(), sprite.getMaxV())
.sprite(1, 0, sprite.getMaxU(), sprite.getMaxV()) .sprite(1, 0, sprite.getMaxU(), sprite.getMaxV())
.sprite(2, 0, sprite.getMaxU(), sprite.getMinV()) .sprite(2, 0, sprite.getMaxU(), sprite.getMinV())
.sprite(3, 0, sprite.getMinU(), sprite.getMinV()); .sprite(3, 0, sprite.getMinU(), sprite.getMinV());
default: default:
break; break;
} }
} }
private static void paintRightSide(MutableQuadView quad, Direction dir, Sprite sprite) { private static void paintRightSide(MutableQuadView quad, Direction dir, Sprite sprite) {
switch(dir) { switch(dir) {
case NORTH: case NORTH:
quad.sprite(0, 0, sprite.getMaxU(), sprite.getMaxV()) quad.sprite(0, 0, sprite.getMaxU(), sprite.getMaxV())
.sprite(1, 0, sprite.getMaxU(), sprite.getMinV()) .sprite(1, 0, sprite.getMaxU(), sprite.getMinV())
.sprite(2, 0, sprite.getMinU(), sprite.getMinV()) .sprite(2, 0, sprite.getMinU(), sprite.getMinV())
.sprite(3, 0, sprite.getMinU(), sprite.getMaxV()); .sprite(3, 0, sprite.getMinU(), sprite.getMaxV());
break; break;
case SOUTH: case SOUTH:
quad.sprite(0, 0, sprite.getMinU(), sprite.getMinV()) quad.sprite(0, 0, sprite.getMinU(), sprite.getMinV())
.sprite(1, 0, sprite.getMinU(), sprite.getMaxV()) .sprite(1, 0, sprite.getMinU(), sprite.getMaxV())
.sprite(2, 0, sprite.getMaxU(), sprite.getMaxV()) .sprite(2, 0, sprite.getMaxU(), sprite.getMaxV())
.sprite(3, 0, sprite.getMaxU(), sprite.getMinV()); .sprite(3, 0, sprite.getMaxU(), sprite.getMinV());
break; break;
case EAST: case EAST:
quad.sprite(0, 0, sprite.getMinU(), sprite.getMinV()) quad.sprite(0, 0, sprite.getMinU(), sprite.getMinV())
.sprite(1, 0, sprite.getMinU(), sprite.getMaxV()) .sprite(1, 0, sprite.getMinU(), sprite.getMaxV())
.sprite(2, 0, sprite.getMaxU(), sprite.getMaxV()) .sprite(2, 0, sprite.getMaxU(), sprite.getMaxV())
.sprite(3, 0, sprite.getMaxU(), sprite.getMinV()); .sprite(3, 0, sprite.getMaxU(), sprite.getMinV());
break; break;
case WEST: case WEST:
quad.sprite(0, 0, sprite.getMaxU(), sprite.getMaxV()) quad.sprite(0, 0, sprite.getMaxU(), sprite.getMaxV())
.sprite(1, 0, sprite.getMaxU(), sprite.getMinV()) .sprite(1, 0, sprite.getMaxU(), sprite.getMinV())
.sprite(2, 0, sprite.getMinU(), sprite.getMinV()) .sprite(2, 0, sprite.getMinU(), sprite.getMinV())
.sprite(3, 0, sprite.getMinU(), sprite.getMaxV()); .sprite(3, 0, sprite.getMinU(), sprite.getMaxV());
default: default:
break; break;
} }
} }
private static void paintBack(MutableQuadView quad, Direction dir, Sprite sprite) { private static void paintBack(MutableQuadView quad, Direction dir, Sprite sprite) {
switch(dir) { switch(dir) {
case NORTH: case NORTH:
quad.sprite(0, 0, sprite.getMaxU(), sprite.getMaxV()) quad.sprite(0, 0, sprite.getMaxU(), sprite.getMaxV())
.sprite(1, 0, sprite.getMaxU(), sprite.getMinV()) .sprite(1, 0, sprite.getMaxU(), sprite.getMinV())
.sprite(2, 0, sprite.getMinU(), sprite.getMinV()) .sprite(2, 0, sprite.getMinU(), sprite.getMinV())
.sprite(3, 0, sprite.getMinU(), sprite.getMaxV()); .sprite(3, 0, sprite.getMinU(), sprite.getMaxV());
break; break;
case SOUTH: case SOUTH:
quad.sprite(0, 0, sprite.getMinU(), sprite.getMaxV()) quad.sprite(0, 0, sprite.getMinU(), sprite.getMaxV())
.sprite(1, 0, sprite.getMaxU(), sprite.getMaxV()) .sprite(1, 0, sprite.getMaxU(), sprite.getMaxV())
.sprite(2, 0, sprite.getMaxU(), sprite.getMinV()) .sprite(2, 0, sprite.getMaxU(), sprite.getMinV())
.sprite(3, 0, sprite.getMinU(), sprite.getMinV()); .sprite(3, 0, sprite.getMinU(), sprite.getMinV());
break; break;
case EAST: case EAST:
quad.sprite(0, 0, sprite.getMaxU(), sprite.getMaxV()) quad.sprite(0, 0, sprite.getMaxU(), sprite.getMaxV())
.sprite(1, 0, sprite.getMaxU(), sprite.getMinV()) .sprite(1, 0, sprite.getMaxU(), sprite.getMinV())
.sprite(2, 0, sprite.getMinU(), sprite.getMinV()) .sprite(2, 0, sprite.getMinU(), sprite.getMinV())
.sprite(3, 0, sprite.getMinU(), sprite.getMaxV()); .sprite(3, 0, sprite.getMinU(), sprite.getMaxV());
break; break;
case WEST: case WEST:
quad.sprite(0, 0, sprite.getMinU(), sprite.getMaxV()) quad.sprite(0, 0, sprite.getMinU(), sprite.getMaxV())
.sprite(1, 0, sprite.getMaxU(), sprite.getMaxV()) .sprite(1, 0, sprite.getMaxU(), sprite.getMaxV())
.sprite(2, 0, sprite.getMaxU(), sprite.getMinV()) .sprite(2, 0, sprite.getMaxU(), sprite.getMinV())
.sprite(3, 0, sprite.getMinU(), sprite.getMinV()); .sprite(3, 0, sprite.getMinU(), sprite.getMinV());
default: default:
break; break;
} }
} }
private static void paintBottom(MutableQuadView quad, Sprite sprite) { private static void paintBottom(MutableQuadView quad, Sprite sprite) {
quad.sprite(0, 0, sprite.getMinU(), sprite.getMaxV()) quad.sprite(0, 0, sprite.getMinU(), sprite.getMaxV())
.sprite(1, 0, sprite.getMaxU(), sprite.getMaxV()) .sprite(1, 0, sprite.getMaxU(), sprite.getMaxV())
.sprite(2, 0, sprite.getMaxU(), sprite.getMinV()) .sprite(2, 0, sprite.getMaxU(), sprite.getMinV())
.sprite(3, 0, sprite.getMinU(), sprite.getMinV()); .sprite(3, 0, sprite.getMinU(), sprite.getMinV());
} }
} }
} }

View File

@ -1,7 +1,5 @@
package io.github.cottonmc.templates.model; package io.github.cottonmc.templates.model;
import java.util.HashMap;
import java.util.function.Function;
import net.fabricmc.fabric.api.client.model.ModelProviderContext; import net.fabricmc.fabric.api.client.model.ModelProviderContext;
import net.fabricmc.fabric.api.client.model.ModelProviderException; import net.fabricmc.fabric.api.client.model.ModelProviderException;
import net.fabricmc.fabric.api.client.model.ModelVariantProvider; import net.fabricmc.fabric.api.client.model.ModelVariantProvider;
@ -12,21 +10,24 @@ import net.minecraft.client.render.model.UnbakedModel;
import net.minecraft.client.util.ModelIdentifier; import net.minecraft.client.util.ModelIdentifier;
import net.minecraft.util.registry.Registry; import net.minecraft.util.registry.Registry;
import java.util.HashMap;
import java.util.function.Function;
public class TemplateModelVariantProvider implements ModelVariantProvider { public class TemplateModelVariantProvider implements ModelVariantProvider {
private final HashMap<ModelIdentifier, UnbakedModel> variants = new HashMap<>(); private final HashMap<ModelIdentifier, UnbakedModel> variants = new HashMap<>();
public TemplateModelVariantProvider() { } public TemplateModelVariantProvider() {}
@Override @Override
public UnbakedModel loadModelVariant(ModelIdentifier modelId, ModelProviderContext context) throws ModelProviderException { public UnbakedModel loadModelVariant(ModelIdentifier modelId, ModelProviderContext context) throws ModelProviderException {
return variants.get(modelId); return variants.get(modelId);
} }
public void registerTemplateModels(Block block, BlockState itemState, Function<BlockState, AbstractModel> model) { public void registerTemplateModels(Block block, BlockState itemState, Function<BlockState, AbstractModel> model) {
for (BlockState state : block.getStateManager().getStates()) { for(BlockState state : block.getStateManager().getStates()) {
variants.put(BlockModels.getModelId(state), (SimpleUnbakedModel)() -> model.apply(state)); variants.put(BlockModels.getModelId(state), (SimpleUnbakedModel) () -> model.apply(state));
} }
variants.put(new ModelIdentifier(Registry.ITEM.getId(block.asItem()), "inventory"), (SimpleUnbakedModel)() -> model.apply(itemState)); variants.put(new ModelIdentifier(Registry.ITEM.getId(block.asItem()), "inventory"), (SimpleUnbakedModel) () -> model.apply(itemState));
} }
} }

View File

@ -1,59 +1,58 @@
package io.github.cottonmc.templates.util; package io.github.cottonmc.templates.util;
import java.util.List;
import java.util.Random;
import net.minecraft.client.texture.MissingSprite;
import it.unimi.dsi.fastutil.objects.Object2ObjectOpenHashMap; import it.unimi.dsi.fastutil.objects.Object2ObjectOpenHashMap;
import net.fabricmc.fabric.api.renderer.v1.model.ModelHelper; import net.fabricmc.fabric.api.renderer.v1.model.ModelHelper;
import net.minecraft.client.MinecraftClient; import net.minecraft.client.MinecraftClient;
import net.minecraft.client.render.model.BakedModel; import net.minecraft.client.render.model.BakedModel;
import net.minecraft.client.render.model.BakedQuad; import net.minecraft.client.render.model.BakedQuad;
import net.minecraft.client.texture.MissingSprite;
import net.minecraft.client.texture.Sprite; import net.minecraft.client.texture.Sprite;
import net.minecraft.util.Identifier; import net.minecraft.util.Identifier;
import net.minecraft.util.math.Direction; import net.minecraft.util.math.Direction;
import java.util.List;
import java.util.Random;
public class SpriteSet { public class SpriteSet {
private Object2ObjectOpenHashMap<Direction, BakedQuad> quads = new Object2ObjectOpenHashMap<>(); private Object2ObjectOpenHashMap<Direction, BakedQuad> quads = new Object2ObjectOpenHashMap<>();
private boolean isDefault = true; private boolean isDefault = true;
public static final Sprite DEFAULT = MinecraftClient.getInstance().getSpriteAtlas().getSprite(new Identifier("minecraft:block/scaffolding_top")); public static final Sprite DEFAULT = MinecraftClient.getInstance().getSpriteAtlas().getSprite(new Identifier("minecraft:block/scaffolding_top"));
public static final Sprite FALLBACK = MissingSprite.getMissingSprite(); public static final Sprite FALLBACK = MissingSprite.getMissingSprite();
public SpriteSet() { public SpriteSet() {
clear(); clear();
} }
/** Allow re-use of instances to avoid allocation in render loop */ /** Allow re-use of instances to avoid allocation in render loop */
public void clear() { public void clear() {
isDefault = true; isDefault = true;
} }
/** Allow re-use of instances to avoid allocation in render loop */ /** Allow re-use of instances to avoid allocation in render loop */
//TODO: pass in block state? //TODO: pass in block state?
public void prepare(BakedModel model, Random rand) { public void prepare(BakedModel model, Random rand) {
this.quads.clear(); this.quads.clear();
isDefault = false; isDefault = false;
// avoid Direction.values() in hot loop - for thread safety may generate new array instances // avoid Direction.values() in hot loop - for thread safety may generate new array instances
//for (Direction dir : Direction.values()) { //for (Direction dir : Direction.values()) {
for(int i = 0; i < 6; i++) { for(int i = 0; i < 6; i++) {
final Direction dir = ModelHelper.faceFromIndex(i); final Direction dir = ModelHelper.faceFromIndex(i);
List<BakedQuad> quads = model.getQuads(null, dir, rand); List<BakedQuad> quads = model.getQuads(null, dir, rand);
if (!quads.isEmpty()) this.quads.put(dir, quads.get(0)); if(!quads.isEmpty()) this.quads.put(dir, quads.get(0));
} }
} }
public Sprite getSprite(Direction dir) { public Sprite getSprite(Direction dir) {
if (isDefault) return DEFAULT; if(isDefault) return DEFAULT;
BakedQuad quad = quads.get(dir); BakedQuad quad = quads.get(dir);
if (quad == null) return FALLBACK; if(quad == null) return FALLBACK;
return quad.getSprite(); return quad.getSprite();
} }
public boolean hasColor(Direction dir) { public boolean hasColor(Direction dir) {
if (isDefault) return false; if(isDefault) return false;
BakedQuad quad = quads.get(dir); BakedQuad quad = quads.get(dir);
if (quad == null) return false; if(quad == null) return false;
return quad.hasColor(); return quad.hasColor();
} }
} }

View File

@ -6,5 +6,6 @@ import net.minecraft.world.World;
public interface StateContainer { public interface StateContainer {
BlockState getContainedState(World world, BlockPos pos); BlockState getContainedState(World world, BlockPos pos);
void setContainedState(World world, BlockPos pos, BlockState state); void setContainedState(World world, BlockPos pos, BlockState state);
} }

View File

@ -1,3 +1,3 @@
{ {
"block.templates.slope": "Slope Template" "block.templates.slope": "Slope Template"
} }

View File

@ -1,32 +1,32 @@
{ {
"parent": "minecraft:recipes/root", "parent": "minecraft:recipes/root",
"rewards": { "rewards": {
"recipes": [ "recipes": [
"minecraft:scaffolding" "minecraft:scaffolding"
] ]
}, },
"criteria": { "criteria": {
"has_bamboo": { "has_bamboo": {
"trigger": "minecraft:inventory_changed", "trigger": "minecraft:inventory_changed",
"conditions": { "conditions": {
"items": [ "items": [
{ {
"item": "minecraft:bamboo" "item": "minecraft:bamboo"
} }
] ]
} }
}, },
"has_the_recipe": { "has_the_recipe": {
"trigger": "minecraft:recipe_unlocked", "trigger": "minecraft:recipe_unlocked",
"conditions": { "conditions": {
"recipe": "templates:slope" "recipe": "templates:slope"
} }
} }
}, },
"requirements": [ "requirements": [
[ [
"has_bamboo", "has_bamboo",
"has_the_recipe" "has_the_recipe"
] ]
] ]
} }

View File

@ -1,19 +1,19 @@
{ {
"type": "minecraft:block", "type": "minecraft:block",
"pools": [ "pools": [
{ {
"rolls": 1, "rolls": 1,
"entries": [ "entries": [
{ {
"type": "minecraft:item", "type": "minecraft:item",
"name": "templates:slope" "name": "templates:slope"
} }
], ],
"conditions": [ "conditions": [
{ {
"condition": "minecraft:survives_explosion" "condition": "minecraft:survives_explosion"
} }
] ]
} }
] ]
} }

View File

@ -1,20 +1,20 @@
{ {
"type": "minecraft:crafting_shaped", "type": "minecraft:crafting_shaped",
"pattern": [ "pattern": [
"I ", "I ",
"I~ ", "I~ ",
"III" "III"
], ],
"key": { "key": {
"I": { "I": {
"item": "minecraft:bamboo" "item": "minecraft:bamboo"
}, },
"~": { "~": {
"item": "minecraft:string" "item": "minecraft:string"
} }
}, },
"result": { "result": {
"item": "templates:slope", "item": "templates:slope",
"count": 4 "count": 4
} }
} }

View File

@ -1,26 +1,25 @@
{ {
"schemaVersion": 1, "schemaVersion": 1,
"id": "templates", "id": "templates",
"version": "$version", "version": "$version",
"name": "Templates",
"name": "Templates", "icon": "assets/templates/icon.png",
"icon": "assets/templates/icon.png", "description": "An API for templated blocks",
"description": "An API for templated blocks", "licence": "MIT",
"licence": "MIT", "contact": {
"contact": { "sources": "https://github.com/CottonMC/Templates"
"sources": "https://github.com/CottonMC/Templates" },
}, "environment": "*",
"environment": "*", "entrypoints": {
"entrypoints": { "main": [
"main": [ "io.github.cottonmc.templates.Templates"
"io.github.cottonmc.templates.Templates" ],
], "client": [
"client": [ "io.github.cottonmc.templates.TemplatesClient"
"io.github.cottonmc.templates.TemplatesClient" ]
] },
}, "depends": {
"depends": { "fabricloader": ">=0.4.0",
"fabricloader": ">=0.4.0", "fabric-renderer-indigo": "*"
"fabric-renderer-indigo": "*" }
}
} }