package mods.betterfoliage.render.block.vanilla import mods.betterfoliage.BetterFoliage import mods.betterfoliage.BetterFoliageMod import mods.betterfoliage.config.Config import mods.betterfoliage.config.SALTWATER_BIOMES import mods.betterfoliage.config.SAND_BLOCKS import mods.betterfoliage.model.HalfBakedSpecialWrapper import mods.betterfoliage.model.HalfBakedWrapperKey import mods.betterfoliage.model.Quad import mods.betterfoliage.model.SpecialRenderModel import mods.betterfoliage.model.SpriteSetDelegate import mods.betterfoliage.model.bake import mods.betterfoliage.model.buildTufts import mods.betterfoliage.model.transform import mods.betterfoliage.model.tuftModelSet import mods.betterfoliage.model.tuftShapeSet import mods.betterfoliage.render.lighting.LightingPreferredFace import mods.betterfoliage.render.pipeline.RenderCtxBase import mods.betterfoliage.resource.discovery.AbstractModelDiscovery import mods.betterfoliage.resource.discovery.BakeWrapperManager import mods.betterfoliage.resource.discovery.ModelBakingContext import mods.betterfoliage.resource.discovery.ModelDiscoveryContext import mods.betterfoliage.util.Atlas import mods.betterfoliage.util.LazyInvalidatable import mods.betterfoliage.util.Rotation import mods.betterfoliage.util.allDirections import mods.betterfoliage.util.get import mods.betterfoliage.util.mapArray import mods.betterfoliage.util.randomB import mods.betterfoliage.util.randomD import mods.betterfoliage.util.randomI import net.minecraft.block.material.Material import net.minecraft.client.renderer.RenderType import net.minecraft.client.renderer.RenderTypeLookup import net.minecraft.client.renderer.model.BlockModel import net.minecraft.util.Direction import net.minecraft.util.Direction.UP import net.minecraft.util.ResourceLocation object StandardSandDiscovery : AbstractModelDiscovery() { override fun processModel(ctx: ModelDiscoveryContext) { if (ctx.getUnbaked() is BlockModel && ctx.blockState.block in SAND_BLOCKS) { BetterFoliage.blockTypes.dirt.add(ctx.blockState) ctx.addReplacement(StandardSandKey) RenderTypeLookup.setRenderLayer(ctx.blockState.block, RenderType.cutoutMipped()) } super.processModel(ctx) } } object StandardSandKey : HalfBakedWrapperKey() { override fun bake(ctx: ModelBakingContext, wrapped: SpecialRenderModel) = StandardSandModel(wrapped) } class StandardSandModel( wrapped: SpecialRenderModel ) : HalfBakedSpecialWrapper(wrapped) { val coralLighting = Direction.values().mapArray { LightingPreferredFace(it) } override fun render(ctx: RenderCtxBase, noDecorations: Boolean) { super.render(ctx, noDecorations) if (noDecorations || !Config.enabled || !Config.coral.enabled(ctx.random)) return if (ctx.biome?.biomeCategory !in SALTWATER_BIOMES) return allDirections.filter { ctx.random.nextInt(64) < Config.coral.chance }.forEach { face -> val isWater = ctx.state(face).material == Material.WATER val isDeepWater = isWater && ctx.offset(face).state(UP).material == Material.WATER if (isDeepWater) { ctx.vertexLighter = coralLighting[face] ctx.renderQuads(coralCrustModels[face][ctx.random]) ctx.renderQuads(coralTuftModels[face][ctx.random]) } } } companion object { val coralTuftSprites by SpriteSetDelegate(Atlas.BLOCKS) { idx -> ResourceLocation(BetterFoliageMod.MOD_ID, "blocks/better_coral_$idx") } val coralCrustSprites by SpriteSetDelegate(Atlas.BLOCKS) { idx -> ResourceLocation(BetterFoliageMod.MOD_ID, "blocks/better_crust_$idx") } val coralTuftModels by LazyInvalidatable(BakeWrapperManager) { val shapes = Config.coral.let { tuftShapeSet(it.size, 1.0, 1.0, it.hOffset) } allDirections.mapArray { face -> tuftModelSet(shapes, -1) { coralTuftSprites[randomI()] } .transform { rotate(Rotation.fromUp[face]) } .buildTufts() } } val coralCrustModels by LazyInvalidatable(BakeWrapperManager) { allDirections.map { face -> Array(64) { idx -> listOf( Quad.horizontalRectangle(x1 = -0.5, x2 = 0.5, z1 = -0.5, z2 = 0.5, y = 0.0) .scale(Config.coral.crustSize) .move(0.5 + randomD(0.01, Config.coral.vOffset) to UP) .rotate(Rotation.fromUp[face]) .mirrorUV(randomB(), randomB()).rotateUV(randomI(max = 4)) .sprite(coralCrustSprites[idx]).colorAndIndex(null) ).bake(applyDiffuseLighting = false) } }.toTypedArray() } } }