diff options
author | nea <nea@nea.moe> | 2023-10-04 16:41:04 +0200 |
---|---|---|
committer | nea <nea@nea.moe> | 2023-10-04 16:41:04 +0200 |
commit | 64523821d82d702c0bf2d62bbe45a1047aed8bda (patch) | |
tree | fe5f25316ddf1895281a932b8fe468b5bc330975 /src/main/kotlin/moe/nea/firmament | |
parent | d0cc95b1e9a674c41bedc50d1d7923159e2bd6a2 (diff) | |
download | Firmament-64523821d82d702c0bf2d62bbe45a1047aed8bda.tar.gz Firmament-64523821d82d702c0bf2d62bbe45a1047aed8bda.tar.bz2 Firmament-64523821d82d702c0bf2d62bbe45a1047aed8bda.zip |
Block selling to NPCs, trading and salvaging UUID locked items
[no changelog]
Diffstat (limited to 'src/main/kotlin/moe/nea/firmament')
3 files changed, 74 insertions, 16 deletions
diff --git a/src/main/kotlin/moe/nea/firmament/events/IsSlotProtectedEvent.kt b/src/main/kotlin/moe/nea/firmament/events/IsSlotProtectedEvent.kt index 02557ab..a60cd06 100644 --- a/src/main/kotlin/moe/nea/firmament/events/IsSlotProtectedEvent.kt +++ b/src/main/kotlin/moe/nea/firmament/events/IsSlotProtectedEvent.kt @@ -18,6 +18,7 @@ data class IsSlotProtectedEvent( val actionType: SlotActionType, var isProtected: Boolean, val itemStackOverride: ItemStack?, + var silent: Boolean = false, ) : FirmamentEvent() { val itemStack get() = itemStackOverride ?: slot!!.stack @@ -25,18 +26,25 @@ data class IsSlotProtectedEvent( isProtected = true } + fun protectSilent() { + if (!isProtected) { + silent = true + } + isProtected = true + } + companion object : FirmamentEventBus<IsSlotProtectedEvent>() { @JvmStatic @JvmOverloads fun shouldBlockInteraction(slot: Slot?, action: SlotActionType, itemStackOverride: ItemStack? = null): Boolean { if (slot == null && itemStackOverride == null) return false val event = IsSlotProtectedEvent(slot, action, false, itemStackOverride) - return publish(event).isProtected.also { - if (it) { - MC.player?.sendMessage(Text.translatable("firmament.protectitem").append(event.itemStack.name)) - CommonSoundEffects.playFailure() - } + publish(event) + if (event.isProtected && !event.silent) { + MC.player?.sendMessage(Text.translatable("firmament.protectitem").append(event.itemStack.name)) + CommonSoundEffects.playFailure() } + return event.isProtected } } } diff --git a/src/main/kotlin/moe/nea/firmament/features/inventory/SlotLocking.kt b/src/main/kotlin/moe/nea/firmament/features/inventory/SlotLocking.kt index 05e9935..6ef9cf4 100644 --- a/src/main/kotlin/moe/nea/firmament/features/inventory/SlotLocking.kt +++ b/src/main/kotlin/moe/nea/firmament/features/inventory/SlotLocking.kt @@ -12,6 +12,7 @@ import org.lwjgl.glfw.GLFW import kotlinx.serialization.Serializable import kotlinx.serialization.UseSerializers import kotlinx.serialization.serializer +import net.minecraft.client.gui.screen.ingame.HandledScreen import net.minecraft.entity.player.PlayerInventory import net.minecraft.screen.slot.SlotActionType import moe.nea.firmament.events.HandledScreenKeyPressedEvent @@ -25,8 +26,11 @@ import moe.nea.firmament.util.CommonSoundEffects import moe.nea.firmament.util.MC import moe.nea.firmament.util.SBData import moe.nea.firmament.util.data.ProfileSpecificDataHolder +import moe.nea.firmament.util.item.displayNameAccordingToNbt +import moe.nea.firmament.util.item.loreAccordingToNbt import moe.nea.firmament.util.json.DashlessUUIDSerializer import moe.nea.firmament.util.skyblockUUID +import moe.nea.firmament.util.unformattedString object SlotLocking : FirmamentFeature { override val identifier: String @@ -61,6 +65,31 @@ object SlotLocking : FirmamentFeature { else -> DConfig.data?.lockedSlots } + fun isSalvageScreen(screen: HandledScreen<*>?): Boolean { + if (screen == null) return false + return screen.title.unformattedString.contains("Salvage Item") + } + + fun isTradeScreen(screen: HandledScreen<*>?): Boolean { + if (screen == null) return false + val handler = screen.screenHandler + if (handler.slots.size < 9) return false + val middlePane = handler.getSlot(4) + if (!middlePane.hasStack()) return false + return middlePane.stack.displayNameAccordingToNbt?.unformattedString == "⇦ Your stuff" + } + + fun isNpcShop(screen: HandledScreen<*>?): Boolean { + if (screen == null) return false + val handler = screen.screenHandler + if (handler.slots.size < 9) return false + val sellItem = handler.getSlot(handler.slots.size - 5) + if (!sellItem.hasStack()) return false + if (sellItem.stack.displayNameAccordingToNbt?.unformattedString == "Sell Item") return true + val lore = sellItem.stack.loreAccordingToNbt + return (lore.lastOrNull() ?: return false).value?.unformattedString == "Click to buyback!" + } + override fun onLoad() { HandledScreenKeyPressedEvent.subscribe { if (!it.matches(TConfig.lockSlot)) return@subscribe @@ -101,18 +130,35 @@ object SlotLocking : FirmamentFeature { it.protect() } } - IsSlotProtectedEvent.subscribe { - if (it.actionType == SlotActionType.SWAP - || it.actionType == SlotActionType.PICKUP - || it.actionType == SlotActionType.QUICK_MOVE - || it.actionType == SlotActionType.QUICK_CRAFT - || it.actionType == SlotActionType.CLONE - || it.actionType == SlotActionType.PICKUP_ALL - ) return@subscribe - val stack = it.itemStack ?: return@subscribe + IsSlotProtectedEvent.subscribe { event -> + val doesNotDeleteItem = event.actionType == SlotActionType.SWAP + || event.actionType == SlotActionType.PICKUP + || event.actionType == SlotActionType.QUICK_MOVE + || event.actionType == SlotActionType.QUICK_CRAFT + || event.actionType == SlotActionType.CLONE + || event.actionType == SlotActionType.PICKUP_ALL + val isSellOrTradeScreen = + isNpcShop(MC.handledScreen) || isTradeScreen(MC.handledScreen) || isSalvageScreen(MC.handledScreen) + if (!isSellOrTradeScreen && doesNotDeleteItem) return@subscribe + val stack = event.itemStack ?: return@subscribe val uuid = stack.skyblockUUID ?: return@subscribe if (uuid in (lockedUUIDs ?: return@subscribe)) { - it.protect() + event.protect() + } + } + IsSlotProtectedEvent.subscribe { event -> + if (event.slot == null) return@subscribe + if (!event.slot.hasStack()) return@subscribe + if (event.slot.stack.displayNameAccordingToNbt?.unformattedString != "Salvage Items") return@subscribe + val inv = event.slot.inventory + var anyBlocked = false + for (i in 0 until event.slot.index) { + val stack = inv.getStack(i) + if (IsSlotProtectedEvent.shouldBlockInteraction(null, SlotActionType.THROW, stack)) + anyBlocked = true + } + if(anyBlocked) { + event.protectSilent() } } SlotRenderEvents.Before.subscribe { diff --git a/src/main/kotlin/moe/nea/firmament/util/item/NbtItemData.kt b/src/main/kotlin/moe/nea/firmament/util/item/NbtItemData.kt index ac30771..ff3e09d 100644 --- a/src/main/kotlin/moe/nea/firmament/util/item/NbtItemData.kt +++ b/src/main/kotlin/moe/nea/firmament/util/item/NbtItemData.kt @@ -11,9 +11,13 @@ import net.minecraft.nbt.NbtElement import net.minecraft.nbt.NbtString import net.minecraft.text.Text +fun textFromNbt() { + +} + val ItemStack.loreAccordingToNbt get() = getOrCreateSubNbt(ItemStack.DISPLAY_KEY).getList(ItemStack.LORE_KEY, NbtElement.STRING_TYPE.toInt()) - .map { Text.Serializer.fromJson((it as NbtString).asString()) } + .map { lazy(LazyThreadSafetyMode.NONE) { Text.Serializer.fromJson((it as NbtString).asString()) } } val ItemStack.displayNameAccordingToNbt get() = getOrCreateSubNbt(ItemStack.DISPLAY_KEY).let { |