Portable condensation drive now use new item filter
Item filter now supports tag and nbt matching
This commit is contained in:
parent
86c706a178
commit
89581bbb52
@ -50,6 +50,10 @@ public class FlexGridPanel extends EditablePanel {
|
||||
// список потомков
|
||||
var children = getUndockedChildren();
|
||||
|
||||
if (children.size() == 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
// хранит общую ширину всех потомков в ряд
|
||||
// а так же ограничитель ширины ряда после
|
||||
// определения количества рядов
|
||||
|
@ -233,24 +233,6 @@ public class MatteryNetworking {
|
||||
Optional.of(NetworkDirection.PLAY_TO_CLIENT)
|
||||
);
|
||||
|
||||
CHANNEL.registerMessage(
|
||||
next_network_id++,
|
||||
DriveViewerMenu.FilterSwitchPacket.class,
|
||||
DriveViewerMenu.FilterSwitchPacket::write,
|
||||
DriveViewerMenu.FilterSwitchPacket::read,
|
||||
DriveViewerMenu.FilterSwitchPacket::play,
|
||||
Optional.of(NetworkDirection.PLAY_TO_SERVER)
|
||||
);
|
||||
|
||||
CHANNEL.registerMessage(
|
||||
next_network_id++,
|
||||
DriveViewerMenu.FilterSetPacket.class,
|
||||
DriveViewerMenu.FilterSetPacket::write,
|
||||
DriveViewerMenu.FilterSetPacket::read,
|
||||
DriveViewerMenu.FilterSetPacket::play,
|
||||
Optional.of(NetworkDirection.PLAY_TO_SERVER)
|
||||
);
|
||||
|
||||
CHANNEL.registerMessage(
|
||||
next_network_id++,
|
||||
EnergyCounterPacket.class,
|
||||
|
@ -6,11 +6,8 @@ import net.minecraft.world.entity.player.Inventory
|
||||
import net.minecraft.world.item.ItemStack
|
||||
import ru.dbotthepony.mc.otm.client.screen.panels.*
|
||||
import ru.dbotthepony.mc.otm.client.screen.widget.PowerGaugePanel
|
||||
import ru.dbotthepony.mc.otm.item.PortableCondensationDriveItem.FilterSettings
|
||||
import ru.dbotthepony.mc.otm.item.PortableCondensationDriveItem
|
||||
import ru.dbotthepony.mc.otm.menu.DriveViewerMenu
|
||||
import ru.dbotthepony.mc.otm.menu.DriveViewerMenu.FilterSetPacket
|
||||
import ru.dbotthepony.mc.otm.menu.DriveViewerMenu.FilterSwitchPacket
|
||||
import ru.dbotthepony.mc.otm.network.MatteryNetworking
|
||||
|
||||
class DriveViewerScreen(menu: DriveViewerMenu, inventory: Inventory, title: Component) :
|
||||
MatteryScreen<DriveViewerMenu>(menu, inventory, title) {
|
||||
@ -86,134 +83,13 @@ class DriveViewerScreen(menu: DriveViewerMenu, inventory: Inventory, title: Comp
|
||||
settings.add(dock_left)
|
||||
settings.add(grid_filter)
|
||||
|
||||
for (i in 0 until FilterSettings.MAX_FILTERS) {
|
||||
object : AbstractSlotPanel(this@DriveViewerScreen, grid_filter, 0f, 0f) {
|
||||
override fun getItemStack(): ItemStack {
|
||||
val filter = menu.getFilter() ?: return ItemStack.EMPTY
|
||||
return filter.items[i]
|
||||
}
|
||||
|
||||
private var clicking = false
|
||||
|
||||
override fun mouseClickedInner(mouse_x: Double, mouse_y: Double, mouse_click_type: Int): Boolean {
|
||||
clicking = true
|
||||
return true
|
||||
}
|
||||
|
||||
override fun mouseReleasedInner(mouse_x: Double, mouse_y: Double, flag: Int): Boolean {
|
||||
if (clicking)
|
||||
MatteryNetworking.send(null, FilterSetPacket(menu.containerId, i, menu.carried))
|
||||
|
||||
clicking = false
|
||||
return true
|
||||
}
|
||||
}
|
||||
for (i in 0 until PortableCondensationDriveItem.MAX_FILTERS) {
|
||||
FilterSlotPanel(this, grid_filter, menu.driveFilterSlots[i], 0f, 0f)
|
||||
}
|
||||
|
||||
val no = TranslatableComponent("otm.filter.no")
|
||||
val yes = TranslatableComponent("otm.filter.yes")
|
||||
|
||||
val matchNbt =
|
||||
object : ButtonPanel(this@DriveViewerScreen, dock_left, 0f, 0f, 90f, 20f, TranslatableComponent("otm.filter.match_nbt", no)) {
|
||||
override fun tick() {
|
||||
super.tick()
|
||||
|
||||
val filter = menu.getFilter()
|
||||
if (filter != null) {
|
||||
widget?.message = TranslatableComponent("otm.filter.match_nbt", if (filter.matchNbt) yes else no)
|
||||
widget?.active = !isWidgetDisabled
|
||||
} else {
|
||||
widget?.active = false
|
||||
}
|
||||
}
|
||||
|
||||
override fun onPress() {
|
||||
super.onPress()
|
||||
|
||||
val filter = menu.getFilter()
|
||||
if (filter != null) {
|
||||
MatteryNetworking.send(
|
||||
null,
|
||||
FilterSwitchPacket(
|
||||
menu.containerId,
|
||||
DriveViewerMenu.FilterSwitch.MATCH_NBT,
|
||||
!filter.matchNbt
|
||||
)
|
||||
)
|
||||
|
||||
disableTicks = 20
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
val matchTag =
|
||||
object : ButtonPanel(this@DriveViewerScreen, dock_left, 0f, 0f, 90f, 20f, TranslatableComponent("otm.filter.match_tag", no)) {
|
||||
override fun tick() {
|
||||
super.tick()
|
||||
|
||||
val filter = menu.getFilter()
|
||||
if (filter != null) {
|
||||
widget?.message = TranslatableComponent("otm.filter.match_tag", if (filter.matchTag) yes else no)
|
||||
widget?.active = !isWidgetDisabled
|
||||
} else {
|
||||
widget?.active = false
|
||||
}
|
||||
}
|
||||
|
||||
override fun onPress() {
|
||||
super.onPress()
|
||||
|
||||
val filter = menu.getFilter()
|
||||
if (filter != null) {
|
||||
MatteryNetworking.send(
|
||||
null,
|
||||
FilterSwitchPacket(
|
||||
menu.containerId,
|
||||
DriveViewerMenu.FilterSwitch.MATCH_TAG,
|
||||
!filter.matchTag
|
||||
)
|
||||
)
|
||||
|
||||
disableTicks = 20
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
val blacklist =
|
||||
object : ButtonPanel(this@DriveViewerScreen, dock_left, 0f, 0f, 90f, 20f, TranslatableComponent("otm.filter.blacklist", no)) {
|
||||
override fun tick() {
|
||||
super.tick()
|
||||
|
||||
val filter = menu.getFilter()
|
||||
if (filter != null) {
|
||||
widget?.message = TranslatableComponent("otm.filter.blacklist", if (filter.isBlacklist) yes else no)
|
||||
widget?.active = !isWidgetDisabled
|
||||
} else {
|
||||
widget?.active = false
|
||||
}
|
||||
}
|
||||
|
||||
override fun onPress() {
|
||||
super.onPress()
|
||||
val filter = menu.getFilter()
|
||||
if (filter != null) {
|
||||
MatteryNetworking.send(
|
||||
null,
|
||||
FilterSwitchPacket(
|
||||
menu.containerId,
|
||||
DriveViewerMenu.FilterSwitch.BLACKLIST,
|
||||
!filter.isBlacklist
|
||||
)
|
||||
)
|
||||
|
||||
disableTicks = 20
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
matchNbt.setDockMargin(0f, 4f, 0f, 0f)
|
||||
matchTag.setDockMargin(0f, 4f, 0f, 0f)
|
||||
blacklist.setDockMargin(0f, 4f, 0f, 0f)
|
||||
CheckBoxLabelInputPanel(this, dock_left, menu.isWhitelist, TranslatableComponent("otm.gui.filter.is_whitelist"), width = 90f, height = 20f).also { it.setDockMargin(0f, 4f, 0f, 0f) }
|
||||
CheckBoxLabelInputPanel(this, dock_left, menu.matchTag, TranslatableComponent("otm.gui.filter.match_tag"), width = 90f, height = 20f).also { it.setDockMargin(0f, 4f, 0f, 0f) }
|
||||
CheckBoxLabelInputPanel(this, dock_left, menu.matchNBT, TranslatableComponent("otm.gui.filter.match_nbt"), width = 90f, height = 20f).also { it.setDockMargin(0f, 4f, 0f, 0f) }
|
||||
|
||||
for (panel in settings) {
|
||||
panel.visible = false
|
||||
|
@ -4,6 +4,8 @@ import net.minecraft.nbt.CompoundTag
|
||||
import net.minecraft.nbt.ListTag
|
||||
import net.minecraft.network.FriendlyByteBuf
|
||||
import net.minecraft.server.level.ServerPlayer
|
||||
import net.minecraft.tags.TagKey
|
||||
import net.minecraft.world.item.Item
|
||||
import net.minecraft.world.item.ItemStack
|
||||
import net.minecraftforge.common.util.INBTSerializable
|
||||
import net.minecraftforge.network.NetworkEvent
|
||||
@ -12,6 +14,7 @@ import ru.dbotthepony.mc.otm.client.minecraft
|
||||
import ru.dbotthepony.mc.otm.ifHas
|
||||
import ru.dbotthepony.mc.otm.menu.MatteryMenu
|
||||
import ru.dbotthepony.mc.otm.set
|
||||
import java.util.Arrays
|
||||
import java.util.LinkedList
|
||||
import java.util.function.Supplier
|
||||
|
||||
@ -42,7 +45,12 @@ data class ItemFilterSlotPacket(val slotID: Int, val newValue: ItemStack) {
|
||||
|
||||
fun playServer(player: ServerPlayer) {
|
||||
val menu = player.containerMenu as? MatteryMenu ?: return LOGGER.error("No MatteryMenu is open right now, can't handle ItemFilterSlotReplicaPacket from $player")
|
||||
menu.filterSlots.getOrNull(slotID)?.set(newValue) //?: LOGGER.error("ItemFilterSlotReplicaPacket: unknown slot $slotID from $player in $menu!")
|
||||
val slot = menu.filterSlots.getOrNull(slotID) ?: return LOGGER.error("ItemFilterSlotReplicaPacket: unknown slot $slotID from $player in $menu!")
|
||||
|
||||
if (slot.filter?.isLocked == true)
|
||||
return
|
||||
|
||||
slot.set(newValue)
|
||||
}
|
||||
|
||||
companion object {
|
||||
@ -54,11 +62,11 @@ data class ItemFilterSlotPacket(val slotID: Int, val newValue: ItemStack) {
|
||||
}
|
||||
}
|
||||
|
||||
data class ItemFilterNetworkSlot(val slotID: Int, val networkID: Int, val filter: ItemFilter?) {
|
||||
data class ItemFilterNetworkSlot(val slotID: Int, val networkID: Int, var filter: ItemFilter?) {
|
||||
fun get() = filter?.get(slotID) ?: remote
|
||||
fun set(value: ItemStack) {
|
||||
if (filter != null)
|
||||
filter[slotID] = value
|
||||
filter!![slotID] = value
|
||||
else
|
||||
remote = value
|
||||
}
|
||||
@ -77,21 +85,85 @@ data class ItemFilterNetworkSlot(val slotID: Int, val networkID: Int, val filter
|
||||
}
|
||||
}
|
||||
|
||||
fun interface ItemFilterCallback {
|
||||
fun invoke(slot: Int?, oldValue: ItemStack?, newValue: ItemStack?)
|
||||
}
|
||||
|
||||
fun interface ItemFilterFullCallback {
|
||||
fun invoke(self: ItemFilter, slot: Int?, oldValue: ItemStack?, newValue: ItemStack?)
|
||||
}
|
||||
|
||||
class ItemFilter(
|
||||
val size: Int,
|
||||
private val modified: (slot: Int?, oldValue: ItemStack?, newValue: ItemStack?) -> Unit
|
||||
private val modified: ItemFilterFullCallback? = null
|
||||
) : INBTSerializable<CompoundTag> {
|
||||
constructor(size: Int, modified: ItemFilterCallback?) :
|
||||
this(size,
|
||||
modified?.let {
|
||||
fn ->
|
||||
return@let ItemFilterFullCallback { _: ItemFilter, slot: Int?, oldValue: ItemStack?, newValue: ItemStack? -> fn.invoke(slot, oldValue, newValue) }
|
||||
})
|
||||
|
||||
private val filter = Array<ItemStack>(size) { ItemStack.EMPTY }
|
||||
private val linkedFilter = LinkedList<ItemStack>()
|
||||
|
||||
var isLocked = false
|
||||
|
||||
var isWhitelist = false
|
||||
set(value) {
|
||||
if (value != field) {
|
||||
field = value
|
||||
modified.invoke(null, null, null)
|
||||
modified?.invoke(this, null, null, null)
|
||||
}
|
||||
}
|
||||
|
||||
var matchTag = false
|
||||
set(value) {
|
||||
if (value != field) {
|
||||
field = value
|
||||
modified?.invoke(this, null, null, null)
|
||||
}
|
||||
}
|
||||
|
||||
var matchNBT = false
|
||||
set(value) {
|
||||
if (value != field) {
|
||||
field = value
|
||||
modified?.invoke(this, null, null, null)
|
||||
}
|
||||
}
|
||||
|
||||
fun clear() {
|
||||
isWhitelist = false
|
||||
matchTag = false
|
||||
matchNBT = false
|
||||
|
||||
Arrays.fill(filter, ItemStack.EMPTY)
|
||||
linkedFilter.clear()
|
||||
|
||||
modified?.invoke(this, null, null, null)
|
||||
}
|
||||
|
||||
fun copyFrom(other: ItemFilter) {
|
||||
require(other.size == size) { "Size differs (this filter has size of $size, other has size of ${other.size})" }
|
||||
|
||||
linkedFilter.clear()
|
||||
|
||||
for (i in 0 until size) {
|
||||
filter[i] = other.filter[i]
|
||||
|
||||
if (!filter[i].isEmpty) {
|
||||
linkedFilter.add(filter[i])
|
||||
}
|
||||
}
|
||||
|
||||
isWhitelist = other.isWhitelist
|
||||
matchTag = other.matchTag
|
||||
matchNBT = other.matchNBT
|
||||
|
||||
modified?.invoke(this, null, null, null)
|
||||
}
|
||||
|
||||
operator fun set(index: Int, value: ItemStack) {
|
||||
if (value.isEmpty && filter[index].isEmpty) {
|
||||
return
|
||||
@ -100,14 +172,17 @@ class ItemFilter(
|
||||
val old = filter[index]
|
||||
filter[index] = value.let { if (!it.isEmpty) it.copy().also { it.count = 1 } else it }
|
||||
|
||||
if (!filter[index].isEmpty && filter[index].tag != null && filter[index].tag!!.isEmpty) {
|
||||
filter[index].tag = null
|
||||
}
|
||||
|
||||
if (!old.isEmpty)
|
||||
linkedFilter.remove(old)
|
||||
|
||||
if (!filter[index].isEmpty)
|
||||
linkedFilter.add(filter[index])
|
||||
|
||||
modified.invoke(index, old, filter[index])
|
||||
|
||||
modified?.invoke(this, index, old, filter[index])
|
||||
}
|
||||
|
||||
operator fun get(index: Int): ItemStack = filter[index].copy()
|
||||
@ -121,24 +196,48 @@ class ItemFilter(
|
||||
return !isWhitelist
|
||||
}
|
||||
|
||||
if (isWhitelist) {
|
||||
for (item in linkedFilter) {
|
||||
if (item.`is`(value.item)) {
|
||||
return true
|
||||
for (item in linkedFilter) {
|
||||
var matched = item.`is`(value.item)
|
||||
|
||||
if (matched && matchTag) {
|
||||
matched = false
|
||||
|
||||
val thisTags = item.tags
|
||||
val stackTags = HashSet<TagKey<Item>>()
|
||||
|
||||
for (tag in value.tags) {
|
||||
stackTags.add(tag)
|
||||
}
|
||||
|
||||
for (tag1 in thisTags) {
|
||||
if (stackTags.contains(tag1)) {
|
||||
matched = true
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return false
|
||||
}
|
||||
if (matched && matchNBT) {
|
||||
val a = item.tag
|
||||
val b = value.tag
|
||||
|
||||
if (a == null && b == null) {
|
||||
// nothing
|
||||
} else if (a != null && b != null) {
|
||||
matched = a == b
|
||||
} else if (a != null) {
|
||||
matched = a.isEmpty
|
||||
} else {
|
||||
matched = false
|
||||
}
|
||||
}
|
||||
|
||||
for (item in linkedFilter) {
|
||||
if (item.`is`(value.item)) {
|
||||
return false
|
||||
if (matched) {
|
||||
return isWhitelist
|
||||
}
|
||||
}
|
||||
|
||||
return true
|
||||
return !isWhitelist
|
||||
}
|
||||
|
||||
override fun serializeNBT(): CompoundTag {
|
||||
@ -150,6 +249,8 @@ class ItemFilter(
|
||||
}
|
||||
|
||||
it["is_whitelist"] = isWhitelist
|
||||
it["match_tag"] = matchTag
|
||||
it["match_nbt"] = matchNBT
|
||||
}
|
||||
}
|
||||
|
||||
@ -169,5 +270,7 @@ class ItemFilter(
|
||||
}
|
||||
|
||||
isWhitelist = nbt.getBoolean("is_whitelist")
|
||||
matchTag = nbt.getBoolean("match_tag")
|
||||
matchNBT = nbt.getBoolean("match_nbt")
|
||||
}
|
||||
}
|
||||
|
@ -24,7 +24,9 @@ import net.minecraftforge.event.ForgeEventFactory
|
||||
import net.minecraftforge.eventbus.api.SubscribeEvent
|
||||
import net.minecraftforge.event.entity.player.EntityItemPickupEvent
|
||||
import ru.dbotthepony.mc.otm.capability.drive.DrivePool
|
||||
import ru.dbotthepony.mc.otm.container.ItemFilter
|
||||
import ru.dbotthepony.mc.otm.core.ImpreciseFraction
|
||||
import ru.dbotthepony.mc.otm.ifHas
|
||||
import ru.dbotthepony.mc.otm.set
|
||||
import java.util.*
|
||||
|
||||
@ -92,117 +94,18 @@ class PortableCondensationDriveItem(capacity: Int) :
|
||||
return DriveCapability(stack)
|
||||
}
|
||||
|
||||
class FilterSettings() {
|
||||
@JvmField
|
||||
val items = Array<ItemStack>(MAX_FILTERS) { ItemStack.EMPTY }
|
||||
|
||||
@JvmField
|
||||
var matchNbt = false
|
||||
|
||||
@JvmField
|
||||
var matchTag = false
|
||||
|
||||
@JvmField
|
||||
var isBlacklist = false
|
||||
|
||||
constructor(tag: CompoundTag) : this() {
|
||||
val list = tag.getList("filter", Tag.TAG_COMPOUND.toInt())
|
||||
var i = 0
|
||||
|
||||
for (tag in list) {
|
||||
if (tag is CompoundTag) {
|
||||
items[i++] = ItemStack.of(tag)
|
||||
}
|
||||
}
|
||||
|
||||
matchNbt = tag.getBoolean("match_nbt")
|
||||
matchTag = tag.getBoolean("match_tag")
|
||||
isBlacklist = tag.getBoolean("blacklist")
|
||||
}
|
||||
|
||||
fun serializeNBT(compound: CompoundTag) {
|
||||
val list = ListTag()
|
||||
|
||||
for (i in 0 until MAX_FILTERS) {
|
||||
list.add(items[i].serializeNBT())
|
||||
}
|
||||
|
||||
compound["filter"] = list
|
||||
compound["match_nbt"] = matchNbt
|
||||
compound["match_tag"] = matchTag
|
||||
compound["blacklist"] = isBlacklist
|
||||
}
|
||||
|
||||
fun serializeNBT(drive: ItemStack) {
|
||||
serializeNBT(drive.orCreateTag)
|
||||
}
|
||||
|
||||
fun matches(stack: ItemStack): Boolean {
|
||||
if (isBlacklist) {
|
||||
for (item in items) {
|
||||
if (!matchNbt && ItemStack.isSame(item, stack)) {
|
||||
return false
|
||||
}
|
||||
|
||||
if (matchTag) {
|
||||
val thisTags = item.tags
|
||||
val stackTatgs = stack.tags.toArray()
|
||||
|
||||
for (tag1 in thisTags) {
|
||||
if (stackTatgs.contains(tag1)) {
|
||||
return false
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (matchNbt && ItemStack.isSameItemSameTags(item, stack)) {
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
return true
|
||||
} else {
|
||||
for (item in items) {
|
||||
var same = ItemStack.isSame(item, stack)
|
||||
|
||||
if (!same && matchTag) {
|
||||
val thisTags = item.tags
|
||||
val stackTatgs = stack.tags.toArray()
|
||||
|
||||
for (tag1 in thisTags) {
|
||||
if (stackTatgs.contains(tag1)) {
|
||||
same = true
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (matchNbt) {
|
||||
if (same && ItemStack.tagMatches(item, stack)) {
|
||||
return true
|
||||
}
|
||||
} else {
|
||||
if (same) {
|
||||
return true
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
companion object {
|
||||
const val MAX_FILTERS = 12
|
||||
}
|
||||
}
|
||||
|
||||
fun getFilterSettings(drive: ItemStack): FilterSettings {
|
||||
return FilterSettings(drive.orCreateTag)
|
||||
fun getFilterSettings(drive: ItemStack): ItemFilter {
|
||||
val filter = ItemFilter(MAX_FILTERS)
|
||||
filter.isWhitelist = true
|
||||
drive.tag?.ifHas(FILTER_PATH, CompoundTag::class.java, filter::deserializeNBT)
|
||||
return filter
|
||||
}
|
||||
|
||||
@Suppress("unused")
|
||||
companion object {
|
||||
const val MAX_FILTERS = 4 * 3
|
||||
const val FILTER_PATH = "filter"
|
||||
|
||||
@SubscribeEvent
|
||||
fun onPickupEvent(event: EntityItemPickupEvent) {
|
||||
if (event.item.owner != null && event.item.owner != event.player.uuid && event.item.age < 200) {
|
||||
@ -221,7 +124,7 @@ class PortableCondensationDriveItem(capacity: Int) :
|
||||
stack.getCapability(MatteryCapability.DRIVE).ifPresent {
|
||||
val filter = drive.getFilterSettings(stack)
|
||||
|
||||
if (filter.matches(event.item.item)) {
|
||||
if (filter.match(event.item.item)) {
|
||||
val copy = event.item.item.copy()
|
||||
val remaining = (it as ItemMatteryDrive).insertStack(event.item.item, false)
|
||||
|
||||
|
@ -1,24 +1,23 @@
|
||||
package ru.dbotthepony.mc.otm.menu
|
||||
|
||||
import net.minecraft.network.FriendlyByteBuf
|
||||
import net.minecraft.world.SimpleContainer
|
||||
import net.minecraft.world.entity.player.Inventory
|
||||
import net.minecraft.world.entity.player.Player
|
||||
import net.minecraft.world.item.ItemStack
|
||||
import net.minecraftforge.energy.CapabilityEnergy
|
||||
import net.minecraftforge.network.NetworkEvent
|
||||
import ru.dbotthepony.mc.otm.OverdriveThatMatters
|
||||
import ru.dbotthepony.mc.otm.block.entity.DriveViewerBlockEntity
|
||||
import ru.dbotthepony.mc.otm.capability.MatteryCapability
|
||||
import ru.dbotthepony.mc.otm.capability.drive.IMatteryDrive
|
||||
import ru.dbotthepony.mc.otm.container.ItemFilter
|
||||
import ru.dbotthepony.mc.otm.ifPresentK
|
||||
import ru.dbotthepony.mc.otm.item.PortableCondensationDriveItem
|
||||
import ru.dbotthepony.mc.otm.item.PortableCondensationDriveItem.FilterSettings
|
||||
import ru.dbotthepony.mc.otm.menu.data.INetworkedItemViewSupplier
|
||||
import ru.dbotthepony.mc.otm.menu.data.NetworkedItemView
|
||||
import ru.dbotthepony.mc.otm.menu.widget.BooleanPlayerInputWidget
|
||||
import ru.dbotthepony.mc.otm.registry.MMenus
|
||||
import ru.dbotthepony.mc.otm.storage.ITEM_STORAGE
|
||||
import ru.dbotthepony.mc.otm.storage.ItemStackWrapper
|
||||
import ru.dbotthepony.mc.otm.storage.PoweredVirtualComponent
|
||||
import java.util.function.Supplier
|
||||
|
||||
class DriveViewerMenu @JvmOverloads constructor(
|
||||
containerID: Int,
|
||||
@ -27,9 +26,10 @@ class DriveViewerMenu @JvmOverloads constructor(
|
||||
) : MatteryPoweredMenu(
|
||||
MMenus.DRIVE_VIEWER, containerID, inventory, tile
|
||||
), INetworkedItemViewSupplier {
|
||||
val view: NetworkedItemView
|
||||
private val powered: PoweredVirtualComponent<ItemStackWrapper>?
|
||||
val view = NetworkedItemView(inventory.player, this, tile == null)
|
||||
val driveSlot: MatterySlot
|
||||
|
||||
private val powered: PoweredVirtualComponent<ItemStackWrapper>?
|
||||
private var lastDrive: IMatteryDrive<ItemStackWrapper>? = null
|
||||
|
||||
override fun getNetworkedItemView() = view
|
||||
@ -43,8 +43,6 @@ class DriveViewerMenu @JvmOverloads constructor(
|
||||
}
|
||||
}
|
||||
|
||||
view = NetworkedItemView(inventory.player, this, tile == null)
|
||||
|
||||
if (tile != null) {
|
||||
powered = PoweredVirtualComponent(
|
||||
ItemStackWrapper::class.java,
|
||||
@ -60,6 +58,26 @@ class DriveViewerMenu @JvmOverloads constructor(
|
||||
addInventorySlots()
|
||||
}
|
||||
|
||||
val driveFilter = ItemFilter(PortableCondensationDriveItem.MAX_FILTERS) { self, _, _, _ ->
|
||||
if (tile?.container?.get(0)?.item is PortableCondensationDriveItem) {
|
||||
tile.container[0].getOrCreateTag().put(PortableCondensationDriveItem.FILTER_PATH, self.serializeNBT())
|
||||
}
|
||||
}
|
||||
|
||||
val driveFilterSlots = addFilterSlots(driveFilter)
|
||||
|
||||
val isWhitelist = BooleanPlayerInputWidget(this)
|
||||
val matchTag = BooleanPlayerInputWidget(this)
|
||||
val matchNBT = BooleanPlayerInputWidget(this)
|
||||
|
||||
init {
|
||||
if (tile == null) {
|
||||
isWhitelist.asClient()
|
||||
matchTag.asClient()
|
||||
matchNBT.asClient()
|
||||
}
|
||||
}
|
||||
|
||||
override fun broadcastChanges() {
|
||||
super.broadcastChanges()
|
||||
|
||||
@ -70,21 +88,44 @@ class DriveViewerMenu @JvmOverloads constructor(
|
||||
lastDrive = null
|
||||
|
||||
if (!itemStack.isEmpty) {
|
||||
itemStack.getCapability(MatteryCapability.DRIVE).ifPresent {
|
||||
if (it.storageType === OverdriveThatMatters.INSTANCE.ITEM_STORAGE()) {
|
||||
itemStack.getCapability(MatteryCapability.DRIVE).ifPresentK {
|
||||
if (it.storageType === ITEM_STORAGE) {
|
||||
lastDrive = it as IMatteryDrive<ItemStackWrapper>
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (prev != lastDrive) {
|
||||
if (prev != null)
|
||||
powered!!.remove(prev)
|
||||
|
||||
prev?.let(powered!!::remove)
|
||||
view.clear()
|
||||
lastDrive?.let(powered!!::add)
|
||||
|
||||
if (lastDrive != null)
|
||||
powered!!.add(lastDrive!!)
|
||||
if (lastDrive != null) {
|
||||
val filter = (itemStack.item as? PortableCondensationDriveItem)?.getFilterSettings(itemStack)
|
||||
|
||||
if (filter != null) {
|
||||
driveFilter.copyFrom(filter)
|
||||
driveFilter.isLocked = false
|
||||
|
||||
isWhitelist.withProperty(driveFilter::isWhitelist)
|
||||
matchTag.withProperty(driveFilter::matchTag)
|
||||
matchNBT.withProperty(driveFilter::matchNBT)
|
||||
} else {
|
||||
driveFilter.clear()
|
||||
driveFilter.isLocked = true
|
||||
|
||||
isWhitelist.withoutAnything()
|
||||
matchTag.withoutAnything()
|
||||
matchNBT.withoutAnything()
|
||||
}
|
||||
} else {
|
||||
driveFilter.clear()
|
||||
driveFilter.isLocked = true
|
||||
|
||||
isWhitelist.withoutAnything()
|
||||
matchTag.withoutAnything()
|
||||
matchNBT.withoutAnything()
|
||||
}
|
||||
}
|
||||
|
||||
view.network()
|
||||
@ -102,10 +143,10 @@ class DriveViewerMenu @JvmOverloads constructor(
|
||||
override fun removed(p_38940_: Player) {
|
||||
super.removed(p_38940_)
|
||||
|
||||
if (powered != null)
|
||||
lastDrive?.removeListener(powered)
|
||||
if (lastDrive != null)
|
||||
powered?.remove(lastDrive!!)
|
||||
|
||||
view.clear()
|
||||
view.removed()
|
||||
}
|
||||
|
||||
override fun quickMoveStack(ply: Player, slot_index: Int): ItemStack {
|
||||
@ -135,107 +176,4 @@ class DriveViewerMenu @JvmOverloads constructor(
|
||||
slot.setChanged()
|
||||
return copy
|
||||
}
|
||||
|
||||
enum class FilterSwitch {
|
||||
MATCH_NBT, MATCH_TAG, BLACKLIST
|
||||
}
|
||||
|
||||
fun getFilter(): FilterSettings? {
|
||||
if (driveSlot.item.isEmpty)
|
||||
return null
|
||||
|
||||
val item = driveSlot.item.item
|
||||
return if (item is PortableCondensationDriveItem) item.getFilterSettings(driveSlot.item) else null
|
||||
}
|
||||
|
||||
class FilterSetPacket(val id: Int, val slot: Int, val value: ItemStack) {
|
||||
fun write(buffer: FriendlyByteBuf) {
|
||||
buffer.writeInt(id)
|
||||
buffer.writeInt(slot)
|
||||
buffer.writeItem(value)
|
||||
}
|
||||
|
||||
fun play(context: Supplier<NetworkEvent.Context>) {
|
||||
context.get().packetHandled = true
|
||||
|
||||
if (slot < 0 || slot >= FilterSettings.MAX_FILTERS)
|
||||
return
|
||||
|
||||
if (value.count > 1)
|
||||
value.count = 1
|
||||
|
||||
context.get().enqueueWork {
|
||||
val ply = context.get().sender!!
|
||||
val menu = ply.containerMenu
|
||||
|
||||
if (menu is DriveViewerMenu && menu.containerId == id) {
|
||||
if (menu.driveSlot.item.isEmpty)
|
||||
return@enqueueWork
|
||||
|
||||
val itemStack = menu.driveSlot.item
|
||||
val item = itemStack.item
|
||||
|
||||
if (item is PortableCondensationDriveItem) {
|
||||
val filter = item.getFilterSettings(itemStack)
|
||||
filter.items[slot] = value
|
||||
filter.serializeNBT(itemStack)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
companion object {
|
||||
@JvmStatic
|
||||
fun read(buffer: FriendlyByteBuf): FilterSetPacket {
|
||||
return FilterSetPacket(buffer.readInt(), buffer.readInt(), buffer.readItem())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class FilterSwitchPacket(val id: Int, val type: FilterSwitch, val value: Boolean) {
|
||||
fun write(buffer: FriendlyByteBuf) {
|
||||
buffer.writeInt(id)
|
||||
buffer.writeEnum(type)
|
||||
buffer.writeBoolean(value)
|
||||
}
|
||||
|
||||
fun play(context: Supplier<NetworkEvent.Context>) {
|
||||
context.get().packetHandled = true
|
||||
context.get().enqueueWork {
|
||||
val ply = context.get().sender!!
|
||||
val menu = ply.containerMenu
|
||||
|
||||
if (menu is DriveViewerMenu && menu.containerId == id) {
|
||||
val settings = menu.getFilter() ?: return@enqueueWork
|
||||
|
||||
when (type) {
|
||||
FilterSwitch.MATCH_NBT -> {
|
||||
settings.matchNbt = value
|
||||
}
|
||||
|
||||
FilterSwitch.MATCH_TAG -> {
|
||||
settings.matchTag = value
|
||||
}
|
||||
|
||||
FilterSwitch.BLACKLIST -> {
|
||||
settings.isBlacklist = value
|
||||
}
|
||||
}
|
||||
|
||||
settings.serializeNBT(menu.driveSlot.item)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
companion object {
|
||||
@JvmStatic
|
||||
fun read(buffer: FriendlyByteBuf): FilterSwitchPacket {
|
||||
return FilterSwitchPacket(
|
||||
buffer.readInt(),
|
||||
buffer.readEnum(FilterSwitch::class.java),
|
||||
buffer.readBoolean()
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -55,6 +55,18 @@ class BooleanPlayerInputWidget(menu: MatteryMenu) : AbstractWidget(menu) {
|
||||
return this
|
||||
}
|
||||
|
||||
fun withProperty(state: KMutableProperty0<Boolean>): BooleanPlayerInputWidget {
|
||||
withClicker { state.set(it) }
|
||||
withSupplier { state.get() }
|
||||
return this
|
||||
}
|
||||
|
||||
fun withoutAnything(): BooleanPlayerInputWidget {
|
||||
supplier = null
|
||||
clicker = null
|
||||
return this
|
||||
}
|
||||
|
||||
fun asClient(): BooleanPlayerInputWidget {
|
||||
supplier = null
|
||||
clicker = {
|
||||
|
@ -35,13 +35,13 @@ open class VirtualComponent<T : IStorageStack>(type: StorageStackType<T>) : IVir
|
||||
override val storageType: StorageStackType<T> = type
|
||||
|
||||
// удаленный UUID -> Кортеж
|
||||
protected val remoteByUUID: MutableMap<UUID, RemoteTuple<T>> = HashMap()
|
||||
protected val remoteByUUID = HashMap<UUID, RemoteTuple<T>>()
|
||||
|
||||
// локальный UUID -> Локальный кортеж
|
||||
protected val localByUUID: MutableMap<UUID, LocalTuple<T>> = HashMap()
|
||||
protected val localByUUID = HashMap<UUID, LocalTuple<T>>()
|
||||
|
||||
// Стак -> Локальный кортеж стака
|
||||
protected val tuples: MutableMap<T, LocalTuple<T>> = HashMap()
|
||||
protected val tuples = HashMap<T, LocalTuple<T>>()
|
||||
|
||||
// ArrayList для скорости работы
|
||||
protected val listeners = ArrayList<IStorageListener<T>>()
|
||||
|
@ -36,6 +36,8 @@
|
||||
"otm.gui.matter.name": "MtU",
|
||||
|
||||
"otm.gui.filter.is_whitelist": "Is Whitelist",
|
||||
"otm.gui.filter.match_nbt": "Match NBT",
|
||||
"otm.gui.filter.match_tag": "Match Tag",
|
||||
|
||||
"otm.gui.android_research": "Research Tree",
|
||||
|
||||
@ -88,10 +90,6 @@
|
||||
"otm.filter.yes": "Yes",
|
||||
"otm.filter.no": "No",
|
||||
|
||||
"otm.filter.match_nbt": "Match NBT: %s",
|
||||
"otm.filter.match_tag": "Match Tag: %s",
|
||||
"otm.filter.blacklist": "Blacklist: %s",
|
||||
|
||||
"otm.matter_bottler.switch_mode": "Switch work mode",
|
||||
|
||||
"android_feature.overdrive_that_matters.air_bags": "Air Bags",
|
||||
|
Loading…
Reference in New Issue
Block a user