diff --git a/Changelog.md b/Changelog.md index a6f00b3..56872c3 100644 --- a/Changelog.md +++ b/Changelog.md @@ -8,23 +8,36 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), ### Highlight -Welcome to Red Core 0.5 a breaking release. +Welcome to Red Core 0.5 an originally breaking release, but now it has a compatibility layer, all mods using it should update before 0.8 when the compatibility layer will be removed. ### Changed +- Red Core is now split into two, `Red Core` and `Red Core MC` the later being the MC specific part of Red Core, this finally allows it to be used everywhere +- `MathUtil` is now under `utils.math` +- Separated `MathUtil` clamping methods into their own class `ClampUtil` - Changed GroupId from `io.redstudioragnarok` to `dev.redstudio` -- Moved `startClientTicker` from `RedCore` to `RedClientTicker -- Moved `forceOptiFineFastRenderOff` from `RedCore` to `OptiNotFine` ### Removed -- Removed `pack.mcmeta` +- Removed `Stopwatch` :sob: it wasn't that good or useful but was fun to make ### Internal - Switched to [gradle-buildconfig-plugin](https://github.com/gmazzo/gradle-buildconfig-plugin) entirely for project constants +- Switched to Gradle Kotlin DSL - General cleanup +### Red Core MC + +#### Changed + +- Moved `startClientTicker` from `RedCore` to `RedClientTicker +- Moved `forceOptiFineFastRenderOff` from `RedCore` to `OptiNotFine` + +#### Removed + +- Removed `pack.mcmeta` + --- ## Red Core Version 0.4 Changelog - 2023-09-07 diff --git a/README.md b/README.md index f8a3d56..a88d9ce 100644 --- a/README.md +++ b/README.md @@ -37,6 +37,8 @@ Join us in enhancing Red-Core! We believe in constant evolution and the power of Integrating Red-Core into your project is a straightforward process that involves tweaking your Gradle build script. Follow the steps below: +*Not up to date with 0.5 dev builds, README will be updated once 0.5 is released* + 1. **Add a New Configuration:** Start by adding a new configuration to your Gradle build script, which will be used to download and attach sources. ```groovy diff --git a/build.gradle b/build.gradle deleted file mode 100644 index 189df1c..0000000 --- a/build.gradle +++ /dev/null @@ -1,120 +0,0 @@ -import org.jetbrains.gradle.ext.Gradle - -plugins { - id 'java' - id 'java-library' - id 'io.freefair.lombok' version '8.+' - id 'com.github.gmazzo.buildconfig' version '4.+' - id 'com.gtnewhorizons.retrofuturagradle' version '1.+' - id 'org.jetbrains.gradle.plugin.idea-ext' version '1.+' -} - -// Add version to the jar name -group = "dev.redstudio" -version = project.version - -// Set the toolchain version to decouple the Java we run Gradle with from the Java used to compile and run the mod -java { - toolchain { - languageVersion.set(JavaLanguageVersion.of(8)) - vendor.set(JvmVendorSpec.AZUL) - } - // Generate sources jar when building and publishing - withSourcesJar() -} - -tasks.withType(JavaCompile).configureEach { - options.encoding = 'UTF-8' - options.fork = true -} - -minecraft { - mcVersion = '1.12.2' - username = 'Desoroxxx' - extraRunJvmArguments.addAll('-Xmx6G', '-Xms4G', '-Dforge.logging.console.level=debug', '-Dfml.coreMods.load=dev.redstudio.redcore.RedCore') -} - -configurations { - implementation - compile.extendsFrom(embed) -} - -dependencies { - implementation 'net.jafama:jafama:2.+' - embed 'net.jafama:jafama:2.+' -} - -buildConfig { - className("ProjectConstants") - packageName("dev.redstudio.redcore.utils") - - buildConfigField("String", "ID", "\"${project.id}\"") - buildConfigField("String", "NAME", "\"Red Core\"") - buildConfigField("String", "VERSION", "\"${project.version}\"") - buildConfigField("org.apache.logging.log4j.Logger", "LOGGER", "LogManager.getLogger(NAME)") - buildConfigField("dev.redstudio.redcore.logging.RedLogger", "RED_LOGGER", "new RedLogger(NAME, \"https://linkify.cz/RedCoreBugReport\", LOGGER)") - buildConfigField("org.apache.logging.log4j.LogManager", "DO_NOT_USE", "null") -} - -jar { - manifest.attributes([ - 'ModSide': 'BOTH', - 'FMLCorePlugin': 'dev.redstudio.redcore.RedCore', - 'FMLCorePluginContainsFMLMod': true, - 'ForceLoadAsMod': true - ]) - - from(provider { configurations.embed.collect { it.isDirectory() ? it : zipTree(it) } }) - archiveBaseName.set('!Red-Core') -} - -idea { - module { - inheritOutputDirs = true - excludeDirs = [ - file('.settings'), - file('.github'), - file('.gradle'), - file('gradle'), - file('.idea'), - file('build'), - file('run'), - file('bin') - ] - } - - project { - jdkName = '1.8' - languageLevel = '1.8' - - settings { - runConfigurations { - 'Client'(Gradle) { - taskNames = ['runClient'] - } - 'Server'(Gradle) { - taskNames = ['runServer'] - } - 'Obfuscated Client'(Gradle) { - taskNames = ['runObfClient'] - } - 'Obfuscated Server'(Gradle) { - taskNames = ['runObfServer'] - } - 'Vanilla Client'(Gradle) { - taskNames = ['runVanillaClient'] - } - 'Vanilla Server'(Gradle) { - taskNames = ['runVanillaServer'] - } - } - - compiler.javac { - afterEvaluate { - javacAdditionalOptions = '-encoding utf8' - moduleJavacAdditionalOptions = [(project.id + '.main'): tasks.compileJava.options.compilerArgs.collect { " $it " }.join(' ')] - } - } - } - } -} diff --git a/build.gradle.kts b/build.gradle.kts new file mode 100644 index 0000000..9403457 --- /dev/null +++ b/build.gradle.kts @@ -0,0 +1,81 @@ +import org.jetbrains.gradle.ext.settings +import org.gradle.plugins.ide.idea.model.IdeaLanguageLevel +import org.jetbrains.gradle.ext.Gradle +import org.jetbrains.gradle.ext.runConfigurations + +plugins { + id("org.jetbrains.kotlin.jvm") version embeddedKotlinVersion + id("org.jetbrains.gradle.plugin.idea-ext") version "1.1.7" + id("dev.redstudio.gradleembeder") version "1.0" + id("io.freefair.lombok") version "8.3" + id("maven-publish") + id("java-library") +} + +allprojects { + apply(plugin = "org.jetbrains.gradle.plugin.idea-ext") + apply(plugin = "io.freefair.lombok") + apply(plugin = "java-library") + apply(plugin = "dev.redstudio.gradleembeder") + apply(plugin = "maven-publish") + + group = "dev.redstudio" + version = "0.5-Dev-2" // Versioning must follow Ragnarök versioning convention: https://shor.cz/ragnarok_versioning_convention + + repositories { + gradlePluginPortal() + } + + idea { + module { + excludeDirs = setOf( + file(".github"), file(".gradle"), file(".idea"), file("build"), file("gradle"), file("run") + ) + } + } + + // Set the toolchain version to decouple the Java we run Gradle with from the Java used to compile and run the mod + java { + toolchain { + languageVersion.set(JavaLanguageVersion.of(8)) + // Azul covers the most platforms for Java 8 toolchains, crucially including macOS arm64 + vendor.set(JvmVendorSpec.AZUL) + } + withJavadocJar() + } + + tasks.withType().configureEach { + options.encoding = "UTF-8" + options.isFork = true + } +} + +idea { + project { + settings { + jdkName = "1.8" + languageLevel = IdeaLanguageLevel("JDK_1_8") + + runConfigurations { + create("MC Client", Gradle::class.java) { + taskNames = setOf("runClient") + } + create("MC Server", Gradle::class.java) { + taskNames = setOf("runServer") + } + create("MC Obfuscated Client", Gradle::class.java) { + taskNames = setOf("runObfClient") + } + create("MC Obfuscated Server", Gradle::class.java) { + taskNames = setOf("runObfServer") + } + create("MC Vanilla Client", Gradle::class.java) { + taskNames = setOf("runVanillaClient") + } + create("MC Vanilla Server", Gradle::class.java) { + taskNames = setOf("runVanillaServer") + } + } + } + } +} diff --git a/core/build.gradle.kts b/core/build.gradle.kts new file mode 100644 index 0000000..7c9bbe7 --- /dev/null +++ b/core/build.gradle.kts @@ -0,0 +1,31 @@ +plugins { + id("com.github.gmazzo.buildconfig") version "4.1.2" +} + +val log4jVersion = "2.17.1" + +dependencies { + embed("net.jafama", "jafama", "2.3.2") + + compileOnly("org.apache.logging.log4j", "log4j-api", log4jVersion) + compileOnly("org.apache.logging.log4j", "log4j-core", log4jVersion) +} + +buildConfig { + packageName(project.group.toString() + ".redcore") + className("ProjectConstants") + + useJavaOutput() + buildConfigField("String", "NAME", provider { "\"Red Core\"" }) + buildConfigField("String", "VERSION", provider { "\"${project.version}\"" }) + buildConfigField("org.apache.logging.log4j.Logger", "LOGGER", "org.apache.logging.log4j.LogManager.getLogger(NAME)") + buildConfigField("dev.redstudio.redcore.logging.RedLogger", "RED_LOGGER", "new RedLogger(NAME, \"https://linkify.cz/RedCoreBugReport\", LOGGER)") +} + +publishing.publications.register("redCore", MavenPublication::class) { + from(components["java"]) + + groupId = project.group.toString() + artifactId = "red-core" + version = project.version.toString() +} diff --git a/src/main/java/dev/redstudio/redcore/logging/RedLogger.java b/core/src/main/java/dev/redstudio/redcore/logging/RedLogger.java similarity index 100% rename from src/main/java/dev/redstudio/redcore/logging/RedLogger.java rename to core/src/main/java/dev/redstudio/redcore/logging/RedLogger.java diff --git a/core/src/main/java/dev/redstudio/redcore/utils/math/ClampUtil.java b/core/src/main/java/dev/redstudio/redcore/utils/math/ClampUtil.java new file mode 100644 index 0000000..cf1529b --- /dev/null +++ b/core/src/main/java/dev/redstudio/redcore/utils/math/ClampUtil.java @@ -0,0 +1,363 @@ +package dev.redstudio.redcore.utils.math; + +import static dev.redstudio.redcore.ProjectConstants.LOGGER; + +/** + * A utility class that offers efficient clamping methods. + *

+ * These functions are optimized for speed and provided for every primitive datatype. + * + * @author Luna Lage (Desoroxxx) + * @since 0.5 + */ +@SuppressWarnings({"unused", "ManualMinMaxCalculation", "DuplicatedCode"}) +public final class ClampUtil { + + /** + * Clamps a value within a specified range [min, max], checking for the maximum value first. + *

+ * If the input is greater than max, it returns max. If the input is less than min, it returns min. + * Otherwise, it returns the input. + *

+ * This will log the result to check if clampMinFirst or clampMaxFirst should be used. + * + * @param input The input value to clamp + * @param min The minimum value to clamp to + * @param max The maximum value to clamp to + * + * @return The clamped value + */ + public static byte clampTest(final byte input, final byte min, final byte max) { + if (input < min) { + LOGGER.info("Clamped to minimum"); + return min; + } else if (input > max) { + LOGGER.info("Clamped to maximum"); + return max; + } else { + LOGGER.info("Did not clamp"); + return input; + } + } + + /** + * Clamps a value within a specified range [min, max], checking for the maximum value first. + *

+ * If the input is greater than max, it returns max. If the input is less than min, it returns min. + * Otherwise, it returns the input. + *

+ * This will log the result to check if clampMinFirst or clampMaxFirst should be used. + * + * @param input The input value to clamp + * @param min The minimum value to clamp to + * @param max The maximum value to clamp to + * + * @return The clamped value + */ + public static short clampTest(final short input, final short min, final short max) { + if (input < min) { + LOGGER.info("Clamped to minimum"); + return min; + } else if (input > max) { + LOGGER.info("Clamped to maximum"); + return max; + } else { + LOGGER.info("Did not clamp"); + return input; + } + } + + /** + * Clamps a value within a specified range [min, max], checking for the maximum value first. + *

+ * If the input is greater than max, it returns max. If the input is less than min, it returns min. + * Otherwise, it returns the input. + *

+ * This will log the result to check if clampMinFirst or clampMaxFirst should be used. + * + * @param input The input value to clamp + * @param min The minimum value to clamp to + * @param max The maximum value to clamp to + * + * @return The clamped value + */ + public static int clampTest(final int input, final int min, final int max) { + if (input < min) { + LOGGER.info("Clamped to minimum"); + return min; + } else if (input > max) { + LOGGER.info("Clamped to maximum"); + return max; + } else { + LOGGER.info("Did not clamp"); + return input; + } + } + + /** + * Clamps a value within a specified range [min, max], checking for the maximum value first. + *

+ * If the input is greater than max, it returns max. If the input is less than min, it returns min. + * Otherwise, it returns the input. + *

+ * This will log the result to check if clampMinFirst or clampMaxFirst should be used. + * + * @param input The input value to clamp + * @param min The minimum value to clamp to + * @param max The maximum value to clamp to + * + * @return The clamped value + */ + public static long clampTest(final long input, final long min, final long max) { + if (input < min) { + LOGGER.info("Clamped to minimum"); + return min; + } else if (input > max) { + LOGGER.info("Clamped to maximum"); + return max; + } else { + LOGGER.info("Did not clamp"); + return input; + } + } + + /** + * Clamps a value within a specified range [min, max], checking for the maximum value first. + *

+ * If the input is greater than max, it returns max. If the input is less than min, it returns min. + * Otherwise, it returns the input. + *

+ * This will log the result to check if clampMinFirst or clampMaxFirst should be used. + * + * @param input The input value to clamp + * @param min The minimum value to clamp to + * @param max The maximum value to clamp to + * + * @return The clamped value + */ + public static float clampTest(final float input, final float min, final float max) { + if (input < min) { + LOGGER.info("Clamped to minimum"); + return min; + } else if (input > max) { + LOGGER.info("Clamped to maximum"); + return max; + } else { + LOGGER.info("Did not clamp"); + return input; + } + } + + /** + * Clamps a value within a specified range [min, max], checking for the maximum value first. + *

+ * If the input is greater than max, it returns max. If the input is less than min, it returns min. + * Otherwise, it returns the input. + *

+ * This will log the result to check if clampMinFirst or clampMaxFirst should be used. + * + * @param input The input value to clamp + * @param min The minimum value to clamp to + * @param max The maximum value to clamp to + * + * @return The clamped value + */ + public static double clampTest(final double input, final double min, final double max) { + if (input < min) { + LOGGER.info("Clamped to minimum"); + return min; + } else if (input > max) { + LOGGER.info("Clamped to maximum"); + return max; + } else { + LOGGER.info("Did not clamp"); + return input; + } + } + + /** + * Clamps a value within a specified range [min, max], checking for the minimum value first. + *

+ * If the input is less than min, it returns min. If the input is greater than max, it returns max. + * Otherwise, it returns the input. + * + * @param input The input value to clamp + * @param min The minimum value to clamp to + * @param max The maximum value to clamp to + * + * @return The clamped value + */ + public static byte clampMinFirst(final byte input, final byte min, final byte max) { + return input < min ? min : input > max ? max : input; + } + + /** + * Clamps a value within a specified range [min, max], checking for the minimum value first. + *

+ * If the input is less than min, it returns min. If the input is greater than max, it returns max. + * Otherwise, it returns the input. + * + * @param input The input value to clamp + * @param min The minimum value to clamp to + * @param max The maximum value to clamp to + * + * @return The clamped value + */ + public static short clampMinFirst(final short input, final short min, final short max) { + return input < min ? min : input > max ? max : input; + } + + /** + * Clamps a value within a specified range [min, max], checking for the minimum value first. + *

+ * If the input is less than min, it returns min. If the input is greater than max, it returns max. + * Otherwise, it returns the input. + * + * @param input The input value to clamp + * @param min The minimum value to clamp to + * @param max The maximum value to clamp to + * + * @return The clamped value + */ + public static int clampMinFirst(final int input, final int min, final int max) { + return input < min ? min : input > max ? max : input; + } + + /** + * Clamps a value within a specified range [min, max], checking for the minimum value first. + *

+ * If the input is less than min, it returns min. If the input is greater than max, it returns max. + * Otherwise, it returns the input. + * + * @param input The input value to clamp + * @param min The minimum value to clamp to + * @param max The maximum value to clamp to + * + * @return The clamped value + */ + public static long clampMinFirst(final long input, final long min, final long max) { + return input < min ? min : input > max ? max : input; + } + + /** + * Clamps a value within a specified range [min, max], checking for the minimum value first. + *

+ * If the input is less than min, it returns min. If the input is greater than max, it returns max. + * Otherwise, it returns the input. + * + * @param input The input value to clamp + * @param min The minimum value to clamp to + * @param max The maximum value to clamp to + * + * @return The clamped value + */ + public static float clampMinFirst(final float input, final float min, final float max) { + return input < min ? min : input > max ? max : input; + } + + /** + * Clamps a value within a specified range [min, max], checking for the minimum value first. + *

+ * If the input is less than min, it returns min. If the input is greater than max, it returns max. + * Otherwise, it returns the input. + * + * @param input The input value to clamp + * @param min The minimum value to clamp to + * @param max The maximum value to clamp to + * + * @return The clamped value + */ + public static double clampMinFirst(final double input, final double min, final double max) { + return input < min ? min : input > max ? max : input; + } + + /** + * Clamps a value within a specified range [min, max], checking for the maximum value first. + *

+ * If the input is greater than max, it returns max. If the input is less than min, it returns min. + * Otherwise, it returns the input. + * + * @param input The input value to clamp + * @param min The minimum value to clamp to + * @param max The maximum value to clamp to + * @return The clamped value + */ + public static byte clampMaxFirst(final byte input, final byte min, final byte max) { + return input > max ? max : input < min ? min : input; + } + + /** + * Clamps a value within a specified range [min, max], checking for the maximum value first. + *

+ * If the input is greater than max, it returns max. If the input is less than min, it returns min. + * Otherwise, it returns the input. + * + * @param input The input value to clamp + * @param min The minimum value to clamp to + * @param max The maximum value to clamp to + * @return The clamped value + */ + public static short clampMaxFirst(final short input, final short min, final short max) { + return input > max ? max : input < min ? min : input; + } + + /** + * Clamps a value within a specified range [min, max], checking for the maximum value first. + *

+ * If the input is greater than max, it returns max. If the input is less than min, it returns min. + * Otherwise, it returns the input. + * + * @param input The input value to clamp + * @param min The minimum value to clamp to + * @param max The maximum value to clamp to + * @return The clamped value + */ + public static int clampMaxFirst(final int input, final int min, final int max) { + return input > max ? max : input < min ? min : input; + } + + /** + * Clamps a value within a specified range [min, max], checking for the maximum value first. + *

+ * If the input is greater than max, it returns max. If the input is less than min, it returns min. + * Otherwise, it returns the input. + * + * @param input The input value to clamp + * @param min The minimum value to clamp to + * @param max The maximum value to clamp to + * @return The clamped value + */ + public static long clampMaxFirst(final long input, final long min, final long max) { + return input > max ? max : input < min ? min : input; + } + + /** + * Clamps a value within a specified range [min, max], checking for the maximum value first. + *

+ * If the input is greater than max, it returns max. If the input is less than min, it returns min. + * Otherwise, it returns the input. + * + * @param input The input value to clamp + * @param min The minimum value to clamp to + * @param max The maximum value to clamp to + * @return The clamped value + */ + public static float clampMaxFirst(final float input, final float min, final float max) { + return input > max ? max : input < min ? min : input; + } + + /** + * Clamps a value within a specified range [min, max], checking for the maximum value first. + *

+ * If the input is greater than max, it returns max. If the input is less than min, it returns min. + * Otherwise, it returns the input. + * + * @param input The input value to clamp + * @param min The minimum value to clamp to + * @param max The maximum value to clamp to + * @return The clamped value + */ + public static double clampMaxFirst(final double input, final double min, final double max) { + return input > max ? max : input < min ? min : input; + } +} diff --git a/core/src/main/java/dev/redstudio/redcore/utils/math/MathUtil.java b/core/src/main/java/dev/redstudio/redcore/utils/math/MathUtil.java new file mode 100644 index 0000000..4d3d28c --- /dev/null +++ b/core/src/main/java/dev/redstudio/redcore/utils/math/MathUtil.java @@ -0,0 +1,197 @@ +package dev.redstudio.redcore.utils.math; + +import net.jafama.FastMath; + +/** + * A utility class that offers efficient mathematical operations such as absolute value calculation, linear interpolation, and rounding operations. + * + * @author Desoroxxx + * @since 0.2 + */ +@SuppressWarnings({"unused"}) +public final class MathUtil { + + /** + * Returns the absolute value of a number. + *

+ * The absolute value of a number is the number without its sign, so it is always a positive number. + * + * @param input The number to get the absolute value of + * @return The absolute value of the input + */ + public static float absolute(final float input) { + return input >= 0 ? input : -input; + } + + /** + * Returns the absolute value of a number. + *

+ * The absolute value of a number is the number without its sign, so it is always a positive number. + * + * @param input The number to get the absolute value of + * @return The absolute value of the input + */ + public static double absolute(final double input) { + return input >= 0 ? input : -input; + } + + /** + * Returns the maximum of the absolute values of two numbers. + *

+ * The absolute value of a number is the number without its sign, so it is always a positive number. + * + * @param input1 The first input + * @param input2 The second input + * @return The absolute maximum of the two inputs + */ + public static float absoluteMax(final float input1, final float input2) { + return Math.max(input1 >= 0 ? input1 : -input1, input2 >= 0 ? input2 : -input2); + } + + /** + * Returns the maximum of the absolute values of two numbers. + *

+ * The absolute value of a number is the number without its sign, so it is always a positive number. + * + * @param input1 The first input + * @param input2 The second input + * @return The absolute maximum of the two inputs + */ + public static double absoluteMax(final double input1, final double input2) { + return Math.max(input1 >= 0 ? input1 : -input1, input2 >= 0 ? input2 : -input2); + } + + /** + * Adds or subtracts a value from the input based on the sign of the input. + *

+ * If the input is negative, the 'add' value is subtracted from the input. + * If the input is positive or zero, the 'add' value is added to the input. + * + * @param input The input value + * @param add The value to add or subtract based on the sign of the input + * @return The result of the operation + */ + public static float addOrSubtractBasedOnSign(final float input, final float add) { + return input < 0 ? input - add : input + add; + } + + /** + * Adds or subtracts a value from the input based on the sign of the input. + *

+ * If the input is negative, the 'add' value is subtracted from the input. + * If the input is positive or zero, the 'add' value is added to the input. + * + * @param input The input value + * @param add The value to add or subtract based on the sign of the input + * @return The result of the operation + */ + public static double addOrSubtractBasedOnSign(final double input, final double add) { + return input < 0 ? input - add : input + add; + } + + /** + * Rounds a number to a specified number of decimal places. + *

+ * This is accomplished by multiplying the input by 10 raised to the power of 'decimals', + * rounding the result to the nearest integer, + * and then dividing by 10 raised to the power of 'decimals' again. + * + * @param input The number to round + * @param decimals The number of decimal places to round to + * @return The rounded number + */ + public static float round(final float input, final int decimals) { + final float multiplier = (float) FastMath.pow(10, decimals); + + // Convert input to an integer by multiplying it by 10^decimals and rounding it + final int rounded = FastMath.round(input * multiplier); + + // Divide the rounded number by 10^decimals to get the rounded result + return (rounded) / multiplier; + } + + /** + * Rounds a number to a specified number of decimal places. + *

+ * This is accomplished by multiplying the input by 10 raised to the power of 'decimals', + * rounding the result to the nearest integer, + * and then dividing by 10 raised to the power of 'decimals' again. + * + * @param input The number to round + * @param decimals The number of decimal places to round to + * @return The rounded number + */ + public static double round(final double input, final int decimals) { + final double multiplier = FastMath.pow(10, decimals); + + // Convert input to an integer by multiplying it by 10^decimals and rounding it + final long rounded = FastMath.round(input * multiplier); + + // Divide the rounded number by 10^decimals to get the rounded result + return (rounded) / multiplier; + } + + /** + * Converts a number to an integer by flooring it. + *

+ * If the input is less than the floored value, it returns one less than the floored value. + * Otherwise, it returns the floored value. + * + * @param input The number to floor and convert to an integer + * @return The floored integer value + */ + public static int floorToInt(final float input) { + final int floored = (int) input; + + return input < floored ? floored - 1 : floored; + } + + /** + * Converts a number to an integer by flooring it. + *

+ * If the input is less than the floored value, it returns one less than the floored value. + * Otherwise, it returns the floored value. + * + * @param input The number to floor and convert to an integer + * @return The floored integer value + */ + public static int floorToInt(final double input) { + final int floored = (int) input; + + return input < floored ? floored - 1 : floored; + } + + /** + * Performs a linear interpolation between two values. + * + * @param startValue The starting value. + * @param partialTicks The fraction of the tick that has passed. + * @param targetValue The target value. + * @return The interpolated value. + */ + public static float lerp(final float startValue, final float partialTicks, final float targetValue) { + return startValue + (targetValue - startValue) * partialTicks; + } + + /** + * Performs a linear interpolation between two values. + * + * @param input The starting value. + * @param partialTicks The fraction of the tick that has passed. + * @param target The target value. + * @return The interpolated value. + */ + public static double lerp(final double input, final double partialTicks, final double target) { + return input + (target - input) * partialTicks; + } + + /** + * Converts a boolean value to an integer. + * + * @param input The boolean value to convert + * @return 1 if the input is true, 0 if it's false + */ + public static int boolToInt(final boolean input) { + return input ? 1 : 0; + } +} diff --git a/gradle.properties b/gradle.properties index e24f27a..22e1dd7 100644 --- a/gradle.properties +++ b/gradle.properties @@ -7,8 +7,3 @@ org.gradle.parallel = true org.gradle.caching = true # Force the daemon to be used instead of being restarted each time. org.gradle.daemon = true - -# Mod Constants -# Versioning must follow Ragnarök versioning convention: https://shor.cz/ragnarok_versioning_convention -id = redcore -version = 0.5-Dev-1 diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index 51cae1e..9170aec 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -1,6 +1,6 @@ #Sun Mar 12 12:17:31 CET 2023 distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-8.3-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-8.4-bin.zip zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists diff --git a/mc/build.gradle.kts b/mc/build.gradle.kts new file mode 100644 index 0000000..2450874 --- /dev/null +++ b/mc/build.gradle.kts @@ -0,0 +1,44 @@ +plugins { + id("com.gtnewhorizons.retrofuturagradle") version "1.3.24" +} + +minecraft { + mcVersion = "1.12.2" + username = "Desoroxxx" + extraRunJvmArguments = listOf("-Dforge.logging.console.level=debug", "-Dfml.coreMods.load=${project.group}.redcore.RedCorePlugin") +} + +dependencies { + embed(project(":core")) + + implementation("net.jafama", "jafama", "2.3.2") +} + +idea { + module { + isDownloadJavadoc = true + isDownloadSources = true + inheritOutputDirs = true // Fix resources in IJ-Native runs + } +} + +tasks.named("jar") { + manifest { + attributes( + "ModSide" to "BOTH", + "FMLCorePlugin" to "${project.group}.redcore.RedCorePlugin", + "FMLCorePluginContainsFMLMod" to "true", + "ForceLoadAsMod" to "true" + ) + } + + archiveBaseName = "!Red-Core-1.12" +} + +publishing.publications.register("redCoreMc", MavenPublication::class) { + from(components["java"]) + + groupId = project.group.toString() + artifactId = "red-core-mc" + version = project.version.toString() +} diff --git a/mc/gradle.properties b/mc/gradle.properties new file mode 100644 index 0000000..74d2d94 --- /dev/null +++ b/mc/gradle.properties @@ -0,0 +1 @@ +rfg.disableDependencyDeobfuscation=true diff --git a/src/main/java/dev/redstudio/redcore/RedCore.java b/mc/src/main/java/dev/redstudio/redcore/RedCorePlugin.java similarity index 86% rename from src/main/java/dev/redstudio/redcore/RedCore.java rename to mc/src/main/java/dev/redstudio/redcore/RedCorePlugin.java index a1b9896..73f87cc 100644 --- a/src/main/java/dev/redstudio/redcore/RedCore.java +++ b/mc/src/main/java/dev/redstudio/redcore/RedCorePlugin.java @@ -1,7 +1,6 @@ package dev.redstudio.redcore; import com.google.common.eventbus.EventBus; -import dev.redstudio.redcore.utils.ProjectConstants; import net.minecraftforge.fml.common.DummyModContainer; import net.minecraftforge.fml.common.LoadController; import net.minecraftforge.fml.common.ModMetadata; @@ -10,20 +9,20 @@ import javax.annotation.Nullable; import java.util.Map; -import static dev.redstudio.redcore.utils.ProjectConstants.*; +import static dev.redstudio.redcore.ProjectConstants.*; -// /$$$$$$$ /$$ /$$$$$$ -// | $$__ $$ | $$ /$$__ $$ -// | $$ \ $$ /$$$$$$ /$$$$$$$ | $$ \__/ /$$$$$$ /$$$$$$ /$$$$$$ -// | $$$$$$$/ /$$__ $$ /$$__ $$ | $$ /$$__ $$ /$$__ $$ /$$__ $$ -// | $$__ $$| $$$$$$$$| $$ | $$ | $$ | $$ \ $$| $$ \__/| $$$$$$$$ -// | $$ \ $$| $$_____/| $$ | $$ | $$ $$| $$ | $$| $$ | $$_____/ -// | $$ | $$| $$$$$$$| $$$$$$$ | $$$$$$/| $$$$$$/| $$ | $$$$$$$ -// |__/ |__/ \_______/ \_______/ \______/ \______/ |__/ \_______/ +// /$$$$$$$ /$$ /$$$$$$ /$$ /$$ /$$$$$$ +// | $$__ $$ | $$ /$$__ $$ | $$$ /$$$ /$$__ $$ +// | $$ \ $$ /$$$$$$ /$$$$$$$ | $$ \__/ /$$$$$$ /$$$$$$ /$$$$$$ | $$$$ /$$$$| $$ \__/ +// | $$$$$$$/ /$$__ $$ /$$__ $$ | $$ /$$__ $$ /$$__ $$ /$$__ $$ | $$ $$/$$ $$| $$ +// | $$__ $$| $$$$$$$$| $$ | $$ | $$ | $$ \ $$| $$ \__/| $$$$$$$$ | $$ $$$| $$| $$ +// | $$ \ $$| $$_____/| $$ | $$ | $$ $$| $$ | $$| $$ | $$_____/ | $$\ $ | $$| $$ $$ +// | $$ | $$| $$$$$$$| $$$$$$$ | $$$$$$/| $$$$$$/| $$ | $$$$$$$ | $$ \/ | $$| $$$$$$/ +// |__/ |__/ \_______/ \_______/ \______/ \______/ |__/ \_______/ |__/ |__/ \______/ @IFMLLoadingPlugin.Name(NAME) @IFMLLoadingPlugin.MCVersion("1.12.2") @IFMLLoadingPlugin.SortingIndex(Integer.MIN_VALUE + 2) -public final class RedCore implements IFMLLoadingPlugin { +public final class RedCorePlugin implements IFMLLoadingPlugin { @Override public String[] getASMTransformerClass() { @@ -32,7 +31,7 @@ public String[] getASMTransformerClass() { @Override public String getModContainerClass() { - return "dev.redstudio.redcore.RedCore$Container"; + return "dev.redstudio.redcore.RedCorePlugin$Container"; } @Nullable @@ -58,7 +57,7 @@ public Container() { final ModMetadata modMetadata = this.getMetadata(); - modMetadata.modId = ID; + modMetadata.modId = "redcore"; modMetadata.name = NAME; modMetadata.description = "§lRed-Core§r\n\nRed-Core is the foundational framework for Red Studio projects and associated projects. It features robust development utilities, streamlined error logging, and a high-speed, clean vectors' suite.\n\n§lFeatures§r\n\n- §lRedLogger:§r This robust error logger elevates error tracking, offering a clean, user-friendly experience that demystifies complex error data.\n- §lVectors:§r Introducing a comprehensive vector suite that is sleek and speedy, continuously evolving with new features as per necessity.\n- §lMathUtil:§r A purpose-built class providing an array of mathematical methods, engineered with a steadfast focus on rapid processing and calculations.\n- §lStopwatch:§r Tailored for precise profiling, this stopwatch sets itself apart in the burgeoning roster of Java-based stopwatch solutions, by its simplicity and easy of use.\n- §lRedClientTicker:§r A useful ticker that allows you to have ticks every 2, 5 or 10 normal ticks, for things that shouldn't run 20 times a second.\n- §lOptiNotFine:§r A must-have when working with OptiFine compatibility, it allows you to know if OptiFine is installed, whether shaders are loaded, and to force fast render off.\n- §lNetworkUtil:§r Designed to streamline network coding practices, this utility makes writing cleaner, safer, and more efficient networking code effortless.\n- §lJafama:§r Red Core embeds Jafama allowing you to use it in your mods\n\n§lWhy Red-Core?§r\n\nRed-Core sits at the heart of Red Studio's Minecraft 1.12 mods, aiming to make your mod development process more efficient. By providing a set of tailored tools and libraries, we allow you to focus more on designing exciting mods and less on the intricacies of development.\n\nWhat sets us apart is our comprehensive Javadoc documentation. We believe good documentation is the cornerstone of effective development. Every method in Red-Core comes with detailed Javadoc comments, making the technical information and guidance you need just a ctrl-click away.\n\nJoin us in enhancing Red-Core! We believe in constant evolution and the power of community-driven development. Whether you're a contributor or a user in the Minecraft modding community, your experience matters. We're here to ensure it's the best it can be."; modMetadata.url = "https://www.curseforge.com/minecraft/mc-mods/red-core"; diff --git a/src/main/java/dev/redstudio/redcore/ticking/RedClientTickEvent.java b/mc/src/main/java/dev/redstudio/redcore/ticking/RedClientTickEvent.java similarity index 100% rename from src/main/java/dev/redstudio/redcore/ticking/RedClientTickEvent.java rename to mc/src/main/java/dev/redstudio/redcore/ticking/RedClientTickEvent.java diff --git a/src/main/java/dev/redstudio/redcore/ticking/RedClientTicker.java b/mc/src/main/java/dev/redstudio/redcore/ticking/RedClientTicker.java similarity index 100% rename from src/main/java/dev/redstudio/redcore/ticking/RedClientTicker.java rename to mc/src/main/java/dev/redstudio/redcore/ticking/RedClientTicker.java diff --git a/src/main/java/dev/redstudio/redcore/utils/NetworkUtil.java b/mc/src/main/java/dev/redstudio/redcore/utils/NetworkUtil.java similarity index 100% rename from src/main/java/dev/redstudio/redcore/utils/NetworkUtil.java rename to mc/src/main/java/dev/redstudio/redcore/utils/NetworkUtil.java diff --git a/src/main/java/dev/redstudio/redcore/utils/OptiNotFine.java b/mc/src/main/java/dev/redstudio/redcore/utils/OptiNotFine.java similarity index 98% rename from src/main/java/dev/redstudio/redcore/utils/OptiNotFine.java rename to mc/src/main/java/dev/redstudio/redcore/utils/OptiNotFine.java index 94b84ab..3571662 100644 --- a/src/main/java/dev/redstudio/redcore/utils/OptiNotFine.java +++ b/mc/src/main/java/dev/redstudio/redcore/utils/OptiNotFine.java @@ -10,7 +10,7 @@ import java.lang.reflect.Field; -import static dev.redstudio.redcore.utils.ProjectConstants.RED_LOGGER; +import static dev.redstudio.redcore.ProjectConstants.RED_LOGGER; /** * This class provides methods to communicate with OptiNotFine (Can you see that I hate OptiFine?) diff --git a/src/main/java/dev/redstudio/redcore/vectors/Vector2D.java b/mc/src/main/java/dev/redstudio/redcore/vectors/Vector2D.java similarity index 100% rename from src/main/java/dev/redstudio/redcore/vectors/Vector2D.java rename to mc/src/main/java/dev/redstudio/redcore/vectors/Vector2D.java diff --git a/src/main/java/dev/redstudio/redcore/vectors/Vector2F.java b/mc/src/main/java/dev/redstudio/redcore/vectors/Vector2F.java similarity index 100% rename from src/main/java/dev/redstudio/redcore/vectors/Vector2F.java rename to mc/src/main/java/dev/redstudio/redcore/vectors/Vector2F.java diff --git a/src/main/java/dev/redstudio/redcore/vectors/Vector2I.java b/mc/src/main/java/dev/redstudio/redcore/vectors/Vector2I.java similarity index 100% rename from src/main/java/dev/redstudio/redcore/vectors/Vector2I.java rename to mc/src/main/java/dev/redstudio/redcore/vectors/Vector2I.java diff --git a/src/main/java/dev/redstudio/redcore/vectors/Vector3D.java b/mc/src/main/java/dev/redstudio/redcore/vectors/Vector3D.java similarity index 100% rename from src/main/java/dev/redstudio/redcore/vectors/Vector3D.java rename to mc/src/main/java/dev/redstudio/redcore/vectors/Vector3D.java diff --git a/src/main/java/dev/redstudio/redcore/vectors/Vector3F.java b/mc/src/main/java/dev/redstudio/redcore/vectors/Vector3F.java similarity index 100% rename from src/main/java/dev/redstudio/redcore/vectors/Vector3F.java rename to mc/src/main/java/dev/redstudio/redcore/vectors/Vector3F.java diff --git a/src/main/java/dev/redstudio/redcore/vectors/Vector3I.java b/mc/src/main/java/dev/redstudio/redcore/vectors/Vector3I.java similarity index 100% rename from src/main/java/dev/redstudio/redcore/vectors/Vector3I.java rename to mc/src/main/java/dev/redstudio/redcore/vectors/Vector3I.java diff --git a/src/main/resources/logo.png b/mc/src/main/resources/logo.png similarity index 100% rename from src/main/resources/logo.png rename to mc/src/main/resources/logo.png diff --git a/settings.gradle b/settings.gradle.kts similarity index 77% rename from settings.gradle rename to settings.gradle.kts index fdce55e..ebb6993 100644 --- a/settings.gradle +++ b/settings.gradle.kts @@ -1,10 +1,12 @@ +rootProject.name = "Red-Core" + pluginManagement { repositories { maven { // RetroFuturaGradle name = "GTNH Maven" url = uri("http://jenkins.usrv.eu:8081/nexus/content/groups/public/") - allowInsecureProtocol = true + isAllowInsecureProtocol = true mavenContent { includeGroup("com.gtnewhorizons") includeGroup("com.gtnewhorizons.retrofuturagradle") @@ -17,6 +19,8 @@ pluginManagement { } plugins { - // Automatic toolchain provisioning - id("org.gradle.toolchains.foojay-resolver-convention") version "0.7.0" + id("org.gradle.toolchains.foojay-resolver-convention") version "0.7.0" // Automatic toolchain provisioning } + +include(":core") +include(":mc") diff --git a/src/main/java/dev/redstudio/redcore/utils/MathUtil.java b/src/main/java/dev/redstudio/redcore/utils/MathUtil.java deleted file mode 100644 index c87e34c..0000000 --- a/src/main/java/dev/redstudio/redcore/utils/MathUtil.java +++ /dev/null @@ -1,495 +0,0 @@ -package dev.redstudio.redcore.utils; - -import net.jafama.FastMath; - -import static dev.redstudio.redcore.utils.ProjectConstants.LOGGER; - -/** - * A utility class that offers efficient mathematical operations such as clamping, absolute value calculation, linear interpolation, and rounding operations. - *

- * These functions are optimized for speed and provided for both float and double data types. - * - * @author Desoroxxx - * @since 0.2 - */ -public final class MathUtil { - - /** - * Clamps a value within a specified range [min, max], checking for the minimum value first. - *

- * If the input is less than min, it returns min. If the input is greater than max, it returns max. - *

- * Otherwise, it returns the input. - * - * @param input The input value to clamp - * @param min The minimum value to clamp to - * @param max The maximum value to clamp to - * @return The clamped value - */ - public static float clampMinFirst(final float input, final float min, final float max) { - return input < min ? min : input > max ? max : input; - } - - /** - * Clamps a value within a specified range [min, max], checking for the maximum value first. - *

- * If the input is greater than max, it returns max. If the input is less than min, it returns min. - *

- * Otherwise, it returns the input. - * - * @param input The input value to clamp - * @param min The minimum value to clamp to - * @param max The maximum value to clamp to - * @return The clamped value - */ - public static float clampMaxFirst(final float input, final float min, final float max) { - return input > max ? max : input < min ? min : input; - } - - /** - * Clamps a value within a specified range [min, max], checking for the maximum value first. - *

- * If the input is greater than max, it returns max. If the input is less than min, it returns min. - *

- * Otherwise, it returns the input. - *

- * This will log the result to check if clampMinFirst or clampMaxFirst should be used. - * - * @param input The input value to clamp - * @param min The minimum value to clamp to - * @param max The maximum value to clamp to - * @return The clamped value - */ - public static float clampTest(final float input, final float min, final float max) { - if (input < min) { - LOGGER.info("Clamped to minimum"); - return min; - } else if (input > max) { - LOGGER.info("Clamped to maximum"); - return max; - } else { - LOGGER.info("Did not clamp"); - return input; - } - } - - /** - * Clamps a value within a specified range [min, max], checking for the minimum value first. - *

- * If the input is less than min, it returns min. If the input is greater than max, it returns max. - *

- * Otherwise, it returns the input. - * - * @param input The input value to clamp - * @param min The minimum value to clamp to - * @param max The maximum value to clamp to - * @return The clamped value - */ - public static double clampMinFirst(final double input, final double min, final double max) { - return input < min ? min : input > max ? max : input; - } - - /** - * Clamps a value within a specified range [min, max], checking for the maximum value first. - *

- * If the input is greater than max, it returns max. If the input is less than min, it returns min. - *

- * Otherwise, it returns the input. - * - * @param input The input value to clamp - * @param min The minimum value to clamp to - * @param max The maximum value to clamp to - * @return The clamped value - */ - public static double clampMaxFirst(final double input, final double min, final double max) { - return input > max ? max : input < min ? min : input; - } - - /** - * Clamps a value within a specified range [min, max], checking for the maximum value first. - *

- * If the input is greater than max, it returns max. If the input is less than min, it returns min. - *

- * Otherwise, it returns the input. - *

- * This will log the result to check if clampMinFirst or clampMaxFirst should be used. - * - * @param input The input value to clamp - * @param min The minimum value to clamp to - * @param max The maximum value to clamp to - * @return The clamped value - */ - public static double clampTest(final double input, final double min, final double max) { - if (input < min) { - LOGGER.info("Clamped to minimum"); - return min; - } else if (input > max) { - LOGGER.info("Clamped to maximum"); - return max; - } else { - LOGGER.info("Did not clamp"); - return input; - } - } - - /** - * Clamps a value within a specified range [min, max], checking for the minimum value first. - *

- * If the input is less than min, it returns min. If the input is greater than max, it returns max. - *

- * Otherwise, it returns the input. - * - * @param input The input value to clamp - * @param min The minimum value to clamp to - * @param max The maximum value to clamp to - * @return The clamped value - */ - public static byte clampMinFirst(final byte input, final byte min, final byte max) { - return input < min ? min : input > max ? max : input; - } - - /** - * Clamps a value within a specified range [min, max], checking for the maximum value first. - *

- * If the input is greater than max, it returns max. If the input is less than min, it returns min. - *

- * Otherwise, it returns the input. - * - * @param input The input value to clamp - * @param min The minimum value to clamp to - * @param max The maximum value to clamp to - * @return The clamped value - */ - public static byte clampMaxFirst(final byte input, final byte min, final byte max) { - return input > max ? max : input < min ? min : input; - } - - /** - * Clamps a value within a specified range [min, max], checking for the maximum value first. - *

- * If the input is greater than max, it returns max. If the input is less than min, it returns min. - *

- * Otherwise, it returns the input. - *

- * This will log the result to check if clampMinFirst or clampMaxFirst should be used. - * - * @param input The input value to clamp - * @param min The minimum value to clamp to - * @param max The maximum value to clamp to - * @return The clamped value - */ - public static byte clampTest(final byte input, final byte min, final byte max) { - if (input < min) { - LOGGER.info("Clamped to minimum"); - return min; - } else if (input > max) { - LOGGER.info("Clamped to maximum"); - return max; - } else { - LOGGER.info("Did not clamp"); - return input; - } - } - - /** - * Clamps a value within a specified range [min, max], checking for the minimum value first. - *

- * If the input is less than min, it returns min. If the input is greater than max, it returns max. - *

- * Otherwise, it returns the input. - * - * @param input The input value to clamp - * @param min The minimum value to clamp to - * @param max The maximum value to clamp to - * @return The clamped value - */ - public static short clampMinFirst(final short input, final short min, final short max) { - return input < min ? min : input > max ? max : input; - } - - /** - * Clamps a value within a specified range [min, max], checking for the maximum value first. - *

- * If the input is greater than max, it returns max. If the input is less than min, it returns min. - *

- * Otherwise, it returns the input. - * - * @param input The input value to clamp - * @param min The minimum value to clamp to - * @param max The maximum value to clamp to - * @return The clamped value - */ - public static short clampMaxFirst(final short input, final short min, final short max) { - return input > max ? max : input < min ? min : input; - } - - /** - * Clamps a value within a specified range [min, max], checking for the maximum value first. - *

- * If the input is greater than max, it returns max. If the input is less than min, it returns min. - *

- * Otherwise, it returns the input. - *

- * This will log the result to check if clampMinFirst or clampMaxFirst should be used. - * - * @param input The input value to clamp - * @param min The minimum value to clamp to - * @param max The maximum value to clamp to - * @return The clamped value - */ - public static short clampTest(final short input, final short min, final short max) { - if (input < min) { - LOGGER.info("Clamped to minimum"); - return min; - } else if (input > max) { - LOGGER.info("Clamped to maximum"); - return max; - } else { - LOGGER.info("Did not clamp"); - return input; - } - } - - /** - * Clamps a value within a specified range [min, max], checking for the minimum value first. - *

- * If the input is less than min, it returns min. If the input is greater than max, it returns max. - *

- * Otherwise, it returns the input. - * - * @param input The input value to clamp - * @param min The minimum value to clamp to - * @param max The maximum value to clamp to - * @return The clamped value - */ - public static int clampMinFirst(final int input, final int min, final int max) { - return input < min ? min : input > max ? max : input; - } - - /** - * Clamps a value within a specified range [min, max], checking for the maximum value first. - *

- * If the input is greater than max, it returns max. If the input is less than min, it returns min. - *

- * Otherwise, it returns the input. - * - * @param input The input value to clamp - * @param min The minimum value to clamp to - * @param max The maximum value to clamp to - * @return The clamped value - */ - public static int clampMaxFirst(final int input, final int min, final int max) { - return input > max ? max : input < min ? min : input; - } - - /** - * Clamps a value within a specified range [min, max], checking for the maximum value first. - *

- * If the input is greater than max, it returns max. If the input is less than min, it returns min. - *

- * Otherwise, it returns the input. - *

- * This will log the result to check if clampMinFirst or clampMaxFirst should be used. - * - * @param input The input value to clamp - * @param min The minimum value to clamp to - * @param max The maximum value to clamp to - * @return The clamped value - */ - public static int clampTest(final int input, final int min, final int max) { - if (input < min) { - LOGGER.info("Clamped to minimum"); - return min; - } else if (input > max) { - LOGGER.info("Clamped to maximum"); - return max; - } else { - LOGGER.info("Did not clamp"); - return input; - } - } - - /** - * Returns the absolute value of a number. - *

- * The absolute value of a number is the number without its sign, so it is always a positive number. - * - * @param input The number to get the absolute value of - * @return The absolute value of the input - */ - public static float absolute(final float input) { - return input >= 0 ? input : -input; - } - - /** - * Returns the absolute value of a number. - *

- * The absolute value of a number is the number without its sign, so it is always a positive number. - * - * @param input The number to get the absolute value of - * @return The absolute value of the input - */ - public static double absolute(final double input) { - return input >= 0 ? input : -input; - } - - /** - * Returns the maximum of the absolute values of two numbers. - *

- * The absolute value of a number is the number without its sign, so it is always a positive number. - * - * @param input1 The first input - * @param input2 The second input - * @return The absolute maximum of the two inputs - */ - public static float absoluteMax(final float input1, final float input2) { - return Math.max(input1 >= 0 ? input1 : -input1, input2 >= 0 ? input2 : -input2); - } - - /** - * Returns the maximum of the absolute values of two numbers. - *

- * The absolute value of a number is the number without its sign, so it is always a positive number. - * - * @param input1 The first input - * @param input2 The second input - * @return The absolute maximum of the two inputs - */ - public static double absoluteMax(final double input1, final double input2) { - return Math.max(input1 >= 0 ? input1 : -input1, input2 >= 0 ? input2 : -input2); - } - - /** - * Adds or subtracts a value from the input based on the sign of the input. - *

- * If the input is negative, the 'add' value is subtracted from the input. - *

- * If the input is positive or zero, the 'add' value is added to the input. - * - * @param input The input value - * @param add The value to add or subtract based on the sign of the input - * @return The result of the operation - */ - public static float addOrSubtractBasedOnSign(final float input, final float add) { - return input < 0 ? input - add : input + add; - } - - /** - * Adds or subtracts a value from the input based on the sign of the input. - *

- * If the input is negative, the 'add' value is subtracted from the input. - *

- * If the input is positive or zero, the 'add' value is added to the input. - * - * @param input The input value - * @param add The value to add or subtract based on the sign of the input - * @return The result of the operation - */ - public static double addOrSubtractBasedOnSign(final double input, final double add) { - return input < 0 ? input - add : input + add; - } - - /** - * Rounds a number to a specified number of decimal places. - *

- * This is accomplished by multiplying the input by 10 raised to the power of 'decimals', - * rounding the result to the nearest integer, - * and then dividing by 10 raised to the power of 'decimals' again. - * - * @param input The number to round - * @param decimals The number of decimal places to round to - * @return The rounded number - */ - public static float round(final float input, final int decimals) { - final float multiplier = (float) FastMath.pow(10, decimals); - // Convert input to an integer by multiplying it by 10^decimals and rounding it - final int rounded = FastMath.round(input * multiplier); - // Divide the rounded number by 10^decimals to get the rounded result - return (rounded) / multiplier; - } - - /** - * Rounds a number to a specified number of decimal places. - *

- * This is accomplished by multiplying the input by 10 raised to the power of 'decimals', - * rounding the result to the nearest integer, - * and then dividing by 10 raised to the power of 'decimals' again. - * - * @param input The number to round - * @param decimals The number of decimal places to round to - * @return The rounded number - */ - public static double round(final double input, final int decimals) { - final double multiplier = FastMath.pow(10, decimals); - // Convert input to an integer by multiplying it by 10^decimals and rounding it - final long rounded = FastMath.round(input * multiplier); - // Divide the rounded number by 10^decimals to get the rounded result - return (rounded) / multiplier; - } - - /** - * Converts a number to an integer by flooring it. - *

- * If the input is less than the floored value, it returns one less than the floored value. - *

- * Otherwise, it returns the floored value. - * - * @param input The number to floor and convert to an integer - * @return The floored integer value - */ - public static int floorToInt(final float input) { - final int floored = (int) input; - - return input < floored ? floored - 1 : floored; - } - - /** - * Converts a number to an integer by flooring it. - *

- * If the input is less than the floored value, it returns one less than the floored value. - *

- * Otherwise, it returns the floored value. - * - * @param input The number to floor and convert to an integer - * @return The floored integer value - */ - public static int floorToInt(final double input) { - final int floored = (int) input; - - return input < floored ? floored - 1 : floored; - } - - /** - * Performs a linear interpolation between two values. - * - * @param startValue The starting value. - * @param partialTicks The fraction of the tick that has passed. - * @param targetValue The target value. - * @return The interpolated value. - */ - public static float lerp(final float startValue, final float partialTicks, final float targetValue) { - return startValue + (targetValue - startValue) * partialTicks; - } - - /** - * Performs a linear interpolation between two values. - * - * @param input The starting value. - * @param partialTicks The fraction of the tick that has passed. - * @param target The target value. - * @return The interpolated value. - */ - public static double lerp(final double input, final double partialTicks, final double target) { - return input + (target - input) * partialTicks; - } - - /** - * Converts a boolean value to an integer. - * - * @param input The boolean value to convert - * @return 1 if the input is true, 0 if it's false - */ - public static int boolToInt(final boolean input) { - return input ? 1 : 0; - } -} diff --git a/src/main/java/dev/redstudio/redcore/utils/Stopwatch.java b/src/main/java/dev/redstudio/redcore/utils/Stopwatch.java deleted file mode 100644 index 5586f46..0000000 --- a/src/main/java/dev/redstudio/redcore/utils/Stopwatch.java +++ /dev/null @@ -1,101 +0,0 @@ -package dev.redstudio.redcore.utils; - -import java.io.*; -import java.util.HashMap; -import java.util.Map; - -import static dev.redstudio.redcore.utils.ProjectConstants.LOGGER; -import static dev.redstudio.redcore.utils.ProjectConstants.RED_LOGGER; - -/** - * A utility class for measuring elapsed time in milliseconds between two points in the code. - * - * @author Desoroxxx - * @since 0.2 - */ -public class Stopwatch { - - /** - * A private static variable that keeps track of the next ID to assign to a newly started stopwatch. - */ - private static int nextId = 0; - - /** - * A Map that stores the start time of each stopwatch identified by its ID. - */ - private static final Map startTimes = new HashMap<>(); - - /** - * Starts a new stopwatch and returns its unique ID. - * - * @return The ID of the newly started stopwatch - */ - public static int start() { - int id = nextId++; - - startTimes.put(id, System.nanoTime()); - LOGGER.info("Started chronometer with " + id); - - return id; - } - - /** - * Stops the stopwatch with the given ID and logs the elapsed time in milliseconds. - * - * @param id The ID of the stopwatch to stop - */ - public static void stop(int id) { - double elapsed = (System.nanoTime() - startTimes.get(id)) / 1_000_000.0; - String elapsedFormatted = String.format("%.2f", elapsed); - - LOGGER.info("Time elapsed for chronometer with id " + id + ": " + elapsedFormatted + "ms"); - startTimes.remove(id); - } - - /** - * Stops the stopwatch with the given ID and writes the elapsed time of the stopwatch with the given ID to the specified file. - * - * @param id The ID of the stopwatch to write to file - * @param filePath The path of the file to write to - */ - public static void stopAndWriteToFile(int id, String filePath) { - double elapsed = (System.nanoTime() - startTimes.get(id)) / 1_000_000.0; - String elapsedFormatted = String.format("%.2f", elapsed); - - LOGGER.info("Time elapsed for chronometer with id " + id + ": " + elapsedFormatted + "ms"); - startTimes.remove(id); - - try (BufferedWriter writer = new BufferedWriter(new FileWriter(filePath, true))) { - writer.write(elapsedFormatted); - writer.newLine(); - } catch (IOException ioException) { - RED_LOGGER.printFramedError("Stopwatch", "Failed to write file", "", ioException.getMessage(), ioException.getStackTrace()[3].toString()); - } - } - - /** - * Reads a file containing elapsed times and calculates their average. - * - * @param filePath The path of the file to read - */ - public static void calculateAverage(String filePath) { - double sum = 0; - int count = 0; - - try (BufferedReader reader = new BufferedReader(new FileReader(filePath))) { - String line; - while ((line = reader.readLine()) != null) { - sum += Double.parseDouble(line); - count++; - } - } catch (IOException ioException) { - RED_LOGGER.printFramedError("Stopwatch", "Failed to read file", "", ioException.getMessage(), ioException.getStackTrace()[3].toString()); - } - - if (count > 0) { - String averageFormatted = String.format("%.2f", sum / count); - LOGGER.info("Average elapsed time between " + count + " entries: " + averageFormatted + "ms"); - } else - LOGGER.warn("No elapsed times found in file."); - } -}