package moe.nea.firmament.features.world import kotlin.compareTo import kotlin.text.clear import kotlin.time.Duration.Companion.seconds import net.minecraft.text.Text import net.minecraft.util.math.BlockPos import moe.nea.firmament.annotations.Subscribe import moe.nea.firmament.events.ProcessChatEvent import moe.nea.firmament.events.WorldReadyEvent import moe.nea.firmament.events.WorldRenderLastEvent import moe.nea.firmament.features.world.Waypoints.TConfig import moe.nea.firmament.util.MC import moe.nea.firmament.util.TimeMark import moe.nea.firmament.util.render.RenderInWorldContext object TemporaryWaypoints { data class TemporaryWaypoint( val pos: BlockPos, val postedAt: TimeMark, ) val temporaryPlayerWaypointList = mutableMapOf() val temporaryPlayerWaypointMatcher = "(?i)x: (-?[0-9]+),? y: (-?[0-9]+),? z: (-?[0-9]+)".toPattern() @Subscribe fun onProcessChat(it: ProcessChatEvent) { val matcher = temporaryPlayerWaypointMatcher.matcher(it.unformattedString) if (it.nameHeuristic != null && TConfig.tempWaypointDuration > 0.seconds && matcher.find()) { temporaryPlayerWaypointList[it.nameHeuristic] = TemporaryWaypoint(BlockPos( matcher.group(1).toInt(), matcher.group(2).toInt(), matcher.group(3).toInt(), ), TimeMark.now()) } } @Subscribe fun onRenderTemporaryWaypoints(event: WorldRenderLastEvent) { temporaryPlayerWaypointList.entries.removeIf { it.value.postedAt.passedTime() > TConfig.tempWaypointDuration } if (temporaryPlayerWaypointList.isEmpty()) return RenderInWorldContext.renderInWorld(event) { temporaryPlayerWaypointList.forEach { (_, waypoint) -> block(waypoint.pos, 0xFFFFFF00.toInt()) } temporaryPlayerWaypointList.forEach { (player, waypoint) -> val skin = MC.networkHandler?.listedPlayerListEntries?.find { it.profile.name == player }?.skinTextures?.texture withFacingThePlayer(waypoint.pos.toCenterPos()) { waypoint(waypoint.pos, Text.stringifiedTranslatable("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, ) } } } } } @Subscribe fun onWorldReady(event: WorldReadyEvent) { temporaryPlayerWaypointList.clear() } }