package com.gt22.gt22core.texturegen; import java.io.BufferedReader; import java.io.BufferedWriter; import java.io.File; import java.io.IOException; import java.io.InputStreamReader; import java.lang.reflect.Field; import java.util.ArrayList; import java.util.HashSet; import java.util.List; import java.util.Set; import java.util.stream.Collectors; import java.util.stream.IntStream; import org.apache.logging.log4j.Level; import com.google.common.collect.Lists; import com.gt22.gt22core.core.Core; import com.gt22.gt22core.texturegen.ICustomJson.JsonType; import com.gt22.gt22core.utils.FileUtils; import net.minecraft.block.Block; import net.minecraft.block.properties.IProperty; import net.minecraft.crash.CrashReport; import net.minecraft.item.Item; import net.minecraft.util.EnumFacing; import net.minecraft.util.ReportedException; import net.minecraft.util.ResourceLocation; import net.minecraftforge.fml.common.FMLLog; public class TextureGenRegistry { private static class TextureStorage { public Class reg; public String modid; public TextureStorage(Class clazz, String modid) { this.reg = clazz; this.modid = modid; } } private static List registries = Core.isDev() ? new ArrayList() : null; /** * Use this method to add class containing Items/Blocks field (Like * {@link net.minecraft.init.Items} or {@link net.minecraft.init.Items} for * vanilla) After registering and jsons will appear in * rundir/GeneratedTextures, Just copy assets forlder in your resources * source forlder to add all generated jsons. Texture generating works ONLY * in dev enviroment, if trying to use this in normal minecraft it will be * just ignored. Also see: {@link DoNotApplyTexture} {@link ICustomJson} * {@link IMultitextureBlock} * * @param registry * @param modid */ public static void reigster(Class registry, String modid) { if (Core.isDev()) { registries.add(new TextureStorage(registry, modid)); } } /** * Called interanly */ public static void generateTextures() { Set addedGenericFor = new HashSet(); for (TextureStorage reg : registries) { if (!addedGenericFor.contains(reg.modid)) { createGeneric(reg.modid); addedGenericFor.add(reg.modid); } Field[] fields = reg.reg.getFields(); for (Field f : fields) { if (!f.isAnnotationPresent(DoNotApplyTexture.class)) { try { if (Item.class.isAssignableFrom(f.getType())) { generateItemTexture(reg.modid, (Item) f.get(null)); } else if (Block.class.isAssignableFrom(f.getType())) { generateBlockTexture(reg.modid, (Block) f.get(null)); } } catch (IllegalAccessException e) { throw new ReportedException(CrashReport.makeCrashReport(e, "Unable to get value from registry. Are you using PRIVATE FIELDS IN REGISTRY!!??")); } catch(NullPointerException e) { FMLLog.log(Core.modid, Level.WARN, "Item/Block field %s was not be initialized, skipping", f.getName()); } } } } registries = null; } private static void createGeneric(String modid) { File generic = new File(getDirForItem(modid), "ItemGeneric.json"); try (BufferedReader in = new BufferedReader(new InputStreamReader(TextureGenRegistry.class.getResourceAsStream("/ItemGeneric.json"), "UTF-8")); BufferedWriter out = FileUtils.createWriter(generic, false)) { for (String buf = in.readLine(); buf != null; buf = in.readLine()) { out.write(buf); } } catch (IOException e) { throw new ReportedException(CrashReport.makeCrashReport(e, "Unable to create ItemGeneric.json for mod " + modid)); } } private static File getCoreModDir(String modid) { return new File("GeneratedTextures/assets/" + modid); } private static File getDirForMod(String modid) { return new File(getCoreModDir(modid), "models/"); } private static File getDirForItem(String modid) { return new File(getDirForMod(modid), "item"); } private static File getDirForBlock(String modid) { return new File(getDirForMod(modid), "block"); } public static File getDirForBlockstate(String modid) { return new File(getCoreModDir(modid), "blockstates"); } private static void generateItemTexture(String modid, Item item) { File itemfile = new File(getDirForItem(modid), item.getRegistryName().getResourcePath() + ".json"); try (BufferedWriter out = FileUtils.createWriter(itemfile, false)) { out.write(formatItemJson(modid, item)); } catch (IOException e) { throw new ReportedException(CrashReport.makeCrashReport(e, "Unable to generate texture for item " + item.getUnlocalizedName())); } } private static void generateBlockTexture(String modid, Block block) { File blockfile = new File(getDirForBlock(modid), block.getRegistryName().getResourcePath() + ".json"); File statefile = new File(getDirForBlockstate(modid), block.getRegistryName().getResourcePath() + ".json"); File itemfile = new File(getDirForItem(modid), block.getRegistryName().getResourcePath() + ".json"); try (BufferedWriter outblock = FileUtils.createWriter(blockfile, false); BufferedWriter outstate = FileUtils.createWriter(statefile, false); BufferedWriter outitem = FileUtils.createWriter(itemfile, false)) { outblock.write(formatBlockJson(modid, block)); outstate.write(formatBlockStateJson(modid, block)); outitem.write(formatItemBlockJson(modid, block)); } catch (IOException e) { throw new ReportedException(CrashReport.makeCrashReport(e, "Unable to generate texture for block " + block.getUnlocalizedName())); } } //@formatter:off private static String formatItemJson(String modid, Item item) { if(item instanceof ICustomJson && ((ICustomJson) item).getJson(JsonType.ITEM) != null) { return ((ICustomJson) item).getJson(JsonType.ITEM); } if(item.isFull3D()) { return String.format("{\n" +"\"parent\": \"item/handheld\",\n" +"\"textures\": {\n" + "\"layer0\": \"%s:items/%s\"\n" +"}\n" +"}", modid, item.getRegistryName().getResourcePath()); } else { return String.format( "{\n" + "\"parent\": \"%s:item/ItemGeneric\",\n" + "\"textures\": {\n" + "\"layer0\": \"%s:items/%s\"\n" + "}\n" + "}", modid, modid, item.getRegistryName().getResourcePath()); } } private static String formatItemBlockJson(String modid, Block block) { if(block instanceof ICustomJson && ((ICustomJson) block).getJson(JsonType.ITEM) != null) { return ((ICustomJson) block).getJson(JsonType.ITEM); } return String.format( "{\n" +"\"parent\":\"%s:block/%s\",\n" +"\"display\": {\n" +"\"thirdperson\": {\n" +"\"rotation\": [ 10, -45, 170 ],\n" +"\"translation\": [ 0, 1.5, -2.75 ],\n" +"\"scale\": [ 0.375, 0.375, 0.375 ]\n" +"}\n" +"}\n" +"}", modid, block.getRegistryName().getResourcePath()); } private static String formatBlockJson(String modid, Block block) { if(block instanceof ICustomJson && ((ICustomJson) block).getJson(JsonType.BLOCK) != null) { return ((ICustomJson) block).getJson(JsonType.BLOCK); } if(block instanceof IMultitextureBlock) { IMultitextureBlock bl = (IMultitextureBlock) block; return String.format("{\n" + "\"parent\": \"block/cube\",\n" + "\"textures\": {\n" + "\"particle\": \"%s\",\n" + "\"up\": \"%s\",\n" + "\"down\": \"%s\",\n" + "\"north\": \"%s\",\n" + "\"east\": \"%s\",\n" + "\"south\": \"%s\",\n" + "\"west\": \"%s\"\n" + "}\n" + "}", bl.getParticleTexture(), bl.getTexture(EnumFacing.UP), bl.getTexture(EnumFacing.DOWN), bl.getTexture(EnumFacing.NORTH), bl.getTexture(EnumFacing.EAST), bl.getTexture(EnumFacing.SOUTH), bl.getTexture(EnumFacing.WEST)); } return String.format("{\n" + "\"parent\": \"block/cube_all\",\n" + "\"textures\": {\n" + "\"all\": \"%s:blocks/%s\"\n" + "}\n" + "}", modid, block.getRegistryName().getResourcePath()); } private static String formatBlockStateJson(String modid, Block block) { if(block instanceof ICustomJson && ((ICustomJson) block).getJson(JsonType.BLOCKSTATE) != null) { return ((ICustomJson) block).getJson(JsonType.BLOCKSTATE); } if(block instanceof IMultiBlockStateBlock) { return formatMultiStateJson(modid, block); } return String.format("{\n" + "\t\"variants\": {\n" + "\t\"normal\": { \"model\":\"%s\" }\n" + "}\n" + "}", block.getRegistryName()); } private static String formatMultiStateJson(String modid, Block block) { IMultiBlockStateBlock states = (IMultiBlockStateBlock) block; IProperty[] props = states.getProps(); StringBuilder sb = new StringBuilder(); for(IProperty prop : props) { getJsonsForProps(prop, states, sb); } return String.format("" + "{\n" + "\t\"forge_marker\": 1,\n" + "\t\"defaults\": {\n" + "\t\t%s\n" + "\t\t\"model\":\"%s\"\n" + "\t}\n" + "\t\"variants\": {\n" + "\t\t\"normal\": [{}]\n" + "%s" + "\t}\n" + "}" ,states.getDefaultJson(), block.getRegistryName(), sb); } private static > void getJsonsForProps(IProperty prop, IMultiBlockStateBlock states, StringBuilder sb) { sb.append(String.format("\t\t\"%s\":{\n", prop.getName())); for(T val : prop.getAllowedValues()) { sb.append(String.format("\t\t\t\"%s\":{\n", prop.getName(val))); sb.append(states.getJson(prop, val)); sb.append(getTexturesForBlock(states.getTextures(prop, val), 4)); sb.append("\t\t\t}\n"); } sb.append("\t\t}\n"); } private static String getTexturesForBlock(Block bl, int tabs) { return getTexturesForBlock(bl instanceof IMultitextureBlock ? (IMultitextureBlock) bl : side -> bl.getRegistryName(), tabs); } private static String getTexturesForBlock(IMultitextureBlock bl, int tabs) { return String.format( tabs(tabs) + "\"textures\": {\n" + tabs(++tabs) + "\"particle\": \"%s\",\n" + tabs(tabs) + "\"up\": \"%s\",\n" + tabs(tabs) + "\"down\": \"%s\",\n" + tabs(tabs) + "\"north\": \"%s\",\n" + tabs(tabs) + "\"east\": \"%s\",\n" + tabs(tabs) + "\"south\": \"%s\",\n" + tabs(tabs) + "\"west\": \"%s\"\n" + tabs(--tabs) + "}\n" ,bl.getParticleTexture(), bl.getTexture(EnumFacing.UP), bl.getTexture(EnumFacing.DOWN), bl.getTexture(EnumFacing.NORTH), bl.getTexture(EnumFacing.EAST), bl.getTexture(EnumFacing.SOUTH), bl.getTexture(EnumFacing.WEST)); } private static String tabs(int tabs) { String ret = ""; for(int i = 0; i < tabs; i++) { ret += '\t'; } return ret; } //@formatter:on }