From fa647a4b5cd3eeac4cb0338e665ed3b843b7481d Mon Sep 17 00:00:00 2001 From: DBotThePony Date: Fri, 23 Sep 2022 23:26:07 +0700 Subject: [PATCH] More work on radial android switch menu --- .../mc/otm/datagen/ResearchData.kt | 2 +- .../mc/otm/datagen/lang/English.kt | 3 + .../otm/android/feature/ShockwaveFeature.kt | 9 +++ .../mc/otm/client/AndroidMenuKeyMapping.kt | 55 ++++++++++++------- .../ru/dbotthepony/mc/otm/core/EuclidMath.kt | 22 ++++++++ 5 files changed, 70 insertions(+), 21 deletions(-) diff --git a/src/data/kotlin/ru/dbotthepony/mc/otm/datagen/ResearchData.kt b/src/data/kotlin/ru/dbotthepony/mc/otm/datagen/ResearchData.kt index 8fa910dd1..55c0b077b 100644 --- a/src/data/kotlin/ru/dbotthepony/mc/otm/datagen/ResearchData.kt +++ b/src/data/kotlin/ru/dbotthepony/mc/otm/datagen/ResearchData.kt @@ -259,7 +259,7 @@ fun addResearchData(serializer: Consumer, lang: MatteryLang add(STEP_ASSIST, "Step Assist") add(STEP_ASSIST, "description", "Allows unit to step up whole blocks") - add(attackBoostList[0], "Improved Arms Servo %s") + add(attackBoostList[0], "Attack Boost %s") add(attackBoostList[0], "description", "Increases total melee attack strength by %s%%") } } diff --git a/src/data/kotlin/ru/dbotthepony/mc/otm/datagen/lang/English.kt b/src/data/kotlin/ru/dbotthepony/mc/otm/datagen/lang/English.kt index b9df87def..6ba5a545e 100644 --- a/src/data/kotlin/ru/dbotthepony/mc/otm/datagen/lang/English.kt +++ b/src/data/kotlin/ru/dbotthepony/mc/otm/datagen/lang/English.kt @@ -461,6 +461,9 @@ private fun research(provider: MatteryLanguageProvider) { private fun androidFeatures(provider: MatteryLanguageProvider) { with(provider.english) { add(AndroidFeatures.AIR_BAGS, "Air Bags") + add(AndroidFeatures.SHOCKWAVE, "Shockwave") + add(AndroidFeatures.NIGHT_VISION, "Night Vision") + add(AndroidFeatures.NANOBOTS_ARMOR, "Nanobots Armor") } } diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/android/feature/ShockwaveFeature.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/android/feature/ShockwaveFeature.kt index 3c1711eb9..cd3b0cd7c 100644 --- a/src/main/kotlin/ru/dbotthepony/mc/otm/android/feature/ShockwaveFeature.kt +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/android/feature/ShockwaveFeature.kt @@ -1,5 +1,6 @@ package ru.dbotthepony.mc.otm.android.feature +import com.mojang.blaze3d.systems.RenderSystem import com.mojang.blaze3d.vertex.PoseStack import net.minecraft.world.entity.LivingEntity import net.minecraft.world.level.block.Block @@ -148,6 +149,14 @@ class ShockwaveFeature(capability: MatteryPlayerCapability) : AndroidSwitchableF } override fun renderIcon(stack: PoseStack, x: Float, y: Float, width: Float, height: Float) { + if (cooldown > 0) { + RenderSystem.setShaderColor(1f, 0.4f, 0.4f, 1f) + } + ResearchIcons.ICON_SHOCKWAVE.render(stack, x, y, width, height) + + if (cooldown > 0) { + RenderSystem.setShaderColor(1f, 1f, 1f, 1f) + } } } diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/client/AndroidMenuKeyMapping.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/client/AndroidMenuKeyMapping.kt index 779846551..d4242d5ea 100644 --- a/src/main/kotlin/ru/dbotthepony/mc/otm/client/AndroidMenuKeyMapping.kt +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/client/AndroidMenuKeyMapping.kt @@ -2,6 +2,8 @@ package ru.dbotthepony.mc.otm.client import com.mojang.blaze3d.platform.InputConstants import com.mojang.blaze3d.systems.RenderSystem +import it.unimi.dsi.fastutil.objects.Object2FloatArrayMap +import it.unimi.dsi.fastutil.objects.Object2FloatFunction import net.minecraft.client.KeyMapping import net.minecraftforge.client.event.RegisterKeyMappingsEvent import net.minecraftforge.client.event.RenderGuiEvent @@ -9,11 +11,17 @@ import net.minecraftforge.client.settings.KeyConflictContext import org.lwjgl.glfw.GLFW.GLFW_CURSOR_DISABLED import org.lwjgl.glfw.GLFW.GLFW_CURSOR_NORMAL import ru.dbotthepony.mc.otm.OverdriveThatMatters +import ru.dbotthepony.mc.otm.android.AndroidFeature import ru.dbotthepony.mc.otm.android.AndroidFeatureType import ru.dbotthepony.mc.otm.android.AndroidSwitchableFeature import ru.dbotthepony.mc.otm.capability.matteryPlayer +import ru.dbotthepony.mc.otm.client.render.TextAlign +import ru.dbotthepony.mc.otm.client.render.drawAligned import ru.dbotthepony.mc.otm.client.render.drawArc +import ru.dbotthepony.mc.otm.core.RGBAColor +import ru.dbotthepony.mc.otm.core.angleDifference import ru.dbotthepony.mc.otm.core.linearInterpolation +import ru.dbotthepony.mc.otm.core.normalizeAngle import ru.dbotthepony.mc.otm.network.MatteryPlayerNetworkChannel import ru.dbotthepony.mc.otm.network.SwitchAndroidFeaturePacket import java.util.stream.Collectors @@ -31,7 +39,7 @@ object AndroidMenuKeyMapping : KeyMapping("key.otm.android_menu", KeyConflictCon private var lastRender: Long = System.nanoTime() private var lastSelectedDegree: Double? = null - private var lastSelectProgress = 0f + private val lastSelectProgress = Object2FloatArrayMap() override fun setDown(isDown: Boolean) { val old = this.isDown @@ -63,7 +71,7 @@ object AndroidMenuKeyMapping : KeyMapping("key.otm.android_menu", KeyConflictCon selectedFeature = null lastSelectedFeature = null lastSelectedDegree = null - lastSelectProgress = 0f + lastSelectProgress.clear() } } @@ -123,34 +131,44 @@ object AndroidMenuKeyMapping : KeyMapping("key.otm.android_menu", KeyConflictCon selectedFeature = features[index] lastSelectedFeature = features[index] - lastSelectProgress = (lastSelectProgress + delta * 0.01).coerceAtMost(1.0).toFloat() + lastSelectProgress.computeIfAbsent(features[index], Object2FloatFunction { 0f }) - RenderSystem.setShaderColor(85 / 255f, 197 / 255f, 255 / 255f, 0.3f * lastSelectProgress) + RenderSystem.setShaderColor(85 / 255f, 197 / 255f, 255 / 255f, 0.3f * lastSelectProgress.getFloat(features[index])) + + val lastSelectedDegree = lastSelectedDegree if (lastSelectedDegree == null) { - this.lastSelectedDegree = index * degreePerSlice + this.lastSelectedDegree = normalizeAngle(index * degreePerSlice) } else { - this.lastSelectedDegree = linearInterpolation(delta, lastSelectedDegree!!, index * degreePerSlice) + this.lastSelectedDegree = lastSelectedDegree + angleDifference(index * degreePerSlice, lastSelectedDegree) * delta * 0.02 } } else { selectedFeature = null - lastSelectProgress = (lastSelectProgress - delta * 0.01).coerceAtLeast(0.0).toFloat() - if (lastSelectProgress == 0f) { + if (!lastSelectProgress.values.any { it > 0f }) { lastSelectedDegree = null lastSelectedFeature = null } } - if (lastSelectedDegree != null) { - RenderSystem.setShaderColor(85 / 255f, 197 / 255f, 255 / 255f, 0.3f * lastSelectProgress) + for (key in lastSelectProgress.keys) { + if (key == selectedFeature) { + lastSelectProgress[key] = (lastSelectProgress.getFloat(key) + delta * 0.01).coerceAtMost(1.0).toFloat() + } else { + lastSelectProgress[key] = (lastSelectProgress.getFloat(key) - delta * 0.01).coerceAtLeast(0.0).toFloat() + } + } + + if (lastSelectedDegree != null && lastSelectedFeature != null) { + val max = lastSelectProgress.values.maxOf { it } + RenderSystem.setShaderColor(85 / 255f, 197 / 255f, 255 / 255f, 0.3f * max) drawArc( event.poseStack, minecraft.window.guiScaledWidth / 2f, minecraft.window.guiScaledHeight / 2f, - linearInterpolation(lastSelectProgress, size, size * 1.2f), - linearInterpolation(lastSelectProgress, size * 0.3f, size * 0.4f), + linearInterpolation(max, size, size * 1.2f), + linearInterpolation(max, size * 0.3f, size * 0.4f), startDegree = lastSelectedDegree!!, endDegree = lastSelectedDegree!! + degreePerSlice @@ -160,7 +178,7 @@ object AndroidMenuKeyMapping : KeyMapping("key.otm.android_menu", KeyConflictCon RenderSystem.setShaderColor(1f, 1f, 1f, 1f) val iconSize = size * 0.25f - val iconSizeSelected = linearInterpolation(lastSelectProgress, size * 0.25f, size * 0.3f) + val iconSizeSelected = linearInterpolation(if (lastSelectedFeature != null) lastSelectProgress.getFloat(lastSelectedFeature) else 0f, size * 0.25f, size * 0.3f) event.poseStack.pushPose() event.poseStack.translate(minecraft.window.guiScaledWidth.toDouble() / 2f, minecraft.window.guiScaledHeight.toDouble() / 2f, 0.0) @@ -168,18 +186,15 @@ object AndroidMenuKeyMapping : KeyMapping("key.otm.android_menu", KeyConflictCon if (features.size == 1) { val feature = features.first() - feature.renderIcon(event.poseStack, -iconSizeSelected / 2f, -size * linearInterpolation(lastSelectProgress, 0.7f, 0.8f) - iconSizeSelected / 2f, iconSizeSelected, iconSizeSelected) + feature.renderIcon(event.poseStack, -iconSizeSelected / 2f, -size * linearInterpolation(lastSelectProgress.getFloat(feature), 0.7f, 0.8f) - iconSizeSelected / 2f, iconSizeSelected, iconSizeSelected) } else { for ((index, feature) in features.withIndex()) { val sin = sin((index + 0.5) * degreePerSlice).toFloat() val cos = cos((index + 0.5) * degreePerSlice).toFloat() - if (feature == lastSelectedFeature) { - val selectedShift = linearInterpolation(lastSelectProgress, size * 0.7f, size * 0.8f) - feature.renderIcon(event.poseStack, -iconSizeSelected / 2f + selectedShift * cos, -selectedShift * sin - iconSizeSelected / 2f, iconSizeSelected, iconSizeSelected) - } else { - feature.renderIcon(event.poseStack, -iconSize / 2f + size * 0.7f * cos, -size * 0.7f * sin - iconSize / 2f, iconSize, iconSize) - } + val selectedShift = linearInterpolation(lastSelectProgress.getFloat(feature), size * 0.6f, size * 0.8f) + feature.renderIcon(event.poseStack, -iconSize / 2f + selectedShift * cos, -selectedShift * sin - iconSize / 2f, iconSize, iconSize) + minecraft.font.drawAligned(event.poseStack, feature.type.displayName, TextAlign.CENTER_CENTER, selectedShift * cos, -selectedShift * sin - iconSize / 1.5f, if (feature.isActive) RGBAColor.DARK_GREEN else RGBAColor.DARK_RED) } } diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/core/EuclidMath.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/core/EuclidMath.kt index 6ba61c65d..afe7516a5 100644 --- a/src/main/kotlin/ru/dbotthepony/mc/otm/core/EuclidMath.kt +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/core/EuclidMath.kt @@ -448,3 +448,25 @@ fun getEllipsoidBlockPositions(x: Int, y: Int, z: Int): List { blockShapeCache[EllipsoidShapeCacheKey(x, y, z)] = SoftReference(immutableList) return immutableList } + +fun normalizeAngle(angle: Double): Double { + return (angle + PI) % (PI * 2.0) - PI +} + +fun angleDifference(angle1: Double, angle2: Double): Double { + val diff = normalizeAngle(angle1 - angle2) + + if (diff < PI) { + return diff + } + + return PI * 2.0 - diff +} + +fun normalizeAngle(angle: Float): Float { + return normalizeAngle(angle.toDouble()).toFloat() +} + +fun angleDifference(angle1: Float, angle2: Float): Float { + return angleDifference(angle1.toDouble(), angle2.toDouble()).toFloat() +}