aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorLinnea Gräf <nea@nea.moe>2023-11-12 14:45:05 +0100
committerLinnea Gräf <nea@nea.moe>2023-11-12 14:45:05 +0100
commit2c9c38868345d5e133179597936f8e584075b8de (patch)
treea055cd6224d71058821558db33296a4900068216 /src
parent897ab0f06b06e4c14eab31a1bf45365671471c8c (diff)
downloadfirmament-2c9c38868345d5e133179597936f8e584075b8de.tar.gz
firmament-2c9c38868345d5e133179597936f8e584075b8de.tar.bz2
firmament-2c9c38868345d5e133179597936f8e584075b8de.zip
Add temporary waypoints and /firm sendcoords
Diffstat (limited to 'src')
-rw-r--r--src/main/java/moe/nea/firmament/mixins/accessor/AccessorGameRenderer.java18
-rw-r--r--src/main/kotlin/moe/nea/firmament/commands/rome.kt11
-rw-r--r--src/main/kotlin/moe/nea/firmament/events/ProcessChatEvent.kt9
-rw-r--r--src/main/kotlin/moe/nea/firmament/features/FeatureManager.kt2
-rw-r--r--src/main/kotlin/moe/nea/firmament/features/world/Waypoints.kt72
-rw-r--r--src/main/kotlin/moe/nea/firmament/util/FirmFormatters.kt6
-rw-r--r--src/main/kotlin/moe/nea/firmament/util/MC.kt4
-rw-r--r--src/main/kotlin/moe/nea/firmament/util/render/RenderInWorldContext.kt30
-rw-r--r--src/main/resources/assets/firmament/lang/en_us.json5
9 files changed, 151 insertions, 6 deletions
diff --git a/src/main/java/moe/nea/firmament/mixins/accessor/AccessorGameRenderer.java b/src/main/java/moe/nea/firmament/mixins/accessor/AccessorGameRenderer.java
new file mode 100644
index 0000000..1137142
--- /dev/null
+++ b/src/main/java/moe/nea/firmament/mixins/accessor/AccessorGameRenderer.java
@@ -0,0 +1,18 @@
+/*
+ * SPDX-FileCopyrightText: 2023 Linnea Gräf <nea@nea.moe>
+ *
+ * SPDX-License-Identifier: GPL-3.0-or-later
+ */
+
+package moe.nea.firmament.mixins.accessor;
+
+import net.minecraft.client.render.Camera;
+import net.minecraft.client.render.GameRenderer;
+import org.spongepowered.asm.mixin.Mixin;
+import org.spongepowered.asm.mixin.gen.Invoker;
+
+@Mixin(GameRenderer.class)
+public interface AccessorGameRenderer {
+ @Invoker("getFov")
+ double getFov_firmament(Camera camera, float tickDelta, boolean changingFov);
+}
diff --git a/src/main/kotlin/moe/nea/firmament/commands/rome.kt b/src/main/kotlin/moe/nea/firmament/commands/rome.kt
index f4c20bd..b175d4b 100644
--- a/src/main/kotlin/moe/nea/firmament/commands/rome.kt
+++ b/src/main/kotlin/moe/nea/firmament/commands/rome.kt
@@ -36,8 +36,9 @@ fun firmamentCommand() = literal("firmament") {
}
thenArgument("property", string()) { property ->
suggestsList {
- (AllConfigsGui.allConfigs.find { it.name == this[config] }?:return@suggestsList listOf())
- .allOptions.entries.asSequence().filter { it.value.handler is BooleanHandler }.map { it.key }
+ (AllConfigsGui.allConfigs.find { it.name == this[config] } ?: return@suggestsList listOf())
+ .allOptions.entries.asSequence().filter { it.value.handler is BooleanHandler }
+ .map { it.key }
.asIterable()
}
thenExecute {
@@ -89,6 +90,12 @@ fun firmamentCommand() = literal("firmament") {
InventoryButtons.openEditor()
}
}
+ thenLiteral("sendcoords") {
+ thenExecute {
+ val p = MC.player ?: return@thenExecute
+ MC.sendServerChat("x: ${p.blockX}, y: ${p.blockY}, z: ${p.blockZ}")
+ }
+ }
thenLiteral("storage") {
thenExecute {
ScreenUtil.setScreenLater(StorageOverlayScreen())
diff --git a/src/main/kotlin/moe/nea/firmament/events/ProcessChatEvent.kt b/src/main/kotlin/moe/nea/firmament/events/ProcessChatEvent.kt
index 413c209..b1b66b0 100644
--- a/src/main/kotlin/moe/nea/firmament/events/ProcessChatEvent.kt
+++ b/src/main/kotlin/moe/nea/firmament/events/ProcessChatEvent.kt
@@ -6,8 +6,8 @@
package moe.nea.firmament.events
-import moe.nea.firmament.util.unformattedString
import net.minecraft.text.Text
+import moe.nea.firmament.util.unformattedString
/**
* Behaves like [AllowChatEvent], but is triggered even when cancelled by other mods. Intended for data collection.
@@ -16,6 +16,13 @@ import net.minecraft.text.Text
data class ProcessChatEvent(val text: Text, val wasExternallyCancelled: Boolean) : FirmamentEvent.Cancellable() {
val unformattedString = text.unformattedString
+ val nameHeuristic: String? = run {
+ val firstColon = unformattedString.indexOf(':')
+ if (firstColon < 0) return@run null
+ val firstSpace = unformattedString.lastIndexOf(' ', firstColon)
+ unformattedString.substring(firstSpace + 1 until firstColon).takeIf { it.isNotEmpty() }
+ }
+
init {
if (wasExternallyCancelled)
cancelled = true
diff --git a/src/main/kotlin/moe/nea/firmament/features/FeatureManager.kt b/src/main/kotlin/moe/nea/firmament/features/FeatureManager.kt
index 4888f54..30036b7 100644
--- a/src/main/kotlin/moe/nea/firmament/features/FeatureManager.kt
+++ b/src/main/kotlin/moe/nea/firmament/features/FeatureManager.kt
@@ -27,6 +27,7 @@ import moe.nea.firmament.features.inventory.buttons.InventoryButtons
import moe.nea.firmament.features.inventory.storageoverlay.StorageOverlay
import moe.nea.firmament.features.texturepack.CustomSkyBlockTextures
import moe.nea.firmament.features.world.FairySouls
+import moe.nea.firmament.features.world.Waypoints
import moe.nea.firmament.util.data.DataHolder
object FeatureManager : DataHolder<FeatureManager.Config>(serializer(), "features", ::Config) {
@@ -56,6 +57,7 @@ object FeatureManager : DataHolder<FeatureManager.Config>(serializer(), "feature
loadFeature(StorageOverlay)
loadFeature(CraftingOverlay)
loadFeature(PowerUserTools)
+ loadFeature(Waypoints)
loadFeature(ChatLinks)
loadFeature(InventoryButtons)
loadFeature(CompatibliltyFeatures)
diff --git a/src/main/kotlin/moe/nea/firmament/features/world/Waypoints.kt b/src/main/kotlin/moe/nea/firmament/features/world/Waypoints.kt
new file mode 100644
index 0000000..de25a37
--- /dev/null
+++ b/src/main/kotlin/moe/nea/firmament/features/world/Waypoints.kt
@@ -0,0 +1,72 @@
+/*
+ * SPDX-FileCopyrightText: 2023 Linnea Gräf <nea@nea.moe>
+ *
+ * SPDX-License-Identifier: GPL-3.0-or-later
+ */
+
+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.math.BlockPos
+import moe.nea.firmament.events.ProcessChatEvent
+import moe.nea.firmament.events.WorldReadyEvent
+import moe.nea.firmament.events.WorldRenderLastEvent
+import moe.nea.firmament.features.FirmamentFeature
+import moe.nea.firmament.gui.config.ManagedConfig
+import moe.nea.firmament.util.TimeMark
+import moe.nea.firmament.util.render.RenderInWorldContext
+
+object Waypoints : FirmamentFeature {
+ override val identifier: String
+ get() = "waypoints"
+
+ object TConfig : ManagedConfig(identifier) {
+ val tempWaypointDuration by duration("temp-waypoint-duration", 0.seconds, 1.hours) { 30.seconds }
+ }
+
+ data class TemporaryWaypoint(
+ val pos: BlockPos,
+ val postedAt: TimeMark,
+ )
+
+ override val config get() = TConfig
+
+ val temporaryWaypointList = mutableMapOf<String, TemporaryWaypoint>()
+ val temporaryWaypointMatcher = "x: (-?[0-9]+),? y: (-?[0-9]+),? z: (-?[0-9]+)".toPattern()
+ override fun onLoad() {
+ WorldRenderLastEvent.subscribe {
+ temporaryWaypointList.entries.removeIf { it.value.postedAt.passedTime() > TConfig.tempWaypointDuration }
+ if (temporaryWaypointList.isNotEmpty())
+ RenderInWorldContext.renderInWorld(it) {
+ 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))
+ }
+ }
+ }
+ WorldReadyEvent.subscribe {
+ temporaryWaypointList.clear()
+ }
+ 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()
+ )
+ )
+ }
+ }
+ }
+}
diff --git a/src/main/kotlin/moe/nea/firmament/util/FirmFormatters.kt b/src/main/kotlin/moe/nea/firmament/util/FirmFormatters.kt
index 96a4389..c07f53d 100644
--- a/src/main/kotlin/moe/nea/firmament/util/FirmFormatters.kt
+++ b/src/main/kotlin/moe/nea/firmament/util/FirmFormatters.kt
@@ -28,6 +28,12 @@ object FirmFormatters {
return formatCurrency(long) + (if (digits.isEmpty()) "" else ".$digits")
}
+ fun formatDistance(distance: Double): String {
+ if (distance < 10)
+ return "%.1fm".format(distance)
+ return "%dm".format(distance.toInt())
+ }
+
fun formatTimespan(duration: Duration): String {
return duration.toString()
}
diff --git a/src/main/kotlin/moe/nea/firmament/util/MC.kt b/src/main/kotlin/moe/nea/firmament/util/MC.kt
index 347a15e..f3fc754 100644
--- a/src/main/kotlin/moe/nea/firmament/util/MC.kt
+++ b/src/main/kotlin/moe/nea/firmament/util/MC.kt
@@ -51,6 +51,10 @@ object MC {
)
}
+ fun sendServerChat(text: String) {
+ player?.networkHandler?.sendChatMessage(text)
+ }
+
fun sendCommand(command: String) {
player?.networkHandler?.sendCommand(command)
}
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 f636529..aa54979 100644
--- a/src/main/kotlin/moe/nea/firmament/util/render/RenderInWorldContext.kt
+++ b/src/main/kotlin/moe/nea/firmament/util/render/RenderInWorldContext.kt
@@ -8,8 +8,10 @@ package moe.nea.firmament.util.render
import com.mojang.blaze3d.systems.RenderSystem
import java.lang.Math.pow
+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
@@ -28,6 +30,8 @@ import net.minecraft.text.Text
import net.minecraft.util.math.BlockPos
import net.minecraft.util.math.Vec3d
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
@@ -35,9 +39,12 @@ class RenderInWorldContext private constructor(
private val tesselator: Tessellator,
private val matrixStack: MatrixStack,
private val camera: Camera,
+ private val tickDelta: Float,
private val vertexConsumers: VertexConsumerProvider.Immediate,
) {
private val buffer = tesselator.buffer
+ val effectiveFov = (MC.instance.gameRenderer as AccessorGameRenderer).getFov_firmament(camera, tickDelta, true)
+ val effectiveFovScaleFactor = 1 / tan(toRadians(effectiveFov) / 2)
fun color(red: Float, green: Float, blue: Float, alpha: Float) {
RenderSystem.setShaderColor(red, green, blue, alpha)
@@ -65,15 +72,24 @@ class RenderInWorldContext private constructor(
}
fun waypoint(position: BlockPos, label: Text) {
- text(position.toCenterPos(), label, Text.literal("§e${MC.player?.pos?.distanceTo(position.toCenterPos())}m"))
+ text(
+ position.toCenterPos(),
+ label,
+ Text.literal("§e${FirmFormatters.formatDistance(MC.player?.pos?.distanceTo(position.toCenterPos()) ?: 42069.0)}")
+ )
}
fun text(position: Vec3d, vararg texts: Text, verticalAlign: VerticalAlign = VerticalAlign.CENTER) {
assertTrueOr(texts.isNotEmpty()) { return@text }
matrixStack.push()
matrixStack.translate(position.x, position.y, position.z)
+ val actualCameraDistance = position.distanceTo(camera.pos)
+ val distanceToMoveTowardsCamera = if (actualCameraDistance < 10) 0.0 else -(actualCameraDistance - 10.0)
+ val vec = position.subtract(camera.pos).multiply(distanceToMoveTowardsCamera / actualCameraDistance)
+ matrixStack.translate(vec.x, vec.y, vec.z)
matrixStack.multiply(camera.rotation)
matrixStack.scale(-0.025F, -0.025F, -1F)
+
for ((index, text) in texts.withIndex()) {
matrixStack.push()
val width = MC.font.getWidth(text)
@@ -145,7 +161,16 @@ class RenderInWorldContext private constructor(
}
companion object {
- private fun doLine(matrix: Entry, buf: BufferBuilder, i: Number, j: Number, k: Number, x: Number, y: Number, z: Number) {
+ private fun doLine(
+ matrix: Entry,
+ buf: BufferBuilder,
+ i: Number,
+ j: Number,
+ k: Number,
+ x: Number,
+ y: Number,
+ z: Number
+ ) {
val normal = Vector3f(x.toFloat(), y.toFloat(), z.toFloat())
.sub(i.toFloat(), j.toFloat(), k.toFloat())
.mul(-1F)
@@ -226,6 +251,7 @@ class RenderInWorldContext private constructor(
RenderSystem.renderThreadTesselator(),
event.matrices,
event.camera,
+ event.tickDelta,
event.vertexConsumers
)
diff --git a/src/main/resources/assets/firmament/lang/en_us.json b/src/main/resources/assets/firmament/lang/en_us.json
index 4d00d4d..8ae1300 100644
--- a/src/main/resources/assets/firmament/lang/en_us.json
+++ b/src/main/resources/assets/firmament/lang/en_us.json
@@ -64,7 +64,10 @@
"firmament.inventory-buttons.save-preset": "Save Preset",
"firmament.inventory-buttons.load-preset": "Load Preset",
"firmament.inventory-buttons.import-failed": "One of your buttons could only be imported partially",
- "firmament.config.inventory-buttons": "One of your buttons could only be imported partially",
+ "firmament.config.inventory-buttons": "Inventory buttons",
+ "firmament.waypoint.temporary": "Temporary Waypoint: %s",
+ "firmament.config.waypoints": "Waypoints",
+ "firmament.config.waypoints.temp-waypoint-duration": "Temporary Waypoint Duration",
"firmament.recipe.forge.time": "Forging Time: %s",
"firmament.pv.skills": "Skills",
"firmament.pv.skills.farming": "Farming",