diff --git a/README.md b/README.md index fcb5b3a..e048374 100644 --- a/README.md +++ b/README.md @@ -6,4 +6,4 @@ More info: http://www.minecraftforum.net/topic/2776217-better-foliage/ Download ======== -[BetterFoliage 0.9-beta] (http://goo.gl/RlsbTk) (MC 1.7.2) +[BetterFoliage 0.9.2-beta] (http://goo.gl/G900w3) (MC 1.7.2) diff --git a/build.gradle b/build.gradle index 49e0f81..82280c5 100644 --- a/build.gradle +++ b/build.gradle @@ -22,7 +22,7 @@ minecraft { jar.baseName = 'BetterFoliage-1.7.2' group = 'com.github.octarine-noise' -version='0.9.1b' +version='0.9.2b' processResources { inputs.property "version", project.version diff --git a/src/main/java/mods/betterfoliage/BlockRenderTypeOverride.java b/src/main/java/mods/betterfoliage/BlockRenderTypeOverride.java deleted file mode 100644 index ab434d9..0000000 --- a/src/main/java/mods/betterfoliage/BlockRenderTypeOverride.java +++ /dev/null @@ -1,23 +0,0 @@ -package mods.betterfoliage; - -import net.minecraft.block.Block; - -/** Allows overriding block rendertype. - * @author octarine-noise - */ -public class BlockRenderTypeOverride { - - public static IRenderTypeProvider provider = null; - - public static interface IRenderTypeProvider { - public int getRenderType(int original, Block block); - } - - /** Entry point from transformed RenderBlocks class. - * @param block block instance - * @return block render type - */ - public static int getRenderTypeOverride(int orig, Block block) { - return provider == null ? orig : provider.getRenderType(orig, block); - } -} \ No newline at end of file diff --git a/src/main/java/mods/betterfoliage/client/BetterFoliageClient.java b/src/main/java/mods/betterfoliage/client/BetterFoliageClient.java index 8aa8fa7..a03acd7 100644 --- a/src/main/java/mods/betterfoliage/client/BetterFoliageClient.java +++ b/src/main/java/mods/betterfoliage/client/BetterFoliageClient.java @@ -1,43 +1,43 @@ package mods.betterfoliage.client; import java.io.File; +import java.util.Map; import java.util.Set; import mods.betterfoliage.BetterFoliage; -import mods.betterfoliage.BlockRenderTypeOverride; -import mods.betterfoliage.BlockRenderTypeOverride.IRenderTypeProvider; -import mods.betterfoliage.client.render.RenderBlockBetterGrass; -import mods.betterfoliage.client.render.RenderBlockBetterLeaves; +import mods.betterfoliage.client.render.IRenderBlockDecorator; +import mods.betterfoliage.client.render.impl.RenderBlockBetterCactus; +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.resource.ILeafTextureRecognizer; import mods.betterfoliage.client.resource.LeafTextureGenerator; -import mods.betterfoliage.common.config.Config; import net.minecraft.block.Block; -import net.minecraft.block.BlockGrass; import net.minecraft.block.BlockLeavesBase; import net.minecraft.client.renderer.texture.TextureAtlasSprite; +import net.minecraft.world.IBlockAccess; import net.minecraftforge.common.MinecraftForge; +import com.google.common.collect.Maps; import com.google.common.collect.Sets; +import cpw.mods.fml.client.registry.RenderingRegistry; import cpw.mods.fml.common.FMLCommonHandler; -import cpw.mods.fml.relauncher.Side; -import cpw.mods.fml.relauncher.SideOnly; -@SideOnly(Side.CLIENT) -public class BetterFoliageClient implements IRenderTypeProvider, ILeafTextureRecognizer { +public class BetterFoliageClient implements ILeafTextureRecognizer { - public static int leavesRenderId; - public static int grassRenderId; - public static LeafTextureGenerator leafGenerator; + public static Map decorators = Maps.newHashMap(); public static Set> blockLeavesClasses = Sets.newHashSet(); + public static LeafTextureGenerator leafGenerator; public static void preInit() { FMLCommonHandler.instance().bus().register(new KeyHandler()); BetterFoliage.log.info("Registering renderers"); - leavesRenderId = RenderBlockBetterLeaves.register(); - grassRenderId = RenderBlockBetterGrass.register(); - BlockRenderTypeOverride.provider = new BetterFoliageClient(); + registerRenderer(new RenderBlockBetterLeaves()); + registerRenderer(new RenderBlockBetterGrass()); + registerRenderer(new RenderBlockBetterCactus()); + registerRenderer(new RenderBlockBetterLilypad()); blockLeavesClasses.add(BlockLeavesBase.class); addLeafBlockClass("forestry.arboriculture.gadgets.BlockLeaves"); @@ -49,31 +49,36 @@ public class BetterFoliageClient implements IRenderTypeProvider, ILeafTextureRec leafGenerator.recognizers.add(new BetterFoliageClient()); leafGenerator.loadLeafMappings(new File(BetterFoliage.configDir, "leafMask.properties")); } - - protected static void addLeafBlockClass(String className) { - try { - blockLeavesClasses.add(Class.forName(className)); - } catch(ClassNotFoundException e) { - } - } - - public int getRenderType(int original, Block block) { - // universal sign for DON'T RENDER ME! - if (original == -1) return original; - - if (Config.grassEnabled && block instanceof BlockGrass) return grassRenderId; - - if (Config.leavesEnabled) - for (Class clazz : blockLeavesClasses) - if (clazz.isAssignableFrom(block.getClass()) && (original == 0 || original >= 42)) - return leavesRenderId; - - return original; - } public boolean isLeafTexture(TextureAtlasSprite icon) { String resourceLocation = icon.getIconName(); if (resourceLocation.startsWith("forestry:leaves/")) return true; return false; } + + public static int getRenderTypeOverride(IBlockAccess blockAccess, int x, int y, int z, Block block, int original) { + // universal sign for DON'T RENDER ME! + if (original == -1) return original; + + for (Map.Entry entry : decorators.entrySet()) + if (entry.getValue().isBlockAccepted(blockAccess, x, y, z, block, original)) + return entry.getKey(); + + return original; + } + + public static void registerRenderer(IRenderBlockDecorator decorator) { + int renderId = RenderingRegistry.getNextAvailableRenderId(); + decorators.put(renderId, decorator); + RenderingRegistry.registerBlockHandler(renderId, decorator); + MinecraftForge.EVENT_BUS.register(decorator); + decorator.init(); + } + + protected static void addLeafBlockClass(String className) { + try { + blockLeavesClasses.add(Class.forName(className)); + } catch(ClassNotFoundException e) { + } + } } diff --git a/src/main/java/mods/betterfoliage/client/gui/ConfigGuiScreen.java b/src/main/java/mods/betterfoliage/client/gui/ConfigGuiScreen.java index 2f797b2..97bc1b2 100644 --- a/src/main/java/mods/betterfoliage/client/gui/ConfigGuiScreen.java +++ b/src/main/java/mods/betterfoliage/client/gui/ConfigGuiScreen.java @@ -17,30 +17,33 @@ import cpw.mods.fml.relauncher.SideOnly; @SideOnly(Side.CLIENT) public class ConfigGuiScreen extends GuiScreen { - public enum Button {CLOSE, TOGGLE_LEAVES, TOGGLE_GRASS} + public enum Button {CLOSE, TOGGLE_LEAVES, TOGGLE_GRASS, LEAVES_OFFSET_MODE, TOGGLE_CACTUS, TOGGLE_LILYPAD} private GuiScreen parent; - protected List widgets = Lists.newLinkedList(); + protected List widgets = Lists.newLinkedList(); public ConfigGuiScreen(GuiScreen parent) { this.parent = parent; - int id = 3; - widgets.add(new OptionDoubleWidget(Config.leavesSize, -160, -65, 150, 40, id++, id++, "message.betterfoliage.size", "%.2f")); - widgets.add(new OptionDoubleWidget(Config.leavesHOffset, -160, -35, 150, 40, id++, id++, "message.betterfoliage.hOffset", "%.3f")); - widgets.add(new OptionDoubleWidget(Config.leavesVOffset, -160, -5, 150, 40, id++, id++, "message.betterfoliage.vOffset", "%.3f")); + int id = 10; + widgets.add(new OptionDoubleWidget(Config.leavesSize, -160, -40, 150, 40, id++, id++, "message.betterfoliage.size", "%.2f")); + widgets.add(new OptionDoubleWidget(Config.leavesHOffset, -160, -10, 150, 40, id++, id++, "message.betterfoliage.hOffset", "%.3f")); + widgets.add(new OptionDoubleWidget(Config.leavesVOffset, -160, 20, 150, 40, id++, id++, "message.betterfoliage.vOffset", "%.3f")); - widgets.add(new OptionDoubleWidget(Config.grassSize, 10, -65, 150, 40, id++, id++, "message.betterfoliage.size", "%.2f")); - widgets.add(new OptionDoubleWidget(Config.grassHOffset, 10, -35, 150, 40, id++, id++, "message.betterfoliage.hOffset", "%.3f")); - widgets.add(new OptionDoubleWidget(Config.grassHeightMin, 10, -5, 150, 40, id++, id++, "message.betterfoliage.minHeight", "%.2f")); - widgets.add(new OptionDoubleWidget(Config.grassHeightMax, 10, 25, 150, 40, id++, id++, "message.betterfoliage.maxHeight", "%.2f")); + widgets.add(new OptionDoubleWidget(Config.grassSize, 10, -70, 150, 40, id++, id++, "message.betterfoliage.size", "%.2f")); + widgets.add(new OptionDoubleWidget(Config.grassHOffset, 10, -40, 150, 40, id++, id++, "message.betterfoliage.hOffset", "%.3f")); + widgets.add(new OptionDoubleWidget(Config.grassHeightMin, 10, -10, 150, 40, id++, id++, "message.betterfoliage.minHeight", "%.2f")); + widgets.add(new OptionDoubleWidget(Config.grassHeightMax, 10, 20, 150, 40, id++, id++, "message.betterfoliage.maxHeight", "%.2f")); + + widgets.add(new OptionDoubleWidget(Config.lilypadHOffset, 10, 80, 150, 40, id++, id++, "message.betterfoliage.hOffset", "%.3f")); + widgets.add(new OptionIntegerWidget(Config.lilypadChance, 10, 110, 150, 40, id++, id++, "message.betterfoliage.flowerChance")); } @Override public void drawScreen(int par1, int par2, float par3) { this.drawDefaultBackground(); int x = width / 2; - int y = height / 2; - for (OptionDoubleWidget widget : widgets) widget.drawStrings(this, fontRendererObj, x, y, 14737632, 16777120); + int y = height / 2 - 30; + for (IOptionWidget widget : widgets) widget.drawStrings(this, fontRendererObj, x, y, 14737632, 16777120); super.drawScreen(par1, par2, par3); } @@ -48,17 +51,23 @@ public class ConfigGuiScreen extends GuiScreen { @Override public void initGui() { int x = width / 2; - int y = height / 2; - for (OptionDoubleWidget widget : widgets) widget.addButtons(buttonList, x, y); - buttonList.add(new GuiButton(Button.CLOSE.ordinal(), x - 50, y + 100, 100, 20, "Close")); + int y = height / 2 - 30; + for (IOptionWidget widget : widgets) widget.addButtons(buttonList, x, y); + buttonList.add(new GuiButton(Button.CLOSE.ordinal(), x - 50, y + 130, 100, 20, "Close")); buttonList.add(new GuiButton(Button.TOGGLE_LEAVES.ordinal(), x - 160, y - 100, 150, 20, "")); + buttonList.add(new GuiButton(Button.LEAVES_OFFSET_MODE.ordinal(), x - 160, y - 70, 150, 20, "")); buttonList.add(new GuiButton(Button.TOGGLE_GRASS.ordinal(), x + 10, y - 100, 150, 20, "")); + buttonList.add(new GuiButton(Button.TOGGLE_CACTUS.ordinal(), x -160, y + 50, 150, 20, "")); + buttonList.add(new GuiButton(Button.TOGGLE_LILYPAD.ordinal(), x + 10, y + 50, 150, 20, "")); updateButtons(); } protected void updateButtons() { setButtonOptionBoolean(Button.TOGGLE_LEAVES, "message.betterfoliage.betterLeaves", Config.leavesEnabled); + setButtonOptionBoolean(Button.LEAVES_OFFSET_MODE, "message.betterfoliage.leavesMode", Config.leavesSkew ? "message.betterfoliage.leavesSkew" : "message.betterfoliage.leavesTranslate"); setButtonOptionBoolean(Button.TOGGLE_GRASS, "message.betterfoliage.betterGrass", Config.grassEnabled); + setButtonOptionBoolean(Button.TOGGLE_CACTUS, "message.betterfoliage.betterCactus", Config.cactusEnabled); + setButtonOptionBoolean(Button.TOGGLE_LILYPAD, "message.betterfoliage.betterLilypad", Config.lilypadEnabled); } @Override @@ -72,13 +81,13 @@ public class ConfigGuiScreen extends GuiScreen { } if (button.id == Button.TOGGLE_LEAVES.ordinal()) Config.leavesEnabled = !Config.leavesEnabled; if (button.id == Button.TOGGLE_GRASS.ordinal()) Config.grassEnabled = !Config.grassEnabled; - - for (OptionDoubleWidget widget : widgets) { - if (button.id == widget.idDecrement) widget.option.decrement(); - if (button.id == widget.idIncrement) widget.option.increment(); - if (widget.option == Config.grassHeightMin && Config.grassHeightMin.value > Config.grassHeightMax.value) Config.grassHeightMin.value = Config.grassHeightMax.value; - if (widget.option == Config.grassHeightMax && Config.grassHeightMin.value > Config.grassHeightMax.value) Config.grassHeightMax.value = Config.grassHeightMin.value; - } + if (button.id == Button.LEAVES_OFFSET_MODE.ordinal()) Config.leavesSkew = !Config.leavesSkew; + if (button.id == Button.TOGGLE_CACTUS.ordinal()) Config.cactusEnabled = !Config.cactusEnabled; + if (button.id == Button.TOGGLE_LILYPAD.ordinal()) Config.lilypadEnabled = !Config.lilypadEnabled; + + for (IOptionWidget widget : widgets) widget.onAction(button.id); + if (Config.grassHeightMin.value > Config.grassHeightMax.value) Config.grassHeightMin.value = Config.grassHeightMax.value; + if (Config.grassHeightMin.value > Config.grassHeightMax.value) Config.grassHeightMax.value = Config.grassHeightMin.value; updateButtons(); } @@ -93,4 +102,13 @@ public class ConfigGuiScreen extends GuiScreen { } } + @SuppressWarnings("unchecked") + protected void setButtonOptionBoolean(Button enumButton, String msgKey, String optionKey) { + for (GuiButton button : (List) buttonList) { + if (button.id == enumButton.ordinal()) { + button.displayString = I18n.format(msgKey, I18n.format(optionKey)); + break; + } + } + } } diff --git a/src/main/java/mods/betterfoliage/client/gui/IOptionWidget.java b/src/main/java/mods/betterfoliage/client/gui/IOptionWidget.java new file mode 100644 index 0000000..09079b9 --- /dev/null +++ b/src/main/java/mods/betterfoliage/client/gui/IOptionWidget.java @@ -0,0 +1,15 @@ +package mods.betterfoliage.client.gui; + +import java.util.List; + +import net.minecraft.client.gui.FontRenderer; +import net.minecraft.client.gui.GuiButton; +import net.minecraft.client.gui.GuiScreen; + +public interface IOptionWidget { + + public void addButtons(List buttonList, int xOffset, int yOffset); + public void drawStrings(GuiScreen screen, FontRenderer fontRenderer, int xOffset, int yOffset, int labelColor, int numColor); + public void onAction(int buttonId); + +} \ No newline at end of file diff --git a/src/main/java/mods/betterfoliage/client/gui/OptionDoubleWidget.java b/src/main/java/mods/betterfoliage/client/gui/OptionDoubleWidget.java index 51d1cc9..9ed13ee 100644 --- a/src/main/java/mods/betterfoliage/client/gui/OptionDoubleWidget.java +++ b/src/main/java/mods/betterfoliage/client/gui/OptionDoubleWidget.java @@ -12,7 +12,7 @@ import net.minecraft.client.gui.GuiScreen; import net.minecraft.client.resources.I18n; @SideOnly(Side.CLIENT) -public class OptionDoubleWidget { +public class OptionDoubleWidget implements IOptionWidget { public OptionDouble option; public int x; @@ -45,4 +45,9 @@ public class OptionDoubleWidget { screen.drawString(fontRenderer, I18n.format(keyLabel), xOffset + x, yOffset + y + 5, labelColor); screen.drawCenteredString(fontRenderer, String.format(formatString, option.value), xOffset + x + width - 20 - numWidth / 2, yOffset + y + 5, numColor); } + + public void onAction(int buttonId) { + if (buttonId == idDecrement) option.decrement(); + if (buttonId == idIncrement) option.increment(); + } } diff --git a/src/main/java/mods/betterfoliage/client/gui/OptionIntegerWidget.java b/src/main/java/mods/betterfoliage/client/gui/OptionIntegerWidget.java new file mode 100644 index 0000000..5eba7e8 --- /dev/null +++ b/src/main/java/mods/betterfoliage/client/gui/OptionIntegerWidget.java @@ -0,0 +1,50 @@ +package mods.betterfoliage.client.gui; + +import java.util.List; + +import mods.betterfoliage.common.config.OptionInteger; +import net.minecraft.client.gui.FontRenderer; +import net.minecraft.client.gui.GuiButton; +import net.minecraft.client.gui.GuiScreen; +import net.minecraft.client.resources.I18n; +import cpw.mods.fml.relauncher.Side; +import cpw.mods.fml.relauncher.SideOnly; + +@SideOnly(Side.CLIENT) +public class OptionIntegerWidget implements IOptionWidget { + + public OptionInteger option; + public int x; + public int y; + public int width; + public int numWidth; + public int idDecrement; + public int idIncrement; + public String keyLabel; + + public OptionIntegerWidget(OptionInteger option, int x, int y, int width, int numWidth, int idDecrement, int idIncrement, String keyLabel) { + this.option = option; + this.x = x; + this.y = y; + this.width = width; + this.numWidth = numWidth; + this.idDecrement = idDecrement; + this.idIncrement = idIncrement; + this.keyLabel = keyLabel; + } + + public void addButtons(List buttonList, int xOffset, int yOffset) { + buttonList.add(new GuiButton(idDecrement, xOffset + x + width - numWidth - 40, yOffset + y, 20, 20, "-")); + buttonList.add(new GuiButton(idIncrement, xOffset + x + width - 20, yOffset + y, 20, 20, "+")); + } + + public void drawStrings(GuiScreen screen, FontRenderer fontRenderer, int xOffset, int yOffset, int labelColor, int numColor) { + screen.drawString(fontRenderer, I18n.format(keyLabel), xOffset + x, yOffset + y + 5, labelColor); + screen.drawCenteredString(fontRenderer, Integer.toString(option.value), xOffset + x + width - 20 - numWidth / 2, yOffset + y + 5, numColor); + } + + public void onAction(int buttonId) { + if (buttonId == idDecrement) option.decrement(); + if (buttonId == idIncrement) option.increment(); + } +} diff --git a/src/main/java/mods/betterfoliage/client/render/FakeRenderBlockAOBase.java b/src/main/java/mods/betterfoliage/client/render/FakeRenderBlockAOBase.java new file mode 100644 index 0000000..e17d302 --- /dev/null +++ b/src/main/java/mods/betterfoliage/client/render/FakeRenderBlockAOBase.java @@ -0,0 +1,59 @@ +package mods.betterfoliage.client.render; + +import net.minecraft.block.Block; +import net.minecraft.util.IIcon; + +/** Same as {@link RenderBlockAOBase}, but does not actually render anything. + * @author octarine-noise + */ +public class FakeRenderBlockAOBase extends RenderBlockAOBase { + + @Override + public void renderFaceZNeg(Block block, double x, double y, double z, IIcon icon) { + saveShadingTopLeft(aoZNXYPP); + saveShadingTopRight(aoZNXYNP); + saveShadingBottomLeft(aoZNXYPN); + saveShadingBottomRight(aoZNXYNN); + } + + @Override + public void renderFaceZPos(Block block, double x, double y, double z, IIcon icon) { + saveShadingTopLeft(aoZPXYNP); + saveShadingTopRight(aoZPXYPP); + saveShadingBottomLeft(aoZPXYNN); + saveShadingBottomRight(aoZPXYPN); + } + + @Override + public void renderFaceXNeg(Block block, double x, double y, double z, IIcon icon) { + saveShadingTopLeft(aoXNYZPN); + saveShadingTopRight(aoXNYZPP); + saveShadingBottomLeft(aoXNYZNN); + saveShadingBottomRight(aoXNYZNP); + } + + @Override + public void renderFaceXPos(Block block, double x, double y, double z, IIcon icon) { + saveShadingTopLeft(aoXPYZPP); + saveShadingTopRight(aoXPYZPN); + saveShadingBottomLeft(aoXPYZNP); + saveShadingBottomRight(aoXPYZNN); + } + + @Override + public void renderFaceYNeg(Block block, double x, double y, double z, IIcon icon) { + saveShadingTopLeft(aoYNXZNP); + saveShadingTopRight(aoYNXZPP); + saveShadingBottomLeft(aoYNXZNN); + saveShadingBottomRight(aoYNXZPN); + } + + @Override + public void renderFaceYPos(Block block, double x, double y, double z, IIcon icon) { + saveShadingTopLeft(aoYPXZPP); + saveShadingTopRight(aoYPXZNP); + saveShadingBottomLeft(aoYPXZPN); + saveShadingBottomRight(aoYPXZNN); + } + +} diff --git a/src/main/java/mods/betterfoliage/client/render/IRenderBlockDecorator.java b/src/main/java/mods/betterfoliage/client/render/IRenderBlockDecorator.java new file mode 100644 index 0000000..2fd71a4 --- /dev/null +++ b/src/main/java/mods/betterfoliage/client/render/IRenderBlockDecorator.java @@ -0,0 +1,12 @@ +package mods.betterfoliage.client.render; + +import cpw.mods.fml.client.registry.ISimpleBlockRenderingHandler; +import net.minecraft.block.Block; +import net.minecraft.world.IBlockAccess; + +public interface IRenderBlockDecorator extends ISimpleBlockRenderingHandler { + + public void init(); + public boolean isBlockAccepted(IBlockAccess blockAccess, int x, int y, int z, Block block, int original); + +} diff --git a/src/main/java/mods/betterfoliage/client/render/RenderBlockAOBase.java b/src/main/java/mods/betterfoliage/client/render/RenderBlockAOBase.java index f537243..52c1523 100644 --- a/src/main/java/mods/betterfoliage/client/render/RenderBlockAOBase.java +++ b/src/main/java/mods/betterfoliage/client/render/RenderBlockAOBase.java @@ -7,11 +7,13 @@ import java.util.List; import mods.betterfoliage.common.util.Double3; import net.minecraft.block.Block; +import net.minecraft.client.Minecraft; 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.util.MathHelper; +import net.minecraftforge.common.util.ForgeDirection; import org.lwjgl.opengl.GL11; @@ -40,6 +42,9 @@ public class RenderBlockAOBase extends RenderBlocks { protected double[] uValues = new double[] {0.0, 16.0, 16.0, 0.0}; protected double[] vValues = new double[] {0.0, 0.0, 16.0, 16.0}; + protected ForgeDirection[] faceDir1 = new ForgeDirection[] {ForgeDirection.WEST, ForgeDirection.WEST, ForgeDirection.WEST, ForgeDirection.EAST, ForgeDirection.SOUTH, ForgeDirection.NORTH}; + protected ForgeDirection[] faceDir2 = new ForgeDirection[] {ForgeDirection.NORTH, ForgeDirection.SOUTH, ForgeDirection.UP, ForgeDirection.UP, ForgeDirection.UP, ForgeDirection.UP}; + /** Random vector pool. Unit rotation vectors in the XZ plane, Y coord goes between [-1.0, 1.0]. * Filled at init time */ public Double3[] pRot = new Double3[64]; @@ -71,6 +76,9 @@ public class RenderBlockAOBase extends RenderBlocks { public ShadingValues aoZNXYPN = new ShadingValues(); public ShadingValues aoZNXYNP = new ShadingValues(); public ShadingValues aoZNXYNN = new ShadingValues(); + + // temporary shading values for a single face + public ShadingValues faceAOPP, faceAOPN, faceAONN, faceAONP; /** Initialize random values */ public void init() { @@ -93,8 +101,24 @@ public class RenderBlockAOBase extends RenderBlocks { * @return semirandom value */ protected int getSemiRandomFromPos(double x, double y, double z, int seed) { - int sum = MathHelper.floor_double(x) * 3 + MathHelper.floor_double(y) * 5 + MathHelper.floor_double(z) * 7 + seed * 11; - return sum & 63; + long lx = MathHelper.floor_double(x); + long ly = MathHelper.floor_double(y); + long lz = MathHelper.floor_double(z); + long value = (lx * lx + ly * ly + lz * lz + lx * ly + ly * lz + lz * lx) & 63; + value = (3 * lx * value + 5 * ly * value + 7 * lz * value) & 63; + return (int) value; + } + + public void renderInventoryBlock(Block block, int metadata, int modelId, RenderBlocks renderer) { + renderStandardBlockAsItem(renderer, block, metadata, 1.0f); + } + + public boolean shouldRender3DInInventory(int modelId) { + return true; + } + + public int getRenderId() { + return 0; } protected void renderStandardBlockAsItem(RenderBlocks renderer, Block p_147800_1_, int p_147800_2_, float p_147800_3_) { @@ -152,6 +176,101 @@ public class RenderBlockAOBase extends RenderBlocks { GL11.glTranslatef(0.5F, 0.5F, 0.5F); } + protected void setShadingForFace(ForgeDirection dir) { + if (dir == ForgeDirection.DOWN) { + // dir1 WEST, dir2 NORTH + faceAOPP = aoYNXZPP; faceAOPN = aoYNXZPN; faceAONN = aoYNXZNN; faceAONP = aoYNXZNP; + } else if (dir == ForgeDirection.UP) { + // dir1 WEST, dir2 SOUTH + faceAOPP = aoYPXZPP; faceAOPN = aoYPXZPN; faceAONN = aoYPXZNN; faceAONP = aoYPXZNP; + } else if (dir == ForgeDirection.NORTH) { + // dir1 WEST, dir2 UP + faceAOPP = aoZNXYNP; faceAOPN = aoZNXYNN; faceAONN = aoZNXYPN; faceAONP = aoZNXYPP; + } else if (dir == ForgeDirection.SOUTH) { + // dir1 EAST, dir2 UP + faceAOPP = aoZPXYPP; faceAOPN = aoZPXYPN; faceAONN = aoZPXYNN; faceAONP = aoZPXYNP; + } else if (dir == ForgeDirection.WEST) { + // dir1 SOUTH, dir2 UP + faceAOPP = aoXNYZPP; faceAOPN = aoXNYZNP; faceAONN = aoXNYZNN; faceAONP = aoXNYZPN; + } else if (dir == ForgeDirection.EAST) { + // dir1 NORTH, dir2 UP + faceAOPP = aoXPYZPN; faceAOPN = aoXPYZNN; faceAONN = aoXPYZNP; faceAONP = aoXPYZPP; + } + } + + public void renderCrossedSideQuads(Double3 drawBase, ForgeDirection dir, double scale, double halfHeight, Double3 rendomVec, double offset, IIcon renderIcon, int uvRot, boolean noShading) { + Double3 facePP, faceNP, faceNormal, drawCenter; + + if (dir == ForgeDirection.UP) { + // special case for block top, we'll be rendering a LOT of those + facePP = new Double3(-scale, 0.0, scale); + faceNP = new Double3(scale, 0.0, scale); + faceNormal = new Double3(0.0, halfHeight, 0.0); + drawCenter = drawBase.add(faceNormal); + if (rendomVec != null) { + drawCenter = drawBase.add(faceNormal).add(rendomVec.scaleAxes(-offset, 0.0, offset)); + } + } else { + facePP = new Double3(faceDir1[dir.ordinal()]).add(new Double3(faceDir2[dir.ordinal()])).scale(scale); + faceNP = new Double3(faceDir1[dir.ordinal()]).inverse().add(new Double3(faceDir2[dir.ordinal()])).scale(scale); + faceNormal = new Double3(dir).scale(halfHeight); + drawCenter = drawBase.add(faceNormal); + if (rendomVec != null) { + drawCenter = drawCenter.add(new Double3(faceDir1[dir.ordinal()]).scale(rendomVec.x).scale(offset)) + .add(new Double3(faceDir2[dir.ordinal()]).scale(rendomVec.z).scale(offset)); + } + } + + if (Minecraft.isAmbientOcclusionEnabled() && !noShading) { + setShadingForFace(dir); + renderQuadWithShading(renderIcon, drawCenter, facePP, faceNormal, uvRot, faceAOPP, faceAONN, faceAONN, faceAOPP); + renderQuadWithShading(renderIcon, drawCenter, facePP.inverse(), faceNormal, uvRot, faceAONN, faceAOPP, faceAOPP, faceAONN); + renderQuadWithShading(renderIcon, drawCenter, faceNP, faceNormal, uvRot, faceAONP, faceAOPN, faceAOPN, faceAONP); + renderQuadWithShading(renderIcon, drawCenter, faceNP.inverse(), faceNormal, uvRot, faceAOPN, faceAONP, faceAONP, faceAOPN); + } else { + renderQuad(renderIcon, drawCenter, facePP, faceNormal, uvRot); + renderQuad(renderIcon, drawCenter, facePP.inverse(), faceNormal, uvRot); + renderQuad(renderIcon, drawCenter, faceNP, faceNormal, uvRot); + renderQuad(renderIcon, drawCenter, faceNP.inverse(), faceNormal, uvRot); + } + } + + protected void renderCrossedBlockQuadsTranslate(Double3 blockCenter, double halfSize, Double3 offsetVec, IIcon crossLeafIcon, int uvRot, boolean isAirTop, boolean isAirBottom) { + Double3 drawCenter = blockCenter; + if (offsetVec != null) drawCenter = drawCenter.add(offsetVec); + Double3 horz1 = new Double3(halfSize, 0.0, halfSize); + Double3 horz2 = new Double3(halfSize, 0.0, -halfSize); + Double3 vert1 = new Double3(0.0, halfSize * 1.41, 0.0); + + renderCrossedBlockQuadsInternal(drawCenter, horz1, horz2, vert1, crossLeafIcon, uvRot, isAirTop, isAirBottom); + } + + protected void renderCrossedBlockQuadsSkew(Double3 blockCenter, double halfSize, Double3 offsetVec1, Double3 offsetVec2, IIcon crossLeafIcon, int uvRot, boolean isAirTop, boolean isAirBottom) { + Double3 horz1 = new Double3(halfSize, 0.0, halfSize).add(offsetVec1); + Double3 horz2 = new Double3(halfSize, 0.0, -halfSize).add(offsetVec2); + Double3 vert1 = new Double3(0.0, halfSize * 1.41, 0.0); + + renderCrossedBlockQuadsInternal(blockCenter, horz1, horz2, vert1, crossLeafIcon, uvRot, isAirTop, isAirBottom); + } + + private void renderCrossedBlockQuadsInternal(Double3 drawCenter, Double3 horz1, Double3 horz2, Double3 vert1, IIcon crossLeafIcon, int uvRot, boolean isAirTop, boolean isAirBottom) { + if (Minecraft.isAmbientOcclusionEnabled()) { + renderQuadWithShading(crossLeafIcon, drawCenter, horz1, vert1, uvRot, + isAirTop ? aoYPXZPP : aoZPXYPP, isAirTop ? aoYPXZNN : aoXNYZPN, isAirBottom ? aoYNXZNN : aoXNYZNN, isAirBottom ? aoYNXZPP : aoZPXYPN); + renderQuadWithShading(crossLeafIcon, drawCenter, horz1.inverse(), vert1, uvRot, + isAirTop ? aoYPXZNN : aoZNXYNP, isAirTop ? aoYPXZPP : aoXPYZPP, isAirBottom ? aoYNXZPP : aoXPYZNP, isAirBottom ? aoYNXZNN : aoZNXYNN); + renderQuadWithShading(crossLeafIcon, drawCenter, horz2, vert1, uvRot, + isAirTop ? aoYPXZPN : aoXPYZPN, isAirTop ? aoYPXZNP : aoZPXYNP, isAirBottom ? aoYNXZNP : aoZPXYNN, isAirBottom ? aoYNXZPN : aoXPYZNN); + renderQuadWithShading(crossLeafIcon, drawCenter, horz2.inverse(), vert1, uvRot, + isAirTop ? aoYPXZNP : aoXNYZPP, isAirTop ? aoYPXZPN : aoZNXYPP, isAirBottom ? aoYNXZPN : aoZNXYPN, isAirBottom ? aoYNXZNP : aoXNYZNP); + } else { + renderQuad(crossLeafIcon, drawCenter, horz1, vert1, uvRot); + renderQuad(crossLeafIcon, drawCenter, horz1.inverse(), vert1, uvRot); + renderQuad(crossLeafIcon, drawCenter, horz2, vert1, uvRot); + renderQuad(crossLeafIcon, drawCenter, horz2.inverse(), vert1, uvRot); + } + } + @Override public void renderFaceZNeg(Block block, double x, double y, double z, IIcon icon) { super.renderFaceZNeg(block, x, y, z, icon); @@ -206,9 +325,6 @@ public class RenderBlockAOBase extends RenderBlocks { saveShadingBottomRight(aoYPXZNN); } - /** Save AO values for top left vertex - * @param values {@link ShadingValues} to store values in - */ protected void saveShadingTopLeft(ShadingValues values) { if (--values.passCounter != 0) return; values.brightness = brightnessTopLeft; @@ -314,4 +430,8 @@ public class RenderBlockAOBase extends RenderBlocks { tessellator.setColorOpaque_F(aoPN.red, aoPN.green, aoPN.blue); tessellator.addVertexWithUV(center.x + vec1.x - vec2.x, center.y + vec1.y - vec2.y, center.z + vec1.z - vec2.z, icon.getInterpolatedU(uValues[(uvRot + 3) & 3]), icon.getInterpolatedV(vValues[(uvRot + 3) & 3])); } + + protected int getBrightness(Block block, int x, int y, int z) { + return block.getMixedBrightnessForBlock(blockAccess, x, y, z); + } } diff --git a/src/main/java/mods/betterfoliage/client/render/RenderBlockBetterGrass.java b/src/main/java/mods/betterfoliage/client/render/RenderBlockBetterGrass.java deleted file mode 100644 index a2e41da..0000000 --- a/src/main/java/mods/betterfoliage/client/render/RenderBlockBetterGrass.java +++ /dev/null @@ -1,88 +0,0 @@ -package mods.betterfoliage.client.render; - -import mods.betterfoliage.common.config.Config; -import mods.betterfoliage.common.util.Double3; -import net.minecraft.block.Block; -import net.minecraft.client.Minecraft; -import net.minecraft.client.renderer.RenderBlocks; -import net.minecraft.client.renderer.Tessellator; -import net.minecraft.util.IIcon; -import net.minecraft.world.IBlockAccess; -import net.minecraftforge.client.event.TextureStitchEvent; -import net.minecraftforge.common.MinecraftForge; -import cpw.mods.fml.client.registry.ISimpleBlockRenderingHandler; -import cpw.mods.fml.client.registry.RenderingRegistry; -import cpw.mods.fml.common.eventhandler.SubscribeEvent; -import cpw.mods.fml.relauncher.Side; -import cpw.mods.fml.relauncher.SideOnly; - -@SideOnly(Side.CLIENT) -public class RenderBlockBetterGrass extends RenderBlockAOBase implements ISimpleBlockRenderingHandler { - - public IIcon grassIcons[] = new IIcon[2]; - - public static int register() { - int result = RenderingRegistry.getNextAvailableRenderId(); - RenderBlockBetterGrass renderGrass = new RenderBlockBetterGrass(); - RenderingRegistry.registerBlockHandler(result, renderGrass); - MinecraftForge.EVENT_BUS.register(renderGrass); - renderGrass.init(); - return result; - } - - public void renderInventoryBlock(Block block, int metadata, int modelId, RenderBlocks renderer) { - renderStandardBlockAsItem(renderer, block, metadata, 1.0f); - } - - public boolean renderWorldBlock(IBlockAccess world, int x, int y, int z, Block block, int modelId, RenderBlocks renderer) { - // store world for later use - blockAccess = world; - - // render grass block - setRenderBoundsFromBlock(block); - setPassCounters(1); - boolean result = renderStandardBlock(block, x, y, z); - - if (y == 255 || !blockAccess.isAirBlock(x, y + 1, z)) return result; - - int variation = getSemiRandomFromPos(x, y, z, 0); - int heightVariation = getSemiRandomFromPos(x, y, z, 1); - double halfSize = Config.grassSize.value * 0.5; - double halfHeight = 0.5 * (Config.grassHeightMin.value + pRand[heightVariation] * (Config.grassHeightMax.value - Config.grassHeightMin.value)); - Double3 drawCenter = new Double3(x + 0.5, y + 1.0 + halfHeight, z + 0.5).add(pRot[variation].scaleAxes(Config.grassHOffset.value, 0.0, Config.grassHOffset.value)); - Double3 horz1 = new Double3(halfSize, 0.0, halfSize); - Double3 horz2 = new Double3(halfSize, 0.0, -halfSize); - Double3 vert1 = new Double3(0.0, halfHeight, 0.0); - IIcon grassIcon = grassIcons[variation % 2]; - - if (Minecraft.isAmbientOcclusionEnabled()) { - renderQuadWithShading(grassIcon, drawCenter, horz1, vert1, 0, aoYPXZPP, aoYPXZNN, aoYPXZNN, aoYPXZPP); - renderQuadWithShading(grassIcon, drawCenter, horz1.inverse(), vert1, 0, aoYPXZNN, aoYPXZPP, aoYPXZPP, aoYPXZNN); - renderQuadWithShading(grassIcon, drawCenter, horz2, vert1, 0, aoYPXZPN, aoYPXZNP, aoYPXZNP, aoYPXZPN); - renderQuadWithShading(grassIcon, drawCenter, horz2.inverse(), vert1, 0, aoYPXZNP, aoYPXZPN, aoYPXZPN, aoYPXZNP); - } else { - Tessellator.instance.setBrightness(block.getMixedBrightnessForBlock(blockAccess, x, y + 1, z)); - renderQuad(grassIcon, drawCenter, horz1, vert1, 0); - renderQuad(grassIcon, drawCenter, horz1.inverse(), vert1, 0); - renderQuad(grassIcon, drawCenter, horz2, vert1, 0); - renderQuad(grassIcon, drawCenter, horz2.inverse(), vert1, 0); - } - return result; - } - - public boolean shouldRender3DInInventory(int modelId) { - return true; - } - - public int getRenderId() { - return 0; - } - - @SubscribeEvent - public void handleTextureReload(TextureStitchEvent.Pre event) { - if (event.map.getTextureType() != 0) return; - for (int idx = 0; idx < 2; idx++) { - grassIcons[idx] = event.map.registerIcon(String.format("betterfoliage:grass_%d", idx)); - } - } -} diff --git a/src/main/java/mods/betterfoliage/client/render/RenderBlockBetterLeaves.java b/src/main/java/mods/betterfoliage/client/render/RenderBlockBetterLeaves.java deleted file mode 100644 index 373c479..0000000 --- a/src/main/java/mods/betterfoliage/client/render/RenderBlockBetterLeaves.java +++ /dev/null @@ -1,111 +0,0 @@ -package mods.betterfoliage.client.render; - -import mods.betterfoliage.client.BetterFoliageClient; -import mods.betterfoliage.common.config.Config; -import mods.betterfoliage.common.util.Double3; -import mods.betterfoliage.common.util.ReflectionUtil; -import net.minecraft.block.Block; -import net.minecraft.client.Minecraft; -import net.minecraft.client.renderer.RenderBlocks; -import net.minecraft.client.renderer.Tessellator; -import net.minecraft.client.renderer.texture.TextureAtlasSprite; -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.client.registry.RenderingRegistry; -import cpw.mods.fml.relauncher.Side; -import cpw.mods.fml.relauncher.SideOnly; - -@SideOnly(Side.CLIENT) -public class RenderBlockBetterLeaves extends RenderBlockAOBase implements ISimpleBlockRenderingHandler { - - public static int register() { - int result = RenderingRegistry.getNextAvailableRenderId(); - RenderBlockBetterLeaves renderLeaves = new RenderBlockBetterLeaves(); - RenderingRegistry.registerBlockHandler(result, renderLeaves); - renderLeaves.init(); - return result; - } - - public void renderInventoryBlock(Block block, int metadata, int modelId, RenderBlocks renderer) { - renderStandardBlockAsItem(renderer, block, metadata, 1.0f); - } - - public boolean renderWorldBlock(IBlockAccess world, int x, int y, int z, Block block, int modelId, RenderBlocks renderer) { - // store world for later use - blockAccess = world; - - // render leaves center - setPassCounters(1); - int origRenderType = block.getRenderType(); - boolean result; - - setRenderBoundsFromBlock(block); - if (origRenderType == 0) { - result = renderStandardBlock(block, x, y, z); - } else { - ISimpleBlockRenderingHandler handler = ReflectionUtil.getRenderingHandler(origRenderType); - result = handler.renderWorldBlock(world, x, y, z, block, origRenderType, this); - } - - if (isBlockSurrounded(x, y, z)) return result; - - // find generated texture to render with, assume the - // "true" texture of the block is the one on the north size - TextureAtlasSprite blockLeafIcon = (TextureAtlasSprite) block.getIcon(world, x, y, z, ForgeDirection.NORTH.ordinal()); - IIcon crossLeafIcon = Minecraft.getMinecraft().getTextureMapBlocks().getAtlasSprite(BetterFoliageClient.leafGenerator.domainName + ":" + blockLeafIcon.getIconName()); - if (crossLeafIcon == null) { - return result; - } - - int variation = getSemiRandomFromPos(x, y, z, 0); - double halfSize = 0.5 * Config.leavesSize.value; - boolean isAirTop = y == 255 || blockAccess.isAirBlock(x, y + 1, z); - boolean isAirBottom = y == 0 || blockAccess.isAirBlock(x, y - 1, z); - Double3 drawCenter = new Double3(x + 0.5, y + 0.5, z + 0.5); - Double3 horz1 = new Double3(halfSize, 0.0, halfSize).add(pRot[variation].scaleAxes(Config.leavesHOffset.value, Config.leavesVOffset.value, Config.leavesHOffset.value)); - Double3 horz2 = new Double3(halfSize, 0.0, -halfSize).add(pRot[(variation + 1) & 63].scaleAxes(Config.leavesHOffset.value, Config.leavesVOffset.value, Config.leavesHOffset.value)); - Double3 vert1 = new Double3(0.0, halfSize * 1.41, 0.0); - - if (Minecraft.isAmbientOcclusionEnabled()) { - renderQuadWithShading(crossLeafIcon, drawCenter, horz1, vert1, variation, - isAirTop ? aoYPXZPP : aoZPXYPP, isAirTop ? aoYPXZNN : aoXNYZPN, isAirBottom ? aoYNXZNN : aoXNYZNN, isAirBottom ? aoYNXZPP : aoZPXYPN); - renderQuadWithShading(crossLeafIcon, drawCenter, horz1.inverse(), vert1, variation, - isAirTop ? aoYPXZNN : aoZNXYNP, isAirTop ? aoYPXZPP : aoXPYZPP, isAirBottom ? aoYNXZPP : aoXPYZNP, isAirBottom ? aoYNXZNN : aoZNXYNN); - renderQuadWithShading(crossLeafIcon, drawCenter, horz2, vert1, variation, - isAirTop ? aoYPXZPN : aoXPYZPN, isAirTop ? aoYPXZNP : aoZPXYNP, isAirBottom ? aoYNXZNP : aoZPXYNN, isAirBottom ? aoYNXZPN : aoXPYZNN); - renderQuadWithShading(crossLeafIcon, drawCenter, horz2.inverse(), vert1, variation, - isAirTop ? aoYPXZNP : aoXNYZPP, isAirTop ? aoYPXZPN : aoZNXYPP, isAirBottom ? aoYNXZPN : aoZNXYPN, isAirBottom ? aoYNXZNP : aoXNYZNP); - } else { - if (isAirTop) Tessellator.instance.setBrightness(block.getMixedBrightnessForBlock(blockAccess, x, y + 1, z)); - else if (isAirBottom) Tessellator.instance.setBrightness(block.getMixedBrightnessForBlock(blockAccess, x, y - 1, z)); - else Tessellator.instance.setBrightness(block.getMixedBrightnessForBlock(blockAccess, x, y, z)); - - renderQuad(crossLeafIcon, drawCenter, horz1, vert1, variation); - renderQuad(crossLeafIcon, drawCenter, horz1.inverse(), vert1, variation); - renderQuad(crossLeafIcon, drawCenter, horz2, vert1, variation); - renderQuad(crossLeafIcon, drawCenter, horz2.inverse(), vert1, variation); - } - return result; - } - - public boolean shouldRender3DInInventory(int modelId) { - return true; - } - - public int getRenderId() { - return 0; - } - - protected boolean isBlockSurrounded(int x, int y, int z) { - if (blockAccess.isAirBlock(x + 1, y, z)) return false; - if (blockAccess.isAirBlock(x - 1, y, z)) return false; - if (blockAccess.isAirBlock(x, y, z + 1)) return false; - if (blockAccess.isAirBlock(x, y, z - 1)) return false; - if (y == 255 || blockAccess.isAirBlock(x, y + 1, z)) return false; - if (y == 0 || blockAccess.isAirBlock(x, y - 1, z)) return false; - return true; - } - -} diff --git a/src/main/java/mods/betterfoliage/client/render/impl/RenderBlockBetterCactus.java b/src/main/java/mods/betterfoliage/client/render/impl/RenderBlockBetterCactus.java new file mode 100644 index 0000000..745adfa --- /dev/null +++ b/src/main/java/mods/betterfoliage/client/render/impl/RenderBlockBetterCactus.java @@ -0,0 +1,84 @@ +package mods.betterfoliage.client.render.impl; + +import mods.betterfoliage.client.render.FakeRenderBlockAOBase; +import mods.betterfoliage.client.render.IRenderBlockDecorator; +import mods.betterfoliage.common.config.Config; +import mods.betterfoliage.common.util.Double3; +import net.minecraft.block.Block; +import net.minecraft.client.Minecraft; +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 RenderBlockBetterCactus extends FakeRenderBlockAOBase implements IRenderBlockDecorator { + + public IIcon cactusRoundIcon; + public IIcon cactusSideIcons[] = new IIcon[2]; + + public static ForgeDirection[] cactusDirections = new ForgeDirection[] { ForgeDirection.NORTH, ForgeDirection.SOUTH, ForgeDirection.EAST, ForgeDirection.WEST}; + public static double cactusRadius = 0.4375; + + public boolean isBlockAccepted(IBlockAccess blockAccess, int x, int y, int z, Block block, int original) { + return Config.cactusEnabled && block == Blocks.cactus; + } + + public boolean renderWorldBlock(IBlockAccess world, int x, int y, int z, Block block, int modelId, RenderBlocks renderer) { + // store world for later use + blockAccess = world; + + // render cactus center + setPassCounters(1); + setRenderBoundsFromBlock(block); + + Double3 blockCenter = new Double3(x + 0.5, y + 0.5, z + 0.5); + renderStandardBlock(block, x, y, z); + Tessellator.instance.setBrightness(getBrightness(block,x, y, z)); + renderCactusCore(block.getBlockTextureFromSide(ForgeDirection.UP.ordinal()), + block.getBlockTextureFromSide(ForgeDirection.NORTH.ordinal()), + blockCenter, 0); + + // render side growth + ForgeDirection drawDirection = cactusDirections[getSemiRandomFromPos(x, y, z, 0) % 4]; + int iconVariation = getSemiRandomFromPos(x, y, z, 1); + Double3 drawBase = blockCenter.add(new Double3(drawDirection).scale(cactusRadius)); + + Tessellator.instance.setBrightness(getBrightness(block, x, y, z)); + renderCrossedSideQuads(drawBase, drawDirection, 0.5, 0.5, pRot[iconVariation], 0.2, cactusSideIcons[iconVariation % 2], 0, false); + renderCrossedBlockQuadsSkew(blockCenter, 0.65, + pRot[iconVariation].scaleAxes(0.1, 0.0, 0.1), + pRot[(iconVariation + 1) & 63].scaleAxes(0.1, 0.0, 0.1), + cactusRoundIcon, iconVariation, false, false); + return true; + } + + protected void renderCactusCore(IIcon topIcon, IIcon sideIcon, Double3 blockCenter, int sideUvRot) { + if (Minecraft.isAmbientOcclusionEnabled()) { + renderQuadWithShading(sideIcon, blockCenter.add(cactusRadius, 0.0, 0.0), new Double3(0.0, 0.0, -0.5), new Double3(0.0, 0.5, 0.0), sideUvRot, aoXPYZPN, aoXPYZPP, aoXPYZNP, aoXPYZNN); + renderQuadWithShading(sideIcon, blockCenter.add(-cactusRadius, 0.0, 0.0), new Double3(0.0, 0.0, 0.5), new Double3(0.0, 0.5, 0.0), sideUvRot, aoXNYZPP, aoXNYZPN, aoXNYZNN, aoXNYZNP); + renderQuadWithShading(sideIcon, blockCenter.add(0.0, 0.0, cactusRadius), new Double3(0.5, 0.0, 0.0), new Double3(0.0, 0.5, 0.0), sideUvRot, aoZPXYPP, aoZPXYNP, aoZPXYNN, aoZPXYPN); + renderQuadWithShading(sideIcon, blockCenter.add(0.0, 0.0, -cactusRadius), new Double3(-0.5, 0.0, 0.0), new Double3(0.0, 0.5, 0.0), sideUvRot, aoZNXYNP, aoZNXYPP, aoZNXYPN, aoZNXYNN); + renderQuadWithShading(topIcon, blockCenter.add(0.0, 0.5, 0.0), new Double3(-0.5, 0.0, 0.0), new Double3(0.0, 0.0, 0.5), 0, aoYPXZNP, aoYPXZPP, aoYPXZPN, aoYPXZNN); + } else { + renderQuad(sideIcon, blockCenter.add(cactusRadius, 0.0, 0.0), new Double3(0.0, 0.0, -0.5), new Double3(0.0, 0.5, 0.0), sideUvRot); + renderQuad(sideIcon, blockCenter.add(-cactusRadius, 0.0, 0.0), new Double3(0.0, 0.0, 0.5), new Double3(0.0, 0.5, 0.0), sideUvRot); + renderQuad(sideIcon, blockCenter.add(0.0, 0.0, cactusRadius), new Double3(0.5, 0.0, 0.0), new Double3(0.0, 0.5, 0.0), sideUvRot); + renderQuad(sideIcon, blockCenter.add(0.0, 0.0, -cactusRadius), new Double3(-0.5, 0.0, 0.0), new Double3(0.0, 0.5, 0.0), sideUvRot); + renderQuad(topIcon, blockCenter.add(0.0, 0.5, 0.0), new Double3(-0.5, 0.0, 0.0), new Double3(0.0, 0.0, 0.5), 0); + } + } + + @SubscribeEvent + public void handleTextureReload(TextureStitchEvent.Pre event) { + if (event.map.getTextureType() != 0) return; + cactusRoundIcon = event.map.registerIcon("bettergrassandleaves:better_cactus"); + for (int idx = 0; idx < 2; idx++) cactusSideIcons[idx] = event.map.registerIcon("bettergrassandleaves:better_cactus_arm_" + Integer.toString(idx)); + } +} diff --git a/src/main/java/mods/betterfoliage/client/render/impl/RenderBlockBetterGrass.java b/src/main/java/mods/betterfoliage/client/render/impl/RenderBlockBetterGrass.java new file mode 100644 index 0000000..e4023db --- /dev/null +++ b/src/main/java/mods/betterfoliage/client/render/impl/RenderBlockBetterGrass.java @@ -0,0 +1,65 @@ +package mods.betterfoliage.client.render.impl; + +import mods.betterfoliage.client.render.IRenderBlockDecorator; +import mods.betterfoliage.client.render.RenderBlockAOBase; +import mods.betterfoliage.common.config.Config; +import mods.betterfoliage.common.util.Double3; +import net.minecraft.block.Block; +import net.minecraft.block.BlockGrass; +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 RenderBlockBetterGrass extends RenderBlockAOBase implements IRenderBlockDecorator { + + public IIcon grassIcons[] = new IIcon[5]; + public IIcon myceliumIcons[] = new IIcon[4]; + + public boolean isBlockAccepted(IBlockAccess blockAccess, int x, int y, int z, Block block, int original) { + if (!Config.grassEnabled) return false; + if (!((block instanceof BlockGrass || block == Blocks.mycelium))) return false; + if (y == 255 || !blockAccess.isAirBlock(x, y + 1, z)) return false; + return true; + } + + public boolean renderWorldBlock(IBlockAccess world, int x, int y, int z, Block block, int modelId, RenderBlocks renderer) { + // store world for later use + blockAccess = world; + + // render grass block + setPassCounters(1); + setRenderBoundsFromBlock(block); + renderStandardBlock(block, x, y, z); + + int variation = getSemiRandomFromPos(x, y, z, 0); + int heightVariation = getSemiRandomFromPos(x, y, z, 1); + + IIcon renderIcon = (block == Blocks.mycelium) ? myceliumIcons[variation % 4] : grassIcons[variation % 5]; + + double scale = Config.grassSize.value * 0.5; + double halfHeight = 0.5 * (Config.grassHeightMin.value + pRand[heightVariation] * (Config.grassHeightMax.value - Config.grassHeightMin.value)); + Tessellator.instance.setBrightness(getBrightness(block, x, y + 1, z)); + renderCrossedSideQuads(new Double3(x + 0.5, y + 1.0, z + 0.5), ForgeDirection.UP, scale, halfHeight, pRot[variation], Config.grassHOffset.value, renderIcon, 0, false); + + return true; + } + + @SubscribeEvent + public void handleTextureReload(TextureStitchEvent.Pre event) { + if (event.map.getTextureType() != 0) return; + for (int idx = 0; idx < 5; idx++) { + grassIcons[idx] = event.map.registerIcon(String.format("bettergrassandleaves:better_grass_long_%d", idx)); + } + for (int idx = 0; idx < 4; idx++) { + myceliumIcons[idx] = event.map.registerIcon(String.format("bettergrassandleaves:better_mycel_%d", idx)); + } + } +} diff --git a/src/main/java/mods/betterfoliage/client/render/impl/RenderBlockBetterLeaves.java b/src/main/java/mods/betterfoliage/client/render/impl/RenderBlockBetterLeaves.java new file mode 100644 index 0000000..67fffb2 --- /dev/null +++ b/src/main/java/mods/betterfoliage/client/render/impl/RenderBlockBetterLeaves.java @@ -0,0 +1,89 @@ +package mods.betterfoliage.client.render.impl; + +import mods.betterfoliage.client.BetterFoliageClient; +import mods.betterfoliage.client.render.IRenderBlockDecorator; +import mods.betterfoliage.client.render.RenderBlockAOBase; +import mods.betterfoliage.common.config.Config; +import mods.betterfoliage.common.util.Double3; +import mods.betterfoliage.common.util.ReflectionUtil; +import net.minecraft.block.Block; +import net.minecraft.client.Minecraft; +import net.minecraft.client.renderer.RenderBlocks; +import net.minecraft.client.renderer.Tessellator; +import net.minecraft.client.renderer.texture.TextureAtlasSprite; +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; + +@SideOnly(Side.CLIENT) +public class RenderBlockBetterLeaves extends RenderBlockAOBase implements IRenderBlockDecorator { + + public boolean isBlockAccepted(IBlockAccess blockAccess, int x, int y, int z, Block block, int original) { + if (!Config.leavesEnabled) return false; + if (original > 0 && original < 42) return false; + for (Class clazz : BetterFoliageClient.blockLeavesClasses) + if (clazz.isAssignableFrom(block.getClass())) + return !isBlockSurrounded(blockAccess, x, y, z); + return false; + } + + public boolean renderWorldBlock(IBlockAccess world, int x, int y, int z, Block block, int modelId, RenderBlocks renderer) { + // store world for later use + blockAccess = world; + + // render leaves center + setPassCounters(1); + setRenderBoundsFromBlock(block); + if (block.getRenderType() == 0) { + renderStandardBlock(block, x, y, z); + } else { + ISimpleBlockRenderingHandler handler = ReflectionUtil.getRenderingHandler(block.getRenderType()); + handler.renderWorldBlock(world, x, y, z, block, block.getRenderType(), this); + } + + // find generated texture to render with, assume the + // "true" texture of the block is the one on the north size + TextureAtlasSprite blockLeafIcon = (TextureAtlasSprite) block.getIcon(world, x, y, z, ForgeDirection.NORTH.ordinal()); + IIcon crossLeafIcon = Minecraft.getMinecraft().getTextureMapBlocks().getAtlasSprite(BetterFoliageClient.leafGenerator.domainName + ":" + blockLeafIcon.getIconName()); + if (crossLeafIcon == null) { + return true; + } + + int offsetVariation = getSemiRandomFromPos(x, y, z, 0); + int uvVariation = getSemiRandomFromPos(x, y, z, 1); + double halfSize = 0.5 * Config.leavesSize.value; + boolean isAirTop = y == 255 || blockAccess.isAirBlock(x, y + 1, z); + boolean isAirBottom = y == 0 || blockAccess.isAirBlock(x, y - 1, z); + + Tessellator.instance.setBrightness(isAirTop ? getBrightness(block, x, y + 1, z) : (isAirBottom ? getBrightness(block, x, y - 1, z) : getBrightness(block, x, y, z))); + Tessellator.instance.setColorOpaque_I(block.colorMultiplier(blockAccess, x, y, z)); + + if (Config.leavesSkew) { + renderCrossedBlockQuadsSkew(new Double3(x + 0.5, y + 0.5, z + 0.5), halfSize, + pRot[offsetVariation].scaleAxes(Config.leavesHOffset.value, Config.leavesVOffset.value, Config.leavesHOffset.value), + pRot[(offsetVariation + 1) & 63].scaleAxes(Config.leavesHOffset.value, Config.leavesVOffset.value, Config.leavesHOffset.value), + crossLeafIcon, uvVariation, isAirTop, isAirBottom); + } else { + renderCrossedBlockQuadsTranslate(new Double3(x + 0.5, y + 0.5, z + 0.5), halfSize, + pRot[offsetVariation].scaleAxes(Config.leavesHOffset.value, Config.leavesVOffset.value, Config.leavesHOffset.value), + crossLeafIcon, uvVariation, isAirTop, isAirBottom); + } + + + return true; + } + + protected boolean isBlockSurrounded(IBlockAccess blockAccess, int x, int y, int z) { + if (blockAccess.isAirBlock(x + 1, y, z)) return false; + if (blockAccess.isAirBlock(x - 1, y, z)) return false; + if (blockAccess.isAirBlock(x, y, z + 1)) return false; + if (blockAccess.isAirBlock(x, y, z - 1)) return false; + if (y == 255 || blockAccess.isAirBlock(x, y + 1, z)) return false; + if (y == 0 || blockAccess.isAirBlock(x, y - 1, z)) return false; + return true; + } + +} diff --git a/src/main/java/mods/betterfoliage/client/render/impl/RenderBlockBetterLilypad.java b/src/main/java/mods/betterfoliage/client/render/impl/RenderBlockBetterLilypad.java new file mode 100644 index 0000000..3142950 --- /dev/null +++ b/src/main/java/mods/betterfoliage/client/render/impl/RenderBlockBetterLilypad.java @@ -0,0 +1,64 @@ +package mods.betterfoliage.client.render.impl; + +import mods.betterfoliage.client.render.FakeRenderBlockAOBase; +import mods.betterfoliage.client.render.IRenderBlockDecorator; +import mods.betterfoliage.common.config.Config; +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 RenderBlockBetterLilypad extends FakeRenderBlockAOBase implements IRenderBlockDecorator { + + public IIcon lilypadFlowers[] = new IIcon[2]; + public IIcon lilypadRoots[] = new IIcon[3]; + + public boolean isBlockAccepted(IBlockAccess blockAccess, int x, int y, int z, Block block, int original) { + return Config.lilypadEnabled && block == Blocks.waterlily; + } + + public boolean renderWorldBlock(IBlockAccess world, int x, int y, int z, Block block, int modelId, RenderBlocks renderer) { + // store world for later use + blockAccess = world; + + // render grass block + renderBlockLilyPad(block, x, y, z); + + int chanceVariation = getSemiRandomFromPos(x, y, z, 0); + int iconVariation = getSemiRandomFromPos(x, y, z, 1); + int offsetVariation = getSemiRandomFromPos(x, y, z, 2); + + Tessellator.instance.setBrightness(getBrightness(block, x, y, z)); + Tessellator.instance.setColorOpaque(255, 255, 255); + renderCrossedSideQuads(new Double3(x + 0.5, y + 0.015, z + 0.5), ForgeDirection.DOWN, + 0.2, 0.3, + null, 0.0, + lilypadRoots[iconVariation % 3], 2, + true); + if (chanceVariation < Config.lilypadChance.value) + renderCrossedSideQuads(new Double3(x + 0.5, y + 0.02, z + 0.5), ForgeDirection.UP, + 0.2, 0.3, + pRot[offsetVariation], Config.lilypadHOffset.value, + lilypadFlowers[iconVariation % 2], 0, + true); + + return true; + } + + @SubscribeEvent + public void handleTextureReload(TextureStitchEvent.Pre event) { + if (event.map.getTextureType() != 0) return; + for (int idx = 0; idx < 2; idx++) lilypadFlowers[idx] = event.map.registerIcon("bettergrassandleaves:better_lilypad_flower_" + Integer.toString(idx)); + for (int idx = 0; idx < 3; idx++) lilypadRoots[idx] = event.map.registerIcon("bettergrassandleaves:better_lilypad_roots_" + Integer.toString(idx)); + } + +} diff --git a/src/main/java/mods/betterfoliage/client/resource/LeafTextureGenerator.java b/src/main/java/mods/betterfoliage/client/resource/LeafTextureGenerator.java index 365b80a..26e29b5 100644 --- a/src/main/java/mods/betterfoliage/client/resource/LeafTextureGenerator.java +++ b/src/main/java/mods/betterfoliage/client/resource/LeafTextureGenerator.java @@ -142,7 +142,14 @@ public class LeafTextureGenerator implements IIconRegister, IResourceManager { @SubscribeEvent public void endTextureReload(TextureStitchEvent.Post event) { blockTextures = null; - if (event.map.getTextureType() == 0) BetterFoliage.log.info(String.format("Generated %d leaf textures", counter)); + if (event.map.getTextureType() == 0) { + BetterFoliage.log.info(String.format("Generated %d leaf textures", counter)); + + // don't leave a mess + Map domainManagers = ReflectionUtil.getDomainResourceManagers(); + if (domainManagers == null) return; + domainManagers.remove(domainName); + } } public void loadLeafMappings(File leafMaskFile) { diff --git a/src/main/java/mods/betterfoliage/common/config/Config.java b/src/main/java/mods/betterfoliage/common/config/Config.java index c2b499b..e44d46e 100644 --- a/src/main/java/mods/betterfoliage/common/config/Config.java +++ b/src/main/java/mods/betterfoliage/common/config/Config.java @@ -8,7 +8,10 @@ import net.minecraftforge.common.config.Configuration; public class Config { public static boolean leavesEnabled = true; + public static boolean leavesSkew = false; public static boolean grassEnabled = true; + public static boolean cactusEnabled = true; + public static boolean lilypadEnabled = true; public static OptionDouble leavesHOffset = new OptionDouble(0.0, 0.4, 0.025, 0.2); public static OptionDouble leavesVOffset = new OptionDouble(0.0, 0.4, 0.025, 0.1); @@ -19,6 +22,9 @@ public class Config { public static OptionDouble grassHeightMax = new OptionDouble(0.1, 1.5, 0.05, 1.0); public static OptionDouble grassSize = new OptionDouble(0.5, 1.5, 0.05, 1.0); + public static OptionDouble lilypadHOffset = new OptionDouble(0.0, 0.25, 0.025, 0.1); + public static OptionInteger lilypadChance = new OptionInteger(0, 64, 1, 16); + private Config() {} public static void load() { @@ -26,6 +32,7 @@ public class Config { config.load(); leavesEnabled = config.get("render", "leavesEnabled", true).getBoolean(true); + leavesSkew = config.get("render", "leavesOffsetSkew", false).getBoolean(false); loadValue(config, "render", "leavesHorizontalOffset", leavesHOffset); loadValue(config, "render", "leavesVerticalOffset", leavesVOffset); loadValue(config, "render", "leavesSize", leavesSize); @@ -36,6 +43,11 @@ public class Config { loadValue(config, "render", "grassHeightMax", grassHeightMax); if (grassHeightMin.value > grassHeightMax.value) grassHeightMin.value = grassHeightMax.value; + grassEnabled = config.get("render", "cactusEnabled", true).getBoolean(true); + grassEnabled = config.get("render", "lilypadEnabled", true).getBoolean(true); + loadValue(config, "render", "lilypadHorizontalOffset", lilypadHOffset); + loadValue(config, "render", "lilypadChance", lilypadChance); + if (config.hasChanged()) config.save(); } @@ -44,6 +56,7 @@ public class Config { config.load(); config.get("render", "leavesEnabled", true).set(leavesEnabled); + config.get("render", "leavesOffsetSkew", false).set(leavesSkew); saveValue(config, "render", "leavesHorizontalOffset", leavesHOffset); saveValue(config, "render", "leavesVerticalOffset", leavesVOffset); saveValue(config, "render", "leavesSize", leavesSize); @@ -53,6 +66,11 @@ public class Config { saveValue(config, "render", "grassHeightMin", grassHeightMin); saveValue(config, "render", "grassHeightMax", grassHeightMax); + config.get("render", "cactusEnabled", true).set(cactusEnabled); + config.get("render", "lilypadEnabled", true).set(lilypadEnabled); + saveValue(config, "render", "lilypadHorizontalOffset", lilypadHOffset); + saveValue(config, "render", "lilypadChance", lilypadChance); + if (config.hasChanged()) config.save(); } @@ -71,4 +89,20 @@ public class Config { saveValue(config, category, key, option); } } + + protected static void saveValue(Configuration config, String category, String key, OptionInteger option) { + config.get(category, key, option.value).set(option.value); + } + + protected static void loadValue(Configuration config, String category, String key, OptionInteger option) { + option.value = config.get(category, key, option.value).getInt(option.value); + if (option.value > option.max) { + option.value = option.max; + saveValue(config, category, key, option); + } + if (option.value < option.min) { + option.value = option.min; + saveValue(config, category, key, option); + } + } } diff --git a/src/main/java/mods/betterfoliage/common/config/OptionInteger.java b/src/main/java/mods/betterfoliage/common/config/OptionInteger.java new file mode 100644 index 0000000..448c887 --- /dev/null +++ b/src/main/java/mods/betterfoliage/common/config/OptionInteger.java @@ -0,0 +1,26 @@ +package mods.betterfoliage.common.config; + +public class OptionInteger { + + public int min; + public int max; + public int step; + public int value; + + public OptionInteger(int min, int max, int step, int value) { + this.min = min; + this.max = max; + this.step = step; + this.value = value; + } + + public void increment() { + value += step; + if (value > max) value = max; + } + + public void decrement() { + value -= step; + if (value < min) value = min; + } +} diff --git a/src/main/java/mods/betterfoliage/common/util/DeobfNames.java b/src/main/java/mods/betterfoliage/common/util/DeobfNames.java index 797ddac..9d46d97 100644 --- a/src/main/java/mods/betterfoliage/common/util/DeobfNames.java +++ b/src/main/java/mods/betterfoliage/common/util/DeobfNames.java @@ -4,6 +4,24 @@ public class DeobfNames { private DeobfNames() {} + /** MCP name of RenderBlocks */ + public static final String RB_NAME_MCP = "net/minecraft/client/renderer/RenderBlocks"; + + /** Obfuscated name of RenderBlocks */ + public static final String RB_NAME_OBF = "ble"; + + /** MCP name of RenderBlocks.blockAccess */ + public static final String RB_BA_NAME_MCP = "blockAccess"; + + /** Obfuscated name of RenderBlocks.blockAccess */ + public static final String RB_BA_NAME_OBF = "a"; + + /** MCP signature of RenderBlocks.blockAccess */ + public static final String RB_BA_SIG_MCP = "Lnet/minecraft/world/IBlockAccess;"; + + /** Obfuscated signature of RenderBlocks.blockAccess */ + public static final String RB_BA_SIG_OBF = "Lafx;"; + /** MCP name of RenderBlocks.renderBlockByRenderType() */ public static final String RB_RBBRT_NAME_MCP = "renderBlockByRenderType"; @@ -16,17 +34,11 @@ public class DeobfNames { /** Obfuscated signature of RenderBlocks.renderBlockByRenderType() */ public static final String RB_RBBRT_SIG_OBF = "(Lahu;III)Z"; - /** MCP signature of BlockRenderTypeOverride.getRenderType(Block) */ - public static final String BRTO_GRT_SIG_MCP = "(Lnet/minecraft/block/Block;)I"; + /** MCP signature of BetterFoliageClient.getRenderTypeOverride() */ + public static final String BFC_GRTO_SIG_MCP = "(Lnet/minecraft/world/IBlockAccess;IIILnet/minecraft/block/Block;I)I"; - /** Obfuscated signature of BlockRenderTypeOverride.getRenderType(Block) */ - public static final String BRTO_GRT_SIG_OBF = "(Lahu;)I"; - - /** MCP signature of BlockRenderTypeOverride.getRenderType(Block) */ - public static final String BRTO_GRTO_SIG_MCP = "(ILnet/minecraft/block/Block;)I"; - - /** Obfuscated signature of BlockRenderTypeOverride.getRenderType(Block) */ - public static final String BRTO_GRTO_SIG_OBF = "(ILahu;)I"; + /** Obfuscated signature of BetterFoliageClient.getRenderTypeOverride() */ + public static final String BFC_GRTO_SIG_OBF = "(Lafx;IIILahu;I)I"; /** MCP name of SimpleReloadableResourceManager.domainResourceManagers */ public static final String SRRM_DRM_MCP = "domainResourceManagers"; diff --git a/src/main/java/mods/betterfoliage/common/util/Double3.java b/src/main/java/mods/betterfoliage/common/util/Double3.java index 747ed25..7e0340a 100644 --- a/src/main/java/mods/betterfoliage/common/util/Double3.java +++ b/src/main/java/mods/betterfoliage/common/util/Double3.java @@ -1,5 +1,7 @@ package mods.betterfoliage.common.util; +import net.minecraftforge.common.util.ForgeDirection; + public class Double3 { public final double x; @@ -12,10 +14,20 @@ public class Double3 { this.z = z; } + public Double3(ForgeDirection dir) { + this.x = dir.offsetX; + this.y = dir.offsetY; + this.z = dir.offsetZ; + } + public Double3 add(Double3 other) { return new Double3(x + other.x, y + other.y, z + other.z); } + public Double3 add(double x, double y, double z) { + return new Double3(this.x + x, this.y + y, this.z + z); + } + public Double3 scaleAxes(double sx, double sy, double sz) { return new Double3(x * sx, y * sy, z * sz); } diff --git a/src/main/java/mods/betterfoliage/loader/BetterFoliageTransformer.java b/src/main/java/mods/betterfoliage/loader/BetterFoliageTransformer.java index c1d2a81..fb811e6 100644 --- a/src/main/java/mods/betterfoliage/loader/BetterFoliageTransformer.java +++ b/src/main/java/mods/betterfoliage/loader/BetterFoliageTransformer.java @@ -4,6 +4,7 @@ import mods.betterfoliage.common.util.DeobfNames; import org.objectweb.asm.Opcodes; import org.objectweb.asm.tree.AbstractInsnNode; +import org.objectweb.asm.tree.FieldInsnNode; import org.objectweb.asm.tree.MethodInsnNode; import org.objectweb.asm.tree.MethodNode; import org.objectweb.asm.tree.VarInsnNode; @@ -18,9 +19,16 @@ public class BetterFoliageTransformer extends EZTransformerBase { AbstractInsnNode invokeGetRenderType = findNext(method.instructions.getFirst(), matchInvokeAny()); AbstractInsnNode storeRenderType = findNext(invokeGetRenderType, matchOpcode(Opcodes.ISTORE)); insertAfter(method.instructions, storeRenderType, - new VarInsnNode(Opcodes.ILOAD, 5), + new VarInsnNode(Opcodes.ALOAD, 0), + obf ? new FieldInsnNode(Opcodes.GETFIELD, DeobfNames.RB_NAME_OBF, DeobfNames.RB_BA_NAME_OBF, DeobfNames.RB_BA_SIG_OBF) : + new FieldInsnNode(Opcodes.GETFIELD, DeobfNames.RB_NAME_MCP, DeobfNames.RB_BA_NAME_MCP, DeobfNames.RB_BA_SIG_MCP), + new VarInsnNode(Opcodes.ILOAD, 2), + new VarInsnNode(Opcodes.ILOAD, 3), + new VarInsnNode(Opcodes.ILOAD, 4), new VarInsnNode(Opcodes.ALOAD, 1), - new MethodInsnNode(Opcodes.INVOKESTATIC, "mods/betterfoliage/BlockRenderTypeOverride", "getRenderTypeOverride", obf ? DeobfNames.BRTO_GRTO_SIG_OBF : DeobfNames.BRTO_GRTO_SIG_MCP), + new VarInsnNode(Opcodes.ILOAD, 5), + obf ? new MethodInsnNode(Opcodes.INVOKESTATIC, "mods/betterfoliage/client/BetterFoliageClient", "getRenderTypeOverride", DeobfNames.BFC_GRTO_SIG_OBF) : + new MethodInsnNode(Opcodes.INVOKESTATIC, "mods/betterfoliage/client/BetterFoliageClient", "getRenderTypeOverride", DeobfNames.BFC_GRTO_SIG_MCP), new VarInsnNode(Opcodes.ISTORE, 5) ); } diff --git a/src/main/resources/assets/betterfoliage/lang/en_US.lang b/src/main/resources/assets/betterfoliage/lang/en_US.lang index 4c1e8ec..1570679 100644 --- a/src/main/resources/assets/betterfoliage/lang/en_US.lang +++ b/src/main/resources/assets/betterfoliage/lang/en_US.lang @@ -6,8 +6,15 @@ message.betterfoliage.optionOff=OFF message.betterfoliage.close=Close message.betterfoliage.betterLeaves=Better Leaves: %s message.betterfoliage.betterGrass=Better Grass: %s +message.betterfoliage.betterCactus=Better Cactus: %s +message.betterfoliage.betterLilypad=Better Lilypad: %s + message.betterfoliage.size=Size message.betterfoliage.hOffset=H.Offset message.betterfoliage.vOffset=V.Offset message.betterfoliage.minHeight=Min.Height -message.betterfoliage.maxHeight=Max.Height \ No newline at end of file +message.betterfoliage.maxHeight=Max.Height +message.betterfoliage.flowerChance=Flower Chance +message.betterfoliage.leavesMode=Leaves Offset: %s +message.betterfoliage.leavesSkew=Skew +message.betterfoliage.leavesTranslate=Translate \ No newline at end of file diff --git a/src/main/resources/assets/betterfoliage/textures/blocks/grass_0.png b/src/main/resources/assets/betterfoliage/textures/blocks/grass_0.png deleted file mode 100644 index 0d42360..0000000 Binary files a/src/main/resources/assets/betterfoliage/textures/blocks/grass_0.png and /dev/null differ diff --git a/src/main/resources/assets/betterfoliage/textures/blocks/grass_1.png b/src/main/resources/assets/betterfoliage/textures/blocks/grass_1.png deleted file mode 100644 index 7a2214a..0000000 Binary files a/src/main/resources/assets/betterfoliage/textures/blocks/grass_1.png and /dev/null differ