001 package org.bukkit;
002
003 import java.util.Random;
004 import org.bukkit.command.CommandSender;
005 import org.bukkit.generator.ChunkGenerator;
006 import org.bukkit.plugin.Plugin;
007
008 /**
009 * Represents various types of options that may be used to create a world.
010 */
011 public class WorldCreator {
012 private final String name;
013 private long seed;
014 private World.Environment environment = World.Environment.NORMAL;
015 private ChunkGenerator generator = null;
016 private WorldType type = WorldType.NORMAL;
017 private boolean generateStructures = true;
018
019 /**
020 * Creates an empty WorldCreationOptions for the given world name
021 *
022 * @param name Name of the world that will be created
023 */
024 public WorldCreator(String name) {
025 if (name == null) {
026 throw new IllegalArgumentException("World name cannot be null");
027 }
028
029 this.name = name;
030 this.seed = (new Random()).nextLong();
031 }
032
033 /**
034 * Copies the options from the specified world
035 *
036 * @param world World to copy options from
037 * @return This object, for chaining
038 */
039 public WorldCreator copy(World world) {
040 if (world == null) {
041 throw new IllegalArgumentException("World cannot be null");
042 }
043
044 seed = world.getSeed();
045 environment = world.getEnvironment();
046 generator = world.getGenerator();
047
048 return this;
049 }
050
051 /**
052 * Copies the options from the specified {@link WorldCreator}
053 *
054 * @param creator World creator to copy options from
055 * @return This object, for chaining
056 */
057 public WorldCreator copy(WorldCreator creator) {
058 if (creator == null) {
059 throw new IllegalArgumentException("Creator cannot be null");
060 }
061
062 seed = creator.seed();
063 environment = creator.environment();
064 generator = creator.generator();
065
066 return this;
067 }
068
069 /**
070 * Gets the name of the world that is to be loaded or created.
071 *
072 * @return World name
073 */
074 public String name() {
075 return name;
076 }
077
078 /**
079 * Gets the seed that will be used to create this world
080 *
081 * @return World seed
082 */
083 public long seed() {
084 return seed;
085 }
086
087 /**
088 * Sets the seed that will be used to create this world
089 *
090 * @param seed World seed
091 * @return This object, for chaining
092 */
093 public WorldCreator seed(long seed) {
094 this.seed = seed;
095
096 return this;
097 }
098
099 /**
100 * Gets the environment that will be used to create or load the world
101 *
102 * @return World environment
103 */
104 public World.Environment environment() {
105 return environment;
106 }
107
108 /**
109 * Sets the environment that will be used to create or load the world
110 *
111 * @param env World environment
112 * @return This object, for chaining
113 */
114 public WorldCreator environment(World.Environment env) {
115 this.environment = env;
116
117 return this;
118 }
119
120 /**
121 * Gets the type of the world that will be created or loaded
122 *
123 * @return World type
124 */
125 public WorldType type() {
126 return type;
127 }
128
129 /**
130 * Sets the type of the world that will be created or loaded
131 *
132 * @param type World type
133 * @return This object, for chaining
134 */
135 public WorldCreator type(WorldType type) {
136 this.type = type;
137
138 return this;
139 }
140
141 /**
142 * Gets the generator that will be used to create or load the world.
143 * <p>
144 * This may be null, in which case the "natural" generator for this
145 * environment will be used.
146 *
147 * @return Chunk generator
148 */
149 public ChunkGenerator generator() {
150 return generator;
151 }
152
153 /**
154 * Sets the generator that will be used to create or load the world.
155 * <p>
156 * This may be null, in which case the "natural" generator for this
157 * environment will be used.
158 *
159 * @param generator Chunk generator
160 * @return This object, for chaining
161 */
162 public WorldCreator generator(ChunkGenerator generator) {
163 this.generator = generator;
164
165 return this;
166 }
167
168 /**
169 * Sets the generator that will be used to create or load the world.
170 * <p>
171 * This may be null, in which case the "natural" generator for this
172 * environment will be used.
173 * <p>
174 * If the generator cannot be found for the given name, the natural
175 * environment generator will be used instead and a warning will be
176 * printed to the console.
177 *
178 * @param generator Name of the generator to use, in "plugin:id" notation
179 * @return This object, for chaining
180 */
181 public WorldCreator generator(String generator) {
182 this.generator = getGeneratorForName(name, generator, Bukkit.getConsoleSender());
183
184 return this;
185 }
186
187 /**
188 * Sets the generator that will be used to create or load the world.
189 * <p>
190 * This may be null, in which case the "natural" generator for this
191 * environment will be used.
192 * <p>
193 * If the generator cannot be found for the given name, the natural
194 * environment generator will be used instead and a warning will be
195 * printed to the specified output
196 *
197 * @param generator Name of the generator to use, in "plugin:id" notation
198 * @param output {@link CommandSender} that will receive any error
199 * messages
200 * @return This object, for chaining
201 */
202 public WorldCreator generator(String generator, CommandSender output) {
203 this.generator = getGeneratorForName(name, generator, output);
204
205 return this;
206 }
207
208 /**
209 * Sets whether or not worlds created or loaded with this creator will
210 * have structures.
211 *
212 * @param generate Whether to generate structures
213 * @return This object, for chaining
214 */
215 public WorldCreator generateStructures(boolean generate) {
216 this.generateStructures = generate;
217
218 return this;
219 }
220
221 /**
222 * Gets whether or not structures will be generated in the world.
223 *
224 * @return True if structures will be generated
225 */
226 public boolean generateStructures() {
227 return generateStructures;
228 }
229
230 /**
231 * Creates a world with the specified options.
232 * <p>
233 * If the world already exists, it will be loaded from disk and some
234 * options may be ignored.
235 *
236 * @return Newly created or loaded world
237 */
238 public World createWorld() {
239 return Bukkit.createWorld(this);
240 }
241
242 /**
243 * Creates a new {@link WorldCreator} for the given world name
244 *
245 * @param name Name of the world to load or create
246 * @return Resulting WorldCreator
247 */
248 public static WorldCreator name(String name) {
249 return new WorldCreator(name);
250 }
251
252 /**
253 * Attempts to get the {@link ChunkGenerator} with the given name.
254 * <p>
255 * If the generator is not found, null will be returned and a message will
256 * be printed to the specified {@link CommandSender} explaining why.
257 * <p>
258 * The name must be in the "plugin:id" notation, or optionally just
259 * "plugin", where "plugin" is the safe-name of a plugin and "id" is an
260 * optional unique identifier for the generator you wish to request from
261 * the plugin.
262 *
263 * @param world Name of the world this will be used for
264 * @param name Name of the generator to retrieve
265 * @param output Where to output if errors are present
266 * @return Resulting generator, or null
267 */
268 public static ChunkGenerator getGeneratorForName(String world, String name, CommandSender output) {
269 ChunkGenerator result = null;
270
271 if (world == null) {
272 throw new IllegalArgumentException("World name must be specified");
273 }
274
275 if (output == null) {
276 output = Bukkit.getConsoleSender();
277 }
278
279 if (name != null) {
280 String[] split = name.split(":", 2);
281 String id = (split.length > 1) ? split[1] : null;
282 Plugin plugin = Bukkit.getPluginManager().getPlugin(split[0]);
283
284 if (plugin == null) {
285 output.sendMessage("Could not set generator for world '" + world + "': Plugin '" + split[0] + "' does not exist");
286 } else if (!plugin.isEnabled()) {
287 output.sendMessage("Could not set generator for world '" + world + "': Plugin '" + plugin.getDescription().getFullName() + "' is not enabled");
288 } else {
289 result = plugin.getDefaultWorldGenerator(world, id);
290 }
291 }
292
293 return result;
294 }
295 }