refactor: Split waypoint classes
This commit is contained in:
37
src/main/kotlin/features/world/ColeWeightCompat.kt
Normal file
37
src/main/kotlin/features/world/ColeWeightCompat.kt
Normal file
@@ -0,0 +1,37 @@
|
|||||||
|
package moe.nea.firmament.features.world
|
||||||
|
|
||||||
|
import kotlinx.serialization.Serializable
|
||||||
|
import net.minecraft.text.Text
|
||||||
|
import moe.nea.firmament.Firmament
|
||||||
|
import moe.nea.firmament.util.ErrorUtil
|
||||||
|
|
||||||
|
object ColeWeightCompat {
|
||||||
|
@Serializable
|
||||||
|
data class ColeWeightWaypoint(
|
||||||
|
val x: Int,
|
||||||
|
val y: Int,
|
||||||
|
val z: Int,
|
||||||
|
val r: Int = 0,
|
||||||
|
val g: Int = 0,
|
||||||
|
val b: Int = 0,
|
||||||
|
)
|
||||||
|
|
||||||
|
fun intoFirm(waypoints: List<ColeWeightWaypoint>): FirmWaypoints {
|
||||||
|
val w = waypoints.map {
|
||||||
|
FirmWaypoints.Waypoint(it.x, it.y, it.z)
|
||||||
|
}
|
||||||
|
return FirmWaypoints(
|
||||||
|
"Imported Waypoints",
|
||||||
|
"imported",
|
||||||
|
null,
|
||||||
|
w.toMutableList(),
|
||||||
|
false
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
fun tryParse(string: String): Result<List<ColeWeightWaypoint>> {
|
||||||
|
return runCatching {
|
||||||
|
Firmament.tightJson.decodeFromString<List<ColeWeightWaypoint>>(string)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
28
src/main/kotlin/features/world/FirmWaypoints.kt
Normal file
28
src/main/kotlin/features/world/FirmWaypoints.kt
Normal file
@@ -0,0 +1,28 @@
|
|||||||
|
package moe.nea.firmament.features.world
|
||||||
|
|
||||||
|
import net.minecraft.util.math.BlockPos
|
||||||
|
|
||||||
|
data class FirmWaypoints(
|
||||||
|
var label: String,
|
||||||
|
var id: String,
|
||||||
|
/**
|
||||||
|
* A hint to indicate where to stand while loading the waypoints.
|
||||||
|
*/
|
||||||
|
var isRelativeTo: String?,
|
||||||
|
var waypoints: MutableList<Waypoint>,
|
||||||
|
var isOrdered: Boolean,
|
||||||
|
// TODO: val resetOnSwap: Boolean,
|
||||||
|
) {
|
||||||
|
val size get() = waypoints.size
|
||||||
|
data class Waypoint(
|
||||||
|
val x: Int,
|
||||||
|
val y: Int,
|
||||||
|
val z: Int,
|
||||||
|
) {
|
||||||
|
val blockPos get() = BlockPos(x, y, z)
|
||||||
|
|
||||||
|
companion object {
|
||||||
|
fun from(blockPos: BlockPos) = Waypoint(blockPos.x, blockPos.y, blockPos.z)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -2,21 +2,12 @@ package moe.nea.firmament.features.world
|
|||||||
|
|
||||||
import com.mojang.brigadier.arguments.IntegerArgumentType
|
import com.mojang.brigadier.arguments.IntegerArgumentType
|
||||||
import me.shedaniel.math.Color
|
import me.shedaniel.math.Color
|
||||||
import net.fabricmc.fabric.api.client.command.v2.FabricClientCommandSource
|
|
||||||
import kotlinx.serialization.Serializable
|
|
||||||
import kotlinx.serialization.encodeToString
|
|
||||||
import kotlin.collections.component1
|
|
||||||
import kotlin.collections.component2
|
|
||||||
import kotlin.collections.set
|
|
||||||
import kotlin.time.Duration.Companion.hours
|
import kotlin.time.Duration.Companion.hours
|
||||||
import kotlin.time.Duration.Companion.seconds
|
import kotlin.time.Duration.Companion.seconds
|
||||||
import net.minecraft.command.argument.BlockPosArgumentType
|
import net.minecraft.command.argument.BlockPosArgumentType
|
||||||
import net.minecraft.server.command.CommandOutput
|
|
||||||
import net.minecraft.server.command.ServerCommandSource
|
|
||||||
import net.minecraft.text.Text
|
import net.minecraft.text.Text
|
||||||
import net.minecraft.util.math.BlockPos
|
import net.minecraft.util.math.BlockPos
|
||||||
import net.minecraft.util.math.Vec3d
|
import net.minecraft.util.math.Vec3d
|
||||||
import moe.nea.firmament.Firmament
|
|
||||||
import moe.nea.firmament.annotations.Subscribe
|
import moe.nea.firmament.annotations.Subscribe
|
||||||
import moe.nea.firmament.commands.get
|
import moe.nea.firmament.commands.get
|
||||||
import moe.nea.firmament.commands.thenArgument
|
import moe.nea.firmament.commands.thenArgument
|
||||||
@@ -32,6 +23,7 @@ import moe.nea.firmament.gui.config.ManagedConfig
|
|||||||
import moe.nea.firmament.util.ClipboardUtils
|
import moe.nea.firmament.util.ClipboardUtils
|
||||||
import moe.nea.firmament.util.MC
|
import moe.nea.firmament.util.MC
|
||||||
import moe.nea.firmament.util.TimeMark
|
import moe.nea.firmament.util.TimeMark
|
||||||
|
import moe.nea.firmament.util.mc.asFakeServer
|
||||||
import moe.nea.firmament.util.render.RenderInWorldContext
|
import moe.nea.firmament.util.render.RenderInWorldContext
|
||||||
import moe.nea.firmament.util.tr
|
import moe.nea.firmament.util.tr
|
||||||
|
|
||||||
@@ -56,54 +48,35 @@ object Waypoints : FirmamentFeature {
|
|||||||
val temporaryPlayerWaypointList = mutableMapOf<String, TemporaryWaypoint>()
|
val temporaryPlayerWaypointList = mutableMapOf<String, TemporaryWaypoint>()
|
||||||
val temporaryPlayerWaypointMatcher = "(?i)x: (-?[0-9]+),? y: (-?[0-9]+),? z: (-?[0-9]+)".toPattern()
|
val temporaryPlayerWaypointMatcher = "(?i)x: (-?[0-9]+),? y: (-?[0-9]+),? z: (-?[0-9]+)".toPattern()
|
||||||
|
|
||||||
val waypoints = mutableListOf<BlockPos>()
|
var waypoints: FirmWaypoints? = null
|
||||||
var ordered = false
|
|
||||||
var orderedIndex = 0
|
var orderedIndex = 0
|
||||||
|
|
||||||
@Serializable
|
|
||||||
data class ColeWeightWaypoint(
|
|
||||||
val x: Int,
|
|
||||||
val y: Int,
|
|
||||||
val z: Int,
|
|
||||||
val r: Int = 0,
|
|
||||||
val g: Int = 0,
|
|
||||||
val b: Int = 0,
|
|
||||||
)
|
|
||||||
|
|
||||||
@Subscribe
|
@Subscribe
|
||||||
fun onRenderOrderedWaypoints(event: WorldRenderLastEvent) {
|
fun onRenderOrderedWaypoints(event: WorldRenderLastEvent) {
|
||||||
if (waypoints.isEmpty()) return
|
val w = useNonEmptyWaypoints() ?: return
|
||||||
RenderInWorldContext.renderInWorld(event) {
|
RenderInWorldContext.renderInWorld(event) {
|
||||||
if (!ordered) {
|
if (!w.isOrdered) {
|
||||||
waypoints.withIndex().forEach {
|
w.waypoints.withIndex().forEach {
|
||||||
block(it.value, 0x800050A0.toInt())
|
block(it.value.blockPos, 0x800050A0.toInt())
|
||||||
if (TConfig.showIndex)
|
if (TConfig.showIndex) withFacingThePlayer(it.value.blockPos.toCenterPos()) {
|
||||||
withFacingThePlayer(it.value.toCenterPos()) {
|
text(Text.literal(it.index.toString()))
|
||||||
text(Text.literal(it.index.toString()))
|
}
|
||||||
}
|
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
orderedIndex %= waypoints.size
|
orderedIndex %= w.waypoints.size
|
||||||
val firstColor = Color.ofRGBA(0, 200, 40, 180)
|
val firstColor = Color.ofRGBA(0, 200, 40, 180)
|
||||||
color(firstColor)
|
color(firstColor)
|
||||||
tracer(waypoints[orderedIndex].toCenterPos(), lineWidth = 3f)
|
tracer(w.waypoints[orderedIndex].blockPos.toCenterPos(), lineWidth = 3f)
|
||||||
waypoints.withIndex().toList()
|
w.waypoints.withIndex().toList().wrappingWindow(orderedIndex, 3).zip(listOf(
|
||||||
.wrappingWindow(orderedIndex, 3)
|
firstColor,
|
||||||
.zip(
|
Color.ofRGBA(180, 200, 40, 150),
|
||||||
listOf(
|
Color.ofRGBA(180, 80, 20, 140),
|
||||||
firstColor,
|
)).reversed().forEach { (waypoint, col) ->
|
||||||
Color.ofRGBA(180, 200, 40, 150),
|
|
||||||
Color.ofRGBA(180, 80, 20, 140),
|
|
||||||
)
|
|
||||||
)
|
|
||||||
.reversed()
|
|
||||||
.forEach { (waypoint, col) ->
|
|
||||||
val (index, pos) = waypoint
|
val (index, pos) = waypoint
|
||||||
block(pos, col.color)
|
block(pos.blockPos, col.color)
|
||||||
if (TConfig.showIndex)
|
if (TConfig.showIndex) withFacingThePlayer(pos.blockPos.toCenterPos()) {
|
||||||
withFacingThePlayer(pos.toCenterPos()) {
|
text(Text.literal(index.toString()))
|
||||||
text(Text.literal(index.toString()))
|
}
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -111,15 +84,17 @@ object Waypoints : FirmamentFeature {
|
|||||||
|
|
||||||
@Subscribe
|
@Subscribe
|
||||||
fun onTick(event: TickEvent) {
|
fun onTick(event: TickEvent) {
|
||||||
if (waypoints.isEmpty() || !ordered) return
|
val w = useNonEmptyWaypoints() ?: return
|
||||||
orderedIndex %= waypoints.size
|
if (!w.isOrdered) return
|
||||||
|
orderedIndex %= w.waypoints.size
|
||||||
val p = MC.player?.pos ?: return
|
val p = MC.player?.pos ?: return
|
||||||
if (TConfig.skipToNearest) {
|
if (TConfig.skipToNearest) {
|
||||||
orderedIndex =
|
orderedIndex =
|
||||||
(waypoints.withIndex().minBy { it.value.getSquaredDistance(p) }.index + 1) % waypoints.size
|
(w.waypoints.withIndex().minBy { it.value.blockPos.getSquaredDistance(p) }.index + 1) % w.waypoints.size
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
if (waypoints[orderedIndex].isWithinDistance(p, 3.0)) {
|
if (w.waypoints[orderedIndex].blockPos.isWithinDistance(p, 3.0)) {
|
||||||
orderedIndex = (orderedIndex + 1) % waypoints.size
|
orderedIndex = (orderedIndex + 1) % w.waypoints.size
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -128,57 +103,70 @@ object Waypoints : FirmamentFeature {
|
|||||||
fun onProcessChat(it: ProcessChatEvent) {
|
fun onProcessChat(it: ProcessChatEvent) {
|
||||||
val matcher = temporaryPlayerWaypointMatcher.matcher(it.unformattedString)
|
val matcher = temporaryPlayerWaypointMatcher.matcher(it.unformattedString)
|
||||||
if (it.nameHeuristic != null && TConfig.tempWaypointDuration > 0.seconds && matcher.find()) {
|
if (it.nameHeuristic != null && TConfig.tempWaypointDuration > 0.seconds && matcher.find()) {
|
||||||
temporaryPlayerWaypointList[it.nameHeuristic] = TemporaryWaypoint(
|
temporaryPlayerWaypointList[it.nameHeuristic] = TemporaryWaypoint(BlockPos(
|
||||||
BlockPos(
|
matcher.group(1).toInt(),
|
||||||
matcher.group(1).toInt(),
|
matcher.group(2).toInt(),
|
||||||
matcher.group(2).toInt(),
|
matcher.group(3).toInt(),
|
||||||
matcher.group(3).toInt(),
|
), TimeMark.now())
|
||||||
),
|
|
||||||
TimeMark.now()
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun useEditableWaypoints(): FirmWaypoints {
|
||||||
|
var w = waypoints
|
||||||
|
if (w == null) {
|
||||||
|
w = FirmWaypoints("Unlabeled", "unlabeled", null, mutableListOf(), false)
|
||||||
|
waypoints = w
|
||||||
|
}
|
||||||
|
return w
|
||||||
|
}
|
||||||
|
|
||||||
|
fun useNonEmptyWaypoints(): FirmWaypoints? {
|
||||||
|
val w = waypoints
|
||||||
|
if (w == null) return null
|
||||||
|
if (w.waypoints.isEmpty()) return null
|
||||||
|
return w
|
||||||
|
}
|
||||||
|
|
||||||
@Subscribe
|
@Subscribe
|
||||||
fun onCommand(event: CommandEvent.SubCommand) {
|
fun onCommand(event: CommandEvent.SubCommand) {
|
||||||
event.subcommand("waypoint") {
|
event.subcommand("waypoint") {
|
||||||
thenArgument("pos", BlockPosArgumentType.blockPos()) { pos ->
|
thenArgument("pos", BlockPosArgumentType.blockPos()) { pos ->
|
||||||
thenExecute {
|
thenExecute {
|
||||||
|
source
|
||||||
val position = pos.get(this).toAbsoluteBlockPos(source.asFakeServer())
|
val position = pos.get(this).toAbsoluteBlockPos(source.asFakeServer())
|
||||||
waypoints.add(position)
|
val w = useEditableWaypoints()
|
||||||
source.sendFeedback(
|
w.waypoints.add(FirmWaypoints.Waypoint.from(position))
|
||||||
Text.stringifiedTranslatable(
|
source.sendFeedback(Text.stringifiedTranslatable("firmament.command.waypoint.added",
|
||||||
"firmament.command.waypoint.added",
|
position.x,
|
||||||
position.x,
|
position.y,
|
||||||
position.y,
|
position.z))
|
||||||
position.z
|
|
||||||
)
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
event.subcommand("waypoints") {
|
event.subcommand("waypoints") {
|
||||||
thenLiteral("clear") {
|
thenLiteral("clear") {
|
||||||
thenExecute {
|
thenExecute {
|
||||||
waypoints.clear()
|
waypoints?.waypoints?.clear()
|
||||||
source.sendFeedback(Text.translatable("firmament.command.waypoint.clear"))
|
source.sendFeedback(Text.translatable("firmament.command.waypoint.clear"))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
thenLiteral("toggleordered") {
|
thenLiteral("toggleordered") {
|
||||||
thenExecute {
|
thenExecute {
|
||||||
ordered = !ordered
|
val w = useEditableWaypoints()
|
||||||
if (ordered) {
|
w.isOrdered = !w.isOrdered
|
||||||
|
if (w.isOrdered) {
|
||||||
val p = MC.player?.pos ?: Vec3d.ZERO
|
val p = MC.player?.pos ?: Vec3d.ZERO
|
||||||
orderedIndex =
|
orderedIndex = // TODO: this should be extracted to a utility method
|
||||||
waypoints.withIndex().minByOrNull { it.value.getSquaredDistance(p) }?.index ?: 0
|
w.waypoints.withIndex().minByOrNull { it.value.blockPos.getSquaredDistance(p) }?.index ?: 0
|
||||||
}
|
}
|
||||||
source.sendFeedback(Text.translatable("firmament.command.waypoint.ordered.toggle.$ordered"))
|
source.sendFeedback(Text.translatable("firmament.command.waypoint.ordered.toggle.${w.isOrdered}"))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
thenLiteral("skip") {
|
thenLiteral("skip") {
|
||||||
thenExecute {
|
thenExecute {
|
||||||
if (ordered && waypoints.isNotEmpty()) {
|
val w = useNonEmptyWaypoints()
|
||||||
orderedIndex = (orderedIndex + 1) % waypoints.size
|
if (w != null && w.isOrdered) {
|
||||||
|
orderedIndex = (orderedIndex + 1) % w.size
|
||||||
source.sendFeedback(Text.translatable("firmament.command.waypoint.skip"))
|
source.sendFeedback(Text.translatable("firmament.command.waypoint.skip"))
|
||||||
} else {
|
} else {
|
||||||
source.sendError(Text.translatable("firmament.command.waypoint.skip.error"))
|
source.sendError(Text.translatable("firmament.command.waypoint.skip.error"))
|
||||||
@@ -189,11 +177,11 @@ object Waypoints : FirmamentFeature {
|
|||||||
thenArgument("index", IntegerArgumentType.integer(0)) { indexArg ->
|
thenArgument("index", IntegerArgumentType.integer(0)) { indexArg ->
|
||||||
thenExecute {
|
thenExecute {
|
||||||
val index = get(indexArg)
|
val index = get(indexArg)
|
||||||
if (index in waypoints.indices) {
|
val w = useNonEmptyWaypoints()
|
||||||
waypoints.removeAt(index)
|
if (w != null && index in w.waypoints.indices) {
|
||||||
source.sendFeedback(Text.stringifiedTranslatable(
|
w.waypoints.removeAt(index)
|
||||||
"firmament.command.waypoint.remove",
|
source.sendFeedback(Text.stringifiedTranslatable("firmament.command.waypoint.remove",
|
||||||
index))
|
index))
|
||||||
} else {
|
} else {
|
||||||
source.sendError(Text.stringifiedTranslatable("firmament.command.waypoint.remove.error"))
|
source.sendError(Text.stringifiedTranslatable("firmament.command.waypoint.remove.error"))
|
||||||
}
|
}
|
||||||
@@ -202,47 +190,48 @@ object Waypoints : FirmamentFeature {
|
|||||||
}
|
}
|
||||||
thenLiteral("export") {
|
thenLiteral("export") {
|
||||||
thenExecute {
|
thenExecute {
|
||||||
val data = Firmament.tightJson.encodeToString<List<ColeWeightWaypoint>>(waypoints.map {
|
TODO()
|
||||||
ColeWeightWaypoint(it.x,
|
// val data = Firmament.tightJson.encodeToString<List<ColeWeightWaypoint>>(waypoints.map {
|
||||||
it.y,
|
// ColeWeightWaypoint(it.x,
|
||||||
it.z)
|
// it.y,
|
||||||
})
|
// it.z)
|
||||||
ClipboardUtils.setTextContent(data)
|
// })
|
||||||
source.sendFeedback(tr("firmament.command.waypoint.export",
|
// ClipboardUtils.setTextContent(data)
|
||||||
"Copied ${waypoints.size} waypoints to clipboard"))
|
// source.sendFeedback(tr("firmament.command.waypoint.export",
|
||||||
|
// "Copied ${waypoints.size} waypoints to clipboard"))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
thenLiteral("exportrelative") {
|
thenLiteral("exportrelative") {
|
||||||
thenExecute {
|
thenExecute {
|
||||||
val playerPos = MC.player!!.blockPos
|
TODO()
|
||||||
val x = playerPos.x
|
// val playerPos = MC.player!!.blockPos
|
||||||
val y = playerPos.y
|
// val x = playerPos.x
|
||||||
val z = playerPos.z
|
// val y = playerPos.y
|
||||||
val data = Firmament.tightJson.encodeToString<List<ColeWeightWaypoint>>(waypoints.map {
|
// val z = playerPos.z
|
||||||
ColeWeightWaypoint(it.x - x,
|
// val data = Firmament.tightJson.encodeToString<List<ColeWeightWaypoint>>(waypoints.map {
|
||||||
it.y - y,
|
// ColeWeightWaypoint(it.x - x,
|
||||||
it.z - z)
|
// it.y - y,
|
||||||
})
|
// it.z - z)
|
||||||
ClipboardUtils.setTextContent(data)
|
// })
|
||||||
source.sendFeedback(tr("firmament.command.waypoint.export.relative",
|
// ClipboardUtils.setTextContent(data)
|
||||||
"Copied ${waypoints.size} relative waypoints to clipboard. Make sure to stand in the same position when importing."))
|
// source.sendFeedback(tr("firmament.command.waypoint.export.relative",
|
||||||
|
// "Copied ${waypoints.size} relative waypoints to clipboard. Make sure to stand in the same position when importing."))
|
||||||
|
//
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
thenLiteral("import") {
|
thenLiteral("import") {
|
||||||
thenExecute {
|
thenExecute {
|
||||||
source.sendFeedback(
|
source.sendFeedback(
|
||||||
importRelative(BlockPos.ORIGIN)
|
importRelative(BlockPos.ORIGIN)// TODO: rework imports
|
||||||
?: Text.stringifiedTranslatable("firmament.command.waypoint.import", waypoints.size),
|
?: Text.stringifiedTranslatable("firmament.command.waypoint.import", useNonEmptyWaypoints()?.waypoints?.size),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
thenLiteral("importrelative") {
|
thenLiteral("importrelative") {
|
||||||
thenExecute {
|
thenExecute {
|
||||||
source.sendFeedback(
|
source.sendFeedback(
|
||||||
importRelative(MC.player!!.blockPos)
|
importRelative(MC.player!!.blockPos) ?: tr("firmament.command.waypoint.import.relative",
|
||||||
?: tr("firmament.command.waypoint.import.relative",
|
"Imported ${useNonEmptyWaypoints()?.waypoints?.size} relative waypoints from clipboard. Make sure you stand in the same position as when you exported these waypoints for them to line up correctly."),
|
||||||
"Imported ${waypoints.size} relative waypoints from clipboard. Make sure you stand in the same position as when you exported these waypoints for them to line up correctly."),
|
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -251,15 +240,10 @@ object Waypoints : FirmamentFeature {
|
|||||||
|
|
||||||
fun importRelative(pos: BlockPos): Text? {
|
fun importRelative(pos: BlockPos): Text? {
|
||||||
val contents = ClipboardUtils.getTextContents()
|
val contents = ClipboardUtils.getTextContents()
|
||||||
val data = try {
|
val cw = ColeWeightCompat.tryParse(contents).map { ColeWeightCompat.intoFirm(it) }
|
||||||
Firmament.tightJson.decodeFromString<List<ColeWeightWaypoint>>(contents)
|
waypoints = cw.getOrNull() // TODO: directly parse firm waypoints
|
||||||
} catch (ex: Exception) {
|
return null // TODO: show error if this does not work
|
||||||
Firmament.logger.error("Could not load waypoints from clipboard", ex)
|
// TODO: make relative imports work again
|
||||||
return (Text.translatable("firmament.command.waypoint.import.error"))
|
|
||||||
}
|
|
||||||
waypoints.clear()
|
|
||||||
data.mapTo(waypoints) { BlockPos(it.x + pos.x, it.y + pos.y, it.z + pos.z) }
|
|
||||||
return null
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Subscribe
|
@Subscribe
|
||||||
@@ -267,14 +251,12 @@ object Waypoints : FirmamentFeature {
|
|||||||
temporaryPlayerWaypointList.entries.removeIf { it.value.postedAt.passedTime() > TConfig.tempWaypointDuration }
|
temporaryPlayerWaypointList.entries.removeIf { it.value.postedAt.passedTime() > TConfig.tempWaypointDuration }
|
||||||
if (temporaryPlayerWaypointList.isEmpty()) return
|
if (temporaryPlayerWaypointList.isEmpty()) return
|
||||||
RenderInWorldContext.renderInWorld(event) {
|
RenderInWorldContext.renderInWorld(event) {
|
||||||
temporaryPlayerWaypointList.forEach { (player, waypoint) ->
|
temporaryPlayerWaypointList.forEach { (_, waypoint) ->
|
||||||
block(waypoint.pos, 0xFFFFFF00.toInt())
|
block(waypoint.pos, 0xFFFFFF00.toInt())
|
||||||
}
|
}
|
||||||
temporaryPlayerWaypointList.forEach { (player, waypoint) ->
|
temporaryPlayerWaypointList.forEach { (player, waypoint) ->
|
||||||
val skin =
|
val skin =
|
||||||
MC.networkHandler?.listedPlayerListEntries?.find { it.profile.name == player }
|
MC.networkHandler?.listedPlayerListEntries?.find { it.profile.name == player }?.skinTextures?.texture
|
||||||
?.skinTextures
|
|
||||||
?.texture
|
|
||||||
withFacingThePlayer(waypoint.pos.toCenterPos()) {
|
withFacingThePlayer(waypoint.pos.toCenterPos()) {
|
||||||
waypoint(waypoint.pos, Text.stringifiedTranslatable("firmament.waypoint.temporary", player))
|
waypoint(waypoint.pos, Text.stringifiedTranslatable("firmament.waypoint.temporary", player))
|
||||||
if (skin != null) {
|
if (skin != null) {
|
||||||
@@ -313,35 +295,3 @@ fun <E> List<E>.wrappingWindow(startIndex: Int, windowSize: Int): List<E> {
|
|||||||
}
|
}
|
||||||
return result
|
return result
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
fun FabricClientCommandSource.asFakeServer(): ServerCommandSource {
|
|
||||||
val source = this
|
|
||||||
return ServerCommandSource(
|
|
||||||
object : CommandOutput {
|
|
||||||
override fun sendMessage(message: Text?) {
|
|
||||||
source.player.sendMessage(message, false)
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun shouldReceiveFeedback(): Boolean {
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun shouldTrackOutput(): Boolean {
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun shouldBroadcastConsoleToOps(): Boolean {
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
},
|
|
||||||
source.position,
|
|
||||||
source.rotation,
|
|
||||||
null,
|
|
||||||
0,
|
|
||||||
"FakeServerCommandSource",
|
|
||||||
Text.literal("FakeServerCommandSource"),
|
|
||||||
null,
|
|
||||||
source.player
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|||||||
37
src/main/kotlin/util/mc/asFakeServer.kt
Normal file
37
src/main/kotlin/util/mc/asFakeServer.kt
Normal file
@@ -0,0 +1,37 @@
|
|||||||
|
package moe.nea.firmament.util.mc
|
||||||
|
|
||||||
|
import net.fabricmc.fabric.api.client.command.v2.FabricClientCommandSource
|
||||||
|
import net.minecraft.server.command.CommandOutput
|
||||||
|
import net.minecraft.server.command.ServerCommandSource
|
||||||
|
import net.minecraft.text.Text
|
||||||
|
|
||||||
|
fun FabricClientCommandSource.asFakeServer(): ServerCommandSource {
|
||||||
|
val source = this
|
||||||
|
return ServerCommandSource(
|
||||||
|
object : CommandOutput {
|
||||||
|
override fun sendMessage(message: Text?) {
|
||||||
|
source.player.sendMessage(message, false)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun shouldReceiveFeedback(): Boolean {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun shouldTrackOutput(): Boolean {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun shouldBroadcastConsoleToOps(): Boolean {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
},
|
||||||
|
source.position,
|
||||||
|
source.rotation,
|
||||||
|
null,
|
||||||
|
0,
|
||||||
|
"FakeServerCommandSource",
|
||||||
|
Text.literal("FakeServerCommandSource"),
|
||||||
|
null,
|
||||||
|
source.player
|
||||||
|
)
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user