Support up to 16 icons for every feature
This commit is contained in:
58
src/main/java/mods/betterfoliage/client/render/IconSet.java
Normal file
58
src/main/java/mods/betterfoliage/client/render/IconSet.java
Normal file
@@ -0,0 +1,58 @@
|
||||
package mods.betterfoliage.client.render;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
import net.minecraft.client.Minecraft;
|
||||
import net.minecraft.client.renderer.texture.IIconRegister;
|
||||
import net.minecraft.client.resources.IResource;
|
||||
import net.minecraft.client.resources.IResourceManager;
|
||||
import net.minecraft.util.IIcon;
|
||||
import net.minecraft.util.ResourceLocation;
|
||||
|
||||
/** Loads an indexed set of textures
|
||||
* @author octarine-noise
|
||||
*/
|
||||
public class IconSet {
|
||||
|
||||
/** Icon array */
|
||||
public IIcon[] icons = new IIcon[16];
|
||||
|
||||
/** Number of successfully loaded icons*/
|
||||
public int numLoaded = 0;
|
||||
|
||||
/** Resource domain of icons */
|
||||
String domain;
|
||||
|
||||
/** Format string of icon paths */
|
||||
String path;
|
||||
|
||||
public IconSet(String domain, String path) {
|
||||
this.domain = domain;
|
||||
this.path = path;
|
||||
}
|
||||
|
||||
public void registerIcons(IIconRegister register) {
|
||||
numLoaded = 0;
|
||||
IResourceManager manager = Minecraft.getMinecraft().getResourceManager();
|
||||
|
||||
for (int idx = 0; idx < 16; idx++) {
|
||||
icons[idx] = null;
|
||||
// if the path contains a domain, use that to check if the resource exists
|
||||
String resolvedDomain = path.contains(":") ? new ResourceLocation(path).getResourceDomain() : domain;
|
||||
String resolvedPath = String.format("textures/blocks/" + (path.contains(":") ? new ResourceLocation(path).getResourcePath() : path) + ".png", idx);
|
||||
try {
|
||||
IResource resource = manager.getResource(new ResourceLocation(resolvedDomain, resolvedPath));
|
||||
if (resource != null) icons[numLoaded++] = register.registerIcon(domain + ":" + String.format(path, idx));
|
||||
} catch (IOException e) {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public IIcon get(int variation) {
|
||||
return numLoaded == 0 ? null : icons[variation % numLoaded];
|
||||
}
|
||||
|
||||
public boolean hasIcons() {
|
||||
return numLoaded > 0;
|
||||
}
|
||||
}
|
||||
@@ -1,7 +1,9 @@
|
||||
package mods.betterfoliage.client.render.impl;
|
||||
|
||||
import mods.betterfoliage.BetterFoliage;
|
||||
import mods.betterfoliage.client.render.FakeRenderBlockAOBase;
|
||||
import mods.betterfoliage.client.render.IRenderBlockDecorator;
|
||||
import mods.betterfoliage.client.render.IconSet;
|
||||
import mods.betterfoliage.common.config.Config;
|
||||
import mods.betterfoliage.common.util.Double3;
|
||||
import net.minecraft.block.Block;
|
||||
@@ -21,7 +23,7 @@ import cpw.mods.fml.relauncher.SideOnly;
|
||||
public class RenderBlockBetterCactus extends FakeRenderBlockAOBase implements IRenderBlockDecorator {
|
||||
|
||||
public IIcon cactusRoundIcon;
|
||||
public IIcon cactusSideIcons[] = new IIcon[2];
|
||||
public IconSet cactusSideIcons = new IconSet("bettergrassandleaves", "better_cactus_arm_%d");
|
||||
|
||||
public static ForgeDirection[] cactusDirections = new ForgeDirection[] { ForgeDirection.NORTH, ForgeDirection.SOUTH, ForgeDirection.EAST, ForgeDirection.WEST};
|
||||
public static double cactusRadius = 0.4375;
|
||||
@@ -51,7 +53,7 @@ public class RenderBlockBetterCactus extends FakeRenderBlockAOBase implements IR
|
||||
Double3 drawBase = blockCenter.add(new Double3(drawDirection).scale(cactusRadius));
|
||||
|
||||
Tessellator.instance.setBrightness(getBrightness(block, x, y, z));
|
||||
renderCrossedSideQuads(drawBase, drawDirection, 0.5, 0.5, pRot[iconVariation], 0.2, cactusSideIcons[iconVariation % 2], 0, false);
|
||||
if (cactusSideIcons.hasIcons()) renderCrossedSideQuads(drawBase, drawDirection, 0.5, 0.5, pRot[iconVariation], 0.2, cactusSideIcons.get(iconVariation), 0, false);
|
||||
renderCrossedBlockQuadsSkew(blockCenter, 0.65,
|
||||
pRot[iconVariation].scaleAxes(0.1, 0.0, 0.1),
|
||||
pRot[(iconVariation + 1) & 63].scaleAxes(0.1, 0.0, 0.1),
|
||||
@@ -78,7 +80,9 @@ public class RenderBlockBetterCactus extends FakeRenderBlockAOBase implements IR
|
||||
@SubscribeEvent
|
||||
public void handleTextureReload(TextureStitchEvent.Pre event) {
|
||||
if (event.map.getTextureType() != 0) return;
|
||||
|
||||
cactusRoundIcon = event.map.registerIcon("bettergrassandleaves:better_cactus");
|
||||
for (int idx = 0; idx < 2; idx++) cactusSideIcons[idx] = event.map.registerIcon("bettergrassandleaves:better_cactus_arm_" + Integer.toString(idx));
|
||||
cactusSideIcons.registerIcons(event.map);
|
||||
BetterFoliage.log.info(String.format("Found %d cactus arm textures", cactusSideIcons.numLoaded));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
package mods.betterfoliage.client.render.impl;
|
||||
|
||||
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.config.Config;
|
||||
import mods.betterfoliage.common.util.Double3;
|
||||
@@ -20,8 +22,9 @@ import cpw.mods.fml.relauncher.SideOnly;
|
||||
@SideOnly(Side.CLIENT)
|
||||
public class RenderBlockBetterGrass extends RenderBlockAOBase implements IRenderBlockDecorator {
|
||||
|
||||
public IIcon grassIcons[] = new IIcon[5];
|
||||
public IIcon myceliumIcons[] = new IIcon[4];
|
||||
public IconSet grassIcons = new IconSet("bettergrassandleaves", "better_grass_long_%d");
|
||||
public IconSet myceliumIcons = new IconSet("bettergrassandleaves", "better_mycel_%d");
|
||||
|
||||
|
||||
public boolean isBlockAccepted(IBlockAccess blockAccess, int x, int y, int z, Block block, int original) {
|
||||
if (!Config.grassEnabled) return false;
|
||||
@@ -42,7 +45,8 @@ public class RenderBlockBetterGrass extends RenderBlockAOBase implements IRender
|
||||
int variation = getSemiRandomFromPos(x, y, z, 0);
|
||||
int heightVariation = getSemiRandomFromPos(x, y, z, 1);
|
||||
|
||||
IIcon renderIcon = (block == Blocks.mycelium) ? myceliumIcons[variation % 4] : grassIcons[variation % 5];
|
||||
IIcon renderIcon = (block == Blocks.mycelium) ? myceliumIcons.get(variation) : grassIcons.get(variation);
|
||||
if (renderIcon == null) return true;
|
||||
|
||||
double scale = Config.grassSize.value * 0.5;
|
||||
double halfHeight = 0.5 * (Config.grassHeightMin.value + pRand[heightVariation] * (Config.grassHeightMax.value - Config.grassHeightMin.value));
|
||||
@@ -55,11 +59,11 @@ public class RenderBlockBetterGrass extends RenderBlockAOBase implements IRender
|
||||
@SubscribeEvent
|
||||
public void handleTextureReload(TextureStitchEvent.Pre event) {
|
||||
if (event.map.getTextureType() != 0) return;
|
||||
for (int idx = 0; idx < 5; idx++) {
|
||||
grassIcons[idx] = event.map.registerIcon(String.format("bettergrassandleaves:better_grass_long_%d", idx));
|
||||
}
|
||||
for (int idx = 0; idx < 4; idx++) {
|
||||
myceliumIcons[idx] = event.map.registerIcon(String.format("bettergrassandleaves:better_mycel_%d", idx));
|
||||
}
|
||||
|
||||
grassIcons.registerIcons(event.map);
|
||||
myceliumIcons.registerIcons(event.map);
|
||||
BetterFoliage.log.info(String.format("Found %d short grass textures", grassIcons.numLoaded));
|
||||
BetterFoliage.log.info(String.format("Found %d mycelium textures", myceliumIcons.numLoaded));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -1,14 +1,15 @@
|
||||
package mods.betterfoliage.client.render.impl;
|
||||
|
||||
import mods.betterfoliage.BetterFoliage;
|
||||
import mods.betterfoliage.client.render.FakeRenderBlockAOBase;
|
||||
import mods.betterfoliage.client.render.IRenderBlockDecorator;
|
||||
import mods.betterfoliage.client.render.IconSet;
|
||||
import mods.betterfoliage.common.config.Config;
|
||||
import mods.betterfoliage.common.util.Double3;
|
||||
import net.minecraft.block.Block;
|
||||
import net.minecraft.client.renderer.RenderBlocks;
|
||||
import net.minecraft.client.renderer.Tessellator;
|
||||
import net.minecraft.init.Blocks;
|
||||
import net.minecraft.util.IIcon;
|
||||
import net.minecraft.world.IBlockAccess;
|
||||
import net.minecraftforge.client.event.TextureStitchEvent;
|
||||
import net.minecraftforge.common.util.ForgeDirection;
|
||||
@@ -19,8 +20,8 @@ import cpw.mods.fml.relauncher.SideOnly;
|
||||
@SideOnly(Side.CLIENT)
|
||||
public class RenderBlockBetterLilypad extends FakeRenderBlockAOBase implements IRenderBlockDecorator {
|
||||
|
||||
public IIcon lilypadFlowers[] = new IIcon[2];
|
||||
public IIcon lilypadRoots[] = new IIcon[3];
|
||||
public IconSet lilypadFlowers = new IconSet("bettergrassandleaves", "better_lilypad_flower_%d");
|
||||
public IconSet lilypadRoots = new IconSet("bettergrassandleaves", "better_lilypad_roots_%d");
|
||||
|
||||
public boolean isBlockAccepted(IBlockAccess blockAccess, int x, int y, int z, Block block, int original) {
|
||||
return Config.lilypadEnabled && block == Blocks.waterlily;
|
||||
@@ -39,16 +40,16 @@ public class RenderBlockBetterLilypad extends FakeRenderBlockAOBase implements I
|
||||
|
||||
Tessellator.instance.setBrightness(getBrightness(block, x, y, z));
|
||||
Tessellator.instance.setColorOpaque(255, 255, 255);
|
||||
renderCrossedSideQuads(new Double3(x + 0.5, y + 0.015, z + 0.5), ForgeDirection.DOWN,
|
||||
0.2, 0.3,
|
||||
null, 0.0,
|
||||
lilypadRoots[iconVariation % 3], 2,
|
||||
true);
|
||||
if (chanceVariation < Config.lilypadChance.value)
|
||||
if (lilypadRoots.hasIcons()) renderCrossedSideQuads(new Double3(x + 0.5, y + 0.015, z + 0.5), ForgeDirection.DOWN,
|
||||
0.2, 0.3,
|
||||
null, 0.0,
|
||||
lilypadRoots.get(iconVariation), 2,
|
||||
true);
|
||||
if (chanceVariation < Config.lilypadChance.value && lilypadFlowers.hasIcons())
|
||||
renderCrossedSideQuads(new Double3(x + 0.5, y + 0.02, z + 0.5), ForgeDirection.UP,
|
||||
0.2, 0.3,
|
||||
pRot[offsetVariation], Config.lilypadHOffset.value,
|
||||
lilypadFlowers[iconVariation % 2], 0,
|
||||
lilypadFlowers.get(iconVariation), 0,
|
||||
true);
|
||||
|
||||
return true;
|
||||
@@ -57,8 +58,11 @@ public class RenderBlockBetterLilypad extends FakeRenderBlockAOBase implements I
|
||||
@SubscribeEvent
|
||||
public void handleTextureReload(TextureStitchEvent.Pre event) {
|
||||
if (event.map.getTextureType() != 0) return;
|
||||
for (int idx = 0; idx < 2; idx++) lilypadFlowers[idx] = event.map.registerIcon("bettergrassandleaves:better_lilypad_flower_" + Integer.toString(idx));
|
||||
for (int idx = 0; idx < 3; idx++) lilypadRoots[idx] = event.map.registerIcon("bettergrassandleaves:better_lilypad_roots_" + Integer.toString(idx));
|
||||
|
||||
lilypadFlowers.registerIcons(event.map);
|
||||
lilypadRoots.registerIcons(event.map);
|
||||
BetterFoliage.log.info(String.format("Found %d lilypad flower textures", lilypadFlowers.numLoaded));
|
||||
BetterFoliage.log.info(String.format("Found %d lilypad root textures", lilypadRoots.numLoaded));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -0,0 +1,88 @@
|
||||
package mods.betterfoliage.client.resource;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
import mods.betterfoliage.BetterFoliage;
|
||||
import mods.betterfoliage.common.util.ReflectionUtil;
|
||||
import net.minecraft.client.Minecraft;
|
||||
import net.minecraft.client.renderer.texture.TextureMap;
|
||||
import net.minecraft.client.resources.IResource;
|
||||
import net.minecraft.client.resources.IResourceManager;
|
||||
import net.minecraft.util.ResourceLocation;
|
||||
import net.minecraftforge.client.event.TextureStitchEvent;
|
||||
|
||||
import com.google.common.collect.ImmutableList;
|
||||
import com.google.common.collect.ImmutableSet;
|
||||
|
||||
import cpw.mods.fml.common.eventhandler.SubscribeEvent;
|
||||
|
||||
public abstract class BlockTextureGenerator implements IResourceManager {
|
||||
|
||||
/** Resource domain name of generated textures */
|
||||
public String domainName;
|
||||
|
||||
/** Resource location for fallback texture (if the generation process fails) */
|
||||
public ResourceLocation missingResource;
|
||||
|
||||
/** 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 = ReflectionUtil.getDomainResourceManagers();
|
||||
if (domainManagers == null) {
|
||||
BetterFoliage.log.warn("Failed to inject texture generator");
|
||||
return;
|
||||
}
|
||||
domainManagers.put(domainName, this);
|
||||
|
||||
onStitchStart(event);
|
||||
}
|
||||
|
||||
@SubscribeEvent
|
||||
public void endTextureReload(TextureStitchEvent.Post event) {
|
||||
blockTextures = null;
|
||||
if (event.map.getTextureType() != 0) return;
|
||||
|
||||
// don't leave a mess
|
||||
Map<String, IResourceManager> domainManagers = ReflectionUtil.getDomainResourceManagers();
|
||||
if (domainManagers != null) domainManagers.remove(domainName);
|
||||
|
||||
onStitchEnd(event);
|
||||
}
|
||||
|
||||
public Set<String> getResourceDomains() {
|
||||
return ImmutableSet.<String>of(domainName);
|
||||
}
|
||||
|
||||
public List<IResource> getAllResources(ResourceLocation resource) throws IOException {
|
||||
return ImmutableList.<IResource>of(getResource(resource));
|
||||
}
|
||||
|
||||
public IResource getMissingResource() throws IOException {
|
||||
return Minecraft.getMinecraft().getResourceManager().getResource(missingResource);
|
||||
}
|
||||
|
||||
public ResourceLocation unwrapResource(ResourceLocation wrapped) {
|
||||
return new ResourceLocation(wrapped.getResourcePath().substring(16));
|
||||
}
|
||||
}
|
||||
@@ -11,22 +11,17 @@ import mods.betterfoliage.client.BetterFoliageClient;
|
||||
import mods.betterfoliage.common.util.DeobfNames;
|
||||
import mods.betterfoliage.common.util.ReflectionUtil;
|
||||
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.renderer.texture.TextureMap;
|
||||
import net.minecraft.client.resources.IResource;
|
||||
import net.minecraft.client.resources.IResourceManager;
|
||||
import net.minecraft.util.IIcon;
|
||||
import net.minecraft.util.ResourceLocation;
|
||||
import net.minecraftforge.client.event.TextureStitchEvent;
|
||||
import net.minecraftforge.client.event.TextureStitchEvent.Post;
|
||||
import net.minecraftforge.client.event.TextureStitchEvent.Pre;
|
||||
|
||||
import com.google.common.collect.ImmutableList;
|
||||
import com.google.common.collect.ImmutableSet;
|
||||
import com.google.common.collect.Lists;
|
||||
import com.google.common.collect.Sets;
|
||||
|
||||
import cpw.mods.fml.common.eventhandler.SubscribeEvent;
|
||||
import cpw.mods.fml.relauncher.Side;
|
||||
import cpw.mods.fml.relauncher.SideOnly;
|
||||
|
||||
@@ -34,41 +29,22 @@ import cpw.mods.fml.relauncher.SideOnly;
|
||||
* @author octarine-noise
|
||||
*/
|
||||
@SideOnly(Side.CLIENT)
|
||||
public class LeafTextureGenerator implements IIconRegister, IResourceManager {
|
||||
public class LeafTextureGenerator extends BlockTextureGenerator implements IIconRegister {
|
||||
|
||||
/** Resource domain name of autogenerated crossleaf textures */
|
||||
public String domainName = "bf_leaves_autogen";
|
||||
|
||||
/** Resource location for fallback texture (if the generation process fails) */
|
||||
public ResourceLocation missing_resource = new ResourceLocation("betterfoliage", "textures/blocks/missingleaf.png");
|
||||
|
||||
/** Texture atlas for block textures used in the current run */
|
||||
public TextureMap blockTextures;
|
||||
|
||||
/** List of helpers which can identify leaf textures loaded by alternate means */
|
||||
public List<ILeafTextureRecognizer> recognizers = Lists.newLinkedList();
|
||||
|
||||
/** Number of textures generated in the current run */
|
||||
int counter = 0;
|
||||
|
||||
public Set<String> getResourceDomains() {
|
||||
return ImmutableSet.<String>of(domainName);
|
||||
public LeafTextureGenerator() {
|
||||
super("bf_leaves_autogen", new ResourceLocation("betterfoliage", "textures/blocks/missingleaf.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 {
|
||||
// remove "/blocks/textures/" from beginning
|
||||
String origResPath = resourceLocation.getResourcePath().substring(16);
|
||||
LeafTextureResource result = new LeafTextureResource(new ResourceLocation(origResPath));
|
||||
if (result.data == null) {
|
||||
return Minecraft.getMinecraft().getResourceManager().getResource(missing_resource);
|
||||
} else {
|
||||
LeafTextureResource result = new LeafTextureResource(unwrapResource(resourceLocation));
|
||||
if (result.data != null) {
|
||||
counter++;
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
public List<IResource> getAllResources(ResourceLocation resource) throws IOException {
|
||||
return ImmutableList.<IResource>of();
|
||||
return getMissingResource();
|
||||
}
|
||||
|
||||
/** Leaf blocks register their textures here. An extra texture will be registered in the atlas
|
||||
@@ -87,21 +63,10 @@ public class LeafTextureGenerator implements IIconRegister, IResourceManager {
|
||||
* @param event
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
@SubscribeEvent
|
||||
public void handleTextureReload(TextureStitchEvent.Pre event) {
|
||||
if (event.map.getTextureType() != 0) return;
|
||||
|
||||
blockTextures = event.map;
|
||||
counter = 0;
|
||||
@Override
|
||||
public void onStitchStart(Pre event) {
|
||||
BetterFoliage.log.info("Reloading leaf textures");
|
||||
|
||||
Map<String, IResourceManager> domainManagers = ReflectionUtil.getDomainResourceManagers();
|
||||
if (domainManagers == null) {
|
||||
BetterFoliage.log.warn("Failed to inject leaf texture generator");
|
||||
return;
|
||||
}
|
||||
domainManagers.put(domainName, this);
|
||||
|
||||
// register simple block textures
|
||||
Iterator<Block> iter = Block.blockRegistry.iterator();
|
||||
while(iter.hasNext()) {
|
||||
@@ -130,18 +95,10 @@ public class LeafTextureGenerator implements IIconRegister, IResourceManager {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@SubscribeEvent
|
||||
public void endTextureReload(TextureStitchEvent.Post event) {
|
||||
blockTextures = null;
|
||||
if (event.map.getTextureType() == 0) {
|
||||
BetterFoliage.log.info(String.format("Generated %d leaf textures", counter));
|
||||
|
||||
// don't leave a mess
|
||||
Map<String, IResourceManager> domainManagers = ReflectionUtil.getDomainResourceManagers();
|
||||
if (domainManagers == null) return;
|
||||
domainManagers.remove(domainName);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onStitchEnd(Post event) {
|
||||
BetterFoliage.log.info(String.format("Generated %d leaf textures", counter));
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user