diff --git a/.editorconfig b/.editorconfig new file mode 100644 index 0000000..4ffbd90 --- /dev/null +++ b/.editorconfig @@ -0,0 +1,22 @@ +# This is the universal Text Editor Configuration +# for all GTNewHorizons projects +# See: https://editorconfig.org/ + +root = true + +[*] +charset = utf-8 +end_of_line = lf +indent_size = 4 +indent_style = space +insert_final_newline = true +trim_trailing_whitespace = true + +[*.{bat,ini}] +end_of_line = crlf + +[*.{dtd,json,info,mcmeta,md,sh,svg,xml,xsd,xsl,yaml,yml}] +indent_size = 2 + +[*.lang] +trim_trailing_whitespace = false diff --git a/.gitattributes b/.gitattributes new file mode 100644 index 0000000..fd2792b --- /dev/null +++ b/.gitattributes @@ -0,0 +1,44 @@ +* text eol=lf + +*.[jJ][aA][rR] binary + +*.[pP][nN][gG] binary +*.[jJ][pP][gG] binary +*.[jJ][pP][eE][gG] binary +*.[gG][iI][fF] binary +*.[tT][iI][fF] binary +*.[tT][iI][fF][fF] binary +*.[iI][cC][oO] binary +*.[sS][vV][gG] text +*.[eE][pP][sS] binary +*.[xX][cC][fF] binary + +*.[kK][aA][rR] binary +*.[mM]4[aA] binary +*.[mM][iI][dD] binary +*.[mM][iI][dD][iI] binary +*.[mM][pP]3 binary +*.[oO][gG][gG] binary +*.[rR][aA] binary + +*.7[zZ] binary +*.[gG][zZ] binary +*.[tT][aA][rR] binary +*.[tT][gG][zZ] binary +*.[zZ][iI][pP] binary + +*.[tT][cC][nN] binary +*.[sS][oO] binary +*.[dD][lL][lL] binary +*.[dD][yY][lL][iI][bB] binary +*.[pP][sS][dD] binary +*.[tT][tT][fF] binary +*.[oO][tT][fF] binary + +*.[pP][aA][tT][cC][hH] -text + +*.[bB][aA][tT] text eol=crlf +*.[cC][mM][dD] text eol=crlf +*.[pP][sS]1 text eol=crlf + +*[aA][uU][tT][oO][gG][eE][nN][eE][rR][aA][tT][eE][dD]* binary diff --git a/.github/workflows/build-and-test.yml b/.github/workflows/build-and-test.yml new file mode 100644 index 0000000..3ee2f68 --- /dev/null +++ b/.github/workflows/build-and-test.yml @@ -0,0 +1,13 @@ + +name: Build and test + +on: + pull_request: + branches: [ master, main ] + push: + branches: [ master, main ] + +jobs: + build-and-test: + uses: GTNewHorizons/GTNH-Actions-Workflows/.github/workflows/build-and-test.yml@master + secrets: inherit diff --git a/.github/workflows/release-tags.yml b/.github/workflows/release-tags.yml new file mode 100644 index 0000000..e4c0be6 --- /dev/null +++ b/.github/workflows/release-tags.yml @@ -0,0 +1,14 @@ + +name: Release tagged build + +on: + push: + tags: [ '*' ] + +permissions: + contents: write + +jobs: + release-tags: + uses: GTNewHorizons/GTNH-Actions-Workflows/.github/workflows/release-tags.yml@master + secrets: inherit diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..5e80e0a --- /dev/null +++ b/.gitignore @@ -0,0 +1,38 @@ +.gradle +.settings +/.idea/ +/.vscode/ +/run/ +/build/ +/eclipse/ +.classpath +.project +/bin/ +/config/ +/crash-reports/ +/logs/ +options.txt +/saves/ +usernamecache.json +banned-ips.json +banned-players.json +eula.txt +ops.json +server.properties +servers.dat +usercache.json +whitelist.json +/out/ +*.iml +*.ipr +*.iws +src/main/resources/mixins.*([!.]).json +*.bat +*.DS_Store +!gradlew.bat +.factorypath +addon.local.gradle +addon.local.gradle.kts +addon.late.local.gradle +addon.late.local.gradle.kts +layout.json diff --git a/CODEOWNERS b/CODEOWNERS new file mode 100644 index 0000000..a6b5f68 --- /dev/null +++ b/CODEOWNERS @@ -0,0 +1,3 @@ +# Any Github changes require admin approval +/.github/** @GTNewHorizons/admin + diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..94a9ed0 --- /dev/null +++ b/LICENSE @@ -0,0 +1,674 @@ + GNU GENERAL PUBLIC LICENSE + Version 3, 29 June 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 General Public License is a free, copyleft license for +software and other kinds of works. + + The licenses for most software and other practical works are designed +to take away your freedom to share and change the works. By contrast, +the GNU General Public License is intended to guarantee your freedom to +share and change all versions of a program--to make sure it remains free +software for all its users. We, the Free Software Foundation, use the +GNU General Public License for most of our software; it applies also to +any other work released this way by its authors. You can apply it to +your programs, too. + + When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +them if you wish), that you receive source code or can get it if you +want it, that you can change the software or use pieces of it in new +free programs, and that you know you can do these things. + + To protect your rights, we need to prevent others from denying you +these rights or asking you to surrender the rights. Therefore, you have +certain responsibilities if you distribute copies of the software, or if +you modify it: responsibilities to respect the freedom of others. + + For example, if you distribute copies of such a program, whether +gratis or for a fee, you must pass on to the recipients the same +freedoms that you received. You must make sure that they, too, receive +or can get the source code. And you must show them these terms so they +know their rights. + + Developers that use the GNU GPL protect your rights with two steps: +(1) assert copyright on the software, and (2) offer you this License +giving you legal permission to copy, distribute and/or modify it. + + For the developers' and authors' protection, the GPL clearly explains +that there is no warranty for this free software. For both users' and +authors' sake, the GPL requires that modified versions be marked as +changed, so that their problems will not be attributed erroneously to +authors of previous versions. + + Some devices are designed to deny users access to install or run +modified versions of the software inside them, although the manufacturer +can do so. This is fundamentally incompatible with the aim of +protecting users' freedom to change the software. The systematic +pattern of such abuse occurs in the area of products for individuals to +use, which is precisely where it is most unacceptable. Therefore, we +have designed this version of the GPL to prohibit the practice for those +products. If such problems arise substantially in other domains, we +stand ready to extend this provision to those domains in future versions +of the GPL, as needed to protect the freedom of users. + + Finally, every program is threatened constantly by software patents. +States should not allow patents to restrict development and use of +software on general-purpose computers, but in those that do, we wish to +avoid the special danger that patents applied to a free program could +make it effectively proprietary. To prevent this, the GPL assures that +patents cannot be used to render the program non-free. + + The precise terms and conditions for copying, distribution and +modification follow. + + TERMS AND CONDITIONS + + 0. Definitions. + + "This License" refers to version 3 of the GNU General Public License. + + "Copyright" also means copyright-like laws that apply to other kinds of +works, such as semiconductor masks. + + "The Program" refers to any copyrightable work licensed under this +License. Each licensee is addressed as "you". "Licensees" and +"recipients" may be individuals or organizations. + + To "modify" a work means to copy from or adapt all or part of the work +in a fashion requiring copyright permission, other than the making of an +exact copy. The resulting work is called a "modified version" of the +earlier work or a work "based on" the earlier work. + + A "covered work" means either the unmodified Program or a work based +on the Program. + + To "propagate" a work means to do anything with it that, without +permission, would make you directly or secondarily liable for +infringement under applicable copyright law, except executing it on a +computer or modifying a private copy. Propagation includes copying, +distribution (with or without modification), making available to the +public, and in some countries other activities as well. + + To "convey" a work means any kind of propagation that enables other +parties to make or receive copies. Mere interaction with a user through +a computer network, with no transfer of a copy, is not conveying. + + An interactive user interface displays "Appropriate Legal Notices" +to the extent that it includes a convenient and prominently visible +feature that (1) displays an appropriate copyright notice, and (2) +tells the user that there is no warranty for the work (except to the +extent that warranties are provided), that licensees may convey the +work under this License, and how to view a copy of this License. If +the interface presents a list of user commands or options, such as a +menu, a prominent item in the list meets this criterion. + + 1. Source Code. + + The "source code" for a work means the preferred form of the work +for making modifications to it. "Object code" means any non-source +form of a work. + + A "Standard Interface" means an interface that either is an official +standard defined by a recognized standards body, or, in the case of +interfaces specified for a particular programming language, one that +is widely used among developers working in that language. + + The "System Libraries" of an executable work include anything, other +than the work as a whole, that (a) is included in the normal form of +packaging a Major Component, but which is not part of that Major +Component, and (b) serves only to enable use of the work with that +Major Component, or to implement a Standard Interface for which an +implementation is available to the public in source code form. A +"Major Component", in this context, means a major essential component +(kernel, window system, and so on) of the specific operating system +(if any) on which the executable work runs, or a compiler used to +produce the work, or an object code interpreter used to run it. + + The "Corresponding Source" for a work in object code form means all +the source code needed to generate, install, and (for an executable +work) run the object code and to modify the work, including scripts to +control those activities. However, it does not include the work's +System Libraries, or general-purpose tools or generally available free +programs which are used unmodified in performing those activities but +which are not part of the work. For example, Corresponding Source +includes interface definition files associated with source files for +the work, and the source code for shared libraries and dynamically +linked subprograms that the work is specifically designed to require, +such as by intimate data communication or control flow between those +subprograms and other parts of the work. + + The Corresponding Source need not include anything that users +can regenerate automatically from other parts of the Corresponding +Source. + + The Corresponding Source for a work in source code form is that +same work. + + 2. Basic Permissions. + + All rights granted under this License are granted for the term of +copyright on the Program, and are irrevocable provided the stated +conditions are met. This License explicitly affirms your unlimited +permission to run the unmodified Program. The output from running a +covered work is covered by this License only if the output, given its +content, constitutes a covered work. This License acknowledges your +rights of fair use or other equivalent, as provided by copyright law. + + You may make, run and propagate covered works that you do not +convey, without conditions so long as your license otherwise remains +in force. You may convey covered works to others for the sole purpose +of having them make modifications exclusively for you, or provide you +with facilities for running those works, provided that you comply with +the terms of this License in conveying all material for which you do +not control copyright. Those thus making or running the covered works +for you must do so exclusively on your behalf, under your direction +and control, on terms that prohibit them from making any copies of +your copyrighted material outside their relationship with you. + + Conveying under any other circumstances is permitted solely under +the conditions stated below. Sublicensing is not allowed; section 10 +makes it unnecessary. + + 3. Protecting Users' Legal Rights From Anti-Circumvention Law. + + No covered work shall be deemed part of an effective technological +measure under any applicable law fulfilling obligations under article +11 of the WIPO copyright treaty adopted on 20 December 1996, or +similar laws prohibiting or restricting circumvention of such +measures. + + When you convey a covered work, you waive any legal power to forbid +circumvention of technological measures to the extent such circumvention +is effected by exercising rights under this License with respect to +the covered work, and you disclaim any intention to limit operation or +modification of the work as a means of enforcing, against the work's +users, your or third parties' legal rights to forbid circumvention of +technological measures. + + 4. Conveying Verbatim Copies. + + You may convey verbatim copies of the Program's source code as you +receive it, in any medium, provided that you conspicuously and +appropriately publish on each copy an appropriate copyright notice; +keep intact all notices stating that this License and any +non-permissive terms added in accord with section 7 apply to the code; +keep intact all notices of the absence of any warranty; and give all +recipients a copy of this License along with the Program. + + You may charge any price or no price for each copy that you convey, +and you may offer support or warranty protection for a fee. + + 5. Conveying Modified Source Versions. + + You may convey a work based on the Program, or the modifications to +produce it from the Program, in the form of source code under the +terms of section 4, provided that you also meet all of these conditions: + + a) The work must carry prominent notices stating that you modified + it, and giving a relevant date. + + b) The work must carry prominent notices stating that it is + released under this License and any conditions added under section + 7. This requirement modifies the requirement in section 4 to + "keep intact all notices". + + c) You must license the entire work, as a whole, under this + License to anyone who comes into possession of a copy. This + License will therefore apply, along with any applicable section 7 + additional terms, to the whole of the work, and all its parts, + regardless of how they are packaged. This License gives no + permission to license the work in any other way, but it does not + invalidate such permission if you have separately received it. + + d) If the work has interactive user interfaces, each must display + Appropriate Legal Notices; however, if the Program has interactive + interfaces that do not display Appropriate Legal Notices, your + work need not make them do so. + + A compilation of a covered work with other separate and independent +works, which are not by their nature extensions of the covered work, +and which are not combined with it such as to form a larger program, +in or on a volume of a storage or distribution medium, is called an +"aggregate" if the compilation and its resulting copyright are not +used to limit the access or legal rights of the compilation's users +beyond what the individual works permit. Inclusion of a covered work +in an aggregate does not cause this License to apply to the other +parts of the aggregate. + + 6. Conveying Non-Source Forms. + + You may convey a covered work in object code form under the terms +of sections 4 and 5, provided that you also convey the +machine-readable Corresponding Source under the terms of this License, +in one of these ways: + + a) Convey the object code in, or embodied in, a physical product + (including a physical distribution medium), accompanied by the + Corresponding Source fixed on a durable physical medium + customarily used for software interchange. + + b) Convey the object code in, or embodied in, a physical product + (including a physical distribution medium), accompanied by a + written offer, valid for at least three years and valid for as + long as you offer spare parts or customer support for that product + model, to give anyone who possesses the object code either (1) a + copy of the Corresponding Source for all the software in the + product that is covered by this License, on a durable physical + medium customarily used for software interchange, for a price no + more than your reasonable cost of physically performing this + conveying of source, or (2) access to copy the + Corresponding Source from a network server at no charge. + + c) Convey individual copies of the object code with a copy of the + written offer to provide the Corresponding Source. This + alternative is allowed only occasionally and noncommercially, and + only if you received the object code with such an offer, in accord + with subsection 6b. + + d) Convey the object code by offering access from a designated + place (gratis or for a charge), and offer equivalent access to the + Corresponding Source in the same way through the same place at no + further charge. You need not require recipients to copy the + Corresponding Source along with the object code. If the place to + copy the object code is a network server, the Corresponding Source + may be on a different server (operated by you or a third party) + that supports equivalent copying facilities, provided you maintain + clear directions next to the object code saying where to find the + Corresponding Source. Regardless of what server hosts the + Corresponding Source, you remain obligated to ensure that it is + available for as long as needed to satisfy these requirements. + + e) Convey the object code using peer-to-peer transmission, provided + you inform other peers where the object code and Corresponding + Source of the work are being offered to the general public at no + charge under subsection 6d. + + A separable portion of the object code, whose source code is excluded +from the Corresponding Source as a System Library, need not be +included in conveying the object code work. + + A "User Product" is either (1) a "consumer product", which means any +tangible personal property which is normally used for personal, family, +or household purposes, or (2) anything designed or sold for incorporation +into a dwelling. In determining whether a product is a consumer product, +doubtful cases shall be resolved in favor of coverage. For a particular +product received by a particular user, "normally used" refers to a +typical or common use of that class of product, regardless of the status +of the particular user or of the way in which the particular user +actually uses, or expects or is expected to use, the product. A product +is a consumer product regardless of whether the product has substantial +commercial, industrial or non-consumer uses, unless such uses represent +the only significant mode of use of the product. + + "Installation Information" for a User Product means any methods, +procedures, authorization keys, or other information required to install +and execute modified versions of a covered work in that User Product from +a modified version of its Corresponding Source. The information must +suffice to ensure that the continued functioning of the modified object +code is in no case prevented or interfered with solely because +modification has been made. + + If you convey an object code work under this section in, or with, or +specifically for use in, a User Product, and the conveying occurs as +part of a transaction in which the right of possession and use of the +User Product is transferred to the recipient in perpetuity or for a +fixed term (regardless of how the transaction is characterized), the +Corresponding Source conveyed under this section must be accompanied +by the Installation Information. But this requirement does not apply +if neither you nor any third party retains the ability to install +modified object code on the User Product (for example, the work has +been installed in ROM). + + The requirement to provide Installation Information does not include a +requirement to continue to provide support service, warranty, or updates +for a work that has been modified or installed by the recipient, or for +the User Product in which it has been modified or installed. Access to a +network may be denied when the modification itself materially and +adversely affects the operation of the network or violates the rules and +protocols for communication across the network. + + Corresponding Source conveyed, and Installation Information provided, +in accord with this section must be in a format that is publicly +documented (and with an implementation available to the public in +source code form), and must require no special password or key for +unpacking, reading or copying. + + 7. Additional Terms. + + "Additional permissions" are terms that supplement the terms of this +License by making exceptions from one or more of its conditions. +Additional permissions that are applicable to the entire Program shall +be treated as though they were included in this License, to the extent +that they are valid under applicable law. If additional permissions +apply only to part of the Program, that part may be used separately +under those permissions, but the entire Program remains governed by +this License without regard to the additional permissions. + + When you convey a copy of a covered work, you may at your option +remove any additional permissions from that copy, or from any part of +it. (Additional permissions may be written to require their own +removal in certain cases when you modify the work.) You may place +additional permissions on material, added by you to a covered work, +for which you have or can give appropriate copyright permission. + + Notwithstanding any other provision of this License, for material you +add to a covered work, you may (if authorized by the copyright holders of +that material) supplement the terms of this License with terms: + + a) Disclaiming warranty or limiting liability differently from the + terms of sections 15 and 16 of this License; or + + b) Requiring preservation of specified reasonable legal notices or + author attributions in that material or in the Appropriate Legal + Notices displayed by works containing it; or + + c) Prohibiting misrepresentation of the origin of that material, or + requiring that modified versions of such material be marked in + reasonable ways as different from the original version; or + + d) Limiting the use for publicity purposes of names of licensors or + authors of the material; or + + e) Declining to grant rights under trademark law for use of some + trade names, trademarks, or service marks; or + + f) Requiring indemnification of licensors and authors of that + material by anyone who conveys the material (or modified versions of + it) with contractual assumptions of liability to the recipient, for + any liability that these contractual assumptions directly impose on + those licensors and authors. + + All other non-permissive additional terms are considered "further +restrictions" within the meaning of section 10. If the Program as you +received it, or any part of it, contains a notice stating that it is +governed by this License along with a term that is a further +restriction, you may remove that term. If a license document contains +a further restriction but permits relicensing or conveying under this +License, you may add to a covered work material governed by the terms +of that license document, provided that the further restriction does +not survive such relicensing or conveying. + + If you add terms to a covered work in accord with this section, you +must place, in the relevant source files, a statement of the +additional terms that apply to those files, or a notice indicating +where to find the applicable terms. + + Additional terms, permissive or non-permissive, may be stated in the +form of a separately written license, or stated as exceptions; +the above requirements apply either way. + + 8. Termination. + + You may not propagate or modify a covered work except as expressly +provided under this License. Any attempt otherwise to propagate or +modify it is void, and will automatically terminate your rights under +this License (including any patent licenses granted under the third +paragraph of section 11). + + However, if you cease all violation of this License, then your +license from a particular copyright holder is reinstated (a) +provisionally, unless and until the copyright holder explicitly and +finally terminates your license, and (b) permanently, if the copyright +holder fails to notify you of the violation by some reasonable means +prior to 60 days after the cessation. + + Moreover, your license from a particular copyright holder is +reinstated permanently if the copyright holder notifies you of the +violation by some reasonable means, this is the first time you have +received notice of violation of this License (for any work) from that +copyright holder, and you cure the violation prior to 30 days after +your receipt of the notice. + + Termination of your rights under this section does not terminate the +licenses of parties who have received copies or rights from you under +this License. If your rights have been terminated and not permanently +reinstated, you do not qualify to receive new licenses for the same +material under section 10. + + 9. Acceptance Not Required for Having Copies. + + You are not required to accept this License in order to receive or +run a copy of the Program. Ancillary propagation of a covered work +occurring solely as a consequence of using peer-to-peer transmission +to receive a copy likewise does not require acceptance. However, +nothing other than this License grants you permission to propagate or +modify any covered work. These actions infringe copyright if you do +not accept this License. Therefore, by modifying or propagating a +covered work, you indicate your acceptance of this License to do so. + + 10. Automatic Licensing of Downstream Recipients. + + Each time you convey a covered work, the recipient automatically +receives a license from the original licensors, to run, modify and +propagate that work, subject to this License. You are not responsible +for enforcing compliance by third parties with this License. + + An "entity transaction" is a transaction transferring control of an +organization, or substantially all assets of one, or subdividing an +organization, or merging organizations. If propagation of a covered +work results from an entity transaction, each party to that +transaction who receives a copy of the work also receives whatever +licenses to the work the party's predecessor in interest had or could +give under the previous paragraph, plus a right to possession of the +Corresponding Source of the work from the predecessor in interest, if +the predecessor has it or can get it with reasonable efforts. + + You may not impose any further restrictions on the exercise of the +rights granted or affirmed under this License. For example, you may +not impose a license fee, royalty, or other charge for exercise of +rights granted under this License, and you may not initiate litigation +(including a cross-claim or counterclaim in a lawsuit) alleging that +any patent claim is infringed by making, using, selling, offering for +sale, or importing the Program or any portion of it. + + 11. Patents. + + A "contributor" is a copyright holder who authorizes use under this +License of the Program or a work on which the Program is based. The +work thus licensed is called the contributor's "contributor version". + + A contributor's "essential patent claims" are all patent claims +owned or controlled by the contributor, whether already acquired or +hereafter acquired, that would be infringed by some manner, permitted +by this License, of making, using, or selling its contributor version, +but do not include claims that would be infringed only as a +consequence of further modification of the contributor version. For +purposes of this definition, "control" includes the right to grant +patent sublicenses in a manner consistent with the requirements of +this License. + + Each contributor grants you a non-exclusive, worldwide, royalty-free +patent license under the contributor's essential patent claims, to +make, use, sell, offer for sale, import and otherwise run, modify and +propagate the contents of its contributor version. + + In the following three paragraphs, a "patent license" is any express +agreement or commitment, however denominated, not to enforce a patent +(such as an express permission to practice a patent or covenant not to +sue for patent infringement). To "grant" such a patent license to a +party means to make such an agreement or commitment not to enforce a +patent against the party. + + If you convey a covered work, knowingly relying on a patent license, +and the Corresponding Source of the work is not available for anyone +to copy, free of charge and under the terms of this License, through a +publicly available network server or other readily accessible means, +then you must either (1) cause the Corresponding Source to be so +available, or (2) arrange to deprive yourself of the benefit of the +patent license for this particular work, or (3) arrange, in a manner +consistent with the requirements of this License, to extend the patent +license to downstream recipients. "Knowingly relying" means you have +actual knowledge that, but for the patent license, your conveying the +covered work in a country, or your recipient's use of the covered work +in a country, would infringe one or more identifiable patents in that +country that you have reason to believe are valid. + + If, pursuant to or in connection with a single transaction or +arrangement, you convey, or propagate by procuring conveyance of, a +covered work, and grant a patent license to some of the parties +receiving the covered work authorizing them to use, propagate, modify +or convey a specific copy of the covered work, then the patent license +you grant is automatically extended to all recipients of the covered +work and works based on it. + + A patent license is "discriminatory" if it does not include within +the scope of its coverage, prohibits the exercise of, or is +conditioned on the non-exercise of one or more of the rights that are +specifically granted under this License. You may not convey a covered +work if you are a party to an arrangement with a third party that is +in the business of distributing software, under which you make payment +to the third party based on the extent of your activity of conveying +the work, and under which the third party grants, to any of the +parties who would receive the covered work from you, a discriminatory +patent license (a) in connection with copies of the covered work +conveyed by you (or copies made from those copies), or (b) primarily +for and in connection with specific products or compilations that +contain the covered work, unless you entered into that arrangement, +or that patent license was granted, prior to 28 March 2007. + + Nothing in this License shall be construed as excluding or limiting +any implied license or other defenses to infringement that may +otherwise be available to you under applicable patent law. + + 12. No Surrender of Others' Freedom. + + If conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot convey a +covered work so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you may +not convey it at all. For example, if you agree to terms that obligate you +to collect a royalty for further conveying from those to whom you convey +the Program, the only way you could satisfy both those terms and this +License would be to refrain entirely from conveying the Program. + + 13. Use with the GNU Affero General Public License. + + Notwithstanding any other provision of this License, you have +permission to link or combine any covered work with a work licensed +under version 3 of the GNU Affero General Public License into a single +combined work, and to convey the resulting work. The terms of this +License will continue to apply to the part which is the covered work, +but the special requirements of the GNU Affero General Public License, +section 13, concerning interaction through a network will apply to the +combination as such. + + 14. Revised Versions of this License. + + The Free Software Foundation may publish revised and/or new versions of +the GNU General Public License from time to time. Such new versions will +be similar in spirit to the present version, but may differ in detail to +address new problems or concerns. + + Each version is given a distinguishing version number. If the +Program specifies that a certain numbered version of the GNU General +Public License "or any later version" applies to it, you have the +option of following the terms and conditions either of that numbered +version or of any later version published by the Free Software +Foundation. If the Program does not specify a version number of the +GNU General Public License, you may choose any version ever published +by the Free Software Foundation. + + If the Program specifies that a proxy can decide which future +versions of the GNU General Public License can be used, that proxy's +public statement of acceptance of a version permanently authorizes you +to choose that version for the Program. + + Later license versions may give you additional or different +permissions. However, no additional obligations are imposed on any +author or copyright holder as a result of your choosing to follow a +later version. + + 15. Disclaimer of Warranty. + + THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY +APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT +HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY +OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, +THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM +IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF +ALL NECESSARY SERVICING, REPAIR OR CORRECTION. + + 16. Limitation of Liability. + + IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS +THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY +GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE +USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF +DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD +PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), +EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF +SUCH DAMAGES. + + 17. Interpretation of Sections 15 and 16. + + If the disclaimer of warranty and limitation of liability provided +above cannot be given local legal effect according to their terms, +reviewing courts shall apply local law that most closely approximates +an absolute waiver of all civil liability in connection with the +Program, unless a warranty or assumption of liability accompanies a +copy of the Program in return for a fee. + + END OF TERMS AND CONDITIONS + + How to Apply These Terms to Your New Programs + + If you develop a new program, and you want it to be of the greatest +possible use to the public, the best way to achieve this is to make it +free software which everyone can redistribute and change under these terms. + + To do so, attach the following notices to the program. It is safest +to attach them to the start of each source file to most effectively +state the exclusion of warranty; and each file should have at least +the "copyright" line and a pointer to where the full notice is found. + + + Copyright (C) + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . + +Also add information on how to contact you by electronic and paper mail. + + If the program does terminal interaction, make it output a short +notice like this when it starts in an interactive mode: + + Copyright (C) + This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'. + This is free software, and you are welcome to redistribute it + under certain conditions; type `show c' for details. + +The hypothetical commands `show w' and `show c' should show the appropriate +parts of the General Public License. Of course, your program's commands +might be different; for a GUI interface, you would use an "about box". + + You should also get your employer (if you work as a programmer) or school, +if any, to sign a "copyright disclaimer" for the program, if necessary. +For more information on this, and how to apply and follow the GNU GPL, see +. + + The GNU General Public License does not permit incorporating your program +into proprietary programs. If your program is a subroutine library, you +may consider it more useful to permit linking proprietary applications with +the library. If this is what you want to do, use the GNU Lesser General +Public License instead of this License. But first, please read +. diff --git a/build.gradle b/build.gradle index 556fe16..d3a4bc1 100644 --- a/build.gradle +++ b/build.gradle @@ -1,76 +1,1605 @@ +//version: 1704650211 /* + DO NOT CHANGE THIS FILE! + Also, you may replace this file at any time if there is an update available. + Please check https://github.com/GTNewHorizons/ExampleMod1.7.10/blob/master/build.gradle for updates. + */ + + +import com.github.jengelman.gradle.plugins.shadow.tasks.ShadowJar +import com.gtnewhorizons.retrofuturagradle.ObfuscationAttribute +import com.gtnewhorizons.retrofuturagradle.mcp.ReobfuscatedJar +import com.gtnewhorizons.retrofuturagradle.minecraft.RunMinecraftTask +import com.gtnewhorizons.retrofuturagradle.util.Distribution +import com.matthewprenger.cursegradle.CurseArtifact +import com.matthewprenger.cursegradle.CurseRelation +import com.modrinth.minotaur.dependencies.ModDependency +import com.modrinth.minotaur.dependencies.VersionDependency +import org.gradle.internal.logging.text.StyledTextOutput.Style +import org.gradle.internal.logging.text.StyledTextOutputFactory +import org.gradle.internal.xml.XmlTransformer +import org.jetbrains.gradle.ext.Application +import org.jetbrains.gradle.ext.Gradle + +import javax.inject.Inject +import java.nio.file.Files +import java.nio.file.Paths +import java.util.concurrent.TimeUnit + buildscript { repositories { - mavenCentral() maven { - name = "forge" - url = "http://files.minecraftforge.net/maven" + // GTNH RetroFuturaGradle and ASM Fork + name "GTNH Maven" + url "https://nexus.gtnewhorizons.com/repository/public/" } - maven { - name = "sonatype" - url = "https://oss.sonatype.org/content/repositories/snapshots/" + mavenLocal() + } +} +plugins { + id 'java-library' + id "org.jetbrains.gradle.plugin.idea-ext" version "1.1.7" + id 'eclipse' + id 'scala' + id 'maven-publish' + id 'org.jetbrains.kotlin.jvm' version '1.8.0' apply false + id 'org.jetbrains.kotlin.kapt' version '1.8.0' apply false + id 'com.google.devtools.ksp' version '1.8.0-1.0.9' apply false + id 'org.ajoberstar.grgit' version '4.1.1' // 4.1.1 is the last jvm8 supporting version, unused, available for addon.gradle + id 'com.github.johnrengelman.shadow' version '8.1.1' apply false + id 'com.palantir.git-version' version '3.0.0' apply false + id 'de.undercouch.download' version '5.5.0' + id 'com.github.gmazzo.buildconfig' version '3.1.0' apply false // Unused, available for addon.gradle + id 'com.diffplug.spotless' version '6.13.0' apply false // 6.13.0 is the last jvm8 supporting version + id 'com.modrinth.minotaur' version '2.+' apply false + id 'com.matthewprenger.cursegradle' version '1.4.0' apply false + id 'com.gtnewhorizons.retrofuturagradle' version '1.3.27' +} + +print("You might want to check out './gradlew :faq' if your build fails.\n") + +boolean settingsupdated = verifySettingsGradle() +settingsupdated = verifyGitAttributes() || settingsupdated +if (settingsupdated) + throw new GradleException("Settings has been updated, please re-run task.") + +// In submodules, .git is a file pointing to the real git dir +if (project.file('.git/HEAD').isFile() || project.file('.git').isFile()) { + apply plugin: 'com.palantir.git-version' +} + +def out = services.get(StyledTextOutputFactory).create('an-output') + +def projectJavaVersion = JavaLanguageVersion.of(8) + +boolean disableSpotless = project.hasProperty("disableSpotless") ? project.disableSpotless.toBoolean() : false +boolean disableCheckstyle = project.hasProperty("disableCheckstyle") ? project.disableCheckstyle.toBoolean() : false + +final String CHECKSTYLE_CONFIG = """ + + + + + + + + + + + +""" + +checkPropertyExists("modName") +checkPropertyExists("modId") +checkPropertyExists("modGroup") +checkPropertyExists("autoUpdateBuildScript") +checkPropertyExists("minecraftVersion") +checkPropertyExists("forgeVersion") +checkPropertyExists("replaceGradleTokenInFile") +checkPropertyExists("gradleTokenVersion") +checkPropertyExists("apiPackage") +checkPropertyExists("accessTransformersFile") +checkPropertyExists("usesMixins") +checkPropertyExists("mixinPlugin") +checkPropertyExists("mixinsPackage") +checkPropertyExists("coreModClass") +checkPropertyExists("containsMixinsAndOrCoreModOnly") +checkPropertyExists("usesShadowedDependencies") +checkPropertyExists("developmentEnvironmentUserName") + +propertyDefaultIfUnset("generateGradleTokenClass", "") +propertyDefaultIfUnset("includeWellKnownRepositories", true) +propertyDefaultIfUnset("noPublishedSources", false) +propertyDefaultIfUnset("usesMixinDebug", project.usesMixins) +propertyDefaultIfUnset("forceEnableMixins", false) +propertyDefaultIfUnset("channel", "stable") +propertyDefaultIfUnset("mappingsVersion", "12") +propertyDefaultIfUnset("usesMavenPublishing", true) +propertyDefaultIfUnset("mavenPublishUrl", "https://nexus.gtnewhorizons.com/repository/releases/") +propertyDefaultIfUnset("modrinthProjectId", "") +propertyDefaultIfUnset("modrinthRelations", "") +propertyDefaultIfUnset("curseForgeProjectId", "") +propertyDefaultIfUnset("curseForgeRelations", "") +propertyDefaultIfUnset("minimizeShadowedDependencies", true) +propertyDefaultIfUnset("relocateShadowedDependencies", true) +// Deprecated properties (kept for backwards compat) +propertyDefaultIfUnset("gradleTokenModId", "") +propertyDefaultIfUnset("gradleTokenModName", "") +propertyDefaultIfUnset("gradleTokenGroupName", "") + +propertyDefaultIfUnset("enableModernJavaSyntax", false) // On by default for new projects only +propertyDefaultIfUnset("enableGenericInjection", false) // On by default for new projects only + +// this is meant to be set using the user wide property file. by default we do nothing. +propertyDefaultIfUnset("ideaOverrideBuildType", "") // Can be nothing, "gradle" or "idea" + +project.extensions.add(com.diffplug.blowdryer.Blowdryer, "Blowdryer", com.diffplug.blowdryer.Blowdryer) // Make blowdryer available in "apply from:" scripts +if (!disableSpotless) { + apply plugin: 'com.diffplug.spotless' + apply from: Blowdryer.file('spotless.gradle') +} + +if (!disableCheckstyle) { + apply plugin: 'checkstyle' + tasks.named("checkstylePatchedMc") { enabled = false } + tasks.named("checkstyleMcLauncher") { enabled = false } + tasks.named("checkstyleIdeVirtualMain") { enabled = false } + tasks.named("checkstyleInjectedTags") { enabled = false } + checkstyle { + config = resources.text.fromString(CHECKSTYLE_CONFIG) + } +} + +String javaSourceDir = "src/main/java/" +String scalaSourceDir = "src/main/scala/" +String kotlinSourceDir = "src/main/kotlin/" + +if (usesShadowedDependencies.toBoolean()) { + apply plugin: "com.github.johnrengelman.shadow" +} + +java { + toolchain { + if (enableModernJavaSyntax.toBoolean()) { + languageVersion.set(JavaLanguageVersion.of(17)) + } else { + languageVersion.set(projectJavaVersion) + } + vendor.set(JvmVendorSpec.AZUL) + } + if (!noPublishedSources) { + withSourcesJar() + } +} + +tasks.withType(JavaCompile).configureEach { + options.encoding = "UTF-8" +} + +tasks.withType(ScalaCompile).configureEach { + options.encoding = "UTF-8" +} + +pluginManager.withPlugin('org.jetbrains.kotlin.jvm') { + // If Kotlin is enabled in the project + kotlin { + jvmToolchain(8) + } + // Kotlin hacks our source sets, so we hack Kotlin's tasks + def disabledKotlinTaskList = [ + "kaptGenerateStubsMcLauncherKotlin", + "kaptGenerateStubsPatchedMcKotlin", + "kaptGenerateStubsInjectedTagsKotlin", + "compileMcLauncherKotlin", + "compilePatchedMcKotlin", + "compileInjectedTagsKotlin", + "kaptMcLauncherKotlin", + "kaptPatchedMcKotlin", + "kaptInjectedTagsKotlin", + "kspMcLauncherKotlin", + "kspPatchedMcKotlin", + "kspInjectedTagsKotlin", + ] + tasks.configureEach { task -> + if (task.name in disabledKotlinTaskList) { + task.enabled = false } } +} + +configurations { + create("runtimeOnlyNonPublishable") { + description = "Runtime only dependencies that are not published alongside the jar" + canBeConsumed = false + canBeResolved = false + } + + create("devOnlyNonPublishable") { + description = "Runtime and compiletime dependencies that are not published alongside the jar (compileOnly + runtimeOnlyNonPublishable)" + canBeConsumed = false + canBeResolved = false + } + compileOnly.extendsFrom(devOnlyNonPublishable) + runtimeOnlyNonPublishable.extendsFrom(devOnlyNonPublishable) +} + +if (enableModernJavaSyntax.toBoolean()) { + repositories { + mavenCentral { + mavenContent { + includeGroup("me.eigenraven.java8unsupported") + } + } + } + dependencies { - classpath 'net.minecraftforge.gradle:ForgeGradle:2.0-SNAPSHOT' + annotationProcessor 'com.github.bsideup.jabel:jabel-javac-plugin:1.0.0' + // workaround for https://github.com/bsideup/jabel/issues/174 + annotationProcessor 'net.java.dev.jna:jna-platform:5.13.0' + compileOnly('com.github.bsideup.jabel:jabel-javac-plugin:1.0.0') { + transitive = false // We only care about the 1 annotation class + } + // Allow using jdk.unsupported classes like sun.misc.Unsafe in the compiled code, working around JDK-8206937. + patchedMinecraft('me.eigenraven.java8unsupported:java-8-unsupported-shim:1.0.0') + } + + tasks.withType(JavaCompile).configureEach { + if (it.name in ["compileMcLauncherJava", "compilePatchedMcJava"]) { + return + } + sourceCompatibility = 17 // for the IDE support + options.release.set(8) + + javaCompiler.set(javaToolchains.compilerFor { + languageVersion.set(JavaLanguageVersion.of(17)) + vendor.set(JvmVendorSpec.AZUL) + }) } } -apply plugin: 'forge' -*/ +eclipse { + classpath { + downloadSources = true + downloadJavadoc = true + } +} -plugins { - id "net.minecraftforge.gradle.forge" version "2.0.2" +final String modGroupPath = modGroup.toString().replace('.' as char, '/' as char) +final String apiPackagePath = apiPackage.toString().replace('.' as char, '/' as char) + +String targetPackageJava = javaSourceDir + modGroupPath +String targetPackageScala = scalaSourceDir + modGroupPath +String targetPackageKotlin = kotlinSourceDir + modGroupPath +if (!(getFile(targetPackageJava).exists() || getFile(targetPackageScala).exists() || getFile(targetPackageKotlin).exists())) { + throw new GradleException("Could not resolve \"modGroup\"! Could not find " + targetPackageJava + " or " + targetPackageScala + " or " + targetPackageKotlin) +} + +if (apiPackage) { + targetPackageJava = javaSourceDir + modGroupPath + "/" + apiPackagePath + targetPackageScala = scalaSourceDir + modGroupPath + "/" + apiPackagePath + targetPackageKotlin = kotlinSourceDir + modGroupPath + "/" + apiPackagePath + if (!(getFile(targetPackageJava).exists() || getFile(targetPackageScala).exists() || getFile(targetPackageKotlin).exists())) { + throw new GradleException("Could not resolve \"apiPackage\"! Could not find " + targetPackageJava + " or " + targetPackageScala + " or " + targetPackageKotlin) + } +} + +if (accessTransformersFile) { + for (atFile in accessTransformersFile.split(" ")) { + String targetFile = "src/main/resources/META-INF/" + atFile.trim() + if (!getFile(targetFile).exists()) { + throw new GradleException("Could not resolve \"accessTransformersFile\"! Could not find " + targetFile) + } + tasks.deobfuscateMergedJarToSrg.accessTransformerFiles.from(targetFile) + tasks.srgifyBinpatchedJar.accessTransformerFiles.from(targetFile) + } +} else { + boolean atsFound = false + for (File at : sourceSets.getByName("main").resources.files) { + if (at.name.toLowerCase().endsWith("_at.cfg")) { + atsFound = true + tasks.deobfuscateMergedJarToSrg.accessTransformerFiles.from(at) + tasks.srgifyBinpatchedJar.accessTransformerFiles.from(at) + } + } + for (File at : sourceSets.getByName("api").resources.files) { + if (at.name.toLowerCase().endsWith("_at.cfg")) { + atsFound = true + tasks.deobfuscateMergedJarToSrg.accessTransformerFiles.from(at) + tasks.srgifyBinpatchedJar.accessTransformerFiles.from(at) + } + } + if (atsFound) { + logger.warn("Found and added access transformers in the resources folder, please configure gradle.properties to explicitly mention them by name") + } +} + +if (usesMixins.toBoolean()) { + if (mixinsPackage.isEmpty()) { + throw new GradleException("\"usesMixins\" requires \"mixinsPackage\" to be set!") + } + final String mixinPackagePath = mixinsPackage.toString().replaceAll("\\.", "/") + final String mixinPluginPath = mixinPlugin.toString().replaceAll("\\.", "/") + + targetPackageJava = javaSourceDir + modGroupPath + "/" + mixinPackagePath + targetPackageScala = scalaSourceDir + modGroupPath + "/" + mixinPackagePath + targetPackageKotlin = kotlinSourceDir + modGroupPath + "/" + mixinPackagePath + if (!(getFile(targetPackageJava).exists() || getFile(targetPackageScala).exists() || getFile(targetPackageKotlin).exists())) { + throw new GradleException("Could not resolve \"mixinsPackage\"! Could not find " + targetPackageJava + " or " + targetPackageScala + " or " + targetPackageKotlin) + } + + if (!mixinPlugin.isEmpty()) { + String targetFileJava = javaSourceDir + modGroupPath + "/" + mixinPluginPath + ".java" + String targetFileScala = scalaSourceDir + modGroupPath + "/" + mixinPluginPath + ".scala" + String targetFileScalaJava = scalaSourceDir + modGroupPath + "/" + mixinPluginPath + ".java" + String targetFileKotlin = kotlinSourceDir + modGroupPath + "/" + mixinPluginPath + ".kt" + if (!(getFile(targetFileJava).exists() || getFile(targetFileScala).exists() || getFile(targetFileScalaJava).exists() || getFile(targetFileKotlin).exists())) { + throw new GradleException("Could not resolve \"mixinPlugin\"! Could not find " + targetFileJava + " or " + targetFileScala + " or " + targetFileScalaJava + " or " + targetFileKotlin) + } + } +} + +if (coreModClass) { + final String coreModPath = coreModClass.toString().replaceAll("\\.", "/") + String targetFileJava = javaSourceDir + modGroupPath + "/" + coreModPath + ".java" + String targetFileScala = scalaSourceDir + modGroupPath + "/" + coreModPath + ".scala" + String targetFileScalaJava = scalaSourceDir + modGroupPath + "/" + coreModPath + ".java" + String targetFileKotlin = kotlinSourceDir + modGroupPath + "/" + coreModPath + ".kt" + if (!(getFile(targetFileJava).exists() || getFile(targetFileScala).exists() || getFile(targetFileScalaJava).exists() || getFile(targetFileKotlin).exists())) { + throw new GradleException("Could not resolve \"coreModClass\"! Could not find " + targetFileJava + " or " + targetFileScala + " or " + targetFileScalaJava + " or " + targetFileKotlin) + } +} + +configurations.configureEach { + resolutionStrategy.cacheChangingModulesFor(0, TimeUnit.SECONDS) + + // Make sure GregTech build won't time out + System.setProperty("org.gradle.internal.http.connectionTimeout", 120000 as String) + System.setProperty("org.gradle.internal.http.socketTimeout", 120000 as String) +} + +// Fix Jenkins' Git: chmod a file should not be detected as a change and append a '.dirty' to the version +try { + 'git config core.fileMode false'.execute() +} +catch (Exception ignored) { + out.style(Style.Failure).println("git isn't installed at all") +} + +// Pulls version first from the VERSION env and then git tag +String identifiedVersion +String versionOverride = System.getenv("VERSION") ?: null +try { + // Produce a version based on the tag, or for branches something like 0.2.2-configurable-maven-and-extras.38+43090270b6-dirty + if (versionOverride == null) { + def gitDetails = versionDetails() + def isDirty = gitVersion().endsWith(".dirty") // No public API for this, isCleanTag has a different meaning + String branchName = gitDetails.branchName ?: (System.getenv('GIT_BRANCH') ?: 'git') + if (branchName.startsWith('origin/')) { + branchName = branchName.minus('origin/') + } + branchName = branchName.replaceAll("[^a-zA-Z0-9-]+", "-") // sanitize branch names for semver + identifiedVersion = gitDetails.lastTag ?: '${gitDetails.gitHash}' + if (gitDetails.commitDistance > 0) { + identifiedVersion += "-${branchName}.${gitDetails.commitDistance}+${gitDetails.gitHash}" + if (isDirty) { + identifiedVersion += "-dirty" + } + } else if (isDirty) { + identifiedVersion += "-${branchName}+${gitDetails.gitHash}-dirty" + } + } else { + identifiedVersion = versionOverride + } +} +catch (Exception ignored) { + out.style(Style.Failure).text( + 'This mod must be version controlled by Git AND the repository must provide at least one tag,\n' + + 'or the VERSION override must be set! ').style(Style.SuccessHeader).text('(Do NOT download from GitHub using the ZIP option, instead\n' + + 'clone the repository, see ').style(Style.Info).text('https://gtnh.miraheze.org/wiki/Development').style(Style.SuccessHeader).println(' for details.)' + ) + versionOverride = 'NO-GIT-TAG-SET' + identifiedVersion = versionOverride +} +version = identifiedVersion +ext { + modVersion = identifiedVersion +} + +if (identifiedVersion == versionOverride) { + out.style(Style.Failure).text('Override version to ').style(Style.Identifier).text(modVersion).style(Style.Failure).println('!\7') +} + +group = "com.github.GTNewHorizons" +if (project.hasProperty("customArchiveBaseName") && customArchiveBaseName) { + base { + archivesName = customArchiveBaseName + } +} else { + base { + archivesName = modId + } } -version = "v6-1.8" -group= "com.yyon.grapplemod" // http://maven.apache.org/guides/mini/guide-naming-conventions.html -archivesBaseName = "grapplemod" minecraft { - version = "1.8-11.14.4.1563" // "1.8.8-11.15.0.1623" - runDir = "eclipse" - - // the mappings can be changed at any time, and must be in the following format. - // snapshot_YYYYMMDD snapshot are built nightly. - // stable_# stables are built at the discretion of the MCP team. - // Use non-default mappings at your own risk. they may not allways work. - // simply re-run your setup task after changing the mappings to update your workspace. - mappings = "snapshot_20141130" + if (replaceGradleTokenInFile) { + for (f in replaceGradleTokenInFile.split(',')) { + tagReplacementFiles.add f + } + } + if (gradleTokenModId) { + injectedTags.put gradleTokenModId, modId + } + if (gradleTokenModName) { + injectedTags.put gradleTokenModName, modName + } + if (gradleTokenVersion) { + injectedTags.put gradleTokenVersion, modVersion + } + if (gradleTokenGroupName) { + injectedTags.put gradleTokenGroupName, modGroup + } + if (enableGenericInjection.toBoolean()) { + injectMissingGenerics.set(true) + } + + username = developmentEnvironmentUserName.toString() + + lwjgl3Version = "3.3.2" + + // Enable assertions in the current mod + extraRunJvmArguments.add("-ea:${modGroup}") + + if (usesMixins.toBoolean() || forceEnableMixins.toBoolean()) { + if (usesMixinDebug.toBoolean()) { + extraRunJvmArguments.addAll([ + "-Dmixin.debug.countInjections=true", + "-Dmixin.debug.verbose=true", + "-Dmixin.debug.export=true" + ]) + } + } + + // Blowdryer is present in some old mod builds, do not propagate it further as a dependency + // IC2 has no reobf jars in its Maven + groupsToExcludeFromAutoReobfMapping.addAll(["com.diffplug", "com.diffplug.durian", "net.industrial-craft"]) +} + +if (generateGradleTokenClass) { + tasks.injectTags.outputClassName.set(generateGradleTokenClass) +} + +// Custom reobf auto-mappings +configurations.configureEach { + dependencies.configureEach { dep -> + if (dep instanceof org.gradle.api.artifacts.ExternalModuleDependency) { + if (dep.group == "net.industrial-craft" && dep.name == "industrialcraft-2") { + // https://www.curseforge.com/minecraft/mc-mods/industrial-craft/files/2353971 + project.dependencies.reobfJarConfiguration("curse.maven:ic2-242638:2353971") + } + } + } + def obfuscationAttr = it.attributes.getAttribute(ObfuscationAttribute.OBFUSCATION_ATTRIBUTE) + if (obfuscationAttr != null && obfuscationAttr.name == ObfuscationAttribute.SRG) { + resolutionStrategy.eachDependency { DependencyResolveDetails details -> + // Remap CoFH core cursemaven dev jar to the obfuscated version for runObfClient/Server + if (details.requested.group == 'curse.maven' && details.requested.name.endsWith('-69162') && details.requested.version == '2388751') { + details.useVersion '2388750' + details.because 'Pick obfuscated jar' + } + } + } +} + +// Ensure tests have access to minecraft classes +sourceSets { + test { + java { + compileClasspath += sourceSets.patchedMc.output + sourceSets.mcLauncher.output + runtimeClasspath += sourceSets.patchedMc.output + sourceSets.mcLauncher.output + } + } +} + +if (file('addon.gradle.kts').exists()) { + apply from: 'addon.gradle.kts' +} else if (file('addon.gradle').exists()) { + apply from: 'addon.gradle' +} + +// File for local tweaks not commited to Git +if (file('addon.local.gradle.kts').exists()) { + apply from: 'addon.local.gradle.kts' +} else if (file('addon.local.gradle').exists()) { + apply from: 'addon.local.gradle' +} + +// Allow unsafe repos but warn +repositories.configureEach { repo -> + if (repo instanceof org.gradle.api.artifacts.repositories.UrlArtifactRepository) { + if (repo.getUrl() != null && repo.getUrl().getScheme() == "http" && !repo.allowInsecureProtocol) { + logger.warn("Deprecated: Allowing insecure connections for repo '${repo.name}' - add 'allowInsecureProtocol = true'") + repo.allowInsecureProtocol = true + } + } +} + +if (file('repositories.gradle.kts').exists()) { + apply from: 'repositories.gradle.kts' +} else if (file('repositories.gradle').exists()) { + apply from: 'repositories.gradle' +} else { + logger.error("Neither repositories.gradle.kts nor repositories.gradle was found, make sure you extracted the full ExampleMod template.") + throw new RuntimeException("Missing repositories.gradle[.kts]") +} + +configurations { + runtimeClasspath.extendsFrom(runtimeOnlyNonPublishable) + testRuntimeClasspath.extendsFrom(runtimeOnlyNonPublishable) + for (config in [compileClasspath, runtimeClasspath, testCompileClasspath, testRuntimeClasspath]) { + if (usesShadowedDependencies.toBoolean()) { + config.extendsFrom(shadowImplementation) + // TODO: remove Compile after all uses are refactored to Implementation + config.extendsFrom(shadeCompile) + config.extendsFrom(shadowCompile) + } + } + // A "bag-of-dependencies"-style configuration for backwards compatibility, gets put in "api" + create("compile") { + description = "Deprecated: use api or implementation instead, gets put in api" + canBeConsumed = false + canBeResolved = false + visible = false + } + create("testCompile") { + description = "Deprecated: use testImplementation instead" + canBeConsumed = false + canBeResolved = false + visible = false + } + api.extendsFrom(compile) + testImplementation.extendsFrom(testCompile) } +afterEvaluate { + if (!configurations.compile.allDependencies.empty || !configurations.testCompile.allDependencies.empty) { + logger.warn("This project uses deprecated `compile` dependencies, please migrate to using `api` and `implementation`") + logger.warn("For more details, see https://github.com/GTNewHorizons/ExampleMod1.7.10/blob/master/dependencies.gradle") + } +} + +repositories { + maven { + name = "GTNH Maven" + url = "https://nexus.gtnewhorizons.com/repository/public/" + // Links for convenience: + // Simple HTML browsing: https://nexus.gtnewhorizons.com/service/rest/repository/browse/releases/ + // Rich web UI browsing: https://nexus.gtnewhorizons.com/#browse/browse:releases + } + maven { + name 'Overmind forge repo mirror' + url 'https://gregtech.overminddl1.com/' + } + maven { + name 'sonatype' + url 'https://oss.sonatype.org/content/repositories/snapshots/' + content { + includeGroup "org.lwjgl" + } + } + if (includeWellKnownRepositories.toBoolean()) { + exclusiveContent { + forRepository { + maven { + name "CurseMaven" + url "https://cursemaven.com" + } + } + filter { + includeGroup "curse.maven" + } + } + exclusiveContent { + forRepository { + maven { + name = "Modrinth" + url = "https://api.modrinth.com/maven" + } + } + filter { + includeGroup "maven.modrinth" + } + } + maven { + name = "ic2" + url = getURL("https://maven2.ic2.player.to/", "https://maven.ic2.player.to/") + content { + includeGroup "net.industrial-craft" + } + metadataSources { + mavenPom() + artifact() + } + } + maven { + name "MMD Maven" + url "https://maven.mcmoddev.com/" + } + } +} + +def mixinProviderGroup = "io.github.legacymoddingmc" +def mixinProviderModule = "unimixins" +def mixinProviderVersion = "0.1.13" +def mixinProviderSpecNoClassifer = "${mixinProviderGroup}:${mixinProviderModule}:${mixinProviderVersion}" +def mixinProviderSpec = "${mixinProviderSpecNoClassifer}:dev" +ext.mixinProviderSpec = mixinProviderSpec + +def mixingConfigRefMap = 'mixins.' + modId + '.refmap.json' + dependencies { - // you may put jars on which you depend on in ./libs - // or you may define them like so.. - //compile "some.group:artifact:version:classifier" - //compile "some.group:artifact:version" - - // real examples - //compile 'com.mod-buildcraft:buildcraft:6.0.8:dev' // adds buildcraft to the dev env - //compile 'com.googlecode.efficient-java-matrix-library:ejml:0.24' // adds ejml to the dev env + if (usesMixins.toBoolean()) { + annotationProcessor('org.ow2.asm:asm-debug-all:5.0.3') + annotationProcessor('com.google.guava:guava:24.1.1-jre') + annotationProcessor('com.google.code.gson:gson:2.8.6') + annotationProcessor(mixinProviderSpec) + if (usesMixinDebug.toBoolean()) { + runtimeOnlyNonPublishable('org.jetbrains:intellij-fernflower:1.2.1.16') + } + } + if (usesMixins.toBoolean()) { + implementation(modUtils.enableMixins(mixinProviderSpec, mixingConfigRefMap)) + } else if (forceEnableMixins.toBoolean()) { + runtimeOnlyNonPublishable(mixinProviderSpec) + } +} + +pluginManager.withPlugin('org.jetbrains.kotlin.kapt') { + if (usesMixins.toBoolean()) { + dependencies { + kapt(mixinProviderSpec) + } + } +} - // for more info... - // http://www.gradle.org/docs/current/userguide/artifact_dependencies_tutorial.html - // http://www.gradle.org/docs/current/userguide/dependency_management.html +// Replace old mixin mods with unimixins +// https://docs.gradle.org/8.0.2/userguide/resolution_rules.html#sec:substitution_with_classifier +configurations.all { + resolutionStrategy.dependencySubstitution { + substitute module('com.gtnewhorizon:gtnhmixins') using module(mixinProviderSpecNoClassifer) withClassifier("dev") because("Unimixins replaces other mixin mods") + substitute module('com.github.GTNewHorizons:Mixingasm') using module(mixinProviderSpecNoClassifer) withClassifier("dev") because("Unimixins replaces other mixin mods") + substitute module('com.github.GTNewHorizons:SpongePoweredMixin') using module(mixinProviderSpecNoClassifer) withClassifier("dev") because("Unimixins replaces other mixin mods") + substitute module('com.github.GTNewHorizons:SpongeMixins') using module(mixinProviderSpecNoClassifer) withClassifier("dev") because("Unimixins replaces other mixin mods") + substitute module('io.github.legacymoddingmc:unimixins') using module(mixinProviderSpecNoClassifer) withClassifier("dev") because("Our previous unimixins upload was missing the dev classifier") + + substitute module('org.scala-lang:scala-library:2.11.1') using module('org.scala-lang:scala-library:2.11.5') because('To allow mixing with Java 8 targets') + } +} + +dependencies { + constraints { + def minGtnhLibVersion = "0.0.13" + implementation("com.github.GTNewHorizons:GTNHLib:${minGtnhLibVersion}") { + because("fixes duplicate mod errors in java 17 configurations using old gtnhlib") + } + runtimeOnly("com.github.GTNewHorizons:GTNHLib:${minGtnhLibVersion}") { + because("fixes duplicate mod errors in java 17 configurations using old gtnhlib") + } + devOnlyNonPublishable("com.github.GTNewHorizons:GTNHLib:${minGtnhLibVersion}") { + because("fixes duplicate mod errors in java 17 configurations using old gtnhlib") + } + runtimeOnlyNonPublishable("com.github.GTNewHorizons:GTNHLib:${minGtnhLibVersion}") { + because("fixes duplicate mod errors in java 17 configurations using old gtnhlib") + } + } +} +if (file('dependencies.gradle.kts').exists()) { + apply from: 'dependencies.gradle.kts' +} else if (file('dependencies.gradle').exists()) { + apply from: 'dependencies.gradle' +} else { + logger.error("Neither dependencies.gradle.kts nor dependencies.gradle was found, make sure you extracted the full ExampleMod template.") + throw new RuntimeException("Missing dependencies.gradle[.kts]") } -processResources -{ +tasks.register('generateAssets') { + group = "GTNH Buildscript" + description = "Generates a mixin config file at /src/main/resources/mixins.modid.json if needed" + onlyIf { usesMixins.toBoolean() } + doLast { + def mixinConfigFile = getFile("/src/main/resources/mixins." + modId + ".json") + if (!mixinConfigFile.exists()) { + def mixinPluginLine = "" + if (!mixinPlugin.isEmpty()) { + // We might not have a mixin plugin if we're using early/late mixins + mixinPluginLine += """\n "plugin": "${modGroup}.${mixinPlugin}", """ + } + + mixinConfigFile.text = """{ + "required": true, + "minVersion": "0.8.5-GTNH", + "package": "${modGroup}.${mixinsPackage}",${mixinPluginLine} + "refmap": "${mixingConfigRefMap}", + "target": "@env(DEFAULT)", + "compatibilityLevel": "JAVA_8", + "mixins": [], + "client": [], + "server": [] +} +""" + } + } +} + +if (usesMixins.toBoolean()) { + tasks.named("processResources").configure { + dependsOn("generateAssets") + } + + tasks.named("compileJava", JavaCompile).configure { + options.compilerArgs += [ + // Elan: from what I understand they are just some linter configs so you get some warning on how to properly code + "-XDenableSunApiLintControl", + "-XDignore.symbol.file" + ] + } +} + +tasks.named("processResources", ProcessResources).configure { // this will ensure that this task is redone when the versions change. inputs.property "version", project.version - inputs.property "mcversion", project.minecraft.version + inputs.property "mcversion", project.minecraft.mcVersion + exclude("spotless.gradle") - // replace stuff in mcmod.info, nothing else - from(sourceSets.main.resources.srcDirs) { - include 'mcmod.info' - - // replace version and mcversion - expand 'version':project.version, 'mcversion':project.minecraft.version + // replace stuff in mcmod.info, nothing else. replaces ${key} with value in text + filesMatching("mcmod.info") { + expand "minecraftVersion": project.minecraft.mcVersion, + "modVersion": modVersion, + "modId": modId, + "modName": modName + } + + if (usesMixins.toBoolean()) { + dependsOn("compileJava", "compileScala") + } +} + +ext.java17Toolchain = (JavaToolchainSpec spec) -> { + spec.languageVersion.set(JavaLanguageVersion.of(17)) + spec.vendor.set(JvmVendorSpec.matching("jetbrains")) +} + +ext.java17DependenciesCfg = configurations.create("java17Dependencies") { + extendsFrom(configurations.getByName("runtimeClasspath")) // Ensure consistent transitive dependency resolution + canBeConsumed = false +} +ext.java17PatchDependenciesCfg = configurations.create("java17PatchDependencies") { + canBeConsumed = false +} + +dependencies { + def lwjgl3ifyVersion = '1.5.7' + if (modId != 'lwjgl3ify') { + java17Dependencies("com.github.GTNewHorizons:lwjgl3ify:${lwjgl3ifyVersion}") + } + if (modId != 'hodgepodge') { + java17Dependencies('com.github.GTNewHorizons:Hodgepodge:2.4.4') + } + + java17PatchDependencies("com.github.GTNewHorizons:lwjgl3ify:${lwjgl3ifyVersion}:forgePatches") {transitive = false} +} + +ext.java17JvmArgs = [ + // Java 9+ support + "--illegal-access=warn", + "-Djava.security.manager=allow", + "-Dfile.encoding=UTF-8", + "--add-opens", "java.base/jdk.internal.loader=ALL-UNNAMED", + "--add-opens", "java.base/java.net=ALL-UNNAMED", + "--add-opens", "java.base/java.nio=ALL-UNNAMED", + "--add-opens", "java.base/java.io=ALL-UNNAMED", + "--add-opens", "java.base/java.lang=ALL-UNNAMED", + "--add-opens", "java.base/java.lang.reflect=ALL-UNNAMED", + "--add-opens", "java.base/java.text=ALL-UNNAMED", + "--add-opens", "java.base/java.util=ALL-UNNAMED", + "--add-opens", "java.base/jdk.internal.reflect=ALL-UNNAMED", + "--add-opens", "java.base/sun.nio.ch=ALL-UNNAMED", + "--add-opens", "jdk.naming.dns/com.sun.jndi.dns=ALL-UNNAMED,java.naming", + "--add-opens", "java.desktop/sun.awt.image=ALL-UNNAMED", + "--add-modules", "jdk.dynalink", + "--add-opens", "jdk.dynalink/jdk.dynalink.beans=ALL-UNNAMED", + "--add-modules", "java.sql.rowset", + "--add-opens", "java.sql.rowset/javax.sql.rowset.serial=ALL-UNNAMED" +] + +ext.hotswapJvmArgs = [ + // DCEVM advanced hot reload + "-XX:+AllowEnhancedClassRedefinition", + "-XX:HotswapAgent=fatjar" +] + +ext.setupHotswapAgentTask = tasks.register("setupHotswapAgent") { + group = "GTNH Buildscript" + description = "Installs a recent version of HotSwapAgent into the Java 17 JetBrains runtime directory" + def hsaUrl = 'https://github.com/HotswapProjects/HotswapAgent/releases/download/1.4.2-SNAPSHOT/hotswap-agent-1.4.2-SNAPSHOT.jar' + def targetFolderProvider = javaToolchains.launcherFor(java17Toolchain).map {it.metadata.installationPath.dir("lib/hotswap")} + def targetFilename = "hotswap-agent.jar" + onlyIf { + !targetFolderProvider.get().file(targetFilename).asFile.exists() + } + doLast { + def targetFolder = targetFolderProvider.get() + targetFolder.asFile.mkdirs() + download.run { + src hsaUrl + dest targetFolder.file(targetFilename).asFile + overwrite false + tempAndMove true + } + } +} + +public abstract class RunHotswappableMinecraftTask extends RunMinecraftTask { + // IntelliJ doesn't seem to allow commandline arguments so we also support an env variable + private boolean enableHotswap = Boolean.valueOf(System.getenv("HOTSWAP")); + + @Input + public boolean getEnableHotswap() { return enableHotswap } + @Option(option = "hotswap", description = "Enables HotSwapAgent for enhanced class reloading under a debugger") + public boolean setEnableHotswap(boolean enable) { enableHotswap = enable } + + @Inject + public RunHotswappableMinecraftTask(Distribution side, String superTask, org.gradle.api.invocation.Gradle gradle) { + super(side, gradle) + + this.lwjglVersion = 3 + this.javaLauncher = project.javaToolchains.launcherFor(project.java17Toolchain) + this.extraJvmArgs.addAll(project.java17JvmArgs) + this.extraJvmArgs.addAll(project.provider(() -> enableHotswap ? project.hotswapJvmArgs : [])) + + this.classpath(project.java17PatchDependenciesCfg) + if (side == Distribution.CLIENT) { + this.classpath(project.minecraftTasks.lwjgl3Configuration) + } + // Use a raw provider instead of map to not create a dependency on the task + this.classpath(project.provider(() -> project.tasks.named(superTask, RunMinecraftTask).get().classpath)) + this.classpath.filter { file -> + !file.path.contains("2.9.4-nightly-20150209") // Remove lwjgl2 + } + this.classpath(project.java17DependenciesCfg) + } + + public void setup(Project project) { + super.setup(project) + if (project.usesMixins.toBoolean()) { + this.extraJvmArgs.addAll(project.provider(() -> { + def mixinCfg = project.configurations.detachedConfiguration(project.dependencies.create(project.mixinProviderSpec)) + mixinCfg.canBeConsumed = false + mixinCfg.transitive = false + enableHotswap ? ["-javaagent:" + mixinCfg.singleFile.absolutePath] : [] + })) + } + } +} + +def runClient17Task = tasks.register("runClient17", RunHotswappableMinecraftTask, Distribution.CLIENT, "runClient") +runClient17Task.configure { + setup(project) + group = "Modded Minecraft" + description = "Runs the modded client using Java 17, lwjgl3ify and Hodgepodge" + dependsOn(setupHotswapAgentTask, mcpTasks.launcherSources.classesTaskName, minecraftTasks.taskDownloadVanillaAssets, mcpTasks.taskPackagePatchedMc, 'jar') + mainClass = "GradleStart" + username = minecraft.username + userUUID = minecraft.userUUID +} + +def runServer17Task = tasks.register("runServer17", RunHotswappableMinecraftTask, Distribution.DEDICATED_SERVER, "runServer") +runServer17Task.configure { + setup(project) + group = "Modded Minecraft" + description = "Runs the modded server using Java 17, lwjgl3ify and Hodgepodge" + dependsOn(setupHotswapAgentTask, mcpTasks.launcherSources.classesTaskName, minecraftTasks.taskDownloadVanillaAssets, mcpTasks.taskPackagePatchedMc, 'jar') + mainClass = "GradleStartServer" + extraArgs.add("nogui") +} + +def getManifestAttributes() { + def manifestAttributes = [:] + if (!containsMixinsAndOrCoreModOnly.toBoolean() && (usesMixins.toBoolean() || coreModClass)) { + manifestAttributes += ["FMLCorePluginContainsFMLMod": true] } - - // copy everything else, thats not the mcmod.info + + if (accessTransformersFile) { + manifestAttributes += ["FMLAT": accessTransformersFile.toString()] + } + + if (coreModClass) { + manifestAttributes += ["FMLCorePlugin": modGroup + "." + coreModClass] + } + + if (usesMixins.toBoolean()) { + manifestAttributes += [ + "TweakClass" : "org.spongepowered.asm.launch.MixinTweaker", + "MixinConfigs" : "mixins." + modId + ".json", + "ForceLoadAsMod": !containsMixinsAndOrCoreModOnly.toBoolean() + ] + } + return manifestAttributes +} + +tasks.named("jar", Jar).configure { + manifest { + attributes(getManifestAttributes()) + } +} + +if (usesShadowedDependencies.toBoolean()) { + tasks.named("shadowJar", ShadowJar).configure { + manifest { + attributes(getManifestAttributes()) + } + + if (minimizeShadowedDependencies.toBoolean()) { + minimize() // This will only allow shading for actually used classes + } + configurations = [ + project.configurations.shadowImplementation, + project.configurations.shadowCompile, + project.configurations.shadeCompile + ] + archiveClassifier.set('dev') + if (relocateShadowedDependencies.toBoolean()) { + relocationPrefix = modGroup + ".shadow" + enableRelocation = true + } + } + configurations.runtimeElements.outgoing.artifacts.clear() + configurations.apiElements.outgoing.artifacts.clear() + configurations.runtimeElements.outgoing.artifact(tasks.named("shadowJar", ShadowJar)) + configurations.apiElements.outgoing.artifact(tasks.named("shadowJar", ShadowJar)) + tasks.named("jar", Jar) { + archiveClassifier.set('dev-preshadow') + } + tasks.named("reobfJar", ReobfuscatedJar) { + inputJar.set(tasks.named("shadowJar", ShadowJar).flatMap({it.archiveFile})) + } + AdhocComponentWithVariants javaComponent = (AdhocComponentWithVariants) project.components.findByName("java") + javaComponent.withVariantsFromConfiguration(configurations.shadowRuntimeElements) { + skip() + } +} +ext.publishableDevJar = usesShadowedDependencies.toBoolean() ? tasks.shadowJar : tasks.jar +ext.publishableObfJar = tasks.reobfJar + +tasks.register('apiJar', Jar) { + from(sourceSets.main.allSource) { + include modGroupPath + "/" + apiPackagePath + '/**' + } + + from(sourceSets.main.output) { + include modGroupPath + "/" + apiPackagePath + '/**' + } + from(sourceSets.main.resources.srcDirs) { - exclude 'mcmod.info' + include("LICENSE") + } + + getArchiveClassifier().set('api') +} + +artifacts { + if (!noPublishedSources) { + archives tasks.named("sourcesJar") + } + if (apiPackage) { + archives tasks.named("apiJar") + } +} + +idea { + module { + downloadJavadoc = true + downloadSources = true + inheritOutputDirs = true + } + project { + settings { + if (ideaOverrideBuildType != "") { + delegateActions { + if ("gradle".equalsIgnoreCase(ideaOverrideBuildType)) { + delegateBuildRunToGradle = true + testRunner = org.jetbrains.gradle.ext.ActionDelegationConfig.TestRunner.GRADLE + } else if ("idea".equalsIgnoreCase(ideaOverrideBuildType)) { + delegateBuildRunToGradle = false + testRunner = org.jetbrains.gradle.ext.ActionDelegationConfig.TestRunner.PLATFORM + } else { + throw GradleScriptException('Accepted value for ideaOverrideBuildType is one of gradle or idea.') + } + } + } + runConfigurations { + "0. Build and Test"(Gradle) { + taskNames = ["build"] + } + "1. Run Client"(Gradle) { + taskNames = ["runClient"] + } + "2. Run Server"(Gradle) { + taskNames = ["runServer"] + } + "1a. Run Client (Java 17)"(Gradle) { + taskNames = ["runClient17"] + } + "2a. Run Server (Java 17)"(Gradle) { + taskNames = ["runServer17"] + } + "1b. Run Client (Java 17, Hotswap)"(Gradle) { + taskNames = ["runClient17"] + envs = ["HOTSWAP": "true"] + } + "2b. Run Server (Java 17, Hotswap)"(Gradle) { + taskNames = ["runServer17"] + envs = ["HOTSWAP": "true"] + } + "3. Run Obfuscated Client"(Gradle) { + taskNames = ["runObfClient"] + } + "4. Run Obfuscated Server"(Gradle) { + taskNames = ["runObfServer"] + } + if (!disableSpotless) { + "5. Apply spotless"(Gradle) { + taskNames = ["spotlessApply"] + } + } + def coreModArgs = "" + if (coreModClass) { + coreModArgs = ' "-Dfml.coreMods.load=' + modGroup + '.' + coreModClass + '"' + } + "Run Client (IJ Native)"(Application) { + mainClass = "GradleStart" + moduleName = project.name + ".ideVirtualMain" + afterEvaluate { + workingDirectory = tasks.runClient.workingDir.absolutePath + programParameters = tasks.runClient.calculateArgs(project).collect { '"' + it + '"' }.join(' ') + jvmArgs = tasks.runClient.calculateJvmArgs(project).collect { '"' + it + '"' }.join(' ') + + ' ' + tasks.runClient.systemProperties.collect { '"-D' + it.key + '=' + it.value.toString() + '"' }.join(' ') + + coreModArgs + } + } + "Run Server (IJ Native)"(Application) { + mainClass = "GradleStartServer" + moduleName = project.name + ".ideVirtualMain" + afterEvaluate { + workingDirectory = tasks.runServer.workingDir.absolutePath + programParameters = tasks.runServer.calculateArgs(project).collect { '"' + it + '"' }.join(' ') + jvmArgs = tasks.runServer.calculateJvmArgs(project).collect { '"' + it + '"' }.join(' ') + + ' ' + tasks.runServer.systemProperties.collect { '"-D' + it.key + '=' + it.value.toString() + '"' }.join(' ') + + coreModArgs + } + } + } + compiler.javac { + afterEvaluate { + javacAdditionalOptions = "-encoding utf8" + moduleJavacAdditionalOptions = [ + (project.name + ".main"): tasks.compileJava.options.compilerArgs.collect { '"' + it + '"' }.join(' ') + ] + } + } + withIDEADir { File ideaDir -> + if (!ideaDir.path.contains(".idea")) { + // If an .ipr file exists, the project root directory is passed here instead of the .idea subdirectory + ideaDir = new File(ideaDir, ".idea") + } + if (ideaDir.isDirectory()) { + def miscFile = new File(ideaDir, "misc.xml") + if (miscFile.isFile()) { + boolean dirty = false + def miscTransformer = new XmlTransformer() + miscTransformer.addAction { root -> + Node rootNode = root.asNode() + def rootManager = rootNode + .component.find { it.@name == 'ProjectRootManager' } + if (!rootManager) { + rootManager = rootNode.appendNode('component', ['name': 'ProjectRootManager', 'version': '2']) + dirty = true + } + def output = rootManager.output + if (!output) { + output = rootManager.appendNode('output') + dirty = true + } + if (!output.@url) { + // Only modify the output url if it doesn't yet have one, or if the existing one is blank somehow. + // This is a sensible default for most setups + output.@url = 'file://$PROJECT_DIR$/build/ideaBuild' + dirty = true + } + } + def result = miscTransformer.transform(miscFile.text) + if (dirty) { + miscFile.write(result) + } + } else { + miscFile.text = """ + + + + + +""" + } + } + } + } + } +} + +tasks.named("processIdeaSettings").configure { + dependsOn("injectTags") +} + +tasks.named("ideVirtualMainClasses").configure { + // Make IntelliJ "Build project" build the mod jars + dependsOn("jar", "reobfJar") + if (!disableSpotless) { + dependsOn("spotlessCheck") + } +} + +// workaround variable hiding in pom processing +def projectConfigs = project.configurations + +publishing { + publications { + create("maven", MavenPublication) { + from components.java + + if (apiPackage) { + artifact apiJar + } + + groupId = System.getenv("ARTIFACT_GROUP_ID") ?: project.group + artifactId = System.getenv("ARTIFACT_ID") ?: project.name + // Using the identified version, not project.version as it has the prepended 1.7.10 + version = System.getenv("RELEASE_VERSION") ?: identifiedVersion + } + } + repositories { + if (usesMavenPublishing.toBoolean() && System.getenv("MAVEN_USER") != null) { + maven { + url = mavenPublishUrl + allowInsecureProtocol = mavenPublishUrl.startsWith("http://") + credentials { + username = System.getenv("MAVEN_USER") ?: "NONE" + password = System.getenv("MAVEN_PASSWORD") ?: "NONE" + } + } + } + } +} + +if (modrinthProjectId.size() != 0 && System.getenv("MODRINTH_TOKEN") != null) { + apply plugin: 'com.modrinth.minotaur' + + File changelogFile = new File(System.getenv("CHANGELOG_FILE") ?: "CHANGELOG.md") + + modrinth { + token = System.getenv("MODRINTH_TOKEN") + projectId = modrinthProjectId + versionNumber = identifiedVersion + versionType = identifiedVersion.endsWith("-pre") ? "beta" : "release" + changelog = changelogFile.exists() ? changelogFile.getText("UTF-8") : "" + uploadFile = publishableObfJar + additionalFiles = getSecondaryArtifacts() + gameVersions = [minecraftVersion] + loaders = ["forge"] + debugMode = false + } + + if (modrinthRelations.size() != 0) { + String[] deps = modrinthRelations.split(";") + deps.each { dep -> + if (dep.size() == 0) { + return + } + String[] parts = dep.split(":") + String[] qual = parts[0].split("-") + addModrinthDep(qual[0], qual[1], parts[1]) + } + } + if (usesMixins.toBoolean()) { + addModrinthDep("required", "project", "unimixins") + } + tasks.modrinth.dependsOn(build) + tasks.publish.dependsOn(tasks.modrinth) +} + +if (curseForgeProjectId.size() != 0 && System.getenv("CURSEFORGE_TOKEN") != null) { + apply plugin: 'com.matthewprenger.cursegradle' + + File changelogFile = new File(System.getenv("CHANGELOG_FILE") ?: "CHANGELOG.md") + + curseforge { + apiKey = System.getenv("CURSEFORGE_TOKEN") + project { + id = curseForgeProjectId + if (changelogFile.exists()) { + changelogType = "markdown" + changelog = changelogFile + } + releaseType = identifiedVersion.endsWith("-pre") ? "beta" : "release" + addGameVersion minecraftVersion + addGameVersion "Forge" + mainArtifact publishableObfJar + for (artifact in getSecondaryArtifacts()) addArtifact artifact + } + + options { + javaIntegration = false + forgeGradleIntegration = false + debug = false + } + } + + if (curseForgeRelations.size() != 0) { + String[] deps = curseForgeRelations.split(";") + deps.each { dep -> + if (dep.size() == 0) { + return + } + String[] parts = dep.split(":") + addCurseForgeRelation(parts[0], parts[1]) + } + } + if (usesMixins.toBoolean()) { + addCurseForgeRelation("requiredDependency", "unimixins") + } + tasks.curseforge.dependsOn(build) + tasks.publish.dependsOn(tasks.curseforge) +} + +def addModrinthDep(String scope, String type, String name) { + com.modrinth.minotaur.dependencies.Dependency dep; + if (!(scope in ["required", "optional", "incompatible", "embedded"])) { + throw new Exception("Invalid modrinth dependency scope: " + scope) + } + switch (type) { + case "project": + dep = new ModDependency(name, scope) + break + case "version": + dep = new VersionDependency(name, scope) + break + default: + throw new Exception("Invalid modrinth dependency type: " + type) + } + project.modrinth.dependencies.add(dep) +} + +def addCurseForgeRelation(String type, String name) { + if (!(type in ["requiredDependency", "embeddedLibrary", "optionalDependency", "tool", "incompatible"])) { + throw new Exception("Invalid CurseForge relation type: " + type) + } + CurseArtifact artifact = project.curseforge.curseProjects[0].mainArtifact + CurseRelation rel = (artifact.curseRelations ?: (artifact.curseRelations = new CurseRelation())) + rel."$type"(name) +} + +// Updating + +def buildscriptGradleVersion = "8.5" + +tasks.named('wrapper', Wrapper).configure { + gradleVersion = buildscriptGradleVersion +} + +tasks.register('updateBuildScript') { + group = 'GTNH Buildscript' + description = 'Updates the build script to the latest version' + + if (gradle.gradleVersion != buildscriptGradleVersion && !Boolean.getBoolean('DISABLE_BUILDSCRIPT_GRADLE_UPDATE')) { + dependsOn('wrapper') + } + + doLast { + if (performBuildScriptUpdate()) return + + print("Build script already up-to-date!") + } +} + +if (!project.getGradle().startParameter.isOffline() && !Boolean.getBoolean('DISABLE_BUILDSCRIPT_UPDATE_CHECK') && isNewBuildScriptVersionAvailable()) { + if (autoUpdateBuildScript.toBoolean()) { + performBuildScriptUpdate() + } else { + out.style(Style.SuccessHeader).println("Build script update available! Run 'gradle updateBuildScript'") + if (gradle.gradleVersion != buildscriptGradleVersion) { + out.style(Style.SuccessHeader).println("updateBuildScript can update gradle from ${gradle.gradleVersion} to ${buildscriptGradleVersion}\n") + } + } +} + +// If you want to add more cases to this task, implement them as arguments if total amount to print gets too large +tasks.register('faq') { + group = 'GTNH Buildscript' + description = 'Prints frequently asked questions about building a project' + + doLast { + print("If your build fails to fetch dependencies, run './gradlew updateDependencies'. " + + "Or you can manually check if the versions are still on the distributing sites - " + + "the links can be found in repositories.gradle and build.gradle:repositories, " + + "but not build.gradle:buildscript.repositories - those ones are for gradle plugin metadata.\n\n" + + "If your build fails to recognize the syntax of new Java versions, enable Jabel in your " + + "gradle.properties. See how it's done in GTNH ExampleMod/gradle.properties. " + + "However, keep in mind that Jabel enables only syntax features, but not APIs that were introduced in " + + "Java 9 or later.") + } +} + +static URL availableBuildScriptUrl() { + new URL("https://raw.githubusercontent.com/GTNewHorizons/ExampleMod1.7.10/master/build.gradle") +} + +static URL exampleSettingsGradleUrl() { + new URL("https://raw.githubusercontent.com/GTNewHorizons/ExampleMod1.7.10/master/settings.gradle.example") +} + +static URL exampleGitAttributesUrl() { + new URL("https://raw.githubusercontent.com/GTNewHorizons/ExampleMod1.7.10/master/.gitattributes") +} + + +boolean verifyGitAttributes() { + def gitattributesFile = getFile(".gitattributes") + if (!gitattributesFile.exists()) { + println("Downloading default .gitattributes") + exampleGitAttributesUrl().withInputStream { i -> gitattributesFile.withOutputStream { it << i } } + exec { + workingDir '.' + commandLine 'git', 'add', '--renormalize', '.' + } + return true + } + return false +} + +boolean verifySettingsGradle() { + def settingsFile = getFile("settings.gradle") + if (!settingsFile.exists()) { + println("Downloading default settings.gradle") + exampleSettingsGradleUrl().withInputStream { i -> settingsFile.withOutputStream { it << i } } + return true + } + return false +} + +boolean performBuildScriptUpdate() { + if (isNewBuildScriptVersionAvailable()) { + def buildscriptFile = getFile("build.gradle") + availableBuildScriptUrl().withInputStream { i -> buildscriptFile.withOutputStream { it << i } } + def out = services.get(StyledTextOutputFactory).create('buildscript-update-output') + out.style(Style.Success).print("Build script updated. Please REIMPORT the project or RESTART your IDE!") + boolean settingsupdated = verifySettingsGradle() + settingsupdated = verifyGitAttributes() || settingsupdated + if (settingsupdated) + throw new GradleException("Settings has been updated, please re-run task.") + return true + } + return false +} + +boolean isNewBuildScriptVersionAvailable() { + Map parameters = ["connectTimeout": 2000, "readTimeout": 2000] + + String currentBuildScript = getFile("build.gradle").getText() + String currentBuildScriptHash = getVersionHash(currentBuildScript) + String availableBuildScriptHash + try { + String availableBuildScript = availableBuildScriptUrl().newInputStream(parameters).getText() + availableBuildScriptHash = getVersionHash(availableBuildScript) + } catch (IOException e) { + logger.warn("Could not check for buildscript update availability: {}", e.message) + return false } + + boolean isUpToDate = currentBuildScriptHash.empty || availableBuildScriptHash.empty || currentBuildScriptHash == availableBuildScriptHash + return !isUpToDate +} + +static String getVersionHash(String buildScriptContent) { + String versionLine = buildScriptContent.find("^//version: [a-z0-9]*") + if (versionLine != null) { + return versionLine.split(": ").last() + } + return "" +} + +// Parameter Deobfuscation + +tasks.register('deobfParams') { + group = 'GTNH Buildscript' + description = 'Rename all obfuscated parameter names inherited from Minecraft classes' + doLast { // TODO + + String mcpDir = "$project.gradle.gradleUserHomeDir/caches/minecraft/de/oceanlabs/mcp/mcp_$channel/$mappingsVersion" + String mcpZIP = "$mcpDir/mcp_$channel-$mappingsVersion-${minecraftVersion}.zip" + String paramsCSV = "$mcpDir/params.csv" + + download.run { + src "https://maven.minecraftforge.net/de/oceanlabs/mcp/mcp_$channel/$mappingsVersion-$minecraftVersion/mcp_$channel-$mappingsVersion-${minecraftVersion}.zip" + dest mcpZIP + overwrite false + } + + if (!file(paramsCSV).exists()) { + println("Extracting MCP archive ...") + copy { + from(zipTree(mcpZIP)) + into(mcpDir) + } + } + + println("Parsing params.csv ...") + Map params = new HashMap<>() + Files.lines(Paths.get(paramsCSV)).forEach { line -> + String[] cells = line.split(",") + if (cells.length > 2 && cells[0].matches("p_i?\\d+_\\d+_")) { + params.put(cells[0], cells[1]) + } + } + + out.style(Style.Success).println("Modified ${replaceParams(file("$projectDir/src/main/java"), params)} files!") + out.style(Style.Failure).println("Don't forget to verify that the code still works as before!\n It could be broken due to duplicate variables existing now\n or parameters taking priority over other variables.") + } +} + +static int replaceParams(File file, Map params) { + int fileCount = 0 + + if (file.isDirectory()) { + for (File f : file.listFiles()) { + fileCount += replaceParams(f, params) + } + return fileCount + } + println("Visiting ${file.getName()} ...") + try { + String content = new String(Files.readAllBytes(file.toPath())) + int hash = content.hashCode() + params.forEach { key, value -> + content = content.replaceAll(key, value) + } + if (hash != content.hashCode()) { + Files.write(file.toPath(), content.getBytes("UTF-8")) + return 1 + } + } catch (Exception e) { + e.printStackTrace() + } + return 0 +} + +// Dependency Deobfuscation (Deprecated, use the new RFG API documented in dependencies.gradle) + +def deobf(String sourceURL) { + try { + URL url = new URL(sourceURL) + String fileName = url.getFile() + + //get rid of directories: + int lastSlash = fileName.lastIndexOf("/") + if (lastSlash > 0) { + fileName = fileName.substring(lastSlash + 1) + } + //get rid of extension: + if (fileName.endsWith(".jar") || fileName.endsWith(".litemod")) { + fileName = fileName.substring(0, fileName.lastIndexOf(".")) + } + + String hostName = url.getHost() + if (hostName.startsWith("www.")) { + hostName = hostName.substring(4) + } + List parts = Arrays.asList(hostName.split("\\.")) + Collections.reverse(parts) + hostName = String.join(".", parts) + + return deobf(sourceURL, "$hostName/$fileName") + } catch (Exception ignored) { + return deobf(sourceURL, "deobf/${sourceURL.hashCode()}") + } +} + +def deobfMaven(String repoURL, String mavenDep) { + if (!repoURL.endsWith("/")) { + repoURL += "/" + } + String[] parts = mavenDep.split(":") + parts[0] = parts[0].replace('.', '/') + def jarURL = repoURL + parts[0] + "/" + parts[1] + "/" + parts[2] + "/" + parts[1] + "-" + parts[2] + ".jar" + return deobf(jarURL) +} + +def deobfCurse(String curseDep) { + return dependencies.rfg.deobf("curse.maven:$curseDep") +} + +// The method above is to be preferred. Use this method if the filename is not at the end of the URL. +def deobf(String sourceURL, String rawFileName) { + String bon2Version = "2.5.1" + String fileName = URLDecoder.decode(rawFileName, "UTF-8") + String cacheDir = "$project.gradle.gradleUserHomeDir/caches" + String obfFile = "$cacheDir/modules-2/files-2.1/${fileName}.jar" + + download.run { + src sourceURL + dest obfFile + quiet true + overwrite false + } + return dependencies.rfg.deobf(files(obfFile)) +} +// Helper methods + +def checkPropertyExists(String propertyName) { + if (!project.hasProperty(propertyName)) { + throw new GradleException("This project requires a property \"" + propertyName + "\"! Please add it your \"gradle.properties\". You can find all properties and their description here: https://github.com/GTNewHorizons/ExampleMod1.7.10/blob/main/gradle.properties") + } +} + +def propertyDefaultIfUnset(String propertyName, defaultValue) { + if (!project.hasProperty(propertyName) || project.property(propertyName) == "") { + project.ext.setProperty(propertyName, defaultValue) + } +} + +def getFile(String relativePath) { + return new File(projectDir, relativePath) +} + +def getSecondaryArtifacts() { + // Because noPublishedSources from the beginning of the script is somehow not visible here... + boolean noPublishedSources = project.hasProperty("noPublishedSources") ? project.noPublishedSources.toBoolean() : false + def secondaryArtifacts = [publishableDevJar] + if (!noPublishedSources) secondaryArtifacts += [sourcesJar] + if (apiPackage) secondaryArtifacts += [apiJar] + return secondaryArtifacts +} + +def getURL(String main, String fallback) { + return pingURL(main, 10000) ? main : fallback +} + +// credit: https://stackoverflow.com/a/3584332 +def pingURL(String url, int timeout) { + url = url.replaceFirst("^https", "http") // Otherwise an exception may be thrown on invalid SSL certificates. + try { + HttpURLConnection connection = (HttpURLConnection) new URL(url).openConnection() + connection.setConnectTimeout(timeout) + connection.setReadTimeout(timeout) + connection.setRequestMethod("HEAD") + int responseCode = connection.getResponseCode() + return 200 <= responseCode && responseCode <= 399 + } catch (IOException ignored) { + return false + } +} + +// For easier scripting of things that require variables defined earlier in the buildscript +if (file('addon.late.gradle.kts').exists()) { + apply from: 'addon.late.gradle.kts' +} else if (file('addon.late.gradle').exists()) { + apply from: 'addon.late.gradle' +} + +// File for local tweaks not commited to Git +if (file('addon.late.local.gradle.kts').exists()) { + apply from: 'addon.late.local.gradle.kts' +} else if (file('addon.late.local.gradle').exists()) { + apply from: 'addon.late.local.gradle' } diff --git a/dependencies.gradle b/dependencies.gradle new file mode 100644 index 0000000..624c487 --- /dev/null +++ b/dependencies.gradle @@ -0,0 +1,37 @@ +/* + * Add your dependencies here. Supported configurations: + * - api("group:name:version:classifier"): if you use the types from this dependency in the public API of this mod + * Available at runtime and compiletime for mods depending on this mod + * - implementation("g:n:v:c"): if you need this for internal implementation details of the mod, but none of it is visible via the public API + * Available at runtime but not compiletime for mods depending on this mod + * - compileOnly("g:n:v:c"): if the mod you're building doesn't need this dependency during runtime at all, e.g. for optional mods + * Not available at all for mods depending on this mod, only visible at compiletime for this mod + * - compileOnlyApi("g:n:v:c"): like compileOnly, but also visible at compiletime for mods depending on this mod + * Available at compiletime but not runtime for mods depending on this mod + * - runtimeOnlyNonPublishable("g:n:v:c"): if you want to include a mod in this mod's runClient/runServer runs, but not publish it as a dependency + * Not available at all for mods depending on this mod, only visible at runtime for this mod + * - devOnlyNonPublishable("g:n:v:c"): a combination of runtimeOnlyNonPublishable and compileOnly for dependencies present at both compiletime and runtime, + * but not published as Maven dependencies - useful for RFG-deobfuscated dependencies or local testing + * - runtimeOnly("g:n:v:c"): if you don't need this at compile time, but want it to be present at runtime + * Available at runtime for mods depending on this mod + * - annotationProcessor("g:n:v:c"): mostly for java compiler plugins, if you know you need this, use it, otherwise don't worry + * - testCONFIG("g:n:v:c") - replace CONFIG by one of the above (except api), same as above but for the test sources instead of main + * + * - shadowImplementation("g:n:v:c"): effectively the same as API, but the dependency is included in your jar under a renamed package name + * Requires you to enable usesShadowedDependencies in gradle.properties + * + * - compile("g:n:v:c"): deprecated, replace with "api" (works like the old "compile") or "implementation" (can be more efficient) + * + * You can exclude transitive dependencies (dependencies of the chosen dependency) by appending { transitive = false } if needed, + * but use this sparingly as it can break using your mod as another mod's dependency if you're not careful. + * + * To depend on obfuscated jars you can use `devOnlyNonPublishable(rfg.deobf("dep:spec:1.2.3"))` to fetch an obfuscated jar from maven, + * or `devOnlyNonPublishable(rfg.deobf(project.files("libs/my-mod-jar.jar")))` to use a file. + * + * Gradle names for some of the configuration can be misleading, compileOnlyApi and runtimeOnly both get published as dependencies in Maven, but compileOnly does not. + * The buildscript adds runtimeOnlyNonPublishable to also have a runtime dependency that's not published. + * + * For more details, see https://docs.gradle.org/8.0.1/userguide/java_library_plugin.html#sec:java_library_configurations_graph + */ +dependencies { +} diff --git a/gradle.properties b/gradle.properties new file mode 100644 index 0000000..b6af6d4 --- /dev/null +++ b/gradle.properties @@ -0,0 +1,152 @@ +modName = Grappling Hook Mod + +# This is a case-sensitive string to identify your mod. Convention is to use lower case. +modId = grapplemod + +modGroup = com.yyon.grapplinghook + +# WHY is there no version field? +# The build script relies on git to provide a version via tags. It is super easy and will enable you to always know the +# code base or your binary. Check out this tutorial: https://blog.mattclemente.com/2017/10/13/versioning-with-git-tags/ + +# Will update your build.gradle automatically whenever an update is available +autoUpdateBuildScript = false + +minecraftVersion = 1.7.10 +forgeVersion = 10.13.4.1614 + +# Specify a MCP channel and mappings version for dependency deobfuscation and the deobfParams task. +channel = stable +mappingsVersion = 12 + +# Define other MCP mappings for dependency deobfuscation +remoteMappings = https://raw.githubusercontent.com/MinecraftForge/FML/1.7.10/conf/ + +# Select a username for testing your mod with breakpoints. You may leave this empty for a random username each time you +# restart Minecraft in development. Choose this dependent on your mod: +# Do you need consistent player progressing (for example Thaumcraft)? -> Select a name +# Do you need to test how your custom blocks interacts with a player that is not the owner? -> leave name empty +developmentEnvironmentUserName = Developer + +# Enables using modern java syntax (up to version 17) via Jabel, while still targeting JVM 8. +# See https://github.com/bsideup/jabel for details on how this works. +enableModernJavaSyntax = true + +# Enables injecting missing generics into the decompiled source code for a better coding experience +# Turns most publicly visible List, Map, etc. into proper List, Map types +enableGenericInjection = true + +# Generate a class with String fields for the mod id, name, version and group name named with the fields below +generateGradleTokenClass = com.yyon.grapplemod.Tags +gradleTokenModId = MODID +gradleTokenModName = MODNAME +gradleTokenVersion = VERSION +gradleTokenGroupName = GROUPNAME +# [DEPRECATED] +# Multiple source files can be defined here by providing a comma-seperated list: Class1.java,Class2.java,Class3.java +# public static final String VERSION = "GRADLETOKEN_VERSION"; +# The string's content will be replaced with your mod's version when compiled. You should use this to specify your mod's +# version in @Mod([...], version = VERSION, [...]) +# Leave these properties empty to skip individual token replacements +replaceGradleTokenInFile = + +# In case your mod provides an API for other mods to implement you may declare its package here. Otherwise, you can +# leave this property empty. +# Example value: apiPackage = api + modGroup = com.myname.mymodid -> com.myname.mymodid.api +apiPackage = + +# Specify the configuration file for Forge's access transformers here. It must be placed into /src/main/resources/META-INF/ +# There can be multiple files in a space-separated list. +# Example value: mymodid_at.cfg nei_at.cfg +accessTransformersFile = + +# Provides setup for Mixins if enabled. If you don't know what mixins are: Keep it disabled! +usesMixins = false +# Adds some debug arguments like verbose output and export +usesMixinDebug = false +# Specify the location of your implementation of IMixinConfigPlugin. Leave it empty otherwise. +mixinPlugin = +# Specify the package that contains all of your Mixins. You may only place Mixins in this package or the build will fail! +mixinsPackage = +# Specify the core mod entry class if you use a core mod. This class must implement IFMLLoadingPlugin! +# This parameter is for legacy compatibility only +# Example value: coreModClass = asm.FMLPlugin + modGroup = com.myname.mymodid -> com.myname.mymodid.asm.FMLPlugin +coreModClass = +# If your project is only a consolidation of mixins or a core mod and does NOT contain a 'normal' mod ( = some class +# that is annotated with @Mod) you want this to be true. When in doubt: leave it on false! +containsMixinsAndOrCoreModOnly = false + +# Enables Mixins even if this mod doesn't use them, useful if one of the dependencies uses mixins. +forceEnableMixins = false + +# If enabled, you may use 'shadowCompile' for dependencies. They will be integrated in your jar. It is your +# responsibility check the licence and request permission for distribution, if required. +usesShadowedDependencies = false +# If disabled, won't remove unused classes from shaded dependencies. Some libraries use reflection to access +# their own classes, making the minimization unreliable. +minimizeShadowedDependencies = true +# If disabled, won't rename the shadowed classes. +relocateShadowedDependencies = true + +# Adds the GTNH maven, CurseMaven, IC2/Player maven, and some more well-known 1.7.10 repositories +includeWellKnownRepositories = true + +# Change these to your Maven coordinates if you want to publish to a custom Maven repository instead of the default GTNH Maven. +# Authenticate with the MAVEN_USERNAME and MAVEN_PASSWORD environment variables. +# If you need a more complex setup disable maven publishing here and add a publishing repository to addon.gradle. +usesMavenPublishing = true +# mavenPublishUrl = https://nexus.gtnewhorizons.com/repository/releases/ + +# Publishing to modrinth requires you to set the MODRINTH_TOKEN environment variable to your current modrinth API token. + +# The project's ID on Modrinth. Can be either the slug or the ID. +# Leave this empty if you don't want to publish on Modrinth. +modrinthProjectId = + +# The project's relations on Modrinth. You can use this to refer to other projects on Modrinth. +# Syntax: scope1-type1:name1;scope2-type2:name2;... +# Where scope can be one of [required, optional, incompatible, embedded], +# type can be one of [project, version], +# and the name is the Modrinth project or version slug/id of the other mod. +# Example: required-project:fplib;optional-project:gasstation;incompatible-project:gregtech +# Note: GTNH Mixins is automatically set as a required dependency if usesMixins = true +modrinthRelations = + + +# Publishing to CurseForge requires you to set the CURSEFORGE_TOKEN environment variable to one of your CurseForge API tokens. + +# The project's numeric ID on CurseForge. You can find this in the About Project box. +# Leave this empty if you don't want to publish on CurseForge. +curseForgeProjectId = + +# The project's relations on CurseForge. You can use this to refer to other projects on CurseForge. +# Syntax: type1:name1;type2:name2;... +# Where type can be one of [requiredDependency, embeddedLibrary, optionalDependency, tool, incompatible], +# and the name is the CurseForge project slug of the other mod. +# Example: requiredDependency:railcraft;embeddedLibrary:cofhlib;incompatible:buildcraft +# Note: GTNH Mixins is automatically set as a required dependency if usesMixins = true +curseForgeRelations = + + +# Optional parameter to customize the produced artifacts. Use this to preserver artifact naming when migrating older +# projects. New projects should not use this parameter. +# customArchiveBaseName = + +# Optional parameter to prevent the source code from being published +# noPublishedSources = + +# Uncomment this to disable spotless checks +# This should only be uncommented to keep it easier to sync with upstream/other forks. +# That is, if there is no other active fork/upstream, NEVER change this. +disableSpotless = true + +# Uncomment this to disable checkstyle checks (currently wildcard import check). +disableCheckstyle = true + +# Override the IDEA build type. Valid value is "" (leave blank, do not override), "idea" (force use native IDEA build), "gradle" +# (force use delegated build). +# This is meant to be set in $HOME/.gradle/gradle.properties. +# e.g. add "systemProp.org.gradle.project.ideaOverrideBuildType=idea" will override the build type to be always native build. +# WARNING: If you do use this option, it will overwrite whatever you have in your existing projects. This might not be what you want! +# Usually there is no need to uncomment this here as other developers do not necessarily use the same build type as you. +# ideaOverrideBuildType = idea diff --git a/gradle/wrapper/gradle-wrapper.jar b/gradle/wrapper/gradle-wrapper.jar new file mode 100644 index 0000000..d64cd49 Binary files /dev/null and b/gradle/wrapper/gradle-wrapper.jar differ diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties new file mode 100644 index 0000000..1af9e09 --- /dev/null +++ b/gradle/wrapper/gradle-wrapper.properties @@ -0,0 +1,7 @@ +distributionBase=GRADLE_USER_HOME +distributionPath=wrapper/dists +distributionUrl=https\://services.gradle.org/distributions/gradle-8.5-bin.zip +networkTimeout=10000 +validateDistributionUrl=true +zipStoreBase=GRADLE_USER_HOME +zipStorePath=wrapper/dists diff --git a/gradlew b/gradlew new file mode 100755 index 0000000..1aa94a4 --- /dev/null +++ b/gradlew @@ -0,0 +1,249 @@ +#!/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##*/} +# Discard cd standard output in case $CDPATH is set (https://github.com/gradle/gradle/issues/25036) +APP_HOME=$( cd "${APP_HOME:-./}" > /dev/null && pwd -P ) || exit + +# 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 + if ! command -v java >/dev/null 2>&1 + then + 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 +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=SC2039,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=SC2039,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 + + +# 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"' + +# Collect all arguments for the java command: +# * DEFAULT_JVM_OPTS, JAVA_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments, +# and any embedded shellness will be escaped. +# * For example: A user cannot expect ${Hostname} to be expanded, as it is an environment variable and will be +# treated as '${Hostname}' itself on the command line. + +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/jitpack.yml b/jitpack.yml new file mode 100644 index 0000000..09bbb51 --- /dev/null +++ b/jitpack.yml @@ -0,0 +1,2 @@ +before_install: + - ./gradlew setupCIWorkspace \ No newline at end of file diff --git a/main/java/com/yyon/grapplinghook/ClientProxyClass.java.orig b/main/java/com/yyon/grapplinghook/ClientProxyClass.java.orig deleted file mode 100644 index cc503f3..0000000 --- a/main/java/com/yyon/grapplinghook/ClientProxyClass.java.orig +++ /dev/null @@ -1,335 +0,0 @@ -package com.yyon.grapplinghook; - -import java.util.Collection; -import java.util.ConcurrentModificationException; -import java.util.HashMap; - -import org.lwjgl.input.Keyboard; -import org.lwjgl.input.Mouse; - -import net.minecraft.client.Minecraft; -import net.minecraft.client.entity.EntityPlayerSP; -import net.minecraft.client.renderer.entity.Render; -import net.minecraft.client.renderer.entity.RenderManager; -import net.minecraft.client.settings.GameSettings; -import net.minecraft.client.settings.KeyBinding; -import net.minecraft.entity.Entity; -import net.minecraft.entity.player.EntityPlayer; -import net.minecraft.init.Items; -import net.minecraft.item.Item; -import net.minecraft.item.ItemStack; -import net.minecraftforge.event.world.BlockEvent.BreakEvent; - -import com.yyon.grapplinghook.controllers.grappleController; -import com.yyon.grapplinghook.entities.RenderGrappleArrow; -import com.yyon.grapplinghook.entities.grappleArrow; -import com.yyon.grapplinghook.items.clickitem; -import com.yyon.grapplinghook.items.enderBow; -import com.yyon.grapplinghook.items.grappleBow; -import com.yyon.grapplinghook.items.hookBow; -import com.yyon.grapplinghook.items.launcherItem; -import com.yyon.grapplinghook.items.magnetBow; -import com.yyon.grapplinghook.items.multiBow; -import com.yyon.grapplinghook.items.repeller; -import com.yyon.grapplinghook.items.smartHookBow; - -import cpw.mods.fml.client.registry.RenderingRegistry; -import cpw.mods.fml.common.event.FMLInitializationEvent; -import cpw.mods.fml.common.event.FMLPostInitializationEvent; -import cpw.mods.fml.common.event.FMLPreInitializationEvent; -import cpw.mods.fml.common.eventhandler.SubscribeEvent; -import cpw.mods.fml.common.gameevent.TickEvent; - -public class ClientProxyClass extends CommonProxyClass { - public boolean leftclick = false; - public boolean prevleftclick = false; - public HashMap enderlaunchtimer = new HashMap(); - public final int reusetime = 50; - - @Override - public void preInit(FMLPreInitializationEvent event) { - super.preInit(event); - } - - /* - public ModelResourceLocation grapplinghookloc = new ModelResourceLocation("grapplemod:grapplinghook", "inventory"); - public ModelResourceLocation hookshotloc = new ModelResourceLocation("grapplemod:hookshot", "inventory"); - public ModelResourceLocation smarthookloc = new ModelResourceLocation("grapplemod:smarthook", "inventory"); - public ModelResourceLocation smarthookropeloc = new ModelResourceLocation("grapplemod:smarthookrope", "inventory"); - public ModelResourceLocation enderhookloc = new ModelResourceLocation("grapplemod:enderhook", "inventory"); - public ModelResourceLocation magnetbowloc = new ModelResourceLocation("grapplemod:magnetbow", "inventory"); - public ModelResourceLocation ropeloc = new ModelResourceLocation("grapplemod:rope", "inventory"); - public ModelResourceLocation hookshotropeloc = new ModelResourceLocation("grapplemod:hookshotrope", "inventory"); - public ModelResourceLocation repellerloc = new ModelResourceLocation("grapplemod:repeller", "inventory"); - public ModelResourceLocation repelleronloc = new ModelResourceLocation("grapplemod:repelleron", "inventory"); - public ModelResourceLocation multihookloc = new ModelResourceLocation("grapplemod:multihook", "inventory"); - public ModelResourceLocation multihookropeloc = new ModelResourceLocation("grapplemod:multihookrope", "inventory"); - - private void setgrapplebowtextures(Item item, final ModelResourceLocation notinusetexture, final ModelResourceLocation inusetexture) { - ModelLoader.setCustomMeshDefinition(item, new ItemMeshDefinition() { - @Override - public ModelResourceLocation getModelLocation(ItemStack stack) { - if (ClientProxyClass.isactive(stack)) { - return inusetexture; - } - return notinusetexture; - } - }); - ModelBakery.registerItemVariants(item, notinusetexture); - ModelBakery.registerItemVariants(item, inusetexture); - } - - private void registerItemModels() { - setgrapplebowtextures(grapplemod.grapplebowitem, grapplinghookloc, ropeloc); - setgrapplebowtextures(grapplemod.hookshotitem, hookshotloc, hookshotropeloc); - registerItemModel(grapplemod.launcheritem); - registerItemModel(grapplemod.longfallboots); - setgrapplebowtextures(grapplemod.enderhookitem, enderhookloc, ropeloc); - setgrapplebowtextures(grapplemod.magnetbowitem, magnetbowloc, ropeloc); - setgrapplebowtextures(grapplemod.repelleritem, repellerloc, repelleronloc); - setgrapplebowtextures(grapplemod.multihookitem, multihookloc, multihookropeloc); - setgrapplebowtextures(grapplemod.smarthookitem, smarthookloc, smarthookropeloc); - } - - private void registerItemModel(Item item) { - registerItemModel(item, Item.REGISTRY.getNameForObject(item).toString()); - } - - private void registerItemModel(Item item, String modelLocation) { - final ModelResourceLocation fullModelLocation = new ModelResourceLocation(modelLocation, "inventory"); -// ModelBakery.registerItemVariants(item, fullModelLocation); // Ensure the custom model is loaded and prevent the default model from being loaded - ModelLoader.setCustomModelResourceLocation(item, 0, fullModelLocation); - } - */ - - @Override - public void init(FMLInitializationEvent event, grapplemod grappleModInst) { - super.init(event, grappleModInst); - RenderGrappleArrow rga = new RenderGrappleArrow(grapplemod.grapplebowitem); - RenderingRegistry.registerEntityRenderingHandler(grappleArrow.class, rga); -// Minecraft.getMinecraft().getRenderItem().getItemModelMesher().register(grapplemod.grapplebowitem, 0, new ModelResourceLocation("grapplemod:grapplinghook", "inventory")); -// Minecraft.getMinecraft().getRenderItem().getItemModelMesher().register(grapplemod.hookshotitem, 0, new ModelResourceLocation("grapplemod:hookshot", "inventory")); -// Minecraft.getMinecraft().getRenderItem().getItemModelMesher().register(grapplemod.launcheritem, 0, new ModelResourceLocation("grapplemod:launcheritem", "inventory")); -// Minecraft.getMinecraft().getRenderItem().getItemModelMesher().register(grapplemod.longfallboots, 0, new ModelResourceLocation("grapplemod:longfallboots", "inventory")); -// Minecraft.getMinecraft().getRenderItem().getItemModelMesher().register(grapplemod.enderhookitem, 0, new ModelResourceLocation("grapplemod:enderhook", "inventory")); - } - - public crosshairRenderer crosshairrenderer; - - @Override - public void postInit(FMLPostInitializationEvent event) { - super.postInit(event); - - crosshairrenderer = new crosshairRenderer(); - } - - @Override - public void getplayermovement(grappleController control, int playerid) { - Entity entity = control.entity; - if (entity instanceof EntityPlayerSP) { - EntityPlayerSP player = (EntityPlayerSP) entity; - control.receivePlayerMovementMessage(player.moveStrafing, player.moveForward, player.movementInput.jump); - } - } - - @SubscribeEvent - public void onClientTick(TickEvent.ClientTickEvent event) { - EntityPlayer player = Minecraft.getMinecraft().thePlayer; - if (player != null) { - if (!Minecraft.getMinecraft().isGamePaused() || !Minecraft.getMinecraft().isSingleplayer()) { - try { - Collection controllers = grapplemod.controllers.values(); - for (grappleController controller : controllers) { - controller.doClientTick(); - } - } catch (ConcurrentModificationException e) { - System.out.println("ConcurrentModificationException caught"); - } - - leftclick = (GameSettings.isKeyDown(Minecraft.getMinecraft().gameSettings.keyBindAttack) && Minecraft.getMinecraft().currentScreen == null); - if (prevleftclick != leftclick) { - if (player != null) { - ItemStack stack = player.getHeldItem(); - if (stack != null) { - Item item = stack.getItem(); - if (item instanceof clickitem) { - if (leftclick) { - ((clickitem)item).onLeftClick(stack, player); - } else { - ((clickitem)item).onLeftClickRelease(stack, player); - } - } - } - } - } - - prevleftclick = leftclick; - - if (player.onGround) { - if (enderlaunchtimer.containsKey(player.getEntityId())) { - long timer = player.worldObj.getTotalWorldTime() - enderlaunchtimer.get(player.getEntityId()); - if (timer > 10) { - this.resetlaunchertime(player.getEntityId()); - } - } - } - } - } - } - - @Override - public void launchplayer(EntityPlayer player) { - long prevtime; - if (enderlaunchtimer.containsKey(player.getEntityId())) { - prevtime = enderlaunchtimer.get(player.getEntityId()); - } else { - prevtime = 0; - } - long timer = player.worldObj.getTotalWorldTime() - prevtime; - if (timer > reusetime) { -<<<<<<< HEAD - if (player.getHeldItem().getItem() instanceof enderBow || player.getHeldItem().getItem() instanceof launcherItem) { -======= - if ((player.getHeldItemMainhand()!=null && (player.getHeldItemMainhand().getItem() instanceof enderBow || player.getHeldItemMainhand().getItem() instanceof launcherItem)) || (player.getHeldItemOffhand()!=null && (player.getHeldItemOffhand().getItem() instanceof enderBow || player.getHeldItemOffhand().getItem() instanceof launcherItem))) { ->>>>>>> 6c8b29cf1a9f87c1801402122aee8a079fcdc67a - enderlaunchtimer.put(player.getEntityId(), player.worldObj.getTotalWorldTime()); - - vec facing = new vec(player.getLookVec()); -// vec playermotion = vec.motionvec(player); -// vec newvec = playermotion.add(facing.mult(3)); - - /* - if (!grapplemod.controllers.containsKey(player.getEntityId())) { - player.motionX = newvec.x; - player.motionY = newvec.y; - player.motionZ = newvec.z; - - if (player instanceof EntityPlayerMP) { - ((EntityPlayerMP) player).connection.sendPacket(new SPacketEntityVelocity(player)); - } else { - grapplemod.network.sendToServer(new PlayerMovementMessage(player.getEntityId(), player.posX, player.posY, player.posZ, player.motionX, player.motionY, player.motionZ)); - } - } else { - facing.mult_ip(3); - grapplemod.receiveEnderLaunch(player.getEntityId(), facing.x, facing.y, facing.z); - } - */ - if (!grapplemod.controllers.containsKey(player.getEntityId())) { - player.onGround = false; - grapplemod.createControl(grapplemod.AIRID, -1, player.getEntityId(), player.worldObj, new vec(0,0,0), 0, null); - } - facing.mult_ip(3); - grapplemod.receiveEnderLaunch(player.getEntityId(), facing.x, facing.y, facing.z); - } - } - } - - @Override - public void resetlaunchertime(int playerid) { - if (enderlaunchtimer.containsKey(playerid)) { - enderlaunchtimer.put(playerid, (long) 0); - } - } - - @Override - public boolean isSneaking(Entity entity) { - if (entity == Minecraft.getMinecraft().thePlayer) { - return (GameSettings.isKeyDown(Minecraft.getMinecraft().gameSettings.keyBindSneak)); - } else { - return entity.isSneaking(); - } - } - - @Override - public void blockbreak(BreakEvent event) { - BlockPos pos = new BlockPos(event.x, event.y, event.z); - if (pos != null) { - if (grapplemod.controllerpos.containsKey(pos)) { - grappleController control = grapplemod.controllerpos.get(pos); - - control.unattach(); - - grapplemod.controllerpos.remove(pos); - } - } - } - - @Override - public void handleDeath(Entity entity) { - int id = entity.getEntityId(); - if (grapplemod.controllers.containsKey(id)) { - grappleController controller = grapplemod.controllers.get(id); - controller.unattach(); - } - } - - @Override - public String getkeyname(CommonProxyClass.keys keyenum) { - KeyBinding binding = null; - - GameSettings gs = Minecraft.getMinecraft().gameSettings; - - if (keyenum == keys.keyBindAttack) { - binding = gs.keyBindAttack; - } else if (keyenum == keys.keyBindBack) { - binding = gs.keyBindBack; - } else if (keyenum == keys.keyBindForward) { - binding = gs.keyBindForward; - } else if (keyenum == keys.keyBindJump) { - binding = gs.keyBindJump; - } else if (keyenum == keys.keyBindLeft) { - binding = gs.keyBindLeft; - } else if (keyenum == keys.keyBindRight) { - binding = gs.keyBindRight; - } else if (keyenum == keys.keyBindSneak) { - binding = gs.keyBindSneak; - } else if (keyenum == keys.keyBindUseItem) { - binding = gs.keyBindUseItem; - } - - if (binding == null) { - return ""; - } - - String displayname; - int keycode = binding.getKeyCode(); - if (keycode == -99) { - return "Right Click"; - } else if (keycode == -100) { - return "Left Click"; - } - try { - displayname = Keyboard.getKeyName(keycode); - } catch (ArrayIndexOutOfBoundsException e) { - displayname = "???"; - } - return displayname; - } - - public static boolean isactive(ItemStack stack) { - EntityPlayer p = Minecraft.getMinecraft().thePlayer; -// if (p.getItemStackFromSlot(EntityEquipmentSlot.MAINHAND) == stack || p.getItemStackFromSlot(EntityEquipmentSlot.OFFHAND) == stack) { - int entityid = p.getEntityId(); - if (grapplemod.controllers.containsKey(entityid)) { - Item item = stack.getItem(); - grappleController controller = grapplemod.controllers.get(entityid); - if (item.getClass() == grappleBow.class && controller.controllerid == grapplemod.GRAPPLEID) { - return true; - } else if (item.getClass() == enderBow.class && controller.controllerid == grapplemod.ENDERID) { - return true; - } else if (item.getClass() == hookBow.class && controller.controllerid == grapplemod.HOOKID) { - return true; - } else if (item.getClass() == magnetBow.class && controller.controllerid == grapplemod.MAGNETID) { - return true; - } else if (item.getClass() == repeller.class && controller.controllerid == grapplemod.REPELID) { - return true; - } else if (item.getClass() == multiBow.class && controller.controllerid == grapplemod.MULTIID) { - return true; - } else if (item.getClass() == smartHookBow.class && controller.controllerid == grapplemod.SMARTHOOKID) { - return true; - } - } -// } - return false; - } -} diff --git a/main/java/com/yyon/grapplinghook/grapplemod.java.orig b/main/java/com/yyon/grapplinghook/grapplemod.java.orig deleted file mode 100644 index 953671f..0000000 --- a/main/java/com/yyon/grapplinghook/grapplemod.java.orig +++ /dev/null @@ -1,562 +0,0 @@ -package com.yyon.grapplinghook; - -import java.util.ArrayList; -import java.util.HashMap; -import java.util.HashSet; -import java.util.Random; - -import net.minecraft.block.Block; -import net.minecraft.entity.Entity; -import net.minecraft.entity.EntityLivingBase; -import net.minecraft.entity.player.EntityPlayer; -import net.minecraft.entity.player.EntityPlayerMP; -import net.minecraft.init.Blocks; -import net.minecraft.init.Items; -import net.minecraft.item.Item; -import net.minecraft.item.ItemArmor; -import net.minecraft.item.ItemStack; -import net.minecraft.nbt.NBTTagCompound; -import net.minecraft.server.MinecraftServer; -import net.minecraft.util.ChatComponentText; -import net.minecraft.world.World; - -import com.yyon.grapplinghook.controllers.airfrictionController; -import com.yyon.grapplinghook.controllers.enderController; -import com.yyon.grapplinghook.controllers.grappleController; -import com.yyon.grapplinghook.controllers.hookControl; -import com.yyon.grapplinghook.controllers.magnetController; -import com.yyon.grapplinghook.controllers.multihookController; -import com.yyon.grapplinghook.controllers.repelController; -import com.yyon.grapplinghook.controllers.smartHookControl; -import com.yyon.grapplinghook.entities.enderArrow; -import com.yyon.grapplinghook.entities.grappleArrow; -import com.yyon.grapplinghook.entities.hookArrow; -import com.yyon.grapplinghook.entities.magnetArrow; -import com.yyon.grapplinghook.entities.multihookArrow; -import com.yyon.grapplinghook.entities.smartHookArrow; -import com.yyon.grapplinghook.items.LongFallBoots; -import com.yyon.grapplinghook.items.enderBow; -import com.yyon.grapplinghook.items.grappleBow; -import com.yyon.grapplinghook.items.hookBow; -import com.yyon.grapplinghook.items.launcherItem; -import com.yyon.grapplinghook.items.magnetBow; -import com.yyon.grapplinghook.items.multiBow; -import com.yyon.grapplinghook.items.repeller; -import com.yyon.grapplinghook.items.smartHookBow; -import com.yyon.grapplinghook.network.GrappleAttachMessage; -import com.yyon.grapplinghook.network.GrappleAttachPosMessage; -import com.yyon.grapplinghook.network.GrappleClickMessage; -import com.yyon.grapplinghook.network.GrappleEndMessage; -import com.yyon.grapplinghook.network.MultiHookMessage; -import com.yyon.grapplinghook.network.PlayerMovementMessage; -import com.yyon.grapplinghook.network.ToolConfigMessage; - -import cpw.mods.fml.common.Mod; -import cpw.mods.fml.common.Mod.EventHandler; -import cpw.mods.fml.common.SidedProxy; -import cpw.mods.fml.common.event.FMLInitializationEvent; -import cpw.mods.fml.common.event.FMLPostInitializationEvent; -import cpw.mods.fml.common.event.FMLPreInitializationEvent; -import cpw.mods.fml.common.event.FMLServerStartingEvent; -import cpw.mods.fml.common.network.NetworkRegistry; -import cpw.mods.fml.common.network.simpleimpl.IMessage; -import cpw.mods.fml.common.network.simpleimpl.SimpleNetworkWrapper; -import cpw.mods.fml.common.registry.EntityRegistry; -import cpw.mods.fml.common.registry.GameRegistry; -import cpw.mods.fml.relauncher.Side; - -/* - * This file is part of GrappleMod. - - GrappleMod is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - GrappleMod is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with GrappleMod. If not, see . - */ - -//TODO -// Pull mobs -// Attach 2 things together - -@Mod(modid = grapplemod.MODID, version = grapplemod.VERSION) -public class grapplemod { - - public grapplemod(){} - - public static final String MODID = "grapplemod"; - -<<<<<<< HEAD - public static final String VERSION = "1.7.10-v7"; -======= - public static final String VERSION = "1.10.2-v10"; ->>>>>>> 6c8b29cf1a9f87c1801402122aee8a079fcdc67a - - public static Item grapplebowitem; - public static Item hookshotitem; - public static Item smarthookitem; - public static Item enderhookitem; - public static Item launcheritem; - public static Item longfallboots; - public static Item magnetbowitem; - public static Item repelleritem; - public static Item multihookitem; - - public static Object instance; - - public static SimpleNetworkWrapper network; - - public static HashMap controllers = new HashMap(); // client side - public static HashMap controllerpos = new HashMap(); - public static HashSet attached = new HashSet(); // server side - - private static int controllerid = 0; - public static int GRAPPLEID = controllerid++; - public static int ENDERID = controllerid++; - public static int HOOKID = controllerid++; - public static int MAGNETID = controllerid++; - public static int REPELID = controllerid++; - public static int MULTIID = controllerid++; - public static int MULTISUBID = controllerid++; - public static int AIRID = controllerid++; - public static int SMARTHOOKID = controllerid++; - - public static int REPELCONFIGS = 0; -// public static int REPELSPEED = REPELCONFIGS++; - public static int REPELSTRONG = REPELCONFIGS++; - public static int REPELWEAK = REPELCONFIGS++; - public static int REPELNONE = REPELCONFIGS++; - - public static int grapplingLength = 0; - public static boolean anyblocks = true; - public static ArrayList grapplingblocks; - public static boolean removeblocks = false; - - @SidedProxy(clientSide="com.yyon.grapplinghook.ClientProxyClass", serverSide="com.yyon.grapplinghook.ServerProxyClass") - public static CommonProxyClass proxy; - - @EventHandler - public void load(FMLInitializationEvent event){ - GameRegistry.addRecipe(new ItemStack(grapplebowitem, 1), new Object[]{ - "X2", - "4X", Character.valueOf('2'), new ItemStack(Items.iron_pickaxe, 1), Character.valueOf('4'), new ItemStack(Items.lead, 1), - }); - GameRegistry.addRecipe(new ItemStack(hookshotitem, 1), new Object[]{ - "X2", - "4X", Character.valueOf('2'), new ItemStack(grapplebowitem, 1), Character.valueOf('4'), new ItemStack(Blocks.piston, 1), - }); - GameRegistry.addRecipe(new ItemStack(smarthookitem, 1), new Object[]{ - "X2", - "4X", Character.valueOf('2'), new ItemStack(hookshotitem, 1), Character.valueOf('4'), new ItemStack(Items.REDSTONE, 1), - }); - GameRegistry.addRecipe(new ItemStack(launcheritem, 1), new Object[]{ - "X2", - "4X", Character.valueOf('2'), new ItemStack(Items.ender_pearl, 1), Character.valueOf('4'), new ItemStack(Blocks.piston, 1), - }); - GameRegistry.addRecipe(new ItemStack(enderhookitem, 1), new Object[]{ - "X2", - "4X", Character.valueOf('2'), new ItemStack(grapplebowitem, 1), Character.valueOf('4'), new ItemStack(launcheritem, 1), - }); - GameRegistry.addRecipe(new ItemStack(repelleritem, 1), new Object[]{ - "X2X", - "242", - "X2X", Character.valueOf('2'), new ItemStack(Items.iron_ingot, 1), Character.valueOf('4'), new ItemStack(Items.compass, 1), - }); - GameRegistry.addRecipe(new ItemStack(magnetbowitem, 1), new Object[]{ - "X2", - "4X", Character.valueOf('2'), new ItemStack(grapplebowitem, 1), Character.valueOf('4'), new ItemStack(repelleritem, 1), - }); - GameRegistry.addRecipe(new ItemStack(longfallboots, 1), new Object[]{ - "2", - "4", Character.valueOf('2'), new ItemStack(Items.diamond_boots, 1), Character.valueOf('4'), new ItemStack(Blocks.wool, 1), - }); - GameRegistry.addRecipe(new ItemStack(multihookitem, 1), new Object[]{ - "X2", - "2X", Character.valueOf('2'), new ItemStack(hookshotitem, 1), - }); - } - - public void registerRenderers(){ - } - public void generateNether(World world, Random random, int chunkX, int chunkZ){} - public void generateSurface(World world, Random random, int chunkX, int chunkZ){} - public int addFuel(ItemStack fuel){ - return 0; - } - - @EventHandler - public void serverLoad(FMLServerStartingEvent event){ - event.getServer().worldServerForDimension(0).getGameRules().addGameRule("grapplingLength", "0"); - event.getServer().worldServerForDimension(0).getGameRules().addGameRule("grapplingBlocks", "any"); - event.getServer().worldServerForDimension(0).getGameRules().addGameRule("grapplingNonBlocks", "none"); - } - - public static void updateMaxLen(World world) { - String s = MinecraftServer.getServer().worldServerForDimension(0).getGameRules().getGameRuleStringValue("grapplingLength"); - if (!s.equals("")) { - grapplemod.grapplingLength = Integer.parseInt(s); - } - } - - public static void updateGrapplingBlocks(World world) { - String s = MinecraftServer.getServer().worldServerForDimension(0).getGameRules().getGameRuleStringValue("grapplingBlocks"); - if (s.equals("any") || s.equals("")) { - s = MinecraftServer.getServer().worldServerForDimension(0).getGameRules().getGameRuleStringValue("grapplingNonBlocks"); - if (s.equals("none") || s.equals("")) { - anyblocks = true; - } else { - anyblocks = false; - removeblocks = true; - } - } else { - anyblocks = false; - removeblocks = false; - } - - if (!anyblocks) { - String[] blockstr = s.split(","); - - grapplingblocks = new ArrayList(); - - for(String str:blockstr){ - str = str.trim(); - String modid; - String name; - if (str.contains(":")) { - String[] splitstr = str.split(":"); - modid = splitstr[0]; - name = splitstr[1]; - } else { - modid = "minecraft"; - name = str; - } - - Block b = GameRegistry.findBlock(modid, name); - - grapplingblocks.add(b); - } - } - } - - @EventHandler - public void preInit(FMLPreInitializationEvent event){ - grapplebowitem = new grappleBow(); - GameRegistry.registerItem(grapplebowitem, "grapplinghook"); - hookshotitem = new hookBow(); -<<<<<<< HEAD - GameRegistry.registerItem(hookshotitem, "hookshot"); -======= - hookshotitem.setRegistryName("hookshot"); - GameRegistry.register(hookshotitem); - smarthookitem = new smartHookBow(); - smarthookitem.setRegistryName("smarthook"); - GameRegistry.register(smarthookitem); ->>>>>>> 6c8b29cf1a9f87c1801402122aee8a079fcdc67a - launcheritem = new launcherItem(); - GameRegistry.registerItem(launcheritem, "launcheritem"); - longfallboots = new LongFallBoots(ItemArmor.ArmorMaterial.DIAMOND, 3); - GameRegistry.registerItem(longfallboots, "longfallboots"); - enderhookitem = new enderBow(); - GameRegistry.registerItem(enderhookitem, "enderhook"); - magnetbowitem = new magnetBow(); - GameRegistry.registerItem(magnetbowitem, "magnetbow"); - repelleritem = new repeller(); - GameRegistry.registerItem(repelleritem, "repeller"); - multihookitem = new multiBow(); - GameRegistry.registerItem(multihookitem, "multihook"); - - registerEntity(grappleArrow.class, "grappleArrow"); - registerEntity(enderArrow.class, "enderArrow"); - registerEntity(hookArrow.class, "hookArrow"); - registerEntity(magnetArrow.class, "magnetArrow"); - registerEntity(multihookArrow.class, "multihookArrow"); - registerEntity(smartHookArrow.class, "smartHookArrow"); - - proxy.preInit(event); - network = NetworkRegistry.INSTANCE.newSimpleChannel("grapplemodchannel"); - byte id = 0; - network.registerMessage(PlayerMovementMessage.Handler.class, PlayerMovementMessage.class, id++, Side.SERVER); - network.registerMessage(GrappleAttachMessage.Handler.class, GrappleAttachMessage.class, id++, Side.CLIENT); - network.registerMessage(GrappleEndMessage.Handler.class, GrappleEndMessage.class, id++, Side.SERVER); - network.registerMessage(GrappleClickMessage.Handler.class, GrappleClickMessage.class, id++, Side.CLIENT); - network.registerMessage(GrappleAttachPosMessage.Handler.class, GrappleAttachPosMessage.class, id++, Side.CLIENT); - network.registerMessage(MultiHookMessage.Handler.class, MultiHookMessage.class, id++, Side.SERVER); - network.registerMessage(ToolConfigMessage.Handler.class, ToolConfigMessage.class, id++, Side.SERVER); - } - - @EventHandler - public void Init(FMLInitializationEvent event) { - proxy.init(event, this); - } - - @EventHandler - public void postInit(FMLPostInitializationEvent event) { - proxy.postInit(event); - } - - int entityID = 0; - public void registerEntity(Class entityClass, String name) - { - EntityRegistry.registerModEntity(entityClass, name, entityID++, this, 900, 1, true); - } - - public static void registerController(int entityId, grappleController controller) { - if (controllers.containsKey(entityId)) { - controllers.get(entityId).unattach(); - } - - controllers.put(entityId, controller); - } - - public static void unregisterController(int entityId) { - controllers.remove(entityId); - } - - public static void receiveGrappleClick(int id, - boolean leftclick) { - grappleController controller = controllers.get(id); - if (controller != null) { - controller.receiveGrappleClick(leftclick); - } else { - System.out.println("Couldn't find controller"); - } - } - - public static void receiveEnderLaunch(int id, double x, double y, double z) { - grappleController controller = controllers.get(id); - if (controller != null) { - controller.receiveEnderLaunch(x, y, z); - } else { - System.out.println("Couldn't find controller"); - } - } - - public static void sendtocorrectclient(IMessage message, int playerid, World w) { - Entity entity = w.getEntityByID(playerid); - if (entity instanceof EntityPlayerMP) { - grapplemod.network.sendTo(message, (EntityPlayerMP) entity); - } else { - System.out.println("ERROR! couldn't find player"); - } - } - - public static grappleController createControl(int id, int arrowid, int entityid, World world, vec pos, int maxlen, BlockPos blockpos) { - - grappleArrow arrow = null; - Entity arrowentity = world.getEntityByID(arrowid); - if (arrowentity != null && arrowentity instanceof grappleArrow) { - arrow = (grappleArrow) arrowentity; - } - - if (id != MULTISUBID) { - grappleController currentcontroller = controllers.get(entityid); - if (currentcontroller != null) { - currentcontroller.unattach(); - } - } - - System.out.println(blockpos); - - grappleController control = null; - if (id == GRAPPLEID) { - control = new grappleController(arrowid, entityid, world, pos, maxlen, id); - } else if (id == ENDERID) { - control = new enderController(arrowid, entityid, world, pos, maxlen, id); - } else if (id == HOOKID) { - control = new hookControl(arrowid, entityid, world, pos, maxlen, id); - } else if (id == SMARTHOOKID) { - boolean slow = false; - if (arrow != null && arrow instanceof smartHookArrow) { - slow = ((smartHookArrow) arrow).slow; - } - control = new smartHookControl(arrowid, entityid, world, pos, maxlen, id, slow); - } else if (id == MAGNETID) { - int repelconf = 0; - if (arrow != null && arrow instanceof magnetArrow) { - repelconf = ((magnetArrow) arrow).repelconf; - } - control = new magnetController(arrowid, entityid, world, pos, maxlen, id, repelconf); - } else if (id == REPELID) { - control = new repelController(arrowid, entityid, world, pos, maxlen, id); - } else if (id == MULTIID) { - control = new multihookController(arrowid, entityid, world, pos, maxlen, id); - } else if (id == MULTISUBID) { - control = grapplemod.controllers.get(entityid); - boolean created = false; - if (control instanceof multihookController) { - multihookController c = (multihookController) control; - if (arrow != null && arrow instanceof multihookArrow) { - multihookArrow multiarrow = (multihookArrow) arrowentity; - created = true; - c.addArrow(multiarrow, pos); - } - } - if (!created) { - System.out.println("Couldn't create"); - grapplemod.removesubarrow(arrowid); - } - } else if (id == AIRID) { - System.out.println("AIR FRICTION CONTROLLER"); - control = new airfrictionController(arrowid, entityid, world, pos, maxlen, id); - } - if (blockpos != null && control != null) { - grapplemod.controllerpos.put(blockpos, control); - } - - return control; - } - - public static void removesubarrow(int id) { - grapplemod.network.sendToServer(new GrappleEndMessage(-1, id)); - } - - public static void receiveGrappleEnd(int id, World world, int arrowid) { - if (grapplemod.attached.contains(id)) { - grapplemod.attached.remove(new Integer - (id)); - } else { - } - - if (arrowid != -1) { - Entity grapple = world.getEntityByID(arrowid); - if (grapple instanceof grappleArrow) { - ((grappleArrow) grapple).removeServer(); - } else { - - } - } - - Entity entity = world.getEntityByID(id); - if (entity != null) { - entity.fallDistance = 0; - } - - grapplemod.removeallmultihookarrows(); - } - - public static HashSet multihookarrows = new HashSet(); - public static void receiveMultihookMessage(int id, World w, boolean sneaking) { - Entity e = w.getEntityByID(id); - if (e != null && e instanceof EntityLivingBase) { - EntityLivingBase player = (EntityLivingBase) e; - - float angle = multiBow.getAngle(player); - - //vec look = new vec(player.getLookVec()); - - //System.out.println(player.rotationPitch); - //System.out.println(player.rotationYaw); - - /* - grappleArrow arrow = new grappleArrow(w, player, false); - arrow.setHeadingFromThrower(player, (float)look.getPitch(), (float)look.getYaw(), 0.0F, arrow.getVelocity(), 0.0F); - w.spawnEntityInWorld(arrow); - */ - - vec anglevec = new vec(0,0,1).rotate_yaw(Math.toRadians(-angle)); - anglevec = anglevec.rotate_pitch(Math.toRadians(-player.rotationPitch)); - anglevec = anglevec.rotate_yaw(Math.toRadians(player.rotationYaw)); - multihookArrow entityarrow = new multihookArrow(w, player, false); - entityarrow.setHeadingFromThrower(player, (float) anglevec.getPitch(), (float)anglevec.getYaw(), 0.0F, entityarrow.func_70182_d(), 0.0F); - - /* - vec pos = vec.positionvec(entityarrow); - pos.add_ip(new vec(0.36, -0.175, 0.45).rotate_yaw(Math.toRadians(player.rotationYaw))); - entityarrow.setPosition(pos.x, pos.y, pos.z); - */ - - w.spawnEntityInWorld(entityarrow); - multihookarrows.add(entityarrow); - - - anglevec = new vec(0,0,1).rotate_yaw(Math.toRadians(angle)); - anglevec = anglevec.rotate_pitch(Math.toRadians(-player.rotationPitch)); - anglevec = anglevec.rotate_yaw(Math.toRadians(player.rotationYaw)); - entityarrow = new multihookArrow(w, player, true); - entityarrow.setHeadingFromThrower(player, (float) anglevec.getPitch(), (float)anglevec.getYaw(), 0.0F, entityarrow.func_70182_d(), 0.0F); - - /* - pos = vec.positionvec(entityarrow); - pos.add_ip(new vec(-0.36, -0.175, 0.45).rotate_yaw(Math.toRadians(player.rotationYaw))); - entityarrow.setPosition(pos.x, pos.y, pos.z); - */ - - w.spawnEntityInWorld(entityarrow); - multihookarrows.add(entityarrow); - } - } - - public static void removeallmultihookarrows() { - for (multihookArrow arrow : multihookarrows) { - if (arrow != null && !arrow.isDead) { - arrow.removeServer(); - } - } - } - - public static void receiveToolConfigMessage(int id, World w) { - Entity e = w.getEntityByID(id); - if (e != null && e instanceof EntityPlayer) { - EntityPlayer player = (EntityPlayer) e; - - ItemStack stack = player.getHeldItem(); - Item item = stack.getItem(); - if (item instanceof multiBow) { - NBTTagCompound compound = stack.getTagCompound(); - if (compound == null) { - compound = new NBTTagCompound(); - stack.setTagCompound(compound); - } - boolean slow = compound.getBoolean("slow"); - slow = !slow; - compound.setBoolean("slow", slow); - - if (slow) { - player.addChatMessage(new ChatComponentText("Set to slow mode")); - } else { - player.addChatMessage(new ChatComponentText("Set to fast mode")); - } - } else if (item instanceof magnetBow) { - NBTTagCompound compound = stack.getTagCompound(); - if (compound == null) { - compound = new NBTTagCompound(); - stack.setTagCompound(compound); - } - int repelconf = compound.getInteger("repelconf"); - repelconf++; - if (repelconf >= REPELCONFIGS) { - repelconf = 0; - } - compound.setInteger("repelconf", repelconf); - -// if (repelconf == REPELSPEED) { -// player.addChatMessage(new TextComponentString("Repel force set to speed based")); - if (repelconf == REPELSTRONG) { - player.addChatMessage(new ChatComponentText("Repel force set to strong")); - } else if (repelconf == REPELWEAK) { - player.addChatMessage(new ChatComponentText("Repel force set to weak")); - } else if (repelconf == REPELNONE) { - player.addChatMessage(new ChatComponentText("Repel force set to off")); - } - } else if (item instanceof smartHookBow) { - NBTTagCompound compound = stack.getSubCompound("grapplemod", true); - boolean slow = compound.getBoolean("slow"); - slow = !slow; - compound.setBoolean("slow", slow); - - if (slow) { - player.addChatMessage(new TextComponentString("Set to slow mode")); - } else { - player.addChatMessage(new TextComponentString("Set to fast mode")); - } - } - } - } -} diff --git a/main/java/com/yyon/grapplinghook/network/PlayerMovementMessage.java b/main/java/com/yyon/grapplinghook/network/PlayerMovementMessage.java deleted file mode 100644 index 2685403..0000000 --- a/main/java/com/yyon/grapplinghook/network/PlayerMovementMessage.java +++ /dev/null @@ -1,110 +0,0 @@ -package com.yyon.grapplinghook.network; - -import io.netty.buffer.ByteBuf; -import net.minecraft.entity.Entity; -import net.minecraft.world.World; -import cpw.mods.fml.common.network.simpleimpl.IMessage; -import cpw.mods.fml.common.network.simpleimpl.IMessageHandler; -import cpw.mods.fml.common.network.simpleimpl.MessageContext; -//* // 1.8 Compatability - - -/* - * This file is part of GrappleMod. - - GrappleMod is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - GrappleMod is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with GrappleMod. If not, see . - */ - -public class PlayerMovementMessage implements IMessage { - - public int entityId; - public double x; - public double y; - public double z; - public double mx; - public double my; - public double mz; - - public PlayerMovementMessage() { - } - - public PlayerMovementMessage(int entityId, double x, double y, double z, double mx, double my, double mz) { - this.entityId = entityId; - this.x = x; - this.y = y; - this.z = z; - this.mx = mx; - this.my = my; - this.mz = mz; - } - - @Override - public void fromBytes(ByteBuf buf) { - try { - this.entityId = buf.readInt(); - this.x = buf.readDouble(); - this.y = buf.readDouble(); - this.z = buf.readDouble(); - this.mx = buf.readDouble(); - this.my = buf.readDouble(); - this.mz = buf.readDouble(); - } catch (Exception e) { - System.out.println(buf); - } - } - - @Override - public void toBytes(ByteBuf buf) { - buf.writeInt(entityId); - buf.writeDouble(x); - buf.writeDouble(y); - buf.writeDouble(z); - buf.writeDouble(mx); - buf.writeDouble(my); - buf.writeDouble(mz); - - } - - public static class Handler implements IMessageHandler { - - public class runner implements Runnable { - PlayerMovementMessage message; - MessageContext ctx; - public runner(PlayerMovementMessage message, MessageContext ctx) { - super(); - this.message = message; - this.ctx = ctx; - } - - @Override - public void run() { - World world = ctx.getServerHandler().playerEntity.worldObj; - Entity entity = world.getEntityByID(message.entityId); - entity.posX = message.x; - entity.posY = message.y; - entity.posZ = message.z; - entity.motionX = message.mx; - entity.motionY = message.my; - entity.motionZ = message.mz; - } - } - - @Override - public IMessage onMessage(PlayerMovementMessage message, MessageContext ctx) { - new runner(message, ctx).run(); - - return null; // no response in this case - } - } -} diff --git a/main/resources/mcmod.info b/main/resources/mcmod.info deleted file mode 100644 index c50dd9e..0000000 --- a/main/resources/mcmod.info +++ /dev/null @@ -1,16 +0,0 @@ -[ -{ - "modid": "grapplemod", - "name": "Grappling hook mod", - "description": "A mod which adds grappling hooks", - "version": "${version}", - "mcversion": "${mcversion}", - "url": "", - "updateUrl": "", - "authorList": ["yyon"], - "credits": "The Forge and FML guys, for making this example", - "logoFile": "", - "screenshots": [], - "dependencies": [] -} -] diff --git a/repositories.gradle b/repositories.gradle new file mode 100644 index 0000000..c884390 --- /dev/null +++ b/repositories.gradle @@ -0,0 +1,5 @@ +// Add any additional repositories for your dependencies here + +repositories { + +} diff --git a/settings.gradle b/settings.gradle new file mode 100644 index 0000000..d5cde6d --- /dev/null +++ b/settings.gradle @@ -0,0 +1,27 @@ + +pluginManagement { + repositories { + maven { + // RetroFuturaGradle + name "GTNH Maven" + url "https://nexus.gtnewhorizons.com/repository/public/" + mavenContent { + includeGroupByRegex("com\\.gtnewhorizons\\..+") + } + } + gradlePluginPortal() + mavenCentral() + mavenLocal() + } +} + +plugins { + id 'com.diffplug.blowdryerSetup' version '1.7.1' + id 'org.gradle.toolchains.foojay-resolver-convention' version '0.7.0' // Provides java toolchains +} + +blowdryerSetup { + repoSubfolder 'gtnhShared' + github('GTNewHorizons/ExampleMod1.7.10', 'tag', '0.2.2') + //devLocal '.' // Use this when testing config updates locally +} diff --git a/main/java/com/yyon/grapplinghook/BlockPos.java b/src/main/java/com/yyon/grapplinghook/BlockPos.java similarity index 100% rename from main/java/com/yyon/grapplinghook/BlockPos.java rename to src/main/java/com/yyon/grapplinghook/BlockPos.java diff --git a/main/java/com/yyon/grapplinghook/ClientProxyClass.java b/src/main/java/com/yyon/grapplinghook/ClientProxyClass.java similarity index 98% rename from main/java/com/yyon/grapplinghook/ClientProxyClass.java rename to src/main/java/com/yyon/grapplinghook/ClientProxyClass.java index 21484a7..120040e 100644 --- a/main/java/com/yyon/grapplinghook/ClientProxyClass.java +++ b/src/main/java/com/yyon/grapplinghook/ClientProxyClass.java @@ -45,12 +45,12 @@ public class ClientProxyClass extends CommonProxyClass { public boolean prevleftclick = false; public HashMap enderlaunchtimer = new HashMap(); public final int reusetime = 50; - + @Override public void preInit(FMLPreInitializationEvent event) { super.preInit(event); } - + /* public ModelResourceLocation grapplinghookloc = new ModelResourceLocation("grapplemod:grapplinghook", "inventory"); public ModelResourceLocation hookshotloc = new ModelResourceLocation("grapplemod:hookshot", "inventory"); @@ -64,7 +64,7 @@ public void preInit(FMLPreInitializationEvent event) { public ModelResourceLocation repelleronloc = new ModelResourceLocation("grapplemod:repelleron", "inventory"); public ModelResourceLocation multihookloc = new ModelResourceLocation("grapplemod:multihook", "inventory"); public ModelResourceLocation multihookropeloc = new ModelResourceLocation("grapplemod:multihookrope", "inventory"); - + private void setgrapplebowtextures(Item item, final ModelResourceLocation notinusetexture, final ModelResourceLocation inusetexture) { ModelLoader.setCustomMeshDefinition(item, new ItemMeshDefinition() { @Override @@ -78,7 +78,7 @@ public ModelResourceLocation getModelLocation(ItemStack stack) { ModelBakery.registerItemVariants(item, notinusetexture); ModelBakery.registerItemVariants(item, inusetexture); } - + private void registerItemModels() { setgrapplebowtextures(grapplemod.grapplebowitem, grapplinghookloc, ropeloc); setgrapplebowtextures(grapplemod.hookshotitem, hookshotloc, hookshotropeloc); @@ -101,7 +101,7 @@ private void registerItemModel(Item item, String modelLocation) { ModelLoader.setCustomModelResourceLocation(item, 0, fullModelLocation); } */ - + @Override public void init(FMLInitializationEvent event, grapplemod grappleModInst) { super.init(event, grappleModInst); @@ -113,16 +113,16 @@ public void init(FMLInitializationEvent event, grapplemod grappleModInst) { // Minecraft.getMinecraft().getRenderItem().getItemModelMesher().register(grapplemod.longfallboots, 0, new ModelResourceLocation("grapplemod:longfallboots", "inventory")); // Minecraft.getMinecraft().getRenderItem().getItemModelMesher().register(grapplemod.enderhookitem, 0, new ModelResourceLocation("grapplemod:enderhook", "inventory")); } - + public crosshairRenderer crosshairrenderer; - + @Override public void postInit(FMLPostInitializationEvent event) { super.postInit(event); - + crosshairrenderer = new crosshairRenderer(); } - + @Override public void getplayermovement(grappleController control, int playerid) { Entity entity = control.entity; @@ -131,7 +131,7 @@ public void getplayermovement(grappleController control, int playerid) { control.receivePlayerMovementMessage(player.moveStrafing, player.moveForward, player.movementInput.jump); } } - + @SubscribeEvent public void onClientTick(TickEvent.ClientTickEvent event) { EntityPlayer player = Minecraft.getMinecraft().thePlayer; @@ -143,9 +143,9 @@ public void onClientTick(TickEvent.ClientTickEvent event) { controller.doClientTick(); } } catch (ConcurrentModificationException e) { - System.out.println("ConcurrentModificationException caught"); + grapplemod.LOGGER.error("ConcurrentModificationException caught"); } - + leftclick = (GameSettings.isKeyDown(Minecraft.getMinecraft().gameSettings.keyBindAttack) && Minecraft.getMinecraft().currentScreen == null); if (prevleftclick != leftclick) { if (player != null) { @@ -162,9 +162,9 @@ public void onClientTick(TickEvent.ClientTickEvent event) { } } } - + prevleftclick = leftclick; - + if (player.onGround) { if (enderlaunchtimer.containsKey(player.getEntityId())) { long timer = player.worldObj.getTotalWorldTime() - enderlaunchtimer.get(player.getEntityId()); @@ -176,7 +176,7 @@ public void onClientTick(TickEvent.ClientTickEvent event) { } } } - + @Override public void launchplayer(EntityPlayer player) { long prevtime; @@ -189,17 +189,17 @@ public void launchplayer(EntityPlayer player) { if (timer > reusetime) { if (player.getHeldItem() != null && (player.getHeldItem().getItem() instanceof enderBow || player.getHeldItem().getItem() instanceof launcherItem)) { enderlaunchtimer.put(player.getEntityId(), player.worldObj.getTotalWorldTime()); - + vec facing = new vec(player.getLookVec()); // vec playermotion = vec.motionvec(player); // vec newvec = playermotion.add(facing.mult(3)); - + /* if (!grapplemod.controllers.containsKey(player.getEntityId())) { player.motionX = newvec.x; player.motionY = newvec.y; player.motionZ = newvec.z; - + if (player instanceof EntityPlayerMP) { ((EntityPlayerMP) player).connection.sendPacket(new SPacketEntityVelocity(player)); } else { @@ -219,14 +219,14 @@ public void launchplayer(EntityPlayer player) { } } } - + @Override public void resetlaunchertime(int playerid) { if (enderlaunchtimer.containsKey(playerid)) { enderlaunchtimer.put(playerid, (long) 0); } } - + @Override public boolean isSneaking(Entity entity) { if (entity == Minecraft.getMinecraft().thePlayer) { @@ -235,7 +235,7 @@ public boolean isSneaking(Entity entity) { return entity.isSneaking(); } } - + @Override public void blockbreak(BreakEvent event) { BlockPos pos = new BlockPos(event.x, event.y, event.z); @@ -244,12 +244,12 @@ public void blockbreak(BreakEvent event) { grappleController control = grapplemod.controllerpos.get(pos); control.unattach(); - + grapplemod.controllerpos.remove(pos); } } } - + @Override public void handleDeath(Entity entity) { int id = entity.getEntityId(); @@ -258,13 +258,13 @@ public void handleDeath(Entity entity) { controller.unattach(); } } - + @Override public String getkeyname(CommonProxyClass.keys keyenum) { KeyBinding binding = null; - + GameSettings gs = Minecraft.getMinecraft().gameSettings; - + if (keyenum == keys.keyBindAttack) { binding = gs.keyBindAttack; } else if (keyenum == keys.keyBindBack) { @@ -282,11 +282,11 @@ public String getkeyname(CommonProxyClass.keys keyenum) { } else if (keyenum == keys.keyBindUseItem) { binding = gs.keyBindUseItem; } - + if (binding == null) { return ""; } - + String displayname; int keycode = binding.getKeyCode(); if (keycode == -99) { diff --git a/main/java/com/yyon/grapplinghook/CommonProxyClass.java b/src/main/java/com/yyon/grapplinghook/CommonProxyClass.java similarity index 100% rename from main/java/com/yyon/grapplinghook/CommonProxyClass.java rename to src/main/java/com/yyon/grapplinghook/CommonProxyClass.java diff --git a/main/java/com/yyon/grapplinghook/ServerProxyClass.java b/src/main/java/com/yyon/grapplinghook/ServerProxyClass.java similarity index 100% rename from main/java/com/yyon/grapplinghook/ServerProxyClass.java rename to src/main/java/com/yyon/grapplinghook/ServerProxyClass.java diff --git a/main/java/com/yyon/grapplinghook/controllers/airfrictionController.java b/src/main/java/com/yyon/grapplinghook/controllers/airfrictionController.java similarity index 100% rename from main/java/com/yyon/grapplinghook/controllers/airfrictionController.java rename to src/main/java/com/yyon/grapplinghook/controllers/airfrictionController.java diff --git a/main/java/com/yyon/grapplinghook/controllers/enderController.java b/src/main/java/com/yyon/grapplinghook/controllers/enderController.java similarity index 96% rename from main/java/com/yyon/grapplinghook/controllers/enderController.java rename to src/main/java/com/yyon/grapplinghook/controllers/enderController.java index 90e7fd6..c501a49 100644 --- a/main/java/com/yyon/grapplinghook/controllers/enderController.java +++ b/src/main/java/com/yyon/grapplinghook/controllers/enderController.java @@ -23,20 +23,20 @@ public class enderController extends grappleController { public final double playermovementmult = 1; - + public enderController(int arrowId, int entityId, World world, vec pos, int maxlen, int id) { super(arrowId, entityId, world, pos, maxlen, id); } public void receiveGrappleClick(boolean leftclick) { super.receiveGrappleClick(leftclick); - + } - + /* @Override public void receiveEnderLaunch(double x, double y, double z) { -// System.out.println("now launching"); +// grapplemod.LOGGER.debug("now launching"); } */ } diff --git a/main/java/com/yyon/grapplinghook/controllers/grappleController.java b/src/main/java/com/yyon/grapplinghook/controllers/grappleController.java similarity index 97% rename from main/java/com/yyon/grapplinghook/controllers/grappleController.java rename to src/main/java/com/yyon/grapplinghook/controllers/grappleController.java index bbf6969..adcb52e 100644 --- a/main/java/com/yyon/grapplinghook/controllers/grappleController.java +++ b/src/main/java/com/yyon/grapplinghook/controllers/grappleController.java @@ -32,50 +32,50 @@ public class grappleController { public int entityId; public World world; public vec pos; - + public grappleArrow arrow; public Entity entity; - + public boolean attached = true; - + public double r; public vec motion; - + public double playerforward = 0; public double playerstrafe = 0; public boolean playerjump = false; public boolean waitingonplayerjump = false; public vec playermovement_unrotated = new vec(0,0,0); public vec playermovement = new vec(0,0,0); - + // public int counter = 0; public int ongroundtimer = 0; public int maxongroundtimer = 3; - + public int maxlen; - + public int controllerid; - + public final double playermovementmult = 0.5; - + public grappleController(int arrowId, int entityId, World world, vec pos, int maxlen, int controllerid) { this.arrowId = arrowId; this.entityId = entityId; this.world = world; this.pos = pos; this.maxlen = maxlen; - + this.controllerid = controllerid; - + this.entity = world.getEntityByID(entityId); - + this.r = this.pos.sub(vec.positionvec(entity)).length(); this.motion = vec.motionvec(entity); - + this.ongroundtimer = 0; - + grapplemod.registerController(this.entityId, this); - + if (arrowId != -1) { Entity arrowentity = world.getEntityByID(arrowId); if (arrowentity != null && !arrowentity.isDead && arrowentity instanceof grappleArrow) { @@ -83,24 +83,24 @@ public grappleController(int arrowId, int entityId, World world, vec pos, int ma } } } - + public void unattach() { if (grapplemod.controllers.containsValue(this)) { this.attached = false; - + grapplemod.unregisterController(this.entityId); - + if (this.controllerid != grapplemod.AIRID) { grapplemod.network.sendToServer(new GrappleEndMessage(this.entityId, this.arrowId)); grapplemod.createControl(grapplemod.AIRID, -1, this.entityId, this.entity.worldObj, new vec(0,0,0), 0, null); } } } - + public grappleArrow getArrow() { return (grappleArrow) world.getEntityByID(arrowId); } - + public void doClientTick() { if (this.attached) { if (this.entity == null || this.entity.isDead) { @@ -111,7 +111,7 @@ public void doClientTick() { } } } - + public void receivePlayerMovementMessage(float strafe, float forward, boolean jump) { playerforward = forward; @@ -125,7 +125,7 @@ public void receivePlayerMovementMessage(float strafe, playermovement_unrotated = new vec(strafe, 0, forward); playermovement = playermovement_unrotated.rotate_yaw((float) (this.entity.rotationYaw * (Math.PI / 180.0))); } - + public boolean isjumping() { if (playerjump && waitingonplayerjump) { waitingonplayerjump = false; @@ -133,36 +133,36 @@ public boolean isjumping() { } return false; } - + public void updatePlayerPos() { Entity entity = this.entity; - + if (this.attached) { if(entity != null) { if (true) { this.normalGround(); this.normalCollisions(); // this.applyAirFriction(); - + vec arrowpos = this.pos;//this.getPositionVector(); vec playerpos = vec.positionvec(entity); // Vec3 playermotion = new Vec3(entity.motionX, entity.motionY, entity.motionZ); - + vec oldspherevec = playerpos.sub(arrowpos); vec spherevec = oldspherevec.changelen(r); vec spherechange = spherevec.sub(oldspherevec); // Vec3 spherepos = spherevec.add(arrowpos); - + vec additionalmotion; if (arrowpos.sub(playerpos).length() < this.r) { additionalmotion = new vec(0,0,0); } else { additionalmotion = spherechange;//new Vec3(0,0,0); } - + double dist = oldspherevec.length(); this.calctaut(dist); - + if (entity instanceof EntityPlayer) { EntityPlayer player = (EntityPlayer) entity; if (this.isjumping()) { @@ -176,11 +176,11 @@ public void updatePlayerPos() { if (motion.dot(motiontorwards) < 0) { motion.add_ip(motiontorwards); } - + vec newmotion = dampenmotion(motion, motiontorwards); motion = new vec(newmotion.x, motion.y, newmotion.z); // motion = multvec(motion, 0.98); - + if (this.playerforward != 0) { if (dist < maxlen || this.playerforward > 0 || maxlen == 0) { // double motionup = this.playerforward; @@ -198,26 +198,26 @@ public void updatePlayerPos() { applyPlayerMovement(); } } - + if (!(this.ongroundtimer > 0)) { motion.add_ip(0, -0.05, 0); } - + vec newmotion = motion.add(additionalmotion); - + if (arrowpos.sub(playerpos.add(motion)).length() > r) { // moving away motion = motion.removealong(spherevec); } - + // entity.setVelocity(newmotion.xCoord, newmotion.yCoord, newmotion.zCoord); entity.motionX = newmotion.x; entity.motionY = newmotion.y; entity.motionZ = newmotion.z; - + // if (entity instanceof EntityPlayerMP) { - + // ((EntityPlayerMP) entity).playerNetServerHandler.sendPacket(new S12PacketEntityVelocity(entity)); - + /* counter++; if (counter > 100) { @@ -226,15 +226,15 @@ public void updatePlayerPos() { } */ // } - + // entity.fallDistance = 0; - + this.updateServerPos(); } } } } - + public void calctaut(double dist) { if (this.arrow != null) { if (dist < this.r) { @@ -299,9 +299,9 @@ public void dojump(Entity player, double jumppower) { if (jumppower < 0) { jumppower = 0; } - + this.unattach(); - + if (jumppower > 0) { if (jumppower > player.motionY + jumppower) { player.motionY = jumppower; @@ -309,10 +309,10 @@ public void dojump(Entity player, double jumppower) { player.motionY += jumppower; } } - + this.updateServerPos(); } - + public void dojump(Entity player, vec spherevec) { double maxjump = 1; vec jump = new vec(0, maxjump, 0); @@ -320,14 +320,14 @@ public void dojump(Entity player, vec spherevec) { jump = jump.proj(spherevec); } double jumppower = jump.y; - + if (spherevec != null && spherevec.y > 0) { jumppower = 0; } if ((this.arrow != null) && r < 1 && (player.posY < this.arrow.posY)) { jumppower = maxjump; } - + this.dojump(player, jumppower); } @@ -336,13 +336,13 @@ public vec dampenmotion(vec motion, vec forward) { double dampening = 0.05; return new vec(newmotion.x*dampening + motion.x*(1-dampening), newmotion.y*dampening + motion.y*(1-dampening), newmotion.z*dampening + motion.z*(1-dampening)); } - + public void updateServerPos() { grapplemod.network.sendToServer(new PlayerMovementMessage(this.entityId, this.entity.posX, this.entity.posY, this.entity.posZ, this.entity.motionX, this.entity.motionY, this.entity.motionZ)); } - + // Vector stuff: - + public void receiveGrappleClick(boolean leftclick) { if (!leftclick) { this.unattach(); @@ -355,18 +355,18 @@ public void receiveEnderLaunch(double x, double y, double z) { this.entity.motionY = this.motion.y; this.entity.motionZ = this.motion.z; } - + public void applyAirFriction() { double vel = this.motion.length(); double dragforce = vel*vel / 200; - + vec airfric = new vec(this.motion.x, this.motion.y, this.motion.z); airfric.changelen_ip(-dragforce); this.motion.add_ip(airfric); } - + public void applyPlayerMovement() { - System.out.println(motion.length()); + //grapplemod.LOGGER.debug(motion.length()); motion.add_ip(this.playermovement.changelen(0.015 + motion.length() * 0.01));//0.02 * playermovementmult)); } } diff --git a/main/java/com/yyon/grapplinghook/controllers/hookControl.java b/src/main/java/com/yyon/grapplinghook/controllers/hookControl.java similarity index 94% rename from main/java/com/yyon/grapplinghook/controllers/hookControl.java rename to src/main/java/com/yyon/grapplinghook/controllers/hookControl.java index 6a5b0d7..08d5fc6 100644 --- a/main/java/com/yyon/grapplinghook/controllers/hookControl.java +++ b/src/main/java/com/yyon/grapplinghook/controllers/hookControl.java @@ -32,22 +32,22 @@ public hookControl(int arrowId, int entityId, World world, vec pos, int maxlen, public double acceleration = 0.2; public float oldstepheight; public final double playermovementmult = 1; - + @Override public void updatePlayerPos() { - + /* super.updatePlayerPos(theplayer); if (r > 1) { r -= 1; } */ - + Entity entity = this.entity; - -// System.out.println(entity == theplayer); -// System.out.println(entity.worldObj.isRemote); - + +// grapplemod.LOGGER.debug(entity == theplayer); +// grapplemod.LOGGER.debug(entity.worldObj.isRemote); + if (this.attached) { if(entity != null && entity instanceof EntityPlayer) { EntityPlayer player = (EntityPlayer) entity; @@ -57,17 +57,17 @@ public void updatePlayerPos() { // this.normalGround(); this.normalCollisions(); // this.applyAirFriction(); - + vec arrowpos = this.pos; vec playerpos = vec.positionvec(player); - + vec oldspherevec = playerpos.sub(arrowpos); vec spherevec = oldspherevec.changelen(r); // Vec3 spherechange = spherevec.subtract(oldspherevec); // Vec3 spherepos = spherevec.add(arrowpos); - + double dist = oldspherevec.length(); - + if (this.isjumping()) { this.dojump(player, spherevec); return; @@ -82,14 +82,14 @@ public void updatePlayerPos() { } else { applyPlayerMovement(); } - + vec newmotion; - + if (dist < 4) { if (motion.length() > 0.3) { motion.mult_ip(0.6); } - + // if (this.playermovement.lengthVector() > 0.05) { // this.unattach(); // } @@ -98,19 +98,19 @@ public void updatePlayerPos() { entity.motionY = 0; entity.motionZ = 0; this.updateServerPos(); - + // this.unattach(); } } - + motion.add_ip(arrowpos.sub(playerpos).changelen(acceleration)); - + double speed = motion.proj(oldspherevec).length(); - + if (speed > maxspeed) { motion.changelen_ip(maxspeed); } - + /* if (!player.onGround) { motion = motion.addVector(0, -0.05, 0); @@ -120,29 +120,29 @@ public void updatePlayerPos() { } } */ - + newmotion = motion; - + vec motiontorwards = spherevec.changelen(-1); motion = dampenmotion(motion, motiontorwards); - + // entity.setVelocity(newmotion.xCoord, newmotion.yCoord, newmotion.zCoord); entity.motionX = newmotion.x; entity.motionY = newmotion.y; entity.motionZ = newmotion.z; - + // if (player instanceof EntityPlayerMP) { - + // ((EntityPlayerMP) entity).playerNetServerHandler.sendPacket(new S12PacketEntityVelocity(entity)); // } - + player.fallDistance = 0; - + this.updateServerPos(); } } } } - + } diff --git a/main/java/com/yyon/grapplinghook/controllers/magnetController.java b/src/main/java/com/yyon/grapplinghook/controllers/magnetController.java similarity index 96% rename from main/java/com/yyon/grapplinghook/controllers/magnetController.java rename to src/main/java/com/yyon/grapplinghook/controllers/magnetController.java index ea32641..1da1baa 100644 --- a/main/java/com/yyon/grapplinghook/controllers/magnetController.java +++ b/src/main/java/com/yyon/grapplinghook/controllers/magnetController.java @@ -31,7 +31,7 @@ public class magnetController extends grappleController { public int repelconf = 0; public final double playermovementmult = 1.5; - + public magnetController(int arrowId, int entityId, World world, vec pos, int maxlen, int id, int repelconf) { super(arrowId, entityId, world, pos, maxlen, id); this.repelconf = repelconf; @@ -39,41 +39,41 @@ public magnetController(int arrowId, int entityId, World world, vec pos, int max public void receiveGrappleClick(boolean leftclick) { super.receiveGrappleClick(leftclick); - + } - + HashMap blockcache = new HashMap(); - + public void updatePlayerPos() { Entity entity = this.entity; - + if (this.attached) { if(entity != null) { if (true) { this.normalGround(); this.normalCollisions(); // this.applyAirFriction(); - + vec arrowpos = this.pos; vec playerpos = vec.positionvec(entity); - - + + vec oldspherevec = playerpos.sub(arrowpos); vec spherevec = oldspherevec.changelen(r); vec spherechange = spherevec.sub(oldspherevec); - + vec additionalmotion; if (arrowpos.sub(playerpos).length() < this.r) { additionalmotion = new vec(0,0,0); } else { additionalmotion = spherechange; } - + double dist = oldspherevec.length(); this.calctaut(dist); - + boolean domagnet = true; - + if (entity instanceof EntityPlayer) { EntityPlayer player = (EntityPlayer) entity; if (this.isjumping()) { @@ -87,10 +87,10 @@ public void updatePlayerPos() { if (motion.dot(motiontorwards) < 0) { motion.add_ip(motiontorwards); } - + vec newmotion = dampenmotion(motion, motiontorwards); motion = new vec(newmotion.x, motion.y, newmotion.z); - + if (this.playerforward != 0) { if (dist < maxlen || this.playerforward > 0 || maxlen == 0) { additionalmotion = new vec(0, this.playerforward, 0); @@ -106,55 +106,55 @@ public void updatePlayerPos() { applyPlayerMovement(); } } - + if (domagnet && this.repelconf != grapplemod.REPELNONE) { vec blockpush = check(playerpos, entity.worldObj); - + // if (this.repelconf == grapplemod.REPELSPEED) { // blockpush.mult_ip(0.5 + motion.length()/2);//0.5);//0.005); -// System.out.println(); +// grapplemod.LOGGER.debug(); if (this.repelconf == grapplemod.REPELSTRONG) { blockpush.mult_ip(1.5); } else if (this.repelconf == grapplemod.REPELWEAK) { blockpush.mult_ip(0.5); } // blockpush.mult_ip(motion.length()); - + // blockpush.print(); // vec facing = new vec(entity.getLookVec()); // blockpush.removealong(facing); this.motion.add_ip(blockpush); } - + if (!entity.onGround) { motion.add_ip(0, -0.05, 0); } - + vec newmotion = motion.add(additionalmotion); - + if (arrowpos.sub(playerpos.add(motion)).length() > r) { // moving away motion = motion.removealong(spherevec); } - + entity.motionX = newmotion.x; entity.motionY = newmotion.y; entity.motionZ = newmotion.z; - + this.updateServerPos(); } } } } - + public final int radius = 10; public final double maxpush = 0.3;//0.25; - + public vec check(vec p, World w) { // long startTime = System.nanoTime(); - + p = p.add(0.0, 0.75, 0.0); vec v = new vec(0, 0, 0); - + /* for (int x = (int)p.x - radius; x <= (int)p.x + radius; x++) { for (int y = (int)p.y - radius; y <= (int)p.y + radius; y++) { @@ -172,9 +172,9 @@ public vec check(vec p, World w) { } } */ - + double t = (1.0 + Math.sqrt(5.0)) / 2.0; - + BlockPos pos = new BlockPos((int) Math.floor(p.x), (int) Math.floor(p.y), (int) Math.floor(p.z)); if (hasblock(pos, w)) { v.add_ip(0, 1, 0); @@ -192,19 +192,19 @@ public vec check(vec p, World w) { v.add_ip(vecdist(p, new vec(-t, 0, -1), w)); v.add_ip(vecdist(p, new vec(-t, 0, 1), w)); } - + if (v.length() > maxpush) { v.changelen_ip(maxpush); } - + // long endTime = System.nanoTime(); // long duration = (endTime - startTime); //divide by 1000000 to get milliseconds. -// System.out.println(duration); - +// grapplemod.LOGGER.debug(duration); + return v; } - + public vec vecdist(vec p, vec v, World w) { for (double i = 0.5; i < 10; i += 0.5) { vec v2 = v.changelen(i); @@ -215,7 +215,7 @@ public vec vecdist(vec p, vec v, World w) { return v3; } } - + return new vec(0, 0, 0); } @@ -226,7 +226,7 @@ public boolean hasblock(BlockPos pos, World w) { if (!(b.isAir(w, pos.x, pos.y, pos.z))) { isblock = true; } - + // blockcache.put(pos, (Boolean) isblock); return isblock; // } else { diff --git a/main/java/com/yyon/grapplinghook/controllers/multihookController.java b/src/main/java/com/yyon/grapplinghook/controllers/multihookController.java similarity index 100% rename from main/java/com/yyon/grapplinghook/controllers/multihookController.java rename to src/main/java/com/yyon/grapplinghook/controllers/multihookController.java diff --git a/main/java/com/yyon/grapplinghook/controllers/repelController.java b/src/main/java/com/yyon/grapplinghook/controllers/repelController.java similarity index 100% rename from main/java/com/yyon/grapplinghook/controllers/repelController.java rename to src/main/java/com/yyon/grapplinghook/controllers/repelController.java diff --git a/main/java/com/yyon/grapplinghook/controllers/smartHookControl.java b/src/main/java/com/yyon/grapplinghook/controllers/smartHookControl.java similarity index 100% rename from main/java/com/yyon/grapplinghook/controllers/smartHookControl.java rename to src/main/java/com/yyon/grapplinghook/controllers/smartHookControl.java diff --git a/main/java/com/yyon/grapplinghook/crosshairRenderer.java b/src/main/java/com/yyon/grapplinghook/crosshairRenderer.java similarity index 100% rename from main/java/com/yyon/grapplinghook/crosshairRenderer.java rename to src/main/java/com/yyon/grapplinghook/crosshairRenderer.java diff --git a/main/java/com/yyon/grapplinghook/entities/RenderGrappleArrow.java b/src/main/java/com/yyon/grapplinghook/entities/RenderGrappleArrow.java similarity index 100% rename from main/java/com/yyon/grapplinghook/entities/RenderGrappleArrow.java rename to src/main/java/com/yyon/grapplinghook/entities/RenderGrappleArrow.java diff --git a/main/java/com/yyon/grapplinghook/entities/enderArrow.java b/src/main/java/com/yyon/grapplinghook/entities/enderArrow.java similarity index 95% rename from main/java/com/yyon/grapplinghook/entities/enderArrow.java rename to src/main/java/com/yyon/grapplinghook/entities/enderArrow.java index 90c0c5a..3a8afeb 100644 --- a/main/java/com/yyon/grapplinghook/entities/enderArrow.java +++ b/src/main/java/com/yyon/grapplinghook/entities/enderArrow.java @@ -27,19 +27,19 @@ public class enderArrow extends grappleArrow public enderArrow(World worldIn) { super(worldIn); } - + public enderArrow(World worldIn, EntityLivingBase shooter, boolean righthand) { super(worldIn, shooter, righthand); } - + @Override protected float func_70182_d() { return 20F; } - - + + @Override public int getControlId() { return grapplemod.ENDERID; @@ -47,7 +47,7 @@ public int getControlId() { /* @Override public void createControl() { - System.out.println("Creating ender controller"); + grapplemod.LOGGER.debug("Creating ender controller"); this.control = new enderController(this.getEntityId(), this.shootingEntity.getEntityId(), this.worldObj, new Vec3(this.posX, this.posY, this.posZ)); } */ diff --git a/main/java/com/yyon/grapplinghook/entities/grappleArrow.java b/src/main/java/com/yyon/grapplinghook/entities/grappleArrow.java similarity index 97% rename from main/java/com/yyon/grapplinghook/entities/grappleArrow.java rename to src/main/java/com/yyon/grapplinghook/entities/grappleArrow.java index a2d26e1..7a10917 100644 --- a/main/java/com/yyon/grapplinghook/entities/grappleArrow.java +++ b/src/main/java/com/yyon/grapplinghook/entities/grappleArrow.java @@ -46,29 +46,29 @@ public class grappleArrow extends EntityThrowable implements IEntityAdditionalSp { public Entity shootingEntity = null; public int shootingEntityID; - + private boolean firstattach = false; public vec thispos; - + public boolean righthand = true; - + public boolean attached = false; - + public double taut = 1; - + public boolean ignoreFrustumCheck = true; - + public grappleArrow(World worldIn) { super(worldIn); } - + public grappleArrow(World worldIn, EntityLivingBase shooter, boolean righthand) { super(worldIn, shooter); - + this.shootingEntity = shooter; this.shootingEntityID = this.shootingEntity.getEntityId(); - + /* double x = 0.36; if (righthand) {x = -0.36;} @@ -79,18 +79,18 @@ public grappleArrow(World worldIn, EntityLivingBase shooter, grapplemod.updateMaxLen(worldIn); grapplemod.updateGrapplingBlocks(worldIn); - + this.righthand = righthand; } - + @Override public void onEntityUpdate(){ super.onEntityUpdate(); - + if (this.shootingEntityID == 0) { // removes ghost grappling hooks this.kill(); } - + if (this.firstattach) { this.motionX = 0; this.motionY = 0; @@ -98,13 +98,13 @@ public void onEntityUpdate(){ this.firstattach = false; super.setPosition(this.thispos.x, this.thispos.y, this.thispos.z); } - - + + if (this.toofaraway()) { this.removeServer(); } } - + @Override @SideOnly(Side.CLIENT) public boolean isInRangeToRender3d(double x, double y, double z) { @@ -122,7 +122,7 @@ public boolean isInRangeToRenderDist(double distance) { @Override @SideOnly(Side.CLIENT) public AxisAlignedBB getRenderBoundingBox() { - return new AxisAlignedBB(-RenderBoundingBoxSize, -RenderBoundingBoxSize, -RenderBoundingBoxSize, + return new AxisAlignedBB(-RenderBoundingBoxSize, -RenderBoundingBoxSize, -RenderBoundingBoxSize, RenderBoundingBoxSize, RenderBoundingBoxSize, RenderBoundingBoxSize); } */ @@ -150,15 +150,15 @@ public void setPosition(double x, double y, double z) { } super.setPosition(x, y, z); } - - + + @Override public void writeSpawnData(ByteBuf data) { data.writeInt(this.shootingEntity != null ? this.shootingEntity.getEntityId() : 0); data.writeBoolean(this.righthand); } - + @Override public void readSpawnData(ByteBuf data) { @@ -166,11 +166,11 @@ public void readSpawnData(ByteBuf data) this.shootingEntity = this.worldObj.getEntityByID(this.shootingEntityID); this.righthand = data.readBoolean(); } - + public void remove() { this.kill(); } - + @Override public String toString() { return super.toString() + String.valueOf(System.identityHashCode(this)) + "]"; @@ -186,23 +186,23 @@ protected void onImpact(MovingObjectPosition movingobjectposition) { if (entityhit == this.shootingEntity) { return; } - + vec playerpos = vec.positionvec(this.shootingEntity); vec entitypos = vec.positionvec(entityhit); vec yank = playerpos.sub(entitypos).mult(0.4); entityhit.addVelocity(yank.x, Math.min(yank.y, 2), yank.z); - + this.removeServer(); return; } - + BlockPos blockpos = null; - + if (movingobjectposition.typeOfHit == MovingObjectPosition.MovingObjectType.BLOCK) { blockpos = new BlockPos(movingobjectposition.blockX, movingobjectposition.blockY, movingobjectposition.blockZ); } vec vec3 = null; - + if (movingobjectposition != null) { vec3 = new vec(movingobjectposition.hitVec.xCoord, movingobjectposition.hitVec.yCoord, movingobjectposition.hitVec.zCoord); @@ -211,13 +211,13 @@ protected void onImpact(MovingObjectPosition movingobjectposition) { } } } - + public void serverAttach(BlockPos blockpos, vec pos, int sideHit) { if (this.attached) { return; } this.attached = true; - + if (blockpos != null) { if (!grapplemod.anyblocks) { Block block = this.worldObj.getBlock(blockpos.x, blockpos.y, blockpos.z); @@ -229,18 +229,18 @@ public void serverAttach(BlockPos blockpos, vec pos, int sideHit) { } } } - + vec vec3 = vec.positionvec(this); vec3.add_ip(vec.motionvec(this)); if (pos != null) { vec3 = pos; - + this.setPosition(vec3.x, vec3.y, vec3.z); } - + //west -x //north -z - System.out.println(sideHit); + //grapplemod.LOGGER.debug(sideHit); if (sideHit == 0) { // bottom this.posY -= 0.3; // } else if (sideHit == 1) { // top @@ -257,18 +257,18 @@ public void serverAttach(BlockPos blockpos, vec pos, int sideHit) { if (this.toofaraway()) { - System.out.println("TOOFAR"); + //grapplemod.LOGGER.error("TOOFAR"); return; } - + this.motionX = 0; this.motionY = 0; this.motionZ = 0; - + this.thispos = vec.positionvec(this); this.firstattach = true; grapplemod.attached.add(this.shootingEntityID); - + grapplemod.sendtocorrectclient(new GrappleAttachMessage(this.getEntityId(), this.posX, this.posY, this.posZ, this.getControlId(), this.shootingEntityID, grapplemod.grapplingLength, blockpos), this.shootingEntityID, this.worldObj); if (this.shootingEntity instanceof EntityPlayerMP) { // fixes strange bug in LAN EntityPlayerMP sender = (EntityPlayerMP) this.shootingEntity; @@ -282,22 +282,22 @@ public void serverAttach(BlockPos blockpos, vec pos, int sideHit) { } } } - + public void clientAttach(double x, double y, double z) { this.setAttachPos(x, y, z); - + if (this.shootingEntity instanceof EntityPlayer) { grapplemod.proxy.resetlaunchertime(this.shootingEntityID); } } - - + + @Override protected float getGravityVelocity() { return 0F; } - + @Override protected float func_70182_d() { @@ -309,7 +309,7 @@ public void removeServer() { this.shootingEntityID = 0; } - + public int getControlId() { return grapplemod.GRAPPLEID; } diff --git a/main/java/com/yyon/grapplinghook/entities/hookArrow.java b/src/main/java/com/yyon/grapplinghook/entities/hookArrow.java similarity index 100% rename from main/java/com/yyon/grapplinghook/entities/hookArrow.java rename to src/main/java/com/yyon/grapplinghook/entities/hookArrow.java diff --git a/main/java/com/yyon/grapplinghook/entities/magnetArrow.java b/src/main/java/com/yyon/grapplinghook/entities/magnetArrow.java similarity index 100% rename from main/java/com/yyon/grapplinghook/entities/magnetArrow.java rename to src/main/java/com/yyon/grapplinghook/entities/magnetArrow.java diff --git a/main/java/com/yyon/grapplinghook/entities/multihookArrow.java b/src/main/java/com/yyon/grapplinghook/entities/multihookArrow.java similarity index 100% rename from main/java/com/yyon/grapplinghook/entities/multihookArrow.java rename to src/main/java/com/yyon/grapplinghook/entities/multihookArrow.java diff --git a/main/java/com/yyon/grapplinghook/entities/smartHookArrow.java b/src/main/java/com/yyon/grapplinghook/entities/smartHookArrow.java similarity index 100% rename from main/java/com/yyon/grapplinghook/entities/smartHookArrow.java rename to src/main/java/com/yyon/grapplinghook/entities/smartHookArrow.java diff --git a/main/java/com/yyon/grapplinghook/grapplemod.java b/src/main/java/com/yyon/grapplinghook/grapplemod.java similarity index 93% rename from main/java/com/yyon/grapplinghook/grapplemod.java rename to src/main/java/com/yyon/grapplinghook/grapplemod.java index 6d8121a..0b809ba 100644 --- a/main/java/com/yyon/grapplinghook/grapplemod.java +++ b/src/main/java/com/yyon/grapplinghook/grapplemod.java @@ -5,6 +5,7 @@ import java.util.HashSet; import java.util.Random; +import com.yyon.grapplemod.Tags; import net.minecraft.block.Block; import net.minecraft.entity.Entity; import net.minecraft.entity.EntityLivingBase; @@ -64,6 +65,8 @@ import cpw.mods.fml.common.registry.EntityRegistry; import cpw.mods.fml.common.registry.GameRegistry; import cpw.mods.fml.relauncher.Side; +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; /* * This file is part of GrappleMod. @@ -86,14 +89,12 @@ // Pull mobs // Attach 2 things together -@Mod(modid = grapplemod.MODID, version = grapplemod.VERSION) +@Mod(modid = Tags.MODID, version = Tags.VERSION) public class grapplemod { - public grapplemod(){} + public static final Logger LOGGER = LogManager.getLogger("grapplemod"); - public static final String MODID = "grapplemod"; - - public static final String VERSION = "1.7.10-v10"; + public grapplemod(){} public static Item grapplebowitem; public static Item hookshotitem; @@ -104,15 +105,15 @@ public grapplemod(){} public static Item magnetbowitem; public static Item repelleritem; public static Item multihookitem; - + public static Object instance; - + public static SimpleNetworkWrapper network; - + public static HashMap controllers = new HashMap(); // client side public static HashMap controllerpos = new HashMap(); public static HashSet attached = new HashSet(); // server side - + private static int controllerid = 0; public static int GRAPPLEID = controllerid++; public static int ENDERID = controllerid++; @@ -123,59 +124,59 @@ public grapplemod(){} public static int MULTISUBID = controllerid++; public static int AIRID = controllerid++; public static int SMARTHOOKID = controllerid++; - + public static int REPELCONFIGS = 0; // public static int REPELSPEED = REPELCONFIGS++; public static int REPELSTRONG = REPELCONFIGS++; public static int REPELWEAK = REPELCONFIGS++; public static int REPELNONE = REPELCONFIGS++; - + public static int grapplingLength = 0; public static boolean anyblocks = true; public static ArrayList grapplingblocks; public static boolean removeblocks = false; - + @SidedProxy(clientSide="com.yyon.grapplinghook.ClientProxyClass", serverSide="com.yyon.grapplinghook.ServerProxyClass") public static CommonProxyClass proxy; - + @EventHandler public void load(FMLInitializationEvent event){ GameRegistry.addRecipe(new ItemStack(grapplebowitem, 1), new Object[]{ - "X2", - "4X", Character.valueOf('2'), new ItemStack(Items.iron_pickaxe, 1), Character.valueOf('4'), new ItemStack(Items.lead, 1), + "X2", + "4X", Character.valueOf('2'), new ItemStack(Items.iron_pickaxe, 1), Character.valueOf('4'), new ItemStack(Items.lead, 1), }); GameRegistry.addRecipe(new ItemStack(hookshotitem, 1), new Object[]{ - "X2", - "4X", Character.valueOf('2'), new ItemStack(grapplebowitem, 1), Character.valueOf('4'), new ItemStack(Blocks.piston, 1), + "X2", + "4X", Character.valueOf('2'), new ItemStack(grapplebowitem, 1), Character.valueOf('4'), new ItemStack(Blocks.piston, 1), }); GameRegistry.addRecipe(new ItemStack(smarthookitem, 1), new Object[]{ - "X2", - "4X", Character.valueOf('2'), new ItemStack(hookshotitem, 1), Character.valueOf('4'), new ItemStack(Items.redstone, 1), + "X2", + "4X", Character.valueOf('2'), new ItemStack(hookshotitem, 1), Character.valueOf('4'), new ItemStack(Items.redstone, 1), }); GameRegistry.addRecipe(new ItemStack(launcheritem, 1), new Object[]{ - "X2", - "4X", Character.valueOf('2'), new ItemStack(Items.ender_pearl, 1), Character.valueOf('4'), new ItemStack(Blocks.piston, 1), + "X2", + "4X", Character.valueOf('2'), new ItemStack(Items.ender_pearl, 1), Character.valueOf('4'), new ItemStack(Blocks.piston, 1), }); GameRegistry.addRecipe(new ItemStack(enderhookitem, 1), new Object[]{ - "X2", - "4X", Character.valueOf('2'), new ItemStack(grapplebowitem, 1), Character.valueOf('4'), new ItemStack(launcheritem, 1), + "X2", + "4X", Character.valueOf('2'), new ItemStack(grapplebowitem, 1), Character.valueOf('4'), new ItemStack(launcheritem, 1), }); GameRegistry.addRecipe(new ItemStack(repelleritem, 1), new Object[]{ - "X2X", + "X2X", "242", - "X2X", Character.valueOf('2'), new ItemStack(Items.iron_ingot, 1), Character.valueOf('4'), new ItemStack(Items.compass, 1), + "X2X", Character.valueOf('2'), new ItemStack(Items.iron_ingot, 1), Character.valueOf('4'), new ItemStack(Items.compass, 1), }); GameRegistry.addRecipe(new ItemStack(magnetbowitem, 1), new Object[]{ - "X2", - "4X", Character.valueOf('2'), new ItemStack(grapplebowitem, 1), Character.valueOf('4'), new ItemStack(repelleritem, 1), + "X2", + "4X", Character.valueOf('2'), new ItemStack(grapplebowitem, 1), Character.valueOf('4'), new ItemStack(repelleritem, 1), }); GameRegistry.addRecipe(new ItemStack(longfallboots, 1), new Object[]{ - "2", - "4", Character.valueOf('2'), new ItemStack(Items.diamond_boots, 1), Character.valueOf('4'), new ItemStack(Blocks.wool, 1), + "2", + "4", Character.valueOf('2'), new ItemStack(Items.diamond_boots, 1), Character.valueOf('4'), new ItemStack(Blocks.wool, 1), }); GameRegistry.addRecipe(new ItemStack(multihookitem, 1), new Object[]{ - "X2", - "2X", Character.valueOf('2'), new ItemStack(hookshotitem, 1), + "X2", + "2X", Character.valueOf('2'), new ItemStack(hookshotitem, 1), }); } @@ -193,14 +194,14 @@ public void serverLoad(FMLServerStartingEvent event){ event.getServer().worldServerForDimension(0).getGameRules().addGameRule("grapplingBlocks", "any"); event.getServer().worldServerForDimension(0).getGameRules().addGameRule("grapplingNonBlocks", "none"); } - + public static void updateMaxLen(World world) { String s = MinecraftServer.getServer().worldServerForDimension(0).getGameRules().getGameRuleStringValue("grapplingLength"); if (!s.equals("")) { grapplemod.grapplingLength = Integer.parseInt(s); } } - + public static void updateGrapplingBlocks(World world) { String s = MinecraftServer.getServer().worldServerForDimension(0).getGameRules().getGameRuleStringValue("grapplingBlocks"); if (s.equals("any") || s.equals("")) { @@ -215,12 +216,12 @@ public static void updateGrapplingBlocks(World world) { anyblocks = false; removeblocks = false; } - + if (!anyblocks) { String[] blockstr = s.split(","); - + grapplingblocks = new ArrayList(); - + for(String str:blockstr){ str = str.trim(); String modid; @@ -233,14 +234,14 @@ public static void updateGrapplingBlocks(World world) { modid = "minecraft"; name = str; } - + Block b = GameRegistry.findBlock(modid, name); - + grapplingblocks.add(b); } } } - + @EventHandler public void preInit(FMLPreInitializationEvent event){ grapplebowitem = new grappleBow(); @@ -261,14 +262,14 @@ public void preInit(FMLPreInitializationEvent event){ GameRegistry.registerItem(repelleritem, "repeller"); multihookitem = new multiBow(); GameRegistry.registerItem(multihookitem, "multihook"); - + registerEntity(grappleArrow.class, "grappleArrow"); registerEntity(enderArrow.class, "enderArrow"); registerEntity(hookArrow.class, "hookArrow"); registerEntity(magnetArrow.class, "magnetArrow"); registerEntity(multihookArrow.class, "multihookArrow"); registerEntity(smartHookArrow.class, "smartHookArrow"); - + proxy.preInit(event); network = NetworkRegistry.INSTANCE.newSimpleChannel("grapplemodchannel"); byte id = 0; @@ -280,31 +281,31 @@ public void preInit(FMLPreInitializationEvent event){ network.registerMessage(MultiHookMessage.Handler.class, MultiHookMessage.class, id++, Side.SERVER); network.registerMessage(ToolConfigMessage.Handler.class, ToolConfigMessage.class, id++, Side.SERVER); } - + @EventHandler public void Init(FMLInitializationEvent event) { proxy.init(event, this); } - + @EventHandler public void postInit(FMLPostInitializationEvent event) { proxy.postInit(event); } - + int entityID = 0; public void registerEntity(Class entityClass, String name) { EntityRegistry.registerModEntity(entityClass, name, entityID++, this, 900, 1, true); } - + public static void registerController(int entityId, grappleController controller) { if (controllers.containsKey(entityId)) { controllers.get(entityId).unattach(); } - + controllers.put(entityId, controller); } - + public static void unregisterController(int entityId) { controllers.remove(entityId); } @@ -315,7 +316,7 @@ public static void receiveGrappleClick(int id, if (controller != null) { controller.receiveGrappleClick(leftclick); } else { - System.out.println("Couldn't find controller"); + grapplemod.LOGGER.error("Couldn't find controller"); } } @@ -324,19 +325,19 @@ public static void receiveEnderLaunch(int id, double x, double y, double z) { if (controller != null) { controller.receiveEnderLaunch(x, y, z); } else { - System.out.println("Couldn't find controller"); + grapplemod.LOGGER.error("Couldn't find controller"); } } - + public static void sendtocorrectclient(IMessage message, int playerid, World w) { Entity entity = w.getEntityByID(playerid); if (entity instanceof EntityPlayerMP) { grapplemod.network.sendTo(message, (EntityPlayerMP) entity); } else { - System.out.println("ERROR! couldn't find player"); + grapplemod.LOGGER.error("ERROR! couldn't find player"); } } - + public static grappleController createControl(int id, int arrowid, int entityid, World world, vec pos, int maxlen, BlockPos blockpos) { grappleArrow arrow = null; @@ -344,16 +345,16 @@ public static grappleController createControl(int id, int arrowid, int entityid, if (arrowentity != null && arrowentity instanceof grappleArrow) { arrow = (grappleArrow) arrowentity; } - + if (id != MULTISUBID) { grappleController currentcontroller = controllers.get(entityid); if (currentcontroller != null) { currentcontroller.unattach(); } } - - System.out.println(blockpos); - + + //grapplemod.LOGGER.debug(blockpos); + grappleController control = null; if (id == GRAPPLEID) { control = new grappleController(arrowid, entityid, world, pos, maxlen, id); @@ -389,20 +390,20 @@ public static grappleController createControl(int id, int arrowid, int entityid, } } if (!created) { - System.out.println("Couldn't create"); + grapplemod.LOGGER.error("Couldn't create"); grapplemod.removesubarrow(arrowid); } } else if (id == AIRID) { - System.out.println("AIR FRICTION CONTROLLER"); + //System.out.println("AIR FRICTION CONTROLLER"); control = new airfrictionController(arrowid, entityid, world, pos, maxlen, id); } if (blockpos != null && control != null) { grapplemod.controllerpos.put(blockpos, control); } - + return control; } - + public static void removesubarrow(int id) { grapplemod.network.sendToServer(new GrappleEndMessage(-1, id)); } @@ -413,21 +414,21 @@ public static void receiveGrappleEnd(int id, World world, int arrowid) { (id)); } else { } - + if (arrowid != -1) { Entity grapple = world.getEntityByID(arrowid); if (grapple instanceof grappleArrow) { ((grappleArrow) grapple).removeServer(); } else { - + } } - + Entity entity = world.getEntityByID(id); if (entity != null) { entity.fallDistance = 0; } - + grapplemod.removeallmultihookarrows(); } @@ -436,53 +437,53 @@ public static void receiveMultihookMessage(int id, World w, boolean sneaking) { Entity e = w.getEntityByID(id); if (e != null && e instanceof EntityLivingBase) { EntityLivingBase player = (EntityLivingBase) e; - + float angle = multiBow.getAngle(player); - + //vec look = new vec(player.getLookVec()); - - //System.out.println(player.rotationPitch); - //System.out.println(player.rotationYaw); - + + //grapplemod.LOGGER.debug(player.rotationPitch); + //grapplemod.LOGGER.debug(player.rotationYaw); + /* grappleArrow arrow = new grappleArrow(w, player, false); arrow.setHeadingFromThrower(player, (float)look.getPitch(), (float)look.getYaw(), 0.0F, arrow.getVelocity(), 0.0F); w.spawnEntityInWorld(arrow); */ - + vec anglevec = new vec(0,0,1).rotate_yaw(Math.toRadians(-angle)); anglevec = anglevec.rotate_pitch(Math.toRadians(-player.rotationPitch)); anglevec = anglevec.rotate_yaw(Math.toRadians(player.rotationYaw)); multihookArrow entityarrow = new multihookArrow(w, player, false); entityarrow.setHeadingFromThrower(player, (float) anglevec.getPitch(), (float)anglevec.getYaw(), 0.0F, entityarrow.func_70182_d(), 0.0F); - + /* vec pos = vec.positionvec(entityarrow); pos.add_ip(new vec(0.36, -0.175, 0.45).rotate_yaw(Math.toRadians(player.rotationYaw))); entityarrow.setPosition(pos.x, pos.y, pos.z); */ - + w.spawnEntityInWorld(entityarrow); multihookarrows.add(entityarrow); - - + + anglevec = new vec(0,0,1).rotate_yaw(Math.toRadians(angle)); anglevec = anglevec.rotate_pitch(Math.toRadians(-player.rotationPitch)); anglevec = anglevec.rotate_yaw(Math.toRadians(player.rotationYaw)); entityarrow = new multihookArrow(w, player, true); entityarrow.setHeadingFromThrower(player, (float) anglevec.getPitch(), (float)anglevec.getYaw(), 0.0F, entityarrow.func_70182_d(), 0.0F); - + /* pos = vec.positionvec(entityarrow); pos.add_ip(new vec(-0.36, -0.175, 0.45).rotate_yaw(Math.toRadians(player.rotationYaw))); entityarrow.setPosition(pos.x, pos.y, pos.z); */ - + w.spawnEntityInWorld(entityarrow); multihookarrows.add(entityarrow); } } - + public static void removeallmultihookarrows() { for (multihookArrow arrow : multihookarrows) { if (arrow != null && !arrow.isDead) { @@ -495,7 +496,7 @@ public static void receiveToolConfigMessage(int id, World w) { Entity e = w.getEntityByID(id); if (e != null && e instanceof EntityPlayer) { EntityPlayer player = (EntityPlayer) e; - + ItemStack stack = player.getHeldItem(); Item item = stack.getItem(); if (item instanceof multiBow) { @@ -507,7 +508,7 @@ public static void receiveToolConfigMessage(int id, World w) { boolean slow = compound.getBoolean("slow"); slow = !slow; compound.setBoolean("slow", slow); - + if (slow) { player.addChatMessage(new ChatComponentText("Set to slow mode")); } else { @@ -525,7 +526,7 @@ public static void receiveToolConfigMessage(int id, World w) { repelconf = 0; } compound.setInteger("repelconf", repelconf); - + // if (repelconf == REPELSPEED) { // player.addChatMessage(new TextComponentString("Repel force set to speed based")); if (repelconf == REPELSTRONG) { @@ -544,7 +545,7 @@ public static void receiveToolConfigMessage(int id, World w) { boolean slow = compound.getBoolean("slow"); slow = !slow; compound.setBoolean("slow", slow); - + if (slow) { player.addChatMessage(new ChatComponentText("Set to slow mode")); } else { diff --git a/main/java/com/yyon/grapplinghook/items/LongFallBoots.java b/src/main/java/com/yyon/grapplinghook/items/LongFallBoots.java similarity index 100% rename from main/java/com/yyon/grapplinghook/items/LongFallBoots.java rename to src/main/java/com/yyon/grapplinghook/items/LongFallBoots.java diff --git a/main/java/com/yyon/grapplinghook/items/clickitem.java b/src/main/java/com/yyon/grapplinghook/items/clickitem.java similarity index 100% rename from main/java/com/yyon/grapplinghook/items/clickitem.java rename to src/main/java/com/yyon/grapplinghook/items/clickitem.java diff --git a/main/java/com/yyon/grapplinghook/items/enderBow.java b/src/main/java/com/yyon/grapplinghook/items/enderBow.java similarity index 100% rename from main/java/com/yyon/grapplinghook/items/enderBow.java rename to src/main/java/com/yyon/grapplinghook/items/enderBow.java diff --git a/main/java/com/yyon/grapplinghook/items/grappleBow.java b/src/main/java/com/yyon/grapplinghook/items/grappleBow.java similarity index 100% rename from main/java/com/yyon/grapplinghook/items/grappleBow.java rename to src/main/java/com/yyon/grapplinghook/items/grappleBow.java diff --git a/main/java/com/yyon/grapplinghook/items/hookBow.java b/src/main/java/com/yyon/grapplinghook/items/hookBow.java similarity index 100% rename from main/java/com/yyon/grapplinghook/items/hookBow.java rename to src/main/java/com/yyon/grapplinghook/items/hookBow.java diff --git a/main/java/com/yyon/grapplinghook/items/launcherItem.java b/src/main/java/com/yyon/grapplinghook/items/launcherItem.java similarity index 100% rename from main/java/com/yyon/grapplinghook/items/launcherItem.java rename to src/main/java/com/yyon/grapplinghook/items/launcherItem.java diff --git a/main/java/com/yyon/grapplinghook/items/magnetBow.java b/src/main/java/com/yyon/grapplinghook/items/magnetBow.java similarity index 100% rename from main/java/com/yyon/grapplinghook/items/magnetBow.java rename to src/main/java/com/yyon/grapplinghook/items/magnetBow.java diff --git a/main/java/com/yyon/grapplinghook/items/multiBow.java b/src/main/java/com/yyon/grapplinghook/items/multiBow.java similarity index 100% rename from main/java/com/yyon/grapplinghook/items/multiBow.java rename to src/main/java/com/yyon/grapplinghook/items/multiBow.java diff --git a/main/java/com/yyon/grapplinghook/items/repeller.java b/src/main/java/com/yyon/grapplinghook/items/repeller.java similarity index 100% rename from main/java/com/yyon/grapplinghook/items/repeller.java rename to src/main/java/com/yyon/grapplinghook/items/repeller.java diff --git a/main/java/com/yyon/grapplinghook/items/smartHookBow.java b/src/main/java/com/yyon/grapplinghook/items/smartHookBow.java similarity index 100% rename from main/java/com/yyon/grapplinghook/items/smartHookBow.java rename to src/main/java/com/yyon/grapplinghook/items/smartHookBow.java diff --git a/main/java/com/yyon/grapplinghook/network/GrappleAttachMessage.java b/src/main/java/com/yyon/grapplinghook/network/GrappleAttachMessage.java similarity index 100% rename from main/java/com/yyon/grapplinghook/network/GrappleAttachMessage.java rename to src/main/java/com/yyon/grapplinghook/network/GrappleAttachMessage.java diff --git a/main/java/com/yyon/grapplinghook/network/GrappleAttachPosMessage.java b/src/main/java/com/yyon/grapplinghook/network/GrappleAttachPosMessage.java similarity index 100% rename from main/java/com/yyon/grapplinghook/network/GrappleAttachPosMessage.java rename to src/main/java/com/yyon/grapplinghook/network/GrappleAttachPosMessage.java diff --git a/main/java/com/yyon/grapplinghook/network/GrappleClickMessage.java b/src/main/java/com/yyon/grapplinghook/network/GrappleClickMessage.java similarity index 100% rename from main/java/com/yyon/grapplinghook/network/GrappleClickMessage.java rename to src/main/java/com/yyon/grapplinghook/network/GrappleClickMessage.java diff --git a/main/java/com/yyon/grapplinghook/network/GrappleEndMessage.java b/src/main/java/com/yyon/grapplinghook/network/GrappleEndMessage.java similarity index 100% rename from main/java/com/yyon/grapplinghook/network/GrappleEndMessage.java rename to src/main/java/com/yyon/grapplinghook/network/GrappleEndMessage.java diff --git a/main/java/com/yyon/grapplinghook/network/MultiHookMessage.java b/src/main/java/com/yyon/grapplinghook/network/MultiHookMessage.java similarity index 100% rename from main/java/com/yyon/grapplinghook/network/MultiHookMessage.java rename to src/main/java/com/yyon/grapplinghook/network/MultiHookMessage.java diff --git a/main/java/com/yyon/grapplinghook/network/PlayerMovementMessage.java.orig b/src/main/java/com/yyon/grapplinghook/network/PlayerMovementMessage.java similarity index 61% rename from main/java/com/yyon/grapplinghook/network/PlayerMovementMessage.java.orig rename to src/main/java/com/yyon/grapplinghook/network/PlayerMovementMessage.java index 708cee8..85f8997 100644 --- a/main/java/com/yyon/grapplinghook/network/PlayerMovementMessage.java.orig +++ b/src/main/java/com/yyon/grapplinghook/network/PlayerMovementMessage.java @@ -1,28 +1,15 @@ package com.yyon.grapplinghook.network; +import com.yyon.grapplinghook.grapplemod; import io.netty.buffer.ByteBuf; - -import java.lang.reflect.Field; - import net.minecraft.entity.Entity; -<<<<<<< HEAD +import net.minecraft.entity.player.EntityPlayerMP; import net.minecraft.world.World; import cpw.mods.fml.common.network.simpleimpl.IMessage; import cpw.mods.fml.common.network.simpleimpl.IMessageHandler; import cpw.mods.fml.common.network.simpleimpl.MessageContext; //* // 1.8 Compatability -======= -import net.minecraft.entity.player.EntityPlayerMP; -import net.minecraft.network.NetHandlerPlayServer; -import net.minecraft.util.IThreadListener; -import net.minecraft.world.World; -import net.minecraft.world.WorldServer; -import net.minecraftforge.fml.common.ObfuscationReflectionHelper; -import net.minecraftforge.fml.common.network.simpleimpl.IMessage; -import net.minecraftforge.fml.common.network.simpleimpl.IMessageHandler; -import net.minecraftforge.fml.common.network.simpleimpl.MessageContext; ->>>>>>> 6c8b29cf1a9f87c1801402122aee8a079fcdc67a /* * This file is part of GrappleMod. @@ -42,41 +29,41 @@ */ public class PlayerMovementMessage implements IMessage { - - public int entityId; - public double x; - public double y; - public double z; - public double mx; - public double my; - public double mz; - - public PlayerMovementMessage() { - } - + + public int entityId; + public double x; + public double y; + public double z; + public double mx; + public double my; + public double mz; + + public PlayerMovementMessage() { + } + public PlayerMovementMessage(int entityId, double x, double y, double z, double mx, double my, double mz) { - this.entityId = entityId; - this.x = x; - this.y = y; - this.z = z; - this.mx = mx; - this.my = my; - this.mz = mz; + this.entityId = entityId; + this.x = x; + this.y = y; + this.z = z; + this.mx = mx; + this.my = my; + this.mz = mz; } @Override public void fromBytes(ByteBuf buf) { - try { - this.entityId = buf.readInt(); - this.x = buf.readDouble(); - this.y = buf.readDouble(); - this.z = buf.readDouble(); - this.mx = buf.readDouble(); - this.my = buf.readDouble(); - this.mz = buf.readDouble(); - } catch (Exception e) { - System.out.println(buf); - } + try { + this.entityId = buf.readInt(); + this.x = buf.readDouble(); + this.y = buf.readDouble(); + this.z = buf.readDouble(); + this.mx = buf.readDouble(); + this.my = buf.readDouble(); + this.mz = buf.readDouble(); + } catch (Exception e) { + grapplemod.LOGGER.error(buf); + } } @Override @@ -88,21 +75,21 @@ public void toBytes(ByteBuf buf) { buf.writeDouble(mx); buf.writeDouble(my); buf.writeDouble(mz); - + } public static class Handler implements IMessageHandler { - - public class runner implements Runnable { - PlayerMovementMessage message; - MessageContext ctx; - - public runner(PlayerMovementMessage message, MessageContext ctx) { - super(); - this.message = message; - this.ctx = ctx; - } - + + public class runner implements Runnable { + PlayerMovementMessage message; + MessageContext ctx; + + public runner(PlayerMovementMessage message, MessageContext ctx) { + super(); + this.message = message; + this.ctx = ctx; + } + @Override public void run() { World world = ctx.getServerHandler().playerEntity.worldObj; @@ -115,12 +102,14 @@ public void run() { entity.motionY = message.my; entity.motionZ = message.mz; if (entity instanceof EntityPlayerMP) { - EntityPlayerMP player = ((EntityPlayerMP) entity); - player.connection.update(); + EntityPlayerMP player = ((EntityPlayerMP) entity); + player.onUpdateEntity(); + player.setPositionAndRotation(message.x, message.y, message.z, player.rotationYaw, player.rotationPitch); + world.updateEntity(player); } } - } - + } + @Override public IMessage onMessage(PlayerMovementMessage message, MessageContext ctx) { new runner(message, ctx).run(); diff --git a/main/java/com/yyon/grapplinghook/network/ToolConfigMessage.java b/src/main/java/com/yyon/grapplinghook/network/ToolConfigMessage.java similarity index 100% rename from main/java/com/yyon/grapplinghook/network/ToolConfigMessage.java rename to src/main/java/com/yyon/grapplinghook/network/ToolConfigMessage.java diff --git a/main/java/com/yyon/grapplinghook/vec.java b/src/main/java/com/yyon/grapplinghook/vec.java similarity index 100% rename from main/java/com/yyon/grapplinghook/vec.java rename to src/main/java/com/yyon/grapplinghook/vec.java diff --git a/src/main/resources/LICENSE b/src/main/resources/LICENSE new file mode 100644 index 0000000..20d40b6 --- /dev/null +++ b/src/main/resources/LICENSE @@ -0,0 +1,674 @@ + GNU GENERAL PUBLIC LICENSE + Version 3, 29 June 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 General Public License is a free, copyleft license for +software and other kinds of works. + + The licenses for most software and other practical works are designed +to take away your freedom to share and change the works. By contrast, +the GNU General Public License is intended to guarantee your freedom to +share and change all versions of a program--to make sure it remains free +software for all its users. We, the Free Software Foundation, use the +GNU General Public License for most of our software; it applies also to +any other work released this way by its authors. You can apply it to +your programs, too. + + When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +them if you wish), that you receive source code or can get it if you +want it, that you can change the software or use pieces of it in new +free programs, and that you know you can do these things. + + To protect your rights, we need to prevent others from denying you +these rights or asking you to surrender the rights. Therefore, you have +certain responsibilities if you distribute copies of the software, or if +you modify it: responsibilities to respect the freedom of others. + + For example, if you distribute copies of such a program, whether +gratis or for a fee, you must pass on to the recipients the same +freedoms that you received. You must make sure that they, too, receive +or can get the source code. And you must show them these terms so they +know their rights. + + Developers that use the GNU GPL protect your rights with two steps: +(1) assert copyright on the software, and (2) offer you this License +giving you legal permission to copy, distribute and/or modify it. + + For the developers' and authors' protection, the GPL clearly explains +that there is no warranty for this free software. For both users' and +authors' sake, the GPL requires that modified versions be marked as +changed, so that their problems will not be attributed erroneously to +authors of previous versions. + + Some devices are designed to deny users access to install or run +modified versions of the software inside them, although the manufacturer +can do so. This is fundamentally incompatible with the aim of +protecting users' freedom to change the software. The systematic +pattern of such abuse occurs in the area of products for individuals to +use, which is precisely where it is most unacceptable. Therefore, we +have designed this version of the GPL to prohibit the practice for those +products. If such problems arise substantially in other domains, we +stand ready to extend this provision to those domains in future versions +of the GPL, as needed to protect the freedom of users. + + Finally, every program is threatened constantly by software patents. +States should not allow patents to restrict development and use of +software on general-purpose computers, but in those that do, we wish to +avoid the special danger that patents applied to a free program could +make it effectively proprietary. To prevent this, the GPL assures that +patents cannot be used to render the program non-free. + + The precise terms and conditions for copying, distribution and +modification follow. + + TERMS AND CONDITIONS + + 0. Definitions. + + "This License" refers to version 3 of the GNU General Public License. + + "Copyright" also means copyright-like laws that apply to other kinds of +works, such as semiconductor masks. + + "The Program" refers to any copyrightable work licensed under this +License. Each licensee is addressed as "you". "Licensees" and +"recipients" may be individuals or organizations. + + To "modify" a work means to copy from or adapt all or part of the work +in a fashion requiring copyright permission, other than the making of an +exact copy. The resulting work is called a "modified version" of the +earlier work or a work "based on" the earlier work. + + A "covered work" means either the unmodified Program or a work based +on the Program. + + To "propagate" a work means to do anything with it that, without +permission, would make you directly or secondarily liable for +infringement under applicable copyright law, except executing it on a +computer or modifying a private copy. Propagation includes copying, +distribution (with or without modification), making available to the +public, and in some countries other activities as well. + + To "convey" a work means any kind of propagation that enables other +parties to make or receive copies. Mere interaction with a user through +a computer network, with no transfer of a copy, is not conveying. + + An interactive user interface displays "Appropriate Legal Notices" +to the extent that it includes a convenient and prominently visible +feature that (1) displays an appropriate copyright notice, and (2) +tells the user that there is no warranty for the work (except to the +extent that warranties are provided), that licensees may convey the +work under this License, and how to view a copy of this License. If +the interface presents a list of user commands or options, such as a +menu, a prominent item in the list meets this criterion. + + 1. Source Code. + + The "source code" for a work means the preferred form of the work +for making modifications to it. "Object code" means any non-source +form of a work. + + A "Standard Interface" means an interface that either is an official +standard defined by a recognized standards body, or, in the case of +interfaces specified for a particular programming language, one that +is widely used among developers working in that language. + + The "System Libraries" of an executable work include anything, other +than the work as a whole, that (a) is included in the normal form of +packaging a Major Component, but which is not part of that Major +Component, and (b) serves only to enable use of the work with that +Major Component, or to implement a Standard Interface for which an +implementation is available to the public in source code form. A +"Major Component", in this context, means a major essential component +(kernel, window system, and so on) of the specific operating system +(if any) on which the executable work runs, or a compiler used to +produce the work, or an object code interpreter used to run it. + + The "Corresponding Source" for a work in object code form means all +the source code needed to generate, install, and (for an executable +work) run the object code and to modify the work, including scripts to +control those activities. However, it does not include the work's +System Libraries, or general-purpose tools or generally available free +programs which are used unmodified in performing those activities but +which are not part of the work. For example, Corresponding Source +includes interface definition files associated with source files for +the work, and the source code for shared libraries and dynamically +linked subprograms that the work is specifically designed to require, +such as by intimate data communication or control flow between those +subprograms and other parts of the work. + + The Corresponding Source need not include anything that users +can regenerate automatically from other parts of the Corresponding +Source. + + The Corresponding Source for a work in source code form is that +same work. + + 2. Basic Permissions. + + All rights granted under this License are granted for the term of +copyright on the Program, and are irrevocable provided the stated +conditions are met. This License explicitly affirms your unlimited +permission to run the unmodified Program. The output from running a +covered work is covered by this License only if the output, given its +content, constitutes a covered work. This License acknowledges your +rights of fair use or other equivalent, as provided by copyright law. + + You may make, run and propagate covered works that you do not +convey, without conditions so long as your license otherwise remains +in force. You may convey covered works to others for the sole purpose +of having them make modifications exclusively for you, or provide you +with facilities for running those works, provided that you comply with +the terms of this License in conveying all material for which you do +not control copyright. Those thus making or running the covered works +for you must do so exclusively on your behalf, under your direction +and control, on terms that prohibit them from making any copies of +your copyrighted material outside their relationship with you. + + Conveying under any other circumstances is permitted solely under +the conditions stated below. Sublicensing is not allowed; section 10 +makes it unnecessary. + + 3. Protecting Users' Legal Rights From Anti-Circumvention Law. + + No covered work shall be deemed part of an effective technological +measure under any applicable law fulfilling obligations under article +11 of the WIPO copyright treaty adopted on 20 December 1996, or +similar laws prohibiting or restricting circumvention of such +measures. + + When you convey a covered work, you waive any legal power to forbid +circumvention of technological measures to the extent such circumvention +is effected by exercising rights under this License with respect to +the covered work, and you disclaim any intention to limit operation or +modification of the work as a means of enforcing, against the work's +users, your or third parties' legal rights to forbid circumvention of +technological measures. + + 4. Conveying Verbatim Copies. + + You may convey verbatim copies of the Program's source code as you +receive it, in any medium, provided that you conspicuously and +appropriately publish on each copy an appropriate copyright notice; +keep intact all notices stating that this License and any +non-permissive terms added in accord with section 7 apply to the code; +keep intact all notices of the absence of any warranty; and give all +recipients a copy of this License along with the Program. + + You may charge any price or no price for each copy that you convey, +and you may offer support or warranty protection for a fee. + + 5. Conveying Modified Source Versions. + + You may convey a work based on the Program, or the modifications to +produce it from the Program, in the form of source code under the +terms of section 4, provided that you also meet all of these conditions: + + a) The work must carry prominent notices stating that you modified + it, and giving a relevant date. + + b) The work must carry prominent notices stating that it is + released under this License and any conditions added under section + 7. This requirement modifies the requirement in section 4 to + "keep intact all notices". + + c) You must license the entire work, as a whole, under this + License to anyone who comes into possession of a copy. This + License will therefore apply, along with any applicable section 7 + additional terms, to the whole of the work, and all its parts, + regardless of how they are packaged. This License gives no + permission to license the work in any other way, but it does not + invalidate such permission if you have separately received it. + + d) If the work has interactive user interfaces, each must display + Appropriate Legal Notices; however, if the Program has interactive + interfaces that do not display Appropriate Legal Notices, your + work need not make them do so. + + A compilation of a covered work with other separate and independent +works, which are not by their nature extensions of the covered work, +and which are not combined with it such as to form a larger program, +in or on a volume of a storage or distribution medium, is called an +"aggregate" if the compilation and its resulting copyright are not +used to limit the access or legal rights of the compilation's users +beyond what the individual works permit. Inclusion of a covered work +in an aggregate does not cause this License to apply to the other +parts of the aggregate. + + 6. Conveying Non-Source Forms. + + You may convey a covered work in object code form under the terms +of sections 4 and 5, provided that you also convey the +machine-readable Corresponding Source under the terms of this License, +in one of these ways: + + a) Convey the object code in, or embodied in, a physical product + (including a physical distribution medium), accompanied by the + Corresponding Source fixed on a durable physical medium + customarily used for software interchange. + + b) Convey the object code in, or embodied in, a physical product + (including a physical distribution medium), accompanied by a + written offer, valid for at least three years and valid for as + long as you offer spare parts or customer support for that product + model, to give anyone who possesses the object code either (1) a + copy of the Corresponding Source for all the software in the + product that is covered by this License, on a durable physical + medium customarily used for software interchange, for a price no + more than your reasonable cost of physically performing this + conveying of source, or (2) access to copy the + Corresponding Source from a network server at no charge. + + c) Convey individual copies of the object code with a copy of the + written offer to provide the Corresponding Source. This + alternative is allowed only occasionally and noncommercially, and + only if you received the object code with such an offer, in accord + with subsection 6b. + + d) Convey the object code by offering access from a designated + place (gratis or for a charge), and offer equivalent access to the + Corresponding Source in the same way through the same place at no + further charge. You need not require recipients to copy the + Corresponding Source along with the object code. If the place to + copy the object code is a network server, the Corresponding Source + may be on a different server (operated by you or a third party) + that supports equivalent copying facilities, provided you maintain + clear directions next to the object code saying where to find the + Corresponding Source. Regardless of what server hosts the + Corresponding Source, you remain obligated to ensure that it is + available for as long as needed to satisfy these requirements. + + e) Convey the object code using peer-to-peer transmission, provided + you inform other peers where the object code and Corresponding + Source of the work are being offered to the general public at no + charge under subsection 6d. + + A separable portion of the object code, whose source code is excluded +from the Corresponding Source as a System Library, need not be +included in conveying the object code work. + + A "User Product" is either (1) a "consumer product", which means any +tangible personal property which is normally used for personal, family, +or household purposes, or (2) anything designed or sold for incorporation +into a dwelling. In determining whether a product is a consumer product, +doubtful cases shall be resolved in favor of coverage. For a particular +product received by a particular user, "normally used" refers to a +typical or common use of that class of product, regardless of the status +of the particular user or of the way in which the particular user +actually uses, or expects or is expected to use, the product. A product +is a consumer product regardless of whether the product has substantial +commercial, industrial or non-consumer uses, unless such uses represent +the only significant mode of use of the product. + + "Installation Information" for a User Product means any methods, +procedures, authorization keys, or other information required to install +and execute modified versions of a covered work in that User Product from +a modified version of its Corresponding Source. The information must +suffice to ensure that the continued functioning of the modified object +code is in no case prevented or interfered with solely because +modification has been made. + + If you convey an object code work under this section in, or with, or +specifically for use in, a User Product, and the conveying occurs as +part of a transaction in which the right of possession and use of the +User Product is transferred to the recipient in perpetuity or for a +fixed term (regardless of how the transaction is characterized), the +Corresponding Source conveyed under this section must be accompanied +by the Installation Information. But this requirement does not apply +if neither you nor any third party retains the ability to install +modified object code on the User Product (for example, the work has +been installed in ROM). + + The requirement to provide Installation Information does not include a +requirement to continue to provide support service, warranty, or updates +for a work that has been modified or installed by the recipient, or for +the User Product in which it has been modified or installed. Access to a +network may be denied when the modification itself materially and +adversely affects the operation of the network or violates the rules and +protocols for communication across the network. + + Corresponding Source conveyed, and Installation Information provided, +in accord with this section must be in a format that is publicly +documented (and with an implementation available to the public in +source code form), and must require no special password or key for +unpacking, reading or copying. + + 7. Additional Terms. + + "Additional permissions" are terms that supplement the terms of this +License by making exceptions from one or more of its conditions. +Additional permissions that are applicable to the entire Program shall +be treated as though they were included in this License, to the extent +that they are valid under applicable law. If additional permissions +apply only to part of the Program, that part may be used separately +under those permissions, but the entire Program remains governed by +this License without regard to the additional permissions. + + When you convey a copy of a covered work, you may at your option +remove any additional permissions from that copy, or from any part of +it. (Additional permissions may be written to require their own +removal in certain cases when you modify the work.) You may place +additional permissions on material, added by you to a covered work, +for which you have or can give appropriate copyright permission. + + Notwithstanding any other provision of this License, for material you +add to a covered work, you may (if authorized by the copyright holders of +that material) supplement the terms of this License with terms: + + a) Disclaiming warranty or limiting liability differently from the + terms of sections 15 and 16 of this License; or + + b) Requiring preservation of specified reasonable legal notices or + author attributions in that material or in the Appropriate Legal + Notices displayed by works containing it; or + + c) Prohibiting misrepresentation of the origin of that material, or + requiring that modified versions of such material be marked in + reasonable ways as different from the original version; or + + d) Limiting the use for publicity purposes of names of licensors or + authors of the material; or + + e) Declining to grant rights under trademark law for use of some + trade names, trademarks, or service marks; or + + f) Requiring indemnification of licensors and authors of that + material by anyone who conveys the material (or modified versions of + it) with contractual assumptions of liability to the recipient, for + any liability that these contractual assumptions directly impose on + those licensors and authors. + + All other non-permissive additional terms are considered "further +restrictions" within the meaning of section 10. If the Program as you +received it, or any part of it, contains a notice stating that it is +governed by this License along with a term that is a further +restriction, you may remove that term. If a license document contains +a further restriction but permits relicensing or conveying under this +License, you may add to a covered work material governed by the terms +of that license document, provided that the further restriction does +not survive such relicensing or conveying. + + If you add terms to a covered work in accord with this section, you +must place, in the relevant source files, a statement of the +additional terms that apply to those files, or a notice indicating +where to find the applicable terms. + + Additional terms, permissive or non-permissive, may be stated in the +form of a separately written license, or stated as exceptions; +the above requirements apply either way. + + 8. Termination. + + You may not propagate or modify a covered work except as expressly +provided under this License. Any attempt otherwise to propagate or +modify it is void, and will automatically terminate your rights under +this License (including any patent licenses granted under the third +paragraph of section 11). + + However, if you cease all violation of this License, then your +license from a particular copyright holder is reinstated (a) +provisionally, unless and until the copyright holder explicitly and +finally terminates your license, and (b) permanently, if the copyright +holder fails to notify you of the violation by some reasonable means +prior to 60 days after the cessation. + + Moreover, your license from a particular copyright holder is +reinstated permanently if the copyright holder notifies you of the +violation by some reasonable means, this is the first time you have +received notice of violation of this License (for any work) from that +copyright holder, and you cure the violation prior to 30 days after +your receipt of the notice. + + Termination of your rights under this section does not terminate the +licenses of parties who have received copies or rights from you under +this License. If your rights have been terminated and not permanently +reinstated, you do not qualify to receive new licenses for the same +material under section 10. + + 9. Acceptance Not Required for Having Copies. + + You are not required to accept this License in order to receive or +run a copy of the Program. Ancillary propagation of a covered work +occurring solely as a consequence of using peer-to-peer transmission +to receive a copy likewise does not require acceptance. However, +nothing other than this License grants you permission to propagate or +modify any covered work. These actions infringe copyright if you do +not accept this License. Therefore, by modifying or propagating a +covered work, you indicate your acceptance of this License to do so. + + 10. Automatic Licensing of Downstream Recipients. + + Each time you convey a covered work, the recipient automatically +receives a license from the original licensors, to run, modify and +propagate that work, subject to this License. You are not responsible +for enforcing compliance by third parties with this License. + + An "entity transaction" is a transaction transferring control of an +organization, or substantially all assets of one, or subdividing an +organization, or merging organizations. If propagation of a covered +work results from an entity transaction, each party to that +transaction who receives a copy of the work also receives whatever +licenses to the work the party's predecessor in interest had or could +give under the previous paragraph, plus a right to possession of the +Corresponding Source of the work from the predecessor in interest, if +the predecessor has it or can get it with reasonable efforts. + + You may not impose any further restrictions on the exercise of the +rights granted or affirmed under this License. For example, you may +not impose a license fee, royalty, or other charge for exercise of +rights granted under this License, and you may not initiate litigation +(including a cross-claim or counterclaim in a lawsuit) alleging that +any patent claim is infringed by making, using, selling, offering for +sale, or importing the Program or any portion of it. + + 11. Patents. + + A "contributor" is a copyright holder who authorizes use under this +License of the Program or a work on which the Program is based. The +work thus licensed is called the contributor's "contributor version". + + A contributor's "essential patent claims" are all patent claims +owned or controlled by the contributor, whether already acquired or +hereafter acquired, that would be infringed by some manner, permitted +by this License, of making, using, or selling its contributor version, +but do not include claims that would be infringed only as a +consequence of further modification of the contributor version. For +purposes of this definition, "control" includes the right to grant +patent sublicenses in a manner consistent with the requirements of +this License. + + Each contributor grants you a non-exclusive, worldwide, royalty-free +patent license under the contributor's essential patent claims, to +make, use, sell, offer for sale, import and otherwise run, modify and +propagate the contents of its contributor version. + + In the following three paragraphs, a "patent license" is any express +agreement or commitment, however denominated, not to enforce a patent +(such as an express permission to practice a patent or covenant not to +sue for patent infringement). To "grant" such a patent license to a +party means to make such an agreement or commitment not to enforce a +patent against the party. + + If you convey a covered work, knowingly relying on a patent license, +and the Corresponding Source of the work is not available for anyone +to copy, free of charge and under the terms of this License, through a +publicly available network server or other readily accessible means, +then you must either (1) cause the Corresponding Source to be so +available, or (2) arrange to deprive yourself of the benefit of the +patent license for this particular work, or (3) arrange, in a manner +consistent with the requirements of this License, to extend the patent +license to downstream recipients. "Knowingly relying" means you have +actual knowledge that, but for the patent license, your conveying the +covered work in a country, or your recipient's use of the covered work +in a country, would infringe one or more identifiable patents in that +country that you have reason to believe are valid. + + If, pursuant to or in connection with a single transaction or +arrangement, you convey, or propagate by procuring conveyance of, a +covered work, and grant a patent license to some of the parties +receiving the covered work authorizing them to use, propagate, modify +or convey a specific copy of the covered work, then the patent license +you grant is automatically extended to all recipients of the covered +work and works based on it. + + A patent license is "discriminatory" if it does not include within +the scope of its coverage, prohibits the exercise of, or is +conditioned on the non-exercise of one or more of the rights that are +specifically granted under this License. You may not convey a covered +work if you are a party to an arrangement with a third party that is +in the business of distributing software, under which you make payment +to the third party based on the extent of your activity of conveying +the work, and under which the third party grants, to any of the +parties who would receive the covered work from you, a discriminatory +patent license (a) in connection with copies of the covered work +conveyed by you (or copies made from those copies), or (b) primarily +for and in connection with specific products or compilations that +contain the covered work, unless you entered into that arrangement, +or that patent license was granted, prior to 28 March 2007. + + Nothing in this License shall be construed as excluding or limiting +any implied license or other defenses to infringement that may +otherwise be available to you under applicable patent law. + + 12. No Surrender of Others' Freedom. + + If conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot convey a +covered work so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you may +not convey it at all. For example, if you agree to terms that obligate you +to collect a royalty for further conveying from those to whom you convey +the Program, the only way you could satisfy both those terms and this +License would be to refrain entirely from conveying the Program. + + 13. Use with the GNU Affero General Public License. + + Notwithstanding any other provision of this License, you have +permission to link or combine any covered work with a work licensed +under version 3 of the GNU Affero General Public License into a single +combined work, and to convey the resulting work. The terms of this +License will continue to apply to the part which is the covered work, +but the special requirements of the GNU Affero General Public License, +section 13, concerning interaction through a network will apply to the +combination as such. + + 14. Revised Versions of this License. + + The Free Software Foundation may publish revised and/or new versions of +the GNU General Public License from time to time. Such new versions will +be similar in spirit to the present version, but may differ in detail to +address new problems or concerns. + + Each version is given a distinguishing version number. If the +Program specifies that a certain numbered version of the GNU General +Public License "or any later version" applies to it, you have the +option of following the terms and conditions either of that numbered +version or of any later version published by the Free Software +Foundation. If the Program does not specify a version number of the +GNU General Public License, you may choose any version ever published +by the Free Software Foundation. + + If the Program specifies that a proxy can decide which future +versions of the GNU General Public License can be used, that proxy's +public statement of acceptance of a version permanently authorizes you +to choose that version for the Program. + + Later license versions may give you additional or different +permissions. However, no additional obligations are imposed on any +author or copyright holder as a result of your choosing to follow a +later version. + + 15. Disclaimer of Warranty. + + THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY +APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT +HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY +OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, +THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM +IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF +ALL NECESSARY SERVICING, REPAIR OR CORRECTION. + + 16. Limitation of Liability. + + IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS +THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY +GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE +USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF +DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD +PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), +EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF +SUCH DAMAGES. + + 17. Interpretation of Sections 15 and 16. + + If the disclaimer of warranty and limitation of liability provided +above cannot be given local legal effect according to their terms, +reviewing courts shall apply local law that most closely approximates +an absolute waiver of all civil liability in connection with the +Program, unless a warranty or assumption of liability accompanies a +copy of the Program in return for a fee. + + END OF TERMS AND CONDITIONS + + How to Apply These Terms to Your New Programs + + If you develop a new program, and you want it to be of the greatest +possible use to the public, the best way to achieve this is to make it +free software which everyone can redistribute and change under these terms. + + To do so, attach the following notices to the program. It is safest +to attach them to the start of each source file to most effectively +state the exclusion of warranty; and each file should have at least +the "copyright" line and a pointer to where the full notice is found. + + + Copyright (C) + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . + +Also add information on how to contact you by electronic and paper mail. + + If the program does terminal interaction, make it output a short +notice like this when it starts in an interactive mode: + + Copyright (C) + This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'. + This is free software, and you are welcome to redistribute it + under certain conditions; type `show c' for details. + +The hypothetical commands `show w' and `show c' should show the appropriate +parts of the General Public License. Of course, your program's commands +might be different; for a GUI interface, you would use an "about box". + + You should also get your employer (if you work as a programmer) or school, +if any, to sign a "copyright disclaimer" for the program, if necessary. +For more information on this, and how to apply and follow the GNU GPL, see +. + + The GNU General Public License does not permit incorporating your program +into proprietary programs. If your program is a subroutine library, you +may consider it more useful to permit linking proprietary applications with +the library. If this is what you want to do, use the GNU Lesser General +Public License instead of this License. But first, please read +. \ No newline at end of file diff --git a/main/resources/assets/grapplemod/lang/en_US.lang b/src/main/resources/assets/grapplemod/lang/en_US.lang similarity index 100% rename from main/resources/assets/grapplemod/lang/en_US.lang rename to src/main/resources/assets/grapplemod/lang/en_US.lang diff --git a/main/resources/assets/grapplemod/models/item/enderhook.json b/src/main/resources/assets/grapplemod/models/item/enderhook.json similarity index 100% rename from main/resources/assets/grapplemod/models/item/enderhook.json rename to src/main/resources/assets/grapplemod/models/item/enderhook.json diff --git a/main/resources/assets/grapplemod/models/item/grapplinghook.json b/src/main/resources/assets/grapplemod/models/item/grapplinghook.json similarity index 100% rename from main/resources/assets/grapplemod/models/item/grapplinghook.json rename to src/main/resources/assets/grapplemod/models/item/grapplinghook.json diff --git a/main/resources/assets/grapplemod/models/item/hookshot.json b/src/main/resources/assets/grapplemod/models/item/hookshot.json similarity index 100% rename from main/resources/assets/grapplemod/models/item/hookshot.json rename to src/main/resources/assets/grapplemod/models/item/hookshot.json diff --git a/main/resources/assets/grapplemod/models/item/hookshotrope.json b/src/main/resources/assets/grapplemod/models/item/hookshotrope.json similarity index 100% rename from main/resources/assets/grapplemod/models/item/hookshotrope.json rename to src/main/resources/assets/grapplemod/models/item/hookshotrope.json diff --git a/main/resources/assets/grapplemod/models/item/launcheritem.json b/src/main/resources/assets/grapplemod/models/item/launcheritem.json similarity index 100% rename from main/resources/assets/grapplemod/models/item/launcheritem.json rename to src/main/resources/assets/grapplemod/models/item/launcheritem.json diff --git a/main/resources/assets/grapplemod/models/item/longfallboots.json b/src/main/resources/assets/grapplemod/models/item/longfallboots.json similarity index 100% rename from main/resources/assets/grapplemod/models/item/longfallboots.json rename to src/main/resources/assets/grapplemod/models/item/longfallboots.json diff --git a/main/resources/assets/grapplemod/models/item/magnetbow.json b/src/main/resources/assets/grapplemod/models/item/magnetbow.json similarity index 100% rename from main/resources/assets/grapplemod/models/item/magnetbow.json rename to src/main/resources/assets/grapplemod/models/item/magnetbow.json diff --git a/main/resources/assets/grapplemod/models/item/multihook.json b/src/main/resources/assets/grapplemod/models/item/multihook.json similarity index 100% rename from main/resources/assets/grapplemod/models/item/multihook.json rename to src/main/resources/assets/grapplemod/models/item/multihook.json diff --git a/main/resources/assets/grapplemod/models/item/multihookrope.json b/src/main/resources/assets/grapplemod/models/item/multihookrope.json similarity index 100% rename from main/resources/assets/grapplemod/models/item/multihookrope.json rename to src/main/resources/assets/grapplemod/models/item/multihookrope.json diff --git a/main/resources/assets/grapplemod/models/item/repeller.json b/src/main/resources/assets/grapplemod/models/item/repeller.json similarity index 100% rename from main/resources/assets/grapplemod/models/item/repeller.json rename to src/main/resources/assets/grapplemod/models/item/repeller.json diff --git a/main/resources/assets/grapplemod/models/item/repelleron.json b/src/main/resources/assets/grapplemod/models/item/repelleron.json similarity index 100% rename from main/resources/assets/grapplemod/models/item/repelleron.json rename to src/main/resources/assets/grapplemod/models/item/repelleron.json diff --git a/main/resources/assets/grapplemod/models/item/rope.json b/src/main/resources/assets/grapplemod/models/item/rope.json similarity index 100% rename from main/resources/assets/grapplemod/models/item/rope.json rename to src/main/resources/assets/grapplemod/models/item/rope.json diff --git a/main/resources/assets/grapplemod/models/item/smarthook.json b/src/main/resources/assets/grapplemod/models/item/smarthook.json similarity index 100% rename from main/resources/assets/grapplemod/models/item/smarthook.json rename to src/main/resources/assets/grapplemod/models/item/smarthook.json diff --git a/main/resources/assets/grapplemod/models/item/smarthookrope.json b/src/main/resources/assets/grapplemod/models/item/smarthookrope.json similarity index 100% rename from main/resources/assets/grapplemod/models/item/smarthookrope.json rename to src/main/resources/assets/grapplemod/models/item/smarthookrope.json diff --git a/main/resources/assets/grapplemod/textures/items/enderhook.png b/src/main/resources/assets/grapplemod/textures/items/enderhook.png similarity index 100% rename from main/resources/assets/grapplemod/textures/items/enderhook.png rename to src/main/resources/assets/grapplemod/textures/items/enderhook.png diff --git a/main/resources/assets/grapplemod/textures/items/grapplinghook.png b/src/main/resources/assets/grapplemod/textures/items/grapplinghook.png similarity index 100% rename from main/resources/assets/grapplemod/textures/items/grapplinghook.png rename to src/main/resources/assets/grapplemod/textures/items/grapplinghook.png diff --git a/main/resources/assets/grapplemod/textures/items/hookshot.png b/src/main/resources/assets/grapplemod/textures/items/hookshot.png similarity index 100% rename from main/resources/assets/grapplemod/textures/items/hookshot.png rename to src/main/resources/assets/grapplemod/textures/items/hookshot.png diff --git a/main/resources/assets/grapplemod/textures/items/hookshotrope.png b/src/main/resources/assets/grapplemod/textures/items/hookshotrope.png similarity index 100% rename from main/resources/assets/grapplemod/textures/items/hookshotrope.png rename to src/main/resources/assets/grapplemod/textures/items/hookshotrope.png diff --git a/main/resources/assets/grapplemod/textures/items/launcheritem.png b/src/main/resources/assets/grapplemod/textures/items/launcheritem.png similarity index 100% rename from main/resources/assets/grapplemod/textures/items/launcheritem.png rename to src/main/resources/assets/grapplemod/textures/items/launcheritem.png diff --git a/main/resources/assets/grapplemod/textures/items/longfallboots.png b/src/main/resources/assets/grapplemod/textures/items/longfallboots.png similarity index 100% rename from main/resources/assets/grapplemod/textures/items/longfallboots.png rename to src/main/resources/assets/grapplemod/textures/items/longfallboots.png diff --git a/main/resources/assets/grapplemod/textures/items/magnetbow.png b/src/main/resources/assets/grapplemod/textures/items/magnetbow.png similarity index 100% rename from main/resources/assets/grapplemod/textures/items/magnetbow.png rename to src/main/resources/assets/grapplemod/textures/items/magnetbow.png diff --git a/main/resources/assets/grapplemod/textures/items/multihook.png b/src/main/resources/assets/grapplemod/textures/items/multihook.png similarity index 100% rename from main/resources/assets/grapplemod/textures/items/multihook.png rename to src/main/resources/assets/grapplemod/textures/items/multihook.png diff --git a/main/resources/assets/grapplemod/textures/items/multihookrope.png b/src/main/resources/assets/grapplemod/textures/items/multihookrope.png similarity index 100% rename from main/resources/assets/grapplemod/textures/items/multihookrope.png rename to src/main/resources/assets/grapplemod/textures/items/multihookrope.png diff --git a/main/resources/assets/grapplemod/textures/items/repeller.png b/src/main/resources/assets/grapplemod/textures/items/repeller.png similarity index 100% rename from main/resources/assets/grapplemod/textures/items/repeller.png rename to src/main/resources/assets/grapplemod/textures/items/repeller.png diff --git a/main/resources/assets/grapplemod/textures/items/repelleron.png b/src/main/resources/assets/grapplemod/textures/items/repelleron.png similarity index 100% rename from main/resources/assets/grapplemod/textures/items/repelleron.png rename to src/main/resources/assets/grapplemod/textures/items/repelleron.png diff --git a/main/resources/assets/grapplemod/textures/items/rope.png b/src/main/resources/assets/grapplemod/textures/items/rope.png similarity index 100% rename from main/resources/assets/grapplemod/textures/items/rope.png rename to src/main/resources/assets/grapplemod/textures/items/rope.png diff --git a/main/resources/assets/grapplemod/textures/items/smarthook.png b/src/main/resources/assets/grapplemod/textures/items/smarthook.png similarity index 100% rename from main/resources/assets/grapplemod/textures/items/smarthook.png rename to src/main/resources/assets/grapplemod/textures/items/smarthook.png diff --git a/main/resources/assets/grapplemod/textures/items/smarthookrope.png b/src/main/resources/assets/grapplemod/textures/items/smarthookrope.png similarity index 100% rename from main/resources/assets/grapplemod/textures/items/smarthookrope.png rename to src/main/resources/assets/grapplemod/textures/items/smarthookrope.png diff --git a/src/main/resources/mcmod.info b/src/main/resources/mcmod.info new file mode 100644 index 0000000..97e6de0 --- /dev/null +++ b/src/main/resources/mcmod.info @@ -0,0 +1,21 @@ +{ + "modListVersion": 2, + "modList": [{ + "modid": "${modId}", + "name": "${modName}", + "description": "A mod which adds grappling hooks", + "version": "${modVersion}", + "mcversion": "${minecraftVersion}", + "url": "", + "updateUrl": "", + "authorList": ["yyon"], + "credits": "", + "logoFile": "", + "screenshots": [], + "parent": "", + "requiredMods": [], + "dependencies": [], + "dependants": [], + "useDependencyInformation": true + }] +}