├── .gitignore ├── LICENSE ├── README.md ├── build.gradle ├── build.properties ├── gradle.properties ├── gradle └── wrapper │ ├── gradle-wrapper.jar │ └── gradle-wrapper.properties ├── gradlew ├── gradlew.bat ├── information ├── changelogs.txt ├── faq.txt └── old_changelogs.txt ├── levels-version-checker.json └── src └── main ├── java └── com │ └── thexfactor117 │ └── levels │ ├── Levels.java │ ├── client │ └── gui │ │ ├── GuiItemInformation.java │ │ └── selection │ │ ├── GuiArmorSelection.java │ │ ├── GuiBowSelection.java │ │ ├── GuiShieldSelection.java │ │ └── GuiWeaponSelection.java │ ├── config │ └── Config.java │ ├── events │ ├── EventAttack.java │ ├── EventCreateWeapon.java │ ├── EventInput.java │ ├── EventTooltip.java │ └── attributes │ │ ├── EventBarrage.java │ │ └── EventSoulBound.java │ ├── init │ └── ModEvents.java │ ├── leveling │ ├── Experience.java │ ├── Rarity.java │ └── attributes │ │ ├── ArmorAttribute.java │ │ ├── BowAttribute.java │ │ ├── ShieldAttribute.java │ │ └── WeaponAttribute.java │ ├── network │ ├── PacketAttributeSelection.java │ └── PacketMythicSound.java │ ├── proxies │ ├── ClientProxy.java │ └── CommonProxy.java │ └── util │ ├── CapabilityUtils.java │ ├── GuiHandler.java │ ├── NBTHelper.java │ ├── RandomCollection.java │ ├── Reference.java │ ├── SimpleCapabilityProvider.java │ └── WeaponHelper.java └── resources ├── assets └── levels │ ├── lang │ ├── da_DK.lang │ ├── de_DE.lang │ ├── en_US.lang │ └── ru_RU.lang │ └── logo │ └── logo.png └── mcmod.info /.gitignore: -------------------------------------------------------------------------------- 1 | /bin/ 2 | /.classpath 3 | /.gradle 4 | /.project 5 | /.settings 6 | /config 7 | /.DS_Store 8 | /eula.txt 9 | /logs 10 | /server.properties 11 | /Levels_Client.launch 12 | /Levels_Server.launch 13 | /.gitignore 14 | /run 15 | /saves 16 | /usercache.json 17 | /usernamecache.json 18 | /options.txt 19 | /crash-reports 20 | /build 21 | /build/classes 22 | /build/sources 23 | /build/tmp 24 | /build/resources 25 | /build/dependency-cache 26 | /build/retromapping 27 | /build/taskLogs 28 | /libs 29 | /Levels 2 experimental.launch 30 | /Levels 2 (1.11)_Server.launch 31 | /Levels 2 hotfix.launch 32 | /Levels 2 hotfix Server.launch -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | GNU GENERAL PUBLIC LICENSE 2 | Version 2, June 1991 3 | 4 | Copyright (C) 1989, 1991 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 | Preamble 10 | 11 | The licenses for most software are designed to take away your 12 | freedom to share and change it. By contrast, the GNU General Public 13 | License is intended to guarantee your freedom to share and change free 14 | software--to make sure the software is free for all its users. This 15 | General Public License applies to most of the Free Software 16 | Foundation's software and to any other program whose authors commit to 17 | using it. (Some other Free Software Foundation software is covered by 18 | the GNU Lesser General Public License instead.) You can apply it to 19 | your programs, too. 20 | 21 | When we speak of free software, we are referring to freedom, not 22 | price. Our General Public Licenses are designed to make sure that you 23 | have the freedom to distribute copies of free software (and charge for 24 | this service if you wish), that you receive source code or can get it 25 | if you want it, that you can change the software or use pieces of it 26 | in new free programs; and that you know you can do these things. 27 | 28 | To protect your rights, we need to make restrictions that forbid 29 | anyone to deny you these rights or to ask you to surrender the rights. 30 | These restrictions translate to certain responsibilities for you if you 31 | distribute copies of the software, or if you modify it. 32 | 33 | For example, if you distribute copies of such a program, whether 34 | gratis or for a fee, you must give the recipients all the rights that 35 | you have. You must make sure that they, too, receive or can get the 36 | source code. And you must show them these terms so they know their 37 | rights. 38 | 39 | We protect your rights with two steps: (1) copyright the software, and 40 | (2) offer you this license which gives you legal permission to copy, 41 | distribute and/or modify the software. 42 | 43 | Also, for each author's protection and ours, we want to make certain 44 | that everyone understands that there is no warranty for this free 45 | software. If the software is modified by someone else and passed on, we 46 | want its recipients to know that what they have is not the original, so 47 | that any problems introduced by others will not reflect on the original 48 | authors' reputations. 49 | 50 | Finally, any free program is threatened constantly by software 51 | patents. We wish to avoid the danger that redistributors of a free 52 | program will individually obtain patent licenses, in effect making the 53 | program proprietary. To prevent this, we have made it clear that any 54 | patent must be licensed for everyone's free use or not licensed at all. 55 | 56 | The precise terms and conditions for copying, distribution and 57 | modification follow. 58 | 59 | GNU GENERAL PUBLIC LICENSE 60 | TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION 61 | 62 | 0. This License applies to any program or other work which contains 63 | a notice placed by the copyright holder saying it may be distributed 64 | under the terms of this General Public License. The "Program", below, 65 | refers to any such program or work, and a "work based on the Program" 66 | means either the Program or any derivative work under copyright law: 67 | that is to say, a work containing the Program or a portion of it, 68 | either verbatim or with modifications and/or translated into another 69 | language. (Hereinafter, translation is included without limitation in 70 | the term "modification".) Each licensee is addressed as "you". 71 | 72 | Activities other than copying, distribution and modification are not 73 | covered by this License; they are outside its scope. The act of 74 | running the Program is not restricted, and the output from the Program 75 | is covered only if its contents constitute a work based on the 76 | Program (independent of having been made by running the Program). 77 | Whether that is true depends on what the Program does. 78 | 79 | 1. You may copy and distribute verbatim copies of the Program's 80 | source code as you receive it, in any medium, provided that you 81 | conspicuously and appropriately publish on each copy an appropriate 82 | copyright notice and disclaimer of warranty; keep intact all the 83 | notices that refer to this License and to the absence of any warranty; 84 | and give any other recipients of the Program a copy of this License 85 | along with the Program. 86 | 87 | You may charge a fee for the physical act of transferring a copy, and 88 | you may at your option offer warranty protection in exchange for a fee. 89 | 90 | 2. You may modify your copy or copies of the Program or any portion 91 | of it, thus forming a work based on the Program, and copy and 92 | distribute such modifications or work under the terms of Section 1 93 | above, provided that you also meet all of these conditions: 94 | 95 | a) You must cause the modified files to carry prominent notices 96 | stating that you changed the files and the date of any change. 97 | 98 | b) You must cause any work that you distribute or publish, that in 99 | whole or in part contains or is derived from the Program or any 100 | part thereof, to be licensed as a whole at no charge to all third 101 | parties under the terms of this License. 102 | 103 | c) If the modified program normally reads commands interactively 104 | when run, you must cause it, when started running for such 105 | interactive use in the most ordinary way, to print or display an 106 | announcement including an appropriate copyright notice and a 107 | notice that there is no warranty (or else, saying that you provide 108 | a warranty) and that users may redistribute the program under 109 | these conditions, and telling the user how to view a copy of this 110 | License. (Exception: if the Program itself is interactive but 111 | does not normally print such an announcement, your work based on 112 | the Program is not required to print an announcement.) 113 | 114 | These requirements apply to the modified work as a whole. If 115 | identifiable sections of that work are not derived from the Program, 116 | and can be reasonably considered independent and separate works in 117 | themselves, then this License, and its terms, do not apply to those 118 | sections when you distribute them as separate works. But when you 119 | distribute the same sections as part of a whole which is a work based 120 | on the Program, the distribution of the whole must be on the terms of 121 | this License, whose permissions for other licensees extend to the 122 | entire whole, and thus to each and every part regardless of who wrote it. 123 | 124 | Thus, it is not the intent of this section to claim rights or contest 125 | your rights to work written entirely by you; rather, the intent is to 126 | exercise the right to control the distribution of derivative or 127 | collective works based on the Program. 128 | 129 | In addition, mere aggregation of another work not based on the Program 130 | with the Program (or with a work based on the Program) on a volume of 131 | a storage or distribution medium does not bring the other work under 132 | the scope of this License. 133 | 134 | 3. You may copy and distribute the Program (or a work based on it, 135 | under Section 2) in object code or executable form under the terms of 136 | Sections 1 and 2 above provided that you also do one of the following: 137 | 138 | a) Accompany it with the complete corresponding machine-readable 139 | source code, which must be distributed under the terms of Sections 140 | 1 and 2 above on a medium customarily used for software interchange; or, 141 | 142 | b) Accompany it with a written offer, valid for at least three 143 | years, to give any third party, for a charge no more than your 144 | cost of physically performing source distribution, a complete 145 | machine-readable copy of the corresponding source code, to be 146 | distributed under the terms of Sections 1 and 2 above on a medium 147 | customarily used for software interchange; or, 148 | 149 | c) Accompany it with the information you received as to the offer 150 | to distribute corresponding source code. (This alternative is 151 | allowed only for noncommercial distribution and only if you 152 | received the program in object code or executable form with such 153 | an offer, in accord with Subsection b above.) 154 | 155 | The source code for a work means the preferred form of the work for 156 | making modifications to it. For an executable work, complete source 157 | code means all the source code for all modules it contains, plus any 158 | associated interface definition files, plus the scripts used to 159 | control compilation and installation of the executable. However, as a 160 | special exception, the source code distributed need not include 161 | anything that is normally distributed (in either source or binary 162 | form) with the major components (compiler, kernel, and so on) of the 163 | operating system on which the executable runs, unless that component 164 | itself accompanies the executable. 165 | 166 | If distribution of executable or object code is made by offering 167 | access to copy from a designated place, then offering equivalent 168 | access to copy the source code from the same place counts as 169 | distribution of the source code, even though third parties are not 170 | compelled to copy the source along with the object code. 171 | 172 | 4. You may not copy, modify, sublicense, or distribute the Program 173 | except as expressly provided under this License. Any attempt 174 | otherwise to copy, modify, sublicense or distribute the Program is 175 | void, and will automatically terminate your rights under this License. 176 | However, parties who have received copies, or rights, from you under 177 | this License will not have their licenses terminated so long as such 178 | parties remain in full compliance. 179 | 180 | 5. You are not required to accept this License, since you have not 181 | signed it. However, nothing else grants you permission to modify or 182 | distribute the Program or its derivative works. These actions are 183 | prohibited by law if you do not accept this License. Therefore, by 184 | modifying or distributing the Program (or any work based on the 185 | Program), you indicate your acceptance of this License to do so, and 186 | all its terms and conditions for copying, distributing or modifying 187 | the Program or works based on it. 188 | 189 | 6. Each time you redistribute the Program (or any work based on the 190 | Program), the recipient automatically receives a license from the 191 | original licensor to copy, distribute or modify the Program subject to 192 | these terms and conditions. You may not impose any further 193 | restrictions on the recipients' exercise of the rights granted herein. 194 | You are not responsible for enforcing compliance by third parties to 195 | this License. 196 | 197 | 7. If, as a consequence of a court judgment or allegation of patent 198 | infringement or for any other reason (not limited to patent issues), 199 | conditions are imposed on you (whether by court order, agreement or 200 | otherwise) that contradict the conditions of this License, they do not 201 | excuse you from the conditions of this License. If you cannot 202 | distribute so as to satisfy simultaneously your obligations under this 203 | License and any other pertinent obligations, then as a consequence you 204 | may not distribute the Program at all. For example, if a patent 205 | license would not permit royalty-free redistribution of the Program by 206 | all those who receive copies directly or indirectly through you, then 207 | the only way you could satisfy both it and this License would be to 208 | refrain entirely from distribution of the Program. 209 | 210 | If any portion of this section is held invalid or unenforceable under 211 | any particular circumstance, the balance of the section is intended to 212 | apply and the section as a whole is intended to apply in other 213 | circumstances. 214 | 215 | It is not the purpose of this section to induce you to infringe any 216 | patents or other property right claims or to contest validity of any 217 | such claims; this section has the sole purpose of protecting the 218 | integrity of the free software distribution system, which is 219 | implemented by public license practices. Many people have made 220 | generous contributions to the wide range of software distributed 221 | through that system in reliance on consistent application of that 222 | system; it is up to the author/donor to decide if he or she is willing 223 | to distribute software through any other system and a licensee cannot 224 | impose that choice. 225 | 226 | This section is intended to make thoroughly clear what is believed to 227 | be a consequence of the rest of this License. 228 | 229 | 8. If the distribution and/or use of the Program is restricted in 230 | certain countries either by patents or by copyrighted interfaces, the 231 | original copyright holder who places the Program under this License 232 | may add an explicit geographical distribution limitation excluding 233 | those countries, so that distribution is permitted only in or among 234 | countries not thus excluded. In such case, this License incorporates 235 | the limitation as if written in the body of this License. 236 | 237 | 9. The Free Software Foundation may publish revised and/or new versions 238 | of the General Public License from time to time. Such new versions will 239 | be similar in spirit to the present version, but may differ in detail to 240 | address new problems or concerns. 241 | 242 | Each version is given a distinguishing version number. If the Program 243 | specifies a version number of this License which applies to it and "any 244 | later version", you have the option of following the terms and conditions 245 | either of that version or of any later version published by the Free 246 | Software Foundation. If the Program does not specify a version number of 247 | this License, you may choose any version ever published by the Free Software 248 | Foundation. 249 | 250 | 10. If you wish to incorporate parts of the Program into other free 251 | programs whose distribution conditions are different, write to the author 252 | to ask for permission. For software which is copyrighted by the Free 253 | Software Foundation, write to the Free Software Foundation; we sometimes 254 | make exceptions for this. Our decision will be guided by the two goals 255 | of preserving the free status of all derivatives of our free software and 256 | of promoting the sharing and reuse of software generally. 257 | 258 | NO WARRANTY 259 | 260 | 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY 261 | FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN 262 | OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES 263 | PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED 264 | OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 265 | MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS 266 | TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE 267 | PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, 268 | REPAIR OR CORRECTION. 269 | 270 | 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING 271 | WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR 272 | REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, 273 | INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING 274 | OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED 275 | TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY 276 | YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER 277 | PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE 278 | POSSIBILITY OF SUCH DAMAGES. 279 | 280 | END OF TERMS AND CONDITIONS 281 | 282 | How to Apply These Terms to Your New Programs 283 | 284 | If you develop a new program, and you want it to be of the greatest 285 | possible use to the public, the best way to achieve this is to make it 286 | free software which everyone can redistribute and change under these terms. 287 | 288 | To do so, attach the following notices to the program. It is safest 289 | to attach them to the start of each source file to most effectively 290 | convey the exclusion of warranty; and each file should have at least 291 | the "copyright" line and a pointer to where the full notice is found. 292 | 293 | {description} 294 | Copyright (C) {year} {fullname} 295 | 296 | This program is free software; you can redistribute it and/or modify 297 | it under the terms of the GNU General Public License as published by 298 | the Free Software Foundation; either version 2 of the License, or 299 | (at your option) any later version. 300 | 301 | This program is distributed in the hope that it will be useful, 302 | but WITHOUT ANY WARRANTY; without even the implied warranty of 303 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 304 | GNU General Public License for more details. 305 | 306 | You should have received a copy of the GNU General Public License along 307 | with this program; if not, write to the Free Software Foundation, Inc., 308 | 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 309 | 310 | Also add information on how to contact you by electronic and paper mail. 311 | 312 | If the program is interactive, make it output a short notice like this 313 | when it starts in an interactive mode: 314 | 315 | Gnomovision version 69, Copyright (C) year name of author 316 | Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. 317 | This is free software, and you are welcome to redistribute it 318 | under certain conditions; type `show c' for details. 319 | 320 | The hypothetical commands `show w' and `show c' should show the appropriate 321 | parts of the General Public License. Of course, the commands you use may 322 | be called something other than `show w' and `show c'; they could even be 323 | mouse-clicks or menu items--whatever suits your program. 324 | 325 | You should also get your employer (if you work as a programmer) or your 326 | school, if any, to sign a "copyright disclaimer" for the program, if 327 | necessary. Here is a sample; alter the names: 328 | 329 | Yoyodyne, Inc., hereby disclaims all copyright interest in the program 330 | `Gnomovision' (which makes passes at compilers) written by James Hacker. 331 | 332 | {signature of Ty Coon}, 1 April 1989 333 | Ty Coon, President of Vice 334 | 335 | This General Public License does not permit incorporating your program into 336 | proprietary programs. If your program is a subroutine library, you may 337 | consider it more useful to permit linking proprietary applications with the 338 | library. If this is what you want to do, use the GNU Lesser General 339 | Public License instead of this License. 340 | 341 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | Since people have given me a lotta shit about the license and other stuff - lemme spell out what is going on. 2 | 3 | The port of Levels 2 which was floating around ported the mod illegally (by GPL's standards). I removed it because it was a shitty version of Levels 2 and apparently had several bugs and issues. I've been on and off trying to update Levels 3, but I'm also trying to cut back how much time I'm spending modding (with work and school), and with LSC taking up a lot of time, I don't have much time to work on Levels 3 - if anyone wants to take over the mod, send me a message please. I'd be interested in handing the project off to someone else. 4 | 5 | # Levels 6 | A small, Minecraft mod focused around the aspect of weapon and armor leveling. 7 | 8 | ## Source Code 9 | To view the source code, navigate between the desired branches, and the source will be viewable there. The master branch of this project is simply just used for information and miscellaneous mod-wide files. 10 | 11 | ## About Levels 12 | Levels is an innovative mod, centered around the concept of leveling systems, combined with adding many new features to the combat system within Minecraft. With Levels, you will be able to level up all of your weapons, swords and axes, along with tools and armor. On top of this, enemies will also become leveled, giving the option of a more challenging experience. 13 | 14 | Through all of these additions, Levels strives to create a unique system in which allows your weapons to become fully customizable and insanely powerful. On top of that, we are striving to create something highly adaptable, in other words, compatible with almost every other mod that adds weapons, tools, armors, and even monsters. 15 | 16 | A wiki implementation will be added here soon, for further information. 17 | 18 | ## Features 19 | At the base of the mod, Levels implements a rarity system. This system essentially determines how powerful the base stats of the item or monster are, with higher rarities being more powerful, while being much more rare. On top of this, items will also be able to gain experience, earn levels, and unlock powerful abilities for you to explore and use. 20 | 21 | ## Setting up a Workspace/Compiling from Source 22 | Perhaps you are interested in getting the most up to date version of the mod possible, or are interested in modifying the mod to fit your own standards, here are some basic instructions for getting started. 23 | 24 | * Setup: Download the source and run `gradlew [setupDecompWorkspace|setupDevWorkspace] [eclipse|idea]` 25 | * Build: Download the source and run `gradlew build` 26 | 27 | Distributing a customized version of Levels publicly is forbidden. You may, however, use your customized version and share it with friends privately. You also may not distribute a compiled version of the mod yourself either. If you have any questions regarding this, just let me know. 28 | 29 | ## Issue Reporting 30 | Please follow this format, even if loosely, when reporting issues. This just saves myself time asking you questions about what version you are running and things like that. 31 | 32 | * Minecraft Version 33 | * Forge Version 34 | * Levels Version 35 | * xLib Version (if appropriate) 36 | * Other mods possibly involved 37 | * Crash Reports and Logs (if applicable) 38 | * Steps to reproduce 39 | 40 | ## Downloads 41 | All official downloads can be found via [CurseForge](http://minecraft.curseforge.com/projects/levels/files). Levels is also dependent on [xLib](http://minecraft.curseforge.com/projects/xlib). Make sure you have the right version installed! 42 | -------------------------------------------------------------------------------- /build.gradle: -------------------------------------------------------------------------------- 1 | buildscript { 2 | repositories { 3 | jcenter() 4 | maven { 5 | name = "forge" 6 | url = "http://files.minecraftforge.net/maven" 7 | } 8 | } 9 | dependencies { 10 | classpath 'net.minecraftforge.gradle:ForgeGradle:2.2-SNAPSHOT' 11 | } 12 | } 13 | apply plugin: 'net.minecraftforge.gradle.forge' 14 | 15 | sourceCompatibility = 1.8 16 | targetCompatibility = 1.8 17 | 18 | loadProperties() 19 | 20 | version=config.minecraft_version + "-" + config.mod_version + "-" + config.major_version 21 | group= "com.thexfactor117.levels" 22 | archivesBaseName = "Levels 3" 23 | 24 | def loadProperties() { 25 | ext.configFile = file "build.properties" 26 | 27 | configFile.withReader { 28 | def prop = new Properties() 29 | prop.load(it) 30 | project.ext.config = new ConfigSlurper().parse prop 31 | } 32 | } 33 | 34 | minecraft { 35 | version = config.forge_version 36 | runDir = "run" 37 | mappings = config.mappings 38 | makeObfSourceJar = false 39 | 40 | replace "@VERSION@", config.mod_version 41 | } 42 | 43 | dependencies { 44 | 45 | } 46 | 47 | processResources 48 | { 49 | // this will ensure that this task is redone when the versions change. 50 | inputs.property "version", project.version 51 | inputs.property "mcversion", project.minecraft.version 52 | 53 | // replace stuff in mcmod.info, nothing else 54 | from(sourceSets.main.resources.srcDirs) { 55 | include 'mcmod.info' 56 | 57 | // replace version and mcversion 58 | expand 'version':project.version, 'mcversion':project.minecraft.version 59 | } 60 | 61 | // copy everything else, thats not the mcmod.info 62 | from(sourceSets.main.resources.srcDirs) { 63 | exclude 'mcmod.info' 64 | } 65 | } 66 | -------------------------------------------------------------------------------- /build.properties: -------------------------------------------------------------------------------- 1 | minecraft_version=1.11.2 2 | forge_version=1.11.2-13.20.0.2282 3 | mappings=snapshot_20161220 4 | 5 | mod_version=3.0.2 6 | major_version=beta -------------------------------------------------------------------------------- /gradle.properties: -------------------------------------------------------------------------------- 1 | # Sets default memory used for gradle commands. Can be overridden by user or command line properties. 2 | # This is required to provide enough memory for the Minecraft decompilation process. 3 | org.gradle.jvmargs=-Xmx3G 4 | -------------------------------------------------------------------------------- /gradle/wrapper/gradle-wrapper.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TheXFactor117/Levels/b8b43fb558c0dd20f6e738017e15c155438efb44/gradle/wrapper/gradle-wrapper.jar -------------------------------------------------------------------------------- /gradle/wrapper/gradle-wrapper.properties: -------------------------------------------------------------------------------- 1 | #Mon Sep 14 12:28:28 PDT 2015 2 | distributionBase=GRADLE_USER_HOME 3 | distributionPath=wrapper/dists 4 | zipStoreBase=GRADLE_USER_HOME 5 | zipStorePath=wrapper/dists 6 | distributionUrl=https\://services.gradle.org/distributions/gradle-2.14-bin.zip 7 | -------------------------------------------------------------------------------- /gradlew: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | ############################################################################## 4 | ## 5 | ## Gradle start up script for UN*X 6 | ## 7 | ############################################################################## 8 | 9 | # Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. 10 | DEFAULT_JVM_OPTS="" 11 | 12 | APP_NAME="Gradle" 13 | APP_BASE_NAME=`basename "$0"` 14 | 15 | # Use the maximum available, or set MAX_FD != -1 to use that value. 16 | MAX_FD="maximum" 17 | 18 | warn ( ) { 19 | echo "$*" 20 | } 21 | 22 | die ( ) { 23 | echo 24 | echo "$*" 25 | echo 26 | exit 1 27 | } 28 | 29 | # OS specific support (must be 'true' or 'false'). 30 | cygwin=false 31 | msys=false 32 | darwin=false 33 | case "`uname`" in 34 | CYGWIN* ) 35 | cygwin=true 36 | ;; 37 | Darwin* ) 38 | darwin=true 39 | ;; 40 | MINGW* ) 41 | msys=true 42 | ;; 43 | esac 44 | 45 | # For Cygwin, ensure paths are in UNIX format before anything is touched. 46 | if $cygwin ; then 47 | [ -n "$JAVA_HOME" ] && JAVA_HOME=`cygpath --unix "$JAVA_HOME"` 48 | fi 49 | 50 | # Attempt to set APP_HOME 51 | # Resolve links: $0 may be a link 52 | PRG="$0" 53 | # Need this for relative symlinks. 54 | while [ -h "$PRG" ] ; do 55 | ls=`ls -ld "$PRG"` 56 | link=`expr "$ls" : '.*-> \(.*\)$'` 57 | if expr "$link" : '/.*' > /dev/null; then 58 | PRG="$link" 59 | else 60 | PRG=`dirname "$PRG"`"/$link" 61 | fi 62 | done 63 | SAVED="`pwd`" 64 | cd "`dirname \"$PRG\"`/" >&- 65 | APP_HOME="`pwd -P`" 66 | cd "$SAVED" >&- 67 | 68 | CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar 69 | 70 | # Determine the Java command to use to start the JVM. 71 | if [ -n "$JAVA_HOME" ] ; then 72 | if [ -x "$JAVA_HOME/jre/sh/java" ] ; then 73 | # IBM's JDK on AIX uses strange locations for the executables 74 | JAVACMD="$JAVA_HOME/jre/sh/java" 75 | else 76 | JAVACMD="$JAVA_HOME/bin/java" 77 | fi 78 | if [ ! -x "$JAVACMD" ] ; then 79 | die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME 80 | 81 | Please set the JAVA_HOME variable in your environment to match the 82 | location of your Java installation." 83 | fi 84 | else 85 | JAVACMD="java" 86 | which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 87 | 88 | Please set the JAVA_HOME variable in your environment to match the 89 | location of your Java installation." 90 | fi 91 | 92 | # Increase the maximum file descriptors if we can. 93 | if [ "$cygwin" = "false" -a "$darwin" = "false" ] ; then 94 | MAX_FD_LIMIT=`ulimit -H -n` 95 | if [ $? -eq 0 ] ; then 96 | if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then 97 | MAX_FD="$MAX_FD_LIMIT" 98 | fi 99 | ulimit -n $MAX_FD 100 | if [ $? -ne 0 ] ; then 101 | warn "Could not set maximum file descriptor limit: $MAX_FD" 102 | fi 103 | else 104 | warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT" 105 | fi 106 | fi 107 | 108 | # For Darwin, add options to specify how the application appears in the dock 109 | if $darwin; then 110 | GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\"" 111 | fi 112 | 113 | # For Cygwin, switch paths to Windows format before running java 114 | if $cygwin ; then 115 | APP_HOME=`cygpath --path --mixed "$APP_HOME"` 116 | CLASSPATH=`cygpath --path --mixed "$CLASSPATH"` 117 | 118 | # We build the pattern for arguments to be converted via cygpath 119 | ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null` 120 | SEP="" 121 | for dir in $ROOTDIRSRAW ; do 122 | ROOTDIRS="$ROOTDIRS$SEP$dir" 123 | SEP="|" 124 | done 125 | OURCYGPATTERN="(^($ROOTDIRS))" 126 | # Add a user-defined pattern to the cygpath arguments 127 | if [ "$GRADLE_CYGPATTERN" != "" ] ; then 128 | OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)" 129 | fi 130 | # Now convert the arguments - kludge to limit ourselves to /bin/sh 131 | i=0 132 | for arg in "$@" ; do 133 | CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -` 134 | CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option 135 | 136 | if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition 137 | eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"` 138 | else 139 | eval `echo args$i`="\"$arg\"" 140 | fi 141 | i=$((i+1)) 142 | done 143 | case $i in 144 | (0) set -- ;; 145 | (1) set -- "$args0" ;; 146 | (2) set -- "$args0" "$args1" ;; 147 | (3) set -- "$args0" "$args1" "$args2" ;; 148 | (4) set -- "$args0" "$args1" "$args2" "$args3" ;; 149 | (5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;; 150 | (6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;; 151 | (7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;; 152 | (8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;; 153 | (9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;; 154 | esac 155 | fi 156 | 157 | # Split up the JVM_OPTS And GRADLE_OPTS values into an array, following the shell quoting and substitution rules 158 | function splitJvmOpts() { 159 | JVM_OPTS=("$@") 160 | } 161 | eval splitJvmOpts $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS 162 | JVM_OPTS[${#JVM_OPTS[*]}]="-Dorg.gradle.appname=$APP_BASE_NAME" 163 | 164 | exec "$JAVACMD" "${JVM_OPTS[@]}" -classpath "$CLASSPATH" org.gradle.wrapper.GradleWrapperMain "$@" 165 | -------------------------------------------------------------------------------- /gradlew.bat: -------------------------------------------------------------------------------- 1 | @if "%DEBUG%" == "" @echo off 2 | @rem ########################################################################## 3 | @rem 4 | @rem Gradle startup script for Windows 5 | @rem 6 | @rem ########################################################################## 7 | 8 | @rem Set local scope for the variables with windows NT shell 9 | if "%OS%"=="Windows_NT" setlocal 10 | 11 | @rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. 12 | set DEFAULT_JVM_OPTS= 13 | 14 | set DIRNAME=%~dp0 15 | if "%DIRNAME%" == "" set DIRNAME=. 16 | set APP_BASE_NAME=%~n0 17 | set APP_HOME=%DIRNAME% 18 | 19 | @rem Find java.exe 20 | if defined JAVA_HOME goto findJavaFromJavaHome 21 | 22 | set JAVA_EXE=java.exe 23 | %JAVA_EXE% -version >NUL 2>&1 24 | if "%ERRORLEVEL%" == "0" goto init 25 | 26 | echo. 27 | echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 28 | echo. 29 | echo Please set the JAVA_HOME variable in your environment to match the 30 | echo location of your Java installation. 31 | 32 | goto fail 33 | 34 | :findJavaFromJavaHome 35 | set JAVA_HOME=%JAVA_HOME:"=% 36 | set JAVA_EXE=%JAVA_HOME%/bin/java.exe 37 | 38 | if exist "%JAVA_EXE%" goto init 39 | 40 | echo. 41 | echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% 42 | echo. 43 | echo Please set the JAVA_HOME variable in your environment to match the 44 | echo location of your Java installation. 45 | 46 | goto fail 47 | 48 | :init 49 | @rem Get command-line arguments, handling Windowz variants 50 | 51 | if not "%OS%" == "Windows_NT" goto win9xME_args 52 | if "%@eval[2+2]" == "4" goto 4NT_args 53 | 54 | :win9xME_args 55 | @rem Slurp the command line arguments. 56 | set CMD_LINE_ARGS= 57 | set _SKIP=2 58 | 59 | :win9xME_args_slurp 60 | if "x%~1" == "x" goto execute 61 | 62 | set CMD_LINE_ARGS=%* 63 | goto execute 64 | 65 | :4NT_args 66 | @rem Get arguments from the 4NT Shell from JP Software 67 | set CMD_LINE_ARGS=%$ 68 | 69 | :execute 70 | @rem Setup the command line 71 | 72 | set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar 73 | 74 | @rem Execute Gradle 75 | "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS% 76 | 77 | :end 78 | @rem End local scope for the variables with windows NT shell 79 | if "%ERRORLEVEL%"=="0" goto mainEnd 80 | 81 | :fail 82 | rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of 83 | rem the _cmd.exe /c_ return code! 84 | if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1 85 | exit /b 1 86 | 87 | :mainEnd 88 | if "%OS%"=="Windows_NT" endlocal 89 | 90 | :omega 91 | -------------------------------------------------------------------------------- /information/changelogs.txt: -------------------------------------------------------------------------------- 1 | ##### 2 | ### Levels 3 Changelogs 3 | ##### 4 | 5 | ### 3.0.2-beta 6 | * Fixes crash when connecting to servers. 7 | 8 | 9 | ### 3.0.1-beta 10 | * Fixes player ticking crash. 11 | * Fixes display name issues when renaming weapons/armor. 12 | * Fixes Unbreakable attribute not correctly applying sometimes. 13 | * Fixes client code reference crashes. 14 | 15 | 16 | ### 3.0.0-beta 17 | + Added Attributes (which replace Abilities). 18 | + Added Damage, Attack Speed, Armor, and Armor Toughness modifiers to all weapons and armor. 19 | + Added multipliers in which multiply the four aspects above each time you level up. 20 | + Added config option for Unlimited durability. 21 | - Removed Enemy Leveling for the time being. 22 | - Removed bow support for the time being. 23 | - Removed Ultra Rare rarity. 24 | - Removed Abilities. 25 | - Removed GUI's. Attributes are gained randomly now. 26 | * Increased difference between different rarities. Legendary and Mythic weapons are now much more powerful. 27 | * Weapon experience is only gained when a mob is killed. 28 | * All experience is now based on the enemies health and damage. 29 | * Changed Archaic rarity to Mythic. 30 | * Increased max level to 10. Configurable in the config. 31 | * Unlimited durability now uses the Unbreakable tag. 32 | * Fixed many bugs and issues with Levels 2. 33 | * Optimized lots of code from Levels 2. -------------------------------------------------------------------------------- /information/faq.txt: -------------------------------------------------------------------------------- 1 | ############################################### 2 | ############################################### 3 | ##### Levels 2 Frequently Asked Questions ##### 4 | ############################################### 5 | ############################################### 6 | 7 | Q: Where can I learn how the mod works? 8 | A: Read the Wiki! It can be found on the Level's GitHub repository. There are also links on the forum thread. 9 | 10 | Q: Will you ever create a tools/pickaxe leveling system? 11 | A: Chances are, probably not. But who knows! Anything could happen. 12 | 13 | Q: When will armor, bow, and enemy leveling systems be added back in? 14 | A: As soon as I can develop them. Re-writing the mod means re-writing each of these systems, so it might take a bit of time to finish them up. However, 15 | they should come out much faster as time goes on. 16 | 17 | Q: I want to help out with the mod. What could I do? 18 | A: I actually don't need much help with this mod right now. The best thing you could do is just play it, share it, and provide feedback about it! -------------------------------------------------------------------------------- /information/old_changelogs.txt: -------------------------------------------------------------------------------- 1 | ############### 2 | ##### Old Changelogs 3 | ############### 4 | 5 | 6 | ##### 7 | ### Levels 2 - Release 1 8 | ##### 9 | 10 | ### r1.2.7 11 | # 12 | # * Fixes issues with r1.2.7 13 | # 14 | ### 15 | 16 | ### r1.2.7 17 | # 18 | # * Fixes issue where armor abilities were displayed as weapon abilities. 19 | # 20 | ### 21 | 22 | ### r1.2.6 23 | # 24 | # + Added tooltips underneath abilities explaining what they do. 25 | # * Fixed duplication bug on servers. 26 | # 27 | ### 28 | 29 | ### r1.2.5 30 | # 31 | # + Added a message explaining Levels after crafting a sword. Must have achievements on for it to work. 32 | # - Removed login message. 33 | # 34 | ### 35 | 36 | ### r1.2.4 37 | # 38 | # * Fixes crash with arrows. 39 | # 40 | ### 41 | 42 | ### r1.2.3 43 | # 44 | # * Fixes crash when not wearing armor. 45 | # 46 | ### 47 | 48 | ### r1.2.2 49 | # 50 | # * Fixes crash when holding/not holding certain items. 51 | # 52 | ### 53 | 54 | ### r1.2.1 55 | # 56 | # * Fixes armor ability selection GUI button placement. 57 | # 58 | ### 59 | 60 | ### r1.2.0 61 | # 62 | # + Added configuration options to remove certain abilities. 63 | # + Added Danish language file (courtesy of Zerotiger). 64 | # * Re-worked configuration file. 65 | # 66 | ### 67 | 68 | ### r1.1.2 69 | # 70 | # * Fixed critical bug where servers would crash on player join. 71 | # 72 | ### 73 | 74 | ### r1.1.1 75 | # 76 | # * Fixed issue where some enemies were unkillable. 77 | # 78 | ### 79 | 80 | ### r1.1.0 81 | # 82 | # + Added config option for changing rarity chance. 83 | # + Added config option for changing rarity bonus damage multiplier. 84 | # + Added config option for changing the leveling algorithm. 85 | # + Added a login message (toggable) to get new users started in the mod. 86 | # + Added a tooltip to show how much damage the weapon could deal given the specific rarity. 87 | # * Fixed bug where armor wouldn't gain experience when hit by arrows. 88 | # * Changed rarity bonus damage to be multipliers. 89 | # 90 | ### 91 | 92 | ### r1.0.0 93 | # 94 | # * Levels 2 has been officially released! 95 | # * Fixes crash on server startup. 96 | # * Fixes some graphical issues. 97 | # 98 | ### 99 | 100 | 101 | ##### 102 | ### Levels 2 - Beta 2 103 | ##### 104 | 105 | 106 | ### b2.2.0 107 | # 108 | # + Added Enemy leveling. 109 | # 110 | ### 111 | 112 | ### b2.1.0 113 | # 114 | # + Added Bow leveling and abilities. 115 | # 116 | ### 117 | 118 | ### b2.0.0 119 | # 120 | # + Added Armor leveling and abilities. 121 | # * Changed rarity damage multipliers from multiplying to adding. 122 | # * Fixed some issues where Axes might not work properly with the leveling systems. 123 | # 124 | ### 125 | 126 | 127 | 128 | ##### 129 | ### Levels 2 - Beta 1 130 | ##### 131 | 132 | 133 | ### b1.1.1 134 | # 135 | # * Fixes issue where abilities can be leveled up more than 3 times. 136 | # * Tweaked Chained ability to only affect hostile enemies. 137 | # 138 | ### 139 | 140 | ### b1.1.0 141 | # 142 | # + Added a tiered ability system. 143 | # + Added new ability: Soul Bound. 144 | # * Fixed a couple Gui bugs. 145 | # * Changed basic rarity color to white; changed archaic rarity color to pink. 146 | # * Fixed Chained ability bug in which it damaged the player whenever triggered. 147 | # 148 | ### 149 | 150 | ### b1.0.1 151 | # 152 | # * Fixes crash on server load. 153 | # 154 | ### 155 | 156 | ### b1.0.0 157 | # 158 | # + Added an item blacklist to manually remove items from receiving the leveling systems. 159 | # - Removed randomized abilities. Abilities can now be picked by the player. 160 | # - Removed some abilities. Also removed some leveling systems temporarily. 161 | # * Re-built leveling system from the ground up. 162 | # * Re-worked rarity bonuses and all abilities. 163 | # * Fixed many, many bugs. 164 | # 165 | ### -------------------------------------------------------------------------------- /levels-version-checker.json: -------------------------------------------------------------------------------- 1 | { 2 | "homepage": "http://minecraft.curseforge.com/projects/levels/files", 3 | "promos": { 4 | "1.11.2-latest": "r1.2.8", 5 | "1.11.2-recommended": "r1.2.8", 6 | "1.10.2-latest": "r1.2.8", 7 | "1.10.2-recommended": "r1.2.8" 8 | }, 9 | "1.11.2": { 10 | "r1.2.8": "* View the full changelog on GitHub." 11 | }, 12 | "1.10.2": { 13 | "r1.2.8": "* View the full changelog on GitHub." 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /src/main/java/com/thexfactor117/levels/Levels.java: -------------------------------------------------------------------------------- 1 | package com.thexfactor117.levels; 2 | 3 | import java.io.File; 4 | 5 | import org.apache.logging.log4j.LogManager; 6 | import org.apache.logging.log4j.Logger; 7 | 8 | import com.thexfactor117.levels.config.Config; 9 | import com.thexfactor117.levels.init.ModEvents; 10 | import com.thexfactor117.levels.network.PacketAttributeSelection; 11 | import com.thexfactor117.levels.network.PacketMythicSound; 12 | import com.thexfactor117.levels.proxies.CommonProxy; 13 | import com.thexfactor117.levels.util.GuiHandler; 14 | import com.thexfactor117.levels.util.Reference; 15 | 16 | import net.minecraftforge.fml.common.Mod; 17 | import net.minecraftforge.fml.common.Mod.EventHandler; 18 | import net.minecraftforge.fml.common.Mod.Instance; 19 | import net.minecraftforge.fml.common.SidedProxy; 20 | import net.minecraftforge.fml.common.event.FMLInitializationEvent; 21 | import net.minecraftforge.fml.common.event.FMLPostInitializationEvent; 22 | import net.minecraftforge.fml.common.event.FMLPreInitializationEvent; 23 | import net.minecraftforge.fml.common.network.NetworkRegistry; 24 | import net.minecraftforge.fml.common.network.simpleimpl.SimpleNetworkWrapper; 25 | import net.minecraftforge.fml.relauncher.Side; 26 | 27 | /** 28 | * 29 | * @author TheXFactor117 30 | * 31 | * Levels 3 32 | * 33 | */ 34 | @Mod(modid = Reference.MODID, name = Reference.NAME, version = Reference.VERSION, updateJSON = Reference.UPDATE_URL) 35 | public class Levels 36 | { 37 | @SidedProxy(clientSide = Reference.CLIENT, serverSide = Reference.COMMON) 38 | public static CommonProxy proxy; 39 | @Instance(Reference.MODID) 40 | public static Levels instance; 41 | public static final Logger LOGGER = LogManager.getLogger("Levels"); 42 | public static SimpleNetworkWrapper network; 43 | private static File configDir; 44 | 45 | @EventHandler 46 | public void preInit(FMLPreInitializationEvent event) 47 | { 48 | configDir = new File(event.getModConfigurationDirectory() + "/" + Reference.MODID); 49 | configDir.mkdirs(); 50 | Config.init(configDir); 51 | 52 | ModEvents.register(); 53 | proxy.preInit(); 54 | 55 | network = NetworkRegistry.INSTANCE.newSimpleChannel(Reference.MODID); 56 | network.registerMessage(PacketAttributeSelection.Handler.class, PacketAttributeSelection.class, 0, Side.SERVER); 57 | network.registerMessage(PacketMythicSound.Handler.class, PacketMythicSound.class, 1, Side.CLIENT); 58 | } 59 | 60 | @EventHandler 61 | public void init(FMLInitializationEvent event) 62 | { 63 | proxy.init(); 64 | NetworkRegistry.INSTANCE.registerGuiHandler(instance, new GuiHandler()); 65 | } 66 | 67 | @EventHandler 68 | public void postInit(FMLPostInitializationEvent event) {} 69 | 70 | public static File getConfigDir() 71 | { 72 | return configDir; 73 | } 74 | } 75 | -------------------------------------------------------------------------------- /src/main/java/com/thexfactor117/levels/client/gui/GuiItemInformation.java: -------------------------------------------------------------------------------- 1 | package com.thexfactor117.levels.client.gui; 2 | 3 | import java.io.IOException; 4 | 5 | import com.thexfactor117.levels.Levels; 6 | import com.thexfactor117.levels.config.Config; 7 | import com.thexfactor117.levels.leveling.Experience; 8 | import com.thexfactor117.levels.leveling.Rarity; 9 | import com.thexfactor117.levels.leveling.attributes.ArmorAttribute; 10 | import com.thexfactor117.levels.leveling.attributes.BowAttribute; 11 | import com.thexfactor117.levels.leveling.attributes.ShieldAttribute; 12 | import com.thexfactor117.levels.leveling.attributes.WeaponAttribute; 13 | import com.thexfactor117.levels.util.GuiHandler; 14 | import com.thexfactor117.levels.util.NBTHelper; 15 | 16 | import net.minecraft.client.entity.EntityPlayerSP; 17 | import net.minecraft.client.gui.GuiButton; 18 | import net.minecraft.client.gui.GuiScreen; 19 | import net.minecraft.client.resources.I18n; 20 | import net.minecraft.entity.player.EntityPlayer; 21 | import net.minecraft.item.ItemArmor; 22 | import net.minecraft.item.ItemBow; 23 | import net.minecraft.item.ItemShield; 24 | import net.minecraft.item.ItemStack; 25 | import net.minecraft.item.ItemSword; 26 | import net.minecraft.item.ItemTool; 27 | import net.minecraft.nbt.NBTTagCompound; 28 | import net.minecraftforge.fml.relauncher.Side; 29 | import net.minecraftforge.fml.relauncher.SideOnly; 30 | 31 | /** 32 | * 33 | * @author TheXFactor117 34 | * 35 | */ 36 | public class GuiItemInformation extends GuiScreen 37 | { 38 | private GuiButton selection; 39 | 40 | @SideOnly(Side.CLIENT) 41 | @Override 42 | public void initGui() 43 | { 44 | selection = new GuiButton(0, this.width / 2 - 166, 125, 110, 20, "Attribute Selection"); 45 | 46 | this.buttonList.add(selection); 47 | } 48 | 49 | @SideOnly(Side.CLIENT) 50 | @Override 51 | public void drawScreen(int mouseX, int mouseY, float partialTicks) 52 | { 53 | this.drawDefaultBackground(); 54 | super.drawScreen(mouseX, mouseY, partialTicks); 55 | 56 | EntityPlayer player = this.mc.player; 57 | 58 | if (player != null) 59 | { 60 | ItemStack stack = player.inventory.getCurrentItem(); 61 | 62 | if (stack != null) 63 | { 64 | NBTTagCompound nbt = NBTHelper.loadStackNBT(stack); 65 | 66 | if (nbt != null) 67 | { 68 | drawStrings(stack, nbt); 69 | } 70 | } 71 | } 72 | } 73 | 74 | @SideOnly(Side.CLIENT) 75 | @Override 76 | protected void actionPerformed(GuiButton button) throws IOException 77 | { 78 | EntityPlayerSP player = mc.player; 79 | 80 | if (player != null) 81 | { 82 | ItemStack stack = player.inventory.getCurrentItem(); 83 | 84 | if (stack != null) 85 | { 86 | if (button == selection) 87 | { 88 | if (stack.getItem() instanceof ItemSword) 89 | { 90 | player.openGui(Levels.instance, GuiHandler.WEAPON_ATTRIBUTES, player.getEntityWorld(), (int) player.posX, (int) player.posY, (int) player.posZ); 91 | } 92 | else if (stack.getItem() instanceof ItemArmor) 93 | { 94 | player.openGui(Levels.instance, GuiHandler.ARMOR_ATTRIBUTES, player.getEntityWorld(), (int) player.posX, (int) player.posY, (int) player.posZ); 95 | } 96 | else if (stack.getItem() instanceof ItemBow) 97 | { 98 | player.openGui(Levels.instance, GuiHandler.BOW_ATTRIBUTES, player.getEntityWorld(), (int) player.posX, (int) player.posY, (int) player.posZ); 99 | } 100 | else if (stack.getItem() instanceof ItemShield) 101 | { 102 | player.openGui(Levels.instance, GuiHandler.SHIELD_ATTRIBUTES, player.getEntityWorld(), (int) player.posX, (int) player.posY, (int) player.posZ); 103 | } 104 | else if (stack.getItem() instanceof ItemTool) 105 | { 106 | //player.openGui(Levels.instance, GuiHandler., player.getEntityWorld(), (int) player.posX, (int) player.posY, (int) player.posZ); 107 | } 108 | } 109 | } 110 | } 111 | } 112 | 113 | /** 114 | * Draws the strings for the ability selection screen. 115 | * @param stack 116 | * @param abilities 117 | * @param nbt 118 | */ 119 | private void drawStrings(ItemStack stack, NBTTagCompound nbt) 120 | { 121 | Rarity rarity = Rarity.getRarity(nbt); 122 | 123 | drawCenteredString(fontRendererObj, stack.getDisplayName(), width / 2, 20, rarity.getHex()); 124 | drawString(fontRendererObj, I18n.format("levels.misc.rarity") + ": " + rarity.getName(), width / 2 - 50, 40, rarity.getHex()); 125 | drawCenteredString(fontRendererObj, I18n.format("levels.misc.attributes"), width / 2, 80, 0xFFFFFF); 126 | drawCenteredString(fontRendererObj, I18n.format("levels.misc.attributes.tokens") + ": " + Experience.getAttributeTokens(nbt), width / 2 - 112, 100, 0xFFFFFF); 127 | drawCenteredString(fontRendererObj, I18n.format("levels.misc.attributes.current"), width / 2 + 112, 100, 0xFFFFFF); 128 | 129 | if (Experience.getLevel(nbt) == Config.maxLevel) 130 | { 131 | drawString(fontRendererObj, I18n.format("levels.misc.level") + ": " + I18n.format("levels.misc.max"), width / 2 - 50, 50, 0xFFFFFF); 132 | drawString(fontRendererObj, I18n.format("levels.misc.experience") + ": " + I18n.format("levels.misc.max"), width / 2 - 50, 60, 0xFFFFFF); 133 | } 134 | else 135 | { 136 | drawString(fontRendererObj, I18n.format("levels.misc.level") + ": " + Experience.getLevel(nbt), width / 2 - 50, 50, 0xFFFFFF); 137 | drawString(fontRendererObj, I18n.format("levels.misc.experience") + ": " + Experience.getExperience(nbt) + " / " + Experience.getNextLevelExperience(Experience.getLevel(nbt)), width / 2 - 50, 60, 0xFFFFFF); 138 | } 139 | 140 | int k = -1; 141 | 142 | if (stack.getItem() instanceof ItemSword) 143 | { 144 | for (int i = 0; i < WeaponAttribute.WEAPON_ATTRIBUTES.size(); i++) 145 | { 146 | if (WeaponAttribute.WEAPON_ATTRIBUTES.get(i).hasAttribute(nbt)) 147 | { 148 | k++; 149 | drawCenteredString(fontRendererObj, WeaponAttribute.WEAPON_ATTRIBUTES.get(i).getName(nbt), width / 2 + 112, 115 + (10 * k), WeaponAttribute.WEAPON_ATTRIBUTES.get(i).getHex()); 150 | } 151 | } 152 | } 153 | else if (stack.getItem() instanceof ItemTool) 154 | { 155 | 156 | } 157 | else if (stack.getItem() instanceof ItemBow) 158 | { 159 | for (int i = 0; i < BowAttribute.BOW_ATTRIBUTES.size(); i++) 160 | { 161 | if (BowAttribute.BOW_ATTRIBUTES.get(i).hasAttribute(nbt)) 162 | { 163 | k++; 164 | drawCenteredString(fontRendererObj, BowAttribute.BOW_ATTRIBUTES.get(i).getName(nbt), width / 2 + 112, 115 + (10 * k), BowAttribute.BOW_ATTRIBUTES.get(i).getHex()); 165 | } 166 | } 167 | } 168 | else if (stack.getItem() instanceof ItemArmor) 169 | { 170 | for (int i = 0; i < ArmorAttribute.ARMOR_ATTRIBUTES.size(); i++) 171 | { 172 | if (ArmorAttribute.ARMOR_ATTRIBUTES.get(i).hasAttribute(nbt)) 173 | { 174 | k++; 175 | drawCenteredString(fontRendererObj, ArmorAttribute.ARMOR_ATTRIBUTES.get(i).getName(nbt), width / 2 + 112, 115 + (10 * k), ArmorAttribute.ARMOR_ATTRIBUTES.get(i).getHex()); 176 | } 177 | } 178 | } 179 | else if (stack.getItem() instanceof ItemShield) 180 | { 181 | for (int i = 0; i < ShieldAttribute.SHIELD_ATTRIBUTES.size(); i++) 182 | { 183 | if (ShieldAttribute.SHIELD_ATTRIBUTES.get(i).hasAttribute(nbt)) 184 | { 185 | k++; 186 | drawCenteredString(fontRendererObj, ShieldAttribute.SHIELD_ATTRIBUTES.get(i).getName(nbt), width / 2 + 112, 115 + (10 * k), ShieldAttribute.SHIELD_ATTRIBUTES.get(i).getHex()); 187 | } 188 | } 189 | } 190 | } 191 | 192 | @Override 193 | public boolean doesGuiPauseGame() 194 | { 195 | return false; 196 | } 197 | } 198 | -------------------------------------------------------------------------------- /src/main/java/com/thexfactor117/levels/client/gui/selection/GuiArmorSelection.java: -------------------------------------------------------------------------------- 1 | package com.thexfactor117.levels.client.gui.selection; 2 | 3 | import java.io.IOException; 4 | import java.util.ArrayList; 5 | import java.util.List; 6 | 7 | import com.thexfactor117.levels.Levels; 8 | import com.thexfactor117.levels.leveling.Experience; 9 | import com.thexfactor117.levels.leveling.Rarity; 10 | import com.thexfactor117.levels.leveling.attributes.ArmorAttribute; 11 | import com.thexfactor117.levels.network.PacketAttributeSelection; 12 | import com.thexfactor117.levels.util.NBTHelper; 13 | 14 | import net.minecraft.client.entity.EntityPlayerSP; 15 | import net.minecraft.client.gui.GuiButton; 16 | import net.minecraft.client.gui.GuiScreen; 17 | import net.minecraft.client.resources.I18n; 18 | import net.minecraft.entity.player.EntityPlayer; 19 | import net.minecraft.item.ItemArmor; 20 | import net.minecraft.item.ItemStack; 21 | import net.minecraft.nbt.NBTTagCompound; 22 | import net.minecraft.util.text.TextFormatting; 23 | import net.minecraftforge.fml.client.config.HoverChecker; 24 | import net.minecraftforge.fml.relauncher.Side; 25 | import net.minecraftforge.fml.relauncher.SideOnly; 26 | 27 | /** 28 | * 29 | * @author TheXFactor117 30 | * 31 | */ 32 | public class GuiArmorSelection extends GuiScreen 33 | { 34 | private GuiButton[] attributes; 35 | 36 | @SideOnly(Side.CLIENT) 37 | @Override 38 | public void initGui() 39 | { 40 | EntityPlayer player = this.mc.player; 41 | ItemStack stack = player.inventory.getCurrentItem(); 42 | NBTTagCompound nbt = NBTHelper.loadStackNBT(stack); 43 | 44 | if (player != null && stack != null && nbt != null && stack.getItem() instanceof ItemArmor) 45 | { 46 | attributes = new GuiButton[ArmorAttribute.ARMOR_ATTRIBUTES.size()]; 47 | 48 | for (int i = 0; i < attributes.length; i++) 49 | { 50 | attributes[i] = new GuiButton(i, width / 2 - 147, 60 + (i * 20), 75, 20, ArmorAttribute.ARMOR_ATTRIBUTES.get(i).getName(nbt)); 51 | this.buttonList.add(attributes[i]); 52 | attributes[i].enabled = false; 53 | } 54 | } 55 | } 56 | 57 | @SideOnly(Side.CLIENT) 58 | @Override 59 | public void drawScreen(int mouseX, int mouseY, float partialTicks) 60 | { 61 | this.drawDefaultBackground(); 62 | super.drawScreen(mouseX, mouseY, partialTicks); 63 | 64 | EntityPlayer player = this.mc.player; 65 | ItemStack stack = player.inventory.getCurrentItem(); 66 | NBTTagCompound nbt = NBTHelper.loadStackNBT(stack); 67 | 68 | if (player != null && stack != null && nbt != null && stack.getItem() instanceof ItemArmor) 69 | { 70 | drawCenteredString(fontRendererObj, I18n.format("levels.misc.attributes"), width / 2, 20, 0xFFFFFF); 71 | drawCenteredString(fontRendererObj, I18n.format("levels.misc.attributes.tokens") + ": " + Experience.getAttributeTokens(nbt), width / 2 - 112, 40, 0xFFFFFF); 72 | drawCenteredString(fontRendererObj, I18n.format("levels.misc.attributes.current"), width / 2 + 112, 40, 0xFFFFFF); 73 | 74 | int k = -1; 75 | 76 | for (int i = 0; i < ArmorAttribute.ARMOR_ATTRIBUTES.size(); i++) 77 | { 78 | if (ArmorAttribute.ARMOR_ATTRIBUTES.get(i).hasAttribute(nbt)) 79 | { 80 | k++; 81 | drawCenteredString(fontRendererObj, ArmorAttribute.ARMOR_ATTRIBUTES.get(i).getName(nbt), width / 2 + 112, 60 + (10 * k), ArmorAttribute.ARMOR_ATTRIBUTES.get(i).getHex()); 82 | } 83 | } 84 | 85 | displayButtons(nbt); 86 | drawTooltips(nbt, mouseX, mouseY); 87 | } 88 | } 89 | 90 | @SideOnly(Side.CLIENT) 91 | @Override 92 | protected void actionPerformed(GuiButton button) throws IOException 93 | { 94 | EntityPlayerSP player = mc.player; 95 | ItemStack stack = player.inventory.getCurrentItem(); 96 | NBTTagCompound nbt = NBTHelper.loadStackNBT(stack); 97 | 98 | if (player != null && stack != null && nbt != null) 99 | { 100 | if (Experience.getAttributeTokens(nbt) > 0) 101 | { 102 | if (stack.getItem() instanceof ItemArmor) 103 | { 104 | for (int i = 0; i < attributes.length; i++) 105 | { 106 | if (button == attributes[i]) 107 | Levels.network.sendToServer(new PacketAttributeSelection(i)); 108 | } 109 | } 110 | } 111 | } 112 | } 113 | 114 | /** 115 | * Determines which buttons need to be enabled. 116 | * @param buttons 117 | * @param nbt 118 | */ 119 | private void displayButtons(NBTTagCompound nbt) 120 | { 121 | if (Experience.getAttributeTokens(nbt) > 0) 122 | { 123 | for (int i = 0; i < attributes.length; i++) 124 | { 125 | ArrayList list = ArmorAttribute.ARMOR_ATTRIBUTES; 126 | 127 | /* 128 | * Enable Uncommon attributes UNLESS already added to nbt AND are not already tier 3. 129 | * Enable ALL attributes that have already been added UNLESS they are at tier 3. 130 | */ 131 | if (Experience.getAttributeTokens(nbt) == 1) 132 | { 133 | if (list.get(i).getRarity() == Rarity.UNCOMMON && list.get(i).getAttributeTier(nbt) != 3) 134 | attributes[i].enabled = true; 135 | 136 | if (list.get(i).hasAttribute(nbt) && list.get(i).getAttributeTier(nbt) != 3) 137 | attributes[i].enabled = true; 138 | else if (list.get(i).hasAttribute(nbt) && list.get(i).getAttributeTier(nbt) == 3) 139 | attributes[i].enabled = false; 140 | } 141 | 142 | /* 143 | * Enable UNCOMMON AND RARE attributes UNLESS already added to nbt AND are not already tier 3. 144 | * Enable ALL attributes that have already been added UNLESS they are at tier 3. 145 | */ 146 | if (Experience.getAttributeTokens(nbt) == 2) 147 | { 148 | if ((list.get(i).getRarity() == Rarity.RARE || list.get(i).getRarity() == Rarity.UNCOMMON) && !list.get(i).hasAttribute(nbt)) 149 | attributes[i].enabled = true; 150 | 151 | if (list.get(i).hasAttribute(nbt) && list.get(i).getAttributeTier(nbt) != 3) 152 | attributes[i].enabled = true; 153 | else if (list.get(i).hasAttribute(nbt) && list.get(i).getAttributeTier(nbt) == 3) 154 | attributes[i].enabled = false; 155 | } 156 | else 157 | { 158 | if (list.get(i).getRarity() == Rarity.RARE && !list.get(i).hasAttribute(nbt)) 159 | attributes[i].enabled = false; 160 | 161 | if (list.get(i).hasAttribute(nbt) && list.get(i).getAttributeTier(nbt) != 3) 162 | attributes[i].enabled = true; 163 | else if (list.get(i).hasAttribute(nbt) && list.get(i).getAttributeTier(nbt) == 3) 164 | attributes[i].enabled = false; 165 | } 166 | 167 | /* 168 | * Enable ALL attributes UNLESS already added to nbt AND are not already tier 3. 169 | * Enable ALL attributes that have already been added. 170 | */ 171 | if (Experience.getAttributeTokens(nbt) >= 3) 172 | { 173 | if (!list.get(i).hasAttribute(nbt)) 174 | attributes[i].enabled = true; 175 | 176 | if (list.get(i).hasAttribute(nbt) && list.get(i).getAttributeTier(nbt) != 3) 177 | attributes[i].enabled = true; 178 | else if (list.get(i).hasAttribute(nbt) && list.get(i).getAttributeTier(nbt) == 3) 179 | attributes[i].enabled = false; 180 | } 181 | else 182 | { 183 | if (list.get(i).getRarity() == Rarity.LEGENDARY && !list.get(i).hasAttribute(nbt)) 184 | attributes[i].enabled = false; 185 | 186 | if (list.get(i).hasAttribute(nbt) && list.get(i).getAttributeTier(nbt) != 3) 187 | attributes[i].enabled = true; 188 | else if (list.get(i).hasAttribute(nbt) && list.get(i).getAttributeTier(nbt) == 3) 189 | attributes[i].enabled = false; 190 | } 191 | } 192 | } 193 | else 194 | { 195 | for (int i = 0; i < attributes.length; i++) 196 | { 197 | attributes[i].enabled = false; 198 | } 199 | } 200 | } 201 | 202 | private void drawTooltips(NBTTagCompound nbt, int mouseX, int mouseY) 203 | { 204 | for (int i = 0; i < attributes.length; i++) 205 | { 206 | HoverChecker checker = new HoverChecker(attributes[i], 0); 207 | 208 | if (checker.checkHover(mouseX, mouseY)) 209 | { 210 | int cost = 1; 211 | 212 | if (ArmorAttribute.ARMOR_ATTRIBUTES.get(i).getRarity() == Rarity.UNCOMMON && !ArmorAttribute.ARMOR_ATTRIBUTES.get(i).hasAttribute(nbt)) cost = 1; 213 | else if (ArmorAttribute.ARMOR_ATTRIBUTES.get(i).getRarity() == Rarity.RARE && !ArmorAttribute.ARMOR_ATTRIBUTES.get(i).hasAttribute(nbt)) cost = 2; 214 | else if (ArmorAttribute.ARMOR_ATTRIBUTES.get(i).getRarity() == Rarity.LEGENDARY && !ArmorAttribute.ARMOR_ATTRIBUTES.get(i).hasAttribute(nbt)) cost = 3; 215 | else if (ArmorAttribute.ARMOR_ATTRIBUTES.get(i).getAttributeTier(nbt) == 3) cost = 0; 216 | 217 | List list = new ArrayList(); 218 | list.add(ArmorAttribute.ARMOR_ATTRIBUTES.get(i).getColor() + ArmorAttribute.ARMOR_ATTRIBUTES.get(i).getName(nbt)); 219 | list.add(TextFormatting.GRAY + "Cost: " + cost + " token(s)"); 220 | list.add(""); 221 | list.add(I18n.format("levels.attributes.armors.info." + ArmorAttribute.ARMOR_ATTRIBUTES.get(i).ordinal())); 222 | list.add(""); 223 | list.add("Tiers:"); 224 | list.add(" I - " + ArmorAttribute.ARMOR_ATTRIBUTES.get(i).getColor() + I18n.format("levels.attributes.armors.info." + ArmorAttribute.ARMOR_ATTRIBUTES.get(i).ordinal() + ".tier1")); 225 | list.add(" II - " + ArmorAttribute.ARMOR_ATTRIBUTES.get(i).getColor() + I18n.format("levels.attributes.armors.info." + ArmorAttribute.ARMOR_ATTRIBUTES.get(i).ordinal() + ".tier2")); 226 | list.add(" III - " + ArmorAttribute.ARMOR_ATTRIBUTES.get(i).getColor() + I18n.format("levels.attributes.armors.info." + ArmorAttribute.ARMOR_ATTRIBUTES.get(i).ordinal() + ".tier3")); 227 | drawHoveringText(list, mouseX + 3, mouseY + 3); 228 | } 229 | } 230 | } 231 | 232 | @Override 233 | public boolean doesGuiPauseGame() 234 | { 235 | return false; 236 | } 237 | } 238 | -------------------------------------------------------------------------------- /src/main/java/com/thexfactor117/levels/client/gui/selection/GuiBowSelection.java: -------------------------------------------------------------------------------- 1 | package com.thexfactor117.levels.client.gui.selection; 2 | 3 | import java.io.IOException; 4 | import java.util.ArrayList; 5 | import java.util.List; 6 | 7 | import com.thexfactor117.levels.Levels; 8 | import com.thexfactor117.levels.leveling.Experience; 9 | import com.thexfactor117.levels.leveling.Rarity; 10 | import com.thexfactor117.levels.leveling.attributes.BowAttribute; 11 | import com.thexfactor117.levels.network.PacketAttributeSelection; 12 | import com.thexfactor117.levels.util.NBTHelper; 13 | 14 | import net.minecraft.client.entity.EntityPlayerSP; 15 | import net.minecraft.client.gui.GuiButton; 16 | import net.minecraft.client.gui.GuiScreen; 17 | import net.minecraft.client.resources.I18n; 18 | import net.minecraft.entity.player.EntityPlayer; 19 | import net.minecraft.item.ItemBow; 20 | import net.minecraft.item.ItemStack; 21 | import net.minecraft.nbt.NBTTagCompound; 22 | import net.minecraft.util.text.TextFormatting; 23 | import net.minecraftforge.fml.client.config.HoverChecker; 24 | import net.minecraftforge.fml.relauncher.Side; 25 | import net.minecraftforge.fml.relauncher.SideOnly; 26 | 27 | /** 28 | * 29 | * @author TheXFactor117 30 | * 31 | */ 32 | public class GuiBowSelection extends GuiScreen 33 | { 34 | private GuiButton[] attributes; 35 | 36 | @SideOnly(Side.CLIENT) 37 | @Override 38 | public void initGui() 39 | { 40 | EntityPlayer player = this.mc.player; 41 | ItemStack stack = player.inventory.getCurrentItem(); 42 | NBTTagCompound nbt = NBTHelper.loadStackNBT(stack); 43 | 44 | if (player != null && stack != null && nbt != null && stack.getItem() instanceof ItemBow) 45 | { 46 | attributes = new GuiButton[BowAttribute.BOW_ATTRIBUTES.size()]; 47 | 48 | for (int i = 0; i < attributes.length; i++) 49 | { 50 | attributes[i] = new GuiButton(i, width / 2 - 147, 60 + (i * 20), 75, 20, BowAttribute.BOW_ATTRIBUTES.get(i).getName(nbt)); 51 | this.buttonList.add(attributes[i]); 52 | attributes[i].enabled = false; 53 | } 54 | } 55 | } 56 | 57 | @SideOnly(Side.CLIENT) 58 | @Override 59 | public void drawScreen(int mouseX, int mouseY, float partialTicks) 60 | { 61 | this.drawDefaultBackground(); 62 | super.drawScreen(mouseX, mouseY, partialTicks); 63 | 64 | EntityPlayer player = this.mc.player; 65 | ItemStack stack = player.inventory.getCurrentItem(); 66 | NBTTagCompound nbt = NBTHelper.loadStackNBT(stack); 67 | 68 | if (player != null && stack != null && nbt != null && stack.getItem() instanceof ItemBow) 69 | { 70 | drawCenteredString(fontRendererObj, I18n.format("levels.misc.attributes"), width / 2, 20, 0xFFFFFF); 71 | drawCenteredString(fontRendererObj, I18n.format("levels.misc.attributes.tokens") + ": " + Experience.getAttributeTokens(nbt), width / 2 - 112, 40, 0xFFFFFF); 72 | drawCenteredString(fontRendererObj, I18n.format("levels.misc.attributes.current"), width / 2 + 112, 40, 0xFFFFFF); 73 | 74 | int k = -1; 75 | 76 | for (int i = 0; i < BowAttribute.BOW_ATTRIBUTES.size(); i++) 77 | { 78 | if (BowAttribute.BOW_ATTRIBUTES.get(i).hasAttribute(nbt)) 79 | { 80 | k++; 81 | drawCenteredString(fontRendererObj, BowAttribute.BOW_ATTRIBUTES.get(i).getName(nbt), width / 2 + 112, 60 + (10 * k), BowAttribute.BOW_ATTRIBUTES.get(i).getHex()); 82 | } 83 | } 84 | 85 | displayButtons(nbt); 86 | drawTooltips(nbt, mouseX, mouseY); 87 | } 88 | } 89 | 90 | @SideOnly(Side.CLIENT) 91 | @Override 92 | protected void actionPerformed(GuiButton button) throws IOException 93 | { 94 | EntityPlayerSP player = mc.player; 95 | ItemStack stack = player.inventory.getCurrentItem(); 96 | NBTTagCompound nbt = NBTHelper.loadStackNBT(stack); 97 | 98 | if (player != null && stack != null && nbt != null) 99 | { 100 | if (Experience.getAttributeTokens(nbt) > 0) 101 | { 102 | if (stack.getItem() instanceof ItemBow) 103 | { 104 | for (int i = 0; i < attributes.length; i++) 105 | { 106 | if (button == attributes[i]) 107 | Levels.network.sendToServer(new PacketAttributeSelection(i)); 108 | } 109 | } 110 | } 111 | } 112 | } 113 | 114 | /** 115 | * Determines which buttons need to be enabled. 116 | * @param buttons 117 | * @param nbt 118 | */ 119 | private void displayButtons(NBTTagCompound nbt) 120 | { 121 | if (Experience.getAttributeTokens(nbt) > 0) 122 | { 123 | for (int i = 0; i < attributes.length; i++) 124 | { 125 | ArrayList list = BowAttribute.BOW_ATTRIBUTES; 126 | 127 | /* 128 | * Enable Uncommon attributes UNLESS already added to nbt AND are not already tier 3. 129 | * Enable ALL attributes that have already been added UNLESS they are at tier 3. 130 | */ 131 | if (Experience.getAttributeTokens(nbt) == 1) 132 | { 133 | if (list.get(i).getRarity() == Rarity.UNCOMMON && list.get(i).getAttributeTier(nbt) != 3) 134 | attributes[i].enabled = true; 135 | 136 | if (list.get(i).hasAttribute(nbt) && list.get(i).getAttributeTier(nbt) != 3) 137 | attributes[i].enabled = true; 138 | else if (list.get(i).hasAttribute(nbt) && list.get(i).getAttributeTier(nbt) == 3) 139 | attributes[i].enabled = false; 140 | } 141 | 142 | /* 143 | * Enable UNCOMMON AND RARE attributes UNLESS already added to nbt AND are not already tier 3. 144 | * Enable ALL attributes that have already been added UNLESS they are at tier 3. 145 | */ 146 | if (Experience.getAttributeTokens(nbt) == 2) 147 | { 148 | if ((list.get(i).getRarity() == Rarity.RARE || list.get(i).getRarity() == Rarity.UNCOMMON) && !list.get(i).hasAttribute(nbt)) 149 | attributes[i].enabled = true; 150 | 151 | if (list.get(i).hasAttribute(nbt) && list.get(i).getAttributeTier(nbt) != 3) 152 | attributes[i].enabled = true; 153 | else if (list.get(i).hasAttribute(nbt) && list.get(i).getAttributeTier(nbt) == 3) 154 | attributes[i].enabled = false; 155 | } 156 | else 157 | { 158 | if (list.get(i).getRarity() == Rarity.RARE && !list.get(i).hasAttribute(nbt)) 159 | attributes[i].enabled = false; 160 | 161 | if (list.get(i).hasAttribute(nbt) && list.get(i).getAttributeTier(nbt) != 3) 162 | attributes[i].enabled = true; 163 | else if (list.get(i).hasAttribute(nbt) && list.get(i).getAttributeTier(nbt) == 3) 164 | attributes[i].enabled = false; 165 | } 166 | 167 | /* 168 | * Enable ALL attributes UNLESS already added to nbt AND are not already tier 3. 169 | * Enable ALL attributes that have already been added. 170 | */ 171 | if (Experience.getAttributeTokens(nbt) >= 3) 172 | { 173 | if (!list.get(i).hasAttribute(nbt)) 174 | attributes[i].enabled = true; 175 | 176 | if (list.get(i).hasAttribute(nbt) && list.get(i).getAttributeTier(nbt) != 3) 177 | attributes[i].enabled = true; 178 | else if (list.get(i).hasAttribute(nbt) && list.get(i).getAttributeTier(nbt) == 3) 179 | attributes[i].enabled = false; 180 | } 181 | else 182 | { 183 | if (list.get(i).getRarity() == Rarity.LEGENDARY && !list.get(i).hasAttribute(nbt)) 184 | attributes[i].enabled = false; 185 | 186 | if (list.get(i).hasAttribute(nbt) && list.get(i).getAttributeTier(nbt) != 3) 187 | attributes[i].enabled = true; 188 | else if (list.get(i).hasAttribute(nbt) && list.get(i).getAttributeTier(nbt) == 3) 189 | attributes[i].enabled = false; 190 | } 191 | } 192 | } 193 | else 194 | { 195 | for (int i = 0; i < attributes.length; i++) 196 | { 197 | attributes[i].enabled = false; 198 | } 199 | } 200 | } 201 | 202 | private void drawTooltips(NBTTagCompound nbt, int mouseX, int mouseY) 203 | { 204 | for (int i = 0; i < attributes.length; i++) 205 | { 206 | HoverChecker checker = new HoverChecker(attributes[i], 0); 207 | 208 | if (checker.checkHover(mouseX, mouseY)) 209 | { 210 | int cost = 1; 211 | 212 | if (BowAttribute.BOW_ATTRIBUTES.get(i).getRarity() == Rarity.UNCOMMON && !BowAttribute.BOW_ATTRIBUTES.get(i).hasAttribute(nbt)) cost = 1; 213 | else if (BowAttribute.BOW_ATTRIBUTES.get(i).getRarity() == Rarity.RARE && !BowAttribute.BOW_ATTRIBUTES.get(i).hasAttribute(nbt)) cost = 2; 214 | else if (BowAttribute.BOW_ATTRIBUTES.get(i).getRarity() == Rarity.LEGENDARY && !BowAttribute.BOW_ATTRIBUTES.get(i).hasAttribute(nbt)) cost = 3; 215 | else if (BowAttribute.BOW_ATTRIBUTES.get(i).getAttributeTier(nbt) == 3) cost = 0; 216 | 217 | List list = new ArrayList(); 218 | list.add(BowAttribute.BOW_ATTRIBUTES.get(i).getColor() + BowAttribute.BOW_ATTRIBUTES.get(i).getName(nbt)); 219 | list.add(TextFormatting.GRAY + "Cost: " + cost + " token(s)"); 220 | list.add(""); 221 | list.add(I18n.format("levels.attributes.bows.info." + BowAttribute.BOW_ATTRIBUTES.get(i).ordinal())); 222 | list.add(""); 223 | list.add("Tiers:"); 224 | list.add(" I - " + BowAttribute.BOW_ATTRIBUTES.get(i).getColor() + I18n.format("levels.attributes.bows.info." + BowAttribute.BOW_ATTRIBUTES.get(i).ordinal() + ".tier1")); 225 | list.add(" II - " + BowAttribute.BOW_ATTRIBUTES.get(i).getColor() + I18n.format("levels.attributes.bows.info." + BowAttribute.BOW_ATTRIBUTES.get(i).ordinal() + ".tier2")); 226 | list.add(" III - " + BowAttribute.BOW_ATTRIBUTES.get(i).getColor() + I18n.format("levels.attributes.bows.info." + BowAttribute.BOW_ATTRIBUTES.get(i).ordinal() + ".tier3")); 227 | drawHoveringText(list, mouseX + 3, mouseY + 3); 228 | } 229 | } 230 | } 231 | 232 | @Override 233 | public boolean doesGuiPauseGame() 234 | { 235 | return false; 236 | } 237 | } 238 | -------------------------------------------------------------------------------- /src/main/java/com/thexfactor117/levels/client/gui/selection/GuiShieldSelection.java: -------------------------------------------------------------------------------- 1 | package com.thexfactor117.levels.client.gui.selection; 2 | 3 | import java.io.IOException; 4 | import java.util.ArrayList; 5 | import java.util.List; 6 | 7 | import com.thexfactor117.levels.Levels; 8 | import com.thexfactor117.levels.leveling.Experience; 9 | import com.thexfactor117.levels.leveling.Rarity; 10 | import com.thexfactor117.levels.leveling.attributes.BowAttribute; 11 | import com.thexfactor117.levels.leveling.attributes.ShieldAttribute; 12 | import com.thexfactor117.levels.network.PacketAttributeSelection; 13 | import com.thexfactor117.levels.util.NBTHelper; 14 | 15 | import net.minecraft.client.entity.EntityPlayerSP; 16 | import net.minecraft.client.gui.GuiButton; 17 | import net.minecraft.client.gui.GuiScreen; 18 | import net.minecraft.client.resources.I18n; 19 | import net.minecraft.entity.player.EntityPlayer; 20 | import net.minecraft.item.ItemShield; 21 | import net.minecraft.item.ItemStack; 22 | import net.minecraft.nbt.NBTTagCompound; 23 | import net.minecraft.util.text.TextFormatting; 24 | import net.minecraftforge.fml.client.config.HoverChecker; 25 | import net.minecraftforge.fml.relauncher.Side; 26 | import net.minecraftforge.fml.relauncher.SideOnly; 27 | 28 | /** 29 | * 30 | * @author TheXFactor117 31 | * 32 | */ 33 | public class GuiShieldSelection extends GuiScreen 34 | { 35 | private GuiButton[] attributes; 36 | 37 | @SideOnly(Side.CLIENT) 38 | @Override 39 | public void initGui() 40 | { 41 | EntityPlayer player = this.mc.player; 42 | ItemStack stack = player.inventory.getCurrentItem(); 43 | NBTTagCompound nbt = NBTHelper.loadStackNBT(stack); 44 | 45 | if (player != null && stack != null && nbt != null && stack.getItem() instanceof ItemShield) 46 | { 47 | attributes = new GuiButton[ShieldAttribute.SHIELD_ATTRIBUTES.size()]; 48 | 49 | for (int i = 0; i < attributes.length; i++) 50 | { 51 | attributes[i] = new GuiButton(i, width / 2 - 147, 60 + (i * 20), 75, 20, ShieldAttribute.SHIELD_ATTRIBUTES.get(i).getName(nbt)); 52 | this.buttonList.add(attributes[i]); 53 | attributes[i].enabled = false; 54 | } 55 | } 56 | } 57 | 58 | @SideOnly(Side.CLIENT) 59 | @Override 60 | public void drawScreen(int mouseX, int mouseY, float partialTicks) 61 | { 62 | this.drawDefaultBackground(); 63 | super.drawScreen(mouseX, mouseY, partialTicks); 64 | 65 | EntityPlayer player = this.mc.player; 66 | ItemStack stack = player.inventory.getCurrentItem(); 67 | NBTTagCompound nbt = NBTHelper.loadStackNBT(stack); 68 | 69 | if (player != null && stack != null && nbt != null && stack.getItem() instanceof ItemShield) 70 | { 71 | drawCenteredString(fontRendererObj, I18n.format("levels.misc.attributes"), width / 2, 20, 0xFFFFFF); 72 | drawCenteredString(fontRendererObj, I18n.format("levels.misc.attributes.tokens") + ": " + Experience.getAttributeTokens(nbt), width / 2 - 112, 40, 0xFFFFFF); 73 | drawCenteredString(fontRendererObj, I18n.format("levels.misc.attributes.current"), width / 2 + 112, 40, 0xFFFFFF); 74 | 75 | int k = -1; 76 | 77 | for (int i = 0; i < BowAttribute.BOW_ATTRIBUTES.size(); i++) 78 | { 79 | if (BowAttribute.BOW_ATTRIBUTES.get(i).hasAttribute(nbt)) 80 | { 81 | k++; 82 | drawCenteredString(fontRendererObj, BowAttribute.BOW_ATTRIBUTES.get(i).getName(nbt), width / 2 + 112, 60 + (10 * k), BowAttribute.BOW_ATTRIBUTES.get(i).getHex()); 83 | } 84 | } 85 | 86 | displayButtons(nbt); 87 | drawTooltips(nbt, mouseX, mouseY); 88 | } 89 | } 90 | 91 | @SideOnly(Side.CLIENT) 92 | @Override 93 | protected void actionPerformed(GuiButton button) throws IOException 94 | { 95 | EntityPlayerSP player = mc.player; 96 | ItemStack stack = player.inventory.getCurrentItem(); 97 | NBTTagCompound nbt = NBTHelper.loadStackNBT(stack); 98 | 99 | if (player != null && stack != null && nbt != null) 100 | { 101 | if (Experience.getAttributeTokens(nbt) > 0) 102 | { 103 | if (stack.getItem() instanceof ItemShield) 104 | { 105 | for (int i = 0; i < attributes.length; i++) 106 | { 107 | if (button == attributes[i]) 108 | Levels.network.sendToServer(new PacketAttributeSelection(i)); 109 | } 110 | } 111 | } 112 | } 113 | } 114 | 115 | /** 116 | * Determines which buttons need to be enabled. 117 | * @param buttons 118 | * @param nbt 119 | */ 120 | private void displayButtons(NBTTagCompound nbt) 121 | { 122 | if (Experience.getAttributeTokens(nbt) > 0) 123 | { 124 | for (int i = 0; i < attributes.length; i++) 125 | { 126 | ArrayList list = ShieldAttribute.SHIELD_ATTRIBUTES; 127 | 128 | /* 129 | * Enable Uncommon attributes UNLESS already added to nbt AND are not already tier 3. 130 | * Enable ALL attributes that have already been added UNLESS they are at tier 3. 131 | */ 132 | if (Experience.getAttributeTokens(nbt) == 1) 133 | { 134 | if (list.get(i).getRarity() == Rarity.UNCOMMON && list.get(i).getAttributeTier(nbt) != 3) 135 | attributes[i].enabled = true; 136 | 137 | if (list.get(i).hasAttribute(nbt) && list.get(i).getAttributeTier(nbt) != 3) 138 | attributes[i].enabled = true; 139 | else if (list.get(i).hasAttribute(nbt) && list.get(i).getAttributeTier(nbt) == 3) 140 | attributes[i].enabled = false; 141 | } 142 | 143 | /* 144 | * Enable UNCOMMON AND RARE attributes UNLESS already added to nbt AND are not already tier 3. 145 | * Enable ALL attributes that have already been added UNLESS they are at tier 3. 146 | */ 147 | if (Experience.getAttributeTokens(nbt) == 2) 148 | { 149 | if ((list.get(i).getRarity() == Rarity.RARE || list.get(i).getRarity() == Rarity.UNCOMMON) && !list.get(i).hasAttribute(nbt)) 150 | attributes[i].enabled = true; 151 | 152 | if (list.get(i).hasAttribute(nbt) && list.get(i).getAttributeTier(nbt) != 3) 153 | attributes[i].enabled = true; 154 | else if (list.get(i).hasAttribute(nbt) && list.get(i).getAttributeTier(nbt) == 3) 155 | attributes[i].enabled = false; 156 | } 157 | else 158 | { 159 | if (list.get(i).getRarity() == Rarity.RARE && !list.get(i).hasAttribute(nbt)) 160 | attributes[i].enabled = false; 161 | 162 | if (list.get(i).hasAttribute(nbt) && list.get(i).getAttributeTier(nbt) != 3) 163 | attributes[i].enabled = true; 164 | else if (list.get(i).hasAttribute(nbt) && list.get(i).getAttributeTier(nbt) == 3) 165 | attributes[i].enabled = false; 166 | } 167 | 168 | /* 169 | * Enable ALL attributes UNLESS already added to nbt AND are not already tier 3. 170 | * Enable ALL attributes that have already been added. 171 | */ 172 | if (Experience.getAttributeTokens(nbt) >= 3) 173 | { 174 | if (!list.get(i).hasAttribute(nbt)) 175 | attributes[i].enabled = true; 176 | 177 | if (list.get(i).hasAttribute(nbt) && list.get(i).getAttributeTier(nbt) != 3) 178 | attributes[i].enabled = true; 179 | else if (list.get(i).hasAttribute(nbt) && list.get(i).getAttributeTier(nbt) == 3) 180 | attributes[i].enabled = false; 181 | } 182 | else 183 | { 184 | if (list.get(i).getRarity() == Rarity.LEGENDARY && !list.get(i).hasAttribute(nbt)) 185 | attributes[i].enabled = false; 186 | 187 | if (list.get(i).hasAttribute(nbt) && list.get(i).getAttributeTier(nbt) != 3) 188 | attributes[i].enabled = true; 189 | else if (list.get(i).hasAttribute(nbt) && list.get(i).getAttributeTier(nbt) == 3) 190 | attributes[i].enabled = false; 191 | } 192 | } 193 | } 194 | else 195 | { 196 | for (int i = 0; i < attributes.length; i++) 197 | { 198 | attributes[i].enabled = false; 199 | } 200 | } 201 | } 202 | 203 | private void drawTooltips(NBTTagCompound nbt, int mouseX, int mouseY) 204 | { 205 | for (int i = 0; i < attributes.length; i++) 206 | { 207 | HoverChecker checker = new HoverChecker(attributes[i], 0); 208 | 209 | if (checker.checkHover(mouseX, mouseY)) 210 | { 211 | int cost = 1; 212 | 213 | if (ShieldAttribute.SHIELD_ATTRIBUTES.get(i).getRarity() == Rarity.UNCOMMON && !ShieldAttribute.SHIELD_ATTRIBUTES.get(i).hasAttribute(nbt)) cost = 1; 214 | else if (ShieldAttribute.SHIELD_ATTRIBUTES.get(i).getRarity() == Rarity.RARE && !ShieldAttribute.SHIELD_ATTRIBUTES.get(i).hasAttribute(nbt)) cost = 2; 215 | else if (ShieldAttribute.SHIELD_ATTRIBUTES.get(i).getRarity() == Rarity.LEGENDARY && !ShieldAttribute.SHIELD_ATTRIBUTES.get(i).hasAttribute(nbt)) cost = 3; 216 | else if (ShieldAttribute.SHIELD_ATTRIBUTES.get(i).getAttributeTier(nbt) == 3) cost = 0; 217 | 218 | List list = new ArrayList(); 219 | list.add(ShieldAttribute.SHIELD_ATTRIBUTES.get(i).getColor() + ShieldAttribute.SHIELD_ATTRIBUTES.get(i).getName(nbt)); 220 | list.add(TextFormatting.GRAY + "Cost: " + cost + " token(s)"); 221 | list.add(""); 222 | list.add(I18n.format("levels.attributes.shields.info." + ShieldAttribute.SHIELD_ATTRIBUTES.get(i).ordinal())); 223 | list.add(""); 224 | list.add("Tiers:"); 225 | list.add(" I - " + ShieldAttribute.SHIELD_ATTRIBUTES.get(i).getColor() + I18n.format("levels.attributes.shields.info." + ShieldAttribute.SHIELD_ATTRIBUTES.get(i).ordinal() + ".tier1")); 226 | list.add(" II - " + ShieldAttribute.SHIELD_ATTRIBUTES.get(i).getColor() + I18n.format("levels.attributes.shields.info." + ShieldAttribute.SHIELD_ATTRIBUTES.get(i).ordinal() + ".tier2")); 227 | list.add(" III - " + ShieldAttribute.SHIELD_ATTRIBUTES.get(i).getColor() + I18n.format("levels.attributes.shields.info." + ShieldAttribute.SHIELD_ATTRIBUTES.get(i).ordinal() + ".tier3")); 228 | drawHoveringText(list, mouseX + 3, mouseY + 3); 229 | } 230 | } 231 | } 232 | 233 | @Override 234 | public boolean doesGuiPauseGame() 235 | { 236 | return false; 237 | } 238 | } 239 | -------------------------------------------------------------------------------- /src/main/java/com/thexfactor117/levels/client/gui/selection/GuiWeaponSelection.java: -------------------------------------------------------------------------------- 1 | package com.thexfactor117.levels.client.gui.selection; 2 | 3 | import java.io.IOException; 4 | import java.util.ArrayList; 5 | import java.util.List; 6 | 7 | import com.thexfactor117.levels.Levels; 8 | import com.thexfactor117.levels.leveling.Experience; 9 | import com.thexfactor117.levels.leveling.Rarity; 10 | import com.thexfactor117.levels.leveling.attributes.WeaponAttribute; 11 | import com.thexfactor117.levels.network.PacketAttributeSelection; 12 | import com.thexfactor117.levels.util.NBTHelper; 13 | 14 | import net.minecraft.client.entity.EntityPlayerSP; 15 | import net.minecraft.client.gui.GuiButton; 16 | import net.minecraft.client.gui.GuiScreen; 17 | import net.minecraft.client.resources.I18n; 18 | import net.minecraft.entity.player.EntityPlayer; 19 | import net.minecraft.item.ItemStack; 20 | import net.minecraft.item.ItemSword; 21 | import net.minecraft.nbt.NBTTagCompound; 22 | import net.minecraft.util.text.TextFormatting; 23 | import net.minecraftforge.fml.client.config.HoverChecker; 24 | import net.minecraftforge.fml.relauncher.Side; 25 | import net.minecraftforge.fml.relauncher.SideOnly; 26 | 27 | /** 28 | * 29 | * @author TheXFactor117 30 | * 31 | */ 32 | public class GuiWeaponSelection extends GuiScreen 33 | { 34 | private GuiButton[] attributes; 35 | 36 | @SideOnly(Side.CLIENT) 37 | @Override 38 | public void initGui() 39 | { 40 | EntityPlayer player = this.mc.player; 41 | ItemStack stack = player.inventory.getCurrentItem(); 42 | NBTTagCompound nbt = NBTHelper.loadStackNBT(stack); 43 | 44 | if (player != null && stack != null && nbt != null && stack.getItem() instanceof ItemSword) 45 | { 46 | attributes = new GuiButton[WeaponAttribute.WEAPON_ATTRIBUTES.size()]; 47 | 48 | for (int i = 0; i < attributes.length; i++) 49 | { 50 | attributes[i] = new GuiButton(i, width / 2 - 147, 60 + (i * 20), 75, 20, WeaponAttribute.WEAPON_ATTRIBUTES.get(i).getName(nbt)); 51 | this.buttonList.add(attributes[i]); 52 | attributes[i].enabled = false; 53 | } 54 | } 55 | } 56 | 57 | @SideOnly(Side.CLIENT) 58 | @Override 59 | public void drawScreen(int mouseX, int mouseY, float partialTicks) 60 | { 61 | this.drawDefaultBackground(); 62 | super.drawScreen(mouseX, mouseY, partialTicks); 63 | 64 | EntityPlayer player = this.mc.player; 65 | ItemStack stack = player.inventory.getCurrentItem(); 66 | NBTTagCompound nbt = NBTHelper.loadStackNBT(stack); 67 | 68 | if (player != null && stack != null && nbt != null && stack.getItem() instanceof ItemSword) 69 | { 70 | drawCenteredString(fontRendererObj, I18n.format("levels.misc.attributes"), width / 2, 20, 0xFFFFFF); 71 | drawCenteredString(fontRendererObj, I18n.format("levels.misc.attributes.tokens") + ": " + Experience.getAttributeTokens(nbt), width / 2 - 112, 40, 0xFFFFFF); 72 | drawCenteredString(fontRendererObj, I18n.format("levels.misc.attributes.current"), width / 2 + 112, 40, 0xFFFFFF); 73 | 74 | int k = -1; 75 | 76 | for (int i = 0; i < WeaponAttribute.WEAPON_ATTRIBUTES.size(); i++) 77 | { 78 | if (WeaponAttribute.WEAPON_ATTRIBUTES.get(i).hasAttribute(nbt)) 79 | { 80 | k++; 81 | drawCenteredString(fontRendererObj, WeaponAttribute.WEAPON_ATTRIBUTES.get(i).getName(nbt), width / 2 + 112, 60 + (10 * k), WeaponAttribute.WEAPON_ATTRIBUTES.get(i).getHex()); 82 | } 83 | } 84 | 85 | displayButtons(nbt); 86 | drawTooltips(nbt, mouseX, mouseY); 87 | } 88 | } 89 | 90 | @SideOnly(Side.CLIENT) 91 | @Override 92 | protected void actionPerformed(GuiButton button) throws IOException 93 | { 94 | EntityPlayerSP player = mc.player; 95 | ItemStack stack = player.inventory.getCurrentItem(); 96 | NBTTagCompound nbt = NBTHelper.loadStackNBT(stack); 97 | 98 | if (player != null && stack != null && nbt != null) 99 | { 100 | if (Experience.getAttributeTokens(nbt) > 0) 101 | { 102 | if (stack.getItem() instanceof ItemSword) 103 | { 104 | for (int i = 0; i < attributes.length; i++) 105 | { 106 | if (button == attributes[i]) 107 | { 108 | Levels.network.sendToServer(new PacketAttributeSelection(i)); 109 | } 110 | } 111 | } 112 | } 113 | } 114 | } 115 | 116 | /** 117 | * Determines which buttons need to be enabled. 118 | * @param buttons 119 | * @param nbt 120 | */ 121 | private void displayButtons(NBTTagCompound nbt) 122 | { 123 | if (Experience.getAttributeTokens(nbt) > 0) 124 | { 125 | for (int i = 0; i < attributes.length; i++) 126 | { 127 | ArrayList list = WeaponAttribute.WEAPON_ATTRIBUTES; 128 | 129 | /* 130 | * Enable Uncommon attributes UNLESS already added to nbt AND are not already tier 3. 131 | * Enable ALL attributes that have already been added UNLESS they are at tier 3. 132 | */ 133 | if (Experience.getAttributeTokens(nbt) == 1) 134 | { 135 | if (list.get(i).getRarity() == Rarity.UNCOMMON && list.get(i).getAttributeTier(nbt) != 3) 136 | attributes[i].enabled = true; 137 | 138 | if (list.get(i).hasAttribute(nbt) && list.get(i).getAttributeTier(nbt) != 3) 139 | attributes[i].enabled = true; 140 | else if (list.get(i).hasAttribute(nbt) && list.get(i).getAttributeTier(nbt) == 3) 141 | attributes[i].enabled = false; 142 | } 143 | 144 | /* 145 | * Enable UNCOMMON AND RARE attributes UNLESS already added to nbt AND are not already tier 3. 146 | * Enable ALL attributes that have already been added UNLESS they are at tier 3. 147 | */ 148 | if (Experience.getAttributeTokens(nbt) == 2) 149 | { 150 | if ((list.get(i).getRarity() == Rarity.RARE || list.get(i).getRarity() == Rarity.UNCOMMON) && !list.get(i).hasAttribute(nbt)) 151 | attributes[i].enabled = true; 152 | 153 | if (list.get(i).hasAttribute(nbt) && list.get(i).getAttributeTier(nbt) != 3) 154 | attributes[i].enabled = true; 155 | else if (list.get(i).hasAttribute(nbt) && list.get(i).getAttributeTier(nbt) == 3) 156 | attributes[i].enabled = false; 157 | } 158 | else 159 | { 160 | if (list.get(i).getRarity() == Rarity.RARE && !list.get(i).hasAttribute(nbt)) 161 | attributes[i].enabled = false; 162 | 163 | if (list.get(i).hasAttribute(nbt) && list.get(i).getAttributeTier(nbt) != 3) 164 | attributes[i].enabled = true; 165 | else if (list.get(i).hasAttribute(nbt) && list.get(i).getAttributeTier(nbt) == 3) 166 | attributes[i].enabled = false; 167 | } 168 | 169 | /* 170 | * Enable ALL attributes UNLESS already added to nbt AND are not already tier 3. 171 | * Enable ALL attributes that have already been added. 172 | */ 173 | if (Experience.getAttributeTokens(nbt) >= 3) 174 | { 175 | if (!list.get(i).hasAttribute(nbt)) 176 | attributes[i].enabled = true; 177 | 178 | if (list.get(i).hasAttribute(nbt) && list.get(i).getAttributeTier(nbt) != 3) 179 | attributes[i].enabled = true; 180 | else if (list.get(i).hasAttribute(nbt) && list.get(i).getAttributeTier(nbt) == 3) 181 | attributes[i].enabled = false; 182 | } 183 | else 184 | { 185 | if (list.get(i).getRarity() == Rarity.LEGENDARY && !list.get(i).hasAttribute(nbt)) 186 | attributes[i].enabled = false; 187 | 188 | if (list.get(i).hasAttribute(nbt) && list.get(i).getAttributeTier(nbt) != 3) 189 | attributes[i].enabled = true; 190 | else if (list.get(i).hasAttribute(nbt) && list.get(i).getAttributeTier(nbt) == 3) 191 | attributes[i].enabled = false; 192 | } 193 | } 194 | } 195 | else 196 | { 197 | for (int i = 0; i < attributes.length; i++) 198 | { 199 | attributes[i].enabled = false; 200 | } 201 | } 202 | } 203 | 204 | private void drawTooltips(NBTTagCompound nbt, int mouseX, int mouseY) 205 | { 206 | for (int i = 0; i < attributes.length; i++) 207 | { 208 | HoverChecker checker = new HoverChecker(attributes[i], 0); 209 | 210 | if (checker.checkHover(mouseX, mouseY)) 211 | { 212 | int cost = 1; 213 | 214 | if (WeaponAttribute.WEAPON_ATTRIBUTES.get(i).getRarity() == Rarity.UNCOMMON && !WeaponAttribute.WEAPON_ATTRIBUTES.get(i).hasAttribute(nbt)) cost = 1; 215 | else if (WeaponAttribute.WEAPON_ATTRIBUTES.get(i).getRarity() == Rarity.RARE && !WeaponAttribute.WEAPON_ATTRIBUTES.get(i).hasAttribute(nbt)) cost = 2; 216 | else if (WeaponAttribute.WEAPON_ATTRIBUTES.get(i).getRarity() == Rarity.LEGENDARY && !WeaponAttribute.WEAPON_ATTRIBUTES.get(i).hasAttribute(nbt)) cost = 3; 217 | else if (WeaponAttribute.WEAPON_ATTRIBUTES.get(i).getAttributeTier(nbt) == 3) cost = 0; 218 | 219 | List list = new ArrayList(); 220 | list.add(WeaponAttribute.WEAPON_ATTRIBUTES.get(i).getColor() + WeaponAttribute.WEAPON_ATTRIBUTES.get(i).getName(nbt)); 221 | list.add(TextFormatting.GRAY + "Cost: " + cost + " token(s)"); 222 | list.add(""); 223 | list.add(I18n.format("levels.attributes.weapons.info." + WeaponAttribute.WEAPON_ATTRIBUTES.get(i).ordinal())); 224 | list.add(""); 225 | list.add("Tiers:"); 226 | list.add(" I - " + WeaponAttribute.WEAPON_ATTRIBUTES.get(i).getColor() + I18n.format("levels.attributes.weapons.info." + WeaponAttribute.WEAPON_ATTRIBUTES.get(i).ordinal() + ".tier1")); 227 | list.add(" II - " + WeaponAttribute.WEAPON_ATTRIBUTES.get(i).getColor() + I18n.format("levels.attributes.weapons.info." + WeaponAttribute.WEAPON_ATTRIBUTES.get(i).ordinal() + ".tier2")); 228 | list.add(" III - " + WeaponAttribute.WEAPON_ATTRIBUTES.get(i).getColor() + I18n.format("levels.attributes.weapons.info." + WeaponAttribute.WEAPON_ATTRIBUTES.get(i).ordinal() + ".tier3")); 229 | drawHoveringText(list, mouseX + 3, mouseY + 3); 230 | } 231 | } 232 | } 233 | 234 | @Override 235 | public boolean doesGuiPauseGame() 236 | { 237 | return false; 238 | } 239 | } 240 | -------------------------------------------------------------------------------- /src/main/java/com/thexfactor117/levels/config/Config.java: -------------------------------------------------------------------------------- 1 | package com.thexfactor117.levels.config; 2 | 3 | import java.io.File; 4 | import java.util.List; 5 | 6 | import com.google.common.collect.Lists; 7 | 8 | import net.minecraftforge.common.config.Configuration; 9 | import net.minecraftforge.common.config.Property; 10 | 11 | /** 12 | * 13 | * @author TheXFactor117 14 | * 15 | */ 16 | public class Config 17 | { 18 | // configuration files 19 | private static Configuration main; 20 | private static Configuration attributes; 21 | 22 | /* 23 | * MAIN 24 | */ 25 | 26 | // experience 27 | public static double maxLevel = 10; 28 | public static double expExponent = 2.1F; 29 | public static int expMultiplier = 20; 30 | 31 | // miscellaneous 32 | public static String[] itemBlacklist = new String[] { "modid:item" }; 33 | public static boolean unlimitedDurability = false; 34 | 35 | /* 36 | * ATTRIBUTES 37 | */ 38 | 39 | // weapon 40 | public static boolean weaponFire = true; 41 | public static boolean weaponFrost = true; 42 | public static boolean weaponPoison = true; 43 | public static boolean weaponDurable = true; 44 | public static boolean weaponAbsorb = true; 45 | public static boolean weaponSoulBound = true; 46 | public static boolean weaponBloodlust = true; 47 | public static boolean weaponCritical = true; 48 | public static boolean weaponChained = true; 49 | public static boolean weaponUnbreakable = true; 50 | public static boolean weaponVoid = true; 51 | 52 | // armor 53 | public static boolean armorFire = true; 54 | public static boolean armorFrost = true; 55 | public static boolean armorPoison = true; 56 | public static boolean armorDurable = true; 57 | public static boolean armorMagical = true; 58 | public static boolean armorSoulBound = true; 59 | public static boolean armorUnbreakable = true; 60 | 61 | // bow 62 | public static boolean bowFire = true; 63 | public static boolean bowFrost = true; 64 | public static boolean bowPoison = true; 65 | public static boolean bowDurable = true; 66 | public static boolean bowAbsorb = true; 67 | public static boolean bowSoulBound = true; 68 | public static boolean bowCritical = true; 69 | public static boolean bowRecover = true; 70 | public static boolean bowBarrage = true; 71 | public static boolean bowUnbreakable = true; 72 | public static boolean bowVoid = true; 73 | 74 | // shield 75 | public static boolean shieldFire = true; 76 | public static boolean shieldFrost = true; 77 | public static boolean shieldPoison = true; 78 | public static boolean shieldDurable = true; 79 | public static boolean shieldSoulBound = true; 80 | public static boolean shieldUnbreakable = true; 81 | 82 | public static void init(File dir) 83 | { 84 | main = new Configuration(new File(dir.getPath(), "levels.cfg")); 85 | attributes = new Configuration(new File(dir.getPath(), "levels_attributes.cfg")); 86 | sync(); 87 | } 88 | 89 | private static void sync() 90 | { 91 | syncMain(); 92 | syncAttributes(); 93 | } 94 | 95 | private static void syncMain() 96 | { 97 | String category = "main"; 98 | List propOrder = Lists.newArrayList(); 99 | Property prop; 100 | 101 | /* 102 | * Experience 103 | */ 104 | prop = main.get(category, "maxLevel", maxLevel); 105 | prop.setComment("Determines the max level of weapons and armor."); 106 | maxLevel = prop.getDouble(); 107 | propOrder.add(prop.getName()); 108 | 109 | prop = main.get(category, "experienceExponent", expExponent); 110 | prop.setComment("Sets the exponent of the experience algorithm."); 111 | expExponent = prop.getDouble(); 112 | propOrder.add(prop.getName()); 113 | 114 | prop = main.get(category, "experienceMultiplier", expMultiplier); 115 | prop.setComment("Sets the multiplier of the experience algorithm."); 116 | expMultiplier = prop.getInt(); 117 | propOrder.add(prop.getName()); 118 | 119 | /* 120 | * Miscellaneous 121 | */ 122 | prop = main.get(category, "itemBlacklist", itemBlacklist); 123 | prop.setComment("Items in this blacklist will not gain the leveling systems. Useful for very powerful items or potential conflicts. Style should be 'modid:item'"); 124 | itemBlacklist = prop.getStringList(); 125 | propOrder.add(prop.getName()); 126 | 127 | prop = main.get(category, "unlimitedDurability", unlimitedDurability); 128 | prop.setComment("Determines whether or not weapons and armor will lose durability."); 129 | unlimitedDurability = prop.getBoolean(); 130 | propOrder.add(prop.getName()); 131 | 132 | main.setCategoryPropertyOrder(category, propOrder); 133 | main.save(); 134 | } 135 | 136 | private static void syncAttributes() 137 | { 138 | String category = "attributes"; 139 | List propOrder = Lists.newArrayList(); 140 | Property prop; 141 | 142 | /* 143 | * Weapon 144 | */ 145 | prop = attributes.get(category, "weaponFire", weaponFire); 146 | prop.setComment("Enables/disables the specific attribute on weapons (swords, etc...)"); 147 | weaponFire = prop.getBoolean(); 148 | propOrder.add(prop.getName()); 149 | 150 | prop = attributes.get(category, "weaponFrost", weaponFrost); 151 | prop.setComment("Enables/disables the specific attribute on weapons (swords, etc...)"); 152 | weaponFrost = prop.getBoolean(); 153 | propOrder.add(prop.getName()); 154 | 155 | prop = attributes.get(category, "weaponPoison", weaponPoison); 156 | prop.setComment("Enables/disables the specific attribute on weapons (swords, etc...)"); 157 | weaponPoison = prop.getBoolean(); 158 | propOrder.add(prop.getName()); 159 | 160 | prop = attributes.get(category, "weaponDurable", weaponDurable); 161 | prop.setComment("Enables/disables the specific attribute on weapons (swords, etc...)"); 162 | weaponDurable = prop.getBoolean(); 163 | propOrder.add(prop.getName()); 164 | 165 | prop = attributes.get(category, "weaponAbsorb", weaponAbsorb); 166 | prop.setComment("Enables/disables the specific attribute on weapons (swords, etc...)"); 167 | weaponAbsorb = prop.getBoolean(); 168 | propOrder.add(prop.getName()); 169 | 170 | prop = attributes.get(category, "weaponSoulBound", weaponSoulBound); 171 | prop.setComment("Enables/disables the specific attribute on weapons (swords, etc...)"); 172 | weaponSoulBound = prop.getBoolean(); 173 | propOrder.add(prop.getName()); 174 | 175 | prop = attributes.get(category, "weaponBloodlust", weaponBloodlust); 176 | prop.setComment("Enables/disables the specific attribute on weapons (swords, etc...)"); 177 | weaponBloodlust = prop.getBoolean(); 178 | propOrder.add(prop.getName()); 179 | 180 | prop = attributes.get(category, "weaponCritical", weaponCritical); 181 | prop.setComment("Enables/disables the specific attribute on weapons (swords, etc...)"); 182 | weaponCritical = prop.getBoolean(); 183 | propOrder.add(prop.getName()); 184 | 185 | prop = attributes.get(category, "weaponChained", weaponChained); 186 | prop.setComment("Enables/disables the specific attribute on weapons (swords, etc...)"); 187 | weaponChained = prop.getBoolean(); 188 | propOrder.add(prop.getName()); 189 | 190 | prop = attributes.get(category, "weaponUnbreakable", weaponUnbreakable); 191 | prop.setComment("Enables/disables the specific attribute on weapons (swords, etc...)"); 192 | weaponUnbreakable = prop.getBoolean(); 193 | propOrder.add(prop.getName()); 194 | 195 | prop = attributes.get(category, "weaponVoid", weaponVoid); 196 | prop.setComment("Enables/disables the specific attribute on weapons (swords, etc...)"); 197 | weaponVoid = prop.getBoolean(); 198 | propOrder.add(prop.getName()); 199 | 200 | 201 | /* 202 | * Armor 203 | */ 204 | prop = attributes.get(category, "armorFire", armorFire); 205 | prop.setComment("Enables/disables the specific attribute on armors."); 206 | armorFire = prop.getBoolean(); 207 | propOrder.add(prop.getName()); 208 | 209 | prop = attributes.get(category, "armorFrost", armorFrost); 210 | prop.setComment("Enables/disables the specific attribute on armors."); 211 | armorFrost = prop.getBoolean(); 212 | propOrder.add(prop.getName()); 213 | 214 | prop = attributes.get(category, "armorPoison", armorPoison); 215 | prop.setComment("Enables/disables the specific attribute on armors."); 216 | armorPoison = prop.getBoolean(); 217 | propOrder.add(prop.getName()); 218 | 219 | prop = attributes.get(category, "armorDurable", armorDurable); 220 | prop.setComment("Enables/disables the specific attribute on armors."); 221 | armorFire = prop.getBoolean(); 222 | propOrder.add(prop.getName()); 223 | 224 | prop = attributes.get(category, "armorSoulBound", armorSoulBound); 225 | prop.setComment("Enables/disables the specific attribute on armors."); 226 | armorSoulBound = prop.getBoolean(); 227 | propOrder.add(prop.getName()); 228 | 229 | prop = attributes.get(category, "armorUnbreakable", armorUnbreakable); 230 | prop.setComment("Enables/disables the specific attribute on armors."); 231 | armorUnbreakable = prop.getBoolean(); 232 | propOrder.add(prop.getName()); 233 | 234 | 235 | /* 236 | * Bow 237 | */ 238 | prop = attributes.get(category, "bowFire", bowFire); 239 | prop.setComment("Enables/disables the specific attribute on bows."); 240 | bowFire = prop.getBoolean(); 241 | propOrder.add(prop.getName()); 242 | 243 | prop = attributes.get(category, "bowFrost", bowFrost); 244 | prop.setComment("Enables/disables the specific attribute on bows."); 245 | bowFrost = prop.getBoolean(); 246 | propOrder.add(prop.getName()); 247 | 248 | prop = attributes.get(category, "bowPoison", bowPoison); 249 | prop.setComment("Enables/disables the specific attribute on bows."); 250 | bowPoison = prop.getBoolean(); 251 | propOrder.add(prop.getName()); 252 | 253 | prop = attributes.get(category, "bowDurable", bowDurable); 254 | prop.setComment("Enables/disables the specific attribute on bows."); 255 | bowDurable = prop.getBoolean(); 256 | propOrder.add(prop.getName()); 257 | 258 | prop = attributes.get(category, "bowAbsorb", bowAbsorb); 259 | prop.setComment("Enables/disables the specific attribute on bows."); 260 | bowAbsorb = prop.getBoolean(); 261 | propOrder.add(prop.getName()); 262 | 263 | prop = attributes.get(category, "bowSoulBound", bowSoulBound); 264 | prop.setComment("Enables/disables the specific attribute on bows."); 265 | bowSoulBound = prop.getBoolean(); 266 | propOrder.add(prop.getName()); 267 | 268 | prop = attributes.get(category, "bowCritical", bowCritical); 269 | prop.setComment("Enables/disables the specific attribute on bows."); 270 | bowCritical = prop.getBoolean(); 271 | propOrder.add(prop.getName()); 272 | 273 | prop = attributes.get(category, "bowRecover", bowRecover); 274 | prop.setComment("Enables/disables the specific attribute on bows."); 275 | bowRecover = prop.getBoolean(); 276 | propOrder.add(prop.getName()); 277 | 278 | prop = attributes.get(category, "bowBarrage", bowBarrage); 279 | prop.setComment("Enables/disables the specific attribute on bows."); 280 | bowBarrage = prop.getBoolean(); 281 | propOrder.add(prop.getName()); 282 | 283 | prop = attributes.get(category, "bowUnbreakable", bowUnbreakable); 284 | prop.setComment("Enables/disables the specific attribute on bows."); 285 | bowFire = prop.getBoolean(); 286 | propOrder.add(prop.getName()); 287 | 288 | prop = attributes.get(category, "bowVoid", bowVoid); 289 | prop.setComment("Enables/disables the specific attribute on bows."); 290 | bowVoid = prop.getBoolean(); 291 | propOrder.add(prop.getName()); 292 | 293 | 294 | /* 295 | * Shield 296 | */ 297 | prop = attributes.get(category, "shieldFire", shieldFire); 298 | prop.setComment("Enables/disables the specific attribute on shields."); 299 | shieldFire = prop.getBoolean(); 300 | propOrder.add(prop.getName()); 301 | 302 | prop = attributes.get(category, "shieldFrost", shieldFrost); 303 | prop.setComment("Enables/disables the specific attribute on shields."); 304 | shieldFrost = prop.getBoolean(); 305 | propOrder.add(prop.getName()); 306 | 307 | prop = attributes.get(category, "shieldPoison", shieldPoison); 308 | prop.setComment("Enables/disables the specific attribute on shields."); 309 | shieldPoison = prop.getBoolean(); 310 | propOrder.add(prop.getName()); 311 | 312 | prop = attributes.get(category, "shieldDurable", shieldDurable); 313 | prop.setComment("Enables/disables the specific attribute on shields."); 314 | shieldDurable = prop.getBoolean(); 315 | propOrder.add(prop.getName()); 316 | 317 | prop = attributes.get(category, "shieldSoulBound", shieldSoulBound); 318 | prop.setComment("Enables/disables the specific attribute on shields."); 319 | shieldSoulBound = prop.getBoolean(); 320 | propOrder.add(prop.getName()); 321 | 322 | prop = attributes.get(category, "shieldUnbreakable", shieldUnbreakable); 323 | prop.setComment("Enables/disables the specific attribute on shields."); 324 | shieldUnbreakable = prop.getBoolean(); 325 | propOrder.add(prop.getName()); 326 | } 327 | } 328 | -------------------------------------------------------------------------------- /src/main/java/com/thexfactor117/levels/events/EventAttack.java: -------------------------------------------------------------------------------- 1 | package com.thexfactor117.levels.events; 2 | 3 | import java.util.Iterator; 4 | import java.util.List; 5 | 6 | import com.thexfactor117.levels.config.Config; 7 | import com.thexfactor117.levels.leveling.Experience; 8 | import com.thexfactor117.levels.leveling.Rarity; 9 | import com.thexfactor117.levels.leveling.attributes.ArmorAttribute; 10 | import com.thexfactor117.levels.leveling.attributes.BowAttribute; 11 | import com.thexfactor117.levels.leveling.attributes.ShieldAttribute; 12 | import com.thexfactor117.levels.leveling.attributes.WeaponAttribute; 13 | import com.thexfactor117.levels.util.NBTHelper; 14 | 15 | import net.minecraft.entity.Entity; 16 | import net.minecraft.entity.EntityLivingBase; 17 | import net.minecraft.entity.SharedMonsterAttributes; 18 | import net.minecraft.entity.passive.EntityAnimal; 19 | import net.minecraft.entity.player.EntityPlayer; 20 | import net.minecraft.entity.projectile.EntityArrow; 21 | import net.minecraft.init.Items; 22 | import net.minecraft.init.MobEffects; 23 | import net.minecraft.item.ItemArmor; 24 | import net.minecraft.item.ItemBow; 25 | import net.minecraft.item.ItemShield; 26 | import net.minecraft.item.ItemStack; 27 | import net.minecraft.item.ItemSword; 28 | import net.minecraft.launchwrapper.Launch; 29 | import net.minecraft.nbt.NBTTagCompound; 30 | import net.minecraft.potion.PotionEffect; 31 | import net.minecraft.util.DamageSource; 32 | import net.minecraft.util.EnumHand; 33 | import net.minecraft.util.math.AxisAlignedBB; 34 | import net.minecraft.world.World; 35 | import net.minecraftforge.common.util.FakePlayer; 36 | import net.minecraftforge.event.entity.living.LivingDeathEvent; 37 | import net.minecraftforge.event.entity.living.LivingHurtEvent; 38 | import net.minecraftforge.fml.common.eventhandler.SubscribeEvent; 39 | 40 | /** 41 | * 42 | * @author TheXFactor117 43 | * 44 | */ 45 | public class EventAttack 46 | { 47 | @SubscribeEvent 48 | public void onAttack(LivingHurtEvent event) 49 | { 50 | if (event.getSource().getSourceOfDamage() instanceof EntityPlayer && !(event.getSource().getSourceOfDamage() instanceof FakePlayer)) 51 | { 52 | EntityPlayer player = (EntityPlayer) event.getSource().getSourceOfDamage(); 53 | EntityLivingBase enemy = event.getEntityLiving(); 54 | ItemStack stack = player.inventory.getCurrentItem(); 55 | NBTTagCompound nbt = NBTHelper.loadStackNBT(stack); 56 | 57 | if (stack != null && nbt != null && stack.getItem() instanceof ItemSword) 58 | { 59 | addExperience(nbt, stack, enemy); 60 | useRarity(nbt, stack, false); 61 | useAttributes(nbt, event, stack, player, enemy); 62 | attemptLevel(nbt, stack, player); 63 | } 64 | } 65 | else if (event.getSource().getSourceOfDamage() instanceof EntityLivingBase && event.getEntityLiving() instanceof EntityPlayer) 66 | { 67 | EntityPlayer player = (EntityPlayer) event.getEntityLiving(); 68 | EntityLivingBase enemy = (EntityLivingBase) event.getSource().getSourceOfDamage(); 69 | 70 | if (enemy != null && player != null) 71 | { 72 | for (ItemStack stack : player.inventory.armorInventory) 73 | { 74 | NBTTagCompound nbt = NBTHelper.loadStackNBT(stack); 75 | 76 | if (stack != null && nbt != null && stack.getItem() instanceof ItemArmor) 77 | { 78 | addExperience(nbt, stack, enemy); 79 | useRarity(nbt, stack, false); 80 | useAttributes(nbt, event, stack, player, enemy); 81 | attemptLevel(nbt, stack, player); 82 | } 83 | } 84 | 85 | if (player.inventory.offHandInventory.get(0).getItem() instanceof ItemShield) 86 | { 87 | ItemStack stack = player.inventory.offHandInventory.get(0); 88 | NBTTagCompound nbt = NBTHelper.loadStackNBT(stack); 89 | 90 | if (stack != null && nbt != null && player.getActiveHand() == EnumHand.OFF_HAND) 91 | { 92 | addExperience(nbt, stack, enemy); 93 | useRarity(nbt, stack, false); 94 | useAttributes(nbt, event, stack, player, enemy); 95 | attemptLevel(nbt, stack, player); 96 | } 97 | } 98 | } 99 | } 100 | else if (event.getSource().getSourceOfDamage() instanceof EntityArrow) 101 | { 102 | EntityArrow arrow = (EntityArrow) event.getSource().getSourceOfDamage(); 103 | 104 | if (arrow.shootingEntity instanceof EntityPlayer) 105 | { 106 | EntityPlayer player = (EntityPlayer) arrow.shootingEntity; 107 | EntityLivingBase enemy = event.getEntityLiving(); 108 | ItemStack stack = player.inventory.getCurrentItem(); 109 | NBTTagCompound nbt = NBTHelper.loadStackNBT(stack); 110 | 111 | if (player != null && enemy != null && stack != null && nbt != null && stack.getItem() instanceof ItemBow) 112 | { 113 | addExperience(nbt, stack, enemy); 114 | useRarity(nbt, stack, false); 115 | useAttributes(nbt, event, stack, player, enemy); 116 | attemptLevel(nbt, stack, player); 117 | } 118 | } 119 | else if (arrow.shootingEntity instanceof EntityLivingBase) 120 | { 121 | EntityPlayer player = (EntityPlayer) event.getEntityLiving(); 122 | EntityLivingBase enemy = (EntityLivingBase) arrow.shootingEntity; 123 | 124 | if (player != null && enemy != null) 125 | { 126 | for (ItemStack stack : player.inventory.armorInventory) 127 | { 128 | NBTTagCompound nbt = NBTHelper.loadStackNBT(stack); 129 | 130 | if (stack != null && nbt != null && stack.getItem() instanceof ItemArmor) 131 | { 132 | addExperience(nbt, stack, enemy); 133 | useRarity(nbt, stack, false); 134 | useAttributes(nbt, event, stack, player, enemy); 135 | attemptLevel(nbt, stack, player); 136 | } 137 | } 138 | 139 | if (player.inventory.offHandInventory.get(0).getItem() instanceof ItemShield) 140 | { 141 | ItemStack stack = player.inventory.offHandInventory.get(0); 142 | NBTTagCompound nbt = NBTHelper.loadStackNBT(stack); 143 | 144 | if (stack != null && nbt != null && player.getActiveHand() == EnumHand.OFF_HAND) 145 | { 146 | addExperience(nbt, stack, enemy); 147 | useRarity(nbt, stack, false); 148 | useAttributes(nbt, event, stack, player, enemy); 149 | attemptLevel(nbt, stack, player); 150 | } 151 | } 152 | } 153 | } 154 | } 155 | } 156 | 157 | /** 158 | * Called every time a living entity dies. 159 | * @param event 160 | */ 161 | @SubscribeEvent 162 | public void onLivingDeath(LivingDeathEvent event) 163 | { 164 | if (event.getSource().getSourceOfDamage() instanceof EntityPlayer && !(event.getSource().getSourceOfDamage() instanceof FakePlayer)) 165 | { 166 | EntityPlayer player = (EntityPlayer) event.getSource().getSourceOfDamage(); 167 | EntityLivingBase enemy = event.getEntityLiving(); 168 | ItemStack stack = player.inventory.getCurrentItem(); 169 | NBTTagCompound nbt = NBTHelper.loadStackNBT(stack); 170 | 171 | if (player != null && enemy != null && stack != null && nbt != null && stack.getItem() instanceof ItemSword) 172 | { 173 | addExperience(nbt, stack, enemy); 174 | useRarity(nbt, stack, true); 175 | attemptLevel(nbt, stack, player); 176 | } 177 | } 178 | else if (event.getSource().getSourceOfDamage() instanceof EntityArrow) 179 | { 180 | EntityArrow arrow = (EntityArrow) event.getSource().getSourceOfDamage(); 181 | 182 | if (arrow.shootingEntity instanceof EntityPlayer) 183 | { 184 | EntityPlayer player = (EntityPlayer) arrow.shootingEntity; 185 | EntityLivingBase enemy = event.getEntityLiving(); 186 | ItemStack stack = player.inventory.getCurrentItem(); 187 | NBTTagCompound nbt = NBTHelper.loadStackNBT(stack); 188 | 189 | if (player != null && enemy != null && stack != null && nbt != null && stack.getItem() instanceof ItemBow) 190 | { 191 | addExperience(nbt, stack, enemy); 192 | useRarity(nbt, stack, true); 193 | attemptLevel(nbt, stack, player); 194 | 195 | if (BowAttribute.RECOVER.hasAttribute(nbt)) 196 | { 197 | enemy.dropItem(Items.ARROW, (int) (Math.random() * 2)); 198 | } 199 | } 200 | } 201 | } 202 | } 203 | 204 | /** 205 | * Adds experience to the stack's NBT. 206 | * @param nbt 207 | * @param stack 208 | * @param enemy 209 | */ 210 | private void addExperience(NBTTagCompound nbt, ItemStack stack, EntityLivingBase enemy) 211 | { 212 | if (Experience.getLevel(nbt) < Config.maxLevel) 213 | { 214 | // DEV 215 | boolean isDev = (Boolean) Launch.blackboard.get("fml.deobfuscatedEnvironment"); 216 | 217 | if (isDev) 218 | { 219 | Experience.setExperience(nbt, Experience.getExperience(nbt) + 200); 220 | } 221 | 222 | // WEAPONS AND BOW 223 | if (stack.getItem() instanceof ItemSword || stack.getItem() instanceof ItemBow) 224 | { 225 | int xp = (int) (enemy.getMaxHealth() * 0.2); 226 | Experience.setExperience(nbt, Experience.getExperience(nbt) + xp); 227 | } 228 | 229 | // ARMOR AND SHIELD 230 | if (stack.getItem() instanceof ItemArmor || stack.getItem() instanceof ItemShield) 231 | { 232 | int xp = 0; 233 | 234 | // Default to use Attack Damage if available; uses Health if Attack Damage doesn't exist. 235 | if (enemy.getEntityAttribute(SharedMonsterAttributes.ATTACK_DAMAGE) != null) 236 | { 237 | xp = (int) (enemy.getEntityAttribute(SharedMonsterAttributes.ATTACK_DAMAGE).getAttributeValue() * 0.5); 238 | } 239 | else 240 | { 241 | xp = (int) (enemy.getEntityAttribute(SharedMonsterAttributes.MAX_HEALTH).getAttributeValue() * 0.5); 242 | } 243 | 244 | Experience.setExperience(nbt, Experience.getExperience(nbt) + xp); 245 | } 246 | } 247 | } 248 | 249 | /** 250 | * Uses rarity bonuses, such as bonus experience or durability bonuses. 251 | * @param nbt 252 | * @param stack 253 | */ 254 | private void useRarity(NBTTagCompound nbt, ItemStack stack, boolean death) 255 | { 256 | Rarity rarity = Rarity.getRarity(nbt); 257 | 258 | if (rarity != Rarity.DEFAULT) 259 | { 260 | int var; 261 | int var1; 262 | int var2; 263 | int var3; 264 | 265 | switch (rarity) 266 | { 267 | case UNCOMMON: // 6% chance of adding 1-3 experience points; 6% chance of not using durability 268 | if ((stack.getItem() instanceof ItemArmor || stack.getItem() instanceof ItemShield) || ((stack.getItem() instanceof ItemSword || stack.getItem() instanceof ItemBow) && death)) 269 | { 270 | var = (int) (Math.random() * 15); 271 | var1 = (int) (Math.random() * 3 + 1); 272 | if (var == 0) Experience.setExperience(nbt, Experience.getExperience(nbt) + var1); 273 | } 274 | 275 | if (!Config.unlimitedDurability && !death) 276 | { 277 | var2 = (int) (Math.random() * 15); 278 | if (var2 == 0) stack.setItemDamage(stack.getItemDamage() - 1); 279 | } 280 | 281 | break; 282 | case RARE: // 10% chance of adding 1-5 experience points; 10% chance of not using durability AND gaining an additional durability point 283 | if ((stack.getItem() instanceof ItemArmor || stack.getItem() instanceof ItemShield) || ((stack.getItem() instanceof ItemSword || stack.getItem() instanceof ItemBow) && death)) 284 | { 285 | var = (int) (Math.random() * 10); 286 | var1 = (int) (Math.random() * 5 + 1); 287 | if (var == 0) Experience.setExperience(nbt, Experience.getExperience(nbt) + var1); 288 | } 289 | 290 | if (!Config.unlimitedDurability && !death) 291 | { 292 | var2 = (int) (Math.random() * 10); 293 | var3 = (int) (Math.random() * 2); 294 | if (var2 == 0) stack.setItemDamage(stack.getItemDamage() - (1 + var3)); 295 | } 296 | 297 | break; 298 | case LEGENDARY: // 14% chance of adding 3-5 experience points; 14% chance of not using durability AND gaining 1-3 durability points 299 | if ((stack.getItem() instanceof ItemArmor || stack.getItem() instanceof ItemShield) || ((stack.getItem() instanceof ItemSword || stack.getItem() instanceof ItemBow) && death)) 300 | { 301 | var = (int) (Math.random() * 7); 302 | var1 = (int) (Math.random() * 5 + 3); 303 | if (var == 0) Experience.setExperience(nbt, Experience.getExperience(nbt) + var1); 304 | } 305 | 306 | if (!Config.unlimitedDurability && !death) 307 | { 308 | var2 = (int) (Math.random() * 7); 309 | var3 = (int) (Math.random() * 3 + 1); 310 | if (var2 == 0) stack.setItemDamage(stack.getItemDamage() - (1 + var3)); 311 | } 312 | 313 | break; 314 | case MYTHIC: // 20% chance of adding 3-10 experience points; 20% chance of not using durability AND gaining 1-5 durability points 315 | if ((stack.getItem() instanceof ItemArmor || stack.getItem() instanceof ItemShield) || ((stack.getItem() instanceof ItemSword || stack.getItem() instanceof ItemBow) && death)) 316 | { 317 | var = (int) (Math.random() * 5); 318 | var1 = (int) (Math.random() * 8 + 3); 319 | if (var == 0) Experience.setExperience(nbt, Experience.getExperience(nbt) + var1); 320 | } 321 | 322 | if (!Config.unlimitedDurability && !death) 323 | { 324 | var2 = (int) (Math.random() * 5); 325 | var3 = (int) (Math.random() * 5 + 1); 326 | if (var2 == 0) stack.setItemDamage(stack.getItemDamage() - (1 + var3)); 327 | } 328 | 329 | break; 330 | default: 331 | break; 332 | } 333 | } 334 | } 335 | 336 | /** 337 | * Uses any attributes the stack currently has. 338 | * @param nbt 339 | * @param event 340 | * @param stack 341 | * @param player 342 | * @param enemy 343 | */ 344 | private void useAttributes(NBTTagCompound nbt, LivingHurtEvent event, ItemStack stack, EntityPlayer player, EntityLivingBase enemy) 345 | { 346 | // WEAPONS 347 | if (stack.getItem() instanceof ItemSword) 348 | { 349 | if (WeaponAttribute.FIRE.hasAttribute(nbt) && (int) (Math.random() * 4) == 0) enemy.setFire((int) WeaponAttribute.FIRE.getCalculatedValue(nbt, 4, 1.25)); // 25% chance; tiers: (4 second, 5 second, 6 second) 350 | if (WeaponAttribute.FROST.hasAttribute(nbt) && (int) (Math.random() * 4) == 0) enemy.addPotionEffect(new PotionEffect(MobEffects.SLOWNESS, (int) WeaponAttribute.FROST.getCalculatedValue(nbt, 20, 1.5), 10)); // 25% chance; tiers: (1 second, 1.5 second, 2.25 second) 351 | if (WeaponAttribute.POISON.hasAttribute(nbt) && (int) (Math.random() * 4) == 0) enemy.addPotionEffect(new PotionEffect(MobEffects.POISON, (int) WeaponAttribute.POISON.getCalculatedValue(nbt, 20 * 7, 1.5), WeaponAttribute.POISON.getAttributeTier(nbt))); // 25% chance; tiers: (7 second, 10.5 second, 15.75 second) 352 | if (WeaponAttribute.DURABLE.hasAttribute(nbt) && (int) (Math.random() * 4) == 0) stack.setItemDamage(stack.getItemDamage() - (int) WeaponAttribute.DURABLE.getCalculatedValue(nbt, 1, 2)); // 25% chance; tiers: (1 point, 2 point, 4 point) 353 | if (WeaponAttribute.ABSORB.hasAttribute(nbt) && (int) (Math.random() * 5) == 0) player.setHealth(player.getHealth() + (float) (event.getAmount() * WeaponAttribute.ABSORB.getCalculatedValue(nbt, 0.25, 1.5))); // 14% chance; returns half the damage dealt back as health; tiers: (25%, 37.5%, 56.25%) 354 | if (WeaponAttribute.VOID.hasAttribute(nbt) && (int) (Math.random() * WeaponAttribute.VOID.getCalculatedValue(nbt, 15, 0.8)) == 0) enemy.setHealth(0.001F); // tiers: (6% chance, 8% chance, 1125%% chance); sets enemies health to something small, so damage kills enemy in one hit 355 | 356 | if (WeaponAttribute.CRITICAL.hasAttribute(nbt) && (int) (Math.random() * 5) == 0) 357 | { 358 | float bonus = (float) (event.getAmount() * WeaponAttribute.CRITICAL.getCalculatedValue(nbt, 0.20, 1.5)); // 20% chance; tiers: (20%, 30%, 45%) 359 | event.setAmount(event.getAmount() + bonus); 360 | } 361 | 362 | if (WeaponAttribute.CHAINED.hasAttribute(nbt) && (int) (Math.random() * 10) == 0) 363 | { 364 | double radius = 10; 365 | World world = enemy.getEntityWorld(); 366 | List entityList = world.getEntitiesWithinAABB(EntityLivingBase.class, new AxisAlignedBB(player.posX - radius, player.posY - radius, player.posZ - radius, player.posX + radius, player.posY + radius, player.posZ + radius)); 367 | Iterator iterator = entityList.iterator(); 368 | 369 | while (iterator.hasNext()) 370 | { 371 | Entity entity = (Entity) iterator.next(); 372 | 373 | if (entity instanceof EntityLivingBase && !(entity instanceof EntityPlayer) && !(entity instanceof EntityAnimal)) 374 | { 375 | entity.attackEntityFrom(DamageSource.causePlayerDamage(player), event.getAmount() / 2); 376 | } 377 | } 378 | } 379 | } 380 | 381 | // ARMOR 382 | if (stack.getItem() instanceof ItemArmor) 383 | { 384 | if (ArmorAttribute.FIRE.hasAttribute(nbt) && (int) (Math.random() * 4) == 0) enemy.setFire((int) ArmorAttribute.FIRE.getCalculatedValue(nbt, 4, 1.25)); // 25% chance; tiers: (4 second, 5 second, 6 second) 385 | if (ArmorAttribute.FROST.hasAttribute(nbt) && (int) (Math.random() * 4) == 0) enemy.addPotionEffect(new PotionEffect(MobEffects.SLOWNESS, (int) ArmorAttribute.FROST.getCalculatedValue(nbt, 20, 1.5), 10)); // 25% chance; tiers: (1 second, 1.5 second, 2.25 second) 386 | if (ArmorAttribute.POISON.hasAttribute(nbt) && (int) (Math.random() * 4) == 0) enemy.addPotionEffect(new PotionEffect(MobEffects.POISON, (int) ArmorAttribute.POISON.getCalculatedValue(nbt, 20 * 7, 1.5), ArmorAttribute.POISON.getAttributeTier(nbt))); // 25% chance; tiers: (7 second, 10.5 second, 15.75 second) 387 | if (ArmorAttribute.DURABLE.hasAttribute(nbt) && (int) (Math.random() * 4) == 0) stack.setItemDamage(stack.getItemDamage() - (int) ArmorAttribute.DURABLE.getCalculatedValue(nbt, 1, 2)); // 25% chance; tiers: (1 point, 2 point, 4 point) 388 | if (ArmorAttribute.MAGICAL.hasAttribute(nbt) && event.getSource().isMagicDamage()) event.setAmount((float) (event.getAmount() * ArmorAttribute.MAGICAL.getCalculatedValue(nbt, 0.2, 1.5))); // tiers: (20%, 30%, 45%) 389 | } 390 | 391 | // BOW 392 | if (stack.getItem() instanceof ItemBow) 393 | { 394 | if (BowAttribute.FIRE.hasAttribute(nbt) && (int) (Math.random() * 4) == 0) enemy.setFire((int) BowAttribute.FIRE.getCalculatedValue(nbt, 4, 1.25)); // 25% chance; tiers: (4 second, 5 second, 6 second) 395 | if (BowAttribute.FROST.hasAttribute(nbt) && (int) (Math.random() * 4) == 0) enemy.addPotionEffect(new PotionEffect(MobEffects.SLOWNESS, (int) BowAttribute.FROST.getCalculatedValue(nbt, 20, 1.5), 10)); // 25% chance; tiers: (1 second, 1.5 second, 2.25 second) 396 | if (BowAttribute.POISON.hasAttribute(nbt) && (int) (Math.random() * 4) == 0) enemy.addPotionEffect(new PotionEffect(MobEffects.POISON, (int) BowAttribute.POISON.getCalculatedValue(nbt, 20 * 7, 1.5), BowAttribute.POISON.getAttributeTier(nbt))); // 25% chance; tiers: (7 second, 10.5 second, 15.75 second) 397 | if (BowAttribute.DURABLE.hasAttribute(nbt) && (int) (Math.random() * 4) == 0) stack.setItemDamage(stack.getItemDamage() - (int) BowAttribute.DURABLE.getCalculatedValue(nbt, 1, 2)); // 25% chance; tiers: (1 point, 2 point, 4 point) 398 | if (BowAttribute.ABSORB.hasAttribute(nbt) && (int) (Math.random() * 5) == 0) player.setHealth(player.getHealth() + (float) (event.getAmount() * BowAttribute.ABSORB.getCalculatedValue(nbt, 0.25, 1.5))); // 14% chance; returns half the damage dealt back as health; tiers: (25%, 37.5%, 56.25%) 399 | if (BowAttribute.VOID.hasAttribute(nbt) && (int) (Math.random() * BowAttribute.VOID.getCalculatedValue(nbt, 15, 0.8)) == 0) enemy.setHealth(0.001F); // tiers: (6% chance, 8% chance, 1125%% chance); sets enemies health to something small, so damage kills enemy in one hit 400 | 401 | if (BowAttribute.CRITICAL.hasAttribute(nbt) && (int) (Math.random() * 5) == 0) 402 | { 403 | float bonus = (float) (event.getAmount() * BowAttribute.CRITICAL.getCalculatedValue(nbt, 0.20, 1.5)); // 20% chance; tiers: (20%, 30%, 45%) 404 | event.setAmount(event.getAmount() + bonus); 405 | } 406 | } 407 | 408 | // SHIELD 409 | if (stack.getItem() instanceof ItemShield) 410 | { 411 | if (ShieldAttribute.FIRE.hasAttribute(nbt) && (int) (Math.random() * 4) == 0) enemy.setFire((int) ShieldAttribute.FIRE.getCalculatedValue(nbt, 4, 1.25)); // 25% chance; tiers: (4 second, 5 second, 6 second) 412 | if (ShieldAttribute.FROST.hasAttribute(nbt) && (int) (Math.random() * 4) == 0) enemy.addPotionEffect(new PotionEffect(MobEffects.SLOWNESS, (int) ShieldAttribute.FROST.getCalculatedValue(nbt, 20, 1.5), 10)); // 25% chance; tiers: (1 second, 1.5 second, 2.25 second) 413 | if (ShieldAttribute.POISON.hasAttribute(nbt) && (int) (Math.random() * 4) == 0) enemy.addPotionEffect(new PotionEffect(MobEffects.POISON, (int) ShieldAttribute.POISON.getCalculatedValue(nbt, 20 * 7, 1.5), ShieldAttribute.POISON.getAttributeTier(nbt))); // 25% chance; tiers: (7 second, 10.5 second, 15.75 second) 414 | if (ShieldAttribute.DURABLE.hasAttribute(nbt) && (int) (Math.random() * 4) == 0) stack.setItemDamage(stack.getItemDamage() - (int) ShieldAttribute.DURABLE.getCalculatedValue(nbt, 1, 2)); // 25% chance; tiers: (1 point, 2 point, 4 point) 415 | } 416 | } 417 | 418 | /** 419 | * Attempts to level up the current stack. 420 | * @param stack 421 | * @param player 422 | */ 423 | private void attemptLevel(NBTTagCompound nbt, ItemStack stack, EntityPlayer player) 424 | { 425 | Experience.levelUp(player, stack); 426 | NBTHelper.saveStackNBT(stack, nbt); 427 | } 428 | } 429 | -------------------------------------------------------------------------------- /src/main/java/com/thexfactor117/levels/events/EventCreateWeapon.java: -------------------------------------------------------------------------------- 1 | package com.thexfactor117.levels.events; 2 | 3 | import com.thexfactor117.levels.config.Config; 4 | import com.thexfactor117.levels.util.NBTHelper; 5 | import com.thexfactor117.levels.util.WeaponHelper; 6 | 7 | import net.minecraft.entity.player.EntityPlayer; 8 | import net.minecraft.item.ItemArmor; 9 | import net.minecraft.item.ItemBow; 10 | import net.minecraft.item.ItemShield; 11 | import net.minecraft.item.ItemStack; 12 | import net.minecraft.item.ItemSword; 13 | import net.minecraft.nbt.NBTTagCompound; 14 | import net.minecraftforge.fml.common.eventhandler.SubscribeEvent; 15 | import net.minecraftforge.fml.common.gameevent.TickEvent.Phase; 16 | import net.minecraftforge.fml.common.gameevent.TickEvent.PlayerTickEvent; 17 | 18 | /** 19 | * 20 | * @author TheXFactor117 21 | * 22 | */ 23 | public class EventCreateWeapon 24 | { 25 | @SubscribeEvent 26 | public void onCreateWeapon(PlayerTickEvent event) 27 | { 28 | if (!event.player.getEntityWorld().isRemote) 29 | { 30 | if (event.phase == Phase.START) 31 | { 32 | for (ItemStack stack : event.player.inventory.mainInventory) 33 | { 34 | if (stack != null && (stack.getItem() instanceof ItemSword || stack.getItem() instanceof ItemBow || stack.getItem() instanceof ItemArmor || stack.getItem() instanceof ItemShield)) 35 | { 36 | create(stack, event.player); 37 | } 38 | } 39 | } 40 | } 41 | } 42 | 43 | /** 44 | * Sets up a weapon with customized values. 45 | * @param stack 46 | */ 47 | private void create(ItemStack stack, EntityPlayer player) 48 | { 49 | NBTTagCompound nbt = NBTHelper.loadStackNBT(stack); 50 | 51 | if (nbt != null) 52 | { 53 | for (int j = 0; j < Config.itemBlacklist.length; j++) 54 | { 55 | if (Config.itemBlacklist[j].equals(stack.getItem().getRegistryName().getResourceDomain() + ":" + stack.getItem().getRegistryName().getResourcePath())) 56 | { 57 | return; 58 | } 59 | } 60 | 61 | WeaponHelper.create(stack, player); 62 | } 63 | } 64 | } 65 | -------------------------------------------------------------------------------- /src/main/java/com/thexfactor117/levels/events/EventInput.java: -------------------------------------------------------------------------------- 1 | package com.thexfactor117.levels.events; 2 | 3 | import com.thexfactor117.levels.Levels; 4 | import com.thexfactor117.levels.proxies.ClientProxy; 5 | import com.thexfactor117.levels.util.GuiHandler; 6 | 7 | import net.minecraft.client.Minecraft; 8 | import net.minecraft.client.settings.KeyBinding; 9 | import net.minecraft.entity.player.EntityPlayer; 10 | import net.minecraft.item.Item; 11 | import net.minecraft.item.ItemArmor; 12 | import net.minecraft.item.ItemBow; 13 | import net.minecraft.item.ItemShield; 14 | import net.minecraft.item.ItemStack; 15 | import net.minecraft.item.ItemSword; 16 | import net.minecraft.item.ItemTool; 17 | import net.minecraftforge.fml.common.eventhandler.SubscribeEvent; 18 | import net.minecraftforge.fml.common.gameevent.InputEvent; 19 | import net.minecraftforge.fml.relauncher.Side; 20 | import net.minecraftforge.fml.relauncher.SideOnly; 21 | 22 | /** 23 | * 24 | * @author TheXFactor117 25 | * 26 | */ 27 | public class EventInput 28 | { 29 | @SideOnly(Side.CLIENT) 30 | @SubscribeEvent 31 | public void onKeyPress(InputEvent.KeyInputEvent event) 32 | { 33 | KeyBinding l = ClientProxy.keyBindingL; 34 | Minecraft mc = Minecraft.getMinecraft(); 35 | EntityPlayer player = mc.player; 36 | 37 | if (player != null) 38 | { 39 | ItemStack stack = player.inventory.getCurrentItem(); 40 | 41 | if (stack != null) 42 | { 43 | Item current = stack.getItem(); 44 | 45 | if (current != null) 46 | { 47 | if (current instanceof ItemSword || current instanceof ItemTool || current instanceof ItemArmor || current instanceof ItemBow || current instanceof ItemShield) 48 | { 49 | if (l.isPressed()) 50 | { 51 | player.openGui(Levels.instance, GuiHandler.ITEM_INFORMATION, player.getEntityWorld(), (int) player.posX, (int) player.posY, (int) player.posZ); 52 | } 53 | } 54 | } 55 | } 56 | } 57 | } 58 | } 59 | -------------------------------------------------------------------------------- /src/main/java/com/thexfactor117/levels/events/EventTooltip.java: -------------------------------------------------------------------------------- 1 | package com.thexfactor117.levels.events; 2 | 3 | import java.text.DecimalFormat; 4 | import java.util.ArrayList; 5 | 6 | import org.lwjgl.input.Keyboard; 7 | 8 | import com.thexfactor117.levels.config.Config; 9 | import com.thexfactor117.levels.leveling.Experience; 10 | import com.thexfactor117.levels.leveling.Rarity; 11 | import com.thexfactor117.levels.leveling.attributes.ArmorAttribute; 12 | import com.thexfactor117.levels.leveling.attributes.BowAttribute; 13 | import com.thexfactor117.levels.leveling.attributes.ShieldAttribute; 14 | import com.thexfactor117.levels.leveling.attributes.WeaponAttribute; 15 | import com.thexfactor117.levels.util.NBTHelper; 16 | 17 | import net.minecraft.client.resources.I18n; 18 | import net.minecraft.item.ItemArmor; 19 | import net.minecraft.item.ItemAxe; 20 | import net.minecraft.item.ItemBow; 21 | import net.minecraft.item.ItemShield; 22 | import net.minecraft.item.ItemStack; 23 | import net.minecraft.item.ItemSword; 24 | import net.minecraft.item.ItemTool; 25 | import net.minecraft.nbt.NBTTagCompound; 26 | import net.minecraft.nbt.NBTTagList; 27 | import net.minecraft.util.text.TextFormatting; 28 | import net.minecraftforge.event.entity.player.ItemTooltipEvent; 29 | import net.minecraftforge.fml.common.eventhandler.EventPriority; 30 | import net.minecraftforge.fml.common.eventhandler.SubscribeEvent; 31 | 32 | /** 33 | * 34 | * @author TheXFactor117 35 | * 36 | */ 37 | public class EventTooltip 38 | { 39 | @SubscribeEvent(priority = EventPriority.HIGHEST) 40 | public void onTooltip(ItemTooltipEvent event) 41 | { 42 | ArrayList tooltip = (ArrayList) event.getToolTip(); 43 | ItemStack stack = event.getItemStack(); 44 | NBTTagCompound nbt = NBTHelper.loadStackNBT(stack); 45 | 46 | if (stack != null && nbt != null) 47 | { 48 | if (stack.getItem() instanceof ItemSword || stack.getItem() instanceof ItemArmor || stack.getItem() instanceof ItemBow || stack.getItem() instanceof ItemShield || stack.getItem() instanceof ItemTool) 49 | { 50 | Rarity rarity = Rarity.getRarity(nbt); 51 | 52 | if (rarity != Rarity.DEFAULT) 53 | { 54 | addTooltips(tooltip, stack, nbt); 55 | } 56 | } 57 | } 58 | } 59 | 60 | private void addTooltips(ArrayList tooltip, ItemStack stack, NBTTagCompound nbt) 61 | { 62 | Rarity rarity = Rarity.getRarity(nbt); 63 | 64 | NBTTagList taglist = nbt.getTagList("AttributeModifiers", 10); 65 | NBTTagCompound damageNbt = taglist.getCompoundTagAt(0); 66 | NBTTagCompound speedNbt = taglist.getCompoundTagAt(1); 67 | DecimalFormat format = new DecimalFormat("#.##"); 68 | 69 | tooltip.add(""); 70 | 71 | if (stack.getItem() instanceof ItemSword || stack.getItem() instanceof ItemAxe) 72 | { 73 | // damage and attack speed 74 | tooltip.add(TextFormatting.BLUE + "+" + format.format(damageNbt.getDouble("Amount")) + " Damage"); 75 | tooltip.add(TextFormatting.BLUE + "+" + format.format(speedNbt.getDouble("Amount") + 4) + " Attack Speed"); 76 | } 77 | else if (stack.getItem() instanceof ItemArmor) 78 | { 79 | // armor and armor toughness 80 | tooltip.add(TextFormatting.BLUE + "+" + format.format(damageNbt.getDouble("Amount")) + " Armor"); 81 | tooltip.add(TextFormatting.BLUE + "+" + format.format(speedNbt.getDouble("Amount")) + " Armor Toughness"); 82 | } 83 | 84 | if (!(stack.getItem() instanceof ItemShield || stack.getItem() instanceof ItemBow)) 85 | { 86 | tooltip.add(""); 87 | } 88 | 89 | // rarity 90 | tooltip.add(rarity.getColor() + TextFormatting.ITALIC + rarity.getName()); // rarity 91 | 92 | // level 93 | if (Experience.getLevel(nbt) >= Config.maxLevel) 94 | tooltip.add(TextFormatting.GRAY + I18n.format("levels.misc.level") + ": " + I18n.format("levels.misc.max")); // max level 95 | else 96 | tooltip.add(TextFormatting.GRAY + I18n.format("levels.misc.level") + ": " + Experience.getLevel(nbt)); // level 97 | 98 | // experience 99 | if (Experience.getLevel(nbt) >= Config.maxLevel) 100 | tooltip.add(TextFormatting.GRAY + I18n.format("levels.misc.experience") + ": " + I18n.format("levels.misc.max")); 101 | else 102 | tooltip.add(TextFormatting.GRAY + I18n.format("levels.misc.experience") + ": " + Experience.getExperience(nbt) + " / " + Experience.getNextLevelExperience(Experience.getLevel(nbt))); 103 | 104 | // durability 105 | if (nbt.getInteger("Unbreakable") == 1) 106 | tooltip.add(TextFormatting.GRAY + I18n.format("levels.misc.durability") + ": " + I18n.format("levels.misc.durability.unlimited")); 107 | else 108 | tooltip.add(TextFormatting.GRAY + I18n.format("levels.misc.durability") + ": " + (stack.getMaxDamage() - stack.getItemDamage()) + " / " + stack.getMaxDamage()); 109 | 110 | tooltip.add(""); 111 | 112 | // attributes 113 | if (Keyboard.isKeyDown(Keyboard.KEY_LSHIFT) || Keyboard.isKeyDown(Keyboard.KEY_RSHIFT)) 114 | { 115 | tooltip.add(TextFormatting.GRAY + "" + TextFormatting.ITALIC + I18n.format("levels.misc.attributes")); 116 | 117 | if (stack.getItem() instanceof ItemSword) 118 | { 119 | for (WeaponAttribute attribute : WeaponAttribute.WEAPON_ATTRIBUTES) 120 | { 121 | if (attribute.hasAttribute(nbt)) 122 | tooltip.add(" " + attribute.getColor() + attribute.getName(nbt)); 123 | } 124 | } 125 | else if (stack.getItem() instanceof ItemArmor) 126 | { 127 | for (ArmorAttribute attribute : ArmorAttribute.ARMOR_ATTRIBUTES) 128 | { 129 | if (attribute.hasAttribute(nbt)) 130 | tooltip.add(" " + attribute.getColor() + attribute.getName(nbt)); 131 | } 132 | } 133 | else if (stack.getItem() instanceof ItemBow) 134 | { 135 | for (BowAttribute attribute : BowAttribute.BOW_ATTRIBUTES) 136 | { 137 | if (attribute.hasAttribute(nbt)) 138 | tooltip.add(" " + attribute.getColor() + attribute.getName(nbt)); 139 | } 140 | } 141 | else if (stack.getItem() instanceof ItemShield) 142 | { 143 | for (ShieldAttribute attribute : ShieldAttribute.SHIELD_ATTRIBUTES) 144 | { 145 | if (attribute.hasAttribute(nbt)) 146 | tooltip.add(" " + attribute.getColor() + attribute.getName(nbt)); 147 | } 148 | } 149 | } 150 | else 151 | { 152 | tooltip.add(TextFormatting.GRAY + "" + TextFormatting.ITALIC + I18n.format("levels.misc.attributes.shift")); 153 | } 154 | 155 | tooltip.add(""); 156 | } 157 | } 158 | -------------------------------------------------------------------------------- /src/main/java/com/thexfactor117/levels/events/attributes/EventBarrage.java: -------------------------------------------------------------------------------- 1 | package com.thexfactor117.levels.events.attributes; 2 | 3 | import com.thexfactor117.levels.leveling.attributes.BowAttribute; 4 | import com.thexfactor117.levels.util.NBTHelper; 5 | 6 | import net.minecraft.entity.player.EntityPlayer; 7 | import net.minecraft.entity.projectile.EntityArrow; 8 | import net.minecraft.entity.projectile.EntityArrow.PickupStatus; 9 | import net.minecraft.entity.projectile.EntityTippedArrow; 10 | import net.minecraft.item.ItemBow; 11 | import net.minecraft.item.ItemStack; 12 | import net.minecraft.nbt.NBTTagCompound; 13 | import net.minecraftforge.event.entity.player.ArrowLooseEvent; 14 | import net.minecraftforge.fml.common.eventhandler.SubscribeEvent; 15 | 16 | /** 17 | * 18 | * @author TheXFactor117 19 | * 20 | */ 21 | public class EventBarrage 22 | { 23 | @SuppressWarnings("static-access") 24 | @SubscribeEvent 25 | public void onBowFire(ArrowLooseEvent event) 26 | { 27 | EntityPlayer player = event.getEntityPlayer(); 28 | ItemStack stack = event.getBow(); 29 | NBTTagCompound nbt = NBTHelper.loadStackNBT(stack); 30 | 31 | if (player != null && stack != null && nbt != null && !player.getEntityWorld().isRemote) 32 | { 33 | if (BowAttribute.BARRAGE.hasAttribute(nbt)) 34 | { 35 | for (int i = 0; i < (int) BowAttribute.BARRAGE.getCalculatedValue(nbt, 3, 1.5); i++) 36 | { 37 | EntityArrow entityarrow = new EntityTippedArrow(player.getEntityWorld(), player); 38 | entityarrow.setAim(player, player.rotationPitch, player.rotationYaw, 0, ((ItemBow) event.getBow().getItem()).getArrowVelocity(event.getCharge()) * 3, 20F); 39 | entityarrow.pickupStatus = PickupStatus.DISALLOWED; 40 | player.getEntityWorld().spawnEntity(entityarrow); 41 | } 42 | } 43 | } 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /src/main/java/com/thexfactor117/levels/events/attributes/EventSoulBound.java: -------------------------------------------------------------------------------- 1 | package com.thexfactor117.levels.events.attributes; 2 | 3 | import com.thexfactor117.levels.leveling.attributes.ArmorAttribute; 4 | import com.thexfactor117.levels.leveling.attributes.BowAttribute; 5 | import com.thexfactor117.levels.leveling.attributes.ShieldAttribute; 6 | import com.thexfactor117.levels.leveling.attributes.WeaponAttribute; 7 | import com.thexfactor117.levels.util.NBTHelper; 8 | 9 | import net.minecraft.entity.player.EntityPlayer; 10 | import net.minecraft.item.Item; 11 | import net.minecraft.item.ItemArmor; 12 | import net.minecraft.item.ItemBow; 13 | import net.minecraft.item.ItemShield; 14 | import net.minecraft.item.ItemStack; 15 | import net.minecraft.item.ItemSword; 16 | import net.minecraft.nbt.NBTTagCompound; 17 | import net.minecraftforge.event.entity.player.PlayerDropsEvent; 18 | import net.minecraftforge.event.entity.player.PlayerEvent; 19 | import net.minecraftforge.fml.common.eventhandler.SubscribeEvent; 20 | 21 | /** 22 | * 23 | * @author TheXFactor117 24 | * 25 | */ 26 | public class EventSoulBound 27 | { 28 | @SubscribeEvent 29 | public void onPlayerClone(PlayerEvent.Clone event) 30 | { 31 | if (event.isWasDeath()) 32 | { 33 | EntityPlayer player = event.getEntityPlayer(); 34 | player.inventory.copyInventory(event.getOriginal().inventory); 35 | } 36 | } 37 | 38 | @SubscribeEvent 39 | public void onPlayerDeath(PlayerDropsEvent event) 40 | { 41 | EntityPlayer player = event.getEntityPlayer(); 42 | Item item; 43 | 44 | for (int i = 0; i < event.getDrops().size(); i++) 45 | { 46 | item = event.getDrops().get(i).getEntityItem().getItem(); 47 | 48 | if (item != null && (item instanceof ItemSword || item instanceof ItemShield || item instanceof ItemArmor || item instanceof ItemBow)) 49 | { 50 | ItemStack stack = event.getDrops().get(i).getEntityItem(); 51 | NBTTagCompound nbt = NBTHelper.loadStackNBT(stack); 52 | 53 | if (nbt != null) 54 | { 55 | if (WeaponAttribute.SOUL_BOUND.hasAttribute(nbt) || ArmorAttribute.SOUL_BOUND.hasAttribute(nbt) || BowAttribute.SOUL_BOUND.hasAttribute(nbt) || ShieldAttribute.SOUL_BOUND.hasAttribute(nbt)) 56 | { 57 | event.getDrops().remove(i); 58 | player.inventory.addItemStackToInventory(stack); 59 | } 60 | } 61 | } 62 | } 63 | } 64 | } 65 | -------------------------------------------------------------------------------- /src/main/java/com/thexfactor117/levels/init/ModEvents.java: -------------------------------------------------------------------------------- 1 | package com.thexfactor117.levels.init; 2 | 3 | import com.thexfactor117.levels.events.EventAttack; 4 | import com.thexfactor117.levels.events.EventCreateWeapon; 5 | import com.thexfactor117.levels.events.EventInput; 6 | import com.thexfactor117.levels.events.EventTooltip; 7 | import com.thexfactor117.levels.events.attributes.EventBarrage; 8 | import com.thexfactor117.levels.events.attributes.EventSoulBound; 9 | 10 | import net.minecraftforge.common.MinecraftForge; 11 | 12 | /** 13 | * 14 | * @author TheXFactor117 15 | * 16 | */ 17 | public class ModEvents 18 | { 19 | public static void register() 20 | { 21 | MinecraftForge.EVENT_BUS.register(new EventInput()); 22 | MinecraftForge.EVENT_BUS.register(new EventCreateWeapon()); 23 | MinecraftForge.EVENT_BUS.register(new EventAttack()); 24 | MinecraftForge.EVENT_BUS.register(new EventTooltip()); 25 | MinecraftForge.EVENT_BUS.register(new EventSoulBound()); 26 | MinecraftForge.EVENT_BUS.register(new EventBarrage()); 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /src/main/java/com/thexfactor117/levels/leveling/Experience.java: -------------------------------------------------------------------------------- 1 | package com.thexfactor117.levels.leveling; 2 | 3 | import com.thexfactor117.levels.config.Config; 4 | import com.thexfactor117.levels.util.NBTHelper; 5 | 6 | import net.minecraft.entity.player.EntityPlayer; 7 | import net.minecraft.item.ItemArmor; 8 | import net.minecraft.item.ItemAxe; 9 | import net.minecraft.item.ItemStack; 10 | import net.minecraft.item.ItemSword; 11 | import net.minecraft.nbt.NBTTagCompound; 12 | import net.minecraft.nbt.NBTTagList; 13 | import net.minecraft.util.text.TextComponentString; 14 | import net.minecraft.util.text.TextFormatting; 15 | 16 | /** 17 | * 18 | * @author TheXFactor117 19 | * 20 | */ 21 | public class Experience 22 | { 23 | /** 24 | * Levels up the current weapon/armor to the next level, assuming it is not at max level. 25 | * @param player 26 | * @param stack 27 | */ 28 | public static void levelUp(EntityPlayer player, ItemStack stack) 29 | { 30 | NBTTagCompound nbt = stack.getTagCompound(); 31 | 32 | if (nbt != null) 33 | { 34 | while (Experience.getLevel(nbt) < Config.maxLevel && Experience.getExperience(nbt) >= Experience.getNextLevelExperience(Experience.getLevel(nbt))) 35 | { 36 | Experience.setLevel(nbt, Experience.getLevel(nbt) + 1); // increase level by one 37 | Experience.setAttributeTokens(nbt, Experience.getAttributeTokens(nbt) + 1); 38 | 39 | player.sendMessage(new TextComponentString(stack.getDisplayName() + TextFormatting.GRAY + " has leveled up to level " + TextFormatting.GOLD + Experience.getLevel(nbt) + TextFormatting.GRAY + "!")); 40 | 41 | if (stack.getItem() instanceof ItemSword || stack.getItem() instanceof ItemAxe) 42 | { 43 | // update damage and attack speed values 44 | NBTTagList taglist = nbt.getTagList("AttributeModifiers", 10); // retrieves our custom Attribute Modifier implementation 45 | NBTTagCompound damageNbt = taglist.getCompoundTagAt(0); 46 | NBTTagCompound speedNbt = taglist.getCompoundTagAt(1); 47 | double newDamage = damageNbt.getDouble("Amount") + ((damageNbt.getDouble("Amount") * nbt.getDouble("Multiplier")) / 2); 48 | double newSpeed = speedNbt.getDouble("Amount") - ((speedNbt.getDouble("Amount") * nbt.getDouble("Multiplier")) / 2); 49 | damageNbt.setDouble("Amount", newDamage); 50 | speedNbt.setDouble("Amount", newSpeed); 51 | } 52 | else if (stack.getItem() instanceof ItemArmor) 53 | { 54 | // update armor and armor toughness values 55 | NBTTagList taglist = nbt.getTagList("AttributeModifiers", 10); // retrieves our custom Attribute Modifier implementation 56 | NBTTagCompound armorNbt = taglist.getCompoundTagAt(0); 57 | NBTTagCompound toughnessNbt = taglist.getCompoundTagAt(1); 58 | double newArmor = armorNbt.getDouble("Amount") + ((armorNbt.getDouble("Amount") * nbt.getDouble("Multiplier")) / 2); 59 | double newToughness = toughnessNbt.getDouble("Amount") - ((toughnessNbt.getDouble("Amount") * nbt.getDouble("Multiplier")) / 2); 60 | armorNbt.setDouble("Amount", newArmor); 61 | toughnessNbt.setDouble("Amount", newToughness); 62 | } 63 | 64 | NBTHelper.saveStackNBT(stack, nbt); 65 | } 66 | } 67 | } 68 | 69 | /** 70 | * Returns the level of the current weapon/armor. 71 | * @param nbt 72 | * @return 73 | */ 74 | public static int getLevel(NBTTagCompound nbt) 75 | { 76 | return nbt != null ? nbt.getInteger("LEVEL") : 1; 77 | } 78 | 79 | /** 80 | * Sets the level of the current weapon/armor. 81 | * @param nbt 82 | * @param level 83 | */ 84 | public static void setLevel(NBTTagCompound nbt, int level) 85 | { 86 | if (nbt != null) 87 | { 88 | if (level > 0) 89 | nbt.setInteger("LEVEL", level); 90 | else 91 | nbt.removeTag("LEVEL"); 92 | } 93 | } 94 | 95 | /** 96 | * Returns the experience of the current weapon/armor. 97 | * @param nbt 98 | * @return 99 | */ 100 | public static int getExperience(NBTTagCompound nbt) 101 | { 102 | return nbt != null ? nbt.getInteger("EXPERIENCE") : 1; 103 | } 104 | 105 | /** 106 | * Sets the experience of the current weapon/armor. 107 | * @param nbt 108 | * @param level 109 | */ 110 | public static void setExperience(NBTTagCompound nbt, int experience) 111 | { 112 | if (nbt != null) 113 | { 114 | if (experience > 0) 115 | nbt.setInteger("EXPERIENCE", experience); 116 | else 117 | nbt.removeTag("EXPERIENCE"); 118 | } 119 | } 120 | 121 | /** 122 | * Sets the amount of Attribute Tokens the specific NBT tag has. 123 | * @param nbt 124 | * @param tokens 125 | */ 126 | public static void setAttributeTokens(NBTTagCompound nbt, int tokens) 127 | { 128 | if (nbt != null) 129 | { 130 | if (tokens > 0) 131 | nbt.setInteger("TOKENS", tokens); 132 | else 133 | nbt.removeTag("TOKENS"); 134 | } 135 | } 136 | 137 | /** 138 | * Returns how many Attribute Tokens the specific NBT tag has. 139 | * @param nbt 140 | * @return 141 | */ 142 | public static int getAttributeTokens(NBTTagCompound nbt) 143 | { 144 | return nbt != null ? nbt.getInteger("TOKENS") : 0; 145 | } 146 | 147 | /** 148 | * Returns the amount of experience to level up. 149 | * @param currentLevel 150 | * @return 151 | */ 152 | public static int getNextLevelExperience(int currentLevel) 153 | { 154 | return (int) Math.pow(currentLevel, Config.expExponent) * Config.expMultiplier; 155 | } 156 | } 157 | -------------------------------------------------------------------------------- /src/main/java/com/thexfactor117/levels/leveling/Rarity.java: -------------------------------------------------------------------------------- 1 | package com.thexfactor117.levels.leveling; 2 | 3 | import java.util.Random; 4 | 5 | import com.thexfactor117.levels.util.RandomCollection; 6 | 7 | import net.minecraft.client.resources.I18n; 8 | import net.minecraft.nbt.NBTTagCompound; 9 | import net.minecraft.util.text.TextFormatting; 10 | import net.minecraftforge.fml.relauncher.Side; 11 | import net.minecraftforge.fml.relauncher.SideOnly; 12 | 13 | /** 14 | * 15 | * @author TheXFactor117 16 | * 17 | */ 18 | public enum Rarity 19 | { 20 | DEFAULT(TextFormatting.GRAY, 0, 0, 0, 0), 21 | COMMON(TextFormatting.WHITE, 0xFFFFFF, 0.65, 0xF0100010, 0x50FFFFFF), 22 | UNCOMMON(TextFormatting.DARK_GREEN, 0x00AA00, 0.2, 0xF0100010, 0x5000AA00), 23 | RARE(TextFormatting.AQUA, 0x55FFFF, 0.1, 0xF0100010, 0x5055FFFF), 24 | LEGENDARY(TextFormatting.DARK_PURPLE, 0xAA00AA, 0.045, 0xF0100010, 0x50AA00AA), 25 | MYTHIC(TextFormatting.GOLD, 0xFFAA00, 0.005, 0xF0100010, 0x50FFAA00); 26 | 27 | private String color; 28 | private int hex; 29 | private double defaultChance; 30 | private int backColor; 31 | private int borderColor; 32 | 33 | Rarity(Object color, int hex, double chance, int backColor, int borderColor) 34 | { 35 | this.color = color.toString(); 36 | this.hex = hex; 37 | this.defaultChance = chance; 38 | this.backColor = backColor; 39 | this.borderColor = borderColor; 40 | } 41 | 42 | /** 43 | * Returns a randomized rarity based on the Blacksmithing rank of the player. 44 | * @param nbt 45 | * @param blacksmithingRank 46 | * @param rand 47 | * @return 48 | */ 49 | public static Rarity getRandomRarity(NBTTagCompound nbt, Random rand) 50 | { 51 | RandomCollection random = new RandomCollection(); 52 | 53 | return random.next(rand); 54 | } 55 | 56 | /** 57 | * Return the current rarity in the given NBTTagCompound. Returns Common if it can't find it. 58 | * @param nbt 59 | * @return 60 | */ 61 | public static Rarity getRarity(NBTTagCompound nbt) 62 | { 63 | return nbt != null && nbt.hasKey("RARITY") ? Rarity.values()[nbt.getInteger("RARITY")] : DEFAULT; 64 | } 65 | 66 | /** 67 | * Sets the rarity specified to the given NBTTagCompound. 68 | * @param nbt 69 | * @param rarity 70 | */ 71 | public static void setRarity(NBTTagCompound nbt, Rarity rarity) 72 | { 73 | if (nbt != null) 74 | { 75 | nbt.setInteger("RARITY", rarity.ordinal()); 76 | } 77 | } 78 | 79 | /* 80 | * 81 | * GETTERS AND SETTERS 82 | * 83 | */ 84 | 85 | @SideOnly(Side.CLIENT) 86 | public String getName() 87 | { 88 | return I18n.format("levels.rarities." + ordinal()); 89 | } 90 | 91 | public String getColor() 92 | { 93 | return color; 94 | } 95 | 96 | public int getHex() 97 | { 98 | return hex; 99 | } 100 | 101 | public double getDefaultChance() 102 | { 103 | return defaultChance; 104 | } 105 | 106 | public int getBackgroundColor() 107 | { 108 | return backColor; 109 | } 110 | 111 | public int getBorderColor() 112 | { 113 | return borderColor; 114 | } 115 | } 116 | -------------------------------------------------------------------------------- /src/main/java/com/thexfactor117/levels/leveling/attributes/ArmorAttribute.java: -------------------------------------------------------------------------------- 1 | package com.thexfactor117.levels.leveling.attributes; 2 | 3 | import java.util.ArrayList; 4 | 5 | import com.thexfactor117.levels.config.Config; 6 | import com.thexfactor117.levels.leveling.Rarity; 7 | 8 | import net.minecraft.nbt.NBTTagCompound; 9 | import net.minecraft.util.text.TextFormatting; 10 | 11 | /** 12 | * 13 | * @author TheXFactor117 14 | * 15 | */ 16 | public enum ArmorAttribute 17 | { 18 | FIRE("Fire", Config.armorFire, TextFormatting.RED, 0xFF5555, Rarity.UNCOMMON), 19 | FROST("Frost", Config.armorFrost, TextFormatting.AQUA, 0x55FFFFF, Rarity.UNCOMMON), 20 | POISON("Poison", Config.armorPoison, TextFormatting.DARK_GREEN, 0x00AA00, Rarity.UNCOMMON), 21 | DURABLE("Durable", Config.armorDurable, TextFormatting.GRAY, 0xAAAAAA, Rarity.UNCOMMON), 22 | MAGICAL("Magical", Config.armorMagical, TextFormatting.BLUE, 0x5555FF, Rarity.RARE), 23 | SOUL_BOUND("Soul Bound", Config.armorSoulBound, TextFormatting.DARK_PURPLE, 0xAA00AA, Rarity.RARE), 24 | UNBREAKABLE("Unbreakable", Config.armorUnbreakable, TextFormatting.GRAY, 0xAAAAAA, Rarity.LEGENDARY); 25 | 26 | private String name; 27 | private boolean enabled; 28 | private String color; 29 | private int hex; 30 | private Rarity rarity; 31 | 32 | public static ArrayList ARMOR_ATTRIBUTES = new ArrayList(); 33 | 34 | ArmorAttribute(String name, boolean enabled, Object color, int hex, Rarity rarity) 35 | { 36 | this.name = name; 37 | this.enabled = enabled; 38 | this.color = color.toString(); 39 | this.hex = hex; 40 | this.rarity = rarity; 41 | } 42 | 43 | /** 44 | * Returns true if the NBT tag compound has the specified Attribute. 45 | * @param nbt 46 | * @return 47 | */ 48 | public boolean hasAttribute(NBTTagCompound nbt) 49 | { 50 | return nbt != null && nbt.getBoolean(toString()); 51 | } 52 | 53 | /** 54 | * Adds the specified Attribute to the NBT tag compound. 55 | * @param nbt 56 | */ 57 | public void addAttribute(NBTTagCompound nbt) 58 | { 59 | if (nbt != null) 60 | { 61 | nbt.setBoolean(toString(), true); 62 | nbt.setInteger(name + "_TIER", 1); 63 | } 64 | } 65 | 66 | /** 67 | * Removes the specified Attribute from the NBT tag compound. 68 | * @param nbt 69 | */ 70 | public void removeAttribute(NBTTagCompound nbt) 71 | { 72 | if (nbt != null) 73 | { 74 | nbt.removeTag(toString()); 75 | nbt.removeTag(name + "_TIER"); 76 | } 77 | } 78 | 79 | /** 80 | * Sets the tier of the specific attribute. 81 | * @param nbt 82 | * @param tier 83 | */ 84 | public void setAttributeTier(NBTTagCompound nbt, int tier) 85 | { 86 | if (nbt != null) 87 | { 88 | nbt.setInteger(name + "_TIER", tier); 89 | } 90 | } 91 | 92 | /** 93 | * Returns the tier of the specific attribute. 94 | * @param nbt 95 | * @return 96 | */ 97 | public int getAttributeTier(NBTTagCompound nbt) 98 | { 99 | return nbt != null ? nbt.getInteger(name + "_TIER") : 0; 100 | } 101 | 102 | public double getCalculatedValue(NBTTagCompound nbt, double baseValue, double multiplier) 103 | { 104 | if (getAttributeTier(nbt) == 1) 105 | return baseValue; 106 | else if (getAttributeTier(nbt) == 2) 107 | return baseValue * multiplier; 108 | else 109 | return baseValue * (Math.pow(multiplier, 2)); 110 | 111 | } 112 | 113 | public String getName(NBTTagCompound nbt) 114 | { 115 | if (getAttributeTier(nbt) == 1) 116 | return name; 117 | else if (getAttributeTier(nbt) == 2) 118 | return name + " II"; 119 | else if (getAttributeTier(nbt) == 3) 120 | return name + " III"; 121 | else 122 | return name; 123 | } 124 | 125 | public String getColor() 126 | { 127 | return color; 128 | } 129 | 130 | public int getHex() 131 | { 132 | return hex; 133 | } 134 | 135 | public Rarity getRarity() 136 | { 137 | return rarity; 138 | } 139 | 140 | static 141 | { 142 | for (int i = 0; i < ArmorAttribute.values().length; i++) 143 | { 144 | if (ArmorAttribute.values()[i].enabled) 145 | { 146 | ArmorAttribute.ARMOR_ATTRIBUTES.add(ArmorAttribute.values()[i]); 147 | } 148 | } 149 | } 150 | } 151 | -------------------------------------------------------------------------------- /src/main/java/com/thexfactor117/levels/leveling/attributes/BowAttribute.java: -------------------------------------------------------------------------------- 1 | package com.thexfactor117.levels.leveling.attributes; 2 | 3 | import java.util.ArrayList; 4 | 5 | import com.thexfactor117.levels.config.Config; 6 | import com.thexfactor117.levels.leveling.Rarity; 7 | 8 | import net.minecraft.nbt.NBTTagCompound; 9 | import net.minecraft.util.text.TextFormatting; 10 | 11 | /** 12 | * 13 | * @author TheXFactor117 14 | * 15 | */ 16 | public enum BowAttribute 17 | { 18 | FIRE("Fire", Config.bowFire, TextFormatting.RED, 0xFF5555, Rarity.UNCOMMON), 19 | FROST("Frost", Config.bowFrost, TextFormatting.AQUA, 0x55FFFF, Rarity.UNCOMMON), 20 | POISON("Poison", Config.bowPoison, TextFormatting.DARK_GREEN, 0x00AA00, Rarity.UNCOMMON), 21 | DURABLE("Durable", Config.bowDurable, TextFormatting.GRAY, 0xAAAAAA, Rarity.UNCOMMON), 22 | ABSORB("Absorb", Config.bowAbsorb, TextFormatting.GREEN, 0x55FF55, Rarity.RARE), 23 | SOUL_BOUND("Soul Bound", Config.bowSoulBound, TextFormatting.DARK_PURPLE, 0xAA00AA, Rarity.RARE), 24 | CRITICAL("Critical", Config.bowCritical, TextFormatting.BLUE, 0x5555FF, Rarity.RARE), 25 | RECOVER("Recover", Config.bowRecover, TextFormatting.DARK_AQUA, 0x00AAAA, Rarity.RARE), 26 | BARRAGE("Barrage", Config.bowBarrage, TextFormatting.DARK_RED, 0xAA0000, Rarity.LEGENDARY), 27 | UNBREAKABLE("Unbreakable", Config.bowUnbreakable, TextFormatting.GRAY, 0xAAAAAA, Rarity.LEGENDARY), 28 | VOID("Void", Config.bowVoid, TextFormatting.DARK_GRAY, 0x555555, Rarity.LEGENDARY); 29 | 30 | private String name; 31 | private boolean enabled; 32 | private String color; 33 | private int hex; 34 | private Rarity rarity; 35 | 36 | public static ArrayList BOW_ATTRIBUTES = new ArrayList(); 37 | 38 | BowAttribute(String name, boolean enabled, Object color, int hex, Rarity rarity) 39 | { 40 | this.name = name; 41 | this.enabled = enabled; 42 | this.color = color.toString(); 43 | this.hex = hex; 44 | this.rarity = rarity; 45 | } 46 | 47 | /** 48 | * Returns true if the NBT tag compound has the specified Attribute. 49 | * @param nbt 50 | * @return 51 | */ 52 | public boolean hasAttribute(NBTTagCompound nbt) 53 | { 54 | return nbt != null && nbt.getBoolean(toString()); 55 | } 56 | 57 | /** 58 | * Adds the specified Attribute to the NBT tag compound. 59 | * @param nbt 60 | */ 61 | public void addAttribute(NBTTagCompound nbt) 62 | { 63 | if (nbt != null) 64 | { 65 | nbt.setBoolean(toString(), true); 66 | nbt.setInteger(name + "_TIER", 1); 67 | } 68 | } 69 | 70 | /** 71 | * Removes the specified Attribute from the NBT tag compound. 72 | * @param nbt 73 | */ 74 | public void removeAttribute(NBTTagCompound nbt) 75 | { 76 | if (nbt != null) 77 | { 78 | nbt.removeTag(toString()); 79 | nbt.removeTag(name + "_TIER"); 80 | } 81 | } 82 | 83 | /** 84 | * Sets the tier of the specific attribute. 85 | * @param nbt 86 | * @param tier 87 | */ 88 | public void setAttributeTier(NBTTagCompound nbt, int tier) 89 | { 90 | if (nbt != null) 91 | { 92 | nbt.setInteger(name + "_TIER", tier); 93 | } 94 | } 95 | 96 | /** 97 | * Returns the tier of the specific attribute. 98 | * @param nbt 99 | * @return 100 | */ 101 | public int getAttributeTier(NBTTagCompound nbt) 102 | { 103 | return nbt != null ? nbt.getInteger(name + "_TIER") : 0; 104 | } 105 | 106 | public double getCalculatedValue(NBTTagCompound nbt, double baseValue, double multiplier) 107 | { 108 | if (getAttributeTier(nbt) == 1) 109 | return baseValue; 110 | else if (getAttributeTier(nbt) == 2) 111 | return baseValue * multiplier; 112 | else 113 | return baseValue * (Math.pow(multiplier, 2)); 114 | 115 | } 116 | 117 | public String getName(NBTTagCompound nbt) 118 | { 119 | if (getAttributeTier(nbt) == 1) 120 | return name; 121 | else if (getAttributeTier(nbt) == 2) 122 | return name + " II"; 123 | else if (getAttributeTier(nbt) == 3) 124 | return name + " III"; 125 | else 126 | return name; 127 | } 128 | 129 | public String getColor() 130 | { 131 | return color; 132 | } 133 | 134 | public int getHex() 135 | { 136 | return hex; 137 | } 138 | 139 | public Rarity getRarity() 140 | { 141 | return rarity; 142 | } 143 | 144 | static 145 | { 146 | for (int i = 0; i < BowAttribute.values().length; i++) 147 | { 148 | if (BowAttribute.values()[i].enabled) 149 | { 150 | BowAttribute.BOW_ATTRIBUTES.add(BowAttribute.values()[i]); 151 | } 152 | } 153 | } 154 | } 155 | -------------------------------------------------------------------------------- /src/main/java/com/thexfactor117/levels/leveling/attributes/ShieldAttribute.java: -------------------------------------------------------------------------------- 1 | package com.thexfactor117.levels.leveling.attributes; 2 | 3 | import java.util.ArrayList; 4 | 5 | import com.thexfactor117.levels.config.Config; 6 | import com.thexfactor117.levels.leveling.Rarity; 7 | 8 | import net.minecraft.nbt.NBTTagCompound; 9 | import net.minecraft.util.text.TextFormatting; 10 | 11 | /** 12 | * 13 | * @author TheXFactor117 14 | * 15 | */ 16 | public enum ShieldAttribute 17 | { 18 | FIRE("Fire", Config.shieldFire, TextFormatting.RED, 0xFF5555, Rarity.UNCOMMON), 19 | FROST("Frost", Config.shieldFrost, TextFormatting.AQUA, 0x55FFFF, Rarity.UNCOMMON), 20 | POISON("Poison", Config.shieldPoison, TextFormatting.DARK_GREEN, 0x00AA00, Rarity.UNCOMMON), 21 | DURABLE("Durable", Config.shieldDurable, TextFormatting.GRAY, 0xAAAAAA, Rarity.UNCOMMON), 22 | SOUL_BOUND("Soul Bound", Config.shieldSoulBound, TextFormatting.DARK_PURPLE, 0xAA00AA, Rarity.RARE), 23 | UNBREAKABLE("Unbreakable", Config.shieldUnbreakable, TextFormatting.GRAY, 0xAAAAAA, Rarity.LEGENDARY); 24 | 25 | private String name; 26 | private boolean enabled; 27 | private String color; 28 | private int hex; 29 | private Rarity rarity; 30 | 31 | public static ArrayList SHIELD_ATTRIBUTES = new ArrayList(); 32 | 33 | ShieldAttribute(String name, boolean enabled, Object color, int hex, Rarity rarity) 34 | { 35 | this.name = name; 36 | this.enabled = enabled; 37 | this.color = color.toString(); 38 | this.hex = hex; 39 | this.rarity = rarity; 40 | } 41 | 42 | /** 43 | * Returns true if the NBT tag compound has the specified Attribute. 44 | * @param nbt 45 | * @return 46 | */ 47 | public boolean hasAttribute(NBTTagCompound nbt) 48 | { 49 | return nbt != null && nbt.getBoolean(toString()); 50 | } 51 | 52 | /** 53 | * Adds the specified Attribute to the NBT tag compound. 54 | * @param nbt 55 | */ 56 | public void addAttribute(NBTTagCompound nbt) 57 | { 58 | if (nbt != null) 59 | { 60 | nbt.setBoolean(toString(), true); 61 | nbt.setInteger(name + "_TIER", 1); 62 | } 63 | } 64 | 65 | /** 66 | * Removes the specified Attribute from the NBT tag compound. 67 | * @param nbt 68 | */ 69 | public void removeAttribute(NBTTagCompound nbt) 70 | { 71 | if (nbt != null) 72 | { 73 | nbt.removeTag(toString()); 74 | nbt.removeTag(name + "_TIER"); 75 | } 76 | } 77 | 78 | /** 79 | * Sets the tier of the specific attribute. 80 | * @param nbt 81 | * @param tier 82 | */ 83 | public void setAttributeTier(NBTTagCompound nbt, int tier) 84 | { 85 | if (nbt != null) 86 | { 87 | nbt.setInteger(name + "_TIER", tier); 88 | } 89 | } 90 | 91 | /** 92 | * Returns the tier of the specific attribute. 93 | * @param nbt 94 | * @return 95 | */ 96 | public int getAttributeTier(NBTTagCompound nbt) 97 | { 98 | return nbt != null ? nbt.getInteger(name + "_TIER") : 0; 99 | } 100 | 101 | public double getCalculatedValue(NBTTagCompound nbt, double baseValue, double multiplier) 102 | { 103 | if (getAttributeTier(nbt) == 1) 104 | return baseValue; 105 | else if (getAttributeTier(nbt) == 2) 106 | return baseValue * multiplier; 107 | else 108 | return baseValue * (Math.pow(multiplier, 2)); 109 | 110 | } 111 | 112 | public String getName(NBTTagCompound nbt) 113 | { 114 | if (getAttributeTier(nbt) == 1) 115 | return name; 116 | else if (getAttributeTier(nbt) == 2) 117 | return name + " II"; 118 | else if (getAttributeTier(nbt) == 3) 119 | return name + " III"; 120 | else 121 | return name; 122 | } 123 | 124 | public String getColor() 125 | { 126 | return color; 127 | } 128 | 129 | public int getHex() 130 | { 131 | return hex; 132 | } 133 | 134 | public Rarity getRarity() 135 | { 136 | return rarity; 137 | } 138 | 139 | static 140 | { 141 | for (int i = 0; i < ShieldAttribute.values().length; i++) 142 | { 143 | if (ShieldAttribute.values()[i].enabled) 144 | { 145 | ShieldAttribute.SHIELD_ATTRIBUTES.add(ShieldAttribute.values()[i]); 146 | } 147 | } 148 | } 149 | } 150 | -------------------------------------------------------------------------------- /src/main/java/com/thexfactor117/levels/leveling/attributes/WeaponAttribute.java: -------------------------------------------------------------------------------- 1 | package com.thexfactor117.levels.leveling.attributes; 2 | 3 | import java.util.ArrayList; 4 | 5 | import com.thexfactor117.levels.config.Config; 6 | import com.thexfactor117.levels.leveling.Rarity; 7 | 8 | import net.minecraft.nbt.NBTTagCompound; 9 | import net.minecraft.util.text.TextFormatting; 10 | 11 | /** 12 | * 13 | * @author TheXFactor117 14 | * 15 | */ 16 | public enum WeaponAttribute 17 | { 18 | FIRE("Fire", Config.weaponFire, TextFormatting.RED, 0xFF5555, Rarity.UNCOMMON), 19 | FROST("Frost", Config.weaponFrost, TextFormatting.AQUA, 0x55FFFF, Rarity.UNCOMMON), 20 | POISON("Poison", Config.weaponPoison, TextFormatting.DARK_GREEN, 0x00AA00, Rarity.UNCOMMON), 21 | DURABLE("Durable", Config.weaponDurable, TextFormatting.GRAY, 0xAAAAAA, Rarity.UNCOMMON), 22 | ABSORB("Absorb", Config.weaponAbsorb, TextFormatting.GREEN, 0x55FF55, Rarity.RARE), 23 | SOUL_BOUND("Soul Bound", Config.weaponSoulBound, TextFormatting.DARK_PURPLE, 0xAA00AA, Rarity.RARE), 24 | CRITICAL("Critical", Config.weaponCritical, TextFormatting.BLUE, 0x5555FF, Rarity.RARE), 25 | CHAINED("Chained", Config.weaponChained, TextFormatting.WHITE, 0xFFFFFF, Rarity.LEGENDARY), 26 | UNBREAKABLE("Unbreakable", Config.weaponUnbreakable, TextFormatting.GRAY, 0xAAAAAA, Rarity.LEGENDARY), 27 | VOID("Void", Config.weaponVoid, TextFormatting.DARK_GRAY, 0x555555, Rarity.LEGENDARY); 28 | 29 | private String name; 30 | private boolean enabled; 31 | private String color; 32 | private int hex; 33 | private Rarity rarity; 34 | 35 | public static ArrayList WEAPON_ATTRIBUTES = new ArrayList(); 36 | 37 | WeaponAttribute(String name, boolean enabled, Object color, int hex, Rarity rarity) 38 | { 39 | this.name = name; 40 | this.enabled = enabled; 41 | this.color = color.toString(); 42 | this.hex = hex; 43 | this.rarity = rarity; 44 | } 45 | 46 | /** 47 | * Returns true if the NBT tag compound has the specified Attribute. 48 | * @param nbt 49 | * @return 50 | */ 51 | public boolean hasAttribute(NBTTagCompound nbt) 52 | { 53 | return nbt != null && nbt.getBoolean(toString()); 54 | } 55 | 56 | /** 57 | * Adds the specified Attribute to the NBT tag compound. 58 | * @param nbt 59 | */ 60 | public void addAttribute(NBTTagCompound nbt) 61 | { 62 | if (nbt != null) 63 | { 64 | nbt.setBoolean(toString(), true); 65 | nbt.setInteger(name + "_TIER", 1); 66 | } 67 | } 68 | 69 | /** 70 | * Removes the specified Attribute from the NBT tag compound. 71 | * @param nbt 72 | */ 73 | public void removeAttribute(NBTTagCompound nbt) 74 | { 75 | if (nbt != null) 76 | { 77 | nbt.removeTag(toString()); 78 | nbt.removeTag(name + "_TIER"); 79 | } 80 | } 81 | 82 | /** 83 | * Sets the tier of the specific attribute. 84 | * @param nbt 85 | * @param tier 86 | */ 87 | public void setAttributeTier(NBTTagCompound nbt, int tier) 88 | { 89 | if (nbt != null) 90 | { 91 | nbt.setInteger(name + "_TIER", tier); 92 | } 93 | } 94 | 95 | /** 96 | * Returns the tier of the specific attribute. 97 | * @param nbt 98 | * @return 99 | */ 100 | public int getAttributeTier(NBTTagCompound nbt) 101 | { 102 | return nbt != null ? nbt.getInteger(name + "_TIER") : 0; 103 | } 104 | 105 | public double getCalculatedValue(NBTTagCompound nbt, double baseValue, double multiplier) 106 | { 107 | if (getAttributeTier(nbt) == 1) 108 | return baseValue; 109 | else if (getAttributeTier(nbt) == 2) 110 | return baseValue * multiplier; 111 | else 112 | return baseValue * (Math.pow(multiplier, 2)); 113 | 114 | } 115 | 116 | public String getName(NBTTagCompound nbt) 117 | { 118 | if (getAttributeTier(nbt) == 1) 119 | return name; 120 | else if (getAttributeTier(nbt) == 2) 121 | return name + " II"; 122 | else if (getAttributeTier(nbt) == 3) 123 | return name + " III"; 124 | else 125 | return name; 126 | } 127 | 128 | public boolean isEnabled() 129 | { 130 | return enabled; 131 | } 132 | 133 | public String getColor() 134 | { 135 | return color; 136 | } 137 | 138 | public int getHex() 139 | { 140 | return hex; 141 | } 142 | 143 | public Rarity getRarity() 144 | { 145 | return rarity; 146 | } 147 | 148 | static 149 | { 150 | for (int i = 0; i < WeaponAttribute.values().length; i++) 151 | { 152 | if (WeaponAttribute.values()[i].enabled) 153 | { 154 | WeaponAttribute.WEAPON_ATTRIBUTES.add(WeaponAttribute.values()[i]); 155 | } 156 | } 157 | } 158 | } 159 | -------------------------------------------------------------------------------- /src/main/java/com/thexfactor117/levels/network/PacketAttributeSelection.java: -------------------------------------------------------------------------------- 1 | package com.thexfactor117.levels.network; 2 | 3 | import com.thexfactor117.levels.leveling.Experience; 4 | import com.thexfactor117.levels.leveling.Rarity; 5 | import com.thexfactor117.levels.leveling.attributes.ArmorAttribute; 6 | import com.thexfactor117.levels.leveling.attributes.BowAttribute; 7 | import com.thexfactor117.levels.leveling.attributes.ShieldAttribute; 8 | import com.thexfactor117.levels.leveling.attributes.WeaponAttribute; 9 | import com.thexfactor117.levels.util.NBTHelper; 10 | 11 | import io.netty.buffer.ByteBuf; 12 | import net.minecraft.entity.player.EntityPlayer; 13 | import net.minecraft.item.ItemArmor; 14 | import net.minecraft.item.ItemBow; 15 | import net.minecraft.item.ItemShield; 16 | import net.minecraft.item.ItemStack; 17 | import net.minecraft.item.ItemSword; 18 | import net.minecraft.nbt.NBTTagCompound; 19 | import net.minecraft.util.IThreadListener; 20 | import net.minecraft.world.WorldServer; 21 | import net.minecraftforge.fml.common.network.simpleimpl.IMessage; 22 | import net.minecraftforge.fml.common.network.simpleimpl.IMessageHandler; 23 | import net.minecraftforge.fml.common.network.simpleimpl.MessageContext; 24 | 25 | /** 26 | * 27 | * @author TheXFactor117 28 | * 29 | */ 30 | public class PacketAttributeSelection implements IMessage 31 | { 32 | private int index; 33 | 34 | public PacketAttributeSelection() {} 35 | 36 | public PacketAttributeSelection(int index) 37 | { 38 | this.index = index; 39 | } 40 | 41 | @Override 42 | public void fromBytes(ByteBuf buf) 43 | { 44 | index = buf.readInt(); 45 | } 46 | 47 | @Override 48 | public void toBytes(ByteBuf buf) 49 | { 50 | buf.writeInt(index); 51 | } 52 | 53 | public static class Handler implements IMessageHandler 54 | { 55 | @Override 56 | public IMessage onMessage(final PacketAttributeSelection message, final MessageContext ctx) 57 | { 58 | IThreadListener mainThread = (WorldServer) ctx.getServerHandler().playerEntity.getEntityWorld(); 59 | mainThread.addScheduledTask(new Runnable() 60 | { 61 | @Override 62 | public void run() 63 | { 64 | EntityPlayer player = ctx.getServerHandler().playerEntity; 65 | ItemStack stack = player.inventory.getCurrentItem(); 66 | NBTTagCompound nbt = NBTHelper.loadStackNBT(stack); 67 | 68 | if (player != null && stack != null && nbt != null) 69 | { 70 | if (stack.getItem() instanceof ItemSword) 71 | { 72 | WeaponAttribute attribute = WeaponAttribute.WEAPON_ATTRIBUTES.get(message.index); 73 | 74 | if (attribute.hasAttribute(nbt)) 75 | { 76 | attribute.setAttributeTier(nbt, attribute.getAttributeTier(nbt) + 1); 77 | Experience.setAttributeTokens(nbt, Experience.getAttributeTokens(nbt) - 1); 78 | } 79 | else 80 | { 81 | int cost = 1; 82 | 83 | if (attribute.getRarity() == Rarity.UNCOMMON) 84 | cost = 1; 85 | else if (attribute.getRarity() == Rarity.RARE) 86 | cost = 2; 87 | else if (attribute.getRarity() == Rarity.LEGENDARY) 88 | cost = 3; 89 | 90 | attribute.addAttribute(nbt); 91 | Experience.setAttributeTokens(nbt, Experience.getAttributeTokens(nbt) - cost); 92 | 93 | if (attribute == WeaponAttribute.UNBREAKABLE) 94 | nbt.setInteger("Unbreakable", 1); 95 | } 96 | } 97 | else if (stack.getItem() instanceof ItemArmor) 98 | { 99 | ArmorAttribute attribute = ArmorAttribute.ARMOR_ATTRIBUTES.get(message.index); 100 | 101 | if (attribute.hasAttribute(nbt)) 102 | { 103 | attribute.setAttributeTier(nbt, attribute.getAttributeTier(nbt) + 1); 104 | Experience.setAttributeTokens(nbt, Experience.getAttributeTokens(nbt) - 1); 105 | } 106 | else 107 | { 108 | int cost = 1; 109 | 110 | if (attribute.getRarity() == Rarity.UNCOMMON) 111 | cost = 1; 112 | else if (attribute.getRarity() == Rarity.RARE) 113 | cost = 2; 114 | else if (attribute.getRarity() == Rarity.LEGENDARY) 115 | cost = 3; 116 | 117 | attribute.addAttribute(nbt); 118 | Experience.setAttributeTokens(nbt, Experience.getAttributeTokens(nbt) - cost); 119 | 120 | if (attribute == ArmorAttribute.UNBREAKABLE) 121 | nbt.setInteger("Unbreakable", 1); 122 | } 123 | } 124 | else if (stack.getItem() instanceof ItemBow) 125 | { 126 | BowAttribute attribute = BowAttribute.BOW_ATTRIBUTES.get(message.index); 127 | 128 | if (attribute.hasAttribute(nbt)) 129 | { 130 | attribute.setAttributeTier(nbt, attribute.getAttributeTier(nbt) + 1); 131 | Experience.setAttributeTokens(nbt, Experience.getAttributeTokens(nbt) - 1); 132 | } 133 | else 134 | { 135 | int cost = 1; 136 | 137 | if (attribute.getRarity() == Rarity.UNCOMMON) 138 | cost = 1; 139 | else if (attribute.getRarity() == Rarity.RARE) 140 | cost = 2; 141 | else if (attribute.getRarity() == Rarity.LEGENDARY) 142 | cost = 3; 143 | 144 | attribute.addAttribute(nbt); 145 | Experience.setAttributeTokens(nbt, Experience.getAttributeTokens(nbt) - cost); 146 | 147 | if (attribute == BowAttribute.UNBREAKABLE) 148 | nbt.setInteger("Unbreakable", 1); 149 | } 150 | } 151 | else if (stack.getItem() instanceof ItemShield) 152 | { 153 | ShieldAttribute attribute = ShieldAttribute.SHIELD_ATTRIBUTES.get(message.index); 154 | 155 | if (attribute.hasAttribute(nbt)) 156 | { 157 | attribute.setAttributeTier(nbt, attribute.getAttributeTier(nbt) + 1); 158 | Experience.setAttributeTokens(nbt, Experience.getAttributeTokens(nbt) - 1); 159 | } 160 | else 161 | { 162 | int cost = 1; 163 | 164 | if (attribute.getRarity() == Rarity.UNCOMMON) 165 | cost = 1; 166 | else if (attribute.getRarity() == Rarity.RARE) 167 | cost = 2; 168 | else if (attribute.getRarity() == Rarity.LEGENDARY) 169 | cost = 3; 170 | 171 | attribute.addAttribute(nbt); 172 | Experience.setAttributeTokens(nbt, Experience.getAttributeTokens(nbt) - cost); 173 | 174 | if (attribute == ShieldAttribute.UNBREAKABLE) 175 | nbt.setInteger("Unbreakable", 1); 176 | } 177 | } 178 | } 179 | } 180 | }); 181 | 182 | return null; 183 | } 184 | } 185 | } 186 | -------------------------------------------------------------------------------- /src/main/java/com/thexfactor117/levels/network/PacketMythicSound.java: -------------------------------------------------------------------------------- 1 | package com.thexfactor117.levels.network; 2 | 3 | import io.netty.buffer.ByteBuf; 4 | import net.minecraft.client.Minecraft; 5 | import net.minecraft.entity.player.EntityPlayer; 6 | import net.minecraft.init.SoundEvents; 7 | import net.minecraft.util.IThreadListener; 8 | import net.minecraftforge.fml.common.network.simpleimpl.IMessage; 9 | import net.minecraftforge.fml.common.network.simpleimpl.IMessageHandler; 10 | import net.minecraftforge.fml.common.network.simpleimpl.MessageContext; 11 | 12 | /** 13 | * 14 | * @author TheXFactor117 15 | * 16 | */ 17 | public class PacketMythicSound implements IMessage 18 | { 19 | public PacketMythicSound() {} 20 | 21 | @Override 22 | public void fromBytes(ByteBuf buf) 23 | { 24 | 25 | } 26 | 27 | @Override 28 | public void toBytes(ByteBuf buf) 29 | { 30 | 31 | } 32 | 33 | public static class Handler implements IMessageHandler 34 | { 35 | @Override 36 | public IMessage onMessage(final PacketMythicSound message, final MessageContext ctx) 37 | { 38 | IThreadListener mainThread = Minecraft.getMinecraft(); 39 | mainThread.addScheduledTask(new Runnable() 40 | { 41 | @Override 42 | public void run() 43 | { 44 | EntityPlayer player = Minecraft.getMinecraft().player; 45 | player.playSound(SoundEvents.ENTITY_ENDERDRAGON_DEATH, 1.0F, 1.0F); 46 | } 47 | }); 48 | 49 | return null; 50 | } 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /src/main/java/com/thexfactor117/levels/proxies/ClientProxy.java: -------------------------------------------------------------------------------- 1 | package com.thexfactor117.levels.proxies; 2 | 3 | import org.lwjgl.input.Keyboard; 4 | 5 | import net.minecraft.client.settings.KeyBinding; 6 | import net.minecraftforge.fml.client.registry.ClientRegistry; 7 | 8 | /** 9 | * 10 | * @author TheXFactor117 11 | * 12 | */ 13 | public class ClientProxy extends CommonProxy 14 | { 15 | public static KeyBinding keyBindingL; 16 | 17 | @Override 18 | public void preInit() {} 19 | 20 | @Override 21 | public void init() 22 | { 23 | keyBindingL = new KeyBinding("key.gui.weapon_interface", Keyboard.KEY_L, "key.levels"); 24 | 25 | ClientRegistry.registerKeyBinding(keyBindingL); 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /src/main/java/com/thexfactor117/levels/proxies/CommonProxy.java: -------------------------------------------------------------------------------- 1 | package com.thexfactor117.levels.proxies; 2 | 3 | /** 4 | * 5 | * @author TheXFactor117 6 | * 7 | */ 8 | public class CommonProxy 9 | { 10 | public void preInit() {} 11 | public void init() {} 12 | public void postInit() {} 13 | } -------------------------------------------------------------------------------- /src/main/java/com/thexfactor117/levels/util/CapabilityUtils.java: -------------------------------------------------------------------------------- 1 | package com.thexfactor117.levels.util; 2 | 3 | import javax.annotation.Nullable; 4 | 5 | import net.minecraft.util.EnumFacing; 6 | import net.minecraftforge.common.capabilities.Capability; 7 | import net.minecraftforge.common.capabilities.ICapabilityProvider; 8 | 9 | /** 10 | * 11 | * @author TheXFactor117 12 | * 13 | */ 14 | public class CapabilityUtils 15 | { 16 | @Nullable 17 | public static T getCapability(@Nullable ICapabilityProvider provider, Capability capability, @Nullable EnumFacing facing) 18 | { 19 | return provider != null && provider.hasCapability(capability, facing) ? provider.getCapability(capability, facing) : null; 20 | } 21 | } -------------------------------------------------------------------------------- /src/main/java/com/thexfactor117/levels/util/GuiHandler.java: -------------------------------------------------------------------------------- 1 | package com.thexfactor117.levels.util; 2 | 3 | import com.thexfactor117.levels.client.gui.GuiItemInformation; 4 | import com.thexfactor117.levels.client.gui.selection.GuiArmorSelection; 5 | import com.thexfactor117.levels.client.gui.selection.GuiBowSelection; 6 | import com.thexfactor117.levels.client.gui.selection.GuiShieldSelection; 7 | import com.thexfactor117.levels.client.gui.selection.GuiWeaponSelection; 8 | 9 | import net.minecraft.entity.player.EntityPlayer; 10 | import net.minecraft.world.World; 11 | import net.minecraftforge.fml.common.network.IGuiHandler; 12 | 13 | /** 14 | * 15 | * @author TheXFactor117 16 | * 17 | */ 18 | public class GuiHandler implements IGuiHandler 19 | { 20 | public static final int ITEM_INFORMATION = 0; 21 | public static final int WEAPON_ATTRIBUTES = 1; 22 | public static final int ARMOR_ATTRIBUTES = 2; 23 | public static final int BOW_ATTRIBUTES = 3; 24 | public static final int SHIELD_ATTRIBUTES = 4; 25 | 26 | @Override 27 | public Object getServerGuiElement(int ID, EntityPlayer player, World world, int x, int y, int z) 28 | { 29 | return null; 30 | } 31 | 32 | @Override 33 | public Object getClientGuiElement(int ID, EntityPlayer player, World world, int x, int y, int z) 34 | { 35 | if (ID == ITEM_INFORMATION) 36 | return new GuiItemInformation(); 37 | if (ID == WEAPON_ATTRIBUTES) 38 | return new GuiWeaponSelection(); 39 | if (ID == ARMOR_ATTRIBUTES) 40 | return new GuiArmorSelection(); 41 | if (ID == BOW_ATTRIBUTES) 42 | return new GuiBowSelection(); 43 | if (ID == SHIELD_ATTRIBUTES) 44 | return new GuiShieldSelection(); 45 | 46 | return null; 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /src/main/java/com/thexfactor117/levels/util/NBTHelper.java: -------------------------------------------------------------------------------- 1 | package com.thexfactor117.levels.util; 2 | 3 | import net.minecraft.item.ItemStack; 4 | import net.minecraft.nbt.NBTTagCompound; 5 | 6 | /** 7 | * 8 | * @author TheXFactor117 9 | * 10 | */ 11 | public class NBTHelper 12 | { 13 | public static NBTTagCompound loadStackNBT(ItemStack stack) 14 | { 15 | return stack.hasTagCompound() ? stack.getTagCompound() : new NBTTagCompound(); 16 | } 17 | 18 | public static void saveStackNBT(ItemStack stack, NBTTagCompound nbt) 19 | { 20 | if (!stack.hasTagCompound() && !nbt.hasNoTags()) 21 | { 22 | stack.setTagCompound(nbt); 23 | } 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /src/main/java/com/thexfactor117/levels/util/RandomCollection.java: -------------------------------------------------------------------------------- 1 | package com.thexfactor117.levels.util; 2 | 3 | import java.util.NavigableMap; 4 | import java.util.Random; 5 | import java.util.TreeMap; 6 | 7 | /** 8 | * 9 | * @author TheXFactor117 10 | * 11 | */ 12 | public class RandomCollection 13 | { 14 | private final NavigableMap map = new TreeMap(); 15 | private double total = 0; 16 | 17 | public void add(double weight, E result) 18 | { 19 | if (weight <= 0) return; 20 | total += weight; 21 | map.put(total, result); 22 | } 23 | 24 | public E next(Random random) 25 | { 26 | double value = random.nextDouble() * total; 27 | return map.ceilingEntry(value).getValue(); 28 | } 29 | } -------------------------------------------------------------------------------- /src/main/java/com/thexfactor117/levels/util/Reference.java: -------------------------------------------------------------------------------- 1 | package com.thexfactor117.levels.util; 2 | 3 | /** 4 | * 5 | * @author TheXFactor117 6 | * 7 | */ 8 | public class Reference 9 | { 10 | public static final String MODID = "levels"; 11 | public static final String NAME = "Levels"; 12 | public static final String VERSION = "@VERSION@"; 13 | public static final String UPDATE_URL = "https://raw.githubusercontent.com/TheXFactor117/Levels/master/levels-version-checker.json"; 14 | public static final String COMMON = "com.thexfactor117.levels.proxies.CommonProxy"; 15 | public static final String CLIENT = "com.thexfactor117.levels.proxies.ClientProxy"; 16 | } 17 | -------------------------------------------------------------------------------- /src/main/java/com/thexfactor117/levels/util/SimpleCapabilityProvider.java: -------------------------------------------------------------------------------- 1 | package com.thexfactor117.levels.util; 2 | 3 | import javax.annotation.Nullable; 4 | 5 | import net.minecraft.nbt.NBTBase; 6 | import net.minecraft.util.EnumFacing; 7 | import net.minecraftforge.common.capabilities.Capability; 8 | import net.minecraftforge.common.capabilities.ICapabilitySerializable; 9 | 10 | /** 11 | * 12 | * @author TheXFactor117 13 | * 14 | */ 15 | public class SimpleCapabilityProvider implements ICapabilitySerializable 16 | { 17 | private final Capability capability; 18 | private final EnumFacing facing; 19 | private final HANDLER instance; 20 | 21 | public SimpleCapabilityProvider(Capability capability, @Nullable EnumFacing facing) 22 | { 23 | this(capability, facing, capability.getDefaultInstance()); 24 | } 25 | 26 | public SimpleCapabilityProvider(Capability capability, @Nullable EnumFacing facing, HANDLER instance) 27 | { 28 | this.capability = capability; 29 | this.instance = instance; 30 | this.facing = facing; 31 | } 32 | 33 | @Override 34 | public boolean hasCapability(Capability capability, EnumFacing facing) 35 | { 36 | return capability == getCapability(); 37 | } 38 | 39 | @Override 40 | @Nullable 41 | public T getCapability(Capability capability, EnumFacing facing) 42 | { 43 | if (capability == getCapability()) 44 | { 45 | return getCapability().cast(getInstance()); 46 | } 47 | 48 | return null; 49 | } 50 | 51 | @Override 52 | public NBTBase serializeNBT() 53 | { 54 | return getCapability().writeNBT(getInstance(), getFacing()); 55 | } 56 | 57 | @Override 58 | public void deserializeNBT(NBTBase nbt) 59 | { 60 | getCapability().readNBT(getInstance(), getFacing(), nbt); 61 | } 62 | 63 | public final Capability getCapability() 64 | { 65 | return capability; 66 | } 67 | 68 | @Nullable 69 | public EnumFacing getFacing() 70 | { 71 | return facing; 72 | } 73 | 74 | public final HANDLER getInstance() 75 | { 76 | return instance; 77 | } 78 | } -------------------------------------------------------------------------------- /src/main/java/com/thexfactor117/levels/util/WeaponHelper.java: -------------------------------------------------------------------------------- 1 | package com.thexfactor117.levels.util; 2 | 3 | import java.util.Collection; 4 | import java.util.Random; 5 | import java.util.UUID; 6 | 7 | import com.google.common.collect.Multimap; 8 | import com.thexfactor117.levels.Levels; 9 | import com.thexfactor117.levels.config.Config; 10 | import com.thexfactor117.levels.leveling.Experience; 11 | import com.thexfactor117.levels.leveling.Rarity; 12 | import com.thexfactor117.levels.network.PacketMythicSound; 13 | 14 | import net.minecraft.entity.SharedMonsterAttributes; 15 | import net.minecraft.entity.ai.attributes.AttributeModifier; 16 | import net.minecraft.entity.ai.attributes.IAttribute; 17 | import net.minecraft.entity.player.EntityPlayer; 18 | import net.minecraft.entity.player.EntityPlayerMP; 19 | import net.minecraft.inventory.EntityEquipmentSlot; 20 | import net.minecraft.item.Item; 21 | import net.minecraft.item.ItemArmor; 22 | import net.minecraft.item.ItemAxe; 23 | import net.minecraft.item.ItemStack; 24 | import net.minecraft.item.ItemSword; 25 | import net.minecraft.nbt.NBTTagCompound; 26 | import net.minecraft.nbt.NBTTagList; 27 | import net.minecraft.network.play.server.SPacketTitle; 28 | import net.minecraft.util.text.TextComponentString; 29 | import net.minecraft.util.text.TextFormatting; 30 | 31 | /** 32 | * 33 | * @author TheXFactor117 34 | * 35 | */ 36 | public class WeaponHelper 37 | { 38 | private static final UUID ATTACK_DAMAGE = UUID.fromString("38d403d3-3e25-4638-957f-71cd25273933"); 39 | private static final UUID ATTACK_SPEED = UUID.fromString("106410b5-3fa8-4fcf-8252-ca4292dc0391"); 40 | private static final UUID ARMOR = UUID.fromString("6ff9f9f0-0498-4623-aeca-a1afa64188e7"); 41 | private static final UUID ARMOR_TOUGHNESS = UUID.fromString("245507c2-cb9d-4274-81ee-ecced32dafe4"); 42 | 43 | public static void create(ItemStack stack, EntityPlayer player) 44 | { 45 | NBTTagCompound nbt = NBTHelper.loadStackNBT(stack); 46 | 47 | if (nbt != null) 48 | { 49 | Rarity rarity = Rarity.getRarity(nbt); 50 | Random rand = player.getEntityWorld().rand; 51 | 52 | if (rarity == Rarity.DEFAULT) 53 | { 54 | Rarity.setRarity(nbt, Rarity.getRandomRarity(nbt, rand)); // sets random rarity 55 | 56 | if (Rarity.getRarity(nbt) == Rarity.MYTHIC) 57 | { 58 | SPacketTitle packet = new SPacketTitle(SPacketTitle.Type.TITLE, new TextComponentString(TextFormatting.GOLD + "MYTHIC"), -1, 20, -1); 59 | EntityPlayerMP playermp = (EntityPlayerMP) player; 60 | playermp.connection.sendPacket(packet); 61 | Levels.network.sendTo(new PacketMythicSound(), (EntityPlayerMP) player); 62 | } 63 | 64 | if (Config.unlimitedDurability) 65 | { 66 | nbt.setInteger("Unbreakable", 1); // adds Unbreakable tag to item 67 | } 68 | 69 | Experience.setLevel(nbt, 1); 70 | nbt.setDouble("Multiplier", getWeightedMultiplier(Rarity.getRarity(nbt))); // adds a randomized multiplier to the item, weighted by rarity 71 | nbt.setInteger("HideFlags", 6); // hides Attribute Modifier and Unbreakable tags 72 | setAttributeModifiers(nbt, stack); // sets up Attribute Modifiers 73 | NBTHelper.saveStackNBT(stack, nbt); 74 | } 75 | } 76 | } 77 | 78 | /** 79 | * Creates a new Attribute Modifier tag list and adds it to the NBTTagCompound. Overrides default vanilla implementation. 80 | * @param nbt 81 | * @param sword 82 | */ 83 | private static void setAttributeModifiers(NBTTagCompound nbt, ItemStack stack) 84 | { 85 | Item item = stack.getItem(); 86 | 87 | if (item instanceof ItemSword || item instanceof ItemAxe) 88 | { 89 | // retrieves the default attributes, like damage and attack speed. 90 | @SuppressWarnings("deprecation") 91 | Multimap map = item.getItemAttributeModifiers(EntityEquipmentSlot.MAINHAND); 92 | Collection damageCollection = map.get(SharedMonsterAttributes.ATTACK_DAMAGE.getName()); 93 | Collection speedCollection = map.get(SharedMonsterAttributes.ATTACK_SPEED.getName()); 94 | AttributeModifier damageModifier = (AttributeModifier) damageCollection.toArray()[0]; 95 | AttributeModifier speedModifier = (AttributeModifier) speedCollection.toArray()[0]; 96 | 97 | double baseDamage = damageModifier.getAmount() + 1; // add one to base damage for player strength 98 | double baseSpeed = speedModifier.getAmount(); 99 | double damage = getWeightedDamage(Rarity.getRarity(nbt), baseDamage); 100 | double speed = getWeightedAttackSpeed(Rarity.getRarity(nbt), baseSpeed); 101 | 102 | // Creates new AttributeModifier's and applies them to the stack's NBT tag compound. 103 | AttributeModifier attackDamage = new AttributeModifier(ATTACK_DAMAGE, "attackDamage", damage, 0); 104 | AttributeModifier attackSpeed = new AttributeModifier(ATTACK_SPEED, "attackSpeed", speed, 0); 105 | NBTTagCompound damageNbt = writeAttributeModifierToNBT(SharedMonsterAttributes.ATTACK_DAMAGE, attackDamage, EntityEquipmentSlot.MAINHAND); 106 | NBTTagCompound speedNbt = writeAttributeModifierToNBT(SharedMonsterAttributes.ATTACK_SPEED, attackSpeed, EntityEquipmentSlot.MAINHAND); 107 | NBTTagList list = new NBTTagList(); 108 | list.appendTag(damageNbt); 109 | list.appendTag(speedNbt); 110 | nbt.setTag("AttributeModifiers", list); 111 | } 112 | else if (item instanceof ItemArmor) 113 | { 114 | Multimap map = ((ItemArmor) item).getAttributeModifiers(((ItemArmor) item).armorType, stack); 115 | Collection armorCollection = map.get(SharedMonsterAttributes.ARMOR.getName()); 116 | Collection toughnessCollection = map.get(SharedMonsterAttributes.ARMOR_TOUGHNESS.getName()); 117 | AttributeModifier armorModifier = (AttributeModifier) armorCollection.toArray()[0]; 118 | AttributeModifier toughnessModifier = (AttributeModifier) toughnessCollection.toArray()[0]; 119 | 120 | double baseArmor = armorModifier.getAmount(); 121 | double baseToughness = toughnessModifier.getAmount(); 122 | double newArmor = getWeightedArmor(Rarity.getRarity(nbt), baseArmor); 123 | double newToughness = getWeightedArmorToughness(Rarity.getRarity(nbt), baseToughness); 124 | 125 | // Creates new AttributeModifier's and applies them to the stack's NBT tag compound. 126 | AttributeModifier armor = new AttributeModifier(ARMOR, "armor", newArmor, 0); 127 | AttributeModifier toughness = new AttributeModifier(ARMOR_TOUGHNESS, "armorToughness", newToughness, 0); 128 | NBTTagCompound armorNbt = writeAttributeModifierToNBT(SharedMonsterAttributes.ARMOR, armor, ((ItemArmor) item).armorType); 129 | NBTTagCompound toughnessNbt = writeAttributeModifierToNBT(SharedMonsterAttributes.ARMOR_TOUGHNESS, toughness, ((ItemArmor) item).armorType); 130 | NBTTagList list = new NBTTagList(); 131 | list.appendTag(armorNbt); 132 | list.appendTag(toughnessNbt); 133 | nbt.setTag("AttributeModifiers", list); 134 | } 135 | } 136 | 137 | /** 138 | * Returns a damage value based on the rarity and base damage of the weapon. 139 | * @param rarity 140 | * @param baseDamage 141 | * @return 142 | */ 143 | private static double getWeightedDamage(Rarity rarity, double baseDamage) 144 | { 145 | double damage = baseDamage; 146 | int range; 147 | 148 | switch (rarity) 149 | { 150 | case COMMON: 151 | range = 3; 152 | damage = Math.random() * range + (baseDamage - 2); 153 | break; 154 | case UNCOMMON: 155 | range = 4; 156 | damage = Math.random() * range + (baseDamage - 1); 157 | break; 158 | case RARE: 159 | range = 5; 160 | damage = Math.random() * range + (baseDamage + 1); 161 | break; 162 | case LEGENDARY: 163 | range = 6; 164 | damage = Math.random() * range + (baseDamage + 2); 165 | break; 166 | case MYTHIC: 167 | range = 7; 168 | damage = Math.random() * range + (baseDamage + 3); 169 | break; 170 | default: 171 | break; 172 | } 173 | 174 | return damage; 175 | } 176 | 177 | /** 178 | * Returns an attack speed value based on the rarity and base attack speed of the weapon. 179 | * @param rarity 180 | * @param baseAttackSpeed 181 | * @return 182 | */ 183 | private static double getWeightedAttackSpeed(Rarity rarity, double baseAttackSpeed) 184 | { 185 | double attackSpeed = baseAttackSpeed; 186 | double range; 187 | 188 | switch (rarity) 189 | { 190 | case COMMON: 191 | range = 0.2; 192 | attackSpeed = Math.random() * range + (baseAttackSpeed - 0.2); 193 | break; 194 | case UNCOMMON: 195 | range = 0.3; 196 | attackSpeed = Math.random() * range + (baseAttackSpeed - 0.1); 197 | break; 198 | case RARE: 199 | range = 0.4; 200 | attackSpeed = Math.random() * range + (baseAttackSpeed + 0.1); 201 | break; 202 | case LEGENDARY: 203 | range = 0.5; 204 | attackSpeed = Math.random() * range + (baseAttackSpeed + 0.2); 205 | break; 206 | case MYTHIC: 207 | range = 0.6; 208 | attackSpeed = Math.random() * range + (baseAttackSpeed + 0.3); 209 | break; 210 | default: 211 | break; 212 | } 213 | 214 | return attackSpeed; 215 | } 216 | 217 | /** 218 | * Returns an armor value based on the rarity and base armor of the armor. 219 | * @param rarity 220 | * @param baseArmor 221 | * @return 222 | */ 223 | private static double getWeightedArmor(Rarity rarity, double baseArmor) 224 | { 225 | double armor = baseArmor; 226 | double range; 227 | 228 | switch (rarity) 229 | { 230 | case COMMON: 231 | range = 0.2; 232 | armor = Math.random() * range + (baseArmor - 0.2); 233 | break; 234 | case UNCOMMON: 235 | range = 0.3; 236 | armor = Math.random() * range + (baseArmor - 0.1); 237 | break; 238 | case RARE: 239 | range = 0.4; 240 | armor = Math.random() * range + (baseArmor + 0.1); 241 | break; 242 | case LEGENDARY: 243 | range = 0.5; 244 | armor = Math.random() * range + (baseArmor + 0.2); 245 | break; 246 | case MYTHIC: 247 | range = 0.6; 248 | armor = Math.random() * range + (baseArmor + 0.3); 249 | break; 250 | default: 251 | break; 252 | } 253 | 254 | return armor; 255 | } 256 | 257 | /** 258 | * Returns a toughness value based on the rarity and base toughness of the armor. 259 | * @param rarity 260 | * @param baseToughness 261 | * @return 262 | */ 263 | private static double getWeightedArmorToughness(Rarity rarity, double baseToughness) 264 | { 265 | double toughness = baseToughness; 266 | double range; 267 | 268 | switch (rarity) 269 | { 270 | case COMMON: 271 | range = 0.2; 272 | toughness = Math.random() * range + (baseToughness - 0.2); 273 | break; 274 | case UNCOMMON: 275 | range = 0.3; 276 | toughness = Math.random() * range + (baseToughness - 0.1); 277 | break; 278 | case RARE: 279 | range = 0.4; 280 | toughness = Math.random() * range + (baseToughness + 0.1); 281 | break; 282 | case LEGENDARY: 283 | range = 0.5; 284 | toughness = Math.random() * range + (baseToughness + 0.2); 285 | break; 286 | case MYTHIC: 287 | range = 0.6; 288 | toughness = Math.random() * range + (baseToughness + 0.3); 289 | break; 290 | default: 291 | break; 292 | } 293 | 294 | if (toughness < 0) 295 | return 0; 296 | 297 | return toughness; 298 | } 299 | 300 | /** 301 | * Returns a randomized, weighted multiplier. 302 | * @param rarity 303 | * @return 304 | */ 305 | private static double getWeightedMultiplier(Rarity rarity) 306 | { 307 | double range = 0D; 308 | 309 | switch (rarity) 310 | { 311 | case COMMON: 312 | range = 0.05; 313 | break; 314 | case UNCOMMON: 315 | range = 0.08; 316 | break; 317 | case RARE: 318 | range = 0.13; 319 | break; 320 | case LEGENDARY: 321 | range = 0.2; 322 | break; 323 | case MYTHIC: 324 | range = 0.3; 325 | break; 326 | default: 327 | break; 328 | } 329 | 330 | double multiplier = Math.random() * range; 331 | 332 | return multiplier; 333 | } 334 | 335 | private static NBTTagCompound writeAttributeModifierToNBT(IAttribute attribute, AttributeModifier modifier, EntityEquipmentSlot slot) 336 | { 337 | NBTTagCompound nbt = new NBTTagCompound(); 338 | 339 | nbt.setString("AttributeName", attribute.getName()); 340 | nbt.setString("Name", modifier.getName()); 341 | nbt.setString("Slot", slot.getName()); 342 | nbt.setDouble("Amount", modifier.getAmount()); 343 | nbt.setInteger("Operation", modifier.getOperation()); 344 | nbt.setLong("UUIDMost", modifier.getID().getMostSignificantBits()); 345 | nbt.setLong("UUIDLeast", modifier.getID().getLeastSignificantBits()); 346 | 347 | return nbt; 348 | } 349 | } 350 | -------------------------------------------------------------------------------- /src/main/resources/assets/levels/lang/da_DK.lang: -------------------------------------------------------------------------------- 1 | levels.rarity.0=Standard 2 | levels.rarity.1=Basal 3 | levels.rarity.2=Ualmindelig 4 | levels.rarity.3=Sjælden 5 | levels.rarity.4=Ultra Sjælden 6 | levels.rarity.5=Legendarisk 7 | levels.rarity.6=Arkaisk 8 | 9 | levels.ability.0=Ild 10 | levels.ability.1=Frost 11 | levels.ability.2=Gift 12 | levels.ability.3=Blodtørst 13 | levels.ability.4=Kædet 14 | levels.ability.5=Tomrum 15 | levels.ability.6=Lys 16 | levels.ability.7=Æterisk 17 | levels.ability.8=Sjældebunden 18 | levels.ability.9=Smeltet 19 | levels.ability.10=Frossen 20 | levels.ability.11=Giftig 21 | levels.ability.12=Absorberende 22 | levels.ability.13=Tomrum 23 | levels.ability.14=Bestialsk 24 | levels.ability.15=Oplyst 25 | levels.ability.16=Hærdet 26 | levels.ability.17=Sjældebunden 27 | 28 | levels.misc.level=Level 29 | levels.misc.max=Max 30 | levels.misc.experience=Erfaring 31 | levels.misc.durability=Slidstyrke 32 | levels.misc.abilities=Evner 33 | levels.misc.abilities.shift=Evner (Shift) 34 | levels.misc.rarity=Sjældenhed 35 | levels.misc.abilities.tokens=Evnepoletter 36 | levels.misc.abilities.purchased=Købte Evner 37 | levels.misc.abilities.active=Aktiv 38 | levels.misc.abilities.passive=Passiv 39 | 40 | levels.update=Levels har nye tilgængelige versioner! 41 | levels.login1=Tryk 'L' med noget udstyr for at komme i gang! 42 | levels.login2=(Du kan slå denne besked fra i config-filen) 43 | -------------------------------------------------------------------------------- /src/main/resources/assets/levels/lang/de_DE.lang: -------------------------------------------------------------------------------- 1 | levels.rarity.0=Standard 2 | levels.rarity.1=Einfach 3 | levels.rarity.2=Ungewöhnlich 4 | levels.rarity.3=Selten 5 | levels.rarity.4=Hochselten 6 | levels.rarity.5=Legendär 7 | levels.rarity.6=Altmodisch 8 | 9 | levels.ability.0=Feuer 10 | levels.ability.1=Frost 11 | levels.ability.2=Gift 12 | levels.ability.3=Blutrausch 13 | levels.ability.4=Verkettet 14 | levels.ability.5=Leere 15 | levels.ability.6=Licht 16 | levels.ability.7=Himmlisch 17 | levels.ability.8=Seelengebunden 18 | levels.ability.9=Geschmolzen 19 | levels.ability.10=Gefroren 20 | levels.ability.11=Giftig 21 | levels.ability.12=Absorbierend 22 | levels.ability.13=Leere 23 | levels.ability.14=Beastialisch 24 | levels.ability.15=Erleuchtet 25 | levels.ability.16=Gehärtet 26 | levels.ability.17=Seelengebunden 27 | 28 | levels.misc.level=Level 29 | levels.misc.max=Max 30 | levels.misc.experience=Erfahrung 31 | levels.misc.durability=Haltbarkeit 32 | levels.misc.abilities=Fähigkeiten 33 | levels.misc.abilities.shift=Fähigkeiten (Shift) 34 | levels.misc.rarity=Seltenheit 35 | levels.misc.abilities.tokens=Fähigkeiten-Wertmarken 36 | levels.misc.abilities.purchased=Gekaufte Fähigkeiten 37 | levels.misc.abilities.active=Aktiv 38 | levels.misc.abilities.passive=Passiv 39 | 40 | levels.update=Es ist eine neue Version von Levels verfügbar! 41 | -------------------------------------------------------------------------------- /src/main/resources/assets/levels/lang/en_US.lang: -------------------------------------------------------------------------------- 1 | levels.rarities.0=Default 2 | levels.rarities.1=Common 3 | levels.rarities.2=Uncommon 4 | levels.rarities.3=Rare 5 | levels.rarities.4=Legendary 6 | levels.rarities.5=Mythic 7 | 8 | levels.misc.level=Level 9 | levels.misc.max=Max 10 | levels.misc.experience=Experience 11 | levels.misc.durability=Durability 12 | levels.misc.durability.unlimited=Unlimited 13 | levels.misc.rarity=Rarity 14 | levels.misc.attributes=Attributes 15 | levels.misc.attributes.shift=Attributes (Shift) 16 | levels.misc.attributes.tokens=Attribute Tokens 17 | levels.misc.attributes.current=Current Attributes 18 | 19 | ### 20 | ## WEAPONS 21 | ### 22 | 23 | levels.attributes.weapons.info.0=Sets enemies on fire for a short time. 24 | levels.attributes.weapons.info.1=Stuns enemies for a short time. 25 | levels.attributes.weapons.info.2=Poisons enemies for a short time. 26 | levels.attributes.weapons.info.3=Your weapon becomes slightly more durable than usual. 27 | levels.attributes.weapons.info.4=Absorb a portion of the damage dealt as health. 28 | levels.attributes.weapons.info.5=Your weapon stays in your inventory on death. 29 | levels.attributes.weapons.info.6=Percentage chance at performing a critical strike. 30 | levels.attributes.weapons.info.7=Percentage chance for enemies within a certain radius to take half the damage as well. 31 | levels.attributes.weapons.info.8=Your weapon will never break or degrade. 32 | levels.attributes.weapons.info.9=There is a slight chance at instantly killing the enemy. 33 | 34 | levels.attributes.weapons.info.0.tier1=4 seconds 35 | levels.attributes.weapons.info.0.tier2=5 seconds 36 | levels.attributes.weapons.info.0.tier3=6 seconds 37 | levels.attributes.weapons.info.1.tier1=1 second 38 | levels.attributes.weapons.info.1.tier2=1.5 seconds 39 | levels.attributes.weapons.info.1.tier3=2 seconds 40 | levels.attributes.weapons.info.2.tier1=7 seconds 41 | levels.attributes.weapons.info.2.tier2=10.5 seconds 42 | levels.attributes.weapons.info.2.tier3=15 seconds 43 | levels.attributes.weapons.info.3.tier1=1 durability point 44 | levels.attributes.weapons.info.3.tier2=2 durability points 45 | levels.attributes.weapons.info.3.tier3=4 durability points 46 | levels.attributes.weapons.info.4.tier1=25%% 47 | levels.attributes.weapons.info.4.tier2=37.5%% 48 | levels.attributes.weapons.info.4.tier3=56%% 49 | levels.attributes.weapons.info.5.tier1=Item remains in inventory on death. 50 | levels.attributes.weapons.info.5.tier2=NOTHING 51 | levels.attributes.weapons.info.5.tier3=NOTHING 52 | levels.attributes.weapons.info.6.tier1=20%% 53 | levels.attributes.weapons.info.6.tier2=30%% 54 | levels.attributes.weapons.info.6.tier3=45%% 55 | levels.attributes.weapons.info.7.tier1=8 blocks 56 | levels.attributes.weapons.info.7.tier2=12 blocks 57 | levels.attributes.weapons.info.7.tier3=18 blocks 58 | levels.attributes.weapons.info.8.tier1=Item will never degrade or break. 59 | levels.attributes.weapons.info.8.tier2=NOTHING 60 | levels.attributes.weapons.info.8.tier3=NOTHING 61 | levels.attributes.weapons.info.9.tier1=5%% chance 62 | levels.attributes.weapons.info.9.tier2=8%% chance 63 | levels.attributes.weapons.info.9.tier3=10%% chance 64 | 65 | ### 66 | ## ARMOR 67 | ### 68 | 69 | levels.attributes.armors.info.0=Sets enemies on fire for a short time. 70 | levels.attributes.armors.info.1=Stuns enemies for a short time. 71 | levels.attributes.armors.info.2=Poisons enemies for a short time. 72 | levels.attributes.armors.info.3=Your armor becomes slightly more durable than usual. 73 | levels.attributes.armors.info.4=Increases your resistance to magical attacks (potions, etc...). 74 | levels.attributes.armors.info.5=Your armor stays in your inventory on death. 75 | levels.attributes.armors.info.6=Your armor will never break or degrade. 76 | 77 | levels.attributes.armors.info.0.tier1=4 seconds 78 | levels.attributes.armors.info.0.tier2=5 seconds 79 | levels.attributes.armors.info.0.tier3=6 seconds 80 | levels.attributes.armors.info.1.tier1=1 second 81 | levels.attributes.armors.info.1.tier2=1.5 seconds 82 | levels.attributes.armors.info.1.tier3=2 seconds 83 | levels.attributes.armors.info.2.tier1=7 seconds 84 | levels.attributes.armors.info.2.tier2=10.5 seconds 85 | levels.attributes.armors.info.2.tier3=15 seconds 86 | levels.attributes.armors.info.3.tier1=1 point 87 | levels.attributes.armors.info.3.tier2=2 points 88 | levels.attributes.armors.info.3.tier3=4 points 89 | levels.attributes.armors.info.4.tier1=20%% 90 | levels.attributes.armors.info.4.tier2=30%% 91 | levels.attributes.armors.info.4.tier3=45%% 92 | levels.attributes.armors.info.5.tier1=Item remains in inventory on death. 93 | levels.attributes.armors.info.5.tier2=NOTHING 94 | levels.attributes.armors.info.5.tier3=NOTHING 95 | levels.attributes.armors.info.6.tier1=Item will never degrade or break. 96 | levels.attributes.armors.info.6.tier2=NOTHING 97 | levels.attributes.armors.info.6.tier3=NOTHING 98 | 99 | ### 100 | ## BOW 101 | ### 102 | 103 | levels.attributes.bows.info.0=Sets enemies on fire for a short time. 104 | levels.attributes.bows.info.1=Stuns enemies for a short time. 105 | levels.attributes.bows.info.2=Poisons enemies for a short time. 106 | levels.attributes.bows.info.3=Your bow becomes slightly more durable than usual. 107 | levels.attributes.bows.info.4=Absorb a portion of the damage dealt in health. 108 | levels.attributes.bows.info.5=Your bow stays in your inventory on death. 109 | levels.attributes.bows.info.6=Percentage chance at performing a critical strike. 110 | levels.attributes.bows.info.7=Percentage chance for enemies to drop arrows. 111 | levels.attributes.bows.info.8=Your bow fires multiple arrows at the enemy. Only consumes one arrow. 112 | levels.attributes.bows.info.9=Your bow will never break or degrade. 113 | levels.attributes.bows.info.10=There is a slight chance at instantly killing the enemy. 114 | 115 | levels.attributes.bows.info.0.tier1=4 seconds 116 | levels.attributes.bows.info.0.tier2=5 seconds 117 | levels.attributes.bows.info.0.tier3=6 seconds 118 | levels.attributes.bows.info.1.tier1=1 seconds 119 | levels.attributes.bows.info.1.tier2=1.5 seconds 120 | levels.attributes.bows.info.1.tier3=2 seconds 121 | levels.attributes.bows.info.2.tier1=7 seconds 122 | levels.attributes.bows.info.2.tier2=10.5 seconds 123 | levels.attributes.bows.info.2.tier3=15 seconds 124 | levels.attributes.bows.info.3.tier1=1 point 125 | levels.attributes.bows.info.3.tier2=2 points 126 | levels.attributes.bows.info.3.tier3=4 points 127 | levels.attributes.bows.info.4.tier1=25%% 128 | levels.attributes.bows.info.4.tier2=37.5%% 129 | levels.attributes.bows.info.4.tier3=56%% 130 | levels.attributes.bows.info.5.tier1=Item remains in inventory on death. 131 | levels.attributes.bows.info.5.tier2=NOTHING 132 | levels.attributes.bows.info.5.tier3=NOTHING 133 | levels.attributes.bows.info.6.tier1=20%% 134 | levels.attributes.bows.info.6.tier2=30%% 135 | levels.attributes.bows.info.6.tier3=45%% 136 | levels.attributes.bows.info.7.tier1=0-2 arrows 137 | levels.attributes.bows.info.7.tier2=0-4 arrows 138 | levels.attributes.bows.info.7.tier3=0-8 arrows 139 | levels.attributes.bows.info.8.tier1=3 arrows 140 | levels.attributes.bows.info.8.tier2=4 arrows 141 | levels.attributes.bows.info.8.tier3=6 arrows 142 | levels.attributes.bows.info.9.tier1=Item will never degrade or break. 143 | levels.attributes.bows.info.9.tier2=NOTHING 144 | levels.attributes.bows.info.9.tier3=NOTHING 145 | levels.attributes.bows.info.10.tier1=5%% chance 146 | levels.attributes.bows.info.10.tier2=8%% chance 147 | levels.attributes.bows.info.10.tier3=10%% chance 148 | 149 | ### 150 | ## SHIELD 151 | ### 152 | 153 | levels.attributes.shields.info.0=Sets enemies on fire for a short time. 154 | levels.attributes.shields.info.1=Stuns enemies for a short time. 155 | levels.attributes.shields.info.2=Poisons enemies for a short time. 156 | levels.attributes.shields.info.3=Your armor becomes slightly more durable than usual. 157 | levels.attributes.shields.info.4=Your armor stays in your inventory on death. 158 | levels.attributes.shields.info.5=Your armor will never break or degrade. 159 | 160 | levels.attributes.shields.info.0.tier1=4 seconds 161 | levels.attributes.shields.info.0.tier2=5 seconds 162 | levels.attributes.shields.info.0.tier3=6 seconds 163 | levels.attributes.shields.info.1.tier1=1 second 164 | levels.attributes.shields.info.1.tier2=1.5 seconds 165 | levels.attributes.shields.info.1.tier3=2 seconds 166 | levels.attributes.shields.info.2.tier1=7 seconds 167 | levels.attributes.shields.info.2.tier2=10.5 seconds 168 | levels.attributes.shields.info.2.tier3=15 seconds 169 | levels.attributes.shields.info.3.tier1=1 point 170 | levels.attributes.shields.info.3.tier2=2 points 171 | levels.attributes.shields.info.3.tier3=4 points 172 | levels.attributes.shields.info.4.tier1=Item remains in inventory on death. 173 | levels.attributes.shields.info.4.tier2=NOTHING 174 | levels.attributes.shields.info.4.tier3=NOTHING 175 | levels.attributes.shields.info.5.tier1=Item will never degrade or break. 176 | levels.attributes.shields.info.5.tier2=NOTHING 177 | levels.attributes.shields.info.5.tier3=NOTHING -------------------------------------------------------------------------------- /src/main/resources/assets/levels/lang/ru_RU.lang: -------------------------------------------------------------------------------- 1 | levels.rarity.0=По умолчанию 2 | levels.rarity.1=Обычный 3 | levels.rarity.2=Необычный 4 | levels.rarity.3=Редкий 5 | levels.rarity.4=Ультра редкий 6 | levels.rarity.5=Легендарный 7 | levels.rarity.6=Архаический 8 | 9 | levels.ability.0=Поджигание 10 | levels.ability.1=Заморозка 11 | levels.ability.2=Отравление 12 | levels.ability.3=Кровожадность 13 | levels.ability.4=Ковка 14 | levels.ability.5=Пустота 15 | levels.ability.6=Ослепление 16 | levels.ability.7=Вампиризм 17 | levels.ability.8=Привязка души 18 | levels.ability.9=Плавитель 19 | levels.ability.10=Заморозка 20 | levels.ability.11=Токсичность 21 | levels.ability.12=Поглощение 22 | levels.ability.13=Пустота 23 | levels.ability.14=Зверскость 24 | levels.ability.15=Просветление 25 | levels.ability.16=Закалка 26 | levels.ability.17=Привязка души 27 | 28 | levels.abilities.info.0=Поджигает врагов на короткое время. 29 | levels.abilities.info.1=Ошеломляет врагов, замораживая их на короткое время. 30 | levels.abilities.info.2=Отравляет врагов на короткое время. 31 | levels.abilities.info.3=Усыпляет врагов. 32 | levels.abilities.info.4=Враги в определенном радиусе загорятся. 33 | levels.abilities.info.5=Небольшой шанс нанести большой урон. 34 | levels.abilities.info.6=Ослабляет и ослепляет врагов. 35 | levels.abilities.info.7=Восстанавливает часть нанесенного урона. 36 | levels.abilities.info.8=Оружие не пропадет после смерти и появится у вас на респауне. 37 | levels.abilities.info.9=Поджигает врагов на короткое время. 38 | levels.abilities.info.10=Ошеломляет врагов, замораживая их на короткое время. 39 | levels.abilities.info.11=Отравляет врагов на короткое время. 40 | levels.abilities.info.12=Быстрое восстановление здоровья в течении короткого времени. 41 | levels.abilities.info.13=Небольшой шанс нанести большой урон. 42 | levels.abilities.info.14=При низком уровне здоровья игрок получает баф на урон. 43 | levels.abilities.info.15=Восстанавливает игроку часть нанесенного урона. 44 | levels.abilities.info.16=Небольшая вероятность парирования всех атак. 45 | levels.abilities.info.17=Оружие не пропадет после смерти и появится у вас на респауне. 46 | 47 | levels.misc.level=Уровень 48 | levels.misc.max=Максимальный 49 | levels.misc.experience=Опыт 50 | levels.misc.durability=Прочность 51 | levels.misc.abilities=Способности 52 | levels.misc.abilities.shift=Способности (Shift) 53 | levels.misc.rarity=Редкость 54 | levels.misc.tier=Уровень 55 | levels.misc.abilities.tokens=Жетоны способностей 56 | levels.misc.abilities.purchased=Приобретенные способности 57 | levels.misc.abilities.active=Активные 58 | levels.misc.abilities.passive=Пассивные 59 | 60 | levels.update=Доступны новые уровни! 61 | levels.login1=Нажмите 'L' с оружием/броней в руках, чтобы начать! 62 | levels.login2=(Вы можете отключить это сообщение в настройках) -------------------------------------------------------------------------------- /src/main/resources/assets/levels/logo/logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TheXFactor117/Levels/b8b43fb558c0dd20f6e738017e15c155438efb44/src/main/resources/assets/levels/logo/logo.png -------------------------------------------------------------------------------- /src/main/resources/mcmod.info: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "modid": "levels", 4 | "name": "Levels 3", 5 | "description": "A simple, unique leveling system.", 6 | "version": "${version}", 7 | "mcversion": "${mcversion}", 8 | "url": "https://github.com/TheXFactor117/Levels", 9 | "updateUrl": "http://minecraft.curseforge.com/projects/levels/files", 10 | "authorList": ["TheXFactor117"], 11 | "credits": "MrIbby and Hlaaftana", 12 | "logoFile": "assets/levels/logo/logo.png", 13 | "screenshots": [], 14 | "dependencies": [] 15 | } 16 | ] 17 | --------------------------------------------------------------------------------