View difference between Paste ID: xzbYAHjW and mtFnd51U
SHOW: | | - or go back to the newest paste.
1-
package test;
1+
/**
2
****************************************************************************************
3
****************************************************************************************
4
*** Bukkit TemplateGenerator
5
*** Contents:
6
***  TemplateChunkGenerator.java
7
***  OBCTemplateChunkGenerator.java
8
***  Usage docs
9-
public class TemplateGenerator extends ChunkGenerator {
9+
***
10
*** @author Kane York (riking)
11
*** @date 4 June 2013
12-
    public TemplateGenerator(World templateWorld) {
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-
}
57+
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
 */