Add /firm exporthotm to save hotm presets
This commit is contained in:
@@ -65,6 +65,10 @@ object Firmament {
|
||||
ignoreUnknownKeys = true
|
||||
encodeDefaults = true
|
||||
}
|
||||
val tightJson = Json(from = json) {
|
||||
prettyPrint = false
|
||||
}
|
||||
|
||||
|
||||
val httpClient by lazy {
|
||||
HttpClient {
|
||||
|
||||
@@ -3,7 +3,10 @@
|
||||
package moe.nea.firmament.events
|
||||
|
||||
import net.minecraft.client.gui.DrawContext
|
||||
import net.minecraft.client.texture.Sprite
|
||||
import net.minecraft.screen.slot.Slot
|
||||
import net.minecraft.util.Identifier
|
||||
import moe.nea.firmament.util.MC
|
||||
|
||||
interface SlotRenderEvents {
|
||||
val context: DrawContext
|
||||
@@ -12,6 +15,13 @@ interface SlotRenderEvents {
|
||||
val mouseY: Int
|
||||
val delta: Float
|
||||
|
||||
fun highlight(sprite: Sprite) {
|
||||
context.drawSprite(
|
||||
slot.x, slot.y, 0, 16, 16,
|
||||
sprite
|
||||
)
|
||||
}
|
||||
|
||||
data class Before(
|
||||
override val context: DrawContext, override val slot: Slot,
|
||||
override val mouseX: Int,
|
||||
|
||||
@@ -20,8 +20,7 @@ object CommissionFeatures {
|
||||
if (MC.screenName != "Commissions") return
|
||||
val stack = event.slot.stack
|
||||
if(stack.loreAccordingToNbt.any { it.unformattedString == "COMPLETED" }) {
|
||||
event.context.drawSprite(
|
||||
event.slot.x, event.slot.y, 0, 16, 16,
|
||||
event.highlight(
|
||||
MC.guiAtlasManager.getSprite(Identifier.of("firmament:completed_commission_background"))
|
||||
)
|
||||
}
|
||||
|
||||
241
src/main/kotlin/features/mining/HotmPresets.kt
Normal file
241
src/main/kotlin/features/mining/HotmPresets.kt
Normal file
@@ -0,0 +1,241 @@
|
||||
package moe.nea.firmament.features.mining
|
||||
|
||||
import me.shedaniel.math.Rectangle
|
||||
import kotlinx.serialization.Serializable
|
||||
import kotlin.time.Duration.Companion.seconds
|
||||
import net.minecraft.block.Blocks
|
||||
import net.minecraft.client.gui.DrawContext
|
||||
import net.minecraft.client.gui.screen.ingame.HandledScreen
|
||||
import net.minecraft.entity.player.PlayerInventory
|
||||
import net.minecraft.item.Items
|
||||
import net.minecraft.screen.GenericContainerScreenHandler
|
||||
import net.minecraft.screen.ScreenHandler
|
||||
import net.minecraft.screen.slot.Slot
|
||||
import net.minecraft.screen.slot.SlotActionType
|
||||
import net.minecraft.text.Text
|
||||
import moe.nea.firmament.Firmament
|
||||
import moe.nea.firmament.annotations.Subscribe
|
||||
import moe.nea.firmament.commands.thenExecute
|
||||
import moe.nea.firmament.events.ChestInventoryUpdateEvent
|
||||
import moe.nea.firmament.events.CommandEvent
|
||||
import moe.nea.firmament.events.ScreenChangeEvent
|
||||
import moe.nea.firmament.events.SlotRenderEvents
|
||||
import moe.nea.firmament.gui.config.ManagedConfig
|
||||
import moe.nea.firmament.mixins.accessor.AccessorHandledScreen
|
||||
import moe.nea.firmament.util.ClipboardUtils
|
||||
import moe.nea.firmament.util.MC
|
||||
import moe.nea.firmament.util.TemplateUtil
|
||||
import moe.nea.firmament.util.TimeMark
|
||||
import moe.nea.firmament.util.customgui.CustomGui
|
||||
import moe.nea.firmament.util.customgui.customGui
|
||||
import moe.nea.firmament.util.mc.CommonTextures
|
||||
import moe.nea.firmament.util.mc.displayNameAccordingToNbt
|
||||
import moe.nea.firmament.util.unformattedString
|
||||
import moe.nea.firmament.util.useMatch
|
||||
|
||||
object HotmPresets {
|
||||
object Config : ManagedConfig("hotm-presets", Category.MINING) {
|
||||
}
|
||||
|
||||
val SHARE_PREFIX = "FIRMHOTM/"
|
||||
|
||||
@Serializable
|
||||
data class HotmPreset(
|
||||
val perks: List<PerkPreset>,
|
||||
)
|
||||
|
||||
@Serializable
|
||||
data class PerkPreset(val perkName: String)
|
||||
|
||||
var hotmCommandSent = TimeMark.farPast()
|
||||
val hotmInventoryName = "Heart of the Mountain"
|
||||
|
||||
@Subscribe
|
||||
fun onScreenOpen(event: ScreenChangeEvent) {
|
||||
val title = event.new?.title?.unformattedString
|
||||
if (title != hotmInventoryName) return
|
||||
val screen = event.new as? HandledScreen<*> ?: return
|
||||
val oldHandler = (event.old as? HandledScreen<*>)?.customGui
|
||||
if (oldHandler is HotmScrollPrompt) {
|
||||
event.new.customGui = oldHandler
|
||||
oldHandler.setNewScreen(screen)
|
||||
return
|
||||
}
|
||||
if (hotmCommandSent.passedTime() > 5.seconds) return
|
||||
hotmCommandSent = TimeMark.farPast()
|
||||
screen.customGui = HotmScrollPrompt(screen)
|
||||
}
|
||||
|
||||
class HotmScrollPrompt(var screen: HandledScreen<*>) : CustomGui() {
|
||||
var bounds = Rectangle(
|
||||
0, 0, 0, 0
|
||||
)
|
||||
|
||||
fun setNewScreen(screen: HandledScreen<*>) {
|
||||
this.screen = screen
|
||||
onInit()
|
||||
hasScrolled = false
|
||||
}
|
||||
|
||||
override fun render(drawContext: DrawContext, delta: Float, mouseX: Int, mouseY: Int) {
|
||||
drawContext.drawGuiTexture(
|
||||
CommonTextures.genericWidget(),
|
||||
bounds.x, bounds.y, 0,
|
||||
bounds.width,
|
||||
bounds.height,
|
||||
)
|
||||
drawContext.drawCenteredTextWithShadow(
|
||||
MC.font,
|
||||
if (hasAll) {
|
||||
Text.translatable("firmament.hotmpreset.copied")
|
||||
} else if (!hasScrolled) {
|
||||
Text.translatable("firmament.hotmpreset.scrollprompt")
|
||||
} else {
|
||||
Text.translatable("firmament.hotmpreset.scrolled")
|
||||
},
|
||||
bounds.centerX,
|
||||
bounds.centerY - 5,
|
||||
-1
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
var hasScrolled = false
|
||||
var hasAll = false
|
||||
|
||||
fun Slot.clickMiddleMouseButton(handler: ScreenHandler) {
|
||||
MC.interactionManager?.clickSlot(
|
||||
handler.syncId,
|
||||
this.id,
|
||||
2,
|
||||
SlotActionType.CLONE,
|
||||
MC.player
|
||||
)
|
||||
}
|
||||
|
||||
fun Slot.clickRightMouseButton(handler: ScreenHandler) {
|
||||
MC.interactionManager?.clickSlot(
|
||||
handler.syncId,
|
||||
this.id,
|
||||
1,
|
||||
SlotActionType.PICKUP,
|
||||
MC.player
|
||||
)
|
||||
}
|
||||
|
||||
override fun mouseClick(mouseX: Double, mouseY: Double, button: Int): Boolean {
|
||||
if (!hasScrolled) {
|
||||
val slot = screen.screenHandler.getSlot(8)
|
||||
println("Clicking ${slot.stack}")
|
||||
slot.clickRightMouseButton(screen.screenHandler)
|
||||
}
|
||||
hasScrolled = true
|
||||
return super.mouseClick(mouseX, mouseY, button)
|
||||
}
|
||||
|
||||
override fun shouldDrawForeground(): Boolean {
|
||||
return false
|
||||
}
|
||||
|
||||
override fun getBounds(): List<Rectangle> {
|
||||
return listOf(bounds)
|
||||
}
|
||||
|
||||
override fun onInit() {
|
||||
bounds = Rectangle(
|
||||
screen.width / 2 - 150,
|
||||
screen.height / 2 - 100,
|
||||
300, 200
|
||||
)
|
||||
val screen = screen as AccessorHandledScreen
|
||||
screen.x_Firmament = bounds.x
|
||||
screen.y_Firmament = bounds.y
|
||||
screen.backgroundWidth_Firmament = bounds.width
|
||||
screen.backgroundHeight_Firmament = bounds.height
|
||||
}
|
||||
|
||||
override fun moveSlot(slot: Slot) {
|
||||
slot.x = -10000
|
||||
}
|
||||
|
||||
val coveredRows = mutableSetOf<Int>()
|
||||
val unlockedPerks = mutableSetOf<String>()
|
||||
val allRows = (1..10).toSet()
|
||||
|
||||
fun onNewItems(event: ChestInventoryUpdateEvent) {
|
||||
val handler = screen.screenHandler as? GenericContainerScreenHandler ?: return
|
||||
for (it in handler.slots) {
|
||||
if (it.inventory is PlayerInventory) continue
|
||||
val stack = it.stack
|
||||
val name = stack.displayNameAccordingToNbt.unformattedString
|
||||
tierRegex.useMatch(name) {
|
||||
coveredRows.add(group("tier").toInt())
|
||||
}
|
||||
if (stack.item == Items.DIAMOND
|
||||
|| stack.item == Items.EMERALD
|
||||
|| stack.item == Blocks.EMERALD_BLOCK.asItem()
|
||||
) {
|
||||
unlockedPerks.add(name)
|
||||
}
|
||||
}
|
||||
if (allRows == coveredRows) {
|
||||
ClipboardUtils.setTextContent(TemplateUtil.encodeTemplate(SHARE_PREFIX, HotmPreset(
|
||||
unlockedPerks.map { PerkPreset(it) }
|
||||
)))
|
||||
hasAll = true
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
val tierRegex = "Tier (?<tier>[0-9]+)".toPattern()
|
||||
var highlightedPerks: Set<String> = emptySet()
|
||||
|
||||
@Subscribe
|
||||
fun onSlotUpdates(event: ChestInventoryUpdateEvent) {
|
||||
val customGui = (event.inventory as? HandledScreen<*>)?.customGui
|
||||
if (customGui is HotmScrollPrompt) {
|
||||
customGui.onNewItems(event)
|
||||
}
|
||||
}
|
||||
|
||||
@Subscribe
|
||||
fun resetOnScreen(event: ScreenChangeEvent) {
|
||||
if (event.new != null && event.new.title.unformattedString != hotmInventoryName) {
|
||||
highlightedPerks = emptySet()
|
||||
}
|
||||
}
|
||||
|
||||
@Subscribe
|
||||
fun onSlotRender(event: SlotRenderEvents.Before) {
|
||||
if (hotmInventoryName == MC.screenName
|
||||
&& event.slot.stack.displayNameAccordingToNbt.unformattedString in highlightedPerks
|
||||
) {
|
||||
event.highlight(MC.guiAtlasManager.getSprite(Firmament.identifier("hotm_perk_preset")))
|
||||
}
|
||||
}
|
||||
|
||||
@Subscribe
|
||||
fun onCommand(event: CommandEvent.SubCommand) {
|
||||
event.subcommand("exporthotm") {
|
||||
thenExecute {
|
||||
hotmCommandSent = TimeMark.now()
|
||||
MC.sendCommand("hotm")
|
||||
source.sendFeedback(Text.translatable("firmament.hotmpreset.openinghotm"))
|
||||
}
|
||||
}
|
||||
event.subcommand("importhotm") {
|
||||
thenExecute {
|
||||
val template =
|
||||
TemplateUtil.maybeDecodeTemplate<HotmPreset>(SHARE_PREFIX, ClipboardUtils.getTextContents())
|
||||
if (template == null) {
|
||||
source.sendFeedback(Text.translatable("firmament.hotmpreset.failedimport"))
|
||||
} else {
|
||||
highlightedPerks = template.perks.mapTo(mutableSetOf()) { it.perkName }
|
||||
source.sendFeedback(Text.translatable("firmament.hotmpreset.okayimport"))
|
||||
MC.sendCommand("hotm")
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -5,6 +5,7 @@ package moe.nea.firmament.util
|
||||
import java.util.*
|
||||
import kotlinx.serialization.DeserializationStrategy
|
||||
import kotlinx.serialization.SerializationStrategy
|
||||
import kotlinx.serialization.json.Json
|
||||
import kotlinx.serialization.serializer
|
||||
import moe.nea.firmament.Firmament
|
||||
|
||||
@@ -61,7 +62,7 @@ object TemplateUtil {
|
||||
|
||||
fun <T> encodeTemplate(sharePrefix: String, data: T, serializer: SerializationStrategy<T>): String {
|
||||
require(sharePrefix.endsWith("/"))
|
||||
return intoBase64Encoded(sharePrefix + Firmament.json.encodeToString(serializer, data))
|
||||
return intoBase64Encoded(sharePrefix + Firmament.tightJson.encodeToString(serializer, data))
|
||||
}
|
||||
|
||||
inline fun <reified T : Any> maybeDecodeTemplate(sharePrefix: String, data: String): T? =
|
||||
|
||||
7
src/main/kotlin/util/mc/CommonTextures.kt
Normal file
7
src/main/kotlin/util/mc/CommonTextures.kt
Normal file
@@ -0,0 +1,7 @@
|
||||
package moe.nea.firmament.util.mc
|
||||
|
||||
import moe.nea.firmament.Firmament
|
||||
|
||||
object CommonTextures {
|
||||
fun genericWidget() = (Firmament.identifier("generic_vanilla_widget"))
|
||||
}
|
||||
@@ -94,6 +94,12 @@
|
||||
"firmament.config.category.meta": "Meta & Firmament",
|
||||
"firmament.config.category.dev": "Developer & Debug",
|
||||
"firmament.ursa.debugrequest.start": "Ursa request launched",
|
||||
"firmament.hotmpreset.openinghotm": "Opening /hotm menu for export.",
|
||||
"firmament.hotmpreset.scrollprompt": "We need to scroll! Please click anywhere to continue.",
|
||||
"firmament.hotmpreset.scrolled": "Just scrolled. Waiting on server to update items.",
|
||||
"firmament.hotmpreset.copied": "Collected all HOTM perks to clipboard. Use /firm importhotm to import.",
|
||||
"firmament.hotmpreset.okayimport": "Imported a HOTM perk preset.",
|
||||
"firmament.hotmpreset.failedimport": "Could not find a HOTM perk preset in your clipboard. You can export your current HOTM perks with /firm exporthotm",
|
||||
"firmament.ursa.debugrequest.result": "Ursa request succeeded: %s",
|
||||
"firmament.sbinfo.nolocraw": "No locraw data available",
|
||||
"firmament.sbinfo.profile": "Current profile cutename: %s",
|
||||
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 4.2 KiB |
@@ -0,0 +1,10 @@
|
||||
{
|
||||
"gui": {
|
||||
"scaling": {
|
||||
"type": "nine_slice",
|
||||
"width": 24,
|
||||
"height": 41,
|
||||
"border": 5
|
||||
}
|
||||
}
|
||||
}
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 558 B |
Reference in New Issue
Block a user