21 Commits
1.14 ... 1.16

Author SHA1 Message Date
Christian Knaapen
b91e6b9147 Updated radial menu to match 1.18, with build mode categories, descriptions and new icons. Changed reach upgrade recipes. 2023-01-14 15:33:24 +01:00
Christian Knaapen
bb81595c3a Added golden and diamond randomizer bags. Using deferred registries. Revamped radial menu: fixed clicking. Removed old code. 2021-12-05 17:26:21 +01:00
Christian Knaapen
72d1085a54 Updated mapping to 1.16.5 official names. 2021-09-01 14:13:08 +02:00
Christian Knaapen
47f38d0a58 Bumped version number 2021-05-20 21:11:38 +02:00
Alexei Robyn
54d9c3a92f Merged in fakeplayer-fix-1.16 (pull request #3)
Fix FakePlayer-related crashes

Approved-by: Requios
2021-05-20 18:16:16 +00:00
Alexei Robyn
f77a937c6c Fix FakePlayer-related crashes 2021-05-20 14:14:58 +10:00
Christian Knaapen
b41f102f0c Using deferred registry for Randomizer Bag container, which fixes startup crash in 1.16.4 and 1.16.5. 2021-02-03 20:50:09 +01:00
grimm auld
f2fee42c58 Merged in 1.16 (pull request #2)
1.16

Approved-by: Requios
2021-02-02 20:28:16 +00:00
grimmauld
d63786f6e2 merge version bump 2021-02-02 12:52:18 +01:00
Christian Knaapen
a6bb10f06d Version update 2021-01-31 13:38:23 +01:00
grimmauld
5fe5978777 Fix some stuff 2021-01-29 23:43:12 +01:00
grimmauld
7b5f055d22 Get stuff running on 1.16.3 2021-01-29 23:12:11 +01:00
Christian Knaapen
bc6bebe387 Fixed radial menu icons not rendering. Partially fixed shader. 2020-09-03 20:37:50 +02:00
Christian Knaapen
a7961c22a6 Started on GUI for player settings. 2020-08-27 02:24:04 +02:00
Christian Knaapen
96e9e9bb3b Retina display fix 2020-08-26 21:11:51 +02:00
Christian Knaapen
4b22cea9ab Fixes from 1.14 (Fixed freezing when looking up + setting NBT data). 2020-08-25 15:43:15 +02:00
Christian Knaapen
d440325b2a Shader works partially 2020-08-25 15:36:43 +02:00
Christian Knaapen
4bab684369 Working on block previews, updated mappings. 2020-08-24 22:35:13 +02:00
Christian Knaapen
804ed4354b Modifier rendering complete (lines and planes) 2020-08-24 18:18:30 +02:00
Christian Knaapen
31f3cf3233 More work on rendering, mostly test code and a custom rendertype. 2020-08-23 19:27:36 +02:00
Christian Knaapen
e22ad0c311 Initial 1.15 commit 2020-03-15 15:05:57 +01:00
118 changed files with 9080 additions and 7321 deletions

1
.gitignore vendored
View File

@@ -20,6 +20,7 @@ build
# other # other
eclipse eclipse
run run
logs/*
# Files from Forge MDK # Files from Forge MDK
forge*changelog.txt forge*changelog.txt

520
LICENSE.txt Normal file
View File

@@ -0,0 +1,520 @@
Unless noted below, Minecraft Forge, Forge Mod Loader, and all
parts herein are licensed under the terms of the LGPL 2.1 found
here http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt and
copied below.
Homepage: http://minecraftforge.net/
https://github.com/MinecraftForge/MinecraftForge
A note on authorship:
All source artifacts are property of their original author, with
the exclusion of the contents of the patches directory and others
copied from it from time to time. Authorship of the contents of
the patches directory is retained by the Minecraft Forge project.
This is because the patches are partially machine generated
artifacts, and are changed heavily due to the way forge works.
Individual attribution within them is impossible.
Consent:
All contributions to Forge must consent to the release of any
patch content to the Forge project.
A note on infectivity:
The LGPL is chosen specifically so that projects may depend on Forge
features without being infected with its license. That is the
purpose of the LGPL. Mods and others using this code via ordinary
Java mechanics for referencing libraries are specifically not bound
by Forge's license for the Mod code.
=== MCP Data ===
This software includes data from the Minecraft Coder Pack (MCP), with kind permission
from them. The license to MCP data is not transitive - distribution of this data by
third parties requires independent licensing from the MCP team. This data is not
redistributable without permission from the MCP team.
=== Sharing ===
I grant permission for some parts of FML to be redistributed outside the terms of the LGPL, for the benefit of
the minecraft modding community. All contributions to these parts should be licensed under the same additional grant.
-- Runtime patcher --
License is granted to redistribute the runtime patcher code (src/main/java/net/minecraftforge/fml/common/patcher
and subdirectories) under any alternative open source license as classified by the OSI (http://opensource.org/licenses)
-- ASM transformers --
License is granted to redistribute the ASM transformer code (src/main/java/net/minecraftforge/common/asm/ and subdirectories)
under any alternative open source license as classified by the OSI (http://opensource.org/licenses)
=========================================================================
This software includes portions from the Apache Maven project at
http://maven.apache.org/ specifically the ComparableVersion.java code. It is
included based on guidelines at
http://www.softwarefreedom.org/resources/2007/gpl-non-gpl-collaboration.html
with notices intact. The only change is a non-functional change of package name.
This software contains a partial repackaging of javaxdelta, a BSD licensed program for generating
binary differences and applying them, sourced from the subversion at http://sourceforge.net/projects/javaxdelta/
authored by genman, heikok, pivot.
The only changes are to replace some Trove collection types with standard Java collections, and repackaged.
=========================================================================
GNU LESSER GENERAL PUBLIC LICENSE
Version 2.1, February 1999
Copyright (C) 1991, 1999 Free Software Foundation, Inc.
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
Everyone is permitted to copy and distribute verbatim copies
of this license document, but changing it is not allowed.
[This is the first released version of the Lesser GPL. It also counts
as the successor of the GNU Library Public License, version 2, hence
the version number 2.1.]
Preamble
The licenses for most software are designed to take away your
freedom to share and change it. By contrast, the GNU General Public
Licenses are intended to guarantee your freedom to share and change
free software--to make sure the software is free for all its users.
This license, the Lesser General Public License, applies to some
specially designated software packages--typically libraries--of the
Free Software Foundation and other authors who decide to use it. You
can use it too, but we suggest you first think carefully about whether
this license or the ordinary General Public License is the better
strategy to use in any particular case, based on the explanations below.
When we speak of free software, we are referring to freedom of use,
not price. Our General Public Licenses are designed to make sure that
you have the freedom to distribute copies of free software (and charge
for this service if you wish); that you receive source code or can get
it if you want it; that you can change the software and use pieces of
it in new free programs; and that you are informed that you can do
these things.
To protect your rights, we need to make restrictions that forbid
distributors to deny you these rights or to ask you to surrender these
rights. These restrictions translate to certain responsibilities for
you if you distribute copies of the library or if you modify it.
For example, if you distribute copies of the library, whether gratis
or for a fee, you must give the recipients all the rights that we gave
you. You must make sure that they, too, receive or can get the source
code. If you link other code with the library, you must provide
complete object files to the recipients, so that they can relink them
with the library after making changes to the library and recompiling
it. And you must show them these terms so they know their rights.
We protect your rights with a two-step method: (1) we copyright the
library, and (2) we offer you this license, which gives you legal
permission to copy, distribute and/or modify the library.
To protect each distributor, we want to make it very clear that
there is no warranty for the free library. Also, if the library is
modified by someone else and passed on, the recipients should know
that what they have is not the original version, so that the original
author's reputation will not be affected by problems that might be
introduced by others.
Finally, software patents pose a constant threat to the existence of
any free program. We wish to make sure that a company cannot
effectively restrict the users of a free program by obtaining a
restrictive license from a patent holder. Therefore, we insist that
any patent license obtained for a version of the library must be
consistent with the full freedom of use specified in this license.
Most GNU software, including some libraries, is covered by the
ordinary GNU General Public License. This license, the GNU Lesser
General Public License, applies to certain designated libraries, and
is quite different from the ordinary General Public License. We use
this license for certain libraries in order to permit linking those
libraries into non-free programs.
When a program is linked with a library, whether statically or using
a shared library, the combination of the two is legally speaking a
combined work, a derivative of the original library. The ordinary
General Public License therefore permits such linking only if the
entire combination fits its criteria of freedom. The Lesser General
Public License permits more lax criteria for linking other code with
the library.
We call this license the "Lesser" General Public License because it
does Less to protect the user's freedom than the ordinary General
Public License. It also provides other free software developers Less
of an advantage over competing non-free programs. These disadvantages
are the reason we use the ordinary General Public License for many
libraries. However, the Lesser license provides advantages in certain
special circumstances.
For example, on rare occasions, there may be a special need to
encourage the widest possible use of a certain library, so that it becomes
a de-facto standard. To achieve this, non-free programs must be
allowed to use the library. A more frequent case is that a free
library does the same job as widely used non-free libraries. In this
case, there is little to gain by limiting the free library to free
software only, so we use the Lesser General Public License.
In other cases, permission to use a particular library in non-free
programs enables a greater number of people to use a large body of
free software. For example, permission to use the GNU C Library in
non-free programs enables many more people to use the whole GNU
operating system, as well as its variant, the GNU/Linux operating
system.
Although the Lesser General Public License is Less protective of the
users' freedom, it does ensure that the user of a program that is
linked with the Library has the freedom and the wherewithal to run
that program using a modified version of the Library.
The precise terms and conditions for copying, distribution and
modification follow. Pay close attention to the difference between a
"work based on the library" and a "work that uses the library". The
former contains code derived from the library, whereas the latter must
be combined with the library in order to run.
GNU LESSER GENERAL PUBLIC LICENSE
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
0. This License Agreement applies to any software library or other
program which contains a notice placed by the copyright holder or
other authorized party saying it may be distributed under the terms of
this Lesser General Public License (also called "this License").
Each licensee is addressed as "you".
A "library" means a collection of software functions and/or data
prepared so as to be conveniently linked with application programs
(which use some of those functions and data) to form executables.
The "Library", below, refers to any such software library or work
which has been distributed under these terms. A "work based on the
Library" means either the Library or any derivative work under
copyright law: that is to say, a work containing the Library or a
portion of it, either verbatim or with modifications and/or translated
straightforwardly into another language. (Hereinafter, translation is
included without limitation in the term "modification".)
"Source code" for a work means the preferred form of the work for
making modifications to it. For a library, complete source code means
all the source code for all modules it contains, plus any associated
interface definition files, plus the scripts used to control compilation
and installation of the library.
Activities other than copying, distribution and modification are not
covered by this License; they are outside its scope. The act of
running a program using the Library is not restricted, and output from
such a program is covered only if its contents constitute a work based
on the Library (independent of the use of the Library in a tool for
writing it). Whether that is true depends on what the Library does
and what the program that uses the Library does.
1. You may copy and distribute verbatim copies of the Library's
complete source code as you receive it, in any medium, provided that
you conspicuously and appropriately publish on each copy an
appropriate copyright notice and disclaimer of warranty; keep intact
all the notices that refer to this License and to the absence of any
warranty; and distribute a copy of this License along with the
Library.
You may charge a fee for the physical act of transferring a copy,
and you may at your option offer warranty protection in exchange for a
fee.
2. You may modify your copy or copies of the Library or any portion
of it, thus forming a work based on the Library, and copy and
distribute such modifications or work under the terms of Section 1
above, provided that you also meet all of these conditions:
a) The modified work must itself be a software library.
b) You must cause the files modified to carry prominent notices
stating that you changed the files and the date of any change.
c) You must cause the whole of the work to be licensed at no
charge to all third parties under the terms of this License.
d) If a facility in the modified Library refers to a function or a
table of data to be supplied by an application program that uses
the facility, other than as an argument passed when the facility
is invoked, then you must make a good faith effort to ensure that,
in the event an application does not supply such function or
table, the facility still operates, and performs whatever part of
its purpose remains meaningful.
(For example, a function in a library to compute square roots has
a purpose that is entirely well-defined independent of the
application. Therefore, Subsection 2d requires that any
application-supplied function or table used by this function must
be optional: if the application does not supply it, the square
root function must still compute square roots.)
These requirements apply to the modified work as a whole. If
identifiable sections of that work are not derived from the Library,
and can be reasonably considered independent and separate works in
themselves, then this License, and its terms, do not apply to those
sections when you distribute them as separate works. But when you
distribute the same sections as part of a whole which is a work based
on the Library, the distribution of the whole must be on the terms of
this License, whose permissions for other licensees extend to the
entire whole, and thus to each and every part regardless of who wrote
it.
Thus, it is not the intent of this section to claim rights or contest
your rights to work written entirely by you; rather, the intent is to
exercise the right to control the distribution of derivative or
collective works based on the Library.
In addition, mere aggregation of another work not based on the Library
with the Library (or with a work based on the Library) on a volume of
a storage or distribution medium does not bring the other work under
the scope of this License.
3. You may opt to apply the terms of the ordinary GNU General Public
License instead of this License to a given copy of the Library. To do
this, you must alter all the notices that refer to this License, so
that they refer to the ordinary GNU General Public License, version 2,
instead of to this License. (If a newer version than version 2 of the
ordinary GNU General Public License has appeared, then you can specify
that version instead if you wish.) Do not make any other change in
these notices.
Once this change is made in a given copy, it is irreversible for
that copy, so the ordinary GNU General Public License applies to all
subsequent copies and derivative works made from that copy.
This option is useful when you wish to copy part of the code of
the Library into a program that is not a library.
4. You may copy and distribute the Library (or a portion or
derivative of it, under Section 2) in object code or executable form
under the terms of Sections 1 and 2 above provided that you accompany
it with the complete corresponding machine-readable source code, which
must be distributed under the terms of Sections 1 and 2 above on a
medium customarily used for software interchange.
If distribution of object code is made by offering access to copy
from a designated place, then offering equivalent access to copy the
source code from the same place satisfies the requirement to
distribute the source code, even though third parties are not
compelled to copy the source along with the object code.
5. A program that contains no derivative of any portion of the
Library, but is designed to work with the Library by being compiled or
linked with it, is called a "work that uses the Library". Such a
work, in isolation, is not a derivative work of the Library, and
therefore falls outside the scope of this License.
However, linking a "work that uses the Library" with the Library
creates an executable that is a derivative of the Library (because it
contains portions of the Library), rather than a "work that uses the
library". The executable is therefore covered by this License.
Section 6 states terms for distribution of such executables.
When a "work that uses the Library" uses material from a header file
that is part of the Library, the object code for the work may be a
derivative work of the Library even though the source code is not.
Whether this is true is especially significant if the work can be
linked without the Library, or if the work is itself a library. The
threshold for this to be true is not precisely defined by law.
If such an object file uses only numerical parameters, data
structure layouts and accessors, and small macros and small inline
functions (ten lines or less in length), then the use of the object
file is unrestricted, regardless of whether it is legally a derivative
work. (Executables containing this object code plus portions of the
Library will still fall under Section 6.)
Otherwise, if the work is a derivative of the Library, you may
distribute the object code for the work under the terms of Section 6.
Any executables containing that work also fall under Section 6,
whether or not they are linked directly with the Library itself.
6. As an exception to the Sections above, you may also combine or
link a "work that uses the Library" with the Library to produce a
work containing portions of the Library, and distribute that work
under terms of your choice, provided that the terms permit
modification of the work for the customer's own use and reverse
engineering for debugging such modifications.
You must give prominent notice with each copy of the work that the
Library is used in it and that the Library and its use are covered by
this License. You must supply a copy of this License. If the work
during execution displays copyright notices, you must include the
copyright notice for the Library among them, as well as a reference
directing the user to the copy of this License. Also, you must do one
of these things:
a) Accompany the work with the complete corresponding
machine-readable source code for the Library including whatever
changes were used in the work (which must be distributed under
Sections 1 and 2 above); and, if the work is an executable linked
with the Library, with the complete machine-readable "work that
uses the Library", as object code and/or source code, so that the
user can modify the Library and then relink to produce a modified
executable containing the modified Library. (It is understood
that the user who changes the contents of definitions files in the
Library will not necessarily be able to recompile the application
to use the modified definitions.)
b) Use a suitable shared library mechanism for linking with the
Library. A suitable mechanism is one that (1) uses at run time a
copy of the library already present on the user's computer system,
rather than copying library functions into the executable, and (2)
will operate properly with a modified version of the library, if
the user installs one, as long as the modified version is
interface-compatible with the version that the work was made with.
c) Accompany the work with a written offer, valid for at
least three years, to give the same user the materials
specified in Subsection 6a, above, for a charge no more
than the cost of performing this distribution.
d) If distribution of the work is made by offering access to copy
from a designated place, offer equivalent access to copy the above
specified materials from the same place.
e) Verify that the user has already received a copy of these
materials or that you have already sent this user a copy.
For an executable, the required form of the "work that uses the
Library" must include any data and utility programs needed for
reproducing the executable from it. However, as a special exception,
the materials to be distributed need not include anything that is
normally distributed (in either source or binary form) with the major
components (compiler, kernel, and so on) of the operating system on
which the executable runs, unless that component itself accompanies
the executable.
It may happen that this requirement contradicts the license
restrictions of other proprietary libraries that do not normally
accompany the operating system. Such a contradiction means you cannot
use both them and the Library together in an executable that you
distribute.
7. You may place library facilities that are a work based on the
Library side-by-side in a single library together with other library
facilities not covered by this License, and distribute such a combined
library, provided that the separate distribution of the work based on
the Library and of the other library facilities is otherwise
permitted, and provided that you do these two things:
a) Accompany the combined library with a copy of the same work
based on the Library, uncombined with any other library
facilities. This must be distributed under the terms of the
Sections above.
b) Give prominent notice with the combined library of the fact
that part of it is a work based on the Library, and explaining
where to find the accompanying uncombined form of the same work.
8. You may not copy, modify, sublicense, link with, or distribute
the Library except as expressly provided under this License. Any
attempt otherwise to copy, modify, sublicense, link with, or
distribute the Library is void, and will automatically terminate your
rights under this License. However, parties who have received copies,
or rights, from you under this License will not have their licenses
terminated so long as such parties remain in full compliance.
9. You are not required to accept this License, since you have not
signed it. However, nothing else grants you permission to modify or
distribute the Library or its derivative works. These actions are
prohibited by law if you do not accept this License. Therefore, by
modifying or distributing the Library (or any work based on the
Library), you indicate your acceptance of this License to do so, and
all its terms and conditions for copying, distributing or modifying
the Library or works based on it.
10. Each time you redistribute the Library (or any work based on the
Library), the recipient automatically receives a license from the
original licensor to copy, distribute, link with or modify the Library
subject to these terms and conditions. You may not impose any further
restrictions on the recipients' exercise of the rights granted herein.
You are not responsible for enforcing compliance by third parties with
this License.
11. If, as a consequence of a court judgment or allegation of patent
infringement or for any other reason (not limited to patent issues),
conditions are imposed on you (whether by court order, agreement or
otherwise) that contradict the conditions of this License, they do not
excuse you from the conditions of this License. If you cannot
distribute so as to satisfy simultaneously your obligations under this
License and any other pertinent obligations, then as a consequence you
may not distribute the Library at all. For example, if a patent
license would not permit royalty-free redistribution of the Library by
all those who receive copies directly or indirectly through you, then
the only way you could satisfy both it and this License would be to
refrain entirely from distribution of the Library.
If any portion of this section is held invalid or unenforceable under any
particular circumstance, the balance of the section is intended to apply,
and the section as a whole is intended to apply in other circumstances.
It is not the purpose of this section to induce you to infringe any
patents or other property right claims or to contest validity of any
such claims; this section has the sole purpose of protecting the
integrity of the free software distribution system which is
implemented by public license practices. Many people have made
generous contributions to the wide range of software distributed
through that system in reliance on consistent application of that
system; it is up to the author/donor to decide if he or she is willing
to distribute software through any other system and a licensee cannot
impose that choice.
This section is intended to make thoroughly clear what is believed to
be a consequence of the rest of this License.
12. If the distribution and/or use of the Library is restricted in
certain countries either by patents or by copyrighted interfaces, the
original copyright holder who places the Library under this License may add
an explicit geographical distribution limitation excluding those countries,
so that distribution is permitted only in or among countries not thus
excluded. In such case, this License incorporates the limitation as if
written in the body of this License.
13. The Free Software Foundation may publish revised and/or new
versions of the Lesser General Public License from time to time.
Such new versions will be similar in spirit to the present version,
but may differ in detail to address new problems or concerns.
Each version is given a distinguishing version number. If the Library
specifies a version number of this License which applies to it and
"any later version", you have the option of following the terms and
conditions either of that version or of any later version published by
the Free Software Foundation. If the Library does not specify a
license version number, you may choose any version ever published by
the Free Software Foundation.
14. If you wish to incorporate parts of the Library into other free
programs whose distribution conditions are incompatible with these,
write to the author to ask for permission. For software which is
copyrighted by the Free Software Foundation, write to the Free
Software Foundation; we sometimes make exceptions for this. Our
decision will be guided by the two goals of preserving the free status
of all derivatives of our free software and of promoting the sharing
and reuse of software generally.
NO WARRANTY
15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO
WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW.
EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR
OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY
KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE
LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME
THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN
WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY
AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU
FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR
CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE
LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING
RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A
FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF
SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
DAMAGES.
END OF TERMS AND CONDITIONS

View File

@@ -1 +0,0 @@
The 1.12 repository can be found here: https://bitbucket.org/Requios/effortless-building/src/master/

View File

@@ -5,7 +5,7 @@ buildscript {
mavenCentral() mavenCentral()
} }
dependencies { dependencies {
classpath group: 'net.minecraftforge.gradle', name: 'ForgeGradle', version: '3.+', changing: true classpath group: 'net.minecraftforge.gradle', name: 'ForgeGradle', version: '5.1+', changing: true
} }
} }
apply plugin: 'net.minecraftforge.gradle' apply plugin: 'net.minecraftforge.gradle'
@@ -13,7 +13,7 @@ apply plugin: 'net.minecraftforge.gradle'
apply plugin: 'eclipse' apply plugin: 'eclipse'
apply plugin: 'maven-publish' apply plugin: 'maven-publish'
version = '1.14.4-2.18' version = '1.16.3-2.32'
group = 'nl.requios.effortlessbuilding' // http://maven.apache.org/guides/mini/guide-naming-conventions.html group = 'nl.requios.effortlessbuilding' // http://maven.apache.org/guides/mini/guide-naming-conventions.html
archivesBaseName = 'effortlessbuilding' archivesBaseName = 'effortlessbuilding'
@@ -25,11 +25,10 @@ minecraft {
// stable_# Stables are built at the discretion of the MCP team. // stable_# Stables are built at the discretion of the MCP team.
// Use non-default mappings at your own risk. they may not always work. // Use non-default mappings at your own risk. they may not always work.
// Simply re-run your setup task after changing the mappings to update your workspace. // Simply re-run your setup task after changing the mappings to update your workspace.
mappings channel: 'snapshot', version: '20190719-1.14.3' mappings channel: 'official', version: '1.16.5'
accessTransformer = file('src/main/resources/META-INF/accesstransformer.cfg')
// makeObfSourceJar = false // an Srg named sources jar is made by default. uncomment this to disable. // makeObfSourceJar = false // an Srg named sources jar is made by default. uncomment this to disable.
// accessTransformer = file('src/main/resources/META-INF/accesstransformer.cfg')
// Default run configurations. // Default run configurations.
// These can be tweaked, removed, or duplicated as needed. // These can be tweaked, removed, or duplicated as needed.
runs { runs {
@@ -74,7 +73,8 @@ minecraft {
// Recommended logging level for the console // Recommended logging level for the console
property 'forge.logging.console.level', 'debug' property 'forge.logging.console.level', 'debug'
args '--mod', 'effortlessbuilding', '--all', '--output', file('src/generated/resources/') // Specify the modid for data generation, where to output the resulting resource, and where to look for existing resources.
args '--mod', 'effortlessbuilding', '--all', '--output', file('src/generated/resources/'), '--existing', file('src/main/resources/')
mods { mods {
effortlessbuilding { effortlessbuilding {
@@ -89,7 +89,7 @@ dependencies {
// Specify the version of Minecraft to use, If this is any group other then 'net.minecraft' it is assumed // Specify the version of Minecraft to use, If this is any group other then 'net.minecraft' it is assumed
// that the dep is a ForgeGradle 'patcher' dependency. And it's patches will be applied. // that the dep is a ForgeGradle 'patcher' dependency. And it's patches will be applied.
// The userdev artifact is a special name and will get all sorts of transformations applied to it. // The userdev artifact is a special name and will get all sorts of transformations applied to it.
minecraft 'net.minecraftforge:forge:1.14.4-28.1.102' minecraft 'net.minecraftforge:forge:1.16.3-34.0.9'
// You may put jars on which you depend on in ./libs or you may define them like so.. // You may put jars on which you depend on in ./libs or you may define them like so..
// compile "some.group:artifact:version:classifier" // compile "some.group:artifact:version:classifier"
@@ -127,18 +127,15 @@ jar {
} }
// Example configuration to allow publishing using the maven-publish task // Example configuration to allow publishing using the maven-publish task
// we define a custom artifact that is sourced from the reobfJar output task // This is the preferred method to reobfuscate your jar file
// and then declare that to be published jar.finalizedBy('reobfJar')
// Note you'll need to add a repository here // However if you are in a multi-project build, dev time needs unobfed jar files, so you can delay the obfuscation until publishing by doing
def reobfFile = file("$buildDir/reobfJar/output.jar") //publish.dependsOn('reobfJar')
def reobfArtifact = artifacts.add('default', reobfFile) {
type 'jar'
builtBy 'reobfJar'
}
publishing { publishing {
publications { publications {
mavenJava(MavenPublication) { mavenJava(MavenPublication) {
artifact reobfArtifact artifact jar
} }
} }
repositories { repositories {

Binary file not shown.

View File

@@ -1,5 +1,5 @@
distributionBase=GRADLE_USER_HOME distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists distributionPath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-7.2-bin.zip
zipStoreBase=GRADLE_USER_HOME zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists zipStorePath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-4.9-bin.zip

71
gradlew vendored
View File

@@ -1,4 +1,20 @@
#!/usr/bin/env sh #!/usr/bin/env bash
#
# Copyright 2015 the original author or authors.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# https://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
############################################################################## ##############################################################################
## ##
@@ -28,7 +44,7 @@ APP_NAME="Gradle"
APP_BASE_NAME=`basename "$0"` APP_BASE_NAME=`basename "$0"`
# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. # Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
DEFAULT_JVM_OPTS="" DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"'
# Use the maximum available, or set MAX_FD != -1 to use that value. # Use the maximum available, or set MAX_FD != -1 to use that value.
MAX_FD="maximum" MAX_FD="maximum"
@@ -56,7 +72,7 @@ case "`uname`" in
Darwin* ) Darwin* )
darwin=true darwin=true
;; ;;
MINGW* ) MSYS* | MINGW* )
msys=true msys=true
;; ;;
NONSTOP* ) NONSTOP* )
@@ -66,6 +82,7 @@ esac
CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
# Determine the Java command to use to start the JVM. # Determine the Java command to use to start the JVM.
if [ -n "$JAVA_HOME" ] ; then if [ -n "$JAVA_HOME" ] ; then
if [ -x "$JAVA_HOME/jre/sh/java" ] ; then if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
@@ -109,10 +126,11 @@ if $darwin; then
GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\"" GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
fi fi
# For Cygwin, switch paths to Windows format before running java # For Cygwin or MSYS, switch paths to Windows format before running java
if $cygwin ; then if [ "$cygwin" = "true" -o "$msys" = "true" ] ; then
APP_HOME=`cygpath --path --mixed "$APP_HOME"` APP_HOME=`cygpath --path --mixed "$APP_HOME"`
CLASSPATH=`cygpath --path --mixed "$CLASSPATH"` CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
JAVACMD=`cygpath --unix "$JAVACMD"` JAVACMD=`cygpath --unix "$JAVACMD"`
# We build the pattern for arguments to be converted via cygpath # We build the pattern for arguments to be converted via cygpath
@@ -138,35 +156,28 @@ if $cygwin ; then
else else
eval `echo args$i`="\"$arg\"" eval `echo args$i`="\"$arg\""
fi fi
i=$((i+1)) i=`expr $i + 1`
done done
case $i in case $i in
(0) set -- ;; 0) set -- ;;
(1) set -- "$args0" ;; 1) set -- "$args0" ;;
(2) set -- "$args0" "$args1" ;; 2) set -- "$args0" "$args1" ;;
(3) set -- "$args0" "$args1" "$args2" ;; 3) set -- "$args0" "$args1" "$args2" ;;
(4) set -- "$args0" "$args1" "$args2" "$args3" ;; 4) set -- "$args0" "$args1" "$args2" "$args3" ;;
(5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;; 5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
(6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;; 6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
(7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;; 7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
(8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;; 8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
(9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;; 9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
esac esac
fi fi
# Escape application args ARGV=("$@")
save () { eval set -- $DEFAULT_JVM_OPTS
for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done
echo " "
}
APP_ARGS=$(save "$@")
# Collect all arguments for the java command, following the shell quoting and substitution rules IFS=$'
eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS" ' read -rd '' -a JAVA_OPTS_ARR <<< "$(echo $JAVA_OPTS | xargs -n1)"
IFS=$'
' read -rd '' -a GRADLE_OPTS_ARR <<< "$(echo $GRADLE_OPTS | xargs -n1)"
# by default we should be in the correct project dir, but when run from Finder on Mac, the cwd is wrong exec "$JAVACMD" "$@" "${JAVA_OPTS_ARR[@]}" "${GRADLE_OPTS_ARR[@]}" "-Dorg.gradle.appname=$APP_BASE_NAME" -classpath "$CLASSPATH" org.gradle.wrapper.GradleWrapperMain "${ARGV[@]}"
if [ "$(uname)" = "Darwin" ] && [ "$HOME" = "$PWD" ]; then
cd "$(dirname "$0")"
fi
exec "$JAVACMD" "$@"

43
gradlew.bat vendored
View File

@@ -1,3 +1,19 @@
@rem
@rem Copyright 2015 the original author or authors.
@rem
@rem Licensed under the Apache License, Version 2.0 (the "License");
@rem you may not use this file except in compliance with the License.
@rem You may obtain a copy of the License at
@rem
@rem https://www.apache.org/licenses/LICENSE-2.0
@rem
@rem Unless required by applicable law or agreed to in writing, software
@rem distributed under the License is distributed on an "AS IS" BASIS,
@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
@rem See the License for the specific language governing permissions and
@rem limitations under the License.
@rem
@if "%DEBUG%" == "" @echo off @if "%DEBUG%" == "" @echo off
@rem ########################################################################## @rem ##########################################################################
@rem @rem
@@ -13,15 +29,18 @@ if "%DIRNAME%" == "" set DIRNAME=.
set APP_BASE_NAME=%~n0 set APP_BASE_NAME=%~n0
set APP_HOME=%DIRNAME% set APP_HOME=%DIRNAME%
@rem Resolve any "." and ".." in APP_HOME to make it shorter.
for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi
@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. @rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
set DEFAULT_JVM_OPTS= set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m"
@rem Find java.exe @rem Find java.exe
if defined JAVA_HOME goto findJavaFromJavaHome if defined JAVA_HOME goto findJavaFromJavaHome
set JAVA_EXE=java.exe set JAVA_EXE=java.exe
%JAVA_EXE% -version >NUL 2>&1 %JAVA_EXE% -version >NUL 2>&1
if "%ERRORLEVEL%" == "0" goto init if "%ERRORLEVEL%" == "0" goto execute
echo. echo.
echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
@@ -35,7 +54,7 @@ goto fail
set JAVA_HOME=%JAVA_HOME:"=% set JAVA_HOME=%JAVA_HOME:"=%
set JAVA_EXE=%JAVA_HOME%/bin/java.exe set JAVA_EXE=%JAVA_HOME%/bin/java.exe
if exist "%JAVA_EXE%" goto init if exist "%JAVA_EXE%" goto execute
echo. echo.
echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
@@ -45,28 +64,14 @@ echo location of your Java installation.
goto fail goto fail
:init
@rem Get command-line arguments, handling Windows variants
if not "%OS%" == "Windows_NT" goto win9xME_args
:win9xME_args
@rem Slurp the command line arguments.
set CMD_LINE_ARGS=
set _SKIP=2
:win9xME_args_slurp
if "x%~1" == "x" goto execute
set CMD_LINE_ARGS=%*
:execute :execute
@rem Setup the command line @rem Setup the command line
set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
@rem Execute Gradle @rem Execute Gradle
"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS% "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %*
:end :end
@rem End local scope for the variables with windows NT shell @rem End local scope for the variables with windows NT shell

View File

@@ -1,37 +1,30 @@
package nl.requios.effortlessbuilding; package nl.requios.effortlessbuilding;
import net.minecraft.block.Block;
import net.minecraft.entity.player.PlayerEntity; import net.minecraft.entity.player.PlayerEntity;
import net.minecraft.inventory.container.Container; import net.minecraft.inventory.container.Container;
import net.minecraft.inventory.container.ContainerType; import net.minecraft.inventory.container.ContainerType;
import net.minecraft.item.Item; import net.minecraft.item.Item;
import net.minecraft.util.ResourceLocation;
import net.minecraft.util.registry.Registry;
import net.minecraft.util.text.StringTextComponent; import net.minecraft.util.text.StringTextComponent;
import net.minecraftforge.common.MinecraftForge;
import net.minecraftforge.common.capabilities.CapabilityManager; import net.minecraftforge.common.capabilities.CapabilityManager;
import net.minecraftforge.common.crafting.CraftingHelper;
import net.minecraftforge.eventbus.api.SubscribeEvent; import net.minecraftforge.eventbus.api.SubscribeEvent;
import net.minecraftforge.fml.DistExecutor; import net.minecraftforge.fml.DistExecutor;
import net.minecraftforge.fml.ExtensionPoint;
import net.minecraftforge.fml.ModLoadingContext; import net.minecraftforge.fml.ModLoadingContext;
import net.minecraftforge.fml.RegistryObject;
import net.minecraftforge.fml.common.Mod; import net.minecraftforge.fml.common.Mod;
import net.minecraftforge.fml.config.ModConfig; import net.minecraftforge.fml.config.ModConfig;
import net.minecraftforge.fml.event.lifecycle.FMLClientSetupEvent; import net.minecraftforge.fml.event.lifecycle.FMLClientSetupEvent;
import net.minecraftforge.fml.event.lifecycle.FMLCommonSetupEvent; import net.minecraftforge.fml.event.lifecycle.FMLCommonSetupEvent;
import net.minecraftforge.fml.event.lifecycle.InterModEnqueueEvent;
import net.minecraftforge.fml.event.lifecycle.InterModProcessEvent;
import net.minecraftforge.fml.event.server.FMLServerStartingEvent;
import net.minecraftforge.fml.javafmlmod.FMLJavaModLoadingContext; import net.minecraftforge.fml.javafmlmod.FMLJavaModLoadingContext;
import net.minecraftforge.fml.network.IContainerFactory;
import net.minecraftforge.registries.DeferredRegister;
import net.minecraftforge.registries.ForgeRegistries;
import nl.requios.effortlessbuilding.capability.ModeCapabilityManager; import nl.requios.effortlessbuilding.capability.ModeCapabilityManager;
import nl.requios.effortlessbuilding.capability.ModifierCapabilityManager; import nl.requios.effortlessbuilding.capability.ModifierCapabilityManager;
import nl.requios.effortlessbuilding.command.CommandReach;
import nl.requios.effortlessbuilding.compatibility.CompatHelper; import nl.requios.effortlessbuilding.compatibility.CompatHelper;
import nl.requios.effortlessbuilding.gui.DiamondRandomizerBagContainer;
import nl.requios.effortlessbuilding.gui.GoldenRandomizerBagContainer;
import nl.requios.effortlessbuilding.gui.RandomizerBagContainer; import nl.requios.effortlessbuilding.gui.RandomizerBagContainer;
import nl.requios.effortlessbuilding.item.ItemRandomizerBag; import nl.requios.effortlessbuilding.item.*;
import nl.requios.effortlessbuilding.item.ItemReachUpgrade1;
import nl.requios.effortlessbuilding.item.ItemReachUpgrade2;
import nl.requios.effortlessbuilding.item.ItemReachUpgrade3;
import nl.requios.effortlessbuilding.network.PacketHandler; import nl.requios.effortlessbuilding.network.PacketHandler;
import nl.requios.effortlessbuilding.proxy.ClientProxy; import nl.requios.effortlessbuilding.proxy.ClientProxy;
import nl.requios.effortlessbuilding.proxy.IProxy; import nl.requios.effortlessbuilding.proxy.IProxy;
@@ -41,59 +34,66 @@ import org.apache.logging.log4j.Logger;
// The value here should match an entry in the META-INF/mods.toml file // The value here should match an entry in the META-INF/mods.toml file
@Mod(EffortlessBuilding.MODID) @Mod(EffortlessBuilding.MODID)
@Mod.EventBusSubscriber(bus=Mod.EventBusSubscriber.Bus.MOD) @Mod.EventBusSubscriber(bus = Mod.EventBusSubscriber.Bus.MOD)
public class EffortlessBuilding public class EffortlessBuilding {
{
public static final String MODID = "effortlessbuilding"; public static final String MODID = "effortlessbuilding";
public static final String NAME = "Effortless Building";
public static final String VERSION = "1.14.4-2.18";
public static EffortlessBuilding instance;
public static final Logger logger = LogManager.getLogger(); public static final Logger logger = LogManager.getLogger();
public static EffortlessBuilding instance;
public static IProxy proxy = DistExecutor.runForDist(() -> ClientProxy::new, () -> ServerProxy::new); public static IProxy proxy = DistExecutor.runForDist(() -> ClientProxy::new, () -> ServerProxy::new);
public static final ItemRandomizerBag ITEM_RANDOMIZER_BAG = new ItemRandomizerBag(); //Registration
public static final ItemReachUpgrade1 ITEM_REACH_UPGRADE_1 = new ItemReachUpgrade1(); private static final DeferredRegister<Item> ITEMS = DeferredRegister.create(ForgeRegistries.ITEMS, MODID);
public static final ItemReachUpgrade2 ITEM_REACH_UPGRADE_2 = new ItemReachUpgrade2(); private static final DeferredRegister<ContainerType<?>> CONTAINERS = DeferredRegister.create(ForgeRegistries.CONTAINERS, EffortlessBuilding.MODID);
public static final ItemReachUpgrade3 ITEM_REACH_UPGRADE_3 = new ItemReachUpgrade3();
public static final Block[] BLOCKS = { public static final RegistryObject<Item> RANDOMIZER_BAG_ITEM = ITEMS.register("randomizer_bag", RandomizerBagItem::new);
}; public static final RegistryObject<Item> GOLDEN_RANDOMIZER_BAG_ITEM = ITEMS.register("golden_randomizer_bag", GoldenRandomizerBagItem::new);
public static final RegistryObject<Item> DIAMOND_RANDOMIZER_BAG_ITEM = ITEMS.register("diamond_randomizer_bag", DiamondRandomizerBagItem::new);
public static final RegistryObject<Item> REACH_UPGRADE_1_ITEM = ITEMS.register("reach_upgrade1", ReachUpgrade1Item::new);
public static final RegistryObject<Item> REACH_UPGRADE_2_ITEM = ITEMS.register("reach_upgrade2", ReachUpgrade2Item::new);
public static final RegistryObject<Item> REACH_UPGRADE_3_ITEM = ITEMS.register("reach_upgrade3", ReachUpgrade3Item::new);
public static final Item[] ITEMS = { public static final RegistryObject<ContainerType<RandomizerBagContainer>> RANDOMIZER_BAG_CONTAINER = CONTAINERS.register("randomizer_bag", () -> registerContainer(RandomizerBagContainer::new));
ITEM_RANDOMIZER_BAG, public static final RegistryObject<ContainerType<GoldenRandomizerBagContainer>> GOLDEN_RANDOMIZER_BAG_CONTAINER = CONTAINERS.register("golden_randomizer_bag", () -> registerContainer(GoldenRandomizerBagContainer::new));
ITEM_REACH_UPGRADE_1, public static final RegistryObject<ContainerType<DiamondRandomizerBagContainer>> DIAMOND_RANDOMIZER_BAG_CONTAINER = CONTAINERS.register("diamond_randomizer_bag", () -> registerContainer(DiamondRandomizerBagContainer::new));
ITEM_REACH_UPGRADE_2,
ITEM_REACH_UPGRADE_3
};
public static final ContainerType<RandomizerBagContainer> RANDOMIZER_BAG_CONTAINER = register("randomizer_bag", RandomizerBagContainer::new);
public static final ResourceLocation RANDOMIZER_BAG_GUI = new ResourceLocation(EffortlessBuilding.MODID, "randomizer_bag");
public EffortlessBuilding() { public EffortlessBuilding() {
instance = this; instance = this;
// Register the setup method for modloading // Register ourselves for server and other game events we are interested in
FMLJavaModLoadingContext.get().getModEventBus().addListener(this::setup); FMLJavaModLoadingContext.get().getModEventBus().register(this);
// Register the enqueueIMC method for modloading
FMLJavaModLoadingContext.get().getModEventBus().addListener(this::enqueueIMC); ITEMS.register(FMLJavaModLoadingContext.get().getModEventBus());
// Register the processIMC method for modloading CONTAINERS.register(FMLJavaModLoadingContext.get().getModEventBus());
FMLJavaModLoadingContext.get().getModEventBus().addListener(this::processIMC);
// Register the clientSetup method for modloading
FMLJavaModLoadingContext.get().getModEventBus().addListener(this::clientSetup);
//Register config //Register config
ModLoadingContext.get().registerConfig(ModConfig.Type.COMMON, BuildConfig.spec); ModLoadingContext.get().registerConfig(ModConfig.Type.COMMON, BuildConfig.spec);
}
// Register ourselves for server and other game events we are interested in public static <T extends Container> ContainerType<T> registerContainer(IContainerFactory<T> fact){
MinecraftForge.EVENT_BUS.register(this); ContainerType<T> type = new ContainerType<T>(fact);
return type;
}
public static void log(String msg) {
logger.info(msg);
}
public static void log(PlayerEntity player, String msg) {
log(player, msg, false);
}
public static void log(PlayerEntity player, String msg, boolean actionBar) {
player.displayClientMessage(new StringTextComponent(msg), actionBar);
}
//Log with translation supported, call either on client or server (which then sends a message)
public static void logTranslate(PlayerEntity player, String prefix, String translationKey, String suffix, boolean actionBar) {
proxy.logTranslate(player, prefix, translationKey, suffix, actionBar);
} }
@SubscribeEvent @SubscribeEvent
public void setup(final FMLCommonSetupEvent event) public void setup(final FMLCommonSetupEvent event) {
{
CapabilityManager.INSTANCE.register(ModifierCapabilityManager.IModifierCapability.class, new ModifierCapabilityManager.Storage(), ModifierCapabilityManager.ModifierCapability::new); CapabilityManager.INSTANCE.register(ModifierCapabilityManager.IModifierCapability.class, new ModifierCapabilityManager.Storage(), ModifierCapabilityManager.ModifierCapability::new);
CapabilityManager.INSTANCE.register(ModeCapabilityManager.IModeCapability.class, new ModeCapabilityManager.Storage(), ModeCapabilityManager.ModeCapability::new); CapabilityManager.INSTANCE.register(ModeCapabilityManager.IModeCapability.class, new ModeCapabilityManager.Storage(), ModeCapabilityManager.ModeCapability::new);
@@ -112,46 +112,4 @@ public class EffortlessBuilding
proxy.clientSetup(event); proxy.clientSetup(event);
} }
@SubscribeEvent
public void enqueueIMC(final InterModEnqueueEvent event) {
// some example code to dispatch IMC to another mod
// InterModComms.sendTo("examplemod", "helloworld", () -> { logger.info("Hello world from the MDK"); return "Hello world";});
}
@SubscribeEvent
public void processIMC(final InterModProcessEvent event) {
// some example code to receive and process InterModComms from other mods
// logger.info("Got IMC {}", event.getIMCStream().
// map(m->m.getMessageSupplier().get()).
// collect(Collectors.toList()));
}
@SubscribeEvent
public void onServerStarting(FMLServerStartingEvent event) {
CommandReach.register(event.getCommandDispatcher());
}
private static <T extends Container> ContainerType<T> register(String key, ContainerType.IFactory<T> factory) {
return Registry.register(Registry.MENU, key, new ContainerType<>(factory));
}
public static void log(String msg){
logger.info(msg);
}
public static void log(PlayerEntity player, String msg){
log(player, msg, false);
}
public static void log(PlayerEntity player, String msg, boolean actionBar){
player.sendStatusMessage(new StringTextComponent(msg), actionBar);
}
//Log with translation supported, call either on client or server (which then sends a message)
public static void logTranslate(PlayerEntity player, String prefix, String translationKey, String suffix, boolean actionBar){
proxy.logTranslate(player, prefix, translationKey, suffix, actionBar);
}
} }

View File

@@ -8,7 +8,7 @@ import net.minecraft.entity.player.ServerPlayerEntity;
import net.minecraft.util.ResourceLocation; import net.minecraft.util.ResourceLocation;
import net.minecraft.util.math.BlockPos; import net.minecraft.util.math.BlockPos;
import net.minecraft.world.World; import net.minecraft.world.World;
import net.minecraftforge.client.event.TextureStitchEvent; import net.minecraftforge.common.util.FakePlayer;
import net.minecraftforge.event.AttachCapabilitiesEvent; import net.minecraftforge.event.AttachCapabilitiesEvent;
import net.minecraftforge.event.entity.player.PlayerEvent; import net.minecraftforge.event.entity.player.PlayerEvent;
import net.minecraftforge.event.world.BlockEvent; import net.minecraftforge.event.world.BlockEvent;
@@ -32,39 +32,25 @@ import nl.requios.effortlessbuilding.network.RequestLookAtMessage;
import java.util.List; import java.util.List;
@Mod.EventBusSubscriber @Mod.EventBusSubscriber
public class EventHandler public class EventHandler {
{
@SubscribeEvent @SubscribeEvent
public static void attachCapabilities(AttachCapabilitiesEvent<Entity> event) { public static void attachCapabilities(AttachCapabilitiesEvent<Entity> event) {
if (event.getObject() instanceof FakePlayer) return;
if (event.getObject() instanceof PlayerEntity) { if (event.getObject() instanceof PlayerEntity) {
event.addCapability(new ResourceLocation(EffortlessBuilding.MODID, "build_modifier"), new ModifierCapabilityManager.Provider()); event.addCapability(new ResourceLocation(EffortlessBuilding.MODID, "build_modifier"), new ModifierCapabilityManager.Provider());
event.addCapability(new ResourceLocation(EffortlessBuilding.MODID, "build_mode"), new ModeCapabilityManager.Provider()); event.addCapability(new ResourceLocation(EffortlessBuilding.MODID, "build_mode"), new ModeCapabilityManager.Provider());
} }
} }
//TODO 1.13 config
// @SubscribeEvent
// public static void onConfigChangedEvent(ConfigChangedEvent.OnConfigChangedEvent event)
// {
// if (event.getModID().equals(EffortlessBuilding.MODID))
// {
// ConfigManager.sync(EffortlessBuilding.MODID, Config.Type.INSTANCE);
// }
// }
// @SubscribeEvent
// public static void onServerTick(TickEvent.ServerTickEvent event) {
//
// }
@SubscribeEvent @SubscribeEvent
//Only called serverside (except with lilypads...)
public static void onBlockPlaced(BlockEvent.EntityPlaceEvent event) { public static void onBlockPlaced(BlockEvent.EntityPlaceEvent event) {
if (event.getWorld().isRemote()) return; if (event.getWorld().isClientSide()) return;
if (!(event.getEntity() instanceof PlayerEntity)) return; if (!(event.getEntity() instanceof PlayerEntity)) return;
if (event.getEntity() instanceof FakePlayer) return;
//Cancel event if necessary //Cancel event if necessary
ServerPlayerEntity player = ((ServerPlayerEntity) event.getEntity()); ServerPlayerEntity player = ((ServerPlayerEntity) event.getEntity());
BuildModes.BuildModeEnum buildMode = ModeSettingsManager.getModeSettings(player).getBuildMode(); BuildModes.BuildModeEnum buildMode = ModeSettingsManager.getModeSettings(player).getBuildMode();
@@ -94,7 +80,9 @@ public class EventHandler
@SubscribeEvent @SubscribeEvent
public static void onBlockBroken(BlockEvent.BreakEvent event) { public static void onBlockBroken(BlockEvent.BreakEvent event) {
if (event.getWorld().isRemote()) return; if (event.getWorld().isClientSide()) return;
if (event.getPlayer() instanceof FakePlayer) return;
//Cancel event if necessary //Cancel event if necessary
//If cant break far then dont cancel event ever //If cant break far then dont cancel event ever
@@ -108,7 +96,11 @@ public class EventHandler
BuildModes.onBlockBroken(event.getPlayer(), event.getPos(), false); BuildModes.onBlockBroken(event.getPlayer(), event.getPos(), false);
//Add to undo stack in client //Add to undo stack in client
PacketHandler.INSTANCE.send(PacketDistributor.PLAYER.with(() -> (ServerPlayerEntity) event.getPlayer()), new AddUndoMessage(event.getPos(), event.getState(), Blocks.AIR.getDefaultState())); if (event.getPlayer() instanceof ServerPlayerEntity && event.getState() != null && event.getPos() != null) {
PacketDistributor.PacketTarget packetTarget = PacketDistributor.PLAYER.with(() -> (ServerPlayerEntity) event.getPlayer());
if (packetTarget != null)
PacketHandler.INSTANCE.send(packetTarget, new AddUndoMessage(event.getPos(), event.getState(), Blocks.AIR.defaultBlockState()));
}
} }
} }
@@ -117,13 +109,15 @@ public class EventHandler
//Disable if config says so //Disable if config says so
if (!BuildConfig.survivalBalancers.increasedMiningTime.get()) return; if (!BuildConfig.survivalBalancers.increasedMiningTime.get()) return;
PlayerEntity player = event.getEntityPlayer(); if (event.getPlayer() instanceof FakePlayer) return;
World world = player.world;
PlayerEntity player = event.getPlayer();
World world = player.level;
BlockPos pos = event.getPos(); BlockPos pos = event.getPos();
//EffortlessBuilding.log(player, String.valueOf(event.getNewSpeed())); //EffortlessBuilding.log(player, String.valueOf(event.getNewSpeed()));
float originalBlockHardness = event.getState().getBlockHardness(world, pos); float originalBlockHardness = event.getState().getDestroySpeed(world, pos);
if (originalBlockHardness < 0) return; //Dont break bedrock if (originalBlockHardness < 0) return; //Dont break bedrock
float totalBlockHardness = 0; float totalBlockHardness = 0;
//get coordinates //get coordinates
@@ -134,7 +128,7 @@ public class EventHandler
BlockState blockState = world.getBlockState(coordinate); BlockState blockState = world.getBlockState(coordinate);
//add hardness for each blockstate, if can break //add hardness for each blockstate, if can break
if (SurvivalHelper.canBreak(world, player, coordinate)) if (SurvivalHelper.canBreak(world, player, coordinate))
totalBlockHardness += blockState.getBlockHardness(world, coordinate); totalBlockHardness += blockState.getDestroySpeed(world, coordinate);
} }
//Grabbing percentage from config //Grabbing percentage from config
@@ -151,6 +145,7 @@ public class EventHandler
@SubscribeEvent @SubscribeEvent
public static void onPlayerLoggedIn(PlayerEvent.PlayerLoggedInEvent event) { public static void onPlayerLoggedIn(PlayerEvent.PlayerLoggedInEvent event) {
if (event.getPlayer() instanceof FakePlayer) return;
PlayerEntity player = event.getPlayer(); PlayerEntity player = event.getPlayer();
ModifierSettingsManager.handleNewPlayer(player); ModifierSettingsManager.handleNewPlayer(player);
ModeSettingsManager.handleNewPlayer(player); ModeSettingsManager.handleNewPlayer(player);
@@ -158,8 +153,9 @@ public class EventHandler
@SubscribeEvent @SubscribeEvent
public static void onPlayerLoggedOut(PlayerEvent.PlayerLoggedOutEvent event) { public static void onPlayerLoggedOut(PlayerEvent.PlayerLoggedOutEvent event) {
if (event.getPlayer() instanceof FakePlayer) return;
PlayerEntity player = event.getPlayer(); PlayerEntity player = event.getPlayer();
if (player.getEntityWorld().isRemote) return; if (player.getCommandSenderWorld().isClientSide) return;
UndoRedo.clear(player); UndoRedo.clear(player);
PacketHandler.INSTANCE.send(PacketDistributor.PLAYER.with(() -> (ServerPlayerEntity) player), new ClearUndoMessage()); PacketHandler.INSTANCE.send(PacketDistributor.PLAYER.with(() -> (ServerPlayerEntity) player), new ClearUndoMessage());
@@ -167,6 +163,7 @@ public class EventHandler
@SubscribeEvent @SubscribeEvent
public static void onPlayerRespawn(PlayerEvent.PlayerRespawnEvent event) { public static void onPlayerRespawn(PlayerEvent.PlayerRespawnEvent event) {
if (event.getPlayer() instanceof FakePlayer) return;
PlayerEntity player = event.getPlayer(); PlayerEntity player = event.getPlayer();
ModifierSettingsManager.handleNewPlayer(player); ModifierSettingsManager.handleNewPlayer(player);
ModeSettingsManager.handleNewPlayer(player); ModeSettingsManager.handleNewPlayer(player);
@@ -174,8 +171,9 @@ public class EventHandler
@SubscribeEvent @SubscribeEvent
public static void onPlayerChangedDimension(PlayerEvent.PlayerChangedDimensionEvent event) { public static void onPlayerChangedDimension(PlayerEvent.PlayerChangedDimensionEvent event) {
if (event.getPlayer() instanceof FakePlayer) return;
PlayerEntity player = event.getPlayer(); PlayerEntity player = event.getPlayer();
if (player.getEntityWorld().isRemote) return; if (player.getCommandSenderWorld().isClientSide) return;
//Set build mode to normal //Set build mode to normal
ModeSettingsManager.ModeSettings modeSettings = ModeSettingsManager.getModeSettings(player); ModeSettingsManager.ModeSettings modeSettings = ModeSettingsManager.getModeSettings(player);
@@ -198,11 +196,12 @@ public class EventHandler
@SubscribeEvent @SubscribeEvent
public static void onPlayerClone(PlayerEvent.Clone event) { public static void onPlayerClone(PlayerEvent.Clone event) {
if (event.getPlayer() instanceof FakePlayer) return;
//Attach capabilities on death, otherwise crash //Attach capabilities on death, otherwise crash
PlayerEntity oldPlayer = event.getOriginal(); PlayerEntity oldPlayer = event.getOriginal();
oldPlayer.revive(); oldPlayer.revive();
PlayerEntity newPlayer = event.getEntityPlayer(); PlayerEntity newPlayer = event.getPlayer();
ModifierSettingsManager.setModifierSettings(newPlayer, ModifierSettingsManager.getModifierSettings(oldPlayer)); ModifierSettingsManager.setModifierSettings(newPlayer, ModifierSettingsManager.getModifierSettings(oldPlayer));
ModeSettingsManager.setModeSettings(newPlayer, ModeSettingsManager.getModeSettings(oldPlayer)); ModeSettingsManager.setModeSettings(newPlayer, ModeSettingsManager.getModeSettings(oldPlayer));
} }

View File

@@ -1,6 +1,7 @@
package nl.requios.effortlessbuilding; package nl.requios.effortlessbuilding;
import net.minecraft.client.Minecraft; import net.minecraft.client.Minecraft;
import net.minecraft.client.renderer.texture.AtlasTexture;
import net.minecraft.client.renderer.texture.TextureAtlasSprite; import net.minecraft.client.renderer.texture.TextureAtlasSprite;
import net.minecraft.util.ResourceLocation; import net.minecraft.util.ResourceLocation;
import net.minecraftforge.api.distmarker.Dist; import net.minecraftforge.api.distmarker.Dist;
@@ -12,7 +13,7 @@ import nl.requios.effortlessbuilding.buildmode.ModeOptions;
import java.util.HashMap; import java.util.HashMap;
@Mod.EventBusSubscriber(bus=Mod.EventBusSubscriber.Bus.MOD, value = {Dist.CLIENT}) @Mod.EventBusSubscriber(bus = Mod.EventBusSubscriber.Bus.MOD, value = {Dist.CLIENT})
public class ModClientEventHandler { public class ModClientEventHandler {
private static final HashMap<BuildModes.BuildModeEnum, ResourceLocation> buildModeIcons = new HashMap<>(); private static final HashMap<BuildModes.BuildModeEnum, ResourceLocation> buildModeIcons = new HashMap<>();
@@ -20,16 +21,15 @@ public class ModClientEventHandler {
@SubscribeEvent @SubscribeEvent
public static void onTextureStitch(final TextureStitchEvent.Pre event) { public static void onTextureStitch(final TextureStitchEvent.Pre event) {
EffortlessBuilding.log("Stitching textures");
//register icon textures //register icon textures
for (final BuildModes.BuildModeEnum mode : BuildModes.BuildModeEnum.values()) for (final BuildModes.BuildModeEnum mode : BuildModes.BuildModeEnum.values()) {
{
final ResourceLocation spriteLocation = new ResourceLocation(EffortlessBuilding.MODID, "icons/" + mode.name().toLowerCase()); final ResourceLocation spriteLocation = new ResourceLocation(EffortlessBuilding.MODID, "icons/" + mode.name().toLowerCase());
event.addSprite(spriteLocation); event.addSprite(spriteLocation);
buildModeIcons.put(mode, spriteLocation); buildModeIcons.put(mode, spriteLocation);
} }
for (final ModeOptions.ActionEnum action : ModeOptions.ActionEnum.values()) for (final ModeOptions.ActionEnum action : ModeOptions.ActionEnum.values()) {
{
final ResourceLocation spriteLocation = new ResourceLocation(EffortlessBuilding.MODID, "icons/" + action.name().toLowerCase()); final ResourceLocation spriteLocation = new ResourceLocation(EffortlessBuilding.MODID, "icons/" + action.name().toLowerCase());
event.addSprite(spriteLocation); event.addSprite(spriteLocation);
modeOptionIcons.put(action, spriteLocation); modeOptionIcons.put(action, spriteLocation);
@@ -37,10 +37,10 @@ public class ModClientEventHandler {
} }
public static TextureAtlasSprite getBuildModeIcon(BuildModes.BuildModeEnum mode) { public static TextureAtlasSprite getBuildModeIcon(BuildModes.BuildModeEnum mode) {
return Minecraft.getInstance().getTextureMap().getSprite(buildModeIcons.get(mode)); return Minecraft.getInstance().getModelManager().getAtlas(AtlasTexture.LOCATION_BLOCKS).getSprite(buildModeIcons.get(mode));
} }
public static TextureAtlasSprite getModeOptionIcon(ModeOptions.ActionEnum action) { public static TextureAtlasSprite getModeOptionIcon(ModeOptions.ActionEnum action) {
return Minecraft.getInstance().getTextureMap().getSprite(modeOptionIcons.get(action)); return Minecraft.getInstance().getModelManager().getAtlas(AtlasTexture.LOCATION_BLOCKS).getSprite(modeOptionIcons.get(action));
} }
} }

View File

@@ -1,45 +0,0 @@
package nl.requios.effortlessbuilding;
import net.minecraft.block.Block;
import net.minecraft.client.Minecraft;
import net.minecraft.client.renderer.texture.TextureAtlasSprite;
import net.minecraft.item.BlockItem;
import net.minecraft.item.Item;
import net.minecraft.util.ResourceLocation;
import net.minecraftforge.api.distmarker.Dist;
import net.minecraftforge.client.event.TextureStitchEvent;
import net.minecraftforge.event.RegistryEvent;
import net.minecraftforge.eventbus.api.SubscribeEvent;
import net.minecraftforge.fml.common.Mod;
import nl.requios.effortlessbuilding.buildmode.BuildModes;
import nl.requios.effortlessbuilding.buildmode.ModeOptions;
import java.util.HashMap;
// You can use EventBusSubscriber to automatically subscribe events on the contained class (this is subscribing to the MOD
// Event bus for receiving Registry Events)
@Mod.EventBusSubscriber(bus=Mod.EventBusSubscriber.Bus.MOD)
public class ModEventHandler {
@SubscribeEvent
public static void registerBlocks(RegistryEvent.Register<Block> event) {
event.getRegistry().registerAll(EffortlessBuilding.BLOCKS);
}
@SubscribeEvent
public static void registerItems(RegistryEvent.Register<Item> event) {
event.getRegistry().registerAll(EffortlessBuilding.ITEMS);
for (Block block : EffortlessBuilding.BLOCKS)
{
event.getRegistry().register(new BlockItem(block, new Item.Properties()).setRegistryName(block.getRegistryName()));
}
}
// @SubscribeEvent
// public static void registerContainerTypes(RegistryEvent.Register<ContainerType<?>> event) {
// event.getRegistry().register()
// }
}

View File

@@ -3,7 +3,7 @@ package nl.requios.effortlessbuilding.buildmode;
import net.minecraft.entity.player.PlayerEntity; import net.minecraft.entity.player.PlayerEntity;
import net.minecraft.util.Direction; import net.minecraft.util.Direction;
import net.minecraft.util.math.BlockPos; import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.Vec3d; import net.minecraft.util.math.vector.Vector3d;
import java.util.Dictionary; import java.util.Dictionary;
import java.util.Hashtable; import java.util.Hashtable;
@@ -16,24 +16,24 @@ public abstract class BaseBuildMode implements IBuildMode {
protected Dictionary<UUID, Integer> rightClickServerTable = new Hashtable<>(); protected Dictionary<UUID, Integer> rightClickServerTable = new Hashtable<>();
protected Dictionary<UUID, BlockPos> firstPosTable = new Hashtable<>(); protected Dictionary<UUID, BlockPos> firstPosTable = new Hashtable<>();
protected Dictionary<UUID, Direction> sideHitTable = new Hashtable<>(); protected Dictionary<UUID, Direction> sideHitTable = new Hashtable<>();
protected Dictionary<UUID, Vec3d> hitVecTable = new Hashtable<>(); protected Dictionary<UUID, Vector3d> hitVecTable = new Hashtable<>();
@Override @Override
public void initialize(PlayerEntity player) { public void initialize(PlayerEntity player) {
rightClickClientTable.put(player.getUniqueID(), 0); rightClickClientTable.put(player.getUUID(), 0);
rightClickServerTable.put(player.getUniqueID(), 0); rightClickServerTable.put(player.getUUID(), 0);
firstPosTable.put(player.getUniqueID(), BlockPos.ZERO); firstPosTable.put(player.getUUID(), BlockPos.ZERO);
sideHitTable.put(player.getUniqueID(), Direction.UP); sideHitTable.put(player.getUUID(), Direction.UP);
hitVecTable.put(player.getUniqueID(), Vec3d.ZERO); hitVecTable.put(player.getUUID(), Vector3d.ZERO);
} }
@Override @Override
public Direction getSideHit(PlayerEntity player) { public Direction getSideHit(PlayerEntity player) {
return sideHitTable.get(player.getUniqueID()); return sideHitTable.get(player.getUUID());
} }
@Override @Override
public Vec3d getHitVec(PlayerEntity player) { public Vector3d getHitVec(PlayerEntity player) {
return hitVecTable.get(player.getUniqueID()); return hitVecTable.get(player.getUUID());
} }
} }

View File

@@ -5,7 +5,8 @@ import net.minecraft.util.Direction;
import net.minecraft.util.math.BlockPos; import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.RayTraceContext; import net.minecraft.util.math.RayTraceContext;
import net.minecraft.util.math.RayTraceResult; import net.minecraft.util.math.RayTraceResult;
import net.minecraft.util.math.Vec3d; import net.minecraft.util.math.vector.Vector3d;
import net.minecraft.util.math.vector.Vector4f;
import nl.requios.effortlessbuilding.EffortlessBuilding; import nl.requios.effortlessbuilding.EffortlessBuilding;
import nl.requios.effortlessbuilding.buildmode.buildmodes.*; import nl.requios.effortlessbuilding.buildmode.buildmodes.*;
import nl.requios.effortlessbuilding.buildmodifier.BuildModifiers; import nl.requios.effortlessbuilding.buildmodifier.BuildModifiers;
@@ -20,7 +21,7 @@ import java.util.Dictionary;
import java.util.Hashtable; import java.util.Hashtable;
import java.util.List; import java.util.List;
import static nl.requios.effortlessbuilding.buildmode.ModeOptions.*; import static nl.requios.effortlessbuilding.buildmode.ModeOptions.OptionEnum;
public class BuildModes { public class BuildModes {
@@ -29,38 +30,13 @@ public class BuildModes {
public static Dictionary<PlayerEntity, Boolean> currentlyBreakingClient = new Hashtable<>(); public static Dictionary<PlayerEntity, Boolean> currentlyBreakingClient = new Hashtable<>();
public static Dictionary<PlayerEntity, Boolean> currentlyBreakingServer = new Hashtable<>(); public static Dictionary<PlayerEntity, Boolean> currentlyBreakingServer = new Hashtable<>();
public enum BuildModeEnum {
NORMAL("effortlessbuilding.mode.normal", new Normal()),
NORMAL_PLUS("effortlessbuilding.mode.normal_plus", new NormalPlus(), OptionEnum.BUILD_SPEED),
LINE("effortlessbuilding.mode.line", new Line() /*, OptionEnum.THICKNESS*/),
WALL("effortlessbuilding.mode.wall", new Wall(), OptionEnum.FILL),
FLOOR("effortlessbuilding.mode.floor", new Floor(), OptionEnum.FILL),
DIAGONAL_LINE("effortlessbuilding.mode.diagonal_line", new DiagonalLine() /*, OptionEnum.THICKNESS*/),
DIAGONAL_WALL("effortlessbuilding.mode.diagonal_wall", new DiagonalWall() /*, OptionEnum.FILL*/),
SLOPE_FLOOR("effortlessbuilding.mode.slope_floor", new SlopeFloor(), OptionEnum.RAISED_EDGE),
CIRCLE("effortlessbuilding.mode.circle", new Circle(), OptionEnum.CIRCLE_START, OptionEnum.FILL),
CYLINDER("effortlessbuilding.mode.cylinder", new Cylinder(), OptionEnum.CIRCLE_START, OptionEnum.FILL),
SPHERE("effortlessbuilding.mode.sphere", new Sphere(), OptionEnum.CIRCLE_START, OptionEnum.FILL),
CUBE("effortlessbuilding.mode.cube", new Cube(), OptionEnum.CUBE_FILL);
public String name;
public IBuildMode instance;
public OptionEnum[] options;
BuildModeEnum(String name, IBuildMode instance, OptionEnum... options) {
this.name = name;
this.instance = instance;
this.options = options;
}
}
//Uses a network message to get the previous raytraceresult from the player //Uses a network message to get the previous raytraceresult from the player
//The server could keep track of all raytraceresults but this might lag with many players //The server could keep track of all raytraceresults but this might lag with many players
//Raytraceresult is needed for sideHit and hitVec //Raytraceresult is needed for sideHit and hitVec
public static void onBlockPlacedMessage(PlayerEntity player, BlockPlacedMessage message) { public static void onBlockPlacedMessage(PlayerEntity player, BlockPlacedMessage message) {
//Check if not in the middle of breaking //Check if not in the middle of breaking
Dictionary<PlayerEntity, Boolean> currentlyBreaking = player.world.isRemote ? currentlyBreakingClient : currentlyBreakingServer; Dictionary<PlayerEntity, Boolean> currentlyBreaking = player.level.isClientSide ? currentlyBreakingClient : currentlyBreakingServer;
if (currentlyBreaking.get(player) != null && currentlyBreaking.get(player)) { if (currentlyBreaking.get(player) != null && currentlyBreaking.get(player)) {
//Cancel breaking //Cancel breaking
initializeMode(player); initializeMode(player);
@@ -78,20 +54,20 @@ public class BuildModes {
//Offset in direction of sidehit if not quickreplace and not replaceable //Offset in direction of sidehit if not quickreplace and not replaceable
//TODO 1.13 replaceable //TODO 1.13 replaceable
boolean replaceable = player.world.getBlockState(startPos).getMaterial().isReplaceable(); boolean replaceable = player.level.getBlockState(startPos).getMaterial().isReplaceable();
boolean becomesDoubleSlab = SurvivalHelper.doesBecomeDoubleSlab(player, startPos, message.getSideHit()); boolean becomesDoubleSlab = SurvivalHelper.doesBecomeDoubleSlab(player, startPos, message.getSideHit());
if (!modifierSettings.doQuickReplace() && !replaceable && !becomesDoubleSlab) { if (!modifierSettings.doQuickReplace() && !replaceable && !becomesDoubleSlab) {
startPos = startPos.offset(message.getSideHit()); startPos = startPos.relative(message.getSideHit());
} }
//Get under tall grass and other replaceable blocks //Get under tall grass and other replaceable blocks
if (modifierSettings.doQuickReplace() && replaceable) { if (modifierSettings.doQuickReplace() && replaceable) {
startPos = startPos.down(); startPos = startPos.below();
} }
//Check if player reach does not exceed startpos //Check if player reach does not exceed startpos
int maxReach = ReachHelper.getMaxReach(player); int maxReach = ReachHelper.getMaxReach(player);
if (buildMode != BuildModeEnum.NORMAL && player.getPosition().distanceSq(startPos) > maxReach * maxReach) { if (buildMode != BuildModeEnum.NORMAL && player.blockPosition().distSqr(startPos) > maxReach * maxReach) {
EffortlessBuilding.log(player, "Placement exceeds your reach."); EffortlessBuilding.log(player, "Placement exceeds your reach.");
return; return;
} }
@@ -115,7 +91,7 @@ public class BuildModes {
Direction sideHit = buildMode.instance.getSideHit(player); Direction sideHit = buildMode.instance.getSideHit(player);
if (sideHit == null) sideHit = message.getSideHit(); if (sideHit == null) sideHit = message.getSideHit();
Vec3d hitVec = buildMode.instance.getHitVec(player); Vector3d hitVec = buildMode.instance.getHitVec(player);
if (hitVec == null) hitVec = message.getHitVec(); if (hitVec == null) hitVec = message.getHitVec();
BuildModifiers.onBlockPlaced(player, coordinates, sideHit, hitVec, message.getPlaceStartPos()); BuildModifiers.onBlockPlaced(player, coordinates, sideHit, hitVec, message.getPlaceStartPos());
@@ -135,7 +111,7 @@ public class BuildModes {
public static void onBlockBroken(PlayerEntity player, BlockPos startPos, boolean breakStartPos) { public static void onBlockBroken(PlayerEntity player, BlockPos startPos, boolean breakStartPos) {
//Check if not in the middle of placing //Check if not in the middle of placing
Dictionary<PlayerEntity, Boolean> currentlyBreaking = player.world.isRemote ? currentlyBreakingClient : currentlyBreakingServer; Dictionary<PlayerEntity, Boolean> currentlyBreaking = player.level.isClientSide ? currentlyBreakingClient : currentlyBreakingServer;
if (currentlyBreaking.get(player) != null && !currentlyBreaking.get(player)) { if (currentlyBreaking.get(player) != null && !currentlyBreaking.get(player)) {
//Cancel placing //Cancel placing
initializeMode(player); initializeMode(player);
@@ -153,7 +129,7 @@ public class BuildModes {
//Get coordinates //Get coordinates
BuildModeEnum buildMode = modeSettings.getBuildMode(); BuildModeEnum buildMode = modeSettings.getBuildMode();
List<BlockPos> coordinates = buildMode.instance.onRightClick(player, startPos, Direction.UP, Vec3d.ZERO, true); List<BlockPos> coordinates = buildMode.instance.onRightClick(player, startPos, Direction.UP, Vector3d.ZERO, true);
if (coordinates.isEmpty()) { if (coordinates.isEmpty()) {
currentlyBreaking.put(player, true); currentlyBreaking.put(player, true);
@@ -179,68 +155,141 @@ public class BuildModes {
public static void initializeMode(PlayerEntity player) { public static void initializeMode(PlayerEntity player) {
//Resetting mode, so not placing or breaking //Resetting mode, so not placing or breaking
Dictionary<PlayerEntity, Boolean> currentlyBreaking = player.world.isRemote ? currentlyBreakingClient : currentlyBreakingServer; Dictionary<PlayerEntity, Boolean> currentlyBreaking = player.level.isClientSide ? currentlyBreakingClient : currentlyBreakingServer;
currentlyBreaking.remove(player); currentlyBreaking.remove(player);
ModeSettingsManager.getModeSettings(player).getBuildMode().instance.initialize(player); ModeSettingsManager.getModeSettings(player).getBuildMode().instance.initialize(player);
} }
public static boolean isCurrentlyPlacing(PlayerEntity player) { public static boolean isCurrentlyPlacing(PlayerEntity player) {
Dictionary<PlayerEntity, Boolean> currentlyBreaking = player.world.isRemote ? currentlyBreakingClient : currentlyBreakingServer; Dictionary<PlayerEntity, Boolean> currentlyBreaking = player.level.isClientSide ? currentlyBreakingClient : currentlyBreakingServer;
return currentlyBreaking.get(player) != null && !currentlyBreaking.get(player); return currentlyBreaking.get(player) != null && !currentlyBreaking.get(player);
} }
public static boolean isCurrentlyBreaking(PlayerEntity player) { public static boolean isCurrentlyBreaking(PlayerEntity player) {
Dictionary<PlayerEntity, Boolean> currentlyBreaking = player.world.isRemote ? currentlyBreakingClient : currentlyBreakingServer; Dictionary<PlayerEntity, Boolean> currentlyBreaking = player.level.isClientSide ? currentlyBreakingClient : currentlyBreakingServer;
return currentlyBreaking.get(player) != null && currentlyBreaking.get(player); return currentlyBreaking.get(player) != null && currentlyBreaking.get(player);
} }
//Either placing or breaking //Either placing or breaking
public static boolean isActive(PlayerEntity player) { public static boolean isActive(PlayerEntity player) {
Dictionary<PlayerEntity, Boolean> currentlyBreaking = player.world.isRemote ? currentlyBreakingClient : currentlyBreakingServer; Dictionary<PlayerEntity, Boolean> currentlyBreaking = player.level.isClientSide ? currentlyBreakingClient : currentlyBreakingServer;
return currentlyBreaking.get(player) != null; return currentlyBreaking.get(player) != null;
} }
//Find coordinates on a line bound by a plane
public static Vector3d findXBound(double x, Vector3d start, Vector3d look) {
//then y and z are
double y = (x - start.x) / look.x * look.y + start.y;
double z = (x - start.x) / look.x * look.z + start.z;
return new Vector3d(x, y, z);
}
//-- Common build mode functionality --// //-- Common build mode functionality --//
//Find coordinates on a line bound by a plane public static Vector3d findYBound(double y, Vector3d start, Vector3d look) {
public static Vec3d findXBound(double x, Vec3d start, Vec3d look) {
//then y and z are
double y = (x - start.x) / look.x * look.y + start.y;
double z = (x - start.x) / look.x * look.z + start.z;
return new Vec3d(x, y, z);
}
public static Vec3d findYBound(double y, Vec3d start, Vec3d look) {
//then x and z are //then x and z are
double x = (y - start.y) / look.y * look.x + start.x; double x = (y - start.y) / look.y * look.x + start.x;
double z = (y - start.y) / look.y * look.z + start.z; double z = (y - start.y) / look.y * look.z + start.z;
return new Vec3d(x, y, z); return new Vector3d(x, y, z);
} }
public static Vec3d findZBound(double z, Vec3d start, Vec3d look) { public static Vector3d findZBound(double z, Vector3d start, Vector3d look) {
//then x and y are //then x and y are
double x = (z - start.z) / look.z * look.x + start.x; double x = (z - start.z) / look.z * look.x + start.x;
double y = (z - start.z) / look.z * look.y + start.y; double y = (z - start.z) / look.z * look.y + start.y;
return new Vec3d(x, y, z); return new Vector3d(x, y, z);
} }
public static boolean isCriteriaValid(Vec3d start, Vec3d look, int reach, PlayerEntity player, boolean skipRaytrace, Vec3d lineBound, Vec3d planeBound, double distToPlayerSq) { //Use this instead of player.getLookVec() in any buildmodes code
public static Vector3d getPlayerLookVec(PlayerEntity player) {
Vector3d lookVec = player.getLookAngle();
double x = lookVec.x;
double y = lookVec.y;
double z = lookVec.z;
//Further calculations (findXBound etc) don't like any component being 0 or 1 (e.g. dividing by 0)
//isCriteriaValid below will take up to 2 minutes to raytrace blocks towards infinity if that is the case
//So make sure they are close to but never exactly 0 or 1
if (Math.abs(x) < 0.0001) x = 0.0001;
if (Math.abs(x - 1.0) < 0.0001) x = 0.9999;
if (Math.abs(x + 1.0) < 0.0001) x = -0.9999;
if (Math.abs(y) < 0.0001) y = 0.0001;
if (Math.abs(y - 1.0) < 0.0001) y = 0.9999;
if (Math.abs(y + 1.0) < 0.0001) y = -0.9999;
if (Math.abs(z) < 0.0001) z = 0.0001;
if (Math.abs(z - 1.0) < 0.0001) z = 0.9999;
if (Math.abs(z + 1.0) < 0.0001) z = -0.9999;
return new Vector3d(x, y, z);
}
public static boolean isCriteriaValid(Vector3d start, Vector3d look, int reach, PlayerEntity player, boolean skipRaytrace, Vector3d lineBound, Vector3d planeBound, double distToPlayerSq) {
boolean intersects = false; boolean intersects = false;
if (!skipRaytrace) { if (!skipRaytrace) {
//collision within a 1 block radius to selected is fine //collision within a 1 block radius to selected is fine
RayTraceContext rayTraceContext = new RayTraceContext(start, lineBound, RayTraceContext.BlockMode.COLLIDER, RayTraceContext.FluidMode.NONE, player); RayTraceContext rayTraceContext = new RayTraceContext(start, lineBound, RayTraceContext.BlockMode.COLLIDER, RayTraceContext.FluidMode.NONE, player);
RayTraceResult rayTraceResult = player.world.rayTraceBlocks(rayTraceContext); RayTraceResult rayTraceResult = player.level.clip(rayTraceContext);
intersects = rayTraceResult != null && rayTraceResult.getType() == RayTraceResult.Type.BLOCK && intersects = rayTraceResult != null && rayTraceResult.getType() == RayTraceResult.Type.BLOCK &&
planeBound.subtract(rayTraceResult.getHitVec()).lengthSquared() > 4; planeBound.subtract(rayTraceResult.getLocation()).lengthSqr() > 4;
} }
return planeBound.subtract(start).dotProduct(look) > 0 && return planeBound.subtract(start).dot(look) > 0 &&
distToPlayerSq > 2 && distToPlayerSq < reach * reach && distToPlayerSq > 2 && distToPlayerSq < reach * reach &&
!intersects; !intersects;
} }
public enum BuildModeEnum {
NORMAL("normal", new Normal(), BuildModeCategoryEnum.BASIC),
NORMAL_PLUS("normal_plus", new NormalPlus(), BuildModeCategoryEnum.BASIC, OptionEnum.BUILD_SPEED),
LINE("line", new Line(), BuildModeCategoryEnum.BASIC /*, OptionEnum.THICKNESS*/),
WALL("wall", new Wall(), BuildModeCategoryEnum.BASIC, OptionEnum.FILL),
FLOOR("floor", new Floor(), BuildModeCategoryEnum.BASIC, OptionEnum.FILL),
CUBE("cube", new Cube(), BuildModeCategoryEnum.BASIC, OptionEnum.CUBE_FILL),
DIAGONAL_LINE("diagonal_line", new DiagonalLine(), BuildModeCategoryEnum.DIAGONAL /*, OptionEnum.THICKNESS*/),
DIAGONAL_WALL("diagonal_wall", new DiagonalWall(), BuildModeCategoryEnum.DIAGONAL /*, OptionEnum.FILL*/),
SLOPE_FLOOR("slope_floor", new SlopeFloor(), BuildModeCategoryEnum.DIAGONAL, OptionEnum.RAISED_EDGE),
CIRCLE("circle", new Circle(), BuildModeCategoryEnum.CIRCULAR, OptionEnum.CIRCLE_START, OptionEnum.FILL),
CYLINDER("cylinder", new Cylinder(), BuildModeCategoryEnum.CIRCULAR, OptionEnum.CIRCLE_START, OptionEnum.FILL),
SPHERE("sphere", new Sphere(), BuildModeCategoryEnum.CIRCULAR, OptionEnum.CIRCLE_START, OptionEnum.FILL);
public String name;
public IBuildMode instance;
public final BuildModeCategoryEnum category;
public OptionEnum[] options;
BuildModeEnum(String name, IBuildMode instance, BuildModeCategoryEnum category, OptionEnum... options) {
this.name = name;
this.instance = instance;
this.category = category;
this.options = options;
}
public String getNameKey() {
return "effortlessbuilding.mode." + name;
}
public String getDescriptionKey() {
return "effortlessbuilding.modedescription." + name;
}
}
public enum BuildModeCategoryEnum {
BASIC(new Vector4f(0f, .5f, 1f, .8f)),
DIAGONAL(new Vector4f(0.56f, 0.28f, 0.87f, .8f)),
CIRCULAR(new Vector4f(0.29f, 0.76f, 0.3f, 1f)),
ROOF(new Vector4f(0.83f, 0.87f, 0.23f, .8f));
public final Vector4f color;
BuildModeCategoryEnum(Vector4f color) {
this.color = color;
}
}
} }

View File

@@ -3,7 +3,7 @@ package nl.requios.effortlessbuilding.buildmode;
import net.minecraft.entity.player.PlayerEntity; import net.minecraft.entity.player.PlayerEntity;
import net.minecraft.util.Direction; import net.minecraft.util.Direction;
import net.minecraft.util.math.BlockPos; import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.Vec3d; import net.minecraft.util.math.vector.Vector3d;
import java.util.List; import java.util.List;
@@ -14,12 +14,12 @@ public interface IBuildMode {
//Fired when a block would be placed //Fired when a block would be placed
//Return a list of coordinates where you want to place blocks //Return a list of coordinates where you want to place blocks
List<BlockPos> onRightClick(PlayerEntity player, BlockPos blockPos, Direction sideHit, Vec3d hitVec, boolean skipRaytrace); List<BlockPos> onRightClick(PlayerEntity player, BlockPos blockPos, Direction sideHit, Vector3d hitVec, boolean skipRaytrace);
//Fired continuously for visualization purposes //Fired continuously for visualization purposes
List<BlockPos> findCoordinates(PlayerEntity player, BlockPos blockPos, boolean skipRaytrace); List<BlockPos> findCoordinates(PlayerEntity player, BlockPos blockPos, boolean skipRaytrace);
Direction getSideHit(PlayerEntity player); Direction getSideHit(PlayerEntity player);
Vec3d getHitVec(PlayerEntity player); Vector3d getHitVec(PlayerEntity player);
} }

View File

@@ -9,56 +9,6 @@ import nl.requios.effortlessbuilding.proxy.ClientProxy;
public class ModeOptions { public class ModeOptions {
public enum ActionEnum {
UNDO("effortlessbuilding.action.undo"),
REDO("effortlessbuilding.action.redo"),
REPLACE("effortlessbuilding.action.replace"),
OPEN_MODIFIER_SETTINGS("effortlessbuilding.action.open_modifier_settings"),
NORMAL_SPEED("effortlessbuilding.action.normal_speed"),
FAST_SPEED("effortlessbuilding.action.fast_speed"),
FULL("effortlessbuilding.action.full"),
HOLLOW("effortlessbuilding.action.hollow"),
CUBE_FULL("effortlessbuilding.action.full"),
CUBE_HOLLOW("effortlessbuilding.action.hollow"),
CUBE_SKELETON("effortlessbuilding.action.skeleton"),
SHORT_EDGE("effortlessbuilding.action.short_edge"),
LONG_EDGE("effortlessbuilding.action.long_edge"),
THICKNESS_1("effortlessbuilding.action.thickness_1"),
THICKNESS_3("effortlessbuilding.action.thickness_3"),
THICKNESS_5("effortlessbuilding.action.thickness_5"),
CIRCLE_START_CORNER("effortlessbuilding.action.start_corner"),
CIRCLE_START_CENTER("effortlessbuilding.action.start_center");
public String name;
ActionEnum(String name) {
this.name = name;
}
}
public enum OptionEnum {
BUILD_SPEED("effortlessbuilding.action.build_speed", ActionEnum.NORMAL_SPEED, ActionEnum.FAST_SPEED),
FILL("effortlessbuilding.action.filling", ActionEnum.FULL, ActionEnum.HOLLOW),
CUBE_FILL("effortlessbuilding.action.filling", ActionEnum.CUBE_FULL, ActionEnum.CUBE_HOLLOW, ActionEnum.CUBE_SKELETON),
RAISED_EDGE("effortlessbuilding.action.raised_edge", ActionEnum.SHORT_EDGE, ActionEnum.LONG_EDGE),
LINE_THICKNESS("effortlessbuilding.action.thickness", ActionEnum.THICKNESS_1, ActionEnum.THICKNESS_3, ActionEnum.THICKNESS_5),
CIRCLE_START("effortlessbuilding.action.circle_start", ActionEnum.CIRCLE_START_CORNER, ActionEnum.CIRCLE_START_CENTER);
public String name;
public ActionEnum[] actions;
OptionEnum(String name, ActionEnum... actions){
this.name = name;
this.actions = actions;
}
}
private static ActionEnum buildSpeed = ActionEnum.NORMAL_SPEED; private static ActionEnum buildSpeed = ActionEnum.NORMAL_SPEED;
private static ActionEnum fill = ActionEnum.FULL; private static ActionEnum fill = ActionEnum.FULL;
private static ActionEnum cubeFill = ActionEnum.CUBE_FULL; private static ActionEnum cubeFill = ActionEnum.CUBE_FULL;
@@ -127,9 +77,13 @@ public class ModeOptions {
modifierSettings.doQuickReplace() ? "on" : "off"), true); modifierSettings.doQuickReplace() ? "on" : "off"), true);
break; break;
case OPEN_MODIFIER_SETTINGS: case OPEN_MODIFIER_SETTINGS:
if (player.world.isRemote) if (player.level.isClientSide)
ClientProxy.openModifierSettings(); ClientProxy.openModifierSettings();
break; break;
case OPEN_PLAYER_SETTINGS:
if (player.level.isClientSide)
ClientProxy.openPlayerSettings();
break;
case NORMAL_SPEED: case NORMAL_SPEED:
buildSpeed = ActionEnum.NORMAL_SPEED; buildSpeed = ActionEnum.NORMAL_SPEED;
@@ -175,8 +129,63 @@ public class ModeOptions {
break; break;
} }
if (player.world.isRemote && action != ActionEnum.REPLACE && action != ActionEnum.OPEN_MODIFIER_SETTINGS) { if (player.level.isClientSide &&
action != ActionEnum.REPLACE &&
action != ActionEnum.OPEN_MODIFIER_SETTINGS &&
action != ActionEnum.OPEN_PLAYER_SETTINGS) {
EffortlessBuilding.logTranslate(player, "", action.name, "", true); EffortlessBuilding.logTranslate(player, "", action.name, "", true);
} }
} }
public enum ActionEnum {
UNDO("effortlessbuilding.action.undo"),
REDO("effortlessbuilding.action.redo"),
REPLACE("effortlessbuilding.action.replace"),
OPEN_MODIFIER_SETTINGS("effortlessbuilding.action.open_modifier_settings"),
OPEN_PLAYER_SETTINGS("effortlessbuilding.action.open_player_settings"),
NORMAL_SPEED("effortlessbuilding.action.normal_speed"),
FAST_SPEED("effortlessbuilding.action.fast_speed"),
FULL("effortlessbuilding.action.full"),
HOLLOW("effortlessbuilding.action.hollow"),
CUBE_FULL("effortlessbuilding.action.full"),
CUBE_HOLLOW("effortlessbuilding.action.hollow"),
CUBE_SKELETON("effortlessbuilding.action.skeleton"),
SHORT_EDGE("effortlessbuilding.action.short_edge"),
LONG_EDGE("effortlessbuilding.action.long_edge"),
THICKNESS_1("effortlessbuilding.action.thickness_1"),
THICKNESS_3("effortlessbuilding.action.thickness_3"),
THICKNESS_5("effortlessbuilding.action.thickness_5"),
CIRCLE_START_CORNER("effortlessbuilding.action.start_corner"),
CIRCLE_START_CENTER("effortlessbuilding.action.start_center");
public String name;
ActionEnum(String name) {
this.name = name;
}
}
public enum OptionEnum {
BUILD_SPEED("effortlessbuilding.action.build_speed", ActionEnum.NORMAL_SPEED, ActionEnum.FAST_SPEED),
FILL("effortlessbuilding.action.filling", ActionEnum.FULL, ActionEnum.HOLLOW),
CUBE_FILL("effortlessbuilding.action.filling", ActionEnum.CUBE_FULL, ActionEnum.CUBE_HOLLOW, ActionEnum.CUBE_SKELETON),
RAISED_EDGE("effortlessbuilding.action.raised_edge", ActionEnum.SHORT_EDGE, ActionEnum.LONG_EDGE),
LINE_THICKNESS("effortlessbuilding.action.thickness", ActionEnum.THICKNESS_1, ActionEnum.THICKNESS_3, ActionEnum.THICKNESS_5),
CIRCLE_START("effortlessbuilding.action.circle_start", ActionEnum.CIRCLE_START_CORNER, ActionEnum.CIRCLE_START_CENTER);
public String name;
public ActionEnum[] actions;
OptionEnum(String name, ActionEnum... actions) {
this.name = name;
this.actions = actions;
}
}
} }

View File

@@ -65,6 +65,18 @@ public class ModeSettingsManager {
return error; return error;
} }
public static void handleNewPlayer(PlayerEntity player) {
//Makes sure player has mode settings (if it doesnt it will create it)
getModeSettings(player);
//Only on server
if (!player.level.isClientSide) {
//Send to client
ModeSettingsMessage msg = new ModeSettingsMessage(getModeSettings(player));
PacketHandler.INSTANCE.send(PacketDistributor.PLAYER.with(() -> (ServerPlayerEntity) player), msg);
}
}
public static class ModeSettings { public static class ModeSettings {
private BuildModes.BuildModeEnum buildMode = BuildModes.BuildModeEnum.NORMAL; private BuildModes.BuildModeEnum buildMode = BuildModes.BuildModeEnum.NORMAL;
@@ -83,16 +95,4 @@ public class ModeSettingsManager {
this.buildMode = buildMode; this.buildMode = buildMode;
} }
} }
public static void handleNewPlayer(PlayerEntity player){
//Makes sure player has mode settings (if it doesnt it will create it)
getModeSettings(player);
//Only on server
if (!player.world.isRemote) {
//Send to client
ModeSettingsMessage msg = new ModeSettingsMessage(getModeSettings(player));
PacketHandler.INSTANCE.send(PacketDistributor.PLAYER.with(() -> (ServerPlayerEntity) player), msg);
}
}
} }

View File

@@ -3,7 +3,7 @@ package nl.requios.effortlessbuilding.buildmode;
import net.minecraft.entity.player.PlayerEntity; import net.minecraft.entity.player.PlayerEntity;
import net.minecraft.util.Direction; import net.minecraft.util.Direction;
import net.minecraft.util.math.BlockPos; import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.Vec3d; import net.minecraft.util.math.vector.Vector3d;
import nl.requios.effortlessbuilding.helper.ReachHelper; import nl.requios.effortlessbuilding.helper.ReachHelper;
import java.util.*; import java.util.*;
@@ -11,76 +11,93 @@ import java.util.*;
public abstract class ThreeClicksBuildMode extends BaseBuildMode { public abstract class ThreeClicksBuildMode extends BaseBuildMode {
protected Dictionary<UUID, BlockPos> secondPosTable = new Hashtable<>(); protected Dictionary<UUID, BlockPos> secondPosTable = new Hashtable<>();
static class HeightCriteria { //Finds height after floor has been chosen in buildmodes with 3 clicks
Vec3d planeBound; public static BlockPos findHeight(PlayerEntity player, BlockPos secondPos, boolean skipRaytrace) {
Vec3d lineBound; Vector3d look = BuildModes.getPlayerLookVec(player);
double distToLineSq; Vector3d start = new Vector3d(player.getX(), player.getY() + player.getEyeHeight(), player.getZ());
double distToPlayerSq;
HeightCriteria(Vec3d planeBound, BlockPos secondPos, Vec3d start) { List<HeightCriteria> criteriaList = new ArrayList<>(3);
this.planeBound = planeBound;
this.lineBound = toLongestLine(this.planeBound, secondPos); //X
this.distToLineSq = this.lineBound.subtract(this.planeBound).lengthSquared(); Vector3d xBound = BuildModes.findXBound(secondPos.getX(), start, look);
this.distToPlayerSq = this.planeBound.subtract(start).lengthSquared(); criteriaList.add(new HeightCriteria(xBound, secondPos, start));
//Z
Vector3d zBound = BuildModes.findZBound(secondPos.getZ(), start, look);
criteriaList.add(new HeightCriteria(zBound, secondPos, start));
//Remove invalid criteria
int reach = ReachHelper.getPlacementReach(player) * 4; //4 times as much as normal placement reach
criteriaList.removeIf(criteria -> !criteria.isValid(start, look, reach, player, skipRaytrace));
//If none are valid, return empty list of blocks
if (criteriaList.isEmpty()) return null;
//If only 1 is valid, choose that one
HeightCriteria selected = criteriaList.get(0);
//If multiple are valid, choose based on criteria
if (criteriaList.size() > 1) {
//Select the one that is closest (from wall position to its line counterpart)
for (int i = 1; i < criteriaList.size(); i++) {
HeightCriteria criteria = criteriaList.get(i);
if (criteria.distToLineSq < 2.0 && selected.distToLineSq < 2.0) {
//Both very close to line, choose closest to player
if (criteria.distToPlayerSq < selected.distToPlayerSq)
selected = criteria;
} else {
//Pick closest to line
if (criteria.distToLineSq < selected.distToLineSq)
selected = criteria;
} }
//Make it from a plane into a line, on y axis only
private Vec3d toLongestLine(Vec3d boundVec, BlockPos secondPos) {
BlockPos bound = new BlockPos(boundVec);
return new Vec3d(secondPos.getX(), bound.getY(), secondPos.getZ());
} }
//check if its not behind the player and its not too close and not too far
//also check if raytrace from player to block does not intersect blocks
public boolean isValid(Vec3d start, Vec3d look, int reach, PlayerEntity player, boolean skipRaytrace) {
return BuildModes.isCriteriaValid(start, look, reach, player, skipRaytrace, lineBound, planeBound, distToPlayerSq);
} }
return new BlockPos(selected.lineBound);
} }
@Override @Override
public void initialize(PlayerEntity player) { public void initialize(PlayerEntity player) {
super.initialize(player); super.initialize(player);
secondPosTable.put(player.getUniqueID(), BlockPos.ZERO); secondPosTable.put(player.getUUID(), BlockPos.ZERO);
} }
@Override @Override
public List<BlockPos> onRightClick(PlayerEntity player, BlockPos blockPos, Direction sideHit, Vec3d hitVec, boolean skipRaytrace) { public List<BlockPos> onRightClick(PlayerEntity player, BlockPos blockPos, Direction sideHit, Vector3d hitVec, boolean skipRaytrace) {
List<BlockPos> list = new ArrayList<>(); List<BlockPos> list = new ArrayList<>();
Dictionary<UUID, Integer> rightClickTable = player.world.isRemote ? rightClickClientTable : rightClickServerTable; Dictionary<UUID, Integer> rightClickTable = player.level.isClientSide ? rightClickClientTable : rightClickServerTable;
int rightClickNr = rightClickTable.get(player.getUniqueID()); int rightClickNr = rightClickTable.get(player.getUUID());
rightClickNr++; rightClickNr++;
rightClickTable.put(player.getUniqueID(), rightClickNr); rightClickTable.put(player.getUUID(), rightClickNr);
if (rightClickNr == 1) { if (rightClickNr == 1) {
//If clicking in air, reset and try again //If clicking in air, reset and try again
if (blockPos == null) { if (blockPos == null) {
rightClickTable.put(player.getUniqueID(), 0); rightClickTable.put(player.getUUID(), 0);
return list; return list;
} }
//First click, remember starting position //First click, remember starting position
firstPosTable.put(player.getUniqueID(), blockPos); firstPosTable.put(player.getUUID(), blockPos);
sideHitTable.put(player.getUniqueID(), sideHit); sideHitTable.put(player.getUUID(), sideHit);
hitVecTable.put(player.getUniqueID(), hitVec); hitVecTable.put(player.getUUID(), hitVec);
//Keep list empty, dont place any blocks yet //Keep list empty, dont place any blocks yet
} else if (rightClickNr == 2) { } else if (rightClickNr == 2) {
//Second click, find other floor point //Second click, find other floor point
BlockPos firstPos = firstPosTable.get(player.getUniqueID()); BlockPos firstPos = firstPosTable.get(player.getUUID());
BlockPos secondPos = findSecondPos(player, firstPos, true); BlockPos secondPos = findSecondPos(player, firstPos, true);
if (secondPos == null) { if (secondPos == null) {
rightClickTable.put(player.getUniqueID(), 1); rightClickTable.put(player.getUUID(), 1);
return list; return list;
} }
secondPosTable.put(player.getUniqueID(), secondPos); secondPosTable.put(player.getUUID(), secondPos);
} else { } else {
//Third click, place diagonal wall with height //Third click, place diagonal wall with height
list = findCoordinates(player, blockPos, skipRaytrace); list = findCoordinates(player, blockPos, skipRaytrace);
rightClickTable.put(player.getUniqueID(), 0); rightClickTable.put(player.getUUID(), 0);
} }
return list; return list;
@@ -89,14 +106,14 @@ public abstract class ThreeClicksBuildMode extends BaseBuildMode {
@Override @Override
public List<BlockPos> findCoordinates(PlayerEntity player, BlockPos blockPos, boolean skipRaytrace) { public List<BlockPos> findCoordinates(PlayerEntity player, BlockPos blockPos, boolean skipRaytrace) {
List<BlockPos> list = new ArrayList<>(); List<BlockPos> list = new ArrayList<>();
Dictionary<UUID, Integer> rightClickTable = player.world.isRemote ? rightClickClientTable : rightClickServerTable; Dictionary<UUID, Integer> rightClickTable = player.level.isClientSide ? rightClickClientTable : rightClickServerTable;
int rightClickNr = rightClickTable.get(player.getUniqueID()); int rightClickNr = rightClickTable.get(player.getUUID());
if (rightClickNr == 0) { if (rightClickNr == 0) {
if (blockPos != null) if (blockPos != null)
list.add(blockPos); list.add(blockPos);
} else if (rightClickNr == 1) { } else if (rightClickNr == 1) {
BlockPos firstPos = firstPosTable.get(player.getUniqueID()); BlockPos firstPos = firstPosTable.get(player.getUUID());
BlockPos secondPos = findSecondPos(player, firstPos, true); BlockPos secondPos = findSecondPos(player, firstPos, true);
if (secondPos == null) return list; if (secondPos == null) return list;
@@ -120,8 +137,8 @@ public abstract class ThreeClicksBuildMode extends BaseBuildMode {
list.addAll(getIntermediateBlocks(player, x1, y1, z1, x2, y2, z2)); list.addAll(getIntermediateBlocks(player, x1, y1, z1, x2, y2, z2));
} else { } else {
BlockPos firstPos = firstPosTable.get(player.getUniqueID()); BlockPos firstPos = firstPosTable.get(player.getUUID());
BlockPos secondPos = secondPosTable.get(player.getUniqueID()); BlockPos secondPos = secondPosTable.get(player.getUUID());
BlockPos thirdPos = findThirdPos(player, firstPos, secondPos, skipRaytrace); BlockPos thirdPos = findThirdPos(player, firstPos, secondPos, skipRaytrace);
if (thirdPos == null) return list; if (thirdPos == null) return list;
@@ -167,47 +184,30 @@ public abstract class ThreeClicksBuildMode extends BaseBuildMode {
//After first, second and third pos are known, we want all the blocks //After first, second and third pos are known, we want all the blocks
protected abstract List<BlockPos> getFinalBlocks(PlayerEntity player, int x1, int y1, int z1, int x2, int y2, int z2, int x3, int y3, int z3); protected abstract List<BlockPos> getFinalBlocks(PlayerEntity player, int x1, int y1, int z1, int x2, int y2, int z2, int x3, int y3, int z3);
//Finds height after floor has been chosen in buildmodes with 3 clicks static class HeightCriteria {
public static BlockPos findHeight(PlayerEntity player, BlockPos secondPos, boolean skipRaytrace) { Vector3d planeBound;
Vec3d look = player.getLookVec(); Vector3d lineBound;
Vec3d start = new Vec3d(player.posX, player.posY + player.getEyeHeight(), player.posZ); double distToLineSq;
double distToPlayerSq;
List<HeightCriteria> criteriaList = new ArrayList<>(3); HeightCriteria(Vector3d planeBound, BlockPos secondPos, Vector3d start) {
this.planeBound = planeBound;
//X this.lineBound = toLongestLine(this.planeBound, secondPos);
Vec3d xBound = BuildModes.findXBound(secondPos.getX(), start, look); this.distToLineSq = this.lineBound.subtract(this.planeBound).lengthSqr();
criteriaList.add(new HeightCriteria(xBound, secondPos, start)); this.distToPlayerSq = this.planeBound.subtract(start).lengthSqr();
//Z
Vec3d zBound = BuildModes.findZBound(secondPos.getZ(), start, look);
criteriaList.add(new HeightCriteria(zBound, secondPos, start));
//Remove invalid criteria
int reach = ReachHelper.getPlacementReach(player) * 4; //4 times as much as normal placement reach
criteriaList.removeIf(criteria -> !criteria.isValid(start, look, reach, player, skipRaytrace));
//If none are valid, return empty list of blocks
if (criteriaList.isEmpty()) return null;
//If only 1 is valid, choose that one
HeightCriteria selected = criteriaList.get(0);
//If multiple are valid, choose based on criteria
if (criteriaList.size() > 1) {
//Select the one that is closest (from wall position to its line counterpart)
for (int i = 1; i < criteriaList.size(); i++) {
HeightCriteria criteria = criteriaList.get(i);
if (criteria.distToLineSq < 2.0 && selected.distToLineSq < 2.0) {
//Both very close to line, choose closest to player
if (criteria.distToPlayerSq < selected.distToPlayerSq)
selected = criteria;
} else {
//Pick closest to line
if (criteria.distToLineSq < selected.distToLineSq)
selected = criteria;
} }
//Make it from a plane into a line, on y axis only
private Vector3d toLongestLine(Vector3d boundVec, BlockPos secondPos) {
BlockPos bound = new BlockPos(boundVec);
return new Vector3d(secondPos.getX(), bound.getY(), secondPos.getZ());
} }
//check if its not behind the player and its not too close and not too far
//also check if raytrace from player to block does not intersect blocks
public boolean isValid(Vector3d start, Vector3d look, int reach, PlayerEntity player, boolean skipRaytrace) {
return BuildModes.isCriteriaValid(start, look, reach, player, skipRaytrace, lineBound, planeBound, distToPlayerSq);
} }
return new BlockPos(selected.lineBound);
} }
} }

View File

@@ -3,7 +3,7 @@ package nl.requios.effortlessbuilding.buildmode;
import net.minecraft.entity.player.PlayerEntity; import net.minecraft.entity.player.PlayerEntity;
import net.minecraft.util.Direction; import net.minecraft.util.Direction;
import net.minecraft.util.math.BlockPos; import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.Vec3d; import net.minecraft.util.math.vector.Vector3d;
import nl.requios.effortlessbuilding.helper.ReachHelper; import nl.requios.effortlessbuilding.helper.ReachHelper;
import java.util.ArrayList; import java.util.ArrayList;
@@ -14,30 +14,30 @@ import java.util.UUID;
public abstract class TwoClicksBuildMode extends BaseBuildMode { public abstract class TwoClicksBuildMode extends BaseBuildMode {
@Override @Override
public List<BlockPos> onRightClick(PlayerEntity player, BlockPos blockPos, Direction sideHit, Vec3d hitVec, boolean skipRaytrace) { public List<BlockPos> onRightClick(PlayerEntity player, BlockPos blockPos, Direction sideHit, Vector3d hitVec, boolean skipRaytrace) {
List<BlockPos> list = new ArrayList<>(); List<BlockPos> list = new ArrayList<>();
Dictionary<UUID, Integer> rightClickTable = player.world.isRemote ? rightClickClientTable : rightClickServerTable; Dictionary<UUID, Integer> rightClickTable = player.level.isClientSide ? rightClickClientTable : rightClickServerTable;
int rightClickNr = rightClickTable.get(player.getUniqueID()); int rightClickNr = rightClickTable.get(player.getUUID());
rightClickNr++; rightClickNr++;
rightClickTable.put(player.getUniqueID(), rightClickNr); rightClickTable.put(player.getUUID(), rightClickNr);
if (rightClickNr == 1) { if (rightClickNr == 1) {
//If clicking in air, reset and try again //If clicking in air, reset and try again
if (blockPos == null) { if (blockPos == null) {
rightClickTable.put(player.getUniqueID(), 0); rightClickTable.put(player.getUUID(), 0);
return list; return list;
} }
//First click, remember starting position //First click, remember starting position
firstPosTable.put(player.getUniqueID(), blockPos); firstPosTable.put(player.getUUID(), blockPos);
sideHitTable.put(player.getUniqueID(), sideHit); sideHitTable.put(player.getUUID(), sideHit);
hitVecTable.put(player.getUniqueID(), hitVec); hitVecTable.put(player.getUUID(), hitVec);
//Keep list empty, dont place any blocks yet //Keep list empty, dont place any blocks yet
} else { } else {
//Second click, place blocks //Second click, place blocks
list = findCoordinates(player, blockPos, skipRaytrace); list = findCoordinates(player, blockPos, skipRaytrace);
rightClickTable.put(player.getUniqueID(), 0); rightClickTable.put(player.getUUID(), 0);
} }
return list; return list;
@@ -46,9 +46,9 @@ public abstract class TwoClicksBuildMode extends BaseBuildMode {
@Override @Override
public List<BlockPos> findCoordinates(PlayerEntity player, BlockPos blockPos, boolean skipRaytrace) { public List<BlockPos> findCoordinates(PlayerEntity player, BlockPos blockPos, boolean skipRaytrace) {
List<BlockPos> list = new ArrayList<>(); List<BlockPos> list = new ArrayList<>();
Dictionary<UUID, Integer> rightClickTable = player.world.isRemote ? rightClickClientTable : rightClickServerTable; Dictionary<UUID, Integer> rightClickTable = player.level.isClientSide ? rightClickClientTable : rightClickServerTable;
int rightClickNr = rightClickTable.get(player.getUniqueID()); int rightClickNr = rightClickTable.get(player.getUUID());
BlockPos firstPos = firstPosTable.get(player.getUniqueID()); BlockPos firstPos = firstPosTable.get(player.getUUID());
if (rightClickNr == 0) { if (rightClickNr == 0) {
if (blockPos != null) if (blockPos != null)

View File

@@ -3,23 +3,14 @@ package nl.requios.effortlessbuilding.buildmode.buildmodes;
import net.minecraft.entity.player.PlayerEntity; import net.minecraft.entity.player.PlayerEntity;
import net.minecraft.util.math.BlockPos; import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.MathHelper; import net.minecraft.util.math.MathHelper;
import nl.requios.effortlessbuilding.buildmode.TwoClicksBuildMode;
import nl.requios.effortlessbuilding.buildmode.ModeOptions; import nl.requios.effortlessbuilding.buildmode.ModeOptions;
import nl.requios.effortlessbuilding.buildmode.TwoClicksBuildMode;
import java.util.*; import java.util.ArrayList;
import java.util.List;
public class Circle extends TwoClicksBuildMode { public class Circle extends TwoClicksBuildMode {
@Override
protected BlockPos findSecondPos(PlayerEntity player, BlockPos firstPos, boolean skipRaytrace) {
return Floor.findFloor(player, firstPos, skipRaytrace);
}
@Override
protected List<BlockPos> getAllBlocks(PlayerEntity player, int x1, int y1, int z1, int x2, int y2, int z2) {
return getCircleBlocks(player, x1, y1, z1, x2, y2, z2);
}
public static List<BlockPos> getCircleBlocks(PlayerEntity player, int x1, int y1, int z1, int x2, int y2, int z2) { public static List<BlockPos> getCircleBlocks(PlayerEntity player, int x1, int y1, int z1, int x2, int y2, int z2) {
List<BlockPos> list = new ArrayList<>(); List<BlockPos> list = new ArrayList<>();
@@ -85,4 +76,14 @@ public class Circle extends TwoClicksBuildMode {
float part2 = radiusZ * radiusZ * MathHelper.cos(theta) * MathHelper.cos(theta); float part2 = radiusZ * radiusZ * MathHelper.cos(theta) * MathHelper.cos(theta);
return radiusX * radiusZ / MathHelper.sqrt(part1 + part2); return radiusX * radiusZ / MathHelper.sqrt(part1 + part2);
} }
@Override
protected BlockPos findSecondPos(PlayerEntity player, BlockPos firstPos, boolean skipRaytrace) {
return Floor.findFloor(player, firstPos, skipRaytrace);
}
@Override
protected List<BlockPos> getAllBlocks(PlayerEntity player, int x1, int y1, int z1, int x2, int y2, int z2) {
return getCircleBlocks(player, x1, y1, z1, x2, y2, z2);
}
} }

View File

@@ -5,30 +5,11 @@ import net.minecraft.util.math.BlockPos;
import nl.requios.effortlessbuilding.buildmode.ModeOptions; import nl.requios.effortlessbuilding.buildmode.ModeOptions;
import nl.requios.effortlessbuilding.buildmode.ThreeClicksBuildMode; import nl.requios.effortlessbuilding.buildmode.ThreeClicksBuildMode;
import java.util.*; import java.util.ArrayList;
import java.util.List;
public class Cube extends ThreeClicksBuildMode { public class Cube extends ThreeClicksBuildMode {
@Override
protected BlockPos findSecondPos(PlayerEntity player, BlockPos firstPos, boolean skipRaytrace) {
return Floor.findFloor(player, firstPos, skipRaytrace);
}
@Override
protected BlockPos findThirdPos(PlayerEntity player, BlockPos firstPos, BlockPos secondPos, boolean skipRaytrace) {
return findHeight(player, secondPos, skipRaytrace);
}
@Override
protected List<BlockPos> getIntermediateBlocks(PlayerEntity player, int x1, int y1, int z1, int x2, int y2, int z2) {
return getFloorBlocksUsingCubeFill(player, x1, y1, z1, x2, y2, z2);
}
@Override
protected List<BlockPos> getFinalBlocks(PlayerEntity player, int x1, int y1, int z1, int x2, int y2, int z2, int x3, int y3, int z3) {
return getCubeBlocks(player, x1, y1, z1, x3, y3, z3);
}
public static List<BlockPos> getFloorBlocksUsingCubeFill(PlayerEntity player, int x1, int y1, int z1, int x2, int y2, int z2) { public static List<BlockPos> getFloorBlocksUsingCubeFill(PlayerEntity player, int x1, int y1, int z1, int x2, int y2, int z2) {
List<BlockPos> list = new ArrayList<>(); List<BlockPos> list = new ArrayList<>();
@@ -97,4 +78,24 @@ public class Cube extends ThreeClicksBuildMode {
Line.addZLineBlocks(list, z1, z2, x2, y1); Line.addZLineBlocks(list, z1, z2, x2, y1);
Line.addZLineBlocks(list, z1, z2, x2, y2); Line.addZLineBlocks(list, z1, z2, x2, y2);
} }
@Override
protected BlockPos findSecondPos(PlayerEntity player, BlockPos firstPos, boolean skipRaytrace) {
return Floor.findFloor(player, firstPos, skipRaytrace);
}
@Override
protected BlockPos findThirdPos(PlayerEntity player, BlockPos firstPos, BlockPos secondPos, boolean skipRaytrace) {
return findHeight(player, secondPos, skipRaytrace);
}
@Override
protected List<BlockPos> getIntermediateBlocks(PlayerEntity player, int x1, int y1, int z1, int x2, int y2, int z2) {
return getFloorBlocksUsingCubeFill(player, x1, y1, z1, x2, y2, z2);
}
@Override
protected List<BlockPos> getFinalBlocks(PlayerEntity player, int x1, int y1, int z1, int x2, int y2, int z2, int x3, int y3, int z3) {
return getCubeBlocks(player, x1, y1, z1, x3, y3, z3);
}
} }

View File

@@ -9,6 +9,25 @@ import java.util.List;
public class Cylinder extends ThreeClicksBuildMode { public class Cylinder extends ThreeClicksBuildMode {
public static List<BlockPos> getCylinderBlocks(PlayerEntity player, int x1, int y1, int z1, int x2, int y2, int z2, int x3, int y3, int z3) {
List<BlockPos> list = new ArrayList<>();
//Get circle blocks (using CIRCLE_START and FILL options built-in)
List<BlockPos> circleBlocks = Circle.getCircleBlocks(player, x1, y1, z1, x2, y2, z2);
int lowest = Math.min(y1, y3);
int highest = Math.max(y1, y3);
//Copy circle on y axis
for (int y = lowest; y <= highest; y++) {
for (BlockPos blockPos : circleBlocks) {
list.add(new BlockPos(blockPos.getX(), y, blockPos.getZ()));
}
}
return list;
}
@Override @Override
public BlockPos findSecondPos(PlayerEntity player, BlockPos firstPos, boolean skipRaytrace) { public BlockPos findSecondPos(PlayerEntity player, BlockPos firstPos, boolean skipRaytrace) {
return Floor.findFloor(player, firstPos, skipRaytrace); return Floor.findFloor(player, firstPos, skipRaytrace);
@@ -28,23 +47,4 @@ public class Cylinder extends ThreeClicksBuildMode {
public List<BlockPos> getFinalBlocks(PlayerEntity player, int x1, int y1, int z1, int x2, int y2, int z2, int x3, int y3, int z3) { public List<BlockPos> getFinalBlocks(PlayerEntity player, int x1, int y1, int z1, int x2, int y2, int z2, int x3, int y3, int z3) {
return getCylinderBlocks(player, x1, y1, z1, x2, y2, z2, x3, y3, z3); return getCylinderBlocks(player, x1, y1, z1, x2, y2, z2, x3, y3, z3);
} }
public static List<BlockPos> getCylinderBlocks(PlayerEntity player, int x1, int y1, int z1, int x2, int y2, int z2, int x3, int y3, int z3) {
List<BlockPos> list = new ArrayList<>();
//Get circle blocks (using CIRCLE_START and FILL options built-in)
List<BlockPos> circleBlocks = Circle.getCircleBlocks(player, x1, y1, z1, x2, y2, z2);
int lowest = Math.min(y1, y3);
int highest = Math.max(y1, y3);
//Copy circle on y axis
for (int y = lowest; y <= highest; y++) {
for (BlockPos blockPos : circleBlocks) {
list.add(new BlockPos(blockPos.getX(), y, blockPos.getZ()));
}
}
return list;
}
} }

View File

@@ -2,7 +2,7 @@ package nl.requios.effortlessbuilding.buildmode.buildmodes;
import net.minecraft.entity.player.PlayerEntity; import net.minecraft.entity.player.PlayerEntity;
import net.minecraft.util.math.BlockPos; import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.Vec3d; import net.minecraft.util.math.vector.Vector3d;
import nl.requios.effortlessbuilding.buildmode.ThreeClicksBuildMode; import nl.requios.effortlessbuilding.buildmode.ThreeClicksBuildMode;
import java.util.ArrayList; import java.util.ArrayList;
@@ -10,6 +10,25 @@ import java.util.List;
public class DiagonalLine extends ThreeClicksBuildMode { public class DiagonalLine extends ThreeClicksBuildMode {
//Add diagonal line from first to second
public static List<BlockPos> getDiagonalLineBlocks(PlayerEntity player, int x1, int y1, int z1, int x2, int y2, int z2, float sampleMultiplier) {
List<BlockPos> list = new ArrayList<>();
Vector3d first = new Vector3d(x1, y1, z1).add(0.5, 0.5, 0.5);
Vector3d second = new Vector3d(x2, y2, z2).add(0.5, 0.5, 0.5);
int iterations = (int) Math.ceil(first.distanceTo(second) * sampleMultiplier);
for (double t = 0; t <= 1.0; t += 1.0 / iterations) {
Vector3d lerp = first.add(second.subtract(first).scale(t));
BlockPos candidate = new BlockPos(lerp);
//Only add if not equal to the last in the list
if (list.isEmpty() || !list.get(list.size() - 1).equals(candidate))
list.add(candidate);
}
return list;
}
@Override @Override
protected BlockPos findSecondPos(PlayerEntity player, BlockPos firstPos, boolean skipRaytrace) { protected BlockPos findSecondPos(PlayerEntity player, BlockPos firstPos, boolean skipRaytrace) {
return Floor.findFloor(player, firstPos, skipRaytrace); return Floor.findFloor(player, firstPos, skipRaytrace);
@@ -31,23 +50,4 @@ public class DiagonalLine extends ThreeClicksBuildMode {
//Add diagonal line from first to third //Add diagonal line from first to third
return getDiagonalLineBlocks(player, x1, y1, z1, x3, y3, z3, 10); return getDiagonalLineBlocks(player, x1, y1, z1, x3, y3, z3, 10);
} }
//Add diagonal line from first to second
public static List<BlockPos> getDiagonalLineBlocks(PlayerEntity player, int x1, int y1, int z1, int x2, int y2, int z2, float sampleMultiplier) {
List<BlockPos> list = new ArrayList<>();
Vec3d first = new Vec3d(x1, y1, z1).add(0.5, 0.5, 0.5);
Vec3d second = new Vec3d(x2, y2, z2).add(0.5, 0.5, 0.5);
int iterations = (int) Math.ceil(first.distanceTo(second) * sampleMultiplier);
for (double t = 0; t <= 1.0; t += 1.0/iterations) {
Vec3d lerp = first.add(second.subtract(first).scale(t));
BlockPos candidate = new BlockPos(lerp);
//Only add if not equal to the last in the list
if (list.isEmpty() || !list.get(list.size() - 1).equals(candidate))
list.add(candidate);
}
return list;
}
} }

View File

@@ -9,26 +9,6 @@ import java.util.List;
public class DiagonalWall extends ThreeClicksBuildMode { public class DiagonalWall extends ThreeClicksBuildMode {
@Override
protected BlockPos findSecondPos(PlayerEntity player, BlockPos firstPos, boolean skipRaytrace) {
return Floor.findFloor(player, firstPos, skipRaytrace);
}
@Override
protected BlockPos findThirdPos(PlayerEntity player, BlockPos firstPos, BlockPos secondPos, boolean skipRaytrace) {
return findHeight(player, secondPos, skipRaytrace);
}
@Override
protected List<BlockPos> getIntermediateBlocks(PlayerEntity player, int x1, int y1, int z1, int x2, int y2, int z2) {
return DiagonalLine.getDiagonalLineBlocks(player, x1, y1, z1, x2, y2, z2, 1);
}
@Override
protected List<BlockPos> getFinalBlocks(PlayerEntity player, int x1, int y1, int z1, int x2, int y2, int z2, int x3, int y3, int z3) {
return getDiagonalWallBlocks(player, x1, y1, z1, x2, y2, z2, x3, y3, z3);
}
//Add diagonal wall from first to second //Add diagonal wall from first to second
public static List<BlockPos> getDiagonalWallBlocks(PlayerEntity player, int x1, int y1, int z1, int x2, int y2, int z2, int x3, int y3, int z3) { public static List<BlockPos> getDiagonalWallBlocks(PlayerEntity player, int x1, int y1, int z1, int x2, int y2, int z2, int x3, int y3, int z3) {
List<BlockPos> list = new ArrayList<>(); List<BlockPos> list = new ArrayList<>();
@@ -48,4 +28,24 @@ public class DiagonalWall extends ThreeClicksBuildMode {
return list; return list;
} }
@Override
protected BlockPos findSecondPos(PlayerEntity player, BlockPos firstPos, boolean skipRaytrace) {
return Floor.findFloor(player, firstPos, skipRaytrace);
}
@Override
protected BlockPos findThirdPos(PlayerEntity player, BlockPos firstPos, BlockPos secondPos, boolean skipRaytrace) {
return findHeight(player, secondPos, skipRaytrace);
}
@Override
protected List<BlockPos> getIntermediateBlocks(PlayerEntity player, int x1, int y1, int z1, int x2, int y2, int z2) {
return DiagonalLine.getDiagonalLineBlocks(player, x1, y1, z1, x2, y2, z2, 1);
}
@Override
protected List<BlockPos> getFinalBlocks(PlayerEntity player, int x1, int y1, int z1, int x2, int y2, int z2, int x3, int y3, int z3) {
return getDiagonalWallBlocks(player, x1, y1, z1, x2, y2, z2, x3, y3, z3);
}
} }

View File

@@ -2,46 +2,25 @@ package nl.requios.effortlessbuilding.buildmode.buildmodes;
import net.minecraft.entity.player.PlayerEntity; import net.minecraft.entity.player.PlayerEntity;
import net.minecraft.util.math.BlockPos; import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.Vec3d; import net.minecraft.util.math.vector.Vector3d;
import nl.requios.effortlessbuilding.buildmode.BuildModes; import nl.requios.effortlessbuilding.buildmode.BuildModes;
import nl.requios.effortlessbuilding.buildmode.TwoClicksBuildMode;
import nl.requios.effortlessbuilding.buildmode.ModeOptions; import nl.requios.effortlessbuilding.buildmode.ModeOptions;
import nl.requios.effortlessbuilding.buildmode.TwoClicksBuildMode;
import nl.requios.effortlessbuilding.helper.ReachHelper; import nl.requios.effortlessbuilding.helper.ReachHelper;
import java.util.*; import java.util.ArrayList;
import java.util.List;
public class Floor extends TwoClicksBuildMode { public class Floor extends TwoClicksBuildMode {
static class Criteria {
Vec3d planeBound;
double distToPlayerSq;
Criteria(Vec3d planeBound, Vec3d start) {
this.planeBound = planeBound;
this.distToPlayerSq = this.planeBound.subtract(start).lengthSquared();
}
//check if its not behind the player and its not too close and not too far
//also check if raytrace from player to block does not intersect blocks
public boolean isValid(Vec3d start, Vec3d look, int reach, PlayerEntity player, boolean skipRaytrace) {
return BuildModes.isCriteriaValid(start, look, reach, player, skipRaytrace, planeBound, planeBound, distToPlayerSq);
}
}
@Override
protected BlockPos findSecondPos(PlayerEntity player, BlockPos firstPos, boolean skipRaytrace) {
return findFloor(player, firstPos, skipRaytrace);
}
public static BlockPos findFloor(PlayerEntity player, BlockPos firstPos, boolean skipRaytrace) { public static BlockPos findFloor(PlayerEntity player, BlockPos firstPos, boolean skipRaytrace) {
Vec3d look = player.getLookVec(); Vector3d look = BuildModes.getPlayerLookVec(player);
Vec3d start = new Vec3d(player.posX, player.posY + player.getEyeHeight(), player.posZ); Vector3d start = new Vector3d(player.getX(), player.getY() + player.getEyeHeight(), player.getZ());
List<Criteria> criteriaList = new ArrayList<>(3); List<Criteria> criteriaList = new ArrayList<>(3);
//Y //Y
Vec3d yBound = BuildModes.findYBound(firstPos.getY(), start, look); Vector3d yBound = BuildModes.findYBound(firstPos.getY(), start, look);
criteriaList.add(new Criteria(yBound, start)); criteriaList.add(new Criteria(yBound, start));
//Remove invalid criteria //Remove invalid criteria
@@ -57,11 +36,6 @@ public class Floor extends TwoClicksBuildMode {
return new BlockPos(selected.planeBound); return new BlockPos(selected.planeBound);
} }
@Override
protected List<BlockPos> getAllBlocks(PlayerEntity player, int x1, int y1, int z1, int x2, int y2, int z2) {
return getFloorBlocks(player, x1, y1, z1, x2, y2, z2);
}
public static List<BlockPos> getFloorBlocks(PlayerEntity player, int x1, int y1, int z1, int x2, int y2, int z2) { public static List<BlockPos> getFloorBlocks(PlayerEntity player, int x1, int y1, int z1, int x2, int y2, int z2) {
List<BlockPos> list = new ArrayList<>(); List<BlockPos> list = new ArrayList<>();
@@ -90,4 +64,31 @@ public class Floor extends TwoClicksBuildMode {
Line.addZLineBlocks(list, z1, z2, x1, y); Line.addZLineBlocks(list, z1, z2, x1, y);
Line.addZLineBlocks(list, z1, z2, x2, y); Line.addZLineBlocks(list, z1, z2, x2, y);
} }
@Override
protected BlockPos findSecondPos(PlayerEntity player, BlockPos firstPos, boolean skipRaytrace) {
return findFloor(player, firstPos, skipRaytrace);
}
@Override
protected List<BlockPos> getAllBlocks(PlayerEntity player, int x1, int y1, int z1, int x2, int y2, int z2) {
return getFloorBlocks(player, x1, y1, z1, x2, y2, z2);
}
static class Criteria {
Vector3d planeBound;
double distToPlayerSq;
Criteria(Vector3d planeBound, Vector3d start) {
this.planeBound = planeBound;
this.distToPlayerSq = this.planeBound.subtract(start).lengthSqr();
}
//check if its not behind the player and its not too close and not too far
//also check if raytrace from player to block does not intersect blocks
public boolean isValid(Vector3d start, Vector3d look, int reach, PlayerEntity player, boolean skipRaytrace) {
return BuildModes.isCriteriaValid(start, look, reach, player, skipRaytrace, planeBound, planeBound, distToPlayerSq);
}
}
} }

View File

@@ -2,7 +2,7 @@ package nl.requios.effortlessbuilding.buildmode.buildmodes;
import net.minecraft.entity.player.PlayerEntity; import net.minecraft.entity.player.PlayerEntity;
import net.minecraft.util.math.BlockPos; import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.Vec3d; import net.minecraft.util.math.vector.Vector3d;
import nl.requios.effortlessbuilding.buildmode.BuildModes; import nl.requios.effortlessbuilding.buildmode.BuildModes;
import nl.requios.effortlessbuilding.buildmode.TwoClicksBuildMode; import nl.requios.effortlessbuilding.buildmode.TwoClicksBuildMode;
import nl.requios.effortlessbuilding.helper.ReachHelper; import nl.requios.effortlessbuilding.helper.ReachHelper;
@@ -12,69 +12,22 @@ import java.util.List;
public class Line extends TwoClicksBuildMode { public class Line extends TwoClicksBuildMode {
static class Criteria {
Vec3d planeBound;
Vec3d lineBound;
double distToLineSq;
double distToPlayerSq;
Criteria(Vec3d planeBound, BlockPos firstPos, Vec3d start) {
this.planeBound = planeBound;
this.lineBound = toLongestLine(this.planeBound, firstPos);
this.distToLineSq = this.lineBound.subtract(this.planeBound).lengthSquared();
this.distToPlayerSq = this.planeBound.subtract(start).lengthSquared();
}
//Make it from a plane into a line
//Select the axis that is longest
private Vec3d toLongestLine(Vec3d boundVec, BlockPos firstPos) {
BlockPos bound = new BlockPos(boundVec);
BlockPos firstToSecond = bound.subtract(firstPos);
firstToSecond = new BlockPos(Math.abs(firstToSecond.getX()), Math.abs(firstToSecond.getY()), Math.abs(firstToSecond.getZ()));
int longest = Math.max(firstToSecond.getX(), Math.max(firstToSecond.getY(), firstToSecond.getZ()));
if (longest == firstToSecond.getX()) {
return new Vec3d(bound.getX(), firstPos.getY(), firstPos.getZ());
}
if (longest == firstToSecond.getY()) {
return new Vec3d(firstPos.getX(), bound.getY(), firstPos.getZ());
}
if (longest == firstToSecond.getZ()) {
return new Vec3d(firstPos.getX(), firstPos.getY(), bound.getZ());
}
return null;
}
//check if its not behind the player and its not too close and not too far
//also check if raytrace from player to block does not intersect blocks
public boolean isValid(Vec3d start, Vec3d look, int reach, PlayerEntity player, boolean skipRaytrace) {
return BuildModes.isCriteriaValid(start, look, reach, player, skipRaytrace, lineBound, planeBound, distToPlayerSq);
}
}
@Override
protected BlockPos findSecondPos(PlayerEntity player, BlockPos firstPos, boolean skipRaytrace) {
return findLine(player, firstPos, skipRaytrace);
}
public static BlockPos findLine(PlayerEntity player, BlockPos firstPos, boolean skipRaytrace) { public static BlockPos findLine(PlayerEntity player, BlockPos firstPos, boolean skipRaytrace) {
Vec3d look = player.getLookVec(); Vector3d look = BuildModes.getPlayerLookVec(player);
Vec3d start = new Vec3d(player.posX, player.posY + player.getEyeHeight(), player.posZ); Vector3d start = new Vector3d(player.getX(), player.getY() + player.getEyeHeight(), player.getZ());
List<Criteria> criteriaList = new ArrayList<>(3); List<Criteria> criteriaList = new ArrayList<>(3);
//X //X
Vec3d xBound = BuildModes.findXBound(firstPos.getX(), start, look); Vector3d xBound = BuildModes.findXBound(firstPos.getX(), start, look);
criteriaList.add(new Criteria(xBound, firstPos, start)); criteriaList.add(new Criteria(xBound, firstPos, start));
//Y //Y
Vec3d yBound = BuildModes.findYBound(firstPos.getY(), start, look); Vector3d yBound = BuildModes.findYBound(firstPos.getY(), start, look);
criteriaList.add(new Criteria(yBound, firstPos, start)); criteriaList.add(new Criteria(yBound, firstPos, start));
//Z //Z
Vec3d zBound = BuildModes.findZBound(firstPos.getZ(), start, look); Vector3d zBound = BuildModes.findZBound(firstPos.getZ(), start, look);
criteriaList.add(new Criteria(zBound, firstPos, start)); criteriaList.add(new Criteria(zBound, firstPos, start));
//Remove invalid criteria //Remove invalid criteria
@@ -108,11 +61,6 @@ public class Line extends TwoClicksBuildMode {
return new BlockPos(selected.lineBound); return new BlockPos(selected.lineBound);
} }
@Override
protected List<BlockPos> getAllBlocks(PlayerEntity player, int x1, int y1, int z1, int x2, int y2, int z2) {
return getLineBlocks(player, x1, y1, z1, x2, y2, z2);
}
public static List<BlockPos> getLineBlocks(PlayerEntity player, int x1, int y1, int z1, int x2, int y2, int z2) { public static List<BlockPos> getLineBlocks(PlayerEntity player, int x1, int y1, int z1, int x2, int y2, int z2) {
List<BlockPos> list = new ArrayList<>(); List<BlockPos> list = new ArrayList<>();
@@ -144,4 +92,56 @@ public class Line extends TwoClicksBuildMode {
list.add(new BlockPos(x, y, z)); list.add(new BlockPos(x, y, z));
} }
} }
@Override
protected BlockPos findSecondPos(PlayerEntity player, BlockPos firstPos, boolean skipRaytrace) {
return findLine(player, firstPos, skipRaytrace);
}
@Override
protected List<BlockPos> getAllBlocks(PlayerEntity player, int x1, int y1, int z1, int x2, int y2, int z2) {
return getLineBlocks(player, x1, y1, z1, x2, y2, z2);
}
static class Criteria {
Vector3d planeBound;
Vector3d lineBound;
double distToLineSq;
double distToPlayerSq;
Criteria(Vector3d planeBound, BlockPos firstPos, Vector3d start) {
this.planeBound = planeBound;
this.lineBound = toLongestLine(this.planeBound, firstPos);
this.distToLineSq = this.lineBound.subtract(this.planeBound).lengthSqr();
this.distToPlayerSq = this.planeBound.subtract(start).lengthSqr();
}
//Make it from a plane into a line
//Select the axis that is longest
private Vector3d toLongestLine(Vector3d boundVec, BlockPos firstPos) {
BlockPos bound = new BlockPos(boundVec);
BlockPos firstToSecond = bound.subtract(firstPos);
firstToSecond = new BlockPos(Math.abs(firstToSecond.getX()), Math.abs(firstToSecond.getY()), Math.abs(firstToSecond.getZ()));
int longest = Math.max(firstToSecond.getX(), Math.max(firstToSecond.getY(), firstToSecond.getZ()));
if (longest == firstToSecond.getX()) {
return new Vector3d(bound.getX(), firstPos.getY(), firstPos.getZ());
}
if (longest == firstToSecond.getY()) {
return new Vector3d(firstPos.getX(), bound.getY(), firstPos.getZ());
}
if (longest == firstToSecond.getZ()) {
return new Vector3d(firstPos.getX(), firstPos.getY(), bound.getZ());
}
return null;
}
//check if its not behind the player and its not too close and not too far
//also check if raytrace from player to block does not intersect blocks
public boolean isValid(Vector3d start, Vector3d look, int reach, PlayerEntity player, boolean skipRaytrace) {
return BuildModes.isCriteriaValid(start, look, reach, player, skipRaytrace, lineBound, planeBound, distToPlayerSq);
}
}
} }

View File

@@ -3,7 +3,7 @@ package nl.requios.effortlessbuilding.buildmode.buildmodes;
import net.minecraft.entity.player.PlayerEntity; import net.minecraft.entity.player.PlayerEntity;
import net.minecraft.util.Direction; import net.minecraft.util.Direction;
import net.minecraft.util.math.BlockPos; import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.Vec3d; import net.minecraft.util.math.vector.Vector3d;
import nl.requios.effortlessbuilding.buildmode.IBuildMode; import nl.requios.effortlessbuilding.buildmode.IBuildMode;
import java.util.ArrayList; import java.util.ArrayList;
@@ -16,7 +16,7 @@ public class Normal implements IBuildMode {
} }
@Override @Override
public List<BlockPos> onRightClick(PlayerEntity player, BlockPos blockPos, Direction sideHit, Vec3d hitVec, boolean skipRaytrace) { public List<BlockPos> onRightClick(PlayerEntity player, BlockPos blockPos, Direction sideHit, Vector3d hitVec, boolean skipRaytrace) {
List<BlockPos> list = new ArrayList<>(); List<BlockPos> list = new ArrayList<>();
if (blockPos != null) list.add(blockPos); if (blockPos != null) list.add(blockPos);
return list; return list;
@@ -35,7 +35,7 @@ public class Normal implements IBuildMode {
} }
@Override @Override
public Vec3d getHitVec(PlayerEntity player) { public Vector3d getHitVec(PlayerEntity player) {
return null; return null;
} }
} }

View File

@@ -3,7 +3,7 @@ package nl.requios.effortlessbuilding.buildmode.buildmodes;
import net.minecraft.entity.player.PlayerEntity; import net.minecraft.entity.player.PlayerEntity;
import net.minecraft.util.Direction; import net.minecraft.util.Direction;
import net.minecraft.util.math.BlockPos; import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.Vec3d; import net.minecraft.util.math.vector.Vector3d;
import nl.requios.effortlessbuilding.buildmode.IBuildMode; import nl.requios.effortlessbuilding.buildmode.IBuildMode;
import java.util.ArrayList; import java.util.ArrayList;
@@ -16,7 +16,7 @@ public class NormalPlus implements IBuildMode {
} }
@Override @Override
public List<BlockPos> onRightClick(PlayerEntity player, BlockPos blockPos, Direction sideHit, Vec3d hitVec, boolean skipRaytrace) { public List<BlockPos> onRightClick(PlayerEntity player, BlockPos blockPos, Direction sideHit, Vector3d hitVec, boolean skipRaytrace) {
List<BlockPos> list = new ArrayList<>(); List<BlockPos> list = new ArrayList<>();
if (blockPos != null) list.add(blockPos); if (blockPos != null) list.add(blockPos);
return list; return list;
@@ -35,7 +35,7 @@ public class NormalPlus implements IBuildMode {
} }
@Override @Override
public Vec3d getHitVec(PlayerEntity player) { public Vector3d getHitVec(PlayerEntity player) {
return null; return null;
} }
} }

View File

@@ -11,26 +11,6 @@ import java.util.List;
public class SlopeFloor extends ThreeClicksBuildMode { public class SlopeFloor extends ThreeClicksBuildMode {
@Override
protected BlockPos findSecondPos(PlayerEntity player, BlockPos firstPos, boolean skipRaytrace) {
return Floor.findFloor(player, firstPos, skipRaytrace);
}
@Override
protected BlockPos findThirdPos(PlayerEntity player, BlockPos firstPos, BlockPos secondPos, boolean skipRaytrace) {
return findHeight(player, secondPos, skipRaytrace);
}
@Override
protected List<BlockPos> getIntermediateBlocks(PlayerEntity player, int x1, int y1, int z1, int x2, int y2, int z2) {
return Floor.getFloorBlocks(player, x1, y1, z1, x2, y2, z2);
}
@Override
protected List<BlockPos> getFinalBlocks(PlayerEntity player, int x1, int y1, int z1, int x2, int y2, int z2, int x3, int y3, int z3) {
return getSlopeFloorBlocks(player, x1, y1, z1, x2, y2, z2, x3, y3, z3);
}
//Add slope floor from first to second //Add slope floor from first to second
public static List<BlockPos> getSlopeFloorBlocks(PlayerEntity player, int x1, int y1, int z1, int x2, int y2, int z2, int x3, int y3, int z3) { public static List<BlockPos> getSlopeFloorBlocks(PlayerEntity player, int x1, int y1, int z1, int x2, int y2, int z2, int x3, int y3, int z3) {
List<BlockPos> list = new ArrayList<>(); List<BlockPos> list = new ArrayList<>();
@@ -92,4 +72,24 @@ public class SlopeFloor extends ThreeClicksBuildMode {
return list; return list;
} }
@Override
protected BlockPos findSecondPos(PlayerEntity player, BlockPos firstPos, boolean skipRaytrace) {
return Floor.findFloor(player, firstPos, skipRaytrace);
}
@Override
protected BlockPos findThirdPos(PlayerEntity player, BlockPos firstPos, BlockPos secondPos, boolean skipRaytrace) {
return findHeight(player, secondPos, skipRaytrace);
}
@Override
protected List<BlockPos> getIntermediateBlocks(PlayerEntity player, int x1, int y1, int z1, int x2, int y2, int z2) {
return Floor.getFloorBlocks(player, x1, y1, z1, x2, y2, z2);
}
@Override
protected List<BlockPos> getFinalBlocks(PlayerEntity player, int x1, int y1, int z1, int x2, int y2, int z2, int x3, int y3, int z3) {
return getSlopeFloorBlocks(player, x1, y1, z1, x2, y2, z2, x3, y3, z3);
}
} }

View File

@@ -11,26 +11,6 @@ import java.util.List;
public class Sphere extends ThreeClicksBuildMode { public class Sphere extends ThreeClicksBuildMode {
@Override
public BlockPos findSecondPos(PlayerEntity player, BlockPos firstPos, boolean skipRaytrace) {
return Floor.findFloor(player, firstPos, skipRaytrace);
}
@Override
public BlockPos findThirdPos(PlayerEntity player, BlockPos firstPos, BlockPos secondPos, boolean skipRaytrace) {
return findHeight(player, secondPos, skipRaytrace);
}
@Override
public List<BlockPos> getIntermediateBlocks(PlayerEntity player, int x1, int y1, int z1, int x2, int y2, int z2) {
return Circle.getCircleBlocks(player, x1, y1, z1, x2, y2, z2);
}
@Override
public List<BlockPos> getFinalBlocks(PlayerEntity player, int x1, int y1, int z1, int x2, int y2, int z2, int x3, int y3, int z3) {
return getSphereBlocks(player, x1, y1, z1, x2, y2, z2, x3, y3, z3);
}
public static List<BlockPos> getSphereBlocks(PlayerEntity player, int x1, int y1, int z1, int x2, int y2, int z2, int x3, int y3, int z3) { public static List<BlockPos> getSphereBlocks(PlayerEntity player, int x1, int y1, int z1, int x2, int y2, int z2, int x3, int y3, int z3) {
List<BlockPos> list = new ArrayList<>(); List<BlockPos> list = new ArrayList<>();
@@ -107,4 +87,24 @@ public class Sphere extends ThreeClicksBuildMode {
return Circle.calculateEllipseRadius(centerX, centerY, radiusXZ, radiusY, x, y); return Circle.calculateEllipseRadius(centerX, centerY, radiusXZ, radiusY, x, y);
} }
@Override
public BlockPos findSecondPos(PlayerEntity player, BlockPos firstPos, boolean skipRaytrace) {
return Floor.findFloor(player, firstPos, skipRaytrace);
}
@Override
public BlockPos findThirdPos(PlayerEntity player, BlockPos firstPos, BlockPos secondPos, boolean skipRaytrace) {
return findHeight(player, secondPos, skipRaytrace);
}
@Override
public List<BlockPos> getIntermediateBlocks(PlayerEntity player, int x1, int y1, int z1, int x2, int y2, int z2) {
return Circle.getCircleBlocks(player, x1, y1, z1, x2, y2, z2);
}
@Override
public List<BlockPos> getFinalBlocks(PlayerEntity player, int x1, int y1, int z1, int x2, int y2, int z2, int x3, int y3, int z3) {
return getSphereBlocks(player, x1, y1, z1, x2, y2, z2, x3, y3, z3);
}
} }

View File

@@ -2,53 +2,29 @@ package nl.requios.effortlessbuilding.buildmode.buildmodes;
import net.minecraft.entity.player.PlayerEntity; import net.minecraft.entity.player.PlayerEntity;
import net.minecraft.util.math.BlockPos; import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.Vec3d; import net.minecraft.util.math.vector.Vector3d;
import nl.requios.effortlessbuilding.buildmode.BuildModes; import nl.requios.effortlessbuilding.buildmode.BuildModes;
import nl.requios.effortlessbuilding.buildmode.TwoClicksBuildMode;
import nl.requios.effortlessbuilding.buildmode.ModeOptions; import nl.requios.effortlessbuilding.buildmode.ModeOptions;
import nl.requios.effortlessbuilding.buildmode.TwoClicksBuildMode;
import nl.requios.effortlessbuilding.helper.ReachHelper; import nl.requios.effortlessbuilding.helper.ReachHelper;
import java.util.*; import java.util.ArrayList;
import java.util.List;
public class Wall extends TwoClicksBuildMode { public class Wall extends TwoClicksBuildMode {
static class Criteria {
Vec3d planeBound;
double distToPlayerSq;
double angle;
Criteria(Vec3d planeBound, BlockPos firstPos, Vec3d start, Vec3d look) {
this.planeBound = planeBound;
this.distToPlayerSq = this.planeBound.subtract(start).lengthSquared();
Vec3d wall = this.planeBound.subtract(new Vec3d(firstPos));
this.angle = wall.x * look.x + wall.z * look.z; //dot product ignoring y (looking up/down should not affect this angle)
}
//check if its not behind the player and its not too close and not too far
//also check if raytrace from player to block does not intersect blocks
public boolean isValid(Vec3d start, Vec3d look, int reach, PlayerEntity player, boolean skipRaytrace) {
return BuildModes.isCriteriaValid(start, look, reach, player, skipRaytrace, planeBound, planeBound, distToPlayerSq);
}
}
@Override
protected BlockPos findSecondPos(PlayerEntity player, BlockPos firstPos, boolean skipRaytrace) {
return findWall(player, firstPos, skipRaytrace);
}
public static BlockPos findWall(PlayerEntity player, BlockPos firstPos, boolean skipRaytrace) { public static BlockPos findWall(PlayerEntity player, BlockPos firstPos, boolean skipRaytrace) {
Vec3d look = player.getLookVec(); Vector3d look = BuildModes.getPlayerLookVec(player);
Vec3d start = new Vec3d(player.posX, player.posY + player.getEyeHeight(), player.posZ); Vector3d start = new Vector3d(player.getX(), player.getY() + player.getEyeHeight(), player.getZ());
List<Criteria> criteriaList = new ArrayList<>(3); List<Criteria> criteriaList = new ArrayList<>(3);
//X //X
Vec3d xBound = BuildModes.findXBound(firstPos.getX(), start, look); Vector3d xBound = BuildModes.findXBound(firstPos.getX(), start, look);
criteriaList.add(new Criteria(xBound, firstPos, start, look)); criteriaList.add(new Criteria(xBound, firstPos, start, look));
//Z //Z
Vec3d zBound = BuildModes.findZBound(firstPos.getZ(), start, look); Vector3d zBound = BuildModes.findZBound(firstPos.getZ(), start, look);
criteriaList.add(new Criteria(zBound, firstPos, start, look)); criteriaList.add(new Criteria(zBound, firstPos, start, look));
//Remove invalid criteria //Remove invalid criteria
@@ -75,11 +51,6 @@ public class Wall extends TwoClicksBuildMode {
return new BlockPos(selected.planeBound); return new BlockPos(selected.planeBound);
} }
@Override
protected List<BlockPos> getAllBlocks(PlayerEntity player, int x1, int y1, int z1, int x2, int y2, int z2) {
return getWallBlocks(player, x1, y1, z1, x2, y2, z2);
}
public static List<BlockPos> getWallBlocks(PlayerEntity player, int x1, int y1, int z1, int x2, int y2, int z2) { public static List<BlockPos> getWallBlocks(PlayerEntity player, int x1, int y1, int z1, int x2, int y2, int z2) {
List<BlockPos> list = new ArrayList<>(); List<BlockPos> list = new ArrayList<>();
@@ -131,4 +102,34 @@ public class Wall extends TwoClicksBuildMode {
Line.addYLineBlocks(list, y1, y2, x1, z); Line.addYLineBlocks(list, y1, y2, x1, z);
Line.addYLineBlocks(list, y1, y2, x2, z); Line.addYLineBlocks(list, y1, y2, x2, z);
} }
@Override
protected BlockPos findSecondPos(PlayerEntity player, BlockPos firstPos, boolean skipRaytrace) {
return findWall(player, firstPos, skipRaytrace);
}
@Override
protected List<BlockPos> getAllBlocks(PlayerEntity player, int x1, int y1, int z1, int x2, int y2, int z2) {
return getWallBlocks(player, x1, y1, z1, x2, y2, z2);
}
static class Criteria {
Vector3d planeBound;
double distToPlayerSq;
double angle;
Criteria(Vector3d planeBound, BlockPos firstPos, Vector3d start, Vector3d look) {
this.planeBound = planeBound;
this.distToPlayerSq = this.planeBound.subtract(start).lengthSqr();
Vector3d wall = this.planeBound.subtract(Vector3d.atLowerCornerOf(firstPos));
this.angle = wall.x * look.x + wall.z * look.z; //dot product ignoring y (looking up/down should not affect this angle)
}
//check if its not behind the player and its not too close and not too far
//also check if raytrace from player to block does not intersect blocks
public boolean isValid(Vector3d start, Vector3d look, int reach, PlayerEntity player, boolean skipRaytrace) {
return BuildModes.isCriteriaValid(start, look, reach, player, skipRaytrace, planeBound, planeBound, distToPlayerSq);
}
}
} }

View File

@@ -6,17 +6,77 @@ import net.minecraft.item.ItemStack;
import net.minecraft.util.Direction; import net.minecraft.util.Direction;
import net.minecraft.util.Hand; import net.minecraft.util.Hand;
import net.minecraft.util.math.BlockPos; import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.Vec3d; import net.minecraft.util.math.vector.Vector3d;
import net.minecraft.util.math.Vec3i; import net.minecraft.util.math.vector.Vector3i;
import net.minecraftforge.items.IItemHandler; import net.minecraftforge.items.IItemHandler;
import nl.requios.effortlessbuilding.item.ItemRandomizerBag; import nl.requios.effortlessbuilding.item.AbstractRandomizerBagItem;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
public class Array { public class Array {
public static class ArraySettings{ public static List<BlockPos> findCoordinates(PlayerEntity player, BlockPos startPos) {
List<BlockPos> coordinates = new ArrayList<>();
//find arraysettings for the player
ArraySettings a = ModifierSettingsManager.getModifierSettings(player).getArraySettings();
if (!isEnabled(a)) return coordinates;
BlockPos pos = startPos;
Vector3i offset = new Vector3i(a.offset.getX(), a.offset.getY(), a.offset.getZ());
for (int i = 0; i < a.count; i++) {
pos = pos.offset(offset);
coordinates.add(pos);
}
return coordinates;
}
public static List<BlockState> findBlockStates(PlayerEntity player, BlockPos startPos, BlockState blockState, ItemStack itemStack, List<ItemStack> itemStacks) {
List<BlockState> blockStates = new ArrayList<>();
//find arraysettings for the player that placed the block
ArraySettings a = ModifierSettingsManager.getModifierSettings(player).getArraySettings();
if (!isEnabled(a)) return blockStates;
BlockPos pos = startPos;
Vector3i offset = new Vector3i(a.offset.getX(), a.offset.getY(), a.offset.getZ());
//Randomizer bag synergy
AbstractRandomizerBagItem randomizerBagItem = null;
IItemHandler bagInventory = null;
if (!itemStack.isEmpty() && itemStack.getItem() instanceof AbstractRandomizerBagItem) {
randomizerBagItem = (AbstractRandomizerBagItem) itemStack.getItem();
bagInventory = randomizerBagItem.getBagInventory(itemStack);
}
for (int i = 0; i < a.count; i++) {
pos = pos.offset(offset);
//Randomizer bag synergy
if (randomizerBagItem != null) {
itemStack = randomizerBagItem.pickRandomStack(bagInventory);
blockState = BuildModifiers
.getBlockStateFromItem(itemStack, player, startPos, Direction.UP, new Vector3d(0, 0, 0), Hand.MAIN_HAND);
}
//blockState = blockState.getBlock().getStateForPlacement(player.world, pos, )
blockStates.add(blockState);
itemStacks.add(itemStack);
}
return blockStates;
}
public static boolean isEnabled(ArraySettings a) {
if (a == null || !a.enabled) return false;
return a.offset.getX() != 0 || a.offset.getY() != 0 || a.offset.getZ() != 0;
}
public static class ArraySettings {
public boolean enabled = false; public boolean enabled = false;
public BlockPos offset = BlockPos.ZERO; public BlockPos offset = BlockPos.ZERO;
public int count = 5; public int count = 5;
@@ -41,64 +101,4 @@ public class Array {
} }
} }
public static List<BlockPos> findCoordinates(PlayerEntity player, BlockPos startPos) {
List<BlockPos> coordinates = new ArrayList<>();
//find arraysettings for the player
ArraySettings a = ModifierSettingsManager.getModifierSettings(player).getArraySettings();
if (!isEnabled(a)) return coordinates;
BlockPos pos = startPos;
Vec3i offset = new Vec3i(a.offset.getX(), a.offset.getY(), a.offset.getZ());
for (int i = 0; i < a.count; i++) {
pos = pos.add(offset);
coordinates.add(pos);
}
return coordinates;
}
public static List<BlockState> findBlockStates(PlayerEntity player, BlockPos startPos, BlockState blockState, ItemStack itemStack, List<ItemStack> itemStacks) {
List<BlockState> blockStates = new ArrayList<>();
//find arraysettings for the player that placed the block
ArraySettings a = ModifierSettingsManager.getModifierSettings(player).getArraySettings();
if (!isEnabled(a)) return blockStates;
BlockPos pos = startPos;
Vec3i offset = new Vec3i(a.offset.getX(), a.offset.getY(), a.offset.getZ());
//Randomizer bag synergy
IItemHandler bagInventory = null;
if (!itemStack.isEmpty() && itemStack.getItem() instanceof ItemRandomizerBag) {
bagInventory = ItemRandomizerBag.getBagInventory(itemStack);
}
for (int i = 0; i < a.count; i++) {
pos = pos.add(offset);
//Randomizer bag synergy
if (bagInventory != null) {
itemStack = ItemRandomizerBag.pickRandomStack(bagInventory);
blockState = BuildModifiers
.getBlockStateFromItem(itemStack, player, startPos, Direction.UP, new Vec3d(0, 0, 0), Hand.MAIN_HAND);
}
//blockState = blockState.getBlock().getStateForPlacement(player.world, pos, )
blockStates.add(blockState);
itemStacks.add(itemStack);
}
return blockStates;
}
public static boolean isEnabled(ArraySettings a) {
if (a == null || !a.enabled) return false;
if (a.offset.getX() == 0 && a.offset.getY() == 0 && a.offset.getZ() == 0) return false;
return true;
}
} }

View File

@@ -2,19 +2,19 @@ package nl.requios.effortlessbuilding.buildmodifier;
import net.minecraft.block.BlockState; import net.minecraft.block.BlockState;
import net.minecraft.util.math.BlockPos; import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.Vec3d; import net.minecraft.util.math.vector.Vector3d;
import java.util.List; import java.util.List;
public class BlockSet { public class BlockSet {
private List<BlockPos> coordinates; private final List<BlockPos> coordinates;
private List<BlockState> previousBlockStates; private final List<BlockState> previousBlockStates;
private List<BlockState> newBlockStates; private final List<BlockState> newBlockStates;
private Vec3d hitVec; private final Vector3d hitVec;
private BlockPos firstPos; private final BlockPos firstPos;
private BlockPos secondPos; private final BlockPos secondPos;
public BlockSet(List<BlockPos> coordinates, List<BlockState> previousBlockStates, List<BlockState> newBlockStates, Vec3d hitVec, public BlockSet(List<BlockPos> coordinates, List<BlockState> previousBlockStates, List<BlockState> newBlockStates, Vector3d hitVec,
BlockPos firstPos, BlockPos secondPos) { BlockPos firstPos, BlockPos secondPos) {
this.coordinates = coordinates; this.coordinates = coordinates;
this.previousBlockStates = previousBlockStates; this.previousBlockStates = previousBlockStates;
@@ -36,7 +36,7 @@ public class BlockSet {
return newBlockStates; return newBlockStates;
} }
public Vec3d getHitVec() { public Vector3d getHitVec() {
return hitVec; return hitVec;
} }

View File

@@ -2,8 +2,8 @@ package nl.requios.effortlessbuilding.buildmodifier;
import net.minecraft.block.Block; import net.minecraft.block.Block;
import net.minecraft.block.BlockState; import net.minecraft.block.BlockState;
import net.minecraft.entity.player.PlayerEntity;
import net.minecraft.block.Blocks; import net.minecraft.block.Blocks;
import net.minecraft.entity.player.PlayerEntity;
import net.minecraft.item.BlockItem; import net.minecraft.item.BlockItem;
import net.minecraft.item.BlockItemUseContext; import net.minecraft.item.BlockItemUseContext;
import net.minecraft.item.ItemStack; import net.minecraft.item.ItemStack;
@@ -12,25 +12,27 @@ import net.minecraft.util.Direction;
import net.minecraft.util.Hand; import net.minecraft.util.Hand;
import net.minecraft.util.math.BlockPos; import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.BlockRayTraceResult; import net.minecraft.util.math.BlockRayTraceResult;
import net.minecraft.util.math.Vec3d; import net.minecraft.util.math.vector.Vector3d;
import net.minecraft.world.World; import net.minecraft.world.World;
import nl.requios.effortlessbuilding.compatibility.CompatHelper; import nl.requios.effortlessbuilding.compatibility.CompatHelper;
import nl.requios.effortlessbuilding.helper.InventoryHelper; import nl.requios.effortlessbuilding.helper.InventoryHelper;
import nl.requios.effortlessbuilding.helper.SurvivalHelper; import nl.requios.effortlessbuilding.helper.SurvivalHelper;
import nl.requios.effortlessbuilding.item.ItemRandomizerBag; import nl.requios.effortlessbuilding.item.AbstractRandomizerBagItem;
import nl.requios.effortlessbuilding.render.BlockPreviewRenderer; import nl.requios.effortlessbuilding.render.BlockPreviewRenderer;
import java.util.*; import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
public class BuildModifiers { public class BuildModifiers {
//Called from BuildModes //Called from BuildModes
public static void onBlockPlaced(PlayerEntity player, List<BlockPos> startCoordinates, Direction sideHit, Vec3d hitVec, boolean placeStartPos) { public static void onBlockPlaced(PlayerEntity player, List<BlockPos> startCoordinates, Direction sideHit, Vector3d hitVec, boolean placeStartPos) {
World world = player.world; World world = player.level;
ItemRandomizerBag.renewRandomness(); AbstractRandomizerBagItem.renewRandomness();
//Format hitvec to 0.x //Format hitvec to 0.x
hitVec = new Vec3d(Math.abs(hitVec.x - ((int) hitVec.x)), Math.abs(hitVec.y - ((int) hitVec.y)), Math.abs(hitVec.z - ((int) hitVec.z))); hitVec = new Vector3d(Math.abs(hitVec.x - ((int) hitVec.x)), Math.abs(hitVec.y - ((int) hitVec.y)), Math.abs(hitVec.z - ((int) hitVec.z)));
//find coordinates and blockstates //find coordinates and blockstates
List<BlockPos> coordinates = findCoordinates(player, startCoordinates); List<BlockPos> coordinates = findCoordinates(player, startCoordinates);
@@ -47,7 +49,7 @@ public class BuildModifiers {
previousBlockStates.add(world.getBlockState(coordinate)); previousBlockStates.add(world.getBlockState(coordinate));
} }
if (world.isRemote) { if (world.isClientSide) {
BlockPreviewRenderer.onBlocksPlaced(); BlockPreviewRenderer.onBlocksPlaced();
@@ -61,7 +63,7 @@ public class BuildModifiers {
BlockState blockState = blockStates.get(i); BlockState blockState = blockStates.get(i);
ItemStack itemStack = itemStacks.get(i); ItemStack itemStack = itemStacks.get(i);
if (world.isBlockPresent(blockPos)) { if (world.isLoaded(blockPos)) {
//check itemstack empty //check itemstack empty
if (itemStack.isEmpty()) { if (itemStack.isEmpty()) {
//try to find new stack, otherwise continue //try to find new stack, otherwise continue
@@ -80,11 +82,11 @@ public class BuildModifiers {
//Set first previousBlockState to empty if in NORMAL mode, to make undo/redo work //Set first previousBlockState to empty if in NORMAL mode, to make undo/redo work
//(Block is placed by the time it gets here, and unplaced after this) //(Block is placed by the time it gets here, and unplaced after this)
if (!placeStartPos) previousBlockStates.set(0, Blocks.AIR.getDefaultState()); if (!placeStartPos) previousBlockStates.set(0, Blocks.AIR.defaultBlockState());
//If all new blockstates are air then no use in adding it, no block was actually placed //If all new blockstates are air then no use in adding it, no block was actually placed
//Can happen when e.g. placing one block in yourself //Can happen when e.g. placing one block in yourself
if (Collections.frequency(newBlockStates, Blocks.AIR.getDefaultState()) != newBlockStates.size()) { if (Collections.frequency(newBlockStates, Blocks.AIR.defaultBlockState()) != newBlockStates.size()) {
//add to undo stack //add to undo stack
BlockPos firstPos = startCoordinates.get(0); BlockPos firstPos = startCoordinates.get(0);
BlockPos secondPos = startCoordinates.get(startCoordinates.size() - 1); BlockPos secondPos = startCoordinates.get(startCoordinates.size() - 1);
@@ -93,7 +95,7 @@ public class BuildModifiers {
} }
public static void onBlockBroken(PlayerEntity player, List<BlockPos> startCoordinates, boolean breakStartPos) { public static void onBlockBroken(PlayerEntity player, List<BlockPos> startCoordinates, boolean breakStartPos) {
World world = player.world; World world = player.level;
List<BlockPos> coordinates = findCoordinates(player, startCoordinates); List<BlockPos> coordinates = findCoordinates(player, startCoordinates);
@@ -106,25 +108,25 @@ public class BuildModifiers {
previousBlockStates.add(world.getBlockState(coordinate)); previousBlockStates.add(world.getBlockState(coordinate));
} }
if (world.isRemote) { if (world.isClientSide) {
BlockPreviewRenderer.onBlocksBroken(); BlockPreviewRenderer.onBlocksBroken();
//list of air blockstates //list of air blockstates
for (int i = 0; i < coordinates.size(); i++) { for (int i = 0; i < coordinates.size(); i++) {
newBlockStates.add(Blocks.AIR.getDefaultState()); newBlockStates.add(Blocks.AIR.defaultBlockState());
} }
} else { } else {
//If the player is going to instabreak grass or a plant, only break other instabreaking things //If the player is going to instabreak grass or a plant, only break other instabreaking things
boolean onlyInstaBreaking = !player.isCreative() && boolean onlyInstaBreaking = !player.isCreative() &&
world.getBlockState(startCoordinates.get(0)).getBlockHardness(world, startCoordinates.get(0)) == 0f; world.getBlockState(startCoordinates.get(0)).getDestroySpeed(world, startCoordinates.get(0)) == 0f;
//break all those blocks //break all those blocks
for (int i = breakStartPos ? 0 : 1; i < coordinates.size(); i++) { for (int i = breakStartPos ? 0 : 1; i < coordinates.size(); i++) {
BlockPos coordinate = coordinates.get(i); BlockPos coordinate = coordinates.get(i);
if (world.isBlockPresent(coordinate) && !world.isAirBlock(coordinate)) { if (world.isLoaded(coordinate) && !world.isEmptyBlock(coordinate)) {
if (!onlyInstaBreaking || world.getBlockState(coordinate).getBlockHardness(world, coordinate) == 0f) { if (!onlyInstaBreaking || world.getBlockState(coordinate).getDestroySpeed(world, coordinate) == 0f) {
SurvivalHelper.breakBlock(world, player, coordinate, false); SurvivalHelper.breakBlock(world, player, coordinate, false);
} }
} }
@@ -138,12 +140,12 @@ public class BuildModifiers {
//Set first newBlockState to empty if in NORMAL mode, to make undo/redo work //Set first newBlockState to empty if in NORMAL mode, to make undo/redo work
//(Block isn't broken yet by the time it gets here, and broken after this) //(Block isn't broken yet by the time it gets here, and broken after this)
if (!breakStartPos) newBlockStates.set(0, Blocks.AIR.getDefaultState()); if (!breakStartPos) newBlockStates.set(0, Blocks.AIR.defaultBlockState());
//add to undo stack //add to undo stack
BlockPos firstPos = startCoordinates.get(0); BlockPos firstPos = startCoordinates.get(0);
BlockPos secondPos = startCoordinates.get(startCoordinates.size() - 1); BlockPos secondPos = startCoordinates.get(startCoordinates.size() - 1);
Vec3d hitVec = new Vec3d(0.5, 0.5, 0.5); Vector3d hitVec = new Vector3d(0.5, 0.5, 0.5);
UndoRedo.addUndo(player, new BlockSet(coordinates, previousBlockStates, newBlockStates, hitVec, firstPos, secondPos)); UndoRedo.addUndo(player, new BlockSet(coordinates, previousBlockStates, newBlockStates, hitVec, firstPos, secondPos));
} }
@@ -170,17 +172,17 @@ public class BuildModifiers {
} }
public static List<BlockPos> findCoordinates(PlayerEntity player, BlockPos blockPos) { public static List<BlockPos> findCoordinates(PlayerEntity player, BlockPos blockPos) {
return findCoordinates(player, new ArrayList<>(Arrays.asList(blockPos))); return findCoordinates(player, new ArrayList<>(Collections.singletonList(blockPos)));
} }
public static List<BlockState> findBlockStates(PlayerEntity player, List<BlockPos> posList, Vec3d hitVec, Direction facing, List<ItemStack> itemStacks) { public static List<BlockState> findBlockStates(PlayerEntity player, List<BlockPos> posList, Vector3d hitVec, Direction facing, List<ItemStack> itemStacks) {
List<BlockState> blockStates = new ArrayList<>(); List<BlockState> blockStates = new ArrayList<>();
itemStacks.clear(); itemStacks.clear();
//Get itemstack //Get itemstack
ItemStack itemStack = player.getHeldItem(Hand.MAIN_HAND); ItemStack itemStack = player.getItemInHand(Hand.MAIN_HAND);
if (itemStack.isEmpty() || !CompatHelper.isItemBlockProxy(itemStack)) { if (itemStack.isEmpty() || !CompatHelper.isItemBlockProxy(itemStack)) {
itemStack = player.getHeldItem(Hand.OFF_HAND); itemStack = player.getItemInHand(Hand.OFF_HAND);
} }
if (itemStack.isEmpty() || !CompatHelper.isItemBlockProxy(itemStack)) { if (itemStack.isEmpty() || !CompatHelper.isItemBlockProxy(itemStack)) {
return blockStates; return blockStates;
@@ -190,7 +192,7 @@ public class BuildModifiers {
ItemStack itemBlock = ItemStack.EMPTY; ItemStack itemBlock = ItemStack.EMPTY;
if (itemStack.getItem() instanceof BlockItem) itemBlock = itemStack; if (itemStack.getItem() instanceof BlockItem) itemBlock = itemStack;
else itemBlock = CompatHelper.getItemBlockFromStack(itemStack); else itemBlock = CompatHelper.getItemBlockFromStack(itemStack);
ItemRandomizerBag.resetRandomness(); AbstractRandomizerBagItem.resetRandomness();
//Add blocks in posList first //Add blocks in posList first
for (BlockPos blockPos : posList) { for (BlockPos blockPos : posList) {
@@ -236,8 +238,8 @@ public class BuildModifiers {
modifierSettings.doQuickReplace(); modifierSettings.doQuickReplace();
} }
public static BlockState getBlockStateFromItem(ItemStack itemStack, PlayerEntity player, BlockPos blockPos, Direction facing, Vec3d hitVec, Hand hand) { public static BlockState getBlockStateFromItem(ItemStack itemStack, PlayerEntity player, BlockPos blockPos, Direction facing, Vector3d hitVec, Hand hand) {
return Block.getBlockFromItem(itemStack.getItem()).getStateForPlacement(new BlockItemUseContext(new ItemUseContext(player, hand, new BlockRayTraceResult(hitVec, facing, blockPos, false)))); return Block.byItem(itemStack.getItem()).getStateForPlacement(new BlockItemUseContext(new ItemUseContext(player, hand, new BlockRayTraceResult(hitVec, facing, blockPos, false))));
} }
//Returns true if equal (or both null) //Returns true if equal (or both null)
@@ -246,8 +248,8 @@ public class BuildModifiers {
if (coordinates1 == null || coordinates2 == null) return false; if (coordinates1 == null || coordinates2 == null) return false;
//Check count, not actual values //Check count, not actual values
if (coordinates1.size() == coordinates2.size()){ if (coordinates1.size() == coordinates2.size()) {
if (coordinates1.size() == 1){ if (coordinates1.size() == 1) {
return coordinates1.get(0).equals(coordinates2.get(0)); return coordinates1.get(0).equals(coordinates2.get(0));
} }
return true; return true;

View File

@@ -1,10 +1,6 @@
package nl.requios.effortlessbuilding.buildmodifier; package nl.requios.effortlessbuilding.buildmodifier;
import net.minecraft.block.*; import net.minecraft.block.*;
import net.minecraft.block.StairsBlock;
import net.minecraft.block.DirectionalBlock;
import net.minecraft.block.SlabBlock;
import net.minecraft.block.BlockState;
import net.minecraft.entity.player.PlayerEntity; import net.minecraft.entity.player.PlayerEntity;
import net.minecraft.item.ItemStack; import net.minecraft.item.ItemStack;
import net.minecraft.state.properties.Half; import net.minecraft.state.properties.Half;
@@ -12,41 +8,15 @@ import net.minecraft.state.properties.SlabType;
import net.minecraft.util.Direction; import net.minecraft.util.Direction;
import net.minecraft.util.Hand; import net.minecraft.util.Hand;
import net.minecraft.util.math.BlockPos; import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.Vec3d; import net.minecraft.util.math.vector.Vector3d;
import net.minecraftforge.items.IItemHandler; import net.minecraftforge.items.IItemHandler;
import nl.requios.effortlessbuilding.item.ItemRandomizerBag; import nl.requios.effortlessbuilding.item.AbstractRandomizerBagItem;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
public class Mirror { public class Mirror {
public static class MirrorSettings {
public boolean enabled = false;
public Vec3d position = new Vec3d(0.5, 64.5, 0.5);
public boolean mirrorX = true, mirrorY = false, mirrorZ = false;
public int radius = 10;
public boolean drawLines = true, drawPlanes = true;
public MirrorSettings() {
}
public MirrorSettings(boolean mirrorEnabled, Vec3d position, boolean mirrorX, boolean mirrorY, boolean mirrorZ, int radius, boolean drawLines, boolean drawPlanes) {
this.enabled = mirrorEnabled;
this.position = position;
this.mirrorX = mirrorX;
this.mirrorY = mirrorY;
this.mirrorZ = mirrorZ;
this.radius = radius;
this.drawLines = drawLines;
this.drawPlanes = drawPlanes;
}
public int getReach() {
return radius * 2; //Change ModifierSettings#setReachUpgrade too
}
}
public static List<BlockPos> findCoordinates(PlayerEntity player, BlockPos startPos) { public static List<BlockPos> findCoordinates(PlayerEntity player, BlockPos startPos) {
List<BlockPos> coordinates = new ArrayList<>(); List<BlockPos> coordinates = new ArrayList<>();
@@ -95,14 +65,19 @@ public class Mirror {
if (!isEnabled(m, startPos)) return blockStates; if (!isEnabled(m, startPos)) return blockStates;
//Randomizer bag synergy //Randomizer bag synergy
AbstractRandomizerBagItem randomizerBagItem = null;
IItemHandler bagInventory = null; IItemHandler bagInventory = null;
if (!itemStack.isEmpty() && itemStack.getItem() instanceof ItemRandomizerBag) { if (!itemStack.isEmpty() && itemStack.getItem() instanceof AbstractRandomizerBagItem) {
bagInventory = ItemRandomizerBag.getBagInventory(itemStack); randomizerBagItem = (AbstractRandomizerBagItem) itemStack.getItem();
bagInventory = randomizerBagItem.getBagInventory(itemStack);
} }
if (m.mirrorX) blockStateMirrorX(player, m, startPos, blockState, bagInventory, itemStack, Hand.MAIN_HAND, blockStates, itemStacks); if (m.mirrorX)
if (m.mirrorY) blockStateMirrorY(player, m, startPos, blockState, bagInventory, itemStack, Hand.MAIN_HAND, blockStates, itemStacks); blockStateMirrorX(player, m, startPos, blockState, bagInventory, itemStack, Hand.MAIN_HAND, blockStates, itemStacks);
if (m.mirrorZ) blockStateMirrorZ(player, m, startPos, blockState, bagInventory, itemStack, Hand.MAIN_HAND, blockStates, itemStacks); if (m.mirrorY)
blockStateMirrorY(player, m, startPos, blockState, bagInventory, itemStack, Hand.MAIN_HAND, blockStates, itemStacks);
if (m.mirrorZ)
blockStateMirrorZ(player, m, startPos, blockState, bagInventory, itemStack, Hand.MAIN_HAND, blockStates, itemStacks);
return blockStates; return blockStates;
} }
@@ -115,8 +90,8 @@ public class Mirror {
//Randomizer bag synergy //Randomizer bag synergy
if (bagInventory != null) { if (bagInventory != null) {
itemStack = ItemRandomizerBag.pickRandomStack(bagInventory); itemStack = ((AbstractRandomizerBagItem)itemStack.getItem()).pickRandomStack(bagInventory);
oldBlockState = BuildModifiers.getBlockStateFromItem(itemStack, player, oldBlockPos, Direction.UP, new Vec3d(0, 0, 0), hand); oldBlockState = BuildModifiers.getBlockStateFromItem(itemStack, player, oldBlockPos, Direction.UP, new Vector3d(0, 0, 0), hand);
} }
//Find blockstate //Find blockstate
@@ -126,8 +101,10 @@ public class Mirror {
blockStates.add(newBlockState); blockStates.add(newBlockState);
itemStacks.add(itemStack); itemStacks.add(itemStack);
if (m.mirrorY) blockStateMirrorY(player, m, newBlockPos, newBlockState, bagInventory, itemStack, hand, blockStates, itemStacks); if (m.mirrorY)
if (m.mirrorZ) blockStateMirrorZ(player, m, newBlockPos, newBlockState, bagInventory, itemStack, hand, blockStates, itemStacks); blockStateMirrorY(player, m, newBlockPos, newBlockState, bagInventory, itemStack, hand, blockStates, itemStacks);
if (m.mirrorZ)
blockStateMirrorZ(player, m, newBlockPos, newBlockState, bagInventory, itemStack, hand, blockStates, itemStacks);
} }
private static void blockStateMirrorY(PlayerEntity player, MirrorSettings m, BlockPos oldBlockPos, BlockState oldBlockState, private static void blockStateMirrorY(PlayerEntity player, MirrorSettings m, BlockPos oldBlockPos, BlockState oldBlockState,
@@ -138,8 +115,8 @@ public class Mirror {
//Randomizer bag synergy //Randomizer bag synergy
if (bagInventory != null) { if (bagInventory != null) {
itemStack = ItemRandomizerBag.pickRandomStack(bagInventory); itemStack = ((AbstractRandomizerBagItem)itemStack.getItem()).pickRandomStack(bagInventory);
oldBlockState = BuildModifiers.getBlockStateFromItem(itemStack, player, oldBlockPos, Direction.UP, new Vec3d(0, 0, 0), hand); oldBlockState = BuildModifiers.getBlockStateFromItem(itemStack, player, oldBlockPos, Direction.UP, new Vector3d(0, 0, 0), hand);
} }
//Find blockstate //Find blockstate
@@ -149,7 +126,8 @@ public class Mirror {
blockStates.add(newBlockState); blockStates.add(newBlockState);
itemStacks.add(itemStack); itemStacks.add(itemStack);
if (m.mirrorZ) blockStateMirrorZ(player, m, newBlockPos, newBlockState, bagInventory, itemStack, hand, blockStates, itemStacks); if (m.mirrorZ)
blockStateMirrorZ(player, m, newBlockPos, newBlockState, bagInventory, itemStack, hand, blockStates, itemStacks);
} }
private static void blockStateMirrorZ(PlayerEntity player, MirrorSettings m, BlockPos oldBlockPos, BlockState oldBlockState, private static void blockStateMirrorZ(PlayerEntity player, MirrorSettings m, BlockPos oldBlockPos, BlockState oldBlockState,
@@ -160,8 +138,8 @@ public class Mirror {
//Randomizer bag synergy //Randomizer bag synergy
if (bagInventory != null) { if (bagInventory != null) {
itemStack = ItemRandomizerBag.pickRandomStack(bagInventory); itemStack = ((AbstractRandomizerBagItem)itemStack.getItem()).pickRandomStack(bagInventory);
oldBlockState = BuildModifiers.getBlockStateFromItem(itemStack, player, oldBlockPos, Direction.UP, new Vec3d(0, 0, 0), hand); oldBlockState = BuildModifiers.getBlockStateFromItem(itemStack, player, oldBlockPos, Direction.UP, new Vector3d(0, 0, 0), hand);
} }
//Find blockstate //Find blockstate
@@ -176,53 +154,76 @@ public class Mirror {
if (m == null || !m.enabled || (!m.mirrorX && !m.mirrorY && !m.mirrorZ)) return false; if (m == null || !m.enabled || (!m.mirrorX && !m.mirrorY && !m.mirrorZ)) return false;
//within mirror distance //within mirror distance
if (startPos.getX() + 0.5 < m.position.x - m.radius || startPos.getX() + 0.5 > m.position.x + m.radius || return !(startPos.getX() + 0.5 < m.position.x - m.radius) && !(startPos.getX() + 0.5 > m.position.x + m.radius) &&
startPos.getY() + 0.5 < m.position.y - m.radius || startPos.getY() + 0.5 > m.position.y + m.radius || !(startPos.getY() + 0.5 < m.position.y - m.radius) && !(startPos.getY() + 0.5 > m.position.y + m.radius) &&
startPos.getZ() + 0.5 < m.position.z - m.radius || startPos.getZ() + 0.5 > m.position.z + m.radius) !(startPos.getZ() + 0.5 < m.position.z - m.radius) && !(startPos.getZ() + 0.5 > m.position.z + m.radius);
return false;
return true;
} }
private static BlockState getVerticalMirror(BlockState blockState) { private static BlockState getVerticalMirror(BlockState blockState) {
//Stairs //Stairs
if (blockState.getBlock() instanceof StairsBlock) { if (blockState.getBlock() instanceof StairsBlock) {
if (blockState.get(StairsBlock.HALF) == Half.BOTTOM) { if (blockState.getValue(StairsBlock.HALF) == Half.BOTTOM) {
return blockState.with(StairsBlock.HALF, Half.TOP); return blockState.setValue(StairsBlock.HALF, Half.TOP);
} else { } else {
return blockState.with(StairsBlock.HALF, Half.BOTTOM); return blockState.setValue(StairsBlock.HALF, Half.BOTTOM);
} }
} }
//Slabs //Slabs
if (blockState.getBlock() instanceof SlabBlock) { if (blockState.getBlock() instanceof SlabBlock) {
if (blockState.get(SlabBlock.TYPE) == SlabType.DOUBLE) { if (blockState.getValue(SlabBlock.TYPE) == SlabType.DOUBLE) {
return blockState; return blockState;
} else if (blockState.get(SlabBlock.TYPE) == SlabType.BOTTOM) { } else if (blockState.getValue(SlabBlock.TYPE) == SlabType.BOTTOM) {
return blockState.with(SlabBlock.TYPE, SlabType.TOP); return blockState.setValue(SlabBlock.TYPE, SlabType.TOP);
} else { } else {
return blockState.with(SlabBlock.TYPE, SlabType.BOTTOM); return blockState.setValue(SlabBlock.TYPE, SlabType.BOTTOM);
} }
} }
//Buttons, endrod, observer, piston //Buttons, endrod, observer, piston
if (blockState.getBlock() instanceof DirectionalBlock) { if (blockState.getBlock() instanceof DirectionalBlock) {
if (blockState.get(DirectionalBlock.FACING) == Direction.DOWN) { if (blockState.getValue(DirectionalBlock.FACING) == Direction.DOWN) {
return blockState.with(DirectionalBlock.FACING, Direction.UP); return blockState.setValue(DirectionalBlock.FACING, Direction.UP);
} else if (blockState.get(DirectionalBlock.FACING) == Direction.UP) { } else if (blockState.getValue(DirectionalBlock.FACING) == Direction.UP) {
return blockState.with(DirectionalBlock.FACING, Direction.DOWN); return blockState.setValue(DirectionalBlock.FACING, Direction.DOWN);
} }
} }
//Dispenser, dropper //Dispenser, dropper
if (blockState.getBlock() instanceof DispenserBlock) { if (blockState.getBlock() instanceof DispenserBlock) {
if (blockState.get(DispenserBlock.FACING) == Direction.DOWN) { if (blockState.getValue(DispenserBlock.FACING) == Direction.DOWN) {
return blockState.with(DispenserBlock.FACING, Direction.UP); return blockState.setValue(DispenserBlock.FACING, Direction.UP);
} else if (blockState.get(DispenserBlock.FACING) == Direction.UP) { } else if (blockState.getValue(DispenserBlock.FACING) == Direction.UP) {
return blockState.with(DispenserBlock.FACING, Direction.DOWN); return blockState.setValue(DispenserBlock.FACING, Direction.DOWN);
} }
} }
return blockState; return blockState;
} }
public static class MirrorSettings {
public boolean enabled = false;
public Vector3d position = new Vector3d(0.5, 64.5, 0.5);
public boolean mirrorX = true, mirrorY = false, mirrorZ = false;
public int radius = 10;
public boolean drawLines = true, drawPlanes = true;
public MirrorSettings() {
}
public MirrorSettings(boolean mirrorEnabled, Vector3d position, boolean mirrorX, boolean mirrorY, boolean mirrorZ, int radius, boolean drawLines, boolean drawPlanes) {
this.enabled = mirrorEnabled;
this.position = position;
this.mirrorX = mirrorX;
this.mirrorY = mirrorY;
this.mirrorZ = mirrorZ;
this.radius = radius;
this.drawLines = drawLines;
this.drawPlanes = drawPlanes;
}
public int getReach() {
return radius * 2; //Change ModifierSettings#setReachUpgrade too
}
}
} }

View File

@@ -20,7 +20,7 @@ public class ModifierSettingsManager {
//Retrieves the buildsettings of a player through the modifierCapability capability //Retrieves the buildsettings of a player through the modifierCapability capability
//Never returns null //Never returns null
@Nonnull @Nonnull
public static ModifierSettings getModifierSettings(PlayerEntity player){ public static ModifierSettings getModifierSettings(PlayerEntity player) {
LazyOptional<ModifierCapabilityManager.IModifierCapability> modifierCapability = LazyOptional<ModifierCapabilityManager.IModifierCapability> modifierCapability =
player.getCapability(ModifierCapabilityManager.modifierCapability, null); player.getCapability(ModifierCapabilityManager.modifierCapability, null);
@@ -68,7 +68,7 @@ public class ModifierSettingsManager {
} }
if (m.getReach() > maxReach) { if (m.getReach() > maxReach) {
m.radius = maxReach / 2; m.radius = maxReach / 2;
error += "Mirror exceeds your maximum reach of " + (maxReach / 2) + ". Radius has been set to "+ (maxReach / 2) + ". "; error += "Mirror exceeds your maximum reach of " + (maxReach / 2) + ". Radius has been set to " + (maxReach / 2) + ". ";
} }
//Array settings //Array settings
@@ -96,7 +96,7 @@ public class ModifierSettingsManager {
} }
if (r.getReach() > maxReach) { if (r.getReach() > maxReach) {
r.radius = maxReach / 2; r.radius = maxReach / 2;
error += "Radial mirror exceeds your maximum reach of " + (maxReach / 2) + ". Radius has been set to "+ (maxReach / 2) + ". "; error += "Radial mirror exceeds your maximum reach of " + (maxReach / 2) + ". Radius has been set to " + (maxReach / 2) + ". ";
} }
//Other //Other
@@ -110,6 +110,18 @@ public class ModifierSettingsManager {
return error; return error;
} }
public static void handleNewPlayer(PlayerEntity player) {
//Makes sure player has modifier settings (if it doesnt it will create it)
getModifierSettings(player);
//Only on server
if (!player.level.isClientSide) {
//Send to client
ModifierSettingsMessage msg = new ModifierSettingsMessage(getModifierSettings(player));
PacketHandler.INSTANCE.send(PacketDistributor.PLAYER.with(() -> (ServerPlayerEntity) player), msg);
}
}
public static class ModifierSettings { public static class ModifierSettings {
private Mirror.MirrorSettings mirrorSettings; private Mirror.MirrorSettings mirrorSettings;
private Array.ArraySettings arraySettings; private Array.ArraySettings arraySettings;
@@ -179,10 +191,18 @@ public class ModifierSettingsManager {
//Set mirror radius to max //Set mirror radius to max
int reach = 10; int reach = 10;
switch (reachUpgrade) { switch (reachUpgrade) {
case 0: reach = BuildConfig.reach.maxReachLevel0.get(); break; case 0:
case 1: reach = BuildConfig.reach.maxReachLevel1.get(); break; reach = BuildConfig.reach.maxReachLevel0.get();
case 2: reach = BuildConfig.reach.maxReachLevel2.get(); break; break;
case 3: reach = BuildConfig.reach.maxReachLevel3.get(); break; case 1:
reach = BuildConfig.reach.maxReachLevel1.get();
break;
case 2:
reach = BuildConfig.reach.maxReachLevel2.get();
break;
case 3:
reach = BuildConfig.reach.maxReachLevel3.get();
break;
} }
if (this.mirrorSettings != null) if (this.mirrorSettings != null)
@@ -191,17 +211,5 @@ public class ModifierSettingsManager {
this.radialMirrorSettings.radius = reach / 2; this.radialMirrorSettings.radius = reach / 2;
} }
} }
public static void handleNewPlayer(PlayerEntity player){
//Makes sure player has modifier settings (if it doesnt it will create it)
getModifierSettings(player);
//Only on server
if (!player.world.isRemote) {
//Send to client
ModifierSettingsMessage msg = new ModifierSettingsMessage(getModifierSettings(player));
PacketHandler.INSTANCE.send(PacketDistributor.PLAYER.with(() -> (ServerPlayerEntity) player), msg);
}
}
} }

View File

@@ -9,41 +9,15 @@ import net.minecraft.util.Mirror;
import net.minecraft.util.Rotation; import net.minecraft.util.Rotation;
import net.minecraft.util.math.BlockPos; import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.MathHelper; import net.minecraft.util.math.MathHelper;
import net.minecraft.util.math.Vec3d; import net.minecraft.util.math.vector.Vector3d;
import net.minecraftforge.items.IItemHandler; import net.minecraftforge.items.IItemHandler;
import nl.requios.effortlessbuilding.item.ItemRandomizerBag; import nl.requios.effortlessbuilding.item.AbstractRandomizerBagItem;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
public class RadialMirror { public class RadialMirror {
public static class RadialMirrorSettings {
public boolean enabled = false;
public Vec3d position = new Vec3d(0.5, 64.5, 0.5);
public int slices = 4;
public boolean alternate = false;
public int radius = 20;
public boolean drawLines = true, drawPlanes = false;
public RadialMirrorSettings() {
}
public RadialMirrorSettings(boolean enabled, Vec3d position, int slices, boolean alternate, int radius, boolean drawLines, boolean drawPlanes) {
this.enabled = enabled;
this.position = position;
this.slices = slices;
this.alternate = alternate;
this.radius = radius;
this.drawLines = drawLines;
this.drawPlanes = drawPlanes;
}
public int getReach() {
return radius * 2;
}
}
public static List<BlockPos> findCoordinates(PlayerEntity player, BlockPos startPos) { public static List<BlockPos> findCoordinates(PlayerEntity player, BlockPos startPos) {
List<BlockPos> coordinates = new ArrayList<>(); List<BlockPos> coordinates = new ArrayList<>();
@@ -54,8 +28,8 @@ public class RadialMirror {
//get angle between slices //get angle between slices
double sliceAngle = 2 * Math.PI / r.slices; double sliceAngle = 2 * Math.PI / r.slices;
Vec3d startVec = new Vec3d(startPos.getX() + 0.5f, startPos.getY() + 0.5f, startPos.getZ() + 0.5f); Vector3d startVec = new Vector3d(startPos.getX() + 0.5f, startPos.getY() + 0.5f, startPos.getZ() + 0.5f);
Vec3d relStartVec = startVec.subtract(r.position); Vector3d relStartVec = startVec.subtract(r.position);
double startAngleToCenter = MathHelper.atan2(relStartVec.x, relStartVec.z); double startAngleToCenter = MathHelper.atan2(relStartVec.x, relStartVec.z);
if (startAngleToCenter < 0) startAngleToCenter += Math.PI; if (startAngleToCenter < 0) startAngleToCenter += Math.PI;
@@ -65,11 +39,11 @@ public class RadialMirror {
double curAngle = sliceAngle * i; double curAngle = sliceAngle * i;
//alternate mirroring of slices //alternate mirroring of slices
if (r.alternate && i%2 == 1) { if (r.alternate && i % 2 == 1) {
curAngle = curAngle - startAngleInSlice + (sliceAngle - startAngleInSlice); curAngle = curAngle - startAngleInSlice + (sliceAngle - startAngleInSlice);
} }
Vec3d relNewVec = relStartVec.rotateYaw((float) curAngle); Vector3d relNewVec = relStartVec.yRot((float) curAngle);
BlockPos newBlockPos = new BlockPos(r.position.add(relNewVec)); BlockPos newBlockPos = new BlockPos(r.position.add(relNewVec));
if (!coordinates.contains(newBlockPos) && !newBlockPos.equals(startPos)) coordinates.add(newBlockPos); if (!coordinates.contains(newBlockPos) && !newBlockPos.equals(startPos)) coordinates.add(newBlockPos);
} }
@@ -89,8 +63,8 @@ public class RadialMirror {
//get angle between slices //get angle between slices
double sliceAngle = 2 * Math.PI / r.slices; double sliceAngle = 2 * Math.PI / r.slices;
Vec3d startVec = new Vec3d(startPos.getX() + 0.5f, startPos.getY() + 0.5f, startPos.getZ() + 0.5f); Vector3d startVec = new Vector3d(startPos.getX() + 0.5f, startPos.getY() + 0.5f, startPos.getZ() + 0.5f);
Vec3d relStartVec = startVec.subtract(r.position); Vector3d relStartVec = startVec.subtract(r.position);
double startAngleToCenter = MathHelper.atan2(relStartVec.x, relStartVec.z); double startAngleToCenter = MathHelper.atan2(relStartVec.x, relStartVec.z);
double startAngleToCenterMod = startAngleToCenter < 0 ? startAngleToCenter + Math.PI : startAngleToCenter; double startAngleToCenterMod = startAngleToCenter < 0 ? startAngleToCenter + Math.PI : startAngleToCenter;
@@ -100,9 +74,11 @@ public class RadialMirror {
blockState = rotateOriginalBlockState(startAngleToCenter, blockState); blockState = rotateOriginalBlockState(startAngleToCenter, blockState);
//Randomizer bag synergy //Randomizer bag synergy
AbstractRandomizerBagItem randomizerBagItem = null;
IItemHandler bagInventory = null; IItemHandler bagInventory = null;
if (!itemStack.isEmpty() && itemStack.getItem() instanceof ItemRandomizerBag) { if (!itemStack.isEmpty() && itemStack.getItem() instanceof AbstractRandomizerBagItem) {
bagInventory = ItemRandomizerBag.getBagInventory(itemStack); randomizerBagItem = (AbstractRandomizerBagItem) itemStack.getItem();
bagInventory = randomizerBagItem.getBagInventory(itemStack);
} }
BlockState newBlockState; BlockState newBlockState;
@@ -111,26 +87,26 @@ public class RadialMirror {
double curAngle = sliceAngle * i; double curAngle = sliceAngle * i;
//alternate mirroring of slices //alternate mirroring of slices
if (r.alternate && i%2 == 1) { if (r.alternate && i % 2 == 1) {
curAngle = curAngle - startAngleInSlice + (sliceAngle - startAngleInSlice); curAngle = curAngle - startAngleInSlice + (sliceAngle - startAngleInSlice);
} }
Vec3d relNewVec = relStartVec.rotateYaw((float) curAngle); Vector3d relNewVec = relStartVec.yRot((float) curAngle);
BlockPos newBlockPos = new BlockPos(r.position.add(relNewVec)); BlockPos newBlockPos = new BlockPos(r.position.add(relNewVec));
if (coordinates.contains(newBlockPos) || newBlockPos.equals(startPos)) continue; //filter out duplicates if (coordinates.contains(newBlockPos) || newBlockPos.equals(startPos)) continue; //filter out duplicates
coordinates.add(newBlockPos); coordinates.add(newBlockPos);
//Randomizer bag synergy //Randomizer bag synergy
if (bagInventory != null) { if (bagInventory != null) {
itemStack = ItemRandomizerBag.pickRandomStack(bagInventory); itemStack = randomizerBagItem.pickRandomStack(bagInventory);
newBlockState = BuildModifiers newBlockState = BuildModifiers
.getBlockStateFromItem(itemStack, player, startPos, Direction.UP, new Vec3d(0, 0, 0), Hand.MAIN_HAND); .getBlockStateFromItem(itemStack, player, startPos, Direction.UP, new Vector3d(0, 0, 0), Hand.MAIN_HAND);
newBlockState = rotateOriginalBlockState(startAngleToCenter, newBlockState); newBlockState = rotateOriginalBlockState(startAngleToCenter, newBlockState);
} }
//rotate //rotate
newBlockState = rotateBlockState(relNewVec, newBlockState, r.alternate && i%2 == 1); newBlockState = rotateBlockState(relNewVec, newBlockState, r.alternate && i % 2 == 1);
blockStates.add(newBlockState); blockStates.add(newBlockState);
itemStacks.add(itemStack); itemStacks.add(itemStack);
@@ -153,7 +129,7 @@ public class RadialMirror {
return newBlockState; return newBlockState;
} }
private static BlockState rotateBlockState(Vec3d relVec, BlockState blockState, boolean alternate) { private static BlockState rotateBlockState(Vector3d relVec, BlockState blockState, boolean alternate) {
BlockState newBlockState; BlockState newBlockState;
double angleToCenter = MathHelper.atan2(relVec.x, relVec.z); //between -PI and PI double angleToCenter = MathHelper.atan2(relVec.x, relVec.z); //between -PI and PI
@@ -185,11 +161,34 @@ public class RadialMirror {
public static boolean isEnabled(RadialMirrorSettings r, BlockPos startPos) { public static boolean isEnabled(RadialMirrorSettings r, BlockPos startPos) {
if (r == null || !r.enabled) return false; if (r == null || !r.enabled) return false;
if (new Vec3d(startPos.getX() + 0.5, startPos.getY() + 0.5, startPos.getZ() + 0.5).subtract(r.position).lengthSquared() > return !(new Vector3d(startPos.getX() + 0.5, startPos.getY() + 0.5, startPos.getZ() + 0.5).subtract(r.position).lengthSqr() >
r.radius * r.radius) r.radius * r.radius);
return false; }
return true; public static class RadialMirrorSettings {
public boolean enabled = false;
public Vector3d position = new Vector3d(0.5, 64.5, 0.5);
public int slices = 4;
public boolean alternate = false;
public int radius = 20;
public boolean drawLines = true, drawPlanes = false;
public RadialMirrorSettings() {
}
public RadialMirrorSettings(boolean enabled, Vector3d position, int slices, boolean alternate, int radius, boolean drawLines, boolean drawPlanes) {
this.enabled = enabled;
this.position = position;
this.slices = slices;
this.alternate = alternate;
this.radius = radius;
this.drawLines = drawLines;
this.drawPlanes = drawPlanes;
}
public int getReach() {
return radius * 2;
}
} }
} }

View File

@@ -5,14 +5,11 @@ import net.minecraft.block.BlockState;
import net.minecraft.block.Blocks; import net.minecraft.block.Blocks;
import net.minecraft.entity.player.PlayerEntity; import net.minecraft.entity.player.PlayerEntity;
import net.minecraft.item.BlockItem; import net.minecraft.item.BlockItem;
import net.minecraft.item.Item;
import net.minecraft.item.ItemStack; import net.minecraft.item.ItemStack;
import net.minecraft.util.Direction; import net.minecraft.util.Direction;
import net.minecraft.util.math.BlockPos; import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.Vec3d; import net.minecraft.util.math.vector.Vector3d;
import net.minecraft.world.server.ServerWorld; import net.minecraft.world.server.ServerWorld;
import net.minecraft.world.storage.loot.LootContext;
import net.minecraft.world.storage.loot.LootParameterSet;
import nl.requios.effortlessbuilding.BuildConfig; import nl.requios.effortlessbuilding.BuildConfig;
import nl.requios.effortlessbuilding.EffortlessBuilding; import nl.requios.effortlessbuilding.EffortlessBuilding;
import nl.requios.effortlessbuilding.helper.FixedStack; import nl.requios.effortlessbuilding.helper.FixedStack;
@@ -26,14 +23,14 @@ public class UndoRedo {
//Undo and redo stacks per player //Undo and redo stacks per player
//Gets added to twice in singleplayer (server and client) if not careful. So separate stacks. //Gets added to twice in singleplayer (server and client) if not careful. So separate stacks.
private static Map<UUID, FixedStack<BlockSet>> undoStacksClient = new HashMap<>(); private static final Map<UUID, FixedStack<BlockSet>> undoStacksClient = new HashMap<>();
private static Map<UUID, FixedStack<BlockSet>> undoStacksServer = new HashMap<>(); private static final Map<UUID, FixedStack<BlockSet>> undoStacksServer = new HashMap<>();
private static Map<UUID, FixedStack<BlockSet>> redoStacksClient = new HashMap<>(); private static final Map<UUID, FixedStack<BlockSet>> redoStacksClient = new HashMap<>();
private static Map<UUID, FixedStack<BlockSet>> redoStacksServer = new HashMap<>(); private static final Map<UUID, FixedStack<BlockSet>> redoStacksServer = new HashMap<>();
//add to undo stack //add to undo stack
public static void addUndo(PlayerEntity player, BlockSet blockSet) { public static void addUndo(PlayerEntity player, BlockSet blockSet) {
Map<UUID, FixedStack<BlockSet>> undoStacks = player.world.isRemote ? undoStacksClient : undoStacksServer; Map<UUID, FixedStack<BlockSet>> undoStacks = player.level.isClientSide ? undoStacksClient : undoStacksServer;
//Assert coordinates is as long as previous and new blockstate lists //Assert coordinates is as long as previous and new blockstate lists
if (blockSet.getCoordinates().size() != blockSet.getPreviousBlockStates().size() || if (blockSet.getCoordinates().size() != blockSet.getPreviousBlockStates().size() ||
@@ -52,32 +49,32 @@ public class UndoRedo {
// } // }
//If no stack exists, make one //If no stack exists, make one
if (!undoStacks.containsKey(player.getUniqueID())) { if (!undoStacks.containsKey(player.getUUID())) {
undoStacks.put(player.getUniqueID(), new FixedStack<>(new BlockSet[BuildConfig.survivalBalancers.undoStackSize.get()])); undoStacks.put(player.getUUID(), new FixedStack<>(new BlockSet[BuildConfig.survivalBalancers.undoStackSize.get()]));
} }
undoStacks.get(player.getUniqueID()).push(blockSet); undoStacks.get(player.getUUID()).push(blockSet);
} }
private static void addRedo(PlayerEntity player, BlockSet blockSet) { private static void addRedo(PlayerEntity player, BlockSet blockSet) {
Map<UUID, FixedStack<BlockSet>> redoStacks = player.world.isRemote ? redoStacksClient : redoStacksServer; Map<UUID, FixedStack<BlockSet>> redoStacks = player.level.isClientSide ? redoStacksClient : redoStacksServer;
//(No asserts necessary, it's private) //(No asserts necessary, it's private)
//If no stack exists, make one //If no stack exists, make one
if (!redoStacks.containsKey(player.getUniqueID())) { if (!redoStacks.containsKey(player.getUUID())) {
redoStacks.put(player.getUniqueID(), new FixedStack<>(new BlockSet[BuildConfig.survivalBalancers.undoStackSize.get()])); redoStacks.put(player.getUUID(), new FixedStack<>(new BlockSet[BuildConfig.survivalBalancers.undoStackSize.get()]));
} }
redoStacks.get(player.getUniqueID()).push(blockSet); redoStacks.get(player.getUUID()).push(blockSet);
} }
public static boolean undo(PlayerEntity player) { public static boolean undo(PlayerEntity player) {
Map<UUID, FixedStack<BlockSet>> undoStacks = player.world.isRemote ? undoStacksClient : undoStacksServer; Map<UUID, FixedStack<BlockSet>> undoStacks = player.level.isClientSide ? undoStacksClient : undoStacksServer;
if (!undoStacks.containsKey(player.getUniqueID())) return false; if (!undoStacks.containsKey(player.getUUID())) return false;
FixedStack<BlockSet> undoStack = undoStacks.get(player.getUniqueID()); FixedStack<BlockSet> undoStack = undoStacks.get(player.getUUID());
if (undoStack.isEmpty()) return false; if (undoStack.isEmpty()) return false;
@@ -85,12 +82,12 @@ public class UndoRedo {
List<BlockPos> coordinates = blockSet.getCoordinates(); List<BlockPos> coordinates = blockSet.getCoordinates();
List<BlockState> previousBlockStates = blockSet.getPreviousBlockStates(); List<BlockState> previousBlockStates = blockSet.getPreviousBlockStates();
List<BlockState> newBlockStates = blockSet.getNewBlockStates(); List<BlockState> newBlockStates = blockSet.getNewBlockStates();
Vec3d hitVec = blockSet.getHitVec(); Vector3d hitVec = blockSet.getHitVec();
//Find up to date itemstacks in player inventory //Find up to date itemstacks in player inventory
List<ItemStack> itemStacks = findItemStacksInInventory(player, previousBlockStates); List<ItemStack> itemStacks = findItemStacksInInventory(player, previousBlockStates);
if (player.world.isRemote) { if (player.level.isClientSide) {
BlockPreviewRenderer.onBlocksBroken(coordinates, itemStacks, newBlockStates, blockSet.getSecondPos(), blockSet.getFirstPos()); BlockPreviewRenderer.onBlocksBroken(coordinates, itemStacks, newBlockStates, blockSet.getSecondPos(), blockSet.getFirstPos());
} else { } else {
//break all those blocks, reset to what they were //break all those blocks, reset to what they were
@@ -101,27 +98,27 @@ public class UndoRedo {
if (previousBlockStates.get(i).equals(newBlockStates.get(i))) continue; if (previousBlockStates.get(i).equals(newBlockStates.get(i))) continue;
//get blockstate from itemstack //get blockstate from itemstack
BlockState previousBlockState = Blocks.AIR.getDefaultState(); BlockState previousBlockState = Blocks.AIR.defaultBlockState();
if (itemStack.getItem() instanceof BlockItem) { if (itemStack.getItem() instanceof BlockItem) {
previousBlockState = ((BlockItem) itemStack.getItem()).getBlock().getDefaultState(); previousBlockState = ((BlockItem) itemStack.getItem()).getBlock().defaultBlockState();
} }
if (player.world.isBlockPresent(coordinate)) { if (player.level.isLoaded(coordinate)) {
//check itemstack empty //check itemstack empty
if (itemStack.isEmpty()) { if (itemStack.isEmpty()) {
itemStack = findItemStackInInventory(player, previousBlockStates.get(i)); itemStack = findItemStackInInventory(player, previousBlockStates.get(i));
//get blockstate from new itemstack //get blockstate from new itemstack
if (!itemStack.isEmpty() && itemStack.getItem() instanceof BlockItem) { if (!itemStack.isEmpty() && itemStack.getItem() instanceof BlockItem) {
previousBlockState = ((BlockItem) itemStack.getItem()).getBlock().getDefaultState(); previousBlockState = ((BlockItem) itemStack.getItem()).getBlock().defaultBlockState();
} else { } else {
if (previousBlockStates.get(i).getBlock() != Blocks.AIR) if (previousBlockStates.get(i).getBlock() != Blocks.AIR)
EffortlessBuilding.logTranslate(player, "", previousBlockStates.get(i).getBlock().getTranslationKey(), " not found in inventory", true); EffortlessBuilding.logTranslate(player, "", previousBlockStates.get(i).getBlock().getDescriptionId(), " not found in inventory", true);
previousBlockState = Blocks.AIR.getDefaultState(); previousBlockState = Blocks.AIR.defaultBlockState();
} }
} }
if (itemStack.isEmpty()) SurvivalHelper.breakBlock(player.world, player, coordinate, true); if (itemStack.isEmpty()) SurvivalHelper.breakBlock(player.level, player, coordinate, true);
//if previousBlockState is air, placeBlock will set it to air //if previousBlockState is air, placeBlock will set it to air
SurvivalHelper.placeBlock(player.world, player, coordinate, previousBlockState, itemStack, Direction.UP, hitVec, true, false, false); SurvivalHelper.placeBlock(player.level, player, coordinate, previousBlockState, itemStack, Direction.UP, hitVec, true, false, false);
} }
} }
} }
@@ -133,11 +130,11 @@ public class UndoRedo {
} }
public static boolean redo(PlayerEntity player) { public static boolean redo(PlayerEntity player) {
Map<UUID, FixedStack<BlockSet>> redoStacks = player.world.isRemote ? redoStacksClient : redoStacksServer; Map<UUID, FixedStack<BlockSet>> redoStacks = player.level.isClientSide ? redoStacksClient : redoStacksServer;
if (!redoStacks.containsKey(player.getUniqueID())) return false; if (!redoStacks.containsKey(player.getUUID())) return false;
FixedStack<BlockSet> redoStack = redoStacks.get(player.getUniqueID()); FixedStack<BlockSet> redoStack = redoStacks.get(player.getUUID());
if (redoStack.isEmpty()) return false; if (redoStack.isEmpty()) return false;
@@ -145,12 +142,12 @@ public class UndoRedo {
List<BlockPos> coordinates = blockSet.getCoordinates(); List<BlockPos> coordinates = blockSet.getCoordinates();
List<BlockState> previousBlockStates = blockSet.getPreviousBlockStates(); List<BlockState> previousBlockStates = blockSet.getPreviousBlockStates();
List<BlockState> newBlockStates = blockSet.getNewBlockStates(); List<BlockState> newBlockStates = blockSet.getNewBlockStates();
Vec3d hitVec = blockSet.getHitVec(); Vector3d hitVec = blockSet.getHitVec();
//Find up to date itemstacks in player inventory //Find up to date itemstacks in player inventory
List<ItemStack> itemStacks = findItemStacksInInventory(player, newBlockStates); List<ItemStack> itemStacks = findItemStacksInInventory(player, newBlockStates);
if (player.world.isRemote) { if (player.level.isClientSide) {
BlockPreviewRenderer.onBlocksPlaced(coordinates, itemStacks, newBlockStates, blockSet.getFirstPos(), blockSet.getSecondPos()); BlockPreviewRenderer.onBlocksPlaced(coordinates, itemStacks, newBlockStates, blockSet.getFirstPos(), blockSet.getSecondPos());
} else { } else {
//place blocks //place blocks
@@ -161,26 +158,26 @@ public class UndoRedo {
if (previousBlockStates.get(i).equals(newBlockStates.get(i))) continue; if (previousBlockStates.get(i).equals(newBlockStates.get(i))) continue;
//get blockstate from itemstack //get blockstate from itemstack
BlockState newBlockState = Blocks.AIR.getDefaultState(); BlockState newBlockState = Blocks.AIR.defaultBlockState();
if (itemStack.getItem() instanceof BlockItem) { if (itemStack.getItem() instanceof BlockItem) {
newBlockState = ((BlockItem) itemStack.getItem()).getBlock().getDefaultState(); newBlockState = ((BlockItem) itemStack.getItem()).getBlock().defaultBlockState();
} }
if (player.world.isBlockPresent(coordinate)) { if (player.level.isLoaded(coordinate)) {
//check itemstack empty //check itemstack empty
if (itemStack.isEmpty()) { if (itemStack.isEmpty()) {
itemStack = findItemStackInInventory(player, newBlockStates.get(i)); itemStack = findItemStackInInventory(player, newBlockStates.get(i));
//get blockstate from new itemstack //get blockstate from new itemstack
if (!itemStack.isEmpty() && itemStack.getItem() instanceof BlockItem) { if (!itemStack.isEmpty() && itemStack.getItem() instanceof BlockItem) {
newBlockState = ((BlockItem) itemStack.getItem()).getBlock().getDefaultState(); newBlockState = ((BlockItem) itemStack.getItem()).getBlock().defaultBlockState();
} else { } else {
if (newBlockStates.get(i).getBlock() != Blocks.AIR) if (newBlockStates.get(i).getBlock() != Blocks.AIR)
EffortlessBuilding.logTranslate(player, "", newBlockStates.get(i).getBlock().getTranslationKey(), " not found in inventory", true); EffortlessBuilding.logTranslate(player, "", newBlockStates.get(i).getBlock().getDescriptionId(), " not found in inventory", true);
newBlockState = Blocks.AIR.getDefaultState(); newBlockState = Blocks.AIR.defaultBlockState();
} }
} }
if (itemStack.isEmpty()) SurvivalHelper.breakBlock(player.world, player, coordinate, true); if (itemStack.isEmpty()) SurvivalHelper.breakBlock(player.level, player, coordinate, true);
SurvivalHelper.placeBlock(player.world, player, coordinate, newBlockState, itemStack, Direction.UP, hitVec, true, false, false); SurvivalHelper.placeBlock(player.level, player, coordinate, newBlockState, itemStack, Direction.UP, hitVec, true, false, false);
} }
} }
} }
@@ -192,13 +189,13 @@ public class UndoRedo {
} }
public static void clear(PlayerEntity player) { public static void clear(PlayerEntity player) {
Map<UUID, FixedStack<BlockSet>> undoStacks = player.world.isRemote ? undoStacksClient : undoStacksServer; Map<UUID, FixedStack<BlockSet>> undoStacks = player.level.isClientSide ? undoStacksClient : undoStacksServer;
Map<UUID, FixedStack<BlockSet>> redoStacks = player.world.isRemote ? redoStacksClient : redoStacksServer; Map<UUID, FixedStack<BlockSet>> redoStacks = player.level.isClientSide ? redoStacksClient : redoStacksServer;
if (undoStacks.containsKey(player.getUniqueID())) { if (undoStacks.containsKey(player.getUUID())) {
undoStacks.get(player.getUniqueID()).clear(); undoStacks.get(player.getUUID()).clear();
} }
if (redoStacks.containsKey(player.getUniqueID())) { if (redoStacks.containsKey(player.getUUID())) {
redoStacks.get(player.getUniqueID()).clear(); redoStacks.get(player.getUUID()).clear();
} }
} }
@@ -223,9 +220,8 @@ public class UndoRedo {
//then anything it drops //then anything it drops
if (itemStack.isEmpty()) { if (itemStack.isEmpty()) {
//Cannot check drops on clientside because loot tables are server only //Cannot check drops on clientside because loot tables are server only
if (!player.world.isRemote) if (!player.level.isClientSide) {
{ List<ItemStack> itemsDropped = Block.getDrops(blockState, (ServerWorld) player.level, BlockPos.ZERO, null);
List<ItemStack> itemsDropped = Block.getDrops(blockState, (ServerWorld) player.world, BlockPos.ZERO, null);
for (ItemStack itemStackDropped : itemsDropped) { for (ItemStack itemStackDropped : itemsDropped) {
if (itemStackDropped.getItem() instanceof BlockItem) { if (itemStackDropped.getItem() instanceof BlockItem) {
Block block = ((BlockItem) itemStackDropped.getItem()).getBlock(); Block block = ((BlockItem) itemStackDropped.getItem()).getBlock();

View File

@@ -8,13 +8,17 @@ import net.minecraftforge.common.util.LazyOptional;
import net.minecraftforge.items.CapabilityItemHandler; import net.minecraftforge.items.CapabilityItemHandler;
import net.minecraftforge.items.IItemHandler; import net.minecraftforge.items.IItemHandler;
import net.minecraftforge.items.ItemStackHandler; import net.minecraftforge.items.ItemStackHandler;
import nl.requios.effortlessbuilding.item.ItemRandomizerBag; import nl.requios.effortlessbuilding.item.RandomizerBagItem;
import javax.annotation.Nonnull; import javax.annotation.Nonnull;
import javax.annotation.Nullable; import javax.annotation.Nullable;
public class ItemHandlerCapabilityProvider implements ICapabilitySerializable<CompoundNBT> { public class ItemHandlerCapabilityProvider implements ICapabilitySerializable<CompoundNBT> {
IItemHandler itemHandler = new ItemStackHandler(ItemRandomizerBag.INV_SIZE); IItemHandler itemHandler;
public ItemHandlerCapabilityProvider(int size) {
itemHandler = new ItemStackHandler(size);
}
@Nonnull @Nonnull
@Override @Override

View File

@@ -17,12 +17,24 @@ import javax.annotation.Nullable;
import static nl.requios.effortlessbuilding.buildmode.ModeSettingsManager.ModeSettings; import static nl.requios.effortlessbuilding.buildmode.ModeSettingsManager.ModeSettings;
import nl.requios.effortlessbuilding.buildmode.ModeSettingsManager.ModeSettings;
@Mod.EventBusSubscriber @Mod.EventBusSubscriber
public class ModeCapabilityManager { public class ModeCapabilityManager {
@CapabilityInject(IModeCapability.class) @CapabilityInject(IModeCapability.class)
public final static Capability<IModeCapability> modeCapability = null; public final static Capability<IModeCapability> modeCapability = null;
// Allows for the capability to persist after death.
@SubscribeEvent
public static void clonePlayer(PlayerEvent.Clone event) {
LazyOptional<IModeCapability> original = event.getOriginal().getCapability(modeCapability, null);
LazyOptional<IModeCapability> clone = event.getEntity().getCapability(modeCapability, null);
clone.ifPresent(cloneModeCapability ->
original.ifPresent(originalModeCapability ->
cloneModeCapability.setModeData(originalModeCapability.getModeData())));
}
public interface IModeCapability { public interface IModeCapability {
ModeSettings getModeData(); ModeSettings getModeData();
@@ -90,14 +102,4 @@ public class ModeCapabilityManager {
} }
} }
// Allows for the capability to persist after death.
@SubscribeEvent
public static void clonePlayer(PlayerEvent.Clone event) {
LazyOptional<IModeCapability> original = event.getOriginal().getCapability(modeCapability, null);
LazyOptional<IModeCapability> clone = event.getEntity().getCapability(modeCapability, null);
clone.ifPresent(cloneModeCapability ->
original.ifPresent(originalModeCapability ->
cloneModeCapability.setModeData(originalModeCapability.getModeData())));
}
} }

View File

@@ -4,7 +4,7 @@ import net.minecraft.nbt.CompoundNBT;
import net.minecraft.nbt.INBT; import net.minecraft.nbt.INBT;
import net.minecraft.util.Direction; import net.minecraft.util.Direction;
import net.minecraft.util.math.BlockPos; import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.Vec3d; import net.minecraft.util.math.vector.Vector3d;
import net.minecraftforge.common.capabilities.Capability; import net.minecraftforge.common.capabilities.Capability;
import net.minecraftforge.common.capabilities.CapabilityInject; import net.minecraftforge.common.capabilities.CapabilityInject;
import net.minecraftforge.common.capabilities.ICapabilitySerializable; import net.minecraftforge.common.capabilities.ICapabilitySerializable;
@@ -19,7 +19,9 @@ import nl.requios.effortlessbuilding.buildmodifier.RadialMirror;
import javax.annotation.Nonnull; import javax.annotation.Nonnull;
import javax.annotation.Nullable; import javax.annotation.Nullable;
import static nl.requios.effortlessbuilding.buildmodifier.ModifierSettingsManager.*; import static nl.requios.effortlessbuilding.buildmodifier.ModifierSettingsManager.ModifierSettings;
import nl.requios.effortlessbuilding.buildmodifier.ModifierSettingsManager.ModifierSettings;
@Mod.EventBusSubscriber @Mod.EventBusSubscriber
public class ModifierCapabilityManager { public class ModifierCapabilityManager {
@@ -27,6 +29,16 @@ public class ModifierCapabilityManager {
@CapabilityInject(IModifierCapability.class) @CapabilityInject(IModifierCapability.class)
public final static Capability<IModifierCapability> modifierCapability = null; public final static Capability<IModifierCapability> modifierCapability = null;
// Allows for the capability to persist after death.
@SubscribeEvent
public static void clonePlayer(PlayerEvent.Clone event) {
LazyOptional<IModifierCapability> original = event.getOriginal().getCapability(modifierCapability, null);
LazyOptional<IModifierCapability> clone = event.getEntity().getCapability(modifierCapability, null);
clone.ifPresent(cloneModifierCapability ->
original.ifPresent(originalModifierCapability ->
cloneModifierCapability.setModifierData(originalModifierCapability.getModifierData())));
}
public interface IModifierCapability { public interface IModifierCapability {
ModifierSettings getModifierData(); ModifierSettings getModifierData();
@@ -103,7 +115,7 @@ public class ModifierCapabilityManager {
//MIRROR //MIRROR
boolean mirrorEnabled = compound.getBoolean("mirrorEnabled"); boolean mirrorEnabled = compound.getBoolean("mirrorEnabled");
Vec3d mirrorPosition = new Vec3d( Vector3d mirrorPosition = new Vector3d(
compound.getDouble("mirrorPosX"), compound.getDouble("mirrorPosX"),
compound.getDouble("mirrorPosY"), compound.getDouble("mirrorPosY"),
compound.getDouble("mirrorPosZ")); compound.getDouble("mirrorPosZ"));
@@ -130,7 +142,7 @@ public class ModifierCapabilityManager {
//RADIAL MIRROR //RADIAL MIRROR
boolean radialMirrorEnabled = compound.getBoolean("radialMirrorEnabled"); boolean radialMirrorEnabled = compound.getBoolean("radialMirrorEnabled");
Vec3d radialMirrorPosition = new Vec3d( Vector3d radialMirrorPosition = new Vector3d(
compound.getDouble("radialMirrorPosX"), compound.getDouble("radialMirrorPosX"),
compound.getDouble("radialMirrorPosY"), compound.getDouble("radialMirrorPosY"),
compound.getDouble("radialMirrorPosZ")); compound.getDouble("radialMirrorPosZ"));
@@ -168,15 +180,4 @@ public class ModifierCapabilityManager {
} }
} }
// Allows for the capability to persist after death.
@SubscribeEvent
public static void clonePlayer(PlayerEvent.Clone event) {
LazyOptional<IModifierCapability> original = event.getOriginal().getCapability(modifierCapability, null);
LazyOptional<IModifierCapability> clone = event.getEntity().getCapability(modifierCapability, null);
clone.ifPresent(cloneModifierCapability ->
original.ifPresent(originalModifierCapability ->
cloneModifierCapability.setModifierData(originalModifierCapability.getModifierData())));
}
} }

View File

@@ -16,27 +16,27 @@ public class CommandReach {
public static void register(CommandDispatcher<CommandSource> dispatcher) { public static void register(CommandDispatcher<CommandSource> dispatcher) {
dispatcher.register(Commands.literal("reach").then(Commands.literal("set").then(Commands.argument("level", IntegerArgumentType.integer(0, 3)).executes((context) -> { dispatcher.register(Commands.literal("reach").then(Commands.literal("set").then(Commands.argument("level", IntegerArgumentType.integer(0, 3)).executes((context) -> {
return setReachLevel(context.getSource().asPlayer(), IntegerArgumentType.getInteger(context, "level")); return setReachLevel(context.getSource().getPlayerOrException(), IntegerArgumentType.getInteger(context, "level"));
}))).then(Commands.literal("get").executes((context -> { }))).then(Commands.literal("get").executes((context -> {
return getReachLevel(context.getSource().asPlayer()); return getReachLevel(context.getSource().getPlayerOrException());
})))); }))));
} }
private static int setReachLevel(ServerPlayerEntity player, int level){ private static int setReachLevel(ServerPlayerEntity player, int level) {
ModifierSettingsManager.ModifierSettings modifierSettings = ModifierSettingsManager.getModifierSettings(player); ModifierSettingsManager.ModifierSettings modifierSettings = ModifierSettingsManager.getModifierSettings(player);
modifierSettings.setReachUpgrade(level); modifierSettings.setReachUpgrade(level);
ModifierSettingsManager.setModifierSettings(player, modifierSettings); ModifierSettingsManager.setModifierSettings(player, modifierSettings);
//Send to client //Send to client
PacketHandler.INSTANCE.send(PacketDistributor.PLAYER.with(() -> player), new ModifierSettingsMessage(modifierSettings)); PacketHandler.INSTANCE.send(PacketDistributor.PLAYER.with(() -> player), new ModifierSettingsMessage(modifierSettings));
player.sendMessage(new StringTextComponent("Reach level of " + player.getName().getString() + " set to " + modifierSettings.getReachUpgrade())); player.sendMessage(new StringTextComponent("Reach level of " + player.getName().getString() + " set to " + modifierSettings.getReachUpgrade()), player.getUUID());
return 1; return 1;
} }
private static int getReachLevel(ServerPlayerEntity player){ private static int getReachLevel(ServerPlayerEntity player) {
int reachUpgrade = ModifierSettingsManager.getModifierSettings(player).getReachUpgrade(); int reachUpgrade = ModifierSettingsManager.getModifierSettings(player).getReachUpgrade();
EffortlessBuilding.log(player, "Current reach: level "+reachUpgrade); EffortlessBuilding.log(player, "Current reach: level " + reachUpgrade);
return 1; return 1;
} }

View File

@@ -1,37 +1,16 @@
package nl.requios.effortlessbuilding.compatibility; package nl.requios.effortlessbuilding.compatibility;
import net.minecraft.block.BlockState; import net.minecraft.block.BlockState;
import net.minecraft.entity.player.PlayerEntity;
import net.minecraft.item.BlockItem; import net.minecraft.item.BlockItem;
import net.minecraft.item.Item; import net.minecraft.item.Item;
import net.minecraft.item.ItemStack; import net.minecraft.item.ItemStack;
import net.minecraftforge.common.util.LazyOptional;
import net.minecraftforge.items.CapabilityItemHandler;
import net.minecraftforge.items.IItemHandler; import net.minecraftforge.items.IItemHandler;
import nl.requios.effortlessbuilding.EffortlessBuilding; import nl.requios.effortlessbuilding.item.AbstractRandomizerBagItem;
import nl.requios.effortlessbuilding.item.ItemRandomizerBag;
public class CompatHelper { public class CompatHelper {
//TODO 1.13 compatibility
// // Get a handle to the dank null item instance. This will remain null if the mod doesn't load
// // and all checks will fail, so it works.
// @GameRegistry.ObjectHolder("danknull:dank_null")
// public static final Item dankNullItem = null;
//
// public static IChiselsAndBitsProxy chiselsAndBitsProxy;
//
public static void setup() { public static void setup() {
//TODO 1.13 compatibility
// if (Loader.isModLoaded("chiselsandbits")) {
// // reflection to avoid hard dependency
// try {
// chiselsAndBitsProxy = Class.forName("nl.requios.effortlessbuilding.compatibility.ActiveChiselsAndBitsProxy").asSubclass(ActiveChiselsAndBitsProxy.class).newInstance();
// } catch (InstantiationException | IllegalAccessException | ClassNotFoundException e) {
// e.printStackTrace();
// }
// } else {
// chiselsAndBitsProxy = new DummyChiselsAndBitsProxy();
// }
} }
// Check if the item given is a proxy for blocks. For now, we check for the randomizer bag, // Check if the item given is a proxy for blocks. For now, we check for the randomizer bag,
@@ -40,12 +19,7 @@ public class CompatHelper {
Item item = stack.getItem(); Item item = stack.getItem();
if (item instanceof BlockItem) if (item instanceof BlockItem)
return true; return true;
if ((item instanceof ItemRandomizerBag)) return item instanceof AbstractRandomizerBagItem;
return true;
//TODO 1.13 compatibility
// if (item == dankNullItem)
// return true;
return false;
} }
// Get the block to be placed by this proxy. For the /dank/null, it's the slot stack // Get the block to be placed by this proxy. For the /dank/null, it's the slot stack
@@ -57,76 +31,32 @@ public class CompatHelper {
return proxy; return proxy;
//Randomizer Bag //Randomizer Bag
if (proxyItem instanceof ItemRandomizerBag) { if (proxyItem instanceof AbstractRandomizerBagItem) {
ItemStack itemStack = proxy; ItemStack itemStack = proxy;
while (!(itemStack.getItem() instanceof BlockItem || itemStack.isEmpty())) { while (!(itemStack.getItem() instanceof BlockItem || itemStack.isEmpty())) {
if (itemStack.getItem() instanceof ItemRandomizerBag) if (itemStack.getItem() instanceof AbstractRandomizerBagItem) {
itemStack = ItemRandomizerBag.pickRandomStack(ItemRandomizerBag.getBagInventory(itemStack)); AbstractRandomizerBagItem randomizerBagItem = (AbstractRandomizerBagItem) itemStack.getItem();
itemStack = randomizerBagItem.pickRandomStack(randomizerBagItem.getBagInventory(itemStack));
}
} }
return itemStack; return itemStack;
} }
//TODO 1.13 compatibility
//Dank Null
// if (proxyItem == dankNullItem) {
// int index = 0;
// if (proxy.hasTagCompound() && proxy.getTagCompound().hasKey("selectedIndex"))
// index = proxy.getTagCompound().getInteger("selectedIndex");
// return proxy.getCapability(CapabilityItemHandler.ITEM_HANDLER_CAPABILITY, null).getStackInSlot(index);
// }
return ItemStack.EMPTY; return ItemStack.EMPTY;
} }
public static ItemStack getItemBlockByState(ItemStack stack, BlockState state) { public static ItemStack getItemBlockByState(ItemStack stack, BlockState state) {
if (state == null) return ItemStack.EMPTY; if (state == null) return ItemStack.EMPTY;
Item blockItem = Item.getItemFromBlock(state.getBlock()); Item blockItem = Item.byBlock(state.getBlock());
if (stack.getItem() instanceof BlockItem) if (stack.getItem() instanceof BlockItem)
return stack; return stack;
else if (stack.getItem() instanceof ItemRandomizerBag) { else if (stack.getItem() instanceof AbstractRandomizerBagItem) {
IItemHandler bagInventory = ItemRandomizerBag.getBagInventory(stack); AbstractRandomizerBagItem randomizerBagItem = (AbstractRandomizerBagItem) stack.getItem();
return ItemRandomizerBag.findStack(bagInventory, blockItem); IItemHandler bagInventory = randomizerBagItem.getBagInventory(stack);
return randomizerBagItem.findStack(bagInventory, blockItem);
} }
//TODO 1.13 compatibility
// else if (stack.getItem() == dankNullItem) {
// int index = itemHandlerSlotForItem(stack, blockItem);
// if (index >= 0)
// return stack.getCapability(CapabilityItemHandler.ITEM_HANDLER_CAPABILITY, null).getStackInSlot(index);
// }
return ItemStack.EMPTY; return ItemStack.EMPTY;
} }
// Handle IItemHandler slot stacks not being modifiable. We must call IItemHandler#extractItem,
// because the ItemStack returned by IItemHandler#getStackInSlot isn't modifiable.
public static void shrinkStack(ItemStack origStack, ItemStack curStack, PlayerEntity player) {
//TODO 1.13 compatibility, offhand support
//Hacky way to get the origstack, because given origStack is itemblock stack and never proxy
// origStack = player.getHeldItem(EnumHand.MAIN_HAND);
// if (origStack.getItem() == dankNullItem) {
// int index = itemHandlerSlotForItem(origStack, curStack.getItem());
// origStack.getCapability(CapabilityItemHandler.ITEM_HANDLER_CAPABILITY, null).extractItem(index, 1, false);
// } else
curStack.shrink(1);
}
private static int itemHandlerSlotForItem(ItemStack stack, Item blockItem) {
LazyOptional<IItemHandler> itemHandlerLazyOptional = stack.getCapability(CapabilityItemHandler.ITEM_HANDLER_CAPABILITY, null);
IItemHandler handler = itemHandlerLazyOptional.orElse(null);
if (handler == null) {
EffortlessBuilding.logger.warn("Itemblock proxy has no item handler capability!");
return -1;
}
for (int i = 0; i < handler.getSlots(); i++) {
ItemStack ref = handler.getStackInSlot(i);
if (ref.getItem() instanceof BlockItem)
if (ref.getItem() == blockItem)
return i;
}
return -1;
}
} }

View File

@@ -0,0 +1,149 @@
package nl.requios.effortlessbuilding.gui;
import net.minecraft.entity.player.PlayerEntity;
import net.minecraft.entity.player.PlayerInventory;
import net.minecraft.inventory.container.ClickType;
import net.minecraft.inventory.container.Container;
import net.minecraft.inventory.container.ContainerType;
import net.minecraft.inventory.container.Slot;
import net.minecraft.item.ItemStack;
import net.minecraft.network.PacketBuffer;
import net.minecraft.util.Hand;
import net.minecraftforge.items.IItemHandler;
import net.minecraftforge.items.ItemStackHandler;
import net.minecraftforge.items.SlotItemHandler;
import nl.requios.effortlessbuilding.EffortlessBuilding;
import nl.requios.effortlessbuilding.item.DiamondRandomizerBagItem;
public class DiamondRandomizerBagContainer extends Container {
private static final int INV_START = DiamondRandomizerBagItem.INV_SIZE,
INV_END = INV_START + 26,
HOTBAR_START = INV_END + 1,
HOTBAR_END = HOTBAR_START + 8;
private final IItemHandler bagInventory;
public DiamondRandomizerBagContainer(ContainerType<?> type, int id){
super(type, id);
bagInventory = null;
}
//Client
public DiamondRandomizerBagContainer(int id, PlayerInventory playerInventory, PacketBuffer packetBuffer) {
this(id, playerInventory);
}
//Server?
public DiamondRandomizerBagContainer(int containerId, PlayerInventory playerInventory) {
this(containerId, playerInventory, new ItemStackHandler(DiamondRandomizerBagItem.INV_SIZE));
}
public DiamondRandomizerBagContainer(int containerId, PlayerInventory playerInventory, IItemHandler inventory) {
super(EffortlessBuilding.DIAMOND_RANDOMIZER_BAG_CONTAINER.get(), containerId);
bagInventory = inventory;
for (int i = 0; i < 3; ++i) {
for (int j = 0; j < 9; ++j) {
this.addSlot(new SlotItemHandler(bagInventory, j + i * 9, 8 + j * 18, 18 + i * 18));
}
}
// add player inventory slots
for (int i = 0; i < 3; ++i) {
for (int j = 0; j < 9; ++j) {
addSlot(new Slot(playerInventory, j + i * 9 + 9, 8 + j * 18, 84 + i * 18));
}
}
// add hotbar slots
for (int i = 0; i < 9; ++i) {
addSlot(new Slot(playerInventory, i, 8 + i * 18, 142));
}
}
@Override
public boolean stillValid(PlayerEntity playerIn) {
return true;
}
@Override
public Slot getSlot(int parSlotIndex) {
if (parSlotIndex >= slots.size())
parSlotIndex = slots.size() - 1;
return super.getSlot(parSlotIndex);
}
@Override
public ItemStack quickMoveStack(PlayerEntity playerIn, int slotIndex) {
ItemStack itemstack = ItemStack.EMPTY;
Slot slot = this.slots.get(slotIndex);
if (slot != null && slot.hasItem()) {
ItemStack itemstack1 = slot.getItem();
itemstack = itemstack1.copy();
// If item is in our custom inventory
if (slotIndex < INV_START) {
// try to place in player inventory / action bar
if (!this.moveItemStackTo(itemstack1, INV_START, HOTBAR_END + 1, true)) {
return ItemStack.EMPTY;
}
slot.onQuickCraft(itemstack1, itemstack);
}
// Item is in inventory / hotbar, try to place in custom inventory or armor slots
else {
/**
* Implementation number 1: Shift-click into your custom inventory
*/
if (slotIndex >= INV_START) {
// place in custom inventory
if (!this.moveItemStackTo(itemstack1, 0, INV_START, false)) {
return ItemStack.EMPTY;
}
}
}
if (itemstack1.getCount() == 0) {
slot.set(ItemStack.EMPTY);
} else {
slot.setChanged();
}
if (itemstack1.getCount() == itemstack.getCount()) {
return ItemStack.EMPTY;
}
slot.onTake(playerIn, itemstack1);
}
return itemstack;
}
/**
* You should override this method to prevent the player from moving the stack that
* opened the inventory, otherwise if the player moves it, the inventory will not
* be able to save properly
* @return
*/
@Override
public ItemStack clicked(int slot, int dragType, ClickType clickTypeIn, PlayerEntity player) {
// this will prevent the player from interacting with the item that opened the inventory:
if (slot >= 0 && getSlot(slot) != null && getSlot(slot).getItem().equals(player.getItemInHand(Hand.MAIN_HAND))) {
//Do nothing;
return ItemStack.EMPTY;
}
return super.clicked(slot, dragType, clickTypeIn, player);
}
/**
* Callback for when the crafting gui is closed.
*/
@Override
public void removed(PlayerEntity player) {
super.removed(player);
if (!player.level.isClientSide) {
broadcastChanges();
}
}
}

View File

@@ -0,0 +1,47 @@
package nl.requios.effortlessbuilding.gui;
import com.mojang.blaze3d.matrix.MatrixStack;
import com.mojang.blaze3d.systems.RenderSystem;
import net.minecraft.client.gui.screen.inventory.ContainerScreen;
import net.minecraft.entity.player.PlayerInventory;
import net.minecraft.util.ResourceLocation;
import net.minecraft.util.text.ITextComponent;
import net.minecraftforge.api.distmarker.Dist;
import net.minecraftforge.api.distmarker.OnlyIn;
import nl.requios.effortlessbuilding.EffortlessBuilding;
import javax.annotation.ParametersAreNonnullByDefault;
@OnlyIn(Dist.CLIENT)
@ParametersAreNonnullByDefault
public class DiamondRandomizerBagScreen extends ContainerScreen<DiamondRandomizerBagContainer> {
private static final ResourceLocation guiTextures =
new ResourceLocation(EffortlessBuilding.MODID, "textures/gui/container/diamondrandomizerbag.png");
public DiamondRandomizerBagScreen(DiamondRandomizerBagContainer randomizerBagContainer, PlayerInventory playerInventory, ITextComponent title) {
super(randomizerBagContainer, playerInventory, title);
imageHeight = 167;
}
@Override
public void render(MatrixStack ms, int mouseX, int mouseY, float partialTicks) {
renderBackground(ms);
super.render(ms, mouseX, mouseY, partialTicks);
this.renderTooltip(ms, mouseX, mouseY);
}
@Override
protected void renderLabels(MatrixStack ms, int mouseX, int mouseY) {
font.draw(ms, this.title, 8, 6, 0x404040);
font.draw(ms, inventory.getDisplayName(), 8, imageHeight - 96 + 2, 0x404040);
}
@Override
protected void renderBg(MatrixStack ms, float partialTicks, int mouseX, int mouseY) {
RenderSystem.color3f(1.0F, 1.0F, 1.0F);
minecraft.getTextureManager().bind(guiTextures);
int marginHorizontal = (width - imageWidth) / 2;
int marginVertical = (height - imageHeight) / 2;
blit(ms, marginHorizontal, marginVertical, 0, 0, imageWidth, imageHeight);
}
}

View File

@@ -0,0 +1,147 @@
package nl.requios.effortlessbuilding.gui;
import net.minecraft.entity.player.PlayerEntity;
import net.minecraft.entity.player.PlayerInventory;
import net.minecraft.inventory.container.ClickType;
import net.minecraft.inventory.container.Container;
import net.minecraft.inventory.container.ContainerType;
import net.minecraft.inventory.container.Slot;
import net.minecraft.item.ItemStack;
import net.minecraft.network.PacketBuffer;
import net.minecraft.util.Hand;
import net.minecraftforge.items.IItemHandler;
import net.minecraftforge.items.ItemStackHandler;
import net.minecraftforge.items.SlotItemHandler;
import nl.requios.effortlessbuilding.EffortlessBuilding;
import nl.requios.effortlessbuilding.item.GoldenRandomizerBagItem;
public class GoldenRandomizerBagContainer extends Container {
private static final int INV_START = GoldenRandomizerBagItem.INV_SIZE,
INV_END = INV_START + 26,
HOTBAR_START = INV_END + 1,
HOTBAR_END = HOTBAR_START + 8;
private final IItemHandler bagInventory;
public GoldenRandomizerBagContainer(ContainerType<?> type, int id){
super(type, id);
bagInventory = null;
}
//Client
public GoldenRandomizerBagContainer(int id, PlayerInventory playerInventory, PacketBuffer packetBuffer) {
this(id, playerInventory);
}
//Server?
public GoldenRandomizerBagContainer(int containerId, PlayerInventory playerInventory) {
this(containerId, playerInventory, new ItemStackHandler(GoldenRandomizerBagItem.INV_SIZE));
}
public GoldenRandomizerBagContainer(int containerId, PlayerInventory playerInventory, IItemHandler inventory) {
super(EffortlessBuilding.GOLDEN_RANDOMIZER_BAG_CONTAINER.get(), containerId);
bagInventory = inventory;
for (int i = 0; i < GoldenRandomizerBagItem.INV_SIZE; ++i) {
this.addSlot(new SlotItemHandler(bagInventory, i, 8 + (18 * i), 20));
}
// add player inventory slots
for (int i = 0; i < 3; ++i) {
for (int j = 0; j < 9; ++j) {
addSlot(new Slot(playerInventory, j + i * 9 + 9, 8 + j * 18, 51 + i * 18));
}
}
// add hotbar slots
for (int i = 0; i < 9; ++i) {
addSlot(new Slot(playerInventory, i, 8 + i * 18, 109));
}
}
@Override
public boolean stillValid(PlayerEntity playerIn) {
return true;
}
@Override
public Slot getSlot(int parSlotIndex) {
if (parSlotIndex >= slots.size())
parSlotIndex = slots.size() - 1;
return super.getSlot(parSlotIndex);
}
@Override
public ItemStack quickMoveStack(PlayerEntity playerIn, int slotIndex) {
ItemStack itemstack = ItemStack.EMPTY;
Slot slot = this.slots.get(slotIndex);
if (slot != null && slot.hasItem()) {
ItemStack itemstack1 = slot.getItem();
itemstack = itemstack1.copy();
// If item is in our custom inventory
if (slotIndex < INV_START) {
// try to place in player inventory / action bar
if (!this.moveItemStackTo(itemstack1, INV_START, HOTBAR_END + 1, true)) {
return ItemStack.EMPTY;
}
slot.onQuickCraft(itemstack1, itemstack);
}
// Item is in inventory / hotbar, try to place in custom inventory or armor slots
else {
/**
* Implementation number 1: Shift-click into your custom inventory
*/
if (slotIndex >= INV_START) {
// place in custom inventory
if (!this.moveItemStackTo(itemstack1, 0, INV_START, false)) {
return ItemStack.EMPTY;
}
}
}
if (itemstack1.getCount() == 0) {
slot.set(ItemStack.EMPTY);
} else {
slot.setChanged();
}
if (itemstack1.getCount() == itemstack.getCount()) {
return ItemStack.EMPTY;
}
slot.onTake(playerIn, itemstack1);
}
return itemstack;
}
/**
* You should override this method to prevent the player from moving the stack that
* opened the inventory, otherwise if the player moves it, the inventory will not
* be able to save properly
* @return
*/
@Override
public ItemStack clicked(int slot, int dragType, ClickType clickTypeIn, PlayerEntity player) {
// this will prevent the player from interacting with the item that opened the inventory:
if (slot >= 0 && getSlot(slot) != null && getSlot(slot).getItem().equals(player.getItemInHand(Hand.MAIN_HAND))) {
//Do nothing;
return ItemStack.EMPTY;
}
return super.clicked(slot, dragType, clickTypeIn, player);
}
/**
* Callback for when the crafting gui is closed.
*/
@Override
public void removed(PlayerEntity player) {
super.removed(player);
if (!player.level.isClientSide) {
broadcastChanges();
}
}
}

View File

@@ -0,0 +1,47 @@
package nl.requios.effortlessbuilding.gui;
import com.mojang.blaze3d.matrix.MatrixStack;
import com.mojang.blaze3d.systems.RenderSystem;
import net.minecraft.client.gui.screen.inventory.ContainerScreen;
import net.minecraft.entity.player.PlayerInventory;
import net.minecraft.util.ResourceLocation;
import net.minecraft.util.text.ITextComponent;
import net.minecraftforge.api.distmarker.Dist;
import net.minecraftforge.api.distmarker.OnlyIn;
import nl.requios.effortlessbuilding.EffortlessBuilding;
import javax.annotation.ParametersAreNonnullByDefault;
@OnlyIn(Dist.CLIENT)
@ParametersAreNonnullByDefault
public class GoldenRandomizerBagScreen extends ContainerScreen<GoldenRandomizerBagContainer> {
private static final ResourceLocation guiTextures =
new ResourceLocation(EffortlessBuilding.MODID, "textures/gui/container/goldenrandomizerbag.png");
public GoldenRandomizerBagScreen(GoldenRandomizerBagContainer randomizerBagContainer, PlayerInventory playerInventory, ITextComponent title) {
super(randomizerBagContainer, playerInventory, title);
imageHeight = 134;
}
@Override
public void render(MatrixStack ms, int mouseX, int mouseY, float partialTicks) {
renderBackground(ms);
super.render(ms, mouseX, mouseY, partialTicks);
this.renderTooltip(ms, mouseX, mouseY);
}
@Override
protected void renderLabels(MatrixStack ms, int mouseX, int mouseY) {
font.draw(ms, this.title, 8, 6, 0x404040);
font.draw(ms, inventory.getDisplayName(), 8, imageHeight - 96 + 2, 0x404040);
}
@Override
protected void renderBg(MatrixStack ms, float partialTicks, int mouseX, int mouseY) {
RenderSystem.color3f(1.0F, 1.0F, 1.0F);
minecraft.getTextureManager().bind(guiTextures);
int marginHorizontal = (width - imageWidth) / 2;
int marginVertical = (height - imageHeight) / 2;
blit(ms, marginHorizontal, marginVertical, 0, 0, imageWidth, imageHeight);
}
}

View File

@@ -2,82 +2,92 @@ package nl.requios.effortlessbuilding.gui;
import net.minecraft.entity.player.PlayerEntity; import net.minecraft.entity.player.PlayerEntity;
import net.minecraft.entity.player.PlayerInventory; import net.minecraft.entity.player.PlayerInventory;
import net.minecraft.inventory.IInventory;
import net.minecraft.inventory.Inventory;
import net.minecraft.inventory.container.ClickType; import net.minecraft.inventory.container.ClickType;
import net.minecraft.inventory.container.Container; import net.minecraft.inventory.container.Container;
import net.minecraft.inventory.container.ContainerType;
import net.minecraft.inventory.container.Slot; import net.minecraft.inventory.container.Slot;
import net.minecraft.item.ItemStack; import net.minecraft.item.ItemStack;
import net.minecraft.network.PacketBuffer;
import net.minecraft.util.Hand; import net.minecraft.util.Hand;
import net.minecraftforge.items.IItemHandler; import net.minecraftforge.items.IItemHandler;
import net.minecraftforge.items.ItemStackHandler; import net.minecraftforge.items.ItemStackHandler;
import net.minecraftforge.items.SlotItemHandler; import net.minecraftforge.items.SlotItemHandler;
import nl.requios.effortlessbuilding.EffortlessBuilding; import nl.requios.effortlessbuilding.EffortlessBuilding;
import nl.requios.effortlessbuilding.item.ItemRandomizerBag; import nl.requios.effortlessbuilding.item.RandomizerBagItem;
public class RandomizerBagContainer extends Container { public class RandomizerBagContainer extends Container {
private static final int INV_START = RandomizerBagItem.INV_SIZE,
INV_END = INV_START + 26,
HOTBAR_START = INV_END + 1,
HOTBAR_END = HOTBAR_START + 8;
private final IItemHandler bagInventory; private final IItemHandler bagInventory;
private static final int INV_START = ItemRandomizerBag.INV_SIZE, INV_END = INV_START + 26, public RandomizerBagContainer(ContainerType<?> type, int id){
HOTBAR_START = INV_END + 1, HOTBAR_END = HOTBAR_START + 8; super(type, id);
bagInventory = null;
}
//Client
public RandomizerBagContainer(int id, PlayerInventory playerInventory, PacketBuffer packetBuffer) {
this(id, playerInventory);
}
//Server?
public RandomizerBagContainer(int containerId, PlayerInventory playerInventory) { public RandomizerBagContainer(int containerId, PlayerInventory playerInventory) {
this(containerId, playerInventory, new ItemStackHandler(ItemRandomizerBag.INV_SIZE)); this(containerId, playerInventory, new ItemStackHandler(RandomizerBagItem.INV_SIZE));
} }
public RandomizerBagContainer(int containerId, PlayerInventory playerInventory, IItemHandler inventory) { public RandomizerBagContainer(int containerId, PlayerInventory playerInventory, IItemHandler inventory) {
super(EffortlessBuilding.RANDOMIZER_BAG_CONTAINER, containerId); super(EffortlessBuilding.RANDOMIZER_BAG_CONTAINER.get(), containerId);
bagInventory = inventory; bagInventory = inventory;
for (int i = 0; i < ItemRandomizerBag.INV_SIZE; ++i) { for (int i = 0; i < RandomizerBagItem.INV_SIZE; ++i) {
this.addSlot(new SlotItemHandler(bagInventory, i, 44 + (18 * i), 20)); this.addSlot(new SlotItemHandler(bagInventory, i, 44 + (18 * i), 20));
} }
// add player inventory slots // add player inventory slots
int i; for (int i = 0; i < 3; ++i) {
for (i = 0; i < 3; ++i) {
for (int j = 0; j < 9; ++j) { for (int j = 0; j < 9; ++j) {
addSlot(new Slot(playerInventory, j + i * 9 + 9, 8 + j * 18, 51 + i * 18)); addSlot(new Slot(playerInventory, j + i * 9 + 9, 8 + j * 18, 51 + i * 18));
} }
} }
// add hotbar slots // add hotbar slots
for (i = 0; i < 9; ++i) { for (int i = 0; i < 9; ++i) {
addSlot(new Slot(playerInventory, i, 8 + i * 18, 109)); addSlot(new Slot(playerInventory, i, 8 + i * 18, 109));
} }
} }
@Override @Override
public boolean canInteractWith(PlayerEntity playerIn) { public boolean stillValid(PlayerEntity playerIn) {
return true; return true;
} }
@Override @Override
public Slot getSlot(int parSlotIndex) public Slot getSlot(int parSlotIndex) {
{ if (parSlotIndex >= slots.size())
if(parSlotIndex >= inventorySlots.size()) parSlotIndex = slots.size() - 1;
parSlotIndex = inventorySlots.size() - 1;
return super.getSlot(parSlotIndex); return super.getSlot(parSlotIndex);
} }
@Override @Override
public ItemStack transferStackInSlot(PlayerEntity playerIn, int slotIndex) { public ItemStack quickMoveStack(PlayerEntity playerIn, int slotIndex) {
ItemStack itemstack = ItemStack.EMPTY; ItemStack itemstack = ItemStack.EMPTY;
Slot slot = this.inventorySlots.get(slotIndex); Slot slot = this.slots.get(slotIndex);
if (slot != null && slot.getHasStack()) { if (slot != null && slot.hasItem()) {
ItemStack itemstack1 = slot.getStack(); ItemStack itemstack1 = slot.getItem();
itemstack = itemstack1.copy(); itemstack = itemstack1.copy();
// If item is in our custom inventory // If item is in our custom inventory
if (slotIndex < INV_START) { if (slotIndex < INV_START) {
// try to place in player inventory / action bar // try to place in player inventory / action bar
if (!this.mergeItemStack(itemstack1, INV_START, HOTBAR_END + 1, true)) { if (!this.moveItemStackTo(itemstack1, INV_START, HOTBAR_END + 1, true)) {
return ItemStack.EMPTY; return ItemStack.EMPTY;
} }
slot.onSlotChange(itemstack1, itemstack); slot.onQuickCraft(itemstack1, itemstack);
} }
// Item is in inventory / hotbar, try to place in custom inventory or armor slots // Item is in inventory / hotbar, try to place in custom inventory or armor slots
else { else {
@@ -86,17 +96,16 @@ public class RandomizerBagContainer extends Container {
*/ */
if (slotIndex >= INV_START) { if (slotIndex >= INV_START) {
// place in custom inventory // place in custom inventory
if (!this.mergeItemStack(itemstack1, 0, INV_START, false)) { if (!this.moveItemStackTo(itemstack1, 0, INV_START, false)) {
return ItemStack.EMPTY; return ItemStack.EMPTY;
} }
} }
} }
if (itemstack1.getCount() == 0) { if (itemstack1.getCount() == 0) {
slot.putStack(ItemStack.EMPTY); slot.set(ItemStack.EMPTY);
} else { } else {
slot.onSlotChanged(); slot.setChanged();
} }
if (itemstack1.getCount() == itemstack.getCount()) { if (itemstack1.getCount() == itemstack.getCount()) {
@@ -113,26 +122,26 @@ public class RandomizerBagContainer extends Container {
* You should override this method to prevent the player from moving the stack that * You should override this method to prevent the player from moving the stack that
* opened the inventory, otherwise if the player moves it, the inventory will not * opened the inventory, otherwise if the player moves it, the inventory will not
* be able to save properly * be able to save properly
* @return
*/ */
@Override @Override
public ItemStack slotClick(int slot, int dragType, ClickType clickTypeIn, PlayerEntity player) { public ItemStack clicked(int slot, int dragType, ClickType clickTypeIn, PlayerEntity player) {
// this will prevent the player from interacting with the item that opened the inventory: // this will prevent the player from interacting with the item that opened the inventory:
if (slot >= 0 && getSlot(slot) != null && getSlot(slot).getStack().equals(player.getHeldItem(Hand.MAIN_HAND))) { if (slot >= 0 && getSlot(slot) != null && getSlot(slot).getItem().equals(player.getItemInHand(Hand.MAIN_HAND))) {
//Do nothing;
return ItemStack.EMPTY; return ItemStack.EMPTY;
} }
return super.slotClick(slot, dragType, clickTypeIn, player); return super.clicked(slot, dragType, clickTypeIn, player);
} }
/** /**
* Callback for when the crafting gui is closed. * Callback for when the crafting gui is closed.
*/ */
@Override @Override
public void onContainerClosed(PlayerEntity player) public void removed(PlayerEntity player) {
{ super.removed(player);
super.onContainerClosed(player); if (!player.level.isClientSide) {
if(!player.world.isRemote) broadcastChanges();
{
detectAndSendChanges();
} }
} }
} }

View File

@@ -1,45 +1,47 @@
package nl.requios.effortlessbuilding.gui; package nl.requios.effortlessbuilding.gui;
import com.mojang.blaze3d.platform.GlStateManager; import com.mojang.blaze3d.matrix.MatrixStack;
import com.mojang.blaze3d.systems.RenderSystem;
import net.minecraft.client.gui.screen.inventory.ContainerScreen; import net.minecraft.client.gui.screen.inventory.ContainerScreen;
import net.minecraft.entity.player.PlayerInventory; import net.minecraft.entity.player.PlayerInventory;
import net.minecraft.util.ResourceLocation; import net.minecraft.util.ResourceLocation;
import net.minecraft.util.text.ITextComponent; import net.minecraft.util.text.ITextComponent;
import net.minecraft.util.text.TranslationTextComponent;
import net.minecraftforge.api.distmarker.Dist; import net.minecraftforge.api.distmarker.Dist;
import net.minecraftforge.api.distmarker.OnlyIn; import net.minecraftforge.api.distmarker.OnlyIn;
import net.minecraftforge.items.IItemHandler;
import nl.requios.effortlessbuilding.EffortlessBuilding; import nl.requios.effortlessbuilding.EffortlessBuilding;
import javax.annotation.ParametersAreNonnullByDefault;
@OnlyIn(Dist.CLIENT) @OnlyIn(Dist.CLIENT)
@ParametersAreNonnullByDefault
public class RandomizerBagScreen extends ContainerScreen<RandomizerBagContainer> { public class RandomizerBagScreen extends ContainerScreen<RandomizerBagContainer> {
private static final ResourceLocation guiTextures = private static final ResourceLocation guiTextures =
new ResourceLocation(EffortlessBuilding.MODID, "textures/gui/container/randomizerbag.png"); new ResourceLocation(EffortlessBuilding.MODID, "textures/gui/container/randomizerbag.png");
public RandomizerBagScreen(RandomizerBagContainer randomizerBagContainer, PlayerInventory playerInventory, ITextComponent title) { public RandomizerBagScreen(RandomizerBagContainer randomizerBagContainer, PlayerInventory playerInventory, ITextComponent title) {
super(randomizerBagContainer, playerInventory, title);//new TranslationTextComponent("effortlessbuilding.screen.randomizer_bag")); super(randomizerBagContainer, playerInventory, title);//new TranslationTextComponent("effortlessbuilding.screen.randomizer_bag"));
ySize = 134; imageHeight = 134;
} }
@Override @Override
public void render(int mouseX, int mouseY, float partialTicks) { public void render(MatrixStack ms, int mouseX, int mouseY, float partialTicks) {
renderBackground(); renderBackground(ms);
super.render(mouseX, mouseY, partialTicks); super.render(ms, mouseX, mouseY, partialTicks);
this.renderHoveredToolTip(mouseX, mouseY); this.renderTooltip(ms, mouseX, mouseY);
} }
@Override @Override
protected void drawGuiContainerForegroundLayer(int mouseX, int mouseY) { protected void renderLabels(MatrixStack ms, int mouseX, int mouseY) {
font.drawString(this.title.getFormattedText(), 8, 6, 0x404040); font.draw(ms, this.title, 8, 6, 0x404040);
font.drawString(playerInventory.getDisplayName().getFormattedText(), 8, ySize - 96 + 2, 0x404040); font.draw(ms, inventory.getDisplayName(), 8, imageHeight - 96 + 2, 0x404040);
} }
@Override @Override
protected void drawGuiContainerBackgroundLayer(float partialTicks, int mouseX, int mouseY) { protected void renderBg(MatrixStack ms, float partialTicks, int mouseX, int mouseY) {
GlStateManager.color3f(1.0F, 1.0F, 1.0F); RenderSystem.color3f(1.0F, 1.0F, 1.0F);
minecraft.getTextureManager().bindTexture(guiTextures); minecraft.getTextureManager().bind(guiTextures);
int marginHorizontal = (width - xSize) / 2; int marginHorizontal = (width - imageWidth) / 2;
int marginVertical = (height - ySize) / 2; int marginVertical = (height - imageHeight) / 2;
blit(marginHorizontal, marginVertical, 0, 0, xSize, ySize); blit(ms, marginHorizontal, marginVertical, 0, 0, imageWidth, imageHeight);
} }
} }

View File

@@ -0,0 +1,311 @@
package nl.requios.effortlessbuilding.gui.buildmode;
import com.mojang.blaze3d.matrix.MatrixStack;
import com.mojang.blaze3d.platform.GlStateManager;
import com.mojang.blaze3d.systems.RenderSystem;
import mcp.MethodsReturnNonnullByDefault;
import net.minecraft.client.Minecraft;
import net.minecraft.client.audio.SimpleSound;
import net.minecraft.client.gui.screen.Screen;
import net.minecraft.client.gui.widget.button.Button;
import net.minecraft.client.gui.widget.list.ExtendedList;
import net.minecraft.client.renderer.BufferBuilder;
import net.minecraft.client.renderer.Tessellator;
import net.minecraft.client.renderer.vertex.DefaultVertexFormats;
import net.minecraft.util.SoundEvents;
import net.minecraft.util.math.MathHelper;
import net.minecraft.util.text.ITextComponent;
import net.minecraft.util.text.StringTextComponent;
import net.minecraft.util.text.TranslationTextComponent;
import net.minecraftforge.api.distmarker.Dist;
import net.minecraftforge.api.distmarker.OnlyIn;
import net.minecraftforge.fml.client.gui.widget.ExtendedButton;
import net.minecraftforge.fml.client.gui.widget.Slider;
import nl.requios.effortlessbuilding.EffortlessBuilding;
import javax.annotation.ParametersAreNonnullByDefault;
@ParametersAreNonnullByDefault
@MethodsReturnNonnullByDefault
public class PlayerSettingsGui extends Screen {
protected int left, right, top, bottom;
protected boolean showShaderList = false;
private Button shaderTypeButton;
private ShaderTypeList shaderTypeList;
private Button closeButton;
public PlayerSettingsGui() {
super(new TranslationTextComponent("effortlessbuilding.screen.player_settings"));
}
@Override
protected void init() {
left = this.width / 2 - 140;
right = this.width / 2 + 140;
top = this.height / 2 - 100;
bottom = this.height / 2 + 100;
int yy = top;
shaderTypeList = new ShaderTypeList(this.minecraft);
this.children.add(shaderTypeList);
//TODO set selected name
ITextComponent currentShaderName = ShaderType.DISSOLVE_BLUE.name;
shaderTypeButton = new ExtendedButton(right - 180, yy, 180, 20, currentShaderName, (button) -> {
showShaderList = !showShaderList;
});
addButton(shaderTypeButton);
yy += 50;
Slider slider = new Slider(right - 200, yy, 200, 20, StringTextComponent.EMPTY, StringTextComponent.EMPTY, 0.5, 2.0, 1.0, true, true, (button) -> {
});
addButton(slider);
closeButton = new ExtendedButton(left + 50, bottom - 20, 180, 20, new StringTextComponent("Done"), (button) -> this.minecraft.player.closeContainer());
addButton(closeButton);
}
@Override
public void tick() {
super.tick();
}
@Override
public void render(MatrixStack ms, int mouseX, int mouseY, float partialTicks) {
this.renderBackground(ms);
int yy = top;
font.draw(ms, "Shader type", left, yy + 5, 0xFFFFFF);
yy += 50;
font.draw(ms, "Shader speed", left, yy + 5, 0xFFFFFF);
super.render(ms, mouseX, mouseY, partialTicks);
if (showShaderList)
this.shaderTypeList.render(ms, mouseX, mouseY, partialTicks);
}
@Override
public boolean mouseClicked(double mouseX, double mouseY, int mouseButton) {
super.mouseClicked(mouseX, mouseY, mouseButton);
if (showShaderList) {
if (!shaderTypeList.isMouseOver(mouseX, mouseY) && !shaderTypeButton.isMouseOver(mouseX, mouseY))
showShaderList = false;
}
return true;
}
@Override
public void removed() {
ShaderTypeList.ShaderTypeEntry selectedShader = shaderTypeList.getSelected();
//TODO save and remove
}
public enum ShaderType {
DISSOLVE_BLUE("Dissolve Blue"),
DISSOLVE_ORANGE("Dissolve Orange");
public ITextComponent name;
ShaderType(ITextComponent name) {
this.name = name;
}
ShaderType(String name) {
this.name = new StringTextComponent(name);
}
}
//Inspired by LanguageScreen
@OnlyIn(Dist.CLIENT)
class ShaderTypeList extends ExtendedList<PlayerSettingsGui.ShaderTypeList.ShaderTypeEntry> {
public ShaderTypeList(Minecraft mcIn) {
super(mcIn, 180, 140, top + 20, top + 100, 18);
this.setLeftPos(right - width);
for (int i = 0; i < 40; i++) {
for (ShaderType shaderType : ShaderType.values()) {
ShaderTypeEntry shaderTypeEntry = new ShaderTypeEntry(shaderType);
addEntry(shaderTypeEntry);
//TODO setSelected to this if appropriate
}
}
if (this.getSelected() != null) {
this.centerScrollOn(this.getSelected());
}
}
@Override
public int getRowWidth() {
return width;
}
@Override
public void setSelected(PlayerSettingsGui.ShaderTypeList.ShaderTypeEntry selected) {
super.setSelected(selected);
Minecraft.getInstance().getSoundManager().play(SimpleSound.forUI(SoundEvents.UI_BUTTON_CLICK, 1.0F));
EffortlessBuilding.log("Selected shader " + selected.shaderType.name);
shaderTypeButton.setMessage(selected.shaderType.name);
// showShaderList = false;
}
@Override
public boolean mouseClicked(double p_mouseClicked_1_, double p_mouseClicked_3_, int p_mouseClicked_5_) {
if (!showShaderList) return false;
return super.mouseClicked(p_mouseClicked_1_, p_mouseClicked_3_, p_mouseClicked_5_);
}
@Override
public boolean mouseReleased(double p_mouseReleased_1_, double p_mouseReleased_3_, int p_mouseReleased_5_) {
if (!showShaderList) return false;
return super.mouseReleased(p_mouseReleased_1_, p_mouseReleased_3_, p_mouseReleased_5_);
}
@Override
public boolean mouseDragged(double p_mouseDragged_1_, double p_mouseDragged_3_, int p_mouseDragged_5_, double p_mouseDragged_6_, double p_mouseDragged_8_) {
if (!showShaderList) return false;
return super.mouseDragged(p_mouseDragged_1_, p_mouseDragged_3_, p_mouseDragged_5_, p_mouseDragged_6_, p_mouseDragged_8_);
}
@Override
public boolean mouseScrolled(double p_mouseScrolled_1_, double p_mouseScrolled_3_, double p_mouseScrolled_5_) {
if (!showShaderList) return false;
return super.mouseScrolled(p_mouseScrolled_1_, p_mouseScrolled_3_, p_mouseScrolled_5_);
}
@Override
public boolean isMouseOver(double p_isMouseOver_1_, double p_isMouseOver_3_) {
if (!showShaderList) return false;
return super.isMouseOver(p_isMouseOver_1_, p_isMouseOver_3_);
}
protected boolean isFocused() {
return PlayerSettingsGui.this.getFocused() == this;
}
@Override
protected int getScrollbarPosition() {
return right - 6;
}
//From AbstractList, disabled parts
@Override
public void render(MatrixStack ms, int p_render_1_, int p_render_2_, float p_render_3_) {
this.renderBackground(ms);
int i = this.getScrollbarPosition();
int j = i + 6;
Tessellator tessellator = Tessellator.getInstance();
BufferBuilder bufferbuilder = tessellator.getBuilder();
// this.minecraft.getTextureManager().bindTexture(AbstractGui.BACKGROUND_LOCATION);
RenderSystem.enableBlend();
RenderSystem.blendFuncSeparate(GlStateManager.SourceFactor.SRC_ALPHA, GlStateManager.DestFactor.ONE_MINUS_SRC_ALPHA, GlStateManager.SourceFactor.ZERO, GlStateManager.DestFactor.ONE);
RenderSystem.color4f(1.0F, 1.0F, 1.0F, 1.0F);
float f = 32.0F;
bufferbuilder.begin(7, DefaultVertexFormats.POSITION_COLOR);
bufferbuilder.vertex(this.x0, this.y1, 0.0D).color(20, 20, 20, 180).endVertex();
bufferbuilder.vertex(this.x1, this.y1, 0.0D).color(20, 20, 20, 180).endVertex();
bufferbuilder.vertex(this.x1, this.y0, 0.0D).color(20, 20, 20, 180).endVertex();
bufferbuilder.vertex(this.x0, this.y0, 0.0D).color(20, 20, 20, 180).endVertex();
tessellator.end();
int k = this.getRowLeft();
int l = this.y0 + 4 - (int) this.getScrollAmount();
if (this.renderHeader) {
this.renderHeader(ms, k, l, tessellator);
}
this.renderList(ms, k, l, p_render_1_, p_render_2_, p_render_3_);
RenderSystem.disableDepthTest();
// this.renderHoleBackground(0, this.y0, 255, 255);
// this.renderHoleBackground(this.y1, this.height, 255, 255);
RenderSystem.enableBlend();
RenderSystem.blendFuncSeparate(GlStateManager.SourceFactor.SRC_ALPHA, GlStateManager.DestFactor.ONE_MINUS_SRC_ALPHA, GlStateManager.SourceFactor.ZERO, GlStateManager.DestFactor.ONE);
RenderSystem.disableAlphaTest();
RenderSystem.shadeModel(7425);
RenderSystem.disableTexture();
// int i1 = 4;
// bufferbuilder.begin(7, DefaultVertexFormats.POSITION_TEX_COLOR);
// bufferbuilder.pos((double)this.x0, (double)(this.y0 + 4), 0.0D).tex(0.0F, 1.0F).color(0, 0, 0, 0).endVertex();
// bufferbuilder.pos((double)this.x1, (double)(this.y0 + 4), 0.0D).tex(1.0F, 1.0F).color(0, 0, 0, 0).endVertex();
// bufferbuilder.pos((double)this.x1, (double)this.y0, 0.0D).tex(1.0F, 0.0F).color(0, 0, 0, 255).endVertex();
// bufferbuilder.pos((double)this.x0, (double)this.y0, 0.0D).tex(0.0F, 0.0F).color(0, 0, 0, 255).endVertex();
// tessellator.draw();
// bufferbuilder.begin(7, DefaultVertexFormats.POSITION_TEX_COLOR);
// bufferbuilder.pos((double)this.x0, (double)this.y1, 0.0D).tex(0.0F, 1.0F).color(0, 0, 0, 255).endVertex();
// bufferbuilder.pos((double)this.x1, (double)this.y1, 0.0D).tex(1.0F, 1.0F).color(0, 0, 0, 255).endVertex();
// bufferbuilder.pos((double)this.x1, (double)(this.y1 - 4), 0.0D).tex(1.0F, 0.0F).color(0, 0, 0, 0).endVertex();
// bufferbuilder.pos((double)this.x0, (double)(this.y1 - 4), 0.0D).tex(0.0F, 0.0F).color(0, 0, 0, 0).endVertex();
// tessellator.draw();
//SCROLLBAR
int j1 = this.getMaxScroll();
if (j1 > 0) {
int k1 = (int) ((float) ((this.y1 - this.y0) * (this.y1 - this.y0)) / (float) this.getMaxPosition());
k1 = MathHelper.clamp(k1, 32, this.y1 - this.y0 - 8);
int l1 = (int) this.getScrollAmount() * (this.y1 - this.y0 - k1) / j1 + this.y0;
if (l1 < this.y0) {
l1 = this.y0;
}
bufferbuilder.begin(7, DefaultVertexFormats.POSITION_TEX_COLOR);
bufferbuilder.vertex(i, this.y1, 0.0D).uv(0.0F, 1.0F).color(0, 0, 0, 255).endVertex();
bufferbuilder.vertex(j, this.y1, 0.0D).uv(1.0F, 1.0F).color(0, 0, 0, 255).endVertex();
bufferbuilder.vertex(j, this.y0, 0.0D).uv(1.0F, 0.0F).color(0, 0, 0, 255).endVertex();
bufferbuilder.vertex(i, this.y0, 0.0D).uv(0.0F, 0.0F).color(0, 0, 0, 255).endVertex();
tessellator.end();
bufferbuilder.begin(7, DefaultVertexFormats.POSITION_TEX_COLOR);
bufferbuilder.vertex(i, l1 + k1, 0.0D).uv(0.0F, 1.0F).color(128, 128, 128, 255).endVertex();
bufferbuilder.vertex(j, l1 + k1, 0.0D).uv(1.0F, 1.0F).color(128, 128, 128, 255).endVertex();
bufferbuilder.vertex(j, l1, 0.0D).uv(1.0F, 0.0F).color(128, 128, 128, 255).endVertex();
bufferbuilder.vertex(i, l1, 0.0D).uv(0.0F, 0.0F).color(128, 128, 128, 255).endVertex();
tessellator.end();
bufferbuilder.begin(7, DefaultVertexFormats.POSITION_TEX_COLOR);
bufferbuilder.vertex(i, l1 + k1 - 1, 0.0D).uv(0.0F, 1.0F).color(192, 192, 192, 255).endVertex();
bufferbuilder.vertex(j - 1, l1 + k1 - 1, 0.0D).uv(1.0F, 1.0F).color(192, 192, 192, 255).endVertex();
bufferbuilder.vertex(j - 1, l1, 0.0D).uv(1.0F, 0.0F).color(192, 192, 192, 255).endVertex();
bufferbuilder.vertex(i, l1, 0.0D).uv(0.0F, 0.0F).color(192, 192, 192, 255).endVertex();
tessellator.end();
}
// this.renderDecorations(p_render_1_, p_render_2_);
RenderSystem.enableTexture();
RenderSystem.shadeModel(7424);
RenderSystem.enableAlphaTest();
RenderSystem.disableBlend();
}
public int getMaxScroll() {
return Math.max(0, this.getMaxPosition() - (this.y1 - this.y0 - 4));
}
@OnlyIn(Dist.CLIENT)
public class ShaderTypeEntry extends ExtendedList.AbstractListEntry<ShaderTypeEntry> {
private final ShaderType shaderType;
public ShaderTypeEntry(ShaderType shaderType) {
this.shaderType = shaderType;
}
@Override
public void render(MatrixStack ms, int itemIndex, int rowTop, int rowLeft, int rowWidth, int rowHeight, int mouseX, int mouseY, boolean hovered, float partialTicks) {
if (rowTop + 10 > ShaderTypeList.this.y0 && rowTop + rowHeight - 5 < ShaderTypeList.this.y1)
drawString(ms, font, shaderType.name, ShaderTypeList.this.x0 + 8, rowTop + 4, 0xFFFFFF);
}
@Override
public boolean mouseClicked(double p_mouseClicked_1_, double p_mouseClicked_3_, int p_mouseClicked_5_) {
if (p_mouseClicked_5_ == 0) {
setSelected(this);
return true;
} else {
return false;
}
}
}
}
}

View File

@@ -1,95 +1,543 @@
package nl.requios.effortlessbuilding.gui.buildmode; package nl.requios.effortlessbuilding.gui.buildmode;
import java.util.ArrayList; import com.mojang.blaze3d.matrix.MatrixStack;
import java.util.concurrent.TimeUnit; import com.mojang.blaze3d.systems.RenderSystem;
import mcp.MethodsReturnNonnullByDefault;
import com.mojang.blaze3d.platform.GlStateManager; import net.minecraft.client.Minecraft;
import net.minecraft.client.audio.SimpleSound;
import net.minecraft.client.gui.screen.Screen; import net.minecraft.client.gui.screen.Screen;
import net.minecraft.client.renderer.BufferBuilder;
import net.minecraft.client.renderer.Tessellator;
import net.minecraft.client.renderer.texture.AtlasTexture;
import net.minecraft.client.renderer.texture.TextureAtlasSprite;
import net.minecraft.client.renderer.vertex.DefaultVertexFormats;
import net.minecraft.client.resources.I18n; import net.minecraft.client.resources.I18n;
import net.minecraft.client.settings.KeyBinding;
import net.minecraft.entity.player.PlayerEntity;
import net.minecraft.util.Direction; import net.minecraft.util.Direction;
import net.minecraft.util.text.ITextComponent; import net.minecraft.util.SoundCategory;
import net.minecraft.util.SoundEvents;
import net.minecraft.util.math.vector.Vector4f;
import net.minecraft.util.text.TextFormatting; import net.minecraft.util.text.TextFormatting;
import net.minecraft.util.text.TranslationTextComponent; import net.minecraft.util.text.TranslationTextComponent;
import nl.requios.effortlessbuilding.EffortlessBuilding; import nl.requios.effortlessbuilding.EffortlessBuilding;
import nl.requios.effortlessbuilding.ModClientEventHandler; import nl.requios.effortlessbuilding.ModClientEventHandler;
import nl.requios.effortlessbuilding.ModEventHandler; import nl.requios.effortlessbuilding.buildmode.ModeOptions;
import nl.requios.effortlessbuilding.buildmode.ModeSettingsManager; import nl.requios.effortlessbuilding.buildmode.ModeSettingsManager;
import nl.requios.effortlessbuilding.network.ModeActionMessage;
import nl.requios.effortlessbuilding.network.ModeSettingsMessage;
import nl.requios.effortlessbuilding.network.PacketHandler;
import nl.requios.effortlessbuilding.proxy.ClientProxy; import nl.requios.effortlessbuilding.proxy.ClientProxy;
import org.apache.commons.lang3.text.WordUtils; import org.apache.commons.lang3.text.WordUtils;
import org.lwjgl.opengl.GL11; import org.lwjgl.opengl.GL11;
import com.google.common.base.Stopwatch; import javax.annotation.ParametersAreNonnullByDefault;
import java.util.ArrayList;
import net.minecraft.client.Minecraft;
import net.minecraft.client.renderer.BufferBuilder;
import net.minecraft.client.renderer.Tessellator;
import net.minecraft.client.renderer.texture.TextureAtlasSprite;
import net.minecraft.client.renderer.vertex.DefaultVertexFormats;
import static nl.requios.effortlessbuilding.buildmode.BuildModes.*;
import static nl.requios.effortlessbuilding.buildmode.ModeOptions.*; import static nl.requios.effortlessbuilding.buildmode.ModeOptions.*;
import nl.requios.effortlessbuilding.buildmode.BuildModes.BuildModeEnum;
import nl.requios.effortlessbuilding.buildmode.ModeOptions.ActionEnum;
import nl.requios.effortlessbuilding.buildmode.ModeOptions.OptionEnum;
/** /**
* From Chisels and Bits by AlgorithmX2 * Initially from Chisels and Bits by AlgorithmX2
* https://github.com/AlgorithmX2/Chisels-and-Bits/blob/1.12/src/main/java/mod/chiselsandbits/client/gui/ChiselsAndBitsMenu.java * <a href="https://github.com/AlgorithmX2/Chisels-and-Bits/blob/1.12/src/main/java/mod/chiselsandbits/client/gui/ChiselsAndBitsMenu.java">Link</a>
*/ */
@ParametersAreNonnullByDefault
@MethodsReturnNonnullByDefault
public class RadialMenu extends Screen { public class RadialMenu extends Screen {
private final float TIME_SCALE = 0.01f;
public static final RadialMenu instance = new RadialMenu(); public static final RadialMenu instance = new RadialMenu();
private float visibility = 0.0f; private final Vector4f radialButtonColor = new Vector4f(0f, 0f, 0f, .5f);
private Stopwatch lastChange = Stopwatch.createStarted(); private final Vector4f sideButtonColor = new Vector4f(.5f, .5f, .5f, .5f);
private final Vector4f highlightColor = new Vector4f(.6f, .8f, 1f, .6f);
private final Vector4f selectedColor = new Vector4f(0f, .5f, 1f, .5f);
private final Vector4f highlightSelectedColor = new Vector4f(0.2f, .7f, 1f, .7f);
private final int whiteTextColor = 0xffffffff;
private final int watermarkTextColor = 0x88888888;
private final int descriptionTextColor = 0xdd888888;
private final int optionTextColor = 0xeeeeeeff;
private final double ringInnerEdge = 30;
private final double ringOuterEdge = 65;
private final double categoryLineWidth = 1;
private final double textDistance = 75;
private final double buttonDistance = 105;
private final float fadeSpeed = 0.3f;
private final int descriptionHeight = 100;
public BuildModeEnum switchTo = null; public BuildModeEnum switchTo = null;
public ActionEnum doAction = null; public ActionEnum doAction = null;
public boolean actionUsed = false; public boolean performedActionUsingMouse;
private float visibility;
public RadialMenu() { public RadialMenu() {
super(new TranslationTextComponent("effortlessbuilding.screen.radial_menu")); super(new TranslationTextComponent("effortlessbuilding.screen.radial_menu"));
} }
private float clampVis(final float f) {
return Math.max( 0.0f, Math.min( 1.0f, f ) );
}
public void raiseVisibility() {
visibility = clampVis( visibility + lastChange.elapsed( TimeUnit.MILLISECONDS ) * TIME_SCALE );
lastChange = Stopwatch.createStarted();
}
public void decreaseVisibility() {
visibility = clampVis( visibility - lastChange.elapsed( TimeUnit.MILLISECONDS ) * TIME_SCALE );
lastChange = Stopwatch.createStarted();
}
public void setVisibility(float visibility) {
this.visibility = visibility;
}
public boolean isVisible() { public boolean isVisible() {
return visibility > 0.001; return Minecraft.getInstance().screen instanceof RadialMenu;
} }
public void configure(final int scaledWidth, final int scaledHeight ) { @Override
protected void init() {
super.init();
performedActionUsingMouse = false;
visibility = 0f;
}
@Override
public void tick() {
super.tick();
if (!ClientProxy.isKeybindDown(2)) {
onClose();
}
}
@Override
public void render(MatrixStack ms, final int mouseX, final int mouseY, final float partialTicks) {
BuildModeEnum currentBuildMode = ModeSettingsManager.getModeSettings(minecraft.player).getBuildMode();
RenderSystem.pushMatrix();
RenderSystem.translatef(0.0F, 0.0F, 200.0F);
visibility += fadeSpeed * partialTicks;
if (visibility > 1f) visibility = 1f;
final int startColor = (int) (visibility * 98) << 24;
final int endColor = (int) (visibility * 128) << 24;
fillGradient(ms, 0, 0, width, height, startColor, endColor);
RenderSystem.disableTexture();
RenderSystem.enableBlend();
RenderSystem.disableAlphaTest();
RenderSystem.blendFuncSeparate(GL11.GL_SRC_ALPHA, GL11.GL_ONE_MINUS_SRC_ALPHA, 1, 0);
RenderSystem.shadeModel(GL11.GL_SMOOTH);
final Tessellator tessellator = Tessellator.getInstance();
final BufferBuilder buffer = tessellator.getBuilder();
buffer.begin(GL11.GL_QUADS, DefaultVertexFormats.POSITION_COLOR);
final double middleX = width / 2.0;
final double middleY = height / 2.0;
//Fix for high def (retina) displays: use custom mouse coordinates
//Borrowed from GameRenderer::updateCameraAndRender
Minecraft mc = Minecraft.getInstance(); Minecraft mc = Minecraft.getInstance();
font = mc.fontRenderer; int mouseXX = (int) (mc.mouseHandler.xpos() * (double) mc.getWindow().getGuiScaledWidth() / (double) mc.getWindow().getScreenWidth());
width = scaledWidth; int mouseYY = (int) (mc.mouseHandler.ypos() * (double) mc.getWindow().getGuiScaledHeight() / (double) mc.getWindow().getScreenHeight());
height = scaledHeight;
final double mouseXCenter = mouseXX - middleX;
final double mouseYCenter = mouseYY - middleY;
double mouseRadians = Math.atan2(mouseYCenter, mouseXCenter);
final double quarterCircle = Math.PI / 2.0;
if (mouseRadians < -quarterCircle) {
mouseRadians = mouseRadians + Math.PI * 2;
}
final ArrayList<MenuRegion> modes = new ArrayList<MenuRegion>();
final ArrayList<MenuButton> buttons = new ArrayList<MenuButton>();
//Add build modes
for (final BuildModeEnum mode : BuildModeEnum.values()) {
modes.add(new MenuRegion(mode));
}
//Add actions
buttons.add(new MenuButton(ActionEnum.UNDO.name, ActionEnum.UNDO, -buttonDistance - 26, -13, Direction.UP));
buttons.add(new MenuButton(ActionEnum.REDO.name, ActionEnum.REDO, -buttonDistance, -13, Direction.UP));
// buttons.add(new MenuButton(ActionEnum.OPEN_PLAYER_SETTINGS.name, ActionEnum.OPEN_PLAYER_SETTINGS, -buttonDistance - 26 - 13, 13, Direction.DOWN));
buttons.add(new MenuButton(ActionEnum.OPEN_MODIFIER_SETTINGS.name, ActionEnum.OPEN_MODIFIER_SETTINGS, -buttonDistance - 26, 13, Direction.DOWN));
buttons.add(new MenuButton(ActionEnum.REPLACE.name, ActionEnum.REPLACE, -buttonDistance, 13, Direction.DOWN));
//Add buildmode dependent options
OptionEnum[] options = currentBuildMode.options;
for (int i = 0; i < options.length; i++) {
for (int j = 0; j < options[i].actions.length; j++) {
ActionEnum action = options[i].actions[j];
buttons.add(new MenuButton(action.name, action, buttonDistance + j * 26, -13 + i * 39, Direction.DOWN));
}
}
switchTo = null;
doAction = null;
//Draw buildmode backgrounds
drawRadialButtonBackgrounds(currentBuildMode, buffer, middleX, middleY, mouseXCenter, mouseYCenter, mouseRadians,
quarterCircle, modes);
//Draw action backgrounds
drawSideButtonBackgrounds(buffer, middleX, middleY, mouseXCenter, mouseYCenter, buttons);
tessellator.end();
drawIcons(buffer, middleX, middleY, mc, modes, buttons);
tessellator.end();
drawTexts(ms, currentBuildMode, middleX, middleY, modes, buttons, options);
RenderSystem.popMatrix();
}
private void drawRadialButtonBackgrounds(BuildModeEnum currentBuildMode, BufferBuilder buffer, double middleX, double middleY,
double mouseXCenter, double mouseYCenter, double mouseRadians, double quarterCircle, ArrayList<MenuRegion> modes) {
if (!modes.isEmpty()) {
final int totalModes = Math.max(3, modes.size());
final double fragment = Math.PI * 0.005;
final double fragment2 = Math.PI * 0.0025;
final double perObject = 2.0 * Math.PI / totalModes;
for (int i = 0; i < modes.size(); i++) {
MenuRegion menuRegion = modes.get(i);
final double beginRadians = i * perObject - quarterCircle;
final double endRadians = (i + 1) * perObject - quarterCircle;
menuRegion.x1 = Math.cos(beginRadians);
menuRegion.x2 = Math.cos(endRadians);
menuRegion.y1 = Math.sin(beginRadians);
menuRegion.y2 = Math.sin(endRadians);
final double x1m1 = Math.cos(beginRadians + fragment) * ringInnerEdge;
final double x2m1 = Math.cos(endRadians - fragment) * ringInnerEdge;
final double y1m1 = Math.sin(beginRadians + fragment) * ringInnerEdge;
final double y2m1 = Math.sin(endRadians - fragment) * ringInnerEdge;
final double x1m2 = Math.cos(beginRadians + fragment2) * ringOuterEdge;
final double x2m2 = Math.cos(endRadians - fragment2) * ringOuterEdge;
final double y1m2 = Math.sin(beginRadians + fragment2) * ringOuterEdge;
final double y2m2 = Math.sin(endRadians - fragment2) * ringOuterEdge;
final boolean isSelected = currentBuildMode.ordinal() == i;
final boolean isMouseInQuad = inTriangle(x1m1, y1m1, x2m2, y2m2, x2m1, y2m1, mouseXCenter, mouseYCenter)
|| inTriangle(x1m1, y1m1, x1m2, y1m2, x2m2, y2m2, mouseXCenter, mouseYCenter);
final boolean isHighlighted = beginRadians <= mouseRadians && mouseRadians <= endRadians && isMouseInQuad;
Vector4f color = radialButtonColor;
if (isSelected) color = selectedColor;
if (isHighlighted) color = highlightColor;
if (isSelected && isHighlighted) color = highlightSelectedColor;
if (isHighlighted) {
menuRegion.highlighted = true;
switchTo = menuRegion.mode;
}
buffer.vertex(middleX + x1m1, middleY + y1m1, getBlitOffset()).color(color.x(), color.y(), color.z(), color.w()).endVertex();
buffer.vertex(middleX + x2m1, middleY + y2m1, getBlitOffset()).color(color.x(), color.y(), color.z(), color.w()).endVertex();
buffer.vertex(middleX + x2m2, middleY + y2m2, getBlitOffset()).color(color.x(), color.y(), color.z(), color.w()).endVertex();
buffer.vertex(middleX + x1m2, middleY + y1m2, getBlitOffset()).color(color.x(), color.y(), color.z(), color.w()).endVertex();
//Category line
color = menuRegion.mode.category.color;
final double categoryLineOuterEdge = ringInnerEdge + categoryLineWidth;
final double x1m3 = Math.cos(beginRadians + fragment) * categoryLineOuterEdge;
final double y1m3 = Math.sin(beginRadians + fragment) * categoryLineOuterEdge;
final double x2m3 = Math.cos(endRadians - fragment) * categoryLineOuterEdge;
final double y2m3 = Math.sin(endRadians - fragment) * categoryLineOuterEdge;
buffer.vertex(middleX + x1m1, middleY + y1m1, getBlitOffset()).color(color.x(), color.y(), color.z(), color.w()).endVertex();
buffer.vertex(middleX + x2m1, middleY + y2m1, getBlitOffset()).color(color.x(), color.y(), color.z(), color.w()).endVertex();
buffer.vertex(middleX + x2m3, middleY + y2m3, getBlitOffset()).color(color.x(), color.y(), color.z(), color.w()).endVertex();
buffer.vertex(middleX + x1m3, middleY + y1m3, getBlitOffset()).color(color.x(), color.y(), color.z(), color.w()).endVertex();
}
}
}
private void drawSideButtonBackgrounds(BufferBuilder buffer, double middleX, double middleY, double mouseXCenter, double mouseYCenter, ArrayList<MenuButton> buttons) {
for (final MenuButton btn : buttons) {
final boolean isSelected =
btn.action == getBuildSpeed() ||
btn.action == getFill() ||
btn.action == getCubeFill() ||
btn.action == getRaisedEdge() ||
btn.action == getLineThickness() ||
btn.action == getCircleStart();
final boolean isHighlighted = btn.x1 <= mouseXCenter && btn.x2 >= mouseXCenter && btn.y1 <= mouseYCenter && btn.y2 >= mouseYCenter;
Vector4f color = sideButtonColor;
if (isSelected) color = selectedColor;
if (isHighlighted) color = highlightColor;
if (isSelected && isHighlighted) color = highlightSelectedColor;
if (isHighlighted) {
btn.highlighted = true;
doAction = btn.action;
}
buffer.vertex(middleX + btn.x1, middleY + btn.y1, getBlitOffset()).color(color.x(), color.y(), color.z(), color.w()).endVertex();
buffer.vertex(middleX + btn.x1, middleY + btn.y2, getBlitOffset()).color(color.x(), color.y(), color.z(), color.w()).endVertex();
buffer.vertex(middleX + btn.x2, middleY + btn.y2, getBlitOffset()).color(color.x(), color.y(), color.z(), color.w()).endVertex();
buffer.vertex(middleX + btn.x2, middleY + btn.y1, getBlitOffset()).color(color.x(), color.y(), color.z(), color.w()).endVertex();
}
}
private void drawIcons(BufferBuilder buffer, double middleX, double middleY, Minecraft mc, ArrayList<MenuRegion> modes, ArrayList<MenuButton> buttons) {
RenderSystem.shadeModel(GL11.GL_FLAT);
RenderSystem.translatef(0f, 0f, 5f);
RenderSystem.enableTexture();
RenderSystem.color3f(1f, 1f, 1f);
RenderSystem.disableBlend();
RenderSystem.enableAlphaTest();
mc.getTextureManager().bind(AtlasTexture.LOCATION_BLOCKS);
buffer.begin(GL11.GL_QUADS, DefaultVertexFormats.POSITION_TEX_COLOR);
//Draw buildmode icons
for (final MenuRegion menuRegion : modes) {
final double x = (menuRegion.x1 + menuRegion.x2) * 0.5 * (ringOuterEdge * 0.55 + 0.45 * ringInnerEdge);
final double y = (menuRegion.y1 + menuRegion.y2) * 0.5 * (ringOuterEdge * 0.55 + 0.45 * ringInnerEdge);
final TextureAtlasSprite sprite = ModClientEventHandler.getBuildModeIcon(menuRegion.mode);
final double x1 = x - 8;
final double x2 = x + 8;
final double y1 = y - 8;
final double y2 = y + 8;
final float f = 1f;
final float a = 1f;
final double u1 = 0;
final double u2 = 16;
final double v1 = 0;
final double v2 = 16;
buffer.vertex(middleX + x1, middleY + y1, getBlitOffset()).uv(sprite.getU(u1), sprite.getV(v1)).color(f, f, f, a).endVertex();
buffer.vertex(middleX + x1, middleY + y2, getBlitOffset()).uv(sprite.getU(u1), sprite.getV(v2)).color(f, f, f, a).endVertex();
buffer.vertex(middleX + x2, middleY + y2, getBlitOffset()).uv(sprite.getU(u2), sprite.getV(v2)).color(f, f, f, a).endVertex();
buffer.vertex(middleX + x2, middleY + y1, getBlitOffset()).uv(sprite.getU(u2), sprite.getV(v1)).color(f, f, f, a).endVertex();
}
//Draw action icons
for (final MenuButton button : buttons) {
final float f = 1f;
final float a = 1f;
final double u1 = 0;
final double u2 = 16;
final double v1 = 0;
final double v2 = 16;
final TextureAtlasSprite sprite = ModClientEventHandler.getModeOptionIcon(button.action);
final double btnmiddleX = (button.x1 + button.x2) / 2 + 0.01;
final double btnmiddleY = (button.y1 + button.y2) / 2 + 0.01;
final double btnx1 = btnmiddleX - 8;
final double btnx2 = btnmiddleX + 8;
final double btny1 = btnmiddleY - 8;
final double btny2 = btnmiddleY + 8;
buffer.vertex(middleX + btnx1, middleY + btny1, getBlitOffset()).uv(sprite.getU(u1), sprite.getV(v1)).color(f, f, f, a).endVertex();
buffer.vertex(middleX + btnx1, middleY + btny2, getBlitOffset()).uv(sprite.getU(u1), sprite.getV(v2)).color(f, f, f, a).endVertex();
buffer.vertex(middleX + btnx2, middleY + btny2, getBlitOffset()).uv(sprite.getU(u2), sprite.getV(v2)).color(f, f, f, a).endVertex();
buffer.vertex(middleX + btnx2, middleY + btny1, getBlitOffset()).uv(sprite.getU(u2), sprite.getV(v1)).color(f, f, f, a).endVertex();
}
}
private void drawTexts(MatrixStack ms, BuildModeEnum currentBuildMode, double middleX, double middleY, ArrayList<MenuRegion> modes, ArrayList<MenuButton> buttons, OptionEnum[] options) {
//font.drawStringWithShadow("Actions", (int) (middleX - buttonDistance - 13) - font.getStringWidth("Actions") * 0.5f, (int) middleY - 38, 0xffffffff);
//Draw option strings
for (int i = 0; i < currentBuildMode.options.length; i++) {
OptionEnum option = options[i];
font.drawShadow(ms, I18n.get(option.name), (int) (middleX + buttonDistance - 9), (int) middleY - 37 + i * 39, optionTextColor);
}
String credits = "Effortless Building";
font.drawShadow(ms, credits, width - font.width(credits) - 4, height - 10, watermarkTextColor);
//Draw buildmode text
for (final MenuRegion menuRegion : modes) {
if (menuRegion.highlighted) {
final double x = (menuRegion.x1 + menuRegion.x2) * 0.5;
final double y = (menuRegion.y1 + menuRegion.y2) * 0.5;
int fixed_x = (int) (x * textDistance);
final int fixed_y = (int) (y * textDistance) - font.lineHeight / 2;
String text = I18n.get(menuRegion.mode.getNameKey());
if (x <= -0.2) {
fixed_x -= font.width(text);
} else if (-0.2 <= x && x <= 0.2) {
fixed_x -= font.width(text) / 2;
}
font.drawShadow(ms, text, (int) middleX + fixed_x, (int) middleY + fixed_y, whiteTextColor);
//Draw description
text = I18n.get(menuRegion.mode.getDescriptionKey());
font.drawShadow(ms, text, (int) middleX - font.width(text) / 2f, (int) middleY + descriptionHeight, descriptionTextColor);
}
}
//Draw action text
for (final MenuButton button : buttons) {
if (button.highlighted) {
String text = TextFormatting.AQUA + button.name;
//Add keybind in brackets
String keybind = findKeybind(button, currentBuildMode);
String keybindFormatted = "";
if (!keybind.isEmpty())
keybindFormatted = TextFormatting.GRAY + "(" + WordUtils.capitalizeFully(keybind) + ")";
if (button.textSide == Direction.WEST) {
font.draw(ms, text, (int) (middleX + button.x1 - 8) - font.width(text),
(int) (middleY + button.y1 + 6), whiteTextColor);
} else if (button.textSide == Direction.EAST) {
font.draw(ms, text, (int) (middleX + button.x2 + 8),
(int) (middleY + button.y1 + 6), whiteTextColor);
} else if (button.textSide == Direction.UP || button.textSide == Direction.NORTH) {
font.draw(ms, keybindFormatted, (int) (middleX + (button.x1 + button.x2) * 0.5 - font.width(keybindFormatted) * 0.5),
(int) (middleY + button.y1 - 26), whiteTextColor);
font.draw(ms, text, (int) (middleX + (button.x1 + button.x2) * 0.5 - font.width(text) * 0.5),
(int) (middleY + button.y1 - 14), whiteTextColor);
} else if (button.textSide == Direction.DOWN || button.textSide == Direction.SOUTH) {
font.draw(ms, text, (int) (middleX + (button.x1 + button.x2) * 0.5 - font.width(text) * 0.5),
(int) (middleY + button.y1 + 26), whiteTextColor);
font.draw(ms, keybindFormatted, (int) (middleX + (button.x1 + button.x2) * 0.5 - font.width(keybindFormatted) * 0.5),
(int) (middleY + button.y1 + 38), whiteTextColor);
}
}
}
}
private String findKeybind(MenuButton button, BuildModeEnum currentBuildMode){
String result = "";
int keybindingIndex = -1;
if (button.action == ActionEnum.UNDO) keybindingIndex = 3;
if (button.action == ActionEnum.REDO) keybindingIndex = 4;
if (button.action == ActionEnum.REPLACE) keybindingIndex = 1;
if (button.action == ActionEnum.OPEN_MODIFIER_SETTINGS) keybindingIndex = 0;
if (keybindingIndex != -1) {
KeyBinding keyMap = ClientProxy.keyBindings[keybindingIndex];
if (!keyMap.getKeyModifier().name().equals("none")) {
result = keyMap.getKeyModifier().name() + " ";
}
result += I18n.get(keyMap.getKey().getName());
}
if (currentBuildMode.options.length > 0) {
//Add (ctrl) to first two actions of first option
if (button.action == currentBuildMode.options[0].actions[0]
|| button.action == currentBuildMode.options[0].actions[1]) {
result = I18n.get(ClientProxy.keyBindings[5].getKey().getName());
if (result.equals("Left Control")) result = "Ctrl";
}
}
return result;
}
private boolean inTriangle(final double x1, final double y1, final double x2, final double y2,
final double x3, final double y3, final double x, final double y) {
final double ab = (x1 - x) * (y2 - y) - (x2 - x) * (y1 - y);
final double bc = (x2 - x) * (y3 - y) - (x3 - x) * (y2 - y);
final double ca = (x3 - x) * (y1 - y) - (x1 - x) * (y3 - y);
return sign(ab) == sign(bc) && sign(bc) == sign(ca);
}
private int sign(final double n) {
return n > 0 ? 1 : -1;
}
@Override
public boolean isPauseScreen() {
return false;
}
@Override
public boolean mouseClicked(double mouseX, double mouseY, int mouseButton) {
performAction(true);
return super.mouseClicked(mouseX, mouseY, mouseButton);
}
@Override
public void onClose() {
super.onClose();
//After onClose so it can open another screen
if (!performedActionUsingMouse) performAction(false);
}
private void performAction(boolean fromMouseClick) {
PlayerEntity player = Minecraft.getInstance().player;
ModeSettingsManager.ModeSettings modeSettings = ModeSettingsManager.getModeSettings(player);
if (switchTo != null) {
playRadialMenuSound();
modeSettings.setBuildMode(switchTo);
ModeSettingsManager.setModeSettings(player, modeSettings);
PacketHandler.INSTANCE.sendToServer(new ModeSettingsMessage(modeSettings));
EffortlessBuilding.log(player, I18n.get(modeSettings.getBuildMode().getNameKey()), true);
if (fromMouseClick) performedActionUsingMouse = true;
}
//Perform button action
ModeOptions.ActionEnum action = doAction;
if (action != null) {
playRadialMenuSound();
ModeOptions.performAction(player, action);
PacketHandler.INSTANCE.sendToServer(new ModeActionMessage(action));
if (fromMouseClick) performedActionUsingMouse = true;
}
}
public static void playRadialMenuSound() {
final float volume = 0.1f;
if (volume >= 0.0001f) {
SimpleSound sound = new SimpleSound(SoundEvents.UI_BUTTON_CLICK, SoundCategory.MASTER, volume, 1.0f, Minecraft.getInstance().player.blockPosition());
Minecraft.getInstance().getSoundManager().play(sound);
}
} }
private static class MenuButton { private static class MenuButton {
public final ActionEnum action;
public double x1, x2; public double x1, x2;
public double y1, y2; public double y1, y2;
public boolean highlighted; public boolean highlighted;
public final ActionEnum action;
public String name; public String name;
public Direction textSide; public Direction textSide;
public MenuButton(final String name, final ActionEnum action, final double x, final double y, public MenuButton(final String name, final ActionEnum action, final double x, final double y,
final Direction textSide) { final Direction textSide) {
this.name = I18n.format(name); this.name = I18n.get(name);
this.action = action; this.action = action;
x1 = x - 10; x1 = x - 10;
x2 = x + 10; x2 = x + 10;
@@ -113,371 +561,5 @@ public class RadialMenu extends Screen {
} }
@Override
public void render(final int mouseX, final int mouseY, final float partialTicks) {
if (!isVisible()) return;
BuildModeEnum currentBuildMode = ModeSettingsManager.getModeSettings(Minecraft.getInstance().player).getBuildMode();
GlStateManager.pushMatrix();
GlStateManager.translatef( 0.0F, 0.0F, 200.0F );
final int startColor = (int) ( visibility * 98 ) << 24;
final int endColor = (int) ( visibility * 128 ) << 24;
fillGradient(0, 0, width, height, startColor, endColor);
GlStateManager.disableTexture();
GlStateManager.enableBlend();
GlStateManager.disableAlphaTest();
GlStateManager.blendFuncSeparate(GL11.GL_SRC_ALPHA, GL11.GL_ONE_MINUS_SRC_ALPHA, 1, 0);
GlStateManager.shadeModel(GL11.GL_SMOOTH);
final Tessellator tessellator = Tessellator.getInstance();
final BufferBuilder buffer = tessellator.getBuffer();
buffer.begin(GL11.GL_QUADS, DefaultVertexFormats.POSITION_COLOR);
final double middleX = width / 2.0;
final double middleY = height / 2.0;
final double mouseXCenter = mouseX - middleX;
final double mouseYCenter = -mouseY + middleY;
double mouseRadians = Math.atan2(mouseYCenter, mouseXCenter);
final double ringInnerEdge = 30;
final double ringOuterEdge = 65;
final double textDistance = 75;
final double buttonDistance = 105;
final double quarterCircle = Math.PI / 2.0;
if ( mouseRadians < -quarterCircle ) {
mouseRadians = mouseRadians + Math.PI * 2;
}
final ArrayList<MenuRegion> modes = new ArrayList<MenuRegion>();
final ArrayList<MenuButton> buttons = new ArrayList<MenuButton>();
//Add build modes
for (final BuildModeEnum mode : BuildModeEnum.values()) {
modes.add(new MenuRegion(mode));
}
//Add actions
buttons.add(new MenuButton(ActionEnum.UNDO.name, ActionEnum.UNDO, -buttonDistance - 26, -13, Direction.UP));
buttons.add(new MenuButton(ActionEnum.REDO.name, ActionEnum.REDO, -buttonDistance, -13, Direction.UP));
buttons.add(new MenuButton(ActionEnum.OPEN_MODIFIER_SETTINGS.name, ActionEnum.OPEN_MODIFIER_SETTINGS, -buttonDistance - 26, 13, Direction.DOWN));
buttons.add(new MenuButton(ActionEnum.REPLACE.name, ActionEnum.REPLACE, -buttonDistance, 13, Direction.DOWN));
//Add buildmode dependent options
OptionEnum[] options = currentBuildMode.options;
for (int i = 0; i < options.length; i++) {
for (int j = 0; j < options[i].actions.length; j++) {
ActionEnum action = options[i].actions[j];
buttons.add(new MenuButton(action.name, action, buttonDistance + j * 26, -13 + i * 39, Direction.DOWN));
}
}
switchTo = null;
doAction = null;
//Draw buildmode backgrounds
if (!modes.isEmpty()) {
final int totalModes = Math.max( 3, modes.size() );
int currentMode = 0;
final double fragment = Math.PI * 0.005;
final double fragment2 = Math.PI * 0.0025;
final double perObject = 2.0 * Math.PI / totalModes;
for (int i = 0; i < modes.size(); i++) {
MenuRegion menuRegion = modes.get(i);
final double beginRadians = currentMode * perObject - quarterCircle;
final double endRadians = (currentMode + 1) * perObject - quarterCircle;
menuRegion.x1 = Math.cos(beginRadians);
menuRegion.x2 = Math.cos(endRadians);
menuRegion.y1 = Math.sin(beginRadians);
menuRegion.y2 = Math.sin(endRadians);
final double x1m1 = Math.cos(beginRadians + fragment) * ringInnerEdge;
final double x2m1 = Math.cos(endRadians - fragment) * ringInnerEdge;
final double y1m1 = Math.sin(beginRadians + fragment) * ringInnerEdge;
final double y2m1 = Math.sin(endRadians - fragment) * ringInnerEdge;
final double x1m2 = Math.cos(beginRadians + fragment2) * ringOuterEdge;
final double x2m2 = Math.cos(endRadians - fragment2) * ringOuterEdge;
final double y1m2 = Math.sin(beginRadians + fragment2) * ringOuterEdge;
final double y2m2 = Math.sin(endRadians - fragment2) * ringOuterEdge;
float r = 0.0f;
float g = 0.0f;
float b = 0.0f;
float a = 0.5f;
//check if current mode
int buildMode = currentBuildMode.ordinal();
if (buildMode == i) {
r = 0f;
g = 0.5f;
b = 1f;
a = 0.5f;
//menuRegion.highlighted = true; //draw text
}
//check if mouse is over this region
final boolean isMouseInQuad = inTriangle(x1m1, y1m1, x2m2, y2m2, x2m1, y2m1, mouseXCenter, mouseYCenter)
|| inTriangle(x1m1, y1m1, x1m2, y1m2, x2m2, y2m2, mouseXCenter, mouseYCenter);
if (beginRadians <= mouseRadians && mouseRadians <= endRadians && isMouseInQuad) {
r = 0.6f;
g = 0.8f;
b = 1f;
a = 0.6f;
menuRegion.highlighted = true;
switchTo = menuRegion.mode;
}
buffer.pos(middleX + x1m1, middleY + y1m1, blitOffset).color(r, g, b, a).endVertex();
buffer.pos(middleX + x2m1, middleY + y2m1, blitOffset).color(r, g, b, a).endVertex();
buffer.pos(middleX + x2m2, middleY + y2m2, blitOffset).color(r, g, b, a).endVertex();
buffer.pos(middleX + x1m2, middleY + y1m2, blitOffset).color(r, g, b, a).endVertex();
currentMode++;
}
}
//Draw action backgrounds
for (final MenuButton btn : buttons) {
float r = 0.5f;
float g = 0.5f;
float b = 0.5f;
float a = 0.5f;
//highlight when active option
if (btn.action == getBuildSpeed() ||
btn.action == getFill() ||
btn.action == getCubeFill() ||
btn.action == getRaisedEdge() ||
btn.action == getLineThickness() ||
btn.action == getCircleStart()) {
r = 0.0f;
g = 0.5f;
b = 1f;
a = 0.6f;
}
//highlight when mouse over
if (btn.x1 <= mouseXCenter && btn.x2 >= mouseXCenter && btn.y1 <= mouseYCenter && btn.y2 >= mouseYCenter) {
r = 0.6f;
g = 0.8f;
b = 1f;
a = 0.6f;
btn.highlighted = true;
doAction = btn.action;
}
buffer.pos(middleX + btn.x1, middleY + btn.y1, blitOffset).color(r, g, b, a).endVertex();
buffer.pos(middleX + btn.x1, middleY + btn.y2, blitOffset).color(r, g, b, a).endVertex();
buffer.pos(middleX + btn.x2, middleY + btn.y2, blitOffset).color(r, g, b, a).endVertex();
buffer.pos(middleX + btn.x2, middleY + btn.y1, blitOffset).color(r, g, b, a).endVertex();
}
tessellator.draw();
GlStateManager.shadeModel(GL11.GL_FLAT);
GlStateManager.translatef(0f, 0f, 5f);
GlStateManager.enableTexture();
GlStateManager.color3f(1f, 1f, 1f);
GlStateManager.disableBlend();
GlStateManager.enableAlphaTest();
GlStateManager.bindTexture(Minecraft.getInstance().getTextureMap().getGlTextureId());
buffer.begin(GL11.GL_QUADS, DefaultVertexFormats.POSITION_TEX_COLOR);
//Draw buildmode icons
for (final MenuRegion menuRegion : modes) {
final double x = (menuRegion.x1 + menuRegion.x2) * 0.5 * (ringOuterEdge * 0.6 + 0.4 * ringInnerEdge);
final double y = (menuRegion.y1 + menuRegion.y2) * 0.5 * (ringOuterEdge * 0.6 + 0.4 * ringInnerEdge);
final TextureAtlasSprite sprite = ModClientEventHandler.getBuildModeIcon(menuRegion.mode);
final double x1 = x - 8;
final double x2 = x + 8;
final double y1 = y - 8;
final double y2 = y + 8;
final float f = 1f;
final float a = 1f;
final double u1 = 0;
final double u2 = 16;
final double v1 = 0;
final double v2 = 16;
buffer.pos(middleX + x1, middleY + y1, blitOffset).tex(sprite.getInterpolatedU(u1), sprite.getInterpolatedV(v1)).color(f, f, f, a).endVertex();
buffer.pos(middleX + x1, middleY + y2, blitOffset).tex(sprite.getInterpolatedU(u1), sprite.getInterpolatedV(v2)).color(f, f, f, a).endVertex();
buffer.pos(middleX + x2, middleY + y2, blitOffset).tex(sprite.getInterpolatedU(u2), sprite.getInterpolatedV(v2)).color(f, f, f, a).endVertex();
buffer.pos(middleX + x2, middleY + y1, blitOffset).tex(sprite.getInterpolatedU(u2), sprite.getInterpolatedV(v1)).color(f, f, f, a).endVertex();
}
//Draw action icons
for (final MenuButton button : buttons) {
final float f = 1f;
final float a = 1f;
final double u1 = 0;
final double u2 = 16;
final double v1 = 0;
final double v2 = 16;
final TextureAtlasSprite sprite = ModClientEventHandler.getModeOptionIcon(button.action);
final double btnmiddleX = (button.x1 + button.x2) / 2 + 0.01;
final double btnmiddleY = (button.y1 + button.y2) / 2 + 0.01;
final double btnx1 = btnmiddleX - 8;
final double btnx2 = btnmiddleX + 8;
final double btny1 = btnmiddleY - 8;
final double btny2 = btnmiddleY + 8;
buffer.pos(middleX + btnx1, middleY + btny1, blitOffset).tex(sprite.getInterpolatedU(u1), sprite.getInterpolatedV(v1)).color(f, f, f, a).endVertex();
buffer.pos(middleX + btnx1, middleY + btny2, blitOffset).tex(sprite.getInterpolatedU(u1), sprite.getInterpolatedV(v2)).color(f, f, f, a).endVertex();
buffer.pos(middleX + btnx2, middleY + btny2, blitOffset).tex(sprite.getInterpolatedU(u2), sprite.getInterpolatedV(v2)).color(f, f, f, a).endVertex();
buffer.pos(middleX + btnx2, middleY + btny1, blitOffset).tex(sprite.getInterpolatedU(u2), sprite.getInterpolatedV(v1)).color(f, f, f, a).endVertex();
}
tessellator.draw();
//Draw strings
//font.drawStringWithShadow("Actions", (int) (middleX - buttonDistance - 13) - font.getStringWidth("Actions") * 0.5f, (int) middleY - 38, 0xffffffff);
//Draw option strings
for (int i = 0; i < currentBuildMode.options.length; i++) {
OptionEnum option = options[i];
font.drawStringWithShadow(I18n.format(option.name), (int) (middleX + buttonDistance - 9), (int) middleY - 37 + i * 39, 0xeeeeeeff);
}
String credits = "Effortless Building";
font.drawStringWithShadow(credits, width - font.getStringWidth(credits) - 4, height - 10, 0x88888888);
//Draw buildmode text
for (final MenuRegion menuRegion : modes) {
if (menuRegion.highlighted) {
final double x = (menuRegion.x1 + menuRegion.x2) * 0.5;
final double y = (menuRegion.y1 + menuRegion.y2) * 0.5;
int fixed_x = (int) (x * textDistance);
final int fixed_y = (int) (y * textDistance) - font.FONT_HEIGHT / 2;
final String text = I18n.format(menuRegion.mode.name);
if ( x <= -0.2 ) {
fixed_x -= font.getStringWidth(text);
} else if ( -0.2 <= x && x <= 0.2 ) {
fixed_x -= font.getStringWidth(text) / 2;
}
font.drawStringWithShadow(text, (int) middleX + fixed_x, (int) middleY + fixed_y, 0xffffffff);
}
}
//Draw action text
for (final MenuButton button : buttons) {
if (button.highlighted) {
String text = TextFormatting.AQUA + button.name;
int wrap = 120;
String keybind = "";
String keybindFormatted = "";
//Add keybind in brackets
if (button.action == ActionEnum.UNDO) {
keybind = ClientProxy.keyBindings[4].getLocalizedName();
}
if (button.action == ActionEnum.REDO) {
keybind = ClientProxy.keyBindings[5].getLocalizedName();
}
if (button.action == ActionEnum.REPLACE) {
keybind = ClientProxy.keyBindings[1].getLocalizedName();
}
if (button.action == ActionEnum.OPEN_MODIFIER_SETTINGS) {
keybind = ClientProxy.keyBindings[0].getLocalizedName();
}
if (currentBuildMode.options.length > 0) {
//Add (ctrl) to first two actions of first option
if (button.action == currentBuildMode.options[0].actions[0]
|| button.action == currentBuildMode.options[0].actions[1]) {
keybind = ClientProxy.keyBindings[6].getLocalizedName();
if (keybind.equals("Left Control")) keybind = "Ctrl";
}
}
if (!keybind.isEmpty()) keybindFormatted = TextFormatting.GRAY + "(" + WordUtils.capitalizeFully(keybind) + ")";
if (button.textSide == Direction.WEST) {
font.drawSplitString( text, (int) (middleX + button.x1 - 8 ) - font.getStringWidth(text),
(int) (middleY + button.y1 + 6), wrap, 0xffffffff);
} else if (button.textSide == Direction.EAST) {
font.drawSplitString(text, (int) (middleX + button.x2 + 8),
(int) (middleY + button.y1 + 6 ), wrap, 0xffffffff);
} else if (button.textSide == Direction.UP || button.textSide == Direction.NORTH) {
font.drawSplitString( keybindFormatted, (int) (middleX + (button.x1 + button.x2) * 0.5 - font.getStringWidth(keybindFormatted) * 0.5),
(int) (middleY + button.y1 - 26), wrap,0xffffffff);
font.drawSplitString( text, (int) (middleX + (button.x1 + button.x2) * 0.5 - font.getStringWidth(text) * 0.5),
(int) (middleY + button.y1 - 14), wrap,0xffffffff);
} else if (button.textSide == Direction.DOWN || button.textSide == Direction.SOUTH) {
font.drawSplitString(text, (int) (middleX + (button.x1 + button.x2) * 0.5 - font.getStringWidth(text) * 0.5),
(int) (middleY + button.y1 + 26), wrap, 0xffffffff);
font.drawSplitString(keybindFormatted, (int) (middleX + (button.x1 + button.x2) * 0.5 - font.getStringWidth(keybindFormatted) * 0.5),
(int) (middleY + button.y1 + 38), wrap, 0xffffffff);
}
}
}
GlStateManager.popMatrix();
}
private boolean inTriangle(final double x1, final double y1, final double x2, final double y2,
final double x3, final double y3, final double x, final double y ) {
final double ab = (x1 - x) * (y2 - y) - (x2 - x) * (y1 - y);
final double bc = (x2 - x) * (y3 - y) - (x3 - x) * (y2 - y);
final double ca = (x3 - x) * (y1 - y) - (x1 - x) * (y3 - y);
return sign(ab) == sign(bc) && sign(bc) == sign(ca);
}
private int sign(final double n) {
return n > 0 ? 1 : -1;
}
/**
* Called when the mouse is clicked. Args : mouseX, mouseY, clickedButton
*/
@Override
public boolean mouseClicked(double mouseX, double mouseY, int mouseButton) {
EffortlessBuilding.log("mouse clicked");
// KeyBinding.updateKeyBindState();
// KeyBinding.setKeyBindState(ClientProxy.keyBindings[3].getKeyCode(), true);
// if (mouseButton == 0) {
// this.mc.displayGuiScreen(null);
//
// if (this.mc.currentScreen == null) {
// this.mc.setIngameFocus();
// }
// }
return super.mouseClicked(mouseX, mouseY, mouseButton);
}
} }

View File

@@ -1,9 +1,10 @@
package nl.requios.effortlessbuilding.gui.buildmodifier; package nl.requios.effortlessbuilding.gui.buildmodifier;
import com.mojang.blaze3d.matrix.MatrixStack;
import net.minecraft.client.gui.screen.Screen; import net.minecraft.client.gui.screen.Screen;
import net.minecraft.client.gui.widget.Widget; import net.minecraft.client.gui.widget.Widget;
import net.minecraft.client.gui.widget.button.Button;
import net.minecraft.util.math.BlockPos; import net.minecraft.util.math.BlockPos;
import net.minecraft.util.text.StringTextComponent;
import net.minecraft.util.text.TextFormatting; import net.minecraft.util.text.TextFormatting;
import net.minecraftforge.api.distmarker.Dist; import net.minecraftforge.api.distmarker.Dist;
import net.minecraftforge.api.distmarker.OnlyIn; import net.minecraftforge.api.distmarker.OnlyIn;
@@ -48,23 +49,23 @@ public class ArraySettingsGui extends GuiCollapsibleScrollEntry {
y = top + 20; y = top + 20;
textArrayOffsetX = new GuiNumberField(font, buttons, left + 70, y, 50, 18); textArrayOffsetX = new GuiNumberField(font, buttons, left + 70, y, 50, 18);
textArrayOffsetX.setNumber(0); textArrayOffsetX.setNumber(0);
textArrayOffsetX.setTooltip("How much each copy is shifted."); textArrayOffsetX.setTooltip(new StringTextComponent("How much each copy is shifted."));
arrayNumberFieldList.add(textArrayOffsetX); arrayNumberFieldList.add(textArrayOffsetX);
textArrayOffsetY = new GuiNumberField(font, buttons, left + 140, y, 50, 18); textArrayOffsetY = new GuiNumberField(font, buttons, left + 140, y, 50, 18);
textArrayOffsetY.setNumber(0); textArrayOffsetY.setNumber(0);
textArrayOffsetY.setTooltip("How much each copy is shifted."); textArrayOffsetY.setTooltip(new StringTextComponent("How much each copy is shifted."));
arrayNumberFieldList.add(textArrayOffsetY); arrayNumberFieldList.add(textArrayOffsetY);
textArrayOffsetZ = new GuiNumberField(font, buttons, left + 210, y, 50, 18); textArrayOffsetZ = new GuiNumberField(font, buttons, left + 210, y, 50, 18);
textArrayOffsetZ.setNumber(0); textArrayOffsetZ.setNumber(0);
textArrayOffsetZ.setTooltip("How much each copy is shifted."); textArrayOffsetZ.setTooltip(new StringTextComponent("How much each copy is shifted."));
arrayNumberFieldList.add(textArrayOffsetZ); arrayNumberFieldList.add(textArrayOffsetZ);
y = top + 50; y = top + 50;
textArrayCount = new GuiNumberField(font, buttons, left + 55, y, 50, 18); textArrayCount = new GuiNumberField(font, buttons, left + 55, y, 50, 18);
textArrayCount.setNumber(5); textArrayCount.setNumber(5);
textArrayCount.setTooltip("How many copies should be made."); textArrayCount.setTooltip(new StringTextComponent("How many copies should be made."));
arrayNumberFieldList.add(textArrayCount); arrayNumberFieldList.add(textArrayCount);
ModifierSettingsManager.ModifierSettings modifierSettings = ModifierSettingsManager.getModifierSettings(mc.player); ModifierSettingsManager.ModifierSettings modifierSettings = ModifierSettingsManager.getModifierSettings(mc.player);
@@ -85,48 +86,47 @@ public class ArraySettingsGui extends GuiCollapsibleScrollEntry {
} }
@Override @Override
public void drawEntry(int slotIndex, int x, int y, int listWidth, int slotHeight, int mouseX, int mouseY, public void drawEntry(MatrixStack ms, int slotIndex, int x, int y, int listWidth, int slotHeight, int mouseX, int mouseY,
boolean isSelected, float partialTicks) { boolean isSelected, float partialTicks) {
int yy = y; int yy = y;
int offset = 8; int offset = 8;
buttonArrayEnabled.render(mouseX, mouseY, partialTicks); buttonArrayEnabled.render(ms, mouseX, mouseY, partialTicks);
if (buttonArrayEnabled.isChecked()) { if (buttonArrayEnabled.isChecked()) {
buttonArrayEnabled.y = yy; buttonArrayEnabled.y = yy;
font.drawString("Array enabled", left + offset, yy + 2, 0xFFFFFF); font.draw(ms, "Array enabled", left + offset, yy + 2, 0xFFFFFF);
yy = y + 20; yy = y + 20;
font.drawString("Offset", left + offset, yy + 5, 0xFFFFFF); font.draw(ms, "Offset", left + offset, yy + 5, 0xFFFFFF);
font.drawString("X", left + 50 + offset, yy + 5, 0xFFFFFF); font.draw(ms, "X", left + 50 + offset, yy + 5, 0xFFFFFF);
textArrayOffsetX.y = yy; textArrayOffsetX.y = yy;
font.drawString("Y", left + 120 + offset, yy + 5, 0xFFFFFF); font.draw(ms, "Y", left + 120 + offset, yy + 5, 0xFFFFFF);
textArrayOffsetY.y = yy; textArrayOffsetY.y = yy;
font.drawString("Z", left + 190 + offset, yy + 5, 0xFFFFFF); font.draw(ms, "Z", left + 190 + offset, yy + 5, 0xFFFFFF);
textArrayOffsetZ.y = yy; textArrayOffsetZ.y = yy;
yy = y + 50; yy = y + 50;
font.drawString("Count", left + offset, yy + 5, 0xFFFFFF); font.draw(ms, "Count", left + offset, yy + 5, 0xFFFFFF);
textArrayCount.y = yy; textArrayCount.y = yy;
int currentReach = Math.max(-1, getArrayReach()); int currentReach = Math.max(-1, getArrayReach());
int maxReach = ReachHelper.getMaxReach(mc.player); int maxReach = ReachHelper.getMaxReach(mc.player);
TextFormatting reachColor = isCurrentReachValid(currentReach, maxReach) ? TextFormatting.GRAY : TextFormatting.RED; TextFormatting reachColor = isCurrentReachValid(currentReach, maxReach) ? TextFormatting.GRAY : TextFormatting.RED;
String reachText = "Reach: " + reachColor + currentReach + TextFormatting.GRAY + "/" + TextFormatting.GRAY + maxReach; String reachText = "Reach: " + reachColor + currentReach + TextFormatting.GRAY + "/" + TextFormatting.GRAY + maxReach;
font.drawString(reachText, left + 176 + offset, yy + 5, 0xFFFFFF); font.draw(ms, reachText, left + 176 + offset, yy + 5, 0xFFFFFF);
arrayNumberFieldList.forEach(numberField -> numberField.drawNumberField(mouseX, mouseY, partialTicks)); arrayNumberFieldList.forEach(numberField -> numberField.drawNumberField(ms, mouseX, mouseY, partialTicks));
} else { } else {
buttonArrayEnabled.y = yy; buttonArrayEnabled.y = yy;
font.drawString("Array disabled", left + offset, yy + 2, 0x999999); font.draw(ms, "Array disabled", left + offset, yy + 2, 0x999999);
} }
} }
public void drawTooltip(Screen guiScreen, int mouseX, int mouseY) { public void drawTooltip(MatrixStack ms, Screen guiScreen, int mouseX, int mouseY) {
//Draw tooltips last //Draw tooltips last
if (buttonArrayEnabled.isChecked()) if (buttonArrayEnabled.isChecked()) {
{ arrayNumberFieldList.forEach(numberField -> numberField.drawTooltip(ms, scrollPane.parent, mouseX, mouseY));
arrayNumberFieldList.forEach(numberField -> numberField.drawTooltip(scrollPane.parent, mouseX, mouseY));
} }
} }
@@ -146,7 +146,7 @@ public class ArraySettingsGui extends GuiCollapsibleScrollEntry {
boolean insideArrayEnabledLabel = mouseX >= left && mouseX < right && relativeY >= -2 && relativeY < 12; boolean insideArrayEnabledLabel = mouseX >= left && mouseX < right && relativeY >= -2 && relativeY < 12;
if (insideArrayEnabledLabel) { if (insideArrayEnabledLabel) {
buttonArrayEnabled.playDownSound(this.mc.getSoundHandler()); buttonArrayEnabled.playDownSound(this.mc.getSoundManager());
buttonArrayEnabled.onClick(mouseX, mouseY); buttonArrayEnabled.onClick(mouseX, mouseY);
} }
@@ -183,8 +183,7 @@ public class ArraySettingsGui extends GuiCollapsibleScrollEntry {
} }
private int getArrayReach() { private int getArrayReach() {
try try {
{
//find largest offset //find largest offset
double x = Math.abs(textArrayOffsetX.getNumber()); double x = Math.abs(textArrayOffsetX.getNumber());
double y = Math.abs(textArrayOffsetY.getNumber()); double y = Math.abs(textArrayOffsetY.getNumber());

View File

@@ -1,10 +1,12 @@
package nl.requios.effortlessbuilding.gui.buildmodifier; package nl.requios.effortlessbuilding.gui.buildmodifier;
import com.mojang.blaze3d.matrix.MatrixStack;
import net.minecraft.client.gui.screen.Screen;
import net.minecraft.client.gui.widget.Widget; import net.minecraft.client.gui.widget.Widget;
import net.minecraft.client.gui.widget.button.Button; import net.minecraft.client.gui.widget.button.Button;
import net.minecraft.client.gui.screen.Screen;
import net.minecraft.util.ResourceLocation; import net.minecraft.util.ResourceLocation;
import net.minecraft.util.math.Vec3d; import net.minecraft.util.math.vector.Vector3d;
import net.minecraft.util.text.StringTextComponent;
import net.minecraft.util.text.TextFormatting; import net.minecraft.util.text.TextFormatting;
import net.minecraftforge.api.distmarker.Dist; import net.minecraftforge.api.distmarker.Dist;
import net.minecraftforge.api.distmarker.OnlyIn; import net.minecraftforge.api.distmarker.OnlyIn;
@@ -55,17 +57,17 @@ public class MirrorSettingsGui extends GuiCollapsibleScrollEntry {
textMirrorPosX = new GuiNumberField(font, buttonList, left + 58, y, 62, 18); textMirrorPosX = new GuiNumberField(font, buttonList, left + 58, y, 62, 18);
textMirrorPosX.setNumber(0); textMirrorPosX.setNumber(0);
textMirrorPosX.setTooltip( textMirrorPosX.setTooltip(
Arrays.asList("The position of the mirror.", TextFormatting.GRAY + "For odd numbered builds add 0.5.")); Arrays.asList(new StringTextComponent("The position of the mirror."), new StringTextComponent("For odd numbered builds add 0.5.").withStyle(TextFormatting.GRAY)));
mirrorNumberFieldList.add(textMirrorPosX); mirrorNumberFieldList.add(textMirrorPosX);
textMirrorPosY = new GuiNumberField(font, buttonList, left + 138, y, 62, 18); textMirrorPosY = new GuiNumberField(font, buttonList, left + 138, y, 62, 18);
textMirrorPosY.setNumber(64); textMirrorPosY.setNumber(64);
textMirrorPosY.setTooltip(Arrays.asList("The position of the mirror.", TextFormatting.GRAY + "For odd numbered builds add 0.5.")); textMirrorPosY.setTooltip(Arrays.asList(new StringTextComponent("The position of the mirror."), new StringTextComponent("For odd numbered builds add 0.5.").withStyle(TextFormatting.GRAY)));
mirrorNumberFieldList.add(textMirrorPosY); mirrorNumberFieldList.add(textMirrorPosY);
textMirrorPosZ = new GuiNumberField(font, buttonList, left + 218, y, 62, 18); textMirrorPosZ = new GuiNumberField(font, buttonList, left + 218, y, 62, 18);
textMirrorPosZ.setNumber(0); textMirrorPosZ.setNumber(0);
textMirrorPosZ.setTooltip(Arrays.asList("The position of the mirror.", TextFormatting.GRAY + "For odd numbered builds add 0.5.")); textMirrorPosZ.setTooltip(Arrays.asList(new StringTextComponent("The position of the mirror."), new StringTextComponent("For odd numbered builds add 0.5.").withStyle(TextFormatting.GRAY)));
mirrorNumberFieldList.add(textMirrorPosZ); mirrorNumberFieldList.add(textMirrorPosZ);
y = top + 50; y = top + 50;
@@ -82,53 +84,53 @@ public class MirrorSettingsGui extends GuiCollapsibleScrollEntry {
textMirrorRadius = new GuiNumberField(font, buttonList, left + 218, y, 62, 18); textMirrorRadius = new GuiNumberField(font, buttonList, left + 218, y, 62, 18);
textMirrorRadius.setNumber(50); textMirrorRadius.setNumber(50);
//TODO change to diameter (remove /2) //TODO change to diameter (remove /2)
textMirrorRadius.setTooltip(Arrays.asList("How far the mirror reaches in any direction.", textMirrorRadius.setTooltip(Arrays.asList(new StringTextComponent("How far the mirror reaches in any direction."),
TextFormatting.GRAY + "Max: " + TextFormatting.GOLD + ReachHelper.getMaxReach(mc.player) / 2, new StringTextComponent("Max: ").withStyle(TextFormatting.GRAY).append(new StringTextComponent(String.valueOf(ReachHelper.getMaxReach(mc.player) / 2)).withStyle(TextFormatting.GOLD)),
TextFormatting.GRAY + "Upgradeable in survival with reach upgrades.")); new StringTextComponent("Upgradeable in survival with reach upgrades.").withStyle(TextFormatting.GRAY)));
mirrorNumberFieldList.add(textMirrorRadius); mirrorNumberFieldList.add(textMirrorRadius);
y = top + 72; y = top + 72;
buttonCurrentPosition = new GuiIconButton(left + 5, y, 0, 0, BUILDING_ICONS, button -> { buttonCurrentPosition = new GuiIconButton(left + 5, y, 0, 0, BUILDING_ICONS, button -> {
Vec3d pos = new Vec3d(Math.floor(mc.player.posX) + 0.5, Math.floor(mc.player.posY) + 0.5, Math.floor(mc.player.posZ) + 0.5); Vector3d pos = new Vector3d(Math.floor(mc.player.getX()) + 0.5, Math.floor(mc.player.getY()) + 0.5, Math.floor(mc.player.getZ()) + 0.5);
textMirrorPosX.setNumber(pos.x); textMirrorPosX.setNumber(pos.x);
textMirrorPosY.setNumber(pos.y); textMirrorPosY.setNumber(pos.y);
textMirrorPosZ.setNumber(pos.z); textMirrorPosZ.setNumber(pos.z);
}); });
buttonCurrentPosition.setTooltip("Set mirror position to current player position"); buttonCurrentPosition.setTooltip(new StringTextComponent("Set mirror position to current player position"));
mirrorIconButtonList.add(buttonCurrentPosition); mirrorIconButtonList.add(buttonCurrentPosition);
buttonToggleOdd = new GuiIconButton(left + 35, y, 0, 20, BUILDING_ICONS, button -> { buttonToggleOdd = new GuiIconButton(left + 35, y, 0, 20, BUILDING_ICONS, button -> {
toggleOdd = !toggleOdd; toggleOdd = !toggleOdd;
buttonToggleOdd.setUseAlternateIcon(toggleOdd); buttonToggleOdd.setUseAlternateIcon(toggleOdd);
if (toggleOdd) { if (toggleOdd) {
buttonToggleOdd.setTooltip(Arrays.asList("Set mirror position to corner of block", "for even numbered builds")); buttonToggleOdd.setTooltip(Arrays.asList(new StringTextComponent("Set mirror position to corner of block"), new StringTextComponent("for even numbered builds")));
textMirrorPosX.setNumber(textMirrorPosX.getNumber() + 0.5); textMirrorPosX.setNumber(textMirrorPosX.getNumber() + 0.5);
textMirrorPosY.setNumber(textMirrorPosY.getNumber() + 0.5); textMirrorPosY.setNumber(textMirrorPosY.getNumber() + 0.5);
textMirrorPosZ.setNumber(textMirrorPosZ.getNumber() + 0.5); textMirrorPosZ.setNumber(textMirrorPosZ.getNumber() + 0.5);
} else { } else {
buttonToggleOdd.setTooltip(Arrays.asList("Set mirror position to middle of block", "for odd numbered builds")); buttonToggleOdd.setTooltip(Arrays.asList(new StringTextComponent("Set mirror position to middle of block"), new StringTextComponent("for odd numbered builds")));
textMirrorPosX.setNumber(Math.floor(textMirrorPosX.getNumber())); textMirrorPosX.setNumber(Math.floor(textMirrorPosX.getNumber()));
textMirrorPosY.setNumber(Math.floor(textMirrorPosY.getNumber())); textMirrorPosY.setNumber(Math.floor(textMirrorPosY.getNumber()));
textMirrorPosZ.setNumber(Math.floor(textMirrorPosZ.getNumber())); textMirrorPosZ.setNumber(Math.floor(textMirrorPosZ.getNumber()));
} }
}); });
buttonToggleOdd.setTooltip(Arrays.asList("Set mirror position to middle of block", "for odd numbered builds")); buttonToggleOdd.setTooltip(Arrays.asList(new StringTextComponent("Set mirror position to middle of block"), new StringTextComponent("for odd numbered builds")));
mirrorIconButtonList.add(buttonToggleOdd); mirrorIconButtonList.add(buttonToggleOdd);
buttonDrawLines = new GuiIconButton(left + 65, y, 0, 40, BUILDING_ICONS, button -> { buttonDrawLines = new GuiIconButton(left + 65, y, 0, 40, BUILDING_ICONS, button -> {
drawLines = !drawLines; drawLines = !drawLines;
buttonDrawLines.setUseAlternateIcon(drawLines); buttonDrawLines.setUseAlternateIcon(drawLines);
buttonDrawLines.setTooltip(drawLines ? "Hide lines" : "Show lines"); buttonDrawLines.setTooltip(new StringTextComponent(drawLines ? "Hide lines" : "Show lines"));
}); });
buttonDrawLines.setTooltip("Show lines"); buttonDrawLines.setTooltip(new StringTextComponent("Show lines"));
mirrorIconButtonList.add(buttonDrawLines); mirrorIconButtonList.add(buttonDrawLines);
buttonDrawPlanes = new GuiIconButton(left + 95, y, 0, 60, BUILDING_ICONS, button -> { buttonDrawPlanes = new GuiIconButton(left + 95, y, 0, 60, BUILDING_ICONS, button -> {
drawPlanes = !drawPlanes; drawPlanes = !drawPlanes;
buttonDrawPlanes.setUseAlternateIcon(drawPlanes); buttonDrawPlanes.setUseAlternateIcon(drawPlanes);
buttonDrawPlanes.setTooltip(drawPlanes ? "Hide area" : "Show area"); buttonDrawPlanes.setTooltip(new StringTextComponent(drawPlanes ? "Hide area" : "Show area"));
}); });
buttonDrawPlanes.setTooltip("Show area"); buttonDrawPlanes.setTooltip(new StringTextComponent("Show area"));
mirrorIconButtonList.add(buttonDrawPlanes); mirrorIconButtonList.add(buttonDrawPlanes);
ModifierSettingsManager.ModifierSettings modifierSettings = ModifierSettingsManager.getModifierSettings(mc.player); ModifierSettingsManager.ModifierSettings modifierSettings = ModifierSettingsManager.getModifierSettings(mc.player);
@@ -146,14 +148,14 @@ public class MirrorSettingsGui extends GuiCollapsibleScrollEntry {
drawPlanes = m.drawPlanes; drawPlanes = m.drawPlanes;
buttonDrawLines.setUseAlternateIcon(drawLines); buttonDrawLines.setUseAlternateIcon(drawLines);
buttonDrawPlanes.setUseAlternateIcon(drawPlanes); buttonDrawPlanes.setUseAlternateIcon(drawPlanes);
buttonDrawLines.setTooltip(drawLines ? "Hide lines" : "Show lines"); buttonDrawLines.setTooltip(new StringTextComponent(drawLines ? "Hide lines" : "Show lines"));
buttonDrawPlanes.setTooltip(drawPlanes ? "Hide area" : "Show area"); buttonDrawPlanes.setTooltip(new StringTextComponent(drawPlanes ? "Hide area" : "Show area"));
if (textMirrorPosX.getNumber() == Math.floor(textMirrorPosX.getNumber())) { if (textMirrorPosX.getNumber() == Math.floor(textMirrorPosX.getNumber())) {
toggleOdd = false; toggleOdd = false;
buttonToggleOdd.setTooltip(Arrays.asList("Set mirror position to middle of block", "for odd numbered builds")); buttonToggleOdd.setTooltip(Arrays.asList(new StringTextComponent("Set mirror position to middle of block"), new StringTextComponent("for odd numbered builds")));
} else { } else {
toggleOdd = true; toggleOdd = true;
buttonToggleOdd.setTooltip(Arrays.asList("Set mirror position to corner of block", "for even numbered builds")); buttonToggleOdd.setTooltip(Arrays.asList(new StringTextComponent("Set mirror position to corner of block"), new StringTextComponent("for even numbered builds")));
} }
buttonToggleOdd.setUseAlternateIcon(toggleOdd); buttonToggleOdd.setUseAlternateIcon(toggleOdd);
} }
@@ -171,32 +173,32 @@ public class MirrorSettingsGui extends GuiCollapsibleScrollEntry {
} }
@Override @Override
public void drawEntry(int slotIndex, int x, int y, int listWidth, int slotHeight, int mouseX, int mouseY, public void drawEntry(MatrixStack ms, int slotIndex, int x, int y, int listWidth, int slotHeight, int mouseX, int mouseY,
boolean isSelected, float partialTicks) { boolean isSelected, float partialTicks) {
int yy = y; int yy = y;
int offset = 8; int offset = 8;
buttonMirrorEnabled.render(mouseX, mouseY, partialTicks); buttonMirrorEnabled.render(ms, mouseX, mouseY, partialTicks);
if (buttonMirrorEnabled.isChecked()) { if (buttonMirrorEnabled.isChecked()) {
buttonMirrorEnabled.y = yy; buttonMirrorEnabled.y = yy;
font.drawString("Mirror enabled", left + offset, yy + 2, 0xFFFFFF); font.draw(ms, "Mirror enabled", left + offset, yy + 2, 0xFFFFFF);
yy = y + 18; yy = y + 18;
font.drawString("Position", left + offset, yy + 5, 0xFFFFFF); font.draw(ms, "Position", left + offset, yy + 5, 0xFFFFFF);
font.drawString("X", left + 40 + offset, yy + 5, 0xFFFFFF); font.draw(ms, "X", left + 40 + offset, yy + 5, 0xFFFFFF);
textMirrorPosX.y = yy; textMirrorPosX.y = yy;
font.drawString("Y", left + 120 + offset, yy + 5, 0xFFFFFF); font.draw(ms, "Y", left + 120 + offset, yy + 5, 0xFFFFFF);
textMirrorPosY.y = yy; textMirrorPosY.y = yy;
font.drawString("Z", left + 200 + offset, yy + 5, 0xFFFFFF); font.draw(ms, "Z", left + 200 + offset, yy + 5, 0xFFFFFF);
textMirrorPosZ.y = yy; textMirrorPosZ.y = yy;
yy = y + 50; yy = y + 50;
font.drawString("Direction", left + offset, yy + 2, 0xFFFFFF); font.draw(ms, "Direction", left + offset, yy + 2, 0xFFFFFF);
buttonMirrorX.y = yy; buttonMirrorX.y = yy;
buttonMirrorY.y = yy; buttonMirrorY.y = yy;
buttonMirrorZ.y = yy; buttonMirrorZ.y = yy;
font.drawString("Radius", left + 176 + offset, yy + 2, 0xFFFFFF); font.draw(ms, "Radius", left + 176 + offset, yy + 2, 0xFFFFFF);
textMirrorRadius.y = yy - 3; textMirrorRadius.y = yy - 3;
yy = y + 72; yy = y + 72;
@@ -205,22 +207,21 @@ public class MirrorSettingsGui extends GuiCollapsibleScrollEntry {
buttonDrawLines.y = yy; buttonDrawLines.y = yy;
buttonDrawPlanes.y = yy; buttonDrawPlanes.y = yy;
mirrorButtonList.forEach(button -> button.render(mouseX, mouseY, partialTicks)); mirrorButtonList.forEach(button -> button.render(ms, mouseX, mouseY, partialTicks));
mirrorIconButtonList.forEach(button -> button.render(mouseX, mouseY, partialTicks)); mirrorIconButtonList.forEach(button -> button.render(ms, mouseX, mouseY, partialTicks));
mirrorNumberFieldList.forEach(numberField -> numberField.drawNumberField(mouseX, mouseY, partialTicks)); mirrorNumberFieldList.forEach(numberField -> numberField.drawNumberField(ms, mouseX, mouseY, partialTicks));
} else { } else {
buttonMirrorEnabled.y = yy; buttonMirrorEnabled.y = yy;
font.drawString("Mirror disabled", left + offset, yy + 2, 0x999999); font.draw(ms, "Mirror disabled", left + offset, yy + 2, 0x999999);
} }
} }
public void drawTooltip(Screen guiScreen, int mouseX, int mouseY) { public void drawTooltip(MatrixStack ms, Screen guiScreen, int mouseX, int mouseY) {
//Draw tooltips last //Draw tooltips last
if (buttonMirrorEnabled.isChecked()) if (buttonMirrorEnabled.isChecked()) {
{ mirrorIconButtonList.forEach(iconButton -> iconButton.drawTooltip(ms, scrollPane.parent, mouseX, mouseY));
mirrorIconButtonList.forEach(iconButton -> iconButton.drawTooltip(scrollPane.parent, mouseX, mouseY)); mirrorNumberFieldList.forEach(numberField -> numberField.drawTooltip(ms, scrollPane.parent, mouseX, mouseY));
mirrorNumberFieldList.forEach(numberField -> numberField.drawTooltip(scrollPane.parent, mouseX, mouseY));
} }
} }
@@ -240,7 +241,7 @@ public class MirrorSettingsGui extends GuiCollapsibleScrollEntry {
boolean insideMirrorEnabledLabel = mouseX >= left && mouseX < right && relativeY >= -2 && relativeY < 12; boolean insideMirrorEnabledLabel = mouseX >= left && mouseX < right && relativeY >= -2 && relativeY < 12;
if (insideMirrorEnabledLabel) { if (insideMirrorEnabledLabel) {
buttonMirrorEnabled.playDownSound(this.mc.getSoundHandler()); buttonMirrorEnabled.playDownSound(this.mc.getSoundManager());
buttonMirrorEnabled.onClick(mouseX, mouseY); buttonMirrorEnabled.onClick(mouseX, mouseY);
} }
@@ -250,9 +251,9 @@ public class MirrorSettingsGui extends GuiCollapsibleScrollEntry {
public Mirror.MirrorSettings getMirrorSettings() { public Mirror.MirrorSettings getMirrorSettings() {
boolean mirrorEnabled = buttonMirrorEnabled.isChecked(); boolean mirrorEnabled = buttonMirrorEnabled.isChecked();
Vec3d mirrorPos = new Vec3d(0, 64, 0); Vector3d mirrorPos = new Vector3d(0, 64, 0);
try { try {
mirrorPos = new Vec3d(textMirrorPosX.getNumber(), textMirrorPosY.getNumber(), textMirrorPosZ.getNumber()); mirrorPos = new Vector3d(textMirrorPosX.getNumber(), textMirrorPosY.getNumber(), textMirrorPosZ.getNumber());
} catch (NumberFormatException | NullPointerException ex) { } catch (NumberFormatException | NullPointerException ex) {
EffortlessBuilding.log(mc.player, "Mirror position not a valid number."); EffortlessBuilding.log(mc.player, "Mirror position not a valid number.");
} }

View File

@@ -1,9 +1,10 @@
package nl.requios.effortlessbuilding.gui.buildmodifier; package nl.requios.effortlessbuilding.gui.buildmodifier;
import com.mojang.blaze3d.matrix.MatrixStack;
import net.minecraft.client.Minecraft; import net.minecraft.client.Minecraft;
import net.minecraft.client.gui.screen.Screen; import net.minecraft.client.gui.screen.Screen;
import net.minecraft.client.gui.widget.button.Button; import net.minecraft.client.gui.widget.button.Button;
import net.minecraft.util.text.ITextComponent; import net.minecraft.util.text.StringTextComponent;
import net.minecraft.util.text.TranslationTextComponent; import net.minecraft.util.text.TranslationTextComponent;
import net.minecraftforge.api.distmarker.Dist; import net.minecraftforge.api.distmarker.Dist;
import net.minecraftforge.api.distmarker.OnlyIn; import net.minecraftforge.api.distmarker.OnlyIn;
@@ -49,8 +50,8 @@ public class ModifierSettingsGui extends Screen {
//Close button //Close button
int y = height - 26; int y = height - 26;
buttonClose = new Button(width / 2 - 100, y, 200, 20, "Close", (button) -> { buttonClose = new Button(width / 2 - 100, y, 200, 20, new StringTextComponent("Close"), (button) -> {
Minecraft.getInstance().player.closeScreen(); Minecraft.getInstance().player.closeContainer();
}); });
buttons.add(buttonClose); buttons.add(buttonClose);
} }
@@ -66,14 +67,14 @@ public class ModifierSettingsGui extends Screen {
@Override @Override
//Set colors using GL11, use the fontObj field to display text //Set colors using GL11, use the fontObj field to display text
//Use drawTexturedModalRect() to transfers areas of a texture resource to the screen //Use drawTexturedModalRect() to transfers areas of a texture resource to the screen
public void render(int mouseX, int mouseY, float partialTicks) { public void render(MatrixStack ms, int mouseX, int mouseY, float partialTicks) {
this.renderBackground(); this.renderBackground(ms);
scrollPane.render(mouseX, mouseY, partialTicks); scrollPane.render(ms, mouseX, mouseY, partialTicks);
buttonClose.render(mouseX, mouseY, partialTicks); buttonClose.render(ms, mouseX, mouseY, partialTicks);
scrollPane.drawTooltip(this, mouseX, mouseY); scrollPane.drawTooltip(ms, this, mouseX, mouseY);
} }
@@ -81,8 +82,8 @@ public class ModifierSettingsGui extends Screen {
public boolean charTyped(char typedChar, int keyCode) { public boolean charTyped(char typedChar, int keyCode) {
super.charTyped(typedChar, keyCode); super.charTyped(typedChar, keyCode);
scrollPane.charTyped(typedChar, keyCode); scrollPane.charTyped(typedChar, keyCode);
if (keyCode == ClientProxy.keyBindings[0].getKey().getKeyCode()) { if (keyCode == ClientProxy.keyBindings[0].getKey().getValue()) {
minecraft.player.closeScreen(); minecraft.player.closeContainer();
} }
return false; return false;
} }
@@ -96,8 +97,7 @@ public class ModifierSettingsGui extends Screen {
@Override @Override
public boolean mouseReleased(double mouseX, double mouseY, int state) { public boolean mouseReleased(double mouseX, double mouseY, int state) {
if (state != 0 || !scrollPane.mouseReleased(mouseX, mouseY, state)) if (state != 0 || !scrollPane.mouseReleased(mouseX, mouseY, state)) {
{
return super.mouseReleased(mouseX, mouseY, state); return super.mouseReleased(mouseX, mouseY, state);
} }
return false; return false;
@@ -137,8 +137,7 @@ public class ModifierSettingsGui extends Screen {
//Send to server //Send to server
PacketHandler.INSTANCE.sendToServer(new ModifierSettingsMessage(modifierSettings)); PacketHandler.INSTANCE.sendToServer(new ModifierSettingsMessage(modifierSettings));
//TODO fix not being able to scroll after this gui has opened Minecraft.getInstance().mouseHandler.grabMouse();
Minecraft.getInstance().mouseHelper.grabMouse();
} }
} }

View File

@@ -1,10 +1,12 @@
package nl.requios.effortlessbuilding.gui.buildmodifier; package nl.requios.effortlessbuilding.gui.buildmodifier;
import com.mojang.blaze3d.matrix.MatrixStack;
import net.minecraft.client.gui.screen.Screen;
import net.minecraft.client.gui.widget.Widget; import net.minecraft.client.gui.widget.Widget;
import net.minecraft.client.gui.widget.button.Button; import net.minecraft.client.gui.widget.button.Button;
import net.minecraft.client.gui.screen.Screen;
import net.minecraft.util.ResourceLocation; import net.minecraft.util.ResourceLocation;
import net.minecraft.util.math.Vec3d; import net.minecraft.util.math.vector.Vector3d;
import net.minecraft.util.text.StringTextComponent;
import net.minecraft.util.text.TextFormatting; import net.minecraft.util.text.TextFormatting;
import net.minecraftforge.api.distmarker.Dist; import net.minecraftforge.api.distmarker.Dist;
import net.minecraftforge.api.distmarker.OnlyIn; import net.minecraftforge.api.distmarker.OnlyIn;
@@ -55,75 +57,75 @@ public class RadialMirrorSettingsGui extends GuiCollapsibleScrollEntry {
textRadialMirrorPosX = new GuiNumberField(font, buttonList, left + 58, y, 62, 18); textRadialMirrorPosX = new GuiNumberField(font, buttonList, left + 58, y, 62, 18);
textRadialMirrorPosX.setNumber(0); textRadialMirrorPosX.setNumber(0);
textRadialMirrorPosX.setTooltip( textRadialMirrorPosX.setTooltip(
Arrays.asList("The position of the radial mirror.", TextFormatting.GRAY + "For odd numbered builds add 0.5.")); Arrays.asList(new StringTextComponent("The position of the radial mirror."), new StringTextComponent("For odd numbered builds add 0.5.").withStyle(TextFormatting.GRAY)));
radialMirrorNumberFieldList.add(textRadialMirrorPosX); radialMirrorNumberFieldList.add(textRadialMirrorPosX);
textRadialMirrorPosY = new GuiNumberField(font, buttonList, left + 138, y, 62, 18); textRadialMirrorPosY = new GuiNumberField(font, buttonList, left + 138, y, 62, 18);
textRadialMirrorPosY.setNumber(64); textRadialMirrorPosY.setNumber(64);
textRadialMirrorPosY.setTooltip(Arrays.asList("The position of the radial mirror.", TextFormatting.GRAY + "For odd numbered builds add 0.5.")); textRadialMirrorPosY.setTooltip(Arrays.asList(new StringTextComponent("The position of the radial mirror."), new StringTextComponent("For odd numbered builds add 0.5.").withStyle(TextFormatting.GRAY)));
radialMirrorNumberFieldList.add(textRadialMirrorPosY); radialMirrorNumberFieldList.add(textRadialMirrorPosY);
textRadialMirrorPosZ = new GuiNumberField(font, buttonList, left + 218, y, 62, 18); textRadialMirrorPosZ = new GuiNumberField(font, buttonList, left + 218, y, 62, 18);
textRadialMirrorPosZ.setNumber(0); textRadialMirrorPosZ.setNumber(0);
textRadialMirrorPosZ.setTooltip(Arrays.asList("The position of the radial mirror.", TextFormatting.GRAY + "For odd numbered builds add 0.5.")); textRadialMirrorPosZ.setTooltip(Arrays.asList(new StringTextComponent("The position of the radial mirror."), new StringTextComponent("For odd numbered builds add 0.5.").withStyle(TextFormatting.GRAY)));
radialMirrorNumberFieldList.add(textRadialMirrorPosZ); radialMirrorNumberFieldList.add(textRadialMirrorPosZ);
y = top + 47; y = top + 47;
textRadialMirrorSlices = new GuiNumberField(font, buttonList, left + 55, y, 50, 18); textRadialMirrorSlices = new GuiNumberField(font, buttonList, left + 55, y, 50, 18);
textRadialMirrorSlices.setNumber(4); textRadialMirrorSlices.setNumber(4);
textRadialMirrorSlices.setTooltip(Arrays.asList("The number of repeating slices.", TextFormatting.GRAY + "Minimally 2.")); textRadialMirrorSlices.setTooltip(Arrays.asList(new StringTextComponent("The number of repeating slices."), new StringTextComponent("Minimally 2.").withStyle(TextFormatting.GRAY)));
radialMirrorNumberFieldList.add(textRadialMirrorSlices); radialMirrorNumberFieldList.add(textRadialMirrorSlices);
textRadialMirrorRadius = new GuiNumberField(font, buttonList, left + 218, y, 62, 18); textRadialMirrorRadius = new GuiNumberField(font, buttonList, left + 218, y, 62, 18);
textRadialMirrorRadius.setNumber(50); textRadialMirrorRadius.setNumber(50);
//TODO change to diameter (remove /2) //TODO change to diameter (remove /2)
textRadialMirrorRadius.setTooltip(Arrays.asList("How far the radial mirror reaches from its center position.", textRadialMirrorRadius.setTooltip(Arrays.asList(new StringTextComponent("How far the radial mirror reaches from its center position."),
TextFormatting.GRAY + "Max: " + TextFormatting.GOLD + ReachHelper.getMaxReach(mc.player) / 2, new StringTextComponent("Max: ").withStyle(TextFormatting.GRAY).append(new StringTextComponent(String.valueOf(ReachHelper.getMaxReach(mc.player) / 2)).withStyle(TextFormatting.GOLD)),
TextFormatting.GRAY + "Upgradeable in survival with reach upgrades.")); new StringTextComponent("Upgradeable in survival with reach upgrades.").withStyle(TextFormatting.GRAY)));
radialMirrorNumberFieldList.add(textRadialMirrorRadius); radialMirrorNumberFieldList.add(textRadialMirrorRadius);
y = top + 72; y = top + 72;
buttonCurrentPosition = new GuiIconButton(left + 5, y, 0, 0, BUILDING_ICONS, button -> { buttonCurrentPosition = new GuiIconButton(left + 5, y, 0, 0, BUILDING_ICONS, button -> {
Vec3d pos = new Vec3d(Math.floor(mc.player.posX) + 0.5, Math.floor(mc.player.posY) + 0.5, Math.floor(mc.player.posZ) + 0.5); Vector3d pos = new Vector3d(Math.floor(mc.player.getX()) + 0.5, Math.floor(mc.player.getY()) + 0.5, Math.floor(mc.player.getZ()) + 0.5);
textRadialMirrorPosX.setNumber(pos.x); textRadialMirrorPosX.setNumber(pos.x);
textRadialMirrorPosY.setNumber(pos.y); textRadialMirrorPosY.setNumber(pos.y);
textRadialMirrorPosZ.setNumber(pos.z); textRadialMirrorPosZ.setNumber(pos.z);
}); });
buttonCurrentPosition.setTooltip("Set radial mirror position to current player position"); buttonCurrentPosition.setTooltip(new StringTextComponent("Set radial mirror position to current player position"));
radialMirrorIconButtonList.add(buttonCurrentPosition); radialMirrorIconButtonList.add(buttonCurrentPosition);
buttonToggleOdd = new GuiIconButton(left + 35, y, 0, 20, BUILDING_ICONS, button -> { buttonToggleOdd = new GuiIconButton(left + 35, y, 0, 20, BUILDING_ICONS, button -> {
toggleOdd = !toggleOdd; toggleOdd = !toggleOdd;
buttonToggleOdd.setUseAlternateIcon(toggleOdd); buttonToggleOdd.setUseAlternateIcon(toggleOdd);
if (toggleOdd) { if (toggleOdd) {
buttonToggleOdd.setTooltip(Arrays.asList("Set mirror position to corner of block", "for even numbered builds")); buttonToggleOdd.setTooltip(Arrays.asList(new StringTextComponent("Set mirror position to corner of block"), new StringTextComponent("for even numbered builds")));
textRadialMirrorPosX.setNumber(textRadialMirrorPosX.getNumber() + 0.5); textRadialMirrorPosX.setNumber(textRadialMirrorPosX.getNumber() + 0.5);
textRadialMirrorPosY.setNumber(textRadialMirrorPosY.getNumber() + 0.5); textRadialMirrorPosY.setNumber(textRadialMirrorPosY.getNumber() + 0.5);
textRadialMirrorPosZ.setNumber(textRadialMirrorPosZ.getNumber() + 0.5); textRadialMirrorPosZ.setNumber(textRadialMirrorPosZ.getNumber() + 0.5);
} else { } else {
buttonToggleOdd.setTooltip(Arrays.asList("Set mirror position to middle of block", "for odd numbered builds")); buttonToggleOdd.setTooltip(Arrays.asList(new StringTextComponent("Set mirror position to middle of block"), new StringTextComponent("for odd numbered builds")));
textRadialMirrorPosX.setNumber(Math.floor(textRadialMirrorPosX.getNumber())); textRadialMirrorPosX.setNumber(Math.floor(textRadialMirrorPosX.getNumber()));
textRadialMirrorPosY.setNumber(Math.floor(textRadialMirrorPosY.getNumber())); textRadialMirrorPosY.setNumber(Math.floor(textRadialMirrorPosY.getNumber()));
textRadialMirrorPosZ.setNumber(Math.floor(textRadialMirrorPosZ.getNumber())); textRadialMirrorPosZ.setNumber(Math.floor(textRadialMirrorPosZ.getNumber()));
} }
}); });
buttonToggleOdd.setTooltip(Arrays.asList("Set radial mirror position to middle of block", "for odd numbered builds")); buttonToggleOdd.setTooltip(Arrays.asList(new StringTextComponent("Set radial mirror position to middle of block"), new StringTextComponent("for odd numbered builds")));
radialMirrorIconButtonList.add(buttonToggleOdd); radialMirrorIconButtonList.add(buttonToggleOdd);
buttonDrawLines = new GuiIconButton(left + 65, y, 0, 40, BUILDING_ICONS, button -> { buttonDrawLines = new GuiIconButton(left + 65, y, 0, 40, BUILDING_ICONS, button -> {
drawLines = !drawLines; drawLines = !drawLines;
buttonDrawLines.setUseAlternateIcon(drawLines); buttonDrawLines.setUseAlternateIcon(drawLines);
buttonDrawLines.setTooltip(drawLines ? "Hide lines" : "Show lines"); buttonDrawLines.setTooltip(new StringTextComponent(drawLines ? "Hide lines" : "Show lines"));
}); });
buttonDrawLines.setTooltip("Show lines"); buttonDrawLines.setTooltip(new StringTextComponent("Show lines"));
radialMirrorIconButtonList.add(buttonDrawLines); radialMirrorIconButtonList.add(buttonDrawLines);
buttonDrawPlanes = new GuiIconButton(left + 95, y, 0, 60, BUILDING_ICONS, button -> { buttonDrawPlanes = new GuiIconButton(left + 95, y, 0, 60, BUILDING_ICONS, button -> {
drawPlanes = !drawPlanes; drawPlanes = !drawPlanes;
buttonDrawPlanes.setUseAlternateIcon(drawPlanes); buttonDrawPlanes.setUseAlternateIcon(drawPlanes);
buttonDrawPlanes.setTooltip(drawPlanes ? "Hide area" : "Show area"); buttonDrawPlanes.setTooltip(new StringTextComponent(drawPlanes ? "Hide area" : "Show area"));
}); });
buttonDrawPlanes.setTooltip("Show area"); buttonDrawPlanes.setTooltip(new StringTextComponent("Show area"));
radialMirrorIconButtonList.add(buttonDrawPlanes); radialMirrorIconButtonList.add(buttonDrawPlanes);
y = top + 76; y = top + 76;
@@ -144,14 +146,14 @@ public class RadialMirrorSettingsGui extends GuiCollapsibleScrollEntry {
drawPlanes = r.drawPlanes; drawPlanes = r.drawPlanes;
buttonDrawLines.setUseAlternateIcon(drawLines); buttonDrawLines.setUseAlternateIcon(drawLines);
buttonDrawPlanes.setUseAlternateIcon(drawPlanes); buttonDrawPlanes.setUseAlternateIcon(drawPlanes);
buttonDrawLines.setTooltip(drawLines ? "Hide lines" : "Show lines"); buttonDrawLines.setTooltip(new StringTextComponent(drawLines ? "Hide lines" : "Show lines"));
buttonDrawPlanes.setTooltip(drawPlanes ? "Hide area" : "Show area"); buttonDrawPlanes.setTooltip(new StringTextComponent(drawPlanes ? "Hide area" : "Show area"));
if (textRadialMirrorPosX.getNumber() == Math.floor(textRadialMirrorPosX.getNumber())) { if (textRadialMirrorPosX.getNumber() == Math.floor(textRadialMirrorPosX.getNumber())) {
toggleOdd = false; toggleOdd = false;
buttonToggleOdd.setTooltip(Arrays.asList("Set radial mirror position to middle of block", "for odd numbered builds")); buttonToggleOdd.setTooltip(Arrays.asList(new StringTextComponent("Set radial mirror position to middle of block"), new StringTextComponent("for odd numbered builds")));
} else { } else {
toggleOdd = true; toggleOdd = true;
buttonToggleOdd.setTooltip(Arrays.asList("Set radial mirror position to corner of block", "for even numbered builds")); buttonToggleOdd.setTooltip(Arrays.asList(new StringTextComponent("Set radial mirror position to corner of block"), new StringTextComponent("for even numbered builds")));
} }
buttonToggleOdd.setUseAlternateIcon(toggleOdd); buttonToggleOdd.setUseAlternateIcon(toggleOdd);
} }
@@ -168,30 +170,30 @@ public class RadialMirrorSettingsGui extends GuiCollapsibleScrollEntry {
@Override @Override
public void drawEntry(int slotIndex, int x, int y, int listWidth, int slotHeight, int mouseX, int mouseY, public void drawEntry(MatrixStack ms, int slotIndex, int x, int y, int listWidth, int slotHeight, int mouseX, int mouseY,
boolean isSelected, float partialTicks) { boolean isSelected, float partialTicks) {
int yy = y; int yy = y;
int offset = 8; int offset = 8;
buttonRadialMirrorEnabled.render(mouseX, mouseY, partialTicks); buttonRadialMirrorEnabled.render(ms, mouseX, mouseY, partialTicks);
if (buttonRadialMirrorEnabled.isChecked()) { if (buttonRadialMirrorEnabled.isChecked()) {
buttonRadialMirrorEnabled.y = yy; buttonRadialMirrorEnabled.y = yy;
font.drawString("Radial mirror enabled", left + offset, yy + 2, 0xFFFFFF); font.draw(ms, "Radial mirror enabled", left + offset, yy + 2, 0xFFFFFF);
yy = y + 18; yy = y + 18;
font.drawString("Position", left + offset, yy + 5, 0xFFFFFF); font.draw(ms, "Position", left + offset, yy + 5, 0xFFFFFF);
font.drawString("X", left + 40 + offset, yy + 5, 0xFFFFFF); font.draw(ms, "X", left + 40 + offset, yy + 5, 0xFFFFFF);
textRadialMirrorPosX.y = yy; textRadialMirrorPosX.y = yy;
font.drawString("Y", left + 120 + offset, yy + 5, 0xFFFFFF); font.draw(ms, "Y", left + 120 + offset, yy + 5, 0xFFFFFF);
textRadialMirrorPosY.y = yy; textRadialMirrorPosY.y = yy;
font.drawString("Z", left + 200 + offset, yy + 5, 0xFFFFFF); font.draw(ms, "Z", left + 200 + offset, yy + 5, 0xFFFFFF);
textRadialMirrorPosZ.y = yy; textRadialMirrorPosZ.y = yy;
yy = y + 50; yy = y + 50;
font.drawString("Slices", left + offset, yy + 2, 0xFFFFFF); font.draw(ms, "Slices", left + offset, yy + 2, 0xFFFFFF);
textRadialMirrorSlices.y = yy - 3; textRadialMirrorSlices.y = yy - 3;
font.drawString("Radius", left + 176 + offset, yy + 2, 0xFFFFFF); font.draw(ms, "Radius", left + 176 + offset, yy + 2, 0xFFFFFF);
textRadialMirrorRadius.y = yy - 3; textRadialMirrorRadius.y = yy - 3;
yy = y + 72; yy = y + 72;
@@ -203,23 +205,22 @@ public class RadialMirrorSettingsGui extends GuiCollapsibleScrollEntry {
yy = y + 76; yy = y + 76;
buttonRadialMirrorAlternate.y = yy; buttonRadialMirrorAlternate.y = yy;
radialMirrorButtonList.forEach(button -> button.render(mouseX, mouseY, partialTicks)); radialMirrorButtonList.forEach(button -> button.render(ms, mouseX, mouseY, partialTicks));
radialMirrorIconButtonList.forEach(button -> button.render(mouseX, mouseY, partialTicks)); radialMirrorIconButtonList.forEach(button -> button.render(ms, mouseX, mouseY, partialTicks));
radialMirrorNumberFieldList radialMirrorNumberFieldList
.forEach(numberField -> numberField.drawNumberField(mouseX, mouseY, partialTicks)); .forEach(numberField -> numberField.drawNumberField(ms, mouseX, mouseY, partialTicks));
} else { } else {
buttonRadialMirrorEnabled.y = yy; buttonRadialMirrorEnabled.y = yy;
font.drawString("Radial mirror disabled", left + offset, yy + 2, 0x999999); font.draw(ms, "Radial mirror disabled", left + offset, yy + 2, 0x999999);
} }
} }
public void drawTooltip(Screen guiScreen, int mouseX, int mouseY) { public void drawTooltip(MatrixStack ms, Screen guiScreen, int mouseX, int mouseY) {
//Draw tooltips last //Draw tooltips last
if (buttonRadialMirrorEnabled.isChecked()) if (buttonRadialMirrorEnabled.isChecked()) {
{ radialMirrorIconButtonList.forEach(iconButton -> iconButton.drawTooltip(ms, scrollPane.parent, mouseX, mouseY));
radialMirrorIconButtonList.forEach(iconButton -> iconButton.drawTooltip(scrollPane.parent, mouseX, mouseY)); radialMirrorNumberFieldList.forEach(numberField -> numberField.drawTooltip(ms, scrollPane.parent, mouseX, mouseY));
radialMirrorNumberFieldList.forEach(numberField -> numberField.drawTooltip(scrollPane.parent, mouseX, mouseY));
} }
} }
@@ -239,7 +240,7 @@ public class RadialMirrorSettingsGui extends GuiCollapsibleScrollEntry {
boolean insideRadialMirrorEnabledLabel = mouseX >= left && mouseX < right && relativeY >= -2 && relativeY < 12; boolean insideRadialMirrorEnabledLabel = mouseX >= left && mouseX < right && relativeY >= -2 && relativeY < 12;
if (insideRadialMirrorEnabledLabel) { if (insideRadialMirrorEnabledLabel) {
buttonRadialMirrorEnabled.playDownSound(this.mc.getSoundHandler()); buttonRadialMirrorEnabled.playDownSound(this.mc.getSoundManager());
buttonRadialMirrorEnabled.onClick(mouseX, mouseY); buttonRadialMirrorEnabled.onClick(mouseX, mouseY);
} }
@@ -249,9 +250,9 @@ public class RadialMirrorSettingsGui extends GuiCollapsibleScrollEntry {
public RadialMirror.RadialMirrorSettings getRadialMirrorSettings() { public RadialMirror.RadialMirrorSettings getRadialMirrorSettings() {
boolean radialMirrorEnabled = buttonRadialMirrorEnabled.isChecked(); boolean radialMirrorEnabled = buttonRadialMirrorEnabled.isChecked();
Vec3d radialMirrorPos = new Vec3d(0, 64, 0); Vector3d radialMirrorPos = new Vector3d(0, 64, 0);
try { try {
radialMirrorPos = new Vec3d(textRadialMirrorPosX.getNumber(), textRadialMirrorPosY.getNumber(), textRadialMirrorPosZ radialMirrorPos = new Vector3d(textRadialMirrorPosX.getNumber(), textRadialMirrorPosY.getNumber(), textRadialMirrorPosZ
.getNumber()); .getNumber());
} catch (NumberFormatException | NullPointerException ex) { } catch (NumberFormatException | NullPointerException ex) {
EffortlessBuilding.log(mc.player, "Radial mirror position not a valid number."); EffortlessBuilding.log(mc.player, "Radial mirror position not a valid number.");

View File

@@ -1,66 +1,62 @@
package nl.requios.effortlessbuilding.gui.elements; package nl.requios.effortlessbuilding.gui.elements;
import com.mojang.blaze3d.matrix.MatrixStack;
import net.minecraft.client.Minecraft; import net.minecraft.client.Minecraft;
import net.minecraft.client.gui.widget.button.Button; import net.minecraft.client.gui.widget.button.Button;
import net.minecraftforge.fml.client.config.GuiUtils; import net.minecraft.util.text.StringTextComponent;
import net.minecraftforge.fml.client.gui.GuiUtils;
import javax.annotation.ParametersAreNonnullByDefault;
/** /**
* This class provides a checkbox style control. * This class provides a checkbox style control.
*/ */
public class GuiCheckBoxFixed extends Button @ParametersAreNonnullByDefault
{ public class GuiCheckBoxFixed extends Button {
private final int boxWidth;
private boolean isChecked; private boolean isChecked;
private int boxWidth;
public GuiCheckBoxFixed(int xPos, int yPos, String displayString, boolean isChecked) public GuiCheckBoxFixed(int xPos, int yPos, String displayString, boolean isChecked) {
{ super(xPos, yPos, Minecraft.getInstance().font.width(displayString) + 2 + 11, 11, new StringTextComponent(displayString), b -> {
super(xPos, yPos, Minecraft.getInstance().fontRenderer.getStringWidth(displayString) + 2 + 11, 11, displayString, b -> {}); });
this.isChecked = isChecked; this.isChecked = isChecked;
this.boxWidth = 11; this.boxWidth = 11;
this.height = 11; this.height = 11;
this.width = this.boxWidth + 2 + Minecraft.getInstance().fontRenderer.getStringWidth(displayString); this.width = this.boxWidth + 2 + Minecraft.getInstance().font.width(displayString);
} }
@Override @Override
public void renderButton(int mouseX, int mouseY, float partial) public void renderButton(MatrixStack ms, int mouseX, int mouseY, float partial) {
{ if (this.visible) {
if (this.visible)
{
Minecraft mc = Minecraft.getInstance(); Minecraft mc = Minecraft.getInstance();
this.isHovered = mouseX >= this.x && mouseY >= this.y && mouseX < this.x + this.boxWidth && mouseY < this.y + this.height; this.isHovered = mouseX >= this.x && mouseY >= this.y && mouseX < this.x + this.boxWidth && mouseY < this.y + this.height;
GuiUtils.drawContinuousTexturedBox(WIDGETS_LOCATION, this.x, this.y, 0, 46, this.boxWidth, this.height, 200, 20, 2, 3, 2, 2, this.blitOffset); GuiUtils.drawContinuousTexturedBox(WIDGETS_LOCATION, this.x, this.y, 0, 46, this.boxWidth, this.height, 200, 20, 2, 3, 2, 2, this.getBlitOffset());
this.renderBg(mc, mouseX, mouseY); this.renderBg(ms, mc, mouseX, mouseY);
int color = 14737632; int color = 14737632;
if (packedFGColor != 0) if (packedFGColor != 0) {
{
color = packedFGColor; color = packedFGColor;
} } else if (!this.active) {
else if (!this.active)
{
color = 10526880; color = 10526880;
} }
if (this.isChecked) if (this.isChecked)
this.drawCenteredString(mc.fontRenderer, "x", this.x + this.boxWidth / 2 + 1, this.y + 1, 14737632); drawCenteredString(ms, mc.font, "x", this.x + this.boxWidth / 2 + 1, this.y + 1, 14737632);
this.drawString(mc.fontRenderer, getMessage(), this.x + this.boxWidth + 2, this.y + 2, color); drawString(ms, mc.font, getMessage(), this.x + this.boxWidth + 2, this.y + 2, color);
} }
} }
@Override @Override
public void onPress() public void onPress() {
{
this.isChecked = !this.isChecked; this.isChecked = !this.isChecked;
} }
public boolean isChecked() public boolean isChecked() {
{
return this.isChecked; return this.isChecked;
} }
public void setIsChecked(boolean isChecked) public void setIsChecked(boolean isChecked) {
{
this.isChecked = isChecked; this.isChecked = isChecked;
} }
} }

View File

@@ -1,10 +1,10 @@
package nl.requios.effortlessbuilding.gui.elements; package nl.requios.effortlessbuilding.gui.elements;
import com.mojang.blaze3d.matrix.MatrixStack;
import net.minecraft.client.Minecraft; import net.minecraft.client.Minecraft;
import net.minecraft.client.gui.FontRenderer; import net.minecraft.client.gui.FontRenderer;
import net.minecraft.client.gui.widget.Widget;
import net.minecraft.client.gui.widget.button.Button;
import net.minecraft.client.gui.screen.Screen; import net.minecraft.client.gui.screen.Screen;
import net.minecraft.client.gui.widget.Widget;
import net.minecraftforge.api.distmarker.Dist; import net.minecraftforge.api.distmarker.Dist;
import net.minecraftforge.api.distmarker.OnlyIn; import net.minecraftforge.api.distmarker.OnlyIn;
@@ -39,7 +39,7 @@ public abstract class GuiCollapsibleScrollEntry implements GuiScrollPane.IScroll
} }
@Override @Override
public void drawTooltip(Screen guiScreen, int mouseX, int mouseY) { public void drawTooltip(MatrixStack ms, Screen guiScreen, int mouseX, int mouseY) {
} }
@Override @Override

View File

@@ -1,22 +1,27 @@
package nl.requios.effortlessbuilding.gui.elements; package nl.requios.effortlessbuilding.gui.elements;
import com.mojang.blaze3d.matrix.MatrixStack;
import net.minecraft.client.Minecraft; import net.minecraft.client.Minecraft;
import net.minecraft.client.gui.widget.button.Button;
import net.minecraft.client.gui.screen.Screen; import net.minecraft.client.gui.screen.Screen;
import net.minecraft.client.gui.widget.button.Button;
import net.minecraft.util.ResourceLocation; import net.minecraft.util.ResourceLocation;
import net.minecraft.util.text.ITextComponent;
import net.minecraft.util.text.StringTextComponent;
import net.minecraftforge.api.distmarker.Dist; import net.minecraftforge.api.distmarker.Dist;
import net.minecraftforge.api.distmarker.OnlyIn; import net.minecraftforge.api.distmarker.OnlyIn;
import javax.annotation.ParametersAreNonnullByDefault;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Arrays; import java.util.Collections;
import java.util.List; import java.util.List;
@OnlyIn(Dist.CLIENT) @OnlyIn(Dist.CLIENT)
@ParametersAreNonnullByDefault
public class GuiIconButton extends Button { public class GuiIconButton extends Button {
private final ResourceLocation resourceLocation; private final ResourceLocation resourceLocation;
private final int iconX, iconY, iconWidth, iconHeight, iconAltX, iconAltY; private final int iconX, iconY, iconWidth, iconHeight, iconAltX, iconAltY;
List<String> tooltip = new ArrayList<>(); List<ITextComponent> tooltip = new ArrayList<>();
private boolean useAltIcon = false; private boolean useAltIcon = false;
public GuiIconButton(int x, int y, int iconX, int iconY, ResourceLocation resourceLocation, Button.IPressable onPress) { public GuiIconButton(int x, int y, int iconX, int iconY, ResourceLocation resourceLocation, Button.IPressable onPress) {
@@ -24,7 +29,7 @@ public class GuiIconButton extends Button {
} }
public GuiIconButton(int x, int y, int width, int height, int iconX, int iconY, int iconWidth, int iconHeight, int iconAltX, int iconAltY, ResourceLocation resourceLocation, Button.IPressable onPress) { public GuiIconButton(int x, int y, int width, int height, int iconX, int iconY, int iconWidth, int iconHeight, int iconAltX, int iconAltY, ResourceLocation resourceLocation, Button.IPressable onPress) {
super(x, y, width, height, "", onPress); super(x, y, width, height, StringTextComponent.EMPTY, onPress);
this.iconX = iconX; this.iconX = iconX;
this.iconY = iconY; this.iconY = iconY;
this.iconWidth = iconWidth; this.iconWidth = iconWidth;
@@ -34,11 +39,11 @@ public class GuiIconButton extends Button {
this.resourceLocation = resourceLocation; this.resourceLocation = resourceLocation;
} }
public void setTooltip(String tooltip) { public void setTooltip(ITextComponent tooltip) {
setTooltip(Arrays.asList(tooltip)); setTooltip(Collections.singletonList(tooltip));
} }
public void setTooltip(List<String> tooltip) { public void setTooltip(List<ITextComponent> tooltip) {
this.tooltip = tooltip; this.tooltip = tooltip;
} }
@@ -47,33 +52,29 @@ public class GuiIconButton extends Button {
} }
@Override @Override
public void render(int mouseX, int mouseY, float partialTicks) { public void render(MatrixStack ms, int mouseX, int mouseY, float partialTicks) {
super.render(mouseX, mouseY, partialTicks); super.render(ms, mouseX, mouseY, partialTicks);
if (this.visible) if (this.visible) {
{
this.isHovered = mouseX >= this.x && mouseY >= this.y && mouseX < this.x + this.width && mouseY < this.y + this.height; this.isHovered = mouseX >= this.x && mouseY >= this.y && mouseX < this.x + this.width && mouseY < this.y + this.height;
Minecraft.getInstance().getTextureManager().bindTexture(this.resourceLocation); Minecraft.getInstance().getTextureManager().bind(this.resourceLocation);
int currentIconX = this.iconX; int currentIconX = this.iconX;
int currentIconY = this.iconY; int currentIconY = this.iconY;
if (useAltIcon) if (useAltIcon) {
{
currentIconX += iconAltX; currentIconX += iconAltX;
currentIconY += iconAltY; currentIconY += iconAltY;
} }
//Draws a textured rectangle at the current z-value. Used to be drawTexturedModalRect in Gui. //Draws a textured rectangle at the current z-value. Used to be drawTexturedModalRect in Gui.
this.blit(this.x, this.y, currentIconX, currentIconY, this.iconWidth, this.iconHeight); this.blit(ms, this.x, this.y, currentIconX, currentIconY, this.iconWidth, this.iconHeight);
} }
} }
public void drawTooltip(Screen screen, int mouseX, int mouseY) { public void drawTooltip(MatrixStack ms, Screen screen, int mouseX, int mouseY) {
boolean flag = mouseX >= x && mouseX < x + width && mouseY >= y && mouseY < y + height; boolean flag = mouseX >= x && mouseX < x + width && mouseY >= y && mouseY < y + height;
if (flag) { if (flag) {
List<String> textLines = new ArrayList<>(); screen.renderComponentTooltip(ms, tooltip, mouseX - 10, mouseY + 25);
textLines.addAll(tooltip);
screen.renderTooltip(textLines, mouseX - 10, mouseY + 25);
} }
} }
} }

View File

@@ -1,21 +1,29 @@
package nl.requios.effortlessbuilding.gui.elements; package nl.requios.effortlessbuilding.gui.elements;
import net.minecraft.client.gui.*; import com.mojang.blaze3d.matrix.MatrixStack;
import mcp.MethodsReturnNonnullByDefault;
import net.minecraft.client.gui.AbstractGui;
import net.minecraft.client.gui.FontRenderer;
import net.minecraft.client.gui.screen.Screen; import net.minecraft.client.gui.screen.Screen;
import net.minecraft.client.gui.widget.TextFieldWidget; import net.minecraft.client.gui.widget.TextFieldWidget;
import net.minecraft.client.gui.widget.Widget; import net.minecraft.client.gui.widget.Widget;
import net.minecraft.client.gui.widget.button.Button; import net.minecraft.client.gui.widget.button.Button;
import net.minecraft.util.text.ITextComponent;
import net.minecraft.util.text.StringTextComponent;
import net.minecraft.util.text.TextFormatting; import net.minecraft.util.text.TextFormatting;
import net.minecraftforge.api.distmarker.Dist; import net.minecraftforge.api.distmarker.Dist;
import net.minecraftforge.api.distmarker.OnlyIn; import net.minecraftforge.api.distmarker.OnlyIn;
import javax.annotation.ParametersAreNonnullByDefault;
import java.text.DecimalFormat; import java.text.DecimalFormat;
import java.text.ParseException; import java.text.ParseException;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Arrays; import java.util.Collections;
import java.util.List; import java.util.List;
@OnlyIn(Dist.CLIENT) @OnlyIn(Dist.CLIENT)
@ParametersAreNonnullByDefault
@MethodsReturnNonnullByDefault
public class GuiNumberField extends AbstractGui { public class GuiNumberField extends AbstractGui {
public int x, y, width, height; public int x, y, width, height;
@@ -24,7 +32,7 @@ public class GuiNumberField extends AbstractGui {
protected TextFieldWidget textField; protected TextFieldWidget textField;
protected Button minusButton, plusButton; protected Button minusButton, plusButton;
List<String> tooltip = new ArrayList<>(); List<ITextComponent> tooltip = new ArrayList<>();
public GuiNumberField(FontRenderer font, List<Widget> buttonList, int x, int y, int width, int height) { public GuiNumberField(FontRenderer font, List<Widget> buttonList, int x, int y, int width, int height) {
this.x = x; this.x = x;
@@ -32,15 +40,15 @@ public class GuiNumberField extends AbstractGui {
this.width = width; this.width = width;
this.height = height; this.height = height;
textField = new TextFieldWidget(font, x + buttonWidth + 1, y + 1, width - 2 * buttonWidth - 2, height - 2, ""); textField = new TextFieldWidget(font, x + buttonWidth + 1, y + 1, width - 2 * buttonWidth - 2, height - 2, StringTextComponent.EMPTY);
minusButton = new Button(x, y - 1, buttonWidth, height + 2, "-", button -> { minusButton = new Button(x, y - 1, buttonWidth, height + 2, new StringTextComponent("-"), button -> {
float valueChanged = 1f; float valueChanged = 1f;
if (Screen.hasControlDown()) valueChanged = 5f; if (Screen.hasControlDown()) valueChanged = 5f;
if (Screen.hasShiftDown()) valueChanged = 10f; if (Screen.hasShiftDown()) valueChanged = 10f;
setNumber(getNumber() - valueChanged); setNumber(getNumber() - valueChanged);
}); });
plusButton = new Button(x + width - buttonWidth, y - 1, buttonWidth, height + 2, "+", button -> { plusButton = new Button(x + width - buttonWidth, y - 1, buttonWidth, height + 2, new StringTextComponent("+"), button -> {
float valueChanged = 1f; float valueChanged = 1f;
if (Screen.hasControlDown()) valueChanged = 5f; if (Screen.hasControlDown()) valueChanged = 5f;
if (Screen.hasShiftDown()) valueChanged = 10f; if (Screen.hasShiftDown()) valueChanged = 10f;
@@ -52,24 +60,24 @@ public class GuiNumberField extends AbstractGui {
buttonList.add(plusButton); buttonList.add(plusButton);
} }
public void setNumber(double number) {
textField.setText(DecimalFormat.getInstance().format(number));
}
public double getNumber() { public double getNumber() {
if (textField.getText().isEmpty()) return 0; if (textField.getValue().isEmpty()) return 0;
try { try {
return DecimalFormat.getInstance().parse(textField.getText()).doubleValue(); return DecimalFormat.getInstance().parse(textField.getValue()).doubleValue();
} catch (ParseException e) { } catch (ParseException e) {
return 0; return 0;
} }
} }
public void setTooltip(String tooltip) { public void setNumber(double number) {
setTooltip(Arrays.asList(tooltip)); textField.setValue(DecimalFormat.getInstance().format(number));
} }
public void setTooltip(List<String> tooltip) { public void setTooltip(ITextComponent tooltip) {
setTooltip(Collections.singletonList(tooltip));
}
public void setTooltip(List<ITextComponent> tooltip) {
this.tooltip = tooltip; this.tooltip = tooltip;
} }
@@ -81,48 +89,54 @@ public class GuiNumberField extends AbstractGui {
//Rightclicked inside textfield //Rightclicked inside textfield
if (flag && mouseButton == 1) { if (flag && mouseButton == 1) {
textField.setText(""); textField.setValue("");
textField.setFocused2(true); textField.setFocus(true);
result = true; result = true;
} }
return result; return result;
} }
public void drawNumberField(int mouseX, int mouseY, float partialTicks) { public void drawNumberField(MatrixStack ms, int mouseX, int mouseY, float partialTicks) {
textField.y = y + 1; textField.y = y + 1;
minusButton.y = y - 1; minusButton.y = y - 1;
plusButton.y = y - 1; plusButton.y = y - 1;
textField.render(mouseX, mouseY, partialTicks); textField.render(ms, mouseX, mouseY, partialTicks);
minusButton.render(mouseX, mouseY, partialTicks); minusButton.render(ms, mouseX, mouseY, partialTicks);
plusButton.render(mouseX, mouseY, partialTicks); plusButton.render(ms, mouseX, mouseY, partialTicks);
} }
public void drawTooltip(Screen screen, int mouseX, int mouseY) { public void drawTooltip(MatrixStack ms, Screen screen, int mouseX, int mouseY) {
boolean insideTextField = mouseX >= x + buttonWidth && mouseX < x + width - buttonWidth && mouseY >= y && mouseY < y + height; boolean insideTextField = mouseX >= x + buttonWidth && mouseX < x + width - buttonWidth && mouseY >= y && mouseY < y + height;
boolean insideMinusButton = mouseX >= x && mouseX < x + buttonWidth && mouseY >= y && mouseY < y + height; boolean insideMinusButton = mouseX >= x && mouseX < x + buttonWidth && mouseY >= y && mouseY < y + height;
boolean insidePlusButton = mouseX >= x + width - buttonWidth && mouseX < x + width && mouseY >= y && mouseY < y + height; boolean insidePlusButton = mouseX >= x + width - buttonWidth && mouseX < x + width && mouseY >= y && mouseY < y + height;
List<String> textLines = new ArrayList<>(); // List<String> textLines = new ArrayList<>();
List<ITextComponent> textLines = new ArrayList<>();
if (insideTextField) { if (insideTextField) {
if (!tooltip.isEmpty())
textLines.addAll(tooltip); textLines.addAll(tooltip);
// textLines.add(TextFormatting.GRAY + "Tip: try scrolling."); // textLines.add(TextFormatting.GRAY + "Tip: try scrolling.");
} }
if (insideMinusButton) { if (insideMinusButton) {
textLines.add("Hold " + TextFormatting.AQUA + "shift " + TextFormatting.RESET + "for " + TextFormatting.RED + "10"); textLines.add(new StringTextComponent("Hold ").append(new StringTextComponent("shift ").withStyle(TextFormatting.AQUA)).append("for ")
textLines.add("Hold " + TextFormatting.AQUA + "ctrl " + TextFormatting.RESET + "for " + TextFormatting.RED + "5"); .append(new StringTextComponent("10").withStyle(TextFormatting.RED)));
textLines.add(new StringTextComponent("Hold ").append(new StringTextComponent("ctrl ").withStyle(TextFormatting.AQUA)).append("for ")
.append(new StringTextComponent("5").withStyle(TextFormatting.RED)));
} }
if (insidePlusButton) { if (insidePlusButton) {
textLines.add("Hold " + TextFormatting.AQUA + "shift " + TextFormatting.RESET + "for " + TextFormatting.DARK_GREEN + "10"); textLines.add(new StringTextComponent("Hold ").append(new StringTextComponent("shift ").withStyle(TextFormatting.DARK_GREEN)).append("for ")
textLines.add("Hold " + TextFormatting.AQUA + "ctrl " + TextFormatting.RESET + "for " + TextFormatting.DARK_GREEN + "5"); .append(new StringTextComponent("10").withStyle(TextFormatting.RED)));
textLines.add(new StringTextComponent("Hold ").append(new StringTextComponent("ctrl ").withStyle(TextFormatting.DARK_GREEN)).append("for ")
.append(new StringTextComponent("5").withStyle(TextFormatting.RED)));
} }
screen.renderTooltip(textLines, mouseX - 10, mouseY + 25); screen.renderComponentTooltip(ms, textLines, mouseX - 10, mouseY + 25);
} }

View File

@@ -1,11 +1,14 @@
package nl.requios.effortlessbuilding.gui.elements; package nl.requios.effortlessbuilding.gui.elements;
import com.mojang.blaze3d.matrix.MatrixStack;
import com.mojang.blaze3d.platform.GlStateManager; import com.mojang.blaze3d.platform.GlStateManager;
import com.mojang.blaze3d.systems.RenderSystem;
import mcp.MethodsReturnNonnullByDefault;
import net.minecraft.client.Minecraft; import net.minecraft.client.Minecraft;
import net.minecraft.client.gui.*; import net.minecraft.client.gui.FontRenderer;
import net.minecraft.client.gui.IGuiEventListener;
import net.minecraft.client.gui.screen.Screen; import net.minecraft.client.gui.screen.Screen;
import net.minecraft.client.gui.widget.Widget; import net.minecraft.client.gui.widget.Widget;
import net.minecraft.client.gui.widget.button.Button;
import net.minecraft.client.renderer.BufferBuilder; import net.minecraft.client.renderer.BufferBuilder;
import net.minecraft.client.renderer.Tessellator; import net.minecraft.client.renderer.Tessellator;
import net.minecraft.client.renderer.vertex.DefaultVertexFormats; import net.minecraft.client.renderer.vertex.DefaultVertexFormats;
@@ -14,15 +17,18 @@ import net.minecraftforge.api.distmarker.Dist;
import net.minecraftforge.api.distmarker.OnlyIn; import net.minecraftforge.api.distmarker.OnlyIn;
import net.minecraftforge.common.MinecraftForge; import net.minecraftforge.common.MinecraftForge;
import javax.annotation.ParametersAreNonnullByDefault;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
@OnlyIn(Dist.CLIENT) @OnlyIn(Dist.CLIENT)
@MethodsReturnNonnullByDefault
@ParametersAreNonnullByDefault
public class GuiScrollPane extends SlotGui { public class GuiScrollPane extends SlotGui {
public Screen parent; public Screen parent;
public FontRenderer font; public FontRenderer font;
private List<IScrollEntry> listEntries; private final List<IScrollEntry> listEntries;
private float scrollMultiplier = 1f; private float scrollMultiplier = 1f;
private int mouseX; private int mouseX;
@@ -41,7 +47,7 @@ public class GuiScrollPane extends SlotGui {
return listEntries.get(index); return listEntries.get(index);
} }
public void AddListEntry(IScrollEntry listEntry){ public void AddListEntry(IScrollEntry listEntry) {
listEntries.add(listEntry); listEntries.add(listEntry);
} }
@@ -68,8 +74,7 @@ public class GuiScrollPane extends SlotGui {
//Removed background //Removed background
@Override @Override
public void render(int mouseXIn, int mouseYIn, float partialTicks) public void render(MatrixStack ms, int mouseXIn, int mouseYIn, float partialTicks) {
{
if (this.visible) { if (this.visible) {
this.mouseX = mouseXIn; this.mouseX = mouseXIn;
this.mouseY = mouseYIn; this.mouseY = mouseYIn;
@@ -77,11 +82,9 @@ public class GuiScrollPane extends SlotGui {
int scrollbarLeft = this.getScrollbarPosition(); int scrollbarLeft = this.getScrollbarPosition();
int scrollbarRight = scrollbarLeft + 6; int scrollbarRight = scrollbarLeft + 6;
this.capYPosition(); this.capYPosition();
GlStateManager.disableLighting();
GlStateManager.disableFog();
Tessellator tessellator = Tessellator.getInstance(); Tessellator tessellator = Tessellator.getInstance();
BufferBuilder bufferbuilder = tessellator.getBuffer(); BufferBuilder bufferbuilder = tessellator.getBuilder();
int insideLeft = this.x0 + this.width / 2 - this.getRowWidth() / 2 + 2; int insideLeft = this.x0 + this.width / 2 - this.getRowWidth() / 2 + 2;
int insideTop = this.y0 + 4 - (int) this.yo; int insideTop = this.y0 + 4 - (int) this.yo;
@@ -90,18 +93,18 @@ public class GuiScrollPane extends SlotGui {
} }
//All entries //All entries
this.renderList(insideLeft, insideTop, mouseXIn, mouseYIn, partialTicks); this.renderList(ms, insideLeft, insideTop, mouseXIn, mouseYIn, partialTicks);
GlStateManager.disableDepthTest(); RenderSystem.disableDepthTest();
//Dirt overlays on top and bottom //Dirt overlays on top and bottom
// this.renderHoleBackground(0, this.y0, 255, 255); // this.renderHoleBackground(0, this.y0, 255, 255);
// this.renderHoleBackground(this.y1, this.height, 255, 255); // this.renderHoleBackground(this.y1, this.height, 255, 255);
GlStateManager.enableBlend(); RenderSystem.enableBlend();
GlStateManager.blendFuncSeparate(GlStateManager.SourceFactor.SRC_ALPHA, GlStateManager.DestFactor.ONE_MINUS_SRC_ALPHA, GlStateManager.SourceFactor.ZERO, GlStateManager.DestFactor.ONE); RenderSystem.blendFuncSeparate(GlStateManager.SourceFactor.SRC_ALPHA, GlStateManager.DestFactor.ONE_MINUS_SRC_ALPHA, GlStateManager.SourceFactor.ZERO, GlStateManager.DestFactor.ONE);
GlStateManager.disableAlphaTest(); RenderSystem.disableAlphaTest();
GlStateManager.shadeModel(7425); RenderSystem.shadeModel(7425);
GlStateManager.disableTexture(); RenderSystem.disableTexture();
//top //top
// bufferbuilder.begin(7, DefaultVertexFormats.POSITION_TEX_COLOR); // bufferbuilder.begin(7, DefaultVertexFormats.POSITION_TEX_COLOR);
@@ -130,29 +133,30 @@ public class GuiScrollPane extends SlotGui {
} }
bufferbuilder.begin(7, DefaultVertexFormats.POSITION_TEX_COLOR); bufferbuilder.begin(7, DefaultVertexFormats.POSITION_TEX_COLOR);
bufferbuilder.pos((double) scrollbarLeft, (double) this.y1, 0.0D).tex(0.0D, 1.0D).color(0, 0, 0, 255).endVertex(); bufferbuilder.vertex(scrollbarLeft, this.y1, 0.0F).uv(0.0F, 1.0F).color(0, 0, 0, 255).endVertex();
bufferbuilder.pos((double) scrollbarRight, (double) this.y1, 0.0D).tex(1.0D, 1.0D).color(0, 0, 0, 255).endVertex(); bufferbuilder.vertex(scrollbarRight, this.y1, 0.0F).uv(1.0F, 1.0F).color(0, 0, 0, 255).endVertex();
bufferbuilder.pos((double) scrollbarRight, (double) this.y0, 0.0D).tex(1.0D, 0.0D).color(0, 0, 0, 255).endVertex(); bufferbuilder.vertex(scrollbarRight, this.y0, 0.0F).uv(1.0F, 0.0F).color(0, 0, 0, 255).endVertex();
bufferbuilder.pos((double) scrollbarLeft, (double) this.y0, 0.0D).tex(0.0D, 0.0D).color(0, 0, 0, 255).endVertex(); bufferbuilder.vertex(scrollbarLeft, this.y0, 0.0F).uv(0.0F, 0.0F).color(0, 0, 0, 255).endVertex();
tessellator.draw(); tessellator.end();
bufferbuilder.begin(7, DefaultVertexFormats.POSITION_TEX_COLOR); bufferbuilder.begin(7, DefaultVertexFormats.POSITION_TEX_COLOR);
bufferbuilder.pos((double) scrollbarLeft, (double) (l1 + k1), 0.0D).tex(0.0D, 1.0D).color(128, 128, 128, 255).endVertex(); bufferbuilder.vertex(scrollbarLeft, l1 + k1, 0.0F).uv(0.0F, 1.0F).color(128, 128, 128, 255).endVertex();
bufferbuilder.pos((double) scrollbarRight, (double) (l1 + k1), 0.0D).tex(1.0D, 1.0D).color(128, 128, 128, 255).endVertex(); bufferbuilder.vertex(scrollbarRight, l1 + k1, 0.0F).uv(1.0F, 1.0F).color(128, 128, 128, 255).endVertex();
bufferbuilder.pos((double) scrollbarRight, (double) l1, 0.0D).tex(1.0D, 0.0D).color(128, 128, 128, 255).endVertex(); bufferbuilder.vertex(scrollbarRight, l1, 0.0F).uv(1.0F, 0.0F).color(128, 128, 128, 255).endVertex();
bufferbuilder.pos((double) scrollbarLeft, (double) l1, 0.0D).tex(0.0D, 0.0D).color(128, 128, 128, 255).endVertex(); bufferbuilder.vertex(scrollbarLeft, l1, 0.0F).uv(0.0F, 0.0F).color(128, 128, 128, 255).endVertex();
tessellator.draw(); tessellator.end();
bufferbuilder.begin(7, DefaultVertexFormats.POSITION_TEX_COLOR); bufferbuilder.begin(7, DefaultVertexFormats.POSITION_TEX_COLOR);
bufferbuilder.pos((double) scrollbarLeft, (double) (l1 + k1 - 1), 0.0D).tex(0.0D, 1.0D).color(192, 192, 192, 255).endVertex(); bufferbuilder.vertex(scrollbarLeft, l1 + k1 - 1, 0.0F).uv(0.0F, 1.0F).color(192, 192, 192, 255).endVertex();
bufferbuilder.pos((double) (scrollbarRight - 1), (double) (l1 + k1 - 1), 0.0D).tex(1.0D, 1.0D).color(192, 192, 192, 255).endVertex(); bufferbuilder.vertex(scrollbarRight - 1, l1 + k1 - 1, 0.0F).uv(1.0F, 1.0F).color(192, 192, 192, 255).endVertex();
bufferbuilder.pos((double) (scrollbarRight - 1), (double) l1, 0.0D).tex(1.0D, 0.0D).color(192, 192, 192, 255).endVertex(); bufferbuilder.vertex(scrollbarRight - 1, l1, 0.0F).uv(1.0F, 0.0F).color(192, 192, 192, 255).endVertex();
bufferbuilder.pos((double) scrollbarLeft, (double) l1, 0.0D).tex(0.0D, 0.0D).color(192, 192, 192, 255).endVertex(); bufferbuilder.vertex(scrollbarLeft, l1, 0.0F).uv(0.0F, 0.0F).color(192, 192, 192, 255).endVertex();
tessellator.draw(); tessellator.end();
} }
GlStateManager.enableTexture(); //this.renderDecorations(mouseXIn, mouseYIn);
GlStateManager.shadeModel(7424); RenderSystem.enableTexture();
GlStateManager.enableAlphaTest(); RenderSystem.shadeModel(7424);
GlStateManager.disableBlend(); RenderSystem.enableAlphaTest();
RenderSystem.disableBlend();
} }
} }
@@ -174,8 +178,8 @@ public class GuiScrollPane extends SlotGui {
} }
@Override @Override
protected void renderItem(int slotIndex, int xPos, int yPos, int heightIn, int mouseXIn, int mouseYIn, float partialTicks) { protected void renderItem(MatrixStack ms, int slotIndex, int xPos, int yPos, int heightIn, int mouseXIn, int mouseYIn, float partialTicks) {
this.getListEntry(slotIndex).drawEntry(slotIndex, xPos, yPos, this.getRowWidth(), heightIn, mouseXIn, mouseYIn, this.getListEntry(slotIndex).drawEntry(ms, slotIndex, xPos, yPos, this.getRowWidth(), heightIn, mouseXIn, mouseYIn,
this.getSlotIndexFromScreenCoords(mouseXIn, mouseYIn) == slotIndex, partialTicks); this.getSlotIndexFromScreenCoords(mouseXIn, mouseYIn) == slotIndex, partialTicks);
} }
@@ -205,6 +209,11 @@ public class GuiScrollPane extends SlotGui {
return -1; return -1;
} }
@Override
public List<? extends IGuiEventListener> children() {
return null;
}
@Override @Override
public boolean mouseClicked(double mouseX, double mouseY, int button) { public boolean mouseClicked(double mouseX, double mouseY, int button) {
int selectedSlot = this.getSlotIndexFromScreenCoords(mouseX, mouseY); int selectedSlot = this.getSlotIndexFromScreenCoords(mouseX, mouseY);
@@ -239,8 +248,7 @@ public class GuiScrollPane extends SlotGui {
@Override @Override
public boolean mouseReleased(double mouseX, double mouseY, int button) { public boolean mouseReleased(double mouseX, double mouseY, int button) {
for (int i = 0; i < this.getItemCount(); ++i) for (int i = 0; i < this.getItemCount(); ++i) {
{
double relativeX = getRelativeMouseX(mouseX); double relativeX = getRelativeMouseX(mouseX);
double relativeY = getRelativeMouseY(mouseY, i); double relativeY = getRelativeMouseY(mouseY, i);
this.getListEntry(i).mouseReleased(i, (int) mouseX, (int) mouseY, button, (int) relativeX, (int) relativeY); this.getListEntry(i).mouseReleased(i, (int) mouseX, (int) mouseY, button, (int) relativeX, (int) relativeY);
@@ -252,7 +260,7 @@ public class GuiScrollPane extends SlotGui {
public void handleMouseInput() { public void handleMouseInput() {
if (this.isMouseInList(this.mouseX, this.mouseY)) { if (this.isMouseInList(this.mouseX, this.mouseY)) {
if (minecraft.mouseHelper.isLeftDown() && this.mouseY >= this.y0 && if (minecraft.mouseHandler.isLeftPressed() && this.mouseY >= this.y0 &&
this.mouseY <= this.y1) { this.mouseY <= this.y1) {
int i = this.x0 + (this.width - this.getRowWidth()) / 2; int i = this.x0 + (this.width - this.getRowWidth()) / 2;
int j = this.x0 + (this.width + this.getRowWidth()) / 2; int j = this.x0 + (this.width + this.getRowWidth()) / 2;
@@ -266,7 +274,7 @@ public class GuiScrollPane extends SlotGui {
} }
} }
if (minecraft.mouseHelper.isLeftDown() && this.isVisible()) { if (minecraft.mouseHandler.isLeftPressed() && this.isVisible()) {
if (this.yDrag == -1) { if (this.yDrag == -1) {
boolean flag1 = true; boolean flag1 = true;
@@ -324,11 +332,10 @@ public class GuiScrollPane extends SlotGui {
//Draw in center if it fits //Draw in center if it fits
@Override @Override
protected void renderList(int insideLeft, int insideTop, int mouseXIn, int mouseYIn, float partialTicks) protected void renderList(MatrixStack ms, int insideLeft, int insideTop, int mouseXIn, int mouseYIn, float partialTicks) {
{
int itemCount = this.getItemCount(); int itemCount = this.getItemCount();
Tessellator tessellator = Tessellator.getInstance(); Tessellator tessellator = Tessellator.getInstance();
BufferBuilder bufferbuilder = tessellator.getBuffer(); BufferBuilder bufferbuilder = tessellator.getBuilder();
//Find y to start with //Find y to start with
int y = this.headerHeight + insideTop; int y = this.headerHeight + insideTop;
@@ -341,39 +348,37 @@ public class GuiScrollPane extends SlotGui {
} }
//Draw all entries //Draw all entries
for (int i = 0; i < itemCount; ++i) for (int i = 0; i < itemCount; ++i) {
{
int entryHeight = listEntries.get(i).getHeight(); int entryHeight = listEntries.get(i).getHeight();
int entryHeight2 = entryHeight - 4; int entryHeight2 = entryHeight - 4;
if (y > this.y1 || y + entryHeight2 < this.y0) if (y > this.y1 || y + entryHeight2 < this.y0) {
{
this.updateItemPosition(i, insideLeft, y, partialTicks); this.updateItemPosition(i, insideLeft, y, partialTicks);
} }
if (this.renderSelection && this.isSelectedItem(i)) { if (this.renderSelection && this.isSelectedItem(i)) {
int i1 = this.x0 + this.width / 2 - this.getRowWidth() / 2; int i1 = this.x0 + this.width / 2 - this.getRowWidth() / 2;
int j1 = this.x0 + this.width / 2 + this.getRowWidth() / 2; int j1 = this.x0 + this.width / 2 + this.getRowWidth() / 2;
GlStateManager.disableTexture(); RenderSystem.disableTexture();
float f = this.isFocused() ? 1.0F : 0.5F; float f = this.isFocused() ? 1.0F : 0.5F;
GlStateManager.color4f(f, f, f, 1.0F); RenderSystem.color4f(f, f, f, 1.0F);
bufferbuilder.begin(7, DefaultVertexFormats.POSITION); bufferbuilder.begin(7, DefaultVertexFormats.POSITION);
bufferbuilder.pos((double)i1, (double)(y + entryHeight2 + 2), 0.0D).endVertex(); bufferbuilder.vertex(i1, y + entryHeight2 + 2, 0.0D).endVertex();
bufferbuilder.pos((double)j1, (double)(y + entryHeight2 + 2), 0.0D).endVertex(); bufferbuilder.vertex(j1, y + entryHeight2 + 2, 0.0D).endVertex();
bufferbuilder.pos((double)j1, (double)(y - 2), 0.0D).endVertex(); bufferbuilder.vertex(j1, y - 2, 0.0D).endVertex();
bufferbuilder.pos((double)i1, (double)(y - 2), 0.0D).endVertex(); bufferbuilder.vertex(i1, y - 2, 0.0D).endVertex();
tessellator.draw(); tessellator.end();
GlStateManager.color4f(0.0F, 0.0F, 0.0F, 1.0F); RenderSystem.color4f(0.0F, 0.0F, 0.0F, 1.0F);
bufferbuilder.begin(7, DefaultVertexFormats.POSITION); bufferbuilder.begin(7, DefaultVertexFormats.POSITION);
bufferbuilder.pos((double)(i1 + 1), (double)(y + entryHeight2 + 1), 0.0D).endVertex(); bufferbuilder.vertex(i1 + 1, y + entryHeight2 + 1, 0.0D).endVertex();
bufferbuilder.pos((double)(j1 - 1), (double)(y + entryHeight2 + 1), 0.0D).endVertex(); bufferbuilder.vertex(j1 - 1, y + entryHeight2 + 1, 0.0D).endVertex();
bufferbuilder.pos((double)(j1 - 1), (double)(y - 1), 0.0D).endVertex(); bufferbuilder.vertex(j1 - 1, y - 1, 0.0D).endVertex();
bufferbuilder.pos((double)(i1 + 1), (double)(y - 1), 0.0D).endVertex(); bufferbuilder.vertex(i1 + 1, y - 1, 0.0D).endVertex();
tessellator.draw(); tessellator.end();
GlStateManager.enableTexture(); RenderSystem.enableTexture();
} }
this.renderItem(i, insideLeft, y, entryHeight2, mouseXIn, mouseYIn, partialTicks); this.renderItem(ms, i, insideLeft, y, entryHeight2, mouseXIn, mouseYIn, partialTicks);
y += entryHeight; y += entryHeight;
} }
} }
@@ -410,9 +415,9 @@ public class GuiScrollPane extends SlotGui {
entry.updateScreen(); entry.updateScreen();
} }
public void drawTooltip(Screen guiScreen, int mouseX, int mouseY) { public void drawTooltip(MatrixStack ms, Screen guiScreen, int mouseX, int mouseY) {
for (IScrollEntry entry : this.listEntries) for (IScrollEntry entry : this.listEntries)
entry.drawTooltip(guiScreen, mouseX, mouseY); entry.drawTooltip(ms, guiScreen, mouseX, mouseY);
} }
@Override @Override
@@ -441,7 +446,7 @@ public class GuiScrollPane extends SlotGui {
void updateScreen(); void updateScreen();
void drawTooltip(Screen guiScreen, int mouseX, int mouseY); void drawTooltip(MatrixStack ms, Screen guiScreen, int mouseX, int mouseY);
boolean charTyped(char eventChar, int eventKey); boolean charTyped(char eventChar, int eventKey);
@@ -451,7 +456,7 @@ public class GuiScrollPane extends SlotGui {
void updatePosition(int slotIndex, int x, int y, float partialTicks); void updatePosition(int slotIndex, int x, int y, float partialTicks);
void drawEntry(int slotIndex, int x, int y, int listWidth, int slotHeight, int mouseX, int mouseY, boolean isSelected, float partialTicks); void drawEntry(MatrixStack ms, int slotIndex, int x, int y, int listWidth, int slotHeight, int mouseX, int mouseY, boolean isSelected, float partialTicks);
/** /**
* Called when the mouse is clicked within this entry. Returning true means that something within this entry was * Called when the mouse is clicked within this entry. Returning true means that something within this entry was

View File

@@ -0,0 +1,263 @@
package nl.requios.effortlessbuilding.gui.elements;
import com.mojang.blaze3d.matrix.MatrixStack;
import com.mojang.blaze3d.systems.RenderSystem;
import mcp.MethodsReturnNonnullByDefault;
import net.minecraft.client.Minecraft;
import net.minecraft.client.gui.FocusableGui;
import net.minecraft.client.gui.IGuiEventListener;
import net.minecraft.client.gui.IRenderable;
import net.minecraft.client.renderer.BufferBuilder;
import net.minecraft.client.renderer.Tessellator;
import net.minecraft.client.renderer.vertex.DefaultVertexFormats;
import net.minecraft.util.math.MathHelper;
import net.minecraftforge.api.distmarker.Dist;
import net.minecraftforge.api.distmarker.OnlyIn;
import javax.annotation.ParametersAreNonnullByDefault;
import java.util.Collections;
import java.util.List;
@OnlyIn(Dist.CLIENT)
@ParametersAreNonnullByDefault
@MethodsReturnNonnullByDefault
@SuppressWarnings("deprecation")
public abstract class SlotGui extends FocusableGui implements IRenderable {
protected final Minecraft minecraft;
protected final int itemHeight;
protected int width;
protected int height;
protected int y0;
protected int y1;
protected int x1;
protected int x0;
protected int yDrag = -2;
protected double yo;
protected boolean visible = true;
protected boolean renderSelection = true;
protected boolean renderHeader;
protected int headerHeight;
private boolean scrolling;
public SlotGui(Minecraft mcIn, int width, int height, int topIn, int bottomIn, int slotHeightIn) {
this.minecraft = mcIn;
this.width = width;
this.height = height;
this.y0 = topIn;
this.y1 = bottomIn;
this.itemHeight = slotHeightIn;
this.x0 = 0;
this.x1 = width;
}
public boolean isVisible() {
return this.visible;
}
protected abstract int getItemCount();
public List<? extends IGuiEventListener> children() {
return Collections.emptyList();
}
protected boolean selectItem(int p_selectItem_1_, int p_selectItem_2_, double p_selectItem_3_, double p_selectItem_5_) {
return true;
}
protected abstract boolean isSelectedItem(int p_isSelectedItem_1_);
protected int getMaxPosition() {
return this.getItemCount() * this.itemHeight + this.headerHeight;
}
protected abstract void renderBackground();
protected void updateItemPosition(int p_updateItemPosition_1_, int p_updateItemPosition_2_, int p_updateItemPosition_3_, float p_updateItemPosition_4_) {
}
protected abstract void renderItem(MatrixStack ms, int p_renderItem_1_, int p_renderItem_2_, int p_renderItem_3_, int p_renderItem_4_, int p_renderItem_5_, int p_renderItem_6_, float p_renderItem_7_);
protected void renderHeader(int p_renderHeader_1_, int p_renderHeader_2_, Tessellator p_renderHeader_3_) {
}
protected void clickedHeader(int p_clickedHeader_1_, int p_clickedHeader_2_) {
}
public int getItemAtPosition(double p_getItemAtPosition_1_, double p_getItemAtPosition_3_) {
int i = this.x0 + this.width / 2 - this.getRowWidth() / 2;
int j = this.x0 + this.width / 2 + this.getRowWidth() / 2;
int k = MathHelper.floor(p_getItemAtPosition_3_ - (double) this.y0) - this.headerHeight + (int) this.yo - 4;
int l = k / this.itemHeight;
return p_getItemAtPosition_1_ < (double) this.getScrollbarPosition() && p_getItemAtPosition_1_ >= (double) i && p_getItemAtPosition_1_ <= (double) j && l >= 0 && k >= 0 && l < this.getItemCount() ? l : -1;
}
protected void capYPosition() {
this.yo = MathHelper.clamp(this.yo, 0.0D, this.getMaxScroll());
}
public int getMaxScroll() {
return Math.max(0, this.getMaxPosition() - (this.y1 - this.y0 - 4));
}
public int getScroll() {
return (int) this.yo;
}
public boolean isMouseInList(double p_isMouseInList_1_, double p_isMouseInList_3_) {
return p_isMouseInList_3_ >= (double) this.y0 && p_isMouseInList_3_ <= (double) this.y1 && p_isMouseInList_1_ >= (double) this.x0 && p_isMouseInList_1_ <= (double) this.x1;
}
public abstract void render(MatrixStack ms, int p_render_1_, int p_render_2_, float p_render_3_);
protected void updateScrollingState(double p_updateScrollingState_1_, double p_updateScrollingState_3_, int p_updateScrollingState_5_) {
this.scrolling = p_updateScrollingState_5_ == 0 && p_updateScrollingState_1_ >= (double) this.getScrollbarPosition() && p_updateScrollingState_1_ < (double) (this.getScrollbarPosition() + 6);
}
public boolean mouseClicked(double p_mouseClicked_1_, double p_mouseClicked_3_, int p_mouseClicked_5_) {
this.updateScrollingState(p_mouseClicked_1_, p_mouseClicked_3_, p_mouseClicked_5_);
if (this.isVisible() && this.isMouseInList(p_mouseClicked_1_, p_mouseClicked_3_)) {
int i = this.getItemAtPosition(p_mouseClicked_1_, p_mouseClicked_3_);
if (i == -1 && p_mouseClicked_5_ == 0) {
this.clickedHeader((int) (p_mouseClicked_1_ - (double) (this.x0 + this.width / 2 - this.getRowWidth() / 2)), (int) (p_mouseClicked_3_ - (double) this.y0) + (int) this.yo - 4);
return true;
} else if (i != -1 && this.selectItem(i, p_mouseClicked_5_, p_mouseClicked_1_, p_mouseClicked_3_)) {
if (this.children().size() > i) {
this.setFocused(this.children().get(i));
}
this.setDragging(true);
return true;
} else {
return this.scrolling;
}
} else {
return false;
}
}
public boolean mouseReleased(double p_mouseReleased_1_, double p_mouseReleased_3_, int p_mouseReleased_5_) {
if (this.getFocused() != null) {
this.getFocused().mouseReleased(p_mouseReleased_1_, p_mouseReleased_3_, p_mouseReleased_5_);
}
return false;
}
public boolean mouseDragged(double p_mouseDragged_1_, double p_mouseDragged_3_, int p_mouseDragged_5_, double p_mouseDragged_6_, double p_mouseDragged_8_) {
if (super.mouseDragged(p_mouseDragged_1_, p_mouseDragged_3_, p_mouseDragged_5_, p_mouseDragged_6_, p_mouseDragged_8_)) {
return true;
} else if (this.isVisible() && p_mouseDragged_5_ == 0 && this.scrolling) {
if (p_mouseDragged_3_ < (double) this.y0) {
this.yo = 0.0D;
} else if (p_mouseDragged_3_ > (double) this.y1) {
this.yo = this.getMaxScroll();
} else {
double d0 = this.getMaxScroll();
if (d0 < 1.0D) {
d0 = 1.0D;
}
int i = (int) ((float) ((this.y1 - this.y0) * (this.y1 - this.y0)) / (float) this.getMaxPosition());
i = MathHelper.clamp(i, 32, this.y1 - this.y0 - 8);
double d1 = d0 / (double) (this.y1 - this.y0 - i);
if (d1 < 1.0D) {
d1 = 1.0D;
}
this.yo += p_mouseDragged_8_ * d1;
this.capYPosition();
}
return true;
} else {
return false;
}
}
public boolean mouseScrolled(double p_mouseScrolled_1_, double p_mouseScrolled_3_, double p_mouseScrolled_5_) {
if (!this.isVisible()) {
return false;
} else {
this.yo -= p_mouseScrolled_5_ * (double) this.itemHeight / 2.0D;
return true;
}
}
public boolean keyPressed(int p_keyPressed_1_, int p_keyPressed_2_, int p_keyPressed_3_) {
if (!this.isVisible()) {
return false;
} else if (super.keyPressed(p_keyPressed_1_, p_keyPressed_2_, p_keyPressed_3_)) {
return true;
} else if (p_keyPressed_1_ == 264) {
this.moveSelection(1);
return true;
} else if (p_keyPressed_1_ == 265) {
this.moveSelection(-1);
return true;
} else {
return false;
}
}
protected void moveSelection(int p_moveSelection_1_) {
}
public boolean charTyped(char p_charTyped_1_, int p_charTyped_2_) {
return this.isVisible() && super.charTyped(p_charTyped_1_, p_charTyped_2_);
}
public boolean isMouseOver(double p_isMouseOver_1_, double p_isMouseOver_3_) {
return this.isMouseInList(p_isMouseOver_1_, p_isMouseOver_3_);
}
public int getRowWidth() {
return 220;
}
protected void renderList(MatrixStack ms, int p_renderList_1_, int p_renderList_2_, int p_renderList_3_, int p_renderList_4_, float p_renderList_5_) {
int i = this.getItemCount();
Tessellator tessellator = Tessellator.getInstance();
BufferBuilder bufferbuilder = tessellator.getBuilder();
for (int j = 0; j < i; ++j) {
int k = p_renderList_2_ + j * this.itemHeight + this.headerHeight;
int l = this.itemHeight - 4;
if (k > this.y1 || k + l < this.y0) {
this.updateItemPosition(j, p_renderList_1_, k, p_renderList_5_);
}
if (this.renderSelection && this.isSelectedItem(j)) {
int i1 = this.x0 + this.width / 2 - this.getRowWidth() / 2;
int j1 = this.x0 + this.width / 2 + this.getRowWidth() / 2;
RenderSystem.disableTexture();
float f = this.isFocused() ? 1.0F : 0.5F;
RenderSystem.color4f(f, f, f, 1.0F);
bufferbuilder.begin(7, DefaultVertexFormats.POSITION);
bufferbuilder.vertex(i1, k + l + 2, 0.0D).endVertex();
bufferbuilder.vertex(j1, k + l + 2, 0.0D).endVertex();
bufferbuilder.vertex(j1, k - 2, 0.0D).endVertex();
bufferbuilder.vertex(i1, k - 2, 0.0D).endVertex();
tessellator.end();
RenderSystem.color4f(0.0F, 0.0F, 0.0F, 1.0F);
bufferbuilder.begin(7, DefaultVertexFormats.POSITION);
bufferbuilder.vertex(i1 + 1, k + l + 1, 0.0D).endVertex();
bufferbuilder.vertex(j1 - 1, k + l + 1, 0.0D).endVertex();
bufferbuilder.vertex(j1 - 1, k - 1, 0.0D).endVertex();
bufferbuilder.vertex(i1 + 1, k - 1, 0.0D).endVertex();
tessellator.end();
RenderSystem.enableTexture();
}
this.renderItem(ms, j, p_renderList_1_, k, l, p_renderList_3_, p_renderList_4_, p_renderList_5_);
}
}
protected boolean isFocused() {
return false;
}
protected int getScrollbarPosition() {
return this.width / 2 + 124;
}
}

View File

@@ -1,11 +1,9 @@
package nl.requios.effortlessbuilding.helper; package nl.requios.effortlessbuilding.helper;
import nl.requios.effortlessbuilding.EffortlessBuilding;
//Stack with fixed size. Removes (overwrites) oldest element on push. //Stack with fixed size. Removes (overwrites) oldest element on push.
public class FixedStack<T> { public class FixedStack<T> {
private T[] stack; private final T[] stack;
private int size; private final int size;
private int top; private int top;
private int filled = 0; //how many valid items are in the stack private int filled = 0; //how many valid items are in the stack

View File

@@ -8,7 +8,7 @@ import net.minecraft.item.ItemStack;
public class InventoryHelper { public class InventoryHelper {
public static ItemStack findItemStackInInventory(PlayerEntity player, Block block) { public static ItemStack findItemStackInInventory(PlayerEntity player, Block block) {
for (ItemStack invStack : player.inventory.mainInventory) { for (ItemStack invStack : player.inventory.items) {
if (!invStack.isEmpty() && invStack.getItem() instanceof BlockItem && if (!invStack.isEmpty() && invStack.getItem() instanceof BlockItem &&
((BlockItem) invStack.getItem()).getBlock().equals(block)) { ((BlockItem) invStack.getItem()).getBlock().equals(block)) {
return invStack; return invStack;
@@ -19,7 +19,7 @@ public class InventoryHelper {
public static int findTotalBlocksInInventory(PlayerEntity player, Block block) { public static int findTotalBlocksInInventory(PlayerEntity player, Block block) {
int total = 0; int total = 0;
for (ItemStack invStack : player.inventory.mainInventory) { for (ItemStack invStack : player.inventory.items) {
if (!invStack.isEmpty() && invStack.getItem() instanceof BlockItem && if (!invStack.isEmpty() && invStack.getItem() instanceof BlockItem &&
((BlockItem) invStack.getItem()).getBlock().equals(block)) { ((BlockItem) invStack.getItem()).getBlock().equals(block)) {
total += invStack.getCount(); total += invStack.getCount();

View File

@@ -14,10 +14,14 @@ public class ReachHelper {
//Check buildsettings for reachUpgrade //Check buildsettings for reachUpgrade
int reachUpgrade = ModifierSettingsManager.getModifierSettings(player).getReachUpgrade(); int reachUpgrade = ModifierSettingsManager.getModifierSettings(player).getReachUpgrade();
switch (reachUpgrade) { switch (reachUpgrade) {
case 0: return BuildConfig.reach.maxReachLevel0.get(); case 0:
case 1: return BuildConfig.reach.maxReachLevel1.get(); return BuildConfig.reach.maxReachLevel0.get();
case 2: return BuildConfig.reach.maxReachLevel2.get(); case 1:
case 3: return BuildConfig.reach.maxReachLevel3.get(); return BuildConfig.reach.maxReachLevel1.get();
case 2:
return BuildConfig.reach.maxReachLevel2.get();
case 3:
return BuildConfig.reach.maxReachLevel3.get();
} }
return BuildConfig.reach.maxReachLevel0.get(); return BuildConfig.reach.maxReachLevel0.get();
} }

View File

@@ -1,21 +1,20 @@
package nl.requios.effortlessbuilding.helper; package nl.requios.effortlessbuilding.helper;
import net.minecraft.advancements.CriteriaTriggers;
import net.minecraft.block.*; import net.minecraft.block.*;
import net.minecraft.block.SlabBlock;
import net.minecraft.block.material.Material; import net.minecraft.block.material.Material;
import net.minecraft.entity.player.PlayerEntity;
import net.minecraft.item.BlockItem;
import net.minecraft.util.*;
import net.minecraft.block.BlockState;
import net.minecraft.entity.Entity; import net.minecraft.entity.Entity;
import net.minecraft.block.Blocks; import net.minecraft.entity.player.PlayerEntity;
import net.minecraft.entity.player.ServerPlayerEntity;
import net.minecraft.item.BlockItem;
import net.minecraft.item.ItemStack; import net.minecraft.item.ItemStack;
import net.minecraft.util.CachedBlockInfo; import net.minecraft.util.CachedBlockInfo;
import net.minecraft.util.Direction; import net.minecraft.util.Direction;
import net.minecraft.util.Hand; import net.minecraft.util.Hand;
import net.minecraft.util.SoundCategory;
import net.minecraft.util.math.BlockPos; import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.Vec3d;
import net.minecraft.util.math.shapes.VoxelShape; import net.minecraft.util.math.shapes.VoxelShape;
import net.minecraft.util.math.vector.Vector3d;
import net.minecraft.world.World; import net.minecraft.world.World;
import net.minecraftforge.common.ToolType; import net.minecraftforge.common.ToolType;
import nl.requios.effortlessbuilding.BuildConfig; import nl.requios.effortlessbuilding.BuildConfig;
@@ -31,9 +30,9 @@ public class SurvivalHelper {
//Checks if area is loaded, if player has the right permissions, if existing block can be replaced (drops it if so) and consumes an item from the stack. //Checks if area is loaded, if player has the right permissions, if existing block can be replaced (drops it if so) and consumes an item from the stack.
//Based on ItemBlock#onItemUse //Based on ItemBlock#onItemUse
public static boolean placeBlock(World world, PlayerEntity player, BlockPos pos, BlockState blockState, public static boolean placeBlock(World world, PlayerEntity player, BlockPos pos, BlockState blockState,
ItemStack origstack, Direction facing, Vec3d hitVec, boolean skipPlaceCheck, ItemStack origstack, Direction facing, Vector3d hitVec, boolean skipPlaceCheck,
boolean skipCollisionCheck, boolean playSound) { boolean skipCollisionCheck, boolean playSound) {
if (!world.isBlockPresent(pos)) return false; if (!world.isLoaded(pos)) return false;
ItemStack itemstack = origstack; ItemStack itemstack = origstack;
if (blockState.getBlock().isAir(blockState, world, pos) || itemstack.isEmpty()) { if (blockState.getBlock().isAir(blockState, world, pos) || itemstack.isEmpty()) {
@@ -57,21 +56,15 @@ public class SurvivalHelper {
//Drop existing block //Drop existing block
dropBlock(world, player, pos); dropBlock(world, player, pos);
//TryPlace sets block with offset, so we only do world.setBlockState now //TryPlace sets block with offset and reduces itemstack count in creative, so we copy only parts of it
//Remember count of itemstack before tryPlace, and set it back after.
//TryPlace reduces stack even in creative so it is not usable here.
// int origCount = itemstack.getCount();
// BlockItemUseContext blockItemUseContext = new BlockItemUseContext(world, player, itemstack, pos, facing, (float) hitVec.x, (float) hitVec.y, (float) hitVec.z); // BlockItemUseContext blockItemUseContext = new BlockItemUseContext(world, player, itemstack, pos, facing, (float) hitVec.x, (float) hitVec.y, (float) hitVec.z);
// EnumActionResult result = ((ItemBlock) itemstack.getItem()).tryPlace(blockItemUseContext); // EnumActionResult result = ((ItemBlock) itemstack.getItem()).tryPlace(blockItemUseContext);
// itemstack.setCount(origCount); if (!world.setBlock(pos, blockState, 3)) return false;
BlockItem.updateCustomBlockEntityTag(world, player, pos, itemstack); //Actually BlockItem::onBlockPlaced but that is protected
//Set our (rotated) blockstate block.setPlacedBy(world, pos, blockState, player, itemstack);
world.setBlockState(pos, blockState, 3); if (player instanceof ServerPlayerEntity) {
// blockState.onBlockAdded(world, pos, blockState); CriteriaTriggers.PLACED_BLOCK.trigger((ServerPlayerEntity) player, pos, itemstack);
// block.onBlockPlacedBy(world, pos, blockState, player, itemstack); }
// world.notifyBlockUpdate(pos, blockState, world.getBlockState(pos), 3);
// if (result != EnumActionResult.SUCCESS) return false;
BlockState afterState = world.getBlockState(pos); BlockState afterState = world.getBlockState(pos);
@@ -80,8 +73,8 @@ public class SurvivalHelper {
world.playSound(null, pos, soundtype.getPlaceSound(), SoundCategory.BLOCKS, (soundtype.getVolume() + 1.0F) / 2.0F, soundtype.getPitch() * 0.8F); world.playSound(null, pos, soundtype.getPlaceSound(), SoundCategory.BLOCKS, (soundtype.getVolume() + 1.0F) / 2.0F, soundtype.getPitch() * 0.8F);
} }
if (!player.isCreative() && Block.getBlockFromItem(itemstack.getItem()) == block) { if (!player.isCreative() && Block.byItem(itemstack.getItem()) == block) {
CompatHelper.shrinkStack(origstack, itemstack, player); itemstack.shrink(1);
} }
return true; return true;
@@ -116,7 +109,7 @@ public class SurvivalHelper {
//Used for all breaking of blocks in this mod. //Used for all breaking of blocks in this mod.
//Checks if area is loaded, if appropriate tool is used in survival mode, and drops the block directly into the players inventory //Checks if area is loaded, if appropriate tool is used in survival mode, and drops the block directly into the players inventory
public static boolean breakBlock(World world, PlayerEntity player, BlockPos pos, boolean skipChecks) { public static boolean breakBlock(World world, PlayerEntity player, BlockPos pos, boolean skipChecks) {
if (!world.isBlockPresent(pos) && !world.isAirBlock(pos)) return false; if (!world.isLoaded(pos) && !world.isEmptyBlock(pos)) return false;
//Check if can break //Check if can break
if (skipChecks || canBreak(world, player, pos)) { if (skipChecks || canBreak(world, player, pos)) {
@@ -127,7 +120,7 @@ public class SurvivalHelper {
dropBlock(world, player, pos); dropBlock(world, player, pos);
//Damage tool //Damage tool
player.getHeldItemMainhand().onBlockDestroyed(world, world.getBlockState(pos), pos, player); player.getMainHandItem().mineBlock(world, world.getBlockState(pos), pos, player);
world.removeBlock(pos, false); world.removeBlock(pos, false);
return true; return true;
@@ -136,13 +129,13 @@ public class SurvivalHelper {
} }
//Gives items directly to player //Gives items directly to player
public static void dropBlock(World world, PlayerEntity player, BlockPos pos){ public static void dropBlock(World world, PlayerEntity player, BlockPos pos) {
if (player.isCreative()) return; if (player.isCreative()) return;
BlockState blockState = world.getBlockState(pos); BlockState blockState = world.getBlockState(pos);
Block block = blockState.getBlock(); Block block = blockState.getBlock();
block.harvestBlock(world, player, pos, blockState, world.getTileEntity(pos), player.getHeldItemMainhand()); block.playerDestroy(world, player, pos, blockState, world.getBlockEntity(pos), player.getMainHandItem());
//TODO drop items in inventory instead of world //TODO drop items in inventory instead of world
@@ -177,6 +170,7 @@ public class SurvivalHelper {
/** /**
* Check if player can place a block. * Check if player can place a block.
* Turn randomizer bag into itemstack inside before. * Turn randomizer bag into itemstack inside before.
*
* @param world * @param world
* @param player * @param player
* @param pos * @param pos
@@ -189,7 +183,7 @@ public class SurvivalHelper {
public static boolean canPlace(World world, PlayerEntity player, BlockPos pos, BlockState newBlockState, ItemStack itemStack, boolean skipCollisionCheck, Direction sidePlacedOn) { public static boolean canPlace(World world, PlayerEntity player, BlockPos pos, BlockState newBlockState, ItemStack itemStack, boolean skipCollisionCheck, Direction sidePlacedOn) {
//Check if itemstack is correct //Check if itemstack is correct
if (!(itemStack.getItem() instanceof BlockItem) || Block.getBlockFromItem(itemStack.getItem()) != newBlockState.getBlock()) { if (!(itemStack.getItem() instanceof BlockItem) || Block.byItem(itemStack.getItem()) != newBlockState.getBlock()) {
// EffortlessBuilding.log(player, "Cannot (re)place block", true); // EffortlessBuilding.log(player, "Cannot (re)place block", true);
// EffortlessBuilding.log("SurvivalHelper#canPlace: itemstack " + itemStack.toString() + " does not match blockstate " + newBlockState.toString()); // EffortlessBuilding.log("SurvivalHelper#canPlace: itemstack " + itemStack.toString() + " does not match blockstate " + newBlockState.toString());
//Happens when breaking blocks, no need to notify in that case //Happens when breaking blocks, no need to notify in that case
@@ -204,49 +198,48 @@ public class SurvivalHelper {
} }
//Can be harvested with hand? (or in creative) //Can be harvested with hand? (or in creative)
private static boolean canReplace(World world, PlayerEntity player, BlockPos pos){ private static boolean canReplace(World world, PlayerEntity player, BlockPos pos) {
if (player.isCreative()) return true; if (player.isCreative()) return true;
BlockState state = world.getBlockState(pos); BlockState state = world.getBlockState(pos);
switch (BuildConfig.survivalBalancers.quickReplaceMiningLevel.get()) { switch (BuildConfig.survivalBalancers.quickReplaceMiningLevel.get()) {
case -1: return state.getMaterial().isToolNotRequired(); case -1:
case 0: return state.getBlock().getHarvestLevel(state) <= 0; return !state.requiresCorrectToolForDrops();
case 1: return state.getBlock().getHarvestLevel(state) <= 1; case 0:
case 2: return state.getBlock().getHarvestLevel(state) <= 2; return state.getBlock().getHarvestLevel(state) <= 0;
case 3: return state.getBlock().getHarvestLevel(state) <= 3; case 1:
return state.getBlock().getHarvestLevel(state) <= 1;
case 2:
return state.getBlock().getHarvestLevel(state) <= 2;
case 3:
return state.getBlock().getHarvestLevel(state) <= 3;
} }
return false; return false;
} }
//From EntityPlayer#canPlayerEdit //From EntityPlayer#canPlayerEdit
private static boolean canPlayerEdit(PlayerEntity player, World world, BlockPos pos, ItemStack stack) private static boolean canPlayerEdit(PlayerEntity player, World world, BlockPos pos, ItemStack stack) {
{ if (!world.mayInteract(player, pos)) return false;
if (!world.isBlockModifiable(player, pos)) return false;
if (player.abilities.allowEdit) if (player.abilities.mayBuild) {
{
//True in creative and survival mode //True in creative and survival mode
return true; return true;
} } else {
else
{
//Adventure mode //Adventure mode
CachedBlockInfo blockworldstate = new CachedBlockInfo(world, pos, false); CachedBlockInfo blockworldstate = new CachedBlockInfo(world, pos, false);
return stack.canPlaceOn(world.getTags(), blockworldstate); return stack.hasAdventureModePlaceTagForBlock(world.getTagManager(), blockworldstate);
} }
} }
//From World#mayPlace //From World#mayPlace
private static boolean mayPlace(World world, Block blockIn, BlockState newBlockState, BlockPos pos, boolean skipCollisionCheck, Direction sidePlacedOn, @Nullable Entity placer) private static boolean mayPlace(World world, Block blockIn, BlockState newBlockState, BlockPos pos, boolean skipCollisionCheck, Direction sidePlacedOn, @Nullable Entity placer) {
{
BlockState iblockstate1 = world.getBlockState(pos); BlockState iblockstate1 = world.getBlockState(pos);
VoxelShape voxelShape = skipCollisionCheck ? null : blockIn.getDefaultState().getCollisionShape(world, pos); VoxelShape voxelShape = skipCollisionCheck ? null : blockIn.defaultBlockState().getCollisionShape(world, pos);
if (voxelShape != null && !world.checkNoEntityCollision(placer, voxelShape)) if (voxelShape != null && !world.isUnobstructed(placer, voxelShape)) {
{
return false; return false;
} }
@@ -262,8 +255,7 @@ public class SurvivalHelper {
} }
//TODO 1.14 check what Material.CIRCUITS has become //TODO 1.14 check what Material.CIRCUITS has become
if (iblockstate1.getMaterial() == Material.REDSTONE_LIGHT && blockIn == Blocks.ANVIL) if (iblockstate1.getMaterial() == Material.BUILDABLE_GLASS && blockIn == Blocks.ANVIL) {
{
return true; return true;
} }
@@ -277,7 +269,6 @@ public class SurvivalHelper {
} }
//Can break using held tool? (or in creative) //Can break using held tool? (or in creative)
public static boolean canBreak(World world, PlayerEntity player, BlockPos pos) { public static boolean canBreak(World world, PlayerEntity player, BlockPos pos) {
BlockState blockState = world.getBlockState(pos); BlockState blockState = world.getBlockState(pos);
@@ -289,46 +280,43 @@ public class SurvivalHelper {
} }
//From ForgeHooks#canHarvestBlock //From ForgeHooks#canHarvestBlock
public static boolean canHarvestBlock(@Nonnull Block block, @Nonnull PlayerEntity player, @Nonnull World world, @Nonnull BlockPos pos) public static boolean canHarvestBlock(@Nonnull Block block, @Nonnull PlayerEntity player, @Nonnull World world, @Nonnull BlockPos pos) {
{
BlockState state = world.getBlockState(pos); BlockState state = world.getBlockState(pos);
//Dont break bedrock //Dont break bedrock
if (state.getBlockHardness(world, pos) < 0) { if (state.getDestroySpeed(world, pos) < 0) {
return false; return false;
} }
if (state.getMaterial().isToolNotRequired()) if (!state.requiresCorrectToolForDrops()) {
{
return true; return true;
} }
ItemStack stack = player.getHeldItemMainhand(); ItemStack stack = player.getMainHandItem();
ToolType tool = block.getHarvestTool(state); ToolType tool = block.getHarvestTool(state);
if (stack.isEmpty() || tool == null) if (stack.isEmpty() || tool == null) {
{ return player.hasCorrectToolForDrops(state);
return player.canHarvestBlock(state);
} }
if (stack.getDamage() >= stack.getMaxDamage()) return false; if (stack.getDamageValue() >= stack.getMaxDamage()) return false;
int toolLevel = stack.getItem().getHarvestLevel(stack, tool, player, state); int toolLevel = stack.getItem().getHarvestLevel(stack, tool, player, state);
if (toolLevel < 0) if (toolLevel < 0) {
{ return player.hasCorrectToolForDrops(state);
return player.canHarvestBlock(state);
} }
return toolLevel >= block.getHarvestLevel(state); return toolLevel >= block.getHarvestLevel(state);
} }
public static boolean doesBecomeDoubleSlab(PlayerEntity player, BlockPos pos, Direction facing) { public static boolean doesBecomeDoubleSlab(PlayerEntity player, BlockPos pos, Direction facing) {
BlockState placedBlockState = player.world.getBlockState(pos); BlockState placedBlockState = player.level.getBlockState(pos);
ItemStack itemstack = player.getHeldItem(Hand.MAIN_HAND); ItemStack itemstack = player.getItemInHand(Hand.MAIN_HAND);
if (CompatHelper.isItemBlockProxy(itemstack)) if (CompatHelper.isItemBlockProxy(itemstack))
itemstack = CompatHelper.getItemBlockFromStack(itemstack); itemstack = CompatHelper.getItemBlockFromStack(itemstack);
if (itemstack.isEmpty() || !(itemstack.getItem() instanceof BlockItem) || !(((BlockItem) itemstack.getItem()).getBlock() instanceof SlabBlock)) return false; if (itemstack.isEmpty() || !(itemstack.getItem() instanceof BlockItem) || !(((BlockItem) itemstack.getItem()).getBlock() instanceof SlabBlock))
return false;
SlabBlock heldSlab = (SlabBlock) ((BlockItem) itemstack.getItem()).getBlock(); SlabBlock heldSlab = (SlabBlock) ((BlockItem) itemstack.getItem()).getBlock();
if (placedBlockState.getBlock() == heldSlab) { if (placedBlockState.getBlock() == heldSlab) {

View File

@@ -1,160 +1,73 @@
package nl.requios.effortlessbuilding.item; package nl.requios.effortlessbuilding.item;
import mcp.MethodsReturnNonnullByDefault;
import net.minecraft.block.Block; import net.minecraft.block.Block;
import net.minecraft.block.BlockState; import net.minecraft.block.BlockState;
import net.minecraft.client.util.ITooltipFlag; import net.minecraft.client.util.ITooltipFlag;
import net.minecraft.entity.player.PlayerEntity; import net.minecraft.entity.player.PlayerEntity;
import net.minecraft.entity.player.PlayerInventory;
import net.minecraft.entity.player.ServerPlayerEntity; import net.minecraft.entity.player.ServerPlayerEntity;
import net.minecraft.inventory.container.Container; import net.minecraft.fluid.Fluids;
import net.minecraft.inventory.container.INamedContainerProvider; import net.minecraft.inventory.container.INamedContainerProvider;
import net.minecraft.item.*; import net.minecraft.item.*;
import net.minecraft.nbt.CompoundNBT; import net.minecraft.nbt.CompoundNBT;
import net.minecraft.util.*; import net.minecraft.util.ActionResult;
import net.minecraft.util.ActionResultType; import net.minecraft.util.ActionResultType;
import net.minecraft.util.Direction;
import net.minecraft.util.Hand; import net.minecraft.util.Hand;
import net.minecraft.util.math.BlockPos; import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.BlockRayTraceResult; import net.minecraft.util.math.BlockRayTraceResult;
import net.minecraft.util.math.Vec3d; import net.minecraft.util.math.vector.Vector3d;
import net.minecraft.util.text.ITextComponent; import net.minecraft.util.text.ITextComponent;
import net.minecraft.util.text.StringTextComponent; import net.minecraft.util.text.StringTextComponent;
import net.minecraft.util.text.TextFormatting; import net.minecraft.util.text.TextFormatting;
import net.minecraft.util.text.TranslationTextComponent;
import net.minecraft.world.World; import net.minecraft.world.World;
import net.minecraftforge.common.capabilities.ICapabilityProvider; import net.minecraftforge.common.capabilities.ICapabilityProvider;
import net.minecraftforge.fml.network.NetworkHooks; import net.minecraftforge.fml.network.NetworkHooks;
import net.minecraftforge.items.CapabilityItemHandler; import net.minecraftforge.items.CapabilityItemHandler;
import net.minecraftforge.items.IItemHandler; import net.minecraftforge.items.IItemHandler;
import nl.requios.effortlessbuilding.EffortlessBuilding;
import nl.requios.effortlessbuilding.buildmode.BuildModes; import nl.requios.effortlessbuilding.buildmode.BuildModes;
import nl.requios.effortlessbuilding.buildmode.ModeSettingsManager; import nl.requios.effortlessbuilding.buildmode.ModeSettingsManager;
import nl.requios.effortlessbuilding.buildmodifier.ModifierSettingsManager; import nl.requios.effortlessbuilding.buildmodifier.ModifierSettingsManager;
import nl.requios.effortlessbuilding.capability.ItemHandlerCapabilityProvider; import nl.requios.effortlessbuilding.capability.ItemHandlerCapabilityProvider;
import nl.requios.effortlessbuilding.gui.RandomizerBagContainer;
import nl.requios.effortlessbuilding.helper.SurvivalHelper; import nl.requios.effortlessbuilding.helper.SurvivalHelper;
import javax.annotation.Nullable; import javax.annotation.Nullable;
import javax.annotation.ParametersAreNonnullByDefault;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Calendar; import java.util.Calendar;
import java.util.List; import java.util.List;
import java.util.Random; import java.util.Random;
public class ItemRandomizerBag extends Item { @MethodsReturnNonnullByDefault
public static final int INV_SIZE = 5; @ParametersAreNonnullByDefault
public abstract class AbstractRandomizerBagItem extends Item {
private static long currentSeed = 1337; private static long currentSeed = 1337;
private static Random rand = new Random(currentSeed); private static final Random rand = new Random(currentSeed);
public ItemRandomizerBag() { public AbstractRandomizerBagItem() {
super(new Item.Properties().group(ItemGroup.TOOLS).maxStackSize(1)); super(new Item.Properties().tab(ItemGroup.TAB_TOOLS).stacksTo(1));
this.setRegistryName(EffortlessBuilding.MODID, "randomizer_bag");
} }
@Override public abstract int getInventorySize();
public ActionResultType onItemUse(ItemUseContext ctx) {
PlayerEntity player = ctx.getPlayer();
World world = ctx.getWorld();
BlockPos pos = ctx.getPos();
Direction facing = ctx.getFace();
ItemStack item = ctx.getItem();
Vec3d hitVec = ctx.getHitVec();
if (player == null) return ActionResultType.FAIL; public abstract INamedContainerProvider getContainerProvider(ItemStack item);
if (ctx.isPlacerSneaking()) {
if (world.isRemote) return ActionResultType.SUCCESS;
//Open inventory
NetworkHooks.openGui((ServerPlayerEntity) player, new ContainerProvider(item));
} else {
if (world.isRemote) return ActionResultType.SUCCESS;
//Only place manually if in normal vanilla mode
BuildModes.BuildModeEnum buildMode = ModeSettingsManager.getModeSettings(player).getBuildMode();
ModifierSettingsManager.ModifierSettings modifierSettings = ModifierSettingsManager.getModifierSettings(player);
if (buildMode != BuildModes.BuildModeEnum.NORMAL || modifierSettings.doQuickReplace()) {
return ActionResultType.FAIL;
}
//Use item
//Get bag inventory
//TODO offhand support
ItemStack bag = player.getHeldItem(Hand.MAIN_HAND);
IItemHandler bagInventory = getBagInventory(bag);
if (bagInventory == null)
return ActionResultType.FAIL;
ItemStack toPlace = pickRandomStack(bagInventory);
if (toPlace.isEmpty()) return ActionResultType.FAIL;
//Previously: use onItemUse to place block (no synergy)
//bag.setItemDamage(toPlace.getMetadata());
//toPlace.onItemUse(player, world, pos, hand, facing, hitX, hitY, hitZ);
//TODO replaceable
if (!world.getBlockState(pos).getBlock().getMaterial(world.getBlockState(pos)).isReplaceable()) {
pos = pos.offset(facing);
}
BlockItemUseContext blockItemUseContext = new BlockItemUseContext(new ItemUseContext(player, Hand.MAIN_HAND, new BlockRayTraceResult(hitVec, facing, pos, false)));
BlockState blockState = Block.getBlockFromItem(toPlace.getItem()).getStateForPlacement(blockItemUseContext);
SurvivalHelper.placeBlock(world, player, pos, blockState, toPlace, facing, hitVec, false, false, true);
//Synergy
//Works without calling
// BlockSnapshot blockSnapshot = new BlockSnapshot(player.world, pos, blockState);
// BlockEvent.PlaceEvent placeEvent = new BlockEvent.PlaceEvent(blockSnapshot, blockState, player, hand);
// Mirror.onBlockPlaced(placeEvent);
// Array.onBlockPlaced(placeEvent);
}
return ActionResultType.SUCCESS;
}
@Override
public ActionResult<ItemStack> onItemRightClick(World world, PlayerEntity player, Hand hand) {
ItemStack bag = player.getHeldItem(hand);
if (player.isSneaking()) {
if (world.isRemote) return new ActionResult<>(ActionResultType.SUCCESS, bag);
//Open inventory
NetworkHooks.openGui((ServerPlayerEntity) player, new ContainerProvider(bag));
} else {
//Use item
//Get bag inventory
IItemHandler bagInventory = getBagInventory(bag);
if (bagInventory == null)
return new ActionResult<>(ActionResultType.FAIL, bag);
ItemStack toUse = pickRandomStack(bagInventory);
if (toUse.isEmpty()) return new ActionResult<>(ActionResultType.FAIL, bag);
return toUse.useItemRightClick(world, player, hand);
}
return new ActionResult<>(ActionResultType.PASS, bag);
}
/** /**
* Get the inventory of a randomizer bag by checking the capability. * Get the inventory of a randomizer bag by checking the capability.
*
* @param bag
* @return
*/ */
public static IItemHandler getBagInventory(ItemStack bag) { public IItemHandler getBagInventory(ItemStack bag) {
return bag.getCapability(CapabilityItemHandler.ITEM_HANDLER_CAPABILITY, null).orElse(null); return bag.getCapability(CapabilityItemHandler.ITEM_HANDLER_CAPABILITY, null).orElse(null);
} }
/** /**
* Pick a random slot from the bag. Empty slots will never get chosen. * Pick a random slot from the bag. Empty slots will never get chosen.
*
* @param bagInventory
* @return
*/ */
public static ItemStack pickRandomStack(IItemHandler bagInventory) { public ItemStack pickRandomStack(IItemHandler bagInventory) {
//Find how many stacks are non-empty, and save them in a list //Find how many stacks are non-empty, and save them in a list
int nonempty = 0; int nonempty = 0;
List<ItemStack> nonEmptyStacks = new ArrayList<>(INV_SIZE); List<ItemStack> nonEmptyStacks = new ArrayList<>();
List<Integer> originalSlots = new ArrayList<>(INV_SIZE); List<Integer> originalSlots = new ArrayList<>(getInventorySize());
for (int i = 0; i < bagInventory.getSlots(); i++) { for (int i = 0; i < bagInventory.getSlots(); i++) {
ItemStack stack = bagInventory.getStackInSlot(i); ItemStack stack = bagInventory.getStackInSlot(i);
if (!stack.isEmpty()) { if (!stack.isEmpty()) {
@@ -179,7 +92,7 @@ public class ItemRandomizerBag extends Item {
return bagInventory.getStackInSlot(originalSlot); return bagInventory.getStackInSlot(originalSlot);
} }
public static ItemStack findStack(IItemHandler bagInventory, Item item) { public ItemStack findStack(IItemHandler bagInventory, Item item) {
for (int i = 0; i < bagInventory.getSlots(); i++) { for (int i = 0; i < bagInventory.getSlots(); i++) {
ItemStack stack = bagInventory.getStackInSlot(i); ItemStack stack = bagInventory.getStackInSlot(i);
if (!stack.isEmpty() && stack.getItem() == item) { if (!stack.isEmpty() && stack.getItem() == item) {
@@ -189,31 +102,6 @@ public class ItemRandomizerBag extends Item {
return ItemStack.EMPTY; return ItemStack.EMPTY;
} }
@Override
public int getUseDuration(ItemStack p_77626_1_) {
return 1;
}
@Nullable
@Override
public ICapabilityProvider initCapabilities(ItemStack stack, @Nullable CompoundNBT nbt) {
return new ItemHandlerCapabilityProvider();
}
@Override
public void addInformation(ItemStack stack, @Nullable World world, List<ITextComponent> tooltip, ITooltipFlag flag) {
tooltip.add(new StringTextComponent(TextFormatting.BLUE + "Rightclick" + TextFormatting.GRAY + " to place a random block"));
tooltip.add(new StringTextComponent(TextFormatting.BLUE + "Sneak + rightclick" + TextFormatting.GRAY + " to open inventory"));
if (world != null && world.getPlayers().size() > 1) {
tooltip.add(new StringTextComponent(TextFormatting.YELLOW + "Experimental on servers: may lose inventory"));
}
}
@Override
public String getTranslationKey() {
return this.getRegistryName().toString();
}
public static void resetRandomness() { public static void resetRandomness() {
rand.setSeed(currentSeed); rand.setSeed(currentSeed);
} }
@@ -223,23 +111,111 @@ public class ItemRandomizerBag extends Item {
rand.setSeed(currentSeed); rand.setSeed(currentSeed);
} }
public static class ContainerProvider implements INamedContainerProvider{ @Override
public ActionResultType useOn(ItemUseContext ctx) {
PlayerEntity player = ctx.getPlayer();
World world = ctx.getLevel();
BlockPos pos = ctx.getClickedPos();
Direction facing = ctx.getClickedFace();
ItemStack item = ctx.getItemInHand();
Vector3d hitVec = ctx.getClickLocation();
private ItemStack bag; if (player == null) return ActionResultType.FAIL;
public ContainerProvider(ItemStack bag) { if (ctx.getPlayer() != null && ctx.getPlayer().isShiftKeyDown()) { //ctx.isPlacerSneaking()
this.bag = bag; if (world.isClientSide) return ActionResultType.SUCCESS;
//Open inventory
NetworkHooks.openGui((ServerPlayerEntity) player, getContainerProvider(item));
} else {
if (world.isClientSide) return ActionResultType.SUCCESS;
//Only place manually if in normal vanilla mode
BuildModes.BuildModeEnum buildMode = ModeSettingsManager.getModeSettings(player).getBuildMode();
ModifierSettingsManager.ModifierSettings modifierSettings = ModifierSettingsManager.getModifierSettings(player);
if (buildMode != BuildModes.BuildModeEnum.NORMAL || modifierSettings.doQuickReplace()) {
return ActionResultType.FAIL;
}
//Use item
//Get bag inventory
//TODO offhand support
ItemStack bag = player.getItemInHand(Hand.MAIN_HAND);
IItemHandler bagInventory = getBagInventory(bag);
if (bagInventory == null)
return ActionResultType.FAIL;
ItemStack toPlace = pickRandomStack(bagInventory);
if (toPlace.isEmpty()) return ActionResultType.FAIL;
//Previously: use onItemUse to place block (no synergy)
//bag.setItemDamage(toPlace.getMetadata());
//toPlace.onItemUse(player, world, pos, hand, facing, hitX, hitY, hitZ);
//TODO replaceable
if (!world.getBlockState(pos).getBlock().canBeReplaced(world.getBlockState(pos), Fluids.EMPTY)) {
pos = pos.relative(facing);
}
BlockItemUseContext blockItemUseContext = new BlockItemUseContext(new ItemUseContext(player, Hand.MAIN_HAND, new BlockRayTraceResult(hitVec, facing, pos, false)));
BlockState blockState = Block.byItem(toPlace.getItem()).getStateForPlacement(blockItemUseContext);
SurvivalHelper.placeBlock(world, player, pos, blockState, toPlace, facing, hitVec, false, false, true);
//Synergy
//Works without calling
// BlockSnapshot blockSnapshot = new BlockSnapshot(player.world, pos, blockState);
// BlockEvent.PlaceEvent placeEvent = new BlockEvent.PlaceEvent(blockSnapshot, blockState, player, hand);
// Mirror.onBlockPlaced(placeEvent);
// Array.onBlockPlaced(placeEvent);
}
return ActionResultType.SUCCESS;
} }
@Override @Override
public ITextComponent getDisplayName() { public ActionResult<ItemStack> use(World world, PlayerEntity player, Hand hand) {
return new TranslationTextComponent("effortlessbuilding.screen.randomizer_bag"); ItemStack bag = player.getItemInHand(hand);
if (player.isShiftKeyDown()) {
if (world.isClientSide) return new ActionResult<>(ActionResultType.SUCCESS, bag);
//Open inventory
NetworkHooks.openGui((ServerPlayerEntity) player, getContainerProvider(bag));
} else {
//Use item
//Get bag inventory
IItemHandler bagInventory = getBagInventory(bag);
if (bagInventory == null)
return new ActionResult<>(ActionResultType.FAIL, bag);
ItemStack toUse = pickRandomStack(bagInventory);
if (toUse.isEmpty()) return new ActionResult<>(ActionResultType.FAIL, bag);
return toUse.use(world, player, hand);
}
return new ActionResult<>(ActionResultType.PASS, bag);
}
@Override
public int getUseDuration(ItemStack p_77626_1_) {
return 1;
} }
@Nullable @Nullable
@Override @Override
public Container createMenu(int containerId, PlayerInventory playerInventory, PlayerEntity player) { public ICapabilityProvider initCapabilities(ItemStack stack, @Nullable CompoundNBT nbt) {
return new RandomizerBagContainer(containerId, playerInventory, ItemRandomizerBag.getBagInventory(bag)); return new ItemHandlerCapabilityProvider(getInventorySize());
} }
@Override
public void appendHoverText(ItemStack stack, @Nullable World world, List<ITextComponent> tooltip, ITooltipFlag flag) {
tooltip.add(new StringTextComponent(TextFormatting.BLUE + "Rightclick" + TextFormatting.GRAY + " to place a random block"));
tooltip.add(new StringTextComponent(TextFormatting.BLUE + "Sneak + rightclick" + TextFormatting.GRAY + " to open inventory"));
if (world != null && world.players().size() > 1) {
tooltip.add(new StringTextComponent(TextFormatting.YELLOW + "Experimental on servers: may lose inventory"));
}
}
@Override
public String getDescriptionId() {
return this.getRegistryName().toString();
} }
} }

View File

@@ -0,0 +1,46 @@
package nl.requios.effortlessbuilding.item;
import net.minecraft.entity.player.PlayerEntity;
import net.minecraft.entity.player.PlayerInventory;
import net.minecraft.inventory.container.Container;
import net.minecraft.inventory.container.INamedContainerProvider;
import net.minecraft.item.ItemStack;
import net.minecraft.util.text.ITextComponent;
import net.minecraft.util.text.TranslationTextComponent;
import nl.requios.effortlessbuilding.gui.DiamondRandomizerBagContainer;
import javax.annotation.Nullable;
public class DiamondRandomizerBagItem extends AbstractRandomizerBagItem{
public static final int INV_SIZE = 27;
@Override
public int getInventorySize() {
return 27;
}
@Override
public INamedContainerProvider getContainerProvider(ItemStack bag) {
return new ContainerProvider(bag);
}
public static class ContainerProvider implements INamedContainerProvider {
private final ItemStack bag;
public ContainerProvider(ItemStack bag) {
this.bag = bag;
}
@Override
public ITextComponent getDisplayName() {
return new TranslationTextComponent("effortlessbuilding:diamond_randomizer_bag");
}
@Nullable
@Override
public Container createMenu(int containerId, PlayerInventory playerInventory, PlayerEntity player) {
return new DiamondRandomizerBagContainer(containerId, playerInventory, ((AbstractRandomizerBagItem)bag.getItem()).getBagInventory(bag));
}
}
}

View File

@@ -0,0 +1,46 @@
package nl.requios.effortlessbuilding.item;
import net.minecraft.entity.player.PlayerEntity;
import net.minecraft.entity.player.PlayerInventory;
import net.minecraft.inventory.container.Container;
import net.minecraft.inventory.container.INamedContainerProvider;
import net.minecraft.item.ItemStack;
import net.minecraft.util.text.ITextComponent;
import net.minecraft.util.text.TranslationTextComponent;
import nl.requios.effortlessbuilding.gui.GoldenRandomizerBagContainer;
import javax.annotation.Nullable;
public class GoldenRandomizerBagItem extends AbstractRandomizerBagItem{
public static final int INV_SIZE = 9;
@Override
public int getInventorySize() {
return 9;
}
@Override
public INamedContainerProvider getContainerProvider(ItemStack bag) {
return new ContainerProvider(bag);
}
public static class ContainerProvider implements INamedContainerProvider {
private final ItemStack bag;
public ContainerProvider(ItemStack bag) {
this.bag = bag;
}
@Override
public ITextComponent getDisplayName() {
return new TranslationTextComponent("effortlessbuilding:golden_randomizer_bag");
}
@Nullable
@Override
public Container createMenu(int containerId, PlayerInventory playerInventory, PlayerEntity player) {
return new GoldenRandomizerBagContainer(containerId, playerInventory, ((AbstractRandomizerBagItem)bag.getItem()).getBagInventory(bag));
}
}
}

View File

@@ -1,65 +0,0 @@
package nl.requios.effortlessbuilding.item;
import net.minecraft.client.util.ITooltipFlag;
import net.minecraft.entity.player.PlayerEntity;
import net.minecraft.item.Item;
import net.minecraft.item.ItemGroup;
import net.minecraft.item.ItemStack;
import net.minecraft.util.*;
import net.minecraft.util.text.ITextComponent;
import net.minecraft.util.text.StringTextComponent;
import net.minecraft.util.text.TextFormatting;
import net.minecraft.world.World;
import nl.requios.effortlessbuilding.BuildConfig;
import nl.requios.effortlessbuilding.EffortlessBuilding;
import nl.requios.effortlessbuilding.buildmodifier.ModifierSettingsManager;
import nl.requios.effortlessbuilding.helper.ReachHelper;
import javax.annotation.Nullable;
import java.util.List;
public class ItemReachUpgrade1 extends Item {
public ItemReachUpgrade1() {
super(new Item.Properties().group(ItemGroup.TOOLS).maxStackSize(1));
this.setRegistryName(EffortlessBuilding.MODID, "reach_upgrade1");
}
@Override
public ActionResult<ItemStack> onItemRightClick(World world, PlayerEntity player, Hand hand) {
if (player.isCreative()) {
if (world.isRemote) EffortlessBuilding.log(player, "Reach upgrades are not necessary in creative.");
if (world.isRemote) EffortlessBuilding.log(player, "Still want increased reach? Use the config.");
return new ActionResult<>(ActionResultType.PASS, player.getHeldItem(hand));
}
ModifierSettingsManager.ModifierSettings modifierSettings = ModifierSettingsManager.getModifierSettings(player);
int currentLevel = modifierSettings.getReachUpgrade();
if (currentLevel == 0) {
modifierSettings.setReachUpgrade(1);
if (world.isRemote) EffortlessBuilding.log(player, "Upgraded reach to " + ReachHelper.getMaxReach(player));
player.setHeldItem(hand, ItemStack.EMPTY);
SoundEvent soundEvent = new SoundEvent(new ResourceLocation("entity.player.levelup"));
player.playSound(soundEvent, 1f, 1f);
} else if (currentLevel > 0) {
if (world.isRemote) EffortlessBuilding.log(player, "Already used this upgrade! Current reach is " + ReachHelper
.getMaxReach(player) + ".");
SoundEvent soundEvent = new SoundEvent(new ResourceLocation("item.armor.equip_leather"));
player.playSound(soundEvent, 1f, 1f);
}
return new ActionResult<>(ActionResultType.PASS, player.getHeldItem(hand));
}
@Override
public void addInformation(ItemStack stack, @Nullable World world, List<ITextComponent> tooltip, ITooltipFlag flag) {
tooltip.add(new StringTextComponent(TextFormatting.GRAY + "Consume to increase reach to " + TextFormatting.BLUE + BuildConfig.reach.maxReachLevel1.get()));
}
@Override
public String getTranslationKey() {
return this.getRegistryName().toString();
}
}

View File

@@ -1,70 +0,0 @@
package nl.requios.effortlessbuilding.item;
import net.minecraft.client.util.ITooltipFlag;
import net.minecraft.entity.player.PlayerEntity;
import net.minecraft.item.Item;
import net.minecraft.item.ItemGroup;
import net.minecraft.item.ItemStack;
import net.minecraft.util.*;
import net.minecraft.util.text.ITextComponent;
import net.minecraft.util.text.StringTextComponent;
import net.minecraft.util.text.TextFormatting;
import net.minecraft.world.World;
import nl.requios.effortlessbuilding.BuildConfig;
import nl.requios.effortlessbuilding.EffortlessBuilding;
import nl.requios.effortlessbuilding.buildmodifier.ModifierSettingsManager;
import nl.requios.effortlessbuilding.helper.ReachHelper;
import javax.annotation.Nullable;
import java.util.List;
public class ItemReachUpgrade2 extends Item {
public ItemReachUpgrade2() {
super(new Item.Properties().group(ItemGroup.TOOLS).maxStackSize(1));
this.setRegistryName(EffortlessBuilding.MODID, "reach_upgrade2");
}
@Override
public ActionResult<ItemStack> onItemRightClick(World world, PlayerEntity player, Hand hand) {
if (player.isCreative()) {
if (world.isRemote) EffortlessBuilding.log(player, "Reach upgrades are not necessary in creative.");
if (world.isRemote) EffortlessBuilding.log(player, "Still want increased reach? Use the config.");
return new ActionResult<>(ActionResultType.PASS, player.getHeldItem(hand));
}
ModifierSettingsManager.ModifierSettings modifierSettings = ModifierSettingsManager.getModifierSettings(player);
int currentLevel = modifierSettings.getReachUpgrade();
if (currentLevel == 1) {
modifierSettings.setReachUpgrade(2);
if (world.isRemote) EffortlessBuilding.log(player, "Upgraded reach to " + ReachHelper.getMaxReach(player));
player.setHeldItem(hand, ItemStack.EMPTY);
SoundEvent soundEvent = new SoundEvent(new ResourceLocation("entity.player.levelup"));
player.playSound(soundEvent, 1f, 1f);
} else if (currentLevel < 1) {
if (world.isRemote) EffortlessBuilding.log(player, "Use Reach Upgrade 1 first.");
SoundEvent soundEvent = new SoundEvent(new ResourceLocation("item.armor.equip_leather"));
player.playSound(soundEvent, 1f, 1f);
} else if (currentLevel > 1) {
if (world.isRemote) EffortlessBuilding.log(player, "Already used this upgrade! Current reach is " + ReachHelper
.getMaxReach(player) + ".");
SoundEvent soundEvent = new SoundEvent(new ResourceLocation("item.armor.equip_leather"));
player.playSound(soundEvent, 1f, 1f);
}
return new ActionResult<>(ActionResultType.PASS, player.getHeldItem(hand));
}
@Override
public void addInformation(ItemStack stack, @Nullable World world, List<ITextComponent> tooltip, ITooltipFlag flag) {
tooltip.add(new StringTextComponent(TextFormatting.GRAY + "Consume to increase reach to " + TextFormatting.BLUE + BuildConfig.reach.maxReachLevel2.get()));
tooltip.add(new StringTextComponent(TextFormatting.GRAY + "Previous upgrades need to be consumed first"));
}
@Override
public String getTranslationKey() {
return this.getRegistryName().toString();
}
}

View File

@@ -1,73 +0,0 @@
package nl.requios.effortlessbuilding.item;
import net.minecraft.client.util.ITooltipFlag;
import net.minecraft.entity.player.PlayerEntity;
import net.minecraft.item.Item;
import net.minecraft.item.ItemGroup;
import net.minecraft.item.ItemStack;
import net.minecraft.util.*;
import net.minecraft.util.text.ITextComponent;
import net.minecraft.util.text.StringTextComponent;
import net.minecraft.util.text.TextFormatting;
import net.minecraft.world.World;
import nl.requios.effortlessbuilding.BuildConfig;
import nl.requios.effortlessbuilding.EffortlessBuilding;
import nl.requios.effortlessbuilding.buildmodifier.ModifierSettingsManager;
import nl.requios.effortlessbuilding.helper.ReachHelper;
import javax.annotation.Nullable;
import java.util.List;
public class ItemReachUpgrade3 extends Item {
public ItemReachUpgrade3() {
super(new Item.Properties().group(ItemGroup.TOOLS).maxStackSize(1));
this.setRegistryName(EffortlessBuilding.MODID, "reach_upgrade3");
}
@Override
public ActionResult<ItemStack> onItemRightClick(World world, PlayerEntity player, Hand hand) {
if (player.isCreative()) {
if (world.isRemote) EffortlessBuilding.log(player, "Reach upgrades are not necessary in creative.");
if (world.isRemote) EffortlessBuilding.log(player, "Still want increased reach? Use the config.");
return new ActionResult<>(ActionResultType.PASS, player.getHeldItem(hand));
}
ModifierSettingsManager.ModifierSettings modifierSettings = ModifierSettingsManager.getModifierSettings(player);
int currentLevel = modifierSettings.getReachUpgrade();
if (currentLevel == 2) {
modifierSettings.setReachUpgrade(3);
if (world.isRemote) EffortlessBuilding.log(player, "Upgraded reach to " + ReachHelper.getMaxReach(player));
player.setHeldItem(hand, ItemStack.EMPTY);
SoundEvent soundEvent = new SoundEvent(new ResourceLocation("entity.player.levelup"));
player.playSound(soundEvent, 1f, 1f);
} else if (currentLevel < 2) {
if (currentLevel == 0)
if (world.isRemote) EffortlessBuilding.log(player, "Use Reach Upgrade 1 and 2 first.");
if (currentLevel == 1)
if (world.isRemote) EffortlessBuilding.log(player, "Use Reach Upgrade 2 first.");
SoundEvent soundEvent = new SoundEvent(new ResourceLocation("item.armor.equip_leather"));
player.playSound(soundEvent, 1f, 1f);
} else if (currentLevel > 2) {
if (world.isRemote) EffortlessBuilding.log(player, "Already used this upgrade! Current reach is " + ReachHelper
.getMaxReach(player) + ".");
SoundEvent soundEvent = new SoundEvent(new ResourceLocation("item.armor.equip_leather"));
player.playSound(soundEvent, 1f, 1f);
}
return new ActionResult<>(ActionResultType.PASS, player.getHeldItem(hand));
}
@Override
public void addInformation(ItemStack stack, @Nullable World world, List<ITextComponent> tooltip, ITooltipFlag flag) {
tooltip.add(new StringTextComponent(TextFormatting.GRAY + "Consume to increase reach to " + TextFormatting.BLUE + BuildConfig.reach.maxReachLevel3.get()));
tooltip.add(new StringTextComponent(TextFormatting.GRAY + "Previous upgrades need to be consumed first"));
}
@Override
public String getTranslationKey() {
return this.getRegistryName().toString();
}
}

View File

@@ -0,0 +1,46 @@
package nl.requios.effortlessbuilding.item;
import net.minecraft.entity.player.PlayerEntity;
import net.minecraft.entity.player.PlayerInventory;
import net.minecraft.inventory.container.Container;
import net.minecraft.inventory.container.INamedContainerProvider;
import net.minecraft.item.ItemStack;
import net.minecraft.util.text.ITextComponent;
import net.minecraft.util.text.TranslationTextComponent;
import nl.requios.effortlessbuilding.gui.RandomizerBagContainer;
import javax.annotation.Nullable;
public class RandomizerBagItem extends AbstractRandomizerBagItem{
public static final int INV_SIZE = 5;
@Override
public int getInventorySize() {
return 5;
}
@Override
public INamedContainerProvider getContainerProvider(ItemStack bag) {
return new ContainerProvider(bag);
}
public static class ContainerProvider implements INamedContainerProvider {
private final ItemStack bag;
public ContainerProvider(ItemStack bag) {
this.bag = bag;
}
@Override
public ITextComponent getDisplayName() {
return new TranslationTextComponent("effortlessbuilding:randomizer_bag");
}
@Nullable
@Override
public Container createMenu(int containerId, PlayerInventory playerInventory, PlayerEntity player) {
return new RandomizerBagContainer(containerId, playerInventory, ((AbstractRandomizerBagItem)bag.getItem()).getBagInventory(bag));
}
}
}

View File

@@ -0,0 +1,69 @@
package nl.requios.effortlessbuilding.item;
import mcp.MethodsReturnNonnullByDefault;
import net.minecraft.client.util.ITooltipFlag;
import net.minecraft.entity.player.PlayerEntity;
import net.minecraft.item.Item;
import net.minecraft.item.ItemGroup;
import net.minecraft.item.ItemStack;
import net.minecraft.util.*;
import net.minecraft.util.text.ITextComponent;
import net.minecraft.util.text.StringTextComponent;
import net.minecraft.util.text.TextFormatting;
import net.minecraft.world.World;
import nl.requios.effortlessbuilding.BuildConfig;
import nl.requios.effortlessbuilding.EffortlessBuilding;
import nl.requios.effortlessbuilding.buildmodifier.ModifierSettingsManager;
import nl.requios.effortlessbuilding.helper.ReachHelper;
import javax.annotation.Nullable;
import javax.annotation.ParametersAreNonnullByDefault;
import java.util.List;
@ParametersAreNonnullByDefault
@MethodsReturnNonnullByDefault
public class ReachUpgrade1Item extends Item {
public ReachUpgrade1Item() {
super(new Item.Properties().tab(ItemGroup.TAB_TOOLS).stacksTo(1));
}
@Override
public ActionResult<ItemStack> use(World world, PlayerEntity player, Hand hand) {
if (player.isCreative()) {
if (world.isClientSide) EffortlessBuilding.log(player, "Reach upgrades are not necessary in creative.");
if (world.isClientSide) EffortlessBuilding.log(player, "Still want increased reach? Use the config.");
return new ActionResult<>(ActionResultType.PASS, player.getItemInHand(hand));
}
ModifierSettingsManager.ModifierSettings modifierSettings = ModifierSettingsManager.getModifierSettings(player);
int currentLevel = modifierSettings.getReachUpgrade();
if (currentLevel == 0) {
modifierSettings.setReachUpgrade(1);
if (world.isClientSide) EffortlessBuilding.log(player, "Upgraded reach to " + ReachHelper.getMaxReach(player));
player.setItemInHand(hand, ItemStack.EMPTY);
SoundEvent soundEvent = new SoundEvent(new ResourceLocation("entity.player.levelup"));
player.playSound(soundEvent, 1f, 1f);
} else if (currentLevel > 0) {
if (world.isClientSide)
EffortlessBuilding.log(player, "Already used this upgrade! Current reach is " + ReachHelper
.getMaxReach(player) + ".");
SoundEvent soundEvent = new SoundEvent(new ResourceLocation("item.armor.equip_leather"));
player.playSound(soundEvent, 1f, 1f);
}
return new ActionResult<>(ActionResultType.PASS, player.getItemInHand(hand));
}
@Override
public void appendHoverText(ItemStack stack, @Nullable World world, List<ITextComponent> tooltip, ITooltipFlag flag) {
tooltip.add(new StringTextComponent(TextFormatting.GRAY + "Consume to increase reach to " + TextFormatting.BLUE + BuildConfig.reach.maxReachLevel1.get()));
}
@Override
public String getDescriptionId() {
return this.getRegistryName().toString();
}
}

View File

@@ -0,0 +1,74 @@
package nl.requios.effortlessbuilding.item;
import mcp.MethodsReturnNonnullByDefault;
import net.minecraft.client.util.ITooltipFlag;
import net.minecraft.entity.player.PlayerEntity;
import net.minecraft.item.Item;
import net.minecraft.item.ItemGroup;
import net.minecraft.item.ItemStack;
import net.minecraft.util.*;
import net.minecraft.util.text.ITextComponent;
import net.minecraft.util.text.StringTextComponent;
import net.minecraft.util.text.TextFormatting;
import net.minecraft.world.World;
import nl.requios.effortlessbuilding.BuildConfig;
import nl.requios.effortlessbuilding.EffortlessBuilding;
import nl.requios.effortlessbuilding.buildmodifier.ModifierSettingsManager;
import nl.requios.effortlessbuilding.helper.ReachHelper;
import javax.annotation.Nullable;
import javax.annotation.ParametersAreNonnullByDefault;
import java.util.List;
@ParametersAreNonnullByDefault
@MethodsReturnNonnullByDefault
public class ReachUpgrade2Item extends Item {
public ReachUpgrade2Item() {
super(new Item.Properties().tab(ItemGroup.TAB_TOOLS).stacksTo(1));
}
@Override
public ActionResult<ItemStack> use(World world, PlayerEntity player, Hand hand) {
if (player.isCreative()) {
if (world.isClientSide) EffortlessBuilding.log(player, "Reach upgrades are not necessary in creative.");
if (world.isClientSide) EffortlessBuilding.log(player, "Still want increased reach? Use the config.");
return new ActionResult<>(ActionResultType.PASS, player.getItemInHand(hand));
}
ModifierSettingsManager.ModifierSettings modifierSettings = ModifierSettingsManager.getModifierSettings(player);
int currentLevel = modifierSettings.getReachUpgrade();
if (currentLevel == 1) {
modifierSettings.setReachUpgrade(2);
if (world.isClientSide) EffortlessBuilding.log(player, "Upgraded reach to " + ReachHelper.getMaxReach(player));
player.setItemInHand(hand, ItemStack.EMPTY);
SoundEvent soundEvent = new SoundEvent(new ResourceLocation("entity.player.levelup"));
player.playSound(soundEvent, 1f, 1f);
} else if (currentLevel < 1) {
if (world.isClientSide) EffortlessBuilding.log(player, "Use Reach Upgrade 1 first.");
SoundEvent soundEvent = new SoundEvent(new ResourceLocation("item.armor.equip_leather"));
player.playSound(soundEvent, 1f, 1f);
} else if (currentLevel > 1) {
if (world.isClientSide)
EffortlessBuilding.log(player, "Already used this upgrade! Current reach is " + ReachHelper
.getMaxReach(player) + ".");
SoundEvent soundEvent = new SoundEvent(new ResourceLocation("item.armor.equip_leather"));
player.playSound(soundEvent, 1f, 1f);
}
return new ActionResult<>(ActionResultType.PASS, player.getItemInHand(hand));
}
@Override
public void appendHoverText(ItemStack stack, @Nullable World world, List<ITextComponent> tooltip, ITooltipFlag flag) {
tooltip.add(new StringTextComponent(TextFormatting.GRAY + "Consume to increase reach to " + TextFormatting.BLUE + BuildConfig.reach.maxReachLevel2.get()));
tooltip.add(new StringTextComponent(TextFormatting.GRAY + "Previous upgrades need to be consumed first"));
}
@Override
public String getDescriptionId() {
return this.getRegistryName().toString();
}
}

View File

@@ -0,0 +1,77 @@
package nl.requios.effortlessbuilding.item;
import mcp.MethodsReturnNonnullByDefault;
import net.minecraft.client.util.ITooltipFlag;
import net.minecraft.entity.player.PlayerEntity;
import net.minecraft.item.Item;
import net.minecraft.item.ItemGroup;
import net.minecraft.item.ItemStack;
import net.minecraft.util.*;
import net.minecraft.util.text.ITextComponent;
import net.minecraft.util.text.StringTextComponent;
import net.minecraft.util.text.TextFormatting;
import net.minecraft.world.World;
import nl.requios.effortlessbuilding.BuildConfig;
import nl.requios.effortlessbuilding.EffortlessBuilding;
import nl.requios.effortlessbuilding.buildmodifier.ModifierSettingsManager;
import nl.requios.effortlessbuilding.helper.ReachHelper;
import javax.annotation.Nullable;
import javax.annotation.ParametersAreNonnullByDefault;
import java.util.List;
@ParametersAreNonnullByDefault
@MethodsReturnNonnullByDefault
public class ReachUpgrade3Item extends Item {
public ReachUpgrade3Item() {
super(new Item.Properties().tab(ItemGroup.TAB_TOOLS).stacksTo(1));
}
@Override
public ActionResult<ItemStack> use(World world, PlayerEntity player, Hand hand) {
if (player.isCreative()) {
if (world.isClientSide) EffortlessBuilding.log(player, "Reach upgrades are not necessary in creative.");
if (world.isClientSide) EffortlessBuilding.log(player, "Still want increased reach? Use the config.");
return new ActionResult<>(ActionResultType.PASS, player.getItemInHand(hand));
}
ModifierSettingsManager.ModifierSettings modifierSettings = ModifierSettingsManager.getModifierSettings(player);
int currentLevel = modifierSettings.getReachUpgrade();
if (currentLevel == 2) {
modifierSettings.setReachUpgrade(3);
if (world.isClientSide) EffortlessBuilding.log(player, "Upgraded reach to " + ReachHelper.getMaxReach(player));
player.setItemInHand(hand, ItemStack.EMPTY);
SoundEvent soundEvent = new SoundEvent(new ResourceLocation("entity.player.levelup"));
player.playSound(soundEvent, 1f, 1f);
} else if (currentLevel < 2) {
if (currentLevel == 0)
if (world.isClientSide) EffortlessBuilding.log(player, "Use Reach Upgrade 1 and 2 first.");
if (currentLevel == 1)
if (world.isClientSide) EffortlessBuilding.log(player, "Use Reach Upgrade 2 first.");
SoundEvent soundEvent = new SoundEvent(new ResourceLocation("item.armor.equip_leather"));
player.playSound(soundEvent, 1f, 1f);
} else if (currentLevel > 2) {
if (world.isClientSide)
EffortlessBuilding.log(player, "Already used this upgrade! Current reach is " + ReachHelper
.getMaxReach(player) + ".");
SoundEvent soundEvent = new SoundEvent(new ResourceLocation("item.armor.equip_leather"));
player.playSound(soundEvent, 1f, 1f);
}
return new ActionResult<>(ActionResultType.PASS, player.getItemInHand(hand));
}
@Override
public void appendHoverText(ItemStack stack, @Nullable World world, List<ITextComponent> tooltip, ITooltipFlag flag) {
tooltip.add(new StringTextComponent(TextFormatting.GRAY + "Consume to increase reach to " + TextFormatting.BLUE + BuildConfig.reach.maxReachLevel3.get()));
tooltip.add(new StringTextComponent(TextFormatting.GRAY + "Previous upgrades need to be consumed first"));
}
@Override
public String getDescriptionId() {
return this.getRegistryName().toString();
}
}

View File

@@ -5,7 +5,7 @@ import net.minecraft.block.BlockState;
import net.minecraft.entity.player.PlayerEntity; import net.minecraft.entity.player.PlayerEntity;
import net.minecraft.network.PacketBuffer; import net.minecraft.network.PacketBuffer;
import net.minecraft.util.math.BlockPos; import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.Vec3d; import net.minecraft.util.math.vector.Vector3d;
import net.minecraftforge.fml.LogicalSide; import net.minecraftforge.fml.LogicalSide;
import net.minecraftforge.fml.network.NetworkEvent; import net.minecraftforge.fml.network.NetworkEvent;
import nl.requios.effortlessbuilding.EffortlessBuilding; import nl.requios.effortlessbuilding.EffortlessBuilding;
@@ -19,9 +19,9 @@ import java.util.function.Supplier;
* Sends a message to the client asking to add a block to the undo stack. * Sends a message to the client asking to add a block to the undo stack.
*/ */
public class AddUndoMessage { public class AddUndoMessage {
private BlockPos coordinate; private final BlockPos coordinate;
private BlockState previousBlockState; private final BlockState previousBlockState;
private BlockState newBlockState; private final BlockState newBlockState;
public AddUndoMessage() { public AddUndoMessage() {
coordinate = BlockPos.ZERO; coordinate = BlockPos.ZERO;
@@ -35,6 +35,21 @@ public class AddUndoMessage {
this.newBlockState = newBlockState; this.newBlockState = newBlockState;
} }
public static void encode(AddUndoMessage message, PacketBuffer buf) {
buf.writeInt(message.coordinate.getX());
buf.writeInt(message.coordinate.getY());
buf.writeInt(message.coordinate.getZ());
buf.writeInt(Block.getId(message.previousBlockState));
buf.writeInt(Block.getId(message.newBlockState));
}
public static AddUndoMessage decode(PacketBuffer buf) {
BlockPos coordinate = new BlockPos(buf.readInt(), buf.readInt(), buf.readInt());
BlockState previousBlockState = Block.stateById(buf.readInt());
BlockState newBlockState = Block.stateById(buf.readInt());
return new AddUndoMessage(coordinate, previousBlockState, newBlockState);
}
public BlockPos getCoordinate() { public BlockPos getCoordinate() {
return coordinate; return coordinate;
} }
@@ -47,25 +62,8 @@ public class AddUndoMessage {
return newBlockState; return newBlockState;
} }
public static void encode(AddUndoMessage message, PacketBuffer buf) { public static class Handler {
buf.writeInt(message.coordinate.getX()); public static void handle(AddUndoMessage message, Supplier<NetworkEvent.Context> ctx) {
buf.writeInt(message.coordinate.getY());
buf.writeInt(message.coordinate.getZ());
buf.writeInt(Block.getStateId(message.previousBlockState));
buf.writeInt(Block.getStateId(message.newBlockState));
}
public static AddUndoMessage decode(PacketBuffer buf) {
BlockPos coordinate = new BlockPos(buf.readInt(), buf.readInt(), buf.readInt());
BlockState previousBlockState = Block.getStateById(buf.readInt());
BlockState newBlockState = Block.getStateById(buf.readInt());
return new AddUndoMessage(coordinate, previousBlockState, newBlockState);
}
public static class Handler
{
public static void handle(AddUndoMessage message, Supplier<NetworkEvent.Context> ctx)
{
ctx.get().enqueueWork(() -> { ctx.get().enqueueWork(() -> {
if (ctx.get().getDirection().getReceptionSide() == LogicalSide.CLIENT) { if (ctx.get().getDirection().getReceptionSide() == LogicalSide.CLIENT) {
//Received clientside //Received clientside
@@ -74,10 +72,16 @@ public class AddUndoMessage {
//Add to undo stack clientside //Add to undo stack clientside
//Only the appropriate player that needs to add this to the undo stack gets this message //Only the appropriate player that needs to add this to the undo stack gets this message
UndoRedo.addUndo(player, new BlockSet( UndoRedo.addUndo(player, new BlockSet(
new ArrayList<BlockPos>() {{add(message.getCoordinate());}}, new ArrayList<BlockPos>() {{
new ArrayList<BlockState>() {{add(message.getPreviousBlockState());}}, add(message.getCoordinate());
new ArrayList<BlockState>() {{add(message.getNewBlockState());}}, }},
new Vec3d(0,0,0), new ArrayList<BlockState>() {{
add(message.getPreviousBlockState());
}},
new ArrayList<BlockState>() {{
add(message.getNewBlockState());
}},
new Vector3d(0, 0, 0),
message.getCoordinate(), message.getCoordinate())); message.getCoordinate(), message.getCoordinate()));
} }
}); });

View File

@@ -5,10 +5,9 @@ import net.minecraft.util.Direction;
import net.minecraft.util.math.BlockPos; import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.BlockRayTraceResult; import net.minecraft.util.math.BlockRayTraceResult;
import net.minecraft.util.math.RayTraceResult; import net.minecraft.util.math.RayTraceResult;
import net.minecraft.util.math.Vec3d; import net.minecraft.util.math.vector.Vector3d;
import net.minecraftforge.fml.LogicalSide; import net.minecraftforge.fml.LogicalSide;
import net.minecraftforge.fml.network.NetworkEvent; import net.minecraftforge.fml.network.NetworkEvent;
import nl.requios.effortlessbuilding.EffortlessBuilding;
import nl.requios.effortlessbuilding.buildmode.BuildModes; import nl.requios.effortlessbuilding.buildmode.BuildModes;
import java.util.function.Supplier; import java.util.function.Supplier;
@@ -18,32 +17,51 @@ import java.util.function.Supplier;
*/ */
public class BlockBrokenMessage { public class BlockBrokenMessage {
private boolean blockHit; private final boolean blockHit;
private BlockPos blockPos; private final BlockPos blockPos;
private Direction sideHit; private final Direction sideHit;
private Vec3d hitVec; private final Vector3d hitVec;
public BlockBrokenMessage() { public BlockBrokenMessage() {
this.blockHit = false; this.blockHit = false;
this.blockPos = BlockPos.ZERO; this.blockPos = BlockPos.ZERO;
this.sideHit = Direction.UP; this.sideHit = Direction.UP;
this.hitVec = new Vec3d(0, 0, 0); this.hitVec = new Vector3d(0, 0, 0);
} }
public BlockBrokenMessage(BlockRayTraceResult result) { public BlockBrokenMessage(BlockRayTraceResult result) {
this.blockHit = result.getType() == RayTraceResult.Type.BLOCK; this.blockHit = result.getType() == RayTraceResult.Type.BLOCK;
this.blockPos = result.getPos(); this.blockPos = result.getBlockPos();
this.sideHit = result.getFace(); this.sideHit = result.getDirection();
this.hitVec = result.getHitVec(); this.hitVec = result.getLocation();
} }
public BlockBrokenMessage(boolean blockHit, BlockPos blockPos, Direction sideHit, Vec3d hitVec) { public BlockBrokenMessage(boolean blockHit, BlockPos blockPos, Direction sideHit, Vector3d hitVec) {
this.blockHit = blockHit; this.blockHit = blockHit;
this.blockPos = blockPos; this.blockPos = blockPos;
this.sideHit = sideHit; this.sideHit = sideHit;
this.hitVec = hitVec; this.hitVec = hitVec;
} }
public static void encode(BlockBrokenMessage message, PacketBuffer buf) {
buf.writeBoolean(message.blockHit);
buf.writeInt(message.blockPos.getX());
buf.writeInt(message.blockPos.getY());
buf.writeInt(message.blockPos.getZ());
buf.writeInt(message.sideHit.get3DDataValue());
buf.writeDouble(message.hitVec.x);
buf.writeDouble(message.hitVec.y);
buf.writeDouble(message.hitVec.z);
}
public static BlockBrokenMessage decode(PacketBuffer buf) {
boolean blockHit = buf.readBoolean();
BlockPos blockPos = new BlockPos(buf.readInt(), buf.readInt(), buf.readInt());
Direction sideHit = Direction.from3DDataValue(buf.readInt());
Vector3d hitVec = new Vector3d(buf.readDouble(), buf.readDouble(), buf.readDouble());
return new BlockBrokenMessage(blockHit, blockPos, sideHit, hitVec);
}
public boolean isBlockHit() { public boolean isBlockHit() {
return blockHit; return blockHit;
} }
@@ -56,33 +74,12 @@ public class BlockBrokenMessage {
return sideHit; return sideHit;
} }
public Vec3d getHitVec() { public Vector3d getHitVec() {
return hitVec; return hitVec;
} }
public static void encode(BlockBrokenMessage message, PacketBuffer buf) { public static class Handler {
buf.writeBoolean(message.blockHit); public static void handle(BlockBrokenMessage message, Supplier<NetworkEvent.Context> ctx) {
buf.writeInt(message.blockPos.getX());
buf.writeInt(message.blockPos.getY());
buf.writeInt(message.blockPos.getZ());
buf.writeInt(message.sideHit.getIndex());
buf.writeDouble(message.hitVec.x);
buf.writeDouble(message.hitVec.y);
buf.writeDouble(message.hitVec.z);
}
public static BlockBrokenMessage decode(PacketBuffer buf) {
boolean blockHit = buf.readBoolean();
BlockPos blockPos = new BlockPos(buf.readInt(), buf.readInt(), buf.readInt());
Direction sideHit = Direction.byIndex(buf.readInt());
Vec3d hitVec = new Vec3d(buf.readDouble(), buf.readDouble(), buf.readDouble());
return new BlockBrokenMessage(blockHit, blockPos, sideHit, hitVec);
}
public static class Handler
{
public static void handle(BlockBrokenMessage message, Supplier<NetworkEvent.Context> ctx)
{
ctx.get().enqueueWork(() -> { ctx.get().enqueueWork(() -> {
if (ctx.get().getDirection().getReceptionSide() == LogicalSide.SERVER) { if (ctx.get().getDirection().getReceptionSide() == LogicalSide.SERVER) {
//Received serverside //Received serverside

View File

@@ -1,14 +1,13 @@
package nl.requios.effortlessbuilding.network; package nl.requios.effortlessbuilding.network;
import net.minecraft.network.PacketBuffer;
import net.minecraft.util.Direction; import net.minecraft.util.Direction;
import net.minecraft.util.math.BlockPos; import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.BlockRayTraceResult; import net.minecraft.util.math.BlockRayTraceResult;
import net.minecraft.util.math.RayTraceResult; import net.minecraft.util.math.RayTraceResult;
import net.minecraft.util.math.Vec3d; import net.minecraft.util.math.vector.Vector3d;
import net.minecraft.network.PacketBuffer;
import net.minecraftforge.fml.LogicalSide; import net.minecraftforge.fml.LogicalSide;
import net.minecraftforge.fml.network.NetworkEvent; import net.minecraftforge.fml.network.NetworkEvent;
import nl.requios.effortlessbuilding.EffortlessBuilding;
import nl.requios.effortlessbuilding.buildmode.BuildModes; import nl.requios.effortlessbuilding.buildmode.BuildModes;
import nl.requios.effortlessbuilding.render.BlockPreviewRenderer; import nl.requios.effortlessbuilding.render.BlockPreviewRenderer;
@@ -20,29 +19,29 @@ import java.util.function.Supplier;
*/ */
public class BlockPlacedMessage { public class BlockPlacedMessage {
private boolean blockHit; private final boolean blockHit;
private BlockPos blockPos; private final BlockPos blockPos;
private Direction sideHit; private final Direction sideHit;
private Vec3d hitVec; private final Vector3d hitVec;
private boolean placeStartPos; //prevent double placing in normal mode private final boolean placeStartPos; //prevent double placing in normal mode
public BlockPlacedMessage() { public BlockPlacedMessage() {
this.blockHit = false; this.blockHit = false;
this.blockPos = BlockPos.ZERO; this.blockPos = BlockPos.ZERO;
this.sideHit = Direction.UP; this.sideHit = Direction.UP;
this.hitVec = new Vec3d(0, 0, 0); this.hitVec = new Vector3d(0, 0, 0);
this.placeStartPos = true; this.placeStartPos = true;
} }
public BlockPlacedMessage(BlockRayTraceResult result, boolean placeStartPos) { public BlockPlacedMessage(BlockRayTraceResult result, boolean placeStartPos) {
this.blockHit = result.getType() == RayTraceResult.Type.BLOCK; this.blockHit = result.getType() == RayTraceResult.Type.BLOCK;
this.blockPos = result.getPos(); this.blockPos = result.getBlockPos();
this.sideHit = result.getFace(); this.sideHit = result.getDirection();
this.hitVec = result.getHitVec(); this.hitVec = result.getLocation();
this.placeStartPos = placeStartPos; this.placeStartPos = placeStartPos;
} }
public BlockPlacedMessage(boolean blockHit, BlockPos blockPos, Direction sideHit, Vec3d hitVec, boolean placeStartPos) { public BlockPlacedMessage(boolean blockHit, BlockPos blockPos, Direction sideHit, Vector3d hitVec, boolean placeStartPos) {
this.blockHit = blockHit; this.blockHit = blockHit;
this.blockPos = blockPos; this.blockPos = blockPos;
this.sideHit = sideHit; this.sideHit = sideHit;
@@ -50,6 +49,27 @@ public class BlockPlacedMessage {
this.placeStartPos = placeStartPos; this.placeStartPos = placeStartPos;
} }
public static void encode(BlockPlacedMessage message, PacketBuffer buf) {
buf.writeBoolean(message.blockHit);
buf.writeInt(message.blockPos.getX());
buf.writeInt(message.blockPos.getY());
buf.writeInt(message.blockPos.getZ());
buf.writeInt(message.sideHit.get3DDataValue());
buf.writeDouble(message.hitVec.x);
buf.writeDouble(message.hitVec.y);
buf.writeDouble(message.hitVec.z);
buf.writeBoolean(message.placeStartPos);
}
public static BlockPlacedMessage decode(PacketBuffer buf) {
boolean blockHit = buf.readBoolean();
BlockPos blockPos = new BlockPos(buf.readInt(), buf.readInt(), buf.readInt());
Direction sideHit = Direction.from3DDataValue(buf.readInt());
Vector3d hitVec = new Vector3d(buf.readDouble(), buf.readDouble(), buf.readDouble());
boolean placeStartPos = buf.readBoolean();
return new BlockPlacedMessage(blockHit, blockPos, sideHit, hitVec, placeStartPos);
}
public boolean isBlockHit() { public boolean isBlockHit() {
return blockHit; return blockHit;
} }
@@ -62,7 +82,7 @@ public class BlockPlacedMessage {
return sideHit; return sideHit;
} }
public Vec3d getHitVec() { public Vector3d getHitVec() {
return hitVec; return hitVec;
} }
@@ -70,31 +90,8 @@ public class BlockPlacedMessage {
return placeStartPos; return placeStartPos;
} }
public static void encode(BlockPlacedMessage message, PacketBuffer buf) { public static class Handler {
buf.writeBoolean(message.blockHit); public static void handle(BlockPlacedMessage message, Supplier<NetworkEvent.Context> ctx) {
buf.writeInt(message.blockPos.getX());
buf.writeInt(message.blockPos.getY());
buf.writeInt(message.blockPos.getZ());
buf.writeInt(message.sideHit.getIndex());
buf.writeDouble(message.hitVec.x);
buf.writeDouble(message.hitVec.y);
buf.writeDouble(message.hitVec.z);
buf.writeBoolean(message.placeStartPos);
}
public static BlockPlacedMessage decode(PacketBuffer buf) {
boolean blockHit = buf.readBoolean();
BlockPos blockPos = new BlockPos(buf.readInt(), buf.readInt(), buf.readInt());
Direction sideHit = Direction.byIndex(buf.readInt());
Vec3d hitVec = new Vec3d(buf.readDouble(), buf.readDouble(), buf.readDouble());
boolean placeStartPos = buf.readBoolean();
return new BlockPlacedMessage(blockHit, blockPos, sideHit, hitVec, placeStartPos);
}
public static class Handler
{
public static void handle(BlockPlacedMessage message, Supplier<NetworkEvent.Context> ctx)
{
ctx.get().enqueueWork(() -> { ctx.get().enqueueWork(() -> {
if (ctx.get().getDirection().getReceptionSide() == LogicalSide.CLIENT) { if (ctx.get().getDirection().getReceptionSide() == LogicalSide.CLIENT) {
//Received clientside //Received clientside

View File

@@ -20,10 +20,8 @@ public class CancelModeMessage {
return new CancelModeMessage(); return new CancelModeMessage();
} }
public static class Handler public static class Handler {
{ public static void handle(CancelModeMessage message, Supplier<NetworkEvent.Context> ctx) {
public static void handle(CancelModeMessage message, Supplier<NetworkEvent.Context> ctx)
{
ctx.get().enqueueWork(() -> { ctx.get().enqueueWork(() -> {
PlayerEntity player = EffortlessBuilding.proxy.getPlayerEntityFromContext(ctx); PlayerEntity player = EffortlessBuilding.proxy.getPlayerEntityFromContext(ctx);

View File

@@ -25,10 +25,8 @@ public class ClearUndoMessage {
return new ClearUndoMessage(); return new ClearUndoMessage();
} }
public static class Handler public static class Handler {
{ public static void handle(ClearUndoMessage message, Supplier<NetworkEvent.Context> ctx) {
public static void handle(ClearUndoMessage message, Supplier<NetworkEvent.Context> ctx)
{
ctx.get().enqueueWork(() -> { ctx.get().enqueueWork(() -> {
if (ctx.get().getDirection().getReceptionSide() == LogicalSide.CLIENT) { if (ctx.get().getDirection().getReceptionSide() == LogicalSide.CLIENT) {
//Received clientside //Received clientside

View File

@@ -31,10 +31,8 @@ public class ModeActionMessage {
return new ModeActionMessage(action); return new ModeActionMessage(action);
} }
public static class Handler public static class Handler {
{ public static void handle(ModeActionMessage message, Supplier<NetworkEvent.Context> ctx) {
public static void handle(ModeActionMessage message, Supplier<NetworkEvent.Context> ctx)
{
ctx.get().enqueueWork(() -> { ctx.get().enqueueWork(() -> {
PlayerEntity player = EffortlessBuilding.proxy.getPlayerEntityFromContext(ctx); PlayerEntity player = EffortlessBuilding.proxy.getPlayerEntityFromContext(ctx);

View File

@@ -34,10 +34,8 @@ public class ModeSettingsMessage {
return new ModeSettingsMessage(new ModeSettings(buildMode)); return new ModeSettingsMessage(new ModeSettings(buildMode));
} }
public static class Handler public static class Handler {
{ public static void handle(ModeSettingsMessage message, Supplier<NetworkEvent.Context> ctx) {
public static void handle(ModeSettingsMessage message, Supplier<NetworkEvent.Context> ctx)
{
ctx.get().enqueueWork(() -> { ctx.get().enqueueWork(() -> {
PlayerEntity player = EffortlessBuilding.proxy.getPlayerEntityFromContext(ctx); PlayerEntity player = EffortlessBuilding.proxy.getPlayerEntityFromContext(ctx);

View File

@@ -3,7 +3,7 @@ package nl.requios.effortlessbuilding.network;
import net.minecraft.entity.player.PlayerEntity; import net.minecraft.entity.player.PlayerEntity;
import net.minecraft.network.PacketBuffer; import net.minecraft.network.PacketBuffer;
import net.minecraft.util.math.BlockPos; import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.Vec3d; import net.minecraft.util.math.vector.Vector3d;
import net.minecraftforge.fml.network.NetworkEvent; import net.minecraftforge.fml.network.NetworkEvent;
import nl.requios.effortlessbuilding.EffortlessBuilding; import nl.requios.effortlessbuilding.EffortlessBuilding;
import nl.requios.effortlessbuilding.buildmodifier.Array; import nl.requios.effortlessbuilding.buildmodifier.Array;
@@ -15,6 +15,8 @@ import java.util.function.Supplier;
import static nl.requios.effortlessbuilding.buildmodifier.ModifierSettingsManager.ModifierSettings; import static nl.requios.effortlessbuilding.buildmodifier.ModifierSettingsManager.ModifierSettings;
import nl.requios.effortlessbuilding.buildmodifier.ModifierSettingsManager.ModifierSettings;
/** /**
* Shares modifier settings (see ModifierSettingsManager) between server and client * Shares modifier settings (see ModifierSettingsManager) between server and client
*/ */
@@ -82,7 +84,7 @@ public class ModifierSettingsMessage {
Mirror.MirrorSettings m = new Mirror.MirrorSettings(); Mirror.MirrorSettings m = new Mirror.MirrorSettings();
if (buf.readBoolean()) { if (buf.readBoolean()) {
boolean mirrorEnabled = buf.readBoolean(); boolean mirrorEnabled = buf.readBoolean();
Vec3d mirrorPosition = new Vec3d(buf.readDouble(), buf.readDouble(), buf.readDouble()); Vector3d mirrorPosition = new Vector3d(buf.readDouble(), buf.readDouble(), buf.readDouble());
boolean mirrorX = buf.readBoolean(); boolean mirrorX = buf.readBoolean();
boolean mirrorY = buf.readBoolean(); boolean mirrorY = buf.readBoolean();
boolean mirrorZ = buf.readBoolean(); boolean mirrorZ = buf.readBoolean();
@@ -110,7 +112,7 @@ public class ModifierSettingsMessage {
RadialMirror.RadialMirrorSettings r = new RadialMirror.RadialMirrorSettings(); RadialMirror.RadialMirrorSettings r = new RadialMirror.RadialMirrorSettings();
if (buf.readBoolean()) { if (buf.readBoolean()) {
boolean radialMirrorEnabled = buf.readBoolean(); boolean radialMirrorEnabled = buf.readBoolean();
Vec3d radialMirrorPosition = new Vec3d(buf.readDouble(), buf.readDouble(), buf.readDouble()); Vector3d radialMirrorPosition = new Vector3d(buf.readDouble(), buf.readDouble(), buf.readDouble());
int radialMirrorSlices = buf.readInt(); int radialMirrorSlices = buf.readInt();
boolean radialMirrorAlternate = buf.readBoolean(); boolean radialMirrorAlternate = buf.readBoolean();
int radialMirrorRadius = buf.readInt(); int radialMirrorRadius = buf.readInt();
@@ -124,10 +126,8 @@ public class ModifierSettingsMessage {
return new ModifierSettingsMessage(modifierSettings); return new ModifierSettingsMessage(modifierSettings);
} }
public static class Handler public static class Handler {
{ public static void handle(ModifierSettingsMessage message, Supplier<NetworkEvent.Context> ctx) {
public static void handle(ModifierSettingsMessage message, Supplier<NetworkEvent.Context> ctx)
{
ctx.get().enqueueWork(() -> { ctx.get().enqueueWork(() -> {
PlayerEntity player = EffortlessBuilding.proxy.getPlayerEntityFromContext(ctx); PlayerEntity player = EffortlessBuilding.proxy.getPlayerEntityFromContext(ctx);

View File

@@ -16,7 +16,7 @@ import java.util.function.Supplier;
* This is then sent back with a BlockPlacedMessage. * This is then sent back with a BlockPlacedMessage.
*/ */
public class RequestLookAtMessage { public class RequestLookAtMessage {
private boolean placeStartPos; private final boolean placeStartPos;
public RequestLookAtMessage() { public RequestLookAtMessage() {
placeStartPos = false; placeStartPos = false;
@@ -26,10 +26,6 @@ public class RequestLookAtMessage {
this.placeStartPos = placeStartPos; this.placeStartPos = placeStartPos;
} }
public boolean getPlaceStartPos() {
return placeStartPos;
}
public static void encode(RequestLookAtMessage message, PacketBuffer buf) { public static void encode(RequestLookAtMessage message, PacketBuffer buf) {
buf.writeBoolean(message.placeStartPos); buf.writeBoolean(message.placeStartPos);
} }
@@ -39,10 +35,12 @@ public class RequestLookAtMessage {
return new RequestLookAtMessage(placeStartPos); return new RequestLookAtMessage(placeStartPos);
} }
public static class Handler public boolean getPlaceStartPos() {
{ return placeStartPos;
public static void handle(RequestLookAtMessage message, Supplier<NetworkEvent.Context> ctx) }
{
public static class Handler {
public static void handle(RequestLookAtMessage message, Supplier<NetworkEvent.Context> ctx) {
ctx.get().enqueueWork(() -> { ctx.get().enqueueWork(() -> {
if (ctx.get().getDirection().getReceptionSide() == LogicalSide.CLIENT) { if (ctx.get().getDirection().getReceptionSide() == LogicalSide.CLIENT) {
//Received clientside //Received clientside

View File

@@ -1,26 +1,20 @@
package nl.requios.effortlessbuilding.network; package nl.requios.effortlessbuilding.network;
import net.minecraft.block.BlockState;
import net.minecraft.entity.player.PlayerEntity; import net.minecraft.entity.player.PlayerEntity;
import net.minecraft.network.PacketBuffer; import net.minecraft.network.PacketBuffer;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.Vec3d;
import net.minecraftforge.fml.LogicalSide; import net.minecraftforge.fml.LogicalSide;
import net.minecraftforge.fml.network.NetworkEvent; import net.minecraftforge.fml.network.NetworkEvent;
import nl.requios.effortlessbuilding.EffortlessBuilding; import nl.requios.effortlessbuilding.EffortlessBuilding;
import nl.requios.effortlessbuilding.buildmodifier.BlockSet;
import nl.requios.effortlessbuilding.buildmodifier.UndoRedo;
import java.util.ArrayList;
import java.util.function.Supplier; import java.util.function.Supplier;
public class TranslatedLogMessage { public class TranslatedLogMessage {
private String prefix; private final String prefix;
private String translationKey; private final String translationKey;
private String suffix; private final String suffix;
private boolean actionBar; private final boolean actionBar;
public TranslatedLogMessage(){ public TranslatedLogMessage() {
prefix = ""; prefix = "";
translationKey = ""; translationKey = "";
suffix = ""; suffix = "";
@@ -34,6 +28,17 @@ public class TranslatedLogMessage {
this.actionBar = actionBar; this.actionBar = actionBar;
} }
public static void encode(TranslatedLogMessage message, PacketBuffer buf) {
buf.writeUtf(message.prefix);
buf.writeUtf(message.translationKey);
buf.writeUtf(message.suffix);
buf.writeBoolean(message.actionBar);
}
public static TranslatedLogMessage decode(PacketBuffer buf) {
return new TranslatedLogMessage(buf.readUtf(), buf.readUtf(), buf.readUtf(), buf.readBoolean());
}
public String getPrefix() { public String getPrefix() {
return prefix; return prefix;
} }
@@ -50,21 +55,8 @@ public class TranslatedLogMessage {
return actionBar; return actionBar;
} }
public static void encode(TranslatedLogMessage message, PacketBuffer buf) { public static class Handler {
buf.writeString(message.prefix); public static void handle(TranslatedLogMessage message, Supplier<NetworkEvent.Context> ctx) {
buf.writeString(message.translationKey);
buf.writeString(message.suffix);
buf.writeBoolean(message.actionBar);
}
public static TranslatedLogMessage decode(PacketBuffer buf) {
return new TranslatedLogMessage(buf.readString(), buf.readString(), buf.readString(), buf.readBoolean());
}
public static class Handler
{
public static void handle(TranslatedLogMessage message, Supplier<NetworkEvent.Context> ctx)
{
ctx.get().enqueueWork(() -> { ctx.get().enqueueWork(() -> {
if (ctx.get().getDirection().getReceptionSide() == LogicalSide.CLIENT) { if (ctx.get().getDirection().getReceptionSide() == LogicalSide.CLIENT) {
//Received clientside //Received clientside

View File

@@ -1,12 +1,12 @@
package nl.requios.effortlessbuilding.proxy; package nl.requios.effortlessbuilding.proxy;
import mcp.MethodsReturnNonnullByDefault;
import net.minecraft.block.BlockState; import net.minecraft.block.BlockState;
import net.minecraft.block.SoundType; import net.minecraft.block.SoundType;
import net.minecraft.client.Minecraft; import net.minecraft.client.Minecraft;
import net.minecraft.client.entity.player.ClientPlayerEntity; import net.minecraft.client.entity.player.ClientPlayerEntity;
import net.minecraft.client.gui.ScreenManager; import net.minecraft.client.gui.ScreenManager;
import net.minecraft.client.gui.screen.Screen; import net.minecraft.client.gui.screen.Screen;
import net.minecraft.client.renderer.texture.TextureAtlasSprite;
import net.minecraft.client.resources.I18n; import net.minecraft.client.resources.I18n;
import net.minecraft.client.settings.KeyBinding; import net.minecraft.client.settings.KeyBinding;
import net.minecraft.client.util.InputMappings; import net.minecraft.client.util.InputMappings;
@@ -14,15 +14,17 @@ import net.minecraft.entity.player.PlayerEntity;
import net.minecraft.item.BlockItem; import net.minecraft.item.BlockItem;
import net.minecraft.item.ItemStack; import net.minecraft.item.ItemStack;
import net.minecraft.util.Hand; import net.minecraft.util.Hand;
import net.minecraft.util.ResourceLocation;
import net.minecraft.util.SoundCategory; import net.minecraft.util.SoundCategory;
import net.minecraft.util.math.*; import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.BlockRayTraceResult;
import net.minecraft.util.math.RayTraceContext;
import net.minecraft.util.math.RayTraceResult;
import net.minecraft.util.math.vector.Vector3d;
import net.minecraft.util.text.TextFormatting; import net.minecraft.util.text.TextFormatting;
import net.minecraft.world.World; import net.minecraft.world.World;
import net.minecraftforge.api.distmarker.Dist; import net.minecraftforge.api.distmarker.Dist;
import net.minecraftforge.client.event.GuiOpenEvent; import net.minecraftforge.client.event.GuiOpenEvent;
import net.minecraftforge.client.event.InputEvent; import net.minecraftforge.client.event.InputEvent;
import net.minecraftforge.client.event.TextureStitchEvent;
import net.minecraftforge.client.settings.KeyConflictContext; import net.minecraftforge.client.settings.KeyConflictContext;
import net.minecraftforge.client.settings.KeyModifier; import net.minecraftforge.client.settings.KeyModifier;
import net.minecraftforge.event.TickEvent; import net.minecraftforge.event.TickEvent;
@@ -40,7 +42,10 @@ import nl.requios.effortlessbuilding.buildmode.ModeOptions;
import nl.requios.effortlessbuilding.buildmode.ModeSettingsManager; import nl.requios.effortlessbuilding.buildmode.ModeSettingsManager;
import nl.requios.effortlessbuilding.buildmodifier.ModifierSettingsManager; import nl.requios.effortlessbuilding.buildmodifier.ModifierSettingsManager;
import nl.requios.effortlessbuilding.compatibility.CompatHelper; import nl.requios.effortlessbuilding.compatibility.CompatHelper;
import nl.requios.effortlessbuilding.gui.DiamondRandomizerBagScreen;
import nl.requios.effortlessbuilding.gui.GoldenRandomizerBagScreen;
import nl.requios.effortlessbuilding.gui.RandomizerBagScreen; import nl.requios.effortlessbuilding.gui.RandomizerBagScreen;
import nl.requios.effortlessbuilding.gui.buildmode.PlayerSettingsGui;
import nl.requios.effortlessbuilding.gui.buildmode.RadialMenu; import nl.requios.effortlessbuilding.gui.buildmode.RadialMenu;
import nl.requios.effortlessbuilding.gui.buildmodifier.ModifierSettingsGui; import nl.requios.effortlessbuilding.gui.buildmodifier.ModifierSettingsGui;
import nl.requios.effortlessbuilding.helper.ReachHelper; import nl.requios.effortlessbuilding.helper.ReachHelper;
@@ -48,59 +53,46 @@ import nl.requios.effortlessbuilding.network.*;
import nl.requios.effortlessbuilding.render.ShaderHandler; import nl.requios.effortlessbuilding.render.ShaderHandler;
import org.lwjgl.glfw.GLFW; import org.lwjgl.glfw.GLFW;
import javax.annotation.Nullable; import javax.annotation.ParametersAreNonnullByDefault;
import java.util.HashMap;
import java.util.function.Supplier; import java.util.function.Supplier;
@Mod.EventBusSubscriber(value = {Dist.CLIENT}) @Mod.EventBusSubscriber(value = {Dist.CLIENT})
@ParametersAreNonnullByDefault
@MethodsReturnNonnullByDefault
public class ClientProxy implements IProxy { public class ClientProxy implements IProxy {
public static KeyBinding[] keyBindings; public static KeyBinding[] keyBindings;
public static RayTraceResult previousLookAt; public static RayTraceResult previousLookAt;
public static RayTraceResult currentLookAt; public static RayTraceResult currentLookAt;
public static int ticksInGame = 0;
private static int placeCooldown = 0; private static int placeCooldown = 0;
private static int breakCooldown = 0; private static int breakCooldown = 0;
private static boolean shadersInitialized = false; private static boolean shadersInitialized = false;
public static int ticksInGame = 0;
@Override @Override
public void setup(FMLCommonSetupEvent event) {} public void setup(FMLCommonSetupEvent event) {
}
@Override @Override
public void clientSetup(FMLClientSetupEvent event) { public void clientSetup(FMLClientSetupEvent event) {
//Crashes in 1.13, do it elsewhere
// ShaderHandler.init();
// register key bindings // register key bindings
keyBindings = new KeyBinding[7]; keyBindings = new KeyBinding[6];
// instantiate the key bindings // instantiate the key bindings
keyBindings[0] = new KeyBinding("key.effortlessbuilding.hud.desc", KeyConflictContext.UNIVERSAL, InputMappings.getInputByCode(GLFW.GLFW_KEY_KP_ADD, 0), "key.effortlessbuilding.category"); keyBindings[0] = new KeyBinding("key.effortlessbuilding.hud.desc", KeyConflictContext.UNIVERSAL, InputMappings.getKey(GLFW.GLFW_KEY_KP_ADD, 0), "key.effortlessbuilding.category");
keyBindings[1] = new KeyBinding("key.effortlessbuilding.replace.desc", KeyConflictContext.IN_GAME, InputMappings.getInputByCode(GLFW.GLFW_KEY_KP_SUBTRACT, 0), "key.effortlessbuilding.category"); keyBindings[1] = new KeyBinding("key.effortlessbuilding.replace.desc", KeyConflictContext.IN_GAME, InputMappings.getKey(GLFW.GLFW_KEY_KP_SUBTRACT, 0), "key.effortlessbuilding.category");
keyBindings[2] = new KeyBinding("key.effortlessbuilding.creative.desc", KeyConflictContext.IN_GAME, InputMappings.getInputByCode(GLFW.GLFW_KEY_F4, 0), "key.effortlessbuilding.category"); keyBindings[2] = new KeyBinding("key.effortlessbuilding.mode.desc", KeyConflictContext.IN_GAME, InputMappings.getKey(GLFW.GLFW_KEY_LEFT_ALT, 0), "key.effortlessbuilding.category");
keyBindings[3] = new KeyBinding("key.effortlessbuilding.mode.desc", KeyConflictContext.IN_GAME, InputMappings.getInputByCode(GLFW.GLFW_KEY_LEFT_ALT, 0), "key.effortlessbuilding.category") { keyBindings[3] = new KeyBinding("key.effortlessbuilding.undo.desc", KeyConflictContext.IN_GAME, KeyModifier.CONTROL, InputMappings.getKey(GLFW.GLFW_KEY_Z, 0), "key.effortlessbuilding.category");
@Override keyBindings[4] = new KeyBinding("key.effortlessbuilding.redo.desc", KeyConflictContext.IN_GAME, KeyModifier.CONTROL, InputMappings.getKey(GLFW.GLFW_KEY_Y, 0), "key.effortlessbuilding.category");
public boolean conflicts(KeyBinding other) { keyBindings[5] = new KeyBinding("key.effortlessbuilding.altplacement.desc", KeyConflictContext.IN_GAME, InputMappings.getKey(GLFW.GLFW_KEY_LEFT_CONTROL, 0), "key.effortlessbuilding.category");
//Does not conflict with Chisels and Bits radial menu
if (other.getKey().getKeyCode() == getKey().getKeyCode() && other.getKeyDescription().equals("mod.chiselsandbits.other.mode")) return false;
return super.conflicts(other);
}
};
keyBindings[4] = new KeyBinding("key.effortlessbuilding.undo.desc", KeyConflictContext.IN_GAME, KeyModifier.CONTROL, InputMappings.getInputByCode(GLFW.GLFW_KEY_Z, 0), "key.effortlessbuilding.category");
keyBindings[5] = new KeyBinding("key.effortlessbuilding.redo.desc", KeyConflictContext.IN_GAME, KeyModifier.CONTROL, InputMappings.getInputByCode(GLFW.GLFW_KEY_Y, 0), "key.effortlessbuilding.category");
keyBindings[6] = new KeyBinding("key.effortlessbuilding.altplacement.desc", KeyConflictContext.IN_GAME, InputMappings.getInputByCode(GLFW.GLFW_KEY_LEFT_CONTROL, 0), "key.effortlessbuilding.category");
//keyBindings[7] = new KeyBinding("Reload shaders", KeyConflictContext.UNIVERSAL, InputMappings.getInputByCode(GLFW.GLFW_KEY_TAB, 0), "key.effortlessbuilding.category");
// register all the key bindings // register all the key bindings
for (int i = 0; i < keyBindings.length; ++i) { for (KeyBinding keyBinding : keyBindings) {
ClientRegistry.registerKeyBinding(keyBindings[i]); ClientRegistry.registerKeyBinding(keyBinding);
} }
DeferredWorkQueue.runLater( () -> ScreenManager.registerFactory(EffortlessBuilding.RANDOMIZER_BAG_CONTAINER, RandomizerBagScreen::new)); ScreenManager.register(EffortlessBuilding.RANDOMIZER_BAG_CONTAINER.get(), RandomizerBagScreen::new);
} ScreenManager.register(EffortlessBuilding.GOLDEN_RANDOMIZER_BAG_CONTAINER.get(), GoldenRandomizerBagScreen::new);
ScreenManager.register(EffortlessBuilding.DIAMOND_RANDOMIZER_BAG_CONTAINER.get(), DiamondRandomizerBagScreen::new);
public PlayerEntity getPlayerEntityFromContext(Supplier<NetworkEvent.Context> ctx){
return (ctx.get().getDirection().getReceptionSide() == LogicalSide.CLIENT ? Minecraft.getInstance().player : ctx.get().getSender());
} }
@SubscribeEvent @SubscribeEvent
@@ -110,7 +102,7 @@ public class ClientProxy implements IProxy {
onMouseInput(); onMouseInput();
//Update previousLookAt //Update previousLookAt
RayTraceResult objectMouseOver = Minecraft.getInstance().objectMouseOver; RayTraceResult objectMouseOver = Minecraft.getInstance().hitResult;
//Checking for null is necessary! Even in vanilla when looking down ladders it is occasionally null (instead of Type MISS) //Checking for null is necessary! Even in vanilla when looking down ladders it is occasionally null (instead of Type MISS)
if (objectMouseOver == null) return; if (objectMouseOver == null) return;
@@ -125,16 +117,16 @@ public class ClientProxy implements IProxy {
currentLookAt = objectMouseOver; currentLookAt = objectMouseOver;
previousLookAt = objectMouseOver; previousLookAt = objectMouseOver;
} else { } else {
if (((BlockRayTraceResult) currentLookAt).getPos() != ((BlockRayTraceResult) objectMouseOver).getPos()) { if (((BlockRayTraceResult) currentLookAt).getBlockPos() != ((BlockRayTraceResult) objectMouseOver).getBlockPos()) {
previousLookAt = currentLookAt; previousLookAt = currentLookAt;
currentLookAt = objectMouseOver; currentLookAt = objectMouseOver;
} }
} }
} }
} else if (event.phase == TickEvent.Phase.END){ } else if (event.phase == TickEvent.Phase.END) {
Screen gui = Minecraft.getInstance().currentScreen; Screen gui = Minecraft.getInstance().screen;
if(gui == null || !gui.isPauseScreen()) { if (gui == null || !gui.isPauseScreen()) {
ticksInGame++; ticksInGame++;
} }
@@ -153,22 +145,22 @@ public class ClientProxy implements IProxy {
if (player == null) return; if (player == null) return;
BuildModes.BuildModeEnum buildMode = ModeSettingsManager.getModeSettings(player).getBuildMode(); BuildModes.BuildModeEnum buildMode = ModeSettingsManager.getModeSettings(player).getBuildMode();
if (Minecraft.getInstance().currentScreen != null || if (Minecraft.getInstance().screen != null ||
buildMode == BuildModes.BuildModeEnum.NORMAL || buildMode == BuildModes.BuildModeEnum.NORMAL ||
RadialMenu.instance.isVisible()) { RadialMenu.instance.isVisible()) {
return; return;
} }
if (mc.gameSettings.keyBindUseItem.isKeyDown()) { if (mc.options.keyUse.isDown()) {
//KeyBinding.setKeyBindState(mc.gameSettings.keyBindUseItem.getKeyCode(), false); //KeyBinding.setKeyBindState(mc.gameSettings.keyBindUseItem.getKeyCode(), false);
if (placeCooldown <= 0) { if (placeCooldown <= 0) {
placeCooldown = 4; placeCooldown = 4;
ItemStack currentItemStack = player.getHeldItem(Hand.MAIN_HAND); ItemStack currentItemStack = player.getItemInHand(Hand.MAIN_HAND);
if (currentItemStack.getItem() instanceof BlockItem || if (currentItemStack.getItem() instanceof BlockItem ||
(CompatHelper.isItemBlockProxy(currentItemStack) && !player.isSneaking())) { (CompatHelper.isItemBlockProxy(currentItemStack) && !player.isShiftKeyDown())) {
ItemStack itemStack = CompatHelper.getItemBlockFromStack(currentItemStack); ItemStack itemStack = CompatHelper.getItemBlockFromStack(currentItemStack);
@@ -181,23 +173,22 @@ public class ClientProxy implements IProxy {
PacketHandler.INSTANCE.sendToServer(new BlockPlacedMessage(blockLookingAt, true)); PacketHandler.INSTANCE.sendToServer(new BlockPlacedMessage(blockLookingAt, true));
//play sound if further than normal //play sound if further than normal
if ((blockLookingAt.getHitVec().subtract(player.getEyePosition(1f))).lengthSquared() > 25f && if ((blockLookingAt.getLocation().subtract(player.getEyePosition(1f))).lengthSqr() > 25f &&
itemStack.getItem() instanceof BlockItem) { itemStack.getItem() instanceof BlockItem) {
BlockState state = ((BlockItem) itemStack.getItem()).getBlock().getDefaultState(); BlockState state = ((BlockItem) itemStack.getItem()).getBlock().defaultBlockState();
BlockPos blockPos = blockLookingAt.getPos(); BlockPos blockPos = blockLookingAt.getBlockPos();
SoundType soundType = state.getBlock().getSoundType(state, player.world, blockPos, player); SoundType soundType = state.getBlock().getSoundType(state, player.level, blockPos, player);
player.world.playSound(player, player.getPosition(), soundType.getPlaceSound(), SoundCategory.BLOCKS, player.level.playSound(player, player.blockPosition(), soundType.getPlaceSound(), SoundCategory.BLOCKS,
0.4f, soundType.getPitch() * 1f); 0.4f, soundType.getPitch());
player.swingArm(Hand.MAIN_HAND); player.swing(Hand.MAIN_HAND);
} }
} else { } else {
BuildModes.onBlockPlacedMessage(player, new BlockPlacedMessage()); BuildModes.onBlockPlacedMessage(player, new BlockPlacedMessage());
PacketHandler.INSTANCE.sendToServer(new BlockPlacedMessage()); PacketHandler.INSTANCE.sendToServer(new BlockPlacedMessage());
} }
} }
} } else if (buildMode == BuildModes.BuildModeEnum.NORMAL_PLUS) {
else if (buildMode == BuildModes.BuildModeEnum.NORMAL_PLUS) {
placeCooldown--; placeCooldown--;
if (ModeOptions.getBuildSpeed() == ModeOptions.ActionEnum.FAST_SPEED) placeCooldown = 0; if (ModeOptions.getBuildSpeed() == ModeOptions.ActionEnum.FAST_SPEED) placeCooldown = 0;
} }
@@ -205,7 +196,7 @@ public class ClientProxy implements IProxy {
placeCooldown = 0; placeCooldown = 0;
} }
if (mc.gameSettings.keyBindAttack.isKeyDown()) { if (mc.options.keyAttack.isDown()) {
//Break block in distance in creative (or survival if enabled in config) //Break block in distance in creative (or survival if enabled in config)
if (breakCooldown <= 0) { if (breakCooldown <= 0) {
@@ -225,21 +216,20 @@ public class ClientProxy implements IProxy {
PacketHandler.INSTANCE.sendToServer(new BlockBrokenMessage(blockLookingAt)); PacketHandler.INSTANCE.sendToServer(new BlockBrokenMessage(blockLookingAt));
//play sound if further than normal //play sound if further than normal
if ((blockLookingAt.getHitVec().subtract(player.getEyePosition(1f))).lengthSquared() > 25f) { if ((blockLookingAt.getLocation().subtract(player.getEyePosition(1f))).lengthSqr() > 25f) {
BlockPos blockPos = blockLookingAt.getPos(); BlockPos blockPos = blockLookingAt.getBlockPos();
BlockState state = player.world.getBlockState(blockPos); BlockState state = player.level.getBlockState(blockPos);
SoundType soundtype = state.getBlock().getSoundType(state, player.world, blockPos, player); SoundType soundtype = state.getBlock().getSoundType(state, player.level, blockPos, player);
player.world.playSound(player, player.getPosition(), soundtype.getBreakSound(), SoundCategory.BLOCKS, player.level.playSound(player, player.blockPosition(), soundtype.getBreakSound(), SoundCategory.BLOCKS,
0.4f, soundtype.getPitch() * 1f); 0.4f, soundtype.getPitch());
player.swingArm(Hand.MAIN_HAND); player.swing(Hand.MAIN_HAND);
} }
} else { } else {
BuildModes.onBlockBrokenMessage(player, new BlockBrokenMessage()); BuildModes.onBlockBrokenMessage(player, new BlockBrokenMessage());
PacketHandler.INSTANCE.sendToServer(new BlockBrokenMessage()); PacketHandler.INSTANCE.sendToServer(new BlockBrokenMessage());
} }
} } else if (buildMode == BuildModes.BuildModeEnum.NORMAL_PLUS) {
else if (buildMode == BuildModes.BuildModeEnum.NORMAL_PLUS) {
breakCooldown--; breakCooldown--;
if (ModeOptions.getBuildSpeed() == ModeOptions.ActionEnum.FAST_SPEED) breakCooldown = 0; if (ModeOptions.getBuildSpeed() == ModeOptions.ActionEnum.FAST_SPEED) breakCooldown = 0;
} }
@@ -254,15 +244,17 @@ public class ClientProxy implements IProxy {
@SubscribeEvent(receiveCanceled = true) @SubscribeEvent(receiveCanceled = true)
public static void onKeyPress(InputEvent.KeyInputEvent event) { public static void onKeyPress(InputEvent.KeyInputEvent event) {
ClientPlayerEntity player = Minecraft.getInstance().player; ClientPlayerEntity player = Minecraft.getInstance().player;
if (player == null)
return;
//Remember to send packet to server if necessary //Remember to send packet to server if necessary
//Show Modifier Settings GUI //Show Modifier Settings GUI
if (keyBindings[0].isPressed()) { if (keyBindings[0].consumeClick()) {
openModifierSettings(); openModifierSettings();
} }
//QuickReplace toggle //QuickReplace toggle
if (keyBindings[1].isPressed()) { if (keyBindings[1].consumeClick()) {
ModifierSettingsManager.ModifierSettings modifierSettings = ModifierSettingsManager.getModifierSettings(player); ModifierSettingsManager.ModifierSettings modifierSettings = ModifierSettingsManager.getModifierSettings(player);
modifierSettings.setQuickReplace(!modifierSettings.doQuickReplace()); modifierSettings.setQuickReplace(!modifierSettings.doQuickReplace());
EffortlessBuilding.log(player, "Set " + TextFormatting.GOLD + "Quick Replace " + TextFormatting.RESET + ( EffortlessBuilding.log(player, "Set " + TextFormatting.GOLD + "Quick Replace " + TextFormatting.RESET + (
@@ -270,31 +262,33 @@ public class ClientProxy implements IProxy {
PacketHandler.INSTANCE.sendToServer(new ModifierSettingsMessage(modifierSettings)); PacketHandler.INSTANCE.sendToServer(new ModifierSettingsMessage(modifierSettings));
} }
//Creative/survival mode toggle //Radial menu
if (keyBindings[2].isPressed()) { if (keyBindings[2].isDown()) {
if (player.isCreative()) { if (ReachHelper.getMaxReach(player) > 0) {
player.sendChatMessage("/gamemode survival"); if (!RadialMenu.instance.isVisible()) {
Minecraft.getInstance().setScreen(RadialMenu.instance);
}
} else { } else {
player.sendChatMessage("/gamemode creative"); EffortlessBuilding.log(player, "Build modes are disabled until your reach has increased. Increase your reach with craftable reach upgrades.");
} }
} }
//Undo (Ctrl+Z) //Undo (Ctrl+Z)
if (keyBindings[4].isPressed()) { if (keyBindings[3].consumeClick()) {
ModeOptions.ActionEnum action = ModeOptions.ActionEnum.UNDO; ModeOptions.ActionEnum action = ModeOptions.ActionEnum.UNDO;
ModeOptions.performAction(player, action); ModeOptions.performAction(player, action);
PacketHandler.INSTANCE.sendToServer(new ModeActionMessage(action)); PacketHandler.INSTANCE.sendToServer(new ModeActionMessage(action));
} }
//Redo (Ctrl+Y) //Redo (Ctrl+Y)
if (keyBindings[5].isPressed()) { if (keyBindings[4].consumeClick()) {
ModeOptions.ActionEnum action = ModeOptions.ActionEnum.REDO; ModeOptions.ActionEnum action = ModeOptions.ActionEnum.REDO;
ModeOptions.performAction(player, action); ModeOptions.performAction(player, action);
PacketHandler.INSTANCE.sendToServer(new ModeActionMessage(action)); PacketHandler.INSTANCE.sendToServer(new ModeActionMessage(action));
} }
//Change placement mode //Change placement mode
if (keyBindings[6].isPressed()) { if (keyBindings[5].consumeClick()) {
//Toggle between first two actions of the first option of the current build mode //Toggle between first two actions of the first option of the current build mode
BuildModes.BuildModeEnum currentBuildMode = ModeSettingsManager.getModeSettings(player).getBuildMode(); BuildModes.BuildModeEnum currentBuildMode = ModeSettingsManager.getModeSettings(player).getBuildMode();
if (currentBuildMode.options.length > 0) { if (currentBuildMode.options.length > 0) {
@@ -310,31 +304,24 @@ public class ClientProxy implements IProxy {
} }
} }
} }
//For shader development
if (keyBindings.length >= 8 && keyBindings[7].isPressed()) {
ShaderHandler.init();
EffortlessBuilding.log(player, "Reloaded shaders");
}
} }
public static void openModifierSettings() { public static void openModifierSettings() {
Minecraft mc = Minecraft.getInstance(); Minecraft mc = Minecraft.getInstance();
ClientPlayerEntity player = mc.player; PlayerEntity player = mc.player;
if (player == null) return;
RadialMenu.instance.setVisibility(0f);
//Disabled if max reach is 0, might be set in the config that way. //Disabled if max reach is 0, might be set in the config that way.
if (ReachHelper.getMaxReach(player) == 0) { if (ReachHelper.getMaxReach(player) == 0) {
EffortlessBuilding.log(player, "Build modifiers are disabled until your reach has increased. Increase your reach with craftable reach upgrades."); EffortlessBuilding.log(player, "Build modifiers are disabled until your reach has increased. Increase your reach with craftable reach upgrades.");
} else { } else {
if (mc.currentScreen == null) { mc.setScreen(new ModifierSettingsGui());
mc.displayGuiScreen(new ModifierSettingsGui());
} else {
player.closeScreen();
} }
} }
public static void openPlayerSettings() {
Minecraft mc = Minecraft.getInstance();
mc.setScreen(new PlayerSettingsGui());
} }
@SubscribeEvent @SubscribeEvent
@@ -345,23 +332,32 @@ public class ClientProxy implements IProxy {
} }
} }
@Nullable public static boolean isKeybindDown(int keybindIndex) {
return InputMappings.isKeyDown(
Minecraft.getInstance().getWindow().getWindow(),
ClientProxy.keyBindings[2].getKey().getValue());
}
public static RayTraceResult getLookingAt(PlayerEntity player) { public static RayTraceResult getLookingAt(PlayerEntity player) {
World world = player.world; World world = player.level;
//base distance off of player ability (config) //base distance off of player ability (config)
float raytraceRange = ReachHelper.getPlacementReach(player); float raytraceRange = ReachHelper.getPlacementReach(player);
Vec3d look = player.getLookVec(); Vector3d look = player.getLookAngle();
Vec3d start = new Vec3d(player.posX, player.posY + player.getEyeHeight(), player.posZ); Vector3d start = new Vector3d(player.getX(), player.getY() + player.getEyeHeight(), player.getZ());
Vec3d end = new Vec3d(player.posX + look.x * raytraceRange, player.posY + player.getEyeHeight() + look.y * raytraceRange, player.posZ + look.z * raytraceRange); Vector3d end = new Vector3d(player.getX() + look.x * raytraceRange, player.getY() + player.getEyeHeight() + look.y * raytraceRange, player.getZ() + look.z * raytraceRange);
// return player.rayTrace(raytraceRange, 1f, RayTraceFluidMode.NEVER); // return player.rayTrace(raytraceRange, 1f, RayTraceFluidMode.NEVER);
//TODO 1.14 check if correct //TODO 1.14 check if correct
return world.rayTraceBlocks(new RayTraceContext(start, end, RayTraceContext.BlockMode.COLLIDER, RayTraceContext.FluidMode.NONE, player)); return world.clip(new RayTraceContext(start, end, RayTraceContext.BlockMode.COLLIDER, RayTraceContext.FluidMode.NONE, player));
}
public PlayerEntity getPlayerEntityFromContext(Supplier<NetworkEvent.Context> ctx) {
return (ctx.get().getDirection().getReceptionSide() == LogicalSide.CLIENT ? Minecraft.getInstance().player : ctx.get().getSender());
} }
@Override @Override
public void logTranslate(PlayerEntity player, String prefix, String translationKey, String suffix, boolean actionBar) { public void logTranslate(PlayerEntity player, String prefix, String translationKey, String suffix, boolean actionBar) {
EffortlessBuilding.log(Minecraft.getInstance().player, prefix + I18n.format(translationKey) + suffix, actionBar); EffortlessBuilding.log(Minecraft.getInstance().player, prefix + I18n.get(translationKey) + suffix, actionBar);
} }
} }

View File

@@ -19,9 +19,10 @@ public class ServerProxy implements IProxy {
} }
@Override @Override
public void clientSetup(FMLClientSetupEvent event) {} public void clientSetup(FMLClientSetupEvent event) {
}
public PlayerEntity getPlayerEntityFromContext(Supplier<NetworkEvent.Context> ctx){ public PlayerEntity getPlayerEntityFromContext(Supplier<NetworkEvent.Context> ctx) {
return ctx.get().getSender(); return ctx.get().getSender();
} }

View File

@@ -1,18 +1,23 @@
package nl.requios.effortlessbuilding.render; package nl.requios.effortlessbuilding.render;
import com.mojang.blaze3d.platform.GlStateManager; import com.mojang.blaze3d.matrix.MatrixStack;
import com.mojang.blaze3d.vertex.IVertexBuilder;
import net.minecraft.block.BlockState; import net.minecraft.block.BlockState;
import net.minecraft.block.SoundType; import net.minecraft.block.SoundType;
import net.minecraft.client.Minecraft; import net.minecraft.client.Minecraft;
import net.minecraft.client.entity.player.ClientPlayerEntity; import net.minecraft.client.entity.player.ClientPlayerEntity;
import net.minecraft.client.renderer.BlockRendererDispatcher; import net.minecraft.client.renderer.BlockRendererDispatcher;
import net.minecraft.client.renderer.texture.AtlasTexture; import net.minecraft.client.renderer.IRenderTypeBuffer;
import net.minecraft.entity.player.PlayerEntity; import net.minecraft.entity.player.PlayerEntity;
import net.minecraft.item.ItemStack; import net.minecraft.item.ItemStack;
import net.minecraft.util.Direction; import net.minecraft.util.Direction;
import net.minecraft.util.SoundCategory; import net.minecraft.util.SoundCategory;
import net.minecraft.util.math.*; import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.BlockRayTraceResult;
import net.minecraft.util.math.MathHelper;
import net.minecraft.util.math.RayTraceResult;
import net.minecraft.util.math.shapes.VoxelShape; import net.minecraft.util.math.shapes.VoxelShape;
import net.minecraft.util.math.vector.Vector3d;
import net.minecraftforge.api.distmarker.Dist; import net.minecraftforge.api.distmarker.Dist;
import net.minecraftforge.api.distmarker.OnlyIn; import net.minecraftforge.api.distmarker.OnlyIn;
import nl.requios.effortlessbuilding.BuildConfig; import nl.requios.effortlessbuilding.BuildConfig;
@@ -27,17 +32,16 @@ import nl.requios.effortlessbuilding.buildmodifier.ModifierSettingsManager.Modif
import nl.requios.effortlessbuilding.compatibility.CompatHelper; import nl.requios.effortlessbuilding.compatibility.CompatHelper;
import nl.requios.effortlessbuilding.helper.ReachHelper; import nl.requios.effortlessbuilding.helper.ReachHelper;
import nl.requios.effortlessbuilding.helper.SurvivalHelper; import nl.requios.effortlessbuilding.helper.SurvivalHelper;
import nl.requios.effortlessbuilding.item.ItemRandomizerBag; import nl.requios.effortlessbuilding.item.RandomizerBagItem;
import nl.requios.effortlessbuilding.proxy.ClientProxy; import nl.requios.effortlessbuilding.proxy.ClientProxy;
import org.lwjgl.opengl.*;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Collections; import java.util.Collections;
import java.util.List; import java.util.List;
import java.util.function.Consumer;
@OnlyIn(Dist.CLIENT) @OnlyIn(Dist.CLIENT)
public class BlockPreviewRenderer { public class BlockPreviewRenderer {
private static final List<PlacedData> placedDataList = new ArrayList<>();
private static List<BlockPos> previousCoordinates; private static List<BlockPos> previousCoordinates;
private static List<BlockState> previousBlockStates; private static List<BlockState> previousBlockStates;
private static List<ItemStack> previousItemStacks; private static List<ItemStack> previousItemStacks;
@@ -45,86 +49,59 @@ public class BlockPreviewRenderer {
private static BlockPos previousSecondPos; private static BlockPos previousSecondPos;
private static int soundTime = 0; private static int soundTime = 0;
static class PlacedData { public static void render(MatrixStack matrixStack, IRenderTypeBuffer.Impl renderTypeBuffer, PlayerEntity player, ModifierSettings modifierSettings, ModeSettings modeSettings) {
float time;
List<BlockPos> coordinates;
List<BlockState> blockStates;
List<ItemStack> itemStacks;
BlockPos firstPos;
BlockPos secondPos;
boolean breaking;
public PlacedData(float time, List<BlockPos> coordinates, List<BlockState> blockStates,
List<ItemStack> itemStacks, BlockPos firstPos, BlockPos secondPos, boolean breaking) {
this.time = time;
this.coordinates = coordinates;
this.blockStates = blockStates;
this.itemStacks = itemStacks;
this.firstPos = firstPos;
this.secondPos = secondPos;
this.breaking = breaking;
}
}
private static List<PlacedData> placedDataList = new ArrayList<>();
private static final int primaryTextureUnit = 0;
private static final int secondaryTextureUnit = 2;
public static void render(PlayerEntity player, ModifierSettings modifierSettings, ModeSettings modeSettings) {
//Render placed blocks with dissolve effect //Render placed blocks with dissolve effect
//Use fancy shader if config allows, otherwise no dissolve //Use fancy shader if config allows, otherwise no dissolve
if (BuildConfig.visuals.useShaders.get()) { if (BuildConfig.visuals.useShaders.get()) {
RenderHandler.beginBlockPreviews();
for (int i = 0; i < placedDataList.size(); i++) { for (int i = 0; i < placedDataList.size(); i++) {
PlacedData placed = placedDataList.get(i); PlacedData placed = placedDataList.get(i);
if (placed.coordinates != null && !placed.coordinates.isEmpty()) { if (placed.coordinates != null && !placed.coordinates.isEmpty()) {
double totalTime = MathHelper.clampedLerp(30, 60, placed.firstPos.distanceSq(placed.secondPos) / 100.0) * BuildConfig.visuals.dissolveTimeMultiplier.get(); double totalTime = MathHelper.clampedLerp(30, 60, placed.firstPos.distSqr(placed.secondPos) / 100.0) * BuildConfig.visuals.dissolveTimeMultiplier.get();
float dissolve = (ClientProxy.ticksInGame - placed.time) / (float) totalTime; float dissolve = (ClientProxy.ticksInGame - placed.time) / (float) totalTime;
renderBlockPreviews(placed.coordinates, placed.blockStates, placed.itemStacks, dissolve, placed.firstPos, placed.secondPos, false, placed.breaking); renderBlockPreviews(matrixStack, renderTypeBuffer, placed.coordinates, placed.blockStates, placed.itemStacks, dissolve, placed.firstPos, placed.secondPos, false, placed.breaking);
} }
} }
RenderHandler.endBlockPreviews();
} }
//Expire //Expire
placedDataList.removeIf(placed -> { placedDataList.removeIf(placed -> {
double totalTime = MathHelper.clampedLerp(30, 60, placed.firstPos.distanceSq(placed.secondPos) / 100.0) * BuildConfig.visuals.dissolveTimeMultiplier.get(); double totalTime = MathHelper.clampedLerp(30, 60, placed.firstPos.distSqr(placed.secondPos) / 100.0) * BuildConfig.visuals.dissolveTimeMultiplier.get();
return placed.time + totalTime < ClientProxy.ticksInGame; return placed.time + totalTime < ClientProxy.ticksInGame;
}); });
//Render block previews //Render block previews
RayTraceResult lookingAt = ClientProxy.getLookingAt(player); RayTraceResult lookingAt = ClientProxy.getLookingAt(player);
if (modeSettings.getBuildMode() == BuildModes.BuildModeEnum.NORMAL) lookingAt = Minecraft.getInstance().objectMouseOver; if (modeSettings.getBuildMode() == BuildModes.BuildModeEnum.NORMAL)
lookingAt = Minecraft.getInstance().hitResult;
ItemStack mainhand = player.getHeldItemMainhand(); ItemStack mainhand = player.getMainHandItem();
boolean toolInHand = !(!mainhand.isEmpty() && CompatHelper.isItemBlockProxy(mainhand)); boolean toolInHand = !(!mainhand.isEmpty() && CompatHelper.isItemBlockProxy(mainhand));
BlockPos startPos = null; BlockPos startPos = null;
Direction sideHit = null; Direction sideHit = null;
Vec3d hitVec = null; Vector3d hitVec = null;
//Checking for null is necessary! Even in vanilla when looking down ladders it is occasionally null (instead of Type MISS) //Checking for null is necessary! Even in vanilla when looking down ladders it is occasionally null (instead of Type MISS)
if (lookingAt != null && lookingAt.getType() == RayTraceResult.Type.BLOCK) { if (lookingAt != null && lookingAt.getType() == RayTraceResult.Type.BLOCK) {
BlockRayTraceResult blockLookingAt = (BlockRayTraceResult) lookingAt; BlockRayTraceResult blockLookingAt = (BlockRayTraceResult) lookingAt;
startPos = blockLookingAt.getPos(); startPos = blockLookingAt.getBlockPos();
//Check if tool (or none) in hand //Check if tool (or none) in hand
//TODO 1.13 replaceable //TODO 1.13 replaceable
boolean replaceable = player.world.getBlockState(startPos).getBlock().getMaterial(player.world.getBlockState(startPos)).isReplaceable(); boolean replaceable = player.level.getBlockState(startPos).getMaterial().isReplaceable();
boolean becomesDoubleSlab = SurvivalHelper.doesBecomeDoubleSlab(player, startPos, blockLookingAt.getFace()); boolean becomesDoubleSlab = SurvivalHelper.doesBecomeDoubleSlab(player, startPos, blockLookingAt.getDirection());
if (!modifierSettings.doQuickReplace() && !toolInHand && !replaceable && !becomesDoubleSlab) { if (!modifierSettings.doQuickReplace() && !toolInHand && !replaceable && !becomesDoubleSlab) {
startPos = startPos.offset(blockLookingAt.getFace()); startPos = startPos.relative(blockLookingAt.getDirection());
} }
//Get under tall grass and other replaceable blocks //Get under tall grass and other replaceable blocks
if (modifierSettings.doQuickReplace() && !toolInHand && replaceable) { if (modifierSettings.doQuickReplace() && !toolInHand && replaceable) {
startPos = startPos.down(); startPos = startPos.below();
} }
sideHit = blockLookingAt.getFace(); sideHit = blockLookingAt.getDirection();
hitVec = blockLookingAt.getHitVec(); hitVec = blockLookingAt.getLocation();
} }
//Dont render if in normal mode and modifiers are disabled //Dont render if in normal mode and modifiers are disabled
@@ -164,7 +141,7 @@ public class BlockPreviewRenderer {
sortOnDistanceToPlayer(newCoordinates, player); sortOnDistanceToPlayer(newCoordinates, player);
hitVec = new Vec3d(Math.abs(hitVec.x - ((int) hitVec.x)), Math.abs(hitVec.y - ((int) hitVec.y)), hitVec = new Vector3d(Math.abs(hitVec.x - ((int) hitVec.x)), Math.abs(hitVec.y - ((int) hitVec.y)),
Math.abs(hitVec.z - ((int) hitVec.z))); Math.abs(hitVec.z - ((int) hitVec.z)));
//Get blockstates //Get blockstates
@@ -173,7 +150,7 @@ public class BlockPreviewRenderer {
if (breaking) { if (breaking) {
//Find blockstate of world //Find blockstate of world
for (BlockPos coordinate : newCoordinates) { for (BlockPos coordinate : newCoordinates) {
blockStates.add(player.world.getBlockState(coordinate)); blockStates.add(player.level.getBlockState(coordinate));
} }
} else { } else {
blockStates = BuildModifiers.findBlockStates(player, startCoordinates, hitVec, sideHit, itemStacks); blockStates = BuildModifiers.findBlockStates(player, startCoordinates, hitVec, sideHit, itemStacks);
@@ -191,15 +168,15 @@ public class BlockPreviewRenderer {
previousSecondPos = secondPos; previousSecondPos = secondPos;
//if so, renew randomness of randomizer bag //if so, renew randomness of randomizer bag
ItemRandomizerBag.renewRandomness(); RandomizerBagItem.renewRandomness();
//and play sound (max once every tick) //and play sound (max once every tick)
if (newCoordinates.size() > 1 && blockStates.size() > 1 && soundTime < ClientProxy.ticksInGame - 0) { if (newCoordinates.size() > 1 && blockStates.size() > 1 && soundTime < ClientProxy.ticksInGame - 0) {
soundTime = ClientProxy.ticksInGame; soundTime = ClientProxy.ticksInGame;
if (blockStates.get(0) != null) { if (blockStates.get(0) != null) {
SoundType soundType = blockStates.get(0).getBlock().getSoundType(blockStates.get(0), player.world, SoundType soundType = blockStates.get(0).getBlock().getSoundType(blockStates.get(0), player.level,
newCoordinates.get(0), player); newCoordinates.get(0), player);
player.world.playSound(player, player.getPosition(), breaking ? soundType.getBreakSound() : soundType.getPlaceSound(), player.level.playSound(player, player.blockPosition(), breaking ? soundType.getBreakSound() : soundType.getPlaceSound(),
SoundCategory.BLOCKS, 0.3f, 0.8f); SoundCategory.BLOCKS, 0.3f, 0.8f);
} }
} }
@@ -211,25 +188,19 @@ public class BlockPreviewRenderer {
//Use fancy shader if config allows, otherwise outlines //Use fancy shader if config allows, otherwise outlines
if (BuildConfig.visuals.useShaders.get() && newCoordinates.size() < BuildConfig.visuals.shaderTreshold.get()) { if (BuildConfig.visuals.useShaders.get() && newCoordinates.size() < BuildConfig.visuals.shaderTreshold.get()) {
blockCount = renderBlockPreviews(matrixStack, renderTypeBuffer, newCoordinates, blockStates, itemStacks, 0f, firstPos, secondPos, !breaking, breaking);
RenderHandler.beginBlockPreviews();
blockCount = renderBlockPreviews(newCoordinates, blockStates, itemStacks, 0f, firstPos, secondPos, !breaking, breaking);
RenderHandler.endBlockPreviews();
} else { } else {
IVertexBuilder buffer = RenderHandler.beginLines(renderTypeBuffer);
RenderHandler.beginLines(); Vector3d color = new Vector3d(1f, 1f, 1f);
if (breaking) color = new Vector3d(1f, 0f, 0f);
Vec3d color = new Vec3d(1f, 1f, 1f);
if (breaking) color = new Vec3d(1f, 0f, 0f);
for (int i = newCoordinates.size() - 1; i >= 0; i--) { for (int i = newCoordinates.size() - 1; i >= 0; i--) {
VoxelShape collisionShape = blockStates.get(i).getCollisionShape(player.world, newCoordinates.get(i)); VoxelShape collisionShape = blockStates.get(i).getCollisionShape(player.level, newCoordinates.get(i));
RenderHandler.renderBlockOutline(newCoordinates.get(i), collisionShape, color); RenderHandler.renderBlockOutline(matrixStack, buffer, newCoordinates.get(i), collisionShape, color);
} }
RenderHandler.endLines(); RenderHandler.endLines(renderTypeBuffer);
blockCount = newCoordinates.size(); blockCount = newCoordinates.size();
} }
@@ -265,30 +236,30 @@ public class BlockPreviewRenderer {
} }
RenderHandler.beginLines(); IVertexBuilder buffer = RenderHandler.beginLines(renderTypeBuffer);
//Draw outlines if tool in hand //Draw outlines if tool in hand
//Find proper raytrace: either normal range or increased range depending on canBreakFar //Find proper raytrace: either normal range or increased range depending on canBreakFar
RayTraceResult objectMouseOver = Minecraft.getInstance().objectMouseOver; RayTraceResult objectMouseOver = Minecraft.getInstance().hitResult;
RayTraceResult breakingRaytrace = ReachHelper.canBreakFar(player) ? lookingAt : objectMouseOver; RayTraceResult breakingRaytrace = ReachHelper.canBreakFar(player) ? lookingAt : objectMouseOver;
if (toolInHand && breakingRaytrace != null && breakingRaytrace.getType() == RayTraceResult.Type.BLOCK) { if (toolInHand && breakingRaytrace != null && breakingRaytrace.getType() == RayTraceResult.Type.BLOCK) {
BlockRayTraceResult blockBreakingRaytrace = (BlockRayTraceResult) breakingRaytrace; BlockRayTraceResult blockBreakingRaytrace = (BlockRayTraceResult) breakingRaytrace;
List<BlockPos> breakCoordinates = BuildModifiers.findCoordinates(player, blockBreakingRaytrace.getPos()); List<BlockPos> breakCoordinates = BuildModifiers.findCoordinates(player, blockBreakingRaytrace.getBlockPos());
//Only render first outline if further than normal reach //Only render first outline if further than normal reach
boolean excludeFirst = objectMouseOver != null && objectMouseOver.getType() == RayTraceResult.Type.BLOCK; boolean excludeFirst = objectMouseOver != null && objectMouseOver.getType() == RayTraceResult.Type.BLOCK;
for (int i = excludeFirst ? 1 : 0; i < breakCoordinates.size(); i++) { for (int i = excludeFirst ? 1 : 0; i < breakCoordinates.size(); i++) {
BlockPos coordinate = breakCoordinates.get(i); BlockPos coordinate = breakCoordinates.get(i);
BlockState blockState = player.world.getBlockState(coordinate); BlockState blockState = player.level.getBlockState(coordinate);
if (!blockState.getBlock().isAir(blockState, player.world, coordinate)) { if (!blockState.getBlock().isAir(blockState, player.level, coordinate)) {
if (SurvivalHelper.canBreak(player.world, player, coordinate) || i == 0) { if (SurvivalHelper.canBreak(player.level, player, coordinate) || i == 0) {
VoxelShape collisionShape = blockState.getCollisionShape(player.world, coordinate); VoxelShape collisionShape = blockState.getCollisionShape(player.level, coordinate);
RenderHandler.renderBlockOutline(coordinate, collisionShape, new Vec3d(0f, 0f, 0f)); RenderHandler.renderBlockOutline(matrixStack, buffer, coordinate, collisionShape, new Vector3d(0f, 0f, 0f));
} }
} }
} }
} }
RenderHandler.endLines(); RenderHandler.endLines(renderTypeBuffer);
} }
} }
@@ -299,12 +270,12 @@ public class BlockPreviewRenderer {
BuildConfig.visuals.alwaysShowBlockPreview.get(); BuildConfig.visuals.alwaysShowBlockPreview.get();
} }
protected static int renderBlockPreviews(List<BlockPos> coordinates, List<BlockState> blockStates, protected static int renderBlockPreviews(MatrixStack matrixStack, IRenderTypeBuffer.Impl renderTypeBuffer, List<BlockPos> coordinates, List<BlockState> blockStates,
List<ItemStack> itemStacks, float dissolve, BlockPos firstPos, List<ItemStack> itemStacks, float dissolve, BlockPos firstPos,
BlockPos secondPos, boolean checkCanPlace, boolean red) { BlockPos secondPos, boolean checkCanPlace, boolean red) {
PlayerEntity player = Minecraft.getInstance().player; PlayerEntity player = Minecraft.getInstance().player;
ModifierSettings modifierSettings = ModifierSettingsManager.getModifierSettings(player); ModifierSettings modifierSettings = ModifierSettingsManager.getModifierSettings(player);
BlockRendererDispatcher dispatcher = Minecraft.getInstance().getBlockRendererDispatcher(); BlockRendererDispatcher dispatcher = Minecraft.getInstance().getBlockRenderer();
int blocksValid = 0; int blocksValid = 0;
if (coordinates.isEmpty()) return blocksValid; if (coordinates.isEmpty()) return blocksValid;
@@ -318,13 +289,10 @@ public class BlockPreviewRenderer {
//Check if can place //Check if can place
//If check is turned off, check if blockstate is the same (for dissolve effect) //If check is turned off, check if blockstate is the same (for dissolve effect)
if ((!checkCanPlace /*&& player.world.getNewBlockState(blockPos) == blockState*/) || //TODO enable (breaks breaking shader) if ((!checkCanPlace /*&& player.world.getNewBlockState(blockPos) == blockState*/) || //TODO enable (breaks the breaking shader)
SurvivalHelper.canPlace(player.world, player, blockPos, blockState, itemstack, modifierSettings.doQuickReplace(), Direction.UP)) { SurvivalHelper.canPlace(player.level, player, blockPos, blockState, itemstack, modifierSettings.doQuickReplace(), Direction.UP)) {
ShaderHandler.useShader(ShaderHandler.dissolve, generateShaderCallback(dissolve, RenderHandler.renderBlockPreview(matrixStack, renderTypeBuffer, dispatcher, blockPos, blockState, dissolve, firstPos, secondPos, red);
new Vec3d(blockPos), new Vec3d(firstPos), new Vec3d(secondPos),
blockPos == secondPos, red));
RenderHandler.renderBlockPreview(dispatcher, blockPos, blockState);
blocksValid++; blocksValid++;
} }
} }
@@ -381,64 +349,35 @@ public class BlockPreviewRenderer {
} }
private static Consumer<Integer> generateShaderCallback(final float dissolve, final Vec3d blockpos,
final Vec3d firstpos, final Vec3d secondpos,
final boolean highlight, final boolean red) {
Minecraft mc = Minecraft.getInstance();
return (Integer shader) -> {
int percentileUniform = ARBShaderObjects.glGetUniformLocationARB(shader, "dissolve");
int highlightUniform = ARBShaderObjects.glGetUniformLocationARB(shader, "highlight");
int redUniform = ARBShaderObjects.glGetUniformLocationARB(shader, "red");
int blockposUniform = ARBShaderObjects.glGetUniformLocationARB(shader, "blockpos");
int firstposUniform = ARBShaderObjects.glGetUniformLocationARB(shader, "firstpos");
int secondposUniform = ARBShaderObjects.glGetUniformLocationARB(shader, "secondpos");
int imageUniform = ARBShaderObjects.glGetUniformLocationARB(shader, "image");
int maskUniform = ARBShaderObjects.glGetUniformLocationARB(shader, "mask");
GlStateManager.enableTexture();
GL11.glGetInteger(GL11.GL_TEXTURE_BINDING_2D);
//mask
ARBShaderObjects.glUniform1iARB(maskUniform, secondaryTextureUnit);
glActiveTexture(ARBMultitexture.GL_TEXTURE0_ARB + secondaryTextureUnit);
GL11.glBindTexture(GL11.GL_TEXTURE_2D, mc.getTextureManager().getTexture(ShaderHandler.shaderMaskTextureLocation).getGlTextureId());
//image
ARBShaderObjects.glUniform1iARB(imageUniform, primaryTextureUnit);
glActiveTexture(ARBMultitexture.GL_TEXTURE0_ARB + primaryTextureUnit);
GL11.glBindTexture(GL11.GL_TEXTURE_2D, mc.getTextureManager().getTexture(AtlasTexture.LOCATION_BLOCKS_TEXTURE).getGlTextureId());
//blockpos
ARBShaderObjects.glUniform3fARB(blockposUniform, (float) blockpos.x, (float) blockpos.y, (float) blockpos.z);
ARBShaderObjects.glUniform3fARB(firstposUniform, (float) firstpos.x, (float) firstpos.y, (float) firstpos.z);
ARBShaderObjects.glUniform3fARB(secondposUniform, (float) secondpos.x, (float) secondpos.y, (float) secondpos.z);
//dissolve
ARBShaderObjects.glUniform1fARB(percentileUniform, dissolve);
//highlight
ARBShaderObjects.glUniform1iARB(highlightUniform, highlight ? 1 : 0);
//red
ARBShaderObjects.glUniform1iARB(redUniform, red ? 1 : 0);
};
}
public static void glActiveTexture(int texture) {
if (GL.getCapabilities().GL_ARB_multitexture && !GL.getCapabilities().OpenGL13) {
ARBMultitexture.glActiveTextureARB(texture);
} else {
GL13.glActiveTexture(texture);
}
}
private static void sortOnDistanceToPlayer(List<BlockPos> coordinates, PlayerEntity player) { private static void sortOnDistanceToPlayer(List<BlockPos> coordinates, PlayerEntity player) {
Collections.sort(coordinates, (lhs, rhs) -> { Collections.sort(coordinates, (lhs, rhs) -> {
// -1 - less than, 1 - greater than, 0 - equal // -1 - less than, 1 - greater than, 0 - equal
double lhsDistanceToPlayer = new Vec3d(lhs).subtract(player.getEyePosition(1f)).lengthSquared(); double lhsDistanceToPlayer = Vector3d.atLowerCornerOf(lhs).subtract(player.getEyePosition(1f)).lengthSqr();
double rhsDistanceToPlayer = new Vec3d(rhs).subtract(player.getEyePosition(1f)).lengthSquared(); double rhsDistanceToPlayer = Vector3d.atLowerCornerOf(rhs).subtract(player.getEyePosition(1f)).lengthSqr();
return (int) Math.signum(lhsDistanceToPlayer - rhsDistanceToPlayer); return (int) Math.signum(lhsDistanceToPlayer - rhsDistanceToPlayer);
}); });
} }
static class PlacedData {
float time;
List<BlockPos> coordinates;
List<BlockState> blockStates;
List<ItemStack> itemStacks;
BlockPos firstPos;
BlockPos secondPos;
boolean breaking;
public PlacedData(float time, List<BlockPos> coordinates, List<BlockState> blockStates,
List<ItemStack> itemStacks, BlockPos firstPos, BlockPos secondPos, boolean breaking) {
this.time = time;
this.coordinates = coordinates;
this.blockStates = blockStates;
this.itemStacks = itemStacks;
this.firstPos = firstPos;
this.secondPos = secondPos;
this.breaking = breaking;
}
}
} }

View File

@@ -0,0 +1,172 @@
package nl.requios.effortlessbuilding.render;
import com.mojang.blaze3d.systems.RenderSystem;
import net.minecraft.client.Minecraft;
import net.minecraft.client.renderer.RenderState;
import net.minecraft.client.renderer.RenderType;
import net.minecraft.client.renderer.texture.AtlasTexture;
import net.minecraft.client.renderer.vertex.DefaultVertexFormats;
import net.minecraft.client.renderer.vertex.VertexFormat;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.vector.Vector3d;
import net.minecraftforge.fml.common.ObfuscationReflectionHelper;
import org.lwjgl.opengl.*;
import java.util.OptionalDouble;
import java.util.function.Consumer;
public class BuildRenderTypes extends RenderType {
public static final RenderType LINES;
public static final RenderType PLANES;
private static final int primaryTextureUnit = 0;
private static final int secondaryTextureUnit = 2;
static {
final LineState LINE = new LineState(OptionalDouble.of(2.0));
final int INITIAL_BUFFER_SIZE = 128;
RenderType.State renderState;
//LINES
renderState = State.builder()
.setLineState(LINE)
.setLayeringState(VIEW_OFFSET_Z_LAYERING)
.setTransparencyState(TRANSLUCENT_TRANSPARENCY)
.setTextureState(NO_TEXTURE)
.setDepthTestState(NO_DEPTH_TEST)
.setLightmapState(NO_LIGHTMAP)
.setWriteMaskState(COLOR_DEPTH_WRITE)
.setCullState(NO_CULL)
.createCompositeState(false);
LINES = RenderType.create("eb_lines",
DefaultVertexFormats.POSITION_COLOR, GL11.GL_LINES, INITIAL_BUFFER_SIZE, false, false, renderState);
//PLANES
renderState = State.builder()
.setLineState(LINE)
.setLayeringState(VIEW_OFFSET_Z_LAYERING)
.setTransparencyState(TRANSLUCENT_TRANSPARENCY)
.setTextureState(NO_TEXTURE)
.setDepthTestState(NO_DEPTH_TEST)
.setLightmapState(NO_LIGHTMAP)
.setWriteMaskState(COLOR_WRITE)
.setCullState(NO_CULL)
.createCompositeState(false);
PLANES = RenderType.create("eb_planes",
DefaultVertexFormats.POSITION_COLOR, GL11.GL_TRIANGLE_STRIP, INITIAL_BUFFER_SIZE, false, false, renderState);
}
// Dummy constructor needed to make java happy
public BuildRenderTypes(String p_i225992_1_, VertexFormat p_i225992_2_, int p_i225992_3_, int p_i225992_4_, boolean p_i225992_5_, boolean p_i225992_6_, Runnable p_i225992_7_, Runnable p_i225992_8_) {
super(p_i225992_1_, p_i225992_2_, p_i225992_3_, p_i225992_4_, p_i225992_5_, p_i225992_6_, p_i225992_7_, p_i225992_8_);
}
public static RenderType getBlockPreviewRenderType(float dissolve, BlockPos blockPos, BlockPos firstPos,
BlockPos secondPos, boolean red) {
// RenderSystem.pushLightingAttributes();
// RenderSystem.pushTextureAttributes();
// RenderSystem.enableCull();
// RenderSystem.enableTexture();
// Minecraft.getInstance().textureManager.bindTexture(ShaderHandler.shaderMaskTextureLocation);
//
// RenderSystem.enableBlend();
// RenderSystem.blendFunc(GL11.GL_SRC_ALPHA, GL11.GL_ONE_MINUS_SRC_ALPHA);
// RenderSystem.blendColor(1f, 1f, 1f, 0.8f);
//end
// ShaderHandler.releaseShader();
//highjacking texturing state (which does nothing by default) to do my own things
String stateName = "eb_texturing_" + dissolve + "_" + blockPos + "_" + firstPos + "_" + secondPos + "_" + red;
TexturingState MY_TEXTURING = new TexturingState(stateName, () -> {
// RenderSystem.pushLightingAttributes();
// RenderSystem.pushTextureAttributes();
ShaderHandler.useShader(ShaderHandler.dissolve, generateShaderCallback(dissolve, Vector3d.atLowerCornerOf(blockPos), Vector3d.atLowerCornerOf(firstPos), Vector3d.atLowerCornerOf(secondPos), blockPos == secondPos, red));
RenderSystem.blendColor(1f, 1f, 1f, 0.8f);
}, ShaderHandler::releaseShader);
RenderType.State renderState = RenderType.State.builder()
.setTextureState(new TextureState(ShaderHandler.shaderMaskTextureLocation, false, false))
.setTexturingState(MY_TEXTURING)
.setTransparencyState(TRANSLUCENT_TRANSPARENCY)
.setDiffuseLightingState(NO_DIFFUSE_LIGHTING)
.setAlphaState(DEFAULT_ALPHA)
.setCullState(new CullState(true))
.setLightmapState(new LightmapState(false))
.setOverlayState(new OverlayState(false))
.createCompositeState(true);
//Unique name for every combination, otherwise it will reuse the previous one
String name = "eb_block_previews_" + dissolve + "_" + blockPos + "_" + firstPos + "_" + secondPos + "_" + red;
return RenderType.create(name,
DefaultVertexFormats.BLOCK, GL11.GL_QUADS, 256, true, true, renderState);
}
private static Consumer<Integer> generateShaderCallback(final float dissolve, final Vector3d blockpos,
final Vector3d firstpos, final Vector3d secondpos,
final boolean highlight, final boolean red) {
Minecraft mc = Minecraft.getInstance();
return (Integer shader) -> {
int percentileUniform = ARBShaderObjects.glGetUniformLocationARB(shader, "dissolve");
int highlightUniform = ARBShaderObjects.glGetUniformLocationARB(shader, "highlight");
int redUniform = ARBShaderObjects.glGetUniformLocationARB(shader, "red");
int blockposUniform = ARBShaderObjects.glGetUniformLocationARB(shader, "blockpos");
int firstposUniform = ARBShaderObjects.glGetUniformLocationARB(shader, "firstpos");
int secondposUniform = ARBShaderObjects.glGetUniformLocationARB(shader, "secondpos");
int imageUniform = ARBShaderObjects.glGetUniformLocationARB(shader, "image");
int maskUniform = ARBShaderObjects.glGetUniformLocationARB(shader, "mask");
RenderSystem.enableTexture();
GL11.glGetInteger(GL11.GL_TEXTURE_BINDING_2D);
//mask
ARBShaderObjects.glUniform1iARB(maskUniform, secondaryTextureUnit);
glActiveTexture(ARBMultitexture.GL_TEXTURE0_ARB + secondaryTextureUnit);
mc.getTextureManager().bind(ShaderHandler.shaderMaskTextureLocation);//getTexture(ShaderHandler.shaderMaskTextureLocation).bindTexture();
//GL11.glBindTexture(GL11.GL_TEXTURE_2D, mc.getTextureManager().getTexture(ShaderHandler.shaderMaskTextureLocation).getGlTextureId());
//image
ARBShaderObjects.glUniform1iARB(imageUniform, primaryTextureUnit);
glActiveTexture(ARBMultitexture.GL_TEXTURE0_ARB + primaryTextureUnit);
mc.getTextureManager().bind(AtlasTexture.LOCATION_BLOCKS);//.getTexture(AtlasTexture.LOCATION_BLOCKS_TEXTURE).bindTexture();
//GL11.glBindTexture(GL11.GL_TEXTURE_2D, mc.getTextureManager().getTexture(AtlasTexture.LOCATION_BLOCKS_TEXTURE).getGlTextureId());
//blockpos
ARBShaderObjects.glUniform3fARB(blockposUniform, (float) blockpos.x, (float) blockpos.y, (float) blockpos.z);
ARBShaderObjects.glUniform3fARB(firstposUniform, (float) firstpos.x, (float) firstpos.y, (float) firstpos.z);
ARBShaderObjects.glUniform3fARB(secondposUniform, (float) secondpos.x, (float) secondpos.y, (float) secondpos.z);
//dissolve
ARBShaderObjects.glUniform1fARB(percentileUniform, dissolve);
//highlight
ARBShaderObjects.glUniform1iARB(highlightUniform, highlight ? 1 : 0);
//red
ARBShaderObjects.glUniform1iARB(redUniform, red ? 1 : 0);
};
}
public static void glActiveTexture(int texture) {
if (GL.getCapabilities().GL_ARB_multitexture && !GL.getCapabilities().OpenGL13) {
ARBMultitexture.glActiveTextureARB(texture);
} else {
GL13.glActiveTexture(texture);
}
}
private class ShaderInfo {
float dissolve;
Vector3d blockPos;
Vector3d firstPos;
Vector3d secondPos;
boolean red;
public ShaderInfo(float dissolve, Vector3d blockPos, Vector3d firstPos, Vector3d secondPos, boolean red) {
this.dissolve = dissolve;
this.blockPos = blockPos;
this.firstPos = firstPos;
this.secondPos = secondPos;
this.red = red;
}
}
}

View File

@@ -1,15 +1,15 @@
package nl.requios.effortlessbuilding.render; package nl.requios.effortlessbuilding.render;
import net.minecraft.client.renderer.BufferBuilder; import com.mojang.blaze3d.matrix.MatrixStack;
import net.minecraft.client.renderer.Tessellator; import com.mojang.blaze3d.vertex.IVertexBuilder;
import net.minecraft.client.renderer.vertex.DefaultVertexFormats; import net.minecraft.client.renderer.IRenderTypeBuffer;
import net.minecraft.util.math.Vec3d; import net.minecraft.util.math.vector.Matrix4f;
import net.minecraft.util.math.vector.Vector3d;
import net.minecraftforge.api.distmarker.Dist; import net.minecraftforge.api.distmarker.Dist;
import net.minecraftforge.api.distmarker.OnlyIn; import net.minecraftforge.api.distmarker.OnlyIn;
import nl.requios.effortlessbuilding.buildmodifier.Mirror; import nl.requios.effortlessbuilding.buildmodifier.Mirror;
import nl.requios.effortlessbuilding.buildmodifier.ModifierSettingsManager; import nl.requios.effortlessbuilding.buildmodifier.ModifierSettingsManager;
import nl.requios.effortlessbuilding.buildmodifier.RadialMirror; import nl.requios.effortlessbuilding.buildmodifier.RadialMirror;
import org.lwjgl.opengl.GL11;
import java.awt.*; import java.awt.*;
@@ -22,155 +22,146 @@ public class ModifierRenderer {
protected static final Color colorRadial = new Color(52, 247, 255); protected static final Color colorRadial = new Color(52, 247, 255);
protected static final int lineAlpha = 200; protected static final int lineAlpha = 200;
protected static final int planeAlpha = 75; protected static final int planeAlpha = 75;
protected static final Vec3d epsilon = new Vec3d(0.001, 0.001, 0.001); //prevents z-fighting protected static final Vector3d epsilon = new Vector3d(0.001, 0.001, 0.001); //prevents z-fighting
public static void render(ModifierSettingsManager.ModifierSettings modifierSettings) {
RenderHandler.beginLines();
public static void render(MatrixStack matrixStack, IRenderTypeBuffer.Impl renderTypeBuffer, ModifierSettingsManager.ModifierSettings modifierSettings) {
//Mirror lines and areas //Mirror lines and areas
Mirror.MirrorSettings m = modifierSettings.getMirrorSettings(); Mirror.MirrorSettings m = modifierSettings.getMirrorSettings();
if (m != null && m.enabled && (m.mirrorX || m.mirrorY || m.mirrorZ)) if (m != null && m.enabled && (m.mirrorX || m.mirrorY || m.mirrorZ)) {
{ Vector3d pos = m.position.add(epsilon);
Vec3d pos = m.position.add(epsilon);
int radius = m.radius; int radius = m.radius;
if (m.mirrorX) if (m.mirrorX) {
{ Vector3d posA = new Vector3d(pos.x, pos.y - radius, pos.z - radius);
Vec3d posA = new Vec3d(pos.x, pos.y - radius, pos.z - radius); Vector3d posB = new Vector3d(pos.x, pos.y + radius, pos.z + radius);
Vec3d posB = new Vec3d(pos.x, pos.y + radius, pos.z + radius);
drawMirrorPlane(posA, posB, colorX, m.drawLines, m.drawPlanes, true); drawMirrorPlane(matrixStack, renderTypeBuffer, posA, posB, colorX, m.drawLines, m.drawPlanes, true);
} }
if (m.mirrorY) if (m.mirrorY) {
{ Vector3d posA = new Vector3d(pos.x - radius, pos.y, pos.z - radius);
Vec3d posA = new Vec3d(pos.x - radius, pos.y, pos.z - radius); Vector3d posB = new Vector3d(pos.x + radius, pos.y, pos.z + radius);
Vec3d posB = new Vec3d(pos.x + radius, pos.y, pos.z + radius);
drawMirrorPlaneY(posA, posB, colorY, m.drawLines, m.drawPlanes); drawMirrorPlaneY(matrixStack, renderTypeBuffer, posA, posB, colorY, m.drawLines, m.drawPlanes);
} }
if (m.mirrorZ) if (m.mirrorZ) {
{ Vector3d posA = new Vector3d(pos.x - radius, pos.y - radius, pos.z);
Vec3d posA = new Vec3d(pos.x - radius, pos.y - radius, pos.z); Vector3d posB = new Vector3d(pos.x + radius, pos.y + radius, pos.z);
Vec3d posB = new Vec3d(pos.x + radius, pos.y + radius, pos.z);
drawMirrorPlane(posA, posB, colorZ, m.drawLines, m.drawPlanes, true); drawMirrorPlane(matrixStack, renderTypeBuffer, posA, posB, colorZ, m.drawLines, m.drawPlanes, true);
} }
//Draw axis coordinated colors if two or more axes are enabled //Draw axis coordinated colors if two or more axes are enabled
//(If only one is enabled the lines are that planes color) //(If only one is enabled the lines are that planes color)
if (m.drawLines && ((m.mirrorX && m.mirrorY) || (m.mirrorX && m.mirrorZ) || (m.mirrorY && m.mirrorZ))) if (m.drawLines && ((m.mirrorX && m.mirrorY) || (m.mirrorX && m.mirrorZ) || (m.mirrorY && m.mirrorZ))) {
{ drawMirrorLines(matrixStack, renderTypeBuffer, m);
drawMirrorLines(m);
} }
} }
//Radial mirror lines and areas //Radial mirror lines and areas
RadialMirror.RadialMirrorSettings r = modifierSettings.getRadialMirrorSettings(); RadialMirror.RadialMirrorSettings r = modifierSettings.getRadialMirrorSettings();
if (r != null && r.enabled) if (r != null && r.enabled) {
{ Vector3d pos = r.position.add(epsilon);
Vec3d pos = r.position.add(epsilon);
int radius = r.radius; int radius = r.radius;
float angle = 2f * ((float) Math.PI) / r.slices; float angle = 2f * ((float) Math.PI) / r.slices;
Vec3d relStartVec = new Vec3d(radius, 0, 0); Vector3d relStartVec = new Vector3d(radius, 0, 0);
if (r.slices%4 == 2) relStartVec = relStartVec.rotateYaw(angle / 2f); if (r.slices % 4 == 2) relStartVec = relStartVec.yRot(angle / 2f);
for (int i = 0; i < r.slices; i++) { for (int i = 0; i < r.slices; i++) {
Vec3d relNewVec = relStartVec.rotateYaw(angle * i); Vector3d relNewVec = relStartVec.yRot(angle * i);
Vec3d newVec = pos.add(relNewVec); Vector3d newVec = pos.add(relNewVec);
Vec3d posA = new Vec3d(pos.x, pos.y - radius, pos.z); Vector3d posA = new Vector3d(pos.x, pos.y - radius, pos.z);
Vec3d posB = new Vec3d(newVec.x, pos.y + radius, newVec.z); Vector3d posB = new Vector3d(newVec.x, pos.y + radius, newVec.z);
drawMirrorPlane(posA, posB, colorRadial, r.drawLines, r.drawPlanes, false); drawMirrorPlane(matrixStack, renderTypeBuffer, posA, posB, colorRadial, r.drawLines, r.drawPlanes, false);
} }
} }
RenderHandler.endLines();
} }
//----Mirror---- //----Mirror----
protected static void drawMirrorPlane(Vec3d posA, Vec3d posB, Color c, boolean drawLines, boolean drawPlanes, boolean drawVerticalLines) { protected static void drawMirrorPlane(MatrixStack matrixStack, IRenderTypeBuffer.Impl renderTypeBuffer, Vector3d posA, Vector3d posB, Color c, boolean drawLines, boolean drawPlanes, boolean drawVerticalLines) {
GL11.glColor4d(c.getRed(), c.getGreen(), c.getBlue(), planeAlpha); // GL11.glColor4d(c.getRed(), c.getGreen(), c.getBlue(), planeAlpha);
Tessellator tessellator = Tessellator.getInstance(); Matrix4f matrixPos = matrixStack.last().pose();
BufferBuilder bufferBuilder = tessellator.getBuffer();
if (drawPlanes) { if (drawPlanes) {
bufferBuilder.begin(GL11.GL_TRIANGLE_STRIP, DefaultVertexFormats.POSITION_COLOR); IVertexBuilder buffer = RenderHandler.beginPlanes(renderTypeBuffer);
bufferBuilder.pos(posA.x, posA.y, posA.z).color(c.getRed(), c.getGreen(), c.getBlue(), planeAlpha).endVertex(); buffer.vertex(matrixPos, (float) posA.x, (float) posA.y, (float) posA.z).color(c.getRed(), c.getGreen(), c.getBlue(), planeAlpha).endVertex();
bufferBuilder.pos(posA.x, posB.y, posA.z).color(c.getRed(), c.getGreen(), c.getBlue(), planeAlpha).endVertex(); buffer.vertex(matrixPos, (float) posA.x, (float) posB.y, (float) posA.z).color(c.getRed(), c.getGreen(), c.getBlue(), planeAlpha).endVertex();
bufferBuilder.pos(posB.x, posA.y, posB.z).color(c.getRed(), c.getGreen(), c.getBlue(), planeAlpha).endVertex(); buffer.vertex(matrixPos, (float) posB.x, (float) posA.y, (float) posB.z).color(c.getRed(), c.getGreen(), c.getBlue(), planeAlpha).endVertex();
bufferBuilder.pos(posB.x, posB.y, posB.z).color(c.getRed(), c.getGreen(), c.getBlue(), planeAlpha).endVertex(); buffer.vertex(matrixPos, (float) posB.x, (float) posB.y, (float) posB.z).color(c.getRed(), c.getGreen(), c.getBlue(), planeAlpha).endVertex();
//backface (using triangle strip)
buffer.vertex(matrixPos, (float) posA.x, (float) posA.y, (float) posA.z).color(c.getRed(), c.getGreen(), c.getBlue(), planeAlpha).endVertex();
buffer.vertex(matrixPos, (float) posA.x, (float) posB.y, (float) posA.z).color(c.getRed(), c.getGreen(), c.getBlue(), planeAlpha).endVertex();
tessellator.draw(); RenderHandler.endPlanes(renderTypeBuffer);
} }
if (drawLines) { if (drawLines) {
Vec3d middle = posA.add(posB).scale(0.5); IVertexBuilder buffer = RenderHandler.beginLines(renderTypeBuffer);
bufferBuilder.begin(GL11.GL_LINES, DefaultVertexFormats.POSITION_COLOR);
bufferBuilder.pos(posA.x, middle.y, posA.z).color(c.getRed(), c.getGreen(), c.getBlue(), lineAlpha).endVertex(); Vector3d middle = posA.add(posB).scale(0.5);
bufferBuilder.pos(posB.x, middle.y, posB.z).color(c.getRed(), c.getGreen(), c.getBlue(), lineAlpha).endVertex(); buffer.vertex(matrixPos, (float) posA.x, (float) middle.y, (float) posA.z).color(c.getRed(), c.getGreen(), c.getBlue(), lineAlpha).endVertex();
buffer.vertex(matrixPos, (float) posB.x, (float) middle.y, (float) posB.z).color(c.getRed(), c.getGreen(), c.getBlue(), lineAlpha).endVertex();
if (drawVerticalLines) { if (drawVerticalLines) {
bufferBuilder.pos(middle.x, posA.y, middle.z).color(c.getRed(), c.getGreen(), c.getBlue(), lineAlpha).endVertex(); buffer.vertex(matrixPos, (float) middle.x, (float) posA.y, (float) middle.z).color(c.getRed(), c.getGreen(), c.getBlue(), lineAlpha).endVertex();
bufferBuilder.pos(middle.x, posB.y, middle.z).color(c.getRed(), c.getGreen(), c.getBlue(), lineAlpha).endVertex(); buffer.vertex(matrixPos, (float) middle.x, (float) posB.y, (float) middle.z).color(c.getRed(), c.getGreen(), c.getBlue(), lineAlpha).endVertex();
} }
tessellator.draw(); RenderHandler.endLines(renderTypeBuffer);
} }
} }
protected static void drawMirrorPlaneY(Vec3d posA, Vec3d posB, Color c, boolean drawLines, boolean drawPlanes) { protected static void drawMirrorPlaneY(MatrixStack matrixStack, IRenderTypeBuffer.Impl renderTypeBuffer, Vector3d posA, Vector3d posB, Color c, boolean drawLines, boolean drawPlanes) {
GL11.glColor4d(c.getRed(), c.getGreen(), c.getBlue(), c.getAlpha()); // GL11.glColor4d(c.getRed(), c.getGreen(), c.getBlue(), c.getAlpha());
Tessellator tessellator = Tessellator.getInstance(); Matrix4f matrixPos = matrixStack.last().pose();
BufferBuilder bufferBuilder = tessellator.getBuffer();
if (drawPlanes) { if (drawPlanes) {
bufferBuilder.begin(GL11.GL_TRIANGLE_STRIP, DefaultVertexFormats.POSITION_COLOR); IVertexBuilder buffer = RenderHandler.beginPlanes(renderTypeBuffer);
bufferBuilder.pos(posA.x, posA.y, posA.z).color(c.getRed(), c.getGreen(), c.getBlue(), planeAlpha).endVertex(); buffer.vertex(matrixPos, (float) posA.x, (float) posA.y, (float) posA.z).color(c.getRed(), c.getGreen(), c.getBlue(), planeAlpha).endVertex();
bufferBuilder.pos(posA.x, posA.y, posB.z).color(c.getRed(), c.getGreen(), c.getBlue(), planeAlpha).endVertex(); buffer.vertex(matrixPos, (float) posA.x, (float) posA.y, (float) posB.z).color(c.getRed(), c.getGreen(), c.getBlue(), planeAlpha).endVertex();
bufferBuilder.pos(posB.x, posA.y, posA.z).color(c.getRed(), c.getGreen(), c.getBlue(), planeAlpha).endVertex(); buffer.vertex(matrixPos, (float) posB.x, (float) posA.y, (float) posA.z).color(c.getRed(), c.getGreen(), c.getBlue(), planeAlpha).endVertex();
bufferBuilder.pos(posB.x, posA.y, posB.z).color(c.getRed(), c.getGreen(), c.getBlue(), planeAlpha).endVertex(); buffer.vertex(matrixPos, (float) posB.x, (float) posA.y, (float) posB.z).color(c.getRed(), c.getGreen(), c.getBlue(), planeAlpha).endVertex();
//backface (using triangle strip)
buffer.vertex(matrixPos, (float) posA.x, (float) posA.y, (float) posA.z).color(c.getRed(), c.getGreen(), c.getBlue(), planeAlpha).endVertex();
buffer.vertex(matrixPos, (float) posA.x, (float) posA.y, (float) posB.z).color(c.getRed(), c.getGreen(), c.getBlue(), planeAlpha).endVertex();
tessellator.draw(); RenderHandler.endPlanes(renderTypeBuffer);
} }
if (drawLines) { if (drawLines) {
Vec3d middle = posA.add(posB).scale(0.5); IVertexBuilder buffer = RenderHandler.beginLines(renderTypeBuffer);
bufferBuilder.begin(GL11.GL_LINES, DefaultVertexFormats.POSITION_COLOR);
bufferBuilder.pos(middle.x, middle.y, posA.z).color(c.getRed(), c.getGreen(), c.getBlue(), lineAlpha).endVertex(); Vector3d middle = posA.add(posB).scale(0.5);
bufferBuilder.pos(middle.x, middle.y, posB.z).color(c.getRed(), c.getGreen(), c.getBlue(), lineAlpha).endVertex(); buffer.vertex(matrixPos, (float) middle.x, (float) middle.y, (float) posA.z).color(c.getRed(), c.getGreen(), c.getBlue(), lineAlpha).endVertex();
bufferBuilder.pos(posA.x, middle.y, middle.z).color(c.getRed(), c.getGreen(), c.getBlue(), lineAlpha).endVertex(); buffer.vertex(matrixPos, (float) middle.x, (float) middle.y, (float) posB.z).color(c.getRed(), c.getGreen(), c.getBlue(), lineAlpha).endVertex();
bufferBuilder.pos(posB.x, middle.y, middle.z).color(c.getRed(), c.getGreen(), c.getBlue(), lineAlpha).endVertex(); buffer.vertex(matrixPos, (float) posA.x, (float) middle.y, (float) middle.z).color(c.getRed(), c.getGreen(), c.getBlue(), lineAlpha).endVertex();
buffer.vertex(matrixPos, (float) posB.x, (float) middle.y, (float) middle.z).color(c.getRed(), c.getGreen(), c.getBlue(), lineAlpha).endVertex();
tessellator.draw(); RenderHandler.endLines(renderTypeBuffer);
} }
} }
protected static void drawMirrorLines(Mirror.MirrorSettings m) { protected static void drawMirrorLines(MatrixStack matrixStack, IRenderTypeBuffer.Impl renderTypeBuffer, Mirror.MirrorSettings m) {
Vec3d pos = m.position.add(epsilon); // GL11.glColor4d(100, 100, 100, 255);
IVertexBuilder buffer = RenderHandler.beginLines(renderTypeBuffer);
Matrix4f matrixPos = matrixStack.last().pose();
GL11.glColor4d(100, 100, 100, 255); Vector3d pos = m.position.add(epsilon);
GL11.glLineWidth(2);
Tessellator tessellator = Tessellator.getInstance();
BufferBuilder bufferBuilder = tessellator.getBuffer();
bufferBuilder.begin(GL11.GL_LINES, DefaultVertexFormats.POSITION_COLOR); buffer.vertex(matrixPos, (float) pos.x - m.radius, (float) pos.y, (float) pos.z).color(colorX.getRed(), colorX.getGreen(), colorX.getBlue(), lineAlpha).endVertex();
buffer.vertex(matrixPos, (float) pos.x + m.radius, (float) pos.y, (float) pos.z).color(colorX.getRed(), colorX.getGreen(), colorX.getBlue(), lineAlpha).endVertex();
buffer.vertex(matrixPos, (float) pos.x, (float) pos.y - m.radius, (float) pos.z).color(colorY.getRed(), colorY.getGreen(), colorY.getBlue(), lineAlpha).endVertex();
buffer.vertex(matrixPos, (float) pos.x, (float) pos.y + m.radius, (float) pos.z).color(colorY.getRed(), colorY.getGreen(), colorY.getBlue(), lineAlpha).endVertex();
buffer.vertex(matrixPos, (float) pos.x, (float) pos.y, (float) pos.z - m.radius).color(colorZ.getRed(), colorZ.getGreen(), colorZ.getBlue(), lineAlpha).endVertex();
buffer.vertex(matrixPos, (float) pos.x, (float) pos.y, (float) pos.z + m.radius).color(colorZ.getRed(), colorZ.getGreen(), colorZ.getBlue(), lineAlpha).endVertex();
bufferBuilder.pos(pos.x - m.radius, pos.y, pos.z).color(colorX.getRed(), colorX.getGreen(), colorX.getBlue(), lineAlpha).endVertex(); RenderHandler.endLines(renderTypeBuffer);
bufferBuilder.pos(pos.x + m.radius, pos.y, pos.z).color(colorX.getRed(), colorX.getGreen(), colorX.getBlue(), lineAlpha).endVertex();
bufferBuilder.pos(pos.x, pos.y - m.radius, pos.z).color(colorY.getRed(), colorY.getGreen(), colorY.getBlue(), lineAlpha).endVertex();
bufferBuilder.pos(pos.x, pos.y + m.radius, pos.z).color(colorY.getRed(), colorY.getGreen(), colorY.getBlue(), lineAlpha).endVertex();
bufferBuilder.pos(pos.x, pos.y, pos.z - m.radius).color(colorZ.getRed(), colorZ.getGreen(), colorZ.getBlue(), lineAlpha).endVertex();
bufferBuilder.pos(pos.x, pos.y, pos.z + m.radius).color(colorZ.getRed(), colorZ.getGreen(), colorZ.getBlue(), lineAlpha).endVertex();
tessellator.draw();
} }
} }

View File

@@ -1,39 +1,25 @@
package nl.requios.effortlessbuilding.render; package nl.requios.effortlessbuilding.render;
import com.mojang.blaze3d.platform.GlStateManager; import com.mojang.blaze3d.matrix.MatrixStack;
import com.mojang.blaze3d.vertex.IVertexBuilder;
import net.minecraft.block.BlockState; import net.minecraft.block.BlockState;
import net.minecraft.client.Minecraft; import net.minecraft.client.Minecraft;
import net.minecraft.client.audio.SimpleSound; import net.minecraft.client.renderer.*;
import net.minecraft.client.entity.player.ClientPlayerEntity; import net.minecraft.client.renderer.model.IBakedModel;
import net.minecraft.client.renderer.BlockRendererDispatcher; import net.minecraft.client.renderer.texture.OverlayTexture;
import net.minecraft.client.renderer.WorldRenderer;
import net.minecraft.client.renderer.tileentity.TileEntityRendererDispatcher;
import net.minecraft.client.resources.I18n;
import net.minecraft.client.settings.KeyBinding;
import net.minecraft.entity.player.PlayerEntity; import net.minecraft.entity.player.PlayerEntity;
import net.minecraft.util.SoundCategory;
import net.minecraft.util.SoundEvents;
import net.minecraft.util.math.AxisAlignedBB; import net.minecraft.util.math.AxisAlignedBB;
import net.minecraft.util.math.BlockPos; import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.Vec3d;
import net.minecraft.util.math.shapes.VoxelShape; import net.minecraft.util.math.shapes.VoxelShape;
import net.minecraft.util.math.vector.Vector3d;
import net.minecraftforge.api.distmarker.Dist; import net.minecraftforge.api.distmarker.Dist;
import net.minecraftforge.client.event.RenderGameOverlayEvent;
import net.minecraftforge.client.event.RenderWorldLastEvent; import net.minecraftforge.client.event.RenderWorldLastEvent;
import net.minecraftforge.eventbus.api.EventPriority;
import net.minecraftforge.eventbus.api.SubscribeEvent; import net.minecraftforge.eventbus.api.SubscribeEvent;
import net.minecraftforge.fml.common.Mod; import net.minecraftforge.fml.common.Mod;
import nl.requios.effortlessbuilding.EffortlessBuilding; import nl.requios.effortlessbuilding.EffortlessBuilding;
import nl.requios.effortlessbuilding.buildmode.ModeOptions;
import nl.requios.effortlessbuilding.buildmode.ModeSettingsManager; import nl.requios.effortlessbuilding.buildmode.ModeSettingsManager;
import nl.requios.effortlessbuilding.buildmodifier.ModifierSettingsManager; import nl.requios.effortlessbuilding.buildmodifier.ModifierSettingsManager;
import nl.requios.effortlessbuilding.gui.buildmode.RadialMenu;
import nl.requios.effortlessbuilding.helper.ReachHelper;
import nl.requios.effortlessbuilding.network.ModeActionMessage;
import nl.requios.effortlessbuilding.network.ModeSettingsMessage;
import nl.requios.effortlessbuilding.network.PacketHandler;
import nl.requios.effortlessbuilding.proxy.ClientProxy;
import org.lwjgl.opengl.GL11;
import org.lwjgl.opengl.GL14;
/*** /***
* Main render class for Effortless Building * Main render class for Effortless Building
@@ -43,205 +29,105 @@ public class RenderHandler {
@SubscribeEvent @SubscribeEvent
public static void onRender(RenderWorldLastEvent event) { public static void onRender(RenderWorldLastEvent event) {
if (event.getPhase() != EventPriority.NORMAL)
return;
MatrixStack matrixStack = event.getMatrixStack();
BufferBuilder bufferBuilder = Tessellator.getInstance().getBuilder();
IRenderTypeBuffer.Impl renderTypeBuffer = IRenderTypeBuffer.immediate(bufferBuilder);
if (renderTypeBuffer == null)
return;
PlayerEntity player = Minecraft.getInstance().player; PlayerEntity player = Minecraft.getInstance().player;
ModeSettingsManager.ModeSettings modeSettings = ModeSettingsManager.getModeSettings(player); ModeSettingsManager.ModeSettings modeSettings = ModeSettingsManager.getModeSettings(player);
ModifierSettingsManager.ModifierSettings modifierSettings = ModifierSettingsManager.getModifierSettings(player); ModifierSettingsManager.ModifierSettings modifierSettings = ModifierSettingsManager.getModifierSettings(player);
begin(event.getPartialTicks()); Vector3d projectedView = Minecraft.getInstance().gameRenderer.getMainCamera().getPosition();
matrixStack.pushPose();
matrixStack.translate(-projectedView.x, -projectedView.y, -projectedView.z);
//Mirror and radial mirror lines and areas //Mirror and radial mirror lines and areas
ModifierRenderer.render(modifierSettings); ModifierRenderer.render(matrixStack, renderTypeBuffer, modifierSettings);
//Render block previews //Render block previews
BlockPreviewRenderer.render(player, modifierSettings, modeSettings); BlockPreviewRenderer.render(matrixStack, renderTypeBuffer, player, modifierSettings, modeSettings);
end(); matrixStack.popPose();
} }
@SubscribeEvent protected static IVertexBuilder beginLines(IRenderTypeBuffer.Impl renderTypeBuffer) {
//Display Radial Menu return renderTypeBuffer.getBuffer(BuildRenderTypes.LINES);
public static void onRenderGameOverlay(final RenderGameOverlayEvent.Post event) {
Minecraft mc = Minecraft.getInstance();
ClientPlayerEntity player = mc.player;
//check if chisel and bits tool in hand (and has menu)
// final boolean hasChiselInHand = CompatHelper.chiselsAndBitsProxy.isHoldingChiselTool(EnumHand.MAIN_HAND);
final RenderGameOverlayEvent.ElementType type = event.getType();
//TODO 1.13 compatibility
if (type == RenderGameOverlayEvent.ElementType.ALL /*&& !hasChiselInHand*/) {
final boolean wasVisible = RadialMenu.instance.isVisible();
if (ClientProxy.keyBindings[3].isKeyDown()) {
if (ReachHelper.getMaxReach(player) > 0) {
RadialMenu.instance.actionUsed = false;
RadialMenu.instance.raiseVisibility();
} else if (ClientProxy.keyBindings[3].isPressed()) {
EffortlessBuilding.log(player, "Build modes are disabled until your reach has increased. Increase your reach with craftable reach upgrades.");
}
} else {
if (!RadialMenu.instance.actionUsed) {
ModeSettingsManager.ModeSettings modeSettings = ModeSettingsManager.getModeSettings(player);
if (RadialMenu.instance.switchTo != null) {
playRadialMenuSound();
modeSettings.setBuildMode(RadialMenu.instance.switchTo);
ModeSettingsManager.setModeSettings(player, modeSettings);
PacketHandler.INSTANCE.sendToServer(new ModeSettingsMessage(modeSettings));
EffortlessBuilding.log(player, I18n.format(modeSettings.getBuildMode().name), true);
} }
//Perform button action protected static void endLines(IRenderTypeBuffer.Impl renderTypeBuffer) {
ModeOptions.ActionEnum action = RadialMenu.instance.doAction; renderTypeBuffer.endBatch();
if (action != null) {
ModeOptions.performAction(player, action);
PacketHandler.INSTANCE.sendToServer(new ModeActionMessage(action));
} }
playRadialMenuSound(); protected static IVertexBuilder beginPlanes(IRenderTypeBuffer.Impl renderTypeBuffer) {
return renderTypeBuffer.getBuffer(BuildRenderTypes.PLANES);
} }
RadialMenu.instance.actionUsed = true; protected static void endPlanes(IRenderTypeBuffer.Impl renderTypeBuffer) {
RadialMenu.instance.decreaseVisibility(); renderTypeBuffer.endBatch();
} }
if (RadialMenu.instance.isVisible()) { protected static void renderBlockPreview(MatrixStack matrixStack, IRenderTypeBuffer.Impl renderTypeBuffer, BlockRendererDispatcher dispatcher,
BlockPos blockPos, BlockState blockState, float dissolve, BlockPos firstPos, BlockPos secondPos, boolean red) {
int scaledWidth = mc.mainWindow.getScaledWidth();
int scaledHeight = mc.mainWindow.getScaledHeight();
RadialMenu.instance.configure(scaledWidth, scaledHeight);
if (!wasVisible) {
mc.mouseHelper.ungrabMouse();
}
if (mc.mouseHelper.isMouseGrabbed()) {
KeyBinding.unPressAllKeys();
}
final int mouseX = ((int) mc.mouseHelper.getMouseX()) * scaledWidth / mc.mainWindow.getFramebufferWidth();
final int mouseY = scaledHeight - ((int) mc.mouseHelper.getMouseY()) * scaledHeight / mc.mainWindow.getFramebufferHeight() - 1;
net.minecraftforge.client.ForgeHooksClient.drawScreen(RadialMenu.instance, mouseX, mouseY, event.getPartialTicks());
} else {
if (wasVisible && RadialMenu.instance.doAction != ModeOptions.ActionEnum.OPEN_MODIFIER_SETTINGS) {
mc.mouseHelper.grabMouse();
}
}
}
}
public static void playRadialMenuSound() {
final float volume = 0.1f;
if (volume >= 0.0001f) {
SimpleSound sound = new SimpleSound(SoundEvents.UI_BUTTON_CLICK, SoundCategory.MASTER, volume, 1.0f, Minecraft.getInstance().player.getPosition());
Minecraft.getInstance().getSoundHandler().play(sound);
}
}
private static void begin(float partialTicks) {
// PlayerEntity player = Minecraft.getInstance().player;
// double playerX = player.prevPosX + (player.posX - player.prevPosX) * partialTicks;
// double playerY = player.prevPosY + (player.posY - player.prevPosY) * partialTicks;
// double playerZ = player.prevPosZ + (player.posZ - player.prevPosZ) * partialTicks;
// Vec3d playerPos = new Vec3d(playerX, playerY, playerZ);
GL11.glPushMatrix();
// GL11.glTranslated(-playerPos.x, -playerPos.y, -playerPos.z);
GlStateManager.translated(-TileEntityRendererDispatcher.staticPlayerX, -TileEntityRendererDispatcher.staticPlayerY, -TileEntityRendererDispatcher.staticPlayerZ);
GL11.glDepthMask(false);
}
protected static void beginLines() {
GL11.glPushAttrib(GL11.GL_ENABLE_BIT);
GL11.glDisable(GL11.GL_CULL_FACE);
GL11.glDisable(GL11.GL_LIGHTING);
GL11.glDisable(GL11.GL_TEXTURE_2D);
GL11.glEnable(GL11.GL_BLEND);
GL11.glBlendFunc(GL11.GL_SRC_ALPHA, GL11.GL_ONE_MINUS_SRC_ALPHA);
GL11.glLineWidth(2);
}
protected static void endLines() {
GL11.glPopAttrib();
}
protected static void beginBlockPreviews() {
GL11.glPushAttrib(GL11.GL_ENABLE_BIT);
GL11.glEnable(GL11.GL_CULL_FACE);
GL11.glEnable(GL11.GL_TEXTURE_2D);
// Minecraft.getMinecraft().renderEngine.bindTexture(TextureMap.LOCATION_BLOCKS_TEXTURE);
Minecraft.getInstance().textureManager.bindTexture(ShaderHandler.shaderMaskTextureLocation);
GlStateManager.enableBlend();
GlStateManager.blendFunc(GL11.GL_SRC_ALPHA, GL11.GL_ONE_MINUS_SRC_ALPHA);
GL14.glBlendColor(1F, 1F, 1F, 0.8f);
}
protected static void endBlockPreviews() {
ShaderHandler.releaseShader();
GlStateManager.disableBlend();
GL11.glPopAttrib();
}
private static void end() {
GL11.glDepthMask(true);
GL11.glPopMatrix();
}
protected static void renderBlockPreview(BlockRendererDispatcher dispatcher, BlockPos blockPos, BlockState blockState) {
if (blockState == null) return; if (blockState == null) return;
GlStateManager.pushMatrix(); matrixStack.pushPose();
GlStateManager.translatef(blockPos.getX(), blockPos.getY(), blockPos.getZ()); matrixStack.translate(blockPos.getX(), blockPos.getY(), blockPos.getZ());
GlStateManager.rotatef(-90.0F, 0.0F, 1.0F, 0.0F); // matrixStack.rotate(Vector3f.YP.rotationDegrees(-90f));
GlStateManager.translatef(-0.01f, -0.01f, 0.01f); matrixStack.translate(-0.01f, -0.01f, -0.01f);
GlStateManager.scalef(1.02f, 1.02f, 1.02f); matrixStack.scale(1.02f, 1.02f, 1.02f);
//Begin block preview rendering
RenderType blockPreviewRenderType = BuildRenderTypes.getBlockPreviewRenderType(dissolve, blockPos, firstPos, secondPos, red);
IVertexBuilder buffer = renderTypeBuffer.getBuffer(blockPreviewRenderType);
// MinecraftServer server = Minecraft.getInstance().getIntegratedServer();
// World world = DimensionManager.getWorld(server, DimensionType.OVERWORLD, false, true);
try { try {
dispatcher.renderBlockBrightness(blockState, 0.85f); IBakedModel model = dispatcher.getBlockModel(blockState);
dispatcher.getModelRenderer().renderModel(matrixStack.last(), buffer,
blockState, model, 1f, 1f, 1f, 0, OverlayTexture.NO_OVERLAY);
// blockRendererDispatcher.getBlockModelRenderer().renderModel(world, blockRendererDispatcher.getModelForState(blockState),
// blockState, logicPos, matrixStack, renderTypeBuffer.getBuffer(renderType), true, new Random(), blockState.getPositionRandom(logicPos), i);
} catch (NullPointerException e) { } catch (NullPointerException e) {
EffortlessBuilding.logger.warn("RenderHandler::renderBlockPreview cannot render " + blockState.getBlock().toString()); EffortlessBuilding.logger.warn("RenderHandler::renderBlockPreview cannot render " + blockState.getBlock().toString());
//Render outline as backup //Render outline as backup, escape out of the current renderstack
GlStateManager.popMatrix(); matrixStack.popPose();
// ShaderHandler.releaseShader(); renderTypeBuffer.endBatch();
GL11.glDisable(GL11.GL_LIGHTING); IVertexBuilder lineBuffer = beginLines(renderTypeBuffer);
renderBlockOutline(blockPos, new Vec3d(1f, 1f, 1f)); renderBlockOutline(matrixStack, lineBuffer, blockPos, new Vector3d(1f, 1f, 1f));
GL11.glEnable(GL11.GL_LIGHTING); endLines(renderTypeBuffer);
GlStateManager.pushMatrix(); buffer = renderTypeBuffer.getBuffer(Atlases.translucentCullBlockSheet()); //any type will do, as long as we have something on the stack
matrixStack.pushPose();
} }
GlStateManager.popMatrix(); renderTypeBuffer.endBatch();
matrixStack.popPose();
} }
protected static void renderBlockOutline(BlockPos pos, Vec3d color) { protected static void renderBlockOutline(MatrixStack matrixStack, IVertexBuilder buffer, BlockPos pos, Vector3d color) {
renderBlockOutline(pos, pos, color); renderBlockOutline(matrixStack, buffer, pos, pos, color);
} }
//Renders outline. Pos1 has to be minimal x,y,z and pos2 maximal x,y,z //Renders outline. Pos1 has to be minimal x,y,z and pos2 maximal x,y,z
protected static void renderBlockOutline(BlockPos pos1, BlockPos pos2, Vec3d color) { protected static void renderBlockOutline(MatrixStack matrixStack, IVertexBuilder buffer, BlockPos pos1, BlockPos pos2, Vector3d color) {
GL11.glLineWidth(2); AxisAlignedBB aabb = new AxisAlignedBB(pos1, pos2.offset(1, 1, 1)).inflate(0.0020000000949949026);
AxisAlignedBB aabb = new AxisAlignedBB(pos1, pos2.add(1, 1, 1)).grow(0.0020000000949949026); WorldRenderer.renderLineBox(matrixStack, buffer, aabb, (float) color.x, (float) color.y, (float) color.z, 0.4f);
// WorldRenderer.drawSelectionBoundingBox(aabb, (float) color.x, (float) color.y, (float) color.z, 0.4f);
WorldRenderer.drawSelectionBoundingBox(aabb, (float) color.x, (float) color.y, (float) color.z, 0.4f);
} }
//Renders outline with given bounding box //Renders outline with given bounding box
protected static void renderBlockOutline(BlockPos pos, VoxelShape collisionShape, Vec3d color) { protected static void renderBlockOutline(MatrixStack matrixStack, IVertexBuilder buffer, BlockPos pos, VoxelShape collisionShape, Vector3d color) {
GL11.glLineWidth(2); // WorldRenderer.drawShape(collisionShape, pos.getX(), pos.getY(), pos.getZ(), (float) color.x, (float) color.y, (float) color.z, 0.4f);
WorldRenderer.renderVoxelShape(matrixStack, buffer, collisionShape, pos.getX(), pos.getY(), pos.getZ(), (float) color.x, (float) color.y, (float) color.z, 0.4f);
// AxisAlignedBB aabb = boundingBox.offset(pos).grow(0.0020000000949949026);
// VoxelShape voxelShape = collisionShape.withOffset(pos.getX(), pos.getY(), pos.getZ());
// WorldRenderer.drawSelectionBoundingBox(aabb, (float) color.x, (float) color.y, (float) color.z, 0.4f);
WorldRenderer.drawShape(collisionShape, pos.getX(), pos.getY(), pos.getZ(), (float) color.x, (float) color.y, (float) color.z, 0.4f);
} }
//TODO 1.14 //TODO 1.14

View File

@@ -2,12 +2,12 @@
* This class was created by <Vazkii>. It's distributed as * This class was created by <Vazkii>. It's distributed as
* part of the Botania Mod. Get the Source Code in github: * part of the Botania Mod. Get the Source Code in github:
* https://github.com/Vazkii/Botania * https://github.com/Vazkii/Botania
* * <p>
* Modified by Requios * Modified by Requios
* * <p>
* Botania is Open Source and distributed under the * Botania is Open Source and distributed under the
* Botania License: http://botaniamod.net/license.php * Botania License: http://botaniamod.net/license.php
* * <p>
* File Created @ [Apr 9, 2014, 11:20:26 PM (GMT)] * File Created @ [Apr 9, 2014, 11:20:26 PM (GMT)]
*/ */
package nl.requios.effortlessbuilding.render; package nl.requios.effortlessbuilding.render;
@@ -42,7 +42,7 @@ public final class ShaderHandler {
public static ResourceLocation shaderMaskTextureLocation = new ResourceLocation(EffortlessBuilding.MODID, "textures/shader_mask.png"); public static ResourceLocation shaderMaskTextureLocation = new ResourceLocation(EffortlessBuilding.MODID, "textures/shader_mask.png");
public static void init() { public static void init() {
if(!doUseShaders()) if (!doUseShaders())
return; return;
// rawColor = createProgram("/assets/effortlessbuilding/shaders/raw_color", FRAG); // rawColor = createProgram("/assets/effortlessbuilding/shaders/raw_color", FRAG);
@@ -50,16 +50,16 @@ public final class ShaderHandler {
} }
public static void useShader(int shader, Consumer<Integer> callback) { public static void useShader(int shader, Consumer<Integer> callback) {
if(!doUseShaders()) if (!doUseShaders())
return; return;
ARBShaderObjects.glUseProgramObjectARB(shader); ARBShaderObjects.glUseProgramObjectARB(shader);
if(shader != 0) { if (shader != 0) {
int time = ARBShaderObjects.glGetUniformLocationARB(shader, "time"); int time = ARBShaderObjects.glGetUniformLocationARB(shader, "time");
ARBShaderObjects.glUniform1iARB(time, ClientProxy.ticksInGame); ARBShaderObjects.glUniform1iARB(time, ClientProxy.ticksInGame);
if(callback != null) if (callback != null)
callback.accept(shader); callback.accept(shader);
} }
} }
@@ -96,22 +96,22 @@ public final class ShaderHandler {
private static int createProgram(String vert, String frag) { private static int createProgram(String vert, String frag) {
int vertId = 0, fragId = 0, program; int vertId = 0, fragId = 0, program;
if(vert != null) if (vert != null)
vertId = createShader(vert, VERT_ST); vertId = createShader(vert, VERT_ST);
if(frag != null) if (frag != null)
fragId = createShader(frag, FRAG_ST); fragId = createShader(frag, FRAG_ST);
program = ARBShaderObjects.glCreateProgramObjectARB(); program = ARBShaderObjects.glCreateProgramObjectARB();
if(program == 0) if (program == 0)
return 0; return 0;
if(vert != null) if (vert != null)
ARBShaderObjects.glAttachObjectARB(program, vertId); ARBShaderObjects.glAttachObjectARB(program, vertId);
if(frag != null) if (frag != null)
ARBShaderObjects.glAttachObjectARB(program, fragId); ARBShaderObjects.glAttachObjectARB(program, fragId);
ARBShaderObjects.glLinkProgramARB(program); ARBShaderObjects.glLinkProgramARB(program);
if(ARBShaderObjects.glGetObjectParameteriARB(program, ARBShaderObjects.GL_OBJECT_LINK_STATUS_ARB) == GL11.GL_FALSE) { if (ARBShaderObjects.glGetObjectParameteriARB(program, ARBShaderObjects.GL_OBJECT_LINK_STATUS_ARB) == GL11.GL_FALSE) {
EffortlessBuilding.logger.log(Level.ERROR, getLogInfo(program)); EffortlessBuilding.logger.log(Level.ERROR, getLogInfo(program));
return 0; return 0;
} }
@@ -125,12 +125,12 @@ public final class ShaderHandler {
return program; return program;
} }
private static int createShader(String filename, int shaderType){ private static int createShader(String filename, int shaderType) {
int shader = 0; int shader = 0;
try { try {
shader = ARBShaderObjects.glCreateShaderObjectARB(shaderType); shader = ARBShaderObjects.glCreateShaderObjectARB(shaderType);
if(shader == 0) if (shader == 0)
return 0; return 0;
ARBShaderObjects.glShaderSourceARB(shader, readFileAsString(filename)); ARBShaderObjects.glShaderSourceARB(shader, readFileAsString(filename));
@@ -140,8 +140,7 @@ public final class ShaderHandler {
throw new RuntimeException("Error creating shader: " + getLogInfo(shader)); throw new RuntimeException("Error creating shader: " + getLogInfo(shader));
return shader; return shader;
} } catch (Exception e) {
catch(Exception e) {
ARBShaderObjects.glDeleteObjectARB(shader); ARBShaderObjects.glDeleteObjectARB(shader);
e.printStackTrace(); e.printStackTrace();
return -1; return -1;
@@ -158,41 +157,41 @@ public final class ShaderHandler {
Exception exception = null; Exception exception = null;
BufferedReader reader; BufferedReader reader;
if(in == null) if (in == null)
return ""; return "";
try { try {
reader = new BufferedReader(new InputStreamReader(in, StandardCharsets.UTF_8)); reader = new BufferedReader(new InputStreamReader(in, StandardCharsets.UTF_8));
Exception innerExc= null; Exception innerExc = null;
try { try {
String line; String line;
while((line = reader.readLine()) != null) while ((line = reader.readLine()) != null)
source.append(line).append('\n'); source.append(line).append('\n');
} catch(Exception exc) { } catch (Exception exc) {
exception = exc; exception = exc;
} finally { } finally {
try { try {
reader.close(); reader.close();
} catch(Exception exc) { } catch (Exception exc) {
innerExc = exc; innerExc = exc;
} }
} }
if(innerExc != null) if (innerExc != null)
throw innerExc; throw innerExc;
} catch(Exception exc) { } catch (Exception exc) {
exception = exc; exception = exc;
} finally { } finally {
try { try {
in.close(); in.close();
} catch(Exception exc) { } catch (Exception exc) {
if(exception == null) if (exception == null)
exception = exc; exception = exc;
else exc.printStackTrace(); else exc.printStackTrace();
} }
if(exception != null) if (exception != null)
throw exception; throw exception;
} }

View File

@@ -0,0 +1,3 @@
public net.minecraft.client.gui.widget.list.AbstractList field_230680_q_ # renderHeader
public net.minecraft.client.gui.FontRenderer func_228078_a_(Ljava/lang/String;FFILnet/minecraft/util/math/vector/Matrix4f;ZZ)I # renderString
public net.minecraft.inventory.container.ContainerType func_221505_a(Ljava/lang/String;Lnet/minecraft/inventory/container/ContainerType$IFactory;)Lnet/minecraft/inventory/container/ContainerType; # register

View File

@@ -1,12 +1,7 @@
# This is an example mods.toml file. It contains the data relating to the loading mods.
# There are several mandatory fields (#mandatory), and many more that are optional (#optional).
# The overall format is standard TOML format, v0.5.0.
# Note that there are a couple of TOML lists in this file.
# Find more information on toml format here: https://github.com/toml-lang/toml
# The name of the mod loader type to load - for regular FML @Mod mods it should be javafml
modLoader="javafml" #mandatory modLoader="javafml" #mandatory
# A version range to match for said mod loader - for regular FML @Mod it will be the forge version # A version range to match for said mod loader - for regular FML @Mod it will be the forge version
loaderVersion="[25,)" #mandatory (24 is current forge version) loaderVersion="[34,)" #mandatory This is typically bumped every Minecraft version by Forge. See our download page for lists of versions.
license="GNU LESSER GENERAL PUBLIC LICENSE"
# A URL to refer people to when problems occur with this mod # A URL to refer people to when problems occur with this mod
issueTrackerURL="https://bitbucket.org/Requios/effortless-building/issues?status=new&status=open" #optional issueTrackerURL="https://bitbucket.org/Requios/effortless-building/issues?status=new&status=open" #optional
# A list of mods - how many allowed here is determined by the individual mod loader # A list of mods - how many allowed here is determined by the individual mod loader
@@ -18,7 +13,7 @@ version="${file.jarVersion}" #mandatory
# A display name for the mod # A display name for the mod
displayName="Effortless Building" #mandatory displayName="Effortless Building" #mandatory
# A URL to query for updates for this mod. See the JSON update specification <here> # A URL to query for updates for this mod. See the JSON update specification <here>
updateJSONURL="http://myurl.me/" #optional #updateJSONURL="example.com" #optional
# A URL for the "homepage" for this mod, displayed in the mod UI # A URL for the "homepage" for this mod, displayed in the mod UI
displayURL="https://minecraft.curseforge.com/projects/effortless-building" #optional displayURL="https://minecraft.curseforge.com/projects/effortless-building" #optional
# A file name (in the root of the mod JAR) containing a logo for display # A file name (in the root of the mod JAR) containing a logo for display
@@ -29,24 +24,24 @@ credits="" #optional
authors="Requios" #optional authors="Requios" #optional
# The description text for the mod (multi line!) (#mandatory) # The description text for the mod (multi line!) (#mandatory)
description=''' description='''
Makes building easier by providing tools like mirrors, arrays, QuickReplace and a block randomizer. For survival and creative mode. Makes building easier by providing tools like mirrors, arrays, build modes and a block randomizer. For survival and creative mode.
''' '''
# A dependency - use the . to indicate dependency for a specific modid. Dependencies are optional. # A dependency - use the . to indicate dependency for a specific modid. Dependencies are optional.
#[[dependencies.examplemod]] #optional [[dependencies.examplemod]] #optional
# # the modid of the dependency # the modid of the dependency
# modId="forge" #mandatory modId="forge" #mandatory
# # Does this dependency have to exist - if not, ordering below must be specified # Does this dependency have to exist - if not, ordering below must be specified
# mandatory=true #mandatory mandatory=true #mandatory
# # The version range of the dependency # The version range of the dependency
# versionRange="[25,)" #mandatory versionRange="[34,)" #mandatory
# # An ordering relationship for the dependency - BEFORE or AFTER required if the relationship is not mandatory # An ordering relationship for the dependency - BEFORE or AFTER required if the relationship is not mandatory
# ordering="NONE" ordering="NONE"
# # Side this dependency is applied on - BOTH, CLIENT or SERVER # Side this dependency is applied on - BOTH, CLIENT or SERVER
# side="BOTH" side="BOTH"
## Here's another dependency # Here's another dependency
#[[dependencies.examplemod]] [[dependencies.examplemod]]
# modId="minecraft" modId="minecraft"
# mandatory=true mandatory=true
# versionRange="[1.13.2]" versionRange="[1.16.3,1.17)"
# ordering="NONE" ordering="NONE"
# side="BOTH" side="BOTH"

View File

@@ -1,24 +1,25 @@
{ {
"effortlessbuilding.screen.modifier_settings": "Modifier Settings", "effortlessbuilding.screen.modifier_settings": "Modifier Settings",
"effortlessbuilding.screen.radial_menu": "Build Modes", "effortlessbuilding.screen.radial_menu": "Build Modes",
"effortlessbuilding.screen.randomizer_bag": "Randomizer Bag", "effortlessbuilding.screen.player_settings": "Player Settings",
"key.effortlessbuilding.category": "Effortless Building", "key.effortlessbuilding.category": "Effortless Building",
"key.effortlessbuilding.hud.desc": "Modifier Menu", "key.effortlessbuilding.hud.desc": "Modifier Menu",
"key.effortlessbuilding.replace.desc": "Toggle QuickReplace", "key.effortlessbuilding.replace.desc": "Toggle QuickReplace",
"key.effortlessbuilding.creative.desc": "Toggle Survival/Creative Mode",
"key.effortlessbuilding.mode.desc": "Radial Menu", "key.effortlessbuilding.mode.desc": "Radial Menu",
"key.effortlessbuilding.undo.desc": "Undo", "key.effortlessbuilding.undo.desc": "Undo",
"key.effortlessbuilding.redo.desc": "Redo", "key.effortlessbuilding.redo.desc": "Redo",
"key.effortlessbuilding.altplacement.desc": "Alternative placement", "key.effortlessbuilding.altplacement.desc": "Alternative placement",
"effortlessbuilding:randomizer_bag": "Randomizer Bag", "effortlessbuilding:randomizer_bag": "Leather Randomizer Bag",
"effortlessbuilding:golden_randomizer_bag": "Golden Randomizer Bag",
"effortlessbuilding:diamond_randomizer_bag": "Diamond Randomizer Bag",
"effortlessbuilding:reach_upgrade1": "Reach Upgrade 1", "effortlessbuilding:reach_upgrade1": "Reach Upgrade 1",
"effortlessbuilding:reach_upgrade2": "Reach Upgrade 2", "effortlessbuilding:reach_upgrade2": "Reach Upgrade 2",
"effortlessbuilding:reach_upgrade3": "Reach Upgrade 3", "effortlessbuilding:reach_upgrade3": "Reach Upgrade 3",
"effortlessbuilding.mode.normal": "Normal", "effortlessbuilding.mode.normal": "Disable",
"effortlessbuilding.mode.normal_plus": "Normal+", "effortlessbuilding.mode.normal_plus": "Single",
"effortlessbuilding.mode.line": "Line", "effortlessbuilding.mode.line": "Line",
"effortlessbuilding.mode.wall": "Wall", "effortlessbuilding.mode.wall": "Wall",
"effortlessbuilding.mode.floor": "Floor", "effortlessbuilding.mode.floor": "Floor",
@@ -29,11 +30,31 @@
"effortlessbuilding.mode.circle": "Circle", "effortlessbuilding.mode.circle": "Circle",
"effortlessbuilding.mode.cylinder": "Cylinder", "effortlessbuilding.mode.cylinder": "Cylinder",
"effortlessbuilding.mode.sphere": "Sphere", "effortlessbuilding.mode.sphere": "Sphere",
"effortlessbuilding.mode.pyramid": "Pyramid",
"effortlessbuilding.mode.cone": "Cone",
"effortlessbuilding.mode.dome": "Dome",
"effortlessbuilding.modedescription.normal": "Disable mod and use vanilla placement rules",
"effortlessbuilding.modedescription.normal_plus": "Like vanilla, but with increased reach and placement preview",
"effortlessbuilding.modedescription.line": "",
"effortlessbuilding.modedescription.wall": "",
"effortlessbuilding.modedescription.floor": "",
"effortlessbuilding.modedescription.diagonal_line": "",
"effortlessbuilding.modedescription.diagonal_wall": "",
"effortlessbuilding.modedescription.slope_floor": "",
"effortlessbuilding.modedescription.cube": "",
"effortlessbuilding.modedescription.circle": "",
"effortlessbuilding.modedescription.cylinder": "",
"effortlessbuilding.modedescription.sphere": "",
"effortlessbuilding.modedescription.pyramid": "",
"effortlessbuilding.modedescription.cone": "",
"effortlessbuilding.modedescription.dome": "",
"effortlessbuilding.action.undo": "Undo", "effortlessbuilding.action.undo": "Undo",
"effortlessbuilding.action.redo": "Redo", "effortlessbuilding.action.redo": "Redo",
"effortlessbuilding.action.replace": "Replace", "effortlessbuilding.action.replace": "Replace",
"effortlessbuilding.action.open_modifier_settings": "Open Modifier Settings", "effortlessbuilding.action.open_modifier_settings": "Open Modifier Settings",
"effortlessbuilding.action.open_player_settings": "Open Settings",
"effortlessbuilding.action.build_speed": "Build Speed", "effortlessbuilding.action.build_speed": "Build Speed",
"effortlessbuilding.action.filling": "Filling", "effortlessbuilding.action.filling": "Filling",

View File

@@ -0,0 +1,79 @@
{
"efortlessbuilding.screen.modifier_settings": "Настройки модификатора",
"efortlessbuilding.screen.radial_menu": "Режимы строительства",
"efortlessbuilding.screen.player_settings": "Настройки игрока",
"key.efortlessbuilding.category": "Строительство без усилий",
"key.efortlessbuilding.hud.desc": "Меню модификаторов",
"key.effortlessbuilding.replace.desc": "Переключить быструю замену",
"key.efortlessbuilding.mode.desc": "Круговое меню",
"key.efortlessbuilding.undo.desc": "Отменить",
"key.effortlessbuilding.redo.desc": "Повторить",
"key.efortlessbuilding.altplacement.desc": "Альтернативное размещение",
"efortlessbuilding:randomizer_bag": "Кожаная сумка рандомизатора",
"efortlessbuilding:golden_randomizer_bag": "Золотой мешок рандомизатора",
"efortlessbuilding:diamond_randomizer_bag": "Бриллиантовый рандомизатор",
"efortlessbuilding:reach_upgrade1": "Достичь улучшения 1",
"efortlessbuilding:reach_upgrade2": "Достичь улучшения 2",
"efortlessbuilding:reach_upgrade3": "Достичь улучшения 3",
"efortlessbuilding.mode.normal": "Отключить",
"efortlessbuilding.mode.normal_plus": "Одиночный",
"efortlessbuilding.mode.line": "Линия",
"efortlessbuilding.mode.wall": "Стена",
"efortlessbuilding.mode.floor": "Этаж",
"efortlessbuilding.mode.diagonal_line": "Диагональная линия",
"efortlessbuilding.mode.diagonal_wall": "Диагональная стена",
"effortlessbuilding.mode.slope_floor": "Наклонный этаж",
"effortlessbuilding.mode.cube": "Куб",
"efortlessbuilding.mode.circle": "Круг",
"efortlessbuilding.mode.cylinder": "Цилиндр",
"efortlessbuilding.mode.sphere": "Сфера",
"efortlessbuilding.mode.pyramid": "Пирамида",
"effortlessbuilding.mode.cone": "Конус",
"efortlessbuilding.mode.dome": "Купол",
"effortlessbuilding.modedescription.normal": "Отключить мод и использовать ванильные правила размещения",
"effortlessbuilding.modedescription.normal_plus": "Как и ваниль, но с увеличенным охватом и предварительным просмотром места размещения",
"efortlessbuilding.modedescription.line": "",
"efortlessbuilding.modedescription.wall": "",
"efortlessbuilding.modedescription.floor": "",
"efortlessbuilding.modedescription.diagonal_line": "",
"efortlessbuilding.modedescription.diagonal_wall": "",
"effortlessbuilding.modedescription.slope_floor": "",
"efortlessbuilding.modedescription.cube": "",
"efortlessbuilding.modedescription.circle": "",
"efortlessbuilding.modedescription.cylinder": "",
"efortlessbuilding.modedescription.sphere": "",
"efortlessbuilding.modedescription.pyramid": "",
"efortlessbuilding.modedescription.cone": "",
"efortlessbuilding.modedescription.dome": "",
"efortlessbuilding.action.undo": "Отменить",
"efortlessbuilding.action.redo": "Повторить",
"efortlessbuilding.action.replace": "Заменить",
"efortlessbuilding.action.open_modifier_settings": "Открыть настройки модификатора",
"efortlessbuilding.action.open_player_settings": "Открыть настройки",
"efortlessbuilding.action.build_speed": "Скорость сборки",
"efortlessbuilding.action.filling": "Заполнение",
"efortlessbuilding.action.raised_edge": "Приподнятый край",
"efortlessbuilding.action.thickness": "Толщина линии",
"efortlessbuilding.action.circle_start": "Начальная точка",
"efortlessbuilding.action.normal_speed": "Нормальный",
"efortlessbuilding.action.fast_speed": "Быстро",
"efortlessbuilding.action.full": "Заполнено",
"efortlessbuilding.action.hollow": "Пустой",
"efortlessbuilding.action.skeleton": "Скелет",
"efortlessbuilding.action.short_edge": "Короткая кромка",
"efortlessbuilding.action.long_edge": "Длинный край",
"efortlessbuilding.action.thickness_1": "Толщиной 1 блок",
"efortlessbuilding.action.thickness_3": "Толщиной 3 блока",
"efortlessbuilding.action.thickness_5": "Толщиной 5 блоков",
"efortlessbuilding.action.start_center": "Посередине",
"efortlessbuilding.action.start_corner": "Угол",
"commands.reach.usage": "/reach <уровень>"
}

View File

@@ -0,0 +1,6 @@
{
"parent": "item/generated",
"textures": {
"layer0": "effortlessbuilding:items/diamondrandomizerbag"
}
}

View File

@@ -0,0 +1,6 @@
{
"parent": "item/generated",
"textures": {
"layer0": "effortlessbuilding:items/goldenrandomizerbag"
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 920 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 10 KiB

Some files were not shown because too many files have changed in this diff Show More