diff --git a/Substrate/SubstrateCS/Source/AlphaChunkManager.cs b/Substrate/SubstrateCS/Source/AlphaChunkManager.cs index f1c6cab..ee784b2 100644 --- a/Substrate/SubstrateCS/Source/AlphaChunkManager.cs +++ b/Substrate/SubstrateCS/Source/AlphaChunkManager.cs @@ -12,7 +12,7 @@ namespace Substrate /// /// Represents an Alpha-compatible interface for globally managing chunks. /// - public class AlphaChunkManager : IChunkManager + public class AlphaChunkManager : IChunkManager, IEnumerable { private string _mapPath; diff --git a/Substrate/SubstrateCS/Source/BlockInfo.cs b/Substrate/SubstrateCS/Source/BlockInfo.cs index 48cb416..6ff9c31 100644 --- a/Substrate/SubstrateCS/Source/BlockInfo.cs +++ b/Substrate/SubstrateCS/Source/BlockInfo.cs @@ -1,11 +1,12 @@ using System; using System.Collections.Generic; -using System.Text; +using Substrate.Nbt; namespace Substrate { - using Nbt; - + /// + /// Provides named id values for known block types. + /// public static class BlockType { public const int AIR = 0; @@ -107,20 +108,59 @@ namespace Substrate public const int TRAPDOOR = 96; } + /// + /// Represents the physical state of a block, such as solid or fluid. + /// public enum BlockState { + /// + /// A solid state that stops movement. + /// SOLID, + + /// + /// A nonsolid state that can be passed through. + /// NONSOLID, + + /// + /// A fluid state that flows and impedes movement. + /// FLUID } + /// + /// Provides information on a specific type of block. + /// + /// By default, all known MC block types are already defined and registered, assuming Substrate + /// is up to date with the current MC version. All unknown blocks are given a default type and unregistered status. + /// New block types may be created and used at runtime, and will automatically populate various static lookup tables + /// in the class. public class BlockInfo { + /// + /// The maximum number of sequential blocks starting at 0 that can be registered. + /// public const int MAX_BLOCKS = 256; + /// + /// The maximum opacity value that can be assigned to a block (fully opaque). + /// public const int MAX_OPACITY = 15; + + /// + /// The minimum opacity value that can be assigned to a block (fully transparent). + /// public const int MIN_OPACITY = 0; + + /// + /// The maximum luminance value that can be assigned to a block. + /// public const int MAX_LUMINANCE = 15; + + /// + /// The minimum luminance value that can be assigned to a block. + /// public const int MIN_LUMINANCE = 0; private static readonly BlockInfo[] _blockTable; @@ -193,61 +233,100 @@ namespace Substrate private static readonly CacheTableArray _opacityTableCache; private static readonly CacheTableArray _luminanceTableCache; + /// + /// Gets the lookup table for id-to-info values. + /// public static ICacheTable BlockTable { get { return _blockTableCache; } } + /// + /// Gets the lookup table for id-to-opacity values. + /// public static ICacheTable OpacityTable { get { return _opacityTableCache; } } + /// + /// Gets the lookup table for id-to-luminance values. + /// public static ICacheTable LuminanceTable { get { return _luminanceTableCache; } } + /// + /// Get's the block's Id. + /// public int ID { get { return _id; } } + /// + /// Get's the name of the block type. + /// public string Name { get { return _name; } } + /// + /// Gets the block's opacity value. An opacity of 0 is fully transparent to light. + /// public int Opacity { get { return _opacity; } } + /// + /// Gets the block's luminance value. + /// + /// Blocks with luminance act as light sources and transmit light to other blocks. public int Luminance { get { return _luminance; } } + /// + /// Checks whether the block transmits light to neighboring blocks. + /// + /// A block may stop the transmission of light, but still be illuminated. public bool TransmitsLight { get { return _transmitLight; } } + /// + /// Checks whether the block partially or fully blocks the transmission of light. + /// public bool ObscuresLight { get { return _opacity > MIN_OPACITY || !_transmitLight; } } + /// + /// Checks whether the block stops fluid from passing through it. + /// + /// A block that does not block fluids will be destroyed by fluid. public bool BlocksFluid { get { return _blocksFluid; } } + /// + /// Gets the block's physical state type. + /// public BlockState State { get { return _state; } } + /// + /// Checks whether this block type has been registered as a known type. + /// public bool Registered { get { return _registered; } @@ -260,6 +339,12 @@ namespace Substrate _blockTable[_id] = this; } + /// + /// Constructs a new record for a given block id and name. + /// + /// The id of the block. + /// The name of the block. + /// All user-constructed objects are registered automatically. public BlockInfo (int id, string name) { _id = id; @@ -268,6 +353,11 @@ namespace Substrate _registered = true; } + /// + /// Sets a new opacity value for this block type. + /// + /// A new opacity value. + /// The object instance used to invoke this method. public BlockInfo SetOpacity (int opacity) { _opacity = MIN_OPACITY + opacity; @@ -283,6 +373,11 @@ namespace Substrate return this; } + /// + /// Sets a new luminance value for this block type. + /// + /// A new luminance value. + /// The object instance used to invoke this method. public BlockInfo SetLuminance (int luminance) { _luminance = luminance; @@ -290,18 +385,35 @@ namespace Substrate return this; } + /// + /// Sets whether or not this block type will transmit light to neigboring blocks. + /// + /// True if this block type can transmit light to neighbors, false otherwise. + /// The object instance used to invoke this method. public BlockInfo SetLightTransmission (bool transmit) { _transmitLight = transmit; return this; } + /// + /// Sets limitations on what data values are considered valid for this block type. + /// + /// The lowest valid integer value. + /// The highest valid integer value. + /// A mask representing which bits are interpreted as a bitmask in the data value. + /// The object instance used to invoke this method. public BlockInfo SetDataLimits (int low, int high, int bitmask) { _dataLimits = new DataLimits(low, high, bitmask); return this; } + /// + /// Sets the physical state of the block type. + /// + /// A physical state. + /// The object instance used to invoke this method. public BlockInfo SetState (BlockState state) { _state = state; @@ -316,12 +428,23 @@ namespace Substrate return this; } + /// + /// Sets whether or not this block type blocks fluids. + /// + /// True if this block type blocks fluids, false otherwise. + /// The object instance used to invoke this method. public BlockInfo SetBlocksFluid (bool blocks) { _blocksFluid = blocks; return this; } + /// + /// Tests if the given data value is valid for this block type. + /// + /// A data value to test. + /// True if the data value is valid, false otherwise. + /// This method uses internal information set by . public bool TestData (int data) { if (_dataLimits == null) { @@ -617,19 +740,36 @@ namespace Substrate } } + /// + /// An extended that includes information. + /// public class BlockInfoEx : BlockInfo { private string _tileEntityName; + /// + /// Gets the name of the type associated with this block type. + /// public string TileEntityName { get { return _tileEntityName; } } - public BlockInfoEx (int id) : base(id) { } + internal BlockInfoEx (int id) : base(id) { } + /// + /// Constructs a new with a given block id and name. + /// + /// The id of the block type. + /// The name of the block type. public BlockInfoEx (int id, string name) : base(id, name) { } + /// + /// Sets the name of the type associated with this block type. + /// + /// The name of a registered type. + /// The object instance used to invoke this method. + /// public BlockInfo SetTileEntity (string name) { _tileEntityName = name; return this; diff --git a/Substrate/SubstrateCS/Source/Core/PlayerFile.cs b/Substrate/SubstrateCS/Source/Core/PlayerFile.cs index 8436abe..6cb38c2 100644 --- a/Substrate/SubstrateCS/Source/Core/PlayerFile.cs +++ b/Substrate/SubstrateCS/Source/Core/PlayerFile.cs @@ -23,5 +23,14 @@ namespace Substrate.Core string file = name + ".dat"; FileName = Path.Combine(path, file); } + + public static string NameFromFilename (string filename) + { + if (filename.EndsWith(".dat")) { + return filename.Remove(filename.Length - 4); + } + + return filename; + } } } diff --git a/Substrate/SubstrateCS/Source/ItemInfo.cs b/Substrate/SubstrateCS/Source/ItemInfo.cs index 26c1cd3..2d4714a 100644 --- a/Substrate/SubstrateCS/Source/ItemInfo.cs +++ b/Substrate/SubstrateCS/Source/ItemInfo.cs @@ -1,11 +1,12 @@ using System; using System.Collections.Generic; -using System.Text; +using Substrate.Nbt; namespace Substrate { - using Nbt; - + /// + /// Provides named id values for known item types. + /// public static class ItemType { public const int IRON_SHOVEL = 256; @@ -116,6 +117,13 @@ namespace Substrate public const int GREEN_MUSIC_DISC = 2257; } + /// + /// Provides information on a specific type of item. + /// + /// By default, all known MC item types are already defined and registered, assuming Substrate + /// is up to date with the current MC version. + /// New item types may be created and used at runtime, and will automatically populate various static lookup tables + /// in the class. public class ItemInfo { private static Random _rand = new Random(); @@ -150,32 +158,53 @@ namespace Substrate private static readonly CacheTableDict _itemTableCache; + /// + /// Gets the lookup table for id-to-info values. + /// public static ICacheTable ItemTable { get { return _itemTableCache; } } + /// + /// Gets the id of the item type. + /// public int ID { get { return _id; } } + /// + /// Gets the name of the item type. + /// public string Name { get { return _name; } } + /// + /// Gets the maximum stack size allowed for this item type. + /// public int StackSize { get { return _stack; } } + /// + /// Constructs a new record for the given item id. + /// + /// The id of an item type. public ItemInfo (int id) { _id = id; _itemTable[_id] = this; } + /// + /// Constructs a new record for the given item id and name. + /// + /// The id of an item type. + /// The name of an item type. public ItemInfo (int id, string name) { _id = id; @@ -183,12 +212,21 @@ namespace Substrate _itemTable[_id] = this; } + /// + /// Sets the maximum stack size for this item type. + /// + /// A stack size between 1 and 64, inclusive. + /// The object instance used to invoke this method. public ItemInfo SetStackSize (int stack) { _stack = stack; return this; } + /// + /// Chooses a registered item type at random and returns it. + /// + /// public static ItemInfo GetRandomItem () { List list = new List(_itemTable.Values); diff --git a/Substrate/SubstrateCS/Source/Player.cs b/Substrate/SubstrateCS/Source/Player.cs index a465cac..0d0b927 100644 --- a/Substrate/SubstrateCS/Source/Player.cs +++ b/Substrate/SubstrateCS/Source/Player.cs @@ -44,6 +44,7 @@ namespace Substrate private int? _spawnZ; private string _world; + private string _name; private ItemCollection _inventory; @@ -141,6 +142,15 @@ namespace Substrate set { _world = value; } } + /// + /// Gets or sets the name that is used when the player is read or written from a . + /// + public string Name + { + get { return _name; } + set { _name = value; } + } + /// /// Creates a new object with reasonable default values. /// diff --git a/Substrate/SubstrateCS/Source/PlayerManager.cs b/Substrate/SubstrateCS/Source/PlayerManager.cs index 16fefe8..8bcfe05 100644 --- a/Substrate/SubstrateCS/Source/PlayerManager.cs +++ b/Substrate/SubstrateCS/Source/PlayerManager.cs @@ -4,6 +4,8 @@ using System.Text; using System.IO; using Substrate.Core; using Substrate.Nbt; +using System.Text.RegularExpressions; +using System.Collections; namespace Substrate { @@ -11,7 +13,7 @@ namespace Substrate /// Functions to manage multiple entities and files in multiplayer settings. /// /// This manager is intended for player files stored in standard compressed NBT format. - public class PlayerManager : IPlayerManager + public class PlayerManager : IPlayerManager, IEnumerable { private string _playerPath; @@ -82,7 +84,9 @@ namespace Substrate } try { - return new Player().LoadTreeSafe(GetPlayerTree(name).Root); + Player p = new Player().LoadTreeSafe(GetPlayerTree(name).Root); + p.Name = name; + return p; } catch (Exception ex) { PlayerIOException pex = new PlayerIOException("Could not load player", ex); @@ -109,6 +113,16 @@ namespace Substrate } } + /// + /// Saves a object's data back to file given the name set in the object. + /// + /// The object containing the data to write back. + /// Thrown when the manager cannot write out the player. + public void SetPlayer (Player player) + { + SetPlayer(player.Name, player); + } + /// /// Checks if data for a player with the given name exists. /// @@ -135,5 +149,118 @@ namespace Substrate throw pex; } } + + #region IEnumerable Members + + /// + /// Gets an enumerator that iterates through all the chunks in the world. + /// + /// An enumerator for this manager. + public IEnumerator GetEnumerator () + { + return new Enumerator(this); + } + + #endregion + + #region IEnumerable Members + + System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator () + { + return new Enumerator(this); + } + + #endregion + + private class Enumerator : IEnumerator + { + protected PlayerManager _pm; + protected Queue _names; + + protected Player _curPlayer; + + public Enumerator (PlayerManager cfm) + { + _pm = cfm; + _names = new Queue(); + + if (!Directory.Exists(_pm._playerPath)) { + throw new DirectoryNotFoundException(); + } + + Reset(); + } + + public bool MoveNext () + { + if (_names.Count == 0) { + return false; + } + + string name = _names.Dequeue(); + _curPlayer = _pm.GetPlayer(name); + _curPlayer.Name = name; + + return true; + } + + public void Reset () + { + _names.Clear(); + _curPlayer = null; + + string[] files = Directory.GetFiles(_pm._playerPath); + foreach (string file in files) { + string basename = Path.GetFileName(file); + + if (!ParseFileName(basename)) { + continue; + } + + _names.Enqueue(PlayerFile.NameFromFilename(basename)); + } + } + + void IDisposable.Dispose () { } + + object IEnumerator.Current + { + get + { + return Current; + } + } + + Player IEnumerator.Current + { + get + { + return Current; + } + } + + public Player Current + { + get + { + if (_curPlayer == null) { + throw new InvalidOperationException(); + } + return _curPlayer; + } + } + + private bool ParseFileName (string filename) + { + Match match = _namePattern.Match(filename); + if (!match.Success) { + return false; + } + + return true; + } + + protected static Regex _namePattern = new Regex(".+\\.dat$"); + } } }