001/*
002 * Trident - A Multithreaded Server Alternative
003 * Copyright 2014 The TridentSDK Team
004 *
005 * Licensed under the Apache License, Version 2.0 (the "License");
006 * you may not use this file except in compliance with the License.
007 * You may obtain a copy of the License at
008 *
009 *    http://www.apache.org/licenses/LICENSE-2.0
010 *
011 * Unless required by applicable law or agreed to in writing, software
012 * distributed under the License is distributed on an "AS IS" BASIS,
013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014 * See the License for the specific language governing permissions and
015 * limitations under the License.
016 */
017package net.tridentsdk.world.settings;
018
019import com.google.common.collect.Maps;
020import net.tridentsdk.base.Position;
021import net.tridentsdk.util.FastRandom;
022import net.tridentsdk.world.gen.ChunkGenerator;
023
024import java.util.Map;
025
026/**
027 * World settings which are applied when a world is created by a worldloader
028 *
029 * @author The TridentSDK Team
030 */
031public final class WorldCreateOptions {
032    private volatile Dimension dimension = Dimension.OVERWORLD;
033    private volatile Difficulty difficulty = Difficulty.NORMAL;
034    private volatile GameMode gameMode = GameMode.SURVIVAL;
035    private volatile LevelType levelType = LevelType.DEFAULT;
036    private final Map<GameRule, GameRule.Value> rules = Maps.newConcurrentMap();
037    private volatile Class<? extends ChunkGenerator> generator = null;
038    private volatile boolean structures = true;
039    private volatile boolean pvp = true;
040    private volatile long seed = FastRandom.random();
041    private final Position spawn = Position.create(null, 0, 0, 0);
042
043    /**
044     * Sets the dimension for the world generator
045     *
046     * @param dimension the dimension
047     * @return the current instance
048     */
049    public WorldCreateOptions dimension(Dimension dimension) {
050        this.dimension = dimension;
051        return this;
052    }
053
054    /**
055     * Sets the difficulty of the world to be generated
056     *
057     * @param difficulty the difficulty
058     * @return the the current instance
059     */
060    public WorldCreateOptions difficulty(Difficulty difficulty) {
061        this.difficulty = difficulty;
062        return this;
063    }
064
065    /**
066     * Sets the gamemode of the world to be generated
067     *
068     * @param gameMode the gamemode
069     * @return the current instance
070     */
071    public WorldCreateOptions gameMode(GameMode gameMode) {
072        this.gameMode = gameMode;
073        return this;
074    }
075
076    /**
077     * Sets the leveltype of the world to be generated
078     *
079     * @param levelType the leveltype
080     * @return the current instance
081     */
082    public WorldCreateOptions level(LevelType levelType) {
083        this.levelType = levelType;
084        return this;
085    }
086
087    /**
088     * Sets the game rules of the world to be generated
089     *
090     * @param rule the game rule to add
091     * @param value the game rule's parameter value
092     * @return the current instance
093     */
094    public WorldCreateOptions rule(GameRule rule, GameRule.Value value) {
095        rules.put(rule, value);
096        return this;
097    }
098
099    /**
100     * Sets whether or not to generate structures (caves, villages, etc)
101     *
102     * @param gen {@code true} to generate structures
103     * @return the current instance
104     */
105    public WorldCreateOptions structures(boolean gen) {
106        this.structures = gen;
107        return this;
108    }
109
110    /**
111     * Sets the PvP enabled flag
112     *
113     * @param enable {@code true} to allow pvp
114     * @return the current instance
115     */
116    public WorldCreateOptions pvp(boolean enable) {
117        this.pvp = enable;
118        return this;
119    }
120
121    /**
122     * Uses the specified generator to generate chunks in the world
123     *
124     * @param generator the generator to use
125     * @return the current instance
126     */
127    public WorldCreateOptions generator(Class<? extends ChunkGenerator> generator) {
128        this.generator = generator;
129        return this;
130    }
131
132    /**
133     * Sets the seed used to generate the world
134     *
135     * @param seed the seed used to generate the world
136     * @return the current instance
137     */
138    public WorldCreateOptions seed(String seed) {
139        long finalSeed;
140        try {
141            finalSeed = Long.parseLong(seed);
142        } catch (NumberFormatException e) {
143            finalSeed = seed.hashCode();
144        }
145
146        this.seed = finalSeed;
147        return this;
148    }
149
150    /**
151     * Sets the seed used to generate the world
152     *
153     * @param seed the seed used to generate the world
154     * @return the current instance
155     */
156    public WorldCreateOptions seed(long seed) {
157        this.seed = seed;
158        return this;
159    }
160
161    /**
162     * Obtains the dimension of the world created using these options
163     *
164     * @return the world's dimension
165     */
166    public Dimension dimension() {
167        return dimension;
168    }
169
170    /**
171     * Obtains the difficulty of the world created using these options
172     *
173     * @return the world's difficulty
174     */
175    public Difficulty difficulty() {
176        return difficulty;
177    }
178
179    /**
180     * Obtains the default gamemode of the world created using these options
181     *
182     * @return the game mode
183     */
184    public GameMode defaultGameMode() {
185        return gameMode;
186    }
187
188    /**
189     * Obtains the level type of the world created using these options
190     *
191     * @return the level type of the world
192     */
193    public LevelType levelType() {
194        return levelType;
195    }
196
197    /**
198     * Checks whether the rule is enabled
199     *
200     * @param rule the game rule
201     * @return {@code true} if the game rule is equal to the provided argument
202     */
203    public boolean isRule(GameRule rule, GameRule.Value value) {
204        if (value.isInteger()) {
205            GameRule.Value v = rules.get(rule);
206            if (v == null) {
207                return rule.intEqualToValue(value.asInt());
208            } else {
209                return v.asInt() == value.asInt();
210            }
211        } else {
212            GameRule.Value v = rules.get(rule);
213            if (v == null) {
214                return rule.boolEqualToValue(value.asBoolean());
215            } else {
216                return v.asBoolean() == value.asBoolean();
217            }
218        }
219    }
220
221    public Map<GameRule, GameRule.Value> gameRules() {
222        return rules;
223    }
224
225    public boolean generateStructures() {
226        return structures;
227    }
228
229    public boolean allowPvp() {
230        return pvp;
231    }
232
233    public Class<? extends ChunkGenerator> generator() {
234        return generator;
235    }
236
237    public long seed() {
238        return seed;
239    }
240}