initial upload
|
@ -0,0 +1,519 @@
|
||||||
|
License of media (textures and sounds)
|
||||||
|
--------------------------------------
|
||||||
|
Copyright (C) 2010-2012 celeron55, Perttu Ahola <celeron55@gmail.com>
|
||||||
|
See README.txt in each mod directory for information about other authors.
|
||||||
|
|
||||||
|
Attribution-ShareAlike 3.0 Unported (CC BY-SA 3.0)
|
||||||
|
http://creativecommons.org/licenses/by-sa/3.0/
|
||||||
|
|
||||||
|
License of menu/header.png
|
||||||
|
Copyright (C) 2015 paramat CC BY-SA 3.0
|
||||||
|
|
||||||
|
|
||||||
|
License of source code
|
||||||
|
----------------------
|
||||||
|
Copyright (C) 2010-2012 celeron55, Perttu Ahola <celeron55@gmail.com>
|
||||||
|
See README.txt in each mod directory for information about other authors.
|
||||||
|
|
||||||
|
GNU LESSER GENERAL PUBLIC LICENSE
|
||||||
|
Version 2.1, February 1999
|
||||||
|
|
||||||
|
Copyright (C) 1991, 1999 Free Software Foundation, Inc.
|
||||||
|
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||||
|
Everyone is permitted to copy and distribute verbatim copies
|
||||||
|
of this license document, but changing it is not allowed.
|
||||||
|
|
||||||
|
[This is the first released version of the Lesser GPL. It also counts
|
||||||
|
as the successor of the GNU Library Public License, version 2, hence
|
||||||
|
the version number 2.1.]
|
||||||
|
|
||||||
|
Preamble
|
||||||
|
|
||||||
|
The licenses for most software are designed to take away your
|
||||||
|
freedom to share and change it. By contrast, the GNU General Public
|
||||||
|
Licenses are intended to guarantee your freedom to share and change
|
||||||
|
free software--to make sure the software is free for all its users.
|
||||||
|
|
||||||
|
This license, the Lesser General Public License, applies to some
|
||||||
|
specially designated software packages--typically libraries--of the
|
||||||
|
Free Software Foundation and other authors who decide to use it. You
|
||||||
|
can use it too, but we suggest you first think carefully about whether
|
||||||
|
this license or the ordinary General Public License is the better
|
||||||
|
strategy to use in any particular case, based on the explanations below.
|
||||||
|
|
||||||
|
When we speak of free software, we are referring to freedom of use,
|
||||||
|
not price. Our General Public Licenses are designed to make sure that
|
||||||
|
you have the freedom to distribute copies of free software (and charge
|
||||||
|
for this service if you wish); that you receive source code or can get
|
||||||
|
it if you want it; that you can change the software and use pieces of
|
||||||
|
it in new free programs; and that you are informed that you can do
|
||||||
|
these things.
|
||||||
|
|
||||||
|
To protect your rights, we need to make restrictions that forbid
|
||||||
|
distributors to deny you these rights or to ask you to surrender these
|
||||||
|
rights. These restrictions translate to certain responsibilities for
|
||||||
|
you if you distribute copies of the library or if you modify it.
|
||||||
|
|
||||||
|
For example, if you distribute copies of the library, whether gratis
|
||||||
|
or for a fee, you must give the recipients all the rights that we gave
|
||||||
|
you. You must make sure that they, too, receive or can get the source
|
||||||
|
code. If you link other code with the library, you must provide
|
||||||
|
complete object files to the recipients, so that they can relink them
|
||||||
|
with the library after making changes to the library and recompiling
|
||||||
|
it. And you must show them these terms so they know their rights.
|
||||||
|
|
||||||
|
We protect your rights with a two-step method: (1) we copyright the
|
||||||
|
library, and (2) we offer you this license, which gives you legal
|
||||||
|
permission to copy, distribute and/or modify the library.
|
||||||
|
|
||||||
|
To protect each distributor, we want to make it very clear that
|
||||||
|
there is no warranty for the free library. Also, if the library is
|
||||||
|
modified by someone else and passed on, the recipients should know
|
||||||
|
that what they have is not the original version, so that the original
|
||||||
|
author's reputation will not be affected by problems that might be
|
||||||
|
introduced by others.
|
||||||
|
|
||||||
|
Finally, software patents pose a constant threat to the existence of
|
||||||
|
any free program. We wish to make sure that a company cannot
|
||||||
|
effectively restrict the users of a free program by obtaining a
|
||||||
|
restrictive license from a patent holder. Therefore, we insist that
|
||||||
|
any patent license obtained for a version of the library must be
|
||||||
|
consistent with the full freedom of use specified in this license.
|
||||||
|
|
||||||
|
Most GNU software, including some libraries, is covered by the
|
||||||
|
ordinary GNU General Public License. This license, the GNU Lesser
|
||||||
|
General Public License, applies to certain designated libraries, and
|
||||||
|
is quite different from the ordinary General Public License. We use
|
||||||
|
this license for certain libraries in order to permit linking those
|
||||||
|
libraries into non-free programs.
|
||||||
|
|
||||||
|
When a program is linked with a library, whether statically or using
|
||||||
|
a shared library, the combination of the two is legally speaking a
|
||||||
|
combined work, a derivative of the original library. The ordinary
|
||||||
|
General Public License therefore permits such linking only if the
|
||||||
|
entire combination fits its criteria of freedom. The Lesser General
|
||||||
|
Public License permits more lax criteria for linking other code with
|
||||||
|
the library.
|
||||||
|
|
||||||
|
We call this license the "Lesser" General Public License because it
|
||||||
|
does Less to protect the user's freedom than the ordinary General
|
||||||
|
Public License. It also provides other free software developers Less
|
||||||
|
of an advantage over competing non-free programs. These disadvantages
|
||||||
|
are the reason we use the ordinary General Public License for many
|
||||||
|
libraries. However, the Lesser license provides advantages in certain
|
||||||
|
special circumstances.
|
||||||
|
|
||||||
|
For example, on rare occasions, there may be a special need to
|
||||||
|
encourage the widest possible use of a certain library, so that it becomes
|
||||||
|
a de-facto standard. To achieve this, non-free programs must be
|
||||||
|
allowed to use the library. A more frequent case is that a free
|
||||||
|
library does the same job as widely used non-free libraries. In this
|
||||||
|
case, there is little to gain by limiting the free library to free
|
||||||
|
software only, so we use the Lesser General Public License.
|
||||||
|
|
||||||
|
In other cases, permission to use a particular library in non-free
|
||||||
|
programs enables a greater number of people to use a large body of
|
||||||
|
free software. For example, permission to use the GNU C Library in
|
||||||
|
non-free programs enables many more people to use the whole GNU
|
||||||
|
operating system, as well as its variant, the GNU/Linux operating
|
||||||
|
system.
|
||||||
|
|
||||||
|
Although the Lesser General Public License is Less protective of the
|
||||||
|
users' freedom, it does ensure that the user of a program that is
|
||||||
|
linked with the Library has the freedom and the wherewithal to run
|
||||||
|
that program using a modified version of the Library.
|
||||||
|
|
||||||
|
The precise terms and conditions for copying, distribution and
|
||||||
|
modification follow. Pay close attention to the difference between a
|
||||||
|
"work based on the library" and a "work that uses the library". The
|
||||||
|
former contains code derived from the library, whereas the latter must
|
||||||
|
be combined with the library in order to run.
|
||||||
|
|
||||||
|
GNU LESSER GENERAL PUBLIC LICENSE
|
||||||
|
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
|
||||||
|
|
||||||
|
0. This License Agreement applies to any software library or other
|
||||||
|
program which contains a notice placed by the copyright holder or
|
||||||
|
other authorized party saying it may be distributed under the terms of
|
||||||
|
this Lesser General Public License (also called "this License").
|
||||||
|
Each licensee is addressed as "you".
|
||||||
|
|
||||||
|
A "library" means a collection of software functions and/or data
|
||||||
|
prepared so as to be conveniently linked with application programs
|
||||||
|
(which use some of those functions and data) to form executables.
|
||||||
|
|
||||||
|
The "Library", below, refers to any such software library or work
|
||||||
|
which has been distributed under these terms. A "work based on the
|
||||||
|
Library" means either the Library or any derivative work under
|
||||||
|
copyright law: that is to say, a work containing the Library or a
|
||||||
|
portion of it, either verbatim or with modifications and/or translated
|
||||||
|
straightforwardly into another language. (Hereinafter, translation is
|
||||||
|
included without limitation in the term "modification".)
|
||||||
|
|
||||||
|
"Source code" for a work means the preferred form of the work for
|
||||||
|
making modifications to it. For a library, complete source code means
|
||||||
|
all the source code for all modules it contains, plus any associated
|
||||||
|
interface definition files, plus the scripts used to control compilation
|
||||||
|
and installation of the library.
|
||||||
|
|
||||||
|
Activities other than copying, distribution and modification are not
|
||||||
|
covered by this License; they are outside its scope. The act of
|
||||||
|
running a program using the Library is not restricted, and output from
|
||||||
|
such a program is covered only if its contents constitute a work based
|
||||||
|
on the Library (independent of the use of the Library in a tool for
|
||||||
|
writing it). Whether that is true depends on what the Library does
|
||||||
|
and what the program that uses the Library does.
|
||||||
|
|
||||||
|
1. You may copy and distribute verbatim copies of the Library's
|
||||||
|
complete source code as you receive it, in any medium, provided that
|
||||||
|
you conspicuously and appropriately publish on each copy an
|
||||||
|
appropriate copyright notice and disclaimer of warranty; keep intact
|
||||||
|
all the notices that refer to this License and to the absence of any
|
||||||
|
warranty; and distribute a copy of this License along with the
|
||||||
|
Library.
|
||||||
|
|
||||||
|
You may charge a fee for the physical act of transferring a copy,
|
||||||
|
and you may at your option offer warranty protection in exchange for a
|
||||||
|
fee.
|
||||||
|
|
||||||
|
2. You may modify your copy or copies of the Library or any portion
|
||||||
|
of it, thus forming a work based on the Library, and copy and
|
||||||
|
distribute such modifications or work under the terms of Section 1
|
||||||
|
above, provided that you also meet all of these conditions:
|
||||||
|
|
||||||
|
a) The modified work must itself be a software library.
|
||||||
|
|
||||||
|
b) You must cause the files modified to carry prominent notices
|
||||||
|
stating that you changed the files and the date of any change.
|
||||||
|
|
||||||
|
c) You must cause the whole of the work to be licensed at no
|
||||||
|
charge to all third parties under the terms of this License.
|
||||||
|
|
||||||
|
d) If a facility in the modified Library refers to a function or a
|
||||||
|
table of data to be supplied by an application program that uses
|
||||||
|
the facility, other than as an argument passed when the facility
|
||||||
|
is invoked, then you must make a good faith effort to ensure that,
|
||||||
|
in the event an application does not supply such function or
|
||||||
|
table, the facility still operates, and performs whatever part of
|
||||||
|
its purpose remains meaningful.
|
||||||
|
|
||||||
|
(For example, a function in a library to compute square roots has
|
||||||
|
a purpose that is entirely well-defined independent of the
|
||||||
|
application. Therefore, Subsection 2d requires that any
|
||||||
|
application-supplied function or table used by this function must
|
||||||
|
be optional: if the application does not supply it, the square
|
||||||
|
root function must still compute square roots.)
|
||||||
|
|
||||||
|
These requirements apply to the modified work as a whole. If
|
||||||
|
identifiable sections of that work are not derived from the Library,
|
||||||
|
and can be reasonably considered independent and separate works in
|
||||||
|
themselves, then this License, and its terms, do not apply to those
|
||||||
|
sections when you distribute them as separate works. But when you
|
||||||
|
distribute the same sections as part of a whole which is a work based
|
||||||
|
on the Library, the distribution of the whole must be on the terms of
|
||||||
|
this License, whose permissions for other licensees extend to the
|
||||||
|
entire whole, and thus to each and every part regardless of who wrote
|
||||||
|
it.
|
||||||
|
|
||||||
|
Thus, it is not the intent of this section to claim rights or contest
|
||||||
|
your rights to work written entirely by you; rather, the intent is to
|
||||||
|
exercise the right to control the distribution of derivative or
|
||||||
|
collective works based on the Library.
|
||||||
|
|
||||||
|
In addition, mere aggregation of another work not based on the Library
|
||||||
|
with the Library (or with a work based on the Library) on a volume of
|
||||||
|
a storage or distribution medium does not bring the other work under
|
||||||
|
the scope of this License.
|
||||||
|
|
||||||
|
3. You may opt to apply the terms of the ordinary GNU General Public
|
||||||
|
License instead of this License to a given copy of the Library. To do
|
||||||
|
this, you must alter all the notices that refer to this License, so
|
||||||
|
that they refer to the ordinary GNU General Public License, version 2,
|
||||||
|
instead of to this License. (If a newer version than version 2 of the
|
||||||
|
ordinary GNU General Public License has appeared, then you can specify
|
||||||
|
that version instead if you wish.) Do not make any other change in
|
||||||
|
these notices.
|
||||||
|
|
||||||
|
Once this change is made in a given copy, it is irreversible for
|
||||||
|
that copy, so the ordinary GNU General Public License applies to all
|
||||||
|
subsequent copies and derivative works made from that copy.
|
||||||
|
|
||||||
|
This option is useful when you wish to copy part of the code of
|
||||||
|
the Library into a program that is not a library.
|
||||||
|
|
||||||
|
4. You may copy and distribute the Library (or a portion or
|
||||||
|
derivative of it, under Section 2) in object code or executable form
|
||||||
|
under the terms of Sections 1 and 2 above provided that you accompany
|
||||||
|
it with the complete corresponding machine-readable source code, which
|
||||||
|
must be distributed under the terms of Sections 1 and 2 above on a
|
||||||
|
medium customarily used for software interchange.
|
||||||
|
|
||||||
|
If distribution of object code is made by offering access to copy
|
||||||
|
from a designated place, then offering equivalent access to copy the
|
||||||
|
source code from the same place satisfies the requirement to
|
||||||
|
distribute the source code, even though third parties are not
|
||||||
|
compelled to copy the source along with the object code.
|
||||||
|
|
||||||
|
5. A program that contains no derivative of any portion of the
|
||||||
|
Library, but is designed to work with the Library by being compiled or
|
||||||
|
linked with it, is called a "work that uses the Library". Such a
|
||||||
|
work, in isolation, is not a derivative work of the Library, and
|
||||||
|
therefore falls outside the scope of this License.
|
||||||
|
|
||||||
|
However, linking a "work that uses the Library" with the Library
|
||||||
|
creates an executable that is a derivative of the Library (because it
|
||||||
|
contains portions of the Library), rather than a "work that uses the
|
||||||
|
library". The executable is therefore covered by this License.
|
||||||
|
Section 6 states terms for distribution of such executables.
|
||||||
|
|
||||||
|
When a "work that uses the Library" uses material from a header file
|
||||||
|
that is part of the Library, the object code for the work may be a
|
||||||
|
derivative work of the Library even though the source code is not.
|
||||||
|
Whether this is true is especially significant if the work can be
|
||||||
|
linked without the Library, or if the work is itself a library. The
|
||||||
|
threshold for this to be true is not precisely defined by law.
|
||||||
|
|
||||||
|
If such an object file uses only numerical parameters, data
|
||||||
|
structure layouts and accessors, and small macros and small inline
|
||||||
|
functions (ten lines or less in length), then the use of the object
|
||||||
|
file is unrestricted, regardless of whether it is legally a derivative
|
||||||
|
work. (Executables containing this object code plus portions of the
|
||||||
|
Library will still fall under Section 6.)
|
||||||
|
|
||||||
|
Otherwise, if the work is a derivative of the Library, you may
|
||||||
|
distribute the object code for the work under the terms of Section 6.
|
||||||
|
Any executables containing that work also fall under Section 6,
|
||||||
|
whether or not they are linked directly with the Library itself.
|
||||||
|
|
||||||
|
6. As an exception to the Sections above, you may also combine or
|
||||||
|
link a "work that uses the Library" with the Library to produce a
|
||||||
|
work containing portions of the Library, and distribute that work
|
||||||
|
under terms of your choice, provided that the terms permit
|
||||||
|
modification of the work for the customer's own use and reverse
|
||||||
|
engineering for debugging such modifications.
|
||||||
|
|
||||||
|
You must give prominent notice with each copy of the work that the
|
||||||
|
Library is used in it and that the Library and its use are covered by
|
||||||
|
this License. You must supply a copy of this License. If the work
|
||||||
|
during execution displays copyright notices, you must include the
|
||||||
|
copyright notice for the Library among them, as well as a reference
|
||||||
|
directing the user to the copy of this License. Also, you must do one
|
||||||
|
of these things:
|
||||||
|
|
||||||
|
a) Accompany the work with the complete corresponding
|
||||||
|
machine-readable source code for the Library including whatever
|
||||||
|
changes were used in the work (which must be distributed under
|
||||||
|
Sections 1 and 2 above); and, if the work is an executable linked
|
||||||
|
with the Library, with the complete machine-readable "work that
|
||||||
|
uses the Library", as object code and/or source code, so that the
|
||||||
|
user can modify the Library and then relink to produce a modified
|
||||||
|
executable containing the modified Library. (It is understood
|
||||||
|
that the user who changes the contents of definitions files in the
|
||||||
|
Library will not necessarily be able to recompile the application
|
||||||
|
to use the modified definitions.)
|
||||||
|
|
||||||
|
b) Use a suitable shared library mechanism for linking with the
|
||||||
|
Library. A suitable mechanism is one that (1) uses at run time a
|
||||||
|
copy of the library already present on the user's computer system,
|
||||||
|
rather than copying library functions into the executable, and (2)
|
||||||
|
will operate properly with a modified version of the library, if
|
||||||
|
the user installs one, as long as the modified version is
|
||||||
|
interface-compatible with the version that the work was made with.
|
||||||
|
|
||||||
|
c) Accompany the work with a written offer, valid for at
|
||||||
|
least three years, to give the same user the materials
|
||||||
|
specified in Subsection 6a, above, for a charge no more
|
||||||
|
than the cost of performing this distribution.
|
||||||
|
|
||||||
|
d) If distribution of the work is made by offering access to copy
|
||||||
|
from a designated place, offer equivalent access to copy the above
|
||||||
|
specified materials from the same place.
|
||||||
|
|
||||||
|
e) Verify that the user has already received a copy of these
|
||||||
|
materials or that you have already sent this user a copy.
|
||||||
|
|
||||||
|
For an executable, the required form of the "work that uses the
|
||||||
|
Library" must include any data and utility programs needed for
|
||||||
|
reproducing the executable from it. However, as a special exception,
|
||||||
|
the materials to be distributed need not include anything that is
|
||||||
|
normally distributed (in either source or binary form) with the major
|
||||||
|
components (compiler, kernel, and so on) of the operating system on
|
||||||
|
which the executable runs, unless that component itself accompanies
|
||||||
|
the executable.
|
||||||
|
|
||||||
|
It may happen that this requirement contradicts the license
|
||||||
|
restrictions of other proprietary libraries that do not normally
|
||||||
|
accompany the operating system. Such a contradiction means you cannot
|
||||||
|
use both them and the Library together in an executable that you
|
||||||
|
distribute.
|
||||||
|
|
||||||
|
7. You may place library facilities that are a work based on the
|
||||||
|
Library side-by-side in a single library together with other library
|
||||||
|
facilities not covered by this License, and distribute such a combined
|
||||||
|
library, provided that the separate distribution of the work based on
|
||||||
|
the Library and of the other library facilities is otherwise
|
||||||
|
permitted, and provided that you do these two things:
|
||||||
|
|
||||||
|
a) Accompany the combined library with a copy of the same work
|
||||||
|
based on the Library, uncombined with any other library
|
||||||
|
facilities. This must be distributed under the terms of the
|
||||||
|
Sections above.
|
||||||
|
|
||||||
|
b) Give prominent notice with the combined library of the fact
|
||||||
|
that part of it is a work based on the Library, and explaining
|
||||||
|
where to find the accompanying uncombined form of the same work.
|
||||||
|
|
||||||
|
8. You may not copy, modify, sublicense, link with, or distribute
|
||||||
|
the Library except as expressly provided under this License. Any
|
||||||
|
attempt otherwise to copy, modify, sublicense, link with, or
|
||||||
|
distribute the Library is void, and will automatically terminate your
|
||||||
|
rights under this License. However, parties who have received copies,
|
||||||
|
or rights, from you under this License will not have their licenses
|
||||||
|
terminated so long as such parties remain in full compliance.
|
||||||
|
|
||||||
|
9. You are not required to accept this License, since you have not
|
||||||
|
signed it. However, nothing else grants you permission to modify or
|
||||||
|
distribute the Library or its derivative works. These actions are
|
||||||
|
prohibited by law if you do not accept this License. Therefore, by
|
||||||
|
modifying or distributing the Library (or any work based on the
|
||||||
|
Library), you indicate your acceptance of this License to do so, and
|
||||||
|
all its terms and conditions for copying, distributing or modifying
|
||||||
|
the Library or works based on it.
|
||||||
|
|
||||||
|
10. Each time you redistribute the Library (or any work based on the
|
||||||
|
Library), the recipient automatically receives a license from the
|
||||||
|
original licensor to copy, distribute, link with or modify the Library
|
||||||
|
subject to these terms and conditions. You may not impose any further
|
||||||
|
restrictions on the recipients' exercise of the rights granted herein.
|
||||||
|
You are not responsible for enforcing compliance by third parties with
|
||||||
|
this License.
|
||||||
|
|
||||||
|
11. If, as a consequence of a court judgment or allegation of patent
|
||||||
|
infringement or for any other reason (not limited to patent issues),
|
||||||
|
conditions are imposed on you (whether by court order, agreement or
|
||||||
|
otherwise) that contradict the conditions of this License, they do not
|
||||||
|
excuse you from the conditions of this License. If you cannot
|
||||||
|
distribute so as to satisfy simultaneously your obligations under this
|
||||||
|
License and any other pertinent obligations, then as a consequence you
|
||||||
|
may not distribute the Library at all. For example, if a patent
|
||||||
|
license would not permit royalty-free redistribution of the Library by
|
||||||
|
all those who receive copies directly or indirectly through you, then
|
||||||
|
the only way you could satisfy both it and this License would be to
|
||||||
|
refrain entirely from distribution of the Library.
|
||||||
|
|
||||||
|
If any portion of this section is held invalid or unenforceable under any
|
||||||
|
particular circumstance, the balance of the section is intended to apply,
|
||||||
|
and the section as a whole is intended to apply in other circumstances.
|
||||||
|
|
||||||
|
It is not the purpose of this section to induce you to infringe any
|
||||||
|
patents or other property right claims or to contest validity of any
|
||||||
|
such claims; this section has the sole purpose of protecting the
|
||||||
|
integrity of the free software distribution system which is
|
||||||
|
implemented by public license practices. Many people have made
|
||||||
|
generous contributions to the wide range of software distributed
|
||||||
|
through that system in reliance on consistent application of that
|
||||||
|
system; it is up to the author/donor to decide if he or she is willing
|
||||||
|
to distribute software through any other system and a licensee cannot
|
||||||
|
impose that choice.
|
||||||
|
|
||||||
|
This section is intended to make thoroughly clear what is believed to
|
||||||
|
be a consequence of the rest of this License.
|
||||||
|
|
||||||
|
12. If the distribution and/or use of the Library is restricted in
|
||||||
|
certain countries either by patents or by copyrighted interfaces, the
|
||||||
|
original copyright holder who places the Library under this License may add
|
||||||
|
an explicit geographical distribution limitation excluding those countries,
|
||||||
|
so that distribution is permitted only in or among countries not thus
|
||||||
|
excluded. In such case, this License incorporates the limitation as if
|
||||||
|
written in the body of this License.
|
||||||
|
|
||||||
|
13. The Free Software Foundation may publish revised and/or new
|
||||||
|
versions of the Lesser General Public License from time to time.
|
||||||
|
Such new versions will be similar in spirit to the present version,
|
||||||
|
but may differ in detail to address new problems or concerns.
|
||||||
|
|
||||||
|
Each version is given a distinguishing version number. If the Library
|
||||||
|
specifies a version number of this License which applies to it and
|
||||||
|
"any later version", you have the option of following the terms and
|
||||||
|
conditions either of that version or of any later version published by
|
||||||
|
the Free Software Foundation. If the Library does not specify a
|
||||||
|
license version number, you may choose any version ever published by
|
||||||
|
the Free Software Foundation.
|
||||||
|
|
||||||
|
14. If you wish to incorporate parts of the Library into other free
|
||||||
|
programs whose distribution conditions are incompatible with these,
|
||||||
|
write to the author to ask for permission. For software which is
|
||||||
|
copyrighted by the Free Software Foundation, write to the Free
|
||||||
|
Software Foundation; we sometimes make exceptions for this. Our
|
||||||
|
decision will be guided by the two goals of preserving the free status
|
||||||
|
of all derivatives of our free software and of promoting the sharing
|
||||||
|
and reuse of software generally.
|
||||||
|
|
||||||
|
NO WARRANTY
|
||||||
|
|
||||||
|
15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO
|
||||||
|
WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW.
|
||||||
|
EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR
|
||||||
|
OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY
|
||||||
|
KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE
|
||||||
|
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||||
|
PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE
|
||||||
|
LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME
|
||||||
|
THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
|
||||||
|
|
||||||
|
16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN
|
||||||
|
WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY
|
||||||
|
AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU
|
||||||
|
FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR
|
||||||
|
CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE
|
||||||
|
LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING
|
||||||
|
RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A
|
||||||
|
FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF
|
||||||
|
SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
|
||||||
|
DAMAGES.
|
||||||
|
|
||||||
|
END OF TERMS AND CONDITIONS
|
||||||
|
|
||||||
|
How to Apply These Terms to Your New Libraries
|
||||||
|
|
||||||
|
If you develop a new library, and you want it to be of the greatest
|
||||||
|
possible use to the public, we recommend making it free software that
|
||||||
|
everyone can redistribute and change. You can do so by permitting
|
||||||
|
redistribution under these terms (or, alternatively, under the terms of the
|
||||||
|
ordinary General Public License).
|
||||||
|
|
||||||
|
To apply these terms, attach the following notices to the library. It is
|
||||||
|
safest to attach them to the start of each source file to most effectively
|
||||||
|
convey the exclusion of warranty; and each file should have at least the
|
||||||
|
"copyright" line and a pointer to where the full notice is found.
|
||||||
|
|
||||||
|
<one line to give the library's name and a brief idea of what it does.>
|
||||||
|
Copyright (C) <year> <name of author>
|
||||||
|
|
||||||
|
This library is free software; you can redistribute it and/or
|
||||||
|
modify it under the terms of the GNU Lesser General Public
|
||||||
|
License as published by the Free Software Foundation; either
|
||||||
|
version 2.1 of the License, or (at your option) any later version.
|
||||||
|
|
||||||
|
This library is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
Lesser General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU Lesser General Public
|
||||||
|
License along with this library; if not, write to the Free Software
|
||||||
|
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||||
|
|
||||||
|
Also add information on how to contact you by electronic and paper mail.
|
||||||
|
|
||||||
|
You should also get your employer (if you work as a programmer) or your
|
||||||
|
school, if any, to sign a "copyright disclaimer" for the library, if
|
||||||
|
necessary. Here is a sample; alter the names:
|
||||||
|
|
||||||
|
Yoyodyne, Inc., hereby disclaims all copyright interest in the
|
||||||
|
library `Frob' (a library for tweaking knobs) written by James Random Hacker.
|
||||||
|
|
||||||
|
<signature of Ty Coon>, 1 April 1990
|
||||||
|
Ty Coon, President of Vice
|
||||||
|
|
||||||
|
That's all there is to it!
|
|
@ -0,0 +1,3 @@
|
||||||
|
name = Epic
|
||||||
|
author = Nathan Salapat
|
||||||
|
description = Based off of MTG with a bunch of custom mods.
|
After Width: | Height: | Size: 17 KiB |
|
@ -0,0 +1,2 @@
|
||||||
|
dofile(minetest.get_modpath('arctic_life')..'/penguin.lua')
|
||||||
|
dofile(minetest.get_modpath('arctic_life')..'/walrus.lua')
|
|
@ -0,0 +1,21 @@
|
||||||
|
Graphics by Nathan(CC-BY-SA 4.0)
|
||||||
|
mobs_penguin
|
||||||
|
mobs_walrus1
|
||||||
|
mobs_walrus2
|
||||||
|
|
||||||
|
Graphics by DuCake (CC-BY-SA 4.0)
|
||||||
|
mobs_penguin_tux
|
||||||
|
|
||||||
|
Sound:
|
||||||
|
Penguin_chirrup.ogg
|
||||||
|
Tai "DuCake" Kedzierski CC-BY-SA 4.0
|
||||||
|
|
||||||
|
Walrus sounds
|
||||||
|
AlexTriceratops123 CCA
|
||||||
|
|
||||||
|
Code is licensed MIT,
|
||||||
|
Copyright 2020 Nathan Salapat
|
||||||
|
|
||||||
|
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
|
||||||
|
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
|
@ -0,0 +1,5 @@
|
||||||
|
name = arctic_life
|
||||||
|
title = Artic Life
|
||||||
|
author = Nathan Salapat
|
||||||
|
description = Simple mod that adds penguins and walrus to snowy biomes.
|
||||||
|
depends = default, mobs
|
|
@ -0,0 +1,58 @@
|
||||||
|
mobs:register_mob("arctic_life:penguin", {
|
||||||
|
type = "animal",
|
||||||
|
passive = false,
|
||||||
|
attack_type = "dogfight",
|
||||||
|
group_attack = true,
|
||||||
|
reach = 1,
|
||||||
|
damage = 1,
|
||||||
|
hp_min = 5,
|
||||||
|
hp_max = 15,
|
||||||
|
armor = 200,
|
||||||
|
fly_in = "default:water_source",
|
||||||
|
collisionbox = {-0.25, -0.4, -0.25, 0.25, 0.3, 0.25},
|
||||||
|
visual = "mesh",
|
||||||
|
mesh = "arctic_life_penguin.b3d",
|
||||||
|
drawtype = "front",
|
||||||
|
textures = {
|
||||||
|
{"arctic_life_penguin.png"},
|
||||||
|
{"arctic_life_penguin_tux.png"},
|
||||||
|
},
|
||||||
|
blood_texture = "mobs_blood.png",
|
||||||
|
visual_size = {x=8,y=8},
|
||||||
|
makes_footstep_sound = true,
|
||||||
|
sounds = {
|
||||||
|
random = "penguin_chirrup",
|
||||||
|
},
|
||||||
|
-- speed and jump
|
||||||
|
walk_velocity = 1,
|
||||||
|
run_velocity = 2,
|
||||||
|
jump = true,
|
||||||
|
jump_height = 1,
|
||||||
|
stepheight = 1.1,
|
||||||
|
floats = 0,
|
||||||
|
-- drops raw meat when dead
|
||||||
|
drops = {
|
||||||
|
{name = "mobs:meat_raw", chance = 1, min = 1, max = 4},
|
||||||
|
{name = 'bonemeal:bone', chance = 2, min = 1, max = 2},
|
||||||
|
},
|
||||||
|
-- damaged by
|
||||||
|
water_damage = 0,
|
||||||
|
lava_damage = 5,
|
||||||
|
light_damage = 0,
|
||||||
|
-- model animation
|
||||||
|
animation = {
|
||||||
|
speed_normal = 15, speed_run = 15,
|
||||||
|
stand_start = 0, stand_end = 60, -- head down/up
|
||||||
|
walk_start = 150, walk_end = 170, -- walk
|
||||||
|
run_start = 150, run_end = 170, -- walk
|
||||||
|
punch_start = 70, punch_end = 140, -- attack
|
||||||
|
fly_start = 171, fly_end = 201, -- swimming
|
||||||
|
},
|
||||||
|
follow = "fishing:fish_raw", view_range = 7,
|
||||||
|
replace_rate = 50,
|
||||||
|
replace_what = {"group:flora"},
|
||||||
|
replace_with = "air",
|
||||||
|
})
|
||||||
|
|
||||||
|
mobs:register_spawn("arctic_life:penguin", {"default:dirt_with_snow", "default:snowblock"}, 20, 0, 20000, 1, 600)
|
||||||
|
mobs:register_egg("arctic_life:penguin", "Penguin", "default_grass.png", 1)
|
After Width: | Height: | Size: 18 KiB |
After Width: | Height: | Size: 18 KiB |
After Width: | Height: | Size: 75 KiB |
After Width: | Height: | Size: 48 KiB |
|
@ -0,0 +1,55 @@
|
||||||
|
mobs:register_mob("arctic_life:walrus", {
|
||||||
|
type = "animal",
|
||||||
|
passive = false,
|
||||||
|
attack_type = "dogfight",
|
||||||
|
reach = 1,
|
||||||
|
damage = 5,
|
||||||
|
hp_min = 15,
|
||||||
|
hp_max = 45,
|
||||||
|
armor = 200,
|
||||||
|
collisionbox = {-0.35, -0.5, -0.35, 0.35, 0.4, 0.35},
|
||||||
|
visual = "mesh",
|
||||||
|
mesh = "arctic_life_walrus.b3d",
|
||||||
|
drawtype = "front",
|
||||||
|
textures = {
|
||||||
|
{"arctic_life_walrus1.png"},
|
||||||
|
{"arctic_life_walrus2.png"},
|
||||||
|
},
|
||||||
|
blood_texture = "mobs_blood.png",
|
||||||
|
visual_size = {x=10,y=10},
|
||||||
|
makes_footstep_sound = false,
|
||||||
|
sounds = {
|
||||||
|
random = "walrus_random.ogg",
|
||||||
|
war_cry = 'walrus_war_cry.ogg',
|
||||||
|
attack = 'walrus_attack.ogg'
|
||||||
|
},
|
||||||
|
-- speed and jump
|
||||||
|
walk_velocity = 1,
|
||||||
|
run_velocity = 2,
|
||||||
|
jump = true,
|
||||||
|
jump_height = 1,
|
||||||
|
stepheight = 1.1,
|
||||||
|
floats = 1,
|
||||||
|
-- drops raw meat when dead
|
||||||
|
drops = {
|
||||||
|
{name = "mobs:meat_raw", chance = 1, min = 2, max = 5},
|
||||||
|
{name = 'bonemeal:bone', chance = 2, min = 1, max = 3},
|
||||||
|
},
|
||||||
|
-- damaged by
|
||||||
|
water_damage = 1,
|
||||||
|
lava_damage = 5,
|
||||||
|
light_damage = 0,
|
||||||
|
-- model animation
|
||||||
|
animation = {
|
||||||
|
speed_normal = 15, speed_run = 15,
|
||||||
|
stand_start = 0, stand_end = 50, -- head down/up
|
||||||
|
walk_start = 55, walk_end = 95, -- walk
|
||||||
|
run_start = 55, run_end = 95, -- walk
|
||||||
|
punch_start = 100, punch_end = 145, -- attack
|
||||||
|
},
|
||||||
|
follow = {"fishing:fish_raw", "mobs_fish:clownfish", "fishing:pike"},
|
||||||
|
view_range = 7,
|
||||||
|
})
|
||||||
|
|
||||||
|
mobs:register_spawn("arctic_life:walrus", {"default:dirt_with_snow", "default:snowblock"}, 20, 0, 20000, 1, 600)
|
||||||
|
mobs:register_egg("arctic_life:walrus", "Walrus", "default_grass.png", 1)
|
|
@ -0,0 +1,502 @@
|
||||||
|
GNU LESSER GENERAL PUBLIC LICENSE
|
||||||
|
Version 2.1, February 1999
|
||||||
|
|
||||||
|
Copyright (C) 1991, 1999 Free Software Foundation, Inc.
|
||||||
|
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||||
|
Everyone is permitted to copy and distribute verbatim copies
|
||||||
|
of this license document, but changing it is not allowed.
|
||||||
|
|
||||||
|
[This is the first released version of the Lesser GPL. It also counts
|
||||||
|
as the successor of the GNU Library Public License, version 2, hence
|
||||||
|
the version number 2.1.]
|
||||||
|
|
||||||
|
Preamble
|
||||||
|
|
||||||
|
The licenses for most software are designed to take away your
|
||||||
|
freedom to share and change it. By contrast, the GNU General Public
|
||||||
|
Licenses are intended to guarantee your freedom to share and change
|
||||||
|
free software--to make sure the software is free for all its users.
|
||||||
|
|
||||||
|
This license, the Lesser General Public License, applies to some
|
||||||
|
specially designated software packages--typically libraries--of the
|
||||||
|
Free Software Foundation and other authors who decide to use it. You
|
||||||
|
can use it too, but we suggest you first think carefully about whether
|
||||||
|
this license or the ordinary General Public License is the better
|
||||||
|
strategy to use in any particular case, based on the explanations below.
|
||||||
|
|
||||||
|
When we speak of free software, we are referring to freedom of use,
|
||||||
|
not price. Our General Public Licenses are designed to make sure that
|
||||||
|
you have the freedom to distribute copies of free software (and charge
|
||||||
|
for this service if you wish); that you receive source code or can get
|
||||||
|
it if you want it; that you can change the software and use pieces of
|
||||||
|
it in new free programs; and that you are informed that you can do
|
||||||
|
these things.
|
||||||
|
|
||||||
|
To protect your rights, we need to make restrictions that forbid
|
||||||
|
distributors to deny you these rights or to ask you to surrender these
|
||||||
|
rights. These restrictions translate to certain responsibilities for
|
||||||
|
you if you distribute copies of the library or if you modify it.
|
||||||
|
|
||||||
|
For example, if you distribute copies of the library, whether gratis
|
||||||
|
or for a fee, you must give the recipients all the rights that we gave
|
||||||
|
you. You must make sure that they, too, receive or can get the source
|
||||||
|
code. If you link other code with the library, you must provide
|
||||||
|
complete object files to the recipients, so that they can relink them
|
||||||
|
with the library after making changes to the library and recompiling
|
||||||
|
it. And you must show them these terms so they know their rights.
|
||||||
|
|
||||||
|
We protect your rights with a two-step method: (1) we copyright the
|
||||||
|
library, and (2) we offer you this license, which gives you legal
|
||||||
|
permission to copy, distribute and/or modify the library.
|
||||||
|
|
||||||
|
To protect each distributor, we want to make it very clear that
|
||||||
|
there is no warranty for the free library. Also, if the library is
|
||||||
|
modified by someone else and passed on, the recipients should know
|
||||||
|
that what they have is not the original version, so that the original
|
||||||
|
author's reputation will not be affected by problems that might be
|
||||||
|
introduced by others.
|
||||||
|
|
||||||
|
Finally, software patents pose a constant threat to the existence of
|
||||||
|
any free program. We wish to make sure that a company cannot
|
||||||
|
effectively restrict the users of a free program by obtaining a
|
||||||
|
restrictive license from a patent holder. Therefore, we insist that
|
||||||
|
any patent license obtained for a version of the library must be
|
||||||
|
consistent with the full freedom of use specified in this license.
|
||||||
|
|
||||||
|
Most GNU software, including some libraries, is covered by the
|
||||||
|
ordinary GNU General Public License. This license, the GNU Lesser
|
||||||
|
General Public License, applies to certain designated libraries, and
|
||||||
|
is quite different from the ordinary General Public License. We use
|
||||||
|
this license for certain libraries in order to permit linking those
|
||||||
|
libraries into non-free programs.
|
||||||
|
|
||||||
|
When a program is linked with a library, whether statically or using
|
||||||
|
a shared library, the combination of the two is legally speaking a
|
||||||
|
combined work, a derivative of the original library. The ordinary
|
||||||
|
General Public License therefore permits such linking only if the
|
||||||
|
entire combination fits its criteria of freedom. The Lesser General
|
||||||
|
Public License permits more lax criteria for linking other code with
|
||||||
|
the library.
|
||||||
|
|
||||||
|
We call this license the "Lesser" General Public License because it
|
||||||
|
does Less to protect the user's freedom than the ordinary General
|
||||||
|
Public License. It also provides other free software developers Less
|
||||||
|
of an advantage over competing non-free programs. These disadvantages
|
||||||
|
are the reason we use the ordinary General Public License for many
|
||||||
|
libraries. However, the Lesser license provides advantages in certain
|
||||||
|
special circumstances.
|
||||||
|
|
||||||
|
For example, on rare occasions, there may be a special need to
|
||||||
|
encourage the widest possible use of a certain library, so that it becomes
|
||||||
|
a de-facto standard. To achieve this, non-free programs must be
|
||||||
|
allowed to use the library. A more frequent case is that a free
|
||||||
|
library does the same job as widely used non-free libraries. In this
|
||||||
|
case, there is little to gain by limiting the free library to free
|
||||||
|
software only, so we use the Lesser General Public License.
|
||||||
|
|
||||||
|
In other cases, permission to use a particular library in non-free
|
||||||
|
programs enables a greater number of people to use a large body of
|
||||||
|
free software. For example, permission to use the GNU C Library in
|
||||||
|
non-free programs enables many more people to use the whole GNU
|
||||||
|
operating system, as well as its variant, the GNU/Linux operating
|
||||||
|
system.
|
||||||
|
|
||||||
|
Although the Lesser General Public License is Less protective of the
|
||||||
|
users' freedom, it does ensure that the user of a program that is
|
||||||
|
linked with the Library has the freedom and the wherewithal to run
|
||||||
|
that program using a modified version of the Library.
|
||||||
|
|
||||||
|
The precise terms and conditions for copying, distribution and
|
||||||
|
modification follow. Pay close attention to the difference between a
|
||||||
|
"work based on the library" and a "work that uses the library". The
|
||||||
|
former contains code derived from the library, whereas the latter must
|
||||||
|
be combined with the library in order to run.
|
||||||
|
|
||||||
|
GNU LESSER GENERAL PUBLIC LICENSE
|
||||||
|
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
|
||||||
|
|
||||||
|
0. This License Agreement applies to any software library or other
|
||||||
|
program which contains a notice placed by the copyright holder or
|
||||||
|
other authorized party saying it may be distributed under the terms of
|
||||||
|
this Lesser General Public License (also called "this License").
|
||||||
|
Each licensee is addressed as "you".
|
||||||
|
|
||||||
|
A "library" means a collection of software functions and/or data
|
||||||
|
prepared so as to be conveniently linked with application programs
|
||||||
|
(which use some of those functions and data) to form executables.
|
||||||
|
|
||||||
|
The "Library", below, refers to any such software library or work
|
||||||
|
which has been distributed under these terms. A "work based on the
|
||||||
|
Library" means either the Library or any derivative work under
|
||||||
|
copyright law: that is to say, a work containing the Library or a
|
||||||
|
portion of it, either verbatim or with modifications and/or translated
|
||||||
|
straightforwardly into another language. (Hereinafter, translation is
|
||||||
|
included without limitation in the term "modification".)
|
||||||
|
|
||||||
|
"Source code" for a work means the preferred form of the work for
|
||||||
|
making modifications to it. For a library, complete source code means
|
||||||
|
all the source code for all modules it contains, plus any associated
|
||||||
|
interface definition files, plus the scripts used to control compilation
|
||||||
|
and installation of the library.
|
||||||
|
|
||||||
|
Activities other than copying, distribution and modification are not
|
||||||
|
covered by this License; they are outside its scope. The act of
|
||||||
|
running a program using the Library is not restricted, and output from
|
||||||
|
such a program is covered only if its contents constitute a work based
|
||||||
|
on the Library (independent of the use of the Library in a tool for
|
||||||
|
writing it). Whether that is true depends on what the Library does
|
||||||
|
and what the program that uses the Library does.
|
||||||
|
|
||||||
|
1. You may copy and distribute verbatim copies of the Library's
|
||||||
|
complete source code as you receive it, in any medium, provided that
|
||||||
|
you conspicuously and appropriately publish on each copy an
|
||||||
|
appropriate copyright notice and disclaimer of warranty; keep intact
|
||||||
|
all the notices that refer to this License and to the absence of any
|
||||||
|
warranty; and distribute a copy of this License along with the
|
||||||
|
Library.
|
||||||
|
|
||||||
|
You may charge a fee for the physical act of transferring a copy,
|
||||||
|
and you may at your option offer warranty protection in exchange for a
|
||||||
|
fee.
|
||||||
|
|
||||||
|
2. You may modify your copy or copies of the Library or any portion
|
||||||
|
of it, thus forming a work based on the Library, and copy and
|
||||||
|
distribute such modifications or work under the terms of Section 1
|
||||||
|
above, provided that you also meet all of these conditions:
|
||||||
|
|
||||||
|
a) The modified work must itself be a software library.
|
||||||
|
|
||||||
|
b) You must cause the files modified to carry prominent notices
|
||||||
|
stating that you changed the files and the date of any change.
|
||||||
|
|
||||||
|
c) You must cause the whole of the work to be licensed at no
|
||||||
|
charge to all third parties under the terms of this License.
|
||||||
|
|
||||||
|
d) If a facility in the modified Library refers to a function or a
|
||||||
|
table of data to be supplied by an application program that uses
|
||||||
|
the facility, other than as an argument passed when the facility
|
||||||
|
is invoked, then you must make a good faith effort to ensure that,
|
||||||
|
in the event an application does not supply such function or
|
||||||
|
table, the facility still operates, and performs whatever part of
|
||||||
|
its purpose remains meaningful.
|
||||||
|
|
||||||
|
(For example, a function in a library to compute square roots has
|
||||||
|
a purpose that is entirely well-defined independent of the
|
||||||
|
application. Therefore, Subsection 2d requires that any
|
||||||
|
application-supplied function or table used by this function must
|
||||||
|
be optional: if the application does not supply it, the square
|
||||||
|
root function must still compute square roots.)
|
||||||
|
|
||||||
|
These requirements apply to the modified work as a whole. If
|
||||||
|
identifiable sections of that work are not derived from the Library,
|
||||||
|
and can be reasonably considered independent and separate works in
|
||||||
|
themselves, then this License, and its terms, do not apply to those
|
||||||
|
sections when you distribute them as separate works. But when you
|
||||||
|
distribute the same sections as part of a whole which is a work based
|
||||||
|
on the Library, the distribution of the whole must be on the terms of
|
||||||
|
this License, whose permissions for other licensees extend to the
|
||||||
|
entire whole, and thus to each and every part regardless of who wrote
|
||||||
|
it.
|
||||||
|
|
||||||
|
Thus, it is not the intent of this section to claim rights or contest
|
||||||
|
your rights to work written entirely by you; rather, the intent is to
|
||||||
|
exercise the right to control the distribution of derivative or
|
||||||
|
collective works based on the Library.
|
||||||
|
|
||||||
|
In addition, mere aggregation of another work not based on the Library
|
||||||
|
with the Library (or with a work based on the Library) on a volume of
|
||||||
|
a storage or distribution medium does not bring the other work under
|
||||||
|
the scope of this License.
|
||||||
|
|
||||||
|
3. You may opt to apply the terms of the ordinary GNU General Public
|
||||||
|
License instead of this License to a given copy of the Library. To do
|
||||||
|
this, you must alter all the notices that refer to this License, so
|
||||||
|
that they refer to the ordinary GNU General Public License, version 2,
|
||||||
|
instead of to this License. (If a newer version than version 2 of the
|
||||||
|
ordinary GNU General Public License has appeared, then you can specify
|
||||||
|
that version instead if you wish.) Do not make any other change in
|
||||||
|
these notices.
|
||||||
|
|
||||||
|
Once this change is made in a given copy, it is irreversible for
|
||||||
|
that copy, so the ordinary GNU General Public License applies to all
|
||||||
|
subsequent copies and derivative works made from that copy.
|
||||||
|
|
||||||
|
This option is useful when you wish to copy part of the code of
|
||||||
|
the Library into a program that is not a library.
|
||||||
|
|
||||||
|
4. You may copy and distribute the Library (or a portion or
|
||||||
|
derivative of it, under Section 2) in object code or executable form
|
||||||
|
under the terms of Sections 1 and 2 above provided that you accompany
|
||||||
|
it with the complete corresponding machine-readable source code, which
|
||||||
|
must be distributed under the terms of Sections 1 and 2 above on a
|
||||||
|
medium customarily used for software interchange.
|
||||||
|
|
||||||
|
If distribution of object code is made by offering access to copy
|
||||||
|
from a designated place, then offering equivalent access to copy the
|
||||||
|
source code from the same place satisfies the requirement to
|
||||||
|
distribute the source code, even though third parties are not
|
||||||
|
compelled to copy the source along with the object code.
|
||||||
|
|
||||||
|
5. A program that contains no derivative of any portion of the
|
||||||
|
Library, but is designed to work with the Library by being compiled or
|
||||||
|
linked with it, is called a "work that uses the Library". Such a
|
||||||
|
work, in isolation, is not a derivative work of the Library, and
|
||||||
|
therefore falls outside the scope of this License.
|
||||||
|
|
||||||
|
However, linking a "work that uses the Library" with the Library
|
||||||
|
creates an executable that is a derivative of the Library (because it
|
||||||
|
contains portions of the Library), rather than a "work that uses the
|
||||||
|
library". The executable is therefore covered by this License.
|
||||||
|
Section 6 states terms for distribution of such executables.
|
||||||
|
|
||||||
|
When a "work that uses the Library" uses material from a header file
|
||||||
|
that is part of the Library, the object code for the work may be a
|
||||||
|
derivative work of the Library even though the source code is not.
|
||||||
|
Whether this is true is especially significant if the work can be
|
||||||
|
linked without the Library, or if the work is itself a library. The
|
||||||
|
threshold for this to be true is not precisely defined by law.
|
||||||
|
|
||||||
|
If such an object file uses only numerical parameters, data
|
||||||
|
structure layouts and accessors, and small macros and small inline
|
||||||
|
functions (ten lines or less in length), then the use of the object
|
||||||
|
file is unrestricted, regardless of whether it is legally a derivative
|
||||||
|
work. (Executables containing this object code plus portions of the
|
||||||
|
Library will still fall under Section 6.)
|
||||||
|
|
||||||
|
Otherwise, if the work is a derivative of the Library, you may
|
||||||
|
distribute the object code for the work under the terms of Section 6.
|
||||||
|
Any executables containing that work also fall under Section 6,
|
||||||
|
whether or not they are linked directly with the Library itself.
|
||||||
|
|
||||||
|
6. As an exception to the Sections above, you may also combine or
|
||||||
|
link a "work that uses the Library" with the Library to produce a
|
||||||
|
work containing portions of the Library, and distribute that work
|
||||||
|
under terms of your choice, provided that the terms permit
|
||||||
|
modification of the work for the customer's own use and reverse
|
||||||
|
engineering for debugging such modifications.
|
||||||
|
|
||||||
|
You must give prominent notice with each copy of the work that the
|
||||||
|
Library is used in it and that the Library and its use are covered by
|
||||||
|
this License. You must supply a copy of this License. If the work
|
||||||
|
during execution displays copyright notices, you must include the
|
||||||
|
copyright notice for the Library among them, as well as a reference
|
||||||
|
directing the user to the copy of this License. Also, you must do one
|
||||||
|
of these things:
|
||||||
|
|
||||||
|
a) Accompany the work with the complete corresponding
|
||||||
|
machine-readable source code for the Library including whatever
|
||||||
|
changes were used in the work (which must be distributed under
|
||||||
|
Sections 1 and 2 above); and, if the work is an executable linked
|
||||||
|
with the Library, with the complete machine-readable "work that
|
||||||
|
uses the Library", as object code and/or source code, so that the
|
||||||
|
user can modify the Library and then relink to produce a modified
|
||||||
|
executable containing the modified Library. (It is understood
|
||||||
|
that the user who changes the contents of definitions files in the
|
||||||
|
Library will not necessarily be able to recompile the application
|
||||||
|
to use the modified definitions.)
|
||||||
|
|
||||||
|
b) Use a suitable shared library mechanism for linking with the
|
||||||
|
Library. A suitable mechanism is one that (1) uses at run time a
|
||||||
|
copy of the library already present on the user's computer system,
|
||||||
|
rather than copying library functions into the executable, and (2)
|
||||||
|
will operate properly with a modified version of the library, if
|
||||||
|
the user installs one, as long as the modified version is
|
||||||
|
interface-compatible with the version that the work was made with.
|
||||||
|
|
||||||
|
c) Accompany the work with a written offer, valid for at
|
||||||
|
least three years, to give the same user the materials
|
||||||
|
specified in Subsection 6a, above, for a charge no more
|
||||||
|
than the cost of performing this distribution.
|
||||||
|
|
||||||
|
d) If distribution of the work is made by offering access to copy
|
||||||
|
from a designated place, offer equivalent access to copy the above
|
||||||
|
specified materials from the same place.
|
||||||
|
|
||||||
|
e) Verify that the user has already received a copy of these
|
||||||
|
materials or that you have already sent this user a copy.
|
||||||
|
|
||||||
|
For an executable, the required form of the "work that uses the
|
||||||
|
Library" must include any data and utility programs needed for
|
||||||
|
reproducing the executable from it. However, as a special exception,
|
||||||
|
the materials to be distributed need not include anything that is
|
||||||
|
normally distributed (in either source or binary form) with the major
|
||||||
|
components (compiler, kernel, and so on) of the operating system on
|
||||||
|
which the executable runs, unless that component itself accompanies
|
||||||
|
the executable.
|
||||||
|
|
||||||
|
It may happen that this requirement contradicts the license
|
||||||
|
restrictions of other proprietary libraries that do not normally
|
||||||
|
accompany the operating system. Such a contradiction means you cannot
|
||||||
|
use both them and the Library together in an executable that you
|
||||||
|
distribute.
|
||||||
|
|
||||||
|
7. You may place library facilities that are a work based on the
|
||||||
|
Library side-by-side in a single library together with other library
|
||||||
|
facilities not covered by this License, and distribute such a combined
|
||||||
|
library, provided that the separate distribution of the work based on
|
||||||
|
the Library and of the other library facilities is otherwise
|
||||||
|
permitted, and provided that you do these two things:
|
||||||
|
|
||||||
|
a) Accompany the combined library with a copy of the same work
|
||||||
|
based on the Library, uncombined with any other library
|
||||||
|
facilities. This must be distributed under the terms of the
|
||||||
|
Sections above.
|
||||||
|
|
||||||
|
b) Give prominent notice with the combined library of the fact
|
||||||
|
that part of it is a work based on the Library, and explaining
|
||||||
|
where to find the accompanying uncombined form of the same work.
|
||||||
|
|
||||||
|
8. You may not copy, modify, sublicense, link with, or distribute
|
||||||
|
the Library except as expressly provided under this License. Any
|
||||||
|
attempt otherwise to copy, modify, sublicense, link with, or
|
||||||
|
distribute the Library is void, and will automatically terminate your
|
||||||
|
rights under this License. However, parties who have received copies,
|
||||||
|
or rights, from you under this License will not have their licenses
|
||||||
|
terminated so long as such parties remain in full compliance.
|
||||||
|
|
||||||
|
9. You are not required to accept this License, since you have not
|
||||||
|
signed it. However, nothing else grants you permission to modify or
|
||||||
|
distribute the Library or its derivative works. These actions are
|
||||||
|
prohibited by law if you do not accept this License. Therefore, by
|
||||||
|
modifying or distributing the Library (or any work based on the
|
||||||
|
Library), you indicate your acceptance of this License to do so, and
|
||||||
|
all its terms and conditions for copying, distributing or modifying
|
||||||
|
the Library or works based on it.
|
||||||
|
|
||||||
|
10. Each time you redistribute the Library (or any work based on the
|
||||||
|
Library), the recipient automatically receives a license from the
|
||||||
|
original licensor to copy, distribute, link with or modify the Library
|
||||||
|
subject to these terms and conditions. You may not impose any further
|
||||||
|
restrictions on the recipients' exercise of the rights granted herein.
|
||||||
|
You are not responsible for enforcing compliance by third parties with
|
||||||
|
this License.
|
||||||
|
|
||||||
|
11. If, as a consequence of a court judgment or allegation of patent
|
||||||
|
infringement or for any other reason (not limited to patent issues),
|
||||||
|
conditions are imposed on you (whether by court order, agreement or
|
||||||
|
otherwise) that contradict the conditions of this License, they do not
|
||||||
|
excuse you from the conditions of this License. If you cannot
|
||||||
|
distribute so as to satisfy simultaneously your obligations under this
|
||||||
|
License and any other pertinent obligations, then as a consequence you
|
||||||
|
may not distribute the Library at all. For example, if a patent
|
||||||
|
license would not permit royalty-free redistribution of the Library by
|
||||||
|
all those who receive copies directly or indirectly through you, then
|
||||||
|
the only way you could satisfy both it and this License would be to
|
||||||
|
refrain entirely from distribution of the Library.
|
||||||
|
|
||||||
|
If any portion of this section is held invalid or unenforceable under any
|
||||||
|
particular circumstance, the balance of the section is intended to apply,
|
||||||
|
and the section as a whole is intended to apply in other circumstances.
|
||||||
|
|
||||||
|
It is not the purpose of this section to induce you to infringe any
|
||||||
|
patents or other property right claims or to contest validity of any
|
||||||
|
such claims; this section has the sole purpose of protecting the
|
||||||
|
integrity of the free software distribution system which is
|
||||||
|
implemented by public license practices. Many people have made
|
||||||
|
generous contributions to the wide range of software distributed
|
||||||
|
through that system in reliance on consistent application of that
|
||||||
|
system; it is up to the author/donor to decide if he or she is willing
|
||||||
|
to distribute software through any other system and a licensee cannot
|
||||||
|
impose that choice.
|
||||||
|
|
||||||
|
This section is intended to make thoroughly clear what is believed to
|
||||||
|
be a consequence of the rest of this License.
|
||||||
|
|
||||||
|
12. If the distribution and/or use of the Library is restricted in
|
||||||
|
certain countries either by patents or by copyrighted interfaces, the
|
||||||
|
original copyright holder who places the Library under this License may add
|
||||||
|
an explicit geographical distribution limitation excluding those countries,
|
||||||
|
so that distribution is permitted only in or among countries not thus
|
||||||
|
excluded. In such case, this License incorporates the limitation as if
|
||||||
|
written in the body of this License.
|
||||||
|
|
||||||
|
13. The Free Software Foundation may publish revised and/or new
|
||||||
|
versions of the Lesser General Public License from time to time.
|
||||||
|
Such new versions will be similar in spirit to the present version,
|
||||||
|
but may differ in detail to address new problems or concerns.
|
||||||
|
|
||||||
|
Each version is given a distinguishing version number. If the Library
|
||||||
|
specifies a version number of this License which applies to it and
|
||||||
|
"any later version", you have the option of following the terms and
|
||||||
|
conditions either of that version or of any later version published by
|
||||||
|
the Free Software Foundation. If the Library does not specify a
|
||||||
|
license version number, you may choose any version ever published by
|
||||||
|
the Free Software Foundation.
|
||||||
|
|
||||||
|
14. If you wish to incorporate parts of the Library into other free
|
||||||
|
programs whose distribution conditions are incompatible with these,
|
||||||
|
write to the author to ask for permission. For software which is
|
||||||
|
copyrighted by the Free Software Foundation, write to the Free
|
||||||
|
Software Foundation; we sometimes make exceptions for this. Our
|
||||||
|
decision will be guided by the two goals of preserving the free status
|
||||||
|
of all derivatives of our free software and of promoting the sharing
|
||||||
|
and reuse of software generally.
|
||||||
|
|
||||||
|
NO WARRANTY
|
||||||
|
|
||||||
|
15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO
|
||||||
|
WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW.
|
||||||
|
EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR
|
||||||
|
OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY
|
||||||
|
KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE
|
||||||
|
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||||
|
PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE
|
||||||
|
LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME
|
||||||
|
THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
|
||||||
|
|
||||||
|
16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN
|
||||||
|
WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY
|
||||||
|
AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU
|
||||||
|
FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR
|
||||||
|
CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE
|
||||||
|
LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING
|
||||||
|
RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A
|
||||||
|
FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF
|
||||||
|
SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
|
||||||
|
DAMAGES.
|
||||||
|
|
||||||
|
END OF TERMS AND CONDITIONS
|
||||||
|
|
||||||
|
How to Apply These Terms to Your New Libraries
|
||||||
|
|
||||||
|
If you develop a new library, and you want it to be of the greatest
|
||||||
|
possible use to the public, we recommend making it free software that
|
||||||
|
everyone can redistribute and change. You can do so by permitting
|
||||||
|
redistribution under these terms (or, alternatively, under the terms of the
|
||||||
|
ordinary General Public License).
|
||||||
|
|
||||||
|
To apply these terms, attach the following notices to the library. It is
|
||||||
|
safest to attach them to the start of each source file to most effectively
|
||||||
|
convey the exclusion of warranty; and each file should have at least the
|
||||||
|
"copyright" line and a pointer to where the full notice is found.
|
||||||
|
|
||||||
|
<one line to give the library's name and a brief idea of what it does.>
|
||||||
|
Copyright (C) <year> <name of author>
|
||||||
|
|
||||||
|
This library is free software; you can redistribute it and/or
|
||||||
|
modify it under the terms of the GNU Lesser General Public
|
||||||
|
License as published by the Free Software Foundation; either
|
||||||
|
version 2.1 of the License, or (at your option) any later version.
|
||||||
|
|
||||||
|
This library is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
Lesser General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU Lesser General Public
|
||||||
|
License along with this library; if not, write to the Free Software
|
||||||
|
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||||
|
|
||||||
|
Also add information on how to contact you by electronic and paper mail.
|
||||||
|
|
||||||
|
You should also get your employer (if you work as a programmer) or your
|
||||||
|
school, if any, to sign a "copyright disclaimer" for the library, if
|
||||||
|
necessary. Here is a sample; alter the names:
|
||||||
|
|
||||||
|
Yoyodyne, Inc., hereby disclaims all copyright interest in the
|
||||||
|
library `Frob' (a library for tweaking knobs) written by James Random Hacker.
|
||||||
|
|
||||||
|
<signature of Ty Coon>, 1 April 1990
|
||||||
|
Ty Coon, President of Vice
|
||||||
|
|
||||||
|
That's all there is to it!
|
|
@ -0,0 +1,103 @@
|
||||||
|
Areas mod for Minetest
|
||||||
|
======================
|
||||||
|
|
||||||
|
Dependencies
|
||||||
|
------------
|
||||||
|
|
||||||
|
Minetest 5.0.0+ is recommended, but 0.4.16+ should work as well.
|
||||||
|
|
||||||
|
|
||||||
|
Configuration
|
||||||
|
-------------
|
||||||
|
|
||||||
|
Open the tab `Settings -> All Settings -> Mods -> areas` to get a list of all
|
||||||
|
possible settings.
|
||||||
|
|
||||||
|
For server owners: Check `settingtypes.txt` and modify your `minetest.conf`
|
||||||
|
according to the wanted setting changes.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
Tutorial
|
||||||
|
--------
|
||||||
|
|
||||||
|
1) Specify the corner positions of the area you would like to protect.
|
||||||
|
Use one of the following commands:
|
||||||
|
|
||||||
|
* `/area_pos set` and punch the two corner nodes to set them.
|
||||||
|
* `/area_pos set1/set2` and punch only the first or second corner node to
|
||||||
|
set them one at a time.
|
||||||
|
* `/area_pos1/2` to set one of the positions to your current position.
|
||||||
|
* `/area_pos1/2 X Y Z` to set one of the positions to the specified
|
||||||
|
coordinates.
|
||||||
|
|
||||||
|
2) Protect the selected area by running one of the following commands:
|
||||||
|
|
||||||
|
* `/set_owner <OwnerName> <AreaName>` -- If you have the `areas` privilege.
|
||||||
|
* `/protect <AreaName>` -- If you have the `areas` privilege or the server
|
||||||
|
administrator has enabled area self-protection.
|
||||||
|
|
||||||
|
The area name is used only for informational purposes and has no functional
|
||||||
|
importance.
|
||||||
|
|
||||||
|
For example: `/set_owner SomePlayer Mese city`
|
||||||
|
|
||||||
|
3) You now own an area. You may now add sub-owners to it if you want to (see command `/add_owner`). Before using the `/add_owner` command you have to
|
||||||
|
select the corners of the sub-area as you did in step 1.
|
||||||
|
|
||||||
|
If your markers are still around your original area and you want to grant
|
||||||
|
access to your entire area you will not have to re-set them. Use `/select_area` to place the markers at the corners of an existing area if you've reset your
|
||||||
|
markers and want to grant access to a full area.
|
||||||
|
|
||||||
|
The `/add_owner` command expects three arguments:
|
||||||
|
1. The ID number of the parent area (the area that you want to add a
|
||||||
|
sub-area to).
|
||||||
|
2. The name of the player that will own the sub-area.
|
||||||
|
3. The name of the sub-area. (can contain spaces)
|
||||||
|
|
||||||
|
For example: `/add_owner 123 BobTheBuilder Diamond lighthouse`
|
||||||
|
|
||||||
|
|
||||||
|
Commands
|
||||||
|
--------
|
||||||
|
|
||||||
|
* `/protect <AreaName>` -- Protects an area for yourself. (if
|
||||||
|
self-protection is enabled)
|
||||||
|
|
||||||
|
* `/set_owner <OwnerName> <AreaName>` -- Protects an area for a specified
|
||||||
|
player. (requires the `areas` privilege)
|
||||||
|
|
||||||
|
* `/add_owner <ParentID> <OwnerName> <ChildName>` -- Grants another player
|
||||||
|
control over part (or all) of an area.
|
||||||
|
|
||||||
|
* `/rename_area <ID> <NewName>` -- Renames an existing area.
|
||||||
|
|
||||||
|
* `/list_areas` -- Lists all of the areas that you own, or all areas if you
|
||||||
|
have the `areas` privilege.
|
||||||
|
|
||||||
|
* `/find_areas <Regex>` -- Finds areas using a Lua regular expresion.
|
||||||
|
For example, to find castles:
|
||||||
|
|
||||||
|
/find_areas [Cc]astle
|
||||||
|
|
||||||
|
* `/remove_area <ID>` -- Removes an area that you own. Any sub-areas of that
|
||||||
|
area are made sub-areas of the removed area's parent, if it exists.
|
||||||
|
If the removed area has no parent it's sub-areas will have no parent.
|
||||||
|
|
||||||
|
* `/recursive_remove_areas <ID>` -- Removes an area and all sub-areas of it.
|
||||||
|
|
||||||
|
* `/change_owner <ID> <NewOwner>` -- Change the owner of an area.
|
||||||
|
|
||||||
|
* `/area_info` -- Returns information about area configuration and usage.
|
||||||
|
|
||||||
|
* `/select_area <ID>` -- Sets the area positions to those of an existing
|
||||||
|
area.
|
||||||
|
|
||||||
|
* `/area_pos {set,set1,set2,get}` -- Sets the area positions by punching
|
||||||
|
nodes or shows the current area positions.
|
||||||
|
|
||||||
|
* `/area_pos1 [X,Y,Z|X Y Z]` -- Sets area position one to your position or
|
||||||
|
the one supplied.
|
||||||
|
|
||||||
|
* `/area_pos2 [X,Y,Z|X Y Z]` -- Sets area position two to your position or
|
||||||
|
the one supplied.
|
|
@ -0,0 +1,165 @@
|
||||||
|
local hudHandlers = {}
|
||||||
|
|
||||||
|
|
||||||
|
areas.registered_on_adds = {}
|
||||||
|
areas.registered_on_removes = {}
|
||||||
|
areas.registered_on_moves = {}
|
||||||
|
|
||||||
|
function areas:registerOnAdd(func)
|
||||||
|
table.insert(areas.registered_on_adds, func)
|
||||||
|
end
|
||||||
|
|
||||||
|
function areas:registerOnRemove(func)
|
||||||
|
table.insert(areas.registered_on_removes, func)
|
||||||
|
end
|
||||||
|
|
||||||
|
function areas:registerOnMove(func)
|
||||||
|
table.insert(areas.registered_on_moves, func)
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
--- Adds a function as a HUD handler, it will be able to add items to the Areas HUD element.
|
||||||
|
function areas:registerHudHandler(handler)
|
||||||
|
table.insert(hudHandlers, handler)
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
function areas:getExternalHudEntries(pos)
|
||||||
|
local areas = {}
|
||||||
|
for _, func in pairs(hudHandlers) do
|
||||||
|
func(pos, areas)
|
||||||
|
end
|
||||||
|
return areas
|
||||||
|
end
|
||||||
|
|
||||||
|
--- Returns a list of areas that include the provided position.
|
||||||
|
function areas:getAreasAtPos(pos)
|
||||||
|
local res = {}
|
||||||
|
|
||||||
|
if self.store then
|
||||||
|
local a = self.store:get_areas_for_pos(pos, false, true)
|
||||||
|
for store_id, store_area in pairs(a) do
|
||||||
|
local id = tonumber(store_area.data)
|
||||||
|
res[id] = self.areas[id]
|
||||||
|
end
|
||||||
|
else
|
||||||
|
local px, py, pz = pos.x, pos.y, pos.z
|
||||||
|
for id, area in pairs(self.areas) do
|
||||||
|
local ap1, ap2 = area.pos1, area.pos2
|
||||||
|
if
|
||||||
|
(px >= ap1.x and px <= ap2.x) and
|
||||||
|
(py >= ap1.y and py <= ap2.y) and
|
||||||
|
(pz >= ap1.z and pz <= ap2.z) then
|
||||||
|
res[id] = area
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
return res
|
||||||
|
end
|
||||||
|
|
||||||
|
--- Returns areas that intersect with the passed area.
|
||||||
|
function areas:getAreasIntersectingArea(pos1, pos2)
|
||||||
|
local res = {}
|
||||||
|
if self.store then
|
||||||
|
local a = self.store:get_areas_in_area(pos1, pos2,
|
||||||
|
true, false, true)
|
||||||
|
for store_id, store_area in pairs(a) do
|
||||||
|
local id = tonumber(store_area.data)
|
||||||
|
res[id] = self.areas[id]
|
||||||
|
end
|
||||||
|
else
|
||||||
|
self:sortPos(pos1, pos2)
|
||||||
|
local p1x, p1y, p1z = pos1.x, pos1.y, pos1.z
|
||||||
|
local p2x, p2y, p2z = pos2.x, pos2.y, pos2.z
|
||||||
|
for id, area in pairs(self.areas) do
|
||||||
|
local ap1, ap2 = area.pos1, area.pos2
|
||||||
|
if
|
||||||
|
(ap1.x <= p2x and ap2.x >= p1x) and
|
||||||
|
(ap1.y <= p2y and ap2.y >= p1y) and
|
||||||
|
(ap1.z <= p2z and ap2.z >= p1z) then
|
||||||
|
-- Found an intersecting area.
|
||||||
|
res[id] = area
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
return res
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Checks if the area is unprotected or owned by you
|
||||||
|
function areas:canInteract(pos, name)
|
||||||
|
if minetest.check_player_privs(name, self.adminPrivs) then
|
||||||
|
return true
|
||||||
|
end
|
||||||
|
local owned = false
|
||||||
|
for _, area in pairs(self:getAreasAtPos(pos)) do
|
||||||
|
if area.owner == name or area.open then
|
||||||
|
return true
|
||||||
|
elseif areas.factions_available and area.faction_open then
|
||||||
|
local faction_name = factions.get_player_faction(area.owner)
|
||||||
|
if faction_name ~= nil and faction_name == factions.get_player_faction(name) then
|
||||||
|
return true
|
||||||
|
end
|
||||||
|
end
|
||||||
|
owned = true
|
||||||
|
end
|
||||||
|
return not owned
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Returns a table (list) of all players that own an area
|
||||||
|
function areas:getNodeOwners(pos)
|
||||||
|
local owners = {}
|
||||||
|
for _, area in pairs(self:getAreasAtPos(pos)) do
|
||||||
|
table.insert(owners, area.owner)
|
||||||
|
end
|
||||||
|
return owners
|
||||||
|
end
|
||||||
|
|
||||||
|
--- Checks if the area intersects with an area that the player can't interact in.
|
||||||
|
-- Note that this fails and returns false when the specified area is fully
|
||||||
|
-- owned by the player, but with multiple protection zones, none of which
|
||||||
|
-- cover the entire checked area.
|
||||||
|
-- @param name (optional) Player name. If not specified checks for any intersecting areas.
|
||||||
|
-- @param allow_open Whether open areas should be counted as if they didn't exist.
|
||||||
|
-- @return Boolean indicating whether the player can interact in that area.
|
||||||
|
-- @return Un-owned intersecting area ID, if found.
|
||||||
|
function areas:canInteractInArea(pos1, pos2, name, allow_open)
|
||||||
|
if name and minetest.check_player_privs(name, self.adminPrivs) then
|
||||||
|
return true
|
||||||
|
end
|
||||||
|
self:sortPos(pos1, pos2)
|
||||||
|
|
||||||
|
-- Intersecting non-owned area ID, if found.
|
||||||
|
local blocking_area = nil
|
||||||
|
|
||||||
|
local areas = self:getAreasIntersectingArea(pos1, pos2)
|
||||||
|
for id, area in pairs(areas) do
|
||||||
|
-- First check for a fully enclosing owned area.
|
||||||
|
-- A little optimization: isAreaOwner isn't necessary
|
||||||
|
-- here since we're iterating over all relevant areas.
|
||||||
|
if area.owner == name and
|
||||||
|
self:isSubarea(pos1, pos2, id) then
|
||||||
|
return true
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Then check for intersecting non-owned (blocking) areas.
|
||||||
|
-- We don't bother with this check if we've already found a
|
||||||
|
-- blocking area, as the check is somewhat expensive.
|
||||||
|
-- The area blocks if the area is closed or open areas aren't
|
||||||
|
-- acceptable to the caller, and the area isn't owned.
|
||||||
|
-- Note: We can't return directly here, because there might be
|
||||||
|
-- an exclosing owned area that we haven't gotten to yet.
|
||||||
|
if not blocking_area and
|
||||||
|
(not allow_open or not area.open) and
|
||||||
|
(not name or not self:isAreaOwner(id, name)) then
|
||||||
|
blocking_area = id
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
if blocking_area then
|
||||||
|
return false, blocking_area
|
||||||
|
end
|
||||||
|
|
||||||
|
-- There are no intersecting areas or they are only partially
|
||||||
|
-- intersecting areas and they are all owned by the player.
|
||||||
|
return true
|
||||||
|
end
|
|
@ -0,0 +1,48 @@
|
||||||
|
Areas mod API
|
||||||
|
===
|
||||||
|
|
||||||
|
API list
|
||||||
|
---
|
||||||
|
|
||||||
|
* `areas:registerHudHandler(handler)` - Registers a handler to add items to the Areas HUD. See [HUD](#hud).
|
||||||
|
* `areas:registerOnAdd(func(id, area))`
|
||||||
|
* `areas:registerOnRemove(func(id))`
|
||||||
|
* `areas:registerOnMove(func(id, area, pos1, pos2))`
|
||||||
|
|
||||||
|
|
||||||
|
HUD
|
||||||
|
---
|
||||||
|
|
||||||
|
If you are making a protection mod or a similar mod that adds invisible regions
|
||||||
|
to the world, and you would like then to show up in the areas HUD element, you
|
||||||
|
can register a callback to show your areas.
|
||||||
|
|
||||||
|
HUD handler specification:
|
||||||
|
|
||||||
|
* `handler(pos, list)`
|
||||||
|
* `pos` - The position to check.
|
||||||
|
* `list` - The list of area HUD elements, this should be modified in-place.
|
||||||
|
|
||||||
|
The area list item is a table containing a list of tables with the following fields:
|
||||||
|
|
||||||
|
* `id` - An identifier for the area. This should be a unique string in the format `mod:id`.
|
||||||
|
* `name` - The name of the area.
|
||||||
|
* `owner` - The player name of the region owner, if any.
|
||||||
|
|
||||||
|
All of the fields are optional but at least one of them must be set.
|
||||||
|
|
||||||
|
### Example
|
||||||
|
|
||||||
|
local function areas_hud_handler(pos, areas)
|
||||||
|
local val = find_my_protection(pos)
|
||||||
|
|
||||||
|
if val then
|
||||||
|
table.insert(areas, {
|
||||||
|
id = "mod:"..val.id,
|
||||||
|
name = val.name,
|
||||||
|
owner = val.owner,
|
||||||
|
})
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
areas:registerHudHandler(areas_hud_handler)
|
|
@ -0,0 +1,434 @@
|
||||||
|
|
||||||
|
minetest.register_chatcommand("protect", {
|
||||||
|
params = "<AreaName>",
|
||||||
|
description = "Protect your own area",
|
||||||
|
privs = {[areas.config.self_protection_privilege]=true},
|
||||||
|
func = function(name, param)
|
||||||
|
if param == "" then
|
||||||
|
return false, "Invalid usage, see /help protect."
|
||||||
|
end
|
||||||
|
local player = minetest.get_player_by_name(name)
|
||||||
|
if not player:get_inventory():contains_item('main', 'epic:deed') then
|
||||||
|
minetest.chat_send_player(name, 'You need a land deed.')
|
||||||
|
return
|
||||||
|
end
|
||||||
|
local pos1, pos2 = areas:getPos(name)
|
||||||
|
if not (pos1 and pos2) then
|
||||||
|
return false, "You need to select an area first."
|
||||||
|
end
|
||||||
|
|
||||||
|
minetest.log("action", "/protect invoked, owner="..name..
|
||||||
|
" AreaName="..param..
|
||||||
|
" StartPos="..minetest.pos_to_string(pos1)..
|
||||||
|
" EndPos=" ..minetest.pos_to_string(pos2))
|
||||||
|
|
||||||
|
local canAdd, errMsg = areas:canPlayerAddArea(pos1, pos2, name)
|
||||||
|
if not canAdd then
|
||||||
|
return false, "You can't protect that area: "..errMsg
|
||||||
|
end
|
||||||
|
|
||||||
|
local id = areas:add(name, param, pos1, pos2, nil)
|
||||||
|
areas:save()
|
||||||
|
|
||||||
|
player:get_inventory():remove_item('main', 'epic:deed')
|
||||||
|
return true, "Area protected. ID: "..id
|
||||||
|
end
|
||||||
|
})
|
||||||
|
|
||||||
|
|
||||||
|
minetest.register_chatcommand("set_owner", {
|
||||||
|
params = "<PlayerName> <AreaName>",
|
||||||
|
description = "Protect an area beetween two positions and give"
|
||||||
|
.." a player access to it without setting the parent of the"
|
||||||
|
.." area to any existing area",
|
||||||
|
privs = areas.adminPrivs,
|
||||||
|
func = function(name, param)
|
||||||
|
local ownerName, areaName = param:match('^(%S+)%s(.+)$')
|
||||||
|
|
||||||
|
if not ownerName then
|
||||||
|
return false, "Incorrect usage, see /help set_owner."
|
||||||
|
end
|
||||||
|
|
||||||
|
local pos1, pos2 = areas:getPos(name)
|
||||||
|
if not (pos1 and pos2) then
|
||||||
|
return false, "You need to select an area first."
|
||||||
|
end
|
||||||
|
|
||||||
|
if not areas:player_exists(ownerName) then
|
||||||
|
return false, "The player \""
|
||||||
|
..ownerName.."\" does not exist."
|
||||||
|
end
|
||||||
|
|
||||||
|
minetest.log("action", name.." runs /set_owner. Owner = "..ownerName..
|
||||||
|
" AreaName = "..areaName..
|
||||||
|
" StartPos = "..minetest.pos_to_string(pos1)..
|
||||||
|
" EndPos = " ..minetest.pos_to_string(pos2))
|
||||||
|
|
||||||
|
local id = areas:add(ownerName, areaName, pos1, pos2, nil)
|
||||||
|
areas:save()
|
||||||
|
|
||||||
|
minetest.chat_send_player(ownerName,
|
||||||
|
"You have been granted control over area #"..
|
||||||
|
id..". Type /list_areas to show your areas.")
|
||||||
|
return true, "Area protected. ID: "..id
|
||||||
|
end
|
||||||
|
})
|
||||||
|
|
||||||
|
|
||||||
|
minetest.register_chatcommand("add_owner", {
|
||||||
|
params = "<ParentID> <Player> <AreaName>",
|
||||||
|
description = "Give a player access to a sub-area beetween two"
|
||||||
|
.." positions that have already been protected,"
|
||||||
|
.." Use set_owner if you don't want the parent to be set.",
|
||||||
|
func = function(name, param)
|
||||||
|
local pid, ownerName, areaName
|
||||||
|
= param:match('^(%d+) ([^ ]+) (.+)$')
|
||||||
|
|
||||||
|
if not pid then
|
||||||
|
minetest.chat_send_player(name, "Incorrect usage, see /help add_owner")
|
||||||
|
return
|
||||||
|
end
|
||||||
|
|
||||||
|
local pos1, pos2 = areas:getPos(name)
|
||||||
|
if not (pos1 and pos2) then
|
||||||
|
return false, "You need to select an area first."
|
||||||
|
end
|
||||||
|
|
||||||
|
if not areas:player_exists(ownerName) then
|
||||||
|
return false, "The player \""..ownerName.."\" does not exist."
|
||||||
|
end
|
||||||
|
|
||||||
|
minetest.log("action", name.." runs /add_owner. Owner = "..ownerName..
|
||||||
|
" AreaName = "..areaName.." ParentID = "..pid..
|
||||||
|
" StartPos = "..pos1.x..","..pos1.y..","..pos1.z..
|
||||||
|
" EndPos = " ..pos2.x..","..pos2.y..","..pos2.z)
|
||||||
|
|
||||||
|
-- Check if this new area is inside an area owned by the player
|
||||||
|
pid = tonumber(pid)
|
||||||
|
if (not areas:isAreaOwner(pid, name)) or
|
||||||
|
(not areas:isSubarea(pos1, pos2, pid)) then
|
||||||
|
return false, "You can't protect that area."
|
||||||
|
end
|
||||||
|
|
||||||
|
local id = areas:add(ownerName, areaName, pos1, pos2, pid)
|
||||||
|
areas:save()
|
||||||
|
|
||||||
|
minetest.chat_send_player(ownerName,
|
||||||
|
"You have been granted control over area #"..
|
||||||
|
id..". Type /list_areas to show your areas.")
|
||||||
|
return true, "Area protected. ID: "..id
|
||||||
|
end
|
||||||
|
})
|
||||||
|
|
||||||
|
|
||||||
|
minetest.register_chatcommand("rename_area", {
|
||||||
|
params = "<ID> <newName>",
|
||||||
|
description = "Rename a area that you own",
|
||||||
|
func = function(name, param)
|
||||||
|
local id, newName = param:match("^(%d+)%s(.+)$")
|
||||||
|
if not id then
|
||||||
|
return false, "Invalid usage, see /help rename_area."
|
||||||
|
end
|
||||||
|
|
||||||
|
id = tonumber(id)
|
||||||
|
if not id then
|
||||||
|
return false, "That area doesn't exist."
|
||||||
|
end
|
||||||
|
|
||||||
|
if not areas:isAreaOwner(id, name) then
|
||||||
|
return true, "You don't own that area."
|
||||||
|
end
|
||||||
|
|
||||||
|
areas.areas[id].name = newName
|
||||||
|
areas:save()
|
||||||
|
return true, "Area renamed."
|
||||||
|
end
|
||||||
|
})
|
||||||
|
|
||||||
|
|
||||||
|
minetest.register_chatcommand("find_areas", {
|
||||||
|
params = "<regexp>",
|
||||||
|
description = "Find areas using a Lua regular expression",
|
||||||
|
privs = areas.adminPrivs,
|
||||||
|
func = function(name, param)
|
||||||
|
if param == "" then
|
||||||
|
return false, "A regular expression is required."
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Check expression for validity
|
||||||
|
local function testRegExp()
|
||||||
|
("Test [1]: Player (0,0,0) (0,0,0)"):find(param)
|
||||||
|
end
|
||||||
|
if not pcall(testRegExp) then
|
||||||
|
return false, "Invalid regular expression."
|
||||||
|
end
|
||||||
|
|
||||||
|
local matches = {}
|
||||||
|
for id, area in pairs(areas.areas) do
|
||||||
|
local str = areas:toString(id)
|
||||||
|
if str:find(param) then
|
||||||
|
table.insert(matches, str)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
if #matches > 0 then
|
||||||
|
return true, table.concat(matches, "\n")
|
||||||
|
else
|
||||||
|
return true, "No matches found."
|
||||||
|
end
|
||||||
|
end
|
||||||
|
})
|
||||||
|
|
||||||
|
|
||||||
|
minetest.register_chatcommand("list_areas", {
|
||||||
|
description = "List your areas, or all areas if you are an admin.",
|
||||||
|
func = function(name, param)
|
||||||
|
local admin = minetest.check_player_privs(name, areas.adminPrivs)
|
||||||
|
local areaStrings = {}
|
||||||
|
for id, area in pairs(areas.areas) do
|
||||||
|
if admin or areas:isAreaOwner(id, name) then
|
||||||
|
table.insert(areaStrings, areas:toString(id))
|
||||||
|
end
|
||||||
|
end
|
||||||
|
if #areaStrings == 0 then
|
||||||
|
return true, "No visible areas."
|
||||||
|
end
|
||||||
|
return true, table.concat(areaStrings, "\n")
|
||||||
|
end
|
||||||
|
})
|
||||||
|
|
||||||
|
|
||||||
|
minetest.register_chatcommand("recursive_remove_areas", {
|
||||||
|
params = "<id>",
|
||||||
|
description = "Recursively remove areas using an id",
|
||||||
|
func = function(name, param)
|
||||||
|
local id = tonumber(param)
|
||||||
|
if not id then
|
||||||
|
return false, "Invalid usage, see"
|
||||||
|
.." /help recursive_remove_areas"
|
||||||
|
end
|
||||||
|
|
||||||
|
if not areas:isAreaOwner(id, name) then
|
||||||
|
return false, "Area "..id.." does not exist or is"
|
||||||
|
.." not owned by you."
|
||||||
|
end
|
||||||
|
|
||||||
|
areas:remove(id, true)
|
||||||
|
areas:save()
|
||||||
|
return true, "Removed area "..id.." and it's sub areas."
|
||||||
|
end
|
||||||
|
})
|
||||||
|
|
||||||
|
|
||||||
|
minetest.register_chatcommand("remove_area", {
|
||||||
|
params = "<id>",
|
||||||
|
description = "Remove an area using an id",
|
||||||
|
func = function(name, param)
|
||||||
|
local id = tonumber(param)
|
||||||
|
if not id then
|
||||||
|
return false, "Invalid usage, see /help remove_area"
|
||||||
|
end
|
||||||
|
|
||||||
|
if not areas:isAreaOwner(id, name) then
|
||||||
|
return false, "Area "..id.." does not exist or"
|
||||||
|
.." is not owned by you."
|
||||||
|
end
|
||||||
|
|
||||||
|
areas:remove(id)
|
||||||
|
areas:save()
|
||||||
|
return true, "Removed area "..id
|
||||||
|
end
|
||||||
|
})
|
||||||
|
|
||||||
|
|
||||||
|
minetest.register_chatcommand("change_owner", {
|
||||||
|
params = "<ID> <NewOwner>",
|
||||||
|
description = "Change the owner of an area using it's ID",
|
||||||
|
func = function(name, param)
|
||||||
|
local id, newOwner = param:match("^(%d+)%s(%S+)$")
|
||||||
|
if not id then
|
||||||
|
return false, "Invalid usage, see"
|
||||||
|
.." /help change_owner."
|
||||||
|
end
|
||||||
|
|
||||||
|
if not areas:player_exists(newOwner) then
|
||||||
|
return false, "The player \""..newOwner
|
||||||
|
.."\" does not exist."
|
||||||
|
end
|
||||||
|
|
||||||
|
id = tonumber(id)
|
||||||
|
if not areas:isAreaOwner(id, name) then
|
||||||
|
return false, "Area "..id.." does not exist"
|
||||||
|
.." or is not owned by you."
|
||||||
|
end
|
||||||
|
areas.areas[id].owner = newOwner
|
||||||
|
areas:save()
|
||||||
|
minetest.chat_send_player(newOwner,
|
||||||
|
("%s has given you control over the area %q (ID %d).")
|
||||||
|
:format(name, areas.areas[id].name, id))
|
||||||
|
return true, "Owner changed."
|
||||||
|
end
|
||||||
|
})
|
||||||
|
|
||||||
|
|
||||||
|
minetest.register_chatcommand("area_open", {
|
||||||
|
params = "<ID>",
|
||||||
|
description = "Toggle an area open (anyone can interact) or closed",
|
||||||
|
func = function(name, param)
|
||||||
|
local id = tonumber(param)
|
||||||
|
if not id then
|
||||||
|
return false, "Invalid usage, see /help area_open."
|
||||||
|
end
|
||||||
|
|
||||||
|
if not areas:isAreaOwner(id, name) then
|
||||||
|
return false, "Area "..id.." does not exist"
|
||||||
|
.." or is not owned by you."
|
||||||
|
end
|
||||||
|
local open = not areas.areas[id].open
|
||||||
|
-- Save false as nil to avoid inflating the DB.
|
||||||
|
areas.areas[id].open = open or nil
|
||||||
|
areas:save()
|
||||||
|
return true, ("Area %s."):format(open and "opened" or "closed")
|
||||||
|
end
|
||||||
|
})
|
||||||
|
|
||||||
|
|
||||||
|
if areas.factions_available then
|
||||||
|
minetest.register_chatcommand("area_faction_open", {
|
||||||
|
params = "<ID>",
|
||||||
|
description = "Toggle an area open/closed for members in your faction.",
|
||||||
|
func = function(name, param)
|
||||||
|
local id = tonumber(param)
|
||||||
|
if not id then
|
||||||
|
return false, "Invalid usage, see /help area_faction_open."
|
||||||
|
end
|
||||||
|
|
||||||
|
if not areas:isAreaOwner(id, name) then
|
||||||
|
return false, "Area "..id.." does not exist"
|
||||||
|
.." or is not owned by you."
|
||||||
|
end
|
||||||
|
local open = not areas.areas[id].faction_open
|
||||||
|
-- Save false as nil to avoid inflating the DB.
|
||||||
|
areas.areas[id].faction_open = open or nil
|
||||||
|
areas:save()
|
||||||
|
return true, ("Area %s for faction members."):format(open and "opened" or "closed")
|
||||||
|
end
|
||||||
|
})
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
minetest.register_chatcommand("move_area", {
|
||||||
|
params = "<ID>",
|
||||||
|
description = "Move (or resize) an area to the current positions.",
|
||||||
|
privs = areas.adminPrivs,
|
||||||
|
func = function(name, param)
|
||||||
|
local id = tonumber(param)
|
||||||
|
if not id then
|
||||||
|
return false, "Invalid usage, see /help move_area."
|
||||||
|
end
|
||||||
|
|
||||||
|
local area = areas.areas[id]
|
||||||
|
if not area then
|
||||||
|
return false, "Area does not exist."
|
||||||
|
end
|
||||||
|
|
||||||
|
local pos1, pos2 = areas:getPos(name)
|
||||||
|
if not pos1 then
|
||||||
|
return false, "You need to select an area first."
|
||||||
|
end
|
||||||
|
|
||||||
|
areas:move(id, area, pos1, pos2)
|
||||||
|
areas:save()
|
||||||
|
|
||||||
|
return true, "Area successfully moved."
|
||||||
|
end,
|
||||||
|
})
|
||||||
|
|
||||||
|
|
||||||
|
minetest.register_chatcommand("area_info", {
|
||||||
|
description = "Get information about area configuration and usage.",
|
||||||
|
func = function(name, param)
|
||||||
|
local lines = {}
|
||||||
|
local privs = minetest.get_player_privs(name)
|
||||||
|
|
||||||
|
-- Short (and fast to access) names
|
||||||
|
local cfg = areas.config
|
||||||
|
local self_prot = cfg.self_protection
|
||||||
|
local prot_priv = cfg.self_protection_privilege
|
||||||
|
local limit = cfg.self_protection_max_areas
|
||||||
|
local limit_high = cfg.self_protection_max_areas_high
|
||||||
|
local size_limit = cfg.self_protection_max_size
|
||||||
|
local size_limit_high = cfg.self_protection_max_size_high
|
||||||
|
|
||||||
|
local has_high_limit = privs.areas_high_limit
|
||||||
|
local has_prot_priv = not prot_priv or privs[prot_priv]
|
||||||
|
local can_prot = privs.areas or (self_prot and has_prot_priv)
|
||||||
|
local max_count = can_prot and
|
||||||
|
(has_high_limit and limit_high or limit) or 0
|
||||||
|
local max_size = has_high_limit and
|
||||||
|
size_limit_high or size_limit
|
||||||
|
|
||||||
|
-- Privilege information
|
||||||
|
local self_prot_line = ("Self protection is %sabled"):format(
|
||||||
|
self_prot and "en" or "dis")
|
||||||
|
if self_prot and prot_priv then
|
||||||
|
self_prot_line = self_prot_line..
|
||||||
|
(" %s have the neccessary privilege (%q).")
|
||||||
|
:format(
|
||||||
|
has_prot_priv and "and you" or
|
||||||
|
"but you don't",
|
||||||
|
prot_priv)
|
||||||
|
else
|
||||||
|
self_prot_line = self_prot_line.."."
|
||||||
|
end
|
||||||
|
table.insert(lines, self_prot_line)
|
||||||
|
if privs.admin_areas then
|
||||||
|
table.insert(lines, "You are an area"..
|
||||||
|
" administrator (\"areas\" privilege).")
|
||||||
|
elseif has_high_limit then
|
||||||
|
table.insert(lines,
|
||||||
|
"You have extended area protection"..
|
||||||
|
" limits (\"areas_high_limit\" privilege).")
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Area count
|
||||||
|
local area_num = 0
|
||||||
|
for id, area in pairs(areas.areas) do
|
||||||
|
if area.owner == name then
|
||||||
|
area_num = area_num + 1
|
||||||
|
end
|
||||||
|
end
|
||||||
|
local count_line = ("You have %d area%s"):format(
|
||||||
|
area_num, area_num == 1 and "" or "s")
|
||||||
|
if privs.admin_areas then
|
||||||
|
count_line = count_line..
|
||||||
|
" and have no area protection limits."
|
||||||
|
elseif can_prot then
|
||||||
|
count_line = count_line..(", out of a maximum of %d.")
|
||||||
|
:format(max_count)
|
||||||
|
end
|
||||||
|
table.insert(lines, count_line)
|
||||||
|
|
||||||
|
-- Area size limits
|
||||||
|
local function size_info(str, size)
|
||||||
|
table.insert(lines, ("%s spanning up to %dx%dx%d.")
|
||||||
|
:format(str, size.x, size.y, size.z))
|
||||||
|
end
|
||||||
|
local function priv_limit_info(lpriv, lmax_count, lmax_size)
|
||||||
|
size_info(("Players with the %q privilege"..
|
||||||
|
" can protect up to %d areas"):format(
|
||||||
|
lpriv, lmax_count), lmax_size)
|
||||||
|
end
|
||||||
|
if self_prot then
|
||||||
|
if privs.admin_areas then
|
||||||
|
priv_limit_info(prot_priv,
|
||||||
|
limit, size_limit)
|
||||||
|
priv_limit_info("areas_high_limit",
|
||||||
|
limit_high, size_limit_high)
|
||||||
|
elseif has_prot_priv then
|
||||||
|
size_info("You can protect areas", max_size)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
return true, table.concat(lines, "\n")
|
||||||
|
end,
|
||||||
|
})
|
|
@ -0,0 +1,72 @@
|
||||||
|
-- This is inspired by the landrush mod by Bremaweb
|
||||||
|
|
||||||
|
areas.hud = {}
|
||||||
|
areas.hud.refresh = 0
|
||||||
|
|
||||||
|
minetest.register_globalstep(function(dtime)
|
||||||
|
|
||||||
|
areas.hud.refresh = areas.hud.refresh + dtime
|
||||||
|
if areas.hud.refresh > areas.config["tick"] then
|
||||||
|
areas.hud.refresh = 0
|
||||||
|
else
|
||||||
|
return
|
||||||
|
end
|
||||||
|
|
||||||
|
for _, player in pairs(minetest.get_connected_players()) do
|
||||||
|
local name = player:get_player_name()
|
||||||
|
local pos = vector.round(player:get_pos())
|
||||||
|
pos = vector.apply(pos, function(p)
|
||||||
|
return math.max(math.min(p, 2147483), -2147483)
|
||||||
|
end)
|
||||||
|
local areaStrings = {}
|
||||||
|
|
||||||
|
for id, area in pairs(areas:getAreasAtPos(pos)) do
|
||||||
|
local faction_info = area.faction_open and areas.factions_available and
|
||||||
|
factions.get_player_faction(area.owner)
|
||||||
|
area.faction_open = faction_info
|
||||||
|
table.insert(areaStrings, ("%s [%u] (%s%s%s)")
|
||||||
|
:format(area.name, id, area.owner,
|
||||||
|
area.open and ":open" or "",
|
||||||
|
faction_info and ":"..faction_info or ""))
|
||||||
|
end
|
||||||
|
|
||||||
|
for i, area in pairs(areas:getExternalHudEntries(pos)) do
|
||||||
|
local str = ""
|
||||||
|
if area.name then str = area.name .. " " end
|
||||||
|
if area.id then str = str.."["..area.id.."] " end
|
||||||
|
if area.owner then str = str.."("..area.owner..")" end
|
||||||
|
table.insert(areaStrings, str)
|
||||||
|
end
|
||||||
|
|
||||||
|
local areaString = "Areas:"
|
||||||
|
if #areaStrings > 0 then
|
||||||
|
areaString = areaString.."\n"..
|
||||||
|
table.concat(areaStrings, "\n")
|
||||||
|
end
|
||||||
|
local hud = areas.hud[name]
|
||||||
|
if not hud then
|
||||||
|
hud = {}
|
||||||
|
areas.hud[name] = hud
|
||||||
|
hud.areasId = player:hud_add({
|
||||||
|
hud_elem_type = "text",
|
||||||
|
name = "Areas",
|
||||||
|
number = 0xFFFFFF,
|
||||||
|
position = {x=0, y=1},
|
||||||
|
offset = {x=8, y=-8},
|
||||||
|
text = areaString,
|
||||||
|
scale = {x=200, y=60},
|
||||||
|
alignment = {x=1, y=-1},
|
||||||
|
})
|
||||||
|
hud.oldAreas = areaString
|
||||||
|
return
|
||||||
|
elseif hud.oldAreas ~= areaString then
|
||||||
|
player:hud_change(hud.areasId, "text", areaString)
|
||||||
|
hud.oldAreas = areaString
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end)
|
||||||
|
|
||||||
|
minetest.register_on_leaveplayer(function(player)
|
||||||
|
areas.hud[player:get_player_name()] = nil
|
||||||
|
end)
|
||||||
|
|
|
@ -0,0 +1,41 @@
|
||||||
|
-- Areas mod by ShadowNinja
|
||||||
|
-- Based on node_ownership
|
||||||
|
-- License: LGPLv2+
|
||||||
|
|
||||||
|
areas = {}
|
||||||
|
|
||||||
|
areas.factions_available = minetest.global_exists("factions")
|
||||||
|
|
||||||
|
areas.adminPrivs = {admin_areas=true}
|
||||||
|
areas.startTime = os.clock()
|
||||||
|
|
||||||
|
areas.modpath = minetest.get_modpath("areas")
|
||||||
|
dofile(areas.modpath.."/settings.lua")
|
||||||
|
dofile(areas.modpath.."/api.lua")
|
||||||
|
dofile(areas.modpath.."/internal.lua")
|
||||||
|
dofile(areas.modpath.."/chatcommands.lua")
|
||||||
|
dofile(areas.modpath.."/pos.lua")
|
||||||
|
dofile(areas.modpath.."/interact.lua")
|
||||||
|
dofile(areas.modpath.."/legacy.lua")
|
||||||
|
dofile(areas.modpath.."/hud.lua")
|
||||||
|
|
||||||
|
areas:load()
|
||||||
|
|
||||||
|
minetest.register_privilege("admin_areas", {
|
||||||
|
description = "Can administer areas.",
|
||||||
|
give_to_singleplayer = false
|
||||||
|
})
|
||||||
|
minetest.register_privilege("areas_high_limit", {
|
||||||
|
description = "Can can more, bigger areas."
|
||||||
|
})
|
||||||
|
|
||||||
|
if not minetest.registered_privileges[areas.config.self_protection_privilege] then
|
||||||
|
minetest.register_privilege(areas.config.self_protection_privilege, {
|
||||||
|
description = "Can protect areas.",
|
||||||
|
})
|
||||||
|
end
|
||||||
|
|
||||||
|
if minetest.settings:get_bool("log_mods") then
|
||||||
|
local diffTime = os.clock() - areas.startTime
|
||||||
|
minetest.log("action", "areas loaded in "..diffTime.."s.")
|
||||||
|
end
|
|
@ -0,0 +1,25 @@
|
||||||
|
|
||||||
|
local old_is_protected = minetest.is_protected
|
||||||
|
function minetest.is_protected(pos, name)
|
||||||
|
if not areas:canInteract(pos, name) then
|
||||||
|
return true
|
||||||
|
end
|
||||||
|
return old_is_protected(pos, name)
|
||||||
|
end
|
||||||
|
|
||||||
|
minetest.register_on_protection_violation(function(pos, name)
|
||||||
|
if not areas:canInteract(pos, name) then
|
||||||
|
local player = minetest.get_player_by_name(name)
|
||||||
|
if player then
|
||||||
|
local yaw = player:get_look_horizontal() + math.pi
|
||||||
|
if yaw > 2 * math.pi then
|
||||||
|
yaw = yaw - 2 * math.pi
|
||||||
|
end
|
||||||
|
player:set_look_horizontal(yaw)
|
||||||
|
player:set_look_vertical(-player:get_look_vertical())
|
||||||
|
local owners = areas:getNodeOwners(pos)
|
||||||
|
minetest.chat_send_player(name,("%s is protected by %s."):format(
|
||||||
|
minetest.pos_to_string(pos), table.concat(owners, ", ")))
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end)
|
|
@ -0,0 +1,305 @@
|
||||||
|
|
||||||
|
function areas:player_exists(name)
|
||||||
|
return minetest.get_auth_handler().get_auth(name) ~= nil
|
||||||
|
end
|
||||||
|
|
||||||
|
local safe_file_write = minetest.safe_file_write
|
||||||
|
if safe_file_write == nil then
|
||||||
|
function safe_file_write(path, content)
|
||||||
|
local file, err = io.open(path, "w")
|
||||||
|
if err then
|
||||||
|
return err
|
||||||
|
end
|
||||||
|
file:write(content)
|
||||||
|
file:close()
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Save the areas table to a file
|
||||||
|
function areas:save()
|
||||||
|
local datastr = minetest.serialize(self.areas)
|
||||||
|
if not datastr then
|
||||||
|
minetest.log("error", "[areas] Failed to serialize area data!")
|
||||||
|
return
|
||||||
|
end
|
||||||
|
return safe_file_write(self.config.filename, datastr)
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Load the areas table from the save file
|
||||||
|
function areas:load()
|
||||||
|
local file, err = io.open(self.config.filename, "r")
|
||||||
|
if err then
|
||||||
|
self.areas = self.areas or {}
|
||||||
|
return err
|
||||||
|
end
|
||||||
|
self.areas = minetest.deserialize(file:read("*a"))
|
||||||
|
if type(self.areas) ~= "table" then
|
||||||
|
self.areas = {}
|
||||||
|
end
|
||||||
|
file:close()
|
||||||
|
self:populateStore()
|
||||||
|
end
|
||||||
|
|
||||||
|
--- Checks an AreaStore ID.
|
||||||
|
-- Deletes the AreaStore (falling back to the iterative method)
|
||||||
|
-- and prints an error message if the ID is invalid.
|
||||||
|
-- @return Whether the ID was valid.
|
||||||
|
function areas:checkAreaStoreId(sid)
|
||||||
|
if not sid then
|
||||||
|
minetest.log("error", "AreaStore failed to find an ID for an "
|
||||||
|
.."area! Falling back to iterative area checking.")
|
||||||
|
self.store = nil
|
||||||
|
self.store_ids = nil
|
||||||
|
end
|
||||||
|
return sid and true or false
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Populates the AreaStore after loading, if needed.
|
||||||
|
function areas:populateStore()
|
||||||
|
if not rawget(_G, "AreaStore") then
|
||||||
|
return
|
||||||
|
end
|
||||||
|
local store = AreaStore()
|
||||||
|
local store_ids = {}
|
||||||
|
for id, area in pairs(areas.areas) do
|
||||||
|
local sid = store:insert_area(area.pos1,
|
||||||
|
area.pos2, tostring(id))
|
||||||
|
if not self:checkAreaStoreId(sid) then
|
||||||
|
return
|
||||||
|
end
|
||||||
|
store_ids[id] = sid
|
||||||
|
end
|
||||||
|
self.store = store
|
||||||
|
self.store_ids = store_ids
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Finds the first usable index in a table
|
||||||
|
-- Eg: {[1]=false,[4]=true} -> 2
|
||||||
|
local function findFirstUnusedIndex(t)
|
||||||
|
local i = 0
|
||||||
|
repeat i = i + 1
|
||||||
|
until t[i] == nil
|
||||||
|
return i
|
||||||
|
end
|
||||||
|
|
||||||
|
--- Add a area.
|
||||||
|
-- @return The new area's ID.
|
||||||
|
function areas:add(owner, name, pos1, pos2, parent)
|
||||||
|
local id = findFirstUnusedIndex(self.areas)
|
||||||
|
self.areas[id] = {
|
||||||
|
name = name,
|
||||||
|
pos1 = pos1,
|
||||||
|
pos2 = pos2,
|
||||||
|
owner = owner,
|
||||||
|
parent = parent
|
||||||
|
}
|
||||||
|
|
||||||
|
for i=1, #areas.registered_on_adds do
|
||||||
|
areas.registered_on_adds[i](id, self.areas[id])
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Add to AreaStore
|
||||||
|
if self.store then
|
||||||
|
local sid = self.store:insert_area(pos1, pos2, tostring(id))
|
||||||
|
if self:checkAreaStoreId(sid) then
|
||||||
|
self.store_ids[id] = sid
|
||||||
|
end
|
||||||
|
end
|
||||||
|
return id
|
||||||
|
end
|
||||||
|
|
||||||
|
--- Remove a area, and optionally it's children recursively.
|
||||||
|
-- If a area is deleted non-recursively the children will
|
||||||
|
-- have the removed area's parent as their new parent.
|
||||||
|
function areas:remove(id, recurse)
|
||||||
|
if recurse then
|
||||||
|
-- Recursively find child entries and remove them
|
||||||
|
local cids = self:getChildren(id)
|
||||||
|
for _, cid in pairs(cids) do
|
||||||
|
self:remove(cid, true)
|
||||||
|
end
|
||||||
|
else
|
||||||
|
-- Update parents
|
||||||
|
local parent = self.areas[id].parent
|
||||||
|
local children = self:getChildren(id)
|
||||||
|
for _, cid in pairs(children) do
|
||||||
|
-- The subarea parent will be niled out if the
|
||||||
|
-- removed area does not have a parent
|
||||||
|
self.areas[cid].parent = parent
|
||||||
|
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
for i=1, #areas.registered_on_removes do
|
||||||
|
areas.registered_on_removes[i](id)
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Remove main entry
|
||||||
|
self.areas[id] = nil
|
||||||
|
|
||||||
|
-- Remove from AreaStore
|
||||||
|
if self.store then
|
||||||
|
self.store:remove_area(self.store_ids[id])
|
||||||
|
self.store_ids[id] = nil
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
--- Move an area.
|
||||||
|
function areas:move(id, area, pos1, pos2)
|
||||||
|
area.pos1 = pos1
|
||||||
|
area.pos2 = pos2
|
||||||
|
|
||||||
|
|
||||||
|
for i=1, #areas.registered_on_moves do
|
||||||
|
areas.registered_on_moves[i](id, area, pos1, pos2)
|
||||||
|
end
|
||||||
|
|
||||||
|
if self.store then
|
||||||
|
self.store:remove_area(areas.store_ids[id])
|
||||||
|
local sid = self.store:insert_area(pos1, pos2, tostring(id))
|
||||||
|
if self:checkAreaStoreId(sid) then
|
||||||
|
self.store_ids[id] = sid
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Checks if a area between two points is entirely contained by another area.
|
||||||
|
-- Positions must be sorted.
|
||||||
|
function areas:isSubarea(pos1, pos2, id)
|
||||||
|
local area = self.areas[id]
|
||||||
|
if not area then
|
||||||
|
return false
|
||||||
|
end
|
||||||
|
local ap1, ap2 = area.pos1, area.pos2
|
||||||
|
local ap1x, ap1y, ap1z = ap1.x, ap1.y, ap1.z
|
||||||
|
local ap2x, ap2y, ap2z = ap2.x, ap2.y, ap2.z
|
||||||
|
local p1x, p1y, p1z = pos1.x, pos1.y, pos1.z
|
||||||
|
local p2x, p2y, p2z = pos2.x, pos2.y, pos2.z
|
||||||
|
if
|
||||||
|
(p1x >= ap1x and p1x <= ap2x) and
|
||||||
|
(p2x >= ap1x and p2x <= ap2x) and
|
||||||
|
(p1y >= ap1y and p1y <= ap2y) and
|
||||||
|
(p2y >= ap1y and p2y <= ap2y) and
|
||||||
|
(p1z >= ap1z and p1z <= ap2z) and
|
||||||
|
(p2z >= ap1z and p2z <= ap2z) then
|
||||||
|
return true
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Returns a table (list) of children of an area given it's identifier
|
||||||
|
function areas:getChildren(id)
|
||||||
|
local children = {}
|
||||||
|
for cid, area in pairs(self.areas) do
|
||||||
|
if area.parent and area.parent == id then
|
||||||
|
table.insert(children, cid)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
return children
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Checks if the user has sufficient privileges.
|
||||||
|
-- If the player is not a administrator it also checks
|
||||||
|
-- if the area intersects other areas that they do not own.
|
||||||
|
-- Also checks the size of the area and if the user already
|
||||||
|
-- has more than max_areas.
|
||||||
|
function areas:canPlayerAddArea(pos1, pos2, name)
|
||||||
|
local privs = minetest.get_player_privs(name)
|
||||||
|
if privs.areas then
|
||||||
|
return true
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Check self protection privilege, if it is enabled,
|
||||||
|
-- and if the area is too big.
|
||||||
|
if not self.config.self_protection or
|
||||||
|
not privs[areas.config.self_protection_privilege] then
|
||||||
|
return false, "Self protection is disabled or you do not have"
|
||||||
|
.." the necessary privilege."
|
||||||
|
end
|
||||||
|
|
||||||
|
local max_size = privs.areas_high_limit and
|
||||||
|
self.config.self_protection_max_size_high or
|
||||||
|
self.config.self_protection_max_size
|
||||||
|
if
|
||||||
|
(pos2.x - pos1.x) > max_size.x or
|
||||||
|
(pos2.y - pos1.y) > max_size.y or
|
||||||
|
(pos2.z - pos1.z) > max_size.z then
|
||||||
|
return false, "Area is too big."
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Check number of areas the user has and make sure it not above the max
|
||||||
|
local count = 0
|
||||||
|
for _, area in pairs(self.areas) do
|
||||||
|
if area.owner == name then
|
||||||
|
count = count + 1
|
||||||
|
end
|
||||||
|
end
|
||||||
|
local max_areas = privs.areas_high_limit and
|
||||||
|
self.config.self_protection_max_areas_high or
|
||||||
|
self.config.self_protection_max_areas
|
||||||
|
if count >= max_areas then
|
||||||
|
return false, "You have reached the maximum amount of"
|
||||||
|
.." areas that you are allowed to protect."
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Check intersecting areas
|
||||||
|
local can, id = self:canInteractInArea(pos1, pos2, name)
|
||||||
|
if not can then
|
||||||
|
local area = self.areas[id]
|
||||||
|
return false, ("The area intersects with %s [%u] (%s).")
|
||||||
|
:format(area.name, id, area.owner)
|
||||||
|
end
|
||||||
|
|
||||||
|
return true
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Given a id returns a string in the format:
|
||||||
|
-- "name [id]: owner (x1, y1, z1) (x2, y2, z2) -> children"
|
||||||
|
function areas:toString(id)
|
||||||
|
local area = self.areas[id]
|
||||||
|
local message = ("%s [%d]: %s %s %s"):format(
|
||||||
|
area.name, id, area.owner,
|
||||||
|
minetest.pos_to_string(area.pos1),
|
||||||
|
minetest.pos_to_string(area.pos2))
|
||||||
|
|
||||||
|
local children = areas:getChildren(id)
|
||||||
|
if #children > 0 then
|
||||||
|
message = message.." -> "..table.concat(children, ", ")
|
||||||
|
end
|
||||||
|
return message
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Re-order areas in table by their identifiers
|
||||||
|
function areas:sort()
|
||||||
|
local sa = {}
|
||||||
|
for k, area in pairs(self.areas) do
|
||||||
|
if not area.parent then
|
||||||
|
table.insert(sa, area)
|
||||||
|
local newid = #sa
|
||||||
|
for _, subarea in pairs(self.areas) do
|
||||||
|
if subarea.parent == k then
|
||||||
|
subarea.parent = newid
|
||||||
|
table.insert(sa, subarea)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
self.areas = sa
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Checks if a player owns an area or a parent of it
|
||||||
|
function areas:isAreaOwner(id, name)
|
||||||
|
local cur = self.areas[id]
|
||||||
|
if cur and minetest.check_player_privs(name, self.adminPrivs) then
|
||||||
|
return true
|
||||||
|
end
|
||||||
|
while cur do
|
||||||
|
if cur.owner == name then
|
||||||
|
return true
|
||||||
|
elseif cur.parent then
|
||||||
|
cur = self.areas[cur.parent]
|
||||||
|
else
|
||||||
|
return false
|
||||||
|
end
|
||||||
|
end
|
||||||
|
return false
|
||||||
|
end
|
|
@ -0,0 +1,139 @@
|
||||||
|
-- This file contains functions to convert from
|
||||||
|
-- the old areas format and other compatability code.
|
||||||
|
|
||||||
|
minetest.register_chatcommand("legacy_load_areas", {
|
||||||
|
params = "<version>",
|
||||||
|
description = "Loads, converts, and saves the areas from"
|
||||||
|
.." a legacy save file.",
|
||||||
|
privs = {areas=true, server=true},
|
||||||
|
func = function(name, param)
|
||||||
|
minetest.chat_send_player(name, "Converting areas...")
|
||||||
|
local version = tonumber(param)
|
||||||
|
if version == 0 then
|
||||||
|
local err = areas:node_ownership_load()
|
||||||
|
if err then
|
||||||
|
minetest.chat_send_player(name, "Error loading legacy file: "..err)
|
||||||
|
return
|
||||||
|
end
|
||||||
|
else
|
||||||
|
minetest.chat_send_player(name, "Invalid version number. (0 allowed)")
|
||||||
|
return
|
||||||
|
end
|
||||||
|
minetest.chat_send_player(name, "Legacy file loaded.")
|
||||||
|
|
||||||
|
for k, area in pairs(areas.areas) do
|
||||||
|
-- New position format
|
||||||
|
area.pos1 = {x=area.x1, y=area.y1, z=area.z1}
|
||||||
|
area.pos2 = {x=area.x2, y=area.y2, z=area.z2}
|
||||||
|
|
||||||
|
area.x1, area.y1, area.z1,
|
||||||
|
area.x2, area.y2, area.z2 =
|
||||||
|
nil, nil, nil, nil, nil, nil
|
||||||
|
|
||||||
|
-- Area positions sorting
|
||||||
|
areas:sortPos(area.pos1, area.pos2)
|
||||||
|
|
||||||
|
-- Add name
|
||||||
|
area.name = "unnamed"
|
||||||
|
|
||||||
|
-- Remove ID
|
||||||
|
area.id = nil
|
||||||
|
end
|
||||||
|
minetest.chat_send_player(name, "Table format updated.")
|
||||||
|
|
||||||
|
areas:save()
|
||||||
|
minetest.chat_send_player(name, "Converted areas saved. Done.")
|
||||||
|
end
|
||||||
|
})
|
||||||
|
|
||||||
|
function areas:node_ownership_load()
|
||||||
|
local filename = minetest.get_worldpath().."/owners.tbl"
|
||||||
|
local tables, err
|
||||||
|
tables, err = loadfile(filename)
|
||||||
|
if err then
|
||||||
|
return err
|
||||||
|
end
|
||||||
|
|
||||||
|
tables = tables()
|
||||||
|
for idx = 1, #tables do
|
||||||
|
local tolinkv, tolinki = {}, {}
|
||||||
|
for i, v in pairs(tables[idx]) do
|
||||||
|
if type(v) == "table" and tables[v[1]] then
|
||||||
|
table.insert(tolinkv, {i, tables[v[1]]})
|
||||||
|
end
|
||||||
|
if type(i) == "table" and tables[i[1]] then
|
||||||
|
table.insert(tolinki, {i, tables[i[1]]})
|
||||||
|
end
|
||||||
|
end
|
||||||
|
-- link values, first due to possible changes of indices
|
||||||
|
for _, v in ipairs(tolinkv) do
|
||||||
|
tables[idx][v[1]] = v[2]
|
||||||
|
end
|
||||||
|
-- link indices
|
||||||
|
for _, v in ipairs(tolinki) do
|
||||||
|
tables[idx][v[2]], tables[idx][v[1]] = tables[idx][v[1]], nil
|
||||||
|
end
|
||||||
|
end
|
||||||
|
self.areas = tables[1]
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Returns the name of the first player that owns an area
|
||||||
|
function areas.getNodeOwnerName(pos)
|
||||||
|
for id, area in pairs(areas:getAreasAtPos(pos)) do
|
||||||
|
return area.owner
|
||||||
|
end
|
||||||
|
return false
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Checks if a node is owned by you
|
||||||
|
function areas.isNodeOwner(pos, name)
|
||||||
|
if minetest.check_player_privs(name, areas.adminPrivs) then
|
||||||
|
return true
|
||||||
|
end
|
||||||
|
for id, area in pairs(areas:getAreasAtPos(pos)) do
|
||||||
|
if name == area.owner then
|
||||||
|
return true
|
||||||
|
end
|
||||||
|
end
|
||||||
|
return false
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Checks if an area has an owner
|
||||||
|
function areas.hasOwner(pos)
|
||||||
|
for id, area in pairs(areas:getAreasAtPos(pos)) do
|
||||||
|
return true
|
||||||
|
end
|
||||||
|
return false
|
||||||
|
end
|
||||||
|
|
||||||
|
IsPlayerNodeOwner = areas.isNodeOwner
|
||||||
|
GetNodeOwnerName = areas.getNodeOwnerName
|
||||||
|
HasOwner = areas.hasOwner
|
||||||
|
|
||||||
|
-- This is entirely untested and may break in strange and new ways.
|
||||||
|
if areas.config.legacy_table then
|
||||||
|
owner_defs = setmetatable({}, {
|
||||||
|
__index = function(table, key)
|
||||||
|
local a = rawget(areas.areas, key)
|
||||||
|
if not a then return a end
|
||||||
|
local b = {}
|
||||||
|
for k, v in pairs(a) do b[k] = v end
|
||||||
|
b.x1, b.y1, b.z1 = b.pos1.x, b.pos1.y, b.pos1.z
|
||||||
|
b.x2, b.y1, b.z2 = b.pos2.x, b.pos2.y, b.pos2.z
|
||||||
|
b.pos1, b.pos2 = nil, nil
|
||||||
|
b.id = key
|
||||||
|
return b
|
||||||
|
end,
|
||||||
|
__newindex = function(table, key, value)
|
||||||
|
local a = value
|
||||||
|
a.pos1, a.pos2 = {x=a.x1, y=a.y1, z=a.z1},
|
||||||
|
{x=a.x2, y=a.y2, z=a.z2}
|
||||||
|
a.x1, a.y1, a.z1, a.x2, a.y2, a.z2 =
|
||||||
|
nil, nil, nil, nil, nil, nil
|
||||||
|
a.name = a.name or "unnamed"
|
||||||
|
a.id = nil
|
||||||
|
return rawset(areas.areas, key, a)
|
||||||
|
end
|
||||||
|
})
|
||||||
|
end
|
||||||
|
|
|
@ -0,0 +1,6 @@
|
||||||
|
Code requiring player to have a land deed to protect an area added by Nathan Salapat.
|
||||||
|
|
||||||
|
Copyright (C) 2013 ShadowNinja
|
||||||
|
|
||||||
|
Licensed under the GNU LGPL version 2.1 or later.
|
||||||
|
See LICENSE.txt and http://www.gnu.org/licenses/lgpl-2.1.txt
|
|
@ -0,0 +1,2 @@
|
||||||
|
name = areas
|
||||||
|
optional_depends = playerfactions
|
|
@ -0,0 +1,265 @@
|
||||||
|
|
||||||
|
-- I could depend on WorldEdit for this, but you need to have the 'worldedit'
|
||||||
|
-- permission to use those commands and you don't have
|
||||||
|
-- /area_pos{1,2} [X Y Z|X,Y,Z].
|
||||||
|
-- Since this is mostly copied from WorldEdit it is mostly
|
||||||
|
-- licensed under the AGPL. (select_area is a exception)
|
||||||
|
|
||||||
|
areas.marker1 = {}
|
||||||
|
areas.marker2 = {}
|
||||||
|
areas.set_pos = {}
|
||||||
|
areas.pos1 = {}
|
||||||
|
areas.pos2 = {}
|
||||||
|
|
||||||
|
local LIMIT = 30992 -- this is due to MAPBLOCK_SIZE=16!
|
||||||
|
|
||||||
|
local function posLimit(pos)
|
||||||
|
return {
|
||||||
|
x = math.max(math.min(pos.x, LIMIT), -LIMIT),
|
||||||
|
y = math.max(math.min(pos.y, LIMIT), -LIMIT),
|
||||||
|
z = math.max(math.min(pos.z, LIMIT), -LIMIT)
|
||||||
|
}
|
||||||
|
end
|
||||||
|
|
||||||
|
minetest.register_chatcommand("select_area", {
|
||||||
|
params = "<ID>",
|
||||||
|
description = "Select a area by id.",
|
||||||
|
func = function(name, param)
|
||||||
|
local id = tonumber(param)
|
||||||
|
if not id then
|
||||||
|
return false, "Invalid usage, see /help select_area."
|
||||||
|
end
|
||||||
|
if not areas.areas[id] then
|
||||||
|
return false, "The area "..id.." does not exist."
|
||||||
|
end
|
||||||
|
|
||||||
|
areas:setPos1(name, areas.areas[id].pos1)
|
||||||
|
areas:setPos2(name, areas.areas[id].pos2)
|
||||||
|
return true, "Area "..id.." selected."
|
||||||
|
end,
|
||||||
|
})
|
||||||
|
|
||||||
|
minetest.register_chatcommand("area_pos1", {
|
||||||
|
params = "[X Y Z|X,Y,Z]",
|
||||||
|
description = "Set area protection region position 1 to your"
|
||||||
|
.." location or the one specified",
|
||||||
|
privs = {},
|
||||||
|
func = function(name, param)
|
||||||
|
local pos
|
||||||
|
local found, _, x, y, z = param:find(
|
||||||
|
"^(-?%d+)[, ](-?%d+)[, ](-?%d+)$")
|
||||||
|
if found then
|
||||||
|
pos = {x=tonumber(x), y=tonumber(y), z=tonumber(z)}
|
||||||
|
elseif param == "" then
|
||||||
|
local player = minetest.get_player_by_name(name)
|
||||||
|
if player then
|
||||||
|
pos = player:get_pos()
|
||||||
|
else
|
||||||
|
return false, "Unable to get position."
|
||||||
|
end
|
||||||
|
else
|
||||||
|
return false, "Invalid usage, see /help area_pos1."
|
||||||
|
end
|
||||||
|
pos = posLimit(vector.round(pos))
|
||||||
|
areas:setPos1(name, pos)
|
||||||
|
return true, "Area position 1 set to "
|
||||||
|
..minetest.pos_to_string(pos)
|
||||||
|
end,
|
||||||
|
})
|
||||||
|
|
||||||
|
minetest.register_chatcommand("area_pos2", {
|
||||||
|
params = "[X Y Z|X,Y,Z]",
|
||||||
|
description = "Set area protection region position 2 to your"
|
||||||
|
.." location or the one specified",
|
||||||
|
func = function(name, param)
|
||||||
|
local pos
|
||||||
|
local found, _, x, y, z = param:find(
|
||||||
|
"^(-?%d+)[, ](-?%d+)[, ](-?%d+)$")
|
||||||
|
if found then
|
||||||
|
pos = {x=tonumber(x), y=tonumber(y), z=tonumber(z)}
|
||||||
|
elseif param == "" then
|
||||||
|
local player = minetest.get_player_by_name(name)
|
||||||
|
if player then
|
||||||
|
pos = player:get_pos()
|
||||||
|
else
|
||||||
|
return false, "Unable to get position."
|
||||||
|
end
|
||||||
|
else
|
||||||
|
return false, "Invalid usage, see /help area_pos2."
|
||||||
|
end
|
||||||
|
pos = posLimit(vector.round(pos))
|
||||||
|
areas:setPos2(name, pos)
|
||||||
|
return true, "Area position 2 set to "
|
||||||
|
..minetest.pos_to_string(pos)
|
||||||
|
end,
|
||||||
|
})
|
||||||
|
|
||||||
|
|
||||||
|
minetest.register_chatcommand("area_pos", {
|
||||||
|
params = "set/set1/set2/get",
|
||||||
|
description = "Set area protection region, position 1, or position 2"
|
||||||
|
.." by punching nodes, or display the region",
|
||||||
|
func = function(name, param)
|
||||||
|
if param == "set" then -- Set both area positions
|
||||||
|
areas.set_pos[name] = "pos1"
|
||||||
|
return true, "Select positions by punching two nodes."
|
||||||
|
elseif param == "set1" then -- Set area position 1
|
||||||
|
areas.set_pos[name] = "pos1only"
|
||||||
|
return true, "Select position 1 by punching a node."
|
||||||
|
elseif param == "set2" then -- Set area position 2
|
||||||
|
areas.set_pos[name] = "pos2"
|
||||||
|
return true, "Select position 2 by punching a node."
|
||||||
|
elseif param == "get" then -- Display current area positions
|
||||||
|
local pos1str, pos2str = "Position 1: ", "Position 2: "
|
||||||
|
if areas.pos1[name] then
|
||||||
|
pos1str = pos1str..minetest.pos_to_string(areas.pos1[name])
|
||||||
|
else
|
||||||
|
pos1str = pos1str.."<not set>"
|
||||||
|
end
|
||||||
|
if areas.pos2[name] then
|
||||||
|
pos2str = pos2str..minetest.pos_to_string(areas.pos2[name])
|
||||||
|
else
|
||||||
|
pos2str = pos2str.."<not set>"
|
||||||
|
end
|
||||||
|
return true, pos1str.."\n"..pos2str
|
||||||
|
else
|
||||||
|
return false, "Unknown subcommand: "..param
|
||||||
|
end
|
||||||
|
end,
|
||||||
|
})
|
||||||
|
|
||||||
|
function areas:getPos(playerName)
|
||||||
|
local pos1, pos2 = areas.pos1[playerName], areas.pos2[playerName]
|
||||||
|
if not (pos1 and pos2) then
|
||||||
|
return nil
|
||||||
|
end
|
||||||
|
-- Copy positions so that the area table doesn't contain multiple
|
||||||
|
-- references to the same position.
|
||||||
|
pos1, pos2 = vector.new(pos1), vector.new(pos2)
|
||||||
|
return areas:sortPos(pos1, pos2)
|
||||||
|
end
|
||||||
|
|
||||||
|
function areas:setPos1(playerName, pos)
|
||||||
|
areas.pos1[playerName] = posLimit(pos)
|
||||||
|
areas.markPos1(playerName)
|
||||||
|
end
|
||||||
|
|
||||||
|
function areas:setPos2(playerName, pos)
|
||||||
|
areas.pos2[playerName] = posLimit(pos)
|
||||||
|
areas.markPos2(playerName)
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
minetest.register_on_punchnode(function(pos, node, puncher)
|
||||||
|
local name = puncher:get_player_name()
|
||||||
|
-- Currently setting position
|
||||||
|
if name ~= "" and areas.set_pos[name] then
|
||||||
|
if areas.set_pos[name] == "pos1" then
|
||||||
|
areas.pos1[name] = pos
|
||||||
|
areas.markPos1(name)
|
||||||
|
areas.set_pos[name] = "pos2"
|
||||||
|
minetest.chat_send_player(name,
|
||||||
|
"Position 1 set to "
|
||||||
|
..minetest.pos_to_string(pos))
|
||||||
|
elseif areas.set_pos[name] == "pos1only" then
|
||||||
|
areas.pos1[name] = pos
|
||||||
|
areas.markPos1(name)
|
||||||
|
areas.set_pos[name] = nil
|
||||||
|
minetest.chat_send_player(name,
|
||||||
|
"Position 1 set to "
|
||||||
|
..minetest.pos_to_string(pos))
|
||||||
|
elseif areas.set_pos[name] == "pos2" then
|
||||||
|
areas.pos2[name] = pos
|
||||||
|
areas.markPos2(name)
|
||||||
|
areas.set_pos[name] = nil
|
||||||
|
minetest.chat_send_player(name,
|
||||||
|
"Position 2 set to "
|
||||||
|
..minetest.pos_to_string(pos))
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end)
|
||||||
|
|
||||||
|
-- Modifies positions `pos1` and `pos2` so that each component of `pos1`
|
||||||
|
-- is less than or equal to its corresponding component of `pos2`,
|
||||||
|
-- returning the two positions.
|
||||||
|
function areas:sortPos(pos1, pos2)
|
||||||
|
if pos1.x > pos2.x then
|
||||||
|
pos2.x, pos1.x = pos1.x, pos2.x
|
||||||
|
end
|
||||||
|
if pos1.y > pos2.y then
|
||||||
|
pos2.y, pos1.y = pos1.y, pos2.y
|
||||||
|
end
|
||||||
|
if pos1.z > pos2.z then
|
||||||
|
pos2.z, pos1.z = pos1.z, pos2.z
|
||||||
|
end
|
||||||
|
return pos1, pos2
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Marks area position 1
|
||||||
|
areas.markPos1 = function(name)
|
||||||
|
local pos = areas.pos1[name]
|
||||||
|
if areas.marker1[name] ~= nil then -- Marker already exists
|
||||||
|
areas.marker1[name]:remove() -- Remove marker
|
||||||
|
areas.marker1[name] = nil
|
||||||
|
end
|
||||||
|
if pos ~= nil then -- Add marker
|
||||||
|
areas.marker1[name] = minetest.add_entity(pos, "areas:pos1")
|
||||||
|
areas.marker1[name]:get_luaentity().active = true
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Marks area position 2
|
||||||
|
areas.markPos2 = function(name)
|
||||||
|
local pos = areas.pos2[name]
|
||||||
|
if areas.marker2[name] ~= nil then -- Marker already exists
|
||||||
|
areas.marker2[name]:remove() -- Remove marker
|
||||||
|
areas.marker2[name] = nil
|
||||||
|
end
|
||||||
|
if pos ~= nil then -- Add marker
|
||||||
|
areas.marker2[name] = minetest.add_entity(pos, "areas:pos2")
|
||||||
|
areas.marker2[name]:get_luaentity().active = true
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
minetest.register_entity("areas:pos1", {
|
||||||
|
initial_properties = {
|
||||||
|
visual = "cube",
|
||||||
|
visual_size = {x=1.1, y=1.1},
|
||||||
|
textures = {"areas_pos1.png", "areas_pos1.png",
|
||||||
|
"areas_pos1.png", "areas_pos1.png",
|
||||||
|
"areas_pos1.png", "areas_pos1.png"},
|
||||||
|
collisionbox = {-0.55, -0.55, -0.55, 0.55, 0.55, 0.55},
|
||||||
|
},
|
||||||
|
on_step = function(self, dtime)
|
||||||
|
if self.active == nil then
|
||||||
|
self.object:remove()
|
||||||
|
end
|
||||||
|
end,
|
||||||
|
on_punch = function(self, hitter)
|
||||||
|
self.object:remove()
|
||||||
|
local name = hitter:get_player_name()
|
||||||
|
areas.marker1[name] = nil
|
||||||
|
end,
|
||||||
|
})
|
||||||
|
|
||||||
|
minetest.register_entity("areas:pos2", {
|
||||||
|
initial_properties = {
|
||||||
|
visual = "cube",
|
||||||
|
visual_size = {x=1.1, y=1.1},
|
||||||
|
textures = {"areas_pos2.png", "areas_pos2.png",
|
||||||
|
"areas_pos2.png", "areas_pos2.png",
|
||||||
|
"areas_pos2.png", "areas_pos2.png"},
|
||||||
|
collisionbox = {-0.55, -0.55, -0.55, 0.55, 0.55, 0.55},
|
||||||
|
},
|
||||||
|
on_step = function(self, dtime)
|
||||||
|
if self.active == nil then
|
||||||
|
self.object:remove()
|
||||||
|
end
|
||||||
|
end,
|
||||||
|
on_punch = function(self, hitter)
|
||||||
|
self.object:remove()
|
||||||
|
local name = hitter:get_player_name()
|
||||||
|
areas.marker2[name] = nil
|
||||||
|
end,
|
||||||
|
})
|
||||||
|
|
|
@ -0,0 +1,46 @@
|
||||||
|
local world_path = minetest.get_worldpath()
|
||||||
|
|
||||||
|
areas.config = {}
|
||||||
|
|
||||||
|
local function setting(name, tp, default)
|
||||||
|
local full_name = "areas." .. name
|
||||||
|
local value
|
||||||
|
if tp == "bool" then
|
||||||
|
value = minetest.settings:get_bool(full_name)
|
||||||
|
default = value == nil and minetest.is_yes(default)
|
||||||
|
elseif tp == "string" then
|
||||||
|
value = minetest.settings:get(full_name)
|
||||||
|
elseif tp == "v3f" then
|
||||||
|
value = minetest.setting_get_pos(full_name)
|
||||||
|
default = value == nil and minetest.string_to_pos(default)
|
||||||
|
elseif tp == "float" or tp == "int" then
|
||||||
|
value = tonumber(minetest.settings:get(full_name))
|
||||||
|
local v, other = default:match("^(%S+) (.+)")
|
||||||
|
default = value == nil and tonumber(other and v or default)
|
||||||
|
else
|
||||||
|
error("Cannot parse setting type " .. tp)
|
||||||
|
end
|
||||||
|
|
||||||
|
if value == nil then
|
||||||
|
value = default
|
||||||
|
assert(default ~= nil, "Cannot parse default for " .. full_name)
|
||||||
|
end
|
||||||
|
--print("add", name, default, value)
|
||||||
|
areas.config[name] = value
|
||||||
|
end
|
||||||
|
|
||||||
|
local file = io.open(areas.modpath .. "/settingtypes.txt", "r")
|
||||||
|
for line in file:lines() do
|
||||||
|
local name, tp, value = line:match("^areas%.(%S+) %(.*%) (%S+) (.*)")
|
||||||
|
if value then
|
||||||
|
setting(name, tp, value)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
file:close()
|
||||||
|
|
||||||
|
--------------
|
||||||
|
-- Settings --
|
||||||
|
--------------
|
||||||
|
|
||||||
|
setting("filename", "string", world_path.."/areas.dat")
|
||||||
|
|
|
@ -0,0 +1,37 @@
|
||||||
|
# This file is parsed in "settings.lua". Check regex first.
|
||||||
|
|
||||||
|
# Static paths do not work well with settings
|
||||||
|
#areas.filename (Configuration file path) string (world_path)/areas.dat
|
||||||
|
|
||||||
|
# Allow players with a privilege create their own areas using /protect
|
||||||
|
# within the specified size and amount limits.
|
||||||
|
areas.self_protection (Self protection) bool true
|
||||||
|
|
||||||
|
# Self protection: Privilege required to protect an area
|
||||||
|
areas.self_protection_privilege (Self protection: Required privs) string areas
|
||||||
|
|
||||||
|
# Refresh delay for the name displays in the HUD in seconds
|
||||||
|
areas.tick (HUD update delay) float 0.5 0 100
|
||||||
|
|
||||||
|
# Enable the legacy owner_defs metatable mode. Untested and possibly unstable
|
||||||
|
areas.legacy_table (Legacy owner_defs metatable) bool false
|
||||||
|
|
||||||
|
[Self protection (normal)]
|
||||||
|
|
||||||
|
# Self protection (normal): Maximal size of the protectable area
|
||||||
|
# Only enter positive whole numbers for the coordinate values or you'll mess up stuff.
|
||||||
|
areas.self_protection_max_size (Maximal area size) v3f (64, 128, 64)
|
||||||
|
|
||||||
|
# Self protection (normal): Maximal amount of protected areas per player
|
||||||
|
areas.self_protection_max_areas (Maximal area count) int 4
|
||||||
|
|
||||||
|
[Self protection (high)]
|
||||||
|
|
||||||
|
# Self protection (normal): Maximal size of the protectable area
|
||||||
|
# This setting applies for plyaers with the privilege 'areas_high_limit'
|
||||||
|
areas.self_protection_max_size_high (Maximal area size) v3f (512, 512, 512)
|
||||||
|
|
||||||
|
# Self protection (normal): Maximal amount of protected areas per player
|
||||||
|
# Only enter positive whole numbers for the coordinate values or you'll mess up stuff.
|
||||||
|
# This setting applies for plyaers with the privilege 'areas_high_limit'
|
||||||
|
areas.self_protection_max_areas_high (Maximal area count) float 32
|
After Width: | Height: | Size: 142 B |
After Width: | Height: | Size: 157 B |
|
@ -0,0 +1,57 @@
|
||||||
|
|
||||||
|
--[[
|
||||||
|
|
||||||
|
Copyright 2017 Auke Kok <sofar@foo-projects.org>
|
||||||
|
|
||||||
|
Permission is hereby granted, free of charge, to any person obtaining
|
||||||
|
a copy of this software and associated documentation files (the
|
||||||
|
"Software"), to deal in the Software without restriction, including
|
||||||
|
without limitation the rights to use, copy, modify, merge, publish,
|
||||||
|
distribute, sublicense, and/or sell copies of the Software, and to
|
||||||
|
permit persons to whom the Software is furnished to do so, subject
|
||||||
|
to the following conditions:
|
||||||
|
|
||||||
|
The above copyright notice and this permission notice shall be included
|
||||||
|
in all copies or substantial portions of the Software.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY
|
||||||
|
KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
|
||||||
|
WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||||
|
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
||||||
|
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
||||||
|
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||||
|
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||||
|
|
||||||
|
]]--
|
||||||
|
|
||||||
|
local def = 300 -- server must be empty for this long
|
||||||
|
local int = 15 -- check interval in seconds
|
||||||
|
|
||||||
|
local to = def
|
||||||
|
|
||||||
|
local function do_shutdown()
|
||||||
|
local i, _ = next(minetest.get_connected_players())
|
||||||
|
if not i then
|
||||||
|
to = to - int
|
||||||
|
else
|
||||||
|
to = def
|
||||||
|
minetest.after(int, do_shutdown)
|
||||||
|
return
|
||||||
|
end
|
||||||
|
if to < 0 then
|
||||||
|
minetest.log("action", "autoshutdown")
|
||||||
|
minetest.request_shutdown()
|
||||||
|
else
|
||||||
|
minetest.after(int, do_shutdown)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
minetest.register_chatcommand("autoshutdown", {
|
||||||
|
params = "autoshutdown server",
|
||||||
|
description = "shut the server down after the last player leaves",
|
||||||
|
privs = {server = true},
|
||||||
|
func = function(name, param)
|
||||||
|
do_shutdown()
|
||||||
|
return true, "autoshutdown issued"
|
||||||
|
end,
|
||||||
|
})
|
|
@ -0,0 +1,2 @@
|
||||||
|
name = autoshutdown
|
||||||
|
description = Shut down the server after the last player leaves.
|
|
@ -0,0 +1,11 @@
|
||||||
|
|
||||||
|
## autoshutdown mod
|
||||||
|
|
||||||
|
Allows admins to schedule a shutdown when the last player leaves.
|
||||||
|
|
||||||
|
The server shuts down a little time after the last player leaves,
|
||||||
|
to make sure all areas are slowly unloaded.
|
||||||
|
|
||||||
|
To schedule an automatic shutdown, issue the `/autoshutdown` command
|
||||||
|
in chat. The shutdown will only happen once.
|
||||||
|
|
|
@ -0,0 +1,19 @@
|
||||||
|
Copyright (c) 2013-8 rubenwardy
|
||||||
|
|
||||||
|
Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||||
|
this software and associated documentation files (the "Software"), to deal in
|
||||||
|
the Software without restriction, including without limitation the rights to
|
||||||
|
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
|
||||||
|
of the Software, and to permit persons to whom the Software is furnished to do
|
||||||
|
so, subject to the following conditions:
|
||||||
|
|
||||||
|
The above copyright notice and this permission notice shall be included in all
|
||||||
|
copies or substantial portions of the Software.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||||
|
THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||||
|
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||||
|
DEALINGS IN THE SOFTWARE.
|
|
@ -0,0 +1,295 @@
|
||||||
|
# Awards
|
||||||
|
|
||||||
|
Adds awards/achievements to Minetest (plus a very good API).
|
||||||
|
|
||||||
|
by [rubenwardy](https://rubenwardy.com), licensed under MIT.
|
||||||
|
With thanks to Wuzzy, kaeza, and MrIbby.
|
||||||
|
|
||||||
|
Majority of awards are back ported from Calinou's old fork in Carbone, under same license.
|
||||||
|
|
||||||
|
|
||||||
|
# Introduction
|
||||||
|
|
||||||
|
## Awards and Triggers
|
||||||
|
|
||||||
|
An award is a single unlockable unit, registered like so:
|
||||||
|
|
||||||
|
```lua
|
||||||
|
awards.register_award("mymod:award", {
|
||||||
|
description = "My Example Award",
|
||||||
|
})
|
||||||
|
```
|
||||||
|
|
||||||
|
Awards are unlocked either using `awards.unlock()` or by a trigger being
|
||||||
|
fullfilled. A trigger is a condition which unlocks an award. Triggers are
|
||||||
|
registered at the same time as an award is registered:
|
||||||
|
|
||||||
|
```lua
|
||||||
|
awards.register_award("mymod:award", {
|
||||||
|
description = "My Example Award",
|
||||||
|
trigger = {
|
||||||
|
type = "dig",
|
||||||
|
node = "default:stone",
|
||||||
|
target = 10,
|
||||||
|
},
|
||||||
|
})
|
||||||
|
```
|
||||||
|
|
||||||
|
The above trigger type is an example of a counted_key trigger:
|
||||||
|
rather than a single counter there's a counter per key - in this
|
||||||
|
case the key is the value of the `node` field. If you leave out
|
||||||
|
the key in a `counted_key` trigger, then the total will be used
|
||||||
|
instead. For example, here is an award which unlocks after you've
|
||||||
|
placed 10 nodes of any type:
|
||||||
|
|
||||||
|
```lua
|
||||||
|
awards.register_award("mymod:award", {
|
||||||
|
description = "Place 10 nodes!",
|
||||||
|
trigger = {
|
||||||
|
type = "place",
|
||||||
|
target = 10,
|
||||||
|
},
|
||||||
|
})
|
||||||
|
```
|
||||||
|
|
||||||
|
You can also register an *Unlock Function*, which can return the name of an
|
||||||
|
award to unlock it:
|
||||||
|
|
||||||
|
```lua
|
||||||
|
awards.register_award("mymod:award", {
|
||||||
|
title = "Lava Miner",
|
||||||
|
description = "Mine any block while being very close to lava.",
|
||||||
|
})
|
||||||
|
|
||||||
|
awards.register_on_dig(function(player, data)
|
||||||
|
local pos = player:get_pos()
|
||||||
|
if pos and (minetest.find_node_near(pos, 1, "default:lava_source") or
|
||||||
|
minetest.find_node_near(pos, 1, "default:lava_flowing")) then
|
||||||
|
return "mymod:award"
|
||||||
|
end
|
||||||
|
return nil
|
||||||
|
end)
|
||||||
|
```
|
||||||
|
|
||||||
|
The above is a bad example as you don't actually need the stats data given.
|
||||||
|
It would be better to register a `dignode` callback and call `awards.unlock()`
|
||||||
|
if the condition is met.
|
||||||
|
|
||||||
|
## Trigger Types
|
||||||
|
|
||||||
|
The trigger type is used to determine which event will cause the trigger will be
|
||||||
|
fulfilled. The awards mod comes with a number of predefined types, documented
|
||||||
|
in [Builtin Trigger Types](#builtin-trigger-types).
|
||||||
|
|
||||||
|
Trigger types are registered like so:
|
||||||
|
|
||||||
|
```lua
|
||||||
|
awards.register_trigger("chat", {
|
||||||
|
type = "counted",
|
||||||
|
progress = "@1/@2 chat messages",
|
||||||
|
auto_description = { "Send a chat message", "Chat @1 times" },
|
||||||
|
})
|
||||||
|
|
||||||
|
minetest.register_on_chat_message(function(name, message)
|
||||||
|
local player = minetest.get_player_by_name(name)
|
||||||
|
if not player or string.find(message, "/") then
|
||||||
|
return
|
||||||
|
end
|
||||||
|
awards.notify_chat(player)
|
||||||
|
end)
|
||||||
|
```
|
||||||
|
|
||||||
|
A trigger type has a type as well, which determines how the data is stored and
|
||||||
|
also how the trigger is fulfilled.
|
||||||
|
|
||||||
|
**Trigger Type Types:**
|
||||||
|
|
||||||
|
* **custom** requires you handle the calling of awards.unlock() yourself. You also
|
||||||
|
need to implement on_register() yourself. You'll also probably want to implement
|
||||||
|
`on_register()` to catch awards registered with your trigger type.
|
||||||
|
* **counted** stores a single counter for each player which is incremented by calling
|
||||||
|
`trigger:notify(player)`. Good for homogenous actions like number of chat messages,
|
||||||
|
joins, and the like.
|
||||||
|
* **counted_key** stores a table of counters each indexed by a key. There is also
|
||||||
|
a total field (`__total`) which stores the sum of all counters. A counter is
|
||||||
|
incremented by calling `trigger:notify(player, key)`. This is good for things like
|
||||||
|
placing nodes or crafting items, where the key will be the item or node name.
|
||||||
|
If `key` is an item, then you should also add `key_is_item = true` to the
|
||||||
|
trigger type definition.
|
||||||
|
|
||||||
|
As said, you could use a custom trigger if none of the other ones match your needs.
|
||||||
|
Here's an example.
|
||||||
|
|
||||||
|
```lua
|
||||||
|
awards.register_trigger("foo", {
|
||||||
|
type = "custom",
|
||||||
|
progress = "@1/@2 foos",
|
||||||
|
auto_description = { "Do a foo", "Foo @1 times" },
|
||||||
|
})
|
||||||
|
|
||||||
|
minetest.register_on_foo(function()
|
||||||
|
for _, trigger in pairs(awards.on.foo) do
|
||||||
|
-- trigger is either a trigger tables or
|
||||||
|
-- or an unlock function.
|
||||||
|
|
||||||
|
-- some complex logic
|
||||||
|
if condition then
|
||||||
|
awards.unlock(trigger)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end)
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
## Award Difficulty
|
||||||
|
|
||||||
|
Difficulty is used to determine how awards are sorted in awards lists.
|
||||||
|
|
||||||
|
If the award trigger is counted, ie: the trigger requires a `target` property,
|
||||||
|
then the difficulty multipler is timesd by `target` to get the overall difficulty.
|
||||||
|
If the award isn't a counted type then the difficulty multiplier is used as the
|
||||||
|
overal difficulty. Award difficulty affects how awards are sorted in a list -
|
||||||
|
more difficult awards are further down the list.
|
||||||
|
|
||||||
|
In real terms, `difficulty` is a relative difficulty to do one unit of the trigger
|
||||||
|
if its counted, otherwise it's the relative difficulty of completely doing the
|
||||||
|
award (if not-counted). For the `dig` trigger type, 1 unit would be 1 node dug.
|
||||||
|
|
||||||
|
|
||||||
|
Actual code used to calculate award difficulty:
|
||||||
|
|
||||||
|
```lua
|
||||||
|
local difficulty = def.difficulty or 1
|
||||||
|
if def.trigger and def.trigger.target then
|
||||||
|
difficulty = difficulty * def.trigger.target
|
||||||
|
end
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
|
# API
|
||||||
|
|
||||||
|
* awards.register_award(name, def), the def table has the following fields:
|
||||||
|
* `title` - title of the award (defaults to name)
|
||||||
|
* `description` - longer description of the award, displayed in Awards tab
|
||||||
|
* `difficulty` - see [Award Difficulty](#award-difficulty).
|
||||||
|
* `requires` - list of awards that need to be unlocked before this one
|
||||||
|
is visible.
|
||||||
|
* `prizes` - list of items to give when you earn the award
|
||||||
|
* `secret` - boolean if this award is secret (i.e. showed on awards list)
|
||||||
|
* `sound` - `SimpleSoundSpec` table to play on unlock.
|
||||||
|
`false` to disable unlock sound.
|
||||||
|
* `icon` - the icon image, use default otherwise.
|
||||||
|
* `background` - the background image, use default otherwise.
|
||||||
|
* `trigger` - trigger definition, see [Builtin Trigger Types](#builtin-trigger-types).
|
||||||
|
* `on_unlock(name, def)` - callback on unlock.
|
||||||
|
* awards.register_trigger(name, def), the def table has the following fields:
|
||||||
|
* `type` - see [Trigger Types](#trigger-types).
|
||||||
|
* `progress` - used to format progress, defaults to "%1/%2".
|
||||||
|
* `auto_description` - a table of two elements. Each element is a format string. Element 1 is singular, element 2 is plural. Used for the award description (not title) if none is given.
|
||||||
|
* `on_register(award_def)` - called when an award registers with this type.
|
||||||
|
* "counted_key" only:
|
||||||
|
* `auto_description_total` - Used if the trigger is for the total.
|
||||||
|
* `get_key(self, def)` - get key for particular award, return nil for a total.
|
||||||
|
* `key_is_item` - true if the key is an item name. On notify(),
|
||||||
|
any watched groups will also be notified as `group:groupname` keys.
|
||||||
|
* awards.register_on_unlock(func(name, def))
|
||||||
|
* name is the player name
|
||||||
|
* def is the award def.
|
||||||
|
* return true to cancel HUD
|
||||||
|
* awards.unlock(name, award)
|
||||||
|
* gives an award to a player
|
||||||
|
* name is the player name
|
||||||
|
|
||||||
|
## Builtin Trigger Types
|
||||||
|
|
||||||
|
Callbacks (register a function to be run)
|
||||||
|
|
||||||
|
* dig type: Dig a node.
|
||||||
|
* node: the dug node type. If nil, all dug nodes are counted
|
||||||
|
* place type: Place a node.
|
||||||
|
* node: the placed node type. If nil, all placed nodes are counted
|
||||||
|
* craft type: Craft something.
|
||||||
|
* item: the crafted item type. If nil, all crafted items are counted
|
||||||
|
* death type: Die.
|
||||||
|
* reason: the death reason, one of the types in PlayerHPChangeReason (see lua_api.txt)
|
||||||
|
or nil for total deaths.
|
||||||
|
* chat type: Write a chat message.
|
||||||
|
* join type: Join the server.
|
||||||
|
* eat type: Eat an item.
|
||||||
|
* item: the eaten item type. If nil, all eaten items are counted
|
||||||
|
|
||||||
|
(for all types) target - how many times to dig/place/craft/etc.
|
||||||
|
|
||||||
|
Each type has a register function like so:
|
||||||
|
|
||||||
|
* awards.register_on_TRIGGERTYPE(func(player, data))
|
||||||
|
* data is the player stats data
|
||||||
|
* return award name or null
|
||||||
|
|
||||||
|
### dig
|
||||||
|
|
||||||
|
```lua
|
||||||
|
trigger = {
|
||||||
|
type = "dig",
|
||||||
|
node = "default:dirt", -- item, alias, or group
|
||||||
|
target = 50,
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### place
|
||||||
|
|
||||||
|
```lua
|
||||||
|
trigger = {
|
||||||
|
type = "place",
|
||||||
|
node = "default:dirt", -- item, alias, or group
|
||||||
|
target = 50,
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### craft
|
||||||
|
|
||||||
|
```lua
|
||||||
|
trigger = {
|
||||||
|
type = "craft",
|
||||||
|
item = "default:dirt", -- item, alias, or group
|
||||||
|
target = 50,
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### death
|
||||||
|
|
||||||
|
```lua
|
||||||
|
trigger = {
|
||||||
|
type = "death",
|
||||||
|
reason = "fall",
|
||||||
|
target = 5,
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### chat
|
||||||
|
|
||||||
|
```lua
|
||||||
|
trigger = {
|
||||||
|
type = "chat",
|
||||||
|
target = 100,
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### join
|
||||||
|
|
||||||
|
```lua
|
||||||
|
trigger = {
|
||||||
|
type = "join",
|
||||||
|
target = 100,
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### eat
|
||||||
|
|
||||||
|
```lua
|
||||||
|
trigger = {
|
||||||
|
type = "eat",
|
||||||
|
item = "default:apple",
|
||||||
|
target = 100,
|
||||||
|
}
|
||||||
|
```
|
|
@ -0,0 +1,36 @@
|
||||||
|
-- Copyright (c) 2013-18 rubenwardy. MIT.
|
||||||
|
|
||||||
|
-- The global award namespace
|
||||||
|
awards = {
|
||||||
|
show_mode = "hud",
|
||||||
|
registered_triggers = {},
|
||||||
|
}
|
||||||
|
|
||||||
|
-- Internationalization support.
|
||||||
|
awards.gettext, awards.ngettext = dofile(minetest.get_modpath("awards").."/src/intllib.lua")
|
||||||
|
|
||||||
|
-- Load files
|
||||||
|
dofile(minetest.get_modpath("awards").."/src/data.lua")
|
||||||
|
dofile(minetest.get_modpath("awards").."/src/api_awards.lua")
|
||||||
|
dofile(minetest.get_modpath("awards").."/src/api_triggers.lua")
|
||||||
|
dofile(minetest.get_modpath("awards").."/src/chat_commands.lua")
|
||||||
|
dofile(minetest.get_modpath("awards").."/src/gui.lua")
|
||||||
|
dofile(minetest.get_modpath("awards").."/src/triggers.lua")
|
||||||
|
dofile(minetest.get_modpath("awards").."/src/awards.lua")
|
||||||
|
|
||||||
|
awards.load()
|
||||||
|
minetest.register_on_shutdown(awards.save)
|
||||||
|
|
||||||
|
|
||||||
|
-- Backwards compatibility
|
||||||
|
awards.give_achievement = awards.unlock
|
||||||
|
awards.getFormspec = awards.get_formspec
|
||||||
|
awards.showto = awards.show_to
|
||||||
|
awards.register_onDig = awards.register_on_dig
|
||||||
|
awards.register_onPlace = awards.register_on_place
|
||||||
|
awards.register_onDeath = awards.register_on_death
|
||||||
|
awards.register_onChat = awards.register_on_chat
|
||||||
|
awards.register_onJoin = awards.register_on_join
|
||||||
|
awards.register_onCraft = awards.register_on_craft
|
||||||
|
awards.def = awards.registered_awards
|
||||||
|
awards.register_achievement = awards.register_award
|
|
@ -0,0 +1,824 @@
|
||||||
|
# German translations for PACKAGE package.
|
||||||
|
# Copyright (C) 2017 THE PACKAGE'S COPYRIGHT HOLDER
|
||||||
|
# This file is distributed under the same license as the PACKAGE package.
|
||||||
|
# Wuzzy2, 2017.
|
||||||
|
#
|
||||||
|
msgid ""
|
||||||
|
msgstr ""
|
||||||
|
"Project-Id-Version: PACKAGE VERSION\n"
|
||||||
|
"Report-Msgid-Bugs-To: \n"
|
||||||
|
"POT-Creation-Date: 2017-02-21 05:35-0300\n"
|
||||||
|
"PO-Revision-Date: 2017-02-21 04:19-0300\n"
|
||||||
|
"Last-Translator: Wuzzy2\n"
|
||||||
|
"Language-Team: German\n"
|
||||||
|
"Language: de\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"
|
||||||
|
|
||||||
|
#: api.lua
|
||||||
|
msgid "Secret Achievement Unlocked:"
|
||||||
|
msgstr "Geheime Auszeichnung erhalten:"
|
||||||
|
|
||||||
|
#: api.lua
|
||||||
|
msgid "Achievement Unlocked:"
|
||||||
|
msgstr "Auszeichnung erhalten:"
|
||||||
|
|
||||||
|
#: api.lua
|
||||||
|
#, lua-format
|
||||||
|
msgid "Secret Achievement Unlocked: %s"
|
||||||
|
msgstr "Geheime Auszeichnung erhalten: %s"
|
||||||
|
|
||||||
|
#: api.lua
|
||||||
|
#, lua-format
|
||||||
|
msgid "Achievement Unlocked: %s"
|
||||||
|
msgstr "Auszeichnung erhalten: %s"
|
||||||
|
|
||||||
|
#: api.lua
|
||||||
|
msgid "Secret Achievement Unlocked!"
|
||||||
|
msgstr "Geheime Auszeichnung erhalten!"
|
||||||
|
|
||||||
|
#: api.lua
|
||||||
|
msgid "Achievement Unlocked!"
|
||||||
|
msgstr "Auszeichnung erhalten:"
|
||||||
|
|
||||||
|
#: api.lua
|
||||||
|
msgid "Error: No awards available."
|
||||||
|
msgstr "Fehler: Keine Auszeichnungen vorhanden."
|
||||||
|
|
||||||
|
#: api.lua
|
||||||
|
msgid "OK"
|
||||||
|
msgstr "OK"
|
||||||
|
|
||||||
|
#: api.lua
|
||||||
|
msgid "(Secret Award)"
|
||||||
|
msgstr "(Geheime Auszeichnung)"
|
||||||
|
|
||||||
|
#: api.lua
|
||||||
|
msgid "Unlock this award to find out what it is."
|
||||||
|
msgstr "Verdienen Sie sich diese Auszeichnung, um herauszufinden, was sie ist."
|
||||||
|
|
||||||
|
#: api.lua
|
||||||
|
#, lua-format
|
||||||
|
msgid "%s (got)"
|
||||||
|
msgstr "%s (erhalten)"
|
||||||
|
|
||||||
|
#: api.lua
|
||||||
|
msgid "You've disabled awards. Type /awards enable to reenable."
|
||||||
|
msgstr ""
|
||||||
|
"Sie haben die Auszeichnungen deaktiviert. Geben Sie »/awards enable« ein, um "
|
||||||
|
"sie wieder zu aktivieren."
|
||||||
|
|
||||||
|
#: api.lua
|
||||||
|
msgid "You have not unlocked any awards."
|
||||||
|
msgstr "Sie haben noch keine Auszeichnungen."
|
||||||
|
|
||||||
|
#: api.lua
|
||||||
|
#, lua-format
|
||||||
|
msgid "%s’s awards:"
|
||||||
|
msgstr "%ss Auszeichnungen:"
|
||||||
|
|
||||||
|
#: api.lua chat_commands.lua
|
||||||
|
#, lua-format
|
||||||
|
msgid "%s: %s"
|
||||||
|
msgstr "%s: %s"
|
||||||
|
|
||||||
|
#: sfinv.lua unified_inventory.lua
|
||||||
|
msgid "Awards"
|
||||||
|
msgstr "Auszeichnungen"
|
||||||
|
|
||||||
|
#: triggers.lua
|
||||||
|
msgid "@1/@2 dug"
|
||||||
|
msgstr "@1/@2 abgebaut"
|
||||||
|
|
||||||
|
#. Translators: @1 is count, @2 is description.
|
||||||
|
#: triggers.lua
|
||||||
|
msgid "Mine: @2"
|
||||||
|
msgid_plural "Mine: @1×@2"
|
||||||
|
msgstr[0] "Bauen Sie einen Block ab: @2"
|
||||||
|
msgstr[1] "Bauen Sie Blöcke ab: @1×@2"
|
||||||
|
|
||||||
|
#: triggers.lua
|
||||||
|
msgid "Mine @1 block."
|
||||||
|
msgid_plural "Mine @1 blocks."
|
||||||
|
msgstr[0] "Bauen Sie einen @1 Block ab."
|
||||||
|
msgstr[1] "Bauen Sie @1 Blöcke ab."
|
||||||
|
|
||||||
|
#: triggers.lua
|
||||||
|
msgid "@1/@2 placed"
|
||||||
|
msgstr "@1/@2 platziert"
|
||||||
|
|
||||||
|
#. Translators: @1 is count, @2 is description.
|
||||||
|
#: triggers.lua
|
||||||
|
msgid "Place: @2"
|
||||||
|
msgid_plural "Place: @1×@2"
|
||||||
|
msgstr[0] "Platzieren Sie einen Block: @2"
|
||||||
|
msgstr[1] "Platzieren Sie Blöcke: @1×@2"
|
||||||
|
|
||||||
|
#: triggers.lua
|
||||||
|
msgid "Place a block."
|
||||||
|
msgid_plural "Place @1 blocks."
|
||||||
|
msgstr[0] "Platzieren Sie einen Block."
|
||||||
|
msgstr[1] "Platzieren Sie @1 Blöcke."
|
||||||
|
|
||||||
|
#: triggers.lua
|
||||||
|
msgid "@1/@2 eaten"
|
||||||
|
msgstr "@1/@2 gegessen"
|
||||||
|
|
||||||
|
#. Translators: @1 is count, @2 is description.
|
||||||
|
#: triggers.lua
|
||||||
|
msgid "Eat: @2"
|
||||||
|
msgid_plural "Eat: @1×@2"
|
||||||
|
msgstr[0] "Essen Sie: @2"
|
||||||
|
msgstr[1] "Essen Sie: @1×@2"
|
||||||
|
|
||||||
|
#: triggers.lua
|
||||||
|
msgid "Eat an item."
|
||||||
|
msgid_plural "Eat @1 items."
|
||||||
|
msgstr[0] ""
|
||||||
|
msgstr[1] ""
|
||||||
|
|
||||||
|
#: triggers.lua
|
||||||
|
msgid "@1/@2 deaths"
|
||||||
|
msgstr "@1/@2 Tode"
|
||||||
|
|
||||||
|
#: triggers.lua
|
||||||
|
msgid "Die."
|
||||||
|
msgid_plural "Die @1 times."
|
||||||
|
msgstr[0] "Sterben Sie."
|
||||||
|
msgstr[1] "Sterben Sie @1 mal."
|
||||||
|
|
||||||
|
#: triggers.lua
|
||||||
|
msgid "@1/@2 chat messages"
|
||||||
|
msgstr "@1/@2 Chatnachrichten"
|
||||||
|
|
||||||
|
#: triggers.lua
|
||||||
|
msgid "Write something in chat."
|
||||||
|
msgid_plural "Write @1 chat messages."
|
||||||
|
msgstr[0] "Schreiben Sie etwas im Chat."
|
||||||
|
msgstr[1] "Schreiben Sie @1 Chatnachrichten."
|
||||||
|
|
||||||
|
#: triggers.lua
|
||||||
|
msgid "@1/@2 game joins"
|
||||||
|
msgstr "@1/@2 Spielen beigetreten"
|
||||||
|
|
||||||
|
#: triggers.lua
|
||||||
|
msgid "Join the game."
|
||||||
|
msgid_plural "Join the game @1 times."
|
||||||
|
msgstr[0] "Treten Sie dem Spiel bei."
|
||||||
|
msgstr[1] "Treten Sie dem Spiel @1 mal bei."
|
||||||
|
|
||||||
|
#: triggers.lua
|
||||||
|
msgid "@1/@2 crafted"
|
||||||
|
msgstr "@1/@2 gefertigt"
|
||||||
|
|
||||||
|
#. Translators: @1 is count, @2 is description.
|
||||||
|
#: triggers.lua
|
||||||
|
msgid "Craft: @2"
|
||||||
|
msgid_plural "Craft: @1×@2"
|
||||||
|
msgstr[0] "Fertigen Sie an: @2"
|
||||||
|
msgstr[1] "Fertigen Sie an: @1×@2"
|
||||||
|
|
||||||
|
#: triggers.lua
|
||||||
|
msgid "Craft an item."
|
||||||
|
msgid_plural "Craft @1 items."
|
||||||
|
msgstr[0] ""
|
||||||
|
msgstr[1] ""
|
||||||
|
|
||||||
|
#: init.lua
|
||||||
|
msgid "Saint-Maclou"
|
||||||
|
msgstr "Saint-Maclou"
|
||||||
|
|
||||||
|
#: init.lua
|
||||||
|
msgid "Place 20 coal checkers."
|
||||||
|
msgstr "Platzieren Sie 20 Kohlenschachbrettmuster."
|
||||||
|
|
||||||
|
#: init.lua
|
||||||
|
msgid "Castorama"
|
||||||
|
msgstr "Gießmeister"
|
||||||
|
|
||||||
|
#: init.lua
|
||||||
|
msgid "Place 20 iron checkers."
|
||||||
|
msgstr "Platzieren Sie 20 Eisenschachbrettmuster."
|
||||||
|
|
||||||
|
#: init.lua
|
||||||
|
msgid "Sam the Trapper"
|
||||||
|
msgstr "Sam der Fallensteller"
|
||||||
|
|
||||||
|
#: init.lua
|
||||||
|
msgid "Place 2 trap stones."
|
||||||
|
msgstr "Platzieren Sie 2 Fallensteine."
|
||||||
|
|
||||||
|
#: init.lua
|
||||||
|
msgid "Backpacker"
|
||||||
|
msgstr "Rucksacktourist"
|
||||||
|
|
||||||
|
#: init.lua
|
||||||
|
msgid "Craft 4 large bags."
|
||||||
|
msgstr "Fertigen Sie 4 große Taschen."
|
||||||
|
|
||||||
|
#: init.lua
|
||||||
|
msgid "Pyromaniac"
|
||||||
|
msgstr "Pyromane"
|
||||||
|
|
||||||
|
#: init.lua
|
||||||
|
msgid "Craft 8 times flint and steel."
|
||||||
|
msgstr "Fertigen Sie 8 mal einen Feuerstein und Stahl an."
|
||||||
|
|
||||||
|
#: init.lua
|
||||||
|
msgid "Firefighter"
|
||||||
|
msgstr "Feuerwehr"
|
||||||
|
|
||||||
|
#: init.lua
|
||||||
|
msgid "Put out 1000 fires."
|
||||||
|
msgstr "Löschen Sie 1000 Flammen."
|
||||||
|
|
||||||
|
#: init.lua
|
||||||
|
msgid "Light It Up"
|
||||||
|
msgstr "Licht an!"
|
||||||
|
|
||||||
|
#: init.lua
|
||||||
|
msgid "Place 100 torches."
|
||||||
|
msgstr "Platzieren Sie 100 Fackeln."
|
||||||
|
|
||||||
|
#: init.lua
|
||||||
|
msgid "Well Lit"
|
||||||
|
msgstr "Gut ausgeleuchtet"
|
||||||
|
|
||||||
|
#: init.lua
|
||||||
|
msgid "Place 1,000 torches."
|
||||||
|
msgstr "Platzieren Sie 1000 Fackeln."
|
||||||
|
|
||||||
|
#: init.lua
|
||||||
|
msgid "Really Well Lit"
|
||||||
|
msgstr "Sehr gute Beleuchtung"
|
||||||
|
|
||||||
|
#: init.lua
|
||||||
|
msgid "Craft 10 mese lamps."
|
||||||
|
msgstr "Fertigen Sie 10 Meselampen."
|
||||||
|
|
||||||
|
#: init.lua
|
||||||
|
msgid "Outpost"
|
||||||
|
msgstr "Außenposten"
|
||||||
|
|
||||||
|
#: init.lua
|
||||||
|
msgid "Craft 200 stone bricks."
|
||||||
|
msgstr "Fertigen Sie 200 Steinziegel."
|
||||||
|
|
||||||
|
#: init.lua
|
||||||
|
msgid "Watchtower"
|
||||||
|
msgstr "Wachturm"
|
||||||
|
|
||||||
|
#: init.lua
|
||||||
|
msgid "Craft 800 stone bricks."
|
||||||
|
msgstr "Fertigen Sie 800 Steinziegel an."
|
||||||
|
|
||||||
|
#: init.lua
|
||||||
|
msgid "Fortress"
|
||||||
|
msgstr "Burg"
|
||||||
|
|
||||||
|
#: init.lua
|
||||||
|
msgid "Craft 3,200 stone bricks."
|
||||||
|
msgstr "Fertigen Sie 3200 Steinziegel."
|
||||||
|
|
||||||
|
#: init.lua
|
||||||
|
msgid "Desert Dweller"
|
||||||
|
msgstr "Wüstenbewohner"
|
||||||
|
|
||||||
|
#: init.lua
|
||||||
|
msgid "Craft 400 desert stone bricks."
|
||||||
|
msgstr "Fertigen Sie 400 Wüstensteinziegel."
|
||||||
|
|
||||||
|
#: init.lua
|
||||||
|
msgid "Pharaoh"
|
||||||
|
msgstr "Pharao"
|
||||||
|
|
||||||
|
#: init.lua
|
||||||
|
msgid "Craft 100 sandstone bricks."
|
||||||
|
msgstr "Fertigen Sie 100 Sandsteinziegel."
|
||||||
|
|
||||||
|
#: init.lua
|
||||||
|
msgid "Little Library"
|
||||||
|
msgstr "Kleine Bücherei"
|
||||||
|
|
||||||
|
#: init.lua
|
||||||
|
msgid "Craft 7 bookshelves."
|
||||||
|
msgstr "Fertigen Sie 7 Bücherregale."
|
||||||
|
|
||||||
|
#: init.lua
|
||||||
|
msgid "Lava and Water"
|
||||||
|
msgstr "Lava und Wasser"
|
||||||
|
|
||||||
|
#: init.lua
|
||||||
|
msgid "Mine your first obsidian."
|
||||||
|
msgstr "Bauen Sie Ihr erstes Obsidian ab."
|
||||||
|
|
||||||
|
#: init.lua
|
||||||
|
msgid "Obsessed with Obsidian"
|
||||||
|
msgstr "Von Obsidian besessen"
|
||||||
|
|
||||||
|
#: init.lua
|
||||||
|
msgid "Mine 50 obsidian."
|
||||||
|
msgstr "Bauen Sie 50 Obsidian ab."
|
||||||
|
|
||||||
|
#: init.lua
|
||||||
|
msgid "Lava Miner"
|
||||||
|
msgstr "Lavagräber"
|
||||||
|
|
||||||
|
#: init.lua
|
||||||
|
msgid "Mine any block while being very close to lava."
|
||||||
|
msgstr ""
|
||||||
|
"Bauen Sie einen beliebigen Block ab, während Sie sehr nahe an der Lava "
|
||||||
|
"stehen."
|
||||||
|
|
||||||
|
#: init.lua
|
||||||
|
msgid "On The Way"
|
||||||
|
msgstr "Auf dem Weg"
|
||||||
|
|
||||||
|
#: init.lua
|
||||||
|
msgid "Place 100 rails."
|
||||||
|
msgstr "Platzieren Sie 100 Gleise."
|
||||||
|
|
||||||
|
#: init.lua
|
||||||
|
msgid "First Day in the Woods"
|
||||||
|
msgstr "Erster Tag im Wald"
|
||||||
|
|
||||||
|
#: init.lua
|
||||||
|
msgid "Dig 6 tree blocks."
|
||||||
|
msgstr "Bauen Sie 6 Baumblöcke ab."
|
||||||
|
|
||||||
|
#: init.lua
|
||||||
|
msgid "Lumberjack"
|
||||||
|
msgstr "Holzfäller"
|
||||||
|
|
||||||
|
#: init.lua
|
||||||
|
msgid "Dig 36 tree blocks."
|
||||||
|
msgstr "Bauen Sie 36 Baumblöcke ab."
|
||||||
|
|
||||||
|
#: init.lua
|
||||||
|
msgid "Semi-pro Lumberjack"
|
||||||
|
msgstr "Fortgeschrittener Holzfäller"
|
||||||
|
|
||||||
|
#: init.lua
|
||||||
|
msgid "Dig 216 tree blocks."
|
||||||
|
msgstr "Bauen Sie 216 Baumblöcke ab."
|
||||||
|
|
||||||
|
#: init.lua
|
||||||
|
msgid "Professional Lumberjack"
|
||||||
|
msgstr "Profiholzfäller"
|
||||||
|
|
||||||
|
#: init.lua
|
||||||
|
msgid "Dig 1,296 tree blocks."
|
||||||
|
msgstr "Bauen Sie 1296 Baumblöcke ab."
|
||||||
|
|
||||||
|
#: init.lua
|
||||||
|
msgid "Junglebaby"
|
||||||
|
msgstr "Dschungelbaby"
|
||||||
|
|
||||||
|
#: init.lua
|
||||||
|
msgid "Dig 100 jungle tree blocks."
|
||||||
|
msgstr "Bauen Sie 100 Dschungelbaumblöcke ab."
|
||||||
|
|
||||||
|
#: init.lua
|
||||||
|
msgid "Jungleman"
|
||||||
|
msgstr "Dschungelmann"
|
||||||
|
|
||||||
|
#: init.lua
|
||||||
|
msgid "Dig 1,000 jungle tree blocks."
|
||||||
|
msgstr "Bauen Sie 1000 Dschungelbaumblöcke ab."
|
||||||
|
|
||||||
|
#: init.lua
|
||||||
|
msgid "First Mese Find"
|
||||||
|
msgstr "Erster Mesefund"
|
||||||
|
|
||||||
|
#: init.lua
|
||||||
|
msgid "Mine your first mese ore."
|
||||||
|
msgstr "Bauen Sie Ihr erstes Meseerz ab."
|
||||||
|
|
||||||
|
#: init.lua
|
||||||
|
msgid "Mese Mastery"
|
||||||
|
msgstr "Mesemeister"
|
||||||
|
|
||||||
|
#: init.lua
|
||||||
|
msgid "Mine a mese block."
|
||||||
|
msgstr "Bauen Sie einen Meseblock ab."
|
||||||
|
|
||||||
|
#: init.lua
|
||||||
|
msgid "You’re a copper"
|
||||||
|
msgstr "Du Kupfer!"
|
||||||
|
|
||||||
|
#: init.lua
|
||||||
|
msgid "Dig 1,000 copper ores."
|
||||||
|
msgstr "Bauen Sie 1000 Kupfererze ab."
|
||||||
|
|
||||||
|
#: init.lua
|
||||||
|
msgid "A Cat in a Pop-Tart?!"
|
||||||
|
msgstr "Eine Katze im Pop-Tart?!"
|
||||||
|
|
||||||
|
#: init.lua
|
||||||
|
msgid "Mine a nyan cat."
|
||||||
|
msgstr "Bauen Sie eine Nyan Cat ab."
|
||||||
|
|
||||||
|
#: init.lua
|
||||||
|
msgid "Mini Miner"
|
||||||
|
msgstr "Berganfänger"
|
||||||
|
|
||||||
|
#: init.lua
|
||||||
|
msgid "Dig 100 stone blocks."
|
||||||
|
msgstr "Bauen Sie 100 Steinblöcke ab."
|
||||||
|
|
||||||
|
#: init.lua
|
||||||
|
msgid "Hardened Miner"
|
||||||
|
msgstr "Abhehärteter Bergarbeiter"
|
||||||
|
|
||||||
|
#: init.lua
|
||||||
|
msgid "Dig 1,000 stone blocks."
|
||||||
|
msgstr "Bauen Sie 1000 Steine ab."
|
||||||
|
|
||||||
|
#: init.lua
|
||||||
|
msgid "Master Miner"
|
||||||
|
msgstr "Profibergarbeiter"
|
||||||
|
|
||||||
|
#: init.lua
|
||||||
|
msgid "Dig 10,000 stone blocks."
|
||||||
|
msgstr "Bauen Sie 10000 Steine ab."
|
||||||
|
|
||||||
|
#: init.lua
|
||||||
|
msgid "Marchand De Sable"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: init.lua
|
||||||
|
msgid "Dig 1,000 sand."
|
||||||
|
msgstr "Bauen Sie 1000 Sand ab."
|
||||||
|
|
||||||
|
#: init.lua
|
||||||
|
msgid "Crafter of Sticks"
|
||||||
|
msgstr "Stockmacher"
|
||||||
|
|
||||||
|
#: init.lua
|
||||||
|
msgid "Craft 100 sticks."
|
||||||
|
msgstr "Fertigen Sie 100 Stöcke."
|
||||||
|
|
||||||
|
#: init.lua
|
||||||
|
msgid "Jungle Discoverer"
|
||||||
|
msgstr "Dschungelerkunder"
|
||||||
|
|
||||||
|
#: init.lua
|
||||||
|
msgid "Mine your first jungle grass."
|
||||||
|
msgstr "Bauen Sie Ihr erstes Dschungelgras ab."
|
||||||
|
|
||||||
|
#: init.lua
|
||||||
|
msgid "Grasslands Discoverer"
|
||||||
|
msgstr "Prärieerkunder"
|
||||||
|
|
||||||
|
#: init.lua
|
||||||
|
msgid "Mine some grass."
|
||||||
|
msgstr "Bauen Sie etwas Gras ab."
|
||||||
|
|
||||||
|
#: init.lua
|
||||||
|
msgid "Savannah Discoverer"
|
||||||
|
msgstr "Savannenerkunder"
|
||||||
|
|
||||||
|
#: init.lua
|
||||||
|
msgid "Mine some dry grass."
|
||||||
|
msgstr "Bauen Sie etwas trockenes Gras ab."
|
||||||
|
|
||||||
|
#: init.lua
|
||||||
|
msgid "Desert Discoverer"
|
||||||
|
msgstr "Wüstenerkunder"
|
||||||
|
|
||||||
|
#: init.lua
|
||||||
|
msgid "Mine your first cactus."
|
||||||
|
msgstr "Bauen Sie Ihren ersten Kaktus ab."
|
||||||
|
|
||||||
|
#: init.lua
|
||||||
|
msgid "Far Lands"
|
||||||
|
msgstr "Ferne Lande"
|
||||||
|
|
||||||
|
#: init.lua
|
||||||
|
msgid "Mine your first dry shrub."
|
||||||
|
msgstr "Bauen Sie Ihren ersten vertrockneten Strauch ab."
|
||||||
|
|
||||||
|
#: init.lua
|
||||||
|
msgid "Glacier Discoverer"
|
||||||
|
msgstr "Gletschererkunder"
|
||||||
|
|
||||||
|
#: init.lua
|
||||||
|
msgid "Mine your first ice."
|
||||||
|
msgstr "Bauen Sie Ihr erstes Eis ab."
|
||||||
|
|
||||||
|
#: init.lua
|
||||||
|
msgid "Very Simple Snow Man"
|
||||||
|
msgstr "Sehr simpler Schneemann"
|
||||||
|
|
||||||
|
#: init.lua
|
||||||
|
msgid "Place two snow blocks."
|
||||||
|
msgstr "Platzieren Sie zwei Schneeblöcke."
|
||||||
|
|
||||||
|
#: init.lua
|
||||||
|
msgid "First Gold Find"
|
||||||
|
msgstr "Erster Goldfund"
|
||||||
|
|
||||||
|
#: init.lua
|
||||||
|
msgid "Mine your first gold ore."
|
||||||
|
msgstr "Bauen Sie Ihr erstes Golderz ab."
|
||||||
|
|
||||||
|
#: init.lua
|
||||||
|
msgid "Gold Rush"
|
||||||
|
msgstr "Goldrausch"
|
||||||
|
|
||||||
|
#: init.lua
|
||||||
|
msgid "Mine 45 gold ores."
|
||||||
|
msgstr "Bauen Sie 18 Diamanterze ab."
|
||||||
|
|
||||||
|
#: init.lua
|
||||||
|
msgid "Wow, I am Diamonds!"
|
||||||
|
msgstr "Wow, ich bin Diamanten!"
|
||||||
|
|
||||||
|
#: init.lua
|
||||||
|
msgid "Mine your first diamond ore."
|
||||||
|
msgstr "Bauen Sie Ihr erstes Diamanterz ab."
|
||||||
|
|
||||||
|
#: init.lua
|
||||||
|
msgid "Girl's Best Friend"
|
||||||
|
msgstr "Bester Freund der Mädchen"
|
||||||
|
|
||||||
|
#: init.lua
|
||||||
|
msgid "Mine 18 diamond ores."
|
||||||
|
msgstr "Bauen Sie 18 Diamanterze ab."
|
||||||
|
|
||||||
|
#: init.lua
|
||||||
|
msgid "Hardest Block on Earth"
|
||||||
|
msgstr "Härtester Block der Welt"
|
||||||
|
|
||||||
|
#: init.lua
|
||||||
|
msgid "Craft a diamond block."
|
||||||
|
msgstr "Fertigen Sie einen Diamantblock an."
|
||||||
|
|
||||||
|
#: init.lua
|
||||||
|
msgid "In the Dungeon"
|
||||||
|
msgstr "Im Verlies"
|
||||||
|
|
||||||
|
#: init.lua
|
||||||
|
msgid "Mine a mossy cobblestone."
|
||||||
|
msgstr "Bauen Sie ein bemoostes Kopfsteinpflaster ab."
|
||||||
|
|
||||||
|
#: init.lua
|
||||||
|
msgid "Smelter"
|
||||||
|
msgstr "Schmelzer"
|
||||||
|
|
||||||
|
#: init.lua
|
||||||
|
msgid "Craft 10 furnaces."
|
||||||
|
msgstr "Fertigen Sie 10 Öfen."
|
||||||
|
|
||||||
|
#: init.lua
|
||||||
|
msgid "Treasurer"
|
||||||
|
msgstr "Schatzmeister"
|
||||||
|
|
||||||
|
#: init.lua
|
||||||
|
msgid "Craft 15 chests."
|
||||||
|
msgstr "Fertigen Sie 15 Truhen."
|
||||||
|
|
||||||
|
#: init.lua
|
||||||
|
msgid "Bankier"
|
||||||
|
msgstr "Bankier"
|
||||||
|
|
||||||
|
#: init.lua
|
||||||
|
msgid "Craft 30 locked chests."
|
||||||
|
msgstr "Fertigen Sie 30 abgeschlossene Truhen."
|
||||||
|
|
||||||
|
#: init.lua
|
||||||
|
msgid "Bricker"
|
||||||
|
msgstr "Ziegler"
|
||||||
|
|
||||||
|
#: init.lua
|
||||||
|
msgid "Craft 200 brick blocks."
|
||||||
|
msgstr "Fertigen Sie 200 Ziegelblöcke."
|
||||||
|
|
||||||
|
#: init.lua
|
||||||
|
msgid "House of Obsidian"
|
||||||
|
msgstr "Haus aus Obsidian"
|
||||||
|
|
||||||
|
#: init.lua
|
||||||
|
msgid "Craft 100 obsidian bricks."
|
||||||
|
msgstr "Fertigen Sie 100 Obsidianziegel."
|
||||||
|
|
||||||
|
#: init.lua
|
||||||
|
msgid "Build a Cave"
|
||||||
|
msgstr "Höhlenbauer"
|
||||||
|
|
||||||
|
#: init.lua
|
||||||
|
msgid "Place 100 stone."
|
||||||
|
msgstr "Platzieren Sie 100 Steine."
|
||||||
|
|
||||||
|
#: init.lua
|
||||||
|
msgid "Long Ladder"
|
||||||
|
msgstr "Lange Leiter"
|
||||||
|
|
||||||
|
#: init.lua
|
||||||
|
msgid "Place 400 wooden ladders."
|
||||||
|
msgstr "Platzieren Sie 400 Holzleitern."
|
||||||
|
|
||||||
|
#: init.lua
|
||||||
|
msgid "Industrial Age"
|
||||||
|
msgstr "Industriezeitalter"
|
||||||
|
|
||||||
|
#: init.lua
|
||||||
|
msgid "Place 40 steel ladders."
|
||||||
|
msgstr "Platzieren Sie 40 Stahlleitern."
|
||||||
|
|
||||||
|
#: init.lua
|
||||||
|
msgid "Yummy!"
|
||||||
|
msgstr "Lecker!"
|
||||||
|
|
||||||
|
#: init.lua
|
||||||
|
msgid "Eat 80 apples."
|
||||||
|
msgstr "Essen Sie 80 Äpfel."
|
||||||
|
|
||||||
|
#: init.lua
|
||||||
|
msgid "Glasser"
|
||||||
|
msgstr "Glasmacher"
|
||||||
|
|
||||||
|
#: init.lua
|
||||||
|
msgid "Craft 14 vessels shelves."
|
||||||
|
msgstr "Fertigen Sie 14 Gefäßregale."
|
||||||
|
|
||||||
|
#: init.lua
|
||||||
|
msgid "Farming Skills Acquired"
|
||||||
|
msgstr "Landwirtschaft erlernt"
|
||||||
|
|
||||||
|
#: init.lua
|
||||||
|
msgid "Harvest a fully grown wheat plant."
|
||||||
|
msgstr "Ernten Sie eine voll ausgewachsene Getreidepflanze."
|
||||||
|
|
||||||
|
#: init.lua
|
||||||
|
msgid "Field Worker"
|
||||||
|
msgstr "Feldarbeiter"
|
||||||
|
|
||||||
|
#: init.lua
|
||||||
|
msgid "Harvest 25 fully grown wheat plants."
|
||||||
|
msgstr "Ernten Sie 25 voll ausgewachsene Getreidepflanzen."
|
||||||
|
|
||||||
|
#: init.lua
|
||||||
|
msgid "Aspiring Farmer"
|
||||||
|
msgstr "Aufstrebender Bauer"
|
||||||
|
|
||||||
|
#: init.lua
|
||||||
|
msgid "Harvest 125 fully grown wheat plants."
|
||||||
|
msgstr "Ernten Sie 125 voll ausgewachsene Getreidepflanzen."
|
||||||
|
|
||||||
|
#: init.lua
|
||||||
|
msgid "Wheat Magnate"
|
||||||
|
msgstr "Getreidemagnat"
|
||||||
|
|
||||||
|
#: init.lua
|
||||||
|
msgid "Harvest 625 fully grown wheat plants."
|
||||||
|
msgstr "Ernten Sie 625 voll ausgewachsene Getreidepflanzen."
|
||||||
|
|
||||||
|
#: init.lua
|
||||||
|
msgid "Baker"
|
||||||
|
msgstr "Bäcker"
|
||||||
|
|
||||||
|
#: init.lua
|
||||||
|
msgid "Eat 10 loaves of bread."
|
||||||
|
msgstr "Essen Sie 10 Brote."
|
||||||
|
|
||||||
|
#: init.lua
|
||||||
|
msgid "Wool Over Your Eyes"
|
||||||
|
msgstr "Wollige Augen"
|
||||||
|
|
||||||
|
#: init.lua
|
||||||
|
msgid "Craft 250 white wool."
|
||||||
|
msgstr "Fertigen Sie 250 weiße Wolle."
|
||||||
|
|
||||||
|
#: init.lua
|
||||||
|
msgid "Hotelier"
|
||||||
|
msgstr "Hotelier"
|
||||||
|
|
||||||
|
#: init.lua
|
||||||
|
msgid "Craft 15 fancy beds."
|
||||||
|
msgstr "Fertigen Sie 15 schicke Betten."
|
||||||
|
|
||||||
|
#: init.lua
|
||||||
|
msgid "Filthy Rich"
|
||||||
|
msgstr "Stinkreich"
|
||||||
|
|
||||||
|
#: init.lua
|
||||||
|
msgid "Craft 24 gold block stairs."
|
||||||
|
msgstr "Fertigen Sie 24 Goldblockstufen."
|
||||||
|
|
||||||
|
#: init.lua
|
||||||
|
msgid "Roses Are Red"
|
||||||
|
msgstr "Rosen sind rot"
|
||||||
|
|
||||||
|
#: init.lua
|
||||||
|
msgid "Craft 400 red dyes."
|
||||||
|
msgstr "Fertigen Sie 400 rote Farbstoffe."
|
||||||
|
|
||||||
|
#: init.lua
|
||||||
|
msgid "Dandelions are Yellow"
|
||||||
|
msgstr "Löwenzahn ist gelb"
|
||||||
|
|
||||||
|
#: init.lua
|
||||||
|
msgid "Craft 400 yellow dyes."
|
||||||
|
msgstr "Fertigen Sie 400 gelbe Farbstoffe."
|
||||||
|
|
||||||
|
#: init.lua
|
||||||
|
msgid "Geraniums are Blue"
|
||||||
|
msgstr "Geranien sind blau"
|
||||||
|
|
||||||
|
#: init.lua
|
||||||
|
msgid "Craft 400 blue dyes."
|
||||||
|
msgstr "Fertigen Sie 400 blaue Farbstoffe."
|
||||||
|
|
||||||
|
#: init.lua
|
||||||
|
msgid "White Color Stock"
|
||||||
|
msgstr "Weißer Farbstoffvorrat"
|
||||||
|
|
||||||
|
#: init.lua
|
||||||
|
msgid "Craft 100 white dyes."
|
||||||
|
msgstr "Fertigen Sie 100 weiße Farbstoffe."
|
||||||
|
|
||||||
|
#: init.lua
|
||||||
|
msgid "Tasty Mushrooms"
|
||||||
|
msgstr "Leckere Pilze"
|
||||||
|
|
||||||
|
#: init.lua
|
||||||
|
msgid "Eat 3 brown mushrooms."
|
||||||
|
msgstr "Essen Sie 3 braune Pilze."
|
||||||
|
|
||||||
|
#: init.lua
|
||||||
|
msgid "Mushroom Lover"
|
||||||
|
msgstr "Pilzfreund"
|
||||||
|
|
||||||
|
#: init.lua
|
||||||
|
msgid "Eat 33 brown mushrooms."
|
||||||
|
msgstr "Essen Sie 33 braune Pilze."
|
||||||
|
|
||||||
|
#: init.lua
|
||||||
|
msgid "Underground Mushroom Farmer"
|
||||||
|
msgstr "Unterirdischer Pilzbauer"
|
||||||
|
|
||||||
|
#: init.lua
|
||||||
|
msgid "Eat 333 brown mushrooms."
|
||||||
|
msgstr "Essen Sie 333 braune Pilze."
|
||||||
|
|
||||||
|
#: init.lua
|
||||||
|
msgid "Builder"
|
||||||
|
msgstr "Bauarbeiter"
|
||||||
|
|
||||||
|
#: init.lua
|
||||||
|
msgid "Constructor"
|
||||||
|
msgstr "Konstrukteur"
|
||||||
|
|
||||||
|
#: init.lua
|
||||||
|
msgid "Architect"
|
||||||
|
msgstr "Architekt"
|
||||||
|
|
||||||
|
#: init.lua
|
||||||
|
msgid "Master Architect"
|
||||||
|
msgstr "Meisterarchitekt"
|
||||||
|
|
||||||
|
#: chat_commands.lua
|
||||||
|
msgid "[c|clear|disable|enable]"
|
||||||
|
msgstr "[c|clear|disable|enable]"
|
||||||
|
|
||||||
|
#: chat_commands.lua
|
||||||
|
msgid "Show, clear, disable or enable your achievements"
|
||||||
|
msgstr "Zeigen, löschen, deaktivieren oder aktivieren Sie Ihre Auszeichnungen"
|
||||||
|
|
||||||
|
#: chat_commands.lua
|
||||||
|
msgid ""
|
||||||
|
"All your awards and statistics have been cleared. You can now start again."
|
||||||
|
msgstr ""
|
||||||
|
"All Ihre Auszeichnugen und Statistiken wurden zurückgesetzt. Sie können nun "
|
||||||
|
"von vorne anfangen."
|
||||||
|
|
||||||
|
#: chat_commands.lua
|
||||||
|
msgid "You have disabled your achievements."
|
||||||
|
msgstr "Sie haben Ihre Auszeichnungen deaktiviert."
|
||||||
|
|
||||||
|
#: chat_commands.lua
|
||||||
|
msgid "You have enabled your achievements."
|
||||||
|
msgstr "Sie haben Ihre Auszeichnungen aktiviert."
|
||||||
|
|
||||||
|
#: chat_commands.lua
|
||||||
|
msgid "<achievement ID>"
|
||||||
|
msgstr "<Auszeichnungs-ID>"
|
||||||
|
|
||||||
|
#: chat_commands.lua
|
||||||
|
msgid "Show details of an achievement"
|
||||||
|
msgstr "Details einer Auszeichnung anzeigen"
|
||||||
|
|
||||||
|
#: chat_commands.lua
|
||||||
|
msgid "Achievement not found."
|
||||||
|
msgstr "Auszeichnung nicht gefunden."
|
||||||
|
|
||||||
|
#: chat_commands.lua
|
||||||
|
msgid "<name>"
|
||||||
|
msgstr "<Name>"
|
||||||
|
|
||||||
|
#: chat_commands.lua
|
||||||
|
msgid "Get the achievements statistics for the given player or yourself"
|
||||||
|
msgstr "Die Statistik der Auszeichnungen eines Spielers zeigen"
|
|
@ -0,0 +1,825 @@
|
||||||
|
# Spanish translations for PACKAGE package
|
||||||
|
# Traducciones al español para el paquete PACKAGE.
|
||||||
|
# Copyright (C) 2017 THE PACKAGE'S COPYRIGHT HOLDER
|
||||||
|
# This file is distributed under the same license as the PACKAGE package.
|
||||||
|
# Diego Martínez <kaeza@users.noreply.github.com>, 2017.
|
||||||
|
#
|
||||||
|
msgid ""
|
||||||
|
msgstr ""
|
||||||
|
"Project-Id-Version: PACKAGE VERSION\n"
|
||||||
|
"Report-Msgid-Bugs-To: \n"
|
||||||
|
"POT-Creation-Date: 2017-02-21 05:35-0300\n"
|
||||||
|
"PO-Revision-Date: 2017-02-20 22:17-0300\n"
|
||||||
|
"Last-Translator: Diego Martínez <kaeza@users.noreply.github.com>\n"
|
||||||
|
"Language-Team: Spanish\n"
|
||||||
|
"Language: es\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"
|
||||||
|
|
||||||
|
#: api.lua
|
||||||
|
msgid "Secret Achievement Unlocked:"
|
||||||
|
msgstr "Logro secreto desbloqueado:"
|
||||||
|
|
||||||
|
#: api.lua
|
||||||
|
msgid "Achievement Unlocked:"
|
||||||
|
msgstr "Logro desbloqueado:"
|
||||||
|
|
||||||
|
#: api.lua
|
||||||
|
#, lua-format
|
||||||
|
msgid "Secret Achievement Unlocked: %s"
|
||||||
|
msgstr "Logro secreto desbloqueado: %s"
|
||||||
|
|
||||||
|
#: api.lua
|
||||||
|
#, lua-format
|
||||||
|
msgid "Achievement Unlocked: %s"
|
||||||
|
msgstr "Logro desbloqueado: %s"
|
||||||
|
|
||||||
|
#: api.lua
|
||||||
|
msgid "Secret Achievement Unlocked!"
|
||||||
|
msgstr "Logro secreto desbloqueado!"
|
||||||
|
|
||||||
|
#: api.lua
|
||||||
|
msgid "Achievement Unlocked!"
|
||||||
|
msgstr "Logro desbloqueado!"
|
||||||
|
|
||||||
|
#: api.lua
|
||||||
|
msgid "Error: No awards available."
|
||||||
|
msgstr "Error: No hay logros disponibles."
|
||||||
|
|
||||||
|
#: api.lua
|
||||||
|
msgid "OK"
|
||||||
|
msgstr "Aceptar"
|
||||||
|
|
||||||
|
#: api.lua
|
||||||
|
msgid "(Secret Award)"
|
||||||
|
msgstr "(Logro secreto)"
|
||||||
|
|
||||||
|
#: api.lua
|
||||||
|
msgid "Unlock this award to find out what it is."
|
||||||
|
msgstr "Desbloquea éste logro para saber qué es."
|
||||||
|
|
||||||
|
#: api.lua
|
||||||
|
#, lua-format
|
||||||
|
msgid "%s (got)"
|
||||||
|
msgstr "%s (obtenido)"
|
||||||
|
|
||||||
|
#: api.lua
|
||||||
|
msgid "You've disabled awards. Type /awards enable to reenable."
|
||||||
|
msgstr ""
|
||||||
|
"Has deshabilitado los logros. Escribe \"/awards enable\" para reactivar."
|
||||||
|
|
||||||
|
#: api.lua
|
||||||
|
msgid "You have not unlocked any awards."
|
||||||
|
msgstr "No has desbloqueado ningún logro."
|
||||||
|
|
||||||
|
#: api.lua
|
||||||
|
#, lua-format
|
||||||
|
msgid "%s’s awards:"
|
||||||
|
msgstr "Logros de %s:"
|
||||||
|
|
||||||
|
#: api.lua chat_commands.lua
|
||||||
|
#, lua-format
|
||||||
|
msgid "%s: %s"
|
||||||
|
msgstr "%s: %s"
|
||||||
|
|
||||||
|
#: sfinv.lua unified_inventory.lua
|
||||||
|
msgid "Awards"
|
||||||
|
msgstr "Logros"
|
||||||
|
|
||||||
|
#: triggers.lua
|
||||||
|
msgid "@1/@2 dug"
|
||||||
|
msgstr "@1/@2 excavados"
|
||||||
|
|
||||||
|
#. Translators: @1 is count, @2 is description.
|
||||||
|
#: triggers.lua
|
||||||
|
msgid "Mine: @2"
|
||||||
|
msgid_plural "Mine: @1×@2"
|
||||||
|
msgstr[0] "Excavar: @2"
|
||||||
|
msgstr[1] "Excavar: @1×@2"
|
||||||
|
|
||||||
|
#: triggers.lua
|
||||||
|
msgid "Mine @1 block."
|
||||||
|
msgid_plural "Mine @1 blocks."
|
||||||
|
msgstr[0] "Excavar un bloque."
|
||||||
|
msgstr[1] "Excavar @1 bloques."
|
||||||
|
|
||||||
|
#: triggers.lua
|
||||||
|
msgid "@1/@2 placed"
|
||||||
|
msgstr "@1/@2 colocados"
|
||||||
|
|
||||||
|
#. Translators: @1 is count, @2 is description.
|
||||||
|
#: triggers.lua
|
||||||
|
msgid "Place: @2"
|
||||||
|
msgid_plural "Place: @1×@2"
|
||||||
|
msgstr[0] "Colocar: @2"
|
||||||
|
msgstr[1] "Colocar: @1×@2"
|
||||||
|
|
||||||
|
#: triggers.lua
|
||||||
|
msgid "Place a block."
|
||||||
|
msgid_plural "Place @1 blocks."
|
||||||
|
msgstr[0] "Colocar un bloque."
|
||||||
|
msgstr[1] "Colocar @1 bloques."
|
||||||
|
|
||||||
|
#: triggers.lua
|
||||||
|
msgid "@1/@2 eaten"
|
||||||
|
msgstr "@1/@2 comidos"
|
||||||
|
|
||||||
|
#. Translators: @1 is count, @2 is description.
|
||||||
|
#: triggers.lua
|
||||||
|
msgid "Eat: @2"
|
||||||
|
msgid_plural "Eat: @1×@2"
|
||||||
|
msgstr[0] "Comer: @2"
|
||||||
|
msgstr[1] "Comer: @1×@2"
|
||||||
|
|
||||||
|
#: triggers.lua
|
||||||
|
msgid "Eat an item."
|
||||||
|
msgid_plural "Eat @1 items."
|
||||||
|
msgstr[0] "Comer un objeto."
|
||||||
|
msgstr[1] "Comer @1 objetos."
|
||||||
|
|
||||||
|
#: triggers.lua
|
||||||
|
msgid "@1/@2 deaths"
|
||||||
|
msgstr "@1/@2 muertes"
|
||||||
|
|
||||||
|
#: triggers.lua
|
||||||
|
msgid "Die."
|
||||||
|
msgid_plural "Die @1 times."
|
||||||
|
msgstr[0] "Morir."
|
||||||
|
msgstr[1] "Morir @1 veces."
|
||||||
|
|
||||||
|
#: triggers.lua
|
||||||
|
msgid "@1/@2 chat messages"
|
||||||
|
msgstr "@1/@2 conversaciones"
|
||||||
|
|
||||||
|
#: triggers.lua
|
||||||
|
msgid "Write something in chat."
|
||||||
|
msgid_plural "Write @1 chat messages."
|
||||||
|
msgstr[0] "Escribir algo."
|
||||||
|
msgstr[1] "Escribir @1 mensajes."
|
||||||
|
|
||||||
|
#: triggers.lua
|
||||||
|
msgid "@1/@2 game joins"
|
||||||
|
msgstr "@1/@2 veces unido"
|
||||||
|
|
||||||
|
#: triggers.lua
|
||||||
|
msgid "Join the game."
|
||||||
|
msgid_plural "Join the game @1 times."
|
||||||
|
msgstr[0] "Unirse al juego."
|
||||||
|
msgstr[1] "Unirse al juego @1 veces."
|
||||||
|
|
||||||
|
#: triggers.lua
|
||||||
|
msgid "@1/@2 crafted"
|
||||||
|
msgstr "@1/@2 elaborado"
|
||||||
|
|
||||||
|
#. Translators: @1 is count, @2 is description.
|
||||||
|
#: triggers.lua
|
||||||
|
msgid "Craft: @2"
|
||||||
|
msgid_plural "Craft: @1×@2"
|
||||||
|
msgstr[0] "Elaborar: @2"
|
||||||
|
msgstr[1] "Elaborar: %1×@2"
|
||||||
|
|
||||||
|
#: triggers.lua
|
||||||
|
msgid "Craft an item."
|
||||||
|
msgid_plural "Craft @1 items."
|
||||||
|
msgstr[0] "Elaborar un objeto."
|
||||||
|
msgstr[1] "Elaborar @1 objetos."
|
||||||
|
|
||||||
|
#: init.lua
|
||||||
|
msgid "Saint-Maclou"
|
||||||
|
msgstr "Saint-Maclou"
|
||||||
|
|
||||||
|
#: init.lua
|
||||||
|
msgid "Place 20 coal checkers."
|
||||||
|
msgstr "Colocar 20 baldosas de ajedrez de carbón."
|
||||||
|
|
||||||
|
#: init.lua
|
||||||
|
msgid "Castorama"
|
||||||
|
msgstr "Castorama"
|
||||||
|
|
||||||
|
#: init.lua
|
||||||
|
msgid "Place 20 iron checkers."
|
||||||
|
msgstr "Colocar 20 baldosas de ajedrez de hierro."
|
||||||
|
|
||||||
|
#: init.lua
|
||||||
|
msgid "Sam the Trapper"
|
||||||
|
msgstr "Sam el Atrapador"
|
||||||
|
|
||||||
|
#: init.lua
|
||||||
|
msgid "Place 2 trap stones."
|
||||||
|
msgstr "Colocar 2 piedras trampa."
|
||||||
|
|
||||||
|
#: init.lua
|
||||||
|
msgid "Backpacker"
|
||||||
|
msgstr "Mochilero"
|
||||||
|
|
||||||
|
#: init.lua
|
||||||
|
msgid "Craft 4 large bags."
|
||||||
|
msgstr "Elaborar 4 bolsas grandes."
|
||||||
|
|
||||||
|
#: init.lua
|
||||||
|
msgid "Pyromaniac"
|
||||||
|
msgstr "Piromaníaco"
|
||||||
|
|
||||||
|
#: init.lua
|
||||||
|
msgid "Craft 8 times flint and steel."
|
||||||
|
msgstr "Elaborar pedernal y hierro 8 veces."
|
||||||
|
|
||||||
|
#: init.lua
|
||||||
|
msgid "Firefighter"
|
||||||
|
msgstr "Bombero"
|
||||||
|
|
||||||
|
#: init.lua
|
||||||
|
msgid "Put out 1000 fires."
|
||||||
|
msgstr "Apagar 1000 incendios."
|
||||||
|
|
||||||
|
#: init.lua
|
||||||
|
msgid "Light It Up"
|
||||||
|
msgstr "Ilumínalo"
|
||||||
|
|
||||||
|
#: init.lua
|
||||||
|
msgid "Place 100 torches."
|
||||||
|
msgstr "Colocar 100 antorchas."
|
||||||
|
|
||||||
|
#: init.lua
|
||||||
|
msgid "Well Lit"
|
||||||
|
msgstr "Bien Iluminado"
|
||||||
|
|
||||||
|
#: init.lua
|
||||||
|
msgid "Place 1,000 torches."
|
||||||
|
msgstr "Colocar 1.000 antorchas."
|
||||||
|
|
||||||
|
#: init.lua
|
||||||
|
msgid "Really Well Lit"
|
||||||
|
msgstr "Realmente Bien Iluminado"
|
||||||
|
|
||||||
|
#: init.lua
|
||||||
|
msgid "Craft 10 mese lamps."
|
||||||
|
msgstr "Elaborar 10 lámparas de MESE."
|
||||||
|
|
||||||
|
#: init.lua
|
||||||
|
msgid "Outpost"
|
||||||
|
msgstr "Puesto de avanzada"
|
||||||
|
|
||||||
|
#: init.lua
|
||||||
|
msgid "Craft 200 stone bricks."
|
||||||
|
msgstr "Elaborar 200 ladrillos de piedra."
|
||||||
|
|
||||||
|
#: init.lua
|
||||||
|
msgid "Watchtower"
|
||||||
|
msgstr "Torre del vigía"
|
||||||
|
|
||||||
|
#: init.lua
|
||||||
|
msgid "Craft 800 stone bricks."
|
||||||
|
msgstr "Elaborar 800 ladrillos de piedra."
|
||||||
|
|
||||||
|
#: init.lua
|
||||||
|
msgid "Fortress"
|
||||||
|
msgstr "Fortaleza"
|
||||||
|
|
||||||
|
#: init.lua
|
||||||
|
msgid "Craft 3,200 stone bricks."
|
||||||
|
msgstr "Elaborar 3.200 ladrillos de piedra."
|
||||||
|
|
||||||
|
#: init.lua
|
||||||
|
msgid "Desert Dweller"
|
||||||
|
msgstr "Morador Desértico"
|
||||||
|
|
||||||
|
#: init.lua
|
||||||
|
msgid "Craft 400 desert stone bricks."
|
||||||
|
msgstr "Elaborar 400 ladrillos de piedra desértica."
|
||||||
|
|
||||||
|
#: init.lua
|
||||||
|
msgid "Pharaoh"
|
||||||
|
msgstr "Faraón"
|
||||||
|
|
||||||
|
#: init.lua
|
||||||
|
msgid "Craft 100 sandstone bricks."
|
||||||
|
msgstr "Elaborar 200 ladrillos de arenisca."
|
||||||
|
|
||||||
|
#: init.lua
|
||||||
|
msgid "Little Library"
|
||||||
|
msgstr "Pequeña Biblioteca"
|
||||||
|
|
||||||
|
#: init.lua
|
||||||
|
msgid "Craft 7 bookshelves."
|
||||||
|
msgstr "Elaborar 7 libreros."
|
||||||
|
|
||||||
|
#: init.lua
|
||||||
|
msgid "Lava and Water"
|
||||||
|
msgstr "Lava y Agua"
|
||||||
|
|
||||||
|
#: init.lua
|
||||||
|
msgid "Mine your first obsidian."
|
||||||
|
msgstr "Excavar tu primera obsidiana."
|
||||||
|
|
||||||
|
#: init.lua
|
||||||
|
msgid "Obsessed with Obsidian"
|
||||||
|
msgstr "Obsesionado con la Obsidiana"
|
||||||
|
|
||||||
|
#: init.lua
|
||||||
|
msgid "Mine 50 obsidian."
|
||||||
|
msgstr "Excavar 50 obsidianas."
|
||||||
|
|
||||||
|
#: init.lua
|
||||||
|
msgid "Lava Miner"
|
||||||
|
msgstr "Minero de Lava"
|
||||||
|
|
||||||
|
#: init.lua
|
||||||
|
msgid "Mine any block while being very close to lava."
|
||||||
|
msgstr "Excavar un bloque cerca de lava."
|
||||||
|
|
||||||
|
#: init.lua
|
||||||
|
msgid "On The Way"
|
||||||
|
msgstr "En Camino"
|
||||||
|
|
||||||
|
#: init.lua
|
||||||
|
msgid "Place 100 rails."
|
||||||
|
msgstr "Colocar 100 rieles."
|
||||||
|
|
||||||
|
#: init.lua
|
||||||
|
msgid "First Day in the Woods"
|
||||||
|
msgstr "Primer Día en el Bosque"
|
||||||
|
|
||||||
|
#: init.lua
|
||||||
|
msgid "Dig 6 tree blocks."
|
||||||
|
msgstr "Cortar 6 árboles."
|
||||||
|
|
||||||
|
#: init.lua
|
||||||
|
msgid "Lumberjack"
|
||||||
|
msgstr "Leñador"
|
||||||
|
|
||||||
|
#: init.lua
|
||||||
|
msgid "Dig 36 tree blocks."
|
||||||
|
msgstr "Cortar 36 árboles."
|
||||||
|
|
||||||
|
#: init.lua
|
||||||
|
msgid "Semi-pro Lumberjack"
|
||||||
|
msgstr "Leñador semi-profesional"
|
||||||
|
|
||||||
|
#: init.lua
|
||||||
|
msgid "Dig 216 tree blocks."
|
||||||
|
msgstr "Cortar 216 árboles."
|
||||||
|
|
||||||
|
#: init.lua
|
||||||
|
msgid "Professional Lumberjack"
|
||||||
|
msgstr "Leñador profesional"
|
||||||
|
|
||||||
|
#: init.lua
|
||||||
|
msgid "Dig 1,296 tree blocks."
|
||||||
|
msgstr "Cortar 1.296 árboles."
|
||||||
|
|
||||||
|
#: init.lua
|
||||||
|
msgid "Junglebaby"
|
||||||
|
msgstr "Bebé de la Selva"
|
||||||
|
|
||||||
|
#: init.lua
|
||||||
|
msgid "Dig 100 jungle tree blocks."
|
||||||
|
msgstr "Cortar 100 árboles selváticos."
|
||||||
|
|
||||||
|
#: init.lua
|
||||||
|
msgid "Jungleman"
|
||||||
|
msgstr "Hombre de la Selva"
|
||||||
|
|
||||||
|
#: init.lua
|
||||||
|
msgid "Dig 1,000 jungle tree blocks."
|
||||||
|
msgstr "Cortar 1.000 árboles selváticos."
|
||||||
|
|
||||||
|
#: init.lua
|
||||||
|
msgid "First Mese Find"
|
||||||
|
msgstr "Primer Encuentro de MESE"
|
||||||
|
|
||||||
|
#: init.lua
|
||||||
|
msgid "Mine your first mese ore."
|
||||||
|
msgstr "Excava tu primer mineral de MESE."
|
||||||
|
|
||||||
|
#: init.lua
|
||||||
|
msgid "Mese Mastery"
|
||||||
|
msgstr "Maestría de MESE"
|
||||||
|
|
||||||
|
#: init.lua
|
||||||
|
msgid "Mine a mese block."
|
||||||
|
msgstr "Excava tu primer bloque de MESE."
|
||||||
|
|
||||||
|
#: init.lua
|
||||||
|
msgid "You’re a copper"
|
||||||
|
msgstr "Eres un cobre"
|
||||||
|
|
||||||
|
#: init.lua
|
||||||
|
msgid "Dig 1,000 copper ores."
|
||||||
|
msgstr "Excavar 1.000 minerales de cobre"
|
||||||
|
|
||||||
|
#: init.lua
|
||||||
|
msgid "A Cat in a Pop-Tart?!"
|
||||||
|
msgstr "¡¿Un Gato en un Pop-Tart?!"
|
||||||
|
|
||||||
|
#: init.lua
|
||||||
|
msgid "Mine a nyan cat."
|
||||||
|
msgstr "Excavar un Gato Nyan."
|
||||||
|
|
||||||
|
#: init.lua
|
||||||
|
msgid "Mini Miner"
|
||||||
|
msgstr "Mini Minero"
|
||||||
|
|
||||||
|
#: init.lua
|
||||||
|
msgid "Dig 100 stone blocks."
|
||||||
|
msgstr "Excavar 100 bloques de piedra."
|
||||||
|
|
||||||
|
#: init.lua
|
||||||
|
msgid "Hardened Miner"
|
||||||
|
msgstr "Minero Curtido"
|
||||||
|
|
||||||
|
#: init.lua
|
||||||
|
msgid "Dig 1,000 stone blocks."
|
||||||
|
msgstr "Excavar 1.000 bloques de piedra."
|
||||||
|
|
||||||
|
#: init.lua
|
||||||
|
msgid "Master Miner"
|
||||||
|
msgstr "Minero Maestro"
|
||||||
|
|
||||||
|
#: init.lua
|
||||||
|
msgid "Dig 10,000 stone blocks."
|
||||||
|
msgstr "Excavar 10.000 bloques de piedra."
|
||||||
|
|
||||||
|
#: init.lua
|
||||||
|
msgid "Marchand De Sable"
|
||||||
|
msgstr "Marchand De Sable"
|
||||||
|
|
||||||
|
#: init.lua
|
||||||
|
msgid "Dig 1,000 sand."
|
||||||
|
msgstr "Cavar 1.000 bloques de arena."
|
||||||
|
|
||||||
|
#: init.lua
|
||||||
|
msgid "Crafter of Sticks"
|
||||||
|
msgstr "Elaborador de Varitas"
|
||||||
|
|
||||||
|
#: init.lua
|
||||||
|
msgid "Craft 100 sticks."
|
||||||
|
msgstr "Elaborar 100 varitas."
|
||||||
|
|
||||||
|
#: init.lua
|
||||||
|
msgid "Jungle Discoverer"
|
||||||
|
msgstr "Descubridor de Selva"
|
||||||
|
|
||||||
|
#: init.lua
|
||||||
|
msgid "Mine your first jungle grass."
|
||||||
|
msgstr "Cortar tu primer pasto de selva."
|
||||||
|
|
||||||
|
#: init.lua
|
||||||
|
msgid "Grasslands Discoverer"
|
||||||
|
msgstr "Descubridor de Praderas"
|
||||||
|
|
||||||
|
#: init.lua
|
||||||
|
msgid "Mine some grass."
|
||||||
|
msgstr "Cortar un poco de pasto."
|
||||||
|
|
||||||
|
#: init.lua
|
||||||
|
msgid "Savannah Discoverer"
|
||||||
|
msgstr "Descubridor de Savana"
|
||||||
|
|
||||||
|
#: init.lua
|
||||||
|
msgid "Mine some dry grass."
|
||||||
|
msgstr "Cortar un poco de pasto seco."
|
||||||
|
|
||||||
|
#: init.lua
|
||||||
|
msgid "Desert Discoverer"
|
||||||
|
msgstr "Descubridor del Desierto"
|
||||||
|
|
||||||
|
#: init.lua
|
||||||
|
msgid "Mine your first cactus."
|
||||||
|
msgstr "Cortar tu primer cácto."
|
||||||
|
|
||||||
|
#: init.lua
|
||||||
|
msgid "Far Lands"
|
||||||
|
msgstr "Tierras Lejanas"
|
||||||
|
|
||||||
|
#: init.lua
|
||||||
|
msgid "Mine your first dry shrub."
|
||||||
|
msgstr "Cortar tu primer arbusto seco"
|
||||||
|
|
||||||
|
#: init.lua
|
||||||
|
msgid "Glacier Discoverer"
|
||||||
|
msgstr "Descubridor del Glaciar"
|
||||||
|
|
||||||
|
#: init.lua
|
||||||
|
msgid "Mine your first ice."
|
||||||
|
msgstr "Romper tu primer bloque de hielo."
|
||||||
|
|
||||||
|
#: init.lua
|
||||||
|
msgid "Very Simple Snow Man"
|
||||||
|
msgstr "Muñeco de Nieve Muy Simple"
|
||||||
|
|
||||||
|
#: init.lua
|
||||||
|
msgid "Place two snow blocks."
|
||||||
|
msgstr "Colocar dos bloques de nieve."
|
||||||
|
|
||||||
|
#: init.lua
|
||||||
|
msgid "First Gold Find"
|
||||||
|
msgstr "Primer Encuentro de Oro"
|
||||||
|
|
||||||
|
#: init.lua
|
||||||
|
msgid "Mine your first gold ore."
|
||||||
|
msgstr "Excavar tu primer pepita de oro."
|
||||||
|
|
||||||
|
#: init.lua
|
||||||
|
msgid "Gold Rush"
|
||||||
|
msgstr "Fiebre del Oro"
|
||||||
|
|
||||||
|
#: init.lua
|
||||||
|
msgid "Mine 45 gold ores."
|
||||||
|
msgstr "Excavar 45 pepitas de oro."
|
||||||
|
|
||||||
|
#: init.lua
|
||||||
|
msgid "Wow, I am Diamonds!"
|
||||||
|
msgstr "¡Guau, Soy Diamantes!"
|
||||||
|
|
||||||
|
#: init.lua
|
||||||
|
msgid "Mine your first diamond ore."
|
||||||
|
msgstr "Excava tu primer diamante."
|
||||||
|
|
||||||
|
#: init.lua
|
||||||
|
msgid "Girl's Best Friend"
|
||||||
|
msgstr "El Mejor Amigo de Las Mujeres"
|
||||||
|
|
||||||
|
#: init.lua
|
||||||
|
msgid "Mine 18 diamond ores."
|
||||||
|
msgstr "Excava 10 diamantes."
|
||||||
|
|
||||||
|
#: init.lua
|
||||||
|
msgid "Hardest Block on Earth"
|
||||||
|
msgstr "El Bloque Más Duro Sobre La Tierra"
|
||||||
|
|
||||||
|
#: init.lua
|
||||||
|
msgid "Craft a diamond block."
|
||||||
|
msgstr "Elaborar un bloque de diamante."
|
||||||
|
|
||||||
|
#: init.lua
|
||||||
|
msgid "In the Dungeon"
|
||||||
|
msgstr "En Las Mazmorras"
|
||||||
|
|
||||||
|
#: init.lua
|
||||||
|
msgid "Mine a mossy cobblestone."
|
||||||
|
msgstr "Excavar unos adoquines musgosos."
|
||||||
|
|
||||||
|
#: init.lua
|
||||||
|
msgid "Smelter"
|
||||||
|
msgstr "Fundidor"
|
||||||
|
|
||||||
|
#: init.lua
|
||||||
|
msgid "Craft 10 furnaces."
|
||||||
|
msgstr "Elaborar 10 hornos."
|
||||||
|
|
||||||
|
#: init.lua
|
||||||
|
msgid "Treasurer"
|
||||||
|
msgstr "Tesorero"
|
||||||
|
|
||||||
|
#: init.lua
|
||||||
|
msgid "Craft 15 chests."
|
||||||
|
msgstr "Elaborar 15 cofres."
|
||||||
|
|
||||||
|
#: init.lua
|
||||||
|
msgid "Bankier"
|
||||||
|
msgstr "Banquero"
|
||||||
|
|
||||||
|
#: init.lua
|
||||||
|
msgid "Craft 30 locked chests."
|
||||||
|
msgstr "Elaborar 30 bloques cerrados."
|
||||||
|
|
||||||
|
#: init.lua
|
||||||
|
msgid "Bricker"
|
||||||
|
msgstr "Ladrillero"
|
||||||
|
|
||||||
|
#: init.lua
|
||||||
|
msgid "Craft 200 brick blocks."
|
||||||
|
msgstr "Elaborar 200 bloques de ladrillo."
|
||||||
|
|
||||||
|
#: init.lua
|
||||||
|
msgid "House of Obsidian"
|
||||||
|
msgstr "Casa de Obsidiana"
|
||||||
|
|
||||||
|
#: init.lua
|
||||||
|
msgid "Craft 100 obsidian bricks."
|
||||||
|
msgstr "Elaborar 100 ladrillos de obsidiana."
|
||||||
|
|
||||||
|
#: init.lua
|
||||||
|
msgid "Build a Cave"
|
||||||
|
msgstr "Construye Una Cueva"
|
||||||
|
|
||||||
|
#: init.lua
|
||||||
|
msgid "Place 100 stone."
|
||||||
|
msgstr "Coloca 100 piedras."
|
||||||
|
|
||||||
|
#: init.lua
|
||||||
|
msgid "Long Ladder"
|
||||||
|
msgstr "Escalerilla Larga"
|
||||||
|
|
||||||
|
#: init.lua
|
||||||
|
msgid "Place 400 wooden ladders."
|
||||||
|
msgstr "Coloca 400 escalerillas de madera."
|
||||||
|
|
||||||
|
#: init.lua
|
||||||
|
msgid "Industrial Age"
|
||||||
|
msgstr "Era Industrial"
|
||||||
|
|
||||||
|
#: init.lua
|
||||||
|
msgid "Place 40 steel ladders."
|
||||||
|
msgstr "Coloca 40 escalerillas de acero."
|
||||||
|
|
||||||
|
#: init.lua
|
||||||
|
msgid "Yummy!"
|
||||||
|
msgstr "¡Qué Rico!"
|
||||||
|
|
||||||
|
#: init.lua
|
||||||
|
msgid "Eat 80 apples."
|
||||||
|
msgstr "Come 80 manzanas."
|
||||||
|
|
||||||
|
# Intentionally marked as fuzzy.
|
||||||
|
#: init.lua
|
||||||
|
#, fuzzy
|
||||||
|
msgid "Glasser"
|
||||||
|
msgstr "Vidriero"
|
||||||
|
|
||||||
|
#: init.lua
|
||||||
|
msgid "Craft 14 vessels shelves."
|
||||||
|
msgstr "Elabora 14 estanterías para botellas."
|
||||||
|
|
||||||
|
#: init.lua
|
||||||
|
msgid "Farming Skills Acquired"
|
||||||
|
msgstr "Habilidades de Granja Adquiridas"
|
||||||
|
|
||||||
|
#: init.lua
|
||||||
|
msgid "Harvest a fully grown wheat plant."
|
||||||
|
msgstr "Cosecha una plantas de trigo madura."
|
||||||
|
|
||||||
|
#: init.lua
|
||||||
|
msgid "Field Worker"
|
||||||
|
msgstr "Trabajador de Campo"
|
||||||
|
|
||||||
|
#: init.lua
|
||||||
|
msgid "Harvest 25 fully grown wheat plants."
|
||||||
|
msgstr "Cosecha 25 plantas de trigo maduras."
|
||||||
|
|
||||||
|
#: init.lua
|
||||||
|
msgid "Aspiring Farmer"
|
||||||
|
msgstr "Aspirante a Granjero"
|
||||||
|
|
||||||
|
#: init.lua
|
||||||
|
msgid "Harvest 125 fully grown wheat plants."
|
||||||
|
msgstr "Cosecha 125 plantas de trigo maduras."
|
||||||
|
|
||||||
|
#: init.lua
|
||||||
|
msgid "Wheat Magnate"
|
||||||
|
msgstr "Magnate del Maíz"
|
||||||
|
|
||||||
|
#: init.lua
|
||||||
|
msgid "Harvest 625 fully grown wheat plants."
|
||||||
|
msgstr "Cosecha 625 plantas de trigo maduras."
|
||||||
|
|
||||||
|
#: init.lua
|
||||||
|
msgid "Baker"
|
||||||
|
msgstr "Panadero"
|
||||||
|
|
||||||
|
#: init.lua
|
||||||
|
msgid "Eat 10 loaves of bread."
|
||||||
|
msgstr "Come 10 rebanadas de pan."
|
||||||
|
|
||||||
|
#: init.lua
|
||||||
|
msgid "Wool Over Your Eyes"
|
||||||
|
msgstr "Lana Sobre Tus Ojos"
|
||||||
|
|
||||||
|
#: init.lua
|
||||||
|
msgid "Craft 250 white wool."
|
||||||
|
msgstr "Elabora 250 bloques de lana blanca."
|
||||||
|
|
||||||
|
#: init.lua
|
||||||
|
msgid "Hotelier"
|
||||||
|
msgstr "Hotelero"
|
||||||
|
|
||||||
|
#: init.lua
|
||||||
|
msgid "Craft 15 fancy beds."
|
||||||
|
msgstr "Elabora 15 camas de lujo."
|
||||||
|
|
||||||
|
#: init.lua
|
||||||
|
msgid "Filthy Rich"
|
||||||
|
msgstr "Sucio Rico"
|
||||||
|
|
||||||
|
#: init.lua
|
||||||
|
msgid "Craft 24 gold block stairs."
|
||||||
|
msgstr "Elabora 24 escaleras de bloque de oro."
|
||||||
|
|
||||||
|
#: init.lua
|
||||||
|
msgid "Roses Are Red"
|
||||||
|
msgstr "Las Rosas Son Rojas"
|
||||||
|
|
||||||
|
#: init.lua
|
||||||
|
msgid "Craft 400 red dyes."
|
||||||
|
msgstr "Elabora 400 colorantes rojos."
|
||||||
|
|
||||||
|
#: init.lua
|
||||||
|
msgid "Dandelions are Yellow"
|
||||||
|
msgstr "Los Dientes de León Son Amarillos"
|
||||||
|
|
||||||
|
#: init.lua
|
||||||
|
msgid "Craft 400 yellow dyes."
|
||||||
|
msgstr "Elabora 400 colorantes amarillos."
|
||||||
|
|
||||||
|
#: init.lua
|
||||||
|
msgid "Geraniums are Blue"
|
||||||
|
msgstr "Los Geranios Son Azules"
|
||||||
|
|
||||||
|
#: init.lua
|
||||||
|
msgid "Craft 400 blue dyes."
|
||||||
|
msgstr "Elabora 400 colorantes azules."
|
||||||
|
|
||||||
|
#: init.lua
|
||||||
|
msgid "White Color Stock"
|
||||||
|
msgstr "Reserva de Color Blanco"
|
||||||
|
|
||||||
|
#: init.lua
|
||||||
|
msgid "Craft 100 white dyes."
|
||||||
|
msgstr "Elabora 100 colorantes blancos."
|
||||||
|
|
||||||
|
#: init.lua
|
||||||
|
msgid "Tasty Mushrooms"
|
||||||
|
msgstr "Ricos Hongos"
|
||||||
|
|
||||||
|
#: init.lua
|
||||||
|
msgid "Eat 3 brown mushrooms."
|
||||||
|
msgstr "Come 3 hongos marrones."
|
||||||
|
|
||||||
|
#: init.lua
|
||||||
|
msgid "Mushroom Lover"
|
||||||
|
msgstr "Amante de los Hongos"
|
||||||
|
|
||||||
|
#: init.lua
|
||||||
|
msgid "Eat 33 brown mushrooms."
|
||||||
|
msgstr "Come 33 hongos marrones."
|
||||||
|
|
||||||
|
#: init.lua
|
||||||
|
msgid "Underground Mushroom Farmer"
|
||||||
|
msgstr "Granjero de Hongos Subterráneo"
|
||||||
|
|
||||||
|
#: init.lua
|
||||||
|
msgid "Eat 333 brown mushrooms."
|
||||||
|
msgstr "Come 333 hongos marrones."
|
||||||
|
|
||||||
|
# Nota: "Builder" y "Constructor" se traducen a "Constructor",
|
||||||
|
# así que lo traduje de ésta manera para diferenciar.
|
||||||
|
#: init.lua
|
||||||
|
msgid "Builder"
|
||||||
|
msgstr "Hacedor"
|
||||||
|
|
||||||
|
#: init.lua
|
||||||
|
msgid "Constructor"
|
||||||
|
msgstr "Constructor"
|
||||||
|
|
||||||
|
#: init.lua
|
||||||
|
msgid "Architect"
|
||||||
|
msgstr "Arquitecto"
|
||||||
|
|
||||||
|
#: init.lua
|
||||||
|
msgid "Master Architect"
|
||||||
|
msgstr "Maestro Arquitecto"
|
||||||
|
|
||||||
|
#: chat_commands.lua
|
||||||
|
msgid "[c|clear|disable|enable]"
|
||||||
|
msgstr "[c|clear|disable|enable]"
|
||||||
|
|
||||||
|
#: chat_commands.lua
|
||||||
|
msgid "Show, clear, disable or enable your achievements"
|
||||||
|
msgstr "Mostrar, limpiar, deshabilitar o habilitar tus logros"
|
||||||
|
|
||||||
|
#: chat_commands.lua
|
||||||
|
msgid ""
|
||||||
|
"All your awards and statistics have been cleared. You can now start again."
|
||||||
|
msgstr ""
|
||||||
|
"Todos tus logros y estadísticas han sido borrados. Puedes iniciar nuevamente."
|
||||||
|
|
||||||
|
#: chat_commands.lua
|
||||||
|
msgid "You have disabled your achievements."
|
||||||
|
msgstr "Has deshabilitado tus logros."
|
||||||
|
|
||||||
|
#: chat_commands.lua
|
||||||
|
msgid "You have enabled your achievements."
|
||||||
|
msgstr "Has habilitado tus logros."
|
||||||
|
|
||||||
|
#: chat_commands.lua
|
||||||
|
msgid "<achievement ID>"
|
||||||
|
msgstr "<ID logro>"
|
||||||
|
|
||||||
|
#: chat_commands.lua
|
||||||
|
msgid "Show details of an achievement"
|
||||||
|
msgstr "Muestra los detalles de un logro"
|
||||||
|
|
||||||
|
#: chat_commands.lua
|
||||||
|
msgid "Achievement not found."
|
||||||
|
msgstr "Logro no encontrado."
|
||||||
|
|
||||||
|
#: chat_commands.lua
|
||||||
|
msgid "<name>"
|
||||||
|
msgstr "<nombre>"
|
||||||
|
|
||||||
|
#: chat_commands.lua
|
||||||
|
msgid "Get the achievements statistics for the given player or yourself"
|
||||||
|
msgstr "Obtener las estadísticas y logros del jugador dado"
|
|
@ -0,0 +1,818 @@
|
||||||
|
# French translations for PACKAGE package.
|
||||||
|
# Copyright (C) 2017 THE PACKAGE'S COPYRIGHT HOLDER
|
||||||
|
# This file is distributed under the same license as the PACKAGE package.
|
||||||
|
# xisd, 2017.
|
||||||
|
#
|
||||||
|
msgid ""
|
||||||
|
msgstr ""
|
||||||
|
"Project-Id-Version: PACKAGE VERSION\n"
|
||||||
|
"Report-Msgid-Bugs-To: \n"
|
||||||
|
"POT-Creation-Date: 2017-02-21 05:50-0300\n"
|
||||||
|
"PO-Revision-Date: 2017-02-21 05:50-0300\n"
|
||||||
|
"Last-Translator: xisd\n"
|
||||||
|
"Language-Team: French\n"
|
||||||
|
"Language: fr\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"
|
||||||
|
|
||||||
|
#: api.lua
|
||||||
|
msgid "Secret Achievement Unlocked:"
|
||||||
|
msgstr "Réussite Secrète Débloquée :"
|
||||||
|
|
||||||
|
#: api.lua
|
||||||
|
msgid "Achievement Unlocked:"
|
||||||
|
msgstr "Réussite Débloquée :"
|
||||||
|
|
||||||
|
#: api.lua
|
||||||
|
#, lua-format
|
||||||
|
msgid "Secret Achievement Unlocked: %s"
|
||||||
|
msgstr "Réussite Secrète Débloquée : %s"
|
||||||
|
|
||||||
|
#: api.lua
|
||||||
|
#, lua-format
|
||||||
|
msgid "Achievement Unlocked: %s"
|
||||||
|
msgstr "Réussite Débloquée : %s"
|
||||||
|
|
||||||
|
#: api.lua
|
||||||
|
msgid "Secret Achievement Unlocked!"
|
||||||
|
msgstr "Réussite Secrète Débloquée !"
|
||||||
|
|
||||||
|
#: api.lua
|
||||||
|
msgid "Achievement Unlocked!"
|
||||||
|
msgstr "Réussite Débloquée !"
|
||||||
|
|
||||||
|
#: api.lua
|
||||||
|
msgid "Error: No awards available."
|
||||||
|
msgstr "Erreur : Aucun trophée disponible"
|
||||||
|
|
||||||
|
#: api.lua
|
||||||
|
msgid "OK"
|
||||||
|
msgstr "OK"
|
||||||
|
|
||||||
|
#: api.lua
|
||||||
|
msgid "(Secret Award)"
|
||||||
|
msgstr "(Trophée Secret)"
|
||||||
|
|
||||||
|
#: api.lua
|
||||||
|
msgid "Unlock this award to find out what it is."
|
||||||
|
msgstr "Débloque ce trophée pour découvrir ce que c'est."
|
||||||
|
|
||||||
|
#: api.lua
|
||||||
|
#, lua-format
|
||||||
|
msgid "%s (got)"
|
||||||
|
msgstr "%s (obtenu)"
|
||||||
|
|
||||||
|
#: api.lua
|
||||||
|
msgid "You've disabled awards. Type /awards enable to reenable."
|
||||||
|
msgstr "Vous avez désactivé les trophées. Tapez '/awards enable' pour les réactiver."
|
||||||
|
|
||||||
|
#: api.lua
|
||||||
|
msgid "You have not unlocked any awards."
|
||||||
|
msgstr "Vous n'avez encore débloqué aucun trophée."
|
||||||
|
|
||||||
|
#: api.lua
|
||||||
|
#, lua-format
|
||||||
|
msgid "%s’s awards:"
|
||||||
|
msgstr "Les trophées de %s :"
|
||||||
|
|
||||||
|
#: api.lua chat_commands.lua
|
||||||
|
#, lua-format
|
||||||
|
msgid "%s: %s"
|
||||||
|
msgstr "%s : %s"
|
||||||
|
|
||||||
|
#: sfinv.lua unified_inventory.lua
|
||||||
|
msgid "Awards"
|
||||||
|
msgstr "Trophées"
|
||||||
|
|
||||||
|
#: triggers.lua
|
||||||
|
msgid "@1/@2 dug"
|
||||||
|
msgstr "@1/@2 creusés"
|
||||||
|
|
||||||
|
#. Translators: @1 is count, @2 is description.
|
||||||
|
#: triggers.lua
|
||||||
|
msgid "Mine: @2"
|
||||||
|
msgid_plural "Mine: @1×@2"
|
||||||
|
msgstr[0] "Mine : @2"
|
||||||
|
msgstr[1] "Mine : @1×@2"
|
||||||
|
|
||||||
|
#: triggers.lua
|
||||||
|
msgid "Mine @1 block."
|
||||||
|
msgid_plural "Mine @1 blocks."
|
||||||
|
msgstr[0] "Creuse @1 bloc."
|
||||||
|
msgstr[1] "Creuse @1 blocs."
|
||||||
|
|
||||||
|
#: triggers.lua
|
||||||
|
msgid "@1/@2 placed"
|
||||||
|
msgstr "@1/@2 placés"
|
||||||
|
|
||||||
|
#. Translators: @1 is count, @2 is description.
|
||||||
|
#: triggers.lua
|
||||||
|
msgid "Place: @2"
|
||||||
|
msgid_plural "Place: @1×@2"
|
||||||
|
msgstr[0] "Place : @2"
|
||||||
|
msgstr[1] "Place : @1×@2"
|
||||||
|
|
||||||
|
#: triggers.lua
|
||||||
|
msgid "Place a block."
|
||||||
|
msgid_plural "Place @1 blocks."
|
||||||
|
msgstr[0] "Place un bloc."
|
||||||
|
msgstr[1] "Place @1 blocs."
|
||||||
|
|
||||||
|
#: triggers.lua
|
||||||
|
msgid "@1/@2 eaten"
|
||||||
|
msgstr "@1/@2 Mangés"
|
||||||
|
|
||||||
|
#. Translators: @1 is count, @2 is description.
|
||||||
|
#: triggers.lua
|
||||||
|
msgid "Eat: @2"
|
||||||
|
msgid_plural "Eat: @1×@2"
|
||||||
|
msgstr[0] "Mange : @2"
|
||||||
|
msgstr[1] "Mange : @1×@2"
|
||||||
|
|
||||||
|
#: triggers.lua
|
||||||
|
msgid "Eat an item."
|
||||||
|
msgid_plural "Eat @1 items."
|
||||||
|
msgstr[0] "Mange quelque chose."
|
||||||
|
msgstr[1] "Mange @1 aliments."
|
||||||
|
|
||||||
|
#: triggers.lua
|
||||||
|
msgid "@1/@2 deaths"
|
||||||
|
msgstr "@1/@2 morts"
|
||||||
|
|
||||||
|
#: triggers.lua
|
||||||
|
msgid "Die."
|
||||||
|
msgid_plural "Die @1 times."
|
||||||
|
msgstr[0] "Mort·e."
|
||||||
|
msgstr[1] "Mort·e %d fois."
|
||||||
|
|
||||||
|
#: triggers.lua
|
||||||
|
msgid "@1/@2 chat messages"
|
||||||
|
msgstr "@1/@2 messages du chat"
|
||||||
|
|
||||||
|
#: triggers.lua
|
||||||
|
msgid "Write something in chat."
|
||||||
|
msgid_plural "Write @1 chat messages."
|
||||||
|
msgstr[0] "Écrit quelque chose dans le chat."
|
||||||
|
msgstr[1] "Écrit @1 messages dans le chat."
|
||||||
|
|
||||||
|
#: triggers.lua
|
||||||
|
msgid "@1/@2 game joins"
|
||||||
|
msgstr "@1/@2 connexions"
|
||||||
|
|
||||||
|
#: triggers.lua
|
||||||
|
msgid "Join the game."
|
||||||
|
msgid_plural "Join the game @1 times."
|
||||||
|
msgstr[0] "Connecte toi au jeu."
|
||||||
|
msgstr[1] "Connecte toi au jeu @1 fois."
|
||||||
|
|
||||||
|
#: triggers.lua
|
||||||
|
msgid "@1/@2 crafted"
|
||||||
|
msgstr "@1/@2 craftés"
|
||||||
|
|
||||||
|
#. Translators: @1 is count, @2 is description.
|
||||||
|
#: triggers.lua
|
||||||
|
msgid "Craft: @2"
|
||||||
|
msgid_plural "Craft: @1×@2"
|
||||||
|
msgstr[0] "Fabrique : @2"
|
||||||
|
msgstr[1] "Fabrique : @1×@2"
|
||||||
|
|
||||||
|
#: triggers.lua
|
||||||
|
msgid "Craft an item."
|
||||||
|
msgid_plural "Craft @1 items."
|
||||||
|
msgstr[0] "Confectionne un objet."
|
||||||
|
msgstr[1] "Confectionne @1 objets."
|
||||||
|
|
||||||
|
#: init.lua
|
||||||
|
msgid "Saint-Maclou"
|
||||||
|
msgstr "Saint-Maclou"
|
||||||
|
|
||||||
|
#: init.lua
|
||||||
|
msgid "Place 20 coal checkers."
|
||||||
|
msgstr "Place 20 damiers de charbon."
|
||||||
|
|
||||||
|
#: init.lua
|
||||||
|
msgid "Castorama"
|
||||||
|
msgstr "Castorama"
|
||||||
|
|
||||||
|
#: init.lua
|
||||||
|
msgid "Place 20 iron checkers."
|
||||||
|
msgstr "Place 20 damiers de fer."
|
||||||
|
|
||||||
|
#: init.lua
|
||||||
|
msgid "Sam the Trapper"
|
||||||
|
msgstr "Sam le Trappeur"
|
||||||
|
|
||||||
|
#: init.lua
|
||||||
|
msgid "Place 2 trap stones."
|
||||||
|
msgstr "Place 2 pièges de pierre."
|
||||||
|
|
||||||
|
#: init.lua
|
||||||
|
msgid "Backpacker"
|
||||||
|
msgstr "Randonneu·r·se"
|
||||||
|
|
||||||
|
#: init.lua
|
||||||
|
msgid "Craft 4 large bags."
|
||||||
|
msgstr "Confectionne 4 grands sacs"
|
||||||
|
|
||||||
|
#: init.lua
|
||||||
|
msgid "Pyromaniac"
|
||||||
|
msgstr "Pyromane"
|
||||||
|
|
||||||
|
#: init.lua
|
||||||
|
msgid "Craft 8 times flint and steel."
|
||||||
|
msgstr "Fabrique 8 silex et aciers."
|
||||||
|
|
||||||
|
#: init.lua
|
||||||
|
msgid "Firefighter"
|
||||||
|
msgstr "Pompier"
|
||||||
|
|
||||||
|
#: init.lua
|
||||||
|
msgid "Put out 1000 fires."
|
||||||
|
msgstr "Éteint 1000 feux."
|
||||||
|
|
||||||
|
#: init.lua
|
||||||
|
msgid "Light It Up"
|
||||||
|
msgstr "Eclairé·e"
|
||||||
|
|
||||||
|
#: init.lua
|
||||||
|
msgid "Place 100 torches."
|
||||||
|
msgstr "Place 100 torches."
|
||||||
|
|
||||||
|
#: init.lua
|
||||||
|
msgid "Well Lit"
|
||||||
|
msgstr "Bien Éclairé"
|
||||||
|
|
||||||
|
#: init.lua
|
||||||
|
msgid "Place 1,000 torches."
|
||||||
|
msgstr "Place 1000 torches."
|
||||||
|
|
||||||
|
#: init.lua
|
||||||
|
msgid "Really Well Lit"
|
||||||
|
msgstr "Vraiment Bien Éclairé"
|
||||||
|
|
||||||
|
#: init.lua
|
||||||
|
msgid "Craft 10 mese lamps."
|
||||||
|
msgstr "Fabrique 10 lampes de mese."
|
||||||
|
|
||||||
|
#: init.lua
|
||||||
|
msgid "Outpost"
|
||||||
|
msgstr "Poste Avancé"
|
||||||
|
|
||||||
|
#: init.lua
|
||||||
|
msgid "Craft 200 stone bricks."
|
||||||
|
msgstr "Confectionne 200 briques de pierre."
|
||||||
|
|
||||||
|
#: init.lua
|
||||||
|
msgid "Watchtower"
|
||||||
|
msgstr "Tour de Garde"
|
||||||
|
|
||||||
|
#: init.lua
|
||||||
|
msgid "Craft 800 stone bricks."
|
||||||
|
msgstr "Confectionne 800 briques de pierre."
|
||||||
|
|
||||||
|
#: init.lua
|
||||||
|
msgid "Fortress"
|
||||||
|
msgstr "Forteresse"
|
||||||
|
|
||||||
|
#: init.lua
|
||||||
|
msgid "Craft 3,200 stone bricks."
|
||||||
|
msgstr "Confectionne 3200 briques de pierre."
|
||||||
|
|
||||||
|
#: init.lua
|
||||||
|
msgid "Desert Dweller"
|
||||||
|
msgstr "Habitant·e du Désert"
|
||||||
|
|
||||||
|
#: init.lua
|
||||||
|
msgid "Craft 400 desert stone bricks."
|
||||||
|
msgstr "Confectionne 400 briques de pierre du désert."
|
||||||
|
|
||||||
|
#: init.lua
|
||||||
|
msgid "Pharaoh"
|
||||||
|
msgstr "Pharaon"
|
||||||
|
|
||||||
|
#: init.lua
|
||||||
|
msgid "Craft 100 sandstone bricks."
|
||||||
|
msgstr "Confectionne 100 briques de roche de sable."
|
||||||
|
|
||||||
|
#: init.lua
|
||||||
|
msgid "Little Library"
|
||||||
|
msgstr "Petite Bibliothèque"
|
||||||
|
|
||||||
|
#: init.lua
|
||||||
|
msgid "Craft 7 bookshelves."
|
||||||
|
msgstr "Fabrique 7 bibliothèques."
|
||||||
|
|
||||||
|
#: init.lua
|
||||||
|
msgid "Lava and Water"
|
||||||
|
msgstr "La Lave et l'Eau"
|
||||||
|
|
||||||
|
#: init.lua
|
||||||
|
msgid "Mine your first obsidian."
|
||||||
|
msgstr "Mine ton premier bloc d'obsidienne."
|
||||||
|
|
||||||
|
#: init.lua
|
||||||
|
msgid "Obsessed with Obsidian"
|
||||||
|
msgstr "Obsédé·e par l'obsidienne"
|
||||||
|
|
||||||
|
#: init.lua
|
||||||
|
msgid "Mine 50 obsidian."
|
||||||
|
msgstr "Mine 50 pierres d'obsidienne."
|
||||||
|
|
||||||
|
#: init.lua
|
||||||
|
msgid "Lava Miner"
|
||||||
|
msgstr "Mineu·r·se de lave"
|
||||||
|
|
||||||
|
#: init.lua
|
||||||
|
msgid "Mine any block while being very close to lava."
|
||||||
|
msgstr "Mine n'importe quel bloc à proximité de la lave."
|
||||||
|
|
||||||
|
#: init.lua
|
||||||
|
msgid "On The Way"
|
||||||
|
msgstr "Sur La Voie"
|
||||||
|
|
||||||
|
#: init.lua
|
||||||
|
msgid "Place 100 rails."
|
||||||
|
msgstr "Place 100 rails."
|
||||||
|
|
||||||
|
#: init.lua
|
||||||
|
msgid "First Day in the Woods"
|
||||||
|
msgstr "Premier Jour dans les Bois"
|
||||||
|
|
||||||
|
#: init.lua
|
||||||
|
msgid "Dig 6 tree blocks."
|
||||||
|
msgstr "Creuse 6 blocs d'arbre."
|
||||||
|
|
||||||
|
#: init.lua
|
||||||
|
msgid "Lumberjack"
|
||||||
|
msgstr "Bûcheron·ne"
|
||||||
|
|
||||||
|
#: init.lua
|
||||||
|
msgid "Dig 36 tree blocks."
|
||||||
|
msgstr "Creuse 36 blocs d'arbre."
|
||||||
|
|
||||||
|
#: init.lua
|
||||||
|
msgid "Semi-pro Lumberjack"
|
||||||
|
msgstr "Bûcheron.ne. Semi-Professionnel.le."
|
||||||
|
|
||||||
|
#: init.lua
|
||||||
|
msgid "Dig 216 tree blocks."
|
||||||
|
msgstr "Creuse 216 blocs d'arbre."
|
||||||
|
|
||||||
|
#: init.lua
|
||||||
|
msgid "Professional Lumberjack"
|
||||||
|
msgstr "Bûcheron·ne Professionnel·le"
|
||||||
|
|
||||||
|
#: init.lua
|
||||||
|
msgid "Dig 1,296 tree blocks."
|
||||||
|
msgstr "Creuse 1296 blocs d'arbre."
|
||||||
|
|
||||||
|
#: init.lua
|
||||||
|
msgid "Junglebaby"
|
||||||
|
msgstr "Enfant de la Jungle"
|
||||||
|
|
||||||
|
#: init.lua
|
||||||
|
msgid "Dig 100 jungle tree blocks."
|
||||||
|
msgstr "Creuse 100 blocs d'arbres de jungle."
|
||||||
|
|
||||||
|
#: init.lua
|
||||||
|
msgid "Jungleman"
|
||||||
|
msgstr "Personne de la Jungle"
|
||||||
|
|
||||||
|
#: init.lua
|
||||||
|
msgid "Dig 1,000 jungle tree blocks."
|
||||||
|
msgstr "Creuse 1000 blocs d'arbre de jungle."
|
||||||
|
|
||||||
|
#: init.lua
|
||||||
|
msgid "First Mese Find"
|
||||||
|
msgstr "Première Pépite : Mese"
|
||||||
|
|
||||||
|
#: init.lua
|
||||||
|
msgid "Mine your first mese ore."
|
||||||
|
msgstr "Mine ton premier minerai de mese."
|
||||||
|
|
||||||
|
#: init.lua
|
||||||
|
msgid "Mese Mastery"
|
||||||
|
msgstr "Maîtrise de Mese"
|
||||||
|
|
||||||
|
#: init.lua
|
||||||
|
msgid "Mine a mese block."
|
||||||
|
msgstr "Mine un bloc de mese."
|
||||||
|
|
||||||
|
#: init.lua
|
||||||
|
msgid "You’re a copper"
|
||||||
|
msgstr "Faîtes Jouer les Cuivres"
|
||||||
|
|
||||||
|
#: init.lua
|
||||||
|
msgid "Dig 1,000 copper ores."
|
||||||
|
msgstr "Creuse 1000 minerais de cuivre."
|
||||||
|
|
||||||
|
#: init.lua
|
||||||
|
msgid "A Cat in a Pop-Tart?!"
|
||||||
|
msgstr "Un Chat dans un Pop-Tart ?!"
|
||||||
|
|
||||||
|
#: init.lua
|
||||||
|
msgid "Mine a nyan cat."
|
||||||
|
msgstr "Mine un nyan cat."
|
||||||
|
|
||||||
|
#: init.lua
|
||||||
|
msgid "Mini Miner"
|
||||||
|
msgstr "Mini Mineu·r·se"
|
||||||
|
|
||||||
|
#: init.lua
|
||||||
|
msgid "Dig 100 stone blocks."
|
||||||
|
msgstr "Creuse 100 blocs de pierre."
|
||||||
|
|
||||||
|
#: init.lua
|
||||||
|
msgid "Hardened Miner"
|
||||||
|
msgstr "Mineu·r·se Endurci·e"
|
||||||
|
|
||||||
|
#: init.lua
|
||||||
|
msgid "Dig 1,000 stone blocks."
|
||||||
|
msgstr "Creuse 1000 blocs de pierre."
|
||||||
|
|
||||||
|
#: init.lua
|
||||||
|
msgid "Master Miner"
|
||||||
|
msgstr "Maître·sse Mineu·r·se"
|
||||||
|
|
||||||
|
#: init.lua
|
||||||
|
msgid "Dig 10,000 stone blocks."
|
||||||
|
msgstr "Creuse 10000 blocs de pierre."
|
||||||
|
|
||||||
|
#: init.lua
|
||||||
|
msgid "Marchand De Sable"
|
||||||
|
msgstr "Marchand·e De Sable"
|
||||||
|
|
||||||
|
#: init.lua
|
||||||
|
msgid "Dig 1,000 sand."
|
||||||
|
msgstr "Creuse 1000 blocs de sable."
|
||||||
|
|
||||||
|
#: init.lua
|
||||||
|
msgid "Crafter of Sticks"
|
||||||
|
msgstr "Fabriquant·e de Bâtons."
|
||||||
|
|
||||||
|
#: init.lua
|
||||||
|
msgid "Craft 100 sticks."
|
||||||
|
msgstr "Confectionne 100 bâtons."
|
||||||
|
|
||||||
|
#: init.lua
|
||||||
|
msgid "Jungle Discoverer"
|
||||||
|
msgstr "Explorat·eur·rice de la Jungle"
|
||||||
|
|
||||||
|
#: init.lua
|
||||||
|
msgid "Mine your first jungle grass."
|
||||||
|
msgstr "Ramasse ta première herbe de jungle."
|
||||||
|
|
||||||
|
#: init.lua
|
||||||
|
msgid "Grasslands Discoverer"
|
||||||
|
msgstr "Découvreu·r·se de prairies"
|
||||||
|
|
||||||
|
#: init.lua
|
||||||
|
msgid "Mine some grass."
|
||||||
|
msgstr "Ramasse de l'herbe."
|
||||||
|
|
||||||
|
#: init.lua
|
||||||
|
msgid "Savannah Discoverer"
|
||||||
|
msgstr "Explorat·eur·rice de la Savanne"
|
||||||
|
|
||||||
|
#: init.lua
|
||||||
|
msgid "Mine some dry grass."
|
||||||
|
msgstr "Ramasse de l'herbe sèche."
|
||||||
|
|
||||||
|
#: init.lua
|
||||||
|
msgid "Desert Discoverer"
|
||||||
|
msgstr "Expolrat·eur·rice du Désert."
|
||||||
|
|
||||||
|
#: init.lua
|
||||||
|
msgid "Mine your first cactus."
|
||||||
|
msgstr "Mine ton premier catus."
|
||||||
|
|
||||||
|
#: init.lua
|
||||||
|
msgid "Far Lands"
|
||||||
|
msgstr "Terres Lointaines"
|
||||||
|
|
||||||
|
#: init.lua
|
||||||
|
msgid "Mine your first dry shrub."
|
||||||
|
msgstr "Coupe ton premier arbuste sec."
|
||||||
|
|
||||||
|
#: init.lua
|
||||||
|
msgid "Glacier Discoverer"
|
||||||
|
msgstr "Découvreu·r·se de glacier"
|
||||||
|
|
||||||
|
#: init.lua
|
||||||
|
msgid "Mine your first ice."
|
||||||
|
msgstr "Creuse ton premier bloc de glace."
|
||||||
|
|
||||||
|
#: init.lua
|
||||||
|
msgid "Very Simple Snow Man"
|
||||||
|
msgstr "Bonhomme de Neige Rudimentaire"
|
||||||
|
|
||||||
|
#: init.lua
|
||||||
|
msgid "Place two snow blocks."
|
||||||
|
msgstr "Place deux blocs de neige."
|
||||||
|
|
||||||
|
#: init.lua
|
||||||
|
msgid "First Gold Find"
|
||||||
|
msgstr "Première Pépite : Or"
|
||||||
|
|
||||||
|
#: init.lua
|
||||||
|
msgid "Mine your first gold ore."
|
||||||
|
msgstr "Mine ton premier minerai d'or."
|
||||||
|
|
||||||
|
#: init.lua
|
||||||
|
msgid "Gold Rush"
|
||||||
|
msgstr "Ruée vers l'Or"
|
||||||
|
|
||||||
|
#: init.lua
|
||||||
|
msgid "Mine 45 gold ores."
|
||||||
|
msgstr "Mine 45 minerais d'or."
|
||||||
|
|
||||||
|
#: init.lua
|
||||||
|
msgid "Wow, I am Diamonds!"
|
||||||
|
msgstr "Wow, Je suis Diamants!"
|
||||||
|
|
||||||
|
#: init.lua
|
||||||
|
msgid "Mine your first diamond ore."
|
||||||
|
msgstr "Mine ton premier diamant."
|
||||||
|
|
||||||
|
#: init.lua
|
||||||
|
#, fuzzy
|
||||||
|
msgid "Girl's Best Friend"
|
||||||
|
msgstr "Girl's Best Friend"
|
||||||
|
|
||||||
|
#: init.lua
|
||||||
|
msgid "Mine 18 diamond ores."
|
||||||
|
msgstr "Mine 18 diamants."
|
||||||
|
|
||||||
|
#: init.lua
|
||||||
|
msgid "Hardest Block on Earth"
|
||||||
|
msgstr "Le Bloc le Plus Dur du Monde"
|
||||||
|
|
||||||
|
#: init.lua
|
||||||
|
msgid "Craft a diamond block."
|
||||||
|
msgstr "Confectionne un bloc de diamant."
|
||||||
|
|
||||||
|
#: init.lua
|
||||||
|
msgid "In the Dungeon"
|
||||||
|
msgstr "Dans le Donjon"
|
||||||
|
|
||||||
|
#: init.lua
|
||||||
|
msgid "Mine a mossy cobblestone."
|
||||||
|
msgstr "Mine un bloc de pavés moussus."
|
||||||
|
|
||||||
|
#: init.lua
|
||||||
|
msgid "Smelter"
|
||||||
|
msgstr "Fondeu·r·se"
|
||||||
|
|
||||||
|
#: init.lua
|
||||||
|
msgid "Craft 10 furnaces."
|
||||||
|
msgstr "Construis 10 fours."
|
||||||
|
|
||||||
|
#: init.lua
|
||||||
|
msgid "Treasurer"
|
||||||
|
msgstr "Trésori·er·ère"
|
||||||
|
|
||||||
|
#: init.lua
|
||||||
|
msgid "Craft 15 chests."
|
||||||
|
msgstr "Fabrique 15 coffres."
|
||||||
|
|
||||||
|
#: init.lua
|
||||||
|
msgid "Bankier"
|
||||||
|
msgstr "Banqui·er·ère"
|
||||||
|
|
||||||
|
#: init.lua
|
||||||
|
msgid "Craft 30 locked chests."
|
||||||
|
msgstr "Fabrique 30 coffres Verrouillés."
|
||||||
|
|
||||||
|
#: init.lua
|
||||||
|
msgid "Bricker"
|
||||||
|
msgstr "Briqueu·r·se"
|
||||||
|
|
||||||
|
#: init.lua
|
||||||
|
msgid "Craft 200 brick blocks."
|
||||||
|
msgstr "Confectionne 200 blocs de brique."
|
||||||
|
|
||||||
|
#: init.lua
|
||||||
|
msgid "House of Obsidian"
|
||||||
|
msgstr "La Maison de L'Obsidienne"
|
||||||
|
|
||||||
|
#: init.lua
|
||||||
|
msgid "Craft 100 obsidian bricks."
|
||||||
|
msgstr "Confectionne 100 briques d'obsidienne."
|
||||||
|
|
||||||
|
#: init.lua
|
||||||
|
msgid "Build a Cave"
|
||||||
|
msgstr "Construis une grotte"
|
||||||
|
|
||||||
|
#: init.lua
|
||||||
|
msgid "Place 100 stone."
|
||||||
|
msgstr "Place 100 pierres."
|
||||||
|
|
||||||
|
#: init.lua
|
||||||
|
msgid "Long Ladder"
|
||||||
|
msgstr "Longue Echelle"
|
||||||
|
|
||||||
|
#: init.lua
|
||||||
|
msgid "Place 400 wooden ladders."
|
||||||
|
msgstr "Place 400 échelles en bois."
|
||||||
|
|
||||||
|
#: init.lua
|
||||||
|
msgid "Industrial Age"
|
||||||
|
msgstr "Âge Industriel"
|
||||||
|
|
||||||
|
#: init.lua
|
||||||
|
msgid "Place 40 steel ladders."
|
||||||
|
msgstr "Place 40 échelles métalliques."
|
||||||
|
|
||||||
|
#: init.lua
|
||||||
|
msgid "Yummy!"
|
||||||
|
msgstr "Miam !"
|
||||||
|
|
||||||
|
#: init.lua
|
||||||
|
msgid "Eat 80 apples."
|
||||||
|
msgstr "Mange 80 pommes."
|
||||||
|
|
||||||
|
#: init.lua
|
||||||
|
msgid "Glasser"
|
||||||
|
msgstr "Verri·er·ère"
|
||||||
|
|
||||||
|
#: init.lua
|
||||||
|
msgid "Craft 14 vessels shelves."
|
||||||
|
msgstr "Fabrique 14 vaisseliers."
|
||||||
|
|
||||||
|
#: init.lua
|
||||||
|
msgid "Farming Skills Acquired"
|
||||||
|
msgstr "Compétences Paysannes Acquises"
|
||||||
|
|
||||||
|
#: init.lua
|
||||||
|
msgid "Harvest a fully grown wheat plant."
|
||||||
|
msgstr "Récolte un plant de blé à maturité."
|
||||||
|
|
||||||
|
#: init.lua
|
||||||
|
msgid "Field Worker"
|
||||||
|
msgstr "Travailleu·r·se Agricole"
|
||||||
|
|
||||||
|
#: init.lua
|
||||||
|
msgid "Harvest 25 fully grown wheat plants."
|
||||||
|
msgstr "Récolte 25 plants de blé à maturité."
|
||||||
|
|
||||||
|
#: init.lua
|
||||||
|
msgid "Aspiring Farmer"
|
||||||
|
msgstr "Apprenti·e Fermi·er·ère"
|
||||||
|
|
||||||
|
#: init.lua
|
||||||
|
msgid "Harvest 125 fully grown wheat plants."
|
||||||
|
msgstr "Récolte 125 plants de blé à maturité."
|
||||||
|
|
||||||
|
#: init.lua
|
||||||
|
msgid "Wheat Magnate"
|
||||||
|
msgstr "Magnat·e du Blé"
|
||||||
|
|
||||||
|
#: init.lua
|
||||||
|
msgid "Harvest 625 fully grown wheat plants."
|
||||||
|
msgstr "Récolte 625 plants de blé à maturité."
|
||||||
|
|
||||||
|
#: init.lua
|
||||||
|
msgid "Baker"
|
||||||
|
msgstr "Boulang·er·ère"
|
||||||
|
|
||||||
|
#: init.lua
|
||||||
|
msgid "Eat 10 loaves of bread."
|
||||||
|
msgstr "Mange 10 miches de pain."
|
||||||
|
|
||||||
|
#: init.lua
|
||||||
|
msgid "Wool Over Your Eyes"
|
||||||
|
msgstr "De la Laines dans Tes Yeux"
|
||||||
|
|
||||||
|
#: init.lua
|
||||||
|
msgid "Craft 250 white wool."
|
||||||
|
msgstr "Confectionne 250 blocs de laine blanche."
|
||||||
|
|
||||||
|
#: init.lua
|
||||||
|
msgid "Hotelier"
|
||||||
|
msgstr "Hoteli·er·ère"
|
||||||
|
|
||||||
|
#: init.lua
|
||||||
|
msgid "Craft 15 fancy beds."
|
||||||
|
msgstr "Construis 15 lits chics."
|
||||||
|
|
||||||
|
#: init.lua
|
||||||
|
msgid "Filthy Rich"
|
||||||
|
msgstr "Richissime"
|
||||||
|
|
||||||
|
#: init.lua
|
||||||
|
msgid "Craft 24 gold block stairs."
|
||||||
|
msgstr "Construis 24 escaliers en or."
|
||||||
|
|
||||||
|
#: init.lua
|
||||||
|
msgid "Roses Are Red"
|
||||||
|
msgstr "Les Roses Sont Rouges"
|
||||||
|
|
||||||
|
#: init.lua
|
||||||
|
msgid "Craft 400 red dyes."
|
||||||
|
msgstr "Prépare 400 teintures rouges."
|
||||||
|
|
||||||
|
#: init.lua
|
||||||
|
msgid "Dandelions are Yellow"
|
||||||
|
msgstr "Les Pissenlits sont Jaunes."
|
||||||
|
|
||||||
|
#: init.lua
|
||||||
|
msgid "Craft 400 yellow dyes."
|
||||||
|
msgstr "Prépare 400 teintures jaunes."
|
||||||
|
|
||||||
|
#: init.lua
|
||||||
|
msgid "Geraniums are Blue"
|
||||||
|
msgstr "Les Geraniums Sont Bleus"
|
||||||
|
|
||||||
|
#: init.lua
|
||||||
|
msgid "Craft 400 blue dyes."
|
||||||
|
msgstr "Prépare 400 teintures bleues."
|
||||||
|
|
||||||
|
#: init.lua
|
||||||
|
msgid "White Color Stock"
|
||||||
|
msgstr "Chaussettes Blanches"
|
||||||
|
|
||||||
|
#: init.lua
|
||||||
|
msgid "Craft 100 white dyes."
|
||||||
|
msgstr "Prépare 100 teintures blanches."
|
||||||
|
|
||||||
|
#: init.lua
|
||||||
|
msgid "Tasty Mushrooms"
|
||||||
|
msgstr "Délicieux Champignons"
|
||||||
|
|
||||||
|
#: init.lua
|
||||||
|
msgid "Eat 3 brown mushrooms."
|
||||||
|
msgstr "Mange 3 champignons marrons."
|
||||||
|
|
||||||
|
#: init.lua
|
||||||
|
msgid "Mushroom Lover"
|
||||||
|
msgstr "Adorat·eur·rice de Champignons"
|
||||||
|
|
||||||
|
#: init.lua
|
||||||
|
msgid "Eat 33 brown mushrooms."
|
||||||
|
msgstr "Mange 33 champignons marrons."
|
||||||
|
|
||||||
|
#: init.lua
|
||||||
|
msgid "Underground Mushroom Farmer"
|
||||||
|
msgstr "Culture de Champignons en Cave"
|
||||||
|
|
||||||
|
#: init.lua
|
||||||
|
msgid "Eat 333 brown mushrooms."
|
||||||
|
msgstr "Mange 333 champignons marrons."
|
||||||
|
|
||||||
|
#: init.lua
|
||||||
|
msgid "Builder"
|
||||||
|
msgstr "Bâtisseu·r·se"
|
||||||
|
|
||||||
|
#: init.lua
|
||||||
|
msgid "Constructor"
|
||||||
|
msgstr "Construct·eur·rice"
|
||||||
|
|
||||||
|
#: init.lua
|
||||||
|
msgid "Architect"
|
||||||
|
msgstr "Architecte"
|
||||||
|
|
||||||
|
#: init.lua
|
||||||
|
msgid "Master Architect"
|
||||||
|
msgstr "Maître·sse Architecte"
|
||||||
|
|
||||||
|
#: chat_commands.lua
|
||||||
|
msgid "[c|clear|disable|enable]"
|
||||||
|
msgstr "[c|clear|disable|enable]"
|
||||||
|
|
||||||
|
#: chat_commands.lua
|
||||||
|
msgid "Show, clear, disable or enable your achievements"
|
||||||
|
msgstr "Affiche, réinitialise, désactive ou active vos réussites."
|
||||||
|
|
||||||
|
#: chat_commands.lua
|
||||||
|
msgid "All your awards and statistics have been cleared. You can now start again."
|
||||||
|
msgstr "Tous vos trophées et statistiques ont été réinitialisés. Vous pouvez recommencer à nouveau."
|
||||||
|
|
||||||
|
#: chat_commands.lua
|
||||||
|
msgid "You have disabled your achievements."
|
||||||
|
msgstr "Vous avez désactivé vos réussites."
|
||||||
|
|
||||||
|
#: chat_commands.lua
|
||||||
|
msgid "You have enabled your achievements."
|
||||||
|
msgstr "Vous avez activé vos réussites."
|
||||||
|
|
||||||
|
#: chat_commands.lua
|
||||||
|
msgid "<achievement ID>"
|
||||||
|
msgstr "<réussite ID>"
|
||||||
|
|
||||||
|
#: chat_commands.lua
|
||||||
|
msgid "Show details of an achievement"
|
||||||
|
msgstr "Afficher les détails d'une réussite"
|
||||||
|
|
||||||
|
#: chat_commands.lua
|
||||||
|
msgid "Achievement not found."
|
||||||
|
msgstr "Réussite non trouvée."
|
||||||
|
|
||||||
|
#: chat_commands.lua
|
||||||
|
msgid "<name>"
|
||||||
|
msgstr "<nom>"
|
||||||
|
|
||||||
|
#: chat_commands.lua
|
||||||
|
msgid "Get the achievements statistics for the given player or yourself"
|
||||||
|
msgstr "Obtenez les statistiques des réussites d'un joueur donné ou de vous-même"
|
|
@ -0,0 +1,819 @@
|
||||||
|
# Portuguese translations for Awards package.
|
||||||
|
# Copyright (C) 2018
|
||||||
|
# This file is distributed under the same license as the Awards package.
|
||||||
|
# FIRST AUTHOR borgesdossantosbruno@gmail.com, 2018.
|
||||||
|
# BrunoMine, 2018
|
||||||
|
#
|
||||||
|
msgid ""
|
||||||
|
msgstr ""
|
||||||
|
"Project-Id-Version: \n"
|
||||||
|
"Report-Msgid-Bugs-To: \n"
|
||||||
|
"POT-Creation-Date: 2017-02-21 05:50-0300\n"
|
||||||
|
"PO-Revision-Date: 2018-08-01 16:16-0300\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"
|
||||||
|
"X-Generator: Poedit 2.0.6\n"
|
||||||
|
"Last-Translator: BrunoMine\n"
|
||||||
|
"Language: pt\n"
|
||||||
|
|
||||||
|
#: api.lua
|
||||||
|
msgid "Secret Achievement Unlocked:"
|
||||||
|
msgstr "Conquista Secreta Desbloqueada:"
|
||||||
|
|
||||||
|
#: api.lua
|
||||||
|
msgid "Achievement Unlocked:"
|
||||||
|
msgstr "Conquista Desbloqueada:"
|
||||||
|
|
||||||
|
#: api.lua
|
||||||
|
#, lua-format
|
||||||
|
msgid "Secret Achievement Unlocked: %s"
|
||||||
|
msgstr "Conquista Secreta Desbloqueada: %s"
|
||||||
|
|
||||||
|
#: api.lua
|
||||||
|
#, lua-format
|
||||||
|
msgid "Achievement Unlocked: %s"
|
||||||
|
msgstr "Conquista Desbloqueada: %s"
|
||||||
|
|
||||||
|
#: api.lua
|
||||||
|
msgid "Secret Achievement Unlocked!"
|
||||||
|
msgstr "Conquista Secreta Desbloqueada!"
|
||||||
|
|
||||||
|
#: api.lua
|
||||||
|
msgid "Achievement Unlocked!"
|
||||||
|
msgstr "Conquista Desbloqueada!"
|
||||||
|
|
||||||
|
#: api.lua
|
||||||
|
msgid "Error: No awards available."
|
||||||
|
msgstr "Erro: Nenhuma conquista encontrada."
|
||||||
|
|
||||||
|
#: api.lua
|
||||||
|
msgid "OK"
|
||||||
|
msgstr "OK"
|
||||||
|
|
||||||
|
#: api.lua
|
||||||
|
msgid "(Secret Award)"
|
||||||
|
msgstr "(Conquista Secreta)"
|
||||||
|
|
||||||
|
#: api.lua
|
||||||
|
msgid "Unlock this award to find out what it is."
|
||||||
|
msgstr "Desbloqueie essa conquista para descobrir o que significa."
|
||||||
|
|
||||||
|
#: api.lua
|
||||||
|
#, lua-format
|
||||||
|
msgid "%s (got)"
|
||||||
|
msgstr "%s (obtido)"
|
||||||
|
|
||||||
|
#: api.lua
|
||||||
|
msgid "You've disabled awards. Type /awards enable to reenable."
|
||||||
|
msgstr "Desabilitaste as conquistas. Digite /awards enable para reabilitar."
|
||||||
|
|
||||||
|
#: api.lua
|
||||||
|
msgid "You have not unlocked any awards."
|
||||||
|
msgstr "Nenhuma conquista desbloqueada ainda."
|
||||||
|
|
||||||
|
#: api.lua
|
||||||
|
#, lua-format
|
||||||
|
msgid "%s’s awards:"
|
||||||
|
msgstr "%s das conquistas:"
|
||||||
|
|
||||||
|
#: api.lua chat_commands.lua
|
||||||
|
#, lua-format
|
||||||
|
msgid "%s: %s"
|
||||||
|
msgstr "%s: %s"
|
||||||
|
|
||||||
|
#: sfinv.lua unified_inventory.lua
|
||||||
|
msgid "Awards"
|
||||||
|
msgstr "Conquistas"
|
||||||
|
|
||||||
|
#: triggers.lua
|
||||||
|
msgid "@1/@2 dug"
|
||||||
|
msgstr "@1 de @2 obtidos"
|
||||||
|
|
||||||
|
#. Translators: @1 is count, @2 is description.
|
||||||
|
#: triggers.lua
|
||||||
|
msgid "Mine: @2"
|
||||||
|
msgid_plural "Mine: @1×@2"
|
||||||
|
msgstr[0] "Cavar: @2"
|
||||||
|
msgstr[1] "Minar: @1×@2"
|
||||||
|
|
||||||
|
#: triggers.lua
|
||||||
|
msgid "Mine @1 block."
|
||||||
|
msgid_plural "Mine @1 blocks."
|
||||||
|
msgstr[0] "Cavar um bloco."
|
||||||
|
msgstr[1] "Cavar @1 blocos."
|
||||||
|
|
||||||
|
#: triggers.lua
|
||||||
|
msgid "@1/@2 placed"
|
||||||
|
msgstr "@1 de @2 colocados"
|
||||||
|
|
||||||
|
#. Translators: @1 is count, @2 is description.
|
||||||
|
#: triggers.lua
|
||||||
|
msgid "Place: @2"
|
||||||
|
msgid_plural "Place: @1×@2"
|
||||||
|
msgstr[0] "Colocar: @2"
|
||||||
|
msgstr[1] "Place: @1×@2"
|
||||||
|
|
||||||
|
#: triggers.lua
|
||||||
|
msgid "Place a block."
|
||||||
|
msgid_plural "Place @1 blocks."
|
||||||
|
msgstr[0] "Colocar um bloco."
|
||||||
|
msgstr[1] "Colocar @1 blocos."
|
||||||
|
|
||||||
|
#: triggers.lua
|
||||||
|
msgid "@1/@2 eaten"
|
||||||
|
msgstr "@1 de @2 consumidos"
|
||||||
|
|
||||||
|
#. Translators: @1 is count, @2 is description.
|
||||||
|
#: triggers.lua
|
||||||
|
msgid "Eat: @2"
|
||||||
|
msgid_plural "Eat: @1×@2"
|
||||||
|
msgstr[0] "Consumir: @2"
|
||||||
|
msgstr[1] "Consumir: @1×@2"
|
||||||
|
|
||||||
|
#: triggers.lua
|
||||||
|
msgid "Eat an item."
|
||||||
|
msgid_plural "Eat @1 items."
|
||||||
|
msgstr[0] "Consumir um item."
|
||||||
|
msgstr[1] "Consumir @1 itens."
|
||||||
|
|
||||||
|
#: triggers.lua
|
||||||
|
msgid "@1/@2 deaths"
|
||||||
|
msgstr "@1 de @2 mortes"
|
||||||
|
|
||||||
|
#: triggers.lua
|
||||||
|
msgid "Die."
|
||||||
|
msgid_plural "Die @1 times."
|
||||||
|
msgstr[0] "Morrer."
|
||||||
|
msgstr[1] "Morrer @1 vezes."
|
||||||
|
|
||||||
|
#: triggers.lua
|
||||||
|
msgid "@1/@2 chat messages"
|
||||||
|
msgstr "@1 de @2"
|
||||||
|
|
||||||
|
#: triggers.lua
|
||||||
|
msgid "Write something in chat."
|
||||||
|
msgid_plural "Write @1 chat messages."
|
||||||
|
msgstr[0] "Escrever algo no bate papo."
|
||||||
|
msgstr[1] "Escrever @1 mensagens no bate papo."
|
||||||
|
|
||||||
|
#: triggers.lua
|
||||||
|
msgid "@1/@2 game joins"
|
||||||
|
msgstr "@1 de @2"
|
||||||
|
|
||||||
|
#: triggers.lua
|
||||||
|
msgid "Join the game."
|
||||||
|
msgid_plural "Join the game @1 times."
|
||||||
|
msgstr[0] "Entre no jogo."
|
||||||
|
msgstr[1] "Entre no jogo @1 vezes."
|
||||||
|
|
||||||
|
#: triggers.lua
|
||||||
|
msgid "@1/@2 crafted"
|
||||||
|
msgstr "@1 de @2 feitos"
|
||||||
|
|
||||||
|
#. Translators: @1 is count, @2 is description.
|
||||||
|
#: triggers.lua
|
||||||
|
msgid "Craft: @2"
|
||||||
|
msgid_plural "Craft: @1×@2"
|
||||||
|
msgstr[0] "Fazer @2"
|
||||||
|
msgstr[1] "Montar @2 @1 vezes"
|
||||||
|
|
||||||
|
#: triggers.lua
|
||||||
|
msgid "Craft an item."
|
||||||
|
msgid_plural "Craft @1 items."
|
||||||
|
msgstr[0] "Fazer um item."
|
||||||
|
msgstr[1] "Fazer @1 itens."
|
||||||
|
|
||||||
|
#: init.lua
|
||||||
|
msgid "Saint-Maclou"
|
||||||
|
msgstr "Saint-Maclou"
|
||||||
|
|
||||||
|
#: init.lua
|
||||||
|
msgid "Place 20 coal checkers."
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: init.lua
|
||||||
|
msgid "Castorama"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: init.lua
|
||||||
|
msgid "Place 20 iron checkers."
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: init.lua
|
||||||
|
msgid "Sam the Trapper"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: init.lua
|
||||||
|
msgid "Place 2 trap stones."
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: init.lua
|
||||||
|
msgid "Backpacker"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: init.lua
|
||||||
|
msgid "Craft 4 large bags."
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: init.lua
|
||||||
|
msgid "Pyromaniac"
|
||||||
|
msgstr "Piromaníaco"
|
||||||
|
|
||||||
|
#: init.lua
|
||||||
|
msgid "Craft 8 times flint and steel."
|
||||||
|
msgstr "Montar acendedor de Ferro e Pederneira 8 vezes."
|
||||||
|
|
||||||
|
#: init.lua
|
||||||
|
msgid "Firefighter"
|
||||||
|
msgstr "Bombeiro"
|
||||||
|
|
||||||
|
#: init.lua
|
||||||
|
msgid "Put out 1000 fires."
|
||||||
|
msgstr "Apagar fogo 1000 vezes."
|
||||||
|
|
||||||
|
#: init.lua
|
||||||
|
msgid "Light It Up"
|
||||||
|
msgstr "Ilumine Isso"
|
||||||
|
|
||||||
|
#: init.lua
|
||||||
|
msgid "Place 100 torches."
|
||||||
|
msgstr "Colocar 100 tochas."
|
||||||
|
|
||||||
|
#: init.lua
|
||||||
|
msgid "Well Lit"
|
||||||
|
msgstr "Bem Iluminado"
|
||||||
|
|
||||||
|
#: init.lua
|
||||||
|
msgid "Place 1,000 torches."
|
||||||
|
msgstr "Colocar 1.000 tochas."
|
||||||
|
|
||||||
|
#: init.lua
|
||||||
|
msgid "Really Well Lit"
|
||||||
|
msgstr "Realmente Bem Iluminado"
|
||||||
|
|
||||||
|
#: init.lua
|
||||||
|
msgid "Craft 10 mese lamps."
|
||||||
|
msgstr "Fazer 10 lâmpadas de mese."
|
||||||
|
|
||||||
|
#: init.lua
|
||||||
|
msgid "Outpost"
|
||||||
|
msgstr "Posto Avançado"
|
||||||
|
|
||||||
|
#: init.lua
|
||||||
|
msgid "Craft 200 stone bricks."
|
||||||
|
msgstr "Fazer 200 tijolos de pedra."
|
||||||
|
|
||||||
|
#: init.lua
|
||||||
|
msgid "Watchtower"
|
||||||
|
msgstr "Sentinela"
|
||||||
|
|
||||||
|
#: init.lua
|
||||||
|
msgid "Craft 800 stone bricks."
|
||||||
|
msgstr "Fazer 800 tijolos de pedra."
|
||||||
|
|
||||||
|
#: init.lua
|
||||||
|
msgid "Fortress"
|
||||||
|
msgstr "Fortaleza"
|
||||||
|
|
||||||
|
#: init.lua
|
||||||
|
msgid "Craft 3,200 stone bricks."
|
||||||
|
msgstr "Fazer 3.200 tijolos de pedra."
|
||||||
|
|
||||||
|
#: init.lua
|
||||||
|
msgid "Desert Dweller"
|
||||||
|
msgstr "Morador do Deserto"
|
||||||
|
|
||||||
|
#: init.lua
|
||||||
|
msgid "Craft 400 desert stone bricks."
|
||||||
|
msgstr "Fazer 400 Tijolos de pedra do deserto."
|
||||||
|
|
||||||
|
#: init.lua
|
||||||
|
msgid "Pharaoh"
|
||||||
|
msgstr "Faraó"
|
||||||
|
|
||||||
|
#: init.lua
|
||||||
|
msgid "Craft 100 sandstone bricks."
|
||||||
|
msgstr "Fazer 100 tijolos de arenito."
|
||||||
|
|
||||||
|
#: init.lua
|
||||||
|
msgid "Little Library"
|
||||||
|
msgstr "Pequena Biblioteca"
|
||||||
|
|
||||||
|
#: init.lua
|
||||||
|
msgid "Craft 7 bookshelves."
|
||||||
|
msgstr "Fazer 7 estantes de livros."
|
||||||
|
|
||||||
|
#: init.lua
|
||||||
|
msgid "Lava and Water"
|
||||||
|
msgstr "Lava e Água"
|
||||||
|
|
||||||
|
#: init.lua
|
||||||
|
msgid "Mine your first obsidian."
|
||||||
|
msgstr "Cavar sua primeira obsidiana."
|
||||||
|
|
||||||
|
#: init.lua
|
||||||
|
msgid "Obsessed with Obsidian"
|
||||||
|
msgstr "Obcecado por Obsidiana"
|
||||||
|
|
||||||
|
#: init.lua
|
||||||
|
msgid "Mine 50 obsidian."
|
||||||
|
msgstr "Minerar 50 obsidianas."
|
||||||
|
|
||||||
|
#: init.lua
|
||||||
|
msgid "Lava Miner"
|
||||||
|
msgstr "Minerador de Lava"
|
||||||
|
|
||||||
|
#: init.lua
|
||||||
|
msgid "Mine any block while being very close to lava."
|
||||||
|
msgstr "Minerar qualquer bloco enquanto estiver mergulhado em lava."
|
||||||
|
|
||||||
|
#: init.lua
|
||||||
|
msgid "On The Way"
|
||||||
|
msgstr "No Caminho"
|
||||||
|
|
||||||
|
#: init.lua
|
||||||
|
msgid "Place 100 rails."
|
||||||
|
msgstr "Colocar 100 trilhos."
|
||||||
|
|
||||||
|
#: init.lua
|
||||||
|
msgid "First Day in the Woods"
|
||||||
|
msgstr "Primeiro dia na Floresta"
|
||||||
|
|
||||||
|
#: init.lua
|
||||||
|
msgid "Dig 6 tree blocks."
|
||||||
|
msgstr "Cortar 6 blocos de árvore."
|
||||||
|
|
||||||
|
#: init.lua
|
||||||
|
msgid "Lumberjack"
|
||||||
|
msgstr "Lenhador"
|
||||||
|
|
||||||
|
#: init.lua
|
||||||
|
msgid "Dig 36 tree blocks."
|
||||||
|
msgstr "Cortar 36 blocos de árvore."
|
||||||
|
|
||||||
|
#: init.lua
|
||||||
|
msgid "Semi-pro Lumberjack"
|
||||||
|
msgstr "Lenhador Semi-Profissional"
|
||||||
|
|
||||||
|
#: init.lua
|
||||||
|
msgid "Dig 216 tree blocks."
|
||||||
|
msgstr "Cortar 216 blocos de árvore."
|
||||||
|
|
||||||
|
#: init.lua
|
||||||
|
msgid "Professional Lumberjack"
|
||||||
|
msgstr "Lenhador Profissional"
|
||||||
|
|
||||||
|
#: init.lua
|
||||||
|
msgid "Dig 1,296 tree blocks."
|
||||||
|
msgstr "Cortar 1.296 blocos de árvore."
|
||||||
|
|
||||||
|
#: init.lua
|
||||||
|
msgid "Junglebaby"
|
||||||
|
msgstr "Bebê Selvagem"
|
||||||
|
|
||||||
|
#: init.lua
|
||||||
|
msgid "Dig 100 jungle tree blocks."
|
||||||
|
msgstr "Cortar 100 blocos de árvore selvagem."
|
||||||
|
|
||||||
|
#: init.lua
|
||||||
|
msgid "Jungleman"
|
||||||
|
msgstr "Homem Selvagem"
|
||||||
|
|
||||||
|
#: init.lua
|
||||||
|
msgid "Dig 1,000 jungle tree blocks."
|
||||||
|
msgstr "Cortar 1.000 blocos de árvore selvagem."
|
||||||
|
|
||||||
|
#: init.lua
|
||||||
|
msgid "First Mese Find"
|
||||||
|
msgstr "Primeiro Mese"
|
||||||
|
|
||||||
|
#: init.lua
|
||||||
|
msgid "Mine your first mese ore."
|
||||||
|
msgstr "Cavar seu primeiro mese."
|
||||||
|
|
||||||
|
#: init.lua
|
||||||
|
msgid "Mese Mastery"
|
||||||
|
msgstr "Mestre do Mese"
|
||||||
|
|
||||||
|
#: init.lua
|
||||||
|
msgid "Mine a mese block."
|
||||||
|
msgstr "Cavar um bloco de mese."
|
||||||
|
|
||||||
|
#: init.lua
|
||||||
|
msgid "You’re a copper"
|
||||||
|
msgstr "Sou um Cobre"
|
||||||
|
|
||||||
|
#: init.lua
|
||||||
|
msgid "Dig 1,000 copper ores."
|
||||||
|
msgstr "Minerar 1.000 cobres."
|
||||||
|
|
||||||
|
#: init.lua
|
||||||
|
msgid "A Cat in a Pop-Tart?!"
|
||||||
|
msgstr "Um Gato em um Pop-Tart?!"
|
||||||
|
|
||||||
|
#: init.lua
|
||||||
|
msgid "Mine a nyan cat."
|
||||||
|
msgstr "Capturar um gato nyan."
|
||||||
|
|
||||||
|
#: init.lua
|
||||||
|
msgid "Mini Miner"
|
||||||
|
msgstr "Mini Minerador"
|
||||||
|
|
||||||
|
#: init.lua
|
||||||
|
msgid "Dig 100 stone blocks."
|
||||||
|
msgstr "Minerar 100 blocos de pedra."
|
||||||
|
|
||||||
|
#: init.lua
|
||||||
|
msgid "Hardened Miner"
|
||||||
|
msgstr "Minerador Avançado"
|
||||||
|
|
||||||
|
#: init.lua
|
||||||
|
msgid "Dig 1,000 stone blocks."
|
||||||
|
msgstr "Minerar 1.000 blocos de pedra."
|
||||||
|
|
||||||
|
#: init.lua
|
||||||
|
msgid "Master Miner"
|
||||||
|
msgstr "Minerador Mestre"
|
||||||
|
|
||||||
|
#: init.lua
|
||||||
|
msgid "Dig 10,000 stone blocks."
|
||||||
|
msgstr "Minerar 10.000 blocos de pedra."
|
||||||
|
|
||||||
|
#: init.lua
|
||||||
|
msgid "Marchand De Sable"
|
||||||
|
msgstr "Vendedor de Areia"
|
||||||
|
|
||||||
|
#: init.lua
|
||||||
|
msgid "Dig 1,000 sand."
|
||||||
|
msgstr "Cavar 1.000 blocos de areia."
|
||||||
|
|
||||||
|
#: init.lua
|
||||||
|
msgid "Crafter of Sticks"
|
||||||
|
msgstr "Rachador de Lenha"
|
||||||
|
|
||||||
|
#: init.lua
|
||||||
|
msgid "Craft 100 sticks."
|
||||||
|
msgstr "Lenhar 100 gravetos."
|
||||||
|
|
||||||
|
#: init.lua
|
||||||
|
msgid "Jungle Discoverer"
|
||||||
|
msgstr "Desbravador Selvagem"
|
||||||
|
|
||||||
|
#: init.lua
|
||||||
|
msgid "Mine your first jungle grass."
|
||||||
|
msgstr "Cortar seu primeiro mato selvagem."
|
||||||
|
|
||||||
|
#: init.lua
|
||||||
|
msgid "Grasslands Discoverer"
|
||||||
|
msgstr "Descobridor do Gramado"
|
||||||
|
|
||||||
|
#: init.lua
|
||||||
|
msgid "Mine some grass."
|
||||||
|
msgstr "Minerar algum mato"
|
||||||
|
|
||||||
|
#: init.lua
|
||||||
|
msgid "Savannah Discoverer"
|
||||||
|
msgstr "Descobridor da Savana"
|
||||||
|
|
||||||
|
#: init.lua
|
||||||
|
msgid "Mine some dry grass."
|
||||||
|
msgstr "Minerar algum mato seco."
|
||||||
|
|
||||||
|
#: init.lua
|
||||||
|
msgid "Desert Discoverer"
|
||||||
|
msgstr "Descobridor do Deserto"
|
||||||
|
|
||||||
|
#: init.lua
|
||||||
|
msgid "Mine your first cactus."
|
||||||
|
msgstr "Cortar seu primeiro cacto."
|
||||||
|
|
||||||
|
#: init.lua
|
||||||
|
msgid "Far Lands"
|
||||||
|
msgstr "Terras Distantes"
|
||||||
|
|
||||||
|
#: init.lua
|
||||||
|
msgid "Mine your first dry shrub."
|
||||||
|
msgstr "Minerar seu primeiro arbusto seco."
|
||||||
|
|
||||||
|
#: init.lua
|
||||||
|
msgid "Glacier Discoverer"
|
||||||
|
msgstr "Descobridor Glacial"
|
||||||
|
|
||||||
|
#: init.lua
|
||||||
|
msgid "Mine your first ice."
|
||||||
|
msgstr "Quebrar seu primeiro bloco de gelo."
|
||||||
|
|
||||||
|
#: init.lua
|
||||||
|
msgid "Very Simple Snow Man"
|
||||||
|
msgstr "Homem de Neve Muito Simples"
|
||||||
|
|
||||||
|
#: init.lua
|
||||||
|
msgid "Place two snow blocks."
|
||||||
|
msgstr "Colocar 2 blocos de neve."
|
||||||
|
|
||||||
|
#: init.lua
|
||||||
|
msgid "First Gold Find"
|
||||||
|
msgstr "Achei Ouro"
|
||||||
|
|
||||||
|
#: init.lua
|
||||||
|
msgid "Mine your first gold ore."
|
||||||
|
msgstr "Minerar sua primeira de ouro."
|
||||||
|
|
||||||
|
#: init.lua
|
||||||
|
msgid "Gold Rush"
|
||||||
|
msgstr "Corriga do Ouro"
|
||||||
|
|
||||||
|
#: init.lua
|
||||||
|
msgid "Mine 45 gold ores."
|
||||||
|
msgstr "Minerar 45 de ouro."
|
||||||
|
|
||||||
|
#: init.lua
|
||||||
|
msgid "Wow, I am Diamonds!"
|
||||||
|
msgstr "Uau, Diamante!"
|
||||||
|
|
||||||
|
#: init.lua
|
||||||
|
msgid "Mine your first diamond ore."
|
||||||
|
msgstr "Minerar seu primeiro diamante."
|
||||||
|
|
||||||
|
#: init.lua
|
||||||
|
msgid "Girl's Best Friend"
|
||||||
|
msgstr "Melhor Amigo da Menina"
|
||||||
|
|
||||||
|
#: init.lua
|
||||||
|
msgid "Mine 18 diamond ores."
|
||||||
|
msgstr "Minere 18 diamantes."
|
||||||
|
|
||||||
|
#: init.lua
|
||||||
|
msgid "Hardest Block on Earth"
|
||||||
|
msgstr "O Bloco mais Duro da Terra"
|
||||||
|
|
||||||
|
#: init.lua
|
||||||
|
msgid "Craft a diamond block."
|
||||||
|
msgstr "Montar um bloco de diamante."
|
||||||
|
|
||||||
|
#: init.lua
|
||||||
|
msgid "In the Dungeon"
|
||||||
|
msgstr "Na Masmorra"
|
||||||
|
|
||||||
|
#: init.lua
|
||||||
|
msgid "Mine a mossy cobblestone."
|
||||||
|
msgstr "Minerar um pedregulho com musgo."
|
||||||
|
|
||||||
|
#: init.lua
|
||||||
|
msgid "Smelter"
|
||||||
|
msgstr "Fundidor"
|
||||||
|
|
||||||
|
#: init.lua
|
||||||
|
msgid "Craft 10 furnaces."
|
||||||
|
msgstr "Montar 10 fornos."
|
||||||
|
|
||||||
|
#: init.lua
|
||||||
|
msgid "Treasurer"
|
||||||
|
msgstr "Tesoureiro"
|
||||||
|
|
||||||
|
#: init.lua
|
||||||
|
msgid "Craft 15 chests."
|
||||||
|
msgstr "Montar 10 baús."
|
||||||
|
|
||||||
|
#: init.lua
|
||||||
|
msgid "Bankier"
|
||||||
|
msgstr "Banqueiro"
|
||||||
|
|
||||||
|
#: init.lua
|
||||||
|
msgid "Craft 30 locked chests."
|
||||||
|
msgstr "Montar 30 baús trancados."
|
||||||
|
|
||||||
|
#: init.lua
|
||||||
|
msgid "Bricker"
|
||||||
|
msgstr "Tijoleiro"
|
||||||
|
|
||||||
|
#: init.lua
|
||||||
|
msgid "Craft 200 brick blocks."
|
||||||
|
msgstr "Fazer 200 blocos de tijolo."
|
||||||
|
|
||||||
|
#: init.lua
|
||||||
|
msgid "House of Obsidian"
|
||||||
|
msgstr "Casa de Obsidiana"
|
||||||
|
|
||||||
|
#: init.lua
|
||||||
|
msgid "Craft 100 obsidian bricks."
|
||||||
|
msgstr "Montar 100 tijolos de obsidiana."
|
||||||
|
|
||||||
|
#: init.lua
|
||||||
|
msgid "Build a Cave"
|
||||||
|
msgstr "Montar uma Caverna"
|
||||||
|
|
||||||
|
#: init.lua
|
||||||
|
msgid "Place 100 stone."
|
||||||
|
msgstr "Colocar 100 pedras."
|
||||||
|
|
||||||
|
#: init.lua
|
||||||
|
msgid "Long Ladder"
|
||||||
|
msgstr "Longa Escadaria"
|
||||||
|
|
||||||
|
#: init.lua
|
||||||
|
msgid "Place 400 wooden ladders."
|
||||||
|
msgstr "Colocar 400 escadas de madeira."
|
||||||
|
|
||||||
|
#: init.lua
|
||||||
|
msgid "Industrial Age"
|
||||||
|
msgstr "Era Industrial"
|
||||||
|
|
||||||
|
#: init.lua
|
||||||
|
msgid "Place 40 steel ladders."
|
||||||
|
msgstr "Colocar 40 escadas de ferro."
|
||||||
|
|
||||||
|
#: init.lua
|
||||||
|
msgid "Yummy!"
|
||||||
|
msgstr "Humm!"
|
||||||
|
|
||||||
|
#: init.lua
|
||||||
|
msgid "Eat 80 apples."
|
||||||
|
msgstr "Comer 80 maçãs."
|
||||||
|
|
||||||
|
#: init.lua
|
||||||
|
msgid "Glasser"
|
||||||
|
msgstr "Vidraceiro"
|
||||||
|
|
||||||
|
#: init.lua
|
||||||
|
msgid "Craft 14 vessels shelves."
|
||||||
|
msgstr "Montar 14 estantes de frascos."
|
||||||
|
|
||||||
|
#: init.lua
|
||||||
|
msgid "Farming Skills Acquired"
|
||||||
|
msgstr "Conhecimento de Cultivo Adquirido"
|
||||||
|
|
||||||
|
#: init.lua
|
||||||
|
msgid "Harvest a fully grown wheat plant."
|
||||||
|
msgstr "Colher um trigo totalmente crescido."
|
||||||
|
|
||||||
|
#: init.lua
|
||||||
|
msgid "Field Worker"
|
||||||
|
msgstr "Trabalhador do Campo"
|
||||||
|
|
||||||
|
#: init.lua
|
||||||
|
msgid "Harvest 25 fully grown wheat plants."
|
||||||
|
msgstr "Colher 25 plantas trigos totalmente crescidos."
|
||||||
|
|
||||||
|
#: init.lua
|
||||||
|
msgid "Aspiring Farmer"
|
||||||
|
msgstr "Fazendeiro Aspirante"
|
||||||
|
|
||||||
|
#: init.lua
|
||||||
|
msgid "Harvest 125 fully grown wheat plants."
|
||||||
|
msgstr "Colher 125 plantas trigos totalmente crescidos."
|
||||||
|
|
||||||
|
#: init.lua
|
||||||
|
msgid "Wheat Magnate"
|
||||||
|
msgstr "Magnata do Trigo"
|
||||||
|
|
||||||
|
#: init.lua
|
||||||
|
msgid "Harvest 625 fully grown wheat plants."
|
||||||
|
msgstr "Colher 625 plantas trigos totalmente crescidos."
|
||||||
|
|
||||||
|
#: init.lua
|
||||||
|
msgid "Baker"
|
||||||
|
msgstr "Padeiro"
|
||||||
|
|
||||||
|
#: init.lua
|
||||||
|
msgid "Eat 10 loaves of bread."
|
||||||
|
msgstr "Comer 10 pães."
|
||||||
|
|
||||||
|
#: init.lua
|
||||||
|
msgid "Wool Over Your Eyes"
|
||||||
|
msgstr "Lã Sobre Meus Olhos"
|
||||||
|
|
||||||
|
#: init.lua
|
||||||
|
msgid "Craft 250 white wool."
|
||||||
|
msgstr "Tecer 250 lãs branca."
|
||||||
|
|
||||||
|
#: init.lua
|
||||||
|
msgid "Hotelier"
|
||||||
|
msgstr "Hoteleiro"
|
||||||
|
|
||||||
|
#: init.lua
|
||||||
|
msgid "Craft 15 fancy beds."
|
||||||
|
msgstr "Montar 15 camas chiques."
|
||||||
|
|
||||||
|
#: init.lua
|
||||||
|
msgid "Filthy Rich"
|
||||||
|
msgstr "Muito Rico"
|
||||||
|
|
||||||
|
#: init.lua
|
||||||
|
msgid "Craft 24 gold block stairs."
|
||||||
|
msgstr "Montar 24 escadas de bloco de ouro."
|
||||||
|
|
||||||
|
#: init.lua
|
||||||
|
msgid "Roses Are Red"
|
||||||
|
msgstr "Rosas São Vermelhas"
|
||||||
|
|
||||||
|
#: init.lua
|
||||||
|
msgid "Craft 400 red dyes."
|
||||||
|
msgstr "Fazer 400 tintas vermelhas."
|
||||||
|
|
||||||
|
#: init.lua
|
||||||
|
msgid "Dandelions are Yellow"
|
||||||
|
msgstr "Dentes-de-Leões são Amarelos"
|
||||||
|
|
||||||
|
#: init.lua
|
||||||
|
msgid "Craft 400 yellow dyes."
|
||||||
|
msgstr "Fazer 400 tintas amarelas."
|
||||||
|
|
||||||
|
#: init.lua
|
||||||
|
msgid "Geraniums are Blue"
|
||||||
|
msgstr "Gerânios são Azuis"
|
||||||
|
|
||||||
|
#: init.lua
|
||||||
|
msgid "Craft 400 blue dyes."
|
||||||
|
msgstr "Fazer 400 tintas azuis."
|
||||||
|
|
||||||
|
#: init.lua
|
||||||
|
msgid "White Color Stock"
|
||||||
|
msgstr "Estoque de Cor Branca"
|
||||||
|
|
||||||
|
#: init.lua
|
||||||
|
msgid "Craft 100 white dyes."
|
||||||
|
msgstr "Fazer 100 tintas brancas."
|
||||||
|
|
||||||
|
#: init.lua
|
||||||
|
msgid "Tasty Mushrooms"
|
||||||
|
msgstr "Cogumelos Deliciosos"
|
||||||
|
|
||||||
|
#: init.lua
|
||||||
|
msgid "Eat 3 brown mushrooms."
|
||||||
|
msgstr "Comer 3 cogumelos marrons."
|
||||||
|
|
||||||
|
#: init.lua
|
||||||
|
msgid "Mushroom Lover"
|
||||||
|
msgstr "Amante de Cogumelo"
|
||||||
|
|
||||||
|
#: init.lua
|
||||||
|
msgid "Eat 33 brown mushrooms."
|
||||||
|
msgstr "Comer 33 cogumelos marrons."
|
||||||
|
|
||||||
|
#: init.lua
|
||||||
|
msgid "Underground Mushroom Farmer"
|
||||||
|
msgstr "Fazendeiro Subterrâneo de Cogumelos"
|
||||||
|
|
||||||
|
#: init.lua
|
||||||
|
msgid "Eat 333 brown mushrooms."
|
||||||
|
msgstr "Comer 333 cogumelos marrons."
|
||||||
|
|
||||||
|
#: init.lua
|
||||||
|
msgid "Builder"
|
||||||
|
msgstr "Construtor"
|
||||||
|
|
||||||
|
#: init.lua
|
||||||
|
msgid "Constructor"
|
||||||
|
msgstr "Empreiteiro"
|
||||||
|
|
||||||
|
#: init.lua
|
||||||
|
msgid "Architect"
|
||||||
|
msgstr "Arquiteto"
|
||||||
|
|
||||||
|
#: init.lua
|
||||||
|
msgid "Master Architect"
|
||||||
|
msgstr "Arquiteto Mestre"
|
||||||
|
|
||||||
|
#: chat_commands.lua
|
||||||
|
msgid "[c|clear|disable|enable]"
|
||||||
|
msgstr "[c|clear|disable|enable]"
|
||||||
|
|
||||||
|
#: chat_commands.lua
|
||||||
|
msgid "Show, clear, disable or enable your achievements"
|
||||||
|
msgstr "Exibir, limpar, desabilitar ou habilitar suas conquistas"
|
||||||
|
|
||||||
|
#: chat_commands.lua
|
||||||
|
msgid "All your awards and statistics have been cleared. You can now start again."
|
||||||
|
msgstr "Todas as suas conquistas e estatísticas foram limpas. Agora podes iniciar novamente."
|
||||||
|
|
||||||
|
#: chat_commands.lua
|
||||||
|
msgid "You have disabled your achievements."
|
||||||
|
msgstr "Suas conquistas foram desabilitadas."
|
||||||
|
|
||||||
|
#: chat_commands.lua
|
||||||
|
msgid "You have enabled your achievements."
|
||||||
|
msgstr "Suas conquistas foram habilitadas."
|
||||||
|
|
||||||
|
#: chat_commands.lua
|
||||||
|
msgid "<achievement ID>"
|
||||||
|
msgstr "<ID da conquista>"
|
||||||
|
|
||||||
|
#: chat_commands.lua
|
||||||
|
msgid "Show details of an achievement"
|
||||||
|
msgstr "Mostra detalhes de uma conquista"
|
||||||
|
|
||||||
|
#: chat_commands.lua
|
||||||
|
msgid "Achievement not found."
|
||||||
|
msgstr "Conquista não encontrada."
|
||||||
|
|
||||||
|
#: chat_commands.lua
|
||||||
|
msgid "<name>"
|
||||||
|
msgstr "<jogador>"
|
||||||
|
|
||||||
|
#: chat_commands.lua
|
||||||
|
msgid "Get the achievements statistics for the given player or yourself"
|
||||||
|
msgstr "Ver as estatísticas de conquistas de um jogador ou suas próprias"
|
|
@ -0,0 +1,819 @@
|
||||||
|
# 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-21 05:50-0300\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=UTF-8\n"
|
||||||
|
"Content-Transfer-Encoding: 8bit\n"
|
||||||
|
"Plural-Forms: nplurals=INTEGER; plural=EXPRESSION;\n"
|
||||||
|
|
||||||
|
#: api.lua
|
||||||
|
msgid "Secret Achievement Unlocked:"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: api.lua
|
||||||
|
msgid "Achievement Unlocked:"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: api.lua
|
||||||
|
#, lua-format
|
||||||
|
msgid "Secret Achievement Unlocked: %s"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: api.lua
|
||||||
|
#, lua-format
|
||||||
|
msgid "Achievement Unlocked: %s"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: api.lua
|
||||||
|
msgid "Secret Achievement Unlocked!"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: api.lua
|
||||||
|
msgid "Achievement Unlocked!"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: api.lua
|
||||||
|
msgid "Error: No awards available."
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: api.lua
|
||||||
|
msgid "OK"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: api.lua
|
||||||
|
msgid "(Secret Award)"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: api.lua
|
||||||
|
msgid "Unlock this award to find out what it is."
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: api.lua
|
||||||
|
#, lua-format
|
||||||
|
msgid "%s (got)"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: api.lua
|
||||||
|
msgid "You've disabled awards. Type /awards enable to reenable."
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: api.lua
|
||||||
|
msgid "You have not unlocked any awards."
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: api.lua
|
||||||
|
#, lua-format
|
||||||
|
msgid "%s’s awards:"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: api.lua chat_commands.lua
|
||||||
|
#, lua-format
|
||||||
|
msgid "%s: %s"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: sfinv.lua unified_inventory.lua
|
||||||
|
msgid "Awards"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: triggers.lua
|
||||||
|
msgid "@1/@2 dug"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#. Translators: @1 is count, @2 is description.
|
||||||
|
#: triggers.lua
|
||||||
|
msgid "Mine: @2"
|
||||||
|
msgid_plural "Mine: @1×@2"
|
||||||
|
msgstr[0] ""
|
||||||
|
msgstr[1] ""
|
||||||
|
|
||||||
|
#: triggers.lua
|
||||||
|
msgid "Mine @1 block."
|
||||||
|
msgid_plural "Mine @1 blocks."
|
||||||
|
msgstr[0] ""
|
||||||
|
msgstr[1] ""
|
||||||
|
|
||||||
|
#: triggers.lua
|
||||||
|
msgid "@1/@2 placed"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#. Translators: @1 is count, @2 is description.
|
||||||
|
#: triggers.lua
|
||||||
|
msgid "Place: @2"
|
||||||
|
msgid_plural "Place: @1×@2"
|
||||||
|
msgstr[0] ""
|
||||||
|
msgstr[1] ""
|
||||||
|
|
||||||
|
#: triggers.lua
|
||||||
|
msgid "Place a block."
|
||||||
|
msgid_plural "Place @1 blocks."
|
||||||
|
msgstr[0] ""
|
||||||
|
msgstr[1] ""
|
||||||
|
|
||||||
|
#: triggers.lua
|
||||||
|
msgid "@1/@2 eaten"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#. Translators: @1 is count, @2 is description.
|
||||||
|
#: triggers.lua
|
||||||
|
msgid "Eat: @2"
|
||||||
|
msgid_plural "Eat: @1×@2"
|
||||||
|
msgstr[0] ""
|
||||||
|
msgstr[1] ""
|
||||||
|
|
||||||
|
#: triggers.lua
|
||||||
|
msgid "Eat an item."
|
||||||
|
msgid_plural "Eat @1 items."
|
||||||
|
msgstr[0] ""
|
||||||
|
msgstr[1] ""
|
||||||
|
|
||||||
|
#: triggers.lua
|
||||||
|
msgid "@1/@2 deaths"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: triggers.lua
|
||||||
|
msgid "Die."
|
||||||
|
msgid_plural "Die @1 times."
|
||||||
|
msgstr[0] ""
|
||||||
|
msgstr[1] ""
|
||||||
|
|
||||||
|
#: triggers.lua
|
||||||
|
msgid "@1/@2 chat messages"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: triggers.lua
|
||||||
|
msgid "Write something in chat."
|
||||||
|
msgid_plural "Write @1 chat messages."
|
||||||
|
msgstr[0] ""
|
||||||
|
msgstr[1] ""
|
||||||
|
|
||||||
|
#: triggers.lua
|
||||||
|
msgid "@1/@2 game joins"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: triggers.lua
|
||||||
|
msgid "Join the game."
|
||||||
|
msgid_plural "Join the game @1 times."
|
||||||
|
msgstr[0] ""
|
||||||
|
msgstr[1] ""
|
||||||
|
|
||||||
|
#: triggers.lua
|
||||||
|
msgid "@1/@2 crafted"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#. Translators: @1 is count, @2 is description.
|
||||||
|
#: triggers.lua
|
||||||
|
msgid "Craft: @2"
|
||||||
|
msgid_plural "Craft: @1×@2"
|
||||||
|
msgstr[0] ""
|
||||||
|
msgstr[1] ""
|
||||||
|
|
||||||
|
#: triggers.lua
|
||||||
|
msgid "Craft an item."
|
||||||
|
msgid_plural "Craft @1 items."
|
||||||
|
msgstr[0] ""
|
||||||
|
msgstr[1] ""
|
||||||
|
|
||||||
|
#: init.lua
|
||||||
|
msgid "Saint-Maclou"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: init.lua
|
||||||
|
msgid "Place 20 coal checkers."
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: init.lua
|
||||||
|
msgid "Castorama"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: init.lua
|
||||||
|
msgid "Place 20 iron checkers."
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: init.lua
|
||||||
|
msgid "Sam the Trapper"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: init.lua
|
||||||
|
msgid "Place 2 trap stones."
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: init.lua
|
||||||
|
msgid "Backpacker"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: init.lua
|
||||||
|
msgid "Craft 4 large bags."
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: init.lua
|
||||||
|
msgid "Pyromaniac"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: init.lua
|
||||||
|
msgid "Craft 8 times flint and steel."
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: init.lua
|
||||||
|
msgid "Firefighter"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: init.lua
|
||||||
|
msgid "Put out 1000 fires."
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: init.lua
|
||||||
|
msgid "Light It Up"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: init.lua
|
||||||
|
msgid "Place 100 torches."
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: init.lua
|
||||||
|
msgid "Well Lit"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: init.lua
|
||||||
|
msgid "Place 1,000 torches."
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: init.lua
|
||||||
|
msgid "Really Well Lit"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: init.lua
|
||||||
|
msgid "Craft 10 mese lamps."
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: init.lua
|
||||||
|
msgid "Outpost"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: init.lua
|
||||||
|
msgid "Craft 200 stone bricks."
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: init.lua
|
||||||
|
msgid "Watchtower"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: init.lua
|
||||||
|
msgid "Craft 800 stone bricks."
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: init.lua
|
||||||
|
msgid "Fortress"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: init.lua
|
||||||
|
msgid "Craft 3,200 stone bricks."
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: init.lua
|
||||||
|
msgid "Desert Dweller"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: init.lua
|
||||||
|
msgid "Craft 400 desert stone bricks."
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: init.lua
|
||||||
|
msgid "Pharaoh"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: init.lua
|
||||||
|
msgid "Craft 100 sandstone bricks."
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: init.lua
|
||||||
|
msgid "Little Library"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: init.lua
|
||||||
|
msgid "Craft 7 bookshelves."
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: init.lua
|
||||||
|
msgid "Lava and Water"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: init.lua
|
||||||
|
msgid "Mine your first obsidian."
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: init.lua
|
||||||
|
msgid "Obsessed with Obsidian"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: init.lua
|
||||||
|
msgid "Mine 50 obsidian."
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: init.lua
|
||||||
|
msgid "Lava Miner"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: init.lua
|
||||||
|
msgid "Mine any block while being very close to lava."
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: init.lua
|
||||||
|
msgid "On The Way"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: init.lua
|
||||||
|
msgid "Place 100 rails."
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: init.lua
|
||||||
|
msgid "First Day in the Woods"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: init.lua
|
||||||
|
msgid "Dig 6 tree blocks."
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: init.lua
|
||||||
|
msgid "Lumberjack"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: init.lua
|
||||||
|
msgid "Dig 36 tree blocks."
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: init.lua
|
||||||
|
msgid "Semi-pro Lumberjack"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: init.lua
|
||||||
|
msgid "Dig 216 tree blocks."
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: init.lua
|
||||||
|
msgid "Professional Lumberjack"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: init.lua
|
||||||
|
msgid "Dig 1,296 tree blocks."
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: init.lua
|
||||||
|
msgid "Junglebaby"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: init.lua
|
||||||
|
msgid "Dig 100 jungle tree blocks."
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: init.lua
|
||||||
|
msgid "Jungleman"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: init.lua
|
||||||
|
msgid "Dig 1,000 jungle tree blocks."
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: init.lua
|
||||||
|
msgid "First Mese Find"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: init.lua
|
||||||
|
msgid "Mine your first mese ore."
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: init.lua
|
||||||
|
msgid "Mese Mastery"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: init.lua
|
||||||
|
msgid "Mine a mese block."
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: init.lua
|
||||||
|
msgid "You’re a copper"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: init.lua
|
||||||
|
msgid "Dig 1,000 copper ores."
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: init.lua
|
||||||
|
msgid "A Cat in a Pop-Tart?!"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: init.lua
|
||||||
|
msgid "Mine a nyan cat."
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: init.lua
|
||||||
|
msgid "Mini Miner"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: init.lua
|
||||||
|
msgid "Dig 100 stone blocks."
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: init.lua
|
||||||
|
msgid "Hardened Miner"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: init.lua
|
||||||
|
msgid "Dig 1,000 stone blocks."
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: init.lua
|
||||||
|
msgid "Master Miner"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: init.lua
|
||||||
|
msgid "Dig 10,000 stone blocks."
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: init.lua
|
||||||
|
msgid "Marchand De Sable"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: init.lua
|
||||||
|
msgid "Dig 1,000 sand."
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: init.lua
|
||||||
|
msgid "Crafter of Sticks"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: init.lua
|
||||||
|
msgid "Craft 100 sticks."
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: init.lua
|
||||||
|
msgid "Jungle Discoverer"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: init.lua
|
||||||
|
msgid "Mine your first jungle grass."
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: init.lua
|
||||||
|
msgid "Grasslands Discoverer"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: init.lua
|
||||||
|
msgid "Mine some grass."
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: init.lua
|
||||||
|
msgid "Savannah Discoverer"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: init.lua
|
||||||
|
msgid "Mine some dry grass."
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: init.lua
|
||||||
|
msgid "Desert Discoverer"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: init.lua
|
||||||
|
msgid "Mine your first cactus."
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: init.lua
|
||||||
|
msgid "Far Lands"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: init.lua
|
||||||
|
msgid "Mine your first dry shrub."
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: init.lua
|
||||||
|
msgid "Glacier Discoverer"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: init.lua
|
||||||
|
msgid "Mine your first ice."
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: init.lua
|
||||||
|
msgid "Very Simple Snow Man"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: init.lua
|
||||||
|
msgid "Place two snow blocks."
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: init.lua
|
||||||
|
msgid "First Gold Find"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: init.lua
|
||||||
|
msgid "Mine your first gold ore."
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: init.lua
|
||||||
|
msgid "Gold Rush"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: init.lua
|
||||||
|
msgid "Mine 45 gold ores."
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: init.lua
|
||||||
|
msgid "Wow, I am Diamonds!"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: init.lua
|
||||||
|
msgid "Mine your first diamond ore."
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: init.lua
|
||||||
|
msgid "Girl's Best Friend"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: init.lua
|
||||||
|
msgid "Mine 18 diamond ores."
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: init.lua
|
||||||
|
msgid "Hardest Block on Earth"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: init.lua
|
||||||
|
msgid "Craft a diamond block."
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: init.lua
|
||||||
|
msgid "In the Dungeon"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: init.lua
|
||||||
|
msgid "Mine a mossy cobblestone."
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: init.lua
|
||||||
|
msgid "Smelter"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: init.lua
|
||||||
|
msgid "Craft 10 furnaces."
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: init.lua
|
||||||
|
msgid "Treasurer"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: init.lua
|
||||||
|
msgid "Craft 15 chests."
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: init.lua
|
||||||
|
msgid "Bankier"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: init.lua
|
||||||
|
msgid "Craft 30 locked chests."
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: init.lua
|
||||||
|
msgid "Bricker"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: init.lua
|
||||||
|
msgid "Craft 200 brick blocks."
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: init.lua
|
||||||
|
msgid "House of Obsidian"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: init.lua
|
||||||
|
msgid "Craft 100 obsidian bricks."
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: init.lua
|
||||||
|
msgid "Build a Cave"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: init.lua
|
||||||
|
msgid "Place 100 stone."
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: init.lua
|
||||||
|
msgid "Long Ladder"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: init.lua
|
||||||
|
msgid "Place 400 wooden ladders."
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: init.lua
|
||||||
|
msgid "Industrial Age"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: init.lua
|
||||||
|
msgid "Place 40 steel ladders."
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: init.lua
|
||||||
|
msgid "Yummy!"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: init.lua
|
||||||
|
msgid "Eat 80 apples."
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: init.lua
|
||||||
|
msgid "Glasser"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: init.lua
|
||||||
|
msgid "Craft 14 vessels shelves."
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: init.lua
|
||||||
|
msgid "Farming Skills Acquired"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: init.lua
|
||||||
|
msgid "Harvest a fully grown wheat plant."
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: init.lua
|
||||||
|
msgid "Field Worker"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: init.lua
|
||||||
|
msgid "Harvest 25 fully grown wheat plants."
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: init.lua
|
||||||
|
msgid "Aspiring Farmer"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: init.lua
|
||||||
|
msgid "Harvest 125 fully grown wheat plants."
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: init.lua
|
||||||
|
msgid "Wheat Magnate"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: init.lua
|
||||||
|
msgid "Harvest 625 fully grown wheat plants."
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: init.lua
|
||||||
|
msgid "Baker"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: init.lua
|
||||||
|
msgid "Eat 10 loaves of bread."
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: init.lua
|
||||||
|
msgid "Wool Over Your Eyes"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: init.lua
|
||||||
|
msgid "Craft 250 white wool."
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: init.lua
|
||||||
|
msgid "Hotelier"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: init.lua
|
||||||
|
msgid "Craft 15 fancy beds."
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: init.lua
|
||||||
|
msgid "Filthy Rich"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: init.lua
|
||||||
|
msgid "Craft 24 gold block stairs."
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: init.lua
|
||||||
|
msgid "Roses Are Red"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: init.lua
|
||||||
|
msgid "Craft 400 red dyes."
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: init.lua
|
||||||
|
msgid "Dandelions are Yellow"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: init.lua
|
||||||
|
msgid "Craft 400 yellow dyes."
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: init.lua
|
||||||
|
msgid "Geraniums are Blue"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: init.lua
|
||||||
|
msgid "Craft 400 blue dyes."
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: init.lua
|
||||||
|
msgid "White Color Stock"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: init.lua
|
||||||
|
msgid "Craft 100 white dyes."
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: init.lua
|
||||||
|
msgid "Tasty Mushrooms"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: init.lua
|
||||||
|
msgid "Eat 3 brown mushrooms."
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: init.lua
|
||||||
|
msgid "Mushroom Lover"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: init.lua
|
||||||
|
msgid "Eat 33 brown mushrooms."
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: init.lua
|
||||||
|
msgid "Underground Mushroom Farmer"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: init.lua
|
||||||
|
msgid "Eat 333 brown mushrooms."
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: init.lua
|
||||||
|
msgid "Builder"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: init.lua
|
||||||
|
msgid "Constructor"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: init.lua
|
||||||
|
msgid "Architect"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: init.lua
|
||||||
|
msgid "Master Architect"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: chat_commands.lua
|
||||||
|
msgid "[c|clear|disable|enable]"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: chat_commands.lua
|
||||||
|
msgid "Show, clear, disable or enable your achievements"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: chat_commands.lua
|
||||||
|
msgid ""
|
||||||
|
"All your awards and statistics have been cleared. You can now start again."
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: chat_commands.lua
|
||||||
|
msgid "You have disabled your achievements."
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: chat_commands.lua
|
||||||
|
msgid "You have enabled your achievements."
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: chat_commands.lua
|
||||||
|
msgid "<achievement ID>"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: chat_commands.lua
|
||||||
|
msgid "Show details of an achievement"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: chat_commands.lua
|
||||||
|
msgid "Achievement not found."
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: chat_commands.lua
|
||||||
|
msgid "<name>"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: chat_commands.lua
|
||||||
|
msgid "Get the achievements statistics for the given player or yourself"
|
||||||
|
msgstr ""
|
|
@ -0,0 +1,8 @@
|
||||||
|
name = awards
|
||||||
|
title = Awards
|
||||||
|
author = rubenwardy
|
||||||
|
description = Adds awards to Minetest, and an API to register new ones.
|
||||||
|
optional_depends = intllib,sfinv,unified_inventory,default,stairs,farming,dye,beds,wool,vessels,moreblocks,fire,flowers,nyancat
|
||||||
|
license = MIT
|
||||||
|
forum = https://forum.minetest.net/viewtopic.php?t=4870
|
||||||
|
version = 3.0.0
|
After Width: | Height: | Size: 62 KiB |
|
@ -0,0 +1,179 @@
|
||||||
|
-- Copyright (c) 2013-18 rubenwardy. MIT.
|
||||||
|
|
||||||
|
local S = awards.gettext
|
||||||
|
|
||||||
|
function awards.register_award(name, def)
|
||||||
|
def.name = name
|
||||||
|
|
||||||
|
-- Add Triggers
|
||||||
|
if def.trigger and def.trigger.type then
|
||||||
|
local tdef = awards.registered_triggers[def.trigger.type]
|
||||||
|
assert(tdef, "Trigger not found: " .. def.trigger.type)
|
||||||
|
tdef:on_register(def)
|
||||||
|
end
|
||||||
|
|
||||||
|
function def:can_unlock(data)
|
||||||
|
if not self.requires then
|
||||||
|
return true
|
||||||
|
end
|
||||||
|
|
||||||
|
for i=1, #self.requires do
|
||||||
|
if not data.unlocked[self.requires[i]] then
|
||||||
|
return false
|
||||||
|
end
|
||||||
|
end
|
||||||
|
return true
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Add Award
|
||||||
|
awards.registered_awards[name] = def
|
||||||
|
|
||||||
|
local tdef = awards.registered_awards[name]
|
||||||
|
if def.description == nil and tdef.getDefaultDescription then
|
||||||
|
def.description = tdef:getDefaultDescription()
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
-- This function is called whenever a target condition is met.
|
||||||
|
-- It checks if a player already has that award, and if they do not,
|
||||||
|
-- it gives it to them
|
||||||
|
----------------------------------------------
|
||||||
|
--awards.unlock(name, award)
|
||||||
|
-- name - the name of the player
|
||||||
|
-- award - the name of the award to give
|
||||||
|
function awards.unlock(name, award)
|
||||||
|
-- Access Player Data
|
||||||
|
local data = awards.player(name)
|
||||||
|
local awdef = awards.registered_awards[award]
|
||||||
|
assert(awdef, "Unable to unlock an award which doesn't exist!")
|
||||||
|
|
||||||
|
if data.disabled or
|
||||||
|
(data.unlocked[award] and data.unlocked[award] == award) then
|
||||||
|
return
|
||||||
|
end
|
||||||
|
|
||||||
|
if not awdef:can_unlock(data) then
|
||||||
|
minetest.log("warning", "can_unlock returned false in unlock of " ..
|
||||||
|
award .. " for " .. name)
|
||||||
|
return
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Unlock Award
|
||||||
|
minetest.log("action", name.." has unlocked award "..name)
|
||||||
|
data.unlocked[award] = award
|
||||||
|
awards.save()
|
||||||
|
|
||||||
|
-- Give Prizes
|
||||||
|
if awdef and awdef.prizes then
|
||||||
|
for i = 1, #awdef.prizes do
|
||||||
|
local itemstack = ItemStack(awdef.prizes[i])
|
||||||
|
if not itemstack:is_empty() then
|
||||||
|
local receiverref = minetest.get_player_by_name(name)
|
||||||
|
if receiverref then
|
||||||
|
receiverref:get_inventory():add_item("main", itemstack)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Run callbacks
|
||||||
|
if awdef.on_unlock and awdef.on_unlock(name, awdef) then
|
||||||
|
return
|
||||||
|
end
|
||||||
|
for _, callback in pairs(awards.on_unlock) do
|
||||||
|
if callback(name, awdef) then
|
||||||
|
return
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Get Notification Settings
|
||||||
|
local title = awdef.title or award
|
||||||
|
local desc = awdef.description or ""
|
||||||
|
local background = awdef.background or "awards_bg_default.png"
|
||||||
|
local icon = awdef.icon or "awards_unknown.png"
|
||||||
|
local sound = awdef.sound
|
||||||
|
if sound == nil then
|
||||||
|
-- Explicit check for nil because sound could be `false` to disable it
|
||||||
|
sound = {name="awards_got_generic", gain=0.25}
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Do Notification
|
||||||
|
if sound then
|
||||||
|
-- Enforce sound delay to prevent sound spamming
|
||||||
|
local lastsound = data.lastsound
|
||||||
|
if lastsound == nil or os.difftime(os.time(), lastsound) >= 1 then
|
||||||
|
minetest.sound_play(sound, {to_player=name})
|
||||||
|
data.lastsound = os.time()
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
if awards.show_mode == "chat" then
|
||||||
|
local chat_announce
|
||||||
|
if awdef.secret then
|
||||||
|
chat_announce = S("Secret Award Unlocked: %s")
|
||||||
|
else
|
||||||
|
chat_announce = S("Award Unlocked: %s")
|
||||||
|
end
|
||||||
|
-- use the chat console to send it
|
||||||
|
minetest.chat_send_player(name, string.format(chat_announce, title))
|
||||||
|
if desc~="" then
|
||||||
|
minetest.chat_send_player(name, desc)
|
||||||
|
end
|
||||||
|
else
|
||||||
|
local player = minetest.get_player_by_name(name)
|
||||||
|
local one = player:hud_add({
|
||||||
|
hud_elem_type = "image",
|
||||||
|
name = "award_bg",
|
||||||
|
scale = {x = 2, y = 1},
|
||||||
|
text = background,
|
||||||
|
position = {x = 0.5, y = 0.05},
|
||||||
|
offset = {x = 0, y = 138},
|
||||||
|
alignment = {x = 0, y = -1}
|
||||||
|
})
|
||||||
|
local hud_announce
|
||||||
|
if awdef.secret then
|
||||||
|
hud_announce = S("Secret Award Unlocked!")
|
||||||
|
else
|
||||||
|
hud_announce = S("Award Unlocked!")
|
||||||
|
end
|
||||||
|
local two = player:hud_add({
|
||||||
|
hud_elem_type = "text",
|
||||||
|
name = "award_au",
|
||||||
|
number = 0xFFFFFF,
|
||||||
|
scale = {x = 100, y = 20},
|
||||||
|
text = hud_announce,
|
||||||
|
position = {x = 0.5, y = 0.05},
|
||||||
|
offset = {x = 0, y = 45},
|
||||||
|
alignment = {x = 0, y = -1}
|
||||||
|
})
|
||||||
|
local three = player:hud_add({
|
||||||
|
hud_elem_type = "text",
|
||||||
|
name = "award_title",
|
||||||
|
number = 0xFFFFFF,
|
||||||
|
scale = {x = 100, y = 20},
|
||||||
|
text = title,
|
||||||
|
position = {x = 0.5, y = 0.05},
|
||||||
|
offset = {x = 0, y = 100},
|
||||||
|
alignment = {x = 0, y = -1}
|
||||||
|
})
|
||||||
|
local four = player:hud_add({
|
||||||
|
hud_elem_type = "image",
|
||||||
|
name = "award_icon",
|
||||||
|
scale = {x = 2, y = 2}, -- adjusted for 32x32 from x/y = 4
|
||||||
|
text = icon,
|
||||||
|
position = {x = 0.5, y = 0.05},
|
||||||
|
offset = {x = -200.5, y = 126},
|
||||||
|
alignment = {x = 0, y = -1}
|
||||||
|
})
|
||||||
|
minetest.after(4, function()
|
||||||
|
local player2 = minetest.get_player_by_name(name)
|
||||||
|
if player2 then
|
||||||
|
player2:hud_remove(one)
|
||||||
|
player2:hud_remove(two)
|
||||||
|
player2:hud_remove(three)
|
||||||
|
player2:hud_remove(four)
|
||||||
|
end
|
||||||
|
end)
|
||||||
|
end
|
||||||
|
end
|
|
@ -0,0 +1,218 @@
|
||||||
|
-- Copyright (c) 2013-18 rubenwardy. MIT.
|
||||||
|
|
||||||
|
local S, NS = awards.gettext, awards.ngettext
|
||||||
|
|
||||||
|
awards.registered_awards = {}
|
||||||
|
awards.on = {}
|
||||||
|
awards.on_unlock = {}
|
||||||
|
|
||||||
|
local default_def = {}
|
||||||
|
|
||||||
|
function default_def:run_callbacks(player, data, table_func)
|
||||||
|
for i = 1, #self.on do
|
||||||
|
local res = nil
|
||||||
|
local entry = self.on[i]
|
||||||
|
if type(entry) == "function" then
|
||||||
|
res = entry(player, data)
|
||||||
|
elseif type(entry) == "table" and entry.award then
|
||||||
|
res = table_func(entry)
|
||||||
|
end
|
||||||
|
|
||||||
|
if res then
|
||||||
|
awards.unlock(player:get_player_name(), res)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
function awards.register_trigger(tname, tdef)
|
||||||
|
assert(type(tdef) == "table",
|
||||||
|
"Passing a callback to register_trigger is not supported in 3.0")
|
||||||
|
|
||||||
|
tdef.name = tname
|
||||||
|
for key, value in pairs(default_def) do
|
||||||
|
tdef[key] = value
|
||||||
|
end
|
||||||
|
|
||||||
|
if tdef.type == "counted" then
|
||||||
|
local old_reg = tdef.on_register
|
||||||
|
|
||||||
|
function tdef:on_register(def)
|
||||||
|
local tmp = {
|
||||||
|
award = def.name,
|
||||||
|
target = def.trigger.target,
|
||||||
|
}
|
||||||
|
tdef.register(tmp)
|
||||||
|
|
||||||
|
function def.getProgress(_, data)
|
||||||
|
local done = math.min(data[tname] or 0, tmp.target)
|
||||||
|
return {
|
||||||
|
perc = done / tmp.target,
|
||||||
|
label = S(tdef.progress, done, tmp.target),
|
||||||
|
}
|
||||||
|
end
|
||||||
|
|
||||||
|
function def.getDefaultDescription(_)
|
||||||
|
local n = def.trigger.target
|
||||||
|
return NS(tdef.auto_description[1], tdef.auto_description[2], n, n)
|
||||||
|
end
|
||||||
|
|
||||||
|
if old_reg then
|
||||||
|
return old_reg(tdef, def)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
function tdef.notify(player)
|
||||||
|
assert(player and player.is_player and player:is_player())
|
||||||
|
local name = player:get_player_name()
|
||||||
|
local data = awards.player(name)
|
||||||
|
|
||||||
|
-- Increment counter
|
||||||
|
local currentVal = (data[tname] or 0) + 1
|
||||||
|
data[tname] = currentVal
|
||||||
|
|
||||||
|
tdef:run_callbacks(player, data, function(entry)
|
||||||
|
if entry.target and entry.award and currentVal and
|
||||||
|
currentVal >= entry.target then
|
||||||
|
return entry.award
|
||||||
|
end
|
||||||
|
end)
|
||||||
|
end
|
||||||
|
|
||||||
|
awards["notify_" .. tname] = tdef.notify
|
||||||
|
|
||||||
|
elseif tdef.type == "counted_key" then
|
||||||
|
if tdef.key_is_item then
|
||||||
|
tdef.watched_groups = {}
|
||||||
|
end
|
||||||
|
|
||||||
|
-- On award register
|
||||||
|
local old_reg = tdef.on_register
|
||||||
|
function tdef:on_register(def)
|
||||||
|
-- Register trigger
|
||||||
|
local tmp = {
|
||||||
|
award = def.name,
|
||||||
|
key = tdef:get_key(def),
|
||||||
|
target = def.trigger.target,
|
||||||
|
}
|
||||||
|
tdef.register(tmp)
|
||||||
|
|
||||||
|
-- If group, add it to watch list
|
||||||
|
if tdef.key_is_item and tmp.key and tmp.key:sub(1, 6) == "group:" then
|
||||||
|
tdef.watched_groups[tmp.key:sub(7, #tmp.key)] = true
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Called to get progress values and labels
|
||||||
|
function def.getProgress(_, data)
|
||||||
|
data[tname] = data[tname] or {}
|
||||||
|
|
||||||
|
local done
|
||||||
|
if tmp.key then
|
||||||
|
done = data[tname][tmp.key] or 0
|
||||||
|
else
|
||||||
|
done = data[tname].__total or 0
|
||||||
|
end
|
||||||
|
done = math.min(done, tmp.target)
|
||||||
|
|
||||||
|
return {
|
||||||
|
perc = done / tmp.target,
|
||||||
|
label = S(tdef.progress, done, tmp.target),
|
||||||
|
}
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Build description if none is specificed by the award
|
||||||
|
function def.getDefaultDescription(_)
|
||||||
|
local n = def.trigger.target
|
||||||
|
if tmp.key then
|
||||||
|
local nname = tmp.key
|
||||||
|
return NS(tdef.auto_description[1],
|
||||||
|
tdef.auto_description[2], n, n, nname)
|
||||||
|
else
|
||||||
|
return NS(tdef.auto_description_total[1],
|
||||||
|
tdef.auto_description_total[2], n, n)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Call on_register in trigger type definition
|
||||||
|
if old_reg then
|
||||||
|
return old_reg(tdef, def)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
function tdef.notify(player, key, n)
|
||||||
|
n = n or 1
|
||||||
|
|
||||||
|
if tdef.key_is_item and key:sub(1, 6) ~= "group:" then
|
||||||
|
local itemdef = minetest.registered_items[key]
|
||||||
|
if itemdef then
|
||||||
|
for groupname, _ in pairs(itemdef.groups or {}) do
|
||||||
|
if tdef.watched_groups[groupname] then
|
||||||
|
tdef.notify(player, "group:" .. groupname, n)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
assert(player and player.is_player and player:is_player() and key)
|
||||||
|
local name = player:get_player_name()
|
||||||
|
local data = awards.player(name)
|
||||||
|
|
||||||
|
-- Increment counter
|
||||||
|
data[tname] = data[tname] or {}
|
||||||
|
local currentVal = (data[tname][key] or 0) + n
|
||||||
|
data[tname][key] = currentVal
|
||||||
|
if key:sub(1, 6) ~= "group:" then
|
||||||
|
data[tname].__total = (data[tname].__total or 0) + n
|
||||||
|
end
|
||||||
|
|
||||||
|
tdef:run_callbacks(player, data, function(entry)
|
||||||
|
local current
|
||||||
|
if entry.key == key then
|
||||||
|
current = currentVal
|
||||||
|
elseif entry.key == nil then
|
||||||
|
current = data[tname].__total
|
||||||
|
else
|
||||||
|
return
|
||||||
|
end
|
||||||
|
|
||||||
|
if current >= entry.target then
|
||||||
|
return entry.award
|
||||||
|
end
|
||||||
|
end)
|
||||||
|
end
|
||||||
|
|
||||||
|
awards["notify_" .. tname] = tdef.notify
|
||||||
|
|
||||||
|
elseif tdef.type and tdef.type ~= "custom" then
|
||||||
|
error("Unrecognised trigger type " .. tdef.type)
|
||||||
|
end
|
||||||
|
|
||||||
|
awards.registered_triggers[tname] = tdef
|
||||||
|
|
||||||
|
tdef.on = {}
|
||||||
|
tdef.register = function(func)
|
||||||
|
table.insert(tdef.on, func)
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Backwards compat
|
||||||
|
awards.on[tname] = tdef.on
|
||||||
|
awards['register_on_' .. tname] = tdef.register
|
||||||
|
return tdef
|
||||||
|
end
|
||||||
|
|
||||||
|
function awards.increment_item_counter(data, field, itemname, count)
|
||||||
|
itemname = minetest.registered_aliases[itemname] or itemname
|
||||||
|
data[field][itemname] = (data[field][itemname] or 0) + 1
|
||||||
|
end
|
||||||
|
|
||||||
|
function awards.get_item_count(data, field, itemname)
|
||||||
|
itemname = minetest.registered_aliases[itemname] or itemname
|
||||||
|
return data[field][itemname] or 0
|
||||||
|
end
|
||||||
|
|
||||||
|
function awards.get_total_keyed_count(data, field)
|
||||||
|
return data[field].__total or 0
|
||||||
|
end
|
||||||
|
|
||||||
|
function awards.register_on_unlock(func)
|
||||||
|
table.insert(awards.on_unlock, func)
|
||||||
|
end
|
|
@ -0,0 +1,61 @@
|
||||||
|
-- Copyright (c) 2013-18 rubenwardy. MIT.
|
||||||
|
|
||||||
|
local S = awards.gettext
|
||||||
|
|
||||||
|
minetest.register_chatcommand("awards", {
|
||||||
|
params = S("[c|clear|disable|enable]"),
|
||||||
|
description = S("Show, clear, disable or enable your awards"),
|
||||||
|
func = function(name, param)
|
||||||
|
if param == "clear" then
|
||||||
|
awards.clear_player(name)
|
||||||
|
minetest.chat_send_player(name,
|
||||||
|
S("All your awards and statistics have been cleared. You can now start again."))
|
||||||
|
elseif param == "disable" then
|
||||||
|
awards.disable(name)
|
||||||
|
minetest.chat_send_player(name, S("You have disabled awards."))
|
||||||
|
elseif param == "enable" then
|
||||||
|
awards.enable(name)
|
||||||
|
minetest.chat_send_player(name, S("You have enabled awards."))
|
||||||
|
elseif param == "c" then
|
||||||
|
awards.show_to(name, name, nil, true)
|
||||||
|
else
|
||||||
|
awards.show_to(name, name, nil, false)
|
||||||
|
end
|
||||||
|
|
||||||
|
if (param == "disable" or param == "enable") and minetest.global_exists("sfinv") then
|
||||||
|
local player = minetest.get_player_by_name(name)
|
||||||
|
if player then
|
||||||
|
sfinv.set_player_inventory_formspec(player)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
})
|
||||||
|
|
||||||
|
minetest.register_chatcommand("awd", {
|
||||||
|
params = S("<award ID>"),
|
||||||
|
description = S("Show details of an award"),
|
||||||
|
func = function(name, param)
|
||||||
|
local def = awards.registered_awards[param]
|
||||||
|
if def then
|
||||||
|
minetest.chat_send_player(name, string.format(S("%s: %s"), def.title, def.description))
|
||||||
|
else
|
||||||
|
minetest.chat_send_player(name, S("Award not found."))
|
||||||
|
end
|
||||||
|
end
|
||||||
|
})
|
||||||
|
|
||||||
|
minetest.register_chatcommand("awpl", {
|
||||||
|
privs = {
|
||||||
|
server = true
|
||||||
|
},
|
||||||
|
params = S("<name>"),
|
||||||
|
description = S("Get the awards statistics for the given player or yourself"),
|
||||||
|
func = function(name, param)
|
||||||
|
if not param or param == "" then
|
||||||
|
param = name
|
||||||
|
end
|
||||||
|
minetest.chat_send_player(name, param)
|
||||||
|
local player = awards.player(param)
|
||||||
|
minetest.chat_send_player(name, dump(player))
|
||||||
|
end
|
||||||
|
})
|
|
@ -0,0 +1,111 @@
|
||||||
|
|
||||||
|
local storage = minetest.get_mod_storage()
|
||||||
|
local __player_data
|
||||||
|
|
||||||
|
-- Table Save Load Functions
|
||||||
|
function awards.save()
|
||||||
|
storage:set_string("player_data", minetest.write_json(__player_data))
|
||||||
|
end
|
||||||
|
|
||||||
|
local function convert_data()
|
||||||
|
minetest.log("warning", "Importing awards data from previous version")
|
||||||
|
|
||||||
|
local old_players = __player_data
|
||||||
|
__player_data = {}
|
||||||
|
for name, data in pairs(old_players) do
|
||||||
|
while name.name do
|
||||||
|
name = name.name
|
||||||
|
end
|
||||||
|
data.name = name
|
||||||
|
print("Converting data for " .. name)
|
||||||
|
|
||||||
|
-- Just rename counted
|
||||||
|
local counted = {
|
||||||
|
chats = "chat",
|
||||||
|
deaths = "death",
|
||||||
|
joins = "join",
|
||||||
|
}
|
||||||
|
for from, to in pairs(counted) do
|
||||||
|
data[to] = data[from]
|
||||||
|
data[from] = nil
|
||||||
|
end
|
||||||
|
|
||||||
|
data.death = {
|
||||||
|
unknown = data.death,
|
||||||
|
__total = data.death,
|
||||||
|
}
|
||||||
|
|
||||||
|
-- Convert item db to new format
|
||||||
|
local counted_items = {
|
||||||
|
count = "dig",
|
||||||
|
place = "place",
|
||||||
|
craft = "craft",
|
||||||
|
}
|
||||||
|
for from, to in pairs(counted_items) do
|
||||||
|
local ret = {}
|
||||||
|
|
||||||
|
local count = 0
|
||||||
|
if data[from] then
|
||||||
|
for modname, items in pairs(data[from]) do
|
||||||
|
for itemname, value in pairs(items) do
|
||||||
|
itemname = modname .. ":" .. itemname
|
||||||
|
local key = minetest.registered_aliases[itemname] or itemname
|
||||||
|
ret[key] = value
|
||||||
|
count = count + value
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
ret.__total = count
|
||||||
|
data[from] = nil
|
||||||
|
data[to] = ret
|
||||||
|
end
|
||||||
|
|
||||||
|
__player_data[name] = data
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
function awards.load()
|
||||||
|
local old_save_path = minetest.get_worldpath().."/awards.txt"
|
||||||
|
local file = io.open(old_save_path, "r")
|
||||||
|
if file then
|
||||||
|
local table = minetest.deserialize(file:read("*all"))
|
||||||
|
if type(table) == "table" then
|
||||||
|
__player_data = table
|
||||||
|
convert_data()
|
||||||
|
else
|
||||||
|
__player_data = {}
|
||||||
|
end
|
||||||
|
file:close()
|
||||||
|
os.rename(old_save_path, minetest.get_worldpath().."/awards.bk.txt")
|
||||||
|
awards.save()
|
||||||
|
else
|
||||||
|
__player_data = minetest.parse_json(storage:get_string("player_data")) or {}
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
function awards.player(name)
|
||||||
|
assert(type(name) == "string")
|
||||||
|
local data = __player_data[name] or {}
|
||||||
|
__player_data[name] = data
|
||||||
|
|
||||||
|
data.name = data.name or name
|
||||||
|
data.unlocked = data.unlocked or {}
|
||||||
|
return data
|
||||||
|
end
|
||||||
|
|
||||||
|
function awards.player_or_nil(name)
|
||||||
|
return __player_data[name]
|
||||||
|
end
|
||||||
|
|
||||||
|
function awards.enable(name)
|
||||||
|
awards.player(name).disabled = nil
|
||||||
|
end
|
||||||
|
|
||||||
|
function awards.disable(name)
|
||||||
|
awards.player(name).disabled = true
|
||||||
|
end
|
||||||
|
|
||||||
|
function awards.clear_player(name)
|
||||||
|
__player_data[name] = {}
|
||||||
|
end
|
|
@ -0,0 +1,285 @@
|
||||||
|
-- Copyright (c) 2013-18 rubenwardy. MIT.
|
||||||
|
|
||||||
|
local S = awards.gettext
|
||||||
|
|
||||||
|
local function order_awards(name)
|
||||||
|
local hash_is_unlocked = {}
|
||||||
|
local retval = {}
|
||||||
|
|
||||||
|
local data = awards.player(name)
|
||||||
|
if data and data.unlocked then
|
||||||
|
for awardname, _ in pairs(data.unlocked) do
|
||||||
|
local def = awards.registered_awards[awardname]
|
||||||
|
if def then
|
||||||
|
hash_is_unlocked[awardname] = true
|
||||||
|
local score = -100000
|
||||||
|
|
||||||
|
local difficulty = def.difficulty or 1
|
||||||
|
if def.trigger and def.trigger.target then
|
||||||
|
difficulty = difficulty * def.trigger.target
|
||||||
|
end
|
||||||
|
score = score + difficulty
|
||||||
|
|
||||||
|
retval[#retval + 1] = {
|
||||||
|
name = awardname,
|
||||||
|
def = def,
|
||||||
|
unlocked = true,
|
||||||
|
started = true,
|
||||||
|
score = score,
|
||||||
|
}
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
for _, def in pairs(awards.registered_awards) do
|
||||||
|
if not hash_is_unlocked[def.name] and def:can_unlock(data) then
|
||||||
|
local started = false
|
||||||
|
local score = def.difficulty or 1
|
||||||
|
if def.secret then
|
||||||
|
score = 1000000
|
||||||
|
elseif def.trigger and def.trigger.target and def.getProgress then
|
||||||
|
local progress = def:getProgress(data).perc
|
||||||
|
score = score * (1 - progress) * def.trigger.target
|
||||||
|
if progress < 0.001 then
|
||||||
|
score = score + 100
|
||||||
|
else
|
||||||
|
started = true
|
||||||
|
end
|
||||||
|
else
|
||||||
|
score = 100
|
||||||
|
end
|
||||||
|
|
||||||
|
retval[#retval + 1] = {
|
||||||
|
name = def.name,
|
||||||
|
def = def,
|
||||||
|
unlocked = false,
|
||||||
|
started = started,
|
||||||
|
score = score,
|
||||||
|
}
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
table.sort(retval, function(a, b)
|
||||||
|
return a.score < b.score
|
||||||
|
end)
|
||||||
|
return retval
|
||||||
|
end
|
||||||
|
|
||||||
|
function awards.get_formspec(name, to, sid)
|
||||||
|
local formspec = ""
|
||||||
|
local awards_list = order_awards(name)
|
||||||
|
local data = awards.player(name)
|
||||||
|
|
||||||
|
if #awards_list == 0 then
|
||||||
|
formspec = formspec .. "label[3.9,1.5;"..minetest.formspec_escape(S("Error: No achivements available.")).."]"
|
||||||
|
formspec = formspec .. "button_exit[4.2,2.3;3,1;close;"..minetest.formspec_escape(S("OK")).."]"
|
||||||
|
return formspec
|
||||||
|
end
|
||||||
|
sid = awards_list[sid] and sid or 1
|
||||||
|
|
||||||
|
-- Sidebar
|
||||||
|
local sitem = awards_list[sid]
|
||||||
|
local sdef = sitem.def
|
||||||
|
if sdef and sdef.secret and not sitem.unlocked then
|
||||||
|
formspec = formspec .. "label[1,2.75;"..
|
||||||
|
minetest.formspec_escape(S("(Secret Award)")).."]"..
|
||||||
|
"image[1,0;3,3;awards_unknown.png]"
|
||||||
|
if sdef and sdef.description then
|
||||||
|
formspec = formspec .. "textarea[0.25,3.25;4.8,1.7;;"..
|
||||||
|
minetest.formspec_escape(
|
||||||
|
S("Unlock this award to find out what it is."))..";]"
|
||||||
|
end
|
||||||
|
else
|
||||||
|
local title = sitem.name
|
||||||
|
if sdef and sdef.title then
|
||||||
|
title = sdef.title
|
||||||
|
end
|
||||||
|
local status = "%s"
|
||||||
|
if sitem.unlocked then
|
||||||
|
status = S("%s (unlocked)")
|
||||||
|
end
|
||||||
|
|
||||||
|
formspec = formspec .. "textarea[0.5,3.1;4.8,1.45;;" ..
|
||||||
|
string.format(status, minetest.formspec_escape(title)) ..
|
||||||
|
";]"
|
||||||
|
|
||||||
|
if sdef and sdef.icon then
|
||||||
|
formspec = formspec .. "image[0.45,0;3.5,3.5;" .. sdef.icon .. "]" -- adjusted values from 0.6,0;3,3
|
||||||
|
end
|
||||||
|
local barwidth = 3.95
|
||||||
|
local perc = nil
|
||||||
|
local label = nil
|
||||||
|
if sdef.getProgress and data then
|
||||||
|
local res = sdef:getProgress(data)
|
||||||
|
perc = res.perc
|
||||||
|
label = res.label
|
||||||
|
end
|
||||||
|
if perc then
|
||||||
|
if perc > 1 then
|
||||||
|
perc = 1
|
||||||
|
end
|
||||||
|
formspec = formspec .. "background[0,8.24;" .. barwidth ..",0.4;awards_progress_gray.png;false]"
|
||||||
|
formspec = formspec .. "background[0,8.24;" .. (barwidth * perc) ..",0.4;awards_progress_green.png;false]"
|
||||||
|
if label then
|
||||||
|
formspec = formspec .. "label[1.6,8.15;" .. minetest.formspec_escape(label) .. "]"
|
||||||
|
end
|
||||||
|
end
|
||||||
|
if sdef and sdef.description then
|
||||||
|
formspec = formspec .. "box[-0.05,3.75;3.9,4.2;#000]"
|
||||||
|
formspec = formspec .. "textarea[0.25,3.75;3.9,4.2;;" ..
|
||||||
|
minetest.formspec_escape(sdef.description) .. ";]"
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Create list box
|
||||||
|
formspec = formspec .. "textlist[4,0;3.8,8.6;awards;"
|
||||||
|
local first = true
|
||||||
|
for _, award in pairs(awards_list) do
|
||||||
|
local def = award.def
|
||||||
|
if def then
|
||||||
|
if not first then
|
||||||
|
formspec = formspec .. ","
|
||||||
|
end
|
||||||
|
first = false
|
||||||
|
|
||||||
|
if def.secret and not award.unlocked then
|
||||||
|
formspec = formspec .. "#707070"..minetest.formspec_escape(S("(Secret Award)"))
|
||||||
|
else
|
||||||
|
local title = award.name
|
||||||
|
if def and def.title then
|
||||||
|
title = def.title
|
||||||
|
end
|
||||||
|
-- title = title .. " [" .. award.score .. "]"
|
||||||
|
if award.unlocked then
|
||||||
|
formspec = formspec .. minetest.formspec_escape(title)
|
||||||
|
elseif award.started then
|
||||||
|
formspec = formspec .. "#c0c0c0".. minetest.formspec_escape(title)
|
||||||
|
else
|
||||||
|
formspec = formspec .. "#a0a0a0".. minetest.formspec_escape(title)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
return formspec .. ";"..sid.."]"
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
function awards.show_to(name, to, sid, text)
|
||||||
|
if name == "" or name == nil then
|
||||||
|
name = to
|
||||||
|
end
|
||||||
|
local data = awards.player(to)
|
||||||
|
if name == to and data.disabled then
|
||||||
|
minetest.chat_send_player(name, S("You've disabled awards. Type /awards enable to reenable."))
|
||||||
|
return
|
||||||
|
end
|
||||||
|
if text then
|
||||||
|
local awards_list = order_awards(name)
|
||||||
|
if #awards_list == 0 then
|
||||||
|
minetest.chat_send_player(to, S("Error: No award available."))
|
||||||
|
return
|
||||||
|
elseif not data or not data.unlocked then
|
||||||
|
minetest.chat_send_player(to, S("You have not unlocked any awards."))
|
||||||
|
return
|
||||||
|
end
|
||||||
|
minetest.chat_send_player(to, string.format(S("%s’s awards:"), name))
|
||||||
|
|
||||||
|
for str, _ in pairs(data.unlocked) do
|
||||||
|
local def = awards.registered_awards[str]
|
||||||
|
if def then
|
||||||
|
if def.title then
|
||||||
|
if def.description then
|
||||||
|
minetest.chat_send_player(to, string.format(S("%s: %s"), def.title, def.description))
|
||||||
|
else
|
||||||
|
minetest.chat_send_player(to, def.title)
|
||||||
|
end
|
||||||
|
else
|
||||||
|
minetest.chat_send_player(to, str)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
else
|
||||||
|
local deco = ""
|
||||||
|
if minetest.global_exists("default") then
|
||||||
|
deco = default.gui_bg .. default.gui_bg_img
|
||||||
|
end
|
||||||
|
-- Show formspec to user
|
||||||
|
minetest.show_formspec(to,"awards:awards",
|
||||||
|
"size[8,8.6]" .. deco ..
|
||||||
|
awards.get_formspec(name, to, sid))
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
minetest.register_on_player_receive_fields(function(player, formname, fields)
|
||||||
|
if formname ~= "awards:awards" then
|
||||||
|
return false
|
||||||
|
end
|
||||||
|
if fields.quit then
|
||||||
|
return true
|
||||||
|
end
|
||||||
|
local name = player:get_player_name()
|
||||||
|
if fields.awards then
|
||||||
|
local event = minetest.explode_textlist_event(fields.awards)
|
||||||
|
if event.type == "CHG" then
|
||||||
|
awards.show_to(name, name, event.index, false)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
return true
|
||||||
|
end)
|
||||||
|
|
||||||
|
if minetest.get_modpath("sfinv") then
|
||||||
|
sfinv.register_page("awards:awards", {
|
||||||
|
title = S("Awards"),
|
||||||
|
on_enter = function(self, player, context)
|
||||||
|
context.awards_idx = 1
|
||||||
|
end,
|
||||||
|
is_in_nav = function(self, player, context)
|
||||||
|
local data = awards.player(player:get_player_name())
|
||||||
|
return not data.disabled
|
||||||
|
end,
|
||||||
|
get = function(self, player, context)
|
||||||
|
local name = player:get_player_name()
|
||||||
|
return sfinv.make_formspec(player, context,
|
||||||
|
awards.get_formspec(name, name, context.awards_idx),
|
||||||
|
false)
|
||||||
|
end,
|
||||||
|
on_player_receive_fields = function(self, player, context, fields)
|
||||||
|
if fields.awards then
|
||||||
|
local event = minetest.explode_textlist_event(fields.awards)
|
||||||
|
if event.type == "CHG" then
|
||||||
|
context.awards_idx = event.index
|
||||||
|
sfinv.set_player_inventory_formspec(player, context)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
})
|
||||||
|
|
||||||
|
local function check_and_reshow(name)
|
||||||
|
local player = minetest.get_player_by_name(name)
|
||||||
|
if not player then
|
||||||
|
return
|
||||||
|
end
|
||||||
|
|
||||||
|
local context = sfinv.get_or_create_context(player)
|
||||||
|
if context.page ~= "awards:awards" then
|
||||||
|
return
|
||||||
|
end
|
||||||
|
|
||||||
|
sfinv.set_player_inventory_formspec(player, context)
|
||||||
|
end
|
||||||
|
|
||||||
|
awards.register_on_unlock(check_and_reshow)
|
||||||
|
end
|
||||||
|
|
||||||
|
if minetest.get_modpath("unified_inventory") ~= nil then
|
||||||
|
unified_inventory.register_button("awards", {
|
||||||
|
type = "image",
|
||||||
|
image = "awards_ui_icon.png",
|
||||||
|
tooltip = S("Awards"),
|
||||||
|
action = function(player)
|
||||||
|
local name = player:get_player_name()
|
||||||
|
awards.show_to(name, name, nil, false)
|
||||||
|
end,
|
||||||
|
})
|
||||||
|
end
|
|
@ -0,0 +1,44 @@
|
||||||
|
-- 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
|
|
@ -0,0 +1,141 @@
|
||||||
|
-- AWARDS
|
||||||
|
--
|
||||||
|
-- Copyright (C) 2013-2015 rubenwardy
|
||||||
|
-- This program is free software; you can redistribute it and/or modify
|
||||||
|
-- it under the terms of the GNU Lesser General Public License as published by
|
||||||
|
-- the Free Software Foundation; either version 2.1 of the License, or
|
||||||
|
-- (at your option) any later version.
|
||||||
|
-- This program is distributed in the hope that it will be useful,
|
||||||
|
-- but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
-- GNU Lesser General Public License for more details.
|
||||||
|
-- You should have received a copy of the GNU Lesser General Public License along
|
||||||
|
-- with this program; if not, write to the Free Software Foundation, Inc.,
|
||||||
|
-- 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||||
|
--
|
||||||
|
|
||||||
|
|
||||||
|
awards.register_trigger("chat", {
|
||||||
|
type = "counted",
|
||||||
|
progress = "@1/@2 chat messages",
|
||||||
|
auto_description = { "Send a chat message", "Chat @1 times" },
|
||||||
|
})
|
||||||
|
minetest.register_on_chat_message(function(name, message)
|
||||||
|
local player = minetest.get_player_by_name(name)
|
||||||
|
if not player or string.find(message, "/") then
|
||||||
|
return
|
||||||
|
end
|
||||||
|
|
||||||
|
awards.notify_chat(player)
|
||||||
|
end)
|
||||||
|
|
||||||
|
|
||||||
|
awards.register_trigger("join", {
|
||||||
|
type = "counted",
|
||||||
|
progress = "@1/@2 joins",
|
||||||
|
auto_description = { "Join once", "Join @1 times" },
|
||||||
|
})
|
||||||
|
minetest.register_on_joinplayer(awards.notify_join)
|
||||||
|
|
||||||
|
|
||||||
|
awards.register_trigger("death", {
|
||||||
|
type = "counted_key",
|
||||||
|
progress = "@1/@2 deaths",
|
||||||
|
auto_description = { "Die once of @2", "Die @1 times of @2" },
|
||||||
|
auto_description_total = { "Die @1 times.", "Mine @1 times" },
|
||||||
|
get_key = function(self, def)
|
||||||
|
return def.trigger.reason
|
||||||
|
end,
|
||||||
|
})
|
||||||
|
minetest.register_on_dieplayer(function(player, reason)
|
||||||
|
if reason then
|
||||||
|
reason = reason.type
|
||||||
|
else
|
||||||
|
reason = "unknown"
|
||||||
|
end
|
||||||
|
awards.notify_death(player, reason)
|
||||||
|
end)
|
||||||
|
|
||||||
|
|
||||||
|
awards.register_trigger("dig", {
|
||||||
|
type = "counted_key",
|
||||||
|
progress = "@1/@2 dug",
|
||||||
|
auto_description = { "Mine: @2", "Mine: @1×@2" },
|
||||||
|
auto_description_total = { "Mine @1 block.", "Mine @1 blocks." },
|
||||||
|
get_key = function(self, def)
|
||||||
|
return minetest.registered_aliases[def.trigger.node] or def.trigger.node
|
||||||
|
end,
|
||||||
|
key_is_item = true,
|
||||||
|
})
|
||||||
|
minetest.register_on_dignode(function(pos, node, player)
|
||||||
|
if not player or not pos or not node then
|
||||||
|
return
|
||||||
|
end
|
||||||
|
|
||||||
|
local node_name = node.name
|
||||||
|
node_name = minetest.registered_aliases[node_name] or node_name
|
||||||
|
awards.notify_dig(player, node_name)
|
||||||
|
end)
|
||||||
|
|
||||||
|
|
||||||
|
awards.register_trigger("place", {
|
||||||
|
type = "counted_key",
|
||||||
|
progress = "@1/@2 placed",
|
||||||
|
auto_description = { "Place: @2", "Place: @1×@2" },
|
||||||
|
auto_description_total = { "Place @1 block.", "Place @1 blocks." },
|
||||||
|
get_key = function(self, def)
|
||||||
|
return minetest.registered_aliases[def.trigger.node] or def.trigger.node
|
||||||
|
end,
|
||||||
|
key_is_item = true,
|
||||||
|
})
|
||||||
|
minetest.register_on_placenode(function(pos, node, player)
|
||||||
|
if not player or not pos or not node then
|
||||||
|
return
|
||||||
|
end
|
||||||
|
|
||||||
|
local node_name = node.name
|
||||||
|
node_name = minetest.registered_aliases[node_name] or node_name
|
||||||
|
awards.notify_place(player, node_name)
|
||||||
|
end)
|
||||||
|
|
||||||
|
|
||||||
|
awards.register_trigger("craft", {
|
||||||
|
type = "counted_key",
|
||||||
|
progress = "@1/@2 crafted",
|
||||||
|
auto_description = { "Craft: @2", "Craft: @1×@2" },
|
||||||
|
auto_description_total = { "Craft @1 item", "Craft @1 items." },
|
||||||
|
get_key = function(self, def)
|
||||||
|
return minetest.registered_aliases[def.trigger.item] or def.trigger.item
|
||||||
|
end,
|
||||||
|
key_is_item = true,
|
||||||
|
})
|
||||||
|
minetest.register_on_craft(function(itemstack, player, old_craft_grid, craft_inv)
|
||||||
|
if not player or itemstack:is_empty() then
|
||||||
|
return
|
||||||
|
end
|
||||||
|
|
||||||
|
local itemname = itemstack:get_name()
|
||||||
|
itemname = minetest.registered_aliases[itemname] or itemname
|
||||||
|
awards.notify_craft(player, itemname, itemstack:get_count())
|
||||||
|
end)
|
||||||
|
|
||||||
|
|
||||||
|
awards.register_trigger("eat", {
|
||||||
|
type = "counted_key",
|
||||||
|
progress = "@1/@2 eaten",
|
||||||
|
auto_description = { "Eat @2", "Eat @1×@2" },
|
||||||
|
auto_description_total = { "Eat @1 item", "Eat @1 items." },
|
||||||
|
get_key = function(self, def)
|
||||||
|
return minetest.registered_aliases[def.trigger.item] or def.trigger.item
|
||||||
|
end,
|
||||||
|
key_is_item = true,
|
||||||
|
})
|
||||||
|
minetest.register_on_item_eat(function(_, _, itemstack, player, _)
|
||||||
|
if not player or itemstack:is_empty() then
|
||||||
|
return
|
||||||
|
end
|
||||||
|
|
||||||
|
local itemname = itemstack:get_name()
|
||||||
|
itemname = minetest.registered_aliases[itemname] or itemname
|
||||||
|
awards.notify_eat(player, itemname, itemstack:get_count())
|
||||||
|
end)
|