0

Merge branch 'master' into my_genpoi

This just updates the code to the current master, so it can be merged
easily.

Conflicts:
	overviewer_core/aux_files/genPOI.py
This commit is contained in:
MasterofJOKers
2014-10-28 22:15:58 +01:00
10 changed files with 288 additions and 70 deletions

View File

@@ -4,7 +4,7 @@ python:
- "2.7"
# - "3.2"
env:
- MC_VERSION=1.7.4
- MC_VERSION=1.8
before_install:
- wget http://hg.effbot.org/pil-117/raw/f356a1f64271/libImaging/Imaging.h
- wget http://hg.effbot.org/pil-117/raw/f356a1f64271/libImaging/ImPlatform.h

View File

@@ -34,7 +34,7 @@ def main():
metavar = '<output>', type = str, dest = 'output', default = "output.png")
(options, args) = parser.parse_args()
tileset = args[0]
# arg is overviewer tile set folder
if len(args) > 1:
@@ -42,6 +42,7 @@ def main():
if not args:
parser.error("Error! Need an overviewer tile set folder. Use --help for a complete list of options.")
tileset = args[0] #set the tileset dir after ensuring it's been provided, not before.
if not options.zoom_level:
parser.error("Error! The option zoom-level is mandatory.")
@@ -126,7 +127,7 @@ def main():
print "The image size will be {0}x{1}".format(final_cropped_img_size[0],final_cropped_img_size[1])
print "A total of {0} MB of memory will be used.".format(mem/1024**2)
if mem/1024.**2. > options.memory_limit:
print "Warning! The expected RAM usage exceeds the spicifyed limit. Exiting."
print "Warning! The expected RAM usage exceeds the specified limit. Exiting."
sys.exit(1)
# Create a new huge image

View File

@@ -625,7 +625,7 @@ Rendering
'crop': (-500, -500, 500, 500),
}
Example that renders two 500 by 500 squares of land:
Example that renders two 500 by 500 squares of land::
renders['myrender'] = {
'world': 'myworld',

View File

@@ -261,13 +261,13 @@ If you want or need to provide your own textures, you have several options:
::
VERSION=1.7.2
VERSION=1.8
wget https://s3.amazonaws.com/Minecraft.Download/versions/${VERSION}/${VERSION}.jar -P ~/.minecraft/versions/${VERSION}/
If that's too confusing for you, then just take this single line and paste it into
a terminal to get 1.7.2 textures::
a terminal to get 1.8 textures::
wget https://s3.amazonaws.com/Minecraft.Download/versions/1.7.2/1.7.2.jar -P ~/.minecraft/versions/1.7.2/
wget https://s3.amazonaws.com/Minecraft.Download/versions/1.8/1.8.jar -P ~/.minecraft/versions/1.8/
* You can also just run the launcher to install the client.

View File

@@ -15,6 +15,7 @@ markers.js holds a list of which markerSets are attached to each tileSet
'''
import os
import time
import logging
import json
import sys
@@ -22,6 +23,7 @@ import re
import urllib2
import multiprocessing
import itertools
import gzip
from collections import defaultdict
from multiprocessing import Pool
@@ -134,6 +136,26 @@ def handleEntities(rset, config, filters, markers):
class PlayerDict(dict):
use_uuid = False
_name = ''
uuid_cache = None # A cache for the UUID->profile lookups
@classmethod
def load_cache(cls, outputdir):
cache_file = os.path.join(outputdir, "uuidcache.dat")
if os.path.exists(cache_file):
gz = gzip.GzipFile(cache_file)
cls.uuid_cache = json.load(gz)
logging.info("Loaded UUID cache from %r with %d entries", cache_file, len(cls.uuid_cache.keys()))
else:
cls.uuid_cache = {}
logging.info("Initialized an empty UUID cache")
@classmethod
def save_cache(cls, outputdir):
cache_file = os.path.join(outputdir, "uuidcache.dat")
gz = gzip.GzipFile(cache_file, "wb")
json.dump(cls.uuid_cache, gz)
logging.info("Wrote UUID cache with %d entries", len(cls.uuid_cache.keys()))
def __getitem__(self, item):
if item == "EntityId":
if not super(PlayerDict, self).has_key("EntityId"):
@@ -145,9 +167,17 @@ class PlayerDict(dict):
return super(PlayerDict, self).__getitem__(item)
def get_name_from_uuid(self):
sname = self._name.replace('-','')
try:
profile = json.loads(urllib2.urlopen(UUID_LOOKUP_URL + self._name.replace('-','')).read())
profile = PlayerDict.uuid_cache[sname]
return profile['name']
except (KeyError,):
pass
try:
profile = json.loads(urllib2.urlopen(UUID_LOOKUP_URL + sname).read())
if 'name' in profile:
PlayerDict.uuid_cache[sname] = profile
return profile['name']
except (ValueError, urllib2.URLError):
logging.warning("Unable to get player name for UUID %s", self._name)
@@ -196,9 +226,12 @@ def handlePlayers(worldpath, filters, markers):
data['x'] = int(data['Pos'][0])
data['y'] = int(data['Pos'][1])
data['z'] = int(data['Pos'][2])
# Time at last logout, calculated from last time the player's file was modified
data['time'] = time.localtime(os.path.getmtime(os.path.join(playerdir, playerfile)))
# Spawn position (bed or main spawn)
if "SpawnX" in data:
# Spawn position (bed or main spawn)
spawn = PlayerDict()
spawn._name = playername
spawn["id"] = "PlayerSpawn"
@@ -395,6 +428,7 @@ def main():
# apply filters to players
if not options.skipplayers:
PlayerDict.load_cache(destdir)
# group filters by worldpath, so we only search for players once per
# world
keyfunc = lambda x: x[4]
@@ -414,6 +448,8 @@ def main():
logging.info("Done handling POIs")
logging.info("Writing out javascript files")
PlayerDict.save_cache(destdir)
with open(os.path.join(destdir, "markersDB.js"), "w") as output:
output.write("var markersDB=")
json.dump(markers, output, indent=2)

View File

@@ -92,17 +92,50 @@ class LoggingObserver(Observer):
#this is an easy way to make the first update() call print a line
self.last_update = -101
# a fake ProgressBar, for the sake of ETA
class FakePBar(object):
def __init__(self):
self.maxval = None
self.currval = 0
self.finished = False
self.start_time = None
self.seconds_elapsed = 0
def finish(self):
self.update(self.maxval)
def update(self, value):
assert 0 <= value <= self.maxval
self.currval = value
if self.finished:
return False
if not self.start_time:
self.start_time = time.time()
self.seconds_elapsed = time.time() - self.start_time
if value == self.maxval:
self.finished = True
self.fake = FakePBar();
self.eta = progressbar.ETA()
def start(self, max_value):
self.fake.maxval = max_value
super(LoggingObserver, self).start(max_value)
def finish(self):
logging.info("Rendered %d of %d. %d%% complete", self.get_max_value(),
self.get_max_value(), 100.0)
self.fake.finish()
logging.info("Rendered %d of %d. %d%% complete. %s", self.get_max_value(),
self.get_max_value(), 100.0, self.eta.update(self.fake))
super(LoggingObserver, self).finish()
def update(self, current_value):
super(LoggingObserver, self).update(current_value)
self.fake.update(current_value)
if self._need_update():
logging.info("Rendered %d of %d. %d%% complete",
logging.info("Rendered %d of %d. %d%% complete. %s",
self.get_current_value(), self.get_max_value(),
self.get_percentage())
self.get_percentage(), self.eta.update(self.fake))
self.last_update = current_value
return True
return False

View File

@@ -262,6 +262,7 @@ is_stairs(int block) {
case 156: /* quartz stairs */
case 163: /* acacia wood stairs */
case 164: /* dark wood stairs */
case 180: /* red sandstone stairs */
return 1;
}
return 0;
@@ -309,9 +310,12 @@ generate_pseudo_data(RenderState *state, unsigned short ancilData) {
}
data = (check_adjacent_blocks(state, x, y, z, state->block) ^ 0x0f) | data;
return (data << 4) | (ancilData & 0x0f);
} else if (state->block == 85) { /* fences */
} else if ((state->block == 85) || (state->block == 188) || (state->block == 189) ||
(state->block == 190) || (state->block == 191) || (state->block == 192)) { /* fences */
/* check for fences AND fence gates */
return check_adjacent_blocks(state, x, y, z, state->block) | check_adjacent_blocks(state, x, y, z, 107);
return check_adjacent_blocks(state, x, y, z, state->block) | check_adjacent_blocks(state, x, y, z, 107) |
check_adjacent_blocks(state, x, y, z, 183) | check_adjacent_blocks(state, x, y, z, 184) | check_adjacent_blocks(state, x, y, z, 185) |
check_adjacent_blocks(state, x, y, z, 186) | check_adjacent_blocks(state, x, y, z, 187);
} else if (state->block == 55) { /* redstone */
/* three addiotional bit are added, one for on/off state, and
@@ -397,7 +401,9 @@ generate_pseudo_data(RenderState *state, unsigned short ancilData) {
/* portal and nether brick fences */
return check_adjacent_blocks(state, x, y, z, state->block);
} else if ((state->block == 64) || (state->block == 71)) {
} else if ((state->block == 64) || (state->block == 71) || (state->block == 193) ||
(state->block == 194) || (state->block == 195) || (state->block == 196) ||
(state->block ==197)) {
/* use bottom block data format plus one bit for top/down
* block (0x8) and one bit for hinge position (0x10)
*/
@@ -703,14 +709,21 @@ chunk_render(PyObject *self, PyObject *args) {
* trapped chests, stairs */
if ((state.block == 2) || (state.block == 9) ||
(state.block == 20) || (state.block == 54) ||
(state.block == 55) || (state.block == 64) ||
(state.block == 71) || (state.block == 79) ||
(state.block == 55) ||
/* doors */
(state.block == 64) || (state.block == 193) ||
(state.block == 194) || (state.block == 195) ||
(state.block == 196) || (state.block == 197) ||
(state.block == 71) || /* end doors */
(state.block == 79) ||
(state.block == 85) || (state.block == 90) ||
(state.block == 101) || (state.block == 102) ||
(state.block == 111) || (state.block == 113) ||
(state.block == 139) || (state.block == 175) ||
(state.block == 160) || (state.block == 95) ||
(state.block == 146) ||
(state.block == 146) || (state.block == 188) ||
(state.block == 189) || (state.block == 190) ||
(state.block == 191) || (state.block == 192) ||
is_stairs(state.block)) {
ancilData = generate_pseudo_data(&state, ancilData);
state.block_pdata = ancilData;

View File

@@ -26,7 +26,7 @@
// increment this value if you've made a change to the c extesion
// and want to force users to rebuild
#define OVERVIEWER_EXTENSION_VERSION 46
#define OVERVIEWER_EXTENSION_VERSION 49
/* Python PIL, and numpy headers */
#include <Python.h>

View File

@@ -138,7 +138,7 @@ estimate_blocklevel(RenderPrimitiveLighting *self, RenderState *state,
blocklevel = get_data(state, BLOCKLIGHT, x, y, z);
/* no longer a guess */
if (!(block == 44 || block == 53 || block == 67 || block == 108 || block == 109) && authoratative) {
if (!(block == 44 || block == 53 || block == 67 || block == 108 || block == 109 || block == 180 || block == 182) && authoratative) {
*authoratative = 1;
}
@@ -160,7 +160,7 @@ get_lighting_color(RenderPrimitiveLighting *self, RenderState *state,
/* special half-step handling, stairs handling */
/* Anvil also needs to be here, blockid 145 */
if (block == 44 || block == 53 || block == 67 || block == 108 || block == 109 || block == 114 ||
block == 128 || block == 134 || block == 135 || block == 136 || block == 145 || block == 156 || block == 163 || block == 164) {
block == 128 || block == 134 || block == 135 || block == 136 || block == 145 || block == 156 || block == 163 || block == 164 || block == 180 || block == 182) {
unsigned int upper_block;
/* stairs and half-blocks take the skylevel from the upper block if it's transparent */
@@ -171,7 +171,7 @@ get_lighting_color(RenderPrimitiveLighting *self, RenderState *state,
upper_block = get_data(state, BLOCKS, x, y + upper_counter, z);
} while (upper_block == 44 || upper_block == 53 || upper_block == 67 || upper_block == 108 ||
upper_block == 109 || upper_block == 114 || upper_block == 128 || upper_block == 134 ||
upper_block == 135 || upper_block == 136 || upper_block == 156 || upper_block == 163 || upper_block == 164);
upper_block == 135 || upper_block == 136 || upper_block == 156 || upper_block == 163 || upper_block == 164 || upper_block == 180 || upper_block == 182);
if (is_transparent(upper_block)) {
skylevel = get_data(state, SKYLIGHT, x, y + upper_counter, z);
} else {

View File

@@ -252,12 +252,12 @@ class Textures(object):
most_recent_version = [0,0,0]
for version in versions:
# Look for the latest non-snapshot that is at least 1.6. This
# version is only compatible with >=1.6, and we cannot in general
# Look for the latest non-snapshot that is at least 1.8. This
# version is only compatible with >=1.8, and we cannot in general
# tell if a snapshot is more or less recent than a release.
# Allow two component names such as "1.6" and three component names
# such as "1.6.1"
# Allow two component names such as "1.8" and three component names
# such as "1.8.1"
if version.count(".") not in (1,2):
continue
try:
@@ -265,14 +265,14 @@ class Textures(object):
except ValueError:
continue
if versionparts < [1,7]:
if versionparts < [1,8]:
continue
if versionparts > most_recent_version:
most_recent_version = versionparts
if most_recent_version != [0,0,0]:
if verbose: logging.info("Most recent version >=1.7.0: {0}. Searching it for the file...".format(most_recent_version))
if verbose: logging.info("Most recent version >=1.8.0: {0}. Searching it for the file...".format(most_recent_version))
jarname = ".".join(str(x) for x in most_recent_version)
jarpath = os.path.join(versiondir, jarname, jarname + ".jar")
@@ -290,7 +290,7 @@ class Textures(object):
if verbose: logging.info("Did not find file {0} in jar {1}".format(filename, jarpath))
else:
if verbose: logging.info("Did not find any non-snapshot minecraft jars >=1.7.0")
if verbose: logging.info("Did not find any non-snapshot minecraft jars >=1.8.0")
# Last ditch effort: look for the file is stored in with the overviewer
# installation. We include a few files that aren't included with Minecraft
@@ -310,7 +310,7 @@ class Textures(object):
if verbose: logging.info("Found %s in '%s'", filename, path)
return open(path, mode)
raise TextureException("Could not find the textures while searching for '{0}'. Try specifying the 'texturepath' option in your config file.\nSet it to the path to a Minecraft Resource pack.\nAlternately, install the Minecraft client (which includes textures)\nAlso see <http://docs.overviewer.org/en/latest/running/#installing-the-textures>\n(Remember, this version of Overviewer requires a 1.7-compatible resource pack)\n(Also note that I won't automatically use snapshots; you'll have to use the texturepath option to use a snapshot jar)".format(filename))
raise TextureException("Could not find the textures while searching for '{0}'. Try specifying the 'texturepath' option in your config file.\nSet it to the path to a Minecraft Resource pack.\nAlternately, install the Minecraft client (which includes textures)\nAlso see <http://docs.overviewer.org/en/latest/running/#installing-the-textures>\n(Remember, this version of Overviewer requires a 1.8-compatible resource pack)\n(Also note that I won't automatically use snapshots; you'll have to use the texturepath option to use a snapshot jar)".format(filename))
def load_image_texture(self, filename):
# Textures may be animated or in a different resolution than 16x16.
@@ -430,7 +430,7 @@ class Textures(object):
self.foliagecolor = list(self.load_image("foliage.png").getdata())
return self.foliagecolor
#I guess "watercolor" is wrong. But I can't correct as my texture pack don't define water color.
#I guess "watercolor" is wrong. But I can't correct as my texture pack don't define water color.
def load_water_color(self):
"""Helper function to load the water color texture."""
if not hasattr(self, "watercolor"):
@@ -864,7 +864,23 @@ def billboard(blockid=[], imagename=None, **kwargs):
##
# stone
block(blockid=1, top_image="assets/minecraft/textures/blocks/stone.png")
@material(blockid=1, data=range(7), solid=True)
def stone(self, blockid, data):
if data == 0: # regular old-school stone
img = self.load_image_texture("assets/minecraft/textures/blocks/stone.png")
elif data == 1: # granite
img = self.load_image_texture("assets/minecraft/textures/blocks/stone_granite.png")
elif data == 2: # polished granite
img = self.load_image_texture("assets/minecraft/textures/blocks/stone_granite_smooth.png")
elif data == 3: # diorite
img = self.load_image_texture("assets/minecraft/textures/blocks/stone_diorite.png")
elif data == 4: # polished diorite
img = self.load_image_texture("assets/minecraft/textures/blocks/stone_diorite_smooth.png")
elif data == 5: # andesite
img = self.load_image_texture("assets/minecraft/textures/blocks/stone_andesite.png")
elif data == 6: # polished andesite
img = self.load_image_texture("assets/minecraft/textures/blocks/stone_andesite_smooth.png")
return self.build_block(img, img)
@material(blockid=2, data=range(11)+[0x10,], solid=True)
def grass(self, blockid, data):
@@ -1135,6 +1151,18 @@ def sandstone(self, blockid, data):
return self.build_block(top, self.load_image_texture("assets/minecraft/textures/blocks/sandstone_carved.png"))
if data == 2: # soft
return self.build_block(top, self.load_image_texture("assets/minecraft/textures/blocks/sandstone_smooth.png"))
# red sandstone
@material(blockid=179, data=range(3), solid=True)
def sandstone(self, blockid, data):
top = self.load_image_texture("assets/minecraft/textures/blocks/red_sandstone_top.png")
if data == 0: # normal
side = self.load_image_texture("assets/minecraft/textures/blocks/red_sandstone_normal.png")
return self.build_full_block(top, None, None, side, side, self.load_image_texture("assets/minecraft/textures/blocks/red_sandstone_bottom.png") )
if data == 1: # hieroglyphic
return self.build_block(top, self.load_image_texture("assets/minecraft/textures/blocks/red_sandstone_carved.png"))
if data == 2: # soft
return self.build_block(top, self.load_image_texture("assets/minecraft/textures/blocks/red_sandstone_smooth.png"))
# note block
block(blockid=25, top_image="assets/minecraft/textures/blocks/noteblock.png")
@@ -1529,38 +1557,56 @@ block(blockid=42, top_image="assets/minecraft/textures/blocks/iron_block.png")
# double slabs and slabs
# these wooden slabs are unobtainable without cheating, they are still
# here because lots of pre-1.3 worlds use this blocks
@material(blockid=[43, 44], data=range(16), transparent=(44,), solid=True)
@material(blockid=[43, 44, 181, 182], data=range(16), transparent=(44,182,), solid=True)
def slabs(self, blockid, data):
if blockid == 44:
if blockid == 44 or blockid == 182:
texture = data & 7
else: # data > 8 are special double slabs
texture = data
if texture== 0: # stone slab
top = self.load_image_texture("assets/minecraft/textures/blocks/stone_slab_top.png")
side = self.load_image_texture("assets/minecraft/textures/blocks/stone_slab_side.png")
elif texture== 1: # smooth stone
top = self.load_image_texture("assets/minecraft/textures/blocks/sandstone_top.png")
side = self.load_image_texture("assets/minecraft/textures/blocks/sandstone_normal.png")
elif texture== 2: # wooden slab
top = side = self.load_image_texture("assets/minecraft/textures/blocks/planks_oak.png")
elif texture== 3: # cobblestone slab
top = side = self.load_image_texture("assets/minecraft/textures/blocks/cobblestone.png")
elif texture== 4: # brick
top = side = self.load_image_texture("assets/minecraft/textures/blocks/brick.png")
elif texture== 5: # stone brick
top = side = self.load_image_texture("assets/minecraft/textures/blocks/stonebrick.png")
elif texture== 6: # nether brick slab
top = side = self.load_image_texture("assets/minecraft/textures/blocks/nether_brick.png")
elif texture== 7: #quartz
top = side = self.load_image_texture("assets/minecraft/textures/blocks/quartz_block_side.png")
elif texture== 8: # special stone double slab with top texture only
top = side = self.load_image_texture("assets/minecraft/textures/blocks/stone_slab_top.png")
elif texture== 9: # special sandstone double slab with top texture only
top = side = self.load_image_texture("assets/minecraft/textures/blocks/sandstone_top.png")
else:
return None
if blockid == 44 or blockid == 43:
if texture== 0: # stone slab
top = self.load_image_texture("assets/minecraft/textures/blocks/stone_slab_top.png")
side = self.load_image_texture("assets/minecraft/textures/blocks/stone_slab_side.png")
elif texture== 1: # sandstone slab
top = self.load_image_texture("assets/minecraft/textures/blocks/sandstone_top.png")
side = self.load_image_texture("assets/minecraft/textures/blocks/sandstone_normal.png")
elif texture== 2: # wooden slab
top = side = self.load_image_texture("assets/minecraft/textures/blocks/planks_oak.png")
elif texture== 3: # cobblestone slab
top = side = self.load_image_texture("assets/minecraft/textures/blocks/cobblestone.png")
elif texture== 4: # brick
top = side = self.load_image_texture("assets/minecraft/textures/blocks/brick.png")
elif texture== 5: # stone brick
top = side = self.load_image_texture("assets/minecraft/textures/blocks/stonebrick.png")
elif texture== 6: # nether brick slab
top = side = self.load_image_texture("assets/minecraft/textures/blocks/nether_brick.png")
elif texture== 7: #quartz
top = side = self.load_image_texture("assets/minecraft/textures/blocks/quartz_block_side.png")
elif texture== 8: # special stone double slab with top texture only
top = side = self.load_image_texture("assets/minecraft/textures/blocks/stone_slab_top.png")
elif texture== 9: # special sandstone double slab with top texture only
top = side = self.load_image_texture("assets/minecraft/textures/blocks/sandstone_top.png")
else:
return None
elif blockid == 182: # single red sandstone slab
if texture == 0:
top = self.load_image_texture("assets/minecraft/textures/blocks/red_sandstone_top.png")
side = self.load_image_texture("assets/minecraft/textures/blocks/red_sandstone_normal.png")
else:
return None
elif blockid == 181: # double red sandstone slab
if texture == 0: # red sandstone
top = self.load_image_texture("assets/minecraft/textures/blocks/red_sandstone_top.png")
side = self.load_image_texture("assets/minecraft/textures/blocks/red_sandstone_normal.png")
elif texture == 8: # 'full' red sandstone (smooth)
top = side = self.load_image_texture("assets/minecraft/textures/blocks/red_sandstone_top.png");
else:
return None
if blockid == 43: # double slab
if blockid == 43 or blockid == 181: # double slab
return self.build_block(top, side)
# cut the side texture in half
@@ -1693,8 +1739,8 @@ def fire(self, blockid, data):
# monster spawner
block(blockid=52, top_image="assets/minecraft/textures/blocks/mob_spawner.png", transparent=True)
# wooden, cobblestone, red brick, stone brick, netherbrick, sandstone, spruce, birch, jungle and quartz stairs.
@material(blockid=[53,67,108,109,114,128,134,135,136,156,163,164], data=range(128), transparent=True, solid=True, nospawn=True)
# wooden, cobblestone, red brick, stone brick, netherbrick, sandstone, spruce, birch, jungle, quartz, and red sandstone stairs.
@material(blockid=[53,67,108,109,114,128,134,135,136,156,163,164,180], data=range(128), transparent=True, solid=True, nospawn=True)
def stairs(self, blockid, data):
# preserve the upside-down bit
upside_down = data & 0x4
@@ -1731,17 +1777,22 @@ def stairs(self, blockid, data):
texture = self.load_image_texture("assets/minecraft/textures/blocks/planks_acacia.png").copy()
elif blockid == 164: # dark oak stairs
texture = self.load_image_texture("assets/minecraft/textures/blocks/planks_big_oak.png").copy()
elif blockid == 180: # red sandstone stairs
texture = self.load_image_texture("assets/minecraft/textures/blocks/red_sandstone_normal.png").copy()
outside_l = texture.copy()
outside_r = texture.copy()
inside_l = texture.copy()
inside_r = texture.copy()
# sandstone & quartz stairs have special top texture
# sandstone, red sandstone, and quartz stairs have special top texture
if blockid == 128:
texture = self.load_image_texture("assets/minecraft/textures/blocks/sandstone_top.png").copy()
elif blockid == 156:
texture = self.load_image_texture("assets/minecraft/textures/blocks/quartz_block_top.png").copy()
elif blockid == 180:
texture = self.load_image_texture("assets/minecraft/textures/blocks/red_sandstone_top.png").copy()
slab_top = texture.copy()
@@ -2179,7 +2230,7 @@ def signpost(self, blockid, data):
# wooden and iron door
# uses pseudo-ancildata found in iterate.c
@material(blockid=[64,71], data=range(32), transparent=True)
@material(blockid=[64,71,193,194,195,196,197], data=range(32), transparent=True)
def door(self, blockid, data):
#Masked to not clobber block top/bottom & swung info
if self.rotation == 1:
@@ -2199,9 +2250,35 @@ def door(self, blockid, data):
elif (data & 0b00011) == 3: data = data & 0b11100 | 2
if data & 0x8 == 0x8: # top of the door
raw_door = self.load_image_texture("assets/minecraft/textures/blocks/%s.png" % ("door_wood_upper" if blockid == 64 else "door_iron_upper"))
if blockid == 64: # classic wood door
raw_door = self.load_image_texture("assets/minecraft/textures/blocks/door_wood_upper.png")
elif blockid == 71: # iron door
raw_door = self.load_image_texture("assets/minecraft/textures/blocks/door_iron_upper.png")
elif blockid == 193: # spruce door
raw_door = self.load_image_texture("assets/minecraft/textures/blocks/door_spruce_upper.png")
elif blockid == 194: # birch door
raw_door = self.load_image_texture("assets/minecraft/textures/blocks/door_birch_upper.png")
elif blockid == 195: # jungle door
raw_door = self.load_image_texture("assets/minecraft/textures/blocks/door_jungle_upper.png")
elif blockid == 196: # acacia door
raw_door = self.load_image_texture("assets/minecraft/textures/blocks/door_acacia_upper.png")
elif blockid == 197: # dark_oak door
raw_door = self.load_image_texture("assets/minecraft/textures/blocks/door_dark_oak_upper.png")
else: # bottom of the door
raw_door = self.load_image_texture("assets/minecraft/textures/blocks/%s.png" % ("door_wood_lower" if blockid == 64 else "door_iron_lower"))
if blockid == 64:
raw_door = self.load_image_texture("assets/minecraft/textures/blocks/door_wood_lower.png")
elif blockid == 71: # iron door
raw_door = self.load_image_texture("assets/minecraft/textures/blocks/door_iron_lower.png")
elif blockid == 193: # spruce door
raw_door = self.load_image_texture("assets/minecraft/textures/blocks/door_spruce_lower.png")
elif blockid == 194: # birch door
raw_door = self.load_image_texture("assets/minecraft/textures/blocks/door_birch_lower.png")
elif blockid == 195: # jungle door
raw_door = self.load_image_texture("assets/minecraft/textures/blocks/door_jungle_lower.png")
elif blockid == 196: # acacia door
raw_door = self.load_image_texture("assets/minecraft/textures/blocks/door_acacia_lower.png")
elif blockid == 197: # dark_oak door
raw_door = self.load_image_texture("assets/minecraft/textures/blocks/door_dark_oak_lower.png")
# if you want to render all doors as closed, then force
# force closed to be True
@@ -2722,7 +2799,7 @@ def jukebox(self, blockid, data):
# nether and normal fences
# uses pseudo-ancildata found in iterate.c
@material(blockid=[85, 113], data=range(16), transparent=True, nospawn=True)
@material(blockid=[85, 188, 189, 190, 191, 192, 113], data=range(16), transparent=True, nospawn=True)
def fence(self, blockid, data):
# no need for rotations, it uses pseudo data.
# create needed images for Big stick fence
@@ -2730,6 +2807,26 @@ def fence(self, blockid, data):
fence_top = self.load_image_texture("assets/minecraft/textures/blocks/planks_oak.png").copy()
fence_side = self.load_image_texture("assets/minecraft/textures/blocks/planks_oak.png").copy()
fence_small_side = self.load_image_texture("assets/minecraft/textures/blocks/planks_oak.png").copy()
elif blockid == 188: # spruce fence
fence_top = self.load_image_texture("assets/minecraft/textures/blocks/planks_spruce.png").copy()
fence_side = self.load_image_texture("assets/minecraft/textures/blocks/planks_spruce.png").copy()
fence_small_side = self.load_image_texture("assets/minecraft/textures/blocks/planks_spruce.png").copy()
elif blockid == 189: # birch fence
fence_top = self.load_image_texture("assets/minecraft/textures/blocks/planks_birch.png").copy()
fence_side = self.load_image_texture("assets/minecraft/textures/blocks/planks_birch.png").copy()
fence_small_side = self.load_image_texture("assets/minecraft/textures/blocks/planks_birch.png").copy()
elif blockid == 190: # jungle fence
fence_top = self.load_image_texture("assets/minecraft/textures/blocks/planks_jungle.png").copy()
fence_side = self.load_image_texture("assets/minecraft/textures/blocks/planks_jungle.png").copy()
fence_small_side = self.load_image_texture("assets/minecraft/textures/blocks/planks_jungle.png").copy()
elif blockid == 191: # big/dark oak fence
fence_top = self.load_image_texture("assets/minecraft/textures/blocks/planks_big_oak.png").copy()
fence_side = self.load_image_texture("assets/minecraft/textures/blocks/planks_big_oak.png").copy()
fence_small_side = self.load_image_texture("assets/minecraft/textures/blocks/planks_big_oak.png").copy()
elif blockid == 192: # acacia oak fence
fence_top = self.load_image_texture("assets/minecraft/textures/blocks/planks_acacia.png").copy()
fence_side = self.load_image_texture("assets/minecraft/textures/blocks/planks_acacia.png").copy()
fence_small_side = self.load_image_texture("assets/minecraft/textures/blocks/planks_acacia.png").copy()
else: # netherbrick fence
fence_top = self.load_image_texture("assets/minecraft/textures/blocks/nether_brick.png").copy()
fence_side = self.load_image_texture("assets/minecraft/textures/blocks/nether_brick.png").copy()
@@ -3216,7 +3313,7 @@ def comparator(self, blockid, data):
# trapdoor
# the trapdoor is looks like a sprite when opened, that's not good
@material(blockid=96, data=range(16), transparent=True, nospawn=True)
@material(blockid=[96,167], data=range(16), transparent=True, nospawn=True)
def trapdoor(self, blockid, data):
# rotation
@@ -3238,7 +3335,10 @@ def trapdoor(self, blockid, data):
elif (data & 0b0011) == 3: data = data & 0b1100 | 0
# texture generation
texture = self.load_image_texture("assets/minecraft/textures/blocks/trapdoor.png")
if blockid == 96:
texture = self.load_image_texture("assets/minecraft/textures/blocks/trapdoor.png")
else:
texture = self.load_image_texture("assets/minecraft/textures/blocks/iron_trapdoor.png")
if data & 0x4 == 0x4: # opened trapdoor
if data & 0x3 == 0: # west
img = self.build_full_block(None, None, None, None, texture)
@@ -3487,7 +3587,7 @@ def vines(self, blockid, data):
return img
# fence gates
@material(blockid=107, data=range(8), transparent=True, nospawn=True)
@material(blockid=[107, 183, 184, 185, 186, 187], data=range(8), transparent=True, nospawn=True)
def fence_gate(self, blockid, data):
# rotation
@@ -3514,7 +3614,21 @@ def fence_gate(self, blockid, data):
data = data | 0x4
# create the closed gate side
gate_side = self.load_image_texture("assets/minecraft/textures/blocks/planks_oak.png").copy()
if blockid == 107: # Oak
gate_side = self.load_image_texture("assets/minecraft/textures/blocks/planks_oak.png").copy()
elif blockid == 183: # Spruce
gate_side = self.load_image_texture("assets/minecraft/textures/blocks/planks_spruce.png").copy()
elif blockid == 184: # Birch
gate_side = self.load_image_texture("assets/minecraft/textures/blocks/planks_birch.png").copy()
elif blockid == 185: # Jungle
gate_side = self.load_image_texture("assets/minecraft/textures/blocks/planks_jungle.png").copy()
elif blockid == 186: # Dark Oak
gate_side = self.load_image_texture("assets/minecraft/textures/blocks/planks_big_oak.png").copy()
elif blockid == 187: # Acacia
gate_side = self.load_image_texture("assets/minecraft/textures/blocks/planks_acacia.png").copy()
else:
return None
gate_side_draw = ImageDraw.Draw(gate_side)
gate_side_draw.rectangle((7,0,15,0),outline=(0,0,0,0),fill=(0,0,0,0))
gate_side_draw.rectangle((7,4,9,6),outline=(0,0,0,0),fill=(0,0,0,0))
@@ -4205,6 +4319,27 @@ def hopper(self, blockid, data):
return img
# slime block
block(blockid=165, top_image="assets/minecraft/textures/blocks/slime.png")
# prismarine block
@material(blockid=168, data=range(3), solid=True)
def prismarine_block(self, blockid, data):
if data == 0: # prismarine
t = self.load_image_texture("assets/minecraft/textures/blocks/prismarine_rough.png")
elif data == 1: # prismarine bricks
t = self.load_image_texture("assets/minecraft/textures/blocks/prismarine_bricks.png")
elif data == 2: # dark prismarine
t = self.load_image_texture("assets/minecraft/textures/blocks/prismarine_dark.png")
img = self.build_block(t, t)
return img
# sea lantern
block(blockid=169, top_image="assets/minecraft/textures/blocks/sea_lantern.png")
# hay block
@material(blockid=170, data=range(9), solid=True)
def hayblock(self, blockid, data):