2017-07-19 22:44:43 +02:00
#!/usr/bin/env python
2018-06-05 01:58:40 +02:00
# -*- coding: utf-8 -*-
2018-06-05 01:44:57 +02:00
# Texture Converter.
# Converts Minecraft resource packs to Minetest texture packs.
# See README.md.
2017-07-19 22:44:43 +02:00
__author__ = " Wuzzy "
2017-11-18 01:25:55 +01:00
__license__ = " MIT License "
2017-07-19 22:44:43 +02:00
__status__ = " Development "
2017-11-18 02:33:43 +01:00
import shutil , csv , os , tempfile , sys , getopt
# Helper vars
home = os . environ [ " HOME " ]
mineclone2_path = home + " /.minetest/games/mineclone2 "
working_dir = os . getcwd ( )
2017-11-18 03:42:44 +01:00
appname = " Texture_Converter.py "
2017-11-18 02:33:43 +01:00
2017-07-19 22:44:43 +02:00
### SETTINGS ###
2017-11-18 02:33:43 +01:00
output_dir = working_dir
base_dir = None
2017-07-19 22:44:43 +02:00
# If True, will only make console output but not convert anything.
dry_run = False
# If True, textures will be put into a texture pack directory structure.
# If False, textures will be put into MineClone 2 directories.
2017-07-28 04:56:49 +02:00
make_texture_pack = True
2017-07-19 22:44:43 +02:00
2017-07-28 14:36:50 +02:00
# If True, prints all copying actions
verbose = False
2017-11-18 03:40:29 +01:00
PXSIZE = 16
2017-11-18 03:42:44 +01:00
syntax_help = appname + """ -i <input dir> [-o <output dir>] [-d] [-v|-q] [-h]
2017-11-18 02:33:43 +01:00
Mandatory argument :
- i < input directory >
Directory of Minecraft resource pack to convert
Optional arguments :
2018-06-05 02:03:07 +02:00
- p < texture size >
Specify the size ( in pixels ) of the original textures ( default : 16 )
2017-11-18 02:33:43 +01:00
- o < output directory >
2018-06-05 01:53:59 +02:00
Directory in which to put the resulting Minetest texture pack
2017-11-18 02:33:43 +01:00
( default : working directory )
- d
2018-06-05 01:53:59 +02:00
Just pretend to convert textures and just print output , but do not actually
change any files .
2017-11-18 02:33:43 +01:00
- v
2018-06-05 01:53:59 +02:00
Print out all copying actions
2017-11-18 02:33:43 +01:00
- h
2018-06-05 01:53:59 +02:00
Show this help and exit """
2017-11-18 02:33:43 +01:00
try :
2017-11-18 03:40:29 +01:00
opts , args = getopt . getopt ( sys . argv [ 1 : ] , " hi:o:p:dv " )
2017-11-18 02:33:43 +01:00
except getopt . GetoptError :
print (
""" ERROR! The options you gave me make no sense!
Here ' s the syntax reference: " " " )
print ( syntax_help )
sys . exit ( 2 )
for opt , arg in opts :
if opt == " -h " :
print (
""" This is the official MineClone 2 Texture Converter.
This will convert textures from Minecraft resource packs to
2018-06-05 01:53:59 +02:00
a Minetest texture pack .
2017-11-18 02:33:43 +01:00
2023-12-29 05:00:53 +01:00
Supported Minecraft version : 1.20 ( Java Edition )
2017-11-18 02:33:43 +01:00
Syntax : """ )
print ( syntax_help )
sys . exit ( )
elif opt == " -d " :
dry_run = True
elif opt == " -v " :
verbose = True
elif opt == " -i " :
base_dir = arg
elif opt == " -o " :
output_dir = arg
2017-11-18 03:40:29 +01:00
elif opt == " -p " :
PXSIZE = int ( arg )
2017-11-18 02:33:43 +01:00
if base_dir == None :
print (
2018-06-05 02:03:07 +02:00
""" ERROR: You didn ' t tell me the path to the Minecraft resource pack.
2017-11-18 02:33:43 +01:00
Mind - reading has not been implemented yet .
Try this :
2018-06-05 02:03:07 +02:00
""" +appname+ """ - i < path to resource pack > - p < texture size >
2017-11-18 02:33:43 +01:00
For the full help , use :
2017-11-18 03:42:44 +01:00
""" +appname+ """ - h """ )
2017-11-18 02:33:43 +01:00
sys . exit ( 2 ) ;
2017-07-19 22:44:43 +02:00
2017-11-18 02:33:43 +01:00
### END OF SETTINGS ###
2017-07-19 22:44:43 +02:00
tex_dir = base_dir + " /assets/minecraft/textures "
2019-02-07 22:22:07 +01:00
# Get texture pack name (from directory name)
bdir_split = base_dir . split ( " / " )
output_dir_name = bdir_split [ - 1 ]
if len ( output_dir_name ) == 0 :
if len ( bdir_split ) > = 2 :
output_dir_name = base_dir . split ( " / " ) [ - 2 ]
else :
# Fallback
output_dir_name = " New_MineClone_2_Texture_Pack "
2017-07-28 14:20:50 +02:00
# FUNCTION DEFINITIONS
2017-11-18 07:39:02 +01:00
def colorize ( colormap , source , colormap_pixel , texture_size , destination ) :
2017-11-18 05:52:40 +01:00
os . system ( " convert " + colormap + " -crop 1x1+ " + colormap_pixel + " -depth 8 -resize " + texture_size + " x " + texture_size + " " + tempfile1 . name )
2017-11-18 07:39:02 +01:00
os . system ( " composite -compose Multiply " + tempfile1 . name + " " + source + " " + destination )
def colorize_alpha ( colormap , source , colormap_pixel , texture_size , destination ) :
colorize ( colormap , source , colormap_pixel , texture_size , tempfile2 . name )
2017-11-18 06:13:08 +01:00
os . system ( " composite -compose Dst_In " + source + " " + tempfile2 . name + " -alpha Set " + destination )
2017-07-19 22:44:43 +02:00
def target_dir ( directory ) :
if make_texture_pack :
2017-11-18 02:33:43 +01:00
return output_dir + " / " + output_dir_name
2017-07-19 22:44:43 +02:00
else :
return mineclone2_path + directory
# Copy texture files
def convert_textures ( ) :
2017-07-28 14:36:50 +02:00
failed_conversions = 0
print ( " Texture conversion BEGINS NOW! " )
2017-11-18 03:42:44 +01:00
with open ( " Conversion_Table.csv " , newline = " " ) as csvfile :
2017-07-19 22:44:43 +02:00
reader = csv . reader ( csvfile , delimiter = " , " , quotechar = ' " ' )
first_row = True
for row in reader :
# Skip first row
if first_row :
first_row = False
continue
src_dir = row [ 0 ]
src_filename = row [ 1 ]
2024-01-09 08:26:54 +01:00
dst_dir = ' ./textures '
dst_filename = row [ 2 ]
2017-07-19 22:44:43 +02:00
if row [ 4 ] != " " :
2024-01-09 08:26:54 +01:00
xs = int ( row [ 3 ] )
ys = int ( row [ 4 ] )
xl = int ( row [ 5 ] )
yl = int ( row [ 6 ] )
xt = int ( row [ 7 ] )
yt = int ( row [ 8 ] )
2017-07-19 22:44:43 +02:00
else :
xs = None
2024-01-09 08:26:54 +01:00
blacklisted = row [ 9 ]
2017-11-18 04:42:42 +01:00
if blacklisted == " y " :
# Skip blacklisted files
continue
2017-07-19 22:44:43 +02:00
2017-11-18 20:30:21 +01:00
if make_texture_pack == False and dst_dir == " " :
# If destination dir is empty, this texture is not supposed to be used in MCL2
# (but maybe an external mod). It should only be used in texture packs.
# Otherwise, it must be ignored.
# Example: textures for mcl_supplemental
continue
2017-07-19 22:44:43 +02:00
src_file = base_dir + src_dir + " / " + src_filename # source file
src_file_exists = os . path . isfile ( src_file )
dst_file = target_dir ( dst_dir ) + " / " + dst_filename # destination file
if src_file_exists == False :
print ( " WARNING: Source file does not exist: " + src_file )
2017-07-28 14:36:50 +02:00
failed_conversions = failed_conversions + 1
2017-07-19 22:44:43 +02:00
continue
if xs != None :
# Crop and copy images
if not dry_run :
2017-11-20 20:51:58 +01:00
os . system ( " convert " + src_file + " -crop " + xl + " x " + yl + " + " + xs + " + " + ys + " " + dst_file )
2017-07-28 14:36:50 +02:00
if verbose :
print ( src_file + " → " + dst_file )
2017-07-19 22:44:43 +02:00
else :
# Copy image verbatim
if not dry_run :
shutil . copy2 ( src_file , dst_file )
2017-07-28 14:36:50 +02:00
if verbose :
print ( src_file + " → " + dst_file )
2017-07-19 22:44:43 +02:00
2021-05-01 16:52:16 +02:00
# Convert map background
map_background_file = tex_dir + " /map/map_background.png "
if os . path . isfile ( map_background_file ) :
os . system ( " convert " + map_background_file + " -interpolate Integer -filter point -resize \" 140x140 \" " + target_dir ( " /mods/ITEMS/mcl_maps/textures " ) + " /mcl_maps_map_background.png " )
2021-01-17 10:12:03 +01:00
# Convert armor textures (requires ImageMagick)
armor_files = [
[ tex_dir + " /models/armor/leather_layer_1.png " , tex_dir + " /models/armor/leather_layer_2.png " , target_dir ( " /mods/ITEMS/mcl_armor/textures " ) , " mcl_armor_helmet_leather.png " , " mcl_armor_chestplate_leather.png " , " mcl_armor_leggings_leather.png " , " mcl_armor_boots_leather.png " ] ,
[ tex_dir + " /models/armor/chainmail_layer_1.png " , tex_dir + " /models/armor/chainmail_layer_2.png " , target_dir ( " /mods/ITEMS/mcl_armor/textures " ) , " mcl_armor_helmet_chain.png " , " mcl_armor_chestplate_chain.png " , " mcl_armor_leggings_chain.png " , " mcl_armor_boots_chain.png " ] ,
[ tex_dir + " /models/armor/gold_layer_1.png " , tex_dir + " /models/armor/gold_layer_2.png " , target_dir ( " /mods/ITEMS/mcl_armor/textures " ) , " mcl_armor_helmet_gold.png " , " mcl_armor_chestplate_gold.png " , " mcl_armor_leggings_gold.png " , " mcl_armor_boots_gold.png " ] ,
[ tex_dir + " /models/armor/iron_layer_1.png " , tex_dir + " /models/armor/iron_layer_2.png " , target_dir ( " /mods/ITEMS/mcl_armor/textures " ) , " mcl_armor_helmet_iron.png " , " mcl_armor_chestplate_iron.png " , " mcl_armor_leggings_iron.png " , " mcl_armor_boots_iron.png " ] ,
2021-04-22 15:59:53 +02:00
[ tex_dir + " /models/armor/diamond_layer_1.png " , tex_dir + " /models/armor/diamond_layer_2.png " , target_dir ( " /mods/ITEMS/mcl_armor/textures " ) , " mcl_armor_helmet_diamond.png " , " mcl_armor_chestplate_diamond.png " , " mcl_armor_leggings_diamond.png " , " mcl_armor_boots_diamond.png " ] ,
[ tex_dir + " /models/armor/netherite_layer_1.png " , tex_dir + " /models/armor/netherite_layer_2.png " , target_dir ( " /mods/ITEMS/mcl_armor/textures " ) , " mcl_armor_helmet_netherite.png " , " mcl_armor_chestplate_netherite.png " , " mcl_armor_leggings_netherite.png " , " mcl_armor_boots_netherite.png " ]
2021-01-17 10:12:03 +01:00
]
for a in armor_files :
APXSIZE = 16 # for some reason MineClone2 requires this
layer_1 = a [ 0 ]
layer_2 = a [ 1 ]
adir = a [ 2 ]
if os . path . isfile ( layer_1 ) :
helmet = adir + " / " + a [ 3 ]
chestplate = adir + " / " + a [ 4 ]
boots = adir + " / " + a [ 6 ]
os . system ( " convert -size " + str ( APXSIZE * 4 ) + " x " + str ( APXSIZE * 2 ) + " xc:none \\ ( " + layer_1 + " -scale " + str ( APXSIZE * 4 ) + " x " + str ( APXSIZE * 2 ) + " -geometry + " + str ( APXSIZE * 2 ) + " +0 -crop " + str ( APXSIZE * 2 ) + " x " + str ( APXSIZE ) + " +0+0 \ ) -composite -channel A -fx \" (a > 0.0) ? 1.0 : 0.0 \" " + helmet )
os . system ( " convert -size " + str ( APXSIZE * 4 ) + " x " + str ( APXSIZE * 2 ) + " xc:none \\ ( " + layer_1 + " -scale " + str ( APXSIZE * 4 ) + " x " + str ( APXSIZE * 2 ) + " -geometry + " + str ( APXSIZE ) + " + " + str ( APXSIZE ) + " -crop " + str ( APXSIZE * 2.5 ) + " x " + str ( APXSIZE ) + " + " + str ( APXSIZE ) + " + " + str ( APXSIZE ) + " \ ) -composite -channel A -fx \" (a > 0.0) ? 1.0 : 0.0 \" " + chestplate )
os . system ( " convert -size " + str ( APXSIZE * 4 ) + " x " + str ( APXSIZE * 2 ) + " xc:none \\ ( " + layer_1 + " -scale " + str ( APXSIZE * 4 ) + " x " + str ( APXSIZE * 2 ) + " -geometry +0+ " + str ( APXSIZE ) + " -crop " + str ( APXSIZE ) + " x " + str ( APXSIZE ) + " +0+ " + str ( APXSIZE ) + " \ ) -composite -channel A -fx \" (a > 0.0) ? 1.0 : 0.0 \" " + boots )
if os . path . isfile ( layer_2 ) :
leggings = adir + " / " + a [ 5 ]
os . system ( " convert -size " + str ( APXSIZE * 4 ) + " x " + str ( APXSIZE * 2 ) + " xc:none \\ ( " + layer_2 + " -scale " + str ( APXSIZE * 4 ) + " x " + str ( APXSIZE * 2 ) + " -geometry +0+ " + str ( APXSIZE ) + " -crop " + str ( APXSIZE * 2.5 ) + " x " + str ( APXSIZE ) + " +0+ " + str ( APXSIZE ) + " \ ) -composite -channel A -fx \" (a > 0.0) ? 1.0 : 0.0 \" " + leggings )
2017-07-19 22:44:43 +02:00
# Convert chest textures (requires ImageMagick)
2018-05-18 19:34:23 +02:00
chest_files = [
[ tex_dir + " /entity/chest/normal.png " , target_dir ( " /mods/ITEMS/mcl_chests/textures " ) , " default_chest_top.png " , " mcl_chests_chest_bottom.png " , " default_chest_front.png " , " mcl_chests_chest_left.png " , " mcl_chests_chest_right.png " , " mcl_chests_chest_back.png " ] ,
[ tex_dir + " /entity/chest/trapped.png " , target_dir ( " /mods/ITEMS/mcl_chests/textures " ) , " mcl_chests_chest_trapped_top.png " , " mcl_chests_chest_trapped_bottom.png " , " mcl_chests_chest_trapped_front.png " , " mcl_chests_chest_trapped_left.png " , " mcl_chests_chest_trapped_right.png " , " mcl_chests_chest_trapped_back.png " ] ,
[ tex_dir + " /entity/chest/ender.png " , target_dir ( " /mods/ITEMS/mcl_chests/textures " ) , " mcl_chests_ender_chest_top.png " , " mcl_chests_ender_chest_bottom.png " , " mcl_chests_ender_chest_front.png " , " mcl_chests_ender_chest_left.png " , " mcl_chests_ender_chest_right.png " , " mcl_chests_ender_chest_back.png " ]
]
for c in chest_files :
chest_file = c [ 0 ]
if os . path . isfile ( chest_file ) :
PPX = ( PXSIZE / 16 )
2018-05-18 19:51:37 +02:00
CHPX = ( PPX * 14 ) # Chest width
LIDPX = ( PPX * 5 ) # Lid height
LIDLOW = ( PPX * 10 ) # Lower lid section height
2018-05-18 19:34:23 +02:00
LOCKW = ( PPX * 6 ) # Lock width
LOCKH = ( PPX * 5 ) # Lock height
cdir = c [ 1 ]
top = cdir + " / " + c [ 2 ]
bottom = cdir + " / " + c [ 3 ]
front = cdir + " / " + c [ 4 ]
left = cdir + " / " + c [ 5 ]
right = cdir + " / " + c [ 6 ]
back = cdir + " / " + c [ 7 ]
# Top
os . system ( " convert " + chest_file + " \
\( - clone 0 - crop " +str(CHPX)+ " x " +str(CHPX)+ " + " +str(CHPX)+ " + 0 \) - geometry + 0 + 0 - composite - extent " +str(CHPX)+ " x " +str(CHPX)+ " " +top)
# Bottom
os . system ( " convert " + chest_file + " \
\( - clone 0 - crop " +str(CHPX)+ " x " +str(CHPX)+ " + " +str(CHPX*2)+ " + " +str(CHPX+LIDPX)+ " \) - geometry + 0 + 0 - composite - extent " +str(CHPX)+ " x " +str(CHPX)+ " " +bottom)
# Front
os . system ( " convert " + chest_file + " \
\( - clone 0 - crop " +str(CHPX)+ " x " +str(LIDPX)+ " + " +str(CHPX)+ " + " +str(CHPX)+ " \) - geometry + 0 + 0 - composite \
2018-05-18 19:51:37 +02:00
\( - clone 0 - crop " +str(CHPX)+ " x " +str(LIDLOW)+ " + " +str(CHPX)+ " + " +str(CHPX*2+LIDPX)+ " \) - geometry + 0 + " +str(LIDPX-PPX)+ " - composite \
2018-05-18 19:34:23 +02:00
- extent " +str(CHPX)+ " x " +str(CHPX)+ " " +front)
# TODO: Add lock
# Left, right back (use same texture, we're lazy
files = [ left , right , back ]
for f in files :
os . system ( " convert " + chest_file + " \
\( - clone 0 - crop " +str(CHPX)+ " x " +str(LIDPX)+ " + " +str(0)+ " + " +str(CHPX)+ " \) - geometry + 0 + 0 - composite \
2018-05-18 19:51:37 +02:00
\( - clone 0 - crop " +str(CHPX)+ " x " +str(LIDLOW)+ " + " +str(0)+ " + " +str(CHPX*2+LIDPX)+ " \) - geometry + 0 + " +str(LIDPX-PPX)+ " - composite \
2018-05-18 19:34:23 +02:00
- extent " +str(CHPX)+ " x " +str(CHPX)+ " " +f)
2017-07-19 22:44:43 +02:00
2018-05-18 20:48:39 +02:00
# Double chests
chest_files = [
[ tex_dir + " /entity/chest/normal_double.png " , target_dir ( " /mods/ITEMS/mcl_chests/textures " ) , " default_chest_front_big.png " , " default_chest_top_big.png " , " default_chest_side_big.png " ] ,
[ tex_dir + " /entity/chest/trapped_double.png " , target_dir ( " /mods/ITEMS/mcl_chests/textures " ) , " mcl_chests_chest_trapped_front_big.png " , " mcl_chests_chest_trapped_top_big.png " , " mcl_chests_chest_trapped_side_big.png " ]
]
for c in chest_files :
chest_file = c [ 0 ]
if os . path . isfile ( chest_file ) :
PPX = ( PXSIZE / 16 )
CHPX = ( PPX * 14 ) # Chest width (short side)
CHPX2 = ( PPX * 15 ) # Chest width (long side)
LIDPX = ( PPX * 5 ) # Lid height
LIDLOW = ( PPX * 10 ) # Lower lid section height
LOCKW = ( PPX * 6 ) # Lock width
LOCKH = ( PPX * 5 ) # Lock height
cdir = c [ 1 ]
front = cdir + " / " + c [ 2 ]
top = cdir + " / " + c [ 3 ]
side = cdir + " / " + c [ 4 ]
# Top
os . system ( " convert " + chest_file + " \
\( - clone 0 - crop " +str(CHPX2)+ " x " +str(CHPX)+ " + " +str(CHPX)+ " + 0 \) - geometry + 0 + 0 - composite - extent " +str(CHPX2)+ " x " +str(CHPX)+ " " +top)
# Front
# TODO: Add lock
os . system ( " convert " + chest_file + " \
\( - clone 0 - crop " +str(CHPX2)+ " x " +str(LIDPX)+ " + " +str(CHPX)+ " + " +str(CHPX)+ " \) - geometry + 0 + 0 - composite \
\( - clone 0 - crop " +str(CHPX2)+ " x " +str(LIDLOW)+ " + " +str(CHPX)+ " + " +str(CHPX*2+LIDPX)+ " \) - geometry + 0 + " +str(LIDPX-PPX)+ " - composite \
- extent " +str(CHPX2)+ " x " +str(CHPX)+ " " +front)
# Side
os . system ( " convert " + chest_file + " \
\( - clone 0 - crop " +str(CHPX)+ " x " +str(LIDPX)+ " + " +str(0)+ " + " +str(CHPX)+ " \) - geometry + 0 + 0 - composite \
\( - clone 0 - crop " +str(CHPX)+ " x " +str(LIDLOW)+ " + " +str(0)+ " + " +str(CHPX*2+LIDPX)+ " \) - geometry + 0 + " +str(LIDPX-PPX)+ " - composite \
- extent " +str(CHPX)+ " x " +str(CHPX)+ " " +side)
2017-11-18 19:38:59 +01:00
# Generate railway crossings and t-junctions. Note: They may look strange.
# Note: these may be only a temporary solution, as crossings and t-junctions do not occour in MC.
# TODO: Curves
rails = [
# (Straigt src, curved src, t-junction dest, crossing dest)
2023-12-29 17:23:44 +01:00
( " rail.png " , " rail_corner.png " , " default_rail_t_junction.png " , " default_rail_crossing.png " ) ,
( " powered_rail.png " , " rail_corner.png " , " carts_rail_t_junction_pwr.png " , " carts_rail_crossing_pwr.png " ) ,
( " powered_rail_on.png " , " rail_corner.png " , " mcl_minecarts_rail_golden_t_junction_powered.png " , " mcl_minecarts_rail_golden_crossing_powered.png " ) ,
( " detector_rail.png " , " rail_corner.png " , " mcl_minecarts_rail_detector_t_junction.png " , " mcl_minecarts_rail_detector_crossing.png " ) ,
( " detector_rail_on.png " , " rail_corner.png " , " mcl_minecarts_rail_detector_t_junction_powered.png " , " mcl_minecarts_rail_detector_crossing_powered.png " ) ,
( " activator_rail.png " , " rail_corner.png " , " mcl_minecarts_rail_activator_t_junction.png " , " mcl_minecarts_rail_activator_crossing.png " ) ,
( " activator_rail_on.png " , " rail_corner.png " , " mcl_minecarts_rail_activator_d_t_junction.png " , " mcl_minecarts_rail_activator_powered_crossing.png " ) ,
2017-11-18 19:38:59 +01:00
]
for r in rails :
2023-12-29 17:16:37 +01:00
os . system ( " composite -compose Dst_Over " + tex_dir + " /block/ " + r [ 0 ] + " " + tex_dir + " /block/ " + r [ 1 ] + " " + target_dir ( " /mods/ENTITIES/mcl_minecarts/textures " ) + " / " + r [ 2 ] )
os . system ( " convert " + tex_dir + " /block/ " + r [ 0 ] + " -rotate 90 " + tempfile1 . name )
os . system ( " composite -compose Dst_Over " + tempfile1 . name + " " + tex_dir + " /block/ " + r [ 0 ] + " " + target_dir ( " /mods/ENTITIES/mcl_minecarts/textures " ) + " / " + r [ 3 ] )
2017-11-18 19:38:59 +01:00
2018-05-18 23:51:17 +02:00
# Convert banner overlays
overlays = [
" base " ,
" border " ,
" bricks " ,
" circle " ,
" creeper " ,
" cross " ,
" curly_border " ,
" diagonal_left " ,
" diagonal_right " ,
" diagonal_up_left " ,
" diagonal_up_right " ,
" flower " ,
" gradient " ,
" gradient_up " ,
" half_horizontal_bottom " ,
" half_horizontal " ,
" half_vertical " ,
" half_vertical_right " ,
" rhombus " ,
" mojang " ,
" skull " ,
" small_stripes " ,
" straight_cross " ,
" stripe_bottom " ,
" stripe_center " ,
" stripe_downleft " ,
" stripe_downright " ,
" stripe_left " ,
" stripe_middle " ,
" stripe_right " ,
" stripe_top " ,
" square_bottom_left " ,
" square_bottom_right " ,
" square_top_left " ,
" square_top_right " ,
" triangle_bottom " ,
" triangles_bottom " ,
" triangle_top " ,
" triangles_top " ,
]
for o in overlays :
orig = tex_dir + " /entity/banner/ " + o + " .png "
if os . path . isfile ( orig ) :
if o == " mojang " :
o = " thing "
dest = target_dir ( " /mods/ITEMS/mcl_banners/textures " ) + " / " + " mcl_banners_ " + o + " .png "
os . system ( " convert " + orig + " -transparent-color white -background black -alpha remove -alpha copy -channel RGB -white-threshold 0 " + dest )
2017-07-19 22:44:43 +02:00
# Convert grass
2023-12-28 18:35:51 +01:00
grass_file = tex_dir + " /block/grass_block_top.png "
2017-07-19 22:44:43 +02:00
if os . path . isfile ( grass_file ) :
FOLIAG = tex_dir + " /colormap/foliage.png "
GRASS = tex_dir + " /colormap/grass.png "
2021-01-17 10:12:03 +01:00
2017-07-19 22:44:43 +02:00
# Leaves
2023-12-29 17:40:11 +01:00
colorize_alpha ( FOLIAG , tex_dir + " /block/oak_leaves.png " , " 116+143 " , str ( PXSIZE ) , target_dir ( " /textures " ) + " /default_leaves.png " )
colorize_alpha ( FOLIAG , tex_dir + " /block/dark_oak_leaves.png " , " 158+177 " , str ( PXSIZE ) , target_dir ( " /textures " ) + " /mcl_core_leaves_big_oak.png " )
colorize_alpha ( FOLIAG , tex_dir + " /block/acacia_leaves.png " , " 40+255 " , str ( PXSIZE ) , target_dir ( " /textures " ) + " /default_acacia_leaves.png " )
colorize_alpha ( FOLIAG , tex_dir + " /block/spruce_leaves.png " , " 226+230 " , str ( PXSIZE ) , target_dir ( " /textures " ) + " /mcl_core_leaves_spruce.png " )
colorize_alpha ( FOLIAG , tex_dir + " /block/birch_leaves.png " , " 141+186 " , str ( PXSIZE ) , target_dir ( " /textures " ) + " /mcl_core_leaves_birch.png " )
colorize_alpha ( FOLIAG , tex_dir + " /block/jungle_leaves.png " , " 16+39 " , str ( PXSIZE ) , target_dir ( " /textures " ) + " /default_jungleleaves.png " )
2017-07-19 22:44:43 +02:00
# Waterlily
2023-12-29 17:40:11 +01:00
colorize_alpha ( FOLIAG , tex_dir + " /block/lily_pad.png " , " 16+39 " , str ( PXSIZE ) , target_dir ( " /textures " ) + " /flowers_waterlily.png " )
2017-07-19 22:44:43 +02:00
# Vines
2023-12-29 17:40:11 +01:00
colorize_alpha ( FOLIAG , tex_dir + " /block/vine.png " , " 16+39 " , str ( PXSIZE ) , target_dir ( " /textures " ) + " /mcl_core_vine.png " )
2017-07-19 22:44:43 +02:00
2017-11-16 03:13:19 +01:00
# Tall grass, fern (inventory images)
2021-11-03 19:57:21 +01:00
pcol = " 50+173 " # Plains grass color
2023-12-28 18:35:51 +01:00
# TODO: TALLGRASS.png does no longer exist
2023-12-29 17:40:11 +01:00
colorize_alpha ( GRASS , tex_dir + " /block/tallgrass.png " , pcol , str ( PXSIZE ) , target_dir ( " /textures " ) + " /mcl_flowers_tallgrass_inv.png " )
colorize_alpha ( GRASS , tex_dir + " /block/fern.png " , pcol , str ( PXSIZE ) , target_dir ( " /textures " ) + " /mcl_flowers_fern_inv.png " )
colorize_alpha ( GRASS , tex_dir + " /block/large_fern_top.png " , pcol , str ( PXSIZE ) , target_dir ( " /textures " ) + " /mcl_flowers_double_plant_fern_inv.png " )
colorize_alpha ( GRASS , tex_dir + " /block/tall_grass_top.png " , pcol , str ( PXSIZE ) , target_dir ( " /textures " ) + " /mcl_flowers_double_plant_grass_inv.png " )
2017-11-16 03:13:19 +01:00
2021-11-03 19:57:21 +01:00
# Convert grass palette: https://minecraft.fandom.com/wiki/Tint
grass_colors = [
# [Coords or #Color, AdditionalTint], # Index - Minecraft biome name (MineClone2 biome names)
[ " 50+173 " ] , # 0 - Plains (flat, Plains, Plains_beach, Plains_ocean, End)
[ " 0+255 " ] , # 1 - Savanna (Savanna, Savanna_beach, Savanna_ocean)
[ " 255+255 " ] , # 2 - Ice Spikes (IcePlainsSpikes, IcePlainsSpikes_ocean)
[ " 255+255 " ] , # 3 - Snowy Taiga (ColdTaiga, ColdTaiga_beach, ColdTaiga_beach_water, ColdTaiga_ocean)
[ " 178+193 " ] , # 4 - Giant Tree Taiga (MegaTaiga, MegaTaiga_ocean)
[ " 178+193 " ] , # 5 - Giant Tree Taiga (MegaSpruceTaiga, MegaSpruceTaiga_ocean)
[ " 203+239 " ] , # 6 - Montains (ExtremeHills, ExtremeHills_beach, ExtremeHills_ocean)
[ " 203+239 " ] , # 7 - Montains (ExtremeHillsM, ExtremeHillsM_ocean)
[ " 203+239 " ] , # 8 - Montains (ExtremeHills+, ExtremeHills+_snowtop, ExtremeHills+_ocean)
[ " 50+173 " ] , # 9 - Beach (StoneBeach, StoneBeach_ocean)
[ " 255+255 " ] , # 10 - Snowy Tundra (IcePlains, IcePlains_ocean)
[ " 50+173 " ] , # 11 - Sunflower Plains (SunflowerPlains, SunflowerPlains_ocean)
[ " 191+203 " ] , # 12 - Taiga (Taiga, Taiga_beach, Taiga_ocean)
[ " 76+112 " ] , # 13 - Forest (Forest, Forest_beach, Forest_ocean)
[ " 76+112 " ] , # 14 - Flower Forest (FlowerForest, FlowerForest_beach, FlowerForest_ocean)
[ " 101+163 " ] , # 15 - Birch Forest (BirchForest, BirchForest_ocean)
[ " 101+163 " ] , # 16 - Birch Forest Hills (BirchForestM, BirchForestM_ocean)
[ " 0+255 " ] , # 17 - Desert and Nether (Desert, Desert_ocean, Nether)
[ " 76+112 " , " #28340A " ] , # 18 - Dark Forest (RoofedForest, RoofedForest_ocean)
[ " #90814d " ] , # 19 - Mesa (Mesa, Mesa_sandlevel, Mesa_ocean, )
[ " #90814d " ] , # 20 - Mesa (MesaBryce, MesaBryce_sandlevel, MesaBryce_ocean)
[ " #90814d " ] , # 21 - Mesa (MesaPlateauF, MesaPlateauF_grasstop, MesaPlateauF_sandlevel, MesaPlateauF_ocean)
[ " #90814d " ] , # 22 - Mesa (MesaPlateauFM, MesaPlateauFM_grasstop, MesaPlateauFM_sandlevel, MesaPlateauFM_ocean)
[ " 0+255 " ] , # 23 - Shattered Savanna (or Savanna Plateau ?) (SavannaM, SavannaM_ocean)
[ " 12+36 " ] , # 24 - Jungle (Jungle, Jungle_shore, Jungle_ocean)
[ " 12+36 " ] , # 25 - Modified Jungle (JungleM, JungleM_shore, JungleM_ocean)
[ " 12+61 " ] , # 26 - Jungle Edge (JungleEdge, JungleEdge_ocean)
[ " 12+61 " ] , # 27 - Modified Jungle Edge (JungleEdgeM, JungleEdgeM_ocean)
[ " #6A7039 " ] , # 28 - Swamp (Swampland, Swampland_shore, Swampland_ocean)
[ " 25+25 " ] , # 29 - Mushroom Fields and Mushroom Field Shore (MushroomIsland, MushroomIslandShore, MushroomIsland_ocean)
2017-11-14 23:44:53 +01:00
]
2021-11-03 19:57:21 +01:00
2023-12-29 17:40:11 +01:00
grass_palette_file = target_dir ( " /textures " ) + " /mcl_core_palette_grass.png "
2021-11-03 19:57:21 +01:00
os . system ( " convert -size 16x16 canvas:transparent " + grass_palette_file )
for i , color in enumerate ( grass_colors ) :
if color [ 0 ] [ 0 ] == " # " :
os . system ( " convert -size 1x1 xc: \" " + color [ 0 ] + " \" " + tempfile1 . name + " .png " )
else :
os . system ( " convert " + GRASS + " -crop 1x1+ " + color [ 0 ] + " " + tempfile1 . name + " .png " )
if len ( color ) > 1 :
os . system ( " convert " + tempfile1 . name + " .png \\ ( -size 1x1 xc: \" " + color [ 1 ] + " \" \\ ) -compose blend -define compose:args=50,50 -composite " + tempfile1 . name + " .png " )
os . system ( " convert " + grass_palette_file + " \\ ( " + tempfile1 . name + " .png -geometry + " + str ( i % 16 ) + " + " + str ( int ( i / 16 ) ) + " \\ ) -composite " + grass_palette_file )
2017-11-14 23:44:53 +01:00
2019-02-07 22:22:07 +01:00
# Metadata
if make_texture_pack :
# Create description file
description = " Texture pack for MineClone 2. Automatically converted from a Minecraft resource pack by the MineClone 2 Texture Converter. Size: " + str ( PXSIZE ) + " × " + str ( PXSIZE )
description_file = open ( target_dir ( " / " ) + " /description.txt " , " w " )
description_file . write ( description )
description_file . close ( )
# Create preview image (screenshot.png)
os . system ( " convert -size 300x200 canvas:transparent " + target_dir ( " / " ) + " /screenshot.png " )
os . system ( " composite " + base_dir + " /pack.png " + target_dir ( " / " ) + " /screenshot.png -gravity center " + target_dir ( " / " ) + " /screenshot.png " )
2017-11-14 23:44:53 +01:00
2017-07-28 14:29:15 +02:00
print ( " Textures conversion COMPLETE! " )
2017-07-28 14:36:50 +02:00
if failed_conversions > 0 :
2017-07-28 14:41:02 +02:00
print ( " WARNING: Number of missing files in original resource pack: " + str ( failed_conversions ) )
print ( " NOTE: Please keep in mind this script does not reliably convert all the textures yet. " )
2017-07-28 14:29:15 +02:00
if make_texture_pack :
2017-11-18 02:33:43 +01:00
print ( " You can now retrieve the texture pack in " + output_dir + " / " + output_dir_name + " / " )
2017-07-19 22:44:43 +02:00
2017-07-28 14:20:50 +02:00
# ENTRY POINT
2017-11-18 02:33:43 +01:00
if make_texture_pack and not os . path . isdir ( output_dir + " / " + output_dir_name ) :
os . mkdir ( output_dir + " / " + output_dir_name )
2017-07-28 14:20:50 +02:00
tempfile1 = tempfile . NamedTemporaryFile ( )
tempfile2 = tempfile . NamedTemporaryFile ( )
2017-07-19 22:44:43 +02:00
convert_textures ( )
2017-07-28 14:20:50 +02:00
tempfile1 . close ( )
tempfile2 . close ( )