From ce37687a1b490e021d0493b19d969dca1ef73481 Mon Sep 17 00:00:00 2001 From: octarine-noise Date: Mon, 18 Aug 2014 22:57:39 +0200 Subject: [PATCH] add connected grass --- .../client/BetterFoliageClient.java | 8 +- .../client/render/RenderBlockAOBase.java | 22 ++++ .../render/impl/RenderBlockBetterCoral.java | 14 +- .../render/impl/RenderBlockBetterGrass.java | 123 ++++++++++-------- .../render/impl/RenderBlockBetterLeaves.java | 22 +--- .../impl/RenderBlockBetterMycelium.java | 69 ++++++++++ .../render/impl/RenderBlockBetterReed.java | 14 +- .../impl/RenderBlocksBetterGrassSide.java | 50 +++++++ .../common/config/BetterFoliageConfig.java | 6 + .../common/util/OffsetBlockAccess.java | 100 ++++++++++++++ 10 files changed, 329 insertions(+), 99 deletions(-) create mode 100644 src/main/java/mods/betterfoliage/client/render/impl/RenderBlockBetterMycelium.java create mode 100644 src/main/java/mods/betterfoliage/client/render/impl/RenderBlocksBetterGrassSide.java create mode 100644 src/main/java/mods/betterfoliage/common/util/OffsetBlockAccess.java diff --git a/src/main/java/mods/betterfoliage/client/BetterFoliageClient.java b/src/main/java/mods/betterfoliage/client/BetterFoliageClient.java index 6da977c..c56f397 100644 --- a/src/main/java/mods/betterfoliage/client/BetterFoliageClient.java +++ b/src/main/java/mods/betterfoliage/client/BetterFoliageClient.java @@ -12,7 +12,9 @@ import mods.betterfoliage.client.render.impl.RenderBlockBetterCoral; import mods.betterfoliage.client.render.impl.RenderBlockBetterGrass; import mods.betterfoliage.client.render.impl.RenderBlockBetterLeaves; import mods.betterfoliage.client.render.impl.RenderBlockBetterLilypad; +import mods.betterfoliage.client.render.impl.RenderBlockBetterMycelium; import mods.betterfoliage.client.render.impl.RenderBlockBetterReed; +import mods.betterfoliage.client.render.impl.RenderBlocksBetterGrassSide; import mods.betterfoliage.client.resource.LeafGenerator; import mods.betterfoliage.client.resource.LeafParticleTextures; import mods.betterfoliage.client.resource.LeafTextureEnumerator; @@ -49,13 +51,15 @@ public class BetterFoliageClient { FMLCommonHandler.instance().bus().register(new KeyHandler()); BetterFoliage.log.info("Registering renderers"); - registerRenderer(new RenderBlockBetterLeaves()); - registerRenderer(new RenderBlockBetterGrass()); registerRenderer(new RenderBlockBetterCactus()); registerRenderer(new RenderBlockBetterLilypad()); + registerRenderer(new RenderBlockBetterMycelium()); + registerRenderer(new RenderBlockBetterLeaves()); + registerRenderer(new RenderBlockBetterGrass()); registerRenderer(new RenderBlockBetterReed()); registerRenderer(new RenderBlockBetterAlgae()); registerRenderer(new RenderBlockBetterCoral()); + registerRenderer(new RenderBlocksBetterGrassSide()); MinecraftForge.EVENT_BUS.register(wind); FMLCommonHandler.instance().bus().register(wind); diff --git a/src/main/java/mods/betterfoliage/client/render/RenderBlockAOBase.java b/src/main/java/mods/betterfoliage/client/render/RenderBlockAOBase.java index a65654f..b308faa 100644 --- a/src/main/java/mods/betterfoliage/client/render/RenderBlockAOBase.java +++ b/src/main/java/mods/betterfoliage/client/render/RenderBlockAOBase.java @@ -6,6 +6,7 @@ import java.util.Iterator; import java.util.List; import mods.betterfoliage.common.util.Double3; +import mods.betterfoliage.common.util.Utils; import net.minecraft.block.Block; import net.minecraft.client.Minecraft; import net.minecraft.client.renderer.RenderBlocks; @@ -13,10 +14,12 @@ import net.minecraft.client.renderer.Tessellator; import net.minecraft.init.Blocks; import net.minecraft.util.IIcon; import net.minecraft.util.MathHelper; +import net.minecraft.world.IBlockAccess; import net.minecraftforge.common.util.ForgeDirection; import org.lwjgl.opengl.GL11; +import cpw.mods.fml.client.registry.ISimpleBlockRenderingHandler; import cpw.mods.fml.relauncher.Side; import cpw.mods.fml.relauncher.SideOnly; @@ -124,6 +127,25 @@ public class RenderBlockAOBase extends RenderBlocks { return 0; } + protected void renderWorldBlockBase(int pass, IBlockAccess world, int x, int y, int z, Block block, int modelId, RenderBlocks renderer) { + // use original renderer for block breaking overlay + if (renderer.hasOverrideBlockTexture()) { + renderer.setRenderBoundsFromBlock(block); + renderer.renderStandardBlock(block, x, y, z); + return; + } + + // render block + setPassCounters(1); + setRenderBoundsFromBlock(block); + ISimpleBlockRenderingHandler handler = Utils.getRenderingHandler(block.getRenderType()); + if (handler != null) { + handler.renderWorldBlock(world, x, y, z, block, block.getRenderType(), this); + } else { + renderStandardBlock(block, x, y, z); + } + } + protected void renderStandardBlockAsItem(RenderBlocks renderer, Block p_147800_1_, int p_147800_2_, float p_147800_3_) { Tessellator tessellator = Tessellator.instance; boolean flag = p_147800_1_ == Blocks.grass; diff --git a/src/main/java/mods/betterfoliage/client/render/impl/RenderBlockBetterCoral.java b/src/main/java/mods/betterfoliage/client/render/impl/RenderBlockBetterCoral.java index 218b64b..ae65abc 100644 --- a/src/main/java/mods/betterfoliage/client/render/impl/RenderBlockBetterCoral.java +++ b/src/main/java/mods/betterfoliage/client/render/impl/RenderBlockBetterCoral.java @@ -36,20 +36,8 @@ public class RenderBlockBetterCoral extends RenderBlockAOBase implements IRender } public boolean renderWorldBlock(IBlockAccess world, int x, int y, int z, Block block, int modelId, RenderBlocks renderer) { - // store world for later use blockAccess = world; - - // use original renderer for block breaking overlay - if (renderer.hasOverrideBlockTexture()) { - renderer.setRenderBoundsFromBlock(block); - renderer.renderStandardBlock(block, x, y, z); - return true; - } - - // render sand block - setPassCounters(1); - setRenderBoundsFromBlock(block); - renderStandardBlock(block, x, y, z); + renderWorldBlockBase(1, world, x, y, z, block, modelId, renderer); Double3 blockCenter = new Double3(x + 0.5, y + 0.5, z + 0.5); double offset = pRand[getSemiRandomFromPos(x, y, z, 6)] * BetterFoliage.config.coralVOffset.value; diff --git a/src/main/java/mods/betterfoliage/client/render/impl/RenderBlockBetterGrass.java b/src/main/java/mods/betterfoliage/client/render/impl/RenderBlockBetterGrass.java index 38d493f..b05cf57 100644 --- a/src/main/java/mods/betterfoliage/client/render/impl/RenderBlockBetterGrass.java +++ b/src/main/java/mods/betterfoliage/client/render/impl/RenderBlockBetterGrass.java @@ -7,7 +7,6 @@ import mods.betterfoliage.client.render.IRenderBlockDecorator; import mods.betterfoliage.client.render.IconSet; import mods.betterfoliage.client.render.RenderBlockAOBase; import mods.betterfoliage.common.util.Double3; -import mods.betterfoliage.common.util.Utils; import net.minecraft.block.Block; import net.minecraft.client.renderer.RenderBlocks; import net.minecraft.client.renderer.Tessellator; @@ -16,7 +15,6 @@ import net.minecraft.util.IIcon; import net.minecraft.world.IBlockAccess; import net.minecraftforge.client.event.TextureStitchEvent; import net.minecraftforge.common.util.ForgeDirection; -import cpw.mods.fml.client.registry.ISimpleBlockRenderingHandler; import cpw.mods.fml.common.eventhandler.SubscribeEvent; import cpw.mods.fml.relauncher.Side; import cpw.mods.fml.relauncher.SideOnly; @@ -26,83 +24,106 @@ public class RenderBlockBetterGrass extends RenderBlockAOBase implements IRender public IconSet grassIcons = new IconSet("bettergrassandleaves", "better_grass_long_%d"); public IconSet snowGrassIcons = new IconSet("bettergrassandleaves", "better_grass_snowed_%d"); - public IconSet myceliumIcons = new IconSet("bettergrassandleaves", "better_mycel_%d"); public IIcon grassGenIcon; public IIcon snowGrassGenIcon; + protected IIcon grassTopIcon; + protected boolean connectXP, connectXN, connectZP, connectZN; + public boolean isBlockAccepted(IBlockAccess blockAccess, int x, int y, int z, Block block, int original) { - if (!BetterFoliage.config.grassEnabled) return false; - if (!(BetterFoliageClient.grass.matchesID(block) || block == Blocks.mycelium)) return false; - if (!blockAccess.isAirBlock(x, y + 1, z) && blockAccess.getBlock(x, y + 1, z) != Blocks.snow_layer) return false; - return true; + return BetterFoliageClient.grass.matchesID(block); } public boolean renderWorldBlock(IBlockAccess world, int x, int y, int z, Block block, int modelId, RenderBlocks renderer) { - // store world for later use blockAccess = world; - // use original renderer for block breaking overlay - if (renderer.hasOverrideBlockTexture()) { - renderer.setRenderBoundsFromBlock(block); - renderer.renderStandardBlock(block, x, y, z); - return true; - } + // check for connected grass + checkConnectedGrass(x, y, z); + grassTopIcon = block.getIcon(blockAccess, x, y, z, ForgeDirection.UP.ordinal()); - // render grass block - setPassCounters(1); - setRenderBoundsFromBlock(block); - if (block.getRenderType() == 0) { - renderStandardBlock(block, x, y, z); - } else { - ISimpleBlockRenderingHandler handler = Utils.getRenderingHandler(block.getRenderType()); - handler.renderWorldBlock(world, x, y, z, block, block.getRenderType(), this); - } + renderWorldBlockBase(1, world, x, y, z, block, modelId, renderer); + if (!BetterFoliage.config.grassEnabled) return true; - int variation = getSemiRandomFromPos(x, y, z, 0); - int heightVariation = getSemiRandomFromPos(x, y, z, 1); - boolean isSnowed = blockAccess.getBlock(x, y + 1, z) == Blocks.snow_layer; + boolean isSnowTop = blockAccess.getBlock(x, y + 1, z) == Blocks.snow_layer; + boolean isAirTop = blockAccess.isAirBlock(x, y + 1, z); - IIcon renderIcon = null; - if (BetterFoliageClient.grass.matchesID(block)) { - if (BetterFoliage.config.grassUseGenerated) { - renderIcon = isSnowed ? snowGrassGenIcon : grassGenIcon; + if (isSnowTop || isAirTop) { + // render short grass + int iconVariation = getSemiRandomFromPos(x, y, z, 0); + int heightVariation = getSemiRandomFromPos(x, y, z, 1); + + double scale = BetterFoliage.config.grassSize.value * 0.5; + double halfHeight = 0.5 * (BetterFoliage.config.grassHeightMin.value + pRand[heightVariation] * (BetterFoliage.config.grassHeightMax.value - BetterFoliage.config.grassHeightMin.value)); + + IIcon shortGrassIcon = null; + if (isSnowTop) { + // clear biome colors + aoYPXZNN.setGray(0.9f); aoYPXZNP.setGray(0.9f); aoYPXZPN.setGray(0.9f); aoYPXZPP.setGray(0.9f); + Tessellator.instance.setColorOpaque(230, 230, 230); + shortGrassIcon = BetterFoliage.config.grassUseGenerated ? snowGrassGenIcon : snowGrassIcons.get(iconVariation); } else { - renderIcon = isSnowed ? snowGrassIcons.get(variation) : grassIcons.get(variation); + Tessellator.instance.setColorOpaque_I(block.colorMultiplier(blockAccess, x, y, z)); + shortGrassIcon = BetterFoliage.config.grassUseGenerated ? grassGenIcon : grassIcons.get(iconVariation); } - } else if (block == Blocks.mycelium && !isSnowed) { - renderIcon = myceliumIcons.get(variation); + if (shortGrassIcon == null) return true; + + ShadersModIntegration.startGrassQuads(); + 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], BetterFoliage.config.grassHOffset.value, shortGrassIcon, 0, false); } - if (renderIcon == null) return true; - - double scale = BetterFoliage.config.grassSize.value * 0.5; - double halfHeight = 0.5 * (BetterFoliage.config.grassHeightMin.value + pRand[heightVariation] * (BetterFoliage.config.grassHeightMax.value - BetterFoliage.config.grassHeightMin.value)); - - if (isSnowed) { - aoYPXZNN.setGray(0.9f); aoYPXZNP.setGray(0.9f); aoYPXZPN.setGray(0.9f); aoYPXZPP.setGray(0.9f); - Tessellator.instance.setColorOpaque(230, 230, 230); - } - - // render short grass - ShadersModIntegration.startGrassQuads(); - Tessellator.instance.setBrightness(getBrightness(block, x, y + 1, z)); - Tessellator.instance.setColorOpaque_I(block.colorMultiplier(blockAccess, x, y, z)); - renderCrossedSideQuads(new Double3(x + 0.5, y + 1.0 + (isSnowed ? 0.0625 : 0.0), z + 0.5), ForgeDirection.UP, scale, halfHeight, pRot[variation], BetterFoliage.config.grassHOffset.value, renderIcon, 0, false); - return true; } + protected void checkConnectedGrass(int x, int y, int z) { + Block blockBelow = blockAccess.getBlock(x, y - 1, z); + if (BetterFoliage.config.ctxGrassAggressiveEnabled && (BetterFoliageClient.grass.matchesID(blockBelow) || BetterFoliageClient.dirt.matchesID(blockBelow))) { + connectXP = true; + connectXN = true; + connectZP = true; + connectZN = true; + } else if (BetterFoliage.config.ctxGrassClassicEnabled) { + connectXP = BetterFoliageClient.grass.matchesID(blockAccess.getBlock(x + 1, y - 1, z)); + connectXN = BetterFoliageClient.grass.matchesID(blockAccess.getBlock(x - 1, y - 1, z)); + connectZP = BetterFoliageClient.grass.matchesID(blockAccess.getBlock(x, y - 1, z + 1)); + connectZN = BetterFoliageClient.grass.matchesID(blockAccess.getBlock(x, y - 1, z - 1)); + } else { + connectXP = false; + connectXN = false; + connectZP = false; + connectZN = false; + } + } + + @Override + public void renderFaceZNeg(Block block, double x, double y, double z, IIcon icon) { + super.renderFaceZNeg(block, x, y, z, connectZN ? grassTopIcon : icon); + } + + @Override + public void renderFaceZPos(Block block, double x, double y, double z, IIcon icon) { + super.renderFaceZPos(block, x, y, z, connectZP ? grassTopIcon : icon); + } + + @Override + public void renderFaceXNeg(Block block, double x, double y, double z, IIcon icon) { + super.renderFaceXNeg(block, x, y, z, connectXN ? grassTopIcon : icon); + } + + @Override + public void renderFaceXPos(Block block, double x, double y, double z, IIcon icon) { + super.renderFaceXPos(block, x, y, z, connectXP ? grassTopIcon : icon); + } + @SubscribeEvent public void handleTextureReload(TextureStitchEvent.Pre event) { if (event.map.getTextureType() != 0) return; grassIcons.registerIcons(event.map); snowGrassIcons.registerIcons(event.map); - myceliumIcons.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 mycelium textures", myceliumIcons.numLoaded)); } } diff --git a/src/main/java/mods/betterfoliage/client/render/impl/RenderBlockBetterLeaves.java b/src/main/java/mods/betterfoliage/client/render/impl/RenderBlockBetterLeaves.java index cd939de..aa01b7f 100644 --- a/src/main/java/mods/betterfoliage/client/render/impl/RenderBlockBetterLeaves.java +++ b/src/main/java/mods/betterfoliage/client/render/impl/RenderBlockBetterLeaves.java @@ -5,7 +5,6 @@ import mods.betterfoliage.client.BetterFoliageClient; import mods.betterfoliage.client.render.IRenderBlockDecorator; import mods.betterfoliage.client.render.RenderBlockAOBase; import mods.betterfoliage.common.util.Double3; -import mods.betterfoliage.common.util.Utils; import net.minecraft.block.Block; import net.minecraft.block.material.Material; import net.minecraft.client.Minecraft; @@ -16,7 +15,6 @@ import net.minecraft.init.Blocks; import net.minecraft.util.IIcon; import net.minecraft.world.IBlockAccess; import net.minecraftforge.common.util.ForgeDirection; -import cpw.mods.fml.client.registry.ISimpleBlockRenderingHandler; import cpw.mods.fml.relauncher.Side; import cpw.mods.fml.relauncher.SideOnly; @@ -30,25 +28,8 @@ public class RenderBlockBetterLeaves extends RenderBlockAOBase implements IRende } public boolean renderWorldBlock(IBlockAccess world, int x, int y, int z, Block block, int modelId, RenderBlocks renderer) { - // store world for later use blockAccess = world; - - // use original renderer for block breaking overlay - if (renderer.hasOverrideBlockTexture()) { - renderer.setRenderBoundsFromBlock(block); - renderer.renderStandardBlock(block, x, y, z); - return true; - } - - // render leaves center - setPassCounters(1); - setRenderBoundsFromBlock(block); - if (block.getRenderType() == 0) { - renderStandardBlock(block, x, y, z); - } else { - ISimpleBlockRenderingHandler handler = Utils.getRenderingHandler(block.getRenderType()); - handler.renderWorldBlock(world, x, y, z, block, block.getRenderType(), this); - } + renderWorldBlockBase(1, world, x, y, z, block, modelId, renderer); // find generated texture to render with, assume the // "true" texture of the block is the one on the north size @@ -57,6 +38,7 @@ public class RenderBlockBetterLeaves extends RenderBlockAOBase implements IRende blockLeafIcon = (TextureAtlasSprite) block.getIcon(world, x, y, z, ForgeDirection.NORTH.ordinal()); } catch (ClassCastException e) { } + if (blockLeafIcon == null) { BetterFoliage.log.debug(String.format("null leaf texture, x:%d, y:%d, z:%d, meta:%d, block:%s", x, y, z, blockAccess.getBlockMetadata(x, y, z), block.getClass().getName())); return true; diff --git a/src/main/java/mods/betterfoliage/client/render/impl/RenderBlockBetterMycelium.java b/src/main/java/mods/betterfoliage/client/render/impl/RenderBlockBetterMycelium.java new file mode 100644 index 0000000..4ac4416 --- /dev/null +++ b/src/main/java/mods/betterfoliage/client/render/impl/RenderBlockBetterMycelium.java @@ -0,0 +1,69 @@ +package mods.betterfoliage.client.render.impl; + +import mods.betterfoliage.BetterFoliage; +import mods.betterfoliage.client.ShadersModIntegration; +import mods.betterfoliage.client.render.IRenderBlockDecorator; +import mods.betterfoliage.client.render.IconSet; +import mods.betterfoliage.client.render.RenderBlockAOBase; +import mods.betterfoliage.common.util.Double3; +import net.minecraft.block.Block; +import net.minecraft.client.renderer.RenderBlocks; +import net.minecraft.client.renderer.Tessellator; +import net.minecraft.init.Blocks; +import net.minecraft.util.IIcon; +import net.minecraft.world.IBlockAccess; +import net.minecraftforge.client.event.TextureStitchEvent; +import net.minecraftforge.common.util.ForgeDirection; +import cpw.mods.fml.common.eventhandler.SubscribeEvent; +import cpw.mods.fml.relauncher.Side; +import cpw.mods.fml.relauncher.SideOnly; + +@SideOnly(Side.CLIENT) +public class RenderBlockBetterMycelium extends RenderBlockAOBase implements IRenderBlockDecorator { + + public IconSet myceliumIcons = new IconSet("bettergrassandleaves", "better_mycel_%d"); + + public boolean isBlockAccepted(IBlockAccess blockAccess, int x, int y, int z, Block block, int original) { + if (!BetterFoliage.config.grassEnabled) return false; + if (block != Blocks.mycelium) return false; + if (!blockAccess.isAirBlock(x, y + 1, z) && blockAccess.getBlock(x, y + 1, z) != Blocks.snow_layer) return false; + return true; + } + + public boolean renderWorldBlock(IBlockAccess world, int x, int y, int z, Block block, int modelId, RenderBlocks renderer) { + blockAccess = world; + renderWorldBlockBase(1, world, x, y, z, block, modelId, renderer); + + boolean isSnowed = blockAccess.getBlock(x, y + 1, z) == Blocks.snow_layer; + int iconVariation = getSemiRandomFromPos(x, y, z, 0); + IIcon renderIcon = myceliumIcons.get(iconVariation); + + if (isSnowed || renderIcon == null) return true; + + int heightVariation = getSemiRandomFromPos(x, y, z, 1); + double scale = BetterFoliage.config.grassSize.value * 0.5; + double halfHeight = 0.5 * (BetterFoliage.config.grassHeightMin.value + pRand[heightVariation] * (BetterFoliage.config.grassHeightMax.value - BetterFoliage.config.grassHeightMin.value)); + + if (isSnowed) { + aoYPXZNN.setGray(0.9f); aoYPXZNP.setGray(0.9f); aoYPXZPN.setGray(0.9f); aoYPXZPP.setGray(0.9f); + Tessellator.instance.setColorOpaque(230, 230, 230); + } + + // render mycelium + ShadersModIntegration.startGrassQuads(); + Tessellator.instance.setBrightness(getBrightness(block, x, y + 1, z)); + Tessellator.instance.setColorOpaque_I(block.colorMultiplier(blockAccess, x, y, z)); + renderCrossedSideQuads(new Double3(x + 0.5, y + 1.0 + (isSnowed ? 0.0625 : 0.0), z + 0.5), ForgeDirection.UP, scale, halfHeight, pRot[iconVariation], BetterFoliage.config.grassHOffset.value, renderIcon, 0, false); + + return true; + } + + @SubscribeEvent + public void handleTextureReload(TextureStitchEvent.Pre event) { + if (event.map.getTextureType() != 0) return; + + myceliumIcons.registerIcons(event.map); + BetterFoliage.log.info(String.format("Found %d mycelium textures", myceliumIcons.numLoaded)); + } + +} diff --git a/src/main/java/mods/betterfoliage/client/render/impl/RenderBlockBetterReed.java b/src/main/java/mods/betterfoliage/client/render/impl/RenderBlockBetterReed.java index 2b42298..9370884 100644 --- a/src/main/java/mods/betterfoliage/client/render/impl/RenderBlockBetterReed.java +++ b/src/main/java/mods/betterfoliage/client/render/impl/RenderBlockBetterReed.java @@ -42,20 +42,8 @@ public class RenderBlockBetterReed extends RenderBlockAOBase implements IRenderB } public boolean renderWorldBlock(IBlockAccess world, int x, int y, int z, Block block, int modelId, RenderBlocks renderer) { - // store world for later use blockAccess = world; - - // use original renderer for block breaking overlay - if (renderer.hasOverrideBlockTexture()) { - renderer.setRenderBoundsFromBlock(block); - renderer.renderStandardBlock(block, x, y, z); - return true; - } - - // render dirt block - setPassCounters(1); - setRenderBoundsFromBlock(block); - renderStandardBlock(block, x, y, z); + renderWorldBlockBase(1, world, x, y, z, block, modelId, renderer); int iconVariation = getSemiRandomFromPos(x, y, z, 0); int heightVariation = getSemiRandomFromPos(x, y, z, 1); diff --git a/src/main/java/mods/betterfoliage/client/render/impl/RenderBlocksBetterGrassSide.java b/src/main/java/mods/betterfoliage/client/render/impl/RenderBlocksBetterGrassSide.java new file mode 100644 index 0000000..8decb35 --- /dev/null +++ b/src/main/java/mods/betterfoliage/client/render/impl/RenderBlocksBetterGrassSide.java @@ -0,0 +1,50 @@ +package mods.betterfoliage.client.render.impl; + +import mods.betterfoliage.BetterFoliage; +import mods.betterfoliage.client.BetterFoliageClient; +import mods.betterfoliage.client.render.FakeRenderBlockAOBase; +import mods.betterfoliage.client.render.IRenderBlockDecorator; +import mods.betterfoliage.common.util.OffsetBlockAccess; +import mods.betterfoliage.common.util.Utils; +import net.minecraft.block.Block; +import net.minecraft.client.renderer.RenderBlocks; +import net.minecraft.world.IBlockAccess; +import cpw.mods.fml.client.registry.ISimpleBlockRenderingHandler; +import cpw.mods.fml.relauncher.Side; +import cpw.mods.fml.relauncher.SideOnly; + +/** Accepts dirt blocks with grass on top if aggressive connected grass is enabled.
+ * Renders the grass block in place of dirt. + * @author octarine-noise + */ +@SideOnly(Side.CLIENT) +public class RenderBlocksBetterGrassSide extends FakeRenderBlockAOBase implements IRenderBlockDecorator { + + @Override + public boolean isBlockAccepted(IBlockAccess blockAccess, int x, int y, int z, Block block, int original) { + return BetterFoliage.config.ctxGrassAggressiveEnabled && + BetterFoliageClient.dirt.matchesID(block) && + BetterFoliageClient.grass.matchesID(blockAccess.getBlock(x, y + 1, z)); + } + + @Override + public boolean renderWorldBlock(IBlockAccess world, int x, int y, int z, Block block, int modelId, RenderBlocks renderer) { + // fake grass block @(0, +1, 0) at render location + IBlockAccess originalBA = renderer.blockAccess; + renderer.blockAccess = new OffsetBlockAccess(world, x, y, z, 0, 1, 0); + + Block renderBlock = renderer.blockAccess.getBlock(x, y, z); + boolean result; + ISimpleBlockRenderingHandler handler = Utils.getRenderingHandler(renderBlock.getRenderType()); + if (handler != null) { + result = handler.renderWorldBlock(renderer.blockAccess, x, y, z, renderBlock, renderBlock.getRenderType(), renderer); + } else { + result = renderer.renderStandardBlock(renderBlock, x, y, z); + } + + // restore renderer to sanity + renderer.blockAccess = originalBA; + return result; + } + +} diff --git a/src/main/java/mods/betterfoliage/common/config/BetterFoliageConfig.java b/src/main/java/mods/betterfoliage/common/config/BetterFoliageConfig.java index a893466..fb9f639 100644 --- a/src/main/java/mods/betterfoliage/common/config/BetterFoliageConfig.java +++ b/src/main/java/mods/betterfoliage/common/config/BetterFoliageConfig.java @@ -29,6 +29,12 @@ public class BetterFoliageConfig extends ConfigBase { @CfgElement(category="coral", key="enabled") public boolean coralEnabled = true; + @CfgElement(category="connectedGrass", key="classic") + public boolean ctxGrassClassicEnabled = true; + + @CfgElement(category="connectedGrass", key="aggressive") + public boolean ctxGrassAggressiveEnabled = true; + @CfgElement(category="fallingLeaves", key="enabled") public boolean fallingLeavesEnabled = true; diff --git a/src/main/java/mods/betterfoliage/common/util/OffsetBlockAccess.java b/src/main/java/mods/betterfoliage/common/util/OffsetBlockAccess.java new file mode 100644 index 0000000..e3b5dec --- /dev/null +++ b/src/main/java/mods/betterfoliage/common/util/OffsetBlockAccess.java @@ -0,0 +1,100 @@ +package mods.betterfoliage.common.util; + +import cpw.mods.fml.relauncher.Side; +import cpw.mods.fml.relauncher.SideOnly; +import net.minecraft.block.Block; +import net.minecraft.tileentity.TileEntity; +import net.minecraft.util.Vec3Pool; +import net.minecraft.world.IBlockAccess; +import net.minecraft.world.biome.BiomeGenBase; +import net.minecraftforge.common.util.ForgeDirection; + +/** {@link IBlockAccess} wrapper that applies an offset for a single target coordinate for all rendering-related methods. + * Returns normal values for all other coordinates. + * @author octarine-noise + * + */ +public class OffsetBlockAccess implements IBlockAccess { + + public IBlockAccess source; + public int xTarget, yTarget, zTarget; + public int xOffset, yOffset, zOffset; + + public OffsetBlockAccess(IBlockAccess source, int x, int y, int z, int xOffset, int yOffset, int zOffset) { + this.source = source; + this.xTarget = x; + this.yTarget = y; + this.zTarget = z; + this.xOffset = xOffset; + this.yOffset = yOffset; + this.zOffset = zOffset; + } + + public Block getBlock(int x, int y, int z) { + if (x == xTarget && y == yTarget && z == zTarget) + return source.getBlock(x + xOffset, y + yOffset, z + zOffset); + else + return source.getBlock(x, y, z); + } + + public TileEntity getTileEntity(int x, int y, int z) { + if (x == xTarget && y == yTarget && z == zTarget) + return source.getTileEntity(x + xOffset, y + yOffset, z + zOffset); + else + return source.getTileEntity(x, y, z); + } + + @SideOnly(Side.CLIENT) + public int getLightBrightnessForSkyBlocks(int x, int y, int z, int min) { + if (x == xTarget && y == yTarget && z == zTarget) + return source.getLightBrightnessForSkyBlocks(x + xOffset, y + yOffset, z + zOffset, min); + else + return source.getLightBrightnessForSkyBlocks(x, y, z, min); + } + + public int getBlockMetadata(int x, int y, int z) { + if (x == xTarget && y == yTarget && z == zTarget) + return source.getBlockMetadata(x + xOffset, y + yOffset, z + zOffset); + else + return source.getBlockMetadata(x, y, z); + } + + public boolean isAirBlock(int x, int y, int z) { + if (x == xTarget && y == yTarget && z == zTarget) + return source.isAirBlock(x + xOffset, y + yOffset, z + zOffset); + else + return source.isAirBlock(x, y, z); + } + + @SideOnly(Side.CLIENT) + public BiomeGenBase getBiomeGenForCoords(int x, int z) { + return source.getBiomeGenForCoords(x, z); + } + + @SideOnly(Side.CLIENT) + public int getHeight() { + return source.getHeight(); + } + + @SideOnly(Side.CLIENT) + public boolean extendedLevelsInChunkCache() { + return source.extendedLevelsInChunkCache(); + } + + @Deprecated + public Vec3Pool getWorldVec3Pool() { + return source.getWorldVec3Pool(); + } + + public int isBlockProvidingPowerTo(int x, int y, int z, int dir) { + return source.isBlockProvidingPowerTo(x, y, z, dir); + } + + public boolean isSideSolid(int x, int y, int z, ForgeDirection side, boolean _default) { + if (x == xTarget && y == yTarget && z == zTarget) + return source.isSideSolid(x + xOffset, y + yOffset, z + zOffset, side, _default); + else + return source.isSideSolid(x, y, z, side, _default); + } + +}