feat: allow skull:texturehash items for neu buttons
This commit is contained in:
@@ -1,5 +1,3 @@
|
|||||||
|
|
||||||
|
|
||||||
package moe.nea.firmament.features.inventory.buttons
|
package moe.nea.firmament.features.inventory.buttons
|
||||||
|
|
||||||
import com.mojang.brigadier.StringReader
|
import com.mojang.brigadier.StringReader
|
||||||
@@ -18,69 +16,86 @@ import moe.nea.firmament.repo.RepoManager
|
|||||||
import moe.nea.firmament.util.MC
|
import moe.nea.firmament.util.MC
|
||||||
import moe.nea.firmament.util.SkyblockId
|
import moe.nea.firmament.util.SkyblockId
|
||||||
import moe.nea.firmament.util.collections.memoize
|
import moe.nea.firmament.util.collections.memoize
|
||||||
|
import moe.nea.firmament.util.mc.arbitraryUUID
|
||||||
|
import moe.nea.firmament.util.mc.createSkullItem
|
||||||
import moe.nea.firmament.util.render.drawGuiTexture
|
import moe.nea.firmament.util.render.drawGuiTexture
|
||||||
|
|
||||||
@Serializable
|
@Serializable
|
||||||
data class InventoryButton(
|
data class InventoryButton(
|
||||||
var x: Int,
|
var x: Int,
|
||||||
var y: Int,
|
var y: Int,
|
||||||
var anchorRight: Boolean,
|
var anchorRight: Boolean,
|
||||||
var anchorBottom: Boolean,
|
var anchorBottom: Boolean,
|
||||||
var icon: String? = "",
|
var icon: String? = "",
|
||||||
var command: String? = "",
|
var command: String? = "",
|
||||||
) {
|
) {
|
||||||
companion object {
|
companion object {
|
||||||
val itemStackParser by lazy {
|
val itemStackParser by lazy {
|
||||||
ItemStackArgumentType.itemStack(CommandRegistryAccess.of(MC.defaultRegistries,
|
ItemStackArgumentType.itemStack(
|
||||||
FeatureFlags.VANILLA_FEATURES))
|
CommandRegistryAccess.of(
|
||||||
}
|
MC.defaultRegistries,
|
||||||
val dimensions = Dimension(18, 18)
|
FeatureFlags.VANILLA_FEATURES
|
||||||
val getItemForName = ::getItemForName0.memoize(1024)
|
)
|
||||||
fun getItemForName0(icon: String): ItemStack {
|
)
|
||||||
val repoItem = RepoManager.getNEUItem(SkyblockId(icon))
|
}
|
||||||
var itemStack = repoItem.asItemStack(idHint = SkyblockId(icon))
|
val dimensions = Dimension(18, 18)
|
||||||
if (repoItem == null) {
|
val getItemForName = ::getItemForName0.memoize(1024)
|
||||||
val giveSyntaxItem = if (icon.startsWith("/give") || icon.startsWith("give"))
|
fun getItemForName0(icon: String): ItemStack {
|
||||||
icon.split(" ", limit = 3).getOrNull(2) ?: icon
|
val repoItem = RepoManager.getNEUItem(SkyblockId(icon))
|
||||||
else icon
|
var itemStack = repoItem.asItemStack(idHint = SkyblockId(icon))
|
||||||
val componentItem =
|
if (repoItem == null) {
|
||||||
runCatching {
|
when {
|
||||||
itemStackParser.parse(StringReader(giveSyntaxItem)).createStack(1, false)
|
icon.startsWith("skull:") -> {
|
||||||
}.getOrNull()
|
itemStack = createSkullItem(
|
||||||
if (componentItem != null)
|
arbitraryUUID,
|
||||||
itemStack = componentItem
|
"https://textures.minecraft.net/texture/${icon.substring("skull:".length)}"
|
||||||
}
|
)
|
||||||
return itemStack
|
}
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fun render(context: DrawContext) {
|
else -> {
|
||||||
context.drawGuiTexture(
|
val giveSyntaxItem = if (icon.startsWith("/give") || icon.startsWith("give"))
|
||||||
0,
|
icon.split(" ", limit = 3).getOrNull(2) ?: icon
|
||||||
0,
|
else icon
|
||||||
0,
|
val componentItem =
|
||||||
dimensions.width,
|
runCatching {
|
||||||
dimensions.height,
|
itemStackParser.parse(StringReader(giveSyntaxItem)).createStack(1, false)
|
||||||
Identifier.of("firmament:inventory_button_background")
|
}.getOrNull()
|
||||||
)
|
if (componentItem != null)
|
||||||
context.drawItem(getItem(), 1, 1)
|
itemStack = componentItem
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return itemStack
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fun isValid() = !icon.isNullOrBlank() && !command.isNullOrBlank()
|
fun render(context: DrawContext) {
|
||||||
|
context.drawGuiTexture(
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
dimensions.width,
|
||||||
|
dimensions.height,
|
||||||
|
Identifier.of("firmament:inventory_button_background")
|
||||||
|
)
|
||||||
|
context.drawItem(getItem(), 1, 1)
|
||||||
|
}
|
||||||
|
|
||||||
fun getPosition(guiRect: Rectangle): Point {
|
fun isValid() = !icon.isNullOrBlank() && !command.isNullOrBlank()
|
||||||
return Point(
|
|
||||||
(if (anchorRight) guiRect.maxX else guiRect.minX) + x,
|
|
||||||
(if (anchorBottom) guiRect.maxY else guiRect.minY) + y,
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
fun getBounds(guiRect: Rectangle): Rectangle {
|
fun getPosition(guiRect: Rectangle): Point {
|
||||||
return Rectangle(getPosition(guiRect), dimensions)
|
return Point(
|
||||||
}
|
(if (anchorRight) guiRect.maxX else guiRect.minX) + x,
|
||||||
|
(if (anchorBottom) guiRect.maxY else guiRect.minY) + y,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
fun getItem(): ItemStack {
|
fun getBounds(guiRect: Rectangle): Rectangle {
|
||||||
return getItemForName(icon ?: "")
|
return Rectangle(getPosition(guiRect), dimensions)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun getItem(): ItemStack {
|
||||||
|
return getItemForName(icon ?: "")
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,7 +1,9 @@
|
|||||||
package moe.nea.firmament.features.inventory.buttons
|
package moe.nea.firmament.features.inventory.buttons
|
||||||
|
|
||||||
import io.github.notenoughupdates.moulconfig.common.IItemStack
|
import io.github.notenoughupdates.moulconfig.common.IItemStack
|
||||||
|
import io.github.notenoughupdates.moulconfig.gui.component.PanelComponent
|
||||||
import io.github.notenoughupdates.moulconfig.platform.ModernItemStack
|
import io.github.notenoughupdates.moulconfig.platform.ModernItemStack
|
||||||
|
import io.github.notenoughupdates.moulconfig.platform.ModernRenderContext
|
||||||
import io.github.notenoughupdates.moulconfig.xml.Bind
|
import io.github.notenoughupdates.moulconfig.xml.Bind
|
||||||
import me.shedaniel.math.Point
|
import me.shedaniel.math.Point
|
||||||
import me.shedaniel.math.Rectangle
|
import me.shedaniel.math.Rectangle
|
||||||
@@ -57,7 +59,10 @@ class InventoryButtonEditor(
|
|||||||
}
|
}
|
||||||
|
|
||||||
override fun resize(client: MinecraftClient, width: Int, height: Int) {
|
override fun resize(client: MinecraftClient, width: Int, height: Int) {
|
||||||
lastGuiRect.move(MC.window.scaledWidth / 2 - lastGuiRect.width / 2, MC.window.scaledHeight / 2 - lastGuiRect.height / 2)
|
lastGuiRect.move(
|
||||||
|
MC.window.scaledWidth / 2 - lastGuiRect.width / 2,
|
||||||
|
MC.window.scaledHeight / 2 - lastGuiRect.height / 2
|
||||||
|
)
|
||||||
super.resize(client, width, height)
|
super.resize(client, width, height)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -89,14 +94,20 @@ class InventoryButtonEditor(
|
|||||||
val movedButtons = mutableListOf<InventoryButton>()
|
val movedButtons = mutableListOf<InventoryButton>()
|
||||||
for (button in buttons) {
|
for (button in buttons) {
|
||||||
if ((!button.anchorBottom && !button.anchorRight && button.x > 0 && button.y > 0)) {
|
if ((!button.anchorBottom && !button.anchorRight && button.x > 0 && button.y > 0)) {
|
||||||
MC.sendChat(tr("firmament.inventory-buttons.button-moved",
|
MC.sendChat(
|
||||||
"One of your imported buttons intersects with the inventory and has been moved to the top left."))
|
tr(
|
||||||
movedButtons.add(button.copy(
|
"firmament.inventory-buttons.button-moved",
|
||||||
x = 0,
|
"One of your imported buttons intersects with the inventory and has been moved to the top left."
|
||||||
y = -InventoryButton.dimensions.width,
|
)
|
||||||
anchorRight = false,
|
)
|
||||||
anchorBottom = false
|
movedButtons.add(
|
||||||
))
|
button.copy(
|
||||||
|
x = 0,
|
||||||
|
y = -InventoryButton.dimensions.width,
|
||||||
|
anchorRight = false,
|
||||||
|
anchorBottom = false
|
||||||
|
)
|
||||||
|
)
|
||||||
} else {
|
} else {
|
||||||
newButtons.add(button)
|
newButtons.add(button)
|
||||||
}
|
}
|
||||||
@@ -105,9 +116,11 @@ class InventoryButtonEditor(
|
|||||||
val zeroRect = Rectangle(0, 0, 1, 1)
|
val zeroRect = Rectangle(0, 0, 1, 1)
|
||||||
for (movedButton in movedButtons) {
|
for (movedButton in movedButtons) {
|
||||||
fun getPosition(button: InventoryButton, index: Int) =
|
fun getPosition(button: InventoryButton, index: Int) =
|
||||||
button.copy(x = (index % 10) * InventoryButton.dimensions.width,
|
button.copy(
|
||||||
y = (index / 10) * -InventoryButton.dimensions.height,
|
x = (index % 10) * InventoryButton.dimensions.width,
|
||||||
anchorRight = false, anchorBottom = false)
|
y = (index / 10) * -InventoryButton.dimensions.height,
|
||||||
|
anchorRight = false, anchorBottom = false
|
||||||
|
)
|
||||||
while (true) {
|
while (true) {
|
||||||
val newPos = getPosition(movedButton, i++)
|
val newPos = getPosition(movedButton, i++)
|
||||||
val newBounds = newPos.getBounds(zeroRect)
|
val newBounds = newPos.getBounds(zeroRect)
|
||||||
@@ -131,7 +144,12 @@ class InventoryButtonEditor(
|
|||||||
super.render(context, mouseX, mouseY, delta)
|
super.render(context, mouseX, mouseY, delta)
|
||||||
context.matrices.push()
|
context.matrices.push()
|
||||||
context.matrices.translate(0f, 0f, -10f)
|
context.matrices.translate(0f, 0f, -10f)
|
||||||
context.fill(lastGuiRect.minX, lastGuiRect.minY, lastGuiRect.maxX, lastGuiRect.maxY, -1)
|
PanelComponent.DefaultBackgroundRenderer.VANILLA
|
||||||
|
.render(
|
||||||
|
ModernRenderContext(context),
|
||||||
|
lastGuiRect.minX, lastGuiRect.minY,
|
||||||
|
lastGuiRect.width, lastGuiRect.height,
|
||||||
|
)
|
||||||
context.matrices.pop()
|
context.matrices.pop()
|
||||||
for (button in buttons) {
|
for (button in buttons) {
|
||||||
val buttonPosition = button.getBounds(lastGuiRect)
|
val buttonPosition = button.getBounds(lastGuiRect)
|
||||||
@@ -193,14 +211,6 @@ class InventoryButtonEditor(
|
|||||||
)
|
)
|
||||||
|
|
||||||
fun getCoordsForMouse(mx: Int, my: Int): AnchoredCoords? {
|
fun getCoordsForMouse(mx: Int, my: Int): AnchoredCoords? {
|
||||||
if (lastGuiRect.contains(mx, my) || lastGuiRect.contains(
|
|
||||||
Point(
|
|
||||||
mx + InventoryButton.dimensions.width,
|
|
||||||
my + InventoryButton.dimensions.height,
|
|
||||||
)
|
|
||||||
)
|
|
||||||
) return null
|
|
||||||
|
|
||||||
val anchorRight = mx > lastGuiRect.maxX
|
val anchorRight = mx > lastGuiRect.maxX
|
||||||
val anchorBottom = my > lastGuiRect.maxY
|
val anchorBottom = my > lastGuiRect.maxY
|
||||||
var offsetX = mx - if (anchorRight) lastGuiRect.maxX else lastGuiRect.minX
|
var offsetX = mx - if (anchorRight) lastGuiRect.maxX else lastGuiRect.minX
|
||||||
@@ -209,7 +219,10 @@ class InventoryButtonEditor(
|
|||||||
offsetX = MathHelper.floor(offsetX / 20F) * 20
|
offsetX = MathHelper.floor(offsetX / 20F) * 20
|
||||||
offsetY = MathHelper.floor(offsetY / 20F) * 20
|
offsetY = MathHelper.floor(offsetY / 20F) * 20
|
||||||
}
|
}
|
||||||
return AnchoredCoords(anchorRight, anchorBottom, offsetX, offsetY)
|
val rect = InventoryButton(offsetX, offsetY, anchorRight, anchorBottom).getBounds(lastGuiRect)
|
||||||
|
if (rect.intersects(lastGuiRect)) return null
|
||||||
|
val anchoredCoords = AnchoredCoords(anchorRight, anchorBottom, offsetX, offsetY)
|
||||||
|
return anchoredCoords
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun mouseClicked(mouseX: Double, mouseY: Double, button: Int): Boolean {
|
override fun mouseClicked(mouseX: Double, mouseY: Double, button: Int): Boolean {
|
||||||
|
|||||||
@@ -11,7 +11,7 @@ import net.minecraft.item.Items
|
|||||||
import moe.nea.firmament.repo.SBItemStack
|
import moe.nea.firmament.repo.SBItemStack
|
||||||
import moe.nea.firmament.util.SkyblockId
|
import moe.nea.firmament.util.SkyblockId
|
||||||
import moe.nea.firmament.util.mc.setEncodedSkullOwner
|
import moe.nea.firmament.util.mc.setEncodedSkullOwner
|
||||||
import moe.nea.firmament.util.mc.zeroUUID
|
import moe.nea.firmament.util.mc.arbitraryUUID
|
||||||
|
|
||||||
object ModifyEquipment : EntityModifier {
|
object ModifyEquipment : EntityModifier {
|
||||||
val names = mapOf(
|
val names = mapOf(
|
||||||
@@ -36,7 +36,7 @@ object ModifyEquipment : EntityModifier {
|
|||||||
if (split.size != 2) return SBItemStack(SkyblockId(item)).asImmutableItemStack()
|
if (split.size != 2) return SBItemStack(SkyblockId(item)).asImmutableItemStack()
|
||||||
val (type, data) = split
|
val (type, data) = split
|
||||||
return when (type) {
|
return when (type) {
|
||||||
"SKULL" -> ItemStack(Items.PLAYER_HEAD).also { it.setEncodedSkullOwner(zeroUUID, data) }
|
"SKULL" -> ItemStack(Items.PLAYER_HEAD).also { it.setEncodedSkullOwner(arbitraryUUID, data) }
|
||||||
"LEATHER_LEGGINGS" -> coloredLeatherArmor(Items.LEATHER_LEGGINGS, data)
|
"LEATHER_LEGGINGS" -> coloredLeatherArmor(Items.LEATHER_LEGGINGS, data)
|
||||||
"LEATHER_BOOTS" -> coloredLeatherArmor(Items.LEATHER_BOOTS, data)
|
"LEATHER_BOOTS" -> coloredLeatherArmor(Items.LEATHER_BOOTS, data)
|
||||||
"LEATHER_HELMET" -> coloredLeatherArmor(Items.LEATHER_HELMET, data)
|
"LEATHER_HELMET" -> coloredLeatherArmor(Items.LEATHER_HELMET, data)
|
||||||
|
|||||||
@@ -10,7 +10,6 @@ import kotlinx.datetime.Clock
|
|||||||
import kotlinx.datetime.Instant
|
import kotlinx.datetime.Instant
|
||||||
import kotlinx.serialization.Serializable
|
import kotlinx.serialization.Serializable
|
||||||
import kotlinx.serialization.UseSerializers
|
import kotlinx.serialization.UseSerializers
|
||||||
import kotlinx.serialization.encodeToString
|
|
||||||
import net.minecraft.component.DataComponentTypes
|
import net.minecraft.component.DataComponentTypes
|
||||||
import net.minecraft.component.type.ProfileComponent
|
import net.minecraft.component.type.ProfileComponent
|
||||||
import net.minecraft.item.ItemStack
|
import net.minecraft.item.ItemStack
|
||||||
@@ -51,7 +50,7 @@ fun ItemStack.setEncodedSkullOwner(uuid: UUID, encodedData: String) {
|
|||||||
this.set(DataComponentTypes.PROFILE, ProfileComponent(gameProfile))
|
this.set(DataComponentTypes.PROFILE, ProfileComponent(gameProfile))
|
||||||
}
|
}
|
||||||
|
|
||||||
val zeroUUID = UUID.fromString("d3cb85e2-3075-48a1-b213-a9bfb62360c1")
|
val arbitraryUUID = UUID.fromString("d3cb85e2-3075-48a1-b213-a9bfb62360c1")
|
||||||
fun createSkullItem(uuid: UUID, url: String) = ItemStack(Items.PLAYER_HEAD)
|
fun createSkullItem(uuid: UUID, url: String) = ItemStack(Items.PLAYER_HEAD)
|
||||||
.also { it.setSkullOwner(uuid, url) }
|
.also { it.setSkullOwner(uuid, url) }
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user