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