From 63e2e4828e59f6e57a4fa0783e3b61b2009d9f3b Mon Sep 17 00:00:00 2001 From: CantWeAllDisagree Date: Fri, 5 May 2023 18:32:04 -0400 Subject: [PATCH 1/3] Updated to 1.19.2 --- .gitignore | 37 + LICENSE | 631 ++++++++++++++++++ build.gradle | 101 +++ gradle.properties | 17 + gradle/wrapper/gradle-wrapper.jar | Bin 0 -> 61574 bytes gradle/wrapper/gradle-wrapper.properties | 6 + gradlew | 244 +++++++ gradlew.bat | 92 +++ settings.gradle | 9 + .../com/dainxt/weaponthrow/ClientMod.java | 24 + .../weaponthrow/ModMenuIntegration.java | 19 + .../com/dainxt/weaponthrow/WeaponThrow.java | 101 +-- .../capabilities/PlayerThrowData.java | 64 ++ .../weaponthrow/config/WeaponThrowConfig.java | 316 +++------ .../enchantment/ConccusionEnchantment.java | 26 +- .../enchantment/GravityEnchantment.java | 26 +- .../enchantment/GroundedEdgeEnchantment.java | 18 +- .../enchantment/ReturnEnchantment.java | 22 +- .../enchantment/ThrowEnchantment.java | 24 +- .../entity/render/WeaponThrowRenderer.java | 102 +-- .../weaponthrow/events/OnApplySlow.java | 19 + .../weaponthrow/events/OnFOVUpdate.java | 23 + .../weaponthrow/events/OnHeldItemRender.java | 23 + .../events/OnStartPlayerRender.java | 19 + .../weaponthrow/events/OnStartPlayerTick.java | 18 + .../weaponthrow/handlers/ConfigRegistry.java | 18 + .../handlers/EnchantmentHandler.java | 28 +- .../weaponthrow/handlers/EntityRegistry.java | 24 + .../weaponthrow/handlers/EventsHandler.java | 616 +++++++---------- .../handlers/KeyBindingHandler.java | 22 +- .../weaponthrow/handlers/PacketHandler.java | 68 +- .../weaponthrow/handlers/RenderRegistry.java | 13 + .../interfaces/IPlayerEntityMixin.java | 9 + .../mixins/IPlayerEntityMixin.java | 9 + .../weaponthrow/mixins/PlayerEntityMixin.java | 33 + .../AbstractClientPlayerEntityMixin.java | 27 + .../client/ClientPlayerEntityMixin.java | 18 + .../mixins/client/HeldItemRendererMixin.java | 23 + .../client/PlayerEntityRendererMixin.java | 19 + .../weaponthrow/packets/BasePacket.java | 25 + .../weaponthrow/packets/CPacketThrow.java | 59 +- .../packets/EntitySpawnPacket.java | 136 ++++ .../weaponthrow/packets/SPacketThrow.java | 42 +- .../projectile/WeaponThrowEntity.java | 540 ++++++++------- .../resources/assets/weaponthrow/icon.png | Bin 0 -> 11542 bytes .../assets/weaponthrow/lang/en_us.json | 92 +++ .../assets/weaponthrow/lang/zh_cn.json | 12 + src/main/resources/fabric.mod.json | 46 ++ src/main/resources/weaponthrow.mixins.json | 18 + 49 files changed, 2760 insertions(+), 1118 deletions(-) create mode 100644 .gitignore create mode 100644 LICENSE create mode 100644 build.gradle create mode 100644 gradle.properties create mode 100644 gradle/wrapper/gradle-wrapper.jar create mode 100644 gradle/wrapper/gradle-wrapper.properties create mode 100644 gradlew create mode 100644 gradlew.bat create mode 100644 settings.gradle create mode 100644 src/main/java/com/dainxt/weaponthrow/ClientMod.java create mode 100644 src/main/java/com/dainxt/weaponthrow/ModMenuIntegration.java create mode 100644 src/main/java/com/dainxt/weaponthrow/capabilities/PlayerThrowData.java create mode 100644 src/main/java/com/dainxt/weaponthrow/events/OnApplySlow.java create mode 100644 src/main/java/com/dainxt/weaponthrow/events/OnFOVUpdate.java create mode 100644 src/main/java/com/dainxt/weaponthrow/events/OnHeldItemRender.java create mode 100644 src/main/java/com/dainxt/weaponthrow/events/OnStartPlayerRender.java create mode 100644 src/main/java/com/dainxt/weaponthrow/events/OnStartPlayerTick.java create mode 100644 src/main/java/com/dainxt/weaponthrow/handlers/ConfigRegistry.java create mode 100644 src/main/java/com/dainxt/weaponthrow/handlers/EntityRegistry.java create mode 100644 src/main/java/com/dainxt/weaponthrow/handlers/RenderRegistry.java create mode 100644 src/main/java/com/dainxt/weaponthrow/interfaces/IPlayerEntityMixin.java create mode 100644 src/main/java/com/dainxt/weaponthrow/mixins/IPlayerEntityMixin.java create mode 100644 src/main/java/com/dainxt/weaponthrow/mixins/PlayerEntityMixin.java create mode 100644 src/main/java/com/dainxt/weaponthrow/mixins/client/AbstractClientPlayerEntityMixin.java create mode 100644 src/main/java/com/dainxt/weaponthrow/mixins/client/ClientPlayerEntityMixin.java create mode 100644 src/main/java/com/dainxt/weaponthrow/mixins/client/HeldItemRendererMixin.java create mode 100644 src/main/java/com/dainxt/weaponthrow/mixins/client/PlayerEntityRendererMixin.java create mode 100644 src/main/java/com/dainxt/weaponthrow/packets/BasePacket.java create mode 100644 src/main/java/com/dainxt/weaponthrow/packets/EntitySpawnPacket.java create mode 100644 src/main/resources/assets/weaponthrow/icon.png create mode 100644 src/main/resources/assets/weaponthrow/lang/en_us.json create mode 100644 src/main/resources/assets/weaponthrow/lang/zh_cn.json create mode 100644 src/main/resources/fabric.mod.json create mode 100644 src/main/resources/weaponthrow.mixins.json diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..6d68846 --- /dev/null +++ b/.gitignore @@ -0,0 +1,37 @@ +# gradle + +.gradle/ +build/ +out/ +classes/ + +# eclipse + +*.launch + +# idea + +.idea/ +*.iml +*.ipr +*.iws + +# vscode + +.settings/ +.vscode/ +bin/ +.classpath +.project + +# macos + +*.DS_Store + +# fabric + +run/ +/logs/ +/minecraft/ +/minecraft/* +/minepkg-lock.toml diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..564be7b --- /dev/null +++ b/LICENSE @@ -0,0 +1,631 @@ +Copyright (c) 2023 + +This program is free software: you can redistribute it and/or modify +it under the terms of the GNU Affero General Public License as published by +the Free Software Foundation, version 3 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU Affero General Public License for more details. + + GNU AFFERO GENERAL PUBLIC LICENSE + Version 3, 19 November 2007 + + Copyright (C) 2007 Free Software Foundation, Inc. + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + Preamble + + The GNU Affero General Public License is a free, copyleft license for +software and other kinds of works, specifically designed to ensure +cooperation with the community in the case of network server software. + + The licenses for most software and other practical works are designed +to take away your freedom to share and change the works. By contrast, +our General Public Licenses are intended to guarantee your freedom to +share and change all versions of a program--to make sure it remains free +software for all its users. + + When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +them if you wish), that you receive source code or can get it if you +want it, that you can change the software or use pieces of it in new +free programs, and that you know you can do these things. + + Developers that use our General Public Licenses protect your rights +with two steps: (1) assert copyright on the software, and (2) offer +you this License which gives you legal permission to copy, distribute +and/or modify the software. + + A secondary benefit of defending all users' freedom is that +improvements made in alternate versions of the program, if they +receive widespread use, become available for other developers to +incorporate. Many developers of free software are heartened and +encouraged by the resulting cooperation. However, in the case of +software used on network servers, this result may fail to come about. +The GNU General Public License permits making a modified version and +letting the public access it on a server without ever releasing its +source code to the public. + + The GNU Affero General Public License is designed specifically to +ensure that, in such cases, the modified source code becomes available +to the community. It requires the operator of a network server to +provide the source code of the modified version running there to the +users of that server. Therefore, public use of a modified version, on +a publicly accessible server, gives the public access to the source +code of the modified version. + + An older license, called the Affero General Public License and +published by Affero, was designed to accomplish similar goals. This is +a different license, not a version of the Affero GPL, but Affero has +released a new version of the Affero GPL which permits relicensing under +this license. + + The precise terms and conditions for copying, distribution and +modification follow. + + TERMS AND CONDITIONS + + 0. Definitions. + + "This License" refers to version 3 of the GNU Affero General Public License. + + "Copyright" also means copyright-like laws that apply to other kinds of +works, such as semiconductor masks. + + "The Program" refers to any copyrightable work licensed under this +License. Each licensee is addressed as "you". "Licensees" and +"recipients" may be individuals or organizations. + + To "modify" a work means to copy from or adapt all or part of the work +in a fashion requiring copyright permission, other than the making of an +exact copy. The resulting work is called a "modified version" of the +earlier work or a work "based on" the earlier work. + + A "covered work" means either the unmodified Program or a work based +on the Program. + + To "propagate" a work means to do anything with it that, without +permission, would make you directly or secondarily liable for +infringement under applicable copyright law, except executing it on a +computer or modifying a private copy. Propagation includes copying, +distribution (with or without modification), making available to the +public, and in some countries other activities as well. + + To "convey" a work means any kind of propagation that enables other +parties to make or receive copies. Mere interaction with a user through +a computer network, with no transfer of a copy, is not conveying. + + An interactive user interface displays "Appropriate Legal Notices" +to the extent that it includes a convenient and prominently visible +feature that (1) displays an appropriate copyright notice, and (2) +tells the user that there is no warranty for the work (except to the +extent that warranties are provided), that licensees may convey the +work under this License, and how to view a copy of this License. If +the interface presents a list of user commands or options, such as a +menu, a prominent item in the list meets this criterion. + + 1. Source Code. + + The "source code" for a work means the preferred form of the work +for making modifications to it. "Object code" means any non-source +form of a work. + + A "Standard Interface" means an interface that either is an official +standard defined by a recognized standards body, or, in the case of +interfaces specified for a particular programming language, one that +is widely used among developers working in that language. + + The "System Libraries" of an executable work include anything, other +than the work as a whole, that (a) is included in the normal form of +packaging a Major Component, but which is not part of that Major +Component, and (b) serves only to enable use of the work with that +Major Component, or to implement a Standard Interface for which an +implementation is available to the public in source code form. A +"Major Component", in this context, means a major essential component +(kernel, window system, and so on) of the specific operating system +(if any) on which the executable work runs, or a compiler used to +produce the work, or an object code interpreter used to run it. + + The "Corresponding Source" for a work in object code form means all +the source code needed to generate, install, and (for an executable +work) run the object code and to modify the work, including scripts to +control those activities. However, it does not include the work's +System Libraries, or general-purpose tools or generally available free +programs which are used unmodified in performing those activities but +which are not part of the work. For example, Corresponding Source +includes interface definition files associated with source files for +the work, and the source code for shared libraries and dynamically +linked subprograms that the work is specifically designed to require, +such as by intimate data communication or control flow between those +subprograms and other parts of the work. + + The Corresponding Source need not include anything that users +can regenerate automatically from other parts of the Corresponding +Source. + + The Corresponding Source for a work in source code form is that +same work. + + 2. Basic Permissions. + + All rights granted under this License are granted for the term of +copyright on the Program, and are irrevocable provided the stated +conditions are met. This License explicitly affirms your unlimited +permission to run the unmodified Program. The output from running a +covered work is covered by this License only if the output, given its +content, constitutes a covered work. This License acknowledges your +rights of fair use or other equivalent, as provided by copyright law. + + You may make, run and propagate covered works that you do not +convey, without conditions so long as your license otherwise remains +in force. You may convey covered works to others for the sole purpose +of having them make modifications exclusively for you, or provide you +with facilities for running those works, provided that you comply with +the terms of this License in conveying all material for which you do +not control copyright. Those thus making or running the covered works +for you must do so exclusively on your behalf, under your direction +and control, on terms that prohibit them from making any copies of +your copyrighted material outside their relationship with you. + + Conveying under any other circumstances is permitted solely under +the conditions stated below. Sublicensing is not allowed; section 10 +makes it unnecessary. + + 3. Protecting Users' Legal Rights From Anti-Circumvention Law. + + No covered work shall be deemed part of an effective technological +measure under any applicable law fulfilling obligations under article +11 of the WIPO copyright treaty adopted on 20 December 1996, or +similar laws prohibiting or restricting circumvention of such +measures. + + When you convey a covered work, you waive any legal power to forbid +circumvention of technological measures to the extent such circumvention +is effected by exercising rights under this License with respect to +the covered work, and you disclaim any intention to limit operation or +modification of the work as a means of enforcing, against the work's +users, your or third parties' legal rights to forbid circumvention of +technological measures. + + 4. Conveying Verbatim Copies. + + You may convey verbatim copies of the Program's source code as you +receive it, in any medium, provided that you conspicuously and +appropriately publish on each copy an appropriate copyright notice; +keep intact all notices stating that this License and any +non-permissive terms added in accord with section 7 apply to the code; +keep intact all notices of the absence of any warranty; and give all +recipients a copy of this License along with the Program. + + You may charge any price or no price for each copy that you convey, +and you may offer support or warranty protection for a fee. + + 5. Conveying Modified Source Versions. + + You may convey a work based on the Program, or the modifications to +produce it from the Program, in the form of source code under the +terms of section 4, provided that you also meet all of these conditions: + + a) The work must carry prominent notices stating that you modified + it, and giving a relevant date. + + b) The work must carry prominent notices stating that it is + released under this License and any conditions added under section + 7. This requirement modifies the requirement in section 4 to + "keep intact all notices". + + c) You must license the entire work, as a whole, under this + License to anyone who comes into possession of a copy. This + License will therefore apply, along with any applicable section 7 + additional terms, to the whole of the work, and all its parts, + regardless of how they are packaged. This License gives no + permission to license the work in any other way, but it does not + invalidate such permission if you have separately received it. + + d) If the work has interactive user interfaces, each must display + Appropriate Legal Notices; however, if the Program has interactive + interfaces that do not display Appropriate Legal Notices, your + work need not make them do so. + + A compilation of a covered work with other separate and independent +works, which are not by their nature extensions of the covered work, +and which are not combined with it such as to form a larger program, +in or on a volume of a storage or distribution medium, is called an +"aggregate" if the compilation and its resulting copyright are not +used to limit the access or legal rights of the compilation's users +beyond what the individual works permit. Inclusion of a covered work +in an aggregate does not cause this License to apply to the other +parts of the aggregate. + + 6. Conveying Non-Source Forms. + + You may convey a covered work in object code form under the terms +of sections 4 and 5, provided that you also convey the +machine-readable Corresponding Source under the terms of this License, +in one of these ways: + + a) Convey the object code in, or embodied in, a physical product + (including a physical distribution medium), accompanied by the + Corresponding Source fixed on a durable physical medium + customarily used for software interchange. + + b) Convey the object code in, or embodied in, a physical product + (including a physical distribution medium), accompanied by a + written offer, valid for at least three years and valid for as + long as you offer spare parts or customer support for that product + model, to give anyone who possesses the object code either (1) a + copy of the Corresponding Source for all the software in the + product that is covered by this License, on a durable physical + medium customarily used for software interchange, for a price no + more than your reasonable cost of physically performing this + conveying of source, or (2) access to copy the + Corresponding Source from a network server at no charge. + + c) Convey individual copies of the object code with a copy of the + written offer to provide the Corresponding Source. This + alternative is allowed only occasionally and noncommercially, and + only if you received the object code with such an offer, in accord + with subsection 6b. + + d) Convey the object code by offering access from a designated + place (gratis or for a charge), and offer equivalent access to the + Corresponding Source in the same way through the same place at no + further charge. You need not require recipients to copy the + Corresponding Source along with the object code. If the place to + copy the object code is a network server, the Corresponding Source + may be on a different server (operated by you or a third party) + that supports equivalent copying facilities, provided you maintain + clear directions next to the object code saying where to find the + Corresponding Source. Regardless of what server hosts the + Corresponding Source, you remain obligated to ensure that it is + available for as long as needed to satisfy these requirements. + + e) Convey the object code using peer-to-peer transmission, provided + you inform other peers where the object code and Corresponding + Source of the work are being offered to the general public at no + charge under subsection 6d. + + A separable portion of the object code, whose source code is excluded +from the Corresponding Source as a System Library, need not be +included in conveying the object code work. + + A "User Product" is either (1) a "consumer product", which means any +tangible personal property which is normally used for personal, family, +or household purposes, or (2) anything designed or sold for incorporation +into a dwelling. In determining whether a product is a consumer product, +doubtful cases shall be resolved in favor of coverage. For a particular +product received by a particular user, "normally used" refers to a +typical or common use of that class of product, regardless of the status +of the particular user or of the way in which the particular user +actually uses, or expects or is expected to use, the product. A product +is a consumer product regardless of whether the product has substantial +commercial, industrial or non-consumer uses, unless such uses represent +the only significant mode of use of the product. + + "Installation Information" for a User Product means any methods, +procedures, authorization keys, or other information required to install +and execute modified versions of a covered work in that User Product from +a modified version of its Corresponding Source. The information must +suffice to ensure that the continued functioning of the modified object +code is in no case prevented or interfered with solely because +modification has been made. + + If you convey an object code work under this section in, or with, or +specifically for use in, a User Product, and the conveying occurs as +part of a transaction in which the right of possession and use of the +User Product is transferred to the recipient in perpetuity or for a +fixed term (regardless of how the transaction is characterized), the +Corresponding Source conveyed under this section must be accompanied +by the Installation Information. But this requirement does not apply +if neither you nor any third party retains the ability to install +modified object code on the User Product (for example, the work has +been installed in ROM). + + The requirement to provide Installation Information does not include a +requirement to continue to provide support service, warranty, or updates +for a work that has been modified or installed by the recipient, or for +the User Product in which it has been modified or installed. Access to a +network may be denied when the modification itself materially and +adversely affects the operation of the network or violates the rules and +protocols for communication across the network. + + Corresponding Source conveyed, and Installation Information provided, +in accord with this section must be in a format that is publicly +documented (and with an implementation available to the public in +source code form), and must require no special password or key for +unpacking, reading or copying. + + 7. Additional Terms. + + "Additional permissions" are terms that supplement the terms of this +License by making exceptions from one or more of its conditions. +Additional permissions that are applicable to the entire Program shall +be treated as though they were included in this License, to the extent +that they are valid under applicable law. If additional permissions +apply only to part of the Program, that part may be used separately +under those permissions, but the entire Program remains governed by +this License without regard to the additional permissions. + + When you convey a copy of a covered work, you may at your option +remove any additional permissions from that copy, or from any part of +it. (Additional permissions may be written to require their own +removal in certain cases when you modify the work.) You may place +additional permissions on material, added by you to a covered work, +for which you have or can give appropriate copyright permission. + + Notwithstanding any other provision of this License, for material you +add to a covered work, you may (if authorized by the copyright holders of +that material) supplement the terms of this License with terms: + + a) Disclaiming warranty or limiting liability differently from the + terms of sections 15 and 16 of this License; or + + b) Requiring preservation of specified reasonable legal notices or + author attributions in that material or in the Appropriate Legal + Notices displayed by works containing it; or + + c) Prohibiting misrepresentation of the origin of that material, or + requiring that modified versions of such material be marked in + reasonable ways as different from the original version; or + + d) Limiting the use for publicity purposes of names of licensors or + authors of the material; or + + e) Declining to grant rights under trademark law for use of some + trade names, trademarks, or service marks; or + + f) Requiring indemnification of licensors and authors of that + material by anyone who conveys the material (or modified versions of + it) with contractual assumptions of liability to the recipient, for + any liability that these contractual assumptions directly impose on + those licensors and authors. + + All other non-permissive additional terms are considered "further +restrictions" within the meaning of section 10. If the Program as you +received it, or any part of it, contains a notice stating that it is +governed by this License along with a term that is a further +restriction, you may remove that term. If a license document contains +a further restriction but permits relicensing or conveying under this +License, you may add to a covered work material governed by the terms +of that license document, provided that the further restriction does +not survive such relicensing or conveying. + + If you add terms to a covered work in accord with this section, you +must place, in the relevant source files, a statement of the +additional terms that apply to those files, or a notice indicating +where to find the applicable terms. + + Additional terms, permissive or non-permissive, may be stated in the +form of a separately written license, or stated as exceptions; +the above requirements apply either way. + + 8. Termination. + + You may not propagate or modify a covered work except as expressly +provided under this License. Any attempt otherwise to propagate or +modify it is void, and will automatically terminate your rights under +this License (including any patent licenses granted under the third +paragraph of section 11). + + However, if you cease all violation of this License, then your +license from a particular copyright holder is reinstated (a) +provisionally, unless and until the copyright holder explicitly and +finally terminates your license, and (b) permanently, if the copyright +holder fails to notify you of the violation by some reasonable means +prior to 60 days after the cessation. + + Moreover, your license from a particular copyright holder is +reinstated permanently if the copyright holder notifies you of the +violation by some reasonable means, this is the first time you have +received notice of violation of this License (for any work) from that +copyright holder, and you cure the violation prior to 30 days after +your receipt of the notice. + + Termination of your rights under this section does not terminate the +licenses of parties who have received copies or rights from you under +this License. If your rights have been terminated and not permanently +reinstated, you do not qualify to receive new licenses for the same +material under section 10. + + 9. Acceptance Not Required for Having Copies. + + You are not required to accept this License in order to receive or +run a copy of the Program. Ancillary propagation of a covered work +occurring solely as a consequence of using peer-to-peer transmission +to receive a copy likewise does not require acceptance. However, +nothing other than this License grants you permission to propagate or +modify any covered work. These actions infringe copyright if you do +not accept this License. Therefore, by modifying or propagating a +covered work, you indicate your acceptance of this License to do so. + + 10. Automatic Licensing of Downstream Recipients. + + Each time you convey a covered work, the recipient automatically +receives a license from the original licensors, to run, modify and +propagate that work, subject to this License. You are not responsible +for enforcing compliance by third parties with this License. + + An "entity transaction" is a transaction transferring control of an +organization, or substantially all assets of one, or subdividing an +organization, or merging organizations. If propagation of a covered +work results from an entity transaction, each party to that +transaction who receives a copy of the work also receives whatever +licenses to the work the party's predecessor in interest had or could +give under the previous paragraph, plus a right to possession of the +Corresponding Source of the work from the predecessor in interest, if +the predecessor has it or can get it with reasonable efforts. + + You may not impose any further restrictions on the exercise of the +rights granted or affirmed under this License. For example, you may +not impose a license fee, royalty, or other charge for exercise of +rights granted under this License, and you may not initiate litigation +(including a cross-claim or counterclaim in a lawsuit) alleging that +any patent claim is infringed by making, using, selling, offering for +sale, or importing the Program or any portion of it. + + 11. Patents. + + A "contributor" is a copyright holder who authorizes use under this +License of the Program or a work on which the Program is based. The +work thus licensed is called the contributor's "contributor version". + + A contributor's "essential patent claims" are all patent claims +owned or controlled by the contributor, whether already acquired or +hereafter acquired, that would be infringed by some manner, permitted +by this License, of making, using, or selling its contributor version, +but do not include claims that would be infringed only as a +consequence of further modification of the contributor version. For +purposes of this definition, "control" includes the right to grant +patent sublicenses in a manner consistent with the requirements of +this License. + + Each contributor grants you a non-exclusive, worldwide, royalty-free +patent license under the contributor's essential patent claims, to +make, use, sell, offer for sale, import and otherwise run, modify and +propagate the contents of its contributor version. + + In the following three paragraphs, a "patent license" is any express +agreement or commitment, however denominated, not to enforce a patent +(such as an express permission to practice a patent or covenant not to +sue for patent infringement). To "grant" such a patent license to a +party means to make such an agreement or commitment not to enforce a +patent against the party. + + If you convey a covered work, knowingly relying on a patent license, +and the Corresponding Source of the work is not available for anyone +to copy, free of charge and under the terms of this License, through a +publicly available network server or other readily accessible means, +then you must either (1) cause the Corresponding Source to be so +available, or (2) arrange to deprive yourself of the benefit of the +patent license for this particular work, or (3) arrange, in a manner +consistent with the requirements of this License, to extend the patent +license to downstream recipients. "Knowingly relying" means you have +actual knowledge that, but for the patent license, your conveying the +covered work in a country, or your recipient's use of the covered work +in a country, would infringe one or more identifiable patents in that +country that you have reason to believe are valid. + + If, pursuant to or in connection with a single transaction or +arrangement, you convey, or propagate by procuring conveyance of, a +covered work, and grant a patent license to some of the parties +receiving the covered work authorizing them to use, propagate, modify +or convey a specific copy of the covered work, then the patent license +you grant is automatically extended to all recipients of the covered +work and works based on it. + + A patent license is "discriminatory" if it does not include within +the scope of its coverage, prohibits the exercise of, or is +conditioned on the non-exercise of one or more of the rights that are +specifically granted under this License. You may not convey a covered +work if you are a party to an arrangement with a third party that is +in the business of distributing software, under which you make payment +to the third party based on the extent of your activity of conveying +the work, and under which the third party grants, to any of the +parties who would receive the covered work from you, a discriminatory +patent license (a) in connection with copies of the covered work +conveyed by you (or copies made from those copies), or (b) primarily +for and in connection with specific products or compilations that +contain the covered work, unless you entered into that arrangement, +or that patent license was granted, prior to 28 March 2007. + + Nothing in this License shall be construed as excluding or limiting +any implied license or other defenses to infringement that may +otherwise be available to you under applicable patent law. + + 12. No Surrender of Others' Freedom. + + If conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot convey a +covered work so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you may +not convey it at all. For example, if you agree to terms that obligate you +to collect a royalty for further conveying from those to whom you convey +the Program, the only way you could satisfy both those terms and this +License would be to refrain entirely from conveying the Program. + + 13. Remote Network Interaction; Use with the GNU General Public License. + + Notwithstanding any other provision of this License, if you modify the +Program, your modified version must prominently offer all users +interacting with it remotely through a computer network (if your version +supports such interaction) an opportunity to receive the Corresponding +Source of your version by providing access to the Corresponding Source +from a network server at no charge, through some standard or customary +means of facilitating copying of software. This Corresponding Source +shall include the Corresponding Source for any work covered by version 3 +of the GNU General Public License that is incorporated pursuant to the +following paragraph. + + Notwithstanding any other provision of this License, you have +permission to link or combine any covered work with a work licensed +under version 3 of the GNU General Public License into a single +combined work, and to convey the resulting work. The terms of this +License will continue to apply to the part which is the covered work, +but the work with which it is combined will remain governed by version +3 of the GNU General Public License. + + 14. Revised Versions of this License. + + The Free Software Foundation may publish revised and/or new versions of +the GNU Affero General Public License from time to time. Such new versions +will be similar in spirit to the present version, but may differ in detail to +address new problems or concerns. + + Each version is given a distinguishing version number. If the +Program specifies that a certain numbered version of the GNU Affero General +Public License "or any later version" applies to it, you have the +option of following the terms and conditions either of that numbered +version or of any later version published by the Free Software +Foundation. If the Program does not specify a version number of the +GNU Affero General Public License, you may choose any version ever published +by the Free Software Foundation. + + If the Program specifies that a proxy can decide which future +versions of the GNU Affero General Public License can be used, that proxy's +public statement of acceptance of a version permanently authorizes you +to choose that version for the Program. + + Later license versions may give you additional or different +permissions. However, no additional obligations are imposed on any +author or copyright holder as a result of your choosing to follow a +later version. + + 15. Disclaimer of Warranty. + + THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY +APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT +HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY +OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, +THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM +IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF +ALL NECESSARY SERVICING, REPAIR OR CORRECTION. + + 16. Limitation of Liability. + + IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS +THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY +GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE +USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF +DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD +PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), +EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF +SUCH DAMAGES. + + 17. Interpretation of Sections 15 and 16. + + If the disclaimer of warranty and limitation of liability provided +above cannot be given local legal effect according to their terms, +reviewing courts shall apply local law that most closely approximates +an absolute waiver of all civil liability in connection with the +Program, unless a warranty or assumption of liability accompanies a +copy of the Program in return for a fee. + + END OF TERMS AND CONDITIONS diff --git a/build.gradle b/build.gradle new file mode 100644 index 0000000..18ea10e --- /dev/null +++ b/build.gradle @@ -0,0 +1,101 @@ +plugins { + id 'fabric-loom' version '1.1-SNAPSHOT' + id 'maven-publish' +} +sourceCompatibility = JavaVersion.VERSION_17 +targetCompatibility = JavaVersion.VERSION_17 + +archivesBaseName = project.archives_base_name +version = project.version +group = project.maven_group + +repositories { + maven { url "https://maven.shedaniel.me/" } + maven { + name = "TerraformersMC" + url = "https://maven.terraformersmc.com/" + } + // You should only use this when depending on other mods because + // Loom adds the essential maven repositories to download Minecraft and libraries from automatically. + // See https://docs.gradle.org/current/userguide/declaring_repositories.html + // for more information about repositories. +} + +dependencies { + // To change the versions see the gradle.properties file + minecraft "com.mojang:minecraft:${project.minecraft_version}" + mappings "net.fabricmc:yarn:${project.yarn_mappings}:v2" + modImplementation "net.fabricmc:fabric-loader:${project.loader_version}" + + // Fabric API. This is technically optional, but you probably want it anyway. + modImplementation "net.fabricmc.fabric-api:fabric-api:${project.fabric_version}" + + // ModMenu + modCompileOnly modRuntimeOnly("me.shedaniel.cloth:cloth-config-fabric:${project.cloth_config_version}") { + exclude group: "net.fabricmc.fabric-api" + } + modCompileOnly modRuntimeOnly ("com.terraformersmc:modmenu:${project.mod_menu_version}") { + exclude group: "net.fabricmc.fabric-api" + } + + } + +processResources { + inputs.property "version", project.version + inputs.property "minecraft_version", project.minecraft_version + inputs.property "loader_version", project.loader_version + filteringCharset "UTF-8" + + filesMatching("fabric.mod.json") { + expand "version": project.version, + "minecraft_version": project.minecraft_version, + "loader_version": project.loader_version + } +} + +def targetJavaVersion = 17 +tasks.withType(JavaCompile).configureEach { + // ensure that the encoding is set to UTF-8, no matter what the system default is + // this fixes some edge cases with special characters not displaying correctly + // see http://yodaconditions.net/blog/fix-for-java-file-encoding-problems-with-gradle.html + // If Javadoc is generated, this must be specified in that task too. + it.options.encoding = "UTF-8" + if (targetJavaVersion >= 10 || JavaVersion.current().isJava10Compatible()) { + it.options.release = targetJavaVersion + } +} + +java { + def javaVersion = JavaVersion.toVersion(targetJavaVersion) + if (JavaVersion.current() < javaVersion) { + toolchain.languageVersion = JavaLanguageVersion.of(targetJavaVersion) + } + archivesBaseName = project.archives_base_name + // Loom will automatically attach sourcesJar to a RemapSourcesJar task and to the "build" task + // if it is present. + // If you remove this line, sources will not be generated. + withSourcesJar() +} + +jar { + from("LICENSE") { + rename { "${it}_${project.archivesBaseName}"} + } +} + +// configure the maven publication +publishing { + publications { + mavenJava(MavenPublication) { + from components.java + } + } + + // See https://docs.gradle.org/current/userguide/publishing_maven.html for information on how to set up publishing. + repositories { + // Add repositories to publish to here. + // Notice: This block does NOT have the same function as the block in the top level. + // The repositories here will be used for publishing your artifact, not for + // retrieving dependencies. + } +} diff --git a/gradle.properties b/gradle.properties new file mode 100644 index 0000000..b3035f4 --- /dev/null +++ b/gradle.properties @@ -0,0 +1,17 @@ +# Done to increase the memory available to gradle. +org.gradle.jvmargs=-Xmx2G + +# Fabric Properties +minecraft_version=1.19.2 +yarn_mappings=1.19.2+build.28 +loader_version=0.14.12 + +# Mod Properties +version = 5.8-1.19.2 +maven_group = com.dainxt +archives_base_name = WeaponThrow + +# Dependencies +fabric_version=0.76.0+1.19.2 +cloth_config_version=8.2.88 +mod_menu_version=4.0.6 \ No newline at end of file diff --git a/gradle/wrapper/gradle-wrapper.jar b/gradle/wrapper/gradle-wrapper.jar new file mode 100644 index 0000000000000000000000000000000000000000..943f0cbfa754578e88a3dae77fce6e3dea56edbf GIT binary patch literal 61574 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 ScNgau(U?ep-K_E5zy1%ZQTdPn literal 0 HcmV?d00001 diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties new file mode 100644 index 0000000..0c85a1f --- /dev/null +++ b/gradle/wrapper/gradle-wrapper.properties @@ -0,0 +1,6 @@ +distributionBase=GRADLE_USER_HOME +distributionPath=wrapper/dists +distributionUrl=https\://services.gradle.org/distributions/gradle-8.1-bin.zip +networkTimeout=10000 +zipStoreBase=GRADLE_USER_HOME +zipStorePath=wrapper/dists diff --git a/gradlew b/gradlew new file mode 100644 index 0000000..65dcd68 --- /dev/null +++ b/gradlew @@ -0,0 +1,244 @@ +#!/bin/sh + +# +# Copyright © 2015-2021 the original 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. +# + +############################################################################## +# +# Gradle start up script for POSIX generated by Gradle. +# +# Important for running: +# +# (1) You need a POSIX-compliant shell to run this script. If your /bin/sh is +# noncompliant, but you have some other compliant shell such as ksh or +# bash, then to run this script, type that shell name before the whole +# command line, like: +# +# ksh Gradle +# +# Busybox and similar reduced shells will NOT work, because this script +# requires all of these POSIX shell features: +# * functions; +# * expansions «$var», «${var}», «${var:-default}», «${var+SET}», +# «${var#prefix}», «${var%suffix}», and «$( cmd )»; +# * compound commands having a testable exit status, especially «case»; +# * various built-in commands including «command», «set», and «ulimit». +# +# Important for patching: +# +# (2) This script targets any POSIX shell, so it avoids extensions provided +# by Bash, Ksh, etc; in particular arrays are avoided. +# +# The "traditional" practice of packing multiple parameters into a +# space-separated string is a well documented source of bugs and security +# problems, so this is (mostly) avoided, by progressively accumulating +# options in "$@", and eventually passing that to Java. +# +# Where the inherited environment variables (DEFAULT_JVM_OPTS, JAVA_OPTS, +# and GRADLE_OPTS) rely on word-splitting, this is performed explicitly; +# see the in-line comments for details. +# +# There are tweaks for specific operating systems such as AIX, CygWin, +# Darwin, MinGW, and NonStop. +# +# (3) This script is generated from the Groovy template +# https://github.com/gradle/gradle/blob/HEAD/subprojects/plugins/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt +# within the Gradle project. +# +# You can find Gradle at https://github.com/gradle/gradle/. +# +############################################################################## + +# Attempt to set APP_HOME + +# Resolve links: $0 may be a link +app_path=$0 + +# Need this for daisy-chained symlinks. +while + APP_HOME=${app_path%"${app_path##*/}"} # leaves a trailing /; empty if no leading path + [ -h "$app_path" ] +do + ls=$( ls -ld "$app_path" ) + link=${ls#*' -> '} + case $link in #( + /*) app_path=$link ;; #( + *) app_path=$APP_HOME$link ;; + esac +done + +# This is normally unused +# shellcheck disable=SC2034 +APP_BASE_NAME=${0##*/} +APP_HOME=$( cd "${APP_HOME:-./}" && pwd -P ) || exit + +# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. +DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"' + +# Use the maximum available, or set MAX_FD != -1 to use that value. +MAX_FD=maximum + +warn () { + echo "$*" +} >&2 + +die () { + echo + echo "$*" + echo + exit 1 +} >&2 + +# OS specific support (must be 'true' or 'false'). +cygwin=false +msys=false +darwin=false +nonstop=false +case "$( uname )" in #( + CYGWIN* ) cygwin=true ;; #( + Darwin* ) darwin=true ;; #( + MSYS* | MINGW* ) msys=true ;; #( + NONSTOP* ) nonstop=true ;; +esac + +CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar + + +# Determine the Java command to use to start the JVM. +if [ -n "$JAVA_HOME" ] ; then + if [ -x "$JAVA_HOME/jre/sh/java" ] ; then + # IBM's JDK on AIX uses strange locations for the executables + JAVACMD=$JAVA_HOME/jre/sh/java + else + JAVACMD=$JAVA_HOME/bin/java + fi + if [ ! -x "$JAVACMD" ] ; then + die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME + +Please set the JAVA_HOME variable in your environment to match the +location of your Java installation." + fi +else + JAVACMD=java + which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. + +Please set the JAVA_HOME variable in your environment to match the +location of your Java installation." +fi + +# Increase the maximum file descriptors if we can. +if ! "$cygwin" && ! "$darwin" && ! "$nonstop" ; then + case $MAX_FD in #( + max*) + # In POSIX sh, ulimit -H is undefined. That's why the result is checked to see if it worked. + # shellcheck disable=SC3045 + MAX_FD=$( ulimit -H -n ) || + warn "Could not query maximum file descriptor limit" + esac + case $MAX_FD in #( + '' | soft) :;; #( + *) + # In POSIX sh, ulimit -n is undefined. That's why the result is checked to see if it worked. + # shellcheck disable=SC3045 + ulimit -n "$MAX_FD" || + warn "Could not set maximum file descriptor limit to $MAX_FD" + esac +fi + +# Collect all arguments for the java command, stacking in reverse order: +# * args from the command line +# * the main class name +# * -classpath +# * -D...appname settings +# * --module-path (only if needed) +# * DEFAULT_JVM_OPTS, JAVA_OPTS, and GRADLE_OPTS environment variables. + +# For Cygwin or MSYS, switch paths to Windows format before running java +if "$cygwin" || "$msys" ; then + APP_HOME=$( cygpath --path --mixed "$APP_HOME" ) + CLASSPATH=$( cygpath --path --mixed "$CLASSPATH" ) + + JAVACMD=$( cygpath --unix "$JAVACMD" ) + + # Now convert the arguments - kludge to limit ourselves to /bin/sh + for arg do + if + case $arg in #( + -*) false ;; # don't mess with options #( + /?*) t=${arg#/} t=/${t%%/*} # looks like a POSIX filepath + [ -e "$t" ] ;; #( + *) false ;; + esac + then + arg=$( cygpath --path --ignore --mixed "$arg" ) + fi + # Roll the args list around exactly as many times as the number of + # args, so each arg winds up back in the position where it started, but + # possibly modified. + # + # NB: a `for` loop captures its iteration list before it begins, so + # changing the positional parameters here affects neither the number of + # iterations, nor the values presented in `arg`. + shift # remove old arg + set -- "$@" "$arg" # push replacement arg + done +fi + +# Collect all arguments for the java command; +# * $DEFAULT_JVM_OPTS, $JAVA_OPTS, and $GRADLE_OPTS can contain fragments of +# shell script including quotes and variable substitutions, so put them in +# double quotes to make sure that they get re-expanded; and +# * put everything else in single quotes, so that it's not re-expanded. + +set -- \ + "-Dorg.gradle.appname=$APP_BASE_NAME" \ + -classpath "$CLASSPATH" \ + org.gradle.wrapper.GradleWrapperMain \ + "$@" + +# Stop when "xargs" is not available. +if ! command -v xargs >/dev/null 2>&1 +then + die "xargs is not available" +fi + +# Use "xargs" to parse quoted args. +# +# With -n1 it outputs one arg per line, with the quotes and backslashes removed. +# +# In Bash we could simply go: +# +# readarray ARGS < <( xargs -n1 <<<"$var" ) && +# set -- "${ARGS[@]}" "$@" +# +# but POSIX shell has neither arrays nor command substitution, so instead we +# post-process each arg (as a line of input to sed) to backslash-escape any +# character that might be a shell metacharacter, then use eval to reverse +# that process (while maintaining the separation between arguments), and wrap +# the whole thing up as a single "set" statement. +# +# This will of course break if any of these variables contains a newline or +# an unmatched quote. +# + +eval "set -- $( + printf '%s\n' "$DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS" | + xargs -n1 | + sed ' s~[^-[:alnum:]+,./:=@_]~\\&~g; ' | + tr '\n' ' ' + )" '"$@"' + +exec "$JAVACMD" "$@" diff --git a/gradlew.bat b/gradlew.bat new file mode 100644 index 0000000..93e3f59 --- /dev/null +++ b/gradlew.bat @@ -0,0 +1,92 @@ +@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 +@rem ########################################################################## +@rem +@rem Gradle startup script for Windows +@rem +@rem ########################################################################## + +@rem Set local scope for the variables with windows NT shell +if "%OS%"=="Windows_NT" setlocal + +set DIRNAME=%~dp0 +if "%DIRNAME%"=="" set DIRNAME=. +@rem This is normally unused +set APP_BASE_NAME=%~n0 +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. +set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m" + +@rem Find java.exe +if defined JAVA_HOME goto findJavaFromJavaHome + +set JAVA_EXE=java.exe +%JAVA_EXE% -version >NUL 2>&1 +if %ERRORLEVEL% equ 0 goto execute + +echo. +echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. +echo. +echo Please set the JAVA_HOME variable in your environment to match the +echo location of your Java installation. + +goto fail + +:findJavaFromJavaHome +set JAVA_HOME=%JAVA_HOME:"=% +set JAVA_EXE=%JAVA_HOME%/bin/java.exe + +if exist "%JAVA_EXE%" goto execute + +echo. +echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% +echo. +echo Please set the JAVA_HOME variable in your environment to match the +echo location of your Java installation. + +goto fail + +:execute +@rem Setup the command line + +set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar + + +@rem Execute Gradle +"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %* + +:end +@rem End local scope for the variables with windows NT shell +if %ERRORLEVEL% equ 0 goto mainEnd + +:fail +rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of +rem the _cmd.exe /c_ return code! +set EXIT_CODE=%ERRORLEVEL% +if %EXIT_CODE% equ 0 set EXIT_CODE=1 +if not ""=="%GRADLE_EXIT_CONSOLE%" exit %EXIT_CODE% +exit /b %EXIT_CODE% + +:mainEnd +if "%OS%"=="Windows_NT" endlocal + +:omega diff --git a/settings.gradle b/settings.gradle new file mode 100644 index 0000000..f91a4fe --- /dev/null +++ b/settings.gradle @@ -0,0 +1,9 @@ +pluginManagement { + repositories { + maven { + name = 'Fabric' + url = 'https://maven.fabricmc.net/' + } + gradlePluginPortal() + } +} diff --git a/src/main/java/com/dainxt/weaponthrow/ClientMod.java b/src/main/java/com/dainxt/weaponthrow/ClientMod.java new file mode 100644 index 0000000..8986ebd --- /dev/null +++ b/src/main/java/com/dainxt/weaponthrow/ClientMod.java @@ -0,0 +1,24 @@ +package com.dainxt.weaponthrow; + +import com.dainxt.weaponthrow.handlers.EventsHandler; +import com.dainxt.weaponthrow.handlers.KeyBindingHandler; +import com.dainxt.weaponthrow.handlers.PacketHandler; +import com.dainxt.weaponthrow.handlers.RenderRegistry; + +import net.fabricmc.api.ClientModInitializer; + +public class ClientMod implements ClientModInitializer{ + + @Override + public void onInitializeClient() { + + EventsHandler.registerClientEvents(); + + RenderRegistry.registerRenderers(); + + PacketHandler.registerClientListeners(); + + KeyBindingHandler.registerKeyBindings(); + } + +} diff --git a/src/main/java/com/dainxt/weaponthrow/ModMenuIntegration.java b/src/main/java/com/dainxt/weaponthrow/ModMenuIntegration.java new file mode 100644 index 0000000..afe5073 --- /dev/null +++ b/src/main/java/com/dainxt/weaponthrow/ModMenuIntegration.java @@ -0,0 +1,19 @@ +package com.dainxt.weaponthrow; + +import com.dainxt.weaponthrow.config.WeaponThrowConfig; +import com.terraformersmc.modmenu.api.ConfigScreenFactory; +import com.terraformersmc.modmenu.api.ModMenuApi; + +import me.shedaniel.autoconfig.AutoConfig; +import net.fabricmc.api.EnvType; +import net.fabricmc.api.Environment; + +@Environment(EnvType.CLIENT) +public class ModMenuIntegration implements ModMenuApi{ + + @Override + public ConfigScreenFactory getModConfigScreenFactory() { + return parent -> AutoConfig.getConfigScreen(WeaponThrowConfig.class, parent).get(); + } + +} diff --git a/src/main/java/com/dainxt/weaponthrow/WeaponThrow.java b/src/main/java/com/dainxt/weaponthrow/WeaponThrow.java index 9cad1ce..c2b76f1 100644 --- a/src/main/java/com/dainxt/weaponthrow/WeaponThrow.java +++ b/src/main/java/com/dainxt/weaponthrow/WeaponThrow.java @@ -3,87 +3,32 @@ import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; -import com.dainxt.weaponthrow.capabilities.ThrowCapability; -import com.dainxt.weaponthrow.capabilities.ThrowPower; -import com.dainxt.weaponthrow.config.WeaponThrowConfig; -import com.dainxt.weaponthrow.entity.render.WeaponThrowRenderer; -import com.dainxt.weaponthrow.handlers.EntityHandler; +import com.dainxt.weaponthrow.handlers.ConfigRegistry; +import com.dainxt.weaponthrow.handlers.EnchantmentHandler; +import com.dainxt.weaponthrow.handlers.EntityRegistry; import com.dainxt.weaponthrow.handlers.EventsHandler; -import com.dainxt.weaponthrow.handlers.KeyBindingHandler; import com.dainxt.weaponthrow.handlers.PacketHandler; -import com.dainxt.weaponthrow.interfaces.IThrowPower; -import com.dainxt.weaponthrow.util.Reference; -import net.minecraftforge.common.MinecraftForge; -import net.minecraftforge.common.capabilities.CapabilityManager; -import net.minecraftforge.eventbus.api.SubscribeEvent; -import net.minecraftforge.fml.ModLoadingContext; -import net.minecraftforge.fml.client.registry.ClientRegistry; -import net.minecraftforge.fml.client.registry.RenderingRegistry; -import net.minecraftforge.fml.common.Mod; -import net.minecraftforge.fml.config.ModConfig; -import net.minecraftforge.fml.event.lifecycle.FMLClientSetupEvent; -import net.minecraftforge.fml.event.lifecycle.FMLCommonSetupEvent; -import net.minecraftforge.fml.event.lifecycle.GatherDataEvent; -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.fabricmc.api.ModInitializer; -// The value here should match an entry in the META-INF/mods.toml file -@Mod(Reference.MODID) -public class WeaponThrow -{ +public class WeaponThrow implements ModInitializer { - public static final Logger LOGGER = LogManager.getLogger(); - - public WeaponThrow() { - - FMLJavaModLoadingContext.get().getModEventBus().addListener(this::setup); - FMLJavaModLoadingContext.get().getModEventBus().addListener(this::enqueueIMC); - FMLJavaModLoadingContext.get().getModEventBus().addListener(this::processIMC); - FMLJavaModLoadingContext.get().getModEventBus().addListener(this::doClientStuff); - FMLJavaModLoadingContext.get().getModEventBus().addListener(this::onGatherData); - - ModLoadingContext.get().registerConfig(ModConfig.Type.COMMON, WeaponThrowConfig.commonSpec); - FMLJavaModLoadingContext.get().getModEventBus().register(WeaponThrowConfig.class); - - MinecraftForge.EVENT_BUS.register(this); - MinecraftForge.EVENT_BUS.register(new EventsHandler()); - - } - - private void setup(final FMLCommonSetupEvent event) - { - CapabilityManager.INSTANCE.register(IThrowPower.class, new ThrowCapability(), ()->{ - return new ThrowPower(); - }); - PacketHandler.init(); - } - - private void doClientStuff(final FMLClientSetupEvent event) { - ClientRegistry.registerKeyBinding(KeyBindingHandler.KEYBINDING); - RenderingRegistry.registerEntityRenderingHandler(EntityHandler.WEAPONTHROW, new WeaponThrowRenderer.RenderFactory()); - } - - private void enqueueIMC(final InterModEnqueueEvent event) - { - - } - - private void processIMC(final InterModProcessEvent event) - { - - } - - @SubscribeEvent - public void onServerStarting(FMLServerStartingEvent event) { - - } - - public void onGatherData(final GatherDataEvent event) { - - - } - + public static final Logger LOGGER = LogManager.getLogger(); + + public static final String MODID = "weaponthrow"; + + @Override + public void onInitialize() { + + ConfigRegistry.registerConfig(); + + EntityRegistry.registerEntities(); + + EventsHandler.registerEvents(); + + PacketHandler.registerServerListeners(); + + EnchantmentHandler.registerEnchantments(); + + } } diff --git a/src/main/java/com/dainxt/weaponthrow/capabilities/PlayerThrowData.java b/src/main/java/com/dainxt/weaponthrow/capabilities/PlayerThrowData.java new file mode 100644 index 0000000..9c90a69 --- /dev/null +++ b/src/main/java/com/dainxt/weaponthrow/capabilities/PlayerThrowData.java @@ -0,0 +1,64 @@ +package com.dainxt.weaponthrow.capabilities; + +import com.dainxt.weaponthrow.handlers.ConfigRegistry; +import com.dainxt.weaponthrow.packets.CPacketThrow; +import com.dainxt.weaponthrow.packets.CPacketThrow.State; + +import net.minecraft.entity.player.PlayerEntity; +import net.minecraft.item.ItemStack; +import net.minecraft.util.math.MathHelper; + +public class PlayerThrowData { + + //Client + public int MAX_CHARGE = -1; + + //Both + CPacketThrow.State action = CPacketThrow.State.NONE; + + //Server + int chargeTime = -1; + + ItemStack item = ItemStack.EMPTY; + + PlayerEntity user; + + public PlayerThrowData(PlayerEntity player) { + this.user = player; + } + + public void setAction(CPacketThrow.State action) { + this.action = action; + } + + public State getAction() { + return this.action; + } + + public int getChargeTime() { + return chargeTime; + } + + public void startCharging(ItemStack stack) { + this.item=stack.copy(); + chargeTime = PlayerThrowData.getMaximumCharge(user); + } + + public ItemStack getChargingStack() { + return item; + } + + public void resetCharging() { + this.action = this.action.equals(State.DURING) ? State.FINISH : this.action; + this.item = ItemStack.EMPTY; + chargeTime = -1; + } + + public void setChargeTime(int ticks) { + chargeTime = ticks; + } + + public static int getMaximumCharge(PlayerEntity player) { + return MathHelper.floor(player.getAttackCooldownProgressPerTick()*ConfigRegistry.COMMON.get().times.castTimeMuliplier); + } +} diff --git a/src/main/java/com/dainxt/weaponthrow/config/WeaponThrowConfig.java b/src/main/java/com/dainxt/weaponthrow/config/WeaponThrowConfig.java index 7b9773a..feb34e3 100644 --- a/src/main/java/com/dainxt/weaponthrow/config/WeaponThrowConfig.java +++ b/src/main/java/com/dainxt/weaponthrow/config/WeaponThrowConfig.java @@ -1,216 +1,122 @@ package com.dainxt.weaponthrow.config; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.List; +import com.dainxt.weaponthrow.WeaponThrow; -import org.apache.commons.lang3.tuple.Pair; +import me.shedaniel.autoconfig.ConfigData; +import me.shedaniel.autoconfig.annotation.Config; +import me.shedaniel.autoconfig.annotation.ConfigEntry; -import net.minecraft.block.Block; -import net.minecraft.item.Item; -import net.minecraft.item.Items; -import net.minecraft.util.ResourceLocation; -import net.minecraftforge.common.ForgeConfigSpec; -import net.minecraftforge.eventbus.api.SubscribeEvent; -import net.minecraftforge.fml.common.Mod; -import net.minecraftforge.fml.config.ModConfig; -import net.minecraftforge.registries.ForgeRegistries; +@Config(name = WeaponThrow.MODID) -@Mod.EventBusSubscriber -public class WeaponThrowConfig { +public class WeaponThrowConfig implements ConfigData { - public static class Server { - - public final ForgeConfigSpec.BooleanValue notUseWhenCooldown; - public final ForgeConfigSpec.BooleanValue creativeSpamming; - - public final ForgeConfigSpec.BooleanValue classicRender; - public final ForgeConfigSpec.IntValue offsetY; - public final ForgeConfigSpec.IntValue offsetX; - - public final ForgeConfigSpec.DoubleValue baseDamageDefault; - public final ForgeConfigSpec.DoubleValue baseVelocityDefault; - - public final ForgeConfigSpec.DoubleValue pickaxeMultiplier; - public final ForgeConfigSpec.DoubleValue axeMultiplier; - public final ForgeConfigSpec.DoubleValue swordMultiplier; - public final ForgeConfigSpec.DoubleValue hoeMultiplier; - public final ForgeConfigSpec.DoubleValue shovelMultiplier; - - public final ForgeConfigSpec.DoubleValue baseDamageMultiplier; - public final ForgeConfigSpec.DoubleValue stackDamageMultiplier; - public final ForgeConfigSpec.DoubleValue modifiedDamageMultiplier; - - public final ForgeConfigSpec.DoubleValue baseVelocityMultiplier; - public final ForgeConfigSpec.DoubleValue stackVelocityMultiplier; - public final ForgeConfigSpec.DoubleValue modifiedVelocityMultiplier; - - public final ForgeConfigSpec.DoubleValue baseExhaustionMultiplier; - public final ForgeConfigSpec.DoubleValue stackExhaustionMultiplier; - public final ForgeConfigSpec.DoubleValue modifiedExhaustionMultiplier; - - public final ForgeConfigSpec.BooleanValue enablePMMOIntegration; - public final ForgeConfigSpec.IntValue requiredCombatLoyalty; - - public final ForgeConfigSpec.BooleanValue enableItemPhysicsFix; - public final ForgeConfigSpec.BooleanValue canBreakBlocks; - public final ForgeConfigSpec.BooleanValue shouldThrowItemsToo; - - public final ForgeConfigSpec.BooleanValue enchantAll; - public final ForgeConfigSpec.BooleanValue throwEnchant; - public final ForgeConfigSpec.BooleanValue conccusionEnchant; - public final ForgeConfigSpec.BooleanValue groundedEdgeEnchant; - public final ForgeConfigSpec.BooleanValue gravityEnchant; - public final ForgeConfigSpec.BooleanValue gravityDrop; - public final ForgeConfigSpec.BooleanValue returnEnchant; - - public final ForgeConfigSpec.IntValue despawnTime; - public final ForgeConfigSpec.IntValue castTimeInTicks; - public final ForgeConfigSpec.IntValue ticksUntilWeaponLoseOwner; - - public final WhiteListedItems whiteList; - public final BlackListedBlocks blackList; - - - Server(ForgeConfigSpec.Builder builder) { - builder.comment("Weapon Throw Mod Configuration Settings").push("general"); - notUseWhenCooldown = builder.comment("Weapon Cant be thrown if it is on cooldown").define("Not Throw If Cooldown", true); - creativeSpamming = builder.comment("Weapons does not remove on creative").define("Creative Spamming", false); - builder.pop(); - - builder.comment("Client Settings").push("client"); - classicRender = builder.comment("If you got rendering problems, try enabling the old rendering").define("Use classic render", false); - offsetY = builder.comment("Charging Y Hud Offset").defineInRange("Ycoord", 20, -32, 32); - offsetX = builder.comment("Charging X Hud Offset").defineInRange("Xcoord", - 8, -32, 32); - builder.pop(); - - builder.comment("If an item is whitelisted and doesn't have damage or attack speed, this values will be assigned").push("default"); - baseDamageDefault = builder.defineInRange("Default Base Damage", 1.0D, 0, 256.D); - baseVelocityDefault = builder.defineInRange("Default Base Velocity", 0.5D, 0, 256.D); - builder.pop(); - - builder.push("enchantments"); - enchantAll = builder.comment("If this is enabled, all tools can be applied mod enchantments too").define("Enchant All", false); - throwEnchant = builder.comment("Should Throw Enchantment be applied on survival?").define("Enable Throw Enchantment", true); - conccusionEnchant = builder.comment("Should Conccusion Enchantment be applied on survival?").define("Enable Conccusion Enchantment", true); - groundedEdgeEnchant = builder.comment("Should Grounded Edge Enchantment be applied on survival?").define("Enable Grounded Edge Enchantment", true); - gravityEnchant = builder.comment("Should Gravity Enchantment be applied on survival?").define("Enable Gravity Enchantment", true); - gravityDrop = builder.comment("Should gravity curse drop after some time?").define("Gravity Drop", false); - returnEnchant = builder.comment("Should Return Enchantment be applied on survival?").define("Enable Return Enchantment", true); - builder.pop(); - - builder.push("experimental"); - shouldThrowItemsToo = builder.comment("Enable using all items as a weapon").define("Throw all items", false); - builder.pop(); - - builder.push("fixes"); - enableItemPhysicsFix = builder.comment("Disable this if theres tossing bugs").define("Item Physics Fix", true); - builder.pop(); - - builder.push("interactions"); - canBreakBlocks = builder.comment("Throwing can break blocks at landing?").define("Break Blocks", true); - builder.pop(); - - builder.push("multipliers"); - pickaxeMultiplier = builder.defineInRange("Pickaxe Multiplier", 0.2D, 0.0D, 256.D); - axeMultiplier = builder.defineInRange("Axe Multiplier", 1.2D, 0.0D, 256.D); - swordMultiplier = builder.defineInRange("Sword Multiplier", 1.D, 0.0D, 256.D); - hoeMultiplier = builder.defineInRange("Hoe Multiplier", 0.5D, 0.0D, 256.D); - shovelMultiplier = builder.defineInRange("Shovel Multiplier", 0.7D, 0.0D, 256.D); - - baseDamageMultiplier = builder.defineInRange("Base Damage Multiplier", 0.25D, 0, 256.D); - stackDamageMultiplier = builder.defineInRange("Stack Size Damage Multiplier", 0.0D, 0, 256.D); - modifiedDamageMultiplier = builder.defineInRange("Modified Damage Multiplier", 0.50D, 0, 256.D); - - baseVelocityMultiplier = builder.defineInRange("Base Velocity Multiplier", 0.25D, 0, 64.D); - stackVelocityMultiplier = builder.defineInRange("Stack Size Velocity Multiplier", 0.005D, 0, 64.D); - modifiedVelocityMultiplier = builder.defineInRange("Modified Velocity Multiplier", 0.4D, 0, 64.D); - - baseExhaustionMultiplier = builder.defineInRange("Base Exhaustion Multiplier", 0.075D, 0, 256.D); - stackExhaustionMultiplier = builder.defineInRange("Stack Size Exhaustion Multiplier", 0.01D, 0, 256.D); - modifiedExhaustionMultiplier = builder.defineInRange("Modified Exhaustion Multiplier", 2.0D, 0, 256.D); - builder.pop(); - - builder.comment("Integration with Project MMO").push("pmmo"); - enablePMMOIntegration = builder.comment("Disable this if running Minecraft 1.16.3 and below").define("Enable PMMO Integration", true); - requiredCombatLoyalty = builder.comment("Minimum Level Required to use Loyalty, 0 is none").defineInRange("Loyalty Requirement", 10, 0, Integer.MAX_VALUE); - builder.pop(); - - builder.push("time"); - despawnTime = builder.comment("Time in ticks when the throwed items should dissapear").defineInRange("Despawn Time", 60*20, 0, Integer.MAX_VALUE); - castTimeInTicks = builder.comment("Attack Speed Multiplier to charging").defineInRange("Charging Multiplier", 3, 0, Integer.MAX_VALUE); - ticksUntilWeaponLoseOwner = builder.comment("Time in ticks when throwed items lose their owner").defineInRange("Lose Owner Time", 20*7, 0, Integer.MAX_VALUE); - builder.pop(); - - builder.comment("All Items Whitelisted will get default values").push("whitelist-items"); - whiteList = new WhiteListedItems(builder); - builder.pop(); - - builder.comment("All Blacklisted blocks cannot be destroyed").push("blacklist-blocks"); - blackList = new BlackListedBlocks(builder); - builder.pop(); - - } - - public class WhiteListedItems{ - public final List DEFAULT_WHITELIST = Arrays.asList(Items.BRICK.getRegistryName().toString(), Items.GLASS.getRegistryName().toString()); - - public ForgeConfigSpec.ConfigValue> whiteList; - - WhiteListedItems(ForgeConfigSpec.Builder builder){ - whiteList = builder.defineList("Whitelisted items", DEFAULT_WHITELIST, o -> o instanceof String); - } - - public List get() { - List items = new ArrayList(); - for(String location: whiteList.get()) { - ResourceLocation resourceLocation = new ResourceLocation(location); - if(ForgeRegistries.ITEMS.containsKey(resourceLocation)) { - items.add(ForgeRegistries.ITEMS.getValue(resourceLocation)); - } - } - return items; - } - } - - public class BlackListedBlocks{ - public final List DEFAULT_BLACKLIST = Arrays.asList(Items.BEDROCK.getRegistryName().toString()); - - public ForgeConfigSpec.ConfigValue> blackList; - - BlackListedBlocks(ForgeConfigSpec.Builder builder){ - blackList = builder.defineList("Blacklisted blocks", DEFAULT_BLACKLIST, o -> o instanceof String); - } - - public List get() { - List items = new ArrayList(); - for(String location: blackList.get()) { - ResourceLocation resourceLocation = new ResourceLocation(location); - if(ForgeRegistries.BLOCKS.containsKey(resourceLocation)) { - items.add(ForgeRegistries.BLOCKS.getValue(resourceLocation)); - } - } - return items; - } - } - } + @ConfigEntry.Category("general") + @ConfigEntry.Gui.TransitiveObject + public General general = new General(); - public static final ForgeConfigSpec commonSpec; - public static final Server COMMON; - static { - final Pair specPair = new ForgeConfigSpec.Builder().configure(Server::new); - commonSpec = specPair.getRight(); - COMMON = specPair.getLeft(); - } + @ConfigEntry.Category("defaults") + @ConfigEntry.Gui.TransitiveObject + public Default defaults = new Default(); + + @ConfigEntry.Category("enchantments") + @ConfigEntry.Gui.TransitiveObject + public Enchantments enchantments = new Enchantments(); + + @ConfigEntry.Category("experimental") + @ConfigEntry.Gui.TransitiveObject + public Experimental experimental = new Experimental(); + + @ConfigEntry.Category("interactions") + @ConfigEntry.Gui.TransitiveObject + public Interactions interactions = new Interactions(); + + @ConfigEntry.Category("multipliers") + @ConfigEntry.Gui.TransitiveObject + public Multipliers multipliers = new Multipliers(); - @SubscribeEvent - public static void onLoad(final ModConfig.Loading configEvent) { - - } - - @SubscribeEvent - public static void onFileChange(final ModConfig.Reloading configEvent) { + @ConfigEntry.Category("times") + @ConfigEntry.Gui.TransitiveObject + public Times times = new Times(); + + + public static class General implements ConfigData { + public boolean creativeSpamming = false; + public boolean notUseWhenCooldown = false; + } + + public static class Default implements ConfigData { + public double baseDamageDefault = 1.0D; + public double velocityDefault = 2.0D; + } + + public static class Enchantments implements ConfigData { + public boolean enchantAllWeapons = false; + public boolean enableThrow = true; + public boolean enableConccusion = true; + public boolean enableGroundedEdge = true; + public boolean enableGravity = true; + public boolean enableReturn = true; + } + + public static class Experimental implements ConfigData { + public boolean shouldThrowItemsToo = false; + } + + public static class Interactions implements ConfigData { + public boolean canBreakBlocks = true; + } + + public static class Multipliers implements ConfigData { + + @ConfigEntry.Gui.CollapsibleObject + public ToolMultipliers tools = new ToolMultipliers(); + + public static class ToolMultipliers implements ConfigData { + public double pickaxeMultiplier = 0.8D; + public double axeMultiplier = 1.2D; + public double swordMultiplier = 1.D; + public double hoeMultiplier = 1.3D; + public double shovelMultiplier = 0.9D; + } + + @ConfigEntry.Gui.CollapsibleObject + public DamageMultipliers damages = new DamageMultipliers(); + + public static class DamageMultipliers implements ConfigData { + public double baseDamageMultiplier = 0.25D; + public double stackDamageMultiplier = 0.0D; + public double modifiedDamageMultiplier = 0.50D; + } + + @ConfigEntry.Gui.CollapsibleObject + public VelocityMultipliers velocities = new VelocityMultipliers(); + + public static class VelocityMultipliers implements ConfigData { + public double baseVelocityMultiplier = 0.25D; + public double stackVelocityMultiplier = 0.005D; + public double modifiedVelocityMultiplier = 0.4D; + } + + @ConfigEntry.Gui.CollapsibleObject + public ExhaustionMultipliers exhaustions = new ExhaustionMultipliers(); + + public static class ExhaustionMultipliers implements ConfigData { + public double baseExhaustionMultiplier = 0.075D; + public double stackExhaustionMultiplier = 0.01D; + public double modifiedExhaustionMultiplier = 2.0D; + } - } + } + + public static class Times implements ConfigData { + @ConfigEntry.BoundedDiscrete(min=0,max=Integer.MAX_VALUE) + public int despawnTime = 60*20; + + public double castTimeMuliplier = 3.0D; + + @ConfigEntry.BoundedDiscrete(min=0,max=Integer.MAX_VALUE) + public int ticksUntilWeaponLoseOwner = 20*7; + } } + diff --git a/src/main/java/com/dainxt/weaponthrow/enchantment/ConccusionEnchantment.java b/src/main/java/com/dainxt/weaponthrow/enchantment/ConccusionEnchantment.java index ab1b027..1a803eb 100644 --- a/src/main/java/com/dainxt/weaponthrow/enchantment/ConccusionEnchantment.java +++ b/src/main/java/com/dainxt/weaponthrow/enchantment/ConccusionEnchantment.java @@ -1,25 +1,26 @@ package com.dainxt.weaponthrow.enchantment; -import com.dainxt.weaponthrow.config.WeaponThrowConfig; +import com.dainxt.weaponthrow.handlers.ConfigRegistry; import net.minecraft.enchantment.Enchantment; -import net.minecraft.enchantment.EnchantmentType; -import net.minecraft.inventory.EquipmentSlotType; +import net.minecraft.enchantment.EnchantmentTarget; +import net.minecraft.entity.EquipmentSlot; import net.minecraft.item.AxeItem; import net.minecraft.item.ItemStack; public class ConccusionEnchantment extends Enchantment { - public ConccusionEnchantment(Enchantment.Rarity rarityIn, EquipmentSlotType... slots) { - super(rarityIn, EnchantmentType.WEAPON, slots); + public ConccusionEnchantment(Enchantment.Rarity rarityIn, EquipmentSlot... slots) { + super(rarityIn, EnchantmentTarget.WEAPON, slots); } - public int getMinEnchantability(int enchantmentLevel) { + public int getMinPower(int enchantmentLevel) { return 30; } - public int getMaxEnchantability(int enchantmentLevel) { - return this.getMinEnchantability(enchantmentLevel) + 30; + + public int getMaxPower(int enchantmentLevel) { + return this.getMinPower(enchantmentLevel) + 30; } /** @@ -29,12 +30,13 @@ public int getMaxLevel() { return 2; } + @Override - public boolean canApply(ItemStack stack) { - boolean enchantAll = WeaponThrowConfig.COMMON.enchantAll.get(); + public boolean isAcceptableItem(ItemStack stack) { + boolean enchantAll = ConfigRegistry.COMMON.getConfig().enchantments.enchantAllWeapons; boolean isAxe = stack.getItem() instanceof AxeItem; - boolean canApply = super.canApply(stack); - return isAxe || canApply || enchantAll ? WeaponThrowConfig.COMMON.conccusionEnchant.get() : false; + boolean canApply = super.isAcceptableItem(stack); + return (isAxe || canApply || enchantAll) && ConfigRegistry.COMMON.getConfig().enchantments.enableConccusion; } } diff --git a/src/main/java/com/dainxt/weaponthrow/enchantment/GravityEnchantment.java b/src/main/java/com/dainxt/weaponthrow/enchantment/GravityEnchantment.java index 381e022..ad4c8cc 100644 --- a/src/main/java/com/dainxt/weaponthrow/enchantment/GravityEnchantment.java +++ b/src/main/java/com/dainxt/weaponthrow/enchantment/GravityEnchantment.java @@ -1,23 +1,23 @@ package com.dainxt.weaponthrow.enchantment; -import com.dainxt.weaponthrow.config.WeaponThrowConfig; +import com.dainxt.weaponthrow.handlers.ConfigRegistry; import net.minecraft.enchantment.Enchantment; -import net.minecraft.enchantment.EnchantmentType; -import net.minecraft.inventory.EquipmentSlotType; +import net.minecraft.enchantment.EnchantmentTarget; +import net.minecraft.entity.EquipmentSlot; import net.minecraft.item.AxeItem; import net.minecraft.item.ItemStack; public class GravityEnchantment extends Enchantment{ - public GravityEnchantment(Enchantment.Rarity rarityIn, EquipmentSlotType... slots) { - super(rarityIn, EnchantmentType.WEAPON, slots); + public GravityEnchantment(Enchantment.Rarity rarityIn, EquipmentSlot... slots) { + super(rarityIn, EnchantmentTarget.WEAPON, slots); } - public int getMinEnchantability(int enchantmentLevel) { + public int getMinPower(int enchantmentLevel) { return 25; } - public int getMaxEnchantability(int enchantmentLevel) { + public int getMaxPower(int enchantmentLevel) { return 50; } @@ -25,19 +25,19 @@ public int getMaxLevel() { return 1; } - public boolean isTreasureEnchantment() { + public boolean isTreasure() { return true; } - public boolean isCurse() { + public boolean isCursed() { return true; } @Override - public boolean canApply(ItemStack stack) { - boolean enchantAll = WeaponThrowConfig.COMMON.enchantAll.get(); + public boolean isAcceptableItem(ItemStack stack) { + boolean enchantAll = ConfigRegistry.COMMON.getConfig().enchantments.enchantAllWeapons; boolean isAxe = stack.getItem() instanceof AxeItem; - boolean canApply = super.canApply(stack); - return isAxe || canApply || enchantAll ? WeaponThrowConfig.COMMON.gravityEnchant.get() : false; + boolean canApply = super.isAcceptableItem(stack); + return (isAxe || canApply || enchantAll) && ConfigRegistry.COMMON.getConfig().enchantments.enableGravity; } } diff --git a/src/main/java/com/dainxt/weaponthrow/enchantment/GroundedEdgeEnchantment.java b/src/main/java/com/dainxt/weaponthrow/enchantment/GroundedEdgeEnchantment.java index bc5af9b..f431a6f 100644 --- a/src/main/java/com/dainxt/weaponthrow/enchantment/GroundedEdgeEnchantment.java +++ b/src/main/java/com/dainxt/weaponthrow/enchantment/GroundedEdgeEnchantment.java @@ -1,17 +1,17 @@ package com.dainxt.weaponthrow.enchantment; -import com.dainxt.weaponthrow.config.WeaponThrowConfig; +import com.dainxt.weaponthrow.handlers.ConfigRegistry; import net.minecraft.enchantment.Enchantment; -import net.minecraft.enchantment.EnchantmentType; -import net.minecraft.inventory.EquipmentSlotType; +import net.minecraft.enchantment.EnchantmentTarget; +import net.minecraft.entity.EquipmentSlot; import net.minecraft.item.AxeItem; import net.minecraft.item.ItemStack; public class GroundedEdgeEnchantment extends Enchantment { - public GroundedEdgeEnchantment(Enchantment.Rarity rarityIn, EquipmentSlotType... slots) { - super(rarityIn, EnchantmentType.WEAPON, slots); + public GroundedEdgeEnchantment(Enchantment.Rarity rarityIn, EquipmentSlot... slots) { + super(rarityIn, EnchantmentTarget.WEAPON, slots); } /** @@ -33,10 +33,10 @@ public int getMaxLevel() { } @Override - public boolean canApply(ItemStack stack) { - boolean enchantAll = WeaponThrowConfig.COMMON.enchantAll.get(); + public boolean isAcceptableItem(ItemStack stack) { + boolean enchantAll = ConfigRegistry.COMMON.getConfig().enchantments.enchantAllWeapons; boolean isAxe = stack.getItem() instanceof AxeItem; - boolean canApply = super.canApply(stack); - return isAxe || canApply || enchantAll ? WeaponThrowConfig.COMMON.groundedEdgeEnchant.get() : false; + boolean canApply = super.isAcceptableItem(stack); + return (isAxe || canApply || enchantAll) && ConfigRegistry.COMMON.getConfig().enchantments.enableGroundedEdge; } } diff --git a/src/main/java/com/dainxt/weaponthrow/enchantment/ReturnEnchantment.java b/src/main/java/com/dainxt/weaponthrow/enchantment/ReturnEnchantment.java index 7638b03..74bf1fe 100644 --- a/src/main/java/com/dainxt/weaponthrow/enchantment/ReturnEnchantment.java +++ b/src/main/java/com/dainxt/weaponthrow/enchantment/ReturnEnchantment.java @@ -1,28 +1,28 @@ package com.dainxt.weaponthrow.enchantment; -import com.dainxt.weaponthrow.config.WeaponThrowConfig; +import com.dainxt.weaponthrow.handlers.ConfigRegistry; import net.minecraft.enchantment.Enchantment; -import net.minecraft.enchantment.EnchantmentType; -import net.minecraft.inventory.EquipmentSlotType; +import net.minecraft.enchantment.EnchantmentTarget; +import net.minecraft.entity.EquipmentSlot; import net.minecraft.item.AxeItem; import net.minecraft.item.ItemStack; public class ReturnEnchantment extends Enchantment { - public ReturnEnchantment(Rarity rarityIn, EquipmentSlotType... mainhand) { - super(rarityIn, EnchantmentType.WEAPON, mainhand); + public ReturnEnchantment(Rarity rarityIn, EquipmentSlot... mainhand) { + super(rarityIn, EnchantmentTarget.WEAPON, mainhand); } /** * Returns the minimal value of enchantability needed on the enchantment level passed. */ - public int getMinEnchantability(int enchantmentLevel) { + public int getMinPower(int enchantmentLevel) { return 5 + enchantmentLevel * 7; } - public int getMaxEnchantability(int enchantmentLevel) { + public int getMaxPower(int enchantmentLevel) { return 50; } @@ -34,11 +34,11 @@ public int getMaxLevel() { } @Override - public boolean canApply(ItemStack stack) { - boolean enchantAll = WeaponThrowConfig.COMMON.enchantAll.get(); + public boolean isAcceptableItem(ItemStack stack) { + boolean enchantAll = ConfigRegistry.COMMON.getConfig().enchantments.enchantAllWeapons; boolean isAxe = stack.getItem() instanceof AxeItem; - boolean canApply = super.canApply(stack); - return isAxe || canApply || enchantAll ? WeaponThrowConfig.COMMON.returnEnchant.get() : false; + boolean canApply = super.isAcceptableItem(stack); + return (isAxe || canApply || enchantAll) && ConfigRegistry.COMMON.getConfig().enchantments.enableReturn; } } diff --git a/src/main/java/com/dainxt/weaponthrow/enchantment/ThrowEnchantment.java b/src/main/java/com/dainxt/weaponthrow/enchantment/ThrowEnchantment.java index a27b6e4..5ce6c98 100644 --- a/src/main/java/com/dainxt/weaponthrow/enchantment/ThrowEnchantment.java +++ b/src/main/java/com/dainxt/weaponthrow/enchantment/ThrowEnchantment.java @@ -1,28 +1,28 @@ package com.dainxt.weaponthrow.enchantment; -import com.dainxt.weaponthrow.config.WeaponThrowConfig; +import com.dainxt.weaponthrow.handlers.ConfigRegistry; import net.minecraft.enchantment.Enchantment; -import net.minecraft.enchantment.EnchantmentType; -import net.minecraft.inventory.EquipmentSlotType; +import net.minecraft.enchantment.EnchantmentTarget; +import net.minecraft.entity.EquipmentSlot; import net.minecraft.item.AxeItem; import net.minecraft.item.ItemStack; public class ThrowEnchantment extends Enchantment { - public ThrowEnchantment(Enchantment.Rarity rarityIn, EquipmentSlotType... slots) { - super(rarityIn, EnchantmentType.WEAPON, slots); + public ThrowEnchantment(Enchantment.Rarity rarityIn, EquipmentSlot... slots) { + super(rarityIn, EnchantmentTarget.WEAPON, slots); } /** * Returns the minimal value of enchantability needed on the enchantment level passed. */ - public int getMinEnchantability(int enchantmentLevel) { + public int getMinPower(int enchantmentLevel) { return 10; } - public int getMaxEnchantability(int enchantmentLevel) { - return this.getMinEnchantability(enchantmentLevel) + 40; + public int getMaxPower(int enchantmentLevel) { + return this.getMinPower(enchantmentLevel) + 40; } /** @@ -33,10 +33,10 @@ public int getMaxLevel() { } @Override - public boolean canApply(ItemStack stack) { - boolean enchantAll = WeaponThrowConfig.COMMON.enchantAll.get(); + public boolean isAcceptableItem(ItemStack stack) { + boolean enchantAll = ConfigRegistry.COMMON.getConfig().enchantments.enchantAllWeapons; boolean isAxe = stack.getItem() instanceof AxeItem; - boolean canApply = super.canApply(stack); - return isAxe || canApply || enchantAll ? WeaponThrowConfig.COMMON.throwEnchant.get() : false; + boolean canApply = super.isAcceptableItem(stack); + return (isAxe || canApply || enchantAll) && ConfigRegistry.COMMON.getConfig().enchantments.enableThrow; } } diff --git a/src/main/java/com/dainxt/weaponthrow/entity/render/WeaponThrowRenderer.java b/src/main/java/com/dainxt/weaponthrow/entity/render/WeaponThrowRenderer.java index bb54154..97a4389 100644 --- a/src/main/java/com/dainxt/weaponthrow/entity/render/WeaponThrowRenderer.java +++ b/src/main/java/com/dainxt/weaponthrow/entity/render/WeaponThrowRenderer.java @@ -1,81 +1,53 @@ package com.dainxt.weaponthrow.entity.render; -import com.dainxt.weaponthrow.config.WeaponThrowConfig; import com.dainxt.weaponthrow.projectile.WeaponThrowEntity; -import com.mojang.blaze3d.matrix.MatrixStack; -import net.minecraft.client.Minecraft; -import net.minecraft.client.renderer.IRenderTypeBuffer; -import net.minecraft.client.renderer.entity.EntityRenderer; -import net.minecraft.client.renderer.entity.EntityRendererManager; -import net.minecraft.client.renderer.entity.SpriteRenderer; -import net.minecraft.client.renderer.model.ItemCameraTransforms; -import net.minecraft.client.renderer.texture.OverlayTexture; +import net.fabricmc.api.EnvType; +import net.fabricmc.api.Environment; +import net.minecraft.client.render.OverlayTexture; +import net.minecraft.client.render.VertexConsumerProvider; +import net.minecraft.client.render.entity.EntityRendererFactory; +import net.minecraft.client.render.entity.FlyingItemEntityRenderer; +import net.minecraft.client.render.item.ItemRenderer; +import net.minecraft.client.render.model.json.ModelTransformation; +import net.minecraft.client.util.math.MatrixStack; import net.minecraft.util.math.MathHelper; -import net.minecraft.util.math.vector.Vector3f; -import net.minecraftforge.api.distmarker.Dist; -import net.minecraftforge.api.distmarker.OnlyIn; -import net.minecraftforge.fml.client.registry.IRenderFactory; +import net.minecraft.util.math.Vec3f; -@OnlyIn(Dist.CLIENT) -public class WeaponThrowRenderer extends SpriteRenderer { +@Environment(EnvType.CLIENT) +public class WeaponThrowRenderer extends FlyingItemEntityRenderer { - public WeaponThrowRenderer(EntityRendererManager renderManagerIn, net.minecraft.client.renderer.ItemRenderer itemRenderer) { - super(renderManagerIn, itemRenderer); + private final ItemRenderer itemRenderer; + + public WeaponThrowRenderer(EntityRendererFactory.Context renderManagerIn) { + super(renderManagerIn); + this.itemRenderer = renderManagerIn.getItemRenderer(); } - public void render(WeaponThrowEntity entityIn, float entityYaw, float partialTicks, MatrixStack matrixStackIn, IRenderTypeBuffer bufferIn, int packedLightIn) { - - float degrees = entityIn.getRotationAnimation(partialTicks); + public void render(WeaponThrowEntity entityIn, float entityYaw, float partialTicks, MatrixStack matrixStackIn, + VertexConsumerProvider bufferIn, int packedLightIn) { + + float degrees = entityIn.getRotationAnimation(partialTicks); - if(WeaponThrowConfig.COMMON.classicRender.get()) { - float amplitude = 0.25F; - float offsetX = amplitude*(MathHelper.sin((float) Math.toRadians(degrees))); - float offsetY = amplitude*(1-MathHelper.cos((float) Math.toRadians(degrees))); - matrixStackIn.push(); + float scale = 0.75F; + matrixStackIn.push(); + matrixStackIn.translate(0.F, 0.15F, 0.0F); + matrixStackIn.multiply(Vec3f.POSITIVE_Y.getDegreesQuaternion(MathHelper.lerp(partialTicks, entityIn.prevYaw, entityIn.getYaw()) - 90.0F)); + matrixStackIn.multiply(Vec3f.POSITIVE_Z.getDegreesQuaternion(-degrees)); + matrixStackIn.scale(scale, scale, scale); - matrixStackIn.rotate(Vector3f.YP.rotationDegrees(MathHelper.lerp(partialTicks, entityIn.prevRotationYaw, entityIn.rotationYaw) - 270.0F)); - matrixStackIn.translate(offsetX, offsetY, 0.0F); - matrixStackIn.scale(1.5F, 1.5F, 1.5F); - - matrixStackIn.rotate(Vector3f.ZP.rotationDegrees(degrees)); - - int count = entityIn.getItemStack().getCount(); - - Minecraft.getInstance().getItemRenderer().renderItem(entityIn.getItem(), ItemCameraTransforms.TransformType.GROUND, packedLightIn, OverlayTexture.NO_OVERLAY, matrixStackIn, bufferIn); - - if(count > 32) { - matrixStackIn.translate(0.05F, 0.05F, 0.05F); - Minecraft.getInstance().getItemRenderer().renderItem(entityIn.getItem(), ItemCameraTransforms.TransformType.GROUND, packedLightIn, OverlayTexture.NO_OVERLAY, matrixStackIn, bufferIn); - } + int count = entityIn.getItemStack().getCount(); - matrixStackIn.pop(); - }else { - float scale = 0.75F; - matrixStackIn.push(); - matrixStackIn.translate(0.F, 0.15F, 0.0F); - matrixStackIn.rotate(Vector3f.YP.rotationDegrees(MathHelper.lerp(partialTicks, entityIn.prevRotationYaw, entityIn.rotationYaw) - 90.0F)); - matrixStackIn.rotate(Vector3f.ZP.rotationDegrees(-degrees)); - matrixStackIn.scale(scale, scale, scale); + this.itemRenderer.renderItem(entityIn.getStack(), ModelTransformation.Mode.FIXED, packedLightIn, + OverlayTexture.DEFAULT_UV, matrixStackIn, bufferIn, entityIn.getId()); + if (count > 32) { + matrixStackIn.translate(-0.05F, -0.05F, -0.05F); + this.itemRenderer.renderItem(entityIn.getStack(), ModelTransformation.Mode.FIXED, + packedLightIn, OverlayTexture.DEFAULT_UV, matrixStackIn, bufferIn, entityIn.getId()); + } - int count = entityIn.getItemStack().getCount(); - - Minecraft.getInstance().getItemRenderer().renderItem(entityIn.getItem(), ItemCameraTransforms.TransformType.FIXED, packedLightIn, OverlayTexture.NO_OVERLAY, matrixStackIn, bufferIn); - if(count > 32) { - matrixStackIn.translate(-0.05F, -0.05F, -0.05F); - Minecraft.getInstance().getItemRenderer().renderItem(entityIn.getItem(), ItemCameraTransforms.TransformType.FIXED, packedLightIn, OverlayTexture.NO_OVERLAY, matrixStackIn, bufferIn); - } - matrixStackIn.pop(); - } - } - - public static class RenderFactory implements IRenderFactory { - - @Override - public EntityRenderer createRenderFor(EntityRendererManager manager) { - return new WeaponThrowRenderer(manager, Minecraft.getInstance().getItemRenderer()); - } + matrixStackIn.pop(); } - + } \ No newline at end of file diff --git a/src/main/java/com/dainxt/weaponthrow/events/OnApplySlow.java b/src/main/java/com/dainxt/weaponthrow/events/OnApplySlow.java new file mode 100644 index 0000000..4cc6210 --- /dev/null +++ b/src/main/java/com/dainxt/weaponthrow/events/OnApplySlow.java @@ -0,0 +1,19 @@ +package com.dainxt.weaponthrow.events; + +import net.fabricmc.fabric.api.event.Event; +import net.fabricmc.fabric.api.event.EventFactory; +import net.minecraft.entity.player.PlayerEntity; + +public interface OnApplySlow { + + Event EVENT = EventFactory.createArrayBacked(OnApplySlow.class, + (listeners) -> (player) -> { + boolean result = false; + for (OnApplySlow listener : listeners) { + result = listener.interact(player) || result; + } + return result; + }); + + boolean interact(PlayerEntity player); +} diff --git a/src/main/java/com/dainxt/weaponthrow/events/OnFOVUpdate.java b/src/main/java/com/dainxt/weaponthrow/events/OnFOVUpdate.java new file mode 100644 index 0000000..d615f4c --- /dev/null +++ b/src/main/java/com/dainxt/weaponthrow/events/OnFOVUpdate.java @@ -0,0 +1,23 @@ +package com.dainxt.weaponthrow.events; + +import net.fabricmc.fabric.api.event.Event; +import net.fabricmc.fabric.api.event.EventFactory; +import net.minecraft.entity.player.PlayerEntity; + +public interface OnFOVUpdate { + + Event EVENT = EventFactory.createArrayBacked(OnFOVUpdate.class, + (listeners) -> (player, amount) -> { + for (OnFOVUpdate listener : listeners) { + float result = listener.interact(player, amount); + + if(result != 0) { + return result; + } + + } + return 0; + }); + + float interact(PlayerEntity entity, float fov); +} diff --git a/src/main/java/com/dainxt/weaponthrow/events/OnHeldItemRender.java b/src/main/java/com/dainxt/weaponthrow/events/OnHeldItemRender.java new file mode 100644 index 0000000..b7f3fa3 --- /dev/null +++ b/src/main/java/com/dainxt/weaponthrow/events/OnHeldItemRender.java @@ -0,0 +1,23 @@ +package com.dainxt.weaponthrow.events; + +import net.fabricmc.fabric.api.event.Event; +import net.fabricmc.fabric.api.event.EventFactory; +import net.minecraft.client.network.AbstractClientPlayerEntity; +import net.minecraft.client.render.VertexConsumerProvider; +import net.minecraft.client.render.item.HeldItemRenderer; +import net.minecraft.client.util.math.MatrixStack; +import net.minecraft.item.ItemStack; +import net.minecraft.util.Hand; + +public interface OnHeldItemRender { + + Event EVENT = EventFactory.createArrayBacked(OnHeldItemRender.class, + (listeners) -> (renderer, player, tickDelta, pitch, hand, swingProgress, item, equipProgress, matrices, vertexConsumers, light) -> { + for (OnHeldItemRender listener : listeners) { + listener.interact(renderer, player, tickDelta, pitch, hand, swingProgress, item, equipProgress, matrices, vertexConsumers, light); + } + + }); + + void interact(HeldItemRenderer renderer , AbstractClientPlayerEntity player, float tickDelta, float pitch, Hand hand, float swingProgress, ItemStack item, float equipProgress, MatrixStack matrices, VertexConsumerProvider vertexConsumers, int light); +} diff --git a/src/main/java/com/dainxt/weaponthrow/events/OnStartPlayerRender.java b/src/main/java/com/dainxt/weaponthrow/events/OnStartPlayerRender.java new file mode 100644 index 0000000..cc611e8 --- /dev/null +++ b/src/main/java/com/dainxt/weaponthrow/events/OnStartPlayerRender.java @@ -0,0 +1,19 @@ +package com.dainxt.weaponthrow.events; + +import net.fabricmc.fabric.api.event.Event; +import net.fabricmc.fabric.api.event.EventFactory; +import net.minecraft.client.render.entity.PlayerEntityRenderer; +import net.minecraft.entity.player.PlayerEntity; + +public interface OnStartPlayerRender { + + Event EVENT = EventFactory.createArrayBacked(OnStartPlayerRender.class, + (listeners) -> (renderer, player) -> { + for (OnStartPlayerRender listener : listeners) { + listener.interact(renderer, player); + } + + }); + + void interact(PlayerEntityRenderer renderer, PlayerEntity entity); +} diff --git a/src/main/java/com/dainxt/weaponthrow/events/OnStartPlayerTick.java b/src/main/java/com/dainxt/weaponthrow/events/OnStartPlayerTick.java new file mode 100644 index 0000000..0d235df --- /dev/null +++ b/src/main/java/com/dainxt/weaponthrow/events/OnStartPlayerTick.java @@ -0,0 +1,18 @@ +package com.dainxt.weaponthrow.events; + +import net.fabricmc.fabric.api.event.Event; +import net.fabricmc.fabric.api.event.EventFactory; +import net.minecraft.entity.player.PlayerEntity; + +public interface OnStartPlayerTick { + + Event EVENT = EventFactory.createArrayBacked(OnStartPlayerTick.class, + (listeners) -> (player) -> { + for (OnStartPlayerTick listener : listeners) { + listener.interact(player); + } + + }); + + void interact(PlayerEntity entity); +} diff --git a/src/main/java/com/dainxt/weaponthrow/handlers/ConfigRegistry.java b/src/main/java/com/dainxt/weaponthrow/handlers/ConfigRegistry.java new file mode 100644 index 0000000..9e262e2 --- /dev/null +++ b/src/main/java/com/dainxt/weaponthrow/handlers/ConfigRegistry.java @@ -0,0 +1,18 @@ +package com.dainxt.weaponthrow.handlers; + +import com.dainxt.weaponthrow.config.WeaponThrowConfig; + +import me.shedaniel.autoconfig.AutoConfig; +import me.shedaniel.autoconfig.ConfigHolder; +import me.shedaniel.autoconfig.serializer.GsonConfigSerializer; + +public class ConfigRegistry { + + public static ConfigHolder COMMON; + + public static void registerConfig() { + + COMMON = AutoConfig.register(WeaponThrowConfig.class, GsonConfigSerializer::new); + } + +} diff --git a/src/main/java/com/dainxt/weaponthrow/handlers/EnchantmentHandler.java b/src/main/java/com/dainxt/weaponthrow/handlers/EnchantmentHandler.java index 00564b6..99565cb 100644 --- a/src/main/java/com/dainxt/weaponthrow/handlers/EnchantmentHandler.java +++ b/src/main/java/com/dainxt/weaponthrow/handlers/EnchantmentHandler.java @@ -1,5 +1,6 @@ package com.dainxt.weaponthrow.handlers; +import com.dainxt.weaponthrow.WeaponThrow; import com.dainxt.weaponthrow.enchantment.ConccusionEnchantment; import com.dainxt.weaponthrow.enchantment.GravityEnchantment; import com.dainxt.weaponthrow.enchantment.GroundedEdgeEnchantment; @@ -7,27 +8,20 @@ import com.dainxt.weaponthrow.enchantment.ThrowEnchantment; import net.minecraft.enchantment.Enchantment; -import net.minecraft.inventory.EquipmentSlotType; -import net.minecraftforge.event.RegistryEvent; -import net.minecraftforge.eventbus.api.SubscribeEvent; -import net.minecraftforge.fml.common.Mod; +import net.minecraft.entity.EquipmentSlot; +import net.minecraft.util.Identifier; +import net.minecraft.util.registry.Registry; -@Mod.EventBusSubscriber(bus=Mod.EventBusSubscriber.Bus.MOD) public class EnchantmentHandler { - public static final Enchantment THROW = new ThrowEnchantment(Enchantment.Rarity.RARE, EquipmentSlotType.MAINHAND); - public static final Enchantment GROUNDEDEDGE = new GroundedEdgeEnchantment(Enchantment.Rarity.UNCOMMON, EquipmentSlotType.MAINHAND); - public static final Enchantment CONCCUSION = new ConccusionEnchantment(Enchantment.Rarity.VERY_RARE, EquipmentSlotType.MAINHAND); - public static final Enchantment GRAVITY = new GravityEnchantment(Enchantment.Rarity.VERY_RARE, EquipmentSlotType.MAINHAND); - public static final Enchantment RETURN = new ReturnEnchantment(Enchantment.Rarity.RARE, EquipmentSlotType.MAINHAND); + public static final Enchantment THROW = Registry.register(Registry.ENCHANTMENT, new Identifier(WeaponThrow.MODID, "throw"), new ThrowEnchantment(Enchantment.Rarity.RARE, EquipmentSlot.MAINHAND)); + public static final Enchantment GROUNDEDEDGE = Registry.register(Registry.ENCHANTMENT, new Identifier(WeaponThrow.MODID, "groundededge"), new GroundedEdgeEnchantment(Enchantment.Rarity.UNCOMMON, EquipmentSlot.MAINHAND)); + public static final Enchantment CONCCUSION = Registry.register(Registry.ENCHANTMENT, new Identifier(WeaponThrow.MODID, "conccusion"), new ConccusionEnchantment(Enchantment.Rarity.VERY_RARE, EquipmentSlot.MAINHAND)); + public static final Enchantment GRAVITY = Registry.register(Registry.ENCHANTMENT, new Identifier(WeaponThrow.MODID, "gravity"), new GravityEnchantment(Enchantment.Rarity.VERY_RARE, EquipmentSlot.MAINHAND)); + public static final Enchantment RETURN = Registry.register(Registry.ENCHANTMENT, new Identifier(WeaponThrow.MODID, "return"), new ReturnEnchantment(Enchantment.Rarity.RARE, EquipmentSlot.MAINHAND)); - @SubscribeEvent - public static void onEnchantmentRegistry(final RegistryEvent.Register e) { - e.getRegistry().register(THROW.setRegistryName("throw")); - e.getRegistry().register(GROUNDEDEDGE.setRegistryName("groundededge")); - e.getRegistry().register(CONCCUSION.setRegistryName("conccusion")); - e.getRegistry().register(GRAVITY.setRegistryName("gravity")); - e.getRegistry().register(RETURN.setRegistryName("return")); + public static void registerEnchantments() { + } } diff --git a/src/main/java/com/dainxt/weaponthrow/handlers/EntityRegistry.java b/src/main/java/com/dainxt/weaponthrow/handlers/EntityRegistry.java new file mode 100644 index 0000000..84e53a7 --- /dev/null +++ b/src/main/java/com/dainxt/weaponthrow/handlers/EntityRegistry.java @@ -0,0 +1,24 @@ +package com.dainxt.weaponthrow.handlers; + +import com.dainxt.weaponthrow.WeaponThrow; +import com.dainxt.weaponthrow.projectile.WeaponThrowEntity; + +import net.fabricmc.fabric.api.object.builder.v1.entity.FabricEntityTypeBuilder; +import net.minecraft.entity.EntityDimensions; +import net.minecraft.entity.EntityType; +import net.minecraft.entity.SpawnGroup; +import net.minecraft.util.Identifier; +import net.minecraft.util.registry.Registry; + +public class EntityRegistry { + + public static final EntityType WEAPONTHROW = Registry.register( + Registry.ENTITY_TYPE, + new Identifier(WeaponThrow.MODID), + FabricEntityTypeBuilder.create(SpawnGroup.MISC, WeaponThrowEntity::new).trackRangeBlocks(4).trackedUpdateRate(20).dimensions(EntityDimensions.fixed(0.5F, 0.5F)).build() + ); + + public static void registerEntities() { + + } +} diff --git a/src/main/java/com/dainxt/weaponthrow/handlers/EventsHandler.java b/src/main/java/com/dainxt/weaponthrow/handlers/EventsHandler.java index d108415..ca0d2b5 100644 --- a/src/main/java/com/dainxt/weaponthrow/handlers/EventsHandler.java +++ b/src/main/java/com/dainxt/weaponthrow/handlers/EventsHandler.java @@ -1,196 +1,131 @@ package com.dainxt.weaponthrow.handlers; -import java.util.Map; -import java.util.Set; import java.util.UUID; -import com.dainxt.weaponthrow.WeaponThrow; -import com.dainxt.weaponthrow.capabilities.ThrowProvider; -import com.dainxt.weaponthrow.config.WeaponThrowConfig; -import com.dainxt.weaponthrow.events.WeaponThrowEvent; -import com.dainxt.weaponthrow.events.WeaponThrowEvent.TestThrow; -import com.dainxt.weaponthrow.interfaces.IThrowPower; +import com.dainxt.weaponthrow.capabilities.PlayerThrowData; +import com.dainxt.weaponthrow.interfaces.IPlayerEntityMixin; +import com.dainxt.weaponthrow.projectile.WeaponThrowEntity; +import com.dainxt.weaponthrow.events.OnApplySlow; +import com.dainxt.weaponthrow.events.OnFOVUpdate; +import com.dainxt.weaponthrow.events.OnHeldItemRender; +import com.dainxt.weaponthrow.events.OnStartPlayerRender; +import com.dainxt.weaponthrow.events.OnStartPlayerTick; import com.dainxt.weaponthrow.packets.CPacketThrow; +import com.dainxt.weaponthrow.packets.CPacketThrow.State; import com.dainxt.weaponthrow.packets.SPacketThrow; -import com.dainxt.weaponthrow.projectile.WeaponThrowEntity; -import com.dainxt.weaponthrow.util.Reference; import com.google.common.collect.Multimap; -import com.mojang.blaze3d.matrix.MatrixStack; -import com.mojang.blaze3d.platform.GlStateManager; -import com.mojang.blaze3d.systems.RenderSystem; -import harmonised.pmmo.config.JType; -import harmonised.pmmo.skills.Skill; -import harmonised.pmmo.util.XP; -import net.minecraft.client.Minecraft; -import net.minecraft.client.entity.player.AbstractClientPlayerEntity; -import net.minecraft.client.gui.IngameGui; -import net.minecraft.client.renderer.entity.model.BipedModel; -import net.minecraft.entity.Entity; -import net.minecraft.entity.ai.attributes.Attribute; -import net.minecraft.entity.ai.attributes.AttributeModifier; -import net.minecraft.entity.ai.attributes.Attributes; +import net.fabricmc.fabric.api.client.event.lifecycle.v1.ClientTickEvents; +import net.minecraft.client.MinecraftClient; +import net.minecraft.client.network.AbstractClientPlayerEntity; +import net.minecraft.client.render.entity.model.BipedEntityModel; +import net.minecraft.entity.EquipmentSlot; +import net.minecraft.entity.attribute.EntityAttribute; +import net.minecraft.entity.attribute.EntityAttributeModifier; +import net.minecraft.entity.attribute.EntityAttributes; import net.minecraft.entity.player.PlayerEntity; -import net.minecraft.entity.player.ServerPlayerEntity; -import net.minecraft.entity.projectile.AbstractArrowEntity; -import net.minecraft.inventory.EquipmentSlotType; -import net.minecraft.item.Item; +import net.minecraft.item.AxeItem; +import net.minecraft.item.HoeItem; import net.minecraft.item.ItemStack; -import net.minecraft.util.HandSide; -import net.minecraft.util.ResourceLocation; -import net.minecraft.util.SoundEvent; -import net.minecraft.util.SoundEvents; +import net.minecraft.item.PickaxeItem; +import net.minecraft.item.ShovelItem; +import net.minecraft.item.SwordItem; +import net.minecraft.server.network.ServerPlayerEntity; +import net.minecraft.server.world.ServerWorld; +import net.minecraft.sound.SoundEvent; +import net.minecraft.sound.SoundEvents; +import net.minecraft.util.Arm; import net.minecraft.util.math.MathHelper; -import net.minecraft.util.text.TranslationTextComponent; -import net.minecraft.world.GameType; -import net.minecraft.world.World; -import net.minecraftforge.api.distmarker.Dist; -import net.minecraftforge.api.distmarker.OnlyIn; -import net.minecraftforge.client.event.FOVUpdateEvent; -import net.minecraftforge.client.event.InputEvent.KeyInputEvent; -import net.minecraftforge.client.event.InputUpdateEvent; -import net.minecraftforge.client.event.RenderGameOverlayEvent; -import net.minecraftforge.client.event.RenderGameOverlayEvent.ElementType; -import net.minecraftforge.client.event.RenderPlayerEvent; -import net.minecraftforge.common.MinecraftForge; -import net.minecraftforge.common.ToolType; -import net.minecraftforge.event.AttachCapabilitiesEvent; -import net.minecraftforge.event.TickEvent; -import net.minecraftforge.event.TickEvent.PlayerTickEvent; -import net.minecraftforge.event.entity.item.ItemTossEvent; -import net.minecraftforge.eventbus.api.SubscribeEvent; -import net.minecraftforge.fml.ModList; +import net.minecraft.util.math.Vec3f; -public class EventsHandler { - - public static final ResourceLocation THROWPOWER = new ResourceLocation(Reference.MODID, "throw_power"); - - public static final int ITEMPHYSICSBLOCKING = -32; +public class EventsHandler{ - //ClientSide - public boolean wasPressed = false; - - public float clientSideCharge; - - public static void onThrowItem(ServerPlayerEntity playerentity, int action) { - - World worldIn = playerentity.world; - ItemStack stack = playerentity.getHeldItemMainhand(); - - boolean isThrowable = WeaponThrowConfig.COMMON.shouldThrowItemsToo.get(); - for(Item item: WeaponThrowConfig.COMMON.whiteList.get()) { - if(stack.getItem().equals(item)){ - isThrowable = true; - } - } + public static boolean wasPressed = false; + + public static void onThrowItem(ServerPlayerEntity serverplayer, CPacketThrow.State action){ - if(ModList.get().isLoaded("pmmo") && WeaponThrowConfig.COMMON.enablePMMOIntegration.get()) { - - ResourceLocation resLoc = playerentity.getHeldItemMainhand().getItem().getRegistryName(); - Map weaponReq = XP.getJsonMap( resLoc, JType.REQ_WEAPON ); - double reqLevel = 0; - - if(weaponReq.containsKey(Skill.COMBAT.name.toLowerCase())) { - reqLevel = weaponReq.get(Skill.COMBAT.name.toLowerCase()); - } - - int combatLevel = Skill.getLevel(Skill.COMBAT.name.toLowerCase(), playerentity.getUniqueID()); - - if((reqLevel > combatLevel) && reqLevel > 0) { - - playerentity.sendStatusMessage(new TranslationTextComponent("weaponthrow.pmmo.requirementThrowing", reqLevel), true); - return; - } - - } - - WeaponThrowEvent.TestThrow testEvent = new WeaponThrowEvent.TestThrow(stack, playerentity); - boolean isCancelled = MinecraftForge.EVENT_BUS.post(testEvent); + ServerWorld world = serverplayer.getWorld(); + ItemStack stack = ((PlayerEntity) serverplayer).getMainHandStack(); + + boolean isThrowable = ConfigRegistry.COMMON.get().experimental.shouldThrowItemsToo; + + Multimap multimap = stack.getAttributeModifiers(EquipmentSlot.MAINHAND); + boolean haveAttributes = multimap.containsKey(EntityAttributes.GENERIC_ATTACK_DAMAGE) || multimap.containsKey(EntityAttributes.GENERIC_ATTACK_SPEED); - Multimap multimap = stack.getAttributeModifiers(EquipmentSlotType.MAINHAND); - boolean haveAttributes = multimap.containsKey(Attributes.field_233823_f_) || multimap.containsKey(Attributes.field_233825_h_); + PlayerThrowData data = ((IPlayerEntityMixin) (PlayerEntity) serverplayer).getThrowPower(); - if((isThrowable || haveAttributes) && !isCancelled && !stack.isEmpty()) { + if ((isThrowable || haveAttributes) && !stack.isEmpty()) { - boolean cdConfig = WeaponThrowConfig.COMMON.notUseWhenCooldown.get(); - if(!(playerentity.getCooldownTracker().getCooldown(stack.getItem(), 1.0F) > 0 && cdConfig)) { + boolean cdConfig = ConfigRegistry.COMMON.get().general.notUseWhenCooldown; + + if(!(((PlayerEntity) serverplayer).getItemCooldownManager().getCooldownProgress(stack.getItem(), 1.0F) > 0 && cdConfig)) { - IThrowPower provider = playerentity.getCapability(ThrowProvider.THROW_POWER).orElse(ThrowProvider.THROW_POWER.getDefaultInstance()); - - if(action == 1 && provider.getChargeTime() <= 0 ) { - provider.setChargeTime(EventsHandler.getMaximumCharge(playerentity)); - + data.setAction(action); + + if(action.equals(CPacketThrow.State.START) && data.getChargeTime() <= 0) { + data.startCharging(stack); } - - if(action == 0 && provider.getChargeTime() >= 0) { - + + if(action.equals(CPacketThrow.State.FINISH) && data.getChargeTime() >= 0 ) { + float baseThrow = 0; float baseExhaustion = 0.05F; + + float modThrow = 1.0F; - float modThrow = 1.F - (provider.getChargeTime()/(float)EventsHandler.getMaximumCharge(playerentity)); + if(Math.signum(PlayerThrowData.getMaximumCharge((PlayerEntity) serverplayer)) != 0.0F) { + modThrow = 1.F - (data.getChargeTime()/(float)PlayerThrowData.getMaximumCharge((PlayerEntity) serverplayer)); + } - provider.setChargeTime(ITEMPHYSICSBLOCKING); + data.resetCharging(); - double defaultVelocity = WeaponThrowConfig.COMMON.baseVelocityDefault.get(); - - if (WeaponThrowConfig.COMMON.shouldThrowItemsToo.get()){ + double defaultVelocity = ConfigRegistry.COMMON.get().defaults.velocityDefault; + + if (ConfigRegistry.COMMON.get().experimental.shouldThrowItemsToo){ baseThrow = (float) defaultVelocity; } - else if (!WeaponThrowConfig.COMMON.whiteList.get().isEmpty()) { - for(Item item: WeaponThrowConfig.COMMON.whiteList.get()) { - if(stack.getItem().equals(item)){ - baseThrow = (float) defaultVelocity; - } - } - - } if(haveAttributes) { - baseThrow = 20/playerentity.getCooldownPeriod(); - baseExhaustion = playerentity.getCooldownPeriod()/20; + baseThrow = 20/ ((PlayerEntity) serverplayer).getAttackCooldownProgressPerTick(); + baseExhaustion = ((PlayerEntity) serverplayer).getAttackCooldownProgressPerTick()/20; } - + if(baseThrow>0) { boolean shouldDestroy = modThrow > 0.99; - float baseDamage = 0.01F; + double baseDamage = ConfigRegistry.COMMON.get().defaults.baseDamageDefault; double toolMultiplier = 0.0D; - double defaultDamage = WeaponThrowConfig.COMMON.baseDamageDefault.get(); - - if (!WeaponThrowConfig.COMMON.whiteList.get().isEmpty()) { - for(Item item: WeaponThrowConfig.COMMON.whiteList.get()) { - if(stack.getItem().equals(item)){ - baseDamage = (float) defaultDamage; - baseExhaustion = 1/baseThrow; - } - } - } + if(haveAttributes) { - baseDamage = (float) playerentity.func_233637_b_(Attributes.field_233823_f_); - - Set types = stack.getToolTypes(); + baseDamage = (float) ((PlayerEntity) serverplayer).getAttributeValue(EntityAttributes.GENERIC_ATTACK_DAMAGE); - if(types.contains(ToolType.AXE)) { - toolMultiplier += WeaponThrowConfig.COMMON.axeMultiplier.get(); + int types = 0; + if(stack.getItem() instanceof AxeItem) { + toolMultiplier += ConfigRegistry.COMMON.get().multipliers.tools.axeMultiplier; + types++; } - if(types.contains(ToolType.HOE)) { - toolMultiplier += WeaponThrowConfig.COMMON.hoeMultiplier.get(); + if(stack.getItem() instanceof HoeItem) { + toolMultiplier += ConfigRegistry.COMMON.get().multipliers.tools.hoeMultiplier; + types++; } - if(types.contains(ToolType.PICKAXE)) { - toolMultiplier += WeaponThrowConfig.COMMON.pickaxeMultiplier.get(); + if(stack.getItem() instanceof PickaxeItem) { + toolMultiplier += ConfigRegistry.COMMON.get().multipliers.tools.pickaxeMultiplier; + types++; } - if(types.contains(ToolType.SHOVEL)) { - toolMultiplier += WeaponThrowConfig.COMMON.shovelMultiplier.get(); + if(stack.getItem() instanceof ShovelItem) { + toolMultiplier += ConfigRegistry.COMMON.get().multipliers.tools.shovelMultiplier; + types++; } - if(types.isEmpty()) { - toolMultiplier = WeaponThrowConfig.COMMON.swordMultiplier.get(); + if(stack.getItem() instanceof SwordItem) { + toolMultiplier = ConfigRegistry.COMMON.get().multipliers.tools.swordMultiplier; + types++; } - toolMultiplier/=(types.size()>0? types.size() : 1); + toolMultiplier/=(types>0? types : 1); } @@ -198,246 +133,209 @@ else if (!WeaponThrowConfig.COMMON.whiteList.get().isEmpty()) { toolMultiplier = 1.0F; } - double bDamageMul = WeaponThrowConfig.COMMON.baseDamageMultiplier.get(); - double sDamageMul = WeaponThrowConfig.COMMON.stackDamageMultiplier.get(); - double mDamageMul = WeaponThrowConfig.COMMON.modifiedDamageMultiplier.get(); - double totalDamage = (baseDamage)*(1*bDamageMul + modThrow*mDamageMul) + (stack.getCount()*sDamageMul); + int size = ((PlayerEntity) serverplayer).isSneaking() ? stack.getCount() : 1; + + double bDamageMul = ConfigRegistry.COMMON.get().multipliers.damages.baseDamageMultiplier; + double sDamageMul = ConfigRegistry.COMMON.get().multipliers.damages.stackDamageMultiplier; + double mDamageMul = ConfigRegistry.COMMON.get().multipliers.damages.modifiedDamageMultiplier; + double totalDamage = (baseDamage)*(1*bDamageMul + modThrow*mDamageMul) + (size*sDamageMul); totalDamage*=toolMultiplier; - double bVelocityMul = WeaponThrowConfig.COMMON.baseVelocityMultiplier.get(); - double sVelocityMul = WeaponThrowConfig.COMMON.stackVelocityMultiplier.get(); - double mVelocityMul = WeaponThrowConfig.COMMON.modifiedVelocityMultiplier.get(); - double totalVelocity = (baseThrow)*(1*bVelocityMul + modThrow*mVelocityMul) - (stack.getCount()*sVelocityMul); + double bVelocityMul = ConfigRegistry.COMMON.get().multipliers.velocities.baseVelocityMultiplier; + double sVelocityMul = ConfigRegistry.COMMON.get().multipliers.velocities.stackVelocityMultiplier; + double mVelocityMul = ConfigRegistry.COMMON.get().multipliers.velocities.modifiedVelocityMultiplier; + double totalVelocity = (baseThrow)*(1*bVelocityMul + modThrow*mVelocityMul) - (size*sVelocityMul); totalVelocity*=toolMultiplier; - double bExhaustionMul = WeaponThrowConfig.COMMON.baseExhaustionMultiplier.get(); - double sExhaustionMul = WeaponThrowConfig.COMMON.stackExhaustionMultiplier.get(); - double mExhaustionMul = WeaponThrowConfig.COMMON.modifiedExhaustionMultiplier.get(); - double totalExhaustion = (baseExhaustion)*(1*bExhaustionMul + modThrow*mExhaustionMul) + (stack.getCount()*sExhaustionMul); + double bExhaustionMul = ConfigRegistry.COMMON.get().multipliers.exhaustions.baseExhaustionMultiplier; + double sExhaustionMul = ConfigRegistry.COMMON.get().multipliers.exhaustions.stackExhaustionMultiplier; + double mExhaustionMul = ConfigRegistry.COMMON.get().multipliers.exhaustions.modifiedExhaustionMultiplier; + double totalExhaustion = (baseExhaustion)*(1*bExhaustionMul + modThrow*mExhaustionMul) + (size*sExhaustionMul); totalExhaustion*=toolMultiplier; - - WeaponThrowEvent.OnThrow onThrowEvent = new WeaponThrowEvent.OnThrow(stack, playerentity, totalDamage, totalVelocity, totalExhaustion); - MinecraftForge.EVENT_BUS.post(onThrowEvent); - - - WeaponThrowEntity throwedEntity = new WeaponThrowEntity(worldIn, playerentity, shouldDestroy, (float) onThrowEvent.totalDamage, stack); - throwedEntity.func_234612_a_(playerentity, playerentity.rotationPitch, playerentity.rotationYaw, 0.0F, (float) onThrowEvent.totalVelocity, 1.0F); - playerentity.addExhaustion((float) onThrowEvent.totalExhaustion); + + WeaponThrowEntity throwedEntity = new WeaponThrowEntity(world, (PlayerEntity) serverplayer, shouldDestroy, (float) totalDamage, stack.split(size)); + throwedEntity.setVelocity((PlayerEntity) serverplayer, ((PlayerEntity) serverplayer).getPitch(), ((PlayerEntity) serverplayer).getYaw(), 0.0F, (float) totalVelocity, 1.0F); + ((PlayerEntity) serverplayer).addExhaustion((float) totalExhaustion); - worldIn.addEntity(throwedEntity); + world.spawnEntity(throwedEntity); SoundEvent soundevent = SoundEvents.ENTITY_EGG_THROW; throwedEntity.playSound(soundevent, 1.0F, 0.5F); - - if (playerentity.abilities.isCreativeMode) { - throwedEntity.pickupStatus = AbstractArrowEntity.PickupStatus.CREATIVE_ONLY; - if(!WeaponThrowConfig.COMMON.creativeSpamming.get()) { - playerentity.inventory.deleteStack(stack); - } - }else { - playerentity.inventory.deleteStack(stack); - } - - + } } + + ((IPlayerEntityMixin) (PlayerEntity) serverplayer).setThrowPower(data); + } + } + + /*if(stack.isEmpty() || !data.getChargingStack().equals(stack)) { + data.resetCharging(); + }*/ + } - @SubscribeEvent - public void onItemCrash(ItemTossEvent event) - { - - } - @SubscribeEvent - public void onPlayerToss(ItemTossEvent event) - { - event.getPlayer().getCapability(ThrowProvider.THROW_POWER).ifPresent(cap -> { - if (cap.getChargeTime() <= ITEMPHYSICSBLOCKING) { - cap.setChargeTime(-1); - if (ModList.get().isLoaded("itemphysic") && WeaponThrowConfig.COMMON.enableItemPhysicsFix.get()) { - event.setCanceled(true); - } + + public static void registerEvents(){ + OnStartPlayerTick.EVENT.register((player)->{ + if(!player.world.isClient()) { + PlayerThrowData cap = ((IPlayerEntityMixin)player).getThrowPower(); + + boolean attacked = player.getAttackCooldownProgress(0.0F) < 1.0F; + boolean cdConfig = ConfigRegistry.COMMON.get().general.notUseWhenCooldown; + + boolean changedItem = !ItemStack.areEqual(cap.getChargingStack(), player.getMainHandStack()); + + if (attacked && cdConfig || changedItem) { + cap.resetCharging(); + } + + if (cap.getChargeTime() > 0) { + cap.setChargeTime(cap.getChargeTime() - 1); } - }); - } - - @SubscribeEvent - public void attachCapability(AttachCapabilitiesEvent event) - { - if (!(event.getObject() instanceof PlayerEntity)) return; - - event.addCapability(THROWPOWER, new ThrowProvider()); - } - - @SubscribeEvent - public void onPlayerTick(PlayerTickEvent event) - { - - if(event.phase.equals(TickEvent.Phase.START)) { - - if(!event.player.world.isRemote) { - event.player.getCapability(ThrowProvider.THROW_POWER).ifPresent(cap -> { - - boolean attacked = event.player.getCooledAttackStrength(0.0F) < 1.0F ? true: false; - boolean cdConfig = WeaponThrowConfig.COMMON.notUseWhenCooldown.get(); + + if(cap.getAction().equals(CPacketThrow.State.START) || cap.getAction().equals(CPacketThrow.State.FINISH)) { + + PacketHandler.sendToAll(player, new SPacketThrow(player.getUuid(), PlayerThrowData.getMaximumCharge(player), cap.getAction().equals(CPacketThrow.State.START))); - if(attacked && cdConfig) { - cap.setChargeTime(-1); + if(cap.getAction().equals(CPacketThrow.State.FINISH)) { + cap.setAction(State.NONE); } - - if(cap.getChargeTime() > 0) { - cap.setChargeTime(cap.getChargeTime()-1); - } - - - if(cap.doesMaxChargeChanged()) { - PacketHandler.sendToAll(new SPacketThrow(PlayerEntity.getUUID(event.player.getGameProfile()), (int) (cap.getChargeTime() >= 0? EventsHandler.getMaximumCharge(event.player): cap.getChargeTime()))); - } - - cap.tick(); - }); - }else { - this.clientSideCharge++; - } - } - } - - public static int getMaximumCharge(PlayerEntity player) { - return MathHelper.floor(player.getCooldownPeriod()*WeaponThrowConfig.COMMON.castTimeInTicks.get()); - } - - @OnlyIn(Dist.CLIENT) - public static void onSeverUpdate(UUID playerUUID, int chargeTime) { - PlayerEntity playerentity = Minecraft.getInstance().world.getPlayerByUuid(playerUUID); + } + }else { + PlayerThrowData cap = ((IPlayerEntityMixin)player).getThrowPower(); + + if(cap.getChargeTime() > 0) { + cap.setChargeTime(cap.getChargeTime()-1); + } + + //clientSideCharge = cap.getAction().equals(State.DURING)? clientSideCharge+1 : 0; + } + }); + + } + + public static void onSeverUpdate(UUID playerUUID, int maxChargeTime, boolean isCharging) { + assert MinecraftClient.getInstance().world != null; + PlayerEntity playerentity = MinecraftClient.getInstance().world.getPlayerByUuid(playerUUID); + if(playerentity != null) { - if(playerentity != null) { - playerentity.getCapability(ThrowProvider.THROW_POWER).ifPresent(cap -> { - cap.setChargeTime(chargeTime); - - }); + PlayerThrowData cap = ((IPlayerEntityMixin)playerentity).getThrowPower(); + cap.MAX_CHARGE = maxChargeTime; + + if(isCharging) { + cap.setChargeTime(maxChargeTime); } - } + + cap.setAction(isCharging ? State.DURING : State.NONE); + + } + } - @OnlyIn(Dist.CLIENT) - @SubscribeEvent - public void renderView(RenderGameOverlayEvent.Post event) - { - - int maxChargeTime = Minecraft.getInstance().player.getCapability(ThrowProvider.THROW_POWER).orElse(ThrowProvider.THROW_POWER.getDefaultInstance()).getChargeTime(); - boolean isCharging = maxChargeTime >= 0 ? true : false; - - if(isCharging) { - if (Minecraft.getInstance().playerController.getCurrentGameType() != GameType.SPECTATOR) { - if(event.getType().equals(ElementType.CROSSHAIRS)) { - - - RenderSystem.blendFuncSeparate(GlStateManager.SourceFactor.ONE_MINUS_DST_COLOR, GlStateManager.DestFactor.ONE_MINUS_SRC_COLOR, GlStateManager.SourceFactor.ONE, GlStateManager.DestFactor.ZERO); - MatrixStack p_238456_1_ = event.getMatrixStack(); - - float f = MathHelper.clamp(this.clientSideCharge / maxChargeTime, 0.0F, 1.0F); + public static void registerClientEvents() { + OnHeldItemRender.EVENT.register((renderer, player, tickDelta, pitch, hand, swingProgress, item, equipProgress, matrices, vertexConsumers, light)->{ + + PlayerThrowData cap = ((IPlayerEntityMixin)player).getThrowPower(); + + if(cap.getAction().equals(State.DURING)) { + + //float progress = MathHelper.clamp((float)(EventsHandler.clientSideCharge+tickDelta)/cap.MAX_CHARGE, 0.F, 1.0F); + + float preProgress = 1.0F; + + /*if(Math.signum(cap.MAX_CHARGE) != 0.0F) { + preProgress = (float)(EventsHandler.clientSideCharge+tickDelta)/cap.MAX_CHARGE; + }*/ + + if(Math.signum(cap.MAX_CHARGE) != 0.0F && cap.getChargeTime() > 0) { + float lerp = MathHelper.lerp(tickDelta, cap.getChargeTime()+1, cap.getChargeTime()); + preProgress = 1.F-(float)(lerp)/cap.MAX_CHARGE; + } + + float progress = MathHelper.clamp(preProgress, 0.F, 1.0F); + + matrices.translate(0.0D, 0.0F, (double)((float)progress * 0.50F)); + matrices.multiply(Vec3f.POSITIVE_Z.getDegreesQuaternion((float)progress * 10.0F)); + matrices.multiply(Vec3f.POSITIVE_X.getDegreesQuaternion((float)progress * 40.0F)); + + } + }); - int scaledWidth = Minecraft.getInstance().getMainWindow().getScaledWidth(); - int scaledHeight = Minecraft.getInstance().getMainWindow().getScaledHeight(); - - IngameGui ingameGui = Minecraft.getInstance().ingameGUI; - - int j = scaledHeight / 2 + WeaponThrowConfig.COMMON.offsetY.get(); - int k = scaledWidth / 2 + WeaponThrowConfig.COMMON.offsetX.get(); + OnStartPlayerRender.EVENT.register((renderer, player)->{ + + PlayerThrowData cap = ((IPlayerEntityMixin)player).getThrowPower(); + if(cap.getAction().equals(State.DURING)) { + if(player instanceof AbstractClientPlayerEntity) { + Arm hand = ((AbstractClientPlayerEntity)player).getMainArm(); + if(hand == Arm.RIGHT) + renderer.getModel().rightArmPose = BipedEntityModel.ArmPose.THROW_SPEAR; + else + renderer.getModel().leftArmPose = BipedEntityModel.ArmPose.THROW_SPEAR; + } + } + }); + + OnApplySlow.EVENT.register((player)->{ + PlayerThrowData cap = ((IPlayerEntityMixin)player).getThrowPower(); + return cap.getAction().equals(State.DURING); + }); + + OnFOVUpdate.EVENT.register((player, amount)->{ + + PlayerThrowData cap = ((IPlayerEntityMixin)player).getThrowPower(); + + int maxChargeTime = cap.MAX_CHARGE; + + int chargeTime = cap.getChargeTime(); - if (f >= 1.0F) { - ingameGui.func_238474_b_(p_238456_1_, k, j, 68, 94, 16, 16); - } else{ - int l = (int)(f * 17.0F); - - ingameGui.func_238474_b_(p_238456_1_, k, j, 36, 94, 16, 4); - ingameGui.func_238474_b_(p_238456_1_, k, j, 52, 94, l, 4); - } - } - } - - }else if(!isCharging){ - this.clientSideCharge = 0; - } - } - @OnlyIn(Dist.CLIENT) - @SubscribeEvent - public void updateFov(FOVUpdateEvent event) - { - int maxChargeTime = Minecraft.getInstance().player.getCapability(ThrowProvider.THROW_POWER).orElse(ThrowProvider.THROW_POWER.getDefaultInstance()).getChargeTime(); - boolean isCharging = maxChargeTime >= 0 ? true : false; - - if(isCharging) { + boolean isCharging = cap.getAction().equals(State.DURING); + float f = amount; - float f = event.getFov(); - int i = (int) (this.clientSideCharge); - - float f1 = (float)i / maxChargeTime; - if (f1 > 1.0F) { - f1 = 1.0F; - } else { - f1 = f1 * f1; - } - - f *= 1.0F + f1 * 0.15F; - - event.setNewfov(f); + if(isCharging) { - } - } - - @OnlyIn(Dist.CLIENT) - @SubscribeEvent - public void renderPlayer(RenderPlayerEvent event) - { - event.getEntity().getCapability(ThrowProvider.THROW_POWER).ifPresent(cap -> { - - if(cap.getChargeTime() >= 0) { - if(event.getEntity() instanceof AbstractClientPlayerEntity) { - HandSide hand = ((AbstractClientPlayerEntity)event.getEntity()).getPrimaryHand(); - if(hand == HandSide.RIGHT) - event.getRenderer().getEntityModel().rightArmPose = BipedModel.ArmPose.THROW_SPEAR; - else - event.getRenderer().getEntityModel().leftArmPose = BipedModel.ArmPose.THROW_SPEAR; - } + float f1 = 1.0F; + + if(Math.signum(maxChargeTime) != 0.0F && chargeTime > 0) { + float lerp = MathHelper.lerp(MinecraftClient.getInstance().getTickDelta(), chargeTime+1, chargeTime); + f1 = MathHelper.clamp(1.0F-(float)lerp / maxChargeTime, 0.F, 1.0F); } - }); - } - - @OnlyIn(Dist.CLIENT) - @SubscribeEvent - public void inputUpdate(InputUpdateEvent event) - { - int maxChargeTime = Minecraft.getInstance().player.getCapability(ThrowProvider.THROW_POWER).orElse(ThrowProvider.THROW_POWER.getDefaultInstance()).getChargeTime(); - boolean isCharging = maxChargeTime >= 0 ? true : false; - - if(isCharging) { - event.getMovementInput().moveStrafe *= 0.2F; - event.getMovementInput().moveForward *= 0.2F; - } - - } + + if (f1 > 1.0F) { + f1 = 1.0F; + } else { + f1 = f1 * f1; + } + + f *= 1.0F + f1 * 0.15F; - @SubscribeEvent - public void onKeyInput(KeyInputEvent event) - { - boolean pressed = KeyBindingHandler.KEYBINDING.isKeyDown(); - - if (pressed && event.getAction() != 0) - { - PacketHandler.sendToServer(new CPacketThrow(this.wasPressed? 2: 1)); - this.wasPressed = true; - - } else if(this.wasPressed && event.getAction() == 0 && !pressed){ - - PacketHandler.sendToServer(new CPacketThrow(event.getAction())); - this.wasPressed = false; - } - - } + } + + return f; + }); + + ClientTickEvents.END_WORLD_TICK.register(client -> { + + boolean pressed = KeyBindingHandler.KEYBINDING.isPressed(); + + if (pressed) { + PacketHandler.sendToServer(new CPacketThrow(EventsHandler.wasPressed ? CPacketThrow.State.DURING: CPacketThrow.State.START)); + EventsHandler.wasPressed = true; + }else if(EventsHandler.wasPressed){ + PacketHandler.sendToServer(new CPacketThrow(CPacketThrow.State.FINISH)); + EventsHandler.wasPressed = false; + } + + }); + + } + } + + + diff --git a/src/main/java/com/dainxt/weaponthrow/handlers/KeyBindingHandler.java b/src/main/java/com/dainxt/weaponthrow/handlers/KeyBindingHandler.java index 9c341de..4befeea 100644 --- a/src/main/java/com/dainxt/weaponthrow/handlers/KeyBindingHandler.java +++ b/src/main/java/com/dainxt/weaponthrow/handlers/KeyBindingHandler.java @@ -2,14 +2,18 @@ import org.lwjgl.glfw.GLFW; -import net.minecraft.client.settings.KeyBinding; -import net.minecraft.client.util.InputMappings; -import net.minecraftforge.api.distmarker.Dist; -import net.minecraftforge.api.distmarker.OnlyIn; -import net.minecraftforge.client.settings.KeyConflictContext; -import net.minecraftforge.client.settings.KeyModifier; - -@OnlyIn(Dist.CLIENT) +import net.fabricmc.api.EnvType; +import net.fabricmc.api.Environment; +import net.fabricmc.fabric.api.client.keybinding.v1.KeyBindingHelper; +import net.minecraft.client.option.KeyBinding; +import net.minecraft.client.util.InputUtil; + +@Environment(EnvType.CLIENT) public class KeyBindingHandler { - public static final KeyBinding KEYBINDING = new KeyBinding("weaponthrow.throw", KeyConflictContext.UNIVERSAL, KeyModifier.ALT, InputMappings.Type.KEYSYM, GLFW.GLFW_KEY_Q, "weaponthrow.categories.throw"); + public static final KeyBinding KEYBINDING = KeyBindingHelper.registerKeyBinding(new KeyBinding("key.weaponthrow", InputUtil.Type.KEYSYM, GLFW.GLFW_KEY_R, KeyBinding.GAMEPLAY_CATEGORY)); + + public static void registerKeyBindings() { + + + } } diff --git a/src/main/java/com/dainxt/weaponthrow/handlers/PacketHandler.java b/src/main/java/com/dainxt/weaponthrow/handlers/PacketHandler.java index 74197cd..c4e80e1 100644 --- a/src/main/java/com/dainxt/weaponthrow/handlers/PacketHandler.java +++ b/src/main/java/com/dainxt/weaponthrow/handlers/PacketHandler.java @@ -1,50 +1,44 @@ package com.dainxt.weaponthrow.handlers; +import com.dainxt.weaponthrow.WeaponThrow; +import com.dainxt.weaponthrow.packets.BasePacket; import com.dainxt.weaponthrow.packets.CPacketThrow; +import com.dainxt.weaponthrow.packets.EntitySpawnPacket; import com.dainxt.weaponthrow.packets.SPacketThrow; -import com.dainxt.weaponthrow.util.Reference; -import net.minecraft.entity.player.ServerPlayerEntity; -import net.minecraft.util.ResourceLocation; -import net.minecraftforge.fml.network.NetworkDirection; -import net.minecraftforge.fml.network.NetworkRegistry; -import net.minecraftforge.fml.network.PacketDistributor; -import net.minecraftforge.fml.network.simple.SimpleChannel; +import net.fabricmc.fabric.api.client.networking.v1.ClientPlayNetworking; +import net.fabricmc.fabric.api.networking.v1.PlayerLookup; +import net.fabricmc.fabric.api.networking.v1.ServerPlayNetworking; +import net.minecraft.entity.Entity; +import net.minecraft.server.network.ServerPlayerEntity; +import net.minecraft.server.world.ServerWorld; +import net.minecraft.util.Identifier; public class PacketHandler { - private static final String PROTOCOL_VERSION = "1"; - public static final SimpleChannel INSTANCE = NetworkRegistry.newSimpleChannel( - new ResourceLocation(Reference.MODID, "main"), - () -> PROTOCOL_VERSION, - PROTOCOL_VERSION::equals, - PROTOCOL_VERSION::equals - ); - - public static void init() { - int id = 0; - INSTANCE.registerMessage(id++, CPacketThrow.class, CPacketThrow::encode, CPacketThrow::decode, CPacketThrow::handle); - INSTANCE.registerMessage(id++, SPacketThrow.class, SPacketThrow::encode, SPacketThrow::decode, SPacketThrow::handle); - } - - - public static void sendTo(ServerPlayerEntity playerMP, Object toSend) { - INSTANCE.sendTo(toSend, playerMP.connection.getNetworkManager(), NetworkDirection.PLAY_TO_CLIENT); + + public static final Identifier SPAWN_PACKET = new Identifier(WeaponThrow.MODID, "spawn_packet"); + + public static final Identifier CPACKET_THROW = new Identifier(WeaponThrow.MODID, "cpacket_throw"); + + public static final Identifier SPACKET_THROW = new Identifier(WeaponThrow.MODID, "spacket_throw"); + + public static void registerClientListeners() { + EntitySpawnPacket.register(); + SPacketThrow.register(); } - public static void sendToAll(Object toSend) { - INSTANCE.send(PacketDistributor.ALL.noArg(), toSend); + public static void registerServerListeners() { + CPacketThrow.register(); } - - public static void sendNonLocal(ServerPlayerEntity playerMP, Object toSend) { - if (playerMP.server.isDedicatedServer() || !playerMP.getGameProfile().getName().equals(playerMP.server.getServerOwner())) { - sendTo(playerMP, toSend); - } + + public static void sendToServer(BasePacket packet) { + ClientPlayNetworking.send(packet.getIdentifier(), packet.getBuf()); } - - public static void sendToServer(Object msg) { - INSTANCE.sendToServer(msg); + + public static void sendToAll(Entity entity, BasePacket packet) { + for (ServerPlayerEntity player : PlayerLookup.tracking((ServerWorld) entity.world, entity.getBlockPos())) { + ServerPlayNetworking.send(player, packet.getIdentifier(), packet.getBuf()); + } } - - private PacketHandler() {} - + } diff --git a/src/main/java/com/dainxt/weaponthrow/handlers/RenderRegistry.java b/src/main/java/com/dainxt/weaponthrow/handlers/RenderRegistry.java new file mode 100644 index 0000000..754087c --- /dev/null +++ b/src/main/java/com/dainxt/weaponthrow/handlers/RenderRegistry.java @@ -0,0 +1,13 @@ +package com.dainxt.weaponthrow.handlers; + +import com.dainxt.weaponthrow.entity.render.WeaponThrowRenderer; + +import net.fabricmc.fabric.api.client.rendering.v1.EntityRendererRegistry; + +public class RenderRegistry { + + public static void registerRenderers() { + EntityRendererRegistry.register(EntityRegistry.WEAPONTHROW, WeaponThrowRenderer::new); + + } +} diff --git a/src/main/java/com/dainxt/weaponthrow/interfaces/IPlayerEntityMixin.java b/src/main/java/com/dainxt/weaponthrow/interfaces/IPlayerEntityMixin.java new file mode 100644 index 0000000..faf5c0d --- /dev/null +++ b/src/main/java/com/dainxt/weaponthrow/interfaces/IPlayerEntityMixin.java @@ -0,0 +1,9 @@ +package com.dainxt.weaponthrow.interfaces; + +import com.dainxt.weaponthrow.capabilities.PlayerThrowData; + +public interface IPlayerEntityMixin { + public void setThrowPower(PlayerThrowData value); + + public PlayerThrowData getThrowPower(); +} diff --git a/src/main/java/com/dainxt/weaponthrow/mixins/IPlayerEntityMixin.java b/src/main/java/com/dainxt/weaponthrow/mixins/IPlayerEntityMixin.java new file mode 100644 index 0000000..63be274 --- /dev/null +++ b/src/main/java/com/dainxt/weaponthrow/mixins/IPlayerEntityMixin.java @@ -0,0 +1,9 @@ +package com.dainxt.weaponthrow.mixins; + +import com.dainxt.weaponthrow.capabilities.PlayerThrowData; + +public interface IPlayerEntityMixin { + public void setThrowPower(PlayerThrowData value); + + public PlayerThrowData getThrowPower(); +} diff --git a/src/main/java/com/dainxt/weaponthrow/mixins/PlayerEntityMixin.java b/src/main/java/com/dainxt/weaponthrow/mixins/PlayerEntityMixin.java new file mode 100644 index 0000000..de5b72d --- /dev/null +++ b/src/main/java/com/dainxt/weaponthrow/mixins/PlayerEntityMixin.java @@ -0,0 +1,33 @@ +package com.dainxt.weaponthrow.mixins; + +import com.dainxt.weaponthrow.capabilities.PlayerThrowData; +import com.dainxt.weaponthrow.events.OnStartPlayerTick; +import com.dainxt.weaponthrow.interfaces.IPlayerEntityMixin; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.Inject; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; + +import net.minecraft.entity.player.PlayerEntity; + +@Mixin(PlayerEntity.class) +public abstract class PlayerEntityMixin implements IPlayerEntityMixin { + + + public PlayerThrowData throwPower = new PlayerThrowData((PlayerEntity)(Object) this); + + @Override + public void setThrowPower(PlayerThrowData value) { + this.throwPower = value; + } + + @Override + public PlayerThrowData getThrowPower() { + return this.throwPower; + } + + @Inject(at = @At("HEAD"), method = "tick") + private void init(CallbackInfo info) { + OnStartPlayerTick.EVENT.invoker().interact((PlayerEntity)(Object)this); + } +} diff --git a/src/main/java/com/dainxt/weaponthrow/mixins/client/AbstractClientPlayerEntityMixin.java b/src/main/java/com/dainxt/weaponthrow/mixins/client/AbstractClientPlayerEntityMixin.java new file mode 100644 index 0000000..c54b256 --- /dev/null +++ b/src/main/java/com/dainxt/weaponthrow/mixins/client/AbstractClientPlayerEntityMixin.java @@ -0,0 +1,27 @@ +package com.dainxt.weaponthrow.mixins.client; + +import com.dainxt.weaponthrow.events.OnFOVUpdate; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.Inject; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; + +import net.minecraft.client.network.AbstractClientPlayerEntity; +import net.minecraft.entity.player.PlayerEntity; + +@Mixin(AbstractClientPlayerEntity.class) +public abstract class AbstractClientPlayerEntityMixin{ + + @Inject(method = "getFovMultiplier", at = @At("RETURN"), cancellable = true) + private void getSpeed(CallbackInfoReturnable info) { + PlayerEntity player = (PlayerEntity) (Object) this; + + float amount = info.getReturnValue(); + + float result = OnFOVUpdate.EVENT.invoker().interact(player, amount); + + info.setReturnValue(result); + + + } +} diff --git a/src/main/java/com/dainxt/weaponthrow/mixins/client/ClientPlayerEntityMixin.java b/src/main/java/com/dainxt/weaponthrow/mixins/client/ClientPlayerEntityMixin.java new file mode 100644 index 0000000..a90826d --- /dev/null +++ b/src/main/java/com/dainxt/weaponthrow/mixins/client/ClientPlayerEntityMixin.java @@ -0,0 +1,18 @@ +package com.dainxt.weaponthrow.mixins.client; + +import com.dainxt.weaponthrow.events.OnApplySlow; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.Inject; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; + +import net.minecraft.client.network.ClientPlayerEntity; +import net.minecraft.entity.player.PlayerEntity; + +@Mixin(ClientPlayerEntity.class) +public class ClientPlayerEntityMixin { + @Inject(at = @At("RETURN"), method = "shouldSlowDown", cancellable = true) + private void init(CallbackInfoReturnable info) { + info.setReturnValue(OnApplySlow.EVENT.invoker().interact((PlayerEntity)(Object)this) || info.getReturnValue()); + } +} diff --git a/src/main/java/com/dainxt/weaponthrow/mixins/client/HeldItemRendererMixin.java b/src/main/java/com/dainxt/weaponthrow/mixins/client/HeldItemRendererMixin.java new file mode 100644 index 0000000..6944132 --- /dev/null +++ b/src/main/java/com/dainxt/weaponthrow/mixins/client/HeldItemRendererMixin.java @@ -0,0 +1,23 @@ +package com.dainxt.weaponthrow.mixins.client; + +import com.dainxt.weaponthrow.events.OnHeldItemRender; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.Inject; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; + +import net.minecraft.client.network.AbstractClientPlayerEntity; +import net.minecraft.client.render.VertexConsumerProvider; +import net.minecraft.client.render.item.HeldItemRenderer; +import net.minecraft.client.util.math.MatrixStack; +import net.minecraft.item.ItemStack; +import net.minecraft.util.Hand; + +@Mixin(HeldItemRenderer.class) +public class HeldItemRendererMixin{ + + @Inject(method = "renderFirstPersonItem", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/network/AbstractClientPlayerEntity;isUsingRiptide()Z")) + private void renderCustom(AbstractClientPlayerEntity player, float tickDelta, float pitch, Hand hand, float swingProgress, ItemStack item, float equipProgress, MatrixStack matrices, VertexConsumerProvider vertexConsumers, int light, CallbackInfo info) { + OnHeldItemRender.EVENT.invoker().interact(((HeldItemRenderer)(Object)this), player, tickDelta, pitch, hand, swingProgress, item, equipProgress, matrices, vertexConsumers, light); + } +} diff --git a/src/main/java/com/dainxt/weaponthrow/mixins/client/PlayerEntityRendererMixin.java b/src/main/java/com/dainxt/weaponthrow/mixins/client/PlayerEntityRendererMixin.java new file mode 100644 index 0000000..2ccd587 --- /dev/null +++ b/src/main/java/com/dainxt/weaponthrow/mixins/client/PlayerEntityRendererMixin.java @@ -0,0 +1,19 @@ +package com.dainxt.weaponthrow.mixins.client; + +import com.dainxt.weaponthrow.events.OnStartPlayerRender; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.Inject; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; + +import net.minecraft.client.network.AbstractClientPlayerEntity; +import net.minecraft.client.render.entity.PlayerEntityRenderer; + +@Mixin(PlayerEntityRenderer.class) +public class PlayerEntityRendererMixin{ + + @Inject(method = "setModelPose", at = @At("TAIL")) + private void setModelPose(AbstractClientPlayerEntity player, CallbackInfo info) { + OnStartPlayerRender.EVENT.invoker().interact(((PlayerEntityRenderer)(Object)this), player); + } +} diff --git a/src/main/java/com/dainxt/weaponthrow/packets/BasePacket.java b/src/main/java/com/dainxt/weaponthrow/packets/BasePacket.java new file mode 100644 index 0000000..e8aa170 --- /dev/null +++ b/src/main/java/com/dainxt/weaponthrow/packets/BasePacket.java @@ -0,0 +1,25 @@ +package com.dainxt.weaponthrow.packets; + +import io.netty.buffer.Unpooled; +import net.minecraft.network.PacketByteBuf; +import net.minecraft.util.Identifier; + +public abstract class BasePacket { + + private Identifier identifier; + + protected PacketByteBuf buf; + + public BasePacket(Identifier id) { + this.identifier = id; + this.buf = new PacketByteBuf(Unpooled.buffer()); + } + + public PacketByteBuf getBuf() { + return this.buf; + } + + public Identifier getIdentifier() { + return this.identifier; + } +} diff --git a/src/main/java/com/dainxt/weaponthrow/packets/CPacketThrow.java b/src/main/java/com/dainxt/weaponthrow/packets/CPacketThrow.java index 26ab462..df009bd 100644 --- a/src/main/java/com/dainxt/weaponthrow/packets/CPacketThrow.java +++ b/src/main/java/com/dainxt/weaponthrow/packets/CPacketThrow.java @@ -1,31 +1,54 @@ package com.dainxt.weaponthrow.packets; -import java.util.function.Supplier; - import com.dainxt.weaponthrow.handlers.EventsHandler; +import com.dainxt.weaponthrow.handlers.PacketHandler; -import net.minecraft.network.PacketBuffer; -import net.minecraftforge.fml.network.NetworkEvent; +import net.fabricmc.fabric.api.networking.v1.ServerPlayNetworking; -public class CPacketThrow { - private final int action; +public class CPacketThrow extends BasePacket { - public CPacketThrow(int action) { - this.action = action; + public enum State { + NONE((byte)0), + START((byte)1), + DURING((byte)2), + FINISH((byte)3); + + private byte index; + private State(byte i) { + this.index = i; + + } + public byte toByte() { + return index; + } + + public static State fromByte(int index) { + for(State equipmentslottype : State.values()) { + if(equipmentslottype.toByte() == index) { + return equipmentslottype; + } + } + return NONE; + + } } - public static void encode(CPacketThrow msg, PacketBuffer buf) { - buf.writeInt(msg.action); + public CPacketThrow(State state) { + super(PacketHandler.CPACKET_THROW); + buf.writeByte(state.toByte()); } - public static CPacketThrow decode(PacketBuffer buf) { - return new CPacketThrow(buf.readInt()); + public static void register() { + + ServerPlayNetworking.registerGlobalReceiver(PacketHandler.CPACKET_THROW, (server, player, handler, buf, responseSender) -> { + CPacketThrow.State action = CPacketThrow.State.fromByte(buf.readByte()); + + server.execute(() -> { + + EventsHandler.onThrowItem(player, action); + }); + }); + } - public static void handle(CPacketThrow msg, Supplier ctx) { - if (ctx.get().getDirection().getReceptionSide().isServer()) { - ctx.get().enqueueWork(() -> EventsHandler.onThrowItem(ctx.get().getSender(), msg.action)); - } - ctx.get().setPacketHandled(true); - } } diff --git a/src/main/java/com/dainxt/weaponthrow/packets/EntitySpawnPacket.java b/src/main/java/com/dainxt/weaponthrow/packets/EntitySpawnPacket.java new file mode 100644 index 0000000..0bfd729 --- /dev/null +++ b/src/main/java/com/dainxt/weaponthrow/packets/EntitySpawnPacket.java @@ -0,0 +1,136 @@ +package com.dainxt.weaponthrow.packets; + +import java.util.UUID; + +import com.dainxt.weaponthrow.handlers.PacketHandler; + +import io.netty.buffer.Unpooled; +import net.fabricmc.fabric.api.client.networking.v1.ClientPlayNetworking; +import net.fabricmc.fabric.api.networking.v1.ServerPlayNetworking; +import net.minecraft.client.MinecraftClient; +import net.minecraft.entity.Entity; +import net.minecraft.entity.EntityType; +import net.minecraft.network.Packet; +import net.minecraft.network.PacketByteBuf; +import net.minecraft.util.math.MathHelper; +import net.minecraft.util.math.Vec3d; +import net.minecraft.util.registry.Registry; + +public class EntitySpawnPacket { + + public static Packet create(Entity e) { + if (e.world.isClient) + throw new IllegalStateException("SpawnPacketUtil.create called on the logical client!"); + PacketByteBuf byteBuf = new PacketByteBuf(Unpooled.buffer()); + byteBuf.writeVarInt(Registry.ENTITY_TYPE.getRawId(e.getType())); + byteBuf.writeUuid(e.getUuid()); + byteBuf.writeVarInt(e.getId()); + + PacketBufUtil.writeVec3d(byteBuf, e.getPos()); + PacketBufUtil.writeAngle(byteBuf, e.getPitch()); + PacketBufUtil.writeAngle(byteBuf, e.getYaw()); + return ServerPlayNetworking.createS2CPacket(PacketHandler.SPAWN_PACKET, byteBuf); + } + + + public static final class PacketBufUtil { + + /** + * Packs a floating-point angle into a {@code byte}. + * + * @param angle + * angle + * @return packed angle + */ + public static byte packAngle(float angle) { + return (byte) MathHelper.floor(angle * 256 / 360); + } + + /** + * Unpacks a floating-point angle from a {@code byte}. + * + * @param angleByte + * packed angle + * @return angle + */ + public static float unpackAngle(byte angleByte) { + return (angleByte * 360) / 256f; + } + + /** + * Writes an angle to a {@link PacketByteBuf}. + * + * @param byteBuf + * destination buffer + * @param angle + * angle + */ + public static void writeAngle(PacketByteBuf byteBuf, float angle) { + byteBuf.writeByte(packAngle(angle)); + } + + /** + * Reads an angle from a {@link PacketByteBuf}. + * + * @param byteBuf + * source buffer + * @return angle + */ + public static float readAngle(PacketByteBuf byteBuf) { + return unpackAngle(byteBuf.readByte()); + } + + /** + * Writes a {@link Vec3d} to a {@link PacketByteBuf}. + * + * @param byteBuf + * destination buffer + * @param vec3d + * vector + */ + public static void writeVec3d(PacketByteBuf byteBuf, Vec3d vec3d) { + byteBuf.writeDouble(vec3d.x); + byteBuf.writeDouble(vec3d.y); + byteBuf.writeDouble(vec3d.z); + } + + /** + * Reads a {@link Vec3d} from a {@link PacketByteBuf}. + * + * @param byteBuf + * source buffer + * @return vector + */ + public static Vec3d readVec3d(PacketByteBuf byteBuf) { + double x = byteBuf.readDouble(); + double y = byteBuf.readDouble(); + double z = byteBuf.readDouble(); + return new Vec3d(x, y, z); + } + } + + public static void register() { + ClientPlayNetworking.registerGlobalReceiver(PacketHandler.SPAWN_PACKET, (client, handler, buf, responseSender) -> { + EntityType et = Registry.ENTITY_TYPE.get(buf.readVarInt()); + UUID uuid = buf.readUuid(); + int entityId = buf.readVarInt(); + Vec3d pos = EntitySpawnPacket.PacketBufUtil.readVec3d(buf); + float pitch = EntitySpawnPacket.PacketBufUtil.readAngle(buf); + float yaw = EntitySpawnPacket.PacketBufUtil.readAngle(buf); + client.execute(() -> { + if (MinecraftClient.getInstance().world == null) + throw new IllegalStateException("Tried to spawn entity in a null world!"); + Entity e = et.create(MinecraftClient.getInstance().world); + if (e == null) + throw new IllegalStateException("Failed to create instance of entity \"" + Registry.ENTITY_TYPE.getId(et) + "\"!"); + e.updateTrackedPosition(pos.x,pos.y,pos.z); + e.setPos(pos.x, pos.y, pos.z); + e.setPitch(pitch); + e.setYaw(yaw); + e.setId(entityId); + e.setUuid(uuid); + MinecraftClient.getInstance().world.addEntity(entityId, e); + }); + }); + } +} diff --git a/src/main/java/com/dainxt/weaponthrow/packets/SPacketThrow.java b/src/main/java/com/dainxt/weaponthrow/packets/SPacketThrow.java index ff9131d..e242af9 100644 --- a/src/main/java/com/dainxt/weaponthrow/packets/SPacketThrow.java +++ b/src/main/java/com/dainxt/weaponthrow/packets/SPacketThrow.java @@ -1,35 +1,33 @@ package com.dainxt.weaponthrow.packets; import java.util.UUID; -import java.util.function.Supplier; import com.dainxt.weaponthrow.handlers.EventsHandler; +import com.dainxt.weaponthrow.handlers.PacketHandler; -import net.minecraft.network.PacketBuffer; -import net.minecraftforge.fml.network.NetworkEvent; +import net.fabricmc.fabric.api.client.networking.v1.ClientPlayNetworking; -public class SPacketThrow { - private final int progress; - private UUID playerAnimated; +public class SPacketThrow extends BasePacket { - public SPacketThrow(UUID player, int maxTime) { - this.progress = maxTime; - this.playerAnimated = player; - } - - public static void encode(SPacketThrow msg, PacketBuffer buf) { - buf.writeString(msg.playerAnimated.toString()); - buf.writeInt(msg.progress); + public SPacketThrow(UUID uuid, int maxChargeTime, boolean isCharging) { + super(PacketHandler.SPACKET_THROW); + buf.writeUuid(uuid); + buf.writeVarInt(maxChargeTime); + buf.writeBoolean(isCharging); } - public static SPacketThrow decode(PacketBuffer buf) { - return new SPacketThrow(UUID.fromString(buf.readString()), buf.readInt()); + public static void register() { + + ClientPlayNetworking.registerGlobalReceiver(PacketHandler.SPACKET_THROW, (client, handler, buf, responseSender) -> { + UUID uuid = buf.readUuid(); + int maxChargeTime = buf.readVarInt(); + boolean isCharging = buf.readBoolean(); + + client.execute(() -> { + EventsHandler.onSeverUpdate(uuid, maxChargeTime, isCharging); + }); + }); + } - public static void handle(SPacketThrow msg, Supplier ctx) { - if (ctx.get().getDirection().getReceptionSide().isClient()) { - ctx.get().enqueueWork(() -> EventsHandler.onSeverUpdate(msg.playerAnimated, msg.progress)); - } - ctx.get().setPacketHandled(true); - } } diff --git a/src/main/java/com/dainxt/weaponthrow/projectile/WeaponThrowEntity.java b/src/main/java/com/dainxt/weaponthrow/projectile/WeaponThrowEntity.java index 28d227f..6bd3b30 100644 --- a/src/main/java/com/dainxt/weaponthrow/projectile/WeaponThrowEntity.java +++ b/src/main/java/com/dainxt/weaponthrow/projectile/WeaponThrowEntity.java @@ -2,212 +2,192 @@ import java.util.List; -import javax.annotation.Nullable; +import org.jetbrains.annotations.Nullable; -import com.dainxt.weaponthrow.config.WeaponThrowConfig; -import com.dainxt.weaponthrow.events.WeaponThrowEvent; +import com.dainxt.weaponthrow.handlers.ConfigRegistry; import com.dainxt.weaponthrow.handlers.EnchantmentHandler; -import com.dainxt.weaponthrow.handlers.EntityHandler; +import com.dainxt.weaponthrow.handlers.EntityRegistry; -import harmonised.pmmo.skills.Skill; +import net.fabricmc.api.EnvType; +import net.fabricmc.api.Environment; +import net.fabricmc.api.EnvironmentInterface; import net.minecraft.block.AnvilBlock; import net.minecraft.block.Block; import net.minecraft.block.BlockState; +import net.minecraft.block.Blocks; import net.minecraft.block.SandBlock; import net.minecraft.block.TorchBlock; import net.minecraft.enchantment.EnchantmentHelper; import net.minecraft.enchantment.Enchantments; import net.minecraft.entity.Entity; import net.minecraft.entity.EntityType; -import net.minecraft.entity.IRendersAsItem; +import net.minecraft.entity.FlyingItemEntity; import net.minecraft.entity.LivingEntity; -import net.minecraft.entity.effect.LightningBoltEntity; +import net.minecraft.entity.damage.DamageSource; +import net.minecraft.entity.data.DataTracker; +import net.minecraft.entity.data.TrackedData; +import net.minecraft.entity.data.TrackedDataHandlerRegistry; +import net.minecraft.entity.effect.StatusEffectInstance; +import net.minecraft.entity.effect.StatusEffects; import net.minecraft.entity.player.PlayerEntity; -import net.minecraft.entity.player.ServerPlayerEntity; -import net.minecraft.entity.projectile.AbstractArrowEntity; +import net.minecraft.entity.projectile.PersistentProjectileEntity; import net.minecraft.item.BlockItem; import net.minecraft.item.Item; import net.minecraft.item.ItemStack; import net.minecraft.item.Items; -import net.minecraft.nbt.CompoundNBT; -import net.minecraft.network.IPacket; -import net.minecraft.network.datasync.DataParameter; -import net.minecraft.network.datasync.DataSerializers; -import net.minecraft.network.datasync.EntityDataManager; -import net.minecraft.potion.EffectInstance; -import net.minecraft.potion.Effects; -import net.minecraft.util.DamageSource; +import net.minecraft.nbt.NbtCompound; +import net.minecraft.nbt.NbtHelper; +import net.minecraft.network.Packet; +import net.minecraft.particle.ItemStackParticleEffect; +import net.minecraft.particle.ParticleTypes; +import net.minecraft.server.network.ServerPlayerEntity; +import net.minecraft.server.world.ServerWorld; +import net.minecraft.sound.SoundCategory; +import net.minecraft.sound.SoundEvent; +import net.minecraft.sound.SoundEvents; import net.minecraft.util.Hand; -import net.minecraft.util.SoundEvent; -import net.minecraft.util.SoundEvents; +import net.minecraft.util.hit.BlockHitResult; +import net.minecraft.util.hit.EntityHitResult; +import net.minecraft.util.hit.HitResult; import net.minecraft.util.math.BlockPos; -import net.minecraft.util.math.BlockRayTraceResult; -import net.minecraft.util.math.EntityRayTraceResult; -import net.minecraft.util.math.MathHelper; -import net.minecraft.util.math.RayTraceResult; -import net.minecraft.util.math.vector.Vector3d; -import net.minecraft.util.text.TranslationTextComponent; +import net.minecraft.util.math.Vec3d; import net.minecraft.world.World; -import net.minecraft.world.server.ServerWorld; -import net.minecraftforge.api.distmarker.Dist; -import net.minecraftforge.api.distmarker.OnlyIn; -import net.minecraftforge.common.MinecraftForge; -import net.minecraftforge.fml.ModList; -import net.minecraftforge.fml.network.NetworkHooks; - -@OnlyIn( - value = Dist.CLIENT, - _interface = IRendersAsItem.class + +@EnvironmentInterface( + value = EnvType.CLIENT, + itf = FlyingItemEntity.class ) -public class WeaponThrowEntity extends AbstractArrowEntity implements IRendersAsItem{ +public class WeaponThrowEntity extends PersistentProjectileEntity implements FlyingItemEntity{ private float clientSideRotation = 0; private boolean counterClockwiseBounce = true; - private static final DataParameter LOYALTY_LEVEL = EntityDataManager.createKey(WeaponThrowEntity.class, DataSerializers.BYTE); - private static final DataParameter COMPOUND_STACK = EntityDataManager.createKey(WeaponThrowEntity.class, DataSerializers.COMPOUND_NBT); - private static final DataParameter DESTROYED_BLOCK = EntityDataManager.createKey(WeaponThrowEntity.class, DataSerializers.BLOCK_POS); - private static final DataParameter SHOULD_DESTROY = EntityDataManager.createKey(WeaponThrowEntity.class, DataSerializers.BOOLEAN); + private static final TrackedData LOYALTY_LEVEL = DataTracker.registerData(WeaponThrowEntity.class, TrackedDataHandlerRegistry.BYTE); + private static final TrackedData COMPOUND_STACK = DataTracker.registerData(WeaponThrowEntity.class, TrackedDataHandlerRegistry.NBT_COMPOUND); + private static final TrackedData DESTROYED_BLOCK = DataTracker.registerData(WeaponThrowEntity.class, TrackedDataHandlerRegistry.BLOCK_POS); + private static final TrackedData SHOULD_DESTROY = DataTracker.registerData(WeaponThrowEntity.class, TrackedDataHandlerRegistry.BOOLEAN); - private boolean dealtDamage; + private boolean dealtDamage = false; private float attackDamage; public int returningTicks; - private int ticksInGround; + @Nullable + private BlockState lastState; public WeaponThrowEntity(EntityType type, World worldIn) { super(type, worldIn); } public WeaponThrowEntity(World worldIn, LivingEntity thrower, boolean canDestroy ,float attackDamage, ItemStack thrownStackIn) { - super(EntityHandler.WEAPONTHROW, thrower, worldIn); + super(EntityRegistry.WEAPONTHROW, thrower, worldIn); this.attackDamage = attackDamage; - this.dataManager.set(COMPOUND_STACK, thrownStackIn.copy().write(new CompoundNBT())); - this.dataManager.set(LOYALTY_LEVEL, (byte)WeaponThrowEntity.getReturnOrLoyaltyEnchantment(thrownStackIn)); - this.dataManager.set(DESTROYED_BLOCK, BlockPos.ZERO); - this.dataManager.set(SHOULD_DESTROY, canDestroy); + this.dataTracker.set(COMPOUND_STACK, thrownStackIn.copy().writeNbt(new NbtCompound())); + this.dataTracker.set(LOYALTY_LEVEL, (byte)WeaponThrowEntity.getReturnOrLoyaltyEnchantment(thrownStackIn)); + this.dataTracker.set(DESTROYED_BLOCK, BlockPos.ORIGIN); + this.dataTracker.set(SHOULD_DESTROY, canDestroy); } - @OnlyIn(Dist.CLIENT) public WeaponThrowEntity(World worldIn, double x, double y, double z) { - super(EntityHandler.WEAPONTHROW, x, y, z, worldIn); + super(EntityRegistry.WEAPONTHROW, x, y, z, worldIn); } - protected void registerData() { - super.registerData(); - this.dataManager.register(COMPOUND_STACK, new CompoundNBT()); - this.dataManager.register(LOYALTY_LEVEL, (byte)0); - this.dataManager.register(DESTROYED_BLOCK, BlockPos.ZERO); - this.dataManager.register(SHOULD_DESTROY, false); + protected void initDataTracker() { + super.initDataTracker(); + this.dataTracker.startTracking(COMPOUND_STACK, new NbtCompound()); + this.dataTracker.startTracking(LOYALTY_LEVEL, (byte)0); + this.dataTracker.startTracking(DESTROYED_BLOCK, BlockPos.ORIGIN); + this.dataTracker.startTracking(SHOULD_DESTROY, false); } public void setItemStack(ItemStack stack) { - this.getDataManager().set(COMPOUND_STACK, stack.write(new CompoundNBT())); + this.getDataTracker().set(COMPOUND_STACK, stack.writeNbt(new NbtCompound())); } public ItemStack getItemStack() { - return ItemStack.read(((CompoundNBT)this.getDataManager().get(COMPOUND_STACK))); + return ItemStack.fromNbt(((NbtCompound)this.getDataTracker().get(COMPOUND_STACK))); } public void shouldDestroy(boolean stack) { - this.getDataManager().set(SHOULD_DESTROY, stack); + this.getDataTracker().set(SHOULD_DESTROY, stack); } public boolean shouldDestroy() { - return ((Boolean)this.getDataManager().get(SHOULD_DESTROY)); + return ((Boolean)this.getDataTracker().get(SHOULD_DESTROY)); } public void setDestroyedBlock(BlockPos pos) { - this.getDataManager().set(DESTROYED_BLOCK, pos); + this.getDataTracker().set(DESTROYED_BLOCK, pos); } public BlockPos getDestroyedBlock() { - return ((BlockPos)this.getDataManager().get(DESTROYED_BLOCK)); + return ((BlockPos)this.getDataTracker().get(DESTROYED_BLOCK)); } public void tick() { - - if (this.timeInGround > 4 && !this.dealtDamage) { + + if (this.inGroundTime > 4 && !this.dealtDamage) { this.dealtDamage = true; } - if(!this.getDestroyedBlock().equals(BlockPos.ZERO) && !world.isRemote) { - if (((PlayerEntity)this.func_234616_v_()).abilities.isCreativeMode && WeaponThrowConfig.COMMON.creativeSpamming.get()) { - ((PlayerEntity)this.func_234616_v_()).setHeldItem(Hand.MAIN_HAND, this.getItemStack()); - - ((ServerPlayerEntity)this.func_234616_v_()).interactionManager.tryHarvestBlock(this.getDestroyedBlock()); - }else { - ((PlayerEntity)this.func_234616_v_()).setHeldItem(Hand.MAIN_HAND, this.getItemStack()); - - ((ServerPlayerEntity)this.func_234616_v_()).interactionManager.tryHarvestBlock(this.getDestroyedBlock()); - - if(((PlayerEntity)this.func_234616_v_()).getHeldItem(Hand.MAIN_HAND).isEmpty()) { - this.setItemStack(ItemStack.EMPTY); - }else { - ((PlayerEntity)this.func_234616_v_()).setHeldItem(Hand.MAIN_HAND, ItemStack.EMPTY); - } - - } + if(!this.getDestroyedBlock().equals(BlockPos.ZERO) && !this.world.isClient) { + + this.doInteractions(() -> { + SoundEvent event = this.world.getBlockState(this.getDestroyedBlock()).getSoundGroup().getBreakSound(); + boolean destroyed = ((ServerPlayerEntity)this.getOwner()).interactionManager.tryBreakBlock(this.getDestroyedBlock()); + if(destroyed) { + this.world.playSound(null, this.getDestroyedBlock(), event , SoundCategory.AMBIENT, 10, 1.0F); + } + }); - this.setDestroyedBlock(BlockPos.ZERO); + this.setDestroyedBlock(BlockPos.ORIGIN); } - int gravityLevel = WeaponThrowConfig.COMMON.gravityEnchant.get() ? EnchantmentHelper.getEnchantmentLevel(EnchantmentHandler.GRAVITY, this.getItemStack()) : 0; - if(gravityLevel > 0) { + int gravityWorld = ConfigRegistry.COMMON.get().enchantments.enableGravity ? EnchantmentHelper.getLevel(EnchantmentHandler.GRAVITY, this.getItemStack()) : 0; + if(gravityWorld > 0) { this.setNoGravity(true); - if(World.isOutsideBuildHeight(this.getPositionUnderneath())) { - this.setMotion(this.getMotion().mul(1, 0, 1)); + if(this.world.isOutOfHeightLimit(this.getBlockPos())) { + this.setVelocity(this.getVelocity().multiply(1, 0, 1)); } - if((Math.abs(this.getMotion().getX()) < 0.1 && Math.abs(this.getMotion().getZ()) < 0.1)) { + if((Math.abs(this.getVelocity().getX()) < 0.1 && Math.abs(this.getVelocity().getZ()) < 0.1)) { - if(WeaponThrowConfig.COMMON.gravityDrop.get()) { - this.setNoGravity(false); - } + this.setNoGravity(false); } } - if(this.inGround && MathHelper.abs(this.rotationPitch) < 45 && this.getItemStack().getItem() instanceof BlockItem) { - - this.setMotion(this.getMotion().scale(-0.5F)); - this.counterClockwiseBounce = !this.counterClockwiseBounce; - this.inGround = false; - } + /*if(this.inGround && MathHelper.abs(this.getPitch()) < 45 && this.getItemStack().getItem() instanceof BlockItem) { + if(!(Math.abs(this.getVelocity().getX()) < 0.1 && Math.abs(this.getVelocity().getZ()) < 0.1)) { + this.setVelocity(this.getVelocity().multiply(-0.5F)); + this.counterClockwiseBounce = !this.counterClockwiseBounce; + this.inGround = false; + } + }*/ - Entity entity = this.func_234616_v_(); - if ((this.dealtDamage || this.getNoClip()) && entity != null) { - int i = WeaponThrowConfig.COMMON.returnEnchant.get() ? this.dataManager.get(LOYALTY_LEVEL) : 0; - - if (i > 0 && ModList.get().isLoaded("pmmo") && WeaponThrowConfig.COMMON.enablePMMOIntegration.get()) { - int combatLevel = Skill.getLevel(Skill.COMBAT.name.toLowerCase(), entity.getUniqueID()); - int requiredLevel = WeaponThrowConfig.COMMON.requiredCombatLoyalty.get(); - - if((requiredLevel > combatLevel) && requiredLevel > 0) { - if(entity instanceof PlayerEntity) { - ((PlayerEntity)entity).sendStatusMessage(new TranslationTextComponent("weaponthrow.pmmo.requirementLoyalty", requiredLevel), true); - } - i = 0; - } - } - - if (i > 0 && !this.shouldReturnToThrower()) { + Entity entity = this.getOwner(); + + + int i = ConfigRegistry.COMMON.get().enchantments.enableReturn ? this.dataTracker.get(LOYALTY_LEVEL) : 0; + + if (i > 0 && (this.dealtDamage || this.isNoClip()) && entity != null) { + + if (!this.shouldReturnToThrower()) { - if (!this.world.isRemote && this.pickupStatus == AbstractArrowEntity.PickupStatus.ALLOWED) { - this.entityDropItem(this.getArrowStack(), 0.1F); + if (!this.world.isClient && this.pickupType == PersistentProjectileEntity.PickupPermission.ALLOWED) { + this.dropStack(this.getItemStack(), 0.1F); } - this.remove(); + this.remove(RemovalReason.DISCARDED); } else if (i > 0) { this.setNoClip(true); - Vector3d vector3d = new Vector3d(entity.getPosX() - this.getPosX(), entity.getPosYEye() - this.getPosY(), entity.getPosZ() - this.getPosZ()); - this.setRawPosition(this.getPosX(), this.getPosY() + vector3d.y * 0.015D * (double)i, this.getPosZ()); - if (this.world.isRemote) { - this.lastTickPosY = this.getPosY(); + Vec3d Vec3d = entity.getEyePos().subtract(this.getPos()); + this.setPos(this.getX(), this.getY() + Vec3d.y * 0.015D * (double)i, this.getZ()); + if (this.world.isClient) { + this.lastRenderY = this.getY(); } double d0 = 0.05D * (double)i; - this.setMotion(this.getMotion().scale(0.95D).add(vector3d.normalize().scale(d0))); + this.setVelocity(this.getVelocity().multiply(0.95D).add(Vec3d.normalize().multiply(d0))); if (this.returningTicks == 0) { this.playSound(SoundEvents.ITEM_TRIDENT_RETURN, 10.0F, 1.0F); } @@ -215,12 +195,11 @@ public void tick() { ++this.returningTicks; } } - super.tick(); } private boolean shouldReturnToThrower() { - Entity entity = this.func_234616_v_(); + Entity entity = this.getOwner(); if (entity != null && entity.isAlive()) { return !(entity instanceof ServerPlayerEntity) || !entity.isSpectator(); @@ -229,32 +208,39 @@ private boolean shouldReturnToThrower() { } } - protected ItemStack getArrowStack() { + protected ItemStack asItemStack() { return this.getItemStack().copy(); } @Nullable - protected EntityRayTraceResult rayTraceEntities(Vector3d startVec, Vector3d endVec) { - return this.dealtDamage ? null : super.rayTraceEntities(startVec, endVec); + protected EntityHitResult getEntityCollision(Vec3d p_37575_, Vec3d p_37576_) { + return this.dealtDamage ? null : super.getEntityCollision(p_37575_, p_37576_); } - - protected void onEntityHit(EntityRayTraceResult p_213868_1_) { + @Override + protected void onEntityHit(EntityHitResult p_213868_1_) { + + Entity entity = p_213868_1_.getEntity(); float f = this.attackDamage; if (entity instanceof LivingEntity) { LivingEntity livingentity = (LivingEntity)entity; - f += WeaponThrowConfig.COMMON.throwEnchant.get() ? EnchantmentHelper.getEnchantmentLevel(EnchantmentHandler.THROW, this.getItemStack())*1F : 0; - f += EnchantmentHelper.getModifierForCreature(this.getItemStack(), livingentity.getCreatureAttribute()); + f += ConfigRegistry.COMMON.get().enchantments.enableThrow ? EnchantmentHelper.getLevel(EnchantmentHandler.THROW, this.getItemStack())*1F : 0; + f += EnchantmentHelper.getAttackDamage(this.getItemStack(), livingentity.getGroup()); } - Entity entity1 = this.func_234616_v_(); - DamageSource damagesource = DamageSource.causeThrownDamage(this, (Entity)(entity1 == null ? this : entity1)); + Entity entity1 = this.getOwner(); + DamageSource damagesource = DamageSource.thrownProjectile(this, (Entity)(entity1 == null ? this : entity1)); + + + this.dealtDamage = true; SoundEvent soundevent = SoundEvents.ITEM_TRIDENT_HIT; - if (entity.attackEntityFrom(damagesource, f)) { + + if (entity.damage(damagesource, f)) { + if (entity.getType() == EntityType.ENDERMAN) { return; } @@ -263,55 +249,55 @@ protected void onEntityHit(EntityRayTraceResult p_213868_1_) { LivingEntity livingentity1 = (LivingEntity)entity; - int contusionLevel = WeaponThrowConfig.COMMON.conccusionEnchant.get() ? EnchantmentHelper.getEnchantmentLevel(EnchantmentHandler.CONCCUSION, this.getItemStack()) : 0; + int contusionWorld = ConfigRegistry.COMMON.get().enchantments.enableConccusion ? EnchantmentHelper.getLevel(EnchantmentHandler.CONCCUSION, this.getItemStack()) : 0; - if (contusionLevel > 0) { - livingentity1.addPotionEffect(new EffectInstance(Effects.SLOWNESS, 20*2*contusionLevel, 5)); - livingentity1.addPotionEffect(new EffectInstance(Effects.NAUSEA, 20*5*contusionLevel, 3)); + if (contusionWorld > 0) { + livingentity1.addStatusEffect(new StatusEffectInstance(StatusEffects.SLOWNESS, 20*2*contusionWorld, 5)); + livingentity1.addStatusEffect(new StatusEffectInstance(StatusEffects.NAUSEA, 20*5*contusionWorld, 3)); } - int fireTime = EnchantmentHelper.getEnchantmentLevel(Enchantments.FIRE_ASPECT, this.getItemStack()); - int groundedLevel = WeaponThrowConfig.COMMON.groundedEdgeEnchant.get() ? EnchantmentHelper.getEnchantmentLevel(EnchantmentHandler.GROUNDEDEDGE, this.getItemStack()) : 0; + int fireTime = EnchantmentHelper.getLevel(Enchantments.FIRE_ASPECT, this.getItemStack()); + int groundedWorld = ConfigRegistry.COMMON.get().enchantments.enableGroundedEdge ? EnchantmentHelper.getLevel(EnchantmentHandler.GROUNDEDEDGE, this.getItemStack()) : 0; - if(fireTime > 0 || groundedLevel > 0) { - List nearEntities = world.getEntitiesWithinAABB(LivingEntity.class, this.getBoundingBox().grow(1.0D)); + if(fireTime > 0 || groundedWorld > 0) { + List nearEntities = world.getNonSpectatingEntities(LivingEntity.class, this.getBoundingBox().expand(1.0D)); if(!nearEntities.isEmpty()) { for(LivingEntity nearEntity: nearEntities) { - if(nearEntity.getRNG().nextInt(3) == 0) { - nearEntity.setFire(fireTime); + if(nearEntity.getRandom().nextInt(3) == 0) { + nearEntity.setOnFireFor(fireTime); } if(true) { - nearEntity.addPotionEffect(new EffectInstance(Effects.WEAKNESS, 80, groundedLevel-1)); + nearEntity.addStatusEffect(new StatusEffectInstance(StatusEffects.WEAKNESS, 80, groundedWorld-1)); } } } } if (entity1 instanceof LivingEntity) { - EnchantmentHelper.applyThornEnchantments(livingentity1, entity1); - EnchantmentHelper.applyArthropodEnchantments((LivingEntity)entity1, livingentity1); + EnchantmentHelper.onUserDamaged(livingentity1, entity1); + EnchantmentHelper.onTargetDamaged((LivingEntity)entity1, livingentity1); } - this.arrowHit(livingentity1); + this.onHit(livingentity1); if(this.getItemStack().getItem() instanceof BlockItem) { Block blockItem = Block.getBlockFromItem(this.getItemStack().getItem()); if(blockItem instanceof SandBlock) { - if(livingentity1.getRNG().nextInt(10) == 0) livingentity1.addPotionEffect(new EffectInstance(Effects.BLINDNESS, 60, 3)); + if(livingentity1.getRandom().nextInt(10) == 0) livingentity1.addStatusEffect(new StatusEffectInstance(StatusEffects.BLINDNESS, 60, 3)); } else if (blockItem instanceof TorchBlock){ - if(livingentity1.getRNG().nextInt(5) == 0) livingentity1.setFire(1); + if(livingentity1.getRandom().nextInt(5) == 0) livingentity1.setOnFireFor(1); } else if (blockItem instanceof AnvilBlock){ - livingentity1.addPotionEffect(new EffectInstance(Effects.NAUSEA, 60, 3)); - livingentity1.addPotionEffect(new EffectInstance(Effects.SLOWNESS, 60, 5)); + livingentity1.addStatusEffect(new StatusEffectInstance(StatusEffects.NAUSEA, 60, 3)); + livingentity1.addStatusEffect(new StatusEffectInstance(StatusEffects.SLOWNESS, 60, 5)); } }else { Item itemThrowed = this.getItemStack().getItem(); if(itemThrowed.equals(Items.BLAZE_ROD) || itemThrowed.equals(Items.BLAZE_POWDER)) { - livingentity1.setFire(1); + livingentity1.setOnFireFor(1); } } } @@ -319,174 +305,226 @@ else if (blockItem instanceof AnvilBlock){ } - + this.setVelocity(this.getVelocity().multiply(-0.01D, -0.1D, -0.01D)); - - this.setMotion(this.getMotion().mul(-0.01D, -0.1D, -0.01D)); - float f1 = 1.0F; - if (this.world instanceof ServerWorld && this.world.isThundering() && EnchantmentHelper.hasChanneling(this.getItemStack())) { - BlockPos blockpos = entity.func_233580_cy_(); - if (this.world.canSeeSky(blockpos)) { - LightningBoltEntity lightningboltentity = EntityType.LIGHTNING_BOLT.create(this.world); - lightningboltentity.func_233576_c_(Vector3d.func_237492_c_(blockpos)); - lightningboltentity.setCaster(entity1 instanceof ServerPlayerEntity ? (ServerPlayerEntity)entity1 : null); - this.world.addEntity(lightningboltentity); - soundevent = SoundEvents.ITEM_TRIDENT_THUNDER; - f1 = 5.0F; - } - } - - this.playSound(soundevent, f1, 1.0F); + this.playSound(soundevent, 1.0F, 1.0F); + } - protected SoundEvent getHitEntitySound() { + + protected SoundEvent getHitSound() { return SoundEvents.BLOCK_METAL_HIT; } - public void onCollideWithPlayer(PlayerEntity entityIn) { + + public void onPlayerCollision(PlayerEntity entityIn) { - Entity entity = this.func_234616_v_(); + Entity entity = this.getOwner(); - if (entity == null || entity.getUniqueID() == entityIn.getUniqueID() || this.ticksInGround > (WeaponThrowConfig.COMMON.ticksUntilWeaponLoseOwner.get())) { - super.onCollideWithPlayer(entityIn); + if (entity == null || entity.getUuid() == entityIn.getUuid() || this.inGroundTime > (ConfigRegistry.COMMON.get().times.ticksUntilWeaponLoseOwner)) { + super.onPlayerCollision(entityIn); } } - - public void readAdditional(CompoundNBT compound) { - super.readAdditional(compound); + + public void readCustomDataFromNbt(NbtCompound compound) { + super.readCustomDataFromNbt(compound); this.dealtDamage = compound.getBoolean("DealtDamage"); if (compound.contains("Stack", 10)) { - this.setItemStack(ItemStack.read(compound.getCompound("Stack"))); + this.setItemStack(ItemStack.fromNbt(compound.getCompound("Stack"))); } - this.dataManager.set(LOYALTY_LEVEL, (byte)WeaponThrowEntity.getReturnOrLoyaltyEnchantment(this.getItemStack())); + this.dataTracker.set(LOYALTY_LEVEL, (byte)WeaponThrowEntity.getReturnOrLoyaltyEnchantment(this.getItemStack())); } + - public void writeAdditional(CompoundNBT compound) { - super.writeAdditional(compound); - compound.put("Stack", this.getDataManager().get(COMPOUND_STACK)); + public void writeCustomDataToNbt(NbtCompound compound) { + super.writeCustomDataToNbt(compound); + compound.put("Stack", this.getDataTracker().get(COMPOUND_STACK)); compound.putBoolean("DealtDamage", this.dealtDamage); + if (this.lastState != null) { + compound.put("inBlockState", NbtHelper.fromBlockState(this.lastState)); + } } - public void func_225516_i_() { - int i = this.dataManager.get(LOYALTY_LEVEL); - if (this.pickupStatus != AbstractArrowEntity.PickupStatus.ALLOWED || i <= 0) { - ++this.ticksInGround; - if (this.ticksInGround >= WeaponThrowConfig.COMMON.despawnTime.get()) { - this.remove(); - } - } + @Override + public void checkDespawn() { + int i = this.dataTracker.get(LOYALTY_LEVEL); + if (this.pickupType != PersistentProjectileEntity.PickupPermission.ALLOWED || i <= 0) { + + if (this.inGroundTime >= ConfigRegistry.COMMON.get().times.despawnTime) { + this.remove(RemovalReason.DISCARDED); + } + } + } - } - protected void onImpact(RayTraceResult result) { - WeaponThrowEvent.OnImpact testEvent = new WeaponThrowEvent.OnImpact(this, (PlayerEntity)this.func_234616_v_(), result); - if(MinecraftForge.EVENT_BUS.post(testEvent)) { - return; - } - - RayTraceResult.Type raytraceresult$type = result.getType(); - if (raytraceresult$type == RayTraceResult.Type.ENTITY) { - Entity hittedEntity = ((EntityRayTraceResult)result).getEntity(); - if(hittedEntity instanceof LivingEntity && this.func_234616_v_() instanceof PlayerEntity) { - if (((PlayerEntity)this.func_234616_v_()).abilities.isCreativeMode && WeaponThrowConfig.COMMON.creativeSpamming.get()) { - ((PlayerEntity)this.func_234616_v_()).setHeldItem(Hand.MAIN_HAND, this.getItemStack()); - ((PlayerEntity)this.func_234616_v_()).attackTargetEntityWithCurrentItem(hittedEntity); - - }else { - ((PlayerEntity)this.func_234616_v_()).setHeldItem(Hand.MAIN_HAND, this.getItemStack()); - ((PlayerEntity)this.func_234616_v_()).attackTargetEntityWithCurrentItem(hittedEntity); - - if(((PlayerEntity)this.func_234616_v_()).getHeldItem(Hand.MAIN_HAND).isEmpty()) { - this.setItemStack(ItemStack.EMPTY); - }else { - ((PlayerEntity)this.func_234616_v_()).setHeldItem(Hand.MAIN_HAND, ItemStack.EMPTY); - } - } + protected void onCollision(HitResult result) { + + HitResult.Type raytraceresult$type = result.getType(); + if (raytraceresult$type == HitResult.Type.ENTITY) { + Entity hittedEntity = ((EntityHitResult)result).getEntity(); + if(hittedEntity instanceof LivingEntity && this.getOwner() instanceof PlayerEntity) { + this.doInteractions(() -> { + ((PlayerEntity) this.getOwner()).attack(hittedEntity); + }); } - - this.onEntityHit((EntityRayTraceResult)result); + this.onEntityHit((EntityHitResult)result); - } else if (raytraceresult$type == RayTraceResult.Type.BLOCK) { + } else if (raytraceresult$type == HitResult.Type.BLOCK) { - BlockPos stickBlockPos = ((BlockRayTraceResult)result).getPos(); + BlockPos stickBlockPos = ((BlockHitResult)result).getBlockPos(); BlockState state = this.world.getBlockState(stickBlockPos); - if(!WeaponThrowConfig.COMMON.blackList.get().contains(state.getBlock()) && this.shouldDestroy()) { + + /*!WeaponThrowConfig.COMMON.blackList.get().contains(state.getBlock()) && */ + + if(!state.getBlock().equals(Blocks.BEDROCK) && this.shouldDestroy()) { - boolean canBreak = WeaponThrowConfig.COMMON.canBreakBlocks.get(); + boolean canBreak = ConfigRegistry.COMMON.get().interactions.canBreakBlocks; - boolean canHarvest = false; + boolean canHarvest = this.getItemStack().isSuitableFor(state) && canBreak; - canHarvest = this.getItemStack().getHarvestLevel(state.getHarvestTool(), null, null) >= state.getHarvestLevel(); - canHarvest = canHarvest && this.getItemStack().getDestroySpeed(state) > 1.0F && canBreak; - if(canHarvest) { - if(!world.isRemote && this.inBlockState == null) { + if(!world.isClient && this.lastState == null) { this.setDestroyedBlock(stickBlockPos); } } } - this.func_230299_a_((BlockRayTraceResult)result); + this.onBlockHit((BlockHitResult)result); } } - protected void func_230299_a_(BlockRayTraceResult p_230299_1_) { - this.inBlockState = this.world.getBlockState(p_230299_1_.getPos()); - Vector3d vector3d = p_230299_1_.getHitVec().subtract(this.getPosX(), this.getPosY(), this.getPosZ()); - this.setMotion(vector3d); - Vector3d vector3d1 = vector3d.normalize().scale((double)0.05F); - this.setRawPosition(this.getPosX() - vector3d1.x, this.getPosY() - vector3d1.y, this.getPosZ() - vector3d1.z); + + + @Override + protected void onBlockHit(BlockHitResult blockHitResult) { + this.lastState = this.world.getBlockState(blockHitResult.getBlockPos()); + Vec3d Vec3d = blockHitResult.getPos().subtract(this.getX(), this.getY(), this.getZ()); + this.setVelocity(Vec3d); + Vec3d Vec3d1 = Vec3d.normalize().multiply((double)0.05F); + this.setPos(this.getX() - Vec3d1.x, this.getY() - Vec3d1.y, this.getZ() - Vec3d1.z); SoundEvent event = SoundEvents.ITEM_TRIDENT_HIT_GROUND; if(this.getItemStack().getItem() instanceof BlockItem) { Block block = Block.getBlockFromItem(this.getItemStack().getItem()); - event = block.getDefaultState().getSoundType().getHitSound(); + event = block.getDefaultState().getSoundGroup().getHitSound(); } - this.playSound(event, 1.0F, 1.2F / (this.rand.nextFloat() * 0.2F + 0.9F)); + this.playSound(event, 1.0F, 1.2F / (this.random.nextFloat() * 0.2F + 0.9F)); this.inGround = true; - this.arrowShake = 7; - this.setIsCritical(false); - this.setPierceLevel((byte)0); - this.setHitSound(event); - this.setShotFromCrossbow(false); - this.func_213870_w(); + this.shake = 7; + + this.setCritical(false); + this.setPierceLevel((byte)0); + this.setSound(event); + this.setShotFromCrossbow(false); + + this.applyBounce(); } - @OnlyIn(Dist.CLIENT) - public boolean isInRangeToRender3d(double x, double y, double z) { - return true; - } + void applyBounce() { + if(this.inGround && this.getItemStack().getItem() instanceof BlockItem ) { + + if(!(Math.abs(this.getVelocity().x) < 0.05 && Math.abs(this.getVelocity().z) < 0.05)) { + + Vec3d vec3 = this.getVelocity().multiply(0.9F); + + BlockPos landingPos = getLandingPos(); + + if(!this.world.getBlockState(landingPos.down()).isAir() || !this.world.getBlockState(landingPos.up()).isAir()) { + this.setVelocity(vec3.x, -vec3.y, vec3.z); + } + else if(!this.world.getBlockState(landingPos.west()).isAir() || !this.world.getBlockState(landingPos.east()).isAir()){ + this.setVelocity(-vec3.x, vec3.y, vec3.z); + } + else if(!this.world.getBlockState(landingPos.north()).isAir() || !this.world.getBlockState(landingPos.south()).isAir()){ + this.setVelocity(vec3.x, vec3.y, -vec3.z); + } + + this.counterClockwiseBounce = !this.counterClockwiseBounce; + + + this.inGround = false; + } + } + } + @Override - public ItemStack getItem() { + public ItemStack getStack() { return this.getItemStack(); } + + @Override - public IPacket createSpawnPacket() { - return NetworkHooks.getEntitySpawningPacket(this); + public Packet createSpawnPacket() { + return super.createSpawnPacket(); + //return EntitySpawnPacket.create(this); + } + + public void doInteractions(Runnable action) { + ItemStack originalStack = ((PlayerEntity)this.getOwner()).getStackInHand(Hand.MAIN_HAND); + + ((PlayerEntity) this.getOwner()).setStackInHand(Hand.MAIN_HAND, this.getItemStack()); + + + action.run(); + + //((PlayerEntity) this.getOwner()).setStackInHand(Hand.MAIN_HAND, originalStack); + + ItemStack newStack = ((PlayerEntity) this.getOwner()).getStackInHand(Hand.MAIN_HAND); + + if (!newStack.isEmpty()) { + ((PlayerEntity) this.getOwner()).setStackInHand(Hand.MAIN_HAND, originalStack); + } else { + + this.world.playSound(null, this.getBlockPos(), SoundEvents.ENTITY_ITEM_BREAK, SoundCategory.AMBIENT, 0.8F, 10F); + + this.spawnItemParticles(this.getItemStack(), 5); + + this.remove(RemovalReason.DISCARDED); + } + + } + + private void spawnItemParticles(ItemStack stack, int count) { + for(int i = 0; i < count; ++i) { + Vec3d vec3d = new Vec3d(((double)this.random.nextFloat() - 0.5D) * 0.1D, Math.random() * 0.1D + 0.1D, 0.0D); + vec3d = vec3d.rotateX(-this.getPitch() * 0.017453292F); + vec3d = vec3d.rotateY(-this.getYaw() * 0.017453292F); + double d = (double)(-this.random.nextFloat()) * 0.6D - 0.3D; + Vec3d vec3d2 = new Vec3d(((double)this.random.nextFloat() - 0.5D) * 0.3D, d, 0.6D); + vec3d2 = vec3d2.rotateX(-this.getPitch() * 0.017453292F); + vec3d2 = vec3d2.rotateY(-this.getYaw() * 0.017453292F); + vec3d2 = vec3d2.add(this.getX(), this.getEyeY(), this.getZ()); + if (this.world instanceof ServerWorld) //Forge: Fix MC-2518 spawnParticle is nooped on server, need to use server specific variant + ((ServerWorld)this.world).spawnParticles(new ItemStackParticleEffect(ParticleTypes.ITEM, stack), vec3d2.x, vec3d2.y, vec3d2.z, 1, vec3d.x, vec3d.y + 0.05D, vec3d.z, 0.0D); + else + this.world.addParticle(new ItemStackParticleEffect(ParticleTypes.ITEM, stack), vec3d2.x, vec3d2.y, vec3d2.z, vec3d.x, vec3d.y + 0.05D, vec3d.z); + } + } public static int getReturnOrLoyaltyEnchantment(ItemStack stack) { - int loyaltyLevel = EnchantmentHelper.getEnchantmentLevel(Enchantments.LOYALTY, stack); - int returnLevel = EnchantmentHelper.getEnchantmentLevel(EnchantmentHandler.RETURN, stack); + int loyaltyLevel = EnchantmentHelper.getLevel(Enchantments.LOYALTY, stack); + int returnLevel = EnchantmentHelper.getLevel(EnchantmentHandler.RETURN, stack); return loyaltyLevel > 0 ? loyaltyLevel : returnLevel; } - @OnlyIn(Dist.CLIENT) + @Environment(EnvType.CLIENT) public float getRotationAnimation(float partialTicks) { if(!this.inGround) { - clientSideRotation = (this.counterClockwiseBounce? 1:-1)*(this.ticksExisted+partialTicks)*50F; + clientSideRotation = (this.counterClockwiseBounce? 1:-1)*(this.age+partialTicks)*50F; } return this.clientSideRotation; } + } diff --git a/src/main/resources/assets/weaponthrow/icon.png b/src/main/resources/assets/weaponthrow/icon.png new file mode 100644 index 0000000000000000000000000000000000000000..573ac2f446e0fb719f0e857cc7286b86716a4fa7 GIT binary patch literal 11542 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 vP!KPv2r=0.14.12+", + "fabric": "*", + "minecraft": "1.19.2", + "java": ">=17" + }, + "suggests": { + "another-mod": "*" + } +} \ No newline at end of file diff --git a/src/main/resources/weaponthrow.mixins.json b/src/main/resources/weaponthrow.mixins.json new file mode 100644 index 0000000..1e3af85 --- /dev/null +++ b/src/main/resources/weaponthrow.mixins.json @@ -0,0 +1,18 @@ +{ + "required": true, + "minVersion": "0.8", + "package": "com.dainxt.weaponthrow.mixins", + "compatibilityLevel": "JAVA_16", + "mixins": [ + "PlayerEntityMixin" + ], + "client": [ + "client.ClientPlayerEntityMixin", + "client.HeldItemRendererMixin", + "client.PlayerEntityRendererMixin", + "client.AbstractClientPlayerEntityMixin" + ], + "injectors": { + "defaultRequire": 1 + } +} From ddfb50d781f2d193733e2b04efb1deb9660d9171 Mon Sep 17 00:00:00 2001 From: CantWeAllDisagree Date: Fri, 5 May 2023 18:36:36 -0400 Subject: [PATCH 2/3] Stupid IDE auto-generating License --- LICENSE | 631 -------------------------------------------------------- 1 file changed, 631 deletions(-) delete mode 100644 LICENSE diff --git a/LICENSE b/LICENSE deleted file mode 100644 index 564be7b..0000000 --- a/LICENSE +++ /dev/null @@ -1,631 +0,0 @@ -Copyright (c) 2023 - -This program is free software: you can redistribute it and/or modify -it under the terms of the GNU Affero General Public License as published by -the Free Software Foundation, version 3 of the License, or -(at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU Affero General Public License for more details. - - GNU AFFERO GENERAL PUBLIC LICENSE - Version 3, 19 November 2007 - - Copyright (C) 2007 Free Software Foundation, Inc. - Everyone is permitted to copy and distribute verbatim copies - of this license document, but changing it is not allowed. - - Preamble - - The GNU Affero General Public License is a free, copyleft license for -software and other kinds of works, specifically designed to ensure -cooperation with the community in the case of network server software. - - The licenses for most software and other practical works are designed -to take away your freedom to share and change the works. By contrast, -our General Public Licenses are intended to guarantee your freedom to -share and change all versions of a program--to make sure it remains free -software for all its users. - - When we speak of free software, we are referring to freedom, not -price. Our General Public Licenses are designed to make sure that you -have the freedom to distribute copies of free software (and charge for -them if you wish), that you receive source code or can get it if you -want it, that you can change the software or use pieces of it in new -free programs, and that you know you can do these things. - - Developers that use our General Public Licenses protect your rights -with two steps: (1) assert copyright on the software, and (2) offer -you this License which gives you legal permission to copy, distribute -and/or modify the software. - - A secondary benefit of defending all users' freedom is that -improvements made in alternate versions of the program, if they -receive widespread use, become available for other developers to -incorporate. Many developers of free software are heartened and -encouraged by the resulting cooperation. However, in the case of -software used on network servers, this result may fail to come about. -The GNU General Public License permits making a modified version and -letting the public access it on a server without ever releasing its -source code to the public. - - The GNU Affero General Public License is designed specifically to -ensure that, in such cases, the modified source code becomes available -to the community. It requires the operator of a network server to -provide the source code of the modified version running there to the -users of that server. Therefore, public use of a modified version, on -a publicly accessible server, gives the public access to the source -code of the modified version. - - An older license, called the Affero General Public License and -published by Affero, was designed to accomplish similar goals. This is -a different license, not a version of the Affero GPL, but Affero has -released a new version of the Affero GPL which permits relicensing under -this license. - - The precise terms and conditions for copying, distribution and -modification follow. - - TERMS AND CONDITIONS - - 0. Definitions. - - "This License" refers to version 3 of the GNU Affero General Public License. - - "Copyright" also means copyright-like laws that apply to other kinds of -works, such as semiconductor masks. - - "The Program" refers to any copyrightable work licensed under this -License. Each licensee is addressed as "you". "Licensees" and -"recipients" may be individuals or organizations. - - To "modify" a work means to copy from or adapt all or part of the work -in a fashion requiring copyright permission, other than the making of an -exact copy. The resulting work is called a "modified version" of the -earlier work or a work "based on" the earlier work. - - A "covered work" means either the unmodified Program or a work based -on the Program. - - To "propagate" a work means to do anything with it that, without -permission, would make you directly or secondarily liable for -infringement under applicable copyright law, except executing it on a -computer or modifying a private copy. Propagation includes copying, -distribution (with or without modification), making available to the -public, and in some countries other activities as well. - - To "convey" a work means any kind of propagation that enables other -parties to make or receive copies. Mere interaction with a user through -a computer network, with no transfer of a copy, is not conveying. - - An interactive user interface displays "Appropriate Legal Notices" -to the extent that it includes a convenient and prominently visible -feature that (1) displays an appropriate copyright notice, and (2) -tells the user that there is no warranty for the work (except to the -extent that warranties are provided), that licensees may convey the -work under this License, and how to view a copy of this License. If -the interface presents a list of user commands or options, such as a -menu, a prominent item in the list meets this criterion. - - 1. Source Code. - - The "source code" for a work means the preferred form of the work -for making modifications to it. "Object code" means any non-source -form of a work. - - A "Standard Interface" means an interface that either is an official -standard defined by a recognized standards body, or, in the case of -interfaces specified for a particular programming language, one that -is widely used among developers working in that language. - - The "System Libraries" of an executable work include anything, other -than the work as a whole, that (a) is included in the normal form of -packaging a Major Component, but which is not part of that Major -Component, and (b) serves only to enable use of the work with that -Major Component, or to implement a Standard Interface for which an -implementation is available to the public in source code form. A -"Major Component", in this context, means a major essential component -(kernel, window system, and so on) of the specific operating system -(if any) on which the executable work runs, or a compiler used to -produce the work, or an object code interpreter used to run it. - - The "Corresponding Source" for a work in object code form means all -the source code needed to generate, install, and (for an executable -work) run the object code and to modify the work, including scripts to -control those activities. However, it does not include the work's -System Libraries, or general-purpose tools or generally available free -programs which are used unmodified in performing those activities but -which are not part of the work. For example, Corresponding Source -includes interface definition files associated with source files for -the work, and the source code for shared libraries and dynamically -linked subprograms that the work is specifically designed to require, -such as by intimate data communication or control flow between those -subprograms and other parts of the work. - - The Corresponding Source need not include anything that users -can regenerate automatically from other parts of the Corresponding -Source. - - The Corresponding Source for a work in source code form is that -same work. - - 2. Basic Permissions. - - All rights granted under this License are granted for the term of -copyright on the Program, and are irrevocable provided the stated -conditions are met. This License explicitly affirms your unlimited -permission to run the unmodified Program. The output from running a -covered work is covered by this License only if the output, given its -content, constitutes a covered work. This License acknowledges your -rights of fair use or other equivalent, as provided by copyright law. - - You may make, run and propagate covered works that you do not -convey, without conditions so long as your license otherwise remains -in force. You may convey covered works to others for the sole purpose -of having them make modifications exclusively for you, or provide you -with facilities for running those works, provided that you comply with -the terms of this License in conveying all material for which you do -not control copyright. Those thus making or running the covered works -for you must do so exclusively on your behalf, under your direction -and control, on terms that prohibit them from making any copies of -your copyrighted material outside their relationship with you. - - Conveying under any other circumstances is permitted solely under -the conditions stated below. Sublicensing is not allowed; section 10 -makes it unnecessary. - - 3. Protecting Users' Legal Rights From Anti-Circumvention Law. - - No covered work shall be deemed part of an effective technological -measure under any applicable law fulfilling obligations under article -11 of the WIPO copyright treaty adopted on 20 December 1996, or -similar laws prohibiting or restricting circumvention of such -measures. - - When you convey a covered work, you waive any legal power to forbid -circumvention of technological measures to the extent such circumvention -is effected by exercising rights under this License with respect to -the covered work, and you disclaim any intention to limit operation or -modification of the work as a means of enforcing, against the work's -users, your or third parties' legal rights to forbid circumvention of -technological measures. - - 4. Conveying Verbatim Copies. - - You may convey verbatim copies of the Program's source code as you -receive it, in any medium, provided that you conspicuously and -appropriately publish on each copy an appropriate copyright notice; -keep intact all notices stating that this License and any -non-permissive terms added in accord with section 7 apply to the code; -keep intact all notices of the absence of any warranty; and give all -recipients a copy of this License along with the Program. - - You may charge any price or no price for each copy that you convey, -and you may offer support or warranty protection for a fee. - - 5. Conveying Modified Source Versions. - - You may convey a work based on the Program, or the modifications to -produce it from the Program, in the form of source code under the -terms of section 4, provided that you also meet all of these conditions: - - a) The work must carry prominent notices stating that you modified - it, and giving a relevant date. - - b) The work must carry prominent notices stating that it is - released under this License and any conditions added under section - 7. This requirement modifies the requirement in section 4 to - "keep intact all notices". - - c) You must license the entire work, as a whole, under this - License to anyone who comes into possession of a copy. This - License will therefore apply, along with any applicable section 7 - additional terms, to the whole of the work, and all its parts, - regardless of how they are packaged. This License gives no - permission to license the work in any other way, but it does not - invalidate such permission if you have separately received it. - - d) If the work has interactive user interfaces, each must display - Appropriate Legal Notices; however, if the Program has interactive - interfaces that do not display Appropriate Legal Notices, your - work need not make them do so. - - A compilation of a covered work with other separate and independent -works, which are not by their nature extensions of the covered work, -and which are not combined with it such as to form a larger program, -in or on a volume of a storage or distribution medium, is called an -"aggregate" if the compilation and its resulting copyright are not -used to limit the access or legal rights of the compilation's users -beyond what the individual works permit. Inclusion of a covered work -in an aggregate does not cause this License to apply to the other -parts of the aggregate. - - 6. Conveying Non-Source Forms. - - You may convey a covered work in object code form under the terms -of sections 4 and 5, provided that you also convey the -machine-readable Corresponding Source under the terms of this License, -in one of these ways: - - a) Convey the object code in, or embodied in, a physical product - (including a physical distribution medium), accompanied by the - Corresponding Source fixed on a durable physical medium - customarily used for software interchange. - - b) Convey the object code in, or embodied in, a physical product - (including a physical distribution medium), accompanied by a - written offer, valid for at least three years and valid for as - long as you offer spare parts or customer support for that product - model, to give anyone who possesses the object code either (1) a - copy of the Corresponding Source for all the software in the - product that is covered by this License, on a durable physical - medium customarily used for software interchange, for a price no - more than your reasonable cost of physically performing this - conveying of source, or (2) access to copy the - Corresponding Source from a network server at no charge. - - c) Convey individual copies of the object code with a copy of the - written offer to provide the Corresponding Source. This - alternative is allowed only occasionally and noncommercially, and - only if you received the object code with such an offer, in accord - with subsection 6b. - - d) Convey the object code by offering access from a designated - place (gratis or for a charge), and offer equivalent access to the - Corresponding Source in the same way through the same place at no - further charge. You need not require recipients to copy the - Corresponding Source along with the object code. If the place to - copy the object code is a network server, the Corresponding Source - may be on a different server (operated by you or a third party) - that supports equivalent copying facilities, provided you maintain - clear directions next to the object code saying where to find the - Corresponding Source. Regardless of what server hosts the - Corresponding Source, you remain obligated to ensure that it is - available for as long as needed to satisfy these requirements. - - e) Convey the object code using peer-to-peer transmission, provided - you inform other peers where the object code and Corresponding - Source of the work are being offered to the general public at no - charge under subsection 6d. - - A separable portion of the object code, whose source code is excluded -from the Corresponding Source as a System Library, need not be -included in conveying the object code work. - - A "User Product" is either (1) a "consumer product", which means any -tangible personal property which is normally used for personal, family, -or household purposes, or (2) anything designed or sold for incorporation -into a dwelling. In determining whether a product is a consumer product, -doubtful cases shall be resolved in favor of coverage. For a particular -product received by a particular user, "normally used" refers to a -typical or common use of that class of product, regardless of the status -of the particular user or of the way in which the particular user -actually uses, or expects or is expected to use, the product. A product -is a consumer product regardless of whether the product has substantial -commercial, industrial or non-consumer uses, unless such uses represent -the only significant mode of use of the product. - - "Installation Information" for a User Product means any methods, -procedures, authorization keys, or other information required to install -and execute modified versions of a covered work in that User Product from -a modified version of its Corresponding Source. The information must -suffice to ensure that the continued functioning of the modified object -code is in no case prevented or interfered with solely because -modification has been made. - - If you convey an object code work under this section in, or with, or -specifically for use in, a User Product, and the conveying occurs as -part of a transaction in which the right of possession and use of the -User Product is transferred to the recipient in perpetuity or for a -fixed term (regardless of how the transaction is characterized), the -Corresponding Source conveyed under this section must be accompanied -by the Installation Information. But this requirement does not apply -if neither you nor any third party retains the ability to install -modified object code on the User Product (for example, the work has -been installed in ROM). - - The requirement to provide Installation Information does not include a -requirement to continue to provide support service, warranty, or updates -for a work that has been modified or installed by the recipient, or for -the User Product in which it has been modified or installed. Access to a -network may be denied when the modification itself materially and -adversely affects the operation of the network or violates the rules and -protocols for communication across the network. - - Corresponding Source conveyed, and Installation Information provided, -in accord with this section must be in a format that is publicly -documented (and with an implementation available to the public in -source code form), and must require no special password or key for -unpacking, reading or copying. - - 7. Additional Terms. - - "Additional permissions" are terms that supplement the terms of this -License by making exceptions from one or more of its conditions. -Additional permissions that are applicable to the entire Program shall -be treated as though they were included in this License, to the extent -that they are valid under applicable law. If additional permissions -apply only to part of the Program, that part may be used separately -under those permissions, but the entire Program remains governed by -this License without regard to the additional permissions. - - When you convey a copy of a covered work, you may at your option -remove any additional permissions from that copy, or from any part of -it. (Additional permissions may be written to require their own -removal in certain cases when you modify the work.) You may place -additional permissions on material, added by you to a covered work, -for which you have or can give appropriate copyright permission. - - Notwithstanding any other provision of this License, for material you -add to a covered work, you may (if authorized by the copyright holders of -that material) supplement the terms of this License with terms: - - a) Disclaiming warranty or limiting liability differently from the - terms of sections 15 and 16 of this License; or - - b) Requiring preservation of specified reasonable legal notices or - author attributions in that material or in the Appropriate Legal - Notices displayed by works containing it; or - - c) Prohibiting misrepresentation of the origin of that material, or - requiring that modified versions of such material be marked in - reasonable ways as different from the original version; or - - d) Limiting the use for publicity purposes of names of licensors or - authors of the material; or - - e) Declining to grant rights under trademark law for use of some - trade names, trademarks, or service marks; or - - f) Requiring indemnification of licensors and authors of that - material by anyone who conveys the material (or modified versions of - it) with contractual assumptions of liability to the recipient, for - any liability that these contractual assumptions directly impose on - those licensors and authors. - - All other non-permissive additional terms are considered "further -restrictions" within the meaning of section 10. If the Program as you -received it, or any part of it, contains a notice stating that it is -governed by this License along with a term that is a further -restriction, you may remove that term. If a license document contains -a further restriction but permits relicensing or conveying under this -License, you may add to a covered work material governed by the terms -of that license document, provided that the further restriction does -not survive such relicensing or conveying. - - If you add terms to a covered work in accord with this section, you -must place, in the relevant source files, a statement of the -additional terms that apply to those files, or a notice indicating -where to find the applicable terms. - - Additional terms, permissive or non-permissive, may be stated in the -form of a separately written license, or stated as exceptions; -the above requirements apply either way. - - 8. Termination. - - You may not propagate or modify a covered work except as expressly -provided under this License. Any attempt otherwise to propagate or -modify it is void, and will automatically terminate your rights under -this License (including any patent licenses granted under the third -paragraph of section 11). - - However, if you cease all violation of this License, then your -license from a particular copyright holder is reinstated (a) -provisionally, unless and until the copyright holder explicitly and -finally terminates your license, and (b) permanently, if the copyright -holder fails to notify you of the violation by some reasonable means -prior to 60 days after the cessation. - - Moreover, your license from a particular copyright holder is -reinstated permanently if the copyright holder notifies you of the -violation by some reasonable means, this is the first time you have -received notice of violation of this License (for any work) from that -copyright holder, and you cure the violation prior to 30 days after -your receipt of the notice. - - Termination of your rights under this section does not terminate the -licenses of parties who have received copies or rights from you under -this License. If your rights have been terminated and not permanently -reinstated, you do not qualify to receive new licenses for the same -material under section 10. - - 9. Acceptance Not Required for Having Copies. - - You are not required to accept this License in order to receive or -run a copy of the Program. Ancillary propagation of a covered work -occurring solely as a consequence of using peer-to-peer transmission -to receive a copy likewise does not require acceptance. However, -nothing other than this License grants you permission to propagate or -modify any covered work. These actions infringe copyright if you do -not accept this License. Therefore, by modifying or propagating a -covered work, you indicate your acceptance of this License to do so. - - 10. Automatic Licensing of Downstream Recipients. - - Each time you convey a covered work, the recipient automatically -receives a license from the original licensors, to run, modify and -propagate that work, subject to this License. You are not responsible -for enforcing compliance by third parties with this License. - - An "entity transaction" is a transaction transferring control of an -organization, or substantially all assets of one, or subdividing an -organization, or merging organizations. If propagation of a covered -work results from an entity transaction, each party to that -transaction who receives a copy of the work also receives whatever -licenses to the work the party's predecessor in interest had or could -give under the previous paragraph, plus a right to possession of the -Corresponding Source of the work from the predecessor in interest, if -the predecessor has it or can get it with reasonable efforts. - - You may not impose any further restrictions on the exercise of the -rights granted or affirmed under this License. For example, you may -not impose a license fee, royalty, or other charge for exercise of -rights granted under this License, and you may not initiate litigation -(including a cross-claim or counterclaim in a lawsuit) alleging that -any patent claim is infringed by making, using, selling, offering for -sale, or importing the Program or any portion of it. - - 11. Patents. - - A "contributor" is a copyright holder who authorizes use under this -License of the Program or a work on which the Program is based. The -work thus licensed is called the contributor's "contributor version". - - A contributor's "essential patent claims" are all patent claims -owned or controlled by the contributor, whether already acquired or -hereafter acquired, that would be infringed by some manner, permitted -by this License, of making, using, or selling its contributor version, -but do not include claims that would be infringed only as a -consequence of further modification of the contributor version. For -purposes of this definition, "control" includes the right to grant -patent sublicenses in a manner consistent with the requirements of -this License. - - Each contributor grants you a non-exclusive, worldwide, royalty-free -patent license under the contributor's essential patent claims, to -make, use, sell, offer for sale, import and otherwise run, modify and -propagate the contents of its contributor version. - - In the following three paragraphs, a "patent license" is any express -agreement or commitment, however denominated, not to enforce a patent -(such as an express permission to practice a patent or covenant not to -sue for patent infringement). To "grant" such a patent license to a -party means to make such an agreement or commitment not to enforce a -patent against the party. - - If you convey a covered work, knowingly relying on a patent license, -and the Corresponding Source of the work is not available for anyone -to copy, free of charge and under the terms of this License, through a -publicly available network server or other readily accessible means, -then you must either (1) cause the Corresponding Source to be so -available, or (2) arrange to deprive yourself of the benefit of the -patent license for this particular work, or (3) arrange, in a manner -consistent with the requirements of this License, to extend the patent -license to downstream recipients. "Knowingly relying" means you have -actual knowledge that, but for the patent license, your conveying the -covered work in a country, or your recipient's use of the covered work -in a country, would infringe one or more identifiable patents in that -country that you have reason to believe are valid. - - If, pursuant to or in connection with a single transaction or -arrangement, you convey, or propagate by procuring conveyance of, a -covered work, and grant a patent license to some of the parties -receiving the covered work authorizing them to use, propagate, modify -or convey a specific copy of the covered work, then the patent license -you grant is automatically extended to all recipients of the covered -work and works based on it. - - A patent license is "discriminatory" if it does not include within -the scope of its coverage, prohibits the exercise of, or is -conditioned on the non-exercise of one or more of the rights that are -specifically granted under this License. You may not convey a covered -work if you are a party to an arrangement with a third party that is -in the business of distributing software, under which you make payment -to the third party based on the extent of your activity of conveying -the work, and under which the third party grants, to any of the -parties who would receive the covered work from you, a discriminatory -patent license (a) in connection with copies of the covered work -conveyed by you (or copies made from those copies), or (b) primarily -for and in connection with specific products or compilations that -contain the covered work, unless you entered into that arrangement, -or that patent license was granted, prior to 28 March 2007. - - Nothing in this License shall be construed as excluding or limiting -any implied license or other defenses to infringement that may -otherwise be available to you under applicable patent law. - - 12. No Surrender of Others' Freedom. - - If conditions are imposed on you (whether by court order, agreement or -otherwise) that contradict the conditions of this License, they do not -excuse you from the conditions of this License. If you cannot convey a -covered work so as to satisfy simultaneously your obligations under this -License and any other pertinent obligations, then as a consequence you may -not convey it at all. For example, if you agree to terms that obligate you -to collect a royalty for further conveying from those to whom you convey -the Program, the only way you could satisfy both those terms and this -License would be to refrain entirely from conveying the Program. - - 13. Remote Network Interaction; Use with the GNU General Public License. - - Notwithstanding any other provision of this License, if you modify the -Program, your modified version must prominently offer all users -interacting with it remotely through a computer network (if your version -supports such interaction) an opportunity to receive the Corresponding -Source of your version by providing access to the Corresponding Source -from a network server at no charge, through some standard or customary -means of facilitating copying of software. This Corresponding Source -shall include the Corresponding Source for any work covered by version 3 -of the GNU General Public License that is incorporated pursuant to the -following paragraph. - - Notwithstanding any other provision of this License, you have -permission to link or combine any covered work with a work licensed -under version 3 of the GNU General Public License into a single -combined work, and to convey the resulting work. The terms of this -License will continue to apply to the part which is the covered work, -but the work with which it is combined will remain governed by version -3 of the GNU General Public License. - - 14. Revised Versions of this License. - - The Free Software Foundation may publish revised and/or new versions of -the GNU Affero General Public License from time to time. Such new versions -will be similar in spirit to the present version, but may differ in detail to -address new problems or concerns. - - Each version is given a distinguishing version number. If the -Program specifies that a certain numbered version of the GNU Affero General -Public License "or any later version" applies to it, you have the -option of following the terms and conditions either of that numbered -version or of any later version published by the Free Software -Foundation. If the Program does not specify a version number of the -GNU Affero General Public License, you may choose any version ever published -by the Free Software Foundation. - - If the Program specifies that a proxy can decide which future -versions of the GNU Affero General Public License can be used, that proxy's -public statement of acceptance of a version permanently authorizes you -to choose that version for the Program. - - Later license versions may give you additional or different -permissions. However, no additional obligations are imposed on any -author or copyright holder as a result of your choosing to follow a -later version. - - 15. Disclaimer of Warranty. - - THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY -APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT -HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY -OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, -THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR -PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM -IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF -ALL NECESSARY SERVICING, REPAIR OR CORRECTION. - - 16. Limitation of Liability. - - IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING -WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS -THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY -GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE -USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF -DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD -PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), -EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF -SUCH DAMAGES. - - 17. Interpretation of Sections 15 and 16. - - If the disclaimer of warranty and limitation of liability provided -above cannot be given local legal effect according to their terms, -reviewing courts shall apply local law that most closely approximates -an absolute waiver of all civil liability in connection with the -Program, unless a warranty or assumption of liability accompanies a -copy of the Program in return for a fee. - - END OF TERMS AND CONDITIONS From 8ab7d688c92e26b843565650ad34bf1d5127a194 Mon Sep 17 00:00:00 2001 From: CantWeAllDisagree Date: Fri, 5 May 2023 19:24:58 -0400 Subject: [PATCH 3/3] Updated to 1.19.2 --- build.gradle | 50 ++--- gradle.properties | 6 - gradle/libs.versions.toml | 18 ++ .../weaponthrow/ModMenuIntegration.java | 5 +- .../weaponthrow/config/WeaponThrowConfig.java | 8 +- .../enchantment/ConccusionEnchantment.java | 13 +- .../enchantment/GravityEnchantment.java | 2 +- .../enchantment/GroundedEdgeEnchantment.java | 11 +- .../enchantment/ReturnEnchantment.java | 15 +- .../enchantment/ThrowEnchantment.java | 13 +- .../entity/render/WeaponThrowRenderer.java | 3 - .../weaponthrow/events/OnApplySlow.java | 4 +- .../weaponthrow/events/OnFOVUpdate.java | 3 - .../weaponthrow/events/OnHeldItemRender.java | 5 - .../events/OnStartPlayerRender.java | 2 - .../weaponthrow/events/OnStartPlayerTick.java | 1 - .../weaponthrow/handlers/ConfigRegistry.java | 2 - .../handlers/EnchantmentHandler.java | 5 +- .../weaponthrow/handlers/EntityRegistry.java | 3 - .../weaponthrow/handlers/EventsHandler.java | 100 +++------ .../handlers/KeyBindingHandler.java | 7 - .../weaponthrow/handlers/PacketHandler.java | 1 - .../interfaces/IPlayerEntityMixin.java | 5 +- .../AbstractClientPlayerEntityMixin.java | 28 --- .../mixin/ClientPlayerEntityMixin.java | 28 --- .../mixin/HeldItemRendererMixin.java | 43 ---- .../weaponthrow/mixin/IPlayerEntityMixin.java | 9 - .../weaponthrow/mixin/PlayerEntityMixin.java | 44 ---- .../mixin/PlayerEntityRendererMixin.java | 37 ---- .../packets/EntitySpawnPacket.java | 4 +- .../projectile/WeaponThrowEntity.java | 203 +++++++----------- src/main/resources/fabric.mod.json | 4 +- src/main/resources/weaponthrow.mixins.json | 10 +- 33 files changed, 167 insertions(+), 525 deletions(-) create mode 100644 gradle/libs.versions.toml delete mode 100644 src/main/java/com/dainxt/weaponthrow/mixin/AbstractClientPlayerEntityMixin.java delete mode 100644 src/main/java/com/dainxt/weaponthrow/mixin/ClientPlayerEntityMixin.java delete mode 100644 src/main/java/com/dainxt/weaponthrow/mixin/HeldItemRendererMixin.java delete mode 100644 src/main/java/com/dainxt/weaponthrow/mixin/IPlayerEntityMixin.java delete mode 100644 src/main/java/com/dainxt/weaponthrow/mixin/PlayerEntityMixin.java delete mode 100644 src/main/java/com/dainxt/weaponthrow/mixin/PlayerEntityRendererMixin.java diff --git a/build.gradle b/build.gradle index 18ea10e..3e9eb93 100644 --- a/build.gradle +++ b/build.gradle @@ -1,5 +1,5 @@ plugins { - id 'fabric-loom' version '1.1-SNAPSHOT' + alias libs.plugins.loom id 'maven-publish' } sourceCompatibility = JavaVersion.VERSION_17 @@ -11,24 +11,14 @@ group = project.maven_group repositories { maven { url "https://maven.shedaniel.me/" } - maven { - name = "TerraformersMC" - url = "https://maven.terraformersmc.com/" - } - // You should only use this when depending on other mods because - // Loom adds the essential maven repositories to download Minecraft and libraries from automatically. - // See https://docs.gradle.org/current/userguide/declaring_repositories.html - // for more information about repositories. + maven { url = "https://maven.terraformersmc.com/"} } dependencies { - // To change the versions see the gradle.properties file - minecraft "com.mojang:minecraft:${project.minecraft_version}" - mappings "net.fabricmc:yarn:${project.yarn_mappings}:v2" - modImplementation "net.fabricmc:fabric-loader:${project.loader_version}" - - // Fabric API. This is technically optional, but you probably want it anyway. - modImplementation "net.fabricmc.fabric-api:fabric-api:${project.fabric_version}" + minecraft libs.minecraft + mappings variantOf(libs.yarn) { classifier 'v2' } + modImplementation libs.fabricloader + modImplementation libs.fabric // ModMenu modCompileOnly modRuntimeOnly("me.shedaniel.cloth:cloth-config-fabric:${project.cloth_config_version}") { @@ -41,24 +31,20 @@ dependencies { } processResources { - inputs.property "version", project.version - inputs.property "minecraft_version", project.minecraft_version - inputs.property "loader_version", project.loader_version + inputs.property "version", version + inputs.property "minecraft_version", libs.minecraft + inputs.property "loader_version", libs.fabricloader filteringCharset "UTF-8" filesMatching("fabric.mod.json") { - expand "version": project.version, - "minecraft_version": project.minecraft_version, - "loader_version": project.loader_version + expand "version": version, + "minecraft_version": libs.minecraft, + "loader_version": libs.fabricloader } } def targetJavaVersion = 17 tasks.withType(JavaCompile).configureEach { - // ensure that the encoding is set to UTF-8, no matter what the system default is - // this fixes some edge cases with special characters not displaying correctly - // see http://yodaconditions.net/blog/fix-for-java-file-encoding-problems-with-gradle.html - // If Javadoc is generated, this must be specified in that task too. it.options.encoding = "UTF-8" if (targetJavaVersion >= 10 || JavaVersion.current().isJava10Compatible()) { it.options.release = targetJavaVersion @@ -71,9 +57,6 @@ java { toolchain.languageVersion = JavaLanguageVersion.of(targetJavaVersion) } archivesBaseName = project.archives_base_name - // Loom will automatically attach sourcesJar to a RemapSourcesJar task and to the "build" task - // if it is present. - // If you remove this line, sources will not be generated. withSourcesJar() } @@ -90,12 +73,5 @@ publishing { from components.java } } - - // See https://docs.gradle.org/current/userguide/publishing_maven.html for information on how to set up publishing. - repositories { - // Add repositories to publish to here. - // Notice: This block does NOT have the same function as the block in the top level. - // The repositories here will be used for publishing your artifact, not for - // retrieving dependencies. - } + repositories {} } diff --git a/gradle.properties b/gradle.properties index b3035f4..79431d4 100644 --- a/gradle.properties +++ b/gradle.properties @@ -1,17 +1,11 @@ # Done to increase the memory available to gradle. org.gradle.jvmargs=-Xmx2G -# Fabric Properties -minecraft_version=1.19.2 -yarn_mappings=1.19.2+build.28 -loader_version=0.14.12 - # Mod Properties version = 5.8-1.19.2 maven_group = com.dainxt archives_base_name = WeaponThrow # Dependencies -fabric_version=0.76.0+1.19.2 cloth_config_version=8.2.88 mod_menu_version=4.0.6 \ No newline at end of file diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml new file mode 100644 index 0000000..b9575a2 --- /dev/null +++ b/gradle/libs.versions.toml @@ -0,0 +1,18 @@ +[versions] +minecraft = "1.19.2" +yarn= "1.19.2+build.28" +fabricloader= "0.14.12" +fabric="0.76.0+1.19.2" + +[libraries] +minecraft = { module = "com.mojang:minecraft", version.ref = "minecraft" } +yarn = { module = "net.fabricmc:yarn", version.ref = "yarn" } +fabricloader = { module = "net.fabricmc:fabric-loader", version.ref = "fabricloader" } +fabric = { module = "net.fabricmc.fabric-api:fabric-api", version.ref = "fabric" } + +# If you have multiple similar dependencies, you can declare a dependency bundle and reference it on the build script with "libs.bundles.example". +[bundles] +fabricapi = ["fabricloader", "fabric"] + +[plugins] +loom = { id = "fabric-loom", version = "1.1-SNAPSHOT" } \ No newline at end of file diff --git a/src/main/java/com/dainxt/weaponthrow/ModMenuIntegration.java b/src/main/java/com/dainxt/weaponthrow/ModMenuIntegration.java index afe5073..3ec971a 100644 --- a/src/main/java/com/dainxt/weaponthrow/ModMenuIntegration.java +++ b/src/main/java/com/dainxt/weaponthrow/ModMenuIntegration.java @@ -10,10 +10,9 @@ @Environment(EnvType.CLIENT) public class ModMenuIntegration implements ModMenuApi{ - - @Override + + @Override public ConfigScreenFactory getModConfigScreenFactory() { return parent -> AutoConfig.getConfigScreen(WeaponThrowConfig.class, parent).get(); } - } diff --git a/src/main/java/com/dainxt/weaponthrow/config/WeaponThrowConfig.java b/src/main/java/com/dainxt/weaponthrow/config/WeaponThrowConfig.java index cb495a8..feb34e3 100644 --- a/src/main/java/com/dainxt/weaponthrow/config/WeaponThrowConfig.java +++ b/src/main/java/com/dainxt/weaponthrow/config/WeaponThrowConfig.java @@ -71,7 +71,7 @@ public static class Multipliers implements ConfigData { @ConfigEntry.Gui.CollapsibleObject public ToolMultipliers tools = new ToolMultipliers(); - public class ToolMultipliers implements ConfigData { + public static class ToolMultipliers implements ConfigData { public double pickaxeMultiplier = 0.8D; public double axeMultiplier = 1.2D; public double swordMultiplier = 1.D; @@ -82,7 +82,7 @@ public class ToolMultipliers implements ConfigData { @ConfigEntry.Gui.CollapsibleObject public DamageMultipliers damages = new DamageMultipliers(); - public class DamageMultipliers implements ConfigData { + public static class DamageMultipliers implements ConfigData { public double baseDamageMultiplier = 0.25D; public double stackDamageMultiplier = 0.0D; public double modifiedDamageMultiplier = 0.50D; @@ -91,7 +91,7 @@ public class DamageMultipliers implements ConfigData { @ConfigEntry.Gui.CollapsibleObject public VelocityMultipliers velocities = new VelocityMultipliers(); - public class VelocityMultipliers implements ConfigData { + public static class VelocityMultipliers implements ConfigData { public double baseVelocityMultiplier = 0.25D; public double stackVelocityMultiplier = 0.005D; public double modifiedVelocityMultiplier = 0.4D; @@ -100,7 +100,7 @@ public class VelocityMultipliers implements ConfigData { @ConfigEntry.Gui.CollapsibleObject public ExhaustionMultipliers exhaustions = new ExhaustionMultipliers(); - public class ExhaustionMultipliers implements ConfigData { + public static class ExhaustionMultipliers implements ConfigData { public double baseExhaustionMultiplier = 0.075D; public double stackExhaustionMultiplier = 0.01D; public double modifiedExhaustionMultiplier = 2.0D; diff --git a/src/main/java/com/dainxt/weaponthrow/enchantment/ConccusionEnchantment.java b/src/main/java/com/dainxt/weaponthrow/enchantment/ConccusionEnchantment.java index 1e59c5a..f966e4c 100644 --- a/src/main/java/com/dainxt/weaponthrow/enchantment/ConccusionEnchantment.java +++ b/src/main/java/com/dainxt/weaponthrow/enchantment/ConccusionEnchantment.java @@ -9,34 +9,25 @@ import net.minecraft.item.ItemStack; public class ConccusionEnchantment extends Enchantment { - public ConccusionEnchantment(Enchantment.Rarity rarityIn, EquipmentSlot... slots) { super(rarityIn, EnchantmentTarget.WEAPON, slots); } - public int getMinPower(int enchantmentLevel) { return 30; } - - public int getMaxPower(int enchantmentLevel) { return this.getMinPower(enchantmentLevel) + 30; } - - /** - * Returns the maximum level that the enchantment can have. - */ + // Returns the maximum level that the enchantment can have. public int getMaxLevel() { return 2; } - - @Override public boolean isAcceptableItem(ItemStack stack) { boolean enchantAll = ConfigRegistry.COMMON.getConfig().enchantments.enchantAllWeapons; boolean isAxe = stack.getItem() instanceof AxeItem; boolean canApply = super.isAcceptableItem(stack); - return isAxe || canApply || enchantAll ? ConfigRegistry.COMMON.getConfig().enchantments.enableConccusion : false; + return (isAxe || canApply || enchantAll) && ConfigRegistry.COMMON.getConfig().enchantments.enableConccusion; } } diff --git a/src/main/java/com/dainxt/weaponthrow/enchantment/GravityEnchantment.java b/src/main/java/com/dainxt/weaponthrow/enchantment/GravityEnchantment.java index da9bfb1..ad4c8cc 100644 --- a/src/main/java/com/dainxt/weaponthrow/enchantment/GravityEnchantment.java +++ b/src/main/java/com/dainxt/weaponthrow/enchantment/GravityEnchantment.java @@ -38,6 +38,6 @@ public boolean isAcceptableItem(ItemStack stack) { boolean enchantAll = ConfigRegistry.COMMON.getConfig().enchantments.enchantAllWeapons; boolean isAxe = stack.getItem() instanceof AxeItem; boolean canApply = super.isAcceptableItem(stack); - return isAxe || canApply || enchantAll ? ConfigRegistry.COMMON.getConfig().enchantments.enableGravity : false; + return (isAxe || canApply || enchantAll) && ConfigRegistry.COMMON.getConfig().enchantments.enableGravity; } } diff --git a/src/main/java/com/dainxt/weaponthrow/enchantment/GroundedEdgeEnchantment.java b/src/main/java/com/dainxt/weaponthrow/enchantment/GroundedEdgeEnchantment.java index 1dee356..45af653 100644 --- a/src/main/java/com/dainxt/weaponthrow/enchantment/GroundedEdgeEnchantment.java +++ b/src/main/java/com/dainxt/weaponthrow/enchantment/GroundedEdgeEnchantment.java @@ -14,9 +14,7 @@ public GroundedEdgeEnchantment(Enchantment.Rarity rarityIn, EquipmentSlot... slo super(rarityIn, EnchantmentTarget.WEAPON, slots); } - /** - * Returns the minimal value of enchantability needed on the enchantment level passed. - */ + // Returns the minimal value of enchantability needed on the enchantment level passed. public int getMinEnchantability(int enchantmentLevel) { return 25; } @@ -24,10 +22,7 @@ public int getMinEnchantability(int enchantmentLevel) { public int getMaxEnchantability(int enchantmentLevel) { return this.getMinEnchantability(enchantmentLevel) + 40; } - - /** - * Returns the maximum level that the enchantment can have. - */ + // Returns the maximum level that the enchantment can have. public int getMaxLevel() { return 3; } @@ -37,6 +32,6 @@ public boolean isAcceptableItem(ItemStack stack) { boolean enchantAll = ConfigRegistry.COMMON.getConfig().enchantments.enchantAllWeapons; boolean isAxe = stack.getItem() instanceof AxeItem; boolean canApply = super.isAcceptableItem(stack); - return isAxe || canApply || enchantAll ? ConfigRegistry.COMMON.getConfig().enchantments.enableGroundedEdge : false; + return (isAxe || canApply || enchantAll) && ConfigRegistry.COMMON.getConfig().enchantments.enableGroundedEdge; } } diff --git a/src/main/java/com/dainxt/weaponthrow/enchantment/ReturnEnchantment.java b/src/main/java/com/dainxt/weaponthrow/enchantment/ReturnEnchantment.java index f669a68..4a87705 100644 --- a/src/main/java/com/dainxt/weaponthrow/enchantment/ReturnEnchantment.java +++ b/src/main/java/com/dainxt/weaponthrow/enchantment/ReturnEnchantment.java @@ -9,26 +9,17 @@ import net.minecraft.item.ItemStack; public class ReturnEnchantment extends Enchantment { - - public ReturnEnchantment(Rarity rarityIn, EquipmentSlot... mainhand) { super(rarityIn, EnchantmentTarget.WEAPON, mainhand); } - - /** - * Returns the minimal value of enchantability needed on the enchantment level passed. - */ + // Returns the minimal value of enchantability needed on the enchantment level passed. public int getMinPower(int enchantmentLevel) { return 5 + enchantmentLevel * 7; } - public int getMaxPower(int enchantmentLevel) { return 50; } - - /** - * Returns the maximum level that the enchantment can have. - */ + // Returns the maximum level that the enchantment can have. public int getMaxLevel() { return 1; } @@ -38,7 +29,7 @@ public boolean isAcceptableItem(ItemStack stack) { boolean enchantAll = ConfigRegistry.COMMON.getConfig().enchantments.enchantAllWeapons; boolean isAxe = stack.getItem() instanceof AxeItem; boolean canApply = super.isAcceptableItem(stack); - return isAxe || canApply || enchantAll ? ConfigRegistry.COMMON.getConfig().enchantments.enableReturn : false; + return (isAxe || canApply || enchantAll) && ConfigRegistry.COMMON.getConfig().enchantments.enableReturn; } } diff --git a/src/main/java/com/dainxt/weaponthrow/enchantment/ThrowEnchantment.java b/src/main/java/com/dainxt/weaponthrow/enchantment/ThrowEnchantment.java index 2650873..52de6e8 100644 --- a/src/main/java/com/dainxt/weaponthrow/enchantment/ThrowEnchantment.java +++ b/src/main/java/com/dainxt/weaponthrow/enchantment/ThrowEnchantment.java @@ -13,21 +13,14 @@ public class ThrowEnchantment extends Enchantment { public ThrowEnchantment(Enchantment.Rarity rarityIn, EquipmentSlot... slots) { super(rarityIn, EnchantmentTarget.WEAPON, slots); } - - /** - * Returns the minimal value of enchantability needed on the enchantment level passed. - */ + // Returns the minimal value of enchantability needed on the enchantment level passed. public int getMinPower(int enchantmentLevel) { return 10; } - public int getMaxPower(int enchantmentLevel) { return this.getMinPower(enchantmentLevel) + 40; } - - /** - * Returns the maximum level that the enchantment can have. - */ + // Returns the maximum level that the enchantment can have. public int getMaxLevel() { return 3; } @@ -37,6 +30,6 @@ public boolean isAcceptableItem(ItemStack stack) { boolean enchantAll = ConfigRegistry.COMMON.getConfig().enchantments.enchantAllWeapons; boolean isAxe = stack.getItem() instanceof AxeItem; boolean canApply = super.isAcceptableItem(stack); - return isAxe || canApply || enchantAll ? ConfigRegistry.COMMON.getConfig().enchantments.enableThrow : false; + return (isAxe || canApply || enchantAll) && ConfigRegistry.COMMON.getConfig().enchantments.enableThrow; } } diff --git a/src/main/java/com/dainxt/weaponthrow/entity/render/WeaponThrowRenderer.java b/src/main/java/com/dainxt/weaponthrow/entity/render/WeaponThrowRenderer.java index 97a4389..ff784b9 100644 --- a/src/main/java/com/dainxt/weaponthrow/entity/render/WeaponThrowRenderer.java +++ b/src/main/java/com/dainxt/weaponthrow/entity/render/WeaponThrowRenderer.java @@ -45,9 +45,6 @@ public void render(WeaponThrowEntity entityIn, float entityYaw, float partialTic this.itemRenderer.renderItem(entityIn.getStack(), ModelTransformation.Mode.FIXED, packedLightIn, OverlayTexture.DEFAULT_UV, matrixStackIn, bufferIn, entityIn.getId()); } - matrixStackIn.pop(); - } - } \ No newline at end of file diff --git a/src/main/java/com/dainxt/weaponthrow/events/OnApplySlow.java b/src/main/java/com/dainxt/weaponthrow/events/OnApplySlow.java index 4cc6210..04a3f26 100644 --- a/src/main/java/com/dainxt/weaponthrow/events/OnApplySlow.java +++ b/src/main/java/com/dainxt/weaponthrow/events/OnApplySlow.java @@ -5,15 +5,13 @@ import net.minecraft.entity.player.PlayerEntity; public interface OnApplySlow { - Event EVENT = EventFactory.createArrayBacked(OnApplySlow.class, (listeners) -> (player) -> { - boolean result = false; + boolean result = false; for (OnApplySlow listener : listeners) { result = listener.interact(player) || result; } return result; }); - boolean interact(PlayerEntity player); } diff --git a/src/main/java/com/dainxt/weaponthrow/events/OnFOVUpdate.java b/src/main/java/com/dainxt/weaponthrow/events/OnFOVUpdate.java index d615f4c..e31ae78 100644 --- a/src/main/java/com/dainxt/weaponthrow/events/OnFOVUpdate.java +++ b/src/main/java/com/dainxt/weaponthrow/events/OnFOVUpdate.java @@ -5,12 +5,10 @@ import net.minecraft.entity.player.PlayerEntity; public interface OnFOVUpdate { - Event EVENT = EventFactory.createArrayBacked(OnFOVUpdate.class, (listeners) -> (player, amount) -> { for (OnFOVUpdate listener : listeners) { float result = listener.interact(player, amount); - if(result != 0) { return result; } @@ -18,6 +16,5 @@ public interface OnFOVUpdate { } return 0; }); - float interact(PlayerEntity entity, float fov); } diff --git a/src/main/java/com/dainxt/weaponthrow/events/OnHeldItemRender.java b/src/main/java/com/dainxt/weaponthrow/events/OnHeldItemRender.java index 4bd0807..69b5b68 100644 --- a/src/main/java/com/dainxt/weaponthrow/events/OnHeldItemRender.java +++ b/src/main/java/com/dainxt/weaponthrow/events/OnHeldItemRender.java @@ -4,22 +4,17 @@ import net.fabricmc.fabric.api.event.EventFactory; import net.minecraft.client.network.AbstractClientPlayerEntity; import net.minecraft.client.render.VertexConsumerProvider; -import net.minecraft.client.render.entity.PlayerEntityRenderer; import net.minecraft.client.render.item.HeldItemRenderer; import net.minecraft.client.util.math.MatrixStack; -import net.minecraft.entity.player.PlayerEntity; import net.minecraft.item.ItemStack; import net.minecraft.util.Hand; public interface OnHeldItemRender { - Event EVENT = EventFactory.createArrayBacked(OnHeldItemRender.class, (listeners) -> (renderer, player, tickDelta, pitch, hand, swingProgress, item, equipProgress, matrices, vertexConsumers, light) -> { for (OnHeldItemRender listener : listeners) { listener.interact(renderer, player, tickDelta, pitch, hand, swingProgress, item, equipProgress, matrices, vertexConsumers, light); } - }); - void interact(HeldItemRenderer renderer , AbstractClientPlayerEntity player, float tickDelta, float pitch, Hand hand, float swingProgress, ItemStack item, float equipProgress, MatrixStack matrices, VertexConsumerProvider vertexConsumers, int light); } diff --git a/src/main/java/com/dainxt/weaponthrow/events/OnStartPlayerRender.java b/src/main/java/com/dainxt/weaponthrow/events/OnStartPlayerRender.java index cc611e8..1fc8d57 100644 --- a/src/main/java/com/dainxt/weaponthrow/events/OnStartPlayerRender.java +++ b/src/main/java/com/dainxt/weaponthrow/events/OnStartPlayerRender.java @@ -6,7 +6,6 @@ import net.minecraft.entity.player.PlayerEntity; public interface OnStartPlayerRender { - Event EVENT = EventFactory.createArrayBacked(OnStartPlayerRender.class, (listeners) -> (renderer, player) -> { for (OnStartPlayerRender listener : listeners) { @@ -14,6 +13,5 @@ public interface OnStartPlayerRender { } }); - void interact(PlayerEntityRenderer renderer, PlayerEntity entity); } diff --git a/src/main/java/com/dainxt/weaponthrow/events/OnStartPlayerTick.java b/src/main/java/com/dainxt/weaponthrow/events/OnStartPlayerTick.java index 0d235df..a76d305 100644 --- a/src/main/java/com/dainxt/weaponthrow/events/OnStartPlayerTick.java +++ b/src/main/java/com/dainxt/weaponthrow/events/OnStartPlayerTick.java @@ -13,6 +13,5 @@ public interface OnStartPlayerTick { } }); - void interact(PlayerEntity entity); } diff --git a/src/main/java/com/dainxt/weaponthrow/handlers/ConfigRegistry.java b/src/main/java/com/dainxt/weaponthrow/handlers/ConfigRegistry.java index 9e262e2..77f7b7d 100644 --- a/src/main/java/com/dainxt/weaponthrow/handlers/ConfigRegistry.java +++ b/src/main/java/com/dainxt/weaponthrow/handlers/ConfigRegistry.java @@ -11,8 +11,6 @@ public class ConfigRegistry { public static ConfigHolder COMMON; public static void registerConfig() { - COMMON = AutoConfig.register(WeaponThrowConfig.class, GsonConfigSerializer::new); } - } diff --git a/src/main/java/com/dainxt/weaponthrow/handlers/EnchantmentHandler.java b/src/main/java/com/dainxt/weaponthrow/handlers/EnchantmentHandler.java index 99565cb..42d1346 100644 --- a/src/main/java/com/dainxt/weaponthrow/handlers/EnchantmentHandler.java +++ b/src/main/java/com/dainxt/weaponthrow/handlers/EnchantmentHandler.java @@ -20,8 +20,5 @@ public class EnchantmentHandler { public static final Enchantment GRAVITY = Registry.register(Registry.ENCHANTMENT, new Identifier(WeaponThrow.MODID, "gravity"), new GravityEnchantment(Enchantment.Rarity.VERY_RARE, EquipmentSlot.MAINHAND)); public static final Enchantment RETURN = Registry.register(Registry.ENCHANTMENT, new Identifier(WeaponThrow.MODID, "return"), new ReturnEnchantment(Enchantment.Rarity.RARE, EquipmentSlot.MAINHAND)); - public static void registerEnchantments() { - - } - + public static void registerEnchantments() {} } diff --git a/src/main/java/com/dainxt/weaponthrow/handlers/EntityRegistry.java b/src/main/java/com/dainxt/weaponthrow/handlers/EntityRegistry.java index 4edb151..db6a376 100644 --- a/src/main/java/com/dainxt/weaponthrow/handlers/EntityRegistry.java +++ b/src/main/java/com/dainxt/weaponthrow/handlers/EntityRegistry.java @@ -7,18 +7,15 @@ import net.minecraft.entity.EntityDimensions; import net.minecraft.entity.EntityType; import net.minecraft.entity.SpawnGroup; -import net.minecraft.entity.mob.MobEntity; import net.minecraft.util.Identifier; import net.minecraft.util.registry.Registry; public class EntityRegistry { - public static final EntityType WEAPONTHROW = Registry.register( Registry.ENTITY_TYPE, new Identifier(WeaponThrow.MODID, "weaponthrow"), FabricEntityTypeBuilder.create(SpawnGroup.MISC, WeaponThrowEntity::new).trackRangeBlocks(4).trackedUpdateRate(20).dimensions(EntityDimensions.fixed(0.5F, 0.5F)).build() ); - public static void registerEntities() { } diff --git a/src/main/java/com/dainxt/weaponthrow/handlers/EventsHandler.java b/src/main/java/com/dainxt/weaponthrow/handlers/EventsHandler.java index 29246d9..e031760 100644 --- a/src/main/java/com/dainxt/weaponthrow/handlers/EventsHandler.java +++ b/src/main/java/com/dainxt/weaponthrow/handlers/EventsHandler.java @@ -41,29 +41,25 @@ public class EventsHandler{ public static boolean wasPressed = false; - - //public static int clientSideCharge = 0; - + public static void onThrowItem(ServerPlayerEntity serverplayer, CPacketThrow.State action){ - - - - PlayerEntity player = (PlayerEntity) serverplayer; + + ServerWorld world = serverplayer.getWorld(); - ItemStack stack = player.getMainHandStack(); + ItemStack stack = serverplayer.getMainHandStack(); boolean isThrowable = ConfigRegistry.COMMON.get().experimental.shouldThrowItemsToo; Multimap multimap = stack.getAttributeModifiers(EquipmentSlot.MAINHAND); boolean haveAttributes = multimap.containsKey(EntityAttributes.GENERIC_ATTACK_DAMAGE) || multimap.containsKey(EntityAttributes.GENERIC_ATTACK_SPEED); - PlayerThrowData data = ((IPlayerEntityMixin)player).getThrowPower(); + PlayerThrowData data = ((IPlayerEntityMixin) serverplayer).getThrowPower(); if ((isThrowable || haveAttributes) && !stack.isEmpty()) { boolean cdConfig = ConfigRegistry.COMMON.get().general.notUseWhenCooldown; - if(!(player.getItemCooldownManager().getCooldownProgress(stack.getItem(), 1.0F) > 0 && cdConfig)) { + if(!(serverplayer.getItemCooldownManager().getCooldownProgress(stack.getItem(), 1.0F) > 0 && cdConfig)) { data.setAction(action); @@ -75,13 +71,10 @@ public static void onThrowItem(ServerPlayerEntity serverplayer, CPacketThrow.Sta float baseThrow = 0; float baseExhaustion = 0.05F; - - //float modThrow = 1.F - (data.getChargeTime()/(float)PlayerThrowData.getMaximumCharge(player)); - float modThrow = 1.0F; - if(Math.signum(PlayerThrowData.getMaximumCharge(player)) != 0.0F) { - modThrow = 1.F - (data.getChargeTime()/(float)PlayerThrowData.getMaximumCharge(player)); + if(Math.signum(PlayerThrowData.getMaximumCharge(serverplayer)) != 0.0F) { + modThrow = 1.F - (data.getChargeTime()/(float)PlayerThrowData.getMaximumCharge(serverplayer)); } data.resetCharging(); @@ -93,21 +86,18 @@ public static void onThrowItem(ServerPlayerEntity serverplayer, CPacketThrow.Sta } if(haveAttributes) { - baseThrow = 20/player.getAttackCooldownProgressPerTick(); - baseExhaustion = player.getAttackCooldownProgressPerTick()/20; + baseThrow = 20/ serverplayer.getAttackCooldownProgressPerTick(); + baseExhaustion = serverplayer.getAttackCooldownProgressPerTick()/20; } if(baseThrow>0) { boolean shouldDestroy = modThrow > 0.99; double baseDamage = ConfigRegistry.COMMON.get().defaults.baseDamageDefault; - double toolMultiplier = 0.0D; - - if(haveAttributes) { - baseDamage = (float) player.getAttributeValue(EntityAttributes.GENERIC_ATTACK_DAMAGE); + baseDamage = (float) serverplayer.getAttributeValue(EntityAttributes.GENERIC_ATTACK_DAMAGE); int types = 0; if(stack.getItem() instanceof AxeItem) { @@ -139,7 +129,7 @@ public static void onThrowItem(ServerPlayerEntity serverplayer, CPacketThrow.Sta toolMultiplier = 1.0F; } - int size = player.isSneaking() ? stack.getCount() : 1; + int size = serverplayer.isSneaking() ? stack.getCount() : 1; double bDamageMul = ConfigRegistry.COMMON.get().multipliers.damages.baseDamageMultiplier; double sDamageMul = ConfigRegistry.COMMON.get().multipliers.damages.stackDamageMultiplier; @@ -159,39 +149,27 @@ public static void onThrowItem(ServerPlayerEntity serverplayer, CPacketThrow.Sta double totalExhaustion = (baseExhaustion)*(1*bExhaustionMul + modThrow*mExhaustionMul) + (size*sExhaustionMul); totalExhaustion*=toolMultiplier; - WeaponThrowEntity throwedEntity = new WeaponThrowEntity(world, player, shouldDestroy, (float) totalDamage, stack.split(size)); - throwedEntity.setVelocity(player, player.getPitch(), player.getYaw(), 0.0F, (float) totalVelocity, 1.0F); - player.addExhaustion((float) totalExhaustion); - + WeaponThrowEntity throwedEntity = new WeaponThrowEntity(world, serverplayer, shouldDestroy, (float) totalDamage, stack.split(size)); + throwedEntity.setVelocity(serverplayer, serverplayer.getPitch(), serverplayer.getYaw(), 0.0F, (float) totalVelocity, 1.0F); + serverplayer.addExhaustion((float) totalExhaustion); world.spawnEntity(throwedEntity); SoundEvent soundevent = SoundEvents.ENTITY_EGG_THROW; throwedEntity.playSound(soundevent, 1.0F, 0.5F); - } } - - ((IPlayerEntityMixin)player).setThrowPower(data); - + ((IPlayerEntityMixin) serverplayer).setThrowPower(data); } - } - - /*if(stack.isEmpty() || !data.getChargingStack().equals(stack)) { - data.resetCharging(); - }*/ - } - - public static void registerEvents(){ OnStartPlayerTick.EVENT.register((player)->{ if(!player.world.isClient()) { PlayerThrowData cap = ((IPlayerEntityMixin)player).getThrowPower(); - boolean attacked = player.getAttackCooldownProgress(0.0F) < 1.0F ? true : false; + boolean attacked = player.getAttackCooldownProgress(0.0F) < 1.0F; boolean cdConfig = ConfigRegistry.COMMON.get().general.notUseWhenCooldown; boolean changedItem = !ItemStack.areEqual(cap.getChargingStack(), player.getMainHandStack()); @@ -204,7 +182,6 @@ public static void registerEvents(){ cap.setChargeTime(cap.getChargeTime() - 1); } - if(cap.getAction().equals(CPacketThrow.State.START) || cap.getAction().equals(CPacketThrow.State.FINISH)) { PacketHandler.sendToAll(player, new SPacketThrow(player.getUuid(), PlayerThrowData.getMaximumCharge(player), cap.getAction().equals(CPacketThrow.State.START))); @@ -219,14 +196,13 @@ public static void registerEvents(){ if(cap.getChargeTime() > 0) { cap.setChargeTime(cap.getChargeTime()-1); } - - //clientSideCharge = cap.getAction().equals(State.DURING)? clientSideCharge+1 : 0; } }); } public static void onSeverUpdate(UUID playerUUID, int maxChargeTime, boolean isCharging) { + assert MinecraftClient.getInstance().world != null; PlayerEntity playerentity = MinecraftClient.getInstance().world.getPlayerByUuid(playerUUID); if(playerentity != null) { @@ -249,24 +225,18 @@ public static void registerClientEvents() { if(cap.getAction().equals(State.DURING)) { - //float progress = MathHelper.clamp((float)(EventsHandler.clientSideCharge+tickDelta)/cap.MAX_CHARGE, 0.F, 1.0F); - float preProgress = 1.0F; - - /*if(Math.signum(cap.MAX_CHARGE) != 0.0F) { - preProgress = (float)(EventsHandler.clientSideCharge+tickDelta)/cap.MAX_CHARGE; - }*/ - + if(Math.signum(cap.MAX_CHARGE) != 0.0F && cap.getChargeTime() > 0) { float lerp = MathHelper.lerp(tickDelta, cap.getChargeTime()+1, cap.getChargeTime()); - preProgress = 1.F-(float)(lerp)/cap.MAX_CHARGE; + preProgress = 1.F- lerp /cap.MAX_CHARGE; } float progress = MathHelper.clamp(preProgress, 0.F, 1.0F); - - matrices.translate(0.0D, 0.0F, (double)((float)progress * 0.50F)); - matrices.multiply(Vec3f.POSITIVE_Z.getDegreesQuaternion((float)progress * 10.0F)); - matrices.multiply(Vec3f.POSITIVE_X.getDegreesQuaternion((float)progress * 40.0F)); + + matrices.translate(0.0D, 0.0F, progress * 0.50F); + matrices.multiply(Vec3f.POSITIVE_Z.getDegreesQuaternion(progress * 10.0F)); + matrices.multiply(Vec3f.POSITIVE_X.getDegreesQuaternion(progress * 40.0F)); } }); @@ -276,7 +246,7 @@ public static void registerClientEvents() { PlayerThrowData cap = ((IPlayerEntityMixin)player).getThrowPower(); if(cap.getAction().equals(State.DURING)) { if(player instanceof AbstractClientPlayerEntity) { - Arm hand = ((AbstractClientPlayerEntity)player).getMainArm(); + Arm hand = player.getMainArm(); if(hand == Arm.RIGHT) renderer.getModel().rightArmPose = BipedEntityModel.ArmPose.THROW_SPEAR; else @@ -302,23 +272,13 @@ public static void registerClientEvents() { float f = amount; if(isCharging) { - - - //int i = (int) (EventsHandler.clientSideCharge); - - //float f1 = (float)i / maxChargeTime; - + float f1 = 1.0F; - /*if(Math.signum(maxChargeTime) != 0.0F) { - f1 =(float)i / maxChargeTime; - }*/ - if(Math.signum(maxChargeTime) != 0.0F && chargeTime > 0) { float lerp = MathHelper.lerp(MinecraftClient.getInstance().getTickDelta(), chargeTime+1, chargeTime); - f1 = MathHelper.clamp(1.0F-(float)lerp / maxChargeTime, 0.F, 1.0F); + f1 = MathHelper.clamp(1.0F- lerp / maxChargeTime, 0.F, 1.0F); } - if (f1 > 1.0F) { f1 = 1.0F; } else { @@ -326,9 +286,7 @@ public static void registerClientEvents() { } f *= 1.0F + f1 * 0.15F; - } - return f; }); @@ -343,12 +301,8 @@ public static void registerClientEvents() { PacketHandler.sendToServer(new CPacketThrow(CPacketThrow.State.FINISH)); EventsHandler.wasPressed = false; } - }); - } - - } diff --git a/src/main/java/com/dainxt/weaponthrow/handlers/KeyBindingHandler.java b/src/main/java/com/dainxt/weaponthrow/handlers/KeyBindingHandler.java index 59736a0..4befeea 100644 --- a/src/main/java/com/dainxt/weaponthrow/handlers/KeyBindingHandler.java +++ b/src/main/java/com/dainxt/weaponthrow/handlers/KeyBindingHandler.java @@ -1,17 +1,10 @@ package com.dainxt.weaponthrow.handlers; -import java.util.Arrays; -import java.util.Collections; -import java.util.List; - import org.lwjgl.glfw.GLFW; -import com.google.common.collect.Lists; - import net.fabricmc.api.EnvType; import net.fabricmc.api.Environment; import net.fabricmc.fabric.api.client.keybinding.v1.KeyBindingHelper; -import net.minecraft.client.MinecraftClient; import net.minecraft.client.option.KeyBinding; import net.minecraft.client.util.InputUtil; diff --git a/src/main/java/com/dainxt/weaponthrow/handlers/PacketHandler.java b/src/main/java/com/dainxt/weaponthrow/handlers/PacketHandler.java index c4e80e1..9c3f2c4 100644 --- a/src/main/java/com/dainxt/weaponthrow/handlers/PacketHandler.java +++ b/src/main/java/com/dainxt/weaponthrow/handlers/PacketHandler.java @@ -40,5 +40,4 @@ public static void sendToAll(Entity entity, BasePacket packet) { ServerPlayNetworking.send(player, packet.getIdentifier(), packet.getBuf()); } } - } diff --git a/src/main/java/com/dainxt/weaponthrow/interfaces/IPlayerEntityMixin.java b/src/main/java/com/dainxt/weaponthrow/interfaces/IPlayerEntityMixin.java index faf5c0d..8d4c207 100644 --- a/src/main/java/com/dainxt/weaponthrow/interfaces/IPlayerEntityMixin.java +++ b/src/main/java/com/dainxt/weaponthrow/interfaces/IPlayerEntityMixin.java @@ -3,7 +3,6 @@ import com.dainxt.weaponthrow.capabilities.PlayerThrowData; public interface IPlayerEntityMixin { - public void setThrowPower(PlayerThrowData value); - - public PlayerThrowData getThrowPower(); + void setThrowPower(PlayerThrowData value); + PlayerThrowData getThrowPower(); } diff --git a/src/main/java/com/dainxt/weaponthrow/mixin/AbstractClientPlayerEntityMixin.java b/src/main/java/com/dainxt/weaponthrow/mixin/AbstractClientPlayerEntityMixin.java deleted file mode 100644 index a31c52b..0000000 --- a/src/main/java/com/dainxt/weaponthrow/mixin/AbstractClientPlayerEntityMixin.java +++ /dev/null @@ -1,28 +0,0 @@ -package com.dainxt.weaponthrow.mixin; - -import org.spongepowered.asm.mixin.Mixin; -import org.spongepowered.asm.mixin.injection.At; -import org.spongepowered.asm.mixin.injection.Inject; -import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; - -import com.dainxt.weaponthrow.events.OnFOVUpdate; - -import net.minecraft.client.network.AbstractClientPlayerEntity; -import net.minecraft.entity.player.PlayerEntity; - -@Mixin(AbstractClientPlayerEntity.class) -public abstract class AbstractClientPlayerEntityMixin{ - - @Inject(method = "getFovMultiplier", at = @At("RETURN"), cancellable = true) - private void getSpeed(CallbackInfoReturnable info) { - PlayerEntity player = (PlayerEntity) (Object) this; - - float amount = info.getReturnValue().floatValue(); - - float result = OnFOVUpdate.EVENT.invoker().interact(player, amount); - - info.setReturnValue(result); - - - } -} diff --git a/src/main/java/com/dainxt/weaponthrow/mixin/ClientPlayerEntityMixin.java b/src/main/java/com/dainxt/weaponthrow/mixin/ClientPlayerEntityMixin.java deleted file mode 100644 index e51d813..0000000 --- a/src/main/java/com/dainxt/weaponthrow/mixin/ClientPlayerEntityMixin.java +++ /dev/null @@ -1,28 +0,0 @@ -package com.dainxt.weaponthrow.mixin; - -import java.util.Arrays; -import java.util.List; - -import org.spongepowered.asm.mixin.Mixin; -import org.spongepowered.asm.mixin.gen.Accessor; -import org.spongepowered.asm.mixin.injection.At; -import org.spongepowered.asm.mixin.injection.Inject; -import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; -import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; - -import com.dainxt.weaponthrow.events.OnApplySlow; -import com.dainxt.weaponthrow.handlers.KeyBindingHandler; - -import net.minecraft.client.MinecraftClient; -import net.minecraft.client.network.ClientPlayerEntity; -import net.minecraft.client.option.GameOptions; -import net.minecraft.client.option.KeyBinding; -import net.minecraft.entity.player.PlayerEntity; - -@Mixin(ClientPlayerEntity.class) -public class ClientPlayerEntityMixin { - @Inject(at = @At("RETURN"), method = "shouldSlowDown", cancellable = true) - private void init(CallbackInfoReturnable info) { - info.setReturnValue(OnApplySlow.EVENT.invoker().interact((PlayerEntity)(Object)this) || info.getReturnValue()); - } -} diff --git a/src/main/java/com/dainxt/weaponthrow/mixin/HeldItemRendererMixin.java b/src/main/java/com/dainxt/weaponthrow/mixin/HeldItemRendererMixin.java deleted file mode 100644 index 6abe7d1..0000000 --- a/src/main/java/com/dainxt/weaponthrow/mixin/HeldItemRendererMixin.java +++ /dev/null @@ -1,43 +0,0 @@ -package com.dainxt.weaponthrow.mixin; - -import java.util.Arrays; -import java.util.List; - -import org.spongepowered.asm.mixin.Mixin; -import org.spongepowered.asm.mixin.Shadow; -import org.spongepowered.asm.mixin.gen.Accessor; -import org.spongepowered.asm.mixin.injection.At; -import org.spongepowered.asm.mixin.injection.Inject; -import org.spongepowered.asm.mixin.injection.ModifyArgs; -import org.spongepowered.asm.mixin.injection.ModifyVariable; -import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; -import org.spongepowered.asm.mixin.injection.invoke.arg.Args; - -import com.dainxt.weaponthrow.capabilities.PlayerThrowData; -import com.dainxt.weaponthrow.events.OnFOVUpdate; -import com.dainxt.weaponthrow.events.OnHeldItemRender; -import com.dainxt.weaponthrow.events.OnStartPlayerRender; -import com.dainxt.weaponthrow.events.OnStartPlayerTick; -import com.dainxt.weaponthrow.handlers.KeyBindingHandler; -import com.dainxt.weaponthrow.interfaces.IPlayerEntityMixin; - -import net.minecraft.client.MinecraftClient; -import net.minecraft.client.network.AbstractClientPlayerEntity; -import net.minecraft.client.option.GameOptions; -import net.minecraft.client.option.KeyBinding; -import net.minecraft.client.render.VertexConsumerProvider; -import net.minecraft.client.render.entity.PlayerEntityRenderer; -import net.minecraft.client.render.item.HeldItemRenderer; -import net.minecraft.client.util.math.MatrixStack; -import net.minecraft.entity.player.PlayerEntity; -import net.minecraft.item.ItemStack; -import net.minecraft.util.Hand; - -@Mixin(HeldItemRenderer.class) -public class HeldItemRendererMixin{ - - @Inject(method = "renderFirstPersonItem", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/network/AbstractClientPlayerEntity;isUsingRiptide()Z")) - private void renderCustom(AbstractClientPlayerEntity player, float tickDelta, float pitch, Hand hand, float swingProgress, ItemStack item, float equipProgress, MatrixStack matrices, VertexConsumerProvider vertexConsumers, int light, CallbackInfo info) { - OnHeldItemRender.EVENT.invoker().interact(((HeldItemRenderer)(Object)this), player, tickDelta, pitch, hand, swingProgress, item, equipProgress, matrices, vertexConsumers, light); - } -} diff --git a/src/main/java/com/dainxt/weaponthrow/mixin/IPlayerEntityMixin.java b/src/main/java/com/dainxt/weaponthrow/mixin/IPlayerEntityMixin.java deleted file mode 100644 index d9f123d..0000000 --- a/src/main/java/com/dainxt/weaponthrow/mixin/IPlayerEntityMixin.java +++ /dev/null @@ -1,9 +0,0 @@ -package com.dainxt.weaponthrow.mixin; - -import com.dainxt.weaponthrow.capabilities.PlayerThrowData; - -public interface IPlayerEntityMixin { - public void setThrowPower(PlayerThrowData value); - - public PlayerThrowData getThrowPower(); -} diff --git a/src/main/java/com/dainxt/weaponthrow/mixin/PlayerEntityMixin.java b/src/main/java/com/dainxt/weaponthrow/mixin/PlayerEntityMixin.java deleted file mode 100644 index ddd68e2..0000000 --- a/src/main/java/com/dainxt/weaponthrow/mixin/PlayerEntityMixin.java +++ /dev/null @@ -1,44 +0,0 @@ -package com.dainxt.weaponthrow.mixin; - -import java.util.Arrays; -import java.util.List; - -import org.spongepowered.asm.mixin.Mixin; -import org.spongepowered.asm.mixin.Shadow; -import org.spongepowered.asm.mixin.gen.Accessor; -import org.spongepowered.asm.mixin.injection.At; -import org.spongepowered.asm.mixin.injection.Inject; -import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; - -import com.dainxt.weaponthrow.capabilities.PlayerThrowData; -import com.dainxt.weaponthrow.events.OnFOVUpdate; -import com.dainxt.weaponthrow.events.OnStartPlayerTick; -import com.dainxt.weaponthrow.handlers.KeyBindingHandler; -import com.dainxt.weaponthrow.interfaces.IPlayerEntityMixin; - -import net.minecraft.client.MinecraftClient; -import net.minecraft.client.option.GameOptions; -import net.minecraft.client.option.KeyBinding; -import net.minecraft.entity.player.PlayerEntity; - -@Mixin(PlayerEntity.class) -public abstract class PlayerEntityMixin implements IPlayerEntityMixin{ - - - public PlayerThrowData throwPower = new PlayerThrowData((PlayerEntity)(Object) this); - - @Override - public void setThrowPower(PlayerThrowData value) { - this.throwPower = value; - } - - @Override - public PlayerThrowData getThrowPower() { - return this.throwPower; - } - - @Inject(at = @At("HEAD"), method = "tick") - private void init(CallbackInfo info) { - OnStartPlayerTick.EVENT.invoker().interact((PlayerEntity)(Object)this); - } -} diff --git a/src/main/java/com/dainxt/weaponthrow/mixin/PlayerEntityRendererMixin.java b/src/main/java/com/dainxt/weaponthrow/mixin/PlayerEntityRendererMixin.java deleted file mode 100644 index 2f5ee0c..0000000 --- a/src/main/java/com/dainxt/weaponthrow/mixin/PlayerEntityRendererMixin.java +++ /dev/null @@ -1,37 +0,0 @@ -package com.dainxt.weaponthrow.mixin; - -import java.util.Arrays; -import java.util.List; - -import org.spongepowered.asm.mixin.Mixin; -import org.spongepowered.asm.mixin.Shadow; -import org.spongepowered.asm.mixin.gen.Accessor; -import org.spongepowered.asm.mixin.injection.At; -import org.spongepowered.asm.mixin.injection.Inject; -import org.spongepowered.asm.mixin.injection.ModifyArgs; -import org.spongepowered.asm.mixin.injection.ModifyVariable; -import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; -import org.spongepowered.asm.mixin.injection.invoke.arg.Args; - -import com.dainxt.weaponthrow.capabilities.PlayerThrowData; -import com.dainxt.weaponthrow.events.OnFOVUpdate; -import com.dainxt.weaponthrow.events.OnStartPlayerRender; -import com.dainxt.weaponthrow.events.OnStartPlayerTick; -import com.dainxt.weaponthrow.handlers.KeyBindingHandler; -import com.dainxt.weaponthrow.interfaces.IPlayerEntityMixin; - -import net.minecraft.client.MinecraftClient; -import net.minecraft.client.network.AbstractClientPlayerEntity; -import net.minecraft.client.option.GameOptions; -import net.minecraft.client.option.KeyBinding; -import net.minecraft.client.render.entity.PlayerEntityRenderer; -import net.minecraft.entity.player.PlayerEntity; - -@Mixin(PlayerEntityRenderer.class) -public class PlayerEntityRendererMixin{ - - @Inject(method = "setModelPose", at = @At("TAIL")) - private void setModelPose(AbstractClientPlayerEntity player, CallbackInfo info) { - OnStartPlayerRender.EVENT.invoker().interact(((PlayerEntityRenderer)(Object)this), player); - } -} diff --git a/src/main/java/com/dainxt/weaponthrow/packets/EntitySpawnPacket.java b/src/main/java/com/dainxt/weaponthrow/packets/EntitySpawnPacket.java index b6da262..0e9ee9f 100644 --- a/src/main/java/com/dainxt/weaponthrow/packets/EntitySpawnPacket.java +++ b/src/main/java/com/dainxt/weaponthrow/packets/EntitySpawnPacket.java @@ -2,7 +2,6 @@ import java.util.UUID; -import com.dainxt.weaponthrow.WeaponThrow; import com.dainxt.weaponthrow.handlers.PacketHandler; import io.netty.buffer.Unpooled; @@ -13,7 +12,6 @@ import net.minecraft.entity.EntityType; import net.minecraft.network.Packet; import net.minecraft.network.PacketByteBuf; -import net.minecraft.util.Identifier; import net.minecraft.util.math.MathHelper; import net.minecraft.util.math.Vec3d; import net.minecraft.util.registry.Registry; @@ -125,7 +123,7 @@ public static void register() { Entity e = et.create(MinecraftClient.getInstance().world); if (e == null) throw new IllegalStateException("Failed to create instance of entity \"" + Registry.ENTITY_TYPE.getId(et) + "\"!"); - e.updateTrackedPosition(pos); + e.updateTrackedPosition(pos.getX(),pos.getY(),pos.getZ()); e.setPos(pos.x, pos.y, pos.z); e.setPitch(pitch); e.setYaw(yaw); diff --git a/src/main/java/com/dainxt/weaponthrow/projectile/WeaponThrowEntity.java b/src/main/java/com/dainxt/weaponthrow/projectile/WeaponThrowEntity.java index 6bd3b30..ff78f95 100644 --- a/src/main/java/com/dainxt/weaponthrow/projectile/WeaponThrowEntity.java +++ b/src/main/java/com/dainxt/weaponthrow/projectile/WeaponThrowEntity.java @@ -1,6 +1,7 @@ package com.dainxt.weaponthrow.projectile; import java.util.List; +import java.util.Objects; import org.jetbrains.annotations.Nullable; @@ -104,21 +105,21 @@ public void setItemStack(ItemStack stack) { this.getDataTracker().set(COMPOUND_STACK, stack.writeNbt(new NbtCompound())); } public ItemStack getItemStack() { - return ItemStack.fromNbt(((NbtCompound)this.getDataTracker().get(COMPOUND_STACK))); + return ItemStack.fromNbt(this.getDataTracker().get(COMPOUND_STACK)); } public void shouldDestroy(boolean stack) { this.getDataTracker().set(SHOULD_DESTROY, stack); } public boolean shouldDestroy() { - return ((Boolean)this.getDataTracker().get(SHOULD_DESTROY)); + return this.getDataTracker().get(SHOULD_DESTROY); } public void setDestroyedBlock(BlockPos pos) { this.getDataTracker().set(DESTROYED_BLOCK, pos); } public BlockPos getDestroyedBlock() { - return ((BlockPos)this.getDataTracker().get(DESTROYED_BLOCK)); + return this.getDataTracker().get(DESTROYED_BLOCK); } @@ -129,22 +130,19 @@ public void tick() { } if(!this.getDestroyedBlock().equals(BlockPos.ZERO) && !this.world.isClient) { - - this.doInteractions(() -> { - SoundEvent event = this.world.getBlockState(this.getDestroyedBlock()).getSoundGroup().getBreakSound(); - boolean destroyed = ((ServerPlayerEntity)this.getOwner()).interactionManager.tryBreakBlock(this.getDestroyedBlock()); - if(destroyed) { - this.world.playSound(null, this.getDestroyedBlock(), event , SoundCategory.AMBIENT, 10, 1.0F); - } - }); - - this.setDestroyedBlock(BlockPos.ORIGIN); + + this.doInteractions(() -> { + SoundEvent event = this.world.getBlockState(this.getDestroyedBlock()).getSoundGroup().getBreakSound(); + boolean destroyed = ((ServerPlayerEntity) Objects.requireNonNull(this.getOwner())).interactionManager.tryBreakBlock(this.getDestroyedBlock()); + if(destroyed) { + this.world.playSound(null, this.getDestroyedBlock(), event , SoundCategory.AMBIENT, 10, 1.0F); + } + }); + this.setDestroyedBlock(BlockPos.ORIGIN); } - int gravityWorld = ConfigRegistry.COMMON.get().enchantments.enableGravity ? EnchantmentHelper.getLevel(EnchantmentHandler.GRAVITY, this.getItemStack()) : 0; - if(gravityWorld > 0) { - this.setNoGravity(true); + if(gravityWorld > 0) {this.setNoGravity(true); if(this.world.isOutOfHeightLimit(this.getBlockPos())) { this.setVelocity(this.getVelocity().multiply(1, 0, 1)); } @@ -154,31 +152,20 @@ public void tick() { } } - - - /*if(this.inGround && MathHelper.abs(this.getPitch()) < 45 && this.getItemStack().getItem() instanceof BlockItem) { - if(!(Math.abs(this.getVelocity().getX()) < 0.1 && Math.abs(this.getVelocity().getZ()) < 0.1)) { - this.setVelocity(this.getVelocity().multiply(-0.5F)); - this.counterClockwiseBounce = !this.counterClockwiseBounce; - this.inGround = false; - } - }*/ Entity entity = this.getOwner(); - - + int i = ConfigRegistry.COMMON.get().enchantments.enableReturn ? this.dataTracker.get(LOYALTY_LEVEL) : 0; if (i > 0 && (this.dealtDamage || this.isNoClip()) && entity != null) { if (!this.shouldReturnToThrower()) { - if (!this.world.isClient && this.pickupType == PersistentProjectileEntity.PickupPermission.ALLOWED) { this.dropStack(this.getItemStack(), 0.1F); } this.remove(RemovalReason.DISCARDED); - } else if (i > 0) { + } else { this.setNoClip(true); Vec3d Vec3d = entity.getEyePos().subtract(this.getPos()); this.setPos(this.getX(), this.getY() + Vec3d.y * 0.015D * (double)i, this.getZ()); @@ -224,15 +211,14 @@ protected void onEntityHit(EntityHitResult p_213868_1_) { Entity entity = p_213868_1_.getEntity(); float f = this.attackDamage; - if (entity instanceof LivingEntity) { - LivingEntity livingentity = (LivingEntity)entity; + if (entity instanceof LivingEntity livingentity) { - f += ConfigRegistry.COMMON.get().enchantments.enableThrow ? EnchantmentHelper.getLevel(EnchantmentHandler.THROW, this.getItemStack())*1F : 0; + f += ConfigRegistry.COMMON.get().enchantments.enableThrow ? EnchantmentHelper.getLevel(EnchantmentHandler.THROW, this.getItemStack())*1F : 0; f += EnchantmentHelper.getAttackDamage(this.getItemStack(), livingentity.getGroup()); } Entity entity1 = this.getOwner(); - DamageSource damagesource = DamageSource.thrownProjectile(this, (Entity)(entity1 == null ? this : entity1)); + DamageSource damagesource = DamageSource.thrownProjectile(this, entity1 == null ? this : entity1); @@ -245,11 +231,10 @@ protected void onEntityHit(EntityHitResult p_213868_1_) { return; } - if (entity instanceof LivingEntity) { - LivingEntity livingentity1 = (LivingEntity)entity; - - - int contusionWorld = ConfigRegistry.COMMON.get().enchantments.enableConccusion ? EnchantmentHelper.getLevel(EnchantmentHandler.CONCCUSION, this.getItemStack()) : 0; + if (entity instanceof LivingEntity livingentity1) { + + + int contusionWorld = ConfigRegistry.COMMON.get().enchantments.enableConccusion ? EnchantmentHelper.getLevel(EnchantmentHandler.CONCCUSION, this.getItemStack()) : 0; if (contusionWorld > 0) { livingentity1.addStatusEffect(new StatusEffectInstance(StatusEffects.SLOWNESS, 20*2*contusionWorld, 5)); @@ -263,14 +248,12 @@ protected void onEntityHit(EntityHitResult p_213868_1_) { List nearEntities = world.getNonSpectatingEntities(LivingEntity.class, this.getBoundingBox().expand(1.0D)); if(!nearEntities.isEmpty()) { - for(LivingEntity nearEntity: nearEntities) { - if(nearEntity.getRandom().nextInt(3) == 0) { - nearEntity.setOnFireFor(fireTime); - } - if(true) { - nearEntity.addStatusEffect(new StatusEffectInstance(StatusEffects.WEAKNESS, 80, groundedWorld-1)); - } - } + for(LivingEntity nearEntity: nearEntities) { + if(nearEntity.getRandom().nextInt(3) == 0) { + nearEntity.setOnFireFor(fireTime); + } + nearEntity.addStatusEffect(new StatusEffectInstance(StatusEffects.WEAKNESS, 80, groundedWorld - 1)); + } } } @@ -282,23 +265,22 @@ protected void onEntityHit(EntityHitResult p_213868_1_) { this.onHit(livingentity1); if(this.getItemStack().getItem() instanceof BlockItem) { - Block blockItem = Block.getBlockFromItem(this.getItemStack().getItem()); - + Block blockItem = Block.getBlockFromItem(this.getItemStack().getItem()); if(blockItem instanceof SandBlock) { - if(livingentity1.getRandom().nextInt(10) == 0) livingentity1.addStatusEffect(new StatusEffectInstance(StatusEffects.BLINDNESS, 60, 3)); + if(livingentity1.getRandom().nextInt(10) == 0) livingentity1.addStatusEffect(new StatusEffectInstance(StatusEffects.BLINDNESS, 60, 3)); } else if (blockItem instanceof TorchBlock){ - if(livingentity1.getRandom().nextInt(5) == 0) livingentity1.setOnFireFor(1); + if(livingentity1.getRandom().nextInt(5) == 0) livingentity1.setOnFireFor(1); } else if (blockItem instanceof AnvilBlock){ - livingentity1.addStatusEffect(new StatusEffectInstance(StatusEffects.NAUSEA, 60, 3)); - livingentity1.addStatusEffect(new StatusEffectInstance(StatusEffects.SLOWNESS, 60, 5)); + livingentity1.addStatusEffect(new StatusEffectInstance(StatusEffects.NAUSEA, 60, 3)); + livingentity1.addStatusEffect(new StatusEffectInstance(StatusEffects.SLOWNESS, 60, 5)); } }else { - Item itemThrowed = this.getItemStack().getItem(); - if(itemThrowed.equals(Items.BLAZE_ROD) || itemThrowed.equals(Items.BLAZE_POWDER)) { - livingentity1.setOnFireFor(1); - } + Item itemThrowed = this.getItemStack().getItem(); + if(itemThrowed.equals(Items.BLAZE_ROD) || itemThrowed.equals(Items.BLAZE_POWDER)) { + livingentity1.setOnFireFor(1); + } } } @@ -323,7 +305,7 @@ public void onPlayerCollision(PlayerEntity entityIn) { Entity entity = this.getOwner(); if (entity == null || entity.getUuid() == entityIn.getUuid() || this.inGroundTime > (ConfigRegistry.COMMON.get().times.ticksUntilWeaponLoseOwner)) { - super.onPlayerCollision(entityIn); + super.onPlayerCollision(entityIn); } } @@ -333,7 +315,7 @@ public void readCustomDataFromNbt(NbtCompound compound) { this.dealtDamage = compound.getBoolean("DealtDamage"); if (compound.contains("Stack", 10)) { - this.setItemStack(ItemStack.fromNbt(compound.getCompound("Stack"))); + this.setItemStack(ItemStack.fromNbt(compound.getCompound("Stack"))); } this.dataTracker.set(LOYALTY_LEVEL, (byte)WeaponThrowEntity.getReturnOrLoyaltyEnchantment(this.getItemStack())); @@ -346,7 +328,7 @@ public void writeCustomDataToNbt(NbtCompound compound) { compound.put("Stack", this.getDataTracker().get(COMPOUND_STACK)); compound.putBoolean("DealtDamage", this.dealtDamage); if (this.lastState != null) { - compound.put("inBlockState", NbtHelper.fromBlockState(this.lastState)); + compound.put("inBlockState", NbtHelper.fromBlockState(this.lastState)); } } @@ -376,40 +358,29 @@ protected void onCollision(HitResult result) { this.onEntityHit((EntityHitResult)result); } else if (raytraceresult$type == HitResult.Type.BLOCK) { - - BlockPos stickBlockPos = ((BlockHitResult)result).getBlockPos(); - BlockState state = this.world.getBlockState(stickBlockPos); - - - - /*!WeaponThrowConfig.COMMON.blackList.get().contains(state.getBlock()) && */ - - if(!state.getBlock().equals(Blocks.BEDROCK) && this.shouldDestroy()) { - - boolean canBreak = ConfigRegistry.COMMON.get().interactions.canBreakBlocks; - - boolean canHarvest = this.getItemStack().isSuitableFor(state) && canBreak; - - if(canHarvest) { - - if(!world.isClient && this.lastState == null) { - this.setDestroyedBlock(stickBlockPos); - } - } - } - - this.onBlockHit((BlockHitResult)result); + BlockPos stickBlockPos = ((BlockHitResult)result).getBlockPos(); + BlockState state = this.world.getBlockState(stickBlockPos); + if(!state.getBlock().equals(Blocks.BEDROCK) && this.shouldDestroy()) { + boolean canBreak = ConfigRegistry.COMMON.get().interactions.canBreakBlocks; + + boolean canHarvest = this.getItemStack().isSuitableFor(state) && canBreak; + if(canHarvest) { + if(!world.isClient && this.lastState == null) { + this.setDestroyedBlock(stickBlockPos); + } + + } + } + this.onBlockHit((BlockHitResult)result); } } - - @Override protected void onBlockHit(BlockHitResult blockHitResult) { this.lastState = this.world.getBlockState(blockHitResult.getBlockPos()); Vec3d Vec3d = blockHitResult.getPos().subtract(this.getX(), this.getY(), this.getZ()); this.setVelocity(Vec3d); - Vec3d Vec3d1 = Vec3d.normalize().multiply((double)0.05F); + Vec3d Vec3d1 = Vec3d.normalize().multiply(0.05F); this.setPos(this.getX() - Vec3d1.x, this.getY() - Vec3d1.y, this.getZ() - Vec3d1.z); SoundEvent event = SoundEvents.ITEM_TRIDENT_HIT_GROUND; @@ -433,28 +404,22 @@ protected void onBlockHit(BlockHitResult blockHitResult) { void applyBounce() { if(this.inGround && this.getItemStack().getItem() instanceof BlockItem ) { - - if(!(Math.abs(this.getVelocity().x) < 0.05 && Math.abs(this.getVelocity().z) < 0.05)) { - - Vec3d vec3 = this.getVelocity().multiply(0.9F); - - BlockPos landingPos = getLandingPos(); - - if(!this.world.getBlockState(landingPos.down()).isAir() || !this.world.getBlockState(landingPos.up()).isAir()) { - this.setVelocity(vec3.x, -vec3.y, vec3.z); - } - else if(!this.world.getBlockState(landingPos.west()).isAir() || !this.world.getBlockState(landingPos.east()).isAir()){ - this.setVelocity(-vec3.x, vec3.y, vec3.z); - } - else if(!this.world.getBlockState(landingPos.north()).isAir() || !this.world.getBlockState(landingPos.south()).isAir()){ - this.setVelocity(vec3.x, vec3.y, -vec3.z); - } - - this.counterClockwiseBounce = !this.counterClockwiseBounce; - - - this.inGround = false; - } + if(!(Math.abs(this.getVelocity().x) < 0.05 && Math.abs(this.getVelocity().z) < 0.05)) { + + Vec3d vec3 = this.getVelocity().multiply(0.9F); + BlockPos landingPos = getSteppingPos(); + + if(!this.world.getBlockState(landingPos.down()).isAir() || !this.world.getBlockState(landingPos.up()).isAir()) { + this.setVelocity(vec3.x, -vec3.y, vec3.z); + } + else if(!this.world.getBlockState(landingPos.west()).isAir() || !this.world.getBlockState(landingPos.east()).isAir()){ + this.setVelocity(-vec3.x, vec3.y, vec3.z); + } + else if(!this.world.getBlockState(landingPos.north()).isAir() || !this.world.getBlockState(landingPos.south()).isAir()){ + this.setVelocity(vec3.x, vec3.y, -vec3.z); + } + this.counterClockwiseBounce = !this.counterClockwiseBounce; + this.inGround = false;} } } @@ -462,24 +427,19 @@ else if(!this.world.getBlockState(landingPos.north()).isAir() || !this.world.get public ItemStack getStack() { return this.getItemStack(); } - - + @Override public Packet createSpawnPacket() { return super.createSpawnPacket(); - //return EntitySpawnPacket.create(this); } public void doInteractions(Runnable action) { - ItemStack originalStack = ((PlayerEntity)this.getOwner()).getStackInHand(Hand.MAIN_HAND); + ItemStack originalStack = ((PlayerEntity) Objects.requireNonNull(this.getOwner())).getStackInHand(Hand.MAIN_HAND); ((PlayerEntity) this.getOwner()).setStackInHand(Hand.MAIN_HAND, this.getItemStack()); - action.run(); - - //((PlayerEntity) this.getOwner()).setStackInHand(Hand.MAIN_HAND, originalStack); - + ItemStack newStack = ((PlayerEntity) this.getOwner()).getStackInHand(Hand.MAIN_HAND); if (!newStack.isEmpty()) { @@ -488,15 +448,14 @@ public void doInteractions(Runnable action) { this.world.playSound(null, this.getBlockPos(), SoundEvents.ENTITY_ITEM_BREAK, SoundCategory.AMBIENT, 0.8F, 10F); - this.spawnItemParticles(this.getItemStack(), 5); + this.spawnItemParticles(this.getItemStack()); this.remove(RemovalReason.DISCARDED); } - } - private void spawnItemParticles(ItemStack stack, int count) { - for(int i = 0; i < count; ++i) { + private void spawnItemParticles(ItemStack stack) { + for(int i = 0; i < 5; ++i) { Vec3d vec3d = new Vec3d(((double)this.random.nextFloat() - 0.5D) * 0.1D, Math.random() * 0.1D + 0.1D, 0.0D); vec3d = vec3d.rotateX(-this.getPitch() * 0.017453292F); vec3d = vec3d.rotateY(-this.getYaw() * 0.017453292F); @@ -510,7 +469,6 @@ private void spawnItemParticles(ItemStack stack, int count) { else this.world.addParticle(new ItemStackParticleEffect(ParticleTypes.ITEM, stack), vec3d2.x, vec3d2.y, vec3d2.z, vec3d.x, vec3d.y + 0.05D, vec3d.z); } - } public static int getReturnOrLoyaltyEnchantment(ItemStack stack) { @@ -521,10 +479,7 @@ public static int getReturnOrLoyaltyEnchantment(ItemStack stack) { @Environment(EnvType.CLIENT) public float getRotationAnimation(float partialTicks) { - if(!this.inGround) { - clientSideRotation = (this.counterClockwiseBounce? 1:-1)*(this.age+partialTicks)*50F; - } + if(!this.inGround) {clientSideRotation = (this.counterClockwiseBounce? 1:-1)*(this.age+partialTicks)*50F;} return this.clientSideRotation; } - } diff --git a/src/main/resources/fabric.mod.json b/src/main/resources/fabric.mod.json index ecaa519..9024e48 100644 --- a/src/main/resources/fabric.mod.json +++ b/src/main/resources/fabric.mod.json @@ -35,9 +35,9 @@ ], "depends": { - "fabricloader": ">=0.11.3", + "fabricloader": ">=0.14.12+", "fabric": "*", - "minecraft": "1.18.x", + "minecraft": "1.19.2", "java": ">=17" }, "suggests": { diff --git a/src/main/resources/weaponthrow.mixins.json b/src/main/resources/weaponthrow.mixins.json index bc2536d..1e3af85 100644 --- a/src/main/resources/weaponthrow.mixins.json +++ b/src/main/resources/weaponthrow.mixins.json @@ -1,16 +1,16 @@ { "required": true, "minVersion": "0.8", - "package": "com.dainxt.weaponthrow.mixin", + "package": "com.dainxt.weaponthrow.mixins", "compatibilityLevel": "JAVA_16", "mixins": [ "PlayerEntityMixin" ], "client": [ - "ClientPlayerEntityMixin", - "HeldItemRendererMixin", - "PlayerEntityRendererMixin", - "AbstractClientPlayerEntityMixin" + "client.ClientPlayerEntityMixin", + "client.HeldItemRendererMixin", + "client.PlayerEntityRendererMixin", + "client.AbstractClientPlayerEntityMixin" ], "injectors": { "defaultRequire": 1