diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/client/screen/ExopackInventoryScreen.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/client/screen/ExopackInventoryScreen.kt index 7b4ba00f9..ad9426d39 100644 --- a/src/main/kotlin/ru/dbotthepony/mc/otm/client/screen/ExopackInventoryScreen.kt +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/client/screen/ExopackInventoryScreen.kt @@ -272,7 +272,7 @@ class ExopackInventoryScreen(menu: ExopackInventoryMenu) : MatteryScreen) if (menu.sortInventoryInput != null) { - controls.customSortingButtons(menu.sortInventoryInput!!) + controls.sortingButtons(menu.sortInventoryInput!!) } var x = -4f diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/client/screen/MatteryScreen.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/client/screen/MatteryScreen.kt index 051719dfa..02a671a0b 100644 --- a/src/main/kotlin/ru/dbotthepony/mc/otm/client/screen/MatteryScreen.kt +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/client/screen/MatteryScreen.kt @@ -23,7 +23,6 @@ import ru.dbotthepony.mc.otm.client.render.Widgets18 import ru.dbotthepony.mc.otm.client.render.translation import ru.dbotthepony.mc.otm.client.screen.panels.* 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.slot.AbstractSlotPanel import ru.dbotthepony.mc.otm.client.screen.panels.slot.BatterySlotPanel import ru.dbotthepony.mc.otm.client.screen.panels.slot.InventorySlotPanel @@ -308,7 +307,7 @@ abstract class MatteryScreen(menu: T, inventory: Inventory, tit } if (menu.sortInventoryInput != null) { - deviceControls.customSortingButtons(menu.sortInventoryInput!!) + deviceControls.sortingButtons(menu.sortInventoryInput!!) } if (menu.exopackChargeSlots.isNotEmpty()) { diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/client/screen/decorative/CargoCrateScreen.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/client/screen/decorative/CargoCrateScreen.kt index 642fc76eb..26bb90d13 100644 --- a/src/main/kotlin/ru/dbotthepony/mc/otm/client/screen/decorative/CargoCrateScreen.kt +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/client/screen/decorative/CargoCrateScreen.kt @@ -2,15 +2,11 @@ package ru.dbotthepony.mc.otm.client.screen.decorative import net.minecraft.network.chat.Component import net.minecraft.world.entity.player.Inventory -import ru.dbotthepony.mc.otm.client.render.Widgets18 import ru.dbotthepony.mc.otm.client.screen.MatteryScreen import ru.dbotthepony.mc.otm.client.screen.panels.FramePanel 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.util.GridPanel -import ru.dbotthepony.mc.otm.client.screen.panels.slot.SlotPanel import ru.dbotthepony.mc.otm.client.screen.panels.slot.UserFilteredSlotPanel -import ru.dbotthepony.mc.otm.core.TranslatableComponent import ru.dbotthepony.mc.otm.menu.decorative.CargoCrateMenu class CargoCrateScreen(menu: CargoCrateMenu, inventory: Inventory, title: Component) : MatteryScreen(menu, inventory, title) { @@ -28,7 +24,7 @@ class CargoCrateScreen(menu: CargoCrateMenu, inventory: Inventory, title: Compon val controls = DeviceControls(this, frame) - controls.customSortingButtons(menu.sort) + controls.sortingButtons(menu.sort) return frame } diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/client/screen/decorative/MinecartCargoCrateScreen.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/client/screen/decorative/MinecartCargoCrateScreen.kt index 3b9cfbc8f..6a65c2e0f 100644 --- a/src/main/kotlin/ru/dbotthepony/mc/otm/client/screen/decorative/MinecartCargoCrateScreen.kt +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/client/screen/decorative/MinecartCargoCrateScreen.kt @@ -23,7 +23,7 @@ class MinecartCargoCrateScreen(menu: MinecartCargoCrateMenu, inventory: Inventor val controls = DeviceControls(this, frame) - controls.customSortingButtons(menu.sort) + controls.sortingButtons(menu.sort) return frame } diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/client/screen/panels/button/Buttons.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/client/screen/panels/button/Buttons.kt index 0a3b3a331..6775e708b 100644 --- a/src/main/kotlin/ru/dbotthepony/mc/otm/client/screen/panels/button/Buttons.kt +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/client/screen/panels/button/Buttons.kt @@ -32,7 +32,6 @@ import ru.dbotthepony.mc.otm.core.immutableList import ru.dbotthepony.mc.otm.core.math.RelativeSide import ru.dbotthepony.mc.otm.core.util.ItemStackSorter import ru.dbotthepony.mc.otm.core.value -import ru.dbotthepony.mc.otm.menu.IItemStackSortingSettings import ru.dbotthepony.mc.otm.menu.MatteryMenu import ru.dbotthepony.mc.otm.menu.UpgradeSlots import ru.dbotthepony.mc.otm.menu.input.BooleanInputWithFeedback @@ -410,7 +409,7 @@ class DeviceControls>( return result } - fun customSortingButtons(input: MatteryMenu.SortInput) { + fun sortingButtons(input: MatteryMenu.SortInput) { addButton(object : LargeRectangleButtonPanel(screen, this@DeviceControls) { var buttons: List>? = null diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/compat/vanilla/MatteryChestMenu.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/compat/vanilla/MatteryChestMenu.kt new file mode 100644 index 000000000..9092f3e61 --- /dev/null +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/compat/vanilla/MatteryChestMenu.kt @@ -0,0 +1,105 @@ +package ru.dbotthepony.mc.otm.compat.vanilla + +import net.minecraft.client.gui.screens.MenuScreens +import net.minecraft.core.registries.Registries +import net.minecraft.world.Container +import net.minecraft.world.SimpleContainer +import net.minecraft.world.entity.player.Inventory +import net.minecraft.world.entity.player.Player +import net.minecraft.world.flag.FeatureFlags +import net.minecraft.world.inventory.MenuType +import net.minecraftforge.eventbus.api.IEventBus +import net.minecraftforge.fml.event.lifecycle.FMLClientSetupEvent +import net.minecraftforge.registries.DeferredRegister +import ru.dbotthepony.mc.otm.OverdriveThatMatters +import ru.dbotthepony.mc.otm.core.getValue +import ru.dbotthepony.mc.otm.menu.MatteryMenu +import ru.dbotthepony.mc.otm.menu.MatterySlot +import ru.dbotthepony.mc.otm.menu.makeSlots + +class MatteryChestMenu( + type: MenuType<*>, containerId: Int, + inventory: Inventory, val rows: Int, + val container: Container = SimpleContainer(rows * 9) +) : MatteryMenu(type, containerId, inventory) { + val chestSlots = makeSlots(container, ::MatterySlot) + val sort = SortInput(container, playerSortSettings) + + init { + container.startOpen(player) + addStorageSlot(chestSlots) + addInventorySlots() + } + + override fun stillValid(player: Player): Boolean { + return container.stillValid(player) + } + + override fun removed(player: Player) { + super.removed(player) + container.stopOpen(player) + } + + companion object { + private val registrar = DeferredRegister.create(Registries.MENU, OverdriveThatMatters.MOD_ID) + + private val GENERIC_9x1 by registrar.register("generic_9x1") { MenuType(::c9x1, FeatureFlags.VANILLA_SET) } + private val GENERIC_9x2 by registrar.register("generic_9x2") { MenuType(::c9x2, FeatureFlags.VANILLA_SET) } + private val GENERIC_9x3 by registrar.register("generic_9x3") { MenuType(::c9x3, FeatureFlags.VANILLA_SET) } + private val GENERIC_9x4 by registrar.register("generic_9x4") { MenuType(::c9x4, FeatureFlags.VANILLA_SET) } + private val GENERIC_9x5 by registrar.register("generic_9x5") { MenuType(::c9x5, FeatureFlags.VANILLA_SET) } + private val GENERIC_9x6 by registrar.register("generic_9x6") { MenuType(::c9x6, FeatureFlags.VANILLA_SET) } + + @JvmStatic + @JvmOverloads + fun c9x1(containerId: Int, inventory: Inventory, container: Container = SimpleContainer(9)): MatteryChestMenu { + return MatteryChestMenu(GENERIC_9x1, containerId, inventory, 1, container) + } + + @JvmStatic + @JvmOverloads + fun c9x2(containerId: Int, inventory: Inventory, container: Container = SimpleContainer(9 * 2)): MatteryChestMenu { + return MatteryChestMenu(GENERIC_9x2, containerId, inventory, 2, container) + } + + @JvmStatic + @JvmOverloads + fun c9x3(containerId: Int, inventory: Inventory, container: Container = SimpleContainer(9 * 3)): MatteryChestMenu { + return MatteryChestMenu(GENERIC_9x3, containerId, inventory, 3, container) + } + + @JvmStatic + @JvmOverloads + fun c9x4(containerId: Int, inventory: Inventory, container: Container = SimpleContainer(9 * 4)): MatteryChestMenu { + return MatteryChestMenu(GENERIC_9x4, containerId, inventory, 4, container) + } + + @JvmStatic + @JvmOverloads + fun c9x5(containerId: Int, inventory: Inventory, container: Container = SimpleContainer(9 * 5)): MatteryChestMenu { + return MatteryChestMenu(GENERIC_9x5, containerId, inventory, 5, container) + } + + @JvmStatic + @JvmOverloads + fun c9x6(containerId: Int, inventory: Inventory, container: Container = SimpleContainer(9 * 6)): MatteryChestMenu { + return MatteryChestMenu(GENERIC_9x6, containerId, inventory, 6, container) + } + + internal fun register(bus: IEventBus) { + registrar.register(bus) + bus.addListener(this::registerClient) + } + + private fun registerClient(event: FMLClientSetupEvent) { + event.enqueueWork { + MenuScreens.register(GENERIC_9x1, ::MatteryChestScreen) + MenuScreens.register(GENERIC_9x2, ::MatteryChestScreen) + MenuScreens.register(GENERIC_9x3, ::MatteryChestScreen) + MenuScreens.register(GENERIC_9x4, ::MatteryChestScreen) + MenuScreens.register(GENERIC_9x5, ::MatteryChestScreen) + MenuScreens.register(GENERIC_9x6, ::MatteryChestScreen) + } + } + } +} diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/compat/vanilla/MatteryChestScreen.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/compat/vanilla/MatteryChestScreen.kt new file mode 100644 index 000000000..6441ec5ed --- /dev/null +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/compat/vanilla/MatteryChestScreen.kt @@ -0,0 +1,31 @@ +package ru.dbotthepony.mc.otm.compat.vanilla + +import net.minecraft.network.chat.Component +import net.minecraft.world.entity.player.Inventory +import ru.dbotthepony.mc.otm.client.screen.MatteryScreen +import ru.dbotthepony.mc.otm.client.screen.panels.Dock +import ru.dbotthepony.mc.otm.client.screen.panels.FramePanel +import ru.dbotthepony.mc.otm.client.screen.panels.button.DeviceControls +import ru.dbotthepony.mc.otm.client.screen.panels.slot.AbstractSlotPanel +import ru.dbotthepony.mc.otm.client.screen.panels.slot.SlotPanel +import ru.dbotthepony.mc.otm.client.screen.panels.util.GridPanel + +class MatteryChestScreen(menu: MatteryChestMenu, inventory: Inventory, title: Component) : MatteryScreen(menu, inventory, title) { + override fun makeMainFrame(): FramePanel> { + val frame = FramePanel.padded(this, AbstractSlotPanel.SIZE * 9f, AbstractSlotPanel.SIZE * menu.rows, title) + + frame.makeCloseButton() + frame.onClose { onClose() } + + val grid = GridPanel.slots(this, frame, 9, menu.rows) + grid.dock = Dock.FILL + + for (slot in menu.chestSlots) + SlotPanel(this, grid, slot) + + val controls = DeviceControls(this, frame) + controls.sortingButtons(menu.sort) + + return frame + } +} diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/registry/MRegistry.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/registry/MRegistry.kt index 2101c8ab0..b13877590 100644 --- a/src/main/kotlin/ru/dbotthepony/mc/otm/registry/MRegistry.kt +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/registry/MRegistry.kt @@ -35,6 +35,7 @@ import ru.dbotthepony.mc.otm.android.feature.NanobotsArmorFeature import ru.dbotthepony.mc.otm.block.decorative.CargoCrateBlock import ru.dbotthepony.mc.otm.block.decorative.TritaniumPressurePlate import ru.dbotthepony.mc.otm.capability.matteryEnergy +import ru.dbotthepony.mc.otm.compat.vanilla.MatteryChestMenu import ru.dbotthepony.mc.otm.core.math.Decimal import ru.dbotthepony.mc.otm.data.DecimalProvider import ru.dbotthepony.mc.otm.item.weapon.EnergySwordItem @@ -276,6 +277,7 @@ object MRegistry { MLootItemConditions.register(bus) MRecipes.register(bus) StorageStack.register(bus) + MatteryChestMenu.register(bus) if (FMLEnvironment.dist == Dist.CLIENT) { MBlockColors.register(bus) diff --git a/src/main/resources/META-INF/coremods.json b/src/main/resources/META-INF/coremods.json index 0f2a0791b..5ce1ea71b 100644 --- a/src/main/resources/META-INF/coremods.json +++ b/src/main/resources/META-INF/coremods.json @@ -1,3 +1,4 @@ { - "code_injector": "coremods/code_injector.js" + "code_injector": "coremods/code_injector.js", + "chest_menus": "coremods/chest_menus.js" } \ No newline at end of file diff --git a/src/main/resources/coremods/chest_menus.js b/src/main/resources/coremods/chest_menus.js new file mode 100644 index 000000000..588fd0068 --- /dev/null +++ b/src/main/resources/coremods/chest_menus.js @@ -0,0 +1,104 @@ + +var ASMAPI = Java.type('net.minecraftforge.coremod.api.ASMAPI') +var Opcodes = Java.type('org.objectweb.asm.Opcodes') +var MethodNode = Java.type('org.objectweb.asm.tree.MethodNode') +var VarInsnNode = Java.type('org.objectweb.asm.tree.VarInsnNode') +var MethodInsnNode = Java.type('org.objectweb.asm.tree.MethodInsnNode') +var InsnNode = Java.type('org.objectweb.asm.tree.InsnNode') +var TypeInsnNode = Java.type('org.objectweb.asm.tree.TypeInsnNode') + +var classesToPatch = [ + 'net.minecraft.world.entity.vehicle.ChestBoat', + 'net.minecraft.world.level.block.entity.BarrelBlockEntity', + 'net.minecraft.world.level.block.entity.ChestBlockEntity', + 'net.minecraft.world.level.block.EnderChestBlock', + 'net.minecraft.world.entity.vehicle.MinecartChest', + 'net.minecraft.world.level.block.ChestBlock$2$1' +] + +var isOwnPatches = [ + 'net.minecraft.world.level.block.entity.BarrelBlockEntity$1', + 'net.minecraft.world.level.block.entity.ChestBlockEntity$1', +] + +function patchMethod(node) { + if (node.desc.endsWith('AbstractContainerMenu;')) { + var threeRows = ASMAPI.mapMethod('m_39237_') + var sixRows = ASMAPI.mapMethod('m_39246_') + + for (var i = 0; i < node.instructions.size(); i++) { + var instr = node.instructions.get(i) + + if (instr.getOpcode() == Opcodes.INVOKESTATIC && instr.name == threeRows && instr.owner == 'net/minecraft/world/inventory/ChestMenu') { + node.instructions.set(instr, new MethodInsnNode( + Opcodes.INVOKESTATIC, + 'ru/dbotthepony/mc/otm/compat/vanilla/MatteryChestMenu', + 'c9x3', + '(ILnet/minecraft/world/entity/player/Inventory;Lnet/minecraft/world/Container;)Lru/dbotthepony/mc/otm/compat/vanilla/MatteryChestMenu;' + )) + + break + } else if (instr.getOpcode() == Opcodes.INVOKESTATIC && instr.name == sixRows && instr.owner == 'net/minecraft/world/inventory/ChestMenu') { + node.instructions.set(instr, new MethodInsnNode( + Opcodes.INVOKESTATIC, + 'ru/dbotthepony/mc/otm/compat/vanilla/MatteryChestMenu', + 'c9x6', + '(ILnet/minecraft/world/entity/player/Inventory;Lnet/minecraft/world/Container;)Lru/dbotthepony/mc/otm/compat/vanilla/MatteryChestMenu;' + )) + + break + } + } + } +} + +function initializeCoreMod() { + var result = {} + + for (i in classesToPatch) { + var clazz = classesToPatch[i] + + result[clazz] = { + 'target': { + 'type': 'CLASS', + 'name': clazz + }, + 'transformer': function(classNode) { + for (var i = 0; i < classNode.methods.size(); i++) { + patchMethod(classNode.methods.get(i)) + } + + return classNode + } + } + } + + for (i in isOwnPatches) { + var clazz = isOwnPatches[i] + + result[clazz] = { + 'target': { + 'type': 'METHOD', + 'class': clazz, + 'methodName': ASMAPI.mapMethod('m_142718_'), + 'methodDesc': '(Lnet/minecraft/world/entity/player/Player;)Z' + }, + 'transformer': function(node) { + for (var i = 0; i < node.instructions.size(); i++) { + var instr = node.instructions.get(i) + + if ((instr.getOpcode() == Opcodes.INSTANCEOF || instr.getOpcode() == Opcodes.CHECKCAST) && instr.desc == 'net/minecraft/world/inventory/ChestMenu') { + instr.desc = 'ru/dbotthepony/mc/otm/compat/vanilla/MatteryChestMenu' + } else if (instr.getOpcode() == Opcodes.INVOKEVIRTUAL && instr.owner == 'net/minecraft/world/inventory/ChestMenu' && instr.name == ASMAPI.mapMethod('m_39261_')) { + instr.owner = 'ru/dbotthepony/mc/otm/compat/vanilla/MatteryChestMenu' + instr.name = 'getContainer' + } + } + + return node + } + } + } + + return result +}