feat: Add huntrap locker

This commit is contained in:
Linnea Gräf
2025-07-06 22:07:47 +02:00
parent 86176d5afc
commit b40ae8a455
4 changed files with 60 additions and 17 deletions

View File

@@ -173,7 +173,10 @@ class LegacyItemExporter private constructor(var itemStack: ItemStack) {
}
private fun copyColour() {
if (!itemStack.isIn(ItemTags.DYEABLE)) return
if (!itemStack.isIn(ItemTags.DYEABLE)) {
itemStack.remove(DataComponentTypes.DYED_COLOR)
return
}
val leatherTint = itemStack.componentChanges.get(DataComponentTypes.DYED_COLOR)?.getOrNull() ?: return
legacyNbt.getOrPutCompound("display").put("color", NbtInt.of(leatherTint.rgb))
}

View File

@@ -4,7 +4,6 @@ package moe.nea.firmament.features.inventory
import java.util.UUID
import org.lwjgl.glfw.GLFW
import util.render.CustomRenderLayers
import kotlinx.serialization.KSerializer
import kotlinx.serialization.Serializable
import kotlinx.serialization.UseSerializers
@@ -19,9 +18,8 @@ import kotlinx.serialization.json.int
import kotlinx.serialization.serializer
import net.minecraft.client.gui.screen.ingame.HandledScreen
import net.minecraft.client.render.RenderLayer
import net.minecraft.client.render.RenderLayers
import net.minecraft.client.render.TexturedRenderLayers
import net.minecraft.entity.player.PlayerInventory
import net.minecraft.item.ItemStack
import net.minecraft.screen.GenericContainerScreenHandler
import net.minecraft.screen.slot.Slot
import net.minecraft.screen.slot.SlotActionType
@@ -44,14 +42,20 @@ import moe.nea.firmament.util.MC
import moe.nea.firmament.util.SBData
import moe.nea.firmament.util.SkyBlockIsland
import moe.nea.firmament.util.data.ProfileSpecificDataHolder
import moe.nea.firmament.util.extraAttributes
import moe.nea.firmament.util.json.DashlessUUIDSerializer
import moe.nea.firmament.util.lime
import moe.nea.firmament.util.mc.ScreenUtil.getSlotByIndex
import moe.nea.firmament.util.mc.SlotUtils.swapWithHotBar
import moe.nea.firmament.util.mc.displayNameAccordingToNbt
import moe.nea.firmament.util.mc.loreAccordingToNbt
import moe.nea.firmament.util.red
import moe.nea.firmament.util.render.drawLine
import moe.nea.firmament.util.skyBlockId
import moe.nea.firmament.util.skyblock.DungeonUtil
import moe.nea.firmament.util.skyblock.SkyBlockItems
import moe.nea.firmament.util.skyblockUUID
import moe.nea.firmament.util.tr
import moe.nea.firmament.util.unformattedString
object SlotLocking : FirmamentFeature {
@@ -132,6 +136,7 @@ object SlotLocking : FirmamentFeature {
val slotBindRequireShift by toggle("require-quick-move") { true }
val slotRenderLines by choice("bind-render") { SlotRenderLinesMode.ONLY_BOXES }
val allowMultiBinding by toggle("multi-bind") { true } // TODO: filter based on this option
val protectAllHuntingBoxes by toggle("hunting-box") { false }
val allowDroppingInDungeons by toggle("drop-in-dungeons") { true }
}
@@ -193,10 +198,12 @@ object SlotLocking : FirmamentFeature {
var anyBlocked = false
for (i in 0 until event.slot.index) {
val stack = inv.getStack(i)
if (IsSlotProtectedEvent.shouldBlockInteraction(null,
SlotActionType.THROW,
IsSlotProtectedEvent.MoveOrigin.SALVAGE,
stack)
if (IsSlotProtectedEvent.shouldBlockInteraction(
null,
SlotActionType.THROW,
IsSlotProtectedEvent.MoveOrigin.SALVAGE,
stack
)
)
anyBlocked = true
}
@@ -219,12 +226,20 @@ object SlotLocking : FirmamentFeature {
&& doesNotDeleteItem
) return
val stack = event.itemStack ?: return
if (TConfig.protectAllHuntingBoxes && (stack.isHuntingBox())) {
event.protect()
return
}
val uuid = stack.skyblockUUID ?: return
if (uuid in (lockedUUIDs ?: return)) {
event.protect()
}
}
fun ItemStack.isHuntingBox(): Boolean {
return skyBlockId == SkyBlockItems.HUNTING_TOOLKIT || extraAttributes.get("tool_kit") != null
}
@Subscribe
fun onProtectSlot(it: IsSlotProtectedEvent) {
if (it.slot != null && it.slot.inventory is PlayerInventory && it.slot.index in (lockedSlots ?: setOf())) {
@@ -271,6 +286,21 @@ object SlotLocking : FirmamentFeature {
val slot = inventory.focusedSlot_Firmament ?: return
val stack = slot.stack ?: return
if (stack.isHuntingBox()) {
MC.sendChat(
tr(
"firmament.slot-locking.hunting-box-unbindable-hint",
"The hunting box cannot be UUID bound reliably. It changes its own UUID frequently when switching tools. "
).red().append(
tr(
"firmament.slot-locking.hunting-box-unbindable-hint.solution",
"Use the Firmament config option for locking all hunting boxes instead."
).lime()
)
)
CommonSoundEffects.playFailure()
return
}
val uuid = stack.skyblockUUID ?: return
val lockedUUIDs = lockedUUIDs ?: return
if (uuid in lockedUUIDs) {
@@ -350,12 +380,16 @@ object SlotLocking : FirmamentFeature {
hotX + sx, hotY + sy,
color(anyHovered)
)
event.context.drawBorder(hotbarSlot.x + sx,
hotbarSlot.y + sy,
16, 16, color(hotbarSlot in highlitSlots).color)
event.context.drawBorder(inventorySlot.x + sx,
inventorySlot.y + sy,
16, 16, color(inventorySlot in highlitSlots).color)
event.context.drawBorder(
hotbarSlot.x + sx,
hotbarSlot.y + sy,
16, 16, color(hotbarSlot in highlitSlots).color
)
event.context.drawBorder(
inventorySlot.x + sx,
inventorySlot.y + sy,
16, 16, color(inventorySlot in highlitSlots).color
)
}
}
@@ -383,9 +417,11 @@ object SlotLocking : FirmamentFeature {
hovX + sx, hovY + sy,
me.shedaniel.math.Color.ofOpaque(0x00FF00)
)
event.context.drawBorder(hoveredSlot.x + sx,
hoveredSlot.y + sy,
16, 16, 0xFF00FF00u.toInt())
event.context.drawBorder(
hoveredSlot.x + sx,
hoveredSlot.y + sy,
16, 16, 0xFF00FF00u.toInt()
)
}
}

View File

@@ -19,4 +19,5 @@ object SkyBlockItems {
val BONE_BOOMERANG = SkyblockId("BONE_BOOMERANG")
val STARRED_BONE_BOOMERANG = SkyblockId("STARRED_BONE_BOOMERANG")
val TRIBAL_SPEAR = SkyblockId("TRIBAL_SPEAR")
val HUNTING_TOOLKIT = SkyblockId("HUNTING_TOOLKIT")
}

View File

@@ -266,6 +266,7 @@
"firmament.config.power-user.export-npc-location.description": "Export the NPC's location to the repo data",
"firmament.config.power-user.export-recipe": "Export Recipe Data",
"firmament.config.power-user.export-recipe.description": "Export Recipe Data to the repo data",
"firmament.config.power-user.highlight-non-overlay.description": "Highlight items missing in overlay",
"firmament.config.power-user.show-item-id": "Show SkyBlock Ids",
"firmament.config.power-user.show-item-id.description": "Show the SkyBlock id of items underneath them.",
"firmament.config.price-data": "Price Data",
@@ -337,6 +338,8 @@
"firmament.config.slot-locking.bind.description": "Bind a hotbar slot to another slot. This allows quick switching between the slots by shift clicking on either slot.",
"firmament.config.slot-locking.drop-in-dungeons": "Allow Dungeon Abilities",
"firmament.config.slot-locking.drop-in-dungeons.description": "Allow dropping items in dungeons, to use your dungeon ultimate abilities.",
"firmament.config.slot-locking.hunting-box": "Protect Hunting Box",
"firmament.config.slot-locking.hunting-box.description": "The Hunting Box frequently changes its UUID, and as such cannot be reliably protected using UUID locking. Instead this option can be used to block from dropping any Hunting Box.",
"firmament.config.slot-locking.lock": "Lock Slot",
"firmament.config.slot-locking.lock-uuid": "Lock UUID (Lock Item)",
"firmament.config.slot-locking.lock-uuid.description": "Lock a SkyBlock item by it's UUID. This blocks a specific item from being dropped/sold, but still allows moving it around.",