mirror of
https://github.com/VolmitSoftware/Iris.git
synced 2025-07-18 18:23:06 +00:00
Merge pull request #13 from cyberpwnn/iris-2
Kablamalakazamshazam... fam
This commit is contained in:
commit
aa168fab8c
3
gource.bat
Normal file
3
gource.bat
Normal file
@ -0,0 +1,3 @@
|
||||
@echo off
|
||||
cd gource
|
||||
gource -f -a 1 -s 0.5 --colour-images --max-file-lag 10 --title MyGuide --user-scale 1.67 --max-user-speed 725 --filename-time 2
|
674
gource/COPYING.txt
Normal file
674
gource/COPYING.txt
Normal file
@ -0,0 +1,674 @@
|
||||
GNU GENERAL PUBLIC LICENSE
|
||||
Version 3, 29 June 2007
|
||||
|
||||
Copyright (C) 2007 Free Software Foundation, Inc. <http://fsf.org/>
|
||||
Everyone is permitted to copy and distribute verbatim copies
|
||||
of this license document, but changing it is not allowed.
|
||||
|
||||
Preamble
|
||||
|
||||
The GNU General Public License is a free, copyleft license for
|
||||
software and other kinds of works.
|
||||
|
||||
The licenses for most software and other practical works are designed
|
||||
to take away your freedom to share and change the works. By contrast,
|
||||
the GNU General Public License is intended to guarantee your freedom to
|
||||
share and change all versions of a program--to make sure it remains free
|
||||
software for all its users. We, the Free Software Foundation, use the
|
||||
GNU General Public License for most of our software; it applies also to
|
||||
any other work released this way by its authors. You can apply it to
|
||||
your programs, too.
|
||||
|
||||
When we speak of free software, we are referring to freedom, 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
|
||||
them if you wish), that you receive source code or can get it if you
|
||||
want it, that you can change the software or use pieces of it in new
|
||||
free programs, and that you know you can do these things.
|
||||
|
||||
To protect your rights, we need to prevent others from denying you
|
||||
these rights or asking you to surrender the rights. Therefore, you have
|
||||
certain responsibilities if you distribute copies of the software, or if
|
||||
you modify it: responsibilities to respect the freedom of others.
|
||||
|
||||
For example, if you distribute copies of such a program, whether
|
||||
gratis or for a fee, you must pass on to the recipients the same
|
||||
freedoms that you received. You must make sure that they, too, receive
|
||||
or can get the source code. And you must show them these terms so they
|
||||
know their rights.
|
||||
|
||||
Developers that use the GNU GPL protect your rights with two steps:
|
||||
(1) assert copyright on the software, and (2) offer you this License
|
||||
giving you legal permission to copy, distribute and/or modify it.
|
||||
|
||||
For the developers' and authors' protection, the GPL clearly explains
|
||||
that there is no warranty for this free software. For both users' and
|
||||
authors' sake, the GPL requires that modified versions be marked as
|
||||
changed, so that their problems will not be attributed erroneously to
|
||||
authors of previous versions.
|
||||
|
||||
Some devices are designed to deny users access to install or run
|
||||
modified versions of the software inside them, although the manufacturer
|
||||
can do so. This is fundamentally incompatible with the aim of
|
||||
protecting users' freedom to change the software. The systematic
|
||||
pattern of such abuse occurs in the area of products for individuals to
|
||||
use, which is precisely where it is most unacceptable. Therefore, we
|
||||
have designed this version of the GPL to prohibit the practice for those
|
||||
products. If such problems arise substantially in other domains, we
|
||||
stand ready to extend this provision to those domains in future versions
|
||||
of the GPL, as needed to protect the freedom of users.
|
||||
|
||||
Finally, every program is threatened constantly by software patents.
|
||||
States should not allow patents to restrict development and use of
|
||||
software on general-purpose computers, but in those that do, we wish to
|
||||
avoid the special danger that patents applied to a free program could
|
||||
make it effectively proprietary. To prevent this, the GPL assures that
|
||||
patents cannot be used to render the program non-free.
|
||||
|
||||
The precise terms and conditions for copying, distribution and
|
||||
modification follow.
|
||||
|
||||
TERMS AND CONDITIONS
|
||||
|
||||
0. Definitions.
|
||||
|
||||
"This License" refers to version 3 of the GNU General Public License.
|
||||
|
||||
"Copyright" also means copyright-like laws that apply to other kinds of
|
||||
works, such as semiconductor masks.
|
||||
|
||||
"The Program" refers to any copyrightable work licensed under this
|
||||
License. Each licensee is addressed as "you". "Licensees" and
|
||||
"recipients" may be individuals or organizations.
|
||||
|
||||
To "modify" a work means to copy from or adapt all or part of the work
|
||||
in a fashion requiring copyright permission, other than the making of an
|
||||
exact copy. The resulting work is called a "modified version" of the
|
||||
earlier work or a work "based on" the earlier work.
|
||||
|
||||
A "covered work" means either the unmodified Program or a work based
|
||||
on the Program.
|
||||
|
||||
To "propagate" a work means to do anything with it that, without
|
||||
permission, would make you directly or secondarily liable for
|
||||
infringement under applicable copyright law, except executing it on a
|
||||
computer or modifying a private copy. Propagation includes copying,
|
||||
distribution (with or without modification), making available to the
|
||||
public, and in some countries other activities as well.
|
||||
|
||||
To "convey" a work means any kind of propagation that enables other
|
||||
parties to make or receive copies. Mere interaction with a user through
|
||||
a computer network, with no transfer of a copy, is not conveying.
|
||||
|
||||
An interactive user interface displays "Appropriate Legal Notices"
|
||||
to the extent that it includes a convenient and prominently visible
|
||||
feature that (1) displays an appropriate copyright notice, and (2)
|
||||
tells the user that there is no warranty for the work (except to the
|
||||
extent that warranties are provided), that licensees may convey the
|
||||
work under this License, and how to view a copy of this License. If
|
||||
the interface presents a list of user commands or options, such as a
|
||||
menu, a prominent item in the list meets this criterion.
|
||||
|
||||
1. Source Code.
|
||||
|
||||
The "source code" for a work means the preferred form of the work
|
||||
for making modifications to it. "Object code" means any non-source
|
||||
form of a work.
|
||||
|
||||
A "Standard Interface" means an interface that either is an official
|
||||
standard defined by a recognized standards body, or, in the case of
|
||||
interfaces specified for a particular programming language, one that
|
||||
is widely used among developers working in that language.
|
||||
|
||||
The "System Libraries" of an executable work include anything, other
|
||||
than the work as a whole, that (a) is included in the normal form of
|
||||
packaging a Major Component, but which is not part of that Major
|
||||
Component, and (b) serves only to enable use of the work with that
|
||||
Major Component, or to implement a Standard Interface for which an
|
||||
implementation is available to the public in source code form. A
|
||||
"Major Component", in this context, means a major essential component
|
||||
(kernel, window system, and so on) of the specific operating system
|
||||
(if any) on which the executable work runs, or a compiler used to
|
||||
produce the work, or an object code interpreter used to run it.
|
||||
|
||||
The "Corresponding Source" for a work in object code form means all
|
||||
the source code needed to generate, install, and (for an executable
|
||||
work) run the object code and to modify the work, including scripts to
|
||||
control those activities. However, it does not include the work's
|
||||
System Libraries, or general-purpose tools or generally available free
|
||||
programs which are used unmodified in performing those activities but
|
||||
which are not part of the work. For example, Corresponding Source
|
||||
includes interface definition files associated with source files for
|
||||
the work, and the source code for shared libraries and dynamically
|
||||
linked subprograms that the work is specifically designed to require,
|
||||
such as by intimate data communication or control flow between those
|
||||
subprograms and other parts of the work.
|
||||
|
||||
The Corresponding Source need not include anything that users
|
||||
can regenerate automatically from other parts of the Corresponding
|
||||
Source.
|
||||
|
||||
The Corresponding Source for a work in source code form is that
|
||||
same work.
|
||||
|
||||
2. Basic Permissions.
|
||||
|
||||
All rights granted under this License are granted for the term of
|
||||
copyright on the Program, and are irrevocable provided the stated
|
||||
conditions are met. This License explicitly affirms your unlimited
|
||||
permission to run the unmodified Program. The output from running a
|
||||
covered work is covered by this License only if the output, given its
|
||||
content, constitutes a covered work. This License acknowledges your
|
||||
rights of fair use or other equivalent, as provided by copyright law.
|
||||
|
||||
You may make, run and propagate covered works that you do not
|
||||
convey, without conditions so long as your license otherwise remains
|
||||
in force. You may convey covered works to others for the sole purpose
|
||||
of having them make modifications exclusively for you, or provide you
|
||||
with facilities for running those works, provided that you comply with
|
||||
the terms of this License in conveying all material for which you do
|
||||
not control copyright. Those thus making or running the covered works
|
||||
for you must do so exclusively on your behalf, under your direction
|
||||
and control, on terms that prohibit them from making any copies of
|
||||
your copyrighted material outside their relationship with you.
|
||||
|
||||
Conveying under any other circumstances is permitted solely under
|
||||
the conditions stated below. Sublicensing is not allowed; section 10
|
||||
makes it unnecessary.
|
||||
|
||||
3. Protecting Users' Legal Rights From Anti-Circumvention Law.
|
||||
|
||||
No covered work shall be deemed part of an effective technological
|
||||
measure under any applicable law fulfilling obligations under article
|
||||
11 of the WIPO copyright treaty adopted on 20 December 1996, or
|
||||
similar laws prohibiting or restricting circumvention of such
|
||||
measures.
|
||||
|
||||
When you convey a covered work, you waive any legal power to forbid
|
||||
circumvention of technological measures to the extent such circumvention
|
||||
is effected by exercising rights under this License with respect to
|
||||
the covered work, and you disclaim any intention to limit operation or
|
||||
modification of the work as a means of enforcing, against the work's
|
||||
users, your or third parties' legal rights to forbid circumvention of
|
||||
technological measures.
|
||||
|
||||
4. Conveying Verbatim Copies.
|
||||
|
||||
You may convey verbatim copies of the Program's source code as you
|
||||
receive it, in any medium, provided that you conspicuously and
|
||||
appropriately publish on each copy an appropriate copyright notice;
|
||||
keep intact all notices stating that this License and any
|
||||
non-permissive terms added in accord with section 7 apply to the code;
|
||||
keep intact all notices of the absence of any warranty; and give all
|
||||
recipients a copy of this License along with the Program.
|
||||
|
||||
You may charge any price or no price for each copy that you convey,
|
||||
and you may offer support or warranty protection for a fee.
|
||||
|
||||
5. Conveying Modified Source Versions.
|
||||
|
||||
You may convey a work based on the Program, or the modifications to
|
||||
produce it from the Program, in the form of source code under the
|
||||
terms of section 4, provided that you also meet all of these conditions:
|
||||
|
||||
a) The work must carry prominent notices stating that you modified
|
||||
it, and giving a relevant date.
|
||||
|
||||
b) The work must carry prominent notices stating that it is
|
||||
released under this License and any conditions added under section
|
||||
7. This requirement modifies the requirement in section 4 to
|
||||
"keep intact all notices".
|
||||
|
||||
c) You must license the entire work, as a whole, under this
|
||||
License to anyone who comes into possession of a copy. This
|
||||
License will therefore apply, along with any applicable section 7
|
||||
additional terms, to the whole of the work, and all its parts,
|
||||
regardless of how they are packaged. This License gives no
|
||||
permission to license the work in any other way, but it does not
|
||||
invalidate such permission if you have separately received it.
|
||||
|
||||
d) If the work has interactive user interfaces, each must display
|
||||
Appropriate Legal Notices; however, if the Program has interactive
|
||||
interfaces that do not display Appropriate Legal Notices, your
|
||||
work need not make them do so.
|
||||
|
||||
A compilation of a covered work with other separate and independent
|
||||
works, which are not by their nature extensions of the covered work,
|
||||
and which are not combined with it such as to form a larger program,
|
||||
in or on a volume of a storage or distribution medium, is called an
|
||||
"aggregate" if the compilation and its resulting copyright are not
|
||||
used to limit the access or legal rights of the compilation's users
|
||||
beyond what the individual works permit. Inclusion of a covered work
|
||||
in an aggregate does not cause this License to apply to the other
|
||||
parts of the aggregate.
|
||||
|
||||
6. Conveying Non-Source Forms.
|
||||
|
||||
You may convey a covered work in object code form under the terms
|
||||
of sections 4 and 5, provided that you also convey the
|
||||
machine-readable Corresponding Source under the terms of this License,
|
||||
in one of these ways:
|
||||
|
||||
a) Convey the object code in, or embodied in, a physical product
|
||||
(including a physical distribution medium), accompanied by the
|
||||
Corresponding Source fixed on a durable physical medium
|
||||
customarily used for software interchange.
|
||||
|
||||
b) Convey the object code in, or embodied in, a physical product
|
||||
(including a physical distribution medium), accompanied by a
|
||||
written offer, valid for at least three years and valid for as
|
||||
long as you offer spare parts or customer support for that product
|
||||
model, to give anyone who possesses the object code either (1) a
|
||||
copy of the Corresponding Source for all the software in the
|
||||
product that is covered by this License, on a durable physical
|
||||
medium customarily used for software interchange, for a price no
|
||||
more than your reasonable cost of physically performing this
|
||||
conveying of source, or (2) access to copy the
|
||||
Corresponding Source from a network server at no charge.
|
||||
|
||||
c) Convey individual copies of the object code with a copy of the
|
||||
written offer to provide the Corresponding Source. This
|
||||
alternative is allowed only occasionally and noncommercially, and
|
||||
only if you received the object code with such an offer, in accord
|
||||
with subsection 6b.
|
||||
|
||||
d) Convey the object code by offering access from a designated
|
||||
place (gratis or for a charge), and offer equivalent access to the
|
||||
Corresponding Source in the same way through the same place at no
|
||||
further charge. You need not require recipients to copy the
|
||||
Corresponding Source along with the object code. If the place to
|
||||
copy the object code is a network server, the Corresponding Source
|
||||
may be on a different server (operated by you or a third party)
|
||||
that supports equivalent copying facilities, provided you maintain
|
||||
clear directions next to the object code saying where to find the
|
||||
Corresponding Source. Regardless of what server hosts the
|
||||
Corresponding Source, you remain obligated to ensure that it is
|
||||
available for as long as needed to satisfy these requirements.
|
||||
|
||||
e) Convey the object code using peer-to-peer transmission, provided
|
||||
you inform other peers where the object code and Corresponding
|
||||
Source of the work are being offered to the general public at no
|
||||
charge under subsection 6d.
|
||||
|
||||
A separable portion of the object code, whose source code is excluded
|
||||
from the Corresponding Source as a System Library, need not be
|
||||
included in conveying the object code work.
|
||||
|
||||
A "User Product" is either (1) a "consumer product", which means any
|
||||
tangible personal property which is normally used for personal, family,
|
||||
or household purposes, or (2) anything designed or sold for incorporation
|
||||
into a dwelling. In determining whether a product is a consumer product,
|
||||
doubtful cases shall be resolved in favor of coverage. For a particular
|
||||
product received by a particular user, "normally used" refers to a
|
||||
typical or common use of that class of product, regardless of the status
|
||||
of the particular user or of the way in which the particular user
|
||||
actually uses, or expects or is expected to use, the product. A product
|
||||
is a consumer product regardless of whether the product has substantial
|
||||
commercial, industrial or non-consumer uses, unless such uses represent
|
||||
the only significant mode of use of the product.
|
||||
|
||||
"Installation Information" for a User Product means any methods,
|
||||
procedures, authorization keys, or other information required to install
|
||||
and execute modified versions of a covered work in that User Product from
|
||||
a modified version of its Corresponding Source. The information must
|
||||
suffice to ensure that the continued functioning of the modified object
|
||||
code is in no case prevented or interfered with solely because
|
||||
modification has been made.
|
||||
|
||||
If you convey an object code work under this section in, or with, or
|
||||
specifically for use in, a User Product, and the conveying occurs as
|
||||
part of a transaction in which the right of possession and use of the
|
||||
User Product is transferred to the recipient in perpetuity or for a
|
||||
fixed term (regardless of how the transaction is characterized), the
|
||||
Corresponding Source conveyed under this section must be accompanied
|
||||
by the Installation Information. But this requirement does not apply
|
||||
if neither you nor any third party retains the ability to install
|
||||
modified object code on the User Product (for example, the work has
|
||||
been installed in ROM).
|
||||
|
||||
The requirement to provide Installation Information does not include a
|
||||
requirement to continue to provide support service, warranty, or updates
|
||||
for a work that has been modified or installed by the recipient, or for
|
||||
the User Product in which it has been modified or installed. Access to a
|
||||
network may be denied when the modification itself materially and
|
||||
adversely affects the operation of the network or violates the rules and
|
||||
protocols for communication across the network.
|
||||
|
||||
Corresponding Source conveyed, and Installation Information provided,
|
||||
in accord with this section must be in a format that is publicly
|
||||
documented (and with an implementation available to the public in
|
||||
source code form), and must require no special password or key for
|
||||
unpacking, reading or copying.
|
||||
|
||||
7. Additional Terms.
|
||||
|
||||
"Additional permissions" are terms that supplement the terms of this
|
||||
License by making exceptions from one or more of its conditions.
|
||||
Additional permissions that are applicable to the entire Program shall
|
||||
be treated as though they were included in this License, to the extent
|
||||
that they are valid under applicable law. If additional permissions
|
||||
apply only to part of the Program, that part may be used separately
|
||||
under those permissions, but the entire Program remains governed by
|
||||
this License without regard to the additional permissions.
|
||||
|
||||
When you convey a copy of a covered work, you may at your option
|
||||
remove any additional permissions from that copy, or from any part of
|
||||
it. (Additional permissions may be written to require their own
|
||||
removal in certain cases when you modify the work.) You may place
|
||||
additional permissions on material, added by you to a covered work,
|
||||
for which you have or can give appropriate copyright permission.
|
||||
|
||||
Notwithstanding any other provision of this License, for material you
|
||||
add to a covered work, you may (if authorized by the copyright holders of
|
||||
that material) supplement the terms of this License with terms:
|
||||
|
||||
a) Disclaiming warranty or limiting liability differently from the
|
||||
terms of sections 15 and 16 of this License; or
|
||||
|
||||
b) Requiring preservation of specified reasonable legal notices or
|
||||
author attributions in that material or in the Appropriate Legal
|
||||
Notices displayed by works containing it; or
|
||||
|
||||
c) Prohibiting misrepresentation of the origin of that material, or
|
||||
requiring that modified versions of such material be marked in
|
||||
reasonable ways as different from the original version; or
|
||||
|
||||
d) Limiting the use for publicity purposes of names of licensors or
|
||||
authors of the material; or
|
||||
|
||||
e) Declining to grant rights under trademark law for use of some
|
||||
trade names, trademarks, or service marks; or
|
||||
|
||||
f) Requiring indemnification of licensors and authors of that
|
||||
material by anyone who conveys the material (or modified versions of
|
||||
it) with contractual assumptions of liability to the recipient, for
|
||||
any liability that these contractual assumptions directly impose on
|
||||
those licensors and authors.
|
||||
|
||||
All other non-permissive additional terms are considered "further
|
||||
restrictions" within the meaning of section 10. If the Program as you
|
||||
received it, or any part of it, contains a notice stating that it is
|
||||
governed by this License along with a term that is a further
|
||||
restriction, you may remove that term. If a license document contains
|
||||
a further restriction but permits relicensing or conveying under this
|
||||
License, you may add to a covered work material governed by the terms
|
||||
of that license document, provided that the further restriction does
|
||||
not survive such relicensing or conveying.
|
||||
|
||||
If you add terms to a covered work in accord with this section, you
|
||||
must place, in the relevant source files, a statement of the
|
||||
additional terms that apply to those files, or a notice indicating
|
||||
where to find the applicable terms.
|
||||
|
||||
Additional terms, permissive or non-permissive, may be stated in the
|
||||
form of a separately written license, or stated as exceptions;
|
||||
the above requirements apply either way.
|
||||
|
||||
8. Termination.
|
||||
|
||||
You may not propagate or modify a covered work except as expressly
|
||||
provided under this License. Any attempt otherwise to propagate or
|
||||
modify it is void, and will automatically terminate your rights under
|
||||
this License (including any patent licenses granted under the third
|
||||
paragraph of section 11).
|
||||
|
||||
However, if you cease all violation of this License, then your
|
||||
license from a particular copyright holder is reinstated (a)
|
||||
provisionally, unless and until the copyright holder explicitly and
|
||||
finally terminates your license, and (b) permanently, if the copyright
|
||||
holder fails to notify you of the violation by some reasonable means
|
||||
prior to 60 days after the cessation.
|
||||
|
||||
Moreover, your license from a particular copyright holder is
|
||||
reinstated permanently if the copyright holder notifies you of the
|
||||
violation by some reasonable means, this is the first time you have
|
||||
received notice of violation of this License (for any work) from that
|
||||
copyright holder, and you cure the violation prior to 30 days after
|
||||
your receipt of the notice.
|
||||
|
||||
Termination of your rights under this section does not terminate the
|
||||
licenses of parties who have received copies or rights from you under
|
||||
this License. If your rights have been terminated and not permanently
|
||||
reinstated, you do not qualify to receive new licenses for the same
|
||||
material under section 10.
|
||||
|
||||
9. Acceptance Not Required for Having Copies.
|
||||
|
||||
You are not required to accept this License in order to receive or
|
||||
run a copy of the Program. Ancillary propagation of a covered work
|
||||
occurring solely as a consequence of using peer-to-peer transmission
|
||||
to receive a copy likewise does not require acceptance. However,
|
||||
nothing other than this License grants you permission to propagate or
|
||||
modify any covered work. These actions infringe copyright if you do
|
||||
not accept this License. Therefore, by modifying or propagating a
|
||||
covered work, you indicate your acceptance of this License to do so.
|
||||
|
||||
10. Automatic Licensing of Downstream Recipients.
|
||||
|
||||
Each time you convey a covered work, the recipient automatically
|
||||
receives a license from the original licensors, to run, modify and
|
||||
propagate that work, subject to this License. You are not responsible
|
||||
for enforcing compliance by third parties with this License.
|
||||
|
||||
An "entity transaction" is a transaction transferring control of an
|
||||
organization, or substantially all assets of one, or subdividing an
|
||||
organization, or merging organizations. If propagation of a covered
|
||||
work results from an entity transaction, each party to that
|
||||
transaction who receives a copy of the work also receives whatever
|
||||
licenses to the work the party's predecessor in interest had or could
|
||||
give under the previous paragraph, plus a right to possession of the
|
||||
Corresponding Source of the work from the predecessor in interest, if
|
||||
the predecessor has it or can get it with reasonable efforts.
|
||||
|
||||
You may not impose any further restrictions on the exercise of the
|
||||
rights granted or affirmed under this License. For example, you may
|
||||
not impose a license fee, royalty, or other charge for exercise of
|
||||
rights granted under this License, and you may not initiate litigation
|
||||
(including a cross-claim or counterclaim in a lawsuit) alleging that
|
||||
any patent claim is infringed by making, using, selling, offering for
|
||||
sale, or importing the Program or any portion of it.
|
||||
|
||||
11. Patents.
|
||||
|
||||
A "contributor" is a copyright holder who authorizes use under this
|
||||
License of the Program or a work on which the Program is based. The
|
||||
work thus licensed is called the contributor's "contributor version".
|
||||
|
||||
A contributor's "essential patent claims" are all patent claims
|
||||
owned or controlled by the contributor, whether already acquired or
|
||||
hereafter acquired, that would be infringed by some manner, permitted
|
||||
by this License, of making, using, or selling its contributor version,
|
||||
but do not include claims that would be infringed only as a
|
||||
consequence of further modification of the contributor version. For
|
||||
purposes of this definition, "control" includes the right to grant
|
||||
patent sublicenses in a manner consistent with the requirements of
|
||||
this License.
|
||||
|
||||
Each contributor grants you a non-exclusive, worldwide, royalty-free
|
||||
patent license under the contributor's essential patent claims, to
|
||||
make, use, sell, offer for sale, import and otherwise run, modify and
|
||||
propagate the contents of its contributor version.
|
||||
|
||||
In the following three paragraphs, a "patent license" is any express
|
||||
agreement or commitment, however denominated, not to enforce a patent
|
||||
(such as an express permission to practice a patent or covenant not to
|
||||
sue for patent infringement). To "grant" such a patent license to a
|
||||
party means to make such an agreement or commitment not to enforce a
|
||||
patent against the party.
|
||||
|
||||
If you convey a covered work, knowingly relying on a patent license,
|
||||
and the Corresponding Source of the work is not available for anyone
|
||||
to copy, free of charge and under the terms of this License, through a
|
||||
publicly available network server or other readily accessible means,
|
||||
then you must either (1) cause the Corresponding Source to be so
|
||||
available, or (2) arrange to deprive yourself of the benefit of the
|
||||
patent license for this particular work, or (3) arrange, in a manner
|
||||
consistent with the requirements of this License, to extend the patent
|
||||
license to downstream recipients. "Knowingly relying" means you have
|
||||
actual knowledge that, but for the patent license, your conveying the
|
||||
covered work in a country, or your recipient's use of the covered work
|
||||
in a country, would infringe one or more identifiable patents in that
|
||||
country that you have reason to believe are valid.
|
||||
|
||||
If, pursuant to or in connection with a single transaction or
|
||||
arrangement, you convey, or propagate by procuring conveyance of, a
|
||||
covered work, and grant a patent license to some of the parties
|
||||
receiving the covered work authorizing them to use, propagate, modify
|
||||
or convey a specific copy of the covered work, then the patent license
|
||||
you grant is automatically extended to all recipients of the covered
|
||||
work and works based on it.
|
||||
|
||||
A patent license is "discriminatory" if it does not include within
|
||||
the scope of its coverage, prohibits the exercise of, or is
|
||||
conditioned on the non-exercise of one or more of the rights that are
|
||||
specifically granted under this License. You may not convey a covered
|
||||
work if you are a party to an arrangement with a third party that is
|
||||
in the business of distributing software, under which you make payment
|
||||
to the third party based on the extent of your activity of conveying
|
||||
the work, and under which the third party grants, to any of the
|
||||
parties who would receive the covered work from you, a discriminatory
|
||||
patent license (a) in connection with copies of the covered work
|
||||
conveyed by you (or copies made from those copies), or (b) primarily
|
||||
for and in connection with specific products or compilations that
|
||||
contain the covered work, unless you entered into that arrangement,
|
||||
or that patent license was granted, prior to 28 March 2007.
|
||||
|
||||
Nothing in this License shall be construed as excluding or limiting
|
||||
any implied license or other defenses to infringement that may
|
||||
otherwise be available to you under applicable patent law.
|
||||
|
||||
12. No Surrender of Others' Freedom.
|
||||
|
||||
If 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 convey a
|
||||
covered work so as to satisfy simultaneously your obligations under this
|
||||
License and any other pertinent obligations, then as a consequence you may
|
||||
not convey it at all. For example, if you agree to terms that obligate you
|
||||
to collect a royalty for further conveying from those to whom you convey
|
||||
the Program, the only way you could satisfy both those terms and this
|
||||
License would be to refrain entirely from conveying the Program.
|
||||
|
||||
13. Use with the GNU Affero General Public License.
|
||||
|
||||
Notwithstanding any other provision of this License, you have
|
||||
permission to link or combine any covered work with a work licensed
|
||||
under version 3 of the GNU Affero General Public License into a single
|
||||
combined work, and to convey the resulting work. The terms of this
|
||||
License will continue to apply to the part which is the covered work,
|
||||
but the special requirements of the GNU Affero General Public License,
|
||||
section 13, concerning interaction through a network will apply to the
|
||||
combination as such.
|
||||
|
||||
14. Revised Versions of this License.
|
||||
|
||||
The Free Software Foundation may publish revised and/or new versions of
|
||||
the GNU 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
|
||||
Program specifies that a certain numbered version of the GNU General
|
||||
Public License "or any later version" applies to it, you have the
|
||||
option of following the terms and conditions either of that numbered
|
||||
version or of any later version published by the Free Software
|
||||
Foundation. If the Program does not specify a version number of the
|
||||
GNU General Public License, you may choose any version ever published
|
||||
by the Free Software Foundation.
|
||||
|
||||
If the Program specifies that a proxy can decide which future
|
||||
versions of the GNU General Public License can be used, that proxy's
|
||||
public statement of acceptance of a version permanently authorizes you
|
||||
to choose that version for the Program.
|
||||
|
||||
Later license versions may give you additional or different
|
||||
permissions. However, no additional obligations are imposed on any
|
||||
author or copyright holder as a result of your choosing to follow a
|
||||
later version.
|
||||
|
||||
15. Disclaimer of Warranty.
|
||||
|
||||
THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY
|
||||
APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT
|
||||
HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "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 PROGRAM
|
||||
IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF
|
||||
ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
|
||||
|
||||
16. Limitation of Liability.
|
||||
|
||||
IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
|
||||
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS
|
||||
THE PROGRAM 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 PROGRAM (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 PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS),
|
||||
EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF
|
||||
SUCH DAMAGES.
|
||||
|
||||
17. Interpretation of Sections 15 and 16.
|
||||
|
||||
If the disclaimer of warranty and limitation of liability provided
|
||||
above cannot be given local legal effect according to their terms,
|
||||
reviewing courts shall apply local law that most closely approximates
|
||||
an absolute waiver of all civil liability in connection with the
|
||||
Program, unless a warranty or assumption of liability accompanies a
|
||||
copy of the Program in return for a fee.
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
||||
|
||||
How to Apply These Terms to Your New Programs
|
||||
|
||||
If you develop a new program, and you want it to be of the greatest
|
||||
possible use to the public, the best way to achieve this is to make it
|
||||
free software which everyone can redistribute and change under these terms.
|
||||
|
||||
To do so, attach the following notices to the program. It is safest
|
||||
to attach them to the start of each source file to most effectively
|
||||
state 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 program's name and a brief idea of what it does.>
|
||||
Copyright (C) <year> <name of author>
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 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 General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
Also add information on how to contact you by electronic and paper mail.
|
||||
|
||||
If the program does terminal interaction, make it output a short
|
||||
notice like this when it starts in an interactive mode:
|
||||
|
||||
<program> Copyright (C) <year> <name of author>
|
||||
This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
|
||||
This is free software, and you are welcome to redistribute it
|
||||
under certain conditions; type `show c' for details.
|
||||
|
||||
The hypothetical commands `show w' and `show c' should show the appropriate
|
||||
parts of the General Public License. Of course, your program's commands
|
||||
might be different; for a GUI interface, you would use an "about box".
|
||||
|
||||
You should also get your employer (if you work as a programmer) or school,
|
||||
if any, to sign a "copyright disclaimer" for the program, if necessary.
|
||||
For more information on this, and how to apply and follow the GNU GPL, see
|
||||
<http://www.gnu.org/licenses/>.
|
||||
|
||||
The GNU General Public License does not permit incorporating your program
|
||||
into proprietary programs. If your program is a subroutine library, you
|
||||
may consider it more useful to permit linking proprietary applications with
|
||||
the library. If this is what you want to do, use the GNU Lesser General
|
||||
Public License instead of this License. But first, please read
|
||||
<http://www.gnu.org/philosophy/why-not-lgpl.html>.
|
298
gource/ChangeLog.txt
Normal file
298
gource/ChangeLog.txt
Normal file
@ -0,0 +1,298 @@
|
||||
0.51:
|
||||
* Fixed --font-file relative path handling.
|
||||
* Fixed a bug in resolving the repository root directory from a relative path.
|
||||
|
||||
0.50:
|
||||
* Right mouse button rotation now pivots around the camera.
|
||||
* Added --font-file option.
|
||||
* Added --enable-font-file option to configure.
|
||||
* Added --no-time-travel option (Lars Schmertmann).
|
||||
* Added --dir-name-position option (Lars Schmertmann).
|
||||
* Added --file-extension-fallback option (Lars Schmertmann).
|
||||
* Added --user-show-filter option (Victor Lopez).
|
||||
* Added --disable-input option (Joey Parrish).
|
||||
* Added --loop-delay-seconds option (Joey Parrish).
|
||||
* Added --font-scale option.
|
||||
* Added filename, dirname and user font size options (Carl Colena).
|
||||
* Added workaround for FFMpeg error parsing Gource PPM video output.
|
||||
* Fixed a bug in the Mercurial log parser that caused changes to be missed.
|
||||
* Fixed file removal being cancelled by an action with an earlier timestamp.
|
||||
* Fixed a bug in the log file format detection that could result in the wrong
|
||||
first entry being displayed for a custom log.
|
||||
* Fixed a bug where automatically cycling through a config with multiple
|
||||
repositories reset settings to their defaults.
|
||||
|
||||
0.49:
|
||||
* Fixed compatibility with GLM 0.9.9.0.
|
||||
|
||||
0.48:
|
||||
* Can now generate logs from git sub module directories.
|
||||
|
||||
0.47:
|
||||
* Fixed low mouse movement speed with some mice while repositioning camera.
|
||||
|
||||
0.46:
|
||||
* Added --screen option.
|
||||
|
||||
0.45:
|
||||
* Added --window-position XxY option.
|
||||
* Added --frameless option.
|
||||
* Added --file-show-filter REGEX option (swoogles).
|
||||
* Added --filename-time and filename-colour options (gh2k).
|
||||
* Improved handling of very low seconds-per-day values (malengrin).
|
||||
* Fixed crash when SVN log lacks author information (obarthel).
|
||||
* Additional git log command validation (cym13).
|
||||
* Allow lower case hex colours in custom logs (HSorensen).
|
||||
* Enabled STDOUT support with --output-stream '-' on Windows (circulosmeos).
|
||||
* Now requires SDL 2 to build (deprecated SDL 1.2 support removed).
|
||||
|
||||
0.44:
|
||||
* Fixed crash when taking a screenshot with an odd resolution.
|
||||
* Fixed type deduction compilation error with newer versions of GCC.
|
||||
* Documentation improvements.
|
||||
|
||||
0.43:
|
||||
* Updated boost autoconf macros to fix multi-arch detection.
|
||||
|
||||
0.42:
|
||||
* Fixed bzr log command when no start date was specified (chrisf).
|
||||
* Fixed hg log commit order when date range specified.
|
||||
* Fixed hg log command line on Windows.
|
||||
* Fixed parser bug in date range filtering code.
|
||||
|
||||
0.41:
|
||||
* Multi-monitor support using SDL 2.0 when available.
|
||||
* SDL 1.2 support is deprecated.
|
||||
* Full screen mode now uses desktop resolution by default.
|
||||
* Added --start-date, --stop-date 'YYYY-MM-DD hh:mm:ss' options.
|
||||
* Added --dir-name-depth option.
|
||||
* Changed --file-idle-time default value to 0.
|
||||
* Changed screenshot format to PNG.
|
||||
|
||||
0.40:
|
||||
* Added caption support.
|
||||
* Improved command line interoperability on Windows.
|
||||
* Fixed directory deletion short circuiting processing the rest of a commit.
|
||||
* Fixed issue loading non-ascii user image filenames on windows.
|
||||
* Ignore UTF-8 byte order mark at the start of lines in custom log files.
|
||||
* Fix to boost macros for Macs and non-GNU systems (mistydemeo).
|
||||
* Autotools improvements (flameeyes).
|
||||
|
||||
0.39:
|
||||
* Fixed blurry non power of 2 logos.
|
||||
* File colour changes now supported in custom logs (rmyorston).
|
||||
* Fixed building against Boost 1.50 (svenstaro).
|
||||
* Updated boost autoconf macros (flameeyes).
|
||||
* Autogen script (matthiaskrgr).
|
||||
|
||||
0.38:
|
||||
* New high quality sprites.
|
||||
* Fullscreen toggle with alt + enter.
|
||||
* Window is now resizable. -WIDTHxHEIGHT! creates a non-resizable window.
|
||||
* Lowered minimum zoom distance.
|
||||
* Use AM_CPPFLAGS in Makefile.am to allow passing custom CPPFLAGS.
|
||||
* Don't add files that match the path of a known directory.
|
||||
* Fixed divide by zero in text shader causing artifacts on some video cards.
|
||||
* Recursively search for repository directory when log-format not specified
|
||||
(thanks to Jörg Bachmann for original concept / prototype).
|
||||
* New dependency on Boost Filesystem.
|
||||
* Doubled the maximum zoom out distance.
|
||||
* Allow negative timestamps before 1970 in custom log (artzub).
|
||||
* Fix for UTF8-CPP checked.h compilation issue (vszakats).
|
||||
* Fixed bug causing missing characters in text.
|
||||
* Fixed --highlight-users option not using highlight-colour.
|
||||
* highlight-colour default changed to white.
|
||||
* Added --selection-colour option (applied to selected users and files).
|
||||
* Added --dir-colour option (applied to directories).
|
||||
|
||||
0.37:
|
||||
* Made SVN log GMT timestamp conversion fix portable.
|
||||
|
||||
0.36:
|
||||
* Fixed SVN log GMT timestamp conversion.
|
||||
* Fixed issue with sub-dirs of deleted dir not being removed in some cases.
|
||||
|
||||
0.35:
|
||||
* Added long file extension truncation handling to file key (--key).
|
||||
* Treat changes in Mercurial log files with the same time/user as one commit.
|
||||
* Fixed handling of spaces in directory names with Mercurial.
|
||||
* Fixed --font-colour option.
|
||||
|
||||
0.34:
|
||||
* Now using VBOs and shaders for faster rendering when OpenGL 2.0 is available.
|
||||
* Eliminated bloom colour banding artifacts (requires OpenGL 2.0).
|
||||
* New font rendering library derived from FTGL (FTGL no longer required).
|
||||
* Single pass font/shadow rendering (with lots of help from Chris Forbes).
|
||||
* Added --no-vsync option.
|
||||
* Fixed bug where tree is out of alignment with object positions in windowed
|
||||
mode due to using the wrong display dimensions internally.
|
||||
* Removed default max-files limit.
|
||||
|
||||
0.33:
|
||||
* Added --hide root option to not draw branches from the root directory.
|
||||
* Fixed log parsing of Bazaar merges and tagged commits.
|
||||
* --output-custom-log now skips unparsed log entries instead of exiting.
|
||||
|
||||
0.32:
|
||||
* Fixed behaviour of user camera tracking.
|
||||
|
||||
0.31:
|
||||
* Added --with-tinyxml option to configure (use the system TinyXML library).
|
||||
|
||||
0.30:
|
||||
* Fixed crash when SVN log entry contains no 'paths' element.
|
||||
* Handle directory deletion (happens in SVN logs).
|
||||
|
||||
0.29:
|
||||
* SVN built-in support.
|
||||
* cvs2cl log support (cvs-exp support is now deprecated).
|
||||
* Made camera behaviour when zooming and selecting objects more intuitive.
|
||||
* Improved interactive performance.
|
||||
* Added file extension key (--key or toggled with 'K').
|
||||
* Added mouse-over tool tips.
|
||||
* Added --highlight-colour option.
|
||||
* Added --hash-seed option. The S key now randomizes colours.
|
||||
* Added --output-custom-log option.
|
||||
* Exposed --time-scale option (previously only available interactively).
|
||||
* Removed arbitrary 1024 maximum length limit for log lines.
|
||||
* Fixed two file colouring bugs (quoted files from git, period in file path).
|
||||
* Fix handling of avatars for UTF-8 usernames on MACOSX (Christian Köstlin).
|
||||
* Recover from video mode failing to set due to multi-sampling (Siddhesh Poyarekar).
|
||||
|
||||
0.28:
|
||||
* Bazaar support for merged commits (Nick Moffit).
|
||||
* C++ efficiency improvements (Oliver Smith).
|
||||
* Improved cvs-exp log compatibility.
|
||||
* Re-show name of user when adding a new action if user is idle.
|
||||
* Added --padding option to control camera view padding.
|
||||
* More accurate camera tracking (tracks the bounding boxes of objects).
|
||||
* Improved automatic rotation logic.
|
||||
|
||||
0.27:
|
||||
* Display time stops at the time of the last commit.
|
||||
* Users fade out when end reached rather than ending abruptly.
|
||||
* Position slider is now hidden by default if recording a video.
|
||||
* Automatic camera rotation for better use of screen space.
|
||||
* Support international keyboards (Peter Kjellerstedt).
|
||||
* C++ efficiency improvements (Jacob Metcalfe).
|
||||
* Fixed crash when reading from STDIN.
|
||||
* Fixed intermittent crash closing Gource when using --output-ppm-stream.
|
||||
* Added ini style config file support (see --load/save-config).
|
||||
* Added screenshot button (F12). Screenshots respect the alpha channel.
|
||||
* Added --transparent to make the background see-through (for screenshots).
|
||||
* Added --logo and --background-image options.
|
||||
* Added --dont-stop option for manual exiting when recording videos.
|
||||
* Added --stop-at-time option to stop Gource after a number of seconds.
|
||||
* Added --hide 'mouse' option.
|
||||
* Added --highlight-dirs option.
|
||||
* Added --file-extensions to show filename extensions only.
|
||||
* Added --user-filter REGEX option.
|
||||
* Allow --file-idle-time 0 (files will never expire).
|
||||
* Allow --start-position 'random' to set a random start position.
|
||||
* --log-command VCS replaces multiple --log-command-VCS options.
|
||||
* Replaced --disable-progress and --disable-bloom with arguments to --hide.
|
||||
|
||||
0.26a:
|
||||
* Updated to latest version of GL autoconf macros.
|
||||
|
||||
0.26:
|
||||
* Improved mouse dragging.
|
||||
* Holding right mouse button and moving the mouse rotates the view.
|
||||
* The middle mouse button now toggles the camera mode.
|
||||
* Username positions now scale correctly.
|
||||
* Simulation time no longer incremented while paused, counting towards file time lag.
|
||||
* M key now toggles mouse visibility.
|
||||
* Added --hide option to use instead of multiple --hide-ELEMENT options.
|
||||
|
||||
0.25:
|
||||
* Bazaar support (John Arbash Meinel).
|
||||
* Dragging the mouse on the background moves the camera.
|
||||
* Added --camera-mode option (track,overview).
|
||||
* Support DOS line endings in logs.
|
||||
* Improved compatibility of hg log command (Brendan Cully).
|
||||
* Fixed PPM exporter producing blank images on some video cards.
|
||||
* Fixed parsing of negative timezones from cvs-exp.pl logs.
|
||||
* Fixed various gdb and compiler warnings.
|
||||
|
||||
0.24:
|
||||
* PPM output speed improvements, including using a second thread (HighlandSun).
|
||||
* Now using standard autotools (Flameeyes).
|
||||
* Fixed --max-file-lag not working with some custom log files.
|
||||
* Gource will stop at the end of the log by default when recording a video.
|
||||
* Fixed STDIN stopping working after the first lot of records with tail -f.
|
||||
* Added proper exception handling.
|
||||
* Print errors to stderr.
|
||||
|
||||
0.23:
|
||||
* Hiding filenames no longer hides directory names.
|
||||
* Fixed --stop-on-idle option.
|
||||
* Added --stop-at-end option (more intuitive than --stop-position 1.0).
|
||||
|
||||
0.22:
|
||||
* Fixed Mercurial log order.
|
||||
|
||||
0.21b:
|
||||
* Fixed windows build.
|
||||
|
||||
0.21:
|
||||
* Some documentation fixes.
|
||||
|
||||
0.20:
|
||||
* Added bloom effect (turn off with --disable-bloom).
|
||||
* Added support for Mercurial (thanks to Justin Love for gource.style).
|
||||
* --start-position option now works in combination with --disable-progress.
|
||||
|
||||
0.19:
|
||||
* Use time_t instead of long for timestamps.
|
||||
|
||||
0.18:
|
||||
* Fixed camera movement while the simulation is paused.
|
||||
|
||||
0.17:
|
||||
* Show correct month for CVS logs.
|
||||
* Added time scaling (Bitshifter).
|
||||
|
||||
0.16:
|
||||
* Added --hide-dirnames option.
|
||||
* Added --user-scale option.
|
||||
* Added --date-format option (Pat Notz).
|
||||
* Fix bug when encountering long log lines.
|
||||
* Fixed incorrect parsing of trivial merges.
|
||||
* Fixed building issues on OSX.
|
||||
|
||||
0.15:
|
||||
* Added PPM output support for creating videos (Johannes Schindelin).
|
||||
* Added experimental Apache combined access log support (--log-format apache).
|
||||
* Added --stop-position and --stop-on-idle options (useful for making videos).
|
||||
* Added --max-file-lag option to limit how long after a commit file changes can take to appear.
|
||||
* Added --no-renames to the git log command as they don't display correctly.
|
||||
* Added --max-user-speed and --user-friction as options.
|
||||
* Now builds on OSX Leopard (with the required libaries installed).
|
||||
* Caught raw exception from replace_invalid().
|
||||
* Added CXXFLAGS. You may want to override the default (eg CXXFLAGS=-O3 ./configure).
|
||||
|
||||
0.14:
|
||||
* Updated SVN instructions.
|
||||
|
||||
0.13:
|
||||
* Removed single quotes from log command (fixes running gource --git-log-command in back ticks)
|
||||
* Added SVN instructions.
|
||||
* Fixed manpage hyphens.
|
||||
|
||||
0.12:
|
||||
* Added --enable-ttf-font-dir=DIR option to configure (to specify the ttf-freefont directory).
|
||||
* UTF-8 support using UTF8-CPP (http://utfcpp.sourceforge.net/).
|
||||
* Changed the git log command (see --git-log-command) to require less work to parse.
|
||||
Log files generated with the previous git-log command used by gource should continue to work.
|
||||
* Allow --seconds-per-day value less than 1.0.
|
||||
* Added --git-branch command.
|
||||
* Added --loop command.
|
||||
* Added --crop command.
|
||||
|
||||
0.11:
|
||||
* Made N key skip to next entry.
|
||||
* Documented --user-image-dir flag.
|
||||
* temp file name now uses uid instead of time
|
||||
|
||||
0.1:
|
||||
* First release.
|
469
gource/README.txt
Normal file
469
gource/README.txt
Normal file
@ -0,0 +1,469 @@
|
||||
|
||||
Gource
|
||||
|
||||
software version control visualization
|
||||
|
||||
Copyright (C) 2009 Andrew Caudwell
|
||||
|
||||
http://gource.io
|
||||
|
||||
Contents
|
||||
========
|
||||
|
||||
1. Description
|
||||
2. Requirements
|
||||
3. Using Gource
|
||||
4. Copyright
|
||||
|
||||
1. Description
|
||||
==============
|
||||
|
||||
OpenGL-based 3D visualisation tool for source control repositories.
|
||||
|
||||
The repository is displayed as a tree where the root of the repository is the
|
||||
centre, directories are branches and files are leaves. Contributors to the
|
||||
source code appear and disappear as they contribute to specific files and
|
||||
directories.
|
||||
|
||||
2. Requirements
|
||||
===============
|
||||
|
||||
Gource's display is rendered using OpenGL and requires a 3D accelerated video
|
||||
card to run.
|
||||
|
||||
3. Using Gource
|
||||
===============
|
||||
|
||||
gource [options] [path]
|
||||
|
||||
options:
|
||||
|
||||
-h, --help
|
||||
Help ('-H' for extended help).
|
||||
|
||||
-WIDTHxHEIGHT, --viewport WIDTHxHEIGHT
|
||||
Set the viewport size. If -f is also supplied, will attempt to set
|
||||
the video mode to this also. Add ! to make the window non-resizable.
|
||||
|
||||
--screen SCREEN
|
||||
Set the number of the screen to display on.
|
||||
|
||||
--window-position XxY
|
||||
Initial window position on your desktop which may be made up of
|
||||
multiple monitors.
|
||||
|
||||
This will override the screen setting so don't specify both.
|
||||
|
||||
--frameless
|
||||
Frameless window.
|
||||
|
||||
-f, --fullscreen
|
||||
Fullscreen.
|
||||
|
||||
-w, --windowed
|
||||
Windowed.
|
||||
|
||||
--transparent
|
||||
Make the background transparent. Only really useful for screenshots.
|
||||
|
||||
--start-date "YYYY-MM-DD hh:mm:ss +tz"
|
||||
Start with the first entry after the supplied date and optional time.
|
||||
|
||||
If a time zone offset isn't specified the local time zone is used.
|
||||
|
||||
Example accepted formats:
|
||||
|
||||
"2012-06-30"
|
||||
"2012-06-30 12:00"
|
||||
"2012-06-30 12:00:00 +12"
|
||||
|
||||
--stop-date "YYYY-MM-DD hh:mm:ss +tz"
|
||||
Stop after the last entry prior to the supplied date and optional time.
|
||||
|
||||
Uses the same format as --start-date.
|
||||
|
||||
-p, --start-position POSITION
|
||||
Begin at some position in the log (between 0.0 and 1.0 or 'random').
|
||||
|
||||
--stop-position POSITION
|
||||
Stop (exit) at some position in the log (does not work with STDIN).
|
||||
|
||||
-t, --stop-at-time SECONDS
|
||||
Stop (exit) after a specified number of seconds.
|
||||
|
||||
--stop-at-end
|
||||
Stop (exit) at the end of the log / stream.
|
||||
|
||||
--loop
|
||||
Loop back to the start of the log when the end is reached.
|
||||
|
||||
--loop-delay-seconds
|
||||
Seconds to delay before looping.
|
||||
|
||||
-a, --auto-skip-seconds SECONDS
|
||||
Skip to next entry if nothing happens for a number of seconds.
|
||||
|
||||
-s, --seconds-per-day SECONDS
|
||||
Speed of simulation in seconds per day.
|
||||
|
||||
--realtime
|
||||
Realtime playback speed.
|
||||
|
||||
--no-time-travel
|
||||
Use the time of the last commit if the time of a commit is in the past.
|
||||
|
||||
-c, --time-scale SCALE
|
||||
Change simulation time scale.
|
||||
|
||||
-i, --file-idle-time SECONDS
|
||||
Time in seconds files remain idle before they are removed or 0
|
||||
for no limit.
|
||||
|
||||
-e, --elasticity FLOAT
|
||||
Elasticity of nodes.
|
||||
|
||||
-b, --background-colour FFFFFF
|
||||
Background colour in hex.
|
||||
|
||||
--background-image IMAGE
|
||||
Set a background image.
|
||||
|
||||
--logo IMAGE
|
||||
Logo to display in the foreground.
|
||||
|
||||
--logo-offset XxY
|
||||
Offset position of the logo.
|
||||
|
||||
--title TITLE
|
||||
Set a title.
|
||||
|
||||
--font-file FILE
|
||||
Specify the font. Should work with most font file formats supported by FreeType, such as TTF and OTF, among others.
|
||||
|
||||
--font-scale SCALE
|
||||
Scale the size of all fonts.
|
||||
|
||||
--font-size SIZE
|
||||
Font size used by the date and title.
|
||||
|
||||
--file-font-size SIZE
|
||||
Font size of filenames.
|
||||
|
||||
--dir-font-size SIZE
|
||||
Font size of directory names
|
||||
|
||||
--user-font-size SIZE
|
||||
Font size of user names.
|
||||
|
||||
--font-colour FFFFFF
|
||||
Font colour used by the date and title in hex.
|
||||
|
||||
--key
|
||||
Show file extension key.
|
||||
|
||||
--date-format FORMAT
|
||||
Specify display date string (strftime format).
|
||||
|
||||
--log-command VCS
|
||||
Show the VCS log command used by gource (git,svn,hg,bzr,cvs2cl).
|
||||
|
||||
--log-format VCS
|
||||
Specify the log format (git,svn,hg,bzr,cvs2cl,custom).
|
||||
|
||||
Required when reading from STDIN.
|
||||
|
||||
--git-branch
|
||||
Get the git log of a branch other than the current one.
|
||||
|
||||
--follow-user USER
|
||||
Have the camera automatically follow a particular user.
|
||||
|
||||
--highlight-dirs
|
||||
Highlight the names of all directories.
|
||||
|
||||
--highlight-user USER
|
||||
Highlight the names of a particular user.
|
||||
|
||||
--highlight-users
|
||||
Highlight the names of all users.
|
||||
|
||||
--highlight-colour FFFFFF
|
||||
Font colour for highlighted users in hex.
|
||||
|
||||
--selection-colour FFFFFF
|
||||
Font colour for selected users and files.
|
||||
|
||||
--filename-colour FFFFFF
|
||||
Font colour for filenames.
|
||||
|
||||
--dir-colour FFFFFF
|
||||
Font colour for directories.
|
||||
|
||||
--dir-name-depth DEPTH
|
||||
Draw names of directories down to a specific depth in the tree.
|
||||
|
||||
--dir-name-position FLOAT
|
||||
Position along edge of the directory name
|
||||
(between 0.1 and 1.0, default is 0.5).
|
||||
|
||||
--filename-time SECONDS
|
||||
Duration to keep filenames on screen (>= 2.0).
|
||||
|
||||
--file-extensions
|
||||
Show filename extensions only.
|
||||
|
||||
--file-extension-fallback
|
||||
Use filename as extension if the extension is missing or empty.
|
||||
|
||||
--file-filter REGEX
|
||||
Filter out file paths matching the specified regular expression.
|
||||
|
||||
--file-show-filter REGEX
|
||||
Show only file paths matching the specified regular expression.
|
||||
|
||||
--user-filter REGEX
|
||||
Filter usernames matching the specified regular expression.
|
||||
|
||||
--user-show-filter REGEX
|
||||
Show only usernames matching the specified regular expression.
|
||||
|
||||
--user-image-dir DIRECTORY
|
||||
Directory containing .jpg or .png images of users
|
||||
(eg "Full Name.png") to use as avatars.
|
||||
|
||||
--default-user-image IMAGE
|
||||
Path of .jpg or .png to use as the default user image.
|
||||
|
||||
--colour-images
|
||||
Colourize user images.
|
||||
|
||||
--crop AXIS
|
||||
Crop view on an axis (vertical,horizontal).
|
||||
|
||||
--padding FLOAT
|
||||
Camera view padding.
|
||||
|
||||
--multi-sampling
|
||||
Enable multi-sampling.
|
||||
|
||||
--no-vsync
|
||||
Disable vsync.
|
||||
|
||||
--bloom-multiplier FLOAT
|
||||
Adjust the amount of bloom.
|
||||
|
||||
--bloom-intensity FLOAT
|
||||
Adjust the intensity of the bloom.
|
||||
|
||||
--max-files NUMBER
|
||||
Set the maximum number of files or 0 for no limit.
|
||||
|
||||
Excess files will be discarded.
|
||||
|
||||
--max-file-lag SECONDS
|
||||
Max time files of a commit can take to appear.
|
||||
|
||||
Use -1 for no limit.
|
||||
|
||||
--max-user-speed UNITS
|
||||
Max speed users can travel per second.
|
||||
|
||||
--user-friction SECONDS
|
||||
Time users take to come to a halt.
|
||||
|
||||
--user-scale SCALE
|
||||
Change scale of user avatars.
|
||||
|
||||
--camera-mode MODE
|
||||
Camera mode (overview,track).
|
||||
|
||||
--disable-auto-rotate
|
||||
Disable automatic camera rotation.
|
||||
|
||||
--disable-input
|
||||
Disable keyboard and mouse input.
|
||||
|
||||
--hide DISPLAY_ELEMENT
|
||||
Hide one or more display elements from the list below:
|
||||
|
||||
bloom - bloom effect
|
||||
date - current date
|
||||
dirnames - names of directories
|
||||
files - file icons
|
||||
filenames - names of files
|
||||
mouse - mouse cursor
|
||||
progress - progress bar widget
|
||||
root - root directory of tree
|
||||
tree - animated tree structure
|
||||
users - user avatars
|
||||
usernames - names of users
|
||||
|
||||
Separate multiple elements with commas (eg "mouse,progress")
|
||||
|
||||
--hash-seed SEED
|
||||
Change the seed of hash function.
|
||||
|
||||
--caption-file FILE
|
||||
Caption file (see Caption Log Format).
|
||||
|
||||
--caption-size SIZE
|
||||
Caption size.
|
||||
|
||||
--caption-colour FFFFFF
|
||||
Caption colour in hex.
|
||||
|
||||
--caption-duration SECONDS
|
||||
Caption duration.
|
||||
|
||||
--caption-offset X
|
||||
Caption horizontal offset (0 to centre captions).
|
||||
|
||||
-o, --output-ppm-stream FILE
|
||||
Output a PPM image stream to a file ('-' for STDOUT).
|
||||
|
||||
This will automatically hide the progress bar initially and
|
||||
enable 'stop-at-end' unless other behaviour is specified.
|
||||
|
||||
-r, --output-framerate FPS
|
||||
Framerate of output (25,30,60). Used with --output-ppm-stream.
|
||||
|
||||
--output-custom-log FILE
|
||||
Output a custom format log file ('-' for STDOUT).
|
||||
|
||||
--load-config CONFIG_FILE
|
||||
Load a gource conf file.
|
||||
|
||||
--save-config CONFIG_FILE
|
||||
Save a gource conf file with the current options.
|
||||
|
||||
--path PATH
|
||||
|
||||
path Either a supported version control directory, a pre-generated log
|
||||
file (see log commands or the custom log format), a Gource conf
|
||||
file or '-' to read STDIN.
|
||||
|
||||
If path is omitted, gource will attempt to read a log from the
|
||||
current directory.
|
||||
|
||||
Git, Bazaar, Mercurial and SVN Examples:
|
||||
|
||||
View the log of the repository in the current path:
|
||||
|
||||
gource
|
||||
|
||||
View the log of a project in the specified directory:
|
||||
|
||||
gource my-project-dir
|
||||
|
||||
For large projects, generating a log of the project history may take a long
|
||||
time. For centralized VCS like SVN, generating the log may also put load on
|
||||
the central VCS server.
|
||||
|
||||
In these cases, you may like to save a copy of the log for later use.
|
||||
|
||||
You can generate a log in the VCS specific log format using
|
||||
the --log-command VCS option:
|
||||
|
||||
cd my-svn-project
|
||||
`gource --log-command svn` > my-svn-project.log
|
||||
gource my-svn-project.log
|
||||
|
||||
You can also have Gource write a copy of the log file in its own format:
|
||||
|
||||
gource --output-custom-log my-project-custom.log
|
||||
|
||||
CVS Support:
|
||||
|
||||
Use 'cvs2cl' to generate the log and then pass it to Gource:
|
||||
|
||||
cvs2cl --chrono --stdout --xml -g-q > my-cvs-project.log
|
||||
gource my-cvs-project.log
|
||||
|
||||
Custom Log Format:
|
||||
|
||||
If you want to use Gource with something other than the supported systems,
|
||||
there is a pipe ('|') delimited custom log format:
|
||||
|
||||
timestamp - A unix timestamp of when the update occured.
|
||||
username - The name of the user who made the update.
|
||||
type - initial for the update type - (A)dded, (M)odified or (D)eleted.
|
||||
file - Path of the file updated.
|
||||
colour - A colour for the file in hex (FFFFFF) format. Optional.
|
||||
|
||||
Caption Log Format:
|
||||
|
||||
Gource can display captions along the timeline by specifying a caption file
|
||||
(using --caption-file) in the pipe ('|') delimited format below:
|
||||
|
||||
timestamp - A unix timestamp of when to display the caption.
|
||||
caption - The caption
|
||||
|
||||
Recording Videos:
|
||||
|
||||
See the guide on the homepage for examples of recording videos with Gource:
|
||||
|
||||
https://github.com/acaudwell/Gource/wiki/Videos
|
||||
|
||||
More Information:
|
||||
|
||||
Visit the Gource homepage for guides and examples of using Gource with various
|
||||
version control systems:
|
||||
|
||||
http://gource.io
|
||||
|
||||
Interface:
|
||||
|
||||
The time shown in the top left of the screen is set initially from the first
|
||||
log entry read and is incremented according to the simulation speed
|
||||
(--seconds-per-day).
|
||||
|
||||
Pressing SPACE at any time will pause/resume the simulation. While paused you
|
||||
may use the mouse to inspect the detail of individual files and users.
|
||||
|
||||
TAB cycles through selecting the current visible users.
|
||||
|
||||
The camera mode, either tracking activity or showing the entire code tree, can
|
||||
be toggled using the Middle mouse button.
|
||||
|
||||
You can drag the left mouse button to manually control the camera. The right
|
||||
mouse button rotates the view.
|
||||
|
||||
Interactive keyboard commands:
|
||||
|
||||
(V) Toggle camera mode
|
||||
(C) Displays Gource logo
|
||||
(K) Toggle file extension key
|
||||
(M) Toggle mouse visibility
|
||||
(N) Jump forward in time to next log entry
|
||||
(S) Randomize colours
|
||||
(D) Toggle directory name display mode
|
||||
(F) Toggle file name display mode
|
||||
(U) Toggle user name display mode
|
||||
(G) Toggle display of users
|
||||
(T) Toggle display of directory tree edges
|
||||
(R) Toggle display of root directory edges
|
||||
(+-) Adjust simulation speed
|
||||
(<>) Adjust time scale
|
||||
(TAB) Cycle through visible users
|
||||
(F12) Screenshot
|
||||
(Alt+Enter) Fullscreen toggle
|
||||
(ESC) Quit
|
||||
|
||||
4. Copyright
|
||||
============
|
||||
|
||||
Gource - software version control visualization
|
||||
Copyright (C) 2009 Andrew Caudwell <acaudwell@gmail.com>
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 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 General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
BIN
gource/SDL2.dll
Normal file
BIN
gource/SDL2.dll
Normal file
Binary file not shown.
BIN
gource/SDL2_image.dll
Normal file
BIN
gource/SDL2_image.dll
Normal file
Binary file not shown.
1
gource/THANKS.txt
Normal file
1
gource/THANKS.txt
Normal file
@ -0,0 +1 @@
|
||||
Cheers to everyone at Catalyst IT for their support and encouragement.
|
3
gource/cmd/gource
Normal file
3
gource/cmd/gource
Normal file
@ -0,0 +1,3 @@
|
||||
#!/bin/sh
|
||||
GOURCE_CMD_DIR=`dirname "$0"`
|
||||
"$GOURCE_CMD_DIR/../gource.exe" "$@"
|
2
gource/cmd/gource.cmd
Normal file
2
gource/cmd/gource.cmd
Normal file
@ -0,0 +1,2 @@
|
||||
@echo off
|
||||
"%~dp0\..\gource.exe" %*
|
BIN
gource/data/beam.png
Normal file
BIN
gource/data/beam.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 358 B |
BIN
gource/data/bloom.tga
Normal file
BIN
gource/data/bloom.tga
Normal file
Binary file not shown.
BIN
gource/data/bloom_alpha.tga
Normal file
BIN
gource/data/bloom_alpha.tga
Normal file
Binary file not shown.
BIN
gource/data/file.png
Normal file
BIN
gource/data/file.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 43 KiB |
BIN
gource/data/fonts/FreeSans.ttf
Normal file
BIN
gource/data/fonts/FreeSans.ttf
Normal file
Binary file not shown.
108
gource/data/fonts/README.txt
Normal file
108
gource/data/fonts/README.txt
Normal file
@ -0,0 +1,108 @@
|
||||
-*-text-*-
|
||||
GNU FreeFont
|
||||
|
||||
The GNU FreeFont project aims to provide a useful set of free scalable
|
||||
(i.e., OpenType) fonts covering as much as possible of the ISO 10646/Unicode
|
||||
UCS (Universal Character Set).
|
||||
|
||||
Statement of Purpose
|
||||
--------------------
|
||||
|
||||
The practical reason for putting glyphs together in a single font face is
|
||||
to conveniently mix symbols and characters from different writing systems,
|
||||
without having to switch fonts.
|
||||
|
||||
Coverage
|
||||
--------
|
||||
|
||||
FreeFont covers the following character sets
|
||||
|
||||
* ISO 8859 parts 1-15
|
||||
* CEN MES-3 European Unicode Subset
|
||||
http://www.evertype.com/standards/iso10646/pdf/cwa13873.pdf
|
||||
* IBM/Microsoft code pages 437, 850, 852, 1250, 1252 and more
|
||||
* Microsoft/Adobe Windows Glyph List 4 (WGL4)
|
||||
http://www.microsoft.com/typography/otspec/WGL4.htm
|
||||
* KOI8-R and KOI8-RU
|
||||
* DEC VT100 graphics symbols
|
||||
* International Phonetic Alphabet
|
||||
* Arabic, Hebrew, Armenian, Georgian, Ethiopian and Thai alphabets,
|
||||
including Arabic presentation forms A/B
|
||||
* mathematical symbols, including the whole TeX repertoire of symbols
|
||||
* APL symbols
|
||||
etc.
|
||||
|
||||
Editing
|
||||
-------
|
||||
|
||||
The free outline font editor, George Williams's FontForge
|
||||
<http://fontforge.sourceforge.net/> is used for editing the fonts.
|
||||
|
||||
Design Issues
|
||||
-------------
|
||||
|
||||
Which font shapes should be made? Historical style terms like Renaissance
|
||||
or Baroque letterforms cannot be applied beyond Latin/Cyrillic/Greek
|
||||
scripts to any greater extent than Kufi or Nashki can be applied beyond
|
||||
Arabic script; "italic" is really only meaningful for Latin letters.
|
||||
|
||||
However, most modern writing systems have typographic formulations for
|
||||
contrasting uniform and modulated character stroke widths, and have some
|
||||
history with "oblique", faces. Since the advent of the typewriter, most
|
||||
have developed a typographic style with uniform-width characters.
|
||||
|
||||
Accordingly, the FreeFont family has one monospaced - FreeMono - and two
|
||||
proportional faces (one with uniform stroke - FreeSans - and one with
|
||||
modulated stroke - FreeSerif).
|
||||
|
||||
To make text from different writing systems look good side-by-side, each
|
||||
FreeFont face is meant to contain characters of similar style and weight.
|
||||
|
||||
Licensing
|
||||
---------
|
||||
|
||||
Free UCS scalable fonts is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU General Public License as published
|
||||
by the Free Software Foundation; either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
The fonts are distributed in the hope that they will be useful, but
|
||||
WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
for more details.
|
||||
|
||||
You should have received a copy of the GNU 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.
|
||||
|
||||
As a special exception, if you create a document which uses this font, and
|
||||
embed this font or unaltered portions of this font into the document, this
|
||||
font does not by itself cause the resulting document to be covered by the
|
||||
GNU General Public License. This exception does not however invalidate any
|
||||
other reasons why the document might be covered by the GNU General Public
|
||||
License. If you modify this font, you may extend this exception to your
|
||||
version of the font, but you are not obligated to do so. If you do not
|
||||
wish to do so, delete this exception statement from your version.
|
||||
|
||||
|
||||
Files and their suffixes
|
||||
------------------------
|
||||
|
||||
The files with .sfd (Spline Font Database) are in FontForge's native format.
|
||||
Please use these if you plan to modify the font files.
|
||||
|
||||
TrueType fonts for immediate consumption are the files with the .ttf
|
||||
(TrueType Font) suffix. These are ready to use in Xwindows based
|
||||
systems using FreeType, on Mac OS, and on older Windows systems.
|
||||
|
||||
OpenType fonts (with suffix .otf) are for use in Windows Vista.
|
||||
Note that although they can be installed on Linux, but many applications
|
||||
in Linux still don't support them.
|
||||
|
||||
|
||||
--------------------------------------------------------------------------
|
||||
Primoz Peterlin, <primoz.peterlin@biofiz.mf.uni-lj.si>
|
||||
Steve White <stevan.white@googlemail.com>
|
||||
|
||||
Free UCS scalable fonts: http://savannah.gnu.org/projects/freefont/
|
||||
$Id: README,v 1.7 2009/01/13 08:43:23 Stevan_White Exp $
|
5
gource/data/gource.style
Normal file
5
gource/data/gource.style
Normal file
@ -0,0 +1,5 @@
|
||||
changeset = '{file_adds}{file_copies}{file_mods}{file_dels}'
|
||||
file_mod = "{date|hgdate}|{author|person}|M|{file_mod}\n"
|
||||
file_add = "{date|hgdate}|{author|person}|A|{file_add}\n"
|
||||
file_del = "{date|hgdate}|{author|person}|D|{file_del}\n"
|
||||
file_copy = "{date|hgdate}|{author|person}|A|{name}\n"
|
16
gource/data/shaders/bloom.frag
Normal file
16
gource/data/shaders/bloom.frag
Normal file
@ -0,0 +1,16 @@
|
||||
|
||||
varying vec3 pos;
|
||||
|
||||
void main()
|
||||
{
|
||||
float r = fract(sin(dot(pos.xy ,vec2(11.3713,67.3219))) * 2351.3718);
|
||||
|
||||
float offset = (0.5 - r) * gl_TexCoord[0].x * 0.045;
|
||||
|
||||
float intensity = min(1.0, cos((length(pos*2.0)+offset)/gl_TexCoord[0].x));
|
||||
float gradient = intensity * smoothstep(0.0, 2.0, intensity);
|
||||
|
||||
gradient *= smoothstep(1.0,0.67+r*0.33, 1.0-intensity);
|
||||
|
||||
gl_FragColor = gl_Color * gradient;
|
||||
}
|
10
gource/data/shaders/bloom.vert
Normal file
10
gource/data/shaders/bloom.vert
Normal file
@ -0,0 +1,10 @@
|
||||
|
||||
varying vec3 pos;
|
||||
|
||||
void main()
|
||||
{
|
||||
pos = gl_Vertex.xyz - gl_MultiTexCoord0.yzw;
|
||||
gl_TexCoord[0] = gl_MultiTexCoord0;
|
||||
gl_FrontColor = gl_Color;
|
||||
gl_Position = ftransform();
|
||||
}
|
9
gource/data/shaders/shadow.frag
Normal file
9
gource/data/shaders/shadow.frag
Normal file
@ -0,0 +1,9 @@
|
||||
uniform sampler2D tex;
|
||||
uniform float shadow_strength;
|
||||
|
||||
void main(void)
|
||||
{
|
||||
vec4 colour = texture2D(tex,gl_TexCoord[0].st);
|
||||
|
||||
gl_FragColor = vec4(0.0, 0.0, 0.0, gl_Color.w * colour.w * shadow_strength);
|
||||
}
|
6
gource/data/shaders/shadow.vert
Normal file
6
gource/data/shaders/shadow.vert
Normal file
@ -0,0 +1,6 @@
|
||||
void main(void)
|
||||
{
|
||||
gl_TexCoord[0] = gl_MultiTexCoord0;
|
||||
gl_FrontColor = gl_Color;
|
||||
gl_Position = ftransform();
|
||||
}
|
15
gource/data/shaders/text.frag
Normal file
15
gource/data/shaders/text.frag
Normal file
@ -0,0 +1,15 @@
|
||||
uniform sampler2D tex;
|
||||
uniform float shadow_strength;
|
||||
uniform float texel_size;
|
||||
|
||||
void main(void)
|
||||
{
|
||||
float colour_alpha = texture2D(tex,gl_TexCoord[0].xy).w;
|
||||
float shadow_alpha = texture2D(tex,gl_TexCoord[0].xy - vec2(texel_size)).w * shadow_strength;
|
||||
|
||||
float combined_alpha = 1.0 - (1.0-shadow_alpha)*(1.0-colour_alpha);
|
||||
|
||||
if(combined_alpha > 0.0) colour_alpha /= combined_alpha;
|
||||
|
||||
gl_FragColor = gl_Color * vec4(vec3(colour_alpha), combined_alpha);
|
||||
}
|
6
gource/data/shaders/text.vert
Normal file
6
gource/data/shaders/text.vert
Normal file
@ -0,0 +1,6 @@
|
||||
void main(void)
|
||||
{
|
||||
gl_TexCoord[0] = gl_MultiTexCoord0;
|
||||
gl_FrontColor = gl_Color;
|
||||
gl_Position = ftransform();
|
||||
}
|
BIN
gource/data/user.png
Normal file
BIN
gource/data/user.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 61 KiB |
BIN
gource/glew32.dll
Normal file
BIN
gource/glew32.dll
Normal file
Binary file not shown.
BIN
gource/gource.exe
Normal file
BIN
gource/gource.exe
Normal file
Binary file not shown.
BIN
gource/libboost_filesystem-mt.dll
Normal file
BIN
gource/libboost_filesystem-mt.dll
Normal file
Binary file not shown.
BIN
gource/libbz2-1.dll
Normal file
BIN
gource/libbz2-1.dll
Normal file
Binary file not shown.
BIN
gource/libfreetype-6.dll
Normal file
BIN
gource/libfreetype-6.dll
Normal file
Binary file not shown.
BIN
gource/libgcc_s_seh-1.dll
Normal file
BIN
gource/libgcc_s_seh-1.dll
Normal file
Binary file not shown.
BIN
gource/libglib-2.0-0.dll
Normal file
BIN
gource/libglib-2.0-0.dll
Normal file
Binary file not shown.
BIN
gource/libgraphite2.dll
Normal file
BIN
gource/libgraphite2.dll
Normal file
Binary file not shown.
BIN
gource/libharfbuzz-0.dll
Normal file
BIN
gource/libharfbuzz-0.dll
Normal file
Binary file not shown.
BIN
gource/libiconv-2.dll
Normal file
BIN
gource/libiconv-2.dll
Normal file
Binary file not shown.
BIN
gource/libintl-8.dll
Normal file
BIN
gource/libintl-8.dll
Normal file
Binary file not shown.
BIN
gource/libjpeg-8.dll
Normal file
BIN
gource/libjpeg-8.dll
Normal file
Binary file not shown.
BIN
gource/liblzma-5.dll
Normal file
BIN
gource/liblzma-5.dll
Normal file
Binary file not shown.
BIN
gource/libpcre-1.dll
Normal file
BIN
gource/libpcre-1.dll
Normal file
Binary file not shown.
BIN
gource/libpng16-16.dll
Normal file
BIN
gource/libpng16-16.dll
Normal file
Binary file not shown.
BIN
gource/libstdc++-6.dll
Normal file
BIN
gource/libstdc++-6.dll
Normal file
Binary file not shown.
BIN
gource/libtiff-5.dll
Normal file
BIN
gource/libtiff-5.dll
Normal file
Binary file not shown.
BIN
gource/libwebp-7.dll
Normal file
BIN
gource/libwebp-7.dll
Normal file
Binary file not shown.
BIN
gource/libwinpthread-1.dll
Normal file
BIN
gource/libwinpthread-1.dll
Normal file
Binary file not shown.
BIN
gource/libzstd.dll
Normal file
BIN
gource/libzstd.dll
Normal file
Binary file not shown.
BIN
gource/zlib1.dll
Normal file
BIN
gource/zlib1.dll
Normal file
Binary file not shown.
69
plains.json
Normal file
69
plains.json
Normal file
@ -0,0 +1,69 @@
|
||||
{
|
||||
"children": [],
|
||||
"decorators": [],
|
||||
"objects": [],
|
||||
"name": "Plains",
|
||||
"layers": [
|
||||
{
|
||||
"minHeight": 1,
|
||||
"terrainZoom": 5,
|
||||
"maxHeight": 3,
|
||||
"palette": [
|
||||
"GRASS_BLOCK"
|
||||
],
|
||||
"dispersion": "SCATTER"
|
||||
},
|
||||
{
|
||||
"minHeight": 1,
|
||||
"terrainZoom": 5,
|
||||
"maxHeight": 1,
|
||||
"palette": [
|
||||
"DIRT"
|
||||
],
|
||||
"dispersion": "SCATTER"
|
||||
},
|
||||
{
|
||||
"minHeight": 1,
|
||||
"terrainZoom": 5,
|
||||
"maxHeight": 3,
|
||||
"palette": [
|
||||
"DIRT",
|
||||
"COARSE_DIRT"
|
||||
],
|
||||
"dispersion": "SCATTER"
|
||||
},
|
||||
{
|
||||
"minHeight": 6,
|
||||
"terrainZoom": 5,
|
||||
"maxHeight": 2341,
|
||||
"palette": [
|
||||
"STONE",
|
||||
"ANDESITE",
|
||||
"STONE"
|
||||
],
|
||||
"dispersion": "SCATTER"
|
||||
}
|
||||
],
|
||||
"childShrinkFactor": 1.55,
|
||||
"derivative": "THE_VOID",
|
||||
"auxiliaryGenerators": [
|
||||
{
|
||||
"offsetX": 0,
|
||||
"offsetZ": 0.01,
|
||||
"min": 1,
|
||||
"seed": 1336,
|
||||
"max": 5,
|
||||
"zoom": 3.065
|
||||
},
|
||||
{
|
||||
"offsetX": 0,
|
||||
"offsetZ": 0,
|
||||
"min": 1.01,
|
||||
"seed": 1339,
|
||||
"max": 2,
|
||||
"zoom": 1.6
|
||||
}
|
||||
],
|
||||
"highHeight": 3.66669,
|
||||
"lowHeight": 31.5
|
||||
}
|
45
pom.xml
45
pom.xml
@ -44,7 +44,7 @@
|
||||
<goal>shade</goal>
|
||||
</goals>
|
||||
<configuration>
|
||||
<minimizeJar>false</minimizeJar>
|
||||
<minimizeJar>true</minimizeJar>
|
||||
</configuration>
|
||||
</execution>
|
||||
</executions>
|
||||
@ -144,26 +144,43 @@
|
||||
</repository>
|
||||
</repositories>
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>ninja.bytecode</groupId>
|
||||
<artifactId>Shuriken</artifactId>
|
||||
<version>1.1.14</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.volmit</groupId>
|
||||
<artifactId>Mortar</artifactId>
|
||||
<version>1.0.76</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.spigotmc</groupId>
|
||||
<artifactId>spigot-api</artifactId>
|
||||
<version>1.12.2-R0.1-SNAPSHOT</version>
|
||||
<version>1.16.1-R0.1-SNAPSHOT</version>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>javax.vecmath</groupId>
|
||||
<artifactId>vecmath</artifactId>
|
||||
<version>1.5.2</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.google.code.gson</groupId>
|
||||
<artifactId>gson</artifactId>
|
||||
<version>2.8.5</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.projectlombok</groupId>
|
||||
<artifactId>lombok</artifactId>
|
||||
<version>1.18.10</version>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>ninja.bytecode</groupId>
|
||||
<artifactId>Shuriken</artifactId>
|
||||
<version>1.1.24</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.bukkit</groupId>
|
||||
<artifactId>bukkit</artifactId>
|
||||
<version>1.16.1-R0.1-SNAPSHOT</version>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.bukkit.craftbukkit</groupId>
|
||||
<artifactId>cb-1.12.2</artifactId>
|
||||
<version>1.12.2</version>
|
||||
<artifactId>cb-1.16.1</artifactId>
|
||||
<version>1.16.1</version>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
20
src/main/java/ninja/bytecode/iris/GeneratedChunk.java
Normal file
20
src/main/java/ninja/bytecode/iris/GeneratedChunk.java
Normal file
@ -0,0 +1,20 @@
|
||||
package ninja.bytecode.iris;
|
||||
|
||||
import org.bukkit.generator.ChunkGenerator.BiomeGrid;
|
||||
import org.bukkit.generator.ChunkGenerator.ChunkData;
|
||||
|
||||
import lombok.Data;
|
||||
import ninja.bytecode.iris.util.ChunkPosition;
|
||||
|
||||
@Data
|
||||
public class GeneratedChunk
|
||||
{
|
||||
private ChunkPosition pos;
|
||||
private ChunkData data;
|
||||
private BiomeGrid grid;
|
||||
|
||||
public GeneratedChunk(ChunkPosition pos)
|
||||
{
|
||||
this.pos = pos;
|
||||
}
|
||||
}
|
@ -1,87 +1,242 @@
|
||||
package ninja.bytecode.iris;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
import java.util.UUID;
|
||||
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.Difficulty;
|
||||
import org.bukkit.ChatColor;
|
||||
import org.bukkit.FluidCollisionMode;
|
||||
import org.bukkit.GameMode;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.Sound;
|
||||
import org.bukkit.World;
|
||||
import org.bukkit.World.Environment;
|
||||
import org.bukkit.WorldCreator;
|
||||
import org.bukkit.block.data.BlockData;
|
||||
import org.bukkit.command.Command;
|
||||
import org.bukkit.command.CommandSender;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.event.EventHandler;
|
||||
import org.bukkit.event.HandlerList;
|
||||
import org.bukkit.event.Listener;
|
||||
import org.bukkit.event.player.PlayerJoinEvent;
|
||||
import org.bukkit.generator.ChunkGenerator;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
import org.bukkit.plugin.Plugin;
|
||||
import org.bukkit.plugin.java.JavaPlugin;
|
||||
import org.bukkit.util.Vector;
|
||||
|
||||
import mortar.api.rift.PhantomRift;
|
||||
import mortar.api.rift.Rift;
|
||||
import mortar.api.rift.RiftException;
|
||||
import mortar.bukkit.command.Command;
|
||||
import mortar.bukkit.plugin.Control;
|
||||
import mortar.bukkit.plugin.MortarPlugin;
|
||||
import mortar.util.text.C;
|
||||
import ninja.bytecode.iris.command.CommandIris;
|
||||
import ninja.bytecode.iris.controller.ExecutionController;
|
||||
import ninja.bytecode.iris.controller.PackController;
|
||||
import ninja.bytecode.iris.controller.WandController;
|
||||
import ninja.bytecode.iris.generator.IrisGenerator;
|
||||
import com.google.gson.Gson;
|
||||
|
||||
import ninja.bytecode.iris.generator.IrisChunkGenerator;
|
||||
import ninja.bytecode.iris.object.IrisBiome;
|
||||
import ninja.bytecode.iris.object.IrisDimension;
|
||||
import ninja.bytecode.iris.object.IrisObject;
|
||||
import ninja.bytecode.iris.util.BiomeResult;
|
||||
import ninja.bytecode.iris.util.BlockDataTools;
|
||||
import ninja.bytecode.iris.util.BoardManager;
|
||||
import ninja.bytecode.iris.util.BoardProvider;
|
||||
import ninja.bytecode.iris.util.BoardSettings;
|
||||
import ninja.bytecode.iris.util.CNG;
|
||||
import ninja.bytecode.iris.util.Cuboid;
|
||||
import ninja.bytecode.iris.util.Cuboid.CuboidDirection;
|
||||
import ninja.bytecode.iris.util.Desc;
|
||||
import ninja.bytecode.iris.util.Direction;
|
||||
import ninja.bytecode.iris.util.HotswapGenerator;
|
||||
import ninja.bytecode.iris.util.IrisMetrics;
|
||||
import ninja.bytecode.iris.util.GroupedExecutor;
|
||||
import ninja.bytecode.iris.util.IO;
|
||||
import ninja.bytecode.iris.util.ScoreDirection;
|
||||
import ninja.bytecode.iris.wand.WandController;
|
||||
import ninja.bytecode.shuriken.collections.KList;
|
||||
import ninja.bytecode.shuriken.collections.KMap;
|
||||
import ninja.bytecode.shuriken.execution.J;
|
||||
import ninja.bytecode.shuriken.format.Form;
|
||||
import ninja.bytecode.shuriken.json.JSONException;
|
||||
import ninja.bytecode.shuriken.json.JSONObject;
|
||||
import ninja.bytecode.shuriken.logging.L;
|
||||
import ninja.bytecode.shuriken.math.RollingSequence;
|
||||
import ninja.bytecode.shuriken.reaction.O;
|
||||
import ninja.bytecode.shuriken.tools.JarScanner;
|
||||
|
||||
public class Iris extends MortarPlugin
|
||||
public class Iris extends JavaPlugin implements BoardProvider
|
||||
{
|
||||
public static Thread primaryThread;
|
||||
public static Settings settings;
|
||||
public static IrisMetrics metrics;
|
||||
private static ExecutionController executionController;
|
||||
|
||||
public static KList<GroupedExecutor> executors = new KList<>();
|
||||
public static Iris instance;
|
||||
public static IrisDataManager data;
|
||||
public static IrisHotloadManager hotloader;
|
||||
public static WandController wand;
|
||||
private static String last = "";
|
||||
private BoardManager manager;
|
||||
private RollingSequence hits = new RollingSequence(20);
|
||||
|
||||
@Control
|
||||
private PackController packController;
|
||||
public Iris()
|
||||
{
|
||||
IO.delete(new File("iris"));
|
||||
}
|
||||
|
||||
@Control
|
||||
private WandController wandController;
|
||||
|
||||
@Command
|
||||
private CommandIris commandIris;
|
||||
|
||||
private Rift r;
|
||||
|
||||
@Override
|
||||
public void onEnable()
|
||||
{
|
||||
instance = this;
|
||||
executionController = new ExecutionController();
|
||||
executionController.start();
|
||||
primaryThread = Thread.currentThread();
|
||||
L.consoleConsumer = (s) -> Bukkit.getConsoleSender().sendMessage(s);
|
||||
Direction.calculatePermutations();
|
||||
settings = new Settings();
|
||||
getServer().getPluginManager().registerEvents((Listener) this, this);
|
||||
super.onEnable();
|
||||
}
|
||||
|
||||
public File getObjectCacheFolder()
|
||||
{
|
||||
return getDataFolder("cache", "object");
|
||||
}
|
||||
|
||||
public static boolean isGen(World world)
|
||||
{
|
||||
IrisGenerator g = getGen(world);
|
||||
return g != null;
|
||||
}
|
||||
|
||||
public static IrisGenerator getGen(World world)
|
||||
hotloader = new IrisHotloadManager();
|
||||
data = new IrisDataManager(getDataFolder());
|
||||
wand = new WandController();
|
||||
manager = new BoardManager(this, BoardSettings.builder().boardProvider(this).scoreDirection(ScoreDirection.UP).build());
|
||||
J.a(() ->
|
||||
{
|
||||
try
|
||||
{
|
||||
return (IrisGenerator) ((HotswapGenerator) world.getGenerator()).getGenerator();
|
||||
writeDocs();
|
||||
}
|
||||
catch(JSONException | InstantiationException | IllegalAccessException | IllegalArgumentException | InvocationTargetException | NoSuchMethodException | SecurityException | IOException e)
|
||||
{
|
||||
e.printStackTrace();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getTitle(Player player)
|
||||
{
|
||||
return ChatColor.GREEN + "Iris";
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<String> getLines(Player player)
|
||||
{
|
||||
World world = player.getWorld();
|
||||
List<String> lines = new ArrayList<>();
|
||||
|
||||
if(world.getGenerator() instanceof IrisChunkGenerator)
|
||||
{
|
||||
IrisChunkGenerator g = (IrisChunkGenerator) world.getGenerator();
|
||||
int x = player.getLocation().getBlockX();
|
||||
int z = player.getLocation().getBlockZ();
|
||||
BiomeResult er = g.sampleTrueBiome(x, z);
|
||||
BiomeResult erx = g.sampleBiome(x, z);
|
||||
IrisBiome b = er != null ? er.getBiome() : null;
|
||||
IrisBiome bx = erx != null ? erx.getBiome() : null;
|
||||
lines.add("&7&m-----------------");
|
||||
lines.add(ChatColor.GREEN + "Speed" + ChatColor.GRAY + ": " + ChatColor.BOLD + "" + ChatColor.GRAY + Form.f(g.getMetrics().getPerSecond().getAverage(), 0) + "/s " + Form.duration(g.getMetrics().getTotal().getAverage(), 1) + "");
|
||||
lines.add(ChatColor.GREEN + "Loss" + ChatColor.GRAY + ": " + ChatColor.BOLD + "" + ChatColor.GRAY + Form.duration(g.getMetrics().getLoss().getAverage(), 4) + "");
|
||||
lines.add(ChatColor.GREEN + "Generators" + ChatColor.GRAY + ": " + Form.f(CNG.creates));
|
||||
lines.add(ChatColor.GREEN + "Noise" + ChatColor.GRAY + ": " + Form.f((int) hits.getAverage()));
|
||||
lines.add(ChatColor.GREEN + "Parallax Regions" + ChatColor.GRAY + ": " + Form.f((int) g.getParallaxMap().getLoadedRegions().size()));
|
||||
lines.add(ChatColor.GREEN + "Parallax Chunks" + ChatColor.GRAY + ": " + Form.f((int) g.getParallaxMap().getLoadedChunks().size()));
|
||||
|
||||
if(er != null && b != null)
|
||||
{
|
||||
lines.add(ChatColor.GREEN + "Biome" + ChatColor.GRAY + ": " + b.getName());
|
||||
lines.add(ChatColor.GREEN + "Real" + ChatColor.GRAY + ": " + bx.getName());
|
||||
lines.add(ChatColor.GREEN + "File" + ChatColor.GRAY + ": " + b.getLoadKey() + ".json");
|
||||
}
|
||||
|
||||
lines.add("&7&m-----------------");
|
||||
}
|
||||
|
||||
else
|
||||
{
|
||||
lines.add(ChatColor.GREEN + "Join an Iris World!");
|
||||
}
|
||||
|
||||
return lines;
|
||||
}
|
||||
|
||||
public void writeDocs() throws IOException, JSONException, InstantiationException, IllegalAccessException, IllegalArgumentException, InvocationTargetException, NoSuchMethodException, SecurityException
|
||||
{
|
||||
JarScanner j = new JarScanner(getFile(), "ninja.bytecode.iris.object");
|
||||
j.scan();
|
||||
File of = new File(getDataFolder(), "packs");
|
||||
of.mkdirs();
|
||||
KMap<String, String> files = new KMap<>();
|
||||
|
||||
for(Class<?> i : j.getClasses())
|
||||
{
|
||||
if(i.isAnnotationPresent(Desc.class))
|
||||
{
|
||||
Desc d = i.getAnnotation(Desc.class);
|
||||
KList<String> page = new KList<>();
|
||||
page.add("# " + i.getSimpleName());
|
||||
page.add("> " + d.value());
|
||||
|
||||
page.add("```json");
|
||||
page.add(new JSONObject(new Gson().toJson(i.getConstructor().newInstance())).toString(4));
|
||||
page.add("```");
|
||||
|
||||
page.add("");
|
||||
for(java.lang.reflect.Field k : i.getDeclaredFields())
|
||||
{
|
||||
if(k.isAnnotationPresent(Desc.class))
|
||||
{
|
||||
page.add("## " + k.getName());
|
||||
page.add("> " + k.getAnnotation(Desc.class).value());
|
||||
page.add("");
|
||||
}
|
||||
}
|
||||
|
||||
String pge = page.toString("\n");
|
||||
files.put(i.getSimpleName(), pge);
|
||||
}
|
||||
}
|
||||
|
||||
for(String i : files.k())
|
||||
{
|
||||
IO.writeAll(new File(of, i + ".md"), files.get(i));
|
||||
}
|
||||
}
|
||||
|
||||
public void onDisable()
|
||||
{
|
||||
for(GroupedExecutor i : executors)
|
||||
{
|
||||
i.close();
|
||||
}
|
||||
|
||||
executors.clear();
|
||||
manager.onDisable();
|
||||
Bukkit.getScheduler().cancelTasks(this);
|
||||
HandlerList.unregisterAll((Plugin) this);
|
||||
}
|
||||
|
||||
@SuppressWarnings("deprecation")
|
||||
@Override
|
||||
public boolean onCommand(CommandSender sender, Command command, String label, String[] args)
|
||||
{
|
||||
if(command.getName().equals("iris"))
|
||||
{
|
||||
if(args.length == 0)
|
||||
{
|
||||
imsg(sender, "/iris dev [dimension] - Create a new dev world");
|
||||
imsg(sender, "/iris what <look/hand> - Data about items & blocks");
|
||||
imsg(sender, "/iris wand [?] - Get a wand / help");
|
||||
imsg(sender, "/iris save <name> - Save object");
|
||||
imsg(sender, "/iris load <name> - Load & place object");
|
||||
}
|
||||
|
||||
if(args.length >= 1)
|
||||
{
|
||||
if(args[0].equalsIgnoreCase("what"))
|
||||
{
|
||||
if(args.length != 2)
|
||||
{
|
||||
imsg(sender, "/iris what <look/hand> - Data about items & blocks");
|
||||
return true;
|
||||
}
|
||||
|
||||
BlockData bd = null;
|
||||
|
||||
try
|
||||
{
|
||||
if(args[1].toLowerCase().startsWith("h"))
|
||||
{
|
||||
bd = BlockDataTools.getBlockData(((Player) sender).getInventory().getItemInMainHand().getType().name());
|
||||
}
|
||||
|
||||
else
|
||||
{
|
||||
bd = ((Player) sender).getTargetBlockExact(128, FluidCollisionMode.NEVER).getBlockData();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
catch(Throwable e)
|
||||
@ -89,112 +244,445 @@ public class Iris extends MortarPlugin
|
||||
|
||||
}
|
||||
|
||||
return null;
|
||||
if(bd == null)
|
||||
{
|
||||
imsg(sender, "No data found.");
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void start()
|
||||
{
|
||||
instance = this;
|
||||
packController.compile();
|
||||
imsg(sender, "Material: " + ChatColor.GREEN + bd.getMaterial().name());
|
||||
imsg(sender, "Full: " + ChatColor.WHITE + bd.getAsString(true));
|
||||
|
||||
if(Iris.settings.performance.debugMode)
|
||||
return true;
|
||||
}
|
||||
|
||||
if(args[0].equalsIgnoreCase("wand"))
|
||||
{
|
||||
if(args.length == 1)
|
||||
{
|
||||
((Player) sender).getInventory().addItem(WandController.createWand());
|
||||
}
|
||||
|
||||
else if(args[1].equalsIgnoreCase("x+y"))
|
||||
{
|
||||
Player p = (Player) sender;
|
||||
|
||||
if(!WandController.isWand(p))
|
||||
{
|
||||
sender.sendMessage("Ready your Wand.");
|
||||
return true;
|
||||
}
|
||||
Location[] b = WandController.getCuboid(p.getInventory().getItemInMainHand());
|
||||
b[0].add(new Vector(0, 1, 0));
|
||||
b[1].add(new Vector(0, 1, 0));
|
||||
Location a1 = b[0].clone();
|
||||
Location a2 = b[1].clone();
|
||||
Cuboid cursor = new Cuboid(a1, a2);
|
||||
|
||||
while(!cursor.containsOnly(Material.AIR))
|
||||
{
|
||||
a1.add(new Vector(0, 1, 0));
|
||||
a2.add(new Vector(0, 1, 0));
|
||||
cursor = new Cuboid(a1, a2);
|
||||
}
|
||||
|
||||
a1.add(new Vector(0, -1, 0));
|
||||
a2.add(new Vector(0, -1, 0));
|
||||
b[0] = a1;
|
||||
a2 = b[1];
|
||||
cursor = new Cuboid(a1, a2);
|
||||
cursor = cursor.contract(CuboidDirection.North);
|
||||
cursor = cursor.contract(CuboidDirection.South);
|
||||
cursor = cursor.contract(CuboidDirection.East);
|
||||
cursor = cursor.contract(CuboidDirection.West);
|
||||
b[0] = cursor.getLowerNE();
|
||||
b[1] = cursor.getUpperSW();
|
||||
p.getInventory().setItemInMainHand(WandController.createWand(b[0], b[1]));
|
||||
p.updateInventory();
|
||||
p.playSound(p.getLocation(), Sound.ENTITY_ITEM_FRAME_ROTATE_ITEM, 1f, 0.55f);
|
||||
}
|
||||
|
||||
else if(args[1].equalsIgnoreCase("x&y"))
|
||||
{
|
||||
Player p = (Player) sender;
|
||||
|
||||
if(!WandController.isWand(p))
|
||||
{
|
||||
sender.sendMessage("Ready your Wand.");
|
||||
return true;
|
||||
}
|
||||
|
||||
Location[] b = WandController.getCuboid(p.getInventory().getItemInMainHand());
|
||||
Location a1 = b[0].clone();
|
||||
Location a2 = b[1].clone();
|
||||
Location a1x = b[0].clone();
|
||||
Location a2x = b[1].clone();
|
||||
Cuboid cursor = new Cuboid(a1, a2);
|
||||
Cuboid cursorx = new Cuboid(a1, a2);
|
||||
|
||||
while(!cursor.containsOnly(Material.AIR))
|
||||
{
|
||||
a1.add(new Vector(0, 1, 0));
|
||||
a2.add(new Vector(0, 1, 0));
|
||||
cursor = new Cuboid(a1, a2);
|
||||
}
|
||||
|
||||
a1.add(new Vector(0, -1, 0));
|
||||
a2.add(new Vector(0, -1, 0));
|
||||
|
||||
while(!cursorx.containsOnly(Material.AIR))
|
||||
{
|
||||
a1x.add(new Vector(0, -1, 0));
|
||||
a2x.add(new Vector(0, -1, 0));
|
||||
cursorx = new Cuboid(a1x, a2x);
|
||||
}
|
||||
|
||||
a1x.add(new Vector(0, 1, 0));
|
||||
a2x.add(new Vector(0, 1, 0));
|
||||
b[0] = a1;
|
||||
b[1] = a2x;
|
||||
cursor = new Cuboid(b[0], b[1]);
|
||||
cursor = cursor.contract(CuboidDirection.North);
|
||||
cursor = cursor.contract(CuboidDirection.South);
|
||||
cursor = cursor.contract(CuboidDirection.East);
|
||||
cursor = cursor.contract(CuboidDirection.West);
|
||||
b[0] = cursor.getLowerNE();
|
||||
b[1] = cursor.getUpperSW();
|
||||
p.getInventory().setItemInMainHand(WandController.createWand(b[0], b[1]));
|
||||
p.updateInventory();
|
||||
p.playSound(p.getLocation(), Sound.ENTITY_ITEM_FRAME_ROTATE_ITEM, 1f, 0.55f);
|
||||
}
|
||||
|
||||
else if(args[1].equalsIgnoreCase(">") && args.length > 2)
|
||||
{
|
||||
Player p = (Player) sender;
|
||||
|
||||
if(!WandController.isWand(p))
|
||||
{
|
||||
sender.sendMessage("Ready your Wand.");
|
||||
return true;
|
||||
}
|
||||
|
||||
int amt = Integer.valueOf(args[2]);
|
||||
Location[] b = WandController.getCuboid(p.getInventory().getItemInMainHand());
|
||||
Location a1 = b[0].clone();
|
||||
Location a2 = b[1].clone();
|
||||
Direction d = Direction.closest(p.getLocation().getDirection()).reverse();
|
||||
a1.add(d.toVector().multiply(amt));
|
||||
a2.add(d.toVector().multiply(amt));
|
||||
Cuboid cursor = new Cuboid(a1, a2);
|
||||
b[0] = cursor.getLowerNE();
|
||||
b[1] = cursor.getUpperSW();
|
||||
p.getInventory().setItemInMainHand(WandController.createWand(b[0], b[1]));
|
||||
p.updateInventory();
|
||||
p.playSound(p.getLocation(), Sound.ENTITY_ITEM_FRAME_ROTATE_ITEM, 1f, 0.55f);
|
||||
}
|
||||
|
||||
else if(args[1].equalsIgnoreCase("+") && args.length > 2)
|
||||
{
|
||||
Player p = (Player) sender;
|
||||
|
||||
if(!WandController.isWand(p))
|
||||
{
|
||||
sender.sendMessage("Ready your Wand.");
|
||||
return true;
|
||||
}
|
||||
|
||||
int amt = Integer.valueOf(args[2]);
|
||||
Location[] b = WandController.getCuboid(p.getInventory().getItemInMainHand());
|
||||
Location a1 = b[0].clone();
|
||||
Location a2 = b[1].clone();
|
||||
Cuboid cursor = new Cuboid(a1, a2);
|
||||
Direction d = Direction.closest(p.getLocation().getDirection()).reverse();
|
||||
cursor = cursor.expand(d, amt);
|
||||
b[0] = cursor.getLowerNE();
|
||||
b[1] = cursor.getUpperSW();
|
||||
p.getInventory().setItemInMainHand(WandController.createWand(b[0], b[1]));
|
||||
p.updateInventory();
|
||||
p.playSound(p.getLocation(), Sound.ENTITY_ITEM_FRAME_ROTATE_ITEM, 1f, 0.55f);
|
||||
}
|
||||
|
||||
else if(args[1].equalsIgnoreCase("-") && args.length > 2)
|
||||
{
|
||||
Player p = (Player) sender;
|
||||
|
||||
if(!WandController.isWand(p))
|
||||
{
|
||||
sender.sendMessage("Ready your Wand.");
|
||||
return true;
|
||||
}
|
||||
|
||||
int amt = Integer.valueOf(args[2]);
|
||||
Location[] b = WandController.getCuboid(p.getInventory().getItemInMainHand());
|
||||
Location a1 = b[0].clone();
|
||||
Location a2 = b[1].clone();
|
||||
Cuboid cursor = new Cuboid(a1, a2);
|
||||
Direction d = Direction.closest(p.getLocation().getDirection()).reverse();
|
||||
cursor = cursor.expand(d, -amt);
|
||||
b[0] = cursor.getLowerNE();
|
||||
b[1] = cursor.getUpperSW();
|
||||
p.getInventory().setItemInMainHand(WandController.createWand(b[0], b[1]));
|
||||
p.updateInventory();
|
||||
p.playSound(p.getLocation(), Sound.ENTITY_ITEM_FRAME_ROTATE_ITEM, 1f, 0.55f);
|
||||
}
|
||||
|
||||
else if(args[1].equalsIgnoreCase("p1"))
|
||||
{
|
||||
ItemStack wand = ((Player) sender).getInventory().getItemInMainHand();
|
||||
if(WandController.isWand(wand))
|
||||
{
|
||||
Location[] g = WandController.getCuboid(wand);
|
||||
g[0] = ((Player) sender).getLocation().getBlock().getLocation().clone().add(0, -1, 0);
|
||||
((Player) sender).setItemInHand(WandController.createWand(g[0], g[1]));
|
||||
}
|
||||
}
|
||||
|
||||
else if(args[1].equalsIgnoreCase("p2"))
|
||||
{
|
||||
ItemStack wand = ((Player) sender).getInventory().getItemInMainHand();
|
||||
if(WandController.isWand(wand))
|
||||
{
|
||||
Location[] g = WandController.getCuboid(wand);
|
||||
g[1] = ((Player) sender).getLocation().getBlock().getLocation().clone().add(0, -1, 0);
|
||||
((Player) sender).setItemInHand(WandController.createWand(g[0], g[1]));
|
||||
}
|
||||
}
|
||||
|
||||
else if(args[1].equalsIgnoreCase("l1"))
|
||||
{
|
||||
ItemStack wand = ((Player) sender).getInventory().getItemInMainHand();
|
||||
if(WandController.isWand(wand))
|
||||
{
|
||||
Location[] g = WandController.getCuboid(wand);
|
||||
g[0] = ((Player) sender).getTargetBlock((Set<Material>) null, 256).getLocation().clone();
|
||||
((Player) sender).setItemInHand(WandController.createWand(g[0], g[1]));
|
||||
}
|
||||
}
|
||||
|
||||
else if(args[1].equalsIgnoreCase("l2"))
|
||||
{
|
||||
ItemStack wand = ((Player) sender).getInventory().getItemInMainHand();
|
||||
if(WandController.isWand(wand))
|
||||
{
|
||||
Location[] g = WandController.getCuboid(wand);
|
||||
g[1] = ((Player) sender).getTargetBlock((Set<Material>) null, 256).getLocation().clone();
|
||||
((Player) sender).setItemInHand(WandController.createWand(g[0], g[1]));
|
||||
}
|
||||
}
|
||||
|
||||
else
|
||||
{
|
||||
imsg(sender, "/iris wand x+y - Expand up and out");
|
||||
imsg(sender, "/iris wand x&y - Expand up and down and out");
|
||||
imsg(sender, "/iris wand > <amt> - Shift in looking direction");
|
||||
imsg(sender, "/iris wand + <amt> - Expand in looking direction");
|
||||
imsg(sender, "/iris wand - <amt> - Contract in looking direction");
|
||||
imsg(sender, "/iris wand p1 - Set wand pos 1 where standing");
|
||||
imsg(sender, "/iris wand p2 - Set wand pos 2 where standing");
|
||||
imsg(sender, "/iris wand l1 - Set wand pos 1 where looking");
|
||||
imsg(sender, "/iris wand l2 - Set wand pos 2 where looking");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if(args[0].equalsIgnoreCase("save") && args.length >= 2)
|
||||
{
|
||||
ItemStack wand = ((Player) sender).getInventory().getItemInMainHand();
|
||||
IrisObject o = WandController.createSchematic(wand);
|
||||
try
|
||||
{
|
||||
//@builder
|
||||
r = new PhantomRift("Iris-Debug/" + UUID.randomUUID().toString())
|
||||
.setTileTickLimit(0.1)
|
||||
.setEntityTickLimit(0.1)
|
||||
.setAllowBosses(false)
|
||||
.setEnvironment(Environment.NORMAL)
|
||||
.setDifficulty(Difficulty.PEACEFUL)
|
||||
.setRandomLightUpdates(false)
|
||||
.setViewDistance(32)
|
||||
.setHangingTickRate(2000)
|
||||
.setGenerator(IrisGenerator.class)
|
||||
.load();
|
||||
|
||||
for(Player i : Bukkit.getOnlinePlayers())
|
||||
{
|
||||
r.send(i);
|
||||
}
|
||||
//@done
|
||||
o.write(new File(getDataFolder(), "objects/" + args[1] + ".iob"));
|
||||
imsg(sender, "Saved " + "objects/" + args[1] + ".iob");
|
||||
}
|
||||
|
||||
catch(RiftException e)
|
||||
catch(IOException e)
|
||||
{
|
||||
imsg(sender, "Failed to save " + "objects/" + args[1] + ".iob");
|
||||
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void stop()
|
||||
if(args[0].equalsIgnoreCase("load") && args.length >= 2)
|
||||
{
|
||||
if(settings.performance.debugMode && r != null)
|
||||
{
|
||||
r.colapse();
|
||||
}
|
||||
File file = new File(getDataFolder(), "objects/" + args[1] + ".iob");
|
||||
boolean intoWand = false;
|
||||
|
||||
HandlerList.unregisterAll((Plugin) this);
|
||||
Bukkit.getScheduler().cancelTasks(this);
|
||||
executionController.stop();
|
||||
}
|
||||
|
||||
@EventHandler
|
||||
public void on(PlayerJoinEvent e)
|
||||
for(String i : args)
|
||||
{
|
||||
if(settings.performance.debugMode && r != null)
|
||||
if(i.equalsIgnoreCase("-edit"))
|
||||
{
|
||||
e.getPlayer().teleport(r.getSpawn());
|
||||
intoWand = true;
|
||||
}
|
||||
}
|
||||
|
||||
public void reload()
|
||||
if(!file.exists())
|
||||
{
|
||||
Bukkit.getScheduler().scheduleSyncDelayedTask(Iris.instance, () ->
|
||||
imsg(sender, "Can't find " + "objects/" + args[1] + ".iob");
|
||||
}
|
||||
|
||||
ItemStack wand = ((Player) sender).getInventory().getItemInMainHand();
|
||||
IrisObject o = new IrisObject(0, 0, 0);
|
||||
|
||||
try
|
||||
{
|
||||
onDisable();
|
||||
onEnable();
|
||||
o.read(new File(getDataFolder(), "objects/" + args[1] + ".iob"));
|
||||
imsg(sender, "Loaded " + "objects/" + args[1] + ".iob");
|
||||
Location block = ((Player) sender).getTargetBlock((Set<Material>) null, 256).getLocation().clone().add(0, 1, 0);
|
||||
|
||||
if(intoWand && WandController.isWand(wand))
|
||||
{
|
||||
wand = WandController.createWand(block.clone().subtract(o.getCenter()).add(o.getW() - 1, o.getH(), o.getD() - 1), block.clone().subtract(o.getCenter()));
|
||||
((Player) sender).getInventory().setItemInMainHand(wand);
|
||||
imsg(sender, "Updated wand for " + "objects/" + args[1] + ".iob");
|
||||
}
|
||||
|
||||
WandController.pasteSchematic(o, block);
|
||||
imsg(sender, "Placed " + "objects/" + args[1] + ".iob");
|
||||
}
|
||||
|
||||
catch(IOException e)
|
||||
{
|
||||
imsg(sender, "Failed to load " + "objects/" + args[1] + ".iob");
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
if(args[0].equalsIgnoreCase("dev"))
|
||||
{
|
||||
String dim = "overworld";
|
||||
|
||||
if(args.length > 1)
|
||||
{
|
||||
dim = args[1];
|
||||
}
|
||||
|
||||
String dimm = dim;
|
||||
|
||||
Bukkit.getScheduler().scheduleSyncDelayedTask(this, () ->
|
||||
{
|
||||
for(World i : Bukkit.getWorlds())
|
||||
{
|
||||
if(i.getName().startsWith("iris/"))
|
||||
{
|
||||
for(Player j : Bukkit.getOnlinePlayers())
|
||||
{
|
||||
imsg(j, "Unloading " + i.getName());
|
||||
}
|
||||
|
||||
Bukkit.unloadWorld(i, false);
|
||||
}
|
||||
}
|
||||
|
||||
IrisDimension d = data.getDimensionLoader().load(dimm);
|
||||
|
||||
if(d == null)
|
||||
{
|
||||
imsg(sender, "Can't find dimension: " + dimm);
|
||||
return;
|
||||
}
|
||||
|
||||
for(Player i : Bukkit.getOnlinePlayers())
|
||||
{
|
||||
imsg(i, "Creating Iris " + dimm + "...");
|
||||
}
|
||||
|
||||
IrisChunkGenerator gx = new IrisChunkGenerator(dimm, 16);
|
||||
O<Boolean> done = new O<Boolean>();
|
||||
done.set(false);
|
||||
|
||||
J.a(() ->
|
||||
{
|
||||
int req = 740;
|
||||
while(!done.get())
|
||||
{
|
||||
for(Player i : Bukkit.getOnlinePlayers())
|
||||
{
|
||||
imsg(i, "Generating " + Form.pc((double) gx.getGenerated() / (double) req));
|
||||
}
|
||||
J.sleep(3000);
|
||||
}
|
||||
});
|
||||
World world = Bukkit.createWorld(new WorldCreator("iris/" + UUID.randomUUID()).generator(gx));
|
||||
done.set(true);
|
||||
|
||||
for(Player i : Bukkit.getOnlinePlayers())
|
||||
{
|
||||
imsg(i, "Generating 100%");
|
||||
}
|
||||
|
||||
for(Player i : Bukkit.getOnlinePlayers())
|
||||
{
|
||||
i.teleport(new Location(world, 0, 100, 0));
|
||||
|
||||
Bukkit.getScheduler().scheduleSyncDelayedTask(this, () ->
|
||||
{
|
||||
imsg(i, "Have Fun!");
|
||||
i.setGameMode(GameMode.SPECTATOR);
|
||||
}, 5);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public void imsg(CommandSender s, String msg)
|
||||
{
|
||||
s.sendMessage(ChatColor.GREEN + "[" + ChatColor.DARK_GRAY + "Iris" + ChatColor.GREEN + "]" + ChatColor.GRAY + ": " + msg);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ChunkGenerator getDefaultWorldGenerator(String worldName, String id)
|
||||
{
|
||||
return new HotswapGenerator(new IrisGenerator());
|
||||
return new IrisChunkGenerator("overworld", 16);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getTag(String arg0)
|
||||
public static void msg(String string)
|
||||
{
|
||||
return makeTag(C.GREEN, C.DARK_GRAY, C.GRAY, C.BOLD + "Iris" + C.RESET);
|
||||
String msg = ChatColor.GREEN + "[Iris]: " + ChatColor.GRAY + string;
|
||||
|
||||
if(last.equals(msg))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
public static String makeTag(C brace, C tag, C text, String tagName)
|
||||
{
|
||||
return brace + "\u3008" + tag + tagName + brace + "\u3009" + " " + text;
|
||||
last = msg;
|
||||
|
||||
Bukkit.getConsoleSender().sendMessage(msg);
|
||||
}
|
||||
|
||||
public static PackController pack()
|
||||
public static void warn(String string)
|
||||
{
|
||||
return instance.packController;
|
||||
msg(ChatColor.YELLOW + string);
|
||||
}
|
||||
|
||||
public static ExecutionController exec()
|
||||
public static void error(String string)
|
||||
{
|
||||
if(executionController == null)
|
||||
{
|
||||
executionController = new ExecutionController();
|
||||
executionController.start();
|
||||
msg(ChatColor.RED + string);
|
||||
}
|
||||
|
||||
return executionController;
|
||||
public static void verbose(String string)
|
||||
{
|
||||
msg(ChatColor.GRAY + string);
|
||||
}
|
||||
|
||||
public static WandController wand()
|
||||
public static void success(String string)
|
||||
{
|
||||
return instance.wandController;
|
||||
msg(ChatColor.GREEN + string);
|
||||
}
|
||||
|
||||
public static void info(String string)
|
||||
{
|
||||
msg(ChatColor.WHITE + string);
|
||||
}
|
||||
|
||||
public void hit(long hits2)
|
||||
{
|
||||
hits.put(hits2);
|
||||
}
|
||||
}
|
||||
|
37
src/main/java/ninja/bytecode/iris/IrisContext.java
Normal file
37
src/main/java/ninja/bytecode/iris/IrisContext.java
Normal file
@ -0,0 +1,37 @@
|
||||
package ninja.bytecode.iris;
|
||||
|
||||
import org.bukkit.World;
|
||||
|
||||
import ninja.bytecode.iris.object.IrisDimension;
|
||||
import ninja.bytecode.iris.object.IrisRegion;
|
||||
import ninja.bytecode.iris.util.BiomeResult;
|
||||
import ninja.bytecode.shuriken.collections.KMap;
|
||||
|
||||
public interface IrisContext
|
||||
{
|
||||
static KMap<World, IrisContext> contexts = new KMap<>();
|
||||
|
||||
public static void pushContext(IrisContext context)
|
||||
{
|
||||
contexts.put(context.getWorld(), context);
|
||||
}
|
||||
|
||||
public static IrisContext of(World world)
|
||||
{
|
||||
return contexts.get(world);
|
||||
}
|
||||
|
||||
public BiomeResult getBiome(int x, int z);
|
||||
|
||||
public IrisDimension getDimension();
|
||||
|
||||
public IrisRegion getRegion(int x, int z);
|
||||
|
||||
public IrisMetrics getMetrics();
|
||||
|
||||
public int getHeight(int x, int z);
|
||||
|
||||
public World getWorld();
|
||||
|
||||
public void onHotloaded();
|
||||
}
|
127
src/main/java/ninja/bytecode/iris/IrisDataManager.java
Normal file
127
src/main/java/ninja/bytecode/iris/IrisDataManager.java
Normal file
@ -0,0 +1,127 @@
|
||||
package ninja.bytecode.iris;
|
||||
|
||||
import java.io.File;
|
||||
|
||||
import org.bukkit.World.Environment;
|
||||
import org.bukkit.block.Biome;
|
||||
|
||||
import com.google.gson.Gson;
|
||||
|
||||
import lombok.Data;
|
||||
import ninja.bytecode.iris.object.IrisBiome;
|
||||
import ninja.bytecode.iris.object.IrisBiomeDecorator;
|
||||
import ninja.bytecode.iris.object.IrisDimension;
|
||||
import ninja.bytecode.iris.object.IrisGenerator;
|
||||
import ninja.bytecode.iris.object.IrisNoiseGenerator;
|
||||
import ninja.bytecode.iris.object.IrisObjectPlacement;
|
||||
import ninja.bytecode.iris.object.IrisRegion;
|
||||
import ninja.bytecode.iris.util.IO;
|
||||
import ninja.bytecode.iris.util.ObjectResourceLoader;
|
||||
import ninja.bytecode.iris.util.ResourceLoader;
|
||||
import ninja.bytecode.shuriken.json.JSONObject;
|
||||
|
||||
@Data
|
||||
public class IrisDataManager
|
||||
{
|
||||
private File dataFolder;
|
||||
private File packs;
|
||||
private ResourceLoader<IrisBiome> biomeLoader;
|
||||
private ResourceLoader<IrisRegion> regionLoader;
|
||||
private ResourceLoader<IrisDimension> dimensionLoader;
|
||||
private ResourceLoader<IrisGenerator> generatorLoader;
|
||||
private ObjectResourceLoader objectLoader;
|
||||
|
||||
public void hotloaded()
|
||||
{
|
||||
packs.mkdirs();
|
||||
this.regionLoader = new ResourceLoader<>(packs, "regions", "Region", IrisRegion.class);
|
||||
this.biomeLoader = new ResourceLoader<>(packs, "biomes", "Biome", IrisBiome.class);
|
||||
this.dimensionLoader = new ResourceLoader<>(packs, "dimensions", "Dimension", IrisDimension.class);
|
||||
this.generatorLoader = new ResourceLoader<>(packs, "generators", "Generator", IrisGenerator.class);
|
||||
this.objectLoader = new ObjectResourceLoader(packs, "objects", "Object");
|
||||
writeExamples();
|
||||
}
|
||||
|
||||
public IrisDataManager(File dataFolder)
|
||||
{
|
||||
this.dataFolder = dataFolder;
|
||||
this.packs = new File(dataFolder, "packs");
|
||||
hotloaded();
|
||||
}
|
||||
|
||||
private void writeExamples()
|
||||
{
|
||||
File examples = new File(dataFolder, "example");
|
||||
examples.mkdirs();
|
||||
String biomes = "";
|
||||
String envs = "";
|
||||
|
||||
for(Biome i : Biome.values())
|
||||
{
|
||||
biomes += i.name() + "\n";
|
||||
}
|
||||
|
||||
for(Environment i : Environment.values())
|
||||
{
|
||||
envs += i.name() + "\n";
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
new File(examples, "example-pack/regions").mkdirs();
|
||||
new File(examples, "example-pack/biomes").mkdirs();
|
||||
new File(examples, "example-pack/dimensions").mkdirs();
|
||||
new File(examples, "example-pack/generators").mkdirs();
|
||||
IO.writeAll(new File(examples, "biome-list.txt"), biomes);
|
||||
IO.writeAll(new File(examples, "environment-list.txt"), envs);
|
||||
|
||||
IrisGenerator gen = new IrisGenerator();
|
||||
IrisNoiseGenerator n = new IrisNoiseGenerator();
|
||||
n.setSeed(1000);
|
||||
IrisNoiseGenerator nf = new IrisNoiseGenerator();
|
||||
nf.setIrisBased(false);
|
||||
nf.setOctaves(3);
|
||||
nf.setOpacity(16);
|
||||
nf.setZoom(24);
|
||||
nf.setSeed(44);
|
||||
n.getFracture().add(nf);
|
||||
IrisNoiseGenerator nf2 = new IrisNoiseGenerator();
|
||||
nf2.setIrisBased(false);
|
||||
nf2.setOctaves(8);
|
||||
nf2.setOpacity(24);
|
||||
nf2.setZoom(64);
|
||||
nf2.setSeed(55);
|
||||
n.getFracture().add(nf2);
|
||||
gen.getComposite().add(n);
|
||||
|
||||
IrisDimension dim = new IrisDimension();
|
||||
|
||||
IrisRegion region = new IrisRegion();
|
||||
region.getLandBiomes().add("plains");
|
||||
region.getLandBiomes().add("desert");
|
||||
region.getLandBiomes().add("forest");
|
||||
region.getLandBiomes().add("mountains");
|
||||
region.getSeaBiomes().add("ocean");
|
||||
region.getShoreBiomes().add("beach");
|
||||
|
||||
IrisObjectPlacement o = new IrisObjectPlacement();
|
||||
o.getPlace().add("schematic1");
|
||||
o.getPlace().add("schematic2");
|
||||
|
||||
IrisBiome biome = new IrisBiome();
|
||||
biome.getChildren().add("another_biome");
|
||||
biome.getDecorators().add(new IrisBiomeDecorator());
|
||||
biome.getObjects().add(o);
|
||||
|
||||
IO.writeAll(new File(examples, "example-pack/biomes/example-biome.json"), new JSONObject(new Gson().toJson(biome)).toString(4));
|
||||
IO.writeAll(new File(examples, "example-pack/regions/example-region.json"), new JSONObject(new Gson().toJson(region)).toString(4));
|
||||
IO.writeAll(new File(examples, "example-pack/dimensions/example-dimension.json"), new JSONObject(new Gson().toJson(dim)).toString(4));
|
||||
IO.writeAll(new File(examples, "example-pack/generators/example-generator.json"), new JSONObject(new Gson().toJson(gen)).toString(4));
|
||||
}
|
||||
|
||||
catch(Throwable e)
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
}
|
58
src/main/java/ninja/bytecode/iris/IrisHotloadManager.java
Normal file
58
src/main/java/ninja/bytecode/iris/IrisHotloadManager.java
Normal file
@ -0,0 +1,58 @@
|
||||
package ninja.bytecode.iris;
|
||||
|
||||
import java.io.File;
|
||||
|
||||
import org.bukkit.Bukkit;
|
||||
|
||||
import ninja.bytecode.iris.util.ChronoLatch;
|
||||
import ninja.bytecode.iris.util.FileWatcher;
|
||||
import ninja.bytecode.shuriken.collections.KSet;
|
||||
|
||||
public class IrisHotloadManager
|
||||
{
|
||||
private ChronoLatch latch;
|
||||
private KSet<FileWatcher> watchers;
|
||||
|
||||
public IrisHotloadManager()
|
||||
{
|
||||
watchers = new KSet<>();
|
||||
latch = new ChronoLatch(3000);
|
||||
}
|
||||
|
||||
public void check(IrisContext ch)
|
||||
{
|
||||
if(!latch.flip())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
Bukkit.getScheduler().scheduleSyncDelayedTask(Iris.instance, () ->
|
||||
{
|
||||
boolean modified = false;
|
||||
int c = 0;
|
||||
|
||||
for(FileWatcher i : watchers)
|
||||
{
|
||||
if(i.checkModified())
|
||||
{
|
||||
c++;
|
||||
Iris.info("File Modified: " + i.getFile().getPath());
|
||||
modified = true;
|
||||
}
|
||||
}
|
||||
|
||||
if(modified)
|
||||
{
|
||||
watchers.clear();
|
||||
Iris.success("Hotloading Iris (" + c + " File" + (c == 1 ? "" : "s") + " changed)");
|
||||
Iris.data.hotloaded();
|
||||
ch.onHotloaded();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public void track(File file)
|
||||
{
|
||||
watchers.add(new FileWatcher(file));
|
||||
}
|
||||
}
|
21
src/main/java/ninja/bytecode/iris/IrisMetrics.java
Normal file
21
src/main/java/ninja/bytecode/iris/IrisMetrics.java
Normal file
@ -0,0 +1,21 @@
|
||||
package ninja.bytecode.iris;
|
||||
|
||||
import lombok.Data;
|
||||
import ninja.bytecode.shuriken.math.RollingSequence;
|
||||
|
||||
@Data
|
||||
public class IrisMetrics
|
||||
{
|
||||
private final RollingSequence total;
|
||||
private final RollingSequence perSecond;
|
||||
private final RollingSequence loss;
|
||||
public int generators = 0;
|
||||
public int noiseHits = 0;
|
||||
|
||||
public IrisMetrics(int memory)
|
||||
{
|
||||
total = new RollingSequence(memory);
|
||||
perSecond = new RollingSequence(5);
|
||||
loss = new RollingSequence(memory);
|
||||
}
|
||||
}
|
9
src/main/java/ninja/bytecode/iris/IrisSettings.java
Normal file
9
src/main/java/ninja/bytecode/iris/IrisSettings.java
Normal file
@ -0,0 +1,9 @@
|
||||
package ninja.bytecode.iris;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
@Data
|
||||
public class IrisSettings
|
||||
{
|
||||
private int threads = 8;
|
||||
}
|
@ -1,87 +0,0 @@
|
||||
package ninja.bytecode.iris;
|
||||
|
||||
import ninja.bytecode.iris.util.InterpolationMode;
|
||||
import ninja.bytecode.iris.util.ObjectMode;
|
||||
import ninja.bytecode.iris.util.PerformanceMode;
|
||||
|
||||
public class Settings
|
||||
{
|
||||
public PerformanceSettings performance = new PerformanceSettings();
|
||||
public GeneratorSettings gen = new GeneratorSettings();
|
||||
public OreSettings ore = new OreSettings();
|
||||
|
||||
public static class PerformanceSettings
|
||||
{
|
||||
public PerformanceMode performanceMode = PerformanceMode.EXPLICIT;
|
||||
public ObjectMode objectMode = ObjectMode.PARALLAX;
|
||||
public int threadPriority = Thread.MAX_PRIORITY;
|
||||
public int threadCount = 32;
|
||||
public boolean debugMode = true;
|
||||
public int decorationAccuracy = 1;
|
||||
public boolean noObjectFail = false;
|
||||
public boolean verbose = false;
|
||||
public int placeHistoryLimit = 8192;
|
||||
}
|
||||
|
||||
public static class GeneratorSettings
|
||||
{
|
||||
public InterpolationMode interpolationMode = InterpolationMode.BILINEAR;
|
||||
public int interpolationRadius = 53;
|
||||
public int blockSmoothing = 1;
|
||||
public double objectDensity = 1D;
|
||||
public double horizontalZoom = 2;
|
||||
public double heightFracture = 155;
|
||||
public double landScale = 0.44;
|
||||
public double landChance = 0.56;
|
||||
public double roughness = 1.25;
|
||||
public double biomeEdgeFuzzScale = 1.75;
|
||||
public double biomeEdgeScrambleScale = 0.2;
|
||||
public double biomeEdgeScrambleRange = 2.5;
|
||||
public double heightMultiplier = 0.806;
|
||||
public double heightExponentBase = 1;
|
||||
public double heightExponentMultiplier = 1.41;
|
||||
public double heightScale = 0.56;
|
||||
public double baseHeight = 0.065;
|
||||
public int seaLevel = 63;
|
||||
public double biomeScale = 0.8;
|
||||
public boolean flatBedrock = false;
|
||||
}
|
||||
|
||||
public static class OreSettings
|
||||
{
|
||||
public int ironMinHeight = 5;
|
||||
public int ironMaxHeight = 65;
|
||||
public double ironMaxDispersion = 0.02;
|
||||
public double ironMinDispersion = 0.26;
|
||||
|
||||
public int coalMinHeight = 5;
|
||||
public int coalMaxHeight = 100;
|
||||
public double coalMaxDispersion = 0.02;
|
||||
public double coalMinDispersion = 0.29;
|
||||
|
||||
public int goldMinHeight = 5;
|
||||
public int goldMaxHeight = 34;
|
||||
public double goldMaxDispersion = 0.01;
|
||||
public double goldMinDispersion = 0.13;
|
||||
|
||||
public int redstoneMinHeight = 5;
|
||||
public int redstoneMaxHeight = 15;
|
||||
public double redstoneMaxDispersion = 0.05;
|
||||
public double redstoneMinDispersion = 0.17;
|
||||
|
||||
public int lapisMinHeight = 13;
|
||||
public int lapisMaxHeight = 33;
|
||||
public double lapisMaxDispersion = 0.05;
|
||||
public double lapisMinDispersion = 0.12;
|
||||
|
||||
public int diamondMinHeight = 5;
|
||||
public int diamondMaxHeight = 16;
|
||||
public double diamondMaxDispersion = 0.05;
|
||||
public double diamondMinDispersion = 0.1;
|
||||
|
||||
public int emeraldMinHeight = 5;
|
||||
public int emeraldMaxHeight = 16;
|
||||
public double emeraldMaxDispersion = 0.005;
|
||||
public double emeraldMinDispersion = 0.07;
|
||||
}
|
||||
}
|
@ -1,33 +0,0 @@
|
||||
package ninja.bytecode.iris.command;
|
||||
|
||||
import mortar.bukkit.command.Command;
|
||||
import mortar.bukkit.command.MortarCommand;
|
||||
import mortar.bukkit.command.MortarSender;
|
||||
import mortar.util.text.C;
|
||||
|
||||
public class CommandFind extends MortarCommand
|
||||
{
|
||||
@Command
|
||||
private CommandFindBiome fBiome;
|
||||
|
||||
@Command
|
||||
private CommandFindObject fObject;
|
||||
|
||||
public CommandFind()
|
||||
{
|
||||
super("find", "f");
|
||||
setDescription("Teleport to a specific biome / object");
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean handle(MortarSender sender, String[] args)
|
||||
{
|
||||
for(MortarCommand i : getChildren())
|
||||
{
|
||||
sender.sendMessage("/iris find " + C.WHITE + i.getNode() + C.GRAY + (!i.getNodes().isEmpty() ? "," : "") + i.getNodes().toString(",") + " - " + C.DARK_GREEN + i.getDescription());
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
@ -1,93 +0,0 @@
|
||||
package ninja.bytecode.iris.command;
|
||||
|
||||
import org.bukkit.World;
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
import mortar.bukkit.command.MortarCommand;
|
||||
import mortar.bukkit.command.MortarSender;
|
||||
import ninja.bytecode.iris.Iris;
|
||||
import ninja.bytecode.iris.generator.IrisGenerator;
|
||||
import ninja.bytecode.iris.pack.IrisBiome;
|
||||
|
||||
public class CommandFindBiome extends MortarCommand
|
||||
{
|
||||
public CommandFindBiome()
|
||||
{
|
||||
super("biome", "b");
|
||||
setDescription("Teleport to a biome by name");
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean handle(MortarSender sender, String[] args)
|
||||
{
|
||||
World w = null;
|
||||
|
||||
if(sender.isPlayer() && Iris.isGen(sender.player().getWorld()))
|
||||
{
|
||||
w = sender.player().getWorld();
|
||||
}
|
||||
|
||||
else
|
||||
{
|
||||
if(sender.isPlayer())
|
||||
{
|
||||
sender.sendMessage(sender.player().getWorld().getGenerator().getClass().getCanonicalName());
|
||||
}
|
||||
|
||||
sender.sendMessage("Console / Non-Iris World.");
|
||||
return true;
|
||||
}
|
||||
|
||||
Player p = sender.player();
|
||||
IrisGenerator g = Iris.getGen(p.getWorld());
|
||||
if(args.length > 0)
|
||||
{
|
||||
IrisBiome b = null;
|
||||
for(IrisBiome i : g.getDimension().getBiomes())
|
||||
{
|
||||
if(args[0].toLowerCase().equals(i.getName().toLowerCase().replaceAll("\\Q \\E", "_")))
|
||||
{
|
||||
b = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if(b == null)
|
||||
{
|
||||
sender.sendMessage("Couldn't find any biomes containing '" + args[0] + "'.");
|
||||
}
|
||||
|
||||
else
|
||||
{
|
||||
sender.sendMessage("Looking for Biome " + b.getName() + "...");
|
||||
boolean f = false;
|
||||
|
||||
for(int i = 0; i < 10000; i++)
|
||||
{
|
||||
int x = (int) ((int) (29999983 / 1.2) * Math.random());
|
||||
int z = (int) ((int) (29999983 / 1.2) * Math.random());
|
||||
|
||||
if(g.getBiome((int) g.getOffsetX(x, z), (int) g.getOffsetZ(x, z)).equals(b))
|
||||
{
|
||||
f = true;
|
||||
p.teleport(w.getHighestBlockAt(x, z).getLocation());
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if(!f)
|
||||
{
|
||||
sender.sendMessage("Couldn't for " + b.getName() + " in 10,000 different locations and could not find it. Try again!");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
else
|
||||
{
|
||||
sender.sendMessage("/iris find biome <query>");
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
@ -1,64 +0,0 @@
|
||||
package ninja.bytecode.iris.command;
|
||||
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.World;
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
import mortar.bukkit.command.MortarCommand;
|
||||
import mortar.bukkit.command.MortarSender;
|
||||
import mortar.util.text.C;
|
||||
import ninja.bytecode.iris.Iris;
|
||||
import ninja.bytecode.iris.generator.genobject.PlacedObject;
|
||||
|
||||
public class CommandFindObject extends MortarCommand
|
||||
{
|
||||
public CommandFindObject()
|
||||
{
|
||||
super("object", "o");
|
||||
setDescription("Teleport to an object by name");
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean handle(MortarSender sender, String[] args)
|
||||
{
|
||||
World w = null;
|
||||
|
||||
if(sender.isPlayer() && Iris.isGen(sender.player().getWorld()))
|
||||
{
|
||||
w = sender.player().getWorld();
|
||||
}
|
||||
|
||||
else
|
||||
{
|
||||
sender.sendMessage("Console / Non-Iris World.");
|
||||
return true;
|
||||
}
|
||||
|
||||
Player p = sender.player();
|
||||
|
||||
if(args.length > 0)
|
||||
{
|
||||
PlacedObject o = Iris.getGen(w).randomObject(args[0]);
|
||||
|
||||
if(o != null)
|
||||
{
|
||||
Location l = new Location(w, o.getX(), o.getY(), o.getZ());
|
||||
p.teleport(l);
|
||||
sender.sendMessage("Found Object " + C.DARK_GREEN + o.getF().replace(":", "/" + C.WHITE));
|
||||
}
|
||||
|
||||
else
|
||||
{
|
||||
sender.sendMessage("Couldn't find any objects containing '" + args[0] + "' Either");
|
||||
}
|
||||
}
|
||||
|
||||
else
|
||||
{
|
||||
sender.sendMessage("/iris find object <query>");
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
@ -1,44 +0,0 @@
|
||||
package ninja.bytecode.iris.command;
|
||||
|
||||
import mortar.bukkit.command.Command;
|
||||
import mortar.bukkit.command.MortarCommand;
|
||||
import mortar.bukkit.command.MortarSender;
|
||||
import mortar.util.text.C;
|
||||
|
||||
public class CommandIris extends MortarCommand
|
||||
{
|
||||
@Command
|
||||
private CommandTimings timings;
|
||||
|
||||
@Command
|
||||
private CommandWhat what;
|
||||
|
||||
@Command
|
||||
private CommandFind find;
|
||||
|
||||
@Command
|
||||
private CommandObject object;
|
||||
|
||||
@Command
|
||||
private CommandSelection selection;
|
||||
|
||||
@Command
|
||||
private CommandReload reload;
|
||||
|
||||
public CommandIris()
|
||||
{
|
||||
super("iris", "irs", "ir");
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean handle(MortarSender sender, String[] args)
|
||||
{
|
||||
for(MortarCommand i : getChildren())
|
||||
{
|
||||
sender.sendMessage("/iris " + C.WHITE + i.getNode() + C.GRAY + (!i.getNodes().isEmpty() ? "," : "") + i.getNodes().toString(",") + " - " + C.DARK_GREEN + i.getDescription());
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
@ -1,36 +0,0 @@
|
||||
package ninja.bytecode.iris.command;
|
||||
|
||||
import mortar.bukkit.command.Command;
|
||||
import mortar.bukkit.command.MortarCommand;
|
||||
import mortar.bukkit.command.MortarSender;
|
||||
import mortar.util.text.C;
|
||||
|
||||
public class CommandObject extends MortarCommand
|
||||
{
|
||||
@Command
|
||||
private CommandObjectWand oWand;
|
||||
|
||||
@Command
|
||||
private CommandObjectLoad oLoad;
|
||||
|
||||
@Command
|
||||
private CommandObjectSave oSave;
|
||||
|
||||
public CommandObject()
|
||||
{
|
||||
super("object", "o");
|
||||
setDescription("Object Subcommands");
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean handle(MortarSender sender, String[] args)
|
||||
{
|
||||
for(MortarCommand i : getChildren())
|
||||
{
|
||||
sender.sendMessage("/iris object " + C.WHITE + i.getNode() + C.GRAY + (!i.getNodes().isEmpty() ? "," : "") + i.getNodes().toString(",") + " - " + C.DARK_GREEN + i.getDescription());
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
@ -1,166 +0,0 @@
|
||||
package ninja.bytecode.iris.command;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileInputStream;
|
||||
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.Sound;
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
import mortar.bukkit.command.MortarCommand;
|
||||
import mortar.bukkit.command.MortarSender;
|
||||
import mortar.util.text.C;
|
||||
import ninja.bytecode.iris.Iris;
|
||||
import ninja.bytecode.iris.controller.WandController;
|
||||
import ninja.bytecode.iris.generator.genobject.GenObject;
|
||||
import ninja.bytecode.iris.util.Direction;
|
||||
import ninja.bytecode.shuriken.format.Form;
|
||||
|
||||
public class CommandObjectLoad extends MortarCommand
|
||||
{
|
||||
public CommandObjectLoad()
|
||||
{
|
||||
super("load", "l");
|
||||
setDescription("Load & Paste an object");
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean handle(MortarSender sender, String[] args)
|
||||
{
|
||||
if(!sender.isPlayer())
|
||||
{
|
||||
sender.sendMessage("Players Only");
|
||||
return true;
|
||||
}
|
||||
|
||||
if(args.length < 1)
|
||||
{
|
||||
sender.sendMessage("/iris object load <name>");
|
||||
sender.sendMessage("Use -c to place at cursor");
|
||||
sender.sendMessage("Use -g to place with gravity");
|
||||
sender.sendMessage("Use -w to set hydrophilic");
|
||||
sender.sendMessage("Use -u to set submerged");
|
||||
sender.sendMessage("Use -h:<int> to shift vertically");
|
||||
sender.sendMessage("Use -m:<int> to set max slope");
|
||||
sender.sendMessage("Use -b:<int> to set base slope");
|
||||
sender.sendMessage("Use -f:N -t:S to rotate north to south (180 deg)");
|
||||
return true;
|
||||
}
|
||||
|
||||
Player p = sender.player();
|
||||
|
||||
GenObject s = new GenObject(1, 1, 1);
|
||||
File f = new File(Iris.instance.getDataFolder(), "schematics/" + args[0] + ".ish");
|
||||
|
||||
if(!f.exists())
|
||||
{
|
||||
sender.sendMessage("Can't find " + args[0]);
|
||||
return true;
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
FileInputStream fin = new FileInputStream(f);
|
||||
s.read(fin, true);
|
||||
|
||||
boolean cursor = false;
|
||||
boolean gravity = false;
|
||||
Direction df = null;
|
||||
Direction dt = null;
|
||||
int shift = 0;
|
||||
|
||||
for(String i : args)
|
||||
{
|
||||
if(i.equalsIgnoreCase("-c"))
|
||||
{
|
||||
sender.sendMessage("Placing @ Cursor");
|
||||
cursor = true;
|
||||
continue;
|
||||
}
|
||||
|
||||
if(i.equalsIgnoreCase("-u"))
|
||||
{
|
||||
sender.sendMessage("Placing Submerged");
|
||||
s.setSubmerged(true);
|
||||
continue;
|
||||
}
|
||||
|
||||
if(i.equalsIgnoreCase("-w"))
|
||||
{
|
||||
sender.sendMessage("Placing with Hydrophilia");
|
||||
s.setHydrophilic(true);
|
||||
continue;
|
||||
}
|
||||
|
||||
if(i.equalsIgnoreCase("-g"))
|
||||
{
|
||||
sender.sendMessage("Placing with Gravity");
|
||||
gravity = true;
|
||||
continue;
|
||||
}
|
||||
|
||||
if(i.startsWith("-m:"))
|
||||
{
|
||||
shift = Integer.valueOf(i.split("\\Q:\\E")[1]);
|
||||
sender.sendMessage("Max Slope set to " + shift);
|
||||
s.setMaxslope(shift);
|
||||
continue;
|
||||
}
|
||||
|
||||
if(i.startsWith("-b:"))
|
||||
{
|
||||
shift = Integer.valueOf(i.split("\\Q:\\E")[1]);
|
||||
sender.sendMessage("Base Slope set to " + shift);
|
||||
s.setBaseslope(shift);
|
||||
continue;
|
||||
}
|
||||
|
||||
if(i.startsWith("-h:"))
|
||||
{
|
||||
shift = Integer.valueOf(i.split("\\Q:\\E")[1]);
|
||||
sender.sendMessage("Shifting Placement by 0," + shift + ",0");
|
||||
continue;
|
||||
}
|
||||
|
||||
if(i.startsWith("-f:"))
|
||||
{
|
||||
df = Direction.valueOf(i.split("\\Q:\\E")[1].toUpperCase().substring(0, 1));
|
||||
continue;
|
||||
}
|
||||
|
||||
if(i.startsWith("-t:"))
|
||||
{
|
||||
dt = Direction.valueOf(i.split("\\Q:\\E")[1].toUpperCase().substring(0, 1));
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
if(dt != null && df != null)
|
||||
{
|
||||
sender.sendMessage("Rotating " + C.WHITE + df + C.GRAY + " to " + C.WHITE + dt);
|
||||
s.rotate(df, dt);
|
||||
}
|
||||
|
||||
Location at = p.getLocation();
|
||||
|
||||
if(cursor)
|
||||
{
|
||||
at = p.getTargetBlock(null, 64).getLocation();
|
||||
}
|
||||
|
||||
s.setShift(0, shift, 0);
|
||||
s.setGravity(gravity);
|
||||
WandController.pasteSchematic(s, at);
|
||||
p.playSound(p.getLocation(), Sound.BLOCK_ENCHANTMENT_TABLE_USE, 1f, 1.25f);
|
||||
sender.sendMessage("Pasted " + args[0] + " (" + Form.f(s.getSchematic().size()) + " Blocks Modified)");
|
||||
}
|
||||
|
||||
catch(Throwable e1)
|
||||
{
|
||||
e1.printStackTrace();
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
@ -1,67 +0,0 @@
|
||||
package ninja.bytecode.iris.command;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileOutputStream;
|
||||
|
||||
import org.bukkit.Sound;
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
import mortar.bukkit.command.MortarCommand;
|
||||
import mortar.bukkit.command.MortarSender;
|
||||
import ninja.bytecode.iris.Iris;
|
||||
import ninja.bytecode.iris.controller.WandController;
|
||||
import ninja.bytecode.iris.generator.genobject.GenObject;
|
||||
import ninja.bytecode.shuriken.format.Form;
|
||||
|
||||
public class CommandObjectSave extends MortarCommand
|
||||
{
|
||||
public CommandObjectSave()
|
||||
{
|
||||
super("save", "s");
|
||||
setDescription("Save an object");
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean handle(MortarSender sender, String[] args)
|
||||
{
|
||||
if(!sender.isPlayer())
|
||||
{
|
||||
sender.sendMessage("Players Only");
|
||||
return true;
|
||||
}
|
||||
|
||||
if(args.length < 1)
|
||||
{
|
||||
sender.sendMessage("/iris object save <name>");
|
||||
return true;
|
||||
}
|
||||
|
||||
Player p = sender.player();
|
||||
GenObject s = WandController.createSchematic(p.getInventory().getItemInMainHand(), p.getLocation());
|
||||
|
||||
if(s == null)
|
||||
{
|
||||
sender.sendMessage("Hold your wand while using this command.");
|
||||
return true;
|
||||
}
|
||||
|
||||
File f = new File(Iris.instance.getDataFolder(), "schematics/" + args[0] + ".ish");
|
||||
f.getParentFile().mkdirs();
|
||||
try
|
||||
{
|
||||
FileOutputStream fos = new FileOutputStream(f);
|
||||
s.write(fos, true);
|
||||
p.sendMessage("Saved " + args[0] + " (" + Form.f(s.getSchematic().size()) + " Entries)");
|
||||
p.playSound(p.getLocation(), Sound.BLOCK_ENCHANTMENT_TABLE_USE, 1f, 0.45f);
|
||||
}
|
||||
|
||||
catch(Throwable e1)
|
||||
{
|
||||
p.sendMessage("Failed. Check the console!");
|
||||
e1.printStackTrace();
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
@ -1,32 +0,0 @@
|
||||
package ninja.bytecode.iris.command;
|
||||
|
||||
import org.bukkit.Sound;
|
||||
|
||||
import mortar.bukkit.command.MortarCommand;
|
||||
import mortar.bukkit.command.MortarSender;
|
||||
import ninja.bytecode.iris.controller.WandController;
|
||||
|
||||
public class CommandObjectWand extends MortarCommand
|
||||
{
|
||||
public CommandObjectWand()
|
||||
{
|
||||
super("wand", "w");
|
||||
setDescription("Obtain Iris Wand");
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean handle(MortarSender sender, String[] args)
|
||||
{
|
||||
if(!sender.isPlayer())
|
||||
{
|
||||
sender.sendMessage("Players Only");
|
||||
return true;
|
||||
}
|
||||
|
||||
sender.player().getInventory().addItem(WandController.createWand());
|
||||
sender.player().playSound(sender.player().getLocation(), Sound.ITEM_ARMOR_EQUIP_DIAMOND, 1f, 1.55f);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
@ -1,36 +0,0 @@
|
||||
package ninja.bytecode.iris.command;
|
||||
|
||||
import mortar.bukkit.command.Command;
|
||||
import mortar.bukkit.command.MortarCommand;
|
||||
import mortar.bukkit.command.MortarSender;
|
||||
import mortar.util.text.C;
|
||||
|
||||
public class CommandReload extends MortarCommand
|
||||
{
|
||||
@Command
|
||||
private CommandReloadPack rThis;
|
||||
|
||||
@Command
|
||||
private CommandReloadChunks rChunks;
|
||||
|
||||
@Command
|
||||
private CommandReloadIris rIris;
|
||||
|
||||
public CommandReload()
|
||||
{
|
||||
super("reload", "r");
|
||||
setDescription("Reload Chunks / Pack / Iris");
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean handle(MortarSender sender, String[] args)
|
||||
{
|
||||
for(MortarCommand i : getChildren())
|
||||
{
|
||||
sender.sendMessage("/iris reload " + C.WHITE + i.getNode() + C.GRAY + (!i.getNodes().isEmpty() ? "," : "") + i.getNodes().toString(",") + " - " + C.DARK_GREEN + i.getDescription());
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
@ -1,38 +0,0 @@
|
||||
package ninja.bytecode.iris.command;
|
||||
|
||||
import org.bukkit.Chunk;
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
import mortar.api.nms.NMP;
|
||||
import mortar.bukkit.command.MortarCommand;
|
||||
import mortar.bukkit.command.MortarSender;
|
||||
|
||||
public class CommandReloadChunks extends MortarCommand
|
||||
{
|
||||
public CommandReloadChunks()
|
||||
{
|
||||
super("chunks", "c");
|
||||
setDescription("Resends chunk packets.");
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean handle(MortarSender sender, String[] args)
|
||||
{
|
||||
|
||||
if(!sender.isPlayer())
|
||||
{
|
||||
sender.sendMessage("Again, You don't have a position. Stop it.");
|
||||
}
|
||||
|
||||
sender.sendMessage("Resending Chunks in your view distance.");
|
||||
Player p = sender.player();
|
||||
|
||||
for(Chunk i : p.getWorld().getLoadedChunks())
|
||||
{
|
||||
NMP.CHUNK.refreshIgnorePosition(p, i);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
@ -1,23 +0,0 @@
|
||||
package ninja.bytecode.iris.command;
|
||||
|
||||
import mortar.bukkit.command.MortarCommand;
|
||||
import mortar.bukkit.command.MortarSender;
|
||||
import ninja.bytecode.iris.Iris;
|
||||
|
||||
public class CommandReloadIris extends MortarCommand
|
||||
{
|
||||
public CommandReloadIris()
|
||||
{
|
||||
super("iris", "i");
|
||||
setDescription("Reloads Iris");
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean handle(MortarSender sender, String[] args)
|
||||
{
|
||||
Iris.instance.reload();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
@ -1,142 +0,0 @@
|
||||
package ninja.bytecode.iris.command;
|
||||
|
||||
import java.util.function.Consumer;
|
||||
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.World;
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
import mortar.api.sched.J;
|
||||
import mortar.bukkit.command.MortarCommand;
|
||||
import mortar.bukkit.command.MortarSender;
|
||||
import mortar.logic.queue.ChronoLatch;
|
||||
import ninja.bytecode.iris.Iris;
|
||||
import ninja.bytecode.iris.controller.PackController;
|
||||
import ninja.bytecode.iris.generator.IrisGenerator;
|
||||
import ninja.bytecode.iris.generator.WorldReactor;
|
||||
import ninja.bytecode.iris.pack.CompiledDimension;
|
||||
import ninja.bytecode.shuriken.collections.KList;
|
||||
import ninja.bytecode.shuriken.collections.KMap;
|
||||
import ninja.bytecode.shuriken.format.Form;
|
||||
import ninja.bytecode.shuriken.logging.L;
|
||||
|
||||
public class CommandReloadPack extends MortarCommand
|
||||
{
|
||||
public CommandReloadPack()
|
||||
{
|
||||
super("pack", "p");
|
||||
setDescription("Reloads the pack + regen");
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean handle(MortarSender sender, String[] args)
|
||||
{
|
||||
sender.sendMessage("=== Hotloading Pack ===");
|
||||
PackController c = Iris.pack();
|
||||
KMap<String, String> f = new KMap<>();
|
||||
|
||||
for(World i : Bukkit.getWorlds())
|
||||
{
|
||||
if(i.getGenerator() instanceof IrisGenerator)
|
||||
{
|
||||
String n = ((IrisGenerator) i.getGenerator()).getDimension().getName();
|
||||
sender.sendMessage("Preparing " + n);
|
||||
f.put(i.getName(), n);
|
||||
}
|
||||
}
|
||||
|
||||
if(f.isEmpty())
|
||||
{
|
||||
sender.sendMessage("No Worlds to inject!");
|
||||
return true;
|
||||
}
|
||||
|
||||
J.a(() ->
|
||||
{
|
||||
try
|
||||
{
|
||||
Consumer<String> m = (msg) ->
|
||||
{
|
||||
J.s(() ->
|
||||
{
|
||||
String mm = msg;
|
||||
|
||||
if(msg.contains("|"))
|
||||
{
|
||||
KList<String> fx = new KList<>();
|
||||
fx.add(msg.split("\\Q|\\E"));
|
||||
fx.remove(0);
|
||||
fx.remove(0);
|
||||
mm = fx.toString("");
|
||||
}
|
||||
|
||||
sender.sendMessage(mm.replaceAll("\\Q \\E", ""));
|
||||
});
|
||||
};
|
||||
|
||||
L.addLogConsumer(m);
|
||||
c.compile();
|
||||
L.logConsumers.remove(m);
|
||||
|
||||
J.s(() ->
|
||||
{
|
||||
if(sender.isPlayer())
|
||||
{
|
||||
ChronoLatch cl = new ChronoLatch(3000);
|
||||
Player p = sender.player();
|
||||
World ww = sender.player().getWorld();
|
||||
|
||||
sender.sendMessage("Regenerating View Distance");
|
||||
|
||||
WorldReactor r = new WorldReactor(ww);
|
||||
r.generateRegionNormal(p, true, 200, (pct) ->
|
||||
{
|
||||
if(cl.flip())
|
||||
{
|
||||
sender.sendMessage("Regenerating " + Form.pc(pct));
|
||||
}
|
||||
}, () ->
|
||||
{
|
||||
sender.sendMessage("Done! Use F3 + A");
|
||||
});
|
||||
}
|
||||
}, 5);
|
||||
|
||||
for(String fi : f.k())
|
||||
{
|
||||
J.s(() ->
|
||||
{
|
||||
World i = Bukkit.getWorld(fi);
|
||||
CompiledDimension dim = c.getDimension(f.get(fi));
|
||||
|
||||
for(String k : c.getDimensions().k())
|
||||
{
|
||||
if(c.getDimension(k).getName().equals(f.get(fi)))
|
||||
{
|
||||
dim = c.getDimension(k);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if(dim == null)
|
||||
{
|
||||
J.s(() -> sender.sendMessage("Cannot find dimnension: " + f.get(fi)));
|
||||
return;
|
||||
}
|
||||
sender.sendMessage("Hotloaded " + i.getName());
|
||||
IrisGenerator g = ((IrisGenerator) i.getGenerator());
|
||||
g.inject(dim);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
catch(Throwable e)
|
||||
{
|
||||
e.printStackTrace();
|
||||
}
|
||||
});
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
@ -1,42 +0,0 @@
|
||||
package ninja.bytecode.iris.command;
|
||||
|
||||
import mortar.bukkit.command.Command;
|
||||
import mortar.bukkit.command.MortarCommand;
|
||||
import mortar.bukkit.command.MortarSender;
|
||||
import mortar.util.text.C;
|
||||
|
||||
public class CommandSelection extends MortarCommand
|
||||
{
|
||||
@Command
|
||||
private CommandSelectionExpand expand;
|
||||
|
||||
@Command
|
||||
private CommandSelectionShift shift;
|
||||
|
||||
@Command
|
||||
private CommandSelectionShrink shr;
|
||||
|
||||
@Command
|
||||
private CommandSelectionXUp xip;
|
||||
|
||||
@Command
|
||||
private CommandSelectionXVert xvc;
|
||||
|
||||
public CommandSelection()
|
||||
{
|
||||
super("selection", "sel", "s");
|
||||
setDescription("Wand Selection Subcommands");
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean handle(MortarSender sender, String[] args)
|
||||
{
|
||||
for(MortarCommand i : getChildren())
|
||||
{
|
||||
sender.sendMessage("/iris sel " + C.WHITE + i.getNode() + C.GRAY + (!i.getNodes().isEmpty() ? "," : "") + i.getNodes().toString(",") + " - " + C.DARK_GREEN + i.getDescription());
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
@ -1,60 +0,0 @@
|
||||
package ninja.bytecode.iris.command;
|
||||
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.Sound;
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
import mortar.bukkit.command.MortarCommand;
|
||||
import mortar.bukkit.command.MortarSender;
|
||||
import ninja.bytecode.iris.controller.WandController;
|
||||
import ninja.bytecode.iris.util.Cuboid;
|
||||
import ninja.bytecode.iris.util.Direction;
|
||||
|
||||
public class CommandSelectionExpand extends MortarCommand
|
||||
{
|
||||
public CommandSelectionExpand()
|
||||
{
|
||||
super("expand", "+");
|
||||
setDescription("Expand in looking direction");
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean handle(MortarSender sender, String[] args)
|
||||
{
|
||||
if(!sender.isPlayer())
|
||||
{
|
||||
sender.sendMessage("Players Only");
|
||||
return true;
|
||||
}
|
||||
|
||||
Player p = sender.player();
|
||||
|
||||
if(!WandController.isWand(p))
|
||||
{
|
||||
sender.sendMessage("Ready your Wand.");
|
||||
return true;
|
||||
}
|
||||
|
||||
if(args.length == 0)
|
||||
{
|
||||
sender.sendMessage("/iris selection expand <amount>");
|
||||
return true;
|
||||
}
|
||||
|
||||
int amt = Integer.valueOf(args[0]);
|
||||
Location[] b = WandController.getCuboid(p.getInventory().getItemInMainHand());
|
||||
Location a1 = b[0].clone();
|
||||
Location a2 = b[1].clone();
|
||||
Cuboid cursor = new Cuboid(a1, a2);
|
||||
Direction d = Direction.closest(p.getLocation().getDirection()).reverse();
|
||||
cursor = cursor.expand(d, amt);
|
||||
b[0] = cursor.getLowerNE();
|
||||
b[1] = cursor.getUpperSW();
|
||||
p.getInventory().setItemInMainHand(WandController.createWand(b[0], b[1]));
|
||||
p.updateInventory();
|
||||
p.playSound(p.getLocation(), Sound.ENTITY_ITEMFRAME_ROTATE_ITEM, 1f, 0.55f);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
@ -1,61 +0,0 @@
|
||||
package ninja.bytecode.iris.command;
|
||||
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.Sound;
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
import mortar.bukkit.command.MortarCommand;
|
||||
import mortar.bukkit.command.MortarSender;
|
||||
import ninja.bytecode.iris.controller.WandController;
|
||||
import ninja.bytecode.iris.util.Cuboid;
|
||||
import ninja.bytecode.iris.util.Direction;
|
||||
|
||||
public class CommandSelectionShift extends MortarCommand
|
||||
{
|
||||
public CommandSelectionShift()
|
||||
{
|
||||
super("shift", ">");
|
||||
setDescription("Shift looking direction");
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean handle(MortarSender sender, String[] args)
|
||||
{
|
||||
if(!sender.isPlayer())
|
||||
{
|
||||
sender.sendMessage("Players Only");
|
||||
return true;
|
||||
}
|
||||
|
||||
Player p = sender.player();
|
||||
|
||||
if(!WandController.isWand(p))
|
||||
{
|
||||
sender.sendMessage("Ready your Wand.");
|
||||
return true;
|
||||
}
|
||||
|
||||
if(args.length == 0)
|
||||
{
|
||||
sender.sendMessage("/iris selection shift <amount>");
|
||||
return true;
|
||||
}
|
||||
|
||||
int amt = Integer.valueOf(args[0]);
|
||||
Location[] b = WandController.getCuboid(p.getInventory().getItemInMainHand());
|
||||
Location a1 = b[0].clone();
|
||||
Location a2 = b[1].clone();
|
||||
Direction d = Direction.closest(p.getLocation().getDirection()).reverse();
|
||||
a1.add(d.toVector().multiply(amt));
|
||||
a2.add(d.toVector().multiply(amt));
|
||||
Cuboid cursor = new Cuboid(a1, a2);
|
||||
b[0] = cursor.getLowerNE();
|
||||
b[1] = cursor.getUpperSW();
|
||||
p.getInventory().setItemInMainHand(WandController.createWand(b[0], b[1]));
|
||||
p.updateInventory();
|
||||
p.playSound(p.getLocation(), Sound.ENTITY_ITEMFRAME_ROTATE_ITEM, 1f, 0.55f);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
@ -1,57 +0,0 @@
|
||||
package ninja.bytecode.iris.command;
|
||||
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.Sound;
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
import mortar.bukkit.command.MortarCommand;
|
||||
import mortar.bukkit.command.MortarSender;
|
||||
import ninja.bytecode.iris.controller.WandController;
|
||||
import ninja.bytecode.iris.util.Cuboid;
|
||||
import ninja.bytecode.iris.util.Cuboid.CuboidDirection;
|
||||
|
||||
public class CommandSelectionShrink extends MortarCommand
|
||||
{
|
||||
public CommandSelectionShrink()
|
||||
{
|
||||
super("shrinkwrap", "shrink");
|
||||
setDescription("Match blocks boundary");
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean handle(MortarSender sender, String[] args)
|
||||
{
|
||||
if(!sender.isPlayer())
|
||||
{
|
||||
sender.sendMessage("Players Only");
|
||||
return true;
|
||||
}
|
||||
|
||||
Player p = sender.player();
|
||||
|
||||
if(!WandController.isWand(p))
|
||||
{
|
||||
sender.sendMessage("Ready your Wand.");
|
||||
return true;
|
||||
}
|
||||
|
||||
Location[] b = WandController.getCuboid(p.getInventory().getItemInMainHand());
|
||||
Location a1 = b[0].clone();
|
||||
Location a2 = b[1].clone();
|
||||
Cuboid cursor = new Cuboid(a1, a2);
|
||||
cursor = cursor.contract(CuboidDirection.North);
|
||||
cursor = cursor.contract(CuboidDirection.South);
|
||||
cursor = cursor.contract(CuboidDirection.East);
|
||||
cursor = cursor.contract(CuboidDirection.West);
|
||||
cursor = cursor.contract(CuboidDirection.Up);
|
||||
cursor = cursor.contract(CuboidDirection.Down);
|
||||
b[0] = cursor.getLowerNE();
|
||||
b[1] = cursor.getUpperSW();
|
||||
p.getInventory().setItemInMainHand(WandController.createWand(b[0], b[1]));
|
||||
p.updateInventory();
|
||||
p.playSound(p.getLocation(), Sound.ENTITY_ITEMFRAME_ROTATE_ITEM, 1f, 0.55f);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
@ -1,72 +0,0 @@
|
||||
package ninja.bytecode.iris.command;
|
||||
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.Sound;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.util.Vector;
|
||||
|
||||
import mortar.bukkit.command.MortarCommand;
|
||||
import mortar.bukkit.command.MortarSender;
|
||||
import ninja.bytecode.iris.controller.WandController;
|
||||
import ninja.bytecode.iris.util.Cuboid;
|
||||
import ninja.bytecode.iris.util.Cuboid.CuboidDirection;
|
||||
|
||||
public class CommandSelectionXUp extends MortarCommand
|
||||
{
|
||||
public CommandSelectionXUp()
|
||||
{
|
||||
super("expandup", "xup");
|
||||
setDescription("Expand Up & Trim In");
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean handle(MortarSender sender, String[] args)
|
||||
{
|
||||
if(!sender.isPlayer())
|
||||
{
|
||||
sender.sendMessage("Players Only");
|
||||
return true;
|
||||
}
|
||||
|
||||
Player p = sender.player();
|
||||
|
||||
if(!WandController.isWand(p))
|
||||
{
|
||||
sender.sendMessage("Ready your Wand.");
|
||||
return true;
|
||||
}
|
||||
|
||||
Location[] b = WandController.getCuboid(p.getInventory().getItemInMainHand());
|
||||
b[0].add(new Vector(0, 1, 0));
|
||||
b[1].add(new Vector(0, 1, 0));
|
||||
Location a1 = b[0].clone();
|
||||
Location a2 = b[1].clone();
|
||||
Cuboid cursor = new Cuboid(a1, a2);
|
||||
|
||||
while(!cursor.containsOnly(Material.AIR))
|
||||
{
|
||||
a1.add(new Vector(0, 1, 0));
|
||||
a2.add(new Vector(0, 1, 0));
|
||||
cursor = new Cuboid(a1, a2);
|
||||
}
|
||||
|
||||
a1.add(new Vector(0, -1, 0));
|
||||
a2.add(new Vector(0, -1, 0));
|
||||
b[0] = a1;
|
||||
a2 = b[1];
|
||||
cursor = new Cuboid(a1, a2);
|
||||
cursor = cursor.contract(CuboidDirection.North);
|
||||
cursor = cursor.contract(CuboidDirection.South);
|
||||
cursor = cursor.contract(CuboidDirection.East);
|
||||
cursor = cursor.contract(CuboidDirection.West);
|
||||
b[0] = cursor.getLowerNE();
|
||||
b[1] = cursor.getUpperSW();
|
||||
p.getInventory().setItemInMainHand(WandController.createWand(b[0], b[1]));
|
||||
p.updateInventory();
|
||||
p.playSound(p.getLocation(), Sound.ENTITY_ITEMFRAME_ROTATE_ITEM, 1f, 0.55f);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
@ -1,83 +0,0 @@
|
||||
package ninja.bytecode.iris.command;
|
||||
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.Sound;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.util.Vector;
|
||||
|
||||
import mortar.bukkit.command.MortarCommand;
|
||||
import mortar.bukkit.command.MortarSender;
|
||||
import ninja.bytecode.iris.controller.WandController;
|
||||
import ninja.bytecode.iris.util.Cuboid;
|
||||
import ninja.bytecode.iris.util.Cuboid.CuboidDirection;
|
||||
|
||||
public class CommandSelectionXVert extends MortarCommand
|
||||
{
|
||||
public CommandSelectionXVert()
|
||||
{
|
||||
super("expandvertical", "xvert");
|
||||
setDescription("Expand Up + Down & Trim In");
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean handle(MortarSender sender, String[] args)
|
||||
{
|
||||
if(!sender.isPlayer())
|
||||
{
|
||||
sender.sendMessage("Players Only");
|
||||
return true;
|
||||
}
|
||||
|
||||
Player p = sender.player();
|
||||
|
||||
if(!WandController.isWand(p))
|
||||
{
|
||||
sender.sendMessage("Ready your Wand.");
|
||||
return true;
|
||||
}
|
||||
|
||||
Location[] b = WandController.getCuboid(p.getInventory().getItemInMainHand());
|
||||
Location a1 = b[0].clone();
|
||||
Location a2 = b[1].clone();
|
||||
Location a1x = b[0].clone();
|
||||
Location a2x = b[1].clone();
|
||||
Cuboid cursor = new Cuboid(a1, a2);
|
||||
Cuboid cursorx = new Cuboid(a1, a2);
|
||||
|
||||
while(!cursor.containsOnly(Material.AIR))
|
||||
{
|
||||
a1.add(new Vector(0, 1, 0));
|
||||
a2.add(new Vector(0, 1, 0));
|
||||
cursor = new Cuboid(a1, a2);
|
||||
}
|
||||
|
||||
a1.add(new Vector(0, -1, 0));
|
||||
a2.add(new Vector(0, -1, 0));
|
||||
|
||||
while(!cursorx.containsOnly(Material.AIR))
|
||||
{
|
||||
a1x.add(new Vector(0, -1, 0));
|
||||
a2x.add(new Vector(0, -1, 0));
|
||||
cursorx = new Cuboid(a1x, a2x);
|
||||
}
|
||||
|
||||
a1x.add(new Vector(0, 1, 0));
|
||||
a2x.add(new Vector(0, 1, 0));
|
||||
b[0] = a1;
|
||||
b[1] = a2x;
|
||||
cursor = new Cuboid(b[0], b[1]);
|
||||
cursor = cursor.contract(CuboidDirection.North);
|
||||
cursor = cursor.contract(CuboidDirection.South);
|
||||
cursor = cursor.contract(CuboidDirection.East);
|
||||
cursor = cursor.contract(CuboidDirection.West);
|
||||
b[0] = cursor.getLowerNE();
|
||||
b[1] = cursor.getUpperSW();
|
||||
p.getInventory().setItemInMainHand(WandController.createWand(b[0], b[1]));
|
||||
p.updateInventory();
|
||||
p.playSound(p.getLocation(), Sound.ENTITY_ITEMFRAME_ROTATE_ITEM, 1f, 0.55f);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
@ -1,57 +0,0 @@
|
||||
package ninja.bytecode.iris.command;
|
||||
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.World;
|
||||
|
||||
import mortar.bukkit.command.MortarCommand;
|
||||
import mortar.bukkit.command.MortarSender;
|
||||
import mortar.util.text.C;
|
||||
import ninja.bytecode.iris.Iris;
|
||||
import ninja.bytecode.iris.generator.IrisGenerator;
|
||||
|
||||
public class CommandTimings extends MortarCommand
|
||||
{
|
||||
public CommandTimings()
|
||||
{
|
||||
super("timings", "t");
|
||||
setDescription("Tick use on a per chunk basis");
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean handle(MortarSender sender, String[] args)
|
||||
{
|
||||
World world = null;
|
||||
|
||||
if(sender.isPlayer() && Iris.isGen(sender.player().getWorld()))
|
||||
{
|
||||
world = sender.player().getWorld();
|
||||
}
|
||||
|
||||
else if(args.length >= 1)
|
||||
{
|
||||
World t = Bukkit.getWorld(args[0]);
|
||||
|
||||
if(t == null)
|
||||
{
|
||||
sender.sendMessage("Unknown world " + args[0]);
|
||||
return true;
|
||||
}
|
||||
|
||||
else if(t.getGenerator() instanceof IrisGenerator)
|
||||
{
|
||||
world = t;
|
||||
}
|
||||
}
|
||||
|
||||
else
|
||||
{
|
||||
sender.sendMessage("Console / Non-Iris World. " + C.WHITE + "Use /iris timings <world>");
|
||||
return true;
|
||||
}
|
||||
|
||||
Iris.getGen(world).getMetrics().send(sender, (m) -> sender.sendMessage(m));
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
@ -1,36 +0,0 @@
|
||||
package ninja.bytecode.iris.command;
|
||||
|
||||
import mortar.bukkit.command.Command;
|
||||
import mortar.bukkit.command.MortarCommand;
|
||||
import mortar.bukkit.command.MortarSender;
|
||||
import mortar.util.text.C;
|
||||
|
||||
public class CommandWhat extends MortarCommand
|
||||
{
|
||||
@Command
|
||||
private CommandWhatBiome wBiome;
|
||||
|
||||
@Command
|
||||
private CommandWhatObject wObject;
|
||||
|
||||
@Command
|
||||
private CommandWhatBlock wBlock;
|
||||
|
||||
public CommandWhat()
|
||||
{
|
||||
super("what", "w");
|
||||
setDescription("Identify what you are looking at.");
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean handle(MortarSender sender, String[] args)
|
||||
{
|
||||
for(MortarCommand i : getChildren())
|
||||
{
|
||||
sender.sendMessage("/iris what " + C.WHITE + i.getNode() + C.GRAY + (!i.getNodes().isEmpty() ? "," : "") + i.getNodes().toString(",") + " - " + C.DARK_GREEN + i.getDescription());
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
@ -1,66 +0,0 @@
|
||||
package ninja.bytecode.iris.command;
|
||||
|
||||
import org.bukkit.World;
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
import mortar.bukkit.command.MortarCommand;
|
||||
import mortar.bukkit.command.MortarSender;
|
||||
import mortar.util.text.C;
|
||||
import ninja.bytecode.iris.Iris;
|
||||
import ninja.bytecode.iris.generator.IrisGenerator;
|
||||
import ninja.bytecode.iris.pack.IrisBiome;
|
||||
import ninja.bytecode.iris.util.BiomeLayer;
|
||||
import ninja.bytecode.shuriken.format.Form;
|
||||
|
||||
public class CommandWhatBiome extends MortarCommand
|
||||
{
|
||||
public CommandWhatBiome()
|
||||
{
|
||||
super("biome", "b");
|
||||
setDescription("Identify Current Biome");
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean handle(MortarSender sender, String[] args)
|
||||
{
|
||||
World world = null;
|
||||
|
||||
if(sender.isPlayer() && Iris.isGen(sender.player().getWorld()))
|
||||
{
|
||||
world = sender.player().getWorld();
|
||||
}
|
||||
|
||||
else
|
||||
{
|
||||
sender.sendMessage("Console / Non-Iris World.");
|
||||
return true;
|
||||
}
|
||||
|
||||
Player p = sender.player();
|
||||
IrisGenerator g = Iris.getGen(world);
|
||||
IrisBiome biome = g.getBiome((int) g.getOffsetX(p.getLocation().getX(), p.getLocation().getZ()), (int) g.getOffsetZ(p.getLocation().getX(), p.getLocation().getZ()));
|
||||
BiomeLayer l = new BiomeLayer(g, biome);
|
||||
sender.sendMessage("Biome: " + C.BOLD + C.WHITE + biome.getName() + C.RESET + C.GRAY + " (" + C.GOLD + l.getBiome().getRarityString() + C.GRAY + ")");
|
||||
|
||||
for(String i : biome.getSchematicGroups().k())
|
||||
{
|
||||
String f = "";
|
||||
double percent = biome.getSchematicGroups().get(i);
|
||||
|
||||
if(percent > 1D)
|
||||
{
|
||||
f = (int) percent + " + " + Form.pc(percent - (int) percent, percent - (int) percent >= 0.01 ? 0 : 3);
|
||||
}
|
||||
|
||||
else
|
||||
{
|
||||
f = Form.pc(percent, percent >= 0.01 ? 0 : 3);
|
||||
}
|
||||
|
||||
sender.sendMessage("* " + C.DARK_GREEN + i + ": " + C.BOLD + C.WHITE + f + C.RESET + C.GRAY + " (" + Form.f(g.getDimension().getObjectGroup(i).size()) + " variants)");
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
@ -1,33 +0,0 @@
|
||||
package ninja.bytecode.iris.command;
|
||||
|
||||
import org.bukkit.block.Block;
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
import mortar.bukkit.command.MortarCommand;
|
||||
import mortar.bukkit.command.MortarSender;
|
||||
|
||||
public class CommandWhatBlock extends MortarCommand
|
||||
{
|
||||
public CommandWhatBlock()
|
||||
{
|
||||
super("block", "id", "i");
|
||||
setDescription("Identify Current Block Looking at");
|
||||
}
|
||||
|
||||
@SuppressWarnings("deprecation")
|
||||
@Override
|
||||
public boolean handle(MortarSender sender, String[] args)
|
||||
{
|
||||
if(!sender.isPlayer())
|
||||
{
|
||||
sender.sendMessage("Not sure where you are looking.");
|
||||
}
|
||||
|
||||
Player p = sender.player();
|
||||
Block b = p.getTargetBlock(null, 64);
|
||||
sender.sendMessage(b.getType().getId() + ":" + b.getData() + " (" + b.getType().toString() + ":" + b.getData() + ")");
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
@ -1,165 +0,0 @@
|
||||
package ninja.bytecode.iris.command;
|
||||
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.World;
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
import mortar.api.sched.SR;
|
||||
import mortar.bukkit.command.MortarCommand;
|
||||
import mortar.bukkit.command.MortarSender;
|
||||
import mortar.lang.collection.FinalInteger;
|
||||
import mortar.util.text.C;
|
||||
import ninja.bytecode.iris.Iris;
|
||||
import ninja.bytecode.iris.generator.IrisGenerator;
|
||||
import ninja.bytecode.iris.generator.genobject.GenObject;
|
||||
import ninja.bytecode.iris.generator.genobject.GenObjectGroup;
|
||||
import ninja.bytecode.iris.generator.genobject.PlacedObject;
|
||||
import ninja.bytecode.iris.pack.IrisBiome;
|
||||
import ninja.bytecode.shuriken.collections.KMap;
|
||||
import ninja.bytecode.shuriken.format.Form;
|
||||
|
||||
public class CommandWhatObject extends MortarCommand
|
||||
{
|
||||
private KMap<String, GenObject> goc;
|
||||
private KMap<String, GenObjectGroup> gog;
|
||||
|
||||
public CommandWhatObject()
|
||||
{
|
||||
super("object", "o");
|
||||
setDescription("WAYLA For Objects");
|
||||
goc = new KMap<>();
|
||||
gog = new KMap<>();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean handle(MortarSender sender, String[] args)
|
||||
{
|
||||
World world = null;
|
||||
|
||||
if(sender.isPlayer() && Iris.isGen(sender.player().getWorld()))
|
||||
{
|
||||
world = sender.player().getWorld();
|
||||
}
|
||||
|
||||
else
|
||||
{
|
||||
sender.sendMessage("Console / Non-Iris World.");
|
||||
return true;
|
||||
}
|
||||
|
||||
Player p = sender.player();
|
||||
IrisGenerator generator = Iris.getGen(world);
|
||||
Location l = p.getTargetBlock(null, 32).getLocation();
|
||||
PlacedObject po = generator.nearest(l, 12);
|
||||
|
||||
if(po != null)
|
||||
{
|
||||
if(!goc.containsKey(po.getF()))
|
||||
{
|
||||
String root = po.getF().split("\\Q:\\E")[0];
|
||||
String n = po.getF().split("\\Q:\\E")[1];
|
||||
GenObjectGroup gg = generator.getDimension().getObjectGroup(root);
|
||||
gog.put(root, gg);
|
||||
|
||||
for(GenObject i : gg.getSchematics())
|
||||
{
|
||||
if(i.getName().equals(n))
|
||||
{
|
||||
goc.put(po.getF(), i);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if(!goc.containsKey(po.getF()))
|
||||
{
|
||||
goc.put(po.getF(), new GenObject(0, 0, 0));
|
||||
}
|
||||
}
|
||||
|
||||
GenObjectGroup ggg = gog.get(po.getF().split("\\Q:\\E")[0]);
|
||||
GenObject g = goc.get(po.getF());
|
||||
|
||||
if(g != null)
|
||||
{
|
||||
Location point = new Location(l.getWorld(), po.getX(), po.getY(), po.getZ());
|
||||
IrisBiome biome = generator.getBiome((int) generator.getOffsetX(po.getX(), po.getZ()), (int) generator.getOffsetZ(po.getX(), po.getZ()));
|
||||
String gg = po.getF().split("\\Q:\\E")[0];
|
||||
|
||||
p.sendMessage(C.DARK_GREEN + C.BOLD.toString() + gg + C.GRAY + "/" + C.RESET + C.ITALIC + C.GRAY + g.getName() + C.RESET + C.WHITE + " (1 of " + Form.f(generator.getDimension().getObjectGroup(gg).size()) + " variants)");
|
||||
|
||||
if(biome.getSchematicGroups().containsKey(gg))
|
||||
{
|
||||
String f = "";
|
||||
double percent = biome.getSchematicGroups().get(gg);
|
||||
|
||||
if(percent > 1D)
|
||||
{
|
||||
f = (int) percent + " + " + Form.pc(percent - (int) percent, percent - (int) percent >= 0.01 ? 0 : 3);
|
||||
}
|
||||
|
||||
else
|
||||
{
|
||||
f = Form.pc(percent, percent >= 0.01 ? 0 : 3);
|
||||
}
|
||||
|
||||
p.sendMessage(C.GOLD + "Spawn Chance in " + C.YELLOW + biome.getName() + C.RESET + ": " + C.BOLD + C.WHITE + f);
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
int a = 0;
|
||||
int b = 0;
|
||||
double c = 0;
|
||||
|
||||
for(GenObject i : ggg.getSchematics())
|
||||
{
|
||||
a += i.getSuccesses();
|
||||
b += i.getPlaces();
|
||||
}
|
||||
|
||||
c = ((double) a / (double) b);
|
||||
p.sendMessage(C.GRAY + "Grp: " + C.DARK_AQUA + Form.f(a) + C.GRAY + " of " + C.AQUA + Form.f(b) + C.GRAY + " placements (" + C.DARK_AQUA + Form.pc(c, 0) + C.GRAY + ")");
|
||||
}
|
||||
|
||||
catch(Throwable e)
|
||||
{
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
p.sendMessage(C.GRAY + "Var: " + C.DARK_AQUA + Form.f(g.getSuccesses()) + C.GRAY + " of " + C.AQUA + Form.f(g.getPlaces()) + C.GRAY + " placements (" + C.DARK_AQUA + Form.pc(g.getSuccess(), 0) + C.GRAY + ")");
|
||||
|
||||
for(String i : ggg.getFlags())
|
||||
{
|
||||
p.sendMessage(C.GRAY + "- " + C.DARK_PURPLE + i);
|
||||
}
|
||||
|
||||
FinalInteger fi = new FinalInteger(125);
|
||||
|
||||
new SR()
|
||||
{
|
||||
@Override
|
||||
public void run()
|
||||
{
|
||||
if(point.distanceSquared(p.getLocation()) > 64 * 64)
|
||||
{
|
||||
cancel();
|
||||
}
|
||||
|
||||
fi.sub(1);
|
||||
Iris.wand().draw(new Location[] {point.clone().add(g.getW() / 2, g.getH() / 2, g.getD() / 2), point.clone().subtract(g.getW() / 2, g.getH() / 2, g.getD() / 2)
|
||||
}, p);
|
||||
|
||||
if(fi.get() <= 0)
|
||||
{
|
||||
cancel();
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
@ -1,64 +0,0 @@
|
||||
package ninja.bytecode.iris.controller;
|
||||
|
||||
import org.bukkit.World;
|
||||
|
||||
import ninja.bytecode.iris.Iris;
|
||||
import ninja.bytecode.shuriken.collections.KMap;
|
||||
import ninja.bytecode.shuriken.execution.TaskExecutor;
|
||||
|
||||
public class ExecutionController
|
||||
{
|
||||
KMap<String, TaskExecutor> executors;
|
||||
|
||||
public void start()
|
||||
{
|
||||
executors = new KMap<>();
|
||||
}
|
||||
|
||||
public void stop()
|
||||
{
|
||||
for(TaskExecutor i : executors.v())
|
||||
{
|
||||
i.close();
|
||||
}
|
||||
|
||||
executors.clear();
|
||||
}
|
||||
|
||||
public TaskExecutor getExecutor(World world, String f)
|
||||
{
|
||||
String k = world.getWorldFolder().getAbsolutePath() + " (" + world + ") " + f;
|
||||
|
||||
if(executors.containsKey(k))
|
||||
{
|
||||
return executors.get(k);
|
||||
}
|
||||
|
||||
TaskExecutor x = new TaskExecutor(getTC(), Iris.settings.performance.threadPriority, "Iris " + f);
|
||||
executors.put(k, x);
|
||||
return x;
|
||||
}
|
||||
|
||||
public int getTC()
|
||||
{
|
||||
switch(Iris.settings.performance.performanceMode)
|
||||
{
|
||||
case HALF_CPU:
|
||||
return Math.max(Runtime.getRuntime().availableProcessors() / 2, 1);
|
||||
case MATCH_CPU:
|
||||
return Runtime.getRuntime().availableProcessors();
|
||||
case SINGLE_THREADED:
|
||||
return 1;
|
||||
case DOUBLE_CPU:
|
||||
return Runtime.getRuntime().availableProcessors() * 2;
|
||||
case UNLIMITED:
|
||||
return -1;
|
||||
case EXPLICIT:
|
||||
return Iris.settings.performance.threadCount;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return Math.max(Runtime.getRuntime().availableProcessors() / 2, 1);
|
||||
}
|
||||
}
|
@ -1,358 +0,0 @@
|
||||
package ninja.bytecode.iris.controller;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
|
||||
import mortar.bukkit.plugin.Controller;
|
||||
import net.md_5.bungee.api.ChatColor;
|
||||
import ninja.bytecode.iris.Iris;
|
||||
import ninja.bytecode.iris.generator.genobject.GenObject;
|
||||
import ninja.bytecode.iris.generator.genobject.GenObjectGroup;
|
||||
import ninja.bytecode.iris.pack.CompiledDimension;
|
||||
import ninja.bytecode.iris.pack.IrisBiome;
|
||||
import ninja.bytecode.iris.pack.IrisDimension;
|
||||
import ninja.bytecode.iris.pack.IrisPack;
|
||||
import ninja.bytecode.shuriken.bench.PrecisionStopwatch;
|
||||
import ninja.bytecode.shuriken.collections.KList;
|
||||
import ninja.bytecode.shuriken.collections.KMap;
|
||||
import ninja.bytecode.shuriken.execution.J;
|
||||
import ninja.bytecode.shuriken.format.Form;
|
||||
import ninja.bytecode.shuriken.io.IO;
|
||||
import ninja.bytecode.shuriken.json.JSONException;
|
||||
import ninja.bytecode.shuriken.json.JSONObject;
|
||||
import ninja.bytecode.shuriken.logging.L;
|
||||
|
||||
public class PackController extends Controller
|
||||
{
|
||||
private KMap<String, CompiledDimension> compiledDimensions;
|
||||
private KMap<String, IrisDimension> dimensions;
|
||||
private KMap<String, IrisBiome> biomes;
|
||||
private KMap<String, GenObjectGroup> genObjectGroups;
|
||||
private boolean ready;
|
||||
|
||||
@Override
|
||||
public void start()
|
||||
{
|
||||
compiledDimensions = new KMap<>();
|
||||
dimensions = new KMap<>();
|
||||
biomes = new KMap<>();
|
||||
genObjectGroups = new KMap<>();
|
||||
ready = false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void stop()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void tick()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
public boolean isReady()
|
||||
{
|
||||
return ready;
|
||||
}
|
||||
|
||||
public KList<File> getFiles(File folder)
|
||||
{
|
||||
KList<File> buf = new KList<File>();
|
||||
|
||||
if(!folder.exists())
|
||||
{
|
||||
return buf;
|
||||
}
|
||||
|
||||
if(folder.isDirectory())
|
||||
{
|
||||
for(File i : folder.listFiles())
|
||||
{
|
||||
if(i.isFile())
|
||||
{
|
||||
buf.add(i);
|
||||
}
|
||||
|
||||
else if(i.isDirectory())
|
||||
{
|
||||
buf.addAll(getFiles(folder));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return buf;
|
||||
}
|
||||
|
||||
public void compile()
|
||||
{
|
||||
dimensions = new KMap<>();
|
||||
biomes = new KMap<>();
|
||||
genObjectGroups = new KMap<>();
|
||||
ready = false;
|
||||
PrecisionStopwatch p = PrecisionStopwatch.start();
|
||||
File dims = new File(Iris.instance.getDataFolder(), "dimensions");
|
||||
dims.mkdirs();
|
||||
|
||||
try
|
||||
{
|
||||
IrisPack master = new IrisPack(loadJSON("pack/manifest.json"));
|
||||
master.load();
|
||||
}
|
||||
|
||||
catch(Throwable e)
|
||||
{
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
L.v(ChatColor.LIGHT_PURPLE + "Processing Content");
|
||||
|
||||
for(GenObjectGroup i : genObjectGroups.v())
|
||||
{
|
||||
i.processVariants();
|
||||
}
|
||||
|
||||
for(String i : dimensions.k())
|
||||
{
|
||||
IrisDimension id = dimensions.get(i);
|
||||
CompiledDimension d = new CompiledDimension(id);
|
||||
|
||||
for(IrisBiome j : id.getBiomes())
|
||||
{
|
||||
d.registerBiome(j);
|
||||
KList<String> g = j.getSchematicGroups().k();
|
||||
g.sort();
|
||||
|
||||
for(String k : g)
|
||||
{
|
||||
d.registerObject(genObjectGroups.get(k));
|
||||
|
||||
if(j.isLush())
|
||||
{
|
||||
try
|
||||
{
|
||||
GenObjectGroup ggx = genObjectGroups.get(k).copy("-lush-" + j.getLush());
|
||||
ggx.applyLushFilter(j.getLush());
|
||||
d.registerObject(ggx);
|
||||
j.getSchematicGroups().put(ggx.getName(), j.getSchematicGroups().get(k));
|
||||
j.getSchematicGroups().remove(k);
|
||||
}
|
||||
|
||||
catch(Throwable e)
|
||||
{
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
if(j.isSnowy())
|
||||
{
|
||||
try
|
||||
{
|
||||
GenObjectGroup ggx = genObjectGroups.get(k).copy("-snow-" + j.getSnow());
|
||||
ggx.applySnowFilter((int) (j.getSnow() * 4));
|
||||
d.registerObject(ggx);
|
||||
j.getSchematicGroups().put(ggx.getName(), j.getSchematicGroups().get(k));
|
||||
j.getSchematicGroups().remove(k);
|
||||
}
|
||||
|
||||
catch(Throwable e)
|
||||
{
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
d.sort();
|
||||
compiledDimensions.put(i, d);
|
||||
}
|
||||
|
||||
for(String i : compiledDimensions.k())
|
||||
{
|
||||
CompiledDimension d = compiledDimensions.get(i);
|
||||
d.computeObjectSize();
|
||||
L.i(ChatColor.GREEN + i + ChatColor.WHITE + " (" + d.getEnvironment().toString().toLowerCase() + ")");
|
||||
L.i(ChatColor.DARK_GREEN + " Biomes: " + ChatColor.GRAY + Form.f(d.getBiomes().size()));
|
||||
L.i(ChatColor.DARK_GREEN + " Objects: " + ChatColor.GRAY + Form.f(d.countObjects()));
|
||||
L.flush();
|
||||
}
|
||||
|
||||
L.i("");
|
||||
L.i(ChatColor.LIGHT_PURPLE + "Compilation Time: " + ChatColor.WHITE + Form.duration(p.getMilliseconds(), 2));
|
||||
L.i(ChatColor.GREEN + "Iris Dimensions Successfully Compiled!");
|
||||
L.i("");
|
||||
L.flush();
|
||||
|
||||
ready = true;
|
||||
}
|
||||
|
||||
public KMap<String, CompiledDimension> getCompiledDimensions()
|
||||
{
|
||||
return compiledDimensions;
|
||||
}
|
||||
|
||||
public KMap<String, IrisDimension> getDimensions()
|
||||
{
|
||||
return dimensions;
|
||||
}
|
||||
|
||||
public KMap<String, IrisBiome> getBiomes()
|
||||
{
|
||||
return biomes;
|
||||
}
|
||||
|
||||
public KMap<String, GenObjectGroup> getGenObjectGroups()
|
||||
{
|
||||
return genObjectGroups;
|
||||
}
|
||||
|
||||
public CompiledDimension getDimension(String name)
|
||||
{
|
||||
return compiledDimensions.get(name);
|
||||
}
|
||||
|
||||
public IrisDimension loadDimension(String s) throws JSONException, IOException
|
||||
{
|
||||
L.v(ChatColor.GOLD + "Loading Dimension: " + ChatColor.GRAY + "pack/dimensions/" + s + ".json");
|
||||
return new IrisDimension(loadJSON("pack/dimensions/" + s + ".json"));
|
||||
}
|
||||
|
||||
public IrisBiome loadBiome(String s) throws JSONException, IOException
|
||||
{
|
||||
L.v(ChatColor.DARK_GREEN + "Loading Biome: " + ChatColor.GRAY + "pack/biomes/" + s + ".json");
|
||||
return new IrisBiome(loadJSON("pack/biomes/" + s + ".json"));
|
||||
}
|
||||
|
||||
public GenObjectGroup loadSchematicGroup(String s)
|
||||
{
|
||||
GenObjectGroup g = GenObjectGroup.load("pack/objects/" + s);
|
||||
L.v(ChatColor.DARK_AQUA + "Loading Objects: " + ChatColor.GRAY + "pack/objects/" + s + ".ish");
|
||||
|
||||
if(g != null)
|
||||
{
|
||||
genObjectGroups.put(s, g);
|
||||
return g;
|
||||
}
|
||||
|
||||
L.i("Cannot load Object Group: " + s);
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public GenObject loadSchematic(String s) throws IOException
|
||||
{
|
||||
return GenObject.load(loadResource("pack/objects/" + s + ".ish"));
|
||||
}
|
||||
|
||||
public JSONObject loadJSON(String s) throws JSONException, IOException
|
||||
{
|
||||
return new JSONObject(IO.readAll(loadResource(s)));
|
||||
}
|
||||
|
||||
public File loadFolder(String string)
|
||||
{
|
||||
File internal = internalResource(string);
|
||||
|
||||
if(internal.exists())
|
||||
{
|
||||
return internal;
|
||||
}
|
||||
|
||||
L.f(ChatColor.RED + "Cannot find folder: " + internal.getAbsolutePath());
|
||||
return null;
|
||||
}
|
||||
|
||||
public InputStream loadResource(String string) throws IOException
|
||||
{
|
||||
File internal = internalResource(string);
|
||||
|
||||
if(internal.exists())
|
||||
{
|
||||
L.flush();
|
||||
return new FileInputStream(internal);
|
||||
}
|
||||
|
||||
else
|
||||
{
|
||||
L.f(ChatColor.RED + "Cannot find Resource: " + ChatColor.YELLOW + internal.getAbsolutePath());
|
||||
|
||||
if(internal.getName().equals("manifest.json"))
|
||||
{
|
||||
L.f(ChatColor.RED + "Reloading Iris to fix manifest jar issues");
|
||||
Iris.instance.reload();
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
private static File internalResource(String resource)
|
||||
{
|
||||
if(new File(Iris.instance.getDataFolder(), "pack").exists())
|
||||
{
|
||||
return new File(Iris.instance.getDataFolder(), resource);
|
||||
}
|
||||
|
||||
return new File(System.getProperty("java.io.tmpdir") + "/Iris/" + resource);
|
||||
}
|
||||
|
||||
public void registerBiome(String name, IrisBiome biome)
|
||||
{
|
||||
biomes.put(name, biome);
|
||||
}
|
||||
|
||||
public void registerDimension(String i, IrisDimension d)
|
||||
{
|
||||
dimensions.put(i, d);
|
||||
}
|
||||
|
||||
public void invalidate()
|
||||
{
|
||||
J.attempt(() -> new File(Iris.instance.getDataFolder(), "dimensions").delete());
|
||||
compiledDimensions.clear();
|
||||
}
|
||||
|
||||
public IrisBiome getBiomeById(String id)
|
||||
{
|
||||
if(!biomes.containsKey(id))
|
||||
{
|
||||
try
|
||||
{
|
||||
biomes.put(id, ((PackController) Iris.instance.getController(PackController.class)).loadBiome(id));
|
||||
}
|
||||
|
||||
catch(JSONException | IOException e)
|
||||
{
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
return biomes.get(id);
|
||||
}
|
||||
|
||||
public void dispose()
|
||||
{
|
||||
for(GenObjectGroup i : genObjectGroups.values())
|
||||
{
|
||||
i.dispose();
|
||||
}
|
||||
|
||||
for(IrisDimension i : dimensions.values())
|
||||
{
|
||||
i.dispose();
|
||||
}
|
||||
|
||||
for(CompiledDimension i : compiledDimensions.values())
|
||||
{
|
||||
i.dispose();
|
||||
}
|
||||
|
||||
compiledDimensions.clear();
|
||||
dimensions.clear();
|
||||
biomes.clear();
|
||||
genObjectGroups.clear();
|
||||
}
|
||||
}
|
@ -0,0 +1,204 @@
|
||||
package ninja.bytecode.iris.generator;
|
||||
|
||||
import java.util.concurrent.locks.ReentrantLock;
|
||||
|
||||
import org.bukkit.World;
|
||||
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
import ninja.bytecode.iris.Iris;
|
||||
import ninja.bytecode.iris.layer.GenLayerBiome;
|
||||
import ninja.bytecode.iris.object.InferredType;
|
||||
import ninja.bytecode.iris.object.IrisBiome;
|
||||
import ninja.bytecode.iris.object.IrisBiomeGeneratorLink;
|
||||
import ninja.bytecode.iris.object.IrisGenerator;
|
||||
import ninja.bytecode.iris.object.IrisRegion;
|
||||
import ninja.bytecode.iris.util.BiomeResult;
|
||||
import ninja.bytecode.iris.util.CNG;
|
||||
import ninja.bytecode.iris.util.ChronoLatch;
|
||||
import ninja.bytecode.iris.util.ChunkPosition;
|
||||
import ninja.bytecode.iris.util.IrisInterpolation;
|
||||
import ninja.bytecode.iris.util.RNG;
|
||||
import ninja.bytecode.shuriken.collections.KList;
|
||||
import ninja.bytecode.shuriken.collections.KMap;
|
||||
import ninja.bytecode.shuriken.math.M;
|
||||
|
||||
@Data
|
||||
@EqualsAndHashCode(callSuper = false)
|
||||
public abstract class BiomeChunkGenerator extends DimensionChunkGenerator
|
||||
{
|
||||
protected ReentrantLock regLock;
|
||||
protected KMap<String, IrisGenerator> generators;
|
||||
protected GenLayerBiome glBiome;
|
||||
protected CNG masterFracture;
|
||||
protected KMap<ChunkPosition, BiomeResult> biomeHitCache;
|
||||
protected ChronoLatch cwarn = new ChronoLatch(1000);
|
||||
|
||||
public BiomeChunkGenerator(String dimensionName)
|
||||
{
|
||||
super(dimensionName);
|
||||
generators = new KMap<>();
|
||||
regLock = new ReentrantLock();
|
||||
biomeHitCache = new KMap<>();
|
||||
}
|
||||
|
||||
public void onInit(World world, RNG rng)
|
||||
{
|
||||
loadGenerators();
|
||||
glBiome = new GenLayerBiome(this, masterRandom.nextParallelRNG(1));
|
||||
masterFracture = CNG.signature(rng.nextParallelRNG(13)).scale(0.12);
|
||||
}
|
||||
|
||||
public void onHotloaded()
|
||||
{
|
||||
biomeHitCache = new KMap<>();
|
||||
generators.clear();
|
||||
loadGenerators();
|
||||
}
|
||||
|
||||
public void registerGenerator(IrisGenerator g)
|
||||
{
|
||||
regLock.lock();
|
||||
if(g.getLoadKey() == null || generators.containsKey(g.getLoadKey()))
|
||||
{
|
||||
regLock.unlock();
|
||||
return;
|
||||
}
|
||||
|
||||
regLock.unlock();
|
||||
generators.put(g.getLoadKey(), g);
|
||||
}
|
||||
|
||||
protected double getBiomeHeight(double rx, double rz)
|
||||
{
|
||||
double h = 0;
|
||||
|
||||
for(IrisGenerator i : generators.values())
|
||||
{
|
||||
h += interpolateGenerator(rx, rz, i);
|
||||
}
|
||||
|
||||
return h;
|
||||
}
|
||||
|
||||
protected double interpolateGenerator(double rx, double rz, IrisGenerator gen)
|
||||
{
|
||||
double hi = IrisInterpolation.getNoise(gen.getInterpolationFunction(), (int) Math.round(rx), (int) Math.round(rz), gen.getInterpolationScale(), (xx, zz) ->
|
||||
{
|
||||
IrisBiome b = sampleBiome((int) xx, (int) zz).getBiome();
|
||||
|
||||
for(IrisBiomeGeneratorLink i : b.getGenerators())
|
||||
{
|
||||
if(i.getGenerator().equals(gen.getLoadKey()))
|
||||
{
|
||||
return i.getMax();
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
});
|
||||
|
||||
double lo = IrisInterpolation.getNoise(gen.getInterpolationFunction(), (int) Math.round(rx), (int) Math.round(rz), gen.getInterpolationScale(), (xx, zz) ->
|
||||
{
|
||||
IrisBiome b = sampleBiome((int) xx, (int) zz).getBiome();
|
||||
|
||||
for(IrisBiomeGeneratorLink i : b.getGenerators())
|
||||
{
|
||||
if(i.getGenerator().equals(gen.getLoadKey()))
|
||||
{
|
||||
return i.getMin();
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
});
|
||||
|
||||
return M.lerp(lo, hi, gen.getHeight(rx, rz, world.getSeed() + 239945));
|
||||
}
|
||||
|
||||
protected void loadGenerators()
|
||||
{
|
||||
KList<String> touch = new KList<>();
|
||||
KList<String> loadQueue = new KList<>();
|
||||
|
||||
for(String i : getDimension().getRegions())
|
||||
{
|
||||
IrisRegion r = Iris.data.getRegionLoader().load(i);
|
||||
|
||||
if(r != null)
|
||||
{
|
||||
loadQueue.addAll(r.getLandBiomes());
|
||||
loadQueue.addAll(r.getSeaBiomes());
|
||||
loadQueue.addAll(r.getShoreBiomes());
|
||||
}
|
||||
}
|
||||
|
||||
while(!loadQueue.isEmpty())
|
||||
{
|
||||
String next = loadQueue.pop();
|
||||
|
||||
if(!touch.contains(next))
|
||||
{
|
||||
touch.add(next);
|
||||
IrisBiome biome = Iris.data.getBiomeLoader().load(next);
|
||||
biome.getGenerators().forEach((i) -> registerGenerator(i.getCachedGenerator()));
|
||||
loadQueue.addAll(biome.getChildren());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public IrisRegion sampleRegion(int x, int z)
|
||||
{
|
||||
double wx = getModifiedX(x, z);
|
||||
double wz = getModifiedZ(x, z);
|
||||
return glBiome.getRegion(wx, wz);
|
||||
}
|
||||
|
||||
public BiomeResult sampleBiome(int x, int z)
|
||||
{
|
||||
if(!getDimension().getFocus().equals(""))
|
||||
{
|
||||
IrisBiome biome = Iris.data.getBiomeLoader().load(getDimension().getFocus());
|
||||
|
||||
for(String i : getDimension().getRegions())
|
||||
{
|
||||
IrisRegion reg = Iris.data.getRegionLoader().load(i);
|
||||
|
||||
if(reg.getLandBiomes().contains(biome.getLoadKey()))
|
||||
{
|
||||
biome.setInferredType(InferredType.LAND);
|
||||
break;
|
||||
}
|
||||
|
||||
if(reg.getSeaBiomes().contains(biome.getLoadKey()))
|
||||
{
|
||||
biome.setInferredType(InferredType.SEA);
|
||||
break;
|
||||
}
|
||||
|
||||
if(reg.getShoreBiomes().contains(biome.getLoadKey()))
|
||||
{
|
||||
biome.setInferredType(InferredType.SHORE);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return new BiomeResult(biome, 0);
|
||||
}
|
||||
|
||||
ChunkPosition pos = new ChunkPosition(x, z);
|
||||
|
||||
if(biomeHitCache.containsKey(pos))
|
||||
{
|
||||
return biomeHitCache.get(pos);
|
||||
}
|
||||
|
||||
double wx = getModifiedX(x, z);
|
||||
double wz = getModifiedZ(x, z);
|
||||
IrisRegion region = glBiome.getRegion(wx, wz);
|
||||
BiomeResult res = glBiome.generateRegionData(wx, wz, x, z, region);
|
||||
biomeHitCache.put(pos, res);
|
||||
|
||||
return res;
|
||||
}
|
||||
}
|
@ -0,0 +1,302 @@
|
||||
package ninja.bytecode.iris.generator;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Random;
|
||||
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.Chunk;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.World;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.event.EventHandler;
|
||||
import org.bukkit.event.HandlerList;
|
||||
import org.bukkit.event.Listener;
|
||||
import org.bukkit.event.player.PlayerJoinEvent;
|
||||
import org.bukkit.event.player.PlayerQuitEvent;
|
||||
import org.bukkit.event.player.PlayerTeleportEvent;
|
||||
import org.bukkit.event.world.ChunkLoadEvent;
|
||||
import org.bukkit.event.world.ChunkUnloadEvent;
|
||||
import org.bukkit.event.world.WorldUnloadEvent;
|
||||
import org.bukkit.generator.BlockPopulator;
|
||||
import org.bukkit.generator.ChunkGenerator;
|
||||
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
import net.md_5.bungee.api.ChatColor;
|
||||
import ninja.bytecode.iris.Iris;
|
||||
import ninja.bytecode.iris.IrisContext;
|
||||
import ninja.bytecode.iris.IrisMetrics;
|
||||
import ninja.bytecode.iris.util.BlockDataTools;
|
||||
import ninja.bytecode.iris.util.CNG;
|
||||
import ninja.bytecode.iris.util.ChronoLatch;
|
||||
import ninja.bytecode.iris.util.RNG;
|
||||
import ninja.bytecode.shuriken.bench.PrecisionStopwatch;
|
||||
import ninja.bytecode.shuriken.logging.L;
|
||||
|
||||
@Data
|
||||
@EqualsAndHashCode(callSuper = false)
|
||||
public abstract class ContextualChunkGenerator extends ChunkGenerator implements Listener
|
||||
{
|
||||
protected boolean failing;
|
||||
protected int task;
|
||||
protected boolean initialized;
|
||||
protected RNG masterRandom;
|
||||
protected ChronoLatch perSecond;
|
||||
protected ChronoLatch pushLatch;
|
||||
protected IrisMetrics metrics;
|
||||
protected World world;
|
||||
protected int generated;
|
||||
protected int ticks;
|
||||
protected boolean pregenDone;
|
||||
|
||||
public ContextualChunkGenerator()
|
||||
{
|
||||
pushLatch = new ChronoLatch(3000);
|
||||
perSecond = new ChronoLatch(1000);
|
||||
CNG.creates = 0;
|
||||
generated = 0;
|
||||
ticks = 0;
|
||||
task = -1;
|
||||
initialized = false;
|
||||
failing = false;
|
||||
pregenDone = false;
|
||||
}
|
||||
|
||||
protected abstract void onGenerate(RNG masterRandom, int x, int z, ChunkData data, BiomeGrid grid);
|
||||
|
||||
protected abstract void onInit(World world, RNG masterRandom);
|
||||
|
||||
protected abstract void onTick(int ticks);
|
||||
|
||||
protected abstract void onClose();
|
||||
|
||||
protected abstract void onFailure(Throwable e);
|
||||
|
||||
protected abstract void onChunkLoaded(Chunk c);
|
||||
|
||||
protected abstract void onChunkUnloaded(Chunk c);
|
||||
|
||||
protected abstract void onPlayerJoin(Player p);
|
||||
|
||||
protected abstract void onPlayerLeft(Player p);
|
||||
|
||||
private void init(World world, RNG rng)
|
||||
{
|
||||
if(initialized)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
this.world = world;
|
||||
this.masterRandom = new RNG(world.getSeed());
|
||||
metrics = new IrisMetrics(128);
|
||||
initialized = true;
|
||||
Bukkit.getServer().getPluginManager().registerEvents(this, Iris.instance);
|
||||
task = Bukkit.getScheduler().scheduleSyncRepeatingTask(Iris.instance, this::tick, 0, 0);
|
||||
onInit(world, masterRandom);
|
||||
}
|
||||
|
||||
private void tick()
|
||||
{
|
||||
if(perSecond.flip())
|
||||
{
|
||||
if(generated > 770)
|
||||
{
|
||||
pregenDone = true;
|
||||
}
|
||||
|
||||
if(pregenDone)
|
||||
{
|
||||
metrics.getPerSecond().put(generated);
|
||||
generated = 0;
|
||||
}
|
||||
}
|
||||
|
||||
onTick(ticks++);
|
||||
}
|
||||
|
||||
@EventHandler
|
||||
public void on(PlayerTeleportEvent e)
|
||||
{
|
||||
if(e.getFrom().getWorld().equals(world) && !e.getTo().getWorld().equals(world))
|
||||
{
|
||||
onPlayerLeft(e.getPlayer());
|
||||
}
|
||||
|
||||
if(!e.getFrom().getWorld().equals(world) && e.getTo().getWorld().equals(world))
|
||||
{
|
||||
onPlayerJoin(e.getPlayer());
|
||||
}
|
||||
}
|
||||
|
||||
@EventHandler
|
||||
public void on(PlayerQuitEvent e)
|
||||
{
|
||||
if(e.getPlayer().getWorld().equals(world))
|
||||
{
|
||||
onPlayerLeft(e.getPlayer());
|
||||
}
|
||||
}
|
||||
|
||||
@EventHandler
|
||||
public void on(PlayerJoinEvent e)
|
||||
{
|
||||
if(e.getPlayer().getWorld().equals(world))
|
||||
{
|
||||
onPlayerJoin(e.getPlayer());
|
||||
}
|
||||
}
|
||||
|
||||
@EventHandler
|
||||
public void on(ChunkLoadEvent e)
|
||||
{
|
||||
if(e.getWorld().equals(world))
|
||||
{
|
||||
onChunkLoaded(e.getChunk());
|
||||
}
|
||||
}
|
||||
|
||||
@EventHandler
|
||||
public void on(ChunkUnloadEvent e)
|
||||
{
|
||||
if(e.getWorld().equals(world))
|
||||
{
|
||||
onChunkUnloaded(e.getChunk());
|
||||
}
|
||||
}
|
||||
|
||||
@EventHandler
|
||||
public void on(WorldUnloadEvent e)
|
||||
{
|
||||
if(world != null && e.getWorld().equals(world))
|
||||
{
|
||||
close();
|
||||
}
|
||||
}
|
||||
|
||||
protected void close()
|
||||
{
|
||||
HandlerList.unregisterAll(this);
|
||||
Bukkit.getScheduler().cancelTask(getTask());
|
||||
onClose();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean canSpawn(World world, int x, int z)
|
||||
{
|
||||
return super.canSpawn(world, x, z);
|
||||
}
|
||||
|
||||
protected ChunkData generateChunkDataFailure(World world, Random no, int x, int z, BiomeGrid biomeGrid)
|
||||
{
|
||||
ChunkData c = Bukkit.createChunkData(world);
|
||||
|
||||
for(int i = 0; i < 16; i++)
|
||||
{
|
||||
for(int j = 0; j < 16; j++)
|
||||
{
|
||||
int h = 0;
|
||||
|
||||
if(j == i || j + i == 16)
|
||||
{
|
||||
c.setBlock(i, h, j, BlockDataTools.getBlockData("RED_TERRACOTTA"));
|
||||
}
|
||||
|
||||
else
|
||||
{
|
||||
c.setBlock(i, h, j, BlockDataTools.getBlockData("BLACK_TERRACOTTA"));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return c;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ChunkData generateChunkData(World world, Random no, int x, int z, BiomeGrid biomeGrid)
|
||||
{
|
||||
PrecisionStopwatch sx = PrecisionStopwatch.start();
|
||||
|
||||
if(failing)
|
||||
{
|
||||
return generateChunkDataFailure(world, no, x, z, biomeGrid);
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
if(pushLatch.flip())
|
||||
{
|
||||
if(this.world == null)
|
||||
{
|
||||
this.world = world;
|
||||
}
|
||||
|
||||
Iris.hotloader.check((IrisContext) this);
|
||||
|
||||
if(this instanceof IrisContext)
|
||||
{
|
||||
IrisContext.pushContext((IrisContext) this);
|
||||
}
|
||||
}
|
||||
|
||||
PrecisionStopwatch s = PrecisionStopwatch.start();
|
||||
RNG random = new RNG(world.getSeed());
|
||||
init(world, random.nextParallelRNG(0));
|
||||
ChunkData c = Bukkit.createChunkData(world);
|
||||
onGenerate(random, x, z, c, biomeGrid);
|
||||
metrics.getTotal().put(s.getMilliseconds());
|
||||
generated++;
|
||||
long hits = CNG.hits;
|
||||
CNG.hits = 0;
|
||||
Iris.instance.hit(hits);
|
||||
metrics.getLoss().put(sx.getMilliseconds() - s.getMilliseconds());
|
||||
return c;
|
||||
}
|
||||
|
||||
catch(Throwable e)
|
||||
{
|
||||
fail(e);
|
||||
}
|
||||
|
||||
return generateChunkDataFailure(world, no, x, z, biomeGrid);
|
||||
}
|
||||
|
||||
public void onHotloaded()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
protected void fail(Throwable e)
|
||||
{
|
||||
failing = true;
|
||||
Iris.error("ERROR! Failed to generate chunk! Iris has entered a failed state!");
|
||||
|
||||
for(Player i : world.getPlayers())
|
||||
{
|
||||
Iris.instance.imsg(i, ChatColor.DARK_RED + "Iris Generator has entered a failed state!");
|
||||
Iris.instance.imsg(i, ChatColor.RED + "- Check the console for the error.");
|
||||
Iris.instance.imsg(i, ChatColor.RED + "- Then simply run /iris dev");
|
||||
}
|
||||
|
||||
L.ex(e);
|
||||
onFailure(e);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<BlockPopulator> getDefaultPopulators(World world)
|
||||
{
|
||||
return super.getDefaultPopulators(world);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Location getFixedSpawnLocation(World world, Random random)
|
||||
{
|
||||
return super.getFixedSpawnLocation(world, random);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isParallelCapable()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
@ -0,0 +1,89 @@
|
||||
package ninja.bytecode.iris.generator;
|
||||
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
import ninja.bytecode.iris.Iris;
|
||||
import ninja.bytecode.iris.object.InferredType;
|
||||
import ninja.bytecode.iris.object.IrisBiome;
|
||||
import ninja.bytecode.iris.object.IrisDimension;
|
||||
import ninja.bytecode.iris.object.IrisRegion;
|
||||
import ninja.bytecode.iris.util.BiomeResult;
|
||||
|
||||
@Data
|
||||
@EqualsAndHashCode(callSuper = false)
|
||||
public abstract class DimensionChunkGenerator extends ContextualChunkGenerator
|
||||
{
|
||||
protected final String dimensionName;
|
||||
|
||||
public DimensionChunkGenerator(String dimensionName)
|
||||
{
|
||||
super();
|
||||
this.dimensionName = dimensionName;
|
||||
}
|
||||
|
||||
public IrisDimension getDimension()
|
||||
{
|
||||
IrisDimension d = Iris.data.getDimensionLoader().load(dimensionName);
|
||||
|
||||
if(d == null)
|
||||
{
|
||||
Iris.error("Can't find dimension: " + dimensionName);
|
||||
}
|
||||
|
||||
return d;
|
||||
}
|
||||
|
||||
protected BiomeResult focus()
|
||||
{
|
||||
IrisBiome biome = Iris.data.getBiomeLoader().load(getDimension().getFocus());
|
||||
|
||||
for(String i : getDimension().getRegions())
|
||||
{
|
||||
IrisRegion reg = Iris.data.getRegionLoader().load(i);
|
||||
|
||||
if(reg.getLandBiomes().contains(biome.getLoadKey()))
|
||||
{
|
||||
biome.setInferredType(InferredType.LAND);
|
||||
break;
|
||||
}
|
||||
|
||||
if(reg.getSeaBiomes().contains(biome.getLoadKey()))
|
||||
{
|
||||
biome.setInferredType(InferredType.SEA);
|
||||
break;
|
||||
}
|
||||
|
||||
if(reg.getShoreBiomes().contains(biome.getLoadKey()))
|
||||
{
|
||||
biome.setInferredType(InferredType.SHORE);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return new BiomeResult(biome, 0);
|
||||
}
|
||||
|
||||
public double getModifiedX(int rx, int rz)
|
||||
{
|
||||
return (getDimension().cosRotate() * rx) + (-getDimension().sinRotate() * rz) +
|
||||
|
||||
getDimension().getCoordFracture(masterRandom, 39392).fitDoubleD(-getDimension().getCoordFractureDistance() / 2, getDimension().getCoordFractureDistance() / 2, rx, rz);
|
||||
}
|
||||
|
||||
public double getModifiedZ(int rx, int rz)
|
||||
{
|
||||
return (getDimension().sinRotate() * rx) + (getDimension().cosRotate() * rz) +
|
||||
|
||||
getDimension().getCoordFracture(masterRandom, 39392).fitDoubleD(-getDimension().getCoordFractureDistance() / 2, getDimension().getCoordFractureDistance() / 2, rx, rz);
|
||||
}
|
||||
|
||||
public double getZoomed(double modified)
|
||||
{
|
||||
return (double) (modified) / getDimension().getTerrainZoom();
|
||||
}
|
||||
|
||||
public double getUnzoomed(double modified)
|
||||
{
|
||||
return (double) (modified) * getDimension().getTerrainZoom();
|
||||
}
|
||||
}
|
@ -0,0 +1,86 @@
|
||||
package ninja.bytecode.iris.generator;
|
||||
|
||||
import java.lang.reflect.Method;
|
||||
|
||||
import org.bukkit.Chunk;
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
import ninja.bytecode.iris.Iris;
|
||||
import ninja.bytecode.iris.IrisContext;
|
||||
import ninja.bytecode.iris.object.IrisRegion;
|
||||
import ninja.bytecode.iris.util.BiomeResult;
|
||||
|
||||
@Data
|
||||
@EqualsAndHashCode(callSuper = false)
|
||||
public class IrisChunkGenerator extends ParallaxChunkGenerator implements IrisContext
|
||||
{
|
||||
private Method initLighting;
|
||||
|
||||
public IrisChunkGenerator(String dimensionName, int threads)
|
||||
{
|
||||
super(dimensionName, threads);
|
||||
}
|
||||
|
||||
@Override
|
||||
public BiomeResult getBiome(int x, int z)
|
||||
{
|
||||
return sampleBiome(x, z);
|
||||
}
|
||||
|
||||
@Override
|
||||
public IrisRegion getRegion(int x, int z)
|
||||
{
|
||||
return sampleRegion(x, z);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getHeight(int x, int z)
|
||||
{
|
||||
return sampleHeight(x, z);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onTick(int ticks)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onClose()
|
||||
{
|
||||
super.onClose();
|
||||
Iris.info("Closing Iris Dimension " + getWorld().getName());
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onFailure(Throwable e)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onChunkLoaded(Chunk c)
|
||||
{
|
||||
// TODO: updateLights(); better
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onChunkUnloaded(Chunk c)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onPlayerJoin(Player p)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onPlayerLeft(Player p)
|
||||
{
|
||||
|
||||
}
|
||||
}
|
@ -1,728 +0,0 @@
|
||||
package ninja.bytecode.iris.generator;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Random;
|
||||
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.TreeSpecies;
|
||||
import org.bukkit.World;
|
||||
import org.bukkit.block.Biome;
|
||||
import org.bukkit.generator.BlockPopulator;
|
||||
import org.bukkit.material.Leaves;
|
||||
import org.bukkit.util.NumberConversions;
|
||||
|
||||
import mortar.util.text.C;
|
||||
import ninja.bytecode.iris.Iris;
|
||||
import ninja.bytecode.iris.generator.atomics.AtomicChunkData;
|
||||
import ninja.bytecode.iris.generator.genobject.GenObjectDecorator;
|
||||
import ninja.bytecode.iris.generator.genobject.PlacedObject;
|
||||
import ninja.bytecode.iris.generator.layer.GenLayerBiome;
|
||||
import ninja.bytecode.iris.generator.layer.GenLayerCarving;
|
||||
import ninja.bytecode.iris.generator.layer.GenLayerCaves;
|
||||
import ninja.bytecode.iris.generator.layer.GenLayerCliffs;
|
||||
import ninja.bytecode.iris.generator.layer.GenLayerLayeredNoise;
|
||||
import ninja.bytecode.iris.generator.layer.GenLayerOres;
|
||||
import ninja.bytecode.iris.generator.layer.GenLayerSnow;
|
||||
import ninja.bytecode.iris.generator.parallax.ParallaxWorldGenerator;
|
||||
import ninja.bytecode.iris.pack.BiomeType;
|
||||
import ninja.bytecode.iris.pack.CompiledDimension;
|
||||
import ninja.bytecode.iris.pack.IrisBiome;
|
||||
import ninja.bytecode.iris.pack.IrisRegion;
|
||||
import ninja.bytecode.iris.util.ChunkPlan;
|
||||
import ninja.bytecode.iris.util.InterpolationMode;
|
||||
import ninja.bytecode.iris.util.IrisInterpolation;
|
||||
import ninja.bytecode.iris.util.IrisMetrics;
|
||||
import ninja.bytecode.iris.util.MB;
|
||||
import ninja.bytecode.iris.util.NoiseProvider;
|
||||
import ninja.bytecode.iris.util.ObjectMode;
|
||||
import ninja.bytecode.iris.util.SChunkVector;
|
||||
import ninja.bytecode.shuriken.bench.PrecisionStopwatch;
|
||||
import ninja.bytecode.shuriken.collections.KList;
|
||||
import ninja.bytecode.shuriken.logging.L;
|
||||
import ninja.bytecode.shuriken.math.CNG;
|
||||
import ninja.bytecode.shuriken.math.M;
|
||||
import ninja.bytecode.shuriken.math.RNG;
|
||||
|
||||
public class IrisGenerator extends ParallaxWorldGenerator
|
||||
{
|
||||
//@builder
|
||||
public static final KList<MB> ROCK = new KList<MB>().add(new MB[] {
|
||||
MB.of(Material.STONE),
|
||||
MB.of(Material.STONE),
|
||||
MB.of(Material.STONE),
|
||||
MB.of(Material.STONE),
|
||||
MB.of(Material.STONE),
|
||||
MB.of(Material.STONE),
|
||||
MB.of(Material.STONE),
|
||||
MB.of(Material.STONE),
|
||||
MB.of(Material.STONE),
|
||||
MB.of(Material.STONE, 5),
|
||||
MB.of(Material.STONE, 5),
|
||||
MB.of(Material.STONE, 5),
|
||||
MB.of(Material.STONE, 5),
|
||||
MB.of(Material.STONE, 5),
|
||||
MB.of(Material.STONE, 5)
|
||||
});
|
||||
//@done
|
||||
private boolean disposed;
|
||||
private CNG scatter;
|
||||
private CNG beach;
|
||||
private CNG swirl;
|
||||
private MB BEDROCK = new MB(Material.BEDROCK);
|
||||
private GenObjectDecorator god;
|
||||
private GenLayerLayeredNoise glLNoise;
|
||||
private GenLayerBiome glBiome;
|
||||
private GenLayerSnow glSnow;
|
||||
private GenLayerCliffs glCliffs;
|
||||
private GenLayerCaves glCaves;
|
||||
private GenLayerCarving glCarving;
|
||||
private GenLayerOres glOres;
|
||||
private RNG rTerrain;
|
||||
private CompiledDimension dim;
|
||||
private IrisMetrics metrics = new IrisMetrics(0, 512);
|
||||
private int objectHits;
|
||||
|
||||
public IrisGenerator()
|
||||
{
|
||||
this(Iris.pack().getDimension("overworld"));
|
||||
}
|
||||
|
||||
public void hitObject()
|
||||
{
|
||||
objectHits++;
|
||||
}
|
||||
|
||||
public IrisGenerator(CompiledDimension dim)
|
||||
{
|
||||
objectHits = 0;
|
||||
CNG.hits = 0;
|
||||
CNG.creates = 0;
|
||||
this.dim = dim;
|
||||
disposed = false;
|
||||
L.i("Preparing Dimension: " + dim.getName() + " With " + dim.getBiomes().size() + " Biomes...");
|
||||
}
|
||||
|
||||
public int scatterInt(int x, int y, int z, int bound)
|
||||
{
|
||||
return (int) (scatter(x, y, z) * (double) (bound - 1));
|
||||
}
|
||||
|
||||
public double scatter(int x, int y, int z)
|
||||
{
|
||||
return scatter.noise(x, y, z);
|
||||
}
|
||||
|
||||
public boolean scatterChance(int x, int y, int z, double chance)
|
||||
{
|
||||
return scatter(x, y, z) > chance;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onInit(World world, Random random)
|
||||
{
|
||||
if(disposed)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
random = new Random(world.getSeed());
|
||||
rTerrain = new RNG(world.getSeed());
|
||||
swirl = new CNG(rTerrain.nextParallelRNG(0), 40, 1).scale(0.007);
|
||||
beach = new CNG(rTerrain.nextParallelRNG(0), 3, 1).scale(0.15);
|
||||
glLNoise = new GenLayerLayeredNoise(this, world, random, rTerrain.nextParallelRNG(2));
|
||||
glBiome = new GenLayerBiome(this, world, random, rTerrain.nextParallelRNG(4), dim.getBiomes());
|
||||
glSnow = new GenLayerSnow(this, world, random, rTerrain.nextParallelRNG(5));
|
||||
glCliffs = new GenLayerCliffs(this, world, random, rTerrain.nextParallelRNG(9));
|
||||
glCaves = new GenLayerCaves(this, world, random, rTerrain.nextParallelRNG(10));
|
||||
glCarving = new GenLayerCarving(this, world, random, rTerrain.nextParallelRNG(11));
|
||||
glOres = new GenLayerOres(this, world, random, rTerrain.nextParallelRNG(12));
|
||||
scatter = new CNG(rTerrain.nextParallelRNG(52), 1, 1).scale(10);
|
||||
|
||||
if(Iris.settings.performance.objectMode.equals(ObjectMode.PARALLAX))
|
||||
{
|
||||
god = new GenObjectDecorator(this);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public ChunkPlan onInitChunk(World world, int x, int z, Random random)
|
||||
{
|
||||
return new ChunkPlan();
|
||||
}
|
||||
|
||||
public ChunkData generateChunkData(World world, Random random, int x, int z, BiomeGrid biome)
|
||||
{
|
||||
random = new Random(world.getSeed());
|
||||
PrecisionStopwatch s = getMetrics().start();
|
||||
ChunkData d = super.generateChunkData(world, random, x, z, biome);
|
||||
getMetrics().stop("chunk:ms", s);
|
||||
getMetrics().put("noise-hits", CNG.hits);
|
||||
metrics.setGenerators((int) CNG.creates);
|
||||
CNG.hits = 0;
|
||||
return d;
|
||||
}
|
||||
|
||||
public IrisBiome biome(String name)
|
||||
{
|
||||
return getDimension().getBiomeByName(name);
|
||||
}
|
||||
|
||||
public double getOffsetX(double x, double z)
|
||||
{
|
||||
return Math.round((double) x * (Iris.settings.gen.horizontalZoom / 1.90476190476)) + swirl.noise(x, z);
|
||||
}
|
||||
|
||||
public double getOffsetZ(double x, double z)
|
||||
{
|
||||
return Math.round((double) z * (Iris.settings.gen.horizontalZoom / 1.90476190476)) - swirl.noise(z, x);
|
||||
}
|
||||
|
||||
public IrisMetrics getMetrics()
|
||||
{
|
||||
return metrics;
|
||||
}
|
||||
|
||||
public IrisBiome getBeach(IrisBiome biome)
|
||||
{
|
||||
IrisBiome beach = null;
|
||||
IrisRegion region = glBiome.getRegion(biome.getRegionID());
|
||||
|
||||
if(region != null)
|
||||
{
|
||||
beach = region.getBeach();
|
||||
}
|
||||
|
||||
if(beach == null)
|
||||
{
|
||||
beach = biome("Beach");
|
||||
}
|
||||
|
||||
return beach;
|
||||
}
|
||||
|
||||
public int computeHeight(int x, int z, ChunkPlan plan, IrisBiome biome)
|
||||
{
|
||||
return (int) Math.round(M.clip(getANoise((int) x, (int) z, plan, biome), 0D, 1D) * 253);
|
||||
}
|
||||
|
||||
public double getInterpolation(int x, int z, double opacity, ChunkPlan plan)
|
||||
{
|
||||
PrecisionStopwatch s = getMetrics().start();
|
||||
NoiseProvider n = (xf, zf) -> getBiomedHeight((int) Math.round(xf), (int) Math.round(zf), plan);
|
||||
double d = 0;
|
||||
double rad = Iris.settings.gen.interpolationRadius;
|
||||
|
||||
InterpolationMode m = Iris.settings.gen.interpolationMode;
|
||||
|
||||
if(m.equals(InterpolationMode.BILINEAR))
|
||||
{
|
||||
d = IrisInterpolation.getBilinearNoise(x, z, rad, n);
|
||||
}
|
||||
|
||||
else if(m.equals(InterpolationMode.BICUBIC))
|
||||
{
|
||||
d = IrisInterpolation.getBicubicNoise(x, z, rad, n);
|
||||
}
|
||||
|
||||
else if(m.equals(InterpolationMode.HERMITE_BICUBIC))
|
||||
{
|
||||
d = IrisInterpolation.getHermiteNoise(x, z, rad, n);
|
||||
}
|
||||
|
||||
else
|
||||
{
|
||||
d = n.noise(x, z);
|
||||
}
|
||||
|
||||
getMetrics().stop("interpolation:ms:x256:/biome:.", s);
|
||||
|
||||
return d;
|
||||
}
|
||||
|
||||
public double getANoise(int x, int z, ChunkPlan plan, IrisBiome biome)
|
||||
{
|
||||
double hv = getInterpolation((int) x, (int) z, 1D, plan);
|
||||
hv += glLNoise.generateLayer(hv * Iris.settings.gen.roughness * 215, (double) x * Iris.settings.gen.roughness * 0.82, (double) z * Iris.settings.gen.roughness * 0.82) * (1.6918 * (hv * 2.35));
|
||||
|
||||
if(biome.hasCliffs())
|
||||
{
|
||||
hv = glCliffs.generateLayer(hv, x, z, biome.getCliffScale(), biome.getCliffChance());
|
||||
}
|
||||
|
||||
return hv;
|
||||
}
|
||||
|
||||
public IrisRegion getRegion(IrisBiome biome)
|
||||
{
|
||||
return glBiome.getRegion(biome.getRegionID());
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<BlockPopulator> getDefaultPopulators(World world)
|
||||
{
|
||||
KList<BlockPopulator> p = new KList<>();
|
||||
|
||||
if(Iris.settings.performance.objectMode.equals(ObjectMode.QUICK_N_DIRTY) || Iris.settings.performance.objectMode.equals(ObjectMode.LIGHTING))
|
||||
{
|
||||
p.add(god = new GenObjectDecorator(this));
|
||||
}
|
||||
|
||||
return p;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onGenParallax(int x, int z, Random random)
|
||||
{
|
||||
try
|
||||
{
|
||||
PrecisionStopwatch s = getMetrics().start();
|
||||
god.populateParallax(x, z, random);
|
||||
String xx = "x" + getParallaxSize().getX() * getParallaxSize().getZ();
|
||||
getMetrics().stop("object:" + xx + ":.:ms:/parallax", s);
|
||||
}
|
||||
|
||||
catch(Throwable e)
|
||||
{
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
private double getObjectHits()
|
||||
{
|
||||
int hits = objectHits;
|
||||
objectHits = 0;
|
||||
return hits;
|
||||
}
|
||||
|
||||
public IrisBiome getBiome(int x, int z)
|
||||
{
|
||||
IrisBiome biome = glBiome.getBiome(x, z);
|
||||
int height = computeHeight((int) x, (int) z, new ChunkPlan(), biome);
|
||||
biome = getBiome((int) x, height, (int) z);
|
||||
|
||||
return biome;
|
||||
}
|
||||
|
||||
private IrisBiome getBiome(int x, int y, int z)
|
||||
{
|
||||
int seaLevel = Iris.settings.gen.seaLevel;
|
||||
boolean land = y >= seaLevel;
|
||||
int beachHeight = land ? 1 + (int) Math.round(seaLevel + beach.noise(x, z) + 1) : seaLevel;
|
||||
boolean beach = y <= beachHeight && land;
|
||||
IrisBiome biome = glBiome.getBiome(x, z);
|
||||
IrisBiome realBiome = glBiome.getBiome(x, z, true);
|
||||
boolean nearAquatic = glBiome.isNearAquatic(x, z);
|
||||
IrisRegion region = getRegion(realBiome);
|
||||
|
||||
// Remove Oceans from biomes above sea level
|
||||
if(land && biome.getType().equals(BiomeType.FLUID))
|
||||
{
|
||||
biome = realBiome;
|
||||
}
|
||||
|
||||
// Add Beaches & Shores
|
||||
if(beach && biome.getType().equals(BiomeType.LAND))
|
||||
{
|
||||
biome = nearAquatic ? region.getBeach() : region.getShore();
|
||||
}
|
||||
|
||||
// // Replace biomes under sea level with lakes
|
||||
if(!land && biome.getType().equals(BiomeType.LAND))
|
||||
{
|
||||
biome = region.getLake();
|
||||
}
|
||||
|
||||
return biome;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Biome onGenColumn(int wxxf, int wzxf, int x, int z, ChunkPlan plan, AtomicChunkData data, boolean surfaceOnly)
|
||||
{
|
||||
PrecisionStopwatch s = getMetrics().start();
|
||||
if(disposed)
|
||||
{
|
||||
data.setBlock(x, 0, z, Material.MAGENTA_GLAZED_TERRACOTTA);
|
||||
return Biome.VOID;
|
||||
}
|
||||
|
||||
double wx = getOffsetX(wxxf, wzxf);
|
||||
double wz = getOffsetZ(wxxf, wzxf);
|
||||
int wxx = (int) wx;
|
||||
int wzx = (int) wz;
|
||||
int highest = 0;
|
||||
int seaLevel = Iris.settings.gen.seaLevel;
|
||||
IrisBiome biome = glBiome.getBiome(wxx, wzx);
|
||||
int height = computeHeight(wxx, wzx, plan, biome);
|
||||
int max = Math.max(height, seaLevel);
|
||||
biome = getBiome(wxx, height, wzx);
|
||||
MB FLUID = biome.getFluid();
|
||||
|
||||
for(int i = surfaceOnly ? max > seaLevel ? max - 2 : height - 2 : 0; i < max; i++)
|
||||
{
|
||||
MB mb = ROCK.get(scatterInt(wzx, i, wxx, ROCK.size()));
|
||||
boolean carved = surfaceOnly ? false : glCarving.isCarved(wzx, wxx, x, z, i, data, plan);
|
||||
boolean underwater = i >= height && i < seaLevel;
|
||||
boolean underground = i < height;
|
||||
int dheight = biome.getDirtDepth();
|
||||
int rheight = biome.getRockDepth();
|
||||
boolean dirt = (height - 1) - i < (dheight > 0 ? scatterInt(x, i, z, 4) : 0) + dheight;
|
||||
boolean rocky = i > height - rheight && !dirt;
|
||||
boolean bedrock = i == 0 || !Iris.settings.gen.flatBedrock ? i <= 2 : i < scatterInt(x, i, z, 3);
|
||||
|
||||
if(!carved)
|
||||
{
|
||||
mb = underwater ? FLUID : mb;
|
||||
mb = underground && dirt ? biome.getSubSurface(wxx, i, wzx, rTerrain) : mb;
|
||||
mb = underground && rocky ? biome.getRock(wxx, i, wzx, rTerrain) : mb;
|
||||
mb = bedrock ? BEDROCK : mb;
|
||||
|
||||
if(i == height - 1)
|
||||
{
|
||||
mb = biome.getSurface(wx, wz, rTerrain);
|
||||
}
|
||||
|
||||
highest = i > highest ? i : highest;
|
||||
}
|
||||
|
||||
else
|
||||
{
|
||||
mb = MB.of(Material.AIR);
|
||||
}
|
||||
data.setBlock(x, i, z, mb.material, mb.data);
|
||||
}
|
||||
|
||||
getMetrics().stop("terrain:ms:x256:/chunk:..", s);
|
||||
|
||||
int hw = 0;
|
||||
int hl = 0;
|
||||
|
||||
for(int i = highest; i > 0; i--)
|
||||
{
|
||||
Material t = data.getType(x, i, z);
|
||||
hw = i > seaLevel && hw == 0 && (t.equals(Material.WATER) || t.equals(Material.STATIONARY_WATER)) ? i : hw;
|
||||
hl = hl == 0 && !t.equals(Material.AIR) ? i : hl;
|
||||
}
|
||||
|
||||
plan.setRealHeight(x, z, hl);
|
||||
plan.setRealWaterHeight(x, z, hw == 0 ? seaLevel : hw);
|
||||
plan.setBiome(x, z, biome);
|
||||
|
||||
if(!surfaceOnly)
|
||||
{
|
||||
glCaves.genCaves(wxxf, wzxf, x, z, data, plan);
|
||||
glOres.genOres(wxxf, wzxf, x, z, hl, data, plan);
|
||||
}
|
||||
|
||||
for(int i = highest; i > 0; i--)
|
||||
{
|
||||
Material t = data.getType(x, i, z);
|
||||
hw = i > seaLevel && hw == 0 && (t.equals(Material.WATER) || t.equals(Material.STATIONARY_WATER)) ? i : hw;
|
||||
hl = hl == 0 && !t.equals(Material.AIR) ? i : hl;
|
||||
}
|
||||
|
||||
plan.setRealHeight(x, z, hl);
|
||||
plan.setRealWaterHeight(x, z, hw == 0 ? seaLevel : hw);
|
||||
plan.setBiome(x, z, biome);
|
||||
double time = s.getMilliseconds() * 256D;
|
||||
double atime = getMetrics().get("chunk:ms").getAverage();
|
||||
getMetrics().setParScale(time / atime);
|
||||
getMetrics().put("objects:,:/parallax", getObjectHits());
|
||||
|
||||
return biome.getRealBiome();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onDecorateChunk(World world, int cx, int cz, AtomicChunkData data, ChunkPlan plan)
|
||||
{
|
||||
PrecisionStopwatch p = PrecisionStopwatch.start();
|
||||
int x = 0;
|
||||
int z = 0;
|
||||
int hhx = 0;
|
||||
int v = 0;
|
||||
int borderh = 0;
|
||||
int above = 0;
|
||||
int below = 0;
|
||||
|
||||
for(int f = 0; f < Iris.settings.gen.blockSmoothing; f++)
|
||||
{
|
||||
for(x = 0; x < 16; x++)
|
||||
{
|
||||
for(z = 0; z < 16; z++)
|
||||
{
|
||||
hhx = plan.getRealHeight(x, z);
|
||||
borderh = 0;
|
||||
|
||||
if(x == 0 || x == 15)
|
||||
{
|
||||
borderh++;
|
||||
}
|
||||
|
||||
if(z == 0 || z == 15)
|
||||
{
|
||||
borderh++;
|
||||
}
|
||||
|
||||
if(hhx > Iris.settings.gen.seaLevel - 2)
|
||||
{
|
||||
above = 0;
|
||||
below = 0;
|
||||
|
||||
if(x + 1 <= 15)
|
||||
{
|
||||
v = plan.getRealHeight(x + 1, z);
|
||||
|
||||
if(v > hhx)
|
||||
{
|
||||
above++;
|
||||
}
|
||||
|
||||
else if(v < hhx)
|
||||
{
|
||||
below++;
|
||||
}
|
||||
}
|
||||
|
||||
if(x - 1 >= 0)
|
||||
{
|
||||
v = plan.getRealHeight(x - 1, z);
|
||||
|
||||
if(v > hhx)
|
||||
{
|
||||
above++;
|
||||
}
|
||||
|
||||
else if(v < hhx)
|
||||
{
|
||||
below++;
|
||||
}
|
||||
}
|
||||
|
||||
if(z + 1 <= 15)
|
||||
{
|
||||
v = plan.getRealHeight(x, z + 1);
|
||||
|
||||
if(v > hhx)
|
||||
{
|
||||
above++;
|
||||
}
|
||||
|
||||
else if(v < hhx)
|
||||
{
|
||||
below++;
|
||||
}
|
||||
}
|
||||
|
||||
if(z - 1 >= 0)
|
||||
{
|
||||
v = plan.getRealHeight(x, z - 1);
|
||||
|
||||
if(v > hhx)
|
||||
{
|
||||
above++;
|
||||
}
|
||||
|
||||
else if(v < hhx)
|
||||
{
|
||||
below++;
|
||||
}
|
||||
}
|
||||
|
||||
// Patch Hole
|
||||
if(above >= 4 - borderh)
|
||||
{
|
||||
data.setBlock(x, hhx + 1, z, data.getMB(x, hhx, z));
|
||||
plan.setRealHeight(x, z, hhx + 1);
|
||||
}
|
||||
|
||||
// Remove Nipple
|
||||
else if(below >= 4 - borderh)
|
||||
{
|
||||
data.setBlock(x, hhx - 1, z, data.getMB(x, hhx, z));
|
||||
data.setBlock(x, hhx, z, Material.AIR);
|
||||
plan.setRealHeight(x, z, hhx - 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
getMetrics().stop("decoration:ms:/chunk:..", p);
|
||||
}
|
||||
|
||||
@SuppressWarnings("deprecation")
|
||||
@Override
|
||||
protected void onDecorateColumn(World world, int x, int z, int wx, int wz, AtomicChunkData data, ChunkPlan plan)
|
||||
{
|
||||
PrecisionStopwatch p = PrecisionStopwatch.start();
|
||||
int h = plan.getRealHeight(x, z);
|
||||
|
||||
if(h < 63)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
IrisBiome biome = plan.getBiome(x, z);
|
||||
|
||||
if(biome == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if(biome.getSnow() > 0)
|
||||
{
|
||||
double level = glSnow.getHeight(wx, wz) * biome.getSnow();
|
||||
int blocks = (int) level;
|
||||
level -= blocks;
|
||||
int layers = (int) (level * 7D);
|
||||
int snowHeight = blocks + (layers > 0 ? 1 : 0);
|
||||
|
||||
for(int j = 0; j < snowHeight; j++)
|
||||
{
|
||||
data.setBlock(x, h + j + 1, z, j == snowHeight - 1 ? Material.SNOW : Material.SNOW_BLOCK, j == snowHeight - 1 ? (byte) layers : (byte) 0);
|
||||
}
|
||||
}
|
||||
|
||||
else
|
||||
{
|
||||
MB mbx = biome.getScatterChanceSingle(scatter(wx, h, wz), scatter(wz, h, wx));
|
||||
|
||||
if(!mbx.material.equals(Material.AIR))
|
||||
{
|
||||
data.setBlock(x, h + 1, z, mbx.material, mbx.data);
|
||||
|
||||
if(mbx.material.equals(Material.DOUBLE_PLANT))
|
||||
{
|
||||
data.setBlock(x, h + 2, z, mbx.material, (byte) 10);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if(biome.getLush() > 0.33)
|
||||
{
|
||||
double lx = (biome.getLush() > 1 ? 1 : biome.getLush()) - 0.33;
|
||||
double g = glSnow.getHeight(wz, wx);
|
||||
|
||||
if(lx / 1.18D > g)
|
||||
{
|
||||
double gx = glSnow.getHeight(wx * 2.25, wz * 2.25);
|
||||
double gf = glSnow.getHeight(wx * 6.25, wz * 6.25);
|
||||
|
||||
if(gf > gx)
|
||||
{
|
||||
Leaves l = new Leaves(TreeSpecies.values()[(int) (gx * (TreeSpecies.values().length - 1))]);
|
||||
l.setDecaying(false);
|
||||
l.setDecayable(false);
|
||||
data.setBlock(x, h - 1, z, data.getMB(x, h, z));
|
||||
data.setBlock(x, h, z, l.getItemType(), l.getData());
|
||||
|
||||
if(gf - gx > 0.2)
|
||||
{
|
||||
l = new Leaves(TreeSpecies.values()[(int) (gf * (TreeSpecies.values().length - 1))]);
|
||||
l.setDecaying(false);
|
||||
l.setDecayable(false);
|
||||
data.setBlock(x, h + 1, z, l.getItemType(), l.getData());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
getMetrics().stop("pardecoration:ms:x256:/chunk:..", p);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onPostChunk(World world, int cx, int cz, Random random, AtomicChunkData data, ChunkPlan plan)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
private double getBiomedHeight(int x, int z, ChunkPlan plan)
|
||||
{
|
||||
double xh = plan.getHeight(x, z);
|
||||
|
||||
if(xh == -1)
|
||||
{
|
||||
IrisBiome biome = glBiome.getBiome(x, z);
|
||||
double h = Iris.settings.gen.baseHeight + biome.getHeight();
|
||||
h += biome.getGenerator().getHeight(x, z) / 2D;
|
||||
plan.setHeight(x, z, h);
|
||||
return h;
|
||||
}
|
||||
|
||||
return xh;
|
||||
}
|
||||
|
||||
public RNG getRTerrain()
|
||||
{
|
||||
return rTerrain;
|
||||
}
|
||||
|
||||
public CompiledDimension getDimension()
|
||||
{
|
||||
return dim;
|
||||
}
|
||||
|
||||
public void dispose()
|
||||
{
|
||||
if(disposed)
|
||||
{
|
||||
return;
|
||||
}
|
||||
L.w(C.YELLOW + "Disposed Iris World " + C.RED + getWorld().getName());
|
||||
disposed = true;
|
||||
dim = null;
|
||||
glLNoise = null;
|
||||
glSnow = null;
|
||||
glCliffs = null;
|
||||
god.dispose();
|
||||
}
|
||||
|
||||
public boolean isDisposed()
|
||||
{
|
||||
return disposed;
|
||||
}
|
||||
|
||||
public PlacedObject nearest(Location o, int i)
|
||||
{
|
||||
PlacedObject f = null;
|
||||
double d = Integer.MAX_VALUE;
|
||||
if(god != null)
|
||||
{
|
||||
for(PlacedObject j : god.getHistory())
|
||||
{
|
||||
double dx = Math.abs(NumberConversions.square(j.getX() - o.getX()) + NumberConversions.square(j.getY() - o.getY()) + NumberConversions.square(j.getZ() - o.getZ()));
|
||||
|
||||
if(dx < d)
|
||||
{
|
||||
d = dx;
|
||||
f = j;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return f;
|
||||
}
|
||||
|
||||
public PlacedObject randomObject(String string)
|
||||
{
|
||||
return god.randomObject(string);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected SChunkVector getParallaxSize()
|
||||
{
|
||||
return dim.getMaxChunkSize();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onUnload()
|
||||
{
|
||||
dispose();
|
||||
}
|
||||
|
||||
public void inject(CompiledDimension dimension)
|
||||
{
|
||||
this.dim = dimension;
|
||||
onInit(getWorld(), rTerrain);
|
||||
}
|
||||
}
|
@ -1,81 +0,0 @@
|
||||
package ninja.bytecode.iris.generator;
|
||||
|
||||
import ninja.bytecode.iris.pack.IrisBiome;
|
||||
import ninja.bytecode.iris.util.MB;
|
||||
|
||||
public class IrisSample
|
||||
{
|
||||
public MB surface;
|
||||
public int height;
|
||||
public IrisBiome biome;
|
||||
|
||||
public MB getSurface()
|
||||
{
|
||||
return surface;
|
||||
}
|
||||
|
||||
public void setSurface(MB surface)
|
||||
{
|
||||
this.surface = surface;
|
||||
}
|
||||
|
||||
public int getHeight()
|
||||
{
|
||||
return height;
|
||||
}
|
||||
|
||||
public void setHeight(int height)
|
||||
{
|
||||
this.height = height;
|
||||
}
|
||||
|
||||
public IrisBiome getBiome()
|
||||
{
|
||||
return biome;
|
||||
}
|
||||
|
||||
public void setBiome(IrisBiome biome)
|
||||
{
|
||||
this.biome = biome;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode()
|
||||
{
|
||||
final int prime = 31;
|
||||
int result = 1;
|
||||
result = prime * result + ((biome == null) ? 0 : biome.hashCode());
|
||||
result = prime * result + height;
|
||||
result = prime * result + ((surface == null) ? 0 : surface.hashCode());
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj)
|
||||
{
|
||||
if(this == obj)
|
||||
return true;
|
||||
if(obj == null)
|
||||
return false;
|
||||
if(getClass() != obj.getClass())
|
||||
return false;
|
||||
IrisSample other = (IrisSample) obj;
|
||||
if(biome == null)
|
||||
{
|
||||
if(other.biome != null)
|
||||
return false;
|
||||
}
|
||||
else if(!biome.equals(other.biome))
|
||||
return false;
|
||||
if(height != other.height)
|
||||
return false;
|
||||
if(surface == null)
|
||||
{
|
||||
if(other.surface != null)
|
||||
return false;
|
||||
}
|
||||
else if(!surface.equals(other.surface))
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
}
|
@ -0,0 +1,202 @@
|
||||
package ninja.bytecode.iris.generator;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
import org.bukkit.World;
|
||||
import org.bukkit.block.data.BlockData;
|
||||
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
import ninja.bytecode.iris.Iris;
|
||||
import ninja.bytecode.iris.object.IrisBiome;
|
||||
import ninja.bytecode.iris.object.IrisObjectPlacement;
|
||||
import ninja.bytecode.iris.object.atomics.AtomicSliver;
|
||||
import ninja.bytecode.iris.object.atomics.AtomicSliverMap;
|
||||
import ninja.bytecode.iris.object.atomics.AtomicWorldData;
|
||||
import ninja.bytecode.iris.object.atomics.MasterLock;
|
||||
import ninja.bytecode.iris.util.BiomeMap;
|
||||
import ninja.bytecode.iris.util.ChunkPosition;
|
||||
import ninja.bytecode.iris.util.HeightMap;
|
||||
import ninja.bytecode.iris.util.IObjectPlacer;
|
||||
import ninja.bytecode.iris.util.RNG;
|
||||
import ninja.bytecode.shuriken.collections.KMap;
|
||||
|
||||
@Data
|
||||
@EqualsAndHashCode(callSuper = false)
|
||||
public abstract class ParallaxChunkGenerator extends TerrainChunkGenerator implements IObjectPlacer
|
||||
{
|
||||
private KMap<ChunkPosition, AtomicSliver> sliverCache;
|
||||
protected AtomicWorldData parallaxMap;
|
||||
private MasterLock masterLock;
|
||||
private int sliverBuffer;
|
||||
|
||||
public ParallaxChunkGenerator(String dimensionName, int threads)
|
||||
{
|
||||
super(dimensionName, threads);
|
||||
sliverCache = new KMap<>();
|
||||
sliverBuffer = 0;
|
||||
masterLock = new MasterLock();
|
||||
}
|
||||
|
||||
public void onInit(World world, RNG rng)
|
||||
{
|
||||
super.onInit(world, rng);
|
||||
parallaxMap = new AtomicWorldData(world);
|
||||
}
|
||||
|
||||
protected void onClose()
|
||||
{
|
||||
super.onClose();
|
||||
|
||||
try
|
||||
{
|
||||
parallaxMap.unloadAll(true);
|
||||
}
|
||||
|
||||
catch(IOException e)
|
||||
{
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getHighest(int x, int z)
|
||||
{
|
||||
return sampleSliver(x, z).getHighestBlock();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void set(int x, int y, int z, BlockData d)
|
||||
{
|
||||
getMasterLock().lock((x >> 4) + "." + (z >> 4));
|
||||
getParallaxSliver(x, z).set(y, d);
|
||||
getMasterLock().unlock((x >> 4) + "." + (z >> 4));
|
||||
}
|
||||
|
||||
@Override
|
||||
public BlockData get(int x, int y, int z)
|
||||
{
|
||||
BlockData b = sampleSliver(x, z).getBlock().get(y);
|
||||
return b == null ? AIR : b;
|
||||
}
|
||||
|
||||
public AtomicSliver getParallaxSliver(int wx, int wz)
|
||||
{
|
||||
getMasterLock().lock("gpc");
|
||||
getMasterLock().lock((wx >> 4) + "." + (wz >> 4));
|
||||
AtomicSliverMap map = getParallaxChunk(wx >> 4, wz >> 4);
|
||||
getMasterLock().unlock("gpc");
|
||||
AtomicSliver sliver = map.getSliver(wx & 15, wz & 15);
|
||||
getMasterLock().unlock((wx >> 4) + "." + (wz >> 4));
|
||||
|
||||
return sliver;
|
||||
}
|
||||
|
||||
public boolean isParallaxGenerated(int x, int z)
|
||||
{
|
||||
return getParallaxChunk(x, z).isParallaxGenerated();
|
||||
}
|
||||
|
||||
public boolean isWorldGenerated(int x, int z)
|
||||
{
|
||||
return getParallaxChunk(x, z).isWorldGenerated();
|
||||
}
|
||||
|
||||
public AtomicSliverMap getParallaxChunk(int x, int z)
|
||||
{
|
||||
try
|
||||
{
|
||||
return getParallaxMap().loadChunk(x, z);
|
||||
}
|
||||
|
||||
catch(IOException e)
|
||||
{
|
||||
fail(e);
|
||||
}
|
||||
|
||||
return new AtomicSliverMap();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onPostGenerate(RNG random, int x, int z, ChunkData data, BiomeGrid grid, HeightMap height, BiomeMap biomeMap)
|
||||
{
|
||||
biomeHitCache.clear();
|
||||
|
||||
if(getDimension().isPlaceObjects())
|
||||
{
|
||||
onGenerateParallax(random, x, z);
|
||||
getParallaxChunk(x, z).inject(data);
|
||||
setSliverBuffer(getSliverCache().size());
|
||||
getParallaxChunk(x, z).setWorldGenerated(true);
|
||||
getParallaxMap().clean(x + z);
|
||||
getSliverCache().clear();
|
||||
getMasterLock().clear();
|
||||
}
|
||||
}
|
||||
|
||||
protected void onGenerateParallax(RNG random, int x, int z)
|
||||
{
|
||||
String key = "par." + x + "." + "z";
|
||||
ChunkPosition rad = Iris.data.getObjectLoader().getParallaxSize();
|
||||
|
||||
for(int ii = x - (rad.getX() / 2); ii <= x + (rad.getX() / 2); ii++)
|
||||
{
|
||||
int i = ii;
|
||||
|
||||
for(int jj = z - (rad.getZ() / 2); jj <= z + (rad.getZ() / 2); jj++)
|
||||
{
|
||||
int j = jj;
|
||||
|
||||
if(isParallaxGenerated(ii, jj))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if(isWorldGenerated(ii, jj))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
getTx().queue(key, () ->
|
||||
{
|
||||
IrisBiome b = sampleTrueBiome((i * 16) + 7, (j * 16) + 7).getBiome();
|
||||
int g = 1;
|
||||
|
||||
for(IrisObjectPlacement k : b.getObjects())
|
||||
{
|
||||
placeObject(k, i, j, random.nextParallelRNG((34 * ((i * 30) + (j * 30) + g++) * i * j) + i - j + 3569222));
|
||||
}
|
||||
});
|
||||
|
||||
getParallaxChunk(ii, jj).setParallaxGenerated(true);
|
||||
}
|
||||
}
|
||||
|
||||
getTx().waitFor(key);
|
||||
}
|
||||
|
||||
protected void placeObject(IrisObjectPlacement o, int x, int z, RNG rng)
|
||||
{
|
||||
for(int i = 0; i < o.getTriesForChunk(rng); i++)
|
||||
{
|
||||
rng = rng.nextParallelRNG((i * 3 + 8) - 23040);
|
||||
o.getSchematic(rng).place((x * 16) + rng.nextInt(16), (z * 16) + rng.nextInt(16), this, o, rng);
|
||||
}
|
||||
}
|
||||
|
||||
public AtomicSliver sampleSliver(int x, int z)
|
||||
{
|
||||
ChunkPosition key = new ChunkPosition(x, z);
|
||||
|
||||
if(sliverCache.containsKey(key))
|
||||
{
|
||||
return sliverCache.get(key);
|
||||
}
|
||||
|
||||
AtomicSliver s = new AtomicSliver(x & 15, z & 15);
|
||||
onGenerateColumn(x >> 4, z >> 4, x, z, x & 15, z & 15, s, null);
|
||||
sliverCache.put(key, s);
|
||||
|
||||
return s;
|
||||
}
|
||||
}
|
@ -0,0 +1,99 @@
|
||||
package ninja.bytecode.iris.generator;
|
||||
|
||||
import org.bukkit.World;
|
||||
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
import ninja.bytecode.iris.Iris;
|
||||
import ninja.bytecode.iris.object.atomics.AtomicSliver;
|
||||
import ninja.bytecode.iris.object.atomics.AtomicSliverMap;
|
||||
import ninja.bytecode.iris.util.BiomeMap;
|
||||
import ninja.bytecode.iris.util.GroupedExecutor;
|
||||
import ninja.bytecode.iris.util.HeightMap;
|
||||
import ninja.bytecode.iris.util.RNG;
|
||||
|
||||
@Data
|
||||
@EqualsAndHashCode(callSuper = false)
|
||||
public abstract class ParallelChunkGenerator extends BiomeChunkGenerator
|
||||
{
|
||||
private GroupedExecutor tx;
|
||||
private int threads;
|
||||
|
||||
public ParallelChunkGenerator(String dimensionName, int threads)
|
||||
{
|
||||
super(dimensionName);
|
||||
this.threads = threads;
|
||||
}
|
||||
|
||||
public void changeThreadCount(int tc)
|
||||
{
|
||||
threads = tc;
|
||||
GroupedExecutor e = tx;
|
||||
tx = new GroupedExecutor(threads, Thread.NORM_PRIORITY, "Iris Generator - " + world.getName());
|
||||
Iris.executors.add(tx);
|
||||
|
||||
if(e != null)
|
||||
{
|
||||
e.close();
|
||||
}
|
||||
}
|
||||
|
||||
protected abstract void onGenerateColumn(int cx, int cz, int wx, int wz, int x, int z, AtomicSliver sliver, BiomeMap biomeMap);
|
||||
|
||||
protected abstract int onSampleColumnHeight(int cx, int cz, int wx, int wz, int x, int z);
|
||||
|
||||
protected abstract void onPostGenerate(RNG random, int x, int z, ChunkData data, BiomeGrid grid, HeightMap height, BiomeMap biomeMap);
|
||||
|
||||
protected int sampleHeight(int x, int z)
|
||||
{
|
||||
return onSampleColumnHeight(x >> 4, z >> 4, x, z, x & 15, z & 15);
|
||||
}
|
||||
|
||||
protected void onGenerate(RNG random, int x, int z, ChunkData data, BiomeGrid grid)
|
||||
{
|
||||
AtomicSliverMap map = new AtomicSliverMap();
|
||||
HeightMap height = new HeightMap();
|
||||
String key = "c" + x + "," + z;
|
||||
BiomeMap biomeMap = new BiomeMap();
|
||||
int ii, jj;
|
||||
|
||||
for(ii = 0; ii < 16; ii++)
|
||||
{
|
||||
int i = ii;
|
||||
int wx = (x * 16) + i;
|
||||
|
||||
for(jj = 0; jj < 16; jj++)
|
||||
{
|
||||
int j = jj;
|
||||
int wz = (z * 16) + j;
|
||||
AtomicSliver sliver = map.getSliver(i, j);
|
||||
|
||||
tx.queue(key, () ->
|
||||
{
|
||||
onGenerateColumn(x, z, wx, wz, i, j, sliver, biomeMap);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
tx.waitFor(key);
|
||||
map.write(data, grid, height);
|
||||
onPostGenerate(random, x, z, data, grid, height, biomeMap);
|
||||
}
|
||||
|
||||
protected void onClose()
|
||||
{
|
||||
tx.close();
|
||||
}
|
||||
|
||||
public void onInit(World world, RNG rng)
|
||||
{
|
||||
super.onInit(world, rng);
|
||||
changeThreadCount(threads);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isParallelCapable()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
@ -0,0 +1,306 @@
|
||||
package ninja.bytecode.iris.generator;
|
||||
|
||||
import java.util.concurrent.locks.ReentrantLock;
|
||||
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.World;
|
||||
import org.bukkit.block.Block;
|
||||
import org.bukkit.block.data.Bisected;
|
||||
import org.bukkit.block.data.Bisected.Half;
|
||||
import org.bukkit.block.data.BlockData;
|
||||
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
import ninja.bytecode.iris.object.IrisBiome;
|
||||
import ninja.bytecode.iris.object.IrisBiomeDecorator;
|
||||
import ninja.bytecode.iris.object.IrisRegion;
|
||||
import ninja.bytecode.iris.object.atomics.AtomicSliver;
|
||||
import ninja.bytecode.iris.util.BiomeMap;
|
||||
import ninja.bytecode.iris.util.BiomeResult;
|
||||
import ninja.bytecode.iris.util.BlockPosition;
|
||||
import ninja.bytecode.iris.util.RNG;
|
||||
import ninja.bytecode.shuriken.collections.KList;
|
||||
import ninja.bytecode.shuriken.math.M;
|
||||
|
||||
@Data
|
||||
@EqualsAndHashCode(callSuper = false)
|
||||
public abstract class TerrainChunkGenerator extends ParallelChunkGenerator
|
||||
{
|
||||
protected static final BlockData AIR = Material.AIR.createBlockData();
|
||||
protected static final BlockData STONE = Material.STONE.createBlockData();
|
||||
protected static final BlockData WATER = Material.WATER.createBlockData();
|
||||
private KList<BlockPosition> updateBlocks = new KList<>();
|
||||
private ReentrantLock relightLock = new ReentrantLock();
|
||||
private long lastUpdateRequest = M.ms();
|
||||
private long lastChunkLoad = M.ms();
|
||||
|
||||
public TerrainChunkGenerator(String dimensionName, int threads)
|
||||
{
|
||||
super(dimensionName, threads);
|
||||
}
|
||||
|
||||
public void onInit(World world, RNG rng)
|
||||
{
|
||||
super.onInit(world, rng);
|
||||
}
|
||||
|
||||
public void queueUpdate(int x, int y, int z)
|
||||
{
|
||||
if(M.ms() - lastUpdateRequest > 3000 && M.ms() - lastChunkLoad > 3000)
|
||||
{
|
||||
updateBlocks.clear();
|
||||
}
|
||||
|
||||
updateBlocks.add(new BlockPosition(x, y, z));
|
||||
lastUpdateRequest = M.ms();
|
||||
}
|
||||
|
||||
public void updateLights()
|
||||
{
|
||||
if(M.ms() - lastUpdateRequest > 3000 && M.ms() - lastChunkLoad > 3000)
|
||||
{
|
||||
updateBlocks.clear();
|
||||
}
|
||||
|
||||
for(BlockPosition i : updateBlocks.copy())
|
||||
{
|
||||
if(getWorld().isChunkLoaded(i.getChunkX(), i.getChunkZ()))
|
||||
{
|
||||
updateBlocks.remove(i);
|
||||
Block b = getWorld().getBlockAt(i.getX(), i.getY(), i.getZ());
|
||||
BlockData bd = b.getBlockData();
|
||||
b.setBlockData(AIR, false);
|
||||
b.setBlockData(bd, true);
|
||||
}
|
||||
}
|
||||
|
||||
while(updateBlocks.size() > 5000)
|
||||
{
|
||||
updateBlocks.remove(0);
|
||||
}
|
||||
|
||||
lastChunkLoad = M.ms();
|
||||
}
|
||||
|
||||
public void checkUnderwater(int x, int y, int z, BlockData d)
|
||||
{
|
||||
if(d.getMaterial().equals(Material.SEA_PICKLE) || d.getMaterial().equals(Material.SOUL_SAND) || d.getMaterial().equals(Material.MAGMA_BLOCK))
|
||||
{
|
||||
queueUpdate(x, y, z);
|
||||
}
|
||||
}
|
||||
|
||||
public void checkSurface(int x, int y, int z, BlockData d)
|
||||
{
|
||||
if(d.getMaterial().equals(Material.SEA_PICKLE) || d.getMaterial().equals(Material.TORCH) || d.getMaterial().equals(Material.REDSTONE_TORCH) || d.getMaterial().equals(Material.TORCH))
|
||||
{
|
||||
queueUpdate(x, y, z);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onGenerateColumn(int cx, int cz, int rx, int rz, int x, int z, AtomicSliver sliver, BiomeMap biomeMap)
|
||||
{
|
||||
try
|
||||
{
|
||||
BlockData block;
|
||||
int fluidHeight = getDimension().getFluidHeight();
|
||||
double ox = getModifiedX(rx, rz);
|
||||
double oz = getModifiedZ(rx, rz);
|
||||
double wx = getZoomed(ox);
|
||||
double wz = getZoomed(oz);
|
||||
int depth = 0;
|
||||
double noise = getNoiseHeight(rx, rz);
|
||||
int height = (int) Math.round(noise) + fluidHeight;
|
||||
IrisBiome biome = sampleTrueBiome(rx, rz).getBiome();
|
||||
KList<BlockData> layers = biome.generateLayers(wx, wz, masterRandom, height);
|
||||
|
||||
for(int k = Math.max(height, fluidHeight); k < 255; k++)
|
||||
{
|
||||
if(k < Math.max(height, fluidHeight) + 3)
|
||||
{
|
||||
if(biomeMap != null)
|
||||
{
|
||||
sliver.set(k, biome.getGroundBiome(masterRandom, rz, k, rx));
|
||||
}
|
||||
}
|
||||
|
||||
else
|
||||
{
|
||||
if(biomeMap != null)
|
||||
{
|
||||
sliver.set(k, biome.getSkyBiome(masterRandom, rx, k, rz));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for(int k = Math.max(height, fluidHeight); k >= 0; k--)
|
||||
{
|
||||
boolean underwater = k > height && k <= fluidHeight;
|
||||
|
||||
if(biomeMap != null)
|
||||
{
|
||||
sliver.set(k, biome.getGroundBiome(masterRandom, rz, k, rx));
|
||||
biomeMap.setBiome(x, z, biome);
|
||||
}
|
||||
|
||||
if(underwater)
|
||||
{
|
||||
block = WATER;
|
||||
}
|
||||
|
||||
else
|
||||
{
|
||||
block = layers.hasIndex(depth) ? layers.get(depth) : STONE;
|
||||
depth++;
|
||||
}
|
||||
|
||||
sliver.set(k, block);
|
||||
|
||||
if(k == height && block.getMaterial().isSolid() && k < fluidHeight && biome.isSea())
|
||||
{
|
||||
int j = 0;
|
||||
|
||||
for(IrisBiomeDecorator i : biome.getDecorators())
|
||||
{
|
||||
BlockData d = i.getBlockData(getMasterRandom().nextParallelRNG(biome.hashCode() + j++), wx, wz);
|
||||
|
||||
if(d != null)
|
||||
{
|
||||
int stack = i.getHeight(getMasterRandom().nextParallelRNG(39456 + i.hashCode()), wx, wz);
|
||||
|
||||
if(stack == 1)
|
||||
{
|
||||
sliver.set(k + 1, d);
|
||||
checkUnderwater(rx, k + 1, rz, d);
|
||||
}
|
||||
|
||||
else if(k < fluidHeight - stack)
|
||||
{
|
||||
for(int l = 0; l < stack; l++)
|
||||
{
|
||||
sliver.set(k + l + 1, d);
|
||||
checkUnderwater(rx, k + l + 1, rz, d);
|
||||
}
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if(k == Math.max(height, fluidHeight) && block.getMaterial().isSolid() && k < 255 && !biome.isSea())
|
||||
{
|
||||
int j = 0;
|
||||
|
||||
for(IrisBiomeDecorator i : biome.getDecorators())
|
||||
{
|
||||
BlockData d = i.getBlockData(getMasterRandom().nextParallelRNG(biome.hashCode() + j++), wx, wz);
|
||||
|
||||
if(d != null)
|
||||
{
|
||||
if(d instanceof Bisected && k < 254)
|
||||
{
|
||||
Bisected t = ((Bisected) d.clone());
|
||||
t.setHalf(Half.TOP);
|
||||
Bisected b = ((Bisected) d.clone());
|
||||
b.setHalf(Half.BOTTOM);
|
||||
sliver.set(k + 1, b);
|
||||
sliver.set(k + 2, t);
|
||||
}
|
||||
|
||||
else
|
||||
{
|
||||
int stack = i.getHeight(getMasterRandom().nextParallelRNG(39456 + i.hashCode()), wx, wz);
|
||||
|
||||
if(stack == 1)
|
||||
{
|
||||
sliver.set(k + 1, d);
|
||||
}
|
||||
|
||||
else if(k < 255 - stack)
|
||||
{
|
||||
for(int l = 0; l < stack; l++)
|
||||
{
|
||||
sliver.set(k + l + 1, d);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
catch(Throwable e)
|
||||
{
|
||||
fail(e);
|
||||
}
|
||||
}
|
||||
|
||||
protected double getNoiseHeight(int rx, int rz)
|
||||
{
|
||||
double wx = getZoomed(rx);
|
||||
double wz = getZoomed(rz);
|
||||
|
||||
return getBiomeHeight(wx, wz);
|
||||
}
|
||||
|
||||
public BiomeResult sampleTrueBiome(int x, int z)
|
||||
{
|
||||
if(!getDimension().getFocus().equals(""))
|
||||
{
|
||||
return focus();
|
||||
}
|
||||
|
||||
double wx = getModifiedX(x, z);
|
||||
double wz = getModifiedZ(x, z);
|
||||
IrisRegion region = sampleRegion(x, z);
|
||||
int height = sampleHeight(x, z);
|
||||
double sh = region.getShoreHeight(wx, wz);
|
||||
IrisBiome current = sampleBiome(x, z).getBiome();
|
||||
|
||||
// Stop shores from spawning on land
|
||||
if(current.isShore() && height > sh)
|
||||
{
|
||||
return glBiome.generateLandData(wx, wz, x, z, region);
|
||||
}
|
||||
|
||||
// Stop land & shore from spawning underwater
|
||||
if(current.isShore() || current.isLand() && height <= getDimension().getFluidHeight())
|
||||
{
|
||||
return glBiome.generateSeaData(wx, wz, x, z, region);
|
||||
}
|
||||
|
||||
// Stop oceans from spawning on land
|
||||
if(current.isSea() && height > getDimension().getFluidHeight())
|
||||
{
|
||||
return glBiome.generateLandData(wx, wz, x, z, region);
|
||||
}
|
||||
|
||||
// Stop land from spawning underwater
|
||||
if(height <= getDimension().getFluidHeight())
|
||||
{
|
||||
return glBiome.generateSeaData(wx, wz, x, z, region);
|
||||
}
|
||||
|
||||
// Stop land from spawning where shores go
|
||||
if(height <= getDimension().getFluidHeight() + sh)
|
||||
{
|
||||
return glBiome.generateShoreData(wx, wz, x, z, region);
|
||||
}
|
||||
|
||||
return glBiome.generateRegionData(wx, wz, x, z, region);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected int onSampleColumnHeight(int cx, int cz, int rx, int rz, int x, int z)
|
||||
{
|
||||
int fluidHeight = getDimension().getFluidHeight();
|
||||
double noise = getNoiseHeight(rx, rz);
|
||||
|
||||
return (int) Math.round(noise) + fluidHeight;
|
||||
}
|
||||
}
|
@ -1,105 +0,0 @@
|
||||
package ninja.bytecode.iris.generator;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.function.Consumer;
|
||||
|
||||
import org.bukkit.Chunk;
|
||||
import org.bukkit.World;
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
import mortar.api.nms.NMP;
|
||||
import mortar.api.sched.J;
|
||||
import mortar.compute.math.M;
|
||||
import mortar.lang.collection.FinalDouble;
|
||||
import ninja.bytecode.iris.Iris;
|
||||
import ninja.bytecode.iris.util.ChronoQueue;
|
||||
import ninja.bytecode.iris.util.ObjectMode;
|
||||
import ninja.bytecode.iris.util.SMCAVector;
|
||||
import ninja.bytecode.shuriken.collections.KList;
|
||||
import ninja.bytecode.shuriken.collections.KMap;
|
||||
|
||||
public class WorldReactor
|
||||
{
|
||||
private static KList<ChronoQueue> q = new KList<>();
|
||||
private final World world;
|
||||
|
||||
public WorldReactor(World world)
|
||||
{
|
||||
this.world = world;
|
||||
}
|
||||
|
||||
public void generateRegionNormal(Player p, boolean force, double mst, Consumer<Double> progress, Runnable done)
|
||||
{
|
||||
for(ChronoQueue i : WorldReactor.q)
|
||||
{
|
||||
i.close();
|
||||
}
|
||||
|
||||
WorldReactor.q.clear();
|
||||
|
||||
ChronoQueue q = new ChronoQueue(mst, 10240);
|
||||
WorldReactor.q.add(q);
|
||||
FinalDouble of = new FinalDouble(0D);
|
||||
FinalDouble max = new FinalDouble(0D);
|
||||
KMap<SMCAVector, Double> d = new KMap<>();
|
||||
int mx = p.getLocation().getChunk().getX();
|
||||
int mz = p.getLocation().getChunk().getZ();
|
||||
for(int xx = p.getLocation().getChunk().getX() - 32; xx < p.getLocation().getChunk().getX() + 32; xx++)
|
||||
{
|
||||
int x = xx;
|
||||
|
||||
for(int zz = p.getLocation().getChunk().getZ() - 32; zz < p.getLocation().getChunk().getZ() + 32; zz++)
|
||||
{
|
||||
int z = zz;
|
||||
|
||||
if(world.isChunkLoaded(x, z) || world.loadChunk(x, z, false))
|
||||
{
|
||||
d.put(new SMCAVector(x, z), Math.sqrt(Math.pow(x - mx, 2) + Math.pow(z - mz, 2)));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
KList<SMCAVector> v = d.k();
|
||||
Collections.sort(v, (a, b) -> (int) (10000 * (d.get(a) - d.get(b))));
|
||||
|
||||
for(SMCAVector i : v)
|
||||
{
|
||||
int x = i.getX();
|
||||
int z = i.getZ();
|
||||
|
||||
if(Iris.settings.performance.objectMode.equals(ObjectMode.PARALLAX) && world.getGenerator() instanceof IrisGenerator)
|
||||
{
|
||||
IrisGenerator gg = ((IrisGenerator) world.getGenerator());
|
||||
gg.getWorldData().deleteChunk(x, z);
|
||||
}
|
||||
|
||||
max.add(1);
|
||||
q.queue(() ->
|
||||
{
|
||||
world.regenerateChunk(x, z);
|
||||
|
||||
Chunk cc = world.getChunkAt(x, z);
|
||||
NMP.host.relight(cc);
|
||||
of.add(1);
|
||||
|
||||
if(of.get() == max.get())
|
||||
{
|
||||
progress.accept(1D);
|
||||
q.dieSlowly();
|
||||
done.run();
|
||||
}
|
||||
|
||||
else
|
||||
{
|
||||
progress.accept(M.clip(of.get() / max.get(), 0D, 1D));
|
||||
}
|
||||
|
||||
});
|
||||
}
|
||||
|
||||
J.s(() ->
|
||||
{
|
||||
q.dieSlowly();
|
||||
}, 20);
|
||||
}
|
||||
}
|
@ -1,83 +0,0 @@
|
||||
package ninja.bytecode.iris.generator.atomics;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.lang.reflect.Field;
|
||||
|
||||
import sun.misc.Unsafe;
|
||||
|
||||
@SuppressWarnings("restriction")
|
||||
public class AtomicCharArray implements Serializable
|
||||
{
|
||||
private static final long serialVersionUID = 2862133569453604235L;
|
||||
private static final Unsafe unsafe;
|
||||
private static final int base;
|
||||
private static final int shift;
|
||||
volatile char[] array;
|
||||
|
||||
public AtomicCharArray(int var1)
|
||||
{
|
||||
this.array = new char[var1];
|
||||
}
|
||||
|
||||
private long checkedByteOffset(int var1)
|
||||
{
|
||||
if(var1 >= 0 && var1 < this.array.length)
|
||||
{
|
||||
return byteOffset(var1);
|
||||
}
|
||||
else
|
||||
{
|
||||
throw new IndexOutOfBoundsException("index " + var1);
|
||||
}
|
||||
}
|
||||
|
||||
public final char get(int var1)
|
||||
{
|
||||
return this.getRaw(this.checkedByteOffset(var1));
|
||||
}
|
||||
|
||||
private char getRaw(long var1)
|
||||
{
|
||||
return unsafe.getCharVolatile(this.array, var1);
|
||||
}
|
||||
|
||||
public final void set(int var1, char var2)
|
||||
{
|
||||
unsafe.putCharVolatile(this.array, this.checkedByteOffset(var1), var2);
|
||||
}
|
||||
|
||||
private static long byteOffset(int var0)
|
||||
{
|
||||
return ((long) var0 << shift) + (long) base;
|
||||
}
|
||||
|
||||
static
|
||||
{
|
||||
Field f;
|
||||
Unsafe o = null;
|
||||
|
||||
try
|
||||
{
|
||||
f = Unsafe.class.getDeclaredField("theUnsafe");
|
||||
f.setAccessible(true);
|
||||
o = (Unsafe) f.get(null);
|
||||
}
|
||||
|
||||
catch(Throwable e)
|
||||
{
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
unsafe = o;
|
||||
base = unsafe.arrayBaseOffset(int[].class);
|
||||
int var0 = unsafe.arrayIndexScale(int[].class);
|
||||
if((var0 & var0 - 1) != 0)
|
||||
{
|
||||
throw new Error("data type scale not a power of two");
|
||||
}
|
||||
else
|
||||
{
|
||||
shift = 31 - Integer.numberOfLeadingZeros(var0);
|
||||
}
|
||||
}
|
||||
}
|
@ -1,456 +0,0 @@
|
||||
package ninja.bytecode.iris.generator.atomics;
|
||||
|
||||
import java.io.DataInputStream;
|
||||
import java.io.DataOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.OutputStream;
|
||||
import java.lang.reflect.Field;
|
||||
import java.util.concurrent.locks.ReentrantLock;
|
||||
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.World;
|
||||
import org.bukkit.craftbukkit.v1_12_R1.generator.CraftChunkData;
|
||||
import org.bukkit.generator.ChunkGenerator;
|
||||
import org.bukkit.generator.ChunkGenerator.ChunkData;
|
||||
import org.bukkit.material.MaterialData;
|
||||
|
||||
import mortar.compute.math.M;
|
||||
import ninja.bytecode.iris.util.MB;
|
||||
|
||||
public final class AtomicChunkData implements ChunkGenerator.ChunkData
|
||||
{
|
||||
private static final Field t;
|
||||
private static final Field[] sections;
|
||||
private static final int h = 0x1000;
|
||||
private final int maxHeight;
|
||||
private static ReentrantLock[] locks;
|
||||
private char[] s0;
|
||||
private char[] s1;
|
||||
private char[] s2;
|
||||
private char[] s3;
|
||||
private char[] s4;
|
||||
private char[] s5;
|
||||
private char[] s6;
|
||||
private char[] s7;
|
||||
private char[] s8;
|
||||
private char[] s9;
|
||||
private char[] s10;
|
||||
private char[] s11;
|
||||
private char[] s12;
|
||||
private char[] s13;
|
||||
private char[] s14;
|
||||
private char[] s15;
|
||||
private char[][] m;
|
||||
private World w;
|
||||
private long lastUse;
|
||||
private int bits;
|
||||
|
||||
public AtomicChunkData(World world)
|
||||
{
|
||||
this.maxHeight = world.getMaxHeight();
|
||||
this.w = world;
|
||||
bits = 0;
|
||||
lastUse = M.ms();
|
||||
}
|
||||
|
||||
public long getTimeSinceLastUse()
|
||||
{
|
||||
return M.ms() - lastUse;
|
||||
}
|
||||
|
||||
public void read(InputStream in) throws IOException
|
||||
{
|
||||
read(in, true);
|
||||
}
|
||||
|
||||
public void read(InputStream in, boolean ignoreAir) throws IOException
|
||||
{
|
||||
DataInputStream din = new DataInputStream(in);
|
||||
int bits = din.readInt();
|
||||
|
||||
for(int i = 0; i < 16; i++)
|
||||
{
|
||||
int bit = getBit(i);
|
||||
if((bits & bit) == bit)
|
||||
{
|
||||
char[] section = getChunkSection(i << 4, true);
|
||||
|
||||
for(int j = 0; j < section.length; j++)
|
||||
{
|
||||
char c = din.readChar();
|
||||
|
||||
if(c == 0 && ignoreAir)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
section[j] = c;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
din.close();
|
||||
}
|
||||
|
||||
public void write(OutputStream out) throws IOException
|
||||
{
|
||||
DataOutputStream dos = new DataOutputStream(out);
|
||||
dos.writeInt(getDataBits());
|
||||
|
||||
for(int i = 0; i < 16; i++)
|
||||
{
|
||||
if(hasDataBit(i))
|
||||
{
|
||||
char[] section = getChunkSection(i << 4, false);
|
||||
for(int j = 0; j < section.length; j++)
|
||||
{
|
||||
dos.writeChar(section[j]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
dos.close();
|
||||
}
|
||||
|
||||
public boolean hasDataBit(int section)
|
||||
{
|
||||
int b = getBit(section);
|
||||
return (bits & b) == b;
|
||||
}
|
||||
|
||||
public void clearDataBits()
|
||||
{
|
||||
bits = 0;
|
||||
}
|
||||
|
||||
public void addDataBit(int section)
|
||||
{
|
||||
bits |= getBit(section);
|
||||
}
|
||||
|
||||
public void removeDataBit(int section)
|
||||
{
|
||||
bits ^= getBit(section);
|
||||
}
|
||||
|
||||
public int getDataBits()
|
||||
{
|
||||
return bits;
|
||||
}
|
||||
|
||||
public int getBit(int index)
|
||||
{
|
||||
return (int) (index < 0 ? -1 : Math.pow(2, index));
|
||||
}
|
||||
|
||||
public int computeDataBits()
|
||||
{
|
||||
int bits = 0;
|
||||
|
||||
for(int i = 0; i < 16; i++)
|
||||
{
|
||||
try
|
||||
{
|
||||
bits |= sections[i].get(this) != null ? getBit(i) : 0;
|
||||
}
|
||||
|
||||
catch(Throwable e)
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
return bits;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getMaxHeight()
|
||||
{
|
||||
return maxHeight;
|
||||
}
|
||||
|
||||
@SuppressWarnings("deprecation")
|
||||
@Override
|
||||
public void setBlock(int x, int y, int z, Material material)
|
||||
{
|
||||
setBlock(x, y, z, material.getId());
|
||||
}
|
||||
|
||||
@SuppressWarnings("deprecation")
|
||||
@Override
|
||||
public void setBlock(int x, int y, int z, MaterialData material)
|
||||
{
|
||||
setBlock(x, y, z, material.getItemTypeId(), material.getData());
|
||||
}
|
||||
|
||||
@SuppressWarnings("deprecation")
|
||||
@Override
|
||||
public void setRegion(int xMin, int yMin, int zMin, int xMax, int yMax, int zMax, Material material)
|
||||
{
|
||||
setRegion(xMin, yMin, zMin, xMax, yMax, zMax, material.getId());
|
||||
}
|
||||
|
||||
@SuppressWarnings("deprecation")
|
||||
@Override
|
||||
public void setRegion(int xMin, int yMin, int zMin, int xMax, int yMax, int zMax, MaterialData material)
|
||||
{
|
||||
setRegion(xMin, yMin, zMin, xMax, yMax, zMax, material.getItemTypeId(), material.getData());
|
||||
}
|
||||
|
||||
@SuppressWarnings("deprecation")
|
||||
@Override
|
||||
public Material getType(int x, int y, int z)
|
||||
{
|
||||
lastUse = M.ms();
|
||||
return Material.getMaterial(getTypeId(x, y, z));
|
||||
}
|
||||
|
||||
@SuppressWarnings("deprecation")
|
||||
@Override
|
||||
public MaterialData getTypeAndData(int x, int y, int z)
|
||||
{
|
||||
lastUse = M.ms();
|
||||
return getType(x, y, z).getNewData(getData(x, y, z));
|
||||
}
|
||||
|
||||
@SuppressWarnings("deprecation")
|
||||
public void setBlock(int x, int y, int z, Material blockId, byte data)
|
||||
{
|
||||
setBlock(x, y, z, blockId.getId(), data);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setRegion(int xMin, int yMin, int zMin, int xMax, int yMax, int zMax, int blockId)
|
||||
{
|
||||
lastUse = M.ms();
|
||||
setRegion(xMin, yMin, zMin, xMax, yMax, zMax, blockId, (byte) 0);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setRegion(int xMin, int yMin, int zMin, int xMax, int yMax, int zMax, int blockId, int data)
|
||||
{
|
||||
lastUse = M.ms();
|
||||
throw new UnsupportedOperationException("AtomicChunkData does not support setting regions");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setBlock(int x, int y, int z, int blockId)
|
||||
{
|
||||
setBlock(x, y, z, blockId, (byte) 0);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setBlock(int x, int y, int z, int blockId, byte data)
|
||||
{
|
||||
setBlock(x, y, z, (char) (blockId << 4 | data));
|
||||
}
|
||||
|
||||
@SuppressWarnings("deprecation")
|
||||
public MB getMB(int x, int y, int z)
|
||||
{
|
||||
if(x != (x & 0xf) || y < 0 || y >= maxHeight || z != (z & 0xf))
|
||||
{
|
||||
lastUse = M.ms();
|
||||
return MB.of(Material.AIR);
|
||||
}
|
||||
|
||||
char[] section = getChunkSection(y, false);
|
||||
|
||||
if(section == null)
|
||||
{
|
||||
lastUse = M.ms();
|
||||
return MB.of(Material.AIR);
|
||||
}
|
||||
|
||||
else
|
||||
{
|
||||
lastUse = M.ms();
|
||||
char xf = section[(y & 0xf) << 8 | z << 4 | x];
|
||||
return MB.of(Material.getMaterial(xf >> 4), xf & 0xf);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getTypeId(int x, int y, int z)
|
||||
{
|
||||
if(x != (x & 0xf) || y < 0 || y >= maxHeight || z != (z & 0xf))
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
char[] section = getChunkSection(y, false);
|
||||
|
||||
if(section == null)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
else
|
||||
{
|
||||
lastUse = M.ms();
|
||||
return section[(y & 0xf) << 8 | z << 4 | x] >> 4;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public byte getData(int x, int y, int z)
|
||||
{
|
||||
if(x != (x & 0xf) || y < 0 || y >= maxHeight || z != (z & 0xf))
|
||||
{
|
||||
lastUse = M.ms();
|
||||
return (byte) 0;
|
||||
}
|
||||
|
||||
char[] section = getChunkSection(y, false);
|
||||
|
||||
if(section == null)
|
||||
{
|
||||
lastUse = M.ms();
|
||||
return (byte) 0;
|
||||
}
|
||||
|
||||
else
|
||||
{
|
||||
lastUse = M.ms();
|
||||
return (byte) (section[(y & 0xf) << 8 | z << 4 | x] & 0xf);
|
||||
}
|
||||
}
|
||||
|
||||
private void setBlock(int x, int y, int z, char type)
|
||||
{
|
||||
if(x != (x & 0xf) || y < 0 || y >= maxHeight || z != (z & 0xf))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
lastUse = M.ms();
|
||||
ReentrantLock l = locks[y >> 4];
|
||||
l.lock();
|
||||
getChunkSection(y, true)[(y & 0xf) << 8 | z << 4 | x] = type;
|
||||
l.unlock();
|
||||
}
|
||||
|
||||
private char[] getChunkSection(int y, boolean c)
|
||||
{
|
||||
try
|
||||
{
|
||||
int s = y >> 4;
|
||||
Field sf = sections[s];
|
||||
char[] section = (char[]) sf.get(this);
|
||||
|
||||
if(section == null && c)
|
||||
{
|
||||
sf.set(this, new char[h]);
|
||||
section = (char[]) sf.get(this);
|
||||
addDataBit(s);
|
||||
}
|
||||
|
||||
return section;
|
||||
}
|
||||
|
||||
catch(Throwable e)
|
||||
{
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public ChunkData toChunkData()
|
||||
{
|
||||
ChunkData c = new CraftChunkData(w);
|
||||
|
||||
try
|
||||
{
|
||||
m = (char[][]) t.get(c);
|
||||
m[0] = s0;
|
||||
m[1] = s1;
|
||||
m[2] = s2;
|
||||
m[3] = s3;
|
||||
m[4] = s4;
|
||||
m[5] = s5;
|
||||
m[6] = s6;
|
||||
m[7] = s7;
|
||||
m[8] = s8;
|
||||
m[9] = s9;
|
||||
m[10] = s10;
|
||||
m[11] = s11;
|
||||
m[12] = s12;
|
||||
m[13] = s13;
|
||||
m[14] = s14;
|
||||
m[15] = s15;
|
||||
}
|
||||
|
||||
catch(IllegalArgumentException | IllegalAccessException e)
|
||||
{
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
return c;
|
||||
}
|
||||
|
||||
static
|
||||
{
|
||||
locks = new ReentrantLock[16];
|
||||
Field[] s = new Field[16];
|
||||
|
||||
for(int i = 0; i < 16; i++)
|
||||
{
|
||||
try
|
||||
{
|
||||
s[i] = AtomicChunkData.class.getDeclaredField("s" + i);
|
||||
locks[i] = new ReentrantLock();
|
||||
}
|
||||
|
||||
catch(Throwable e)
|
||||
{
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
sections = s;
|
||||
|
||||
Field x = null;
|
||||
|
||||
try
|
||||
{
|
||||
x = CraftChunkData.class.getDeclaredField("sections");
|
||||
x.setAccessible(true);
|
||||
}
|
||||
|
||||
catch(Throwable e)
|
||||
{
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
t = x;
|
||||
}
|
||||
|
||||
public void inject(AtomicChunkData data)
|
||||
{
|
||||
for(int i = 0; i < 16; i++)
|
||||
{
|
||||
if(hasDataBit(i))
|
||||
{
|
||||
char[] fromSection = getChunkSection(i << 4, false);
|
||||
char[] toSection = data.getChunkSection(i << 4, true);
|
||||
|
||||
for(int j = 0; j < fromSection.length; j++)
|
||||
{
|
||||
char x = fromSection[j];
|
||||
|
||||
if(x != 0)
|
||||
{
|
||||
toSection[j] = x;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void setBlock(int x, int y, int z, MB mb)
|
||||
{
|
||||
setBlock(x, y, z, mb.material, mb.data);
|
||||
}
|
||||
}
|
@ -1,158 +0,0 @@
|
||||
package ninja.bytecode.iris.generator.atomics;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.IOException;
|
||||
|
||||
import org.bukkit.World;
|
||||
|
||||
import ninja.bytecode.iris.util.SMCAVector;
|
||||
import ninja.bytecode.shuriken.collections.KList;
|
||||
import ninja.bytecode.shuriken.collections.KMap;
|
||||
|
||||
public class AtomicWorldData
|
||||
{
|
||||
private World world;
|
||||
private KMap<SMCAVector, AtomicRegionData> loadedSections;
|
||||
|
||||
public AtomicWorldData(World world)
|
||||
{
|
||||
this.world = world;
|
||||
loadedSections = new KMap<>();
|
||||
getSubregionFolder().mkdirs();
|
||||
}
|
||||
|
||||
public KList<SMCAVector> getLoadedRegions()
|
||||
{
|
||||
return loadedSections.k();
|
||||
}
|
||||
|
||||
public AtomicRegionData getSubregion(int x, int z) throws IOException
|
||||
{
|
||||
if(!isSectionLoaded(x, z))
|
||||
{
|
||||
loadedSections.put(new SMCAVector(x, z), loadSection(x, z));
|
||||
}
|
||||
|
||||
AtomicRegionData f = loadedSections.get(new SMCAVector(x, z));
|
||||
|
||||
return f;
|
||||
}
|
||||
|
||||
public void saveAll() throws IOException
|
||||
{
|
||||
for(SMCAVector i : loadedSections.keySet())
|
||||
{
|
||||
saveSection(i);
|
||||
}
|
||||
}
|
||||
|
||||
public void unloadAll(boolean save) throws IOException
|
||||
{
|
||||
for(SMCAVector i : loadedSections.keySet())
|
||||
{
|
||||
unloadSection(i, save);
|
||||
}
|
||||
}
|
||||
|
||||
public void deleteSection(int x, int z) throws IOException
|
||||
{
|
||||
unloadSection(x, z, false);
|
||||
getSubregionFile(x, z).delete();
|
||||
}
|
||||
|
||||
public boolean isSectionLoaded(int x, int z)
|
||||
{
|
||||
return isSectionLoaded(new SMCAVector(x, z));
|
||||
}
|
||||
|
||||
public boolean isSectionLoaded(SMCAVector s)
|
||||
{
|
||||
return loadedSections.containsKey(s);
|
||||
}
|
||||
|
||||
public boolean unloadSection(int x, int z, boolean save) throws IOException
|
||||
{
|
||||
return unloadSection(new SMCAVector(x, z), save);
|
||||
}
|
||||
|
||||
public boolean unloadSection(SMCAVector s, boolean save) throws IOException
|
||||
{
|
||||
if(!isSectionLoaded(s))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if(save)
|
||||
{
|
||||
saveSection(s);
|
||||
}
|
||||
|
||||
loadedSections.remove(s);
|
||||
return true;
|
||||
}
|
||||
|
||||
public boolean saveSection(int x, int z) throws IOException
|
||||
{
|
||||
return saveSection(new SMCAVector(x, z));
|
||||
}
|
||||
|
||||
public boolean saveSection(SMCAVector s) throws IOException
|
||||
{
|
||||
if(!isSectionLoaded(s.getX(), s.getZ()))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
AtomicRegionData data = loadedSections.get(s);
|
||||
FileOutputStream fos = new FileOutputStream(getSubregionFile(s.getX(), s.getZ()));
|
||||
data.write(fos);
|
||||
fos.close();
|
||||
return true;
|
||||
}
|
||||
|
||||
public AtomicRegionData loadSection(int x, int z) throws IOException
|
||||
{
|
||||
if(isSectionLoaded(x, z))
|
||||
{
|
||||
return loadedSections.get(new SMCAVector(x, z));
|
||||
}
|
||||
|
||||
File file = getSubregionFile(x, z);
|
||||
|
||||
if(!file.exists())
|
||||
{
|
||||
return createSection(x, z);
|
||||
}
|
||||
|
||||
FileInputStream fin = new FileInputStream(file);
|
||||
AtomicRegionData data = new AtomicRegionData(world);
|
||||
data.read(fin);
|
||||
fin.close();
|
||||
return data;
|
||||
}
|
||||
|
||||
public AtomicRegionData createSection(int x, int z)
|
||||
{
|
||||
if(isSectionLoaded(x, z))
|
||||
{
|
||||
return loadedSections.get(new SMCAVector(x, z));
|
||||
}
|
||||
|
||||
AtomicRegionData data = new AtomicRegionData(world);
|
||||
loadedSections.put(new SMCAVector(x, z), data);
|
||||
|
||||
return data;
|
||||
}
|
||||
|
||||
public File getSubregionFile(int x, int z)
|
||||
{
|
||||
return new File(getSubregionFolder(), "sr." + x + "." + z + ".smca");
|
||||
}
|
||||
|
||||
public File getSubregionFolder()
|
||||
{
|
||||
return new File(world.getWorldFolder(), "subregion");
|
||||
}
|
||||
}
|
File diff suppressed because it is too large
Load Diff
@ -1,463 +0,0 @@
|
||||
package ninja.bytecode.iris.generator.genobject;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.Random;
|
||||
|
||||
import org.bukkit.Chunk;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.World;
|
||||
import org.bukkit.block.Block;
|
||||
import org.bukkit.generator.BlockPopulator;
|
||||
|
||||
import mortar.api.sched.S;
|
||||
import mortar.logic.format.F;
|
||||
import mortar.util.text.C;
|
||||
import net.md_5.bungee.api.ChatColor;
|
||||
import ninja.bytecode.iris.Iris;
|
||||
import ninja.bytecode.iris.generator.IrisGenerator;
|
||||
import ninja.bytecode.iris.generator.parallax.ParallaxCache;
|
||||
import ninja.bytecode.iris.generator.placer.AtomicParallaxPlacer;
|
||||
import ninja.bytecode.iris.generator.placer.BukkitPlacer;
|
||||
import ninja.bytecode.iris.generator.placer.NMSPlacer;
|
||||
import ninja.bytecode.iris.pack.IrisBiome;
|
||||
import ninja.bytecode.iris.util.IPlacer;
|
||||
import ninja.bytecode.iris.util.MB;
|
||||
import ninja.bytecode.iris.util.ObjectMode;
|
||||
import ninja.bytecode.iris.util.SMCAVector;
|
||||
import ninja.bytecode.shuriken.collections.KList;
|
||||
import ninja.bytecode.shuriken.collections.KMap;
|
||||
import ninja.bytecode.shuriken.collections.KSet;
|
||||
import ninja.bytecode.shuriken.execution.ChronoLatch;
|
||||
import ninja.bytecode.shuriken.execution.J;
|
||||
import ninja.bytecode.shuriken.logging.L;
|
||||
import ninja.bytecode.shuriken.math.M;
|
||||
import ninja.bytecode.shuriken.math.RNG;
|
||||
|
||||
public class GenObjectDecorator extends BlockPopulator
|
||||
{
|
||||
private KList<PlacedObject> placeHistory;
|
||||
private KMap<IrisBiome, KList<GenObjectGroup>> orderCache;
|
||||
private KMap<IrisBiome, KMap<GenObjectGroup, Double>> populationCache;
|
||||
private IPlacer placer;
|
||||
private IrisGenerator g;
|
||||
private ChronoLatch cl = new ChronoLatch(250);
|
||||
|
||||
public GenObjectDecorator(IrisGenerator generator)
|
||||
{
|
||||
this.g = generator;
|
||||
placeHistory = new KList<>();
|
||||
populationCache = new KMap<>();
|
||||
orderCache = new KMap<>();
|
||||
|
||||
for(IrisBiome i : generator.getDimension().getBiomes())
|
||||
{
|
||||
KMap<GenObjectGroup, Double> gc = new KMap<>();
|
||||
KMap<Integer, KList<GenObjectGroup>> or = new KMap<>();
|
||||
int ff = 0;
|
||||
for(String j : i.getSchematicGroups().k())
|
||||
{
|
||||
double c = i.getSchematicGroups().get(j);
|
||||
|
||||
try
|
||||
{
|
||||
GenObjectGroup g = generator.getDimension().getObjectGroup(j);
|
||||
ff += g.size();
|
||||
gc.put(g, c);
|
||||
|
||||
if(!or.containsKey(g.getPiority()))
|
||||
{
|
||||
or.put(g.getPiority(), new KList<>());
|
||||
}
|
||||
|
||||
or.get(g.getPiority()).add(g);
|
||||
}
|
||||
|
||||
catch(Throwable e)
|
||||
{
|
||||
L.f(ChatColor.RED + "Failed to inject " + j + " into GenObjectDecorator");
|
||||
L.ex(e);
|
||||
}
|
||||
}
|
||||
|
||||
if(!gc.isEmpty())
|
||||
{
|
||||
KList<GenObjectGroup> g = new KList<>();
|
||||
for(KList<GenObjectGroup> j : or.v())
|
||||
{
|
||||
g.addAll(j);
|
||||
}
|
||||
|
||||
Collections.sort(g, (a, b) -> a.getPiority() - b.getPiority());
|
||||
orderCache.put(i, g);
|
||||
populationCache.put(i, gc);
|
||||
|
||||
if(Iris.settings.performance.verbose)
|
||||
{
|
||||
L.v(C.DARK_GREEN + i.getName() + ": " + C.DARK_AQUA + F.f(ff) + " Objects");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
L.i("Population Cache is " + populationCache.size());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void populate(World world, Random random, Chunk source)
|
||||
{
|
||||
Runnable m = () ->
|
||||
{
|
||||
try
|
||||
{
|
||||
if(g.isDisposed())
|
||||
{
|
||||
placeHistory.clear();
|
||||
return;
|
||||
}
|
||||
|
||||
KSet<IrisBiome> hits = new KSet<>();
|
||||
int cx = source.getX();
|
||||
int cz = source.getZ();
|
||||
|
||||
for(int i = 0; i < Iris.settings.performance.decorationAccuracy; i++)
|
||||
{
|
||||
int x = (cx << 4) + random.nextInt(16);
|
||||
int z = (cz << 4) + random.nextInt(16);
|
||||
IrisBiome biome = g.getBiome((int) g.getOffsetX(x, z), (int) g.getOffsetZ(x, z));
|
||||
|
||||
if(hits.contains(biome))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
KMap<GenObjectGroup, Double> objects = populationCache.get(biome);
|
||||
|
||||
if(objects == null)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
hits.add(biome);
|
||||
populate(world, cx, cz, random, biome);
|
||||
}
|
||||
}
|
||||
|
||||
catch(Throwable e)
|
||||
{
|
||||
e.printStackTrace();
|
||||
}
|
||||
};
|
||||
|
||||
if(Iris.settings.performance.objectMode.equals(ObjectMode.QUICK_N_DIRTY))
|
||||
{
|
||||
J.a(m);
|
||||
}
|
||||
|
||||
else
|
||||
{
|
||||
m.run();
|
||||
}
|
||||
}
|
||||
|
||||
@SuppressWarnings("deprecation")
|
||||
private void populate(World world, int cx, int cz, Random random, IrisBiome biome)
|
||||
{
|
||||
for(GenObjectGroup i : orderCache.get(biome))
|
||||
{
|
||||
if(biome.getSchematicGroups().get(i.getName()) == null)
|
||||
{
|
||||
L.w(C.YELLOW + "Cannot find chance for " + C.RED + i.getName() + C.YELLOW + " in Biome " + C.RED + biome.getName());
|
||||
continue;
|
||||
}
|
||||
|
||||
for(int j = 0; j < getTries(biome.getSchematicGroups().get(i.getName())); j++)
|
||||
{
|
||||
if(M.r(Iris.settings.gen.objectDensity))
|
||||
{
|
||||
GenObject go = i.getSchematics().get(random.nextInt(i.getSchematics().size()));
|
||||
int x = (cx << 4) + random.nextInt(16);
|
||||
int z = (cz << 4) + random.nextInt(16);
|
||||
|
||||
if(i.getWorldChance() >= 0D)
|
||||
{
|
||||
int rngx = (int) Math.floor(x / (double) (i.getWorldRadius() == 0 ? 32 : i.getWorldRadius()));
|
||||
int rngz = (int) Math.floor(z / (double) (i.getWorldRadius() == 0 ? 32 : i.getWorldRadius()));
|
||||
|
||||
if(new RNG(new SMCAVector(rngx, rngz).hashCode()).nextDouble() < i.getWorldChance())
|
||||
{
|
||||
if(Iris.settings.performance.verbose)
|
||||
{
|
||||
L.w(C.WHITE + "Object " + C.YELLOW + i.getName() + "/*" + C.WHITE + " failed to place due to a world chance.");
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
int by = world.getHighestBlockYAt(x, z);
|
||||
Block b = world.getBlockAt(x, by - 1, z);
|
||||
MB mb = MB.of(b.getType(), b.getData());
|
||||
|
||||
if(!Iris.settings.performance.noObjectFail)
|
||||
{
|
||||
if(!mb.material.isSolid() || !biome.isSurface(mb.material))
|
||||
{
|
||||
if(Iris.settings.performance.verbose)
|
||||
{
|
||||
L.w(C.WHITE + "Object " + C.YELLOW + i.getName() + "/*" + C.WHITE + " failed to place in " + C.YELLOW + mb.material.toString().toLowerCase() + C.WHITE + " at " + C.YELLOW + F.f(x) + " " + F.f(by) + " " + F.f(z));
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if(Iris.settings.performance.objectMode.equals(ObjectMode.QUICK_N_DIRTY))
|
||||
{
|
||||
placer = new NMSPlacer(world);
|
||||
}
|
||||
|
||||
else if(Iris.settings.performance.objectMode.equals(ObjectMode.LIGHTING_PHYSICS))
|
||||
{
|
||||
placer = new BukkitPlacer(world, true);
|
||||
}
|
||||
|
||||
else if(Iris.settings.performance.objectMode.equals(ObjectMode.LIGHTING))
|
||||
{
|
||||
placer = new BukkitPlacer(world, false);
|
||||
}
|
||||
|
||||
Runnable rx = () ->
|
||||
{
|
||||
Location start = go.place(x, by, z, placer);
|
||||
|
||||
if(start != null)
|
||||
{
|
||||
g.hitObject();
|
||||
if(Iris.settings.performance.verbose)
|
||||
{
|
||||
L.v(C.GRAY + "Placed " + C.DARK_GREEN + i.getName() + C.WHITE + "/" + C.DARK_GREEN + go.getName() + C.GRAY + " at " + C.DARK_GREEN + F.f(start.getBlockX()) + " " + F.f(start.getBlockY()) + " " + F.f(start.getBlockZ()));
|
||||
}
|
||||
|
||||
if(Iris.settings.performance.debugMode)
|
||||
{
|
||||
placeHistory.add(new PlacedObject(start.getBlockX(), start.getBlockY(), start.getBlockZ(), i.getName() + ":" + go.getName()));
|
||||
|
||||
if(placeHistory.size() > Iris.settings.performance.placeHistoryLimit)
|
||||
{
|
||||
while(placeHistory.size() > Iris.settings.performance.placeHistoryLimit)
|
||||
{
|
||||
placeHistory.remove(0);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
if(Iris.settings.performance.objectMode.equals(ObjectMode.QUICK_N_DIRTY))
|
||||
{
|
||||
new S(20)
|
||||
{
|
||||
@Override
|
||||
public void run()
|
||||
{
|
||||
rx.run();
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
else
|
||||
{
|
||||
rx.run();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if(placer != null && cl.flip())
|
||||
{
|
||||
placer.flush();
|
||||
}
|
||||
}
|
||||
|
||||
public void populateParallax(int cx, int cz, Random random)
|
||||
{
|
||||
try
|
||||
{
|
||||
if(g.isDisposed())
|
||||
{
|
||||
placeHistory.clear();
|
||||
return;
|
||||
}
|
||||
|
||||
ParallaxCache cache = new ParallaxCache(g);
|
||||
KSet<IrisBiome> hits = new KSet<>();
|
||||
|
||||
for(int i = 0; i < Iris.settings.performance.decorationAccuracy; i++)
|
||||
{
|
||||
int x = (cx << 4) + random.nextInt(16);
|
||||
int z = (cz << 4) + random.nextInt(16);
|
||||
IrisBiome biome = cache.getBiome(x, z);
|
||||
|
||||
if(hits.contains(biome))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
KMap<GenObjectGroup, Double> objects = populationCache.get(biome);
|
||||
|
||||
if(objects == null)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
hits.add(biome);
|
||||
populateParallax(cx, cz, random, biome, cache);
|
||||
}
|
||||
}
|
||||
|
||||
catch(Throwable e)
|
||||
{
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
private void populateParallax(int cx, int cz, Random random, IrisBiome biome, ParallaxCache cache)
|
||||
{
|
||||
for(GenObjectGroup i : orderCache.get(biome))
|
||||
{
|
||||
if(biome.getSchematicGroups().get(i.getName()) == null)
|
||||
{
|
||||
L.w(C.YELLOW + "Cannot find chance for " + C.RED + i.getName() + C.YELLOW + " in Biome " + C.RED + biome.getName());
|
||||
continue;
|
||||
}
|
||||
|
||||
for(int j = 0; j < getTries(biome.getSchematicGroups().get(i.getName())); j++)
|
||||
{
|
||||
if(M.r(Iris.settings.gen.objectDensity))
|
||||
{
|
||||
if(i.getSchematics().isEmpty())
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
GenObject go = i.getSchematics().get(random.nextInt(i.getSchematics().size()));
|
||||
int x = (cx << 4) + random.nextInt(16);
|
||||
int z = (cz << 4) + random.nextInt(16);
|
||||
|
||||
if(i.getWorldChance() >= 0D)
|
||||
{
|
||||
int rngx = (int) Math.floor(x / (double) (i.getWorldRadius() == 0 ? 32 : i.getWorldRadius()));
|
||||
int rngz = (int) Math.floor(z / (double) (i.getWorldRadius() == 0 ? 32 : i.getWorldRadius()));
|
||||
|
||||
if(new RNG(new SMCAVector(rngx, rngz).hashCode()).nextDouble() < i.getWorldChance())
|
||||
{
|
||||
if(Iris.settings.performance.verbose)
|
||||
{
|
||||
L.w(C.WHITE + "Object " + C.YELLOW + i.getName() + "/*" + C.WHITE + " failed to place due to a world chance.");
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
int by = cache.getHeight(x, z);
|
||||
MB mb = cache.get(x, by, z);
|
||||
|
||||
if(!Iris.settings.performance.noObjectFail)
|
||||
{
|
||||
if(!mb.material.isSolid() || !biome.isSurface(mb.material))
|
||||
{
|
||||
if(Iris.settings.performance.verbose)
|
||||
{
|
||||
L.w(C.WHITE + "Object " + C.YELLOW + i.getName() + "/*" + C.WHITE + " failed to place in " + C.YELLOW + mb.material.toString().toLowerCase() + C.WHITE + " at " + C.YELLOW + F.f(x) + " " + F.f(by) + " " + F.f(z));
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
placer = new AtomicParallaxPlacer(g, cache);
|
||||
Location start = go.place(x, by, z, placer);
|
||||
|
||||
if(start != null)
|
||||
{
|
||||
g.hitObject();
|
||||
if(Iris.settings.performance.verbose)
|
||||
{
|
||||
L.v(C.GRAY + "Placed " + C.DARK_GREEN + i.getName() + C.WHITE + "/" + C.DARK_GREEN + go.getName() + C.GRAY + " at " + C.DARK_GREEN + F.f(start.getBlockX()) + " " + F.f(start.getBlockY()) + " " + F.f(start.getBlockZ()));
|
||||
}
|
||||
|
||||
if(Iris.settings.performance.debugMode)
|
||||
{
|
||||
placeHistory.add(new PlacedObject(start.getBlockX(), start.getBlockY(), start.getBlockZ(), i.getName() + ":" + go.getName()));
|
||||
|
||||
if(placeHistory.size() > Iris.settings.performance.placeHistoryLimit)
|
||||
{
|
||||
while(placeHistory.size() > Iris.settings.performance.placeHistoryLimit)
|
||||
{
|
||||
placeHistory.remove(0);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if(placer != null && cl.flip())
|
||||
{
|
||||
placer.flush();
|
||||
}
|
||||
}
|
||||
|
||||
public int getTries(double chance)
|
||||
{
|
||||
if(chance <= 0)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
if(Math.floor(chance) == chance)
|
||||
{
|
||||
return (int) chance;
|
||||
}
|
||||
|
||||
int floor = (int) Math.floor(chance);
|
||||
|
||||
if(chance - floor > 0 && M.r(chance - floor))
|
||||
{
|
||||
floor++;
|
||||
}
|
||||
|
||||
return floor;
|
||||
}
|
||||
|
||||
public KList<PlacedObject> getHistory()
|
||||
{
|
||||
return placeHistory;
|
||||
}
|
||||
|
||||
public void dispose()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
public PlacedObject randomObject(String string)
|
||||
{
|
||||
KList<PlacedObject> v = new KList<>();
|
||||
|
||||
for(PlacedObject i : placeHistory)
|
||||
{
|
||||
if(i.getF().toLowerCase().replaceAll("\\Q:\\E", "/").startsWith(string.toLowerCase()))
|
||||
{
|
||||
v.add(i);
|
||||
}
|
||||
}
|
||||
|
||||
if(v.isEmpty())
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
return v.getRandom();
|
||||
}
|
||||
}
|
@ -1,387 +0,0 @@
|
||||
package ninja.bytecode.iris.generator.genobject;
|
||||
|
||||
import java.io.DataInputStream;
|
||||
import java.io.DataOutputStream;
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.util.function.Consumer;
|
||||
|
||||
import net.md_5.bungee.api.ChatColor;
|
||||
import ninja.bytecode.iris.Iris;
|
||||
import ninja.bytecode.iris.util.Direction;
|
||||
import ninja.bytecode.shuriken.collections.KList;
|
||||
import ninja.bytecode.shuriken.format.Form;
|
||||
import ninja.bytecode.shuriken.io.IO;
|
||||
import ninja.bytecode.shuriken.logging.L;
|
||||
|
||||
public class GenObjectGroup
|
||||
{
|
||||
private KList<GenObject> schematics;
|
||||
private KList<GenObject> osSchematics;
|
||||
private KList<GenObject> pxSchematics;
|
||||
private KList<String> flags;
|
||||
private String name;
|
||||
private int priority;
|
||||
private double worldChance;
|
||||
private int worldRad;
|
||||
|
||||
public GenObjectGroup(String name)
|
||||
{
|
||||
this.schematics = new KList<>();
|
||||
this.flags = new KList<>();
|
||||
this.name = name;
|
||||
priority = Integer.MIN_VALUE;
|
||||
worldChance = Integer.MIN_VALUE;
|
||||
worldRad = 32;
|
||||
}
|
||||
|
||||
public void read(DataInputStream din) throws IOException
|
||||
{
|
||||
flags.clear();
|
||||
schematics.clear();
|
||||
name = din.readUTF();
|
||||
int fl = din.readInt();
|
||||
int sc = din.readInt();
|
||||
|
||||
for(int i = 0; i < fl; i++)
|
||||
{
|
||||
flags.add(din.readUTF());
|
||||
}
|
||||
|
||||
for(int i = 0; i < sc; i++)
|
||||
{
|
||||
GenObject g = new GenObject(0, 0, 0);
|
||||
g.readDirect(din);
|
||||
schematics.add(g);
|
||||
}
|
||||
}
|
||||
|
||||
public void write(DataOutputStream dos, Consumer<Double> progress) throws IOException
|
||||
{
|
||||
dos.writeUTF(name);
|
||||
dos.writeInt(flags.size());
|
||||
dos.writeInt(schematics.size());
|
||||
|
||||
for(String i : flags)
|
||||
{
|
||||
dos.writeUTF(i);
|
||||
}
|
||||
|
||||
int of = 0;
|
||||
|
||||
if(progress != null)
|
||||
{
|
||||
progress.accept((double) of / (double) schematics.size());
|
||||
}
|
||||
|
||||
for(GenObject i : schematics)
|
||||
{
|
||||
i.writeDirect(dos);
|
||||
of++;
|
||||
|
||||
if(progress != null)
|
||||
{
|
||||
progress.accept((double) of / (double) schematics.size());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void applyLushFilter(double factor)
|
||||
{
|
||||
if(flags.contains("no lush"))
|
||||
{
|
||||
L.i(ChatColor.DARK_GREEN + "Skipping Lush Filter for " + ChatColor.GRAY + getName());
|
||||
return;
|
||||
}
|
||||
|
||||
L.i(ChatColor.GREEN + "Applying Lush Filter to " + ChatColor.WHITE + getName());
|
||||
|
||||
for(GenObject i : schematics)
|
||||
{
|
||||
i.applyLushFilter(factor);
|
||||
}
|
||||
}
|
||||
|
||||
public void applySnowFilter(int factor)
|
||||
{
|
||||
if(flags.contains("no snow"))
|
||||
{
|
||||
L.i(ChatColor.DARK_AQUA + "Skipping Snow Filter for " + ChatColor.GRAY + getName());
|
||||
return;
|
||||
}
|
||||
|
||||
L.i(ChatColor.AQUA + "Applying Snow Filter to " + ChatColor.WHITE + getName());
|
||||
|
||||
for(GenObject i : schematics)
|
||||
{
|
||||
i.applySnowFilter(factor);
|
||||
}
|
||||
}
|
||||
|
||||
public GenObjectGroup copy(String suffix)
|
||||
{
|
||||
GenObjectGroup gog = new GenObjectGroup(name + suffix);
|
||||
gog.schematics = new KList<>();
|
||||
gog.flags = flags.copy();
|
||||
|
||||
for(GenObject i : schematics)
|
||||
{
|
||||
GenObject g = i.copy();
|
||||
g.setName(i.getName() + suffix);
|
||||
gog.schematics.add(g);
|
||||
}
|
||||
|
||||
return gog;
|
||||
}
|
||||
|
||||
public String getName()
|
||||
{
|
||||
return name;
|
||||
}
|
||||
|
||||
public void setName(String name)
|
||||
{
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
public KList<GenObject> getSchematics()
|
||||
{
|
||||
return schematics;
|
||||
}
|
||||
|
||||
public KList<GenObject> getPXSchematics()
|
||||
{
|
||||
if(pxSchematics == null)
|
||||
{
|
||||
pxSchematics = new KList<>();
|
||||
|
||||
for(GenObject i : schematics)
|
||||
{
|
||||
if(!i.isOversized())
|
||||
{
|
||||
pxSchematics.add(i);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return pxSchematics;
|
||||
}
|
||||
|
||||
public KList<GenObject> getOSSchematics()
|
||||
{
|
||||
if(osSchematics == null)
|
||||
{
|
||||
osSchematics = new KList<>();
|
||||
|
||||
for(GenObject i : schematics)
|
||||
{
|
||||
if(i.isOversized())
|
||||
{
|
||||
osSchematics.add(i);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return pxSchematics;
|
||||
}
|
||||
|
||||
public void setSchematics(KList<GenObject> schematics)
|
||||
{
|
||||
this.schematics = schematics;
|
||||
}
|
||||
|
||||
public KList<String> getFlags()
|
||||
{
|
||||
return flags;
|
||||
}
|
||||
|
||||
public void setFlags(KList<String> flags)
|
||||
{
|
||||
this.flags = flags;
|
||||
}
|
||||
|
||||
public int size()
|
||||
{
|
||||
return getSchematics().size();
|
||||
}
|
||||
|
||||
public int getPiority()
|
||||
{
|
||||
if(priority == Integer.MIN_VALUE)
|
||||
{
|
||||
for(String i : flags)
|
||||
{
|
||||
if(i.startsWith("priority "))
|
||||
{
|
||||
priority = Integer.valueOf(i.split("\\Q \\E")[1]);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return priority;
|
||||
}
|
||||
|
||||
public static GenObjectGroup load(String string)
|
||||
{
|
||||
File folder = Iris.pack().loadFolder(string);
|
||||
|
||||
if(folder != null)
|
||||
{
|
||||
GenObjectGroup g = new GenObjectGroup(string);
|
||||
|
||||
for(File i : folder.listFiles())
|
||||
{
|
||||
if(i.getName().endsWith(".ifl"))
|
||||
{
|
||||
try
|
||||
{
|
||||
g.flags.add(IO.readAll(i).split("\\Q\n\\E"));
|
||||
}
|
||||
|
||||
catch(IOException e)
|
||||
{
|
||||
L.ex(e);
|
||||
}
|
||||
}
|
||||
|
||||
if(i.getName().endsWith(".ish"))
|
||||
{
|
||||
try
|
||||
{
|
||||
GenObject s = GenObject.load(i);
|
||||
g.getSchematics().add(s);
|
||||
}
|
||||
|
||||
catch(IOException e)
|
||||
{
|
||||
L.f("Cannot load Schematic: " + string + "/" + i.getName());
|
||||
L.ex(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return g;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public void processVariants()
|
||||
{
|
||||
for(GenObject i : getSchematics())
|
||||
{
|
||||
i.recalculateMountShift();
|
||||
|
||||
for(String j : flags)
|
||||
{
|
||||
i.computeFlag(j);
|
||||
}
|
||||
}
|
||||
|
||||
if(!flags.contains("no rotation"))
|
||||
{
|
||||
KList<GenObject> inject = new KList<>();
|
||||
for(GenObject i : getSchematics())
|
||||
{
|
||||
for(Direction j : new Direction[] {Direction.S, Direction.E, Direction.W})
|
||||
{
|
||||
GenObject cp = i.copy();
|
||||
GenObject f = cp;
|
||||
f.rotate(Direction.N, j);
|
||||
f.recalculateMountShift();
|
||||
inject.add(f);
|
||||
}
|
||||
}
|
||||
|
||||
getSchematics().add(inject);
|
||||
}
|
||||
|
||||
L.i(ChatColor.LIGHT_PURPLE + "Processed " + ChatColor.WHITE + Form.f(schematics.size()) + ChatColor.LIGHT_PURPLE + " Schematics in " + ChatColor.WHITE + name);
|
||||
}
|
||||
|
||||
public void dispose()
|
||||
{
|
||||
for(GenObject i : schematics)
|
||||
{
|
||||
i.dispose();
|
||||
}
|
||||
|
||||
schematics.clear();
|
||||
flags.clear();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode()
|
||||
{
|
||||
final int prime = 31;
|
||||
int result = 1;
|
||||
result = prime * result + ((flags == null) ? 0 : flags.hashCode());
|
||||
result = prime * result + ((name == null) ? 0 : name.hashCode());
|
||||
result = prime * result + priority;
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj)
|
||||
{
|
||||
if(this == obj)
|
||||
return true;
|
||||
if(obj == null)
|
||||
return false;
|
||||
if(getClass() != obj.getClass())
|
||||
return false;
|
||||
GenObjectGroup other = (GenObjectGroup) obj;
|
||||
if(flags == null)
|
||||
{
|
||||
if(other.flags != null)
|
||||
return false;
|
||||
}
|
||||
else if(!flags.equals(other.flags))
|
||||
return false;
|
||||
if(name == null)
|
||||
{
|
||||
if(other.name != null)
|
||||
return false;
|
||||
}
|
||||
else if(!name.equals(other.name))
|
||||
return false;
|
||||
if(priority != other.priority)
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public double getWorldChance()
|
||||
{
|
||||
if(worldChance == Integer.MIN_VALUE)
|
||||
{
|
||||
for(String i : flags)
|
||||
{
|
||||
if(i.startsWith("world chance "))
|
||||
{
|
||||
worldChance = Double.valueOf(i.split("\\Q \\E")[2]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return worldChance;
|
||||
}
|
||||
|
||||
public double getWorldRadius()
|
||||
{
|
||||
if(worldRad == Integer.MIN_VALUE)
|
||||
{
|
||||
for(String i : flags)
|
||||
{
|
||||
if(i.startsWith("world radius "))
|
||||
{
|
||||
worldRad = Integer.valueOf(i.split("\\Q \\E")[2]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return worldRad;
|
||||
}
|
||||
|
||||
}
|
@ -1,95 +0,0 @@
|
||||
package ninja.bytecode.iris.generator.genobject;
|
||||
|
||||
public class PlacedObject
|
||||
{
|
||||
private int x;
|
||||
private int y;
|
||||
private int z;
|
||||
private String f;
|
||||
|
||||
public PlacedObject(int x, int y, int z, String f)
|
||||
{
|
||||
this.x = x;
|
||||
this.y = y;
|
||||
this.z = z;
|
||||
this.f = f;
|
||||
}
|
||||
|
||||
public int getX()
|
||||
{
|
||||
return x;
|
||||
}
|
||||
|
||||
public void setX(int x)
|
||||
{
|
||||
this.x = x;
|
||||
}
|
||||
|
||||
public int getY()
|
||||
{
|
||||
return y;
|
||||
}
|
||||
|
||||
public void setY(int y)
|
||||
{
|
||||
this.y = y;
|
||||
}
|
||||
|
||||
public int getZ()
|
||||
{
|
||||
return z;
|
||||
}
|
||||
|
||||
public void setZ(int z)
|
||||
{
|
||||
this.z = z;
|
||||
}
|
||||
|
||||
public String getF()
|
||||
{
|
||||
return f;
|
||||
}
|
||||
|
||||
public void setF(String f)
|
||||
{
|
||||
this.f = f;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode()
|
||||
{
|
||||
final int prime = 31;
|
||||
int result = 1;
|
||||
result = prime * result + ((f == null) ? 0 : f.hashCode());
|
||||
result = prime * result + x;
|
||||
result = prime * result + y;
|
||||
result = prime * result + z;
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj)
|
||||
{
|
||||
if(this == obj)
|
||||
return true;
|
||||
if(obj == null)
|
||||
return false;
|
||||
if(getClass() != obj.getClass())
|
||||
return false;
|
||||
PlacedObject other = (PlacedObject) obj;
|
||||
if(f == null)
|
||||
{
|
||||
if(other.f != null)
|
||||
return false;
|
||||
}
|
||||
else if(!f.equals(other.f))
|
||||
return false;
|
||||
if(x != other.x)
|
||||
return false;
|
||||
if(y != other.y)
|
||||
return false;
|
||||
if(z != other.z)
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
}
|
@ -1,34 +0,0 @@
|
||||
package ninja.bytecode.iris.generator.layer;
|
||||
|
||||
import ninja.bytecode.iris.pack.IrisBiome;
|
||||
import ninja.bytecode.shuriken.math.CNG;
|
||||
import ninja.bytecode.shuriken.math.RNG;
|
||||
|
||||
public class BiomeNoiseGenerator
|
||||
{
|
||||
protected IrisBiome biome;
|
||||
protected CNG gen;
|
||||
private double block = 1D / 255D;
|
||||
|
||||
public BiomeNoiseGenerator(RNG rng, IrisBiome biome)
|
||||
{
|
||||
this.biome = biome;
|
||||
//@builder
|
||||
gen = new CNG(rng.nextParallelRNG(31289 - biome.getName().length() * biome.getRealBiome().ordinal()), 1D, 1)
|
||||
.scale(0.0025 * biome.getGenScale())
|
||||
.fractureWith(new CNG(rng.nextParallelRNG(2922 * biome.getName().length() - biome.getRealBiome().ordinal()), 1D, 1)
|
||||
.scale(0.0075 * biome.getGenSwirlScale()), 20D * biome.getGenSwirl());
|
||||
//@done
|
||||
}
|
||||
|
||||
public double getHeight(double x, double z)
|
||||
{
|
||||
if(biome.getGenAmplifier() == 0)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
double r = block * 52;
|
||||
return (gen.noise(x, z) * biome.getGenAmplifier() * r);
|
||||
}
|
||||
}
|
@ -1,217 +0,0 @@
|
||||
package ninja.bytecode.iris.generator.layer;
|
||||
|
||||
import java.util.Random;
|
||||
import java.util.function.Function;
|
||||
|
||||
import org.bukkit.World;
|
||||
|
||||
import mortar.util.text.C;
|
||||
import ninja.bytecode.iris.Iris;
|
||||
import ninja.bytecode.iris.generator.IrisGenerator;
|
||||
import ninja.bytecode.iris.pack.IrisBiome;
|
||||
import ninja.bytecode.iris.pack.IrisRegion;
|
||||
import ninja.bytecode.iris.util.BiomeLayer;
|
||||
import ninja.bytecode.iris.util.Borders;
|
||||
import ninja.bytecode.iris.util.GenLayer;
|
||||
import ninja.bytecode.iris.util.PolygonGenerator;
|
||||
import ninja.bytecode.shuriken.collections.KList;
|
||||
import ninja.bytecode.shuriken.collections.KMap;
|
||||
import ninja.bytecode.shuriken.logging.L;
|
||||
import ninja.bytecode.shuriken.math.CNG;
|
||||
import ninja.bytecode.shuriken.math.RNG;
|
||||
|
||||
public class GenLayerBiome extends GenLayer
|
||||
{
|
||||
private KMap<String, IrisRegion> regions;
|
||||
private Function<CNG, CNG> factory;
|
||||
private CNG fracture;
|
||||
private CNG fuzz;
|
||||
private PolygonGenerator channel;
|
||||
private PolygonGenerator ocean;
|
||||
private BiomeLayer master;
|
||||
|
||||
public GenLayerBiome(IrisGenerator iris, World world, Random random, RNG rng, KList<IrisBiome> biomes)
|
||||
{
|
||||
super(iris, world, random, rng);
|
||||
//@builder
|
||||
channel = new PolygonGenerator(rng.nextParallelRNG(-12), 2, 0.0005, 1, (g)->g.fractureWith(new CNG(rng.nextParallelRNG(34), 1D, 2)
|
||||
.scale(0.01), 30));
|
||||
ocean = new PolygonGenerator(rng.nextParallelRNG(-11), 6, 0.005, 1, (g)->g.fractureWith(new CNG(rng.nextParallelRNG(34), 1D, 2)
|
||||
.scale(0.01), 150));
|
||||
fuzz = new CNG(rng.nextParallelRNG(9112), 1D * 12 * Iris.settings.gen.biomeEdgeFuzzScale, 1).scale(6.5);
|
||||
fracture = new CNG(rng.nextParallelRNG(28), 1D, 4).scale(0.0021 * Iris.settings.gen.biomeEdgeScrambleScale)
|
||||
.fractureWith(new CNG(rng.nextParallelRNG(34), 1D, 2)
|
||||
.scale(0.01), 12250);
|
||||
factory = (g) -> g.fractureWith(new CNG(rng.nextParallelRNG(29), 1D, 3)
|
||||
.scale(0.005 * Iris.settings.gen.biomeScale), 1024D / Iris.settings.gen.biomeScale)
|
||||
.fractureWith(new CNG(rng.nextParallelRNG(1212), 1D, 2)
|
||||
.scale(0.04)
|
||||
.fractureWith(new CNG(rng.nextParallelRNG(1216), 1D, 3).scale(0.0004), 266), 66);
|
||||
//@done
|
||||
regions = new KMap<>();
|
||||
|
||||
for(IrisBiome i : biomes)
|
||||
{
|
||||
if(i.getRegionID().equals("default"))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if(!regions.containsKey(i.getRegionID()))
|
||||
{
|
||||
regions.put(i.getRegionID(), new IrisRegion(i.getRegionID()));
|
||||
}
|
||||
|
||||
regions.get(i.getRegionID()).getBiomes().add(i);
|
||||
}
|
||||
|
||||
for(IrisRegion i : regions.values())
|
||||
{
|
||||
i.load();
|
||||
}
|
||||
|
||||
int m = 0;
|
||||
|
||||
for(IrisBiome i : iris.getDimension().getBiomes())
|
||||
{
|
||||
i.seal(iris.getRTerrain().nextParallelRNG(3922 - m++));
|
||||
}
|
||||
|
||||
master = BiomeLayer.compile(iris, 0.082 * Iris.settings.gen.biomeScale * 0.189, 1, factory);
|
||||
|
||||
if(Iris.settings.performance.verbose)
|
||||
{
|
||||
master.print(2);
|
||||
}
|
||||
}
|
||||
|
||||
public IrisBiome getBiome(double wxx, double wzx)
|
||||
{
|
||||
return getBiome(wxx, wzx, false);
|
||||
}
|
||||
|
||||
public boolean isNearAquatic(int wxx, int wzx)
|
||||
{
|
||||
double wx = Math.round((double) wxx * (Iris.settings.gen.horizontalZoom / 1.90476190476)) * Iris.settings.gen.biomeScale;
|
||||
double wz = Math.round((double) wzx * (Iris.settings.gen.horizontalZoom / 1.90476190476)) * Iris.settings.gen.biomeScale;
|
||||
double xf = wx + ((fracture.noise(wx, wz) / 2D) * 200D * Iris.settings.gen.biomeEdgeScrambleRange);
|
||||
double zf = wz - ((fracture.noise(wz, wx) / 2D) * 200D * Iris.settings.gen.biomeEdgeScrambleRange);
|
||||
double x = xf - fuzz.noise(wx, wz);
|
||||
double z = zf + fuzz.noise(wz, wx);
|
||||
|
||||
if(ocean.getIndex(x, z) == 0)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
if(channel.hasBorder(3, 44, xf, zf))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
if(Borders.isBorderWithin(x, z, 3, 24D, (x + z) / 100D, (xx, zz) -> ocean.getIndex(xx, zz)))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
if(ocean.getClosestNeighbor(x, z) > 0.2)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
if(channel.getClosestNeighbor(x, z) > 0.2)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
if(channel.hasBorder(3, 7, xf, zf) || channel.hasBorder(3, 3, xf, zf))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public IrisBiome getBiome(double wxx, double wzx, boolean real)
|
||||
{
|
||||
double wx = Math.round((double) wxx * (Iris.settings.gen.horizontalZoom / 1.90476190476)) * Iris.settings.gen.biomeScale;
|
||||
double wz = Math.round((double) wzx * (Iris.settings.gen.horizontalZoom / 1.90476190476)) * Iris.settings.gen.biomeScale;
|
||||
double xf = wx + ((fracture.noise(wx, wz) / 2D) * 200D * Iris.settings.gen.biomeEdgeScrambleRange);
|
||||
double zf = wz - ((fracture.noise(wz, wx) / 2D) * 200D * Iris.settings.gen.biomeEdgeScrambleRange);
|
||||
double x = xf - fuzz.noise(wx, wz);
|
||||
double z = zf + fuzz.noise(wz, wx);
|
||||
IrisBiome biome = master.computeBiome(x, z);
|
||||
|
||||
if(real)
|
||||
{
|
||||
return biome;
|
||||
}
|
||||
|
||||
if(ocean.getIndex(x, z) == 0)
|
||||
{
|
||||
IrisRegion region = getRegion(biome.getRegionID());
|
||||
|
||||
if(region == null)
|
||||
{
|
||||
L.f(C.YELLOW + "Cannot find Region " + C.RED + biome.getRegionID());
|
||||
return biome;
|
||||
}
|
||||
|
||||
if(!Borders.isBorderWithin(x, z, 7, 45, (x / 10D) + (z / 10D), (a, b) -> ocean.getIndex(a, b)))
|
||||
{
|
||||
if(region.getDeepOcean() == null)
|
||||
{
|
||||
L.f(C.YELLOW + "Cannot find Deep Ocean in Region" + C.RED + biome.getRegionID());
|
||||
return biome;
|
||||
}
|
||||
|
||||
return getRegion(biome.getRegionID()).getDeepOcean();
|
||||
}
|
||||
|
||||
if(region.getOcean() == null)
|
||||
{
|
||||
L.f(C.YELLOW + "Cannot find Ocean in Region" + C.RED + biome.getRegionID());
|
||||
return biome;
|
||||
}
|
||||
|
||||
return getRegion(biome.getRegionID()).getOcean();
|
||||
}
|
||||
|
||||
if(channel.hasBorder(3, 44, xf, zf))
|
||||
{
|
||||
IrisRegion region = getRegion(biome.getRegionID());
|
||||
|
||||
if(region == null)
|
||||
{
|
||||
L.f(C.YELLOW + "Cannot find Region " + C.RED + biome.getRegionID());
|
||||
return biome;
|
||||
}
|
||||
|
||||
if(region.getChannel() == null)
|
||||
{
|
||||
L.f(C.YELLOW + "Cannot find Channel in Region" + C.RED + biome.getRegionID());
|
||||
return biome;
|
||||
}
|
||||
|
||||
return getRegion(biome.getRegionID()).getChannel();
|
||||
}
|
||||
|
||||
return biome;
|
||||
}
|
||||
|
||||
@Override
|
||||
public double generateLayer(double noise, double dx, double dz)
|
||||
{
|
||||
return noise;
|
||||
}
|
||||
|
||||
public IrisRegion getRegion(String name)
|
||||
{
|
||||
return regions.get(name);
|
||||
}
|
||||
|
||||
public void compileInfo(BiomeLayer l)
|
||||
{
|
||||
l.compileChildren(0.082 * Iris.settings.gen.biomeScale * 0.189, 1, factory, true);
|
||||
}
|
||||
}
|
@ -1,64 +0,0 @@
|
||||
package ninja.bytecode.iris.generator.layer;
|
||||
|
||||
import java.util.Random;
|
||||
|
||||
import org.bukkit.World;
|
||||
|
||||
import ninja.bytecode.iris.generator.IrisGenerator;
|
||||
import ninja.bytecode.iris.generator.atomics.AtomicChunkData;
|
||||
import ninja.bytecode.iris.util.ChunkPlan;
|
||||
import ninja.bytecode.iris.util.GenLayer;
|
||||
import ninja.bytecode.iris.util.IrisInterpolation;
|
||||
import ninja.bytecode.shuriken.math.CNG;
|
||||
import ninja.bytecode.shuriken.math.M;
|
||||
import ninja.bytecode.shuriken.math.RNG;
|
||||
|
||||
public class GenLayerCarving extends GenLayer
|
||||
{
|
||||
private CNG scram;
|
||||
private CNG cng;
|
||||
private CNG cngh;
|
||||
private CNG cngo;
|
||||
|
||||
public GenLayerCarving(IrisGenerator iris, World world, Random random, RNG rng)
|
||||
{
|
||||
//@builder
|
||||
super(iris, world, random, rng);
|
||||
cng = new CNG(rng.nextParallelRNG(2339234), 1D, 1).scale(0.02);
|
||||
cngh = new CNG(rng.nextParallelRNG(1939234), 1D, 1).scale(0.027);
|
||||
cngo = new CNG(rng.nextParallelRNG(8939234), 1D, 1).scale(0.002);
|
||||
scram = new CNG(rng.nextParallelRNG(2639634), 1D, 1).scale(0.15);
|
||||
|
||||
//@done
|
||||
}
|
||||
|
||||
@Override
|
||||
public double generateLayer(double gnoise, double dx, double dz)
|
||||
{
|
||||
return gnoise;
|
||||
}
|
||||
|
||||
public boolean isCarved(double vwxxf, double vwzxf, int x, int z, double hl, AtomicChunkData data, ChunkPlan plan)
|
||||
{
|
||||
double a = cngh.noise(vwxxf, vwzxf);
|
||||
double hmax = 99 + (a * 30);
|
||||
double hmin = 68 + (a * 30);
|
||||
|
||||
if(hl > hmax || hl < hmin)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
double wxxf = (scram.noise(vwxxf, vwzxf) * 12) - vwzxf;
|
||||
double wzxf = (scram.noise(vwzxf, vwxxf) * 12) + vwxxf;
|
||||
|
||||
double downrange = M.lerpInverse(hmin, hmax, hl);
|
||||
double opacity = IrisInterpolation.sinCenter(downrange);
|
||||
|
||||
if(cng.noise(wxxf, wzxf, hl / 3) < (opacity / 1.4D) * cngo.noise(wxxf, wzxf))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
@ -1,120 +0,0 @@
|
||||
package ninja.bytecode.iris.generator.layer;
|
||||
|
||||
import java.util.Random;
|
||||
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.World;
|
||||
|
||||
import ninja.bytecode.iris.generator.IrisGenerator;
|
||||
import ninja.bytecode.iris.generator.atomics.AtomicChunkData;
|
||||
import ninja.bytecode.iris.util.Borders;
|
||||
import ninja.bytecode.iris.util.ChunkPlan;
|
||||
import ninja.bytecode.iris.util.GenLayer;
|
||||
import ninja.bytecode.iris.util.PolygonGenerator;
|
||||
import ninja.bytecode.shuriken.bench.PrecisionStopwatch;
|
||||
import ninja.bytecode.shuriken.math.CNG;
|
||||
import ninja.bytecode.shuriken.math.RNG;
|
||||
|
||||
public class GenLayerCaves extends GenLayer
|
||||
{
|
||||
private PolygonGenerator g;
|
||||
private CNG gincline;
|
||||
private CNG scram;
|
||||
|
||||
public GenLayerCaves(IrisGenerator iris, World world, Random random, RNG rng)
|
||||
{
|
||||
//@builder
|
||||
super(iris, world, random, rng);
|
||||
g = new PolygonGenerator(rng.nextParallelRNG(1111), 3, 0.024, 8, (c) -> c);
|
||||
gincline = new CNG(rng.nextParallelRNG(1112), 1D, 3).scale(0.00652);
|
||||
scram = new CNG(rng.nextParallelRNG(2639634), 1D, 1).scale(0.15);
|
||||
//@done
|
||||
}
|
||||
|
||||
@Override
|
||||
public double generateLayer(double gnoise, double dx, double dz)
|
||||
{
|
||||
return gnoise;
|
||||
}
|
||||
|
||||
public void genCaves(double vwxxf, double vwzxf, int x, int z, AtomicChunkData data, ChunkPlan plan)
|
||||
{
|
||||
PrecisionStopwatch s = PrecisionStopwatch.start();
|
||||
double itr = 2;
|
||||
double level = 8;
|
||||
double incline = 187;
|
||||
double baseWidth = 11;
|
||||
double drop = 41;
|
||||
double wxxf = (scram.noise(vwxxf, vwzxf) * 6) - vwzxf;
|
||||
double wzxf = (scram.noise(vwzxf, vwxxf) * 6) + vwxxf;
|
||||
|
||||
for(double m = 1; m <= itr; m += 0.45)
|
||||
{
|
||||
double w = baseWidth / m;
|
||||
|
||||
if(w < 5)
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
int lowest = 325;
|
||||
|
||||
double n = incline * gincline.noise((wxxf + (m * 10000)), (wzxf - (m * 10000)));
|
||||
for(double i = 1; i <= w / 3D; i++)
|
||||
{
|
||||
if(Borders.isBorderWithin((wxxf + (m * 10000)), (wzxf - (m * 10000)), 5, w / 2D / i, (wxxf / 3D) + (wzxf / 3D), (xx, zz) -> g.getIndex(xx, zz)))
|
||||
{
|
||||
int h = (int) ((level + n) - drop);
|
||||
if(dig(x, (int) (h + i), z, data) && h + i < lowest)
|
||||
{
|
||||
lowest = (int) (h + i);
|
||||
}
|
||||
|
||||
if(dig(x, (int) (h - i), z, data) && h - i < lowest)
|
||||
{
|
||||
lowest = (int) (h - i);
|
||||
}
|
||||
|
||||
if(i == 1)
|
||||
{
|
||||
if(dig(x, (int) (h), z, data) && h < lowest)
|
||||
{
|
||||
lowest = (int) (h);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
iris.getMetrics().stop("caves:ms:x256:/chunk:..", s);
|
||||
}
|
||||
|
||||
public boolean dig(int x, int y, int z, AtomicChunkData data)
|
||||
{
|
||||
Material a = data.getType(x, y, z);
|
||||
Material b = data.getType(x, y, z + 1);
|
||||
Material c = data.getType(x, y + 1, z);
|
||||
Material d = data.getType(x + 1, y, z);
|
||||
Material e = data.getType(x, y, z - 1);
|
||||
Material f = data.getType(x, y - 1, z);
|
||||
Material g = data.getType(x - 1, y, z);
|
||||
|
||||
if(can(a) && cann(b) && cann(c) && cann(d) && cann(e) && cann(f) && cann(g))
|
||||
{
|
||||
data.setBlock(x, y, z, Material.AIR);
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public boolean cann(Material m)
|
||||
{
|
||||
return m.isSolid() || m.equals(Material.AIR) && !m.equals(Material.BEDROCK);
|
||||
}
|
||||
|
||||
public boolean can(Material m)
|
||||
{
|
||||
return m.isSolid() && !m.equals(Material.BEDROCK);
|
||||
}
|
||||
}
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
x
Reference in New Issue
Block a user