diff --git a/SubstrateCS/Source/Level.cs b/SubstrateCS/Source/Level.cs index 90dec98..671e174 100644 --- a/SubstrateCS/Source/Level.cs +++ b/SubstrateCS/Source/Level.cs @@ -5,6 +5,102 @@ using Substrate.Nbt; namespace Substrate { + /// + /// Encompases data to specify game rules. + /// + public class GameRules : ICopyable + { + private string _commandBlockOutput = "true"; + private string _doFireTick = "true"; + private string _doMobLoot = "true"; + private string _doMobSpawning = "true"; + private string _doTileDrops = "true"; + private string _keepInventory = "false"; + private string _mobGriefing = "true"; + + /// + /// Gets or sets whether or not actions performed by command blocks are displayed in the chat. + /// + public bool CommandBlockOutput + { + get { return _commandBlockOutput == "true"; } + set { _commandBlockOutput = value ? "true" : "false"; } + } + + /// + /// Gets or sets whether to spread or remove fire. + /// + public bool DoFireTick + { + get { return _doFireTick == "true"; } + set { _doFireTick = value ? "true" : "false"; ; } + } + + /// + /// Gets or sets whether mobs should drop loot when killed. + /// + public bool DoMobLoot + { + get { return _doMobLoot == "true"; } + set { _doMobLoot = value ? "true" : "false"; ; } + } + + /// + /// Gets or sets whether mobs should spawn naturally. + /// + public bool DoMobSpawning + { + get { return _doMobSpawning == "true"; } + set { _doMobSpawning = value ? "true" : "false"; ; } + } + + /// + /// Gets or sets whether breaking blocks should drop the block's item drop. + /// + public bool DoTileDrops + { + get { return _doTileDrops == "true"; } + set { _doTileDrops = value ? "true" : "false"; ; } + } + + /// + /// Gets or sets whether players keep their inventory after they die. + /// + public bool KeepInventory + { + get { return _keepInventory == "true"; } + set { _keepInventory = value ? "true" : "false"; ; } + } + + /// + /// Gets or sets whether mobs can destroy blocks (creeper explosions, zombies breaking doors, etc.). + /// + public bool MobGriefing + { + get { return _mobGriefing == "true"; } + set { _mobGriefing = value ? "true" : "false"; ; } + } + + #region ICopyable Members + + /// + public GameRules Copy () + { + GameRules gr = new GameRules(); + gr._commandBlockOutput = _commandBlockOutput; + gr._doFireTick = _doFireTick; + gr._doMobLoot = _doMobLoot; + gr._doMobSpawning = _doMobSpawning; + gr._doTileDrops = _doTileDrops; + gr._keepInventory = _keepInventory; + gr._mobGriefing = _mobGriefing; + + return gr; + } + + #endregion + } + /// /// Specifies the type of gameplay associated with a world. /// @@ -58,6 +154,21 @@ namespace Substrate new SchemaNodeScaler("GameType", TagType.TAG_INT, SchemaOptions.OPTIONAL), new SchemaNodeScaler("MapFeatures", TagType.TAG_BYTE, SchemaOptions.OPTIONAL), new SchemaNodeScaler("hardcore", TagType.TAG_BYTE, SchemaOptions.OPTIONAL), + new SchemaNodeScaler("generatorVersion", TagType.TAG_INT, SchemaOptions.OPTIONAL), + new SchemaNodeScaler("generatorOptions", TagType.TAG_STRING, SchemaOptions.OPTIONAL), + new SchemaNodeScaler("initialized", TagType.TAG_BYTE, SchemaOptions.OPTIONAL), + new SchemaNodeScaler("allowCommands", TagType.TAG_BYTE, SchemaOptions.OPTIONAL), + new SchemaNodeScaler("DayTime", TagType.TAG_LONG, SchemaOptions.OPTIONAL), + new SchemaNodeCompound("GameRules") + { + new SchemaNodeScaler("commandBlockOutput", TagType.TAG_STRING), + new SchemaNodeScaler("doFireTick", TagType.TAG_STRING), + new SchemaNodeScaler("doMobLoot", TagType.TAG_STRING), + new SchemaNodeScaler("doMobSpawning", TagType.TAG_STRING), + new SchemaNodeScaler("doTileDrops", TagType.TAG_STRING), + new SchemaNodeScaler("keepInventory", TagType.TAG_STRING), + new SchemaNodeScaler("mobGriefing", TagType.TAG_STRING), + }, }, }; @@ -89,6 +200,14 @@ namespace Substrate private byte? _mapFeatures; private byte? _hardcore; + private int? _generatorVersion; + private string _generatorOptions; + private byte? _initialized; + private byte? _allowCommands; + private long? _DayTime; + + private GameRules _gameRules; + /// /// Gets or sets the creation time of the world as a long timestamp. /// @@ -250,6 +369,68 @@ namespace Substrate set { _hardcore = value ? (byte)1 : (byte)0; } } + /// + /// Gets or sets a value indicating the version of the level generator + /// + public int GeneratorVersion + { + get { return _generatorVersion ?? 0; } + set { _generatorVersion = value; } + } + + /// + /// Gets or sets a value indicating controls options for the generator, + /// currently only the Superflat generator. The format is a comma separated + /// list of block IDs from the bottom of the map up, and each block ID may + /// optionally be preceded by the number of layers and an x. + /// Damage values are not supported. + /// + public string GeneratorOptions + { + get { return _generatorOptions ?? ""; } + set { _generatorOptions = value; } + } + + /// + /// Gets or sets a value, normally true, indicating whether a world has been + /// initialized properly after creation. If the initial simulation was canceled + /// somehow, this can be false and the world will be re-initialized on next load. + /// + public bool Initialized + { + get { return (_generatorVersion ?? 0) == 1; } + set { _generatorVersion = value ? (byte)1 : (byte)0; } + } + + /// + /// Gets or sets a value indicating if cheats are enabled. + /// + public bool AllowCommands + { + get { return (_allowCommands ?? 0) == 1; } + set { _allowCommands = value ? (byte)1 : (byte)0; } + } + + /// + /// Gets or sets a value indicating the time of day. + /// 0 is sunrise, 6000 is midday, 12000 is sunset, + /// 18000 is midnight, 24000 is the next day's 0. + /// This value keeps counting past 24000 and does not reset to 0 + /// + public long DayTime + { + get { return _DayTime ?? 0; } + set { _DayTime = value; } + } + + /// + /// Gets the level's game rules. + /// + public GameRules GameRules + { + get { return _gameRules; } + } + /// /// Gets the source used to create this if it exists. /// @@ -288,6 +469,13 @@ namespace Substrate _generator = "default"; _hardcore = 0; + _generatorOptions = ""; + _generatorVersion = 1; + _initialized = 0; + _allowCommands = 0; + _DayTime = 0; + _gameRules = new GameRules(); + GameType = GameType.SURVIVAL; UseMapFeatures = true; @@ -322,6 +510,13 @@ namespace Substrate _mapFeatures = p._mapFeatures; _hardcore = p._hardcore; + _generatorVersion = p._generatorVersion; + _generatorOptions = p._generatorOptions; + _initialized = p._initialized; + _allowCommands = p._allowCommands; + _DayTime = p._DayTime; + _gameRules = p._gameRules.Copy(); + if (p._player != null) { _player = p._player.Copy(); } @@ -398,6 +593,11 @@ namespace Substrate _thunderTime = null; _gameType = null; _mapFeatures = null; + _generatorOptions = null; + _generatorVersion = null; + _allowCommands = null; + _initialized = null; + _DayTime = null; TagNodeCompound ctree = dtree["Data"].ToTagCompound(); @@ -449,6 +649,35 @@ namespace Substrate _hardcore = ctree["hardcore"].ToTagByte(); } + if (ctree.ContainsKey("generatorVersion")) { + _generatorVersion = ctree["generatorVersion"].ToTagInt(); + } + if (ctree.ContainsKey("generatorOptions")) { + _generatorOptions = ctree["generatorOptions"].ToTagString(); + } + if (ctree.ContainsKey("allowCommands")) { + _allowCommands = ctree["allowCommands"].ToTagByte(); + } + if (ctree.ContainsKey("initialized")) { + _initialized = ctree["initialized"].ToTagByte(); + } + if (ctree.ContainsKey("DayTime")) { + _DayTime = ctree["DayTime"].ToTagLong(); + } + if (ctree.ContainsKey("GameRules")) + { + TagNodeCompound gr = ctree["GameRules"].ToTagCompound(); + + _gameRules = new GameRules(); + _gameRules.CommandBlockOutput = gr["commandBlockOutput"].ToTagString().Data == "true"; + _gameRules.DoFireTick = gr["doFireTick"].ToTagString().Data == "true"; + _gameRules.DoMobLoot = gr["doMobLoot"].ToTagString().Data == "true"; + _gameRules.DoMobSpawning = gr["doMobSpawning"].ToTagString().Data == "true"; + _gameRules.DoTileDrops = gr["doTileDrops"].ToTagString().Data == "true"; + _gameRules.KeepInventory = gr["keepInventory"].ToTagString().Data == "true"; + _gameRules.MobGriefing = gr["mobGriefing"].ToTagString().Data == "true"; + } + _source = ctree.Copy() as TagNodeCompound; return this; @@ -523,6 +752,31 @@ namespace Substrate data["hardcore"] = new TagNodeByte(_hardcore ?? 0); } + if (_generatorOptions != null) { + data["generatorOptions"] = new TagNodeString(_generatorOptions); + } + if (_generatorVersion != null) { + data["generatorVersion"] = new TagNodeInt(_generatorVersion ?? 0); + } + if (_allowCommands != null) { + data["allowCommands"] = new TagNodeByte(_allowCommands ?? 0); + } + if (_initialized != null) { + data["initialized"] = new TagNodeByte(_initialized ?? 0); + } + if (_DayTime != null) { + data["DayTime"] = new TagNodeLong(_DayTime ?? 0); + } + TagNodeCompound gr = new TagNodeCompound(); + gr["commandBlockOutput"] = new TagNodeString(_gameRules.CommandBlockOutput ? "true" : "false"); + gr["doFireTick"] = new TagNodeString(_gameRules.DoFireTick ? "true" : "false"); + gr["doMobLoot"] = new TagNodeString(_gameRules.DoMobLoot ? "true" : "false"); + gr["doMobSpawning"] = new TagNodeString(_gameRules.DoMobSpawning ? "true" : "false"); + gr["doTileDrops"] = new TagNodeString(_gameRules.DoTileDrops ? "true" : "false"); + gr["keepInventory"] = new TagNodeString(_gameRules.KeepInventory ? "true" : "false"); + gr["mobGriefing"] = new TagNodeString(_gameRules.MobGriefing ? "true" : "false"); + data["GameRules"] = gr; + if (_source != null) { data.MergeFrom(_source); } @@ -559,4 +813,4 @@ namespace Substrate #endregion } -} \ No newline at end of file +}