diff --git a/Substrate/SubstrateCS/Examples/BlockReplace/BlockReplace.csproj b/Substrate/SubstrateCS/Examples/BlockReplace/BlockReplace.csproj new file mode 100644 index 0000000..4df719a --- /dev/null +++ b/Substrate/SubstrateCS/Examples/BlockReplace/BlockReplace.csproj @@ -0,0 +1,56 @@ + + + + Debug + AnyCPU + 9.0.30729 + 2.0 + {6D24D262-34D3-43A6-B066-1312A0C72B16} + Exe + Properties + BlockReplace + BlockReplace + v4.0 + 512 + + + + + 3.5 + + + true + full + false + bin\Debug\ + DEBUG;TRACE + prompt + 4 + + + pdbonly + true + bin\Release\ + TRACE + prompt + 4 + + + + ..\..\bin\Release\Substrate.dll + + + + + + + + + + \ No newline at end of file diff --git a/Substrate/SubstrateCS/Examples/BlockReplace/Program.cs b/Substrate/SubstrateCS/Examples/BlockReplace/Program.cs new file mode 100644 index 0000000..c106e8c --- /dev/null +++ b/Substrate/SubstrateCS/Examples/BlockReplace/Program.cs @@ -0,0 +1,61 @@ +using System; +using Substrate; + +// This example replaces all instances of one block ID with another in a world. +// Substrate will handle all of the lower-level headaches that can pop up, such +// as maintaining correct lighting or replacing TileEntity records for blocks +// that need them. + +// For a more advanced Block Replace example, see replace.cs in NBToolkit. + +namespace BlockReplace +{ + class Program + { + static void Main (string[] args) + { + if (args.Length != 3) { + Console.WriteLine("Usage: BlockReplace "); + return; + } + + string dest = args[0]; + int before = Convert.ToInt32(args[1]); + int after = Convert.ToInt32(args[2]); + + // Open our world + BetaWorld world = BetaWorld.Open(dest); + + // The chunk manager is more efficient than the block manager for + // this purpose, since we'll inspect every block + ChunkManager cm = world.GetChunkManager(); + + foreach (ChunkRef chunk in cm) { + // You could hardcode your dimensions, but maybe some day they + // won't always be 16. Also the CLR is a bit stupid and has + // trouble optimizing repeated calls to Chunk.Blocks.xx, so we + // cache them in locals + int xdim = chunk.Blocks.XDim; + int ydim = chunk.Blocks.YDim; + int zdim = chunk.Blocks.ZDim; + + // x, z, y is the most efficient order to scan blocks (not that + // you should care about internal detail) + for (int x = 0; x < xdim; x++) { + for (int z = 0; z < zdim; z++) { + for (int y = 0; y < ydim; y++) { + + // Replace the block with after if it matches before + if (chunk.Blocks.GetID(x, y, z) == before) { + chunk.Blocks.SetID(x, y, z, after); + } + } + } + } + + // Save the chunk + cm.Save(); + } + } + } +} diff --git a/Substrate/SubstrateCS/Examples/BlockReplace/Properties/AssemblyInfo.cs b/Substrate/SubstrateCS/Examples/BlockReplace/Properties/AssemblyInfo.cs new file mode 100644 index 0000000..3cf8e7a --- /dev/null +++ b/Substrate/SubstrateCS/Examples/BlockReplace/Properties/AssemblyInfo.cs @@ -0,0 +1,36 @@ +using System.Reflection; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; + +// General Information about an assembly is controlled through the following +// set of attributes. Change these attribute values to modify the information +// associated with an assembly. +[assembly: AssemblyTitle("BlockReplace")] +[assembly: AssemblyDescription("")] +[assembly: AssemblyConfiguration("")] +[assembly: AssemblyCompany("Microsoft")] +[assembly: AssemblyProduct("BlockReplace")] +[assembly: AssemblyCopyright("Copyright © Microsoft 2011")] +[assembly: AssemblyTrademark("")] +[assembly: AssemblyCulture("")] + +// Setting ComVisible to false makes the types in this assembly not visible +// to COM components. If you need to access a type in this assembly from +// COM, set the ComVisible attribute to true on that type. +[assembly: ComVisible(false)] + +// The following GUID is for the ID of the typelib if this project is exposed to COM +[assembly: Guid("672d767f-c56e-42eb-8583-a835bcf7d4a0")] + +// Version information for an assembly consists of the following four values: +// +// Major Version +// Minor Version +// Build Number +// Revision +// +// You can specify all the values or you can default the Build and Revision Numbers +// by using the '*' as shown below: +// [assembly: AssemblyVersion("1.0.*")] +[assembly: AssemblyVersion("1.0.0.0")] +[assembly: AssemblyFileVersion("1.0.0.0")] diff --git a/Substrate/SubstrateCS/Examples/FlatMap/Program.cs b/Substrate/SubstrateCS/Examples/FlatMap/Program.cs index 70f816f..572b60b 100644 --- a/Substrate/SubstrateCS/Examples/FlatMap/Program.cs +++ b/Substrate/SubstrateCS/Examples/FlatMap/Program.cs @@ -27,7 +27,10 @@ namespace FlatMap world.Level.SpawnX = 20; world.Level.SpawnZ = 20; world.Level.SpawnY = 70; - //world.Level.SetDefaultPlayer(); + + // world.Level.SetDefaultPlayer(); + // We'll let MC create the player for us, but you could use the above + // line to create the SSP player entry in level.dat. // We'll create chunks at chunk coordinates xmin,zmin to xmax,zmax for (int xi = xmin; xi < xmax; xi++) { diff --git a/Substrate/SubstrateCS/Examples/MoveSpawn/Program.cs b/Substrate/SubstrateCS/Examples/MoveSpawn/Program.cs index 01a7e76..5f5ea5e 100644 --- a/Substrate/SubstrateCS/Examples/MoveSpawn/Program.cs +++ b/Substrate/SubstrateCS/Examples/MoveSpawn/Program.cs @@ -1,10 +1,9 @@ using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; - using Substrate; +// MoveSpawn changes the location of the world spawn location +// (which is separate from individual player spawn locations) + namespace MoveSpawn { class Program @@ -21,12 +20,18 @@ namespace MoveSpawn int y = Convert.ToInt32(args[2]); int z = Convert.ToInt32(args[3]); + // Open our world BetaWorld world = BetaWorld.Open(dest); + // Set the level's spawn + // Note: Players do not have separate spawns by default + // If you wanted to change a player's spawn, you must set all + // 3 coordinates for it to stick. It will not take the level's defaults. world.Level.SpawnX = x; world.Level.SpawnY = y; world.Level.SpawnZ = z; + // Save the changes world.Save(); } } diff --git a/Substrate/SubstrateCS/Examples/PurgeEntities/Program.cs b/Substrate/SubstrateCS/Examples/PurgeEntities/Program.cs index 59b8c66..f53e0b6 100644 --- a/Substrate/SubstrateCS/Examples/PurgeEntities/Program.cs +++ b/Substrate/SubstrateCS/Examples/PurgeEntities/Program.cs @@ -2,6 +2,10 @@ using System.Collections.Generic; using Substrate; +// This example is a tool to delete all entities of a given type (e.g., "pig") +// on a map. It optionally can be restricted to boxed region in block coords. +// Only 10% of the effort is actually spend purging anything. + namespace PurgeEntities { class Program @@ -16,11 +20,13 @@ namespace PurgeEntities string dest = args[0]; string eid = args[1]; + // Our initial bounding box is "infinite" int x1 = BlockManager.MIN_X; int x2 = BlockManager.MAX_X; int z1 = BlockManager.MIN_Z; int z2 = BlockManager.MAX_Z; + // If we have all coordinate parameters, set the bounding box if (args.Length == 6) { x1 = Convert.ToInt32(args[2]); z1 = Convert.ToInt32(args[3]); diff --git a/Substrate/SubstrateCS/Examples/Relight/Program.cs b/Substrate/SubstrateCS/Examples/Relight/Program.cs index b781e87..23f47bd 100644 --- a/Substrate/SubstrateCS/Examples/Relight/Program.cs +++ b/Substrate/SubstrateCS/Examples/Relight/Program.cs @@ -1,6 +1,16 @@ using System; using Substrate; +// This example will reset and rebuild the lighting (heightmap, block light, +// skylight) for all chunks in a map. + +// Note: If it looks silly to reset the lighting, loading and saving +// all the chunks, just to load and save them again later: it's not. +// If the world lighting is not correct, it must be completely reset +// before rebuilding the light in any chunks. That's just how the +// algorithms work, in order to limit the number of chunks that must +// be loaded at any given time. + namespace Relight { class Program