"""### Generate a simple example village.
This file contains a comprehensive collection of functions designed
to introduce new coders to the GDMC HTTP client in Python.
The source code of this module contains examples for:
* How to structure a file neatly (search 'STRUCTURE')
* Requesting the build area (search 'BUILDAREA')
* Introduction to world slices (search 'WORLDSLICE')
* Introduction to basic heightmaps (search 'HEIGHTMAP')
* Introduction to basic geometric shapes (search 'GEO')
"""
# === STRUCTURE #1
# These are the modules (libraries) we will use in this code
# We are giving these modules shorter, but distinct, names for convenience
from random import randint
from gdpc import geometry as GEO
from gdpc import interface as INTF
from gdpc import toolbox as TB
from gdpc import worldLoader as WL
# === STRUCTURE #2
# These variables are global and can be read from anywhere in the code
# I like to write them in capitals so I know they're global
# Here we read start and end coordinates of our build area
STARTX, STARTY, STARTZ, ENDX, ENDY, ENDZ = INTF.requestBuildArea() # BUILDAREA
# WORLDSLICE
# Using the start and end coordinates we are generating a world slice
# It contains all manner of information, including heightmaps and biomes
# For further information on what information it contains, see
# https://minecraft.fandom.com/wiki/Chunk_format
#
# IMPORTANT: Keep in mind that a wold slice is a 'snapshot' of the world,
# and any changes you make later on will not be reflected in the world slice
WORLDSLICE = WL.WorldSlice(STARTX, STARTZ,
ENDX + 1, ENDZ + 1) # this takes a while
ROADHEIGHT = 0
# === STRUCTURE #3
# Here we are defining all of our functions to keep our code organised
# They are:
# - buildPerimeter()
# - buildRoads()
# - buildCity()
def buildPerimeter():
"""Build a wall along the build area border.
In this function we're building a simple wall around the build area
pillar-by-pillar, which means we can adjust to the terrain height
"""
# HEIGHTMAP
# Heightmaps are an easy way to get the uppermost block at any coordinate
# There are four types available in a world slice:
# - 'WORLD_SURFACE': The top non-air blocks
# - 'MOTION_BLOCKING': The top blocks with a hitbox or fluid
# - 'MOTION_BLOCKING_NO_LEAVES': Like MOTION_BLOCKING but ignoring leaves
# - 'OCEAN_FLOOR': The top solid blocks
heights = WORLDSLICE.heightmaps["MOTION_BLOCKING_NO_LEAVES"]
print("Building east-west walls...")
# building the east-west walls
for x in range(STARTX, ENDX + 1):
# the northern wall
y = heights[(x, STARTZ)]
GEO.placeCuboid(x, y - 2, STARTZ, x, y, STARTZ, "granite")
GEO.placeCuboid(x, y + 1, STARTZ, x, y + 4, STARTZ, "granite_wall")
# the southern wall
y = heights[(x, ENDZ)]
GEO.placeCuboid(x, y - 2, ENDZ, x, y, ENDZ, "red_sandstone")
GEO.placeCuboid(x, y + 1, ENDZ, x, y + 4, ENDZ, "red_sandstone_wall")
print("Building north-south walls...")
# building the north-south walls
for z in range(STARTZ, ENDZ + 1):
# the western wall
y = heights[(STARTX, z)]
GEO.placeCuboid(STARTX, y - 2, z, STARTX, y, z, "sandstone")
GEO.placeCuboid(STARTX, y + 1, z, STARTX, y + 4, z, "sandstone_wall")
# the eastern wall
y = heights[(ENDX, z)]
GEO.placeCuboid(ENDX, y - 2, z, ENDX, y, z, "prismarine")
GEO.placeCuboid(ENDX, y + 1, z, ENDX, y + 4, z, "prismarine_wall")
def buildRoads():
"""Build a road from north to south and east to west."""
xaxis = STARTX + (ENDX - STARTX) // 2 # getting start + half the length
zaxis = STARTZ + (ENDZ - STARTZ) // 2
heights = WORLDSLICE.heightmaps["MOTION_BLOCKING_NO_LEAVES"]
print("Calculating road height...")
# caclulating the average height along where we want to build our road
y = heights[(xaxis, zaxis)]
for x in range(STARTX, ENDX + 1):
newy = heights[(x, zaxis)]
y = (y + newy) // 2
for z in range(STARTZ, ENDZ + 1):
newy = heights[(xaxis, z)]
y = (y + newy) // 2
# GLOBAL
# By calling 'global ROADHEIGHT' we allow writing to ROADHEIGHT
# If 'global' is not called, a new, local variable is created
global ROADHEIGHT
ROADHEIGHT = y
print("Building east-west road...")
# building the east-west road
GEO.placeCuboid(xaxis - 2, y, STARTZ,
xaxis - 2, y, ENDZ, "end_stone_bricks")
GEO.placeCuboid(xaxis - 1, y, STARTZ,
xaxis + 1, y, ENDZ, "gold_block")
GEO.placeCuboid(xaxis + 2, y, STARTZ,
xaxis + 2, y, ENDZ, "end_stone_bricks")
GEO.placeCuboid(xaxis - 1, y + 1, STARTZ,
xaxis + 1, y + 3, ENDZ, "air")
print("Building north-south road...")
# building the north-south road
GEO.placeCuboid(STARTX, y, zaxis - 2,
ENDX, y, zaxis - 2, "end_stone_bricks")
GEO.placeCuboid(STARTX, y, zaxis - 1,
ENDX, y, zaxis + 1, "gold_block")
GEO.placeCuboid(STARTX, y, zaxis + 2,
ENDX, y, zaxis + 2, "end_stone_bricks")
GEO.placeCuboid(STARTX, y + 1, zaxis - 1,
ENDX, y + 3, zaxis + 1, "air")
def buildCity():
xaxis = STARTX + (ENDX - STARTX) // 2 # getting center
zaxis = STARTZ + (ENDZ - STARTZ) // 2
y = ROADHEIGHT
print("Building city platform...")
# Building a platform and clearing a dome for the city to sit in
GEO.placeCenteredCylinder(xaxis, y, zaxis, 1, 21, "end_stone_bricks")
GEO.placeCenteredCylinder(xaxis, y, zaxis, 1, 20, "gold_block")
GEO.placeCenteredCylinder(xaxis, y + 1, zaxis, 3, 20, "air")
GEO.placeCenteredCylinder(xaxis, y + 4, zaxis, 2, 19, "air")
GEO.placeCenteredCylinder(xaxis, y + 6, zaxis, 1, 18, "air")
GEO.placeCenteredCylinder(xaxis, y + 7, zaxis, 1, 17, "air")
GEO.placeCenteredCylinder(xaxis, y + 8, zaxis, 1, 15, "air")
GEO.placeCenteredCylinder(xaxis, y + 9, zaxis, 1, 12, "air")
GEO.placeCenteredCylinder(xaxis, y + 10, zaxis, 1, 8, "air")
GEO.placeCenteredCylinder(xaxis, y + 11, zaxis, 1, 3, "air")
for i in range(50):
buildTower(randint(xaxis - 20, xaxis + 20),
randint(zaxis - 20, zaxis + 20))
# Place a book on a Lectern
# See the wiki for book formatting codes
INTF.placeBlock(xaxis, y, zaxis, "emerald_block")
bookData = TB.writeBook("This book has a page!")
TB.placeLectern(xaxis, y + 1, zaxis, bookData)
def buildTower(x, z):
radius = 3
y = ROADHEIGHT
print(f"Building tower at {x}, {z}...")
# if the blocks to the north, south, east and west aren't all gold
if not (INTF.getBlock(x - radius, y, z) == "minecraft:gold_block"
and INTF.getBlock(x + radius, y, z) == "minecraft:gold_block"
and INTF.getBlock(x, y, z - radius) == "minecraft:gold_block"
and INTF.getBlock(x, y, z + radius) == "minecraft:gold_block"):
return # return without building anything
# lay the foundation
GEO.placeCenteredCylinder(x, y, z, 1, radius, "emerald_block")
# build ground floor
GEO.placeCenteredCylinder(x, y + 1, z, 3, radius,
"lime_concrete", tube=True)
# extend height
height = randint(5, 20)
GEO.placeCenteredCylinder(
x, y + 4, z, height, radius, "lime_concrete", tube=True)
height += 4
# build roof
GEO.placeCenteredCylinder(x, y + height, z, 1, radius, "emerald_block")
GEO.placeCenteredCylinder(x, y + height + 1, z, 1,
radius - 1, "emerald_block")
GEO.placeCenteredCylinder(x, y + height + 2, z, 1,
radius - 2, "emerald_block")
GEO.placeCuboid(x, y + height, z, x, y + height
+ 2, z, "lime_stained_glass")
INTF.placeBlock(x, y + 1, z, "beacon")
# trim sides and add windows and doors
# GEO.placeCuboid(x + radius, y + 1, z, x + radius, y + height + 2, z, "air")
GEO.placeCuboid(x + radius - 1, y + 1, z,
x + radius - 1, y + height + 2, z, "lime_stained_glass")
# NOTE: When placing doors you need to place two blocks,
# the upper block defines the direction
INTF.placeBlock(x + radius - 1, y + 1, z, "warped_door")
INTF.placeBlock(x + radius - 1, y + 2, z,
"warped_door[facing=west, half=upper]")
GEO.placeCuboid(x - radius, y + 1, z, x - radius, y + height + 2, z, "air")
GEO.placeCuboid(x - radius + 1, y + 1, z,
x - radius + 1, y + height + 2, z, "lime_stained_glass")
INTF.placeBlock(x - radius + 1, y + 1, z, "warped_door")
INTF.placeBlock(x - radius + 1, y + 2, z,
"warped_door[facing=east, half=upper]")
GEO.placeCuboid(x, y + 1, z + radius, x, y + height + 2, z + radius, "air")
GEO.placeCuboid(x, y + 1, z + radius - 1,
x, y + height + 2, z + radius - 1, "lime_stained_glass")
INTF.placeBlock(x, y + 1, z + radius - 1, "warped_door")
INTF.placeBlock(x, y + 2, z + radius - 1,
"warped_door[facing=south, half=upper]")
GEO.placeCuboid(x, y + 1, z - radius, x, y + height + 2, z - radius, "air")
GEO.placeCuboid(x, y + 1, z - radius + 1,
x, y + height + 2, z - radius + 1, "lime_stained_glass")
INTF.placeBlock(x, y + 1, z - radius + 1, "warped_door")
INTF.placeBlock(x, y + 2, z - radius + 1,
"warped_door[facing=north, half=upper]")
def buildStatue(x, z):
"""
Build a statue of Steve, the minecraft character.
"""
y = ROADHEIGHT
# build the base
GEO.placeCuboid(x - 1, y, z - 1, x + 1, y, z + 1, "emerald_block")
GEO.placeCuboid(x - 1, y + 1, z - 1, x + 1, y + 1, z + 1, "emerald_block")
GEO.placeCuboid(x - 1, y + 2, z - 1, x + 1, y + 2, z + 1, "emerald_block")
GEO.placeCuboid(x - 1, y + 3, z - 1, x + 1, y + 3, z + 1, "emerald_block")
GEO.placeCuboid(x - 1, y + 4, z - 1, x + 1, y + 4, z + 1, "emerald_block")
GEO.placeCuboid(x - 1, y + 5, z - 1, x + 1, y + 5, z + 1, "emerald_block")
GEO.placeCuboid(x - 1, y + 6, z - 1, x + 1, y + 6, z + 1, "emerald_block")
GEO.placeCuboid(x - 1, y + 7, z - 1, x + 1, y + 7, z + 1, "emerald_block")
GEO.placeCuboid(x - 1, y + 8, z - 1, x + 1, y + 8, z + 1, "emerald_block")
GEO.placeCuboid(x - 1, y + 9, z - 1, x + 1, y + 9, z + 1, "emerald_block")
GEO.placeCuboid(x - 1, y + 10, z - 1, x + 1, y + 10, z + 1, "emerald_block")
GEO.placeCuboid(x - 1, y + 11, z - 1, x + 1, y + 11, z + 1, "emerald_block")
GEO.placeCuboid(x - 1, y + 12, z - 1, x + 1, y + 12, z + 1, "emerald_block")
GEO.placeCuboid(x - 1, y + 13, z - 1, x + 1, y + 13, z + 1, "emerald_block")
GEO.placeCuboid(x - 1, y + 14, z - 1, x + 1, y + 14, z + 1, "emerald_block")
GEO.placeCuboid(x - 1, y + 15, z - 1, x + 1, y + 15, z + 1, "emerald_block")
GEO.placeCuboid(x - 1, y + 16, z - 1, x + 1, y + 16, z + 1, "emerald_block")
GEO.placeCuboid(x - 1, y + 17, z - 1, x + 1, y + 17, z + 1, "emerald_block")
GEO.placeCuboid(x - 1, y + 18, z - 1, x + 1, y + 18, z + 1, "emerald_block")
GEO.placeCuboid(x - 1, y + 19, z - 1, x + 1, y + 19, z + 1, "emerald_block")
GEO.placeCuboid(x - 1, y + 20, z - 1, x + 1, y + 20, z + 1, "emerald_block")
GEO.placeCuboid(x - 1, y + 21, z - 1, x + 1, y + 21, z + 1, "emerald_block")
GEO.placeCuboid(x - 1, y + 22, z - 1, x + 1, y + 22, z + 1, "emerald_block")
GEO.placeCuboid(x - 1, y + 23, z - 1, x + 1, y + 23, z + 1, "emerald_block")
GEO.placeCuboid(x - 1, y + 24, z - 1, x + 1, y + 24, z + 1, "emerald_block")
GEO.placeCuboid(x - 1, y + 25, z - 1, x + 1, y + 25, z + 1, "emerald_block")
GEO.placeCuboid(x - 1, y + 26, z - 1, x + 1, y + 26, z + 1, "emerald_block")
GEO.placeCuboid(x - 1, y + 27, z - 1, x + 1, y + 27, z + 1, "emerald_block")
GEO.placeCuboid(x - 1, y + 28, z - 1, x + 1, y + 28, z + 1, "emerald_block")
GEO.placeCuboid(x - 1, y + 29, z - 1, x + 1, y + 29, z + 1, "emerald_block")
GEO.placeCuboid(x - 1, y + 30, z - 1, x + 1, y + 30, z + 1, "emerald_block")
GEO.placeCuboid(x - 1, y + 31, z - 1, x + 1, y + 31, z + 1, "emerald_block")
GEO.placeCuboid(x - 1, y + 32, z - 1, x + 1, y + 32, z + 1, "emerald_block")
GEO.placeCuboid(x - 1, y + 33, z - 1, x + 1, y + 33, z + 1, "emerald_block")
GEO.placeCuboid(x - 1, y + 34, z - 1, x + 1, y + 34, z + 1, "emerald_block")
GEO.placeCuboid(x - 1, y + 35, z - 1, x + 1, y + 35, z + 1, "emerald_block")
GEO.placeCuboid(x - 1, y + 36, z - 1, x + 1, y + 36, z + 1, "emerald_block")
GEO.placeCuboid(x - 1, y + 37, z - 1, x + 1, y + 37, z + 1, "emerald_block")
GEO.placeCuboid(x - 1, y + 38, z - 1, x + 1, y + 38, z + 1, "emerald_block")
GEO.placeCuboid(x - 1, y + 39, z - 1, x + 1, y + 39, z + 1, "emerald_block")
GEO.placeCuboid(x - 1, y + 40, z - 1, x + 1, y + 40, z + 1, "emerald_block")
GEO.placeCuboid(x - 1, y + 41, z - 1, x + 1, y + 41, z + 1, "emerald_block")
GEO.placeCuboid(x - 1, y + 42, z - 1, x + 1, y + 42, z + 1, "emerald_block")
GEO.placeCuboid(x - 1, y + 43, z - 1, x + 1, y + 43, z + 1, "emerald_block")
GEO.placeCuboid(x - 1, y + 44, z - 1, x + 1, y + 44, z + 1, "emerald_block")
GEO.placeCuboid(x - 1, y + 45, z - 1, x + 1, y + 45, z + 1, "emerald_block")
GEO.placeCuboid(x - 1, y + 46, z - 1, x + 1, y + 46, z + 1, "emerald_block")
GEO.placeCuboid(x - 1, y + 47, z - 1, x + 1, y + 47, z + 1, "emerald_block")
GEO.placeCuboid(x - 1, y + 48, z - 1, x + 1, y + 48, z + 1, "emerald_block")
GEO.placeCuboid(x - 1, y + 49, z - 1, x + 1, y + 49, z + 1, "emerald_block")
GEO.placeCuboid(x - 1, y + 50, z - 1, x + 1, y + 50, z + 1, "emerald_block")
GEO.placeCuboid(x - 1, y + 51, z - 1, x + 1, y + 51, z + 1, "emerald_block")
GEO.placeCuboid(x