Minecraft.psm1

function ConvertTo-NetherCoordinates {
    <#
    .SYNOPSIS
        Converts Overworld coordinates to their equivalent Nether coordinates.
 
    .DESCRIPTION
        The ConvertTo-NetherCoordinates cmdlet converts a pair of Overworld X/Z coordinates into the equivalent
        Nether coordinates, by dividing each value by 8. The result is rounded down to the nearest whole
        number (block coordinates in Minecraft are always whole numbers), matching the game's own conversion
        behavior.
 
    .EXAMPLE
        ConvertTo-NetherCoordinates -X 800 -Z -400
 
        Returns the Nether coordinates equivalent to Overworld coordinates X 800, Z -400, i.e. X 100, Z -50.
 
    .EXAMPLE
        ConvertTo-NetherCoordinates 1600 240
 
        X and Z are positional, so they don't need to be named explicitly.
 
    .EXAMPLE
        [pscustomobject]@{ X = 240; Z = 88 } | ConvertTo-NetherCoordinates
 
        X and Z can also be supplied via the pipeline by property name, e.g. from an object such as one
        recording a player's Overworld position.
    #>

    [CmdletBinding()]
    [OutputType([pscustomobject])]
    Param(
        # The Overworld X coordinate to convert.
        [Parameter(Mandatory, Position = 0, ValueFromPipelineByPropertyName)]
        [double]
        $X,

        # The Overworld Z coordinate to convert.
        [Parameter(Mandatory, Position = 1, ValueFromPipelineByPropertyName)]
        [double]
        $Z
    )
    Process {
        [pscustomobject]@{
            X = [int][Math]::Floor($X / 8)
            Z = [int][Math]::Floor($Z / 8)
        }
    }
}
function ConvertTo-OverworldCoordinates {
    <#
    .SYNOPSIS
        Converts Nether coordinates to their equivalent Overworld coordinates.
 
    .DESCRIPTION
        The ConvertTo-OverworldCoordinates cmdlet converts a pair of Nether X/Z coordinates into the equivalent
        Overworld coordinates, by multiplying each value by 8, reflecting the Nether's 1:8 scale relative to
        the Overworld.
 
    .EXAMPLE
        ConvertTo-OverworldCoordinates -X 100 -Z -50
 
        Returns the Overworld coordinates equivalent to Nether coordinates X 100, Z -50, i.e. X 800, Z -400.
 
    .EXAMPLE
        ConvertTo-OverworldCoordinates 200 30
 
        X and Z are positional, so they don't need to be named explicitly.
 
    .EXAMPLE
        [pscustomobject]@{ X = 30; Z = 11 } | ConvertTo-OverworldCoordinates
 
        X and Z can also be supplied via the pipeline by property name, e.g. from an object such as one
        recording a player's Nether position.
    #>

    [CmdletBinding()]
    [OutputType([pscustomobject])]
    Param(
        # The Nether X coordinate to convert.
        [Parameter(Mandatory, Position = 0, ValueFromPipelineByPropertyName)]
        [double]
        $X,

        # The Nether Z coordinate to convert.
        [Parameter(Mandatory, Position = 1, ValueFromPipelineByPropertyName)]
        [double]
        $Z
    )
    Process {
        [pscustomobject]@{
            X = [int]($X * 8)
            Z = [int]($Z * 8)
        }
    }
}
function New-Coordinates {
    <#
    .SYNOPSIS
        Creates a coordinates object with X and Z properties.
 
    .DESCRIPTION
        The New-Coordinates cmdlet returns a PowerShell object with X and Z properties, for use as input to
        the other coordinate conversion cmdlets in this module, or anywhere else a simple X/Z position is
        needed.
 
    .EXAMPLE
        New-Coordinates -X 800 -Z -400
 
        Returns a coordinates object with X 800, Z -400.
 
    .EXAMPLE
        New-Coordinates 1600 240
 
        X and Z are positional, so they don't need to be named explicitly.
 
    .EXAMPLE
        New-Coordinates -X 800 -Z -400 | ConvertTo-NetherCoordinates
 
        The returned object can be passed directly into ConvertTo-NetherCoordinates or
        ConvertTo-OverworldCoordinates via the pipeline.
    #>

    [Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSUseShouldProcessForStateChangingFunctions', '',
        Justification = 'Creates an in-memory object only; there is no system state to confirm changing.')]
    [CmdletBinding()]
    [OutputType([pscustomobject])]
    Param(
        # The X coordinate.
        [Parameter(Mandatory, Position = 0)]
        [double]
        $X,

        # The Z coordinate.
        [Parameter(Mandatory, Position = 1)]
        [double]
        $Z
    )
    [pscustomobject]@{
        X = $X
        Z = $Z
    }
}