forked from mathuin/TopoMC
-
Notifications
You must be signed in to change notification settings - Fork 0
/
buildregion.py
executable file
·121 lines (103 loc) · 4.18 KB
/
buildregion.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
#!/usr/bin/env python
import logging
logging.basicConfig(level=logging.WARNING)
from tile import Tile
from utils import setspawnandsave
import argparse
import os
import yaml
from multiprocessing import Pool
from itertools import product
from tree import Tree, treeObjs
from ore import Ore, oreObjs
from pymclevel import mclevel
def buildtile(args):
"""Given a region name and coordinates, build the corresponding tile."""
# this should work for single and multi threaded cases
(name, tilex, tiley) = args
yamlfile = file(os.path.join('regions', name, 'Region.yaml'))
myRegion = yaml.load(yamlfile)
yamlfile.close()
myTile = Tile(myRegion, tilex, tiley)
myTile()
def main():
"""Builds a region."""
# example:
# ./BuildRegion.py --name BlockIsland
# parse options and get results
parser = argparse.ArgumentParser(description='Builds Minecraft worlds from regions.')
parser.add_argument('--name', required=True, type=str, help='name of the region to be built')
parser.add_argument('--debug', action='store_true', help='enable debug output')
parser.add_argument('--single', action='store_true', help='enable single-threaded mode for debugging or profiling')
args = parser.parse_args()
# enable debug
if (args.debug):
print "Do something!"
# build the region
print "Building region %s..." % args.name
yamlfile = file(os.path.join('regions', args.name, 'Region.yaml'))
myRegion = yaml.load(yamlfile)
yamlfile.close()
# exit if map does not exist
if not os.path.exists(myRegion.mapfile):
raise IOError('no map file exists')
# tree and ore variables
treeobjs = dict([(tree.name, tree) for tree in treeObjs])
trees = dict([(name, list()) for name in treeobjs])
oreobjs = dict([(ore.name, ore) for ore in oreObjs])
ores = dict([(name, list()) for name in oreobjs])
# generate overall world
worlddir = os.path.join('worlds', args.name)
world = mclevel.MCInfdevOldLevel(worlddir, create=True)
peak = [0, 0, 0]
# generate individual tiles
tilexrange = xrange(myRegion.tiles['xmin'], myRegion.tiles['xmax'])
tileyrange = xrange(myRegion.tiles['ymin'], myRegion.tiles['ymax'])
name = myRegion.name
tiles = [(name, x, y) for x, y in product(tilexrange, tileyrange)]
if args.single:
# single process version - works
for tile in tiles:
buildtile(tile)
else:
# multi-process ... let's see...
pool = Pool()
pool.map(buildtile, tiles)
pool.close()
pool.join()
# merge individual worlds into it
print "Merging %d tiles into one world..." % len(tiles)
for tile in tiles:
(name, x, y) = tile
tiledir = os.path.join('regions', name, 'Tiles', '%dx%d' % (x, y))
tilefile = file(os.path.join(tiledir, 'Tile.yaml'))
newtile = yaml.load(tilefile)
tilefile.close()
if (newtile.peak[1] > peak[1]):
peak = newtile.peak
for treetype in newtile.trees:
trees.setdefault(treetype, []).extend(newtile.trees[treetype])
if myRegion.doOre:
for oretype in newtile.ores:
ores.setdefault(oretype, []).extend(newtile.ores[oretype])
tileworld = mclevel.MCInfdevOldLevel(tiledir, create=False)
world.copyBlocksFrom(tileworld, tileworld.bounds, tileworld.bounds.origin)
tileworld = False
# plant trees in our world
print "Planting %d trees at the region level..." % sum([len(trees[treetype]) for treetype in trees])
Tree.placetreesinregion(trees, treeobjs, world)
# deposit ores in our world
if myRegion.doOre:
print "Depositing %d ores at the region level..." % sum([len(ores[oretype]) for oretype in ores])
Ore.placeoreinregion(ores, oreobjs, world)
# replace all 'end stone' with stone
print "Replacing all 'end stone' with stone..."
EndStoneID = world.materials["End Stone"].ID
StoneID = world.materials["Stone"].ID
for xpos, zpos in world.allChunks:
chunk = world.getChunk(xpos, zpos)
chunk.Blocks[chunk.Blocks == EndStoneID] = StoneID
# tie up loose ends
setspawnandsave(world, peak)
if __name__ == '__main__':
main()