3 Commits

Author SHA1 Message Date
octarine-noise
53fdd321aa Merge branch 'master' into 1.7.10 2014-07-12 00:20:58 +02:00
octarine-noise
e47391c62a Merge branch 'master' into 1.7.10 2014-07-06 21:14:46 +02:00
octarine-noise
4521454228 port to 1.7.10 2014-07-01 02:16:46 +02:00
33 changed files with 395 additions and 798 deletions

View File

@@ -6,4 +6,6 @@ More info: http://www.minecraftforum.net/topic/2776217-better-foliage/
Download Download
======== ========
[BetterFoliage 0.9.7-beta] (http://goo.gl/xNVloR) (MC 1.7.2 & 1.7.10) [BetterFoliage 0.9.4-beta] (http://goo.gl/pNBE23) (MC 1.7.2)
[BetterFoliage 0.9.4-beta] (http://goo.gl/ywT6Xg) (MC 1.7.10)

View File

@@ -17,12 +17,12 @@ buildscript {
apply plugin: 'forge' apply plugin: 'forge'
minecraft { minecraft {
version = '1.7.2-10.12.2.1147' version = '1.7.10-10.13.0.1159'
} }
jar.baseName = 'BetterFoliage' jar.baseName = 'BetterFoliage-1.7.10'
group = 'com.github.octarine-noise' group = 'com.github.octarine-noise'
version='0.9.8b' version='0.9.5b'
processResources { processResources {
inputs.property "version", project.version inputs.property "version", project.version

View File

@@ -18,7 +18,7 @@ public class BetterFoliage {
public static final String MOD_ID = "BetterFoliage"; public static final String MOD_ID = "BetterFoliage";
public static final String MOD_NAME = "Better Foliage"; public static final String MOD_NAME = "Better Foliage";
public static final String MC_VERSIONS = "[1.7.2,1.7.10]"; public static final String MC_VERSIONS = "[1.7.10]";
public static final String GUI_FACTORY = "mods.betterfoliage.client.gui.ConfigGuiFactory"; public static final String GUI_FACTORY = "mods.betterfoliage.client.gui.ConfigGuiFactory";
@Mod.Instance @Mod.Instance

View File

@@ -8,18 +8,25 @@ import mods.betterfoliage.BetterFoliage;
import mods.betterfoliage.client.render.IRenderBlockDecorator; import mods.betterfoliage.client.render.IRenderBlockDecorator;
import mods.betterfoliage.client.render.impl.RenderBlockBetterAlgae; import mods.betterfoliage.client.render.impl.RenderBlockBetterAlgae;
import mods.betterfoliage.client.render.impl.RenderBlockBetterCactus; import mods.betterfoliage.client.render.impl.RenderBlockBetterCactus;
import mods.betterfoliage.client.render.impl.RenderBlockBetterCoral;
import mods.betterfoliage.client.render.impl.RenderBlockBetterGrass; import mods.betterfoliage.client.render.impl.RenderBlockBetterGrass;
import mods.betterfoliage.client.render.impl.RenderBlockBetterLeaves; import mods.betterfoliage.client.render.impl.RenderBlockBetterLeaves;
import mods.betterfoliage.client.render.impl.RenderBlockBetterLilypad; import mods.betterfoliage.client.render.impl.RenderBlockBetterLilypad;
import mods.betterfoliage.client.render.impl.RenderBlockBetterReed; import mods.betterfoliage.client.render.impl.RenderBlockBetterReed;
import mods.betterfoliage.client.resource.BlockTextureGenerator; import mods.betterfoliage.client.resource.BlockTextureGenerator;
import mods.betterfoliage.client.resource.HalfTextureResource; import mods.betterfoliage.client.resource.HalfTextureResource;
import mods.betterfoliage.client.resource.ILeafTextureRecognizer;
import mods.betterfoliage.client.resource.LeafTextureGenerator; import mods.betterfoliage.client.resource.LeafTextureGenerator;
import mods.betterfoliage.client.resource.ShortGrassTextureResource;
import net.minecraft.block.Block; import net.minecraft.block.Block;
import net.minecraft.block.BlockCarrot;
import net.minecraft.block.BlockCrops;
import net.minecraft.block.BlockDoublePlant;
import net.minecraft.block.BlockLeavesBase;
import net.minecraft.block.BlockPotato;
import net.minecraft.block.BlockReed;
import net.minecraft.block.BlockTallGrass;
import net.minecraft.client.renderer.texture.TextureAtlasSprite; import net.minecraft.client.renderer.texture.TextureAtlasSprite;
import net.minecraft.client.resources.IResource; import net.minecraft.client.resources.IResource;
import net.minecraft.init.Blocks;
import net.minecraft.util.ResourceLocation; import net.minecraft.util.ResourceLocation;
import net.minecraft.world.IBlockAccess; import net.minecraft.world.IBlockAccess;
import net.minecraftforge.common.MinecraftForge; import net.minecraftforge.common.MinecraftForge;
@@ -29,13 +36,13 @@ import com.google.common.collect.Maps;
import cpw.mods.fml.client.registry.RenderingRegistry; import cpw.mods.fml.client.registry.RenderingRegistry;
import cpw.mods.fml.common.FMLCommonHandler; import cpw.mods.fml.common.FMLCommonHandler;
public class BetterFoliageClient { public class BetterFoliageClient implements ILeafTextureRecognizer {
public static Map<Integer, IRenderBlockDecorator> decorators = Maps.newHashMap(); public static Map<Integer, IRenderBlockDecorator> decorators = Maps.newHashMap();
public static LeafTextureGenerator leafGenerator; public static LeafTextureGenerator leafGenerator;
public static BlockMatcher leaves = new BlockMatcher(); public static BlockMatcher leaves;
public static BlockMatcher crops = new BlockMatcher(); public static BlockMatcher crops;
public static void preInit() { public static void preInit() {
FMLCommonHandler.instance().bus().register(new KeyHandler()); FMLCommonHandler.instance().bus().register(new KeyHandler());
@@ -47,17 +54,27 @@ public class BetterFoliageClient {
registerRenderer(new RenderBlockBetterLilypad()); registerRenderer(new RenderBlockBetterLilypad());
registerRenderer(new RenderBlockBetterReed()); registerRenderer(new RenderBlockBetterReed());
registerRenderer(new RenderBlockBetterAlgae()); registerRenderer(new RenderBlockBetterAlgae());
registerRenderer(new RenderBlockBetterCoral());
leaves.load(new File(BetterFoliage.configDir, "classesLeaves.cfg"), new ResourceLocation("betterfoliage:classesLeavesDefault.cfg")); leaves = new BlockMatcher(BlockLeavesBase.class.getName(),
MinecraftForge.EVENT_BUS.register(leaves); "forestry.arboriculture.gadgets.BlockLeaves",
"thaumcraft.common.blocks.BlockMagicalLeaves");
leaves.load(new File(BetterFoliage.configDir, "classesLeaves.cfg"));
crops.load(new File(BetterFoliage.configDir, "classesCrops.cfg"), new ResourceLocation("betterfoliage:classesCropsDefault.cfg")); crops = new BlockMatcher(BlockCrops.class.getName(),
MinecraftForge.EVENT_BUS.register(crops); "-" + BlockCarrot.class.getName(),
"-" + BlockPotato.class.getName(),
BlockTallGrass.class.getName(),
BlockDoublePlant.class.getName(),
BlockReed.class.getName(),
"biomesoplenty.common.blocks.BlockBOPFlower",
"biomesoplenty.common.blocks.BlockBOPFlower2",
"tconstruct.blocks.slime.SlimeTallGrass");
crops.load(new File(BetterFoliage.configDir, "classesCrops.cfg"));
BetterFoliage.log.info("Registering leaf texture generator"); BetterFoliage.log.info("Registering leaf texture generator");
leafGenerator = new LeafTextureGenerator(); leafGenerator = new LeafTextureGenerator();
MinecraftForge.EVENT_BUS.register(leafGenerator); MinecraftForge.EVENT_BUS.register(leafGenerator);
leafGenerator.recognizers.add(new BetterFoliageClient());
MinecraftForge.EVENT_BUS.register(new BlockTextureGenerator("bf_reed_bottom", new ResourceLocation("betterfoliage", "textures/blocks/missing_leaf.png")) { MinecraftForge.EVENT_BUS.register(new BlockTextureGenerator("bf_reed_bottom", new ResourceLocation("betterfoliage", "textures/blocks/missing_leaf.png")) {
@Override @Override
@@ -71,25 +88,11 @@ public class BetterFoliageClient {
return new HalfTextureResource(unwrapResource(var1), false, getMissingResource()); return new HalfTextureResource(unwrapResource(var1), false, getMissingResource());
} }
}); });
MinecraftForge.EVENT_BUS.register(new BlockTextureGenerator("bf_shortgrass", new ResourceLocation("betterfoliage", "textures/blocks/missing_leaf.png")) {
@Override
public IResource getResource(ResourceLocation var1) throws IOException {
return new ShortGrassTextureResource(unwrapResource(var1), false, getMissingResource());
}
});
MinecraftForge.EVENT_BUS.register(new BlockTextureGenerator("bf_shortgrass_snow", new ResourceLocation("betterfoliage", "textures/blocks/missing_leaf.png")) {
@Override
public IResource getResource(ResourceLocation var1) throws IOException {
return new ShortGrassTextureResource(unwrapResource(var1), true, getMissingResource());
}
});
MinecraftForge.EVENT_BUS.register(new BetterFoliageClient()); MinecraftForge.EVENT_BUS.register(new BetterFoliageClient());
ShadersModIntegration.init();
} }
public static boolean isLeafTexture(TextureAtlasSprite icon) { public boolean isLeafTexture(TextureAtlasSprite icon) {
String resourceLocation = icon.getIconName(); String resourceLocation = icon.getIconName();
if (resourceLocation.startsWith("forestry:leaves/")) return true; if (resourceLocation.startsWith("forestry:leaves/")) return true;
return false; return false;
@@ -106,6 +109,14 @@ public class BetterFoliageClient {
return original; return original;
} }
public static int getGLSLBlockIdOverride(int original, Block block) {
if (leaves.matchesID(original & 0xFFFF))
return Block.blockRegistry.getIDForObject(Blocks.leaves) & 0xFFFF | block.getRenderType() << 16;
if (crops.matchesID(original & 0xFFFF))
return Block.blockRegistry.getIDForObject(Blocks.tallgrass) & 0xFFFF | block.getRenderType() << 16;
return original;
}
public static void registerRenderer(IRenderBlockDecorator decorator) { public static void registerRenderer(IRenderBlockDecorator decorator) {
int renderId = RenderingRegistry.getNextAvailableRenderId(); int renderId = RenderingRegistry.getNextAvailableRenderId();
decorators.put(renderId, decorator); decorators.put(renderId, decorator);

View File

@@ -2,15 +2,16 @@ package mods.betterfoliage.client;
import java.io.BufferedReader; import java.io.BufferedReader;
import java.io.File; import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileReader; import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.util.Iterator; import java.util.Iterator;
import java.util.Set; import java.util.Set;
import mods.betterfoliage.BetterFoliage; import mods.betterfoliage.BetterFoliage;
import mods.betterfoliage.common.util.Utils;
import net.minecraft.block.Block; import net.minecraft.block.Block;
import net.minecraft.client.multiplayer.WorldClient; import net.minecraftforge.common.MinecraftForge;
import net.minecraft.util.ResourceLocation;
import net.minecraftforge.event.world.WorldEvent; import net.minecraftforge.event.world.WorldEvent;
import com.google.common.collect.Sets; import com.google.common.collect.Sets;
@@ -19,22 +20,35 @@ import cpw.mods.fml.common.eventhandler.SubscribeEvent;
public class BlockMatcher { public class BlockMatcher {
public Set<Class<?>> whiteList = Sets.newHashSet(); public Set<String> whiteList = Sets.newHashSet();
public Set<Class<?>> blackList = Sets.newHashSet(); public Set<String> blackList = Sets.newHashSet();
public Set<Integer> blockIDs = Sets.newHashSet(); public Set<Integer> blockIDs = Sets.newHashSet();
public BlockMatcher(String... defaults) {
for (String clazz : defaults) addClass(clazz);
MinecraftForge.EVENT_BUS.register(this);
}
public void addClass(String className) { public void addClass(String className) {
try { if (className.startsWith("-"))
if (className.startsWith("-")) blackList.add(className.substring(1));
blackList.add(Class.forName(className.substring(1))); else
else whiteList.add(className);
whiteList.add(Class.forName(className));
} catch(ClassNotFoundException e) {}
} }
public boolean matchesClass(Block block) { public boolean matchesClass(Block block) {
for (Class<?> clazz : blackList) if (clazz.isAssignableFrom(block.getClass())) return false; for (String className : blackList) {
for (Class<?> clazz : whiteList) if (clazz.isAssignableFrom(block.getClass())) return true; try {
Class<?> clazz = Class.forName(className);
if (clazz.isAssignableFrom(block.getClass())) return false;
} catch(ClassNotFoundException e) {}
}
for (String className : whiteList) {
try {
Class<?> clazz = Class.forName(className);
if (clazz.isAssignableFrom(block.getClass())) return true;
} catch(ClassNotFoundException e) {}
}
return false; return false;
} }
@@ -46,9 +60,7 @@ public class BlockMatcher {
return blockIDs.contains(Block.blockRegistry.getIDForObject(block)); return blockIDs.contains(Block.blockRegistry.getIDForObject(block));
} }
public void load(File file, ResourceLocation defaults) { public void load(File file) {
if (!file.exists()) Utils.copyFromTextResource(defaults, file);
BufferedReader reader = null; BufferedReader reader = null;
try { try {
reader = new BufferedReader(new FileReader(file)); reader = new BufferedReader(new FileReader(file));
@@ -60,19 +72,40 @@ public class BlockMatcher {
line = reader.readLine(); line = reader.readLine();
} }
reader.close(); reader.close();
} catch (Exception e) { } catch (FileNotFoundException e) {
saveDefaults(file);
} catch (IOException e) {
BetterFoliage.log.warn(String.format("Error reading configuration: %s", file.getName())); BetterFoliage.log.warn(String.format("Error reading configuration: %s", file.getName()));
} }
} }
public void saveDefaults(File file) {
FileWriter writer = null;
try {
writer = new FileWriter(file);
for (String className : whiteList) {
writer.write(className);
writer.write("\n");
}
for (String className : blackList) {
writer.write("-");
writer.write(className);
writer.write("\n");
}
writer.close();
} catch (FileNotFoundException e) {
saveDefaults(file);
} catch (IOException e) {
BetterFoliage.log.warn(String.format("Error writing default configuration: %s", file.getName()));
}
}
/** Caches block IDs on world load for fast lookup /** Caches block IDs on world load for fast lookup
* @param event * @param event
*/ */
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
@SubscribeEvent @SubscribeEvent
public void handleWorldLoad(WorldEvent.Load event) { public void handleWorldLoad(WorldEvent.Load event) {
if (!(event.world instanceof WorldClient)) return;
blockIDs.clear(); blockIDs.clear();
Iterator<Block> iter = Block.blockRegistry.iterator(); Iterator<Block> iter = Block.blockRegistry.iterator();
while (iter.hasNext()) { while (iter.hasNext()) {

View File

@@ -1,55 +0,0 @@
package mods.betterfoliage.client;
import java.lang.reflect.Field;
import net.minecraft.block.Block;
import net.minecraft.init.Blocks;
public class ShadersModIntegration {
private static boolean hasShadersMod = false;
private static int tallGrassEntityData;
private static int leavesEntityData;
private static Field shadersEntityData;
private static Field shadersEntityDataIndex;
private ShadersModIntegration() {}
public static void init() {
tallGrassEntityData = Block.blockRegistry.getIDForObject(Blocks.tallgrass) & 0xFFFF | Blocks.tallgrass.getRenderType() << 16;
leavesEntityData = Block.blockRegistry.getIDForObject(Blocks.leaves) & 0xFFFF | Blocks.leaves.getRenderType() << 16;
try {
Class<?> classShaders = Class.forName("shadersmodcore.client.Shaders");
shadersEntityData = classShaders.getDeclaredField("entityData");
shadersEntityDataIndex = classShaders.getDeclaredField("entityDataIndex");
hasShadersMod = true;
} catch(Exception e) {
}
}
public static void startGrassQuads() {
if (!hasShadersMod) return;
setShadersEntityData(tallGrassEntityData);
}
public static void startLeavesQuads() {
if (!hasShadersMod) return;
setShadersEntityData(leavesEntityData);
}
private static void setShadersEntityData(int data) {
try {
int[] entityData = (int[]) shadersEntityData.get(null);
int entityDataIndex = shadersEntityDataIndex.getInt(null);
entityData[(entityDataIndex * 2)] = data;
} catch (Exception e) {
}
}
public static int getBlockIdOverride(int original, Block block) {
if (BetterFoliageClient.leaves.matchesID(original & 0xFFFF)) return leavesEntityData;
if (BetterFoliageClient.crops.matchesID(original & 0xFFFF)) return tallGrassEntityData;
return original;
}
}

View File

@@ -1,34 +0,0 @@
package mods.betterfoliage.client.gui;
import cpw.mods.fml.client.FMLClientHandler;
import mods.betterfoliage.BetterFoliage;
import mods.betterfoliage.client.gui.widget.OptionDoubleWidget;
import mods.betterfoliage.client.gui.widget.OptionIntegerWidget;
import net.minecraft.client.gui.GuiButton;
import net.minecraft.client.gui.GuiScreen;
import net.minecraft.client.resources.I18n;
public class ConfigGuiCoral extends ConfigGuiScreenBase {
public ConfigGuiCoral(GuiScreen parent) {
super(parent);
int id = 10;
widgets.add(new OptionDoubleWidget(BetterFoliage.config.coralCrustSize, -100, -100, 200, 50, id++, id++, "message.betterfoliage.crustSize", "%.2f"));
widgets.add(new OptionDoubleWidget(BetterFoliage.config.coralVOffset, -100, -70, 200, 50, id++, id++, "message.betterfoliage.vOffset", "%.3f"));
widgets.add(new OptionDoubleWidget(BetterFoliage.config.coralSize, -100, -40, 200, 50, id++, id++, "message.betterfoliage.size", "%.2f"));
widgets.add(new OptionDoubleWidget(BetterFoliage.config.coralHOffset, -100, -10, 200, 50, id++, id++, "message.betterfoliage.hOffset", "%.3f"));
widgets.add(new OptionIntegerWidget(BetterFoliage.config.coralPopulation, -100, 20, 200, 50, id++, id++, "message.betterfoliage.coralPopulation"));
widgets.add(new OptionIntegerWidget(BetterFoliage.config.coralChance, -100, 50, 200, 50, id++, id++, "message.betterfoliage.coralChance"));
}
@SuppressWarnings("unchecked")
@Override
public void addButtons(int x, int y) {
buttonList.add(new GuiButton(0, x - 50, y + 80, 100, 20, I18n.format("message.betterfoliage.back")));
}
@Override
protected void onButtonPress(int id) {
if (id == 0) FMLClientHandler.instance().showGuiScreen(parent);
}
}

View File

@@ -9,32 +9,24 @@ import cpw.mods.fml.client.FMLClientHandler;
public class ConfigGuiGrass extends ConfigGuiScreenBase { public class ConfigGuiGrass extends ConfigGuiScreenBase {
public enum Button {CLOSE, GRASS_USE_GENERATED}
public ConfigGuiGrass(GuiScreen parent) { public ConfigGuiGrass(GuiScreen parent) {
super(parent); super(parent);
int id = 10; int id = 10;
widgets.add(new OptionDoubleWidget(BetterFoliage.config.grassSize, -100, -70, 200, 50, id++, id++, "message.betterfoliage.size", "%.2f")); widgets.add(new OptionDoubleWidget(BetterFoliage.config.grassSize, -100, -70, 200, 50, id++, id++, "message.betterfoliage.size", "%.2f"));
widgets.add(new OptionDoubleWidget(BetterFoliage.config.grassHOffset, -100, -10, 200, 50, id++, id++, "message.betterfoliage.hOffset", "%.3f")); widgets.add(new OptionDoubleWidget(BetterFoliage.config.grassHOffset, -100, -40, 200, 50, id++, id++, "message.betterfoliage.hOffset", "%.3f"));
widgets.add(new OptionDoubleWidget(BetterFoliage.config.grassHeightMin, -100, 20, 200, 50, id++, id++, "message.betterfoliage.minHeight", "%.2f")); widgets.add(new OptionDoubleWidget(BetterFoliage.config.grassHeightMin, -100, -10, 200, 50, id++, id++, "message.betterfoliage.minHeight", "%.2f"));
widgets.add(new OptionDoubleWidget(BetterFoliage.config.grassHeightMax, -100, 50, 200, 50, id++, id++, "message.betterfoliage.maxHeight", "%.2f")); widgets.add(new OptionDoubleWidget(BetterFoliage.config.grassHeightMax, -100, 20, 200, 50, id++, id++, "message.betterfoliage.maxHeight", "%.2f"));
} }
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
@Override @Override
public void addButtons(int x, int y) { public void addButtons(int x, int y) {
buttonList.add(new GuiButton(Button.CLOSE.ordinal(), x - 50, y + 80, 100, 20, I18n.format("message.betterfoliage.back"))); buttonList.add(new GuiButton(0, x - 50, y + 50, 100, 20, I18n.format("message.betterfoliage.back")));
buttonList.add(new GuiButton(Button.GRASS_USE_GENERATED.ordinal(), x - 100, y - 40, 200, 20, ""));
} }
protected void updateButtons() {
setButtonOptionBoolean(Button.GRASS_USE_GENERATED.ordinal(), "message.betterfoliage.genShortgrass", BetterFoliage.config.grassUseGenerated);
}
@Override @Override
protected void onButtonPress(int id) { protected void onButtonPress(int id) {
if (id == Button.CLOSE.ordinal()) FMLClientHandler.instance().showGuiScreen(parent); if (id == 0) FMLClientHandler.instance().showGuiScreen(parent);
if (id == Button.GRASS_USE_GENERATED.ordinal()) BetterFoliage.config.grassUseGenerated = !BetterFoliage.config.grassUseGenerated;
if (BetterFoliage.config.grassHeightMin.value > BetterFoliage.config.grassHeightMax.value) BetterFoliage.config.grassHeightMin.value = BetterFoliage.config.grassHeightMax.value; if (BetterFoliage.config.grassHeightMin.value > BetterFoliage.config.grassHeightMax.value) BetterFoliage.config.grassHeightMin.value = BetterFoliage.config.grassHeightMax.value;
} }

View File

@@ -18,8 +18,7 @@ public class ConfigGuiMain extends ConfigGuiScreenBase {
TOGGLE_CACTUS, CONFIG_CACTUS, TOGGLE_CACTUS, CONFIG_CACTUS,
TOGGLE_LILYPAD, CONFIG_LILYPAD, TOGGLE_LILYPAD, CONFIG_LILYPAD,
TOGGLE_REED, CONFIG_REED, TOGGLE_REED, CONFIG_REED,
TOGGLE_ALGAE, CONFIG_ALGAE, TOGGLE_ALGAE, CONFIG_ALGAE}
TOGGLE_CORAL, CONFIG_CORAL}
public ConfigGuiMain(GuiScreen parent) { public ConfigGuiMain(GuiScreen parent) {
super(parent); super(parent);
@@ -29,7 +28,7 @@ public class ConfigGuiMain extends ConfigGuiScreenBase {
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
@Override @Override
protected void addButtons(int x, int y) { protected void addButtons(int x, int y) {
buttonList.add(new GuiButton(Button.CLOSE.ordinal(), x - 50, y + 110, 100, 20, I18n.format("message.betterfoliage.close"))); buttonList.add(new GuiButton(Button.CLOSE.ordinal(), x - 50, y + 80, 100, 20, I18n.format("message.betterfoliage.close")));
buttonList.add(new GuiButton(Button.TOGGLE_LEAVES.ordinal(), x - 100, y - 100, 150, 20, "")); buttonList.add(new GuiButton(Button.TOGGLE_LEAVES.ordinal(), x - 100, y - 100, 150, 20, ""));
buttonList.add(new GuiButton(Button.CONFIG_LEAVES.ordinal(), x + 60, y - 100, 40, 20, I18n.format("message.betterfoliage.config"))); buttonList.add(new GuiButton(Button.CONFIG_LEAVES.ordinal(), x + 60, y - 100, 40, 20, I18n.format("message.betterfoliage.config")));
@@ -48,9 +47,6 @@ public class ConfigGuiMain extends ConfigGuiScreenBase {
buttonList.add(new GuiButton(Button.TOGGLE_ALGAE.ordinal(), x - 100, y + 50, 150, 20, "")); buttonList.add(new GuiButton(Button.TOGGLE_ALGAE.ordinal(), x - 100, y + 50, 150, 20, ""));
buttonList.add(new GuiButton(Button.CONFIG_ALGAE.ordinal(), x + 60, y + 50, 40, 20, I18n.format("message.betterfoliage.config"))); buttonList.add(new GuiButton(Button.CONFIG_ALGAE.ordinal(), x + 60, y + 50, 40, 20, I18n.format("message.betterfoliage.config")));
buttonList.add(new GuiButton(Button.TOGGLE_CORAL.ordinal(), x - 100, y + 80, 150, 20, ""));
buttonList.add(new GuiButton(Button.CONFIG_CORAL.ordinal(), x + 60, y + 80, 40, 20, I18n.format("message.betterfoliage.config")));
} }
protected void updateButtons() { protected void updateButtons() {
@@ -60,7 +56,6 @@ public class ConfigGuiMain extends ConfigGuiScreenBase {
setButtonOptionBoolean(Button.TOGGLE_LILYPAD.ordinal(), "message.betterfoliage.betterLilypad", BetterFoliage.config.lilypadEnabled); setButtonOptionBoolean(Button.TOGGLE_LILYPAD.ordinal(), "message.betterfoliage.betterLilypad", BetterFoliage.config.lilypadEnabled);
setButtonOptionBoolean(Button.TOGGLE_REED.ordinal(), "message.betterfoliage.betterReed", BetterFoliage.config.reedEnabled); setButtonOptionBoolean(Button.TOGGLE_REED.ordinal(), "message.betterfoliage.betterReed", BetterFoliage.config.reedEnabled);
setButtonOptionBoolean(Button.TOGGLE_ALGAE.ordinal(), "message.betterfoliage.betterAlgae", BetterFoliage.config.algaeEnabled); setButtonOptionBoolean(Button.TOGGLE_ALGAE.ordinal(), "message.betterfoliage.betterAlgae", BetterFoliage.config.algaeEnabled);
setButtonOptionBoolean(Button.TOGGLE_CORAL.ordinal(), "message.betterfoliage.betterCoral", BetterFoliage.config.coralEnabled);
((GuiButton) buttonList.get(Button.CONFIG_CACTUS.ordinal())).enabled = false; ((GuiButton) buttonList.get(Button.CONFIG_CACTUS.ordinal())).enabled = false;
} }
@@ -77,14 +72,12 @@ public class ConfigGuiMain extends ConfigGuiScreenBase {
if (id == Button.TOGGLE_LILYPAD.ordinal()) BetterFoliage.config.lilypadEnabled = !BetterFoliage.config.lilypadEnabled; if (id == Button.TOGGLE_LILYPAD.ordinal()) BetterFoliage.config.lilypadEnabled = !BetterFoliage.config.lilypadEnabled;
if (id == Button.TOGGLE_REED.ordinal()) BetterFoliage.config.reedEnabled = !BetterFoliage.config.reedEnabled; if (id == Button.TOGGLE_REED.ordinal()) BetterFoliage.config.reedEnabled = !BetterFoliage.config.reedEnabled;
if (id == Button.TOGGLE_ALGAE.ordinal()) BetterFoliage.config.algaeEnabled = !BetterFoliage.config.algaeEnabled; if (id == Button.TOGGLE_ALGAE.ordinal()) BetterFoliage.config.algaeEnabled = !BetterFoliage.config.algaeEnabled;
if (id == Button.TOGGLE_CORAL.ordinal()) BetterFoliage.config.coralEnabled = !BetterFoliage.config.coralEnabled;
if (id== Button.CONFIG_LEAVES.ordinal()) FMLClientHandler.instance().showGuiScreen(new ConfigGuiLeaves(this)); if (id== Button.CONFIG_LEAVES.ordinal()) FMLClientHandler.instance().showGuiScreen(new ConfigGuiLeaves(this));
if (id== Button.CONFIG_GRASS.ordinal()) FMLClientHandler.instance().showGuiScreen(new ConfigGuiGrass(this)); if (id== Button.CONFIG_GRASS.ordinal()) FMLClientHandler.instance().showGuiScreen(new ConfigGuiGrass(this));
if (id== Button.CONFIG_LILYPAD.ordinal()) FMLClientHandler.instance().showGuiScreen(new ConfigGuiLilypad(this)); if (id== Button.CONFIG_LILYPAD.ordinal()) FMLClientHandler.instance().showGuiScreen(new ConfigGuiLilypad(this));
if (id== Button.CONFIG_REED.ordinal()) FMLClientHandler.instance().showGuiScreen(new ConfigGuiReed(this)); if (id== Button.CONFIG_REED.ordinal()) FMLClientHandler.instance().showGuiScreen(new ConfigGuiReed(this));
if (id== Button.CONFIG_ALGAE.ordinal()) FMLClientHandler.instance().showGuiScreen(new ConfigGuiAlgae(this)); if (id== Button.CONFIG_ALGAE.ordinal()) FMLClientHandler.instance().showGuiScreen(new ConfigGuiAlgae(this));
if (id== Button.CONFIG_CORAL.ordinal()) FMLClientHandler.instance().showGuiScreen(new ConfigGuiCoral(this));
} }
} }

View File

@@ -37,9 +37,6 @@ public class RenderBlockAOBase extends RenderBlocks {
public float red; public float red;
public float green; public float green;
public float blue; public float blue;
public void setGray(float value) {
red = value; green = value; blue = value;
}
} }
protected double[] uValues = new double[] {0.0, 16.0, 16.0, 0.0}; protected double[] uValues = new double[] {0.0, 16.0, 16.0, 0.0};

View File

@@ -43,7 +43,7 @@ public class RenderBlockBetterAlgae extends RenderBlockAOBase implements IRender
// store world for later use // store world for later use
blockAccess = world; blockAccess = world;
// render dirt block // render grass block
setPassCounters(1); setPassCounters(1);
setRenderBoundsFromBlock(block); setRenderBoundsFromBlock(block);
renderStandardBlock(block, x, y, z); renderStandardBlock(block, x, y, z);

View File

@@ -1,98 +0,0 @@
package mods.betterfoliage.client.render.impl;
import java.util.Random;
import mods.betterfoliage.BetterFoliage;
import mods.betterfoliage.client.render.IRenderBlockDecorator;
import mods.betterfoliage.client.render.IconSet;
import mods.betterfoliage.client.render.RenderBlockAOBase;
import mods.betterfoliage.common.util.Double3;
import net.minecraft.block.Block;
import net.minecraft.block.material.Material;
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.minecraft.world.IBlockAccess;
import net.minecraft.world.gen.NoiseGeneratorSimplex;
import net.minecraftforge.client.event.TextureStitchEvent;
import net.minecraftforge.common.util.ForgeDirection;
import net.minecraftforge.event.world.WorldEvent;
import cpw.mods.fml.common.eventhandler.SubscribeEvent;
public class RenderBlockBetterCoral extends RenderBlockAOBase implements IRenderBlockDecorator {
public IconSet coralCrustIcons = new IconSet("bettergrassandleaves", "better_crust_%d");
public IconSet coralCrossIcons = new IconSet("bettergrassandleaves", "better_coral_%d");
public NoiseGeneratorSimplex noise;
public boolean isBlockAccepted(IBlockAccess blockAccess, int x, int y, int z, Block block, int original) {
if (!BetterFoliage.config.coralEnabled) return false;
if (block != Blocks.sand) return false;
int terrainVariation = MathHelper.floor_double((noise.func_151605_a(x * 0.1, z * 0.1) + 1.0) * 32.0);
return terrainVariation < BetterFoliage.config.coralPopulation.value;
}
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 sand block
setPassCounters(1);
setRenderBoundsFromBlock(block);
renderStandardBlock(block, x, y, z);
Double3 blockCenter = new Double3(x + 0.5, y + 0.5, z + 0.5);
double offset = pRand[getSemiRandomFromPos(x, y, z, 6)] * BetterFoliage.config.coralVOffset.value;
double halfSize = BetterFoliage.config.coralSize.value * 0.5;
double halfCrustSize = BetterFoliage.config.coralCrustSize.value * 0.5;
Tessellator.instance.setBrightness(getBrightness(block, x, y, z));
for (ForgeDirection dir : ForgeDirection.VALID_DIRECTIONS) {
if (blockAccess.getBlock(x + dir.offsetX, y + dir.offsetY, z + dir.offsetZ).getMaterial() != Material.water) continue;
if (blockAccess.isAirBlock(x + dir.offsetX, y + dir.offsetY + 1, z + dir.offsetZ)) continue;
int variation = getSemiRandomFromPos(x, y, z, dir.ordinal());
if (variation < BetterFoliage.config.coralChance.value) {
IIcon crustIcon = coralCrustIcons.get(variation);
IIcon coralIcon = coralCrossIcons.get(variation);
if (crustIcon != null) renderCoralCrust(blockCenter, dir, offset, halfCrustSize, crustIcon, variation);
if (coralIcon != null) renderCrossedSideQuads(blockCenter.add(new Double3(dir).scale(0.5)), dir,
halfSize, halfSize,
pRot[variation], BetterFoliage.config.coralHOffset.value,
coralIcon, 0, false);
}
}
return true;
}
protected void renderCoralCrust(Double3 blockCenter, ForgeDirection dir, double offset, double scale, IIcon icon, int uvRot) {
Double3 face1 = new Double3(faceDir1[dir.ordinal()]).scale(scale);
Double3 face2 = new Double3(faceDir2[dir.ordinal()]).scale(scale);
Double3 drawCenter = blockCenter.add(new Double3(dir).scale(0.5 + offset));
if (Minecraft.isAmbientOcclusionEnabled()) {
setShadingForFace(dir);
renderQuadWithShading(icon, drawCenter, face1, face2, uvRot, faceAOPP, faceAONP, faceAONN, faceAOPN);
} else {
renderQuad(icon, drawCenter, face1, face2, uvRot);
}
}
@SubscribeEvent
public void handleTextureReload(TextureStitchEvent.Pre event) {
if (event.map.getTextureType() != 0) return;
coralCrustIcons.registerIcons(event.map);
coralCrossIcons.registerIcons(event.map);
BetterFoliage.log.info(String.format("Found %d coral crust textures", coralCrustIcons.numLoaded));
BetterFoliage.log.info(String.format("Found %d coral textures", coralCrossIcons.numLoaded));
}
@SubscribeEvent
public void handleWorldLoad(WorldEvent.Load event) {
noise = new NoiseGeneratorSimplex(new Random(event.world.getWorldInfo().getSeed() + 2));
}
}

View File

@@ -1,7 +1,6 @@
package mods.betterfoliage.client.render.impl; package mods.betterfoliage.client.render.impl;
import mods.betterfoliage.BetterFoliage; import mods.betterfoliage.BetterFoliage;
import mods.betterfoliage.client.ShadersModIntegration;
import mods.betterfoliage.client.render.IRenderBlockDecorator; import mods.betterfoliage.client.render.IRenderBlockDecorator;
import mods.betterfoliage.client.render.IconSet; import mods.betterfoliage.client.render.IconSet;
import mods.betterfoliage.client.render.RenderBlockAOBase; import mods.betterfoliage.client.render.RenderBlockAOBase;
@@ -23,15 +22,13 @@ import cpw.mods.fml.relauncher.SideOnly;
public class RenderBlockBetterGrass extends RenderBlockAOBase implements IRenderBlockDecorator { public class RenderBlockBetterGrass extends RenderBlockAOBase implements IRenderBlockDecorator {
public IconSet grassIcons = new IconSet("bettergrassandleaves", "better_grass_long_%d"); public IconSet grassIcons = new IconSet("bettergrassandleaves", "better_grass_long_%d");
public IconSet snowGrassIcons = new IconSet("bettergrassandleaves", "better_grass_snowed_%d");
public IconSet myceliumIcons = new IconSet("bettergrassandleaves", "better_mycel_%d"); public IconSet myceliumIcons = new IconSet("bettergrassandleaves", "better_mycel_%d");
public IIcon grassGenIcon;
public IIcon snowGrassGenIcon;
public boolean isBlockAccepted(IBlockAccess blockAccess, int x, int y, int z, Block block, int original) { public boolean isBlockAccepted(IBlockAccess blockAccess, int x, int y, int z, Block block, int original) {
if (!BetterFoliage.config.grassEnabled) return false; if (!BetterFoliage.config.grassEnabled) return false;
if (!((block instanceof BlockGrass || block == Blocks.mycelium))) return false; if (!((block instanceof BlockGrass || block == Blocks.mycelium))) return false;
if (!blockAccess.isAirBlock(x, y + 1, z) && blockAccess.getBlock(x, y + 1, z) != Blocks.snow_layer) return false; if (y == 255 || !blockAccess.isAirBlock(x, y + 1, z)) return false;
return true; return true;
} }
@@ -46,32 +43,14 @@ public class RenderBlockBetterGrass extends RenderBlockAOBase implements IRender
int variation = getSemiRandomFromPos(x, y, z, 0); int variation = getSemiRandomFromPos(x, y, z, 0);
int heightVariation = getSemiRandomFromPos(x, y, z, 1); int heightVariation = getSemiRandomFromPos(x, y, z, 1);
boolean isSnowed = blockAccess.getBlock(x, y + 1, z) == Blocks.snow_layer;
IIcon renderIcon = null; IIcon renderIcon = (block == Blocks.mycelium) ? myceliumIcons.get(variation) : grassIcons.get(variation);
if (block instanceof BlockGrass) {
if (BetterFoliage.config.grassUseGenerated) {
renderIcon = isSnowed ? snowGrassGenIcon : grassGenIcon;
} else {
renderIcon = isSnowed ? snowGrassIcons.get(variation) : grassIcons.get(variation);
}
} else if (block == Blocks.mycelium && !isSnowed) {
renderIcon = myceliumIcons.get(variation);
}
if (renderIcon == null) return true; if (renderIcon == null) return true;
double scale = BetterFoliage.config.grassSize.value * 0.5; double scale = BetterFoliage.config.grassSize.value * 0.5;
double halfHeight = 0.5 * (BetterFoliage.config.grassHeightMin.value + pRand[heightVariation] * (BetterFoliage.config.grassHeightMax.value - BetterFoliage.config.grassHeightMin.value)); double halfHeight = 0.5 * (BetterFoliage.config.grassHeightMin.value + pRand[heightVariation] * (BetterFoliage.config.grassHeightMax.value - BetterFoliage.config.grassHeightMin.value));
if (isSnowed) {
aoYPXZNN.setGray(0.9f); aoYPXZNP.setGray(0.9f); aoYPXZPN.setGray(0.9f); aoYPXZPP.setGray(0.9f);
Tessellator.instance.setColorOpaque(230, 230, 230);
}
// render short grass
ShadersModIntegration.startGrassQuads();
Tessellator.instance.setBrightness(getBrightness(block, x, y + 1, z)); Tessellator.instance.setBrightness(getBrightness(block, x, y + 1, z));
renderCrossedSideQuads(new Double3(x + 0.5, y + 1.0 + (isSnowed ? 0.0625 : 0.0), z + 0.5), ForgeDirection.UP, scale, halfHeight, pRot[variation], BetterFoliage.config.grassHOffset.value, renderIcon, 0, false); renderCrossedSideQuads(new Double3(x + 0.5, y + 1.0 - 0.125 * halfHeight, z + 0.5), ForgeDirection.UP, scale, halfHeight, pRot[variation], BetterFoliage.config.grassHOffset.value, renderIcon, 0, false);
return true; return true;
} }
@@ -81,12 +60,8 @@ public class RenderBlockBetterGrass extends RenderBlockAOBase implements IRender
if (event.map.getTextureType() != 0) return; if (event.map.getTextureType() != 0) return;
grassIcons.registerIcons(event.map); grassIcons.registerIcons(event.map);
snowGrassIcons.registerIcons(event.map);
myceliumIcons.registerIcons(event.map); myceliumIcons.registerIcons(event.map);
grassGenIcon = event.map.registerIcon("bf_shortgrass:minecraft:tallgrass");
snowGrassGenIcon = event.map.registerIcon("bf_shortgrass_snow:minecraft:tallgrass");
BetterFoliage.log.info(String.format("Found %d short grass textures", grassIcons.numLoaded)); BetterFoliage.log.info(String.format("Found %d short grass textures", grassIcons.numLoaded));
BetterFoliage.log.info(String.format("Found %d snowy grass textures", snowGrassIcons.numLoaded));
BetterFoliage.log.info(String.format("Found %d mycelium textures", myceliumIcons.numLoaded)); BetterFoliage.log.info(String.format("Found %d mycelium textures", myceliumIcons.numLoaded));
} }

View File

@@ -44,10 +44,6 @@ public class RenderBlockBetterLeaves extends RenderBlockAOBase implements IRende
// find generated texture to render with, assume the // find generated texture to render with, assume the
// "true" texture of the block is the one on the north size // "true" texture of the block is the one on the north size
TextureAtlasSprite blockLeafIcon = (TextureAtlasSprite) block.getIcon(world, x, y, z, ForgeDirection.NORTH.ordinal()); TextureAtlasSprite blockLeafIcon = (TextureAtlasSprite) block.getIcon(world, x, y, z, ForgeDirection.NORTH.ordinal());
if (blockLeafIcon == null) {
BetterFoliage.log.debug(String.format("null leaf texture, x:%d, y:%d, z:%d, meta:%d, block:%s", x, y, z, blockAccess.getBlockMetadata(x, y, z), block.getClass().getName()));
return true;
}
IIcon crossLeafIcon = Minecraft.getMinecraft().getTextureMapBlocks().getAtlasSprite(BetterFoliageClient.leafGenerator.domainName + ":" + blockLeafIcon.getIconName()); IIcon crossLeafIcon = Minecraft.getMinecraft().getTextureMapBlocks().getAtlasSprite(BetterFoliageClient.leafGenerator.domainName + ":" + blockLeafIcon.getIconName());
if (crossLeafIcon == null) { if (crossLeafIcon == null) {
return true; return true;

View File

@@ -30,7 +30,7 @@ public class RenderBlockBetterLilypad extends FakeRenderBlockAOBase implements I
// store world for later use // store world for later use
blockAccess = world; blockAccess = world;
// render lilypad block // render grass block
renderBlockLilyPad(block, x, y, z); renderBlockLilyPad(block, x, y, z);
int chanceVariation = getSemiRandomFromPos(x, y, z, 0); int chanceVariation = getSemiRandomFromPos(x, y, z, 0);

View File

@@ -3,7 +3,6 @@ package mods.betterfoliage.client.render.impl;
import java.util.Random; import java.util.Random;
import mods.betterfoliage.BetterFoliage; import mods.betterfoliage.BetterFoliage;
import mods.betterfoliage.client.ShadersModIntegration;
import mods.betterfoliage.client.render.IRenderBlockDecorator; import mods.betterfoliage.client.render.IRenderBlockDecorator;
import mods.betterfoliage.client.render.IconSet; import mods.betterfoliage.client.render.IconSet;
import mods.betterfoliage.client.render.RenderBlockAOBase; import mods.betterfoliage.client.render.RenderBlockAOBase;
@@ -45,7 +44,7 @@ public class RenderBlockBetterReed extends RenderBlockAOBase implements IRenderB
// store world for later use // store world for later use
blockAccess = world; blockAccess = world;
// render dirt block // render grass block
setPassCounters(1); setPassCounters(1);
setRenderBoundsFromBlock(block); setRenderBoundsFromBlock(block);
renderStandardBlock(block, x, y, z); renderStandardBlock(block, x, y, z);
@@ -60,9 +59,6 @@ public class RenderBlockBetterReed extends RenderBlockAOBase implements IRenderB
double quarterHeight = 0.25 * (BetterFoliage.config.reedHeightMin.value + pRand[heightVariation] * (BetterFoliage.config.reedHeightMax.value - BetterFoliage.config.reedHeightMin.value)); double quarterHeight = 0.25 * (BetterFoliage.config.reedHeightMin.value + pRand[heightVariation] * (BetterFoliage.config.reedHeightMax.value - BetterFoliage.config.reedHeightMin.value));
Tessellator.instance.setBrightness(getBrightness(block, x, y + 2, z)); Tessellator.instance.setBrightness(getBrightness(block, x, y + 2, z));
Tessellator.instance.setColorOpaque(255, 255, 255); Tessellator.instance.setColorOpaque(255, 255, 255);
// render reeds
ShadersModIntegration.startGrassQuads();
renderCrossedSideQuads(new Double3(x + 0.5, y + 1.0, z + 0.5), ForgeDirection.UP, 0.5, quarterHeight, pRot[iconVariation], BetterFoliage.config.reedHOffset.value, bottomIcon, 0, true); renderCrossedSideQuads(new Double3(x + 0.5, y + 1.0, z + 0.5), ForgeDirection.UP, 0.5, quarterHeight, pRot[iconVariation], BetterFoliage.config.reedHOffset.value, bottomIcon, 0, true);
renderCrossedSideQuads(new Double3(x + 0.5, y + 1.0 + 2.0 * quarterHeight, z + 0.5), ForgeDirection.UP, 0.5, quarterHeight, pRot[iconVariation], BetterFoliage.config.reedHOffset.value, topIcon, 0, true); renderCrossedSideQuads(new Double3(x + 0.5, y + 1.0 + 2.0 * quarterHeight, z + 0.5), ForgeDirection.UP, 0.5, quarterHeight, pRot[iconVariation], BetterFoliage.config.reedHOffset.value, topIcon, 0, true);

View File

@@ -0,0 +1,11 @@
package mods.betterfoliage.client.resource;
import cpw.mods.fml.relauncher.Side;
import cpw.mods.fml.relauncher.SideOnly;
import net.minecraft.client.renderer.texture.TextureAtlasSprite;
@SideOnly(Side.CLIENT)
public interface ILeafTextureRecognizer {
public boolean isLeafTexture(TextureAtlasSprite icon);
}

View File

@@ -2,24 +2,25 @@ package mods.betterfoliage.client.resource;
import java.io.IOException; import java.io.IOException;
import java.util.Iterator; import java.util.Iterator;
import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.Set; import java.util.Set;
import mods.betterfoliage.BetterFoliage; import mods.betterfoliage.BetterFoliage;
import mods.betterfoliage.client.BetterFoliageClient; import mods.betterfoliage.client.BetterFoliageClient;
import mods.betterfoliage.common.util.DeobfNames;
import mods.betterfoliage.common.util.Utils; import mods.betterfoliage.common.util.Utils;
import mods.betterfoliage.loader.DeobfHelper;
import net.minecraft.block.Block; import net.minecraft.block.Block;
import net.minecraft.client.Minecraft; import net.minecraft.client.Minecraft;
import net.minecraft.client.renderer.texture.IIconRegister; import net.minecraft.client.renderer.texture.IIconRegister;
import net.minecraft.client.renderer.texture.TextureAtlasSprite; import net.minecraft.client.renderer.texture.TextureAtlasSprite;
import net.minecraft.client.resources.IResource; import net.minecraft.client.resources.IResource;
import net.minecraft.client.resources.IResourceManager;
import net.minecraft.util.IIcon; import net.minecraft.util.IIcon;
import net.minecraft.util.ResourceLocation; import net.minecraft.util.ResourceLocation;
import net.minecraftforge.client.event.TextureStitchEvent.Post; import net.minecraftforge.client.event.TextureStitchEvent.Post;
import net.minecraftforge.client.event.TextureStitchEvent.Pre; import net.minecraftforge.client.event.TextureStitchEvent.Pre;
import com.google.common.collect.Lists;
import com.google.common.collect.Sets; import com.google.common.collect.Sets;
import cpw.mods.fml.relauncher.Side; import cpw.mods.fml.relauncher.Side;
@@ -39,32 +40,23 @@ public class LeafTextureGenerator extends BlockTextureGenerator implements IIcon
super("bf_leaves_autogen", new ResourceLocation("betterfoliage", "textures/blocks/missing_leaf.png")); super("bf_leaves_autogen", new ResourceLocation("betterfoliage", "textures/blocks/missing_leaf.png"));
} }
/** List of helpers which can identify leaf textures loaded by alternate means */
public List<ILeafTextureRecognizer> recognizers = Lists.newLinkedList();
public IResource getResource(ResourceLocation resourceLocation) throws IOException { public IResource getResource(ResourceLocation resourceLocation) throws IOException {
IResourceManager resourceManager = Minecraft.getMinecraft().getResourceManager(); ResourceLocation original = unwrapResource(resourceLocation);
ResourceLocation originalNoDirs = unwrapResource(resourceLocation);
ResourceLocation originalWithDirs = new ResourceLocation(originalNoDirs.getResourceDomain(), "textures/blocks/" + originalNoDirs.getResourcePath());
// check for provided texture // check for provided texture
ResourceLocation handDrawnLocation = new ResourceLocation(nonGeneratedDomain, String.format("textures/blocks/%s/%s", originalNoDirs.getResourceDomain(), originalNoDirs.getResourcePath())); ResourceLocation handDrawnLocation = new ResourceLocation(nonGeneratedDomain, String.format("textures/blocks/%s/%s", original.getResourceDomain(), original.getResourcePath()));
if (Utils.resourceExists(handDrawnLocation)) { if (Utils.resourceExists(handDrawnLocation)) {
nonGeneratedCounter++; nonGeneratedCounter++;
return resourceManager.getResource(handDrawnLocation); return Minecraft.getMinecraft().getResourceManager().getResource(handDrawnLocation);
}
// Don't alter ShaderMod normal and specular maps
if (originalWithDirs.getResourcePath().toLowerCase().endsWith("_n.png") || originalWithDirs.getResourcePath().toLowerCase().endsWith("_s.png")) {
resourceManager.getResource(originalWithDirs);
} }
// generate our own // generate our own
if (!Utils.resourceExists(originalWithDirs)) return getMissingResource(); LeafTextureResource result = new LeafTextureResource(original, getMissingResource());
LeafTextureResource result = new LeafTextureResource(resourceManager.getResource(originalWithDirs)); if (result.data != null) counter++;
if (result.data != null) { return result;
counter++;
return result;
} else {
return getMissingResource();
}
} }
/** Leaf blocks register their textures here. An extra texture will be registered in the atlas /** Leaf blocks register their textures here. An extra texture will be registered in the atlas
@@ -100,15 +92,16 @@ public class LeafTextureGenerator extends BlockTextureGenerator implements IIcon
// enumerate all registered textures, find leaf textures among them // enumerate all registered textures, find leaf textures among them
Map<String, TextureAtlasSprite> mapAtlas = null; Map<String, TextureAtlasSprite> mapAtlas = null;
mapAtlas = Utils.getField(blockTextures, DeobfHelper.transformElementSearge("mapRegisteredSprites"), Map.class); mapAtlas = Utils.getField(blockTextures, DeobfNames.TM_MRS_SRG, Map.class);
if (mapAtlas == null) mapAtlas = Utils.getField(blockTextures, "mapRegisteredSprites", Map.class); if (mapAtlas == null) mapAtlas = Utils.getField(blockTextures, DeobfNames.TM_MRS_MCP, Map.class);
if (mapAtlas == null) { if (mapAtlas == null) {
BetterFoliage.log.warn("Failed to reflect texture atlas, textures may be missing"); BetterFoliage.log.warn("Failed to reflect texture atlas, textures may be missing");
} else { } else {
Set<String> foundLeafTextures = Sets.newHashSet(); Set<String> foundLeafTextures = Sets.newHashSet();
for (TextureAtlasSprite icon : mapAtlas.values()) for (TextureAtlasSprite icon : mapAtlas.values())
if (BetterFoliageClient.isLeafTexture(icon)) for (ILeafTextureRecognizer recognizer : recognizers)
foundLeafTextures.add(icon.getIconName()); if (recognizer.isLeafTexture(icon))
foundLeafTextures.add(icon.getIconName());
for (String resourceLocation : foundLeafTextures) { for (String resourceLocation : foundLeafTextures) {
BetterFoliage.log.debug(String.format("Found non-block-registered leaf texture: %s", resourceLocation)); BetterFoliage.log.debug(String.format("Found non-block-registered leaf texture: %s", resourceLocation));
blockTextures.registerIcon(new ResourceLocation(domainName, resourceLocation).toString()); blockTextures.registerIcon(new ResourceLocation(domainName, resourceLocation).toString());

View File

@@ -4,6 +4,7 @@ import java.awt.Graphics2D;
import java.awt.image.BufferedImage; import java.awt.image.BufferedImage;
import java.io.ByteArrayInputStream; import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream; import java.io.ByteArrayOutputStream;
import java.io.FileNotFoundException;
import java.io.IOException; import java.io.IOException;
import java.io.InputStream; import java.io.InputStream;
@@ -30,10 +31,17 @@ public class LeafTextureResource implements IResource {
/** Name of the default alpha mask to use */ /** Name of the default alpha mask to use */
public static String defaultMask = "rough"; public static String defaultMask = "rough";
public LeafTextureResource(IResource resLeaf) { /** Resource to return if generation fails */
public IResource fallbackResource;
public LeafTextureResource(ResourceLocation resLeaf, IResource fallbackResource) {
this.fallbackResource = fallbackResource;
IResourceManager resourceManager = Minecraft.getMinecraft().getResourceManager();
try { try {
// load normal leaf texture // load normal leaf texture
BufferedImage origImage = ImageIO.read(resLeaf.getInputStream()); ResourceLocation origResource = new ResourceLocation(resLeaf.getResourceDomain(), "textures/blocks/" + resLeaf.getResourcePath());
BufferedImage origImage = ImageIO.read(resourceManager.getResource(origResource).getInputStream());
if (origImage.getWidth() != origImage.getHeight()) return; if (origImage.getWidth() != origImage.getHeight()) return;
int size = origImage.getWidth(); int size = origImage.getWidth();
@@ -64,6 +72,7 @@ public class LeafTextureResource implements IResource {
data = baos.toByteArray(); data = baos.toByteArray();
} catch (Exception e) { } catch (Exception e) {
// stop log spam with GLSL installed // stop log spam with GLSL installed
if (e instanceof FileNotFoundException) return;
BetterFoliage.log.info(String.format("Could not create leaf texture: %s, exception: %s", resLeaf.toString(), e.getClass().getSimpleName())); BetterFoliage.log.info(String.format("Could not create leaf texture: %s, exception: %s", resLeaf.toString(), e.getClass().getSimpleName()));
} }
} }
@@ -93,7 +102,7 @@ public class LeafTextureResource implements IResource {
} }
public InputStream getInputStream() { public InputStream getInputStream() {
return new ByteArrayInputStream(data); return data != null ? new ByteArrayInputStream(data) : fallbackResource.getInputStream();
} }
public boolean hasMetadata() { public boolean hasMetadata() {

View File

@@ -1,82 +0,0 @@
package mods.betterfoliage.client.resource;
import java.awt.Graphics2D;
import java.awt.image.BufferedImage;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.InputStream;
import javax.imageio.ImageIO;
import mods.betterfoliage.BetterFoliage;
import net.minecraft.client.Minecraft;
import net.minecraft.client.resources.IResource;
import net.minecraft.client.resources.IResourceManager;
import net.minecraft.client.resources.data.IMetadataSection;
import net.minecraft.util.ResourceLocation;
public class ShortGrassTextureResource implements IResource {
/** Raw PNG data*/
public byte[] data = null;
/** Resource to return if generation fails */
public IResource fallbackResource;
public ShortGrassTextureResource(ResourceLocation resource, boolean isSnowed, IResource fallbackResource) {
this.fallbackResource = fallbackResource;
boolean isSpecialTexture = resource.getResourcePath().toLowerCase().endsWith("_n.png") || resource.getResourcePath().toLowerCase().endsWith("_s.png");
IResourceManager resourceManager = Minecraft.getMinecraft().getResourceManager();
try {
// load full texture
ResourceLocation origResource = new ResourceLocation(resource.getResourceDomain(), "textures/blocks/" + resource.getResourcePath());
BufferedImage origImage = ImageIO.read(resourceManager.getResource(origResource).getInputStream());
// draw bottom half of texture
BufferedImage result = new BufferedImage(origImage.getWidth(), origImage.getHeight(), BufferedImage.TYPE_4BYTE_ABGR);
Graphics2D graphics = result.createGraphics();
graphics.drawImage(origImage, 0, 3 * origImage.getHeight() / 8, null);
// blend with white if snowed
if (isSnowed && !isSpecialTexture) {
for (int x = 0; x < result.getWidth(); x++) for (int y = 0; y < result.getHeight(); y++) {
result.setRGB(x, y, blend(result.getRGB(x, y), 0xFFFFFF, 2, 3));
}
}
// create PNG image
ByteArrayOutputStream baos = new ByteArrayOutputStream();
ImageIO.write(result, "PNG", baos);
data = baos.toByteArray();
} catch (Exception e) {
// stop log spam with GLSL installed
BetterFoliage.log.info(String.format("Could not load texture: %s, exception: %s", resource.toString(), e.getClass().getSimpleName()));
}
}
protected int blend(int rgbOrig, int rgbBlend, int weightOrig, int weightBlend) {
int r = ((rgbOrig & 0xFF) * weightOrig + (rgbBlend & 0xFF) * weightBlend) / (weightOrig + weightBlend);
int g = (((rgbOrig >> 8) & 0xFF) * weightOrig + ((rgbBlend >> 8) & 0xFF) * weightBlend) / (weightOrig + weightBlend);
int b = (((rgbOrig >> 16) & 0xFF) * weightOrig + ((rgbBlend >> 16) & 0xFF) * weightBlend) / (weightOrig + weightBlend);
int a = (rgbOrig >> 24) & 0xFF;
int result = (int) (a << 24 | b << 16 | g << 8 | r);
return result;
}
@Override
public InputStream getInputStream() {
return data != null ? new ByteArrayInputStream(data) : fallbackResource.getInputStream();
}
@Override
public boolean hasMetadata() {
return false;
}
@Override
public IMetadataSection getMetadata(String var1) {
return null;
}
}

View File

@@ -11,9 +11,6 @@ public class BetterFoliageConfig extends ConfigBase {
@CfgElement(category="grass", key="enabled") @CfgElement(category="grass", key="enabled")
public boolean grassEnabled = true; public boolean grassEnabled = true;
@CfgElement(category="grass", key="useGenerated")
public boolean grassUseGenerated = false;
@CfgElement(category="cactus", key="enabled") @CfgElement(category="cactus", key="enabled")
public boolean cactusEnabled = true; public boolean cactusEnabled = true;
@@ -26,9 +23,6 @@ public class BetterFoliageConfig extends ConfigBase {
@CfgElement(category="algae", key="enabled") @CfgElement(category="algae", key="enabled")
public boolean algaeEnabled = true; public boolean algaeEnabled = true;
@CfgElement(category="coral", key="enabled")
public boolean coralEnabled = true;
@CfgElement(category="leaves", key="horizontalOffset") @CfgElement(category="leaves", key="horizontalOffset")
public OptionDouble leavesHOffset = new OptionDouble(0.0, 0.4, 0.025, 0.2); public OptionDouble leavesHOffset = new OptionDouble(0.0, 0.4, 0.025, 0.2);
@@ -85,22 +79,4 @@ public class BetterFoliageConfig extends ConfigBase {
@CfgElement(category="algae", key="chance") @CfgElement(category="algae", key="chance")
public OptionInteger algaeChance = new OptionInteger(0, 64, 1, 48); public OptionInteger algaeChance = new OptionInteger(0, 64, 1, 48);
@CfgElement(category="coral", key="population")
public OptionInteger coralPopulation = new OptionInteger(0, 64, 1, 32);
@CfgElement(category="coral", key="chance")
public OptionInteger coralChance = new OptionInteger(0, 64, 1, 32);
@CfgElement(category="coral", key="verticalOffset")
public OptionDouble coralVOffset = new OptionDouble(0.0, 0.25, 0.025, 0.1);
@CfgElement(category="coral", key="horizontalOffset")
public OptionDouble coralHOffset = new OptionDouble(0.0, 0.4, 0.025, 0.2);
@CfgElement(category="coral", key="crustSize")
public OptionDouble coralCrustSize = new OptionDouble(0.75, 1.75, 0.05, 1.4);
@CfgElement(category="coral", key="size")
public OptionDouble coralSize = new OptionDouble(0.25, 1.0, 0.05, 0.7);
} }

View File

@@ -0,0 +1,71 @@
package mods.betterfoliage.common.util;
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 = "blm";
/** 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 = "Lahl;";
/** MCP name of RenderBlocks.renderBlockByRenderType() */
public static final String RB_RBBRT_NAME_MCP = "renderBlockByRenderType";
/** Obfuscated name of RenderBlocks.renderBlockByRenderType() */
public static final String RB_RBBRT_NAME_OBF = "b";
/** MCP signature of RenderBlocks.renderBlockByRenderType() */
public static final String RB_RBBRT_SIG_MCP = "(Lnet/minecraft/block/Block;III)Z";
/** Obfuscated signature of RenderBlocks.renderBlockByRenderType() */
public static final String RB_RBBRT_SIG_OBF = "(Laji;III)Z";
/** 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 BetterFoliageClient.getRenderTypeOverride() */
public static final String BFC_GRTO_SIG_OBF = "(Lahl;IIILaji;I)I";
/** MCP name of SimpleReloadableResourceManager.domainResourceManagers */
public static final String SRRM_DRM_MCP = "domainResourceManagers";
/** SRG name of SimpleReloadableResourceManager.domainResourceManagers */
public static final String SRRM_DRM_SRGNAME = "field_110548_a";
/** MCP name of TextureMap.mapRegisteredSprites */
public static final String TM_MRS_MCP = "mapRegisteredSprites";
/** Obfuscated name of TextureMap.mapRegisteredSprites */
public static final String TM_MRS_OBF = "bpr";
/** SRG name of TextureMap.mapRegisteredSprites */
public static final String TM_MRS_SRG = "field_110574_e";
/** MCP signature of Shaders.pushEntity() */
public static final String SHADERS_PE_SIG_MCP = "(Lnet/minecraft/client/renderer/RenderBlocks;Lnet/minecraft/block/Block;III)V";
/** Obfuscated signature of Shaders.pushEntity() */
public static final String SHADERS_PE_SIG_OBF = "(Lblm;Laji;III)V";
/** MCP signature of BetterFoliageClient.getGLSLBlockIdOverride() */
public static final String BFC_GLSLID_SIG_MCP = "(ILnet/minecraft/block/Block;)I";
/** Obfuscated signature of BetterFoliageClient.getGLSLBlockIdOverride() */
public static final String BFC_GLSLID_SIG_OBF = "(ILaji;)I";
}

View File

@@ -1,16 +1,9 @@
package mods.betterfoliage.common.util; package mods.betterfoliage.common.util;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException; import java.io.IOException;
import java.io.InputStreamReader;
import java.lang.reflect.Field; import java.lang.reflect.Field;
import java.util.Map; import java.util.Map;
import com.google.common.base.Charsets;
import mods.betterfoliage.loader.DeobfHelper;
import net.minecraft.client.Minecraft; import net.minecraft.client.Minecraft;
import net.minecraft.client.resources.IResource; import net.minecraft.client.resources.IResource;
import net.minecraft.client.resources.IResourceManager; import net.minecraft.client.resources.IResourceManager;
@@ -25,8 +18,8 @@ public class Utils {
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
public static Map<String, IResourceManager> getDomainResourceManagers() { public static Map<String, IResourceManager> getDomainResourceManagers() {
IResourceManager manager = Minecraft.getMinecraft().getResourceManager(); IResourceManager manager = Minecraft.getMinecraft().getResourceManager();
Map<String, IResourceManager> result = getField(manager, "domainResourceManagers", Map.class); Map<String, IResourceManager> result = getField(manager, DeobfNames.SRRM_DRM_MCP, Map.class);
if (result == null) result = getField(manager, DeobfHelper.transformElementSearge("domainResourceManagers"), Map.class); if (result == null) result = getField(manager, DeobfNames.SRRM_DRM_SRGNAME, Map.class);
return result; return result;
} }
@@ -74,21 +67,4 @@ public class Utils {
} }
return false; return false;
} }
public static void copyFromTextResource(ResourceLocation resourceLocation, File target) {
try {
IResource defaults = Minecraft.getMinecraft().getResourceManager().getResource(resourceLocation);
BufferedReader reader = new BufferedReader(new InputStreamReader(defaults.getInputStream(), Charsets.UTF_8));
FileWriter writer = new FileWriter(target);
String line = reader.readLine();
while(line != null) {
writer.write(line + System.lineSeparator());
line = reader.readLine();
}
reader.close();
writer.close();
} catch(IOException e) {
}
}
} }

View File

@@ -4,6 +4,7 @@ import java.util.Map;
import cpw.mods.fml.relauncher.IFMLLoadingPlugin; import cpw.mods.fml.relauncher.IFMLLoadingPlugin;
@IFMLLoadingPlugin.MCVersion("1.7.10")
@IFMLLoadingPlugin.TransformerExclusions({"mods.betterfoliage.loader"}) @IFMLLoadingPlugin.TransformerExclusions({"mods.betterfoliage.loader"})
public class BetterFoliageLoader implements IFMLLoadingPlugin { public class BetterFoliageLoader implements IFMLLoadingPlugin {

View File

@@ -1,78 +1,48 @@
package mods.betterfoliage.loader; package mods.betterfoliage.loader;
import net.minecraft.launchwrapper.IClassTransformer; import mods.betterfoliage.common.util.DeobfNames;
import org.apache.logging.log4j.LogManager; import org.objectweb.asm.Opcodes;
import org.apache.logging.log4j.Logger; import org.objectweb.asm.tree.AbstractInsnNode;
import org.objectweb.asm.ClassReader; import org.objectweb.asm.tree.FieldInsnNode;
import org.objectweb.asm.ClassWriter; import org.objectweb.asm.tree.MethodInsnNode;
import org.objectweb.asm.tree.ClassNode;
import org.objectweb.asm.tree.MethodNode; import org.objectweb.asm.tree.MethodNode;
import org.objectweb.asm.tree.VarInsnNode;
import com.google.common.collect.ImmutableList; public class BetterFoliageTransformer extends EZTransformerBase {
import cpw.mods.fml.relauncher.FMLInjectionData; @MethodTransform(className="net.minecraft.client.renderer.RenderBlocks",
obf=@MethodMatch(name=DeobfNames.RB_RBBRT_NAME_OBF, signature=DeobfNames.RB_RBBRT_SIG_OBF),
public class BetterFoliageTransformer implements IClassTransformer { deobf=@MethodMatch(name=DeobfNames.RB_RBBRT_NAME_MCP, signature=DeobfNames.RB_RBBRT_SIG_MCP),
log="Applying RenderBlocks.renderBlockByRenderType() render type ovverride")
protected Iterable<MethodTransformerBase> transformers = ImmutableList.<MethodTransformerBase>of( public void handleRenderBlockOverride(MethodNode method, boolean obf) {
new TransformRenderBlockOverride(), AbstractInsnNode invokeGetRenderType = findNext(method.instructions.getFirst(), matchInvokeAny());
new TransformShaderModBlockOverride() AbstractInsnNode storeRenderType = findNext(invokeGetRenderType, matchOpcode(Opcodes.ISTORE));
); insertAfter(method.instructions, storeRenderType,
new VarInsnNode(Opcodes.ALOAD, 0),
protected Logger logger = LogManager.getLogger(getClass().getSimpleName()); 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),
public BetterFoliageTransformer() { new VarInsnNode(Opcodes.ILOAD, 2),
String mcVersion = FMLInjectionData.data()[4].toString(); new VarInsnNode(Opcodes.ILOAD, 3),
if (!ImmutableList.<String>of("1.7.2", "1.7.10").contains(mcVersion)) new VarInsnNode(Opcodes.ILOAD, 4),
logger.warn(String.format("Unsupported Minecraft version %s", mcVersion)); new VarInsnNode(Opcodes.ALOAD, 1),
new VarInsnNode(Opcodes.ILOAD, 5),
DeobfHelper.init(); 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)
);
} }
@Override @MethodTransform(className="shadersmodcore.client.Shaders",
public byte[] transform(String name, String transformedName, byte[] basicClass) { obf=@MethodMatch(name="pushEntity", signature=DeobfNames.SHADERS_PE_SIG_OBF),
// ??? deobf=@MethodMatch(name="pushEntity", signature=DeobfNames.SHADERS_PE_SIG_MCP),
if (basicClass == null) return null; log="Applying Shaders.pushEntity() block id ovverride")
public void handleGLSLBlockIDOverride(MethodNode method, boolean obf) {
// read class AbstractInsnNode arrayStore = findNext(method.instructions.getFirst(), matchOpcode(Opcodes.IASTORE));
ClassNode classNode = new ClassNode(); insertAfter(method.instructions, arrayStore.getPrevious(),
ClassReader classReader = new ClassReader(basicClass); new VarInsnNode(Opcodes.ALOAD, 1),
classReader.accept(classNode, 0); obf ? new MethodInsnNode(Opcodes.INVOKESTATIC, "mods/betterfoliage/client/BetterFoliageClient", "getGLSLBlockIdOverride", DeobfNames.BFC_GLSLID_SIG_OBF) :
boolean hasTransformed = false; new MethodInsnNode(Opcodes.INVOKESTATIC, "mods/betterfoliage/client/BetterFoliageClient", "getGLSLBlockIdOverride", DeobfNames.BFC_GLSLID_SIG_MCP)
);
for (MethodTransformerBase transformer : transformers) {
// try to find specified method in class
if (!transformedName.equals(transformer.getClassName())) continue;
logger.debug(String.format("Found class: %s -> %s", name, transformedName));
for (MethodNode methodNode : classNode.methods) {
logger.trace(String.format("Checking method: %s, sig: %s", methodNode.name, methodNode.desc));
Boolean isObfuscated = null;
if (methodNode.name.equals(DeobfHelper.transformElementName(transformer.getMethodName())) && methodNode.desc.equals(DeobfHelper.transformSignature(transformer.getSignature()))) {
isObfuscated = true;
} else if (methodNode.name.equals(transformer.getMethodName()) && methodNode.desc.equals(transformer.getSignature())) {
isObfuscated = false;
}
if (isObfuscated != null) {
// transform
hasTransformed = true;
try {
transformer.transform(methodNode, isObfuscated);
logger.info(String.format("%s: SUCCESS", transformer.getLogMessage()));
} catch (Exception e) {
logger.info(String.format("%s: FAILURE", transformer.getLogMessage()));
}
break;
}
}
}
// return result
ClassWriter writer = new ClassWriter(0);
if (hasTransformed) classNode.accept(writer);
return !hasTransformed ? basicClass : writer.toByteArray();
} }
} }

View File

@@ -1,62 +0,0 @@
package mods.betterfoliage.loader;
import java.util.Map;
import com.google.common.collect.Maps;
import cpw.mods.fml.relauncher.FMLInjectionData;
public class DeobfHelper {
private static Map<String, String> obfClasses = Maps.newHashMap();
private static Map<String, String> obfElements = Maps.newHashMap();
private static Map<String, String> srgElements = Maps.newHashMap();
public static void init() {
String mcVersion = FMLInjectionData.data()[4].toString();
srgElements.put("domainResourceManagers", "field_110548_a");
srgElements.put("mapRegisteredSprites", "field_110574_e");
if ("1.7.2".equals(mcVersion)) {
obfClasses.put("net/minecraft/client/renderer/RenderBlocks", "ble");
obfClasses.put("net/minecraft/world/IBlockAccess", "afx");
obfClasses.put("net/minecraft/block/Block", "ahu");
obfElements.put("blockAccess", "a");
obfElements.put("renderBlockByRenderType", "b");
obfElements.put("mapRegisteredSprites", "bpr");
} else if ("1.7.10".equals(mcVersion)) {
obfClasses.put("net/minecraft/client/renderer/RenderBlocks", "blm");
obfClasses.put("net/minecraft/world/IBlockAccess", "ahl");
obfClasses.put("net/minecraft/block/Block", "aji");
obfElements.put("blockAccess", "a");
obfElements.put("renderBlockByRenderType", "b");
obfElements.put("mapRegisteredSprites", "bpr");
}
}
public static String transformClassName(String className) {
return obfClasses.containsKey(className) ? obfClasses.get(className) : className;
}
public static String transformElementName(String elementName) {
return obfElements.containsKey(elementName) ? obfElements.get(elementName) : elementName;
}
public static String transformElementSearge(String elementName) {
return srgElements.containsKey(elementName) ? srgElements.get(elementName) : elementName;
}
public static String transformSignature(String signature) {
String result = signature;
boolean hasChanged = false;
do {
hasChanged = false;
for (Map.Entry<String, String> entry : obfClasses.entrySet()) if (result.contains("L" + entry.getKey() + ";")) {
result = result.replace("L" + entry.getKey() + ";", "L" + entry.getValue() + ";");
hasChanged = true;
}
} while(hasChanged);
return result;
}
}

View File

@@ -0,0 +1,131 @@
package mods.betterfoliage.loader;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import java.lang.reflect.Method;
import net.minecraft.launchwrapper.IClassTransformer;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.objectweb.asm.ClassReader;
import org.objectweb.asm.ClassWriter;
import org.objectweb.asm.tree.AbstractInsnNode;
import org.objectweb.asm.tree.ClassNode;
import org.objectweb.asm.tree.InsnList;
import org.objectweb.asm.tree.MethodInsnNode;
import org.objectweb.asm.tree.MethodNode;
public class EZTransformerBase implements IClassTransformer {
public static interface IInstructionMatch {
public boolean matches(AbstractInsnNode node);
}
@Retention(RetentionPolicy.RUNTIME)
public static @interface MethodMatch {
public String name();
public String signature();
}
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public static @interface MethodTransform {
public String className();
public MethodMatch deobf();
public MethodMatch obf();
public String log();
}
protected Logger logger = LogManager.getLogger(getClass().getSimpleName());
public byte[] transform(String name, String transformedName, byte[] basicClass) {
// ???
if (basicClass == null) return null;
// read class
ClassNode classNode = new ClassNode();
ClassReader classReader = new ClassReader(basicClass);
classReader.accept(classNode, 0);
boolean hasTransformed = false;
for (Method classMethod : getClass().getMethods()) {
// check for annotated method with correct signature
MethodTransform annot = classMethod.getAnnotation(MethodTransform.class);
if (annot == null) continue;
if (classMethod.getParameterTypes().length != 2) continue;
if (!classMethod.getParameterTypes()[0].equals(MethodNode.class)) continue;
if (!classMethod.getParameterTypes()[1].equals(boolean.class)) continue;
// try to find specified method in class
if (!transformedName.equals(annot.className())) continue;
for (MethodNode methodNode : classNode.methods) {
Boolean obf = null;
if (methodNode.name.equals(annot.obf().name()) && methodNode.desc.equals(annot.obf().signature())) {
obf = true;
} else if (methodNode.name.equals(annot.deobf().name()) && methodNode.desc.equals(annot.deobf().signature())) {
obf = false;
}
if (obf != null) {
// transform
hasTransformed = true;
try {
classMethod.invoke(this, new Object[] {methodNode, obf});
logger.info(String.format("%s: SUCCESS", annot.log()));
} catch (Exception e) {
logger.info(String.format("%s: FAILURE", annot.log()));
}
break;
}
}
}
// return result
ClassWriter writer = new ClassWriter(0);
if (hasTransformed) classNode.accept(writer);
return !hasTransformed ? basicClass : writer.toByteArray();
}
protected AbstractInsnNode findNext(AbstractInsnNode start, IInstructionMatch match) {
AbstractInsnNode current = start;
while(current != null) {
if (match.matches(current)) break;
current = current.getNext();
}
return current;
}
protected AbstractInsnNode findPrevious(AbstractInsnNode start, IInstructionMatch match) {
AbstractInsnNode current = start;
while(current != null) {
if (match.matches(current)) break;
current = current.getPrevious();
}
return current;
}
protected static IInstructionMatch matchInvokeAny() {
return new IInstructionMatch() {
public boolean matches(AbstractInsnNode node) {
return node instanceof MethodInsnNode;
}
};
}
protected static IInstructionMatch matchOpcode(final int opcode) {
return new IInstructionMatch() {
public boolean matches(AbstractInsnNode node) {
return node.getOpcode() == opcode;
}
};
}
protected static void insertAfter(InsnList insnList, AbstractInsnNode node, AbstractInsnNode... added) {
InsnList listAdd = new InsnList();
for (AbstractInsnNode inst : added) listAdd.add(inst);
insnList.insert(node, listAdd);
}
}

View File

@@ -1,72 +0,0 @@
package mods.betterfoliage.loader;
import org.objectweb.asm.tree.AbstractInsnNode;
import org.objectweb.asm.tree.InsnList;
import org.objectweb.asm.tree.MethodInsnNode;
import org.objectweb.asm.tree.MethodNode;
public abstract class MethodTransformerBase {
public static interface IInstructionMatch {
public boolean matches(AbstractInsnNode node);
}
public abstract String getClassName();
public abstract String getMethodName();
public abstract String getSignature();
public abstract String getLogMessage();
public abstract void transform(MethodNode method, boolean obf);
protected static String className(String className, boolean isObfuscated) {
return isObfuscated ? DeobfHelper.transformClassName(className) : className;
}
protected static String element(String fieldName, boolean isObfuscated) {
return isObfuscated ? DeobfHelper.transformElementName(fieldName) : fieldName;
}
protected static String signature(String signature, boolean isObfuscated) {
return isObfuscated ? DeobfHelper.transformSignature(signature) : signature;
}
protected AbstractInsnNode findNext(AbstractInsnNode start, IInstructionMatch match) {
AbstractInsnNode current = start;
while(current != null) {
if (match.matches(current)) break;
current = current.getNext();
}
return current;
}
protected AbstractInsnNode findPrevious(AbstractInsnNode start, IInstructionMatch match) {
AbstractInsnNode current = start;
while(current != null) {
if (match.matches(current)) break;
current = current.getPrevious();
}
return current;
}
protected IInstructionMatch matchInvokeAny() {
return new IInstructionMatch() {
public boolean matches(AbstractInsnNode node) {
return node instanceof MethodInsnNode;
}
};
}
protected IInstructionMatch matchOpcode(final int opcode) {
return new IInstructionMatch() {
public boolean matches(AbstractInsnNode node) {
return node.getOpcode() == opcode;
}
};
}
protected void insertAfter(InsnList insnList, AbstractInsnNode node, AbstractInsnNode... added) {
InsnList listAdd = new InsnList();
for (AbstractInsnNode inst : added) listAdd.add(inst);
insnList.insert(node, listAdd);
}
}

View File

@@ -1,49 +0,0 @@
package mods.betterfoliage.loader;
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;
public class TransformRenderBlockOverride extends MethodTransformerBase {
@Override
public String getClassName() {
return "net.minecraft.client.renderer.RenderBlocks";
}
@Override
public String getMethodName() {
return "renderBlockByRenderType";
}
@Override
public String getSignature() {
return "(Lnet/minecraft/block/Block;III)Z";
}
@Override
public String getLogMessage() {
return "Applying RenderBlocks.renderBlockByRenderType() render type ovverride";
}
@Override
public void transform(MethodNode method, boolean obf) {
AbstractInsnNode invokeGetRenderType = findNext(method.instructions.getFirst(), matchInvokeAny());
AbstractInsnNode storeRenderType = findNext(invokeGetRenderType, matchOpcode(Opcodes.ISTORE));
insertAfter(method.instructions, storeRenderType,
new VarInsnNode(Opcodes.ALOAD, 0),
new FieldInsnNode(Opcodes.GETFIELD, className("net/minecraft/client/renderer/RenderBlocks", obf), element("blockAccess", obf), signature("Lnet/minecraft/world/IBlockAccess;", obf)),
new VarInsnNode(Opcodes.ILOAD, 2),
new VarInsnNode(Opcodes.ILOAD, 3),
new VarInsnNode(Opcodes.ILOAD, 4),
new VarInsnNode(Opcodes.ALOAD, 1),
new VarInsnNode(Opcodes.ILOAD, 5),
new MethodInsnNode(Opcodes.INVOKESTATIC, "mods/betterfoliage/client/BetterFoliageClient", "getRenderTypeOverride", signature("(Lnet/minecraft/world/IBlockAccess;IIILnet/minecraft/block/Block;I)I", obf)),
new VarInsnNode(Opcodes.ISTORE, 5)
);
}
}

View File

@@ -1,40 +0,0 @@
package mods.betterfoliage.loader;
import org.objectweb.asm.Opcodes;
import org.objectweb.asm.tree.AbstractInsnNode;
import org.objectweb.asm.tree.MethodInsnNode;
import org.objectweb.asm.tree.MethodNode;
import org.objectweb.asm.tree.VarInsnNode;
public class TransformShaderModBlockOverride extends MethodTransformerBase {
@Override
public String getClassName() {
return "shadersmodcore.client.Shaders";
}
@Override
public String getMethodName() {
return "pushEntity";
}
@Override
public String getSignature() {
return "(Lnet/minecraft/client/renderer/RenderBlocks;Lnet/minecraft/block/Block;III)V";
}
@Override
public String getLogMessage() {
return "Applying Shaders.pushEntity() block id ovverride";
}
@Override
public void transform(MethodNode method, boolean obf) {
AbstractInsnNode arrayStore = findNext(method.instructions.getFirst(), matchOpcode(Opcodes.IASTORE));
insertAfter(method.instructions, arrayStore.getPrevious(),
new VarInsnNode(Opcodes.ALOAD, 1),
new MethodInsnNode(Opcodes.INVOKESTATIC, "mods/betterfoliage/client/ShadersModIntegration", "getBlockIdOverride", signature("(ILnet/minecraft/block/Block;)I", obf))
);
}
}

View File

@@ -1,35 +0,0 @@
// Vanilla
net.minecraft.block.BlockTallGrass
net.minecraft.block.BlockCrops
net.minecraft.block.BlockReed
net.minecraft.block.BlockDoublePlant
-net.minecraft.block.BlockCarrot
-net.minecraft.block.BlockPotato
// Biomes O'Plenty
biomesoplenty.common.blocks.BlockBOPFlower
biomesoplenty.common.blocks.BlockBOPFlower2
// Tinkers' Construct
tconstruct.blocks.slime.SlimeTallGrass
// Plant Mega Pack
plantmegapack.block.PMPBlockBerrybush
plantmegapack.block.PMPBlockCrops
plantmegapack.block.PMPBlockDesert
plantmegapack.block.PMPBlockFern
plantmegapack.block.PMPBlockFlowerMulti
plantmegapack.block.PMPBlockFlowerSingle
plantmegapack.block.PMPBlockForest
plantmegapack.block.PMPBlockGrass
plantmegapack.block.PMPBlockJungle
plantmegapack.block.PMPBlockMountain
plantmegapack.block.PMPBlockSavanna
plantmegapack.block.PMPBlockShrub
plantmegapack.block.PMPBlockWetlands
// Pam's HarvestCraft
com.pam.harvestcraft.BlockPamCrop
com.pam.harvestcraft.BlockPamDesertGarden
com.pam.harvestcraft.BlockPamNormalGarden
com.pam.harvestcraft.BlockPamWaterGarden

View File

@@ -1,4 +0,0 @@
net.minecraft.block.BlockLeavesBase
forestry.arboriculture.gadgets.BlockLeaves
thaumcraft.common.blocks.BlockMagicalLeaves
-tconstruct.blocks.OreberryBushEssence

View File

@@ -12,7 +12,6 @@ message.betterfoliage.betterCactus=Better Cactus: %s
message.betterfoliage.betterLilypad=Better Lilypad: %s message.betterfoliage.betterLilypad=Better Lilypad: %s
message.betterfoliage.betterReed=Reeds: %s message.betterfoliage.betterReed=Reeds: %s
message.betterfoliage.betterAlgae=Algae: %s message.betterfoliage.betterAlgae=Algae: %s
message.betterfoliage.betterCoral=Coral: %s
message.betterfoliage.size=Size message.betterfoliage.size=Size
message.betterfoliage.hOffset=H.Offset message.betterfoliage.hOffset=H.Offset
@@ -20,12 +19,8 @@ message.betterfoliage.vOffset=V.Offset
message.betterfoliage.minHeight=Min.Height message.betterfoliage.minHeight=Min.Height
message.betterfoliage.maxHeight=Max.Height message.betterfoliage.maxHeight=Max.Height
message.betterfoliage.flowerChance=Flower Chance message.betterfoliage.flowerChance=Flower Chance
message.betterfoliage.reedChance=Reed Population message.betterfoliage.reedChance=Reed Chance
message.betterfoliage.leavesMode=Leaves Offset: %s message.betterfoliage.leavesMode=Leaves Offset: %s
message.betterfoliage.genShortgrass=Use generated: %s
message.betterfoliage.leavesSkew=Skew message.betterfoliage.leavesSkew=Skew
message.betterfoliage.leavesTranslate=Translate message.betterfoliage.leavesTranslate=Translate
message.betterfoliage.algaeChance=Algae Population message.betterfoliage.algaeChance=Algae Chance
message.betterfoliage.crustSize=Crust Size
message.betterfoliage.coralChance=Coral Chance
message.betterfoliage.coralPopulation=Coral Population