Bulk painting

This commit is contained in:
DBotThePony 2023-08-22 11:58:56 +07:00
parent 98e7ea96b2
commit e61d98e54d
Signed by: DBot
GPG Key ID: DCC23B5715498507
6 changed files with 58 additions and 14 deletions

View File

@ -714,6 +714,10 @@ private fun gui(provider: MatteryLanguageProvider) {
with(provider.english) { with(provider.english) {
gui("quicksearch", "Quick search...") gui("quicksearch", "Quick search...")
gui("painter.is_bulk", "Bulk painting")
gui("painter.is_bulk.desc", "Input slot will be automatically refilled from your inventory")
gui("painter.is_bulk.desc2", "Quick moving result will paint as many items as possible from your inventory")
gui("energy_required", "Energy required: %s") gui("energy_required", "Energy required: %s")
gui("insert_priority", "Insert priority") gui("insert_priority", "Insert priority")

View File

@ -716,6 +716,12 @@ private fun gui(provider: MatteryLanguageProvider) {
with(provider.russian) { with(provider.russian) {
gui("quicksearch", "Быстрый поиск...") gui("quicksearch", "Быстрый поиск...")
gui("painter.is_bulk", "Массовая покраска")
gui("painter.is_bulk.desc", "Слот покраски будет автоматически наполняться из вашего инвентаря")
gui("painter.is_bulk.desc2", "Быстрое перемещение покрасит максимальное количество предметов из вашего инвентаря")
gui("energy_required", "Требуется энергии: %s")
gui("insert_priority", "Приоритет вставки") gui("insert_priority", "Приоритет вставки")
gui("extract_priority", "Приоритет забора") gui("extract_priority", "Приоритет забора")
gui("increase", "Увеличить") gui("increase", "Увеличить")

View File

@ -413,14 +413,8 @@ class MatteryPlayerCapability(val ply: Player) : ICapabilityProvider, INBTSerial
private var shouldSendIteration = false private var shouldSendIteration = false
/** private var iteration = 0
* Android' iteration counter (death counter, updating only when Android)
*/
var iteration = 0
private set
private var lastDeathTick = 0 private var lastDeathTick = 0
private val deathLog = ArrayDeque<Pair<Int, Component>>() private val deathLog = ArrayDeque<Pair<Int, Component>>()
private val featureMap = IdentityHashMap<AndroidFeatureType<*>, AndroidFeature>() private val featureMap = IdentityHashMap<AndroidFeatureType<*>, AndroidFeature>()
@ -433,6 +427,8 @@ class MatteryPlayerCapability(val ply: Player) : ICapabilityProvider, INBTSerial
private var nextDischargeHurt = 20 private var nextDischargeHurt = 20
private var nextHealTick = 0 private var nextHealTick = 0
var painterBulkCrafting = false
// players tracking us // players tracking us
// stored separately because EntityTracker and ChunkMup, etc are buried deep and // stored separately because EntityTracker and ChunkMup, etc are buried deep and
// getting them unburied will be a very work intense task // getting them unburied will be a very work intense task
@ -572,6 +568,7 @@ class MatteryPlayerCapability(val ply: Player) : ICapabilityProvider, INBTSerial
savetables.int(::ticksIExist) savetables.int(::ticksIExist)
savetables.int(::iteration) savetables.int(::iteration)
savetables.bool(::painterBulkCrafting)
savetables.bool(::shouldSendIteration) savetables.bool(::shouldSendIteration)
savetables.bool(::wasInLiquid) savetables.bool(::wasInLiquid)
savetables.bool(::isAndroid) savetables.bool(::isAndroid)
@ -584,7 +581,7 @@ class MatteryPlayerCapability(val ply: Player) : ICapabilityProvider, INBTSerial
savetables.int(::nextHealTick) savetables.int(::nextHealTick)
savetables.vector(::lastOutsideLiquid) savetables.vector(::lastOutsideLiquid)
savetables.location(::lastDimension) savetables.codec(::lastDimension, ResourceLocation.CODEC)
savetables.stateful(::exopackSlotModifier, "exoSuitSlotCountModifiers") savetables.stateful(::exopackSlotModifier, "exoSuitSlotCountModifiers")
savetables.stateful(::exopackContainer, "exoSuitContainer") savetables.stateful(::exopackContainer, "exoSuitContainer")

View File

@ -1,5 +1,6 @@
package ru.dbotthepony.mc.otm.client.screen.decorative package ru.dbotthepony.mc.otm.client.screen.decorative
import net.minecraft.ChatFormatting
import net.minecraft.client.gui.GuiGraphics import net.minecraft.client.gui.GuiGraphics
import net.minecraft.network.chat.Component import net.minecraft.network.chat.Component
import net.minecraft.util.RandomSource import net.minecraft.util.RandomSource
@ -18,6 +19,7 @@ import ru.dbotthepony.mc.otm.client.screen.panels.Dock
import ru.dbotthepony.mc.otm.client.screen.panels.DockResizeMode import ru.dbotthepony.mc.otm.client.screen.panels.DockResizeMode
import ru.dbotthepony.mc.otm.client.screen.panels.EditablePanel import ru.dbotthepony.mc.otm.client.screen.panels.EditablePanel
import ru.dbotthepony.mc.otm.client.screen.panels.FramePanel import ru.dbotthepony.mc.otm.client.screen.panels.FramePanel
import ru.dbotthepony.mc.otm.client.screen.panels.button.CheckBoxLabelInputPanel
import ru.dbotthepony.mc.otm.client.screen.panels.button.DeviceControls import ru.dbotthepony.mc.otm.client.screen.panels.button.DeviceControls
import ru.dbotthepony.mc.otm.client.screen.panels.button.LargeRectangleButtonPanel import ru.dbotthepony.mc.otm.client.screen.panels.button.LargeRectangleButtonPanel
import ru.dbotthepony.mc.otm.client.screen.panels.button.RectangleButtonPanel import ru.dbotthepony.mc.otm.client.screen.panels.button.RectangleButtonPanel
@ -30,7 +32,7 @@ import ru.dbotthepony.mc.otm.core.math.RGBAColor
import ru.dbotthepony.mc.otm.menu.decorative.PainterMenu import ru.dbotthepony.mc.otm.menu.decorative.PainterMenu
class PainterScreen(menu: PainterMenu, inventory: Inventory, title: Component) : MatteryScreen<PainterMenu>(menu, inventory, title) { class PainterScreen(menu: PainterMenu, inventory: Inventory, title: Component) : MatteryScreen<PainterMenu>(menu, inventory, title) {
inner class Bar(parent: EditablePanel<*>, val dye: DyeColor) : EditablePanel<PainterScreen>(this@PainterScreen, parent, width = 5f) { private inner class Bar(parent: EditablePanel<*>, val dye: DyeColor) : EditablePanel<PainterScreen>(this@PainterScreen, parent, width = 5f) {
init { init {
dock = Dock.RIGHT dock = Dock.RIGHT
dockLeft = 1f dockLeft = 1f
@ -100,12 +102,22 @@ class PainterScreen(menu: PainterMenu, inventory: Inventory, title: Component) :
.fixed() .fixed()
} }
val canvas = ScrollableCanvasPanel(this, frame) val column = EditablePanel(this, frame)
column.dock = Dock.FILL
val bulk = CheckBoxLabelInputPanel(this, column, menu.isBulk, TranslatableComponent("otm.gui.painter.is_bulk"))
bulk.dock = Dock.BOTTOM
bulk.tooltips.add(TranslatableComponent("otm.gui.painter.is_bulk.desc"))
bulk.tooltips.add(TranslatableComponent("otm.gui.painter.is_bulk.desc2").withStyle(ChatFormatting.GRAY))
bulk.dockBottom = 4f
val canvas = ScrollableCanvasPanel(this, column)
canvas.dock = Dock.FILL canvas.dock = Dock.FILL
val buttons = ArrayList<RectangleButtonPanel<PainterScreen>>() val buttons = ArrayList<RectangleButtonPanel<PainterScreen>>()
menu.listeners.addListener { menu.listeners.addListener {
if (frame.isRemoved) return@addListener
buttons.forEach { it.remove() } buttons.forEach { it.remove() }
buttons.clear() buttons.clear()

View File

@ -46,6 +46,10 @@ interface IContainerSlot : GetterSetter<ItemStack> {
container[slot] = ItemStack.EMPTY container[slot] = ItemStack.EMPTY
} }
fun remove(count: Int): ItemStack {
return container.removeItem(slot, count)
}
override fun get(): ItemStack { override fun get(): ItemStack {
return container[slot] return container[slot]
} }

View File

@ -6,17 +6,21 @@ import net.minecraft.world.entity.player.Player
import net.minecraft.world.item.DyeColor import net.minecraft.world.item.DyeColor
import net.minecraft.world.item.ItemStack import net.minecraft.world.item.ItemStack
import ru.dbotthepony.mc.otm.block.entity.decorative.PainterBlockEntity import ru.dbotthepony.mc.otm.block.entity.decorative.PainterBlockEntity
import ru.dbotthepony.mc.otm.capability.matteryPlayer
import ru.dbotthepony.mc.otm.container.MatteryContainer import ru.dbotthepony.mc.otm.container.MatteryContainer
import ru.dbotthepony.mc.otm.core.ISubscriptable import ru.dbotthepony.mc.otm.core.ISubscriptable
import ru.dbotthepony.mc.otm.core.addAll import ru.dbotthepony.mc.otm.core.addAll
import ru.dbotthepony.mc.otm.core.collect.SupplierMap import ru.dbotthepony.mc.otm.core.collect.SupplierMap
import ru.dbotthepony.mc.otm.core.collect.filter import ru.dbotthepony.mc.otm.core.collect.filter
import ru.dbotthepony.mc.otm.core.collect.find
import ru.dbotthepony.mc.otm.core.collect.maybe
import ru.dbotthepony.mc.otm.core.isNotEmpty import ru.dbotthepony.mc.otm.core.isNotEmpty
import ru.dbotthepony.mc.otm.core.map import ru.dbotthepony.mc.otm.core.map
import ru.dbotthepony.mc.otm.core.util.CreativeMenuItemComparator import ru.dbotthepony.mc.otm.core.util.CreativeMenuItemComparator
import ru.dbotthepony.mc.otm.core.util.ResourceLocationValueCodec import ru.dbotthepony.mc.otm.core.util.ResourceLocationValueCodec
import ru.dbotthepony.mc.otm.menu.MatteryMenu import ru.dbotthepony.mc.otm.menu.MatteryMenu
import ru.dbotthepony.mc.otm.menu.MatterySlot import ru.dbotthepony.mc.otm.menu.MatterySlot
import ru.dbotthepony.mc.otm.menu.input.BooleanInputWithFeedback
import ru.dbotthepony.mc.otm.menu.input.ItemConfigPlayerInput import ru.dbotthepony.mc.otm.menu.input.ItemConfigPlayerInput
import ru.dbotthepony.mc.otm.recipe.PainterRecipe import ru.dbotthepony.mc.otm.recipe.PainterRecipe
import ru.dbotthepony.mc.otm.registry.MMenus import ru.dbotthepony.mc.otm.registry.MMenus
@ -40,6 +44,8 @@ class PainterMenu(
private var lastRecipe: PainterRecipe? = null private var lastRecipe: PainterRecipe? = null
var selectedRecipe by mSynchronizer.Field(null, ResourceLocationValueCodec.nullable).also { it.addListener { rescan() } } var selectedRecipe by mSynchronizer.Field(null, ResourceLocationValueCodec.nullable).also { it.addListener { rescan() } }
val isBulk = BooleanInputWithFeedback(this, true, player.matteryPlayer!!::painterBulkCrafting)
val selectRecipe = PlayerInput(ResourceLocationValueCodec) { val selectRecipe = PlayerInput(ResourceLocationValueCodec) {
selectedRecipe = it selectedRecipe = it
} }
@ -56,13 +62,28 @@ class PainterMenu(
return super.tryRemove(p_150642_, p_150643_, p_150644_) return super.tryRemove(p_150642_, p_150643_, p_150644_)
} }
override fun onTake(p_150645_: Player, p_150646_: ItemStack) { override fun onTake(player: Player, itemStack: ItemStack) {
if (p_150646_.isNotEmpty) { if (itemStack.isNotEmpty) {
lastRecipe?.dyes?.let { tile?.takeDyes(it) } lastRecipe?.dyes?.let { tile?.takeDyes(it) }
inputContainer.removeItem(0, 1)
if (isBulk.value) {
val found = player.matteryPlayer!!.inventoryAndExopack
.slotIterator()
.filter { !it.isForbiddenForAutomation && ItemStack.isSameItemSameTags(it.item, inputSlot.item) }
.maybe()
if (found != null) {
found.remove(1)
rescan()
} else {
inputContainer.removeItem(0, 1)
}
} else {
inputContainer.removeItem(0, 1)
}
} }
super.onTake(p_150645_, p_150646_) super.onTake(player, itemStack)
} }
override fun mayPlace(itemStack: ItemStack): Boolean { override fun mayPlace(itemStack: ItemStack): Boolean {