Major refactoring
Added cactus and lilypads
This commit is contained in:
@@ -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)
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
@@ -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<Integer, IRenderBlockDecorator> decorators = Maps.newHashMap();
|
||||
public static Set<Class<?>> 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<Integer, IRenderBlockDecorator> 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) {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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<OptionDoubleWidget> widgets = Lists.newLinkedList();
|
||||
protected List<IOptionWidget> 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<GuiButton>) buttonList) {
|
||||
if (button.id == enumButton.ordinal()) {
|
||||
button.displayString = I18n.format(msgKey, I18n.format(optionKey));
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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<GuiButton> 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);
|
||||
|
||||
}
|
||||
@@ -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();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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<GuiButton> 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();
|
||||
}
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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);
|
||||
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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));
|
||||
}
|
||||
}
|
||||
@@ -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));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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));
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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<String, IResourceManager> domainManagers = ReflectionUtil.getDomainResourceManagers();
|
||||
if (domainManagers == null) return;
|
||||
domainManagers.remove(domainName);
|
||||
}
|
||||
}
|
||||
|
||||
public void loadLeafMappings(File leafMaskFile) {
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
@@ -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";
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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)
|
||||
);
|
||||
}
|
||||
|
||||
@@ -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
|
||||
message.betterfoliage.maxHeight=Max.Height
|
||||
message.betterfoliage.flowerChance=Flower Chance
|
||||
message.betterfoliage.leavesMode=Leaves Offset: %s
|
||||
message.betterfoliage.leavesSkew=Skew
|
||||
message.betterfoliage.leavesTranslate=Translate
|
||||
Binary file not shown.
|
Before Width: | Height: | Size: 204 B |
Binary file not shown.
|
Before Width: | Height: | Size: 285 B |
Reference in New Issue
Block a user