Add pet upgrade cost recipes

This commit is contained in:
Linnea Gräf
2024-07-10 19:58:51 +02:00
parent c54276ee66
commit 67cc7c22ac
10 changed files with 314 additions and 52 deletions

View File

@@ -1,10 +0,0 @@
Format: https://www.debian.org/doc/packaging-manuals/copyright-format/1.0/
Upstream-Name: Firmament
Upstream-Contact: Linnea Gräf <nea@nea.moe>
Source: https://github.com/romangraef/Firmament
# Sample paragraph, commented out:
#
# Files: src/*
# Copyright: $YEAR $NAME <$CONTACT>
# License: ...

9
REUSE.toml Normal file
View File

@@ -0,0 +1,9 @@
#SPDX-FileCopyrightText: 2024 Linnea Gräf <nea@nea.moe>
#
#SPDX-License-Identifier: CC0-1.0
version = 1
SPDX-PackageName = "Firmament"
SPDX-PackageSupplier = "Linnea Gräf <nea@nea.moe>"
SPDX-PackageDownloadLocation = "https://github.com/romangraef/Firmament"
annotations = []

View File

@@ -1,5 +1,6 @@
/* /*
* SPDX-FileCopyrightText: 2023 Linnea Gräf <nea@nea.moe> * SPDX-FileCopyrightText: 2023 Linnea Gräf <nea@nea.moe>
* SPDX-FileCopyrightText: 2024 Linnea Gräf <nea@nea.moe>
* *
* SPDX-License-Identifier: GPL-3.0-or-later * SPDX-License-Identifier: GPL-3.0-or-later
*/ */
@@ -46,7 +47,7 @@ object CraftingOverlay : FirmamentFeature {
val expectedItem = recipe.neuRecipe.inputs[recipeIndex] val expectedItem = recipe.neuRecipe.inputs[recipeIndex]
val actualStack = slot.stack ?: ItemStack.EMPTY!! val actualStack = slot.stack ?: ItemStack.EMPTY!!
val actualEntry = SBItemEntryDefinition.getEntry(actualStack).value val actualEntry = SBItemEntryDefinition.getEntry(actualStack).value
if ((actualEntry.skyblockId.neuItem != expectedItem.itemId || actualEntry.stackSize < expectedItem.amount) && expectedItem.amount.toInt() != 0) { if ((actualEntry.skyblockId.neuItem != expectedItem.itemId || actualEntry.getStackSize() < expectedItem.amount) && expectedItem.amount.toInt() != 0) {
event.context.fill( event.context.fill(
event.slot.x, event.slot.x,
event.slot.y, event.slot.y,

View File

@@ -32,6 +32,7 @@ import moe.nea.firmament.features.inventory.CraftingOverlay
import moe.nea.firmament.features.inventory.storageoverlay.StorageOverlayScreen import moe.nea.firmament.features.inventory.storageoverlay.StorageOverlayScreen
import moe.nea.firmament.rei.recipes.SBCraftingRecipe import moe.nea.firmament.rei.recipes.SBCraftingRecipe
import moe.nea.firmament.rei.recipes.SBForgeRecipe import moe.nea.firmament.rei.recipes.SBForgeRecipe
import moe.nea.firmament.rei.recipes.SBKatRecipe
import moe.nea.firmament.rei.recipes.SBMobDropRecipe import moe.nea.firmament.rei.recipes.SBMobDropRecipe
import moe.nea.firmament.repo.RepoManager import moe.nea.firmament.repo.RepoManager
import moe.nea.firmament.util.SkyblockId import moe.nea.firmament.util.SkyblockId
@@ -70,6 +71,7 @@ class FirmamentReiPlugin : REIClientPlugin {
registry.add(SBCraftingRecipe.Category) registry.add(SBCraftingRecipe.Category)
registry.add(SBForgeRecipe.Category) registry.add(SBForgeRecipe.Category)
registry.add(SBMobDropRecipe.Category) registry.add(SBMobDropRecipe.Category)
registry.add(SBKatRecipe.Category)
} }
override fun registerExclusionZones(zones: ExclusionZones) { override fun registerExclusionZones(zones: ExclusionZones) {
@@ -80,14 +82,16 @@ class FirmamentReiPlugin : REIClientPlugin {
override fun registerDisplays(registry: DisplayRegistry) { override fun registerDisplays(registry: DisplayRegistry) {
registry.registerDisplayGenerator( registry.registerDisplayGenerator(
SBCraftingRecipe.Category.catIdentifier, SBCraftingRecipe.Category.catIdentifier,
SkyblockCraftingRecipeDynamicGenerator SkyblockCraftingRecipeDynamicGenerator)
)
registry.registerDisplayGenerator( registry.registerDisplayGenerator(
SBForgeRecipe.Category.categoryIdentifier, SBForgeRecipe.Category.categoryIdentifier,
SkyblockForgeRecipeDynamicGenerator SkyblockForgeRecipeDynamicGenerator)
) registry.registerDisplayGenerator(
registry.registerDisplayGenerator(SBMobDropRecipe.Category.categoryIdentifier, SBMobDropRecipe.Category.categoryIdentifier,
SkyblockMobDropRecipeDynamicGenerator) SkyblockMobDropRecipeDynamicGenerator)
registry.registerDisplayGenerator(
SBKatRecipe.Category.categoryIdentifier,
SkyblockKatRecipeDynamicGenerator)
} }
override fun registerCollapsibleEntries(registry: CollapsibleEntryRegistry) { override fun registerCollapsibleEntries(registry: CollapsibleEntryRegistry) {

View File

@@ -47,13 +47,13 @@ object NEUItemEntryRenderer : EntryRenderer<SBItemStack>, BatchedEntryRenderer<S
val minecraft = MinecraftClient.getInstance() val minecraft = MinecraftClient.getInstance()
override fun getTooltip(entry: EntryStack<SBItemStack>, tooltipContext: TooltipContext): Tooltip? { override fun getTooltip(entry: EntryStack<SBItemStack>, tooltipContext: TooltipContext): Tooltip? {
return Tooltip.create( val stack = entry.value.asImmutableItemStack()
entry.asItemEntry().value.getTooltip( val lore = stack.getTooltip(
Item.TooltipContext.DEFAULT, Item.TooltipContext.DEFAULT,
null, null,
TooltipType.BASIC TooltipType.BASIC
)
) )
return Tooltip.create(lore)
} }
override fun getExtraData(entry: EntryStack<SBItemStack>): BakedModel { override fun getExtraData(entry: EntryStack<SBItemStack>): BakedModel {

View File

@@ -1,5 +1,6 @@
/* /*
* SPDX-FileCopyrightText: 2023 Linnea Gräf <nea@nea.moe> * SPDX-FileCopyrightText: 2023 Linnea Gräf <nea@nea.moe>
* SPDX-FileCopyrightText: 2024 Linnea Gräf <nea@nea.moe>
* *
* SPDX-License-Identifier: GPL-3.0-or-later * SPDX-License-Identifier: GPL-3.0-or-later
*/ */
@@ -27,7 +28,7 @@ object NEUItemEntrySerializer : EntrySerializer<SBItemStack> {
override fun save(entry: EntryStack<SBItemStack>, value: SBItemStack): NbtCompound { override fun save(entry: EntryStack<SBItemStack>, value: SBItemStack): NbtCompound {
return NbtCompound().apply { return NbtCompound().apply {
putString(SKYBLOCK_ID_ENTRY, value.skyblockId.neuItem) putString(SKYBLOCK_ID_ENTRY, value.skyblockId.neuItem)
putInt(SKYBLOCK_ITEM_COUNT, value.stackSize) putInt(SKYBLOCK_ITEM_COUNT, value.getStackSize())
} }
} }
} }

View File

@@ -46,6 +46,9 @@ data class PetData(
fun fromHypixel(petInfo: HypixelPetInfo) = PetData( fun fromHypixel(petInfo: HypixelPetInfo) = PetData(
petInfo.tier, petInfo.type, petInfo.exp, petInfo.tier, petInfo.type, petInfo.exp,
) )
fun forLevel(petId: String, rarity: Rarity, level: Int) = PetData(
rarity, petId, ExpLadders.getExpLadder(petId, rarity).getPetExpForLevel(level).toDouble()
)
} }
val levelData by lazy { ExpLadders.getExpLadder(petId, rarity).getPetLevel(exp) } val levelData by lazy { ExpLadders.getExpLadder(petId, rarity).getPetLevel(exp) }
@@ -54,10 +57,22 @@ data class PetData(
data class SBItemStack( data class SBItemStack(
val skyblockId: SkyblockId, val skyblockId: SkyblockId,
val neuItem: NEUItem?, val neuItem: NEUItem?,
val stackSize: Int, private var stackSize: Int,
val petData: PetData?, private var petData: PetData?,
val extraLore: List<Text> = emptyList(), val extraLore: List<Text> = emptyList(),
) { ) {
fun getStackSize() = stackSize
fun setStackSize(newSize: Int) {
this.stackSize = stackSize
this.itemStack_ = null
}
fun getPetData() = petData
fun setPetData(petData: PetData?) {
this.petData = petData
this.itemStack_ = null
}
constructor(skyblockId: SkyblockId, petData: PetData) : this( constructor(skyblockId: SkyblockId, petData: PetData) : this(
skyblockId, skyblockId,
RepoManager.getNEUItem(skyblockId), RepoManager.getNEUItem(skyblockId),
@@ -87,7 +102,7 @@ data class SBItemStack(
} }
private fun injectReplacementDataForPets(replacementData: MutableMap<String, String>) { private fun injectReplacementDataForPets(replacementData: MutableMap<String, String>) {
if (petData == null) return val petData = this.petData ?: return
val petInfo = RepoManager.neuRepo.constants.petNumbers[petData.petId]?.get(petData.rarity) ?: return val petInfo = RepoManager.neuRepo.constants.petNumbers[petData.petId]?.get(petData.rarity) ?: return
if (petData.isStub) { if (petData.isStub) {
val mapLow = mutableMapOf<String, String>() val mapLow = mutableMapOf<String, String>()
@@ -105,14 +120,23 @@ data class SBItemStack(
} }
} }
private val itemStack: ItemStack by lazy(LazyThreadSafetyMode.NONE) {
if (skyblockId == SkyblockId.COINS) private var itemStack_: ItemStack? = null
return@lazy ItemCache.coinItem(stackSize).also { it.appendLore(extraLore) }
val replacementData = mutableMapOf<String, String>() private val itemStack: ItemStack
injectReplacementDataForPets(replacementData) get() {
return@lazy neuItem.asItemStack(idHint = skyblockId, replacementData).copyWithCount(stackSize) val itemStack = itemStack_ ?: run {
.also { it.appendLore(extraLore) } if (skyblockId == SkyblockId.COINS)
} return@run ItemCache.coinItem(stackSize).also { it.appendLore(extraLore) }
val replacementData = mutableMapOf<String, String>()
injectReplacementDataForPets(replacementData)
return@run neuItem.asItemStack(idHint = skyblockId, replacementData).copyWithCount(stackSize)
.also { it.appendLore(extraLore) }
}
if (itemStack_ == null)
itemStack_ = itemStack
return itemStack
}
fun asImmutableItemStack(): ItemStack { fun asImmutableItemStack(): ItemStack {
return itemStack return itemStack
@@ -125,7 +149,7 @@ data class SBItemStack(
object SBItemEntryDefinition : EntryDefinition<SBItemStack> { object SBItemEntryDefinition : EntryDefinition<SBItemStack> {
override fun equals(o1: SBItemStack, o2: SBItemStack, context: ComparisonContext): Boolean { override fun equals(o1: SBItemStack, o2: SBItemStack, context: ComparisonContext): Boolean {
return o1.skyblockId == o2.skyblockId && o1.stackSize == o2.stackSize return o1.skyblockId == o2.skyblockId && o1.getStackSize() == o2.getStackSize()
} }
override fun cheatsAs(entry: EntryStack<SBItemStack>?, value: SBItemStack): ItemStack { override fun cheatsAs(entry: EntryStack<SBItemStack>?, value: SBItemStack): ItemStack {
@@ -167,7 +191,7 @@ object SBItemEntryDefinition : EntryDefinition<SBItemStack> {
} }
override fun isEmpty(entry: EntryStack<SBItemStack>?, value: SBItemStack): Boolean { override fun isEmpty(entry: EntryStack<SBItemStack>?, value: SBItemStack): Boolean {
return value.stackSize == 0 return value.getStackSize() == 0
} }
override fun getIdentifier(entry: EntryStack<SBItemStack>?, value: SBItemStack): Identifier { override fun getIdentifier(entry: EntryStack<SBItemStack>?, value: SBItemStack): Identifier {

View File

@@ -9,32 +9,34 @@ package moe.nea.firmament.rei
import io.github.moulberry.repo.data.NEUCraftingRecipe import io.github.moulberry.repo.data.NEUCraftingRecipe
import io.github.moulberry.repo.data.NEUForgeRecipe import io.github.moulberry.repo.data.NEUForgeRecipe
import io.github.moulberry.repo.data.NEUKatUpgradeRecipe
import io.github.moulberry.repo.data.NEUMobDropRecipe import io.github.moulberry.repo.data.NEUMobDropRecipe
import io.github.moulberry.repo.data.NEURecipe import io.github.moulberry.repo.data.NEURecipe
import java.util.* import java.util.Optional
import me.shedaniel.rei.api.client.registry.display.DynamicDisplayGenerator import me.shedaniel.rei.api.client.registry.display.DynamicDisplayGenerator
import me.shedaniel.rei.api.client.view.ViewSearchBuilder import me.shedaniel.rei.api.client.view.ViewSearchBuilder
import me.shedaniel.rei.api.common.display.Display import me.shedaniel.rei.api.common.display.Display
import me.shedaniel.rei.api.common.entry.EntryStack import me.shedaniel.rei.api.common.entry.EntryStack
import moe.nea.firmament.rei.recipes.SBCraftingRecipe import moe.nea.firmament.rei.recipes.SBCraftingRecipe
import moe.nea.firmament.rei.recipes.SBForgeRecipe import moe.nea.firmament.rei.recipes.SBForgeRecipe
import moe.nea.firmament.rei.recipes.SBKatRecipe
import moe.nea.firmament.rei.recipes.SBMobDropRecipe import moe.nea.firmament.rei.recipes.SBMobDropRecipe
import moe.nea.firmament.repo.RepoManager import moe.nea.firmament.repo.RepoManager
val SkyblockCraftingRecipeDynamicGenerator = neuDisplayGenerator<SBCraftingRecipe, NEUCraftingRecipe> { val SkyblockCraftingRecipeDynamicGenerator =
SBCraftingRecipe(it) neuDisplayGenerator<SBCraftingRecipe, NEUCraftingRecipe> { SBCraftingRecipe(it) }
}
val SkyblockForgeRecipeDynamicGenerator = neuDisplayGenerator<SBForgeRecipe, NEUForgeRecipe> { val SkyblockForgeRecipeDynamicGenerator =
SBForgeRecipe(it) neuDisplayGenerator<SBForgeRecipe, NEUForgeRecipe> { SBForgeRecipe(it) }
}
val SkyblockMobDropRecipeDynamicGenerator = neuDisplayGenerator<SBMobDropRecipe, NEUMobDropRecipe> { val SkyblockMobDropRecipeDynamicGenerator =
SBMobDropRecipe(it) neuDisplayGenerator<SBMobDropRecipe, NEUMobDropRecipe> { SBMobDropRecipe(it) }
}
inline fun <D : Display, reified T : NEURecipe> neuDisplayGenerator(noinline mapper: (T) -> D) = val SkyblockKatRecipeDynamicGenerator =
neuDisplayGenerator<SBKatRecipe, NEUKatUpgradeRecipe> { SBKatRecipe(it) }
inline fun <D : Display, reified T : NEURecipe> neuDisplayGenerator(crossinline mapper: (T) -> D) =
object : DynamicDisplayGenerator<D> { object : DynamicDisplayGenerator<D> {
override fun getRecipeFor(entry: EntryStack<*>): Optional<List<D>> { override fun getRecipeFor(entry: EntryStack<*>): Optional<List<D>> {
if (entry.type != SBItemEntryDefinition.type) return Optional.empty() if (entry.type != SBItemEntryDefinition.type) return Optional.empty()
@@ -47,7 +49,7 @@ inline fun <D : Display, reified T : NEURecipe> neuDisplayGenerator(noinline map
override fun generate(builder: ViewSearchBuilder): Optional<List<D>> { override fun generate(builder: ViewSearchBuilder): Optional<List<D>> {
if (SBCraftingRecipe.Category.catIdentifier !in builder.categories) return Optional.empty() if (SBCraftingRecipe.Category.catIdentifier !in builder.categories) return Optional.empty()
return Optional.of( return Optional.of(
RepoManager.getAllRecipes().filterIsInstance<T>().map(mapper) RepoManager.getAllRecipes().filterIsInstance<T>().map { mapper(it) }
.toList() .toList()
) )
} }

View File

@@ -0,0 +1,229 @@
/*
* SPDX-FileCopyrightText: 2024 Linnea Gräf <nea@nea.moe>
*
* SPDX-License-Identifier: GPL-3.0-or-later
*/
package moe.nea.firmament.rei.recipes
import io.github.moulberry.repo.data.NEUKatUpgradeRecipe
import io.github.notenoughupdates.moulconfig.common.IMinecraft
import io.github.notenoughupdates.moulconfig.gui.GuiComponent
import io.github.notenoughupdates.moulconfig.gui.GuiImmediateContext
import io.github.notenoughupdates.moulconfig.gui.MouseEvent
import io.github.notenoughupdates.moulconfig.gui.component.SliderComponent
import io.github.notenoughupdates.moulconfig.observer.GetSetter
import io.github.notenoughupdates.moulconfig.observer.Property
import io.github.notenoughupdates.moulconfig.platform.ModernRenderContext
import me.shedaniel.math.Point
import me.shedaniel.math.Rectangle
import me.shedaniel.rei.api.client.gui.Renderer
import me.shedaniel.rei.api.client.gui.widgets.Widget
import me.shedaniel.rei.api.client.gui.widgets.WidgetWithBounds
import me.shedaniel.rei.api.client.gui.widgets.Widgets
import me.shedaniel.rei.api.client.registry.display.DisplayCategory
import me.shedaniel.rei.api.common.category.CategoryIdentifier
import me.shedaniel.rei.api.common.util.EntryStacks
import kotlin.time.Duration.Companion.seconds
import net.minecraft.block.Blocks
import net.minecraft.client.gui.DrawContext
import net.minecraft.client.gui.Element
import net.minecraft.item.Items
import net.minecraft.text.Text
import moe.nea.firmament.Firmament
import moe.nea.firmament.rei.PetData
import moe.nea.firmament.rei.SBItemEntryDefinition
import moe.nea.firmament.rei.SBItemStack
import moe.nea.firmament.util.FirmFormatters
import moe.nea.firmament.util.MC
import moe.nea.firmament.util.SkyblockId
class SBKatRecipe(override val neuRecipe: NEUKatUpgradeRecipe) : SBRecipe() {
override fun getCategoryIdentifier(): CategoryIdentifier<*> = Category.categoryIdentifier
object Category : DisplayCategory<SBKatRecipe> {
override fun getCategoryIdentifier(): CategoryIdentifier<SBKatRecipe> =
CategoryIdentifier.of(Firmament.MOD_ID, "kat_recipe")
override fun getTitle(): Text = Text.literal("Kat Pet Upgrade")
override fun getDisplayHeight(): Int {
return 100
}
override fun getIcon(): Renderer = EntryStacks.of(Items.BONE)
override fun setupDisplay(display: SBKatRecipe, bounds: Rectangle): List<Widget> {
return buildList {
val arrowWidth = 24
val recipe = display.neuRecipe
val levelValue = Property.upgrade(GetSetter.floating(0F))
val slider = SliderComponent(levelValue, 1F, 100F, 1f, 100)
val outputStack = SBItemStack(SkyblockId(recipe.output.itemId))
val inputStack = SBItemStack(SkyblockId(recipe.input.itemId))
val inputLevelLabelCenter = Point(bounds.minX + 30 - 18 + 5 + 8, bounds.minY + 25)
val inputLevelLabel = Widgets.createLabel(
inputLevelLabelCenter,
Text.literal("")).centered()
val outputLevelLabelCenter = Point(bounds.maxX - 30 + 8, bounds.minY + 25)
val outputLevelLabel = Widgets.createLabel(
outputLevelLabelCenter,
Text.literal("")).centered()
val coinStack = SBItemStack(SkyblockId.COINS, recipe.coins.toInt())
levelValue.whenChanged { oldValue, newValue ->
if (oldValue.toInt() == newValue.toInt()) return@whenChanged
val oldInput = inputStack.getPetData() ?: return@whenChanged
val newInput = PetData.forLevel(oldInput.petId, oldInput.rarity, newValue.toInt())
inputStack.setPetData(newInput)
val oldOutput = outputStack.getPetData() ?: return@whenChanged
val newOutput = PetData(oldOutput.rarity, oldOutput.petId, newInput.exp)
outputStack.setPetData(newOutput)
inputLevelLabel.message = Text.literal(newInput.levelData.currentLevel.toString())
inputLevelLabel.bounds.location = Point(
inputLevelLabelCenter.x - MC.font.getWidth(inputLevelLabel.message) / 2,
inputLevelLabelCenter.y)
outputLevelLabel.message = Text.literal(newOutput.levelData.currentLevel.toString())
outputLevelLabel.bounds.location = Point(
outputLevelLabelCenter.x - MC.font.getWidth(outputLevelLabel.message) / 2,
outputLevelLabelCenter.y)
coinStack.setStackSize((recipe.coins * (1 - 0.3 * newValue / 100)).toInt())
}
levelValue.set(1F)
add(Widgets.createRecipeBase(bounds))
add(wrapWidget(Rectangle(bounds.centerX - slider.width / 2,
bounds.maxY - 30,
slider.width,
slider.height),
slider))
add(Widgets.withTooltip(
Widgets.createArrow(Point(bounds.centerX - arrowWidth / 2, bounds.minY + 40)),
Text.literal("Upgrade time: " + FirmFormatters.formatTimespan(recipe.seconds.seconds))))
add(Widgets.createResultSlotBackground(Point(bounds.maxX - 30, bounds.minY + 40)))
add(inputLevelLabel)
add(outputLevelLabel)
add(Widgets.createSlot(Point(bounds.maxX - 30, bounds.minY + 40)).markOutput().disableBackground()
.entry(SBItemEntryDefinition.getEntry(outputStack)))
add(Widgets.createSlot(Point(bounds.minX + 30 - 18 + 5, bounds.minY + 40)).markInput()
.entry(SBItemEntryDefinition.getEntry(inputStack)))
val allInputs = recipe.items.map { SBItemEntryDefinition.getEntry(it) } +
listOf(SBItemEntryDefinition.getEntry(coinStack))
for ((index, item) in allInputs.withIndex()) {
add(Widgets.createSlot(
Point(bounds.centerX + index * 20 - allInputs.size * 18 / 2 - (allInputs.size - 1) * 2 / 2,
bounds.minY + 20))
.markInput()
.entry(item))
}
}
}
}
}
fun wrapWidget(bounds: Rectangle, component: GuiComponent): Widget {
return object : WidgetWithBounds() {
override fun getBounds(): Rectangle {
return bounds
}
override fun children(): List<Element> {
return listOf()
}
override fun render(context: DrawContext, mouseX: Int, mouseY: Int, delta: Float) {
context.matrices.push()
context.matrices.translate(bounds.minX.toFloat(), bounds.minY.toFloat(), 0F)
component.render(
GuiImmediateContext(
ModernRenderContext(context),
bounds.minX, bounds.minY,
bounds.width, bounds.height,
mouseX - bounds.minX, mouseY - bounds.minY,
mouseX, mouseY,
mouseX.toFloat(), mouseY.toFloat()
))
context.matrices.pop()
}
override fun mouseMoved(mouseX: Double, mouseY: Double) {
val mouseXInt = mouseX.toInt()
val mouseYInt = mouseY.toInt()
component.mouseEvent(MouseEvent.Move(0F, 0F),
GuiImmediateContext(
IMinecraft.instance.provideTopLevelRenderContext(),
bounds.minX, bounds.minY,
bounds.width, bounds.height,
mouseXInt - bounds.minX, mouseYInt - bounds.minY,
mouseXInt, mouseYInt,
mouseX.toFloat(), mouseY.toFloat()
))
}
override fun mouseClicked(mouseX: Double, mouseY: Double, button: Int): Boolean {
val mouseXInt = mouseX.toInt()
val mouseYInt = mouseY.toInt()
return component.mouseEvent(MouseEvent.Click(button, true),
GuiImmediateContext(
IMinecraft.instance.provideTopLevelRenderContext(),
bounds.minX, bounds.minY,
bounds.width, bounds.height,
mouseXInt - bounds.minX, mouseYInt - bounds.minY,
mouseXInt, mouseYInt,
mouseX.toFloat(), mouseY.toFloat()
))
}
override fun mouseReleased(mouseX: Double, mouseY: Double, button: Int): Boolean {
val mouseXInt = mouseX.toInt()
val mouseYInt = mouseY.toInt()
return component.mouseEvent(MouseEvent.Click(button, false),
GuiImmediateContext(
IMinecraft.instance.provideTopLevelRenderContext(),
bounds.minX, bounds.minY,
bounds.width, bounds.height,
mouseXInt - bounds.minX, mouseYInt - bounds.minY,
mouseXInt, mouseYInt,
mouseX.toFloat(), mouseY.toFloat()
))
}
override fun mouseDragged(
mouseX: Double,
mouseY: Double,
button: Int,
deltaX: Double,
deltaY: Double
): Boolean {
val mouseXInt = mouseX.toInt()
val mouseYInt = mouseY.toInt()
return component.mouseEvent(MouseEvent.Move(deltaX.toFloat(), deltaY.toFloat()),
GuiImmediateContext(
IMinecraft.instance.provideTopLevelRenderContext(),
bounds.minX, bounds.minY,
bounds.width, bounds.height,
mouseXInt - bounds.minX, mouseYInt - bounds.minY,
mouseXInt, mouseYInt,
mouseX.toFloat(), mouseY.toFloat()
))
}
override fun mouseScrolled(
mouseX: Double,
mouseY: Double,
horizontalAmount: Double,
verticalAmount: Double
): Boolean {
val mouseXInt = mouseX.toInt()
val mouseYInt = mouseY.toInt()
return component.mouseEvent(MouseEvent.Scroll(verticalAmount.toFloat()),
GuiImmediateContext(
IMinecraft.instance.provideTopLevelRenderContext(),
bounds.minX, bounds.minY,
bounds.width, bounds.height,
mouseXInt - bounds.minX, mouseYInt - bounds.minY,
mouseXInt, mouseYInt,
mouseX.toFloat(), mouseY.toFloat()
))
}
}
}

View File

@@ -12,7 +12,7 @@ package moe.nea.firmament.util.item
import com.mojang.authlib.GameProfile import com.mojang.authlib.GameProfile
import com.mojang.authlib.minecraft.MinecraftProfileTexture import com.mojang.authlib.minecraft.MinecraftProfileTexture
import com.mojang.authlib.properties.Property import com.mojang.authlib.properties.Property
import java.util.* import java.util.UUID
import kotlinx.datetime.Clock import kotlinx.datetime.Clock
import kotlinx.datetime.Instant import kotlinx.datetime.Instant
import kotlinx.serialization.Serializable import kotlinx.serialization.Serializable
@@ -63,10 +63,12 @@ fun ItemStack.setEncodedSkullOwner(uuid: UUID, encodedData: String) {
val zeroUUID = UUID.fromString("d3cb85e2-3075-48a1-b213-a9bfb62360c1") val zeroUUID = UUID.fromString("d3cb85e2-3075-48a1-b213-a9bfb62360c1")
fun ItemStack.setSkullOwner(uuid: UUID, url: String) { fun ItemStack.setSkullOwner(uuid: UUID, url: String) {
assert(this.item == Items.PLAYER_HEAD) assert(this.item == Items.PLAYER_HEAD)
val gameProfile = GameProfile(uuid, "LameGuy123") val gameProfile = GameProfile(uuid, "nea89")
gameProfile.setTextures( gameProfile.setTextures(
MinecraftTexturesPayloadKt( MinecraftTexturesPayloadKt(
mapOf(MinecraftProfileTexture.Type.SKIN to MinecraftProfileTextureKt(url)) textures = mapOf(MinecraftProfileTexture.Type.SKIN to MinecraftProfileTextureKt(url)),
profileId = uuid,
profileName = "nea89",
) )
) )
this.set(DataComponentTypes.PROFILE, ProfileComponent(gameProfile)) this.set(DataComponentTypes.PROFILE, ProfileComponent(gameProfile))