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" - "2.7"
# - "3.2" # - "3.2"
env: env:
- MC_VERSION=1.7.4 - MC_VERSION=1.8
before_install: before_install:
- wget http://hg.effbot.org/pil-117/raw/f356a1f64271/libImaging/Imaging.h - wget http://hg.effbot.org/pil-117/raw/f356a1f64271/libImaging/Imaging.h
- wget http://hg.effbot.org/pil-117/raw/f356a1f64271/libImaging/ImPlatform.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") metavar = '<output>', type = str, dest = 'output', default = "output.png")
(options, args) = parser.parse_args() (options, args) = parser.parse_args()
tileset = args[0]
# arg is overviewer tile set folder # arg is overviewer tile set folder
if len(args) > 1: if len(args) > 1:
@@ -42,6 +42,7 @@ def main():
if not args: if not args:
parser.error("Error! Need an overviewer tile set folder. Use --help for a complete list of options.") 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: if not options.zoom_level:
parser.error("Error! The option zoom-level is mandatory.") 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 "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) print "A total of {0} MB of memory will be used.".format(mem/1024**2)
if mem/1024.**2. > options.memory_limit: 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) sys.exit(1)
# Create a new huge image # Create a new huge image

View File

@@ -625,7 +625,7 @@ Rendering
'crop': (-500, -500, 500, 500), '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'] = { renders['myrender'] = {
'world': 'myworld', '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}/ 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 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. * 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 os
import time
import logging import logging
import json import json
import sys import sys
@@ -22,6 +23,7 @@ import re
import urllib2 import urllib2
import multiprocessing import multiprocessing
import itertools import itertools
import gzip
from collections import defaultdict from collections import defaultdict
from multiprocessing import Pool from multiprocessing import Pool
@@ -134,6 +136,26 @@ def handleEntities(rset, config, filters, markers):
class PlayerDict(dict): class PlayerDict(dict):
use_uuid = False use_uuid = False
_name = '' _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): def __getitem__(self, item):
if item == "EntityId": if item == "EntityId":
if not super(PlayerDict, self).has_key("EntityId"): if not super(PlayerDict, self).has_key("EntityId"):
@@ -145,9 +167,17 @@ class PlayerDict(dict):
return super(PlayerDict, self).__getitem__(item) return super(PlayerDict, self).__getitem__(item)
def get_name_from_uuid(self): def get_name_from_uuid(self):
sname = self._name.replace('-','')
try: 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: if 'name' in profile:
PlayerDict.uuid_cache[sname] = profile
return profile['name'] return profile['name']
except (ValueError, urllib2.URLError): except (ValueError, urllib2.URLError):
logging.warning("Unable to get player name for UUID %s", self._name) 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['x'] = int(data['Pos'][0])
data['y'] = int(data['Pos'][1]) data['y'] = int(data['Pos'][1])
data['z'] = int(data['Pos'][2]) 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) # Spawn position (bed or main spawn)
if "SpawnX" in data: if "SpawnX" in data:
# Spawn position (bed or main spawn)
spawn = PlayerDict() spawn = PlayerDict()
spawn._name = playername spawn._name = playername
spawn["id"] = "PlayerSpawn" spawn["id"] = "PlayerSpawn"
@@ -395,6 +428,7 @@ def main():
# apply filters to players # apply filters to players
if not options.skipplayers: if not options.skipplayers:
PlayerDict.load_cache(destdir)
# group filters by worldpath, so we only search for players once per # group filters by worldpath, so we only search for players once per
# world # world
keyfunc = lambda x: x[4] keyfunc = lambda x: x[4]
@@ -414,6 +448,8 @@ def main():
logging.info("Done handling POIs") logging.info("Done handling POIs")
logging.info("Writing out javascript files") logging.info("Writing out javascript files")
PlayerDict.save_cache(destdir)
with open(os.path.join(destdir, "markersDB.js"), "w") as output: with open(os.path.join(destdir, "markersDB.js"), "w") as output:
output.write("var markersDB=") output.write("var markersDB=")
json.dump(markers, output, indent=2) 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 #this is an easy way to make the first update() call print a line
self.last_update = -101 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): def finish(self):
logging.info("Rendered %d of %d. %d%% complete", self.get_max_value(), self.fake.finish()
self.get_max_value(), 100.0) 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() super(LoggingObserver, self).finish()
def update(self, current_value): def update(self, current_value):
super(LoggingObserver, self).update(current_value) super(LoggingObserver, self).update(current_value)
self.fake.update(current_value)
if self._need_update(): 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_current_value(), self.get_max_value(),
self.get_percentage()) self.get_percentage(), self.eta.update(self.fake))
self.last_update = current_value self.last_update = current_value
return True return True
return False return False

View File

@@ -262,6 +262,7 @@ is_stairs(int block) {
case 156: /* quartz stairs */ case 156: /* quartz stairs */
case 163: /* acacia wood stairs */ case 163: /* acacia wood stairs */
case 164: /* dark wood stairs */ case 164: /* dark wood stairs */
case 180: /* red sandstone stairs */
return 1; return 1;
} }
return 0; 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; data = (check_adjacent_blocks(state, x, y, z, state->block) ^ 0x0f) | data;
return (data << 4) | (ancilData & 0x0f); 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 */ /* 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 */ } else if (state->block == 55) { /* redstone */
/* three addiotional bit are added, one for on/off state, and /* 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 */ /* portal and nether brick fences */
return check_adjacent_blocks(state, x, y, z, state->block); 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 /* use bottom block data format plus one bit for top/down
* block (0x8) and one bit for hinge position (0x10) * block (0x8) and one bit for hinge position (0x10)
*/ */
@@ -703,14 +709,21 @@ chunk_render(PyObject *self, PyObject *args) {
* trapped chests, stairs */ * trapped chests, stairs */
if ((state.block == 2) || (state.block == 9) || if ((state.block == 2) || (state.block == 9) ||
(state.block == 20) || (state.block == 54) || (state.block == 20) || (state.block == 54) ||
(state.block == 55) || (state.block == 64) || (state.block == 55) ||
(state.block == 71) || (state.block == 79) || /* 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 == 85) || (state.block == 90) ||
(state.block == 101) || (state.block == 102) || (state.block == 101) || (state.block == 102) ||
(state.block == 111) || (state.block == 113) || (state.block == 111) || (state.block == 113) ||
(state.block == 139) || (state.block == 175) || (state.block == 139) || (state.block == 175) ||
(state.block == 160) || (state.block == 95) || (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)) { is_stairs(state.block)) {
ancilData = generate_pseudo_data(&state, ancilData); ancilData = generate_pseudo_data(&state, ancilData);
state.block_pdata = ancilData; state.block_pdata = ancilData;

View File

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

View File

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

View File

@@ -252,12 +252,12 @@ class Textures(object):
most_recent_version = [0,0,0] most_recent_version = [0,0,0]
for version in versions: for version in versions:
# Look for the latest non-snapshot that is at least 1.6. This # Look for the latest non-snapshot that is at least 1.8. This
# version is only compatible with >=1.6, and we cannot in general # version is only compatible with >=1.8, and we cannot in general
# tell if a snapshot is more or less recent than a release. # tell if a snapshot is more or less recent than a release.
# Allow two component names such as "1.6" and three component names # Allow two component names such as "1.8" and three component names
# such as "1.6.1" # such as "1.8.1"
if version.count(".") not in (1,2): if version.count(".") not in (1,2):
continue continue
try: try:
@@ -265,14 +265,14 @@ class Textures(object):
except ValueError: except ValueError:
continue continue
if versionparts < [1,7]: if versionparts < [1,8]:
continue continue
if versionparts > most_recent_version: if versionparts > most_recent_version:
most_recent_version = versionparts most_recent_version = versionparts
if most_recent_version != [0,0,0]: 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) jarname = ".".join(str(x) for x in most_recent_version)
jarpath = os.path.join(versiondir, jarname, jarname + ".jar") 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)) if verbose: logging.info("Did not find file {0} in jar {1}".format(filename, jarpath))
else: 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 # 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 # 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) if verbose: logging.info("Found %s in '%s'", filename, path)
return open(path, mode) 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): def load_image_texture(self, filename):
# Textures may be animated or in a different resolution than 16x16. # 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()) self.foliagecolor = list(self.load_image("foliage.png").getdata())
return self.foliagecolor 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): def load_water_color(self):
"""Helper function to load the water color texture.""" """Helper function to load the water color texture."""
if not hasattr(self, "watercolor"): if not hasattr(self, "watercolor"):
@@ -864,7 +864,23 @@ def billboard(blockid=[], imagename=None, **kwargs):
## ##
# stone # 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) @material(blockid=2, data=range(11)+[0x10,], solid=True)
def grass(self, blockid, data): 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")) return self.build_block(top, self.load_image_texture("assets/minecraft/textures/blocks/sandstone_carved.png"))
if data == 2: # soft if data == 2: # soft
return self.build_block(top, self.load_image_texture("assets/minecraft/textures/blocks/sandstone_smooth.png")) 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 # note block
block(blockid=25, top_image="assets/minecraft/textures/blocks/noteblock.png") 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 # double slabs and slabs
# these wooden slabs are unobtainable without cheating, they are still # these wooden slabs are unobtainable without cheating, they are still
# here because lots of pre-1.3 worlds use this blocks # 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): def slabs(self, blockid, data):
if blockid == 44: if blockid == 44 or blockid == 182:
texture = data & 7 texture = data & 7
else: # data > 8 are special double slabs else: # data > 8 are special double slabs
texture = data texture = data
if texture== 0: # stone slab
top = self.load_image_texture("assets/minecraft/textures/blocks/stone_slab_top.png") if blockid == 44 or blockid == 43:
side = self.load_image_texture("assets/minecraft/textures/blocks/stone_slab_side.png") if texture== 0: # stone slab
elif texture== 1: # smooth stone top = self.load_image_texture("assets/minecraft/textures/blocks/stone_slab_top.png")
top = self.load_image_texture("assets/minecraft/textures/blocks/sandstone_top.png") side = self.load_image_texture("assets/minecraft/textures/blocks/stone_slab_side.png")
side = self.load_image_texture("assets/minecraft/textures/blocks/sandstone_normal.png") elif texture== 1: # sandstone slab
elif texture== 2: # wooden slab top = self.load_image_texture("assets/minecraft/textures/blocks/sandstone_top.png")
top = side = self.load_image_texture("assets/minecraft/textures/blocks/planks_oak.png") side = self.load_image_texture("assets/minecraft/textures/blocks/sandstone_normal.png")
elif texture== 3: # cobblestone slab elif texture== 2: # wooden slab
top = side = self.load_image_texture("assets/minecraft/textures/blocks/cobblestone.png") top = side = self.load_image_texture("assets/minecraft/textures/blocks/planks_oak.png")
elif texture== 4: # brick elif texture== 3: # cobblestone slab
top = side = self.load_image_texture("assets/minecraft/textures/blocks/brick.png") top = side = self.load_image_texture("assets/minecraft/textures/blocks/cobblestone.png")
elif texture== 5: # stone brick elif texture== 4: # brick
top = side = self.load_image_texture("assets/minecraft/textures/blocks/stonebrick.png") top = side = self.load_image_texture("assets/minecraft/textures/blocks/brick.png")
elif texture== 6: # nether brick slab elif texture== 5: # stone brick
top = side = self.load_image_texture("assets/minecraft/textures/blocks/nether_brick.png") top = side = self.load_image_texture("assets/minecraft/textures/blocks/stonebrick.png")
elif texture== 7: #quartz elif texture== 6: # nether brick slab
top = side = self.load_image_texture("assets/minecraft/textures/blocks/quartz_block_side.png") top = side = self.load_image_texture("assets/minecraft/textures/blocks/nether_brick.png")
elif texture== 8: # special stone double slab with top texture only elif texture== 7: #quartz
top = side = self.load_image_texture("assets/minecraft/textures/blocks/stone_slab_top.png") top = side = self.load_image_texture("assets/minecraft/textures/blocks/quartz_block_side.png")
elif texture== 9: # special sandstone double slab with top texture only elif texture== 8: # special stone double slab with top texture only
top = side = self.load_image_texture("assets/minecraft/textures/blocks/sandstone_top.png") top = side = self.load_image_texture("assets/minecraft/textures/blocks/stone_slab_top.png")
else: elif texture== 9: # special sandstone double slab with top texture only
return None 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) return self.build_block(top, side)
# cut the side texture in half # cut the side texture in half
@@ -1693,8 +1739,8 @@ def fire(self, blockid, data):
# monster spawner # monster spawner
block(blockid=52, top_image="assets/minecraft/textures/blocks/mob_spawner.png", transparent=True) 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. # 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], data=range(128), transparent=True, solid=True, nospawn=True) @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): def stairs(self, blockid, data):
# preserve the upside-down bit # preserve the upside-down bit
upside_down = data & 0x4 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() texture = self.load_image_texture("assets/minecraft/textures/blocks/planks_acacia.png").copy()
elif blockid == 164: # dark oak stairs elif blockid == 164: # dark oak stairs
texture = self.load_image_texture("assets/minecraft/textures/blocks/planks_big_oak.png").copy() 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_l = texture.copy()
outside_r = texture.copy() outside_r = texture.copy()
inside_l = texture.copy() inside_l = texture.copy()
inside_r = 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: if blockid == 128:
texture = self.load_image_texture("assets/minecraft/textures/blocks/sandstone_top.png").copy() texture = self.load_image_texture("assets/minecraft/textures/blocks/sandstone_top.png").copy()
elif blockid == 156: elif blockid == 156:
texture = self.load_image_texture("assets/minecraft/textures/blocks/quartz_block_top.png").copy() 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() slab_top = texture.copy()
@@ -2179,7 +2230,7 @@ def signpost(self, blockid, data):
# wooden and iron door # wooden and iron door
# uses pseudo-ancildata found in iterate.c # 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): def door(self, blockid, data):
#Masked to not clobber block top/bottom & swung info #Masked to not clobber block top/bottom & swung info
if self.rotation == 1: if self.rotation == 1:
@@ -2199,9 +2250,35 @@ def door(self, blockid, data):
elif (data & 0b00011) == 3: data = data & 0b11100 | 2 elif (data & 0b00011) == 3: data = data & 0b11100 | 2
if data & 0x8 == 0x8: # top of the door 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 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 # if you want to render all doors as closed, then force
# force closed to be True # force closed to be True
@@ -2722,7 +2799,7 @@ def jukebox(self, blockid, data):
# nether and normal fences # nether and normal fences
# uses pseudo-ancildata found in iterate.c # 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): def fence(self, blockid, data):
# no need for rotations, it uses pseudo data. # no need for rotations, it uses pseudo data.
# create needed images for Big stick fence # 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_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_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() 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 else: # netherbrick fence
fence_top = self.load_image_texture("assets/minecraft/textures/blocks/nether_brick.png").copy() 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() fence_side = self.load_image_texture("assets/minecraft/textures/blocks/nether_brick.png").copy()
@@ -3216,7 +3313,7 @@ def comparator(self, blockid, data):
# trapdoor # trapdoor
# the trapdoor is looks like a sprite when opened, that's not good # 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): def trapdoor(self, blockid, data):
# rotation # rotation
@@ -3238,7 +3335,10 @@ def trapdoor(self, blockid, data):
elif (data & 0b0011) == 3: data = data & 0b1100 | 0 elif (data & 0b0011) == 3: data = data & 0b1100 | 0
# texture generation # 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 & 0x4 == 0x4: # opened trapdoor
if data & 0x3 == 0: # west if data & 0x3 == 0: # west
img = self.build_full_block(None, None, None, None, texture) img = self.build_full_block(None, None, None, None, texture)
@@ -3487,7 +3587,7 @@ def vines(self, blockid, data):
return img return img
# fence gates # 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): def fence_gate(self, blockid, data):
# rotation # rotation
@@ -3514,7 +3614,21 @@ def fence_gate(self, blockid, data):
data = data | 0x4 data = data | 0x4
# create the closed gate side # 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 = 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,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)) 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 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 # hay block
@material(blockid=170, data=range(9), solid=True) @material(blockid=170, data=range(9), solid=True)
def hayblock(self, blockid, data): def hayblock(self, blockid, data):