Repository cleanup (#34)
* Add luacheck (and fix warnings) * Remove/or cleanup old files
This commit is contained in:
parent
7906282fa8
commit
3cd0f67943
15
.gitattributes
vendored
15
.gitattributes
vendored
@ -1,17 +1,2 @@
|
||||
# Auto detect text files and perform LF normalization
|
||||
* text=auto
|
||||
|
||||
# Custom for Visual Studio
|
||||
*.cs diff=csharp
|
||||
|
||||
# Standard to msysgit
|
||||
*.doc diff=astextplain
|
||||
*.DOC diff=astextplain
|
||||
*.docx diff=astextplain
|
||||
*.DOCX diff=astextplain
|
||||
*.dot diff=astextplain
|
||||
*.DOT diff=astextplain
|
||||
*.pdf diff=astextplain
|
||||
*.PDF diff=astextplain
|
||||
*.rtf diff=astextplain
|
||||
*.RTF diff=astextplain
|
||||
|
10
.github/workflows/luacheck.yml
vendored
Normal file
10
.github/workflows/luacheck.yml
vendored
Normal file
@ -0,0 +1,10 @@
|
||||
name: luacheck
|
||||
on: [push, pull_request]
|
||||
jobs:
|
||||
luacheck:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@master
|
||||
- name: Luacheck
|
||||
uses: lunarmodules/luacheck@master
|
47
.gitignore
vendored
47
.gitignore
vendored
@ -1,47 +0,0 @@
|
||||
# Windows image file caches
|
||||
Thumbs.db
|
||||
ehthumbs.db
|
||||
|
||||
# Folder config file
|
||||
Desktop.ini
|
||||
|
||||
# Recycle Bin used on file shares
|
||||
$RECYCLE.BIN/
|
||||
|
||||
# Windows Installer files
|
||||
*.cab
|
||||
*.msi
|
||||
*.msm
|
||||
*.msp
|
||||
|
||||
# Windows shortcuts
|
||||
*.lnk
|
||||
|
||||
# =========================
|
||||
# Operating System Files
|
||||
# =========================
|
||||
|
||||
# OSX
|
||||
# =========================
|
||||
|
||||
.DS_Store
|
||||
.AppleDouble
|
||||
.LSOverride
|
||||
|
||||
# Thumbnails
|
||||
._*
|
||||
|
||||
# Files that might appear in the root of a volume
|
||||
.DocumentRevisions-V100
|
||||
.fseventsd
|
||||
.Spotlight-V100
|
||||
.TemporaryItems
|
||||
.Trashes
|
||||
.VolumeIcon.icns
|
||||
|
||||
# Directories potentially created on remote AFP share
|
||||
.AppleDB
|
||||
.AppleDesktop
|
||||
Network Trash Folder
|
||||
Temporary Items
|
||||
.apdisk
|
13
.luacheckrc
Normal file
13
.luacheckrc
Normal file
@ -0,0 +1,13 @@
|
||||
unused_args = false
|
||||
|
||||
read_globals = {
|
||||
"minetest",
|
||||
"ItemStack",
|
||||
table = {fields = {"copy"}},
|
||||
"vector",
|
||||
"default"
|
||||
}
|
||||
|
||||
globals = {
|
||||
"anvil"
|
||||
}
|
@ -1,4 +0,0 @@
|
||||
default
|
||||
doc?
|
||||
intllib?
|
||||
technic?
|
@ -1 +0,0 @@
|
||||
Hammer and anvil for repairing tools
|
448
i18n.py
448
i18n.py
@ -1,448 +0,0 @@
|
||||
#!/usr/bin/env python3
|
||||
# -*- coding: utf-8 -*-
|
||||
#
|
||||
# Script to generate the template file and update the translation files.
|
||||
# Copy the script into the mod or modpack root folder and run it there.
|
||||
#
|
||||
# Copyright (C) 2019 Joachim Stolberg, 2020 FaceDeer, 2020 Louis Royer
|
||||
# LGPLv2.1+
|
||||
#
|
||||
# See https://github.com/minetest-tools/update_translations for
|
||||
# potential future updates to this script.
|
||||
|
||||
from __future__ import print_function
|
||||
import os, fnmatch, re, shutil, errno
|
||||
from sys import argv as _argv
|
||||
from sys import stderr as _stderr
|
||||
|
||||
# Running params
|
||||
params = {"recursive": False,
|
||||
"help": False,
|
||||
"mods": False,
|
||||
"verbose": False,
|
||||
"folders": [],
|
||||
"no-old-file": False
|
||||
}
|
||||
# Available CLI options
|
||||
options = {"recursive": ['--recursive', '-r'],
|
||||
"help": ['--help', '-h'],
|
||||
"mods": ['--installed-mods'],
|
||||
"verbose": ['--verbose', '-v'],
|
||||
"no-old-file": ['--no-old-file']
|
||||
}
|
||||
|
||||
# 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["no-old-file"])}
|
||||
do not create *.old files
|
||||
{', '.join(options["verbose"])}
|
||||
add output information
|
||||
''')
|
||||
|
||||
|
||||
def main():
|
||||
'''Main function'''
|
||||
set_params(_argv)
|
||||
set_params_folders(_argv)
|
||||
if params["help"]:
|
||||
print_help(_argv[0])
|
||||
elif params["recursive"] and params["mods"]:
|
||||
print("Option --installed-mods is incompatible with --recursive")
|
||||
else:
|
||||
# Add recursivity message
|
||||
print("Running ", end='')
|
||||
if params["recursive"]:
|
||||
print("recursively ", end='')
|
||||
# Running
|
||||
if params["mods"]:
|
||||
print(f"on all locally installed modules in {os.path.abspath('~/.minetest/mods/')}")
|
||||
run_all_subfolders("~/.minetest/mods")
|
||||
elif len(params["folders"]) >= 2:
|
||||
print("on folder list:", params["folders"])
|
||||
for f in params["folders"]:
|
||||
if params["recursive"]:
|
||||
run_all_subfolders(f)
|
||||
else:
|
||||
update_folder(f)
|
||||
elif len(params["folders"]) == 1:
|
||||
print("on folder", params["folders"][0])
|
||||
if params["recursive"]:
|
||||
run_all_subfolders(params["folders"][0])
|
||||
else:
|
||||
update_folder(params["folders"][0])
|
||||
else:
|
||||
print("on folder", os.path.abspath("./"))
|
||||
if params["recursive"]:
|
||||
run_all_subfolders(os.path.abspath("./"))
|
||||
else:
|
||||
update_folder(os.path.abspath("./"))
|
||||
|
||||
#group 2 will be the string, groups 1 and 3 will be the delimiters (" or ')
|
||||
#See https://stackoverflow.com/questions/46967465/regex-match-text-in-either-single-or-double-quote
|
||||
pattern_lua_s = re.compile(r'[\.=^\t,{\(\s]N?S\(\s*(["\'])((?:\\\1|(?:(?!\1)).)*)(\1)[\s,\)]', re.DOTALL)
|
||||
pattern_lua_fs = re.compile(r'[\.=^\t,{\(\s]N?FS\(\s*(["\'])((?:\\\1|(?:(?!\1)).)*)(\1)[\s,\)]', re.DOTALL)
|
||||
pattern_lua_bracketed_s = re.compile(r'[\.=^\t,{\(\s]N?S\(\s*\[\[(.*?)\]\][\s,\)]', re.DOTALL)
|
||||
pattern_lua_bracketed_fs = re.compile(r'[\.=^\t,{\(\s]N?FS\(\s*\[\[(.*?)\]\][\s,\)]', re.DOTALL)
|
||||
|
||||
# Handles "concatenation" .. " of strings"
|
||||
pattern_concat = re.compile(r'["\'][\s]*\.\.[\s]*["\']', re.DOTALL)
|
||||
|
||||
pattern_tr = re.compile(r'(.*?[^@])=(.*)')
|
||||
pattern_name = re.compile(r'^name[ ]*=[ ]*([^ \n]*)')
|
||||
pattern_tr_filename = re.compile(r'\.tr$')
|
||||
pattern_po_language_code = re.compile(r'(.*)\.po$')
|
||||
|
||||
#attempt to read the mod's name from the mod.conf file. Returns None on failure
|
||||
def get_modname(folder):
|
||||
try:
|
||||
with open(os.path.join(folder, "mod.conf"), "r", encoding='utf-8') as mod_conf:
|
||||
for line in mod_conf:
|
||||
match = pattern_name.match(line)
|
||||
if match:
|
||||
return match.group(1)
|
||||
except FileNotFoundError:
|
||||
pass
|
||||
return None
|
||||
|
||||
#If there are already .tr files in /locale, returns a list of their names
|
||||
def get_existing_tr_files(folder):
|
||||
out = []
|
||||
for root, dirs, files in os.walk(os.path.join(folder, 'locale/')):
|
||||
for name in files:
|
||||
if pattern_tr_filename.search(name):
|
||||
out.append(name)
|
||||
return out
|
||||
|
||||
# A series of search and replaces that massage a .po file's contents into
|
||||
# a .tr file's equivalent
|
||||
def process_po_file(text):
|
||||
# The first three items are for unused matches
|
||||
text = re.sub(r'#~ msgid "', "", text)
|
||||
text = re.sub(r'"\n#~ msgstr ""\n"', "=", text)
|
||||
text = re.sub(r'"\n#~ msgstr "', "=", text)
|
||||
# comment lines
|
||||
text = re.sub(r'#.*\n', "", text)
|
||||
# converting msg pairs into "=" pairs
|
||||
text = re.sub(r'msgid "', "", text)
|
||||
text = re.sub(r'"\nmsgstr ""\n"', "=", text)
|
||||
text = re.sub(r'"\nmsgstr "', "=", text)
|
||||
# various line breaks and escape codes
|
||||
text = re.sub(r'"\n"', "", text)
|
||||
text = re.sub(r'"\n', "\n", text)
|
||||
text = re.sub(r'\\"', '"', text)
|
||||
text = re.sub(r'\\n', '@n', text)
|
||||
# remove header text
|
||||
text = re.sub(r'=Project-Id-Version:.*\n', "", text)
|
||||
# remove double-spaced lines
|
||||
text = re.sub(r'\n\n', '\n', text)
|
||||
return text
|
||||
|
||||
# Go through existing .po files and, if a .tr file for that language
|
||||
# *doesn't* exist, convert it and create it.
|
||||
# The .tr file that results will subsequently be reprocessed so
|
||||
# any "no longer used" strings will be preserved.
|
||||
# Note that "fuzzy" tags will be lost in this process.
|
||||
def process_po_files(folder, modname):
|
||||
for root, dirs, files in os.walk(os.path.join(folder, 'locale/')):
|
||||
for name in files:
|
||||
code_match = pattern_po_language_code.match(name)
|
||||
if code_match == None:
|
||||
continue
|
||||
language_code = code_match.group(1)
|
||||
tr_name = modname + "." + language_code + ".tr"
|
||||
tr_file = os.path.join(root, tr_name)
|
||||
if os.path.exists(tr_file):
|
||||
if params["verbose"]:
|
||||
print(f"{tr_name} already exists, ignoring {name}")
|
||||
continue
|
||||
fname = os.path.join(root, name)
|
||||
with open(fname, "r", encoding='utf-8') as po_file:
|
||||
if params["verbose"]:
|
||||
print(f"Importing translations from {name}")
|
||||
text = process_po_file(po_file.read())
|
||||
with open(tr_file, "wt", encoding='utf-8') as tr_out:
|
||||
tr_out.write(text)
|
||||
|
||||
# from https://stackoverflow.com/questions/600268/mkdir-p-functionality-in-python/600612#600612
|
||||
# Creates a directory if it doesn't exist, silently does
|
||||
# nothing if it already exists
|
||||
def mkdir_p(path):
|
||||
try:
|
||||
os.makedirs(path)
|
||||
except OSError as exc: # Python >2.5
|
||||
if exc.errno == errno.EEXIST and os.path.isdir(path):
|
||||
pass
|
||||
else: raise
|
||||
|
||||
# Converts the template dictionary to a text to be written as a file
|
||||
# dKeyStrings is a dictionary of localized string to source file sets
|
||||
# dOld is a dictionary of existing translations and comments from
|
||||
# the previous version of this text
|
||||
def strings_to_text(dkeyStrings, dOld, mod_name, header_comments):
|
||||
lOut = [f"# textdomain: {mod_name}\n"]
|
||||
if header_comments is not None:
|
||||
lOut.append(header_comments)
|
||||
|
||||
dGroupedBySource = {}
|
||||
|
||||
for key in dkeyStrings:
|
||||
sourceList = list(dkeyStrings[key])
|
||||
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, existing_template[2])
|
||||
mkdir_p(os.path.dirname(templ_file))
|
||||
with open(templ_file, "wt", encoding='utf-8') as template_file:
|
||||
template_file.write(text)
|
||||
|
||||
|
||||
# Gets all translatable strings from a lua file
|
||||
def read_lua_file_strings(lua_file):
|
||||
lOut = []
|
||||
with open(lua_file, encoding='utf-8') as text_file:
|
||||
text = text_file.read()
|
||||
#TODO remove comments here
|
||||
|
||||
text = re.sub(pattern_concat, "", text)
|
||||
|
||||
strings = []
|
||||
for s in pattern_lua_s.findall(text):
|
||||
strings.append(s[1])
|
||||
for s in pattern_lua_bracketed_s.findall(text):
|
||||
strings.append(s)
|
||||
for s in pattern_lua_fs.findall(text):
|
||||
strings.append(s[1])
|
||||
for s in pattern_lua_bracketed_fs.findall(text):
|
||||
strings.append(s)
|
||||
|
||||
for s in strings:
|
||||
s = re.sub(r'"\.\.\s+"', "", s)
|
||||
s = re.sub("@[^@=0-9]", "@@", s)
|
||||
s = s.replace('\\"', '"')
|
||||
s = s.replace("\\'", "'")
|
||||
s = s.replace("\n", "@n")
|
||||
s = s.replace("\\n", "@n")
|
||||
s = s.replace("=", "@=")
|
||||
lOut.append(s)
|
||||
return lOut
|
||||
|
||||
# Gets strings from an existing translation file
|
||||
# returns both a dictionary of translations
|
||||
# and the full original source text so that the new text
|
||||
# can be compared to it for changes.
|
||||
# Returns also header comments in the third return value.
|
||||
def import_tr_file(tr_file):
|
||||
dOut = {}
|
||||
text = None
|
||||
header_comment = None
|
||||
if os.path.exists(tr_file):
|
||||
with open(tr_file, "r", encoding='utf-8') as existing_file :
|
||||
# save the full text to allow for comparison
|
||||
# of the old version with the new output
|
||||
text = existing_file.read()
|
||||
existing_file.seek(0)
|
||||
# a running record of the current comment block
|
||||
# we're inside, to allow preceeding multi-line comments
|
||||
# to be retained for a translation line
|
||||
latest_comment_block = None
|
||||
for line in existing_file.readlines():
|
||||
line = line.rstrip('\n')
|
||||
if line[:3] == "###":
|
||||
if header_comment is None:
|
||||
# Save header comments
|
||||
header_comment = latest_comment_block
|
||||
# Stip textdomain line
|
||||
tmp_h_c = ""
|
||||
for l in header_comment.split('\n'):
|
||||
if not l.startswith("# textdomain:"):
|
||||
tmp_h_c += l + '\n'
|
||||
header_comment = tmp_h_c
|
||||
|
||||
# Reset comment block if we hit a header
|
||||
latest_comment_block = None
|
||||
continue
|
||||
if line[:1] == "#":
|
||||
# Save the comment we're inside
|
||||
if not latest_comment_block:
|
||||
latest_comment_block = line
|
||||
else:
|
||||
latest_comment_block = latest_comment_block + "\n" + line
|
||||
continue
|
||||
match = pattern_tr.match(line)
|
||||
if match:
|
||||
# this line is a translated line
|
||||
outval = {}
|
||||
outval["translation"] = match.group(2)
|
||||
if latest_comment_block:
|
||||
# if there was a comment, record that.
|
||||
outval["comment"] = latest_comment_block
|
||||
latest_comment_block = None
|
||||
dOut[match.group(1)] = outval
|
||||
return (dOut, text, header_comment)
|
||||
|
||||
# Walks all lua files in the mod folder, collects translatable strings,
|
||||
# and writes it to a template.txt file
|
||||
# Returns a dictionary of localized strings to source file sets
|
||||
# that can be used with the strings_to_text function.
|
||||
def generate_template(folder, mod_name):
|
||||
dOut = {}
|
||||
for root, dirs, files in os.walk(folder):
|
||||
for name in files:
|
||||
if fnmatch.fnmatch(name, "*.lua"):
|
||||
fname = os.path.join(root, name)
|
||||
found = read_lua_file_strings(fname)
|
||||
if params["verbose"]:
|
||||
print(f"{fname}: {str(len(found))} translatable strings")
|
||||
|
||||
for s in found:
|
||||
sources = dOut.get(s, set())
|
||||
sources.add(f"### {os.path.basename(fname)} ###")
|
||||
dOut[s] = sources
|
||||
|
||||
if len(dOut) == 0:
|
||||
return None
|
||||
templ_file = os.path.join(folder, "locale/template.txt")
|
||||
write_template(templ_file, dOut, mod_name)
|
||||
return dOut
|
||||
|
||||
# Updates an existing .tr file, copying the old one to a ".old" file
|
||||
# if any changes have happened
|
||||
# dNew is the data used to generate the template, it has all the
|
||||
# currently-existing localized strings
|
||||
def update_tr_file(dNew, mod_name, tr_file):
|
||||
if params["verbose"]:
|
||||
print(f"updating {tr_file}")
|
||||
|
||||
tr_import = import_tr_file(tr_file)
|
||||
dOld = tr_import[0]
|
||||
textOld = tr_import[1]
|
||||
|
||||
textNew = strings_to_text(dNew, dOld, mod_name, tr_import[2])
|
||||
|
||||
if textOld and textOld != textNew:
|
||||
print(f"{tr_file} has changed.")
|
||||
if not params["no-old-file"]:
|
||||
shutil.copyfile(tr_file, f"{tr_file}.old")
|
||||
|
||||
with open(tr_file, "w", encoding='utf-8') as new_tr_file:
|
||||
new_tr_file.write(textNew)
|
||||
|
||||
# Updates translation files for the mod in the given folder
|
||||
def update_mod(folder):
|
||||
modname = get_modname(folder)
|
||||
if modname is not None:
|
||||
process_po_files(folder, modname)
|
||||
print(f"Updating translations for {modname}")
|
||||
data = generate_template(folder, modname)
|
||||
if data == None:
|
||||
print(f"No translatable strings found in {modname}")
|
||||
else:
|
||||
for tr_file in get_existing_tr_files(folder):
|
||||
update_tr_file(data, modname, os.path.join(folder, "locale/", tr_file))
|
||||
else:
|
||||
print(f"\033[31mUnable to find modname in folder {folder}.\033[0m", file=_stderr)
|
||||
exit(1)
|
||||
|
||||
# Determines if the folder being pointed to is a mod or a mod pack
|
||||
# and then runs update_mod accordingly
|
||||
def update_folder(folder):
|
||||
is_modpack = os.path.exists(os.path.join(folder, "modpack.txt")) or os.path.exists(os.path.join(folder, "modpack.conf"))
|
||||
if is_modpack:
|
||||
subfolders = [f.path for f in os.scandir(folder) if f.is_dir()]
|
||||
for subfolder in subfolders:
|
||||
update_mod(subfolder + "/")
|
||||
else:
|
||||
update_mod(folder)
|
||||
print("Done.")
|
||||
|
||||
def run_all_subfolders(folder):
|
||||
for modfolder in [f.path for f in os.scandir(folder) if f.is_dir()]:
|
||||
update_folder(modfolder + "/")
|
||||
|
||||
|
||||
main()
|
37
init.lua
37
init.lua
@ -19,11 +19,8 @@ local hud_timeout = 2 -- seconds
|
||||
anvil.make_unrepairable = function(item_name)
|
||||
local item_def = minetest.registered_items[item_name]
|
||||
if item_def then
|
||||
-- Drop table reference. Copy other values over.
|
||||
local groups = {not_repaired_by_anvil = 1}
|
||||
for k, v in pairs(item_def.groups) do
|
||||
groups[k] = v
|
||||
end
|
||||
local groups = table.copy(item_def.groups)
|
||||
groups.not_repaired_by_anvil = 1
|
||||
minetest.override_item(item_name, {groups = groups})
|
||||
end
|
||||
end
|
||||
@ -62,7 +59,8 @@ local S = minetest.get_translator(minetest.get_current_modname())
|
||||
local hammer_def = {
|
||||
description = S("Steel blacksmithing hammer"),
|
||||
_doc_items_longdesc = S("A tool for repairing other tools at a blacksmith's anvil."),
|
||||
_doc_items_usagehelp = 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."),
|
||||
_doc_items_usagehelp = 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."),
|
||||
image = "anvil_tool_steelhammer.png",
|
||||
inventory_image = "anvil_tool_steelhammer.png",
|
||||
|
||||
@ -120,7 +118,8 @@ minetest.register_entity("anvil:item", {
|
||||
})
|
||||
|
||||
local remove_item = function(pos, node)
|
||||
local objs = minetest.get_objects_inside_radius({x = pos.x, y = pos.y + anvil.setting.item_displacement, z = pos.z}, .5)
|
||||
local npos = vector.new(pos.x, pos.y + anvil.setting.item_displacement, pos.z)
|
||||
local objs = minetest.get_objects_inside_radius(npos, .5)
|
||||
if objs then
|
||||
for _, obj in ipairs(objs) do
|
||||
if obj and obj:get_luaentity() and obj:get_luaentity().name == "anvil:item" then
|
||||
@ -139,16 +138,10 @@ local update_item = function(pos, node)
|
||||
tmp.texture = inv:get_stack("input", 1):get_name()
|
||||
local e = minetest.add_entity(pos, "anvil:item")
|
||||
local yaw = math.pi * 2 - node.param2 * math.pi / 2
|
||||
if e.set_rotation == nil then
|
||||
-- This is for 0.4.16 support, remove it eventually
|
||||
e:set_yaw(yaw)
|
||||
pos.y = pos.y + 5 / 16
|
||||
e:set_pos(pos)
|
||||
else
|
||||
e:set_rotation({x = -1.5708, y = yaw, z = 0}) -- x is pitch, 1.5708 is 90 degrees.
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
local function has_access(pos, player)
|
||||
local name = player:get_player_name()
|
||||
@ -162,14 +155,6 @@ local function has_access(pos, player)
|
||||
end
|
||||
end
|
||||
|
||||
local metal_sounds
|
||||
-- Apparently node_sound_metal_defaults is a newer thing, I ran into games using an older version of the default mod without it.
|
||||
if default.node_sound_metal_defaults ~= nil then
|
||||
metal_sounds = default.node_sound_metal_defaults()
|
||||
else
|
||||
metal_sounds = default.node_sound_stone_defaults()
|
||||
end
|
||||
|
||||
local hud_info_by_puncher_name = {}
|
||||
|
||||
minetest.register_globalstep(function()
|
||||
@ -200,12 +185,15 @@ minetest.register_node("anvil:anvil", {
|
||||
drawtype = "nodebox",
|
||||
description = S("Anvil"),
|
||||
_doc_items_longdesc = S("A tool for repairing other tools in conjunction with a blacksmith's hammer."),
|
||||
_doc_items_usagehelp = S("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."),
|
||||
_doc_items_usagehelp = S("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."),
|
||||
tiles = {"default_stone.png"},
|
||||
paramtype = "light",
|
||||
paramtype2 = "facedir",
|
||||
groups = {cracky = 2},
|
||||
sounds = metal_sounds,
|
||||
sounds = default.node_sound_metal_defaults(),
|
||||
-- the nodebox model comes from realtest
|
||||
node_box = {
|
||||
type = "fixed",
|
||||
@ -334,7 +322,6 @@ minetest.register_node("anvil:anvil", {
|
||||
local this_def = minetest.registered_nodes[node.name]
|
||||
if this_def.allow_metadata_inventory_put(pos, "input", 1, itemstack:peek_item(), clicker) > 0 then
|
||||
local s = itemstack:take_item()
|
||||
local meta = minetest.get_meta(pos)
|
||||
local inv = meta:get_inventory()
|
||||
inv:add_item("input", s)
|
||||
local meta_description = s:get_meta():get_string("description")
|
||||
|
@ -1,23 +1,12 @@
|
||||
# textdomain: anvil
|
||||
|
||||
|
||||
|
||||
### init.lua ###
|
||||
|
||||
@1 cannot be repaired with an anvil.=@1 kann nicht mit einem Amboss repariert werden.
|
||||
@1's anvil=@1 Amboss
|
||||
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.=Ein Werkzeug zur Reparatur anderer Werkzeuge mit einem Schmiedehammer.
|
||||
|
||||
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.=Klicken Sie mit einem beschädigten Werkzeug mit der rechten Maustaste auf diesen Amboss, um das beschädigte Werkzeug darauf zu platzieren. Sie können das beschädigte Werkzeug dann reparieren, indem Sie es mit einem Schmiedehammer schlagen. Wiederholte Schläge können erforderlich sein, um ein stark abgenutztes Werkzeug vollständig zu reparieren. Um das Werkzeug abzurufen, schlagen Sie entweder mit einer leeren Hand auf den Amboss oder klicken Sie mit der rechten Maustaste darauf.
|
||||
|
||||
Shared anvil=Geteilter Amboss
|
||||
Steel blacksmithing hammer=Stahlschmiedehammer
|
||||
This anvil is for damaged tools only.=Dieser Amboss ist nur für beschädigte Werkzeuge geeignet.
|
||||
|
||||
A tool for repairing other tools at a blacksmith's anvil.=Stahlhammer um Werkzeuge auf dem Amboss zu reparieren
|
||||
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.=Schlagen Sie mit diesem Hammer auf einen Amboss mit einem beschädigten Werkzeug und reparieren Sie ihn. Es kann auch zum Zertrümmern von Steinen verwendet werden, ist jedoch für diese Aufgabe nicht gut geeignet.
|
||||
|
||||
Anvil=Amboss
|
||||
A tool for repairing other tools in conjunction with a blacksmith's hammer.=Ein Werkzeug zur Reparatur anderer Werkzeuge mit einem Schmiedehammer.
|
||||
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.=Klicken Sie mit einem beschädigten Werkzeug mit der rechten Maustaste auf diesen Amboss, um das beschädigte Werkzeug darauf zu platzieren. Sie können das beschädigte Werkzeug dann reparieren, indem Sie es mit einem Schmiedehammer schlagen. Wiederholte Schläge können erforderlich sein, um ein stark abgenutztes Werkzeug vollständig zu reparieren. Um das Werkzeug abzurufen, schlagen Sie entweder mit einer leeren Hand auf den Amboss oder klicken Sie mit der rechten Maustaste darauf.
|
||||
Shared anvil=Geteilter Amboss
|
||||
@1's anvil=@1 Amboss
|
||||
This anvil is for damaged tools only.=Dieser Amboss ist nur für beschädigte Werkzeuge geeignet.
|
||||
@1 cannot be repaired with an anvil.=@1 kann nicht mit einem Amboss repariert werden.
|
||||
Your @1 has been repaired successfully.=Ihr @1 wurde erfolgreich repariert.
|
||||
|
@ -1,26 +1,12 @@
|
||||
# textdomain: anvil
|
||||
|
||||
|
||||
|
||||
### init.lua ###
|
||||
|
||||
#WARNING: AUTOTRANSLATED BY GOOGLE TRANSLATE
|
||||
@1 cannot be repaired with an anvil.=@1 no se puede reparar con un yunque.
|
||||
#WARNING: AUTOTRANSLATED BY GOOGLE TRANSLATE
|
||||
@1's anvil=Yunque de @1
|
||||
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
|
||||
|
||||
#WARNING: AUTOTRANSLATED BY GOOGLE TRANSLATE
|
||||
Shared anvil=Yunque compartido
|
||||
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
|
||||
|
||||
A tool for repairing other tools at a blacksmith's anvil.=Es una herramienta para reparar otras herramientas en el yunque del herrero
|
||||
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.
|
||||
|
||||
Anvil=Yunque
|
||||
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.
|
||||
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
|
||||
Shared anvil=Yunque compartido
|
||||
@1's anvil=Yunque de @1
|
||||
This anvil is for damaged tools only.=Este yunque es sólo para herramientas dañadas
|
||||
@1 cannot be repaired with an anvil.=@1 no se puede reparar con un yunque.
|
||||
Your @1 has been repaired successfully.=Su @1 ha sido reparado correctamente.
|
||||
|
@ -1,24 +1,12 @@
|
||||
# textdomain: anvil
|
||||
|
||||
|
||||
|
||||
### init.lua ###
|
||||
|
||||
@1 cannot be repaired with an anvil.=@1 ne peut pas être réparé avec une enclume.
|
||||
@1's anvil=enclume de @1
|
||||
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.
|
||||
|
||||
#WARNING: AUTOTRANSLATED BY GOOGLE TRANSLATE
|
||||
Shared anvil=Enclume partagée
|
||||
Steel blacksmithing hammer=Marteau de forgeron en acier
|
||||
This anvil is for damaged tools only.=L'enclume s'utilise sur les outils endommagés.
|
||||
|
||||
A tool for repairing other tools at a blacksmith's anvil.=Un outil pour réparer les autres outils avec une enclume de forgeron.
|
||||
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.
|
||||
|
||||
Anvil=Enclume
|
||||
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.
|
||||
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.
|
||||
Shared anvil=Enclume partagée
|
||||
@1's anvil=enclume de @1
|
||||
This anvil is for damaged tools only.=L'enclume s'utilise sur les outils endommagés.
|
||||
@1 cannot be repaired with an anvil.=@1 ne peut pas être réparé avec une enclume.
|
||||
Your @1 has been repaired successfully.=Votre @1 a été réparé avec succès.
|
||||
|
@ -1,26 +1,12 @@
|
||||
# textdomain: anvil
|
||||
|
||||
|
||||
|
||||
### init.lua ###
|
||||
|
||||
#WARNING: AUTOTRANSLATED BY GOOGLE TRANSLATE
|
||||
@1 cannot be repaired with an anvil.=@1 non può essere riparato con un'incudine.
|
||||
#WARNING: AUTOTRANSLATED BY GOOGLE TRANSLATE
|
||||
@1's anvil=L'incudine di @1
|
||||
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.
|
||||
|
||||
#WARNING: AUTOTRANSLATED BY GOOGLE TRANSLATE
|
||||
Shared anvil=Incudine condivisa
|
||||
Steel blacksmithing hammer=Martello da fabbro di acciaio
|
||||
This anvil is for damaged tools only.=Questa incudine è solo per attrezzi danneggiati.
|
||||
|
||||
A tool for repairing other tools at a blacksmith's anvil.=Un attrezzo per riparare altri attrezzi su di una incudine da fabbro.
|
||||
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.
|
||||
|
||||
Anvil=Incudine
|
||||
A tool for repairing other tools in conjunction with a blacksmith's hammer.=Un attrezzo per riparare altri attrezzi usando un martello da fabbro.
|
||||
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.
|
||||
Shared anvil=Incudine condivisa
|
||||
@1's anvil=L'incudine di @1
|
||||
This anvil is for damaged tools only.=Questa incudine è solo per attrezzi danneggiati.
|
||||
@1 cannot be repaired with an anvil.=@1 non può essere riparato con un'incudine.
|
||||
Your @1 has been repaired successfully.=La/il vostr* @1 è stat* riparat* con successo.
|
||||
|
@ -1,23 +1,12 @@
|
||||
# textdomain: anvil
|
||||
|
||||
|
||||
|
||||
### init.lua ###
|
||||
|
||||
@1 cannot be repaired with an anvil.=@1 não pode ser reparado com uma bigorna.
|
||||
@1's anvil=bigorna de @1
|
||||
A tool for repairing other tools at a blacksmith's anvil.=Uma ferramenta para consertar outras ferramentas na bigorna de um ferreiro.
|
||||
|
||||
A tool for repairing other tools in conjunction with a blacksmith's hammer.=Uma ferramenta para reparar outras ferramentas em conjunto com um martelo de ferreiro.
|
||||
|
||||
Anvil=Bigorna
|
||||
|
||||
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.=Clique com o botão direito nesta bigorna com uma ferramenta danificada para colocar a ferramenta danificada sobre ela. Você pode consertar a ferramenta danificada batendo nela com um martelo de ferreiro. Golpes repetidos podem ser necessários para reparar completamente uma ferramenta muito gasta. Para recuperar a ferramenta, perfure ou clique com o botão direito do mouse na bigorna com a mão vazia.
|
||||
|
||||
Shared anvil=bigorna compartilhada
|
||||
Steel blacksmithing hammer=Martelo de ferreiro de aço
|
||||
This anvil is for damaged tools only.=Esta bigorna é apenas para ferramentas danificadas.
|
||||
|
||||
A tool for repairing other tools at a blacksmith's anvil.=Uma ferramenta para consertar outras ferramentas na bigorna de um ferreiro.
|
||||
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 martelo para golpear uma bigorna com uma ferramenta danificada e você poderá consertá-la. Também pode ser usado para quebrar pedras, mas não é adequado para essa tarefa.
|
||||
|
||||
Anvil=Bigorna
|
||||
A tool for repairing other tools in conjunction with a blacksmith's hammer.=Uma ferramenta para reparar outras ferramentas em conjunto com um martelo de ferreiro.
|
||||
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.=Clique com o botão direito nesta bigorna com uma ferramenta danificada para colocar a ferramenta danificada sobre ela. Você pode consertar a ferramenta danificada batendo nela com um martelo de ferreiro. Golpes repetidos podem ser necessários para reparar completamente uma ferramenta muito gasta. Para recuperar a ferramenta, perfure ou clique com o botão direito do mouse na bigorna com a mão vazia.
|
||||
Shared anvil=bigorna compartilhada
|
||||
@1's anvil=bigorna de @1
|
||||
This anvil is for damaged tools only.=Esta bigorna é apenas para ferramentas danificadas.
|
||||
@1 cannot be repaired with an anvil.=@1 não pode ser reparado com uma bigorna.
|
||||
Your @1 has been repaired successfully.=Seu @1 foi reparado com sucesso.
|
||||
|
@ -1,23 +1,12 @@
|
||||
# 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.=
|
||||
|
||||
Shared anvil=
|
||||
Steel blacksmithing hammer=
|
||||
This anvil is for damaged tools only.=
|
||||
|
||||
A tool for repairing other tools at a blacksmith's anvil.=
|
||||
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.=
|
||||
|
||||
Anvil=
|
||||
A tool for repairing other tools in conjunction with a blacksmith's hammer.=
|
||||
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.=
|
||||
Shared anvil=
|
||||
@1's anvil=
|
||||
This anvil is for damaged tools only.=
|
||||
@1 cannot be repaired with an anvil.=
|
||||
Your @1 has been repaired successfully.=
|
||||
|
Loading…
x
Reference in New Issue
Block a user