2025-04-22 09:22:46 -06:00

121 lines
4.0 KiB
Kotlin

package com.github.itzilly.sbt.features
import com.github.itzilly.sbt.Keybinds
import com.github.itzilly.sbt.data.NodeOptions
import com.github.itzilly.sbt.data.RouteNode
import com.github.itzilly.sbt.render.BlockOutlineRenderer
import com.github.itzilly.sbt.util.Chatterbox
import com.github.itzilly.sbt.util.SimpleChatMsg
import com.google.gson.Gson
import net.minecraft.client.Minecraft
import net.minecraft.util.BlockPos
import net.minecraftforge.client.event.RenderWorldLastEvent
import net.minecraftforge.fml.common.eventhandler.SubscribeEvent
import net.minecraftforge.fml.common.gameevent.InputEvent
import java.awt.Toolkit
import java.awt.datatransfer.Clipboard
import java.awt.datatransfer.StringSelection
import kotlin.math.round
object RouteBuilder {
private const val OFFSET: Float = 0.5f;
private const val MAX_HISTORY = 5
private var nodes: ArrayList<RouteNode> = ArrayList()
private val history = ArrayDeque<List<RouteNode>>()
private fun nodeExists(x: Int, y: Int, z: Int): Boolean {
return nodes.any { it.x == x && it.y == y && it.z == z }
}
private fun addNode(x: Int, y: Int, z: Int) {
nodes.add(RouteNode(x, y, z, 0u, 1u, 0u, NodeOptions("${nodes.size + 1}")))
}
private fun addNode(x: Int, y: Int, z: Int, r: UByte, g: UByte, b: UByte) {
nodes.add(RouteNode(x, y, z, r, g, b, NodeOptions("${nodes.size + 1}")))
}
@SubscribeEvent
fun onKeyInput(event: InputEvent.KeyInputEvent) {
if (Keybinds.addRouteNode.isPressed) {
addRouteNode()
}
if (Keybinds.removeLastNode.isPressed) {
removeLastNode()
}
if (Keybinds.finishRoute.isPressed) {
finishRoute()
}
}
@SubscribeEvent
fun renderBlockOverlay(event: RenderWorldLastEvent) {
val player = Minecraft.getMinecraft().thePlayer
for (marker: RouteNode in nodes) {
val pos = BlockPos(marker.x, marker.y, marker.z)
BlockOutlineRenderer.drawBlockOutline(player, pos, event.partialTicks)
BlockOutlineRenderer.drawBlockLine(pos, event.partialTicks)
}
}
private fun addRouteNode() {
val mc = Minecraft.getMinecraft()
val x = round(mc.thePlayer.posX - OFFSET).toInt()
val y = round(mc.thePlayer.posY).toInt() - 1 // for the block below the player
val z = round(mc.thePlayer.posZ - OFFSET).toInt()
if (nodeExists(x, y, z)) {
Chatterbox.say(SimpleChatMsg("Node already exists!").red())
} else {
addNode(x, y, z)
Chatterbox.say("This is a string")
}
}
private fun removeLastNode() {
val wasRemoved = nodes.removeLastOrNull()
if (wasRemoved == null) {
val msg = SimpleChatMsg("There isn't a node to delete!")
Chatterbox.say(msg.red())
} else {
val msg = SimpleChatMsg("Removed previous node")
Chatterbox.say(msg.green())
}
}
private fun finishRoute() {
if (nodes.size == 0) {
val msg = SimpleChatMsg("There aren't any nodes to copy!")
Chatterbox.say(msg.red())
return
}
// TODO: Make a config option to export to coleweight or the other mod (different format)
// Maybe skytils too??
saveRouteToHistory()
// TODO: Make a way to view the history in case you goof up
val jsonString = Gson().toJson(nodes)
val msg = SimpleChatMsg("String copied to clipboard!")
setClipboard(jsonString)
Chatterbox.say(msg.green())
nodes.clear()
}
private fun setClipboard(s: String) {
val selection = StringSelection(s)
val clipboard: Clipboard = Toolkit.getDefaultToolkit().systemClipboard
clipboard.setContents(selection, selection)
}
private fun saveRouteToHistory() {
history.addLast(nodes.map { it.copy() })
if (history.size > MAX_HISTORY) {
history.removeFirst()
}
}
}