aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authornea <nea@nea.moe>2023-10-04 16:41:04 +0200
committernea <nea@nea.moe>2023-10-04 16:41:04 +0200
commit64523821d82d702c0bf2d62bbe45a1047aed8bda (patch)
treefe5f25316ddf1895281a932b8fe468b5bc330975
parentd0cc95b1e9a674c41bedc50d1d7923159e2bd6a2 (diff)
downloadFirmament-64523821d82d702c0bf2d62bbe45a1047aed8bda.tar.gz
Firmament-64523821d82d702c0bf2d62bbe45a1047aed8bda.tar.bz2
Firmament-64523821d82d702c0bf2d62bbe45a1047aed8bda.zip
Block selling to NPCs, trading and salvaging UUID locked items
[no changelog]
-rw-r--r--src/main/kotlin/moe/nea/firmament/events/IsSlotProtectedEvent.kt18
-rw-r--r--src/main/kotlin/moe/nea/firmament/features/inventory/SlotLocking.kt66
-rw-r--r--src/main/kotlin/moe/nea/firmament/util/item/NbtItemData.kt6
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 {