gt22

Structure Api

Sep 14th, 2016
192
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Java 14.29 KB | None | 0 0
  1. package com.gt22.gt22core.api.structure;
  2.  
  3. import java.io.BufferedReader;
  4. import java.io.File;
  5. import java.io.FileOutputStream;
  6. import java.io.FileReader;
  7. import java.io.IOException;
  8. import java.util.ArrayList;
  9.  
  10. import org.apache.logging.log4j.Level;
  11.  
  12. import com.google.gson.JsonArray;
  13. import com.google.gson.JsonElement;
  14. import com.google.gson.JsonObject;
  15. import com.google.gson.JsonParser;
  16. import com.gt22.gt22core.core.Core;
  17. import com.gt22.gt22core.utils.FileUtils;
  18. import com.gt22.gt22core.utils.Gt22MathHelper;
  19.  
  20. import cpw.mods.fml.common.FMLLog;
  21. import cpw.mods.fml.common.Loader;
  22. import cpw.mods.fml.common.registry.GameData;
  23. import net.minecraft.block.Block;
  24. import net.minecraft.crash.CrashReport;
  25. import net.minecraft.init.Blocks;
  26. import net.minecraft.item.ItemStack;
  27. import net.minecraft.util.ReportedException;
  28. import net.minecraft.world.World;
  29.  
  30. public class StructureApi
  31. {      
  32.     private static final File structurelist = new File(Loader.instance().getConfigDir() + "/GT22CoreStructure","strucutres.cfg");
  33.     //Main json names
  34.     public static final String STRUCTURE = "structure";
  35.     public static final String PROPERTIES = "properties";
  36.     //Structure names
  37.     public static final String X_OFFSET = "xOffset";
  38.     public static final String Y_OFFSET = "yOffset";
  39.     public static final String Z_OFFSET = "zOffset";
  40.     public static final String BLOCK_META = "meta";
  41.     public static final String BLOCK_NAME = "blockname";
  42.     //Properties names
  43.     public static final String WEIGHT = "weight";
  44.     public static final String NAME = "name";
  45.     public static final String TARGET = "target";
  46.     public static final String USE_TARGET = "usetarget";
  47.     public static final String MIN_Y = "miny";
  48.     public static final String MAX_Y = "maxy";
  49.     public static final String WORLD = "world";
  50.     /**
  51.      * Create and write to file strcuture, this structure will not generate in normal ways. Designet to use form commands, but can be used in other cases
  52.      * @param name - name of the structure
  53.      * @param firstpoint - first corner of structure in format {x, y, z}
  54.      * @param secondpoint - second corner of structure in format {x, y, z}
  55.      * @param templateWorld - world where structure template was build in
  56.      */
  57.     public static void createStructure(String name, int[] firstpoint, int[] secondpoint, World world)
  58.     {
  59.         createStructure(name, firstpoint, secondpoint, world, -1, Blocks.air, false, 0, 0, 0);
  60.     }
  61.  
  62.     /**
  63.      * Create and write to file strcuture. Designet to use form commands, but can be used in other cases
  64.      * @param name - name of the structure
  65.      * @param firstpoint - first corner of structure in format {x, y, z}
  66.      * @param secondpoint - second corner of structure in format {x, y, z}
  67.      * @param templateWorld - world where structure template was build in, does not affect generating
  68.      * @param weight - generation weight, than it bigget than rarer will be the structure (formula is crazy, even i can't understand how it working), negative weight will prevent structure from generation
  69.      * @param target - Target block whitch structure should replace, structure will not generate if even one block doen't eqals target
  70.      * @param usetarget - if false target will be ignored, usually used for custom generating structure
  71.      * @param miny - minimum y coordinate, structure will not generate lower
  72.      * @param miny - maximum y coordinate, structure will not generate higher
  73.      * @param targetWorld - id of world where structure should generate
  74.      */
  75.     public static boolean createStructure(String name, int[] firstpoint, int[] secondpoint, World templateWorld, int weight, Block target, boolean usetarget, int miny, int maxy, int targetWorld)
  76.     {
  77.         try
  78.         {
  79.             new StructureJson(name, firstpoint, secondpoint, templateWorld, weight, target, usetarget, miny, maxy, targetWorld);
  80.             return true;
  81.         }
  82.         catch (IllegalArgumentException e)
  83.         {
  84.             e.printStackTrace();
  85.             return false;
  86.         }
  87.     }
  88.  
  89.     /**
  90.      * Return json of structure
  91.      * @param name
  92.      * of structure
  93.      * @return
  94.      */
  95.     public static JsonObject getByName(String name)
  96.     {
  97.         return load(new File(Loader.instance().getConfigDir() + "/GT22CoreStructure", name + ".json"));
  98.     }
  99.  
  100.     /**
  101.      * Return properties of the structure.
  102.      * Properties contain:
  103.      * weight : weight of structure
  104.      * name : name of structure
  105.      * target : name of target block
  106.      * usetarget : does structure uses target or not
  107.      * miny : minimal y coordinate
  108.      * maxy : maximal y coordinate
  109.      * world : id of world where strucutre will genetate
  110.      * @param name
  111.      * @return
  112.      */
  113.     public static JsonObject getStructureProperties(String name)
  114.     {
  115.         return getByName(name).getAsJsonObject(PROPERTIES);
  116.     }
  117.  
  118.     /**
  119.      * Delete structure
  120.      * @param name
  121.      * of structure
  122.      * @return true if structure was succsfully deleted
  123.      */
  124.     public static boolean deleteStructure(String name)
  125.     {
  126.         File file = new File(Loader.instance().getConfigDir() + "/GT22CoreStructure", name + ".json");
  127.         if (!file.exists())
  128.         {
  129.             return false;
  130.         }
  131.         file.delete();
  132.         if (!structurelist.exists())
  133.         {
  134.             return true;
  135.         }
  136.         try
  137.         {
  138.             FileUtils.deleteLine(structurelist, name);
  139.         }
  140.         catch (IOException e)
  141.         {
  142.             throw new ReportedException(CrashReport.makeCrashReport(e, "Unable to read structure config"));
  143.         }
  144.         return true;
  145.     }
  146.  
  147.     private static JsonObject load(File file)
  148.     {
  149.  
  150.         if (!file.canWrite())
  151.         {
  152.             FMLLog.warning("cannot load json for structure " + file.getName());
  153.             return null;
  154.         }
  155.         try
  156.         {
  157.             return new JsonParser().parse(new FileReader(file)).getAsJsonObject();
  158.         }
  159.         catch (Exception e)
  160.         {
  161.             FMLLog.bigWarning("Can't load json for structure");
  162.             e.printStackTrace();
  163.         }
  164.         return null;
  165.     }
  166.  
  167.     private static ArrayList<JsonObject> getStructures()
  168.     {
  169.         ArrayList<JsonObject> ret = new ArrayList<JsonObject>();
  170.         try
  171.         {
  172.             FileUtils.initFile(structurelist);
  173.             BufferedReader list = FileUtils.createReader(structurelist);
  174.             String temp = "";
  175.             int i = 0;
  176.             while (true)
  177.             {
  178.                 temp = list.readLine();
  179.                 i++;
  180.                 if (temp == null)
  181.                 {
  182.                     break;
  183.                 }
  184.                 JsonObject jsontemp = StructureApi.getByName(temp);
  185.                 if (jsontemp == null)
  186.                 {
  187.                     FileUtils.deleteLine(structurelist, i);
  188.                     continue;
  189.                 }
  190.                 ret.add(jsontemp);
  191.             }
  192.         }
  193.         catch (IOException e)
  194.         {
  195.             throw new ReportedException(CrashReport.makeCrashReport(e, "Unable to read structure config"));
  196.         }
  197.         return ret;
  198.     }
  199.  
  200.     /**
  201.      * Return list with names of all registered strcutures
  202.      * @return
  203.      */
  204.     public static ArrayList<String> getStructuresNames()
  205.     {
  206.         ArrayList<JsonObject> structures = getStructures();
  207.         ArrayList<String> ret = new ArrayList<String>();
  208.         for (JsonObject j : structures)
  209.         {
  210.             ret.add(j.getAsJsonObject(PROPERTIES).get(NAME).getAsString());
  211.         }
  212.         return ret;
  213.     }
  214.  
  215.     /**
  216.      * Generate random structure based on weight, y corrdinate calculated
  217.      * internaly
  218.      * @param world
  219.      * @param x
  220.      * @param z
  221.      */
  222.     public static void getnerateRandomStrucutre(World world, int x, int z)
  223.     {
  224.         ArrayList<JsonObject> structures = getStructures();
  225.         if (structures.isEmpty())
  226.         {
  227.             return;
  228.         }
  229.         ArrayList<Integer> weights = new ArrayList<Integer>();
  230.         for (int i = 0; i < structures.size(); i++)
  231.         {
  232.             JsonObject j = structures.get(i);
  233.             int weight = j.getAsJsonObject(PROPERTIES).get(StructureApi.WEIGHT).getAsInt();
  234.             if (weight < 0)
  235.             {
  236.                 structures.remove(j);
  237.                 continue;
  238.             }
  239.             weights.add(weight);
  240.         }
  241.         if (weights.isEmpty())
  242.         {
  243.             return;
  244.         }
  245.         weights.sort(null);
  246.         int randweight = world.rand.nextInt(weights.get(weights.size() - 1) + 1);
  247.         int midweight = weights.get((weights.size() / 2));
  248.         if (randweight >= midweight)
  249.         {
  250.             JsonObject structure = weights.size() == 1 ? structures.get(0) : structures.get(Gt22MathHelper.getPositionOfClosest(weights, world.rand.nextInt(weights.get(weights.size() - 1) - world.rand.nextInt(weights.get(weights.size() - 2)))));
  251.             JsonObject properties = structure.getAsJsonObject(StructureApi.PROPERTIES);
  252.             int miny = properties.get(StructureApi.MIN_Y).getAsInt(), maxy = properties.get(StructureApi.MAX_Y).getAsInt(), ydiff = Gt22MathHelper.diff(miny, maxy);
  253.             generateStructure(structure, world, x, miny + world.rand.nextInt(ydiff), z);
  254.         }
  255.     }
  256.  
  257.     /**
  258.      * Generate specified structure
  259.      * @param json
  260.      * of the structure
  261.      * @param world
  262.      * to generate structure (Srtucture will no generate if different
  263.      * from structure world)
  264.      * @param x
  265.      * @param y
  266.      * @param z
  267.      */
  268.     public static void generateStructure(JsonObject json, World world, int x, int y, int z)
  269.     {
  270.         generateStructure(json, world, x, y, z, false, false);
  271.     }
  272.  
  273.     /**
  274.      * Generate specified structure
  275.      * @param json
  276.      * of the structure
  277.      * @param world
  278.      * to generate structure
  279.      * @param x
  280.      * @param y
  281.      * @param z
  282.      * @param ignoreJsonTargetSetting
  283.      * - if true usetarget setting in json will be ignored and
  284.      * counted as false
  285.      * @param ignoreJsonWorldSetting
  286.      * - if true world setting in json will be ignored
  287.      */
  288.     public static void generateStructure(JsonObject json, World world, int x, int y, int z, boolean ignoreJsonTargetSetting, boolean ignoreJsonWorldSetting)
  289.     {
  290.         JsonObject properties = json.getAsJsonObject(StructureApi.PROPERTIES);
  291.         if (!ignoreJsonWorldSetting && world.provider.dimensionId != properties.get(StructureApi.WORLD).getAsInt())
  292.         {
  293.             return;
  294.         }
  295.         Block target = GameData.getBlockRegistry().getObject(properties.get(StructureApi.TARGET).getAsString());
  296.         boolean forcetarget = !ignoreJsonTargetSetting && properties.get(StructureApi.USE_TARGET).getAsBoolean();
  297.         JsonArray str = json.getAsJsonArray(STRUCTURE);
  298.         if (forcetarget && !ignoreJsonTargetSetting)
  299.         {
  300.             for (JsonElement e : str)
  301.             {
  302.                 JsonObject o = e.getAsJsonObject();
  303.                 if (world.getBlock(x + o.get(X_OFFSET).getAsInt(), y + o.get(Y_OFFSET).getAsInt(), z + o.get(Z_OFFSET).getAsInt()) != target)
  304.                 {
  305.                     System.out.println("target");
  306.                     return;
  307.                 }
  308.             }
  309.         }
  310.         for (JsonElement e : str)
  311.         {
  312.             JsonObject o = e.getAsJsonObject();
  313.             world.setBlock(x + o.get(X_OFFSET).getAsInt(), y + o.get(Y_OFFSET).getAsInt(), z + o.get(Z_OFFSET).getAsInt(), GameData.getBlockRegistry().getObject(o.get(BLOCK_NAME).getAsString()), o.get(BLOCK_META).getAsInt(), 3);
  314.         }
  315.     }
  316.    
  317.     private static class StructureJson
  318.     {
  319.         private String name;
  320.         private JsonObject json = new JsonObject();
  321.         private File file;
  322.         private ItemStack[][][] structure;
  323.         private int[] f, s;
  324.         private int xSize, ySize, zSize, weight, miny, maxy, worldid;
  325.         private String target;
  326.         private boolean usetarget;
  327.        
  328.         public StructureJson(String name, int[] firstpoint, int[] secondpoint, World world, int weight, Block target, boolean usetarget, int miny, int maxy, int worldid) throws IllegalArgumentException
  329.         {
  330.             if(firstpoint.length != 3)
  331.             {
  332.                 throw new IllegalArgumentException("First point must contain three coordinates {X, Y, Z}");
  333.             }
  334.             if(secondpoint.length != 3)
  335.             {
  336.                 throw new IllegalArgumentException("Second point must contain three coordinates {X, Y, Z}");
  337.             }
  338.             if(miny > maxy || miny < 0 || maxy > world.getActualHeight())
  339.             {
  340.                 throw new IllegalArgumentException("Incorrect height arguments");
  341.             }
  342.             addToStructureList(name);
  343.             this.weight = weight;
  344.             this.name = name;
  345.             this.file = new File(Loader.instance().getConfigDir() + "/GT22CoreStructure", name + ".json");
  346.             this.f = firstpoint;
  347.             this.s = secondpoint;
  348.             this.target = GameData.getBlockRegistry().getNameForObject(target);
  349.             this.usetarget = usetarget;
  350.             this.miny = miny;
  351.             this.maxy = maxy;
  352.             this.worldid = worldid;
  353.             sortPoints();
  354.             generateStructure(world);
  355.             generateJson();
  356.             write();
  357.         }
  358.        
  359.         private static void addToStructureList(String name)
  360.         {
  361.             try
  362.             {
  363.                 FileUtils.initFile(structurelist);
  364.                 FileUtils.addLine(structurelist, name);
  365.             }
  366.             catch (IOException e)
  367.             {
  368.                 throw new ReportedException(CrashReport.makeCrashReport(e, "Unable to write structure to structure config"));
  369.             }
  370.         }
  371.        
  372.         private void sortPoints()
  373.         {
  374.             for(int i = 0; i < f.length; i++)
  375.             {
  376.                 if(f[i] > s[i])
  377.                 {
  378.                     s[i] = Gt22MathHelper.swap(f[i], f[i] = s[i]);
  379.                 }
  380.             }
  381.         }
  382.        
  383.         private void generateJson()
  384.         {
  385.             JsonArray structureJson = new JsonArray();
  386.             for(int x = 0; x < xSize; x++)
  387.             {
  388.                 for(int y = 0; y < ySize; y++)
  389.                 {
  390.                     for(int z = 0; z < zSize; z++)
  391.                     {
  392.                         JsonObject block = new JsonObject();
  393.                         ItemStack s = structure[x][y][z];
  394.                         block.addProperty(X_OFFSET, x);
  395.                         block.addProperty(Y_OFFSET, y);
  396.                         block.addProperty(Z_OFFSET, z);
  397.                         block.addProperty(BLOCK_META, structure == null || s == null || s.getItem() == null ? 0 : s.getItemDamage());
  398.                         block.addProperty(BLOCK_NAME, structure == null || s == null || s.getItem() == null ? GameData.getBlockRegistry().getNameForObject(Blocks.air) : GameData.getBlockRegistry().getNameForObject(Block.getBlockFromItem(s.getItem())));
  399.                         structureJson.add(block);
  400.                     }
  401.                 }
  402.             }
  403.             JsonObject structureProperties = new JsonObject();
  404.             structureProperties.addProperty(StructureApi.WEIGHT, weight);
  405.             structureProperties.addProperty(StructureApi.NAME, name);
  406.             structureProperties.addProperty(StructureApi.TARGET, target);
  407.             structureProperties.addProperty(StructureApi.USE_TARGET, usetarget);
  408.             structureProperties.addProperty(StructureApi.MIN_Y, miny);
  409.             structureProperties.addProperty(StructureApi.MAX_Y, maxy);
  410.             structureProperties.addProperty(StructureApi.WORLD, worldid);
  411.             json.add(StructureApi.STRUCTURE, structureJson);
  412.             json.add(PROPERTIES, structureProperties);
  413.         }
  414.        
  415.         private void generateStructure(World world)
  416.         {
  417.             xSize = s[0] - f[0] + 1;
  418.             ySize = s[1] - f[1] + 1;
  419.             zSize = s[2] - f[2] + 1;
  420.             structure = new ItemStack[xSize][ySize][zSize];
  421.             for(int x = 0; x < xSize; x++)
  422.             {
  423.                 for(int y = 0; y < ySize; y++)
  424.                 {
  425.                     for(int z = 0; z < zSize; z++)
  426.                     {
  427.                         structure[x][y][z] = new ItemStack(world.getBlock(x + f[0], y + f[1], z + f[2]), 1, world.getBlockMetadata(x + f[0], y + f[1], z + f[2]));
  428.                     }
  429.                 }
  430.             }
  431.         }
  432.        
  433.         private void write()
  434.         {
  435.             try
  436.             {
  437.                 FileUtils.initFile(file);
  438.                 FileOutputStream jsonfile = new FileOutputStream(file);
  439.                 jsonfile.write(json.toString().getBytes());
  440.                 jsonfile.close();
  441.             }
  442.             catch (Exception e)
  443.             {
  444.                 FMLLog.log(Core.modid, Level.ERROR, e, "Unable to write json for structure %s", name);
  445.                 e.printStackTrace();
  446.             }
  447.         }
  448.     }
  449. }
Advertisement
Add Comment
Please, Sign In to add comment