update castles, bonemeal, homedecor, pipeworks, signs_lib, cool_trees

This commit is contained in:
Vanessa Dannenberg 2020-02-28 11:48:06 -05:00
parent e40b44462f
commit e6f3313f30
83 changed files with 2952 additions and 1248 deletions

View File

@ -2,4 +2,8 @@ Anvil mod by Sokomine, originally a part of the Cottages mod but extracted to st
This anvil (and its associated hammer) allows a player to repair worn tools. Place the worn tool in the anvil's inventory and strike it with the hammer to improve its condition.
By default, a hammer can be repaired on the anvil just like any other tool, allowing for infinite recycling of worn tools. Set "anvil_hammer_is_repairable false" to prevent this.
By default, a hammer can be repaired on the anvil just like any other tool, allowing for infinite recycling of worn tools. Set "anvil_hammer_is_repairable false" to prevent this.
Any tool belonging to the group "not_repaired_by_anvil" can't be repaired at an anvil.
The API function anvil.make_unrepairable(item_name) can be used as a convenience function to add this group to an already-registered tool.

281
anvil/i18n.py Normal file
View File

@ -0,0 +1,281 @@
#!/usr/bin/env python
# -*- 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
# LGPLv2.1+
from __future__ import print_function
import os, fnmatch, re, shutil, errno
verbose = False
#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 = re.compile(r'[\.=^\t,{\(\s]N?S\(\s*(["\'])((?:\\\1|(?:(?!\1)).)*)(\1)[\s,\)]', re.DOTALL)
pattern_lua_bracketed = re.compile(r'[\.=^\t,{\(\s]N?S\(\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(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(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(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 verbose:
print(tr_name + " already exists, ignoring " + name)
continue
fname = os.path.join(root, name)
with open(fname, "r", encoding='utf-8') as po_file:
if verbose:
print("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, for use when updating
# existing .tr files
def strings_to_text(dkeyStrings, dOld, mod_name):
lOut = ["# textdomain: %s\n" % mod_name]
dGroupedBySource = {}
for key in dkeyStrings:
sourceList = list(dkeyStrings[key])
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:
lOut.append("")
localizedStrings = dGroupedBySource[source]
localizedStrings.sort()
lOut.append(source)
for localizedString in localizedStrings:
val = dOld.get(localizedString, "")
lOut.append("%s=%s" % (localizedString, val))
unusedExist = False
for key in dOld:
if key not in dkeyStrings:
if not unusedExist:
unusedExist = True
lOut.append("\n##### not used anymore #####")
lOut.append("%s=%s" % (key, dOld[key]))
return "\n".join(lOut)
# Writes a template.txt file
# dkeyStrings is the dictionary returned by generate_template
def write_template(templ_file, dkeyStrings, mod_name):
text = strings_to_text(dkeyStrings, {}, mod_name)
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.findall(text):
strings.append(s[1])
for s in pattern_lua_bracketed.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.
def import_tr_file(tr_file):
dOut = {}
text = None
if os.path.exists(tr_file):
with open(tr_file, "r", encoding='utf-8') as existing_file :
text = existing_file.read()
existing_file.seek(0)
for line in existing_file.readlines():
s = line.strip()
if s == "" or s[0] == "#":
continue
match = pattern_tr.match(s)
if match:
dOut[match.group(1)] = match.group(2)
return (dOut, text)
# 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 verbose:
print(fname + ": " + str(len(found)) + " translatable strings")
for s in found:
sources = dOut.get(s, set())
sources.add("# " + fname)
dOut[s] = sources
if len(dOut) == 0:
return None
templ_file = 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 verbose:
print("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)
if textOld and textOld != textNew:
print(tr_file + " has changed.")
shutil.copyfile(tr_file, 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("Updating translations for " + modname)
data = generate_template(folder, modname)
if data == None:
print("No translatable strings found in " + modname)
else:
for tr_file in get_existing_tr_files(folder):
update_tr_file(data, modname, folder + "locale/" + tr_file)
else:
print("Unable to find modname in folder " + folder)
# 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(folder+"modpack.txt") or os.path.exists(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.")
update_folder("./")
# Runs this script on each sub-folder in the parent folder.
# I'm using this for testing this script on all installed mods.
#for modfolder in [f.path for f in os.scandir("../") if f.is_dir()]:
# update_folder(modfolder + "/")

View File

@ -2,7 +2,7 @@
-- simple anvil that can be used to repair tools
---------------------------------------------------------------------------------------
-- * can be used to repair tools
-- * the hammer gets dammaged a bit at each repair step
-- * the hammer gets damaged a bit at each repair step
---------------------------------------------------------------------------------------
anvil = {
@ -13,22 +13,19 @@ anvil = {
minetest.register_alias("castle:anvil", "anvil:anvil")
local hammer_repairable = minetest.setting_getbool("anvil_hammer_is_repairable")
if hammer_repairable == nil then hammer_repairable = true end
local hammer_repairable = minetest.settings:get_bool("anvil_hammer_is_repairable", true)
local make_unrepairable = function(item_name)
anvil.make_unrepairable = function(item_name)
local item_def = minetest.registered_items[item_name]
if item_def then
item_def.groups.not_repaired_by_anvil = 1
minetest.override_item(item_name, {groups = item_def.groups})
end
end
make_unrepairable("technic:water_can")
make_unrepairable("technic:lava_can")
anvil.make_unrepairable("technic:water_can")
anvil.make_unrepairable("technic:lava_can")
-- internationalization boilerplate
local MP = minetest.get_modpath(minetest.get_current_modname())
local S, NS = dofile(MP.."/intllib.lua")
local S = minetest.get_translator(minetest.get_current_modname())
-- the hammer for the anvil
@ -170,7 +167,7 @@ minetest.register_node("anvil:anvil", {
after_place_node = function(pos, placer)
local meta = minetest.get_meta(pos)
meta:set_string("owner", placer:get_player_name() or "")
meta:set_string("infotext",placer:get_player_name().."'s anvil")
meta:set_string("infotext", S("@1's anvil", placer:get_player_name()))
end,
can_dig = function(pos,player)

View File

@ -1,45 +0,0 @@
-- Fallback functions for when `intllib` is not installed.
-- Code released under Unlicense <http://unlicense.org>.
-- Get the latest version of this file at:
-- https://raw.githubusercontent.com/minetest-mods/intllib/master/lib/intllib.lua
local function format(str, ...)
local args = { ... }
local function repl(escape, open, num, close)
if escape == "" then
local replacement = tostring(args[tonumber(num)])
if open == "" then
replacement = replacement..close
end
return replacement
else
return "@"..open..num..close
end
end
return (str:gsub("(@?)@(%(?)(%d+)(%)?)", repl))
end
local gettext, ngettext
if minetest.get_modpath("intllib") then
if intllib.make_gettext_pair then
-- New method using gettext.
gettext, ngettext = intllib.make_gettext_pair()
else
-- Old method using text files.
gettext = intllib.Getter()
end
end
-- Fill in missing functions.
gettext = gettext or function(msgid, ...)
return format(msgid, ...)
end
ngettext = ngettext or function(msgid, msgid_plural, n, ...)
return format(n==1 and msgid or msgid_plural, ...)
end
return gettext, ngettext

24
anvil/locale/anvil.de.tr Normal file
View File

@ -0,0 +1,24 @@
# textdomain: anvil
# ./init.lua
@1 cannot be repaired with an anvil.=
@1's anvil=
A tool for repairing other tools at a blacksmith's anvil.=Stahlhammer um Werkzeuge auf dem Amboss zu reparieren
A tool for repairing other tools in conjunction with a blacksmith's hammer.=
Anvil=Amboss
Right-click on this anvil with a damaged tool to place the damaged tool upon it. You can then repair the damaged tool by striking it with a blacksmith's hammer. Repeated blows may be necessary to fully repair a badly worn tool. To retrieve the tool either punch or right-click the anvil with an empty hand.=
Steel blacksmithing hammer=
This anvil is for damaged tools only.=Das Werkstueckfeld gilt nur fuer beschaedigtes Werkzeug.
Use this hammer to strike blows upon an anvil bearing a damaged tool and you can repair it. It can also be used for smashing stone, but it is not well suited to this task.=
Your @1 has been repaired successfully.=
##### not used anymore #####
Workpiece:=Werkstueck:
Optional=Moegliche
storage for=Aufbewahrung fuer
your hammer=deinen Hammer
Punch anvil with hammer to=Schlage mit dem Hammer auf den Amboss um
repair tool in workpiece-slot.=das Werkzeug im Werkstueckfeld zu reparieren.
anvil=Amboss
Anvil (owned by %s)=Amboss (gehoert %s)
Owner: %s=Besitzer: %s

14
anvil/locale/anvil.es.tr Normal file
View File

@ -0,0 +1,14 @@
# textdomain: anvil
# ./init.lua
@1 cannot be repaired with an anvil.=
@1's anvil=
A tool for repairing other tools at a blacksmith's anvil.=Es una herramienta para reparar otras herramientas en el yunque del herrero
A tool for repairing other tools in conjunction with a blacksmith's hammer.=Es una herramienta para reparar de herramientas dañadas en conjunto con el martillo del herrero.
Anvil=Yunque
Right-click on this anvil with a damaged tool to place the damaged tool upon it. You can then repair the damaged tool by striking it with a blacksmith's hammer. Repeated blows may be necessary to fully repair a badly worn tool. To retrieve the tool either punch or right-click the anvil with an empty hand.=Haga clic derecho sobre este yunque con una herramienta dañada Puede reparar la herramienta dañada golpeándola con el martillo del herrero Para reparar completamente una herramienta puede dar varios golpes Para sacar la herramienta, golpeela con la mano vacia o tambien con un clic derecho
Steel blacksmithing hammer=Martillo de acero para la herrería
This anvil is for damaged tools only.=Este yunque es sólo para herramientas dañadas
Use this hammer to strike blows upon an anvil bearing a damaged tool and you can repair it. It can also be used for smashing stone, but it is not well suited to this task.=Use este martillo para dar golpes sobre el yunque donde puso la herramienta dañada Tambien puede ser usado para romper piedra pero no es muy adecuado para esa tarea.
Your @1 has been repaired successfully.=Su @1 ha sido reparado correctamente.

14
anvil/locale/anvil.fr.tr Normal file
View File

@ -0,0 +1,14 @@
# textdomain: anvil
# ./init.lua
@1 cannot be repaired with an anvil.=
@1's anvil=
A tool for repairing other tools at a blacksmith's anvil.=Un outil pour réparer les autres outils avec une enclume de forgeron.
A tool for repairing other tools in conjunction with a blacksmith's hammer.=Un outil pour réparer les autres outils à utiliser avec un marteau de forgeron.
Anvil=Enclume
Right-click on this anvil with a damaged tool to place the damaged tool upon it. You can then repair the damaged tool by striking it with a blacksmith's hammer. Repeated blows may be necessary to fully repair a badly worn tool. To retrieve the tool either punch or right-click the anvil with an empty hand.=Cliquez-droit sur cette enclume avec un outil endommagé pour le placer dessus. Vous pourrez alors réparer l'outil endommagé en le frappant avec un marteau de forgeron. Des coups successifs seront nécessaires pour réparer l'outil entièrement. Pour récupérer l'outil, frappez dessus ou faites un click-droit en ayant la main vide.
Steel blacksmithing hammer=Marteau de forgeron en acier
This anvil is for damaged tools only.=L'enclume s'utilise sur les outils endommagés.
Use this hammer to strike blows upon an anvil bearing a damaged tool and you can repair it. It can also be used for smashing stone, but it is not well suited to this task.=Utilisez ce marteau pour frapper une enclume contenant un outil endommagé, ainsi vous pourrez le réparer. Il peut être aussi utilisé pour casser de la pierre, mais il n'est pas adapté à cette tâche.
Your @1 has been repaired successfully.=Votre @1 a été réparé avec succès.

14
anvil/locale/anvil.it.tr Normal file
View File

@ -0,0 +1,14 @@
# textdomain: anvil
# ./init.lua
@1 cannot be repaired with an anvil.=
@1's anvil=
A tool for repairing other tools at a blacksmith's anvil.=Un attrezzo per riparare altri attrezzi su di una incudine da fabbro.
A tool for repairing other tools in conjunction with a blacksmith's hammer.=Un attrezzo per riparare altri attrezzi usando un martello da fabbro.
Anvil=Incudine
Right-click on this anvil with a damaged tool to place the damaged tool upon it. You can then repair the damaged tool by striking it with a blacksmith's hammer. Repeated blows may be necessary to fully repair a badly worn tool. To retrieve the tool either punch or right-click the anvil with an empty hand.=Fate click destro su questa incudine con un attrezzo danneggiato per metterlo sull'incudine. Poi potrete ripararlo colpendolo con un martello da fabbro. Potrebbero essere necessari più colpi per riparare un attrezzo gravemente danneggiato. Per riprendere l'attrezzo colpite o fate click destro sull'incudine a mani vuote.
Steel blacksmithing hammer=Martello da fabbro di acciaio
This anvil is for damaged tools only.=Questa incudine è solo per attrezzi danneggiati.
Use this hammer to strike blows upon an anvil bearing a damaged tool and you can repair it. It can also be used for smashing stone, but it is not well suited to this task.=Usate questo martello per colpire una incudine su cui è posto un attrezzo danneggiato e potrete ripararlo. Può anche essere usato per colpire la pietra, ma non è molto adatto a questo compito.
Your @1 has been repaired successfully.=La/il vostr* @1 è stat* riparat* con successo.

View File

@ -1,91 +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: 2019-04-14 21:16-0600\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: XanthinLanguage-Team: LANGUAGE <LL@li.org>\n"
"Language: \n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
#: init.lua:36
msgid "Steel blacksmithing hammer"
msgstr ""
#: init.lua:37
#, fuzzy
msgid "A tool for repairing other tools at a blacksmith's anvil."
msgstr "Stahlhammer um Werkzeuge auf dem Amboss zu reparieren"
#: init.lua:38
msgid ""
"Use this hammer to strike blows upon an anvil bearing a damaged tool and you "
"can repair it. It can also be used for smashing stone, but it is not well "
"suited to this task."
msgstr ""
#: init.lua:136
msgid "Anvil"
msgstr "Amboss"
#: init.lua:137
msgid ""
"A tool for repairing other tools in conjunction with a blacksmith's hammer."
msgstr ""
#: init.lua:138
msgid ""
"Right-click on this anvil with a damaged tool to place the damaged tool upon "
"it. You can then repair the damaged tool by striking it with a blacksmith's "
"hammer. Repeated blows may be necessary to fully repair a badly worn tool. "
"To retrieve the tool either punch or right-click the anvil with an empty "
"hand."
msgstr ""
#: init.lua:193
#, fuzzy
msgid "This anvil is for damaged tools only."
msgstr "Das Werkstueckfeld gilt nur fuer beschaedigtes Werkzeug."
#: init.lua:199
msgid "@1 cannot be repaired with an anvil."
msgstr ""
#: init.lua:325
msgid "Your @1 has been repaired successfully."
msgstr ""
#~ msgid "Workpiece:"
#~ msgstr "Werkstueck:"
#~ msgid "Optional"
#~ msgstr "Moegliche"
#~ msgid "storage for"
#~ msgstr "Aufbewahrung fuer"
#~ msgid "your hammer"
#~ msgstr "deinen Hammer"
#~ msgid "Punch anvil with hammer to"
#~ msgstr "Schlage mit dem Hammer auf den Amboss um"
#~ msgid "repair tool in workpiece-slot."
#~ msgstr "das Werkzeug im Werkstueckfeld zu reparieren."
#~ msgid "anvil"
#~ msgstr "Amboss"
#~ msgid "Anvil (owned by %s)"
#~ msgstr "Amboss (gehoert %s)"
#~ msgid "Owner: %s"
#~ msgstr "Besitzer: %s"

View File

@ -1,69 +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: 2017-03-07 22:17-0700\n"
"PO-Revision-Date: 2017-04-20 19:05 -0500\n"
"Last-Translator: Carlos Barraza <carlosbarrazaes@gmail.com>\n"
"Language-Team: LANGUAGE <LL@li.org>\n"
"Language: Español\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=CHARSET\n"
"Content-Transfer-Encoding: 8bit\n"
#: init.lua:19
msgid "Steel blacksmithing hammer"
msgstr "Martillo de acero para la herrería"
#: init.lua:20
msgid "A tool for repairing other tools at a blacksmith's anvil."
msgstr "Es una herramienta para reparar otras herramientas en el yunque del herrero"
#: init.lua:21
msgid ""
"Use this hammer to strike blows upon an anvil bearing a damaged tool and you "
"can repair it. It can also be used for smashing stone, but it is not well "
"suited to this task."
msgstr ""
"Use este martillo para dar golpes sobre el yunque donde puso la herramienta dañada"
"Tambien puede ser usado para romper piedra pero no es muy adecuado para esa tarea."
#: init.lua:98
msgid "Anvil"
msgstr "Yunque"
#: init.lua:99
msgid ""
"A tool for repairing other tools in conjunction with a blacksmith's hammer."
msgstr "Es una herramienta para reparar de herramientas dañadas en conjunto con el martillo del herrero."
#: init.lua:100
msgid ""
"Right-click on this anvil with a damaged tool to place the damaged tool upon "
"it. You can then repair the damaged tool by striking it with a blacksmith's "
"hammer. Repeated blows may be necessary to fully repair a badly worn tool. "
"To retrieve the tool either punch or right-click the anvil with an empty "
"hand."
msgstr ""
"Haga clic derecho sobre este yunque con una herramienta dañada"
"Puede reparar la herramienta dañada golpeándola con el martillo del herrero"
"Para reparar completamente una herramienta puede dar varios golpes"
"Para sacar la herramienta, golpeela con la mano vacia o tambien con un clic derecho"
#: init.lua:155
msgid "This anvil is for damaged tools only."
msgstr "Este yunque es sólo para herramientas dañadas"
#: init.lua:199
msgid "@1 cannot be repaired with an anvil."
msgstr ""
#: init.lua:267
msgid "Your @1 has been repaired successfully."
msgstr "Su @1 ha sido reparado correctamente."

View File

@ -1,74 +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: 2019-04-14 21:16-0600\n"
"PO-Revision-Date: 2017-06-26 12:22+0200\n"
"Last-Translator: \n"
"Language-Team: \n"
"Language: fr_FR\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"X-Generator: Poedit 2.0.2\n"
"Plural-Forms: nplurals=2; plural=(n > 1);\n"
#: init.lua:36
msgid "Steel blacksmithing hammer"
msgstr "Marteau de forgeron en acier"
#: init.lua:37
msgid "A tool for repairing other tools at a blacksmith's anvil."
msgstr "Un outil pour réparer les autres outils avec une enclume de forgeron."
#: init.lua:38
msgid ""
"Use this hammer to strike blows upon an anvil bearing a damaged tool and you "
"can repair it. It can also be used for smashing stone, but it is not well "
"suited to this task."
msgstr ""
"Utilisez ce marteau pour frapper une enclume contenant un outil endommagé, "
"ainsi vous pourrez le réparer. Il peut être aussi utilisé pour casser de la "
"pierre, mais il n'est pas adapté à cette tâche."
#: init.lua:136
msgid "Anvil"
msgstr "Enclume"
#: init.lua:137
msgid ""
"A tool for repairing other tools in conjunction with a blacksmith's hammer."
msgstr ""
"Un outil pour réparer les autres outils à utiliser avec un marteau de "
"forgeron."
#: init.lua:138
msgid ""
"Right-click on this anvil with a damaged tool to place the damaged tool upon "
"it. You can then repair the damaged tool by striking it with a blacksmith's "
"hammer. Repeated blows may be necessary to fully repair a badly worn tool. "
"To retrieve the tool either punch or right-click the anvil with an empty "
"hand."
msgstr ""
"Cliquez-droit sur cette enclume avec un outil endommagé pour le placer "
"dessus. Vous pourrez alors réparer l'outil endommagé en le frappant avec un "
"marteau de forgeron. Des coups successifs seront nécessaires pour réparer "
"l'outil entièrement. Pour récupérer l'outil, frappez dessus ou faites un "
"click-droit en ayant la main vide."
#: init.lua:193
msgid "This anvil is for damaged tools only."
msgstr "L'enclume s'utilise sur les outils endommagés."
#: init.lua:199
msgid "@1 cannot be repaired with an anvil."
msgstr ""
#: init.lua:325
msgid "Your @1 has been repaired successfully."
msgstr "Votre @1 a été réparé avec succès."

View File

@ -1,72 +0,0 @@
# ITALIAN LOCALE FILE FOR THE ANVIL MODULE
# Copyright (C) 2017 Sokomine
# This file is distributed under the same license as the ANVIL package.
# Hamlet <h4mlet@riseup.net>, 2017.
#
msgid ""
msgstr ""
"Project-Id-Version: Italian locale file for the Anvil module\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2019-04-14 21:16-0600\n"
"PO-Revision-Date: 2017-08-18 16:14+0100\n"
"Last-Translator: H4mlet <h4mlet@riseup.net>\n"
"Language-Team: \n"
"Language: it\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
"X-Generator: Poedit 1.6.10\n"
#: init.lua:36
msgid "Steel blacksmithing hammer"
msgstr "Martello da fabbro di acciaio"
#: init.lua:37
msgid "A tool for repairing other tools at a blacksmith's anvil."
msgstr "Un attrezzo per riparare altri attrezzi su di una incudine da fabbro."
#: init.lua:38
msgid ""
"Use this hammer to strike blows upon an anvil bearing a damaged tool and you "
"can repair it. It can also be used for smashing stone, but it is not well "
"suited to this task."
msgstr ""
"Usate questo martello per colpire una incudine su cui è posto un attrezzo "
"danneggiato e potrete ripararlo. Può anche essere usato per colpire la "
"pietra, ma non è molto adatto a questo compito."
#: init.lua:136
msgid "Anvil"
msgstr "Incudine"
#: init.lua:137
msgid ""
"A tool for repairing other tools in conjunction with a blacksmith's hammer."
msgstr "Un attrezzo per riparare altri attrezzi usando un martello da fabbro."
#: init.lua:138
msgid ""
"Right-click on this anvil with a damaged tool to place the damaged tool upon "
"it. You can then repair the damaged tool by striking it with a blacksmith's "
"hammer. Repeated blows may be necessary to fully repair a badly worn tool. "
"To retrieve the tool either punch or right-click the anvil with an empty "
"hand."
msgstr ""
"Fate click destro su questa incudine con un attrezzo danneggiato per "
"metterlo sull'incudine. Poi potrete ripararlo colpendolo con un martello da "
"fabbro. Potrebbero essere necessari più colpi per riparare un attrezzo "
"gravemente danneggiato. Per riprendere l'attrezzo colpite o fate click "
"destro sull'incudine a mani vuote."
#: init.lua:193
msgid "This anvil is for damaged tools only."
msgstr "Questa incudine è solo per attrezzi danneggiati."
#: init.lua:199
msgid "@1 cannot be repaired with an anvil."
msgstr ""
#: init.lua:325
msgid "Your @1 has been repaired successfully."
msgstr "La/il vostr* @1 è stat* riparat* con successo."

View File

@ -1,63 +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: 2019-04-14 21:16-0600\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"
#: init.lua:36
msgid "Steel blacksmithing hammer"
msgstr ""
#: init.lua:37
msgid "A tool for repairing other tools at a blacksmith's anvil."
msgstr ""
#: init.lua:38
msgid ""
"Use this hammer to strike blows upon an anvil bearing a damaged tool and you "
"can repair it. It can also be used for smashing stone, but it is not well "
"suited to this task."
msgstr ""
#: init.lua:136
msgid "Anvil"
msgstr ""
#: init.lua:137
msgid ""
"A tool for repairing other tools in conjunction with a blacksmith's hammer."
msgstr ""
#: init.lua:138
msgid ""
"Right-click on this anvil with a damaged tool to place the damaged tool upon "
"it. You can then repair the damaged tool by striking it with a blacksmith's "
"hammer. Repeated blows may be necessary to fully repair a badly worn tool. "
"To retrieve the tool either punch or right-click the anvil with an empty "
"hand."
msgstr ""
#: init.lua:193
msgid "This anvil is for damaged tools only."
msgstr ""
#: init.lua:199
msgid "@1 cannot be repaired with an anvil."
msgstr ""
#: init.lua:325
msgid "Your @1 has been repaired successfully."
msgstr ""

14
anvil/locale/template.txt Normal file
View File

@ -0,0 +1,14 @@
# textdomain: anvil
# ./init.lua
@1 cannot be repaired with an anvil.=
@1's anvil=
A tool for repairing other tools at a blacksmith's anvil.=
A tool for repairing other tools in conjunction with a blacksmith's hammer.=
Anvil=
Right-click on this anvil with a damaged tool to place the damaged tool upon it. You can then repair the damaged tool by striking it with a blacksmith's hammer. Repeated blows may be necessary to fully repair a badly worn tool. To retrieve the tool either punch or right-click the anvil with an empty hand.=
Steel blacksmithing hammer=
This anvil is for damaged tools only.=
Use this hammer to strike blows upon an anvil bearing a damaged tool and you can repair it. It can also be used for smashing stone, but it is not well suited to this task.=
Your @1 has been repaired successfully.=

View File

@ -1,6 +0,0 @@
@echo off
setlocal ENABLEEXTENSIONS ENABLEDELAYEDEXPANSION
cd ..
set LIST=
for /r %%X in (*.lua) do set LIST=!LIST! %%X
..\intllib\tools\xgettext.bat %LIST%

View File

@ -1,4 +1,4 @@
name = anvil
depends = default
optional_depends = doc, intllib
optional_depends = doc
description = Hammer and anvil for repairing tools.

View File

@ -2,7 +2,6 @@
bonemeal = {}
local path = minetest.get_modpath("bonemeal")
local table_insert = table.insert
local min, max, random = math.min, math.max, math.random
@ -91,7 +90,9 @@ local deco = {
}
----- local functions
--
-- local functions
--
-- particles
@ -261,11 +262,7 @@ local function check_soil(pos, nodename, strength)
local pos2, nod, def
-- loop through soil
for _,n in pairs(dirt) do
pos2 = n
pos2.y = pos2.y + 1
for _, n in pairs(dirt) do
if random(5) == 5 then
if decor and #decor > 0 then
@ -281,9 +278,22 @@ local function check_soil(pos, nodename, strength)
end
end
pos2 = n
pos2.y = pos2.y + 1
if nod and nod ~= "" then
-- get crop param2 value
def = minetest.registered_nodes[nod]
def = def and def.place_param2 or 0
def = def and def.place_param2
-- if param2 not preset then get from existing node
if not def then
local node = minetest.get_node_or_nil(pos2)
def = node and node.param2 or 0
end
minetest.set_node(pos2, {name = nod, param2 = def})
end
@ -302,7 +312,7 @@ end
function bonemeal:add_sapling(list)
for n = 1, #list do
table_insert(saplings, list[n])
saplings[#saplings + 1] = list[n]
end
end
@ -313,7 +323,7 @@ end
function bonemeal:add_crop(list)
for n = 1, #list do
table_insert(crops, list[n])
crops[#crops + 1] = list[n]
end
end
@ -333,11 +343,11 @@ function bonemeal:add_deco(list)
if list[l][1] == deco[n][1] then
-- adding grass types
for _,extra in pairs(list[l][2]) do
for _, extra in pairs(list[l][2]) do
if extra ~= "" then
for _,entry in pairs(deco[n][2]) do
for _, entry in pairs(deco[n][2]) do
if extra == entry then
extra = false
@ -347,16 +357,16 @@ function bonemeal:add_deco(list)
end
if extra then
table_insert(deco[n][2], extra)
deco[n][2][#deco[n][2] + 1] = extra
end
end
-- adding decoration types
for _,extra in ipairs(list[l][3]) do
for _, extra in ipairs(list[l][3]) do
if extra ~= "" then
for __,entry in pairs(deco[n][3]) do
for __, entry in pairs(deco[n][3]) do
if extra == entry then
extra = false
@ -366,7 +376,7 @@ function bonemeal:add_deco(list)
end
if extra then
table_insert(deco[n][3], extra)
deco[n][3][#deco[n][3] + 1] = extra
end
end
@ -376,7 +386,7 @@ function bonemeal:add_deco(list)
end
if list[l] then
table_insert(deco, list[l])
deco[#deco + 1] = list[l]
end
end
end
@ -400,7 +410,7 @@ function bonemeal:set_deco(list)
end
if list[l] then
table_insert(deco, list[l])
deco[#deco + 1] = list[l]
end
end
end
@ -461,7 +471,9 @@ function bonemeal:on_use(pos, strength, node)
end
----- items
--
-- items
--
-- mulch (strength 1)
@ -568,7 +580,10 @@ minetest.register_craftitem("bonemeal:gelatin_powder", {
})
--- crafting recipes
--
-- crafting recipes
--
-- gelatin powder
minetest.register_craft({
@ -636,7 +651,7 @@ minetest.override_item("default:dirt", {
items = {"default:dirt"}
}
}
},
}
})

218
castle_masonry/i18n.py Normal file
View File

@ -0,0 +1,218 @@
#!/usr/bin/env python
# -*- 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
# LGPLv2.1+
from __future__ import print_function
import os, fnmatch, re, shutil, errno
#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
#TODO: support [[]] delimiters
pattern_lua = re.compile(r'[\.=^\t,{\(\s]N?S\(\s*(["\'])((?:\\\1|(?:(?!\1)).)*)(\1)[\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(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(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(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):
print(tr_name + " already exists, ignoring " + name)
continue
fname = os.path.join(root, name)
with open(fname, "r", encoding='utf-8') as po_file:
print("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
# Writes a template.txt file
def write_template(templ_file, lkeyStrings):
lOut = []
lkeyStrings.sort()
for s in lkeyStrings:
lOut.append("%s=" % s)
mkdir_p(os.path.dirname(templ_file))
with open(templ_file, "wt", encoding='utf-8') as template_file:
template_file.write("\n".join(lOut))
# 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()
text = re.sub(pattern_concat, "", text)
for s in pattern_lua.findall(text):
s = s[1]
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
def import_tr_file(tr_file):
dOut = {}
if os.path.exists(tr_file):
with open(tr_file, "r", encoding='utf-8') as existing_file :
for line in existing_file.readlines():
s = line.strip()
if s == "" or s[0] == "#":
continue
match = pattern_tr.match(s)
if match:
dOut[match.group(1)] = match.group(2)
return dOut
# Walks all lua files in the mod folder, collects translatable strings,
# and writes it to a template.txt file
def generate_template(folder):
lOut = []
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)
print(fname + ": " + str(len(found)) + " translatable strings")
lOut.extend(found)
lOut = list(set(lOut))
lOut.sort()
if len(lOut) == 0:
return None
templ_file = folder + "locale/template.txt"
write_template(templ_file, lOut)
return lOut
# Updates an existing .tr file, copying the old one to a ".old" file
def update_tr_file(lNew, mod_name, tr_file):
print("updating " + tr_file)
lOut = ["# textdomain: %s\n" % mod_name]
#TODO only make a .old if there are actual changes from the old file
if os.path.exists(tr_file):
shutil.copyfile(tr_file, tr_file+".old")
dOld = import_tr_file(tr_file)
for key in lNew:
val = dOld.get(key, "")
lOut.append("%s=%s" % (key, val))
lOut.append("##### not used anymore #####")
for key in dOld:
if key not in lNew:
lOut.append("%s=%s" % (key, dOld[key]))
with open(tr_file, "w", encoding='utf-8') as new_tr_file:
new_tr_file.write("\n".join(lOut))
# 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("Updating translations for " + modname)
data = generate_template(folder)
if data == None:
print("No translatable strings found in " + modname)
else:
for tr_file in get_existing_tr_files(folder):
update_tr_file(data, modname, folder + "locale/" + tr_file)
else:
print("Unable to find modname in folder " + folder)
def update_folder(folder):
is_modpack = os.path.exists(folder+"modpack.txt") or os.path.exists(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.")
update_folder("./")
# Runs this script on each sub-folder in the parent folder.
# I'm using this for testing this script on all installed mods.
#for modfolder in [f.path for f in os.scandir("../") if f.is_dir()]:
# update_folder(modfolder + "/")

View File

@ -0,0 +1,50 @@
# textdomain: castle_masonry
@1 Arrowslit=Aspillera de @1
@1 Arrowslit with Cross=Aspillera con Crus de @1
@1 Arrowslit with Hole=Aspillera con Agujero de @1
@1 Crossbrace=Viga de @1
@1 Embrasure=Aféizar de @1
@1 Extended Crossbrace=Viga Extendida de @1
@1 Half Pillar Base=Base de Medio Pilar de @1
@1 Half Pillar Middle=Medio del Medio Pilar de @1
@1 Half Pillar Top=Parte Superior de Medio Pilar @1
@1 Machicolation=Matacán de @1
@1 Murder Hole=Agujero de @1
@1 Pillar Base=Base de Pilar de @1
@1 Pillar Middle=Medio Pilar de @1
@1 Pillar Top=Parte Superior de Pilar de @1
Castle Corner=Esquina de Castillo
Castle Pavement Slab=Pavimento de Castillo
Castle Pavement Stair=Escalera de Castillo Pavimentada
Castle Rubble=Escombros de Castillo
Castle Rubble Slab=Losa de Escombro de Castillo
Castle Rubble Stair=Escalera de Escombro de Castillo
Castle Stonewall Slab=Losa de Pared de Castillo
Castle Stonewall Stair=Escalera de Pared de Castillo
Castle Wall=Pared de Castillo
Cobble=Adoquín
Desert Sandstone=Piedra del Desierto
Desert Sandstone Brick=Ladrillo de Piedra del Desierto
Desert Stone=Piedra del Desierto
Desert Stone Brick=Ladrillo de Piedra del Desierto
Dungeon Stone=Piedra de Mazmorra
Dungeon Stone Slab=Losa de Piedra de Mazmorra
Dungeon Stone Stair=Escalera de Piedra de Mazmorra
Ice=Hielo
Obsidian Brick=Ladrillo de Obsidiana
Pavement Brick=Ladrillo Pavimentado
Paving Stone=Piedra Pavimentada
Roof Slates=Pizarras de Techo
Rubble=Escombros
Sandstone=Arenisca
Sandstone Brick=Ladrillo de Arenisca
Silver Sandstone=Arenisca
Silver Sandstone Brick=Ladrillo de Arenisca
Snow=Nieve
Stone=Piedra
Stone Wall=Pared de Piedra
Stonebrick=Ladrillo de Piedra
Stonewall=Pared de piedra
Wood=Madera
##### not used anymore #####

View File

@ -0,0 +1,50 @@
# textdomain: castle_masonry
@1 Arrowslit=Meurtrière en @1
@1 Arrowslit with Cross=Meurtrière en croix en @1
@1 Arrowslit with Hole=Meurtrière avec trou en @1
@1 Crossbrace=Travers en @1
@1 Embrasure=Embrasure en @1
@1 Extended Crossbrace=Travers entendu en @1
@1 Half Pillar Base=Base de demi pilier en @1
@1 Half Pillar Middle=Milieu de demi pilier en @1
@1 Half Pillar Top=Haut de demi pilier en @1
@1 Machicolation=Machicoulis en @1
@1 Murder Hole=Trou en @1
@1 Pillar Base=Base de pilier en @1
@1 Pillar Middle=Milieu de pilier en @1
@1 Pillar Top=Haut de pilier en @1
Castle Corner=Angle de chateau
Castle Pavement Slab=Dalle de chateau pavé
Castle Pavement Stair=Escaliers de chateau pavé
Castle Rubble=Gravats de chateau
Castle Rubble Slab=Dalle en gravats de chateau
Castle Rubble Stair=Escalier en gravats de chateau
Castle Stonewall Slab=Dalle en pierre brune
Castle Stonewall Stair=Escalier en pierre brune
Castle Wall=Pierre brune
Cobble=Pavé
Desert Sandstone=Pierre du désert
Desert Sandstone Brick=Brique de pierre du désert
Desert Stone=Pierre du désert
Desert Stone Brick=Brique de pierre du désert
Dungeon Stone=Pierre de dongeon
Dungeon Stone Slab=Dalle en pierre de dongeon
Dungeon Stone Stair=Escalier en pierre de dongeon
Ice=Glace
Obsidian Brick=Brique d'obsidienne
Pavement Brick=Brique de pavage
Paving Stone=Pierre de pavage
Roof Slates=Toiture en ardoise
Rubble=Décombre
Sandstone=Grès
Sandstone Brick=Brique de grès
Silver Sandstone=Grès
Silver Sandstone Brick=Brique de grès
Snow=Neige
Stone=Pierre
Stone Wall=Mur de pierre
Stonebrick=Brique de pierre
Stonewall=Pierre brune
Wood=Bois
##### not used anymore #####

View File

@ -1,49 +1,50 @@
# textdomain:castle_masonry
# textdomain: castle_masonry
@1 Arrowslit=Feritoia per frecce di @1
@1 Arrowslit with Cross=Feritoia a croce per frecce di @1
@1 Arrowslit with Hole=Feritoia a foro per frecce di @1
@1 Embrasure=Feritoia di @1
Stonewall=muro di pietra
Cobble=ciottoli
Stonebrick=mattone di pietra
Sandstone Brick=mattone d'arenaria
Desert Stone Brick=mattone di pietra del deserto
Desert Sandstone Brick=mattone d'arenaria del deserto
Silver Sandstone Brick=mattone d'arenaria argentata
Stone=pietra
Sandstone=arenaria
Desert Stone=pietra del deserto
Desert Sandstone=arenaria del deserto
Silver Sandstone=arenaria argentata
Wood=legno
Ice=ghiaccio
Snow=neve
Obsidian Brick=mattone d'ossidiana
@1 Murder Hole=Buca assassina di @1
@1 Machicolation=Caditoia di @1
Paving Stone=Pietra pavimentale
Pavement Brick=Mattone pavimentale
Castle Pavement Stair=Scala pavimentale del castello
Castle Pavement Slab=Lastra pavimentale del castello
Roof Slates=Tegole d'ardesia
@1 Pillar Base=Base della colonna di @1
@1 Half Pillar Base=Mezza base della colonna di @1
@1 Pillar Top=Capitello di @1
@1 Half Pillar Top=Mezzo capitello di @1
@1 Pillar Middle=Fusto della colonna di @1
@1 Half Pillar Middle=Mezzo fusto della colonna di @1
@1 Crossbrace=Costolone di @1
@1 Embrasure=Feritoia di @1
@1 Extended Crossbrace=Costolone esteso di @1
Castle Wall=Muro del castello
Castle Rubble=Detriti del castello
@1 Half Pillar Base=Mezza base della colonna di @1
@1 Half Pillar Middle=Mezzo fusto della colonna di @1
@1 Half Pillar Top=Mezzo capitello di @1
@1 Machicolation=Caditoia di @1
@1 Murder Hole=Buca assassina di @1
@1 Pillar Base=Base della colonna di @1
@1 Pillar Middle=Fusto della colonna di @1
@1 Pillar Top=Capitello di @1
Castle Corner=Angolo del castello
Stone Wall=Muro di pietra
Rubble=Detriti
Castle Stonewall Stair=Scala del castello in muro di pietra
Castle Stonewall Slab=Lastra del castello in muro di pietra
Castle Rubble Stair=Scala del castello in detriti
Castle Pavement Slab=Lastra pavimentale del castello
Castle Pavement Stair=Scala pavimentale del castello
Castle Rubble=Detriti del castello
Castle Rubble Slab=Lastra del castello in detriti
Castle Rubble Stair=Scala del castello in detriti
Castle Stonewall Slab=Lastra del castello in muro di pietra
Castle Stonewall Stair=Scala del castello in muro di pietra
Castle Wall=Muro del castello
Cobble=ciottoli
Desert Sandstone=arenaria del deserto
Desert Sandstone Brick=mattone d'arenaria del deserto
Desert Stone=pietra del deserto
Desert Stone Brick=mattone di pietra del deserto
Dungeon Stone=Pietra del sotterraneo
Dungeon Stone Stair=Scala di pietra del sotterraneo
Dungeon Stone Slab=Lastra di pietra del sotterraneo
Dungeon Stone Stair=Scala di pietra del sotterraneo
Ice=ghiaccio
Obsidian Brick=mattone d'ossidiana
Pavement Brick=Mattone pavimentale
Paving Stone=Pietra pavimentale
Roof Slates=Tegole d'ardesia
Rubble=Detriti
Sandstone=arenaria
Sandstone Brick=mattone d'arenaria del deserto
Silver Sandstone=arenaria argentata
Silver Sandstone Brick=mattone d'arenaria argentata
Snow=neve
Stone=pietra
Stone Wall=Muro di pietra
Stonebrick=mattone di pietra
Stonewall=muro di pietra
Wood=legno
##### not used anymore #####

View File

@ -1,18 +1,8 @@
-- Used for localization, choose either built-in or intllib.
local S = minetest.get_translator("castle_tapestries")
local MP, S, NS = nil
if (minetest.get_modpath("intllib") == nil) then
S = minetest.get_translator("castle_tapestries")
else
-- internationalization boilerplate
MP = minetest.get_modpath(minetest.get_current_modname())
S, NS = dofile(MP.."/intllib.lua")
end
-- cottages support
local use_cottages = minetest.get_modpath("cottages")
local tapestry = {}
@ -142,35 +132,37 @@ minetest.register_craft({
recipe = {'wool:white', 'default:stick'},
})
minetest.register_craft({
type = "shapeless",
output = 'castle_tapestries:tapestry',
recipe = {'cottages:wool', 'default:stick'},
})
minetest.register_craft({
type = "shapeless",
output = 'castle_tapestries:tapestry_long',
recipe = {'wool:white', 'castle_tapestries:tapestry'},
})
minetest.register_craft({
type = "shapeless",
output = 'castle_tapestries:tapestry_long',
recipe = {'cottages:wool', 'castle_tapestries:tapestry'},
})
minetest.register_craft({
type = "shapeless",
output = 'castle_tapestries:tapestry_very_long',
recipe = {'wool:white', 'castle_tapestries:tapestry_long'},
})
minetest.register_craft({
type = "shapeless",
output = 'castle_tapestries:tapestry_very_long',
recipe = {'cottages:wool', 'castle_tapestries:tapestry_long'},
})
if use_cottages then
minetest.register_craft({
type = "shapeless",
output = 'castle_tapestries:tapestry',
recipe = {'cottages:wool', 'default:stick'},
})
minetest.register_craft({
type = "shapeless",
output = 'castle_tapestries:tapestry_long',
recipe = {'cottages:wool', 'castle_tapestries:tapestry'},
})
minetest.register_craft({
type = "shapeless",
output = 'castle_tapestries:tapestry_very_long',
recipe = {'cottages:wool', 'castle_tapestries:tapestry_long'},
})
end
unifieddyes.register_color_craft({

View File

@ -1,45 +0,0 @@
-- Fallback functions for when `intllib` is not installed.
-- Code released under Unlicense <http://unlicense.org>.
-- Get the latest version of this file at:
-- https://raw.githubusercontent.com/minetest-mods/intllib/master/lib/intllib.lua
local function format(str, ...)
local args = { ... }
local function repl(escape, open, num, close)
if escape == "" then
local replacement = tostring(args[tonumber(num)])
if open == "" then
replacement = replacement..close
end
return replacement
else
return "@"..open..num..close
end
end
return (str:gsub("(@?)@(%(?)(%d+)(%)?)", repl))
end
local gettext, ngettext
if minetest.get_modpath("intllib") then
if intllib.make_gettext_pair then
-- New method using gettext.
gettext, ngettext = intllib.make_gettext_pair()
else
-- Old method using text files.
gettext = intllib.Getter()
end
end
-- Fill in missing functions.
gettext = gettext or function(msgid, ...)
return format(msgid, ...)
end
ngettext = ngettext or function(msgid, msgid_plural, n, ...)
return format(n==1 and msgid or msgid_plural, ...)
end
return gettext, ngettext

View File

@ -0,0 +1,6 @@
# textdomain:castle_tapestries
Tapestry Top=Haut de tapisserie
Tapestry=Tapisserie
Tapestry (Long)=Tapisserie (longue)
Tapestry (Very Long)=Tapisserie (très longue)

View File

@ -1,35 +0,0 @@
# ITALIAN LOCALE FILE FOR THE CASTLE TAPESTRIES MODULE
# Copyright (C) 2017 Philipbenr And DanDuncombe
# This file is distributed under the same license as the CASTLE TAPESTRIES package.
# Hamlet <h4mlet@riseup.net>, 2017.
#
msgid ""
msgstr ""
"Project-Id-Version: Castle Tapestries\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2017-02-25 14:32-0700\n"
"PO-Revision-Date: 2017-09-20 00:41+0100\n"
"Last-Translator: Hamlet <h4mlet@riseup.net>\n"
"Language-Team: \n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
"Language: it\n"
"X-Generator: Poedit 1.6.10\n"
#: init.lua:14
msgid "Tapestry Top"
msgstr "Cima dell'arazzo"
#: init.lua:64
msgid "Tapestry"
msgstr "Arazzo"
#: init.lua:94
msgid "Tapestry (Long)"
msgstr "Arazzo (lungo)"
#: init.lua:124
msgid "Tapestry (Very Long)"
msgstr "Arazzo (molto lungo)"

View File

@ -1,33 +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: 2017-02-25 14:32-0700\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"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=CHARSET\n"
"Content-Transfer-Encoding: 8bit\n"
#: init.lua:14
msgid "Tapestry Top"
msgstr ""
#: init.lua:64
msgid "Tapestry"
msgstr ""
#: init.lua:94
msgid "Tapestry (Long)"
msgstr ""
#: init.lua:124
msgid "Tapestry (Very Long)"
msgstr ""

View File

@ -1,4 +1,4 @@
name = castle_tapestries
depends = default, unifieddyes
optional_depends = intllib
description = This is a mod for creating medieval tapestries, as found in castles.
depends = default, unifieddyes, wool
optional_depends = cottages
description = This is a mod for creating medieval tapestries, as found in castles.

View File

@ -1,4 +1,3 @@
local S = homedecor.gettext
local shapes = {
@ -220,10 +219,10 @@ local function step(pos, fields)
if fields then
if fields.new then
new_game(pos)
else
elseif t then
key(fields)
end
else
elseif t then
run = tick()
end

View File

@ -2,6 +2,7 @@ homedecor_common
default
dye
creative
basic_materials
moreblocks?
building_blocks?
bucket?

View File

@ -349,7 +349,7 @@ minetest.register_craft({
recipe = {
{ "","homedecor:fence_chainlink","" },
{ "default:steel_ingot","fake_fire:embers","default:steel_ingot" },
{ "homedecor:pole_wrought_iron","default:steel_ingot","homedecor:pole_wrought_iron" }
{ "basic_materials:steel_bar","default:steel_ingot","basic_materials:steel_bar" }
},
})

View File

@ -920,7 +920,7 @@ minetest.register_craft({
minetest.register_craft({
output = "homedecor:sportbench",
recipe = {
{ "stairs:slab_steelblock","homedecor:pole_wrought_iron","stairs:slab_steelblock" },
{ "stairs:slab_steelblock","basic_materials:steel_bar","stairs:slab_steelblock" },
{ "default:steel_ingot","wool:black","default:steel_ingot" },
{ "default:steel_ingot","wool:black","default:steel_ingot" }
},

View File

@ -2,3 +2,4 @@ default
wool
homedecor_common
unifieddyes
basic_materials

View File

@ -212,7 +212,7 @@ minetest.register_craft( {
recipe = {
{ "group:wood", "group:wood", "group:wood" },
{ "group:wood", "group:wood", "group:wood" },
{ "homedecor:pole_wrought_iron", "", "homedecor:pole_wrought_iron" }
{ "basic_materials:steel_bar", "", "basic_materials:steel_bar" }
},
})
@ -316,7 +316,7 @@ minetest.register_craft({
recipe = {
{ "", "", "wool:black" },
{ "", "wool:black", "default:steel_ingot" },
{ "group:stick", "homedecor:pole_wrought_iron", "group:stick" }
{ "group:stick", "basic_materials:steel_bar", "group:stick" }
},
})
@ -325,7 +325,7 @@ minetest.register_craft({
recipe = {
{ "dye:black", "building_blocks:sticks", "group:wool" },
{ "basic_materials:plastic_sheet", "group:wool", "default:steel_ingot" },
{ "building_blocks:sticks", "homedecor:pole_wrought_iron", "building_blocks:sticks" }
{ "building_blocks:sticks", "basic_materials:steel_bar", "building_blocks:sticks" }
},
})

View File

@ -1,3 +1,4 @@
local S = minetest.get_translator("pipeworks")
local autocrafterCache = {} -- caches some recipe data to avoid to call the slow function minetest.get_craft_result() every second
local craft_time = 1
@ -16,7 +17,7 @@ end
local function get_item_info(stack)
local name = stack:get_name()
local def = minetest.registered_items[name]
local description = def and def.description or "Unknown item"
local description = def and def.description or S("Unknown item")
return description, name
end
@ -68,7 +69,7 @@ local function run_autocrafter(pos, elapsed)
local output_item = craft.output.item
-- only use crafts that have an actual result
if output_item:is_empty() then
meta:set_string("infotext", "unconfigured Autocrafter: unknown recipe")
meta:set_string("infotext", S("unconfigured Autocrafter: unknown recipe"))
return false
end
@ -101,7 +102,7 @@ local function after_recipe_change(pos, inventory)
if inventory:is_empty("recipe") then
minetest.get_node_timer(pos):stop()
autocrafterCache[minetest.hash_node_position(pos)] = nil
meta:set_string("infotext", "unconfigured Autocrafter")
meta:set_string("infotext", S("unconfigured Autocrafter"))
inventory:set_stack("output", 1, "")
return
end
@ -126,7 +127,7 @@ local function after_recipe_change(pos, inventory)
craft = craft or get_craft(pos, inventory, hash)
local output_item = craft.output.item
local description, name = get_item_info(output_item)
meta:set_string("infotext", string.format("'%s' Autocrafter (%s)", description, name))
meta:set_string("infotext", S("'@1' Autocrafter (@2)", description, name))
inventory:set_stack("output", 1, output_item)
after_inventory_change(pos)
@ -190,8 +191,8 @@ local function update_meta(meta, enabled)
"listring[context;dst]" ..
"listring[current_player;main]"
if minetest.get_modpath("digilines") then
fs = fs.."field[1,3.5;4,1;channel;Channel;${channel}]"
fs = fs.."button_exit[5,3.2;2,1;save;Save]"
fs = fs.."field[1,3.5;4,1;channel;"..S("Channel")..";${channel}]"
fs = fs.."button_exit[5,3.2;2,1;save;"..S("Save").."]"
end
meta:set_string("formspec",fs)
@ -200,13 +201,13 @@ local function update_meta(meta, enabled)
-- this might be more written code, but actually executes less
local output = meta:get_inventory():get_stack("output", 1)
if output:is_empty() then -- doesn't matter if paused or not
meta:set_string("infotext", "unconfigured Autocrafter")
meta:set_string("infotext", S("unconfigured Autocrafter"))
return false
end
local description, name = get_item_info(output)
local infotext = enabled and string.format("'%s' Autocrafter (%s)", description, name)
or string.format("paused '%s' Autocrafter", description)
local infotext = enabled and S("'@1' Autocrafter (@2)", description, name)
or S("paused '@1' Autocrafter", description)
meta:set_string("infotext", infotext)
return enabled
@ -226,7 +227,7 @@ local function upgrade_autocrafter(pos, meta)
update_meta(meta, true)
if meta:get_string("virtual_items") == "1" then -- we are version 2
-- we allready dropped stuff, so lets remove the metadatasetting (we are not being called again for this node)
-- we already dropped stuff, so lets remove the metadatasetting (we are not being called again for this node)
meta:set_string("virtual_items", "")
else -- we are version 1
local recipe = inv:get_list("recipe")
@ -248,7 +249,7 @@ local function upgrade_autocrafter(pos, meta)
end
minetest.register_node("pipeworks:autocrafter", {
description = "Autocrafter",
description = S("Autocrafter"),
drawtype = "normal",
tiles = {"pipeworks_autocrafter.png"},
groups = {snappy = 3, tubedevice = 1, tubedevice_receiver = 1},

View File

@ -1,7 +1,10 @@
-- this file is basically a modified copy of
-- minetest_game/mods/default/furnaces.lua
-- translation support
local S = minetest.get_translator("pipeworks")
local DS = minetest.get_translator("default")
local fs_helpers = pipeworks.fs_helpers
tube_entry = "^pipeworks_tube_connection_stony.png"
@ -36,7 +39,7 @@ local function active_formspec(fuel_percent, item_percent, pos, meta)
pipeworks.button_off,
pipeworks.button_on
}
).."label[0.9,3.51;Allow splitting incoming material (not fuel) stacks from tubes]"
).."label[0.9,3.51;"..S("Allow splitting incoming material (not fuel) stacks from tubes").."]"
return formspec
end
@ -67,7 +70,7 @@ local function inactive_formspec(pos, meta)
pipeworks.button_off,
pipeworks.button_on
}
).."label[0.9,3.51;Allow splitting incoming material (not fuel) stacks from tubes]"
).."label[0.9,3.51;"..S("Allow splitting incoming material (not fuel) stacks from tubes").."]"
return formspec
end
@ -90,7 +93,7 @@ local function allow_metadata_inventory_put(pos, listname, index, stack, player)
if listname == "fuel" then
if minetest.get_craft_result({method="fuel", width=1, items={stack}}).time ~= 0 then
if inv:is_empty("src") then
meta:set_string("infotext", "Furnace is empty")
meta:set_string("infotext", DS("Furnace is empty"))
end
return stack:get_count()
else
@ -219,40 +222,40 @@ local function furnace_node_timer(pos, elapsed)
if cookable then
item_percent = math.floor(src_time / cooked.time * 100)
if item_percent > 100 then
item_state = "100% (output full)"
item_state = DS("100% (output full)")
else
item_state = item_percent .. "%"
item_state = DS("@1%", item_percent)
end
else
if srclist[1]:is_empty() then
item_state = "Empty"
item_state = DS("Empty")
else
item_state = "Not cookable"
item_state = DS("Not cookable")
end
end
local fuel_state = "Empty"
local active = "inactive "
local fuel_state = DS("Empty")
local active = DS("Furnace inactive")
local result = false
if fuel_totaltime ~= 0 then
active = "active "
active = DS("Furnace active")
local fuel_percent = math.floor(fuel_time / fuel_totaltime * 100)
fuel_state = fuel_percent .. "%"
fuel_state = DS("@1%", fuel_percent)
formspec = active_formspec(fuel_percent, item_percent, pos, meta)
swap_node(pos, "default:furnace_active")
-- make sure timer restarts automatically
result = true
else
if not fuellist[1]:is_empty() then
fuel_state = "0%"
fuel_state = DS("@1%", "0")
end
swap_node(pos, "default:furnace")
-- stop timer on the inactive furnace
minetest.get_node_timer(pos):stop()
end
local infotext = "Furnace " .. active .. "(Item: " .. item_state .. "; Fuel: " .. fuel_state .. ")"
local infotext = active.." "..DS("(Item: @1; Fuel: @2)", item_state, fuel_state)
--
-- Set meta values
@ -271,7 +274,7 @@ end
--
minetest.register_node(":default:furnace", {
description = "Furnace",
description = DS("Furnace"),
tiles = {
"default_furnace_top.png"..tube_entry,
"default_furnace_bottom.png"..tube_entry,
@ -360,7 +363,7 @@ minetest.register_node(":default:furnace", {
})
minetest.register_node(":default:furnace_active", {
description = "Furnace",
description = DS("Furnace"),
tiles = {
"default_furnace_top.png"..tube_entry,
"default_furnace_bottom.png"..tube_entry,

View File

@ -1,7 +1,9 @@
local S = minetest.get_translator("pipeworks")
local straight = function(pos, node, velocity, stack) return {velocity} end
minetest.register_node("pipeworks:steel_block_embedded_tube", {
description = "Airtight steelblock embedded tube",
description = S("Airtight steelblock embedded tube"),
tiles = {
"default_steel_block.png", "default_steel_block.png",
"default_steel_block.png", "default_steel_block.png",
@ -45,7 +47,7 @@ local pane_box = {
}
minetest.register_node("pipeworks:steel_pane_embedded_tube", {
drawtype = "nodebox",
description = "Airtight panel embedded tube ",
description = S("Airtight panel embedded tube"),
tiles = {
"pipeworks_pane_embedded_tube_sides.png^[transformR90",
"pipeworks_pane_embedded_tube_sides.png^[transformR90",

View File

@ -1,7 +0,0 @@
default
basic_materials
screwdriver
mesecons?
mesecons_mvps?
digilines?
signs_lib?

View File

@ -1 +0,0 @@
This mod uses mesh nodes and nodeboxes to supply a complete set of 3D pipes and tubes, along with devices that work with them.

View File

@ -1,3 +1,4 @@
local S = minetest.get_translator("pipeworks")
local new_flow_logic_register = pipeworks.flowables.register
local polys = ""
@ -135,7 +136,7 @@ for s in ipairs(states) do
local pumpname = "pipeworks:pump_"..states[s]
minetest.register_node(pumpname, {
description = "Pump/Intake Module",
description = S("Pump/Intake Module"),
drawtype = "mesh",
mesh = "pipeworks_pump"..polys..".obj",
tiles = { "pipeworks_pump_"..states[s]..".png" },
@ -178,7 +179,7 @@ for s in ipairs(states) do
local nodename_valve_empty = "pipeworks:valve_"..states[s].."_empty"
minetest.register_node(nodename_valve_empty, {
description = "Valve",
description = S("Valve"),
drawtype = "mesh",
mesh = "pipeworks_valve_"..states[s]..polys..".obj",
tiles = { "pipeworks_valve.png" },
@ -224,7 +225,7 @@ end
local nodename_valve_loaded = "pipeworks:valve_on_loaded"
minetest.register_node(nodename_valve_loaded, {
description = "Valve",
description = S("Valve"),
drawtype = "mesh",
mesh = "pipeworks_valve_on"..polys..".obj",
tiles = { "pipeworks_valve.png" },
@ -272,7 +273,7 @@ new_flow_logic_register.directional_horizonal_rotate(nodename_valve_loaded, true
-- FIXME: should this do anything useful in the new flow logic?
minetest.register_node("pipeworks:grating", {
description = "Decorative grating",
description = S("Decorative grating"),
tiles = {
"pipeworks_grating_top.png",
"pipeworks_grating_sides.png",
@ -305,7 +306,7 @@ minetest.register_node("pipeworks:grating", {
local nodename_spigot_empty = "pipeworks:spigot"
minetest.register_node(nodename_spigot_empty, {
description = "Spigot outlet",
description = S("Spigot outlet"),
drawtype = "mesh",
mesh = "pipeworks_spigot"..polys..".obj",
tiles = { "pipeworks_spigot.png" },
@ -336,7 +337,7 @@ minetest.register_node(nodename_spigot_empty, {
local nodename_spigot_loaded = "pipeworks:spigot_pouring"
minetest.register_node(nodename_spigot_loaded, {
description = "Spigot outlet",
description = S("Spigot outlet"),
drawtype = "mesh",
mesh = "pipeworks_spigot_pouring"..polys..".obj",
tiles = {
@ -402,7 +403,7 @@ local panel_cbox = {
local nodename_panel_empty = "pipeworks:entry_panel_empty"
minetest.register_node(nodename_panel_empty, {
description = "Airtight Pipe entry/exit",
description = S("Airtight Pipe entry/exit"),
drawtype = "mesh",
mesh = "pipeworks_entry_panel"..polys..".obj",
tiles = { "pipeworks_entry_panel.png" },
@ -422,7 +423,7 @@ minetest.register_node(nodename_panel_empty, {
local nodename_panel_loaded = "pipeworks:entry_panel_loaded"
minetest.register_node(nodename_panel_loaded, {
description = "Airtight Pipe entry/exit",
description = S("Airtight Pipe entry/exit"),
drawtype = "mesh",
mesh = "pipeworks_entry_panel"..polys..".obj",
tiles = { "pipeworks_entry_panel.png" },
@ -448,7 +449,7 @@ new_flow_logic_register.directional_horizonal_rotate(nodename_panel_loaded, true
local nodename_sensor_empty = "pipeworks:flow_sensor_empty"
minetest.register_node(nodename_sensor_empty, {
description = "Flow Sensor",
description = S("Flow Sensor"),
drawtype = "mesh",
mesh = "pipeworks_flow_sensor"..polys..".obj",
tiles = { "pipeworks_flow_sensor_off.png" },
@ -487,7 +488,7 @@ minetest.register_node(nodename_sensor_empty, {
local nodename_sensor_loaded = "pipeworks:flow_sensor_loaded"
minetest.register_node(nodename_sensor_loaded, {
description = "Flow sensor (on)",
description = S("Flow sensor (on)"),
drawtype = "mesh",
mesh = "pipeworks_flow_sensor"..polys..".obj",
tiles = { "pipeworks_flow_sensor_on.png" },
@ -536,18 +537,18 @@ new_flow_logic_register.transition_simple_set(sensor_pressure_set, { mesecons=pi
-- TODO flow-logic-stub: these don't currently do anything under the new flow logic.
for fill = 0, 10 do
local filldesc="empty"
local filldesc=S("empty")
local sgroups = {snappy=3, pipe=1, tankfill=fill+1}
local image = nil
if fill ~= 0 then
filldesc=fill.."0% full"
filldesc=S("@1% full", 10*fill)
sgroups = {snappy=3, pipe=1, tankfill=fill+1, not_in_creative_inventory=1}
image = "pipeworks_storage_tank_fittings.png"
end
minetest.register_node("pipeworks:expansion_tank_"..fill, {
description = "Expansion Tank ("..filldesc..")... You hacker, you.",
description = S("Expansion Tank (@1)", filldesc),
tiles = {
"pipeworks_storage_tank_fittings.png",
"pipeworks_storage_tank_fittings.png",
@ -575,7 +576,7 @@ for fill = 0, 10 do
})
minetest.register_node("pipeworks:storage_tank_"..fill, {
description = "Fluid Storage Tank ("..filldesc..")",
description = S("Fluid Storage Tank (@1)", filldesc),
tiles = {
"pipeworks_storage_tank_fittings.png",
"pipeworks_storage_tank_fittings.png",
@ -607,7 +608,7 @@ end
local nodename_fountain_empty = "pipeworks:fountainhead"
minetest.register_node(nodename_fountain_empty, {
description = "Fountainhead",
description = S("Fountainhead"),
drawtype = "mesh",
mesh = "pipeworks_fountainhead"..polys..".obj",
tiles = { "pipeworks_fountainhead.png" },
@ -641,7 +642,7 @@ minetest.register_node(nodename_fountain_empty, {
local nodename_fountain_loaded = "pipeworks:fountainhead_pouring"
minetest.register_node(nodename_fountain_loaded, {
description = "Fountainhead",
description = S("Fountainhead"),
drawtype = "mesh",
mesh = "pipeworks_fountainhead"..polys..".obj",
tiles = { "pipeworks_fountainhead.png" },
@ -691,7 +692,7 @@ local sp_cbox = {
local nodename_sp_empty = "pipeworks:straight_pipe_empty"
minetest.register_node(nodename_sp_empty, {
description = "Straight-only Pipe",
description = S("Straight-only Pipe"),
drawtype = "mesh",
mesh = "pipeworks_straight_pipe"..polys..".obj",
tiles = { "pipeworks_straight_pipe_empty.png" },
@ -713,7 +714,7 @@ minetest.register_node(nodename_sp_empty, {
local nodename_sp_loaded = "pipeworks:straight_pipe_loaded"
minetest.register_node(nodename_sp_loaded, {
description = "Straight-only Pipe",
description = S("Straight-only Pipe"),
drawtype = "mesh",
mesh = "pipeworks_straight_pipe"..polys..".obj",
tiles = { "pipeworks_straight_pipe_loaded.png" },

View File

@ -1,3 +1,4 @@
local S = minetest.get_translator("pipeworks")
local fs_helpers = pipeworks.fs_helpers
local function delay(x)
@ -5,47 +6,47 @@ local function delay(x)
end
local function set_filter_infotext(data, meta)
local infotext = data.wise_desc.." Filter-Injector"
local infotext = S("@1 Filter-Injector", data.wise_desc)
if meta:get_int("slotseq_mode") == 2 then
infotext = infotext .. " (slot #"..meta:get_int("slotseq_index").." next)"
infotext = infotext .. " "..S("(slot #@1 next)", meta:get_int("slotseq_index"))
end
meta:set_string("infotext", infotext)
end
local function set_filter_formspec(data, meta)
local itemname = data.wise_desc.." Filter-Injector"
local itemname = S("@1 Filter-Injector", data.wise_desc)
local formspec
if data.digiline then
formspec = "size[8,2.7]"..
"item_image[0,0;1,1;pipeworks:"..data.name.."]"..
"label[1,0;"..minetest.formspec_escape(itemname).."]"..
"field[0.3,1.5;8.0,1;channel;Channel;${channel}]"..
"field[0.3,1.5;8.0,1;channel;"..S("Channel")..";${channel}]"..
fs_helpers.cycling_button(meta, "button[0,2;4,1", "slotseq_mode",
{"Sequence slots by Priority",
"Sequence slots Randomly",
"Sequence slots by Rotation"})..
{S("Sequence slots by Priority"),
S("Sequence slots Randomly"),
S("Sequence slots by Rotation")})..
fs_helpers.cycling_button(meta, "button[4,2;4,1", "exmatch_mode",
{"Exact match - off",
"Exact match - on "})
{S("Exact match - off"),
S("Exact match - on")})
else
local exmatch_button = ""
if data.stackwise then
exmatch_button =
fs_helpers.cycling_button(meta, "button[4,3.5;4,1", "exmatch_mode",
{"Exact match - off",
"Exact match - on "})
{S("Exact match - off"),
S("Exact match - on")})
end
formspec = "size[8,8.5]"..
"item_image[0,0;1,1;pipeworks:"..data.name.."]"..
"label[1,0;"..minetest.formspec_escape(itemname).."]"..
"label[0,1;Prefer item types:]"..
"label[0,1;"..S("Prefer item types:").."]"..
"list[context;main;0,1.5;8,2;]"..
fs_helpers.cycling_button(meta, "button[0,3.5;4,1", "slotseq_mode",
{"Sequence slots by Priority",
"Sequence slots Randomly",
"Sequence slots by Rotation"})..
{S("Sequence slots by Priority"),
S("Sequence slots Randomly"),
S("Sequence slots by Rotation")})..
exmatch_button..
"list[current_player;main;0,4.5;8,4;]" ..
"listring[]"
@ -348,23 +349,23 @@ end
for _, data in ipairs({
{
name = "filter",
wise_desc = "Itemwise",
wise_desc = S("Itemwise"),
stackwise = false,
},
{
name = "mese_filter",
wise_desc = "Stackwise",
wise_desc = S("Stackwise"),
stackwise = true,
},
{ -- register even if no digilines
name = "digiline_filter",
wise_desc = "Digiline",
wise_desc = S("Digiline"),
stackwise = true,
digiline = true,
},
}) do
local node = {
description = data.wise_desc.." Filter-Injector",
description = S("@1 Filter-Injector", data.wise_desc),
tiles = {
"pipeworks_"..data.name.."_top.png",
"pipeworks_"..data.name.."_top.png",

View File

@ -10,6 +10,7 @@ local DEBUG = false
pipeworks.worldpath = minetest.get_worldpath()
pipeworks.modpath = minetest.get_modpath("pipeworks")
local S = minetest.get_translator("pipeworks")
dofile(pipeworks.modpath.."/default_settings.lua")
-- Read the external config file if it exists.
@ -45,7 +46,7 @@ pipeworks.liquid_texture = "default_water.png"
pipeworks.button_off = {text="", texture="pipeworks_button_off.png", addopts="false;false;pipeworks_button_interm.png"}
pipeworks.button_on = {text="", texture="pipeworks_button_on.png", addopts="false;false;pipeworks_button_interm.png"}
pipeworks.button_base = "image_button[0,4.3;1,0.6"
pipeworks.button_label = "label[0.9,4.31;Allow splitting incoming stacks from tubes]"
pipeworks.button_label = "label[0.9,4.31;"..S("Allow splitting incoming stacks from tubes").."]"
-- Helper functions

View File

@ -61,7 +61,7 @@ local crunch_tube = function(pos, cnode, cmeta)
local itemcount = tube_item_count[h] or 0
if itemcount > max_tube_limit then
cmeta:set_string("the_tube_was", minetest.serialize(cnode))
print("[Pipeworks] Warning - a tube at "..minetest.pos_to_string(pos).." broke due to too many items ("..itemcount..")")
pipeworks.logger("Warning - a tube at "..minetest.pos_to_string(pos).." broke due to too many items ("..itemcount..")")
minetest.swap_node(pos, {name = "pipeworks:broken_tube_1"})
pipeworks.scan_for_tube_objects(pos)
end

View File

@ -1,3 +1,4 @@
local S = minetest.get_translator("pipeworks")
if not minetest.get_modpath("auto_tree_tap") and
minetest.get_modpath("technic") then
@ -20,7 +21,7 @@ if not minetest.get_modpath("auto_tree_tap") and
})
minetest.register_node(":auto_tree_tap:off", {
description = "Auto-Tap",
description = S("Auto-Tap"),
tiles = {"pipeworks_nodebreaker_top_off.png","pipeworks_nodebreaker_bottom_off.png","pipeworks_nodebreaker_side2_off.png","pipeworks_nodebreaker_side1_off.png",
"pipeworks_nodebreaker_back.png","pipeworks_nodebreaker_front_off.png"},
is_ground_content = true,

View File

@ -0,0 +1,112 @@
# textdomain: pipeworks
# License: CC-by-SA 4.0
# Author: Louis Royer <4259825-lroyer@users.noreply.gitlab.com>
## digilines interfacing
Channel=Canal
## init
Allow splitting incoming stacks from tubes=Séparer les piles venant des tubes
## autocrafter
Unknown item=Item inconnu
unconfigured Autocrafter: unknown recipe=Autocrafteur non-configuré : recette inconnue
unconfigured Autocrafter=Autocrafteur non-configuré
'@1' Autocrafter (@2)=Autocrafteur de '@1' (@2)
Save=Valider
paused '@1' Autocrafter=Autocrafteur de '@1' en pause
Autocrafter=Autocrafteur
## compat-furnaces
Allow splitting incoming material (not fuel) stacks from tubes=Séparer les piles (sauf le carburant) venant des tubes
## decorative tubes
Airtight steelblock embedded tube=Tube hermétique intégré à un bloc dacier
Airtight panel embedded tube=Tube hermétique intégré à un panneau
## devices
Pump/Intake Module=Module de pompage et dadmission
Valve=Vanne
Decorative grating=Grillage décoratif
Spigot outlet=Sortie de robinet
Airtight Pipe entry/exit=Extrémité de tube hermétique
Flow Sensor=Détecteur de débit
Flow sensor (on)=Détecteur de débit (actif)
empty=vide
@1% full=plein à @1 %
Expansion Tank (@1)=Réservoir dexpansion (@1)
Fluid Storage Tank (@1)=Réservoir de liquides (@1)
Fountainhead=Tête de fontaine
Straight-only Pipe=Tuyau droit
## filter-injector
(slot #@1 next)=(slot suivant : #@1)
@1 Filter-Injector=Filtre-injecteur @1
Sequence slots by Priority=Ordonner par priorité
Sequence slots Randomly=Ordonner aléatoirement
Sequence slots by Rotation=Ordonner en rotation
Exact match - off=Filtrage inactif
Exact match - on=Filtrage actif
Prefer item types:=Items à filtrer :
Itemwise=par item
Stackwise=par piles ditems
Digiline=digiline
## legacy
Auto-Tap=Robinet darbre automatique
## pipes
Pipe Segment=Segment de tuyau
Pipe Segment (legacy)=Segment de tuyau (obsolète)
## routing tubes
Pneumatic tube segment=Segment de tuyau pneumatique
Broken Tube=Tuyau cassé
High Priority Tube Segment=Segment de tuyau haute priorité
Accelerating Pneumatic Tube Segment=Segment de tuyau pneumatique accélérante
Crossing Pneumatic Tube Segment=Intersection de tuyau pneumatique
One way tube=Tuyau unidirectionnel
## signal tubes
Detecting Pneumatic Tube Segment on=Segment de tuyau pneumatique avec détecteur (actif)
Detecting Pneumatic Tube Segment=Segment de tuyau pneumatique avec détecteur
Digiline Detecting Pneumatic Tube Segment=Segment de tuyau pneumatique avec détecteur digiline
Digiline Detecting Tube=Tuyau avec détecteur digiline
Conducting Pneumatic Tube Segment=Segment de tuyau pneumatique conducteur
Conducting Pneumatic Tube Segment on=Segment de tuyau pneumatique conducteur actif
Digiline Conducting Pneumatic Tube Segment=Segment de tuyau pneumatique conducteur digiline
Mesecon and Digiline Conducting Pneumatic Tube Segment=Segment de tuyau pneumatique conducteur mesecon et digiline
Mesecon and Digiline Conducting Pneumatic Tube Segment on=Segment de tuyau pneumatique conducteur mesecon et digiline (actif)
## sorting tubes
Sorting Pneumatic Tube Segment=Segment de tuyau pneumatique triant
Sorting pneumatic tube=Tuyau pneumatique triant
## teleport tube
Receive=Reception
channels are public by default=Les canaux sont publics par défaut
use <player>:<channel> for fully private channels=Utilisez <joueur>:<canal> pour un canal entièrement privé
use <player>;<channel> for private receivers=Utilisez <joueur>;<canal> pour une réception privée
Teleporting Pneumatic Tube Segment=Segment de tuyau pneumatique téléporteur
unconfigured Teleportation Tube=Tuyau téléporteur non-configuré
Sorry, channel '@1' is reserved for exclusive use by @2=Désolé, le canal '@1' est réservé exclusivement à lutilisateur @2.
Sorry, receiving from channel '@1' is reserved for @2=Désolé, la réception depuis le canal '@1' est réservée pour @2.
Teleportation Tube @1 on '@2'=Tuyau de téléportation @1 sur '@2'
## trashcan
Trash Can=Poubelle
## tube registration
Pneumatic tube segment (legacy)=Segment de tuyau pneumatique (obsolète)
## vacuum tubes
Vacuuming Pneumatic Tube Segment=Segment de tuyau pneumatique aspirant
Adjustable Vacuuming Pneumatic Tube Segment=Segment de tuyau pneumatique aspirant réglable
Adjustable Vacuuming Pneumatic Tube Segment (@1m)=Segment de tuyau pneumatique aspirant réglable (@1 m)
## wielder
Node Breaker=Casseur de blocs
Deployer=Poseur de blocs
Dispenser=Distributeur

View File

@ -0,0 +1,112 @@
# textdomain: pipeworks
# License: CC-by-SA 4.0
# Author:
## digilines interfacing
Channel=
## init
Allow splitting incoming stacks from tubes=
## autocrafter
Unknown item=
unconfigured Autocrafter: unknown recipe=
unconfigured Autocrafter=
'@1' Autocrafter (@2)=
Save=
paused '@1' Autocrafter=
Autocrafter=
## compat-furnaces
Allow splitting incoming material (not fuel) stacks from tubes=
## decorative tubes
Airtight steelblock embedded tube=
Airtight panel embedded tube=
## devices
Pump/Intake Module=
Valve=
Decorative grating=
Spigot outlet=
Airtight Pipe entry/exit=
Flow Sensor=
Flow sensor (on)=
empty=
@1% full=
Expansion Tank (@1)=
Fluid Storage Tank (@1)=
Fountainhead=
Straight-only Pipe=
## filter-injector
(slot #@1 next)=
@1 Filter-Injector=
Sequence slots by Priority=
Sequence slots Randomly=
Sequence slots by Rotation=
Exact match - off=
Exact match - on=
Prefer item types:=
Itemwise=
Stackwise=
Digiline=
## legacy
Auto-Tap=
## pipes
Pipe Segment=
Pipe Segment (legacy)=
## routing tubes
Pneumatic tube segment=
Broken Tube=
High Priority Tube Segment=
Accelerating Pneumatic Tube Segment=
Crossing Pneumatic Tube Segment=
One way tube=
## signal tubes
Detecting Pneumatic Tube Segment on=
Detecting Pneumatic Tube Segment=
Digiline Detecting Pneumatic Tube Segment=
Digiline Detecting Tube=
Conducting Pneumatic Tube Segment=
Conducting Pneumatic Tube Segment on=
Digiline Conducting Pneumatic Tube Segment=
Mesecon and Digiline Conducting Pneumatic Tube Segment=
Mesecon and Digiline Conducting Pneumatic Tube Segment on=
## sorting tubes
Sorting Pneumatic Tube Segment=
Sorting pneumatic tube=
## teleport tube
Receive=
channels are public by default=
use <player>:<channel> for fully private channels=
use <player>;<channel> for private receivers=
Teleporting Pneumatic Tube Segment=
unconfigured Teleportation Tube=
Sorry, channel '@1' is reserved for exclusive use by @2=
Sorry, receiving from channel '@1' is reserved for @2=
Teleportation Tube @1 on '@2'=
## trashcan
Trash Can=
## tube registration
Pneumatic tube segment (legacy)=
## vacuum tubes
Vacuuming Pneumatic Tube Segment=
Adjustable Vacuuming Pneumatic Tube Segment=
Adjustable Vacuuming Pneumatic Tube Segment (@1m)=
## wielder
Node Breaker=
Deployer=
Dispenser=

View File

@ -24,7 +24,7 @@
-- use too much memory from the sandbox.
-- You can add more functions to the environment
-- (see where local env is defined)
-- Something nice to play is is appending minetest.env to it.
-- Something nice to play is appending minetest.env to it.
local BASENAME = "pipeworks:lua_tube"

View File

@ -1 +1,4 @@
name = pipeworks
description = This mod uses mesh nodes and nodeboxes to supply a complete set of 3D pipes and tubes, along with devices that work with them.
depends = default, basic_materials, screwdriver
optional_depends = mesecons, mesecons_mvps, digilines, signs_lib

View File

@ -1,4 +1,5 @@
-- This file supplies the steel pipes
local S = minetest.get_translator("pipeworks")
local REGISTER_COMPATIBILITY = true
@ -35,11 +36,11 @@ for index, connects in ipairs(cconnects) do
end
local pgroups = {snappy = 3, pipe = 1, not_in_creative_inventory = 1}
local pipedesc = "Pipe segement".." "..dump(connects).."... You hacker, you."
local pipedesc = S("Pipe Segment").." "..dump(connects)
if #connects == 0 then
pgroups = {snappy = 3, tube = 1}
pipedesc = "Pipe segment"
pipedesc = S("Pipe Segment")
end
local outimg_e = { "pipeworks_pipe_plain.png" }
@ -140,7 +141,7 @@ if REGISTER_COMPATIBILITY then
drawtype = "airlike",
sunlight_propagates = true,
paramtype = "light",
description = "Pipe Segment (legacy)",
description = S("Pipe Segment (legacy)"),
groups = {not_in_creative_inventory = 1, pipe_to_update = 1},
drop = "pipeworks:pipe_1_empty",
after_place_node = function(pos)

View File

@ -1,6 +1,6 @@
local S = minetest.get_translator("pipeworks")
-- the default tube and default textures
pipeworks.register_tube("pipeworks:tube", "Pneumatic tube segment")
pipeworks.register_tube("pipeworks:tube", S("Pneumatic tube segment"))
minetest.register_craft( {
output = "pipeworks:tube_1 6",
recipe = {
@ -13,7 +13,7 @@ minetest.register_craft( {
local nodecolor = 0xffff3030
pipeworks.register_tube("pipeworks:broken_tube", {
description = "Broken Tube (you hacker you)",
description = S("Broken Tube"),
plain = { { name = "pipeworks_broken_tube_plain.png", backface_culling = false, color = nodecolor } },
noctr = { { name = "pipeworks_broken_tube_plain.png", backface_culling = false, color = nodecolor } },
ends = { { name = "pipeworks_broken_tube_end.png", color = nodecolor } },
@ -35,7 +35,7 @@ pipeworks.register_tube("pipeworks:broken_tube", {
local itemstack = puncher:get_wielded_item()
local wieldname = itemstack:get_name()
local playername = puncher:get_player_name()
print("[Pipeworks] "..playername.." struck a broken tube at "..minetest.pos_to_string(pos))
local log_msg = playername.." struck a broken tube at "..minetest.pos_to_string(pos).."\n"
if wieldname == "anvil:hammer"
or wieldname == "cottages:hammer"
or wieldname == "glooptest:hammer_steel"
@ -47,17 +47,17 @@ pipeworks.register_tube("pipeworks:broken_tube", {
local meta = minetest.get_meta(pos)
local was_node = minetest.deserialize(meta:get_string("the_tube_was"))
if was_node and was_node ~= "" then
print(" with "..wieldname.." to repair it.")
pipeworks.logger(log_msg.." with "..wieldname.." to repair it.")
minetest.swap_node(pos, { name = was_node.name, param2 = was_node.param2 })
pipeworks.scan_for_tube_objects(pos)
itemstack:add_wear(1000)
puncher:set_wielded_item(itemstack)
return itemstack
else
print(" but it can't be repaired.")
pipeworks.logger(log_msg.." but it can't be repaired.")
end
else
print(" with "..wieldname.." but that tool is too weak.")
pipeworks.logger(log_msg.." with "..wieldname.." but that tool is too weak.")
end
end
}
@ -69,7 +69,7 @@ pipeworks.register_tube("pipeworks:broken_tube", {
if pipeworks.enable_priority_tube then
local color = "#ff3030:128"
pipeworks.register_tube("pipeworks:priority_tube", {
description = "High Priority Tube Segment",
description = S("High Priority Tube Segment"),
inventory_image = "pipeworks_tube_inv.png^[colorize:" .. color,
plain = { { name = "pipeworks_tube_plain.png", color = nodecolor } },
noctr = { { name = "pipeworks_tube_noctr.png", color = nodecolor } },
@ -91,7 +91,7 @@ end
if pipeworks.enable_accelerator_tube then
pipeworks.register_tube("pipeworks:accelerator_tube", {
description = "Accelerating Pneumatic Tube Segment",
description = S("Accelerating Pneumatic Tube Segment"),
inventory_image = "pipeworks_accelerator_tube_inv.png",
plain = { "pipeworks_accelerator_tube_plain.png" },
noctr = { "pipeworks_accelerator_tube_noctr.png" },
@ -116,7 +116,7 @@ end
if pipeworks.enable_crossing_tube then
pipeworks.register_tube("pipeworks:crossing_tube", {
description = "Crossing Pneumatic Tube Segment",
description = S("Crossing Pneumatic Tube Segment"),
inventory_image = "pipeworks_crossing_tube_inv.png",
plain = { "pipeworks_crossing_tube_plain.png" },
noctr = { "pipeworks_crossing_tube_noctr.png" },
@ -138,7 +138,7 @@ end
if pipeworks.enable_one_way_tube then
minetest.register_node("pipeworks:one_way_tube", {
description = "One way tube",
description = S("One way tube"),
tiles = {"pipeworks_one_way_tube_top.png", "pipeworks_one_way_tube_top.png", "pipeworks_one_way_tube_output.png",
"pipeworks_one_way_tube_input.png", "pipeworks_one_way_tube_side.png", "pipeworks_one_way_tube_top.png"},
paramtype2 = "facedir",

View File

@ -1,7 +1,8 @@
local S = minetest.get_translator("pipeworks")
if pipeworks.enable_detector_tube then
local detector_tube_step = 5 * tonumber(minetest.settings:get("dedicated_server_step"))
pipeworks.register_tube("pipeworks:detector_tube_on", {
description = "Detecting Pneumatic Tube Segment on (you hacker you)",
description = S("Detecting Pneumatic Tube Segment on"),
inventory_image = "pipeworks_detector_tube_inv.png",
plain = { "pipeworks_detector_tube_plain.png" },
node_def = {
@ -40,7 +41,7 @@ if pipeworks.enable_detector_tube then
},
})
pipeworks.register_tube("pipeworks:detector_tube_off", {
description = "Detecting Pneumatic Tube Segment",
description = S("Detecting Pneumatic Tube Segment"),
inventory_image = "pipeworks_detector_tube_inv.png",
plain = { "pipeworks_detector_tube_plain.png" },
node_def = {
@ -70,7 +71,7 @@ end
local digiline_enabled = minetest.get_modpath("digilines") ~= nil
if digiline_enabled and pipeworks.enable_digiline_detector_tube then
pipeworks.register_tube("pipeworks:digiline_detector_tube", {
description = "Digiline Detecting Pneumatic Tube Segment",
description = S("Digiline Detecting Pneumatic Tube Segment"),
inventory_image = "pipeworks_digiline_detector_tube_inv.png",
plain = { "pipeworks_digiline_detector_tube_plain.png" },
node_def = {
@ -87,9 +88,9 @@ if digiline_enabled and pipeworks.enable_digiline_detector_tube then
local meta = minetest.get_meta(pos)
meta:set_string("formspec",
"size[8.6,2.2]"..
"field[0.6,0.6;8,1;channel;Channel:;${channel}]"..
"field[0.6,0.6;8,1;channel;"..S("Channel")..";${channel}]"..
"image[0.3,1.3;1,1;pipeworks_digiline_detector_tube_inv.png]"..
"label[1.6,1.2;Digiline Detecting Tube]"
"label[1.6,1.2;"..S("Digiline Detecting Tube").."]"
)
end,
on_receive_fields = function(pos, formname, fields, sender)
@ -122,7 +123,7 @@ end
if pipeworks.enable_conductor_tube then
pipeworks.register_tube("pipeworks:conductor_tube_off", {
description = "Conducting Pneumatic Tube Segment",
description = S("Conducting Pneumatic Tube Segment"),
inventory_image = "pipeworks_conductor_tube_inv.png",
short = "pipeworks_conductor_tube_short.png",
plain = { "pipeworks_conductor_tube_plain.png" },
@ -136,7 +137,7 @@ if pipeworks.enable_conductor_tube then
},
})
pipeworks.register_tube("pipeworks:conductor_tube_on", {
description = "Conducting Pneumatic Tube Segment on (you hacker you)",
description = S("Conducting Pneumatic Tube Segment on"),
inventory_image = "pipeworks_conductor_tube_inv.png",
short = "pipeworks_conductor_tube_short.png",
plain = { "pipeworks_conductor_tube_on_plain.png" },
@ -160,7 +161,7 @@ end
if digiline_enabled and pipeworks.enable_digiline_conductor_tube then
pipeworks.register_tube("pipeworks:digiline_conductor_tube", {
description = "Digiline Conducting Pneumatic Tube Segment",
description = S("Digiline Conducting Pneumatic Tube Segment"),
inventory_image = "pipeworks_tube_inv.png^pipeworks_digiline_conductor_tube_inv.png",
short = "pipeworks_tube_short.png^pipeworks_digiline_conductor_tube_short.png",
plain = {"pipeworks_tube_plain.png^pipeworks_digiline_conductor_tube_plain.png"},
@ -178,7 +179,7 @@ end
if digiline_enabled and pipeworks.enable_digiline_conductor_tube and
pipeworks.enable_conductor_tube then
pipeworks.register_tube("pipeworks:mesecon_and_digiline_conductor_tube_off", {
description = "Mesecon and Digiline Conducting Pneumatic Tube Segment",
description = S("Mesecon and Digiline Conducting Pneumatic Tube Segment"),
inventory_image = "pipeworks_conductor_tube_inv.png^pipeworks_digiline_conductor_tube_inv.png",
short = "pipeworks_conductor_tube_short.png^pipeworks_digiline_conductor_tube_short.png",
plain = {"pipeworks_conductor_tube_plain.png^pipeworks_digiline_conductor_tube_plain.png"},
@ -195,7 +196,7 @@ if digiline_enabled and pipeworks.enable_digiline_conductor_tube and
},
})
pipeworks.register_tube("pipeworks:mesecon_and_digiline_conductor_tube_on", {
description = "Mesecon and Digiline Conducting Pneumatic Tube Segment on (you hacker you)",
description = S("Mesecon and Digiline Conducting Pneumatic Tube Segment on"),
inventory_image = "pipeworks_conductor_tube_inv.png^pipeworks_digiline_conductor_tube_inv.png",
short = "pipeworks_conductor_tube_short.png^pipeworks_digiline_conductor_tube_short.png",
plain = {"pipeworks_conductor_tube_on_plain.png^pipeworks_digiline_conductor_tube_plain.png"},

View File

@ -1,3 +1,4 @@
local S = minetest.get_translator("pipeworks")
local fs_helpers = pipeworks.fs_helpers
if pipeworks.enable_mese_tube then
@ -55,7 +56,7 @@ if pipeworks.enable_mese_tube then
end
pipeworks.register_tube("pipeworks:mese_tube", {
description = "Sorting Pneumatic Tube Segment",
description = S("Sorting Pneumatic Tube Segment"),
inventory_image = "pipeworks_mese_tube_inv.png",
noctr = {"pipeworks_mese_tube_noctr_1.png", "pipeworks_mese_tube_noctr_2.png", "pipeworks_mese_tube_noctr_3.png",
"pipeworks_mese_tube_noctr_4.png", "pipeworks_mese_tube_noctr_5.png", "pipeworks_mese_tube_noctr_6.png"},
@ -107,7 +108,7 @@ if pipeworks.enable_mese_tube then
inv:set_size("line"..tostring(i), 6*1)
end
update_formspec(pos)
meta:set_string("infotext", "Sorting pneumatic tube")
meta:set_string("infotext", S("Sorting pneumatic tube"))
end,
on_punch = update_formspec,
on_receive_fields = function(pos, formname, fields, sender)

View File

@ -1,3 +1,4 @@
local S = minetest.get_translator("pipeworks")
local filename=minetest.get_worldpath() .. "/teleport_tubes"
local tp_tube_db = nil -- nil forces a read
@ -127,19 +128,19 @@ local function update_meta(meta, can_receive)
meta:set_int("can_receive", can_receive and 1 or 0)
local cr_state = can_receive and "on" or "off"
meta:set_string("formspec","size[8.6,2.2]"..
"field[0.6,0.6;7,1;channel;Channel:;${channel}]"..
"label[7.3,0;Receive]"..
"field[0.6,0.6;7,1;channel;"..S("Channel")..";${channel}]"..
"label[7.3,0;"..S("Receive").."]"..
"image_button[7.3,0.3;1,0.6;pipeworks_button_" .. cr_state .. ".png;cr" .. (can_receive and 0 or 1) .. ";;;false;pipeworks_button_interm.png]"..
"image[0.3,1.3;1,1;pipeworks_teleport_tube_inv.png]"..
"label[1.6,1.2;channels are public by default]" ..
"label[1.6,1.5;use <player>:<channel> for fully private channels]" ..
"label[1.6,1.8;use <player>\\;<channel> for private receivers]" ..
"label[1.6,1.2;"..S("channels are public by default").."]" ..
"label[1.6,1.5;"..S("use <player>:<channel> for fully private channels").."]" ..
"label[1.6,1.8;"..S("use <player>\\;<channel> for private receivers").."]" ..
default.gui_bg..
default.gui_bg_img)
end
pipeworks.register_tube("pipeworks:teleport_tube", {
description = "Teleporting Pneumatic Tube Segment",
description = S("Teleporting Pneumatic Tube Segment"),
inventory_image = "pipeworks_teleport_tube_inv.png",
noctr = { "pipeworks_teleport_tube_noctr.png" },
plain = { "pipeworks_teleport_tube_plain.png" },
@ -169,7 +170,7 @@ pipeworks.register_tube("pipeworks:teleport_tube", {
on_construct = function(pos)
local meta = minetest.get_meta(pos)
update_meta(meta, true)
meta:set_string("infotext", "unconfigured Teleportation Tube")
meta:set_string("infotext", S("unconfigured Teleportation Tube"))
end,
on_receive_fields = function(pos,formname,fields,sender)
if not fields.channel -- ignore escaping or clientside manipulation of the form
@ -189,12 +190,14 @@ pipeworks.register_tube("pipeworks:teleport_tube", {
if name and mode and name ~= sender_name then
--channels starting with '[name]:' can only be used by the named player
if mode == ":" then
minetest.chat_send_player(sender_name, "Sorry, channel '"..new_channel.."' is reserved for exclusive use by "..name)
minetest.chat_send_player(sender_name, S("Sorry, channel '@1' is reserved for exclusive use by @2",
new_channel, name))
return
--channels starting with '[name];' can be used by other players, but cannot be received from
elseif mode == ";" and (fields.cr1 or (can_receive ~= 0 and not fields.cr0)) then
minetest.chat_send_player(sender_name, "Sorry, receiving from channel '"..new_channel.."' is reserved for "..name)
minetest.chat_send_player(sender_name, S("Sorry, receiving from channel '@1' is reserved for @2",
new_channel, name))
return
end
end
@ -226,11 +229,11 @@ pipeworks.register_tube("pipeworks:teleport_tube", {
if channel ~= "" then
set_tube(pos, channel, can_receive)
local cr_description = (can_receive == 1) and "sending and receiving" or "sending"
meta:set_string("infotext", string.format("Teleportation Tube %s on '%s'", cr_description, channel))
meta:set_string("infotext", S("Teleportation Tube @1 on '@2'", cr_description, channel))
else
-- remove empty channel tubes, to not have to search through them
remove_tube(pos)
meta:set_string("infotext", "unconfigured Teleportation Tube")
meta:set_string("infotext", S("unconfigured Teleportation Tube"))
end
end
end,

View File

@ -1,5 +1,6 @@
local S = minetest.get_translator("pipeworks")
minetest.register_node("pipeworks:trashcan", {
description = "Trash Can",
description = S("Trash Can"),
drawtype = "normal",
tiles = {
"pipeworks_trashcan_bottom.png",
@ -22,7 +23,7 @@ minetest.register_node("pipeworks:trashcan", {
meta:set_string("formspec",
"size[8,7]"..
"item_image[0,0;1,1;pipeworks:trashcan]"..
"label[1,0;Trash Can]"..
"label[1,0;"..S("Trash Can").."]"..
"list[context;trash;3.5,1;1,1;]"..
default.gui_bg..
default.gui_bg_img..
@ -30,7 +31,7 @@ minetest.register_node("pipeworks:trashcan", {
default.get_hotbar_bg(0,3) ..
"list[current_player;main;0,3;8,4;]" ..
"listring[]")
meta:set_string("infotext", "Trash Can")
meta:set_string("infotext", S("Trash Can"))
meta:get_inventory():set_size("trash", 1)
end,
after_place_node = pipeworks.after_place,

View File

@ -1,4 +1,5 @@
-- This file supplies the various kinds of pneumatic tubes
local S = minetest.get_translator("pipeworks")
local tubenodes = {}
pipeworks.tubenodes = tubenodes
@ -56,7 +57,7 @@ local register_one_tube = function(name, tname, dropname, desc, plain, noctrs, e
end
local tgroups = {snappy = 3, tube = 1, tubedevice = 1, not_in_creative_inventory = 1}
local tubedesc = string.format("%s %s... You hacker, you.", desc, dump(connects))
local tubedesc = string.format("%s %s", desc, dump(connects))
local iimg = plain[1]
local wscale = {x = 1, y = 1, z = 1}
@ -197,7 +198,7 @@ local register_all_tubes = function(name, desc, plain, noctrs, ends, short, inv,
wield_image = inv,
paramtype = "light",
sunlight_propagates = true,
description = "Pneumatic tube segment (legacy)",
description = S("Pneumatic tube segment (legacy)"),
after_place_node = pipeworks.after_place,
groups = {not_in_creative_inventory = 1, tube_to_update = 1, tube = 1},
tube = {connect_sides = {front = 1, back = 1, left = 1, right = 1, top = 1, bottom = 1}},

View File

@ -1,6 +1,7 @@
local S = minetest.get_translator("pipeworks")
if pipeworks.enable_sand_tube then
pipeworks.register_tube("pipeworks:sand_tube", {
description = "Vacuuming Pneumatic Tube Segment",
description = S("Vacuuming Pneumatic Tube Segment"),
inventory_image = "pipeworks_sand_tube_inv.png",
short = "pipeworks_sand_tube_short.png",
noctr = {"pipeworks_sand_tube_noctr.png"},
@ -28,7 +29,7 @@ end
if pipeworks.enable_mese_sand_tube then
pipeworks.register_tube("pipeworks:mese_sand_tube", {
description = "Adjustable Vacuuming Pneumatic Tube Segment",
description = S("Adjustable Vacuuming Pneumatic Tube Segment"),
inventory_image = "pipeworks_mese_sand_tube_inv.png",
short = "pipeworks_mese_sand_tube_short.png",
noctr = {"pipeworks_mese_sand_tube_noctr.png"},
@ -44,7 +45,7 @@ if pipeworks.enable_mese_sand_tube then
"field[1.3,0.4;1,1;dist;radius;${dist}]"..
default.gui_bg..
default.gui_bg_img)
meta:set_string("infotext", "Adjustable Vacuuming Pneumatic Tube Segment")
meta:set_string("infotext", S("Adjustable Vacuuming Pneumatic Tube Segment"))
end,
on_receive_fields = function(pos,formname,fields,sender)
if not pipeworks.may_configure(pos, sender) then return end
@ -54,7 +55,7 @@ if pipeworks.enable_mese_sand_tube then
dist = math.max(0, dist)
dist = math.min(8, dist)
meta:set_int("dist", dist)
meta:set_string("infotext", ("Adjustable Vacuuming Pneumatic Tube Segment (%dm)"):format(dist))
meta:set_string("infotext", (S("Adjustable Vacuuming Pneumatic Tube Segment (@1m)", dist)))
end
end,
},

View File

@ -1,3 +1,4 @@
local S = minetest.get_translator("pipeworks")
local assumed_eye_pos = vector.new(0, 1.5, 0)
local function vector_copy(v)
@ -259,7 +260,7 @@ if pipeworks.enable_node_breaker then
local wield_inv_name = "pick"
data = {
name_base = name_base,
description = "Node Breaker",
description = S("Node Breaker"),
texture_base = "pipeworks_nodebreaker",
texture_stateful = { top = true, bottom = true, side2 = true, side1 = true, front = true },
tube_connect_sides = { top=1, bottom=1, left=1, right=1, back=1 },
@ -408,7 +409,7 @@ end
if pipeworks.enable_deployer then
register_wielder({
name_base = "pipeworks:deployer",
description = "Deployer",
description = S("Deployer"),
texture_base = "pipeworks_deployer",
texture_stateful = { front = true },
tube_connect_sides = { back=1 },
@ -441,7 +442,7 @@ end
if pipeworks.enable_dispenser then
register_wielder({
name_base = "pipeworks:dispenser",
description = "Dispenser",
description = S("Dispenser"),
texture_base = "pipeworks_dispenser",
texture_stateful = { front = true },
tube_connect_sides = { back=1 },

View File

@ -1,5 +1,4 @@
local modpath = minetest.get_modpath(minetest.get_current_modname())
local S, NS = dofile(modpath.."/intllib.lua")
local S = ropes.S
if ropes.bridges_enabled then

View File

@ -1,6 +1,4 @@
-- internationalization boilerplate
local MP = minetest.get_modpath(minetest.get_current_modname())
local S, NS = dofile(MP.."/intllib.lua")
local S = ropes.S
if minetest.get_modpath("farming") then
-- this doesn't work reliably due to side effects of https://github.com/minetest/minetest/issues/5518

View File

@ -2,7 +2,6 @@ default
farming?
vines?
doc?
intllib?
loot?
hemp?
cottages?
cottages?

View File

@ -4,9 +4,7 @@ if not minetest.get_modpath("doc") then
return
end
-- internationalization boilerplate
local MP = minetest.get_modpath(minetest.get_current_modname())
local S, NS = dofile(MP.."/intllib.lua")
local S = ropes.S
ropes.doc.ropesegment_longdesc = S("Rope segments are bundles of fibre twisted into robust cables.")
ropes.doc.ropesegment_usage = S("This craft item is useful for creating rope ladders, or for spooling on wooden spindles to hang and climb upon.")
@ -14,7 +12,7 @@ ropes.doc.ropesegment_usage = S("This craft item is useful for creating rope lad
ropes.doc.ropeladder_longdesc = S("A hanging rope ladder that automatically extends downward.")
ropes.doc.ropeladder_usage = S("After a rope ladder is placed on a vertical wall it will begin extending downward until it reaches its maximum length (@1 meters). If the rope ladder is removed all of the ladder below the point of removal will disappear. A rope ladder can be severed partway down using an axe or similar tool, and the ladder below the point where it is cut will collapse. No rope is actually lost in the process, though, and if the uppermost section of the ladder is removed and replaced the ladder will re-extend to the same maximum length as before.", ropes.ropeLadderLength)
local rope_length_doc = S("Rope boxes have a certain amount of rope contained within them specified in the name of the node, and have a limit to how much rope they can support that depends on the material they're made of. The different lengths can be crafted by combining and splitting up rope boxes in the crafting grid. For example, you can craft a @1m rope box by putting a @2m rope box and a rope segment in the crafting grid, or a @3m rope box and two rope segments in the crafting grid. Two rope segments can be recovered by putting the @1m rope box in the crafting grid by itself.", ropes.ropeLength*3, ropes.ropeLength*2, ropes.ropeLength) .. "\n"
local rope_length_doc = S("Rope boxes have a certain amount of rope contained within them specified in the name of the node, and have a limit to how much rope they can support that depends on the material they're made of. The different lengths can be crafted by combining and splitting up rope boxes in the crafting grid. For example, you can craft a @1m rope box by putting a @2m rope box and a rope segment in the crafting grid, or a @3m rope box and two rope segments in the crafting grid. Two rope segments can be recovered by putting the @4m rope box in the crafting grid by itself.", ropes.ropeLength*3, ropes.ropeLength*2, ropes.ropeLength, ropes.ropeLength*3) .. "\n"
if ropes.woodRopeBoxMaxMultiple == 1 then
rope_length_doc = rope_length_doc .. "\n" .. S("Wood") .. " " .. S("rope boxes can hold @1m of rope.", ropes.ropeLength)
@ -52,4 +50,4 @@ doc.add_entry_alias("nodes", "ropes:ropeladder_top", "nodes", "ropes:ropeladder_
doc.add_entry_alias("nodes", "ropes:ropeladder_top", "nodes", "ropes:ropeladder_falling")
doc.add_entry_alias("nodes", "ropes:rope", "nodes", "ropes:rope_bottom")
doc.add_entry_alias("nodes", "ropes:rope", "nodes", "ropes:rope_top")
doc.add_entry_alias("nodes", "ropes:rope", "nodes", "ropes:rope_top")

View File

@ -1,5 +1,4 @@
local modpath = minetest.get_modpath(minetest.get_current_modname())
local S, NS = dofile(modpath.."/intllib.lua")
local S = ropes.S
if ropes.extending_ladder_enabled then

418
ropes/i18n.py Normal file
View File

@ -0,0 +1,418 @@
#!/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+
from __future__ import print_function
import os, fnmatch, re, shutil, errno
from sys import argv as _argv
# Running params
params = {"recursive": False,
"help": False,
"mods": False,
"verbose": False,
"folders": []
}
# Available CLI options
options = {"recursive": ['--recursive', '-r'],
"help": ['--help', '-h'],
"mods": ['--installed-mods'],
"verbose": ['--verbose', '-v']
}
# 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 = 60
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["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 = re.compile(r'[\.=^\t,{\(\s]N?S\(\s*(["\'])((?:\\\1|(?:(?!\1)).)*)(\1)[\s,\)]', re.DOTALL)
pattern_lua_bracketed = re.compile(r'[\.=^\t,{\(\s]N?S\(\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):
lOut = [f"# textdomain: {mod_name}\n"]
dGroupedBySource = {}
for key in dkeyStrings:
sourceList = list(dkeyStrings[key])
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]
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 len(localizedString) > doublespace_threshold and not lOut[-1] == "":
lOut.append("")
if comment != None:
lOut.append(comment)
lOut.append(f"{localizedString}={translation}")
if 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 len(key) > doublespace_threshold and not lOut[-1] == "":
lOut.append("")
if comment != None:
lOut.append(comment)
lOut.append(f"{key}={translation}")
if 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)
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.findall(text):
strings.append(s[1])
for s in pattern_lua_bracketed.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.
def import_tr_file(tr_file):
dOut = {}
text = 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] == "###":
# 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)
# 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)
if textOld and textOld != textNew:
print(f"{tr_file} has changed.")
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("Unable to find modname in folder " + folder)
# 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

@ -3,8 +3,9 @@ ropes = {
}
-- internationalization boilerplate
local MP = minetest.get_modpath(minetest.get_current_modname())
local S, NS = dofile(MP.."/intllib.lua")
local modname = minetest.get_current_modname()
local MP = minetest.get_modpath(modname)
ropes.S = minetest.get_translator(modname)
ropes.ropeLength = tonumber(minetest.settings:get("ropes_rope_length")) or 50
ropes.woodRopeBoxMaxMultiple = tonumber(minetest.settings:get("ropes_wood_rope_box_max_multiple")) or 2

View File

@ -1,45 +0,0 @@
-- Fallback functions for when `intllib` is not installed.
-- Code released under Unlicense <http://unlicense.org>.
-- Get the latest version of this file at:
-- https://raw.githubusercontent.com/minetest-mods/intllib/master/lib/intllib.lua
local function format(str, ...)
local args = { ... }
local function repl(escape, open, num, close)
if escape == "" then
local replacement = tostring(args[tonumber(num)])
if open == "" then
replacement = replacement..close
end
return replacement
else
return "@"..open..num..close
end
end
return (str:gsub("(@?)@(%(?)(%d+)(%)?)", repl))
end
local gettext, ngettext
if minetest.get_modpath("intllib") then
if intllib.make_gettext_pair then
-- New method using gettext.
gettext, ngettext = intllib.make_gettext_pair()
else
-- Old method using text files.
gettext = intllib.Getter()
end
end
-- Fill in missing functions.
gettext = gettext or function(msgid, ...)
return format(msgid, ...)
end
ngettext = ngettext or function(msgid, msgid_plural, n, ...)
return format(n==1 and msgid or msgid_plural, ...)
end
return gettext, ngettext

View File

@ -1,222 +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: 2019-04-28 16:30-0600\n"
"PO-Revision-Date: 2018-10-27 11:26+0200\n"
"Last-Translator: \n"
"Language-Team: \n"
"Language: es\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"X-Generator: Poedit 1.8.11\n"
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
#: bridge.lua:49
msgid "Wooden Bridge"
msgstr ""
#: crafts.lua:54
msgid "Rope Segment"
msgstr "Segmento de cuerda"
#: doc.lua:11
msgid "Rope segments are bundles of fibre twisted into robust cables."
msgstr ""
"Los segmentos de cable son haces de fibras trenzadas en cables robustos."
#: doc.lua:12
msgid ""
"This craft item is useful for creating rope ladders, or for spooling on "
"wooden spindles to hang and climb upon."
msgstr ""
"Esta objeto es útil para crear escaleras de cuerda, o para enrollar en "
"husillos de madera para colgar y trepar."
#: doc.lua:14
msgid "A hanging rope ladder that automatically extends downward."
msgstr ""
"Una escalera de cuerda colgante que se extiende automáticamente hacia abajo."
#: doc.lua:15
msgid ""
"After a rope ladder is placed on a vertical wall it will begin extending "
"downward until it reaches its maximum length (@1 meters). If the rope ladder "
"is removed all of the ladder below the point of removal will disappear. A "
"rope ladder can be severed partway down using an axe or similar tool, and "
"the ladder below the point where it is cut will collapse. No rope is "
"actually lost in the process, though, and if the uppermost section of the "
"ladder is removed and replaced the ladder will re-extend to the same maximum "
"length as before."
msgstr ""
"Después de colocar una escalera de cuerda en una pared vertical, comenzará a "
"extenderse hacia abajo hasta que alcance su longitud máxima (@1 metro). Si "
"se retira la escalera de cuerda, desaparecerá toda la escalera por debajo "
"del punto de extracción. Una escalera de cuerda puede ser cortada hasta la "
"mitad usando un hacha o una herramienta similar, y la escalera por debajo "
"del punto donde es cortada colapsará. Sin embargo, no se pierde ninguna "
"cuerda en el proceso, y si la sección superior de la escalera se retira y se "
"reemplaza, la escalera se volverá a extender a la misma longitud máxima que "
"antes."
#: doc.lua:17
msgid ""
"Rope boxes have a certain amount of rope contained within them specified in "
"the name of the node, and have a limit to how much rope they can support "
"that depends on the material they're made of. The different lengths can be "
"crafted by combining and splitting up rope boxes in the crafting grid. For "
"example, you can craft a @1m rope box by putting a @2m rope box and a rope "
"segment in the crafting grid, or a @3m rope box and two rope segments in the "
"crafting grid. Two rope segments can be recovered by putting the @1m rope "
"box in the crafting grid by itself."
msgstr ""
"Las cajas de cuerdas tienen una cierta cantidad de cuerda contenida dentro "
"de ellas especificada en el nombre del nodo, y tienen un límite en la "
"cantidad de cuerda que pueden soportar que depende del material del que "
"están hechas. Las diferentes longitudes se pueden realizar combinando y "
"dividiendo las cajas de cuerda en la rejilla de elaboración. Por ejemplo, "
"puedes crear una caja de cuerda de @1m poniendo una caja de cuerda de @2m y "
"un segmento de cuerda en la rejilla de artesanía, o una caja de cuerda de "
"@3m y dos segmentos de cuerda en la rejilla de artesanía. Se pueden "
"recuperar dos segmentos de cable colocando solo la caja de cable de @1m en "
"la rejilla de fabricación."
#: doc.lua:20
#: doc.lua:22
#: ropeboxes.lua:321
msgid "Wood"
msgstr "madera"
#: doc.lua:20
#: doc.lua:26
#: doc.lua:32
msgid "rope boxes can hold @1m of rope."
msgstr "Las cajas de cuerdas pueden mantener @1m de cuerda."
#: doc.lua:22
#: doc.lua:28
#: doc.lua:34
msgid "rope boxes can hold rope lengths from @1m to @2m."
msgstr "Las cajas de cuerda pueden contener longitudes de cuerda de @1m a @2m."
#: doc.lua:26
#: doc.lua:28
#: ropeboxes.lua:338
msgid "Copper"
msgstr "cobre"
#: doc.lua:32
#: doc.lua:34
#: ropeboxes.lua:355
msgid "Steel"
msgstr "acero"
#: doc.lua:37
msgid ""
"Ropes are hung by placing rope boxes, which automatically lower a rope of "
"fixed length below them. They can be climbed and cut."
msgstr ""
"Las cuerdas se cuelgan colocando cajas de cuerda, que bajan automáticamente "
"una cuerda de longitud fija por debajo de ellas. Se pueden escalar y cortar."
#: doc.lua:39
msgid ""
"When a rope box is placed the rope will immediately begin lowering from it "
"at one meter per second. The rope will only descend when its end is in the "
"vicinity of an active player, suspending its journey when no players are "
"nearby, so a long descent may require a player to climb down the rope as it "
"goes. If you are near the bottom end of a rope that's extending you'll be "
"automatically carried down with it. The rope will stop when it encounters "
"and obstruction, but will resume lowering if the obstruction is removed."
msgstr ""
"Cuando se coloca una caja de cuerda, la cuerda comienza a descender "
"inmediatamente a un metro por segundo. La cuerda sólo descenderá cuando su "
"final esté cerca de un jugador activo, suspendiendo su viaje cuando no haya "
"jugadores cerca, por lo que un largo descenso puede requerir que el jugador "
"baje por la cuerda a medida que avanza. Si estás cerca del extremo inferior "
"de una cuerda que se está extendiendo, serás arrastrado automáticamente "
"hacia abajo con ella. La cuerda se detendrá cuando se encuentre con una "
"obstrucción, pero volverá a bajar si se retira la obstrucción."
#: doc.lua:40
msgid ""
"A rope can be severed midway using an axe or other similar tool. The section "
"of rope below the cut will collapse and disappear, potentially causing "
"players who were hanging on to it to fall. The remaining rope will not "
"resume descent on its own, but the rope box at the top of the rope "
"\"remembers\" how long the rope was and if it is deconstructed and replaced "
"it will still have the same maximum length of rope as before - no rope is "
"permanently lost when a rope is severed like this."
msgstr ""
"Una cuerda puede ser cortada a mitad de camino usando un hacha u otra "
"herramienta similar. La sección de la cuerda debajo del corte se colapsará y "
"desaparecerá, lo que puede causar que los jugadores que estaban colgados de "
"ella se caigan. El resto de la cuerda no volverá a descender por sí sola, "
"pero la caja de la cuerda en la parte superior de la cuerda \"recuerda\" la "
"longitud de la cuerda y si es deconstruida y reemplazada tendrá la misma "
"longitud máxima de cuerda que antes - ninguna cuerda se pierde "
"permanentemente cuando una cuerda es cortada de esta manera."
#: doc.lua:43
msgid ""
"A ladder for climbing. It can reach greater heights when placed against a "
"supporting block."
msgstr ""
#: doc.lua:44
msgid ""
"Right-clicking on a ladder with a stack of identical ladder items will "
"automatically add new ladder segments to the top, provided it hasn't "
"extended too far up beyond the last block behind it providing support."
msgstr ""
#: doc.lua:47
msgid "A wooden platform with support struts useful for bridging gaps."
msgstr ""
#: doc.lua:48
msgid ""
"This behaves like most structural blocks except in one circumstance: when "
"placed on top of a block with buildable space on the side facing away from "
"you, this block will not be built on top but instead will extend out from "
"that far side of the target block. This allows a platform to be easily built "
"that juts out away from the location you're standing on."
msgstr ""
#: extendingladder.lua:11
msgid "Wooden Ladder"
msgstr ""
#: extendingladder.lua:18
msgid "Steel Ladder"
msgstr ""
#: extendingladder.lua:57
msgid "Wooden Extendable Ladder"
msgstr ""
#: extendingladder.lua:64
msgid "Steel Extendable Ladder"
msgstr ""
#: ropeboxes.lua:121
msgid "@1 Ropebox @2m"
msgstr "Caja de cuerda de @1 de @2m"
#: ropeboxes.lua:229
#: ropeboxes.lua:264
msgid "Rope"
msgstr "Cuerda"
#: ropeladder.lua:27
#: ropeladder.lua:89
#: ropeladder.lua:119
#: ropeladder.lua:153
msgid "Rope Ladder"
msgstr "Escalera de cuerda"

62
ropes/locale/ropes.es.tr Normal file
View File

@ -0,0 +1,62 @@
# textdomain: ropes
### bridge.lua ###
Wooden Bridge=
### crafts.lua ###
Rope Segment=Segmento de cuerda
### doc.lua ###
A hanging rope ladder that automatically extends downward.=Una escalera de cuerda colgante que se extiende automáticamente hacia abajo.
A ladder for climbing. It can reach greater heights when placed against a supporting block.=
A rope can be severed midway using an axe or other similar tool. The section of rope below the cut will collapse and disappear, potentially causing players who were hanging on to it to fall. The remaining rope will not resume descent on its own, but the rope box at the top of the rope "remembers" how long the rope was and if it is deconstructed and replaced it will still have the same maximum length of rope as before - no rope is permanently lost when a rope is severed like this.=Una cuerda puede ser cortada a mitad de camino usando un hacha u otra herramienta similar. La sección de la cuerda debajo del corte se colapsará y desaparecerá, lo que puede causar que los jugadores que estaban colgados de ella se caigan. El resto de la cuerda no volverá a descender por sí sola, pero la caja de la cuerda en la parte superior de la cuerda "recuerda" la longitud de la cuerda y si es deconstruida y reemplazada tendrá la misma longitud máxima de cuerda que antes - ninguna cuerda se pierde permanentemente cuando una cuerda es cortada de esta manera.
A wooden platform with support struts useful for bridging gaps.=
After a rope ladder is placed on a vertical wall it will begin extending downward until it reaches its maximum length (@1 meters). If the rope ladder is removed all of the ladder below the point of removal will disappear. A rope ladder can be severed partway down using an axe or similar tool, and the ladder below the point where it is cut will collapse. No rope is actually lost in the process, though, and if the uppermost section of the ladder is removed and replaced the ladder will re-extend to the same maximum length as before.=Después de colocar una escalera de cuerda en una pared vertical, comenzará a extenderse hacia abajo hasta que alcance su longitud máxima (@1 metro). Si se retira la escalera de cuerda, desaparecerá toda la escalera por debajo del punto de extracción. Una escalera de cuerda puede ser cortada hasta la mitad usando un hacha o una herramienta similar, y la escalera por debajo del punto donde es cortada colapsará. Sin embargo, no se pierde ninguna cuerda en el proceso, y si la sección superior de la escalera se retira y se reemplaza, la escalera se volverá a extender a la misma longitud máxima que antes.
Right-clicking on a ladder with a stack of identical ladder items will automatically add new ladder segments to the top, provided it hasn't extended too far up beyond the last block behind it providing support.=
Rope boxes have a certain amount of rope contained within them specified in the name of the node, and have a limit to how much rope they can support that depends on the material they're made of. The different lengths can be crafted by combining and splitting up rope boxes in the crafting grid. For example, you can craft a @1m rope box by putting a @2m rope box and a rope segment in the crafting grid, or a @3m rope box and two rope segments in the crafting grid. Two rope segments can be recovered by putting the @4m rope box in the crafting grid by itself.=Las cajas de cuerdas tienen una cierta cantidad de cuerda contenida dentro de ellas especificada en el nombre del nodo, y tienen un límite en la cantidad de cuerda que pueden soportar que depende del material del que están hechas. Las diferentes longitudes se pueden realizar combinando y dividiendo las cajas de cuerda en la rejilla de elaboración. Por ejemplo, puedes crear una caja de cuerda de @1m poniendo una caja de cuerda de @2m y un segmento de cuerda en la rejilla de artesanía, o una caja de cuerda de @3m y dos segmentos de cuerda en la rejilla de artesanía. Se pueden recuperar dos segmentos de cable colocando solo la caja de cable de @4m en la rejilla de fabricación.
Rope segments are bundles of fibre twisted into robust cables.=Los segmentos de cable son haces de fibras trenzadas en cables robustos.
Ropes are hung by placing rope boxes, which automatically lower a rope of fixed length below them. They can be climbed and cut.=Las cuerdas se cuelgan colocando cajas de cuerda, que bajan automáticamente una cuerda de longitud fija por debajo de ellas. Se pueden escalar y cortar.
This behaves like most structural blocks except in one circumstance: when placed on top of a block with buildable space on the side facing away from you, this block will not be built on top but instead will extend out from that far side of the target block. This allows a platform to be easily built that juts out away from the location you're standing on.=
This craft item is useful for creating rope ladders, or for spooling on wooden spindles to hang and climb upon.=Esta objeto es útil para crear escaleras de cuerda, o para enrollar en husillos de madera para colgar y trepar.
When a rope box is placed the rope will immediately begin lowering from it at one meter per second. The rope will only descend when its end is in the vicinity of an active player, suspending its journey when no players are nearby, so a long descent may require a player to climb down the rope as it goes. If you are near the bottom end of a rope that's extending you'll be automatically carried down with it. The rope will stop when it encounters and obstruction, but will resume lowering if the obstruction is removed.=Cuando se coloca una caja de cuerda, la cuerda comienza a descender inmediatamente a un metro por segundo. La cuerda sólo descenderá cuando su final esté cerca de un jugador activo, suspendiendo su viaje cuando no haya jugadores cerca, por lo que un largo descenso puede requerir que el jugador baje por la cuerda a medida que avanza. Si estás cerca del extremo inferior de una cuerda que se está extendiendo, serás arrastrado automáticamente hacia abajo con ella. La cuerda se detendrá cuando se encuentre con una obstrucción, pero volverá a bajar si se retira la obstrucción.
rope boxes can hold @1m of rope.=Las cajas de cuerdas pueden mantener @1m de cuerda.
rope boxes can hold rope lengths from @1m to @2m.=Las cajas de cuerda pueden contener longitudes de cuerda de @1m a @2m.
### doc.lua ###
### ropeboxes.lua ###
Copper=cobre
Steel=acero
Wood=madera
### extendingladder.lua ###
Steel Extendable Ladder=
Steel Ladder=
Wooden Extendable Ladder=
Wooden Ladder=
### ropeboxes.lua ###
@1 Ropebox @2m=Caja de cuerda de @1 de @2m
Rope=Cuerda
### ropeladder.lua ###
Rope Ladder=Escalera de cuerda

View File

@ -1,180 +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: 2019-04-28 16:30-0600\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"
#: bridge.lua:49
msgid "Wooden Bridge"
msgstr ""
#: crafts.lua:54
msgid "Rope Segment"
msgstr ""
#: doc.lua:11
msgid "Rope segments are bundles of fibre twisted into robust cables."
msgstr ""
#: doc.lua:12
msgid ""
"This craft item is useful for creating rope ladders, or for spooling on "
"wooden spindles to hang and climb upon."
msgstr ""
#: doc.lua:14
msgid "A hanging rope ladder that automatically extends downward."
msgstr ""
#: doc.lua:15
msgid ""
"After a rope ladder is placed on a vertical wall it will begin extending "
"downward until it reaches its maximum length (@1 meters). If the rope ladder "
"is removed all of the ladder below the point of removal will disappear. A "
"rope ladder can be severed partway down using an axe or similar tool, and "
"the ladder below the point where it is cut will collapse. No rope is "
"actually lost in the process, though, and if the uppermost section of the "
"ladder is removed and replaced the ladder will re-extend to the same maximum "
"length as before."
msgstr ""
#: doc.lua:17
msgid ""
"Rope boxes have a certain amount of rope contained within them specified in "
"the name of the node, and have a limit to how much rope they can support "
"that depends on the material they're made of. The different lengths can be "
"crafted by combining and splitting up rope boxes in the crafting grid. For "
"example, you can craft a @1m rope box by putting a @2m rope box and a rope "
"segment in the crafting grid, or a @3m rope box and two rope segments in the "
"crafting grid. Two rope segments can be recovered by putting the @1m rope "
"box in the crafting grid by itself."
msgstr ""
#: doc.lua:20
#: doc.lua:22
#: ropeboxes.lua:321
msgid "Wood"
msgstr ""
#: doc.lua:20
#: doc.lua:26
#: doc.lua:32
msgid "rope boxes can hold @1m of rope."
msgstr ""
#: doc.lua:22
#: doc.lua:28
#: doc.lua:34
msgid "rope boxes can hold rope lengths from @1m to @2m."
msgstr ""
#: doc.lua:26
#: doc.lua:28
#: ropeboxes.lua:338
msgid "Copper"
msgstr ""
#: doc.lua:32
#: doc.lua:34
#: ropeboxes.lua:355
msgid "Steel"
msgstr ""
#: doc.lua:37
msgid ""
"Ropes are hung by placing rope boxes, which automatically lower a rope of "
"fixed length below them. They can be climbed and cut."
msgstr ""
#: doc.lua:39
msgid ""
"When a rope box is placed the rope will immediately begin lowering from it "
"at one meter per second. The rope will only descend when its end is in the "
"vicinity of an active player, suspending its journey when no players are "
"nearby, so a long descent may require a player to climb down the rope as it "
"goes. If you are near the bottom end of a rope that's extending you'll be "
"automatically carried down with it. The rope will stop when it encounters "
"and obstruction, but will resume lowering if the obstruction is removed."
msgstr ""
#: doc.lua:40
msgid ""
"A rope can be severed midway using an axe or other similar tool. The section "
"of rope below the cut will collapse and disappear, potentially causing "
"players who were hanging on to it to fall. The remaining rope will not "
"resume descent on its own, but the rope box at the top of the rope "
"\"remembers\" how long the rope was and if it is deconstructed and replaced "
"it will still have the same maximum length of rope as before - no rope is "
"permanently lost when a rope is severed like this."
msgstr ""
#: doc.lua:43
msgid ""
"A ladder for climbing. It can reach greater heights when placed against a "
"supporting block."
msgstr ""
#: doc.lua:44
msgid ""
"Right-clicking on a ladder with a stack of identical ladder items will "
"automatically add new ladder segments to the top, provided it hasn't "
"extended too far up beyond the last block behind it providing support."
msgstr ""
#: doc.lua:47
msgid "A wooden platform with support struts useful for bridging gaps."
msgstr ""
#: doc.lua:48
msgid ""
"This behaves like most structural blocks except in one circumstance: when "
"placed on top of a block with buildable space on the side facing away from "
"you, this block will not be built on top but instead will extend out from "
"that far side of the target block. This allows a platform to be easily built "
"that juts out away from the location you're standing on."
msgstr ""
#: extendingladder.lua:11
msgid "Wooden Ladder"
msgstr ""
#: extendingladder.lua:18
msgid "Steel Ladder"
msgstr ""
#: extendingladder.lua:57
msgid "Wooden Extendable Ladder"
msgstr ""
#: extendingladder.lua:64
msgid "Steel Extendable Ladder"
msgstr ""
#: ropeboxes.lua:121
msgid "@1 Ropebox @2m"
msgstr ""
#: ropeboxes.lua:229
#: ropeboxes.lua:264
msgid "Rope"
msgstr ""
#: ropeladder.lua:27
#: ropeladder.lua:89
#: ropeladder.lua:119
#: ropeladder.lua:153
msgid "Rope Ladder"
msgstr ""

62
ropes/locale/template.txt Normal file
View File

@ -0,0 +1,62 @@
# textdomain: ropes
### bridge.lua ###
Wooden Bridge=
### crafts.lua ###
Rope Segment=
### doc.lua ###
A hanging rope ladder that automatically extends downward.=
A ladder for climbing. It can reach greater heights when placed against a supporting block.=
A rope can be severed midway using an axe or other similar tool. The section of rope below the cut will collapse and disappear, potentially causing players who were hanging on to it to fall. The remaining rope will not resume descent on its own, but the rope box at the top of the rope "remembers" how long the rope was and if it is deconstructed and replaced it will still have the same maximum length of rope as before - no rope is permanently lost when a rope is severed like this.=
A wooden platform with support struts useful for bridging gaps.=
After a rope ladder is placed on a vertical wall it will begin extending downward until it reaches its maximum length (@1 meters). If the rope ladder is removed all of the ladder below the point of removal will disappear. A rope ladder can be severed partway down using an axe or similar tool, and the ladder below the point where it is cut will collapse. No rope is actually lost in the process, though, and if the uppermost section of the ladder is removed and replaced the ladder will re-extend to the same maximum length as before.=
Right-clicking on a ladder with a stack of identical ladder items will automatically add new ladder segments to the top, provided it hasn't extended too far up beyond the last block behind it providing support.=
Rope boxes have a certain amount of rope contained within them specified in the name of the node, and have a limit to how much rope they can support that depends on the material they're made of. The different lengths can be crafted by combining and splitting up rope boxes in the crafting grid. For example, you can craft a @1m rope box by putting a @2m rope box and a rope segment in the crafting grid, or a @3m rope box and two rope segments in the crafting grid. Two rope segments can be recovered by putting the @4m rope box in the crafting grid by itself.=
Rope segments are bundles of fibre twisted into robust cables.=
Ropes are hung by placing rope boxes, which automatically lower a rope of fixed length below them. They can be climbed and cut.=
This behaves like most structural blocks except in one circumstance: when placed on top of a block with buildable space on the side facing away from you, this block will not be built on top but instead will extend out from that far side of the target block. This allows a platform to be easily built that juts out away from the location you're standing on.=
This craft item is useful for creating rope ladders, or for spooling on wooden spindles to hang and climb upon.=
When a rope box is placed the rope will immediately begin lowering from it at one meter per second. The rope will only descend when its end is in the vicinity of an active player, suspending its journey when no players are nearby, so a long descent may require a player to climb down the rope as it goes. If you are near the bottom end of a rope that's extending you'll be automatically carried down with it. The rope will stop when it encounters and obstruction, but will resume lowering if the obstruction is removed.=
rope boxes can hold @1m of rope.=
rope boxes can hold rope lengths from @1m to @2m.=
### doc.lua ###
### ropeboxes.lua ###
Copper=
Steel=
Wood=
### extendingladder.lua ###
Steel Extendable Ladder=
Steel Ladder=
Wooden Extendable Ladder=
Wooden Ladder=
### ropeboxes.lua ###
@1 Ropebox @2m=
Rope=
### ropeladder.lua ###
Rope Ladder=

View File

@ -1,6 +0,0 @@
@echo off
setlocal ENABLEEXTENSIONS ENABLEDELAYEDEXPANSION
cd ..
set LIST=
for /r %%X in (*.lua) do set LIST=!LIST! %%X
..\intllib\tools\xgettext.bat %LIST%

View File

@ -1 +1,4 @@
name = ropes
name = ropes
description = Adds rope boxes and ladders
depends = default
optional_depends = cottages, doc, farming, hemp, loot, vines

View File

@ -1,6 +1,5 @@
-- internationalization boilerplate
local MP = minetest.get_modpath(minetest.get_current_modname())
local S, NS = dofile(MP.."/intllib.lua")
local S = ropes.S
local function rope_box_tiles(count, tint)
return {

View File

@ -2,9 +2,7 @@ if ropes.ropeLadderLength == 0 and not ropes.create_all_definitions then
return
end
-- internationalization boilerplate
local MP = minetest.get_modpath(minetest.get_current_modname())
local S, NS = dofile(MP.."/intllib.lua")
local S = ropes.S
if ropes.ropeLadderLength > 0 then
minetest.register_craft({

View File

@ -4,3 +4,4 @@ screwdriver?
streetspoles?
streetlamps?
cottages?
prefab_redo?

198
willow/init.lua Normal file
View File

@ -0,0 +1,198 @@
--
-- Willow
--
local modname = "willow"
local modpath = minetest.get_modpath(modname)
local mg_name = minetest.get_mapgen_setting("mg_name")
-- internationalization boilerplate
local S = minetest.get_translator(minetest.get_current_modname())
-- Willow
local function grow_new_willow_tree(pos)
if not default.can_grow(pos) then
-- try a bit later again
minetest.get_node_timer(pos):start(math.random(240, 600))
return
end
minetest.remove_node(pos)
minetest.place_schematic({x = pos.x-5, y = pos.y, z = pos.z-5}, modpath.."/schematics/willow.mts", "0", nil, false)
end
--
-- Decoration
--
if mg_name ~= "v6" and mg_name ~= "singlenode" then
minetest.register_decoration({
deco_type = "schematic",
place_on = {"default:dirt_with_rainforest_litter"},
sidelen = 16,
noise_params = {
offset = 0.005,
scale = 0.002,
spread = {x = 250, y = 250, z = 250},
seed = 2,
octaves = 3,
persist = 0.66
},
biomes = {"savanna_shore"},
height = 2,
y_min = -1,
y_max = 62,
schematic = modpath.."/schematics/willow.mts",
flags = "place_center_x, place_center_z, force_placement",
rotation = "random",
})
end
--
-- Nodes
--
minetest.register_node("willow:sapling", {
description = S("Willow Tree Sapling"),
drawtype = "plantlike",
visual_scale = 1.0,
tiles = {"willow_sapling.png"},
inventory_image = "willow_sapling.png",
wield_image = "willow_sapling.png",
paramtype = "light",
sunlight_propagates = true,
walkable = false,
on_timer = grow_new_willow_tree,
selection_box = {
type = "fixed",
fixed = {-4 / 16, -0.5, -4 / 16, 4 / 16, 7 / 16, 4 / 16}
},
groups = {snappy = 2, dig_immediate = 3, flammable = 2,
attached_node = 1, sapling = 1},
sounds = default.node_sound_leaves_defaults(),
on_construct = function(pos)
minetest.get_node_timer(pos):start(math.random(2400,4800))
end,
on_place = function(itemstack, placer, pointed_thing)
itemstack = default.sapling_on_place(itemstack, placer, pointed_thing,
"willow:sapling",
-- minp, maxp to be checked, relative to sapling pos
-- minp_relative.y = 1 because sapling pos has been checked
{x = -2, y = 1, z = -2},
{x = 2, y = 6, z = 2},
-- maximum interval of interior volume check
4)
return itemstack
end,
})
minetest.register_node("willow:trunk", {
description = S("Willow Trunk"),
tiles = {
"willow_trunk_top.png",
"willow_trunk_top.png",
"willow_trunk.png"
},
groups = {tree = 1, choppy = 2, oddly_breakable_by_hand = 1, flammable = 2},
sounds = default.node_sound_wood_defaults(),
paramtype2 = "facedir",
is_ground_content = false,
on_place = minetest.rotate_node,
})
-- willow wood
minetest.register_node("willow:wood", {
description = S("Willow Wood"),
tiles = {"willow_wood.png"},
paramtype2 = "facedir",
place_param2 = 0,
is_ground_content = false,
groups = {wood = 1, choppy = 2, oddly_breakable_by_hand = 1, flammable = 3},
sounds = default.node_sound_wood_defaults(),
})
-- willow tree leaves
minetest.register_node("willow:leaves", {
description = S("Willow Leaves"),
drawtype = "allfaces_optional",
visual_scale = 1.2,
tiles = {"willow_leaves.png"},
inventory_image = "willow_leaves.png",
wield_image = "willow_leaves.png",
paramtype = "light",
walkable = true,
waving = 1,
groups = {snappy = 3, leafdecay = 3, leaves = 1, flammable = 2},
drop = {
max_items = 1,
items = {
{items = {"willow:sapling"}, rarity = 20},
{items = {"willow:leaves"}}
}
},
sounds = default.node_sound_leaves_defaults(),
after_place_node = default.after_place_leaves,
})
--
-- Craftitems
--
--
-- Recipes
--
minetest.register_craft({
output = "willow:wood 4",
recipe = {{"willow:trunk"}}
})
minetest.register_craft({
type = "fuel",
recipe = "willow:trunk",
burntime = 30,
})
minetest.register_craft({
type = "fuel",
recipe = "willow:wood",
burntime = 7,
})
minetest.register_lbm({
name = "willow:convert_willow_saplings_to_node_timer",
nodenames = {"willow:sapling"},
action = function(pos)
minetest.get_node_timer(pos):start(math.random(1200, 2400))
end
})
default.register_leafdecay({
trunks = {"willow:trunk"},
leaves = {"willow:leaves"},
radius = 3,
})
--Stairs
if minetest.get_modpath("stairs") ~= nil then
stairs.register_stair_and_slab(
"willow_trunk",
"willow:trunk",
{choppy = 2, oddly_breakable_by_hand = 2, flammable = 2},
{"willow_wood.png"},
S("Willow Stair"),
S("Willow Slab"),
default.node_sound_wood_defaults()
)
end
if minetest.get_modpath("bonemeal") ~= nil then
bonemeal:add_sapling({
{"willow:sapling", grow_new_willow_tree, "soil"},
})
end

View File

@ -0,0 +1,9 @@
# textdomain: willow
Willow Trunk=Madera de sauce
Willow Wood=Tablas de sauce
Willow Leaves=Hojas de sauce
Willow Tree Sapling=Retoño de árbol de sauce
Willow Stair=Escaleras de sauce
Inner Willow Stair=Escaleras de sauce interior
Outer Willow Stair=Escaleras de sauce exterior
Willow Slab=Losa de sauce

4
willow/mod.conf Normal file
View File

@ -0,0 +1,4 @@
name = willow
description = Willow Tree for Swampy Biomes
depends = default
optional_depends = stairs, bonemeal

1008
willow/schematics/willow.lua Normal file

File diff suppressed because it is too large Load Diff

Binary file not shown.

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 KiB