aboutsummaryrefslogtreecommitdiff
path: root/src/main/kotlin/moe/nea/firmament/features/world
diff options
context:
space:
mode:
authorLinnea Gräf <nea@nea.moe>2024-08-28 19:04:24 +0200
committerLinnea Gräf <nea@nea.moe>2024-08-28 19:04:24 +0200
commitd2f240ff0ca0d27f417f837e706c781a98c31311 (patch)
tree0db7aff6cc14deaf36eed83889d59fd6b3a6f599 /src/main/kotlin/moe/nea/firmament/features/world
parenta6906308163aa3b2d18fa1dc1aa71ac9bbcc83ab (diff)
downloadFirmament-d2f240ff0ca0d27f417f837e706c781a98c31311.tar.gz
Firmament-d2f240ff0ca0d27f417f837e706c781a98c31311.tar.bz2
Firmament-d2f240ff0ca0d27f417f837e706c781a98c31311.zip
Refactor source layout
Introduce compat source sets and move all kotlin sources to the main directory [no changelog]
Diffstat (limited to 'src/main/kotlin/moe/nea/firmament/features/world')
-rw-r--r--src/main/kotlin/moe/nea/firmament/features/world/FairySouls.kt131
-rw-r--r--src/main/kotlin/moe/nea/firmament/features/world/NPCWaypoints.kt40
-rw-r--r--src/main/kotlin/moe/nea/firmament/features/world/NavigableWaypoint.kt22
-rw-r--r--src/main/kotlin/moe/nea/firmament/features/world/NavigationHelper.kt121
-rw-r--r--src/main/kotlin/moe/nea/firmament/features/world/NpcWaypointGui.kt68
-rw-r--r--src/main/kotlin/moe/nea/firmament/features/world/Waypoints.kt297
6 files changed, 0 insertions, 679 deletions
diff --git a/src/main/kotlin/moe/nea/firmament/features/world/FairySouls.kt b/src/main/kotlin/moe/nea/firmament/features/world/FairySouls.kt
deleted file mode 100644
index 8a8291a..0000000
--- a/src/main/kotlin/moe/nea/firmament/features/world/FairySouls.kt
+++ /dev/null
@@ -1,131 +0,0 @@
-
-
-package moe.nea.firmament.features.world
-
-import io.github.moulberry.repo.data.Coordinate
-import kotlinx.serialization.Serializable
-import kotlinx.serialization.serializer
-import net.minecraft.text.Text
-import net.minecraft.util.math.Vec3d
-import moe.nea.firmament.annotations.Subscribe
-import moe.nea.firmament.events.ProcessChatEvent
-import moe.nea.firmament.events.SkyblockServerUpdateEvent
-import moe.nea.firmament.events.WorldRenderLastEvent
-import moe.nea.firmament.features.FirmamentFeature
-import moe.nea.firmament.gui.config.ManagedConfig
-import moe.nea.firmament.repo.RepoManager
-import moe.nea.firmament.util.MC
-import moe.nea.firmament.util.SBData
-import moe.nea.firmament.util.SkyBlockIsland
-import moe.nea.firmament.util.blockPos
-import moe.nea.firmament.util.data.ProfileSpecificDataHolder
-import moe.nea.firmament.util.render.RenderInWorldContext
-import moe.nea.firmament.util.render.RenderInWorldContext.Companion.renderInWorld
-import moe.nea.firmament.util.unformattedString
-
-
-object FairySouls : FirmamentFeature {
-
-
- @Serializable
- data class Data(
- val foundSouls: MutableMap<SkyBlockIsland, MutableSet<Int>> = mutableMapOf()
- )
-
- override val config: ManagedConfig
- get() = TConfig
-
- object DConfig : ProfileSpecificDataHolder<Data>(serializer(), "found-fairysouls", ::Data)
-
-
- object TConfig : ManagedConfig("fairy-souls") {
- val displaySouls by toggle("show") { false }
- val resetSouls by button("reset") {
- DConfig.data?.foundSouls?.clear() != null
- updateMissingSouls()
- }
- }
-
-
- override val identifier: String get() = "fairy-souls"
-
- val playerReach = 5
- val playerReachSquared = playerReach * playerReach
-
- var currentLocationName: SkyBlockIsland? = null
- var currentLocationSouls: List<Coordinate> = emptyList()
- var currentMissingSouls: List<Coordinate> = emptyList()
-
- fun updateMissingSouls() {
- currentMissingSouls = emptyList()
- val c = DConfig.data ?: return
- val fi = c.foundSouls[currentLocationName] ?: setOf()
- val cms = currentLocationSouls.toMutableList()
- fi.asSequence().sortedDescending().filter { it in cms.indices }.forEach { cms.removeAt(it) }
- currentMissingSouls = cms
- }
-
- fun updateWorldSouls() {
- currentLocationSouls = emptyList()
- val loc = currentLocationName ?: return
- currentLocationSouls = RepoManager.neuRepo.constants.fairySouls.soulLocations[loc.locrawMode] ?: return
- }
-
- fun findNearestClickableSoul(): Coordinate? {
- val player = MC.player ?: return null
- val pos = player.pos
- val location = SBData.skyblockLocation ?: return null
- val soulLocations: List<Coordinate> =
- RepoManager.neuRepo.constants.fairySouls.soulLocations[location.locrawMode] ?: return null
- return soulLocations
- .map { it to it.blockPos.getSquaredDistance(pos) }
- .filter { it.second < playerReachSquared }
- .minByOrNull { it.second }
- ?.first
- }
-
- private fun markNearestSoul() {
- val nearestSoul = findNearestClickableSoul() ?: return
- val c = DConfig.data ?: return
- val loc = currentLocationName ?: return
- val idx = currentLocationSouls.indexOf(nearestSoul)
- c.foundSouls.computeIfAbsent(loc) { mutableSetOf() }.add(idx)
- DConfig.markDirty()
- updateMissingSouls()
- }
-
- @Subscribe
- fun onWorldRender(it: WorldRenderLastEvent) {
- if (!TConfig.displaySouls) return
- renderInWorld(it) {
- color(1F, 1F, 0F, 0.8F)
- currentMissingSouls.forEach {
- block(it.blockPos)
- }
- color(1f, 0f, 1f, 1f)
- currentLocationSouls.forEach {
- wireframeCube(it.blockPos)
- }
- }
- }
-
- @Subscribe
- fun onProcessChat(it: ProcessChatEvent) {
- when (it.text.unformattedString) {
- "You have already found that Fairy Soul!" -> {
- markNearestSoul()
- }
-
- "SOUL! You found a Fairy Soul!" -> {
- markNearestSoul()
- }
- }
- }
-
- @Subscribe
- fun onLocationChange(it: SkyblockServerUpdateEvent) {
- currentLocationName = it.newLocraw?.skyblockLocation
- updateWorldSouls()
- updateMissingSouls()
- }
-}
diff --git a/src/main/kotlin/moe/nea/firmament/features/world/NPCWaypoints.kt b/src/main/kotlin/moe/nea/firmament/features/world/NPCWaypoints.kt
deleted file mode 100644
index 592b8fa..0000000
--- a/src/main/kotlin/moe/nea/firmament/features/world/NPCWaypoints.kt
+++ /dev/null
@@ -1,40 +0,0 @@
-package moe.nea.firmament.features.world
-
-import moe.nea.firmament.annotations.Subscribe
-import moe.nea.firmament.commands.thenExecute
-import moe.nea.firmament.events.CommandEvent
-import moe.nea.firmament.events.ReloadRegistrationEvent
-import moe.nea.firmament.util.MoulConfigUtils
-import moe.nea.firmament.util.ScreenUtil
-
-object NPCWaypoints {
-
- var allNpcWaypoints = listOf<NavigableWaypoint>()
-
- @Subscribe
- fun onRepoReloadRegistration(event: ReloadRegistrationEvent) {
- event.repo.registerReloadListener {
- allNpcWaypoints = it.items.items.values
- .asSequence()
- .filter { !it.island.isNullOrBlank() }
- .map {
- NavigableWaypoint.NPCWaypoint(it)
- }
- .toList()
- }
- }
-
- @Subscribe
- fun onOpenGui(event: CommandEvent.SubCommand) {
- event.subcommand("npcs") {
- thenExecute {
- ScreenUtil.setScreenLater(MoulConfigUtils.loadScreen(
- "npc_waypoints",
- NpcWaypointGui(allNpcWaypoints),
- null))
- }
- }
- }
-
-
-}
diff --git a/src/main/kotlin/moe/nea/firmament/features/world/NavigableWaypoint.kt b/src/main/kotlin/moe/nea/firmament/features/world/NavigableWaypoint.kt
deleted file mode 100644
index 28a517f..0000000
--- a/src/main/kotlin/moe/nea/firmament/features/world/NavigableWaypoint.kt
+++ /dev/null
@@ -1,22 +0,0 @@
-package moe.nea.firmament.features.world
-
-import io.github.moulberry.repo.data.NEUItem
-import net.minecraft.util.math.BlockPos
-import moe.nea.firmament.util.SkyBlockIsland
-
-abstract class NavigableWaypoint {
- abstract val name: String
- abstract val position: BlockPos
- abstract val island: SkyBlockIsland
-
- data class NPCWaypoint(
- val item: NEUItem,
- ) : NavigableWaypoint() {
- override val name: String
- get() = item.displayName
- override val position: BlockPos
- get() = BlockPos(item.x, item.y, item.z)
- override val island: SkyBlockIsland
- get() = SkyBlockIsland.forMode(item.island)
- }
-}
diff --git a/src/main/kotlin/moe/nea/firmament/features/world/NavigationHelper.kt b/src/main/kotlin/moe/nea/firmament/features/world/NavigationHelper.kt
deleted file mode 100644
index acdfb86..0000000
--- a/src/main/kotlin/moe/nea/firmament/features/world/NavigationHelper.kt
+++ /dev/null
@@ -1,121 +0,0 @@
-package moe.nea.firmament.features.world
-
-import io.github.moulberry.repo.constants.Islands
-import net.minecraft.text.Text
-import net.minecraft.util.math.BlockPos
-import net.minecraft.util.math.Position
-import net.minecraft.util.math.Vec3i
-import moe.nea.firmament.annotations.Subscribe
-import moe.nea.firmament.events.SkyblockServerUpdateEvent
-import moe.nea.firmament.events.TickEvent
-import moe.nea.firmament.events.WorldRenderLastEvent
-import moe.nea.firmament.repo.RepoManager
-import moe.nea.firmament.util.MC
-import moe.nea.firmament.util.SBData
-import moe.nea.firmament.util.SkyBlockIsland
-import moe.nea.firmament.util.WarpUtil
-import moe.nea.firmament.util.render.RenderInWorldContext
-
-object NavigationHelper {
- var targetWaypoint: NavigableWaypoint? = null
- set(value) {
- field = value
- recalculateRoute()
- }
-
- var nextTeleporter: Islands.Teleporter? = null
- private set
-
- val Islands.Teleporter.toIsland get() = SkyBlockIsland.forMode(this.getTo())
- val Islands.Teleporter.fromIsland get() = SkyBlockIsland.forMode(this.getFrom())
- val Islands.Teleporter.blockPos get() = BlockPos(x.toInt(), y.toInt(), z.toInt())
-
- @Subscribe
- fun onWorldSwitch(event: SkyblockServerUpdateEvent) {
- recalculateRoute()
- }
-
- fun recalculateRoute() {
- val tp = targetWaypoint
- val currentIsland = SBData.skyblockLocation
- if (tp == null || currentIsland == null) {
- nextTeleporter = null
- return
- }
- val route = findRoute(currentIsland, tp.island, mutableSetOf())
- nextTeleporter = route?.get(0)
- }
-
- private fun findRoute(
- fromIsland: SkyBlockIsland,
- targetIsland: SkyBlockIsland,
- visitedIslands: MutableSet<SkyBlockIsland>
- ): MutableList<Islands.Teleporter>? {
- var shortestChain: MutableList<Islands.Teleporter>? = null
- for (it in RepoManager.neuRepo.constants.islands.teleporters) {
- if (it.toIsland in visitedIslands) continue
- if (it.fromIsland != fromIsland) continue
- if (it.toIsland == targetIsland) return mutableListOf(it)
- visitedIslands.add(fromIsland)
- val nextRoute = findRoute(it.toIsland, targetIsland, visitedIslands) ?: continue
- nextRoute.add(0, it)
- if (shortestChain == null || shortestChain.size > nextRoute.size) {
- shortestChain = nextRoute
- }
- visitedIslands.remove(fromIsland)
- }
- return shortestChain
- }
-
-
- @Subscribe
- fun onMovement(event: TickEvent) { // TODO: add a movement tick event maybe?
- val tp = targetWaypoint ?: return
- val p = MC.player ?: return
- if (p.squaredDistanceTo(tp.position.toCenterPos()) < 5 * 5) {
- targetWaypoint = null
- }
- }
-
- @Subscribe
- fun drawWaypoint(event: WorldRenderLastEvent) {
- val tp = targetWaypoint ?: return
- val nt = nextTeleporter
- RenderInWorldContext.renderInWorld(event) {
- if (nt != null) {
- waypoint(nt.blockPos,
- Text.literal("Teleporter to " + nt.toIsland.userFriendlyName),
- Text.literal("(towards " + tp.name + "§f)"))
- } else if (tp.island == SBData.skyblockLocation) {
- waypoint(tp.position,
- Text.literal(tp.name))
- }
- }
- }
-
- fun tryWarpNear() {
- val tp = targetWaypoint
- if (tp == null) {
- MC.sendChat(Text.literal("Could not find a waypoint to warp you to. Select one first."))
- return
- }
- WarpUtil.teleportToNearestWarp(tp.island, tp.position.asPositionView())
- }
-
-}
-
-fun Vec3i.asPositionView(): Position {
- return object : Position {
- override fun getX(): Double {
- return this@asPositionView.x.toDouble()
- }
-
- override fun getY(): Double {
- return this@asPositionView.y.toDouble()
- }
-
- override fun getZ(): Double {
- return this@asPositionView.z.toDouble()
- }
- }
-}
diff --git a/src/main/kotlin/moe/nea/firmament/features/world/NpcWaypointGui.kt b/src/main/kotlin/moe/nea/firmament/features/world/NpcWaypointGui.kt
deleted file mode 100644
index 6146e50..0000000
--- a/src/main/kotlin/moe/nea/firmament/features/world/NpcWaypointGui.kt
+++ /dev/null
@@ -1,68 +0,0 @@
-package moe.nea.firmament.features.world
-
-import io.github.notenoughupdates.moulconfig.observer.ObservableList
-import io.github.notenoughupdates.moulconfig.xml.Bind
-import moe.nea.firmament.features.events.anniversity.AnniversaryFeatures.atOnce
-import moe.nea.firmament.keybindings.SavedKeyBinding
-
-class NpcWaypointGui(
- val allWaypoints: List<NavigableWaypoint>,
-) {
-
- data class NavigableWaypointW(val waypoint: NavigableWaypoint) {
- @Bind
- fun name() = waypoint.name
-
- @Bind
- fun isSelected() = NavigationHelper.targetWaypoint == waypoint
-
- @Bind
- fun click() {
- if (SavedKeyBinding.isShiftDown()) {
- NavigationHelper.targetWaypoint = waypoint
- NavigationHelper.tryWarpNear()
- } else if (isSelected()) {
- NavigationHelper.targetWaypoint = null
- } else {
- NavigationHelper.targetWaypoint = waypoint
- }
- }
- }
-
- @JvmField
- @field:Bind
- var search: String = ""
- var lastSearch: String? = null
-
- @Bind("results")
- fun results(): ObservableList<NavigableWaypointW> {
- return results
- }
-
- @Bind
- fun tick() {
- if (search != lastSearch) {
- updateSearch()
- lastSearch = search
- }
- }
-
- val results: ObservableList<NavigableWaypointW> = ObservableList(mutableListOf())
-
- fun updateSearch() {
- val split = search.split(" +".toRegex())
- results.atOnce {
- results.clear()
- allWaypoints.filter { waypoint ->
- if (search.isBlank()) {
- true
- } else {
- split.all { waypoint.name.contains(it, ignoreCase = true) }
- }
- }.mapTo(results) {
- NavigableWaypointW(it)
- }
- }
- }
-
-}
diff --git a/src/main/kotlin/moe/nea/firmament/features/world/Waypoints.kt b/src/main/kotlin/moe/nea/firmament/features/world/Waypoints.kt
deleted file mode 100644
index 91a06da..0000000
--- a/src/main/kotlin/moe/nea/firmament/features/world/Waypoints.kt
+++ /dev/null
@@ -1,297 +0,0 @@
-
-
-package moe.nea.firmament.features.world
-
-import com.mojang.brigadier.arguments.IntegerArgumentType
-import me.shedaniel.math.Color
-import net.fabricmc.fabric.api.client.command.v2.FabricClientCommandSource
-import kotlinx.serialization.Serializable
-import kotlin.collections.component1
-import kotlin.collections.component2
-import kotlin.collections.set
-import kotlin.time.Duration.Companion.hours
-import kotlin.time.Duration.Companion.seconds
-import net.minecraft.command.argument.BlockPosArgumentType
-import net.minecraft.server.command.ServerCommandSource
-import net.minecraft.text.Text
-import net.minecraft.util.math.BlockPos
-import net.minecraft.util.math.Vec3d
-import moe.nea.firmament.Firmament
-import moe.nea.firmament.annotations.Subscribe
-import moe.nea.firmament.commands.get
-import moe.nea.firmament.commands.thenArgument
-import moe.nea.firmament.commands.thenExecute
-import moe.nea.firmament.commands.thenLiteral
-import moe.nea.firmament.events.CommandEvent
-import moe.nea.firmament.events.ProcessChatEvent
-import moe.nea.firmament.events.TickEvent
-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.ClipboardUtils
-import moe.nea.firmament.util.MC
-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 }
- val showIndex by toggle("show-index") { true }
- val skipToNearest by toggle("skip-to-nearest") { false }
- // TODO: look ahead size
- }
-
- data class TemporaryWaypoint(
- val pos: BlockPos,
- val postedAt: TimeMark,
- )
-
- override val config get() = TConfig
-
- val temporaryPlayerWaypointList = mutableMapOf<String, TemporaryWaypoint>()
- val temporaryPlayerWaypointMatcher = "(?i)x: (-?[0-9]+),? y: (-?[0-9]+),? z: (-?[0-9]+)".toPattern()
-
- val waypoints = mutableListOf<BlockPos>()
- var ordered = false
- 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
- fun onRenderOrderedWaypoints(event: WorldRenderLastEvent) {
- if (waypoints.isEmpty()) return
- RenderInWorldContext.renderInWorld(event) {
- if (!ordered) {
- waypoints.withIndex().forEach {
- color(0f, 0.3f, 0.7f, 0.5f)
- block(it.value)
- color(1f, 1f, 1f, 1f)
- if (TConfig.showIndex)
- withFacingThePlayer(it.value.toCenterPos()) {
- text(Text.literal(it.index.toString()))
- }
- }
- } else {
- orderedIndex %= waypoints.size
- val firstColor = Color.ofRGBA(0, 200, 40, 180)
- color(firstColor)
- tracer(waypoints[orderedIndex].toCenterPos(), lineWidth = 3f)
- waypoints.withIndex().toList()
- .wrappingWindow(orderedIndex, 3)
- .zip(
- listOf(
- firstColor,
- Color.ofRGBA(180, 200, 40, 150),
- Color.ofRGBA(180, 80, 20, 140),
- )
- )
- .reversed()
- .forEach { (waypoint, col) ->
- val (index, pos) = waypoint
- color(col)
- block(pos)
- color(1f, 1f, 1f, 1f)
- if (TConfig.showIndex)
- withFacingThePlayer(pos.toCenterPos()) {
- text(Text.literal(index.toString()))
- }
- }
- }
- }
- }
-
- @Subscribe
- fun onTick(event: TickEvent) {
- if (waypoints.isEmpty() || !ordered) return
- orderedIndex %= waypoints.size
- val p = MC.player?.pos ?: return
- if (TConfig.skipToNearest) {
- orderedIndex =
- (waypoints.withIndex().minBy { it.value.getSquaredDistance(p) }.index + 1) % waypoints.size
- } else {
- if (waypoints[orderedIndex].isWithinDistance(p, 3.0)) {
- orderedIndex = (orderedIndex + 1) % waypoints.size
- }
- }
- }
-
- @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 onCommand(event: CommandEvent.SubCommand) {
- event.subcommand("waypoint") {
- thenArgument("pos", BlockPosArgumentType.blockPos()) { pos ->
- thenExecute {
- val position = pos.get(this).toAbsoluteBlockPos(source.asFakeServer())
- waypoints.add(position)
- source.sendFeedback(
- Text.stringifiedTranslatable(
- "firmament.command.waypoint.added",
- position.x,
- position.y,
- position.z
- )
- )
- }
- }
- }
- event.subcommand("waypoints") {
- thenLiteral("clear") {
- thenExecute {
- waypoints.clear()
- source.sendFeedback(Text.translatable("firmament.command.waypoint.clear"))
- }
- }
- thenLiteral("toggleordered") {
- thenExecute {
- ordered = !ordered
- if (ordered) {
- val p = MC.player?.pos ?: Vec3d.ZERO
- orderedIndex =
- waypoints.withIndex().minByOrNull { it.value.getSquaredDistance(p) }?.index ?: 0
- }
- source.sendFeedback(Text.translatable("firmament.command.waypoint.ordered.toggle.$ordered"))
- }
- }
- thenLiteral("skip") {
- thenExecute {
- if (ordered && waypoints.isNotEmpty()) {
- orderedIndex = (orderedIndex + 1) % waypoints.size
- source.sendFeedback(Text.translatable("firmament.command.waypoint.skip"))
- } else {
- source.sendError(Text.translatable("firmament.command.waypoint.skip.error"))
- }
- }
- }
- thenLiteral("remove") {
- thenArgument("index", IntegerArgumentType.integer(0)) { indexArg ->
- thenExecute {
- val index = get(indexArg)
- if (index in waypoints.indices) {
- waypoints.removeAt(index)
- source.sendFeedback(Text.stringifiedTranslatable(
- "firmament.command.waypoint.remove",
- index))
- } else {
- source.sendError(Text.stringifiedTranslatable("firmament.command.waypoint.remove.error"))
- }
- }
- }
- }
- thenLiteral("import") {
- thenExecute {
- val contents = ClipboardUtils.getTextContents()
- val data = try {
- Firmament.json.decodeFromString<List<ColeWeightWaypoint>>(contents)
- } catch (ex: Exception) {
- Firmament.logger.error("Could not load waypoints from clipboard", ex)
- source.sendError(Text.translatable("firmament.command.waypoint.import.error"))
- return@thenExecute
- }
- waypoints.clear()
- data.mapTo(waypoints) { BlockPos(it.x, it.y, it.z) }
- source.sendFeedback(
- Text.stringifiedTranslatable(
- "firmament.command.waypoint.import",
- data.size
- )
- )
- }
- }
- }
- }
-
- @Subscribe
- fun onRenderTemporaryWaypoints(event: WorldRenderLastEvent) {
- temporaryPlayerWaypointList.entries.removeIf { it.value.postedAt.passedTime() > TConfig.tempWaypointDuration }
- if (temporaryPlayerWaypointList.isEmpty()) return
- RenderInWorldContext.renderInWorld(event) {
- color(1f, 1f, 0f, 1f)
- temporaryPlayerWaypointList.forEach { (player, waypoint) ->
- block(waypoint.pos)
- }
- color(1f, 1f, 1f, 1f)
- 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()
- }
-}
-
-fun <E> List<E>.wrappingWindow(startIndex: Int, windowSize: Int): List<E> {
- val result = ArrayList<E>(windowSize)
- if (startIndex + windowSize < size) {
- result.addAll(subList(startIndex, startIndex + windowSize))
- } else {
- result.addAll(subList(startIndex, size))
- result.addAll(subList(0, minOf(windowSize - (size - startIndex), startIndex)))
- }
- return result
-}
-
-
-fun FabricClientCommandSource.asFakeServer(): ServerCommandSource {
- val source = this
- return ServerCommandSource(
- source.player,
- source.position,
- source.rotation,
- null,
- 0,
- "FakeServerCommandSource",
- Text.literal("FakeServerCommandSource"),
- null,
- source.player
- )
-}