Remplissage du dépôt
This commit is contained in:
commit
3ba9c542bb
6
.hg_archival.txt
Normal file
6
.hg_archival.txt
Normal file
@ -0,0 +1,6 @@
|
||||
repo: 09eecdf0f6536402038ec3167b37def72e380b40
|
||||
node: 9957de6f53674924478b884100a42b8dec833532
|
||||
branch: default
|
||||
latesttag: null
|
||||
latesttagdistance: 29
|
||||
changessincelatesttag: 29
|
21
LICENSE
Normal file
21
LICENSE
Normal file
@ -0,0 +1,21 @@
|
||||
The MIT License (MIT)
|
||||
|
||||
Copyright (c) 2015 Sascha L. Teichmann
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
54
README.md
Normal file
54
README.md
Normal file
@ -0,0 +1,54 @@
|
||||
# MTAutocolors
|
||||
|
||||
A tool to generate a colors.txt from the registered nodes of a Minetest server.
|
||||
To have a colors.txt for Minetest mapping for example with [MTSatellite](https://bitbucket.org/s_l_teichmann/mtsatellite)
|
||||
you need a colors.txt file. You can grab one from [VanessaE](http://digitalaudioconcepts.com/vanessa/hobbies/minetest/colors.txt)
|
||||
or build one yourself.
|
||||
|
||||
gravgun wrote the generator [automappercolors](https://github.com/MinetestForFun/minetest-minetestforfun-server/tree/master/mods/automappercolors).
|
||||
MTAutocolors is a slightly extended version of this generator being much faster, too (The image processor
|
||||
is written in Go instead of Python). It consists of two parts:
|
||||
|
||||
1. The included [mod](https://bitbucket.org/s_l_teichmann/mtautocolors/src/default/mods/automappercolors/) to be installed into your minetest
|
||||
server to extract the needed node informations.
|
||||
|
||||
2. The program `mtautocolors` to generate the final colors.txt file from the
|
||||
informations gathered by the mod.
|
||||
|
||||
## Build
|
||||
|
||||
Your need a [Go](http://golang.org/) 1.8 or later [installation](https://golang.org/dl/) to compile the program.
|
||||
Go 1.9.2+ is recommended as there is a known issue with decoding images in earlier versions.
|
||||
Mercurial and Git have to be install installed.
|
||||
|
||||
$ go get -u bitbucket.org/s_l_teichmann/mtautocolors/cmd/mtautocolors
|
||||
|
||||
will result in a binary `mtautocolors` to be put into your PATH.
|
||||
|
||||
## Usage
|
||||
|
||||
Install the [mod](https://bitbucket.org/s_l_teichmann/mtautocolors/src/default/mods/automappercolors/) into your
|
||||
Minetest server. Start your game. Now you can type `/amcdumpnodes` as a chat command in the Minetest client. This
|
||||
will result in a file `amc_nodes.txt` in the data directory of your world. Once created you can deactivate the
|
||||
mod until you install or remove mods or update the game in a way which changes the registered nodes.
|
||||
`mtautocolors` needs a few arguments. The path to the `amc_nodes.txt` file generated with the mod and
|
||||
paths to the images of your minetest server. This would be the root of the minetest server and/or the folder
|
||||
where you have the actual minetest game. Something like this (adjusted to your setting):
|
||||
|
||||
$ mtautocolors -predefined=/predefined.json \
|
||||
/home/xyz/minetest/worlds/colors/amc_nodes.txt \
|
||||
/home/xyz/minetest/ /home/xyz/minetest_game > colors.txt
|
||||
|
||||
There is an option to overwrite the machine generated behavior for certain kinds
|
||||
of nodes with a JSON file. Look at [predefined.json](https://bitbucket.org/s_l_teichmann/mtautocolors/src/default/predefined.json)
|
||||
to get the idea. Basically its a list of entries with a regular expression matching the node name
|
||||
and a tuple of RGBA values which should be used instead of the machine generated.
|
||||
|
||||
Transparency: Some nodes should be transparent like glass or water. `mtautocolors` only generates
|
||||
a alpha channel for nodes with of certain draw types. By default this are the ones which drawtype contains 'glasslike' or 'liquid'.
|
||||
This can be overwritten with the `-transparent=` flag.
|
||||
|
||||
This is Free Software under the terms of the MIT license. See [LICENSE](https://bitbucket.org/s_l_teichmann/mtautocolors/src/default/LICENSE)
|
||||
for details.
|
||||
gravgun's original is covered by the WTFPL license. See [LICENSE](https://bitbucket.org/s_l_teichmann/mtautocolors/src/default/mods/automappercolors/LICENSE)
|
||||
for details, too.
|
87
cmd/mtautocolors/images.go
Normal file
87
cmd/mtautocolors/images.go
Normal file
@ -0,0 +1,87 @@
|
||||
// Copyright 2015 by Sascha L. Teichmann
|
||||
// Use of this source code is governed by the MIT license
|
||||
// that can be found in the LICENSE file.
|
||||
|
||||
package main
|
||||
|
||||
import (
|
||||
"bufio"
|
||||
"fmt"
|
||||
"image"
|
||||
"image/color"
|
||||
"image/draw"
|
||||
"os"
|
||||
|
||||
_ "image/jpeg"
|
||||
_ "image/png"
|
||||
)
|
||||
|
||||
func loadRGBA(filename string) (*image.RGBA, error) {
|
||||
|
||||
file, err := os.Open(filename)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer file.Close()
|
||||
|
||||
var img image.Image
|
||||
if img, _, err = image.Decode(bufio.NewReader(file)); err != nil {
|
||||
return nil, fmt.Errorf("Decoding '%s' failed: %s", filename, err)
|
||||
}
|
||||
|
||||
if rgba, ok := img.(*image.RGBA); ok {
|
||||
return rgba, nil
|
||||
}
|
||||
bounds := img.Bounds()
|
||||
rgba := image.NewRGBA(bounds)
|
||||
draw.Draw(rgba, bounds, img, image.ZP, draw.Src)
|
||||
|
||||
return rgba, nil
|
||||
}
|
||||
|
||||
func averageColor(filename string) (color.Color, error) {
|
||||
|
||||
img, err := loadRGBA(filename)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
bounds := img.Bounds()
|
||||
if bounds.Empty() {
|
||||
return color.Black, nil
|
||||
}
|
||||
y := img.PixOffset(bounds.Min.X, bounds.Min.Y)
|
||||
yEnd := img.PixOffset(bounds.Min.X, bounds.Max.Y)
|
||||
w := bounds.Dx() * 4
|
||||
pix := img.Pix
|
||||
|
||||
var r, g, b, a uint64
|
||||
|
||||
for ; y < yEnd; y += img.Stride {
|
||||
for pos, end := y, y+w; pos < end; pos += 4 {
|
||||
pa := uint64(pix[pos+3])
|
||||
r += pa * uint64(pix[pos])
|
||||
g += pa * uint64(pix[pos+1])
|
||||
b += pa * uint64(pix[pos+2])
|
||||
a += pa
|
||||
}
|
||||
}
|
||||
|
||||
r /= 255
|
||||
g /= 255
|
||||
b /= 255
|
||||
|
||||
if s := a / 255; s > 0 {
|
||||
r /= s
|
||||
g /= s
|
||||
b /= s
|
||||
}
|
||||
|
||||
col := color.RGBA{
|
||||
R: uint8(r),
|
||||
G: uint8(g),
|
||||
B: uint8(b),
|
||||
A: uint8(a / uint64(bounds.Dx()*bounds.Dy()))}
|
||||
|
||||
return &col, nil
|
||||
}
|
237
cmd/mtautocolors/main.go
Normal file
237
cmd/mtautocolors/main.go
Normal file
@ -0,0 +1,237 @@
|
||||
// Copyright 2015 by Sascha L. Teichmann
|
||||
// Use of this source code is governed by the MIT license
|
||||
// that can be found in the LICENSE file.
|
||||
|
||||
package main
|
||||
|
||||
import (
|
||||
"bufio"
|
||||
"flag"
|
||||
"fmt"
|
||||
"image/color"
|
||||
"io"
|
||||
"log"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"regexp"
|
||||
"runtime"
|
||||
"sort"
|
||||
"strings"
|
||||
"sync"
|
||||
)
|
||||
|
||||
var nodesSplit = regexp.MustCompile(" +")
|
||||
|
||||
func usage() {
|
||||
fmt.Fprintf(os.Stderr,
|
||||
"Usage: %s [<options>] <nodes.txt> [<data source directory> ...]\n",
|
||||
os.Args[0])
|
||||
fmt.Fprintln(os.Stderr, "Options:")
|
||||
flag.PrintDefaults()
|
||||
}
|
||||
|
||||
func main() {
|
||||
var predef string
|
||||
var transparent string
|
||||
var workers int
|
||||
|
||||
flag.Usage = usage
|
||||
flag.StringVar(&predef, "predefined", "", "predefined colors")
|
||||
flag.StringVar(&predef, "p", "", "predefined colors (shorthand)")
|
||||
flag.StringVar(&transparent, "transparent", "glasslike,liquid", "transparent nodes")
|
||||
flag.StringVar(&transparent, "t", "glasslike,liquid", "transparent nodes (shorthand)")
|
||||
flag.IntVar(&workers, "workers", 0, "number of image processing workers")
|
||||
flag.IntVar(&workers, "w", 0, "number of image processing workers (shorthand)")
|
||||
flag.Parse()
|
||||
|
||||
nargs := flag.NArg()
|
||||
if nargs < 1 {
|
||||
usage()
|
||||
os.Exit(1)
|
||||
}
|
||||
|
||||
var err error
|
||||
var predefs PredefCols
|
||||
|
||||
if predef != "" {
|
||||
if predefs, err = LoadPredefCols(predef); err != nil {
|
||||
log.Fatalf("Cannot load predefined colors: %s\n", err)
|
||||
}
|
||||
}
|
||||
|
||||
var roots []string
|
||||
if nargs > 1 {
|
||||
roots = flag.Args()[1:]
|
||||
} else {
|
||||
roots = []string{"."}
|
||||
}
|
||||
|
||||
files, err := buildFileIndex(roots)
|
||||
if err != nil {
|
||||
log.Fatalf("error while building file index: %s\n", err)
|
||||
}
|
||||
|
||||
drawTypes := strings.Split(transparent, ",")
|
||||
|
||||
if err = process(flag.Arg(0), drawTypes, files, predefs, workers); err != nil {
|
||||
log.Fatalf("error while generating colors: %s\n", err)
|
||||
}
|
||||
}
|
||||
|
||||
func contains(haystack []string, needle string) bool {
|
||||
for _, straw := range haystack {
|
||||
if strings.Contains(needle, straw) {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
type outLine struct {
|
||||
name string
|
||||
col color.Color
|
||||
alpha bool
|
||||
}
|
||||
|
||||
func asByte(x uint32) byte {
|
||||
return byte(x >> 8)
|
||||
}
|
||||
|
||||
func (ol *outLine) print(out io.Writer) {
|
||||
r, g, b, a := ol.col.RGBA()
|
||||
ba := asByte(a)
|
||||
if ol.alpha && ba < 255 {
|
||||
fmt.Fprintf(out, "%s %d %d %d %d\n",
|
||||
ol.name, asByte(r), asByte(g), asByte(b), ba)
|
||||
} else {
|
||||
fmt.Fprintf(out, "%s %d %d %d\n",
|
||||
ol.name, asByte(r), asByte(g), asByte(b))
|
||||
}
|
||||
}
|
||||
|
||||
func process(
|
||||
nodesFile string,
|
||||
drawTypes []string,
|
||||
files map[string]string,
|
||||
predefs PredefCols,
|
||||
workers int) error {
|
||||
|
||||
file, err := os.Open(nodesFile)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer file.Close()
|
||||
|
||||
lineCh := make(chan []string)
|
||||
|
||||
if workers < 1 {
|
||||
workers = runtime.NumCPU()
|
||||
}
|
||||
|
||||
var outLineMu sync.Mutex
|
||||
var outLines []outLine
|
||||
|
||||
var wg sync.WaitGroup
|
||||
|
||||
for i := 0; i < workers; i++ {
|
||||
wg.Add(1)
|
||||
go func() {
|
||||
defer wg.Done()
|
||||
lines:
|
||||
for line := range lineCh {
|
||||
name, drawType, texture := line[0], line[1], line[2]
|
||||
|
||||
var c color.Color
|
||||
switch col := predefs.findCol(name); {
|
||||
case col != nil && col.Complete():
|
||||
c = col
|
||||
case col == nil || !col.Complete():
|
||||
tfile := files[texture]
|
||||
if tfile == "" {
|
||||
log.Printf("WARN: node '%s' missing texture '%s'\n", name, texture)
|
||||
continue lines
|
||||
}
|
||||
avg, err := averageColor(tfile)
|
||||
if err != nil {
|
||||
log.Printf("WARN: node '%s' defect image: %s\n", name, err)
|
||||
continue lines
|
||||
}
|
||||
if col != nil {
|
||||
c = col.Apply(avg)
|
||||
} else {
|
||||
c = avg
|
||||
}
|
||||
}
|
||||
alpha := contains(drawTypes, drawType)
|
||||
outLineMu.Lock()
|
||||
outLines = append(outLines, outLine{
|
||||
name: name,
|
||||
col: c,
|
||||
alpha: alpha,
|
||||
})
|
||||
outLineMu.Unlock()
|
||||
}
|
||||
}()
|
||||
}
|
||||
|
||||
scanner := bufio.NewScanner(file)
|
||||
for lineNo := 1; scanner.Scan(); lineNo++ {
|
||||
parts := nodesSplit.Split(scanner.Text(), 3)
|
||||
if len(parts) < 3 {
|
||||
log.Printf("WARN: line %d too short.\n", lineNo)
|
||||
} else {
|
||||
lineCh <- parts
|
||||
}
|
||||
}
|
||||
close(lineCh)
|
||||
wg.Wait()
|
||||
if err := scanner.Err(); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// To make it more deterministic.
|
||||
sort.Slice(outLines, func(i, j int) bool {
|
||||
return outLines[i].name < outLines[j].name
|
||||
})
|
||||
|
||||
out := bufio.NewWriter(os.Stdout)
|
||||
for i := range outLines {
|
||||
outLines[i].print(out)
|
||||
}
|
||||
return out.Flush()
|
||||
}
|
||||
|
||||
func buildFileIndex(roots []string) (map[string]string, error) {
|
||||
index := make(map[string]string)
|
||||
|
||||
acceptedExts := map[string]bool{
|
||||
".png": true,
|
||||
".jpg": true,
|
||||
".jpeg": true}
|
||||
|
||||
walkFn := func(path string, info os.FileInfo, err error) error {
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if !info.Mode().IsRegular() {
|
||||
return nil
|
||||
}
|
||||
name := info.Name()
|
||||
if !acceptedExts[strings.ToLower(filepath.Ext(name))] {
|
||||
return nil
|
||||
}
|
||||
if _, found := index[name]; !found {
|
||||
index[name] = path
|
||||
} else {
|
||||
log.Printf("WARN: more than one file for '%s'\n", name)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
for _, root := range roots {
|
||||
if err := filepath.Walk(root, walkFn); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
return index, nil
|
||||
}
|
116
cmd/mtautocolors/predefined.go
Normal file
116
cmd/mtautocolors/predefined.go
Normal file
@ -0,0 +1,116 @@
|
||||
// Copyright 2015 by Sascha L. Teichmann
|
||||
// Use of this source code is governed by the MIT license
|
||||
// that can be found in the LICENSE file.
|
||||
|
||||
package main
|
||||
|
||||
import (
|
||||
"bufio"
|
||||
"encoding/json"
|
||||
"image/color"
|
||||
"os"
|
||||
"regexp"
|
||||
"strconv"
|
||||
)
|
||||
|
||||
type Component struct {
|
||||
Value uint8
|
||||
Used bool
|
||||
}
|
||||
|
||||
type Expr struct{ *regexp.Regexp }
|
||||
|
||||
type Col struct {
|
||||
E Expr `json:"expr"`
|
||||
R Component `json:"r"`
|
||||
G Component `json:"g"`
|
||||
B Component `json:"b"`
|
||||
A Component `json:"a"`
|
||||
}
|
||||
|
||||
type PredefCols []Col
|
||||
|
||||
func (e *Expr) UnmarshalJSON(data []byte) error {
|
||||
unquoted := string(data[1 : len(data)-1])
|
||||
expr, err := regexp.Compile(unquoted)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
*e = Expr{expr}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (c *Component) UnmarshalJSON(data []byte) error {
|
||||
v, err := strconv.ParseUint(string(data), 10, 8)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
c.Value = uint8(v)
|
||||
c.Used = true
|
||||
return nil
|
||||
}
|
||||
|
||||
func LoadPredefCols(filename string) (PredefCols, error) {
|
||||
|
||||
file, err := os.Open(filename)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer file.Close()
|
||||
|
||||
decoder := json.NewDecoder(bufio.NewReader(file))
|
||||
|
||||
var predef PredefCols
|
||||
if err = decoder.Decode(&predef); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return predef, nil
|
||||
}
|
||||
|
||||
func (pd *PredefCols) findCol(name string) *Col {
|
||||
for i, n := 0, len(*pd); i < n; i++ {
|
||||
if (*pd)[i].E.MatchString(name) {
|
||||
return &(*pd)[i]
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (c *Col) Complete() bool {
|
||||
return c.R.Used && c.G.Used && c.B.Used && c.A.Used
|
||||
}
|
||||
|
||||
func (c *Col) RGBA() (r, g, b, a uint32) {
|
||||
r = uint32(c.R.Value)
|
||||
r |= r << 8
|
||||
g = uint32(c.G.Value)
|
||||
g |= g << 8
|
||||
b = uint32(c.B.Value)
|
||||
b |= b << 8
|
||||
a = uint32(c.A.Value)
|
||||
a |= a << 8
|
||||
return
|
||||
}
|
||||
|
||||
func (c *Col) Apply(other color.Color) color.Color {
|
||||
r, g, b, a := other.RGBA()
|
||||
x := color.RGBA{
|
||||
R: uint8(r >> 8),
|
||||
G: uint8(g >> 8),
|
||||
B: uint8(b >> 8),
|
||||
A: uint8(a >> 8)}
|
||||
if c.R.Used {
|
||||
x.R = c.R.Value
|
||||
}
|
||||
if c.G.Used {
|
||||
x.G = c.G.Value
|
||||
}
|
||||
if c.B.Used {
|
||||
x.B = c.B.Value
|
||||
}
|
||||
if c.A.Used {
|
||||
x.A = c.A.Value
|
||||
}
|
||||
return &x
|
||||
}
|
16
maps_mt_sha_bang_de_predefined.json
Normal file
16
maps_mt_sha_bang_de_predefined.json
Normal file
@ -0,0 +1,16 @@
|
||||
[
|
||||
{ "expr": "^default:(river_water_.+|water.+)", "a": 128},
|
||||
{ "expr": "^default:glass", "a": 128},
|
||||
{ "expr": "^pumpkin_face_light", "r": 255, "g": 255, "b": 36, "a": 255},
|
||||
{ "expr": "^default:torch", "r": 255, "g": 255, "b": 0, "a": 255},
|
||||
{ "expr": "^farming:cotton_(6|7|8)", "r": 255, "g": 255, "b": 255},
|
||||
{ "expr": "^default:junglewood", "r": 79, "g": 57, "b": 26, "a": 255},
|
||||
{ "expr": "^default:(desertstone|desert_stone)", "r": 149, "g": 99, "b": 80, "a": 255},
|
||||
{ "expr": "^pipeworks:tube_.+", "r": 190, "g": 190, "b": 190, "a": 255},
|
||||
{ "expr": "^pipeworks:(priority|crossing|detector)_tube_.+", "r": 190, "g": 190, "b": 190, "a": 255},
|
||||
{ "expr": "^tnt:gunpowder_burning$", "r": 122, "g": 59, "b": 1, "a": 255},
|
||||
{ "expr": "^tnt:gunpowder$", "r": 0, "g": 0, "b": 0 , "a": 255},
|
||||
{ "expr": "^default:nyancat_rainbow$", "r": 102, "g": 50, "b": 255, "a": 255},
|
||||
{ "expr": "^default:nyancat$", "r": 255, "g": 153, "b": 255, "a": 255 },
|
||||
{ "expr": "^default:mossycobble", "r": 75, "g": 100, "b": 71, "a": 255 }
|
||||
]
|
13
mods/automappercolors/LICENSE
Normal file
13
mods/automappercolors/LICENSE
Normal file
@ -0,0 +1,13 @@
|
||||
DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE
|
||||
Version 2, December 2004
|
||||
|
||||
Copyright (C) 2015 gravgun
|
||||
14 rue de Plaisance, 75014 Paris, France
|
||||
Everyone is permitted to copy and distribute verbatim or modified
|
||||
copies of this license document, and changing it is allowed as long
|
||||
as the name is changed.
|
||||
|
||||
DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE
|
||||
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
|
||||
|
||||
0. You just DO WHAT THE FUCK YOU WANT TO.
|
50
mods/automappercolors/init.lua
Normal file
50
mods/automappercolors/init.lua
Normal file
@ -0,0 +1,50 @@
|
||||
-- Automappercolors by gravgun, modified by s-l-teichmann
|
||||
-- WTFPL
|
||||
|
||||
function amc_dumpnodes()
|
||||
local fd, err = io.open(minetest.get_worldpath()..'/amc_nodes.txt', 'wb')
|
||||
if not fd then
|
||||
return 0, err
|
||||
end
|
||||
local n = 0
|
||||
for name, def in pairs(minetest.registered_nodes) do
|
||||
if def.drawtype ~= 'airlike' then
|
||||
local tile = def.tiles or def.tile_images
|
||||
if type(tile) == 'table' then
|
||||
tile = tile[1]
|
||||
if type(tile) == 'table' then
|
||||
tile = tile.name
|
||||
end
|
||||
end
|
||||
if tile ~= nil then
|
||||
tile = (tile .. '^'):match('([a-zA-Z0-9\\._-]-)^')
|
||||
fd:write(name .. ' ' .. def.drawtype .. ' ' .. tile .. '\n')
|
||||
n = n + 1
|
||||
end
|
||||
end
|
||||
end
|
||||
fd:close()
|
||||
return n, "done"
|
||||
end
|
||||
|
||||
minetest.register_chatcommand("amcdumpnodes", {
|
||||
params = "",
|
||||
description = "",
|
||||
func = function(plname, param)
|
||||
local n, msg = amc_dumpnodes()
|
||||
if n == 0 then
|
||||
minetest.chat_send_player(plname, 'io.open: ' .. msg)
|
||||
else
|
||||
minetest.chat_send_player(plname, n .. " nodes dumped.")
|
||||
end
|
||||
end,
|
||||
})
|
||||
|
||||
minetest.after(1, function(args)
|
||||
amc_dumpnodes()
|
||||
if minetest.setting_getbool("log_mods") then
|
||||
minetest.log("action", "[automappercolors] nodes dumped")
|
||||
end
|
||||
end)
|
||||
|
||||
|
106
predefined.json
Normal file
106
predefined.json
Normal file
@ -0,0 +1,106 @@
|
||||
[
|
||||
{
|
||||
"expr": "^default:([a-z_]*)glass",
|
||||
"a": 64
|
||||
},
|
||||
{
|
||||
"expr": "^default:torch",
|
||||
"r": 255,
|
||||
"g": 255,
|
||||
"b": 0,
|
||||
"a": 255
|
||||
},
|
||||
{
|
||||
"expr": "^default:ice",
|
||||
"r": 74,
|
||||
"g": 105,
|
||||
"b": 159,
|
||||
"a": 159
|
||||
},
|
||||
{
|
||||
"expr": "^default:water_([a-z]+)",
|
||||
"r": 43,
|
||||
"g": 97,
|
||||
"b": 183,
|
||||
"a": 128
|
||||
},
|
||||
{
|
||||
"expr": "^default:dirt_with_grass",
|
||||
"r": 107,
|
||||
"g": 134,
|
||||
"b": 51,
|
||||
"a": 255
|
||||
},
|
||||
{
|
||||
"expr": "^flowers:cotton_plant",
|
||||
"r": 199,
|
||||
"g": 218,
|
||||
"b": 158
|
||||
},
|
||||
{
|
||||
"expr": "^flowers:seaweed",
|
||||
"r": 48,
|
||||
"g": 114,
|
||||
"b": 107
|
||||
},
|
||||
{
|
||||
"expr": "^flowers:waterlily",
|
||||
"r": 119,
|
||||
"g": 166,
|
||||
"b": 100
|
||||
},
|
||||
{
|
||||
"expr": "^flowers:waterlily_225",
|
||||
"r": 119,
|
||||
"g": 166,
|
||||
"b": 100
|
||||
},
|
||||
{
|
||||
"expr": "^flowers:waterlily_45",
|
||||
"r": 119,
|
||||
"g": 166,
|
||||
"b": 100
|
||||
},
|
||||
{
|
||||
"expr": "^flowers:waterlily_675",
|
||||
"r": 119,
|
||||
"g": 166,
|
||||
"b": 100
|
||||
},
|
||||
{
|
||||
"expr": "^flowers:dandelion_white",
|
||||
"r": 161,
|
||||
"g": 174,
|
||||
"b": 149
|
||||
},
|
||||
{
|
||||
"expr": "^flowers:dandelion_yellow",
|
||||
"r": 144,
|
||||
"g": 138,
|
||||
"b": 0
|
||||
},
|
||||
{
|
||||
"expr": "^flowers:geranium",
|
||||
"r": 75,
|
||||
"g": 101,
|
||||
"b": 84
|
||||
},
|
||||
{
|
||||
"expr": "^flowers:rose",
|
||||
"r": 153,
|
||||
"g": 9,
|
||||
"b": 0
|
||||
},
|
||||
{
|
||||
"expr": "^flowers:tulip",
|
||||
"r": 175,
|
||||
"g": 114,
|
||||
"b": 0
|
||||
},
|
||||
{
|
||||
"expr": "^flowers:viola",
|
||||
"r": 84,
|
||||
"g": 90,
|
||||
"b": 64
|
||||
}
|
||||
]
|
Loading…
Reference in New Issue
Block a user