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>
|
<goal>shade</goal>
|
||||||
</goals>
|
</goals>
|
||||||
<configuration>
|
<configuration>
|
||||||
<minimizeJar>false</minimizeJar>
|
<minimizeJar>true</minimizeJar>
|
||||||
</configuration>
|
</configuration>
|
||||||
</execution>
|
</execution>
|
||||||
</executions>
|
</executions>
|
||||||
@ -144,26 +144,43 @@
|
|||||||
</repository>
|
</repository>
|
||||||
</repositories>
|
</repositories>
|
||||||
<dependencies>
|
<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>
|
<dependency>
|
||||||
<groupId>org.spigotmc</groupId>
|
<groupId>org.spigotmc</groupId>
|
||||||
<artifactId>spigot-api</artifactId>
|
<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>
|
<scope>provided</scope>
|
||||||
</dependency>
|
</dependency>
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.bukkit.craftbukkit</groupId>
|
<groupId>org.bukkit.craftbukkit</groupId>
|
||||||
<artifactId>cb-1.12.2</artifactId>
|
<artifactId>cb-1.16.1</artifactId>
|
||||||
<version>1.12.2</version>
|
<version>1.16.1</version>
|
||||||
<scope>provided</scope>
|
<scope>provided</scope>
|
||||||
</dependency>
|
</dependency>
|
||||||
</dependencies>
|
</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,200 +1,688 @@
|
|||||||
package ninja.bytecode.iris;
|
package ninja.bytecode.iris;
|
||||||
|
|
||||||
import java.io.File;
|
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 java.util.UUID;
|
||||||
|
|
||||||
import org.bukkit.Bukkit;
|
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;
|
||||||
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.entity.Player;
|
||||||
import org.bukkit.event.EventHandler;
|
|
||||||
import org.bukkit.event.HandlerList;
|
import org.bukkit.event.HandlerList;
|
||||||
import org.bukkit.event.Listener;
|
|
||||||
import org.bukkit.event.player.PlayerJoinEvent;
|
|
||||||
import org.bukkit.generator.ChunkGenerator;
|
import org.bukkit.generator.ChunkGenerator;
|
||||||
|
import org.bukkit.inventory.ItemStack;
|
||||||
import org.bukkit.plugin.Plugin;
|
import org.bukkit.plugin.Plugin;
|
||||||
|
import org.bukkit.plugin.java.JavaPlugin;
|
||||||
|
import org.bukkit.util.Vector;
|
||||||
|
|
||||||
import mortar.api.rift.PhantomRift;
|
import com.google.gson.Gson;
|
||||||
import mortar.api.rift.Rift;
|
|
||||||
import mortar.api.rift.RiftException;
|
import ninja.bytecode.iris.generator.IrisChunkGenerator;
|
||||||
import mortar.bukkit.command.Command;
|
import ninja.bytecode.iris.object.IrisBiome;
|
||||||
import mortar.bukkit.plugin.Control;
|
import ninja.bytecode.iris.object.IrisDimension;
|
||||||
import mortar.bukkit.plugin.MortarPlugin;
|
import ninja.bytecode.iris.object.IrisObject;
|
||||||
import mortar.util.text.C;
|
import ninja.bytecode.iris.util.BiomeResult;
|
||||||
import ninja.bytecode.iris.command.CommandIris;
|
import ninja.bytecode.iris.util.BlockDataTools;
|
||||||
import ninja.bytecode.iris.controller.ExecutionController;
|
import ninja.bytecode.iris.util.BoardManager;
|
||||||
import ninja.bytecode.iris.controller.PackController;
|
import ninja.bytecode.iris.util.BoardProvider;
|
||||||
import ninja.bytecode.iris.controller.WandController;
|
import ninja.bytecode.iris.util.BoardSettings;
|
||||||
import ninja.bytecode.iris.generator.IrisGenerator;
|
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.Direction;
|
||||||
import ninja.bytecode.iris.util.HotswapGenerator;
|
import ninja.bytecode.iris.util.GroupedExecutor;
|
||||||
import ninja.bytecode.iris.util.IrisMetrics;
|
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.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 KList<GroupedExecutor> executors = new KList<>();
|
||||||
public static Settings settings;
|
|
||||||
public static IrisMetrics metrics;
|
|
||||||
private static ExecutionController executionController;
|
|
||||||
|
|
||||||
public static Iris instance;
|
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
|
public Iris()
|
||||||
private PackController packController;
|
{
|
||||||
|
IO.delete(new File("iris"));
|
||||||
|
}
|
||||||
|
|
||||||
@Control
|
|
||||||
private WandController wandController;
|
|
||||||
|
|
||||||
@Command
|
|
||||||
private CommandIris commandIris;
|
|
||||||
|
|
||||||
private Rift r;
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onEnable()
|
public void onEnable()
|
||||||
{
|
{
|
||||||
instance = this;
|
instance = this;
|
||||||
executionController = new ExecutionController();
|
hotloader = new IrisHotloadManager();
|
||||||
executionController.start();
|
data = new IrisDataManager(getDataFolder());
|
||||||
primaryThread = Thread.currentThread();
|
wand = new WandController();
|
||||||
L.consoleConsumer = (s) -> Bukkit.getConsoleSender().sendMessage(s);
|
manager = new BoardManager(this, BoardSettings.builder().boardProvider(this).scoreDirection(ScoreDirection.UP).build());
|
||||||
Direction.calculatePermutations();
|
J.a(() ->
|
||||||
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)
|
|
||||||
{
|
|
||||||
try
|
|
||||||
{
|
|
||||||
return (IrisGenerator) ((HotswapGenerator) world.getGenerator()).getGenerator();
|
|
||||||
}
|
|
||||||
|
|
||||||
catch(Throwable e)
|
|
||||||
{
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void start()
|
|
||||||
{
|
|
||||||
instance = this;
|
|
||||||
packController.compile();
|
|
||||||
|
|
||||||
if(Iris.settings.performance.debugMode)
|
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
//@builder
|
writeDocs();
|
||||||
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
|
|
||||||
}
|
}
|
||||||
|
catch(JSONException | InstantiationException | IllegalAccessException | IllegalArgumentException | InvocationTargetException | NoSuchMethodException | SecurityException | IOException e)
|
||||||
catch(RiftException e)
|
|
||||||
{
|
{
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
}
|
}
|
||||||
}
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void stop()
|
public String getTitle(Player player)
|
||||||
{
|
{
|
||||||
if(settings.performance.debugMode && r != null)
|
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)
|
||||||
{
|
{
|
||||||
r.colapse();
|
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-----------------");
|
||||||
}
|
}
|
||||||
|
|
||||||
HandlerList.unregisterAll((Plugin) this);
|
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);
|
Bukkit.getScheduler().cancelTasks(this);
|
||||||
executionController.stop();
|
HandlerList.unregisterAll((Plugin) this);
|
||||||
}
|
}
|
||||||
|
|
||||||
@EventHandler
|
@SuppressWarnings("deprecation")
|
||||||
public void on(PlayerJoinEvent e)
|
@Override
|
||||||
|
public boolean onCommand(CommandSender sender, Command command, String label, String[] args)
|
||||||
{
|
{
|
||||||
if(settings.performance.debugMode && r != null)
|
if(command.getName().equals("iris"))
|
||||||
{
|
{
|
||||||
e.getPlayer().teleport(r.getSpawn());
|
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)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
if(bd == null)
|
||||||
|
{
|
||||||
|
imsg(sender, "No data found.");
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
imsg(sender, "Material: " + ChatColor.GREEN + bd.getMaterial().name());
|
||||||
|
imsg(sender, "Full: " + ChatColor.WHITE + bd.getAsString(true));
|
||||||
|
|
||||||
|
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
|
||||||
|
{
|
||||||
|
o.write(new File(getDataFolder(), "objects/" + args[1] + ".iob"));
|
||||||
|
imsg(sender, "Saved " + "objects/" + args[1] + ".iob");
|
||||||
|
}
|
||||||
|
|
||||||
|
catch(IOException e)
|
||||||
|
{
|
||||||
|
imsg(sender, "Failed to save " + "objects/" + args[1] + ".iob");
|
||||||
|
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if(args[0].equalsIgnoreCase("load") && args.length >= 2)
|
||||||
|
{
|
||||||
|
File file = new File(getDataFolder(), "objects/" + args[1] + ".iob");
|
||||||
|
boolean intoWand = false;
|
||||||
|
|
||||||
|
for(String i : args)
|
||||||
|
{
|
||||||
|
if(i.equalsIgnoreCase("-edit"))
|
||||||
|
{
|
||||||
|
intoWand = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if(!file.exists())
|
||||||
|
{
|
||||||
|
imsg(sender, "Can't find " + "objects/" + args[1] + ".iob");
|
||||||
|
}
|
||||||
|
|
||||||
|
ItemStack wand = ((Player) sender).getInventory().getItemInMainHand();
|
||||||
|
IrisObject o = new IrisObject(0, 0, 0);
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
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 reload()
|
public void imsg(CommandSender s, String msg)
|
||||||
{
|
{
|
||||||
Bukkit.getScheduler().scheduleSyncDelayedTask(Iris.instance, () ->
|
s.sendMessage(ChatColor.GREEN + "[" + ChatColor.DARK_GRAY + "Iris" + ChatColor.GREEN + "]" + ChatColor.GRAY + ": " + msg);
|
||||||
{
|
|
||||||
onDisable();
|
|
||||||
onEnable();
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ChunkGenerator getDefaultWorldGenerator(String worldName, String id)
|
public ChunkGenerator getDefaultWorldGenerator(String worldName, String id)
|
||||||
{
|
{
|
||||||
return new HotswapGenerator(new IrisGenerator());
|
return new IrisChunkGenerator("overworld", 16);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
public static void msg(String string)
|
||||||
public String getTag(String arg0)
|
|
||||||
{
|
{
|
||||||
return makeTag(C.GREEN, C.DARK_GRAY, C.GRAY, C.BOLD + "Iris" + C.RESET);
|
String msg = ChatColor.GREEN + "[Iris]: " + ChatColor.GRAY + string;
|
||||||
}
|
|
||||||
|
|
||||||
public static String makeTag(C brace, C tag, C text, String tagName)
|
if(last.equals(msg))
|
||||||
{
|
|
||||||
return brace + "\u3008" + tag + tagName + brace + "\u3009" + " " + text;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static PackController pack()
|
|
||||||
{
|
|
||||||
return instance.packController;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static ExecutionController exec()
|
|
||||||
{
|
|
||||||
if(executionController == null)
|
|
||||||
{
|
{
|
||||||
executionController = new ExecutionController();
|
return;
|
||||||
executionController.start();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return executionController;
|
last = msg;
|
||||||
|
|
||||||
|
Bukkit.getConsoleSender().sendMessage(msg);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static WandController wand()
|
public static void warn(String string)
|
||||||
{
|
{
|
||||||
return instance.wandController;
|
msg(ChatColor.YELLOW + string);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void error(String string)
|
||||||
|
{
|
||||||
|
msg(ChatColor.RED + string);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void verbose(String string)
|
||||||
|
{
|
||||||
|
msg(ChatColor.GRAY + string);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void success(String string)
|
||||||
|
{
|
||||||
|
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