diff --git a/src/main/java/mods/betterfoliage/client/render/impl/RenderBlockGrass.java b/src/main/java/mods/betterfoliage/client/render/impl/RenderBlockGrass.java index 11c64e62..265c4add 100644 --- a/src/main/java/mods/betterfoliage/client/render/impl/RenderBlockGrass.java +++ b/src/main/java/mods/betterfoliage/client/render/impl/RenderBlockGrass.java @@ -12,6 +12,7 @@ import mods.betterfoliage.common.config.Config; import net.minecraft.block.Block; import net.minecraft.block.material.Material; +import net.minecraft.client.Minecraft; import net.minecraft.client.renderer.RenderBlocks; import net.minecraft.client.renderer.Tessellator; import net.minecraft.util.IIcon; @@ -29,6 +30,7 @@ public enum RenderMode { DEFAULT, TFC }; public IconSet grassIcons = new IconSet("bettergrassandleaves", "better_grass_long_%d"); public IconSet snowGrassIcons = new IconSet("bettergrassandleaves", "better_grass_snowed_%d"); + public IconSet hangingGrassIcons = new IconSet("bettergrassandleaves", "better_grass_side_%d"); public IIcon grassGenIcon; public IIcon snowGrassGenIcon; @@ -40,7 +42,7 @@ public enum RenderMode { DEFAULT, TFC }; public boolean isBlockAccepted(IBlockAccess blockAccess, int x, int y, int z, Block block, int original) { - return Config.grass.matchesID(block) && getCameraDistance(x, y, z) <= Config.grassDistance; + return Config.grass.matchesID(block); } public boolean renderWorldBlock(IBlockAccess world, int x, int y, int z, Block block, int modelId, RenderBlocks renderer) { @@ -62,12 +64,28 @@ public boolean renderWorldBlock(IBlockAccess world, int x, int y, int z, Block b boolean useTextureColor = (avgColor != null); renderWorldBlockBase(2, world, x, y, z, block, modelId, renderer); - if (!Config.grassEnabled) return true; - if (isSnowTop && !Config.grassSnowEnabled) return true; boolean isAirTop = blockAccess.isAirBlock(x, y + 1, z); + int distance = getCameraDistance(x, y, z); - if (isSnowTop || isAirTop) { + if (Config.hangingGrassEnabled && distance <= Config.hangingGrassDistance) { + // render hanging grass + Double3 blockCenter = new Double3(x + 0.5, y + 0.5, z + 0.5); + int iconVariation = getSemiRandomFromPos(x, y, z, 2); + + Tessellator.instance.setBrightness(getBrightness(block, x, y + 1, z)); + if (isSnowTop) + Tessellator.instance.setColorOpaque(230, 230, 230); + else + Tessellator.instance.setColorOpaque_I(useTextureColor ? avgColor : blockColor); + + if (!blockAccess.getBlock(x + 1, y, z).isOpaqueCube()) renderHangingGrass(blockCenter, ForgeDirection.EAST, Config.hangingGrassSize, Config.hangingGrassSeparation, hangingGrassIcons.get(iconVariation)); + if (!blockAccess.getBlock(x - 1, y, z).isOpaqueCube()) renderHangingGrass(blockCenter, ForgeDirection.WEST, Config.hangingGrassSize, Config.hangingGrassSeparation, hangingGrassIcons.get(iconVariation)); + if (!blockAccess.getBlock(x, y, z + 1).isOpaqueCube()) renderHangingGrass(blockCenter, ForgeDirection.SOUTH, Config.hangingGrassSize, Config.hangingGrassSeparation, hangingGrassIcons.get(iconVariation)); + if (!blockAccess.getBlock(x, y, z - 1).isOpaqueCube()) renderHangingGrass(blockCenter, ForgeDirection.NORTH, Config.hangingGrassSize, Config.hangingGrassSeparation, hangingGrassIcons.get(iconVariation)); + } + + if (Config.grassEnabled && distance <= Config.grassDistance && (isAirTop || (isSnowTop && Config.grassSnowEnabled))) { // render short grass int iconVariation = getSemiRandomFromPos(x, y, z, 0); int heightVariation = getSemiRandomFromPos(x, y, z, 1); @@ -94,9 +112,28 @@ public boolean renderWorldBlock(IBlockAccess world, int x, int y, int z, Block b Tessellator.instance.setBrightness(getBrightness(block, x, y + 1, z)); renderCrossedSideQuads(new Double3(x + 0.5, y + 1.0 + (isSnowTop ? 0.0625 : 0.0), z + 0.5), ForgeDirection.UP, scale, halfHeight, pRot[iconVariation], Config.grassHOffset, shortGrassIcon, 0, false); } + return true; } + protected void renderHangingGrass(Double3 blockCenter, ForgeDirection face, double length, double separation, IIcon icon) { + Double3 edgeCenter = blockCenter.add(new Double3(face).scale(0.5)).add(0.0, 0.5, 0.0); + Double3 edge = new Double3(faceDir1[face.ordinal()]).scale(0.5); + Double3 extrude = new Double3(face).scale(separation).add(0.0, -length, 0.0); + + ShadingValues shP = null; + ShadingValues shN = null; + if (Minecraft.isAmbientOcclusionEnabled() && !noShading) { + shP = getAoLookup(ForgeDirection.UP, face, faceDir1[face.ordinal()]); + shN = getAoLookup(ForgeDirection.UP, face, faceDir1[face.getOpposite().ordinal()]); + } + + Double3 vert1 = edgeCenter.add(edge); + Double3 vert2 = edgeCenter.sub(edge); + renderQuad(icon, vert1, vert2, vert2.add(extrude), vert1.add(extrude), uValues, vValues, shP, shN, shN, shP); +// renderQuadWithShading(icon, edgeCenter.add(extrude.scale(0.5)), edge.inverse(), extrude.scale(0.5), 2, faceAOPP, faceAONP, faceAONP, faceAOPP); + } + protected void checkConnectedGrass(int x, int y, int z) { if (isSnowTop) { connectXP = false; @@ -182,10 +219,12 @@ public void handleTextureReload(TextureStitchEvent.Pre event) { grassIcons.registerIcons(event.map); snowGrassIcons.registerIcons(event.map); + hangingGrassIcons.registerIcons(event.map); grassGenIcon = event.map.registerIcon("bf_shortgrass:minecraft:tallgrass"); snowGrassGenIcon = event.map.registerIcon("bf_shortgrass_snow:minecraft:tallgrass"); BetterFoliage.log.info(String.format("Found %d short grass textures", grassIcons.numLoaded)); BetterFoliage.log.info(String.format("Found %d snowy grass textures", snowGrassIcons.numLoaded)); + BetterFoliage.log.info(String.format("Found %d hanging grass textures", hangingGrassIcons.numLoaded)); } } diff --git a/src/main/java/mods/betterfoliage/common/config/Config.java b/src/main/java/mods/betterfoliage/common/config/Config.java index 83b24f7d..6e37004e 100644 --- a/src/main/java/mods/betterfoliage/common/config/Config.java +++ b/src/main/java/mods/betterfoliage/common/config/Config.java @@ -26,7 +26,7 @@ public class Config { public enum Category { - blockTypes, extraLeaves, shortGrass, cactus, lilypad, reed, algae, coral, netherrack, fallingLeaves, risingSoul, connectedGrass, roundLogs; + blockTypes, extraLeaves, shortGrass, hangingGrass, cactus, lilypad, reed, algae, coral, netherrack, fallingLeaves, risingSoul, connectedGrass, roundLogs; } /** {@link Configuration} object bound to the config file */ @@ -59,6 +59,11 @@ public enum Category { public static boolean myceliumEnabled; public static boolean grassSnowEnabled; + public static boolean hangingGrassEnabled; + public static int hangingGrassDistance; + public static double hangingGrassSize; + public static double hangingGrassSeparation; + public static boolean cactusEnabled; public static int cactusDistance; @@ -168,6 +173,11 @@ public static void updateValues() { myceliumEnabled = getBoolean(Category.shortGrass, "myceliumEnabled", true, "betterfoliage.shortGrass.myceliumEnabled"); grassSnowEnabled = getBoolean(Category.shortGrass, "snowEnabled", true, "betterfoliage.shortGrass.grassSnowEnabled"); + hangingGrassEnabled = getBoolean(Category.hangingGrass, "enabled", false, "betterfoliage.enabled"); + hangingGrassDistance = getInt(Category.hangingGrass, "distance", 1000, 1, 1000, "betterfoliage.distance"); + hangingGrassSize = getDouble(Category.hangingGrass, "size", 0.75, 0.25, 1.5, "betterfoliage.size"); + hangingGrassSeparation = getDouble(Category.hangingGrass, "separation", 0.25, 0.0, 0.5, "betterfoliage.hangingGrass.separation"); + cactusEnabled = getBoolean(Category.cactus, "enabled", true, "betterfoliage.enabled"); cactusDistance = getInt(Category.cactus, "distance", 1000, 1, 1000, "betterfoliage.distance"); @@ -241,7 +251,7 @@ public static void updateValues() { ctxGrassClassicEnabled = getBoolean(Category.connectedGrass, "classic", true, "betterfoliage.connectedGrass.classic"); ctxGrassAggressiveEnabled= getBoolean(Category.connectedGrass, "aggressive", true, "betterfoliage.connectedGrass.aggressive"); - logsEnabled = getBoolean(Category.roundLogs, "enabled", true, "betterfoliage.enabled"); + logsEnabled = getBoolean(Category.roundLogs, "enabled", false, "betterfoliage.enabled"); logsDistance = getInt(Category.roundLogs, "distance", 1000, 1, 1000, "betterfoliage.distance"); logsSmallRadius = getDouble(Category.roundLogs, "smallRadius", 0.25, 0.0, 0.5, "betterfoliage.roundLogs.smallRadius"); logsLargeRadius = getDouble(Category.roundLogs, "largeRadius", 0.45, 0.0, 0.5, "betterfoliage.roundLogs.largeRadius"); @@ -264,6 +274,7 @@ public static void updateValues() { setOrder(Category.extraLeaves, "enabled", "distance", "dense", "skewMode", "hOffset", "vOffset", "size"); setOrder(Category.shortGrass, "enabled", "distance", "myceliumEnabled", "snowEnabled", "useGenerated", "hOffset", "heightMin", "heightMax", "size", "shaderWind"); + setOrder(Category.hangingGrass, "enabled", "distance", "size", "separation"); setOrder(Category.lilypad, "enabled", "distance", "hOffset", "flowerChance"); setOrder(Category.reed, "enabled", "distance", "hOffset", "heightMin", "heightMax", "population", "biomeList", "shaderWind"); setOrder(Category.algae, "enabled", "distance", "hOffset", "heightMin", "heightMax", "size", "population", "biomeList"); diff --git a/src/main/resources/assets/betterfoliage/lang/en_US.lang b/src/main/resources/assets/betterfoliage/lang/en_US.lang index 6a7cb83d..7d240dce 100644 --- a/src/main/resources/assets/betterfoliage/lang/en_US.lang +++ b/src/main/resources/assets/betterfoliage/lang/en_US.lang @@ -66,6 +66,12 @@ betterfoliage.shortGrass.grassEnabled.tooltip=Is this feature enabled for grass betterfoliage.shortGrass.grassSnowEnabled=Enable under snow betterfoliage.shortGrass.grassSnowEnabled.tooltip=Enable on snowed grass blocks? +betterfoliage.hangingGrass=Hanging Grass +betterfoliage.hangingGrass.tooltip=Grass tufts hanging down from the top edges of grass blocks + +betterfoliage.hangingGrass.separation=Separation +betterfoliage.hangingGrass.separation.tooltip=How much the hanging grass stands out from the block + betterfoliage.cactus=Better Cactus betterfoliage.cactus.tooltip=Enhance cactus with extra bits and smooth shading