built on 07/02/2021 14:37:07

This commit is contained in:
Joachim Stolberg 2021-02-07 14:37:07 +01:00
parent b0bb384ac5
commit c28d6858b2
495 changed files with 2276 additions and 1032 deletions

View File

@ -0,0 +1,34 @@
# textdomain: basic_materials
# Author: Salvo 'LtWorf' Tomaselli <tiposchi@tiscali.it>
Silicon lump=Grumo di silicio
Simple Integrated Circuit=Circuito integrato semplice
Simple Motor=Motore semplice
Heating element=Elemento riscaldante
Simple energy crystal=Cristallo di energia semplice
Spool of steel wire=Bobina di filo d'acciaio
Spool of copper wire=Bobina di filo di rame
Spool of silver wire=Bobina di filo d'argento
Spool of gold wire=Bobina di filo d'oro
Steel Strip=Striscia d'acciaio
Copper Strip=Striscia di rame
Steel Bar=Barra d'acciaio
Chainlinks (brass)=Catena (ottone)
Chainlinks (steel)=Catena (acciaio)
Brass Ingot=Lingotto di ottone
Steel gear=Ingranaggio d'acciaio
Padlock=Catenaccio
Chain (steel, hanging)=Catena (acciaio, pendente)
Chain (brass, hanging)=Catena (ottone, pendente)
Brass Block=Blocco di ottone
Oil extract=Estratto d'olio
Unprocessed paraffin=Paraffina grezza
Uncooked Terracotta Base=Argilla cruda
Wet Cement=Cemento umido
Cement=Cemento
Concrete Block=Blocco di calcestruzzo
Plastic sheet=Foglio di plastica
Plastic strips=Striscia di plastica
Empty wire spool=Rocchetto vuoto

View File

@ -2,6 +2,8 @@ local S = minetest.get_translator("compost")
compost = {} compost = {}
local CYCLE_TIME = 10
-- Version for compatibility checks -- Version for compatibility checks
compost.version = 1.0 compost.version = 1.0
@ -74,43 +76,58 @@ end)
local function next_state(pos, elapsed) local function next_state(pos, elapsed)
local node = minetest.get_node(pos) local node = minetest.get_node(pos)
if node.name == "compost:wood_barrel_1" then if node.name == "compost:wood_barrel_1" then
minetest.set_node(pos, {name = "compost:wood_barrel_2"}) minetest.swap_node(pos, {name = "compost:wood_barrel_2"})
return true elseif node.name == "compost:wood_barrel_2" then
end minetest.swap_node(pos, {name = "compost:wood_barrel_3"})
if node.name == "compost:wood_barrel_2" then elseif node.name == "compost:wood_barrel_3" then
minetest.set_node(pos, {name = "compost:wood_barrel_3"})
return false return false
end end
return false return true
end
local function start_composter(pos)
local meta = minetest.get_meta(pos)
local num = meta:get_int("num") or 0
if num >= 4 then
-- 4 leaves for one compost node
meta:set_int("num", num - 4)
minetest.swap_node(pos, {name = "compost:wood_barrel_1"})
minetest.get_node_timer(pos):start(CYCLE_TIME)
end
end
local function add_item(pos, stack)
local meta = minetest.get_meta(pos)
local num = meta:get_int("num") or 0
if num < 4 then
-- add futher leaves
meta:set_int("num", num + stack:get_count())
stack:set_count(0)
end
start_composter(pos)
return stack
end end
local function minecart_hopper_additem(pos, stack) local function minecart_hopper_additem(pos, stack)
if compost.can_compost(stack:get_name()) then if compost.can_compost(stack:get_name()) then
local meta = minetest.get_meta(pos) return add_item(pos, stack)
-- 4 leaves for one compost node
local num = (meta:get_int("num") or 0) + stack:get_count()
if num >= 4 then
num = num - 4
minetest.set_node(pos, {name = "compost:wood_barrel_1"})
-- speed up the process by means of a timer
minetest.get_node_timer(pos):start(10)
end
meta:set_int("num", num)
stack:set_count(0)
return stack
end end
return stack return stack
end end
local function minecart_hopper_takeitem(pos, num) local function minecart_hopper_takeitem(pos, num)
local node = minetest.get_node(pos) local node = minetest.get_node(pos)
minetest.set_node(pos, {name = "compost:wood_barrel"}) minetest.swap_node(pos, {name = "compost:wood_barrel"})
start_composter(pos)
return ItemStack("compost:compost") return ItemStack("compost:compost")
end end
local function minecart_hopper_untakeitem(pos, in_dir, stack) local function minecart_hopper_untakeitem(pos, in_dir, stack)
minetest.set_node(pos, {name = "compost:wood_barrel_2"}) minetest.swap_node(pos, {name = "compost:wood_barrel_2"})
end end
minetest.register_node("compost:wood_barrel", { minetest.register_node("compost:wood_barrel", {
@ -132,14 +149,16 @@ minetest.register_node("compost:wood_barrel", {
on_punch = function(pos, node, puncher, pointed_thing) on_punch = function(pos, node, puncher, pointed_thing)
local wielded_item = puncher:get_wielded_item():get_name() local wielded_item = puncher:get_wielded_item():get_name()
if compost.can_compost(wielded_item) then if compost.can_compost(wielded_item) then
minetest.set_node(pos, {name = "compost:wood_barrel_1"}) minetest.swap_node(pos, {name = "compost:wood_barrel_1"})
local w = puncher:get_wielded_item() local w = puncher:get_wielded_item()
if not(minetest.setting_getbool("creative_mode")) then if not(minetest.setting_getbool("creative_mode")) then
w:take_item(1) w:take_item(1)
puncher:set_wielded_item(w) puncher:set_wielded_item(w)
end end
minetest.get_node_timer(pos):start(CYCLE_TIME)
end end
end, end,
on_timer = next_state,
minecart_hopper_additem = minecart_hopper_additem, minecart_hopper_additem = minecart_hopper_additem,
minecart_hopper_untakeitem = minecart_hopper_untakeitem, minecart_hopper_untakeitem = minecart_hopper_untakeitem,
}) })
@ -206,30 +225,13 @@ minetest.register_node("compost:wood_barrel_3", {
on_punch = function(pos, node, player, pointed_thing) on_punch = function(pos, node, player, pointed_thing)
local p = {x = pos.x + math.random(0, 5)/5 - 0.5, y = pos.y+1, z = pos.z + math.random(0, 5)/5 - 0.5} local p = {x = pos.x + math.random(0, 5)/5 - 0.5, y = pos.y+1, z = pos.z + math.random(0, 5)/5 - 0.5}
minetest.add_item(p, {name = "compost:compost"}) minetest.add_item(p, {name = "compost:compost"})
minetest.set_node(pos, {name = "compost:wood_barrel"}) minetest.swap_node(pos, {name = "compost:wood_barrel"})
end, end,
on_timer = next_state,
minecart_hopper_takeitem = minecart_hopper_takeitem, minecart_hopper_takeitem = minecart_hopper_takeitem,
minecart_hopper_untakeitem = minecart_hopper_untakeitem, minecart_hopper_untakeitem = minecart_hopper_untakeitem,
}) })
minetest.register_abm({
nodenames = {"compost:wood_barrel_1"},
interval = 40,
chance = 5,
action = function(pos, node, active_object_count, active_object_count_wider)
minetest.set_node(pos, {name = "compost:wood_barrel_2"})
end,
})
minetest.register_abm({
nodenames = {"compost:wood_barrel_2"},
interval = 40,
chance = 5,
action = function(pos, node, active_object_count, active_object_count_wider)
minetest.set_node(pos, {name = "compost:wood_barrel_3"})
end,
})
minetest.register_craft({ minetest.register_craft({
output = "compost:wood_barrel", output = "compost:wood_barrel",
recipe = { recipe = {
@ -279,7 +281,8 @@ if minetest.global_exists("techage") then
on_pull_item = function(pos, in_dir, num) on_pull_item = function(pos, in_dir, num)
local node = minetest.get_node(pos) local node = minetest.get_node(pos)
if node.name == "compost:wood_barrel_3" then if node.name == "compost:wood_barrel_3" then
minetest.set_node(pos, {name = "compost:wood_barrel"}) minetest.swap_node(pos, {name = "compost:wood_barrel"})
start_composter(pos)
return ItemStack("compost:compost") return ItemStack("compost:compost")
end end
return nil return nil
@ -287,22 +290,13 @@ if minetest.global_exists("techage") then
on_push_item = function(pos, in_dir, stack) on_push_item = function(pos, in_dir, stack)
local node = minetest.get_node(pos) local node = minetest.get_node(pos)
if node.name == "compost:wood_barrel" and compost.can_compost(stack:get_name()) then if node.name == "compost:wood_barrel" and compost.can_compost(stack:get_name()) then
local meta = minetest.get_meta(pos) stack = add_item(pos, stack)
-- 4 leaves for one compost node return stack:get_count() == 0
local num = (meta:get_int("num") or 0) + 1
if num >= 4 then
num = 0
minetest.set_node(pos, {name = "compost:wood_barrel_1"})
-- speed up the process by means of a timer
minetest.get_node_timer(pos):start(10)
end
meta:set_int("num", num)
return true
end end
return false return false
end, end,
on_unpull_item = function(pos, in_dir, stack) on_unpull_item = function(pos, in_dir, stack)
minetest.set_node(pos, {name = "compost:wood_barrel_2"}) minetest.swap_node(pos, {name = "compost:wood_barrel_2"})
return true return true
end, end,
}) })

View File

@ -368,6 +368,9 @@ local function on_arrival_floor(tDeparture, tArrival, player_name, snd)
if player ~= nil then if player ~= nil then
tArrival.pos.y = tArrival.pos.y - kPLAYER_OVER_GROUND tArrival.pos.y = tArrival.pos.y - kPLAYER_OVER_GROUND
player:set_pos(tArrival.pos) player:set_pos(tArrival.pos)
if tArrival.attributes then
player:set_nametag_attributes(tArrival.attributes)
end
tArrival.pos.y = tArrival.pos.y + kPLAYER_OVER_GROUND tArrival.pos.y = tArrival.pos.y + kPLAYER_OVER_GROUND
end end
minetest.sound_stop(snd) minetest.sound_stop(snd)
@ -375,8 +378,15 @@ local function on_arrival_floor(tDeparture, tArrival, player_name, snd)
end end
local function on_travel(tDeparture, tArrival, player_name, seconds) local function on_travel(tDeparture, tArrival, player_name, seconds)
local player = minetest.get_player_by_name(player_name)
door_command(tDeparture.pos, tDeparture.facedir, "darken", false) door_command(tDeparture.pos, tDeparture.facedir, "darken", false)
door_command(tArrival.pos, tArrival.facedir, "darken", false) door_command(tArrival.pos, tArrival.facedir, "darken", false)
if player ~= nil then
tArrival.attributes = player:get_nametag_attributes()
player:set_nametag_attributes({text = " "})
else
tArrival.attributes = nil
end
local snd = minetest.sound_play("ele_norm", { local snd = minetest.sound_play("ele_norm", {
pos = tDeparture.pos, pos = tDeparture.pos,
gain = 0.5, gain = 0.5,

458
hyperloop/i18n.py Normal file
View File

@ -0,0 +1,458 @@
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
#
# Script to generate the template file and update the translation files.
# Copy the script into the mod or modpack root folder and run it there.
#
# Copyright (C) 2019 Joachim Stolberg, 2020 FaceDeer, 2020 Louis Royer
# LGPLv2.1+
#
# See https://github.com/minetest-tools/update_translations for
# potential future updates to this script.
from __future__ import print_function
import os, fnmatch, re, shutil, errno
from sys import argv as _argv
from sys import stderr as _stderr
# Running params
params = {"recursive": False,
"help": False,
"mods": False,
"verbose": False,
"folders": [],
"no-old-file": False,
"break-long-lines": False,
"sort": False
}
# Available CLI options
options = {"recursive": ['--recursive', '-r'],
"help": ['--help', '-h'],
"mods": ['--installed-mods', '-m'],
"verbose": ['--verbose', '-v'],
"no-old-file": ['--no-old-file', '-O'],
"break-long-lines": ['--break-long-lines', '-b'],
"sort": ['--sort', '-s']
}
# Strings longer than this will have extra space added between
# them in the translation files to make it easier to distinguish their
# beginnings and endings at a glance
doublespace_threshold = 80
def set_params_folders(tab: list):
'''Initialize params["folders"] from CLI arguments.'''
# Discarding argument 0 (tool name)
for param in tab[1:]:
stop_param = False
for option in options:
if param in options[option]:
stop_param = True
break
if not stop_param:
params["folders"].append(os.path.abspath(param))
def set_params(tab: list):
'''Initialize params from CLI arguments.'''
for option in options:
for option_name in options[option]:
if option_name in tab:
params[option] = True
break
def print_help(name):
'''Prints some help message.'''
print(f'''SYNOPSIS
{name} [OPTIONS] [PATHS...]
DESCRIPTION
{', '.join(options["help"])}
prints this help message
{', '.join(options["recursive"])}
run on all subfolders of paths given
{', '.join(options["mods"])}
run on locally installed modules
{', '.join(options["no-old-file"])}
do not create *.old files
{', '.join(options["sort"])}
sort output strings alphabetically
{', '.join(options["break-long-lines"])}
add extra line breaks before and after long strings
{', '.join(options["verbose"])}
add output information
''')
def main():
'''Main function'''
set_params(_argv)
set_params_folders(_argv)
if params["help"]:
print_help(_argv[0])
elif params["recursive"] and params["mods"]:
print("Option --installed-mods is incompatible with --recursive")
else:
# Add recursivity message
print("Running ", end='')
if params["recursive"]:
print("recursively ", end='')
# Running
if params["mods"]:
print(f"on all locally installed modules in {os.path.abspath('~/.minetest/mods/')}")
run_all_subfolders("~/.minetest/mods")
elif len(params["folders"]) >= 2:
print("on folder list:", params["folders"])
for f in params["folders"]:
if params["recursive"]:
run_all_subfolders(f)
else:
update_folder(f)
elif len(params["folders"]) == 1:
print("on folder", params["folders"][0])
if params["recursive"]:
run_all_subfolders(params["folders"][0])
else:
update_folder(params["folders"][0])
else:
print("on folder", os.path.abspath("./"))
if params["recursive"]:
run_all_subfolders(os.path.abspath("./"))
else:
update_folder(os.path.abspath("./"))
#group 2 will be the string, groups 1 and 3 will be the delimiters (" or ')
#See https://stackoverflow.com/questions/46967465/regex-match-text-in-either-single-or-double-quote
pattern_lua_s = re.compile(r'[\.=^\t,{\(\s]N?S\(\s*(["\'])((?:\\\1|(?:(?!\1)).)*)(\1)[\s,\)]', re.DOTALL)
pattern_lua_fs = re.compile(r'[\.=^\t,{\(\s]N?FS\(\s*(["\'])((?:\\\1|(?:(?!\1)).)*)(\1)[\s,\)]', re.DOTALL)
pattern_lua_bracketed_s = re.compile(r'[\.=^\t,{\(\s]N?S\(\s*\[\[(.*?)\]\][\s,\)]', re.DOTALL)
pattern_lua_bracketed_fs = re.compile(r'[\.=^\t,{\(\s]N?FS\(\s*\[\[(.*?)\]\][\s,\)]', re.DOTALL)
# Handles "concatenation" .. " of strings"
pattern_concat = re.compile(r'["\'][\s]*\.\.[\s]*["\']', re.DOTALL)
pattern_tr = re.compile(r'(.*?[^@])=(.*)')
pattern_name = re.compile(r'^name[ ]*=[ ]*([^ \n]*)')
pattern_tr_filename = re.compile(r'\.tr$')
pattern_po_language_code = re.compile(r'(.*)\.po$')
#attempt to read the mod's name from the mod.conf file. Returns None on failure
def get_modname(folder):
try:
with open(os.path.join(folder, "mod.conf"), "r", encoding='utf-8') as mod_conf:
for line in mod_conf:
match = pattern_name.match(line)
if match:
return match.group(1)
except FileNotFoundError:
pass
return None
#If there are already .tr files in /locale, returns a list of their names
def get_existing_tr_files(folder):
out = []
for root, dirs, files in os.walk(os.path.join(folder, 'locale/')):
for name in files:
if pattern_tr_filename.search(name):
out.append(name)
return out
# A series of search and replaces that massage a .po file's contents into
# a .tr file's equivalent
def process_po_file(text):
# The first three items are for unused matches
text = re.sub(r'#~ msgid "', "", text)
text = re.sub(r'"\n#~ msgstr ""\n"', "=", text)
text = re.sub(r'"\n#~ msgstr "', "=", text)
# comment lines
text = re.sub(r'#.*\n', "", text)
# converting msg pairs into "=" pairs
text = re.sub(r'msgid "', "", text)
text = re.sub(r'"\nmsgstr ""\n"', "=", text)
text = re.sub(r'"\nmsgstr "', "=", text)
# various line breaks and escape codes
text = re.sub(r'"\n"', "", text)
text = re.sub(r'"\n', "\n", text)
text = re.sub(r'\\"', '"', text)
text = re.sub(r'\\n', '@n', text)
# remove header text
text = re.sub(r'=Project-Id-Version:.*\n', "", text)
# remove double-spaced lines
text = re.sub(r'\n\n', '\n', text)
return text
# Go through existing .po files and, if a .tr file for that language
# *doesn't* exist, convert it and create it.
# The .tr file that results will subsequently be reprocessed so
# any "no longer used" strings will be preserved.
# Note that "fuzzy" tags will be lost in this process.
def process_po_files(folder, modname):
for root, dirs, files in os.walk(os.path.join(folder, 'locale/')):
for name in files:
code_match = pattern_po_language_code.match(name)
if code_match == None:
continue
language_code = code_match.group(1)
tr_name = modname + "." + language_code + ".tr"
tr_file = os.path.join(root, tr_name)
if os.path.exists(tr_file):
if params["verbose"]:
print(f"{tr_name} already exists, ignoring {name}")
continue
fname = os.path.join(root, name)
with open(fname, "r", encoding='utf-8') as po_file:
if params["verbose"]:
print(f"Importing translations from {name}")
text = process_po_file(po_file.read())
with open(tr_file, "wt", encoding='utf-8') as tr_out:
tr_out.write(text)
# from https://stackoverflow.com/questions/600268/mkdir-p-functionality-in-python/600612#600612
# Creates a directory if it doesn't exist, silently does
# nothing if it already exists
def mkdir_p(path):
try:
os.makedirs(path)
except OSError as exc: # Python >2.5
if exc.errno == errno.EEXIST and os.path.isdir(path):
pass
else: raise
# Converts the template dictionary to a text to be written as a file
# dKeyStrings is a dictionary of localized string to source file sets
# dOld is a dictionary of existing translations and comments from
# the previous version of this text
def strings_to_text(dkeyStrings, dOld, mod_name, header_comments):
lOut = [f"# textdomain: {mod_name}\n"]
if header_comments is not None:
lOut.append(header_comments)
dGroupedBySource = {}
for key in dkeyStrings:
sourceList = list(dkeyStrings[key])
if params["sort"]:
sourceList.sort()
sourceString = "\n".join(sourceList)
listForSource = dGroupedBySource.get(sourceString, [])
listForSource.append(key)
dGroupedBySource[sourceString] = listForSource
lSourceKeys = list(dGroupedBySource.keys())
lSourceKeys.sort()
for source in lSourceKeys:
localizedStrings = dGroupedBySource[source]
if params["sort"]:
localizedStrings.sort()
lOut.append("")
lOut.append(source)
lOut.append("")
for localizedString in localizedStrings:
val = dOld.get(localizedString, {})
translation = val.get("translation", "")
comment = val.get("comment")
if params["break-long-lines"] and len(localizedString) > doublespace_threshold and not lOut[-1] == "":
lOut.append("")
if comment != None:
lOut.append(comment)
lOut.append(f"{localizedString}={translation}")
if params["break-long-lines"] and len(localizedString) > doublespace_threshold:
lOut.append("")
unusedExist = False
for key in dOld:
if key not in dkeyStrings:
val = dOld[key]
translation = val.get("translation")
comment = val.get("comment")
# only keep an unused translation if there was translated
# text or a comment associated with it
if translation != None and (translation != "" or comment):
if not unusedExist:
unusedExist = True
lOut.append("\n\n##### not used anymore #####\n")
if params["break-long-lines"] and len(key) > doublespace_threshold and not lOut[-1] == "":
lOut.append("")
if comment != None:
lOut.append(comment)
lOut.append(f"{key}={translation}")
if params["break-long-lines"] and len(key) > doublespace_threshold:
lOut.append("")
return "\n".join(lOut) + '\n'
# Writes a template.txt file
# dkeyStrings is the dictionary returned by generate_template
def write_template(templ_file, dkeyStrings, mod_name):
# read existing template file to preserve comments
existing_template = import_tr_file(templ_file)
text = strings_to_text(dkeyStrings, existing_template[0], mod_name, existing_template[2])
mkdir_p(os.path.dirname(templ_file))
with open(templ_file, "wt", encoding='utf-8') as template_file:
template_file.write(text)
# Gets all translatable strings from a lua file
def read_lua_file_strings(lua_file):
lOut = []
with open(lua_file, encoding='utf-8') as text_file:
text = text_file.read()
#TODO remove comments here
text = re.sub(pattern_concat, "", text)
strings = []
for s in pattern_lua_s.findall(text):
strings.append(s[1])
for s in pattern_lua_bracketed_s.findall(text):
strings.append(s)
for s in pattern_lua_fs.findall(text):
strings.append(s[1])
for s in pattern_lua_bracketed_fs.findall(text):
strings.append(s)
for s in strings:
s = re.sub(r'"\.\.\s+"', "", s)
s = re.sub("@[^@=0-9]", "@@", s)
s = s.replace('\\"', '"')
s = s.replace("\\'", "'")
s = s.replace("\n", "@n")
s = s.replace("\\n", "@n")
s = s.replace("=", "@=")
lOut.append(s)
return lOut
# Gets strings from an existing translation file
# returns both a dictionary of translations
# and the full original source text so that the new text
# can be compared to it for changes.
# Returns also header comments in the third return value.
def import_tr_file(tr_file):
dOut = {}
text = None
header_comment = None
if os.path.exists(tr_file):
with open(tr_file, "r", encoding='utf-8') as existing_file :
# save the full text to allow for comparison
# of the old version with the new output
text = existing_file.read()
existing_file.seek(0)
# a running record of the current comment block
# we're inside, to allow preceeding multi-line comments
# to be retained for a translation line
latest_comment_block = None
for line in existing_file.readlines():
line = line.rstrip('\n')
if line[:3] == "###":
if header_comment is None:
# Save header comments
header_comment = latest_comment_block
# Stip textdomain line
tmp_h_c = ""
for l in header_comment.split('\n'):
if not l.startswith("# textdomain:"):
tmp_h_c += l + '\n'
header_comment = tmp_h_c
# Reset comment block if we hit a header
latest_comment_block = None
continue
if line[:1] == "#":
# Save the comment we're inside
if not latest_comment_block:
latest_comment_block = line
else:
latest_comment_block = latest_comment_block + "\n" + line
continue
match = pattern_tr.match(line)
if match:
# this line is a translated line
outval = {}
outval["translation"] = match.group(2)
if latest_comment_block:
# if there was a comment, record that.
outval["comment"] = latest_comment_block
latest_comment_block = None
dOut[match.group(1)] = outval
return (dOut, text, header_comment)
# Walks all lua files in the mod folder, collects translatable strings,
# and writes it to a template.txt file
# Returns a dictionary of localized strings to source file sets
# that can be used with the strings_to_text function.
def generate_template(folder, mod_name):
dOut = {}
for root, dirs, files in os.walk(folder):
for name in files:
if fnmatch.fnmatch(name, "*.lua"):
fname = os.path.join(root, name)
found = read_lua_file_strings(fname)
if params["verbose"]:
print(f"{fname}: {str(len(found))} translatable strings")
for s in found:
sources = dOut.get(s, set())
sources.add(f"### {os.path.basename(fname)} ###")
dOut[s] = sources
if len(dOut) == 0:
return None
templ_file = os.path.join(folder, "locale/template.txt")
write_template(templ_file, dOut, mod_name)
return dOut
# Updates an existing .tr file, copying the old one to a ".old" file
# if any changes have happened
# dNew is the data used to generate the template, it has all the
# currently-existing localized strings
def update_tr_file(dNew, mod_name, tr_file):
if params["verbose"]:
print(f"updating {tr_file}")
tr_import = import_tr_file(tr_file)
dOld = tr_import[0]
textOld = tr_import[1]
textNew = strings_to_text(dNew, dOld, mod_name, tr_import[2])
if textOld and textOld != textNew:
print(f"{tr_file} has changed.")
if not params["no-old-file"]:
shutil.copyfile(tr_file, f"{tr_file}.old")
with open(tr_file, "w", encoding='utf-8') as new_tr_file:
new_tr_file.write(textNew)
# Updates translation files for the mod in the given folder
def update_mod(folder):
modname = get_modname(folder)
if modname is not None:
process_po_files(folder, modname)
print(f"Updating translations for {modname}")
data = generate_template(folder, modname)
if data == None:
print(f"No translatable strings found in {modname}")
else:
for tr_file in get_existing_tr_files(folder):
update_tr_file(data, modname, os.path.join(folder, "locale/", tr_file))
else:
print(f"\033[31mUnable to find modname in folder {folder}.\033[0m", file=_stderr)
exit(1)
# Determines if the folder being pointed to is a mod or a mod pack
# and then runs update_mod accordingly
def update_folder(folder):
is_modpack = os.path.exists(os.path.join(folder, "modpack.txt")) or os.path.exists(os.path.join(folder, "modpack.conf"))
if is_modpack:
subfolders = [f.path for f in os.scandir(folder) if f.is_dir()]
for subfolder in subfolders:
update_mod(subfolder + "/")
else:
update_mod(folder)
print("Done.")
def run_all_subfolders(folder):
for modfolder in [f.path for f in os.scandir(folder) if f.is_dir()]:
update_folder(modfolder + "/")
main()

View File

@ -40,10 +40,10 @@
hyperloop = {} hyperloop = {}
-- Version for compatibility checks, see history -- Version for compatibility checks, see history
hyperloop.version = 2.05 hyperloop.version = 2.06
if minetest.global_exists("techage") and techage.version < 0.06 then if minetest.global_exists("techage") and techage.version < 0.06 then
minetest.log("error", "[hyperloop] Hyperloop requires techage version 0.06 or newer!") error("[hyperloop] Hyperloop requires techage version 0.06 or newer!")
return return
end end
@ -59,7 +59,7 @@ else
end end
if tubelib2.version < 1.7 then if tubelib2.version < 1.7 then
minetest.log("error", "Hyperloop requires tubelib2 version 1.7 or newer!!!") error("Hyperloop requires tubelib2 version 1.7 or newer!!!")
else else
-- Configuration settings -- Configuration settings
hyperloop.wifi_enabled = minetest.settings:get_bool("hyperloop_wifi_enabled") hyperloop.wifi_enabled = minetest.settings:get_bool("hyperloop_wifi_enabled")

View File

@ -1,3 +0,0 @@
#!/bin/bash
../intllib/tools/xgettext.sh ./booking.lua ./door.lua ./lcd.lua ./tube.lua ./booking_node.lua ./elevator.lua ./map.lua ./seat.lua ./utils.lua ./data_base.lua ./init.lua ./waypoint.lua ./network.lua ./station.lua ./wifi.lua ./deco.lua ./junction.lua ./recipes.lua ./tubecrowbar.lua ./recipes.lua

Binary file not shown.

View File

@ -1,314 +0,0 @@
# SOME DESCRIPTIVE TITLE.
# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
# This file is distributed under the same license as the PACKAGE package.
# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR.
#
msgid ""
msgstr ""
"Project-Id-Version: \n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2018-12-22 11:22+0100\n"
"PO-Revision-Date: 2018-12-22 11:23+0100\n"
"Last-Translator: \n"
"Language-Team: \n"
"Language: de\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"X-Generator: Poedit 2.0.6\n"
#: booking.lua
msgid "Station data is corrupted. Please rebuild the station!"
msgstr "Stationsdaten sind beschädigt. Bitte die Station neu bauen!"
#: booking.lua
msgid "Station is still blocked. Please try again in a few seconds!"
msgstr ""
"Die Station ist noch blockiert. Bitte versuche es in ein paar Sekunden "
"wieder!"
#: door.lua
msgid "The Booking Machine for this station is missing!"
msgstr "Der Fahrkartenautomat für die Station fehlt!"
#: lcd.lua
msgid "Hyperloop Display"
msgstr "Hyperloop Bildschirm"
#: lcd.lua seat.lua
msgid " | | << Hyperloop >> | be anywhere"
msgstr " | | << Hyperloop >> | be anywhere"
#: tube.lua
msgid "Junction at "
msgstr "Anschlussstelle bei "
#: tube.lua
msgid "There is no station/junction on this level. "
msgstr "Es gibt keine Station/Anschlussstelle auf dieser Höhe. "
#: tube.lua
msgid "Do you really want to start a new network?!"
msgstr "Willst du wirklich ein neues Liniennetz beginnen?!"
#: tube.lua
msgid "Hyperloop Tube"
msgstr "Hyperloop Röhre"
#: booking_node.lua elevator.lua
msgid "Select your destination"
msgstr "Wähle dein Ziel"
#: booking_node.lua elevator.lua
msgid "Destination"
msgstr "Ziel"
#: booking_node.lua
msgid "Distance"
msgstr "Entfernung"
#: booking_node.lua
msgid "Local Info"
msgstr "Zusatzinfo"
#: booking_node.lua
msgid ""
"Please enter the station name to\n"
"which this booking machine belongs."
msgstr ""
"Bitte gib den Stationsnamen ein\n"
"zu dem dieser Fahrkartenautomat gehört."
#: booking_node.lua
msgid "Station name"
msgstr "Stationsname"
#: booking_node.lua
msgid "Additional station information"
msgstr "Zusätzliche Stationsinformationen"
#: booking_node.lua
msgid "Station has already a booking machine!"
msgstr "Station hat bereits einen Fahrkartenautomat!"
#: booking_node.lua
msgid "Invalid station name!"
msgstr "Ungültiger Stationsname!"
#: booking_node.lua
msgid "Hyperloop Booking Machine"
msgstr "Hyperloop Fahrkartenautomat"
#: elevator.lua
msgid "Hyperloop Elevator Shaft"
msgstr "Hyperloop Aufzugsschacht"
#: elevator.lua
msgid "Floor"
msgstr "Stockwerk"
#: elevator.lua
msgid "(current position)"
msgstr "(aktuelle Position)"
#: elevator.lua
msgid "Hyperloop Elevator"
msgstr "Hyperloop Aufzug"
#: elevator.lua
msgid "Please insert floor name"
msgstr "Gib den Stockwerknamen ein"
#: elevator.lua
msgid "Floor name"
msgstr "Stockwerkname"
#: elevator.lua
msgid "Base"
msgstr "Basis"
#: elevator.lua wifi.lua
msgid "Save"
msgstr "Speichern"
#: map.lua
msgid "Dist."
msgstr "Entf."
#: map.lua
msgid "Station/Junction"
msgstr "Station/Anschlussstelle"
#: map.lua
msgid "Position"
msgstr "Position"
#: map.lua
msgid "Owner"
msgstr "Besitzer"
#: map.lua
msgid "Conn. with"
msgstr "Verb. mit"
#: map.lua
msgid "Close"
msgstr "Schließen"
#: map.lua
msgid "Hyperloop Station Book"
msgstr "Hyperloop Stationsbuch"
#: seat.lua
msgid "Thank you | for | travelling | with | Hyperloop."
msgstr "Thank you | for | travelling | with | Hyperloop."
#: seat.lua
msgid " | Welcome at | | "
msgstr " | Willkommen | in | | "
#: seat.lua
msgid "[Hyperloop] No booking entered!"
msgstr "[Hyperloop] Keine Buchung eingegeben!"
#: seat.lua
msgid "Destination:"
msgstr "Ziel:"
#: seat.lua
msgid "Distance:"
msgstr "Entfernung:"
#: seat.lua
msgid "Arrival in:"
msgstr "Ankunft in:"
#: seat.lua
msgid "Hyperloop Pod Seat"
msgstr "Hyperloop Sitz"
#: waypoint.lua
msgid "Hyperloop Waypoint"
msgstr "Hyperloop Wegpunkt"
#: station.lua
msgid "Station completed. Now place the Booking Machine!"
msgstr "Station fertig. Setze nun den Fahrkartenautomat!"
#: station.lua
msgid "Area is protected!"
msgstr "Die Area ist geschützt!"
#: station.lua
msgid "Not enough space to build the station!"
msgstr "Nicht ausreichend Platz um die Station zu errichten!"
#: station.lua
msgid "Hyperloop Station Pod Builder"
msgstr "Hyperloop Stations Ersteller"
#: station.lua
msgid "Hyperloop Pod Shell"
msgstr "Hyperloop Kabinenwand"
#: station.lua recipes.lua
msgid "Hypersteel Ingot"
msgstr "Hypersteel Barren"
#: station.lua
msgid "Blue Wool"
msgstr "Blaue Wolle"
#: station.lua
msgid "Glass"
msgstr "Glas"
#: station.lua
msgid "Not enough inventory items to build the station!"
msgstr "Nicht ausreichend Inventory Items um die Station zu bauen!"
#: station.lua
msgid "Destroy Station"
msgstr "Zerstöre Station"
#: station.lua
msgid "Build Station"
msgstr "Baue Station"
#: station.lua
msgid "Hyperloop Station Block"
msgstr "Hyperloop Stations Block"
#: station.lua
msgid "Station"
msgstr "Station"
#: wifi.lua
msgid "Enter channel string"
msgstr "Kanalname eingeben"
#: wifi.lua
msgid "Hyperloop WiFi Tube"
msgstr "Hyperloop Wifi Röhre"
#: deco.lua
msgid "Hyperloop Promo Poster "
msgstr "Hyperloop Werbeposter "
#: deco.lua
msgid "Hyperloop Station Sign"
msgstr "Hyperloop Stationszeichen"
#: deco.lua
msgid "Hyperloop Station Sign Right"
msgstr "Hyperloop Stationszeichen rechts"
#: deco.lua
msgid "Hyperloop Station Sign Left"
msgstr "Hyperloop Stationszeichen links"
#: junction.lua
msgid "Station connected with "
msgstr "Station verbunden mit "
#: junction.lua
msgid "Junction connected with "
msgstr "Anschlussstelle verbunden mit "
#: junction.lua
msgid "Hyperloop Junction Block"
msgstr "Hyperloop Anschlussstelle"
#: junction.lua
msgid "Junction"
msgstr "Anschlussstelle"
#: junction.lua
msgid "Hyperloop Pillar"
msgstr "Hyperloop Stütze"
#: tubecrowbar.lua
msgid "[Crowbar Help]\n"
msgstr "[Brecheisen Hilfe]\n"
#: tubecrowbar.lua
msgid " left: remove node\n"
msgstr " links: entferne Block\n"
#: tubecrowbar.lua
msgid " right: repair tube/shaft line\n"
msgstr " rechts: repariere Röhre/Schacht\n"
#: tubecrowbar.lua
msgid "You don't have the necessary privs!"
msgstr "Du hast nicht die notwendigen Rechte!"
#: tubecrowbar.lua
msgid "Hyperloop Tube Crowbar"
msgstr "Hyperloop Brecheisen"
#~ msgid "Tube connection missing!"
#~ msgstr "Anschluss an eine Röhre fehlt!"
#~ msgid "Hypersteel Pod Shell"
#~ msgstr "Hyperloop Kabinenwand"

View File

@ -1,111 +1,142 @@
# textdomain: hyperloop # textdomain: hyperloop
### booking.lua ### ### booking.lua ###
Station data is corrupted. Please rebuild the station!=Stationsdaten sind beschädigt. Bitte die Station neu bauen! Station data is corrupted. Please rebuild the station!=Stationsdaten sind beschädigt. Bitte die Station neu bauen!
Station is still blocked. Please try again in a few seconds!=Die Station ist noch blockiert. Bitte versuche es in ein paar Sekunden wieder! Station is still blocked. Please try again in a few seconds!=Die Station ist noch blockiert. Bitte versuche es in ein paar Sekunden wieder!
### booking_node.lua ### ### booking_node.lua ###
Additional station information=Zusätzliche Stationsinformationen
Hyperloop Booking Machine=Hyperloop Fahrkartenautomat
Invalid station name!=Ungültiger Stationsname!
Please enter the station name to@nwhich this booking machine belongs.=Bitte gib den Stationsnamen ein@nzu dem dieser Fahrkartenautomat gehört.
Station has already a booking machine!=Station hat bereits einen Fahrkartenautomat!
Station name=Stationsname
Please enter the station name to@nwhich this booking machine belongs.=Bitte gib den Stationsnamen ein@nzu dem dieser Fahrkartenautomat gehört.
Station name=Stationsname
Additional station information=Zusätzliche Stationsinformationen
Station has already a booking machine!=Station hat bereits einen Fahrkartenautomat!
Invalid station name!=Ungültiger Stationsname!
Hyperloop Booking Machine=Hyperloop Fahrkartenautomat
### booking_node.lua ###
### elevator.lua ### ### elevator.lua ###
Select your destination=Wähle dein Ziel Select your destination=Wähle dein Ziel
### booking_node.lua ###
### migrate.lua ### ### migrate.lua ###
<unknown>=<unbekannt> <unknown>=<unbekannt>
### deco.lua ### ### deco.lua ###
Hyperloop Promo Poster =Hyperloop Werbeposter Hyperloop Promo Poster =Hyperloop Werbeposter
Hyperloop Station Sign=Hyperloop Stationszeichen Hyperloop Station Sign=Hyperloop Stationszeichen
Hyperloop Station Sign Left=Hyperloop Stationszeichen links
Hyperloop Station Sign Right=Hyperloop Stationszeichen rechts Hyperloop Station Sign Right=Hyperloop Stationszeichen rechts
Hyperloop Station Sign Left=Hyperloop Stationszeichen links
### door.lua ### ### door.lua ###
Hyperloop Door Bottom=Hyperloop Tür Unterteil
Hyperloop Door Top=Hyperloop Tür Oberteil
The Booking Machine for this station is missing!=Der Fahrkartenautomat für die Station fehlt! The Booking Machine for this station is missing!=Der Fahrkartenautomat für die Station fehlt!
Hyperloop Door Top=Hyperloop Tür Oberteil
Hyperloop Door Bottom=Hyperloop Tür Unterteil
### elevator.lua ### ### elevator.lua ###
(current position)=(aktuelle Position)
Base=Basis Hyperloop Elevator Shaft=Hyperloop Aufzugsschacht
Destination=Ziel Destination=Ziel
Floor=Stockwerk Floor=Stockwerk
Floor name=Stockwerkname (current position)=(aktuelle Position)
Hyperloop Elevator=Hyperloop Aufzug Hyperloop Elevator=Hyperloop Aufzug
Hyperloop Elevator Shaft=Hyperloop Aufzugsschacht
Please insert floor name=Gib den Stockwerknamen ein Please insert floor name=Gib den Stockwerknamen ein
Floor name=Stockwerkname
Base=Basis
### elevator.lua ###
### wifi.lua ### ### wifi.lua ###
Save=Speichern Save=Speichern
### junction.lua ### ### junction.lua ###
Station connected with =Station verbunden mit
Junction connected with =Anschlussstelle verbunden mit
Hyperloop Junction Block=Hyperloop Anschlussstelle Hyperloop Junction Block=Hyperloop Anschlussstelle
Hyperloop Pillar=Hyperloop Stütze Hyperloop Pillar=Hyperloop Stütze
Junction connected with =Anschlussstelle verbunden mit
Station connected with =Station verbunden mit
### junction.lua ###
### migrate.lua ### ### migrate.lua ###
Junction=Anschlussstelle Junction=Anschlussstelle
Hyperloop Legacy Tube=Hyperloop veraltetes Rohr
unknown=unbekant
### lcd.lua ### ### lcd.lua ###
Hyperloop Display=Hyperloop Bildschirm Hyperloop Display=Hyperloop Bildschirm
### map.lua ### ### map.lua ###
Close=Schließen
Conn. with=Verb. mit
Dist.=Entf. Dist.=Entf.
Hyperloop Station Book=Hyperloop Stationsbuch
Owner=Besitzer
Position=Position
Station/Junction=Station/Anschlussstelle Station/Junction=Station/Anschlussstelle
Position=Position
Owner=Besitzer
Conn. with=Verb. mit
Close=Schließen
Hyperloop Station Book=Hyperloop Stationsbuch
### migrate.lua ###
Hyperloop Legacy Tube=Hyperloop veraltetes Rohr
unknown=unbekant
### recipes.lua ###
### station.lua ###
Hypersteel Ingot=Hyperstahl Barren
### seat.lua ### ### seat.lua ###
Hyperloop Pod Seat=Hyperloop Sitz
[Hyperloop] No booking entered!=[Hyperloop] Keine Buchung eingegeben! [Hyperloop] No booking entered!=[Hyperloop] Keine Buchung eingegeben!
Hyperloop Pod Seat=Hyperloop Sitz
### station.lua ### ### station.lua ###
Hypersteel Ingot=Hyperstahl Barren
Area is protected!=Die Area ist geschützt!
Blue Wool=Blaue Wolle
Build Station=Baue Station
Destroy Station=Zerstöre Station
Glass=Glas
Hyperloop Pod Shell=Hyperloop Kabinenwand
Hyperloop Station Block=Hyperloop Stations Block
Hyperloop Station Pod Builder=Hyperloop Stations Ersteller
Not enough inventory items to build the station!=Nicht ausreichend Inventory Items um die Station zu bauen!
Not enough space to build the station!=Nicht ausreichend Platz um die Station zu errichten!
Station=Station
Station completed. Now place the Booking Machine!=Station fertig. Setze nun den Fahrkartenautomat! Station completed. Now place the Booking Machine!=Station fertig. Setze nun den Fahrkartenautomat!
Area is protected!=Die Area ist geschützt!
Not enough space to build the station!=Nicht ausreichend Platz um die Station zu errichten!
Hyperloop Station Pod Builder=Hyperloop Stations Ersteller
Hyperloop Pod Shell=Hyperloop Kabinenwand
Blue Wool=Blaue Wolle
Glass=Glas
Not enough inventory items to build the station!=Nicht ausreichend Inventory Items um die Station zu bauen!
Destroy Station=Zerstöre Station
Build Station=Baue Station
Hyperloop Station Block=Hyperloop Stations Block
Station=Station
### tube.lua ### ### tube.lua ###
Do you really want to start a new network?!=Willst du wirklich ein neues Liniennetz beginnen?!
Hyperloop Tube=Hyperloop Röhre
Junction at =Anschlussstelle bei Junction at =Anschlussstelle bei
Open end at =Offenes Ende bei
Station '=Station ' Station '=Station '
Station at =Station bei Station at =Station bei
Open end at =Offenes Ende bei
There is no station/junction on this level. =Es gibt keine Station/Anschlussstelle auf dieser Höhe. There is no station/junction on this level. =Es gibt keine Station/Anschlussstelle auf dieser Höhe.
Do you really want to start a new network?!=Willst du wirklich ein neues Liniennetz beginnen?!
Hyperloop Tube=Hyperloop Röhre
### tubecrowbar.lua ### ### tubecrowbar.lua ###
[Hyperloop] Error: Tube is too long!=[Hyperloop] Fehler: Röhre ist zu lang!
[Crowbar Help]@n=[Brecheisen Hilfe]@n
left: remove node@n= links: entferne Block@n left: remove node@n= links: entferne Block@n
right: repair tube/shaft line@n= rechts: repariere Röhre/Schacht@n right: repair tube/shaft line@n= rechts: repariere Röhre/Schacht@n
Hyperloop Tube Crowbar=Hyperloop Brecheisen
Repair via WorldEdit placed Hyperloop tubes by reusing WorldEdit pos1/pos2=Reparatur über WorldEdit platzierte Hyperloop-Röhren durch Wiederverwendung von WorldEdit pos1/pos2
Rights to remove tube nodes by means of the crowbar=Rechte zur Entfernung von Rohrknoten mit Hilfe der Brechstange
You don't have the necessary privs!=Du hast nicht die notwendigen Rechte! You don't have the necessary privs!=Du hast nicht die notwendigen Rechte!
[Crowbar Help]@n=[Brecheisen Hilfe]@n Hyperloop Tube Crowbar=Hyperloop Brecheisen
Rights to remove tube nodes by means of the crowbar=Rechte zur Entfernung von Rohrknoten mit Hilfe der Brechstange
Repair via WorldEdit placed Hyperloop tubes by reusing WorldEdit pos1/pos2=Reparatur über WorldEdit platzierte Hyperloop-Röhren durch Wiederverwendung von WorldEdit pos1/pos2
### waypoint.lua ### ### waypoint.lua ###
Hyperloop Waypoint=Hyperloop Wegpunkt Hyperloop Waypoint=Hyperloop Wegpunkt
### wifi.lua ### ### wifi.lua ###
Enter channel string=Kanalname eingeben Enter channel string=Kanalname eingeben
Hyperloop WiFi Tube=Hyperloop Wifi Röhre Hyperloop WiFi Tube=Hyperloop Wifi Röhre

View File

@ -1,304 +0,0 @@
# SOME DESCRIPTIVE TITLE.
# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
# This file is distributed under the same license as the PACKAGE package.
# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR.
#
#, fuzzy
msgid ""
msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2018-12-22 11:22+0100\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: LANGUAGE <LL@li.org>\n"
"Language: \n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=CHARSET\n"
"Content-Transfer-Encoding: 8bit\n"
#: booking.lua
msgid "Station data is corrupted. Please rebuild the station!"
msgstr ""
#: booking.lua
msgid "Station is still blocked. Please try again in a few seconds!"
msgstr ""
#: door.lua
msgid "The Booking Machine for this station is missing!"
msgstr ""
#: lcd.lua
msgid "Hyperloop Display"
msgstr ""
#: lcd.lua seat.lua
msgid " | | << Hyperloop >> | be anywhere"
msgstr ""
#: tube.lua
msgid "Junction at "
msgstr ""
#: tube.lua
msgid "There is no station/junction on this level. "
msgstr ""
#: tube.lua
msgid "Do you really want to start a new network?!"
msgstr ""
#: tube.lua
msgid "Hyperloop Tube"
msgstr ""
#: booking_node.lua elevator.lua
msgid "Select your destination"
msgstr ""
#: booking_node.lua elevator.lua
msgid "Destination"
msgstr ""
#: booking_node.lua
msgid "Distance"
msgstr ""
#: booking_node.lua
msgid "Local Info"
msgstr ""
#: booking_node.lua
msgid ""
"Please enter the station name to\n"
"which this booking machine belongs."
msgstr ""
#: booking_node.lua
msgid "Station name"
msgstr ""
#: booking_node.lua
msgid "Additional station information"
msgstr ""
#: booking_node.lua
msgid "Station has already a booking machine!"
msgstr ""
#: booking_node.lua
msgid "Invalid station name!"
msgstr ""
#: booking_node.lua
msgid "Hyperloop Booking Machine"
msgstr ""
#: elevator.lua
msgid "Hyperloop Elevator Shaft"
msgstr ""
#: elevator.lua
msgid "Floor"
msgstr ""
#: elevator.lua
msgid "(current position)"
msgstr ""
#: elevator.lua
msgid "Hyperloop Elevator"
msgstr ""
#: elevator.lua
msgid "Please insert floor name"
msgstr ""
#: elevator.lua
msgid "Floor name"
msgstr ""
#: elevator.lua
msgid "Base"
msgstr ""
#: elevator.lua wifi.lua
msgid "Save"
msgstr ""
#: map.lua
msgid "Dist."
msgstr ""
#: map.lua
msgid "Station/Junction"
msgstr ""
#: map.lua
msgid "Position"
msgstr ""
#: map.lua
msgid "Owner"
msgstr ""
#: map.lua
msgid "Conn. with"
msgstr ""
#: map.lua
msgid "Close"
msgstr ""
#: map.lua
msgid "Hyperloop Station Book"
msgstr ""
#: seat.lua
msgid "Thank you | for | travelling | with | Hyperloop."
msgstr ""
#: seat.lua
msgid " | Welcome at | | "
msgstr ""
#: seat.lua
msgid "[Hyperloop] No booking entered!"
msgstr ""
#: seat.lua
msgid "Destination:"
msgstr ""
#: seat.lua
msgid "Distance:"
msgstr ""
#: seat.lua
msgid "Arrival in:"
msgstr ""
#: seat.lua
msgid "Hyperloop Pod Seat"
msgstr ""
#: waypoint.lua
msgid "Hyperloop Waypoint"
msgstr ""
#: station.lua
msgid "Station completed. Now place the Booking Machine!"
msgstr ""
#: station.lua
msgid "Area is protected!"
msgstr ""
#: station.lua
msgid "Not enough space to build the station!"
msgstr ""
#: station.lua
msgid "Hyperloop Station Pod Builder"
msgstr ""
#: station.lua
msgid "Hyperloop Pod Shell"
msgstr ""
#: station.lua recipes.lua
msgid "Hypersteel Ingot"
msgstr ""
#: station.lua
msgid "Blue Wool"
msgstr ""
#: station.lua
msgid "Glass"
msgstr ""
#: station.lua
msgid "Not enough inventory items to build the station!"
msgstr ""
#: station.lua
msgid "Destroy Station"
msgstr ""
#: station.lua
msgid "Build Station"
msgstr ""
#: station.lua
msgid "Hyperloop Station Block"
msgstr ""
#: station.lua
msgid "Station"
msgstr ""
#: wifi.lua
msgid "Enter channel string"
msgstr ""
#: wifi.lua
msgid "Hyperloop WiFi Tube"
msgstr ""
#: deco.lua
msgid "Hyperloop Promo Poster "
msgstr ""
#: deco.lua
msgid "Hyperloop Station Sign"
msgstr ""
#: deco.lua
msgid "Hyperloop Station Sign Right"
msgstr ""
#: deco.lua
msgid "Hyperloop Station Sign Left"
msgstr ""
#: junction.lua
msgid "Station connected with "
msgstr ""
#: junction.lua
msgid "Junction connected with "
msgstr ""
#: junction.lua
msgid "Hyperloop Junction Block"
msgstr ""
#: junction.lua
msgid "Junction"
msgstr ""
#: junction.lua
msgid "Hyperloop Pillar"
msgstr ""
#: tubecrowbar.lua
msgid "[Crowbar Help]\n"
msgstr ""
#: tubecrowbar.lua
msgid " left: remove node\n"
msgstr ""
#: tubecrowbar.lua
msgid " right: repair tube/shaft line\n"
msgstr ""
#: tubecrowbar.lua
msgid "You don't have the necessary privs!"
msgstr ""
#: tubecrowbar.lua
msgid "Hyperloop Tube Crowbar"
msgstr ""

View File

@ -1,6 +1,7 @@
# textdomain: hyperloop # textdomain: hyperloop
### booking.lua ### ### booking.lua ###
Station data is corrupted. Please rebuild the station!= Station data is corrupted. Please rebuild the station!=
@ -8,14 +9,12 @@ Station is still blocked. Please try again in a few seconds!=
### booking_node.lua ### ### booking_node.lua ###
Additional station information=
Hyperloop Booking Machine=
Invalid station name!=
Please enter the station name to@nwhich this booking machine belongs.= Please enter the station name to@nwhich this booking machine belongs.=
Station has already a booking machine!=
Station name= Station name=
Additional station information=
Station has already a booking machine!=
Invalid station name!=
Hyperloop Booking Machine=
### booking_node.lua ### ### booking_node.lua ###
### elevator.lua ### ### elevator.lua ###
@ -31,25 +30,25 @@ Select your destination=
Hyperloop Promo Poster = Hyperloop Promo Poster =
Hyperloop Station Sign= Hyperloop Station Sign=
Hyperloop Station Sign Left=
Hyperloop Station Sign Right= Hyperloop Station Sign Right=
Hyperloop Station Sign Left=
### door.lua ### ### door.lua ###
Hyperloop Door Bottom=
Hyperloop Door Top=
The Booking Machine for this station is missing!= The Booking Machine for this station is missing!=
Hyperloop Door Top=
Hyperloop Door Bottom=
### elevator.lua ### ### elevator.lua ###
(current position)= Hyperloop Elevator Shaft=
Base=
Destination= Destination=
Floor= Floor=
Floor name= (current position)=
Hyperloop Elevator= Hyperloop Elevator=
Hyperloop Elevator Shaft=
Please insert floor name= Please insert floor name=
Floor name=
Base=
### elevator.lua ### ### elevator.lua ###
### wifi.lua ### ### wifi.lua ###
@ -58,10 +57,10 @@ Save=
### junction.lua ### ### junction.lua ###
Station connected with =
Junction connected with =
Hyperloop Junction Block= Hyperloop Junction Block=
Hyperloop Pillar= Hyperloop Pillar=
Junction connected with =
Station connected with =
### junction.lua ### ### junction.lua ###
### migrate.lua ### ### migrate.lua ###
@ -72,20 +71,15 @@ Junction=
Hyperloop Display= Hyperloop Display=
### lcd.lua ###
### seat.lua ###
| | << Hyperloop >> | be anywhere=
### map.lua ### ### map.lua ###
Close=
Conn. with=
Dist.= Dist.=
Hyperloop Station Book=
Owner=
Position=
Station/Junction= Station/Junction=
Position=
Owner=
Conn. with=
Close=
Hyperloop Station Book=
### migrate.lua ### ### migrate.lua ###
@ -99,50 +93,44 @@ Hypersteel Ingot=
### seat.lua ### ### seat.lua ###
| Welcome at | | =
Arrival in:=
Destination:=
Distance:=
Hyperloop Pod Seat=
Thank you | for | travelling | with | Hyperloop.=
[Hyperloop] No booking entered!= [Hyperloop] No booking entered!=
Hyperloop Pod Seat=
### station.lua ### ### station.lua ###
Area is protected!=
Blue Wool=
Build Station=
Destroy Station=
Glass=
Hyperloop Pod Shell=
Hyperloop Station Block=
Hyperloop Station Pod Builder=
Not enough inventory items to build the station!=
Not enough space to build the station!=
Station=
Station completed. Now place the Booking Machine!= Station completed. Now place the Booking Machine!=
Area is protected!=
Not enough space to build the station!=
Hyperloop Station Pod Builder=
Hyperloop Pod Shell=
Blue Wool=
Glass=
Not enough inventory items to build the station!=
Destroy Station=
Build Station=
Hyperloop Station Block=
Station=
### tube.lua ### ### tube.lua ###
Do you really want to start a new network?!=
Hyperloop Tube=
Junction at = Junction at =
Open end at =
Station '= Station '=
Station at = Station at =
Open end at =
There is no station/junction on this level. = There is no station/junction on this level. =
Do you really want to start a new network?!=
Hyperloop Tube=
### tubecrowbar.lua ### ### tubecrowbar.lua ###
[Hyperloop] Error: Tube is too long!=
[Crowbar Help]@n=
left: remove node@n= left: remove node@n=
right: repair tube/shaft line@n= right: repair tube/shaft line@n=
Hyperloop Tube Crowbar=
Repair via WorldEdit placed Hyperloop tubes by reusing WorldEdit pos1/pos2=
Rights to remove tube nodes by means of the crowbar=
You don't have the necessary privs!= You don't have the necessary privs!=
[Crowbar Help]@n= Hyperloop Tube Crowbar=
Rights to remove tube nodes by means of the crowbar=
Repair via WorldEdit placed Hyperloop tubes by reusing WorldEdit pos1/pos2=
### waypoint.lua ### ### waypoint.lua ###

View File

@ -75,6 +75,10 @@ local function on_arrival(tDeparture, tArrival, player_name, sound)
local yaw = hyperloop.facedir_to_rad(tArrival.facedir) - offs local yaw = hyperloop.facedir_to_rad(tArrival.facedir) - offs
player:set_look_yaw(yaw) player:set_look_yaw(yaw)
end end
-- set player name again
if tArrival.attributes then
player:set_nametag_attributes(tArrival.attributes)
end
end end
-- play arrival sound -- play arrival sound
minetest.sound_stop(sound) minetest.sound_stop(sound)
@ -156,7 +160,10 @@ local function on_start_travel(pos, node, clicker)
clicker:set_pos(pos) clicker:set_pos(pos)
-- rotate player to look in move direction -- rotate player to look in move direction
clicker:set_look_horizontal(hyperloop.facedir_to_rad(tDeparture.facedir)) clicker:set_look_horizontal(hyperloop.facedir_to_rad(tDeparture.facedir))
-- hide player name
tArrival.attributes = clicker:get_nametag_attributes()
clicker:set_nametag_attributes({text = " "})
-- activate display -- activate display
local dist = hyperloop.distance(pos, tArrival.pos) local dist = hyperloop.distance(pos, tArrival.pos)
local text = I("Destination:").." | "..string.sub(tArrival.name, 1, 13).." | "..I("Distance:").." | ".. local text = I("Destination:").." | "..string.sub(tArrival.name, 1, 13).." | "..I("Distance:").." | "..

View File

@ -39,6 +39,10 @@ local function repair_tubes(itemstack, placer, pointed_thing)
local dir1, dir2, fpos1, fpos2, fdir1, fdir2, cnt1, cnt2 = local dir1, dir2, fpos1, fpos2, fdir1, fdir2, cnt1, cnt2 =
Shaft:tool_repair_tube(pos, placer, pointed_thing) Shaft:tool_repair_tube(pos, placer, pointed_thing)
if fpos1 and fpos2 then if fpos1 and fpos2 then
if cnt1 + cnt2 >= Shaft.max_tube_length then
minetest.chat_send_player(placer:get_player_name(), string.char(0x1b) ..
"(c@#ff0000)" .. S("[Hyperloop] Error: Tube is too long!"))
end
minetest.chat_send_player(placer:get_player_name(), chat_message(dir1, cnt1, fpos1, fdir1)) minetest.chat_send_player(placer:get_player_name(), chat_message(dir1, cnt1, fpos1, fdir1))
minetest.chat_send_player(placer:get_player_name(), chat_message(dir2, cnt2, fpos2, fdir2)) minetest.chat_send_player(placer:get_player_name(), chat_message(dir2, cnt2, fpos2, fdir2))
minetest.sound_play({ minetest.sound_play({
@ -51,6 +55,10 @@ local function repair_tubes(itemstack, placer, pointed_thing)
local dir1, dir2, fpos1, fpos2, fdir1, fdir2, cnt1, cnt2 = local dir1, dir2, fpos1, fpos2, fdir1, fdir2, cnt1, cnt2 =
Tube:tool_repair_tube(pos, placer, pointed_thing) Tube:tool_repair_tube(pos, placer, pointed_thing)
if fpos1 and fpos2 then if fpos1 and fpos2 then
if cnt1 + cnt2 >= Shaft.max_tube_length then
minetest.chat_send_player(placer:get_player_name(), string.char(0x1b) ..
"(c@#ff0000)" .. S("[Hyperloop] Error: Tube is too long!"))
end
minetest.chat_send_player(placer:get_player_name(), chat_message(dir1, cnt1, fpos1, fdir1)) minetest.chat_send_player(placer:get_player_name(), chat_message(dir1, cnt1, fpos1, fdir1))
minetest.chat_send_player(placer:get_player_name(), chat_message(dir2, cnt2, fpos2, fdir2)) minetest.chat_send_player(placer:get_player_name(), chat_message(dir2, cnt2, fpos2, fdir2))
minetest.sound_play({ minetest.sound_play({

View File

@ -62,11 +62,13 @@ function minecart.get_node_lvm(pos)
local param2_data = vm:get_param2_data() local param2_data = vm:get_param2_data()
local area = VoxelArea:new({MinEdge = MinEdge, MaxEdge = MaxEdge}) local area = VoxelArea:new({MinEdge = MinEdge, MaxEdge = MaxEdge})
local idx = area:indexp(pos) local idx = area:indexp(pos)
node = { if data[idx] and param2_data[idx] then
name = minetest.get_name_from_content_id(data[idx]), return {
param2 = param2_data[idx] name = minetest.get_name_from_content_id(data[idx]),
} param2 = param2_data[idx]
return node }
end
return {name="ignore", param2=0}
end end
function minecart.stopped(vel, tolerance) function minecart.stopped(vel, tolerance)

View File

@ -133,13 +133,14 @@ local function monitoring()
local pos = entity.object:get_pos() local pos = entity.object:get_pos()
local vel = entity.object:get_velocity() local vel = entity.object:get_velocity()
local rot = entity.object:get_rotation() local rot = entity.object:get_rotation()
if not minetest.get_node_or_nil(pos) then -- unloaded area if pos and vel and rot then
lib.unload_cart(pos, vel, entity, item) if not minetest.get_node_or_nil(pos) then -- unloaded area
item.stopped = minecart.stopped(vel) lib.unload_cart(pos, vel, entity, item)
item.stopped = minecart.stopped(vel)
end
-- store last pos from cart
item.last_pos, item.last_vel, item.last_pitch, item.last_yaw = pos, vel, rot.x, rot.y
end end
-- store last pos from cart
item.last_pos, item.last_vel, item.last_pitch, item.last_yaw = pos, vel, rot.x, rot.y
else -- no cart running else -- no cart running
local pos, vel, pitch, yaw = get_pos_vel_pitch_yaw(item) local pos, vel, pitch, yaw = get_pos_vel_pitch_yaw(item)
if pos and vel then if pos and vel then

View File

@ -3,9 +3,9 @@ Signs Bot [signs_bot]
**A robot controlled by signs.** **A robot controlled by signs.**
Browse on: ![GitHub](https://github.com/joe7575/signs_bot) Browse on: [GitHub](https://github.com/joe7575/signs_bot)
Download: ![GitHub](https://github.com/joe7575/signs_bot/archive/master.zip) Download: [GitHub](https://github.com/joe7575/signs_bot/archive/master.zip)
![Signs Bot](https://github.com/joe7575/signs_bot/blob/master/screenshot.png) ![Signs Bot](https://github.com/joe7575/signs_bot/blob/master/screenshot.png)
@ -105,7 +105,7 @@ For all Inventory commands applies: If the inventory stack specified by <slot> i
repeat <num> -- start of a loop block, <num> is a number 1..999 repeat <num> -- start of a loop block, <num> is a number 1..999
end -- end of a loop block end -- end of a loop block
call <label> -- call of a function (with return via the command 'return') call <label> -- call of a function (with return via the command 'return')
Example with a function at the beginning: Example with a function at the beginning:
jump main -- jump to the label 'main' jump main -- jump to the label 'main'
@ -140,12 +140,12 @@ Or alternatively with the function at the end:
return -- end of 'foo'. Jump back return -- end of 'foo'. Jump back
### License ### License
Copyright (C) 2019-2020 Joachim Stolberg Copyright (C) 2019-2021 Joachim Stolberg
Code: Licensed under the GNU GPL version 3 or later. See LICENSE.txt Code: Licensed under the GNU GPL version 3 or later. See LICENSE.txt
### Dependencies ### Dependencies
default, farming, basic_materials, tubelib2 default, farming, basic_materials, tubelib2
optional: farming redo, node_io, doc, techage, minecart optional: farming redo, node_io, doc, techage, minecart
@ -167,5 +167,6 @@ optional: farming redo, node_io, doc, techage, minecart
- 2020-03-27 v1.01 * flower command and sign added - 2020-03-27 v1.01 * flower command and sign added
- 2020-03-30 v1.02 * Program flow control commands added - 2020-03-30 v1.02 * Program flow control commands added
- 2020-06-21 v1.03 * Interpreter bugfixes, node and crop sensors changed - 2020-06-21 v1.03 * Interpreter bugfixes, node and crop sensors changed
- 2020-10-01 v1.04 * Many improvements and bugfixes (Thanks toThomas-S) - 2020-10-01 v1.04 * Many improvements and bugfixes (Thanks to Thomas-S)
- 2021-01-30 v1.05 * Many improvements and bugfixes

View File

@ -89,7 +89,7 @@ minetest.register_node("signs_bot:bot_sensor_on", {
end, end,
on_timer = function(pos) on_timer = function(pos)
local node = lib.get_node_lvm(pos) local node = tubelib2.get_node_lvm(pos)
node.name = "signs_bot:bot_sensor" node.name = "signs_bot:bot_sensor"
minetest.swap_node(pos, node) minetest.swap_node(pos, node)
return false return false

View File

@ -30,7 +30,7 @@ local RegisteredInventories = {}
-- From chest to robot -- From chest to robot
function signs_bot.robot_take(base_pos, robot_pos, param2, want_count, slot) function signs_bot.robot_take(base_pos, robot_pos, param2, want_count, slot)
local target_pos = lib.next_pos(robot_pos, param2) local target_pos = lib.next_pos(robot_pos, param2)
local node = lib.get_node_lvm(target_pos) local node = tubelib2.get_node_lvm(target_pos)
local def = RegisteredInventories[node.name] local def = RegisteredInventories[node.name]
local owner = M(base_pos):get_string("owner") local owner = M(base_pos):get_string("owner")
@ -51,7 +51,7 @@ end
-- From robot to chest -- From robot to chest
function signs_bot.robot_put(base_pos, robot_pos, param2, num, slot) function signs_bot.robot_put(base_pos, robot_pos, param2, num, slot)
local target_pos = lib.next_pos(robot_pos, param2) local target_pos = lib.next_pos(robot_pos, param2)
local node = lib.get_node_lvm(target_pos) local node = tubelib2.get_node_lvm(target_pos)
local def = RegisteredInventories[node.name] local def = RegisteredInventories[node.name]
local owner = M(base_pos):get_string("owner") local owner = M(base_pos):get_string("owner")
local taken = signs_bot.bot_inv_take_item(base_pos, slot, num) local taken = signs_bot.bot_inv_take_item(base_pos, slot, num)
@ -71,7 +71,7 @@ end
-- From robot to furnace -- From robot to furnace
function signs_bot.robot_put_fuel(base_pos, robot_pos, param2, num, slot) function signs_bot.robot_put_fuel(base_pos, robot_pos, param2, num, slot)
local target_pos = lib.next_pos(robot_pos, param2) local target_pos = lib.next_pos(robot_pos, param2)
local node = lib.get_node_lvm(target_pos) local node = tubelib2.get_node_lvm(target_pos)
local def = RegisteredInventories[node.name] local def = RegisteredInventories[node.name]
local owner = M(base_pos):get_string("owner") local owner = M(base_pos):get_string("owner")
local taken = signs_bot.bot_inv_take_item(base_pos, slot, num) local taken = signs_bot.bot_inv_take_item(base_pos, slot, num)

View File

@ -22,7 +22,7 @@ local MP = minetest.get_modpath("signs_bot")
local I,_ = dofile(MP.."/intllib.lua") local I,_ = dofile(MP.."/intllib.lua")
local lib = signs_bot.lib local lib = signs_bot.lib
local get_node_lvm = lib.get_node_lvm local get_node_lvm = tubelib2.get_node_lvm
local function node_and_pos(pos) local function node_and_pos(pos)

View File

@ -102,10 +102,10 @@ local function pattern_copy(base_pos, mem)
mem.steps = mem.steps + 1 mem.steps = mem.steps + 1
if lib.not_protected(base_pos, dst_pos) then if lib.not_protected(base_pos, dst_pos) then
local src_node = lib.get_node_lvm(src_pos) local src_node = tubelib2.get_node_lvm(src_pos)
src_node.name = inv_get_item(base_pos, src_node.name) src_node.name = inv_get_item(base_pos, src_node.name)
local dst_node = lib.get_node_lvm(dst_pos) local dst_node = tubelib2.get_node_lvm(dst_pos)
inv_put_item(base_pos, mem, dst_node.name) inv_put_item(base_pos, mem, dst_node.name)
param2_conversion(src_node, mem.dir_offs) param2_conversion(src_node, mem.dir_offs)
minetest.set_node(dst_pos, src_node) minetest.set_node(dst_pos, src_node)

View File

@ -138,7 +138,7 @@ local function place_item_below(base_pos, robot_pos, param2, slot)
if not lib.not_protected(base_pos, pos1) then if not lib.not_protected(base_pos, pos1) then
return signs_bot.ERROR, I("Error: Position protected") return signs_bot.ERROR, I("Error: Position protected")
end end
local node = lib.get_node_lvm(pos1) local node = tubelib2.get_node_lvm(pos1)
if node.name == "signs_bot:robot_foot" then if node.name == "signs_bot:robot_foot" then
local taken = bot_inv_take_item(base_pos, slot, 1) local taken = bot_inv_take_item(base_pos, slot, 1)
if taken then if taken then
@ -204,7 +204,7 @@ signs_bot.register_botcommand("place_above", {
local function dig_item(base_pos, robot_pos, param2, slot, route, level) local function dig_item(base_pos, robot_pos, param2, slot, route, level)
local pos1 = lib.dest_pos(robot_pos, param2, route) local pos1 = lib.dest_pos(robot_pos, param2, route)
pos1.y = pos1.y + (level or 0) pos1.y = pos1.y + (level or 0)
local node = lib.get_node_lvm(pos1) local node = tubelib2.get_node_lvm(pos1)
local dug_name = lib.is_simple_node(node) local dug_name = lib.is_simple_node(node)
if not lib.not_protected(base_pos, pos1) then if not lib.not_protected(base_pos, pos1) then
return signs_bot.ERROR, I("Error: Position protected") return signs_bot.ERROR, I("Error: Position protected")
@ -287,7 +287,7 @@ signs_bot.register_botcommand("dig_right", {
local function dig_item_below(base_pos, robot_pos, param2, slot) local function dig_item_below(base_pos, robot_pos, param2, slot)
local pos1 = {x=robot_pos.x,y=robot_pos.y-1,z=robot_pos.z} local pos1 = {x=robot_pos.x,y=robot_pos.y-1,z=robot_pos.z}
local node = lib.get_node_lvm(pos1) local node = tubelib2.get_node_lvm(pos1)
local dug_name = lib.is_simple_node(node) local dug_name = lib.is_simple_node(node)
if not lib.not_protected(base_pos, pos1) then if not lib.not_protected(base_pos, pos1) then
return signs_bot.ERROR, I("Error: Position protected") return signs_bot.ERROR, I("Error: Position protected")
@ -321,7 +321,7 @@ signs_bot.register_botcommand("dig_below", {
local function dig_item_above(base_pos, robot_pos, param2, slot) local function dig_item_above(base_pos, robot_pos, param2, slot)
local pos1 = {x=robot_pos.x,y=robot_pos.y+1,z=robot_pos.z} local pos1 = {x=robot_pos.x,y=robot_pos.y+1,z=robot_pos.z}
local node = lib.get_node_lvm(pos1) local node = tubelib2.get_node_lvm(pos1)
local dug_name = lib.is_simple_node(node) local dug_name = lib.is_simple_node(node)
if not lib.not_protected(base_pos, pos1) then if not lib.not_protected(base_pos, pos1) then
return signs_bot.ERROR, I("Error: Position protected") return signs_bot.ERROR, I("Error: Position protected")
@ -356,7 +356,7 @@ signs_bot.register_botcommand("dig_above", {
local function rotate_item(base_pos, robot_pos, param2, route, level, steps) local function rotate_item(base_pos, robot_pos, param2, route, level, steps)
local pos1 = lib.dest_pos(robot_pos, param2, route) local pos1 = lib.dest_pos(robot_pos, param2, route)
pos1.y = pos1.y + level pos1.y = pos1.y + level
local node = lib.get_node_lvm(pos1) local node = tubelib2.get_node_lvm(pos1)
if not lib.not_protected(base_pos, pos1) then if not lib.not_protected(base_pos, pos1) then
return signs_bot.ERROR, I("Error: Position protected") return signs_bot.ERROR, I("Error: Position protected")
end end

View File

@ -280,7 +280,7 @@ local function dig_sign(base_pos, robot_pos, param2, slot)
return signs_bot.ERROR, I("Error: No sign available") return signs_bot.ERROR, I("Error: No sign available")
end end
if lib.not_protected(base_pos, pos1) then if lib.not_protected(base_pos, pos1) then
local node = lib.get_node_lvm(pos1) local node = tubelib2.get_node_lvm(pos1)
local sign = ItemStack(node.name) local sign = ItemStack(node.name)
local meta = sign:get_meta() local meta = sign:get_meta()
meta:set_string("description", name) meta:set_string("description", name)
@ -320,7 +320,7 @@ local function trash_sign(base_pos, robot_pos, param2, slot)
return signs_bot.ERROR, I("Error: No sign available") return signs_bot.ERROR, I("Error: No sign available")
end end
if lib.not_protected(base_pos, pos1) then if lib.not_protected(base_pos, pos1) then
local node = lib.get_node_lvm(pos1) local node = tubelib2.get_node_lvm(pos1)
local sign = ItemStack("signs_bot:sign_cmnd") local sign = ItemStack("signs_bot:sign_cmnd")
minetest.remove_node(pos1) minetest.remove_node(pos1)
signs_bot.bot_inv_put_item(base_pos, slot, sign) signs_bot.bot_inv_put_item(base_pos, slot, sign)

View File

@ -109,7 +109,7 @@ local function check_sign(pos, mem)
return false return false
end end
local node = lib.get_node_lvm(pos) local node = tubelib2.get_node_lvm(pos)
-- correct sign direction? -- correct sign direction?
if mem.robot_param2 == node.param2 then if mem.robot_param2 == node.param2 then
return true return true
@ -143,7 +143,7 @@ end
local function activate_sensor(pos, param2) local function activate_sensor(pos, param2)
local pos1 = lib.next_pos(pos, param2) local pos1 = lib.next_pos(pos, param2)
local node = lib.get_node_lvm(pos1) local node = tubelib2.get_node_lvm(pos1)
if node.name == "signs_bot:bot_sensor" then if node.name == "signs_bot:bot_sensor" then
node.name = "signs_bot:bot_sensor_on" node.name = "signs_bot:bot_sensor_on"
minetest.swap_node(pos1, node) minetest.swap_node(pos1, node)

View File

@ -99,7 +99,7 @@ minetest.register_node("signs_bot:sensor_extender_on", {
end, end,
on_timer = function(pos) on_timer = function(pos)
local node = lib.get_node_lvm(pos) local node = tubelib2.get_node_lvm(pos)
node.name = "signs_bot:sensor_extender" node.name = "signs_bot:sensor_extender"
minetest.swap_node(pos, node) minetest.swap_node(pos, node)
return false return false

View File

@ -15,11 +15,14 @@
signs_bot = {} signs_bot = {}
-- Version for compatibility checks, see readme.md/history -- Version for compatibility checks, see readme.md/history
signs_bot.version = 1.03 signs_bot.version = 1.05
if minetest.global_exists("techage") and techage.version < 0.06 then if minetest.global_exists("techage") and techage.version < 0.25 then
minetest.log("error", "[signs_bot] Signs Bot requires techage version 0.06 or newer!") error("[signs_bot] Signs Bot requires techage version 0.25 or newer!")
return end
if tubelib2.version < 1.9 then
error("[signs_bot] Signs Bot requires tubelib2 version 1.9 or newer!")
end end
signs_bot.S = minetest.get_translator("signs_bot") signs_bot.S = minetest.get_translator("signs_bot")

View File

@ -183,7 +183,7 @@ register_command("call", 1,
return api.DONE return api.DONE
end, end,
function(addr) function(addr)
return tSymbolTbl[addr..":"] return addr and tSymbolTbl[addr..":"]
end end
) )
@ -204,7 +204,7 @@ register_command("jump", 1,
return api.DONE return api.DONE
end, end,
function(addr) function(addr)
return tSymbolTbl[addr..":"] return addr and tSymbolTbl[addr..":"]
end end
) )

View File

@ -53,27 +53,9 @@ function signs_bot.lib.dest_pos(pos, param2, route)
return pos, p2 return pos, p2
end end
function signs_bot.lib.get_node_lvm(pos)
local node = minetest.get_node_or_nil(pos)
if node then
return node
end
local vm = minetest.get_voxel_manip()
local MinEdge, MaxEdge = vm:read_from_map(pos, pos)
local data = vm:get_data()
local param2_data = vm:get_param2_data()
local area = VoxelArea:new({MinEdge = MinEdge, MaxEdge = MaxEdge})
local idx = area:indexp(pos)
node = {
name = minetest.get_name_from_content_id(data[idx]),
param2 = param2_data[idx]
}
return node
end
local next_pos = signs_bot.lib.next_pos local next_pos = signs_bot.lib.next_pos
local dest_pos = signs_bot.lib.dest_pos local dest_pos = signs_bot.lib.dest_pos
local get_node_lvm = signs_bot.lib.get_node_lvm local get_node_lvm = tubelib2.get_node_lvm
local function poke_objects(pos, param2, objects) local function poke_objects(pos, param2, objects)
minetest.sound_play('signs_bot_go_away', {pos = pos}) minetest.sound_play('signs_bot_go_away', {pos = pos})
@ -124,6 +106,7 @@ end
-- Has to be checked before a node is dug -- Has to be checked before a node is dug
function signs_bot.lib.is_simple_node(node) function signs_bot.lib.is_simple_node(node)
if node.name == "signs_bot:box" then return false end
-- don't remove nodes with some intelligence or undiggable nodes -- don't remove nodes with some intelligence or undiggable nodes
local ndef = minetest.registered_nodes[node.name] local ndef = minetest.registered_nodes[node.name]
if not NotSoSimpleNodes[node.name] then if not NotSoSimpleNodes[node.name] then

View File

@ -23,7 +23,7 @@ local I,_ = dofile(MP.."/intllib.lua")
local lib = signs_bot.lib local lib = signs_bot.lib
local CYCLE_TIME = 4 local CYCLE_TIME = 2
local function update_infotext(pos, dest_pos, cmnd) local function update_infotext(pos, dest_pos, cmnd)
M(pos):set_string("infotext", I("Node Sensor: Connected with ")..S(dest_pos).." / "..cmnd) M(pos):set_string("infotext", I("Node Sensor: Connected with ")..S(dest_pos).." / "..cmnd)
@ -74,12 +74,16 @@ local function any_node_changed(pos)
if mem.num ~= num then if mem.num ~= num then
if mem.mode == 1 and num < mem.num then if mem.mode == 1 and num < mem.num then
mem.num = num
return true return true
elseif mem.mode == 2 and num > mem.num then elseif mem.mode == 2 and num > mem.num then
mem.num = num
return true return true
elseif mem.mode == 3 then elseif mem.mode == 3 then
mem.num = num
return true return true
end end
mem.num = num
end end
return false return false
end end

View File

@ -21,8 +21,8 @@ local lib = signs_bot.lib
-- Called when robot is started -- Called when robot is started
function signs_bot.place_robot(pos1, pos2, param2) function signs_bot.place_robot(pos1, pos2, param2)
local node1 = lib.get_node_lvm(pos1) local node1 = tubelib2.get_node_lvm(pos1)
local node2 = lib.get_node_lvm(pos2) local node2 = tubelib2.get_node_lvm(pos2)
if lib.check_pos(pos1, node1, node2, param2) then if lib.check_pos(pos1, node1, node2, param2) then
minetest.set_node(pos1, {name = "signs_bot:robot", param2 = param2}) minetest.set_node(pos1, {name = "signs_bot:robot", param2 = param2})
end end
@ -31,11 +31,11 @@ end
-- Called when robot is removed -- Called when robot is removed
function signs_bot.remove_robot(mem) function signs_bot.remove_robot(mem)
local pos = mem.robot_pos local pos = mem.robot_pos
local node = lib.get_node_lvm(pos) local node = tubelib2.get_node_lvm(pos)
if node.name == "signs_bot:robot" then if node.name == "signs_bot:robot" then
minetest.remove_node(pos) minetest.remove_node(pos)
local pos1 = {x=pos.x, y=pos.y-1, z=pos.z} local pos1 = {x=pos.x, y=pos.y-1, z=pos.z}
node = lib.get_node_lvm(pos1) node = tubelib2.get_node_lvm(pos1)
if node.name == "signs_bot:robot_foot" or node.name == "signs_bot:robot_leg" then if node.name == "signs_bot:robot_foot" or node.name == "signs_bot:robot_leg" then
if node.name == "signs_bot:robot_foot" then if node.name == "signs_bot:robot_foot" then
minetest.swap_node(pos1, mem.stored_node or {name = "air"}) minetest.swap_node(pos1, mem.stored_node or {name = "air"})
@ -43,7 +43,7 @@ function signs_bot.remove_robot(mem)
minetest.remove_node(pos1) minetest.remove_node(pos1)
end end
pos1 = {x=pos.x, y=pos.y-2, z=pos.z} pos1 = {x=pos.x, y=pos.y-2, z=pos.z}
node = lib.get_node_lvm(pos1) node = tubelib2.get_node_lvm(pos1)
if node.name == "signs_bot:robot_foot" then if node.name == "signs_bot:robot_foot" then
minetest.swap_node(pos1, mem.stored_node or {name = "air"}) minetest.swap_node(pos1, mem.stored_node or {name = "air"})
end end

View File

@ -21,7 +21,7 @@ local lib = signs_bot.lib
-- Used by the pairing tool -- Used by the pairing tool
function signs_bot.get_node_type(pos) function signs_bot.get_node_type(pos)
local node = lib.get_node_lvm(pos) local node = tubelib2.get_node_lvm(pos)
local ndef = minetest.registered_nodes[node.name] local ndef = minetest.registered_nodes[node.name]
local is_sensor = minetest.get_item_group(node.name, "sign_bot_sensor") == 1 local is_sensor = minetest.get_item_group(node.name, "sign_bot_sensor") == 1
if ndef then if ndef then
@ -38,7 +38,7 @@ end
-- Used by the pairing tool -- Used by the pairing tool
function signs_bot.get_signal(actuator_pos) function signs_bot.get_signal(actuator_pos)
if actuator_pos then if actuator_pos then
local node = lib.get_node_lvm(actuator_pos) local node = tubelib2.get_node_lvm(actuator_pos)
local ndef = minetest.registered_nodes[node.name] local ndef = minetest.registered_nodes[node.name]
if ndef and ndef.signs_bot_get_signal then if ndef and ndef.signs_bot_get_signal then
return ndef.signs_bot_get_signal(actuator_pos, node) return ndef.signs_bot_get_signal(actuator_pos, node)
@ -65,7 +65,7 @@ function signs_bot.send_signal(sensor_pos)
local signal = meta:get_string("signal_data") local signal = meta:get_string("signal_data")
if dest_pos ~= "" and signal ~= "" then if dest_pos ~= "" and signal ~= "" then
local pos = P(dest_pos) local pos = P(dest_pos)
local node = lib.get_node_lvm(pos) local node = tubelib2.get_node_lvm(pos)
local ndef = minetest.registered_nodes[node.name] local ndef = minetest.registered_nodes[node.name]
if ndef and ndef.signs_bot_on_signal then if ndef and ndef.signs_bot_on_signal then
ndef.signs_bot_on_signal(pos, node, signal) ndef.signs_bot_on_signal(pos, node, signal)

View File

@ -57,7 +57,7 @@ if minetest.get_modpath("techage") then
description = S("Ignite the techage charcoal lighter"), description = S("Ignite the techage charcoal lighter"),
cmnd = function(base_pos, mem) cmnd = function(base_pos, mem)
local pos = signs_bot.lib.dest_pos(mem.robot_pos, mem.robot_param2, {0}) local pos = signs_bot.lib.dest_pos(mem.robot_pos, mem.robot_param2, {0})
local node = signs_bot.lib.get_node_lvm(pos) local node = tubelib2.get_node_lvm(pos)
if minetest.registered_nodes[node.name] if minetest.registered_nodes[node.name]
and minetest.registered_nodes[node.name].on_ignite then and minetest.registered_nodes[node.name].on_ignite then
minetest.registered_nodes[node.name].on_ignite(pos) minetest.registered_nodes[node.name].on_ignite(pos)

View File

@ -53,7 +53,7 @@ local function pairing(actuator_pos, sensor_pos)
local signal = signs_bot.get_signal(actuator_pos) local signal = signs_bot.get_signal(actuator_pos)
if signal then if signal then
signs_bot.store_signal(sensor_pos, actuator_pos, signal) signs_bot.store_signal(sensor_pos, actuator_pos, signal)
local node = lib.get_node_lvm(sensor_pos) local node = tubelib2.get_node_lvm(sensor_pos)
local ndef = minetest.registered_nodes[node.name] local ndef = minetest.registered_nodes[node.name]
if ndef and ndef.update_infotext then if ndef and ndef.update_infotext then
ndef.update_infotext(sensor_pos, actuator_pos, signal) ndef.update_infotext(sensor_pos, actuator_pos, signal)

View File

@ -25,4 +25,5 @@ Code: GNU GPL version 3. See LICENSE.txt
Textures: CC BY-SA 3.0 Textures: CC BY-SA 3.0
### History
- 2020-10-15 v1.0 * First version

View File

@ -71,6 +71,7 @@ minetest.register_tool(
else else
minetest.chat_send_player(name, minetest.chat_send_player(name,
minetest.colorize("#FFFF00", S("First jump from a hill and then use the paraglider"))) minetest.colorize("#FFFF00", S("First jump from a hill and then use the paraglider")))
pmeta:set_int("player_physics_locked", 0)
end end
end, end,

View File

@ -77,10 +77,10 @@ local function prepare_tiles(tiles, stage, power_png)
local tbl = {} local tbl = {}
for _,item in ipairs(tiles) do for _,item in ipairs(tiles) do
if type(item) == "string" then if type(item) == "string" then
tbl[#tbl+1] = item:gsub("#", stage):gsub("{power}", power_png) tbl[#tbl+1] = item:gsub("#", stage):gsub("{power}", power_png):gsub("@@", '#')
else else
local temp = table.copy(item) local temp = table.copy(item)
temp.image = temp.image:gsub("#", stage):gsub("{power}", power_png) temp.image = temp.image:gsub("#", stage):gsub("{power}", power_png):gsub("@@", '#')
tbl[#tbl+1] = temp tbl[#tbl+1] = temp
end end
end end

View File

@ -27,7 +27,7 @@ local STANDBY_TICKS = 3
local COUNTDOWN_TICKS = 4 local COUNTDOWN_TICKS = 4
local CYCLE_TIME = 4 local CYCLE_TIME = 4
local INFO = [[Turn port on/off: command = 'port', payload = red/green/blue/yellow=on/off]] local INFO = [[Turn port on/off or read its state: command = 'port', payload = red/green/blue/yellow{=on/off}]]
--local Side2Color = {B="red", L="green", F="blue", R="yellow"} --local Side2Color = {B="red", L="green", F="blue", R="yellow"}
@ -374,6 +374,13 @@ local function change_filter_settings(pos, slot, val)
return true return true
end end
-- techage command to read filter channel status (on/off)
local function read_filter_settings(pos, slot)
local slots = {["red"] = 1, ["green"] = 2, ["blue"] = 3, ["yellow"] = 4}
local filter = minetest.deserialize(M(pos):get_string("filter"))
return filter[slots[slot]] and "on" or "off"
end
local function can_dig(pos, player) local function can_dig(pos, player)
if minetest.is_protected(pos, player:get_player_name()) then if minetest.is_protected(pos, player:get_player_name()) then
return false return false
@ -437,7 +444,11 @@ local tubing = {
elseif topic == "port" then elseif topic == "port" then
-- "red"/"green"/"blue"/"yellow" = "on"/"off" -- "red"/"green"/"blue"/"yellow" = "on"/"off"
local slot, val = techage.ident_value(payload) local slot, val = techage.ident_value(payload)
return change_filter_settings(pos, slot, val) if val == "" then
return read_filter_settings(pos, slot)
else
return change_filter_settings(pos, slot, val)
end
else else
return CRD(pos).State:on_receive_message(pos, topic, payload) return CRD(pos).State:on_receive_message(pos, topic, payload)
end end

View File

@ -54,6 +54,7 @@ local function chat(player, text)
end end
local function postload_area(pos) local function postload_area(pos)
minetest.log("warning", "[FLB] area "..P2S(pos).." not loaded!")
if not minetest.forceload_block(pos, true) then if not minetest.forceload_block(pos, true) then
minetest.after(60, postload_area, pos) minetest.after(60, postload_area, pos)
end end

View File

@ -0,0 +1,100 @@
--[[
TechAge
=======
Copyright (C) 2019-2020 Joachim Stolberg
AGPL v3
See LICENSE.txt for more information
Item Source Block
]]--
-- for lazy programmers
local M = minetest.get_meta
local S = techage.S
local CYCLE_TIME = 30
local function formspec()
return "size[8,7.2]"..
default.gui_bg..
default.gui_bg_img..
default.gui_slots..
"list[context;main;3.5,0.8;1,1;]"..
"list[current_player;main;0,3.5;8,4;]"..
"listring[context;main]"..
"listring[current_player;main]"
end
local function allow_metadata_inventory_put(pos, listname, index, stack, player)
if minetest.is_protected(pos, player:get_player_name()) then
return 0
end
return stack:get_count()
end
local function allow_metadata_inventory_take(pos, listname, index, stack, player)
if minetest.is_protected(pos, player:get_player_name()) then
return 0
end
return stack:get_count()
end
minetest.register_node("techage:itemsource", {
description = "Techage Item Source",
tiles = {
-- up, down, right, left, back, front
"techage_filling_ta3.png^techage_frame_ta3_top.png^techage_appl_arrow.png",
"techage_filling_ta3.png^techage_frame_ta3.png",
"techage_filling_ta3.png^techage_frame_ta3.png^techage_appl_outp.png",
"techage_filling_ta3.png^techage_frame_ta3.png",
"techage_filling_ta3.png^techage_appl_nodedetector.png^techage_frame_ta3.png",
"techage_filling_ta3.png^techage_appl_nodedetector.png^techage_frame_ta3.png",
},
after_place_node = function(pos, placer)
local meta = M(pos)
local node = minetest.get_node(pos)
meta:set_int("push_dir", techage.side_to_outdir("R", node.param2))
local inv = meta:get_inventory()
inv:set_size('main', 1)
minetest.get_node_timer(pos):start(CYCLE_TIME)
meta:set_string("infotext", "Techage Item Source")
meta:set_string("formspec", formspec())
end,
on_timer = function(pos, elapsed)
local meta = M(pos)
local inv = meta:get_inventory()
local stack = inv:get_stack('main', 1)
if stack:get_count() > 0 then
local push_dir = meta:get_int("push_dir")
if techage.push_items(pos, push_dir, stack) then
local cnt = meta:get_int("counter") + stack:get_count()
meta:set_int("counter", cnt)
meta:set_string("infotext", "Techage Item Source: "..cnt)
end
end
return true
end,
allow_metadata_inventory_put = allow_metadata_inventory_put,
allow_metadata_inventory_take = allow_metadata_inventory_take,
paramtype2 = "facedir", -- important!
on_rotate = screwdriver.disallow, -- important!
is_ground_content = false,
drop = "",
groups = {crumbly = 3, cracky = 3, snappy = 3},
sounds = default.node_sound_glass_defaults(),
})
techage.register_node({"techage:itemsource"}, {
on_node_load = function(pos)
minetest.get_node_timer(pos):start(CYCLE_TIME)
end,
})

View File

@ -0,0 +1,345 @@
--[[
TechAge
=======
Copyright (C) 2019-2021 Joachim Stolberg
AGPL v3
See LICENSE.txt for more information
TA4 Recycler, recycling techage machines
]]--
-- for lazy programmers
local M = minetest.get_meta
local S = techage.S
-- Consumer Related Data
local CRD = function(pos) return (minetest.registered_nodes[techage.get_node_lvm(pos).name] or {}).consumer end
local STANDBY_TICKS = 3
local COUNTDOWN_TICKS = 4
local CYCLE_TIME = 8
local Recipes = {}
local SpecialItems = {
["techage:sieved_gravel"] = "default:sand",
["basic_materials:heating_element"] = "default:copper_ingot",
["techage:ta4_wlanchip"] = "",
["techage:basalt_cobble"] = "default:sand",
["default:stone"] = "techage:sieved_gravel",
["default:wood"] = "default:stick 5",
["basic_materials:concrete_block"] = "techage:sieved_gravel",
["dye:green"] = "",
["dye:red"] = "",
["dye:white"] = "",
["dye:blue"] = "",
["dye:brown"] = "",
["dye:cyan"] = "",
["dye:yellow"] = "",
["dye:grey"] = "",
["dye:orange"] = "",
["dye:black"] = "",
["techage:basalt_glass_thin"] = "",
["group:stone"] = "techage:sieved_gravel",
["basic_materials:plastic_sheet"] = "",
["group:wood"] = "default:stick 5",
["techage:basalt_glass"] = "",
["default:junglewood"] = "default:stick 5",
["techage:ta4_silicon_wafer"] = "",
["default:cobble"] = "techage:sieved_gravel",
["default:pick_diamond"] = "default:stick",
["techage:hammer_steel"] = "default:stick",
["default:paper"] = "",
["stairs:slab_basalt_glass2"] = "",
["techage:basalt_stone"] = "techage:sieved_gravel",
["techage:ta4_ramchip"] = "",
["protector:chest"] = "default:chest",
["techage:ta4_rotor_blade"] = "",
["techage:ta4_carbon_fiber"] = "",
}
local function formspec(self, pos, nvm)
return "size[8,8]"..
default.gui_bg..
default.gui_bg_img..
default.gui_slots..
"list[context;src;0,0;3,3;]"..
--"item_image[0,0;1,1;default:cobble]"..
"image[0,0;1,1;techage_form_mask.png]"..
"image[3.5,0;1,1;"..techage.get_power_image(pos, nvm).."]"..
"image[3.5,1;1,1;techage_form_arrow.png]"..
"image_button[3.5,2;1,1;"..self:get_state_button_image(nvm)..";state_button;]"..
"tooltip[3.5,2;1,1;"..self:get_state_tooltip(nvm).."]"..
"list[context;dst;5,0;3,3;]"..
--"item_image[5,0;1,1;default:gravel]"..
"image[5,0;1,1;techage_form_mask.png]"..
"list[current_player;main;0,4;8,4;]"..
"listring[context;dst]"..
"listring[current_player;main]"..
"listring[context;src]"..
"listring[current_player;main]"..
default.get_hotbar_bg(0, 4)
end
local function allow_metadata_inventory_put(pos, listname, index, stack, player)
if minetest.is_protected(pos, player:get_player_name()) then
return 0
end
if listname == "src" then
CRD(pos).State:start_if_standby(pos)
end
return stack:get_count()
end
local function allow_metadata_inventory_move(pos, from_list, from_index, to_list, to_index, count, player)
local inv = M(pos):get_inventory()
local stack = inv:get_stack(from_list, from_index)
return allow_metadata_inventory_put(pos, to_list, to_index, stack, player)
end
local function allow_metadata_inventory_take(pos, listname, index, stack, player)
if minetest.is_protected(pos, player:get_player_name()) then
return 0
end
return stack:get_count()
end
local function cook_reverse(stack, inv, idx, recipe)
-- check space
for _,item in ipairs(recipe.items) do
if not inv:room_for_item("dst", stack) then
return false
end
end
-- take item
inv:remove_item("src", ItemStack(recipe.output))
-- add items
for _,item in ipairs(recipe.items) do
inv:add_item("dst", item)
end
return true
end
local function get_recipe(stack)
local name = stack:get_name()
local recipe = Recipes[name]
if recipe then
if stack:get_count() >= ItemStack(recipe.output):get_count() then
return recipe
end
end
end
local function recycling(pos, crd, nvm, inv)
for idx,stack in ipairs(inv:get_list("src")) do
local recipe = not stack:is_empty() and get_recipe(stack)
if recipe then
if cook_reverse(stack, inv, idx, recipe) then
crd.State:keep_running(pos, nvm, COUNTDOWN_TICKS)
else
crd.State:blocked(pos, nvm)
end
return
end
end
crd.State:idle(pos, nvm)
end
local function keep_running(pos, elapsed)
local nvm = techage.get_nvm(pos)
local crd = CRD(pos)
local inv = M(pos):get_inventory()
recycling(pos, crd, nvm, inv)
end
local function on_receive_fields(pos, formname, fields, player)
if minetest.is_protected(pos, player:get_player_name()) then
return
end
local nvm = techage.get_nvm(pos)
CRD(pos).State:state_button_event(pos, nvm, fields)
end
local function can_dig(pos, player)
if minetest.is_protected(pos, player:get_player_name()) then
return false
end
local inv = M(pos):get_inventory()
return inv:is_empty("dst") and inv:is_empty("src")
end
local tiles = {}
-- '#' will be replaced by the stage number
-- '{power}' will be replaced by the power PNG
tiles.pas = {
-- up, down, right, left, back, front
"techage_appl_grinder.png^[colorize:@@000000:100^techage_frame_ta#_top.png",
--"techage_appl_grinder.png^techage_frame_ta#_top.png^[multiply:#FF0000",
"techage_filling_ta#.png^techage_frame_ta#.png",
"techage_filling_ta#.png^techage_frame_ta#.png^techage_appl_outp.png",
"techage_filling_ta#.png^techage_frame_ta#.png^techage_appl_inp.png",
"techage_filling_ta#.png^techage_appl_recycler.png^techage_frame_ta#.png",
"techage_filling_ta#.png^techage_appl_recycler.png^techage_frame_ta#.png",
}
tiles.act = {
-- up, down, right, left, back, front
{
image = "techage_appl_grinder4.png^[colorize:@@000000:100^techage_frame4_ta#_top.png",
backface_culling = false,
animation = {
type = "vertical_frames",
aspect_w = 32,
aspect_h = 32,
length = 1.0,
},
},
"techage_filling_ta#.png^techage_frame_ta#.png",
"techage_filling_ta#.png^techage_frame_ta#.png^techage_appl_outp.png",
"techage_filling_ta#.png^techage_frame_ta#.png^techage_appl_inp.png",
"techage_filling_ta#.png^techage_appl_recycler.png^techage_frame_ta#.png",
"techage_filling_ta#.png^techage_appl_recycler.png^techage_frame_ta#.png",
}
local tubing = {
on_pull_item = function(pos, in_dir, num)
local meta = minetest.get_meta(pos)
if meta:get_int("pull_dir") == in_dir then
local inv = M(pos):get_inventory()
return techage.get_items(pos, inv, "dst", num)
end
end,
on_push_item = function(pos, in_dir, stack)
local meta = minetest.get_meta(pos)
if meta:get_int("push_dir") == in_dir or in_dir == 5 then
local inv = M(pos):get_inventory()
--CRD(pos).State:start_if_standby(pos) -- would need power!
return techage.put_items(inv, "src", stack)
end
end,
on_unpull_item = function(pos, in_dir, stack)
local meta = minetest.get_meta(pos)
if meta:get_int("pull_dir") == in_dir then
local inv = M(pos):get_inventory()
return techage.put_items(inv, "dst", stack)
end
end,
on_recv_message = function(pos, src, topic, payload)
return CRD(pos).State:on_receive_message(pos, topic, payload)
end,
}
local _, _, node_name_ta4 =
techage.register_consumer("recycler", S("Recycler"), tiles, {
drawtype = "nodebox",
paramtype = "light",
node_box = {
type = "fixed",
fixed = {
{-8/16, -8/16, -8/16, 8/16, 8/16, -6/16},
{-8/16, -8/16, 6/16, 8/16, 8/16, 8/16},
{-8/16, -8/16, -8/16, -6/16, 8/16, 8/16},
{ 6/16, -8/16, -8/16, 8/16, 8/16, 8/16},
{-6/16, -8/16, -6/16, 6/16, 6/16, 6/16},
},
},
selection_box = {
type = "fixed",
fixed = {-8/16, -8/16, -8/16, 8/16, 8/16, 8/16},
},
cycle_time = CYCLE_TIME,
standby_ticks = STANDBY_TICKS,
formspec = formspec,
tubing = tubing,
after_place_node = function(pos, placer)
local inv = M(pos):get_inventory()
inv:set_size('src', 9)
inv:set_size('dst', 9)
end,
can_dig = can_dig,
node_timer = keep_running,
on_receive_fields = on_receive_fields,
allow_metadata_inventory_put = allow_metadata_inventory_put,
allow_metadata_inventory_move = allow_metadata_inventory_move,
allow_metadata_inventory_take = allow_metadata_inventory_take,
groups = {choppy=2, cracky=2, crumbly=2},
sounds = default.node_sound_wood_defaults(),
num_items = {0,0,0,1},
power_consumption = {0,0,0,16},
},
{false, false, false, true}) -- TA4 only
minetest.register_craft({
output = node_name_ta4,
recipe = {
{"", "default:mese_crystal", ""},
{"", "techage:ta4_grinder_pas", ""},
{"", "techage:ta4_wlanchip", ""},
},
})
-------------------------------------------------------------------------------
-- Prepare recipes
-------------------------------------------------------------------------------
-- Nodes from mods that can be recycled
local ModNames = {
techage = true,
hyperloop = true,
}
local function get_item_list(inputs)
local lst = {}
for _,input in pairs(inputs or {}) do
if SpecialItems[input] then
input = SpecialItems[input]
end
if input and input ~= "" then
if minetest.registered_nodes[input] or minetest.registered_items[input] then
table.insert(lst, input)
end
end
end
return lst
end
local function get_special_recipe(name)
if SpecialItems[name] then
return {
output = name,
items = {SpecialItems[name]}
}
end
end
local function collect_recipes()
local add = function(name, ndef)
local _, _, mod, _ = string.find(name, "([%w_]+):([%w_]+)")
local recipe = get_special_recipe(name) or
techage.recipes.get_recipe(name) or
minetest.get_craft_recipe(name)
local items = get_item_list(recipe.items)
if ModNames[mod]
and ndef.groups.not_in_creative_inventory ~= 1
and not ndef.tool_capabilities
and recipe.output
and next(items) then
local s = table.concat(items, ", ")
--print(string.format("%-36s {%s}", recipe.output, s))
Recipes[name] = {output = recipe.output, items = items}
end
end
for name, ndef in pairs(minetest.registered_nodes) do
add(name, ndef)
end
for name, ndef in pairs(minetest.registered_items) do
add(name, ndef)
end
end
minetest.after(2, collect_recipes)

View File

@ -99,12 +99,14 @@ function techage.get_node_lvm(pos)
local data = vm:get_data() local data = vm:get_data()
local param2_data = vm:get_param2_data() local param2_data = vm:get_param2_data()
local area = VoxelArea:new({MinEdge = MinEdge, MaxEdge = MaxEdge}) local area = VoxelArea:new({MinEdge = MinEdge, MaxEdge = MaxEdge})
local idx = area:index(pos.x, pos.y, pos.z) local idx = area:indexp(pos)
node = { if data[idx] and param2_data[idx] then
name = minetest.get_name_from_content_id(data[idx]), return {
param2 = param2_data[idx] name = minetest.get_name_from_content_id(data[idx]),
} param2 = param2_data[idx]
return node }
end
return {name="ignore", param2=0}
end end
-- --

View File

@ -15,7 +15,8 @@
local S = techage.S local S = techage.S
local M = minetest.get_meta local M = minetest.get_meta
local Recipes = {} -- {rtype = {ouput = {....},...}} local Recipes = {} -- {rtype = {ouput = {....},...}}
local NormalizedRecipes = {} -- {output = "", items = {...}}
local range = techage.in_range local range = techage.in_range
@ -63,12 +64,13 @@ function techage.recipes.add(rtype, recipe)
Recipes[rtype] = {} Recipes[rtype] = {}
end end
local name, num local name, num, output
local item = {input = {}} local item = {input = {}}
for idx = 1,4 do for idx = 1,4 do
local inp = recipe.input[idx] or "" local inp = recipe.input[idx] or ""
name, num = unpack(string.split(inp, " ")) name, num = unpack(string.split(inp, " "))
item.input[idx] = {name = name or "", num = tonumber(num) or 0} item.input[idx] = {name = name or "", num = tonumber(num) or 0}
name2 = name
end end
if recipe.waste then if recipe.waste then
name, num = unpack(string.split(recipe.waste, " ")) name, num = unpack(string.split(recipe.waste, " "))
@ -80,6 +82,7 @@ function techage.recipes.add(rtype, recipe)
item.output = {name = name or "", num = tonumber(num) or 0} item.output = {name = name or "", num = tonumber(num) or 0}
item.catalyst = recipe.catalyst item.catalyst = recipe.catalyst
Recipes[rtype][#Recipes[rtype]+1] = item Recipes[rtype][#Recipes[rtype]+1] = item
output = name
if minetest.global_exists("unified_inventory") then if minetest.global_exists("unified_inventory") then
unified_inventory.register_craft({ unified_inventory.register_craft({
@ -88,6 +91,10 @@ function techage.recipes.add(rtype, recipe)
type = rtype, type = rtype,
}) })
end end
NormalizedRecipes[output] = {
output = recipe.output,
items = recipe.input,
}
end end
function techage.recipes.formspec(x, y, rtype, nvm) function techage.recipes.formspec(x, y, rtype, nvm)
@ -126,3 +133,8 @@ function techage.recipes.on_receive_fields(pos, formname, fields, player)
end end
end end
end end
function techage.recipes.get_recipe(name)
return NormalizedRecipes[name]
end

View File

@ -34,7 +34,11 @@ local function plan(images)
if item ~= false then if item ~= false then
local img, tooltip = tooltip(item) local img, tooltip = tooltip(item)
local x_offs, y_offs = (x-1) * 0.9, (y-1) * 0.9 + 0.8 local x_offs, y_offs = (x-1) * 0.9, (y-1) * 0.9 + 0.8
if img == "" then if img == "top_view" then
tbl[#tbl+1] = "label["..x_offs..","..y_offs..";"..S("Top view").."]"
elseif img == "side_view" then
tbl[#tbl+1] = "label["..x_offs..","..y_offs..";"..S("Side view").."]"
elseif img == "" then
img = tooltip -- use tooltip for bigger image img = tooltip -- use tooltip for bigger image
tbl[#tbl+1] = "image["..x_offs..","..y_offs..";2.2,2.2;"..img.."]" tbl[#tbl+1] = "image["..x_offs..","..y_offs..";2.2,2.2;"..img.."]"
elseif string.find(img, ":") then elseif string.find(img, ":") then

View File

@ -176,6 +176,8 @@ techage.Items = {
ta4_electronicfab = "techage:ta4_electronic_fab_pas", ta4_electronicfab = "techage:ta4_electronic_fab_pas",
ta4_injector = "techage:ta4_injector_pas", ta4_injector = "techage:ta4_injector_pas",
ta4_liquid_filter = "techage_ta4_filter.png", ta4_liquid_filter = "techage_ta4_filter.png",
ta4_recycler = "techage:ta4_recycler_pas",
--ta4_ "", --ta4_ "",
} }

View File

@ -104,6 +104,7 @@ techage.manual_DE.aTitel = {
"3,TechAge Signallampe / Signal Lamp", "3,TechAge Signallampe / Signal Lamp",
"3,Tür/Tor Blöcke / Door/Gate Blocks", "3,Tür/Tor Blöcke / Door/Gate Blocks",
"3,TA3 Tür Controller / Door Controller", "3,TA3 Tür Controller / Door Controller",
"3,TA3 Tür Controller II / Door Controller II",
"3,TA3 Mesecons Umsetzer / TA3 Mesecons Converter", "3,TA3 Mesecons Umsetzer / TA3 Mesecons Converter",
"2,Detektoren", "2,Detektoren",
"3,TA3 Detektor / Detector", "3,TA3 Detektor / Detector",
@ -193,6 +194,7 @@ techage.manual_DE.aTitel = {
"3,TA4 Steinbrecher / Quarry", "3,TA4 Steinbrecher / Quarry",
"3,TA4 Elektronikfabrik / Electronic Fab", "3,TA4 Elektronikfabrik / Electronic Fab",
"3,TA4 Injektor / Injector", "3,TA4 Injektor / Injector",
"3,TA4 Recycler",
} }
techage.manual_DE.aText = { techage.manual_DE.aText = {
@ -680,7 +682,7 @@ techage.manual_DE.aText = {
"Der TA3 Industrieofen dient als Ergänzung zu normalen Ofen (furnace). Damit können alle Waren mit \"Koch\" Rezepten\\, auch im Industrieofen hergestellt werden. Es gibt aber auch spezielle Rezepte\\, die nur im Industrieofen hergestellt werden können.\n".. "Der TA3 Industrieofen dient als Ergänzung zu normalen Ofen (furnace). Damit können alle Waren mit \"Koch\" Rezepten\\, auch im Industrieofen hergestellt werden. Es gibt aber auch spezielle Rezepte\\, die nur im Industrieofen hergestellt werden können.\n"..
"Der Industrieofen hat sein eigenes Menü zur Rezeptauswahl. Abhängig von den Waren im Industrieofen Inventar links kann rechts das Ausgangsprodukt gewählt werden.\n".. "Der Industrieofen hat sein eigenes Menü zur Rezeptauswahl. Abhängig von den Waren im Industrieofen Inventar links kann rechts das Ausgangsprodukt gewählt werden.\n"..
"\n".. "\n"..
"Der Industrieofen benötigt Strom (für das Gebläse) sowie Öl/Benzin für den Brenner. Der Industrieofens und muss wie im Plan rechts abgebildet\\, zusammen gebaut werden.\n".. "Der Industrieofen benötigt Strom (für das Gebläse) sowie Schweröl/Benzin für den Brenner. Der Industrieofens und muss wie im Plan rechts abgebildet\\, zusammen gebaut werden.\n"..
"\n".. "\n"..
"Siehe auch TA4 Ofenheizung.\n".. "Siehe auch TA4 Ofenheizung.\n"..
"\n".. "\n"..
@ -983,11 +985,19 @@ techage.manual_DE.aText = {
"\n".. "\n"..
"\n".. "\n"..
"\n", "\n",
"Der Tür Controller II kann alle Arten von Blöcken entfernen und wieder setzen. Um den Tür Controller II anzulernen\\, muss der \"Aufzeichnen\" Button gedrückt werden. Dann müssen alle Blöcke angeklickt werden\\, die Teil der Tür / des Tores sein sollen. Danach muss der \"Fertig\" Button gedrückt werden. Es können bis zu 16 Blöcke ausgewählt werden. Die entfernten Blöcke werden im Inventar des Controllers gespeichert. Über die Tasten \"Entfernen\" bzw. \"Setzen\" kann die Funktion des Controllers von Hand getestet werden.\n"..
"\n"..
"Wird ein 'on' / 'off' Kommando an den Tür Controller II gesendet\\, entfernt bzw. setzt er die Blöcke ebenfalls.\n"..
"\n"..
"\n"..
"\n",
"Der Mesecons Umsetzer dient zur Umwandlung von Techage on/off Kommandos in Mesecons Signale und umgekehrt.\n".. "Der Mesecons Umsetzer dient zur Umwandlung von Techage on/off Kommandos in Mesecons Signale und umgekehrt.\n"..
"Dazu müssen eine oder mehrere Knotennummern eingegeben und der Konverter mit Mesecons Blöcken \n".. "Dazu müssen eine oder mehrere Knotennummern eingegeben und der Konverter mit Mesecons Blöcken \n"..
"über Mesecons Leitungen verbunden werden. Den Mesecons Umsetzer kann man auch mit dem Programmer konfigurieren.\n".. "über Mesecons Leitungen verbunden werden. Den Mesecons Umsetzer kann man auch mit dem Programmer konfigurieren.\n"..
"Der Mesecons Umsetzer akzeptiert bis zu 5 Kommandos pro Sekunde\\, bei höherer Belastung schaltet er sich ab.\n".. "Der Mesecons Umsetzer akzeptiert bis zu 5 Kommandos pro Sekunde\\, bei höherer Belastung schaltet er sich ab.\n"..
"\n".. "\n"..
"*Dieser Block existiert aber nur\\, wenn die Mod mesecons aktiv ist!*\n"..
"\n"..
"\n".. "\n"..
"\n", "\n",
"Detektoren scannen ihre Umgebung ab und senden ein 'on'-Kommando\\, wenn das Gesuchte erkannt wurde.\n".. "Detektoren scannen ihre Umgebung ab und senden ein 'on'-Kommando\\, wenn das Gesuchte erkannt wurde.\n"..
@ -1571,6 +1581,18 @@ techage.manual_DE.aText = {
"\n".. "\n"..
"\n".. "\n"..
"\n", "\n",
"Der Recycler ist eine Maschine\\, die alle Techage Rezepte rückwärts abarbeitet\\, also Maschinen und Blöcke wieder in die Bestandteile zerlegen kann. Die Maschine kann so ziemlich alle Techage und Hyperloop Blöcke zerlegen.\n"..
"Aber nicht alle Materialen lassen sich recyclen:\n"..
"\n"..
" - Holz wird zu Sticks\n"..
" - Stein wird zu Sand oder Kies\n"..
" - Halbleiter/Chips können nicht recycelt werden\n"..
" - Werkzeuge können nicht recycelt werden\n"..
"\n"..
"Die Verarbeitungsleistung beträgt ein Item alle 8 s. Der Block benötigt hierfür 16 ku Strom.\n"..
"\n"..
"\n"..
"\n",
} }
techage.manual_DE.aItemName = { techage.manual_DE.aItemName = {
@ -1677,6 +1699,7 @@ techage.manual_DE.aItemName = {
"ta3_signallamp", "ta3_signallamp",
"ta3_doorblock", "ta3_doorblock",
"ta3_doorcontroller", "ta3_doorcontroller",
"ta3_doorcontroller",
"ta3_mesecons_converter", "ta3_mesecons_converter",
"ta3_nodedetector", "ta3_nodedetector",
"ta3_detector", "ta3_detector",
@ -1766,6 +1789,7 @@ techage.manual_DE.aItemName = {
"ta4_quarry", "ta4_quarry",
"ta4_electronicfab", "ta4_electronicfab",
"ta4_injector", "ta4_injector",
"ta4_recycler",
} }
techage.manual_DE.aPlanTable = { techage.manual_DE.aPlanTable = {
@ -1894,6 +1918,7 @@ techage.manual_DE.aPlanTable = {
"", "",
"", "",
"", "",
"",
"ta4_windturbine", "ta4_windturbine",
"", "",
"", "",
@ -1961,5 +1986,6 @@ techage.manual_DE.aPlanTable = {
"", "",
"", "",
"", "",
"",
} }

View File

@ -103,6 +103,7 @@ techage.manual_EN.aTitel = {
"3,TechAge Signal Lamp", "3,TechAge Signal Lamp",
"3,Door/Gate Blocks", "3,Door/Gate Blocks",
"3,TA3 Door Controller", "3,TA3 Door Controller",
"3,TA3 Door Controller II",
"3,TA3 Mesecons Converter", "3,TA3 Mesecons Converter",
"2,Detectors", "2,Detectors",
"3,TA3 Detector", "3,TA3 Detector",
@ -192,6 +193,7 @@ techage.manual_EN.aTitel = {
"3,TA4 Quarry", "3,TA4 Quarry",
"3,TA4 Electronic Fab", "3,TA4 Electronic Fab",
"3,TA4 Injector", "3,TA4 Injector",
"3,TA4 recycler",
} }
techage.manual_EN.aText = { techage.manual_EN.aText = {
@ -671,7 +673,7 @@ techage.manual_EN.aText = {
"The TA3 industrial furnace serves as a supplement to normal furnaces. This means that all goods can be produced with \"cooking\" recipes\\, even in an industrial furnace. But there are also special recipes that can only be made in an industrial furnace.\n".. "The TA3 industrial furnace serves as a supplement to normal furnaces. This means that all goods can be produced with \"cooking\" recipes\\, even in an industrial furnace. But there are also special recipes that can only be made in an industrial furnace.\n"..
"The industrial furnace has its own menu for recipe selection. Depending on the goods in the industrial furnace inventory on the left\\, the output product can be selected on the right.\n".. "The industrial furnace has its own menu for recipe selection. Depending on the goods in the industrial furnace inventory on the left\\, the output product can be selected on the right.\n"..
"\n".. "\n"..
"The industrial furnace requires electricity (for the fan) and oil / gasoline for the burner. The industrial furnace and must be assembled as shown in the plan on the right.\n".. "The industrial furnace requires electricity (for the fan) and fuel oil / gasoline for the burner. The industrial furnace and must be assembled as shown in the plan on the right.\n"..
"\n".. "\n"..
"See also TA4 heater.\n".. "See also TA4 heater.\n"..
"\n".. "\n"..
@ -974,11 +976,17 @@ techage.manual_EN.aText = {
"\n".. "\n"..
"\n".. "\n"..
"\n", "\n",
"The Door Controller II can remove and set all types of blocks. To teach in the Door Controller II\\, the \"Record\" button must be pressed. Then all blocks that should be part of the door / gate must be clicked. Then the \"Done\" button must be pressed. Up to 16 blocks can be selected. The removed blocks are saved in the controller's inventory. The function of the controller can be tested manually using the \"Remove\" or \"Set\" buttons. If an 'on' /'off' command is sent to the Door Controller II\\, it removes or sets the blocks as well.\n"..
"\n"..
"\n"..
"\n",
"The Mesecons converter is used to convert Techage on/off commands into Mesecons signals and vice versa.\n".. "The Mesecons converter is used to convert Techage on/off commands into Mesecons signals and vice versa.\n"..
"To do this\\, one or more node numbers must be entered and the converter with Mesecons blocks\n".. "To do this\\, one or more node numbers must be entered and the converter with Mesecons blocks\n"..
"has to be connected via Mesecons cables. The Mesecons converter can also be configured with the programmer.\n".. "has to be connected via Mesecons cables. The Mesecons converter can also be configured with the programmer.\n"..
"The Mesecons converter accepts up to 5 commands per second\\; it switches itself off at higher loads.\n".. "The Mesecons converter accepts up to 5 commands per second\\; it switches itself off at higher loads.\n"..
"\n".. "\n"..
"*This node only exists if the mod mesecons is active!*\n"..
"\n"..
"\n".. "\n"..
"\n", "\n",
"Detectors scan their surroundings and send an 'on' command when the search is recognized.\n".. "Detectors scan their surroundings and send an 'on' command when the search is recognized.\n"..
@ -1555,6 +1563,19 @@ techage.manual_EN.aText = {
"\n".. "\n"..
"\n".. "\n"..
"\n", "\n",
"The recycler is a machine that processes all Techage recipes backwards\\, i.e. it can dismantle machines and blocks back into their components. \n"..
"\n"..
"The machine can disassemble pretty much any Techage and Hyperloop blocks. But not all materials can be recycled:\n"..
"\n"..
" - Wood turns into sticks\n"..
" - Stone turns into sand or gravel\n"..
" - Semiconductors / chips cannot be recycled\n"..
" - Tools cannot be recycled\n"..
"\n"..
"The processing power is one item every 8 s. The block requires 16 ku of electricity for this.\n"..
"\n"..
" \n"..
"\n",
} }
techage.manual_EN.aItemName = { techage.manual_EN.aItemName = {
@ -1660,6 +1681,7 @@ techage.manual_EN.aItemName = {
"ta3_signallamp", "ta3_signallamp",
"ta3_doorblock", "ta3_doorblock",
"ta3_doorcontroller", "ta3_doorcontroller",
"ta3_doorcontroller",
"ta3_mesecons_converter", "ta3_mesecons_converter",
"ta3_nodedetector", "ta3_nodedetector",
"ta3_detector", "ta3_detector",
@ -1749,6 +1771,7 @@ techage.manual_EN.aItemName = {
"ta4_quarry", "ta4_quarry",
"ta4_electronicfab", "ta4_electronicfab",
"ta4_injector", "ta4_injector",
"ta4_recycler",
} }
techage.manual_EN.aPlanTable = { techage.manual_EN.aPlanTable = {
@ -1876,6 +1899,7 @@ techage.manual_EN.aPlanTable = {
"", "",
"", "",
"", "",
"",
"ta4_windturbine", "ta4_windturbine",
"", "",
"", "",
@ -1943,5 +1967,6 @@ techage.manual_EN.aPlanTable = {
"", "",
"", "",
"", "",
"",
} }

View File

@ -25,6 +25,9 @@ local IMG42 = {"", "techage_ta4_solar.png"}
local IMG43 = {"", "techage_reactor_inv.png"} local IMG43 = {"", "techage_reactor_inv.png"}
local IMG44 = {"", "techage_ta4_filter.png"} local IMG44 = {"", "techage_ta4_filter.png"}
local TOP_V = {"top_view", ""}
local SIDEV = {"side_view", ""}
-- --
-- TA1: Coal Pile -- TA1: Coal Pile
-- --
@ -33,11 +36,14 @@ local DWOOD = {"default_wood.png" , "default:wood"}
local LIGTR = {"techage_lighter.png", "techage:lighter"} local LIGTR = {"techage_lighter.png", "techage:lighter"}
techage.ConstructionPlans["coalpile"] = { techage.ConstructionPlans["coalpile"] = {
{DDIRT, DDIRT, DDIRT, DDIRT, DDIRT}, {false, false, SIDEV, false, false, false, false, false, TOP_V, false, false},
{DDIRT, DWOOD, DWOOD, DWOOD, DDIRT}, {false, false, false, false, false, false, false, false, false, false, false},
{DDIRT, DWOOD, DWOOD, DWOOD, DDIRT}, {DDIRT, DDIRT, DDIRT, DDIRT, DDIRT, false, DDIRT, DDIRT, DDIRT, DDIRT, DDIRT},
{DDIRT, DWOOD, LIGTR, DWOOD, DDIRT}, {DDIRT, DWOOD, DWOOD, DWOOD, DDIRT, false, DDIRT, DWOOD, DWOOD, DWOOD, DDIRT},
{DDIRT, DDIRT, DDIRT, DDIRT, DDIRT}, {DDIRT, DWOOD, DWOOD, DWOOD, DDIRT, false, DDIRT, DWOOD, LIGTR, DWOOD, DDIRT},
{DDIRT, DWOOD, LIGTR, DWOOD, DDIRT, false, DDIRT, DWOOD, DWOOD, DWOOD, DDIRT},
{DDIRT, DDIRT, DDIRT, DDIRT, DDIRT, false, DDIRT, DDIRT, DDIRT, DDIRT, DDIRT},
{false, false, false, false, false, false, false, false, false, false, false},
} }
-- --
@ -49,6 +55,7 @@ local MEPOT = {"default_cobble.png^techage_meltingpot.png", "techage:meltingpot"
local FLAME = {"techage_flame.png", nil} local FLAME = {"techage_flame.png", nil}
techage.ConstructionPlans["coalburner"] = { techage.ConstructionPlans["coalburner"] = {
{false, false, SIDEV, false, false, false, false},
{false, false, MEPOT, false, false, IMG_1, false}, {false, false, MEPOT, false, false, IMG_1, false},
{false, false, FLAME, false}, {false, false, FLAME, false},
{false, COBBL, CCOAL, COBBL}, {false, COBBL, CCOAL, COBBL},
@ -119,15 +126,21 @@ techage.ConstructionPlans["itemtransport"] = {
local RINSR = {"techage_filling_ta2.png^techage_appl_rinser.png^techage_frame_ta2.png", "techage:ta2_rinser_pas"} local RINSR = {"techage_filling_ta2.png^techage_appl_rinser.png^techage_frame_ta2.png", "techage:ta2_rinser_pas"}
local GLASS = {"default_glass.png", "default:glass"} local GLASS = {"default_glass.png", "default:glass"}
local WATER = {"default_water.png^default_glass.png", "default:water_source"} local WATER = {"default_water.png^default_glass.png", "default:water_source"}
local WATR2 = {"default_water.png", "default:water_source"}
local TK000 = {"techage_tube_knee.png", "techage:tubeS"} -- like 'r' local TK000 = {"techage_tube_knee.png", "techage:tubeS"} -- like 'r'
local TK090 = {"techage_tube_knee.png^[transformR90", "techage:tubeS"} -- '7' local TK090 = {"techage_tube_knee.png^[transformR90", "techage:tubeS"} -- '7'
local TK180 = {"techage_tube_knee.png^[transformR180", "techage:tubeS"} local TK180 = {"techage_tube_knee.png^[transformR180", "techage:tubeS"}
local TK270 = {"techage_tube_knee.png^[transformR270", "techage:tubeS"} local TK270 = {"techage_tube_knee.png^[transformR270", "techage:tubeS"}
techage.ConstructionPlans["gravelrinser"] = { techage.ConstructionPlans["gravelrinser"] = {
{false, false, false, false, false, false, false, false}, {false, false, false, SIDEV, false, false, false, false},
{false, GLASS, WATER, GLASS, GLASS, GLASS, GLASS, GLASS}, {false, GLASS, WATER, GLASS, GLASS, GLASS, GLASS, GLASS},
{false, DDIRT, DDIRT, TK000, RINSR, TK270, HOPPR, CHEST}, {false, DDIRT, DDIRT, TK000, RINSR, TK270, HOPPR, CHEST},
{false, false, false, false, false, false, false, false},
{false, false, false, TOP_V, false, false, false, false},
{false, GLASS, GLASS, GLASS, GLASS, GLASS, GLASS, GLASS},
{false, GLASS, WATR2, TK000, RINSR, TK270, HOPPR, GLASS},
{false, GLASS, GLASS, GLASS, GLASS, GLASS, GLASS, GLASS},
} }
-- --
@ -183,6 +196,7 @@ local PN180 = {"techage_gaspipe_knee.png^[transformR180", "techage:ta4_pipeS"}
local PN270 = {"techage_gaspipe_knee.png^[transformR270", "techage:ta4_pipeS"} -- 7 local PN270 = {"techage_gaspipe_knee.png^[transformR270", "techage:ta4_pipeS"} -- 7
techage.ConstructionPlans["ta3_tank"] = { techage.ConstructionPlans["ta3_tank"] = {
{false, false, false, false, SIDEV, false, false, false, false, false},
{false, false, false, false, false, false, false, false, false, false}, {false, false, false, false, false, false, false, false, false, false},
{false, Tubes, PushR, Tubes, Fillr, Tubes, PushR, Tubes, false, false}, {false, Tubes, PushR, Tubes, Fillr, Tubes, PushR, Tubes, false, false},
{false, false, false, false, TANK3, PIPEH, PIPEH, Pump, PIPEH, false}, {false, false, false, false, TANK3, PIPEH, PIPEH, Pump, PIPEH, false},
@ -204,13 +218,13 @@ local CRAIL = {"carts_rail_curved.png^[transformR90", "carts:rail"}
local BUFFR = {"default_junglewood.png^minecart_buffer.png", "minecart:buffer"} local BUFFR = {"default_junglewood.png^minecart_buffer.png", "minecart:buffer"}
techage.ConstructionPlans["ta3_loading"] = { techage.ConstructionPlans["ta3_loading"] = {
{false, false, PIPEH, Pump, PIPEH, PN270, false, false, false, false, false}, {false, false, PIPEH, Pump, PIPEH, PN270, SIDEV, false, false, false, false},
{false, false, false, false, false, PIPEV, false, false, false, false, false}, {false, false, false, false, false, PIPEV, false, false, false, false, false},
{false, MCART, false, false, false, PN090, TANK3, false, false, false, false}, {false, MCART, false, false, false, PN090, TANK3, false, false, false, false},
{false, HOPPR, CHEST, Tubes, PushR, Tubes, Fillr, PushR, Tubes, MCART, false}, {false, HOPPR, CHEST, Tubes, PushR, Tubes, Fillr, PushR, Tubes, MCART, false},
{false, false, false, false, false, false, false, false, false, false, false}, {false, false, false, false, false, false, false, false, false, false, false},
{false, false, false, false, false, false, false, false, false, false, false}, {false, false, false, false, false, false, false, false, false, false, false},
{false, BUFFR, false, false, false, false, false, false, false, BUFFR, false}, {false, BUFFR, false, false, false, TOP_V, false, false, false, BUFFR, false},
{false, PRAIL, false, false, false, false, false, false, false, PRAIL, false}, {false, PRAIL, false, false, false, false, false, false, false, PRAIL, false},
{false, CRAIL, RAILH, PRAIH, RAILH, RAILH, PRAIH, RAILH, RAILH, TRAIL, RAILH}, {false, CRAIL, RAILH, PRAIH, RAILH, RAILH, PRAIH, RAILH, RAILH, TRAIL, RAILH},
} }
@ -227,7 +241,7 @@ local DBASE = {"techage_concrete.png", "techage:ta3_distiller_base"}
local REBIO = {"techage_filling_ta3.png^techage_appl_reboiler.png^techage_frame_ta3.png", "techage:ta3_reboiler"} local REBIO = {"techage_filling_ta3.png^techage_appl_reboiler.png^techage_frame_ta3.png", "techage:ta3_reboiler"}
techage.ConstructionPlans["ta3_distiller"] = { techage.ConstructionPlans["ta3_distiller"] = {
{false, false, false, false, false, false, false, PN000, PIPEH, TANK3, false}, {false, false, false, false, false, SIDEV, false, PN000, PIPEH, TANK3, false},
{false, IMG31, false, false, false, false, false, DIST4, false, false, false}, {false, IMG31, false, false, false, false, false, DIST4, false, false, false},
{false, false, false, false, false, false, false, DIST3, PIPEH, TANK3, false}, {false, false, false, false, false, false, false, DIST3, PIPEH, TANK3, false},
{false, false, false, false, false, false, false, DIST2, false, false, false}, {false, false, false, false, false, false, false, DIST2, false, false, false},
@ -250,13 +264,13 @@ local DOSER = {"techage_filling_ta4.png^techage_frame_ta4.png^techage_appl_pump_
local SILO = {"techage_filling_ta3.png^techage_frame_ta3.png^techage_appl_silo.png", "techage:ta3_silo"} local SILO = {"techage_filling_ta3.png^techage_frame_ta3.png^techage_appl_silo.png", "techage:ta3_silo"}
techage.ConstructionPlans["ta4_reactor"] = { techage.ConstructionPlans["ta4_reactor"] = {
{false, false, false, false, false, false, false, false, false, false, false}, {false, false, false, false, false, false, SIDEV, false, false, false, false},
{false, IMG43, false, false, false, false, false, false, false, false, false}, {false, IMG43, false, false, false, false, false, false, false, false, false},
{false, false, false, false, PN000, PIPEH, PIPEH, PN270, false, false, false}, {false, false, false, false, PN000, PIPEH, PIPEH, PN270, false, false, false},
{false, false, false, false, PIPEV, false, false, FILLR, false, false, false}, {false, false, false, false, PIPEV, false, false, FILLR, false, false, false},
{false, false, false, false, PIPEV, false, false, REACT, false, false, false}, {false, false, false, false, PIPEV, false, false, REACT, false, false, false},
{false, false, false, false, PIPEV, false, false, STAND, PIPEH, PIPEH, SILO}, {false, false, false, false, PIPEV, false, false, STAND, PIPEH, PIPEH, SILO},
{false, TANK3, PIPEH, PIPEH, DOSER, PN270, false, RBASE, PIPEH, PIPEH, Tank}, {false, TANK3, PIPEH, PIPEH, DOSER, PN270, false, RBASE, PIPEH, PIPEH, TANK3},
{false, SILO, PIPEH, PIPEH, PIPEH, PN180, false, false, false, false, false}, {false, SILO, PIPEH, PIPEH, PIPEH, PN180, false, false, false, false, false},
} }
@ -269,6 +283,7 @@ local PILLR = {"techage:pillar", "techage:pillar"}
local SLAMP = {"techage:rotor_signal_lamp_off", "techage:rotor_signal_lamp_off"} local SLAMP = {"techage:rotor_signal_lamp_off", "techage:rotor_signal_lamp_off"}
techage.ConstructionPlans["ta4_windturbine"] = { techage.ConstructionPlans["ta4_windturbine"] = {
{false, false, false, SIDEV, false, false, false},
{false, false, false, SLAMP, false, false, IMG_4, false}, {false, false, false, SLAMP, false, false, IMG_4, false},
{false, false, false, ROTOR, NCLLE, false, false}, {false, false, false, ROTOR, NCLLE, false, false},
{false, false, false, PILLR, false, false, false}, {false, false, false, PILLR, false, false, false},
@ -294,14 +309,14 @@ local INLET = {"basic_materials_concrete_block.png^techage_gaspipe.png^[transfor
local OGLAS = {"default_obsidian_glass.png", "default:obsidian_glass"} local OGLAS = {"default_obsidian_glass.png", "default:obsidian_glass"}
techage.ConstructionPlans["ta4_storagesystem"] = { techage.ConstructionPlans["ta4_storagesystem"] = {
{false, false, false, false, false, false, false, false, false, IMG41, false}, {false, false, TOP_V, false, false, false, false, SIDEV, false, IMG41, false},
{false, false, false, PN000, PIPEH, PIPEH, PN270, false, false, false, false}, {false, false, PN000, PIPEH, PIPEH, PIPEH, PN270, false, false, false, false},
{false, CONCR, CONCR, INLET, CONCR, CONCR, PIPEV, false, false, false, false}, {CONCR, CONCR, INLET, CONCR, CONCR, false, PIPEV, false, false, false, false},
{false, CONCR, GRAVL, GRAVL, GRAVL, CONCR, PN090, HEXR1, PIPEH, PN270, false}, {CONCR, GRAVL, GRAVL, GRAVL, CONCR, false, PN090, HEXR1, PIPEH, PN270, false},
{false, OGLAS, GRAVL, GRAVL, GRAVL, CONCR, false, HEXR2, false, PIPEV, false}, {OGLAS, GRAVL, GRAVL, GRAVL, CONCR, false, false, HEXR2, false, PIPEV, false},
{false, CONCR, GRAVL, GRAVL, GRAVL, CONCR, PN000, HEXR3, PIPEH, TURBN, GENER}, {CONCR, GRAVL, GRAVL, GRAVL, CONCR, false, PN000, HEXR3, PIPEH, TURBN, GENER},
{false, CONCR, CONCR, INLET, CONCR, CONCR, PIPEV, false, false, false, false}, {CONCR, CONCR, INLET, CONCR, CONCR, false, PIPEV, false, false, false, false},
{false, false, false, PN090, PIPEH, PIPEH, PN180, false, false, false, false}, {false, false, PN090, PIPEH, PIPEH, PIPEH, PN180, false, false, false, false},
} }
-- --
@ -315,7 +330,7 @@ local INVAC = {"techage_filling_ta4.png^techage_frame_ta4.png^techage_appl_inver
techage.ConstructionPlans["ta4_solarplant"] = { techage.ConstructionPlans["ta4_solarplant"] = {
{false, false, false, false, false, false, false, false, false, IMG42, false}, {false, false, false, false, false, false, false, false, false, IMG42, false},
{false, false, false, false, false, false, false, false, false, false, false}, {false, false, TOP_V, false, false, false, false, false, false, false, false},
{false, false, false, false, false, false, false, false, false, false, false}, {false, false, false, false, false, false, false, false, false, false, false},
{false, SOLAR, SOLAR, SOLAR}, {false, SOLAR, SOLAR, SOLAR},
{false, CARRI, CARRI, CARRI, RCBLE, RCBLE, RCBLE, INVAC, Cable}, {false, CARRI, CARRI, CARRI, RCBLE, RCBLE, RCBLE, INVAC, Cable},
@ -334,7 +349,7 @@ local LFFIL = {"basic_materials_concrete_block.png^techage_gaspipe_hole.png", "t
techage.ConstructionPlans["ta4_liquid_filter_base"] = { techage.ConstructionPlans["ta4_liquid_filter_base"] = {
{false, false, false, false, false, false, false, false, IMG44, false}, {false, false, false, false, false, false, false, false, IMG44, false},
{false, false, false, false, false, false, false, false, false, false}, {false, false, false, TOP_V, false, false, false, false, false, false},
{false, false, false, false, false, false, false, false, false, false}, {false, false, false, false, false, false, false, false, false, false},
{false, CONCR, CONCR, CONCR, CONCR, CONCR}, {false, CONCR, CONCR, CONCR, CONCR, CONCR},
{false, CONCR, CONCR, CONCR, CONCR, CONCR}, {false, CONCR, CONCR, CONCR, CONCR, CONCR},
@ -345,7 +360,7 @@ techage.ConstructionPlans["ta4_liquid_filter_base"] = {
techage.ConstructionPlans["ta4_liquid_filter_gravel"] = { techage.ConstructionPlans["ta4_liquid_filter_gravel"] = {
{false, false, false, false, false, false, false, false, IMG44, false}, {false, false, false, false, false, false, false, false, IMG44, false},
{false, false, false, false, false, false, false, false, false, false}, {false, false, false, TOP_V, false, false, false, false, false, false},
{false, false, false, false, false, false, false, false, false, false}, {false, false, false, false, false, false, false, false, false, false},
{false, CONCR, OGLAS, OGLAS, OGLAS, CONCR}, {false, CONCR, OGLAS, OGLAS, OGLAS, CONCR},
{false, OGLAS, GRAVL, GRAVL, GRAVL, OGLAS}, {false, OGLAS, GRAVL, GRAVL, GRAVL, OGLAS},
@ -356,7 +371,7 @@ techage.ConstructionPlans["ta4_liquid_filter_gravel"] = {
techage.ConstructionPlans["ta4_liquid_filter_top"] = { techage.ConstructionPlans["ta4_liquid_filter_top"] = {
{false, false, false, false, false, false, false, false, IMG44, false}, {false, false, false, false, false, false, false, false, IMG44, false},
{false, false, false, false, false, false, false, false, false, false}, {false, false, false, TOP_V, false, false, false, false, false, false},
{false, false, false, false, false, false, false, false, false, false}, {false, false, false, false, false, false, false, false, false, false},
{false, CONCR, CONCR, CONCR, CONCR, CONCR}, {false, CONCR, CONCR, CONCR, CONCR, CONCR},
{false, CONCR, false, false, false, CONCR}, {false, CONCR, false, false, false, CONCR},
@ -369,4 +384,4 @@ function techage.add_manual_plans(table_with_plans)
for name, tbl in pairs(table_with_plans) do for name, tbl in pairs(table_with_plans) do
techage.ConstructionPlans[name] = tbl techage.ConstructionPlans[name] = tbl
end end
end end

View File

@ -73,21 +73,46 @@ local function chat(owner, text)
return text return text
end end
local function get_radius(pos, in_dir) local function get_diameter(pos, in_dir)
local dir = tubelib2.Dir6dToVector[in_dir] local dir = tubelib2.Dir6dToVector[in_dir]
local pos2 = vector.add(pos, vector.multiply(dir, 8)) local pos2, node
local poses = minetest.find_nodes_in_area(pos, pos2, {"techage:ta4_pipe_inlet"})
if #poses == 2 then pos2 = vector.add(pos, vector.multiply(dir, 4))
local radius = vector.distance(poses[1], poses[2]) / 2 node = minetest.get_node(pos2)
if radius == 2 or radius == 3 or radius == 4 then if node.name == "techage:ta3_pipe_wall_entry" then
return radius return
end end
if node.name == "techage:ta4_pipe_inlet" then
return 5
end
pos2 = vector.add(pos, vector.multiply(dir, 6))
node = minetest.get_node(pos2)
if node.name == "techage:ta3_pipe_wall_entry" then
return
end
if node.name == "techage:ta4_pipe_inlet" then
return 7
end
pos2 = vector.add(pos, vector.multiply(dir, 8))
node = minetest.get_node(pos2)
if node.name == "techage:ta3_pipe_wall_entry" then
return
end
if node.name == "techage:ta4_pipe_inlet" then
return 9
end
pos2 = vector.add(pos, vector.multiply(dir, 10))
local poses = minetest.find_nodes_in_area(pos, pos2, {"techage:ta4_pipe_inlet"})
if #poses > 1 then
return vector.distance(pos, poses[2]) + 1
end end
return 1
end end
local function check_volume(pos, in_dir, owner) local function check_volume(pos, in_dir, owner)
local radius = get_radius(pos, in_dir) local radius = (get_diameter(pos, in_dir) - 1) / 2
if radius then if radius then
local dir = tubelib2.Dir6dToVector[in_dir] local dir = tubelib2.Dir6dToVector[in_dir]
local cpos = vector.add(pos, vector.multiply(dir, radius)) local cpos = vector.add(pos, vector.multiply(dir, radius))
@ -113,7 +138,7 @@ end
-- provide position behind the obsidian_glass -- provide position behind the obsidian_glass
local function check_window(pos, in_dir) local function check_window(pos, in_dir)
local radius = get_radius(pos, in_dir) local radius = (get_diameter(pos, in_dir) - 1) / 2
if radius then if radius then
local dir = tubelib2.Dir6dToVector[in_dir] local dir = tubelib2.Dir6dToVector[in_dir]
local cpos = vector.add(pos, vector.multiply(dir, radius)) local cpos = vector.add(pos, vector.multiply(dir, radius))
@ -134,7 +159,7 @@ end
techage.register_node({"techage:ta4_pipe_inlet"}, { techage.register_node({"techage:ta4_pipe_inlet"}, {
on_transfer = function(pos, in_dir, topic, payload) on_transfer = function(pos, in_dir, topic, payload)
if topic == "diameter" then if topic == "diameter" then
return get_radius(pos, in_dir) * 2 - 1 return get_diameter(pos, in_dir)
elseif topic == "integrity" then elseif topic == "integrity" then
return check_volume(pos, in_dir, payload) return check_volume(pos, in_dir, payload)
elseif topic == "volume" then elseif topic == "volume" then

View File

@ -744,3 +744,52 @@ techage.icta_register_action("set_filter", {
end end
end, end,
}) })
techage.icta_register_condition("get_filter", {
title = "read state of a Distributor filter slot",
formspec = {
{
type = "number",
name = "number",
label = "distri number",
default = "",
},
{
type = "textlist",
name = "color",
label = "filter port",
choices = "red,green,blue,yellow",
default = "red",
},
{
type = "textlist",
name = "operand",
choices = "is,is not",
default = "is",
},
{
type = "textlist",
name = "value",
label = "state",
choices = "on,off",
default = "off",
},
{
type = "label",
name = "lbl",
label = "Read state of a Distributor filter slot.\n",
},
},
button = function(data, environ) -- default button label
return 'fltr('..techage.fmt_number(data.number)..","..data.color..' '..data.operand..' '..data.value..')'
end,
code = function(data, environ)
local condition = function(env, idx)
return techage.send_single(environ.number, data.number, "port", data.color)
end
local result = function(val)
return techage.compare(val, data.value, data.operand)
end
return condition, result
end,
})

View File

@ -64,7 +64,7 @@ function techage.display.on_timer(pos)
if mem.ticks > 0 then if mem.ticks > 0 then
local node = minetest.get_node(pos) local node = minetest.get_node(pos)
-- check if display is loaded and a player in front of the display -- check if display is loaded and a player in front of the display
if node.name == "techage:ta4_display" or node.name == "techage:ta4_displayXL" then if node.name ~= "ignore" then
local dir = minetest.facedir_to_dir(Param2ToFacedir[node.param2 % 6]) local dir = minetest.facedir_to_dir(Param2ToFacedir[node.param2 % 6])
local pos2 = vector.add(pos, vector.multiply(dir, RADIUS)) local pos2 = vector.add(pos, vector.multiply(dir, RADIUS))
for _, obj in pairs(minetest.get_objects_inside_radius(pos2, RADIUS)) do for _, obj in pairs(minetest.get_objects_inside_radius(pos2, RADIUS)) do
@ -205,7 +205,7 @@ function techage.display.add_line(pos, payload, cycle_time)
while #nvm.text >= NUM_ROWS do while #nvm.text >= NUM_ROWS do
table.remove(nvm.text, 1) table.remove(nvm.text, 1)
end end
table.insert(nvm.text, payload) table.insert(nvm.text, str)
end end
function techage.display.write_row(pos, payload, cycle_time) function techage.display.write_row(pos, payload, cycle_time)

View File

@ -159,6 +159,8 @@ dofile(MP.."/basic_machines/liquidsampler.lua")
dofile(MP.."/basic_machines/quarry.lua") dofile(MP.."/basic_machines/quarry.lua")
dofile(MP.."/basic_machines/ta4_chest.lua") dofile(MP.."/basic_machines/ta4_chest.lua")
dofile(MP.."/basic_machines/ta4_injector.lua") dofile(MP.."/basic_machines/ta4_injector.lua")
dofile(MP.."/basic_machines/itemsource.lua")
dofile(MP.."/basic_machines/recycler.lua")
-- Liquids II -- Liquids II
dofile(MP.."/liquids/tank.lua") dofile(MP.."/liquids/tank.lua")
@ -242,6 +244,7 @@ dofile(MP.."/logic/cart_detector.lua")
dofile(MP.."/logic/gateblock.lua") dofile(MP.."/logic/gateblock.lua")
dofile(MP.."/logic/doorblock.lua") dofile(MP.."/logic/doorblock.lua")
dofile(MP.."/logic/doorcontroller.lua") dofile(MP.."/logic/doorcontroller.lua")
dofile(MP.."/logic/doorcontroller2.lua")
dofile(MP.."/logic/collector.lua") dofile(MP.."/logic/collector.lua")
if minetest.global_exists("mesecon") then if minetest.global_exists("mesecon") then
dofile(MP.."/logic/mesecons_converter.lua") dofile(MP.."/logic/mesecons_converter.lua")

View File

@ -17,24 +17,6 @@ local S = techage.S
local COAL_BURN_TIME = 1200 local COAL_BURN_TIME = 1200
local CYCLE_TIME = 5 local CYCLE_TIME = 5
local function get_node_lvm(pos)
local node = minetest.get_node_or_nil(pos)
if node then
return node
end
local vm = minetest.get_voxel_manip()
local MinEdge, MaxEdge = vm:read_from_map(pos, pos)
local data = vm:get_data()
local param2_data = vm:get_param2_data()
local area = VoxelArea:new({MinEdge = MinEdge, MaxEdge = MaxEdge})
local idx = area:indexp(pos)
node = {
name = minetest.get_name_from_content_id(data[idx]),
param2 = param2_data[idx]
}
return node
end
local function num_coal(pos) local function num_coal(pos)
local pos1 = {x=pos.x, y=pos.y+1, z=pos.z} local pos1 = {x=pos.x, y=pos.y+1, z=pos.z}
local pos2 = {x=pos.x, y=pos.y+32, z=pos.z} local pos2 = {x=pos.x, y=pos.y+32, z=pos.z}
@ -77,7 +59,7 @@ local function remove_flame(pos, height)
pos = {x=pos.x, y=pos.y+height, z=pos.z} pos = {x=pos.x, y=pos.y+height, z=pos.z}
for idx=height,1,-1 do for idx=height,1,-1 do
pos = {x=pos.x, y=pos.y+1, z=pos.z} pos = {x=pos.x, y=pos.y+1, z=pos.z}
local node = get_node_lvm(pos) local node = techage.get_node_lvm(pos)
if string.find(node.name, "techage:flame") then if string.find(node.name, "techage:flame") then
minetest.remove_node(pos) minetest.remove_node(pos)
elseif node.name == "techage:meltingpot" then elseif node.name == "techage:meltingpot" then
@ -102,7 +84,7 @@ local function flame(pos, height, heat, first_time)
for idx=heat,1,-1 do for idx=heat,1,-1 do
pos = {x=pos.x, y=pos.y+1, z=pos.z} pos = {x=pos.x, y=pos.y+1, z=pos.z}
idx = math.min(idx, 12) idx = math.min(idx, 12)
local node = get_node_lvm(pos) local node = techage.get_node_lvm(pos)
if node.name == "techage:meltingpot_active" or node.name == "ignore" then if node.name == "techage:meltingpot_active" or node.name == "ignore" then
return return
end end
@ -144,7 +126,7 @@ for idx,ratio in ipairs(lRatio) do
after_destruct = function(pos, oldnode) after_destruct = function(pos, oldnode)
pos.y = pos.y + 1 pos.y = pos.y + 1
local node = get_node_lvm(pos) local node = techage.get_node_lvm(pos)
if minetest.get_item_group(node.name, "techage_flame") > 0 then if minetest.get_item_group(node.name, "techage_flame") > 0 then
minetest.remove_node(pos) minetest.remove_node(pos)
end end

View File

@ -128,11 +128,11 @@ for idx = 0,3 do
minetest.register_node("techage:sieve"..idx, { minetest.register_node("techage:sieve"..idx, {
description = S("TA1 Gravel Sieve"), description = S("TA1 Gravel Sieve"),
tiles = tiles_data, tiles = table.copy(tiles_data),
drawtype = "nodebox", drawtype = "nodebox",
node_box = { node_box = {
type = "fixed", type = "fixed",
fixed = nodebox_data, fixed = table.copy(nodebox_data),
}, },
selection_box = { selection_box = {
type = "fixed", type = "fixed",

View File

@ -209,6 +209,7 @@ minetest.register_node("techage:ta3_silo", {
after_dig_node = function(pos, oldnode, oldmetadata, digger) after_dig_node = function(pos, oldnode, oldmetadata, digger)
Pipe:after_dig_node(pos) Pipe:after_dig_node(pos)
techage.remove_node(pos, oldnode, oldmetadata) techage.remove_node(pos, oldnode, oldmetadata)
techage.del_mem(pos)
end, end,
liquid = tLiquid, liquid = tLiquid,
networks = tNetworks, networks = tNetworks,
@ -254,6 +255,7 @@ minetest.register_node("techage:ta4_silo", {
after_dig_node = function(pos, oldnode, oldmetadata, digger) after_dig_node = function(pos, oldnode, oldmetadata, digger)
Pipe:after_dig_node(pos) Pipe:after_dig_node(pos)
techage.remove_node(pos, oldnode, oldmetadata) techage.remove_node(pos, oldnode, oldmetadata)
techage.del_mem(pos)
end, end,
liquid = tLiquid, liquid = tLiquid,
networks = tNetworks, networks = tNetworks,
@ -272,7 +274,11 @@ techage.register_node({"techage:ta3_silo", "techage:ta4_silo"}, {
on_pull_item = function(pos, in_dir, num) on_pull_item = function(pos, in_dir, num)
local inv = M(pos):get_inventory() local inv = M(pos):get_inventory()
if not inv:is_empty("main") then if not inv:is_empty("main") then
return techage.get_items(pos, inv, "main", num) local taken = techage.get_items(pos, inv, "main", num)
local nvm = techage.get_nvm(pos)
nvm.item_count = nvm.item_count or get_item_count(pos)
nvm.item_count = nvm.item_count - taken:get_count()
return taken
end end
end, end,
on_push_item = function(pos, in_dir, stack) on_push_item = function(pos, in_dir, stack)
@ -284,11 +290,17 @@ techage.register_node({"techage:ta3_silo", "techage:ta4_silo"}, {
if inv:is_empty("main") then if inv:is_empty("main") then
inv:add_item("main", stack) inv:add_item("main", stack)
local nvm = techage.get_nvm(pos)
nvm.item_count = nvm.item_count or get_item_count(pos)
nvm.item_count = nvm.item_count + stack:get_count()
return true return true
end end
if inv:contains_item("main", name) and inv:room_for_item("main", stack) then if inv:contains_item("main", name) and inv:room_for_item("main", stack) then
inv:add_item("main", stack) inv:add_item("main", stack)
local nvm = techage.get_nvm(pos)
nvm.item_count = nvm.item_count or get_item_count(pos)
nvm.item_count = nvm.item_count + stack:get_count()
return true return true
end end
end end
@ -297,6 +309,9 @@ techage.register_node({"techage:ta3_silo", "techage:ta4_silo"}, {
on_unpull_item = function(pos, in_dir, stack) on_unpull_item = function(pos, in_dir, stack)
local meta = M(pos) local meta = M(pos)
local inv = meta:get_inventory() local inv = meta:get_inventory()
local nvm = techage.get_nvm(pos)
nvm.item_count = nvm.item_count or get_item_count(pos)
nvm.item_count = nvm.item_count + stack:get_count()
return techage.put_items(inv, "main", stack) return techage.put_items(inv, "main", stack)
end, end,
on_recv_message = function(pos, src, topic, payload) on_recv_message = function(pos, src, topic, payload)
@ -314,6 +329,10 @@ techage.register_node({"techage:ta3_silo", "techage:ta4_silo"}, {
return "unsupported" return "unsupported"
end end
end, end,
on_node_load = function(pos)
local nvm = techage.get_nvm(pos)
nvm.item_count = nil
end,
}) })
Pipe:add_secondary_node_names({"techage:ta3_silo", "techage:ta4_silo"}) Pipe:add_secondary_node_names({"techage:ta3_silo", "techage:ta4_silo"})

View File

@ -244,10 +244,20 @@ TechAge Door Block=TechAge Türblock
Insert door/gate block number(s)=Gebe Tür-/Tornummer(n) ein Insert door/gate block number(s)=Gebe Tür-/Tornummer(n) ein
TA3 Door Controller=TA3 Tür Controller TA3 Door Controller=TA3 Tür Controller
### doorcontroller.lua ### ### doorcontroller2.lua ###
### repeater.lua ###
TA3 Repeater=TA3 Wiederholer Blocks are back=Blöcke sind wieder da
Blocks are disappeared=Blöcke sind verschwunden
Click on all the blocks that are part of the door/gate=Klicke auf alle Blöcke, die Teil des Tores sind
Ctrl,Inv=Ctrl,Inv
Done=Fertig
Error: Inventory already in use=Fehler: Inventar wird bereits genutzt
Record=Aufzeichnen
Recording...=Aufzeichnung...
Remove=Entfernen
Set=Setzen
TA3 Door Controller II=TA3 Tür Controller II
block positions are stored.=Block Positionen gespeichert.
### drillbox.lua ### ### drillbox.lua ###
@ -409,6 +419,8 @@ TA4 LED Grow Light=TA4 LED Pflanzenlampe
No plan available=Kein Plan verfügar No plan available=Kein Plan verfügar
Plan=Plan Plan=Plan
Side view=Seitenansicht
Top view=Draufsicht
### hammer.lua ### ### hammer.lua ###
@ -795,6 +807,10 @@ TechAge Info Tool (use @= read status info)=TechAge Info Werkzeug
TechAge Repair Kit=TechAge Reparaturset TechAge Repair Kit=TechAge Reparaturset
repaired=repariert repaired=repariert
### repeater.lua ###
TA3 Repeater=TA3 Wiederholer
### rotor.lua ### ### rotor.lua ###
Nacelle is missing=Die Gondel fehlt Nacelle is missing=Die Gondel fehlt
@ -1006,6 +1022,3 @@ This is not the surface of the ocean!=Das ist nicht die Meeresoberfläche!
[TA4 Wind Turbine]=[TA4 Windkraftanlage] [TA4 Wind Turbine]=[TA4 Windkraftanlage]
biome and no ocean!=Biom und keine Meer (ocean)! biome and no ocean!=Biom und keine Meer (ocean)!
is a suitable place for a wind turbine!=ist ein geeigneter Ort für eine Windkraftanlage! is a suitable place for a wind turbine!=ist ein geeigneter Ort für eine Windkraftanlage!
##### not used anymore #####

View File

@ -244,10 +244,20 @@ TechAge Door Block=
Insert door/gate block number(s)= Insert door/gate block number(s)=
TA3 Door Controller= TA3 Door Controller=
### doorcontroller.lua ### ### doorcontroller2.lua ###
### repeater.lua ###
TA3 Repeater= Blocks are back=
Blocks are disappeared=
Click on all the blocks that are part of the door/gate=
Ctrl,Inv=
Done=
Error: Inventory already in use=
Record=
Recording...=
Remove=
Set=
TA3 Door Controller II=
block positions are stored.=
### drillbox.lua ### ### drillbox.lua ###
@ -409,6 +419,8 @@ TA4 LED Grow Light=
No plan available= No plan available=
Plan= Plan=
Side view=
Top view=
### hammer.lua ### ### hammer.lua ###
@ -795,6 +807,10 @@ TechAge Info Tool (use @= read status info)=
TechAge Repair Kit= TechAge Repair Kit=
repaired= repaired=
### repeater.lua ###
TA3 Repeater=
### rotor.lua ### ### rotor.lua ###
Nacelle is missing= Nacelle is missing=

View File

@ -95,7 +95,7 @@ minetest.register_node("techage:ta3_doorcontroller", {
techage_set_numbers = function(pos, numbers, player_name) techage_set_numbers = function(pos, numbers, player_name)
local meta = M(pos) local meta = M(pos)
local res = logic.set_numbers(pos, numbers, player_name, S("TA3 Repeater")) local res = logic.set_numbers(pos, numbers, player_name, S("TA3 Door Controller"))
if res then if res then
swap_door_nodes(pos, false) swap_door_nodes(pos, false)
meta:set_string("formspec", formspec(meta)) meta:set_string("formspec", formspec(meta))

View File

@ -0,0 +1,352 @@
--[[
TechAge
=======
Copyright (C) 2020 Joachim Stolberg
AGPL v3
See LICENSE.txt for more information
Door/Gate Controller II
]]--
-- for lazy programmers
local M = minetest.get_meta
local P2S = function(pos) if pos then return minetest.pos_to_string(pos) end end
local S = techage.S
local logic = techage.logic
local MarkedNodes = {} -- t[player][hash] = entity
local CurrentPos -- to mark punched entities
local function unmark_position(name, pos)
MarkedNodes[name] = MarkedNodes[name] or {}
pos = vector.round(pos)
local hash = minetest.hash_node_position(pos)
if MarkedNodes[name][hash] then
MarkedNodes[name][hash]:remove()
MarkedNodes[name][hash] = nil
CurrentPos = hash
end
end
local function unmark_all(name)
for _,entity in pairs(MarkedNodes[name] or {}) do
entity:remove()
end
MarkedNodes[name] = nil
end
local function mark_position(name, pos)
MarkedNodes[name] = MarkedNodes[name] or {}
pos = vector.round(pos)
local hash = minetest.hash_node_position(pos)
if hash ~= CurrentPos then -- entity not punched?
local entity = minetest.add_entity(pos, "techage:marker")
if entity ~= nil then
entity:get_luaentity().player_name = name
MarkedNodes[name][hash] = entity
end
CurrentPos = nil
return true
end
CurrentPos = nil
end
local function table_to_poslist(name)
local lst = {}
for hash,_ in pairs(MarkedNodes[name] or {}) do
local pos = minetest.get_position_from_hash(hash)
table.insert(lst, pos)
end
return lst
end
minetest.register_entity(":techage:marker", {
initial_properties = {
visual = "cube",
textures = {
"techage_cube_mark.png",
"techage_cube_mark.png",
"techage_cube_mark.png",
"techage_cube_mark.png",
"techage_cube_mark.png",
"techage_cube_mark.png",
},
--use_texture_alpha = true,
physical = false,
visual_size = {x = 1.1, y = 1.1},
collisionbox = {-0.55,-0.55,-0.55, 0.55,0.55,0.55},
glow = 8,
},
on_step = function(self, dtime)
self.ttl = (self.ttl or 600) - 1
if self.ttl <= 0 then
local pos = self.object:get_pos()
unmark_position(self.player_name, pos)
end
end,
on_punch = function(self, hitter)
local pos = self.object:get_pos()
local name = hitter:get_player_name()
if name == self.player_name then
unmark_position(name, pos)
end
end,
})
local function formspec1(meta)
local status = meta:get_string("status")
return "size[8,6.5]"..
"tabheader[0,0;tab;"..S("Ctrl,Inv")..";1;;true]"..
"button[0.7,0;3,1;record;"..S("Record").."]"..
"button[4.3,0;3,1;ready;"..S("Done").."]"..
"button[0.7,1;3,1;show;"..S("Set").."]"..
"button[4.3,1;3,1;hide;"..S("Remove").."]"..
"label[0.5,2;"..status.."]"..
"list[current_player;main;0,2.8;8,4;]"
end
local function formspec2()
return "size[8,6.5]"..
"tabheader[0,0;tab;"..S("Ctrl,Inv")..";2;;true]"..
"list[context;main;0,0;8,2;]"..
"list[current_player;main;0,2.8;8,4;]"..
"listring[context;main]"..
"listring[current_player;main]"
end
local function play_sound(pos)
minetest.sound_play("techage_button", {
pos = pos,
gain = 1,
max_hear_distance = 15})
end
local function show_nodes(pos)
local meta = M(pos)
local inv = meta:get_inventory()
if not inv:is_empty("main") then
local item_list = inv:get_list("main")
local pos_list = minetest.deserialize(meta:get_string("pos_list")) or {}
local param2_list = minetest.deserialize(meta:get_string("param2_list")) or {}
local owner = meta:get_string("owner")
local res = false
for idx = 1, 16 do
local pos = pos_list[idx]
local name = item_list[idx]:get_name()
local param2 = param2_list[idx]
if pos and param2 and name ~= "" then
if not minetest.is_protected(pos, owner) then
local node = minetest.get_node(pos)
if node.name == "air" then
minetest.add_node(pos, {name = name, param2 = param2})
end
res = true
item_list[idx]:set_count(0)
end
end
end
inv:set_list("main", item_list)
return res
end
return false
end
local function hide_nodes(pos)
local meta = M(pos)
local inv = meta:get_inventory()
if inv:is_empty("main") then
local item_list = inv:get_list("main")
local pos_list = minetest.deserialize(meta:get_string("pos_list")) or {}
local param2_list = minetest.deserialize(meta:get_string("param2_list")) or {}
local owner = meta:get_string("owner")
local res = false
for idx = 1, 16 do
local pos = pos_list[idx]
if pos then
if not minetest.is_protected(pos, owner) then
local node = minetest.get_node_or_nil(pos)
local meta = minetest.get_meta(pos)
if node and (not meta or not next((meta:to_table()).fields)) then
minetest.remove_node(pos)
if node.name ~= "air" then
item_list[idx] = ItemStack({name = node.name, count = 1})
param2_list[idx] = node.param2
end
else
item_list[idx] = nil
param2_list[idx] = 0
end
res = true
else
item_list[idx] = nil
param2_list[idx] = 0
end
else
item_list[idx] = nil
param2_list[idx] = 0
end
end
meta:set_string("param2_list", minetest.serialize(param2_list))
inv:set_list("main", item_list)
return res
end
return false
end
minetest.register_node("techage:ta3_doorcontroller2", {
description = S("TA3 Door Controller II"),
tiles = {
-- up, down, right, left, back, front
"techage_filling_ta3.png^techage_frame_ta3_top.png",
"techage_filling_ta3.png^techage_frame_ta3_top.png",
"techage_filling_ta3.png^techage_frame_ta3.png^techage_appl_doorcontroller.png",
},
after_place_node = function(pos, placer, itemstack)
local meta = M(pos)
local inv = meta:get_inventory()
inv:set_size('main', 16)
logic.after_place_node(pos, placer, "techage:ta3_doorcontroller", S("TA3 Door Controller II"))
logic.infotext(meta, S("TA3 Door Controller II"))
meta:set_string("formspec", formspec1(meta))
end,
on_receive_fields = function(pos, formname, fields, player)
if minetest.is_protected(pos, player:get_player_name()) then
return
end
local meta = M(pos)
if fields.tab == "2" then
meta:set_string("formspec", formspec2(meta))
return
elseif fields.tab == "1" then
meta:set_string("formspec", formspec1(meta))
return
elseif fields.record then
local inv = meta:get_inventory()
if not inv:is_empty("main") then
meta:set_string("status", S("Error: Inventory already in use"))
else
meta:set_string("status", S("Recording..."))
local name = player:get_player_name()
minetest.chat_send_player(name, S("Click on all the blocks that are part of the door/gate"))
MarkedNodes[name] = {}
end
meta:set_string("formspec", formspec1(meta))
elseif fields.ready then
local name = player:get_player_name()
local pos_list = table_to_poslist(name)
local text = #pos_list.." "..S("block positions are stored.")
meta:set_string("status", text)
local s = minetest.serialize(pos_list)
meta:set_string("pos_list", s)
unmark_all(name)
meta:set_string("formspec", formspec1(meta))
elseif fields.show then
if show_nodes(pos) then
play_sound(pos)
meta:set_string("status", S("Blocks are back"))
meta:set_string("formspec", formspec1(meta))
local name = player:get_player_name()
MarkedNodes[name] = nil
end
elseif fields.hide then
if hide_nodes(pos) then
play_sound(pos)
meta:set_string("status", S("Blocks are disappeared"))
meta:set_string("formspec", formspec1(meta))
local name = player:get_player_name()
MarkedNodes[name] = nil
end
end
end,
allow_metadata_inventory_move = function(pos, from_list, from_index, to_list, to_index, count, player)
if minetest.is_protected(pos, player:get_player_name()) then
return 0
end
return 0
end,
allow_metadata_inventory_take = function(pos, listname, index, stack, player)
if minetest.is_protected(pos, player:get_player_name()) then
return 0
end
return 1
end,
allow_metadata_inventory_put = function(pos, listname, index, stack, player)
if minetest.is_protected(pos, player:get_player_name()) then
return 0
end
local inv = minetest.get_inventory({type="node", pos=pos})
local pos_list = minetest.deserialize(M(pos):get_string("pos_list")) or {}
if pos_list[index] and inv:get_stack(listname, index):get_count() == 0 then
return 1
end
return 0
end,
can_dig = function(pos, player)
if player and minetest.is_protected(pos, player:get_player_name()) then
return 0
end
local inv = minetest.get_inventory({type="node", pos=pos})
return inv:is_empty("main")
end,
after_dig_node = function(pos, oldnode, oldmetadata)
techage.remove_node(pos, oldnode, oldmetadata)
end,
paramtype2 = "facedir",
groups = {choppy=2, cracky=2, crumbly=2},
is_ground_content = false,
sounds = default.node_sound_wood_defaults(),
})
techage.register_node({"techage:ta3_doorcontroller2"}, {
on_recv_message = function(pos, src, topic, payload)
if topic == "on" then
return hide_nodes(pos, nil)
elseif topic == "off" then
return show_nodes(pos)
end
return false
end,
on_node_load = function(pos)
local meta = M(pos)
meta:set_string("status", "")
meta:set_string("formspec", formspec1(meta))
end,
})
minetest.register_craft({
type = "shapeless",
output = "techage:ta3_doorcontroller2",
recipe = {"techage:ta3_doorcontroller"},
})
minetest.register_on_punchnode(function(pos, node, puncher, pointed_thing)
if puncher and puncher:is_player() then
local name = puncher:get_player_name()
if not MarkedNodes[name] then
return
end
mark_position(name, pointed_thing.under)
end
end)

View File

@ -93,6 +93,7 @@ local function restart_timer(pos, time)
timer:stop() timer:stop()
end end
if type(time) == "number" then if type(time) == "number" then
time = math.max(time, 0.5)
timer:start(time) timer:start(time)
end end
end end
@ -115,6 +116,7 @@ local function check_rules(pos, elapsed)
offs = 1 offs = 1
end end
if offs > 0 then if offs > 0 then
-- we can't restart the timer within the function om_timer
minetest.after(0, restart_timer, pos, offs) minetest.after(0, restart_timer, pos, offs)
return false return false
end end

View File

@ -105,6 +105,19 @@ techage.lua_ctlr.register_action("set_filter", {
' example: $set_filter("1234", "red", "off")' ' example: $set_filter("1234", "red", "off")'
}) })
techage.lua_ctlr.register_action("get_filter", {
cmnd = function(self, num, slot)
num = tostring(num or "")
slot = tostring(slot or "red")
if not_protected(self.meta.owner, num) then
return techage.send_single(self.meta.number, num, "port", slot)
end
end,
help = " $get_filter(num, slot)\n"..
' Read state of a Distributor filter slot.\n'..
' Return value is "on" or "off".\n'..
' example: state = $get_filter("1234", "red")'
})
techage.lua_ctlr.register_action("display", { techage.lua_ctlr.register_action("display", {
cmnd = function(self, num, row, text) cmnd = function(self, num, row, text)

View File

@ -180,9 +180,10 @@ local function formspec1(meta)
default.gui_bg.. default.gui_bg..
default.gui_bg_img.. default.gui_bg_img..
default.gui_slots.. default.gui_slots..
"style_type[textarea;font=mono]".. "style_type[textarea;font=mono;textcolor=#FFFFFF;border=false]"..
"tabheader[0,0;tab;init,func,loop,outp,notes,help;1;;true]".. "tabheader[0,0;tab;init,func,loop,outp,notes,help;1;;true]"..
"textarea[0.3,0.2;10,8.3;init;function init();"..init.."]".. "textarea[0.3,0.2;10,8.3;init;function init();"..init.."]"..
"background[0.1,0.3;9.8,7.0;techage_form_mask.png]"..
"label[0,7.3;end]".. "label[0,7.3;end]"..
"button_exit[4.4,7.5;1.8,1;cancel;Cancel]".. "button_exit[4.4,7.5;1.8,1;cancel;Cancel]"..
"button[6.3,7.5;1.8,1;save;Save]".. "button[6.3,7.5;1.8,1;save;Save]"..
@ -198,9 +199,10 @@ local function formspec2(meta)
default.gui_bg.. default.gui_bg..
default.gui_bg_img.. default.gui_bg_img..
default.gui_slots.. default.gui_slots..
"style_type[textarea;font=mono]".. "style_type[textarea;font=mono;textcolor=#FFFFFF;border=false]"..
"tabheader[0,0;tab;init,func,loop,outp,notes,help;2;;true]".. "tabheader[0,0;tab;init,func,loop,outp,notes,help;2;;true]"..
"textarea[0.3,0.2;10,8.3;func;functions:;"..func.."]".. "textarea[0.3,0.2;10,8.3;func;functions:;"..func.."]"..
"background[0.1,0.3;9.8,7.0;techage_form_mask.png]"..
"button_exit[4.4,7.5;1.8,1;cancel;Cancel]".. "button_exit[4.4,7.5;1.8,1;cancel;Cancel]"..
"button[6.3,7.5;1.8,1;save;Save]".. "button[6.3,7.5;1.8,1;save;Save]"..
"button[8.2,7.5;1.8,1;"..cmnd.."]" "button[8.2,7.5;1.8,1;"..cmnd.."]"
@ -215,9 +217,10 @@ local function formspec3(meta)
default.gui_bg.. default.gui_bg..
default.gui_bg_img.. default.gui_bg_img..
default.gui_slots.. default.gui_slots..
"style_type[textarea;font=mono]".. "style_type[textarea;font=mono;textcolor=#FFFFFF;border=false]"..
"tabheader[0,0;tab;init,func,loop,outp,notes,help;3;;true]".. "tabheader[0,0;tab;init,func,loop,outp,notes,help;3;;true]"..
"textarea[0.3,0.2;10,8.3;loop;function loop(ticks, elapsed);"..loop.."]".. "textarea[0.3,0.2;10,8.3;loop;function loop(ticks, elapsed);"..loop.."]"..
"background[0.1,0.3;9.8,7.0;techage_form_mask.png]"..
"label[0,7.3;end]".. "label[0,7.3;end]"..
"button_exit[4.4,7.5;1.8,1;cancel;Cancel]".. "button_exit[4.4,7.5;1.8,1;cancel;Cancel]"..
"button[6.3,7.5;1.8,1;save;Save]".. "button[6.3,7.5;1.8,1;save;Save]"..
@ -248,9 +251,10 @@ local function formspec5(meta)
default.gui_bg.. default.gui_bg..
default.gui_bg_img.. default.gui_bg_img..
default.gui_slots.. default.gui_slots..
"style_type[textarea;font=mono]".. "style_type[textarea;font=mono;textcolor=#FFFFFF;border=false]"..
"tabheader[0,0;tab;init,func,loop,outp,notes,help;5;;true]".. "tabheader[0,0;tab;init,func,loop,outp,notes,help;5;;true]"..
"textarea[0.3,0.2;10,8.3;notes;Notepad:;"..notes.."]".. "textarea[0.3,0.2;10,8.3;notes;Notepad:;"..notes.."]"..
"background[0.1,0.3;9.8,7.0;techage_form_mask.png]"..
"button_exit[6.3,7.5;1.8,1;cancel;Cancel]".. "button_exit[6.3,7.5;1.8,1;cancel;Cancel]"..
"button[8.2,7.5;1.8,1;save;Save]" "button[8.2,7.5;1.8,1;save;Save]"
end end
@ -261,7 +265,7 @@ local function formspec6(items, pos, text)
default.gui_bg.. default.gui_bg..
default.gui_bg_img.. default.gui_bg_img..
default.gui_slots.. default.gui_slots..
"style_type[textarea;font=mono]".. "style_type[textarea;font=mono;textcolor=#FFFFFF]"..
"tabheader[0,0;tab;init,func,loop,outp,notes,help;6;;true]".. "tabheader[0,0;tab;init,func,loop,outp,notes,help;6;;true]"..
"label[0,-0.2;Functions:]".. "label[0,-0.2;Functions:]"..
"dropdown[0.3,0.2;10,8.3;functions;"..items..";"..pos.."]".. "dropdown[0.3,0.2;10,8.3;functions;"..items..";"..pos.."]"..

View File

@ -122,6 +122,8 @@ minetest.register_craft({
local function calc_size(v) local function calc_size(v)
if type(v) == "number" then if type(v) == "number" then
return 1 return 1
elseif type(v) == "boolean" then
return 1
elseif v == nil then elseif v == nil then
return 0 return 0
elseif type(v) == "string" then elseif type(v) == "string" then

View File

@ -201,7 +201,7 @@ techage.register_node({"techage:ta4_terminal"}, {
output(pos, payload) output(pos, payload)
return true return true
elseif topic == "msg" then elseif topic == "msg" then
output(pos, payload.src..": "..payload.text) output(pos, tostring(payload.src)..": "..tostring(payload.text))
return true return true
end end
end, end,

View File

@ -224,7 +224,7 @@ In der unteren Hälfte werden die Daten aller Generatoren und Speichersystemen d
Der TA3 Industrieofen dient als Ergänzung zu normalen Ofen (furnace). Damit können alle Waren mit "Koch" Rezepten, auch im Industrieofen hergestellt werden. Es gibt aber auch spezielle Rezepte, die nur im Industrieofen hergestellt werden können. Der TA3 Industrieofen dient als Ergänzung zu normalen Ofen (furnace). Damit können alle Waren mit "Koch" Rezepten, auch im Industrieofen hergestellt werden. Es gibt aber auch spezielle Rezepte, die nur im Industrieofen hergestellt werden können.
Der Industrieofen hat sein eigenes Menü zur Rezeptauswahl. Abhängig von den Waren im Industrieofen Inventar links kann rechts das Ausgangsprodukt gewählt werden. Der Industrieofen hat sein eigenes Menü zur Rezeptauswahl. Abhängig von den Waren im Industrieofen Inventar links kann rechts das Ausgangsprodukt gewählt werden.
Der Industrieofen benötigt Strom (für das Gebläse) sowie Öl/Benzin für den Brenner. Der Industrieofens und muss wie im Plan rechts abgebildet, zusammen gebaut werden. Der Industrieofen benötigt Strom (für das Gebläse) sowie Schweröl/Benzin für den Brenner. Der Industrieofens und muss wie im Plan rechts abgebildet, zusammen gebaut werden.
Siehe auch TA4 Ofenheizung. Siehe auch TA4 Ofenheizung.
@ -620,6 +620,14 @@ Der Tür Controller dient zur Ansteuerung der TA3 Tür/Tor Blöcke. Beim Tür Co
[ta3_doorcontroller|image] [ta3_doorcontroller|image]
### TA3 Tür Controller II / Door Controller II
Der Tür Controller II kann alle Arten von Blöcken entfernen und wieder setzen. Um den Tür Controller II anzulernen, muss der "Aufzeichnen" Button gedrückt werden. Dann müssen alle Blöcke angeklickt werden, die Teil der Tür / des Tores sein sollen. Danach muss der "Fertig" Button gedrückt werden. Es können bis zu 16 Blöcke ausgewählt werden. Die entfernten Blöcke werden im Inventar des Controllers gespeichert. Über die Tasten "Entfernen" bzw. "Setzen" kann die Funktion des Controllers von Hand getestet werden.
Wird ein `on` / `off` Kommando an den Tür Controller II gesendet, entfernt bzw. setzt er die Blöcke ebenfalls.
[ta3_doorcontroller|image]
### TA3 Mesecons Umsetzer / TA3 Mesecons Converter ### TA3 Mesecons Umsetzer / TA3 Mesecons Converter
Der Mesecons Umsetzer dient zur Umwandlung von Techage on/off Kommandos in Mesecons Signale und umgekehrt. Der Mesecons Umsetzer dient zur Umwandlung von Techage on/off Kommandos in Mesecons Signale und umgekehrt.

View File

@ -215,7 +215,7 @@ The electric motor takes max. 40 ku of electricity and provides on the other sid
The TA3 industrial furnace serves as a supplement to normal furnaces. This means that all goods can be produced with "cooking" recipes, even in an industrial furnace. But there are also special recipes that can only be made in an industrial furnace. The TA3 industrial furnace serves as a supplement to normal furnaces. This means that all goods can be produced with "cooking" recipes, even in an industrial furnace. But there are also special recipes that can only be made in an industrial furnace.
The industrial furnace has its own menu for recipe selection. Depending on the goods in the industrial furnace inventory on the left, the output product can be selected on the right. The industrial furnace has its own menu for recipe selection. Depending on the goods in the industrial furnace inventory on the left, the output product can be selected on the right.
The industrial furnace requires electricity (for the fan) and oil / gasoline for the burner. The industrial furnace and must be assembled as shown in the plan on the right. The industrial furnace requires electricity (for the fan) and fuel oil / gasoline for the burner. The industrial furnace and must be assembled as shown in the plan on the right.
See also TA4 heater. See also TA4 heater.
@ -603,14 +603,18 @@ This makes it possible to realize secret doors that only open for certain player
[ta3_doorblock|image] [ta3_doorblock|image]
### TA3 Door Controller ### TA3 Door Controller
The door controller is used to control the TA3 door/gate blocks. With the door controller, the numbers of the door/gate blocks must be entered. If an `on` / `off` command is sent to the door controller, this opens/closes the door or gate. The door controller is used to control the TA3 door/gate blocks. With the door controller, the numbers of the door/gate blocks must be entered. If an `on` / `off` command is sent to the door controller, this opens/closes the door or gate.
[ta3_doorcontroller|image] [ta3_doorcontroller|image]
### TA3 Door Controller II
The Door Controller II can remove and set all types of blocks. To teach in the Door Controller II, the "Record" button must be pressed. Then all blocks that should be part of the door / gate must be clicked. Then the "Done" button must be pressed. Up to 16 blocks can be selected. The removed blocks are saved in the controller's inventory. The function of the controller can be tested manually using the "Remove" or "Set" buttons. If an `on` /` off` command is sent to the Door Controller II, it removes or sets the blocks as well.
[ta3_doorcontroller|image]
### TA3 Mesecons Converter ### TA3 Mesecons Converter

View File

@ -658,3 +658,17 @@ Beim Weitergeben wird in der Zielmaschine pro Item nur eine Position im Inventar
Die Verarbeitungsleistung beträgt bis zu 8 Items alle 3 Sekunden. Die Verarbeitungsleistung beträgt bis zu 8 Items alle 3 Sekunden.
[ta4_injector|image] [ta4_injector|image]
### TA4 Recycler
Der Recycler ist eine Maschine, die alle Techage Rezepte rückwärts abarbeitet, also Maschinen und Blöcke wieder in die Bestandteile zerlegen kann. Die Maschine kann so ziemlich alle Techage und Hyperloop Blöcke zerlegen.
Aber nicht alle Materialen lassen sich recyclen:
- Holz wird zu Sticks
- Stein wird zu Sand oder Kies
- Halbleiter/Chips können nicht recycelt werden
- Werkzeuge können nicht recycelt werden
Die Verarbeitungsleistung beträgt ein Item alle 8 s. Der Block benötigt hierfür 16 ku Strom.
[ta4_recycler|image]

View File

@ -659,3 +659,19 @@ When passing on, only one position in the inventory is used in the target machin
The processing power is up to 8 items every 3 seconds. The processing power is up to 8 items every 3 seconds.
[ta4_injector|image] [ta4_injector|image]
### TA4 recycler
The recycler is a machine that processes all Techage recipes backwards, i.e. it can dismantle machines and blocks back into their components.
The machine can disassemble pretty much any Techage and Hyperloop blocks. But not all materials can be recycled:
- Wood turns into sticks
- Stone turns into sand or gravel
- Semiconductors / chips cannot be recycled
- Tools cannot be recycled
The processing power is one item every 8 s. The block requires 16 ku of electricity for this.
[ta4_recycler|image]

View File

@ -45,10 +45,10 @@
- [TA2 Flüssigkeitensammler / Liquid Sampler](./manual_ta2_DE.md#ta2-flüssigkeitensammler--liquid-sampler) - [TA2 Flüssigkeitensammler / Liquid Sampler](./manual_ta2_DE.md#ta2-flüssigkeitensammler--liquid-sampler)
- [TA2 Gesicherte Kiste / Protected Chest](./manual_ta2_DE.md#ta2-gesicherte-kiste--protected-chest) - [TA2 Gesicherte Kiste / Protected Chest](./manual_ta2_DE.md#ta2-gesicherte-kiste--protected-chest)
- [Techage Forceload Block](./manual_ta2_DE.md#techage-forceload-block) - [Techage Forceload Block](./manual_ta2_DE.md#techage-forceload-block)
- [TA3: Ölzeitalter](./manual_ta3_DE.md#ta3:-Ölzeitalter) - [TA3: Ölzeitalter](./manual_ta3_DE.md#ta3:-ölzeitalter)
- [Kohlekraftwerk / Ölkraftwerk](./manual_ta3_DE.md#kohlekraftwerk--Ölkraftwerk) - [Kohlekraftwerk / Ölkraftwerk](./manual_ta3_DE.md#kohlekraftwerk--ölkraftwerk)
- [TA3 Kraftwerks-Feuerbox / Power Station Firebox](./manual_ta3_DE.md#ta3-kraftwerks-feuerbox--power-station-firebox) - [TA3 Kraftwerks-Feuerbox / Power Station Firebox](./manual_ta3_DE.md#ta3-kraftwerks-feuerbox--power-station-firebox)
- [TA3 Kraftwerks-Ölbrenner / TA3 Power Station Oil Burner](./manual_ta3_DE.md#ta3-kraftwerks-Ölbrenner--ta3-power-station-oil-burner) - [TA3 Kraftwerks-Ölbrenner / TA3 Power Station Oil Burner](./manual_ta3_DE.md#ta3-kraftwerks-ölbrenner--ta3-power-station-oil-burner)
- [TA3 Boiler unten/oben](./manual_ta3_DE.md#ta3-boiler-untenoben) - [TA3 Boiler unten/oben](./manual_ta3_DE.md#ta3-boiler-untenoben)
- [TA3 Turbine](./manual_ta3_DE.md#ta3-turbine) - [TA3 Turbine](./manual_ta3_DE.md#ta3-turbine)
- [TA3 Generator](./manual_ta3_DE.md#ta3-generator) - [TA3 Generator](./manual_ta3_DE.md#ta3-generator)
@ -69,7 +69,7 @@
- [TA3 Elektromotor / TA3 Electric Motor](./manual_ta3_DE.md#ta3-elektromotor--ta3-electric-motor) - [TA3 Elektromotor / TA3 Electric Motor](./manual_ta3_DE.md#ta3-elektromotor--ta3-electric-motor)
- [TA3 Strom Terminal / Power Terminal](./manual_ta3_DE.md#ta3-strom-terminal--power-terminal) - [TA3 Strom Terminal / Power Terminal](./manual_ta3_DE.md#ta3-strom-terminal--power-terminal)
- [TA3 Industrieofen](./manual_ta3_DE.md#ta3-industrieofen) - [TA3 Industrieofen](./manual_ta3_DE.md#ta3-industrieofen)
- [TA3 Ofen-Ölbrenner / Furnace Oil Burner](./manual_ta3_DE.md#ta3-ofen-Ölbrenner--furnace-oil-burner) - [TA3 Ofen-Ölbrenner / Furnace Oil Burner](./manual_ta3_DE.md#ta3-ofen-ölbrenner--furnace-oil-burner)
- [TA3 Ofenoberteil / Furnace Top](./manual_ta3_DE.md#ta3-ofenoberteil--furnace-top) - [TA3 Ofenoberteil / Furnace Top](./manual_ta3_DE.md#ta3-ofenoberteil--furnace-top)
- [TA3 Gebläse / Booster](./manual_ta3_DE.md#ta3-gebläse--booster) - [TA3 Gebläse / Booster](./manual_ta3_DE.md#ta3-gebläse--booster)
- [Flüssigkeiten](./manual_ta3_DE.md#flüssigkeiten) - [Flüssigkeiten](./manual_ta3_DE.md#flüssigkeiten)
@ -79,18 +79,18 @@
- [TA4 Röhre / Pipe](./manual_ta3_DE.md#ta4-röhre--pipe) - [TA4 Röhre / Pipe](./manual_ta3_DE.md#ta4-röhre--pipe)
- [TA3 Rohr/Wanddurchbruch / TA3 Pipe Wall Entry Blöcke](./manual_ta3_DE.md#ta3-rohrwanddurchbruch--ta3-pipe-wall-entry-blöcke) - [TA3 Rohr/Wanddurchbruch / TA3 Pipe Wall Entry Blöcke](./manual_ta3_DE.md#ta3-rohrwanddurchbruch--ta3-pipe-wall-entry-blöcke)
- [TA Ventil / TA Valve](./manual_ta3_DE.md#ta-ventil--ta-valve) - [TA Ventil / TA Valve](./manual_ta3_DE.md#ta-ventil--ta-valve)
- [Öl-Förderung](./manual_ta3_DE.md#Öl-förderung) - [Öl-Förderung](./manual_ta3_DE.md#öl-förderung)
- [TA3 Ölexplorer / Oil Explorer](./manual_ta3_DE.md#ta3-Ölexplorer--oil-explorer) - [TA3 Ölexplorer / Oil Explorer](./manual_ta3_DE.md#ta3-ölexplorer--oil-explorer)
- [TA3 Ölbohrkiste / Oil Drill Box](./manual_ta3_DE.md#ta3-Ölbohrkiste--oil-drill-box) - [TA3 Ölbohrkiste / Oil Drill Box](./manual_ta3_DE.md#ta3-ölbohrkiste--oil-drill-box)
- [TA3 Ölpumpe / Oil Pumpjack](./manual_ta3_DE.md#ta3-Ölpumpe--oil-pumpjack) - [TA3 Ölpumpe / Oil Pumpjack](./manual_ta3_DE.md#ta3-ölpumpe--oil-pumpjack)
- [TA3 Bohrgestänge / Drill Pipe](./manual_ta3_DE.md#ta3-bohrgestänge--drill-pipe) - [TA3 Bohrgestänge / Drill Pipe](./manual_ta3_DE.md#ta3-bohrgestänge--drill-pipe)
- [Öltank / Oil Tank](./manual_ta3_DE.md#Öltank--oil-tank) - [Öltank / Oil Tank](./manual_ta3_DE.md#öltank--oil-tank)
- [Öl-Transport](./manual_ta3_DE.md#Öl-transport) - [Öl-Transport](./manual_ta3_DE.md#öl-transport)
- [Öl-Transport mit dem Tankwagen](./manual_ta3_DE.md#Öl-transport-mit-dem-tankwagen) - [Öl-Transport mit dem Tankwagen](./manual_ta3_DE.md#öl-transport-mit-dem-tankwagen)
- [Öl-Transport mit Fässern über Minecarts](./manual_ta3_DE.md#Öl-transport-mit-fässern-über-minecarts) - [Öl-Transport mit Fässern über Minecarts](./manual_ta3_DE.md#öl-transport-mit-fässern-über-minecarts)
- [Tankwagen / Tank Cart](./manual_ta3_DE.md#tankwagen--tank-cart) - [Tankwagen / Tank Cart](./manual_ta3_DE.md#tankwagen--tank-cart)
- [Kistenwagen / Chest Cart](./manual_ta3_DE.md#kistenwagen--chest-cart) - [Kistenwagen / Chest Cart](./manual_ta3_DE.md#kistenwagen--chest-cart)
- [Öl-Verarbeitung](./manual_ta3_DE.md#Öl-verarbeitung) - [Öl-Verarbeitung](./manual_ta3_DE.md#öl-verarbeitung)
- [Destillationsturm / distiller tower](./manual_ta3_DE.md#destillationsturm--distiller-tower) - [Destillationsturm / distiller tower](./manual_ta3_DE.md#destillationsturm--distiller-tower)
- [Aufkocher / reboiler)](./manual_ta3_DE.md#aufkocher--reboiler)) - [Aufkocher / reboiler)](./manual_ta3_DE.md#aufkocher--reboiler))
- [Logik-/Schalt-Blöcke](./manual_ta3_DE.md#logik-schalt-blöcke) - [Logik-/Schalt-Blöcke](./manual_ta3_DE.md#logik-schalt-blöcke)
@ -103,6 +103,7 @@
- [TechAge Signallampe / Signal Lamp](./manual_ta3_DE.md#techage-signallampe--signal-lamp) - [TechAge Signallampe / Signal Lamp](./manual_ta3_DE.md#techage-signallampe--signal-lamp)
- [Tür/Tor Blöcke / Door/Gate Blocks](./manual_ta3_DE.md#türtor-blöcke--doorgate-blocks) - [Tür/Tor Blöcke / Door/Gate Blocks](./manual_ta3_DE.md#türtor-blöcke--doorgate-blocks)
- [TA3 Tür Controller / Door Controller](./manual_ta3_DE.md#ta3-tür-controller--door-controller) - [TA3 Tür Controller / Door Controller](./manual_ta3_DE.md#ta3-tür-controller--door-controller)
- [TA3 Tür Controller II / Door Controller II](./manual_ta3_DE.md#ta3-tür-controller-ii--door-controller-ii)
- [TA3 Mesecons Umsetzer / TA3 Mesecons Converter](./manual_ta3_DE.md#ta3-mesecons-umsetzer--ta3-mesecons-converter) - [TA3 Mesecons Umsetzer / TA3 Mesecons Converter](./manual_ta3_DE.md#ta3-mesecons-umsetzer--ta3-mesecons-converter)
- [Detektoren](./manual_ta3_DE.md#detektoren) - [Detektoren](./manual_ta3_DE.md#detektoren)
- [TA3 Detektor / Detector](./manual_ta3_DE.md#ta3-detektor--detector) - [TA3 Detektor / Detector](./manual_ta3_DE.md#ta3-detektor--detector)
@ -191,4 +192,5 @@
- [TA4 Mühle / Grinder](./manual_ta4_DE.md#ta4-mühle--grinder) - [TA4 Mühle / Grinder](./manual_ta4_DE.md#ta4-mühle--grinder)
- [TA4 Steinbrecher / Quarry](./manual_ta4_DE.md#ta4-steinbrecher--quarry) - [TA4 Steinbrecher / Quarry](./manual_ta4_DE.md#ta4-steinbrecher--quarry)
- [TA4 Elektronikfabrik / Electronic Fab](./manual_ta4_DE.md#ta4-elektronikfabrik--electronic-fab) - [TA4 Elektronikfabrik / Electronic Fab](./manual_ta4_DE.md#ta4-elektronikfabrik--electronic-fab)
- [TA4 Injektor / Injector](./manual_ta4_DE.md#ta4-injektor--injector) - [TA4 Injektor / Injector](./manual_ta4_DE.md#ta4-injektor--injector)
- [TA4 Recycler](./manual_ta4_DE.md#ta4-recycler)

View File

@ -102,6 +102,7 @@
- [TechAge Signal Lamp](./manual_ta3_EN.md#techage-signal-lamp) - [TechAge Signal Lamp](./manual_ta3_EN.md#techage-signal-lamp)
- [Door/Gate Blocks](./manual_ta3_EN.md#doorgate-blocks) - [Door/Gate Blocks](./manual_ta3_EN.md#doorgate-blocks)
- [TA3 Door Controller](./manual_ta3_EN.md#ta3-door-controller) - [TA3 Door Controller](./manual_ta3_EN.md#ta3-door-controller)
- [TA3 Door Controller II](./manual_ta3_EN.md#ta3-door-controller-ii)
- [TA3 Mesecons Converter](./manual_ta3_EN.md#ta3-mesecons-converter) - [TA3 Mesecons Converter](./manual_ta3_EN.md#ta3-mesecons-converter)
- [Detectors](./manual_ta3_EN.md#detectors) - [Detectors](./manual_ta3_EN.md#detectors)
- [TA3 Detector](./manual_ta3_EN.md#ta3-detector) - [TA3 Detector](./manual_ta3_EN.md#ta3-detector)
@ -190,4 +191,5 @@
- [TA4 Grinder](./manual_ta4_EN.md#ta4-grinder) - [TA4 Grinder](./manual_ta4_EN.md#ta4-grinder)
- [TA4 Quarry](./manual_ta4_EN.md#ta4-quarry) - [TA4 Quarry](./manual_ta4_EN.md#ta4-quarry)
- [TA4 Electronic Fab](./manual_ta4_EN.md#ta4-electronic-fab) - [TA4 Electronic Fab](./manual_ta4_EN.md#ta4-electronic-fab)
- [TA4 Injector](./manual_ta4_EN.md#ta4-injector) - [TA4 Injector](./manual_ta4_EN.md#ta4-injector)
- [TA4 recycler](./manual_ta4_EN.md#ta4-recycler)

View File

@ -69,7 +69,7 @@ function Cable:get_secondary_node(pos, dir)
local node = self:get_node_lvm(npos) local node = self:get_node_lvm(npos)
if self.secondary_node_names[node.name] or if self.secondary_node_names[node.name] or
self.secondary_node_names[M(npos):get_string("techage_hidden_nodename")] then self.secondary_node_names[M(npos):get_string("techage_hidden_nodename")] then
return node, npos return node, npos, true
end end
end end

View File

@ -19,7 +19,7 @@
local in_range = techage.in_range local in_range = techage.in_range
function techage.power.percent(max_val, curr_val) function techage.power.percent(max_val, curr_val)
return math.min(math.ceil(((curr_val or 0) * 100.0) / (max_val or 1.0)), 100) return math.min(math.ceil(((curr_val or 0) * 100) / (max_val or 1.0)), 100)
end end
function techage.power.formspec_load_bar(charging, max_val) function techage.power.formspec_load_bar(charging, max_val)

View File

@ -248,7 +248,7 @@ function techage.power.needed_power(pos, Cable, outdir)
local nvm = techage.get_nvm(pos) local nvm = techage.get_nvm(pos)
local def = nvm[Cable.tube_type] -- power related data local def = nvm[Cable.tube_type] -- power related data
if def and def["cstate"] ~= STOPPED then if def and def["cstate"] and def["cstate"] ~= STOPPED then
if def["calive"] >= 0 then if def["calive"] >= 0 then
sum = sum + (net.nominal or def.curr_power or 0) sum = sum + (net.nominal or def.curr_power or 0)
end end

View File

@ -1,13 +1,13 @@
import os, fnmatch import os, fnmatch
print ">>> Convert" print(">>> Convert")
for filename in os.listdir("./"): for filename in os.listdir("./"):
if fnmatch.fnmatch(filename, "*.png"): if fnmatch.fnmatch(filename, "*.png"):
print(filename) print(filename)
os.system("pngquant --skip-if-larger --quality=8-32 --output ./%s.new ./%s" % (filename, filename)) os.system("pngquant --skip-if-larger --quality=60-80 --strip --output ./%s.new ./%s" % (filename, filename))
print "\n>>> Copy" print("\n>>> Copy")
for filename in os.listdir("./"): for filename in os.listdir("./"):
if fnmatch.fnmatch(filename, "*.new"): if fnmatch.fnmatch(filename, "*.new"):
print(filename) print(filename)

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.3 KiB

After

Width:  |  Height:  |  Size: 1.2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 163 B

After

Width:  |  Height:  |  Size: 122 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 175 B

After

Width:  |  Height:  |  Size: 154 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 172 B

After

Width:  |  Height:  |  Size: 151 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 238 B

After

Width:  |  Height:  |  Size: 139 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 388 B

After

Width:  |  Height:  |  Size: 217 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 156 B

After

Width:  |  Height:  |  Size: 135 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 173 B

After

Width:  |  Height:  |  Size: 152 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 223 B

After

Width:  |  Height:  |  Size: 161 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 227 B

After

Width:  |  Height:  |  Size: 165 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 303 B

After

Width:  |  Height:  |  Size: 164 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 290 B

After

Width:  |  Height:  |  Size: 167 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 430 B

After

Width:  |  Height:  |  Size: 229 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 226 B

After

Width:  |  Height:  |  Size: 164 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 204 B

After

Width:  |  Height:  |  Size: 183 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 284 B

After

Width:  |  Height:  |  Size: 263 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 477 B

After

Width:  |  Height:  |  Size: 456 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 383 B

After

Width:  |  Height:  |  Size: 313 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 233 B

After

Width:  |  Height:  |  Size: 208 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 425 B

After

Width:  |  Height:  |  Size: 210 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 297 B

After

Width:  |  Height:  |  Size: 235 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 215 B

After

Width:  |  Height:  |  Size: 194 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 215 B

After

Width:  |  Height:  |  Size: 194 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 212 B

After

Width:  |  Height:  |  Size: 191 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 212 B

After

Width:  |  Height:  |  Size: 191 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 212 B

After

Width:  |  Height:  |  Size: 191 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 212 B

After

Width:  |  Height:  |  Size: 191 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 203 B

After

Width:  |  Height:  |  Size: 182 B

Some files were not shown because too many files have changed in this diff Show More