====== cBlockArea class ======
This class is used when multiple adjacent blocks are to be manipulated. Because of chunking and multithreading, manipulating single blocks using [[api:cWorld|cWorld:SetBlock]]() is a rather time-consuming operation (locks for exclusive access need to be obtained, chunk lookup is done for each block), so whenever you need to manipulate multiple adjacent blocks, it's better to wrap the operation into a cBlockArea access. cBlockArea is capable of reading / writing across chunk boundaries, has no chunk lookups for get and set operations and is not subject to multithreading locking (because it is not shared among threads).

cBlockArea remembers its origin (MinX, MinY, MinZ coords in the Read() call) and therefore supports absolute as well as relative get / set operations. Despite that, the contents of a cBlockArea can be written back into the world at any coords.

cBlockArea can hold any combination of the following datatypes: 
  * block types
  * block metas
  * blocklight
  * skylight
Read() and Write() functions have parameters that tell the class which datatypes to read / write. Note that a datatype that has not been read cannot be written (FIXME).

Typical usage:
  * Create cBlockArea object
  * Read an area from the world
  * Modify blocks inside cBlockArea
  * Write the area back to a world

===== Constants =====
Several constants are used as enumerated values. The DataTypes specifier is a bitmask of the following constants that specifies what data the operations work on:
^ Constant ^ Meaning ^
| baTypes | Operation should work on block types |
| baMetas | Operations should work on block metas |
| baLight | Operations should work on block (emissive) light |
| baSkyLight | Operations should work on skylight |
Note that light and skylight are not supported in all operations and usually are to be used only for querying, not for writing.

The MergeStrategy specifies the strategy to use when merging two block areas. One of the following values are used:
^ Constant ^ Value ^
| msOverwrite | Src overwrites anything in Dst |
| msFillAir | Dst is overwritten by Src only where Src has air blocks |
| msImprint | Src overwrites Dst anywhere where Dst has non-air blocks |
| msLake | Special mode for merging lake images |

===== Functions =====
^ Function name ^ Parameters ^ Return value ^ Note ^
| Clear | | | Clears the object, resets it to zero size |
| CopyFrom | BlockAreaSrc | | Copies contents from BlockAreaSrc into self |
| CopyTo | BlockAreaDst | | Copies contents from self into BlockAreaDst. |
| Create | SizeX, SizeY, SizeZ, [DataTypes] | | Initializes this BlockArea to an empty area of the specified size and origin of {0, 0, 0}. Any previous contents are lost. |
| Crop | AddMinX, SubMaxX, AddMinY, SubMaxY, AddMinZ, SubMaxZ | | Crops the specified number of blocks from each border. Modifies the size of this blockarea object. |
| DumpToRawFile | FileName | | Dumps the raw data into a file. For debugging purposes only. |
| Expand | SubMinX, AddMaxX, SubMinY, AddMaxY, SubMinZ, AddMaxZ | | Expands the specified number of blocks from each border. Modifies the size of this blockarea object. New blocks created with this operation are filled with zeroes. |
| Fill | DataTypes, BlockType, [BlockMeta], [BlockLight], [BlockSkyLight] | | Fills the entire block area with the same values, specified. Uses the DataTypes param to determine which content types are modified. |
| FillRelCuboid | MinRelX, MaxRelX, MinRelY, MaxRelY, MinRelZ, MaxRelZ, DataTypes, BlockType, [BlockMeta], [BlockLight], [BlockSkyLight] | | Fills the specified cuboid with the same values (like Fill() ). |
| GetBlockLight | BlockX, BlockY, BlockZ | NIBBLETYPE | Returns the blocklight at the specified absolute coords |
| GetBlockMeta | BlockX, BlockY, BlockZ | NIBBLETYPE | Returns the block meta at the specified absolute coords |
| GetBlockSkyLight | BlockX, BlockY, BlockZ | NIBBLETYPE | Returns the skylight at the specified absolute coords |
| GetBlockType | BlockX, BlockY, BlockZ | BLOCKTYPE | Returns the block type at the specified absolute coords |
| GetBlockTypeMeta | BlockX, BlockY, BlockZ | BLOCKTYPE, NIBBLETYPE | Returns the block type and meta at the specified absolute coords |
| GetDataTypes | | number | Returns the mask of datatypes that the objectis currently holding |
| GetOriginX | | number | Returns the origin x-coord |
| GetOriginY | | number | Returns the origin y-coord |
| GetOriginZ | | number | Returns the origin z-coord |
| GetRelBlockLight | RelBlockX, RelBlockY, RelBlockZ | NIBBLETYPE | Returns the blocklight at the specified relative coords |
| GetRelBlockMeta | RelBlockX, RelBlockY, RelBlockZ | NIBBLETYPE | Returns the block meta at the specified relative coords |
| GetRelBlockSkyLight | RelBlockX, RelBlockY, RelBlockZ | NIBBLETYPE | Returns the skylight at the specified relative coords |
| GetRelBlockType | RelBlockX, RelBlockY, RelBlockZ | BLOCKTYPE | Returns the block type at the specified relative coords |
| GetRelBlockTypeMeta | RelBlockX, RelBlockY, RelBlockZ | NIBBLETYPE | Returns the block type and meta at the specified relative coords |
| GetSizeX | | number | Returns the size of the held data in the x-axis |
| GetSizeY | | number | Returns the size of the held data in the y-axis |
| GetSizeZ | | number | Returns the size of the held data in the z-axis |
| HasBlockLights | | bool | Returns true if current datatypes include blocklight |
| HasBlockMetas | | bool | Returns true if current datatypes include block metas |
| HasBlockSkyLights | | bool | Returns true if current datatypes include skylight |
| HasBlockTypes | | bool | Returns true if current datatypes include block types |
| LoadFromSchematicFile | FileName | | Clears current content and loads new content from the specified schematic file. Returns true if successful. Returns false and logs error if unsuccessful, old content is preserved in such a case. |
| Merge | BlockAreaSrc, RelX, RelY, RelZ, Strategy | | Merges BlockAreaSrc into this object at the specified relative coords, using the specified strategy |
| MirrorXY | | | Mirrors this block area around the XY plane. Modifies blocks' metas (if present) to match (i. e. furnaces facing the opposite direction). |
| MirrorXYNoMeta | | | Mirrors this block area around the XY plane. Doesn't modify blocks' metas. |
| MirrorXZ | | | Mirrors this block area around the XZ plane. Modifies blocks' metas (if present) |
| MirrorXZNoMeta | | | Mirrors this block area around the XZ plane. Doesn't modify blocks' metas. |
| MirrorYZ | | | Mirrors this block area around the YZ plane. Modifies blocks' metas (if present) |
| MirrorYZNoMeta | | | Mirrors this block area around the YZ plane. Doesn't modify blocks' metas. |
| Read | World, MinX, MaxX, MinY, MaxY, MinZ, MaxZ, DataTypes | bool | Reads the area from World, returns true if successful |
| RelLine | RelX1, RelY1, RelZ1, RelX2, RelY2, RelZ2, DataTypes, BlockType, [BlockMeta], [BlockLight], [BlockSkyLight] | | Draws a line between the two specified points. Sets only datatypes specified by DataTypes. |
| RotateCCW | | | Rotates the block area around the Y axis, counter-clockwise (east -> north). Modifies blocks' metas (if present) to match. |
| RotateCCWNoMeta | | | Rotates the block area around the Y axis, counter-clockwise (east -> north). Doesn't modify blocks' metas. |
| RotateCW | | | Rotates the block area around the Y axis, clockwise (north -> east). Modifies blocks' metas (if present) to match. |
| RotateCWNoMeta | | | Rotates the block area around the Y axis, clockwise (north -> east). Doesn't modify blocks' metas. |
| SaveToSchematicFile | FileName | | Saves the current contents to a schematic file. Returns true if successful. |
| SetBlockLight | BlockX, BlockY, BlockZ, BlockLight | | Sets the blocklight at the specified absolute coords |
| SetBlockMeta | BlockX, BlockY, BlockZ, BlockMeta | | Sets the block meta at the specified absolute coords |
| SetBlockSkyLight | BlockX, BlockY, BlockZ, SkyLight | | Sets the skylight at the specified absolute coords |
| SetBlockType | BlockX, BlockY, BlockZ, BlockType | | Sets the block type at the specified absolute coords |
| SetRelBlockLight | RelBlockX, RelBlockY, RelBlockZ, BlockLight | | Sets the blocklight at the specified relative coords |
| SetRelBlockMeta | RelBlockX, RelBlockY, RelBlockZ, BlockMeta | | Sets the block meta at the specified relative coords |
| SetRelBlockSkyLight | RelBlockX, RelBlockY, RelBlockZ, SkyLight | | Sets the skylight at the specified relative coords |
| SetRelBlockType | RelBlockX, RelBlockY, RelBlockZ, BlockType | | Sets the block type at the specified relative coords |
| Write | World, MinX, MinY, MinZ, DataTypes | bool | Writes the area into World at the specified coords, returns true if successful |

===== Merge strategies =====
The strategy parameter specifies how individual blocks are combined together, using the table below.

^ area block ^^                 result           ^^^
^ this ^ Src ^ msOverwrite ^ msFillAir ^ msImprint ^
| air  | air | air         | air       | air       |
| A    | air | air         | A         | A         |
| air  | B   | B           | B         | B         |
| A    | B   | B           | A         | B         |

So to sum up:
  - msOverwrite completely overwrites all blocks with the Src's blocks
  - msFillAir overwrites only those blocks that were air
  - msImprint overwrites with only those blocks that are non-air

Special strategies:

**msLake** (evaluate top-down, first match wins):
^    area block    ^^        ^ Notes ^
^   this   ^ Src    ^ result ^ ^
| A        | sponge | A      | Sponge is the NOP block |
| *        | air    | air    | Air always gets hollowed out, even under the oceans |
| water    | *      | water  | Water is never overwritten |
| lava     | *      | lava   | Lava is never overwritten |
| *        | water  | water  | Water always overwrites anything |
| *        | lava   | lava   | Lava always overwrites anything |
| dirt     | stone  | stone  | Stone overwrites dirt |
| grass    | stone  | stone  | ... and grass |
| mycelium | stone  | stone  | ... and mycelium |
| A        | stone  | A      | ... but nothing else |
| A        | *      | A      | Everything else is left as it is |
