More work on radial android switch menu

This commit is contained in:
DBotThePony 2022-09-23 23:26:07 +07:00
parent fe1e7c4cf4
commit fa647a4b5c
Signed by: DBot
GPG Key ID: DCC23B5715498507
5 changed files with 70 additions and 21 deletions

View File

@ -259,7 +259,7 @@ fun addResearchData(serializer: Consumer<AndroidResearchType>, lang: MatteryLang
add(STEP_ASSIST, "Step Assist") add(STEP_ASSIST, "Step Assist")
add(STEP_ASSIST, "description", "Allows unit to step up whole blocks") 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%%") add(attackBoostList[0], "description", "Increases total melee attack strength by %s%%")
} }
} }

View File

@ -461,6 +461,9 @@ private fun research(provider: MatteryLanguageProvider) {
private fun androidFeatures(provider: MatteryLanguageProvider) { private fun androidFeatures(provider: MatteryLanguageProvider) {
with(provider.english) { with(provider.english) {
add(AndroidFeatures.AIR_BAGS, "Air Bags") add(AndroidFeatures.AIR_BAGS, "Air Bags")
add(AndroidFeatures.SHOCKWAVE, "Shockwave")
add(AndroidFeatures.NIGHT_VISION, "Night Vision")
add(AndroidFeatures.NANOBOTS_ARMOR, "Nanobots Armor")
} }
} }

View File

@ -1,5 +1,6 @@
package ru.dbotthepony.mc.otm.android.feature package ru.dbotthepony.mc.otm.android.feature
import com.mojang.blaze3d.systems.RenderSystem
import com.mojang.blaze3d.vertex.PoseStack import com.mojang.blaze3d.vertex.PoseStack
import net.minecraft.world.entity.LivingEntity import net.minecraft.world.entity.LivingEntity
import net.minecraft.world.level.block.Block 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) { 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) ResearchIcons.ICON_SHOCKWAVE.render(stack, x, y, width, height)
if (cooldown > 0) {
RenderSystem.setShaderColor(1f, 1f, 1f, 1f)
}
} }
} }

View File

@ -2,6 +2,8 @@ package ru.dbotthepony.mc.otm.client
import com.mojang.blaze3d.platform.InputConstants import com.mojang.blaze3d.platform.InputConstants
import com.mojang.blaze3d.systems.RenderSystem 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.minecraft.client.KeyMapping
import net.minecraftforge.client.event.RegisterKeyMappingsEvent import net.minecraftforge.client.event.RegisterKeyMappingsEvent
import net.minecraftforge.client.event.RenderGuiEvent 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_DISABLED
import org.lwjgl.glfw.GLFW.GLFW_CURSOR_NORMAL import org.lwjgl.glfw.GLFW.GLFW_CURSOR_NORMAL
import ru.dbotthepony.mc.otm.OverdriveThatMatters 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.AndroidFeatureType
import ru.dbotthepony.mc.otm.android.AndroidSwitchableFeature import ru.dbotthepony.mc.otm.android.AndroidSwitchableFeature
import ru.dbotthepony.mc.otm.capability.matteryPlayer 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.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.linearInterpolation
import ru.dbotthepony.mc.otm.core.normalizeAngle
import ru.dbotthepony.mc.otm.network.MatteryPlayerNetworkChannel import ru.dbotthepony.mc.otm.network.MatteryPlayerNetworkChannel
import ru.dbotthepony.mc.otm.network.SwitchAndroidFeaturePacket import ru.dbotthepony.mc.otm.network.SwitchAndroidFeaturePacket
import java.util.stream.Collectors 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 lastRender: Long = System.nanoTime()
private var lastSelectedDegree: Double? = null private var lastSelectedDegree: Double? = null
private var lastSelectProgress = 0f private val lastSelectProgress = Object2FloatArrayMap<AndroidFeature>()
override fun setDown(isDown: Boolean) { override fun setDown(isDown: Boolean) {
val old = this.isDown val old = this.isDown
@ -63,7 +71,7 @@ object AndroidMenuKeyMapping : KeyMapping("key.otm.android_menu", KeyConflictCon
selectedFeature = null selectedFeature = null
lastSelectedFeature = null lastSelectedFeature = null
lastSelectedDegree = null lastSelectedDegree = null
lastSelectProgress = 0f lastSelectProgress.clear()
} }
} }
@ -123,34 +131,44 @@ object AndroidMenuKeyMapping : KeyMapping("key.otm.android_menu", KeyConflictCon
selectedFeature = features[index] selectedFeature = features[index]
lastSelectedFeature = 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) { if (lastSelectedDegree == null) {
this.lastSelectedDegree = index * degreePerSlice this.lastSelectedDegree = normalizeAngle(index * degreePerSlice)
} else { } else {
this.lastSelectedDegree = linearInterpolation(delta, lastSelectedDegree!!, index * degreePerSlice) this.lastSelectedDegree = lastSelectedDegree + angleDifference(index * degreePerSlice, lastSelectedDegree) * delta * 0.02
} }
} else { } else {
selectedFeature = null selectedFeature = null
lastSelectProgress = (lastSelectProgress - delta * 0.01).coerceAtLeast(0.0).toFloat()
if (lastSelectProgress == 0f) { if (!lastSelectProgress.values.any { it > 0f }) {
lastSelectedDegree = null lastSelectedDegree = null
lastSelectedFeature = null lastSelectedFeature = null
} }
} }
if (lastSelectedDegree != null) { for (key in lastSelectProgress.keys) {
RenderSystem.setShaderColor(85 / 255f, 197 / 255f, 255 / 255f, 0.3f * lastSelectProgress) 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( drawArc(
event.poseStack, event.poseStack,
minecraft.window.guiScaledWidth / 2f, minecraft.window.guiScaledWidth / 2f,
minecraft.window.guiScaledHeight / 2f, minecraft.window.guiScaledHeight / 2f,
linearInterpolation(lastSelectProgress, size, size * 1.2f), linearInterpolation(max, size, size * 1.2f),
linearInterpolation(lastSelectProgress, size * 0.3f, size * 0.4f), linearInterpolation(max, size * 0.3f, size * 0.4f),
startDegree = lastSelectedDegree!!, startDegree = lastSelectedDegree!!,
endDegree = lastSelectedDegree!! + degreePerSlice endDegree = lastSelectedDegree!! + degreePerSlice
@ -160,7 +178,7 @@ object AndroidMenuKeyMapping : KeyMapping("key.otm.android_menu", KeyConflictCon
RenderSystem.setShaderColor(1f, 1f, 1f, 1f) RenderSystem.setShaderColor(1f, 1f, 1f, 1f)
val iconSize = size * 0.25f 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.pushPose()
event.poseStack.translate(minecraft.window.guiScaledWidth.toDouble() / 2f, minecraft.window.guiScaledHeight.toDouble() / 2f, 0.0) 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) { if (features.size == 1) {
val feature = features.first() 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 { } else {
for ((index, feature) in features.withIndex()) { for ((index, feature) in features.withIndex()) {
val sin = sin((index + 0.5) * degreePerSlice).toFloat() val sin = sin((index + 0.5) * degreePerSlice).toFloat()
val cos = cos((index + 0.5) * degreePerSlice).toFloat() val cos = cos((index + 0.5) * degreePerSlice).toFloat()
if (feature == lastSelectedFeature) { val selectedShift = linearInterpolation(lastSelectProgress.getFloat(feature), size * 0.6f, size * 0.8f)
val selectedShift = linearInterpolation(lastSelectProgress, size * 0.7f, size * 0.8f) feature.renderIcon(event.poseStack, -iconSize / 2f + selectedShift * cos, -selectedShift * sin - iconSize / 2f, iconSize, iconSize)
feature.renderIcon(event.poseStack, -iconSizeSelected / 2f + selectedShift * cos, -selectedShift * sin - iconSizeSelected / 2f, iconSizeSelected, iconSizeSelected) 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)
} else {
feature.renderIcon(event.poseStack, -iconSize / 2f + size * 0.7f * cos, -size * 0.7f * sin - iconSize / 2f, iconSize, iconSize)
}
} }
} }

View File

@ -448,3 +448,25 @@ fun getEllipsoidBlockPositions(x: Int, y: Int, z: Int): List<BlockPos> {
blockShapeCache[EllipsoidShapeCacheKey(x, y, z)] = SoftReference(immutableList) blockShapeCache[EllipsoidShapeCacheKey(x, y, z)] = SoftReference(immutableList)
return 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()
}