├── .gitattributes ├── .gitignore ├── LICENSE ├── PowerfulJS.iml ├── README.md ├── build.gradle ├── common.iml ├── common ├── build.gradle └── src │ └── main │ ├── java │ └── com │ │ └── prunoideae │ │ └── powerfuljs │ │ ├── CapabilityBuilder.java │ │ ├── CapabilityService.java │ │ ├── PowerfulJS.java │ │ ├── PowerfulJSPlugin.java │ │ ├── events │ │ ├── BlockEntityCapEventJS.java │ │ └── EntityCapEventJS.java │ │ ├── mixins │ │ ├── BlockEntityInfoMixin.java │ │ ├── ItemBuilderMixin.java │ │ └── ItemMixin.java │ │ └── proxy │ │ ├── PowerfulJSClient.java │ │ └── PowerfulJSCommon.java │ └── resources │ ├── powerfuljs-common.accesswidener │ └── powerfuljs-common.mixins.json ├── examples ├── 1.gif ├── 1.js ├── 2.gif ├── 2.js ├── 3.gif └── 3.js ├── fabric.iml ├── fabric ├── build.gradle └── src │ └── main │ ├── java │ └── com │ │ └── prunoideae │ │ └── powerfuljs │ │ └── fabric │ │ ├── CapabilitiesFabric.java │ │ ├── PowerfulJSFabric.java │ │ └── PowerfulJSPluginFabric.java │ └── resources │ ├── fabric.mod.json │ ├── kubejs.plugins.txt │ └── powerfuljs-fabric.mixins.json ├── forge.iml ├── forge ├── build.gradle ├── gradle.properties └── src │ └── main │ ├── java │ └── com │ │ └── prunoideae │ │ └── powerfuljs │ │ ├── capabilities │ │ └── forge │ │ │ ├── CapabilitiesForge.java │ │ │ ├── CapabilityBuilderForge.java │ │ │ ├── CapabilityFluid.java │ │ │ ├── CapabilityForgeEnergy.java │ │ │ ├── CapabilityItem.java │ │ │ ├── CapabilityProvider.java │ │ │ └── mods │ │ │ ├── botania │ │ │ ├── CapabilitiesBotania.java │ │ │ ├── CapabilityAvatar.java │ │ │ ├── CapabilityBlockProvider.java │ │ │ ├── CapabilityExoflame.java │ │ │ ├── CapabilityMana.java │ │ │ └── CapabilityRelic.java │ │ │ ├── curios │ │ │ ├── CapabilitiesCurios.java │ │ │ ├── CapabilityCurios.java │ │ │ ├── EventCurios.java │ │ │ ├── RegisterCuriosRendererEventJS.java │ │ │ └── RendererCurios.java │ │ │ ├── immersive │ │ │ ├── CapabilitiesHelperIE.java │ │ │ ├── CapabilitiesIE.java │ │ │ ├── CapabilityExternalHeatable.java │ │ │ └── CapabilityRotationAcceptor.java │ │ │ ├── mekanism │ │ │ ├── CapabilitiesMekanism.java │ │ │ ├── CapabilityAlloyInteractable.java │ │ │ ├── CapabilityConfigurable.java │ │ │ ├── CapabilityEvaporationTower.java │ │ │ ├── CapabilityLaser.java │ │ │ ├── CapabilityProtection.java │ │ │ ├── MekanismHelper.java │ │ │ └── chemical │ │ │ │ ├── CapabilityChemical.java │ │ │ │ ├── CapabilityGas.java │ │ │ │ ├── CapabilityInfusion.java │ │ │ │ ├── CapabilityPigment.java │ │ │ │ └── CapabilitySlurry.java │ │ │ └── pnc │ │ │ ├── CapabilitiesPneumatic.java │ │ │ └── CapabilityAir.java │ │ ├── events │ │ └── forge │ │ │ ├── DynamicAttachEventJS.java │ │ │ ├── DynamicBEEventJS.java │ │ │ ├── DynamicEntityEventJS.java │ │ │ └── DynamicItemStackEventJS.java │ │ └── forge │ │ ├── CapabilityServiceForge.java │ │ ├── PowerfulJSEvents.java │ │ ├── PowerfulJSForge.java │ │ └── PowerfulJSPluginForge.java │ └── resources │ ├── META-INF │ ├── accesstransformer.cfg │ └── mods.toml │ ├── icon.png │ ├── kubejs.plugins.txt │ ├── pack.mcmeta │ └── powerfuljs-forge.mixins.json ├── gradle.properties ├── gradle └── wrapper │ └── gradle-wrapper.properties └── settings.gradle /.gitattributes: -------------------------------------------------------------------------------- 1 | # Auto detect text files and perform LF normalization 2 | * text=auto 3 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .idea 2 | .gradle 3 | .architectury-transformer 4 | **/build/ 5 | !src/**/build/ 6 | 7 | # Ignore Gradle GUI config 8 | gradle-app.setting 9 | 10 | # Avoid ignoring Gradle wrapper jar file (.jar files are usually ignored) 11 | !gradle-wrapper.jar 12 | 13 | # Cache of project 14 | .gradletasknamecache 15 | 16 | # Eclipse Gradle plugin generated files 17 | # Eclipse Core 18 | .project 19 | # JDT-specific (Eclipse Java Development Tools) 20 | .classpath 21 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | GNU LESSER GENERAL PUBLIC LICENSE 2 | Version 2.1, February 1999 3 | 4 | Copyright (C) 1991, 1999 Free Software Foundation, Inc. 5 | 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 6 | Everyone is permitted to copy and distribute verbatim copies 7 | of this license document, but changing it is not allowed. 8 | 9 | [This is the first released version of the Lesser GPL. It also counts 10 | as the successor of the GNU Library Public License, version 2, hence 11 | the version number 2.1.] 12 | 13 | Preamble 14 | 15 | The licenses for most software are designed to take away your 16 | freedom to share and change it. By contrast, the GNU General Public 17 | Licenses are intended to guarantee your freedom to share and change 18 | free software--to make sure the software is free for all its users. 19 | 20 | This license, the Lesser General Public License, applies to some 21 | specially designated software packages--typically libraries--of the 22 | Free Software Foundation and other authors who decide to use it. You 23 | can use it too, but we suggest you first think carefully about whether 24 | this license or the ordinary General Public License is the better 25 | strategy to use in any particular case, based on the explanations below. 26 | 27 | When we speak of free software, we are referring to freedom of use, 28 | not price. Our General Public Licenses are designed to make sure that 29 | you have the freedom to distribute copies of free software (and charge 30 | for this service if you wish); that you receive source code or can get 31 | it if you want it; that you can change the software and use pieces of 32 | it in new free programs; and that you are informed that you can do 33 | these things. 34 | 35 | To protect your rights, we need to make restrictions that forbid 36 | distributors to deny you these rights or to ask you to surrender these 37 | rights. These restrictions translate to certain responsibilities for 38 | you if you distribute copies of the library or if you modify it. 39 | 40 | For example, if you distribute copies of the library, whether gratis 41 | or for a fee, you must give the recipients all the rights that we gave 42 | you. You must make sure that they, too, receive or can get the source 43 | code. If you link other code with the library, you must provide 44 | complete object files to the recipients, so that they can relink them 45 | with the library after making changes to the library and recompiling 46 | it. And you must show them these terms so they know their rights. 47 | 48 | We protect your rights with a two-step method: (1) we copyright the 49 | library, and (2) we offer you this license, which gives you legal 50 | permission to copy, distribute and/or modify the library. 51 | 52 | To protect each distributor, we want to make it very clear that 53 | there is no warranty for the free library. Also, if the library is 54 | modified by someone else and passed on, the recipients should know 55 | that what they have is not the original version, so that the original 56 | author's reputation will not be affected by problems that might be 57 | introduced by others. 58 | 59 | Finally, software patents pose a constant threat to the existence of 60 | any free program. We wish to make sure that a company cannot 61 | effectively restrict the users of a free program by obtaining a 62 | restrictive license from a patent holder. Therefore, we insist that 63 | any patent license obtained for a version of the library must be 64 | consistent with the full freedom of use specified in this license. 65 | 66 | Most GNU software, including some libraries, is covered by the 67 | ordinary GNU General Public License. This license, the GNU Lesser 68 | General Public License, applies to certain designated libraries, and 69 | is quite different from the ordinary General Public License. We use 70 | this license for certain libraries in order to permit linking those 71 | libraries into non-free programs. 72 | 73 | When a program is linked with a library, whether statically or using 74 | a shared library, the combination of the two is legally speaking a 75 | combined work, a derivative of the original library. The ordinary 76 | General Public License therefore permits such linking only if the 77 | entire combination fits its criteria of freedom. The Lesser General 78 | Public License permits more lax criteria for linking other code with 79 | the library. 80 | 81 | We call this license the "Lesser" General Public License because it 82 | does Less to protect the user's freedom than the ordinary General 83 | Public License. It also provides other free software developers Less 84 | of an advantage over competing non-free programs. These disadvantages 85 | are the reason we use the ordinary General Public License for many 86 | libraries. However, the Lesser license provides advantages in certain 87 | special circumstances. 88 | 89 | For example, on rare occasions, there may be a special need to 90 | encourage the widest possible use of a certain library, so that it becomes 91 | a de-facto standard. To achieve this, non-free programs must be 92 | allowed to use the library. A more frequent case is that a free 93 | library does the same job as widely used non-free libraries. In this 94 | case, there is little to gain by limiting the free library to free 95 | software only, so we use the Lesser General Public License. 96 | 97 | In other cases, permission to use a particular library in non-free 98 | programs enables a greater number of people to use a large body of 99 | free software. For example, permission to use the GNU C Library in 100 | non-free programs enables many more people to use the whole GNU 101 | operating system, as well as its variant, the GNU/Linux operating 102 | system. 103 | 104 | Although the Lesser General Public License is Less protective of the 105 | users' freedom, it does ensure that the user of a program that is 106 | linked with the Library has the freedom and the wherewithal to run 107 | that program using a modified version of the Library. 108 | 109 | The precise terms and conditions for copying, distribution and 110 | modification follow. Pay close attention to the difference between a 111 | "work based on the library" and a "work that uses the library". The 112 | former contains code derived from the library, whereas the latter must 113 | be combined with the library in order to run. 114 | 115 | GNU LESSER GENERAL PUBLIC LICENSE 116 | TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION 117 | 118 | 0. This License Agreement applies to any software library or other 119 | program which contains a notice placed by the copyright holder or 120 | other authorized party saying it may be distributed under the terms of 121 | this Lesser General Public License (also called "this License"). 122 | Each licensee is addressed as "you". 123 | 124 | A "library" means a collection of software functions and/or data 125 | prepared so as to be conveniently linked with application programs 126 | (which use some of those functions and data) to form executables. 127 | 128 | The "Library", below, refers to any such software library or work 129 | which has been distributed under these terms. A "work based on the 130 | Library" means either the Library or any derivative work under 131 | copyright law: that is to say, a work containing the Library or a 132 | portion of it, either verbatim or with modifications and/or translated 133 | straightforwardly into another language. (Hereinafter, translation is 134 | included without limitation in the term "modification".) 135 | 136 | "Source code" for a work means the preferred form of the work for 137 | making modifications to it. For a library, complete source code means 138 | all the source code for all modules it contains, plus any associated 139 | interface definition files, plus the scripts used to control compilation 140 | and installation of the library. 141 | 142 | Activities other than copying, distribution and modification are not 143 | covered by this License; they are outside its scope. The act of 144 | running a program using the Library is not restricted, and output from 145 | such a program is covered only if its contents constitute a work based 146 | on the Library (independent of the use of the Library in a tool for 147 | writing it). Whether that is true depends on what the Library does 148 | and what the program that uses the Library does. 149 | 150 | 1. You may copy and distribute verbatim copies of the Library's 151 | complete source code as you receive it, in any medium, provided that 152 | you conspicuously and appropriately publish on each copy an 153 | appropriate copyright notice and disclaimer of warranty; keep intact 154 | all the notices that refer to this License and to the absence of any 155 | warranty; and distribute a copy of this License along with the 156 | Library. 157 | 158 | You may charge a fee for the physical act of transferring a copy, 159 | and you may at your option offer warranty protection in exchange for a 160 | fee. 161 | 162 | 2. You may modify your copy or copies of the Library or any portion 163 | of it, thus forming a work based on the Library, and copy and 164 | distribute such modifications or work under the terms of Section 1 165 | above, provided that you also meet all of these conditions: 166 | 167 | a) The modified work must itself be a software library. 168 | 169 | b) You must cause the files modified to carry prominent notices 170 | stating that you changed the files and the date of any change. 171 | 172 | c) You must cause the whole of the work to be licensed at no 173 | charge to all third parties under the terms of this License. 174 | 175 | d) If a facility in the modified Library refers to a function or a 176 | table of data to be supplied by an application program that uses 177 | the facility, other than as an argument passed when the facility 178 | is invoked, then you must make a good faith effort to ensure that, 179 | in the event an application does not supply such function or 180 | table, the facility still operates, and performs whatever part of 181 | its purpose remains meaningful. 182 | 183 | (For example, a function in a library to compute square roots has 184 | a purpose that is entirely well-defined independent of the 185 | application. Therefore, Subsection 2d requires that any 186 | application-supplied function or table used by this function must 187 | be optional: if the application does not supply it, the square 188 | root function must still compute square roots.) 189 | 190 | These requirements apply to the modified work as a whole. If 191 | identifiable sections of that work are not derived from the Library, 192 | and can be reasonably considered independent and separate works in 193 | themselves, then this License, and its terms, do not apply to those 194 | sections when you distribute them as separate works. But when you 195 | distribute the same sections as part of a whole which is a work based 196 | on the Library, the distribution of the whole must be on the terms of 197 | this License, whose permissions for other licensees extend to the 198 | entire whole, and thus to each and every part regardless of who wrote 199 | it. 200 | 201 | Thus, it is not the intent of this section to claim rights or contest 202 | your rights to work written entirely by you; rather, the intent is to 203 | exercise the right to control the distribution of derivative or 204 | collective works based on the Library. 205 | 206 | In addition, mere aggregation of another work not based on the Library 207 | with the Library (or with a work based on the Library) on a volume of 208 | a storage or distribution medium does not bring the other work under 209 | the scope of this License. 210 | 211 | 3. You may opt to apply the terms of the ordinary GNU General Public 212 | License instead of this License to a given copy of the Library. To do 213 | this, you must alter all the notices that refer to this License, so 214 | that they refer to the ordinary GNU General Public License, version 2, 215 | instead of to this License. (If a newer version than version 2 of the 216 | ordinary GNU General Public License has appeared, then you can specify 217 | that version instead if you wish.) Do not make any other change in 218 | these notices. 219 | 220 | Once this change is made in a given copy, it is irreversible for 221 | that copy, so the ordinary GNU General Public License applies to all 222 | subsequent copies and derivative works made from that copy. 223 | 224 | This option is useful when you wish to copy part of the code of 225 | the Library into a program that is not a library. 226 | 227 | 4. You may copy and distribute the Library (or a portion or 228 | derivative of it, under Section 2) in object code or executable form 229 | under the terms of Sections 1 and 2 above provided that you accompany 230 | it with the complete corresponding machine-readable source code, which 231 | must be distributed under the terms of Sections 1 and 2 above on a 232 | medium customarily used for software interchange. 233 | 234 | If distribution of object code is made by offering access to copy 235 | from a designated place, then offering equivalent access to copy the 236 | source code from the same place satisfies the requirement to 237 | distribute the source code, even though third parties are not 238 | compelled to copy the source along with the object code. 239 | 240 | 5. A program that contains no derivative of any portion of the 241 | Library, but is designed to work with the Library by being compiled or 242 | linked with it, is called a "work that uses the Library". Such a 243 | work, in isolation, is not a derivative work of the Library, and 244 | therefore falls outside the scope of this License. 245 | 246 | However, linking a "work that uses the Library" with the Library 247 | creates an executable that is a derivative of the Library (because it 248 | contains portions of the Library), rather than a "work that uses the 249 | library". The executable is therefore covered by this License. 250 | Section 6 states terms for distribution of such executables. 251 | 252 | When a "work that uses the Library" uses material from a header file 253 | that is part of the Library, the object code for the work may be a 254 | derivative work of the Library even though the source code is not. 255 | Whether this is true is especially significant if the work can be 256 | linked without the Library, or if the work is itself a library. The 257 | threshold for this to be true is not precisely defined by law. 258 | 259 | If such an object file uses only numerical parameters, data 260 | structure layouts and accessors, and small macros and small inline 261 | functions (ten lines or less in length), then the use of the object 262 | file is unrestricted, regardless of whether it is legally a derivative 263 | work. (Executables containing this object code plus portions of the 264 | Library will still fall under Section 6.) 265 | 266 | Otherwise, if the work is a derivative of the Library, you may 267 | distribute the object code for the work under the terms of Section 6. 268 | Any executables containing that work also fall under Section 6, 269 | whether or not they are linked directly with the Library itself. 270 | 271 | 6. As an exception to the Sections above, you may also combine or 272 | link a "work that uses the Library" with the Library to produce a 273 | work containing portions of the Library, and distribute that work 274 | under terms of your choice, provided that the terms permit 275 | modification of the work for the customer's own use and reverse 276 | engineering for debugging such modifications. 277 | 278 | You must give prominent notice with each copy of the work that the 279 | Library is used in it and that the Library and its use are covered by 280 | this License. You must supply a copy of this License. If the work 281 | during execution displays copyright notices, you must include the 282 | copyright notice for the Library among them, as well as a reference 283 | directing the user to the copy of this License. Also, you must do one 284 | of these things: 285 | 286 | a) Accompany the work with the complete corresponding 287 | machine-readable source code for the Library including whatever 288 | changes were used in the work (which must be distributed under 289 | Sections 1 and 2 above); and, if the work is an executable linked 290 | with the Library, with the complete machine-readable "work that 291 | uses the Library", as object code and/or source code, so that the 292 | user can modify the Library and then relink to produce a modified 293 | executable containing the modified Library. (It is understood 294 | that the user who changes the contents of definitions files in the 295 | Library will not necessarily be able to recompile the application 296 | to use the modified definitions.) 297 | 298 | b) Use a suitable shared library mechanism for linking with the 299 | Library. A suitable mechanism is one that (1) uses at run time a 300 | copy of the library already present on the user's computer system, 301 | rather than copying library functions into the executable, and (2) 302 | will operate properly with a modified version of the library, if 303 | the user installs one, as long as the modified version is 304 | interface-compatible with the version that the work was made with. 305 | 306 | c) Accompany the work with a written offer, valid for at 307 | least three years, to give the same user the materials 308 | specified in Subsection 6a, above, for a charge no more 309 | than the cost of performing this distribution. 310 | 311 | d) If distribution of the work is made by offering access to copy 312 | from a designated place, offer equivalent access to copy the above 313 | specified materials from the same place. 314 | 315 | e) Verify that the user has already received a copy of these 316 | materials or that you have already sent this user a copy. 317 | 318 | For an executable, the required form of the "work that uses the 319 | Library" must include any data and utility programs needed for 320 | reproducing the executable from it. However, as a special exception, 321 | the materials to be distributed need not include anything that is 322 | normally distributed (in either source or binary form) with the major 323 | components (compiler, kernel, and so on) of the operating system on 324 | which the executable runs, unless that component itself accompanies 325 | the executable. 326 | 327 | It may happen that this requirement contradicts the license 328 | restrictions of other proprietary libraries that do not normally 329 | accompany the operating system. Such a contradiction means you cannot 330 | use both them and the Library together in an executable that you 331 | distribute. 332 | 333 | 7. You may place library facilities that are a work based on the 334 | Library side-by-side in a single library together with other library 335 | facilities not covered by this License, and distribute such a combined 336 | library, provided that the separate distribution of the work based on 337 | the Library and of the other library facilities is otherwise 338 | permitted, and provided that you do these two things: 339 | 340 | a) Accompany the combined library with a copy of the same work 341 | based on the Library, uncombined with any other library 342 | facilities. This must be distributed under the terms of the 343 | Sections above. 344 | 345 | b) Give prominent notice with the combined library of the fact 346 | that part of it is a work based on the Library, and explaining 347 | where to find the accompanying uncombined form of the same work. 348 | 349 | 8. You may not copy, modify, sublicense, link with, or distribute 350 | the Library except as expressly provided under this License. Any 351 | attempt otherwise to copy, modify, sublicense, link with, or 352 | distribute the Library is void, and will automatically terminate your 353 | rights under this License. However, parties who have received copies, 354 | or rights, from you under this License will not have their licenses 355 | terminated so long as such parties remain in full compliance. 356 | 357 | 9. You are not required to accept this License, since you have not 358 | signed it. However, nothing else grants you permission to modify or 359 | distribute the Library or its derivative works. These actions are 360 | prohibited by law if you do not accept this License. Therefore, by 361 | modifying or distributing the Library (or any work based on the 362 | Library), you indicate your acceptance of this License to do so, and 363 | all its terms and conditions for copying, distributing or modifying 364 | the Library or works based on it. 365 | 366 | 10. Each time you redistribute the Library (or any work based on the 367 | Library), the recipient automatically receives a license from the 368 | original licensor to copy, distribute, link with or modify the Library 369 | subject to these terms and conditions. You may not impose any further 370 | restrictions on the recipients' exercise of the rights granted herein. 371 | You are not responsible for enforcing compliance by third parties with 372 | this License. 373 | 374 | 11. If, as a consequence of a court judgment or allegation of patent 375 | infringement or for any other reason (not limited to patent issues), 376 | conditions are imposed on you (whether by court order, agreement or 377 | otherwise) that contradict the conditions of this License, they do not 378 | excuse you from the conditions of this License. If you cannot 379 | distribute so as to satisfy simultaneously your obligations under this 380 | License and any other pertinent obligations, then as a consequence you 381 | may not distribute the Library at all. For example, if a patent 382 | license would not permit royalty-free redistribution of the Library by 383 | all those who receive copies directly or indirectly through you, then 384 | the only way you could satisfy both it and this License would be to 385 | refrain entirely from distribution of the Library. 386 | 387 | If any portion of this section is held invalid or unenforceable under any 388 | particular circumstance, the balance of the section is intended to apply, 389 | and the section as a whole is intended to apply in other circumstances. 390 | 391 | It is not the purpose of this section to induce you to infringe any 392 | patents or other property right claims or to contest validity of any 393 | such claims; this section has the sole purpose of protecting the 394 | integrity of the free software distribution system which is 395 | implemented by public license practices. Many people have made 396 | generous contributions to the wide range of software distributed 397 | through that system in reliance on consistent application of that 398 | system; it is up to the author/donor to decide if he or she is willing 399 | to distribute software through any other system and a licensee cannot 400 | impose that choice. 401 | 402 | This section is intended to make thoroughly clear what is believed to 403 | be a consequence of the rest of this License. 404 | 405 | 12. If the distribution and/or use of the Library is restricted in 406 | certain countries either by patents or by copyrighted interfaces, the 407 | original copyright holder who places the Library under this License may add 408 | an explicit geographical distribution limitation excluding those countries, 409 | so that distribution is permitted only in or among countries not thus 410 | excluded. In such case, this License incorporates the limitation as if 411 | written in the body of this License. 412 | 413 | 13. The Free Software Foundation may publish revised and/or new 414 | versions of the Lesser General Public License from time to time. 415 | Such new versions will be similar in spirit to the present version, 416 | but may differ in detail to address new problems or concerns. 417 | 418 | Each version is given a distinguishing version number. If the Library 419 | specifies a version number of this License which applies to it and 420 | "any later version", you have the option of following the terms and 421 | conditions either of that version or of any later version published by 422 | the Free Software Foundation. If the Library does not specify a 423 | license version number, you may choose any version ever published by 424 | the Free Software Foundation. 425 | 426 | 14. If you wish to incorporate parts of the Library into other free 427 | programs whose distribution conditions are incompatible with these, 428 | write to the author to ask for permission. For software which is 429 | copyrighted by the Free Software Foundation, write to the Free 430 | Software Foundation; we sometimes make exceptions for this. Our 431 | decision will be guided by the two goals of preserving the free status 432 | of all derivatives of our free software and of promoting the sharing 433 | and reuse of software generally. 434 | 435 | NO WARRANTY 436 | 437 | 15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO 438 | WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW. 439 | EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR 440 | OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY 441 | KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE 442 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 443 | PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE 444 | LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME 445 | THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. 446 | 447 | 16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN 448 | WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY 449 | AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU 450 | FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR 451 | CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE 452 | LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING 453 | RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A 454 | FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF 455 | SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH 456 | DAMAGES. 457 | 458 | END OF TERMS AND CONDITIONS 459 | 460 | How to Apply These Terms to Your New Libraries 461 | 462 | If you develop a new library, and you want it to be of the greatest 463 | possible use to the public, we recommend making it free software that 464 | everyone can redistribute and change. You can do so by permitting 465 | redistribution under these terms (or, alternatively, under the terms of the 466 | ordinary General Public License). 467 | 468 | To apply these terms, attach the following notices to the library. It is 469 | safest to attach them to the start of each source file to most effectively 470 | convey the exclusion of warranty; and each file should have at least the 471 | "copyright" line and a pointer to where the full notice is found. 472 | 473 | 474 | Copyright (C) 475 | 476 | This library is free software; you can redistribute it and/or 477 | modify it under the terms of the GNU Lesser General Public 478 | License as published by the Free Software Foundation; either 479 | version 2.1 of the License, or (at your option) any later version. 480 | 481 | This library is distributed in the hope that it will be useful, 482 | but WITHOUT ANY WARRANTY; without even the implied warranty of 483 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 484 | Lesser General Public License for more details. 485 | 486 | You should have received a copy of the GNU Lesser General Public 487 | License along with this library; if not, write to the Free Software 488 | Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 489 | USA 490 | 491 | Also add information on how to contact you by electronic and paper mail. 492 | 493 | You should also get your employer (if you work as a programmer) or your 494 | school, if any, to sign a "copyright disclaimer" for the library, if 495 | necessary. Here is a sample; alter the names: 496 | 497 | Yoyodyne, Inc., hereby disclaims all copyright interest in the 498 | library `Frob' (a library for tweaking knobs) written by James Random 499 | Hacker. 500 | 501 | , 1 April 1990 502 | Ty Coon, President of Vice 503 | 504 | That's all there is to it! 505 | -------------------------------------------------------------------------------- /PowerfulJS.iml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # PowerfulJS 2 | Attach capabilities to many things, via KubeJS 3 | -------------------------------------------------------------------------------- /build.gradle: -------------------------------------------------------------------------------- 1 | plugins { 2 | id "architectury-plugin" version "3.4-SNAPSHOT" 3 | id "dev.architectury.loom" version "0.11.0-SNAPSHOT" apply false 4 | } 5 | 6 | architectury { 7 | minecraft = rootProject.minecraft_version 8 | } 9 | 10 | subprojects { 11 | apply plugin: "dev.architectury.loom" 12 | 13 | loom { 14 | silentMojangMappingsLicense() 15 | } 16 | 17 | dependencies { 18 | minecraft "com.mojang:minecraft:${rootProject.minecraft_version}" 19 | // The following line declares the mojmap mappings, you may use other mappings as well 20 | mappings loom.officialMojangMappings() 21 | // The following line declares the yarn mappings you may select this one as well. 22 | // mappings "net.fabricmc:yarn:@YARN_MAPPINGS@:v2" 23 | } 24 | } 25 | 26 | allprojects { 27 | apply plugin: "java" 28 | apply plugin: "architectury-plugin" 29 | apply plugin: "maven-publish" 30 | 31 | archivesBaseName = rootProject.archives_base_name 32 | version = rootProject.mod_version 33 | group = rootProject.maven_group 34 | 35 | repositories { 36 | maven { 37 | name = "C4" 38 | url = "https://maven.theillusivec4.top/" 39 | } 40 | maven { 41 | url "https://maven.architectury.dev/" 42 | content { 43 | includeGroup "me.shedaniel" 44 | } 45 | } 46 | maven { 47 | url "https://maven.saps.dev/minecraft" 48 | content { 49 | includeGroup "dev.latvian.mods" 50 | includeGroup "dev.ftb.mods" 51 | } 52 | } 53 | maven { 54 | name = "Modmuss" 55 | url = "https://maven.modmuss50.me/" 56 | } 57 | maven { 58 | name = "Jared" 59 | url = "https://maven.blamejared.com/" 60 | } 61 | maven { 62 | url = "https://maven.terraformersmc.com/" // for trinkets 63 | } 64 | maven { 65 | name = "BuildCraft" // for LBA 66 | url = "https://mod-buildcraft.com/maven" 67 | } 68 | maven { 69 | name "entity reach" 70 | url "https://maven.jamieswhiteshirt.com/libs-release/" 71 | } 72 | maven { 73 | url "https://jitpack.io" // for step height eam 74 | } 75 | maven { 76 | url "https://maven.shedaniel.me/" // for rei 77 | } 78 | maven { 79 | url "https://server.bbkr.space/artifactory/libs-release/" // for bannerplusplus 80 | } 81 | maven { 82 | name = "ParchmentMC" 83 | url = "https://maven.parchmentmc.net/" 84 | } 85 | maven { 86 | name = "Modrinth" 87 | url = "https://api.modrinth.com/maven" 88 | content { 89 | includeGroup "maven.modrinth" 90 | } 91 | } 92 | maven { 93 | name = "Ladysnake Libs" 94 | url = 'https://maven.ladysnake.org/releases' 95 | } 96 | maven { 97 | // location of the maven that hosts JEI files 98 | name = "Progwml6 maven" 99 | url = "https://dvs1.progwml6.com/files/maven/" 100 | } 101 | maven { 102 | // location of a maven mirror for JEI files, as a fallback 103 | name = "ModMaven" 104 | url = "https://modmaven.dev" 105 | } 106 | maven { 107 | // Location of the maven for mixed mappings, Registrate, and Flywheel 108 | name 'tterrag maven' 109 | url 'https://maven.tterrag.com' 110 | } 111 | maven { 112 | // location of maven for CC: Tweaked 113 | name = "squiddev" 114 | url = "https://squiddev.cc/maven/" 115 | content { 116 | includeGroup "org.squiddev" 117 | } 118 | } 119 | maven { 120 | url 'https://www.cursemaven.com' 121 | content { 122 | includeGroup "curse.maven" 123 | } 124 | } 125 | } 126 | 127 | 128 | tasks.withType(JavaCompile) { 129 | options.encoding = "UTF-8" 130 | options.release = 17 131 | } 132 | 133 | java { 134 | withSourcesJar() 135 | } 136 | } 137 | -------------------------------------------------------------------------------- /common.iml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /common/build.gradle: -------------------------------------------------------------------------------- 1 | dependencies { 2 | // We depend on fabric loader here to use the fabric @Environment annotations and get the mixin dependencies 3 | // Do NOT use other classes from fabric loader 4 | modImplementation "net.fabricmc:fabric-loader:${rootProject.fabric_loader_version}" 5 | // Remove the next line if you don't want to depend on the API 6 | modApi "dev.architectury:architectury:${rootProject.architectury_version}" 7 | modImplementation "dev.latvian.mods:kubejs-fabric:${rootProject.kubejs_version}" 8 | modImplementation "dev.latvian.mods:rhino:${rootProject.rhino_version}" 9 | modImplementation "vazkii.botania:Botania-xplat:${rootProject.botania_version}" 10 | } 11 | 12 | loom { 13 | accessWidenerPath = file("src/main/resources/powerfuljs-common.accesswidener") 14 | } 15 | 16 | architectury { 17 | common() 18 | } 19 | 20 | publishing { 21 | publications { 22 | mavenCommon(MavenPublication) { 23 | artifactId = rootProject.archives_base_name 24 | from components.java 25 | } 26 | } 27 | 28 | // See https://docs.gradle.org/current/userguide/publishing_maven.html for information on how to set up publishing. 29 | repositories { 30 | // Add repositories to publish to here. 31 | } 32 | } -------------------------------------------------------------------------------- /common/src/main/java/com/prunoideae/powerfuljs/CapabilityBuilder.java: -------------------------------------------------------------------------------- 1 | package com.prunoideae.powerfuljs; 2 | 3 | import dev.latvian.mods.rhino.util.HideFromJS; 4 | import net.minecraft.core.Direction; 5 | import net.minecraft.resources.ResourceLocation; 6 | 7 | import java.util.function.BiPredicate; 8 | 9 | public abstract class CapabilityBuilder { 10 | protected BiPredicate isAvailable = (a, b) -> true; 11 | 12 | @HideFromJS 13 | public abstract T getCapability(I instance); 14 | 15 | @HideFromJS 16 | public abstract K getCapabilityKey(); 17 | 18 | @HideFromJS 19 | public abstract ResourceLocation getResourceLocation(); 20 | 21 | public CapabilityBuilder availableOn(BiPredicate isAvailable) { 22 | this.isAvailable = isAvailable; 23 | return this; 24 | } 25 | 26 | public CapabilityBuilder side(Direction direction) { 27 | this.isAvailable = (a, b) -> b.equals(direction); 28 | return this; 29 | } 30 | 31 | @HideFromJS 32 | public BiPredicate getDirection() { 33 | return isAvailable; 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /common/src/main/java/com/prunoideae/powerfuljs/CapabilityService.java: -------------------------------------------------------------------------------- 1 | package com.prunoideae.powerfuljs; 2 | 3 | import com.mojang.datafixers.util.Pair; 4 | import dev.latvian.mods.kubejs.block.entity.BlockEntityInfo; 5 | import dev.latvian.mods.kubejs.item.ItemBuilder; 6 | import net.minecraft.world.entity.Entity; 7 | import net.minecraft.world.entity.EntityType; 8 | import net.minecraft.world.item.Item; 9 | import net.minecraft.world.item.ItemStack; 10 | import net.minecraft.world.level.block.entity.BlockEntity; 11 | import net.minecraft.world.level.block.entity.BlockEntityType; 12 | 13 | import java.util.*; 14 | 15 | public class CapabilityService { 16 | public static final CapabilityService INSTANCE = new CapabilityService(); 17 | protected final Map>> itemBuilders = new HashMap<>(); 18 | protected final Map>> items = new HashMap<>(); 19 | protected final Map, List>> blockEntities = new HashMap<>(); 20 | protected final Map, List>> entities = new HashMap<>(); 21 | protected final List>> blockEntityInfo = new ArrayList<>(); 22 | 23 | public void addLazyBECapability(BlockEntityInfo info, CapabilityBuilder capabilityBuilder) { 24 | blockEntityInfo.add(Pair.of(info, capabilityBuilder)); 25 | } 26 | 27 | public void resolveLazyBECapabilities() { 28 | if (!blockEntityInfo.isEmpty()) { 29 | for (Pair> pair : blockEntityInfo) { 30 | addBECapability(pair.getFirst().entityType, pair.getSecond()); 31 | } 32 | blockEntityInfo.clear(); 33 | } 34 | } 35 | 36 | public void addBuilderCapability(ItemBuilder builder, CapabilityBuilder capabilityBuilder) { 37 | itemBuilders.computeIfAbsent(builder, b -> new ArrayList<>()).add(capabilityBuilder); 38 | } 39 | 40 | public void addItemCapability(Item item, CapabilityBuilder capabilityBuilder) { 41 | items.computeIfAbsent(item, i -> new ArrayList<>()).add(capabilityBuilder); 42 | } 43 | 44 | public void addBECapability(BlockEntityType type, CapabilityBuilder capabilityBuilder) { 45 | blockEntities.computeIfAbsent(type, b -> new ArrayList<>()).add(capabilityBuilder); 46 | } 47 | 48 | public void addEntityCapability(EntityType type, CapabilityBuilder capabilityBuilder) { 49 | entities.computeIfAbsent(type, e -> new ArrayList<>()).add(capabilityBuilder); 50 | } 51 | 52 | public void loadBuilders() { 53 | for (Map.Entry>> entry : itemBuilders.entrySet()) { 54 | ItemBuilder builder = entry.getKey(); 55 | List> capabilityBuilder = entry.getValue(); 56 | items.computeIfAbsent(builder.get(), i -> new ArrayList<>()).addAll(capabilityBuilder); 57 | } 58 | } 59 | 60 | public Optional>> getCapabilitiesFor(ItemStack itemStack) { 61 | return Optional.ofNullable(items.get(itemStack.getItem())); 62 | } 63 | 64 | public Optional>> getCapabilitiesFor(BlockEntity blockEntity) { 65 | CapabilityService.INSTANCE.resolveLazyBECapabilities(); 66 | return Optional.ofNullable(blockEntities.get(blockEntity.getType())); 67 | } 68 | 69 | public Optional>> getCapabilitiesFor(Entity entity) { 70 | return Optional.ofNullable(entities.get(entity.getType())); 71 | } 72 | } 73 | -------------------------------------------------------------------------------- /common/src/main/java/com/prunoideae/powerfuljs/PowerfulJS.java: -------------------------------------------------------------------------------- 1 | package com.prunoideae.powerfuljs; 2 | 3 | import com.google.common.base.Suppliers; 4 | import com.prunoideae.powerfuljs.proxy.PowerfulJSClient; 5 | import com.prunoideae.powerfuljs.proxy.PowerfulJSCommon; 6 | import dev.architectury.utils.EnvExecutor; 7 | import org.apache.logging.log4j.LogManager; 8 | import org.apache.logging.log4j.Logger; 9 | 10 | import java.util.function.Supplier; 11 | 12 | 13 | public class PowerfulJS { 14 | public static final String MOD_ID = "powerfuljs"; 15 | public static Supplier PROXY = Suppliers.memoize(() -> EnvExecutor.getEnvSpecific(() -> PowerfulJSClient::new, () -> PowerfulJSCommon::new)); 16 | 17 | public static void init() { 18 | 19 | } 20 | } -------------------------------------------------------------------------------- /common/src/main/java/com/prunoideae/powerfuljs/PowerfulJSPlugin.java: -------------------------------------------------------------------------------- 1 | package com.prunoideae.powerfuljs; 2 | 3 | import com.prunoideae.powerfuljs.events.BlockEntityCapEventJS; 4 | import com.prunoideae.powerfuljs.events.EntityCapEventJS; 5 | import dev.latvian.mods.kubejs.KubeJSPlugin; 6 | import dev.latvian.mods.kubejs.event.EventGroup; 7 | import dev.latvian.mods.kubejs.event.EventHandler; 8 | import dev.latvian.mods.kubejs.script.ScriptType; 9 | 10 | public class PowerfulJSPlugin extends KubeJSPlugin { 11 | 12 | //Only this event here so no need to make container classes 13 | public static final EventGroup GROUP = EventGroup.of("CapabilityEvents"); 14 | 15 | public static final EventHandler REGISTER_BE_CAP = GROUP.startup("blockEntity", () -> BlockEntityCapEventJS.class); 16 | public static final EventHandler REGISTER_ENTITY_CAP = GROUP.startup("entity", () -> EntityCapEventJS.class); 17 | 18 | @Override 19 | public void registerEvents() { 20 | GROUP.register(); 21 | } 22 | 23 | @Override 24 | public void afterInit() { 25 | CapabilityService.INSTANCE.loadBuilders(); 26 | REGISTER_BE_CAP.post(ScriptType.STARTUP, new BlockEntityCapEventJS()); 27 | REGISTER_ENTITY_CAP.post(ScriptType.STARTUP, new EntityCapEventJS()); 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /common/src/main/java/com/prunoideae/powerfuljs/events/BlockEntityCapEventJS.java: -------------------------------------------------------------------------------- 1 | package com.prunoideae.powerfuljs.events; 2 | 3 | import com.prunoideae.powerfuljs.CapabilityBuilder; 4 | import com.prunoideae.powerfuljs.CapabilityService; 5 | import dev.latvian.mods.kubejs.event.EventJS; 6 | import net.minecraft.world.level.block.entity.BlockEntity; 7 | import net.minecraft.world.level.block.entity.BlockEntityType; 8 | 9 | public class BlockEntityCapEventJS extends EventJS { 10 | public void attach(BlockEntityType entityType, CapabilityBuilder builder) { 11 | CapabilityService.INSTANCE.addBECapability(entityType, builder); 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /common/src/main/java/com/prunoideae/powerfuljs/events/EntityCapEventJS.java: -------------------------------------------------------------------------------- 1 | package com.prunoideae.powerfuljs.events; 2 | 3 | import com.prunoideae.powerfuljs.CapabilityBuilder; 4 | import dev.latvian.mods.kubejs.event.EventJS; 5 | import net.minecraft.world.entity.Entity; 6 | import net.minecraft.world.entity.EntityType; 7 | 8 | public class EntityCapEventJS extends EventJS { 9 | public void attach(EntityType entityType, CapabilityBuilder capabilityBuilder) { 10 | 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /common/src/main/java/com/prunoideae/powerfuljs/mixins/BlockEntityInfoMixin.java: -------------------------------------------------------------------------------- 1 | package com.prunoideae.powerfuljs.mixins; 2 | 3 | import com.prunoideae.powerfuljs.CapabilityBuilder; 4 | import com.prunoideae.powerfuljs.CapabilityService; 5 | import dev.latvian.mods.kubejs.block.entity.BlockEntityInfo; 6 | import net.minecraft.world.level.block.entity.BlockEntity; 7 | import org.spongepowered.asm.mixin.Mixin; 8 | 9 | @Mixin(value = BlockEntityInfo.class, remap = false) 10 | public class BlockEntityInfoMixin { 11 | public BlockEntityInfo attachCapability(CapabilityBuilder builder) { 12 | BlockEntityInfo thisBuilder = (BlockEntityInfo) (Object) this; 13 | CapabilityService.INSTANCE.addLazyBECapability(thisBuilder, builder); 14 | return thisBuilder; 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /common/src/main/java/com/prunoideae/powerfuljs/mixins/ItemBuilderMixin.java: -------------------------------------------------------------------------------- 1 | package com.prunoideae.powerfuljs.mixins; 2 | 3 | import com.prunoideae.powerfuljs.CapabilityBuilder; 4 | import com.prunoideae.powerfuljs.CapabilityService; 5 | import dev.latvian.mods.kubejs.item.ItemBuilder; 6 | import net.minecraft.world.item.ItemStack; 7 | import org.spongepowered.asm.mixin.Mixin; 8 | 9 | @Mixin(value = ItemBuilder.class, remap = false) 10 | public abstract class ItemBuilderMixin { 11 | public ItemBuilder attachCapability(CapabilityBuilder builder) { 12 | ItemBuilder thisBuilder = (ItemBuilder) (Object) this; 13 | CapabilityService.INSTANCE.addBuilderCapability(thisBuilder, builder); 14 | return thisBuilder; 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /common/src/main/java/com/prunoideae/powerfuljs/mixins/ItemMixin.java: -------------------------------------------------------------------------------- 1 | package com.prunoideae.powerfuljs.mixins; 2 | 3 | import com.prunoideae.powerfuljs.CapabilityBuilder; 4 | import com.prunoideae.powerfuljs.CapabilityService; 5 | import net.minecraft.world.item.Item; 6 | import net.minecraft.world.item.ItemStack; 7 | import org.spongepowered.asm.mixin.Mixin; 8 | 9 | @Mixin(Item.class) 10 | public abstract class ItemMixin { 11 | 12 | public void attachCapability(CapabilityBuilder capabilityBuilder) { 13 | CapabilityService.INSTANCE.addItemCapability((Item) (Object) this, capabilityBuilder); 14 | } 15 | 16 | } 17 | -------------------------------------------------------------------------------- /common/src/main/java/com/prunoideae/powerfuljs/proxy/PowerfulJSClient.java: -------------------------------------------------------------------------------- 1 | package com.prunoideae.powerfuljs.proxy; 2 | 3 | public class PowerfulJSClient extends PowerfulJSCommon { 4 | @Override 5 | public void runOnClient(Runnable run) { 6 | run.run(); 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /common/src/main/java/com/prunoideae/powerfuljs/proxy/PowerfulJSCommon.java: -------------------------------------------------------------------------------- 1 | package com.prunoideae.powerfuljs.proxy; 2 | 3 | public class PowerfulJSCommon { 4 | public void runOnClient(Runnable run) { 5 | 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /common/src/main/resources/powerfuljs-common.accesswidener: -------------------------------------------------------------------------------- 1 | accessWidener v2 named -------------------------------------------------------------------------------- /common/src/main/resources/powerfuljs-common.mixins.json: -------------------------------------------------------------------------------- 1 | { 2 | "required": true, 3 | "minVersion": "0.8", 4 | "package": "com.prunoideae.powerfuljs.mixins", 5 | "compatibilityLevel": "JAVA_17", 6 | "mixins": [ 7 | "BlockEntityInfoMixin", 8 | "ItemBuilderMixin", 9 | "ItemMixin" 10 | ], 11 | "client": [ 12 | ], 13 | "injectors": { 14 | "defaultRequire": 1 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /examples/1.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Prunoideae/PowerfulJS/1ce050ea39fc22e1a498e804e33b98bceae96b74/examples/1.gif -------------------------------------------------------------------------------- /examples/1.js: -------------------------------------------------------------------------------- 1 | //In startup_scripts 2 | 3 | CapabilityEvents.blockEntity(event => { 4 | event.attach("thermal:energy_cell", 5 | BotaniaCapabilityBuilder.MANA.blockEntity() 6 | .receiveMana((be, amount) => { 7 | let energy = be.getCapability(ForgeCapabilities.ENERGY).orElse(null) 8 | energy.receiveEnergy(amount, false) 9 | }) 10 | .getCurrentMana(be => { 11 | let energy = be.getCapability(ForgeCapabilities.ENERGY).orElse(null) 12 | return energy.energyStored 13 | }) 14 | .isFull(be => { 15 | let energy = be.getCapability(ForgeCapabilities.ENERGY).orElse(null) 16 | return energy.energyStored >= energy.maxEnergyStored; 17 | }) 18 | ) 19 | 20 | }) -------------------------------------------------------------------------------- /examples/2.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Prunoideae/PowerfulJS/1ce050ea39fc22e1a498e804e33b98bceae96b74/examples/2.gif -------------------------------------------------------------------------------- /examples/2.js: -------------------------------------------------------------------------------- 1 | //In startup_scripts 2 | 3 | StartupEvents.registry('item', event => { 4 | event.create("test") 5 | .maxDamage(1000) 6 | .attachCapability( 7 | CapabilityBuilder.ENERGY.customItemStack() 8 | .canExtract(i => true) 9 | .getEnergyStored(i => 1000) 10 | .getMaxEnergyStored(i => 1000) 11 | .extractEnergy((itm, i, sim) => { 12 | if (!sim) { 13 | //itm.damageValue += 1 14 | //if (itm.damageValue >= 1000) 15 | // itm.shrink(1) 16 | } 17 | return 20 18 | }) 19 | ) 20 | }) -------------------------------------------------------------------------------- /examples/3.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Prunoideae/PowerfulJS/1ce050ea39fc22e1a498e804e33b98bceae96b74/examples/3.gif -------------------------------------------------------------------------------- /examples/3.js: -------------------------------------------------------------------------------- 1 | //In startup_scripts 2 | 3 | StartupEvents.registry("block", event => { 4 | event.create("sussy_dynamo", "powerfuljs:dummy_block_entity") 5 | .attachCapability(CapabilityBuilder.ENERGY.customBlockEntity() 6 | .canExtract(() => true) 7 | .canReceive(() => true) 8 | .extractEnergy((be, amount, simulate) => { 9 | let energy = be.persistentData.getInt("energy") 10 | let extracted = Math.min(energy, amount) 11 | if (!simulate) { 12 | be.persistentData.putInt("energy", energy - extracted) 13 | } 14 | return extracted 15 | }) 16 | .receiveEnergy((be, amount, simulate) => { 17 | let energy = be.persistentData.getInt("energy") 18 | let received = Math.min(1919810 - energy, amount) 19 | if (!simulate) { 20 | be.persistentData.putInt("energy", energy + received) 21 | } 22 | return received 23 | 24 | }) 25 | .getEnergyStored(be => { 26 | return be.persistentData.getInt("energy") 27 | }) 28 | .getMaxEnergyStored(() => 1919810) 29 | ) 30 | }) -------------------------------------------------------------------------------- /fabric.iml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /fabric/build.gradle: -------------------------------------------------------------------------------- 1 | plugins { 2 | id "com.github.johnrengelman.shadow" version "7.1.2" 3 | } 4 | 5 | architectury { 6 | platformSetupLoomIde() 7 | fabric() 8 | } 9 | 10 | configurations { 11 | common 12 | shadowCommon // Don't use shadow from the shadow plugin because we don't want IDEA to index this. 13 | compileClasspath.extendsFrom common 14 | runtimeClasspath.extendsFrom common 15 | developmentFabric.extendsFrom common 16 | } 17 | 18 | dependencies { 19 | modImplementation "net.fabricmc:fabric-loader:${rootProject.fabric_loader_version}" 20 | modApi "net.fabricmc.fabric-api:fabric-api:${rootProject.fabric_api_version}" 21 | // Remove the next line if you don't want to depend on the API 22 | modApi "dev.architectury:architectury-fabric:${rootProject.architectury_version}" 23 | modImplementation "dev.latvian.mods:kubejs-fabric:${rootProject.kubejs_version}" 24 | modImplementation "dev.latvian.mods:rhino:${rootProject.rhino_version}" 25 | modImplementation "vazkii.botania:Botania:${rootProject.botania_version}-FABRIC" 26 | 27 | common(project(path: ":common", configuration: "namedElements")) { transitive false } 28 | shadowCommon(project(path: ":common", configuration: "transformProductionFabric")) { transitive false } 29 | } 30 | 31 | processResources { 32 | inputs.property "version", project.version 33 | 34 | filesMatching("fabric.mod.json") { 35 | expand "version": project.version 36 | } 37 | } 38 | 39 | shadowJar { 40 | configurations = [project.configurations.shadowCommon] 41 | classifier "dev-shadow" 42 | } 43 | 44 | remapJar { 45 | input.set shadowJar.archiveFile 46 | dependsOn shadowJar 47 | classifier null 48 | } 49 | 50 | jar { 51 | classifier "dev" 52 | } 53 | 54 | sourcesJar { 55 | def commonSources = project(":common").sourcesJar 56 | dependsOn commonSources 57 | from commonSources.archiveFile.map { zipTree(it) } 58 | } 59 | 60 | components.java { 61 | withVariantsFromConfiguration(project.configurations.shadowRuntimeElements) { 62 | skip() 63 | } 64 | } 65 | 66 | publishing { 67 | publications { 68 | mavenFabric(MavenPublication) { 69 | artifactId = rootProject.archives_base_name + "-" + project.name 70 | from components.java 71 | } 72 | } 73 | 74 | // See https://docs.gradle.org/current/userguide/publishing_maven.html for information on how to set up publishing. 75 | repositories { 76 | // Add repositories to publish to here. 77 | } 78 | } -------------------------------------------------------------------------------- /fabric/src/main/java/com/prunoideae/powerfuljs/fabric/CapabilitiesFabric.java: -------------------------------------------------------------------------------- 1 | package com.prunoideae.powerfuljs.fabric; 2 | 3 | public class CapabilitiesFabric { 4 | } 5 | -------------------------------------------------------------------------------- /fabric/src/main/java/com/prunoideae/powerfuljs/fabric/PowerfulJSFabric.java: -------------------------------------------------------------------------------- 1 | package com.prunoideae.powerfuljs.fabric; 2 | 3 | import com.prunoideae.powerfuljs.PowerfulJS; 4 | import net.fabricmc.api.ModInitializer; 5 | 6 | public class PowerfulJSFabric implements ModInitializer { 7 | @Override 8 | public void onInitialize() { 9 | PowerfulJS.init(); 10 | } 11 | } -------------------------------------------------------------------------------- /fabric/src/main/java/com/prunoideae/powerfuljs/fabric/PowerfulJSPluginFabric.java: -------------------------------------------------------------------------------- 1 | package com.prunoideae.powerfuljs.fabric; 2 | 3 | import com.prunoideae.powerfuljs.PowerfulJSPlugin; 4 | 5 | public class PowerfulJSPluginFabric extends PowerfulJSPlugin { 6 | } 7 | -------------------------------------------------------------------------------- /fabric/src/main/resources/fabric.mod.json: -------------------------------------------------------------------------------- 1 | { 2 | "schemaVersion": 1, 3 | "id": "powerfuljs", 4 | "version": "${version}", 5 | 6 | "name": "PowerfulJS", 7 | "description": "Adds Capability/ApiLookup support for KubeJS", 8 | "authors": [ 9 | "Prunoideae" 10 | ], 11 | "contact": {}, 12 | 13 | "license": "LGPL-3.0", 14 | "icon": "icon.png", 15 | 16 | "environment": "*", 17 | "entrypoints": { 18 | "main": [ 19 | "com.prunoideae.powerfuljs.fabric.PowerfulJSFabric" 20 | ] 21 | }, 22 | "mixins": [ 23 | "powerfuljs-fabric.mixins.json", 24 | "powerfuljs-common.mixins.json" 25 | ], 26 | "depends": { 27 | "fabricloader": ">=0.14.12", 28 | "minecraft": ">=1.19.2", 29 | "kubejs": ">=1902.6.1-build.277" 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /fabric/src/main/resources/kubejs.plugins.txt: -------------------------------------------------------------------------------- 1 | com.prunoideae.powerfuljs.fabric.PowerfulJSPluginFabric -------------------------------------------------------------------------------- /fabric/src/main/resources/powerfuljs-fabric.mixins.json: -------------------------------------------------------------------------------- 1 | { 2 | "required": true, 3 | "minVersion": "0.8", 4 | "package": "com.prunoideae.powerfuljs.fabric.mixins", 5 | "compatibilityLevel": "JAVA_17", 6 | "mixins": [ 7 | ], 8 | "client": [ 9 | ], 10 | "injectors": { 11 | "defaultRequire": 1 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /forge.iml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /forge/build.gradle: -------------------------------------------------------------------------------- 1 | plugins { 2 | id "com.github.johnrengelman.shadow" version "7.1.2" 3 | } 4 | architectury { 5 | platformSetupLoomIde() 6 | forge() 7 | } 8 | 9 | loom { 10 | forge { 11 | mixinConfig("powerfuljs-common.mixins.json") 12 | mixinConfig("powerfuljs-forge.mixins.json") 13 | } 14 | } 15 | 16 | configurations { 17 | common 18 | shadowCommon // Don't use shadow from the shadow plugin because we don't want IDEA to index this. 19 | compileClasspath.extendsFrom common 20 | runtimeClasspath.extendsFrom common 21 | developmentForge.extendsFrom common 22 | } 23 | 24 | dependencies { 25 | forge "net.minecraftforge:forge:${rootProject.forge_version}" 26 | // Remove the next line if you don't want to depend on the API 27 | modApi "dev.architectury:architectury-forge:${rootProject.architectury_version}" 28 | modImplementation "dev.latvian.mods:kubejs-forge:${rootProject.kubejs_version}" 29 | modImplementation "dev.latvian.mods:rhino-forge:${rootProject.rhino_version}" 30 | modImplementation "vazkii.botania:Botania:${rootProject.botania_version}-FORGE" 31 | modImplementation "me.desht.pneumaticcraft:pneumaticcraft-repressurized:${rootProject.minecraft_version}-${rootProject.pnc_version}" 32 | modImplementation "mekanism:Mekanism:${rootProject.minecraft_version}-${rootProject.mekanism_version}" 33 | compileOnly "top.theillusivec4.curios:curios-forge:${rootProject.minecraft_version}-${rootProject.curios_version}:api" 34 | runtimeOnly "top.theillusivec4.curios:curios-forge:${rootProject.minecraft_version}-${rootProject.curios_version}" 35 | runtimeOnly "mekanism:Mekanism:${rootProject.minecraft_version}-${rootProject.mekanism_version}:additions" 36 | runtimeOnly "mekanism:Mekanism:${rootProject.minecraft_version}-${rootProject.mekanism_version}:generators" 37 | runtimeOnly "mekanism:Mekanism:${rootProject.minecraft_version}-${rootProject.mekanism_version}:tools" 38 | common(project(path: ":common", configuration: "namedElements")) { transitive false } 39 | shadowCommon(project(path: ":common", configuration: "transformProductionForge")) { transitive = false } 40 | modImplementation "curse.maven:immersive-engineering-231951:${project.immersive_engineering_file}" 41 | modImplementation "com.simibubi.create:create-${rootProject.minecraft_version}:${rootProject.create_version}:all" 42 | } 43 | 44 | 45 | processResources { 46 | inputs.property "version", project.version 47 | 48 | filesMatching("META-INF/mods.toml") { 49 | expand "version": project.version 50 | } 51 | } 52 | 53 | shadowJar { 54 | exclude "fabric.mod.json" 55 | 56 | configurations = [project.configurations.shadowCommon] 57 | classifier "dev-shadow" 58 | } 59 | 60 | remapJar { 61 | input.set shadowJar.archiveFile 62 | dependsOn shadowJar 63 | classifier null 64 | } 65 | 66 | jar { 67 | classifier "dev" 68 | } 69 | 70 | sourcesJar { 71 | def commonSources = project(":common").sourcesJar 72 | dependsOn commonSources 73 | from commonSources.archiveFile.map { zipTree(it) } 74 | } 75 | 76 | components.java { 77 | withVariantsFromConfiguration(project.configurations.shadowRuntimeElements) { 78 | skip() 79 | } 80 | } 81 | 82 | publishing { 83 | publications { 84 | mavenForge(MavenPublication) { 85 | artifactId = rootProject.archives_base_name + "-" + project.name 86 | from components.java 87 | } 88 | } 89 | 90 | // See https://docs.gradle.org/current/userguide/publishing_maven.html for information on how to set up publishing. 91 | repositories { 92 | // Add repositories to publish to here. 93 | } 94 | } -------------------------------------------------------------------------------- /forge/gradle.properties: -------------------------------------------------------------------------------- 1 | loom.platform=forge -------------------------------------------------------------------------------- /forge/src/main/java/com/prunoideae/powerfuljs/capabilities/forge/CapabilitiesForge.java: -------------------------------------------------------------------------------- 1 | package com.prunoideae.powerfuljs.capabilities.forge; 2 | 3 | public interface CapabilitiesForge { 4 | CapabilityForgeEnergy ENERGY = new CapabilityForgeEnergy(); 5 | CapabilityFluid FLUID = new CapabilityFluid(); 6 | CapabilityItem ITEM = new CapabilityItem(); 7 | } 8 | -------------------------------------------------------------------------------- /forge/src/main/java/com/prunoideae/powerfuljs/capabilities/forge/CapabilityBuilderForge.java: -------------------------------------------------------------------------------- 1 | package com.prunoideae.powerfuljs.capabilities.forge; 2 | 3 | import com.prunoideae.powerfuljs.CapabilityBuilder; 4 | import dev.latvian.mods.rhino.util.HideFromJS; 5 | import net.minecraft.core.Direction; 6 | import net.minecraftforge.common.capabilities.Capability; 7 | import net.minecraftforge.common.capabilities.CapabilityProvider; 8 | 9 | import java.util.function.BiPredicate; 10 | 11 | @SuppressWarnings("UnstableApiUsage") 12 | public abstract class CapabilityBuilderForge, T> extends CapabilityBuilder> { 13 | } 14 | -------------------------------------------------------------------------------- /forge/src/main/java/com/prunoideae/powerfuljs/capabilities/forge/CapabilityFluid.java: -------------------------------------------------------------------------------- 1 | package com.prunoideae.powerfuljs.capabilities.forge; 2 | 3 | import dev.architectury.hooks.fluid.forge.FluidStackHooksForge; 4 | import dev.latvian.mods.kubejs.fluid.FluidStackJS; 5 | import dev.latvian.mods.rhino.util.HideFromJS; 6 | import net.minecraft.resources.ResourceLocation; 7 | import net.minecraft.world.item.ItemStack; 8 | import net.minecraft.world.level.block.entity.BlockEntity; 9 | import net.minecraft.world.level.material.Fluid; 10 | import net.minecraftforge.common.capabilities.Capability; 11 | import net.minecraftforge.common.capabilities.ForgeCapabilities; 12 | import net.minecraftforge.fluids.FluidStack; 13 | import net.minecraftforge.fluids.capability.IFluidHandler; 14 | import net.minecraftforge.fluids.capability.IFluidHandlerItem; 15 | import net.minecraftforge.fluids.capability.templates.FluidHandlerItemStack; 16 | import org.jetbrains.annotations.NotNull; 17 | 18 | import java.util.function.BiPredicate; 19 | import java.util.function.Function; 20 | import java.util.function.ToIntFunction; 21 | 22 | public class CapabilityFluid { 23 | 24 | @FunctionalInterface 25 | public interface FluidIOItemStack { 26 | int transfer(ItemStack container, FluidStackJS resource, boolean simulate); 27 | } 28 | 29 | @FunctionalInterface 30 | public interface FluidIOBlockEntity { 31 | int transfer(BlockEntity container, FluidStackJS resource, boolean simulate); 32 | } 33 | 34 | public NormalTankBuilderItemStack itemStack(int capacity) { 35 | return new NormalTankBuilderItemStack(capacity); 36 | } 37 | 38 | public CustomTankBuilderItemStack customItemStack() { 39 | return new CustomTankBuilderItemStack(); 40 | } 41 | 42 | public CustomTankBuilderBlockEntity customBlockEntity() { 43 | return new CustomTankBuilderBlockEntity(); 44 | } 45 | 46 | public static class NormalTankBuilderItemStack extends CapabilityBuilderForge { 47 | private final int capacity; 48 | 49 | private NormalTankBuilderItemStack(int capacity) { 50 | this.capacity = capacity; 51 | } 52 | 53 | @Override 54 | public IFluidHandlerItem getCapability(ItemStack instance) { 55 | return new FluidHandlerItemStack(instance, capacity); 56 | } 57 | 58 | @Override 59 | public Capability getCapabilityKey() { 60 | return ForgeCapabilities.FLUID_HANDLER_ITEM; 61 | } 62 | 63 | @Override 64 | public ResourceLocation getResourceLocation() { 65 | return new ResourceLocation("powerful:normal_tank_item"); 66 | } 67 | } 68 | 69 | public static class FluidHandlerItemStackCustom extends FluidHandlerItemStack { 70 | 71 | private final FluidIOItemStack onFill; 72 | private final FluidIOItemStack onDrain; 73 | private final BiPredicate isFluidGood; 74 | private final ToIntFunction getCapacity; 75 | 76 | public FluidHandlerItemStackCustom(@NotNull ItemStack container, int capacity, 77 | FluidIOItemStack onFill, FluidIOItemStack onDrain, 78 | BiPredicate isFluidGood, 79 | ToIntFunction getCapacity) { 80 | super(container, capacity); 81 | this.onDrain = onDrain; 82 | this.onFill = onFill; 83 | this.isFluidGood = isFluidGood; 84 | this.getCapacity = getCapacity; 85 | } 86 | 87 | @Override 88 | public boolean isFluidValid(int tank, @NotNull FluidStack stack) { 89 | return isFluidGood == null || isFluidGood.test(container, FluidStackJS.of(FluidStackHooksForge.fromForge(stack))); 90 | } 91 | 92 | @Override 93 | public int fill(FluidStack resource, FluidAction doFill) { 94 | return onFill == null ? super.fill(resource, doFill) : onFill.transfer(container, FluidStackJS.of(FluidStackHooksForge.fromForge(resource)), doFill.simulate()); 95 | } 96 | 97 | @Override 98 | public @NotNull FluidStack drain(FluidStack resource, FluidAction action) { 99 | if (onDrain == null) 100 | return super.drain(resource, action); 101 | FluidStack stack = resource.copy(); 102 | stack.setAmount(onDrain.transfer(container, FluidStackJS.of(FluidStackHooksForge.fromForge(resource)), action.simulate())); 103 | return stack; 104 | } 105 | 106 | @Override 107 | public @NotNull FluidStack drain(int maxDrain, FluidAction action) { 108 | if (onDrain == null) 109 | return super.drain(maxDrain, action); 110 | FluidStack stack = getFluid().copy(); 111 | FluidStack drain = getFluid().copy(); 112 | drain.setAmount(maxDrain); 113 | stack.setAmount(onDrain.transfer(container, FluidStackJS.of(FluidStackHooksForge.fromForge(drain)), action.simulate())); 114 | return stack; 115 | } 116 | 117 | @Override 118 | public boolean canFillFluidType(FluidStack fluid) { 119 | return isFluidValid(0, fluid); 120 | } 121 | 122 | @Override 123 | public boolean canDrainFluidType(FluidStack fluid) { 124 | return isFluidValid(0, fluid); 125 | } 126 | 127 | @Override 128 | public int getTankCapacity(int tank) { 129 | return getCapacity == null ? 1000 : getCapacity.applyAsInt(container); 130 | } 131 | } 132 | 133 | public static class CustomTankBuilderItemStack extends CapabilityBuilderForge { 134 | private FluidIOItemStack onFill; 135 | private FluidIOItemStack onDrain; 136 | private BiPredicate isFluidGood; 137 | private ToIntFunction getCapacity; 138 | 139 | public CustomTankBuilderItemStack withCapacity(int capacity) { 140 | return getCapacity(i -> capacity); 141 | } 142 | 143 | public CustomTankBuilderItemStack getCapacity(ToIntFunction getCapacity) { 144 | this.getCapacity = getCapacity; 145 | return this; 146 | } 147 | 148 | public CustomTankBuilderItemStack acceptFluid(Fluid fluid) { 149 | return isFluidGood((i, fluidStackJS) -> fluidStackJS.getFluid() == fluid); 150 | } 151 | 152 | public CustomTankBuilderItemStack isFluidGood(BiPredicate isFluidGood) { 153 | this.isFluidGood = isFluidGood; 154 | return this; 155 | } 156 | 157 | public CustomTankBuilderItemStack onFill(FluidIOItemStack onFill) { 158 | this.onFill = onFill; 159 | return this; 160 | } 161 | 162 | public CustomTankBuilderItemStack onDrain(FluidIOItemStack onDrain) { 163 | this.onDrain = onDrain; 164 | return this; 165 | } 166 | 167 | @Override 168 | @HideFromJS 169 | public IFluidHandlerItem getCapability(ItemStack instance) { 170 | return new FluidHandlerItemStackCustom(instance, 1000, onFill, onDrain, isFluidGood, getCapacity); 171 | } 172 | 173 | @Override 174 | @HideFromJS 175 | public Capability getCapabilityKey() { 176 | return ForgeCapabilities.FLUID_HANDLER_ITEM; 177 | } 178 | 179 | @Override 180 | @HideFromJS 181 | public ResourceLocation getResourceLocation() { 182 | return new ResourceLocation("powerful:custom_tank_item"); 183 | } 184 | } 185 | 186 | public static class CustomTankBuilderBlockEntity extends CapabilityBuilderForge { 187 | private FluidIOBlockEntity onFill; 188 | private FluidIOBlockEntity onDrain; 189 | private BiPredicate isFluidGood; 190 | private ToIntFunction getCapacity; 191 | private Function getFluid; 192 | 193 | public CustomTankBuilderBlockEntity onFill(FluidIOBlockEntity onFill) { 194 | this.onFill = onFill; 195 | return this; 196 | } 197 | 198 | public CustomTankBuilderBlockEntity onDrain(FluidIOBlockEntity onDrain) { 199 | this.onDrain = onDrain; 200 | return this; 201 | } 202 | 203 | public CustomTankBuilderBlockEntity isFluidGood(BiPredicate isFluidGood) { 204 | this.isFluidGood = isFluidGood; 205 | return this; 206 | } 207 | 208 | public CustomTankBuilderBlockEntity getCapacity(ToIntFunction getCapacity) { 209 | this.getCapacity = getCapacity; 210 | return this; 211 | } 212 | 213 | public CustomTankBuilderBlockEntity getFluid(Function getFluid) { 214 | this.getFluid = getFluid; 215 | return this; 216 | } 217 | 218 | @Override 219 | public IFluidHandler getCapability(BlockEntity instance) { 220 | return new IFluidHandler() { 221 | @Override 222 | public int getTanks() { 223 | return 1; 224 | } 225 | 226 | @Override 227 | public @NotNull FluidStack getFluidInTank(int i) { 228 | return getFluid != null ? FluidStackHooksForge.toForge(getFluid.apply(instance).getFluidStack()) : FluidStack.EMPTY; 229 | } 230 | 231 | @Override 232 | public int getTankCapacity(int i) { 233 | return getCapacity != null ? getCapacity.applyAsInt(instance) : 1000; 234 | } 235 | 236 | @Override 237 | public boolean isFluidValid(int i, @NotNull FluidStack fluidStack) { 238 | return isFluidGood == null || isFluidGood.test(instance, FluidStackJS.of(FluidStackHooksForge.fromForge(fluidStack))); 239 | } 240 | 241 | @Override 242 | public int fill(FluidStack fluidStack, FluidAction fluidAction) { 243 | return onFill != null ? onFill.transfer(instance, FluidStackJS.of(FluidStackHooksForge.fromForge(fluidStack)), fluidAction.simulate()) : 0; 244 | } 245 | 246 | @Override 247 | public @NotNull FluidStack drain(FluidStack fluidStack, FluidAction fluidAction) { 248 | int drained = onDrain != null ? onDrain.transfer(instance, FluidStackJS.of(FluidStackHooksForge.fromForge(fluidStack)), fluidAction.simulate()) : 0; 249 | if (drained == 0) 250 | return FluidStack.EMPTY; 251 | return new FluidStack(fluidStack, drained); 252 | } 253 | 254 | @Override 255 | public @NotNull FluidStack drain(int i, FluidAction fluidAction) { 256 | FluidStack inTank = getFluidInTank(0).copy(); 257 | if (inTank.isEmpty()) 258 | return inTank; 259 | inTank.setAmount(i); 260 | return drain(inTank, fluidAction); 261 | } 262 | }; 263 | } 264 | 265 | @Override 266 | public Capability getCapabilityKey() { 267 | return ForgeCapabilities.FLUID_HANDLER; 268 | } 269 | 270 | @Override 271 | public ResourceLocation getResourceLocation() { 272 | return new ResourceLocation("powerful:custom_tank_be"); 273 | } 274 | } 275 | 276 | } 277 | -------------------------------------------------------------------------------- /forge/src/main/java/com/prunoideae/powerfuljs/capabilities/forge/CapabilityForgeEnergy.java: -------------------------------------------------------------------------------- 1 | package com.prunoideae.powerfuljs.capabilities.forge; 2 | 3 | import dev.latvian.mods.rhino.util.HideFromJS; 4 | import net.minecraft.resources.ResourceLocation; 5 | import net.minecraft.world.item.ItemStack; 6 | import net.minecraft.world.level.block.entity.BlockEntity; 7 | import net.minecraftforge.common.capabilities.Capability; 8 | import net.minecraftforge.common.capabilities.ForgeCapabilities; 9 | import net.minecraftforge.energy.IEnergyStorage; 10 | 11 | import java.util.function.Predicate; 12 | import java.util.function.ToIntFunction; 13 | 14 | public class CapabilityForgeEnergy { 15 | @FunctionalInterface 16 | public interface EnergyIOItemStack { 17 | int transfer(ItemStack itemStack, int i, boolean simulate); 18 | } 19 | 20 | @FunctionalInterface 21 | public interface EnergyIOBlockEntity { 22 | int transfer(BlockEntity blockEntity, int i, boolean simulate); 23 | } 24 | 25 | public ItemStorageBuilder normalItemStack(int capacity, boolean canExtract, boolean canReceive) { 26 | return new ItemStorageBuilder(capacity, canExtract, canReceive); 27 | } 28 | 29 | public ItemStackBuilder customItemStack() { 30 | return new ItemStackBuilder(); 31 | } 32 | 33 | public static class ItemStorageBuilder extends CapabilityBuilderForge { 34 | private final int capacity; 35 | private final boolean canExtract; 36 | private final boolean canReceive; 37 | 38 | private int receiveRate = Integer.MAX_VALUE; 39 | private int extractRate = Integer.MAX_VALUE; 40 | private static final String ENERGY_TAG = "pjs:fe_energy"; 41 | 42 | public ItemStorageBuilder(int capacity, boolean canExtract, boolean canReceive) { 43 | this.capacity = capacity; 44 | this.canExtract = canExtract; 45 | this.canReceive = canReceive; 46 | } 47 | 48 | public ItemStorageBuilder receiveRate(int receiveRate) { 49 | this.receiveRate = receiveRate; 50 | return this; 51 | } 52 | 53 | public ItemStorageBuilder extractRate(int extractRate) { 54 | this.extractRate = extractRate; 55 | return this; 56 | } 57 | 58 | @Override 59 | public IEnergyStorage getCapability(ItemStack instance) { 60 | return new IEnergyStorage() { 61 | @Override 62 | public int receiveEnergy(int i, boolean bl) { 63 | if (!canReceive) 64 | return 0; 65 | int received = Math.min(receiveRate, Math.min(getMaxEnergyStored() - getEnergyStored(), i)); 66 | 67 | if (!bl) { 68 | instance.getOrCreateTag().putInt(ENERGY_TAG, received + getEnergyStored()); 69 | } 70 | return received; 71 | } 72 | 73 | @Override 74 | public int extractEnergy(int i, boolean bl) { 75 | if (!canExtract) 76 | return 0; 77 | int extracted = Math.min(extractRate, Math.min(getEnergyStored(), i)); 78 | if (!bl) { 79 | instance.getOrCreateTag().putInt(ENERGY_TAG, getEnergyStored() - extracted); 80 | } 81 | return extracted; 82 | } 83 | 84 | @Override 85 | public int getEnergyStored() { 86 | return instance.getOrCreateTag().getInt(ENERGY_TAG); 87 | } 88 | 89 | @Override 90 | public int getMaxEnergyStored() { 91 | return capacity; 92 | } 93 | 94 | @Override 95 | public boolean canExtract() { 96 | return canExtract; 97 | } 98 | 99 | @Override 100 | public boolean canReceive() { 101 | return canReceive; 102 | } 103 | }; 104 | } 105 | 106 | @Override 107 | public Capability getCapabilityKey() { 108 | return ForgeCapabilities.ENERGY; 109 | } 110 | 111 | @Override 112 | public ResourceLocation getResourceLocation() { 113 | return new ResourceLocation("powerful:fe_item"); 114 | } 115 | } 116 | 117 | public static class ItemStackBuilder extends CapabilityBuilderForge { 118 | private EnergyIOItemStack receiveEnergy; 119 | private EnergyIOItemStack extractEnergy; 120 | 121 | private ToIntFunction getEnergyStored; 122 | private ToIntFunction getMaxEnergyStored; 123 | private Predicate canExtract; 124 | private Predicate canReceive; 125 | 126 | public ItemStackBuilder getEnergyStored(ToIntFunction getEnergyStored) { 127 | this.getEnergyStored = getEnergyStored; 128 | return this; 129 | } 130 | 131 | public ItemStackBuilder withCapacity(int capacity) { 132 | return getMaxEnergyStored(i -> capacity); 133 | } 134 | 135 | public ItemStackBuilder getMaxEnergyStored(ToIntFunction getMaxEnergyStored) { 136 | this.getMaxEnergyStored = getMaxEnergyStored; 137 | return this; 138 | } 139 | 140 | public ItemStackBuilder canExtract(Predicate canExtract) { 141 | this.canExtract = canExtract; 142 | return this; 143 | } 144 | 145 | public ItemStackBuilder canReceive(Predicate canReceive) { 146 | this.canReceive = canReceive; 147 | return this; 148 | } 149 | 150 | 151 | public ItemStackBuilder receiveEnergy(EnergyIOItemStack receiveEnergy) { 152 | this.receiveEnergy = receiveEnergy; 153 | return this; 154 | } 155 | 156 | public ItemStackBuilder extractEnergy(EnergyIOItemStack extractEnergy) { 157 | this.extractEnergy = extractEnergy; 158 | return this; 159 | } 160 | 161 | @HideFromJS 162 | @Override 163 | public IEnergyStorage getCapability(ItemStack instance) { 164 | return new IEnergyStorage() { 165 | @Override 166 | public int receiveEnergy(int i, boolean bl) { 167 | return receiveEnergy == null ? 0 : receiveEnergy.transfer(instance, i, bl); 168 | } 169 | 170 | @Override 171 | public int extractEnergy(int i, boolean bl) { 172 | return extractEnergy == null ? 0 : extractEnergy.transfer(instance, i, bl); 173 | } 174 | 175 | @Override 176 | public int getEnergyStored() { 177 | return getEnergyStored == null ? 0 : getEnergyStored.applyAsInt(instance); 178 | } 179 | 180 | @Override 181 | public int getMaxEnergyStored() { 182 | return getMaxEnergyStored == null ? 0 : getMaxEnergyStored.applyAsInt(instance); 183 | } 184 | 185 | @Override 186 | public boolean canExtract() { 187 | return canExtract != null && canExtract.test(instance); 188 | } 189 | 190 | @Override 191 | public boolean canReceive() { 192 | return canReceive != null && canReceive.test(instance); 193 | } 194 | }; 195 | } 196 | 197 | @HideFromJS 198 | @Override 199 | public Capability getCapabilityKey() { 200 | return ForgeCapabilities.ENERGY; 201 | } 202 | 203 | @HideFromJS 204 | @Override 205 | public ResourceLocation getResourceLocation() { 206 | return new ResourceLocation("powerful:fe_item_custom"); 207 | } 208 | } 209 | 210 | // No default implementation for BE caps since we're not likely to do data sync here 211 | public BlockEntityBuilder customBlockEntity() { 212 | return new BlockEntityBuilder(); 213 | } 214 | 215 | public static class BlockEntityBuilder extends CapabilityBuilderForge { 216 | private EnergyIOBlockEntity receiveEnergy; 217 | private EnergyIOBlockEntity extractEnergy; 218 | 219 | private ToIntFunction getEnergyStored; 220 | private ToIntFunction getMaxEnergyStored; 221 | private Predicate canExtract; 222 | private Predicate canReceive; 223 | 224 | public BlockEntityBuilder receiveEnergy(EnergyIOBlockEntity receiveEnergy) { 225 | this.receiveEnergy = receiveEnergy; 226 | return this; 227 | } 228 | 229 | public BlockEntityBuilder extractEnergy(EnergyIOBlockEntity extractEnergy) { 230 | this.extractEnergy = extractEnergy; 231 | return this; 232 | } 233 | 234 | public BlockEntityBuilder getEnergyStored(ToIntFunction getEnergyStored) { 235 | this.getEnergyStored = getEnergyStored; 236 | return this; 237 | } 238 | 239 | public BlockEntityBuilder withCapacity(int capacity) { 240 | return getMaxEnergyStored(be -> capacity); 241 | } 242 | 243 | public BlockEntityBuilder getMaxEnergyStored(ToIntFunction getMaxEnergyStored) { 244 | this.getMaxEnergyStored = getMaxEnergyStored; 245 | return this; 246 | } 247 | 248 | public BlockEntityBuilder canExtract(Predicate canExtract) { 249 | this.canExtract = canExtract; 250 | return this; 251 | } 252 | 253 | public BlockEntityBuilder canReceive(Predicate canReceive) { 254 | this.canReceive = canReceive; 255 | return this; 256 | } 257 | 258 | @Override 259 | @HideFromJS 260 | public IEnergyStorage getCapability(BlockEntity instance) { 261 | return new IEnergyStorage() { 262 | @Override 263 | public int receiveEnergy(int i, boolean bl) { 264 | return receiveEnergy == null ? 0 : receiveEnergy.transfer(instance, i, bl); 265 | } 266 | 267 | @Override 268 | public int extractEnergy(int i, boolean bl) { 269 | return extractEnergy == null ? 0 : extractEnergy.transfer(instance, i, bl); 270 | } 271 | 272 | @Override 273 | public int getEnergyStored() { 274 | return getEnergyStored == null ? 0 : getEnergyStored.applyAsInt(instance); 275 | } 276 | 277 | @Override 278 | public int getMaxEnergyStored() { 279 | return getMaxEnergyStored == null ? 0 : getMaxEnergyStored.applyAsInt(instance); 280 | } 281 | 282 | @Override 283 | public boolean canExtract() { 284 | return canExtract != null && canExtract.test(instance); 285 | } 286 | 287 | @Override 288 | public boolean canReceive() { 289 | return canReceive != null && canReceive.test(instance); 290 | } 291 | }; 292 | } 293 | 294 | @Override 295 | @HideFromJS 296 | public Capability getCapabilityKey() { 297 | return ForgeCapabilities.ENERGY; 298 | } 299 | 300 | @Override 301 | @HideFromJS 302 | public ResourceLocation getResourceLocation() { 303 | return new ResourceLocation("powerful:fe_be_custom"); 304 | } 305 | } 306 | } 307 | -------------------------------------------------------------------------------- /forge/src/main/java/com/prunoideae/powerfuljs/capabilities/forge/CapabilityItem.java: -------------------------------------------------------------------------------- 1 | package com.prunoideae.powerfuljs.capabilities.forge; 2 | 3 | import net.minecraft.resources.ResourceLocation; 4 | import net.minecraft.world.item.ItemStack; 5 | import net.minecraft.world.level.block.entity.BlockEntity; 6 | import net.minecraftforge.common.capabilities.Capability; 7 | import net.minecraftforge.common.capabilities.ForgeCapabilities; 8 | import net.minecraftforge.items.IItemHandler; 9 | import org.jetbrains.annotations.NotNull; 10 | 11 | import java.util.function.BiFunction; 12 | import java.util.function.ToIntBiFunction; 13 | import java.util.function.ToIntFunction; 14 | 15 | public class CapabilityItem { 16 | @FunctionalInterface 17 | public interface InsertItem { 18 | ItemStack insert(BlockEntity be, int i, ItemStack item, boolean simulate); 19 | } 20 | 21 | @FunctionalInterface 22 | public interface ExtractItem { 23 | ItemStack extract(BlockEntity be, int i, int amount, boolean simulate); 24 | } 25 | 26 | @FunctionalInterface 27 | public interface IsItemValid { 28 | boolean isValid(BlockEntity be, int i, ItemStack arg); 29 | } 30 | 31 | public BlockEntityBuilder blockEntity() { 32 | return new BlockEntityBuilder(); 33 | } 34 | 35 | public static class BlockEntityBuilder extends CapabilityBuilderForge { 36 | 37 | private ToIntFunction getSlots; 38 | private BiFunction getStackInSlot; 39 | private InsertItem insertItem; 40 | private ExtractItem extractItem; 41 | private ToIntBiFunction getSlotLimit; 42 | private IsItemValid isItemValid; 43 | 44 | public BlockEntityBuilder getSlots(ToIntFunction getSlots) { 45 | this.getSlots = getSlots; 46 | return this; 47 | } 48 | 49 | public BlockEntityBuilder getStackInSlot(BiFunction getStackInSlot) { 50 | this.getStackInSlot = getStackInSlot; 51 | return this; 52 | } 53 | 54 | public BlockEntityBuilder insertItem(InsertItem insertItem) { 55 | this.insertItem = insertItem; 56 | return this; 57 | } 58 | 59 | public BlockEntityBuilder extractItem(ExtractItem extractItem) { 60 | this.extractItem = extractItem; 61 | return this; 62 | } 63 | 64 | public BlockEntityBuilder getSlotLimit(ToIntBiFunction getSlotLimit) { 65 | this.getSlotLimit = getSlotLimit; 66 | return this; 67 | } 68 | 69 | public BlockEntityBuilder isItemValid(IsItemValid isItemValid) { 70 | this.isItemValid = isItemValid; 71 | return this; 72 | } 73 | 74 | @Override 75 | public IItemHandler getCapability(BlockEntity instance) { 76 | return new IItemHandler() { 77 | @Override 78 | public int getSlots() { 79 | return getSlots != null ? getSlots.applyAsInt(instance) : 0; 80 | } 81 | 82 | @Override 83 | public @NotNull ItemStack getStackInSlot(int i) { 84 | return getStackInSlot == null ? ItemStack.EMPTY : getStackInSlot.apply(instance, i); 85 | } 86 | 87 | @Override 88 | public @NotNull ItemStack insertItem(int i, @NotNull ItemStack arg, boolean bl) { 89 | return insertItem == null ? ItemStack.EMPTY : insertItem.insert(instance, i, arg, bl); 90 | } 91 | 92 | @Override 93 | public @NotNull ItemStack extractItem(int i, int j, boolean bl) { 94 | return extractItem == null ? ItemStack.EMPTY : extractItem.extract(instance, i, j, bl); 95 | } 96 | 97 | @Override 98 | public int getSlotLimit(int i) { 99 | return getSlotLimit == null ? 64 : getSlotLimit.applyAsInt(instance, i); 100 | } 101 | 102 | @Override 103 | public boolean isItemValid(int i, @NotNull ItemStack arg) { 104 | return isItemValid == null || isItemValid.isValid(instance, i, arg); 105 | } 106 | }; 107 | } 108 | 109 | @Override 110 | public Capability getCapabilityKey() { 111 | return ForgeCapabilities.ITEM_HANDLER; 112 | } 113 | 114 | @Override 115 | public ResourceLocation getResourceLocation() { 116 | return new ResourceLocation("powerful:item_be"); 117 | } 118 | } 119 | } 120 | -------------------------------------------------------------------------------- /forge/src/main/java/com/prunoideae/powerfuljs/capabilities/forge/CapabilityProvider.java: -------------------------------------------------------------------------------- 1 | package com.prunoideae.powerfuljs.capabilities.forge; 2 | 3 | import net.minecraft.core.Direction; 4 | import net.minecraftforge.common.capabilities.Capability; 5 | import net.minecraftforge.common.capabilities.ICapabilityProvider; 6 | import net.minecraftforge.common.util.LazyOptional; 7 | import org.jetbrains.annotations.NotNull; 8 | import org.jetbrains.annotations.Nullable; 9 | 10 | import java.util.function.Predicate; 11 | 12 | public class CapabilityProvider implements ICapabilityProvider { 13 | 14 | public static CapabilityProvider of(Object capability, Object instance, Predicate available) { 15 | return new CapabilityProvider((Capability) capability, LazyOptional.of(() -> instance), available); 16 | } 17 | 18 | protected final Capability capability; 19 | protected final LazyOptional instance; 20 | protected final Predicate available; 21 | 22 | public CapabilityProvider(Capability capability, LazyOptional instance, Predicate available) { 23 | this.capability = capability; 24 | this.instance = instance; 25 | this.available = available; 26 | } 27 | 28 | @Override 29 | public @NotNull LazyOptional getCapability(@NotNull Capability capability, @Nullable Direction arg) { 30 | //Types are wiped as fuck here 31 | return this.capability == capability && available.test(arg) ? instance.cast() : LazyOptional.empty(); 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /forge/src/main/java/com/prunoideae/powerfuljs/capabilities/forge/mods/botania/CapabilitiesBotania.java: -------------------------------------------------------------------------------- 1 | package com.prunoideae.powerfuljs.capabilities.forge.mods.botania; 2 | 3 | public interface CapabilitiesBotania { 4 | CapabilityMana MANA = new CapabilityMana(); 5 | CapabilityAvatar AVATAR = new CapabilityAvatar(); 6 | CapabilityBlockProvider BLOCK_PROVIDER = new CapabilityBlockProvider(); 7 | CapabilityRelic RELIC = new CapabilityRelic(); 8 | CapabilityExoflame EXOFLAME = new CapabilityExoflame(); 9 | } 10 | -------------------------------------------------------------------------------- /forge/src/main/java/com/prunoideae/powerfuljs/capabilities/forge/mods/botania/CapabilityAvatar.java: -------------------------------------------------------------------------------- 1 | package com.prunoideae.powerfuljs.capabilities.forge.mods.botania; 2 | 3 | import com.prunoideae.powerfuljs.capabilities.forge.CapabilityBuilderForge; 4 | import dev.latvian.mods.rhino.util.HideFromJS; 5 | import net.minecraft.resources.ResourceLocation; 6 | import net.minecraft.world.item.ItemStack; 7 | import net.minecraft.world.level.block.entity.BlockEntity; 8 | import net.minecraftforge.common.capabilities.Capability; 9 | import vazkii.botania.api.BotaniaForgeCapabilities; 10 | import vazkii.botania.api.block.Avatar; 11 | import vazkii.botania.api.item.AvatarWieldable; 12 | 13 | import java.util.function.BiConsumer; 14 | 15 | public class CapabilityAvatar { 16 | 17 | public AvatarBehaviorBuilder wieldable() { 18 | return new AvatarBehaviorBuilder(); 19 | } 20 | 21 | public static class AvatarBehaviorBuilder extends CapabilityBuilderForge { 22 | private BiConsumer onUpdate; 23 | private ResourceLocation overlay = new ResourceLocation("botania:textures/model/avatar.png"); 24 | 25 | public AvatarBehaviorBuilder onUpdate(BiConsumer onUpdate) { 26 | this.onUpdate = onUpdate; 27 | return this; 28 | } 29 | 30 | public AvatarBehaviorBuilder setOverlay(ResourceLocation overlay) { 31 | this.overlay = overlay; 32 | return this; 33 | } 34 | 35 | @Override 36 | @HideFromJS 37 | public AvatarWieldable getCapability(ItemStack instance) { 38 | return new AvatarWieldable() { 39 | @Override 40 | public void onAvatarUpdate(Avatar tile) { 41 | BlockEntity t = (BlockEntity) tile; 42 | if (!t.hasLevel()) 43 | return; 44 | if (onUpdate != null && t.getLevel().getGameTime() % 10 == 0) 45 | onUpdate.accept(instance, tile); 46 | } 47 | 48 | @Override 49 | public ResourceLocation getOverlayResource(Avatar tile) { 50 | return overlay; 51 | } 52 | }; 53 | } 54 | 55 | @Override 56 | @HideFromJS 57 | public Capability getCapabilityKey() { 58 | return BotaniaForgeCapabilities.AVATAR_WIELDABLE; 59 | } 60 | 61 | @Override 62 | @HideFromJS 63 | public ResourceLocation getResourceLocation() { 64 | return new ResourceLocation("powerful:botania_avatar_wieldable"); 65 | } 66 | } 67 | } 68 | -------------------------------------------------------------------------------- /forge/src/main/java/com/prunoideae/powerfuljs/capabilities/forge/mods/botania/CapabilityBlockProvider.java: -------------------------------------------------------------------------------- 1 | package com.prunoideae.powerfuljs.capabilities.forge.mods.botania; 2 | 3 | import com.prunoideae.powerfuljs.capabilities.forge.CapabilityBuilderForge; 4 | import dev.latvian.mods.rhino.util.HideFromJS; 5 | import net.minecraft.resources.ResourceLocation; 6 | import net.minecraft.world.entity.player.Player; 7 | import net.minecraft.world.item.ItemStack; 8 | import net.minecraft.world.level.block.Block; 9 | import net.minecraftforge.common.capabilities.Capability; 10 | import vazkii.botania.api.BotaniaForgeCapabilities; 11 | import vazkii.botania.api.item.BlockProvider; 12 | 13 | public class CapabilityBlockProvider { 14 | 15 | public BuilderItemStack blockProvider() { 16 | return new BuilderItemStack(); 17 | } 18 | 19 | @FunctionalInterface 20 | public interface ProvideBlock { 21 | boolean provideBlock(ItemStack instance, Player player, ItemStack requestor, Block block, boolean doit); 22 | } 23 | 24 | @FunctionalInterface 25 | public interface GetBlockCount { 26 | int getBlockCount(ItemStack instance, Player player, ItemStack requestor, Block block); 27 | } 28 | 29 | public static class BuilderItemStack extends CapabilityBuilderForge { 30 | private ProvideBlock provideBlock; 31 | private GetBlockCount getBlockCount; 32 | 33 | public BuilderItemStack provideBlock(ProvideBlock provideBlock) { 34 | this.provideBlock = provideBlock; 35 | return this; 36 | } 37 | 38 | public BuilderItemStack getBlockCount(GetBlockCount getBlockCount) { 39 | this.getBlockCount = getBlockCount; 40 | return this; 41 | } 42 | 43 | @Override 44 | @HideFromJS 45 | public BlockProvider getCapability(ItemStack instance) { 46 | return new BlockProvider() { 47 | @Override 48 | public boolean provideBlock(Player player, ItemStack requestor, Block block, boolean doit) { 49 | return provideBlock != null && provideBlock.provideBlock(instance, player, requestor, block, doit); 50 | } 51 | 52 | @Override 53 | public int getBlockCount(Player player, ItemStack requestor, Block block) { 54 | return getBlockCount == null ? 0 : getBlockCount.getBlockCount(instance, player, requestor, block); 55 | } 56 | }; 57 | } 58 | 59 | @Override 60 | @HideFromJS 61 | public Capability getCapabilityKey() { 62 | return BotaniaForgeCapabilities.BLOCK_PROVIDER; 63 | } 64 | 65 | @Override 66 | @HideFromJS 67 | public ResourceLocation getResourceLocation() { 68 | return new ResourceLocation("powerful:block_provider_botania"); 69 | } 70 | } 71 | } 72 | -------------------------------------------------------------------------------- /forge/src/main/java/com/prunoideae/powerfuljs/capabilities/forge/mods/botania/CapabilityExoflame.java: -------------------------------------------------------------------------------- 1 | package com.prunoideae.powerfuljs.capabilities.forge.mods.botania; 2 | 3 | import com.prunoideae.powerfuljs.capabilities.forge.CapabilityBuilderForge; 4 | import net.minecraft.resources.ResourceLocation; 5 | import net.minecraft.world.level.block.entity.BlockEntity; 6 | import net.minecraftforge.common.capabilities.Capability; 7 | import vazkii.botania.api.BotaniaForgeCapabilities; 8 | import vazkii.botania.api.block.ExoflameHeatable; 9 | 10 | import java.util.function.Consumer; 11 | import java.util.function.Predicate; 12 | import java.util.function.ToIntFunction; 13 | 14 | public class CapabilityExoflame { 15 | 16 | public BuilderBlockEntity tileEntity() { 17 | return new BuilderBlockEntity(); 18 | } 19 | 20 | public static class BuilderBlockEntity extends CapabilityBuilderForge { 21 | 22 | private Predicate canSmelt; 23 | private ToIntFunction getBurnTime; 24 | private Consumer boostBurnTime; 25 | private Consumer boostSpeed; 26 | 27 | public BuilderBlockEntity canSmelt(Predicate canSmelt) { 28 | this.canSmelt = canSmelt; 29 | return this; 30 | } 31 | 32 | public BuilderBlockEntity getBurnTime(ToIntFunction getBurnTime) { 33 | this.getBurnTime = getBurnTime; 34 | return this; 35 | } 36 | 37 | public BuilderBlockEntity boostBurnTime(Consumer boostBurnTime) { 38 | this.boostBurnTime = boostBurnTime; 39 | return this; 40 | } 41 | 42 | public BuilderBlockEntity boostSpeed(Consumer boostSpeed) { 43 | this.boostSpeed = boostSpeed; 44 | return this; 45 | } 46 | 47 | @Override 48 | public ExoflameHeatable getCapability(BlockEntity instance) { 49 | return new ExoflameHeatable() { 50 | @Override 51 | public boolean canSmelt() { 52 | return canSmelt.test(instance); 53 | } 54 | 55 | @Override 56 | public int getBurnTime() { 57 | return getBurnTime.applyAsInt(instance); 58 | } 59 | 60 | @Override 61 | public void boostBurnTime() { 62 | if (boostBurnTime != null) 63 | boostBurnTime.accept(instance); 64 | } 65 | 66 | @Override 67 | public void boostCookTime() { 68 | if (boostSpeed != null) 69 | boostSpeed.accept(instance); 70 | } 71 | }; 72 | } 73 | 74 | @Override 75 | public Capability getCapabilityKey() { 76 | return BotaniaForgeCapabilities.EXOFLAME_HEATABLE; 77 | } 78 | 79 | @Override 80 | public ResourceLocation getResourceLocation() { 81 | return new ResourceLocation("powerful:exoflame_be"); 82 | } 83 | } 84 | } 85 | -------------------------------------------------------------------------------- /forge/src/main/java/com/prunoideae/powerfuljs/capabilities/forge/mods/botania/CapabilityMana.java: -------------------------------------------------------------------------------- 1 | package com.prunoideae.powerfuljs.capabilities.forge.mods.botania; 2 | 3 | import com.prunoideae.powerfuljs.capabilities.forge.CapabilityBuilderForge; 4 | import net.minecraft.core.BlockPos; 5 | import net.minecraft.resources.ResourceLocation; 6 | import net.minecraft.world.item.ItemStack; 7 | import net.minecraft.world.level.Level; 8 | import net.minecraft.world.level.block.entity.BlockEntity; 9 | import net.minecraftforge.common.capabilities.Capability; 10 | import vazkii.botania.api.BotaniaForgeCapabilities; 11 | import vazkii.botania.api.mana.ManaItem; 12 | import vazkii.botania.api.mana.ManaReceiver; 13 | 14 | import java.util.function.BiConsumer; 15 | import java.util.function.BiPredicate; 16 | import java.util.function.Predicate; 17 | import java.util.function.ToIntFunction; 18 | 19 | public class CapabilityMana { 20 | 21 | public ItemStackBuilder itemStack() { 22 | return new ItemStackBuilder(); 23 | } 24 | 25 | public BlockEntityBuilder blockEntity() { 26 | return new BlockEntityBuilder(); 27 | } 28 | 29 | public static class ItemStackBuilder extends CapabilityBuilderForge { 30 | private ToIntFunction getMana; 31 | private ToIntFunction getMaxMana; 32 | private BiConsumer addMana; 33 | private BiPredicate canReceiveManaFromPool; 34 | private BiPredicate canReceiveManaFromItem; 35 | private BiPredicate canExportManaToPool; 36 | private BiPredicate canExportManaToItem; 37 | private boolean noExport = false; 38 | 39 | public ItemStackBuilder getMana(ToIntFunction getMana) { 40 | this.getMana = getMana; 41 | return this; 42 | } 43 | 44 | public ItemStackBuilder getMaxMana(ToIntFunction getMaxMana) { 45 | this.getMaxMana = getMaxMana; 46 | return this; 47 | } 48 | 49 | public ItemStackBuilder addMana(BiConsumer addMana) { 50 | this.addMana = addMana; 51 | return this; 52 | } 53 | 54 | public ItemStackBuilder canReceiveManaFromPool(BiPredicate canReceiveManaFromPool) { 55 | this.canReceiveManaFromPool = canReceiveManaFromPool; 56 | return this; 57 | } 58 | 59 | public ItemStackBuilder canReceiveManaFromItem(BiPredicate canReceiveManaFromItem) { 60 | this.canReceiveManaFromItem = canReceiveManaFromItem; 61 | return this; 62 | } 63 | 64 | public ItemStackBuilder canExportManaToPool(BiPredicate canExportManaToPool) { 65 | this.canExportManaToPool = canExportManaToPool; 66 | return this; 67 | } 68 | 69 | public ItemStackBuilder canExportManaToItem(BiPredicate canExportManaToItem) { 70 | this.canExportManaToItem = canExportManaToItem; 71 | return this; 72 | } 73 | 74 | public ItemStackBuilder setNoExport(boolean noExport) { 75 | this.noExport = noExport; 76 | return this; 77 | } 78 | 79 | @Override 80 | public ManaItem getCapability(ItemStack instance) { 81 | return new ManaItem() { 82 | @Override 83 | public int getMana() { 84 | return getMana == null ? 0 : getMana.applyAsInt(instance); 85 | } 86 | 87 | @Override 88 | public int getMaxMana() { 89 | return getMaxMana == null ? 0 : getMaxMana.applyAsInt(instance); 90 | } 91 | 92 | @Override 93 | public void addMana(int mana) { 94 | if (addMana != null) 95 | addMana.accept(instance, mana); 96 | } 97 | 98 | @Override 99 | public boolean canReceiveManaFromPool(BlockEntity pool) { 100 | return canReceiveManaFromPool != null && canReceiveManaFromPool.test(instance, pool); 101 | } 102 | 103 | @Override 104 | public boolean canReceiveManaFromItem(ItemStack otherStack) { 105 | return canReceiveManaFromItem != null && canReceiveManaFromItem.test(instance, otherStack); 106 | } 107 | 108 | @Override 109 | public boolean canExportManaToPool(BlockEntity pool) { 110 | return canExportManaToPool != null && canExportManaToPool.test(instance, pool); 111 | } 112 | 113 | @Override 114 | public boolean canExportManaToItem(ItemStack otherStack) { 115 | return canExportManaToItem != null && canExportManaToItem.test(instance, otherStack); 116 | } 117 | 118 | @Override 119 | public boolean isNoExport() { 120 | return noExport; 121 | } 122 | }; 123 | } 124 | 125 | @Override 126 | public Capability getCapabilityKey() { 127 | return BotaniaForgeCapabilities.MANA_ITEM; 128 | } 129 | 130 | @Override 131 | public ResourceLocation getResourceLocation() { 132 | return new ResourceLocation("powerful:mana_item"); 133 | } 134 | } 135 | 136 | public static class BlockEntityBuilder extends CapabilityBuilderForge { 137 | 138 | private ToIntFunction getCurrentMana; 139 | private Predicate isFull; 140 | private BiConsumer receiveMana; 141 | private Predicate canReceiveManaFromBurst; 142 | 143 | public BlockEntityBuilder getCurrentMana(ToIntFunction getCurrentMana) { 144 | this.getCurrentMana = getCurrentMana; 145 | return this; 146 | } 147 | 148 | public BlockEntityBuilder isFull(Predicate isFull) { 149 | this.isFull = isFull; 150 | return this; 151 | } 152 | 153 | public BlockEntityBuilder receiveMana(BiConsumer receiveMana) { 154 | this.receiveMana = receiveMana; 155 | return this; 156 | } 157 | 158 | public BlockEntityBuilder canReceiveManaFromBurst(Predicate canReceiveManaFromBurst) { 159 | this.canReceiveManaFromBurst = canReceiveManaFromBurst; 160 | return this; 161 | } 162 | 163 | @Override 164 | public ManaReceiver getCapability(BlockEntity instance) { 165 | return new ManaReceiver() { 166 | @Override 167 | public Level getManaReceiverLevel() { 168 | return instance.getLevel(); 169 | } 170 | 171 | @Override 172 | public BlockPos getManaReceiverPos() { 173 | return instance.getBlockPos(); 174 | } 175 | 176 | @Override 177 | public int getCurrentMana() { 178 | return getCurrentMana == null ? 0 : getCurrentMana.applyAsInt(instance); 179 | } 180 | 181 | @Override 182 | public boolean isFull() { 183 | return isFull != null && isFull.test(instance); 184 | } 185 | 186 | @Override 187 | public void receiveMana(int mana) { 188 | if (receiveMana != null) 189 | receiveMana.accept(instance, mana); 190 | } 191 | 192 | @Override 193 | public boolean canReceiveManaFromBursts() { 194 | return canReceiveManaFromBurst == null ? !isFull() : canReceiveManaFromBurst.test(instance); 195 | } 196 | }; 197 | } 198 | 199 | @Override 200 | public Capability getCapabilityKey() { 201 | return BotaniaForgeCapabilities.MANA_RECEIVER; 202 | } 203 | 204 | @Override 205 | public ResourceLocation getResourceLocation() { 206 | return new ResourceLocation("powerful:mana_be"); 207 | } 208 | } 209 | } 210 | -------------------------------------------------------------------------------- /forge/src/main/java/com/prunoideae/powerfuljs/capabilities/forge/mods/botania/CapabilityRelic.java: -------------------------------------------------------------------------------- 1 | package com.prunoideae.powerfuljs.capabilities.forge.mods.botania; 2 | 3 | import com.prunoideae.powerfuljs.capabilities.forge.CapabilityBuilderForge; 4 | import dev.latvian.mods.rhino.util.HideFromJS; 5 | import net.minecraft.network.chat.Component; 6 | import net.minecraft.resources.ResourceLocation; 7 | import net.minecraft.world.entity.player.Player; 8 | import net.minecraft.world.item.ItemStack; 9 | import net.minecraftforge.common.capabilities.Capability; 10 | import org.jetbrains.annotations.Nullable; 11 | import vazkii.botania.api.BotaniaForgeCapabilities; 12 | import vazkii.botania.api.item.Relic; 13 | import vazkii.botania.common.helper.ItemNBTHelper; 14 | import vazkii.botania.common.item.relic.RelicImpl; 15 | 16 | import java.util.List; 17 | import java.util.UUID; 18 | 19 | 20 | public class CapabilityRelic { 21 | 22 | @FunctionalInterface 23 | public interface RelicTick { 24 | void tick(ItemStack stack, Relic relic, Player player); 25 | } 26 | 27 | public NormalRelicBuilder normalRelic() { 28 | return normalRelic(null); 29 | } 30 | 31 | public NormalRelicBuilder normalRelic(ResourceLocation advancement) { 32 | return new NormalRelicBuilder(advancement); 33 | } 34 | 35 | public CustomRelicBuilder customRelic() { 36 | return new CustomRelicBuilder(); 37 | } 38 | 39 | public void addRelicTooltipForItem(ItemStack stack, List tooltip) { 40 | RelicImpl.addDefaultTooltip(stack, tooltip); 41 | } 42 | 43 | public static class NormalRelicBuilder extends CapabilityBuilderForge { 44 | 45 | private final ResourceLocation advancement; 46 | 47 | public NormalRelicBuilder(ResourceLocation advancement) { 48 | this.advancement = advancement; 49 | } 50 | 51 | @Override 52 | public Relic getCapability(ItemStack instance) { 53 | return new RelicImpl(instance, advancement); 54 | } 55 | 56 | @Override 57 | public Capability getCapabilityKey() { 58 | return BotaniaForgeCapabilities.RELIC; 59 | } 60 | 61 | @Override 62 | public ResourceLocation getResourceLocation() { 63 | return new ResourceLocation("powerful:relic_botania"); 64 | } 65 | } 66 | 67 | public static class CustomRelicBuilder extends CapabilityBuilderForge { 68 | private static final String TAG_SOULBIND_UUID = "soulbindUUID"; 69 | 70 | private RelicTick tick; 71 | private ResourceLocation advancement; 72 | private boolean shouldDamageWrongPlayer = true; 73 | 74 | public CustomRelicBuilder setAdvancement(ResourceLocation advancement) { 75 | this.advancement = advancement; 76 | return this; 77 | } 78 | 79 | public CustomRelicBuilder shouldDamageWrongPlayer(boolean shouldDamageWrongPlayer) { 80 | this.shouldDamageWrongPlayer = shouldDamageWrongPlayer; 81 | return this; 82 | } 83 | 84 | public CustomRelicBuilder onTick(RelicTick tick) { 85 | this.tick = tick; 86 | return this; 87 | } 88 | 89 | @Override 90 | @HideFromJS 91 | public Relic getCapability(ItemStack instance) { 92 | return new Relic() { 93 | @Override 94 | public void bindToUUID(UUID uuid) { 95 | ItemNBTHelper.setString(instance, TAG_SOULBIND_UUID, uuid.toString()); 96 | } 97 | 98 | @Override 99 | public @Nullable UUID getSoulbindUUID() { 100 | if (ItemNBTHelper.verifyExistance(instance, TAG_SOULBIND_UUID)) { 101 | try { 102 | return UUID.fromString(ItemNBTHelper.getString(instance, TAG_SOULBIND_UUID, "")); 103 | } catch (IllegalArgumentException ex) { // Bad UUID in tag 104 | ItemNBTHelper.removeEntry(instance, TAG_SOULBIND_UUID); 105 | } 106 | } 107 | return null; 108 | } 109 | 110 | @Override 111 | public void tickBinding(Player player) { 112 | if (tick != null) 113 | tick.tick(instance, this, player); 114 | } 115 | 116 | @Override 117 | public boolean isRightPlayer(Player player) { 118 | return player.getUUID().equals(getSoulbindUUID()); 119 | } 120 | 121 | @Override 122 | public @Nullable ResourceLocation getAdvancement() { 123 | return advancement; 124 | } 125 | 126 | @Override 127 | public boolean shouldDamageWrongPlayer() { 128 | return shouldDamageWrongPlayer; 129 | } 130 | }; 131 | } 132 | 133 | @Override 134 | @HideFromJS 135 | public Capability getCapabilityKey() { 136 | return BotaniaForgeCapabilities.RELIC; 137 | } 138 | 139 | @Override 140 | @HideFromJS 141 | public ResourceLocation getResourceLocation() { 142 | return new ResourceLocation("powerful:relic_custom_botania"); 143 | } 144 | } 145 | } 146 | -------------------------------------------------------------------------------- /forge/src/main/java/com/prunoideae/powerfuljs/capabilities/forge/mods/curios/CapabilitiesCurios.java: -------------------------------------------------------------------------------- 1 | package com.prunoideae.powerfuljs.capabilities.forge.mods.curios; 2 | 3 | public interface CapabilitiesCurios { 4 | CapabilityCurios CURIOS = new CapabilityCurios(); 5 | } 6 | -------------------------------------------------------------------------------- /forge/src/main/java/com/prunoideae/powerfuljs/capabilities/forge/mods/curios/CapabilityCurios.java: -------------------------------------------------------------------------------- 1 | package com.prunoideae.powerfuljs.capabilities.forge.mods.curios; 2 | 3 | import com.google.common.collect.HashMultimap; 4 | import com.google.common.collect.Multimap; 5 | import com.prunoideae.powerfuljs.capabilities.forge.CapabilityBuilderForge; 6 | import dev.latvian.mods.kubejs.registry.KubeJSRegistries; 7 | import dev.latvian.mods.rhino.util.HideFromJS; 8 | import net.minecraft.resources.ResourceLocation; 9 | import net.minecraft.world.damagesource.DamageSource; 10 | import net.minecraft.world.entity.ai.attributes.Attribute; 11 | import net.minecraft.world.entity.ai.attributes.AttributeModifier; 12 | import net.minecraft.world.item.ItemStack; 13 | import net.minecraftforge.common.capabilities.Capability; 14 | import org.jetbrains.annotations.NotNull; 15 | import top.theillusivec4.curios.api.CuriosCapability; 16 | import top.theillusivec4.curios.api.SlotContext; 17 | import top.theillusivec4.curios.api.type.capability.ICurio; 18 | 19 | import java.util.Map; 20 | import java.util.UUID; 21 | import java.util.function.BiConsumer; 22 | import java.util.function.BiPredicate; 23 | import java.util.function.Consumer; 24 | 25 | public class CapabilityCurios { 26 | @FunctionalInterface 27 | public interface EquipCallback { 28 | void changed(ItemStack instance, SlotContext slotContext, ItemStack stack); 29 | } 30 | 31 | @FunctionalInterface 32 | public interface ShouldDrop { 33 | boolean test(ItemStack instance, SlotContext slotContext, DamageSource source, int lootingLevel, boolean recentlyHit); 34 | } 35 | 36 | public static class AttributeModificationContext { 37 | private final ItemStack stack; 38 | private final SlotContext context; 39 | private final UUID uuid; 40 | 41 | private final Multimap modifiers; 42 | 43 | public AttributeModificationContext(ItemStack stack, SlotContext context, UUID uuid, Multimap modifiers) { 44 | this.stack = stack; 45 | this.context = context; 46 | this.uuid = uuid; 47 | this.modifiers = modifiers; 48 | } 49 | 50 | public ItemStack getStack() { 51 | return stack; 52 | } 53 | 54 | public SlotContext getContext() { 55 | return context; 56 | } 57 | 58 | public UUID getUUID() { 59 | return uuid; 60 | } 61 | 62 | public AttributeModificationContext modify(Attribute attribute, String identifier, double amount, AttributeModifier.Operation operation) { 63 | modifiers.put(attribute, new AttributeModifier(new UUID(identifier.hashCode(), identifier.hashCode()), identifier, amount, operation)); 64 | return this; 65 | } 66 | 67 | public AttributeModificationContext remove(Attribute attribute, String identifier) { 68 | modifiers.get(attribute).removeIf(modifier -> modifier.getName().equals(identifier)); 69 | return this; 70 | } 71 | 72 | @HideFromJS 73 | public Multimap getModifiers() { 74 | return modifiers; 75 | } 76 | } 77 | 78 | public ItemStackBuilder itemStack() { 79 | return new ItemStackBuilder(); 80 | } 81 | 82 | public static class ItemStackBuilder extends CapabilityBuilderForge { 83 | private BiConsumer curioTick; 84 | private EquipCallback onEquip; 85 | private EquipCallback onUnequip; 86 | private BiPredicate canEquip; 87 | private BiPredicate canUnequip; 88 | private ShouldDrop shouldDrop; 89 | 90 | public ItemStackBuilder curioTick(BiConsumer curioTick) { 91 | this.curioTick = curioTick; 92 | return this; 93 | } 94 | 95 | public ItemStackBuilder onEquip(EquipCallback onEquip) { 96 | this.onEquip = onEquip; 97 | return this; 98 | } 99 | 100 | public ItemStackBuilder onUnequip(EquipCallback onUnequip) { 101 | this.onUnequip = onUnequip; 102 | return this; 103 | } 104 | 105 | public ItemStackBuilder canEquip(BiPredicate canEquip) { 106 | this.canEquip = canEquip; 107 | return this; 108 | } 109 | 110 | public ItemStackBuilder canUnequip(BiPredicate canUnequip) { 111 | this.canUnequip = canUnequip; 112 | return this; 113 | } 114 | 115 | public ItemStackBuilder getDropRule(ShouldDrop getDropRule) { 116 | this.shouldDrop = getDropRule; 117 | return this; 118 | } 119 | 120 | private final Multimap modifiers = HashMultimap.create(); 121 | private final Multimap attributes = HashMultimap.create(); 122 | private Consumer dynamicAttribute = null; 123 | private boolean attributeInitialized = false; 124 | 125 | public ItemStackBuilder modifyAttribute(ResourceLocation attribute, String identifier, double d, AttributeModifier.Operation operation) { 126 | modifiers.put(attribute, new AttributeModifier(new UUID(identifier.hashCode(), identifier.hashCode()), identifier, d, operation)); 127 | return this; 128 | } 129 | 130 | public ItemStackBuilder dynamicAttribute(Consumer context) { 131 | dynamicAttribute = context; 132 | return this; 133 | } 134 | 135 | @Override 136 | public ICurio getCapability(ItemStack instance) { 137 | return new ICurio() { 138 | @Override 139 | public ItemStack getStack() { 140 | return instance; 141 | } 142 | 143 | @Override 144 | public void curioTick(SlotContext slotContext) { 145 | if (curioTick != null) 146 | curioTick.accept(instance, slotContext); 147 | else 148 | ICurio.super.curioTick(slotContext); 149 | } 150 | 151 | @Override 152 | public void onEquip(SlotContext slotContext, ItemStack prevStack) { 153 | if (onEquip != null) 154 | onEquip.changed(instance, slotContext, prevStack); 155 | else 156 | ICurio.super.onEquip(slotContext, prevStack); 157 | } 158 | 159 | @Override 160 | public void onUnequip(SlotContext slotContext, ItemStack newStack) { 161 | if (onUnequip != null) 162 | onUnequip.changed(instance, slotContext, newStack); 163 | else 164 | ICurio.super.onUnequip(slotContext, newStack); 165 | } 166 | 167 | @Override 168 | public boolean canEquip(SlotContext slotContext) { 169 | if (canEquip != null) 170 | return canEquip.test(instance, slotContext); 171 | else 172 | return ICurio.super.canEquip(slotContext); 173 | } 174 | 175 | @Override 176 | public boolean canUnequip(SlotContext slotContext) { 177 | if (canUnequip != null) 178 | return canUnequip.test(instance, slotContext); 179 | return ICurio.super.canUnequip(slotContext); 180 | } 181 | 182 | @Override 183 | public Multimap getAttributeModifiers(SlotContext slotContext, UUID uuid) { 184 | if (!attributeInitialized) { 185 | for (Map.Entry entry : modifiers.entries()) { 186 | ResourceLocation key = entry.getKey(); 187 | AttributeModifier modifier = entry.getValue(); 188 | attributes.put(KubeJSRegistries.attributes().get(key), modifier); 189 | } 190 | attributeInitialized = true; 191 | } 192 | 193 | if (dynamicAttribute != null) { 194 | Multimap attributeCopy = HashMultimap.create(attributes); 195 | dynamicAttribute.accept(new AttributeModificationContext(instance, slotContext, uuid, attributeCopy)); 196 | return attributeCopy; 197 | } 198 | 199 | return attributes; 200 | } 201 | 202 | @NotNull 203 | @Override 204 | public DropRule getDropRule(SlotContext slotContext, DamageSource source, int lootingLevel, boolean recentlyHit) { 205 | if (shouldDrop != null) 206 | return shouldDrop.test(instance, slotContext, source, lootingLevel, recentlyHit) ? DropRule.ALWAYS_DROP : DropRule.ALWAYS_KEEP; 207 | return DropRule.DEFAULT; 208 | } 209 | 210 | @Override 211 | public boolean canEquipFromUse(SlotContext slotContext) { 212 | return true; 213 | } 214 | }; 215 | } 216 | 217 | @Override 218 | public Capability getCapabilityKey() { 219 | return CuriosCapability.ITEM; 220 | } 221 | 222 | @Override 223 | public ResourceLocation getResourceLocation() { 224 | return CuriosCapability.ID_ITEM; 225 | } 226 | } 227 | } 228 | -------------------------------------------------------------------------------- /forge/src/main/java/com/prunoideae/powerfuljs/capabilities/forge/mods/curios/EventCurios.java: -------------------------------------------------------------------------------- 1 | package com.prunoideae.powerfuljs.capabilities.forge.mods.curios; 2 | 3 | import dev.latvian.mods.kubejs.event.EventGroup; 4 | import dev.latvian.mods.kubejs.event.EventHandler; 5 | 6 | public interface EventCurios { 7 | EventGroup GROUP = EventGroup.of("CuriosEvents"); 8 | EventHandler REGISTER_RENDERER = GROUP.client("registerRenderer", () -> RegisterCuriosRendererEventJS.class); 9 | } 10 | -------------------------------------------------------------------------------- /forge/src/main/java/com/prunoideae/powerfuljs/capabilities/forge/mods/curios/RegisterCuriosRendererEventJS.java: -------------------------------------------------------------------------------- 1 | package com.prunoideae.powerfuljs.capabilities.forge.mods.curios; 2 | 3 | import com.prunoideae.powerfuljs.PowerfulJS; 4 | import dev.latvian.mods.kubejs.client.ClientEventJS; 5 | import dev.latvian.mods.kubejs.event.EventJS; 6 | import net.minecraft.world.item.Item; 7 | import top.theillusivec4.curios.api.client.CuriosRendererRegistry; 8 | 9 | import java.util.function.Consumer; 10 | 11 | public class RegisterCuriosRendererEventJS extends EventJS { 12 | public void register(Item item, Consumer renderer) { 13 | PowerfulJS.PROXY.get().runOnClient(() -> CuriosRendererRegistry.register(item, () -> new RendererCurios(renderer))); 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /forge/src/main/java/com/prunoideae/powerfuljs/capabilities/forge/mods/curios/RendererCurios.java: -------------------------------------------------------------------------------- 1 | package com.prunoideae.powerfuljs.capabilities.forge.mods.curios; 2 | 3 | import com.mojang.blaze3d.vertex.PoseStack; 4 | import net.minecraft.client.model.EntityModel; 5 | import net.minecraft.client.renderer.MultiBufferSource; 6 | import net.minecraft.client.renderer.entity.RenderLayerParent; 7 | import net.minecraft.world.entity.LivingEntity; 8 | import net.minecraft.world.item.ItemStack; 9 | import top.theillusivec4.curios.api.SlotContext; 10 | import top.theillusivec4.curios.api.client.ICurioRenderer; 11 | 12 | import java.util.function.Consumer; 13 | 14 | public class RendererCurios implements ICurioRenderer { 15 | public RendererCurios(Consumer renderer) { 16 | this.renderer = renderer; 17 | } 18 | 19 | public static class RenderContext { 20 | public final ItemStack stack; 21 | public final SlotContext slotContext; 22 | public final PoseStack matrixStack; 23 | public final RenderLayerParent> renderLayerParent; 24 | public final MultiBufferSource renderTypeBuffer; 25 | public final int light; 26 | public final float limbSwing; 27 | public final float limbSwingAmount; 28 | public final float partialTicks; 29 | public final float ageInTicks; 30 | public final float netHeadYaw; 31 | public final float netHeadPitch; 32 | 33 | public RenderContext(ItemStack stack, SlotContext slotContext, PoseStack matrixStack, RenderLayerParent> renderLayerParent, MultiBufferSource renderTypeBuffer, int light, float limbSwing, float limbSwingAmount, float partialTicks, float ageInTicks, float netHeadYaw, float netHeadPitch) { 34 | this.stack = stack; 35 | this.slotContext = slotContext; 36 | this.matrixStack = matrixStack; 37 | this.renderLayerParent = renderLayerParent; 38 | this.renderTypeBuffer = renderTypeBuffer; 39 | this.light = light; 40 | this.limbSwing = limbSwing; 41 | this.limbSwingAmount = limbSwingAmount; 42 | this.partialTicks = partialTicks; 43 | this.ageInTicks = ageInTicks; 44 | this.netHeadYaw = netHeadYaw; 45 | this.netHeadPitch = netHeadPitch; 46 | } 47 | } 48 | 49 | private final Consumer renderer; 50 | 51 | @Override 52 | @SuppressWarnings("unchecked") 53 | public > void render(ItemStack stack, SlotContext slotContext, PoseStack matrixStack, RenderLayerParent renderLayerParent, MultiBufferSource renderTypeBuffer, int light, float limbSwing, float limbSwingAmount, float partialTicks, float ageInTicks, float netHeadYaw, float headPitch) { 54 | renderer.accept(new RenderContext(stack, slotContext, matrixStack, (RenderLayerParent>) renderLayerParent, renderTypeBuffer, light, limbSwing, limbSwingAmount, partialTicks, ageInTicks, netHeadYaw, headPitch)); 55 | } 56 | } 57 | -------------------------------------------------------------------------------- /forge/src/main/java/com/prunoideae/powerfuljs/capabilities/forge/mods/immersive/CapabilitiesHelperIE.java: -------------------------------------------------------------------------------- 1 | package com.prunoideae.powerfuljs.capabilities.forge.mods.immersive; 2 | 3 | import blusunrize.immersiveengineering.api.energy.IRotationAcceptor; 4 | import blusunrize.immersiveengineering.api.shader.CapabilityShader; 5 | import blusunrize.immersiveengineering.api.tool.ExternalHeaterHandler; 6 | import blusunrize.immersiveengineering.api.wires.GlobalWireNetwork; 7 | import blusunrize.immersiveengineering.api.wires.NetHandlerCapability; 8 | import blusunrize.immersiveengineering.api.wires.redstone.CapabilityRedstoneNetwork; 9 | import net.minecraftforge.common.capabilities.Capability; 10 | 11 | public interface CapabilitiesHelperIE { 12 | Capability ROTATION_ACCEPTOR = IRotationAcceptor.CAPABILITY; 13 | Capability EXTERNAL_HEATABLE = ExternalHeaterHandler.CAPABILITY; 14 | Capability GLOBAL_WIRE_NETWORK = NetHandlerCapability.NET_CAPABILITY; 15 | Capability REDSTONE_BUNDLE_CONNECTION = CapabilityRedstoneNetwork.REDSTONE_BUNDLE_CONNECTION; 16 | Capability SHADER_WRAPPER = CapabilityShader.SHADER_CAPABILITY; 17 | } 18 | -------------------------------------------------------------------------------- /forge/src/main/java/com/prunoideae/powerfuljs/capabilities/forge/mods/immersive/CapabilitiesIE.java: -------------------------------------------------------------------------------- 1 | package com.prunoideae.powerfuljs.capabilities.forge.mods.immersive; 2 | 3 | public interface CapabilitiesIE { 4 | CapabilityRotationAcceptor ROTATION_ACCEPTOR = new CapabilityRotationAcceptor(); 5 | CapabilityExternalHeatable EXTERNAL_HEATABLE = new CapabilityExternalHeatable(); 6 | } 7 | -------------------------------------------------------------------------------- /forge/src/main/java/com/prunoideae/powerfuljs/capabilities/forge/mods/immersive/CapabilityExternalHeatable.java: -------------------------------------------------------------------------------- 1 | package com.prunoideae.powerfuljs.capabilities.forge.mods.immersive; 2 | 3 | import blusunrize.immersiveengineering.api.tool.ExternalHeaterHandler; 4 | import com.prunoideae.powerfuljs.capabilities.forge.CapabilityBuilderForge; 5 | import net.minecraft.resources.ResourceLocation; 6 | import net.minecraft.world.level.block.entity.BlockEntity; 7 | import net.minecraftforge.common.capabilities.Capability; 8 | 9 | public class CapabilityExternalHeatable { 10 | 11 | public BlockEntityBuilder blockEntity() { 12 | return new BlockEntityBuilder(); 13 | } 14 | 15 | @FunctionalInterface 16 | interface DoHeatTick { 17 | int doHeatTick(BlockEntity blockEntity, int energyAvailable, boolean redstone); 18 | } 19 | 20 | public static class BlockEntityBuilder extends CapabilityBuilderForge { 21 | DoHeatTick doHeatTick = (a, b, c) -> 0; 22 | 23 | public BlockEntityBuilder doHeatTick(DoHeatTick doHeatTick) { 24 | this.doHeatTick = doHeatTick; 25 | return this; 26 | } 27 | 28 | @Override 29 | public ExternalHeaterHandler.IExternalHeatable getCapability(BlockEntity instance) { 30 | return (ExternalHeaterHandler.IExternalHeatable) doHeatTick; 31 | } 32 | 33 | @Override 34 | public Capability getCapabilityKey() { 35 | return ExternalHeaterHandler.CAPABILITY; 36 | } 37 | 38 | @Override 39 | public ResourceLocation getResourceLocation() { 40 | return new ResourceLocation("ie_exheater_be_custom"); 41 | } 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /forge/src/main/java/com/prunoideae/powerfuljs/capabilities/forge/mods/immersive/CapabilityRotationAcceptor.java: -------------------------------------------------------------------------------- 1 | package com.prunoideae.powerfuljs.capabilities.forge.mods.immersive; 2 | 3 | import blusunrize.immersiveengineering.api.energy.IRotationAcceptor; 4 | import com.prunoideae.powerfuljs.capabilities.forge.CapabilityBuilderForge; 5 | import net.minecraft.resources.ResourceLocation; 6 | import net.minecraft.world.level.block.entity.BlockEntity; 7 | import net.minecraftforge.common.capabilities.Capability; 8 | 9 | import java.util.function.BiConsumer; 10 | 11 | public class CapabilityRotationAcceptor { 12 | public BlockEntityBuilder blockEntity() { 13 | return new BlockEntityBuilder(); 14 | } 15 | 16 | public static class BlockEntityBuilder extends CapabilityBuilderForge { 17 | private BiConsumer inputRotation; 18 | 19 | public BlockEntityBuilder inputRotation(BiConsumer inputRotation) { 20 | this.inputRotation = inputRotation; 21 | return this; 22 | } 23 | 24 | @Override 25 | public IRotationAcceptor getCapability(BlockEntity instance) { 26 | return rotation -> { 27 | if (inputRotation != null) 28 | inputRotation.accept(instance, rotation); 29 | }; 30 | } 31 | 32 | @Override 33 | public Capability getCapabilityKey() { 34 | return IRotationAcceptor.CAPABILITY; 35 | } 36 | 37 | @Override 38 | public ResourceLocation getResourceLocation() { 39 | return new ResourceLocation("powerful:ie_rotation_be_custom"); 40 | } 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /forge/src/main/java/com/prunoideae/powerfuljs/capabilities/forge/mods/mekanism/CapabilitiesMekanism.java: -------------------------------------------------------------------------------- 1 | package com.prunoideae.powerfuljs.capabilities.forge.mods.mekanism; 2 | 3 | import com.prunoideae.powerfuljs.capabilities.forge.mods.mekanism.chemical.CapabilityGas; 4 | import com.prunoideae.powerfuljs.capabilities.forge.mods.mekanism.chemical.CapabilityInfusion; 5 | import com.prunoideae.powerfuljs.capabilities.forge.mods.mekanism.chemical.CapabilityPigment; 6 | import com.prunoideae.powerfuljs.capabilities.forge.mods.mekanism.chemical.CapabilitySlurry; 7 | 8 | public interface CapabilitiesMekanism { 9 | CapabilityGas GAS = new CapabilityGas(); 10 | CapabilityInfusion INFUSION = new CapabilityInfusion(); 11 | CapabilityPigment PIGMENT = new CapabilityPigment(); 12 | CapabilitySlurry SLURRY = new CapabilitySlurry(); 13 | CapabilityProtection PROTECTION = new CapabilityProtection(); 14 | CapabilityAlloyInteractable ALLOY_INTERACTABLE = new CapabilityAlloyInteractable(); 15 | CapabilityConfigurable CONFIGURABLE = new CapabilityConfigurable(); 16 | CapabilityEvaporationTower EVAPORATION_TOWER = new CapabilityEvaporationTower(); 17 | CapabilityLaser LASER = new CapabilityLaser(); 18 | } 19 | -------------------------------------------------------------------------------- /forge/src/main/java/com/prunoideae/powerfuljs/capabilities/forge/mods/mekanism/CapabilityAlloyInteractable.java: -------------------------------------------------------------------------------- 1 | package com.prunoideae.powerfuljs.capabilities.forge.mods.mekanism; 2 | 3 | import com.prunoideae.powerfuljs.capabilities.forge.CapabilityBuilderForge; 4 | import mekanism.api.IAlloyInteraction; 5 | import mekanism.api.tier.AlloyTier; 6 | import mekanism.common.capabilities.Capabilities; 7 | import net.minecraft.resources.ResourceLocation; 8 | import net.minecraft.world.entity.player.Player; 9 | import net.minecraft.world.item.ItemStack; 10 | import net.minecraft.world.level.block.entity.BlockEntity; 11 | import net.minecraftforge.common.capabilities.Capability; 12 | 13 | public class CapabilityAlloyInteractable { 14 | 15 | public BlockEntityBuilder blockEntity() { 16 | return new BlockEntityBuilder(); 17 | } 18 | 19 | @FunctionalInterface 20 | public interface AlloyInteraction { 21 | void onInteraction(BlockEntity instance, Player player, ItemStack itemStack, AlloyTier tier); 22 | } 23 | 24 | 25 | public static class BlockEntityBuilder extends CapabilityBuilderForge { 26 | 27 | private AlloyInteraction interaction; 28 | 29 | public BlockEntityBuilder interaction(AlloyInteraction interaction) { 30 | this.interaction = interaction; 31 | return this; 32 | } 33 | 34 | @Override 35 | public IAlloyInteraction getCapability(BlockEntity instance) { 36 | return (player, stack, tier) -> { 37 | if (interaction != null) 38 | interaction.onInteraction(instance, player, stack, tier); 39 | }; 40 | } 41 | 42 | @Override 43 | public Capability getCapabilityKey() { 44 | return Capabilities.ALLOY_INTERACTION; 45 | } 46 | 47 | @Override 48 | public ResourceLocation getResourceLocation() { 49 | return new ResourceLocation("powerful:alloy_be_custom"); 50 | } 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /forge/src/main/java/com/prunoideae/powerfuljs/capabilities/forge/mods/mekanism/CapabilityConfigurable.java: -------------------------------------------------------------------------------- 1 | package com.prunoideae.powerfuljs.capabilities.forge.mods.mekanism; 2 | 3 | import com.prunoideae.powerfuljs.capabilities.forge.CapabilityBuilderForge; 4 | import mekanism.api.IConfigurable; 5 | import mekanism.common.capabilities.Capabilities; 6 | import net.minecraft.resources.ResourceLocation; 7 | import net.minecraft.world.InteractionResult; 8 | import net.minecraft.world.entity.player.Player; 9 | import net.minecraft.world.level.block.entity.BlockEntity; 10 | import net.minecraftforge.common.capabilities.Capability; 11 | 12 | import java.util.function.BiFunction; 13 | 14 | public class CapabilityConfigurable { 15 | public BlockEntityBuilder blockEntity() { 16 | return new BlockEntityBuilder(); 17 | } 18 | 19 | public static class BlockEntityBuilder extends CapabilityBuilderForge { 20 | private BiFunction onSneakRightClick; 21 | private BiFunction onRightClick; 22 | 23 | public BlockEntityBuilder onSneakRightClick(BiFunction onSneakRightClick) { 24 | this.onSneakRightClick = onSneakRightClick; 25 | return this; 26 | } 27 | 28 | public BlockEntityBuilder onRightClick(BiFunction onRightClick) { 29 | this.onRightClick = onRightClick; 30 | return this; 31 | } 32 | 33 | @Override 34 | public IConfigurable getCapability(BlockEntity instance) { 35 | return new IConfigurable() { 36 | @Override 37 | public InteractionResult onSneakRightClick(Player player) { 38 | return onSneakRightClick != null ? InteractionResult.valueOf(onSneakRightClick.apply(instance, player)) : InteractionResult.FAIL; 39 | } 40 | 41 | @Override 42 | public InteractionResult onRightClick(Player player) { 43 | return onRightClick != null ? InteractionResult.valueOf(onRightClick.apply(instance, player)) : InteractionResult.FAIL; 44 | } 45 | }; 46 | } 47 | 48 | @Override 49 | public Capability getCapabilityKey() { 50 | return Capabilities.CONFIGURABLE; 51 | } 52 | 53 | @Override 54 | public ResourceLocation getResourceLocation() { 55 | return new ResourceLocation("powerful:mek_configurable_be"); 56 | } 57 | } 58 | } 59 | -------------------------------------------------------------------------------- /forge/src/main/java/com/prunoideae/powerfuljs/capabilities/forge/mods/mekanism/CapabilityEvaporationTower.java: -------------------------------------------------------------------------------- 1 | package com.prunoideae.powerfuljs.capabilities.forge.mods.mekanism; 2 | 3 | import com.prunoideae.powerfuljs.capabilities.forge.CapabilityBuilderForge; 4 | import mekanism.api.IEvaporationSolar; 5 | import mekanism.common.capabilities.Capabilities; 6 | import net.minecraft.resources.ResourceLocation; 7 | import net.minecraft.world.level.block.entity.BlockEntity; 8 | import net.minecraftforge.common.capabilities.Capability; 9 | 10 | import java.util.function.Predicate; 11 | 12 | public class CapabilityEvaporationTower { 13 | 14 | public BlockEntityBuilder blockEntity() { 15 | return new BlockEntityBuilder(); 16 | } 17 | 18 | public static class BlockEntityBuilder extends CapabilityBuilderForge { 19 | private Predicate canSeeSun; 20 | 21 | public BlockEntityBuilder canSeeSun(Predicate canSeeSun) { 22 | this.canSeeSun = canSeeSun; 23 | return this; 24 | } 25 | 26 | @Override 27 | public IEvaporationSolar getCapability(BlockEntity instance) { 28 | return () -> canSeeSun != null && canSeeSun.test(instance); 29 | } 30 | 31 | @Override 32 | public Capability getCapabilityKey() { 33 | return Capabilities.EVAPORATION_SOLAR; 34 | } 35 | 36 | @Override 37 | public ResourceLocation getResourceLocation() { 38 | return new ResourceLocation("powerful:mek_solar_be"); 39 | } 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /forge/src/main/java/com/prunoideae/powerfuljs/capabilities/forge/mods/mekanism/CapabilityLaser.java: -------------------------------------------------------------------------------- 1 | package com.prunoideae.powerfuljs.capabilities.forge.mods.mekanism; 2 | 3 | import com.prunoideae.powerfuljs.capabilities.forge.CapabilityBuilderForge; 4 | import mekanism.api.lasers.ILaserReceptor; 5 | import mekanism.api.math.FloatingLong; 6 | import mekanism.common.capabilities.Capabilities; 7 | import net.minecraft.resources.ResourceLocation; 8 | import net.minecraft.world.level.block.entity.BlockEntity; 9 | import net.minecraftforge.common.capabilities.Capability; 10 | import org.jetbrains.annotations.NotNull; 11 | 12 | import java.util.function.BiConsumer; 13 | import java.util.function.Predicate; 14 | 15 | public class CapabilityLaser { 16 | 17 | public BlockEntityBuilder blockEntity() { 18 | return new BlockEntityBuilder(); 19 | } 20 | 21 | public static class BlockEntityBuilder extends CapabilityBuilderForge { 22 | private Predicate canLaserDig; 23 | private BiConsumer receiveEnergy; 24 | 25 | public BlockEntityBuilder canLaserDig(Predicate canLaserDig) { 26 | this.canLaserDig = canLaserDig; 27 | return this; 28 | } 29 | 30 | public BlockEntityBuilder receiveEnergy(BiConsumer receiveEnergy) { 31 | this.receiveEnergy = receiveEnergy; 32 | return this; 33 | } 34 | 35 | @Override 36 | public ILaserReceptor getCapability(BlockEntity instance) { 37 | return new ILaserReceptor() { 38 | @Override 39 | public void receiveLaserEnergy(@NotNull FloatingLong floatingLong) { 40 | if (receiveEnergy != null) 41 | receiveEnergy.accept(instance, floatingLong); 42 | } 43 | 44 | @Override 45 | public boolean canLasersDig() { 46 | return canLaserDig != null && canLaserDig.test(instance); 47 | } 48 | }; 49 | } 50 | 51 | @Override 52 | public Capability getCapabilityKey() { 53 | return Capabilities.LASER_RECEPTOR; 54 | } 55 | 56 | @Override 57 | public ResourceLocation getResourceLocation() { 58 | return new ResourceLocation("powerful:mek_laser_be"); 59 | } 60 | } 61 | } 62 | -------------------------------------------------------------------------------- /forge/src/main/java/com/prunoideae/powerfuljs/capabilities/forge/mods/mekanism/CapabilityProtection.java: -------------------------------------------------------------------------------- 1 | package com.prunoideae.powerfuljs.capabilities.forge.mods.mekanism; 2 | 3 | import com.prunoideae.powerfuljs.capabilities.forge.CapabilityBuilderForge; 4 | import mekanism.api.lasers.ILaserDissipation; 5 | import mekanism.api.radiation.capability.IRadiationShielding; 6 | import mekanism.common.capabilities.Capabilities; 7 | import net.minecraft.resources.ResourceLocation; 8 | import net.minecraft.world.item.ItemStack; 9 | import net.minecraftforge.common.capabilities.Capability; 10 | 11 | import java.util.function.ToDoubleFunction; 12 | 13 | public class CapabilityProtection { 14 | public LaserItemStackBuilder itemStackLaserProtection() { 15 | return new LaserItemStackBuilder(); 16 | } 17 | 18 | public RadiationItemStackBuilder itemStackRadiationProtection() { 19 | return new RadiationItemStackBuilder(); 20 | } 21 | 22 | public static class LaserItemStackBuilder extends CapabilityBuilderForge { 23 | 24 | private ToDoubleFunction getDissipationPercent; 25 | private ToDoubleFunction getRefractionPercent; 26 | 27 | public LaserItemStackBuilder getDissipationPercent(ToDoubleFunction getDissipationPercent) { 28 | this.getDissipationPercent = getDissipationPercent; 29 | return this; 30 | } 31 | 32 | public LaserItemStackBuilder getRefractionPercent(ToDoubleFunction getRefractionPercent) { 33 | this.getRefractionPercent = getRefractionPercent; 34 | return this; 35 | } 36 | 37 | @Override 38 | public ILaserDissipation getCapability(ItemStack instance) { 39 | return new ILaserDissipation() { 40 | @Override 41 | public double getDissipationPercent() { 42 | return getDissipationPercent == null ? 0 : getDissipationPercent.applyAsDouble(instance); 43 | } 44 | 45 | @Override 46 | public double getRefractionPercent() { 47 | return getRefractionPercent == null ? 0 : getRefractionPercent.applyAsDouble(instance); 48 | } 49 | }; 50 | } 51 | 52 | @Override 53 | public Capability getCapabilityKey() { 54 | return Capabilities.LASER_DISSIPATION; 55 | } 56 | 57 | @Override 58 | public ResourceLocation getResourceLocation() { 59 | return new ResourceLocation("powerful:laser_protection_item"); 60 | } 61 | } 62 | 63 | public static class RadiationItemStackBuilder extends CapabilityBuilderForge { 64 | 65 | private ToDoubleFunction getRadiationShielding; 66 | 67 | public RadiationItemStackBuilder getRadiationShielding(ToDoubleFunction getRadiationShielding) { 68 | this.getRadiationShielding = getRadiationShielding; 69 | return this; 70 | } 71 | 72 | @Override 73 | public IRadiationShielding getCapability(ItemStack instance) { 74 | return () -> getRadiationShielding == null ? 0 : getRadiationShielding.applyAsDouble(instance); 75 | } 76 | 77 | @Override 78 | public Capability getCapabilityKey() { 79 | return Capabilities.RADIATION_SHIELDING; 80 | } 81 | 82 | @Override 83 | public ResourceLocation getResourceLocation() { 84 | return new ResourceLocation("powerful:radiation_protection_item"); 85 | } 86 | } 87 | 88 | } 89 | -------------------------------------------------------------------------------- /forge/src/main/java/com/prunoideae/powerfuljs/capabilities/forge/mods/mekanism/MekanismHelper.java: -------------------------------------------------------------------------------- 1 | package com.prunoideae.powerfuljs.capabilities.forge.mods.mekanism; 2 | 3 | import mekanism.api.chemical.gas.Gas; 4 | import mekanism.api.chemical.gas.GasStack; 5 | import mekanism.api.chemical.infuse.InfuseType; 6 | import mekanism.api.chemical.infuse.InfusionStack; 7 | import mekanism.api.chemical.pigment.Pigment; 8 | import mekanism.api.chemical.pigment.PigmentStack; 9 | import mekanism.api.chemical.slurry.Slurry; 10 | import mekanism.api.chemical.slurry.SlurryStack; 11 | 12 | public class MekanismHelper { 13 | //TODO: add type wrappers, but I don't wanna 14 | public static GasStack asGasStack(Gas gas, long amount) { 15 | return new GasStack(gas, amount); 16 | } 17 | 18 | public static InfusionStack asInfusionStack(InfuseType infuseType, long amount) { 19 | return new InfusionStack(infuseType, amount); 20 | } 21 | 22 | public static PigmentStack asPigmentStack(Pigment pigment, long amount) { 23 | return new PigmentStack(pigment, amount); 24 | } 25 | 26 | public static SlurryStack asSlurryStack(Slurry slurry, long amount) { 27 | return new SlurryStack(slurry, amount); 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /forge/src/main/java/com/prunoideae/powerfuljs/capabilities/forge/mods/mekanism/chemical/CapabilityChemical.java: -------------------------------------------------------------------------------- 1 | package com.prunoideae.powerfuljs.capabilities.forge.mods.mekanism.chemical; 2 | 3 | import com.prunoideae.powerfuljs.capabilities.forge.CapabilityBuilderForge; 4 | import mekanism.api.chemical.Chemical; 5 | import mekanism.api.chemical.ChemicalStack; 6 | import mekanism.api.chemical.IChemicalHandler; 7 | import net.minecraftforge.common.capabilities.CapabilityProvider; 8 | import net.minecraftforge.common.util.TriPredicate; 9 | 10 | import java.util.function.BiFunction; 11 | import java.util.function.ToIntFunction; 12 | 13 | /** 14 | * 人活着哪有不疯的?硬撑罢了! 15 | * 人活着哪有不疯的?硬撑罢了! 16 | * 人活着哪有不疯的?硬撑罢了! 17 | * 人活着哪有不疯的?硬撑罢了! 18 | * 妈的,忍不了,一拳把地球打爆!妈的,忍不了,一拳把地球打爆!妈的,忍不了,一拳把地球打爆!妈的,忍不了,一拳把地球打爆!妈的,忍不了,一 19 | * 拳把地球打爆!妈的,忍不了,一拳把地球打爆!妈的,忍不了,一拳把地球打爆!妈的,忍不了,一拳把地球打爆!妈的,忍不了,一拳把地球打爆!妈 20 | * 的,忍不了,一拳把地球打爆!妈的,忍不了,一拳把地球打爆!妈的,忍不了,一拳把地球打爆!妈的,忍不了,一拳把地球打爆!妈的,忍不了,一拳 21 | * 把地球打爆!妈的,忍不了,一拳把地球打爆!妈的,忍不了,一拳把地球打爆!妈的,忍不了,一拳把地球打爆!妈的,忍不了,一拳把地球打爆!他奶 22 | * 奶的鸡蛋六舅的哈密瓜妹妹的大窝瓜爷爷的大鸡腿婶婶的大葡萄妈妈的黄瓜菜爸爸的大面包三舅姥爷的大李子二婶的桃子三叔的西瓜七舅姥爷的小荔枝二舅 23 | * 姥爷的火龙果姑姑的猕猴桃祖爷爷的车厘子祖姥爷的大菠萝祖奶奶的大榴莲二爷的小草莓他三婶姥姥的大白菜他哥哥的大面条妹妹的小油菜弟弟的西葫芦姐 24 | * 姐的大土豆姐夫的大青椒爷爷的大茄子嗯啊,杀杀杀!!好可怕杀杀杀杀杀杀上勾拳!下勾拳!左勾拳!右勾拳!扫堂腿!回旋踢!这是蜘蛛吃耳屎,这是 25 | * 龙卷风摧毁停车场!这是羚羊蹬,这是山羊跳!乌鸦坐飞机!老鼠走迷宫!大象踢腿!愤怒的章鱼!巨斧砍大树!彻底疯狂!彻底疯狂!彻底疯狂!彻底疯 26 | * 狂!彻底疯狂!彻底疯狂!彻底疯狂!彻底疯狂!彻底疯狂!杀!杀!杀!杀!杀!杀!杀!杀!杀!杀!杀!杀!杀!杀!杀!杀!杀!杀!杀!杀!杀 27 | * !杀!彻底疯狂!彻底疯狂!彻底疯狂!彻底疯狂!彻底疯狂!彻底疯狂!彻底疯狂!彻底疯狂!彻底疯狂!彻底疯狂! 28 | */ 29 | @SuppressWarnings("ALL") 30 | public class CapabilityChemical { 31 | 32 | @FunctionalInterface 33 | public interface SetChemicalInTank, S extends ChemicalStack> { 34 | void accept(I instance, int slot, S stack); 35 | } 36 | 37 | @FunctionalInterface 38 | public interface InsertChemical, S extends ChemicalStack> { 39 | S apply(I instance, int slot, S stack, boolean simulate); 40 | } 41 | 42 | @FunctionalInterface 43 | public interface ExtractChemical, S extends ChemicalStack> { 44 | S apply(I instance, int slot, long amount, boolean simulate); 45 | } 46 | 47 | 48 | public static abstract class ChemicalBuilder< 49 | I extends CapabilityProvider, //Instance 50 | H extends IChemicalHandler, //Handler 51 | C extends Chemical, //Chemical 52 | S extends ChemicalStack //Chemical Stack 53 | > extends CapabilityBuilderForge { 54 | 55 | protected ToIntFunction getTanks; 56 | protected BiFunction getChemicalInTank; 57 | protected SetChemicalInTank setChemicalInTank; 58 | protected BiFunction getTankCapacity; 59 | protected TriPredicate isValid; 60 | protected InsertChemical insertChemical; 61 | protected ExtractChemical extractChemical; 62 | 63 | public ChemicalBuilder getTanks(ToIntFunction getTanks) { 64 | this.getTanks = getTanks; 65 | return this; 66 | } 67 | 68 | public ChemicalBuilder getChemicalInTank(BiFunction getChemicalInTank) { 69 | this.getChemicalInTank = getChemicalInTank; 70 | return this; 71 | } 72 | 73 | public ChemicalBuilder setChemicalInTank(SetChemicalInTank setChemicalInTank) { 74 | this.setChemicalInTank = setChemicalInTank; 75 | return this; 76 | } 77 | 78 | public ChemicalBuilder getTankCapacity(BiFunction getTankCapacity) { 79 | this.getTankCapacity = getTankCapacity; 80 | return this; 81 | } 82 | 83 | public ChemicalBuilder isValid(TriPredicate isValid) { 84 | this.isValid = isValid; 85 | return this; 86 | } 87 | 88 | public ChemicalBuilder insertChemical(InsertChemical insertChemical) { 89 | this.insertChemical = insertChemical; 90 | return this; 91 | } 92 | 93 | public ChemicalBuilder extractChemical(ExtractChemical extractChemical) { 94 | this.extractChemical = extractChemical; 95 | return this; 96 | } 97 | } 98 | } 99 | -------------------------------------------------------------------------------- /forge/src/main/java/com/prunoideae/powerfuljs/capabilities/forge/mods/mekanism/chemical/CapabilityGas.java: -------------------------------------------------------------------------------- 1 | package com.prunoideae.powerfuljs.capabilities.forge.mods.mekanism.chemical; 2 | 3 | import dev.latvian.mods.rhino.util.HideFromJS; 4 | import mekanism.api.Action; 5 | import mekanism.api.chemical.gas.Gas; 6 | import mekanism.api.chemical.gas.GasStack; 7 | import mekanism.api.chemical.gas.IGasHandler; 8 | import mekanism.common.capabilities.Capabilities; 9 | import net.minecraft.resources.ResourceLocation; 10 | import net.minecraft.world.item.ItemStack; 11 | import net.minecraft.world.level.block.entity.BlockEntity; 12 | import net.minecraftforge.common.capabilities.Capability; 13 | import net.minecraftforge.common.capabilities.CapabilityProvider; 14 | import org.jetbrains.annotations.NotNull; 15 | 16 | public class CapabilityGas { 17 | public ItemStackBuilder itemStack() { 18 | return new ItemStackBuilder(); 19 | } 20 | 21 | public BlockEntityBuilder blockEntity() { 22 | return new BlockEntityBuilder(); 23 | } 24 | 25 | public static abstract class GasBuilder> extends CapabilityChemical.ChemicalBuilder { 26 | @Override 27 | @HideFromJS 28 | public Capability getCapabilityKey() { 29 | return Capabilities.GAS_HANDLER; 30 | } 31 | 32 | @Override 33 | @HideFromJS 34 | public IGasHandler getCapability(I instance) { 35 | return new IGasHandler() { 36 | @Override 37 | public int getTanks() { 38 | return getTanks == null ? 1 : getTanks.applyAsInt(instance); 39 | } 40 | 41 | @Override 42 | public @NotNull GasStack getChemicalInTank(int i) { 43 | return getChemicalInTank == null ? GasStack.EMPTY : getChemicalInTank.apply(instance, i); 44 | } 45 | 46 | @Override 47 | public void setChemicalInTank(int i, @NotNull GasStack stack) { 48 | if (setChemicalInTank != null) 49 | setChemicalInTank.accept(instance, i, stack); 50 | } 51 | 52 | @Override 53 | public long getTankCapacity(int i) { 54 | return getTankCapacity == null ? 0 : getTankCapacity.apply(instance, i); 55 | } 56 | 57 | @Override 58 | public boolean isValid(int i, @NotNull GasStack stack) { 59 | return isValid == null || isValid.test(instance, i, stack); 60 | } 61 | 62 | @Override 63 | public @NotNull GasStack insertChemical(int i, @NotNull GasStack stack, @NotNull Action action) { 64 | return insertChemical == null ? stack : insertChemical.apply(instance, i, stack, action.simulate()); 65 | } 66 | 67 | @Override 68 | public @NotNull GasStack extractChemical(int i, long l, @NotNull Action action) { 69 | return extractChemical == null ? GasStack.EMPTY : extractChemical.apply(instance, i, l, action.simulate()); 70 | } 71 | }; 72 | } 73 | } 74 | 75 | public static class ItemStackBuilder extends GasBuilder { 76 | @Override 77 | @HideFromJS 78 | public ResourceLocation getResourceLocation() { 79 | return new ResourceLocation("powerful:gas_item_custom"); 80 | } 81 | } 82 | 83 | public static class BlockEntityBuilder extends GasBuilder { 84 | @Override 85 | @HideFromJS 86 | public ResourceLocation getResourceLocation() { 87 | return new ResourceLocation("powerful:gas_be_custom"); 88 | } 89 | } 90 | } 91 | -------------------------------------------------------------------------------- /forge/src/main/java/com/prunoideae/powerfuljs/capabilities/forge/mods/mekanism/chemical/CapabilityInfusion.java: -------------------------------------------------------------------------------- 1 | package com.prunoideae.powerfuljs.capabilities.forge.mods.mekanism.chemical; 2 | 3 | import mekanism.api.Action; 4 | import mekanism.api.chemical.infuse.IInfusionHandler; 5 | import mekanism.api.chemical.infuse.InfuseType; 6 | import mekanism.api.chemical.infuse.InfusionStack; 7 | import mekanism.common.capabilities.Capabilities; 8 | import net.minecraft.resources.ResourceLocation; 9 | import net.minecraft.world.item.ItemStack; 10 | import net.minecraft.world.level.block.entity.BlockEntity; 11 | import net.minecraftforge.common.capabilities.Capability; 12 | import net.minecraftforge.common.capabilities.CapabilityProvider; 13 | import org.jetbrains.annotations.NotNull; 14 | 15 | public class CapabilityInfusion { 16 | public ItemStackBuilder itemStack() { 17 | return new ItemStackBuilder(); 18 | } 19 | 20 | public BlockEntityBuilder blockEntity() { 21 | return new BlockEntityBuilder(); 22 | } 23 | 24 | public static abstract class InfusionBuilder> extends CapabilityChemical.ChemicalBuilder { 25 | @Override 26 | public Capability getCapabilityKey() { 27 | return Capabilities.INFUSION_HANDLER; 28 | } 29 | 30 | @Override 31 | public IInfusionHandler getCapability(I instance) { 32 | return new IInfusionHandler() { 33 | @Override 34 | public int getTanks() { 35 | return getTanks == null ? 1 : getTanks.applyAsInt(instance); 36 | } 37 | 38 | @Override 39 | public @NotNull InfusionStack getChemicalInTank(int i) { 40 | return getChemicalInTank == null ? InfusionStack.EMPTY : getChemicalInTank.apply(instance, i); 41 | } 42 | 43 | @Override 44 | public void setChemicalInTank(int i, @NotNull InfusionStack stack) { 45 | if (setChemicalInTank != null) 46 | setChemicalInTank.accept(instance, i, stack); 47 | } 48 | 49 | @Override 50 | public long getTankCapacity(int i) { 51 | return getTankCapacity == null ? 0 : getTankCapacity.apply(instance, i); 52 | } 53 | 54 | @Override 55 | public boolean isValid(int i, @NotNull InfusionStack stack) { 56 | return isValid == null || isValid.test(instance, i, stack); 57 | } 58 | 59 | @Override 60 | public @NotNull InfusionStack insertChemical(int i, @NotNull InfusionStack stack, @NotNull Action action) { 61 | return insertChemical == null ? stack : insertChemical.apply(instance, i, stack, action.simulate()); 62 | } 63 | 64 | @Override 65 | public @NotNull InfusionStack extractChemical(int i, long l, @NotNull Action action) { 66 | return extractChemical == null ? InfusionStack.EMPTY : extractChemical.apply(instance, i, l, action.simulate()); 67 | } 68 | }; 69 | } 70 | } 71 | 72 | public static class ItemStackBuilder extends InfusionBuilder { 73 | @Override 74 | public ResourceLocation getResourceLocation() { 75 | return new ResourceLocation("powerful:infusion_item_custom"); 76 | } 77 | } 78 | 79 | public static class BlockEntityBuilder extends InfusionBuilder { 80 | 81 | @Override 82 | public ResourceLocation getResourceLocation() { 83 | return new ResourceLocation("powerful:infusion_be_custom"); 84 | } 85 | } 86 | } 87 | -------------------------------------------------------------------------------- /forge/src/main/java/com/prunoideae/powerfuljs/capabilities/forge/mods/mekanism/chemical/CapabilityPigment.java: -------------------------------------------------------------------------------- 1 | package com.prunoideae.powerfuljs.capabilities.forge.mods.mekanism.chemical; 2 | 3 | import mekanism.api.Action; 4 | import mekanism.api.chemical.pigment.IPigmentHandler; 5 | import mekanism.api.chemical.pigment.Pigment; 6 | import mekanism.api.chemical.pigment.PigmentStack; 7 | import mekanism.common.capabilities.Capabilities; 8 | import net.minecraft.resources.ResourceLocation; 9 | import net.minecraft.world.item.ItemStack; 10 | import net.minecraft.world.level.block.entity.BlockEntity; 11 | import net.minecraftforge.common.capabilities.Capability; 12 | import net.minecraftforge.common.capabilities.CapabilityProvider; 13 | import org.jetbrains.annotations.NotNull; 14 | 15 | public class CapabilityPigment { 16 | public ItemStackBuilder itemStack() { 17 | return new ItemStackBuilder(); 18 | } 19 | 20 | public BlockEntityBuilder blockEntity() { 21 | return new BlockEntityBuilder(); 22 | } 23 | 24 | public static abstract class PigmentBuilder> extends CapabilityChemical.ChemicalBuilder { 25 | @Override 26 | public Capability getCapabilityKey() { 27 | return Capabilities.PIGMENT_HANDLER; 28 | } 29 | 30 | @Override 31 | public IPigmentHandler getCapability(I instance) { 32 | return new IPigmentHandler() { 33 | @Override 34 | public int getTanks() { 35 | return getTanks == null ? 1 : getTanks.applyAsInt(instance); 36 | } 37 | 38 | @Override 39 | public @NotNull PigmentStack getChemicalInTank(int i) { 40 | return getChemicalInTank == null ? PigmentStack.EMPTY : getChemicalInTank.apply(instance, i); 41 | } 42 | 43 | @Override 44 | public void setChemicalInTank(int i, @NotNull PigmentStack stack) { 45 | if (setChemicalInTank != null) 46 | setChemicalInTank.accept(instance, i, stack); 47 | } 48 | 49 | @Override 50 | public long getTankCapacity(int i) { 51 | return getTankCapacity == null ? 0 : getTankCapacity.apply(instance, i); 52 | } 53 | 54 | @Override 55 | public boolean isValid(int i, @NotNull PigmentStack stack) { 56 | return isValid == null || isValid.test(instance, i, stack); 57 | } 58 | 59 | @Override 60 | public @NotNull PigmentStack insertChemical(int i, @NotNull PigmentStack stack, @NotNull Action action) { 61 | return insertChemical == null ? stack : insertChemical.apply(instance, i, stack, action.simulate()); 62 | } 63 | 64 | @Override 65 | public @NotNull PigmentStack extractChemical(int i, long l, @NotNull Action action) { 66 | return extractChemical == null ? PigmentStack.EMPTY : extractChemical.apply(instance, i, l, action.simulate()); 67 | } 68 | }; 69 | } 70 | } 71 | 72 | public static class ItemStackBuilder extends PigmentBuilder { 73 | @Override 74 | public ResourceLocation getResourceLocation() { 75 | return new ResourceLocation("powerful:pigment_item_custom"); 76 | } 77 | } 78 | 79 | public static class BlockEntityBuilder extends PigmentBuilder { 80 | @Override 81 | public ResourceLocation getResourceLocation() { 82 | return new ResourceLocation("powerful:pigment_be_custom"); 83 | } 84 | } 85 | } 86 | -------------------------------------------------------------------------------- /forge/src/main/java/com/prunoideae/powerfuljs/capabilities/forge/mods/mekanism/chemical/CapabilitySlurry.java: -------------------------------------------------------------------------------- 1 | package com.prunoideae.powerfuljs.capabilities.forge.mods.mekanism.chemical; 2 | 3 | import mekanism.api.Action; 4 | import mekanism.api.chemical.slurry.ISlurryHandler; 5 | import mekanism.api.chemical.slurry.Slurry; 6 | import mekanism.api.chemical.slurry.SlurryStack; 7 | import mekanism.common.capabilities.Capabilities; 8 | import net.minecraft.resources.ResourceLocation; 9 | import net.minecraft.world.item.ItemStack; 10 | import net.minecraft.world.level.block.entity.BlockEntity; 11 | import net.minecraftforge.common.capabilities.Capability; 12 | import net.minecraftforge.common.capabilities.CapabilityProvider; 13 | import org.jetbrains.annotations.NotNull; 14 | 15 | public class CapabilitySlurry { 16 | 17 | public ItemStackBuilder itemStack() { 18 | return new ItemStackBuilder(); 19 | } 20 | 21 | public BlockEntityBuilder blockEntity() { 22 | return new BlockEntityBuilder(); 23 | } 24 | 25 | public static abstract class SlurryBuilder> extends CapabilityChemical.ChemicalBuilder { 26 | @Override 27 | public Capability getCapabilityKey() { 28 | return Capabilities.SLURRY_HANDLER; 29 | } 30 | 31 | @Override 32 | public ISlurryHandler getCapability(I instance) { 33 | return new ISlurryHandler() { 34 | @Override 35 | public int getTanks() { 36 | return getTanks == null ? 1 : getTanks.applyAsInt(instance); 37 | } 38 | 39 | @Override 40 | public @NotNull SlurryStack getChemicalInTank(int i) { 41 | return getChemicalInTank == null ? SlurryStack.EMPTY : getChemicalInTank.apply(instance, i); 42 | } 43 | 44 | @Override 45 | public void setChemicalInTank(int i, @NotNull SlurryStack stack) { 46 | if (setChemicalInTank != null) 47 | setChemicalInTank.accept(instance, i, stack); 48 | } 49 | 50 | @Override 51 | public long getTankCapacity(int i) { 52 | return getTankCapacity == null ? 0 : getTankCapacity.apply(instance, i); 53 | } 54 | 55 | @Override 56 | public boolean isValid(int i, @NotNull SlurryStack stack) { 57 | return isValid == null || isValid.test(instance, i, stack); 58 | } 59 | 60 | @Override 61 | public @NotNull SlurryStack insertChemical(int i, @NotNull SlurryStack stack, @NotNull Action action) { 62 | return insertChemical == null ? stack : insertChemical.apply(instance, i, stack, action.simulate()); 63 | } 64 | 65 | @Override 66 | public @NotNull SlurryStack extractChemical(int i, long l, @NotNull Action action) { 67 | return extractChemical == null ? SlurryStack.EMPTY : extractChemical.apply(instance, i, l, action.simulate()); 68 | } 69 | }; 70 | } 71 | } 72 | 73 | public static class ItemStackBuilder extends SlurryBuilder { 74 | 75 | @Override 76 | public ResourceLocation getResourceLocation() { 77 | return new ResourceLocation("powerful:slurry_item_custom"); 78 | } 79 | } 80 | 81 | public static class BlockEntityBuilder extends SlurryBuilder { 82 | 83 | @Override 84 | public ResourceLocation getResourceLocation() { 85 | return new ResourceLocation("powerful:slurry_be_custom"); 86 | } 87 | } 88 | } 89 | -------------------------------------------------------------------------------- /forge/src/main/java/com/prunoideae/powerfuljs/capabilities/forge/mods/pnc/CapabilitiesPneumatic.java: -------------------------------------------------------------------------------- 1 | package com.prunoideae.powerfuljs.capabilities.forge.mods.pnc; 2 | 3 | public interface CapabilitiesPneumatic { 4 | CapabilityAir AIR = new CapabilityAir(); 5 | } 6 | -------------------------------------------------------------------------------- /forge/src/main/java/com/prunoideae/powerfuljs/capabilities/forge/mods/pnc/CapabilityAir.java: -------------------------------------------------------------------------------- 1 | package com.prunoideae.powerfuljs.capabilities.forge.mods.pnc; 2 | 3 | import com.prunoideae.powerfuljs.capabilities.forge.CapabilityBuilderForge; 4 | import me.desht.pneumaticcraft.api.PNCCapabilities; 5 | import me.desht.pneumaticcraft.api.tileentity.IAirHandlerItem; 6 | import net.minecraft.resources.ResourceLocation; 7 | import net.minecraft.world.item.ItemStack; 8 | import net.minecraftforge.common.capabilities.Capability; 9 | import org.jetbrains.annotations.NotNull; 10 | 11 | import java.util.function.BiConsumer; 12 | import java.util.function.Function; 13 | import java.util.function.ToIntFunction; 14 | 15 | public class CapabilityAir { 16 | public static final String AIR_TAG = "pnc:air"; 17 | 18 | public ItemStackBuilder itemStack(int capacity, float maxPressure) { 19 | return new ItemStackBuilder(capacity, maxPressure); 20 | } 21 | 22 | public ItemStackBuilderCustom itemStackCustom() { 23 | return new ItemStackBuilderCustom(); 24 | } 25 | 26 | public static class ItemStackBuilder extends CapabilityBuilderForge { 27 | private final int capacity; 28 | private final float maxPressure; 29 | 30 | public ItemStackBuilder(int capacity, float maxPressure) { 31 | this.capacity = capacity; 32 | this.maxPressure = maxPressure; 33 | } 34 | 35 | @Override 36 | public IAirHandlerItem getCapability(ItemStack instance) { 37 | return new IAirHandlerItem() { 38 | @NotNull 39 | @Override 40 | public ItemStack getContainer() { 41 | return instance; 42 | } 43 | 44 | @Override 45 | public float getPressure() { 46 | return (float) getVolume() / getAir(); 47 | } 48 | 49 | @Override 50 | public int getAir() { 51 | return instance.getOrCreateTag().getInt(AIR_TAG); 52 | } 53 | 54 | @Override 55 | public void addAir(int amount) { 56 | instance.getOrCreateTag().putInt(AIR_TAG, getAir() + amount); 57 | } 58 | 59 | @Override 60 | public int getBaseVolume() { 61 | return capacity; 62 | } 63 | 64 | @Override 65 | public void setBaseVolume(int newBaseVolume) { 66 | 67 | } 68 | 69 | @Override 70 | public int getVolume() { 71 | return capacity; 72 | } 73 | 74 | @Override 75 | public float maxPressure() { 76 | return maxPressure; 77 | } 78 | }; 79 | } 80 | 81 | @Override 82 | public Capability getCapabilityKey() { 83 | return PNCCapabilities.AIR_HANDLER_ITEM_CAPABILITY; 84 | } 85 | 86 | @Override 87 | public ResourceLocation getResourceLocation() { 88 | return new ResourceLocation("powerful:air_pnc"); 89 | } 90 | } 91 | 92 | public static class ItemStackBuilderCustom extends CapabilityBuilderForge { 93 | 94 | private Function getPressure; 95 | private ToIntFunction getAir; 96 | private BiConsumer addAir; 97 | private ToIntFunction getBaseVolume; 98 | private BiConsumer setBaseVolume; 99 | private ToIntFunction getVolume; 100 | private Function maxPressure; 101 | 102 | public ItemStackBuilderCustom getPressure(Function getPressure) { 103 | this.getPressure = getPressure; 104 | return this; 105 | } 106 | 107 | public ItemStackBuilderCustom getAir(ToIntFunction getAir) { 108 | this.getAir = getAir; 109 | return this; 110 | } 111 | 112 | public ItemStackBuilderCustom addAir(BiConsumer addAir) { 113 | this.addAir = addAir; 114 | return this; 115 | } 116 | 117 | public ItemStackBuilderCustom getBaseVolume(ToIntFunction getBaseVolume) { 118 | this.getBaseVolume = getBaseVolume; 119 | return this; 120 | } 121 | 122 | public ItemStackBuilderCustom setBaseVolume(BiConsumer setBaseVolume) { 123 | this.setBaseVolume = setBaseVolume; 124 | return this; 125 | } 126 | 127 | public ItemStackBuilderCustom getVolume(ToIntFunction getVolume) { 128 | this.getVolume = getVolume; 129 | return this; 130 | } 131 | 132 | public ItemStackBuilderCustom maxPressure(Function maxPressure) { 133 | this.maxPressure = maxPressure; 134 | return this; 135 | } 136 | 137 | @Override 138 | public IAirHandlerItem getCapability(ItemStack instance) { 139 | return new IAirHandlerItem() { 140 | @NotNull 141 | @Override 142 | public ItemStack getContainer() { 143 | return instance; 144 | } 145 | 146 | @Override 147 | public float getPressure() { 148 | return getPressure == null ? 0 : getPressure.apply(instance); 149 | } 150 | 151 | @Override 152 | public int getAir() { 153 | return getAir == null ? 0 : getAir.applyAsInt(instance); 154 | } 155 | 156 | @Override 157 | public void addAir(int amount) { 158 | if (addAir != null) 159 | addAir.accept(instance, amount); 160 | } 161 | 162 | @Override 163 | public int getBaseVolume() { 164 | return getBaseVolume == null ? 1 : getBaseVolume.applyAsInt(instance); 165 | } 166 | 167 | @Override 168 | public void setBaseVolume(int newBaseVolume) { 169 | if (setBaseVolume != null) 170 | setBaseVolume.accept(instance, newBaseVolume); 171 | } 172 | 173 | @Override 174 | public int getVolume() { 175 | return getVolume == null ? 1 : getVolume.applyAsInt(instance); 176 | } 177 | 178 | @Override 179 | public float maxPressure() { 180 | return maxPressure == null ? 1 : maxPressure.apply(instance); 181 | } 182 | }; 183 | } 184 | 185 | @Override 186 | public Capability getCapabilityKey() { 187 | return PNCCapabilities.AIR_HANDLER_ITEM_CAPABILITY; 188 | } 189 | 190 | @Override 191 | public ResourceLocation getResourceLocation() { 192 | return new ResourceLocation("powerful:air_pnc_item_custom"); 193 | } 194 | } 195 | } 196 | -------------------------------------------------------------------------------- /forge/src/main/java/com/prunoideae/powerfuljs/events/forge/DynamicAttachEventJS.java: -------------------------------------------------------------------------------- 1 | package com.prunoideae.powerfuljs.events.forge; 2 | 3 | import com.mojang.datafixers.util.Pair; 4 | import com.prunoideae.powerfuljs.capabilities.forge.CapabilityBuilderForge; 5 | import dev.latvian.mods.kubejs.event.EventJS; 6 | import dev.latvian.mods.rhino.util.HideFromJS; 7 | import net.minecraftforge.common.capabilities.CapabilityProvider; 8 | 9 | import java.util.ArrayList; 10 | import java.util.List; 11 | import java.util.function.Predicate; 12 | 13 | @SuppressWarnings("UnstableApiUsage") 14 | public abstract class DynamicAttachEventJS> extends EventJS { 15 | 16 | public abstract DynamicAttachEventJS add(Predicate predicate, CapabilityBuilderForge provider); 17 | } 18 | -------------------------------------------------------------------------------- /forge/src/main/java/com/prunoideae/powerfuljs/events/forge/DynamicBEEventJS.java: -------------------------------------------------------------------------------- 1 | package com.prunoideae.powerfuljs.events.forge; 2 | 3 | import com.prunoideae.powerfuljs.capabilities.forge.CapabilityBuilderForge; 4 | import com.prunoideae.powerfuljs.forge.CapabilityServiceForge; 5 | import net.minecraft.world.level.block.entity.BlockEntity; 6 | 7 | import java.util.function.Predicate; 8 | 9 | public class DynamicBEEventJS extends DynamicAttachEventJS { 10 | @Override 11 | public DynamicAttachEventJS add(Predicate predicate, CapabilityBuilderForge provider) { 12 | CapabilityServiceForge.INSTANCE.addBE(predicate, provider); 13 | return this; 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /forge/src/main/java/com/prunoideae/powerfuljs/events/forge/DynamicEntityEventJS.java: -------------------------------------------------------------------------------- 1 | package com.prunoideae.powerfuljs.events.forge; 2 | 3 | import com.prunoideae.powerfuljs.capabilities.forge.CapabilityBuilderForge; 4 | import com.prunoideae.powerfuljs.forge.CapabilityServiceForge; 5 | import net.minecraft.world.entity.Entity; 6 | 7 | import java.util.function.Predicate; 8 | 9 | public class DynamicEntityEventJS extends DynamicAttachEventJS { 10 | @Override 11 | public DynamicAttachEventJS add(Predicate predicate, CapabilityBuilderForge provider) { 12 | CapabilityServiceForge.INSTANCE.addEntity(predicate, provider); 13 | return this; 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /forge/src/main/java/com/prunoideae/powerfuljs/events/forge/DynamicItemStackEventJS.java: -------------------------------------------------------------------------------- 1 | package com.prunoideae.powerfuljs.events.forge; 2 | 3 | import com.prunoideae.powerfuljs.capabilities.forge.CapabilityBuilderForge; 4 | import com.prunoideae.powerfuljs.forge.CapabilityServiceForge; 5 | import net.minecraft.world.item.ItemStack; 6 | 7 | import java.util.function.Predicate; 8 | 9 | public class DynamicItemStackEventJS extends DynamicAttachEventJS { 10 | @Override 11 | public DynamicAttachEventJS add(Predicate predicate, CapabilityBuilderForge provider) { 12 | CapabilityServiceForge.INSTANCE.addItem(predicate, provider); 13 | return this; 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /forge/src/main/java/com/prunoideae/powerfuljs/forge/CapabilityServiceForge.java: -------------------------------------------------------------------------------- 1 | package com.prunoideae.powerfuljs.forge; 2 | 3 | import com.mojang.datafixers.util.Pair; 4 | import com.prunoideae.powerfuljs.capabilities.forge.CapabilityBuilderForge; 5 | import net.minecraft.world.entity.Entity; 6 | import net.minecraft.world.item.ItemStack; 7 | import net.minecraft.world.level.block.entity.BlockEntity; 8 | 9 | import java.util.ArrayList; 10 | import java.util.List; 11 | import java.util.function.Predicate; 12 | import java.util.stream.Stream; 13 | 14 | public class CapabilityServiceForge { 15 | public static final CapabilityServiceForge INSTANCE = new CapabilityServiceForge(); 16 | 17 | protected final List, CapabilityBuilderForge>> itemTester = new ArrayList<>(); 18 | protected final List, CapabilityBuilderForge>> beTester = new ArrayList<>(); 19 | protected final List, CapabilityBuilderForge>> entityTester = new ArrayList<>(); 20 | 21 | public Stream> getCapabilitiesFor(ItemStack stack) { 22 | return itemTester.stream().filter(pair -> pair.getFirst().test(stack)).map(Pair::getSecond); 23 | } 24 | 25 | public Stream> getCapabilitiesFor(BlockEntity be) { 26 | return beTester.stream().filter(pair -> pair.getFirst().test(be)).map(Pair::getSecond); 27 | } 28 | 29 | public Stream> getCapabilitiesFor(Entity entity) { 30 | return entityTester.stream().filter(pair -> pair.getFirst().test(entity)).map(Pair::getSecond); 31 | } 32 | 33 | public void addItem(Predicate predicate, CapabilityBuilderForge builder) { 34 | itemTester.add(new Pair<>(predicate, builder)); 35 | } 36 | 37 | public void addBE(Predicate predicate, CapabilityBuilderForge builder) { 38 | beTester.add(new Pair<>(predicate, builder)); 39 | } 40 | 41 | public void addEntity(Predicate predicate, CapabilityBuilderForge builder) { 42 | entityTester.add(new Pair<>(predicate, builder)); 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /forge/src/main/java/com/prunoideae/powerfuljs/forge/PowerfulJSEvents.java: -------------------------------------------------------------------------------- 1 | package com.prunoideae.powerfuljs.forge; 2 | 3 | import com.prunoideae.powerfuljs.CapabilityBuilder; 4 | import com.prunoideae.powerfuljs.CapabilityService; 5 | import com.prunoideae.powerfuljs.capabilities.forge.CapabilityProvider; 6 | import net.minecraft.world.entity.Entity; 7 | import net.minecraft.world.item.ItemStack; 8 | import net.minecraft.world.level.block.entity.BlockEntity; 9 | import net.minecraftforge.event.AttachCapabilitiesEvent; 10 | import net.minecraftforge.eventbus.api.SubscribeEvent; 11 | import net.minecraftforge.fml.common.Mod; 12 | 13 | @Mod.EventBusSubscriber 14 | public class PowerfulJSEvents { 15 | 16 | @SubscribeEvent 17 | public static void attachItemCapabilities(AttachCapabilitiesEvent event) { 18 | ItemStack object = event.getObject(); 19 | CapabilityService.INSTANCE.getCapabilitiesFor(object).ifPresent(builders -> { 20 | for (CapabilityBuilder builder : builders) { 21 | event.addCapability(builder.getResourceLocation(), CapabilityProvider.of(builder.getCapabilityKey(), builder.getCapability(object), side -> builder.getDirection().test(object, side))); 22 | } 23 | }); 24 | 25 | CapabilityServiceForge.INSTANCE.getCapabilitiesFor(object).forEach(builder -> { 26 | event.addCapability(builder.getResourceLocation(), CapabilityProvider.of(builder.getCapabilityKey(), builder.getCapability(object), side -> builder.getDirection().test(object, side))); 27 | }); 28 | } 29 | 30 | @SubscribeEvent 31 | public static void attachBECapabilities(AttachCapabilitiesEvent event) { 32 | BlockEntity object = event.getObject(); 33 | CapabilityService.INSTANCE.getCapabilitiesFor(object).ifPresent(builders -> { 34 | for (CapabilityBuilder builder : builders) { 35 | event.addCapability(builder.getResourceLocation(), CapabilityProvider.of(builder.getCapabilityKey(), builder.getCapability(object), side -> builder.getDirection().test(object, side))); 36 | } 37 | }); 38 | CapabilityServiceForge.INSTANCE.getCapabilitiesFor(object).forEach(builder -> { 39 | event.addCapability(builder.getResourceLocation(), CapabilityProvider.of(builder.getCapabilityKey(), builder.getCapability(object), side -> builder.getDirection().test(object, side))); 40 | }); 41 | } 42 | 43 | @SubscribeEvent 44 | public static void attachEntityCapabilities(AttachCapabilitiesEvent event) { 45 | Entity object = event.getObject(); 46 | CapabilityService.INSTANCE.getCapabilitiesFor(object).ifPresent(builders -> { 47 | for (CapabilityBuilder builder : builders) { 48 | event.addCapability(builder.getResourceLocation(), CapabilityProvider.of(builder.getCapabilityKey(), builder.getCapability(object), side -> builder.getDirection().test(object, side))); 49 | } 50 | }); 51 | CapabilityServiceForge.INSTANCE.getCapabilitiesFor(object).forEach(builder -> { 52 | event.addCapability(builder.getResourceLocation(), CapabilityProvider.of(builder.getCapabilityKey(), builder.getCapability(object), side -> builder.getDirection().test(object, side))); 53 | }); 54 | } 55 | 56 | } 57 | -------------------------------------------------------------------------------- /forge/src/main/java/com/prunoideae/powerfuljs/forge/PowerfulJSForge.java: -------------------------------------------------------------------------------- 1 | package com.prunoideae.powerfuljs.forge; 2 | 3 | import com.prunoideae.powerfuljs.PowerfulJS; 4 | import dev.architectury.platform.forge.EventBuses; 5 | import net.minecraftforge.fml.common.Mod; 6 | import net.minecraftforge.fml.javafmlmod.FMLJavaModLoadingContext; 7 | 8 | @Mod(PowerfulJS.MOD_ID) 9 | public class PowerfulJSForge { 10 | 11 | public PowerfulJSForge() { 12 | // Submit our event bus to let architectury register our content on the right time 13 | EventBuses.registerModEventBus(PowerfulJS.MOD_ID, FMLJavaModLoadingContext.get().getModEventBus()); 14 | PowerfulJS.init(); 15 | } 16 | } -------------------------------------------------------------------------------- /forge/src/main/java/com/prunoideae/powerfuljs/forge/PowerfulJSPluginForge.java: -------------------------------------------------------------------------------- 1 | package com.prunoideae.powerfuljs.forge; 2 | 3 | import com.prunoideae.powerfuljs.PowerfulJS; 4 | import com.prunoideae.powerfuljs.PowerfulJSPlugin; 5 | import com.prunoideae.powerfuljs.capabilities.forge.CapabilitiesForge; 6 | import com.prunoideae.powerfuljs.capabilities.forge.mods.botania.CapabilitiesBotania; 7 | import com.prunoideae.powerfuljs.capabilities.forge.mods.curios.CapabilitiesCurios; 8 | import com.prunoideae.powerfuljs.capabilities.forge.mods.curios.EventCurios; 9 | import com.prunoideae.powerfuljs.capabilities.forge.mods.curios.RegisterCuriosRendererEventJS; 10 | import com.prunoideae.powerfuljs.capabilities.forge.mods.immersive.CapabilitiesHelperIE; 11 | import com.prunoideae.powerfuljs.capabilities.forge.mods.immersive.CapabilitiesIE; 12 | import com.prunoideae.powerfuljs.capabilities.forge.mods.mekanism.CapabilitiesMekanism; 13 | import com.prunoideae.powerfuljs.capabilities.forge.mods.mekanism.MekanismHelper; 14 | import com.prunoideae.powerfuljs.capabilities.forge.mods.pnc.CapabilitiesPneumatic; 15 | import com.prunoideae.powerfuljs.events.forge.DynamicBEEventJS; 16 | import com.prunoideae.powerfuljs.events.forge.DynamicEntityEventJS; 17 | import com.prunoideae.powerfuljs.events.forge.DynamicItemStackEventJS; 18 | import dev.architectury.platform.Platform; 19 | import dev.latvian.mods.kubejs.event.EventHandler; 20 | import dev.latvian.mods.kubejs.script.BindingsEvent; 21 | import dev.latvian.mods.kubejs.script.ScriptType; 22 | import me.desht.pneumaticcraft.api.PNCCapabilities; 23 | import mekanism.common.capabilities.Capabilities; 24 | import net.minecraftforge.common.capabilities.ForgeCapabilities; 25 | import top.theillusivec4.curios.api.CuriosCapability; 26 | import top.theillusivec4.curios.api.client.ICurioRenderer; 27 | import vazkii.botania.api.BotaniaForgeCapabilities; 28 | 29 | public class PowerfulJSPluginForge extends PowerfulJSPlugin { 30 | 31 | public static final EventHandler DYNAMIC_ATTACH_ITEMSTACK_CAP = GROUP.startup("dynamicItem", () -> DynamicItemStackEventJS.class); 32 | public static final EventHandler DYNAMIC_ATTACH_ENTITY_CAP = GROUP.startup("dynamicEntity", () -> DynamicEntityEventJS.class); 33 | public static final EventHandler DYNAMIC_ATTACH_BLOCK_ENTITY_CAP = GROUP.startup("dynamicBE", () -> DynamicBEEventJS.class); 34 | 35 | @Override 36 | public void init() { 37 | } 38 | 39 | @Override 40 | public void registerBindings(BindingsEvent event) { 41 | event.add("CapabilityBuilder", CapabilitiesForge.class); 42 | event.add("ForgeCapabilities", ForgeCapabilities.class); 43 | if (Platform.isModLoaded("botania")) { 44 | event.add("BotaniaCapabilityBuilder", CapabilitiesBotania.class); 45 | event.add("BotaniaCapabilities", BotaniaForgeCapabilities.class); 46 | } 47 | 48 | if (Platform.isModLoaded("pneumaticcraft")) { 49 | event.add("PNCCapabilityBuilder", CapabilitiesPneumatic.class); 50 | event.add("PNCCapabilities", PNCCapabilities.class); 51 | } 52 | 53 | if (Platform.isModLoaded("mekanism")) { 54 | event.add("MekanismCapabilityBuilder", CapabilitiesMekanism.class); 55 | event.add("MekanismCapabilities", Capabilities.class); 56 | event.add("MekanismHelper", MekanismHelper.class); 57 | } 58 | if (Platform.isModLoaded("curios")) { 59 | event.add("CuriosCapabilities", CuriosCapability.class); 60 | event.add("CuriosCapabilityBuilder", CapabilitiesCurios.class); 61 | PowerfulJS.PROXY.get().runOnClient(() -> event.add("CuriosRenderer", ICurioRenderer.class)); 62 | } 63 | if (Platform.isModLoaded("immersiveengineering")) { 64 | event.add("IECapabilityBuilder", CapabilitiesIE.class); 65 | event.add("IECapabilities", CapabilitiesHelperIE.class); 66 | } 67 | } 68 | 69 | @Override 70 | public void registerEvents() { 71 | super.registerEvents(); 72 | if (Platform.isModLoaded("curios")) { 73 | EventCurios.GROUP.register(); 74 | } 75 | } 76 | 77 | @Override 78 | public void afterInit() { 79 | super.afterInit(); 80 | DYNAMIC_ATTACH_ITEMSTACK_CAP.post(ScriptType.STARTUP, new DynamicItemStackEventJS()); 81 | DYNAMIC_ATTACH_BLOCK_ENTITY_CAP.post(ScriptType.STARTUP, new DynamicBEEventJS()); 82 | DYNAMIC_ATTACH_ENTITY_CAP.post(ScriptType.STARTUP, new DynamicEntityEventJS()); 83 | 84 | if (Platform.isModLoaded("curios")) { 85 | PowerfulJS.PROXY.get().runOnClient(() -> EventCurios.REGISTER_RENDERER.post(ScriptType.STARTUP, new RegisterCuriosRendererEventJS())); 86 | } 87 | } 88 | } 89 | -------------------------------------------------------------------------------- /forge/src/main/resources/META-INF/accesstransformer.cfg: -------------------------------------------------------------------------------- 1 | public net.minecraftforge.eventbus.EventBus addListener(Lnet/minecraftforge/eventbus/api/EventPriority;Ljava/util/function/Predicate;Ljava/util/function/Consumer;)V -------------------------------------------------------------------------------- /forge/src/main/resources/META-INF/mods.toml: -------------------------------------------------------------------------------- 1 | # This is an example mods.toml file. It contains the data relating to the loading mods. 2 | # There are several mandatory fields (#mandatory), and many more that are optional (#optional). 3 | # The overall format is standard TOML format, v0.5.0. 4 | # Note that there are a couple of TOML lists in this file. 5 | # Find more information on toml format here: https://github.com/toml-lang/toml 6 | # The name of the mod loader type to load - for regular FML @Mod mods it should be javafml 7 | modLoader = "javafml" #mandatory 8 | # A version range to match for said mod loader - for regular FML @Mod it will be the forge version 9 | loaderVersion = "[43,)" #mandatory This is typically bumped every Minecraft version by Forge. See our download page for lists of versions. 10 | # The license for you mod. This is mandatory metadata and allows for easier comprehension of your redistributive properties. 11 | # Review your options at https://choosealicense.com/. All rights reserved is the default copyright stance, and is thus the default here. 12 | license = "GNU LGPL 3.0" 13 | # A URL to refer people to when problems occur with this mod 14 | issueTrackerURL="http://my.issue.tracker/" #optional 15 | # A list of mods - how many allowed here is determined by the individual mod loader 16 | [[mods]] #mandatory 17 | # The modid of the mod 18 | modId = "powerfuljs" #mandatory 19 | # The version number of the mod - there's a few well known ${} variables useable here or just hardcode it 20 | # ${version} will substitute the value of the Implementation-Version as read from the mod's JAR file metadata 21 | # see the associated build.gradle script for how to populate this completely automatically during a build 22 | version = "${version}" #mandatory 23 | # A display name for the mod 24 | displayName = "PowerfulJS" #mandatory 25 | # A URL to query for updates for this mod. See the JSON update specification 26 | #updateJSONURL="http://myurl.me/" #optional 27 | # A URL for the "homepage" for this mod, displayed in the mod UI 28 | #displayURL="http://example.com/" #optional 29 | # A file name (in the root of the mod JAR) containing a logo for display 30 | logoFile = "icon.png" #optional 31 | # A text field displayed in the mod UI 32 | #credits="Thanks for this example mod goes to Java" #optional 33 | # A text field displayed in the mod UI 34 | authors = "Prunoideae" #optional 35 | # Display Test controls the display for your mod in the server connection screen 36 | # MATCH_VERSION means that your mod will cause a red X if the versions on client and server differ. This is the default behaviour and should be what you choose if you have server and client elements to your mod. 37 | # IGNORE_SERVER_VERSION means that your mod will not cause a red X if it's present on the server but not on the client. This is what you should use if you're a server only mod. 38 | # IGNORE_ALL_VERSION means that your mod will not cause a red X if it's present on the client or the server. This is a special case and should only be used if your mod has no server component. 39 | # NONE means that no display test is set on your mod. You need to do this yourself, see IExtensionPoint.DisplayTest for more information. You can define any scheme you wish with this value. 40 | # IMPORTANT NOTE: this is NOT an instruction as to which environments (CLIENT or DEDICATED SERVER) your mod loads on. Your mod should load (and maybe do nothing!) whereever it finds itself. 41 | #displayTest="MATCH_VERSION" # MATCH_VERSION is the default if nothing is specified (#optional) 42 | 43 | # The description text for the mod (multi line!) (#mandatory) 44 | description = ''' 45 | Adds Capability/ApiLookup support for KubeJS 46 | ''' 47 | # A dependency - use the . to indicate dependency for a specific modid. Dependencies are optional. 48 | [[dependencies.powerfuljs]] #optional 49 | # the modid of the dependency 50 | modId = "forge" #mandatory 51 | # Does this dependency have to exist - if not, ordering below must be specified 52 | mandatory = true #mandatory 53 | # The version range of the dependency 54 | versionRange = "[43,)" #mandatory 55 | # An ordering relationship for the dependency - BEFORE or AFTER required if the relationship is not mandatory 56 | ordering = "NONE" 57 | # Side this dependency is applied on - BOTH, CLIENT or SERVER 58 | side = "BOTH" 59 | # Here's another dependency 60 | [[dependencies.powerfuljs]] 61 | modId = "minecraft" 62 | mandatory = true 63 | # This version range declares a minimum of the current minecraft version up to but not including the next major version 64 | versionRange = "[1.19.2,1.20)" 65 | ordering = "NONE" 66 | side = "BOTH" 67 | [[dependencies.powerfuljs]] 68 | modId = "kubejs" 69 | mandatory = true 70 | versionRange = "[1902.6.1-build.277,)" 71 | ordering = "NONE" 72 | side = "BOTH" 73 | [[dependencies.powerfuljs]] 74 | modId = "create" 75 | mandatory = false 76 | versionRange = "*" 77 | ordering = "AFTER" 78 | side = "BOTH" -------------------------------------------------------------------------------- /forge/src/main/resources/icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Prunoideae/PowerfulJS/1ce050ea39fc22e1a498e804e33b98bceae96b74/forge/src/main/resources/icon.png -------------------------------------------------------------------------------- /forge/src/main/resources/kubejs.plugins.txt: -------------------------------------------------------------------------------- 1 | com.prunoideae.powerfuljs.forge.PowerfulJSPluginForge -------------------------------------------------------------------------------- /forge/src/main/resources/pack.mcmeta: -------------------------------------------------------------------------------- 1 | { 2 | "pack": { 3 | "description": "PowerfulJS resources", 4 | "pack_format": 9, 5 | "forge:resource_pack_format": 9, 6 | "forge:data_pack_format": 10 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /forge/src/main/resources/powerfuljs-forge.mixins.json: -------------------------------------------------------------------------------- 1 | { 2 | "required": true, 3 | "minVersion": "0.8", 4 | "package": "com.prunoideae.powerfuljs.forge.mixins", 5 | "compatibilityLevel": "JAVA_17", 6 | "mixins": [ 7 | ], 8 | "client": [ 9 | ], 10 | "injectors": { 11 | "defaultRequire": 1 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /gradle.properties: -------------------------------------------------------------------------------- 1 | org.gradle.jvmargs=-Xmx8G 2 | minecraft_version=1.19.2 3 | archives_base_name=powerfuljs 4 | mod_version=1.5.0 5 | maven_group=com.prunoideae.powerfuljs 6 | architectury_version=5.13.60 7 | fabric_loader_version=0.14.12 8 | fabric_api_version=0.72.0+1.19.2 9 | forge_version=1.19.2-43.2.21 10 | 11 | # Mod versions 12 | kubejs_version=1902.6.2-build.23 13 | rhino_version=1902.2.2-build.268 14 | botania_version=1.19.2-440 15 | pnc_version=4.2.0 16 | mekanism_version=10.3.2.469 17 | curios_version=5.1.4.1 18 | immersive_engineering_file=4370621 19 | create_version=0.5.1.c+ -------------------------------------------------------------------------------- /gradle/wrapper/gradle-wrapper.properties: -------------------------------------------------------------------------------- 1 | distributionUrl=https\://services.gradle.org/distributions/gradle-7.3.3-bin.zip 2 | -------------------------------------------------------------------------------- /settings.gradle: -------------------------------------------------------------------------------- 1 | pluginManagement { 2 | repositories { 3 | maven { url "https://maven.fabricmc.net/" } 4 | maven { url "https://maven.architectury.dev/" } 5 | maven { url "https://maven.minecraftforge.net/" } 6 | gradlePluginPortal() 7 | } 8 | } 9 | 10 | include("common") 11 | include("fabric") 12 | include("forge") --------------------------------------------------------------------------------