From 98c9718a3d54a74e7700f4015d2624948bd6df0c Mon Sep 17 00:00:00 2001 From: nopothegamer <40329022+nopothegamer@users.noreply.github.com> Date: Tue, 2 Nov 2021 21:22:31 +1100 Subject: Adding skill overlays and hotm stuff in pv + other minor stuff (#15) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * idk where im commiting to * idk where im commiting to * made tita overlay and waypoints work with dwarven overlay off "fixed" divan rarity in neuah made eitherwarp block overlay turn off able * Added change notes * i stopped being pepega and worked out how neu config works * Added mining skill overlay * fixed mining overlay * add option to hide Mining waypoints in Dwarven mines when at location * better check location * Make cata xp in /pv be calculated on how many runs you have * Added master cata xp rates * Make gitignore not show as changed * Added warnings to some things in /neu * maybe fix hiding waypoints * Added a fishing skill overlay its kinda scuffed because of the interp stuff * Hopefully fix Rampart's quarry (for real now) * Moul said i could no one leak in general or smth * Cache itemstacks in miningoverlay and crystalhollows overlay (untested) * Fix preinit crash due to manager not existing yet * Make tab do the same as down button while in tab completion mode * remove debug print * Added pitch to farming overlay * Changed the panoramas back to the old one because ery is scuffed * isnt finished but should work for ery * Made it so if ur mining 60 it just says maxed level instead of b u g * Made skills not show int limit when at max level in skill overlays * wh :omegalul: made neu * sad you cant type that long in search bar * Hello don't mind me just improving your workflow * æ * Oh also this * Added the cata xp scaling(idk if m3 and 4 values are right) * Added Expertise Progress * Fix farming overlay * Added cult/crops to next cult level * Go to the other end of the tab-completion List when hitting the end * remove debug prints * added combat skill overlay and some changes to the others (combat doesnt work rn could someone look into it :prayge:) * Added cooldown to god pot showing in todo overlay * comment * Added option to remove enchant glint in storage gui * Added option to remove enchant glint in storage gui * please fix * please fix * Fixed the placement of help.png * Added fairy soul waypoints to misc * unclear not clear * Added dg partner cape * fix space cape * Fix space cape * Make it so you can hold down keys in sign GUIs * Added a button in storage menu to open the settings Added an option to change the click names for /pv to /ah * Made it so ur config doesnt reset * Added bhop (shhh dont tell anyone) * Added a help menu to /neuec * changed fisgifis overlay button no work * make working fishing tiemr * jani can you test this out for us * Added a gui locations tab * very important feature * Fixed wart hoe overlay if not alch 50 * Make it so the ding time is customizable * Added coins/m to farming overlay * Basic mining tab in pv * Just for jani * Just for jani v2 * works ig * my balls * hotm pv is mostly done missing some perks * hotm pv done * message goes here * push so i can pr jani * Final hotm pv texture + fix m3 and m4 cata xp * edit: didnt work * fixed up stuff dokm said * added image for hotm pv * Fixed previews for furf and dg capes * removed combat overlay from location gui menu in /neu * Start of a custom pv page * Removed custom pv because -2 people would use it Removed neubhop (found out bhop is bannable) * update build gradle Co-authored-by: Lulonaut Co-authored-by: Lulonaut <67191924+Lulonaut@users.noreply.github.com> Co-authored-by: DoKM Co-authored-by: TymanWasTaken Co-authored-by: MicrocontrollersDev Co-authored-by: jani270 --- .../FSR_do_not_texture_this_please.png | Bin 0 -> 142 bytes .../resources/assets/notenoughupdates/capes/dg.png | Bin 0 -> 81534 bytes .../assets/notenoughupdates/capes/dg_preview.png | Bin 0 -> 42377 bytes .../assets/notenoughupdates/capes/furf_preview.png | Bin 2089 -> 3506 bytes .../assets/notenoughupdates/capes/space.png | Bin 866931 -> 922429 bytes .../assets/notenoughupdates/pv_mining.png | Bin 0 -> 4550 bytes .../notenoughupdates/storage_gui/storage_icons.png | Bin 11843 -> 5046 bytes 7 files changed, 0 insertions(+), 0 deletions(-) create mode 100644 src/main/resources/assets/notenoughupdates/FSR_do_not_texture_this_please.png create mode 100644 src/main/resources/assets/notenoughupdates/capes/dg.png create mode 100644 src/main/resources/assets/notenoughupdates/capes/dg_preview.png create mode 100644 src/main/resources/assets/notenoughupdates/pv_mining.png (limited to 'src/main/resources/assets') diff --git a/src/main/resources/assets/notenoughupdates/FSR_do_not_texture_this_please.png b/src/main/resources/assets/notenoughupdates/FSR_do_not_texture_this_please.png new file mode 100644 index 00000000..6c001940 Binary files /dev/null and b/src/main/resources/assets/notenoughupdates/FSR_do_not_texture_this_please.png differ diff --git a/src/main/resources/assets/notenoughupdates/capes/dg.png b/src/main/resources/assets/notenoughupdates/capes/dg.png new file mode 100644 index 00000000..8625fbfc Binary files /dev/null and b/src/main/resources/assets/notenoughupdates/capes/dg.png differ diff --git a/src/main/resources/assets/notenoughupdates/capes/dg_preview.png b/src/main/resources/assets/notenoughupdates/capes/dg_preview.png new file mode 100644 index 00000000..0ef73797 Binary files /dev/null and b/src/main/resources/assets/notenoughupdates/capes/dg_preview.png differ diff --git a/src/main/resources/assets/notenoughupdates/capes/furf_preview.png b/src/main/resources/assets/notenoughupdates/capes/furf_preview.png index 2b152b15..d65f8fbe 100644 Binary files a/src/main/resources/assets/notenoughupdates/capes/furf_preview.png and b/src/main/resources/assets/notenoughupdates/capes/furf_preview.png differ diff --git a/src/main/resources/assets/notenoughupdates/capes/space.png b/src/main/resources/assets/notenoughupdates/capes/space.png index ba239e22..76d4a42c 100644 Binary files a/src/main/resources/assets/notenoughupdates/capes/space.png and b/src/main/resources/assets/notenoughupdates/capes/space.png differ diff --git a/src/main/resources/assets/notenoughupdates/pv_mining.png b/src/main/resources/assets/notenoughupdates/pv_mining.png new file mode 100644 index 00000000..a0f99931 Binary files /dev/null and b/src/main/resources/assets/notenoughupdates/pv_mining.png differ diff --git a/src/main/resources/assets/notenoughupdates/storage_gui/storage_icons.png b/src/main/resources/assets/notenoughupdates/storage_gui/storage_icons.png index 8e435046..be569369 100644 Binary files a/src/main/resources/assets/notenoughupdates/storage_gui/storage_icons.png and b/src/main/resources/assets/notenoughupdates/storage_gui/storage_icons.png differ -- cgit From eaaa44eaac80eb7a3d2d0b1ea390700093fcfed2 Mon Sep 17 00:00:00 2001 From: jani270 <69345714+jani270@users.noreply.github.com> Date: Sat, 6 Nov 2021 14:28:22 +0100 Subject: Fixed HOTM Texture (#17) --- .../resources/assets/notenoughupdates/pv_mining.png | Bin 4550 -> 4543 bytes 1 file changed, 0 insertions(+), 0 deletions(-) (limited to 'src/main/resources/assets') diff --git a/src/main/resources/assets/notenoughupdates/pv_mining.png b/src/main/resources/assets/notenoughupdates/pv_mining.png index a0f99931..3c0066e8 100644 Binary files a/src/main/resources/assets/notenoughupdates/pv_mining.png and b/src/main/resources/assets/notenoughupdates/pv_mining.png differ -- cgit From 7a086d1d341f6c51a9857af439c3be9221b10fec Mon Sep 17 00:00:00 2001 From: jani270 <69345714+jani270@users.noreply.github.com> Date: Wed, 10 Nov 2021 21:01:24 +0100 Subject: Updated PV Hotm Texture and made itemlist tools category work with drills and gauntlet (#20) * Update pv_mining.png * Itemlist drills and gauntlet * My name --- Update Notes/2.1.md | 1 + .../github/moulberry/notenoughupdates/NEUOverlay.java | 2 +- .../resources/assets/notenoughupdates/pv_mining.png | Bin 4543 -> 4516 bytes 3 files changed, 2 insertions(+), 1 deletion(-) (limited to 'src/main/resources/assets') diff --git a/Update Notes/2.1.md b/Update Notes/2.1.md index 468fc728..61ae2455 100644 --- a/Update Notes/2.1.md +++ b/Update Notes/2.1.md @@ -19,6 +19,7 @@ - Added a help menu to /neuec - Made it so treecap shows foraging xp instead of farming xp on the farming overlay - Made it so a jungle axe with cult will show the "farming" overlay +- Added Drills and Gauntlet to the itemlist tools category - jani ### **Bug Fixes** - Made titanium overlay and waypoints work with dwarven overlay off - "fixed" divan rarity in NEUAH (scuffed) diff --git a/src/main/java/io/github/moulberry/notenoughupdates/NEUOverlay.java b/src/main/java/io/github/moulberry/notenoughupdates/NEUOverlay.java index adf0df8b..ef2c14b9 100644 --- a/src/main/java/io/github/moulberry/notenoughupdates/NEUOverlay.java +++ b/src/main/java/io/github/moulberry/notenoughupdates/NEUOverlay.java @@ -1215,7 +1215,7 @@ public class NEUOverlay extends Gui { return internalname.matches(petRegex) && item.get("displayname").getAsString().contains("["); } else if (getSortMode() == SORT_MODE_TOOL) { return checkItemType(item.get("lore").getAsJsonArray(), - "SWORD", "BOW", "AXE", "PICKAXE", "FISHING ROD", "WAND", "SHOVEL", "HOE", "DUNGEON SWORD", "DUNGEON BOW") >= 0; + "SWORD", "BOW", "AXE", "PICKAXE", "FISHING ROD", "WAND", "SHOVEL", "HOE", "DUNGEON SWORD", "DUNGEON BOW", "DRILL", "GAUNTLET") >= 0; } else if (getSortMode() == SORT_MODE_ARMOR) { return checkItemType(item.get("lore").getAsJsonArray(), "HELMET", "CHESTPLATE", "LEGGINGS", "BOOTS", "DUNGEON HELMET", "DUNGEON CHESTPLATE", "DUNGEON LEGGINGS", "DUNGEON BOOTS") >= 0; } else if (getSortMode() == SORT_MODE_ACCESSORY) { diff --git a/src/main/resources/assets/notenoughupdates/pv_mining.png b/src/main/resources/assets/notenoughupdates/pv_mining.png index 3c0066e8..a183fe88 100644 Binary files a/src/main/resources/assets/notenoughupdates/pv_mining.png and b/src/main/resources/assets/notenoughupdates/pv_mining.png differ -- cgit From c37dab7e54654c033bfff63461490bac6c86f6c7 Mon Sep 17 00:00:00 2001 From: jani270 <69345714+jani270@users.noreply.github.com> Date: Sat, 13 Nov 2021 11:50:32 +0100 Subject: Changing Patreon to Twitch - bcs moul bad (#24) * Changing Patreon to Twitch * Change Icon again --- .../notenoughupdates/options/NEUConfigEditor.java | 4 ++-- .../moulberry/notenoughupdates/util/GuiTextures.java | 2 +- .../resources/assets/notenoughupdates/social/patreon.png | Bin 3696 -> 0 bytes .../resources/assets/notenoughupdates/social/twitch.png | Bin 0 -> 828 bytes 4 files changed, 3 insertions(+), 3 deletions(-) delete mode 100644 src/main/resources/assets/notenoughupdates/social/patreon.png create mode 100644 src/main/resources/assets/notenoughupdates/social/twitch.png (limited to 'src/main/resources/assets') diff --git a/src/main/java/io/github/moulberry/notenoughupdates/options/NEUConfigEditor.java b/src/main/java/io/github/moulberry/notenoughupdates/options/NEUConfigEditor.java index f4702761..67e61114 100644 --- a/src/main/java/io/github/moulberry/notenoughupdates/options/NEUConfigEditor.java +++ b/src/main/java/io/github/moulberry/notenoughupdates/options/NEUConfigEditor.java @@ -41,14 +41,14 @@ public class NEUConfigEditor extends GuiElement { GITHUB, TWITTER, YOUTUBE, - PATREON + TWITCH }; private static final String[] socialsLink = new String[]{ "https://discord.gg/moulberry", "https://github.com/Moulberry/NotEnoughUpdates", "https://twitter.com/moulberry/", "https://www.youtube.com/channel/UCPh-OKmRSS3IQi9p6YppLcw", - "https://patreon.com/moulberry" + "https://www.twitch.tv/moulberry2" }; private static final ResourceLocation SEARCH_ICON = new ResourceLocation("notenoughupdates:core/search.png"); diff --git a/src/main/java/io/github/moulberry/notenoughupdates/util/GuiTextures.java b/src/main/java/io/github/moulberry/notenoughupdates/util/GuiTextures.java index 8b9376f4..327637b8 100644 --- a/src/main/java/io/github/moulberry/notenoughupdates/util/GuiTextures.java +++ b/src/main/java/io/github/moulberry/notenoughupdates/util/GuiTextures.java @@ -25,7 +25,7 @@ public class GuiTextures { public static final ResourceLocation DISCORD = new ResourceLocation("notenoughupdates:social/discord.png"); public static final ResourceLocation GITHUB = new ResourceLocation("notenoughupdates:social/github.png"); - public static final ResourceLocation PATREON = new ResourceLocation("notenoughupdates:social/patreon.png"); + public static final ResourceLocation TWITCH = new ResourceLocation("notenoughupdates:social/twitch.png"); public static final ResourceLocation TWITTER = new ResourceLocation("notenoughupdates:social/twitter.png"); public static final ResourceLocation YOUTUBE = new ResourceLocation("notenoughupdates:social/youtube.png"); diff --git a/src/main/resources/assets/notenoughupdates/social/patreon.png b/src/main/resources/assets/notenoughupdates/social/patreon.png deleted file mode 100644 index 00a169de..00000000 Binary files a/src/main/resources/assets/notenoughupdates/social/patreon.png and /dev/null differ diff --git a/src/main/resources/assets/notenoughupdates/social/twitch.png b/src/main/resources/assets/notenoughupdates/social/twitch.png new file mode 100644 index 00000000..77a775d2 Binary files /dev/null and b/src/main/resources/assets/notenoughupdates/social/twitch.png differ -- cgit From 9475677afdb86078f3c014b52ef1b0a414f3c5e5 Mon Sep 17 00:00:00 2001 From: nopothegamer <40329022+nopothegamer@users.noreply.github.com> Date: Fri, 10 Dec 2021 22:54:22 +1100 Subject: Slayer overlay (#28) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * idk where im commiting to * idk where im commiting to * made tita overlay and waypoints work with dwarven overlay off "fixed" divan rarity in neuah made eitherwarp block overlay turn off able * Added change notes * i stopped being pepega and worked out how neu config works * Added mining skill overlay * fixed mining overlay * add option to hide Mining waypoints in Dwarven mines when at location * better check location * Make cata xp in /pv be calculated on how many runs you have * Added master cata xp rates * Make gitignore not show as changed * Added warnings to some things in /neu * maybe fix hiding waypoints * Added a fishing skill overlay its kinda scuffed because of the interp stuff * Hopefully fix Rampart's quarry (for real now) * Moul said i could no one leak in general or smth * Cache itemstacks in miningoverlay and crystalhollows overlay (untested) * Fix preinit crash due to manager not existing yet * Make tab do the same as down button while in tab completion mode * remove debug print * Added pitch to farming overlay * Changed the panoramas back to the old one because ery is scuffed * isnt finished but should work for ery * Made it so if ur mining 60 it just says maxed level instead of b u g * Made skills not show int limit when at max level in skill overlays * wh :omegalul: made neu * sad you cant type that long in search bar * Hello don't mind me just improving your workflow * æ * Oh also this * Added the cata xp scaling(idk if m3 and 4 values are right) * Added Expertise Progress * Fix farming overlay * Added cult/crops to next cult level * Go to the other end of the tab-completion List when hitting the end * remove debug prints * added combat skill overlay and some changes to the others (combat doesnt work rn could someone look into it :prayge:) * Added cooldown to god pot showing in todo overlay * comment * Added option to remove enchant glint in storage gui * Added option to remove enchant glint in storage gui * please fix * please fix * Fixed the placement of help.png * Added fairy soul waypoints to misc * unclear not clear * Added dg partner cape * fix space cape * Fix space cape * Make it so you can hold down keys in sign GUIs * Added a button in storage menu to open the settings Added an option to change the click names for /pv to /ah * Made it so ur config doesnt reset * Added bhop (shhh dont tell anyone) * Added a help menu to /neuec * changed fisgifis overlay button no work * make working fishing tiemr * jani can you test this out for us * Added a gui locations tab * very important feature * Fixed wart hoe overlay if not alch 50 * Make it so the ding time is customizable * Added coins/m to farming overlay * Basic mining tab in pv * Just for jani * Just for jani v2 * works ig * my balls * hotm pv is mostly done missing some perks * hotm pv done * message goes here * push so i can pr jani * Final hotm pv texture + fix m3 and m4 cata xp * edit: didnt work * fixed up stuff dokm said * added image for hotm pv * Fixed previews for furf and dg capes * removed combat overlay from location gui menu in /neu * Start of a custom pv page * Removed custom pv because -2 people would use it Removed neubhop (found out bhop is bannable) * update build gradle * - Made it so treecap shows foraging xp instead of farming xp on the farming overlay - Made it so a jungle axe with cult will show the "farming" overlay * Added entrance + made blur limit at 100 * Added blocking clicks back to the enchanting minigames * update patch notes * Fixed rounding issue * let you use screenshot in et overlay * Added /neurepomode to toggle item editing and dev mode * Changed "NEUAH is DISABLED! Enable in /neusettings." to /neu * Changed misc overlays tab to todo overlays * Added config option for npc retexture (idk if it works i dont have a pack to test it with) * update patch note * Fixed api key autofill with dg copy chat feature * Fixed api key autofill with dg copy chat feature v2 * Made missing enchants not show on an item if its not missing any enchants * remove todo because pepega * Added a config option for dirt wand overlay Added a config option for hoe of tilling * patch notes * Fix pet getlorereplacements crash (im guessing) (#21) * Added an option to use short numbers (1.5mil) for price tooltips * Added warning to slotlocking + short prices default to off * make it not dungeon map * Fixed pet overlay not updating when going into /pets * Dokm after not making his own patch notes * Fixed capital letter * Refactor miscoverlays to todooverlays * idk man make the short number prices use like 5 less lines * Added an option to show next click in chronomatron * added bz price to farming overlay coins/m (only wart rn) * added bz price to farming overlay coins/m * me when cactus price was divided by 1296 :pepela: * unrefactor todo overlay because it resets the config * Fixed fetchur for the 765754465th time * Fixed time that experiment table resets + Made prevent missclicks off by default * Added slayer overlay * fixed quickforge level 20 because it goes up +0.5% every level... and randomly the last level gives + 10.5% * ery wanted to texture himself so i made a hidden toggle for it * made it so if your modlist is under 15 and you do /neustats modlist it will just show /neustats * Finished slayer overlay * Auto turn off search mode after 2 minutes * i forgor bout patch notes * Added setting jani wanted * removed hide incompatible enchants because no workie * i forgor to make it build :skull: * Added max enchant book to /neuec - Dokm * Fixed the slayer overlay when ping * edit: didnt work * Made a lil error if you have new tab list off * Fixed fishing overlay for lava fishing * Fix spelling + comments * Added bingo profile icon to /pv * comments * istg people are pepega * ery made good texture for pv bingo * making the pr fricked me (please build) * Fixed pet overlay not resetting pet when making new profile * Fixed pet overlay not resetting pet when making new profile * i forgor to add to LocationEdit neu page + last commit was added combat overlay * Fix comments because either me or intellij was on crack * comments stuff * ok de duimon no0b Co-authored-by: Lulonaut Co-authored-by: Lulonaut <67191924+Lulonaut@users.noreply.github.com> Co-authored-by: DoKM Co-authored-by: TymanWasTaken Co-authored-by: MicrocontrollersDev Co-authored-by: jani270 Co-authored-by: DoKM <54663875+DoKM@users.noreply.github.com> Co-authored-by: IRONM00N <64110067+IRONM00N@users.noreply.github.com> --- Update Notes/2.1.md | 13 +- .../notenoughupdates/NEUEventListener.java | 26 +++ .../moulberry/notenoughupdates/NEUOverlay.java | 12 +- .../notenoughupdates/commands/Commands.java | 7 +- .../notenoughupdates/commands/StatsCommand.java | 9 +- .../miscfeatures/FishingHelper.java | 9 +- .../miscfeatures/NPCRetexturing.java | 2 +- .../miscfeatures/PetInfoOverlay.java | 8 +- .../notenoughupdates/miscgui/GuiCustomEnchant.java | 12 +- .../notenoughupdates/miscgui/GuiEnchantColour.java | 26 +++ .../notenoughupdates/options/NEUConfig.java | 18 ++ .../options/seperateSections/Enchanting.java | 7 +- .../options/seperateSections/LocationEdit.java | 22 ++ .../options/seperateSections/SkillOverlays.java | 77 +++++++ .../options/seperateSections/SlayerOverlay.java | 68 ++++++ .../options/seperateSections/Toolbar.java | 9 + .../overlays/CombatSkillOverlay.java | 246 +++++++++++++++++++++ .../notenoughupdates/overlays/MiningOverlay.java | 7 + .../overlays/MiningSkillOverlay.java | 2 +- .../notenoughupdates/overlays/OverlayManager.java | 44 ++++ .../notenoughupdates/overlays/SlayerOverlay.java | 194 ++++++++++++++++ .../notenoughupdates/overlays/TimersOverlay.java | 18 +- .../profileviewer/GuiProfileViewer.java | 15 +- .../moulberry/notenoughupdates/util/SBInfo.java | 32 +++ .../assets/notenoughupdates/custom_enchant_gui.png | Bin 5501 -> 4982 bytes .../resources/assets/notenoughupdates/pv_bingo.png | Bin 0 -> 250 bytes 26 files changed, 850 insertions(+), 33 deletions(-) create mode 100644 src/main/java/io/github/moulberry/notenoughupdates/options/seperateSections/SlayerOverlay.java create mode 100644 src/main/java/io/github/moulberry/notenoughupdates/overlays/CombatSkillOverlay.java create mode 100644 src/main/java/io/github/moulberry/notenoughupdates/overlays/SlayerOverlay.java create mode 100644 src/main/resources/assets/notenoughupdates/pv_bingo.png (limited to 'src/main/resources/assets') diff --git a/Update Notes/2.1.md b/Update Notes/2.1.md index 1b623418..11b57447 100644 --- a/Update Notes/2.1.md +++ b/Update Notes/2.1.md @@ -3,6 +3,8 @@ ### **Major Changes** - Added mining skill overlay - Added fishing skill overlay +- Added combat skill overlay +- Added slayer overlay - [Added mining tab in /pv](https://cdn.discordapp.com/attachments/832652653292027904/903619242384056370/unknown.png) - Big thanks to kwev1n for some math and jani for the texture - Added blocking clicks back to the enchanting minigames (because apparently its not bannable?) @@ -31,7 +33,12 @@ - Added a config option for hoe of tilling - Added an option to use short numbers (1.5mil) for price tooltips - Added Drills and Gauntlet to the itemlist tools category - jani -- Added an option to show next click in chronomatron +- Added an option to turn off showing next click in chronomatron +- Turns off inv search mode after 2 minutes +- Made /neustats modlist show normal /neustats if under 15 mods +- Added max enchant book to /neuec - Dokm +- [Added bingo profile icon to /pv](https://cdn.discordapp.com/attachments/832652653292027904/915844465372065842/unknown.png) +- Fixed pet overlay not resetting pet when making new profile - Added a warning in the tooltip when price info couldn't be found/is outdated - Lulonaut ### **Bug Fixes** - Made titanium overlay and waypoints work with dwarven overlay off @@ -48,10 +55,12 @@ - Fixed Mining overlay crash - Dokm - Fixed pet crash - Dokm - Fixed fetchur for the 75th time -- Fixed time that experiment table resets +- [Made a lil error if you have new tab list off](https://cdn.discordapp.com/attachments/896407218151366687/913681097605398528/unknown.png) +- Fixed lava fishing with the fishing alert ### **Other** - New icons was added in storage_icons.png - Moved the help icon in /neucustomize over a lil - Added dg partner cape +- Changed custom_enchant_gui.png to remove top right button ### **Previous change log** https://github.com/NotEnoughUpdates/NotEnoughUpdates/blob/master/Update%20Notes/2.0-Pre31-Release.md diff --git a/src/main/java/io/github/moulberry/notenoughupdates/NEUEventListener.java b/src/main/java/io/github/moulberry/notenoughupdates/NEUEventListener.java index 6ba3c244..09505c52 100644 --- a/src/main/java/io/github/moulberry/notenoughupdates/NEUEventListener.java +++ b/src/main/java/io/github/moulberry/notenoughupdates/NEUEventListener.java @@ -68,6 +68,7 @@ import java.util.concurrent.atomic.AtomicBoolean; import java.util.regex.Matcher; import java.util.regex.Pattern; +import static io.github.moulberry.notenoughupdates.overlays.SlayerOverlay.*; import static io.github.moulberry.notenoughupdates.util.GuiTextures.dungeon_chest_worth; public class NEUEventListener { @@ -171,6 +172,7 @@ public class NEUEventListener { private static boolean showNotificationOverInv = false; private static final Pattern BAD_ITEM_REGEX = Pattern.compile("x[0-9]{1,2}$"); + private static final Pattern SLAYER_XP = Pattern.compile(" (Spider|Zombie|Wolf|Enderman) Slayer LVL (\\d) - (?:Next LVL in ([\\d,]+) XP!|LVL MAXED OUT!)"); /** * 1)Will send the cached message from #sendChatMessage when at least 200ms has passed since the last message. @@ -830,6 +832,7 @@ public class NEUEventListener { String r = null; String unformatted = Utils.cleanColour(e.message.getUnformattedText()); + Matcher matcher = SLAYER_XP.matcher(unformatted); if (unformatted.startsWith("You are playing on profile: ")) { neu.manager.setCurrentProfile(unformatted.substring("You are playing on profile: ".length()).split(" ")[0].trim()); } else if (unformatted.startsWith("Your profile was changed to: ")) {//Your profile was changed to: @@ -846,6 +849,29 @@ public class NEUEventListener { } else if (e.message.getFormattedText().startsWith(EnumChatFormatting.RESET.toString() + EnumChatFormatting.RED + "Invalid recipe ")) { r = ""; + } else if (unformatted.equals(" NICE! SLAYER BOSS SLAIN!")) { + SlayerOverlay.isSlain = true; + } else if (unformatted.equals(" SLAYER QUEST STARTED!")) { + SlayerOverlay.isSlain = false; + if (timeSinceLastBoss == 0) { + SlayerOverlay.timeSinceLastBoss = System.currentTimeMillis(); + } else { + timeSinceLastBoss2 = timeSinceLastBoss; + timeSinceLastBoss = System.currentTimeMillis(); + } + } else if (unformatted.startsWith(" RNGesus Meter:")) { + RNGMeter = unformatted.substring(" RNGesus Meter: -------------------- ".length()); + } else if (matcher.matches()) { + //matcher.group(1); + SlayerOverlay.slayerLVL = matcher.group(2); + if (!SlayerOverlay.slayerLVL.equals("9")) { + SlayerOverlay.slayerXp = matcher.group(3); + } else { + slayerXp = "maxed"; + } + } else if (unformatted.startsWith("Sending to server") || (unformatted.startsWith("Your Slayer Quest has been cancelled!"))) { + SlayerOverlay.slayerQuest = false; + SlayerOverlay.unloadOverlayTimer = System.currentTimeMillis(); } if (e.message.getFormattedText().contains(EnumChatFormatting.YELLOW + "Visit the Auction House to collect your item!")) { if (NotEnoughUpdates.INSTANCE.manager.auctionManager.customAH.latestBid != null && diff --git a/src/main/java/io/github/moulberry/notenoughupdates/NEUOverlay.java b/src/main/java/io/github/moulberry/notenoughupdates/NEUOverlay.java index ef2c14b9..d943d135 100644 --- a/src/main/java/io/github/moulberry/notenoughupdates/NEUOverlay.java +++ b/src/main/java/io/github/moulberry/notenoughupdates/NEUOverlay.java @@ -96,6 +96,7 @@ public class NEUOverlay extends Gui { //Various constants used for GUI structure private final int searchBarYOffset = 10; private final int searchBarPadding = 2; + private long lastSearchMode = 0; private float oldWidthMult = 0; @@ -197,6 +198,7 @@ public class NEUOverlay extends Gui { } else { if (System.currentTimeMillis() - millisLastLeftClick < 300) { searchMode = !searchMode; + lastSearchMode = System.currentTimeMillis(); if (searchMode && NotEnoughUpdates.INSTANCE.config.hidden.firstTimeSearchFocus) { NEUEventListener.displayNotification(Lists.newArrayList( "\u00a7eSearch Highlight", @@ -205,13 +207,16 @@ public class NEUOverlay extends Gui { "\u00a77This allows you easily find items as the item will stand out.", "\u00a77To toggle this please double click on the search bar in your inventory.", "\u00a77", - "\u00a77Press X on your keyboard to close this notifcation"), true, true); + "\u00a77Press X on your keyboard to close this notification"), true, true); NotEnoughUpdates.INSTANCE.config.hidden.firstTimeSearchFocus = false; } } textField.setCursorPosition(getClickedIndex(mouseX, mouseY)); millisLastLeftClick = System.currentTimeMillis(); + if (searchMode) { + lastSearchMode = System.currentTimeMillis(); + } } } } @@ -2041,6 +2046,11 @@ public class NEUOverlay extends Gui { GlStateManager.disableLighting(); Utils.pushGuiScale(-1); + + if (System.currentTimeMillis() - lastSearchMode > 120000 && NotEnoughUpdates.INSTANCE.config.toolbar.autoTurnOffSearchMode + || !NotEnoughUpdates.INSTANCE.config.toolbar.searchBar) { + searchMode = false; + } } /** diff --git a/src/main/java/io/github/moulberry/notenoughupdates/commands/Commands.java b/src/main/java/io/github/moulberry/notenoughupdates/commands/Commands.java index 7d1ef905..3be881ac 100644 --- a/src/main/java/io/github/moulberry/notenoughupdates/commands/Commands.java +++ b/src/main/java/io/github/moulberry/notenoughupdates/commands/Commands.java @@ -716,7 +716,7 @@ public class Commands { "Ok, this is actually the last message, use the command again and you'll crash I promise"}; private int devFailIndex = 0; - private static final List devTestUsers = new ArrayList<>(Arrays.asList("moulberry", "lucycoconut", "ironm00n", "ariyio")); + private static final List devTestUsers = new ArrayList<>(Arrays.asList("moulberry", "lucycoconut", "ironm00n", "ariyio", "throwpo")); SimpleCommand devTestCommand = new SimpleCommand("neudevtest", new SimpleCommand.ProcessCommandRunnable() { @Override public void processCommand(ICommandSender sender, String[] args) { @@ -767,6 +767,11 @@ public class Commands { NotEnoughUpdates.INSTANCE.saveConfig(); return; } + if (args.length == 1 && args[0].equalsIgnoreCase("searchmode")) { + NotEnoughUpdates.INSTANCE.config.hidden.firstTimeSearchFocus = true; + Minecraft.getMinecraft().thePlayer.addChatMessage(new ChatComponentText(EnumChatFormatting.AQUA + "I would never search")); + return; + } if (args.length == 1 && args[0].equalsIgnoreCase("center")) { double x = Math.floor(Minecraft.getMinecraft().thePlayer.posX) + 0.5f; double z = Math.floor(Minecraft.getMinecraft().thePlayer.posZ) + 0.5f; diff --git a/src/main/java/io/github/moulberry/notenoughupdates/commands/StatsCommand.java b/src/main/java/io/github/moulberry/notenoughupdates/commands/StatsCommand.java index e0743162..3888e3ea 100644 --- a/src/main/java/io/github/moulberry/notenoughupdates/commands/StatsCommand.java +++ b/src/main/java/io/github/moulberry/notenoughupdates/commands/StatsCommand.java @@ -34,12 +34,18 @@ public class StatsCommand extends ClientCommandBase { super("neustats"); } + private static int activeModCount = Loader.instance().getActiveModList().size(); + @Override public void processCommand(ICommandSender sender, String[] args) { if (args.length > 0) { switch (args[0].toLowerCase(Locale.ROOT)) { case "modlist": - clipboardAndSendMessage(createModList(new DiscordMarkdownBuilder()).toString()); + if (activeModCount > 15) { + clipboardAndSendMessage(createModList(new DiscordMarkdownBuilder()).toString()); + } else { + clipboardAndSendMessage(createStats()); + } break; case "dump": modPrefixedMessage(EnumChatFormatting.GREEN + "This will upload a dump of the java classes your game has loaded how big they are and how many there are. This can take a few seconds as it is uploading to HasteBin."); @@ -95,7 +101,6 @@ public class StatsCommand extends ClientCommandBase { long totalMemory = Runtime.getRuntime().totalMemory(); long freeMemory = Runtime.getRuntime().freeMemory(); long currentMemory = totalMemory - freeMemory; - int activeModCount = Loader.instance().getActiveModList().size(); builder.category("System Stats"); builder.append("OS", System.getProperty("os.name")); diff --git a/src/main/java/io/github/moulberry/notenoughupdates/miscfeatures/FishingHelper.java b/src/main/java/io/github/moulberry/notenoughupdates/miscfeatures/FishingHelper.java index 8e712012..94e308a1 100644 --- a/src/main/java/io/github/moulberry/notenoughupdates/miscfeatures/FishingHelper.java +++ b/src/main/java/io/github/moulberry/notenoughupdates/miscfeatures/FishingHelper.java @@ -355,8 +355,13 @@ public class FishingHelper { Minecraft.getMinecraft().thePlayer.fishEntity != null && Minecraft.getMinecraft().thePlayer.fishEntity.getEntityId() == hookEntityId && chain.particleNum > 3) { - - if (newDistance <= 0.2f + 0.1f * pingDelayTicks && NotEnoughUpdates.INSTANCE.config.fishing.incomingFishWarningR) { + float lavaOffset = 0.1f; + if (particleType == EnumParticleTypes.SMOKE_NORMAL) { + lavaOffset = 0.03f; + } else if (particleType == EnumParticleTypes.WATER_WAKE) { + lavaOffset = 0.1f; + } + if (newDistance <= 0.2f + lavaOffset * pingDelayTicks && NotEnoughUpdates.INSTANCE.config.fishing.incomingFishWarningR) { if (NotEnoughUpdates.INSTANCE.config.fishing.incomingFishHookedSounds && hookedWarningStateTicks <= 0) { float vol = NotEnoughUpdates.INSTANCE.config.fishing.incomingFishHookedSoundsVol / 100f; diff --git a/src/main/java/io/github/moulberry/notenoughupdates/miscfeatures/NPCRetexturing.java b/src/main/java/io/github/moulberry/notenoughupdates/miscfeatures/NPCRetexturing.java index 9180cca6..19dca439 100644 --- a/src/main/java/io/github/moulberry/notenoughupdates/miscfeatures/NPCRetexturing.java +++ b/src/main/java/io/github/moulberry/notenoughupdates/miscfeatures/NPCRetexturing.java @@ -43,7 +43,7 @@ public class NPCRetexturing implements IResourceManagerReloadListener { public Skin getSkin(AbstractClientPlayer player) { if (gettingSkin) return null; - if (player.getUniqueID().version() == 4) return null; + if (player.getUniqueID().version() == 4 && !NotEnoughUpdates.INSTANCE.config.hidden.npcRetextureOnSelf) return null; if (skinOverrideCache.containsKey(player)) { return skinOverrideCache.get(player); diff --git a/src/main/java/io/github/moulberry/notenoughupdates/miscfeatures/PetInfoOverlay.java b/src/main/java/io/github/moulberry/notenoughupdates/miscfeatures/PetInfoOverlay.java index 0415c629..955fbbbd 100644 --- a/src/main/java/io/github/moulberry/notenoughupdates/miscfeatures/PetInfoOverlay.java +++ b/src/main/java/io/github/moulberry/notenoughupdates/miscfeatures/PetInfoOverlay.java @@ -764,6 +764,9 @@ public class PetInfoOverlay extends TextOverlay { foundDespawn = true; break; } + if (line.equals("\u00a77\u00a77Selected pet: \u00a7cNone")){ + clearPet(); + } } if (!foundDespawn && config.selectedPet == petIndex && currentTime - lastPetSelect > 500) { clearPet(); @@ -1140,9 +1143,8 @@ public class PetInfoOverlay extends TextOverlay { Minecraft.getMinecraft().thePlayer.addChatMessage(new ChatComponentText(EnumChatFormatting.RED + "[NEU] Can't find pet \u00a7" + petStringMatch + EnumChatFormatting.RED + " try revisiting all pages of /pets.")); } - } else if (chatMessage.toLowerCase().startsWith("you despawned your")) { - clearPet(); - } else if (chatMessage.toLowerCase().contains("switching to profile")) { + } else if ((chatMessage.toLowerCase().startsWith("you despawned your")) || (chatMessage.toLowerCase().contains("switching to profile")) + || (chatMessage.toLowerCase().contains("transferring you to a new island..."))) { clearPet(); } } diff --git a/src/main/java/io/github/moulberry/notenoughupdates/miscgui/GuiCustomEnchant.java b/src/main/java/io/github/moulberry/notenoughupdates/miscgui/GuiCustomEnchant.java index 218076a5..4510c675 100644 --- a/src/main/java/io/github/moulberry/notenoughupdates/miscgui/GuiCustomEnchant.java +++ b/src/main/java/io/github/moulberry/notenoughupdates/miscgui/GuiCustomEnchant.java @@ -586,9 +586,9 @@ public class GuiCustomEnchant extends Gui { Utils.drawTexturedRect(guiLeft + 295, guiTop + 147, 16, 16, 0, 16 / 512f, 387 / 512f, (387 + 16) / 512f, GL11.GL_NEAREST); //Incompatible Settings Button - float incompatibleMinU = NotEnoughUpdates.INSTANCE.config.enchantingSolvers.incompatibleEnchants * 16 / 512f; + /*float incompatibleMinU = NotEnoughUpdates.INSTANCE.config.enchantingSolvers.incompatibleEnchants * 16 / 512f; Utils.drawTexturedRect(guiLeft + 295 + 18, guiTop + 147, 16, 16, - incompatibleMinU, incompatibleMinU + 16 / 512f, 403 / 512f, (403 + 16) / 512f, GL11.GL_NEAREST); + incompatibleMinU, incompatibleMinU + 16 / 512f, 403 / 512f, (403 + 16) / 512f, GL11.GL_NEAREST);*/ //Sorting Settings Button float sortingMinU = NotEnoughUpdates.INSTANCE.config.enchantingSolvers.enchantSorting * 16 / 512f; Utils.drawTexturedRect(guiLeft + 295, guiTop + 147 + 18, 16, 16, @@ -606,7 +606,7 @@ public class GuiCustomEnchant extends Gui { Gui.drawRect(guiLeft + 295, guiTop + 147, guiLeft + 295 + 16, guiTop + 147 + 16, 0x80ffffff); tooltipToDisplay = createTooltip("Enable GUI", 0, "On", "Off"); break; - case 1: + /*case 1: Gui.drawRect(guiLeft + 295 + 18, guiTop + 147, guiLeft + 295 + 16 + 18, guiTop + 147 + 16, 0x80ffffff); tooltipToDisplay = createTooltip("Incompatible Enchants", NotEnoughUpdates.INSTANCE.config.enchantingSolvers.incompatibleEnchants, @@ -614,7 +614,7 @@ public class GuiCustomEnchant extends Gui { tooltipToDisplay.add(1, EnumChatFormatting.GRAY + "How to display enchants that are"); tooltipToDisplay.add(2, EnumChatFormatting.GRAY + "incompatible with your current item,"); tooltipToDisplay.add(3, EnumChatFormatting.GRAY + "eg. Smite on a sword with Sharpness"); - break; + break;*/ case 2: Gui.drawRect(guiLeft + 295, guiTop + 147 + 18, guiLeft + 295 + 16, guiTop + 147 + 16 + 18, 0x80ffffff); tooltipToDisplay = createTooltip("Sort enchants...", @@ -1435,14 +1435,14 @@ public class GuiCustomEnchant extends Gui { NotEnoughUpdates.INSTANCE.config.enchantingSolvers.enableTableGUI = false; break; } - case 1: { + /*case 1: { int val = NotEnoughUpdates.INSTANCE.config.enchantingSolvers.incompatibleEnchants; val += direction; if (val < 0) val = 1; if (val > 1) val = 0; NotEnoughUpdates.INSTANCE.config.enchantingSolvers.incompatibleEnchants = val; break; - } + }*/ case 2: { int val = NotEnoughUpdates.INSTANCE.config.enchantingSolvers.enchantSorting; val += direction; diff --git a/src/main/java/io/github/moulberry/notenoughupdates/miscgui/GuiEnchantColour.java b/src/main/java/io/github/moulberry/notenoughupdates/miscgui/GuiEnchantColour.java index 87084199..e1280bb9 100644 --- a/src/main/java/io/github/moulberry/notenoughupdates/miscgui/GuiEnchantColour.java +++ b/src/main/java/io/github/moulberry/notenoughupdates/miscgui/GuiEnchantColour.java @@ -14,6 +14,7 @@ import net.minecraft.client.gui.FontRenderer; import net.minecraft.client.gui.Gui; import net.minecraft.client.gui.GuiScreen; import net.minecraft.client.renderer.GlStateManager; +import net.minecraft.item.ItemStack; import net.minecraft.util.EnumChatFormatting; import net.minecraft.util.ResourceLocation; import org.lwjgl.input.Keyboard; @@ -85,6 +86,9 @@ public class GuiEnchantColour extends GuiScreen { return enchantNamesPretty; } + private ItemStack maxedBook; + private int maxedBookFound =0; + private List getEnchantColours() { return NotEnoughUpdates.INSTANCE.config.hidden.enchantColours; } @@ -192,8 +196,30 @@ public class GuiEnchantColour extends GuiScreen { GlStateManager.color(1, 1, 1, 1); Minecraft.getMinecraft().getTextureManager().bindTexture(help); Utils.drawTexturedRect(guiLeft + xSize + 3, guiTopSidebar - 18, 16, 16, GL11.GL_NEAREST); + if(maxedBookFound == 0){ + try { + if (NotEnoughUpdates.INSTANCE.manager.jsonToStack( + NotEnoughUpdates.INSTANCE.manager.getItemInformation().get("MAXED_ENCHANT_BOOK")).hasDisplayName()) { + maxedBook = NotEnoughUpdates.INSTANCE.manager.jsonToStack(NotEnoughUpdates.INSTANCE.manager.getItemInformation().get("MAXED_ENCHANT_BOOK")); + maxedBookFound = 1; + } else { + maxedBookFound = 2; + } + + } catch(Exception ignored){ + maxedBookFound = 2; + } + } + if (maxedBookFound == 1){ + Utils.drawItemStack(maxedBook, guiLeft + xSize +3, guiTopSidebar - 34); + } if (mouseX >= guiLeft + xSize + 3 && mouseX < guiLeft + xSize + 19) { + if(mouseY >= guiTopSidebar - 34 && mouseY <= guiTopSidebar - 18 && maxedBookFound == 1){ + tooltipToDisplay = maxedBook.getTooltip(Minecraft.getMinecraft().thePlayer, false); + Utils.drawHoveringText(tooltipToDisplay, mouseX, mouseY, width, height, -1, fr); + tooltipToDisplay = null; + } if (mouseY >= guiTopSidebar - 18 && mouseY <= guiTopSidebar - 2) { tooltipToDisplay = Lists.newArrayList( EnumChatFormatting.AQUA+"NEUEC Colouring Guide", diff --git a/src/main/java/io/github/moulberry/notenoughupdates/options/NEUConfig.java b/src/main/java/io/github/moulberry/notenoughupdates/options/NEUConfig.java index 7087961c..8dce4cc1 100644 --- a/src/main/java/io/github/moulberry/notenoughupdates/options/NEUConfig.java +++ b/src/main/java/io/github/moulberry/notenoughupdates/options/NEUConfig.java @@ -101,6 +101,13 @@ public class NEUConfig extends Config { return; case 17: ClientCommandHandler.instance.executeCommand(Minecraft.getMinecraft().thePlayer, "/neusouls unclear"); + return; + case 18: + editOverlay(activeConfigCategory, OverlayManager.slayerOverlay, slayerOverlay.slayerPosition); + return; + case 19: + editOverlay(activeConfigCategory, OverlayManager.combatSkillOverlay, skillOverlays.combatPosition); + } } @@ -181,6 +188,13 @@ public class NEUConfig extends Config { ) public MiscOverlays miscOverlays = new MiscOverlays(); + @Expose + @Category( + name = "Slayer Overlay", + desc = "Slayer Overlay" + ) + public SlayerOverlay slayerOverlay = new SlayerOverlay(); + @Expose @Category( name = "Storage GUI", @@ -331,6 +345,10 @@ public class NEUConfig extends Config { @Expose public boolean disableBrokenCapes = false; + //Ery wanted to texture himself because its ery + @Expose + public boolean npcRetextureOnSelf = false; + } public static ArrayList createDefaultEnchantColours() { diff --git a/src/main/java/io/github/moulberry/notenoughupdates/options/seperateSections/Enchanting.java b/src/main/java/io/github/moulberry/notenoughupdates/options/seperateSections/Enchanting.java index 6666302e..16288f21 100644 --- a/src/main/java/io/github/moulberry/notenoughupdates/options/seperateSections/Enchanting.java +++ b/src/main/java/io/github/moulberry/notenoughupdates/options/seperateSections/Enchanting.java @@ -20,7 +20,7 @@ public class Enchanting { @ConfigAccordionId(id = 1) public boolean enableTableGUI = true; - @Expose + /*@Expose @ConfigOption( name = "Incompatible Enchants", desc = "How to display enchants that are incompatible with your current item, eg. Smite on a sword with Sharpness" @@ -29,7 +29,7 @@ public class Enchanting { values = {"Highlight", "Hide"} ) @ConfigAccordionId(id = 1) - public int incompatibleEnchants = 0; + public int incompatibleEnchants = 0;*/ @Expose @ConfigOption( @@ -68,7 +68,8 @@ public class Enchanting { @ConfigEditorBoolean @ConfigAccordionId(id = 0) public boolean enableEnchantingSolvers = true; - + //In an email from Donpireso (admin) he says not sending a packet at all isn't bannable + //https://cdn.discordapp.com/attachments/823769568933576764/906101631861526559/unknown.png @Expose @ConfigOption( name = "Prevent Misclicks", diff --git a/src/main/java/io/github/moulberry/notenoughupdates/options/seperateSections/LocationEdit.java b/src/main/java/io/github/moulberry/notenoughupdates/options/seperateSections/LocationEdit.java index edd0ad46..1fe90985 100644 --- a/src/main/java/io/github/moulberry/notenoughupdates/options/seperateSections/LocationEdit.java +++ b/src/main/java/io/github/moulberry/notenoughupdates/options/seperateSections/LocationEdit.java @@ -135,4 +135,26 @@ public class LocationEdit { ) public Position fishingPosition = new Position(10, 200); + @Expose + @ConfigOption( + name = "Slayer Position", + desc = "Change the position of the Slayer overlay" + ) + @ConfigEditorButton( + runnableId = 18, + buttonText = "Edit" + ) + public Position slayerPosition = new Position(10, 200); + + @Expose + @ConfigOption( + name = "Combat Position", + desc = "Change the position of the Combat overlay" + ) + @ConfigEditorButton( + runnableId = 19, + buttonText = "Edit" + ) + public Position combatPosition = new Position(10, 200); + } diff --git a/src/main/java/io/github/moulberry/notenoughupdates/options/seperateSections/SkillOverlays.java b/src/main/java/io/github/moulberry/notenoughupdates/options/seperateSections/SkillOverlays.java index d9278280..cc419380 100644 --- a/src/main/java/io/github/moulberry/notenoughupdates/options/seperateSections/SkillOverlays.java +++ b/src/main/java/io/github/moulberry/notenoughupdates/options/seperateSections/SkillOverlays.java @@ -236,4 +236,81 @@ public class SkillOverlays { ) @ConfigAccordionId(id = 3) public int customFishTimer = 300; + + @ConfigOption( + name = "Combat", + desc = "" + ) + @ConfigEditorAccordion(id = 4) + public boolean combatAccordion = false; + + @Expose + @ConfigOption( + name = "\u00A7cWarning", + desc = "The combat display will only show if you have a Book of Stats on the item you are using" + ) + @ConfigEditorFSR( + runnableId = 12, + buttonText = "" + ) + @ConfigAccordionId(id = 4) + public boolean combatInfo = false; + + @Expose + @ConfigOption( + name = "Enable Combat Overlay", + desc = "Show an overlay while Combat with useful information" + ) + @ConfigEditorBoolean + @ConfigAccordionId(id = 4) + public boolean combatSkillOverlay = true; + + @Expose + @ConfigOption( + name = "Combat Text", + desc = "\u00a7eDrag text to change the appearance of the overlay\n" + + "\u00a7rHold an item with Book of Stats to show the display" + ) + @ConfigEditorDraggableList( + exampleText = {"\u00a7bKills: \u00a7e547,860", + "\u00a7bCombat: \u00a7e12\u00a77 [\u00a7e|||||||||||||||||\u00a78||||||||\u00a77] \u00a7e67%", + "\u00a7bCurrent XP: \u00a7e6,734", + "\u00a7bRemaining XP: \u00a7e3,265", + "\u00a7bXP/h: \u00a7e238,129", + "\u00a7bETA: \u00a7e13h12m"} + ) + @ConfigAccordionId(id = 4) + public List combatText = new ArrayList<>(Arrays.asList(0, 1, 2, 3, 4, 5)); + + @Expose + @ConfigOption( + name = "Combat Position", + desc = "Change the position of the Combat overlay" + ) + @ConfigEditorButton( + runnableId = 19, + buttonText = "Edit" + ) + @ConfigAccordionId(id = 4) + public Position combatPosition = new Position(10, 200); + + @Expose + @ConfigOption( + name = "Combat Style", + desc = "Change the style of the Combat overlay" + ) + @ConfigEditorDropdown( + values = {"Background", "No Shadow", "Shadow", "Full Shadow"} + ) + @ConfigAccordionId(id = 4) + public int combatStyle = 0; + + @Expose + @ConfigOption( + name = "Always show combat overlay", + desc = "Shows combat overlay even if you dont have Book of Stats" + ) + @ConfigEditorBoolean + @ConfigAccordionId(id = 4) + public boolean alwaysShowCombatOverlay = false; } diff --git a/src/main/java/io/github/moulberry/notenoughupdates/options/seperateSections/SlayerOverlay.java b/src/main/java/io/github/moulberry/notenoughupdates/options/seperateSections/SlayerOverlay.java new file mode 100644 index 00000000..8ea34c52 --- /dev/null +++ b/src/main/java/io/github/moulberry/notenoughupdates/options/seperateSections/SlayerOverlay.java @@ -0,0 +1,68 @@ +package io.github.moulberry.notenoughupdates.options.seperateSections; + +import com.google.gson.annotations.Expose; +import io.github.moulberry.notenoughupdates.core.config.Position; +import io.github.moulberry.notenoughupdates.core.config.annotations.*; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; + +public class SlayerOverlay { + + @Expose + @ConfigOption( + name = "\u00A7cWarning", + desc = "You may have to do 2 bosses before everything shows" + ) + @ConfigEditorFSR( + runnableId = 12 + ) + public boolean slayerWarning = false; + + @Expose + @ConfigOption( + name = "Slayer Overlay", + desc = "Toggles the slayer overlay" + ) + @ConfigEditorBoolean + public boolean slayerOverlay = false; + + @Expose + @ConfigOption( + name = "Slayer Text", + desc = "\u00a7eDrag text to change the appearance of the overlay" + ) + @ConfigEditorDraggableList( + exampleText = {"\u00a7eSlayer: \u00a74Sven", + "\u00a7eRNG Meter: \u00a75100%", + "\u00a7eLvl: \u00a7d7", + "\u00a7eKill time: \u00a7c1:30", + "\u00a7eXP: \u00a7d75,450/100,000", + "\u00a7eBosses till next Lvl: \u00a7d17", + "\u00a7eAverage kill time: \u00a7c3:20" + } + ) + public List slayerText = new ArrayList<>(Arrays.asList(0, 1, 4, 5, 3, 6)); + + @Expose + @ConfigOption( + name = "Slayer Position", + desc = "Change the position of the Slayer overlay" + ) + @ConfigEditorButton( + runnableId = 18, + buttonText = "Edit" + ) + public Position slayerPosition = new Position(10, 200); + + @Expose + @ConfigOption( + name = "Slayer Style", + desc = "Change the style of the Slayer overlay" + ) + @ConfigEditorDropdown( + values = {"Background", "No Shadow", "Shadow", "Full Shadow"} + ) + public int slayerStyle = 0; +} diff --git a/src/main/java/io/github/moulberry/notenoughupdates/options/seperateSections/Toolbar.java b/src/main/java/io/github/moulberry/notenoughupdates/options/seperateSections/Toolbar.java index 6f5865ed..734c517c 100644 --- a/src/main/java/io/github/moulberry/notenoughupdates/options/seperateSections/Toolbar.java +++ b/src/main/java/io/github/moulberry/notenoughupdates/options/seperateSections/Toolbar.java @@ -72,6 +72,15 @@ public class Toolbar { @ConfigAccordionId(id = 0) public int searchBarHeight = 40; + @Expose + @ConfigOption( + name = "Auto turnoff search mode", + desc = "Turns off the inventory search mode after 2 minutes" + ) + @ConfigEditorBoolean + @ConfigAccordionId(id = 0) + public boolean autoTurnOffSearchMode = true; + @Expose @ConfigOption( name = "Show Quick Commands", diff --git a/src/main/java/io/github/moulberry/notenoughupdates/overlays/CombatSkillOverlay.java b/src/main/java/io/github/moulberry/notenoughupdates/overlays/CombatSkillOverlay.java new file mode 100644 index 00000000..36d3e17a --- /dev/null +++ b/src/main/java/io/github/moulberry/notenoughupdates/overlays/CombatSkillOverlay.java @@ -0,0 +1,246 @@ +package io.github.moulberry.notenoughupdates.overlays; + +import io.github.moulberry.notenoughupdates.NotEnoughUpdates; +import io.github.moulberry.notenoughupdates.core.config.Position; +import io.github.moulberry.notenoughupdates.core.util.lerp.LerpUtils; +import io.github.moulberry.notenoughupdates.util.Utils; +import io.github.moulberry.notenoughupdates.util.XPInformation; +import net.minecraft.client.Minecraft; +import net.minecraft.item.ItemStack; +import net.minecraft.nbt.NBTTagCompound; +import net.minecraft.util.EnumChatFormatting; + +import java.text.NumberFormat; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.LinkedList; +import java.util.List; +import java.util.function.Supplier; + +public class CombatSkillOverlay extends TextOverlay { //Im sure there is a much better way to do this besides making another class ¯\_(ツ)_/¯ + + private long lastUpdate = -1; + private int killLast = -1; + private int kill = -1; + private LinkedList killQueue = new LinkedList<>(); + + private XPInformation.SkillInfo skillInfo = null; + private XPInformation.SkillInfo skillInfoLast = null; + + private float lastTotalXp = -1; + private boolean isKilling = false; + private LinkedList xpGainQueue = new LinkedList<>(); + private float xpGainHourLast = -1; + private float xpGainHour = -1; + + private int xpGainTimer = 0; + + private String skillType = "Combat"; + + public CombatSkillOverlay(Position position, Supplier> dummyStrings, Supplier styleSupplier) { + super(position, dummyStrings, styleSupplier); + } + + private float interp(float now, float last) { + float interp = now; + if(last >= 0 && last != now) { + float factor = (System.currentTimeMillis()-lastUpdate)/1000f; + factor = LerpUtils.clampZeroOne(factor); + interp = last + (now - last) * factor; + } + return interp; + } + + @Override + public void update() { + if(!NotEnoughUpdates.INSTANCE.config.skillOverlays.combatSkillOverlay) { + kill = -1; + overlayStrings = null; + return; + } + + lastUpdate = System.currentTimeMillis(); + killLast = kill; + xpGainHourLast = xpGainHour; + kill = -1; + + if(Minecraft.getMinecraft().thePlayer == null) return; + + ItemStack stack = Minecraft.getMinecraft().thePlayer.getHeldItem(); + if(stack != null && stack.hasTagCompound()) { + NBTTagCompound tag = stack.getTagCompound(); + + if(tag.hasKey("ExtraAttributes", 10)) { + NBTTagCompound ea = tag.getCompoundTag("ExtraAttributes"); + + if(ea.hasKey("stats_book", 99)) { + kill = ea.getInteger("stats_book"); + killQueue.add(0, kill); + } + } + } + + String internalname = NotEnoughUpdates.INSTANCE.manager.getInternalNameForItem(stack); + + skillInfoLast = skillInfo; + skillInfo = XPInformation.getInstance().getSkillInfo(skillType); + if(skillInfo != null) { + float totalXp = skillInfo.totalXp; + + if(lastTotalXp > 0) { + float delta = totalXp - lastTotalXp; + + if(delta > 0 && delta < 1000) { + xpGainTimer = 3; + + xpGainQueue.add(0, delta); + while(xpGainQueue.size() > 30) { + xpGainQueue.removeLast(); + } + + float totalGain = 0; + for(float f : xpGainQueue) totalGain += f; + + xpGainHour = totalGain * (60 * 60) / xpGainQueue.size(); + + isKilling = true; + } else if(xpGainTimer > 0) { + xpGainTimer--; + + xpGainQueue.add(0, 0f); + while(xpGainQueue.size() > 30) { + xpGainQueue.removeLast(); + } + + float totalGain = 0; + for(float f : xpGainQueue) totalGain += f; + + xpGainHour = totalGain * (60 * 60) / xpGainQueue.size(); + + isKilling = true; + } else if(delta <= 0) { + isKilling = false; + } + } + + lastTotalXp = totalXp; + } + + while(killQueue.size() >= 4) { + killQueue.removeLast(); + } + + if(kill != -1) { + overlayStrings = new ArrayList<>(); + } else { + overlayStrings = null; + } + + } + + @Override + public void updateFrequent() { + super.updateFrequent(); + + if(kill < 0 && !NotEnoughUpdates.INSTANCE.config.skillOverlays.alwaysShowCombatOverlay) { + overlayStrings = null; + } else { + HashMap lineMap = new HashMap<>(); + + overlayStrings = new ArrayList<>(); + + NumberFormat format = NumberFormat.getIntegerInstance(); + + if (kill >= 0) { + int counterInterp = (int) interp(kill, killLast); + + lineMap.put(0, EnumChatFormatting.AQUA + "Kills: " + EnumChatFormatting.YELLOW + format.format(counterInterp)); + } + + float xpInterp = xpGainHour; + if (xpGainHourLast == xpGainHour && xpGainHour <= 0) { + lineMap.put(4, EnumChatFormatting.AQUA + "XP/h: " + EnumChatFormatting.YELLOW + "N/A"); + } else { + xpInterp = interp(xpGainHour, xpGainHourLast); + + lineMap.put(4, EnumChatFormatting.AQUA + "XP/h: " + EnumChatFormatting.YELLOW + + format.format(xpInterp) + (isKilling ? "" : EnumChatFormatting.RED + " (PAUSED)")); + } + + if (skillInfo != null && skillInfo.level < 60) { + StringBuilder levelStr = new StringBuilder(EnumChatFormatting.AQUA + "Combat" + ": "); + + levelStr.append(EnumChatFormatting.YELLOW) + .append(skillInfo.level) + .append(EnumChatFormatting.GRAY) + .append(" ["); + + float progress = skillInfo.currentXp / skillInfo.currentXpMax; + if (skillInfoLast != null && skillInfo.currentXpMax == skillInfoLast.currentXpMax) { + progress = interp(progress, skillInfoLast.currentXp / skillInfoLast.currentXpMax); + } + + float lines = 25; + for (int i = 0; i < lines; i++) { + if (i / lines < progress) { + levelStr.append(EnumChatFormatting.YELLOW); + } else { + levelStr.append(EnumChatFormatting.DARK_GRAY); + } + levelStr.append('|'); + } + + levelStr.append(EnumChatFormatting.GRAY) + .append("] ") + .append(EnumChatFormatting.YELLOW) + .append((int) (progress * 100)) + .append("%"); + + int current = (int) skillInfo.currentXp; + if (skillInfoLast != null && skillInfo.currentXpMax == skillInfoLast.currentXpMax) { + current = (int) interp(current, skillInfoLast.currentXp); + } + + int remaining = (int) (skillInfo.currentXpMax - skillInfo.currentXp); + if (skillInfoLast != null && skillInfo.currentXpMax == skillInfoLast.currentXpMax) { + remaining = (int) interp(remaining, (int) (skillInfoLast.currentXpMax - skillInfoLast.currentXp)); + } + + lineMap.put(1, levelStr.toString()); + lineMap.put(2, EnumChatFormatting.AQUA + "Current XP: " + EnumChatFormatting.YELLOW + format.format(current)); + if (remaining < 0) { + lineMap.put(3, EnumChatFormatting.AQUA + "Remaining XP: " + EnumChatFormatting.YELLOW + "MAXED!"); + lineMap.put(5, EnumChatFormatting.AQUA + "ETA: " + EnumChatFormatting.YELLOW + "MAXED!"); + } else { + lineMap.put(3, EnumChatFormatting.AQUA + "Remaining XP: " + EnumChatFormatting.YELLOW + format.format(remaining)); + if (xpGainHour < 1000) { + lineMap.put(5, EnumChatFormatting.AQUA + "ETA: " + EnumChatFormatting.YELLOW + "N/A"); + } else { + lineMap.put(5, EnumChatFormatting.AQUA + "ETA: " + EnumChatFormatting.YELLOW + Utils.prettyTime((long) (remaining) * 1000 * 60 * 60 / (long) xpInterp)); + } + } + + } + + if (skillInfo != null && skillInfo.level == 60) { + int current = (int) skillInfo.currentXp; + if (skillInfoLast != null && skillInfo.currentXpMax == skillInfoLast.currentXpMax) { + current = (int) interp(current, skillInfoLast.currentXp); + } + + lineMap.put(1, EnumChatFormatting.AQUA + "Combat: " + EnumChatFormatting.YELLOW + "60 " + EnumChatFormatting.RED + "(Maxed)"); + lineMap.put(2, EnumChatFormatting.AQUA + "Current XP: " + EnumChatFormatting.YELLOW + format.format(current)); + + } + + for(int strIndex : NotEnoughUpdates.INSTANCE.config.skillOverlays.combatText) { + if(lineMap.get(strIndex) != null) { + overlayStrings.add(lineMap.get(strIndex)); + } + } + if(overlayStrings != null && overlayStrings.isEmpty()) overlayStrings = null; + } + } + + +} \ No newline at end of file diff --git a/src/main/java/io/github/moulberry/notenoughupdates/overlays/MiningOverlay.java b/src/main/java/io/github/moulberry/notenoughupdates/overlays/MiningOverlay.java index 84b5f716..acace238 100644 --- a/src/main/java/io/github/moulberry/notenoughupdates/overlays/MiningOverlay.java +++ b/src/main/java/io/github/moulberry/notenoughupdates/overlays/MiningOverlay.java @@ -282,10 +282,17 @@ public class MiningOverlay extends TextOverlay { if (name.contains("Mithril Powder:")) { mithrilPowder = DARK_AQUA + Utils.trimIgnoreColour(name).replaceAll("\u00a7[f|F|r]", ""); continue; + } else if (mithrilPowder == null) { + mithrilPowder = RED + "[NEU] Failed to get data from your tablist"; + continue; } + if (name.contains("Gemstone Powder:")) { gemstonePowder = DARK_AQUA + Utils.trimIgnoreColour(name).replaceAll("\u00a7[f|F|r]", ""); continue; + } else if (gemstonePowder == null) { + gemstonePowder = RED + "Please enable player list info in your skyblock settings"; + continue; } if (name.matches("\\xa7r\\xa79\\xa7lForges \\xa7r(?:\\xa7f\\(\\+1 more\\)\\xa7r)?") && hidden != null) { diff --git a/src/main/java/io/github/moulberry/notenoughupdates/overlays/MiningSkillOverlay.java b/src/main/java/io/github/moulberry/notenoughupdates/overlays/MiningSkillOverlay.java index 43d6ab70..d143aa6c 100644 --- a/src/main/java/io/github/moulberry/notenoughupdates/overlays/MiningSkillOverlay.java +++ b/src/main/java/io/github/moulberry/notenoughupdates/overlays/MiningSkillOverlay.java @@ -317,7 +317,7 @@ public class MiningSkillOverlay extends TextOverlay { //Im sure there is a much current = (int) interp(current, skillInfoLast.currentXp); } - lineMap.put(2, EnumChatFormatting.AQUA + "Mine: " + EnumChatFormatting.YELLOW + "60 " + EnumChatFormatting.RED + "(Maxed)"); + lineMap.put(2, EnumChatFormatting.AQUA + "Mining: " + EnumChatFormatting.YELLOW + "60 " + EnumChatFormatting.RED + "(Maxed)"); lineMap.put(3, EnumChatFormatting.AQUA + "Current XP: " + EnumChatFormatting.YELLOW + format.format(current)); } diff --git a/src/main/java/io/github/moulberry/notenoughupdates/overlays/OverlayManager.java b/src/main/java/io/github/moulberry/notenoughupdates/overlays/OverlayManager.java index aa52d874..dd9abc31 100644 --- a/src/main/java/io/github/moulberry/notenoughupdates/overlays/OverlayManager.java +++ b/src/main/java/io/github/moulberry/notenoughupdates/overlays/OverlayManager.java @@ -15,10 +15,12 @@ public class OverlayManager { public static FarmingOverlay farmingOverlay; public static FishingSkillOverlay fishingSkillOverlay; public static MiningSkillOverlay miningSkillOverlay; + public static CombatSkillOverlay combatSkillOverlay; public static PetInfoOverlay petInfoOverlay; public static TimersOverlay timersOverlay; public static BonemerangOverlay bonemerangOverlay; public static CrystalHollowOverlay crystalHollowOverlay; + public static SlayerOverlay slayerOverlay; public static final List textOverlays = new ArrayList<>(); static { @@ -131,6 +133,26 @@ public class OverlayManager { } return TextOverlayStyle.BACKGROUND; }); + List combatSkillDummy = Lists.newArrayList( + "\u00a7bKills: \u00a7e547,860", + "\u00a7bCombat: \u00a7e12\u00a77 [\u00a7e|||||||||||||||||\u00a78||||||||\u00a77] \u00a7e67%", + "\u00a7bCurrent XP: \u00a7e6,734", + "\u00a7bRemaining XP: \u00a7e3,265", + "\u00a7bXP/h: \u00a7e238,129", + "\u00a7bETA: \u00a7e13h12m"); + combatSkillOverlay = new CombatSkillOverlay(NotEnoughUpdates.INSTANCE.config.skillOverlays.combatPosition, () -> { + List strings = new ArrayList<>(); + for(int i : NotEnoughUpdates.INSTANCE.config.skillOverlays.combatText) { + if(i >= 0 && i < combatSkillDummy.size()) strings.add(combatSkillDummy.get(i)); + } + return strings; + }, () -> { + int style = NotEnoughUpdates.INSTANCE.config.skillOverlays.combatStyle; + if(style >= 0 && style < TextOverlayStyle.values().length) { + return TextOverlayStyle.values()[style]; + } + return TextOverlayStyle.BACKGROUND; + }); List petInfoDummy = Lists.newArrayList("\u00a7a[Lvl 37] \u00a7fRock", "\u00a7b2,312.9/2,700\u00a7e (85.7%)", "\u00a7b2.3k/2.7k\u00a7e (85.7%)", @@ -210,14 +232,36 @@ public class OverlayManager { } return TextOverlayStyle.BACKGROUND; }); + List slayerDummy = Lists.newArrayList("\u00a7eSlayer: \u00a74Sven", + "\u00a7eRNG Meter: \u00a75100%", + "\u00a7eLvl: \u00a7d7", + "\u00a7eKill time: \u00a7c1:30", + "\u00a7eXP: \u00a7d75,450/100,000", + "\u00a7eBosses till next Lvl: \u00a7d17", + "\u00a7eAverage kill time: \u00a7c3:20"); + slayerOverlay = new SlayerOverlay(NotEnoughUpdates.INSTANCE.config.slayerOverlay.slayerPosition, () -> { + List strings = new ArrayList<>(); + for (int i : NotEnoughUpdates.INSTANCE.config.slayerOverlay.slayerText) { + if (i >= 0 && i < slayerDummy.size()) strings.add(slayerDummy.get(i)); + } + return strings; + }, () -> { + int style = NotEnoughUpdates.INSTANCE.config.slayerOverlay.slayerStyle; + if (style >= 0 && style < TextOverlayStyle.values().length) { + return TextOverlayStyle.values()[style]; + } + return TextOverlayStyle.BACKGROUND; + }); textOverlays.add(miningOverlay); textOverlays.add(farmingOverlay); textOverlays.add(miningSkillOverlay); + textOverlays.add(combatSkillOverlay); textOverlays.add(fishingSkillOverlay); textOverlays.add(petInfoOverlay); textOverlays.add(bonemerangOverlay); textOverlays.add(crystalHollowOverlay); + textOverlays.add(slayerOverlay); } } diff --git a/src/main/java/io/github/moulberry/notenoughupdates/overlays/SlayerOverlay.java b/src/main/java/io/github/moulberry/notenoughupdates/overlays/SlayerOverlay.java new file mode 100644 index 00000000..6f5be7e9 --- /dev/null +++ b/src/main/java/io/github/moulberry/notenoughupdates/overlays/SlayerOverlay.java @@ -0,0 +1,194 @@ +package io.github.moulberry.notenoughupdates.overlays; + +import io.github.moulberry.notenoughupdates.NotEnoughUpdates; +import io.github.moulberry.notenoughupdates.core.config.Position; +import io.github.moulberry.notenoughupdates.util.SBInfo; +import io.github.moulberry.notenoughupdates.util.Utils; +import net.minecraft.client.Minecraft; +import net.minecraft.util.EnumChatFormatting; + +import java.text.NumberFormat; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.function.Supplier; + +public class SlayerOverlay extends TextOverlay { + + public static boolean slayerQuest; + public static String RNGMeter = "?"; + public static boolean isSlain = false; + public static String slayerLVL = "-1"; + public static String slayerXp = "0"; + private static String slayerEXP = "0"; + private static int slayerIntXP; + private static int untilNextSlayerLevel; + private static int xpToLevelUp; + private static boolean useSmallXpNext = true; + public static long timeSinceLastBoss = 0; + public static long timeSinceLastBoss2 = 0; + private static long agvSlayerTime = 0; + private static boolean isSlayerNine = false; + public static int slayerTier = 0; + private static int xpPerBoss = 0; + private static int bossesUntilNextLevel = 0; + public static long unloadOverlayTimer = -1; + + public SlayerOverlay(Position position, Supplier> dummyStrings, Supplier styleSupplier) { + super(position, dummyStrings, styleSupplier); + } + + @Override + public void update() { + if (!NotEnoughUpdates.INSTANCE.config.slayerOverlay.slayerOverlay) { + overlayStrings = null; + return; + } + + if (Minecraft.getMinecraft().thePlayer == null) return; + + if (!slayerQuest) { + slayerTier = 0; + } + + if (slayerXp.equals("maxed")) { + isSlayerNine = true; + } else if (!slayerXp.equals("0")) { + slayerEXP = slayerXp.replace(",", ""); + slayerIntXP = Integer.parseInt(slayerEXP); + isSlayerNine = false; + } else { + slayerIntXP = 0; + isSlayerNine = false; + } + //System.out.println(slayerEXP); + if (SBInfo.getInstance().slayer.equals("Tarantula") || SBInfo.getInstance().slayer.equals("Revenant")) { + useSmallXpNext = true; + } else if (SBInfo.getInstance().slayer.equals("Sven") || SBInfo.getInstance().slayer.equals("Enderman")) { + useSmallXpNext = false; + } + switch (slayerLVL) { + case "9": + xpToLevelUp = 2000000; + break; + case "8": + xpToLevelUp = 1000000; + break; + case "7": + xpToLevelUp = 400000; + break; + case "6": + xpToLevelUp = 100000; + break; + case "5": + xpToLevelUp = 20000; + break; + case "4": + xpToLevelUp = 5000; + break; + case "3": + if (useSmallXpNext) { + xpToLevelUp = 1000; + } else { + xpToLevelUp = 1500; + } + break; + case "2": + if (useSmallXpNext) { + xpToLevelUp = 200; + } else { + xpToLevelUp = 250; + } + break; + case "1": + if (SBInfo.getInstance().slayer.equals("Revenant")) { + xpToLevelUp = 15; + } else if (SBInfo.getInstance().slayer.equals("Tarantula")) { + xpToLevelUp = 25; + } else { + xpToLevelUp = 30; + } + break; + case "0": + if (useSmallXpNext) { + xpToLevelUp = 5; + } else { + xpToLevelUp = 10; + } + break; + } + if (slayerTier == 5) { + xpPerBoss = 1500; + } else if (slayerTier == 4) { + xpPerBoss = 500; + } else if (slayerTier == 3) { + xpPerBoss = 100; + } else if (slayerTier == 2) { + xpPerBoss = 25; + } else if (slayerTier == 1) { + xpPerBoss = 5; + } else { + xpPerBoss = 0; + } + untilNextSlayerLevel = xpToLevelUp - slayerIntXP; + if (xpPerBoss != 0 && untilNextSlayerLevel != 0 && xpToLevelUp != 0) { + bossesUntilNextLevel = (xpToLevelUp - untilNextSlayerLevel) / xpPerBoss; + } else { + bossesUntilNextLevel = 0; + } + agvSlayerTime = (timeSinceLastBoss+timeSinceLastBoss2)/2; + } + + @Override + public void updateFrequent() { + super.updateFrequent(); + + if (!slayerQuest || !NotEnoughUpdates.INSTANCE.config.slayerOverlay.slayerOverlay) { + overlayStrings = null; + } else { + HashMap lineMap = new HashMap<>(); + + NumberFormat format = NumberFormat.getIntegerInstance(); + //System.out.println(SBInfo.getInstance().isSlain); + overlayStrings = new ArrayList<>(); + lineMap.put(0, EnumChatFormatting.YELLOW + "Slayer: " + EnumChatFormatting.DARK_RED + SBInfo.getInstance().slayer + + EnumChatFormatting.GREEN + (isSlain ? " (Killed) " : " ")/* + slayerTier*/); + + if (!RNGMeter.equals("?")) { + lineMap.put(1, EnumChatFormatting.YELLOW + "RNG Meter: " + EnumChatFormatting.DARK_PURPLE + RNGMeter); + } + + if (!slayerLVL.equals("-1")) { + lineMap.put(2, EnumChatFormatting.YELLOW + "Lvl: " + EnumChatFormatting.LIGHT_PURPLE + slayerLVL); + } + + if (timeSinceLastBoss > 0) { + lineMap.put(3, EnumChatFormatting.YELLOW + "Kill time: " + EnumChatFormatting.RED + + Utils.prettyTime((System.currentTimeMillis() - timeSinceLastBoss))); + } + + if (slayerIntXP > 0) { + lineMap.put(4, EnumChatFormatting.YELLOW + "XP: " + EnumChatFormatting.LIGHT_PURPLE + + format.format(untilNextSlayerLevel) + "/" + format.format(xpToLevelUp)); + } else if (isSlayerNine) { + lineMap.put(4, EnumChatFormatting.YELLOW + "XP: " + EnumChatFormatting.LIGHT_PURPLE + "MAXED"); + } + + if (xpPerBoss != 0 && slayerIntXP > 0) { + lineMap.put(5, EnumChatFormatting.YELLOW + "Bosses till next Lvl: " + EnumChatFormatting.LIGHT_PURPLE + + (bossesUntilNextLevel > 1000 ? "?" : bossesUntilNextLevel)); + } + + if (timeSinceLastBoss > 0 && timeSinceLastBoss2 > 0) { + lineMap.put(6, EnumChatFormatting.YELLOW + "Average kill time: " + EnumChatFormatting.RED + + Utils.prettyTime((System.currentTimeMillis() - agvSlayerTime))); + } + for (int strIndex : NotEnoughUpdates.INSTANCE.config.slayerOverlay.slayerText) { + if (lineMap.get(strIndex) != null) { + overlayStrings.add(lineMap.get(strIndex)); + } + } + if (overlayStrings != null && overlayStrings.isEmpty()) overlayStrings = null; + } + } +} diff --git a/src/main/java/io/github/moulberry/notenoughupdates/overlays/TimersOverlay.java b/src/main/java/io/github/moulberry/notenoughupdates/overlays/TimersOverlay.java index d5bc5d56..67873df8 100644 --- a/src/main/java/io/github/moulberry/notenoughupdates/overlays/TimersOverlay.java +++ b/src/main/java/io/github/moulberry/notenoughupdates/overlays/TimersOverlay.java @@ -398,12 +398,10 @@ public class TimersOverlay extends TextOverlay { } long midnightReset = (currentTime - 18000000) / 86400000 * 86400000 + 18000000; - long experimentReset = (currentTime - 18000000) / 86400000 * 86400000 + 86400000; long fetchurComplete = hidden.fetchurCompleted; long timeDiffMidnightNow = midnightReset + 86400000 - currentTime; - long timeDiffMidnightNowExp = experimentReset + 86400000 - currentTime; //Fetchur Display if (fetchurComplete < midnightReset) { @@ -438,19 +436,19 @@ public class TimersOverlay extends TextOverlay { } //Experiment Display - if (hidden.experimentsCompleted < experimentReset) { + if (hidden.experimentsCompleted < midnightReset) { map.put(6, DARK_AQUA + "Experiments: " + EnumChatFormatting.values()[NotEnoughUpdates.INSTANCE.config.miscOverlays.readyColour] + "Ready!"); } else if (NotEnoughUpdates.INSTANCE.config.miscOverlays.experimentationDisplay >= DISPLAYTYPE.VERYSOON.ordinal() && - (hidden.experimentsCompleted < (experimentReset - TimeEnums.HALFANHOUR.time))) { - map.put(6, DARK_AQUA + "Experiments: " + EnumChatFormatting.values()[NotEnoughUpdates.INSTANCE.config.miscOverlays.verySoonColour] + Utils.prettyTime(timeDiffMidnightNowExp)); + (hidden.experimentsCompleted < (midnightReset - TimeEnums.HALFANHOUR.time))) { + map.put(6, DARK_AQUA + "Experiments: " + EnumChatFormatting.values()[NotEnoughUpdates.INSTANCE.config.miscOverlays.verySoonColour] + Utils.prettyTime(timeDiffMidnightNow)); } else if (NotEnoughUpdates.INSTANCE.config.miscOverlays.experimentationDisplay >= DISPLAYTYPE.SOON.ordinal() && - (hidden.experimentsCompleted < (experimentReset - TimeEnums.HOUR.time))) { - map.put(6, DARK_AQUA + "Experiments: " + EnumChatFormatting.values()[NotEnoughUpdates.INSTANCE.config.miscOverlays.soonColour] + Utils.prettyTime(timeDiffMidnightNowExp)); + (hidden.experimentsCompleted < (midnightReset - TimeEnums.HOUR.time))) { + map.put(6, DARK_AQUA + "Experiments: " + EnumChatFormatting.values()[NotEnoughUpdates.INSTANCE.config.miscOverlays.soonColour] + Utils.prettyTime(timeDiffMidnightNow)); } else if (NotEnoughUpdates.INSTANCE.config.miscOverlays.experimentationDisplay >= DISPLAYTYPE.KINDASOON.ordinal() && - (hidden.experimentsCompleted < (experimentReset - (TimeEnums.HOUR.time * 3)))) { - map.put(6, DARK_AQUA + "Experiments: " + EnumChatFormatting.values()[NotEnoughUpdates.INSTANCE.config.miscOverlays.kindaSoonColour] + Utils.prettyTime(timeDiffMidnightNowExp)); + (hidden.experimentsCompleted < (midnightReset - (TimeEnums.HOUR.time * 3)))) { + map.put(6, DARK_AQUA + "Experiments: " + EnumChatFormatting.values()[NotEnoughUpdates.INSTANCE.config.miscOverlays.kindaSoonColour] + Utils.prettyTime(timeDiffMidnightNow)); } else if (NotEnoughUpdates.INSTANCE.config.miscOverlays.experimentationDisplay >= DISPLAYTYPE.ALWAYS.ordinal()) { - map.put(6, DARK_AQUA + "Experiments: " + EnumChatFormatting.values()[NotEnoughUpdates.INSTANCE.config.miscOverlays.defaultColour] + Utils.prettyTime(timeDiffMidnightNowExp)); + map.put(6, DARK_AQUA + "Experiments: " + EnumChatFormatting.values()[NotEnoughUpdates.INSTANCE.config.miscOverlays.defaultColour] + Utils.prettyTime(timeDiffMidnightNow)); } overlayStrings = new ArrayList<>(); diff --git a/src/main/java/io/github/moulberry/notenoughupdates/profileviewer/GuiProfileViewer.java b/src/main/java/io/github/moulberry/notenoughupdates/profileviewer/GuiProfileViewer.java index 8295fcbc..81453a8d 100644 --- a/src/main/java/io/github/moulberry/notenoughupdates/profileviewer/GuiProfileViewer.java +++ b/src/main/java/io/github/moulberry/notenoughupdates/profileviewer/GuiProfileViewer.java @@ -73,6 +73,7 @@ public class GuiProfileViewer extends GuiScreen { public static final ResourceLocation pv_bg = new ResourceLocation("notenoughupdates:pv_bg.png"); public static final ResourceLocation pv_elements = new ResourceLocation("notenoughupdates:pv_elements.png"); public static final ResourceLocation pv_ironman = new ResourceLocation("notenoughupdates:pv_ironman.png"); + public static final ResourceLocation pv_bingo = new ResourceLocation("notenoughupdates:pv_bingo.png"); public static final ResourceLocation resource_packs = new ResourceLocation("minecraft:textures/gui/resource_packs.png"); public static final ResourceLocation icons = new ResourceLocation("textures/gui/icons.png"); @@ -200,11 +201,18 @@ public class GuiProfileViewer extends GuiScreen { 0, 100 / 200f, 0, 20 / 185f, GL11.GL_NEAREST); Utils.drawStringCenteredScaledMaxWidth(profileId, Minecraft.getMinecraft().fontRendererObj, guiLeft + 50, guiTop + sizeY + 3 + 10, true, 90, new Color(63, 224, 208, 255).getRGB()); + //ironman icon if (currProfileInfo != null && currProfileInfo.has("game_mode") && currProfileInfo.get("game_mode").getAsString().equals("ironman")) { GlStateManager.color(1, 1, 1, 1); Minecraft.getMinecraft().getTextureManager().bindTexture(pv_ironman); Utils.drawTexturedRect(guiLeft - 16 - 5, guiTop + sizeY + 5, 16, 16, GL11.GL_NEAREST); } + //bingo! icon + if (currProfileInfo != null && currProfileInfo.has("game_mode") && currProfileInfo.get("game_mode").getAsString().equals("bingo")) { + GlStateManager.color(1, 1, 1, 1); + Minecraft.getMinecraft().getTextureManager().bindTexture(pv_bingo); + Utils.drawTexturedRect(guiLeft - 16 - 5, guiTop + sizeY + 5, 16, 16, GL11.GL_NEAREST); + } //Render Open In Skycrypt button renderBlurredBackground(width, height, guiLeft + 100 + 6 + 2, guiTop + sizeY + 3 + 2, 100 - 4, 20 - 4); Minecraft.getMinecraft().getTextureManager().bindTexture(pv_dropdown); @@ -237,6 +245,11 @@ public class GuiProfileViewer extends GuiScreen { Minecraft.getMinecraft().getTextureManager().bindTexture(pv_ironman); Utils.drawTexturedRect(guiLeft - 16 - 5, guiTop + sizeY + 2 + 23 + dropdownOptionSize * yIndex, 16, 16, GL11.GL_NEAREST); } + if (currProfileInfo != null && currProfileInfo.has("game_mode") && currProfileInfo.get("game_mode").getAsString().equals("bingo")) { + GlStateManager.color(1, 1, 1, 1); + Minecraft.getMinecraft().getTextureManager().bindTexture(pv_bingo); + Utils.drawTexturedRect(guiLeft - 16 - 5, guiTop + sizeY + 2 + 23 + dropdownOptionSize * yIndex, 16, 16, GL11.GL_NEAREST); + } } } @@ -3553,7 +3566,7 @@ public class GuiProfileViewer extends GuiScreen { "§7Level " + quickForge + EnumChatFormatting.DARK_GRAY + "/20", "", "§7Decreases the time it takes to", - "§7forge by §a" + quickForgeStat + "%§7." + "§7forge by §a" + (quickForgeStat < 20 ? quickForgeStat : 30) + "%§7." ); Utils.drawHoveringText(quickForgeTooltip, mouseX, mouseY, width, height, -1, fr); quickForgeTooltip = null; diff --git a/src/main/java/io/github/moulberry/notenoughupdates/util/SBInfo.java b/src/main/java/io/github/moulberry/notenoughupdates/util/SBInfo.java index 15906884..6b901622 100644 --- a/src/main/java/io/github/moulberry/notenoughupdates/util/SBInfo.java +++ b/src/main/java/io/github/moulberry/notenoughupdates/util/SBInfo.java @@ -2,6 +2,7 @@ package io.github.moulberry.notenoughupdates.util; import com.google.gson.JsonObject; import io.github.moulberry.notenoughupdates.NotEnoughUpdates; +import io.github.moulberry.notenoughupdates.overlays.SlayerOverlay; import net.minecraft.client.Minecraft; import net.minecraft.client.gui.inventory.GuiChest; import net.minecraft.client.network.NetworkPlayerInfo; @@ -42,6 +43,7 @@ public class SBInfo { public String date = ""; public String time = ""; public String objective = ""; + public String slayer = ""; public String mode = ""; @@ -182,6 +184,36 @@ public class SBInfo { } isInDungeon = tempIsInDungeon; + for (String line : lines) { //Slayer stuff + //System.out.println(line); + if (line.contains("Tarantula Broodfather")) { + slayer = "Tarantula"; + } else if (line.contains("Revenant Horror")) { + slayer = "Revenant"; + } else if (line.contains("Sven Packmaster")) { + slayer = "Sven"; + } else if (line.contains("Voidgloom Seraph")) { + slayer = "Enderman"; + } + if (lines.contains("Slayer Quest") && SlayerOverlay.unloadOverlayTimer == -1 || + lines.contains("Slayer Quest") && System.currentTimeMillis() - SlayerOverlay.unloadOverlayTimer > 500) { + SlayerOverlay.slayerQuest = true; + } + if (SlayerOverlay.slayerQuest) { + if (line.contains(" I")) { + SlayerOverlay.slayerTier = 1; + } if (line.contains(" II")) { + SlayerOverlay.slayerTier = 2; + } if (line.contains(" III")) { + SlayerOverlay.slayerTier = 3; + } if (line.contains(" IV")) { + SlayerOverlay.slayerTier = 4; + } if (line.contains(" V")) { + SlayerOverlay.slayerTier = 5; + } + } + } + if (lines.size() >= 5) { date = Utils.cleanColour(lines.get(1)).trim(); //§74:40am diff --git a/src/main/resources/assets/notenoughupdates/custom_enchant_gui.png b/src/main/resources/assets/notenoughupdates/custom_enchant_gui.png index 06a1fb5d..735a3fb4 100644 Binary files a/src/main/resources/assets/notenoughupdates/custom_enchant_gui.png and b/src/main/resources/assets/notenoughupdates/custom_enchant_gui.png differ diff --git a/src/main/resources/assets/notenoughupdates/pv_bingo.png b/src/main/resources/assets/notenoughupdates/pv_bingo.png new file mode 100644 index 00000000..5651dfce Binary files /dev/null and b/src/main/resources/assets/notenoughupdates/pv_bingo.png differ -- cgit From aca006bb4d379b6afe79357f24957f035184636e Mon Sep 17 00:00:00 2001 From: nopothegamer <40329022+nopothegamer@users.noreply.github.com> Date: Sat, 18 Dec 2021 21:27:48 +1100 Subject: added pv icons + changed mines of divan waypoint color (#31) * istg if you give me 170 commits i will end someone(added stranded pv icon + added an icon for gamemodes that neu doesnt know about) * Change the mines of divan waypoints to blue because it was hard to see the gold waypoint gold blocks everywhere --- .../miscfeatures/CrystalMetalDetectorSolver.java | 2 +- .../profileviewer/GuiProfileViewer.java | 30 +++++++++++++++++++++ .../assets/notenoughupdates/pv_stranded.png | Bin 0 -> 242 bytes .../assets/notenoughupdates/pv_unknown.png | Bin 0 -> 1814 bytes 4 files changed, 31 insertions(+), 1 deletion(-) create mode 100644 src/main/resources/assets/notenoughupdates/pv_stranded.png create mode 100644 src/main/resources/assets/notenoughupdates/pv_unknown.png (limited to 'src/main/resources/assets') diff --git a/src/main/java/io/github/moulberry/notenoughupdates/miscfeatures/CrystalMetalDetectorSolver.java b/src/main/java/io/github/moulberry/notenoughupdates/miscfeatures/CrystalMetalDetectorSolver.java index f20081ad..8d73e28d 100644 --- a/src/main/java/io/github/moulberry/notenoughupdates/miscfeatures/CrystalMetalDetectorSolver.java +++ b/src/main/java/io/github/moulberry/notenoughupdates/miscfeatures/CrystalMetalDetectorSolver.java @@ -104,7 +104,7 @@ public class CrystalMetalDetectorSolver { } public static void render(float partialTicks) { - int beaconRGB = 0xffdf00; + int beaconRGB = 0x1fd8f1; if (SBInfo.getInstance().getLocation() != null && SBInfo.getInstance().getLocation().equals("crystal_hollows") && SBInfo.getInstance().location.equals("Mines of Divan")) { diff --git a/src/main/java/io/github/moulberry/notenoughupdates/profileviewer/GuiProfileViewer.java b/src/main/java/io/github/moulberry/notenoughupdates/profileviewer/GuiProfileViewer.java index 81453a8d..227d52d0 100644 --- a/src/main/java/io/github/moulberry/notenoughupdates/profileviewer/GuiProfileViewer.java +++ b/src/main/java/io/github/moulberry/notenoughupdates/profileviewer/GuiProfileViewer.java @@ -74,6 +74,8 @@ public class GuiProfileViewer extends GuiScreen { public static final ResourceLocation pv_elements = new ResourceLocation("notenoughupdates:pv_elements.png"); public static final ResourceLocation pv_ironman = new ResourceLocation("notenoughupdates:pv_ironman.png"); public static final ResourceLocation pv_bingo = new ResourceLocation("notenoughupdates:pv_bingo.png"); + public static final ResourceLocation pv_stranded = new ResourceLocation("notenoughupdates:pv_stranded.png"); + public static final ResourceLocation pv_unknown = new ResourceLocation("notenoughupdates:pv_unknown.png"); public static final ResourceLocation resource_packs = new ResourceLocation("minecraft:textures/gui/resource_packs.png"); public static final ResourceLocation icons = new ResourceLocation("textures/gui/icons.png"); @@ -213,6 +215,21 @@ public class GuiProfileViewer extends GuiScreen { Minecraft.getMinecraft().getTextureManager().bindTexture(pv_bingo); Utils.drawTexturedRect(guiLeft - 16 - 5, guiTop + sizeY + 5, 16, 16, GL11.GL_NEAREST); } + //stranded icon + if (currProfileInfo != null && currProfileInfo.has("game_mode") && currProfileInfo.get("game_mode").getAsString().equals("stranded")) { + GlStateManager.color(1, 1, 1, 1); + Minecraft.getMinecraft().getTextureManager().bindTexture(pv_stranded); + Utils.drawTexturedRect(guiLeft - 16 - 5, guiTop + sizeY + 5, 16, 16, GL11.GL_NEAREST); + } + //icon if game mode is unknown + if (currProfileInfo != null && currProfileInfo.has("game_mode") && + !currProfileInfo.get("game_mode").getAsString().equals("stranded") && + !currProfileInfo.get("game_mode").getAsString().equals("bingo") && + !currProfileInfo.get("game_mode").getAsString().equals("ironman")) { + GlStateManager.color(1, 1, 1, 1); + Minecraft.getMinecraft().getTextureManager().bindTexture(pv_unknown); + Utils.drawTexturedRect(guiLeft - 16 - 5, guiTop + sizeY + 5, 16, 16, GL11.GL_NEAREST); + } //Render Open In Skycrypt button renderBlurredBackground(width, height, guiLeft + 100 + 6 + 2, guiTop + sizeY + 3 + 2, 100 - 4, 20 - 4); Minecraft.getMinecraft().getTextureManager().bindTexture(pv_dropdown); @@ -250,6 +267,19 @@ public class GuiProfileViewer extends GuiScreen { Minecraft.getMinecraft().getTextureManager().bindTexture(pv_bingo); Utils.drawTexturedRect(guiLeft - 16 - 5, guiTop + sizeY + 2 + 23 + dropdownOptionSize * yIndex, 16, 16, GL11.GL_NEAREST); } + if (currProfileInfo != null && currProfileInfo.has("game_mode") && currProfileInfo.get("game_mode").getAsString().equals("stranded")) { + GlStateManager.color(1, 1, 1, 1); + Minecraft.getMinecraft().getTextureManager().bindTexture(pv_stranded); + Utils.drawTexturedRect(guiLeft - 16 - 5, guiTop + sizeY + 2 + 23 + dropdownOptionSize * yIndex, 16, 16, GL11.GL_NEAREST); + } + if (currProfileInfo != null && currProfileInfo.has("game_mode") && + !currProfileInfo.get("game_mode").getAsString().equals("stranded") && + !currProfileInfo.get("game_mode").getAsString().equals("bingo") && + !currProfileInfo.get("game_mode").getAsString().equals("ironman")) { + GlStateManager.color(1, 1, 1, 1); + Minecraft.getMinecraft().getTextureManager().bindTexture(pv_unknown); + Utils.drawTexturedRect(guiLeft - 16 - 5, guiTop + sizeY + 2 + 23 + dropdownOptionSize * yIndex, 16, 16, GL11.GL_NEAREST); + } } } diff --git a/src/main/resources/assets/notenoughupdates/pv_stranded.png b/src/main/resources/assets/notenoughupdates/pv_stranded.png new file mode 100644 index 00000000..41b7a7cd Binary files /dev/null and b/src/main/resources/assets/notenoughupdates/pv_stranded.png differ diff --git a/src/main/resources/assets/notenoughupdates/pv_unknown.png b/src/main/resources/assets/notenoughupdates/pv_unknown.png new file mode 100644 index 00000000..d6ce3a00 Binary files /dev/null and b/src/main/resources/assets/notenoughupdates/pv_unknown.png differ -- cgit From 98436ad0cf75c9a4bacbfb35a63948cc61c543f9 Mon Sep 17 00:00:00 2001 From: DeDiamondPro <67508414+DeDiamondPro@users.noreply.github.com> Date: Wed, 29 Dec 2021 15:26:46 +0100 Subject: Add price graph (#43) * graph thingy * styles * cool stuff * move enabled to top * no pretty printing so smaller files * general improvements to how data is visualised * small oopsie * bazaar support (delete old price data or crash) * Update AHGraph.java * remove 1 line so iron doesn't have to * Update GuiPriceGraph.java * happy now jani? * there ironmoon Co-authored-by: nopothegamer <40329022+nopothegamer@users.noreply.github.com> --- .../moulberry/notenoughupdates/NEUOverlay.java | 4 + .../notenoughupdates/auction/APIManager.java | 3 + .../notenoughupdates/commands/Commands.java | 10 +- .../notenoughupdates/miscgui/GuiPriceGraph.java | 492 +++++++++++++++++++++ .../notenoughupdates/options/NEUConfig.java | 7 + .../options/seperateSections/AHGraph.java | 83 ++++ .../moulberry/notenoughupdates/util/Utils.java | 75 ++++ .../price_graph_gui/price_information_gui.png | Bin 0 -> 2079 bytes .../price_graph_gui/price_information_gui_dark.png | Bin 0 -> 2088 bytes .../price_graph_gui/price_information_gui_fsr.png | Bin 0 -> 2045 bytes .../price_information_gui_phqdark.png | Bin 0 -> 2091 bytes 11 files changed, 673 insertions(+), 1 deletion(-) create mode 100644 src/main/java/io/github/moulberry/notenoughupdates/miscgui/GuiPriceGraph.java create mode 100644 src/main/java/io/github/moulberry/notenoughupdates/options/seperateSections/AHGraph.java create mode 100644 src/main/resources/assets/notenoughupdates/price_graph_gui/price_information_gui.png create mode 100644 src/main/resources/assets/notenoughupdates/price_graph_gui/price_information_gui_dark.png create mode 100644 src/main/resources/assets/notenoughupdates/price_graph_gui/price_information_gui_fsr.png create mode 100644 src/main/resources/assets/notenoughupdates/price_graph_gui/price_information_gui_phqdark.png (limited to 'src/main/resources/assets') diff --git a/src/main/java/io/github/moulberry/notenoughupdates/NEUOverlay.java b/src/main/java/io/github/moulberry/notenoughupdates/NEUOverlay.java index 18e0fc3b..acc15e8d 100644 --- a/src/main/java/io/github/moulberry/notenoughupdates/NEUOverlay.java +++ b/src/main/java/io/github/moulberry/notenoughupdates/NEUOverlay.java @@ -17,6 +17,7 @@ import io.github.moulberry.notenoughupdates.mbgui.MBGuiElement; import io.github.moulberry.notenoughupdates.mbgui.MBGuiGroupAligned; import io.github.moulberry.notenoughupdates.mbgui.MBGuiGroupFloating; import io.github.moulberry.notenoughupdates.miscfeatures.SunTzu; +import io.github.moulberry.notenoughupdates.miscgui.GuiPriceGraph; import io.github.moulberry.notenoughupdates.options.NEUConfigEditor; import io.github.moulberry.notenoughupdates.util.Constants; import io.github.moulberry.notenoughupdates.util.LerpingFloat; @@ -1037,6 +1038,9 @@ public class NEUOverlay extends Gui { textField.setText("id:" + internalname.get()); itemPaneOpen = true; updateSearch(); + } else if (keyPressed == NotEnoughUpdates.INSTANCE.config.ahGraph.graphKey && NotEnoughUpdates.INSTANCE.config.ahGraph.graphEnabled) { + NotEnoughUpdates.INSTANCE.openGui = new GuiPriceGraph(internalname.get()); + return true; } } } diff --git a/src/main/java/io/github/moulberry/notenoughupdates/auction/APIManager.java b/src/main/java/io/github/moulberry/notenoughupdates/auction/APIManager.java index b3e145a8..254ab5cf 100644 --- a/src/main/java/io/github/moulberry/notenoughupdates/auction/APIManager.java +++ b/src/main/java/io/github/moulberry/notenoughupdates/auction/APIManager.java @@ -6,6 +6,7 @@ import com.google.gson.JsonObject; import io.github.moulberry.notenoughupdates.ItemPriceInformation; import io.github.moulberry.notenoughupdates.NEUManager; import io.github.moulberry.notenoughupdates.NotEnoughUpdates; +import io.github.moulberry.notenoughupdates.miscgui.GuiPriceGraph; import io.github.moulberry.notenoughupdates.util.Constants; import io.github.moulberry.notenoughupdates.util.Utils; import net.minecraft.client.Minecraft; @@ -261,6 +262,7 @@ public class APIManager { ItemPriceInformation.updateAuctionableItemsList(); didFirstUpdate = true; } + GuiPriceGraph.addToCache(lowestBins, false); }, () -> {}); } @@ -675,6 +677,7 @@ public class APIManager { bazaarJson.add(entry.getKey().replace(":", "-"), productInfo); } } + GuiPriceGraph.addToCache(bazaarJson, true); }); } diff --git a/src/main/java/io/github/moulberry/notenoughupdates/commands/Commands.java b/src/main/java/io/github/moulberry/notenoughupdates/commands/Commands.java index 97004752..910870d5 100644 --- a/src/main/java/io/github/moulberry/notenoughupdates/commands/Commands.java +++ b/src/main/java/io/github/moulberry/notenoughupdates/commands/Commands.java @@ -715,7 +715,7 @@ public class Commands { "Ok, this is actually the last message, use the command again and you'll crash I promise"}; private int devFailIndex = 0; - private static final List devTestUsers = new ArrayList<>(Arrays.asList("moulberry", "lucycoconut", "ironm00n", "ariyio", "throwpo")); + private static final List devTestUsers = new ArrayList<>(Arrays.asList("moulberry", "lucycoconut", "ironm00n", "ariyio", "throwpo", "dediamondpro")); SimpleCommand devTestCommand = new SimpleCommand("neudevtest", new SimpleCommand.ProcessCommandRunnable() { @Override public void processCommand(ICommandSender sender, String[] args) { @@ -748,6 +748,14 @@ public class Commands { DupePOC.doDupe(args[0]); return; }*/ + if (args.length >= 1 && args[0].equalsIgnoreCase("pricetest")) { + if (args.length == 1) { + NotEnoughUpdates.INSTANCE.manager.auctionManager.updateBazaar(); + } else { + NotEnoughUpdates.INSTANCE.openGui = new GuiPriceGraph(args[1]); + } + } + if (args.length == 1 && args[0].equalsIgnoreCase("positiontest")) { NotEnoughUpdates.INSTANCE.openGui = new GuiPositionEditor(); return; diff --git a/src/main/java/io/github/moulberry/notenoughupdates/miscgui/GuiPriceGraph.java b/src/main/java/io/github/moulberry/notenoughupdates/miscgui/GuiPriceGraph.java new file mode 100644 index 00000000..a063bafe --- /dev/null +++ b/src/main/java/io/github/moulberry/notenoughupdates/miscgui/GuiPriceGraph.java @@ -0,0 +1,492 @@ +package io.github.moulberry.notenoughupdates.miscgui; + +import com.google.common.reflect.TypeToken; +import com.google.gson.Gson; +import com.google.gson.GsonBuilder; +import com.google.gson.JsonElement; +import com.google.gson.JsonObject; +import io.github.moulberry.notenoughupdates.NotEnoughUpdates; +import io.github.moulberry.notenoughupdates.util.SpecialColour; +import io.github.moulberry.notenoughupdates.util.Utils; +import net.minecraft.client.Minecraft; +import net.minecraft.client.gui.Gui; +import net.minecraft.client.gui.GuiScreen; +import net.minecraft.client.renderer.GlStateManager; +import net.minecraft.item.ItemStack; +import net.minecraft.util.EnumChatFormatting; +import net.minecraft.util.ResourceLocation; +import org.lwjgl.opengl.GL11; + +import java.io.*; +import java.lang.reflect.Type; +import java.nio.charset.StandardCharsets; +import java.text.DecimalFormat; +import java.text.NumberFormat; +import java.text.SimpleDateFormat; +import java.time.Instant; +import java.util.*; +import java.util.stream.Collectors; +import java.util.zip.GZIPInputStream; +import java.util.zip.GZIPOutputStream; + +public class GuiPriceGraph extends GuiScreen { + + private static final Gson GSON = new GsonBuilder().create(); + private static final SimpleDateFormat format = new SimpleDateFormat("dd-MM-yyyy"); + private final ResourceLocation TEXTURE; + private static final int X_SIZE = 364; + private static final int Y_SIZE = 215; + private Data dataPoints; + private float highestValue; + private long firstTime; + private long lastTime; + private Float lowestValue = null; + private String itemName; + private final String itemId; + private int guiLeft; + private int guiTop; + private ItemStack itemStack = null; + private boolean loaded = false; + /** + * 0 = hour + * 1 = day + * 2 = week + * 3 = all + * 4 = custom + **/ + private int mode = NotEnoughUpdates.INSTANCE.config.ahGraph.defaultMode; + private long customStart = 0; + private long customEnd = 0; + private boolean customSelecting = false; + + public GuiPriceGraph(String itemId) { + switch (NotEnoughUpdates.INSTANCE.config.ahGraph.graphStyle) { + case 1: + TEXTURE = new ResourceLocation("notenoughupdates:price_graph_gui/price_information_gui_dark.png"); + break; + case 2: + TEXTURE = new ResourceLocation("notenoughupdates:price_graph_gui/price_information_gui_phqdark.png"); + break; + case 3: + TEXTURE = new ResourceLocation("notenoughupdates:price_graph_gui/price_information_gui_fsr.png"); + break; + default: + TEXTURE = new ResourceLocation("notenoughupdates:price_graph_gui/price_information_gui.png"); + break; + } + this.itemId = itemId; + if (NotEnoughUpdates.INSTANCE.manager.getItemInformation().containsKey(itemId)) { + JsonObject itemInfo = NotEnoughUpdates.INSTANCE.manager.getItemInformation().get(itemId); + itemName = itemInfo.get("displayname").getAsString(); + itemStack = NotEnoughUpdates.INSTANCE.manager.jsonToStack(itemInfo); + } + loadData(); + } + + @Override + public void drawScreen(int mouseX, int mouseY, float partialTicks) { + guiLeft = (width - X_SIZE) / 2; + guiTop = (height - Y_SIZE) / 2; + + Minecraft.getMinecraft().getTextureManager().bindTexture(TEXTURE); + GlStateManager.color(1, 1, 1, 1); + Utils.drawTexturedRect(guiLeft, guiTop, X_SIZE, Y_SIZE, + 0, X_SIZE / 512f, 0, Y_SIZE / 512f, GL11.GL_NEAREST); + Utils.drawTexturedRect(guiLeft + 245, guiTop + 17, 16, 16, + 0, 16 / 512f, (mode == 0 ? 215 : 231) / 512f, (mode == 0 ? 231 : 247) / 512f, GL11.GL_NEAREST); + Utils.drawTexturedRect(guiLeft + 263, guiTop + 17, 16, 16, + 16 / 512f, 32 / 512f, (mode == 1 ? 215 : 231) / 512f, (mode == 1 ? 231 : 247) / 512f, GL11.GL_NEAREST); + Utils.drawTexturedRect(guiLeft + 281, guiTop + 17, 16, 16, + 32 / 512f, 48 / 512f, (mode == 2 ? 215 : 231) / 512f, (mode == 2 ? 231 : 247) / 512f, GL11.GL_NEAREST); + Utils.drawTexturedRect(guiLeft + 299, guiTop + 17, 16, 16, + 48 / 512f, 64 / 512f, (mode == 3 ? 215 : 231) / 512f, (mode == 3 ? 231 : 247) / 512f, GL11.GL_NEAREST); + + if (itemName != null && itemStack != null) { + Utils.drawItemStack(itemStack, guiLeft + 16, guiTop + 11); + Utils.drawStringScaledMax(itemName, Minecraft.getMinecraft().fontRendererObj, guiLeft + 35, guiTop + 13, false, + 0xffffff, 1.77f, 208); + } + + if (!loaded) + Utils.drawStringCentered("Loading...", Minecraft.getMinecraft().fontRendererObj, + guiLeft + 166, guiTop + 116, false, 0xffffff00); + else if (dataPoints == null || dataPoints.get() == null || dataPoints.get().size() <= 1) + Utils.drawStringCentered("No data found.", Minecraft.getMinecraft().fontRendererObj, + guiLeft + 166, guiTop + 116, false, 0xffff0000); + else { + + int graphColor = SpecialColour.specialToChromaRGB(NotEnoughUpdates.INSTANCE.config.ahGraph.graphColor); + int graphColor2 = SpecialColour.specialToChromaRGB(NotEnoughUpdates.INSTANCE.config.ahGraph.graphColor2); + Integer lowestDist = null; + Long lowestDistTime = null; + HashMap secondLineData = new HashMap<>(); + for (int i = (dataPoints.isBz() ? 1 : 0); i >= 0; i--) { + Utils.drawGradientRect(0, guiLeft + 17, guiTop + 35, guiLeft + 315, guiTop + 198, + changeAlpha(i == 0 ? graphColor : graphColor2, 120), changeAlpha(i == 0 ? graphColor : graphColor2, 10)); + Integer prevX = null; + Integer prevY = null; + for (Long time : dataPoints.get().keySet()) { + float price = dataPoints.isBz() ? i == 0 ? dataPoints.bz.get(time).b : dataPoints.bz.get(time).s : dataPoints.ah.get(time); + int xPos = (int) map(time, firstTime, lastTime, guiLeft + 17, guiLeft + 315); + int yPos = (int) map(price, highestValue + 10, lowestValue - 10, guiTop + 35, guiTop + 198); + if (prevX != null) { + Minecraft.getMinecraft().getTextureManager().bindTexture(TEXTURE); + GlStateManager.color(1, 1, 1, 1); + Utils.drawTexturedQuad(prevX, prevY, xPos, yPos, xPos, guiTop + 35, prevX, guiTop + 35, 18 / 512f, 19 / 512f, + 36 / 512f, 37 / 512f, GL11.GL_NEAREST); + if (i == 0) { + Utils.drawLine(prevX, prevY + 0.5f, xPos, yPos + 0.5f, 2, graphColor); + if (dataPoints.isBz()) + Utils.drawLine(prevX, secondLineData.get(prevX) + 0.5f, xPos, secondLineData.get(xPos) + 0.5f, 2, graphColor2); + } + } + if (i == 1) + secondLineData.put(xPos, yPos); + if (mouseX >= guiLeft + 17 && mouseX <= guiLeft + 315 && mouseY >= guiTop + 35 && mouseY <= guiTop + 198) { + int dist = Math.abs(mouseX - xPos); + if (lowestDist == null || dist < lowestDist) { + lowestDist = dist; + lowestDistTime = time; + } + } + prevX = xPos; + prevY = yPos; + } + } + boolean showDays = lastTime - firstTime > 86400; + int prevNum = showDays ? Date.from(Instant.ofEpochSecond(firstTime)).getDate() : Date.from(Instant.ofEpochSecond(firstTime)).getHours(); + long prevXPos = -100; + for (long time = firstTime; time <= lastTime; time += showDays ? 3600 : 60) { + int num = showDays ? Date.from(Instant.ofEpochSecond(time)).getDate() : Date.from(Instant.ofEpochSecond(time)).getHours(); + if (num != prevNum) { + int xPos = (int) map(time, firstTime, lastTime, guiLeft + 17, guiLeft + 315); + if (Math.abs(prevXPos - xPos) > 30) { + Utils.drawStringCentered(String.valueOf(num), Minecraft.getMinecraft().fontRendererObj, + xPos, guiTop + 206, false, 0x8b8b8b); + prevXPos = xPos; + } + prevNum = num; + } + } + for (int i = 0; i <= 6; i++) { + long price = (long) map(i, 0, 6, highestValue, lowestValue); + String formattedPrice = formatPrice(price); + Utils.drawStringF(formattedPrice, Minecraft.getMinecraft().fontRendererObj, guiLeft + 320, + (float) map(i, 0, 6, guiTop + 35, guiTop + 198) + - Minecraft.getMinecraft().fontRendererObj.FONT_HEIGHT / 2f, + false, 0x8b8b8b); + } + if (customSelecting) { + Utils.drawDottedLine(customStart, guiTop + 36, customStart, guiTop + 197, 2, 10, 0xFFc6c6c6); + Utils.drawDottedLine(customEnd, guiTop + 36, customEnd, guiTop + 197, 2, 10, 0xFFc6c6c6); + Utils.drawDottedLine(customStart, guiTop + 36, customEnd, guiTop + 36, 2, 10, 0xFFc6c6c6); + Utils.drawDottedLine(customStart, guiTop + 197, customEnd, guiTop + 197, 2, 10, 0xFFc6c6c6); + } + if (lowestDist != null && !customSelecting) { + float price = dataPoints.isBz() ? dataPoints.bz.get(lowestDistTime).b : dataPoints.ah.get(lowestDistTime); + Float price2 = dataPoints.isBz() ? dataPoints.bz.get(lowestDistTime).s : null; + int xPos = (int) map(lowestDistTime, firstTime, lastTime, guiLeft + 17, guiLeft + 315); + int yPos = (int) map(price, highestValue + 10, lowestValue - 10, guiTop + 35, guiTop + 198); + int yPos2 = price2 != null ? (int) map(price2, highestValue + 10, lowestValue - 10, guiTop + 35, guiTop + 198) : 0; + + Utils.drawLine(xPos, guiTop + 35, xPos, guiTop + 198, 2, 0x4D8b8b8b); + Minecraft.getMinecraft().getTextureManager().bindTexture(TEXTURE); + GlStateManager.color(1, 1, 1, 1); + Utils.drawTexturedRect(xPos - 2.5f, yPos - 2.5f, 5, 5, + 0, 5 / 512f, 247 / 512f, 252 / 512f, GL11.GL_NEAREST); + if (price2 != null) { + Utils.drawTexturedRect(xPos - 2.5f, yPos2 - 2.5f, 5, 5, + 0, 5 / 512f, 247 / 512f, 252 / 512f, GL11.GL_NEAREST); + } + + Date date = Date.from(Instant.ofEpochSecond(lowestDistTime)); + SimpleDateFormat displayFormat = new SimpleDateFormat("'§b'd MMMMM yyyy '§eat§b' HH:mm"); + NumberFormat nf = NumberFormat.getInstance(); + ArrayList text = new ArrayList<>(); + text.add(displayFormat.format(date)); + if (dataPoints.isBz()) { + text.add(EnumChatFormatting.YELLOW + "" + EnumChatFormatting.BOLD + "Bazaar Insta-Buy: " + + EnumChatFormatting.GOLD + EnumChatFormatting.BOLD + nf.format(price)); + text.add(EnumChatFormatting.YELLOW + "" + EnumChatFormatting.BOLD + "Bazaar Insta-Sell: " + + EnumChatFormatting.GOLD + EnumChatFormatting.BOLD + nf.format(price2)); + } else { + text.add(EnumChatFormatting.YELLOW + "" + EnumChatFormatting.BOLD + "Lowest BIN: " + + EnumChatFormatting.GOLD + EnumChatFormatting.BOLD + nf.format(price)); + } + drawHoveringText(text, xPos, yPos); + } + } + + if (mouseY >= guiTop + 17 && mouseY <= guiTop + 35 && mouseX >= guiLeft + 244 && mouseX <= guiLeft + 316) { + int index = (mouseX - guiLeft - 245) / 18; + switch (index) { + case 0: + Gui.drawRect(guiLeft + 245, guiTop + 17, guiLeft + 261, guiTop + 33, 0x80ffffff); + drawHoveringText(Collections.singletonList("Show 1 Hour"), mouseX, mouseY); + break; + case 1: + Gui.drawRect(guiLeft + 263, guiTop + 17, guiLeft + 279, guiTop + 33, 0x80ffffff); + drawHoveringText(Collections.singletonList("Show 1 Day"), mouseX, mouseY); + break; + case 2: + Gui.drawRect(guiLeft + 281, guiTop + 17, guiLeft + 297, guiTop + 33, 0x80ffffff); + drawHoveringText(Collections.singletonList("Show 1 Week"), mouseX, mouseY); + break; + case 3: + Gui.drawRect(guiLeft + 299, guiTop + 17, guiLeft + 315, guiTop + 33, 0x80ffffff); + drawHoveringText(Collections.singletonList("Show All"), mouseX, mouseY); + break; + } + } + } + + @Override + protected void mouseClicked(int mouseX, int mouseY, int mouseButton) throws IOException { + super.mouseClicked(mouseX, mouseY, mouseButton); + if (mouseY >= guiTop + 17 && mouseY <= guiTop + 35 && mouseX >= guiLeft + 244 && mouseX <= guiLeft + 316) { + mode = (mouseX - guiLeft - 245) / 18; + loadData(); + } else if (mouseY >= guiTop + 35 && mouseY <= guiTop + 198 && mouseX >= guiLeft + 17 && mouseX <= guiLeft + 315) { + customSelecting = true; + customStart = mouseX; + customEnd = mouseX; + } + } + + @Override + protected void mouseReleased(int mouseX, int mouseY, int state) { + super.mouseReleased(mouseX, mouseY, state); + if (customSelecting) { + customSelecting = false; + customStart = (int) map(customStart, guiLeft + 17, guiLeft + 315, firstTime, lastTime); + customEnd = (int) map(mouseX, guiLeft + 17, guiLeft + 315, firstTime, lastTime); + if (customStart > customEnd) { + long temp = customStart; + customStart = customEnd; + customEnd = temp; + } + if (customEnd - customStart != 0) { + mode = 4; + loadData(); + } + } + } + + @Override + protected void mouseClickMove(int mouseX, int mouseY, int clickedMouseButton, long timeSinceLastClick) { + super.mouseClickMove(mouseX, mouseY, clickedMouseButton, timeSinceLastClick); + if (customSelecting) { + customEnd = mouseX < guiLeft + 18 ? guiLeft + 18 : Math.min(mouseX, guiLeft + 314); + } + } + + private void loadData() { + dataPoints = null; + loaded = false; + new Thread(() -> { + File dir = new File("config/notenoughupdates/prices"); + if (!dir.exists()) { + loaded = true; + return; + } + File[] files = dir.listFiles(); + Data data = new Data(); + if (files == null) return; + for (File file : files) { + if (!file.getName().endsWith(".gz")) continue; + HashMap data2 = load(file); + if (data2 == null || !data2.containsKey(itemId)) continue; + if (data2.get(itemId).isBz()) { + if (data.bz == null) data.bz = data2.get(itemId).bz; + else data.bz.putAll(data2.get(itemId).bz); + } else if (data.ah == null) data.ah = data2.get(itemId).ah; + else data.ah.putAll(data2.get(itemId).ah); + } + if (data.get() != null && !data.get().isEmpty()) { + if (mode < 3) + data = new Data(new TreeMap<>(data.get().entrySet().stream() + .filter(e -> e.getKey() > System.currentTimeMillis() / 1000 - (mode == 0 ? 3600 : mode == 1 ? 86400 : 604800)) + .collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue))), data.isBz()); + else if (mode == 4) + data = new Data(new TreeMap<>(data.get().entrySet().stream() + .filter(e -> e.getKey() >= customStart && e.getKey() <= customEnd) + .collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue))), data.isBz()); + if (data.get() == null || data.get().isEmpty()) { + loaded = true; + return; + } + dataPoints = trimData(data); + firstTime = dataPoints.get().firstKey(); + lastTime = dataPoints.get().lastKey(); + highestValue = 0; + lowestValue = null; + for (long key : dataPoints.get().keySet()) { + float value1 = dataPoints.isBz() ? dataPoints.bz.get(key).b : dataPoints.ah.get(key); + Float value2 = dataPoints.isBz() ? dataPoints.bz.get(key).s : null; + if (value1 > highestValue) { + highestValue = value1; + } + if (value2 != null && value2 > highestValue) { + highestValue = value2; + } + if (lowestValue == null || value1 < lowestValue) { + lowestValue = value1; + } + if (value2 != null && value2 < lowestValue) { + lowestValue = value2; + } + } + } + loaded = true; + }).start(); + } + + public static void addToCache(JsonObject items, boolean bazaar) { + if (!NotEnoughUpdates.INSTANCE.config.ahGraph.graphEnabled) return; + try { + File dir = new File("config/notenoughupdates/prices"); + if (!dir.exists() && !dir.mkdir()) return; + File[] files = dir.listFiles(); + if (files != null) + for (File file : files) { + if (!file.getName().endsWith(".gz")) continue; + if (file.lastModified() < System.currentTimeMillis() - NotEnoughUpdates.INSTANCE.config.ahGraph.dataRetention * 86400000L) + file.delete(); + } + Date date = new Date(); + Long epochSecond = date.toInstant().getEpochSecond(); + File file = new File(dir, "prices_" + format.format(date) + ".gz"); + HashMap prices = new HashMap<>(); + if (file.exists()) + prices = load(file); + if (prices == null) return; + for (Map.Entry item : items.entrySet()) { + if (prices.containsKey(item.getKey())) { + if (bazaar && item.getValue().getAsJsonObject().has("curr_buy") && item.getValue().getAsJsonObject().has("curr_sell")) + prices.get(item.getKey()).bz.put(epochSecond, new BzData(item.getValue().getAsJsonObject().get("curr_buy").getAsFloat(), + item.getValue().getAsJsonObject().get("curr_sell").getAsFloat())); + else if (!bazaar) + prices.get(item.getKey()).ah.put(epochSecond, item.getValue().getAsInt()); + } else { + TreeMap mapData = new TreeMap<>(); + if (bazaar && item.getValue().getAsJsonObject().has("curr_buy") && item.getValue().getAsJsonObject().has("curr_sell")) + mapData.put(epochSecond, new BzData(item.getValue().getAsJsonObject().get("curr_buy").getAsFloat(), + item.getValue().getAsJsonObject().get("curr_sell").getAsFloat())); + else if (!bazaar) + mapData.put(epochSecond, item.getValue().getAsLong()); + prices.put(item.getKey(), new Data(mapData, bazaar)); + } + } + //noinspection ResultOfMethodCallIgnored + file.createNewFile(); + try (BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(new GZIPOutputStream(new FileOutputStream(file)), StandardCharsets.UTF_8))) { + writer.write(GSON.toJson(prices)); + } + } catch (Exception e) { + e.printStackTrace(); + } + } + + private Data trimData(Data data) { + long first = data.get().firstKey(); + long last = data.get().lastKey(); + Data trimmed = new Data(); + if (data.isBz()) + trimmed.bz = new TreeMap<>(); + else + trimmed.ah = new TreeMap<>(); + int zones = NotEnoughUpdates.INSTANCE.config.ahGraph.graphZones; + Long[] dataArray = !data.isBz() ? data.ah.keySet().toArray(new Long[0]) : data.bz.keySet().toArray(new Long[0]); + int prev = 0; + for (int i = 0; i < zones; i++) { + long lowest = (long) map(i, 0, zones, first, last); + long highest = (long) map(i + 1, 0, zones, first, last); + int amount = 0; + double sumBuy = 0; + double sumSell = 0; + for (int l = prev; l < dataArray.length; l++) { + if (dataArray[l] >= lowest && dataArray[l] <= highest) { + amount++; + sumBuy += data.isBz() ? data.bz.get(dataArray[l]).b : data.ah.get(dataArray[l]); + if (data.isBz()) sumSell += data.bz.get(dataArray[l]).s; + prev = l + 1; + } else if (dataArray[l] > highest) + break; + } + if (amount > 0) { + if (data.isBz()) + trimmed.bz.put(lowest, new BzData((float) (sumBuy / amount), (float) (sumSell / amount))); + else + trimmed.ah.put(lowest, (int) (sumBuy / amount)); + } + } + return trimmed; + } + + + private static HashMap load(File file) { + Type type = new TypeToken>() { + }.getType(); + if (file.exists()) { + try (BufferedReader reader = new BufferedReader(new InputStreamReader(new GZIPInputStream(new FileInputStream(file)), StandardCharsets.UTF_8))) { + return GSON.fromJson(reader, type); + } catch (Exception ignored) { + } + } + return null; + } + + private static double map(double x, double in_min, double in_max, double out_min, double out_max) { + return (x - in_min) * (out_max - out_min) / (in_max - in_min) + out_min; + } + + private static String formatPrice(long price) { + DecimalFormat df = new DecimalFormat("#.00"); + if (price >= 1000000000) { + return df.format(price / 1000000000f) + "B"; + } else if (price >= 1000000) { + return df.format(price / 1000000f) + "M"; + } else if (price >= 1000) { + return df.format(price / 1000f) + "K"; + } + return String.valueOf(price); + } + + private int changeAlpha(int origColor, int alpha) { + origColor = origColor & 0x00ffffff; //drop the previous alpha value + return (alpha << 24) | origColor; //add the one the user inputted + } +} + +class Data { + public TreeMap ah = null; + public TreeMap bz = null; + + public Data() { + } + + public Data(TreeMap map, boolean bz) { + if (bz) + this.bz = (TreeMap) map; + else + this.ah = (TreeMap) map; + } + + public TreeMap get() { + return !isBz() ? ah : bz; + } + + public boolean isBz() { + return bz != null && !bz.isEmpty(); + } +} + +class BzData { + float b; + float s; + + public BzData(float b, float s) { + this.b = b; + this.s = s; + } +} diff --git a/src/main/java/io/github/moulberry/notenoughupdates/options/NEUConfig.java b/src/main/java/io/github/moulberry/notenoughupdates/options/NEUConfig.java index 31930e77..1cb06c52 100644 --- a/src/main/java/io/github/moulberry/notenoughupdates/options/NEUConfig.java +++ b/src/main/java/io/github/moulberry/notenoughupdates/options/NEUConfig.java @@ -271,6 +271,13 @@ public class NEUConfig extends Config { ) public AHTweaks ahTweaks = new AHTweaks(); + @Expose + @Category( + name = "AH/BZ Graph", + desc = "Graph of auction and bazaar prices" + ) + public AHGraph ahGraph = new AHGraph(); + @Expose @Category( name = "Accessory Bag Overlay", diff --git a/src/main/java/io/github/moulberry/notenoughupdates/options/seperateSections/AHGraph.java b/src/main/java/io/github/moulberry/notenoughupdates/options/seperateSections/AHGraph.java new file mode 100644 index 00000000..ce4c8f09 --- /dev/null +++ b/src/main/java/io/github/moulberry/notenoughupdates/options/seperateSections/AHGraph.java @@ -0,0 +1,83 @@ +package io.github.moulberry.notenoughupdates.options.seperateSections; + +import com.google.gson.annotations.Expose; +import io.github.moulberry.notenoughupdates.core.config.annotations.*; +import org.lwjgl.input.Keyboard; + +public class AHGraph { + @Expose + @ConfigOption( + name = "Enabled", + desc = "Enable or disable the graph. Disabling this will also make it so that no price data is stored." + ) + @ConfigEditorBoolean + public boolean graphEnabled = true; + + @Expose + @ConfigOption( + name = "Keybind", + desc = "Key to press to open the graph." + ) + @ConfigEditorKeybind(defaultKey = Keyboard.KEY_P) + public int graphKey = Keyboard.KEY_P; + + @Expose + @ConfigOption( + name = "GUI Style", + desc = "Change the style of the graph GUI" + ) + @ConfigEditorDropdown( + values = {"Minecraft", "Dark", "PacksHQ Dark", "FSR"} + ) + public int graphStyle = 0; + + @Expose + @ConfigOption( + name = "Graph Colour", + desc = "Set a custom colour for the graph." + ) + @ConfigEditorColour + public String graphColor = "0:255:0:255:0"; + + @Expose + @ConfigOption( + name = "Secondary Graph Colour", + desc = "Set a custom colour for the second graph line." + ) + @ConfigEditorColour + public String graphColor2 = "0:255:255:255:0"; + + @Expose + @ConfigOption( + name = "Default Time", + desc = "Change the default time period for the graph." + ) + @ConfigEditorDropdown( + values = {"1 Hour", "1 Day", "1 Week", "All Time"} + ) + public int defaultMode = 1; + + @Expose + @ConfigOption( + name = "Data Retention", + desc = "Change the time (in days) that data is kept for.\nLonger retention require more storage." + ) + @ConfigEditorSlider( + minValue = 1, + maxValue = 30, + minStep = 1 + ) + public int dataRetention = 7; + + @Expose + @ConfigOption( + name = "Number of Graph Zones", + desc = "Change the number of graph zones.\nHigher numbers will have more detail, but will look way more cramped." + ) + @ConfigEditorSlider( + minValue = 50, + maxValue = 300, + minStep = 1 + ) + public int graphZones = 175; +} diff --git a/src/main/java/io/github/moulberry/notenoughupdates/util/Utils.java b/src/main/java/io/github/moulberry/notenoughupdates/util/Utils.java index f34ba230..dc301db2 100644 --- a/src/main/java/io/github/moulberry/notenoughupdates/util/Utils.java +++ b/src/main/java/io/github/moulberry/notenoughupdates/util/Utils.java @@ -472,6 +472,7 @@ public class Utils { //EnumChatFormatting.AQUA+EnumChatFormatting.BOLD.toString()+"DIVINE", }; + public static final HashMap rarityArrMap = new HashMap() {{ put("COMMON", rarityArrC[0]); put("UNCOMMON", rarityArrC[1]); @@ -828,6 +829,16 @@ public class Utils { GlStateManager.scale(1 / factor, 1 / factor, 1); } + public static void drawStringScaledMax(String str, FontRenderer fr, float x, float y, boolean shadow, int colour, float factor, int len) { + int strLen = fr.getStringWidth(str); + float f = len / (float) strLen; + factor = Math.min(factor, f); + + GlStateManager.scale(factor, factor, 1); + fr.drawString(str, x / factor, y / factor, colour, shadow); + GlStateManager.scale(1 / factor, 1 / factor, 1); + } + public static void drawStringCenteredScaledMaxWidth(String str, FontRenderer fr, float x, float y, boolean shadow, int len, int colour) { int strLen = fr.getStringWidth(str); float factor = len / (float) strLen; @@ -1351,4 +1362,68 @@ public class Utils { return endsIn; } + + public static void drawLine(float sx, float sy, float ex, float ey, int width, int color) { + float f = (float) (color >> 24 & 255) / 255.0F; + float f1 = (float) (color >> 16 & 255) / 255.0F; + float f2 = (float) (color >> 8 & 255) / 255.0F; + float f3 = (float) (color & 255) / 255.0F; + GlStateManager.pushMatrix(); + GlStateManager.disableTexture2D(); + GlStateManager.enableBlend(); + GlStateManager.disableAlpha(); + GlStateManager.tryBlendFuncSeparate(770, 771, 1, 0); + GlStateManager.color(f1, f2, f3, f); + GL11.glLineWidth(width); + GL11.glBegin(GL11.GL_LINES); + GL11.glVertex2d(sx, sy); + GL11.glVertex2d(ex, ey); + GL11.glEnd(); + GlStateManager.disableBlend(); + GlStateManager.enableAlpha(); + GlStateManager.enableTexture2D(); + GlStateManager.popMatrix(); + } + + public static void drawDottedLine(float sx, float sy, float ex, float ey, int width, int factor , int color) { + GlStateManager.pushMatrix(); + GL11.glLineStipple(factor, (short) 0xAAAA); + GL11.glEnable(GL11.GL_LINE_STIPPLE); + drawLine(sx, sy, ex, ey, width, color); + GL11.glDisable(GL11.GL_LINE_STIPPLE); + GlStateManager.popMatrix(); + } + + public static void drawTexturedQuad(float x1, float y1, float x2, float y2, float x3, float y3, float x4, float y4, + float uMin, float uMax, float vMin, float vMax, int filter) { + GlStateManager.enableTexture2D(); + GlStateManager.enableBlend(); + GlStateManager.tryBlendFuncSeparate(GL11.GL_SRC_ALPHA, GL11.GL_ONE_MINUS_SRC_ALPHA, GL11.GL_ONE, GL11.GL_ONE_MINUS_SRC_ALPHA); + GL14.glBlendFuncSeparate(GL11.GL_SRC_ALPHA, GL11.GL_ONE_MINUS_SRC_ALPHA, GL11.GL_ONE, GL11.GL_ONE_MINUS_SRC_ALPHA); + + GL11.glTexParameteri(GL11.GL_TEXTURE_2D, GL11.GL_TEXTURE_MIN_FILTER, filter); + GL11.glTexParameteri(GL11.GL_TEXTURE_2D, GL11.GL_TEXTURE_MAG_FILTER, filter); + + Tessellator tessellator = Tessellator.getInstance(); + WorldRenderer worldrenderer = tessellator.getWorldRenderer(); + worldrenderer.begin(7, DefaultVertexFormats.POSITION_TEX); + worldrenderer + .pos(x1, y1, 0.0D) + .tex(uMin, vMax).endVertex(); + worldrenderer + .pos(x2, y2, 0.0D) + .tex(uMax, vMax).endVertex(); + worldrenderer + .pos(x3, y3, 0.0D) + .tex(uMax, vMin).endVertex(); + worldrenderer + .pos(x4, y4, 0.0D) + .tex(uMin, vMin).endVertex(); + tessellator.draw(); + + GL11.glTexParameteri(GL11.GL_TEXTURE_2D, GL11.GL_TEXTURE_MIN_FILTER, GL11.GL_NEAREST); + GL11.glTexParameteri(GL11.GL_TEXTURE_2D, GL11.GL_TEXTURE_MAG_FILTER, GL11.GL_NEAREST); + + GlStateManager.disableBlend(); + } } diff --git a/src/main/resources/assets/notenoughupdates/price_graph_gui/price_information_gui.png b/src/main/resources/assets/notenoughupdates/price_graph_gui/price_information_gui.png new file mode 100644 index 00000000..633be870 Binary files /dev/null and b/src/main/resources/assets/notenoughupdates/price_graph_gui/price_information_gui.png differ diff --git a/src/main/resources/assets/notenoughupdates/price_graph_gui/price_information_gui_dark.png b/src/main/resources/assets/notenoughupdates/price_graph_gui/price_information_gui_dark.png new file mode 100644 index 00000000..0f7743e6 Binary files /dev/null and b/src/main/resources/assets/notenoughupdates/price_graph_gui/price_information_gui_dark.png differ diff --git a/src/main/resources/assets/notenoughupdates/price_graph_gui/price_information_gui_fsr.png b/src/main/resources/assets/notenoughupdates/price_graph_gui/price_information_gui_fsr.png new file mode 100644 index 00000000..e98bdb7d Binary files /dev/null and b/src/main/resources/assets/notenoughupdates/price_graph_gui/price_information_gui_fsr.png differ diff --git a/src/main/resources/assets/notenoughupdates/price_graph_gui/price_information_gui_phqdark.png b/src/main/resources/assets/notenoughupdates/price_graph_gui/price_information_gui_phqdark.png new file mode 100644 index 00000000..f794319f Binary files /dev/null and b/src/main/resources/assets/notenoughupdates/price_graph_gui/price_information_gui_phqdark.png differ -- cgit From b0b0b7567ec0656c60f2f3e4730c0edace353fb7 Mon Sep 17 00:00:00 2001 From: Roman / Nea Date: Thu, 30 Dec 2021 14:37:02 +0100 Subject: Adding support for more recipe types and forge recipes (#40) * Foundations for support of different crafting recipe types. NeuRecipe is now a base class for a recipe which provides common concepts, such as inputs, outputs and a rendering task. GuiItemRecipe has been reworked to work with this new NeuRecipe. NeuManager now parses said recipes. This should be reworked to be a two step process (first register items, then register recipes). To keep compatibility with older repo versions, NeuRecipes are parse lenient and default to a crafting recipe. New recipes should be added in the `recipes` json field which is an array of json dictionaries, which have a `type` and other fields depending on the `type` of that recipe. This also adds support for having multiple recipes for a single item (e.g. uncrafting storage blocks). * Remove references in existing code * Recipe Generation * ring recipes * recipe generator v2 * quick forge * bugfixes and performance improvements * fix raw craft cost * reload hotm if you open the hotm tree inv * add myself to the changelog * replace quickforge formular with lookup table * do not crash anymore when opening recipes outside of skyblock * format coins differently * remove debug logs * change recipe generator so that it doesnt crash old versions --- Update Notes/2.1.md | 2 + .../notenoughupdates/ItemPriceInformation.java | 4 +- .../moulberry/notenoughupdates/NEUManager.java | 212 +++++++---------- .../notenoughupdates/NotEnoughUpdates.java | 2 + .../notenoughupdates/auction/APIManager.java | 138 ++++++----- .../notenoughupdates/commands/Commands.java | 2 +- .../notenoughupdates/miscgui/GuiItemRecipe.java | 257 +++++++++------------ .../notenoughupdates/overlays/CraftingOverlay.java | 44 ++-- .../notenoughupdates/recipes/CraftingRecipe.java | 141 +++++++++++ .../notenoughupdates/recipes/ForgeRecipe.java | 220 ++++++++++++++++++ .../notenoughupdates/recipes/Ingredient.java | 88 +++++++ .../notenoughupdates/recipes/NeuRecipe.java | 39 ++++ .../notenoughupdates/recipes/RecipeGenerator.java | 180 +++++++++++++++ .../notenoughupdates/recipes/RecipeSlot.java | 28 +++ .../moulberry/notenoughupdates/util/Debouncer.java | 34 +++ .../notenoughupdates/util/HotmInformation.java | 179 ++++++++++++++ .../notenoughupdates/util/HypixelApi.java | 36 ++- .../moulberry/notenoughupdates/util/Utils.java | 38 ++- .../notenoughupdates/textures/gui/forge_recipe.png | Bin 0 -> 889 bytes 19 files changed, 1263 insertions(+), 381 deletions(-) create mode 100644 src/main/java/io/github/moulberry/notenoughupdates/recipes/CraftingRecipe.java create mode 100644 src/main/java/io/github/moulberry/notenoughupdates/recipes/ForgeRecipe.java create mode 100644 src/main/java/io/github/moulberry/notenoughupdates/recipes/Ingredient.java create mode 100644 src/main/java/io/github/moulberry/notenoughupdates/recipes/NeuRecipe.java create mode 100644 src/main/java/io/github/moulberry/notenoughupdates/recipes/RecipeGenerator.java create mode 100644 src/main/java/io/github/moulberry/notenoughupdates/recipes/RecipeSlot.java create mode 100644 src/main/java/io/github/moulberry/notenoughupdates/util/Debouncer.java create mode 100644 src/main/java/io/github/moulberry/notenoughupdates/util/HotmInformation.java create mode 100644 src/main/resources/assets/notenoughupdates/textures/gui/forge_recipe.png (limited to 'src/main/resources/assets') diff --git a/Update Notes/2.1.md b/Update Notes/2.1.md index 325ed5ae..6c5fb48b 100644 --- a/Update Notes/2.1.md +++ b/Update Notes/2.1.md @@ -11,6 +11,7 @@ - [Donpireso replied to an sba dev's email about some of sba features and it seems to imply that blocking clicks in guis arent bannable](https://cdn.discordapp.com/attachments/823769568933576764/906101631861526559/unknown.png) - Fixed pet overlay not updating when going into /pets ### **Minor Changes:** +- Add built-in recipes for forge crafts - nea89 - Make cata xp in /pv be calculated on how many runs you have and shows master mode xp rates - Hide mine waypoints when at location setting - Lulonaut - Added some info panels to some settings in /neu @@ -42,6 +43,7 @@ - Added a warning in the tooltip when price info couldn't be found/is outdated - Lulonaut - Added custom runes and crab hat system - jani ### **Bug Fixes** +- Fix wiki pages freezing the entire game - nea89 - Made titanium overlay and waypoints work with dwarven overlay off - "fixed" divan rarity in NEUAH (scuffed) - Made etherwarp block overlay config option diff --git a/src/main/java/io/github/moulberry/notenoughupdates/ItemPriceInformation.java b/src/main/java/io/github/moulberry/notenoughupdates/ItemPriceInformation.java index 5c26e3d6..e78c117b 100644 --- a/src/main/java/io/github/moulberry/notenoughupdates/ItemPriceInformation.java +++ b/src/main/java/io/github/moulberry/notenoughupdates/ItemPriceInformation.java @@ -152,7 +152,7 @@ public class ItemPriceInformation { } break; case 4: - if (craftCost.fromRecipe) { + if (craftCost != null && craftCost.fromRecipe) { if ((int) craftCost.craftCost == 0) { continue; } @@ -224,7 +224,7 @@ public class ItemPriceInformation { } break; case 3: - if (craftCost.fromRecipe) { + if (craftCost != null && craftCost.fromRecipe) { if ((int) craftCost.craftCost == 0) { continue; } diff --git a/src/main/java/io/github/moulberry/notenoughupdates/NEUManager.java b/src/main/java/io/github/moulberry/notenoughupdates/NEUManager.java index 0f4e58bf..064b1fa7 100644 --- a/src/main/java/io/github/moulberry/notenoughupdates/NEUManager.java +++ b/src/main/java/io/github/moulberry/notenoughupdates/NEUManager.java @@ -1,14 +1,13 @@ package io.github.moulberry.notenoughupdates; -import com.google.common.collect.Lists; import com.google.gson.*; import io.github.moulberry.notenoughupdates.auction.APIManager; import io.github.moulberry.notenoughupdates.miscgui.GuiItemRecipe; import io.github.moulberry.notenoughupdates.overlays.CraftingOverlay; -import io.github.moulberry.notenoughupdates.util.Constants; -import io.github.moulberry.notenoughupdates.util.HypixelApi; -import io.github.moulberry.notenoughupdates.util.SBInfo; -import io.github.moulberry.notenoughupdates.util.Utils; +import io.github.moulberry.notenoughupdates.recipes.CraftingRecipe; +import io.github.moulberry.notenoughupdates.recipes.Ingredient; +import io.github.moulberry.notenoughupdates.recipes.NeuRecipe; +import io.github.moulberry.notenoughupdates.util.*; import net.minecraft.client.Minecraft; import net.minecraft.client.settings.KeyBinding; import net.minecraft.init.Blocks; @@ -17,8 +16,8 @@ import net.minecraft.inventory.ContainerChest; import net.minecraft.item.Item; import net.minecraft.item.ItemStack; import net.minecraft.nbt.*; -import net.minecraft.network.play.client.C0DPacketCloseWindow; import net.minecraft.util.ResourceLocation; +import net.minecraftforge.fml.common.ProgressManager; import org.apache.commons.io.FileUtils; import org.lwjgl.input.Keyboard; import org.lwjgl.opengl.Display; @@ -68,18 +67,26 @@ public class NEUManager { private static String GIT_COMMITS_URL; - private final HashMap> usagesMap = new HashMap<>(); + // TODO: private final Map + + private final Set recipes = new HashSet<>(); + private final HashMap> recipesMap = new HashMap<>(); + private final HashMap> usagesMap = new HashMap<>(); public String latestRepoCommit = null; public File configLocation; public File repoLocation; public File configFile; + public HotmInformation hotm; public NEUManager(NotEnoughUpdates neu, File configLocation) { this.neu = neu; this.configLocation = configLocation; this.auctionManager = new APIManager(this); + this.hotm = new HotmInformation(neu); + + GIT_COMMITS_URL = neu.config.hidden.repoCommitsURL; gson = new GsonBuilder().setPrettyPrinting().create(); @@ -261,14 +268,17 @@ public class NEUManager { if (items.exists()) { File[] itemFiles = new File(repoLocation, "items").listFiles(); if (itemFiles != null) { + ProgressManager.ProgressBar bar = ProgressManager.push("Loading recipes", itemFiles.length); for (File f : itemFiles) { String internalname = f.getName().substring(0, f.getName().length() - 5); + bar.step(internalname); synchronized (itemMap) { if (!itemMap.containsKey(internalname)) { loadItem(internalname); } } } + ProgressManager.pop(bar); } } @@ -283,14 +293,17 @@ public class NEUManager { if (items.exists()) { File[] itemFiles = new File(repoLocation, "items").listFiles(); if (itemFiles != null) { + ProgressManager.ProgressBar bar = ProgressManager.push("Loading items", itemFiles.length); for (File f : itemFiles) { String internalname = f.getName().substring(0, f.getName().length() - 5); + bar.step(internalname); synchronized (itemMap) { if (!itemMap.containsKey(internalname)) { loadItem(internalname); } } } + ProgressManager.pop(bar); } } @@ -325,23 +338,17 @@ public class NEUManager { itemMap.put(internalName, json); if (json.has("recipe")) { - synchronized (usagesMap) { - JsonObject recipe = json.get("recipe").getAsJsonObject(); - - String[] x = {"1", "2", "3"}; - String[] y = {"A", "B", "C"}; - for (int i = 0; i < 9; i++) { - String name = y[i / 3] + x[i % 3]; - String itemS = recipe.get(name).getAsString(); - if (itemS != null && itemS.split(":").length == 2) { - itemS = itemS.split(":")[0]; - } - - if (!usagesMap.containsKey(itemS)) { - usagesMap.put(itemS, new HashSet<>()); - } - usagesMap.get(itemS).add(internalName); - } + JsonObject recipe = json.getAsJsonObject("recipe"); + NeuRecipe neuRecipe = NeuRecipe.parseRecipe(this, recipe, json); + if (neuRecipe != null) + registerNeuRecipe(neuRecipe); + } + if (json.has("recipes")) { + for (JsonElement element : json.getAsJsonArray("recipes")) { + JsonObject recipe = element.getAsJsonObject(); + NeuRecipe neuRecipe = NeuRecipe.parseRecipe(this, recipe, json); + if (neuRecipe != null) + registerNeuRecipe(neuRecipe); } } @@ -392,6 +399,24 @@ public class NEUManager { } } + public void registerNeuRecipe(NeuRecipe recipe) { + recipes.add(recipe); + for (Ingredient output : recipe.getOutputs()) { + recipesMap.computeIfAbsent(output.getInternalItemId(), ignored -> new HashSet<>()).add(recipe); + } + for (Ingredient input : recipe.getIngredients()) { + usagesMap.computeIfAbsent(input.getInternalItemId(), ignored -> new HashSet<>()).add(recipe); + } + } + + public Set getRecipesFor(String internalName) { + return recipesMap.getOrDefault(internalName, Collections.emptySet()); + } + + public Set getUsagesFor(String internalName) { + return usagesMap.getOrDefault(internalName, Collections.emptySet()); + } + /** * Searches a string for a query. This method is used to mimic the behaviour of the * more complex map-based search function. This method is used for the chest-item-search feature. @@ -820,27 +845,25 @@ public class NEUManager { ContainerChest container = null; if (Minecraft.getMinecraft().thePlayer.openContainer instanceof ContainerChest) container = (ContainerChest) Minecraft.getMinecraft().thePlayer.openContainer; - if (item.has("recipe") && container != null && container.getLowerChestInventory().getDisplayName().getUnformattedText().equals("Craft Item")) { - CraftingOverlay.updateItem(item); - } else if (item.has("useneucraft") && item.get("useneucraft").getAsBoolean()) { - displayGuiItemRecipe(item.get("internalname").getAsString(), ""); - } else if (item.has("clickcommand")) { - String clickcommand = item.get("clickcommand").getAsString(); - - if (clickcommand.equals("viewrecipe")) { - neu.sendChatMessage( - "/" + clickcommand + " " + - item.get("internalname").getAsString().split(";")[0]); - viewItemAttemptID = item.get("internalname").getAsString(); - viewItemAttemptTime = System.currentTimeMillis(); - } else if (clickcommand.equals("viewpotion")) { - neu.sendChatMessage( - "/" + clickcommand + " " + - item.get("internalname").getAsString().split(";")[0].toLowerCase()); - viewItemAttemptID = item.get("internalname").getAsString(); - viewItemAttemptTime = System.currentTimeMillis(); + String internalName = item.get("internalname").getAsString(); + Set recipesFor = getRecipesFor(internalName); + if (container != null && container.getLowerChestInventory().getDisplayName().getUnformattedText().equals("Craft Item")) { + Optional recipe = recipesFor.stream().filter(it -> it instanceof CraftingRecipe).findAny(); + if (recipe.isPresent()) { + CraftingOverlay.updateItem((CraftingRecipe) recipe.get()); + return; } } + if (!item.has("clickcommand")) return; + String clickcommand = item.get("clickcommand").getAsString(); + switch (clickcommand.intern()) { + case "viewrecipe": + displayGuiItemRecipe(internalName, null); + break; + case "viewoption": + neu.sendChatMessage("/viewpotion " + internalName.split(";")[0].toLowerCase(Locale.ROOT)); + } + displayGuiItemRecipe(internalName, ""); } /** @@ -920,90 +943,24 @@ public class NEUManager { loadItem(internalname); } - /** - * Constructs a GuiItemUsages from the recipe usage data (see #usagesMap) of a given item - */ public boolean displayGuiItemUsages(String internalName) { - List craftMatrices = new ArrayList<>(); - List results = new ArrayList<>(); - - if (!usagesMap.containsKey(internalName)) { - return false; - } - - for (String internalNameResult : usagesMap.get(internalName)) { - JsonObject item = getItemInformation().get(internalNameResult); - results.add(item); - - if (item != null && item.has("recipe")) { - JsonObject recipe = item.get("recipe").getAsJsonObject(); - - ItemStack[] craftMatrix = new ItemStack[9]; - - String[] x = {"1", "2", "3"}; - String[] y = {"A", "B", "C"}; - for (int i = 0; i < 9; i++) { - String name = y[i / 3] + x[i % 3]; - String itemS = recipe.get(name).getAsString(); - int count = 1; - if (itemS != null && itemS.split(":").length == 2) { - count = Integer.parseInt(itemS.split(":")[1]); - itemS = itemS.split(":")[0]; - } - JsonObject craft = getItemInformation().get(itemS); - if (craft != null) { - ItemStack stack = jsonToStack(craft); - stack.stackSize = count; - craftMatrix[i] = stack; - } - } - - craftMatrices.add(craftMatrix); - } - } - - if (craftMatrices.size() > 0) { - Minecraft.getMinecraft().displayGuiScreen(new GuiItemRecipe("Item Usages", craftMatrices, results, this)); - return true; - } - return false; + if (!usagesMap.containsKey(internalName)) return false; + Set usages = usagesMap.get(internalName); + if (usages.isEmpty()) return false; + Utils.sendCloseScreenPacket(); + Minecraft.getMinecraft().displayGuiScreen( + new GuiItemRecipe("Item Usages", new ArrayList<>(usages), this)); + return true; } - /** - * Constructs a GuiItemRecipeOld from the recipe data of a given item. - */ public boolean displayGuiItemRecipe(String internalName, String text) { - JsonObject item = getItemInformation().get(internalName); - if (item != null && item.has("recipe")) { - JsonObject recipe = item.get("recipe").getAsJsonObject(); - - ItemStack[] craftMatrix = new ItemStack[9]; - - String[] x = {"1", "2", "3"}; - String[] y = {"A", "B", "C"}; - for (int i = 0; i < 9; i++) { - String name = y[i / 3] + x[i % 3]; - String itemS = recipe.get(name).getAsString(); - int count = 1; - if (itemS != null && itemS.split(":").length == 2) { - count = Integer.parseInt(itemS.split(":")[1]); - itemS = itemS.split(":")[0]; - } - JsonObject craft = getItemInformation().get(itemS); - if (craft != null) { - ItemStack stack = jsonToStack(craft); - stack.stackSize = count; - craftMatrix[i] = stack; - } - } - - Minecraft.getMinecraft().thePlayer.sendQueue.addToSendQueue(new C0DPacketCloseWindow( - Minecraft.getMinecraft().thePlayer.openContainer.windowId)); - Minecraft.getMinecraft().displayGuiScreen(new GuiItemRecipe(text != null ? text : "Item Recipe", - Lists.newArrayList(craftMatrix), Lists.newArrayList(item), this)); - return true; - } - return false; + if (!recipesMap.containsKey(internalName)) return false; + Set recipes = recipesMap.get(internalName); + if (recipes.isEmpty()) return false; + Utils.sendCloseScreenPacket(); + Minecraft.getMinecraft().displayGuiScreen( + new GuiItemRecipe(text != null ? text : "Item Recipe", new ArrayList<>(recipes), this)); + return true; } /** @@ -1207,6 +1164,15 @@ public class NEUManager { writeJson(json, file); } + public JsonObject readJsonDefaultDir(String filename) throws IOException { + File f = new File(new File(repoLocation, "items"), filename); + if (f.exists() && f.isFile() && f.canRead()) + try (Reader reader = new InputStreamReader(new FileInputStream(f), StandardCharsets.UTF_8)) { + return gson.fromJson(reader, JsonObject.class); + } // rethrow io exceptions + return null; + } + public TreeMap getItemInformation() { return itemMap; } diff --git a/src/main/java/io/github/moulberry/notenoughupdates/NotEnoughUpdates.java b/src/main/java/io/github/moulberry/notenoughupdates/NotEnoughUpdates.java index 23b89b44..3a6afef8 100644 --- a/src/main/java/io/github/moulberry/notenoughupdates/NotEnoughUpdates.java +++ b/src/main/java/io/github/moulberry/notenoughupdates/NotEnoughUpdates.java @@ -15,6 +15,7 @@ import io.github.moulberry.notenoughupdates.options.NEUConfig; import io.github.moulberry.notenoughupdates.overlays.FuelBar; import io.github.moulberry.notenoughupdates.overlays.OverlayManager; import io.github.moulberry.notenoughupdates.profileviewer.ProfileViewer; +import io.github.moulberry.notenoughupdates.recipes.RecipeGenerator; import io.github.moulberry.notenoughupdates.util.SBInfo; import io.github.moulberry.notenoughupdates.util.Utils; import io.github.moulberry.notenoughupdates.util.XPInformation; @@ -131,6 +132,7 @@ public class NotEnoughUpdates { MinecraftForge.EVENT_BUS.register(this); MinecraftForge.EVENT_BUS.register(new NEUEventListener(this)); + MinecraftForge.EVENT_BUS.register(new RecipeGenerator(this)); MinecraftForge.EVENT_BUS.register(CapeManager.getInstance()); //MinecraftForge.EVENT_BUS.register(new SBGamemodes()); MinecraftForge.EVENT_BUS.register(new EnchantingSolvers()); diff --git a/src/main/java/io/github/moulberry/notenoughupdates/auction/APIManager.java b/src/main/java/io/github/moulberry/notenoughupdates/auction/APIManager.java index 254ab5cf..d0b4a7f5 100644 --- a/src/main/java/io/github/moulberry/notenoughupdates/auction/APIManager.java +++ b/src/main/java/io/github/moulberry/notenoughupdates/auction/APIManager.java @@ -7,6 +7,8 @@ import io.github.moulberry.notenoughupdates.ItemPriceInformation; import io.github.moulberry.notenoughupdates.NEUManager; import io.github.moulberry.notenoughupdates.NotEnoughUpdates; import io.github.moulberry.notenoughupdates.miscgui.GuiPriceGraph; +import io.github.moulberry.notenoughupdates.recipes.Ingredient; +import io.github.moulberry.notenoughupdates.recipes.NeuRecipe; import io.github.moulberry.notenoughupdates.util.Constants; import io.github.moulberry.notenoughupdates.util.Utils; import net.minecraft.client.Minecraft; @@ -760,87 +762,77 @@ public class APIManager { } public CraftInfo getCraftCost(String internalname) { - return getCraftCost(internalname, 0); + return getCraftCost(internalname, new HashSet<>()); } /** * Recursively calculates the cost of crafting an item from raw materials. */ - public CraftInfo getCraftCost(String internalname, int depth) { - if (craftCost.containsKey(internalname)) { - return craftCost.get(internalname); - } else { - CraftInfo ci = new CraftInfo(); - - ci.vanillaItem = isVanillaItem(internalname); - - JsonObject auctionInfo = getItemAuctionInfo(internalname); - float lowestBin = getLowestBin(internalname); - JsonObject bazaarInfo = getBazaarInfo(internalname); - - if (bazaarInfo != null && bazaarInfo.get("curr_buy") != null) { - float bazaarInstantBuyPrice = bazaarInfo.get("curr_buy").getAsFloat(); - ci.craftCost = bazaarInstantBuyPrice; - } - //Don't use auction prices for vanilla items cuz people like to transfer money, messing up the cost of vanilla items. - if (lowestBin > 0 && !ci.vanillaItem) { - if (ci.craftCost < 0 || lowestBin < ci.craftCost) { - ci.craftCost = lowestBin; - } - } else if (auctionInfo != null && !ci.vanillaItem) { - float auctionPrice = auctionInfo.get("price").getAsFloat() / auctionInfo.get("count").getAsFloat(); - if (ci.craftCost < 0 || auctionPrice < ci.craftCost) { - ci.craftCost = auctionPrice; - } - } - - if (depth > 16) { - craftCost.put(internalname, ci); - return ci; - } - - JsonObject item = manager.getItemInformation().get(internalname); - if (item != null && item.has("recipe")) { - float craftPrice = 0; - JsonObject recipe = item.get("recipe").getAsJsonObject(); - - String[] x = {"1", "2", "3"}; - String[] y = {"A", "B", "C"}; - for (int i = 0; i < 9; i++) { - String name = y[i / 3] + x[i % 3]; - String itemS = recipe.get(name).getAsString(); - if (itemS == null || itemS.length() == 0) continue; - - int count = 1; - if (itemS.split(":").length == 2) { - count = Integer.parseInt(itemS.split(":")[1]); - itemS = itemS.split(":")[0]; - } - if (itemS.equals(internalname)) { //if item is used a crafting component in its own recipe, return - craftCost.put(internalname, ci); - return ci; - } - - float compCost = getCraftCost(itemS, depth + 1).craftCost * count; - if (compCost < 0) { - //If it's a custom item without a cost, return - if (!getCraftCost(itemS).vanillaItem) { - craftCost.put(internalname, ci); - return ci; + private CraftInfo getCraftCost(String internalname, Set visited) { + if (craftCost.containsKey(internalname)) return craftCost.get(internalname); + if (visited.contains(internalname)) return null; + visited.add(internalname); + + + boolean vanillaItem = isVanillaItem(internalname); + float craftCost = Float.POSITIVE_INFINITY; + + JsonObject auctionInfo = getItemAuctionInfo(internalname); + float lowestBin = getLowestBin(internalname); + JsonObject bazaarInfo = getBazaarInfo(internalname); + + if (bazaarInfo != null && bazaarInfo.get("curr_buy") != null) { + craftCost = bazaarInfo.get("curr_buy").getAsFloat(); + } + //Don't use auction prices for vanilla items cuz people like to transfer money, messing up the cost of vanilla items. + if (!vanillaItem) { + if (lowestBin > 0) { + craftCost = Math.min(lowestBin, craftCost); + } else if (auctionInfo != null) { + float auctionPrice = auctionInfo.get("price").getAsFloat() / auctionInfo.get("count").getAsInt(); + craftCost = Math.min(auctionPrice, craftCost); + } + } + + Set recipes = manager.getRecipesFor(internalname); + boolean fromRecipe = false; + if (recipes != null) + RECIPE_ITER: + for (NeuRecipe recipe : recipes) { + float craftPrice = 0; + for (Ingredient i : recipe.getIngredients()) { + if (i.isCoins()) { + craftPrice += i.getCount(); + continue; + } + CraftInfo ingredientCraftCost = getCraftCost(i.getInternalItemId(), visited); + if (ingredientCraftCost == null) + continue RECIPE_ITER; // Skip recipes with items further up the chain + craftPrice += ingredientCraftCost.craftCost * i.getCount(); + } + int resultCount = 0; + for (Ingredient item : recipe.getOutputs()) + if (item.getInternalItemId().equals(internalname)) + resultCount += item.getCount(); + + if (resultCount == 0) + continue; + float craftPricePer = craftPrice / resultCount; + if (craftPricePer < craftCost) { + fromRecipe = true; + craftCost = craftPricePer; } - } else { - craftPrice += compCost; } - } - - if (ci.craftCost < 0 || craftPrice < ci.craftCost) { - ci.craftCost = craftPrice; - ci.fromRecipe = true; - } - } - craftCost.put(internalname, ci); - return ci; + visited.remove(internalname); + if (Float.isInfinite(craftCost)) { + return null; } + CraftInfo craftInfo = new CraftInfo(); + craftInfo.vanillaItem = vanillaItem; + craftInfo.craftCost = craftCost; + craftInfo.fromRecipe = fromRecipe; + this.craftCost.put(internalname, craftInfo); + return craftInfo; } /** diff --git a/src/main/java/io/github/moulberry/notenoughupdates/commands/Commands.java b/src/main/java/io/github/moulberry/notenoughupdates/commands/Commands.java index 910870d5..0e58a6bc 100644 --- a/src/main/java/io/github/moulberry/notenoughupdates/commands/Commands.java +++ b/src/main/java/io/github/moulberry/notenoughupdates/commands/Commands.java @@ -715,7 +715,7 @@ public class Commands { "Ok, this is actually the last message, use the command again and you'll crash I promise"}; private int devFailIndex = 0; - private static final List devTestUsers = new ArrayList<>(Arrays.asList("moulberry", "lucycoconut", "ironm00n", "ariyio", "throwpo", "dediamondpro")); + private static final List devTestUsers = new ArrayList<>(Arrays.asList("moulberry", "lucycoconut", "ironm00n", "ariyio", "throwpo", "lrg89", "dediamondpro")); SimpleCommand devTestCommand = new SimpleCommand("neudevtest", new SimpleCommand.ProcessCommandRunnable() { @Override public void processCommand(ICommandSender sender, String[] args) { diff --git a/src/main/java/io/github/moulberry/notenoughupdates/miscgui/GuiItemRecipe.java b/src/main/java/io/github/moulberry/notenoughupdates/miscgui/GuiItemRecipe.java index 210e1da7..e820378b 100644 --- a/src/main/java/io/github/moulberry/notenoughupdates/miscgui/GuiItemRecipe.java +++ b/src/main/java/io/github/moulberry/notenoughupdates/miscgui/GuiItemRecipe.java @@ -1,33 +1,51 @@ package io.github.moulberry.notenoughupdates.miscgui; -import com.google.gson.JsonObject; +import com.google.common.collect.ImmutableList; import io.github.moulberry.notenoughupdates.NEUManager; +import io.github.moulberry.notenoughupdates.recipes.NeuRecipe; +import io.github.moulberry.notenoughupdates.recipes.RecipeSlot; import io.github.moulberry.notenoughupdates.util.Utils; import net.minecraft.client.Minecraft; import net.minecraft.client.gui.FontRenderer; import net.minecraft.client.gui.GuiScreen; import net.minecraft.client.gui.ScaledResolution; import net.minecraft.client.renderer.GlStateManager; +import net.minecraft.entity.player.InventoryPlayer; import net.minecraft.item.ItemStack; +import net.minecraft.util.MathHelper; import net.minecraft.util.ResourceLocation; import org.lwjgl.input.Keyboard; import org.lwjgl.input.Mouse; import org.lwjgl.opengl.GL11; -import org.lwjgl.util.vector.Vector2f; import java.awt.*; import java.io.IOException; +import java.util.ArrayList; import java.util.List; public class GuiItemRecipe extends GuiScreen { - private static final ResourceLocation resourcePacksTexture = new ResourceLocation("textures/gui/resource_packs.png"); - private static final ResourceLocation craftingTableGuiTextures = new ResourceLocation("textures/gui/container/crafting_table.png"); + public static final ResourceLocation resourcePacksTexture = new ResourceLocation("textures/gui/resource_packs.png"); + + public static final int SLOT_SIZE = 16; + public static final int SLOT_SPACING = SLOT_SIZE + 2; + public static final int BUTTON_WIDTH = 7; + public static final int BUTTON_HEIGHT = 11; + public static final int BUTTON_POSITION_Y = 63; + public static final int BUTTON_POSITION_LEFT_X = 110; + public static final int BUTTON_POSITION_RIGHT_X = 147; + public static final int PAGE_STRING_X = 132; + public static final int PAGE_STRING_Y = 69; + public static final int TITLE_X = 28; + public static final int TITLE_Y = 6; + public static final int HOTBAR_SLOT_X = 8; + public static final int HOTBAR_SLOT_Y = 142; + public static final int PLAYER_INVENTORY_X = 8; + public static final int PLAYER_INVENTORY_Y = 84; - private final List craftMatrices; - private final List results; private int currentIndex = 0; private final String title; + private final List craftingRecipes; private final NEUManager manager; public int guiLeft = 0; @@ -35,159 +53,122 @@ public class GuiItemRecipe extends GuiScreen { public int xSize = 176; public int ySize = 166; - public GuiItemRecipe(String title, List craftMatrices, List results, NEUManager manager) { - this.craftMatrices = craftMatrices; - this.results = results; + public GuiItemRecipe(String title, List craftingRecipes, NEUManager manager) { + this.craftingRecipes = craftingRecipes; this.manager = manager; this.title = title; } - private String getCraftText() { - if(results.get(currentIndex).has("crafttext")) { - return results.get(currentIndex).get("crafttext").getAsString(); - } else { - return ""; - } + public NeuRecipe getCurrentRecipe() { + currentIndex = MathHelper.clamp_int(currentIndex, 0, craftingRecipes.size()); + return craftingRecipes.get(currentIndex); + } + + public boolean isWithinRect(int x, int y, int topLeftX, int topLeftY, int width, int height) { + return topLeftX <= x && x <= topLeftX + width + && topLeftY <= y && y <= topLeftY + height; + } + + private ImmutableList getAllRenderedSlots() { + return ImmutableList.builder() + .addAll(getPlayerInventory()) + .addAll(getCurrentRecipe().getSlots()).build(); } @Override public void drawScreen(int mouseX, int mouseY, float partialTicks) { drawDefaultBackground(); - - if(currentIndex < 0) { - currentIndex = 0; - } else if(currentIndex >= craftMatrices.size()) { - currentIndex = craftMatrices.size()-1; - } - FontRenderer fontRendererObj = Minecraft.getMinecraft().fontRendererObj; this.guiLeft = (width - this.xSize) / 2; this.guiTop = (height - this.ySize) / 2; GlStateManager.color(1.0F, 1.0F, 1.0F, 1.0F); - Minecraft.getMinecraft().getTextureManager().bindTexture(craftingTableGuiTextures); + + NeuRecipe currentRecipe = getCurrentRecipe(); + + Minecraft.getMinecraft().getTextureManager().bindTexture(currentRecipe.getBackground()); this.drawTexturedModalRect(guiLeft, guiTop, 0, 0, this.xSize, this.ySize); - List tooltipToRender = null; - for(int index=0; index <= 45; index++) { - Vector2f pos = getPositionForIndex(index); - Utils.drawItemStack(getStackForIndex(index), (int)pos.x, (int)pos.y); - - if(mouseX > pos.x && mouseX < pos.x+16) { - if(mouseY > pos.y && mouseY < pos.y+16) { - ItemStack stack = getStackForIndex(index); - if(stack != null) { - tooltipToRender = stack.getTooltip(Minecraft.getMinecraft().thePlayer, false); - } - } - } + currentRecipe.drawExtraBackground(this); + + List slots = getAllRenderedSlots(); + for (RecipeSlot slot : slots) { + Utils.drawItemStack(slot.getItemStack(), slot.getX(this), slot.getY(this)); } - if(craftMatrices.size() > 1) { - int guiX = mouseX - guiLeft; - int guiY = mouseY - guiTop; + if (craftingRecipes.size() > 1) drawArrows(mouseX, mouseY); - int buttonWidth = 7; - int buttonHeight = 11; + Utils.drawStringScaledMaxWidth(title, fontRendererObj, guiLeft + TITLE_X, guiTop + TITLE_Y, false, xSize - 38, 0x404040); - boolean leftSelected = false; - boolean rightSelected = false; + currentRecipe.drawExtraInfo(this); - if(guiY > + 63 && guiY < + 63 + buttonHeight) { - if(guiX > + 110 && guiX < 110 + buttonWidth) { - leftSelected = true; - } else if(guiX > 147 && guiX < 147 + buttonWidth) { - rightSelected = true; - } + for (RecipeSlot slot : slots) { + if (isWithinRect(mouseX, mouseY, slot.getX(this), slot.getY(this), SLOT_SIZE, SLOT_SIZE)) { + if (slot.getItemStack() == null) continue; + Utils.drawHoveringText(slot.getItemStack().getTooltip(Minecraft.getMinecraft().thePlayer, false), mouseX, mouseY, width, height, -1, fontRendererObj); } - - Minecraft.getMinecraft().getTextureManager().bindTexture(resourcePacksTexture); - //Left arrow - Utils.drawTexturedRect(guiLeft+110, guiTop+63, 7, 11, 34/256f, 48/256f, - 5/256f + (leftSelected ? 32/256f : 0), 27/256f + (leftSelected ? 32/256f : 0)); - //Right arrow - Utils.drawTexturedRect(guiLeft+147, guiTop+63, 7, 11, 10/256f, 24/256f, - 5/256f + (rightSelected ? 32/256f : 0), 27/256f + (rightSelected ? 32/256f : 0)); - GL11.glBindTexture(GL11.GL_TEXTURE_2D, 0); - - String str = (currentIndex+1)+"/"+craftMatrices.size(); - Utils.drawStringCenteredScaledMaxWidth(str, fontRendererObj, guiLeft+132, guiTop+69, - false, 24, Color.BLACK.getRGB()); } + currentRecipe.drawHoverInformation(this, mouseX, mouseY); + } - Utils.drawStringCenteredScaledMaxWidth(getCraftText(), fontRendererObj, guiLeft+132, guiTop+25, - false, 75, 4210752); + private void drawArrows(int mouseX, int mouseY) { + boolean leftSelected = isWithinRect(mouseX - guiLeft, mouseY - guiTop, BUTTON_POSITION_LEFT_X, BUTTON_POSITION_Y, BUTTON_WIDTH, BUTTON_HEIGHT); + boolean rightSelected = isWithinRect(mouseX - guiLeft, mouseY - guiTop, BUTTON_POSITION_RIGHT_X, BUTTON_POSITION_Y, BUTTON_WIDTH, BUTTON_HEIGHT); - Utils.drawStringScaledMaxWidth(title, fontRendererObj, guiLeft+28, guiTop+6, title.contains("\u00a7"), xSize-38, 4210752); + Minecraft.getMinecraft().getTextureManager().bindTexture(resourcePacksTexture); - if(tooltipToRender != null) { - Utils.drawHoveringText(tooltipToRender, mouseX, mouseY, width, height, -1, fontRendererObj); - } - } + Utils.drawTexturedRect(guiLeft + BUTTON_POSITION_LEFT_X, guiTop + BUTTON_POSITION_Y, BUTTON_WIDTH, BUTTON_HEIGHT, + 34 / 256f, 48 / 256f, + leftSelected ? 37 / 256f : 5 / 256f, leftSelected ? 59 / 256f : 27 / 256f + ); + Utils.drawTexturedRect(guiLeft + BUTTON_POSITION_RIGHT_X, guiTop + BUTTON_POSITION_Y, BUTTON_WIDTH, BUTTON_HEIGHT, + 10 / 256f, 24 / 256f, + rightSelected ? 37 / 256f : 5 / 256f, rightSelected ? 59 / 256f : 27 / 256f + ); + GL11.glBindTexture(GL11.GL_TEXTURE_2D, 0); - public ItemStack getStackForIndex(int index) { - if(index == 0) { - return manager.jsonToStack(results.get(currentIndex)); - } else if(index >= 1 && index <= 9) { - return craftMatrices.get(currentIndex)[index-1]; - } else { - return Minecraft.getMinecraft().thePlayer.inventory.getStackInSlot(index-10); - } + String selectedPage = (currentIndex + 1) + "/" + craftingRecipes.size(); + + Utils.drawStringCenteredScaledMaxWidth(selectedPage, fontRendererObj, + guiLeft + PAGE_STRING_X, guiTop + PAGE_STRING_Y, false, 24, Color.BLACK.getRGB()); } - public Vector2f getPositionForIndex(int index) { - //0 = result - //1-9 = craft matrix - //10-18 = hotbar - //19-45 = player inv - - if(index == 0) { - return new Vector2f(guiLeft+124, guiTop+35); - } else if(index >= 1 && index <= 9) { - index -= 1; - int x = index % 3; - int y = index / 3; - return new Vector2f(guiLeft+30 + x*18, guiTop+17 + y * 18); - } else if(index >= 10 && index <= 18) { - index -= 10; - return new Vector2f(guiLeft+8 + index*18, guiTop+142); - } else if(index >= 19 && index <= 45) { - index -= 19; - int x = index % 9; - int y = index / 9; - return new Vector2f(guiLeft+8 + x*18, guiTop+84 + y*18); + public List getPlayerInventory() { + List slots = new ArrayList<>(); + ItemStack[] inventory = Minecraft.getMinecraft().thePlayer.inventory.mainInventory; + int hotbarSize = InventoryPlayer.getHotbarSize(); + for (int i = 0; i < inventory.length; i++) { + ItemStack item = inventory[i]; + if (item == null || item.stackSize == 0) continue; + int row = i / hotbarSize; + int col = i % hotbarSize; + if (row == 0) + slots.add(new RecipeSlot(HOTBAR_SLOT_X + i * SLOT_SPACING, HOTBAR_SLOT_Y, item)); + else + slots.add(new RecipeSlot(PLAYER_INVENTORY_X + col * SLOT_SPACING, PLAYER_INVENTORY_Y + (row - 1) * SLOT_SPACING, item)); } - return null; + return slots; } @Override public void handleKeyboardInput() throws IOException { super.handleKeyboardInput(); - if(!Keyboard.getEventKeyState()) return; - ScaledResolution scaledResolution = new ScaledResolution(Minecraft.getMinecraft()); int width = scaledResolution.getScaledWidth(); int height = scaledResolution.getScaledHeight(); int mouseX = Mouse.getX() * width / Minecraft.getMinecraft().displayWidth; int mouseY = height - Mouse.getY() * height / Minecraft.getMinecraft().displayHeight - 1; - int keyPressed = Keyboard.getEventKey() == 0 ? Keyboard.getEventCharacter()+256 : Keyboard.getEventKey(); - for(int index=0; index <= 45; index++) { - Vector2f pos = getPositionForIndex(index); - if(mouseX > pos.x && mouseX < pos.x+16) { - if(mouseY > pos.y && mouseY < pos.y+16) { - ItemStack stack = getStackForIndex(index); - if(stack != null) { - if(keyPressed == manager.keybindViewRecipe.getKeyCode()) { - manager.displayGuiItemRecipe(manager.getInternalNameForItem(stack), ""); - } else if(keyPressed == manager.keybindViewUsages.getKeyCode()) { - manager.displayGuiItemUsages(manager.getInternalNameForItem(stack)); - } - } - return; + for (RecipeSlot slot : getAllRenderedSlots()) { + if (isWithinRect(mouseX, mouseY, slot.getX(this), slot.getY(this), SLOT_SIZE, SLOT_SIZE)) { + ItemStack itemStack = slot.getItemStack(); + if (keyPressed == manager.keybindViewRecipe.getKeyCode()) { // TODO: rework this so it doesnt skip recipe chains + manager.displayGuiItemRecipe(manager.getInternalNameForItem(itemStack), ""); + } else if (keyPressed == manager.keybindViewUsages.getKeyCode()) { + manager.displayGuiItemUsages(manager.getInternalNameForItem(itemStack)); } } } @@ -197,37 +178,25 @@ public class GuiItemRecipe extends GuiScreen { protected void mouseClicked(int mouseX, int mouseY, int mouseButton) throws IOException { super.mouseClicked(mouseX, mouseY, mouseButton); - int guiX = mouseX - guiLeft; - int guiY = mouseY - guiTop; - - int buttonWidth = 7; - int buttonHeight = 11; - - if(guiY > + 63 && guiY < + 63 + buttonHeight) { - if(guiX > + 110 && guiX < 110 + buttonWidth) { - currentIndex--; - Utils.playPressSound(); - return; - } else if(guiX > 147 && guiX < 147 + buttonWidth) { - currentIndex++; - Utils.playPressSound(); - return; - } + if (isWithinRect(mouseX - guiLeft, mouseY - guiTop, BUTTON_POSITION_LEFT_X, BUTTON_POSITION_Y, BUTTON_WIDTH, BUTTON_HEIGHT)) { + currentIndex = currentIndex == 0 ? 0 : currentIndex - 1; + Utils.playPressSound(); + return; + } + + if (isWithinRect(mouseX - guiLeft, mouseY - guiTop, BUTTON_POSITION_RIGHT_X, BUTTON_POSITION_Y, BUTTON_WIDTH, BUTTON_HEIGHT)) { + currentIndex = currentIndex == craftingRecipes.size() - 1 ? currentIndex : currentIndex + 1; + Utils.playPressSound(); + return; } - for(int index=0; index <= 45; index++) { - Vector2f pos = getPositionForIndex(index); - if(mouseX > pos.x && mouseX < pos.x+16) { - if(mouseY > pos.y && mouseY < pos.y+16) { - ItemStack stack = getStackForIndex(index); - if(stack != null) { - if(mouseButton == 0) { - manager.displayGuiItemRecipe(manager.getInternalNameForItem(stack), ""); - } else if(mouseButton == 1) { - manager.displayGuiItemUsages(manager.getInternalNameForItem(stack)); - } - } - return; + for (RecipeSlot slot : getAllRenderedSlots()) { + if (isWithinRect(mouseX, mouseY, slot.getX(this), slot.getY(this), SLOT_SIZE, SLOT_SIZE)) { + ItemStack itemStack = slot.getItemStack(); + if (mouseButton == 0) { + manager.displayGuiItemRecipe(manager.getInternalNameForItem(itemStack), ""); + } else if (mouseButton == 1) { + manager.displayGuiItemUsages(manager.getInternalNameForItem(itemStack)); } } } diff --git a/src/main/java/io/github/moulberry/notenoughupdates/overlays/CraftingOverlay.java b/src/main/java/io/github/moulberry/notenoughupdates/overlays/CraftingOverlay.java index 532f3324..c0cbef0f 100644 --- a/src/main/java/io/github/moulberry/notenoughupdates/overlays/CraftingOverlay.java +++ b/src/main/java/io/github/moulberry/notenoughupdates/overlays/CraftingOverlay.java @@ -3,6 +3,8 @@ package io.github.moulberry.notenoughupdates.overlays; import com.google.gson.JsonObject; import io.github.moulberry.notenoughupdates.NEUManager; import io.github.moulberry.notenoughupdates.NotEnoughUpdates; +import io.github.moulberry.notenoughupdates.recipes.CraftingRecipe; +import io.github.moulberry.notenoughupdates.recipes.Ingredient; import io.github.moulberry.notenoughupdates.util.Utils; import net.minecraft.client.Minecraft; import net.minecraft.client.gui.FontRenderer; @@ -17,7 +19,7 @@ import org.lwjgl.input.Mouse; import java.util.List; public class CraftingOverlay { - private static ItemStack[] items = new ItemStack[9]; + private static final ItemStack[] items = new ItemStack[9]; private static final NEUManager manager = NotEnoughUpdates.INSTANCE.manager; public static boolean shouldRender = false; private static String text = null; @@ -56,34 +58,6 @@ public class CraftingOverlay { } } - public static void updateItem(JsonObject item) { - items = new ItemStack[9]; - text = null; - String[] x = {"1", "2", "3"}; - String[] y = {"A", "B", "C"}; - for (int i = 0; i < 9; i++) { - String name = y[i / 3] + x[i % 3]; - String itemS = item.getAsJsonObject("recipe").get(name).getAsString(); - if (itemS != null && !itemS.equals("")) { - int count = 1; - if (itemS.split(":").length == 2) { - count = Integer.parseInt(itemS.split(":")[1]); - itemS = itemS.split(":")[0]; - } - JsonObject craft = manager.getItemInformation().get(itemS); - if (craft != null) { - ItemStack stack = manager.jsonToStack(craft); - stack.stackSize = count; - items[i] = stack; - } - } - } - if (item.has("crafttext")) { - text = item.get("crafttext").getAsString(); - } - shouldRender = true; - } - public static void keyInput() { if (!Keyboard.getEventKeyState() || Keyboard.getEventKey() != Keyboard.KEY_U && Keyboard.getEventKey() != Keyboard.KEY_R) return; @@ -114,4 +88,16 @@ public class CraftingOverlay { } } } + + public static void updateItem(CraftingRecipe recipe) { + for (int i = 0; i < 9; i++) { + Ingredient ingredient = recipe.getInputs()[i]; + if (ingredient == null) { + items[i] = null; + } else { + items[i] = ingredient.getItemStack(); + } + } + text = recipe.getCraftText(); + } } diff --git a/src/main/java/io/github/moulberry/notenoughupdates/recipes/CraftingRecipe.java b/src/main/java/io/github/moulberry/notenoughupdates/recipes/CraftingRecipe.java new file mode 100644 index 00000000..00e70462 --- /dev/null +++ b/src/main/java/io/github/moulberry/notenoughupdates/recipes/CraftingRecipe.java @@ -0,0 +1,141 @@ +package io.github.moulberry.notenoughupdates.recipes; + +import com.google.common.collect.Sets; +import com.google.gson.JsonObject; +import io.github.moulberry.notenoughupdates.NEUManager; +import io.github.moulberry.notenoughupdates.miscgui.GuiItemRecipe; +import io.github.moulberry.notenoughupdates.util.Utils; +import net.minecraft.client.Minecraft; +import net.minecraft.client.gui.FontRenderer; +import net.minecraft.item.ItemStack; +import net.minecraft.util.ResourceLocation; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; +import java.util.Set; + +public class CraftingRecipe implements NeuRecipe { + + public static final ResourceLocation BACKGROUND = new ResourceLocation("textures/gui/container/crafting_table.png"); + + private static final int EXTRA_STRING_X = 132; + private static final int EXTRA_STRING_Y = 25; + + private final NEUManager manager; + private final Ingredient[] inputs; + private final String extraText; + private final Ingredient outputIngredient; + private List slots; + + public CraftingRecipe(NEUManager manager, Ingredient[] inputs, Ingredient output, String extra) { + this.manager = manager; + this.inputs = inputs; + this.outputIngredient = output; + this.extraText = extra; + if (inputs.length != 9) + throw new IllegalArgumentException("Cannot construct crafting recipe with non standard crafting grid size"); + } + + @Override + public Set getIngredients() { + Set ingredients = Sets.newHashSet(inputs); + ingredients.remove(null); + return ingredients; + } + + @Override + public Set getOutputs() { + return Collections.singleton(getOutput()); + } + + public Ingredient getOutput() { + return outputIngredient; + } + + public Ingredient[] getInputs() { + return inputs; + } + + + @Override + public List getSlots() { + if (slots != null) return slots; + slots = new ArrayList<>(); + for (int x = 0; x < 3; x++) { + for (int y = 0; y < 3; y++) { + Ingredient input = inputs[x + y * 3]; + if (input == null) continue; + ItemStack item = input.getItemStack(); + if (item == null) continue; + slots.add(new RecipeSlot(30 + x * GuiItemRecipe.SLOT_SPACING, 17 + y * GuiItemRecipe.SLOT_SPACING, item)); + } + } + slots.add(new RecipeSlot(124, 35, outputIngredient.getItemStack())); + return slots; + } + + public String getCraftText() { + return extraText; + } + + @Override + public ResourceLocation getBackground() { + return BACKGROUND; + } + + @Override + public void drawExtraInfo(GuiItemRecipe gui) { + FontRenderer fontRenderer = Minecraft.getMinecraft().fontRendererObj; + + String craftingText = getCraftText(); + if (craftingText != null) + Utils.drawStringCenteredScaledMaxWidth(craftingText, fontRenderer, + gui.guiLeft + EXTRA_STRING_X, gui.guiTop + EXTRA_STRING_Y, false, 75, 0x404040); + } + + @Override + public JsonObject serialize() { + JsonObject object = new JsonObject(); + object.addProperty("type", "crafting"); + object.addProperty("count", outputIngredient.getCount()); + object.addProperty("overrideOutputId", outputIngredient.getInternalItemId()); + for (int i = 0; i < 9; i++) { + Ingredient ingredient = inputs[i]; + if (ingredient == null) continue; + String[] x = {"1", "2", "3"}; + String[] y = {"A", "B", "C"}; + String name = x[i / 3] + y[i % 3]; + object.addProperty(name, ingredient.serialize()); + } + if(extraText != null) + object.addProperty("crafttext", extraText); + return object; + } + + public static CraftingRecipe parseCraftingRecipe(NEUManager manager, JsonObject recipe, JsonObject outputItem) { + Ingredient[] craftMatrix = new Ingredient[9]; + + String[] x = {"1", "2", "3"}; + String[] y = {"A", "B", "C"}; + for (int i = 0; i < 9; i++) { + String name = y[i / 3] + x[i % 3]; + if (!recipe.has(name)) continue; + String item = recipe.get(name).getAsString(); + if (item == null || item.isEmpty()) continue; + craftMatrix[i] = new Ingredient(manager, item); + } + int resultCount = 1; + if (recipe.has("count")) + resultCount = recipe.get("count").getAsInt(); + String extra = null; + if (outputItem.has("crafttext")) + extra = outputItem.get("crafttext").getAsString(); + if (recipe.has("crafttext")) + extra = recipe.get("crafttext").getAsString(); + String outputItemId = outputItem.get("internalname").getAsString(); + if (recipe.has("overrideOutputId")) + outputItemId = recipe.get("overrideOutputId").getAsString(); + return new CraftingRecipe(manager, craftMatrix, new Ingredient(manager, outputItemId, resultCount), extra); + } +} diff --git a/src/main/java/io/github/moulberry/notenoughupdates/recipes/ForgeRecipe.java b/src/main/java/io/github/moulberry/notenoughupdates/recipes/ForgeRecipe.java new file mode 100644 index 00000000..5cbb4afe --- /dev/null +++ b/src/main/java/io/github/moulberry/notenoughupdates/recipes/ForgeRecipe.java @@ -0,0 +1,220 @@ +package io.github.moulberry.notenoughupdates.recipes; + +import com.google.common.collect.Sets; +import com.google.gson.JsonArray; +import com.google.gson.JsonElement; +import com.google.gson.JsonObject; +import com.google.gson.JsonPrimitive; +import io.github.moulberry.notenoughupdates.NEUManager; +import io.github.moulberry.notenoughupdates.miscgui.GuiItemRecipe; +import io.github.moulberry.notenoughupdates.util.HotmInformation; +import io.github.moulberry.notenoughupdates.util.Utils; +import net.minecraft.client.Minecraft; +import net.minecraft.client.gui.FontRenderer; +import net.minecraft.item.ItemStack; +import net.minecraft.util.EnumChatFormatting; +import net.minecraft.util.ResourceLocation; + +import java.util.*; + +public class ForgeRecipe implements NeuRecipe { + + private static final ResourceLocation BACKGROUND = new ResourceLocation("notenoughupdates", "textures/gui/forge_recipe.png"); + + private static final int SLOT_IMAGE_U = 176; + private static final int SLOT_IMAGE_V = 0; + private static final int SLOT_IMAGE_SIZE = 18; + private static final int SLOT_PADDING = 1; + private static final int EXTRA_INFO_MAX_WIDTH = 75; + public static final int EXTRA_INFO_X = 132; + public static final int EXTRA_INFO_Y = 25; + + public enum ForgeType { + REFINING, ITEM_FORGING + } + + private final NEUManager manager; + private final List inputs; + private final Ingredient output; + private final int hotmLevel; + private final int timeInSeconds; // TODO: quick forge + private List slots; + + public ForgeRecipe(NEUManager manager, List inputs, Ingredient output, int durationInSeconds, int hotmLevel) { + this.manager = manager; + this.inputs = inputs; + this.output = output; + this.hotmLevel = hotmLevel; + this.timeInSeconds = durationInSeconds; + } + + public List getInputs() { + return inputs; + } + + public Ingredient getOutput() { + return output; + } + + public int getHotmLevel() { + return hotmLevel; + } + + public int getTimeInSeconds() { + return timeInSeconds; + } + + @Override + public ResourceLocation getBackground() { + return BACKGROUND; + } + + @Override + public Set getIngredients() { + return Sets.newHashSet(inputs); + } + + @Override + public Set getOutputs() { + return Collections.singleton(output); + } + + @Override + public List getSlots() { + if (slots != null) return slots; + slots = new ArrayList<>(); + for (int i = 0; i < inputs.size(); i++) { + Ingredient input = inputs.get(i); + ItemStack itemStack = input.getItemStack(); + if (itemStack == null) continue; + int[] slotCoordinates = getSlotCoordinates(i, inputs.size()); + slots.add(new RecipeSlot(slotCoordinates[0], slotCoordinates[1], itemStack)); + } + slots.add(new RecipeSlot(124, 35, output.getItemStack())); + return slots; + } + + @Override + public void drawExtraBackground(GuiItemRecipe gui) { + Minecraft.getMinecraft().getTextureManager().bindTexture(BACKGROUND); + for (int i = 0; i < inputs.size(); i++) { + int[] slotCoordinates = getSlotCoordinates(i, inputs.size()); + gui.drawTexturedModalRect( + gui.guiLeft + slotCoordinates[0] - SLOT_PADDING, gui.guiTop + slotCoordinates[1] - SLOT_PADDING, + SLOT_IMAGE_U, SLOT_IMAGE_V, + SLOT_IMAGE_SIZE, SLOT_IMAGE_SIZE); + } + } + + @Override + public void drawExtraInfo(GuiItemRecipe gui) { + FontRenderer fontRenderer = Minecraft.getMinecraft().fontRendererObj; + if (timeInSeconds > 0) + Utils.drawStringCenteredScaledMaxWidth(formatDuration(timeInSeconds), fontRenderer, gui.guiLeft + EXTRA_INFO_X, gui.guiTop + EXTRA_INFO_Y, false, EXTRA_INFO_MAX_WIDTH, 0xff00ff); + } + + @Override + public void drawHoverInformation(GuiItemRecipe gui, int mouseX, int mouseY) { + manager.hotm.getInformationOnCurrentProfile().ifPresent(hotmTree -> { + if (timeInSeconds > 0 && gui.isWithinRect( + mouseX, mouseY, + gui.guiLeft + EXTRA_INFO_X - EXTRA_INFO_MAX_WIDTH / 2, + gui.guiTop + EXTRA_INFO_Y - 8, + EXTRA_INFO_MAX_WIDTH, 16 + )) { + int qf = hotmTree.getLevel("forge_time"); + int reducedTime = getReducedTime(qf); + if (qf > 0) { + + Utils.drawHoveringText(Arrays.asList(EnumChatFormatting.YELLOW + formatDuration(reducedTime) + " with Quick Forge (Level " + qf + ")"), mouseX, mouseY, gui.width, gui.height, 500, Minecraft.getMinecraft().fontRendererObj); + } + } + }); + } + + public int getReducedTime(int quickForgeUpgradeLevel) { + return HotmInformation.getQuickForgeMultiplier(quickForgeUpgradeLevel) * timeInSeconds / 1000; + } + + @Override + public JsonObject serialize() { + JsonObject object = new JsonObject(); + JsonArray ingredients = new JsonArray(); + for (Ingredient input : inputs) { + ingredients.add(new JsonPrimitive(input.serialize())); + } + object.addProperty("type", "forge"); + object.add("inputs", ingredients); + object.addProperty("count", output.getCount()); + object.addProperty("overrideOutputId", output.getInternalItemId()); + if (hotmLevel >= 0) + object.addProperty("hotmLevel", hotmLevel); + if (timeInSeconds >= 0) + object.addProperty("duration", timeInSeconds); + return object; + } + + static ForgeRecipe parseForgeRecipe(NEUManager manager, JsonObject recipe, JsonObject output) { + List ingredients = new ArrayList<>(); + for (JsonElement element : recipe.getAsJsonArray("inputs")) { + String ingredientString = element.getAsString(); + ingredients.add(new Ingredient(manager, ingredientString)); + } + String internalItemId = output.get("internalname").getAsString(); + if (recipe.has("overrideOutputId")) + internalItemId = recipe.get("overrideOutputId").getAsString(); + int resultCount = 1; + if (recipe.has("count")) { + resultCount = recipe.get("count").getAsInt(); + } + int duration = -1; + if (recipe.has("duration")) { + duration = recipe.get("duration").getAsInt(); + } + int hotmLevel = -1; + if (recipe.has("hotmLevel")) { + hotmLevel = recipe.get("hotmLevel").getAsInt(); + } + return new ForgeRecipe(manager, ingredients, new Ingredient(manager, internalItemId, resultCount), duration, hotmLevel); + } + + private static final int RECIPE_CENTER_X = 40; + private static final int RECIPE_CENTER_Y = 34; + private static final int SLOT_DISTANCE_FROM_CENTER = 22; + private static final int RECIPE_FALLBACK_X = 20; + private static final int RECIPE_FALLBACK_Y = 15; + + static int[] getSlotCoordinates(int slotNumber, int totalSlotCount) { + if (totalSlotCount > 6) { + return new int[]{ + RECIPE_FALLBACK_X + (slotNumber % 4) * GuiItemRecipe.SLOT_SPACING, + RECIPE_FALLBACK_Y + (slotNumber / 4) * GuiItemRecipe.SLOT_SPACING, + }; + } + if (totalSlotCount == 1) { + return new int[] { + RECIPE_CENTER_X - GuiItemRecipe.SLOT_SIZE / 2, + RECIPE_CENTER_Y - GuiItemRecipe.SLOT_SIZE / 2 + }; + } + double rad = Math.PI * 2 * slotNumber / totalSlotCount; + int x = (int) (Math.cos(rad) * SLOT_DISTANCE_FROM_CENTER); + int y = (int) (Math.sin(rad) * SLOT_DISTANCE_FROM_CENTER); + return new int[]{RECIPE_CENTER_X + x, RECIPE_CENTER_Y + y}; + } + + static String formatDuration(int seconds) { + int minutes = seconds / 60; + seconds %= 60; + int hours = minutes / 60; + minutes %= 60; + int days = hours / 24; + hours %= 24; + StringBuilder sB = new StringBuilder(); + if (days != 0) sB.append(days).append("d "); + if (hours != 0) sB.append(hours).append("h "); + if (minutes != 0) sB.append(minutes).append("m "); + if (seconds != 0) sB.append(seconds).append("s "); + return sB.substring(0, sB.length() - 1); + } +} diff --git a/src/main/java/io/github/moulberry/notenoughupdates/recipes/Ingredient.java b/src/main/java/io/github/moulberry/notenoughupdates/recipes/Ingredient.java new file mode 100644 index 00000000..d72c901f --- /dev/null +++ b/src/main/java/io/github/moulberry/notenoughupdates/recipes/Ingredient.java @@ -0,0 +1,88 @@ +package io.github.moulberry.notenoughupdates.recipes; + +import com.google.gson.JsonObject; +import io.github.moulberry.notenoughupdates.NEUManager; +import io.github.moulberry.notenoughupdates.util.Utils; +import net.minecraft.init.Items; +import net.minecraft.item.ItemStack; + +import java.text.NumberFormat; +import java.util.HashMap; +import java.util.HashSet; +import java.util.Map; +import java.util.Set; + +public class Ingredient { + + public static final String SKYBLOCK_COIN = "SKYBLOCK_COIN"; + private final int count; + private final String internalItemId; + private final NEUManager manager; + private ItemStack itemStack; + + public Ingredient(NEUManager manager, String ingredientIdentifier) { + this.manager = manager; + String[] parts = ingredientIdentifier.split(":"); + internalItemId = parts[0]; + if (parts.length == 2) { + count = Integer.parseInt(parts[1]); + } else if (parts.length == 1) { + count = 1; + } else { + throw new IllegalArgumentException("Could not parse ingredient " + ingredientIdentifier); + } + } + + public Ingredient(NEUManager manager, String internalItemId, int count) { + this.manager = manager; + this.count = count; + this.internalItemId = internalItemId; + } + + private Ingredient(NEUManager manager, int coinValue) { + this.manager = manager; + this.internalItemId = SKYBLOCK_COIN; + this.count = coinValue; + } + + public static Set mergeIngredients(Iterable ingredients) { + Map newIngredients = new HashMap<>(); + for (Ingredient i : ingredients) { + newIngredients.merge(i.getInternalItemId(), i, (a, b) -> new Ingredient(i.manager, i.internalItemId, a.count + b.count)); + } + return new HashSet<>(newIngredients.values()); + } + + public static Ingredient coinIngredient(NEUManager manager, int coins) { + return new Ingredient(manager, coins); + } + + public boolean isCoins() { + return "SKYBLOCK_COIN".equals(internalItemId); + } + + public int getCount() { + return count; + } + + public String getInternalItemId() { + return internalItemId; + } + + public ItemStack getItemStack() { + if (itemStack != null) return itemStack; + if(isCoins()) { + itemStack = new ItemStack(Items.gold_nugget); + itemStack.setStackDisplayName("\u00A7r\u00A76" + Utils.formatNumberWithDots(getCount()) + " Coins"); + return itemStack; + } + JsonObject itemInfo = manager.getItemInformation().get(internalItemId); + itemStack = manager.jsonToStack(itemInfo); + itemStack.stackSize = count; + return itemStack; + } + + public String serialize() { + return internalItemId + ":" + count; + } +} diff --git a/src/main/java/io/github/moulberry/notenoughupdates/recipes/NeuRecipe.java b/src/main/java/io/github/moulberry/notenoughupdates/recipes/NeuRecipe.java new file mode 100644 index 00000000..cfa091d5 --- /dev/null +++ b/src/main/java/io/github/moulberry/notenoughupdates/recipes/NeuRecipe.java @@ -0,0 +1,39 @@ +package io.github.moulberry.notenoughupdates.recipes; + +import com.google.gson.JsonObject; +import io.github.moulberry.notenoughupdates.NEUManager; +import io.github.moulberry.notenoughupdates.miscgui.GuiItemRecipe; +import net.minecraft.util.ResourceLocation; + +import java.util.List; +import java.util.Set; + +public interface NeuRecipe { + Set getIngredients(); + + Set getOutputs(); + + List getSlots(); + + void drawExtraInfo(GuiItemRecipe gui); + + default void drawExtraBackground(GuiItemRecipe gui) { + } + + default void drawHoverInformation(GuiItemRecipe gui, int mouseX, int mouseY) { + } + + JsonObject serialize(); + + ResourceLocation getBackground(); + + static NeuRecipe parseRecipe(NEUManager manager, JsonObject recipe, JsonObject output) { + if (recipe.has("type")) { + switch (recipe.get("type").getAsString().intern()) { + case "forge": + return ForgeRecipe.parseForgeRecipe(manager, recipe, output); + } + } + return CraftingRecipe.parseCraftingRecipe(manager, recipe, output); + } +} diff --git a/src/main/java/io/github/moulberry/notenoughupdates/recipes/RecipeGenerator.java b/src/main/java/io/github/moulberry/notenoughupdates/recipes/RecipeGenerator.java new file mode 100644 index 00000000..6862de29 --- /dev/null +++ b/src/main/java/io/github/moulberry/notenoughupdates/recipes/RecipeGenerator.java @@ -0,0 +1,180 @@ +package io.github.moulberry.notenoughupdates.recipes; + +import com.google.gson.JsonArray; +import com.google.gson.JsonObject; +import io.github.moulberry.notenoughupdates.NotEnoughUpdates; +import io.github.moulberry.notenoughupdates.util.Debouncer; +import io.github.moulberry.notenoughupdates.util.Utils; +import net.minecraft.client.Minecraft; +import net.minecraft.client.entity.EntityPlayerSP; +import net.minecraft.client.gui.GuiScreen; +import net.minecraft.client.gui.inventory.GuiChest; +import net.minecraft.inventory.ContainerChest; +import net.minecraft.inventory.IInventory; +import net.minecraft.item.ItemStack; +import net.minecraft.util.ChatComponentText; +import net.minecraft.util.EnumChatFormatting; +import net.minecraftforge.fml.common.eventhandler.SubscribeEvent; +import net.minecraftforge.fml.common.gameevent.TickEvent; +import org.lwjgl.input.Keyboard; + +import java.io.IOException; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +public class RecipeGenerator { + public static final String DURATION = "Duration: "; + public static final String COINS_SUFFIX = " Coins"; + + private final NotEnoughUpdates neu; + + private final Map savedForgingDurations = new HashMap<>(); + + private final Debouncer debouncer = new Debouncer(1000 * 1000 * 50 /* 50 ms */); + private final Debouncer durationDebouncer = new Debouncer(1000 * 1000 * 500); + + public RecipeGenerator(NotEnoughUpdates neu) { + this.neu = neu; + } + + @SubscribeEvent + public void onTick(TickEvent event) { + if (!neu.config.hidden.enableItemEditing) return; + GuiScreen currentScreen = Minecraft.getMinecraft().currentScreen; + if (currentScreen == null) return; + if (!(currentScreen instanceof GuiChest)) return; + analyzeUI((GuiChest) currentScreen); + } + + private boolean shouldSaveRecipe() { + return Keyboard.isKeyDown(Keyboard.KEY_O) && debouncer.trigger(); + } + + public void analyzeUI(GuiChest gui) { + ContainerChest container = (ContainerChest) gui.inventorySlots; + IInventory menu = container.getLowerChestInventory(); + String uiTitle = menu.getDisplayName().getUnformattedText(); + EntityPlayerSP p = Minecraft.getMinecraft().thePlayer; + if (uiTitle.startsWith("Item Casting") || uiTitle.startsWith("Refine")) { + if (durationDebouncer.trigger()) + parseAllForgeItemMetadata(menu); + } + boolean saveRecipe = shouldSaveRecipe(); + if (uiTitle.equals("Confirm Process") && saveRecipe) { + ForgeRecipe recipe = parseSingleForgeRecipe(menu); + if (recipe == null) { + p.addChatMessage(new ChatComponentText("" + EnumChatFormatting.DARK_RED + EnumChatFormatting.BOLD + "Could not parse recipe for this UI")); + } else { + p.addChatMessage(new ChatComponentText("" + EnumChatFormatting.GREEN + EnumChatFormatting.BOLD + "Parsed recipe:")); + p.addChatMessage(new ChatComponentText("" + EnumChatFormatting.AQUA + " Inputs:")); + for (Ingredient i : recipe.getInputs()) + p.addChatMessage(new ChatComponentText(" - " + EnumChatFormatting.AQUA + i.getInternalItemId() + " x " + i.getCount())); + p.addChatMessage(new ChatComponentText("" + EnumChatFormatting.AQUA + " Output: " + EnumChatFormatting.GOLD + recipe.getOutput().getInternalItemId() + " x " + recipe.getOutput().getCount())); + p.addChatMessage(new ChatComponentText("" + EnumChatFormatting.AQUA + " Time: " + EnumChatFormatting.GRAY + recipe.getTimeInSeconds() + " seconds (no QF) .")); + boolean saved = false; + try { + saved = saveRecipe(recipe); + } catch (IOException e) { + } + if (!saved) + p.addChatMessage(new ChatComponentText("" + + EnumChatFormatting.DARK_RED + EnumChatFormatting.BOLD + EnumChatFormatting.OBFUSCATED + "#" + + EnumChatFormatting.RESET + EnumChatFormatting.DARK_RED + EnumChatFormatting.BOLD + " ERROR " + + EnumChatFormatting.DARK_RED + EnumChatFormatting.BOLD + EnumChatFormatting.OBFUSCATED + "#" + + EnumChatFormatting.RESET + EnumChatFormatting.DARK_RED + EnumChatFormatting.BOLD + " Failed to save recipe. Does the item already exist?")); + } + } + } + + public boolean saveRecipe(NeuRecipe recipe) throws IOException { + JsonObject recipeJson = recipe.serialize(); + for (Ingredient i : recipe.getOutputs()) { + if (i.isCoins()) continue; + JsonObject outputJson = neu.manager.readJsonDefaultDir(i.getInternalItemId() + ".json"); + if (outputJson == null) return false; + outputJson.addProperty("clickcommand", "viewrecipe"); + JsonArray array = new JsonArray(); + array.add(recipeJson); + outputJson.add("recipes", array); + neu.manager.writeJsonDefaultDir(outputJson, i.getInternalItemId() + ".json"); + neu.manager.loadItem(i.getInternalItemId()); + } + return true; + } + + + public ForgeRecipe parseSingleForgeRecipe(IInventory chest) { + int durationInSeconds = -1; + List inputs = new ArrayList<>(); + Ingredient output = null; + for (int i = 0; i < chest.getSizeInventory(); i++) { + int col = i % 9; + ItemStack itemStack = chest.getStackInSlot(i); + if (itemStack == null) continue; + String name = Utils.cleanColour(itemStack.getDisplayName()); + String internalId = neu.manager.getInternalNameForItem(itemStack); + Ingredient ingredient = null; + if (itemStack.getDisplayName().endsWith(COINS_SUFFIX)) { + int coinCost = Integer.parseInt( + name.substring(0, name.length() - COINS_SUFFIX.length()) + .replace(",", "")); + ingredient = Ingredient.coinIngredient(neu.manager, coinCost); + } else if (internalId != null) { + ingredient = new Ingredient(neu.manager, internalId, itemStack.stackSize); + } + if (ingredient == null) continue; + if (col < 4) { + inputs.add(ingredient); + } else { + output = ingredient; + } + } + if (output == null || inputs.isEmpty()) return null; + if (savedForgingDurations.containsKey(output.getInternalItemId())) + durationInSeconds = parseDuration(savedForgingDurations.get(output.getInternalItemId())); + return new ForgeRecipe(neu.manager, new ArrayList<>(Ingredient.mergeIngredients(inputs)), output, durationInSeconds, -1); + } + + private static Map durationSuffixLengthMap = new HashMap() {{ + put('d', 60 * 60 * 24); + put('h', 60 * 60); + put('m', 60); + put('s', 1); + }}; + + public int parseDuration(String durationString) { + String[] parts = durationString.split(" "); + int timeInSeconds = 0; + for (String part : parts) { + char signifier = part.charAt(part.length() - 1); + int value = Integer.parseInt(part.substring(0, part.length() - 1)); + if (!durationSuffixLengthMap.containsKey(signifier)) { + return -1; + } + timeInSeconds += value * durationSuffixLengthMap.get(signifier); + } + return timeInSeconds; + } + + private void parseAllForgeItemMetadata(IInventory chest) { + for (int i = 0; i < chest.getSizeInventory(); i++) { + ItemStack stack = chest.getStackInSlot(i); + if (stack == null) continue; + String internalName = neu.manager.getInternalNameForItem(stack); + if (internalName == null) continue; + List tooltip = stack.getTooltip(Minecraft.getMinecraft().thePlayer, false); + String durationInfo = null; + for (String s : tooltip) { + String info = Utils.cleanColour(s); + if (info.startsWith(DURATION)) { + durationInfo = info.substring(DURATION.length()); + } + } + if (durationInfo != null) + savedForgingDurations.put(internalName, durationInfo); + } + } + +} diff --git a/src/main/java/io/github/moulberry/notenoughupdates/recipes/RecipeSlot.java b/src/main/java/io/github/moulberry/notenoughupdates/recipes/RecipeSlot.java new file mode 100644 index 00000000..ec97e59a --- /dev/null +++ b/src/main/java/io/github/moulberry/notenoughupdates/recipes/RecipeSlot.java @@ -0,0 +1,28 @@ +package io.github.moulberry.notenoughupdates.recipes; + +import io.github.moulberry.notenoughupdates.miscgui.GuiItemRecipe; +import net.minecraft.item.ItemStack; + +public class RecipeSlot { + private final int x; + private final int y; + private final ItemStack itemStack; + + public RecipeSlot(int x, int y, ItemStack itemStack) { + this.x = x; + this.y = y; + this.itemStack = itemStack; + } + + public ItemStack getItemStack() { + return itemStack; + } + + public int getX(GuiItemRecipe recipe) { + return recipe.guiLeft + x; + } + + public int getY(GuiItemRecipe recipe) { + return recipe.guiTop + y; + } +} diff --git a/src/main/java/io/github/moulberry/notenoughupdates/util/Debouncer.java b/src/main/java/io/github/moulberry/notenoughupdates/util/Debouncer.java new file mode 100644 index 00000000..be42364a --- /dev/null +++ b/src/main/java/io/github/moulberry/notenoughupdates/util/Debouncer.java @@ -0,0 +1,34 @@ +package io.github.moulberry.notenoughupdates.util; + +/** + * This debouncer always triggers on the leading edge. + *

+ * Calling {@link #trigger} will only result in a truthy return value the first time it is called + * within {@link #getDelayInNanoSeconds()} nanoseconds. + */ +public class Debouncer { + private long lastPinged = 0L; + private final long delay; + + public Debouncer(long minimumDelayInNanoSeconds) { + this.delay = minimumDelayInNanoSeconds; + } + + public long getDelayInNanoSeconds() { + return delay; + } + + public synchronized long timePassed() { + // longs are technically not atomic reads since they use two 32 bit registers + // so, yes, this technically has to be synchronized + return System.nanoTime() - lastPinged; + } + + public synchronized boolean trigger() { + long newPingTime = System.nanoTime(); + long newDelay = newPingTime - lastPinged; + lastPinged = newPingTime; + return newDelay >= this.delay; + } + +} diff --git a/src/main/java/io/github/moulberry/notenoughupdates/util/HotmInformation.java b/src/main/java/io/github/moulberry/notenoughupdates/util/HotmInformation.java new file mode 100644 index 00000000..9ca53b5d --- /dev/null +++ b/src/main/java/io/github/moulberry/notenoughupdates/util/HotmInformation.java @@ -0,0 +1,179 @@ +package io.github.moulberry.notenoughupdates.util; + +import com.google.gson.JsonArray; +import com.google.gson.JsonElement; +import com.google.gson.JsonObject; +import io.github.moulberry.notenoughupdates.NotEnoughUpdates; +import net.minecraft.client.Minecraft; +import net.minecraft.client.gui.inventory.GuiChest; +import net.minecraft.inventory.ContainerChest; +import net.minecraftforge.client.event.ClientChatReceivedEvent; +import net.minecraftforge.client.event.GuiOpenEvent; +import net.minecraftforge.common.MinecraftForge; +import net.minecraftforge.event.world.WorldEvent; +import net.minecraftforge.fml.common.eventhandler.SubscribeEvent; + +import java.util.HashMap; +import java.util.Map; +import java.util.Optional; +import java.util.Set; +import java.util.concurrent.CompletableFuture; +import java.util.concurrent.ConcurrentHashMap; + +public class HotmInformation { + private final NotEnoughUpdates neu; + public static final int[] EXPERIENCE_FOR_HOTM_LEVEL = { + // Taken from the wiki: https://hypixel-skyblock.fandom.com/wiki/Heart_of_the_Mountain#Experience_for_Each_Tier + 0, 3000, 12000, 37000, 97000, 197000, 347000 + }; + public static final int[] QUICK_FORGE_MULTIPLIERS = { + 985, + 970, + 955, + 940, + 925, + 910, + 895, + 880, + 865, + 850, + 845, + 840, + 835, + 830, + 825, + 820, + 815, + 810, + 805, + 700 + }; + private final Map profiles = new ConcurrentHashMap<>(); + + public static class Tree { + private Map levels = new HashMap<>(); + private int totalMithrilPowder; + private int totalGemstonePowder; + private int hotmExp; + + public int getHotmExp() { + return hotmExp; + } + + public int getTotalGemstonePowder() { + return totalGemstonePowder; + } + + public int getTotalMithrilPowder() { + return totalMithrilPowder; + } + + public Set getAllUnlockedNodes() { + return levels.keySet(); + } + + public int getHotmLevel() { + for (int i = EXPERIENCE_FOR_HOTM_LEVEL.length - 1; i >= 0; i--) { + if (EXPERIENCE_FOR_HOTM_LEVEL[i] >= this.hotmExp) + return i; + } + return 0; + } + + public int getLevel(String node) { + return levels.getOrDefault(node, 0); + } + + } + + private CompletableFuture updateTask = CompletableFuture.completedFuture(null); + + private boolean shouldReloadSoon = false; + + public HotmInformation(NotEnoughUpdates neu) { + this.neu = neu; + MinecraftForge.EVENT_BUS.register(this); + } + + public Optional getInformationOn(String profile) { + if (profile == null) { + return Optional.empty(); + } + return Optional.ofNullable(this.profiles.get(profile)); + } + + public Optional getInformationOnCurrentProfile() { + return getInformationOn(neu.manager.getCurrentProfile()); + } + + + @SubscribeEvent + public synchronized void onLobbyJoin(WorldEvent.Load event) { + if (shouldReloadSoon) { + shouldReloadSoon = false; + requestUpdate(false); + } + } + + @SubscribeEvent + public synchronized void onGuiOpen(GuiOpenEvent event) { + if (event.gui instanceof GuiChest) { + String containerName = ((ContainerChest) ((GuiChest) event.gui).inventorySlots).getLowerChestInventory().getDisplayName().getUnformattedText(); + if (containerName.equals("Heart of the Mountain")) + shouldReloadSoon = true; + } + } + + @SubscribeEvent + public synchronized void onChat(ClientChatReceivedEvent event) { + if (event.message.getUnformattedText().equals("Welcome to Hypixel SkyBlock!")) + requestUpdate(false); + } + + public synchronized void requestUpdate(boolean force) { + if (updateTask.isDone() || force) { + updateTask = neu.manager.hypixelApi.getHypixelApiAsync(neu.config.apiKey.apiKey, "skyblock/profiles", new HashMap() {{ + put("uuid", Minecraft.getMinecraft().thePlayer.getUniqueID().toString().replace("-", "")); + }}).thenAccept(this::updateInformation); + } + } + + /* + * 1000 = 100% of the time left + * 700 = 70% of the time left + * */ + public static int getQuickForgeMultiplier(int level) { + if (level <= 0) return 1000; + if (level > 20) return -1; + return QUICK_FORGE_MULTIPLIERS[level - 1]; + } + + public void updateInformation(JsonObject entireApiResponse) { + if (!entireApiResponse.has("success") || !entireApiResponse.get("success").getAsBoolean()) return; + JsonArray profiles = entireApiResponse.getAsJsonArray("profiles"); + for (JsonElement element : profiles) { + JsonObject profile = element.getAsJsonObject(); + String profileName = profile.get("cute_name").getAsString(); + JsonObject player = profile.getAsJsonObject("members").getAsJsonObject(Minecraft.getMinecraft().thePlayer.getUniqueID().toString().replace("-", "")); + if (!player.has("mining_core")) + continue; + JsonObject miningCore = player.getAsJsonObject("mining_core"); + Tree tree = new Tree(); + JsonObject nodes = miningCore.getAsJsonObject("nodes"); + for (Map.Entry node : nodes.entrySet()) { + tree.levels.put(node.getKey(), node.getValue().getAsInt()); + } + if (miningCore.has("powder_mithril_total")) { + tree.totalMithrilPowder = miningCore.get("powder_mithril_total").getAsInt(); + } + if (miningCore.has("powder_gemstone_total")) { + tree.totalGemstonePowder = miningCore.get("powder_gemstone_total").getAsInt(); + } + if (miningCore.has("experience")) { + tree.hotmExp = miningCore.get("experience").getAsInt(); + } + this.profiles.put(profileName, tree); + } + } + +} diff --git a/src/main/java/io/github/moulberry/notenoughupdates/util/HypixelApi.java b/src/main/java/io/github/moulberry/notenoughupdates/util/HypixelApi.java index 923b962a..3d313f25 100644 --- a/src/main/java/io/github/moulberry/notenoughupdates/util/HypixelApi.java +++ b/src/main/java/io/github/moulberry/notenoughupdates/util/HypixelApi.java @@ -6,12 +6,15 @@ import io.github.moulberry.notenoughupdates.NotEnoughUpdates; import org.apache.commons.io.IOUtils; import java.io.IOException; +import java.io.UnsupportedEncodingException; import java.net.ConnectException; import java.net.URL; import java.net.URLConnection; +import java.net.URLEncoder; import java.nio.charset.StandardCharsets; import java.util.HashMap; import java.util.Map; +import java.util.concurrent.CompletableFuture; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; import java.util.function.Consumer; @@ -27,12 +30,17 @@ public class HypixelApi { private final String[] myApiURLs = {"https://moulberry.codes/"};//, "http://moulberry.codes/", "http://51.79.51.21/"};//, "http://51.75.78.252/" }; private final Integer[] myApiSuccesses = {0, 0, 0, 0}; + public CompletableFuture getHypixelApiAsync(String apiKey, String method, HashMap args) { + return getApiAsync(generateApiUrl(apiKey, method, args)); + } + public void getHypixelApiAsync(String apiKey, String method, HashMap args, Consumer consumer) { - getHypixelApiAsync(apiKey, method, args, consumer, () -> {}); + getHypixelApiAsync(apiKey, method, args, consumer, () -> { + }); } public void getHypixelApiAsync(String apiKey, String method, HashMap args, Consumer consumer, Runnable error) { - getApiAsync(generateApiUrl(apiKey != null ? apiKey.trim() : null, method, args), consumer, error); + getApiAsync(generateApiUrl(apiKey, method, args), consumer, error); } private String getMyApiURL() { @@ -61,6 +69,18 @@ public class HypixelApi { } } + public CompletableFuture getApiAsync(String urlS) { + CompletableFuture result = new CompletableFuture<>(); + es.submit(() -> { + try { + result.complete(getApiSync(urlS)); + } catch (Exception e) { + result.completeExceptionally(e); + } + }); + return result; + } + public void getApiAsync(String urlS, Consumer consumer, Runnable error) { es.submit(() -> { try { @@ -134,16 +154,22 @@ public class HypixelApi { } public String generateApiUrl(String apiKey, String method, HashMap args) { - StringBuilder url = new StringBuilder("https://api.hypixel.net/" + method + (apiKey != null ? ("?key=" + apiKey.replace(" ", "")) : "")); + if (apiKey != null) + args.put("key", apiKey.trim().replace("-", "")); + StringBuilder url = new StringBuilder("https://api.hypixel.net/" + method); boolean first = true; for (Map.Entry entry : args.entrySet()) { - if (first && apiKey == null) { + if (first) { url.append("?"); first = false; } else { url.append("&"); } - url.append(entry.getKey()).append("=").append(entry.getValue()); + try { + url.append(URLEncoder.encode(entry.getKey(), StandardCharsets.UTF_8.name())).append("=") + .append(URLEncoder.encode(entry.getValue(), StandardCharsets.UTF_8.name())); + } catch (UnsupportedEncodingException e) { + } } return url.toString(); } diff --git a/src/main/java/io/github/moulberry/notenoughupdates/util/Utils.java b/src/main/java/io/github/moulberry/notenoughupdates/util/Utils.java index dc301db2..4a3e6400 100644 --- a/src/main/java/io/github/moulberry/notenoughupdates/util/Utils.java +++ b/src/main/java/io/github/moulberry/notenoughupdates/util/Utils.java @@ -7,6 +7,7 @@ import io.github.moulberry.notenoughupdates.NotEnoughUpdates; import io.github.moulberry.notenoughupdates.miscfeatures.SlotLocking; import net.minecraft.client.Minecraft; import net.minecraft.client.audio.PositionedSoundRecord; +import net.minecraft.client.entity.EntityPlayerSP; import net.minecraft.client.gui.FontRenderer; import net.minecraft.client.gui.ScaledResolution; import net.minecraft.client.gui.inventory.GuiContainer; @@ -28,6 +29,7 @@ import net.minecraft.item.ItemStack; import net.minecraft.nbt.NBTTagCompound; import net.minecraft.nbt.NBTTagList; import net.minecraft.nbt.NBTTagString; +import net.minecraft.network.play.client.C0DPacketCloseWindow; import net.minecraft.util.*; import net.minecraftforge.fml.common.Loader; import org.lwjgl.BufferUtils; @@ -44,8 +46,8 @@ import java.lang.reflect.Method; import java.nio.FloatBuffer; import java.nio.charset.StandardCharsets; import java.nio.file.Files; -import java.util.*; import java.util.List; +import java.util.*; import java.util.regex.Matcher; import java.util.regex.Pattern; @@ -472,7 +474,6 @@ public class Utils { //EnumChatFormatting.AQUA+EnumChatFormatting.BOLD.toString()+"DIVINE", }; - public static final HashMap rarityArrMap = new HashMap() {{ put("COMMON", rarityArrC[0]); put("UNCOMMON", rarityArrC[1]); @@ -1362,7 +1363,6 @@ public class Utils { return endsIn; } - public static void drawLine(float sx, float sy, float ex, float ey, int width, int color) { float f = (float) (color >> 24 & 255) / 255.0F; float f1 = (float) (color >> 16 & 255) / 255.0F; @@ -1395,7 +1395,7 @@ public class Utils { } public static void drawTexturedQuad(float x1, float y1, float x2, float y2, float x3, float y3, float x4, float y4, - float uMin, float uMax, float vMin, float vMax, int filter) { + float uMin, float uMax, float vMin, float vMax, int filter) { GlStateManager.enableTexture2D(); GlStateManager.enableBlend(); GlStateManager.tryBlendFuncSeparate(GL11.GL_SRC_ALPHA, GL11.GL_ONE_MINUS_SRC_ALPHA, GL11.GL_ONE, GL11.GL_ONE_MINUS_SRC_ALPHA); @@ -1426,4 +1426,34 @@ public class Utils { GlStateManager.disableBlend(); } + + public static boolean sendCloseScreenPacket() { + EntityPlayerSP thePlayer = Minecraft.getMinecraft().thePlayer; + if (thePlayer.openContainer == null) return false; + thePlayer.sendQueue.addToSendQueue(new C0DPacketCloseWindow( + thePlayer.openContainer.windowId)); + return true; + } + + public static String formatNumberWithDots(long number) { + if (number == 0) + return "0"; + String work = ""; + boolean isNegative = false; + if (number < 0) { + isNegative = true; + number = -number; + } + while (number != 0) { + work = String.format("%03d.%s", number % 1000, work); + number /= 1000; + } + work = work.substring(0, work.length() - 1); + while (work.startsWith("0")) + work = work.substring(1); + if (isNegative) + return "-" + work; + return work; + } + } diff --git a/src/main/resources/assets/notenoughupdates/textures/gui/forge_recipe.png b/src/main/resources/assets/notenoughupdates/textures/gui/forge_recipe.png new file mode 100644 index 00000000..2c3d2eb1 Binary files /dev/null and b/src/main/resources/assets/notenoughupdates/textures/gui/forge_recipe.png differ -- cgit From 0f3cfc259f89c22840b761931e238d699f17acc7 Mon Sep 17 00:00:00 2001 From: NopoTheGamer <40329022+NopoTheGamer@users.noreply.github.com> Date: Sun, 2 Jan 2022 09:07:24 +1100 Subject: Added custom wardrobe display for the new stuff they have put on the alpha (#36) * istg if you give me 170 commits i will end someone(added stranded pv icon + added an icon for gamemodes that neu doesnt know about) * Change the mines of divan waypoints to blue because it was hard to see the gold waypoint gold blocks everywhere * Added a custom armor stuff for the alpha content * Made it so it doesnt show if you dont have hide potion effects on * very cool and epic armor display (dont look at the code its bad) ((not finished)) * hello yes please test armor hud (finished but i will clean it up a lil) * clean up code + show thingy when no items cached + fix neu buttons placement + fixed crash * fixed neubutton placment but the fix works (i hope) * i see no reason for this to work outside skyblock soo * ery wanted it to be possible for an on texture to be different to an off texture in /neu * Added "Has Advanced Tab" to /neustats * Added "Has Advanced Tab" to /neustats * https://cdn.discordapp.com/attachments/896407218151366687/924981162714234900/unknown.png https://cdn.discordapp.com/attachments/896407218151366687/924981203319263232/unknown.png (fixed storage menu if you have new tab off) * tried to fix the gui being offset * Add a pet display for your inventory * tries to show your pet stats in the inv display * skyblock check * Fix texture * try to lower file size by unused assets * patch notes ! * remove some random code that wasnt doing anything * added a repo check to see if the wardrobe stuff has come out yet * fixed it showing wrong pet * fixed caching --- Update Notes/2.1.md | 10 +- .../notenoughupdates/NEUEventListener.java | 34 ++ .../moulberry/notenoughupdates/NEUManager.java | 2 +- .../moulberry/notenoughupdates/NEUOverlay.java | 367 ++++++++++++++++++++- .../notenoughupdates/commands/StatsCommand.java | 1 + .../notenoughupdates/core/GuiElementBoolean.java | 14 +- .../miscfeatures/PetInfoOverlay.java | 7 +- .../notenoughupdates/options/NEUConfig.java | 8 + .../options/seperateSections/PetOverlay.java | 18 + .../notenoughupdates/overlays/CustomArmour.java | 28 ++ .../profileviewer/ProfileViewer.java | 4 +- .../notenoughupdates/util/GuiTextures.java | 4 + .../moulberry/notenoughupdates/util/SBInfo.java | 3 + .../notenoughupdates/armordisplay/armordisplay.png | Bin 0 -> 1599 bytes .../armordisplay/armordisplay_fsr.png | Bin 0 -> 267 bytes .../armordisplay/armordisplay_grey.png | Bin 0 -> 270 bytes .../armordisplay/armordisplay_phq_dark.png | Bin 0 -> 258 bytes .../armordisplay/armordisplay_transparent.png | Bin 0 -> 225 bytes .../armordisplay/armordisplay_transparent_pet.png | Bin 0 -> 1500 bytes .../assets/notenoughupdates/collectionlog.png | Bin 12083 -> 0 bytes .../assets/notenoughupdates/core/bar_1.png | Bin 0 -> 2095 bytes .../assets/notenoughupdates/core/bar_2.png | Bin 0 -> 2095 bytes .../assets/notenoughupdates/core/bar_3.png | Bin 0 -> 2095 bytes .../assets/notenoughupdates/core/bar_on.png | Bin 0 -> 2095 bytes .../assets/notenoughupdates/groundplane.png | Bin 40868 -> 0 bytes .../petdisplay/petdisplayarmor.png | Bin 0 -> 229 bytes .../petdisplay/petdisplayarmor_dark.png | Bin 0 -> 1738 bytes .../petdisplay/petdisplayarmor_fsr.png | Bin 0 -> 1734 bytes .../petdisplay/petdisplayarmor_phqdark.png | Bin 0 -> 1728 bytes .../petdisplay/petdisplayarmor_transparent.png | Bin 0 -> 1890 bytes .../notenoughupdates/petdisplay/petdisplaysolo.png | Bin 0 -> 1743 bytes .../petdisplay/petdisplaysolo_dark.png | Bin 0 -> 1545 bytes .../petdisplay/petdisplaysolo_fsr.png | Bin 0 -> 1548 bytes .../petdisplay/petdisplaysolo_phqdark.png | Bin 0 -> 1537 bytes .../petdisplay/petdisplaysolo_transparent.png | Bin 0 -> 1720 bytes .../portal_panoramas/nether/pansc-1.png | Bin 82574 -> 0 bytes .../portal_panoramas/nether/pansc-2.png | Bin 1228306 -> 0 bytes .../portal_panoramas/nether/pansc-3.png | Bin 646267 -> 0 bytes .../portal_panoramas/nether/pansc-4.png | Bin 668239 -> 0 bytes .../portal_panoramas/nether/pansc-5.png | Bin 531635 -> 0 bytes .../portal_panoramas/nether/pansc-6.png | Bin 275559 -> 0 bytes .../assets/notenoughupdates/ss_border.jpg | Bin 14021 -> 0 bytes 42 files changed, 490 insertions(+), 10 deletions(-) create mode 100644 src/main/java/io/github/moulberry/notenoughupdates/overlays/CustomArmour.java create mode 100644 src/main/resources/assets/notenoughupdates/armordisplay/armordisplay.png create mode 100644 src/main/resources/assets/notenoughupdates/armordisplay/armordisplay_fsr.png create mode 100644 src/main/resources/assets/notenoughupdates/armordisplay/armordisplay_grey.png create mode 100644 src/main/resources/assets/notenoughupdates/armordisplay/armordisplay_phq_dark.png create mode 100644 src/main/resources/assets/notenoughupdates/armordisplay/armordisplay_transparent.png create mode 100644 src/main/resources/assets/notenoughupdates/armordisplay/armordisplay_transparent_pet.png delete mode 100644 src/main/resources/assets/notenoughupdates/collectionlog.png create mode 100644 src/main/resources/assets/notenoughupdates/core/bar_1.png create mode 100644 src/main/resources/assets/notenoughupdates/core/bar_2.png create mode 100644 src/main/resources/assets/notenoughupdates/core/bar_3.png create mode 100644 src/main/resources/assets/notenoughupdates/core/bar_on.png delete mode 100644 src/main/resources/assets/notenoughupdates/groundplane.png create mode 100644 src/main/resources/assets/notenoughupdates/petdisplay/petdisplayarmor.png create mode 100644 src/main/resources/assets/notenoughupdates/petdisplay/petdisplayarmor_dark.png create mode 100644 src/main/resources/assets/notenoughupdates/petdisplay/petdisplayarmor_fsr.png create mode 100644 src/main/resources/assets/notenoughupdates/petdisplay/petdisplayarmor_phqdark.png create mode 100644 src/main/resources/assets/notenoughupdates/petdisplay/petdisplayarmor_transparent.png create mode 100644 src/main/resources/assets/notenoughupdates/petdisplay/petdisplaysolo.png create mode 100644 src/main/resources/assets/notenoughupdates/petdisplay/petdisplaysolo_dark.png create mode 100644 src/main/resources/assets/notenoughupdates/petdisplay/petdisplaysolo_fsr.png create mode 100644 src/main/resources/assets/notenoughupdates/petdisplay/petdisplaysolo_phqdark.png create mode 100644 src/main/resources/assets/notenoughupdates/petdisplay/petdisplaysolo_transparent.png delete mode 100644 src/main/resources/assets/notenoughupdates/portal_panoramas/nether/pansc-1.png delete mode 100644 src/main/resources/assets/notenoughupdates/portal_panoramas/nether/pansc-2.png delete mode 100644 src/main/resources/assets/notenoughupdates/portal_panoramas/nether/pansc-3.png delete mode 100644 src/main/resources/assets/notenoughupdates/portal_panoramas/nether/pansc-4.png delete mode 100644 src/main/resources/assets/notenoughupdates/portal_panoramas/nether/pansc-5.png delete mode 100644 src/main/resources/assets/notenoughupdates/portal_panoramas/nether/pansc-6.png delete mode 100644 src/main/resources/assets/notenoughupdates/ss_border.jpg (limited to 'src/main/resources/assets') diff --git a/Update Notes/2.1.md b/Update Notes/2.1.md index b5cad116..85a6907a 100644 --- a/Update Notes/2.1.md +++ b/Update Notes/2.1.md @@ -10,6 +10,8 @@ - Added blocking clicks back to the enchanting minigames (because apparently its not bannable?) - [Donpireso replied to an sba dev's email about some of sba features and it seems to imply that blocking clicks in guis arent bannable](https://cdn.discordapp.com/attachments/823769568933576764/906101631861526559/unknown.png) - Fixed pet overlay not updating when going into /pets +- [Added an armor overlay for the new armor slots](https://cdn.discordapp.com/attachments/832652653292027904/922399046528794634/unknown.png) +- Added a pet overlay that shows your active pet in your inventory ### **Minor Changes:** - Add built-in recipes for forge crafts - nea89 - Make cata xp in /pv be calculated on how many runs you have and shows master mode xp rates @@ -38,10 +40,13 @@ - Turns off inv search mode after 2 minutes - Made /neustats modlist show normal /neustats if under 15 mods - Added max enchant book to /neuec - Dokm -- [Added bingo profile icon to /pv](https://cdn.discordapp.com/attachments/832652653292027904/915844465372065842/unknown.png) +- [Added bingo and Stranded profile icons to /pv](https://cdn.discordapp.com/attachments/832652653292027904/915844465372065842/unknown.png) +- Added an icon if neu doesnt know about a gamemode in /pv - Fixed pet overlay not resetting pet when making new profile - Added a warning in the tooltip when price info couldn't be found/is outdated - Lulonaut +- Added "Has Advanced Tab" to /neustats - Added custom runes and crab hat system - jani +- Removed unused textures - Added total xp if player is above cata 50 in /pv - efefury - Added daily powder to todo overlay - efefury - Added a way to include kismet feather to profit calculator - efefury @@ -70,6 +75,7 @@ - Moved the help icon in /neucustomize over a little - Added dg partner cape - Changed custom_enchant_gui.png to remove top right button +- Added 4 new textures for the on/off switches in /neu - Code Cleanup - IRONM00N ### **Previous change log** -https://github.com/NotEnoughUpdates/NotEnoughUpdates/blob/master/Update%20Notes/2.0-Pre31-Release.md +https://github.com/NotEnoughUpdates/NotEnoughUpdates/blob/master/Update%20Notes/2.0-Pre31-Release.md \ No newline at end of file diff --git a/src/main/java/io/github/moulberry/notenoughupdates/NEUEventListener.java b/src/main/java/io/github/moulberry/notenoughupdates/NEUEventListener.java index 99a48a36..6d2904be 100644 --- a/src/main/java/io/github/moulberry/notenoughupdates/NEUEventListener.java +++ b/src/main/java/io/github/moulberry/notenoughupdates/NEUEventListener.java @@ -843,6 +843,10 @@ public class NEUEventListener { Minecraft.getMinecraft().thePlayer.addChatMessage(new ChatComponentText(EnumChatFormatting.YELLOW + "[NEU] API Key automatically configured")); NotEnoughUpdates.INSTANCE.config.apiKey.apiKey = NotEnoughUpdates.INSTANCE.config.apiKey.apiKey.substring(0, 36); + } else if (unformatted.startsWith("Player List Info is now disabled!")) { + SBInfo.getInstance().hasNewTab = false; + } else if (unformatted.startsWith("Player List Info is now enabled!")) { + SBInfo.getInstance().hasNewTab = true; } if (e.message.getFormattedText().equals(EnumChatFormatting.RESET.toString() + EnumChatFormatting.RED + "You haven't unlocked this recipe!" + EnumChatFormatting.RESET)) { @@ -1080,6 +1084,16 @@ public class NEUEventListener { x += 80 + 28; } } + if (NEUOverlay.isRenderingArmorHud()) { + if (x < guiLeft + xSize - 150 && x > guiLeft + xSize - 200 && y > guiTop && y < guiTop + 84) { + x -= 25; + } + } + if (NEUOverlay.isRenderingPetHud()) { + if (x < guiLeft + xSize - 150 && x > guiLeft + xSize - 200 && y > guiTop + 60 && y < guiTop + 120) { + x -= 25; + } + } GlStateManager.color(1, 1, 1, 1f); @@ -1191,6 +1205,16 @@ public class NEUEventListener { x += 80 + 28; } } + if (NEUOverlay.isRenderingArmorHud()) { + if (x < guiLeft + xSize - 150 && x > guiLeft + xSize - 200 && y > guiTop && y < guiTop + 84) { + x -= 25; + } + } + if (NEUOverlay.isRenderingPetHud()) { + if (x < guiLeft + xSize - 150 && x > guiLeft + xSize - 200 && y > guiTop + 60 && y < guiTop + 120) { + x -= 25; + } + } if (x - guiLeft >= 85 && x - guiLeft <= 115 && y - guiTop >= 4 && y - guiTop <= 25) { disableCraftingText = true; @@ -1565,6 +1589,16 @@ public class NEUEventListener { x += 80 + 28; } } + if (NEUOverlay.isRenderingArmorHud()) { + if (x < guiLeft + xSize - 150 && x > guiLeft + xSize - 200 && y > guiTop && y < guiTop + 84) { + x -= 25; + } + } + if (NEUOverlay.isRenderingPetHud()) { + if (x < guiLeft + xSize - 150 && x > guiLeft + xSize - 200 && y > guiTop + 60 && y < guiTop + 120) { + x -= 25; + } + } if (mouseX >= x && mouseX <= x + 18 && mouseY >= y && mouseY <= y + 18) { if (Minecraft.getMinecraft().thePlayer.inventory.getItemStack() == null) { diff --git a/src/main/java/io/github/moulberry/notenoughupdates/NEUManager.java b/src/main/java/io/github/moulberry/notenoughupdates/NEUManager.java index 064b1fa7..b3d13351 100644 --- a/src/main/java/io/github/moulberry/notenoughupdates/NEUManager.java +++ b/src/main/java/io/github/moulberry/notenoughupdates/NEUManager.java @@ -96,7 +96,7 @@ public class NEUManager { } public void setCurrentProfile(String currentProfile) { - this.currentProfile = currentProfile; + SBInfo.getInstance().currentProfile = currentProfile; } public String getCurrentProfile() { diff --git a/src/main/java/io/github/moulberry/notenoughupdates/NEUOverlay.java b/src/main/java/io/github/moulberry/notenoughupdates/NEUOverlay.java index acc15e8d..ca8a48d8 100644 --- a/src/main/java/io/github/moulberry/notenoughupdates/NEUOverlay.java +++ b/src/main/java/io/github/moulberry/notenoughupdates/NEUOverlay.java @@ -16,6 +16,7 @@ import io.github.moulberry.notenoughupdates.mbgui.MBAnchorPoint; import io.github.moulberry.notenoughupdates.mbgui.MBGuiElement; import io.github.moulberry.notenoughupdates.mbgui.MBGuiGroupAligned; import io.github.moulberry.notenoughupdates.mbgui.MBGuiGroupFloating; +import io.github.moulberry.notenoughupdates.miscfeatures.PetInfoOverlay; import io.github.moulberry.notenoughupdates.miscfeatures.SunTzu; import io.github.moulberry.notenoughupdates.miscgui.GuiPriceGraph; import io.github.moulberry.notenoughupdates.options.NEUConfigEditor; @@ -26,8 +27,11 @@ import io.github.moulberry.notenoughupdates.util.Utils; import net.minecraft.client.Minecraft; import net.minecraft.client.gui.FontRenderer; import net.minecraft.client.gui.Gui; +import net.minecraft.client.gui.GuiScreen; import net.minecraft.client.gui.GuiTextField; +import net.minecraft.client.gui.inventory.GuiChest; import net.minecraft.client.gui.inventory.GuiContainer; +import net.minecraft.client.gui.inventory.GuiInventory; import net.minecraft.client.renderer.*; import net.minecraft.client.renderer.block.model.BakedQuad; import net.minecraft.client.renderer.entity.RenderManager; @@ -39,6 +43,8 @@ import net.minecraft.entity.Entity; import net.minecraft.entity.EntityList; import net.minecraft.entity.EntityLivingBase; import net.minecraft.init.Items; +import net.minecraft.inventory.ContainerChest; +import net.minecraft.inventory.IInventory; import net.minecraft.inventory.Slot; import net.minecraft.item.Item; import net.minecraft.item.ItemStack; @@ -73,6 +79,33 @@ public class NEUOverlay extends Gui { private static final ResourceLocation SEARCH_BAR = new ResourceLocation("notenoughupdates:search_bar.png"); private static final ResourceLocation SEARCH_BAR_GOLD = new ResourceLocation("notenoughupdates:search_bar_gold.png"); + private static final ResourceLocation ARMOR_DISPLAY = new ResourceLocation("notenoughupdates:armordisplay/armordisplay.png"); + private static final ResourceLocation ARMOR_DISPLAY_GREY = new ResourceLocation("notenoughupdates:armordisplay/armordisplay_grey.png"); + private static final ResourceLocation ARMOR_DISPLAY_DARK = new ResourceLocation("notenoughupdates:armordisplay/armordisplay_phq_dark.png"); + private static final ResourceLocation ARMOR_DISPLAY_FSR = new ResourceLocation("notenoughupdates:armordisplay/armordisplay_fsr.png"); + private static final ResourceLocation ARMOR_DISPLAY_TRANSPARENT = new ResourceLocation("notenoughupdates:armordisplay/armordisplay_transparent.png"); + private static final ResourceLocation ARMOR_DISPLAY_TRANSPARENT_PET = new ResourceLocation("notenoughupdates:armordisplay/armordisplay_transparent_pet.png"); + + private static final ResourceLocation QUESTION_MARK = new ResourceLocation("notenoughupdates:pv_unknown.png"); + + private static final ResourceLocation PET_DISPLAY = new ResourceLocation("notenoughupdates:petdisplay/petdisplaysolo.png"); + private static final ResourceLocation PET_DISPLAY_GREY = new ResourceLocation("notenoughupdates:petdisplay/petdisplaysolo_dark.png"); + private static final ResourceLocation PET_DISPLAY_DARK = new ResourceLocation("notenoughupdates:petdisplay/petdisplaysolo_phqdark.png"); + private static final ResourceLocation PET_DISPLAY_FSR = new ResourceLocation("notenoughupdates:petdisplay/petdisplaysolo_fsr.png"); + private static final ResourceLocation PET_DISPLAY_TRANSPARENT = new ResourceLocation("notenoughupdates:petdisplay/petdisplaysolo_transparent.png"); + + + private static final ResourceLocation PET_ARMOR_DISPLAY = new ResourceLocation("notenoughupdates:petdisplay/petdisplayarmor.png"); + private static final ResourceLocation PET_ARMOR_DISPLAY_GREY = new ResourceLocation("notenoughupdates:petdisplay/petdisplayarmor_dark.png"); + private static final ResourceLocation PET_ARMOR_DISPLAY_DARK = new ResourceLocation("notenoughupdates:petdisplay/petdisplayarmor_phqdark.png"); + private static final ResourceLocation PET_ARMOR_DISPLAY_FSR = new ResourceLocation("notenoughupdates:petdisplay/petdisplayarmor_fsr.png"); + private static final ResourceLocation PET_ARMOR_DISPLAY_TRANSPARENT = new ResourceLocation("notenoughupdates:petdisplay/petdisplayarmor_transparent.png"); + + private static boolean renderingArmorHud; + private static boolean renderingPetHud; + public static boolean shouldUseCachedPet; + public static long cachedPetTimer; + private final NEUManager manager; private final String mobRegex = ".*?((_MONSTER)|(_ANIMAL)|(_MINIBOSS)|(_BOSS)|(_SC))$"; @@ -1656,13 +1689,174 @@ public class NEUOverlay extends Gui { int guiScaleLast = 0; private boolean showVanillaLast = false; + private boolean wardrobeOpen = false; + private boolean isInNamedGui(String guiName) { + GuiScreen guiScreen = Minecraft.getMinecraft().currentScreen; + if (guiScreen instanceof GuiChest) { + GuiChest chest = (GuiChest) Minecraft.getMinecraft().currentScreen; + ContainerChest container = (ContainerChest) chest.inventorySlots; + IInventory lower = container.getLowerChestInventory(); + String containerName = lower.getDisplayName().getUnformattedText(); + if (containerName.contains(guiName)) { + wardrobeOpen = true; + } else wardrobeOpen = false; + } + if (guiScreen instanceof GuiInventory) { + wardrobeOpen = false; + } + return wardrobeOpen; + } + private int wardrobePage = -1; + private int getWardrobePage () { + GuiScreen guiScreen = Minecraft.getMinecraft().currentScreen; + if (guiScreen instanceof GuiChest) { + if (isInNamedGui("Wardrobe")) { + GuiChest chest = (GuiChest) Minecraft.getMinecraft().currentScreen; + ContainerChest container = (ContainerChest) chest.inventorySlots; + IInventory lower = container.getLowerChestInventory(); + String containerName = lower.getDisplayName().getUnformattedText(); + try { + wardrobePage = Integer.parseInt(containerName.substring(10, 11)); + } catch (NumberFormatException e) { + System.out.println(containerName.charAt(10)); + System.out.println("Did hypixel change the wardrobe string?"); + wardrobePage = -1; + } + } else wardrobePage = -1; + } + return wardrobePage; + } + private int petPage = -1; + private int getPetPage () { + GuiScreen guiScreen = Minecraft.getMinecraft().currentScreen; + if (guiScreen instanceof GuiChest) { + if (isInNamedGui("Pets")) { + GuiChest chest = (GuiChest) Minecraft.getMinecraft().currentScreen; + ContainerChest container = (ContainerChest) chest.inventorySlots; + IInventory lower = container.getLowerChestInventory(); + String containerName = lower.getDisplayName().getUnformattedText(); + try { + petPage = Integer.parseInt(containerName.substring(1, 2)); + } catch (NumberFormatException e) { + petPage = 1; + } + } else petPage = -1; + } + return petPage; + } + private ItemStack getChestSlotsAsItemStack(int slot) { + GuiScreen guiScreen = Minecraft.getMinecraft().currentScreen; + if (guiScreen instanceof GuiChest) { + GuiChest chest = (GuiChest) Minecraft.getMinecraft().currentScreen; + return chest.inventorySlots.getSlot(slot).getStack(); + } else { + return null; + } + } + private int selectedArmor = 9; + private int getEquippedArmor() { + if (isInNamedGui("Wardrobe")) { + ItemStack nullTest1 = getChestSlotsAsItemStack(8); + ItemStack nullTest2 = getChestSlotsAsItemStack(17); + ItemStack nullTest3 = getChestSlotsAsItemStack(26); + ItemStack nullTest4 = getChestSlotsAsItemStack(35); + ItemStack nullTest5 = getChestSlotsAsItemStack(44); + if (nullTest1 != null || nullTest2 != null || nullTest3 != null || nullTest4 != null || nullTest5 != null) { + selectedArmor = 9; + } + for (int ii = 1; ii < 5; ii++) { + if (ii == 1 || selectedArmor == 9) { + if (getWardrobePage() == ii) { + for (int i = 8; i < 54; i += 9) { + ItemStack stack1 = getChestSlotsAsItemStack(i); + if (stack1 != null) { + String[] lore1 = NotEnoughUpdates.INSTANCE.manager.getLoreFromNBT(stack1.getTagCompound()); + for (String line : lore1) { + //System.out.println(line); + if (line.contains("to unequip this armor")) { + selectedArmor = i; + break; + } + } + } + } + } + } + } + } + return selectedArmor; + } + + private int selectedPet = 0; + private int getEquippedPet() { + if (isInNamedGui("Pets")) { + for (int ii = 1; ii < 3; ii++) { + if (ii == 1 || selectedPet == 0) { + if (getPetPage() == ii) { + for (int i = 0; i < 54; i ++) { + ItemStack stack1 = getChestSlotsAsItemStack(i); + if (stack1 != null) { + String[] lore1 = NotEnoughUpdates.INSTANCE.manager.getLoreFromNBT(stack1.getTagCompound()); + for (String line : lore1) { + //System.out.println(line); + if (line.contains("\u00a77\u00a7cClick to despawn.")) { + selectedPet = i; + shouldUseCachedPet = true; + } + } + } else { + shouldUseCachedPet = false; + } + } + } + } + } + } + return selectedPet; + } + + private ItemStack getWardrobeSlot(int armourSlot) { + if (isInNamedGui("Wardrobe")) { + if (getChestSlotsAsItemStack(getEquippedArmor() - armourSlot) != null && getEquippedArmor() != 9) { + return getChestSlotsAsItemStack(getEquippedArmor() - armourSlot); + } else return null; + } else return null; + } + + public boolean isWardrobeSystemOnMainServer() { + JsonElement alphaWardrobeElement = Utils.getElement( Constants.DISABLE, "wardrobeFeature"); + if (alphaWardrobeElement == null || !alphaWardrobeElement.isJsonObject()) { + return true; + } + JsonObject isWardrobe = alphaWardrobeElement.getAsJsonObject(); + if (isWardrobe.has("enableNewWardrob")) { + return isWardrobe.get("enableNewWardrob").getAsBoolean(); + } else { + return true; + } + } + + public ItemStack slot1 = null; + public ItemStack slot2 = null; + public ItemStack slot3 = null; + public ItemStack slot4 = null; + public ItemStack petSlot = null; + public ItemStack petSlot2 = null; + public static boolean isRenderingArmorHud() { + return renderingArmorHud; + } + public static boolean isRenderingPetHud() { + return renderingPetHud; + } /** - * Renders the search bar, quick commands, item selection (right) and item info (left) gui elements. + * Renders the search bar, quick commands, item selection (right), item info (left) and armor hud gui elements. */ public void render(boolean hoverInv) { if (disabled) { return; } + renderingArmorHud = false; + renderingPetHud = false; GlStateManager.enableDepth(); FontRenderer fr = Minecraft.getMinecraft().fontRendererObj; @@ -1686,6 +1880,177 @@ public class NEUOverlay extends Gui { Utils.drawTexturedRect((width - 64) / 2f, (height - 64) / 2f - 114, 64, 64, GL11.GL_LINEAR); GlStateManager.bindTexture(0); } + GuiScreen guiScreen = Minecraft.getMinecraft().currentScreen; + + if (NotEnoughUpdates.INSTANCE.config.customArmour.enableArmourHud && NotEnoughUpdates.INSTANCE.config.misc.hidePotionEffect + && NotEnoughUpdates.INSTANCE.hasSkyblockScoreboard() && isWardrobeSystemOnMainServer()) { + if (getWardrobeSlot(1) != null) { + slot1 = getWardrobeSlot(4); + slot2 = getWardrobeSlot(3); + slot3 = getWardrobeSlot(2); + slot4 = getWardrobeSlot(1); + } + if (guiScreen instanceof GuiInventory) { + renderingArmorHud = true; + selectedArmor = 9; + + List tooltipToDisplay = null; + if (NotEnoughUpdates.INSTANCE.config.customArmour.colourStyle == 0) { + Minecraft.getMinecraft().getTextureManager().bindTexture(ARMOR_DISPLAY); + } + if (NotEnoughUpdates.INSTANCE.config.customArmour.colourStyle == 1) { + Minecraft.getMinecraft().getTextureManager().bindTexture(ARMOR_DISPLAY_GREY); + } + if (NotEnoughUpdates.INSTANCE.config.customArmour.colourStyle == 2) { + Minecraft.getMinecraft().getTextureManager().bindTexture(ARMOR_DISPLAY_DARK); + } + if (NotEnoughUpdates.INSTANCE.config.customArmour.colourStyle == 3) { + if (NotEnoughUpdates.INSTANCE.config.petOverlay.colourStyle == 3 && NotEnoughUpdates.INSTANCE.config.petOverlay.petInvDisplay) { + Minecraft.getMinecraft().getTextureManager().bindTexture(ARMOR_DISPLAY_TRANSPARENT_PET); + } else { + Minecraft.getMinecraft().getTextureManager().bindTexture(ARMOR_DISPLAY_TRANSPARENT); + } + } + if (NotEnoughUpdates.INSTANCE.config.customArmour.colourStyle == 4) { + Minecraft.getMinecraft().getTextureManager().bindTexture(ARMOR_DISPLAY_FSR); + } + + GlStateManager.color(1, 1, 1, 1); + GL11.glTranslatef(0, 0, 80); + float yNumber = (float) (height - 167) / 2f; + Utils.drawTexturedRect((float) ((width - 224.1) / 2f), yNumber, 31, 86, GL11.GL_NEAREST); + GlStateManager.bindTexture(0); + + Utils.drawItemStack(slot1, (int) ((width - 208) / 2f), (int) ((height + 60) / 2f - 105)); + Utils.drawItemStack(slot2, (int) ((width - 208) / 2f), (int) ((height + 60) / 2f - 105) + 18); + Utils.drawItemStack(slot3, (int) ((width - 208) / 2f), (int) ((height + 60) / 2f - 105) + 36); + Utils.drawItemStack(slot4, (int) ((width - 208) / 2f), (int) ((height + 60) / 2f - 105) + 54); + if (slot1 == null) { + Minecraft.getMinecraft().getTextureManager().bindTexture(QUESTION_MARK); + GlStateManager.color(1, 1, 1, 1); + GL11.glTranslatef(0, 0, 100); + Utils.drawTexturedRect(((width - 208) / 2f), ((height + 60) / 2f - 105), 16, 16, GL11.GL_NEAREST); + GlStateManager.bindTexture(0); + + tooltipToDisplay = Lists.newArrayList( + EnumChatFormatting.RED+"Warning", + EnumChatFormatting.GREEN+"You need to open /wardrobe", + EnumChatFormatting.GREEN+"To cache your armour" + ); + if (mouseX >= ((width - 208) / 2f) && mouseX < ((width - 208) / 2f) + 16) { + //top slot + if (mouseY >= ((height + 60) / 2f - 105) && mouseY <= ((height + 60) / 2f - 105) + 16) { + Utils.drawHoveringText(tooltipToDisplay, mouseX, mouseY, width, height, -1, fr); + } + } + + } + if (slot1 != null && slot2 != null && slot3 != null && slot4 != null) { + if (mouseX >= ((width - 208) / 2f) && mouseX < ((width - 208) / 2f) + 16) { + //top slot + if (mouseY >= ((height + 60) / 2f - 105) && mouseY <= ((height + 60) / 2f - 105) + 16) { + tooltipToDisplay = slot1.getTooltip(Minecraft.getMinecraft().thePlayer, false); + Utils.drawHoveringText(tooltipToDisplay, mouseX, mouseY, width, height, -1, fr); + tooltipToDisplay = null; + GL11.glTranslatef(0, 0, -80); + } + if (mouseY >= ((height + 60) / 2f - 105) + 18 && mouseY <= ((height + 60) / 2f - 105) + 34) { + tooltipToDisplay = slot2.getTooltip(Minecraft.getMinecraft().thePlayer, false); + Utils.drawHoveringText(tooltipToDisplay, mouseX, mouseY, width, height, -1, fr); + tooltipToDisplay = null; + GL11.glTranslatef(0, 0, -80); + } + if (mouseY >= ((height + 60) / 2f - 105) + 36 && mouseY <= ((height + 60) / 2f - 105) + 52) { + tooltipToDisplay = slot3.getTooltip(Minecraft.getMinecraft().thePlayer, false); + Utils.drawHoveringText(tooltipToDisplay, mouseX, mouseY, width, height, -1, fr); + tooltipToDisplay = null; + GL11.glTranslatef(0, 0, -80); + } + if (mouseY >= ((height + 60) / 2f - 105) + 54 && mouseY <= ((height + 60) / 2f - 105) + 70) { + tooltipToDisplay = slot4.getTooltip(Minecraft.getMinecraft().thePlayer, false); + Utils.drawHoveringText(tooltipToDisplay, mouseX, mouseY, width, height, -1, fr); + tooltipToDisplay = null; + GL11.glTranslatef(0, 0, -80); + } + } + GL11.glTranslatef(0, 0, -80); + } + } + } + if (PetInfoOverlay.getCurrentPet() != null) { + if (NotEnoughUpdates.INSTANCE.config.petOverlay.petInvDisplay + && NotEnoughUpdates.INSTANCE.manager.jsonToStack(NotEnoughUpdates.INSTANCE.manager.getItemInformation().get(PetInfoOverlay.getCurrentPet().petType + ";" + PetInfoOverlay.getCurrentPet().rarity.petId)).hasDisplayName() + && NotEnoughUpdates.INSTANCE.config.misc.hidePotionEffect && NotEnoughUpdates.INSTANCE.hasSkyblockScoreboard()) { + petSlot = NotEnoughUpdates.INSTANCE.manager.jsonToStack( + NotEnoughUpdates.INSTANCE.manager.getItemInformation().get( + PetInfoOverlay.getCurrentPet().petType + ";" + PetInfoOverlay.getCurrentPet().rarity.petId)); + if (isInNamedGui("Pets")) { + petSlot2 = getChestSlotsAsItemStack(getEquippedPet()); + } + ItemStack petInfo = null; + + if (shouldUseCachedPet) { + petInfo = petSlot2; + } else { + petInfo = petSlot; + } + if (guiScreen instanceof GuiInventory) { + GL11.glTranslatef(0, 0, 80); + if (!NotEnoughUpdates.INSTANCE.config.customArmour.enableArmourHud || !isWardrobeSystemOnMainServer()) { + if (NotEnoughUpdates.INSTANCE.config.petOverlay.colourStyle == 0) { + Minecraft.getMinecraft().getTextureManager().bindTexture(PET_DISPLAY); + } + if (NotEnoughUpdates.INSTANCE.config.petOverlay.colourStyle == 1) { + Minecraft.getMinecraft().getTextureManager().bindTexture(PET_DISPLAY_GREY); + } + if (NotEnoughUpdates.INSTANCE.config.petOverlay.colourStyle == 2) { + Minecraft.getMinecraft().getTextureManager().bindTexture(PET_DISPLAY_DARK); + } + if (NotEnoughUpdates.INSTANCE.config.petOverlay.colourStyle == 3) { + Minecraft.getMinecraft().getTextureManager().bindTexture(PET_DISPLAY_TRANSPARENT); + } + if (NotEnoughUpdates.INSTANCE.config.petOverlay.colourStyle == 4) { + Minecraft.getMinecraft().getTextureManager().bindTexture(PET_DISPLAY_FSR); + } + } else { + if (NotEnoughUpdates.INSTANCE.config.petOverlay.colourStyle == 0) { + Minecraft.getMinecraft().getTextureManager().bindTexture(PET_ARMOR_DISPLAY); + } + if (NotEnoughUpdates.INSTANCE.config.petOverlay.colourStyle == 1) { + Minecraft.getMinecraft().getTextureManager().bindTexture(PET_ARMOR_DISPLAY_GREY); + } + if (NotEnoughUpdates.INSTANCE.config.petOverlay.colourStyle == 2) { + Minecraft.getMinecraft().getTextureManager().bindTexture(PET_ARMOR_DISPLAY_DARK); + } + if (NotEnoughUpdates.INSTANCE.config.petOverlay.colourStyle == 3) { + Minecraft.getMinecraft().getTextureManager().bindTexture(PET_ARMOR_DISPLAY_TRANSPARENT); + } + if (NotEnoughUpdates.INSTANCE.config.petOverlay.colourStyle == 4) { + Minecraft.getMinecraft().getTextureManager().bindTexture(PET_ARMOR_DISPLAY_FSR); + } + } + + GlStateManager.color(1, 1, 1, 1); + float yNumber = (float) (height - 23) / 2f; + Utils.drawTexturedRect((float) ((width - 224.1) / 2f), yNumber, 31, 32, GL11.GL_NEAREST); + GlStateManager.bindTexture(0); + + Utils.drawItemStack(petInfo, (int) ((width - 208) / 2f), (int) ((height + 60) / 2f - 105) + 72); + renderingPetHud = true; + List tooltipToDisplay = null; + if (petInfo != null) { + if (mouseX >= ((width - 208) / 2f) && mouseX < ((width - 208) / 2f) + 16) { + if (mouseY >= ((height + 60) / 2f - 105) + 72 && mouseY <= ((height + 60) / 2f - 105) + 88) { + tooltipToDisplay = petInfo.getTooltip(Minecraft.getMinecraft().thePlayer, false); + Utils.drawHoveringText(tooltipToDisplay, mouseX, mouseY, width, height, -1, fr); + tooltipToDisplay = null; + GL11.glTranslatef(0, 0, -80); + } + } + } + } + } + } SunTzu.setEnabled(textField.getText().toLowerCase().startsWith("potato")); diff --git a/src/main/java/io/github/moulberry/notenoughupdates/commands/StatsCommand.java b/src/main/java/io/github/moulberry/notenoughupdates/commands/StatsCommand.java index 99bfe368..525e8aea 100644 --- a/src/main/java/io/github/moulberry/notenoughupdates/commands/StatsCommand.java +++ b/src/main/java/io/github/moulberry/notenoughupdates/commands/StatsCommand.java @@ -122,6 +122,7 @@ public class StatsCommand extends ClientCommandBase { builder.append("On Skyblock", NotEnoughUpdates.INSTANCE.hasSkyblockScoreboard() ? "TRUE" : "FALSE"); builder.append("Mod Version", Loader.instance().getIndexedModList().get(NotEnoughUpdates.MODID).getSource().getName()); builder.append("SB Profile", SBInfo.getInstance().currentProfile); + builder.append("Has Advanced Tab", SBInfo.getInstance().hasNewTab ? "TRUE" : "FALSE"); builder.category("Repo Stats"); builder.append("Last Commit", NotEnoughUpdates.INSTANCE.manager.latestRepoCommit); builder.append("Loaded Items", String.valueOf(NotEnoughUpdates.INSTANCE.manager.getItemInformation().size())); diff --git a/src/main/java/io/github/moulberry/notenoughupdates/core/GuiElementBoolean.java b/src/main/java/io/github/moulberry/notenoughupdates/core/GuiElementBoolean.java index be13e410..0936fb93 100644 --- a/src/main/java/io/github/moulberry/notenoughupdates/core/GuiElementBoolean.java +++ b/src/main/java/io/github/moulberry/notenoughupdates/core/GuiElementBoolean.java @@ -7,6 +7,7 @@ import net.minecraft.client.Minecraft; import net.minecraft.client.renderer.GlStateManager; import net.minecraft.util.ResourceLocation; import org.lwjgl.input.Mouse; +import org.lwjgl.opengl.GL11; import java.util.function.Consumer; @@ -43,10 +44,8 @@ public class GuiElementBoolean extends GuiElement { @Override public void render() { GlStateManager.color(1, 1, 1, 1); - Minecraft.getMinecraft().getTextureManager().bindTexture(GuiTextures.BAR); - RenderUtils.drawTexturedRect(x, y, xSize, ySize); - ResourceLocation buttonLoc = GuiTextures.ON; + ResourceLocation barLoc = GuiTextures.BAR_ON; long currentMillis = System.currentTimeMillis(); long deltaMillis = currentMillis - lastMillis; lastMillis = currentMillis; @@ -83,16 +82,25 @@ public class GuiElementBoolean extends GuiElement { int animation = (int) (LerpUtils.sigmoidZeroOne(this.animation / 36f) * 36); if (animation < 3) { buttonLoc = GuiTextures.OFF; + barLoc = GuiTextures.BAR; } else if (animation < 13) { buttonLoc = GuiTextures.ONE; + barLoc = GuiTextures.BAR_ONE; } else if (animation < 23) { buttonLoc = GuiTextures.TWO; + barLoc = GuiTextures.BAR_TWO; } else if (animation < 33) { buttonLoc = GuiTextures.THREE; + barLoc = GuiTextures.BAR_THREE; } + GL11.glTranslatef(0, 0, 100); Minecraft.getMinecraft().getTextureManager().bindTexture(buttonLoc); RenderUtils.drawTexturedRect(x + animation, y, 12, 14); + GL11.glTranslatef(0, 0, -100); + + Minecraft.getMinecraft().getTextureManager().bindTexture(barLoc); + RenderUtils.drawTexturedRect(x, y, xSize, ySize); } @Override diff --git a/src/main/java/io/github/moulberry/notenoughupdates/miscfeatures/PetInfoOverlay.java b/src/main/java/io/github/moulberry/notenoughupdates/miscfeatures/PetInfoOverlay.java index 9663868b..8fe64b55 100644 --- a/src/main/java/io/github/moulberry/notenoughupdates/miscfeatures/PetInfoOverlay.java +++ b/src/main/java/io/github/moulberry/notenoughupdates/miscfeatures/PetInfoOverlay.java @@ -3,6 +3,7 @@ package io.github.moulberry.notenoughupdates.miscfeatures; import com.google.common.collect.Lists; import com.google.gson.*; import io.github.moulberry.notenoughupdates.NEUEventListener; +import io.github.moulberry.notenoughupdates.NEUOverlay; import io.github.moulberry.notenoughupdates.NotEnoughUpdates; import io.github.moulberry.notenoughupdates.core.config.Position; import io.github.moulberry.notenoughupdates.core.util.lerp.LerpUtils; @@ -1114,7 +1115,11 @@ public class PetInfoOverlay extends TextOverlay { String chatMessage = Utils.cleanColour(event.message.getUnformattedText()); Matcher autopetMatcher = AUTOPET_EQUIP.matcher(event.message.getFormattedText()); - if (autopetMatcher.matches()) { + if (event.message.getUnformattedText().startsWith("You summoned your") || System.currentTimeMillis() - NEUOverlay.cachedPetTimer < 500) { + NEUOverlay.cachedPetTimer = System.currentTimeMillis(); + NEUOverlay.shouldUseCachedPet = false; + } else if (autopetMatcher.matches()) { + NEUOverlay.shouldUseCachedPet = false; try { lastLevelHovered = Integer.parseInt(autopetMatcher.group(1)); } catch (NumberFormatException ignored) {} diff --git a/src/main/java/io/github/moulberry/notenoughupdates/options/NEUConfig.java b/src/main/java/io/github/moulberry/notenoughupdates/options/NEUConfig.java index 4bd65acd..a239e741 100644 --- a/src/main/java/io/github/moulberry/notenoughupdates/options/NEUConfig.java +++ b/src/main/java/io/github/moulberry/notenoughupdates/options/NEUConfig.java @@ -12,6 +12,7 @@ import io.github.moulberry.notenoughupdates.miscgui.GuiEnchantColour; import io.github.moulberry.notenoughupdates.miscgui.GuiInvButtonEditor; import io.github.moulberry.notenoughupdates.miscgui.NEUOverlayPlacements; import io.github.moulberry.notenoughupdates.options.seperateSections.*; +import io.github.moulberry.notenoughupdates.overlays.CustomArmour; import io.github.moulberry.notenoughupdates.overlays.MiningOverlay; import io.github.moulberry.notenoughupdates.overlays.OverlayManager; import io.github.moulberry.notenoughupdates.overlays.TextOverlay; @@ -243,6 +244,13 @@ public class NEUConfig extends Config { ) public ImprovedSBMenu improvedSBMenu = new ImprovedSBMenu(); + @Expose + @Category( + name = "Custom Armour Hud", + desc = "Custom Armour Hud" + ) + public CustomArmour customArmour = new CustomArmour(); + @Expose @Category( name = "Calendar", diff --git a/src/main/java/io/github/moulberry/notenoughupdates/options/seperateSections/PetOverlay.java b/src/main/java/io/github/moulberry/notenoughupdates/options/seperateSections/PetOverlay.java index f37280fa..7e49222c 100644 --- a/src/main/java/io/github/moulberry/notenoughupdates/options/seperateSections/PetOverlay.java +++ b/src/main/java/io/github/moulberry/notenoughupdates/options/seperateSections/PetOverlay.java @@ -71,4 +71,22 @@ public class PetOverlay { ) @ConfigEditorBoolean public boolean dualPets = false; + + @Expose + @ConfigOption( + name = "GUI Colour", + desc = "Change the colour of the GUI" + ) + @ConfigEditorDropdown( + values = {"Vanilla", "Grey", "Dark", "Transparent", "FSR"} + ) + public int colourStyle = 0; + + @Expose + @ConfigOption( + name = "Pet Inventory Display", + desc = "Shows an overlay in your inventory showing your current pet" + ) + @ConfigEditorBoolean + public boolean petInvDisplay = true; } diff --git a/src/main/java/io/github/moulberry/notenoughupdates/overlays/CustomArmour.java b/src/main/java/io/github/moulberry/notenoughupdates/overlays/CustomArmour.java new file mode 100644 index 00000000..35e325bb --- /dev/null +++ b/src/main/java/io/github/moulberry/notenoughupdates/overlays/CustomArmour.java @@ -0,0 +1,28 @@ +package io.github.moulberry.notenoughupdates.overlays; + +import com.google.gson.annotations.Expose; +import io.github.moulberry.notenoughupdates.core.config.annotations.ConfigEditorBoolean; +import io.github.moulberry.notenoughupdates.core.config.annotations.ConfigEditorDropdown; +import io.github.moulberry.notenoughupdates.core.config.annotations.ConfigOption; + +public class CustomArmour { + + @Expose + @ConfigOption( + name = "Enables Custom Amour Hud", + desc = "Shows an overlay in your inventory showing your 4 extra armour slots" + ) + @ConfigEditorBoolean + public boolean enableArmourHud = true; + + @Expose + @ConfigOption( + name = "GUI Colour", + desc = "Change the colour of the GUI" + ) + @ConfigEditorDropdown( + values = {"Vanilla", "Grey", "Dark", "Transparent", "FSR"} + ) + public int colourStyle = 0; + +} diff --git a/src/main/java/io/github/moulberry/notenoughupdates/profileviewer/ProfileViewer.java b/src/main/java/io/github/moulberry/notenoughupdates/profileviewer/ProfileViewer.java index bdffb42f..592caa92 100644 --- a/src/main/java/io/github/moulberry/notenoughupdates/profileviewer/ProfileViewer.java +++ b/src/main/java/io/github/moulberry/notenoughupdates/profileviewer/ProfileViewer.java @@ -359,9 +359,9 @@ public class ProfileViewer { if (networth == 0) return -1; //System.out.println(profileId); - for (Map.Entry entry : mostExpensiveInternal.entrySet()) { + //for (Map.Entry entry : mostExpensiveInternal.entrySet()) { //System.out.println(entry.getKey() + ":" + entry.getValue()); - } + //} networth = (int) (networth * 1.3f); diff --git a/src/main/java/io/github/moulberry/notenoughupdates/util/GuiTextures.java b/src/main/java/io/github/moulberry/notenoughupdates/util/GuiTextures.java index d7d5dcc6..fad58b17 100644 --- a/src/main/java/io/github/moulberry/notenoughupdates/util/GuiTextures.java +++ b/src/main/java/io/github/moulberry/notenoughupdates/util/GuiTextures.java @@ -85,6 +85,10 @@ public class GuiTextures { public static final ResourceLocation descending_overlay = new ResourceLocation("notenoughupdates:descending_overlay.png"); public static final ResourceLocation BAR = new ResourceLocation("notenoughupdates:core/bar.png"); + public static final ResourceLocation BAR_ONE = new ResourceLocation("notenoughupdates:core/bar_1.png"); + public static final ResourceLocation BAR_TWO = new ResourceLocation("notenoughupdates:core/bar_2.png"); + public static final ResourceLocation BAR_THREE = new ResourceLocation("notenoughupdates:core/bar_3.png"); + public static final ResourceLocation BAR_ON = new ResourceLocation("notenoughupdates:core/bar_on.png"); public static final ResourceLocation OFF = new ResourceLocation("notenoughupdates:core/toggle_off.png"); public static final ResourceLocation ONE = new ResourceLocation("notenoughupdates:core/toggle_1.png"); public static final ResourceLocation TWO = new ResourceLocation("notenoughupdates:core/toggle_2.png"); diff --git a/src/main/java/io/github/moulberry/notenoughupdates/util/SBInfo.java b/src/main/java/io/github/moulberry/notenoughupdates/util/SBInfo.java index 352d2d1a..008738fd 100644 --- a/src/main/java/io/github/moulberry/notenoughupdates/util/SBInfo.java +++ b/src/main/java/io/github/moulberry/notenoughupdates/util/SBInfo.java @@ -56,6 +56,7 @@ public class SBInfo { public long unloadedWorld = -1; private JsonObject locraw = null; public boolean isInDungeon = false; + public boolean hasNewTab = false; public String currentProfile = null; @@ -79,6 +80,7 @@ public class SBInfo { mode = null; joinedWorld = System.currentTimeMillis(); lastOpenContainerName = ""; + hasNewTab = false; } @SubscribeEvent @@ -144,6 +146,7 @@ public class SBInfo { String name = Minecraft.getMinecraft().ingameGUI.getTabList().getPlayerName(info); if (name.startsWith(profilePrefix)) { currentProfile = Utils.cleanColour(name.substring(profilePrefix.length())); + hasNewTab = true; } else if (name.startsWith(skillsPrefix)) { String levelInfo = name.substring(skillsPrefix.length()).trim(); Matcher matcher = SKILL_LEVEL_PATTERN.matcher(Utils.cleanColour(levelInfo).split(":")[0]); diff --git a/src/main/resources/assets/notenoughupdates/armordisplay/armordisplay.png b/src/main/resources/assets/notenoughupdates/armordisplay/armordisplay.png new file mode 100644 index 00000000..56f6060a Binary files /dev/null and b/src/main/resources/assets/notenoughupdates/armordisplay/armordisplay.png differ diff --git a/src/main/resources/assets/notenoughupdates/armordisplay/armordisplay_fsr.png b/src/main/resources/assets/notenoughupdates/armordisplay/armordisplay_fsr.png new file mode 100644 index 00000000..b4302903 Binary files /dev/null and b/src/main/resources/assets/notenoughupdates/armordisplay/armordisplay_fsr.png differ diff --git a/src/main/resources/assets/notenoughupdates/armordisplay/armordisplay_grey.png b/src/main/resources/assets/notenoughupdates/armordisplay/armordisplay_grey.png new file mode 100644 index 00000000..cb8d0b1b Binary files /dev/null and b/src/main/resources/assets/notenoughupdates/armordisplay/armordisplay_grey.png differ diff --git a/src/main/resources/assets/notenoughupdates/armordisplay/armordisplay_phq_dark.png b/src/main/resources/assets/notenoughupdates/armordisplay/armordisplay_phq_dark.png new file mode 100644 index 00000000..ce36a0cc Binary files /dev/null and b/src/main/resources/assets/notenoughupdates/armordisplay/armordisplay_phq_dark.png differ diff --git a/src/main/resources/assets/notenoughupdates/armordisplay/armordisplay_transparent.png b/src/main/resources/assets/notenoughupdates/armordisplay/armordisplay_transparent.png new file mode 100644 index 00000000..49f1ce4f Binary files /dev/null and b/src/main/resources/assets/notenoughupdates/armordisplay/armordisplay_transparent.png differ diff --git a/src/main/resources/assets/notenoughupdates/armordisplay/armordisplay_transparent_pet.png b/src/main/resources/assets/notenoughupdates/armordisplay/armordisplay_transparent_pet.png new file mode 100644 index 00000000..aeb1b5ed Binary files /dev/null and b/src/main/resources/assets/notenoughupdates/armordisplay/armordisplay_transparent_pet.png differ diff --git a/src/main/resources/assets/notenoughupdates/collectionlog.png b/src/main/resources/assets/notenoughupdates/collectionlog.png deleted file mode 100644 index c30a0b8f..00000000 Binary files a/src/main/resources/assets/notenoughupdates/collectionlog.png and /dev/null differ diff --git a/src/main/resources/assets/notenoughupdates/core/bar_1.png b/src/main/resources/assets/notenoughupdates/core/bar_1.png new file mode 100644 index 00000000..664c0f32 Binary files /dev/null and b/src/main/resources/assets/notenoughupdates/core/bar_1.png differ diff --git a/src/main/resources/assets/notenoughupdates/core/bar_2.png b/src/main/resources/assets/notenoughupdates/core/bar_2.png new file mode 100644 index 00000000..664c0f32 Binary files /dev/null and b/src/main/resources/assets/notenoughupdates/core/bar_2.png differ diff --git a/src/main/resources/assets/notenoughupdates/core/bar_3.png b/src/main/resources/assets/notenoughupdates/core/bar_3.png new file mode 100644 index 00000000..664c0f32 Binary files /dev/null and b/src/main/resources/assets/notenoughupdates/core/bar_3.png differ diff --git a/src/main/resources/assets/notenoughupdates/core/bar_on.png b/src/main/resources/assets/notenoughupdates/core/bar_on.png new file mode 100644 index 00000000..664c0f32 Binary files /dev/null and b/src/main/resources/assets/notenoughupdates/core/bar_on.png differ diff --git a/src/main/resources/assets/notenoughupdates/groundplane.png b/src/main/resources/assets/notenoughupdates/groundplane.png deleted file mode 100644 index 99630d67..00000000 Binary files a/src/main/resources/assets/notenoughupdates/groundplane.png and /dev/null differ diff --git a/src/main/resources/assets/notenoughupdates/petdisplay/petdisplayarmor.png b/src/main/resources/assets/notenoughupdates/petdisplay/petdisplayarmor.png new file mode 100644 index 00000000..f6a873ea Binary files /dev/null and b/src/main/resources/assets/notenoughupdates/petdisplay/petdisplayarmor.png differ diff --git a/src/main/resources/assets/notenoughupdates/petdisplay/petdisplayarmor_dark.png b/src/main/resources/assets/notenoughupdates/petdisplay/petdisplayarmor_dark.png new file mode 100644 index 00000000..27abd2d5 Binary files /dev/null and b/src/main/resources/assets/notenoughupdates/petdisplay/petdisplayarmor_dark.png differ diff --git a/src/main/resources/assets/notenoughupdates/petdisplay/petdisplayarmor_fsr.png b/src/main/resources/assets/notenoughupdates/petdisplay/petdisplayarmor_fsr.png new file mode 100644 index 00000000..39782b3f Binary files /dev/null and b/src/main/resources/assets/notenoughupdates/petdisplay/petdisplayarmor_fsr.png differ diff --git a/src/main/resources/assets/notenoughupdates/petdisplay/petdisplayarmor_phqdark.png b/src/main/resources/assets/notenoughupdates/petdisplay/petdisplayarmor_phqdark.png new file mode 100644 index 00000000..83b78351 Binary files /dev/null and b/src/main/resources/assets/notenoughupdates/petdisplay/petdisplayarmor_phqdark.png differ diff --git a/src/main/resources/assets/notenoughupdates/petdisplay/petdisplayarmor_transparent.png b/src/main/resources/assets/notenoughupdates/petdisplay/petdisplayarmor_transparent.png new file mode 100644 index 00000000..f1bebc01 Binary files /dev/null and b/src/main/resources/assets/notenoughupdates/petdisplay/petdisplayarmor_transparent.png differ diff --git a/src/main/resources/assets/notenoughupdates/petdisplay/petdisplaysolo.png b/src/main/resources/assets/notenoughupdates/petdisplay/petdisplaysolo.png new file mode 100644 index 00000000..c047d5ad Binary files /dev/null and b/src/main/resources/assets/notenoughupdates/petdisplay/petdisplaysolo.png differ diff --git a/src/main/resources/assets/notenoughupdates/petdisplay/petdisplaysolo_dark.png b/src/main/resources/assets/notenoughupdates/petdisplay/petdisplaysolo_dark.png new file mode 100644 index 00000000..6ad6216c Binary files /dev/null and b/src/main/resources/assets/notenoughupdates/petdisplay/petdisplaysolo_dark.png differ diff --git a/src/main/resources/assets/notenoughupdates/petdisplay/petdisplaysolo_fsr.png b/src/main/resources/assets/notenoughupdates/petdisplay/petdisplaysolo_fsr.png new file mode 100644 index 00000000..f39235af Binary files /dev/null and b/src/main/resources/assets/notenoughupdates/petdisplay/petdisplaysolo_fsr.png differ diff --git a/src/main/resources/assets/notenoughupdates/petdisplay/petdisplaysolo_phqdark.png b/src/main/resources/assets/notenoughupdates/petdisplay/petdisplaysolo_phqdark.png new file mode 100644 index 00000000..80566c92 Binary files /dev/null and b/src/main/resources/assets/notenoughupdates/petdisplay/petdisplaysolo_phqdark.png differ diff --git a/src/main/resources/assets/notenoughupdates/petdisplay/petdisplaysolo_transparent.png b/src/main/resources/assets/notenoughupdates/petdisplay/petdisplaysolo_transparent.png new file mode 100644 index 00000000..dfe92b74 Binary files /dev/null and b/src/main/resources/assets/notenoughupdates/petdisplay/petdisplaysolo_transparent.png differ diff --git a/src/main/resources/assets/notenoughupdates/portal_panoramas/nether/pansc-1.png b/src/main/resources/assets/notenoughupdates/portal_panoramas/nether/pansc-1.png deleted file mode 100644 index e6d34776..00000000 Binary files a/src/main/resources/assets/notenoughupdates/portal_panoramas/nether/pansc-1.png and /dev/null differ diff --git a/src/main/resources/assets/notenoughupdates/portal_panoramas/nether/pansc-2.png b/src/main/resources/assets/notenoughupdates/portal_panoramas/nether/pansc-2.png deleted file mode 100644 index c94d88c1..00000000 Binary files a/src/main/resources/assets/notenoughupdates/portal_panoramas/nether/pansc-2.png and /dev/null differ diff --git a/src/main/resources/assets/notenoughupdates/portal_panoramas/nether/pansc-3.png b/src/main/resources/assets/notenoughupdates/portal_panoramas/nether/pansc-3.png deleted file mode 100644 index 8ca52a12..00000000 Binary files a/src/main/resources/assets/notenoughupdates/portal_panoramas/nether/pansc-3.png and /dev/null differ diff --git a/src/main/resources/assets/notenoughupdates/portal_panoramas/nether/pansc-4.png b/src/main/resources/assets/notenoughupdates/portal_panoramas/nether/pansc-4.png deleted file mode 100644 index d889fef5..00000000 Binary files a/src/main/resources/assets/notenoughupdates/portal_panoramas/nether/pansc-4.png and /dev/null differ diff --git a/src/main/resources/assets/notenoughupdates/portal_panoramas/nether/pansc-5.png b/src/main/resources/assets/notenoughupdates/portal_panoramas/nether/pansc-5.png deleted file mode 100644 index 2e40a05b..00000000 Binary files a/src/main/resources/assets/notenoughupdates/portal_panoramas/nether/pansc-5.png and /dev/null differ diff --git a/src/main/resources/assets/notenoughupdates/portal_panoramas/nether/pansc-6.png b/src/main/resources/assets/notenoughupdates/portal_panoramas/nether/pansc-6.png deleted file mode 100644 index 95e684f7..00000000 Binary files a/src/main/resources/assets/notenoughupdates/portal_panoramas/nether/pansc-6.png and /dev/null differ diff --git a/src/main/resources/assets/notenoughupdates/ss_border.jpg b/src/main/resources/assets/notenoughupdates/ss_border.jpg deleted file mode 100644 index 28c1019f..00000000 Binary files a/src/main/resources/assets/notenoughupdates/ss_border.jpg and /dev/null differ -- cgit From 1cf4a3bc76fa52cd847b3da8022e9820de5862c2 Mon Sep 17 00:00:00 2001 From: "Erymanthus[#5074] | (u/)RayDeeUx" <51521765+RayDeeUx@users.noreply.github.com> Date: Fri, 14 Jan 2022 20:22:25 -0500 Subject: add crystal hollows + dwarven mines panos (#62) --- .../panoramas/crystal_hollows/panorama_0.jpg | Bin 0 -> 117941 bytes .../panoramas/crystal_hollows/panorama_1.jpg | Bin 0 -> 129312 bytes .../panoramas/crystal_hollows/panorama_2.jpg | Bin 0 -> 118567 bytes .../panoramas/crystal_hollows/panorama_3.jpg | Bin 0 -> 129964 bytes .../panoramas/crystal_hollows/panorama_4.jpg | Bin 0 -> 151882 bytes .../panoramas/crystal_hollows/panorama_5.jpg | Bin 0 -> 20266 bytes .../notenoughupdates/panoramas/mining_3/panorama_0.jpg | Bin 0 -> 106322 bytes .../notenoughupdates/panoramas/mining_3/panorama_1.jpg | Bin 0 -> 127085 bytes .../notenoughupdates/panoramas/mining_3/panorama_2.jpg | Bin 0 -> 112627 bytes .../notenoughupdates/panoramas/mining_3/panorama_3.jpg | Bin 0 -> 139768 bytes .../notenoughupdates/panoramas/mining_3/panorama_4.jpg | Bin 0 -> 122294 bytes .../notenoughupdates/panoramas/mining_3/panorama_5.jpg | Bin 0 -> 29041 bytes 12 files changed, 0 insertions(+), 0 deletions(-) create mode 100644 src/main/resources/assets/notenoughupdates/panoramas/crystal_hollows/panorama_0.jpg create mode 100644 src/main/resources/assets/notenoughupdates/panoramas/crystal_hollows/panorama_1.jpg create mode 100644 src/main/resources/assets/notenoughupdates/panoramas/crystal_hollows/panorama_2.jpg create mode 100644 src/main/resources/assets/notenoughupdates/panoramas/crystal_hollows/panorama_3.jpg create mode 100644 src/main/resources/assets/notenoughupdates/panoramas/crystal_hollows/panorama_4.jpg create mode 100644 src/main/resources/assets/notenoughupdates/panoramas/crystal_hollows/panorama_5.jpg create mode 100644 src/main/resources/assets/notenoughupdates/panoramas/mining_3/panorama_0.jpg create mode 100644 src/main/resources/assets/notenoughupdates/panoramas/mining_3/panorama_1.jpg create mode 100644 src/main/resources/assets/notenoughupdates/panoramas/mining_3/panorama_2.jpg create mode 100644 src/main/resources/assets/notenoughupdates/panoramas/mining_3/panorama_3.jpg create mode 100644 src/main/resources/assets/notenoughupdates/panoramas/mining_3/panorama_4.jpg create mode 100644 src/main/resources/assets/notenoughupdates/panoramas/mining_3/panorama_5.jpg (limited to 'src/main/resources/assets') diff --git a/src/main/resources/assets/notenoughupdates/panoramas/crystal_hollows/panorama_0.jpg b/src/main/resources/assets/notenoughupdates/panoramas/crystal_hollows/panorama_0.jpg new file mode 100644 index 00000000..55cf5d16 Binary files /dev/null and b/src/main/resources/assets/notenoughupdates/panoramas/crystal_hollows/panorama_0.jpg differ diff --git a/src/main/resources/assets/notenoughupdates/panoramas/crystal_hollows/panorama_1.jpg b/src/main/resources/assets/notenoughupdates/panoramas/crystal_hollows/panorama_1.jpg new file mode 100644 index 00000000..9ab86278 Binary files /dev/null and b/src/main/resources/assets/notenoughupdates/panoramas/crystal_hollows/panorama_1.jpg differ diff --git a/src/main/resources/assets/notenoughupdates/panoramas/crystal_hollows/panorama_2.jpg b/src/main/resources/assets/notenoughupdates/panoramas/crystal_hollows/panorama_2.jpg new file mode 100644 index 00000000..722b6500 Binary files /dev/null and b/src/main/resources/assets/notenoughupdates/panoramas/crystal_hollows/panorama_2.jpg differ diff --git a/src/main/resources/assets/notenoughupdates/panoramas/crystal_hollows/panorama_3.jpg b/src/main/resources/assets/notenoughupdates/panoramas/crystal_hollows/panorama_3.jpg new file mode 100644 index 00000000..c8f23175 Binary files /dev/null and b/src/main/resources/assets/notenoughupdates/panoramas/crystal_hollows/panorama_3.jpg differ diff --git a/src/main/resources/assets/notenoughupdates/panoramas/crystal_hollows/panorama_4.jpg b/src/main/resources/assets/notenoughupdates/panoramas/crystal_hollows/panorama_4.jpg new file mode 100644 index 00000000..29b0216f Binary files /dev/null and b/src/main/resources/assets/notenoughupdates/panoramas/crystal_hollows/panorama_4.jpg differ diff --git a/src/main/resources/assets/notenoughupdates/panoramas/crystal_hollows/panorama_5.jpg b/src/main/resources/assets/notenoughupdates/panoramas/crystal_hollows/panorama_5.jpg new file mode 100644 index 00000000..c43d80de Binary files /dev/null and b/src/main/resources/assets/notenoughupdates/panoramas/crystal_hollows/panorama_5.jpg differ diff --git a/src/main/resources/assets/notenoughupdates/panoramas/mining_3/panorama_0.jpg b/src/main/resources/assets/notenoughupdates/panoramas/mining_3/panorama_0.jpg new file mode 100644 index 00000000..4b7ce678 Binary files /dev/null and b/src/main/resources/assets/notenoughupdates/panoramas/mining_3/panorama_0.jpg differ diff --git a/src/main/resources/assets/notenoughupdates/panoramas/mining_3/panorama_1.jpg b/src/main/resources/assets/notenoughupdates/panoramas/mining_3/panorama_1.jpg new file mode 100644 index 00000000..689a6e5c Binary files /dev/null and b/src/main/resources/assets/notenoughupdates/panoramas/mining_3/panorama_1.jpg differ diff --git a/src/main/resources/assets/notenoughupdates/panoramas/mining_3/panorama_2.jpg b/src/main/resources/assets/notenoughupdates/panoramas/mining_3/panorama_2.jpg new file mode 100644 index 00000000..f7bfa2c1 Binary files /dev/null and b/src/main/resources/assets/notenoughupdates/panoramas/mining_3/panorama_2.jpg differ diff --git a/src/main/resources/assets/notenoughupdates/panoramas/mining_3/panorama_3.jpg b/src/main/resources/assets/notenoughupdates/panoramas/mining_3/panorama_3.jpg new file mode 100644 index 00000000..403945d0 Binary files /dev/null and b/src/main/resources/assets/notenoughupdates/panoramas/mining_3/panorama_3.jpg differ diff --git a/src/main/resources/assets/notenoughupdates/panoramas/mining_3/panorama_4.jpg b/src/main/resources/assets/notenoughupdates/panoramas/mining_3/panorama_4.jpg new file mode 100644 index 00000000..b936aa51 Binary files /dev/null and b/src/main/resources/assets/notenoughupdates/panoramas/mining_3/panorama_4.jpg differ diff --git a/src/main/resources/assets/notenoughupdates/panoramas/mining_3/panorama_5.jpg b/src/main/resources/assets/notenoughupdates/panoramas/mining_3/panorama_5.jpg new file mode 100644 index 00000000..adcda786 Binary files /dev/null and b/src/main/resources/assets/notenoughupdates/panoramas/mining_3/panorama_5.jpg differ -- cgit From c81b6a34ae7bbb70a11f23f49422f2fceffa689c Mon Sep 17 00:00:00 2001 From: Roman / Nea Date: Sun, 16 Jan 2022 01:03:04 +0100 Subject: Add sounds and rework the existing textures to custom Dwarven Mines /… (#51) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Pre Work of custom biomes * Work on auto chunk update, Add Debug command * Added 6 new biomes that are used in crystal hollows * Made it so the biomes are registered in the main class so it loads properly * Add sounds and rework the existing textures to custom Dwarven Mines / CH blocks * Config fixups * make titanium sounds work * Added sounds per gemstone type * fix dwarven mines sounds * stop spamming sound effects with config * Changelog for CH custom blocks * add all the files * Update src/main/resources/assets/notenoughupdates/sounds/titaniumbreak.json * Update src/main/resources/assets/notenoughupdates/sounds/mithrilbreak.json * Update src/main/resources/assets/notenoughupdates/sounds/gemstonetopazbreak.json * Update src/main/resources/assets/notenoughupdates/sounds/gemstonerubybreak.json * Update src/main/resources/assets/notenoughupdates/sounds/gemstonesapphirebreak.json * Update src/main/resources/assets/notenoughupdates/sounds/gemstonejasperbreak.json * Update src/main/resources/assets/notenoughupdates/sounds/gemstoneamethystbreak.json * Update src/main/resources/assets/notenoughupdates/sounds/gemstonejadebreak.json * Update src/main/resources/assets/notenoughupdates/sounds/gemstoneamberbreak.json * Update src/main/java/io/github/moulberry/notenoughupdates/commands/Commands.java * Update src/main/java/io/github/moulberry/notenoughupdates/commands/Commands.java * Update src/main/java/io/github/moulberry/notenoughupdates/commands/Commands.java * Update src/main/java/io/github/moulberry/notenoughupdates/commands/Commands.java * Update src/main/java/io/github/moulberry/notenoughupdates/commands/Commands.java * Update src/main/java/io/github/moulberry/notenoughupdates/commands/Commands.java Co-authored-by: DoKM Co-authored-by: nopothegamer <40329022+nopothegamer@users.noreply.github.com> Co-authored-by: IRONM00N <64110067+IRONM00N@users.noreply.github.com> --- Update Notes/2.1.md | 2 + .../notenoughupdates/NEUEventListener.java | 1 - .../notenoughupdates/NotEnoughUpdates.java | 29 +- .../notenoughupdates/commands/Commands.java | 23 +- .../notenoughupdates/events/NEUEvent.java | 11 + .../events/OnBlockBreakSoundEffect.java | 40 +++ .../miscfeatures/DwarvenMinesTextures.java | 400 --------------------- .../customblockzones/CrystalHollowsTextures.java | 22 ++ .../customblockzones/CustomBiomes.java | 151 ++++++++ .../customblockzones/CustomBlockSounds.java | 102 ++++++ .../customblockzones/DwarvenMinesTextures.java | 191 ++++++++++ .../customblockzones/IslandZoneSubdivider.java | 7 + .../customblockzones/LocationChangeEvent.java | 13 + .../customblockzones/SpecialBlockZone.java | 60 ++++ .../mixins/MixinPlayerControllerMP.java | 14 + .../notenoughupdates/mixins/MixinWorld.java | 13 +- .../options/seperateSections/Mining.java | 37 +- .../moulberry/notenoughupdates/util/SBInfo.java | 35 +- .../resources/assets/notenoughupdates/sounds.json | 120 ++++++- .../sounds/gemstoneamberbreak.json | 1 + .../notenoughupdates/sounds/gemstoneamberbreak.ogg | Bin 0 -> 40373 bytes .../sounds/gemstoneamethystbreak.json | 1 + .../sounds/gemstoneamethystbreak.ogg | Bin 0 -> 40373 bytes .../notenoughupdates/sounds/gemstonejadebreak.json | 1 + .../notenoughupdates/sounds/gemstonejadebreak.ogg | Bin 0 -> 40373 bytes .../sounds/gemstonejasperbreak.json | 1 + .../sounds/gemstonejasperbreak.ogg | Bin 0 -> 40373 bytes .../notenoughupdates/sounds/gemstonerubybreak.json | 1 + .../notenoughupdates/sounds/gemstonerubybreak.ogg | Bin 0 -> 40373 bytes .../sounds/gemstonesapphirebreak.json | 1 + .../sounds/gemstonesapphirebreak.ogg | Bin 0 -> 40373 bytes .../sounds/gemstonetopazbreak.json | 1 + .../notenoughupdates/sounds/gemstonetopazbreak.ogg | Bin 0 -> 40373 bytes .../notenoughupdates/sounds/mithrilbreak.json | 1 + .../notenoughupdates/sounds/mithrilbreak.ogg | Bin 0 -> 40373 bytes .../notenoughupdates/sounds/titaniumbreak.json | 1 + .../notenoughupdates/sounds/titaniumbreak.ogg | Bin 0 -> 40373 bytes 37 files changed, 836 insertions(+), 444 deletions(-) create mode 100644 src/main/java/io/github/moulberry/notenoughupdates/events/NEUEvent.java create mode 100644 src/main/java/io/github/moulberry/notenoughupdates/events/OnBlockBreakSoundEffect.java delete mode 100644 src/main/java/io/github/moulberry/notenoughupdates/miscfeatures/DwarvenMinesTextures.java create mode 100644 src/main/java/io/github/moulberry/notenoughupdates/miscfeatures/customblockzones/CrystalHollowsTextures.java create mode 100644 src/main/java/io/github/moulberry/notenoughupdates/miscfeatures/customblockzones/CustomBiomes.java create mode 100644 src/main/java/io/github/moulberry/notenoughupdates/miscfeatures/customblockzones/CustomBlockSounds.java create mode 100644 src/main/java/io/github/moulberry/notenoughupdates/miscfeatures/customblockzones/DwarvenMinesTextures.java create mode 100644 src/main/java/io/github/moulberry/notenoughupdates/miscfeatures/customblockzones/IslandZoneSubdivider.java create mode 100644 src/main/java/io/github/moulberry/notenoughupdates/miscfeatures/customblockzones/LocationChangeEvent.java create mode 100644 src/main/java/io/github/moulberry/notenoughupdates/miscfeatures/customblockzones/SpecialBlockZone.java create mode 100644 src/main/resources/assets/notenoughupdates/sounds/gemstoneamberbreak.json create mode 100644 src/main/resources/assets/notenoughupdates/sounds/gemstoneamberbreak.ogg create mode 100644 src/main/resources/assets/notenoughupdates/sounds/gemstoneamethystbreak.json create mode 100644 src/main/resources/assets/notenoughupdates/sounds/gemstoneamethystbreak.ogg create mode 100644 src/main/resources/assets/notenoughupdates/sounds/gemstonejadebreak.json create mode 100644 src/main/resources/assets/notenoughupdates/sounds/gemstonejadebreak.ogg create mode 100644 src/main/resources/assets/notenoughupdates/sounds/gemstonejasperbreak.json create mode 100644 src/main/resources/assets/notenoughupdates/sounds/gemstonejasperbreak.ogg create mode 100644 src/main/resources/assets/notenoughupdates/sounds/gemstonerubybreak.json create mode 100644 src/main/resources/assets/notenoughupdates/sounds/gemstonerubybreak.ogg create mode 100644 src/main/resources/assets/notenoughupdates/sounds/gemstonesapphirebreak.json create mode 100644 src/main/resources/assets/notenoughupdates/sounds/gemstonesapphirebreak.ogg create mode 100644 src/main/resources/assets/notenoughupdates/sounds/gemstonetopazbreak.json create mode 100644 src/main/resources/assets/notenoughupdates/sounds/gemstonetopazbreak.ogg create mode 100644 src/main/resources/assets/notenoughupdates/sounds/mithrilbreak.json create mode 100644 src/main/resources/assets/notenoughupdates/sounds/mithrilbreak.ogg create mode 100644 src/main/resources/assets/notenoughupdates/sounds/titaniumbreak.json create mode 100644 src/main/resources/assets/notenoughupdates/sounds/titaniumbreak.ogg (limited to 'src/main/resources/assets') diff --git a/Update Notes/2.1.md b/Update Notes/2.1.md index eb170a0a..ccf13781 100644 --- a/Update Notes/2.1.md +++ b/Update Notes/2.1.md @@ -51,6 +51,8 @@ - Added total xp if player is above cata 50 in /pv - efefury - Added daily powder to todo overlay - efefury - Added a way to include kismet feather to profit calculator - efefury +- Added custom sounds for crystal hollow gemstones - nea89 +- Added custom biomes for crystal hollow areas - nopo ### **Bug Fixes** - Fix wiki pages freezing the entire game - nea89 - Made titanium overlay and waypoints work with dwarven overlay off diff --git a/src/main/java/io/github/moulberry/notenoughupdates/NEUEventListener.java b/src/main/java/io/github/moulberry/notenoughupdates/NEUEventListener.java index 4b6cd511..d7061c22 100644 --- a/src/main/java/io/github/moulberry/notenoughupdates/NEUEventListener.java +++ b/src/main/java/io/github/moulberry/notenoughupdates/NEUEventListener.java @@ -305,7 +305,6 @@ public class NEUEventListener { if (longUpdate) { CrystalOverlay.tick(); - DwarvenMinesTextures.tick(); FairySouls.tick(); XPInformation.getInstance().tick(); ProfileApiSyncer.getInstance().tick(); diff --git a/src/main/java/io/github/moulberry/notenoughupdates/NotEnoughUpdates.java b/src/main/java/io/github/moulberry/notenoughupdates/NotEnoughUpdates.java index 3a6afef8..0cff5de1 100644 --- a/src/main/java/io/github/moulberry/notenoughupdates/NotEnoughUpdates.java +++ b/src/main/java/io/github/moulberry/notenoughupdates/NotEnoughUpdates.java @@ -9,6 +9,9 @@ import io.github.moulberry.notenoughupdates.core.BackgroundBlur; import io.github.moulberry.notenoughupdates.cosmetics.CapeManager; import io.github.moulberry.notenoughupdates.dungeons.DungeonMap; import io.github.moulberry.notenoughupdates.miscfeatures.*; +import io.github.moulberry.notenoughupdates.miscfeatures.customblockzones.CustomBiomes; +import io.github.moulberry.notenoughupdates.miscfeatures.customblockzones.CustomBlockSounds; +import io.github.moulberry.notenoughupdates.miscfeatures.customblockzones.DwarvenMinesTextures; import io.github.moulberry.notenoughupdates.miscgui.CalendarOverlay; import io.github.moulberry.notenoughupdates.miscgui.InventoryStorageSelector; import io.github.moulberry.notenoughupdates.options.NEUConfig; @@ -28,6 +31,7 @@ import net.minecraft.scoreboard.ScoreObjective; import net.minecraft.scoreboard.Scoreboard; import net.minecraft.util.ChatComponentText; import net.minecraft.util.EnumChatFormatting; +import net.minecraft.world.biome.*; import net.minecraftforge.common.MinecraftForge; import net.minecraftforge.fml.client.registry.ClientRegistry; import net.minecraftforge.fml.common.Mod; @@ -35,6 +39,7 @@ import net.minecraftforge.fml.common.Mod.EventHandler; import net.minecraftforge.fml.common.event.FMLPreInitializationEvent; import net.minecraftforge.fml.common.eventhandler.SubscribeEvent; import net.minecraftforge.fml.common.gameevent.TickEvent; +import scala.collection.parallel.ParIterableLike; import java.awt.*; import java.io.*; @@ -100,6 +105,17 @@ public class NotEnoughUpdates { public Color[][] colourMap = null; + /** + * Registers the biomes for the crystal hollows here so optifine knows they exists + */ + public static final BiomeGenBase crystalHollowsJungle = (new BiomeGenJungle(101, true)).setColor(5470985).setBiomeName("NeuCrystalHollowsJungle").setFillerBlockMetadata(5470985).setTemperatureRainfall(0.95F, 0.9F); + public static final BiomeGenBase crystalHollowsMagmaFields = (new BiomeGenHell(102)).setColor(16711680).setBiomeName("NeuCrystalHollowsMagmaFields").setDisableRain().setTemperatureRainfall(2.0F, 0.0F); + public static final BiomeGenBase crystalHollowsGoblinHoldout = (new BiomeGenMesa(103, false, false)).setColor(13274213).setBiomeName("NeuCrystalHollowsGoblinHoldout"); + public static final BiomeGenBase crystalHollowsPrecursorRemnants = (new BiomeGenMesa(104, false, true)).setColor(11573093).setBiomeName("NeuCrystalHollowsPrecursorRemnants"); + public static final BiomeGenBase crystalHollowsMithrilDeposit = (new BiomeGenSnow(105, false)).setColor(16777215).setBiomeName("NeuCrystalHollowsMithrilDeposits"); + public static final BiomeGenBase crystalHollowsCrystalNucleus = (new BiomeGenJungle(106, true)).setColor(5470985).setBiomeName("NeuCrystalHollowsCrystalNucleus").setFillerBlockMetadata(5470985).setTemperatureRainfall(0.95F, 0.9F); + + /** * Instantiates NEUIo, NEUManager and NEUOverlay instances. Registers keybinds and adds a shutdown hook to clear tmp folder. */ @@ -145,7 +161,7 @@ public class NotEnoughUpdates { MinecraftForge.EVENT_BUS.register(new FairySouls()); MinecraftForge.EVENT_BUS.register(new CrystalOverlay()); MinecraftForge.EVENT_BUS.register(new ItemCooldowns()); - MinecraftForge.EVENT_BUS.register(new DwarvenMinesTextures()); + MinecraftForge.EVENT_BUS.register(new DwarvenMinesWaypoints()); MinecraftForge.EVENT_BUS.register(new FuelBar()); //MinecraftForge.EVENT_BUS.register(new FancyPortals()); @@ -157,10 +173,15 @@ public class NotEnoughUpdates { MinecraftForge.EVENT_BUS.register(SlotLocking.getInstance()); MinecraftForge.EVENT_BUS.register(FishingHelper.getInstance()); + MinecraftForge.EVENT_BUS.register(new DwarvenMinesTextures()); + MinecraftForge.EVENT_BUS.register(CustomBiomes.INSTANCE); + if (Minecraft.getMinecraft().getResourceManager() instanceof IReloadableResourceManager) { - ((IReloadableResourceManager) Minecraft.getMinecraft().getResourceManager()).registerReloadListener(CustomSkulls.getInstance()); - ((IReloadableResourceManager) Minecraft.getMinecraft().getResourceManager()).registerReloadListener(NPCRetexturing.getInstance()); - ((IReloadableResourceManager) Minecraft.getMinecraft().getResourceManager()).registerReloadListener(new ItemCustomizeManager.ReloadListener()); + IReloadableResourceManager manager = (IReloadableResourceManager) Minecraft.getMinecraft().getResourceManager(); + manager.registerReloadListener(CustomSkulls.getInstance()); + manager.registerReloadListener(NPCRetexturing.getInstance()); + manager.registerReloadListener(new ItemCustomizeManager.ReloadListener()); + manager.registerReloadListener(new CustomBlockSounds.ReloaderListener()); } this.commands = new Commands(); diff --git a/src/main/java/io/github/moulberry/notenoughupdates/commands/Commands.java b/src/main/java/io/github/moulberry/notenoughupdates/commands/Commands.java index 0e58a6bc..37fe5f63 100644 --- a/src/main/java/io/github/moulberry/notenoughupdates/commands/Commands.java +++ b/src/main/java/io/github/moulberry/notenoughupdates/commands/Commands.java @@ -14,6 +14,9 @@ import io.github.moulberry.notenoughupdates.cosmetics.GuiCosmetics; import io.github.moulberry.notenoughupdates.dungeons.DungeonWin; import io.github.moulberry.notenoughupdates.dungeons.GuiDungeonMapEditor; import io.github.moulberry.notenoughupdates.gamemodes.GuiGamemodes; +import io.github.moulberry.notenoughupdates.miscfeatures.customblockzones.CustomBiomes; +import io.github.moulberry.notenoughupdates.miscfeatures.customblockzones.LocationChangeEvent; +import io.github.moulberry.notenoughupdates.miscfeatures.customblockzones.SpecialBlockZone; import io.github.moulberry.notenoughupdates.miscfeatures.FairySouls; import io.github.moulberry.notenoughupdates.miscfeatures.FancyPortals; import io.github.moulberry.notenoughupdates.miscfeatures.FishingHelper; @@ -25,6 +28,7 @@ import io.github.moulberry.notenoughupdates.options.NEUConfigEditor; import io.github.moulberry.notenoughupdates.profileviewer.GuiProfileViewer; import io.github.moulberry.notenoughupdates.profileviewer.PlayerStats; import io.github.moulberry.notenoughupdates.util.Constants; +import io.github.moulberry.notenoughupdates.util.SBInfo; import io.github.moulberry.notenoughupdates.util.Utils; import net.minecraft.block.material.MapColor; import net.minecraft.client.Minecraft; @@ -39,16 +43,17 @@ import net.minecraft.item.ItemStack; import net.minecraft.util.*; import net.minecraft.world.storage.MapData; import net.minecraftforge.client.ClientCommandHandler; +import net.minecraftforge.common.MinecraftForge; import net.minecraftforge.fml.common.Loader; import org.apache.commons.lang3.StringUtils; import org.apache.commons.lang3.text.WordUtils; -import java.awt.*; +import java.awt.Color; +import java.awt.Desktop; import java.io.*; import java.net.URI; import java.net.URISyntaxException; import java.nio.charset.StandardCharsets; -import java.util.List; import java.util.*; import java.util.concurrent.Executors; import java.util.concurrent.ScheduledExecutorService; @@ -97,6 +102,7 @@ public class Commands { ClientCommandHandler.instance.registerCommand(neuRepoMode); } + SimpleCommand.ProcessCommandRunnable collectionLogRun = new SimpleCommand.ProcessCommandRunnable() { public void processCommand(ICommandSender sender, String[] args) { NotEnoughUpdates.INSTANCE.openGui = new GuiCollectionLog(); @@ -755,7 +761,18 @@ public class Commands { NotEnoughUpdates.INSTANCE.openGui = new GuiPriceGraph(args[1]); } } - + if (args.length == 1 && args[0].equalsIgnoreCase("zone")) { + BlockPos target = Minecraft.getMinecraft().objectMouseOver.getBlockPos(); + if (target == null) target = Minecraft.getMinecraft().thePlayer.getPosition(); + SpecialBlockZone zone = CustomBiomes.INSTANCE.getSpecialZone(target); + Arrays.asList( + new ChatComponentText("Showing Zone Info for: " + target), + new ChatComponentText("Zone: " + (zone != null ? zone.name() : "null")), + new ChatComponentText("Location: " + SBInfo.getInstance().getLocation()), + new ChatComponentText("Biome: " + CustomBiomes.INSTANCE.getCustomBiome(target)) + ).forEach(Minecraft.getMinecraft().thePlayer::addChatMessage); + MinecraftForge.EVENT_BUS.post(new LocationChangeEvent(SBInfo.getInstance().getLocation(), SBInfo.getInstance().getLocation())); + } if (args.length == 1 && args[0].equalsIgnoreCase("positiontest")) { NotEnoughUpdates.INSTANCE.openGui = new GuiPositionEditor(); return; diff --git a/src/main/java/io/github/moulberry/notenoughupdates/events/NEUEvent.java b/src/main/java/io/github/moulberry/notenoughupdates/events/NEUEvent.java new file mode 100644 index 00000000..edcfe072 --- /dev/null +++ b/src/main/java/io/github/moulberry/notenoughupdates/events/NEUEvent.java @@ -0,0 +1,11 @@ +package io.github.moulberry.notenoughupdates.events; + +import net.minecraftforge.common.MinecraftForge; +import net.minecraftforge.fml.common.eventhandler.Event; + +public class NEUEvent extends Event { + public boolean post() { + MinecraftForge.EVENT_BUS.post(this); + return isCancelable() && isCanceled(); + } +} diff --git a/src/main/java/io/github/moulberry/notenoughupdates/events/OnBlockBreakSoundEffect.java b/src/main/java/io/github/moulberry/notenoughupdates/events/OnBlockBreakSoundEffect.java new file mode 100644 index 00000000..b11cbd13 --- /dev/null +++ b/src/main/java/io/github/moulberry/notenoughupdates/events/OnBlockBreakSoundEffect.java @@ -0,0 +1,40 @@ +package io.github.moulberry.notenoughupdates.events; + +import net.minecraft.block.state.BlockState; +import net.minecraft.block.state.IBlockState; +import net.minecraft.client.audio.ISound; +import net.minecraft.util.BlockPos; + +public class OnBlockBreakSoundEffect extends NEUEvent { + + private ISound sound; + private final BlockPos position; + private final IBlockState block; + + public OnBlockBreakSoundEffect(ISound sound, BlockPos position, IBlockState block) { + this.sound = sound; + this.position = position; + this.block = block; + } + + @Override + public boolean isCancelable() { + return true; + } + + public BlockPos getPosition() { + return position; + } + + public IBlockState getBlock() { + return block; + } + + public ISound getSound() { + return sound; + } + + public void setSound(ISound sound) { + this.sound = sound; + } +} diff --git a/src/main/java/io/github/moulberry/notenoughupdates/miscfeatures/DwarvenMinesTextures.java b/src/main/java/io/github/moulberry/notenoughupdates/miscfeatures/DwarvenMinesTextures.java deleted file mode 100644 index 58ea414f..00000000 --- a/src/main/java/io/github/moulberry/notenoughupdates/miscfeatures/DwarvenMinesTextures.java +++ /dev/null @@ -1,400 +0,0 @@ -package io.github.moulberry.notenoughupdates.miscfeatures; - -import com.google.gson.JsonArray; -import com.google.gson.JsonElement; -import com.google.gson.JsonObject; -import com.google.gson.JsonPrimitive; -import io.github.moulberry.notenoughupdates.NotEnoughUpdates; -import io.github.moulberry.notenoughupdates.util.SBInfo; -import net.minecraft.block.BlockColored; -import net.minecraft.block.BlockStone; -import net.minecraft.block.state.IBlockState; -import net.minecraft.client.Minecraft; -import net.minecraft.init.Blocks; -import net.minecraft.item.EnumDyeColor; -import net.minecraft.util.BlockPos; -import net.minecraft.util.MathHelper; -import net.minecraft.util.ResourceLocation; -import net.minecraft.world.ChunkCoordIntPair; - -import java.io.BufferedReader; -import java.io.InputStream; -import java.io.InputStreamReader; -import java.nio.charset.StandardCharsets; -import java.util.HashMap; -import java.util.HashSet; -import java.util.Map; -import java.util.Set; - -public class DwarvenMinesTextures { - private static class IgnoreColumn { - boolean always; - int minY; - int maxY; - - public IgnoreColumn(boolean always, int minY, int maxY) { - this.always = always; - this.minY = minY; - this.maxY = maxY; - } - } - - private static HashSet ignoredChunks = null; - private static final HashMap> loadedChunkData = new HashMap<>(); - private static final HashMap lastRetextureCheck = new HashMap<>(); - private static long time; - private static boolean error = false; - - public static int retexture(BlockPos pos) { - if (!NotEnoughUpdates.INSTANCE.config.mining.dwarvenTextures) return 0; - if (error) return 0; - if (Minecraft.getMinecraft().theWorld == null) return 0; - - String location = SBInfo.getInstance().getLocation(); - - if (location == null) return 0; - if (location.equals("crystal_hollows")) return 3; - if (!location.equals("mining_3")) return 0; - - IBlockState state = Minecraft.getMinecraft().theWorld.getBlockState(pos); - boolean titanium = state.getBlock() == Blocks.stone && state.getValue(BlockStone.VARIANT) == BlockStone.EnumType.DIORITE_SMOOTH; - if (titanium) { - IBlockState plus = Minecraft.getMinecraft().theWorld.getBlockState(pos.add(1, 0, 0)); - if (plus.getBlock() == Blocks.double_stone_slab) { - return 1; - } - IBlockState minus = Minecraft.getMinecraft().theWorld.getBlockState(pos.add(-1, 0, 0)); - if (minus.getBlock() == Blocks.double_stone_slab) { - return 1; - } - IBlockState above = Minecraft.getMinecraft().theWorld.getBlockState(pos.add(0, 1, 0)); - if (above.getBlock() == Blocks.stone_slab) { - return 1; - } - } - - if (titanium || (state.getBlock() == Blocks.stained_hardened_clay && state.getValue(BlockColored.COLOR) == EnumDyeColor.CYAN) || - (state.getBlock() == Blocks.wool && state.getValue(BlockColored.COLOR) == EnumDyeColor.GRAY)) { - - if (ignoredChunks == null) { - try { - ignoredChunks = new HashSet<>(); - ResourceLocation loc = new ResourceLocation("notenoughupdates:dwarven_data/all.json"); - InputStream is = Minecraft.getMinecraft().getResourceManager().getResource(loc).getInputStream(); - - try (BufferedReader reader = new BufferedReader(new InputStreamReader(is, StandardCharsets.UTF_8))) { - JsonObject json = NotEnoughUpdates.INSTANCE.manager.gson.fromJson(reader, JsonObject.class); - for (Map.Entry entry : json.entrySet()) { - String coord = entry.getKey(); - String[] split = coord.split("_"); - int left = Integer.parseInt(split[0]); - int right = Integer.parseInt(split[1]); - ignoredChunks.add(new ChunkCoordIntPair(left, right)); - } - } - } catch (Exception e) { - error = true; - return 1; - } - } - if (ignoredChunks != null) { - ChunkCoordIntPair pair = new ChunkCoordIntPair(MathHelper.floor_float(pos.getX() / 16f), - MathHelper.floor_float(pos.getZ() / 16f)); - - lastRetextureCheck.put(pair, time); - - if (ignoredChunks.contains(pair)) { - return 1; - } - if (titanium) { - return 2; - } - - if (!loadedChunkData.containsKey(pair)) { - try { - HashMap map = new HashMap<>(); - loadedChunkData.put(pair, map); - - ResourceLocation loc = new ResourceLocation("notenoughupdates:dwarven_data/" + - pair.chunkXPos + "_" + pair.chunkZPos + ".json"); - InputStream is = Minecraft.getMinecraft().getResourceManager().getResource(loc).getInputStream(); - - try (BufferedReader reader = new BufferedReader(new InputStreamReader(is, StandardCharsets.UTF_8))) { - JsonObject json = NotEnoughUpdates.INSTANCE.manager.gson.fromJson(reader, JsonObject.class); - for (Map.Entry entry : json.entrySet()) { - String coord = entry.getKey(); - String[] split = coord.split(":"); - int left = Integer.parseInt(split[0]); - int right = Integer.parseInt(split[1]); - - IgnoreColumn ignore = null; - if (entry.getValue().isJsonPrimitive()) { - JsonPrimitive prim = entry.getValue().getAsJsonPrimitive(); - if (prim.isBoolean()) { - ignore = new IgnoreColumn(true, 0, 0); - } else if (prim.isNumber()) { - int y = prim.getAsInt(); - ignore = new IgnoreColumn(false, y, y); - } - } else if (entry.getValue().isJsonArray()) { - JsonArray arr = entry.getValue().getAsJsonArray(); - if (arr.size() == 2) { - int min = arr.get(0).getAsInt(); - int max = arr.get(1).getAsInt(); - ignore = new IgnoreColumn(false, min, max); - } - } - if (ignore != null) { - ChunkCoordIntPair offset = new ChunkCoordIntPair(left, right); - map.put(offset, ignore); - } - } - } - } catch (Exception e) { - loadedChunkData.put(pair, null); - } - } - if (loadedChunkData.get(pair) != null) { - HashMap map = loadedChunkData.get(pair); - if (map == null) { - return 0; - } - - int modX = pos.getX() % 16; - int modZ = pos.getZ() % 16; - if (modX < 0) modX += 16; - if (modZ < 0) modZ += 16; - ChunkCoordIntPair offset = new ChunkCoordIntPair(modX, modZ); - - IgnoreColumn ignore = map.get(offset); - if (ignore != null) { - if (ignore.always) { - return 1; - } else { - int y = pos.getY(); - if (y >= ignore.minY && y <= ignore.maxY) { - return 1; - } - } - } - } - } - } - - return 2; - } - - /*@SubscribeEvent - public void onRender(RenderWorldLastEvent event) { - Entity viewer = Minecraft.getMinecraft().getRenderViewEntity(); - double viewerX = viewer.lastTickPosX + (viewer.posX - viewer.lastTickPosX) * event.partialTicks; - double viewerY = viewer.lastTickPosY + (viewer.posY - viewer.lastTickPosY) * event.partialTicks; - double viewerZ = viewer.lastTickPosZ + (viewer.posZ - viewer.lastTickPosZ) * event.partialTicks; - - int x = MathHelper.floor_double(viewer.posX / 16f); - int z = MathHelper.floor_double(viewer.posZ / 16f); - File file = new File("C:/Users/James/Desktop/testfolder/" + x + "_" + z + ".json"); - - int col = 0xff0000; - if (file.exists()) { - col = 0x00ff00; - if (Keyboard.isKeyDown(Keyboard.KEY_K)) { - file.delete(); - } - - } - - AxisAlignedBB bb = new AxisAlignedBB( - MathHelper.floor_double(viewerX / 16) * 16 - viewerX, - 0 - viewerY, - MathHelper.floor_double(viewerZ / 16) * 16 - viewerZ, - MathHelper.floor_double(viewerX / 16) * 16 + 16 - viewerX, - 255 - viewerY, - MathHelper.floor_double(viewerZ / 16) * 16 + 16 - viewerZ).expand(0.01f, 0.01f, 0.01f); - - GlStateManager.disableCull(); - CustomItemEffects.drawFilledBoundingBox(bb, 1f, SpecialColour.special(0, 100, col)); - GlStateManager.enableCull(); - GlStateManager.enableTexture2D(); - }*/ - - //Render all blocks - extremeHillsEdge - //Don't render smooth diorite - extremeHillsPlus - //Don't render clay - mesaPlateau_F - - public static void tick() { - if (!NotEnoughUpdates.INSTANCE.config.mining.dwarvenTextures) return; - - time = System.currentTimeMillis(); - Set remove = new HashSet<>(); - for (Map.Entry entry : lastRetextureCheck.entrySet()) { - if (time - entry.getValue() > 30 * 1000) { - remove.add(entry.getKey()); - } - } - lastRetextureCheck.keySet().removeAll(remove); - loadedChunkData.keySet().removeAll(remove); - - /*if (Minecraft.getMinecraft().theWorld == null) return; - - if (SBInfo.getInstance().getLocation() == null) return; - if (!SBInfo.getInstance().getLocation().equals("mining_3")) return; - - int playerX = (int) Minecraft.getMinecraft().thePlayer.posX; - int playerZ = (int) Minecraft.getMinecraft().thePlayer.posZ; - - if (Keyboard.isKeyDown(Keyboard.KEY_C)) { - ignoredBlocks.clear(); - whitelistBlocks.clear(); - } - if (Keyboard.isKeyDown(Keyboard.KEY_R)) { - ignoredChunks.clear(); - } - if (Keyboard.isKeyDown(Keyboard.KEY_P)) { - Gson gson = new GsonBuilder().create(); - JsonObject obj = new JsonObject(); - - for (Map.Entry>> entry : ignoredBlocks.entrySet()) { - String chunkId = entry.getKey().chunkXPos + "_" + entry.getKey().chunkZPos; - if (!whitelistBlocks.containsKey(entry.getKey()) || whitelistBlocks.get(entry.getKey()).isEmpty()) { - obj.addProperty(chunkId, true); - } else { - HashMap> whitelistMap = whitelistBlocks.get(entry.getKey()); - JsonObject subChunkObj = new JsonObject(); - - for (Map.Entry> columnEntry : entry.getValue().entrySet()) { - String columnId = columnEntry.getKey().chunkXPos + ":" + columnEntry.getKey().chunkZPos; - - if (!whitelistMap.containsKey(columnEntry.getKey()) || whitelistMap.get(columnEntry.getKey()).isEmpty()) { - subChunkObj.addProperty(columnId, true); - } else if (!columnEntry.getValue().isEmpty()) { - JsonArray whitelistedBlocksInColumn = new JsonArray(); - - int min = 300; - int max = 0; - for (BlockPos pos : columnEntry.getValue()) { - int y = pos.getY(); - if (y < min) { - min = y; - } - if (y > max) { - max = y; - } - } - whitelistedBlocksInColumn.add(new JsonPrimitive(min)); - whitelistedBlocksInColumn.add(new JsonPrimitive(max)); - if (min < max) { - subChunkObj.add(columnId, whitelistedBlocksInColumn); - } else { - subChunkObj.addProperty(columnId, min); - } - } - } - try { - File file = new File("C:/Users/James/Desktop/testfolder/" + chunkId + ".json"); - file.createNewFile(); - - try (BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(file), StandardCharsets.UTF_8))) { - writer.write(gson.toJson(subChunkObj)); - } - } catch (IOException ignored) { - ignored.printStackTrace(); - } - } - } - - try { - File file = new File("C:/Users/James/Desktop/testfolder/all.json"); - file.createNewFile(); - - try (BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(file), StandardCharsets.UTF_8))) { - writer.write(gson.toJson(obj)); - } - } catch (IOException ignored) { - ignored.printStackTrace(); - } - - } - - for (int xC = -10; xC <= 10; xC++) { - out: - for (int zC = -10; zC <= 10; zC++) { - ChunkCoordIntPair pair = new ChunkCoordIntPair(playerX / 16 + xC, playerZ / 16 + zC); - - if (!ignoredChunks.contains(pair)) { - ignoredChunks.add(pair); - - boolean add = false; - for (int x = 0; x < 16; x++) { - for (int y = 0; y < 255; y++) { - for (int z = 0; z < 16; z++) { - BlockPos pos = new BlockPos(pair.chunkXPos * 16 + x, y, pair.chunkZPos * 16 + z); - IBlockState state = Minecraft.getMinecraft().theWorld.getBlockState(pos); - - ChunkCoordIntPair column = new ChunkCoordIntPair(x, z); - - if (state != null && state.getBlock() != Blocks.air) add = true; - - if (state != null && ((state.getBlock() == Blocks.stained_hardened_clay && - state.getValue(BlockColored.COLOR) == EnumDyeColor.CYAN) || - (state.getBlock() == Blocks.wool) && state.getValue(BlockColored.COLOR) == EnumDyeColor.GRAY || - (state.getBlock() == Blocks.stone && state.getValue(BlockStone.VARIANT) == BlockStone.EnumType.DIORITE_SMOOTH))) { - - boolean hasAir = false; - for (int xO = -1; xO <= 1; xO++) { - for (int yO = -1; yO <= 1; yO++) { - for (int zO = -1; zO <= 1; zO++) { - int tot = Math.abs(xO) + Math.abs(yO) + Math.abs(zO); - if (tot == 1) { - BlockPos pos2 = pos.add(xO, yO, zO); - IBlockState state2 = Minecraft.getMinecraft().theWorld.getBlockState(pos2); - - if (state2 == null) { - continue out; - } else if (state2.getBlock() == Blocks.air) { - hasAir = true; - } - } - } - } - } - if (!hasAir) continue; - - boolean found = false; - out2: - for (int xO = -4; xO <= 4; xO++) { - for (int yO = -4; yO <= 4; yO++) { - for (int zO = -4; zO <= 4; zO++) { - int distSq = xO * xO + yO * yO + zO * zO; - if (distSq < 4 * 4) { - BlockPos pos2 = pos.add(xO, yO, zO); - IBlockState state2 = Minecraft.getMinecraft().theWorld.getBlockState(pos2); - - if (state2 == null) { - continue out; - } else if (state2.getBlock() == Blocks.prismarine) { - ignoredBlocks.computeIfAbsent(pair, k -> new HashMap<>()) - .computeIfAbsent(column, k -> new HashSet<>()).remove(pos); - whitelistBlocks.computeIfAbsent(pair, k -> new HashMap<>()) - .computeIfAbsent(column, k -> new HashSet<>()).add(pos); - found = true; - break out2; - } - } - } - } - } - if (!found) { - ignoredBlocks.computeIfAbsent(pair, k -> new HashMap<>()) - .computeIfAbsent(column, k -> new HashSet<>()).add(pos); - } - - } - } - } - } - } - } - }*/ - } -} diff --git a/src/main/java/io/github/moulberry/notenoughupdates/miscfeatures/customblockzones/CrystalHollowsTextures.java b/src/main/java/io/github/moulberry/notenoughupdates/miscfeatures/customblockzones/CrystalHollowsTextures.java new file mode 100644 index 00000000..ab6aaf90 --- /dev/null +++ b/src/main/java/io/github/moulberry/notenoughupdates/miscfeatures/customblockzones/CrystalHollowsTextures.java @@ -0,0 +1,22 @@ +package io.github.moulberry.notenoughupdates.miscfeatures.customblockzones; + +import net.minecraft.util.BlockPos; + +public class CrystalHollowsTextures implements IslandZoneSubdivider { + public SpecialBlockZone getSpecialZoneForBlock(String location, BlockPos pos) { + if (pos.getY() < 65) { + return SpecialBlockZone.CRYSTAL_HOLLOWS_MAGMA_FIELDS; + } else if (pos.getX() < 565 && pos.getX() > 461 && pos.getZ() < 566 && pos.getZ() > 460 && pos.getY() > 64) { + return SpecialBlockZone.CRYSTAL_HOLLOWS_NUCLEUS; + } else if (pos.getX() < 513 && pos.getZ() < 513 && pos.getY() > 64) { + return SpecialBlockZone.CRYSTAL_HOLLOWS_JUNGLE; + } else if (pos.getX() < 513 && pos.getZ() > 512 && pos.getY() > 64) { + return SpecialBlockZone.CRYSTAL_HOLLOWS_GOBLIN_HIDEOUT; + } else if (pos.getX() > 512 && pos.getZ() < 513 && pos.getY() > 64) { + return SpecialBlockZone.CRYSTAL_HOLLOWS_MITHRIL_DEPOSIT; + } else if (pos.getX() > 512 && pos.getZ() > 512 && pos.getY() > 64) { + return SpecialBlockZone.CRYSTAL_HOLLOWS_PRECURSOR_REMNANTS; + } + return null; + } +} diff --git a/src/main/java/io/github/moulberry/notenoughupdates/miscfeatures/customblockzones/CustomBiomes.java b/src/main/java/io/github/moulberry/notenoughupdates/miscfeatures/customblockzones/CustomBiomes.java new file mode 100644 index 00000000..2b1f5a1b --- /dev/null +++ b/src/main/java/io/github/moulberry/notenoughupdates/miscfeatures/customblockzones/CustomBiomes.java @@ -0,0 +1,151 @@ +package io.github.moulberry.notenoughupdates.miscfeatures.customblockzones; + +import io.github.moulberry.notenoughupdates.NotEnoughUpdates; +import io.github.moulberry.notenoughupdates.events.OnBlockBreakSoundEffect; +import io.github.moulberry.notenoughupdates.util.SBInfo; +import net.minecraft.block.BlockColored; +import net.minecraft.block.BlockStone; +import net.minecraft.block.state.IBlockState; +import net.minecraft.client.Minecraft; +import net.minecraft.client.entity.EntityPlayerSP; +import net.minecraft.client.multiplayer.WorldClient; +import net.minecraft.init.Blocks; +import net.minecraft.item.EnumDyeColor; +import net.minecraft.util.BlockPos; +import net.minecraft.world.biome.BiomeGenBase; +import net.minecraftforge.fml.common.eventhandler.SubscribeEvent; + +import java.util.HashMap; +import java.util.Map; + +public class CustomBiomes { + + public static final CustomBiomes INSTANCE = new CustomBiomes(); + + private Map subdividers = new HashMap<>(); + + private CustomBiomes() { + subdividers.put("crystal_hollows", new CrystalHollowsTextures()); + subdividers.put("mining_3", new DwarvenMinesTextures()); + } + + //Biome Prefix: NeuAreaBiomeName + //Example: NeuCHJungle + + public BiomeGenBase getCustomBiome(BlockPos pos) { + SpecialBlockZone specialZone = getSpecialZone(pos); + if (specialZone != null) { + if ((specialZone.isDwarvenMines() && NotEnoughUpdates.INSTANCE.config.mining.dwarvenTextures) + || (specialZone.isCrystalHollows() && NotEnoughUpdates.INSTANCE.config.mining.crystalHollowTextures)) + return specialZone.getCustomBiome(); + } + return null; + } + + /** + * Finds the special zone for the give block position + *

+ * Returns null on error + */ + public SpecialBlockZone getSpecialZone(BlockPos pos) { + if (Minecraft.getMinecraft().theWorld == null) return null; + String location = SBInfo.getInstance().getLocation(); + IslandZoneSubdivider subdivider = subdividers.get(location); + if (subdivider == null) return SpecialBlockZone.NON_SPECIAL_ZONE; + return subdivider.getSpecialZoneForBlock(location, pos); + } + + + @SubscribeEvent + public void onBreakSound(OnBlockBreakSoundEffect event) { + SpecialBlockZone specialZone = getSpecialZone(event.getPosition()); + boolean hasMithrilSounds = NotEnoughUpdates.INSTANCE.config.mining.mithrilSounds; + boolean hasCrystalSounds = NotEnoughUpdates.INSTANCE.config.mining.gemstoneSounds; + if (specialZone != null) { + CustomBlockSounds.CustomSoundEvent customSound = null; + if (specialZone.hasMithril() && isBreakableMithril(event.getBlock()) && hasMithrilSounds && SBInfo.getInstance().getLocation().equals("mining_3")) { + customSound = CustomBlockSounds.mithrilBreak; + } + if (specialZone.hasMithril() && isMithrilHollows(event.getBlock()) && hasMithrilSounds && SBInfo.getInstance().getLocation().equals("crystal_hollows")) { + customSound = CustomBlockSounds.mithrilBreak; + } + if (specialZone.hasTitanium() && isTitanium(event.getBlock()) && hasMithrilSounds) { + customSound = CustomBlockSounds.titaniumBreak; + } + + if (specialZone.hasGemstones() && isGemstone(event.getBlock(), EnumDyeColor.RED) && hasCrystalSounds) { + customSound = CustomBlockSounds.gemstoneBreakRuby; + } + if (specialZone.hasGemstones() && isGemstone(event.getBlock(), EnumDyeColor.YELLOW) && hasCrystalSounds) { + customSound = CustomBlockSounds.gemstoneBreakTopaz; + } + if (specialZone.hasGemstones() && isGemstone(event.getBlock(), EnumDyeColor.PINK) && hasCrystalSounds) { + customSound = CustomBlockSounds.gemstoneBreakJasper; + } + if (specialZone.hasGemstones() && isGemstone(event.getBlock(), EnumDyeColor.LIGHT_BLUE) && hasCrystalSounds) { + customSound = CustomBlockSounds.gemstoneBreakSapphire; + } + if (specialZone.hasGemstones() && isGemstone(event.getBlock(), EnumDyeColor.ORANGE) && hasCrystalSounds) { + customSound = CustomBlockSounds.gemstoneBreakAmber; + } + if (specialZone.hasGemstones() && isGemstone(event.getBlock(), EnumDyeColor.PURPLE) && hasCrystalSounds) { + customSound = CustomBlockSounds.gemstoneBreakAmethyst; + } + if (specialZone.hasGemstones() && isGemstone(event.getBlock(), EnumDyeColor.LIME) && hasCrystalSounds) { + customSound = CustomBlockSounds.gemstoneBreakJade; + } + + if (customSound != null) { + if (customSound.shouldReplace()) { + event.setSound(customSound.replaceSoundEvent(event.getSound())); + } else { + event.setCanceled(true); + } + } + } + } + + public static boolean isTitanium(IBlockState state) { + return state.getBlock() == Blocks.stone && state.getValue(BlockStone.VARIANT) == BlockStone.EnumType.DIORITE_SMOOTH; + } + + public static boolean isMithril(IBlockState state) { + return isBreakableMithril(state) + || state.getBlock() == Blocks.bedrock; + } + + public static boolean isBreakableMithril(IBlockState state) { + return (state.getBlock() == Blocks.stained_hardened_clay && state.getValue(BlockColored.COLOR) == EnumDyeColor.CYAN) + || (state.getBlock() == Blocks.wool && state.getValue(BlockColored.COLOR) == EnumDyeColor.GRAY) + || (state.getBlock() == Blocks.wool && state.getValue(BlockColored.COLOR) == EnumDyeColor.LIGHT_BLUE) + || state.getBlock() == Blocks.prismarine; + } + + public static boolean isMithrilHollows(IBlockState state) { + return state.getBlock() == Blocks.prismarine + || (state.getBlock() == Blocks.wool && state.getValue(BlockColored.COLOR) == EnumDyeColor.LIGHT_BLUE); + } + + public static boolean isGemstone(IBlockState state, EnumDyeColor color) { + return ((state.getBlock() == Blocks.stained_glass || state.getBlock() == Blocks.stained_glass_pane) && state.getValue(BlockColored.COLOR) == color); + } + + @SubscribeEvent + public void onLocationChange(LocationChangeEvent event) { + WorldClient world = Minecraft.getMinecraft().theWorld; + String location = event.newLocation; + if (world == null) return; + if (location == null) return; + switch (location.intern()) { + case "crystal_hollows": + case "mining_3": + //if has custom biome, do chunk update or something + EntityPlayerSP player = Minecraft.getMinecraft().thePlayer; + if (player == null) return; + + world.markBlocksDirtyVertical((int) player.posX, (int) player.posX, (int) player.posZ, (int) player.posZ); + } + } + + +} diff --git a/src/main/java/io/github/moulberry/notenoughupdates/miscfeatures/customblockzones/CustomBlockSounds.java b/src/main/java/io/github/moulberry/notenoughupdates/miscfeatures/customblockzones/CustomBlockSounds.java new file mode 100644 index 00000000..45f22163 --- /dev/null +++ b/src/main/java/io/github/moulberry/notenoughupdates/miscfeatures/customblockzones/CustomBlockSounds.java @@ -0,0 +1,102 @@ +package io.github.moulberry.notenoughupdates.miscfeatures.customblockzones; + +import com.google.gson.Gson; +import com.google.gson.JsonObject; +import io.github.moulberry.notenoughupdates.NotEnoughUpdates; +import net.minecraft.client.Minecraft; +import net.minecraft.client.audio.ISound; +import net.minecraft.client.audio.PositionedSoundRecord; +import net.minecraft.client.resources.IResource; +import net.minecraft.client.resources.IResourceManager; +import net.minecraft.client.resources.IResourceManagerReloadListener; +import net.minecraft.util.ResourceLocation; + +import java.io.IOException; +import java.io.InputStreamReader; +import java.io.Reader; +import java.nio.charset.StandardCharsets; +import java.util.ArrayList; +import java.util.List; +import java.util.Locale; + +public class CustomBlockSounds { + + static Gson gson = new Gson(); + + static List allCustomSoundEvents = new ArrayList<>(); + + public static final CustomSoundEvent mithrilBreak = newCustomSoundEvent("mithril"); + public static final CustomSoundEvent gemstoneBreakRuby = newCustomSoundEvent("gemstoneRuby"); + public static final CustomSoundEvent gemstoneBreakAmber = newCustomSoundEvent("gemstoneAmber"); + public static final CustomSoundEvent gemstoneBreakAmethyst = newCustomSoundEvent("gemstoneAmethyst"); + public static final CustomSoundEvent gemstoneBreakSapphire = newCustomSoundEvent("gemstoneSapphire"); + public static final CustomSoundEvent gemstoneBreakJade = newCustomSoundEvent("gemstoneJade"); + public static final CustomSoundEvent gemstoneBreakTopaz = newCustomSoundEvent("gemstoneTopaz"); + public static final CustomSoundEvent gemstoneBreakJasper = newCustomSoundEvent("gemstoneJasper"); + public static final CustomSoundEvent titaniumBreak = newCustomSoundEvent("titanium"); + + + public static class ReloaderListener implements IResourceManagerReloadListener { + @Override + public void onResourceManagerReload(IResourceManager iResourceManager) { + allCustomSoundEvents.forEach(CustomSoundEvent::reload); + } + } + + public static class CustomSoundEvent { + public ResourceLocation soundEvent; + public ResourceLocation configFile; + private boolean loaded = false; + private int timer = 0; + private long lastReplaced = 0L; + + public CustomSoundEvent() { + allCustomSoundEvents.add(this); + } + + public boolean shouldReplace() { + if (!loaded) reload(); + if (timer < 0) return true; + long now = System.currentTimeMillis(); + if (now - lastReplaced >= timer) { + lastReplaced = now; + return true; + } + return false; + } + + public ISound replaceSoundEvent(ISound sound) { + return new PositionedSoundRecord( + this.soundEvent, + sound.getPitch(), sound.getVolume(), + sound.getXPosF(), sound.getYPosF(), sound.getZPosF() + ); + } + + public void reload() { + loaded = true; + IResource resource; + try { + resource = Minecraft.getMinecraft().getResourceManager().getResource(configFile); + } catch (IOException e) { + timer = -1; + return; + } + try (Reader r = new InputStreamReader(resource.getInputStream(), StandardCharsets.UTF_8)) { + JsonObject jsonObject = gson.fromJson(r, JsonObject.class); + timer = jsonObject.getAsJsonPrimitive("debouncer").getAsInt() * 1000 / 20; + } catch (IOException e) { + e.printStackTrace(); + } + } + + } + + private static CustomSoundEvent newCustomSoundEvent(String soundEvent) { + CustomSoundEvent event = new CustomSoundEvent(); + event.soundEvent = new ResourceLocation("notenoughupdates", soundEvent + ".break"); + event.configFile = new ResourceLocation("notenoughupdates", "sounds/" + soundEvent.toLowerCase(Locale.ROOT) + "break.json"); + return event; + } + +} diff --git a/src/main/java/io/github/moulberry/notenoughupdates/miscfeatures/customblockzones/DwarvenMinesTextures.java b/src/main/java/io/github/moulberry/notenoughupdates/miscfeatures/customblockzones/DwarvenMinesTextures.java new file mode 100644 index 00000000..4a25c4af --- /dev/null +++ b/src/main/java/io/github/moulberry/notenoughupdates/miscfeatures/customblockzones/DwarvenMinesTextures.java @@ -0,0 +1,191 @@ +package io.github.moulberry.notenoughupdates.miscfeatures.customblockzones; + +import com.google.gson.JsonArray; +import com.google.gson.JsonElement; +import com.google.gson.JsonObject; +import com.google.gson.JsonPrimitive; +import io.github.moulberry.notenoughupdates.NotEnoughUpdates; +import net.minecraft.block.state.IBlockState; +import net.minecraft.client.Minecraft; +import net.minecraft.init.Blocks; +import net.minecraft.util.BlockPos; +import net.minecraft.util.EnumFacing; +import net.minecraft.util.MathHelper; +import net.minecraft.util.ResourceLocation; +import net.minecraft.world.ChunkCoordIntPair; + +import java.io.BufferedReader; +import java.io.IOException; +import java.io.InputStreamReader; +import java.io.Reader; +import java.nio.charset.StandardCharsets; +import java.util.HashMap; +import java.util.HashSet; +import java.util.Map; +import java.util.Set; + +import static io.github.moulberry.notenoughupdates.miscfeatures.customblockzones.CustomBiomes.isMithril; +import static io.github.moulberry.notenoughupdates.miscfeatures.customblockzones.CustomBiomes.isTitanium; + +public class DwarvenMinesTextures implements IslandZoneSubdivider { + + private static class IgnoreColumn { + boolean always; + int minY; + int maxY; + + public IgnoreColumn(boolean always, int minY, int maxY) { + this.always = always; + this.minY = minY; + this.maxY = maxY; + } + } + + private Set ignoredChunks = null; + private final Map> loadedChunkData = new HashMap<>(); + private boolean error = false; + + private IBlockState getBlock(BlockPos pos) { + return Minecraft.getMinecraft().theWorld.getBlockState(pos); + } + + + private boolean isDoubleSlab(IBlockState state) { + return state.getBlock() == Blocks.double_stone_slab; + } + + + private Reader getUTF8Resource(ResourceLocation location) throws IOException { + return new BufferedReader(new InputStreamReader(Minecraft.getMinecraft().getResourceManager().getResource(location).getInputStream(), StandardCharsets.UTF_8)); + } + + private void loadIgnoredChunks() { + ignoredChunks = new HashSet<>(); + try (Reader reader = getUTF8Resource(new ResourceLocation("notenoughupdates:dwarven_data/all.json"))) { + JsonObject json = NotEnoughUpdates.INSTANCE.manager.gson.fromJson(reader, JsonObject.class); + for (Map.Entry entry : json.entrySet()) { + String coord = entry.getKey(); + String[] split = coord.split("_"); + int left = Integer.parseInt(split[0]); + int right = Integer.parseInt(split[1]); + ignoredChunks.add(new ChunkCoordIntPair(left, right)); + } + } catch (IOException e) { + ignoredChunks = null; + error = true; + System.out.println("NEU failed to load dwarven mines ignore chunks: "); + e.printStackTrace(); + } + } + + private Set getIgnoredChunks() { + if (ignoredChunks == null) + synchronized (this) { + if (ignoredChunks != null) return ignoredChunks; + loadIgnoredChunks(); + } + return ignoredChunks; + } + + private IgnoreColumn parseIgnoreColumn(JsonElement element) { + if (element.isJsonPrimitive()) { + JsonPrimitive prim = element.getAsJsonPrimitive(); + if (prim.isBoolean()) { + return new IgnoreColumn(true, 0, 0); + } else if (prim.isNumber()) { + int y = prim.getAsInt(); + return new IgnoreColumn(false, y, y); + } + } + if (element.isJsonArray()) { + JsonArray arr = element.getAsJsonArray(); + if (arr.size() == 2) { + int min = arr.get(0).getAsInt(); + int max = arr.get(1).getAsInt(); + return new IgnoreColumn(false, min, max); + } + } + return null; + } + + private Map loadChunkData(ChunkCoordIntPair pair) { + Map map = new HashMap<>(); + try { + ResourceLocation loc = new ResourceLocation("notenoughupdates:dwarven_data/" + + pair.chunkXPos + "_" + pair.chunkZPos + ".json"); + + try (Reader reader = getUTF8Resource(loc)) { + JsonObject json = NotEnoughUpdates.INSTANCE.manager.gson.fromJson(reader, JsonObject.class); + for (Map.Entry entry : json.entrySet()) { + String coord = entry.getKey(); + String[] split = coord.split(":"); + int left = Integer.parseInt(split[0]); + int right = Integer.parseInt(split[1]); + + IgnoreColumn ignore = parseIgnoreColumn(entry.getValue()); + if (ignore != null) { + ChunkCoordIntPair offset = new ChunkCoordIntPair(left, right); + map.put(offset, ignore); + } + } + } + } catch (Exception e) { + } + return map; + } + + private Map getChunkData(ChunkCoordIntPair chunkCoordinates) { + synchronized (this) { + return loadedChunkData.computeIfAbsent(chunkCoordinates, this::loadChunkData); + } + } + + @Override + public SpecialBlockZone getSpecialZoneForBlock(String location, BlockPos pos) { + if (error) return null; + IBlockState block = getBlock(pos); + boolean isTitanium = isTitanium(block); + boolean isMithril = isMithril(block); + if (isTitanium) { + for (EnumFacing direction : EnumFacing.values()) + if (isDoubleSlab(getBlock(pos.offset(direction)))) + return SpecialBlockZone.DWARVEN_MINES_NON_MITHRIL; + } + if (!isMithril && !isTitanium) return SpecialBlockZone.DWARVEN_MINES_NON_MITHRIL; + + Set ignoredChunks = getIgnoredChunks(); + if (ignoredChunks == null) + return null; + ChunkCoordIntPair pair = new ChunkCoordIntPair( + MathHelper.floor_float(pos.getX() / 16f), + MathHelper.floor_float(pos.getZ() / 16f)); + + if (ignoredChunks.contains(pair)) { + return SpecialBlockZone.DWARVEN_MINES_NON_MITHRIL; + } + if (isTitanium) { + return SpecialBlockZone.DWARVEN_MINES_MITHRIL; + } + + Map chunkData = getChunkData(pair); + if (chunkData == null || error) return null; + + int modX = pos.getX() % 16; + int modZ = pos.getZ() % 16; + if (modX < 0) modX += 16; + if (modZ < 0) modZ += 16; + ChunkCoordIntPair subChunkCoordinates = new ChunkCoordIntPair(modX, modZ); + + IgnoreColumn ignore = chunkData.get(subChunkCoordinates); + if (ignore != null) { + if (ignore.always) { + return SpecialBlockZone.DWARVEN_MINES_NON_MITHRIL; + } + int y = pos.getY(); + if (ignore.minY <= y && y <= ignore.maxY) { + return SpecialBlockZone.DWARVEN_MINES_NON_MITHRIL; + } + } + return SpecialBlockZone.DWARVEN_MINES_MITHRIL; + } +} diff --git a/src/main/java/io/github/moulberry/notenoughupdates/miscfeatures/customblockzones/IslandZoneSubdivider.java b/src/main/java/io/github/moulberry/notenoughupdates/miscfeatures/customblockzones/IslandZoneSubdivider.java new file mode 100644 index 00000000..72278894 --- /dev/null +++ b/src/main/java/io/github/moulberry/notenoughupdates/miscfeatures/customblockzones/IslandZoneSubdivider.java @@ -0,0 +1,7 @@ +package io.github.moulberry.notenoughupdates.miscfeatures.customblockzones; + +import net.minecraft.util.BlockPos; + +public interface IslandZoneSubdivider { + SpecialBlockZone getSpecialZoneForBlock(String location, BlockPos position); +} diff --git a/src/main/java/io/github/moulberry/notenoughupdates/miscfeatures/customblockzones/LocationChangeEvent.java b/src/main/java/io/github/moulberry/notenoughupdates/miscfeatures/customblockzones/LocationChangeEvent.java new file mode 100644 index 00000000..b4217b27 --- /dev/null +++ b/src/main/java/io/github/moulberry/notenoughupdates/miscfeatures/customblockzones/LocationChangeEvent.java @@ -0,0 +1,13 @@ +package io.github.moulberry.notenoughupdates.miscfeatures.customblockzones; + +import net.minecraftforge.fml.common.eventhandler.Event; + +public class LocationChangeEvent extends Event { + public final String newLocation; + public final String oldLocation; + public LocationChangeEvent(String newLocation, String oldLocation) + { + this.newLocation = newLocation; + this.oldLocation = oldLocation; + } +} diff --git a/src/main/java/io/github/moulberry/notenoughupdates/miscfeatures/customblockzones/SpecialBlockZone.java b/src/main/java/io/github/moulberry/notenoughupdates/miscfeatures/customblockzones/SpecialBlockZone.java new file mode 100644 index 00000000..403e5b9b --- /dev/null +++ b/src/main/java/io/github/moulberry/notenoughupdates/miscfeatures/customblockzones/SpecialBlockZone.java @@ -0,0 +1,60 @@ +package io.github.moulberry.notenoughupdates.miscfeatures.customblockzones; + +import io.github.moulberry.notenoughupdates.NotEnoughUpdates; +import net.minecraft.world.biome.BiomeGenBase; + +public enum SpecialBlockZone { + DWARVEN_MINES_NON_MITHRIL(BiomeGenBase.extremeHillsPlus, false, false, false, true, false), + DWARVEN_MINES_MITHRIL(BiomeGenBase.extremeHillsEdge, true, true, false, true, false), + CRYSTAL_HOLLOWS_MAGMA_FIELDS(NotEnoughUpdates.crystalHollowsMagmaFields, true, false, true, false, true), + CRYSTAL_HOLLOWS_NUCLEUS(NotEnoughUpdates.crystalHollowsCrystalNucleus, true, false, true, false, true), + CRYSTAL_HOLLOWS_JUNGLE(NotEnoughUpdates.crystalHollowsJungle, true, false, true, false, true), + CRYSTAL_HOLLOWS_GOBLIN_HIDEOUT(NotEnoughUpdates.crystalHollowsGoblinHoldout, true, false, true, false, true), + CRYSTAL_HOLLOWS_MITHRIL_DEPOSIT(NotEnoughUpdates.crystalHollowsMithrilDeposit, true, false, true, false, true), + CRYSTAL_HOLLOWS_PRECURSOR_REMNANTS(NotEnoughUpdates.crystalHollowsPrecursorRemnants, true, false, true, false, true), + NON_SPECIAL_ZONE(null, false, false, false, false, false); + + private final BiomeGenBase customBiome; + private final boolean hasMithril; + private final boolean hasTitanium; + private final boolean hasGemstones; + private final boolean isDwarvenMines; + private final boolean isCrystalHollows; + + SpecialBlockZone(BiomeGenBase customBiome, boolean hasMithril, boolean hasTitanium, boolean hasGemstones, boolean isDwarvenMines, boolean isCrystalHollows) { + this.customBiome = customBiome; + this.hasMithril = hasMithril; + this.hasTitanium = hasTitanium; + this.hasGemstones = hasGemstones; + this.isDwarvenMines = isDwarvenMines; + this.isCrystalHollows = isCrystalHollows; + } + + public BiomeGenBase getCustomBiome() { + return customBiome; + } + + public boolean hasMithril() { + return hasMithril; + } + + public boolean hasTitanium() { + return hasTitanium; + } + + public boolean hasGemstones() { + return hasGemstones; + } + + public boolean isDwarvenMines() { + return isDwarvenMines; + } + + public boolean isCrystalHollows() { + return isCrystalHollows; + } + + public boolean isMiningZone() { + return isCrystalHollows || isDwarvenMines; + } +} diff --git a/src/main/java/io/github/moulberry/notenoughupdates/mixins/MixinPlayerControllerMP.java b/src/main/java/io/github/moulberry/notenoughupdates/mixins/MixinPlayerControllerMP.java index 78130cb4..969b5b88 100644 --- a/src/main/java/io/github/moulberry/notenoughupdates/mixins/MixinPlayerControllerMP.java +++ b/src/main/java/io/github/moulberry/notenoughupdates/mixins/MixinPlayerControllerMP.java @@ -1,12 +1,17 @@ package io.github.moulberry.notenoughupdates.mixins; +import io.github.moulberry.notenoughupdates.events.OnBlockBreakSoundEffect; import io.github.moulberry.notenoughupdates.miscfeatures.ItemCooldowns; +import net.minecraft.client.Minecraft; +import net.minecraft.client.audio.ISound; +import net.minecraft.client.audio.SoundHandler; import net.minecraft.client.multiplayer.PlayerControllerMP; import net.minecraft.util.BlockPos; import net.minecraft.util.EnumFacing; import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.injection.At; import org.spongepowered.asm.mixin.injection.Inject; +import org.spongepowered.asm.mixin.injection.Redirect; import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; @Mixin(PlayerControllerMP.class) @@ -19,4 +24,13 @@ public class MixinPlayerControllerMP { ((PlayerControllerMP)(Object)this).resetBlockRemoving(); }*/ } + + @Redirect(method = "onPlayerDamageBlock", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/audio/SoundHandler;playSound(Lnet/minecraft/client/audio/ISound;)V")) + public void onPlayerDamageBlock(SoundHandler instance, ISound p_playSound_1_, BlockPos p_onPlayerDamageBlock_1_, EnumFacing p_onPlayerDamageBlock_2_) { + OnBlockBreakSoundEffect onBlockBreakSoundEffect = new OnBlockBreakSoundEffect(p_playSound_1_, p_onPlayerDamageBlock_1_, Minecraft.getMinecraft().theWorld.getBlockState(p_onPlayerDamageBlock_1_)); + if (!onBlockBreakSoundEffect.post()) { + instance.playSound(onBlockBreakSoundEffect.getSound()); + } + } + } diff --git a/src/main/java/io/github/moulberry/notenoughupdates/mixins/MixinWorld.java b/src/main/java/io/github/moulberry/notenoughupdates/mixins/MixinWorld.java index 30b217db..3cee3564 100644 --- a/src/main/java/io/github/moulberry/notenoughupdates/mixins/MixinWorld.java +++ b/src/main/java/io/github/moulberry/notenoughupdates/mixins/MixinWorld.java @@ -1,8 +1,8 @@ package io.github.moulberry.notenoughupdates.mixins; import io.github.moulberry.notenoughupdates.NotEnoughUpdates; +import io.github.moulberry.notenoughupdates.miscfeatures.customblockzones.CustomBiomes; import io.github.moulberry.notenoughupdates.miscfeatures.CustomItemEffects; -import io.github.moulberry.notenoughupdates.miscfeatures.DwarvenMinesTextures; import net.minecraft.util.BlockPos; import net.minecraft.world.World; import net.minecraft.world.biome.BiomeGenBase; @@ -27,13 +27,10 @@ public class MixinWorld { @Inject(method = "getBiomeGenForCoords", at = @At("HEAD"), cancellable = true) public void getBiomeGenForCoords(BlockPos pos, CallbackInfoReturnable cir) { - int retexture = DwarvenMinesTextures.retexture(pos); - if (retexture == 1) { - cir.setReturnValue(BiomeGenBase.extremeHillsPlus); - } else if (retexture == 2) { - cir.setReturnValue(BiomeGenBase.extremeHillsEdge); - } else if (retexture == 3) { - cir.setReturnValue(BiomeGenBase.coldBeach); + BiomeGenBase customBiome = CustomBiomes.INSTANCE.getCustomBiome(pos); + if(customBiome != null){ + cir.setReturnValue(customBiome); } + } } diff --git a/src/main/java/io/github/moulberry/notenoughupdates/options/seperateSections/Mining.java b/src/main/java/io/github/moulberry/notenoughupdates/options/seperateSections/Mining.java index 2b0c42f7..c5580011 100644 --- a/src/main/java/io/github/moulberry/notenoughupdates/options/seperateSections/Mining.java +++ b/src/main/java/io/github/moulberry/notenoughupdates/options/seperateSections/Mining.java @@ -492,11 +492,46 @@ public class Mining { @ConfigEditorBoolean public boolean titaniumAlertMustBeVisible = false; + @ConfigOption( + name = "Custom Textures", + desc = "" + ) + @ConfigEditorAccordion(id = 7) + public boolean texturesAccordion = false; + @Expose @ConfigOption( name = "Dwarven Mines Textures", - desc = "Allows texture packs to retexture blocks in the Dwarven Mines. If you don't have a texturepack that does this, you should leave this off" + desc = "Allows texture packs to retexture blocks in the Dwarven Mines. If you don't have a texture pack that does this, you should leave this off" ) + @ConfigAccordionId(id = 7) @ConfigEditorBoolean public boolean dwarvenTextures = false; + @Expose + @ConfigOption( + name = "Crystal Hollows Textures", + desc = "Allows texture packs to retexture blocks in the Crystal Hollows. If you don't have a texture pack that does this, you should leave this off" + ) + @ConfigAccordionId(id = 7) + @ConfigEditorBoolean + public boolean crystalHollowTextures = false; + + @Expose + @ConfigOption( + name = "Replace Gemstone sounds", + desc = "Replace the break sounds of crystals in the Crystal Hollows. Requires a texture pack with this feature" + ) + @ConfigAccordionId(id = 7) + @ConfigEditorBoolean + public boolean gemstoneSounds = false; + + @Expose + @ConfigOption( + name = "Replace Mithril sounds", + desc = "Replace the break sounds of mithril and titanium in the Dwarven mines. Requires a texture pack with this feature" + ) + @ConfigAccordionId(id = 7) + @ConfigEditorBoolean + public boolean mithrilSounds = false; + } diff --git a/src/main/java/io/github/moulberry/notenoughupdates/util/SBInfo.java b/src/main/java/io/github/moulberry/notenoughupdates/util/SBInfo.java index 008738fd..6dcd284e 100644 --- a/src/main/java/io/github/moulberry/notenoughupdates/util/SBInfo.java +++ b/src/main/java/io/github/moulberry/notenoughupdates/util/SBInfo.java @@ -2,6 +2,7 @@ package io.github.moulberry.notenoughupdates.util; import com.google.gson.JsonObject; import io.github.moulberry.notenoughupdates.NotEnoughUpdates; +import io.github.moulberry.notenoughupdates.miscfeatures.customblockzones.LocationChangeEvent; import io.github.moulberry.notenoughupdates.overlays.SlayerOverlay; import net.minecraft.client.Minecraft; import net.minecraft.client.gui.inventory.GuiChest; @@ -14,6 +15,7 @@ import net.minecraft.scoreboard.Scoreboard; import net.minecraft.util.IChatComponent; import net.minecraftforge.client.event.ClientChatReceivedEvent; import net.minecraftforge.client.event.GuiOpenEvent; +import net.minecraftforge.common.MinecraftForge; import net.minecraftforge.event.world.WorldEvent; import net.minecraftforge.fml.common.eventhandler.EventPriority; import net.minecraftforge.fml.common.eventhandler.SubscribeEvent; @@ -23,6 +25,7 @@ import java.text.SimpleDateFormat; import java.util.ArrayList; import java.util.Date; import java.util.List; +import java.util.Objects; import java.util.regex.Matcher; import java.util.regex.Pattern; @@ -77,7 +80,7 @@ public class SBInfo { public void onWorldLoad(WorldEvent.Load event) { lastLocRaw = -1; locraw = null; - mode = null; + this.setLocation(null); joinedWorld = System.currentTimeMillis(); lastOpenContainerName = ""; hasNewTab = false; @@ -106,7 +109,7 @@ public class SBInfo { if (System.currentTimeMillis() - lastManualLocRaw > 5000) event.setCanceled(true); if (obj.has("gametype") && obj.has("mode") && obj.has("map")) { locraw = obj; - mode = locraw.get("mode").getAsString(); + setLocation(locraw.get("mode").getAsString()); } } } catch (Exception e) { @@ -116,12 +119,16 @@ public class SBInfo { } public String getLocation() { - if (mode == null) { - return null; - } return mode; } + public void setLocation(String location) { + if (!Objects.equals(this.mode, location)) { + MinecraftForge.EVENT_BUS.post(new LocationChangeEvent(location, this.mode)); + } + this.mode = location; + } + private static final String profilePrefix = "\u00a7r\u00a7e\u00a7lProfile: \u00a7r\u00a7a"; private static final String skillsPrefix = "\u00a7r\u00a7e\u00a7lSkills: \u00a7r\u00a7a"; @@ -154,7 +161,8 @@ public class SBInfo { try { int level = Integer.parseInt(matcher.group(2).trim()); XPInformation.getInstance().updateLevel(matcher.group(1).toLowerCase().trim(), level); - } catch (Exception ignored) {} + } catch (Exception ignored) { + } } } } @@ -204,13 +212,17 @@ public class SBInfo { if (SlayerOverlay.slayerQuest) { if (line.contains(" I")) { SlayerOverlay.slayerTier = 1; - } if (line.contains(" II")) { + } + if (line.contains(" II")) { SlayerOverlay.slayerTier = 2; - } if (line.contains(" III")) { + } + if (line.contains(" III")) { SlayerOverlay.slayerTier = 3; - } if (line.contains(" IV")) { + } + if (line.contains(" IV")) { SlayerOverlay.slayerTier = 4; - } if (line.contains(" V")) { + } + if (line.contains(" V")) { SlayerOverlay.slayerTier = 5; } } @@ -226,7 +238,8 @@ public class SBInfo { String timeSpace = time.replace("am", " am").replace("pm", " pm"); SimpleDateFormat parseFormat = new SimpleDateFormat("hh:mm a"); currentTimeDate = parseFormat.parse(timeSpace); - } catch (ParseException ignored) {} + } catch (ParseException ignored) { + } } //Replaced with for loop because in crystal hollows with events the line it's on can shift. for (String line : lines) { diff --git a/src/main/resources/assets/notenoughupdates/sounds.json b/src/main/resources/assets/notenoughupdates/sounds.json index 47b0ba1b..6d827876 100644 --- a/src/main/resources/assets/notenoughupdates/sounds.json +++ b/src/main/resources/assets/notenoughupdates/sounds.json @@ -1,23 +1,111 @@ { - "calendar_notif_jingle":{ + "mithril.break": { + "category": "block", + "sounds": [ + { + "name": "mithrilbreak", + "stream": false + } + ] + }, + "gemstoneTopaz.break": { + "category": "block", + "sounds": [ + { + "name": "gemstonebreaktopaz", + "stream": false + } + ] + }, + "gemstoneRuby.break": { + "category": "block", + "sounds": [ + { + "name": "gemstonebreakruby", + "stream": false + } + ] + }, + "gemstoneAmber.break": { + "category": "block", + "sounds": [ + { + "name": "gemstonebreakamber", + "stream": false + } + ] + }, + "gemstoneAmethyst.break": { + "category": "block", + "sounds": [ + { + "name": "gemstoneamethystbreak", + "stream": false + } + ] + }, + "gemstoneSapphire.break": { + "category": "block", + "sounds": [ + { + "name": "gemstonesapphirebreak", + "stream": false + } + ] + }, + "gemstoneJade.break": { + "category": "block", + "sounds": [ + { + "name": "gemstonejadebreak", + "stream": false + } + ] + }, + "gemstoneJasper.break": { + "category": "block", + "sounds": [ + { + "name": "gemstonejasperbreak", + "stream": false + } + ] + }, + + "titanium.break": { + "category": "block", + "sounds": [ + { + "name": "titaniumbreak", + "stream": false + } + ] + }, + "calendar_notif_jingle": { "category": "master", - "sounds": [{ - "name": "jingle", - "stream": false - }] + "sounds": [ + { + "name": "jingle", + "stream": false + } + ] }, - "calendar_notif_in":{ + "calendar_notif_in": { "category": "master", - "sounds": [{ - "name": "in", - "stream": false - }] + "sounds": [ + { + "name": "in", + "stream": false + } + ] }, - "calendar_notif_out":{ + "calendar_notif_out": { "category": "master", - "sounds": [{ - "name": "out", - "stream": false - }] + "sounds": [ + { + "name": "out", + "stream": false + } + ] } -} \ No newline at end of file +} diff --git a/src/main/resources/assets/notenoughupdates/sounds/gemstoneamberbreak.json b/src/main/resources/assets/notenoughupdates/sounds/gemstoneamberbreak.json new file mode 100644 index 00000000..b02ee0c7 --- /dev/null +++ b/src/main/resources/assets/notenoughupdates/sounds/gemstoneamberbreak.json @@ -0,0 +1 @@ +{ "debouncer": 20 } diff --git a/src/main/resources/assets/notenoughupdates/sounds/gemstoneamberbreak.ogg b/src/main/resources/assets/notenoughupdates/sounds/gemstoneamberbreak.ogg new file mode 100644 index 00000000..a04e171a Binary files /dev/null and b/src/main/resources/assets/notenoughupdates/sounds/gemstoneamberbreak.ogg differ diff --git a/src/main/resources/assets/notenoughupdates/sounds/gemstoneamethystbreak.json b/src/main/resources/assets/notenoughupdates/sounds/gemstoneamethystbreak.json new file mode 100644 index 00000000..b02ee0c7 --- /dev/null +++ b/src/main/resources/assets/notenoughupdates/sounds/gemstoneamethystbreak.json @@ -0,0 +1 @@ +{ "debouncer": 20 } diff --git a/src/main/resources/assets/notenoughupdates/sounds/gemstoneamethystbreak.ogg b/src/main/resources/assets/notenoughupdates/sounds/gemstoneamethystbreak.ogg new file mode 100644 index 00000000..a04e171a Binary files /dev/null and b/src/main/resources/assets/notenoughupdates/sounds/gemstoneamethystbreak.ogg differ diff --git a/src/main/resources/assets/notenoughupdates/sounds/gemstonejadebreak.json b/src/main/resources/assets/notenoughupdates/sounds/gemstonejadebreak.json new file mode 100644 index 00000000..b02ee0c7 --- /dev/null +++ b/src/main/resources/assets/notenoughupdates/sounds/gemstonejadebreak.json @@ -0,0 +1 @@ +{ "debouncer": 20 } diff --git a/src/main/resources/assets/notenoughupdates/sounds/gemstonejadebreak.ogg b/src/main/resources/assets/notenoughupdates/sounds/gemstonejadebreak.ogg new file mode 100644 index 00000000..a04e171a Binary files /dev/null and b/src/main/resources/assets/notenoughupdates/sounds/gemstonejadebreak.ogg differ diff --git a/src/main/resources/assets/notenoughupdates/sounds/gemstonejasperbreak.json b/src/main/resources/assets/notenoughupdates/sounds/gemstonejasperbreak.json new file mode 100644 index 00000000..b02ee0c7 --- /dev/null +++ b/src/main/resources/assets/notenoughupdates/sounds/gemstonejasperbreak.json @@ -0,0 +1 @@ +{ "debouncer": 20 } diff --git a/src/main/resources/assets/notenoughupdates/sounds/gemstonejasperbreak.ogg b/src/main/resources/assets/notenoughupdates/sounds/gemstonejasperbreak.ogg new file mode 100644 index 00000000..a04e171a Binary files /dev/null and b/src/main/resources/assets/notenoughupdates/sounds/gemstonejasperbreak.ogg differ diff --git a/src/main/resources/assets/notenoughupdates/sounds/gemstonerubybreak.json b/src/main/resources/assets/notenoughupdates/sounds/gemstonerubybreak.json new file mode 100644 index 00000000..b02ee0c7 --- /dev/null +++ b/src/main/resources/assets/notenoughupdates/sounds/gemstonerubybreak.json @@ -0,0 +1 @@ +{ "debouncer": 20 } diff --git a/src/main/resources/assets/notenoughupdates/sounds/gemstonerubybreak.ogg b/src/main/resources/assets/notenoughupdates/sounds/gemstonerubybreak.ogg new file mode 100644 index 00000000..a04e171a Binary files /dev/null and b/src/main/resources/assets/notenoughupdates/sounds/gemstonerubybreak.ogg differ diff --git a/src/main/resources/assets/notenoughupdates/sounds/gemstonesapphirebreak.json b/src/main/resources/assets/notenoughupdates/sounds/gemstonesapphirebreak.json new file mode 100644 index 00000000..b02ee0c7 --- /dev/null +++ b/src/main/resources/assets/notenoughupdates/sounds/gemstonesapphirebreak.json @@ -0,0 +1 @@ +{ "debouncer": 20 } diff --git a/src/main/resources/assets/notenoughupdates/sounds/gemstonesapphirebreak.ogg b/src/main/resources/assets/notenoughupdates/sounds/gemstonesapphirebreak.ogg new file mode 100644 index 00000000..a04e171a Binary files /dev/null and b/src/main/resources/assets/notenoughupdates/sounds/gemstonesapphirebreak.ogg differ diff --git a/src/main/resources/assets/notenoughupdates/sounds/gemstonetopazbreak.json b/src/main/resources/assets/notenoughupdates/sounds/gemstonetopazbreak.json new file mode 100644 index 00000000..b02ee0c7 --- /dev/null +++ b/src/main/resources/assets/notenoughupdates/sounds/gemstonetopazbreak.json @@ -0,0 +1 @@ +{ "debouncer": 20 } diff --git a/src/main/resources/assets/notenoughupdates/sounds/gemstonetopazbreak.ogg b/src/main/resources/assets/notenoughupdates/sounds/gemstonetopazbreak.ogg new file mode 100644 index 00000000..a04e171a Binary files /dev/null and b/src/main/resources/assets/notenoughupdates/sounds/gemstonetopazbreak.ogg differ diff --git a/src/main/resources/assets/notenoughupdates/sounds/mithrilbreak.json b/src/main/resources/assets/notenoughupdates/sounds/mithrilbreak.json new file mode 100644 index 00000000..b02ee0c7 --- /dev/null +++ b/src/main/resources/assets/notenoughupdates/sounds/mithrilbreak.json @@ -0,0 +1 @@ +{ "debouncer": 20 } diff --git a/src/main/resources/assets/notenoughupdates/sounds/mithrilbreak.ogg b/src/main/resources/assets/notenoughupdates/sounds/mithrilbreak.ogg new file mode 100644 index 00000000..a04e171a Binary files /dev/null and b/src/main/resources/assets/notenoughupdates/sounds/mithrilbreak.ogg differ diff --git a/src/main/resources/assets/notenoughupdates/sounds/titaniumbreak.json b/src/main/resources/assets/notenoughupdates/sounds/titaniumbreak.json new file mode 100644 index 00000000..b02ee0c7 --- /dev/null +++ b/src/main/resources/assets/notenoughupdates/sounds/titaniumbreak.json @@ -0,0 +1 @@ +{ "debouncer": 20 } diff --git a/src/main/resources/assets/notenoughupdates/sounds/titaniumbreak.ogg b/src/main/resources/assets/notenoughupdates/sounds/titaniumbreak.ogg new file mode 100644 index 00000000..a04e171a Binary files /dev/null and b/src/main/resources/assets/notenoughupdates/sounds/titaniumbreak.ogg differ -- cgit From 593b2c8c1078d0bf40d08d3f100afb8f947da422 Mon Sep 17 00:00:00 2001 From: jani270 <69345714+jani270@users.noreply.github.com> Date: Sun, 30 Jan 2022 14:21:24 +0100 Subject: Added patreon back and made so settings look better (#72) * Added patreon back * Make settings look better --- .../notenoughupdates/options/NEUConfig.java | 2 +- .../notenoughupdates/options/NEUConfigEditor.java | 2 + .../options/seperateSections/AHGraph.java | 2 +- .../options/seperateSections/CustomArmour.java | 28 +++++ .../options/seperateSections/Fishing.java | 8 +- .../options/seperateSections/LocationEdit.java | 120 +++++++++++++-------- .../options/seperateSections/Mining.java | 10 +- .../options/seperateSections/MiscOverlays.java | 2 +- .../options/seperateSections/PetOverlay.java | 2 +- .../options/seperateSections/SkillOverlays.java | 8 +- .../options/seperateSections/SlayerOverlay.java | 4 +- .../notenoughupdates/overlays/CustomArmour.java | 28 ----- .../notenoughupdates/util/GuiTextures.java | 3 +- .../assets/notenoughupdates/social/patreon.png | Bin 0 -> 3696 bytes 14 files changed, 125 insertions(+), 94 deletions(-) create mode 100644 src/main/java/io/github/moulberry/notenoughupdates/options/seperateSections/CustomArmour.java delete mode 100644 src/main/java/io/github/moulberry/notenoughupdates/overlays/CustomArmour.java create mode 100644 src/main/resources/assets/notenoughupdates/social/patreon.png (limited to 'src/main/resources/assets') diff --git a/src/main/java/io/github/moulberry/notenoughupdates/options/NEUConfig.java b/src/main/java/io/github/moulberry/notenoughupdates/options/NEUConfig.java index a239e741..b16092ab 100644 --- a/src/main/java/io/github/moulberry/notenoughupdates/options/NEUConfig.java +++ b/src/main/java/io/github/moulberry/notenoughupdates/options/NEUConfig.java @@ -12,7 +12,7 @@ import io.github.moulberry.notenoughupdates.miscgui.GuiEnchantColour; import io.github.moulberry.notenoughupdates.miscgui.GuiInvButtonEditor; import io.github.moulberry.notenoughupdates.miscgui.NEUOverlayPlacements; import io.github.moulberry.notenoughupdates.options.seperateSections.*; -import io.github.moulberry.notenoughupdates.overlays.CustomArmour; +import io.github.moulberry.notenoughupdates.options.seperateSections.CustomArmour; import io.github.moulberry.notenoughupdates.overlays.MiningOverlay; import io.github.moulberry.notenoughupdates.overlays.OverlayManager; import io.github.moulberry.notenoughupdates.overlays.TextOverlay; diff --git a/src/main/java/io/github/moulberry/notenoughupdates/options/NEUConfigEditor.java b/src/main/java/io/github/moulberry/notenoughupdates/options/NEUConfigEditor.java index da94d1e1..41739ece 100644 --- a/src/main/java/io/github/moulberry/notenoughupdates/options/NEUConfigEditor.java +++ b/src/main/java/io/github/moulberry/notenoughupdates/options/NEUConfigEditor.java @@ -40,6 +40,7 @@ public class NEUConfigEditor extends GuiElement { GITHUB, TWITTER, YOUTUBE, + PATREON, TWITCH }; private static final String[] socialsLink = new String[]{ @@ -47,6 +48,7 @@ public class NEUConfigEditor extends GuiElement { "https://github.com/Moulberry/NotEnoughUpdates", "https://twitter.com/moulberry/", "https://www.youtube.com/channel/UCPh-OKmRSS3IQi9p6YppLcw", + "https://patreon.com/moulberry", "https://www.twitch.tv/moulberry2" }; diff --git a/src/main/java/io/github/moulberry/notenoughupdates/options/seperateSections/AHGraph.java b/src/main/java/io/github/moulberry/notenoughupdates/options/seperateSections/AHGraph.java index ce4c8f09..3e9cb4e4 100644 --- a/src/main/java/io/github/moulberry/notenoughupdates/options/seperateSections/AHGraph.java +++ b/src/main/java/io/github/moulberry/notenoughupdates/options/seperateSections/AHGraph.java @@ -7,7 +7,7 @@ import org.lwjgl.input.Keyboard; public class AHGraph { @Expose @ConfigOption( - name = "Enabled", + name = "Enable AH/BZ Price Graph", desc = "Enable or disable the graph. Disabling this will also make it so that no price data is stored." ) @ConfigEditorBoolean diff --git a/src/main/java/io/github/moulberry/notenoughupdates/options/seperateSections/CustomArmour.java b/src/main/java/io/github/moulberry/notenoughupdates/options/seperateSections/CustomArmour.java new file mode 100644 index 00000000..5ebbeb46 --- /dev/null +++ b/src/main/java/io/github/moulberry/notenoughupdates/options/seperateSections/CustomArmour.java @@ -0,0 +1,28 @@ +package io.github.moulberry.notenoughupdates.options.seperateSections; + +import com.google.gson.annotations.Expose; +import io.github.moulberry.notenoughupdates.core.config.annotations.ConfigEditorBoolean; +import io.github.moulberry.notenoughupdates.core.config.annotations.ConfigEditorDropdown; +import io.github.moulberry.notenoughupdates.core.config.annotations.ConfigOption; + +public class CustomArmour { + + @Expose + @ConfigOption( + name = "Enable Custom Armour Hud", + desc = "Shows an overlay in your inventory showing your 4 extra armour slots" + ) + @ConfigEditorBoolean + public boolean enableArmourHud = true; + + @Expose + @ConfigOption( + name = "GUI Colour", + desc = "Change the colour of the GUI" + ) + @ConfigEditorDropdown( + values = {"Vanilla", "Grey", "Dark", "Transparent", "FSR"} + ) + public int colourStyle = 0; + +} diff --git a/src/main/java/io/github/moulberry/notenoughupdates/options/seperateSections/Fishing.java b/src/main/java/io/github/moulberry/notenoughupdates/options/seperateSections/Fishing.java index 61fcc559..e04bfe57 100644 --- a/src/main/java/io/github/moulberry/notenoughupdates/options/seperateSections/Fishing.java +++ b/src/main/java/io/github/moulberry/notenoughupdates/options/seperateSections/Fishing.java @@ -22,7 +22,7 @@ public class Fishing { @Expose @ConfigOption( - name = "Fish Warning (R)", + name = "Enable Fish Warning (R)", desc = "Display a red '!' when you need to pull the fish up. The warning takes your ping into account" ) @ConfigEditorBoolean @@ -31,7 +31,7 @@ public class Fishing { @Expose @ConfigOption( - name = "Fish Warning (Y)", + name = "Enable Fish Warning (Y)", desc = "Display a yellow '!' when a fish is approaching your bobber" ) @ConfigEditorBoolean @@ -40,7 +40,7 @@ public class Fishing { @Expose @ConfigOption( - name = "Hooked Sound", + name = "Enable Hooked Sound", desc = "Play a high-pitched ding sound when the '!' turns red" ) @ConfigEditorBoolean @@ -49,7 +49,7 @@ public class Fishing { @Expose @ConfigOption( - name = "Approach Sound", + name = "Enable Approach Sound", desc = "Play low-pitched ding sounds while the yellow '!' is visible" ) @ConfigEditorBoolean diff --git a/src/main/java/io/github/moulberry/notenoughupdates/options/seperateSections/LocationEdit.java b/src/main/java/io/github/moulberry/notenoughupdates/options/seperateSections/LocationEdit.java index dd5fcd64..6b9f6bee 100644 --- a/src/main/java/io/github/moulberry/notenoughupdates/options/seperateSections/LocationEdit.java +++ b/src/main/java/io/github/moulberry/notenoughupdates/options/seperateSections/LocationEdit.java @@ -2,9 +2,7 @@ package io.github.moulberry.notenoughupdates.options.seperateSections; import com.google.gson.annotations.Expose; import io.github.moulberry.notenoughupdates.core.config.Position; -import io.github.moulberry.notenoughupdates.core.config.annotations.ConfigAccordionId; -import io.github.moulberry.notenoughupdates.core.config.annotations.ConfigEditorButton; -import io.github.moulberry.notenoughupdates.core.config.annotations.ConfigOption; +import io.github.moulberry.notenoughupdates.core.config.annotations.*; public class LocationEdit { @Expose @@ -21,65 +19,62 @@ public class LocationEdit { @Expose @ConfigOption( - name = "Overlay Position", - desc = "Change the position of the Dwarven Mines information Overlay (commisions, powder & forge statuses)" + name = "Edit Pet Info Position", + desc = "The position of the pet info overlay." ) @ConfigEditorButton( - runnableId = 1, + runnableId = 4, buttonText = "Edit" ) - public Position overlayPosition = new Position(10, 100); + public Position petInfoPosition = new Position(-1, -1); @Expose @ConfigOption( - name = "Fuel Bar Position", - desc = "Set the position of the drill fuel bar" + name = "Edit Todo Position", + desc = "Change the position of the Todo overlay" ) @ConfigEditorButton( - runnableId = 2, + runnableId = 5, buttonText = "Edit" ) - public Position drillFuelBarPosition = new Position(0, -100, true, false); + @ConfigAccordionId(id = 0) + public Position todoPosition = new Position(100, 0); @Expose @ConfigOption( - name = "Farming Position", - desc = "Change the position of the Farming overlay" + name = "Edit Bonemerang Overlay Position", + desc = "The position of the Bonemerang overlay." ) @ConfigEditorButton( - runnableId = 3, + runnableId = 9, buttonText = "Edit" ) - public Position farmingPosition = new Position(10, 200); + public Position bonemerangPosition = new Position(-1, -1); @Expose @ConfigOption( - name = "Pet Info Position", - desc = "The position of the pet info." + name = "Edit Slayer Overlay Position", + desc = "Change the position of the Slayer overlay" ) @ConfigEditorButton( - runnableId = 4, + runnableId = 18, buttonText = "Edit" ) - public Position petInfoPosition = new Position(-1, -1); + public Position slayerPosition = new Position(10, 200); - @Expose @ConfigOption( - name = "Todo Position", - desc = "Change the position of the Todo overlay" - ) - @ConfigEditorButton( - runnableId = 5, - buttonText = "Edit" + name = "Inventory", + desc = "" ) - @ConfigAccordionId(id = 0) - public Position todoPosition = new Position(100, 0); + @ConfigEditorAccordion(id = 1) + public boolean inventoryAccordion = false; @Expose @ConfigOption( name = "Edit Toolbar Positions", desc = "Edit the position of the QuickCommands / Search Bar" ) + @ConfigAccordionId(id = 1) @ConfigEditorButton(runnableId = 6, buttonText = "Edit") public boolean positionButton = true; @@ -88,72 +83,105 @@ public class LocationEdit { name = "Open Button Editor", desc = "Open button editor GUI (/neubuttons)" ) + @ConfigAccordionId(id = 1) @ConfigEditorButton(runnableId = 7, buttonText = "Open") public boolean openEditorButton = true; + @ConfigOption( + name = "Mining Overlays", + desc = "" + ) + @ConfigEditorAccordion(id = 2) + public boolean miningoverlayAccordion = false; + @Expose @ConfigOption( - name = "Bonemerang Overlay Position", - desc = "The position of the Bonemerang overlay." + name = "Edit Dwarven Overlay Position", + desc = "Change the position of the Dwarven Mines information Overlay (commisions, powder & forge statuses)" ) @ConfigEditorButton( - runnableId = 9, + runnableId = 1, buttonText = "Edit" ) - public Position bonemerangPosition = new Position(-1, -1); + @ConfigAccordionId(id = 2) + public Position overlayPosition = new Position(10, 100); @Expose @ConfigOption( - name = "Overlay Position", + name = "Edit Crystal Overlay Position", desc = "Change the position of the Crystal Hollows Overlay." ) @ConfigEditorButton( runnableId = 10, buttonText = "Edit" ) + @ConfigAccordionId(id = 2) public Position crystalHollowOverlayPosition = new Position(200, 0); @Expose @ConfigOption( - name = "Mining Position", - desc = "Change the position of the Mining overlay" + name = "Edit Fuel Bar Position", + desc = "Set the position of the drill fuel bar" ) @ConfigEditorButton( - runnableId = 11, + runnableId = 2, buttonText = "Edit" ) - public Position miningPosition = new Position(10, 200); + @ConfigAccordionId(id = 2) + public Position drillFuelBarPosition = new Position(0, -100, true, false); + + @ConfigOption( + name = "Skill Overlays", + desc = "" + ) + @ConfigEditorAccordion(id = 3) + public boolean skilloverlayAccordion = false; @Expose @ConfigOption( - name = "Fishing Position", - desc = "Change the position of the Fishing overlay" + name = "Edit Farming Overlay Position", + desc = "Change the position of the Farming overlay" ) @ConfigEditorButton( - runnableId = 14, + runnableId = 3, buttonText = "Edit" ) - public Position fishingPosition = new Position(10, 200); + @ConfigAccordionId(id = 3) + public Position farmingPosition = new Position(10, 200); @Expose @ConfigOption( - name = "Slayer Position", - desc = "Change the position of the Slayer overlay" + name = "Edit Mining Overlay Position", + desc = "Change the position of the Mining overlay" ) @ConfigEditorButton( - runnableId = 18, + runnableId = 11, buttonText = "Edit" ) - public Position slayerPosition = new Position(10, 200); + @ConfigAccordionId(id = 3) + public Position miningPosition = new Position(10, 200); + + @Expose + @ConfigOption( + name = "Edit Fishing Overlay Position", + desc = "Change the position of the Fishing overlay" + ) + @ConfigEditorButton( + runnableId = 14, + buttonText = "Edit" + ) + @ConfigAccordionId(id = 3) + public Position fishingPosition = new Position(10, 200); @Expose @ConfigOption( - name = "Combat Position", + name = "Edit Combat Overlay Position", desc = "Change the position of the Combat overlay" ) @ConfigEditorButton( runnableId = 19, buttonText = "Edit" ) + @ConfigAccordionId(id = 3) public Position combatPosition = new Position(10, 200); } diff --git a/src/main/java/io/github/moulberry/notenoughupdates/options/seperateSections/Mining.java b/src/main/java/io/github/moulberry/notenoughupdates/options/seperateSections/Mining.java index c5580011..eea442b5 100644 --- a/src/main/java/io/github/moulberry/notenoughupdates/options/seperateSections/Mining.java +++ b/src/main/java/io/github/moulberry/notenoughupdates/options/seperateSections/Mining.java @@ -83,7 +83,7 @@ public class Mining { @Expose @ConfigOption( - name = "Fuel Bar Position", + name = "Edit Fuel Bar Position", desc = "Set the position of the drill fuel bar" ) @ConfigEditorButton( @@ -102,7 +102,7 @@ public class Mining { @Expose @ConfigOption( - name = "Dwarven Overlay", + name = "Enable Dwarven Overlay", desc = "Show an Overlay with useful information on the screen while in Dwarven Mines" ) @ConfigEditorBoolean @@ -127,7 +127,7 @@ public class Mining { @Expose @ConfigOption( - name = "Overlay Position", + name = "Edit Dwarven Overlay Position", desc = "Change the position of the Dwarven Mines information Overlay (commisions, powder & forge statuses)" ) @ConfigEditorButton( @@ -214,7 +214,7 @@ public class Mining { @Expose @ConfigOption( - name = "Enable Overlay", + name = "Enable Crystal Overlay", desc = "Enables the Crystal Hollows Overlay." ) @ConfigEditorBoolean @@ -223,7 +223,7 @@ public class Mining { @Expose @ConfigOption( - name = "Overlay Position", + name = "Edit Crystal Overlay Position", desc = "Change the position of the Crystal Hollows Overlay." ) @ConfigEditorButton( diff --git a/src/main/java/io/github/moulberry/notenoughupdates/options/seperateSections/MiscOverlays.java b/src/main/java/io/github/moulberry/notenoughupdates/options/seperateSections/MiscOverlays.java index aec7b326..5749ced1 100644 --- a/src/main/java/io/github/moulberry/notenoughupdates/options/seperateSections/MiscOverlays.java +++ b/src/main/java/io/github/moulberry/notenoughupdates/options/seperateSections/MiscOverlays.java @@ -247,7 +247,7 @@ public class MiscOverlays { @Expose @ConfigOption( - name = "Todo Position", + name = "Edit Todo Overlay Position", desc = "Change the position of the Todo overlay" ) @ConfigEditorButton( diff --git a/src/main/java/io/github/moulberry/notenoughupdates/options/seperateSections/PetOverlay.java b/src/main/java/io/github/moulberry/notenoughupdates/options/seperateSections/PetOverlay.java index a9140fe3..e8d385b5 100644 --- a/src/main/java/io/github/moulberry/notenoughupdates/options/seperateSections/PetOverlay.java +++ b/src/main/java/io/github/moulberry/notenoughupdates/options/seperateSections/PetOverlay.java @@ -19,7 +19,7 @@ public class PetOverlay { @Expose @ConfigOption( - name = "Pet Info Position", + name = "Edit Pet Info Position", desc = "The position of the pet info." ) @ConfigEditorButton( diff --git a/src/main/java/io/github/moulberry/notenoughupdates/options/seperateSections/SkillOverlays.java b/src/main/java/io/github/moulberry/notenoughupdates/options/seperateSections/SkillOverlays.java index cc419380..92697cb4 100644 --- a/src/main/java/io/github/moulberry/notenoughupdates/options/seperateSections/SkillOverlays.java +++ b/src/main/java/io/github/moulberry/notenoughupdates/options/seperateSections/SkillOverlays.java @@ -77,7 +77,7 @@ public class SkillOverlays { @Expose @ConfigOption( - name = "Farming Position", + name = "Edit Farming Overlay Position", desc = "Change the position of the Farming overlay" ) @ConfigEditorButton( @@ -134,7 +134,7 @@ public class SkillOverlays { @Expose @ConfigOption( - name = "Mining Position", + name = "Edit Mining Overlay Position", desc = "Change the position of the Mining overlay" ) @ConfigEditorButton( @@ -193,7 +193,7 @@ public class SkillOverlays { @Expose @ConfigOption( - name = "Fishing Position", + name = "Edit Fishing Overlay Position", desc = "Change the position of the Fishing overlay" ) @ConfigEditorButton( @@ -284,7 +284,7 @@ public class SkillOverlays { @Expose @ConfigOption( - name = "Combat Position", + name = "Edit Combat Overlay Position", desc = "Change the position of the Combat overlay" ) @ConfigEditorButton( diff --git a/src/main/java/io/github/moulberry/notenoughupdates/options/seperateSections/SlayerOverlay.java b/src/main/java/io/github/moulberry/notenoughupdates/options/seperateSections/SlayerOverlay.java index de05c0f2..32da4691 100644 --- a/src/main/java/io/github/moulberry/notenoughupdates/options/seperateSections/SlayerOverlay.java +++ b/src/main/java/io/github/moulberry/notenoughupdates/options/seperateSections/SlayerOverlay.java @@ -21,7 +21,7 @@ public class SlayerOverlay { @Expose @ConfigOption( - name = "Slayer Overlay", + name = "Enable Slayer Overlay", desc = "Toggles the slayer overlay" ) @ConfigEditorBoolean @@ -46,7 +46,7 @@ public class SlayerOverlay { @Expose @ConfigOption( - name = "Slayer Position", + name = "Edit Slayer Overlay Position", desc = "Change the position of the Slayer overlay" ) @ConfigEditorButton( diff --git a/src/main/java/io/github/moulberry/notenoughupdates/overlays/CustomArmour.java b/src/main/java/io/github/moulberry/notenoughupdates/overlays/CustomArmour.java deleted file mode 100644 index 35e325bb..00000000 --- a/src/main/java/io/github/moulberry/notenoughupdates/overlays/CustomArmour.java +++ /dev/null @@ -1,28 +0,0 @@ -package io.github.moulberry.notenoughupdates.overlays; - -import com.google.gson.annotations.Expose; -import io.github.moulberry.notenoughupdates.core.config.annotations.ConfigEditorBoolean; -import io.github.moulberry.notenoughupdates.core.config.annotations.ConfigEditorDropdown; -import io.github.moulberry.notenoughupdates.core.config.annotations.ConfigOption; - -public class CustomArmour { - - @Expose - @ConfigOption( - name = "Enables Custom Amour Hud", - desc = "Shows an overlay in your inventory showing your 4 extra armour slots" - ) - @ConfigEditorBoolean - public boolean enableArmourHud = true; - - @Expose - @ConfigOption( - name = "GUI Colour", - desc = "Change the colour of the GUI" - ) - @ConfigEditorDropdown( - values = {"Vanilla", "Grey", "Dark", "Transparent", "FSR"} - ) - public int colourStyle = 0; - -} diff --git a/src/main/java/io/github/moulberry/notenoughupdates/util/GuiTextures.java b/src/main/java/io/github/moulberry/notenoughupdates/util/GuiTextures.java index fad58b17..60fd7f13 100644 --- a/src/main/java/io/github/moulberry/notenoughupdates/util/GuiTextures.java +++ b/src/main/java/io/github/moulberry/notenoughupdates/util/GuiTextures.java @@ -24,9 +24,10 @@ public class GuiTextures { public static final ResourceLocation DISCORD = new ResourceLocation("notenoughupdates:social/discord.png"); public static final ResourceLocation GITHUB = new ResourceLocation("notenoughupdates:social/github.png"); - public static final ResourceLocation TWITCH = new ResourceLocation("notenoughupdates:social/twitch.png"); + public static final ResourceLocation PATREON = new ResourceLocation("notenoughupdates:social/patreon.png"); public static final ResourceLocation TWITTER = new ResourceLocation("notenoughupdates:social/twitter.png"); public static final ResourceLocation YOUTUBE = new ResourceLocation("notenoughupdates:social/youtube.png"); + public static final ResourceLocation TWITCH = new ResourceLocation("notenoughupdates:social/twitch.png"); public static final ResourceLocation item_mask = new ResourceLocation("notenoughupdates:item_mask.png"); public static final ResourceLocation item_haschild = new ResourceLocation("notenoughupdates:item_haschild.png"); diff --git a/src/main/resources/assets/notenoughupdates/social/patreon.png b/src/main/resources/assets/notenoughupdates/social/patreon.png new file mode 100644 index 00000000..00a169de Binary files /dev/null and b/src/main/resources/assets/notenoughupdates/social/patreon.png differ -- cgit From f11f6953a207606ae920ede9e713467a47cfc018 Mon Sep 17 00:00:00 2001 From: Roman / Nea Date: Sat, 12 Feb 2022 13:53:01 +0100 Subject: Dream skin (#80) --- Update Notes/2.1.md | 1 + .../moulberry/notenoughupdates/NEUManager.java | 18 ++- .../moulberry/notenoughupdates/NEUOverlay.java | 17 +-- .../notenoughupdates/auction/APIManager.java | 1 + .../notenoughupdates/commands/Commands.java | 11 +- .../notenoughupdates/miscgui/GuiItemRecipe.java | 4 +- .../notenoughupdates/mixins/MixinEntity.java | 24 ++++ .../mixins/MixinEntityAgeable.java | 21 +++ .../notenoughupdates/mixins/MixinEntityPlayer.java | 40 ++++++ .../notenoughupdates/recipes/CraftingRecipe.java | 7 +- .../notenoughupdates/recipes/ForgeRecipe.java | 9 +- .../notenoughupdates/recipes/NeuRecipe.java | 17 ++- .../recipes/VillagerTradeRecipe.java | 145 +++++++++++++++++++++ .../moulberry/notenoughupdates/util/SBInfo.java | 110 +++++++++++++++- .../assets/notenoughupdates/dreamskin.png | Bin 0 -> 220 bytes .../textures/gui/villager_recipe.png | Bin 0 -> 8633 bytes src/main/resources/mixins.notenoughupdates.json | 73 ++++++----- 17 files changed, 432 insertions(+), 66 deletions(-) create mode 100644 src/main/java/io/github/moulberry/notenoughupdates/mixins/MixinEntity.java create mode 100644 src/main/java/io/github/moulberry/notenoughupdates/mixins/MixinEntityAgeable.java create mode 100644 src/main/java/io/github/moulberry/notenoughupdates/recipes/VillagerTradeRecipe.java create mode 100644 src/main/resources/assets/notenoughupdates/dreamskin.png create mode 100644 src/main/resources/assets/notenoughupdates/textures/gui/villager_recipe.png (limited to 'src/main/resources/assets') diff --git a/Update Notes/2.1.md b/Update Notes/2.1.md index ee124398..d6618bd3 100644 --- a/Update Notes/2.1.md +++ b/Update Notes/2.1.md @@ -15,6 +15,7 @@ - [Price graph for items on /ah and /bz](https://cdn.discordapp.com/attachments/896407218151366687/926968296929107999/unknown.png) - DeDiamondPro ### **Minor Changes:** - Add built-in recipes for forge crafts - nea89 +- Add Stranded Villager Trades to the item list - nea89 - Make cata xp in /pv be calculated on how many runs you have and shows master mode xp rates - Hide mine waypoints when at location setting - Lulonaut - Added some info panels to some settings in /neu diff --git a/src/main/java/io/github/moulberry/notenoughupdates/NEUManager.java b/src/main/java/io/github/moulberry/notenoughupdates/NEUManager.java index 614884d9..bf3a0714 100644 --- a/src/main/java/io/github/moulberry/notenoughupdates/NEUManager.java +++ b/src/main/java/io/github/moulberry/notenoughupdates/NEUManager.java @@ -3,7 +3,6 @@ package io.github.moulberry.notenoughupdates; import com.google.gson.*; import io.github.moulberry.notenoughupdates.auction.APIManager; import io.github.moulberry.notenoughupdates.miscgui.GuiItemRecipe; -import io.github.moulberry.notenoughupdates.options.NEUConfig; import io.github.moulberry.notenoughupdates.recipes.CraftingOverlay; import io.github.moulberry.notenoughupdates.recipes.CraftingRecipe; import io.github.moulberry.notenoughupdates.recipes.Ingredient; @@ -33,6 +32,7 @@ import java.util.*; import java.util.concurrent.CompletableFuture; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; +import java.util.stream.Collectors; import java.util.zip.ZipEntry; import java.util.zip.ZipInputStream; @@ -418,10 +418,18 @@ public class NEUManager { return recipesMap.getOrDefault(internalName, Collections.emptySet()); } + public List getAvailableRecipesFor(String internalname) { + return getRecipesFor(internalname).stream().filter(NeuRecipe::isAvailable).collect(Collectors.toList()); + } + public Set getUsagesFor(String internalName) { return usagesMap.getOrDefault(internalName, Collections.emptySet()); } + public List getAvailableUsagesFor(String internalname) { + return getUsagesFor(internalname).stream().filter(NeuRecipe::isAvailable).collect(Collectors.toList()); + } + /** * Searches a string for a query. This method is used to mimic the behaviour of the more complex map-based search * function. This method is used for the chest-item-search feature. @@ -952,19 +960,19 @@ public class NEUManager { public boolean displayGuiItemUsages(String internalName) { if (!usagesMap.containsKey(internalName)) return false; - Set usages = usagesMap.get(internalName); + List usages = getAvailableUsagesFor(internalName); if (usages.isEmpty()) return false; Minecraft.getMinecraft().displayGuiScreen( - new GuiItemRecipe("Item Usages", new ArrayList<>(usages), this)); + new GuiItemRecipe("Item Usages", usages, this)); return true; } public boolean displayGuiItemRecipe(String internalName, String text) { if (!recipesMap.containsKey(internalName)) return false; - Set recipes = recipesMap.get(internalName); + List recipes = getAvailableRecipesFor(internalName); if (recipes.isEmpty()) return false; Minecraft.getMinecraft().displayGuiScreen( - new GuiItemRecipe(text != null ? text : "Item Recipe", new ArrayList<>(recipes), this)); + new GuiItemRecipe(text != null ? text : "Item Recipe", recipes, this)); return true; } diff --git a/src/main/java/io/github/moulberry/notenoughupdates/NEUOverlay.java b/src/main/java/io/github/moulberry/notenoughupdates/NEUOverlay.java index 1fbffd5f..04ed9964 100644 --- a/src/main/java/io/github/moulberry/notenoughupdates/NEUOverlay.java +++ b/src/main/java/io/github/moulberry/notenoughupdates/NEUOverlay.java @@ -62,9 +62,8 @@ import org.lwjgl.opengl.GL11; import org.lwjgl.opengl.GL14; import org.lwjgl.util.vector.Vector2f; -import java.awt.*; +import java.awt.Color; import java.lang.reflect.InvocationTargetException; -import java.util.List; import java.util.*; import java.util.concurrent.CompletableFuture; import java.util.concurrent.ExecutorService; @@ -2345,14 +2344,10 @@ public class NEUOverlay extends Gui { ItemPriceInformation.addToTooltip(text, internalname, stack); } - boolean hasClick = false; - boolean hasInfo = false; - if (json.has("clickcommand") && !json.get("clickcommand").getAsString().isEmpty()) { - hasClick = true; - } - if (json.has("info") && json.get("info").getAsJsonArray().size() > 0) { - hasInfo = true; - } + boolean hasClick = + (json.has("clickcommand") && !json.get("clickcommand").getAsString().isEmpty()) + || !manager.getAvailableRecipesFor(internalname).isEmpty(); + boolean hasInfo = json.has("info") && json.get("info").getAsJsonArray().size() > 0; if (hasClick || hasInfo) text.add(""); if (hasClick) @@ -2685,4 +2680,4 @@ public class NEUOverlay extends Gui { public float getInfoPaneOffsetFactor() { return infoPaneOffsetFactor.getValue() * getWidthMult(); } -} \ No newline at end of file +} diff --git a/src/main/java/io/github/moulberry/notenoughupdates/auction/APIManager.java b/src/main/java/io/github/moulberry/notenoughupdates/auction/APIManager.java index d0b4a7f5..9455eb64 100644 --- a/src/main/java/io/github/moulberry/notenoughupdates/auction/APIManager.java +++ b/src/main/java/io/github/moulberry/notenoughupdates/auction/APIManager.java @@ -799,6 +799,7 @@ public class APIManager { if (recipes != null) RECIPE_ITER: for (NeuRecipe recipe : recipes) { + if (recipe.hasVariableCost() || !recipe.shouldUseForCraftCost()) continue; float craftPrice = 0; for (Ingredient i : recipe.getIngredients()) { if (i.isCoins()) { diff --git a/src/main/java/io/github/moulberry/notenoughupdates/commands/Commands.java b/src/main/java/io/github/moulberry/notenoughupdates/commands/Commands.java index d3fd7e0c..50662a80 100644 --- a/src/main/java/io/github/moulberry/notenoughupdates/commands/Commands.java +++ b/src/main/java/io/github/moulberry/notenoughupdates/commands/Commands.java @@ -14,13 +14,13 @@ import io.github.moulberry.notenoughupdates.cosmetics.GuiCosmetics; import io.github.moulberry.notenoughupdates.dungeons.DungeonWin; import io.github.moulberry.notenoughupdates.dungeons.GuiDungeonMapEditor; import io.github.moulberry.notenoughupdates.gamemodes.GuiGamemodes; -import io.github.moulberry.notenoughupdates.miscfeatures.customblockzones.CustomBiomes; -import io.github.moulberry.notenoughupdates.miscfeatures.customblockzones.LocationChangeEvent; -import io.github.moulberry.notenoughupdates.miscfeatures.customblockzones.SpecialBlockZone; import io.github.moulberry.notenoughupdates.miscfeatures.FairySouls; import io.github.moulberry.notenoughupdates.miscfeatures.FancyPortals; import io.github.moulberry.notenoughupdates.miscfeatures.FishingHelper; import io.github.moulberry.notenoughupdates.miscfeatures.NullzeeSphere; +import io.github.moulberry.notenoughupdates.miscfeatures.customblockzones.CustomBiomes; +import io.github.moulberry.notenoughupdates.miscfeatures.customblockzones.LocationChangeEvent; +import io.github.moulberry.notenoughupdates.miscfeatures.customblockzones.SpecialBlockZone; import io.github.moulberry.notenoughupdates.miscgui.*; import io.github.moulberry.notenoughupdates.miscgui.tutorials.NeuTutorial; import io.github.moulberry.notenoughupdates.options.NEUConfig; @@ -745,6 +745,11 @@ public class Commands { DupePOC.doDupe(args[0]); return; }*/ + if (args.length >= 1 && args[0].equalsIgnoreCase("profileinfo")) { + String currentProfile = SBInfo.getInstance().currentProfile; + SBInfo.Gamemode gamemode = SBInfo.getInstance().getGamemodeForProfile(currentProfile); + sender.addChatMessage(new ChatComponentText(EnumChatFormatting.GOLD + "You are on Profile " + currentProfile + " with the mode " + gamemode)); + } if (args.length >= 1 && args[0].equalsIgnoreCase("pricetest")) { if (args.length == 1) { NotEnoughUpdates.INSTANCE.manager.auctionManager.updateBazaar(); diff --git a/src/main/java/io/github/moulberry/notenoughupdates/miscgui/GuiItemRecipe.java b/src/main/java/io/github/moulberry/notenoughupdates/miscgui/GuiItemRecipe.java index e820378b..6e4d13f6 100644 --- a/src/main/java/io/github/moulberry/notenoughupdates/miscgui/GuiItemRecipe.java +++ b/src/main/java/io/github/moulberry/notenoughupdates/miscgui/GuiItemRecipe.java @@ -90,7 +90,7 @@ public class GuiItemRecipe extends GuiScreen { Minecraft.getMinecraft().getTextureManager().bindTexture(currentRecipe.getBackground()); this.drawTexturedModalRect(guiLeft, guiTop, 0, 0, this.xSize, this.ySize); - currentRecipe.drawExtraBackground(this); + currentRecipe.drawExtraBackground(this, mouseX, mouseY); List slots = getAllRenderedSlots(); for (RecipeSlot slot : slots) { @@ -101,7 +101,7 @@ public class GuiItemRecipe extends GuiScreen { Utils.drawStringScaledMaxWidth(title, fontRendererObj, guiLeft + TITLE_X, guiTop + TITLE_Y, false, xSize - 38, 0x404040); - currentRecipe.drawExtraInfo(this); + currentRecipe.drawExtraInfo(this, mouseX, mouseY); for (RecipeSlot slot : slots) { if (isWithinRect(mouseX, mouseY, slot.getX(this), slot.getY(this), SLOT_SIZE, SLOT_SIZE)) { diff --git a/src/main/java/io/github/moulberry/notenoughupdates/mixins/MixinEntity.java b/src/main/java/io/github/moulberry/notenoughupdates/mixins/MixinEntity.java new file mode 100644 index 00000000..6e8f5cd2 --- /dev/null +++ b/src/main/java/io/github/moulberry/notenoughupdates/mixins/MixinEntity.java @@ -0,0 +1,24 @@ +package io.github.moulberry.notenoughupdates.mixins; + +import net.minecraft.entity.Entity; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.Inject; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; + +@Mixin(Entity.class) +public class MixinEntity { + // Fix NPE in vanilla code, that we need to work for VillagerTradeRecipe + @Inject(method = "getBrightnessForRender", at = @At("HEAD"), cancellable = true) + public void onGetBrightnessForRender(float p_getBrightnessForRender_1_, CallbackInfoReturnable cir) { + if (((Entity) (Object) this).worldObj == null) + cir.setReturnValue(-1); + } + + // Fix NPE in vanilla code, that we need to work for VillagerTradeRecipe + @Inject(method = "getBrightness", at = @At("HEAD"), cancellable = true) + public void onGetBrightness(float p_getBrightness_1_, CallbackInfoReturnable cir) { + if (((Entity) (Object) this).worldObj == null) + cir.setReturnValue(1.0F); + } +} diff --git a/src/main/java/io/github/moulberry/notenoughupdates/mixins/MixinEntityAgeable.java b/src/main/java/io/github/moulberry/notenoughupdates/mixins/MixinEntityAgeable.java new file mode 100644 index 00000000..a6f6c0c6 --- /dev/null +++ b/src/main/java/io/github/moulberry/notenoughupdates/mixins/MixinEntityAgeable.java @@ -0,0 +1,21 @@ +package io.github.moulberry.notenoughupdates.mixins; + +import net.minecraft.entity.EntityAgeable; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.Shadow; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.Inject; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; + +@Mixin(EntityAgeable.class) +public class MixinEntityAgeable { + @Shadow + protected int growingAge; + + // Fix NPE in vanilla code, that we need to work for VillagerTradeRecipe + @Inject(method = "getGrowingAge", cancellable = true, at = @At("HEAD")) + public void onGetGrowingAge(CallbackInfoReturnable cir) { + if (((EntityAgeable) (Object) this).worldObj == null) + cir.setReturnValue(growingAge); + } +} diff --git a/src/main/java/io/github/moulberry/notenoughupdates/mixins/MixinEntityPlayer.java b/src/main/java/io/github/moulberry/notenoughupdates/mixins/MixinEntityPlayer.java index 218e03eb..21063ea6 100644 --- a/src/main/java/io/github/moulberry/notenoughupdates/mixins/MixinEntityPlayer.java +++ b/src/main/java/io/github/moulberry/notenoughupdates/mixins/MixinEntityPlayer.java @@ -1,15 +1,26 @@ package io.github.moulberry.notenoughupdates.mixins; import io.github.moulberry.notenoughupdates.cosmetics.CapeManager; +import net.minecraft.entity.Entity; import net.minecraft.entity.player.EntityPlayer; import net.minecraft.entity.player.EnumPlayerModelParts; +import net.minecraft.scoreboard.ScorePlayerTeam; +import net.minecraft.scoreboard.Scoreboard; +import net.minecraft.util.BlockPos; +import net.minecraft.world.World; +import org.spongepowered.asm.lib.Opcodes; import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.Shadow; import org.spongepowered.asm.mixin.injection.At; import org.spongepowered.asm.mixin.injection.Inject; +import org.spongepowered.asm.mixin.injection.Redirect; import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; @Mixin({EntityPlayer.class}) public abstract class MixinEntityPlayer { + @Shadow + public abstract boolean interactWith(Entity par1); + @Inject(method = "isWearing", at = @At("HEAD"), cancellable = true) public void isWearing(EnumPlayerModelParts part, CallbackInfoReturnable cir) { if (part == EnumPlayerModelParts.CAPE) { @@ -21,4 +32,33 @@ public abstract class MixinEntityPlayer { } } } + + @Redirect(method = "", at = @At(value = "FIELD", target = "Lnet/minecraft/world/World;isRemote:Z", opcode = Opcodes.GETFIELD)) + public boolean onIsRemote(World instance) { + if (instance == null) return true; + return instance.isRemote; + } + + @Redirect(method = "", at = @At(value = "INVOKE", target = "Lnet/minecraft/world/World;getSpawnPoint()Lnet/minecraft/util/BlockPos;")) + public BlockPos onGetSpawnPoint(World instance) { + if (instance == null) + return new BlockPos(0, 0, 0); + return instance.getSpawnPoint(); + } + + @Inject(method = "getWorldScoreboard", at = @At("HEAD"), cancellable = true) + public void onGetWorldScoreboard(CallbackInfoReturnable cir) { + if (((EntityPlayer) (Object) this).worldObj == null) { + cir.setReturnValue(null); + } + } + + @Redirect(method = "getTeam", at = @At(value = "INVOKE", target = "Lnet/minecraft/scoreboard/Scoreboard;getPlayersTeam(Ljava/lang/String;)Lnet/minecraft/scoreboard/ScorePlayerTeam;")) + public ScorePlayerTeam onGetTeam(Scoreboard instance, String p_getPlayersTeam_1_) { + if (instance == null) { + return null; + } + return instance.getPlayersTeam(p_getPlayersTeam_1_); + } + } diff --git a/src/main/java/io/github/moulberry/notenoughupdates/recipes/CraftingRecipe.java b/src/main/java/io/github/moulberry/notenoughupdates/recipes/CraftingRecipe.java index 00e70462..082c1ad8 100644 --- a/src/main/java/io/github/moulberry/notenoughupdates/recipes/CraftingRecipe.java +++ b/src/main/java/io/github/moulberry/notenoughupdates/recipes/CraftingRecipe.java @@ -44,6 +44,11 @@ public class CraftingRecipe implements NeuRecipe { return ingredients; } + @Override + public boolean hasVariableCost() { + return false; + } + @Override public Set getOutputs() { return Collections.singleton(getOutput()); @@ -85,7 +90,7 @@ public class CraftingRecipe implements NeuRecipe { } @Override - public void drawExtraInfo(GuiItemRecipe gui) { + public void drawExtraInfo(GuiItemRecipe gui, int mouseX, int mouseY) { FontRenderer fontRenderer = Minecraft.getMinecraft().fontRendererObj; String craftingText = getCraftText(); diff --git a/src/main/java/io/github/moulberry/notenoughupdates/recipes/ForgeRecipe.java b/src/main/java/io/github/moulberry/notenoughupdates/recipes/ForgeRecipe.java index 5cbb4afe..2870a54e 100644 --- a/src/main/java/io/github/moulberry/notenoughupdates/recipes/ForgeRecipe.java +++ b/src/main/java/io/github/moulberry/notenoughupdates/recipes/ForgeRecipe.java @@ -74,6 +74,11 @@ public class ForgeRecipe implements NeuRecipe { return Sets.newHashSet(inputs); } + @Override + public boolean hasVariableCost() { + return false; + } + @Override public Set getOutputs() { return Collections.singleton(output); @@ -95,7 +100,7 @@ public class ForgeRecipe implements NeuRecipe { } @Override - public void drawExtraBackground(GuiItemRecipe gui) { + public void drawExtraBackground(GuiItemRecipe gui, int mouseX, int mouseY) { Minecraft.getMinecraft().getTextureManager().bindTexture(BACKGROUND); for (int i = 0; i < inputs.size(); i++) { int[] slotCoordinates = getSlotCoordinates(i, inputs.size()); @@ -107,7 +112,7 @@ public class ForgeRecipe implements NeuRecipe { } @Override - public void drawExtraInfo(GuiItemRecipe gui) { + public void drawExtraInfo(GuiItemRecipe gui, int mouseX, int mouseY) { FontRenderer fontRenderer = Minecraft.getMinecraft().fontRendererObj; if (timeInSeconds > 0) Utils.drawStringCenteredScaledMaxWidth(formatDuration(timeInSeconds), fontRenderer, gui.guiLeft + EXTRA_INFO_X, gui.guiTop + EXTRA_INFO_Y, false, EXTRA_INFO_MAX_WIDTH, 0xff00ff); diff --git a/src/main/java/io/github/moulberry/notenoughupdates/recipes/NeuRecipe.java b/src/main/java/io/github/moulberry/notenoughupdates/recipes/NeuRecipe.java index cfa091d5..99b05d28 100644 --- a/src/main/java/io/github/moulberry/notenoughupdates/recipes/NeuRecipe.java +++ b/src/main/java/io/github/moulberry/notenoughupdates/recipes/NeuRecipe.java @@ -15,14 +15,17 @@ public interface NeuRecipe { List getSlots(); - void drawExtraInfo(GuiItemRecipe gui); + default void drawExtraInfo(GuiItemRecipe gui, int mouseX, int mouseY) { + } - default void drawExtraBackground(GuiItemRecipe gui) { + default void drawExtraBackground(GuiItemRecipe gui, int mouseX, int mouseY) { } default void drawHoverInformation(GuiItemRecipe gui, int mouseX, int mouseY) { } + boolean hasVariableCost(); + JsonObject serialize(); ResourceLocation getBackground(); @@ -32,8 +35,18 @@ public interface NeuRecipe { switch (recipe.get("type").getAsString().intern()) { case "forge": return ForgeRecipe.parseForgeRecipe(manager, recipe, output); + case "trade": + return VillagerTradeRecipe.parseStaticRecipe(manager, recipe); } } return CraftingRecipe.parseCraftingRecipe(manager, recipe, output); } + + default boolean shouldUseForCraftCost() { + return true; + } + + default boolean isAvailable() { + return true; + } } diff --git a/src/main/java/io/github/moulberry/notenoughupdates/recipes/VillagerTradeRecipe.java b/src/main/java/io/github/moulberry/notenoughupdates/recipes/VillagerTradeRecipe.java new file mode 100644 index 00000000..530e8e32 --- /dev/null +++ b/src/main/java/io/github/moulberry/notenoughupdates/recipes/VillagerTradeRecipe.java @@ -0,0 +1,145 @@ +package io.github.moulberry.notenoughupdates.recipes; + +import com.google.common.collect.Sets; +import com.google.gson.JsonObject; +import com.mojang.authlib.GameProfile; +import io.github.moulberry.notenoughupdates.NEUManager; +import io.github.moulberry.notenoughupdates.NotEnoughUpdates; +import io.github.moulberry.notenoughupdates.miscgui.GuiItemRecipe; +import io.github.moulberry.notenoughupdates.util.SBInfo; +import io.github.moulberry.notenoughupdates.util.Utils; +import net.minecraft.client.Minecraft; +import net.minecraft.client.entity.AbstractClientPlayer; +import net.minecraft.client.gui.FontRenderer; +import net.minecraft.client.gui.inventory.GuiInventory; +import net.minecraft.client.network.NetworkPlayerInfo; +import net.minecraft.entity.EntityLivingBase; +import net.minecraft.entity.passive.EntityVillager; +import net.minecraft.util.ResourceLocation; + +import java.util.*; + +public class VillagerTradeRecipe implements NeuRecipe { + + public static final int COST_SLOT_X = 51; + public static final int COST_SLOT_Y = 34; + public static final int RESULT_SLOT_Y = 35; + public static final int RESULT_SLOT_X = 124; + + private static class Holder { // This holder object exists to defer initialization to first access + private static final GameProfile DREAM_PROFILE = new GameProfile(UUID.fromString("ec70bcaf-702f-4bb8-b48d-276fa52a780c"), "Dream"); + private static final EntityLivingBase DEMO_DREAM = new AbstractClientPlayer(null, DREAM_PROFILE) { + @Override + protected NetworkPlayerInfo getPlayerInfo() { + return new NetworkPlayerInfo(DREAM_PROFILE) { + @Override + public ResourceLocation getLocationSkin() { + return new ResourceLocation("notenoughupdates", "dreamskin.png"); + } + }; + } + }; + private static final EntityLivingBase DEMO_VILLAGER = new EntityVillager(null); + + private static boolean isAprilFirst() { + Calendar cal = Calendar.getInstance(); + return cal.get(Calendar.DAY_OF_MONTH) == 1 && cal.get(Calendar.MONTH) == Calendar.APRIL; + } + + private static final EntityLivingBase DEMO_ENTITY = isAprilFirst() ? DEMO_DREAM : DEMO_VILLAGER; + + } + + private final static ResourceLocation BACKGROUND = new ResourceLocation("notenoughupdates", "textures/gui/villager_recipe.png"); + + private final Ingredient result; + private final Ingredient cost; + private final int minCost, maxCost; + + public VillagerTradeRecipe(Ingredient result, Ingredient cost, int minCost, int maxCost) { + this.result = result; + this.cost = cost; + this.minCost = minCost; + this.maxCost = maxCost; + } + + public VillagerTradeRecipe(Ingredient result, Ingredient cost) { + this(result, cost, -1, -1); + } + + public boolean hasVariableCost() { + return minCost != -1 && maxCost != -1; + } + + @Override + public Set getIngredients() { + return Sets.newHashSet(cost); + } + + @Override + public Set getOutputs() { + return Sets.newHashSet(result); + } + + @Override + public List getSlots() { + return Arrays.asList( + new RecipeSlot(COST_SLOT_X, COST_SLOT_Y, cost.getItemStack()), + new RecipeSlot(RESULT_SLOT_X, RESULT_SLOT_Y, result.getItemStack()) + ); + } + + @Override + public boolean shouldUseForCraftCost() { + return false; + } + + @Override + public boolean isAvailable() { + return SBInfo.getInstance().getCurrentMode() == SBInfo.Gamemode.STRANDED || NotEnoughUpdates.INSTANCE.config.hidden.dev; + } + + @Override + public void drawExtraInfo(GuiItemRecipe gui, int mouseX, int mouseY) { + if (hasVariableCost()) { + FontRenderer fontRenderer = Minecraft.getMinecraft().fontRendererObj; + Utils.drawStringCenteredScaledMaxWidth( + minCost + " - " + maxCost, fontRenderer, + gui.guiLeft + 50, gui.guiTop + 60, false, 75, 0xff00ff); + + } + } + + @Override + public void drawExtraBackground(GuiItemRecipe gui, int mouseX, int mouseY) { + GuiInventory.drawEntityOnScreen(gui.guiLeft + 90, gui.guiTop + 75, 30, gui.guiLeft - mouseX + 80, gui.guiTop + 60 - mouseY, Holder.DEMO_ENTITY); + } + + @Override + public JsonObject serialize() { + JsonObject jsonObject = new JsonObject(); + jsonObject.addProperty("type", "trade"); + jsonObject.addProperty("result", result.serialize()); + jsonObject.addProperty("cost", cost.getInternalItemId()); + if (minCost > 0) + jsonObject.addProperty("min", minCost); + if (maxCost > 0) + jsonObject.addProperty("max", maxCost); + return jsonObject; + } + + @Override + public ResourceLocation getBackground() { + return BACKGROUND; + } + + public static VillagerTradeRecipe parseStaticRecipe(NEUManager manager, JsonObject recipe) { + return new VillagerTradeRecipe( + new Ingredient(manager, recipe.get("result").getAsString()), + new Ingredient(manager, recipe.get("cost").getAsString()), + recipe.has("min") ? recipe.get("min").getAsInt() : -1, + recipe.has("max") ? recipe.get("max").getAsInt() : -1 + ); + } + +} diff --git a/src/main/java/io/github/moulberry/notenoughupdates/util/SBInfo.java b/src/main/java/io/github/moulberry/notenoughupdates/util/SBInfo.java index 6dcd284e..7b5a29a9 100644 --- a/src/main/java/io/github/moulberry/notenoughupdates/util/SBInfo.java +++ b/src/main/java/io/github/moulberry/notenoughupdates/util/SBInfo.java @@ -1,13 +1,19 @@ package io.github.moulberry.notenoughupdates.util; +import com.google.common.reflect.TypeToken; import com.google.gson.JsonObject; import io.github.moulberry.notenoughupdates.NotEnoughUpdates; import io.github.moulberry.notenoughupdates.miscfeatures.customblockzones.LocationChangeEvent; import io.github.moulberry.notenoughupdates.overlays.SlayerOverlay; import net.minecraft.client.Minecraft; +import net.minecraft.client.gui.GuiScreen; import net.minecraft.client.gui.inventory.GuiChest; import net.minecraft.client.network.NetworkPlayerInfo; +import net.minecraft.init.Blocks; import net.minecraft.inventory.ContainerChest; +import net.minecraft.inventory.Slot; +import net.minecraft.item.Item; +import net.minecraft.item.ItemStack; import net.minecraft.scoreboard.Score; import net.minecraft.scoreboard.ScoreObjective; import net.minecraft.scoreboard.ScorePlayerTeam; @@ -19,13 +25,16 @@ import net.minecraftforge.common.MinecraftForge; import net.minecraftforge.event.world.WorldEvent; import net.minecraftforge.fml.common.eventhandler.EventPriority; import net.minecraftforge.fml.common.eventhandler.SubscribeEvent; +import net.minecraftforge.fml.common.gameevent.TickEvent; +import java.io.File; +import java.io.IOException; +import java.nio.charset.StandardCharsets; +import java.nio.file.Files; +import java.nio.file.Path; import java.text.ParseException; import java.text.SimpleDateFormat; -import java.util.ArrayList; -import java.util.Date; -import java.util.List; -import java.util.Objects; +import java.util.*; import java.util.regex.Matcher; import java.util.regex.Pattern; @@ -61,6 +70,31 @@ public class SBInfo { public boolean isInDungeon = false; public boolean hasNewTab = false; + + public enum Gamemode { + NORMAL("", ""), IRONMAN("Ironman", "♲"), STRANDED("Stranded", "☀"); + + private final String name; + private final String emoji; + + Gamemode(String name, String emoji) { + this.name = name; + this.emoji = emoji; + } + + public static Gamemode find(String type) { + for (Gamemode gamemode : values()) { + if (type.contains(gamemode.name)) + return gamemode; + } + return null; + } + } + + + private Map gamemodes = new HashMap<>(); + private boolean areGamemodesLoaded = false; + private int tickCount = 0; public String currentProfile = null; @SubscribeEvent @@ -76,6 +110,74 @@ public class SBInfo { } } + @SubscribeEvent + public void onGuiTick(TickEvent event) { + if (tickCount++ % 10 != 0) return; + GuiScreen currentScreen = Minecraft.getMinecraft().currentScreen; + if (currentScreen instanceof GuiChest) { + ContainerChest container = (ContainerChest) ((GuiChest) currentScreen).inventorySlots; + if ("Profile Management".equals(container.getLowerChestInventory().getDisplayName().getUnformattedText())) { + updateProfileInformation(container); + } + } + } + + private static final Pattern PROFILE_PATTERN = Pattern.compile("(?(♲ Ironman)|(☀ Stranded)|()) *Profile: (?[^ ]+)"); + + private void updateProfileInformation(ContainerChest container) { + for (int i = 11; i < 16; i = -~i) { + Slot slot = container.getSlot(i); + if (slot == null || !slot.getHasStack()) continue; + ItemStack item = slot.getStack(); + if (item == null || item.getItem() == Item.getItemFromBlock(Blocks.bedrock)) continue; + String displayName = Utils.cleanColour(item.getDisplayName()); + Matcher matcher = PROFILE_PATTERN.matcher(displayName); + if (!matcher.matches()) continue; + String type = matcher.group("type"); + String name = matcher.group("name"); + Gamemode gamemode = Gamemode.find(type); + gamemodes.put(name, gamemode); + } + areGamemodesLoaded = true; + saveGameModes(); + } + + private Path getProfilesFile() { + return new File(NotEnoughUpdates.INSTANCE.manager.configLocation, "profiles.json").toPath(); + } + + public Map getAllGamemodes() { + if (!areGamemodesLoaded) + loadGameModes(); + return gamemodes; + } + + public void saveGameModes() { + try { + Files.write(getProfilesFile(), NotEnoughUpdates.INSTANCE.manager.gson.toJson(gamemodes).getBytes(StandardCharsets.UTF_8)); + } catch (IOException e) { + e.printStackTrace(); + } + } + + public Gamemode getGamemodeForProfile(String profiles) { + return getAllGamemodes().get(profiles); + } + + public Gamemode getCurrentMode() { + return getGamemodeForProfile(currentProfile); + } + + public void loadGameModes() { + try { + gamemodes = NotEnoughUpdates.INSTANCE.manager.gson.fromJson(Files.newBufferedReader(getProfilesFile()), new TypeToken>() { + }.getType()); + areGamemodesLoaded = true; + } catch (IOException e) { + e.printStackTrace(); + } + } + @SubscribeEvent public void onWorldLoad(WorldEvent.Load event) { lastLocRaw = -1; diff --git a/src/main/resources/assets/notenoughupdates/dreamskin.png b/src/main/resources/assets/notenoughupdates/dreamskin.png new file mode 100644 index 00000000..067d396e Binary files /dev/null and b/src/main/resources/assets/notenoughupdates/dreamskin.png differ diff --git a/src/main/resources/assets/notenoughupdates/textures/gui/villager_recipe.png b/src/main/resources/assets/notenoughupdates/textures/gui/villager_recipe.png new file mode 100644 index 00000000..42b6241c Binary files /dev/null and b/src/main/resources/assets/notenoughupdates/textures/gui/villager_recipe.png differ diff --git a/src/main/resources/mixins.notenoughupdates.json b/src/main/resources/mixins.notenoughupdates.json index bec344ec..a566ee2e 100644 --- a/src/main/resources/mixins.notenoughupdates.json +++ b/src/main/resources/mixins.notenoughupdates.json @@ -3,40 +3,41 @@ "refmap": "mixins.notenoughupdates.refmap.json", "compatibilityLevel": "JAVA_8", "mixins": [ - "MixinMinecraft", - "MixinAbstractClientPlayer", - "MixinContainer", - "MixinEffectRenderer", - "MixinEntityPlayer", - "MixinEntityPlayerSP", - "MixinEntityRenderer", - "MixinGuiChest", - "MixinGuiContainer", - "MixinGuiIngame", - "MixinGuiInventory", - "MixinGuiScreen", - "MixinInventoryEffectRenderer", - "MixinInventoryPlayer", - "MixinItemCameraTransforms", - "MixinItemRenderer", - "MixinItemStack", - "MixinLayerArmorBase", - "MixinLayerCustomHead", - - "MixinMouseHelper", - "MixinNetHandlerPlayClient", - "MixinPlayerControllerMP", - "MixinRender", - "MixinRendererLivingEntity", - "MixinRenderFish", - "MixinRenderGlobal", - "MixinRenderItem", - "MixinRenderList", - "MixinTextureManager", - "MixinTileEntitySkullRenderer", - "MixinTileEntitySpecialRenderer", - "MixinVboRenderList", - "MixinWorld", - "MixinWorldClient" + "MixinAbstractClientPlayer", + "MixinContainer", + "MixinEffectRenderer", + "MixinEntity", + "MixinEntityAgeable", + "MixinEntityPlayer", + "MixinEntityPlayerSP", + "MixinEntityRenderer", + "MixinGuiChest", + "MixinGuiContainer", + "MixinGuiIngame", + "MixinGuiInventory", + "MixinGuiScreen", + "MixinInventoryEffectRenderer", + "MixinInventoryPlayer", + "MixinItemCameraTransforms", + "MixinItemRenderer", + "MixinItemStack", + "MixinLayerArmorBase", + "MixinLayerCustomHead", + "MixinMinecraft", + "MixinMouseHelper", + "MixinNetHandlerPlayClient", + "MixinPlayerControllerMP", + "MixinRender", + "MixinRendererLivingEntity", + "MixinRenderFish", + "MixinRenderGlobal", + "MixinRenderItem", + "MixinRenderList", + "MixinTextureManager", + "MixinTileEntitySkullRenderer", + "MixinTileEntitySpecialRenderer", + "MixinVboRenderList", + "MixinWorld", + "MixinWorldClient" ] -} \ No newline at end of file +} -- cgit