-
Notifications
You must be signed in to change notification settings - Fork 194
/
Copy pathtopsoil.py
79 lines (64 loc) · 2.24 KB
/
topsoil.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
from numpy import zeros
import itertools
from pymclevel import alphaMaterials
from pymclevel.level import extractHeights
am = alphaMaterials
#naturally occuring materials
blocks = [
am.Grass,
am.Dirt,
am.Stone,
am.Bedrock,
am.Sand,
am.Gravel,
am.GoldOre,
am.IronOre,
am.CoalOre,
am.LapisLazuliOre,
am.DiamondOre,
am.RedstoneOre,
am.RedstoneOreGlowing,
am.Netherrack,
am.SoulSand,
am.Clay,
am.Glowstone
]
blocktypes = [b.ID for b in blocks]
def naturalBlockmask():
blockmask = zeros((256,), dtype='bool')
blockmask[blocktypes] = True
return blockmask
inputs = (
("Depth", (4, -128, 128)),
("Pick a block:", alphaMaterials.Grass),
)
def perform(level, box, options):
depth = options["Depth"]
blocktype = options["Pick a block:"]
#compute a truth table that we can index to find out whether a block
# is naturally occuring and should be considered in a heightmap
blockmask = naturalBlockmask()
# always consider the chosen blocktype to be "naturally occuring" to stop
# it from adding extra layers
blockmask[blocktype.ID] = True
#iterate through the slices of each chunk in the selection box
for chunk, slices, point in level.getChunkSlices(box):
# slicing the block array is straightforward. blocks will contain only
# the area of interest in this chunk.
blocks = chunk.Blocks[slices]
data = chunk.Data[slices]
# use indexing to look up whether or not each block in blocks is
# naturally-occuring. these blocks will "count" for column height.
maskedBlocks = blockmask[blocks]
heightmap = extractHeights(maskedBlocks)
for x, z in itertools.product(*map(xrange, heightmap.shape)):
h = heightmap[x, z]
if depth > 0:
blocks[x, z, max(0, h - depth):h] = blocktype.ID
data[x, z, max(0, h - depth):h] = blocktype.blockData
else:
#negative depth values mean to put a layer above the surface
blocks[x, z, h:min(blocks.shape[2], h - depth)] = blocktype.ID
data[x, z, h:min(blocks.shape[2], h - depth)] = blocktype.blockData
#remember to do this to make sure the chunk is saved
chunk.chunkChanged()