Permalink
Browse files

Renamed structures to schematics and updated documentation.

Structures started off as simple arbitrary collections of blocks, but
schematics work a whole lot better.

GetRegion.py: renamed structures to schematics
README: renamed structures to schematics
README.schematics: added schematics documentation
newore.py: renamed structures to schematics
newregion.py: renamed structures to schematics
newschematic.py: renamed from newstructure.py
newstructure.py: renamed to newschematic.py
newterrain.py: renamed structures to schematics
newtile.py: renamed structures to schematics
  • Loading branch information...
1 parent 4e49666 commit 9a111e8be343661b4c3264e44525a5f3a939c9f5 @mathuin committed Feb 28, 2012
Showing with 96 additions and 60 deletions.
  1. +2 −2 GetRegion.py
  2. +1 −1 README
  3. +38 −0 README.schematics
  4. BIN School.schematic
  5. +1 −1 newore.py
  6. +3 −3 newregion.py
  7. +20 −22 newstructure.py → newschematic.py
  8. +29 −29 newterrain.py
  9. +2 −2 newtile.py
View
@@ -49,7 +49,7 @@ def main(argv):
parser.add_argument('--elevationIDs', default=default_elevationIDs, type=checkElevationIDs, help='ordered list of product IDs (default %s)' % default_elevationIDs)
parser.add_argument('--landcoverIDs', default=default_landcoverIDs, type=checkLandcoverIDs, help='ordered list of product IDs (default %s)' % default_landcoverIDs)
parser.add_argument('--disable-ore', action='store_false', dest='doOre', default=True, help='disable ore generation')
- parser.add_argument('--enable-structures', action='store_true', dest='doStructures', default=False, help='enable structure usage')
+ parser.add_argument('--enable-schematics', action='store_true', dest='doSchematics', default=False, help='enable schematic usage')
parser.add_argument('--debug', action='store_true', help='enable debug output')
args = parser.parse_args()
@@ -59,7 +59,7 @@ def main(argv):
# create the region
print "Creating new region %s..." % args.name
- myRegion = Region(name=args.name, xmax=args.xmax, xmin=args.xmin, ymax=args.ymax, ymin=args.ymin, scale=args.scale, vscale=args.vscale, trim=args.trim, tilesize=args.tilesize, sealevel=args.sealevel, maxdepth=args.maxdepth, lcIDs=args.landcoverIDs, elIDs=args.elevationIDs, doOre=args.doOre, doStructures=args.doStructures)
+ myRegion = Region(name=args.name, xmax=args.xmax, xmin=args.xmin, ymax=args.ymax, ymin=args.ymin, scale=args.scale, vscale=args.vscale, trim=args.trim, tilesize=args.tilesize, sealevel=args.sealevel, maxdepth=args.maxdepth, lcIDs=args.landcoverIDs, elIDs=args.elevationIDs, doOre=args.doOre, doSchematics=args.doSchematics)
print "Downloading files..."
myRegion.getfiles()
View
2 README
@@ -10,7 +10,7 @@ Major changes:
* GPGPU support has been added. Yes, your video card can help you build Minecraft worlds! This latest feature relies on PyOpenCL, so see http://mathema.tician.de/software/pyopencl for more information.
- * The landcover code has been rewritten to support the usage of MCEdit schematics as templates for certain areas, specifically croplands (farms) and developed areas. MCEdit is not required to use TopoMC, only to modify or replace the example schematics. It can be found at http://davidvierra.com/mcedit/download.html.
+ * The landcover code has been rewritten to support the usage of MCEdit schematics as templates for certain areas, specifically croplands (farms) and developed areas. More information about this feature can be found in README.schematics.
* The test dataset has been removed.
View
@@ -0,0 +1,38 @@
+TopoMC now supports the use of MCEdit schematics in place of randomly
+selected terrain for certain landcover types.
+
+MCEdit is not required to use TopoMC, only to modify or replace the
+example schematics. It can be found at
+http://davidvierra.com/mcedit/download.html.
+
+To use the schematic feature, add "--enable-schematics" to the ./GetRegion.py command.
+
+The following landcover types support schematics, and have example files:
+
+ * 21: developed/open-space "OpenSpace.schematic"
+ * 22: developed/low-intensity "Neighborhood.schematic"
+ * 23: developed/medium-intensity "School.schematic"
+ * 24: developed/high-intensity "Apartments.schematic"
+ * 25: commercial-industrial-transportation "Commercial.schematic"
+ * 82: crops "Farm.schematic"
+
+The example schematics demonstrate some of the capabilities of the
+concept. Some useful tips to keep in mind when designing schematics
+for TopoMC:
+
+ * Make sure sizes are uniform and regular
+ Landcover types can come together like puzzle pieces. Having all
+ of the schematics the same size with regular road and street-light
+ placement helps the maintain the impression of a consistent world.
+ Also, larger schematics repeat less often and look better.
+
+ * Minimize the use of water
+ The elevation under the schematics is not flattened, so water in
+ schematics runs the risk of inundating local terrain.
+
+ * Do not use end stone
+ End stone is used by TopoMC as a placeholder for stone for terrain
+ generation and ore placement. Any end stone found in schematics
+ will be converted into stone or possibly ore by the software.
+
+
View
Binary file not shown.
View
@@ -12,7 +12,7 @@ class Ore:
"""Each type of ore will be an instance of this class."""
# what ID is stone?
- # we use 'end stone' actually since 'stone' might be in a structure
+ # we use 'end stone' actually since 'stone' might be in a schematic
stoneID = materialNamed('End Stone')
def __init__(self, name, depth=None, rounds=None, size=None):
View
@@ -97,7 +97,7 @@ class Region:
compressionTypes = { 'tgz': ['T'],
'zip': ['Z'] }
- def __init__(self, name, xmax, xmin, ymax, ymin, tilesize=None, scale=None, vscale=None, trim=None, sealevel=None, maxdepth=None, lcIDs=None, elIDs=None, debug=False, doOre=True, doStructures=False):
+ def __init__(self, name, xmax, xmin, ymax, ymin, tilesize=None, scale=None, vscale=None, trim=None, sealevel=None, maxdepth=None, lcIDs=None, elIDs=None, debug=False, doOre=True, doSchematics=False):
"""Create a region based on lat-longs and other parameters."""
# NB: smart people check names
self.name = name
@@ -169,9 +169,9 @@ def __init__(self, name, xmax, xmin, ymax, ymin, tilesize=None, scale=None, vsca
if elevationIDs == []:
raise AttributeError, 'invalid elevation ID'
- # enable or disable ore and structures
+ # enable or disable ore and schematics
self.doOre = doOre
- self.doStructures = doStructures
+ self.doSchematics = doSchematics
# crazy directory fun
self.regiondir = os.path.join('Regions', self.name)
@@ -1,24 +1,22 @@
-# structure module
+# schematic module
from newutils import height
import os
import sys
sys.path.append('..')
from pymclevel import mclevel
-class Structure:
- """This class is for maintaining structures.
+class Schematic:
+ """Schematics are associated with landcover types. When the
+ landcover type comes up, the relevant portion of the schematic is
+ placed.
- Structures are MCEdit schematics which are associated with landcover types.
- When the landcover type comes up, the relevant portion of the structure is placed.
-
- Structures should be designed to mesh well together. The sample structures all
+ Schematics should be designed to mesh well together. The sample schematics all
come from a specific pattern so streets and sidewalks go well together, but do
not be limited by this example!"""
-
# dict
# key: landcover value
- # value: structure object
- structs = dict()
+ # value: schematic object
+ schems = dict()
def __init__(self, tag=None, layout=None, offset=1):
# handles:
@@ -32,7 +30,7 @@ def __init__(self, tag=None, layout=None, offset=1):
raise IOError, 'no file found'
else:
schem = mclevel.fromFile(filename)
- self.layout = [[Structure.compressrow([(1, (int(schem.Blocks[elemX, elemZ, elemY]), int(schem.Data[elemX, elemZ, elemY]))) for elemY in xrange(schem.Height)]) for elemZ in xrange(schem.Length)] for elemX in xrange(schem.Width)]
+ self.layout = [[Schematic.compressrow([(1, (int(schem.Blocks[elemX, elemZ, elemY]), int(schem.Data[elemX, elemZ, elemY]))) for elemY in xrange(schem.Height)]) for elemZ in xrange(schem.Length)] for elemX in xrange(schem.Width)]
else:
self.layout = layout
self.offset = offset
@@ -59,32 +57,32 @@ def check(self, verbose=False):
raise AttributeError, "not all cols are the same height"
if verbose:
- print "structure has dimensions %dX x %dY x %dZ" % (self.length, self.height, self.width)
+ print "schematic has dimensions %dX x %dY x %dZ" % (self.length, self.height, self.width)
@staticmethod
def use(key, name, nameoffset, layout, offset):
def decorator(target):
def wrapper(*args, **kwargs):
# major assumption:
- # args are (x, y, z, crustval, bathyval, doStructures)
+ # args are (x, y, z, crustval, bathyval, doSchematics)
x = args[0]
y = args[1]
z = args[2]
crustval = args[3]
bathyval = args[4]
- doStructures = args[5]
+ doSchematics = args[5]
try:
- Structure.structs[key]
+ Schematic.schems[key]
except KeyError:
- if doStructures:
+ if doSchematics:
try:
- newstruct = Structure(tag=name, offset=nameoffset)
+ newschem = Schematic(tag=name, offset=nameoffset)
except IOError:
- newstruct = Structure(layout=layout, offset=offset)
+ newschem = Schematic(layout=layout, offset=offset)
else:
- newstruct = Structure(layout=layout, offset=offset)
- Structure.structs[key] = newstruct
- struct = Structure.structs[key]
- return (y + struct.height - struct.offset, [(crustval, 'Dirt')] + struct.layout[x % struct.length][z % struct.width], None)
+ newschem = Schematic(layout=layout, offset=offset)
+ Schematic.schems[key] = newschem
+ schem = Schematic.schems[key]
+ return (y + schem.height - schem.offset, [(crustval, 'Dirt')] + schem.layout[x % schem.length][z % schem.width], None)
return wrapper
return decorator
View
@@ -1,6 +1,6 @@
from random import random, choice
from newutils import materialNamed, height
-from newstructure import Structure
+from newschematic import Schematic
import yaml
try:
from yaml import CLoader as Loader, CDumper as Dumper
@@ -28,7 +28,7 @@ class Terrain:
treeProb = 0.001
forestProb = 0.03
- # structure defaults
+ # schematic defaults
# 21: 10%, 22: 35%, 23: 65%, 24: 90%, 25: 95%
layout21 = [[[(1, 'Stone' if random() < 0.1 else 'Grass')] for x in xrange(10)] for x in xrange(10)]
layout22 = [[[(1, 'Stone' if random() < 0.35 else 'Grass')] for x in xrange(10)] for x in xrange(10)]
@@ -91,95 +91,95 @@ def placegrass(x, y, z, crustval, tallgrassProb=0.05):
# valid terrain functions
# 0: default
- def zero(x, y, z, crustval, bathyval, doStructures):
+ def zero(x, y, z, crustval, bathyval, doSchematics):
return (y, [(crustval, 'Obsidian')], None)
# 11: water
- def eleven(x, y, z, crustval, bathyval, doStructures):
+ def eleven(x, y, z, crustval, bathyval, doSchematics):
return Terrain.placewater(x, y, z, crustval, bathyval)
# 12: ice
- def twelve(x, y, z, crustval, bathyval, doStructures):
+ def twelve(x, y, z, crustval, bathyval, doSchematics):
return Terrain.placeice(x, y, z, crustval)
# 21: developed/open-space (<20% developed)
- #@Structure.use(21, 'OpenSpace', 2, [[[(1, 'Stone')]]], 0)
- @Structure.use(21, 'OpenSpace', 2, layout21, 0)
- def twentyone(x, y, z, crustval, bathyval, doStructures):
+ #@Schematic.use(21, 'OpenSpace', 2, [[[(1, 'Stone')]]], 0)
+ @Schematic.use(21, 'OpenSpace', 2, layout21, 0)
+ def twentyone(x, y, z, crustval, bathyval, doSchematics):
pass
# 22: developed/low-intensity (20-49% developed)
- @Structure.use(22, 'Neighborhood', 2, layout22, 0)
- def twentytwo(x, y, z, crustval, bathyval, doStructures):
+ @Schematic.use(22, 'Neighborhood', 2, layout22, 0)
+ def twentytwo(x, y, z, crustval, bathyval, doSchematics):
pass
# 23: developed/medium-intensity (50-79% developed)
- @Structure.use(23, 'Apartments', 2, layout23, 0)
- def twentythree(x, y, z, crustval, bathyval, doStructures):
+ @Schematic.use(23, 'Apartments', 2, layout23, 0)
+ def twentythree(x, y, z, crustval, bathyval, doSchematics):
pass
# 24: developed/high-intensity (80-100% developed)
- @Structure.use(24, 'Apartments', 2, layout24, 0)
- def twentyfour(x, y, z, crustval, bathyval, doStructures):
+ @Schematic.use(24, 'Apartments', 2, layout24, 0)
+ def twentyfour(x, y, z, crustval, bathyval, doSchematics):
pass
# 25: commercial-industrial-transportation
- @Structure.use(25, 'Commercial', 2, layout25, 0)
- def twentyfive(x, y, z, crustval, bathyval, doStructures):
+ @Schematic.use(25, 'Commercial', 2, layout25, 0)
+ def twentyfive(x, y, z, crustval, bathyval, doSchematics):
pass
# 31: barren land (rock/sand/clay)
- def thirtyone(x, y, z, crustval, bathyval, doStructures):
+ def thirtyone(x, y, z, crustval, bathyval, doSchematics):
return Terrain.placedesert(x, y, z, crustval, stoneProb=0.50)
# 32: transitional
- def thirtytwo(x, y, z, crustval, bathyval, doStructures):
+ def thirtytwo(x, y, z, crustval, bathyval, doSchematics):
return Terrain.placedesert(x, y, z, crustval)
# 41: deciduous forest
- def fortyone(x, y, z, crustval, bathyval, doStructures):
+ def fortyone(x, y, z, crustval, bathyval, doSchematics):
return Terrain.placeforest(x, y, z, crustval, 'Redwood')
# 42: evergreen forest
- def fortytwo(x, y, z, crustval, bathyval, doStructures):
+ def fortytwo(x, y, z, crustval, bathyval, doSchematics):
return Terrain.placeforest(x, y, z, crustval, 'Birch')
# 43: mixed forest
- def fortythree(x, y, z, crustval, bathyval, doStructures):
+ def fortythree(x, y, z, crustval, bathyval, doSchematics):
return Terrain.placeforest(x, y, z, crustval, ['Redwood', 'Birch'])
# 51: shrubland
- def fiftyone(x, y, z, crustval, bathyval, doStructures):
+ def fiftyone(x, y, z, crustval, bathyval, doSchematics):
return Terrain.placeshrubland(x, y, z, crustval, stoneProb=0.25)
# 71: grassland
- def seventyone(x, y, z, crustval, bathyval, doStructures):
+ def seventyone(x, y, z, crustval, bathyval, doSchematics):
return Terrain.placegrass(x, y, z, crustval, tallgrassProb=0.75)
# 81: pasture/hay
- def eightyone(x, y, z, crustval, bathyval, doStructures):
+ def eightyone(x, y, z, crustval, bathyval, doSchematics):
return Terrain.placegrass(x, y, z, crustval, tallgrassProb=0.50)
# 82: crops
- @Structure.use(82, 'Farm', 2, [[[(1, ('Farmland', 7)), (1, ('Crops', 7))]]], 1)
- def eightytwo(x, y, z, crustval, bathyval, doStructures):
+ @Schematic.use(82, 'Farm', 2, [[[(1, ('Farmland', 7)), (1, ('Crops', 7))]]], 1)
+ def eightytwo(x, y, z, crustval, bathyval, doSchematics):
pass
# 91: wetlands
- def ninetyone(x, y, z, crustval, bathyval, doStructures):
+ def ninetyone(x, y, z, crustval, bathyval, doSchematics):
return Terrain.placegrass(x, y, z, crustval)
# dictionary used by place
terdict = { 0: zero, 11: eleven, 12: twelve, 21: twentyone, 22: twentytwo, 23: twentythree, 24: twentyfour, 25: twentyfive, 31: thirtyone, 32: thirtytwo, 41: fortyone, 42: fortytwo, 43: fortythree, 51: fiftyone, 71: seventyone, 81: eightyone, 82: eightytwo, 91: ninetyone }
# method that actually places terrain
@staticmethod
- def place(x, y, z, lcval, crustval, bathyval, doStructures):
+ def place(x, y, z, lcval, crustval, bathyval, doSchematics):
try:
Terrain.terdict[lcval]
except KeyError:
print "lcval value %s not found!" % lcval
- (y, column, tree) = Terrain.terdict.get(lcval, Terrain.terdict[0])(x, y, z, crustval, bathyval, doStructures)
+ (y, column, tree) = Terrain.terdict.get(lcval, Terrain.terdict[0])(x, y, z, crustval, bathyval, doSchematics)
merged = [ (depth, (block, 0)) if type(block) is not tuple else (depth, block) for (depth, block) in column ]
blocks = []
datas = []
View
@@ -42,7 +42,7 @@ def __init__(self, region, tilex, tiley):
self.tiley = int(tiley)
self.tiles = region.tiles
self.doOre = region.doOre
- self.doStructures = region.doStructures
+ self.doSchematics = region.doSchematics
if (self.tilex < self.tiles['xmin']) or (self.tilex >= self.tiles['xmax']):
raise AttributeError, "tilex (%d) must be between %d and %d" % (self.tilex, self.tiles['xmin'], self.tiles['xmax'])
@@ -92,7 +92,7 @@ def build(self):
crustval = int(crustarray[myz, myx])
if mcy > self.peak[1]:
self.peak = [mcx, mcy, mcz]
- (blocks, datas, tree) = Terrain.place(mcx, mcy, mcz, lcval, crustval, bathyval, self.doStructures)
+ (blocks, datas, tree) = Terrain.place(mcx, mcy, mcz, lcval, crustval, bathyval, self.doSchematics)
[ self.world.setBlockAt(mcx, y, mcz, block) for (y, block) in blocks if block != 0 ]
[ self.world.setBlockDataAt(mcx, y, mcz, data) for (y, data) in datas if data != 0 ]
# if trees are placed, elevation cannot be changed

0 comments on commit 9a111e8

Please sign in to comment.