Advertisement
riking

TemplateGenerator + OBCTemplateGenerator

Jun 5th, 2013
269
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. /**
  2. ****************************************************************************************
  3. ****************************************************************************************
  4. *** Bukkit TemplateGenerator
  5. *** Contents:
  6. ***  TemplateChunkGenerator.java
  7. ***  OBCTemplateChunkGenerator.java
  8. ***  Usage docs
  9. ***
  10. *** @author Kane York (riking)
  11. *** @date 4 June 2013
  12. *** @license This code is released into the public domain in the hope that it may be
  13. ***     useful. No restrictions are placed upon copying or reuse, even commercially.
  14. ***     This code is provided as-is, without any warranty. If it doesn't work, it
  15. ***     (may not be) my fault, but I'm not liable for any losses you incur from trying
  16. ***     to get it to work or from malfunctions.
  17. ***
  18. *** The documentation you see below may be outdated, see http://jd.bukkit.org/ for
  19. *** up-to-date usage information.
  20. ***
  21. *** Also, no additional support will be provided for the OBC version. Figure it out
  22. *** yourself once you get the pure-bukkit version going.
  23. ****************************************************************************************
  24. *** TemplateGenerator.java
  25. ***************************************************************************************/
  26. import java.util.Random;
  27.  
  28. import org.bukkit.generator.ChunkGenerator;
  29. import org.bukkit.ChunkSnapshot;
  30. import org.bukkit.World;
  31.  
  32. public class TemplateChunkGenerator extends ChunkGenerator {
  33.     protected World world;
  34.  
  35.     public TemplateChunkGenerator(World templateWorld) {
  36.         this.world = templateWorld;
  37.     }
  38.  
  39.     /*
  40.     void setBlock(short[][] result, int x, int y, int z, short blkid) {
  41.         if (result[y >> 4] == null) {
  42.             result[y >> 4] = new short[4096];
  43.         }
  44.         result[y >> 4][((y & 0xF) << 8) | (z << 4) | x] = blkid;
  45.     }
  46.     */
  47.  
  48.     @Override
  49.     public short[][] generateExtBlockSections(World contextWorld, Random worldRandom, int cx, int cz, BiomeGrid biomes) {
  50.         ChunkSnapshot templateChunk = world.getChunkAt(cx, cz).getChunkSnapshot();
  51.  
  52.         // Pure-bukkit impl - can be optimized via NMS
  53.  
  54.         // Load block IDs
  55.         short[][] result = new short[256 / 16][];
  56.         for (int y = 0; y < 256; y += 16) {
  57.             short[] locres = new short[4096];
  58.             for (int py = y; py < y + 16; py++) {
  59.                 for (int px = 0; px < 16; px++) {
  60.                     for (int pz = 0; pz < 16; pz++) {
  61.                         locres[((py & 0xF) << 8) | (pz << 4) | px] = (short) templateChunk.getBlockTypeId(px, py, pz);
  62.                     }
  63.                 }
  64.             }
  65.             result[y >> 4] = locres;
  66.         }
  67.  
  68.         loadBiomesIntoGrid(biomes, templateChunk);
  69.  
  70.         return result;
  71.     }
  72.  
  73.     public void loadBiomesIntoGrid(BiomeGrid biomes, ChunkSnapshot template) {
  74.         for (int px = 0; px < 16; px++) {
  75.             for (int pz = 0; pz < 16; pz++) {
  76.                 biomes.setBiome(px, pz, template.getBiome(px, pz));
  77.             }
  78.         }
  79.     }
  80. }
  81. /***************************************************************************************
  82. *** OBCTemplateGenerator.java
  83. ***************************************************************************************/
  84. import java.lang.reflect.Field;
  85. import java.util.Random;
  86.  
  87. import org.bukkit.ChunkSnapshot;
  88. import org.bukkit.World;
  89. import org.bukkit.craftbukkit.CraftChunkSnapshot; // THIS MUST BE CHANGED TO THE CORRECT VERSIONED PACKAGE
  90.  
  91.  
  92. public class OBCTemplateChunkGenerator extends TemplateChunkGenerator {
  93.  
  94.     public OBCTemplateChunkGenerator(World templateWorld) {
  95.         super(templateWorld);
  96.     }
  97.  
  98.     /**
  99.      * @throws NoClassDefFoundError on wrong version of craftbukkit
  100.      */
  101.     @Override
  102.     public short[][] generateExtBlockSections(World contextWorld, Random worldRandom, int cx, int cz, BiomeGrid biomes)
  103.       throws RuntimeException {
  104.         ChunkSnapshot tmp = world.getChunkAt(cx, cz).getChunkSnapshot();
  105.         // let's do this first, shall we?
  106.         loadBiomesIntoGrid(biomes, tmp);
  107.  
  108.         try {
  109.             CraftChunkSnapshot templateChunk = (CraftChunkSnapshot)tmp;
  110.  
  111.             Field blockids = CraftChunkSnapshot.class.getDeclaredField("blockids");
  112.             blockids.setAccessible(true);
  113.  
  114.             short[][] result = (short[][]) blockids.get(templateChunk);
  115.             return result;
  116.         } catch (Throwable e) {
  117.             System.err.println("[WARNING] Suppressing" + e.toString() + ", falling back on pure-bukkit");
  118.             return super.generateExtBlockSections(contextWorld, worldRandom, cx, cz, biomes);
  119.         }
  120.     }
  121. }
  122.  
  123. /***************************************************************************************
  124. *** Usage Notes
  125. ***************************************************************************************/
  126.  
  127. /**
  128.  * The TemplateGenerator loads chunks from an alternate world to a 'main'
  129.  * world that can be modified and reset as needed.
  130.  * <p>
  131.  * How to use:
  132.  * <p>
  133.  * The first method we want to look at is
  134.  * {@link org.bukkit.Server#createWorld(org.bukkit.WorldCreator)}. This takes
  135.  * a WorldCreator, what's that? Well, the constructor is WorldCreator(String
  136.  * name).
  137.  * <p>
  138.  * The general use-case for this is a unchanging template populating a
  139.  * revertable main world. So, we don't want any of the random parts of
  140.  * Minecraft worldgen.
  141.  * <p>
  142.  * Let's say that your template world is named "gameTemplate", and the game
  143.  * world (the one that players join) will be named "gameWorld". So first:
  144.  *
  145.  * <pre>
  146.  * World templateWorld = getServer().createWorld(new WorldCreator(&quot;gameTemplate&quot;));
  147.  * </pre>
  148.  *
  149.  * Now that we have the template world loaded, we want to setup the playing
  150.  * world. We need to set the generator, and some other options to make sure
  151.  * that Minecraft doesn't mess us up and add stuff to our beautiful template:
  152.  *
  153.  * <pre>
  154.  * WorldCreator gameCreator = new WorldCreator("gameWorld")
  155.  *   .generateStructures(false) // no mineshafts
  156.  *   .type(WorldType.FLAT) // no ores
  157.  *   .generator(new TemplateGenerator(templateWorld));
  158.  * </pre>
  159.  *
  160.  * Now, you need to be aware of this caveat: No block data, entities (like
  161.  * paintings and item frames), or tile entities (like chests, signs, furnaces,
  162.  * pistons, beacons, player skulls, or anything else with a BlockState) is
  163.  * loaded from the template world.
  164.  * <p>
  165.  * The first step in fixing this is the TemplateBlockPopulator.
  166.  * // TODO expand, create the TemplateBlockPopulator
  167.  * <p>
  168.  * And we're almost done setting up! Now we just need to:
  169.  *
  170.  * <pre>
  171.  * World gameWorld = getServer().createWorld(gameCreator);
  172.  * </pre>
  173.  *
  174.  * We can now teleport players into the gameWorld and let them play away.
  175.  * When the game is done and it's time to clean up, use
  176.  * {@link World#regenerateChunk(int, int)} and the Game world will revert back
  177.  * to the Template world. It's as simple as that!
  178.  *
  179.  * <p>
  180.  *
  181.  * If you want to use the OBCTemplateGenerator, which should be faster, do this:
  182.  * <pre>
  183.  * WorldCreator gameCreator = ...; // same as above
  184.  * try {
  185.  *   gameCreator.generator(new OBCTemplateGenerator(templateWorld));
  186.  * } catch (Throwable t) {
  187.  *   // ignore - we can't use it right now
  188.  * }
  189.  */
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement