diff --git a/common/src/main/kotlin/com/cobblemon/mod/common/CobblemonBlockEntities.kt b/common/src/main/kotlin/com/cobblemon/mod/common/CobblemonBlockEntities.kt index 4a9c487520..dcdfbffa41 100644 --- a/common/src/main/kotlin/com/cobblemon/mod/common/CobblemonBlockEntities.kt +++ b/common/src/main/kotlin/com/cobblemon/mod/common/CobblemonBlockEntities.kt @@ -8,6 +8,7 @@ package com.cobblemon.mod.common +import com.cobblemon.mod.common.block.entity.PokeCakeBlockEntity import com.cobblemon.mod.common.block.entity.BerryBlockEntity import com.cobblemon.mod.common.block.entity.HealingMachineBlockEntity import com.cobblemon.mod.common.block.entity.PCBlockEntity @@ -105,8 +106,13 @@ object CobblemonBlockEntities : PlatformRegistry>, R @JvmField val LURE_CAKE: BlockEntityType = this.create( - "lure_cake", - BlockEntityType.Builder.of(::LureCakeBlockEntity, CobblemonBlocks.LURE_CAKE).build(null) + "lure_cake", + BlockEntityType.Builder.of(::LureCakeBlockEntity, CobblemonBlocks.LURE_CAKE).build(null) + ) + @JvmField + val POKE_CAKE: BlockEntityType = this.create( + "poke_cake", + BlockEntityType.Builder.of(::PokeCakeBlockEntity, CobblemonBlocks.POKE_CAKE).build(null) ) diff --git a/common/src/main/kotlin/com/cobblemon/mod/common/CobblemonBlocks.kt b/common/src/main/kotlin/com/cobblemon/mod/common/CobblemonBlocks.kt index 666694a1d5..d3483c911d 100644 --- a/common/src/main/kotlin/com/cobblemon/mod/common/CobblemonBlocks.kt +++ b/common/src/main/kotlin/com/cobblemon/mod/common/CobblemonBlocks.kt @@ -10,8 +10,8 @@ package com.cobblemon.mod.common import com.cobblemon.mod.common.api.apricorn.Apricorn import com.cobblemon.mod.common.block.* -import com.cobblemon.mod.common.block.LecternBlock import com.cobblemon.mod.common.block.CampfireBlock +import com.cobblemon.mod.common.block.LecternBlock import com.cobblemon.mod.common.block.MintBlock.MintType import com.cobblemon.mod.common.block.chest.GildedChestBlock import com.cobblemon.mod.common.block.sign.CobblemonHangingSignBlock @@ -232,6 +232,8 @@ object CobblemonBlocks : PlatformRegistry, ResourceKey, ResourceKey() @JvmField @@ -511,8 +513,6 @@ object CobblemonItems : PlatformRegistry, ResourceKey? { + return simpleCodec(::PokeCakeBlock) + } + + override fun newBlockEntity(pos: BlockPos, state: BlockState): BlockEntity? { + return PokeCakeBlockEntity(pos, state) + } + + override fun setPlacedBy( + level: Level, + pos: BlockPos, + state: BlockState, + placer: LivingEntity?, + stack: ItemStack + ) { + super.setPlacedBy(level, pos, state, placer, stack) + + val blockEntity = level.getBlockEntity(pos) as? PokeCakeBlockEntity + blockEntity?.initializeFromItemStack(stack) + } + + override fun useWithoutItem( + state: BlockState, + level: Level, + pos: BlockPos, + player: Player, + hitResult: BlockHitResult + ): InteractionResult? { + if (level.isClientSide) { + if (eat(level, pos, player).consumesAction()) { + return InteractionResult.SUCCESS; + } + + if (player.getItemInHand(MAIN_HAND).isEmpty) { + return InteractionResult.CONSUME; + } + } + + return eat(level, pos, player); + } + + fun eat(level: LevelAccessor, pos: BlockPos, player: Player): InteractionResult { + if (!player.canEat(false)) { + return InteractionResult.PASS; + } + + player.getFoodData().eat(2, 0.1F); + level.gameEvent(player, GameEvent.EAT, pos); + + var bites = getBites(level, pos) + if (bites < 6) { + setBites(level, pos, bites + 1) + } else { + level.removeBlock(pos, false); + level.gameEvent(player, GameEvent.BLOCK_DESTROY, pos); + } + + return InteractionResult.SUCCESS; + } + + override fun getShape( + state: BlockState, + level: BlockGetter, + pos: BlockPos, + context: CollisionContext + ): VoxelShape? { + return SHAPE_BY_BITE[getBites(level, pos)] + } + + override fun getCloneItemStack( + level: LevelReader, + pos: BlockPos, + state: BlockState + ): ItemStack? { + val blockEntity = level.getBlockEntity(pos) as? PokeCakeBlockEntity ?: return ItemStack.EMPTY + return blockEntity.toItemStack() + } + + fun getBites(level: BlockGetter, pos: BlockPos): Int = (level.getBlockEntity(pos) as? PokeCakeBlockEntity)?.bites ?: 0 + fun setBites(level: BlockGetter, pos: BlockPos, bites: Int) = (level.getBlockEntity(pos) as? PokeCakeBlockEntity)?.bites = bites +} diff --git a/common/src/main/kotlin/com/cobblemon/mod/common/block/entity/PokeCakeBlockEntity.kt b/common/src/main/kotlin/com/cobblemon/mod/common/block/entity/PokeCakeBlockEntity.kt new file mode 100644 index 0000000000..581e5e62a1 --- /dev/null +++ b/common/src/main/kotlin/com/cobblemon/mod/common/block/entity/PokeCakeBlockEntity.kt @@ -0,0 +1,81 @@ +package com.cobblemon.mod.common.block.entity + +import com.cobblemon.mod.common.CobblemonBlockEntities +import com.cobblemon.mod.common.CobblemonItemComponents +import com.cobblemon.mod.common.item.components.CookingComponent +import net.minecraft.core.BlockPos +import net.minecraft.core.HolderLookup +import net.minecraft.nbt.CompoundTag +import net.minecraft.nbt.NbtOps +import net.minecraft.network.protocol.Packet +import net.minecraft.network.protocol.game.ClientGamePacketListener +import net.minecraft.network.protocol.game.ClientboundBlockEntityDataPacket +import net.minecraft.world.item.ItemStack +import net.minecraft.world.level.block.entity.BlockEntity +import net.minecraft.world.level.block.state.BlockState + +class PokeCakeBlockEntity( + pos: BlockPos, + state: BlockState +) : BlockEntity(CobblemonBlockEntities.POKE_CAKE, pos, state) { + var cookingComponent: CookingComponent? = null + var bites: Int = 0 + + fun initializeFromItemStack(itemStack: ItemStack) { + cookingComponent = itemStack.get(CobblemonItemComponents.COOKING_COMPONENT) + } + + override fun saveAdditional( + tag: CompoundTag, + registries: HolderLookup.Provider + ) { + super.saveAdditional(tag, registries) + + tag.putInt("Bites", bites) + cookingComponent?.let { component -> + CobblemonItemComponents.COOKING_COMPONENT.codec() + ?.encodeStart(NbtOps.INSTANCE, component) + ?.result() + ?.ifPresent { encodedTag -> + tag.put("CookingComponent", encodedTag) + } + } + } + + override fun loadAdditional( + tag: CompoundTag, + registries: HolderLookup.Provider + ) { + super.loadAdditional(tag, registries) + + bites = tag.getInt("Bites") + if (tag.contains("CookingComponent")) { + CobblemonItemComponents.COOKING_COMPONENT.codec() + ?.parse(NbtOps.INSTANCE, tag.getCompound("CookingComponent")) + ?.result() + ?.ifPresent { component -> + cookingComponent = component + } + } + } + + override fun getUpdatePacket(): Packet? { + return ClientboundBlockEntityDataPacket.create(this) + } + + override fun getUpdateTag(registries: HolderLookup.Provider): CompoundTag? { + val tag = CompoundTag() + saveAdditional(tag, registries) + return tag + } + + fun toItemStack(): ItemStack { + val stack = ItemStack(this.blockState.block) + cookingComponent?.let { component -> + stack.getComponents().apply { + stack.set(CobblemonItemComponents.COOKING_COMPONENT, component) + } + } + return stack + } +} \ No newline at end of file diff --git a/common/src/main/kotlin/com/cobblemon/mod/common/client/CobblemonClient.kt b/common/src/main/kotlin/com/cobblemon/mod/common/client/CobblemonClient.kt index 650dc3f1b5..f63013bb7a 100644 --- a/common/src/main/kotlin/com/cobblemon/mod/common/client/CobblemonClient.kt +++ b/common/src/main/kotlin/com/cobblemon/mod/common/client/CobblemonClient.kt @@ -267,6 +267,7 @@ object CobblemonClient { CobblemonBlocks.SACCHARINE_WALL_HANGING_SIGN, CobblemonBlocks.SACCHARINE_SAPLING, CobblemonBlocks.LURE_CAKE, + CobblemonBlocks.POKE_CAKE, CobblemonBlocks.LECTERN, CobblemonBlocks.CAMPFIRE ) @@ -304,6 +305,7 @@ object CobblemonClient { this.implementation.registerBlockEntityRenderer(CobblemonBlockEntities.LECTERN, ::LecternBlockEntityRenderer) this.implementation.registerBlockEntityRenderer(CobblemonBlockEntities.CAMPFIRE, ::CampfireBlockEntityRenderer) this.implementation.registerBlockEntityRenderer(CobblemonBlockEntities.LURE_CAKE, ::LureCakeBlockEntityRenderer) + this.implementation.registerBlockEntityRenderer(CobblemonBlockEntities.POKE_CAKE, ::PokeCakeBlockEntityRenderer) } private fun registerEntityRenderers() { diff --git a/common/src/main/kotlin/com/cobblemon/mod/common/client/render/block/CakeRendererHelper.kt b/common/src/main/kotlin/com/cobblemon/mod/common/client/render/block/CakeRendererHelper.kt new file mode 100644 index 0000000000..7a24af8dab --- /dev/null +++ b/common/src/main/kotlin/com/cobblemon/mod/common/client/render/block/CakeRendererHelper.kt @@ -0,0 +1,226 @@ +package com.cobblemon.mod.common.client.render.block + +import com.cobblemon.mod.common.api.cooking.getColor +import com.cobblemon.mod.common.block.entity.LureCakeBlockEntity +import com.cobblemon.mod.common.item.components.CookingComponent +import com.mojang.blaze3d.vertex.PoseStack +import com.mojang.blaze3d.vertex.VertexConsumer +import com.mojang.math.Axis +import net.minecraft.client.Minecraft +import net.minecraft.client.renderer.MultiBufferSource +import net.minecraft.client.renderer.RenderType +import net.minecraft.client.renderer.texture.TextureAtlasSprite +import net.minecraft.resources.ResourceLocation +import net.minecraft.world.inventory.InventoryMenu.BLOCK_ATLAS +import net.minecraft.world.level.block.state.BlockState +import org.joml.Vector3d + +const val PIXEL_SHIFT = 1.0 / 16.0 +const val WHITE_OPAQUE_COLOR = 0xFFFFFFFF.toInt() + +const val ATLAS_START = 0.0f +const val ATLAS_END = 1.0f +const val HEIGHT = 0.5f +const val TOP_LAYER_HEIGHT = 0.5625f +const val BOTTOM_LAYER_HEIGHT = 0.0f + +val TOP_LAYER: TextureAtlasSprite = loadTexture("block/poke_snack_top_layer2") +val CHERRY_LAYER: TextureAtlasSprite = loadTexture("block/poke_snack_top_layer3") +val SIDE_LAYER_BOTTOM: TextureAtlasSprite = loadTexture("block/poke_snack_side_layer1") +val SIDE_LAYER_TOP: TextureAtlasSprite = loadTexture("block/poke_snack_side_layer2") +val SIDE_LAYER_MIDDLE: TextureAtlasSprite = loadTexture("block/poke_snack_side_layer3") +val BOTTOM_LAYER: TextureAtlasSprite = loadTexture("block/poke_snack_bottom_layer1") +val FIRST_INNER_LAYER: TextureAtlasSprite = loadTexture("block/poke_snack_inner_layer1") +val SECOND_INNER_LAYER: TextureAtlasSprite = loadTexture("block/poke_snack_inner_layer2") +val THIRD_INNER_LAYER: TextureAtlasSprite = loadTexture("block/poke_snack_inner_layer3") + +fun loadTexture(textureName: String): TextureAtlasSprite { + return Minecraft.getInstance().getTextureAtlas(BLOCK_ATLAS).apply(ResourceLocation("cobblemon", textureName)) +} + +fun renderCake( + cookingComponent: CookingComponent?, + poseStack: PoseStack, + multiBufferSource: MultiBufferSource, + light: Int, + bites: Int, +) { + val maxBites = 7f + val cakeIsFull = bites.toFloat() == 0f + val percentageToRender = if (cakeIsFull) 1.0f else PIXEL_SHIFT.toFloat() + (PIXEL_SHIFT.toFloat() * 2f * (maxBites - bites).toFloat()) + val clippedWidth = (ATLAS_END - ATLAS_START) * percentageToRender + val uClipped = TOP_LAYER.u0 + (TOP_LAYER.u1 - TOP_LAYER.u0) * percentageToRender + + val vertexConsumer = multiBufferSource.getBuffer(RenderType.cutout()) + val primaryColor = cookingComponent?.seasoning1?.color?.let { getColor(it) } ?: WHITE_OPAQUE_COLOR + val secondaryColor = cookingComponent?.seasoning2?.color?.let { getColor(it) } ?: WHITE_OPAQUE_COLOR + val tertiaryColor = cookingComponent?.seasoning3?.color?.let { getColor(it) } ?: WHITE_OPAQUE_COLOR + + poseStack.pushPose() + poseStack.translate(0.5, 0.5, 0.5) + poseStack.mulPose(Axis.YP.rotationDegrees(180f)) + poseStack.translate(-0.5, -0.5, -0.5) + + poseStack.pushPose() + drawQuad( + vertexConsumer, poseStack, + ATLAS_START, TOP_LAYER_HEIGHT, ATLAS_START, clippedWidth, TOP_LAYER_HEIGHT, ATLAS_END, + TOP_LAYER.u0, TOP_LAYER.v0, uClipped, TOP_LAYER.v1, + light, secondaryColor + ) + + drawQuad( + vertexConsumer, poseStack, + ATLAS_START, TOP_LAYER_HEIGHT, ATLAS_START, clippedWidth, TOP_LAYER_HEIGHT, ATLAS_END, + CHERRY_LAYER.u0, CHERRY_LAYER.v0, uClipped, CHERRY_LAYER.v1, + light, primaryColor + ) + poseStack.popPose() + + val translations = arrayOf( + Vector3d(-1.0, 1.0, 0.5 - PIXEL_SHIFT), + Vector3d(0.0, 1.0, 0.5 - PIXEL_SHIFT), + Vector3d(0.0, 1.0, -0.5 - PIXEL_SHIFT), + Vector3d(-1.0, 1.0, -0.5 - PIXEL_SHIFT), + ) + + val rotationsY = arrayOf( + Axis.YP.rotationDegrees(90f), + Axis.YP.rotationDegrees(0f), + Axis.YP.rotationDegrees(-90f), + Axis.YP.rotationDegrees(-180f) + ) + + for (i in translations.indices) { + poseStack.pushPose() + poseStack.mulPose(rotationsY[i]) + poseStack.translate(translations[i].x, translations[i].y, translations[i].z) + poseStack.mulPose(Axis.XP.rotationDegrees(90f)) + + if (i == 0 && !cakeIsFull) { + poseStack.translate(0.0, -bites * PIXEL_SHIFT * 2, 0.0) + drawQuad( + vertexConsumer, poseStack, + ATLAS_START, HEIGHT, ATLAS_START, ATLAS_END, HEIGHT, ATLAS_END, + FIRST_INNER_LAYER.u0, FIRST_INNER_LAYER.v0, FIRST_INNER_LAYER.u1, FIRST_INNER_LAYER.v1, + light, tertiaryColor + ) + drawQuad( + vertexConsumer, poseStack, + ATLAS_START, HEIGHT, ATLAS_START, ATLAS_END, HEIGHT, ATLAS_END, + SECOND_INNER_LAYER.u0, SECOND_INNER_LAYER.v0, SECOND_INNER_LAYER.u1, SECOND_INNER_LAYER.v1, + light, secondaryColor + ) + drawQuad( + vertexConsumer, poseStack, + ATLAS_START, HEIGHT, ATLAS_START, ATLAS_END, HEIGHT, ATLAS_END, + THIRD_INNER_LAYER.u0, THIRD_INNER_LAYER.v0, THIRD_INNER_LAYER.u1, THIRD_INNER_LAYER.v1, + light, primaryColor + ) + } else if (i == 0 || i == 1) { + drawQuad( + vertexConsumer, poseStack, + ATLAS_START, HEIGHT, ATLAS_START, clippedWidth, HEIGHT, ATLAS_END, + SIDE_LAYER_BOTTOM.u0, SIDE_LAYER_BOTTOM.v0, uClipped, SIDE_LAYER_BOTTOM.v1, + light, tertiaryColor + ) + drawQuad( + vertexConsumer, poseStack, + ATLAS_START, HEIGHT, ATLAS_START, clippedWidth, HEIGHT, ATLAS_END, + SIDE_LAYER_TOP.u0, SIDE_LAYER_TOP.v0, uClipped, SIDE_LAYER_TOP.v1, + light, secondaryColor + ) + drawQuad( + vertexConsumer, poseStack, + ATLAS_START, HEIGHT, ATLAS_START, clippedWidth, HEIGHT, ATLAS_END, + SIDE_LAYER_MIDDLE.u0, SIDE_LAYER_MIDDLE.v0, uClipped, SIDE_LAYER_MIDDLE.v1, + light, primaryColor + ) + } else if (i == 2) { + drawQuad( + vertexConsumer, poseStack, + ATLAS_START, HEIGHT, ATLAS_START, ATLAS_END, HEIGHT, ATLAS_END, + SIDE_LAYER_BOTTOM.u0, SIDE_LAYER_BOTTOM.v0, SIDE_LAYER_BOTTOM.u1, SIDE_LAYER_BOTTOM.v1, + light, tertiaryColor + ) + drawQuad( + vertexConsumer, poseStack, + ATLAS_START, HEIGHT, ATLAS_START, ATLAS_END, HEIGHT, ATLAS_END, + SIDE_LAYER_TOP.u0, SIDE_LAYER_TOP.v0, SIDE_LAYER_TOP.u1, SIDE_LAYER_TOP.v1, + light, secondaryColor + ) + drawQuad( + vertexConsumer, poseStack, + ATLAS_START, HEIGHT, ATLAS_START, ATLAS_END, HEIGHT, ATLAS_END, + SIDE_LAYER_TOP.u0, SIDE_LAYER_MIDDLE.v0, SIDE_LAYER_MIDDLE.u1, SIDE_LAYER_MIDDLE.v1, + light, primaryColor + ) + } else if (i == 3) { + val clippedStartX = ATLAS_START + (ATLAS_END - ATLAS_START) * (1 - percentageToRender) + val clippedUStart = SIDE_LAYER_BOTTOM.u0 + (SIDE_LAYER_BOTTOM.u1 - SIDE_LAYER_BOTTOM.u0) * (1 - percentageToRender) + + drawQuad( + vertexConsumer, poseStack, + clippedStartX, HEIGHT, ATLAS_START, ATLAS_END, HEIGHT, ATLAS_END, + clippedUStart, SIDE_LAYER_BOTTOM.v0, SIDE_LAYER_BOTTOM.u1, SIDE_LAYER_BOTTOM.v1, + light, tertiaryColor + ) + drawQuad( + vertexConsumer, poseStack, + clippedStartX, HEIGHT, ATLAS_START, ATLAS_END, HEIGHT, ATLAS_END, + clippedUStart, SIDE_LAYER_TOP.v0, SIDE_LAYER_TOP.u1, SIDE_LAYER_TOP.v1, + light, secondaryColor + ) + drawQuad( + vertexConsumer, poseStack, + clippedStartX, HEIGHT, ATLAS_START, ATLAS_END, HEIGHT, ATLAS_END, + clippedUStart, SIDE_LAYER_MIDDLE.v0, SIDE_LAYER_MIDDLE.u1, SIDE_LAYER_MIDDLE.v1, + light, primaryColor + ) + } + + poseStack.popPose() + } + + poseStack.pushPose() + poseStack.translate(0.5, 0.0, 0.5) + poseStack.mulPose(Axis.XP.rotationDegrees(180f)) + poseStack.translate(-0.5, 0.0, -0.5) + drawQuad( + vertexConsumer, poseStack, + ATLAS_START, BOTTOM_LAYER_HEIGHT, ATLAS_START, clippedWidth, BOTTOM_LAYER_HEIGHT, ATLAS_END, + BOTTOM_LAYER.u0, BOTTOM_LAYER.v0, uClipped, BOTTOM_LAYER.v1, + light, tertiaryColor + ) + poseStack.popPose() + + poseStack.popPose() +} + +private fun drawQuad( + builder: VertexConsumer, + poseStack: PoseStack, + x0: Float, y0: Float, z0: Float, + x1: Float, y1: Float, z1: Float, + u0: Float, v0: Float, u1: Float, v1: Float, + packedLight: Int, color: Int, +) { + drawVertex(builder, poseStack, x0, y0, z0, u0, v0, packedLight, color) + drawVertex(builder, poseStack, x0, y1, z1, u0, v1, packedLight, color) + drawVertex(builder, poseStack, x1, y1, z1, u1, v1, packedLight, color) + drawVertex(builder, poseStack, x1, y0, z0, u1, v0, packedLight, color) +} + +private fun drawVertex( + builder: VertexConsumer, + poseStack: PoseStack, + x: Float, y: Float, z: Float, + u: Float, v: Float, + packedLight: Int, color: Int +) { + builder.addVertex(poseStack.last().pose(), x, y, z) + .setColor(color) + .setUv(u, v) + .setLight(packedLight) + .setNormal(0f, 1f, 0f) +} \ No newline at end of file diff --git a/common/src/main/kotlin/com/cobblemon/mod/common/client/render/block/LureCakeBlockEntityRenderer.kt b/common/src/main/kotlin/com/cobblemon/mod/common/client/render/block/LureCakeBlockEntityRenderer.kt index c4035f24a0..ff1c8b7d18 100644 --- a/common/src/main/kotlin/com/cobblemon/mod/common/client/render/block/LureCakeBlockEntityRenderer.kt +++ b/common/src/main/kotlin/com/cobblemon/mod/common/client/render/block/LureCakeBlockEntityRenderer.kt @@ -8,50 +8,15 @@ package com.cobblemon.mod.common.client.render.block -import com.cobblemon.mod.common.api.cooking.getColor import com.cobblemon.mod.common.block.LureCakeBlock.Companion.BITES import com.cobblemon.mod.common.block.entity.LureCakeBlockEntity import com.mojang.blaze3d.vertex.PoseStack -import com.mojang.blaze3d.vertex.VertexConsumer -import com.mojang.math.Axis -import net.minecraft.client.Minecraft import net.minecraft.client.renderer.MultiBufferSource -import net.minecraft.client.renderer.RenderType import net.minecraft.client.renderer.blockentity.BlockEntityRenderer import net.minecraft.client.renderer.blockentity.BlockEntityRendererProvider -import net.minecraft.client.renderer.texture.TextureAtlasSprite -import net.minecraft.resources.ResourceLocation -import net.minecraft.world.inventory.InventoryMenu.BLOCK_ATLAS -import net.minecraft.world.level.block.state.BlockState -import org.joml.Vector3d class LureCakeBlockEntityRenderer(ctx: BlockEntityRendererProvider.Context) : BlockEntityRenderer { - companion object { - const val PIXEL_SHIFT = 1.0 / 16.0 - const val WHITE_OPAQUE_COLOR = 0xFFFFFFFF.toInt() - - const val ATLAS_START = 0.0f - const val ATLAS_END = 1.0f - const val HEIGHT = 0.5f - const val TOP_LAYER_HEIGHT = 0.5625f - const val BOTTOM_LAYER_HEIGHT = 0.0f - - val TOP_LAYER: TextureAtlasSprite = loadTexture("block/poke_snack_top_layer2") - val CHERRY_LAYER: TextureAtlasSprite = loadTexture("block/poke_snack_top_layer3") - val SIDE_LAYER_BOTTOM: TextureAtlasSprite = loadTexture("block/poke_snack_side_layer1") - val SIDE_LAYER_TOP: TextureAtlasSprite = loadTexture("block/poke_snack_side_layer2") - val SIDE_LAYER_MIDDLE: TextureAtlasSprite = loadTexture("block/poke_snack_side_layer3") - val BOTTOM_LAYER: TextureAtlasSprite = loadTexture("block/poke_snack_bottom_layer1") - val FIRST_INNER_LAYER: TextureAtlasSprite = loadTexture("block/poke_snack_inner_layer1") - val SECOND_INNER_LAYER: TextureAtlasSprite = loadTexture("block/poke_snack_inner_layer2") - val THIRD_INNER_LAYER: TextureAtlasSprite = loadTexture("block/poke_snack_inner_layer3") - - fun loadTexture(textureName: String): TextureAtlasSprite { - return Minecraft.getInstance().getTextureAtlas(BLOCK_ATLAS).apply(ResourceLocation("cobblemon", textureName)) - } - } - override fun render( blockEntity: LureCakeBlockEntity, tickDelta: Float, @@ -60,190 +25,6 @@ class LureCakeBlockEntityRenderer(ctx: BlockEntityRendererProvider.Context) : Bl light: Int, overlay: Int ) { - val blockState: BlockState = blockEntity.blockState - if (blockState.isAir) { - return - } - - val bites = blockState.getValue(BITES).toFloat() - val maxBites = 7f - val cakeIsFull = bites == 0f - val percentageToRender = if (cakeIsFull) 1.0f else PIXEL_SHIFT.toFloat() + (PIXEL_SHIFT.toFloat() * 2f * (maxBites - bites).toFloat()) - val clippedWidth = (ATLAS_END - ATLAS_START) * percentageToRender - val uClipped = TOP_LAYER.u0 + (TOP_LAYER.u1 - TOP_LAYER.u0) * percentageToRender - - val vertexConsumer = multiBufferSource.getBuffer(RenderType.cutout()) - val cookingComponent = blockEntity.cookingComponent - val primaryColor = cookingComponent?.seasoning1?.color?.let { getColor(it) } ?: WHITE_OPAQUE_COLOR - val secondaryColor = cookingComponent?.seasoning2?.color?.let { getColor(it) } ?: WHITE_OPAQUE_COLOR - val tertiaryColor = cookingComponent?.seasoning3?.color?.let { getColor(it) } ?: WHITE_OPAQUE_COLOR - - poseStack.pushPose() - poseStack.translate(0.5, 0.5, 0.5) - poseStack.mulPose(Axis.YP.rotationDegrees(180f)) - poseStack.translate(-0.5, -0.5, -0.5) - - poseStack.pushPose() - drawQuad( - vertexConsumer, poseStack, - ATLAS_START, TOP_LAYER_HEIGHT, ATLAS_START, clippedWidth, TOP_LAYER_HEIGHT, ATLAS_END, - TOP_LAYER.u0, TOP_LAYER.v0, uClipped, TOP_LAYER.v1, - light, secondaryColor - ) - - drawQuad( - vertexConsumer, poseStack, - ATLAS_START, TOP_LAYER_HEIGHT, ATLAS_START, clippedWidth, TOP_LAYER_HEIGHT, ATLAS_END, - CHERRY_LAYER.u0, CHERRY_LAYER.v0, uClipped, CHERRY_LAYER.v1, - light, primaryColor - ) - poseStack.popPose() - - val translations = arrayOf( - Vector3d(-1.0, 1.0, 0.5 - PIXEL_SHIFT), - Vector3d(0.0, 1.0, 0.5 - PIXEL_SHIFT), - Vector3d(0.0, 1.0, -0.5 - PIXEL_SHIFT), - Vector3d(-1.0, 1.0, -0.5 - PIXEL_SHIFT), - ) - - val rotationsY = arrayOf( - Axis.YP.rotationDegrees(90f), - Axis.YP.rotationDegrees(0f), - Axis.YP.rotationDegrees(-90f), - Axis.YP.rotationDegrees(-180f) - ) - - for (i in translations.indices) { - poseStack.pushPose() - poseStack.mulPose(rotationsY[i]) - poseStack.translate(translations[i].x, translations[i].y, translations[i].z) - poseStack.mulPose(Axis.XP.rotationDegrees(90f)) - - if (i == 0 && !cakeIsFull) { - poseStack.translate(0.0, -bites * PIXEL_SHIFT * 2, 0.0) - drawQuad( - vertexConsumer, poseStack, - ATLAS_START, HEIGHT, ATLAS_START, ATLAS_END, HEIGHT, ATLAS_END, - FIRST_INNER_LAYER.u0, FIRST_INNER_LAYER.v0, FIRST_INNER_LAYER.u1, FIRST_INNER_LAYER.v1, - light, tertiaryColor - ) - drawQuad( - vertexConsumer, poseStack, - ATLAS_START, HEIGHT, ATLAS_START, ATLAS_END, HEIGHT, ATLAS_END, - SECOND_INNER_LAYER.u0, SECOND_INNER_LAYER.v0, SECOND_INNER_LAYER.u1, SECOND_INNER_LAYER.v1, - light, secondaryColor - ) - drawQuad( - vertexConsumer, poseStack, - ATLAS_START, HEIGHT, ATLAS_START, ATLAS_END, HEIGHT, ATLAS_END, - THIRD_INNER_LAYER.u0, THIRD_INNER_LAYER.v0, THIRD_INNER_LAYER.u1, THIRD_INNER_LAYER.v1, - light, primaryColor - ) - } else if (i == 0 || i == 1) { - drawQuad( - vertexConsumer, poseStack, - ATLAS_START, HEIGHT, ATLAS_START, clippedWidth, HEIGHT, ATLAS_END, - SIDE_LAYER_BOTTOM.u0, SIDE_LAYER_BOTTOM.v0, uClipped, SIDE_LAYER_BOTTOM.v1, - light, tertiaryColor - ) - drawQuad( - vertexConsumer, poseStack, - ATLAS_START, HEIGHT, ATLAS_START, clippedWidth, HEIGHT, ATLAS_END, - SIDE_LAYER_TOP.u0, SIDE_LAYER_TOP.v0, uClipped, SIDE_LAYER_TOP.v1, - light, secondaryColor - ) - drawQuad( - vertexConsumer, poseStack, - ATLAS_START, HEIGHT, ATLAS_START, clippedWidth, HEIGHT, ATLAS_END, - SIDE_LAYER_MIDDLE.u0, SIDE_LAYER_MIDDLE.v0, uClipped, SIDE_LAYER_MIDDLE.v1, - light, primaryColor - ) - } else if (i == 2) { - drawQuad( - vertexConsumer, poseStack, - ATLAS_START, HEIGHT, ATLAS_START, ATLAS_END, HEIGHT, ATLAS_END, - SIDE_LAYER_BOTTOM.u0, SIDE_LAYER_BOTTOM.v0, SIDE_LAYER_BOTTOM.u1, SIDE_LAYER_BOTTOM.v1, - light, tertiaryColor - ) - drawQuad( - vertexConsumer, poseStack, - ATLAS_START, HEIGHT, ATLAS_START, ATLAS_END, HEIGHT, ATLAS_END, - SIDE_LAYER_TOP.u0, SIDE_LAYER_TOP.v0, SIDE_LAYER_TOP.u1, SIDE_LAYER_TOP.v1, - light, secondaryColor - ) - drawQuad( - vertexConsumer, poseStack, - ATLAS_START, HEIGHT, ATLAS_START, ATLAS_END, HEIGHT, ATLAS_END, - SIDE_LAYER_TOP.u0, SIDE_LAYER_MIDDLE.v0, SIDE_LAYER_MIDDLE.u1, SIDE_LAYER_MIDDLE.v1, - light, primaryColor - ) - } else if (i == 3) { - val clippedStartX = ATLAS_START + (ATLAS_END - ATLAS_START) * (1 - percentageToRender) - val clippedUStart = SIDE_LAYER_BOTTOM.u0 + (SIDE_LAYER_BOTTOM.u1 - SIDE_LAYER_BOTTOM.u0) * (1 - percentageToRender) - - drawQuad( - vertexConsumer, poseStack, - clippedStartX, HEIGHT, ATLAS_START, ATLAS_END, HEIGHT, ATLAS_END, - clippedUStart, SIDE_LAYER_BOTTOM.v0, SIDE_LAYER_BOTTOM.u1, SIDE_LAYER_BOTTOM.v1, - light, tertiaryColor - ) - drawQuad( - vertexConsumer, poseStack, - clippedStartX, HEIGHT, ATLAS_START, ATLAS_END, HEIGHT, ATLAS_END, - clippedUStart, SIDE_LAYER_TOP.v0, SIDE_LAYER_TOP.u1, SIDE_LAYER_TOP.v1, - light, secondaryColor - ) - drawQuad( - vertexConsumer, poseStack, - clippedStartX, HEIGHT, ATLAS_START, ATLAS_END, HEIGHT, ATLAS_END, - clippedUStart, SIDE_LAYER_MIDDLE.v0, SIDE_LAYER_MIDDLE.u1, SIDE_LAYER_MIDDLE.v1, - light, primaryColor - ) - } - - poseStack.popPose() - } - - poseStack.pushPose() - poseStack.translate(0.5, 0.0, 0.5) - poseStack.mulPose(Axis.XP.rotationDegrees(180f)) - poseStack.translate(-0.5, 0.0, -0.5) - drawQuad( - vertexConsumer, poseStack, - ATLAS_START, BOTTOM_LAYER_HEIGHT, ATLAS_START, clippedWidth, BOTTOM_LAYER_HEIGHT, ATLAS_END, - BOTTOM_LAYER.u0, BOTTOM_LAYER.v0, uClipped, BOTTOM_LAYER.v1, - light, tertiaryColor - ) - poseStack.popPose() - - poseStack.popPose() - } - - private fun drawQuad( - builder: VertexConsumer, - poseStack: PoseStack, - x0: Float, y0: Float, z0: Float, - x1: Float, y1: Float, z1: Float, - u0: Float, v0: Float, u1: Float, v1: Float, - packedLight: Int, color: Int, - ) { - drawVertex(builder, poseStack, x0, y0, z0, u0, v0, packedLight, color) - drawVertex(builder, poseStack, x0, y1, z1, u0, v1, packedLight, color) - drawVertex(builder, poseStack, x1, y1, z1, u1, v1, packedLight, color) - drawVertex(builder, poseStack, x1, y0, z0, u1, v0, packedLight, color) - } - - private fun drawVertex( - builder: VertexConsumer, - poseStack: PoseStack, - x: Float, y: Float, z: Float, - u: Float, v: Float, - packedLight: Int, color: Int - ) { - builder.addVertex(poseStack.last().pose(), x, y, z) - .setColor(color) - .setUv(u, v) - .setLight(packedLight) - .setNormal(0f, 1f, 0f) + renderCake(blockEntity.cookingComponent, poseStack, multiBufferSource, light, blockEntity.blockState.getValue(BITES)) } } \ No newline at end of file diff --git a/common/src/main/kotlin/com/cobblemon/mod/common/client/render/block/PokeCakeBlockEntityRenderer.kt b/common/src/main/kotlin/com/cobblemon/mod/common/client/render/block/PokeCakeBlockEntityRenderer.kt new file mode 100644 index 0000000000..c4922809fc --- /dev/null +++ b/common/src/main/kotlin/com/cobblemon/mod/common/client/render/block/PokeCakeBlockEntityRenderer.kt @@ -0,0 +1,22 @@ +package com.cobblemon.mod.common.client.render.block + +import com.cobblemon.mod.common.block.entity.PokeCakeBlockEntity +import com.mojang.blaze3d.vertex.PoseStack +import net.minecraft.client.renderer.MultiBufferSource +import net.minecraft.client.renderer.blockentity.BlockEntityRenderer +import net.minecraft.client.renderer.blockentity.BlockEntityRendererProvider + +class PokeCakeBlockEntityRenderer(ctx: BlockEntityRendererProvider.Context) : BlockEntityRenderer { + + override fun render( + blockEntity: PokeCakeBlockEntity, + partialTick: Float, + poseStack: PoseStack, + bufferSource: MultiBufferSource, + packedLight: Int, + packedOverlay: Int + ) { + val cookingComponent = blockEntity.cookingComponent + renderCake(cookingComponent, poseStack, bufferSource, packedLight, blockEntity.bites) + } +} \ No newline at end of file diff --git a/common/src/main/resources/assets/cobblemon/blockstates/poke_cake.json b/common/src/main/resources/assets/cobblemon/blockstates/poke_cake.json new file mode 100644 index 0000000000..c0c395d7a8 --- /dev/null +++ b/common/src/main/resources/assets/cobblemon/blockstates/poke_cake.json @@ -0,0 +1,7 @@ +{ + "variants": { + "": { + "model": "builtin/entity" + } + } +} \ No newline at end of file diff --git a/common/src/main/resources/data/cobblemon/recipe/cooking_pot/poke_cake_from_cooking_pot.json b/common/src/main/resources/data/cobblemon/recipe/cooking_pot/poke_cake_from_cooking_pot.json new file mode 100644 index 0000000000..fe1e21deb2 --- /dev/null +++ b/common/src/main/resources/data/cobblemon/recipe/cooking_pot/poke_cake_from_cooking_pot.json @@ -0,0 +1,12 @@ +{ + "type": "cobblemon:cooking_pot_shapeless", + "category": "foods", + "ingredients": [ + { + "item": "minecraft:cake" + } + ], + "result": { + "id": "cobblemon:poke_cake" + } +} \ No newline at end of file