2014-03-14 22:05:35 +01:00
|
|
|
==FILE== mods/dumpnodes/init.lua
|
|
|
|
local function nd_get_tiles(nd)
|
2017-06-06 12:57:00 +02:00
|
|
|
return nd.tiles or nd.tile_images
|
|
|
|
end
|
|
|
|
|
|
|
|
local function nd_get_tile(nd, n)
|
|
|
|
local tile = nd_get_tiles(nd)[n]
|
|
|
|
if type(tile) == 'table' then
|
|
|
|
tile = tile.name
|
2014-03-14 22:05:35 +01:00
|
|
|
end
|
2017-06-06 12:57:00 +02:00
|
|
|
return tile
|
2014-03-14 22:05:35 +01:00
|
|
|
end
|
|
|
|
|
2016-01-14 21:52:15 +01:00
|
|
|
local function pairs_s(dict)
|
|
|
|
local keys = {}
|
|
|
|
for k in pairs(dict) do
|
|
|
|
table.insert(keys, k)
|
|
|
|
end
|
|
|
|
table.sort(keys)
|
|
|
|
return ipairs(keys)
|
|
|
|
end
|
|
|
|
|
2014-03-14 22:05:35 +01:00
|
|
|
minetest.register_chatcommand("dumpnodes", {
|
|
|
|
params = "",
|
|
|
|
description = "",
|
2017-06-06 12:57:00 +02:00
|
|
|
func = function(player, param)
|
2014-03-14 22:05:35 +01:00
|
|
|
local n = 0
|
|
|
|
local ntbl = {}
|
2016-01-14 21:52:15 +01:00
|
|
|
for _, nn in pairs_s(minetest.registered_nodes) do
|
|
|
|
local nd = minetest.registered_nodes[nn]
|
2014-03-14 22:05:35 +01:00
|
|
|
local prefix, name = nn:match('(.*):(.*)')
|
2017-06-06 12:57:00 +02:00
|
|
|
if prefix == nil or name == nil then
|
2016-01-14 21:52:15 +01:00
|
|
|
print("ignored(1): " .. nn)
|
2014-03-14 22:05:35 +01:00
|
|
|
else
|
|
|
|
if ntbl[prefix] == nil then
|
|
|
|
ntbl[prefix] = {}
|
|
|
|
end
|
2017-06-06 12:57:00 +02:00
|
|
|
ntbl[prefix][name] = true
|
2014-03-14 22:05:35 +01:00
|
|
|
end
|
|
|
|
end
|
|
|
|
local out, err = io.open('nodes.txt', 'wb')
|
|
|
|
if not out then
|
2016-01-14 21:52:15 +01:00
|
|
|
return true, "io.open(): " .. err
|
2014-03-14 22:05:35 +01:00
|
|
|
end
|
2016-01-14 21:52:15 +01:00
|
|
|
for _, prefix in pairs_s(ntbl) do
|
2014-03-14 22:05:35 +01:00
|
|
|
out:write('# ' .. prefix .. '\n')
|
2017-06-06 12:57:00 +02:00
|
|
|
for _, name in pairs_s(ntbl[prefix]) do
|
|
|
|
local nn = prefix .. ":" .. name
|
|
|
|
local nd = minetest.registered_nodes[nn]
|
|
|
|
if nd.drawtype == 'airlike' or nd_get_tiles(nd) == nil then
|
|
|
|
print("ignored(2): " .. nn)
|
2016-01-14 21:52:15 +01:00
|
|
|
else
|
2017-06-06 12:57:00 +02:00
|
|
|
local tl = nd_get_tile(nd, 1)
|
|
|
|
tl = (tl .. '^'):match('(.-)^') -- strip modifiers
|
|
|
|
out:write(nn .. ' ' .. tl .. '\n')
|
|
|
|
n = n + 1
|
2014-03-14 22:05:35 +01:00
|
|
|
end
|
|
|
|
end
|
|
|
|
out:write('\n')
|
|
|
|
end
|
|
|
|
out:close()
|
2016-01-14 21:52:15 +01:00
|
|
|
return true, n .. " nodes dumped."
|
2014-03-14 22:05:35 +01:00
|
|
|
end,
|
|
|
|
})
|
|
|
|
==FILE== avgcolor.py
|
|
|
|
#!/usr/bin/env python
|
|
|
|
import sys
|
|
|
|
from PIL import Image
|
|
|
|
|
2017-06-06 12:57:00 +02:00
|
|
|
def tadd(a, b):
|
2016-01-14 21:52:15 +01:00
|
|
|
return tuple(sum(e) for e in zip(a, b))
|
2014-03-14 22:05:35 +01:00
|
|
|
|
2016-01-14 21:52:15 +01:00
|
|
|
if len(sys.argv) < 2:
|
|
|
|
print("Prints average color (RGB) of input image")
|
2014-03-14 22:05:35 +01:00
|
|
|
print("Usage: %s <input>" % sys.argv[0])
|
2016-01-14 21:52:15 +01:00
|
|
|
exit(1)
|
|
|
|
|
2017-06-06 12:57:00 +02:00
|
|
|
inp = Image.open(sys.argv[1]).convert('RGBA')
|
2016-01-14 21:52:15 +01:00
|
|
|
ind = inp.load()
|
|
|
|
|
|
|
|
cl = (0, 0, 0)
|
|
|
|
counted = 0
|
|
|
|
for x in range(inp.size[0]):
|
|
|
|
for y in range(inp.size[1]):
|
|
|
|
px = ind[x, y]
|
2017-06-06 12:57:00 +02:00
|
|
|
if px[3] < 128: continue # alpha
|
|
|
|
cl = tadd(cl, px[:3])
|
|
|
|
counted += 1
|
2016-01-14 21:52:15 +01:00
|
|
|
|
|
|
|
if counted == 0:
|
2017-06-06 12:57:00 +02:00
|
|
|
sys.stderr.write("did not find avg color for %s\n" % sys.argv[1])
|
2016-01-14 21:52:15 +01:00
|
|
|
print("0 0 0")
|
2017-06-06 12:57:00 +02:00
|
|
|
else:
|
|
|
|
cl = tuple(int(n / counted) for n in cl)
|
|
|
|
print("%d %d %d" % cl)
|
2016-01-14 21:52:15 +01:00
|
|
|
==SCRIPT==
|
|
|
|
#!/bin/bash -e
|
|
|
|
AVGCOLOR_PATH=/path/to/avgcolor.py
|
2017-06-06 12:57:00 +02:00
|
|
|
GAME_PATH=/path/to/minetest_game
|
|
|
|
MODS_PATH= # path to "mods" folder, only set if you have loaded mods
|
2016-01-14 21:52:15 +01:00
|
|
|
NODESTXT_PATH=./nodes.txt
|
|
|
|
COLORSTXT_PATH=./colors.txt
|
2014-03-14 22:05:35 +01:00
|
|
|
|
2016-10-08 13:31:03 +02:00
|
|
|
while read -r line; do
|
2017-06-06 12:57:00 +02:00
|
|
|
set -- junk $line; shift
|
2016-10-08 13:31:03 +02:00
|
|
|
if [[ -z "$1" || $1 == "#" ]]; then
|
2017-06-06 12:57:00 +02:00
|
|
|
echo "$line"; continue
|
2014-03-14 22:05:35 +01:00
|
|
|
fi
|
2017-06-06 12:57:00 +02:00
|
|
|
tex=$(find $GAME_PATH -type f -name "$2")
|
|
|
|
[[ -z "$tex" && -n "$MODS_PATH" ]] && tex=$(find $MODS_PATH -type f -name "$2")
|
2016-10-08 13:31:03 +02:00
|
|
|
if [ -z "$tex" ]; then
|
|
|
|
echo "skip $1: texture not found" >&2
|
|
|
|
continue
|
|
|
|
fi
|
2017-06-06 12:57:00 +02:00
|
|
|
echo "$1" $(python $AVGCOLOR_PATH "$tex")
|
2016-10-08 13:31:03 +02:00
|
|
|
echo "ok $1" >&2
|
2016-01-14 21:52:15 +01:00
|
|
|
done < $NODESTXT_PATH > $COLORSTXT_PATH
|
|
|
|
# Use nicer colors for water and lava:
|
2016-10-08 13:31:03 +02:00
|
|
|
sed -re 's/^default:((river_)?water_(flowing|source)) [0-9 ]+$/default:\1 39 66 106 128 224/g' $COLORSTXT_PATH -i
|
|
|
|
sed -re 's/^default:(lava_(flowing|source)) [0-9 ]+$/default:\1 255 100 0/g' $COLORSTXT_PATH -i
|
2018-03-25 13:40:19 +02:00
|
|
|
# Add transparency to glass nodes and xpanes:
|
2016-01-15 10:20:05 +01:00
|
|
|
sed -re 's/^default:(.*glass) ([0-9 ]+)$/default:\1 \2 64 16/g' $COLORSTXT_PATH -i
|
|
|
|
sed -re 's/^doors:(.*glass[^ ]*) ([0-9 ]+)$/doors:\1 \2 64 16/g' $COLORSTXT_PATH -i
|
2018-03-25 13:40:19 +02:00
|
|
|
sed -re 's/^xpanes:(.*(pane|bar)[^ ]*) ([0-9 ]+)$/xpanes:\1 \3 64 16/g' $COLORSTXT_PATH -i
|
|
|
|
# Delete some usually hidden nodes:
|
|
|
|
sed '/^doors:hidden /d' $COLORSTXT_PATH -i
|
|
|
|
sed '/^fireflies:firefly /d' $COLORSTXT_PATH -i
|
2019-03-09 15:16:28 +01:00
|
|
|
sed '/^butterflies:butterfly_/d' $COLORSTXT_PATH -i
|
2014-03-14 22:05:35 +01:00
|
|
|
==INSTRUCTIONS==
|
2017-06-06 12:57:00 +02:00
|
|
|
1) Make sure avgcolors.py works (outputs the usage instructions when run)
|
2014-03-14 22:05:35 +01:00
|
|
|
2) Add the dumpnodes mod to Minetest
|
2016-01-15 10:20:05 +01:00
|
|
|
3) Create a world and load dumpnodes & all mods you want to generate colors for
|
2014-03-14 22:05:35 +01:00
|
|
|
4) Execute /dumpnodes ingame
|
2017-06-06 12:57:00 +02:00
|
|
|
5) Run the script to generate colors.txt (make sure to adjust the PATH variables at the top)
|