Compare commits
10 Commits
untagged-2
...
0.9.9b
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
9d9d32b32a | ||
|
|
6623bee39f | ||
|
|
ffa8dd724e | ||
|
|
bd4a4885fe | ||
|
|
9d59105af1 | ||
|
|
7cdddef1bf | ||
|
|
168fad883d | ||
|
|
572d517828 | ||
|
|
d4963ec173 | ||
|
|
ad83a511fb |
@@ -22,7 +22,7 @@ minecraft {
|
||||
|
||||
jar.baseName = 'BetterFoliage'
|
||||
group = 'com.github.octarine-noise'
|
||||
version='0.9.7b-hotfix1'
|
||||
version='0.9.9b'
|
||||
|
||||
processResources {
|
||||
inputs.property "version", project.version
|
||||
|
||||
@@ -1,23 +1,23 @@
|
||||
package mods.betterfoliage.client;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.util.Map;
|
||||
|
||||
import mods.betterfoliage.BetterFoliage;
|
||||
import mods.betterfoliage.client.render.IRenderBlockDecorator;
|
||||
import mods.betterfoliage.client.render.impl.RenderBlockBetterAlgae;
|
||||
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.RenderBlockBetterLeaves;
|
||||
import mods.betterfoliage.client.render.impl.RenderBlockBetterLilypad;
|
||||
import mods.betterfoliage.client.render.impl.RenderBlockBetterReed;
|
||||
import mods.betterfoliage.client.resource.BlockTextureGenerator;
|
||||
import mods.betterfoliage.client.resource.HalfTextureResource;
|
||||
import mods.betterfoliage.client.resource.LeafTextureGenerator;
|
||||
import mods.betterfoliage.client.resource.LeafGenerator;
|
||||
import mods.betterfoliage.client.resource.LeafTextureEnumerator;
|
||||
import mods.betterfoliage.client.resource.ReedGenerator;
|
||||
import mods.betterfoliage.client.resource.ShortGrassGenerator;
|
||||
import net.minecraft.block.Block;
|
||||
import net.minecraft.client.renderer.texture.TextureAtlasSprite;
|
||||
import net.minecraft.client.resources.IResource;
|
||||
import net.minecraft.util.ResourceLocation;
|
||||
import net.minecraft.world.IBlockAccess;
|
||||
import net.minecraftforge.common.MinecraftForge;
|
||||
@@ -30,11 +30,13 @@ import cpw.mods.fml.common.FMLCommonHandler;
|
||||
public class BetterFoliageClient {
|
||||
|
||||
public static Map<Integer, IRenderBlockDecorator> decorators = Maps.newHashMap();
|
||||
public static LeafTextureGenerator leafGenerator;
|
||||
public static LeafGenerator leafGenerator;
|
||||
|
||||
public static BlockMatcher leaves = new BlockMatcher();
|
||||
public static BlockMatcher crops = new BlockMatcher();
|
||||
|
||||
public static ResourceLocation missingTexture = new ResourceLocation("betterfoliage", "textures/blocks/missing_leaf.png");
|
||||
|
||||
public static void preInit() {
|
||||
FMLCommonHandler.instance().bus().register(new KeyHandler());
|
||||
|
||||
@@ -45,6 +47,7 @@ public class BetterFoliageClient {
|
||||
registerRenderer(new RenderBlockBetterLilypad());
|
||||
registerRenderer(new RenderBlockBetterReed());
|
||||
registerRenderer(new RenderBlockBetterAlgae());
|
||||
registerRenderer(new RenderBlockBetterCoral());
|
||||
|
||||
leaves.load(new File(BetterFoliage.configDir, "classesLeaves.cfg"), new ResourceLocation("betterfoliage:classesLeavesDefault.cfg"));
|
||||
MinecraftForge.EVENT_BUS.register(leaves);
|
||||
@@ -52,24 +55,15 @@ public class BetterFoliageClient {
|
||||
crops.load(new File(BetterFoliage.configDir, "classesCrops.cfg"), new ResourceLocation("betterfoliage:classesCropsDefault.cfg"));
|
||||
MinecraftForge.EVENT_BUS.register(crops);
|
||||
|
||||
BetterFoliage.log.info("Registering leaf texture generator");
|
||||
leafGenerator = new LeafTextureGenerator();
|
||||
MinecraftForge.EVENT_BUS.register(leafGenerator);
|
||||
MinecraftForge.EVENT_BUS.register(new LeafTextureEnumerator("bf_leaves"));
|
||||
|
||||
MinecraftForge.EVENT_BUS.register(new BlockTextureGenerator("bf_reed_bottom", new ResourceLocation("betterfoliage", "textures/blocks/missing_leaf.png")) {
|
||||
@Override
|
||||
public IResource getResource(ResourceLocation var1) throws IOException {
|
||||
return new HalfTextureResource(unwrapResource(var1), true, getMissingResource());
|
||||
}
|
||||
});
|
||||
MinecraftForge.EVENT_BUS.register(new BlockTextureGenerator("bf_reed_top", new ResourceLocation("betterfoliage", "textures/blocks/missing_leaf.png")) {
|
||||
@Override
|
||||
public IResource getResource(ResourceLocation var1) throws IOException {
|
||||
return new HalfTextureResource(unwrapResource(var1), false, getMissingResource());
|
||||
}
|
||||
});
|
||||
|
||||
MinecraftForge.EVENT_BUS.register(new BetterFoliageClient());
|
||||
BetterFoliage.log.info("Registering texture generators");
|
||||
leafGenerator = new LeafGenerator("bf_leaves", missingTexture);
|
||||
MinecraftForge.EVENT_BUS.register(leafGenerator);
|
||||
MinecraftForge.EVENT_BUS.register(new ReedGenerator("bf_reed_bottom", missingTexture, true));
|
||||
MinecraftForge.EVENT_BUS.register(new ReedGenerator("bf_reed_top", missingTexture, false));
|
||||
MinecraftForge.EVENT_BUS.register(new ShortGrassGenerator("bf_shortgrass", missingTexture, false));
|
||||
MinecraftForge.EVENT_BUS.register(new ShortGrassGenerator("bf_shortgrass_snow", missingTexture, true));
|
||||
|
||||
ShadersModIntegration.init();
|
||||
}
|
||||
|
||||
@@ -4,6 +4,7 @@ import java.lang.reflect.Field;
|
||||
|
||||
import net.minecraft.block.Block;
|
||||
import net.minecraft.init.Blocks;
|
||||
import net.minecraft.util.ResourceLocation;
|
||||
|
||||
public class ShadersModIntegration {
|
||||
|
||||
@@ -52,4 +53,8 @@ public class ShadersModIntegration {
|
||||
if (BetterFoliageClient.crops.matchesID(original & 0xFFFF)) return tallGrassEntityData;
|
||||
return original;
|
||||
}
|
||||
|
||||
public static boolean isSpecialTexture(ResourceLocation resource) {
|
||||
return resource.getResourcePath().toLowerCase().endsWith("_n.png") || resource.getResourcePath().toLowerCase().endsWith("_s.png");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,34 @@
|
||||
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);
|
||||
}
|
||||
}
|
||||
@@ -9,24 +9,32 @@ import cpw.mods.fml.client.FMLClientHandler;
|
||||
|
||||
public class ConfigGuiGrass extends ConfigGuiScreenBase {
|
||||
|
||||
public enum Button {CLOSE, GRASS_USE_GENERATED}
|
||||
|
||||
public ConfigGuiGrass(GuiScreen parent) {
|
||||
super(parent);
|
||||
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.grassHOffset, -100, -40, 200, 50, id++, id++, "message.betterfoliage.hOffset", "%.3f"));
|
||||
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, 20, 200, 50, id++, id++, "message.betterfoliage.maxHeight", "%.2f"));
|
||||
widgets.add(new OptionDoubleWidget(BetterFoliage.config.grassHOffset, -100, -10, 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.grassHeightMax, -100, 50, 200, 50, id++, id++, "message.betterfoliage.maxHeight", "%.2f"));
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
@Override
|
||||
public void addButtons(int x, int y) {
|
||||
buttonList.add(new GuiButton(0, x - 50, y + 50, 100, 20, I18n.format("message.betterfoliage.back")));
|
||||
buttonList.add(new GuiButton(Button.CLOSE.ordinal(), x - 50, y + 80, 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
|
||||
protected void onButtonPress(int id) {
|
||||
if (id == 0) FMLClientHandler.instance().showGuiScreen(parent);
|
||||
if (id == Button.CLOSE.ordinal()) 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;
|
||||
}
|
||||
|
||||
@@ -18,7 +18,8 @@ public class ConfigGuiMain extends ConfigGuiScreenBase {
|
||||
TOGGLE_CACTUS, CONFIG_CACTUS,
|
||||
TOGGLE_LILYPAD, CONFIG_LILYPAD,
|
||||
TOGGLE_REED, CONFIG_REED,
|
||||
TOGGLE_ALGAE, CONFIG_ALGAE}
|
||||
TOGGLE_ALGAE, CONFIG_ALGAE,
|
||||
TOGGLE_CORAL, CONFIG_CORAL}
|
||||
|
||||
public ConfigGuiMain(GuiScreen parent) {
|
||||
super(parent);
|
||||
@@ -28,7 +29,7 @@ public class ConfigGuiMain extends ConfigGuiScreenBase {
|
||||
@SuppressWarnings("unchecked")
|
||||
@Override
|
||||
protected void addButtons(int x, int y) {
|
||||
buttonList.add(new GuiButton(Button.CLOSE.ordinal(), x - 50, y + 80, 100, 20, I18n.format("message.betterfoliage.close")));
|
||||
buttonList.add(new GuiButton(Button.CLOSE.ordinal(), x - 50, y + 110, 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.CONFIG_LEAVES.ordinal(), x + 60, y - 100, 40, 20, I18n.format("message.betterfoliage.config")));
|
||||
@@ -47,6 +48,9 @@ public class ConfigGuiMain extends ConfigGuiScreenBase {
|
||||
|
||||
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.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() {
|
||||
@@ -56,6 +60,7 @@ public class ConfigGuiMain extends ConfigGuiScreenBase {
|
||||
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_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;
|
||||
}
|
||||
|
||||
@@ -72,12 +77,14 @@ public class ConfigGuiMain extends ConfigGuiScreenBase {
|
||||
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_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_GRASS.ordinal()) FMLClientHandler.instance().showGuiScreen(new ConfigGuiGrass(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_ALGAE.ordinal()) FMLClientHandler.instance().showGuiScreen(new ConfigGuiAlgae(this));
|
||||
if (id== Button.CONFIG_CORAL.ordinal()) FMLClientHandler.instance().showGuiScreen(new ConfigGuiCoral(this));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -37,6 +37,9 @@ public class RenderBlockAOBase extends RenderBlocks {
|
||||
public float red;
|
||||
public float green;
|
||||
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};
|
||||
|
||||
@@ -43,6 +43,13 @@ public class RenderBlockBetterAlgae extends RenderBlockAOBase implements IRender
|
||||
// store world for later use
|
||||
blockAccess = world;
|
||||
|
||||
// use original renderer for block breaking overlay
|
||||
if (renderer.hasOverrideBlockTexture()) {
|
||||
renderer.setRenderBoundsFromBlock(block);
|
||||
renderer.renderStandardBlock(block, x, y, z);
|
||||
return true;
|
||||
}
|
||||
|
||||
// render dirt block
|
||||
setPassCounters(1);
|
||||
setRenderBoundsFromBlock(block);
|
||||
|
||||
@@ -35,9 +35,14 @@ public class RenderBlockBetterCactus extends FakeRenderBlockAOBase implements IR
|
||||
// store world for later use
|
||||
blockAccess = world;
|
||||
|
||||
// use original renderer for block breaking overlay
|
||||
if (renderer.hasOverrideBlockTexture()) {
|
||||
renderer.renderBlockCactus(block, x, y, z);
|
||||
return true;
|
||||
}
|
||||
|
||||
// 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);
|
||||
|
||||
@@ -0,0 +1,105 @@
|
||||
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;
|
||||
|
||||
// use original renderer for block breaking overlay
|
||||
if (renderer.hasOverrideBlockTexture()) {
|
||||
renderer.setRenderBoundsFromBlock(block);
|
||||
renderer.renderStandardBlock(block, x, y, z);
|
||||
return true;
|
||||
}
|
||||
|
||||
// render sand block
|
||||
setPassCounters(1);
|
||||
setRenderBoundsFromBlock(block);
|
||||
renderStandardBlock(block, x, y, z);
|
||||
|
||||
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));
|
||||
}
|
||||
}
|
||||
@@ -23,13 +23,15 @@ import cpw.mods.fml.relauncher.SideOnly;
|
||||
public class RenderBlockBetterGrass extends RenderBlockAOBase implements IRenderBlockDecorator {
|
||||
|
||||
public IconSet grassIcons = new IconSet("bettergrassandleaves", "better_grass_long_%d");
|
||||
public IconSet snowGrassIcons = new IconSet("bettergrassandleaves", "better_grass_snowed_%d");
|
||||
public IconSet myceliumIcons = new IconSet("bettergrassandleaves", "better_mycel_%d");
|
||||
|
||||
public IIcon grassGenIcon;
|
||||
public IIcon snowGrassGenIcon;
|
||||
|
||||
public boolean isBlockAccepted(IBlockAccess blockAccess, int x, int y, int z, Block block, int original) {
|
||||
if (!BetterFoliage.config.grassEnabled) return false;
|
||||
if (!((block instanceof BlockGrass || block == Blocks.mycelium))) return false;
|
||||
if (y == 255 || !blockAccess.isAirBlock(x, y + 1, z)) return false;
|
||||
if (!blockAccess.isAirBlock(x, y + 1, z) && blockAccess.getBlock(x, y + 1, z) != Blocks.snow_layer) return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -37,6 +39,13 @@ public class RenderBlockBetterGrass extends RenderBlockAOBase implements IRender
|
||||
// store world for later use
|
||||
blockAccess = world;
|
||||
|
||||
// use original renderer for block breaking overlay
|
||||
if (renderer.hasOverrideBlockTexture()) {
|
||||
renderer.setRenderBoundsFromBlock(block);
|
||||
renderer.renderStandardBlock(block, x, y, z);
|
||||
return true;
|
||||
}
|
||||
|
||||
// render grass block
|
||||
setPassCounters(1);
|
||||
setRenderBoundsFromBlock(block);
|
||||
@@ -44,17 +53,32 @@ public class RenderBlockBetterGrass extends RenderBlockAOBase implements IRender
|
||||
|
||||
int variation = getSemiRandomFromPos(x, y, z, 0);
|
||||
int heightVariation = getSemiRandomFromPos(x, y, z, 1);
|
||||
boolean isSnowed = blockAccess.getBlock(x, y + 1, z) == Blocks.snow_layer;
|
||||
|
||||
IIcon renderIcon = (block == Blocks.mycelium) ? myceliumIcons.get(variation) : grassIcons.get(variation);
|
||||
IIcon renderIcon = null;
|
||||
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;
|
||||
|
||||
double scale = BetterFoliage.config.grassSize.value * 0.5;
|
||||
double halfHeight = 0.5 * (BetterFoliage.config.grassHeightMin.value + pRand[heightVariation] * (BetterFoliage.config.grassHeightMax.value - BetterFoliage.config.grassHeightMin.value));
|
||||
|
||||
if (isSnowed) {
|
||||
aoYPXZNN.setGray(0.9f); aoYPXZNP.setGray(0.9f); aoYPXZPN.setGray(0.9f); aoYPXZPP.setGray(0.9f);
|
||||
Tessellator.instance.setColorOpaque(230, 230, 230);
|
||||
}
|
||||
|
||||
// render short grass
|
||||
ShadersModIntegration.startGrassQuads();
|
||||
Tessellator.instance.setBrightness(getBrightness(block, x, y + 1, z));
|
||||
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);
|
||||
renderCrossedSideQuads(new Double3(x + 0.5, y + 1.0 + (isSnowed ? 0.0625 : 0.0), z + 0.5), ForgeDirection.UP, scale, halfHeight, pRot[variation], BetterFoliage.config.grassHOffset.value, renderIcon, 0, false);
|
||||
|
||||
return true;
|
||||
}
|
||||
@@ -64,8 +88,12 @@ public class RenderBlockBetterGrass extends RenderBlockAOBase implements IRender
|
||||
if (event.map.getTextureType() != 0) return;
|
||||
|
||||
grassIcons.registerIcons(event.map);
|
||||
snowGrassIcons.registerIcons(event.map);
|
||||
myceliumIcons.registerIcons(event.map);
|
||||
grassGenIcon = event.map.registerIcon("bf_shortgrass:minecraft:tallgrass");
|
||||
snowGrassGenIcon = event.map.registerIcon("bf_shortgrass_snow:minecraft:tallgrass");
|
||||
BetterFoliage.log.info(String.format("Found %d short grass textures", grassIcons.numLoaded));
|
||||
BetterFoliage.log.info(String.format("Found %d snowy grass textures", snowGrassIcons.numLoaded));
|
||||
BetterFoliage.log.info(String.format("Found %d mycelium textures", myceliumIcons.numLoaded));
|
||||
}
|
||||
|
||||
|
||||
@@ -31,6 +31,13 @@ public class RenderBlockBetterLeaves extends RenderBlockAOBase implements IRende
|
||||
// store world for later use
|
||||
blockAccess = world;
|
||||
|
||||
// use original renderer for block breaking overlay
|
||||
if (renderer.hasOverrideBlockTexture()) {
|
||||
renderer.setRenderBoundsFromBlock(block);
|
||||
renderer.renderStandardBlock(block, x, y, z);
|
||||
return true;
|
||||
}
|
||||
|
||||
// render leaves center
|
||||
setPassCounters(1);
|
||||
setRenderBoundsFromBlock(block);
|
||||
|
||||
@@ -30,6 +30,12 @@ public class RenderBlockBetterLilypad extends FakeRenderBlockAOBase implements I
|
||||
// store world for later use
|
||||
blockAccess = world;
|
||||
|
||||
// use original renderer for block breaking overlay
|
||||
if (renderer.hasOverrideBlockTexture()) {
|
||||
renderer.renderBlockLilyPad(block, x, y, z);
|
||||
return true;
|
||||
}
|
||||
|
||||
// render lilypad block
|
||||
renderBlockLilyPad(block, x, y, z);
|
||||
|
||||
|
||||
@@ -45,6 +45,13 @@ public class RenderBlockBetterReed extends RenderBlockAOBase implements IRenderB
|
||||
// store world for later use
|
||||
blockAccess = world;
|
||||
|
||||
// use original renderer for block breaking overlay
|
||||
if (renderer.hasOverrideBlockTexture()) {
|
||||
renderer.setRenderBoundsFromBlock(block);
|
||||
renderer.renderStandardBlock(block, x, y, z);
|
||||
return true;
|
||||
}
|
||||
|
||||
// render dirt block
|
||||
setPassCounters(1);
|
||||
setRenderBoundsFromBlock(block);
|
||||
|
||||
@@ -33,32 +33,22 @@ public abstract class BlockTextureGenerator implements IResourceManager {
|
||||
/** Texture atlas for block textures used in the current run */
|
||||
public TextureMap blockTextures;
|
||||
|
||||
/** Number of textures generated in the current run */
|
||||
int counter = 0;
|
||||
|
||||
public BlockTextureGenerator(String domainName, ResourceLocation missingResource) {
|
||||
this.domainName = domainName;
|
||||
this.missingResource = missingResource;
|
||||
}
|
||||
|
||||
public void onStitchStart(TextureStitchEvent.Pre event) {}
|
||||
|
||||
public void onStitchEnd(TextureStitchEvent.Post event) {}
|
||||
|
||||
@SubscribeEvent
|
||||
public void handleTextureReload(TextureStitchEvent.Pre event) {
|
||||
if (event.map.getTextureType() != 0) return;
|
||||
|
||||
blockTextures = event.map;
|
||||
counter = 0;
|
||||
|
||||
Map<String, IResourceManager> domainManagers = Utils.getDomainResourceManagers();
|
||||
if (domainManagers == null) {
|
||||
BetterFoliage.log.warn("Failed to inject texture generator");
|
||||
return;
|
||||
}
|
||||
domainManagers.put(domainName, this);
|
||||
|
||||
onStitchStart(event);
|
||||
}
|
||||
|
||||
@SubscribeEvent
|
||||
@@ -69,8 +59,6 @@ public abstract class BlockTextureGenerator implements IResourceManager {
|
||||
// don't leave a mess
|
||||
Map<String, IResourceManager> domainManagers = Utils.getDomainResourceManagers();
|
||||
if (domainManagers != null) domainManagers.remove(domainName);
|
||||
|
||||
onStitchEnd(event);
|
||||
}
|
||||
|
||||
public Set<String> getResourceDomains() {
|
||||
@@ -88,4 +76,13 @@ public abstract class BlockTextureGenerator implements IResourceManager {
|
||||
public ResourceLocation unwrapResource(ResourceLocation wrapped) {
|
||||
return new ResourceLocation(wrapped.getResourcePath().substring(16));
|
||||
}
|
||||
|
||||
protected static int blendRGB(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;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,44 @@
|
||||
package mods.betterfoliage.client.resource;
|
||||
|
||||
import java.awt.image.BufferedImage;
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
|
||||
import javax.imageio.ImageIO;
|
||||
|
||||
import net.minecraft.client.resources.IResource;
|
||||
import net.minecraft.client.resources.data.IMetadataSection;
|
||||
|
||||
public class BufferedImageResource implements IResource {
|
||||
|
||||
/** Raw PNG data*/
|
||||
protected byte[] data = null;
|
||||
|
||||
public BufferedImageResource(BufferedImage image) {
|
||||
// create PNG image
|
||||
try {
|
||||
ByteArrayOutputStream baos = new ByteArrayOutputStream();
|
||||
ImageIO.write(image, "PNG", baos);
|
||||
data = baos.toByteArray();
|
||||
} catch (IOException e) {
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public InputStream getInputStream() {
|
||||
return data == null ? null : new ByteArrayInputStream(data);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasMetadata() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public IMetadataSection getMetadata(String var1) {
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,74 +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.FileNotFoundException;
|
||||
import java.io.InputStream;
|
||||
|
||||
import javax.imageio.ImageIO;
|
||||
|
||||
import cpw.mods.fml.relauncher.Side;
|
||||
import cpw.mods.fml.relauncher.SideOnly;
|
||||
|
||||
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;
|
||||
|
||||
/** {@link IResource} of PNG containing one half (top or bottom) of a given texture resource
|
||||
* @author octarine-noise
|
||||
*/
|
||||
@SideOnly(Side.CLIENT)
|
||||
public class HalfTextureResource implements IResource {
|
||||
|
||||
/** Raw PNG data*/
|
||||
public byte[] data = null;
|
||||
|
||||
/** Resource to return if generation fails */
|
||||
public IResource fallbackResource;
|
||||
|
||||
public HalfTextureResource(ResourceLocation resource, boolean bottom, IResource fallbackResource) {
|
||||
this.fallbackResource = fallbackResource;
|
||||
|
||||
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 half texture
|
||||
BufferedImage result = new BufferedImage(origImage.getWidth(), origImage.getHeight() / 2, BufferedImage.TYPE_4BYTE_ABGR);
|
||||
Graphics2D graphics = result.createGraphics();
|
||||
graphics.drawImage(origImage, 0, bottom ? -origImage.getHeight() / 2 : 0, null);
|
||||
|
||||
// create PNG image
|
||||
ByteArrayOutputStream baos = new ByteArrayOutputStream();
|
||||
ImageIO.write(result, "PNG", baos);
|
||||
data = baos.toByteArray();
|
||||
} catch (Exception e) {
|
||||
// stop log spam with GLSL installed
|
||||
if (e instanceof FileNotFoundException) return;
|
||||
BetterFoliage.log.info(String.format("Could not load texture: %s, exception: %s", resource.toString(), e.getClass().getSimpleName()));
|
||||
}
|
||||
}
|
||||
|
||||
@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;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,130 @@
|
||||
package mods.betterfoliage.client.resource;
|
||||
|
||||
import java.awt.Graphics2D;
|
||||
import java.awt.image.BufferedImage;
|
||||
import java.io.IOException;
|
||||
|
||||
import javax.imageio.ImageIO;
|
||||
|
||||
import cpw.mods.fml.common.eventhandler.SubscribeEvent;
|
||||
|
||||
import mods.betterfoliage.BetterFoliage;
|
||||
import mods.betterfoliage.client.ShadersModIntegration;
|
||||
import mods.betterfoliage.common.util.Utils;
|
||||
import net.minecraft.client.Minecraft;
|
||||
import net.minecraft.client.resources.IResource;
|
||||
import net.minecraft.client.resources.IResourceManager;
|
||||
import net.minecraft.util.ResourceLocation;
|
||||
import net.minecraftforge.client.event.TextureStitchEvent.Post;
|
||||
import net.minecraftforge.client.event.TextureStitchEvent.Pre;
|
||||
|
||||
public class LeafGenerator extends BlockTextureGenerator {
|
||||
|
||||
/** Resource domain name of pre-drawn textures */
|
||||
public String nonGeneratedDomain = "betterfoliage";
|
||||
|
||||
/** Number of textures generated in the current run */
|
||||
public int generatedCounter = 0;
|
||||
|
||||
/** Number of pre-drawn textures found in the current run */
|
||||
public int drawnCounter = 0;
|
||||
|
||||
/** Name of the default alpha mask to use */
|
||||
public static String defaultMask = "rough";
|
||||
|
||||
public LeafGenerator(String domainName, ResourceLocation missingResource) {
|
||||
super(domainName, missingResource);
|
||||
}
|
||||
|
||||
@Override
|
||||
public IResource getResource(ResourceLocation resourceLocation) throws IOException {
|
||||
IResourceManager resourceManager = Minecraft.getMinecraft().getResourceManager();
|
||||
ResourceLocation originalNoDirs = unwrapResource(resourceLocation);
|
||||
ResourceLocation originalWithDirs = new ResourceLocation(originalNoDirs.getResourceDomain(), "textures/blocks/" + originalNoDirs.getResourcePath());
|
||||
|
||||
// check for provided texture
|
||||
ResourceLocation handDrawnLocation = new ResourceLocation(nonGeneratedDomain, String.format("textures/blocks/%s/%s", originalNoDirs.getResourceDomain(), originalNoDirs.getResourcePath()));
|
||||
if (Utils.resourceExists(handDrawnLocation)) {
|
||||
drawnCounter++;
|
||||
return resourceManager.getResource(handDrawnLocation);
|
||||
}
|
||||
|
||||
// generate our own
|
||||
if (!Utils.resourceExists(originalWithDirs)) return getMissingResource();
|
||||
|
||||
// load normal leaf texture
|
||||
BufferedImage origImage = ImageIO.read(resourceManager.getResource(originalWithDirs).getInputStream());
|
||||
if (origImage.getWidth() != origImage.getHeight()) return getMissingResource();
|
||||
int size = origImage.getWidth();
|
||||
|
||||
// tile leaf texture 2x2
|
||||
BufferedImage overlayIcon = new BufferedImage(size * 2, size * 2, BufferedImage.TYPE_4BYTE_ABGR);
|
||||
Graphics2D graphics = overlayIcon.createGraphics();
|
||||
graphics.drawImage(origImage, 0, 0, null);
|
||||
graphics.drawImage(origImage, 0, size, null);
|
||||
graphics.drawImage(origImage, size, 0, null);
|
||||
graphics.drawImage(origImage, size, size, null);
|
||||
|
||||
// overlay mask alpha on texture
|
||||
if (!ShadersModIntegration.isSpecialTexture(originalWithDirs)) {
|
||||
// load alpha mask of appropriate size
|
||||
BufferedImage maskImage = loadLeafMaskImage(defaultMask, size * 2);
|
||||
int scale = size * 2 / maskImage.getWidth();
|
||||
|
||||
for (int x = 0; x < overlayIcon.getWidth(); x++) {
|
||||
for (int y = 0; y < overlayIcon.getHeight(); y++) {
|
||||
long origPixel = overlayIcon.getRGB(x, y) & 0xFFFFFFFFl;
|
||||
long maskPixel = maskImage.getRGB(x / scale, y / scale) & 0xFF000000l | 0x00FFFFFF;
|
||||
overlayIcon.setRGB(x, y, (int) (origPixel & maskPixel));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
generatedCounter++;
|
||||
return new BufferedImageResource(overlayIcon);
|
||||
}
|
||||
|
||||
/** Loads the alpha mask of the given type and size. If a mask of the exact size can not be found,
|
||||
* will try to load progressively smaller masks down to 16x16
|
||||
* @param type mask type
|
||||
* @param size texture size
|
||||
* @return alpha mask
|
||||
*/
|
||||
protected BufferedImage loadLeafMaskImage(String type, int size) {
|
||||
IResourceManager resourceManager = Minecraft.getMinecraft().getResourceManager();
|
||||
IResource maskResource = null;
|
||||
|
||||
while (maskResource == null && size >= 16) {
|
||||
try {
|
||||
maskResource = resourceManager.getResource(new ResourceLocation(String.format("betterfoliage:textures/blocks/leafmask_%d_%s.png", size, type)));
|
||||
} catch (Exception e) {}
|
||||
size /= 2;
|
||||
}
|
||||
|
||||
try {
|
||||
return maskResource == null ? null : ImageIO.read(maskResource.getInputStream());
|
||||
} catch (IOException e) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
@SubscribeEvent
|
||||
public void handleTextureReload(Pre event) {
|
||||
super.handleTextureReload(event);
|
||||
if (event.map.getTextureType() != 0) return;
|
||||
generatedCounter = 0;
|
||||
drawnCounter = 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
@SubscribeEvent
|
||||
public void endTextureReload(Post event) {
|
||||
super.endTextureReload(event);
|
||||
if (event.map.getTextureType() != 0) return;
|
||||
BetterFoliage.log.info(String.format("Found %d pre-drawn leaf textures", drawnCounter));
|
||||
BetterFoliage.log.info(String.format("Found %d leaf textures", generatedCounter));
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -1,6 +1,5 @@
|
||||
package mods.betterfoliage.client.resource;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.Iterator;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
@@ -10,50 +9,29 @@ import mods.betterfoliage.client.BetterFoliageClient;
|
||||
import mods.betterfoliage.common.util.Utils;
|
||||
import mods.betterfoliage.loader.DeobfHelper;
|
||||
import net.minecraft.block.Block;
|
||||
import net.minecraft.client.Minecraft;
|
||||
import net.minecraft.client.renderer.texture.IIconRegister;
|
||||
import net.minecraft.client.renderer.texture.TextureAtlasSprite;
|
||||
import net.minecraft.client.resources.IResource;
|
||||
import net.minecraft.client.renderer.texture.TextureMap;
|
||||
import net.minecraft.util.IIcon;
|
||||
import net.minecraft.util.ResourceLocation;
|
||||
import net.minecraftforge.client.event.TextureStitchEvent.Post;
|
||||
import net.minecraftforge.client.event.TextureStitchEvent.Pre;
|
||||
import net.minecraftforge.client.event.TextureStitchEvent;
|
||||
|
||||
import com.google.common.collect.Sets;
|
||||
|
||||
import cpw.mods.fml.relauncher.Side;
|
||||
import cpw.mods.fml.relauncher.SideOnly;
|
||||
import cpw.mods.fml.common.eventhandler.SubscribeEvent;
|
||||
|
||||
/** Generates rounded crossleaf textures for all registered normal leaf textures at stitch time.
|
||||
* @author octarine-noise
|
||||
*/
|
||||
@SideOnly(Side.CLIENT)
|
||||
public class LeafTextureGenerator extends BlockTextureGenerator implements IIconRegister {
|
||||
public class LeafTextureEnumerator implements IIconRegister {
|
||||
|
||||
public String nonGeneratedDomain = "betterfoliage";
|
||||
/** Resource domain name of generated textures */
|
||||
public String domainName;
|
||||
|
||||
public int nonGeneratedCounter = 0;
|
||||
/** Texture atlas for block textures used in the current run */
|
||||
public TextureMap blockTextures;
|
||||
|
||||
public LeafTextureGenerator() {
|
||||
super("bf_leaves_autogen", new ResourceLocation("betterfoliage", "textures/blocks/missing_leaf.png"));
|
||||
public LeafTextureEnumerator(String domainName) {
|
||||
this.domainName = domainName;
|
||||
}
|
||||
|
||||
public IResource getResource(ResourceLocation resourceLocation) throws IOException {
|
||||
ResourceLocation original = unwrapResource(resourceLocation);
|
||||
|
||||
// check for provided texture
|
||||
ResourceLocation handDrawnLocation = new ResourceLocation(nonGeneratedDomain, String.format("textures/blocks/%s/%s", original.getResourceDomain(), original.getResourcePath()));
|
||||
if (Utils.resourceExists(handDrawnLocation)) {
|
||||
nonGeneratedCounter++;
|
||||
return Minecraft.getMinecraft().getResourceManager().getResource(handDrawnLocation);
|
||||
}
|
||||
|
||||
// generate our own
|
||||
LeafTextureResource result = new LeafTextureResource(original, getMissingResource());
|
||||
if (result.data != null) counter++;
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
/** Leaf blocks register their textures here. An extra texture will be registered in the atlas
|
||||
* for each, with the resource domain of this generator.
|
||||
* @return the originally registered {@link IIcon} already in the atlas
|
||||
@@ -69,10 +47,12 @@ public class LeafTextureGenerator extends BlockTextureGenerator implements IIcon
|
||||
* their textures to "sniff out" all leaf textures.
|
||||
* @param event
|
||||
*/
|
||||
@SubscribeEvent
|
||||
@SuppressWarnings("unchecked")
|
||||
@Override
|
||||
public void onStitchStart(Pre event) {
|
||||
nonGeneratedCounter = 0;
|
||||
public void handleTextureReload(TextureStitchEvent.Pre event) {
|
||||
if (event.map.getTextureType() != 0) return;
|
||||
blockTextures = event.map;
|
||||
|
||||
BetterFoliage.log.info("Reloading leaf textures");
|
||||
|
||||
// register simple block textures
|
||||
@@ -102,11 +82,11 @@ public class LeafTextureGenerator extends BlockTextureGenerator implements IIcon
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onStitchEnd(Post event) {
|
||||
BetterFoliage.log.info(String.format("Found %d pre-drawn leaf textures", nonGeneratedCounter));
|
||||
BetterFoliage.log.info(String.format("Generated %d leaf textures", counter));
|
||||
|
||||
@SubscribeEvent
|
||||
public void endTextureReload(TextureStitchEvent.Post event) {
|
||||
if (event.map.getTextureType() != 0) return;
|
||||
blockTextures = null;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -1,122 +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.FileNotFoundException;
|
||||
import java.io.IOException;
|
||||
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;
|
||||
import cpw.mods.fml.relauncher.Side;
|
||||
import cpw.mods.fml.relauncher.SideOnly;
|
||||
|
||||
/** {@link IResource} containing an autogenerated round crossleaf texture
|
||||
* @author octarine-noise
|
||||
*/
|
||||
@SideOnly(Side.CLIENT)
|
||||
public class LeafTextureResource implements IResource {
|
||||
|
||||
/** Raw PNG data*/
|
||||
protected byte[] data = null;
|
||||
|
||||
/** Name of the default alpha mask to use */
|
||||
public static String defaultMask = "rough";
|
||||
|
||||
/** Resource to return if generation fails */
|
||||
public IResource fallbackResource;
|
||||
|
||||
public LeafTextureResource(ResourceLocation resLeaf, IResource fallbackResource) {
|
||||
this.fallbackResource = fallbackResource;
|
||||
|
||||
IResourceManager resourceManager = Minecraft.getMinecraft().getResourceManager();
|
||||
try {
|
||||
ResourceLocation origResource = new ResourceLocation(resLeaf.getResourceDomain(), "textures/blocks/" + resLeaf.getResourcePath());
|
||||
if (origResource.getResourcePath().toLowerCase().endsWith("_n.png") || origResource.getResourcePath().toLowerCase().endsWith("_s.png")) {
|
||||
// Don't alter ShaderMod normal and specular maps
|
||||
fallbackResource = resourceManager.getResource(origResource);
|
||||
return;
|
||||
}
|
||||
|
||||
// load normal leaf texture
|
||||
BufferedImage origImage = ImageIO.read(resourceManager.getResource(origResource).getInputStream());
|
||||
if (origImage.getWidth() != origImage.getHeight()) return;
|
||||
int size = origImage.getWidth();
|
||||
|
||||
// load alpha mask of appropriate size
|
||||
BufferedImage maskImage = loadLeafMaskImage(defaultMask, size * 2);
|
||||
int scale = size * 2 / maskImage.getWidth();
|
||||
|
||||
// tile leaf texture 2x2
|
||||
BufferedImage overlayIcon = new BufferedImage(size * 2, size * 2, BufferedImage.TYPE_4BYTE_ABGR);
|
||||
Graphics2D graphics = overlayIcon.createGraphics();
|
||||
graphics.drawImage(origImage, 0, 0, null);
|
||||
graphics.drawImage(origImage, 0, size, null);
|
||||
graphics.drawImage(origImage, size, 0, null);
|
||||
graphics.drawImage(origImage, size, size, null);
|
||||
|
||||
// overlay mask alpha on texture
|
||||
for (int x = 0; x < overlayIcon.getWidth(); x++) {
|
||||
for (int y = 0; y < overlayIcon.getHeight(); y++) {
|
||||
long origPixel = overlayIcon.getRGB(x, y) & 0xFFFFFFFFl;
|
||||
long maskPixel = maskImage.getRGB(x / scale, y / scale) & 0xFF000000l | 0x00FFFFFF;
|
||||
overlayIcon.setRGB(x, y, (int) (origPixel & maskPixel));
|
||||
}
|
||||
}
|
||||
|
||||
// create PNG image
|
||||
ByteArrayOutputStream baos = new ByteArrayOutputStream();
|
||||
ImageIO.write(overlayIcon, "PNG", baos);
|
||||
data = baos.toByteArray();
|
||||
} catch (Exception e) {
|
||||
// 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()));
|
||||
}
|
||||
}
|
||||
|
||||
/** Loads the alpha mask of the given type and size. If a mask of the exact size can not be found,
|
||||
* will try to load progressively smaller masks down to 16x16
|
||||
* @param type mask type
|
||||
* @param size texture size
|
||||
* @return alpha mask
|
||||
*/
|
||||
protected BufferedImage loadLeafMaskImage(String type, int size) {
|
||||
IResourceManager resourceManager = Minecraft.getMinecraft().getResourceManager();
|
||||
IResource maskResource = null;
|
||||
|
||||
while (maskResource == null && size >= 16) {
|
||||
try {
|
||||
maskResource = resourceManager.getResource(new ResourceLocation(String.format("betterfoliage:textures/blocks/leafmask_%d_%s.png", size, type)));
|
||||
} catch (Exception e) {}
|
||||
size /= 2;
|
||||
}
|
||||
|
||||
try {
|
||||
return maskResource == null ? null : ImageIO.read(maskResource.getInputStream());
|
||||
} catch (IOException e) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public InputStream getInputStream() {
|
||||
return data != null ? new ByteArrayInputStream(data) : fallbackResource.getInputStream();
|
||||
}
|
||||
|
||||
public boolean hasMetadata() {
|
||||
return false;
|
||||
}
|
||||
|
||||
public IMetadataSection getMetadata(String var1) {
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,40 @@
|
||||
package mods.betterfoliage.client.resource;
|
||||
|
||||
import java.awt.Graphics2D;
|
||||
import java.awt.image.BufferedImage;
|
||||
import java.io.IOException;
|
||||
|
||||
import javax.imageio.ImageIO;
|
||||
|
||||
import net.minecraft.client.Minecraft;
|
||||
import net.minecraft.client.resources.IResource;
|
||||
import net.minecraft.client.resources.IResourceManager;
|
||||
import net.minecraft.util.ResourceLocation;
|
||||
|
||||
public class ReedGenerator extends BlockTextureGenerator {
|
||||
|
||||
public boolean isBottom;
|
||||
|
||||
public ReedGenerator(String domainName, ResourceLocation missingResource, boolean isBottom) {
|
||||
super(domainName, missingResource);
|
||||
this.isBottom = isBottom;
|
||||
}
|
||||
|
||||
@Override
|
||||
public IResource getResource(ResourceLocation resourceLocation) throws IOException {
|
||||
IResourceManager resourceManager = Minecraft.getMinecraft().getResourceManager();
|
||||
ResourceLocation originalNoDirs = unwrapResource(resourceLocation);
|
||||
ResourceLocation originalWithDirs = new ResourceLocation(originalNoDirs.getResourceDomain(), "textures/blocks/" + originalNoDirs.getResourcePath());
|
||||
|
||||
// load full texture
|
||||
BufferedImage origImage = ImageIO.read(resourceManager.getResource(originalWithDirs).getInputStream());
|
||||
|
||||
// draw half texture
|
||||
BufferedImage result = new BufferedImage(origImage.getWidth(), origImage.getHeight() / 2, BufferedImage.TYPE_4BYTE_ABGR);
|
||||
Graphics2D graphics = result.createGraphics();
|
||||
graphics.drawImage(origImage, 0, isBottom ? -origImage.getHeight() / 2 : 0, null);
|
||||
|
||||
return new BufferedImageResource(result);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,52 @@
|
||||
package mods.betterfoliage.client.resource;
|
||||
|
||||
import java.awt.Graphics2D;
|
||||
import java.awt.image.BufferedImage;
|
||||
import java.io.IOException;
|
||||
|
||||
import javax.imageio.ImageIO;
|
||||
|
||||
import mods.betterfoliage.client.ShadersModIntegration;
|
||||
import net.minecraft.client.Minecraft;
|
||||
import net.minecraft.client.resources.IResource;
|
||||
import net.minecraft.client.resources.IResourceManager;
|
||||
import net.minecraft.util.ResourceLocation;
|
||||
|
||||
public class ShortGrassGenerator extends BlockTextureGenerator {
|
||||
|
||||
protected boolean isSnowed = false;
|
||||
|
||||
protected int snowOriginalWeight = 2;
|
||||
|
||||
protected int snowWhiteWeight = 3;
|
||||
|
||||
public ShortGrassGenerator(String domainName, ResourceLocation missingResource, boolean isSnowed) {
|
||||
super(domainName, missingResource);
|
||||
this.isSnowed = isSnowed;
|
||||
}
|
||||
|
||||
@Override
|
||||
public IResource getResource(ResourceLocation resourceLocation) throws IOException {
|
||||
IResourceManager resourceManager = Minecraft.getMinecraft().getResourceManager();
|
||||
ResourceLocation originalNoDirs = unwrapResource(resourceLocation);
|
||||
ResourceLocation originalWithDirs = new ResourceLocation(originalNoDirs.getResourceDomain(), "textures/blocks/" + originalNoDirs.getResourcePath());
|
||||
|
||||
// load full texture
|
||||
BufferedImage origImage = ImageIO.read(resourceManager.getResource(originalWithDirs).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 && !ShadersModIntegration.isSpecialTexture(originalWithDirs)) {
|
||||
for (int x = 0; x < result.getWidth(); x++) for (int y = 0; y < result.getHeight(); y++) {
|
||||
result.setRGB(x, y, blendRGB(result.getRGB(x, y), 0xFFFFFF, 2, 3));
|
||||
}
|
||||
}
|
||||
|
||||
return new BufferedImageResource(result);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -11,6 +11,9 @@ public class BetterFoliageConfig extends ConfigBase {
|
||||
@CfgElement(category="grass", key="enabled")
|
||||
public boolean grassEnabled = true;
|
||||
|
||||
@CfgElement(category="grass", key="useGenerated")
|
||||
public boolean grassUseGenerated = false;
|
||||
|
||||
@CfgElement(category="cactus", key="enabled")
|
||||
public boolean cactusEnabled = true;
|
||||
|
||||
@@ -23,6 +26,9 @@ public class BetterFoliageConfig extends ConfigBase {
|
||||
@CfgElement(category="algae", key="enabled")
|
||||
public boolean algaeEnabled = true;
|
||||
|
||||
@CfgElement(category="coral", key="enabled")
|
||||
public boolean coralEnabled = true;
|
||||
|
||||
@CfgElement(category="leaves", key="horizontalOffset")
|
||||
public OptionDouble leavesHOffset = new OptionDouble(0.0, 0.4, 0.025, 0.2);
|
||||
|
||||
@@ -79,4 +85,22 @@ public class BetterFoliageConfig extends ConfigBase {
|
||||
|
||||
@CfgElement(category="algae", key="chance")
|
||||
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);
|
||||
}
|
||||
|
||||
@@ -12,6 +12,7 @@ message.betterfoliage.betterCactus=Better Cactus: %s
|
||||
message.betterfoliage.betterLilypad=Better Lilypad: %s
|
||||
message.betterfoliage.betterReed=Reeds: %s
|
||||
message.betterfoliage.betterAlgae=Algae: %s
|
||||
message.betterfoliage.betterCoral=Coral: %s
|
||||
|
||||
message.betterfoliage.size=Size
|
||||
message.betterfoliage.hOffset=H.Offset
|
||||
@@ -19,8 +20,12 @@ message.betterfoliage.vOffset=V.Offset
|
||||
message.betterfoliage.minHeight=Min.Height
|
||||
message.betterfoliage.maxHeight=Max.Height
|
||||
message.betterfoliage.flowerChance=Flower Chance
|
||||
message.betterfoliage.reedChance=Reed Chance
|
||||
message.betterfoliage.reedChance=Reed Population
|
||||
message.betterfoliage.leavesMode=Leaves Offset: %s
|
||||
message.betterfoliage.genShortgrass=Use generated: %s
|
||||
message.betterfoliage.leavesSkew=Skew
|
||||
message.betterfoliage.leavesTranslate=Translate
|
||||
message.betterfoliage.algaeChance=Algae Chance
|
||||
message.betterfoliage.algaeChance=Algae Population
|
||||
message.betterfoliage.crustSize=Crust Size
|
||||
message.betterfoliage.coralChance=Coral Chance
|
||||
message.betterfoliage.coralPopulation=Coral Population
|
||||
Reference in New Issue
Block a user