Add /firm npcs command
This commit is contained in:
@@ -23,7 +23,7 @@ notenoughanimations = "WaI2x21x"
|
|||||||
|
|
||||||
devauth = "1.2.0"
|
devauth = "1.2.0"
|
||||||
ktor = "2.3.0"
|
ktor = "2.3.0"
|
||||||
neurepoparser = "1.4.0"
|
neurepoparser = "1.5.0"
|
||||||
hotswap_agent = "1.4.2-SNAPSHOT"
|
hotswap_agent = "1.4.2-SNAPSHOT"
|
||||||
mixinextras = "0.3.5"
|
mixinextras = "0.3.5"
|
||||||
jarvis = "1.1.3"
|
jarvis = "1.1.3"
|
||||||
|
|||||||
@@ -112,6 +112,7 @@ object Firmament {
|
|||||||
|
|
||||||
@JvmStatic
|
@JvmStatic
|
||||||
fun onClientInitialize() {
|
fun onClientInitialize() {
|
||||||
|
FeatureManager.subscribeEvents()
|
||||||
var tick = 0
|
var tick = 0
|
||||||
ClientTickEvents.END_CLIENT_TICK.register(ClientTickEvents.EndTick { instance ->
|
ClientTickEvents.END_CLIENT_TICK.register(ClientTickEvents.EndTick { instance ->
|
||||||
TickEvent.publish(TickEvent(tick++))
|
TickEvent.publish(TickEvent(tick++))
|
||||||
|
|||||||
@@ -0,0 +1,7 @@
|
|||||||
|
package moe.nea.firmament.events
|
||||||
|
|
||||||
|
import io.github.moulberry.repo.NEURepository
|
||||||
|
|
||||||
|
data class ReloadRegistrationEvent(val repo: NEURepository) : FirmamentEvent() {
|
||||||
|
companion object : FirmamentEventBus<ReloadRegistrationEvent>()
|
||||||
|
}
|
||||||
@@ -87,13 +87,12 @@ object FeatureManager : DataHolder<FeatureManager.Config>(serializer(), "feature
|
|||||||
loadFeature(DebugView)
|
loadFeature(DebugView)
|
||||||
}
|
}
|
||||||
allFeatures.forEach { it.config }
|
allFeatures.forEach { it.config }
|
||||||
subscribeEvents()
|
|
||||||
FeaturesInitializedEvent.publish(FeaturesInitializedEvent(allFeatures.toList()))
|
FeaturesInitializedEvent.publish(FeaturesInitializedEvent(allFeatures.toList()))
|
||||||
hasAutoloaded = true
|
hasAutoloaded = true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun subscribeEvents() {
|
fun subscribeEvents() {
|
||||||
AllSubscriptions.provideSubscriptions {
|
AllSubscriptions.provideSubscriptions {
|
||||||
subscribeSingleEvent(it)
|
subscribeSingleEvent(it)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,40 @@
|
|||||||
|
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))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,22 @@
|
|||||||
|
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)
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,121 @@
|
|||||||
|
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()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,68 @@
|
|||||||
|
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)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -18,8 +18,9 @@ import io.github.notenoughupdates.moulconfig.observer.GetSetter
|
|||||||
open class FirmButtonComponent(
|
open class FirmButtonComponent(
|
||||||
child: GuiComponent,
|
child: GuiComponent,
|
||||||
val isEnabled: GetSetter<Boolean> = GetSetter.constant(true),
|
val isEnabled: GetSetter<Boolean> = GetSetter.constant(true),
|
||||||
|
val noBackground: Boolean = false,
|
||||||
val action: Runnable,
|
val action: Runnable,
|
||||||
) : PanelComponent(child) {
|
) : PanelComponent(child, if (noBackground) 0 else 2, DefaultBackgroundRenderer.TRANSPARENT) {
|
||||||
|
|
||||||
/* TODO: make use of vanillas built in nine slicer */
|
/* TODO: make use of vanillas built in nine slicer */
|
||||||
val hoveredBg =
|
val hoveredBg =
|
||||||
@@ -44,7 +45,6 @@ open class FirmButtonComponent(
|
|||||||
.cornerUv(5 / 200F, 5 / 20F)
|
.cornerUv(5 / 200F, 5 / 20F)
|
||||||
.mode(NinePatch.Mode.STRETCHING)
|
.mode(NinePatch.Mode.STRETCHING)
|
||||||
.build()
|
.build()
|
||||||
|
|
||||||
var isClicking = false
|
var isClicking = false
|
||||||
override fun mouseEvent(mouseEvent: MouseEvent, context: GuiImmediateContext): Boolean {
|
override fun mouseEvent(mouseEvent: MouseEvent, context: GuiImmediateContext): Boolean {
|
||||||
if (!isEnabled.get()) return false
|
if (!isEnabled.get()) return false
|
||||||
@@ -54,12 +54,14 @@ open class FirmButtonComponent(
|
|||||||
if (context.isHovered) {
|
if (context.isHovered) {
|
||||||
action.run()
|
action.run()
|
||||||
}
|
}
|
||||||
|
blur()
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (!context.isHovered) return false
|
if (!context.isHovered) return false
|
||||||
if (mouseEvent !is MouseEvent.Click) return false
|
if (mouseEvent !is MouseEvent.Click) return false
|
||||||
if (mouseEvent.mouseState && mouseEvent.mouseButton == 0) {
|
if (mouseEvent.mouseState && mouseEvent.mouseButton == 0) {
|
||||||
|
requestFocus()
|
||||||
isClicking = true
|
isClicking = true
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
@@ -73,10 +75,11 @@ open class FirmButtonComponent(
|
|||||||
|
|
||||||
override fun render(context: GuiImmediateContext) {
|
override fun render(context: GuiImmediateContext) {
|
||||||
context.renderContext.pushMatrix()
|
context.renderContext.pushMatrix()
|
||||||
context.renderContext.drawNinePatch(
|
if (!noBackground)
|
||||||
getBackground(context),
|
context.renderContext.drawNinePatch(
|
||||||
0f, 0f, context.width, context.height
|
getBackground(context),
|
||||||
)
|
0f, 0f, context.width, context.height
|
||||||
|
)
|
||||||
context.renderContext.translate(insets.toFloat(), insets.toFloat(), 0f)
|
context.renderContext.translate(insets.toFloat(), insets.toFloat(), 0f)
|
||||||
element.render(getChildContext(context))
|
element.render(getChildContext(context))
|
||||||
context.renderContext.popMatrix()
|
context.renderContext.popMatrix()
|
||||||
|
|||||||
59
src/main/kotlin/moe/nea/firmament/gui/FirmHoverComponent.kt
Normal file
59
src/main/kotlin/moe/nea/firmament/gui/FirmHoverComponent.kt
Normal file
@@ -0,0 +1,59 @@
|
|||||||
|
package moe.nea.firmament.gui
|
||||||
|
|
||||||
|
import io.github.notenoughupdates.moulconfig.gui.GuiComponent
|
||||||
|
import io.github.notenoughupdates.moulconfig.gui.GuiImmediateContext
|
||||||
|
import io.github.notenoughupdates.moulconfig.gui.KeyboardEvent
|
||||||
|
import io.github.notenoughupdates.moulconfig.gui.MouseEvent
|
||||||
|
import java.util.function.BiFunction
|
||||||
|
import java.util.function.Supplier
|
||||||
|
import kotlin.time.Duration
|
||||||
|
import moe.nea.firmament.util.TimeMark
|
||||||
|
|
||||||
|
class FirmHoverComponent(
|
||||||
|
val child: GuiComponent,
|
||||||
|
val hoverLines: Supplier<List<String>>,
|
||||||
|
val hoverDelay: Duration,
|
||||||
|
) : GuiComponent() {
|
||||||
|
override fun getWidth(): Int {
|
||||||
|
return child.width
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun getHeight(): Int {
|
||||||
|
return child.height
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun <T : Any?> foldChildren(
|
||||||
|
initial: T,
|
||||||
|
visitor: BiFunction<GuiComponent, T, T>
|
||||||
|
): T {
|
||||||
|
return visitor.apply(child, initial)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun render(context: GuiImmediateContext) {
|
||||||
|
if (context.isHovered && (permaHover || lastMouseMove.passedTime() > hoverDelay)) {
|
||||||
|
context.renderContext.scheduleDrawTooltip(hoverLines.get())
|
||||||
|
permaHover = true
|
||||||
|
} else {
|
||||||
|
permaHover = false
|
||||||
|
}
|
||||||
|
if (!context.isHovered) {
|
||||||
|
lastMouseMove = TimeMark.now()
|
||||||
|
}
|
||||||
|
child.render(context)
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
var permaHover = false
|
||||||
|
var lastMouseMove = TimeMark.farPast()
|
||||||
|
|
||||||
|
override fun mouseEvent(mouseEvent: MouseEvent, context: GuiImmediateContext): Boolean {
|
||||||
|
if (mouseEvent is MouseEvent.Move) {
|
||||||
|
lastMouseMove = TimeMark.now()
|
||||||
|
}
|
||||||
|
return child.mouseEvent(mouseEvent, context)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun keyboardEvent(event: KeyboardEvent, context: GuiImmediateContext): Boolean {
|
||||||
|
return child.keyboardEvent(event, context)
|
||||||
|
}
|
||||||
|
}
|
||||||
33
src/main/kotlin/moe/nea/firmament/gui/ImageComponent.kt
Normal file
33
src/main/kotlin/moe/nea/firmament/gui/ImageComponent.kt
Normal file
@@ -0,0 +1,33 @@
|
|||||||
|
package moe.nea.firmament.gui
|
||||||
|
|
||||||
|
import io.github.notenoughupdates.moulconfig.common.MyResourceLocation
|
||||||
|
import io.github.notenoughupdates.moulconfig.gui.GuiComponent
|
||||||
|
import io.github.notenoughupdates.moulconfig.gui.GuiImmediateContext
|
||||||
|
import java.util.function.Supplier
|
||||||
|
|
||||||
|
class ImageComponent(
|
||||||
|
private val width: Int,
|
||||||
|
private val height: Int,
|
||||||
|
val resourceLocation: Supplier<MyResourceLocation>,
|
||||||
|
val u1: Float,
|
||||||
|
val u2: Float,
|
||||||
|
val v1: Float,
|
||||||
|
val v2: Float,
|
||||||
|
) : GuiComponent() {
|
||||||
|
override fun getWidth(): Int {
|
||||||
|
return width
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun getHeight(): Int {
|
||||||
|
return height
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun render(context: GuiImmediateContext) {
|
||||||
|
context.renderContext.bindTexture(resourceLocation.get())
|
||||||
|
context.renderContext.drawTexturedRect(
|
||||||
|
0f, 0f,
|
||||||
|
context.width.toFloat(), context.height.toFloat(),
|
||||||
|
u1, v1, u2, v2
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
18
src/main/kotlin/moe/nea/firmament/gui/TickComponent.kt
Normal file
18
src/main/kotlin/moe/nea/firmament/gui/TickComponent.kt
Normal file
@@ -0,0 +1,18 @@
|
|||||||
|
package moe.nea.firmament.gui
|
||||||
|
|
||||||
|
import io.github.notenoughupdates.moulconfig.gui.GuiComponent
|
||||||
|
import io.github.notenoughupdates.moulconfig.gui.GuiImmediateContext
|
||||||
|
|
||||||
|
class TickComponent(val onTick: Runnable) : GuiComponent() {
|
||||||
|
override fun getWidth(): Int {
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun getHeight(): Int {
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun render(context: GuiImmediateContext) {
|
||||||
|
onTick.run()
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -47,8 +47,7 @@ data class SavedKeyBinding(
|
|||||||
|| InputUtil.isKeyPressed(h, GLFW.GLFW_KEY_RIGHT_SUPER)
|
|| InputUtil.isKeyPressed(h, GLFW.GLFW_KEY_RIGHT_SUPER)
|
||||||
} else InputUtil.isKeyPressed(h, GLFW.GLFW_KEY_LEFT_CONTROL)
|
} else InputUtil.isKeyPressed(h, GLFW.GLFW_KEY_LEFT_CONTROL)
|
||||||
|| InputUtil.isKeyPressed(h, GLFW.GLFW_KEY_RIGHT_CONTROL)
|
|| InputUtil.isKeyPressed(h, GLFW.GLFW_KEY_RIGHT_CONTROL)
|
||||||
val shift = InputUtil.isKeyPressed(h, GLFW.GLFW_KEY_LEFT_SHIFT)
|
val shift = isShiftDown()
|
||||||
|| InputUtil.isKeyPressed(h, GLFW.GLFW_KEY_RIGHT_SHIFT)
|
|
||||||
val alt = InputUtil.isKeyPressed(h, GLFW.GLFW_KEY_LEFT_ALT)
|
val alt = InputUtil.isKeyPressed(h, GLFW.GLFW_KEY_LEFT_ALT)
|
||||||
|| InputUtil.isKeyPressed(h, GLFW.GLFW_KEY_RIGHT_ALT)
|
|| InputUtil.isKeyPressed(h, GLFW.GLFW_KEY_RIGHT_ALT)
|
||||||
var mods = 0
|
var mods = 0
|
||||||
@@ -57,6 +56,11 @@ data class SavedKeyBinding(
|
|||||||
if (alt) mods = mods or GLFW.GLFW_MOD_ALT
|
if (alt) mods = mods or GLFW.GLFW_MOD_ALT
|
||||||
return mods
|
return mods
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private val h get() = MC.window.handle
|
||||||
|
fun isShiftDown() = InputUtil.isKeyPressed(h, GLFW.GLFW_KEY_LEFT_SHIFT)
|
||||||
|
|| InputUtil.isKeyPressed(h, GLFW.GLFW_KEY_RIGHT_SHIFT)
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fun isPressed(atLeast: Boolean = false): Boolean {
|
fun isPressed(atLeast: Boolean = false): Boolean {
|
||||||
@@ -69,8 +73,7 @@ data class SavedKeyBinding(
|
|||||||
|| InputUtil.isKeyPressed(h, GLFW.GLFW_KEY_RIGHT_SUPER)
|
|| InputUtil.isKeyPressed(h, GLFW.GLFW_KEY_RIGHT_SUPER)
|
||||||
} else InputUtil.isKeyPressed(h, GLFW.GLFW_KEY_LEFT_CONTROL)
|
} else InputUtil.isKeyPressed(h, GLFW.GLFW_KEY_LEFT_CONTROL)
|
||||||
|| InputUtil.isKeyPressed(h, GLFW.GLFW_KEY_RIGHT_CONTROL)
|
|| InputUtil.isKeyPressed(h, GLFW.GLFW_KEY_RIGHT_CONTROL)
|
||||||
val shift = InputUtil.isKeyPressed(h, GLFW.GLFW_KEY_LEFT_SHIFT)
|
val shift = isShiftDown()
|
||||||
|| InputUtil.isKeyPressed(h, GLFW.GLFW_KEY_RIGHT_SHIFT)
|
|
||||||
val alt = InputUtil.isKeyPressed(h, GLFW.GLFW_KEY_LEFT_ALT)
|
val alt = InputUtil.isKeyPressed(h, GLFW.GLFW_KEY_LEFT_ALT)
|
||||||
|| InputUtil.isKeyPressed(h, GLFW.GLFW_KEY_RIGHT_ALT)
|
|| InputUtil.isKeyPressed(h, GLFW.GLFW_KEY_RIGHT_ALT)
|
||||||
if (atLeast)
|
if (atLeast)
|
||||||
|
|||||||
@@ -7,7 +7,6 @@
|
|||||||
|
|
||||||
package moe.nea.firmament.repo
|
package moe.nea.firmament.repo
|
||||||
|
|
||||||
import io.github.moulberry.repo.NEURecipeCache
|
|
||||||
import io.github.moulberry.repo.NEURepository
|
import io.github.moulberry.repo.NEURepository
|
||||||
import io.github.moulberry.repo.NEURepositoryException
|
import io.github.moulberry.repo.NEURepositoryException
|
||||||
import io.github.moulberry.repo.data.NEUItem
|
import io.github.moulberry.repo.data.NEUItem
|
||||||
@@ -20,6 +19,7 @@ import net.minecraft.network.packet.s2c.play.SynchronizeRecipesS2CPacket
|
|||||||
import net.minecraft.text.Text
|
import net.minecraft.text.Text
|
||||||
import moe.nea.firmament.Firmament
|
import moe.nea.firmament.Firmament
|
||||||
import moe.nea.firmament.Firmament.logger
|
import moe.nea.firmament.Firmament.logger
|
||||||
|
import moe.nea.firmament.events.ReloadRegistrationEvent
|
||||||
import moe.nea.firmament.gui.config.ManagedConfig
|
import moe.nea.firmament.gui.config.ManagedConfig
|
||||||
import moe.nea.firmament.rei.PetData
|
import moe.nea.firmament.rei.PetData
|
||||||
import moe.nea.firmament.util.MinecraftDispatcher
|
import moe.nea.firmament.util.MinecraftDispatcher
|
||||||
@@ -57,6 +57,7 @@ object RepoManager {
|
|||||||
registerReloadListener(ItemCache)
|
registerReloadListener(ItemCache)
|
||||||
registerReloadListener(ExpLadders)
|
registerReloadListener(ExpLadders)
|
||||||
registerReloadListener(ItemNameLookup)
|
registerReloadListener(ItemNameLookup)
|
||||||
|
ReloadRegistrationEvent.publish(ReloadRegistrationEvent(this))
|
||||||
registerReloadListener {
|
registerReloadListener {
|
||||||
Firmament.coroutineScope.launch(MinecraftDispatcher) {
|
Firmament.coroutineScope.launch(MinecraftDispatcher) {
|
||||||
if (!trySendClientboundUpdateRecipesPacket()) {
|
if (!trySendClientboundUpdateRecipesPacket()) {
|
||||||
@@ -69,9 +70,10 @@ object RepoManager {
|
|||||||
|
|
||||||
val essenceRecipeProvider = EssenceRecipeProvider()
|
val essenceRecipeProvider = EssenceRecipeProvider()
|
||||||
val recipeCache = BetterRepoRecipeCache(essenceRecipeProvider)
|
val recipeCache = BetterRepoRecipeCache(essenceRecipeProvider)
|
||||||
|
|
||||||
init {
|
init {
|
||||||
neuRepo.registerReloadListener(essenceRecipeProvider)
|
neuRepo.registerReloadListener(essenceRecipeProvider)
|
||||||
neuRepo.registerReloadListener(recipeCache)
|
neuRepo.registerReloadListener(recipeCache)
|
||||||
}
|
}
|
||||||
|
|
||||||
fun getAllRecipes() = neuRepo.items.items.values.asSequence().flatMap { it.recipes }
|
fun getAllRecipes() = neuRepo.items.items.values.asSequence().flatMap { it.recipes }
|
||||||
@@ -110,7 +112,9 @@ object RepoManager {
|
|||||||
|
|
||||||
fun reload() {
|
fun reload() {
|
||||||
try {
|
try {
|
||||||
ItemCache.ReloadProgressHud.reportProgress("Reloading from Disk", 0, -1) // TODO: replace with a proper boundy bar
|
ItemCache.ReloadProgressHud.reportProgress("Reloading from Disk",
|
||||||
|
0,
|
||||||
|
-1) // TODO: replace with a proper boundy bar
|
||||||
ItemCache.ReloadProgressHud.isEnabled = true
|
ItemCache.ReloadProgressHud.isEnabled = true
|
||||||
neuRepo.reload()
|
neuRepo.reload()
|
||||||
} catch (exc: NEURepositoryException) {
|
} catch (exc: NEURepositoryException) {
|
||||||
|
|||||||
@@ -18,13 +18,19 @@ import io.github.notenoughupdates.moulconfig.xml.XMLGuiLoader
|
|||||||
import io.github.notenoughupdates.moulconfig.xml.XMLUniverse
|
import io.github.notenoughupdates.moulconfig.xml.XMLUniverse
|
||||||
import io.github.notenoughupdates.moulconfig.xml.XSDGenerator
|
import io.github.notenoughupdates.moulconfig.xml.XSDGenerator
|
||||||
import java.io.File
|
import java.io.File
|
||||||
|
import java.util.function.Supplier
|
||||||
import javax.xml.namespace.QName
|
import javax.xml.namespace.QName
|
||||||
import me.shedaniel.math.Color
|
import me.shedaniel.math.Color
|
||||||
import org.w3c.dom.Element
|
import org.w3c.dom.Element
|
||||||
|
import kotlin.time.Duration
|
||||||
|
import kotlin.time.Duration.Companion.seconds
|
||||||
import net.minecraft.client.gui.screen.Screen
|
import net.minecraft.client.gui.screen.Screen
|
||||||
import moe.nea.firmament.gui.BarComponent
|
import moe.nea.firmament.gui.BarComponent
|
||||||
import moe.nea.firmament.gui.FirmButtonComponent
|
import moe.nea.firmament.gui.FirmButtonComponent
|
||||||
|
import moe.nea.firmament.gui.FirmHoverComponent
|
||||||
import moe.nea.firmament.gui.FixedComponent
|
import moe.nea.firmament.gui.FixedComponent
|
||||||
|
import moe.nea.firmament.gui.ImageComponent
|
||||||
|
import moe.nea.firmament.gui.TickComponent
|
||||||
|
|
||||||
object MoulConfigUtils {
|
object MoulConfigUtils {
|
||||||
val firmUrl = "http://firmament.nea.moe/moulconfig"
|
val firmUrl = "http://firmament.nea.moe/moulconfig"
|
||||||
@@ -69,6 +75,31 @@ object MoulConfigUtils {
|
|||||||
return mapOf("progress" to true, "total" to true, "emptyColor" to true, "fillColor" to true)
|
return mapOf("progress" to true, "total" to true, "emptyColor" to true, "fillColor" to true)
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
uni.registerLoader(object : XMLGuiLoader.Basic<FirmHoverComponent> {
|
||||||
|
override fun createInstance(context: XMLContext<*>, element: Element): FirmHoverComponent {
|
||||||
|
return FirmHoverComponent(
|
||||||
|
context.getChildFragment(element),
|
||||||
|
context.getPropertyFromAttribute(element, QName("lines"), List::class.java) as Supplier<List<String>>,
|
||||||
|
context.getPropertyFromAttribute(element, QName("delay"), Duration::class.java, 0.6.seconds),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun getName(): QName {
|
||||||
|
return QName(firmUrl, "Hover")
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun getChildCount(): ChildCount {
|
||||||
|
return ChildCount.ONE
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun getAttributeNames(): Map<String, Boolean> {
|
||||||
|
return mapOf(
|
||||||
|
"lines" to true,
|
||||||
|
"delay" to false,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
})
|
||||||
uni.registerLoader(object : XMLGuiLoader.Basic<FirmButtonComponent> {
|
uni.registerLoader(object : XMLGuiLoader.Basic<FirmButtonComponent> {
|
||||||
override fun getName(): QName {
|
override fun getName(): QName {
|
||||||
return QName(firmUrl, "Button")
|
return QName(firmUrl, "Button")
|
||||||
@@ -79,6 +110,7 @@ object MoulConfigUtils {
|
|||||||
context.getChildFragment(element),
|
context.getChildFragment(element),
|
||||||
context.getPropertyFromAttribute(element, QName("enabled"), Boolean::class.java)
|
context.getPropertyFromAttribute(element, QName("enabled"), Boolean::class.java)
|
||||||
?: GetSetter.constant(true),
|
?: GetSetter.constant(true),
|
||||||
|
context.getPropertyFromAttribute(element, QName("noBackground"), Boolean::class.java, false),
|
||||||
context.getMethodFromAttribute(element, QName("onClick")),
|
context.getMethodFromAttribute(element, QName("onClick")),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
@@ -88,7 +120,56 @@ object MoulConfigUtils {
|
|||||||
}
|
}
|
||||||
|
|
||||||
override fun getAttributeNames(): Map<String, Boolean> {
|
override fun getAttributeNames(): Map<String, Boolean> {
|
||||||
return mapOf("onClick" to true, "enabled" to false)
|
return mapOf("onClick" to true, "enabled" to false, "noBackground" to false)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
uni.registerLoader(object : XMLGuiLoader.Basic<ImageComponent> {
|
||||||
|
override fun createInstance(context: XMLContext<*>, element: Element): ImageComponent {
|
||||||
|
return ImageComponent(
|
||||||
|
context.getPropertyFromAttribute(element, QName("width"), Int::class.java)!!.get(),
|
||||||
|
context.getPropertyFromAttribute(element, QName("height"), Int::class.java)!!.get(),
|
||||||
|
context.getPropertyFromAttribute(element, QName("resource"), MyResourceLocation::class.java)!!,
|
||||||
|
context.getPropertyFromAttribute(element, QName("u1"), Float::class.java, 0f),
|
||||||
|
context.getPropertyFromAttribute(element, QName("u2"), Float::class.java, 1f),
|
||||||
|
context.getPropertyFromAttribute(element, QName("v1"), Float::class.java, 0f),
|
||||||
|
context.getPropertyFromAttribute(element, QName("v2"), Float::class.java, 1f),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun getName(): QName {
|
||||||
|
return QName(firmUrl, "Image")
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun getChildCount(): ChildCount {
|
||||||
|
return ChildCount.NONE
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun getAttributeNames(): Map<String, Boolean> {
|
||||||
|
return mapOf(
|
||||||
|
"width" to true, "height" to true,
|
||||||
|
"resource" to true,
|
||||||
|
"u1" to false,
|
||||||
|
"u2" to false,
|
||||||
|
"v1" to false,
|
||||||
|
"v2" to false,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
uni.registerLoader(object : XMLGuiLoader.Basic<TickComponent> {
|
||||||
|
override fun createInstance(context: XMLContext<*>, element: Element): TickComponent {
|
||||||
|
return TickComponent(context.getMethodFromAttribute(element, QName("tick")))
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun getName(): QName {
|
||||||
|
return QName(firmUrl, "Tick")
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun getChildCount(): ChildCount {
|
||||||
|
return ChildCount.NONE
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun getAttributeNames(): Map<String, Boolean> {
|
||||||
|
return mapOf("tick" to true)
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
uni.registerLoader(object : XMLGuiLoader.Basic<FixedComponent> {
|
uni.registerLoader(object : XMLGuiLoader.Basic<FixedComponent> {
|
||||||
|
|||||||
@@ -31,8 +31,8 @@ object WarpUtil {
|
|||||||
private var lastAttemptedWarp = ""
|
private var lastAttemptedWarp = ""
|
||||||
private var lastWarpAttempt = TimeMark.farPast()
|
private var lastWarpAttempt = TimeMark.farPast()
|
||||||
fun findNearestWarp(island: SkyBlockIsland, pos: Position): Islands.Warp? {
|
fun findNearestWarp(island: SkyBlockIsland, pos: Position): Islands.Warp? {
|
||||||
return warps.minByOrNull {
|
return warps.asSequence().filter { it.mode == island.locrawMode }.minByOrNull {
|
||||||
if (island.locrawMode != it.mode || (DConfig.data?.excludedWarps?.contains(it.warp) == true)) {
|
if (DConfig.data?.excludedWarps?.contains(it.warp) == true) {
|
||||||
return@minByOrNull Double.MAX_VALUE
|
return@minByOrNull Double.MAX_VALUE
|
||||||
} else {
|
} else {
|
||||||
return@minByOrNull squaredDist(pos, it)
|
return@minByOrNull squaredDist(pos, it)
|
||||||
@@ -48,8 +48,11 @@ object WarpUtil {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fun teleportToNearestWarp(island: SkyBlockIsland, pos: Position) {
|
fun teleportToNearestWarp(island: SkyBlockIsland, pos: Position) {
|
||||||
val nearestWarp = findNearestWarp(island, pos) ?: return
|
val nearestWarp = findNearestWarp(island, pos)
|
||||||
|
if (nearestWarp == null) {
|
||||||
|
MC.sendChat(Text.literal("Could not find an unlocked warp in ${island.userFriendlyName}"))
|
||||||
|
return
|
||||||
|
}
|
||||||
if (island == SBData.skyblockLocation
|
if (island == SBData.skyblockLocation
|
||||||
&& sqrt(squaredDist(pos, nearestWarp)) > 1.1 * sqrt(squaredDist((MC.player ?: return).pos, nearestWarp))
|
&& sqrt(squaredDist(pos, nearestWarp)) > 1.1 * sqrt(squaredDist((MC.player ?: return).pos, nearestWarp))
|
||||||
) {
|
) {
|
||||||
|
|||||||
@@ -37,7 +37,8 @@ class FacingThePlayerContext(val worldContext: RenderInWorldContext) {
|
|||||||
|
|
||||||
fun text(
|
fun text(
|
||||||
vararg texts: Text,
|
vararg texts: Text,
|
||||||
verticalAlign: RenderInWorldContext.VerticalAlign = RenderInWorldContext.VerticalAlign.CENTER
|
verticalAlign: RenderInWorldContext.VerticalAlign = RenderInWorldContext.VerticalAlign.CENTER,
|
||||||
|
background: Int = 0x70808080,
|
||||||
) {
|
) {
|
||||||
assertTrueOr(texts.isNotEmpty()) { return@text }
|
assertTrueOr(texts.isNotEmpty()) { return@text }
|
||||||
for ((index, text) in texts.withIndex()) {
|
for ((index, text) in texts.withIndex()) {
|
||||||
@@ -47,14 +48,14 @@ class FacingThePlayerContext(val worldContext: RenderInWorldContext) {
|
|||||||
val vertexConsumer: VertexConsumer =
|
val vertexConsumer: VertexConsumer =
|
||||||
worldContext.vertexConsumers.getBuffer(RenderLayer.getTextBackgroundSeeThrough())
|
worldContext.vertexConsumers.getBuffer(RenderLayer.getTextBackgroundSeeThrough())
|
||||||
val matrix4f = worldContext.matrixStack.peek().positionMatrix
|
val matrix4f = worldContext.matrixStack.peek().positionMatrix
|
||||||
vertexConsumer.vertex(matrix4f, -1.0f, -1.0f, 0.0f).color(0x70808080)
|
vertexConsumer.vertex(matrix4f, -1.0f, -1.0f, 0.0f).color(background)
|
||||||
.light(LightmapTextureManager.MAX_BLOCK_LIGHT_COORDINATE).next()
|
.light(LightmapTextureManager.MAX_BLOCK_LIGHT_COORDINATE).next()
|
||||||
vertexConsumer.vertex(matrix4f, -1.0f, MC.font.fontHeight.toFloat(), 0.0f).color(0x70808080)
|
vertexConsumer.vertex(matrix4f, -1.0f, MC.font.fontHeight.toFloat(), 0.0f).color(background)
|
||||||
.light(LightmapTextureManager.MAX_BLOCK_LIGHT_COORDINATE).next()
|
.light(LightmapTextureManager.MAX_BLOCK_LIGHT_COORDINATE).next()
|
||||||
vertexConsumer.vertex(matrix4f, width.toFloat(), MC.font.fontHeight.toFloat(), 0.0f)
|
vertexConsumer.vertex(matrix4f, width.toFloat(), MC.font.fontHeight.toFloat(), 0.0f)
|
||||||
.color(0x70808080)
|
.color(background)
|
||||||
.light(LightmapTextureManager.MAX_BLOCK_LIGHT_COORDINATE).next()
|
.light(LightmapTextureManager.MAX_BLOCK_LIGHT_COORDINATE).next()
|
||||||
vertexConsumer.vertex(matrix4f, width.toFloat(), -1.0f, 0.0f).color(0x70808080)
|
vertexConsumer.vertex(matrix4f, width.toFloat(), -1.0f, 0.0f).color(background)
|
||||||
.light(LightmapTextureManager.MAX_BLOCK_LIGHT_COORDINATE).next()
|
.light(LightmapTextureManager.MAX_BLOCK_LIGHT_COORDINATE).next()
|
||||||
worldContext.matrixStack.translate(0F, 0F, 0.01F)
|
worldContext.matrixStack.translate(0F, 0F, 0.01F)
|
||||||
|
|
||||||
|
|||||||
@@ -83,11 +83,12 @@ class RenderInWorldContext private constructor(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fun waypoint(position: BlockPos, label: Text) {
|
fun waypoint(position: BlockPos, vararg label: Text) {
|
||||||
text(
|
text(
|
||||||
position.toCenterPos(),
|
position.toCenterPos(),
|
||||||
label,
|
*label,
|
||||||
Text.literal("§e${FirmFormatters.formatDistance(MC.player?.pos?.distanceTo(position.toCenterPos()) ?: 42069.0)}")
|
Text.literal("§e${FirmFormatters.formatDistance(MC.player?.pos?.distanceTo(position.toCenterPos()) ?: 42069.0)}"),
|
||||||
|
background = 0xAA202020.toInt()
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -123,9 +124,9 @@ class RenderInWorldContext private constructor(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fun text(position: Vec3d, vararg texts: Text, verticalAlign: VerticalAlign = VerticalAlign.CENTER) {
|
fun text(position: Vec3d, vararg texts: Text, verticalAlign: VerticalAlign = VerticalAlign.CENTER, background: Int = 0x70808080) {
|
||||||
withFacingThePlayer(position) {
|
withFacingThePlayer(position) {
|
||||||
text(*texts, verticalAlign = verticalAlign)
|
text(*texts, verticalAlign = verticalAlign, background = background)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
42
src/main/resources/assets/firmament/gui/npc_waypoints.xml
Normal file
42
src/main/resources/assets/firmament/gui/npc_waypoints.xml
Normal file
@@ -0,0 +1,42 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8" ?>
|
||||||
|
|
||||||
|
<!--
|
||||||
|
SPDX-FileCopyrightText: 2023 Linnea Gräf <nea@nea.moe>
|
||||||
|
|
||||||
|
SPDX-License-Identifier: GPL-3.0-or-later
|
||||||
|
-->
|
||||||
|
|
||||||
|
<Root xmlns="http://notenoughupdates.org/moulconfig" xmlns:firm="http://firmament.nea.moe/moulconfig">
|
||||||
|
<Center>
|
||||||
|
<Panel background="VANILLA" insets="5">
|
||||||
|
<Column>
|
||||||
|
<Center>
|
||||||
|
<TextField value="@search" width="200"/>
|
||||||
|
</Center>
|
||||||
|
<firm:Tick tick="@tick"/>
|
||||||
|
<Spacer height="5"/>
|
||||||
|
<Panel background="TRANSPARENT" insets="4">
|
||||||
|
<ScrollPanel width="200" height="300">
|
||||||
|
<Array data="@results">
|
||||||
|
<Row>
|
||||||
|
<Text text="@name" width="180"/>
|
||||||
|
<firm:Hover lines="Click to set this waypoint as your destination;Shift-Click to warp to the nearest warp point and set this as your destination">
|
||||||
|
<firm:Button onClick="@click" noBackground="true">
|
||||||
|
<When condition="@isSelected">
|
||||||
|
<firm:Image resource="firmament:textures/gui/waypoint_selected.png"
|
||||||
|
width="16"
|
||||||
|
height="16"/>
|
||||||
|
<firm:Image resource="firmament:textures/gui/waypoint_unselected.png"
|
||||||
|
width="16"
|
||||||
|
height="16"/>
|
||||||
|
</When>
|
||||||
|
</firm:Button>
|
||||||
|
</firm:Hover>
|
||||||
|
</Row>
|
||||||
|
</Array>
|
||||||
|
</ScrollPanel>
|
||||||
|
</Panel>
|
||||||
|
</Column>
|
||||||
|
</Panel>
|
||||||
|
</Center>
|
||||||
|
</Root>
|
||||||
Binary file not shown.
|
After Width: | Height: | Size: 225 B |
Binary file not shown.
|
After Width: | Height: | Size: 217 B |
Reference in New Issue
Block a user