port to MC 1.8
This commit is contained in:
@@ -1,11 +1,35 @@
|
||||
package mods.betterfoliage.client.render
|
||||
|
||||
import mods.betterfoliage.client.config.BlockMatcher
|
||||
import mods.betterfoliage.client.render.AbstractRenderColumn.BlockType.*
|
||||
import mods.betterfoliage.client.render.AbstractRenderColumn.QuadrantType.*
|
||||
import mods.octarinecore.client.render.*
|
||||
import net.minecraft.block.Block
|
||||
import net.minecraft.client.renderer.RenderBlocks
|
||||
import net.minecraftforge.common.util.ForgeDirection.*
|
||||
import mods.octarinecore.client.resource.BlockTextureInspector
|
||||
import mods.octarinecore.common.Int3
|
||||
import mods.octarinecore.common.Rotation
|
||||
import mods.octarinecore.common.face
|
||||
import mods.octarinecore.common.rot
|
||||
import net.minecraft.block.state.IBlockState
|
||||
import net.minecraft.client.renderer.BlockRendererDispatcher
|
||||
import net.minecraft.client.renderer.WorldRenderer
|
||||
import net.minecraft.client.renderer.texture.TextureAtlasSprite
|
||||
import net.minecraft.client.renderer.texture.TextureMap
|
||||
import net.minecraft.util.EnumFacing
|
||||
import net.minecraft.util.EnumFacing.*
|
||||
import net.minecraft.util.EnumWorldBlockLayer
|
||||
|
||||
data class ColumnInfo(val topTexture: TextureAtlasSprite,
|
||||
val bottomTexture: TextureAtlasSprite,
|
||||
val sideTexture: TextureAtlasSprite)
|
||||
|
||||
open class ColumnTextures(val matcher: BlockMatcher) : BlockTextureInspector<ColumnInfo>() {
|
||||
init {
|
||||
matchClassAndModel(matcher, "block/column_side", listOf("end", "end", "side"))
|
||||
matchClassAndModel(matcher, "block/cube_column", listOf("end", "end", "side"))
|
||||
}
|
||||
override fun processTextures(textures: List<TextureAtlasSprite>, atlas: TextureMap) =
|
||||
ColumnInfo(textures[0], textures[1], textures[2])
|
||||
}
|
||||
|
||||
/** Index of SOUTH-EAST quadrant. */
|
||||
const val SE = 0
|
||||
@@ -30,7 +54,7 @@ abstract class AbstractRenderColumn(modId: String) : AbstractBlockRenderingHandl
|
||||
// ============================
|
||||
abstract val radiusSmall: Double
|
||||
abstract val radiusLarge: Double
|
||||
abstract val surroundPredicate: (Block) -> Boolean
|
||||
abstract val surroundPredicate: (IBlockState) -> Boolean
|
||||
abstract val connectPerpendicular: Boolean
|
||||
abstract val connectSolids: Boolean
|
||||
abstract val lenientConnect: Boolean
|
||||
@@ -89,26 +113,26 @@ abstract class AbstractRenderColumn(modId: String) : AbstractBlockRenderingHandl
|
||||
val transitionTop = model { mix(sideRoundLarge.model, sideRoundSmall.model) { it > 1 } }
|
||||
val transitionBottom = model { mix(sideRoundSmall.model, sideRoundLarge.model) { it > 1 } }
|
||||
|
||||
val sideTexture = { ctx: ShadingContext, qi: Int, q: Quad -> if ((qi and 1) == 0) ctx.icon(SOUTH) else ctx.icon(EAST) }
|
||||
val upTexture = { ctx: ShadingContext, qi: Int, q: Quad -> ctx.icon(UP) }
|
||||
val downTexture = { ctx: ShadingContext, qi: Int, q: Quad -> ctx.icon(DOWN) }
|
||||
|
||||
inline fun continous(q1: QuadrantType, q2: QuadrantType) =
|
||||
q1 == q2 || ((q1 == SQUARE || q1 == INVISIBLE) && (q2 == SQUARE || q2 == INVISIBLE))
|
||||
|
||||
abstract val axisFunc: (Block, Int)->Axis
|
||||
abstract val blockPredicate: (Block, Int)->Boolean
|
||||
abstract val axisFunc: (IBlockState)->EnumFacing.Axis
|
||||
abstract val blockPredicate: (IBlockState)->Boolean
|
||||
|
||||
abstract val sideTexture: (ShadingContext, Int, Quad)->TextureAtlasSprite?
|
||||
abstract val upTexture: (ShadingContext, Int, Quad)->TextureAtlasSprite?
|
||||
abstract val downTexture: (ShadingContext, Int, Quad)->TextureAtlasSprite?
|
||||
|
||||
@Suppress("NON_EXHAUSTIVE_WHEN")
|
||||
override fun render(ctx: BlockContext, parent: RenderBlocks): Boolean {
|
||||
override fun render(ctx: BlockContext, dispatcher: BlockRendererDispatcher, renderer: WorldRenderer, layer: EnumWorldBlockLayer): Boolean {
|
||||
if (ctx.isSurroundedBy(surroundPredicate) ) return false
|
||||
|
||||
// get AO data
|
||||
if (renderWorldBlockBase(parent, face = neverRender)) return true
|
||||
modelRenderer.updateShading(Int3.zero, allFaces)
|
||||
|
||||
// check log neighborhood
|
||||
val logAxis = ctx.blockAxis
|
||||
val baseRotation = rotationFromUp[(logAxis to Dir.P).face.ordinal]
|
||||
val baseRotation = rotationFromUp[(logAxis to AxisDirection.POSITIVE).face.ordinal]
|
||||
|
||||
val upType = ctx.blockType(baseRotation, logAxis, Int3(0, 1, 0))
|
||||
val downType = ctx.blockType(baseRotation, logAxis, Int3(0, -1, 0))
|
||||
@@ -141,6 +165,7 @@ abstract class AbstractRenderColumn(modId: String) : AbstractBlockRenderingHandl
|
||||
}
|
||||
|
||||
if (sideModel != null) modelRenderer.render(
|
||||
renderer,
|
||||
sideModel,
|
||||
rotation,
|
||||
blockContext.blockCenter,
|
||||
@@ -192,6 +217,7 @@ abstract class AbstractRenderColumn(modId: String) : AbstractBlockRenderingHandl
|
||||
}
|
||||
|
||||
if (upModel != null) modelRenderer.render(
|
||||
renderer,
|
||||
upModel,
|
||||
rotation,
|
||||
blockContext.blockCenter,
|
||||
@@ -200,6 +226,7 @@ abstract class AbstractRenderColumn(modId: String) : AbstractBlockRenderingHandl
|
||||
postProcess = noPost
|
||||
)
|
||||
if (downModel != null) modelRenderer.render(
|
||||
renderer,
|
||||
downModel,
|
||||
rotation,
|
||||
blockContext.blockCenter,
|
||||
@@ -283,19 +310,18 @@ abstract class AbstractRenderColumn(modId: String) : AbstractBlockRenderingHandl
|
||||
}
|
||||
|
||||
/** Get the axis of the block */
|
||||
val BlockContext.blockAxis: Axis get() = axisFunc(block(Int3.zero), meta(Int3.zero))
|
||||
val BlockContext.blockAxis: Axis get() = axisFunc(blockState(Int3.zero))
|
||||
|
||||
/**
|
||||
* Get the type of the block at the given offset in a rotated reference frame.
|
||||
*/
|
||||
fun BlockContext.blockType(rotation: Rotation, axis: Axis, offset: Int3): BlockType {
|
||||
val offsetRot = offset.rotate(rotation)
|
||||
val logBlock = block(offsetRot)
|
||||
val logMeta = meta(offsetRot)
|
||||
return if (!blockPredicate(logBlock, logMeta)) {
|
||||
if (logBlock.isOpaqueCube) SOLID else NONSOLID
|
||||
val state = blockState(offsetRot)
|
||||
return if (!blockPredicate(state)) {
|
||||
if (state.block.isOpaqueCube) SOLID else NONSOLID
|
||||
} else {
|
||||
if (axisFunc(logBlock, logMeta) == axis) PARALLEL else PERPENDICULAR
|
||||
if (axisFunc(state) == axis) PARALLEL else PERPENDICULAR
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,31 +1,31 @@
|
||||
package mods.betterfoliage.client.render
|
||||
|
||||
import cpw.mods.fml.common.FMLCommonHandler
|
||||
import cpw.mods.fml.common.eventhandler.SubscribeEvent
|
||||
import cpw.mods.fml.common.gameevent.TickEvent
|
||||
import cpw.mods.fml.relauncher.Side
|
||||
import cpw.mods.fml.relauncher.SideOnly
|
||||
import mods.betterfoliage.client.config.Config
|
||||
import mods.betterfoliage.client.texture.LeafRegistry
|
||||
import mods.octarinecore.PI2
|
||||
import mods.octarinecore.client.render.AbstractEntityFX
|
||||
import mods.octarinecore.client.render.Double3
|
||||
import mods.octarinecore.client.render.HSB
|
||||
import mods.octarinecore.common.Double3
|
||||
import mods.octarinecore.minmax
|
||||
import mods.octarinecore.random
|
||||
import net.minecraft.client.Minecraft
|
||||
import net.minecraft.client.renderer.Tessellator
|
||||
import net.minecraft.client.renderer.WorldRenderer
|
||||
import net.minecraft.util.BlockPos
|
||||
import net.minecraft.util.MathHelper
|
||||
import net.minecraft.world.World
|
||||
import net.minecraftforge.common.MinecraftForge
|
||||
import net.minecraftforge.common.util.ForgeDirection.DOWN
|
||||
import net.minecraftforge.event.world.WorldEvent
|
||||
import net.minecraftforge.fml.common.FMLCommonHandler
|
||||
import net.minecraftforge.fml.common.eventhandler.SubscribeEvent
|
||||
import net.minecraftforge.fml.common.gameevent.TickEvent
|
||||
import net.minecraftforge.fml.relauncher.Side
|
||||
import net.minecraftforge.fml.relauncher.SideOnly
|
||||
import org.lwjgl.opengl.GL11
|
||||
import java.lang.Math.*
|
||||
import java.util.*
|
||||
|
||||
class EntityFallingLeavesFX(world: World, x: Int, y: Int, z: Int) :
|
||||
AbstractEntityFX(world, x.toDouble() + 0.5, y.toDouble(), z.toDouble() + 0.5) {
|
||||
class EntityFallingLeavesFX(world: World, pos: BlockPos) :
|
||||
AbstractEntityFX(world, pos.x.toDouble() + 0.5, pos.y.toDouble(), pos.z.toDouble() + 0.5) {
|
||||
|
||||
companion object {
|
||||
@JvmStatic val biomeBrightnessMultiplier = 0.5f
|
||||
@@ -41,10 +41,10 @@ AbstractEntityFX(world, x.toDouble() + 0.5, y.toDouble(), z.toDouble() + 0.5) {
|
||||
motionY = -Config.fallingLeaves.speed
|
||||
particleScale = Config.fallingLeaves.size.toFloat() * 0.1f
|
||||
|
||||
val block = world.getBlock(x, y, z)
|
||||
LeafRegistry.leaves[block.getIcon(world, x, y, z, DOWN.ordinal)]?.let {
|
||||
val state = world.getBlockState(pos)
|
||||
LeafRegistry[world.getBlockState(pos)]?.let {
|
||||
particleIcon = it.particleTextures[rand.nextInt(1024)]
|
||||
calculateParticleColor(it.averageColor, block.colorMultiplier(world, x, y, z))
|
||||
calculateParticleColor(it.averageColor, state.block.colorMultiplier(world, pos))
|
||||
}
|
||||
}
|
||||
|
||||
@@ -67,9 +67,9 @@ AbstractEntityFX(world, x.toDouble() + 0.5, y.toDouble(), z.toDouble() + 0.5) {
|
||||
}
|
||||
}
|
||||
|
||||
override fun render(tessellator: Tessellator, partialTickTime: Float) {
|
||||
override fun render(worldRenderer: WorldRenderer, partialTickTime: Float) {
|
||||
if (Config.fallingLeaves.opacityHack) GL11.glDepthMask(true)
|
||||
renderParticleQuad(tessellator, partialTickTime, rotation = particleRot, isMirrored = isMirrored)
|
||||
renderParticleQuad(worldRenderer, partialTickTime, rotation = particleRot, isMirrored = isMirrored)
|
||||
}
|
||||
|
||||
fun calculateParticleColor(textureAvgColor: Int, blockColor: Int) {
|
||||
|
||||
@@ -1,22 +1,23 @@
|
||||
package mods.betterfoliage.client.render
|
||||
|
||||
import cpw.mods.fml.relauncher.Side
|
||||
import cpw.mods.fml.relauncher.SideOnly
|
||||
import mods.betterfoliage.BetterFoliageMod
|
||||
import mods.betterfoliage.client.Client
|
||||
import mods.betterfoliage.client.config.Config
|
||||
import mods.octarinecore.client.render.AbstractEntityFX
|
||||
import mods.octarinecore.client.render.Double3
|
||||
import mods.octarinecore.client.resource.ResourceHandler
|
||||
import mods.octarinecore.common.Double3
|
||||
import mods.octarinecore.forEachPairIndexed
|
||||
import net.minecraft.client.renderer.Tessellator
|
||||
import net.minecraft.client.renderer.WorldRenderer
|
||||
import net.minecraft.util.BlockPos
|
||||
import net.minecraft.util.MathHelper
|
||||
import net.minecraft.world.World
|
||||
import org.apache.logging.log4j.Level.*
|
||||
import net.minecraftforge.fml.relauncher.Side
|
||||
import net.minecraftforge.fml.relauncher.SideOnly
|
||||
import org.apache.logging.log4j.Level.INFO
|
||||
import java.util.*
|
||||
|
||||
class EntityRisingSoulFX(world: World, x: Int, y: Int, z: Int) :
|
||||
AbstractEntityFX(world, x.toDouble() + 0.5, y.toDouble() + 1.0, z.toDouble() + 0.5) {
|
||||
class EntityRisingSoulFX(world: World, pos: BlockPos) :
|
||||
AbstractEntityFX(world, pos.x.toDouble() + 0.5, pos.y.toDouble() + 1.0, pos.z.toDouble() + 0.5) {
|
||||
|
||||
val particleTrail: Deque<Double3> = linkedListOf()
|
||||
val initialPhase = rand.nextInt(64)
|
||||
@@ -40,11 +41,11 @@ AbstractEntityFX(world, x.toDouble() + 0.5, y.toDouble() + 1.0, z.toDouble() + 0
|
||||
if (!Config.enabled) setDead()
|
||||
}
|
||||
|
||||
override fun render(tessellator: Tessellator, partialTickTime: Float) {
|
||||
override fun render(worldRenderer: WorldRenderer, partialTickTime: Float) {
|
||||
var alpha = Config.risingSoul.opacity
|
||||
if (particleAge > particleMaxAge - 40) alpha *= (particleMaxAge - particleAge) / 40.0f
|
||||
|
||||
renderParticleQuad(tessellator, partialTickTime,
|
||||
renderParticleQuad(worldRenderer, partialTickTime,
|
||||
size = Config.risingSoul.headSize * 0.25,
|
||||
alpha = alpha
|
||||
)
|
||||
@@ -53,7 +54,7 @@ AbstractEntityFX(world, x.toDouble() + 0.5, y.toDouble() + 1.0, z.toDouble() + 0
|
||||
particleTrail.forEachPairIndexed { idx, current, previous ->
|
||||
scale *= Config.risingSoul.sizeDecay
|
||||
alpha *= Config.risingSoul.opacityDecay
|
||||
if (idx % Config.risingSoul.trailDensity == 0) renderParticleQuad(tessellator, partialTickTime,
|
||||
if (idx % Config.risingSoul.trailDensity == 0) renderParticleQuad(worldRenderer, partialTickTime,
|
||||
currentPos = current,
|
||||
prevPos = previous,
|
||||
size = scale,
|
||||
@@ -66,8 +67,8 @@ AbstractEntityFX(world, x.toDouble() + 0.5, y.toDouble() + 1.0, z.toDouble() + 0
|
||||
|
||||
@SideOnly(Side.CLIENT)
|
||||
object RisingSoulTextures : ResourceHandler(BetterFoliageMod.MOD_ID) {
|
||||
val headIcons = iconSet(BetterFoliageMod.LEGACY_DOMAIN, "rising_soul_%d")
|
||||
val trackIcon = iconStatic(BetterFoliageMod.LEGACY_DOMAIN, "soul_track")
|
||||
val headIcons = iconSet(BetterFoliageMod.LEGACY_DOMAIN, "blocks/rising_soul_%d")
|
||||
val trackIcon = iconStatic(BetterFoliageMod.LEGACY_DOMAIN, "blocks/soul_track")
|
||||
|
||||
override fun afterStitch() {
|
||||
Client.log(INFO, "Registered ${headIcons.num} soul particle textures")
|
||||
|
||||
@@ -3,8 +3,9 @@ package mods.betterfoliage.client.render
|
||||
|
||||
import mods.betterfoliage.client.config.Config
|
||||
import mods.octarinecore.client.render.*
|
||||
import mods.octarinecore.common.Double3
|
||||
import mods.octarinecore.exchange
|
||||
import net.minecraftforge.common.util.ForgeDirection.*
|
||||
import net.minecraft.util.EnumFacing.*
|
||||
|
||||
/** Weight of the same-side AO values on the outer edges of the 45deg chamfered column faces. */
|
||||
const val chamferAffinity = 0.9f
|
||||
|
||||
@@ -5,16 +5,19 @@ import mods.betterfoliage.client.Client
|
||||
import mods.betterfoliage.client.config.Config
|
||||
import mods.betterfoliage.client.integration.ShadersModIntegration
|
||||
import mods.octarinecore.client.render.*
|
||||
import mods.octarinecore.common.Int3
|
||||
import mods.octarinecore.common.Rotation
|
||||
import net.minecraft.block.material.Material
|
||||
import net.minecraft.client.renderer.RenderBlocks
|
||||
import net.minecraft.init.Blocks
|
||||
import net.minecraft.client.renderer.BlockRendererDispatcher
|
||||
import net.minecraft.client.renderer.WorldRenderer
|
||||
import net.minecraft.util.EnumWorldBlockLayer
|
||||
import org.apache.logging.log4j.Level.INFO
|
||||
|
||||
class RenderAlgae : AbstractBlockRenderingHandler(BetterFoliageMod.MOD_ID) {
|
||||
|
||||
val noise = simplexNoise()
|
||||
|
||||
val algaeIcons = iconSet(BetterFoliageMod.LEGACY_DOMAIN, "better_algae_%d")
|
||||
val algaeIcons = iconSet(BetterFoliageMod.LEGACY_DOMAIN, "blocks/better_algae_%d")
|
||||
val algaeModels = modelSet(64, RenderGrass.grassTopQuads)
|
||||
|
||||
override fun afterStitch() {
|
||||
@@ -28,15 +31,17 @@ class RenderAlgae : AbstractBlockRenderingHandler(BetterFoliageMod.MOD_ID) {
|
||||
ctx.block(up1).material == Material.water &&
|
||||
Config.blocks.dirt.matchesID(ctx.block) &&
|
||||
ctx.biomeId in Config.algae.biomes &&
|
||||
noise[ctx.x, ctx.z] < Config.algae.population
|
||||
noise[ctx.pos] < Config.algae.population
|
||||
|
||||
override fun render(ctx: BlockContext, parent: RenderBlocks): Boolean {
|
||||
if (renderWorldBlockBase(parent, face = alwaysRender)) return true
|
||||
override fun render(ctx: BlockContext, dispatcher: BlockRendererDispatcher, renderer: WorldRenderer, layer: EnumWorldBlockLayer): Boolean {
|
||||
renderWorldBlockBase(ctx, dispatcher, renderer, null)
|
||||
modelRenderer.updateShading(Int3.zero, allFaces)
|
||||
|
||||
val rand = ctx.semiRandomArray(3)
|
||||
|
||||
ShadersModIntegration.grass(Config.algae.shaderWind) {
|
||||
ShadersModIntegration.grass(renderer, Config.algae.shaderWind) {
|
||||
modelRenderer.render(
|
||||
renderer,
|
||||
algaeModels[rand[2]],
|
||||
Rotation.identity,
|
||||
icon = { ctx, qi, q -> algaeIcons[rand[qi and 1]]!! },
|
||||
|
||||
@@ -4,8 +4,13 @@ import mods.betterfoliage.BetterFoliageMod
|
||||
import mods.betterfoliage.client.Client
|
||||
import mods.betterfoliage.client.config.Config
|
||||
import mods.octarinecore.client.render.*
|
||||
import net.minecraft.client.renderer.RenderBlocks
|
||||
import net.minecraftforge.common.util.ForgeDirection.*
|
||||
import mods.octarinecore.client.resource.BlockTextureInspector
|
||||
import mods.octarinecore.common.Int3
|
||||
import mods.octarinecore.common.Rotation
|
||||
import net.minecraft.client.renderer.BlockRendererDispatcher
|
||||
import net.minecraft.client.renderer.WorldRenderer
|
||||
import net.minecraft.util.EnumFacing.*
|
||||
import net.minecraft.util.EnumWorldBlockLayer
|
||||
import org.apache.logging.log4j.Level
|
||||
|
||||
class RenderCactus : AbstractBlockRenderingHandler(BetterFoliageMod.MOD_ID) {
|
||||
@@ -13,8 +18,13 @@ class RenderCactus : AbstractBlockRenderingHandler(BetterFoliageMod.MOD_ID) {
|
||||
val cactusStemRadius = 0.4375
|
||||
val cactusArmRotation = listOf(NORTH, SOUTH, EAST, WEST).map { Rotation.rot90[it.ordinal] }
|
||||
|
||||
val iconCross = iconStatic(BetterFoliageMod.LEGACY_DOMAIN, "better_cactus")
|
||||
val iconArm = iconSet(BetterFoliageMod.LEGACY_DOMAIN, "better_cactus_arm_%d")
|
||||
val iconCross = iconStatic(BetterFoliageMod.LEGACY_DOMAIN, "blocks/better_cactus")
|
||||
val iconArm = iconSet(BetterFoliageMod.LEGACY_DOMAIN, "blocks/better_cactus_arm_%d")
|
||||
val iconBase = object : ColumnTextures(Config.blocks.cactus) {
|
||||
init {
|
||||
matchClassAndModel(matcher, "block/cactus", listOf("top", "bottom", "side"))
|
||||
}
|
||||
}
|
||||
|
||||
val modelStem = model {
|
||||
horizontalRectangle(x1 = -cactusStemRadius, x2 = cactusStemRadius, z1 = -cactusStemRadius, z2 = cactusStemRadius, y = 0.5)
|
||||
@@ -53,18 +63,23 @@ class RenderCactus : AbstractBlockRenderingHandler(BetterFoliageMod.MOD_ID) {
|
||||
ctx.cameraDistance < Config.cactus.distance &&
|
||||
Config.blocks.cactus.matchesID(ctx.block)
|
||||
|
||||
override fun render(ctx: BlockContext, parent: RenderBlocks): Boolean {
|
||||
override fun render(ctx: BlockContext, dispatcher: BlockRendererDispatcher, renderer: WorldRenderer, layer: EnumWorldBlockLayer): Boolean {
|
||||
// get AO data
|
||||
if (renderWorldBlockBase(parent, face = neverRender)) return true
|
||||
modelRenderer.updateShading(Int3.zero, allFaces)
|
||||
val icons = iconBase[ctx.blockState(Int3.zero)] ?: return renderWorldBlockBase(ctx, dispatcher, renderer, null)
|
||||
|
||||
modelRenderer.render(
|
||||
renderer,
|
||||
modelStem.model,
|
||||
Rotation.identity,
|
||||
icon = { ctx, qi, q -> ctx.icon(forgeDirs[qi])},
|
||||
icon = { ctx, qi, q -> when(qi) {
|
||||
0 -> icons.bottomTexture; 1 -> icons.topTexture; else -> icons.sideTexture
|
||||
} },
|
||||
rotateUV = { 0 },
|
||||
postProcess = noPost
|
||||
)
|
||||
modelRenderer.render(
|
||||
renderer,
|
||||
modelCross[ctx.random(0)],
|
||||
Rotation.identity,
|
||||
icon = { ctx, qi, q -> iconCross.icon!!},
|
||||
@@ -72,6 +87,7 @@ class RenderCactus : AbstractBlockRenderingHandler(BetterFoliageMod.MOD_ID) {
|
||||
postProcess = noPost
|
||||
)
|
||||
modelRenderer.render(
|
||||
renderer,
|
||||
modelArm[ctx.random(1)],
|
||||
cactusArmRotation[ctx.random(2) % 4],
|
||||
icon = { ctx2, qi, q -> iconArm[ctx.random(3)]!!},
|
||||
|
||||
@@ -2,9 +2,13 @@ package mods.betterfoliage.client.render
|
||||
|
||||
import mods.betterfoliage.BetterFoliageMod
|
||||
import mods.betterfoliage.client.config.Config
|
||||
import mods.octarinecore.client.render.*
|
||||
import net.minecraft.block.material.Material
|
||||
import net.minecraft.client.renderer.RenderBlocks
|
||||
import mods.octarinecore.client.render.AbstractBlockRenderingHandler
|
||||
import mods.octarinecore.client.render.BlockContext
|
||||
import mods.octarinecore.client.render.withOffset
|
||||
import mods.octarinecore.common.Int3
|
||||
import net.minecraft.client.renderer.BlockRendererDispatcher
|
||||
import net.minecraft.client.renderer.WorldRenderer
|
||||
import net.minecraft.util.EnumWorldBlockLayer
|
||||
|
||||
class RenderConnectedGrass : AbstractBlockRenderingHandler(BetterFoliageMod.MOD_ID) {
|
||||
override fun isEligible(ctx: BlockContext) =
|
||||
@@ -13,10 +17,10 @@ class RenderConnectedGrass : AbstractBlockRenderingHandler(BetterFoliageMod.MOD_
|
||||
Config.blocks.grass.matchesID(ctx.block(up1)) &&
|
||||
(Config.connectedGrass.snowEnabled || !ctx.block(up2).isSnow)
|
||||
|
||||
override fun render(ctx: BlockContext, parent: RenderBlocks): Boolean {
|
||||
override fun render(ctx: BlockContext, dispatcher: BlockRendererDispatcher, renderer: WorldRenderer, layer: EnumWorldBlockLayer): Boolean {
|
||||
return ctx.withOffset(Int3.zero, up1) {
|
||||
ctx.withOffset(up1, up2) {
|
||||
renderWorldBlockBase(parent, face = alwaysRender)
|
||||
renderWorldBlockBase(ctx, dispatcher, renderer, null)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,9 +2,15 @@ package mods.betterfoliage.client.render
|
||||
|
||||
import mods.betterfoliage.BetterFoliageMod
|
||||
import mods.betterfoliage.client.config.Config
|
||||
import mods.octarinecore.client.render.*
|
||||
import net.minecraft.client.renderer.RenderBlocks
|
||||
import net.minecraftforge.common.util.ForgeDirection.*
|
||||
import mods.octarinecore.client.render.AbstractBlockRenderingHandler
|
||||
import mods.octarinecore.client.render.BlockContext
|
||||
import mods.octarinecore.client.render.withOffset
|
||||
import mods.octarinecore.common.Int3
|
||||
import mods.octarinecore.common.offset
|
||||
import net.minecraft.client.renderer.BlockRendererDispatcher
|
||||
import net.minecraft.client.renderer.WorldRenderer
|
||||
import net.minecraft.util.EnumFacing.*
|
||||
import net.minecraft.util.EnumWorldBlockLayer
|
||||
|
||||
class RenderConnectedGrassLog : AbstractBlockRenderingHandler(BetterFoliageMod.MOD_ID) {
|
||||
|
||||
@@ -15,17 +21,17 @@ class RenderConnectedGrassLog : AbstractBlockRenderingHandler(BetterFoliageMod.M
|
||||
Config.blocks.dirt.matchesID(ctx.block) &&
|
||||
Config.blocks.logs.matchesID(ctx.block(up1))
|
||||
|
||||
override fun render(ctx: BlockContext, parent: RenderBlocks): Boolean {
|
||||
override fun render(ctx: BlockContext, dispatcher: BlockRendererDispatcher, renderer: WorldRenderer, layer: EnumWorldBlockLayer): Boolean {
|
||||
val grassDir = grassCheckDirs.find {
|
||||
Config.blocks.grass.matchesID(ctx.block(it.offset))
|
||||
}
|
||||
|
||||
return if (grassDir != null) {
|
||||
ctx.withOffset(Int3.zero, grassDir.offset) {
|
||||
renderWorldBlockBase(parent, face = alwaysRender)
|
||||
renderWorldBlockBase(ctx, dispatcher, renderer, null)
|
||||
}
|
||||
} else {
|
||||
renderWorldBlockBase(parent, face = alwaysRender)
|
||||
renderWorldBlockBase(ctx, dispatcher, renderer, null)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -4,18 +4,24 @@ import mods.betterfoliage.BetterFoliageMod
|
||||
import mods.betterfoliage.client.Client
|
||||
import mods.betterfoliage.client.config.Config
|
||||
import mods.octarinecore.client.render.*
|
||||
import mods.octarinecore.common.Int3
|
||||
import mods.octarinecore.common.forgeDirOffsets
|
||||
import mods.octarinecore.common.forgeDirs
|
||||
import mods.octarinecore.random
|
||||
import net.minecraft.block.material.Material
|
||||
import net.minecraft.client.renderer.RenderBlocks
|
||||
import net.minecraftforge.common.util.ForgeDirection.UP
|
||||
import net.minecraft.client.renderer.BlockRendererDispatcher
|
||||
import net.minecraft.client.renderer.WorldRenderer
|
||||
import net.minecraft.util.EnumFacing.Axis
|
||||
import net.minecraft.util.EnumFacing.UP
|
||||
import net.minecraft.util.EnumWorldBlockLayer
|
||||
import org.apache.logging.log4j.Level.INFO
|
||||
|
||||
class RenderCoral : AbstractBlockRenderingHandler(BetterFoliageMod.MOD_ID) {
|
||||
|
||||
val noise = simplexNoise()
|
||||
|
||||
val coralIcons = iconSet(BetterFoliageMod.LEGACY_DOMAIN, "better_coral_%d")
|
||||
val crustIcons = iconSet(BetterFoliageMod.LEGACY_DOMAIN, "better_crust_%d")
|
||||
val coralIcons = iconSet(BetterFoliageMod.LEGACY_DOMAIN, "blocks/better_coral_%d")
|
||||
val crustIcons = iconSet(BetterFoliageMod.LEGACY_DOMAIN, "blocks/better_crust_%d")
|
||||
val coralModels = modelSet(64) { modelIdx ->
|
||||
verticalRectangle(x1 = -0.5, z1 = 0.5, x2 = 0.5, z2 = -0.5, yBottom = 0.0, yTop = 1.0)
|
||||
.scale(Config.coral.size).move(0.5 to UP)
|
||||
@@ -32,7 +38,8 @@ class RenderCoral : AbstractBlockRenderingHandler(BetterFoliageMod.MOD_ID) {
|
||||
}
|
||||
|
||||
override fun afterStitch() {
|
||||
Client.log(INFO, "Registered ${coralIcons.num} algae textures")
|
||||
Client.log(INFO, "Registered ${coralIcons.num} coral textures")
|
||||
Client.log(INFO, "Registered ${crustIcons.num} coral crust textures")
|
||||
}
|
||||
|
||||
override fun isEligible(ctx: BlockContext) =
|
||||
@@ -42,15 +49,17 @@ class RenderCoral : AbstractBlockRenderingHandler(BetterFoliageMod.MOD_ID) {
|
||||
ctx.block(up1).material == Material.water &&
|
||||
Config.blocks.sand.matchesID(ctx.block) &&
|
||||
ctx.biomeId in Config.coral.biomes &&
|
||||
noise[ctx.x, ctx.z] < Config.coral.population
|
||||
noise[ctx.pos] < Config.coral.population
|
||||
|
||||
override fun render(ctx: BlockContext, parent: RenderBlocks): Boolean {
|
||||
if (renderWorldBlockBase(parent, face = alwaysRender)) return true
|
||||
override fun render(ctx: BlockContext, dispatcher: BlockRendererDispatcher, renderer: WorldRenderer, layer: EnumWorldBlockLayer): Boolean {
|
||||
renderWorldBlockBase(ctx, dispatcher, renderer, null)
|
||||
modelRenderer.updateShading(Int3.zero, allFaces)
|
||||
|
||||
forgeDirs.forEachIndexed { idx, face ->
|
||||
if (!ctx.block(forgeDirOffsets[idx]).isOpaqueCube && blockContext.random(idx) < Config.coral.chance) {
|
||||
var variation = blockContext.random(6)
|
||||
modelRenderer.render(
|
||||
renderer,
|
||||
coralModels[variation++],
|
||||
rotationFromUp[idx],
|
||||
icon = { ctx, qi, q -> if (qi == 4) crustIcons[variation]!! else coralIcons[variation + (qi and 1)]!!},
|
||||
|
||||
@@ -6,10 +6,16 @@ import mods.betterfoliage.client.config.Config
|
||||
import mods.betterfoliage.client.integration.ShadersModIntegration
|
||||
import mods.betterfoliage.client.texture.GrassRegistry
|
||||
import mods.octarinecore.client.render.*
|
||||
import mods.octarinecore.common.Double3
|
||||
import mods.octarinecore.common.Int3
|
||||
import mods.octarinecore.common.Rotation
|
||||
import mods.octarinecore.random
|
||||
import net.minecraft.block.material.Material
|
||||
import net.minecraft.client.renderer.RenderBlocks
|
||||
import net.minecraftforge.common.util.ForgeDirection.UP
|
||||
import net.minecraft.client.renderer.BlockRendererDispatcher
|
||||
import net.minecraft.client.renderer.WorldRenderer
|
||||
import net.minecraft.util.EnumFacing.Axis
|
||||
import net.minecraft.util.EnumFacing.UP
|
||||
import net.minecraft.util.EnumWorldBlockLayer
|
||||
import org.apache.logging.log4j.Level.INFO
|
||||
|
||||
class RenderGrass : AbstractBlockRenderingHandler(BetterFoliageMod.MOD_ID) {
|
||||
@@ -25,10 +31,10 @@ class RenderGrass : AbstractBlockRenderingHandler(BetterFoliageMod.MOD_ID) {
|
||||
}
|
||||
}
|
||||
|
||||
val normalIcons = iconSet(BetterFoliageMod.LEGACY_DOMAIN, "better_grass_long_%d")
|
||||
val snowedIcons = iconSet(BetterFoliageMod.LEGACY_DOMAIN, "better_grass_snowed_%d")
|
||||
val normalGenIcon = iconStatic(Client.genGrass.generatedResource("minecraft:tallgrass", "snowed" to false))
|
||||
val snowedGenIcon = iconStatic(Client.genGrass.generatedResource("minecraft:tallgrass", "snowed" to true))
|
||||
val normalIcons = iconSet(BetterFoliageMod.LEGACY_DOMAIN, "blocks/better_grass_long_%d")
|
||||
val snowedIcons = iconSet(BetterFoliageMod.LEGACY_DOMAIN, "blocks/better_grass_snowed_%d")
|
||||
val normalGenIcon = iconStatic(Client.genGrass.generatedResource("minecraft:blocks/tallgrass", "snowed" to false))
|
||||
val snowedGenIcon = iconStatic(Client.genGrass.generatedResource("minecraft:blocks/tallgrass", "snowed" to true))
|
||||
|
||||
val grassModels = modelSet(64, grassTopQuads)
|
||||
|
||||
@@ -43,61 +49,58 @@ class RenderGrass : AbstractBlockRenderingHandler(BetterFoliageMod.MOD_ID) {
|
||||
(Config.shortGrass.grassEnabled || Config.connectedGrass.enabled) &&
|
||||
Config.blocks.grass.matchesID(ctx.block)
|
||||
|
||||
override fun render(ctx: BlockContext, parent: RenderBlocks): Boolean {
|
||||
override fun render(ctx: BlockContext, dispatcher: BlockRendererDispatcher, renderer: WorldRenderer, layer: EnumWorldBlockLayer): Boolean {
|
||||
val isConnected = ctx.block(down1).let { Config.blocks.dirt.matchesID(it) || Config.blocks.grass.matchesID(it) }
|
||||
val isSnowed = ctx.block(up1).isSnow
|
||||
val connectedGrass = isConnected && Config.connectedGrass.enabled && (!isSnowed || Config.connectedGrass.snowEnabled)
|
||||
|
||||
val grassInfo = GrassRegistry.grass[ctx.icon(UP)]
|
||||
if (grassInfo == null) {
|
||||
renderWorldBlockBase(parent, face = alwaysRender)
|
||||
return true
|
||||
}
|
||||
val cubeTexture = if (isSnowed) ctx.icon(up1, UP) else null ?: grassInfo.grassTopTexture
|
||||
val blockColor = ctx.blockColor(Int3.zero)
|
||||
val grassInfo = GrassRegistry[ctx.blockState(Int3.zero)] ?: return renderWorldBlockBase(ctx, dispatcher, renderer, layer)
|
||||
val blockColor = ctx.blockData(Int3.zero, 0).color
|
||||
|
||||
if (connectedGrass) {
|
||||
// get AO data
|
||||
if (renderWorldBlockBase(parent, face = neverRender)) return true
|
||||
// get full AO data
|
||||
modelRenderer.updateShading(Int3.zero, allFaces)
|
||||
|
||||
// render full grass block
|
||||
modelRenderer.render(
|
||||
renderer,
|
||||
fullCube,
|
||||
Rotation.identity,
|
||||
ctx.blockCenter,
|
||||
icon = { ctx, qi, q -> cubeTexture },
|
||||
icon = { ctx, qi, q -> grassInfo.grassTopTexture },
|
||||
rotateUV = { 2 },
|
||||
postProcess = { ctx, qi, q, vi, v ->
|
||||
if (isSnowed) { if(!ctx.aoEnabled) setGrey(1.4f) }
|
||||
else if (qi != UP.ordinal && ctx.aoEnabled) multiplyColor(blockColor)
|
||||
else if (ctx.aoEnabled) multiplyColor(blockColor)
|
||||
}
|
||||
)
|
||||
} else {
|
||||
// render normally
|
||||
if (renderWorldBlockBase(parent, face = alwaysRender)) return true
|
||||
renderWorldBlockBase(ctx, dispatcher, renderer, null)
|
||||
|
||||
// get AO data only for block top
|
||||
modelRenderer.updateShading(Int3.zero, topOnly)
|
||||
}
|
||||
|
||||
if (!Config.shortGrass.grassEnabled) return true
|
||||
if (isSnowed && !Config.shortGrass.snowEnabled) return true
|
||||
if (ctx.block(up1).isOpaqueCube) return true
|
||||
if (ctx.block(up1).material != Material.air) return true
|
||||
|
||||
// render grass quads
|
||||
val iconset = if (isSnowed) snowedIcons else normalIcons
|
||||
val iconGen = if (isSnowed) snowedGenIcon else normalGenIcon
|
||||
val rand = ctx.semiRandomArray(2)
|
||||
|
||||
ShadersModIntegration.grass(Config.shortGrass.shaderWind) {
|
||||
ShadersModIntegration.grass(renderer, Config.shortGrass.shaderWind) {
|
||||
modelRenderer.render(
|
||||
renderer,
|
||||
grassModels[rand[0]],
|
||||
Rotation.identity,
|
||||
ctx.blockCenter + (if (isSnowed) snowOffset else Double3.zero),
|
||||
icon = if (Config.shortGrass.useGenerated)
|
||||
{ ctx: ShadingContext, qi: Int, q: Quad -> iconGen.icon!! }
|
||||
else
|
||||
{ ctx: ShadingContext, qi: Int, q: Quad -> iconset[rand[qi and 1]]!! },
|
||||
icon = { ctx: ShadingContext, qi: Int, q: Quad ->
|
||||
if (Config.shortGrass.useGenerated) iconGen.icon!! else iconset[rand[qi and 1]]!!
|
||||
},
|
||||
rotateUV = { 0 },
|
||||
postProcess = if (isSnowed) whitewash else if (grassInfo.overrideColor == null) noPost else
|
||||
{ ctx, qi, q, vi, v -> multiplyColor(grassInfo.overrideColor) }
|
||||
postProcess = { ctx, qi, q, vi, v -> if (isSnowed) setGrey(1.4f) else multiplyColor(grassInfo.overrideColor ?: blockColor) }
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
@@ -6,11 +6,16 @@ import mods.betterfoliage.client.integration.ShadersModIntegration
|
||||
import mods.betterfoliage.client.texture.LeafRegistry
|
||||
import mods.octarinecore.PI2
|
||||
import mods.octarinecore.client.render.*
|
||||
import mods.octarinecore.common.Double3
|
||||
import mods.octarinecore.common.Int3
|
||||
import mods.octarinecore.common.Rotation
|
||||
import mods.octarinecore.common.vec
|
||||
import mods.octarinecore.random
|
||||
import net.minecraft.block.material.Material
|
||||
import net.minecraft.client.renderer.RenderBlocks
|
||||
import net.minecraftforge.common.util.ForgeDirection.DOWN
|
||||
import net.minecraftforge.common.util.ForgeDirection.UP
|
||||
import net.minecraft.client.renderer.BlockRendererDispatcher
|
||||
import net.minecraft.client.renderer.WorldRenderer
|
||||
import net.minecraft.util.EnumFacing.UP
|
||||
import net.minecraft.util.EnumWorldBlockLayer
|
||||
import java.lang.Math.cos
|
||||
import java.lang.Math.sin
|
||||
|
||||
@@ -23,7 +28,7 @@ class RenderLeaves : AbstractBlockRenderingHandler(BetterFoliageMod.MOD_ID) {
|
||||
.scale(Config.leaves.size)
|
||||
.toCross(UP).addAll()
|
||||
}
|
||||
val snowedIcon = iconSet(BetterFoliageMod.LEGACY_DOMAIN, "better_leaves_snowed_%d")
|
||||
val snowedIcon = iconSet(BetterFoliageMod.LEGACY_DOMAIN, "blocks/better_leaves_snowed_%d")
|
||||
|
||||
val perturbs = vectorSet(64) { idx ->
|
||||
val angle = PI2 * idx / 64.0
|
||||
@@ -37,27 +42,30 @@ class RenderLeaves : AbstractBlockRenderingHandler(BetterFoliageMod.MOD_ID) {
|
||||
ctx.cameraDistance < Config.leaves.distance &&
|
||||
Config.blocks.leaves.matchesID(ctx.block)
|
||||
|
||||
override fun render(ctx: BlockContext, parent: RenderBlocks): Boolean {
|
||||
override fun render(ctx: BlockContext, dispatcher: BlockRendererDispatcher, renderer: WorldRenderer, layer: EnumWorldBlockLayer): Boolean {
|
||||
val isSnowed = ctx.block(up1).material.let {
|
||||
it == Material.snow || it == Material.craftedSnow
|
||||
}
|
||||
renderWorldBlockBase(ctx, dispatcher, renderer, null)
|
||||
val leafInfo = LeafRegistry[ctx.blockState(Int3.zero)] ?: return true
|
||||
val blockColor = ctx.blockData(Int3.zero, 0).color
|
||||
|
||||
if (renderWorldBlockBase(parent, face = alwaysRender)) return true
|
||||
|
||||
val leafInfo = LeafRegistry.leaves[ctx.icon(DOWN)]
|
||||
if (leafInfo != null) ShadersModIntegration.leaves {
|
||||
modelRenderer.updateShading(Int3.zero, allFaces)
|
||||
ShadersModIntegration.leaves(renderer) {
|
||||
val rand = ctx.semiRandomArray(2)
|
||||
(if (Config.leaves.dense) denseLeavesRot else normalLeavesRot).forEach { rotation ->
|
||||
modelRenderer.render(
|
||||
renderer,
|
||||
leavesModel.model,
|
||||
rotation,
|
||||
ctx.blockCenter + perturbs[rand[0]],
|
||||
icon = { ctx, qi, q -> leafInfo.roundLeafTexture },
|
||||
rotateUV = { q -> rand[1] },
|
||||
postProcess = noPost
|
||||
postProcess = { ctx, qi, q, vi, v -> multiplyColor(blockColor) }
|
||||
)
|
||||
}
|
||||
if (isSnowed) modelRenderer.render(
|
||||
renderer,
|
||||
leavesModel.model,
|
||||
Rotation.identity,
|
||||
ctx.blockCenter + perturbs[rand[0]],
|
||||
|
||||
@@ -3,9 +3,15 @@ package mods.betterfoliage.client.render
|
||||
import mods.betterfoliage.BetterFoliageMod
|
||||
import mods.betterfoliage.client.Client
|
||||
import mods.betterfoliage.client.config.Config
|
||||
import mods.betterfoliage.client.integration.ShadersModIntegration
|
||||
import mods.octarinecore.client.render.*
|
||||
import net.minecraft.client.renderer.RenderBlocks
|
||||
import net.minecraftforge.common.util.ForgeDirection.*
|
||||
import mods.octarinecore.common.Int3
|
||||
import mods.octarinecore.common.Rotation
|
||||
import net.minecraft.client.renderer.BlockRendererDispatcher
|
||||
import net.minecraft.client.renderer.WorldRenderer
|
||||
import net.minecraft.util.EnumFacing.DOWN
|
||||
import net.minecraft.util.EnumFacing.UP
|
||||
import net.minecraft.util.EnumWorldBlockLayer
|
||||
import org.apache.logging.log4j.Level
|
||||
|
||||
class RenderLilypad : AbstractBlockRenderingHandler(BetterFoliageMod.MOD_ID) {
|
||||
@@ -21,8 +27,8 @@ class RenderLilypad : AbstractBlockRenderingHandler(BetterFoliageMod.MOD_ID) {
|
||||
.setFlatShader(FlatOffsetNoColor(Int3.zero))
|
||||
.toCross(UP).addAll()
|
||||
}
|
||||
val rootIcon = iconSet(BetterFoliageMod.LEGACY_DOMAIN, "better_lilypad_roots_%d")
|
||||
val flowerIcon = iconSet(BetterFoliageMod.LEGACY_DOMAIN, "better_lilypad_flower_%d")
|
||||
val rootIcon = iconSet(BetterFoliageMod.LEGACY_DOMAIN, "blocks/better_lilypad_roots_%d")
|
||||
val flowerIcon = iconSet(BetterFoliageMod.LEGACY_DOMAIN, "blocks/better_lilypad_flower_%d")
|
||||
val perturbs = vectorSet(64) { modelIdx -> xzDisk(modelIdx) * Config.lilypad.hOffset }
|
||||
|
||||
override fun afterStitch() {
|
||||
@@ -35,21 +41,27 @@ class RenderLilypad : AbstractBlockRenderingHandler(BetterFoliageMod.MOD_ID) {
|
||||
ctx.cameraDistance < Config.lilypad.distance &&
|
||||
Config.blocks.lilypad.matchesID(ctx.block)
|
||||
|
||||
override fun render(ctx: BlockContext, parent: RenderBlocks): Boolean {
|
||||
if (renderWorldBlockBase(parent, face = alwaysRender)) return true
|
||||
override fun render(ctx: BlockContext, dispatcher: BlockRendererDispatcher, renderer: WorldRenderer, layer: EnumWorldBlockLayer): Boolean {
|
||||
renderWorldBlockBase(ctx, dispatcher, renderer, null)
|
||||
modelRenderer.updateShading(Int3.zero, allFaces)
|
||||
|
||||
val rand = ctx.semiRandomArray(5)
|
||||
modelRenderer.render(
|
||||
rootModel.model,
|
||||
Rotation.identity,
|
||||
ctx.blockCenter.add(perturbs[rand[2]]),
|
||||
forceFlat = true,
|
||||
icon = { ctx, qi, q -> rootIcon[rand[qi and 1]]!! },
|
||||
rotateUV = { 0 },
|
||||
postProcess = noPost
|
||||
)
|
||||
|
||||
ShadersModIntegration.grass(renderer) {
|
||||
modelRenderer.render(
|
||||
renderer,
|
||||
rootModel.model,
|
||||
Rotation.identity,
|
||||
ctx.blockCenter.add(perturbs[rand[2]]),
|
||||
forceFlat = true,
|
||||
icon = { ctx, qi, q -> rootIcon[rand[qi and 1]]!! },
|
||||
rotateUV = { 0 },
|
||||
postProcess = noPost
|
||||
)
|
||||
}
|
||||
|
||||
if (rand[3] < Config.lilypad.flowerChance) modelRenderer.render(
|
||||
renderer,
|
||||
flowerModel.model,
|
||||
Rotation.identity,
|
||||
ctx.blockCenter.add(perturbs[rand[4]]),
|
||||
|
||||
@@ -2,9 +2,16 @@ package mods.betterfoliage.client.render
|
||||
|
||||
import mods.betterfoliage.BetterFoliageMod
|
||||
import mods.betterfoliage.client.config.Config
|
||||
import mods.octarinecore.client.render.Axis
|
||||
import mods.octarinecore.client.render.BlockContext
|
||||
import net.minecraft.block.Block
|
||||
import mods.octarinecore.client.render.Quad
|
||||
import mods.octarinecore.client.render.ShadingContext
|
||||
import mods.octarinecore.client.resource.BlockTextureInspector
|
||||
import mods.octarinecore.common.Int3
|
||||
import net.minecraft.block.BlockLog
|
||||
import net.minecraft.block.state.IBlockState
|
||||
import net.minecraft.client.renderer.texture.TextureAtlasSprite
|
||||
import net.minecraft.client.renderer.texture.TextureMap
|
||||
import net.minecraft.util.EnumFacing.Axis
|
||||
|
||||
class RenderLog : AbstractRenderColumn(BetterFoliageMod.MOD_ID) {
|
||||
|
||||
@@ -13,18 +20,32 @@ class RenderLog : AbstractRenderColumn(BetterFoliageMod.MOD_ID) {
|
||||
ctx.cameraDistance < Config.roundLogs.distance &&
|
||||
Config.blocks.logs.matchesID(ctx.block)
|
||||
|
||||
override var axisFunc = { block: Block, meta: Int -> when ((meta shr 2) and 3) {
|
||||
1 -> Axis.X
|
||||
2 -> Axis.Z
|
||||
else -> Axis.Y
|
||||
} }
|
||||
override var axisFunc = { state: IBlockState ->
|
||||
when (state.getValue(BlockLog.LOG_AXIS).toString()) {
|
||||
"x" -> Axis.X
|
||||
"z" -> Axis.Z
|
||||
else -> Axis.Y
|
||||
}
|
||||
}
|
||||
|
||||
override val blockPredicate = { block: Block, meta: Int -> Config.blocks.logs.matchesID(block) }
|
||||
override val surroundPredicate = { block: Block -> block.isOpaqueCube && !Config.blocks.logs.matchesID(block) }
|
||||
val columnTextures = ColumnTextures(Config.blocks.logs)
|
||||
|
||||
override val blockPredicate = { state: IBlockState -> Config.blocks.logs.matchesID(state.block) }
|
||||
override val surroundPredicate = { state: IBlockState -> state.block.isOpaqueCube && !Config.blocks.logs.matchesID(state.block) }
|
||||
|
||||
override val connectPerpendicular: Boolean get() = Config.roundLogs.connectPerpendicular
|
||||
override val connectSolids: Boolean get() = Config.roundLogs.connectSolids
|
||||
override val lenientConnect: Boolean get() = Config.roundLogs.lenientConnect
|
||||
override val radiusLarge: Double get() = Config.roundLogs.radiusLarge
|
||||
override val radiusSmall: Double get() = Config.roundLogs.radiusSmall
|
||||
|
||||
override val downTexture = { ctx: ShadingContext, idx: Int, quad: Quad ->
|
||||
columnTextures[ctx.blockData(Int3.zero).state]?.bottomTexture
|
||||
}
|
||||
override val sideTexture = { ctx: ShadingContext, idx: Int, quad: Quad ->
|
||||
columnTextures[ctx.blockData(Int3.zero).state]?.sideTexture
|
||||
}
|
||||
override val upTexture = { ctx: ShadingContext, idx: Int, quad: Quad ->
|
||||
columnTextures[ctx.blockData(Int3.zero).state]?.topTexture
|
||||
}
|
||||
}
|
||||
@@ -3,15 +3,22 @@ package mods.betterfoliage.client.render
|
||||
import mods.betterfoliage.BetterFoliageMod
|
||||
import mods.betterfoliage.client.Client
|
||||
import mods.betterfoliage.client.config.Config
|
||||
import mods.octarinecore.client.render.*
|
||||
import mods.octarinecore.client.render.AbstractBlockRenderingHandler
|
||||
import mods.octarinecore.client.render.BlockContext
|
||||
import mods.octarinecore.client.render.modelRenderer
|
||||
import mods.octarinecore.client.render.noPost
|
||||
import mods.octarinecore.common.Double3
|
||||
import mods.octarinecore.common.Rotation
|
||||
import net.minecraft.block.material.Material
|
||||
import net.minecraft.client.renderer.RenderBlocks
|
||||
import net.minecraft.client.renderer.BlockRendererDispatcher
|
||||
import net.minecraft.client.renderer.WorldRenderer
|
||||
import net.minecraft.init.Blocks
|
||||
import net.minecraft.util.EnumWorldBlockLayer
|
||||
import org.apache.logging.log4j.Level.INFO
|
||||
|
||||
class RenderMycelium : AbstractBlockRenderingHandler(BetterFoliageMod.MOD_ID) {
|
||||
|
||||
val myceliumIcon = iconSet(BetterFoliageMod.LEGACY_DOMAIN, "better_mycel_%d")
|
||||
val myceliumIcon = iconSet(BetterFoliageMod.LEGACY_DOMAIN, "blocks/better_mycel_%d")
|
||||
val myceliumModel = modelSet(64, RenderGrass.grassTopQuads)
|
||||
|
||||
override fun afterStitch() {
|
||||
@@ -24,17 +31,17 @@ class RenderMycelium : AbstractBlockRenderingHandler(BetterFoliageMod.MOD_ID) {
|
||||
ctx.cameraDistance < Config.shortGrass.distance
|
||||
}
|
||||
|
||||
override fun render(ctx: BlockContext, parent: RenderBlocks): Boolean {
|
||||
val isSnowed = ctx.block(up1).material.let {
|
||||
it == Material.snow || it == Material.craftedSnow
|
||||
}
|
||||
override fun render(ctx: BlockContext, dispatcher: BlockRendererDispatcher, renderer: WorldRenderer, layer: EnumWorldBlockLayer): Boolean {
|
||||
val isSnowed = ctx.block(up1).isSnow
|
||||
|
||||
renderWorldBlockBase(ctx, dispatcher, renderer, null)
|
||||
|
||||
if (renderWorldBlockBase(parent, face = alwaysRender)) return true
|
||||
if (isSnowed && !Config.shortGrass.snowEnabled) return true
|
||||
if (ctx.block(up1).isOpaqueCube) return true
|
||||
|
||||
val rand = ctx.semiRandomArray(2)
|
||||
modelRenderer.render(
|
||||
renderer,
|
||||
myceliumModel[rand[0]],
|
||||
Rotation.identity,
|
||||
ctx.blockCenter + (if (isSnowed) snowOffset else Double3.zero),
|
||||
|
||||
@@ -4,16 +4,19 @@ import mods.betterfoliage.BetterFoliageMod
|
||||
import mods.betterfoliage.client.Client
|
||||
import mods.betterfoliage.client.config.Config
|
||||
import mods.octarinecore.client.render.*
|
||||
import mods.octarinecore.common.Int3
|
||||
import mods.octarinecore.common.Rotation
|
||||
import mods.octarinecore.random
|
||||
import net.minecraft.client.renderer.RenderBlocks
|
||||
import net.minecraft.client.renderer.BlockRendererDispatcher
|
||||
import net.minecraft.client.renderer.WorldRenderer
|
||||
import net.minecraft.init.Blocks
|
||||
import net.minecraftforge.common.util.ForgeDirection.DOWN
|
||||
import net.minecraftforge.common.util.ForgeDirection.UP
|
||||
import net.minecraft.util.EnumWorldBlockLayer
|
||||
import net.minecraft.util.EnumFacing.*
|
||||
import org.apache.logging.log4j.Level.INFO
|
||||
|
||||
class RenderNetherrack : AbstractBlockRenderingHandler(BetterFoliageMod.MOD_ID) {
|
||||
|
||||
val netherrackIcon = iconSet(BetterFoliageMod.LEGACY_DOMAIN, "better_netherrack_%d")
|
||||
val netherrackIcon = iconSet(BetterFoliageMod.LEGACY_DOMAIN, "blocks/better_netherrack_%d")
|
||||
val netherrackModel = modelSet(64) { modelIdx ->
|
||||
verticalRectangle(x1 = -0.5, z1 = 0.5, x2 = 0.5, z2 = -0.5, yTop = -0.5,
|
||||
yBottom = -0.5 - random(Config.netherrack.heightMin, Config.netherrack.heightMax))
|
||||
@@ -33,12 +36,14 @@ class RenderNetherrack : AbstractBlockRenderingHandler(BetterFoliageMod.MOD_ID)
|
||||
ctx.cameraDistance < Config.netherrack.distance
|
||||
}
|
||||
|
||||
override fun render(ctx: BlockContext, parent: RenderBlocks): Boolean {
|
||||
if (renderWorldBlockBase(parent, face = alwaysRender)) return true
|
||||
override fun render(ctx: BlockContext, dispatcher: BlockRendererDispatcher, renderer: WorldRenderer, layer: EnumWorldBlockLayer): Boolean {
|
||||
renderWorldBlockBase(ctx, dispatcher, renderer, null)
|
||||
if (ctx.block(down1).isOpaqueCube) return true
|
||||
modelRenderer.updateShading(Int3.zero, allFaces)
|
||||
|
||||
val rand = ctx.semiRandomArray(2)
|
||||
modelRenderer.render(
|
||||
renderer,
|
||||
netherrackModel[rand[0]],
|
||||
Rotation.identity,
|
||||
icon = { ctx, qi, q -> netherrackIcon[rand[qi and 1]]!! },
|
||||
|
||||
@@ -5,16 +5,20 @@ import mods.betterfoliage.client.Client
|
||||
import mods.betterfoliage.client.config.Config
|
||||
import mods.betterfoliage.client.integration.ShadersModIntegration
|
||||
import mods.octarinecore.client.render.*
|
||||
import mods.octarinecore.common.Int3
|
||||
import mods.octarinecore.common.Rotation
|
||||
import mods.octarinecore.random
|
||||
import net.minecraft.block.material.Material
|
||||
import net.minecraft.client.renderer.RenderBlocks
|
||||
import net.minecraftforge.common.util.ForgeDirection.UP
|
||||
import net.minecraft.client.renderer.BlockRendererDispatcher
|
||||
import net.minecraft.client.renderer.WorldRenderer
|
||||
import net.minecraft.util.EnumFacing.UP
|
||||
import net.minecraft.util.EnumWorldBlockLayer
|
||||
import org.apache.logging.log4j.Level
|
||||
|
||||
class RenderReeds : AbstractBlockRenderingHandler(BetterFoliageMod.MOD_ID) {
|
||||
|
||||
val noise = simplexNoise()
|
||||
val reedIcons = iconSet(Client.genReeds.generatedResource("${BetterFoliageMod.LEGACY_DOMAIN}:better_reed_%d"))
|
||||
val reedIcons = iconSet(Client.genReeds.generatedResource("${BetterFoliageMod.LEGACY_DOMAIN}:blocks/better_reed_%d"))
|
||||
val reedModels = modelSet(64) { modelIdx ->
|
||||
val height = random(Config.reed.heightMin, Config.reed.heightMax)
|
||||
val waterline = 0.875f
|
||||
@@ -44,14 +48,16 @@ class RenderReeds : AbstractBlockRenderingHandler(BetterFoliageMod.MOD_ID) {
|
||||
ctx.block(up1).material == Material.water &&
|
||||
Config.blocks.dirt.matchesID(ctx.block) &&
|
||||
ctx.biomeId in Config.reed.biomes &&
|
||||
noise[ctx.x, ctx.z] < Config.reed.population
|
||||
noise[ctx.pos] < Config.reed.population
|
||||
|
||||
override fun render(ctx: BlockContext, parent: RenderBlocks): Boolean {
|
||||
if (renderWorldBlockBase(parent, face = alwaysRender)) return true
|
||||
override fun render(ctx: BlockContext, dispatcher: BlockRendererDispatcher, renderer: WorldRenderer, layer: EnumWorldBlockLayer): Boolean {
|
||||
renderWorldBlockBase(ctx, dispatcher, renderer, null)
|
||||
modelRenderer.updateShading(Int3.zero, allFaces)
|
||||
|
||||
val iconVar = ctx.random(1)
|
||||
ShadersModIntegration.grass(Config.reed.shaderWind) {
|
||||
ShadersModIntegration.grass(renderer, Config.reed.shaderWind) {
|
||||
modelRenderer.render(
|
||||
renderer,
|
||||
reedModels[ctx.random(0)],
|
||||
Rotation.identity,
|
||||
forceFlat = true,
|
||||
|
||||
@@ -3,13 +3,14 @@ package mods.betterfoliage.client.render
|
||||
|
||||
import mods.octarinecore.PI2
|
||||
import mods.octarinecore.client.render.*
|
||||
import mods.octarinecore.common.Double3
|
||||
import mods.octarinecore.common.Int3
|
||||
import mods.octarinecore.common.Rotation
|
||||
import mods.octarinecore.common.times
|
||||
import net.minecraft.block.Block
|
||||
import net.minecraft.block.material.Material
|
||||
import net.minecraft.tileentity.TileEntity
|
||||
import net.minecraft.world.IBlockAccess
|
||||
import net.minecraft.world.biome.BiomeGenBase
|
||||
import net.minecraftforge.common.util.ForgeDirection
|
||||
import net.minecraftforge.common.util.ForgeDirection.*
|
||||
import net.minecraft.util.EnumFacing
|
||||
import net.minecraft.util.EnumFacing.*
|
||||
|
||||
val up1 = Int3(1 to UP)
|
||||
val up2 = Int3(2 to UP)
|
||||
@@ -24,11 +25,11 @@ val greywash: RenderVertex.(ShadingContext, Int, Quad, Int, Vertex)->Unit = { ct
|
||||
|
||||
val Block.isSnow: Boolean get() = material.let { it == Material.snow || it == Material.craftedSnow }
|
||||
|
||||
fun Quad.toCross(rotAxis: ForgeDirection, trans: (Quad)->Quad) =
|
||||
fun Quad.toCross(rotAxis: EnumFacing, trans: (Quad)->Quad) =
|
||||
(0..3).map { rotIdx ->
|
||||
trans(rotate(Rotation.rot90[rotAxis.ordinal] * rotIdx).mirrorUV(rotIdx > 1, false))
|
||||
}
|
||||
fun Quad.toCross(rotAxis: ForgeDirection) = toCross(rotAxis) { it }
|
||||
fun Quad.toCross(rotAxis: EnumFacing) = toCross(rotAxis) { it }
|
||||
|
||||
fun xzDisk(modelIdx: Int) = (PI2 * modelIdx / 64.0).let { Double3(Math.cos(it), 0.0, Math.sin(it)) }
|
||||
|
||||
|
||||
Reference in New Issue
Block a user