diff --git a/Build and copy to mods.bat b/Build and copy to mods.bat index c8d7802..7424335 100644 --- a/Build and copy to mods.bat +++ b/Build and copy to mods.bat @@ -1,5 +1,5 @@ @echo off -set MCVERSION=1.18.1 +set MCVERSION=1.19 set MODVERSION=1.1 gradlew build && copy "build\libs\PlayerStatisticsList-%MCVERSION%-%MODVERSION%.jar" "%AppData%\.minecraft\mods\PlayerStatisticsList-%MCVERSION%-%MODVERSION%.jar" pause \ No newline at end of file diff --git a/Forge-README.txt b/Forge-README.txt index 344bca7..867e97e 100644 --- a/Forge-README.txt +++ b/Forge-README.txt @@ -40,7 +40,7 @@ https://github.com/MinecraftForge/MCPConfig/blob/master/Mojang.md Additional Resources: ========================= -Community Documentation: http://mcforge.readthedocs.io/en/latest/gettingstarted/ +Community Documentation: https://mcforge.readthedocs.io/en/latest/gettingstarted/ LexManos' Install Video: https://www.youtube.com/watch?v=8VEdtQLuLO0 Forge Forum: https://forums.minecraftforge.net/ -Forge Discord: https://discord.gg/UvedJ9m \ No newline at end of file +Forge Discord: https://discord.gg/UvedJ9m diff --git a/README.md b/README.md index d187917..cbde5c1 100644 --- a/README.md +++ b/README.md @@ -3,9 +3,11 @@ A Minecraft Forge mod showing relevant statistics about the player and the world This mod is client-side only, meaning the server(s) you are joining don't need to be modded in order for this mod to work for you. +The code in this project is several years old and in need of a huge refactor. Read it at your own risk. :) + ## Requirements For running: -- Minecraft Forge Client 39.0.10 or higher (MC version 1.18.1) +- Minecraft Forge Client 41.0.98 or higher (MC version 1.19) For building: - Java SE Development Kit 17 / OpenJDK 17 or higher diff --git a/build.gradle b/build.gradle index d0fd610..aa6e915 100644 --- a/build.gradle +++ b/build.gradle @@ -1,39 +1,32 @@ -buildscript { - repositories { - // These repositories are only for Gradle plugins, put any other repositories in the repository block further below - maven { url = 'https://maven.minecraftforge.net' } - mavenCentral() - } - dependencies { - classpath group: 'net.minecraftforge.gradle', name: 'ForgeGradle', version: '5.1.+', changing: true - } +plugins { + id 'eclipse' + id 'maven-publish' + id 'net.minecraftforge.gradle' version '5.1.+' } -apply plugin: 'net.minecraftforge.gradle' -// Only edit below this line, the above code adds and enables the necessary things for Forge to be setup. -apply plugin: 'eclipse' -apply plugin: 'maven-publish' -version = '1.18.1-1.1' +version = '1.19-1.1' group = 'com.mydoomsite.statsmod' // http://maven.apache.org/guides/mini/guide-naming-conventions.html archivesBaseName = 'PlayerStatisticsList' // Mojang ships Java 17 to end users in 1.18+, so your mod should target Java 17. java.toolchain.languageVersion = JavaLanguageVersion.of(17) -println('Java: ' + System.getProperty('java.version') + ' JVM: ' + System.getProperty('java.vm.version') + '(' + System.getProperty('java.vendor') + ') Arch: ' + System.getProperty('os.arch')) +println "Java: ${System.getProperty 'java.version'}, JVM: ${System.getProperty 'java.vm.version'} (${System.getProperty 'java.vendor'}), Arch: ${System.getProperty 'os.arch'}" minecraft { // The mappings can be changed at any time and must be in the following format. // Channel: Version: - // snapshot YYYYMMDD Snapshot are built nightly. - // stable # Stables are built at the discretion of the MCP team. - // official MCVersion Official field/method names from Mojang mapping files + // official MCVersion Official field/method names from Mojang mapping files + // parchment YYYY.MM.DD-MCVersion Open community-sourced parameter names and javadocs layered on top of official // - // You must be aware of the Mojang license when using the 'official' mappings. + // You must be aware of the Mojang license when using the 'official' or 'parchment' mappings. // See more information here: https://github.com/MinecraftForge/MCPConfig/blob/master/Mojang.md // + // Parchment is an unofficial project maintained by ParchmentMC, separate from MinecraftForge + // Additional setup is needed to use their mappings: https://github.com/ParchmentMC/Parchment/wiki/Getting-Started + // // Use non-default mappings at your own risk. They may not always work. // Simply re-run your setup task after changing the mappings to update your workspace. - mappings channel: 'official', version: '1.18.1' + mappings channel: 'official', version: '1.19' // accessTransformer = file('src/main/resources/META-INF/accesstransformer.cfg') // Currently, this location cannot be changed from the default. @@ -55,8 +48,11 @@ minecraft { // Please read: https://stackoverflow.com/questions/2031163/when-to-use-the-different-log-levels property 'forge.logging.console.level', 'debug' + // Comma-separated list of namespaces to load gametests from. Empty = all namespaces. + property 'forge.enabledGameTestNamespaces', 'mydoomsite_statsmod' + mods { - examplemod { + mydoomsite_statsmod { source sourceSets.main } } @@ -65,18 +61,31 @@ minecraft { server { workingDirectory project.file('run') - // Recommended logging data for a userdev environment - // The markers can be added/remove as needed separated by commas. - // "SCAN": For mods scan. - // "REGISTRIES": For firing of registry events. - // "REGISTRYDUMP": For getting the contents of all registries. property 'forge.logging.markers', 'REGISTRIES' - // Recommended logging level for the console - // You can set various levels here. - // Please read: https://stackoverflow.com/questions/2031163/when-to-use-the-different-log-levels property 'forge.logging.console.level', 'debug' + property 'forge.enabledGameTestNamespaces', 'mydoomsite_statsmod' + + mods { + mydoomsite_statsmod { + source sourceSets.main + } + } + } + + // This run config launches GameTestServer and runs all registered gametests, then exits. + // By default, the server will crash when no gametests are provided. + // The gametest system is also enabled by default for other run configs under the /test command. + gameTestServer { + workingDirectory project.file('run') + + property 'forge.logging.markers', 'REGISTRIES' + + property 'forge.logging.console.level', 'debug' + + property 'forge.enabledGameTestNamespaces', 'mydoomsite_statsmod' + mods { mydoomsite_statsmod { source sourceSets.main @@ -87,16 +96,8 @@ minecraft { data { workingDirectory project.file('run') - // Recommended logging data for a userdev environment - // The markers can be added/remove as needed separated by commas. - // "SCAN": For mods scan. - // "REGISTRIES": For firing of registry events. - // "REGISTRYDUMP": For getting the contents of all registries. property 'forge.logging.markers', 'REGISTRIES' - // Recommended logging level for the console - // You can set various levels here. - // Please read: https://stackoverflow.com/questions/2031163/when-to-use-the-different-log-levels property 'forge.logging.console.level', 'debug' // Specify the modid for data generation, where to output the resulting resource, and where to look for existing resources. @@ -128,7 +129,7 @@ dependencies { // Specify the version of Minecraft to use. If this is any group other than 'net.minecraft', it is assumed // that the dep is a ForgeGradle 'patcher' dependency, and its patches will be applied. // The userdev artifact is a special name and will get all sorts of transformations applied to it. - minecraft 'net.minecraftforge:forge:1.18.1-39.0.10' + minecraft 'net.minecraftforge:forge:1.19-41.0.98' // Real mod deobf dependency examples - these get remapped to your current mappings // compileOnly fg.deobf("mezz.jei:jei-${mc_version}:${jei_version}:api") // Adds JEI API as a compile dependency @@ -176,3 +177,7 @@ publishing { } } } + +tasks.withType(JavaCompile).configureEach { + options.encoding = 'UTF-8' // Use the UTF-8 charset for Java compilation +} diff --git a/gradle/wrapper/gradle-wrapper.jar b/gradle/wrapper/gradle-wrapper.jar index 7454180..41d9927 100644 Binary files a/gradle/wrapper/gradle-wrapper.jar and b/gradle/wrapper/gradle-wrapper.jar differ diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index e750102..aa991fc 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -1,5 +1,5 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-7.3-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-7.4.2-bin.zip zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists diff --git a/gradlew b/gradlew index c53aefa..1b6c787 100644 --- a/gradlew +++ b/gradlew @@ -1,7 +1,7 @@ #!/bin/sh # -# Copyright © 2015-2021 the original authors. +# Copyright © 2015-2021 the original authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. @@ -32,10 +32,10 @@ # Busybox and similar reduced shells will NOT work, because this script # requires all of these POSIX shell features: # * functions; -# * expansions «$var», «${var}», «${var:-default}», «${var+SET}», -# «${var#prefix}», «${var%suffix}», and «$( cmd )»; -# * compound commands having a testable exit status, especially «case»; -# * various built-in commands including «command», «set», and «ulimit». +# * expansions «$var», «${var}», «${var:-default}», «${var+SET}», +# «${var#prefix}», «${var%suffix}», and «$( cmd )»; +# * compound commands having a testable exit status, especially «case»; +# * various built-in commands including «command», «set», and «ulimit». # # Important for patching: # diff --git a/settings.gradle b/settings.gradle new file mode 100644 index 0000000..fb61b26 --- /dev/null +++ b/settings.gradle @@ -0,0 +1,6 @@ +pluginManagement { + repositories { + gradlePluginPortal() + maven { url = 'https://maven.minecraftforge.net/' } + } +} \ No newline at end of file diff --git a/src/main/java/com/mydoomsite/statsmod/Main/Drawing.java b/src/main/java/com/mydoomsite/statsmod/Main/Drawing.java index 5d64f2e..de78449 100644 --- a/src/main/java/com/mydoomsite/statsmod/Main/Drawing.java +++ b/src/main/java/com/mydoomsite/statsmod/Main/Drawing.java @@ -5,7 +5,7 @@ import com.mydoomsite.statsmod.lib.TextMetrics; import net.minecraft.client.Minecraft; -import net.minecraft.network.chat.TextComponent; +import net.minecraft.network.chat.Component; public class Drawing { @@ -97,6 +97,6 @@ public static void DrawTextScaled(PoseStack matrixStack, String text, float x, f public static void sendChatMessageToClient(String message) { - minecraft.player.sendMessage(new TextComponent("\u00A7l\u00A7e[Statistics List]\u00A7r " + message), null); + minecraft.player.displayClientMessage(Component.literal("\u00A7l\u00A7e[Statistics List]\u00A7r " + message), false); // false = Display in chat, true = Display above status bar } } diff --git a/src/main/java/com/mydoomsite/statsmod/Main/MainRegistry.java b/src/main/java/com/mydoomsite/statsmod/Main/MainRegistry.java index 84b3462..3432149 100644 --- a/src/main/java/com/mydoomsite/statsmod/Main/MainRegistry.java +++ b/src/main/java/com/mydoomsite/statsmod/Main/MainRegistry.java @@ -1,6 +1,7 @@ package com.mydoomsite.statsmod.Main; import net.minecraftforge.api.distmarker.Dist; +import net.minecraftforge.client.event.RegisterKeyMappingsEvent; import net.minecraftforge.common.MinecraftForge; import net.minecraftforge.fml.DistExecutor; import net.minecraftforge.fml.IExtensionPoint; @@ -29,6 +30,7 @@ public MainRegistry() DistExecutor.unsafeRunWhenOn(Dist.CLIENT, () -> () -> { FMLJavaModLoadingContext.get().getModEventBus().addListener(this::Setup); FMLJavaModLoadingContext.get().getModEventBus().addListener(this::ClientSetup); + FMLJavaModLoadingContext.get().getModEventBus().addListener(this::RegisterKeyBindings); }); } @@ -41,7 +43,12 @@ private void ClientSetup(final FMLClientSetupEvent event) { StringHelper.Initialize(); MinecraftForge.EVENT_BUS.register(RenderHandler.Instance); - MinecraftForge.EVENT_BUS.register(new KeyBindings()); + MinecraftForge.EVENT_BUS.register(KeyBindings.Instance); MinecraftForge.EVENT_BUS.register(new TickHandlers()); } + + private void RegisterKeyBindings(RegisterKeyMappingsEvent event) + { + KeyBindings.RegisterKeyBindings(event); + } } diff --git a/src/main/java/com/mydoomsite/statsmod/handlers/KeyBindings.java b/src/main/java/com/mydoomsite/statsmod/handlers/KeyBindings.java index fadfed5..f1feaf8 100644 --- a/src/main/java/com/mydoomsite/statsmod/handlers/KeyBindings.java +++ b/src/main/java/com/mydoomsite/statsmod/handlers/KeyBindings.java @@ -8,12 +8,14 @@ import net.minecraft.client.KeyMapping; import net.minecraft.client.Minecraft; import net.minecraft.client.gui.screens.ChatScreen; -import net.minecraftforge.client.ClientRegistry; -import net.minecraftforge.client.event.InputEvent.KeyInputEvent; +import net.minecraftforge.client.event.InputEvent.Key; +import net.minecraftforge.client.event.RegisterKeyMappingsEvent; import net.minecraftforge.eventbus.api.SubscribeEvent; -public class KeyBindings +public final class KeyBindings { + public static KeyBindings Instance = new KeyBindings(); + public static final int ShowHideList = 0; public static final int ShowHideCoords = 1; public static final int ResetDistances = 2; @@ -48,23 +50,29 @@ public class KeyBindings GLFW.GLFW_KEY_KP_7 }; - private final KeyMapping[] keys; + private static KeyMapping[] keys; private static Minecraft minecraft = Minecraft.getInstance(); - public KeyBindings() + private KeyBindings() {} + + @SubscribeEvent + public static void RegisterKeyBindings(RegisterKeyMappingsEvent event) { + if(keys != null) + return; + keys = new KeyMapping[desc.length]; for (int i = 0; i < desc.length; ++i) { keys[i] = new KeyMapping(desc[i], keyValues[i], "Player Statistics List"); - ClientRegistry.registerKeyBinding(keys[i]); + event.register(keys[i]); } } @SubscribeEvent - public void onKeyInput(KeyInputEvent event) + public void onKeyInput(Key event) { if ((minecraft.isWindowActive() || (minecraft.screen != null && (minecraft.screen instanceof ChatScreen))) && !minecraft.options.renderDebug) { @@ -124,5 +132,4 @@ else if(keys[StartStopMeasurement].isDown()) } } } - } diff --git a/src/main/java/com/mydoomsite/statsmod/handlers/RenderHandler.java b/src/main/java/com/mydoomsite/statsmod/handlers/RenderHandler.java index 99f97dd..5fa59f1 100644 --- a/src/main/java/com/mydoomsite/statsmod/handlers/RenderHandler.java +++ b/src/main/java/com/mydoomsite/statsmod/handlers/RenderHandler.java @@ -37,483 +37,480 @@ public class RenderHandler { - public static RenderHandler Instance = new RenderHandler(); - private static Minecraft minecraft = Minecraft.getInstance(); + public static RenderHandler Instance = new RenderHandler(); + private static Minecraft minecraft = Minecraft.getInstance(); - public static final float SwordBaseDamage = 3.0f; //From the constructor of SwordItem. - - public static int StatusAlpha = 255; - public static int DeathTimerAlpha = 255; - private static ReferenceType armorPieces = new ReferenceType(0); - - @SubscribeEvent(priority = EventPriority.NORMAL) - public void RenderGameOverlayEvent(RenderGameOverlayEvent.Post event) - { - if(event.getType() == RenderGameOverlayEvent.ElementType.TEXT) - { - if ((minecraft.isWindowActive() || (minecraft.screen != null && (minecraft.screen instanceof ChatScreen))) && !minecraft.options.renderDebug) - { - if(!GlobalProperties.renderList && !GlobalProperties.renderCoords) - return; - - Vec3 playerPos = minecraft.player.position(); - - if(GlobalProperties.renderCoords) - { - String coords = - MathHelper.roundWithTrail(playerPos.x, 2) + ", " + - MathHelper.roundWithTrail(playerPos.y, 2) + ", " + - MathHelper.roundWithTrail(playerPos.z, 2); - - Drawing.DrawTextScaled(event.getMatrixStack(), coords, 4.0f*(1 / GlobalProperties.listScale), 4.0f*(1 / GlobalProperties.listScale), 0xFFFFFF, GlobalProperties.listScale, true); - } - - if(!GlobalProperties.renderList) - return; - - Window window = event.getWindow(); - - int width = window.getGuiScaledWidth(); - int height = window.getGuiScaledHeight(); - - long TimeOfDay = minecraft.level.getDayTime() % 24000; - int TimeLeftSeconds; - String NextWhat; - boolean isDay = TimeOfDay < 12000; - - if(TimeOfDay < 12000) //Next sunset. - { - TimeLeftSeconds = (int)((12000-TimeOfDay) / 20); - NextWhat = "sunset"; - } - else //Next dawn. - { - TimeOfDay -= 12000; - TimeLeftSeconds = (int)((12000-TimeOfDay) / 20); - NextWhat = "dawn"; - } - - String TimeString = TimeLeftSeconds/60 + ":" + (TimeLeftSeconds%60)/10 + TimeLeftSeconds%10; - String DeathDropsString = ""; - - if(GlobalProperties.deathTimer > 0.0) - { - int DeathDropsSeconds = (int)(GlobalProperties.deathTimer / 20.0); - DeathDropsString = DeathDropsSeconds/60 + ":" + (DeathDropsSeconds%60)/10 + DeathDropsSeconds%10; - - Drawing.DrawCenteredText( - new RenderedLine(GlobalProperties.deathTimer > 0.0 ? "Death drops de-spawn: " + StringHelper.getColorFromValue(GlobalProperties.deathTimer, GlobalProperties.deathTimerMax, false) + DeathDropsString : "", DeathTimerAlpha), - window, event.getMatrixStack(), 0, 8, 0xFFFFFFF, GlobalProperties.listScale, true - ); - } - - BlockPos playerBlockPos = minecraft.player.blockPosition(); - - if(GlobalProperties.measureStart != null) - { - double diffX = playerBlockPos.getX() - GlobalProperties.measureStart.getX(); - double diffY = playerBlockPos.getY() - GlobalProperties.measureStart.getY(); - double diffZ = playerBlockPos.getZ() - GlobalProperties.measureStart.getZ(); - - double dist = MathHelper.round(Math.sqrt(diffX*diffX + diffY*diffY + diffZ*diffZ), 2); - - Drawing.DrawCenteredText( - new RenderedLine("Distance: \u00A72" + dist + "m"), - window, event.getMatrixStack(), 0, 8 + minecraft.font.lineHeight + 2, 0xFFFFFFF, GlobalProperties.listScale, true - ); - } - - float xpPercentage = minecraft.player.experienceProgress * 100; - - BlockPos CurrentBlock = new BlockPos(playerPos.x, playerPos.y, playerPos.z); - - int LightLevelSky = minecraft.level.getBrightness(LightLayer.SKY, CurrentBlock); - int LightLevelBlock = minecraft.level.getBrightness(LightLayer.BLOCK, CurrentBlock); - - HitResult crosshairObj = minecraft.hitResult; - - ItemStack ArmorBoots = minecraft.player.getInventory().getArmor(0); - ItemStack ArmorLeggings = minecraft.player.getInventory().getArmor(1); - ItemStack ArmorChestplate = minecraft.player.getInventory().getArmor(2); - ItemStack ArmorHelmet = minecraft.player.getInventory().getArmor(3); - - String armorDisplay = ""; - double armorPercentage = 0.0; - - armorPieces.Value = 0; - - double ArmorBootsDamage = MathHelper.damagePercentage(ArmorBoots, armorPieces); - double ArmorLegginsDamage = MathHelper.damagePercentage(ArmorLeggings, armorPieces); - double ArmorChestplateDamage = MathHelper.damagePercentage(ArmorChestplate, armorPieces); - double ArmorHelmetDamage = MathHelper.damagePercentage(ArmorHelmet, armorPieces); - - armorPercentage = ArmorBootsDamage + - ArmorLegginsDamage + - ArmorChestplateDamage + - ArmorHelmetDamage; - - armorPercentage = MathHelper.safeDivide(armorPercentage, armorPieces.Value); - - armorDisplay = "\u00A7f("; - armorDisplay = StringHelper.appendIfHasDurability(armorDisplay, ArmorHelmet, StringHelper.getColorFromValue(ArmorHelmetDamage, 100.0, true) + "H"); - armorDisplay = StringHelper.appendIfHasDurability(armorDisplay, ArmorChestplate, StringHelper.getColorFromValue(ArmorChestplateDamage, 100.0, true) + "C"); - armorDisplay = StringHelper.appendIfHasDurability(armorDisplay, ArmorLeggings, StringHelper.getColorFromValue(ArmorLegginsDamage, 100.0, true) + "L"); - armorDisplay = StringHelper.appendIfHasDurability(armorDisplay, ArmorBoots, StringHelper.getColorFromValue(ArmorBootsDamage, 100.0, true) + "B"); - armorDisplay += "\u00A7f)"; - - if(armorPieces.Value == 0) { - armorDisplay = ""; - } - - ItemStack heldItemMainHand = minecraft.player.getItemInHand(InteractionHand.MAIN_HAND); - ItemStack heldItemOffHand = minecraft.player.getItemInHand(InteractionHand.OFF_HAND); - - float directionYaw = minecraft.player.getRotationVector().y + 180.0f; - float directionDegreesYaw = Math.abs(directionYaw) % 360.0f; - float directionDegrees = (directionYaw >= 0.0f) ? directionDegreesYaw : (360.0f - directionDegreesYaw); - String direction = (int)Math.floor(directionDegrees) + ""; - - if(directionDegrees > 337.5f || directionDegrees <= 22.5f) { - direction = direction + " N"; - } - else if(directionDegrees > 22.5f && directionDegrees <= 67.5f) { - direction = direction + " NE"; - } - else if(directionDegrees > 67.5f && directionDegrees <= 112.5f) { - direction = direction + " E"; - } - else if(directionDegrees > 112.5f && directionDegrees <= 157.5f) { - direction = direction + " SE"; - } - else if(directionDegrees > 157.5f && directionDegrees <= 202.5f) { - direction = direction + " S"; - } - else if(directionDegrees > 202.5f && directionDegrees <= 247.5f) { - direction = direction + " SW"; - } - else if(directionDegrees > 247.5f && directionDegrees <= 292.5f) { - direction = direction + " W"; - } - else if(directionDegrees > 292.5f && directionDegrees <= 337.5f) { - direction = direction + " NW"; - } - - RenderedLine[] Statistics = new RenderedLine[] { - new RenderedLine("\u00A7aPlayer Statistics"), - new RenderedLine("\u00A7a--------------"), - - new RenderedLine("Direction: \u00A7a" + direction), - new RenderedLine("Status: " + StringHelper.getPlayerStatus(MathHelper.round(minecraft.player.getHealth()/20.0, 2), MathHelper.round(minecraft.player.getFoodData().getFoodLevel()/20.0, 2)), StatusAlpha), - new RenderedLine("Health: " + StringHelper.colorIntValue((int)((minecraft.player.getHealth()/2.0)*10.0), 100, false) + "%"), - new RenderedLine("Food: " + StringHelper.colorIntValue((int)((minecraft.player.getFoodData().getFoodLevel()/2.0)*10.0), 100, false) + "%"), - new RenderedLine("Air: " + StringHelper.colorAirValue((minecraft.player.getAirSupply()/3)>=0 ? (minecraft.player.getAirSupply()/3) : 0, 100, false) + "%"), - new RenderedLine(playerPos.y >= MathHelper.SeaLevel ? "MASL: \u00A7a" + MathHelper.roundWithTrail(playerPos.y - MathHelper.SeaLevel, 2) + " m" : "MBSL: \u00A7a" + MathHelper.roundWithTrail(MathHelper.SeaLevel - playerPos.y, 2) + " m"), - new RenderedLine("Xp: \u00A7a" + MathHelper.round(xpPercentage, 2) + "%"), - - new RenderedLine("Light: " + (LightLevelSky > 7 ? "\u00A7a" : "\u00A7c") + LightLevelSky + " " + (LightLevelBlock > 7 ? "\u00A7a" : "\u00A7c") + LightLevelBlock), - new RenderedLine("Speed: \u00A7a" + (GlobalProperties.doDistanceCalculations ? MathHelper.roundWithTrail(20*GlobalProperties.playerSpeed, 2) + " m/s" : "\u00A74-")), - new RenderedLine("Travelled: \u00A7a" + (GlobalProperties.doDistanceCalculations ? StringHelper.formatDistance(GlobalProperties.distanceTravelled, true, 2, false) : "\u00A74-")), - new RenderedLine("Fallen: \u00A7a" + (GlobalProperties.doDistanceCalculations ? StringHelper.formatDistance(GlobalProperties.distanceFallen, true, 2, false) : "\u00A74-")), - - new RenderedLine("Dmg taken: \u00A7b" + MathHelper.roundWithTrail(GlobalProperties.damageTaken, 1) + " hp"), - - new RenderedLine("Next " + NextWhat + ": " + StringHelper.getColorFromValue(TimeOfDay, 12000, isDay) + TimeString), - - // Be last - new RenderedLine(" "), - new RenderedLine(armorPieces.Value > 0 ? "Armor (avg.): " + StringHelper.colorDoubleValue(armorPercentage, 100.0, 2, true) + "% " + armorDisplay : ""), - new RenderedLine(heldItemMainHand != null && heldItemMainHand.getMaxDamage() > 0 ? heldItemMainHand.getHoverName().getString() + ": " + StringHelper.colorDoubleValue(((double)heldItemMainHand.getDamageValue()*100.0)/(double)heldItemMainHand.getMaxDamage(), 100, 2, true) + "%" : ""), - new RenderedLine(heldItemOffHand != null && heldItemOffHand.getMaxDamage() > 0 ? heldItemOffHand.getHoverName().getString() + ": " + StringHelper.colorDoubleValue(((double)heldItemOffHand.getDamageValue()*100.0)/(double)heldItemOffHand.getMaxDamage(), 100, 2, true) + "%" : "") - }; - Drawing.DrawTextLines(Statistics, window, event.getMatrixStack(), 1, 8, height / 2, 0xFFFFFF, GlobalProperties.listScale, true); - - - int rStatIndex = 0; - RenderedLine[] rightStatistics = new RenderedLine[48]; - boolean hasToolStatistics = false; - - // Right now you may be asking yourself: - // "Why is this guy using a regular array instead of an ArrayList<>?" - // - // The answer is simple: - // Even though an ArrayList<> is much more flexible than a regular array, - // I want to ensure that this mod affects performance as little as possible. - // Thus, I sacrifice readability and flexibility in order to get a little - // (even though it is very little) performance gain. - - - // Statistics about the held item - if(GlobalProperties.AdditionalStatistics == 2 && heldItemMainHand != null && heldItemMainHand.isEnchanted() == true) - { - ListTag toolEnchantments = heldItemMainHand.getEnchantmentTags(); - if(toolEnchantments != null) - { - int enchantmentCount = toolEnchantments.size(); - - rightStatistics[rStatIndex] = new RenderedLine("\u00A7a" + heldItemMainHand.getHoverName().getString()); rStatIndex ++; - rightStatistics[rStatIndex] = new RenderedLine("\u00A7a------------"); rStatIndex ++; - - Item heldItem = heldItemMainHand.getItem(); - - float SwordDamage = (heldItem instanceof SwordItem) ? (3.0f + ((SwordItem)heldItem).getDamage() + 1.0f) : 0.0f; - float SwordDamageFactor = 0.0f; - int SwordDamageIndex = rStatIndex; rStatIndex ++; - rightStatistics[SwordDamageIndex] = new RenderedLine(""); - - for(int i = 0; i < enchantmentCount; i++) - { - CompoundTag enchantment = (CompoundTag)toolEnchantments.get(i); - String id = enchantment.getString("id"); - short level = enchantment.getShort("lvl"); - - if(level > 0) - { - double sweepDamage; - switch(id) - { - case "minecraft:sharpness": - if(EnchantmentCategory.WEAPON.canEnchant(heldItem) && heldItem instanceof SwordItem) - { - SwordItem Sword = (SwordItem)heldItem; - SwordDamageFactor += (level - 1.0f) * 0.5f + 1.0f; - } - break; - - case "minecraft:smite": - rightStatistics[rStatIndex] = new RenderedLine("Undead: \u00A72+" + Math.round(((SwordDamage + level * 2.5f) / SwordDamage - 1.0f) * 100.0f) + "%"); rStatIndex ++; - break; - - case "minecraft:bane_of_arthropods": - rightStatistics[rStatIndex] = new RenderedLine("Arthropods: \u00A72+" + Math.round(((SwordDamage + level * 2.5f) / SwordDamage - 1.0f) * 100.0f) + "%"); rStatIndex ++; - break; - - case "minecraft:knockback": - rightStatistics[rStatIndex] = new RenderedLine("Knockback: \u00A72+" + (level * 3)); rStatIndex ++; - break; - - case "minecraft:fire_aspect": - rightStatistics[rStatIndex] = new RenderedLine("Applied fire: \u00A72" + (level * 4) + "s"); rStatIndex ++; - break; - - case "minecraft:looting": - rightStatistics[rStatIndex] = new RenderedLine("Maximum loot: \u00A72+" + level); rStatIndex ++; - break; - - case "minecraft:sweeping_edge": - sweepDamage = 50.0D; - if (level == 2) { sweepDamage = 67.0D; } - else if (level >= 3) { sweepDamage = 75.0D; } - - rightStatistics[rStatIndex] = new RenderedLine("Sweep: \u00A72+" + Math.round(sweepDamage) + "%"); rStatIndex ++; - break; - - case "minecraft:efficiency": - rightStatistics[rStatIndex] = new RenderedLine("Mining speed: \u00A72" + Math.round(Math.pow(level, 2.0D) + 1.0D) + "x"); rStatIndex ++; - break; - - case "minecraft:unbreaking": - rightStatistics[rStatIndex] = new RenderedLine("Durability: \u00A72" + (level + 1) + "x"); rStatIndex ++; - break; - - case "minecraft:fortune": - rightStatistics[rStatIndex] = new RenderedLine("Maximum drops: \u00A72" + (level + 1) + "x"); rStatIndex ++; - break; - - case "minecraft:power": - rightStatistics[rStatIndex] = new RenderedLine("Damage: \u00A72+" + Math.round(0.25D * (level + 1) * 100.0D) + "%"); rStatIndex ++; - break; - - case "minecraft:punch": - rightStatistics[rStatIndex] = new RenderedLine("Knockback: \u00A72+" + (level * 3)); rStatIndex ++; - break; - - case "minecraft:flame": - rightStatistics[rStatIndex] = new RenderedLine("Applied fire: \u00A725s"); rStatIndex ++; - break; - } - } - } - - if(SwordDamageFactor > 0.0f) - { - SwordDamageFactor = (SwordDamage + SwordDamageFactor) / SwordDamage - 1.0f; - rightStatistics[SwordDamageIndex] = new RenderedLine("Damage: \u00A72+" + Math.round(SwordDamageFactor * 100.0f) + "%"); - } - - hasToolStatistics = true; - } - } - - // Target identification - if(GlobalProperties.AdditionalStatistics >= 1 && crosshairObj != null) - { - if(crosshairObj != null - && crosshairObj.getType() == HitResult.Type.ENTITY - && ((EntityHitResult)crosshairObj).getEntity() instanceof LivingEntity) - { - LivingEntity TargetEntity = (LivingEntity)((EntityHitResult)crosshairObj).getEntity(); - - double playX = playerPos.x; - double playY = playerPos.y; - double playZ = playerPos.z; - - Vec3 entityPos = TargetEntity.position(); - - double entX = entityPos.x; - double entY = entityPos.y; - double entZ = entityPos.z; - - double diffX = entX - playX; - double diffZ = entZ - playZ; - - double EnemyDistance = Math.sqrt(diffX*diffX + diffZ*diffZ); - - if(hasToolStatistics == true) - { - rightStatistics[rStatIndex] = new RenderedLine(" "); rStatIndex ++; - rightStatistics[rStatIndex] = new RenderedLine(" "); rStatIndex ++; - } - - rightStatistics[rStatIndex] = new RenderedLine("\u00A74Target"); rStatIndex ++; - rightStatistics[rStatIndex] = new RenderedLine("\u00A74------"); rStatIndex ++; - rightStatistics[rStatIndex] = new RenderedLine("Name: \u00A7b" + TargetEntity.getName().getString()); rStatIndex ++; - rightStatistics[rStatIndex] = new RenderedLine("Health: " + StringHelper.colorIntValue((int)((TargetEntity.getHealth()/TargetEntity.getMaxHealth())*100.0f), 100, false) + "%"); rStatIndex ++; - rightStatistics[rStatIndex] = new RenderedLine("Distance: \u00A7b" + StringHelper.formatDistance(EnemyDistance, true, 2, true)); rStatIndex ++; - - // Specific mob statistics - if(TargetEntity.getClass().getSimpleName().contains("Creeper")) - { - try - { - int swell = (Integer)getInstanceField(TargetEntity, "f_32270_"); - int swellMax = (Integer)getInstanceField(TargetEntity, "f_32271_"); - - double explodeTics = swellMax - swell; - String explodeSecs = MathHelper.roundWithTrail(explodeTics / 20.0, 2); - - rightStatistics[rStatIndex] = new RenderedLine("\u00A74Explodes in: \u00A7b" + explodeSecs + " s"); rStatIndex ++; - } - catch(Throwable e) {} - - // fuseTime and timeSinceIgnited don't exist anymore - /* - try - { - //fuseTime - timeSinceIgnited - double explodeTics = (Integer)getInstanceField(TargetEntity, "field_82225_f") - (Integer)getInstanceField(TargetEntity, "field_70833_d"); - String explodeSecs = MathHelper.roundWithTrail(explodeTics / 20.0, 2); - - rightStatistics[rStatIndex] = new RenderedLine("\u00A74Explodes in: \u00A7b" + explodeSecs + " s"); rStatIndex ++; - } - catch (Throwable e) {} - */ - } - else if(TargetEntity instanceof AbstractHorse) - { - AbstractHorse horseEntity = (AbstractHorse)TargetEntity; - boolean horseIsTame = horseEntity.isTamed(); - - rightStatistics[rStatIndex] = new RenderedLine("Tame: " + (horseIsTame ? "\u00A7aYes" : "\u00A7cNo")); rStatIndex ++; - - if(horseIsTame == true) { - double jumpStrength = horseEntity.getCustomJump(); - double jumpHeight = -0.1817584952D * Math.pow(jumpStrength, 3.0D) + 3.689713992D * Math.pow(jumpStrength, 2.0D) + 2.128599134D * jumpStrength - 0.343930367D; - - rightStatistics[rStatIndex] = new RenderedLine("Speed: \u00A7a" + MathHelper.round(horseEntity.getAttribute(Attributes.MOVEMENT_SPEED).getValue() * 43.1718071434983D, 2) + " m/s"); rStatIndex ++; - rightStatistics[rStatIndex] = new RenderedLine("Jump: \u00A7a" + MathHelper.round(jumpHeight, 2) + " m"); rStatIndex ++; - } - } - } - else if(crosshairObj != null - && crosshairObj.getType() == HitResult.Type.BLOCK) - { - BlockPos blockpos = ((BlockHitResult)crosshairObj).getBlockPos(); - if(blockpos != null) - { - BlockState blockstate = minecraft.level.getBlockState(blockpos); - Block block = blockstate.getBlock(); - if(block instanceof CropBlock) - { - CropBlock crop = (CropBlock)block; - String cropName = ""; - int cropAge = -1; - int cropMaxAge = crop.getMaxAge(); - float growthChance = -1.0f; - - try - { - cropName = ((ItemLike)getInstanceMethod(crop, "m_6404_")).asItem().getDefaultInstance().getHoverName().getString(); - } catch(Throwable e) {} - try - { - if(block.getClass().equals(CropBlock.class)) - { - cropAge = (Integer)getInstanceMethod(crop, "m_52305_", new Class[] {BlockState.class}, new Object[] {blockstate}); - } - else - { - cropAge = (Integer)getSuperInstanceMethod(crop, "m_52305_", new Class[] {BlockState.class}, new Object[] {blockstate}); - } - - } catch(Throwable e) {} - try - { - if(block.getClass().equals(CropBlock.class)) - { - growthChance = (Float)getInstanceMethod(crop, "m_52272_", new Class[] {Block.class, BlockGetter.class, BlockPos.class}, new Object[] {block, minecraft.level, blockpos}); - } - else - { - growthChance = (Float)getSuperInstanceMethod(crop, "m_52272_", new Class[] {Block.class, BlockGetter.class, BlockPos.class}, new Object[] {block, minecraft.level, blockpos}); - } - } catch(Throwable e) {} - - - if(hasToolStatistics) - { - rightStatistics[rStatIndex] = new RenderedLine(" "); rStatIndex ++; - rightStatistics[rStatIndex] = new RenderedLine(" "); rStatIndex ++; - } - - rightStatistics[rStatIndex] = new RenderedLine("\u00A72Crop"); rStatIndex ++; - rightStatistics[rStatIndex] = new RenderedLine("\u00A72----"); rStatIndex ++; - rightStatistics[rStatIndex] = new RenderedLine("Name: \u00A7b" + cropName); rStatIndex ++; - rightStatistics[rStatIndex] = new RenderedLine((cropAge >= 0 ? ("Stage: \u00A7b" + cropAge + "/" + cropMaxAge) : "")); rStatIndex ++; - rightStatistics[rStatIndex] = new RenderedLine((growthChance >= 0.0f ? ("G. chance: \u00A7b" + MathHelper.round((double)growthChance, 2) + "%") : "")); rStatIndex ++; - } - } - } - } - - if(rStatIndex > 0) - Drawing.DrawTextLines(rightStatistics, window, event.getMatrixStack(), 1, 65536, height / 2, 0xFFFFFF, GlobalProperties.listScale, true); - } - } - } - - public static Object getInstanceField(Object instance, String fieldName) throws Throwable - { + public static final float SwordBaseDamage = 3.0f; //From the constructor of SwordItem. + + public static int StatusAlpha = 255; + public static int DeathTimerAlpha = 255; + private static ReferenceType armorPieces = new ReferenceType(0); + + @SubscribeEvent(priority = EventPriority.NORMAL) + public void CustomizeGuiOverlayEvent(CustomizeGuiOverlayEvent.DebugText event) + { + if ((minecraft.isWindowActive() || (minecraft.screen != null && (minecraft.screen instanceof ChatScreen))) && !minecraft.options.renderDebug) + { + if(!GlobalProperties.renderList && !GlobalProperties.renderCoords) + return; + + Vec3 playerPos = minecraft.player.position(); + + if(GlobalProperties.renderCoords) + { + String coords = + MathHelper.roundWithTrail(playerPos.x, 2) + ", " + + MathHelper.roundWithTrail(playerPos.y, 2) + ", " + + MathHelper.roundWithTrail(playerPos.z, 2); + + Drawing.DrawTextScaled(event.getPoseStack(), coords, 4.0f*(1 / GlobalProperties.listScale), 4.0f*(1 / GlobalProperties.listScale), 0xFFFFFF, GlobalProperties.listScale, true); + } + + if(!GlobalProperties.renderList) + return; + + Window window = event.getWindow(); + + int width = window.getGuiScaledWidth(); + int height = window.getGuiScaledHeight(); + + long TimeOfDay = minecraft.level.getDayTime() % 24000; + int TimeLeftSeconds; + String NextWhat; + boolean isDay = TimeOfDay < 12000; + + if(TimeOfDay < 12000) //Next sunset. + { + TimeLeftSeconds = (int)((12000-TimeOfDay) / 20); + NextWhat = "sunset"; + } + else //Next dawn. + { + TimeOfDay -= 12000; + TimeLeftSeconds = (int)((12000-TimeOfDay) / 20); + NextWhat = "dawn"; + } + + String TimeString = TimeLeftSeconds/60 + ":" + (TimeLeftSeconds%60)/10 + TimeLeftSeconds%10; + String DeathDropsString = ""; + + if(GlobalProperties.deathTimer > 0.0) + { + int DeathDropsSeconds = (int)(GlobalProperties.deathTimer / 20.0); + DeathDropsString = DeathDropsSeconds/60 + ":" + (DeathDropsSeconds%60)/10 + DeathDropsSeconds%10; + + Drawing.DrawCenteredText( + new RenderedLine(GlobalProperties.deathTimer > 0.0 ? "Death drops de-spawn: " + StringHelper.getColorFromValue(GlobalProperties.deathTimer, GlobalProperties.deathTimerMax, false) + DeathDropsString : "", DeathTimerAlpha), + window, event.getPoseStack(), 0, 8, 0xFFFFFFF, GlobalProperties.listScale, true + ); + } + + BlockPos playerBlockPos = minecraft.player.blockPosition(); + + if(GlobalProperties.measureStart != null) + { + double diffX = playerBlockPos.getX() - GlobalProperties.measureStart.getX(); + double diffY = playerBlockPos.getY() - GlobalProperties.measureStart.getY(); + double diffZ = playerBlockPos.getZ() - GlobalProperties.measureStart.getZ(); + + double dist = MathHelper.round(Math.sqrt(diffX*diffX + diffY*diffY + diffZ*diffZ), 2); + + Drawing.DrawCenteredText( + new RenderedLine("Distance: \u00A72" + dist + "m"), + window, event.getPoseStack(), 0, 8 + minecraft.font.lineHeight + 2, 0xFFFFFFF, GlobalProperties.listScale, true + ); + } + + float xpPercentage = minecraft.player.experienceProgress * 100; + + BlockPos CurrentBlock = new BlockPos(playerPos.x, playerPos.y, playerPos.z); + + int LightLevelSky = minecraft.level.getBrightness(LightLayer.SKY, CurrentBlock); + int LightLevelBlock = minecraft.level.getBrightness(LightLayer.BLOCK, CurrentBlock); + + HitResult crosshairObj = minecraft.hitResult; + + ItemStack ArmorBoots = minecraft.player.getInventory().getArmor(0); + ItemStack ArmorLeggings = minecraft.player.getInventory().getArmor(1); + ItemStack ArmorChestplate = minecraft.player.getInventory().getArmor(2); + ItemStack ArmorHelmet = minecraft.player.getInventory().getArmor(3); + + String armorDisplay = ""; + double armorPercentage = 0.0; + + armorPieces.Value = 0; + + double ArmorBootsDamage = MathHelper.damagePercentage(ArmorBoots, armorPieces); + double ArmorLegginsDamage = MathHelper.damagePercentage(ArmorLeggings, armorPieces); + double ArmorChestplateDamage = MathHelper.damagePercentage(ArmorChestplate, armorPieces); + double ArmorHelmetDamage = MathHelper.damagePercentage(ArmorHelmet, armorPieces); + + armorPercentage = ArmorBootsDamage + + ArmorLegginsDamage + + ArmorChestplateDamage + + ArmorHelmetDamage; + + armorPercentage = MathHelper.safeDivide(armorPercentage, armorPieces.Value); + + armorDisplay = "\u00A7f("; + armorDisplay = StringHelper.appendIfHasDurability(armorDisplay, ArmorHelmet, StringHelper.getColorFromValue(ArmorHelmetDamage, 100.0, true) + "H"); + armorDisplay = StringHelper.appendIfHasDurability(armorDisplay, ArmorChestplate, StringHelper.getColorFromValue(ArmorChestplateDamage, 100.0, true) + "C"); + armorDisplay = StringHelper.appendIfHasDurability(armorDisplay, ArmorLeggings, StringHelper.getColorFromValue(ArmorLegginsDamage, 100.0, true) + "L"); + armorDisplay = StringHelper.appendIfHasDurability(armorDisplay, ArmorBoots, StringHelper.getColorFromValue(ArmorBootsDamage, 100.0, true) + "B"); + armorDisplay += "\u00A7f)"; + + if(armorPieces.Value == 0) { + armorDisplay = ""; + } + + ItemStack heldItemMainHand = minecraft.player.getItemInHand(InteractionHand.MAIN_HAND); + ItemStack heldItemOffHand = minecraft.player.getItemInHand(InteractionHand.OFF_HAND); + + float directionYaw = minecraft.player.getRotationVector().y + 180.0f; + float directionDegreesYaw = Math.abs(directionYaw) % 360.0f; + float directionDegrees = (directionYaw >= 0.0f) ? directionDegreesYaw : (360.0f - directionDegreesYaw); + String direction = (int)Math.floor(directionDegrees) + ""; + + if(directionDegrees > 337.5f || directionDegrees <= 22.5f) { + direction = direction + " N"; + } + else if(directionDegrees > 22.5f && directionDegrees <= 67.5f) { + direction = direction + " NE"; + } + else if(directionDegrees > 67.5f && directionDegrees <= 112.5f) { + direction = direction + " E"; + } + else if(directionDegrees > 112.5f && directionDegrees <= 157.5f) { + direction = direction + " SE"; + } + else if(directionDegrees > 157.5f && directionDegrees <= 202.5f) { + direction = direction + " S"; + } + else if(directionDegrees > 202.5f && directionDegrees <= 247.5f) { + direction = direction + " SW"; + } + else if(directionDegrees > 247.5f && directionDegrees <= 292.5f) { + direction = direction + " W"; + } + else if(directionDegrees > 292.5f && directionDegrees <= 337.5f) { + direction = direction + " NW"; + } + + RenderedLine[] Statistics = new RenderedLine[] { + new RenderedLine("\u00A7aPlayer Statistics"), + new RenderedLine("\u00A7a--------------"), + + new RenderedLine("Direction: \u00A7a" + direction), + new RenderedLine("Status: " + StringHelper.getPlayerStatus(MathHelper.round(minecraft.player.getHealth()/20.0, 2), MathHelper.round(minecraft.player.getFoodData().getFoodLevel()/20.0, 2)), StatusAlpha), + new RenderedLine("Health: " + StringHelper.colorIntValue((int)((minecraft.player.getHealth()/2.0)*10.0), 100, false) + "%"), + new RenderedLine("Food: " + StringHelper.colorIntValue((int)((minecraft.player.getFoodData().getFoodLevel()/2.0)*10.0), 100, false) + "%"), + new RenderedLine("Air: " + StringHelper.colorAirValue((minecraft.player.getAirSupply()/3)>=0 ? (minecraft.player.getAirSupply()/3) : 0, 100, false) + "%"), + new RenderedLine(playerPos.y >= MathHelper.SeaLevel ? "MASL: \u00A7a" + MathHelper.roundWithTrail(playerPos.y - MathHelper.SeaLevel, 2) + " m" : "MBSL: \u00A7a" + MathHelper.roundWithTrail(MathHelper.SeaLevel - playerPos.y, 2) + " m"), + new RenderedLine("Xp: \u00A7a" + MathHelper.round(xpPercentage, 2) + "%"), + + new RenderedLine("Light: " + (LightLevelSky > 7 ? "\u00A7a" : "\u00A7c") + LightLevelSky + " " + (LightLevelBlock > 7 ? "\u00A7a" : "\u00A7c") + LightLevelBlock), + new RenderedLine("Speed: \u00A7a" + (GlobalProperties.doDistanceCalculations ? MathHelper.roundWithTrail(20*GlobalProperties.playerSpeed, 2) + " m/s" : "\u00A74-")), + new RenderedLine("Travelled: \u00A7a" + (GlobalProperties.doDistanceCalculations ? StringHelper.formatDistance(GlobalProperties.distanceTravelled, true, 2, false) : "\u00A74-")), + new RenderedLine("Fallen: \u00A7a" + (GlobalProperties.doDistanceCalculations ? StringHelper.formatDistance(GlobalProperties.distanceFallen, true, 2, false) : "\u00A74-")), + + new RenderedLine("Dmg taken: \u00A7b" + MathHelper.roundWithTrail(GlobalProperties.damageTaken, 1) + " hp"), + + new RenderedLine("Next " + NextWhat + ": " + StringHelper.getColorFromValue(TimeOfDay, 12000, isDay) + TimeString), + + // Be last + new RenderedLine(" "), + new RenderedLine(armorPieces.Value > 0 ? "Armor (avg.): " + StringHelper.colorDoubleValue(armorPercentage, 100.0, 2, true) + "% " + armorDisplay : ""), + new RenderedLine(heldItemMainHand != null && heldItemMainHand.getMaxDamage() > 0 ? heldItemMainHand.getHoverName().getString() + ": " + StringHelper.colorDoubleValue(((double)heldItemMainHand.getDamageValue()*100.0)/(double)heldItemMainHand.getMaxDamage(), 100, 2, true) + "%" : ""), + new RenderedLine(heldItemOffHand != null && heldItemOffHand.getMaxDamage() > 0 ? heldItemOffHand.getHoverName().getString() + ": " + StringHelper.colorDoubleValue(((double)heldItemOffHand.getDamageValue()*100.0)/(double)heldItemOffHand.getMaxDamage(), 100, 2, true) + "%" : "") + }; + Drawing.DrawTextLines(Statistics, window, event.getPoseStack(), 1, 8, height / 2, 0xFFFFFF, GlobalProperties.listScale, true); + + + int rStatIndex = 0; + RenderedLine[] rightStatistics = new RenderedLine[48]; + boolean hasToolStatistics = false; + + // Right now you may be asking yourself: + // "Why is this guy using a regular array instead of an ArrayList<>?" + // + // The answer is simple: + // Even though an ArrayList<> is much more flexible than a regular array, + // I want to ensure that this mod affects performance as little as possible. + // Thus, I sacrifice readability and flexibility in order to get a little + // (even though it is very little) performance gain. + + + // Statistics about the held item + if(GlobalProperties.AdditionalStatistics == 2 && heldItemMainHand != null && heldItemMainHand.isEnchanted() == true) + { + ListTag toolEnchantments = heldItemMainHand.getEnchantmentTags(); + if(toolEnchantments != null) + { + int enchantmentCount = toolEnchantments.size(); + + rightStatistics[rStatIndex] = new RenderedLine("\u00A7a" + heldItemMainHand.getHoverName().getString()); rStatIndex ++; + rightStatistics[rStatIndex] = new RenderedLine("\u00A7a------------"); rStatIndex ++; + + Item heldItem = heldItemMainHand.getItem(); + + float SwordDamage = (heldItem instanceof SwordItem) ? (3.0f + ((SwordItem)heldItem).getDamage() + 1.0f) : 0.0f; + float SwordDamageFactor = 0.0f; + int SwordDamageIndex = rStatIndex; rStatIndex ++; + rightStatistics[SwordDamageIndex] = new RenderedLine(""); + + for(int i = 0; i < enchantmentCount; i++) + { + CompoundTag enchantment = (CompoundTag)toolEnchantments.get(i); + String id = enchantment.getString("id"); + short level = enchantment.getShort("lvl"); + + if(level > 0) + { + double sweepDamage; + switch(id) + { + case "minecraft:sharpness": + if(EnchantmentCategory.WEAPON.canEnchant(heldItem) && heldItem instanceof SwordItem) + { + SwordItem Sword = (SwordItem)heldItem; + SwordDamageFactor += (level - 1.0f) * 0.5f + 1.0f; + } + break; + + case "minecraft:smite": + rightStatistics[rStatIndex] = new RenderedLine("Undead: \u00A72+" + Math.round(((SwordDamage + level * 2.5f) / SwordDamage - 1.0f) * 100.0f) + "%"); rStatIndex ++; + break; + + case "minecraft:bane_of_arthropods": + rightStatistics[rStatIndex] = new RenderedLine("Arthropods: \u00A72+" + Math.round(((SwordDamage + level * 2.5f) / SwordDamage - 1.0f) * 100.0f) + "%"); rStatIndex ++; + break; + + case "minecraft:knockback": + rightStatistics[rStatIndex] = new RenderedLine("Knockback: \u00A72+" + (level * 3)); rStatIndex ++; + break; + + case "minecraft:fire_aspect": + rightStatistics[rStatIndex] = new RenderedLine("Applied fire: \u00A72" + (level * 4) + "s"); rStatIndex ++; + break; + + case "minecraft:looting": + rightStatistics[rStatIndex] = new RenderedLine("Maximum loot: \u00A72+" + level); rStatIndex ++; + break; + + case "minecraft:sweeping_edge": + sweepDamage = 50.0D; + if (level == 2) { sweepDamage = 67.0D; } + else if (level >= 3) { sweepDamage = 75.0D; } + + rightStatistics[rStatIndex] = new RenderedLine("Sweep: \u00A72+" + Math.round(sweepDamage) + "%"); rStatIndex ++; + break; + + case "minecraft:efficiency": + rightStatistics[rStatIndex] = new RenderedLine("Mining speed: \u00A72" + Math.round(Math.pow(level, 2.0D) + 1.0D) + "x"); rStatIndex ++; + break; + + case "minecraft:unbreaking": + rightStatistics[rStatIndex] = new RenderedLine("Durability: \u00A72" + (level + 1) + "x"); rStatIndex ++; + break; + + case "minecraft:fortune": + rightStatistics[rStatIndex] = new RenderedLine("Maximum drops: \u00A72" + (level + 1) + "x"); rStatIndex ++; + break; + + case "minecraft:power": + rightStatistics[rStatIndex] = new RenderedLine("Damage: \u00A72+" + Math.round(0.25D * (level + 1) * 100.0D) + "%"); rStatIndex ++; + break; + + case "minecraft:punch": + rightStatistics[rStatIndex] = new RenderedLine("Knockback: \u00A72+" + (level * 3)); rStatIndex ++; + break; + + case "minecraft:flame": + rightStatistics[rStatIndex] = new RenderedLine("Applied fire: \u00A725s"); rStatIndex ++; + break; + } + } + } + + if(SwordDamageFactor > 0.0f) + { + SwordDamageFactor = (SwordDamage + SwordDamageFactor) / SwordDamage - 1.0f; + rightStatistics[SwordDamageIndex] = new RenderedLine("Damage: \u00A72+" + Math.round(SwordDamageFactor * 100.0f) + "%"); + } + + hasToolStatistics = true; + } + } + + // Target identification + if(GlobalProperties.AdditionalStatistics >= 1 && crosshairObj != null) + { + if(crosshairObj != null + && crosshairObj.getType() == HitResult.Type.ENTITY + && ((EntityHitResult)crosshairObj).getEntity() instanceof LivingEntity) + { + LivingEntity TargetEntity = (LivingEntity)((EntityHitResult)crosshairObj).getEntity(); + + double playX = playerPos.x; + double playY = playerPos.y; + double playZ = playerPos.z; + + Vec3 entityPos = TargetEntity.position(); + + double entX = entityPos.x; + double entY = entityPos.y; + double entZ = entityPos.z; + + double diffX = entX - playX; + double diffZ = entZ - playZ; + + double EnemyDistance = Math.sqrt(diffX*diffX + diffZ*diffZ); + + if(hasToolStatistics == true) + { + rightStatistics[rStatIndex] = new RenderedLine(" "); rStatIndex ++; + rightStatistics[rStatIndex] = new RenderedLine(" "); rStatIndex ++; + } + + rightStatistics[rStatIndex] = new RenderedLine("\u00A74Target"); rStatIndex ++; + rightStatistics[rStatIndex] = new RenderedLine("\u00A74------"); rStatIndex ++; + rightStatistics[rStatIndex] = new RenderedLine("Name: \u00A7b" + TargetEntity.getName().getString()); rStatIndex ++; + rightStatistics[rStatIndex] = new RenderedLine("Health: " + StringHelper.colorIntValue((int)((TargetEntity.getHealth()/TargetEntity.getMaxHealth())*100.0f), 100, false) + "%"); rStatIndex ++; + rightStatistics[rStatIndex] = new RenderedLine("Distance: \u00A7b" + StringHelper.formatDistance(EnemyDistance, true, 2, true)); rStatIndex ++; + + // Specific mob statistics + if(TargetEntity.getClass().getSimpleName().contains("Creeper")) + { + try + { + int swell = (Integer)getInstanceField(TargetEntity, "f_32270_"); + int swellMax = (Integer)getInstanceField(TargetEntity, "f_32271_"); + + double explodeTics = swellMax - swell; + String explodeSecs = MathHelper.roundWithTrail(explodeTics / 20.0, 2); + + rightStatistics[rStatIndex] = new RenderedLine("\u00A74Explodes in: \u00A7b" + explodeSecs + " s"); rStatIndex ++; + } + catch(Throwable e) {} + + // fuseTime and timeSinceIgnited don't exist anymore + /* + try + { + //fuseTime - timeSinceIgnited + double explodeTics = (Integer)getInstanceField(TargetEntity, "field_82225_f") - (Integer)getInstanceField(TargetEntity, "field_70833_d"); + String explodeSecs = MathHelper.roundWithTrail(explodeTics / 20.0, 2); + + rightStatistics[rStatIndex] = new RenderedLine("\u00A74Explodes in: \u00A7b" + explodeSecs + " s"); rStatIndex ++; + } + catch (Throwable e) {} + */ + } + else if(TargetEntity instanceof AbstractHorse) + { + AbstractHorse horseEntity = (AbstractHorse)TargetEntity; + boolean horseIsTame = horseEntity.isTamed(); + + rightStatistics[rStatIndex] = new RenderedLine("Tame: " + (horseIsTame ? "\u00A7aYes" : "\u00A7cNo")); rStatIndex ++; + + if(horseIsTame == true) { + double jumpStrength = horseEntity.getCustomJump(); + double jumpHeight = -0.1817584952D * Math.pow(jumpStrength, 3.0D) + 3.689713992D * Math.pow(jumpStrength, 2.0D) + 2.128599134D * jumpStrength - 0.343930367D; + + rightStatistics[rStatIndex] = new RenderedLine("Speed: \u00A7a" + MathHelper.round(horseEntity.getAttribute(Attributes.MOVEMENT_SPEED).getValue() * 43.1718071434983D, 2) + " m/s"); rStatIndex ++; + rightStatistics[rStatIndex] = new RenderedLine("Jump: \u00A7a" + MathHelper.round(jumpHeight, 2) + " m"); rStatIndex ++; + } + } + } + else if(crosshairObj != null + && crosshairObj.getType() == HitResult.Type.BLOCK) + { + BlockPos blockpos = ((BlockHitResult)crosshairObj).getBlockPos(); + if(blockpos != null) + { + BlockState blockstate = minecraft.level.getBlockState(blockpos); + Block block = blockstate.getBlock(); + if(block instanceof CropBlock) + { + CropBlock crop = (CropBlock)block; + String cropName = ""; + int cropAge = -1; + int cropMaxAge = crop.getMaxAge(); + float growthChance = -1.0f; + + try + { + cropName = ((ItemLike)getInstanceMethod(crop, "m_6404_")).asItem().getDefaultInstance().getHoverName().getString(); + } catch(Throwable e) {} + try + { + if(block.getClass().equals(CropBlock.class)) + { + cropAge = (Integer)getInstanceMethod(crop, "m_52305_", new Class[] {BlockState.class}, new Object[] {blockstate}); + } + else + { + cropAge = (Integer)getSuperInstanceMethod(crop, "m_52305_", new Class[] {BlockState.class}, new Object[] {blockstate}); + } + + } catch(Throwable e) {} + try + { + if(block.getClass().equals(CropBlock.class)) + { + growthChance = (Float)getInstanceMethod(crop, "m_52272_", new Class[] {Block.class, BlockGetter.class, BlockPos.class}, new Object[] {block, minecraft.level, blockpos}); + } + else + { + growthChance = (Float)getSuperInstanceMethod(crop, "m_52272_", new Class[] {Block.class, BlockGetter.class, BlockPos.class}, new Object[] {block, minecraft.level, blockpos}); + } + } catch(Throwable e) {} + + + if(hasToolStatistics) + { + rightStatistics[rStatIndex] = new RenderedLine(" "); rStatIndex ++; + rightStatistics[rStatIndex] = new RenderedLine(" "); rStatIndex ++; + } + + rightStatistics[rStatIndex] = new RenderedLine("\u00A72Crop"); rStatIndex ++; + rightStatistics[rStatIndex] = new RenderedLine("\u00A72----"); rStatIndex ++; + rightStatistics[rStatIndex] = new RenderedLine("Name: \u00A7b" + cropName); rStatIndex ++; + rightStatistics[rStatIndex] = new RenderedLine((cropAge >= 0 ? ("Stage: \u00A7b" + cropAge + "/" + cropMaxAge) : "")); rStatIndex ++; + rightStatistics[rStatIndex] = new RenderedLine((growthChance >= 0.0f ? ("G. chance: \u00A7b" + MathHelper.round((double)growthChance, 2) + "%") : "")); rStatIndex ++; + } + } + } + } + + if(rStatIndex > 0) + Drawing.DrawTextLines(rightStatistics, window, event.getPoseStack(), 1, 65536, height / 2, 0xFFFFFF, GlobalProperties.listScale, true); + } + } + + public static Object getInstanceField(Object instance, String fieldName) throws Throwable + { Field field = instance.getClass().getDeclaredField(fieldName); field.setAccessible(true); return field.get(instance); } - - public static Object getInstanceMethod(Object instance, String methodName) throws Throwable - { - return getInstanceMethod(instance, methodName, new Class[] {}, new Object[] {}); - } - - public static Object getInstanceMethod(Object instance, String methodName, Class[] argTypes, Object[] args) throws Throwable - { - Method method = instance.getClass().getDeclaredMethod(methodName, argTypes); - method.setAccessible(true); - return method.invoke(instance, args); + + public static Object getInstanceMethod(Object instance, String methodName) throws Throwable + { + return getInstanceMethod(instance, methodName, new Class[] {}, new Object[] {}); + } + + public static Object getInstanceMethod(Object instance, String methodName, Class[] argTypes, Object[] args) throws Throwable + { + Method method = instance.getClass().getDeclaredMethod(methodName, argTypes); + method.setAccessible(true); + return method.invoke(instance, args); } - - public static Object getSuperInstanceMethod(Object instance, String methodName, Class[] argTypes, Object[] args) throws Throwable - { - Method method = instance.getClass().getSuperclass().getDeclaredMethod(methodName, argTypes); - method.setAccessible(true); - return method.invoke(instance, args); + + public static Object getSuperInstanceMethod(Object instance, String methodName, Class[] argTypes, Object[] args) throws Throwable + { + Method method = instance.getClass().getSuperclass().getDeclaredMethod(methodName, argTypes); + method.setAccessible(true); + return method.invoke(instance, args); } } \ No newline at end of file diff --git a/src/main/resources/META-INF/mods.toml b/src/main/resources/META-INF/mods.toml index 7c2331a..36cbe97 100644 --- a/src/main/resources/META-INF/mods.toml +++ b/src/main/resources/META-INF/mods.toml @@ -6,7 +6,7 @@ # The name of the mod loader type to load - for regular FML @Mod mods it should be javafml modLoader="javafml" #mandatory # A version range to match for said mod loader - for regular FML @Mod it will be the forge version -loaderVersion="[39,)" #mandatory This is typically bumped every Minecraft version by Forge. See our download page for lists of versions. +loaderVersion="[41,)" #mandatory This is typically bumped every Minecraft version by Forge. See our download page for lists of versions. # The license for you mod. This is mandatory metadata and allows for easier comprehension of your redistributive properties. # Review your options at https://choosealicense.com/. All rights reserved is the default copyright stance, and is thus the default here. license="BSD 3-Clause License" @@ -29,7 +29,7 @@ displayURL="https://www.mydoomsite.com/" #optional # A file name (in the root of the mod JAR) containing a logo for display logoFile="" #optional # A text field displayed in the mod UI -credits="Created and maintained by Visual Vincent, help with ideas: Zoro, Simmmmme, Fazzew, Hazard, Swoomy." #optional +credits="Created and maintained by Visual Vincent. Help with ideas: Zoro, Simmmmme, Fazzew, Hazard, Swoomy." #optional # A text field displayed in the mod UI authors="Visual Vincent" #optional # The description text for the mod (multi line!) (#mandatory) @@ -43,7 +43,7 @@ A mod showing relevant statistics about the player and the world around them. # Does this dependency have to exist - if not, ordering below must be specified mandatory=true #mandatory # The version range of the dependency - versionRange="[39,)" #mandatory + versionRange="[41,)" #mandatory # An ordering relationship for the dependency - BEFORE or AFTER required if the relationship is not mandatory ordering="NONE" # Side this dependency is applied on - BOTH, CLIENT or SERVER @@ -53,6 +53,6 @@ A mod showing relevant statistics about the player and the world around them. modId="minecraft" mandatory=true # This version range declares a minimum of the current minecraft version up to but not including the next major version - versionRange="[1.18.1,1.19)" + versionRange="[1.19,1.20)" ordering="NONE" side="CLIENT" diff --git a/src/main/resources/pack.mcmeta b/src/main/resources/pack.mcmeta index 46913b3..ed52e90 100644 --- a/src/main/resources/pack.mcmeta +++ b/src/main/resources/pack.mcmeta @@ -1,6 +1,8 @@ { "pack": { "description": "Player Statistics List Resources", - "pack_format": 8 + "pack_format": 9, + "forge:resource_pack_format": 9, + "forge:data_pack_format": 10 } }