diff options
Diffstat (limited to 'src/main/kotlin/moe/nea/firmament')
4 files changed, 152 insertions, 75 deletions
diff --git a/src/main/kotlin/moe/nea/firmament/features/world/Waypoints.kt b/src/main/kotlin/moe/nea/firmament/features/world/Waypoints.kt index f3bea4e..00cbc10 100644 --- a/src/main/kotlin/moe/nea/firmament/features/world/Waypoints.kt +++ b/src/main/kotlin/moe/nea/firmament/features/world/Waypoints.kt @@ -9,7 +9,6 @@ package moe.nea.firmament.features.world import kotlin.time.Duration.Companion.hours import kotlin.time.Duration.Companion.seconds import net.minecraft.text.Text -import net.minecraft.util.Identifier import net.minecraft.util.math.BlockPos import moe.nea.firmament.events.ProcessChatEvent import moe.nea.firmament.events.WorldReadyEvent @@ -36,19 +35,40 @@ object Waypoints : FirmamentFeature { override val config get() = TConfig val temporaryWaypointList = mutableMapOf<String, TemporaryWaypoint>() - val temporaryWaypointMatcher = "x: (-?[0-9]+),? y: (-?[0-9]+),? z: (-?[0-9]+)".toPattern() + val temporaryWaypointMatcher = "(?i)x: (-?[0-9]+),? y: (-?[0-9]+),? z: (-?[0-9]+)".toPattern() override fun onLoad() { - WorldRenderLastEvent.subscribe { + WorldRenderLastEvent.subscribe { event -> temporaryWaypointList.entries.removeIf { it.value.postedAt.passedTime() > TConfig.tempWaypointDuration } if (temporaryWaypointList.isNotEmpty()) - RenderInWorldContext.renderInWorld(it) { + RenderInWorldContext.renderInWorld(event) { color(1f, 1f, 0f, 1f) temporaryWaypointList.forEach { (player, waypoint) -> block(waypoint.pos) } color(1f, 1f, 1f, 1f) temporaryWaypointList.forEach { (player, waypoint) -> - waypoint(waypoint.pos, Text.translatable("firmament.waypoint.temporary", player)) + val skin = + MC.networkHandler?.listedPlayerListEntries?.find { it.profile.name == player } + ?.skinTextures + ?.texture + withFacingThePlayer(waypoint.pos.toCenterPos()) { + waypoint(waypoint.pos, Text.translatable("firmament.waypoint.temporary", player)) + if (skin != null) { + matrixStack.translate(0F, -20F, 0F) + // Head front + texture( + skin, 16, 16, + 1 / 8f, 1 / 8f, + 2 / 8f, 2 / 8f, + ) + // Head overlay + texture( + skin, 16, 16, + 5 / 8f, 1 / 8f, + 6 / 8f, 2 / 8f, + ) + } + } } } } @@ -58,15 +78,13 @@ object Waypoints : FirmamentFeature { ProcessChatEvent.subscribe { val matcher = temporaryWaypointMatcher.matcher(it.unformattedString) if (it.nameHeuristic != null && TConfig.tempWaypointDuration > 0.seconds && matcher.find()) { - temporaryWaypointList.put( - it.nameHeuristic, TemporaryWaypoint( - BlockPos( - matcher.group(1).toInt(), - matcher.group(2).toInt(), - matcher.group(3).toInt(), - ), - TimeMark.now() - ) + temporaryWaypointList[it.nameHeuristic] = TemporaryWaypoint( + BlockPos( + matcher.group(1).toInt(), + matcher.group(2).toInt(), + matcher.group(3).toInt(), + ), + TimeMark.now() ) } } diff --git a/src/main/kotlin/moe/nea/firmament/util/render/FacingThePlayerContext.kt b/src/main/kotlin/moe/nea/firmament/util/render/FacingThePlayerContext.kt new file mode 100644 index 0000000..178422d --- /dev/null +++ b/src/main/kotlin/moe/nea/firmament/util/render/FacingThePlayerContext.kt @@ -0,0 +1,102 @@ +/* + * SPDX-FileCopyrightText: 2024 Linnea Gräf <nea@nea.moe> + * + * SPDX-License-Identifier: GPL-3.0-or-later + */ + +package moe.nea.firmament.util.render + +import com.mojang.blaze3d.systems.RenderSystem +import org.joml.Matrix4f +import net.minecraft.client.font.TextRenderer +import net.minecraft.client.render.BufferRenderer +import net.minecraft.client.render.GameRenderer +import net.minecraft.client.render.LightmapTextureManager +import net.minecraft.client.render.RenderLayer +import net.minecraft.client.render.Tessellator +import net.minecraft.client.render.VertexConsumer +import net.minecraft.client.render.VertexFormat +import net.minecraft.client.render.VertexFormats +import net.minecraft.text.Text +import net.minecraft.util.Identifier +import net.minecraft.util.math.BlockPos +import moe.nea.firmament.util.FirmFormatters +import moe.nea.firmament.util.MC +import moe.nea.firmament.util.assertTrueOr + +@RenderContextDSL +class FacingThePlayerContext(val worldContext: RenderInWorldContext) { + val matrixStack by worldContext::matrixStack + fun waypoint(position: BlockPos, label: Text) { + text( + label, + Text.literal("§e${FirmFormatters.formatDistance(MC.player?.pos?.distanceTo(position.toCenterPos()) ?: 42069.0)}") + ) + } + + fun text( + vararg texts: Text, + verticalAlign: RenderInWorldContext.VerticalAlign = RenderInWorldContext.VerticalAlign.CENTER + ) { + assertTrueOr(texts.isNotEmpty()) { return@text } + for ((index, text) in texts.withIndex()) { + worldContext.matrixStack.push() + val width = MC.font.getWidth(text) + worldContext.matrixStack.translate(-width / 2F, verticalAlign.align(index, texts.size), 0F) + val vertexConsumer: VertexConsumer = + worldContext.vertexConsumers.getBuffer(RenderLayer.getTextBackgroundSeeThrough()) + val matrix4f = worldContext.matrixStack.peek().positionMatrix + vertexConsumer.vertex(matrix4f, -1.0f, -1.0f, 0.0f).color(0x70808080) + .light(LightmapTextureManager.MAX_BLOCK_LIGHT_COORDINATE).next() + vertexConsumer.vertex(matrix4f, -1.0f, MC.font.fontHeight.toFloat(), 0.0f).color(0x70808080) + .light(LightmapTextureManager.MAX_BLOCK_LIGHT_COORDINATE).next() + vertexConsumer.vertex(matrix4f, width.toFloat(), MC.font.fontHeight.toFloat(), 0.0f) + .color(0x70808080) + .light(LightmapTextureManager.MAX_BLOCK_LIGHT_COORDINATE).next() + vertexConsumer.vertex(matrix4f, width.toFloat(), -1.0f, 0.0f).color(0x70808080) + .light(LightmapTextureManager.MAX_BLOCK_LIGHT_COORDINATE).next() + worldContext.matrixStack.translate(0F, 0F, 0.01F) + + MC.font.draw( + text, + 0F, + 0F, + -1, + false, + worldContext.matrixStack.peek().positionMatrix, + worldContext.vertexConsumers, + TextRenderer.TextLayerType.SEE_THROUGH, + 0, + LightmapTextureManager.MAX_LIGHT_COORDINATE + ) + worldContext.matrixStack.pop() + } + } + + + fun texture( + texture: Identifier, width: Int, height: Int, + u1: Float, v1: Float, + u2: Float, v2: Float, + ) { + RenderSystem.setShaderTexture(0, texture) + RenderSystem.setShader(GameRenderer::getPositionColorTexProgram) + val hw = width / 2F + val hh = height / 2F + val matrix4f: Matrix4f = worldContext.matrixStack.peek().positionMatrix + val buf = Tessellator.getInstance().buffer + buf.begin(VertexFormat.DrawMode.QUADS, VertexFormats.POSITION_COLOR_TEXTURE) + buf.fixedColor(255, 255, 255, 255) + buf.vertex(matrix4f, -hw, -hh, 0F) + .texture(u1, v1).next() + buf.vertex(matrix4f, -hw, +hh, 0F) + .texture(u1, v2).next() + buf.vertex(matrix4f, +hw, +hh, 0F) + .texture(u2, v2).next() + buf.vertex(matrix4f, +hw, -hh, 0F) + .texture(u2, v1).next() + buf.unfixColor() + BufferRenderer.drawWithGlobalProgram(buf.end()) + } + +} diff --git a/src/main/kotlin/moe/nea/firmament/util/render/RenderContextDSL.kt b/src/main/kotlin/moe/nea/firmament/util/render/RenderContextDSL.kt new file mode 100644 index 0000000..f692620 --- /dev/null +++ b/src/main/kotlin/moe/nea/firmament/util/render/RenderContextDSL.kt @@ -0,0 +1,11 @@ +/* + * SPDX-FileCopyrightText: 2024 Linnea Gräf <nea@nea.moe> + * + * SPDX-License-Identifier: GPL-3.0-or-later + */ + +package moe.nea.firmament.util.render + +@DslMarker +annotation class RenderContextDSL { +} diff --git a/src/main/kotlin/moe/nea/firmament/util/render/RenderInWorldContext.kt b/src/main/kotlin/moe/nea/firmament/util/render/RenderInWorldContext.kt index a1a18c8..897fabb 100644 --- a/src/main/kotlin/moe/nea/firmament/util/render/RenderInWorldContext.kt +++ b/src/main/kotlin/moe/nea/firmament/util/render/RenderInWorldContext.kt @@ -12,16 +12,11 @@ import java.lang.Math.toRadians import org.joml.Matrix4f import org.joml.Vector3f import kotlin.math.tan -import net.minecraft.client.font.TextRenderer import net.minecraft.client.gl.VertexBuffer import net.minecraft.client.render.BufferBuilder -import net.minecraft.client.render.BufferRenderer import net.minecraft.client.render.Camera import net.minecraft.client.render.GameRenderer -import net.minecraft.client.render.LightmapTextureManager -import net.minecraft.client.render.RenderLayer import net.minecraft.client.render.Tessellator -import net.minecraft.client.render.VertexConsumer import net.minecraft.client.render.VertexConsumerProvider import net.minecraft.client.render.VertexFormat import net.minecraft.client.render.VertexFormats @@ -36,14 +31,14 @@ import moe.nea.firmament.events.WorldRenderLastEvent import moe.nea.firmament.mixins.accessor.AccessorGameRenderer import moe.nea.firmament.util.FirmFormatters import moe.nea.firmament.util.MC -import moe.nea.firmament.util.assertTrueOr +@RenderContextDSL class RenderInWorldContext private constructor( private val tesselator: Tessellator, - private val matrixStack: MatrixStack, + val matrixStack: MatrixStack, private val camera: Camera, private val tickDelta: Float, - private val vertexConsumers: VertexConsumerProvider.Immediate, + val vertexConsumers: VertexConsumerProvider.Immediate, ) { private val buffer = tesselator.buffer val effectiveFov = (MC.instance.gameRenderer as AccessorGameRenderer).getFov_firmament(camera, tickDelta, true) @@ -82,7 +77,7 @@ class RenderInWorldContext private constructor( ) } - fun withFacingThePlayer(position: Vec3d, block: () -> Unit) { + fun withFacingThePlayer(position: Vec3d, block: FacingThePlayerContext.() -> Unit) { matrixStack.push() matrixStack.translate(position.x, position.y, position.z) val actualCameraDistance = position.distanceTo(camera.pos) @@ -92,7 +87,7 @@ class RenderInWorldContext private constructor( matrixStack.multiply(camera.rotation) matrixStack.scale(-0.025F, -0.025F, -1F) - block() + FacingThePlayerContext(this).run(block) matrixStack.pop() vertexConsumers.drawCurrentLayer() @@ -110,62 +105,13 @@ class RenderInWorldContext private constructor( u2: Float, v2: Float, ) { withFacingThePlayer(position) { - RenderSystem.setShaderTexture(0, texture) - RenderSystem.setShader(GameRenderer::getPositionColorTexProgram) - val hw = width / 2F - val hh = height / 2F - val matrix4f: Matrix4f = matrixStack.peek().positionMatrix - val buf = Tessellator.getInstance().buffer - buf.begin(VertexFormat.DrawMode.QUADS, VertexFormats.POSITION_COLOR_TEXTURE) - buf.fixedColor(255, 255, 255, 255) - buf.vertex(matrix4f, -hw, -hh, 0F) - .texture(u1, v1).next() - buf.vertex(matrix4f, -hw, +hh, 0F) - .texture(u1, v2).next() - buf.vertex(matrix4f, +hw, +hh, 0F) - .texture(u2, v2).next() - buf.vertex(matrix4f, +hw, -hh, 0F) - .texture(u2, v1).next() - buf.unfixColor() - BufferRenderer.drawWithGlobalProgram(buf.end()) + texture(texture, width, height, u1, v1, u2, v2) } } fun text(position: Vec3d, vararg texts: Text, verticalAlign: VerticalAlign = VerticalAlign.CENTER) { - assertTrueOr(texts.isNotEmpty()) { return@text } withFacingThePlayer(position) { - for ((index, text) in texts.withIndex()) { - matrixStack.push() - val width = MC.font.getWidth(text) - matrixStack.translate(-width / 2F, verticalAlign.align(index, texts.size), 0F) - val vertexConsumer: VertexConsumer = - vertexConsumers.getBuffer(RenderLayer.getTextBackgroundSeeThrough()) - val matrix4f = matrixStack.peek().positionMatrix - vertexConsumer.vertex(matrix4f, -1.0f, -1.0f, 0.0f).color(0x70808080) - .light(LightmapTextureManager.MAX_BLOCK_LIGHT_COORDINATE).next() - vertexConsumer.vertex(matrix4f, -1.0f, MC.font.fontHeight.toFloat(), 0.0f).color(0x70808080) - .light(LightmapTextureManager.MAX_BLOCK_LIGHT_COORDINATE).next() - vertexConsumer.vertex(matrix4f, width.toFloat(), MC.font.fontHeight.toFloat(), 0.0f) - .color(0x70808080) - .light(LightmapTextureManager.MAX_BLOCK_LIGHT_COORDINATE).next() - vertexConsumer.vertex(matrix4f, width.toFloat(), -1.0f, 0.0f).color(0x70808080) - .light(LightmapTextureManager.MAX_BLOCK_LIGHT_COORDINATE).next() - matrixStack.translate(0F, 0F, 0.01F) - - MC.font.draw( - text, - 0F, - 0F, - -1, - false, - matrixStack.peek().positionMatrix, - vertexConsumers, - TextRenderer.TextLayerType.SEE_THROUGH, - 0, - LightmapTextureManager.MAX_LIGHT_COORDINATE - ) - matrixStack.pop() - } + text(*texts, verticalAlign = verticalAlign) } } |