001package net.minecraft.world.storage;
002
003import java.util.Map;
004
005import cpw.mods.fml.relauncher.Side;
006import cpw.mods.fml.relauncher.SideOnly;
007import net.minecraft.crash.CrashReportCategory;
008import net.minecraft.nbt.NBTBase;
009import net.minecraft.nbt.NBTTagCompound;
010import net.minecraft.world.EnumGameType;
011import net.minecraft.world.GameRules;
012import net.minecraft.world.WorldSettings;
013import net.minecraft.world.WorldType;
014
015public class WorldInfo
016{
017    /** Holds the seed of the currently world. */
018    private long randomSeed;
019    private WorldType terrainType;
020    private String generatorOptions;
021
022    /** The spawn zone position X coordinate. */
023    private int spawnX;
024
025    /** The spawn zone position Y coordinate. */
026    private int spawnY;
027
028    /** The spawn zone position Z coordinate. */
029    private int spawnZ;
030
031    /** Total time for this world. */
032    private long totalTime;
033
034    /** The current world time in ticks, ranging from 0 to 23999. */
035    private long worldTime;
036
037    /** The last time the player was in this world. */
038    private long lastTimePlayed;
039
040    /** The size of entire save of current world on the disk, isn't exactly. */
041    private long sizeOnDisk;
042    private NBTTagCompound playerTag;
043    private int dimension;
044
045    /** The name of the save defined at world creation. */
046    private String levelName;
047
048    /** Introduced in beta 1.3, is the save version for future control. */
049    private int saveVersion;
050
051    /** True if it's raining, false otherwise. */
052    private boolean raining;
053
054    /** Number of ticks until next rain. */
055    private int rainTime;
056
057    /** Is thunderbolts failing now? */
058    private boolean thundering;
059
060    /** Number of ticks untils next thunderbolt. */
061    private int thunderTime;
062
063    /** The Game Type. */
064    private EnumGameType theGameType;
065
066    /**
067     * Whether the map features (e.g. strongholds) generation is enabled or disabled.
068     */
069    private boolean mapFeaturesEnabled;
070
071    /** Hardcore mode flag */
072    private boolean hardcore;
073    private boolean allowCommands;
074    private boolean initialized;
075    private GameRules theGameRules;
076    private Map<String, NBTBase> additionalProperties;
077
078    protected WorldInfo()
079    {
080        this.terrainType = WorldType.DEFAULT;
081        this.generatorOptions = "";
082        this.theGameRules = new GameRules();
083    }
084
085    public WorldInfo(NBTTagCompound par1NBTTagCompound)
086    {
087        this.terrainType = WorldType.DEFAULT;
088        this.generatorOptions = "";
089        this.theGameRules = new GameRules();
090        this.randomSeed = par1NBTTagCompound.getLong("RandomSeed");
091
092        if (par1NBTTagCompound.hasKey("generatorName"))
093        {
094            String s = par1NBTTagCompound.getString("generatorName");
095            this.terrainType = WorldType.parseWorldType(s);
096
097            if (this.terrainType == null)
098            {
099                this.terrainType = WorldType.DEFAULT;
100            }
101            else if (this.terrainType.isVersioned())
102            {
103                int i = 0;
104
105                if (par1NBTTagCompound.hasKey("generatorVersion"))
106                {
107                    i = par1NBTTagCompound.getInteger("generatorVersion");
108                }
109
110                this.terrainType = this.terrainType.getWorldTypeForGeneratorVersion(i);
111            }
112
113            if (par1NBTTagCompound.hasKey("generatorOptions"))
114            {
115                this.generatorOptions = par1NBTTagCompound.getString("generatorOptions");
116            }
117        }
118
119        this.theGameType = EnumGameType.getByID(par1NBTTagCompound.getInteger("GameType"));
120
121        if (par1NBTTagCompound.hasKey("MapFeatures"))
122        {
123            this.mapFeaturesEnabled = par1NBTTagCompound.getBoolean("MapFeatures");
124        }
125        else
126        {
127            this.mapFeaturesEnabled = true;
128        }
129
130        this.spawnX = par1NBTTagCompound.getInteger("SpawnX");
131        this.spawnY = par1NBTTagCompound.getInteger("SpawnY");
132        this.spawnZ = par1NBTTagCompound.getInteger("SpawnZ");
133        this.totalTime = par1NBTTagCompound.getLong("Time");
134
135        if (par1NBTTagCompound.hasKey("DayTime"))
136        {
137            this.worldTime = par1NBTTagCompound.getLong("DayTime");
138        }
139        else
140        {
141            this.worldTime = this.totalTime;
142        }
143
144        this.lastTimePlayed = par1NBTTagCompound.getLong("LastPlayed");
145        this.sizeOnDisk = par1NBTTagCompound.getLong("SizeOnDisk");
146        this.levelName = par1NBTTagCompound.getString("LevelName");
147        this.saveVersion = par1NBTTagCompound.getInteger("version");
148        this.rainTime = par1NBTTagCompound.getInteger("rainTime");
149        this.raining = par1NBTTagCompound.getBoolean("raining");
150        this.thunderTime = par1NBTTagCompound.getInteger("thunderTime");
151        this.thundering = par1NBTTagCompound.getBoolean("thundering");
152        this.hardcore = par1NBTTagCompound.getBoolean("hardcore");
153
154        if (par1NBTTagCompound.hasKey("initialized"))
155        {
156            this.initialized = par1NBTTagCompound.getBoolean("initialized");
157        }
158        else
159        {
160            this.initialized = true;
161        }
162
163        if (par1NBTTagCompound.hasKey("allowCommands"))
164        {
165            this.allowCommands = par1NBTTagCompound.getBoolean("allowCommands");
166        }
167        else
168        {
169            this.allowCommands = this.theGameType == EnumGameType.CREATIVE;
170        }
171
172        if (par1NBTTagCompound.hasKey("Player"))
173        {
174            this.playerTag = par1NBTTagCompound.getCompoundTag("Player");
175            this.dimension = this.playerTag.getInteger("Dimension");
176        }
177
178        if (par1NBTTagCompound.hasKey("GameRules"))
179        {
180            this.theGameRules.readGameRulesFromNBT(par1NBTTagCompound.getCompoundTag("GameRules"));
181        }
182    }
183
184    public WorldInfo(WorldSettings par1WorldSettings, String par2Str)
185    {
186        this.terrainType = WorldType.DEFAULT;
187        this.generatorOptions = "";
188        this.theGameRules = new GameRules();
189        this.randomSeed = par1WorldSettings.getSeed();
190        this.theGameType = par1WorldSettings.getGameType();
191        this.mapFeaturesEnabled = par1WorldSettings.isMapFeaturesEnabled();
192        this.levelName = par2Str;
193        this.hardcore = par1WorldSettings.getHardcoreEnabled();
194        this.terrainType = par1WorldSettings.getTerrainType();
195        this.generatorOptions = par1WorldSettings.func_82749_j();
196        this.allowCommands = par1WorldSettings.areCommandsAllowed();
197        this.initialized = false;
198    }
199
200    public WorldInfo(WorldInfo par1WorldInfo)
201    {
202        this.terrainType = WorldType.DEFAULT;
203        this.generatorOptions = "";
204        this.theGameRules = new GameRules();
205        this.randomSeed = par1WorldInfo.randomSeed;
206        this.terrainType = par1WorldInfo.terrainType;
207        this.generatorOptions = par1WorldInfo.generatorOptions;
208        this.theGameType = par1WorldInfo.theGameType;
209        this.mapFeaturesEnabled = par1WorldInfo.mapFeaturesEnabled;
210        this.spawnX = par1WorldInfo.spawnX;
211        this.spawnY = par1WorldInfo.spawnY;
212        this.spawnZ = par1WorldInfo.spawnZ;
213        this.totalTime = par1WorldInfo.totalTime;
214        this.worldTime = par1WorldInfo.worldTime;
215        this.lastTimePlayed = par1WorldInfo.lastTimePlayed;
216        this.sizeOnDisk = par1WorldInfo.sizeOnDisk;
217        this.playerTag = par1WorldInfo.playerTag;
218        this.dimension = par1WorldInfo.dimension;
219        this.levelName = par1WorldInfo.levelName;
220        this.saveVersion = par1WorldInfo.saveVersion;
221        this.rainTime = par1WorldInfo.rainTime;
222        this.raining = par1WorldInfo.raining;
223        this.thunderTime = par1WorldInfo.thunderTime;
224        this.thundering = par1WorldInfo.thundering;
225        this.hardcore = par1WorldInfo.hardcore;
226        this.allowCommands = par1WorldInfo.allowCommands;
227        this.initialized = par1WorldInfo.initialized;
228        this.theGameRules = par1WorldInfo.theGameRules;
229    }
230
231    /**
232     * Gets the NBTTagCompound for the worldInfo
233     */
234    public NBTTagCompound getNBTTagCompound()
235    {
236        NBTTagCompound nbttagcompound = new NBTTagCompound();
237        this.updateTagCompound(nbttagcompound, this.playerTag);
238        return nbttagcompound;
239    }
240
241    /**
242     * Creates a new NBTTagCompound for the world, with the given NBTTag as the "Player"
243     */
244    public NBTTagCompound cloneNBTCompound(NBTTagCompound par1NBTTagCompound)
245    {
246        NBTTagCompound nbttagcompound1 = new NBTTagCompound();
247        this.updateTagCompound(nbttagcompound1, par1NBTTagCompound);
248        return nbttagcompound1;
249    }
250
251    private void updateTagCompound(NBTTagCompound par1NBTTagCompound, NBTTagCompound par2NBTTagCompound)
252    {
253        par1NBTTagCompound.setLong("RandomSeed", this.randomSeed);
254        par1NBTTagCompound.setString("generatorName", this.terrainType.getWorldTypeName());
255        par1NBTTagCompound.setInteger("generatorVersion", this.terrainType.getGeneratorVersion());
256        par1NBTTagCompound.setString("generatorOptions", this.generatorOptions);
257        par1NBTTagCompound.setInteger("GameType", this.theGameType.getID());
258        par1NBTTagCompound.setBoolean("MapFeatures", this.mapFeaturesEnabled);
259        par1NBTTagCompound.setInteger("SpawnX", this.spawnX);
260        par1NBTTagCompound.setInteger("SpawnY", this.spawnY);
261        par1NBTTagCompound.setInteger("SpawnZ", this.spawnZ);
262        par1NBTTagCompound.setLong("Time", this.totalTime);
263        par1NBTTagCompound.setLong("DayTime", this.worldTime);
264        par1NBTTagCompound.setLong("SizeOnDisk", this.sizeOnDisk);
265        par1NBTTagCompound.setLong("LastPlayed", System.currentTimeMillis());
266        par1NBTTagCompound.setString("LevelName", this.levelName);
267        par1NBTTagCompound.setInteger("version", this.saveVersion);
268        par1NBTTagCompound.setInteger("rainTime", this.rainTime);
269        par1NBTTagCompound.setBoolean("raining", this.raining);
270        par1NBTTagCompound.setInteger("thunderTime", this.thunderTime);
271        par1NBTTagCompound.setBoolean("thundering", this.thundering);
272        par1NBTTagCompound.setBoolean("hardcore", this.hardcore);
273        par1NBTTagCompound.setBoolean("allowCommands", this.allowCommands);
274        par1NBTTagCompound.setBoolean("initialized", this.initialized);
275        par1NBTTagCompound.setCompoundTag("GameRules", this.theGameRules.writeGameRulesToNBT());
276
277        if (par2NBTTagCompound != null)
278        {
279            par1NBTTagCompound.setCompoundTag("Player", par2NBTTagCompound);
280        }
281    }
282
283    /**
284     * Returns the seed of current world.
285     */
286    public long getSeed()
287    {
288        return this.randomSeed;
289    }
290
291    /**
292     * Returns the x spawn position
293     */
294    public int getSpawnX()
295    {
296        return this.spawnX;
297    }
298
299    /**
300     * Return the Y axis spawning point of the player.
301     */
302    public int getSpawnY()
303    {
304        return this.spawnY;
305    }
306
307    /**
308     * Returns the z spawn position
309     */
310    public int getSpawnZ()
311    {
312        return this.spawnZ;
313    }
314
315    public long getWorldTotalTime()
316    {
317        return this.totalTime;
318    }
319
320    /**
321     * Get current world time
322     */
323    public long getWorldTime()
324    {
325        return this.worldTime;
326    }
327
328    @SideOnly(Side.CLIENT)
329    public long getSizeOnDisk()
330    {
331        return this.sizeOnDisk;
332    }
333
334    /**
335     * Returns the player's NBTTagCompound to be loaded
336     */
337    public NBTTagCompound getPlayerNBTTagCompound()
338    {
339        return this.playerTag;
340    }
341
342    public int getDimension()
343    {
344        return this.dimension;
345    }
346
347    @SideOnly(Side.CLIENT)
348
349    /**
350     * Set the x spawn position to the passed in value
351     */
352    public void setSpawnX(int par1)
353    {
354        this.spawnX = par1;
355    }
356
357    @SideOnly(Side.CLIENT)
358
359    /**
360     * Sets the y spawn position
361     */
362    public void setSpawnY(int par1)
363    {
364        this.spawnY = par1;
365    }
366
367    public void incrementTotalWorldTime(long par1)
368    {
369        this.totalTime = par1;
370    }
371
372    @SideOnly(Side.CLIENT)
373
374    /**
375     * Set the z spawn position to the passed in value
376     */
377    public void setSpawnZ(int par1)
378    {
379        this.spawnZ = par1;
380    }
381
382    /**
383     * Set current world time
384     */
385    public void setWorldTime(long par1)
386    {
387        this.worldTime = par1;
388    }
389
390    /**
391     * Sets the spawn zone position. Args: x, y, z
392     */
393    public void setSpawnPosition(int par1, int par2, int par3)
394    {
395        this.spawnX = par1;
396        this.spawnY = par2;
397        this.spawnZ = par3;
398    }
399
400    /**
401     * Get current world name
402     */
403    public String getWorldName()
404    {
405        return this.levelName;
406    }
407
408    public void setWorldName(String par1Str)
409    {
410        this.levelName = par1Str;
411    }
412
413    /**
414     * Returns the save version of this world
415     */
416    public int getSaveVersion()
417    {
418        return this.saveVersion;
419    }
420
421    /**
422     * Sets the save version of the world
423     */
424    public void setSaveVersion(int par1)
425    {
426        this.saveVersion = par1;
427    }
428
429    @SideOnly(Side.CLIENT)
430
431    /**
432     * Return the last time the player was in this world.
433     */
434    public long getLastTimePlayed()
435    {
436        return this.lastTimePlayed;
437    }
438
439    /**
440     * Returns true if it is thundering, false otherwise.
441     */
442    public boolean isThundering()
443    {
444        return this.thundering;
445    }
446
447    /**
448     * Sets whether it is thundering or not.
449     */
450    public void setThundering(boolean par1)
451    {
452        this.thundering = par1;
453    }
454
455    /**
456     * Returns the number of ticks until next thunderbolt.
457     */
458    public int getThunderTime()
459    {
460        return this.thunderTime;
461    }
462
463    /**
464     * Defines the number of ticks until next thunderbolt.
465     */
466    public void setThunderTime(int par1)
467    {
468        this.thunderTime = par1;
469    }
470
471    /**
472     * Returns true if it is raining, false otherwise.
473     */
474    public boolean isRaining()
475    {
476        return this.raining;
477    }
478
479    /**
480     * Sets whether it is raining or not.
481     */
482    public void setRaining(boolean par1)
483    {
484        this.raining = par1;
485    }
486
487    /**
488     * Return the number of ticks until rain.
489     */
490    public int getRainTime()
491    {
492        return this.rainTime;
493    }
494
495    /**
496     * Sets the number of ticks until rain.
497     */
498    public void setRainTime(int par1)
499    {
500        this.rainTime = par1;
501    }
502
503    /**
504     * Gets the GameType.
505     */
506    public EnumGameType getGameType()
507    {
508        return this.theGameType;
509    }
510
511    /**
512     * Get whether the map features (e.g. strongholds) generation is enabled or disabled.
513     */
514    public boolean isMapFeaturesEnabled()
515    {
516        return this.mapFeaturesEnabled;
517    }
518
519    /**
520     * Sets the GameType.
521     */
522    public void setGameType(EnumGameType par1EnumGameType)
523    {
524        this.theGameType = par1EnumGameType;
525    }
526
527    /**
528     * Returns true if hardcore mode is enabled, otherwise false
529     */
530    public boolean isHardcoreModeEnabled()
531    {
532        return this.hardcore;
533    }
534
535    public WorldType getTerrainType()
536    {
537        return this.terrainType;
538    }
539
540    public void setTerrainType(WorldType par1WorldType)
541    {
542        this.terrainType = par1WorldType;
543    }
544
545    public String getGeneratorOptions()
546    {
547        return this.generatorOptions;
548    }
549
550    /**
551     * Returns true if commands are allowed on this World.
552     */
553    public boolean areCommandsAllowed()
554    {
555        return this.allowCommands;
556    }
557
558    /**
559     * Returns true if the World is initialized.
560     */
561    public boolean isInitialized()
562    {
563        return this.initialized;
564    }
565
566    /**
567     * Sets the initialization status of the World.
568     */
569    public void setServerInitialized(boolean par1)
570    {
571        this.initialized = par1;
572    }
573
574    /**
575     * Gets the GameRules class Instance.
576     */
577    public GameRules getGameRulesInstance()
578    {
579        return this.theGameRules;
580    }
581
582    /**
583     * Adds this WorldInfo instance to the crash report.
584     */
585    public void addToCrashReport(CrashReportCategory par1CrashReportCategory)
586    {
587        par1CrashReportCategory.addCrashSectionCallable("Level seed", new CallableLevelSeed(this));
588        par1CrashReportCategory.addCrashSectionCallable("Level generator", new CallableLevelGenerator(this));
589        par1CrashReportCategory.addCrashSectionCallable("Level generator options", new CallableLevelGeneratorOptions(this));
590        par1CrashReportCategory.addCrashSectionCallable("Level spawn location", new CallableLevelSpawnLocation(this));
591        par1CrashReportCategory.addCrashSectionCallable("Level time", new CallableLevelTime(this));
592        par1CrashReportCategory.addCrashSectionCallable("Level dimension", new CallableLevelDimension(this));
593        par1CrashReportCategory.addCrashSectionCallable("Level storage version", new CallableLevelStorageVersion(this));
594        par1CrashReportCategory.addCrashSectionCallable("Level weather", new CallableLevelWeather(this));
595        par1CrashReportCategory.addCrashSectionCallable("Level game mode", new CallableLevelGamemode(this));
596    }
597
598    /**
599     * Return the terrain type of a world
600     */
601    static WorldType getTerrainTypeOfWorld(WorldInfo par0WorldInfo)
602    {
603        return par0WorldInfo.terrainType;
604    }
605
606    /**
607     * Return the map feautures enabled of a world
608     */
609    static boolean getMapFeaturesEnabled(WorldInfo par0WorldInfo)
610    {
611        return par0WorldInfo.mapFeaturesEnabled;
612    }
613
614    static String func_85130_c(WorldInfo par0WorldInfo)
615    {
616        return par0WorldInfo.generatorOptions;
617    }
618
619    static int func_85125_d(WorldInfo par0WorldInfo)
620    {
621        return par0WorldInfo.spawnX;
622    }
623
624    static int func_85124_e(WorldInfo par0WorldInfo)
625    {
626        return par0WorldInfo.spawnY;
627    }
628
629    static int func_85123_f(WorldInfo par0WorldInfo)
630    {
631        return par0WorldInfo.spawnZ;
632    }
633
634    static long func_85126_g(WorldInfo par0WorldInfo)
635    {
636        return par0WorldInfo.totalTime;
637    }
638
639    static long func_85129_h(WorldInfo par0WorldInfo)
640    {
641        return par0WorldInfo.worldTime;
642    }
643
644    static int func_85122_i(WorldInfo par0WorldInfo)
645    {
646        return par0WorldInfo.dimension;
647    }
648
649    static int func_85121_j(WorldInfo par0WorldInfo)
650    {
651        return par0WorldInfo.saveVersion;
652    }
653
654    static int func_85119_k(WorldInfo par0WorldInfo)
655    {
656        return par0WorldInfo.rainTime;
657    }
658
659    static boolean func_85127_l(WorldInfo par0WorldInfo)
660    {
661        return par0WorldInfo.raining;
662    }
663
664    static int func_85133_m(WorldInfo par0WorldInfo)
665    {
666        return par0WorldInfo.thunderTime;
667    }
668
669    static boolean func_85116_n(WorldInfo par0WorldInfo)
670    {
671        return par0WorldInfo.thundering;
672    }
673
674    static EnumGameType func_85120_o(WorldInfo par0WorldInfo)
675    {
676        return par0WorldInfo.theGameType;
677    }
678
679    static boolean func_85117_p(WorldInfo par0WorldInfo)
680    {
681        return par0WorldInfo.hardcore;
682    }
683
684    static boolean func_85131_q(WorldInfo par0WorldInfo)
685    {
686        return par0WorldInfo.allowCommands;
687    }
688
689    /**
690     * Allow access to additional mod specific world based properties
691     * Used by FML to store mod list associated with a world, and maybe an id map
692     * Used by Forge to store the dimensions available to a world
693     * @param additionalProperties
694     */
695    public void setAdditionalProperties(Map<String,NBTBase> additionalProperties)
696    {
697        // one time set for this
698        if (this.additionalProperties == null)
699        {
700            this.additionalProperties = additionalProperties;
701        }
702    }
703
704    public NBTBase getAdditionalProperty(String additionalProperty)
705    {
706        return this.additionalProperties!=null? this.additionalProperties.get(additionalProperty) : null;
707    }
708}