diff --git a/plugin/rei/src/main/kotlin/net/shadowfacts/phycon/plugin/rei/PhyConPlugin.kt b/plugin/rei/src/main/kotlin/net/shadowfacts/phycon/plugin/rei/PhyConPlugin.kt index 2d36745..b4c66af 100644 --- a/plugin/rei/src/main/kotlin/net/shadowfacts/phycon/plugin/rei/PhyConPlugin.kt +++ b/plugin/rei/src/main/kotlin/net/shadowfacts/phycon/plugin/rei/PhyConPlugin.kt @@ -34,8 +34,8 @@ object PhyConPlugin: ClientModInitializer, REIPluginV0 { override fun registerBounds(helper: DisplayHelper) { BaseBoundsHandler.getInstance().registerExclusionZones(TerminalScreen::class.java) { val screen = MinecraftClient.getInstance().currentScreen as TerminalScreen - val button = screen.terminalVC.sortMode - val rect = button.convert(button.bounds, to = null) + val view = screen.terminalVC.settingsView + val rect = view.convert(view.bounds, to = null) listOf( Rectangle(rect.left.toInt(), rect.top.toInt(), 20, 20) ) diff --git a/src/main/java/net/shadowfacts/phycon/api/PhyConAPI.java b/src/main/java/net/shadowfacts/phycon/api/PhyConAPI.java new file mode 100644 index 0000000..7877ffb --- /dev/null +++ b/src/main/java/net/shadowfacts/phycon/api/PhyConAPI.java @@ -0,0 +1,14 @@ +package net.shadowfacts.phycon.api; + +import net.minecraft.util.Identifier; +import org.jetbrains.annotations.NotNull; + +/** + * @author shadowfacts + */ +public interface PhyConAPI { + + @NotNull + & TerminalSetting> TerminalSettingKey registerTerminalSetting(Identifier id, E defaultValue); + +} diff --git a/src/main/java/net/shadowfacts/phycon/api/PhyConPlugin.java b/src/main/java/net/shadowfacts/phycon/api/PhyConPlugin.java new file mode 100644 index 0000000..6ea49ca --- /dev/null +++ b/src/main/java/net/shadowfacts/phycon/api/PhyConPlugin.java @@ -0,0 +1,10 @@ +package net.shadowfacts.phycon.api; + +/** + * @author shadowfacts + */ +public interface PhyConPlugin { + + void initializePhyCon(PhyConAPI api); + +} diff --git a/src/main/java/net/shadowfacts/phycon/api/TerminalSetting.java b/src/main/java/net/shadowfacts/phycon/api/TerminalSetting.java new file mode 100644 index 0000000..fbeb93c --- /dev/null +++ b/src/main/java/net/shadowfacts/phycon/api/TerminalSetting.java @@ -0,0 +1,18 @@ +package net.shadowfacts.phycon.api; + +import net.minecraft.text.Text; +import net.minecraft.util.Identifier; +import org.jetbrains.annotations.Nullable; + +/** + * @author shadowfacts + */ +public interface TerminalSetting { + + Identifier getIconTexture(); + + int[] getUV(); + + @Nullable Text getTooltip(); + +} diff --git a/src/main/java/net/shadowfacts/phycon/api/TerminalSettingKey.java b/src/main/java/net/shadowfacts/phycon/api/TerminalSettingKey.java new file mode 100644 index 0000000..f109ea6 --- /dev/null +++ b/src/main/java/net/shadowfacts/phycon/api/TerminalSettingKey.java @@ -0,0 +1,14 @@ +package net.shadowfacts.phycon.api; + +import net.minecraft.util.Identifier; + +/** + * @author shadowfacts + */ +public interface TerminalSettingKey & TerminalSetting> { + + Identifier getID(); + + E getValue(); + +} diff --git a/src/main/kotlin/net/shadowfacts/cacao/view/TextureView.kt b/src/main/kotlin/net/shadowfacts/cacao/view/TextureView.kt index b261089..9a082c6 100644 --- a/src/main/kotlin/net/shadowfacts/cacao/view/TextureView.kt +++ b/src/main/kotlin/net/shadowfacts/cacao/view/TextureView.kt @@ -11,10 +11,12 @@ import net.shadowfacts.cacao.util.texture.Texture * * @author shadowfacts */ -class TextureView(var texture: Texture): View() { +class TextureView(var texture: Texture?): View() { override fun drawContent(matrixStack: MatrixStack, mouse: Point, delta: Float) { - RenderHelper.draw(matrixStack, bounds, texture) + texture?.also { + RenderHelper.draw(matrixStack, bounds, it) + } } } diff --git a/src/main/kotlin/net/shadowfacts/phycon/DefaultPlugin.kt b/src/main/kotlin/net/shadowfacts/phycon/DefaultPlugin.kt new file mode 100644 index 0000000..98de308 --- /dev/null +++ b/src/main/kotlin/net/shadowfacts/phycon/DefaultPlugin.kt @@ -0,0 +1,21 @@ +package net.shadowfacts.phycon + +import net.minecraft.util.Identifier +import net.shadowfacts.phycon.api.PhyConAPI +import net.shadowfacts.phycon.api.PhyConPlugin +import net.shadowfacts.phycon.api.TerminalSettingKey +import net.shadowfacts.phycon.util.SortMode + +/** + * @author shadowfacts + */ +object DefaultPlugin: PhyConPlugin { + + lateinit var SORT_MODE: TerminalSettingKey + private set + + override fun initializePhyCon(api: PhyConAPI) { + SORT_MODE = api.registerTerminalSetting(Identifier(PhysicalConnectivity.MODID, "sort"), SortMode.COUNT_HIGH_FIRST) + } + +} diff --git a/src/main/kotlin/net/shadowfacts/phycon/PhyConAPIImpl.kt b/src/main/kotlin/net/shadowfacts/phycon/PhyConAPIImpl.kt new file mode 100644 index 0000000..328d535 --- /dev/null +++ b/src/main/kotlin/net/shadowfacts/phycon/PhyConAPIImpl.kt @@ -0,0 +1,18 @@ +package net.shadowfacts.phycon + +import net.minecraft.util.Identifier +import net.shadowfacts.phycon.api.PhyConAPI +import net.shadowfacts.phycon.api.TerminalSetting +import net.shadowfacts.phycon.api.TerminalSettingKey +import net.shadowfacts.phycon.util.TerminalSettings + +/** + * @author shadowfacts + */ +object PhyConAPIImpl: PhyConAPI { + + override fun registerTerminalSetting(id: Identifier, defaultValue: E): TerminalSettingKey where E: Enum, E: TerminalSetting? { + return TerminalSettings.register(id, defaultValue) + } + +} diff --git a/src/main/kotlin/net/shadowfacts/phycon/PhysicalConnectivity.kt b/src/main/kotlin/net/shadowfacts/phycon/PhysicalConnectivity.kt index 2a5ff63..62e55aa 100644 --- a/src/main/kotlin/net/shadowfacts/phycon/PhysicalConnectivity.kt +++ b/src/main/kotlin/net/shadowfacts/phycon/PhysicalConnectivity.kt @@ -2,6 +2,8 @@ package net.shadowfacts.phycon import net.fabricmc.api.ModInitializer import net.fabricmc.fabric.api.networking.v1.ServerPlayNetworking +import net.fabricmc.loader.api.FabricLoader +import net.shadowfacts.phycon.api.PhyConPlugin import net.shadowfacts.phycon.init.PhyBlockEntities import net.shadowfacts.phycon.init.PhyBlocks import net.shadowfacts.phycon.init.PhyItems @@ -27,6 +29,10 @@ object PhysicalConnectivity: ModInitializer { registerGlobalReceiver(C2STerminalRequestItem) registerGlobalReceiver(C2STerminalUpdateDisplayedItems) registerGlobalReceiver(C2SConfigureDevice) + + for (it in FabricLoader.getInstance().getEntrypoints("phycon", PhyConPlugin::class.java)) { + it.initializePhyCon(PhyConAPIImpl) + } } private fun registerGlobalReceiver(receiver: ServerReceiver) { diff --git a/src/main/kotlin/net/shadowfacts/phycon/PhysicalConnectivityClient.kt b/src/main/kotlin/net/shadowfacts/phycon/PhysicalConnectivityClient.kt index 06c7f47..5ed45f9 100644 --- a/src/main/kotlin/net/shadowfacts/phycon/PhysicalConnectivityClient.kt +++ b/src/main/kotlin/net/shadowfacts/phycon/PhysicalConnectivityClient.kt @@ -14,12 +14,15 @@ import net.shadowfacts.phycon.client.PhyExtendedModelProvider import net.shadowfacts.phycon.client.PhyModelProvider import net.shadowfacts.phycon.networking.ClientReceiver import net.shadowfacts.phycon.networking.S2CTerminalUpdateDisplayedItems +import net.shadowfacts.phycon.util.TerminalSettings /** * @author shadowfacts */ object PhysicalConnectivityClient: ClientModInitializer { + val terminalSettings = TerminalSettings() + var screenMaterial: RenderMaterial? = null private set diff --git a/src/main/kotlin/net/shadowfacts/phycon/block/terminal/SettingButton.kt b/src/main/kotlin/net/shadowfacts/phycon/block/terminal/SettingButton.kt new file mode 100644 index 0000000..330e592 --- /dev/null +++ b/src/main/kotlin/net/shadowfacts/phycon/block/terminal/SettingButton.kt @@ -0,0 +1,72 @@ +package net.shadowfacts.phycon.block.terminal + +import net.minecraft.client.util.math.MatrixStack +import net.shadowfacts.cacao.geometry.Point +import net.shadowfacts.cacao.geometry.Size +import net.shadowfacts.cacao.util.EnumHelper +import net.shadowfacts.cacao.util.MouseButton +import net.shadowfacts.cacao.util.texture.Texture +import net.shadowfacts.cacao.view.TextureView +import net.shadowfacts.cacao.view.button.AbstractButton +import net.shadowfacts.phycon.PhysicalConnectivityClient +import net.shadowfacts.phycon.api.TerminalSetting +import net.shadowfacts.phycon.util.TerminalSettings +import java.util.EnumMap + +/** + * @author shadowfacts + */ +class SettingButton( + val key: TerminalSettings.SettingKey, +): AbstractButton>( + TextureView(null).apply { + intrinsicContentSize = Size(16.0, 16.0) + }, + padding = 2.0 +) where E: Enum, E: TerminalSetting { + + private val textureCache = EnumMap(key.clazz) + + private val textureView: TextureView + get() = content as TextureView + + init { + updateTexture() + } + + private fun updateTexture() { + textureView.texture = textureCache.getOrPut(key.value) { + val uv = key.value.uv + Texture(key.value.iconTexture, uv[0], uv[1]) + } + } + + override fun mouseClicked(point: Point, mouseButton: MouseButton): Boolean { + if (!disabled) { + val newValue = when (mouseButton) { + MouseButton.LEFT -> EnumHelper.next(key.value) + MouseButton.RIGHT -> EnumHelper.previous(key.value) + else -> { + return false + } + } + + PhysicalConnectivityClient.terminalSettings[key] = newValue + + updateTexture() + } + + return super.mouseClicked(point, mouseButton) + } + + override fun draw(matrixStack: MatrixStack, mouse: Point, delta: Float) { + super.draw(matrixStack, mouse, delta) + + if (mouse in bounds) { + key.value.tooltip?.also { + window!!.drawTooltip(listOf(it)) + } + } + } + +} diff --git a/src/main/kotlin/net/shadowfacts/phycon/block/terminal/SortModeButton.kt b/src/main/kotlin/net/shadowfacts/phycon/block/terminal/SortModeButton.kt deleted file mode 100644 index 8ba1847..0000000 --- a/src/main/kotlin/net/shadowfacts/phycon/block/terminal/SortModeButton.kt +++ /dev/null @@ -1,57 +0,0 @@ -package net.shadowfacts.phycon.block.terminal - -import net.minecraft.util.Identifier -import net.shadowfacts.cacao.geometry.Point -import net.shadowfacts.cacao.geometry.Size -import net.shadowfacts.cacao.util.EnumHelper -import net.shadowfacts.cacao.util.MouseButton -import net.shadowfacts.cacao.util.texture.Texture -import net.shadowfacts.cacao.view.TextureView -import net.shadowfacts.cacao.view.button.AbstractButton -import net.shadowfacts.phycon.PhysicalConnectivity -import net.shadowfacts.phycon.util.SortMode - -/** - * @author shadowfacts - */ -class SortModeButton( - initialValue: SortMode, -): AbstractButton( - TextureView(TEXTURES[initialValue]!!).apply { - intrinsicContentSize = Size(16.0, 16.0) - } -) { - - companion object { - private val ID = Identifier(PhysicalConnectivity.MODID, "textures/gui/terminal.png") - private val TEXTURES = mapOf( - SortMode.COUNT_HIGH_FIRST to Texture(ID, 0, 230), - SortMode.COUNT_LOW_FIRST to Texture(ID, 16, 230), - SortMode.ALPHABETICAL to Texture(ID, 32, 230), - ) - } - - private val textureView: TextureView - get() = content as TextureView - - var value: SortMode = initialValue - set(value) { - field = value - textureView.texture = TEXTURES[value]!! - } - - override fun mouseClicked(point: Point, mouseButton: MouseButton): Boolean { - if (!disabled) { - value = when (mouseButton) { - MouseButton.LEFT -> EnumHelper.next(value) - MouseButton.RIGHT -> EnumHelper.previous(value) - else -> { - return false - } - } - } - - return super.mouseClicked(point, mouseButton) - } - -} diff --git a/src/main/kotlin/net/shadowfacts/phycon/block/terminal/TerminalBlockEntity.kt b/src/main/kotlin/net/shadowfacts/phycon/block/terminal/TerminalBlockEntity.kt index 35396db..315b6f9 100644 --- a/src/main/kotlin/net/shadowfacts/phycon/block/terminal/TerminalBlockEntity.kt +++ b/src/main/kotlin/net/shadowfacts/phycon/block/terminal/TerminalBlockEntity.kt @@ -57,6 +57,7 @@ class TerminalBlockEntity: DeviceBlockEntity(PhyBlockEntities.TERMINAL), private var observers = 0 val cachedNetItems = ItemStackCollections.intMap() + // todo: multiple players could have the terminal open simultaneously var netItemObserver: WeakReference? = null init { @@ -117,7 +118,9 @@ class TerminalBlockEntity: DeviceBlockEntity(PhyBlockEntities.TERMINAL), private fun updateAndSync() { updateNetItems() + // syncs the internal buffer to the client sync() + // syncs the open container (if any) to the client netItemObserver?.get()?.netItemsChanged() } @@ -153,14 +156,6 @@ class TerminalBlockEntity: DeviceBlockEntity(PhyBlockEntities.TERMINAL), finishable.forEach(::stackLocateRequestCompleted) } - fun addObserver() { - observers++ - } - - fun removeObserver() { - observers-- - } - override fun tick() { super.tick() @@ -171,10 +166,6 @@ class TerminalBlockEntity: DeviceBlockEntity(PhyBlockEntities.TERMINAL), if (counter % 20 == 0L && !world!!.isClient) { beginInsertions() - - if (observers > 0) { - updateAndSync() - } } } @@ -197,7 +188,6 @@ class TerminalBlockEntity: DeviceBlockEntity(PhyBlockEntities.TERMINAL), } player.openHandledScreen(factory) } - addObserver() } fun requestItem(stack: ItemStack, amount: Int = stack.count) { diff --git a/src/main/kotlin/net/shadowfacts/phycon/block/terminal/TerminalScreen.kt b/src/main/kotlin/net/shadowfacts/phycon/block/terminal/TerminalScreen.kt index 3011d72..e2cec76 100644 --- a/src/main/kotlin/net/shadowfacts/phycon/block/terminal/TerminalScreen.kt +++ b/src/main/kotlin/net/shadowfacts/phycon/block/terminal/TerminalScreen.kt @@ -53,7 +53,6 @@ class TerminalScreen(handler: TerminalScreenHandler, playerInv: PlayerInventory, var searchQuery = "" var scrollPosition = 0.0 - var sortMode = SortMode.COUNT_HIGH_FIRST init { backgroundWidth = 252 @@ -72,7 +71,7 @@ class TerminalScreen(handler: TerminalScreenHandler, playerInv: PlayerInventory, fun requestUpdatedItems() { val player = MinecraftClient.getInstance().player!! - player.networkHandler.sendPacket(C2STerminalUpdateDisplayedItems(handler.terminal, searchQuery, sortMode, scrollPosition.toFloat())) + player.networkHandler.sendPacket(C2STerminalUpdateDisplayedItems(handler.terminal, searchQuery, scrollPosition.toFloat())) } private fun showRequestAmountDialog(stack: ItemStack) { diff --git a/src/main/kotlin/net/shadowfacts/phycon/block/terminal/TerminalScreenHandler.kt b/src/main/kotlin/net/shadowfacts/phycon/block/terminal/TerminalScreenHandler.kt index f6bd6fa..0ece564 100644 --- a/src/main/kotlin/net/shadowfacts/phycon/block/terminal/TerminalScreenHandler.kt +++ b/src/main/kotlin/net/shadowfacts/phycon/block/terminal/TerminalScreenHandler.kt @@ -10,11 +10,13 @@ import net.minecraft.screen.ScreenHandler import net.minecraft.server.network.ServerPlayerEntity import net.minecraft.util.Identifier import net.minecraft.util.registry.Registry +import net.shadowfacts.phycon.DefaultPlugin import net.shadowfacts.phycon.PhysicalConnectivity import net.shadowfacts.phycon.init.PhyBlocks import net.shadowfacts.phycon.init.PhyScreens import net.shadowfacts.phycon.networking.S2CTerminalUpdateDisplayedItems import net.shadowfacts.phycon.util.SortMode +import net.shadowfacts.phycon.util.TerminalSettings import net.shadowfacts.phycon.util.copyWithCount import java.lang.ref.WeakReference import kotlin.math.ceil @@ -25,7 +27,11 @@ import kotlin.math.roundToInt /** * @author shadowfacts */ -class TerminalScreenHandler(syncId: Int, val playerInv: PlayerInventory, val terminal: TerminalBlockEntity): ScreenHandler(PhyScreens.TERMINAL, syncId), +class TerminalScreenHandler( + syncId: Int, + val playerInv: PlayerInventory, + val terminal: TerminalBlockEntity, +): ScreenHandler(PhyScreens.TERMINAL, syncId), TerminalBlockEntity.NetItemObserver { companion object { @@ -36,8 +42,7 @@ class TerminalScreenHandler(syncId: Int, val playerInv: PlayerInventory, val ter private val fakeInv = FakeInventory(this) private var searchQuery: String = "" - var sortMode = SortMode.COUNT_HIGH_FIRST - private set + private var settings = TerminalSettings() var totalEntries = 0 private set var scrollPosition = 0f @@ -54,12 +59,17 @@ class TerminalScreenHandler(syncId: Int, val playerInv: PlayerInventory, val ter private set constructor(syncId: Int, playerInv: PlayerInventory, buf: PacketByteBuf): - this(syncId, playerInv, PhyBlocks.TERMINAL.getBlockEntity(playerInv.player.world, buf.readBlockPos())!!) + this( + syncId, + playerInv, + PhyBlocks.TERMINAL.getBlockEntity(playerInv.player.world, buf.readBlockPos())!! + ) init { if (!terminal.world!!.isClient) { + assert(terminal.netItemObserver?.get() === null) terminal.netItemObserver = WeakReference(this) - netItemsChanged() + // intentionally don't call netItemsChanged immediately, we need to wait for the client to send us its settings } // network @@ -107,7 +117,7 @@ class TerminalScreenHandler(syncId: Int, val playerInv: PlayerInventory, val ter totalEntries = filtered.size val sorted = - when (sortMode) { + when (settings[DefaultPlugin.SORT_MODE]) { SortMode.COUNT_HIGH_FIRST -> filtered.sortedByDescending { it.intValue } SortMode.COUNT_LOW_FIRST -> filtered.sortedBy { it.intValue } SortMode.ALPHABETICAL -> filtered.sortedBy { it.key.name.string } @@ -120,7 +130,7 @@ class TerminalScreenHandler(syncId: Int, val playerInv: PlayerInventory, val ter // itemEntries = sorted.map { Entry(it.key, it.intValue) } - (player as ServerPlayerEntity).networkHandler.sendPacket(S2CTerminalUpdateDisplayedItems(terminal, itemEntries, searchQuery, sortMode, scrollPosition, totalEntries)) + (player as ServerPlayerEntity).networkHandler.sendPacket(S2CTerminalUpdateDisplayedItems(terminal, itemEntries, searchQuery, settings, scrollPosition, totalEntries)) } fun totalRows(): Int { @@ -139,18 +149,17 @@ class TerminalScreenHandler(syncId: Int, val playerInv: PlayerInventory, val ter return currentScrollOffsetInRows() * 9 } - fun sendUpdatedItemsToClient(player: ServerPlayerEntity, query: String, sortMode: SortMode, scrollPosition: Float) { + fun sendUpdatedItemsToClient(player: ServerPlayerEntity, query: String, settings: TerminalSettings, scrollPosition: Float) { this.searchQuery = query - this.sortMode = sortMode + this.settings = settings this.scrollPosition = scrollPosition netItemsChanged() } - fun receivedUpdatedItemsFromServer(entries: List, query: String, sortMode: SortMode, scrollPosition: Float, totalEntries: Int) { + fun receivedUpdatedItemsFromServer(entries: List, query: String, scrollPosition: Float, totalEntries: Int) { assert(playerInv.player.world.isClient) this.searchQuery = query - this.sortMode = sortMode this.scrollPosition = scrollPosition this.totalEntries = totalEntries itemEntries = entries @@ -163,7 +172,7 @@ class TerminalScreenHandler(syncId: Int, val playerInv: PlayerInventory, val ter override fun close(player: PlayerEntity) { super.close(player) - terminal.removeObserver() + terminal.netItemObserver = null } override fun onSlotClick(slotId: Int, clickData: Int, actionType: SlotActionType, player: PlayerEntity): ItemStack { diff --git a/src/main/kotlin/net/shadowfacts/phycon/block/terminal/TerminalViewController.kt b/src/main/kotlin/net/shadowfacts/phycon/block/terminal/TerminalViewController.kt index dbb03a7..1cb2b3f 100644 --- a/src/main/kotlin/net/shadowfacts/phycon/block/terminal/TerminalViewController.kt +++ b/src/main/kotlin/net/shadowfacts/phycon/block/terminal/TerminalViewController.kt @@ -2,15 +2,18 @@ package net.shadowfacts.phycon.block.terminal import net.minecraft.text.TranslatableText import net.minecraft.util.math.MathHelper +import net.shadowfacts.cacao.geometry.Axis import net.shadowfacts.cacao.geometry.Point import net.shadowfacts.cacao.util.Color import net.shadowfacts.cacao.util.MouseButton import net.shadowfacts.cacao.view.Label +import net.shadowfacts.cacao.view.StackView import net.shadowfacts.cacao.view.View import net.shadowfacts.cacao.view.textfield.TextField import net.shadowfacts.cacao.viewcontroller.ViewController import net.shadowfacts.kiwidsl.dsl import net.shadowfacts.phycon.util.SortMode +import net.shadowfacts.phycon.util.TerminalSettings /** * @author shadowfacts @@ -22,7 +25,7 @@ class TerminalViewController( ): ViewController() { private lateinit var scrollTrack: ScrollTrackView - lateinit var sortMode: SortModeButton + lateinit var settingsView: View private set lateinit var searchField: TextField private set @@ -84,8 +87,12 @@ class TerminalViewController( scrollTrack = view.addSubview(ScrollTrackView(::scrollPositionChanged)) - sortMode = view.addSubview(SortModeButton(SortMode.COUNT_HIGH_FIRST)).apply { - handler = ::sortModeChanged + val settingsStack = view.addSubview(StackView(Axis.VERTICAL, spacing = 2.0)) + settingsView = settingsStack + TerminalSettings.allKeys.forEach { key -> + val button = SettingButton(key) + button.handler = { settingsChanged() } + settingsStack.addArrangedSubview(button) } view.solver.dsl { @@ -108,10 +115,8 @@ class TerminalViewController( scrollTrack.bottomAnchor equalTo (network.bottomAnchor - 1) scrollTrack.widthAnchor equalTo 12 - sortMode.leftAnchor equalTo pane.rightAnchor + 4 - sortMode.topAnchor equalTo pane.topAnchor - sortMode.widthAnchor equalTo 20 - sortMode.heightAnchor equalTo 20 + settingsStack.leftAnchor equalTo (pane.rightAnchor + 4) + settingsStack.topAnchor equalTo pane.topAnchor } } @@ -131,8 +136,7 @@ class TerminalViewController( } } - private fun sortModeChanged(button: SortModeButton) { - screen.sortMode = button.value + private fun settingsChanged() { screen.requestUpdatedItems() } diff --git a/src/main/kotlin/net/shadowfacts/phycon/networking/C2STerminalUpdateDisplayedItems.kt b/src/main/kotlin/net/shadowfacts/phycon/networking/C2STerminalUpdateDisplayedItems.kt index c27da55..4f0d094 100644 --- a/src/main/kotlin/net/shadowfacts/phycon/networking/C2STerminalUpdateDisplayedItems.kt +++ b/src/main/kotlin/net/shadowfacts/phycon/networking/C2STerminalUpdateDisplayedItems.kt @@ -10,9 +10,11 @@ import net.minecraft.server.network.ServerPlayNetworkHandler import net.minecraft.server.network.ServerPlayerEntity import net.minecraft.util.Identifier import net.shadowfacts.phycon.PhysicalConnectivity +import net.shadowfacts.phycon.PhysicalConnectivityClient import net.shadowfacts.phycon.block.terminal.TerminalBlockEntity import net.shadowfacts.phycon.block.terminal.TerminalScreenHandler import net.shadowfacts.phycon.util.SortMode +import net.shadowfacts.phycon.util.TerminalSettings /** * @author shadowfacts @@ -21,14 +23,14 @@ object C2STerminalUpdateDisplayedItems: ServerReceiver { override val CHANNEL = Identifier(PhysicalConnectivity.MODID, "terminal_update_displayed") - operator fun invoke(terminal: TerminalBlockEntity, query: String, sortMode: SortMode, scrollPosition: Float): Packet<*> { + operator fun invoke(terminal: TerminalBlockEntity, query: String, scrollPosition: Float): Packet<*> { val buf = PacketByteBufs.create() buf.writeIdentifier(terminal.world!!.registryKey.value) buf.writeBlockPos(terminal.pos) buf.writeString(query) - buf.writeVarInt(sortMode.ordinal) + buf.writeCompoundTag(PhysicalConnectivityClient.terminalSettings.toTag()) buf.writeFloat(scrollPosition) return ClientPlayNetworking.createC2SPacket(CHANNEL, buf) @@ -38,7 +40,8 @@ object C2STerminalUpdateDisplayedItems: ServerReceiver { val dimID = buf.readIdentifier() val pos = buf.readBlockPos() val query = buf.readString() - val sortMode = SortMode.values()[buf.readVarInt()] + val settings = TerminalSettings() + settings.fromTag(buf.readCompoundTag()!!) val scrollPosition = buf.readFloat() server.execute { @@ -46,7 +49,7 @@ object C2STerminalUpdateDisplayedItems: ServerReceiver { val screenHandler = player.currentScreenHandler if (screenHandler !is TerminalScreenHandler) return@execute if (screenHandler.terminal.pos != pos) return@execute - screenHandler.sendUpdatedItemsToClient(player, query, sortMode, scrollPosition) + screenHandler.sendUpdatedItemsToClient(player, query, settings, scrollPosition) } } } diff --git a/src/main/kotlin/net/shadowfacts/phycon/networking/S2CTerminalUpdateDisplayedItems.kt b/src/main/kotlin/net/shadowfacts/phycon/networking/S2CTerminalUpdateDisplayedItems.kt index 4a95ad2..14170f4 100644 --- a/src/main/kotlin/net/shadowfacts/phycon/networking/S2CTerminalUpdateDisplayedItems.kt +++ b/src/main/kotlin/net/shadowfacts/phycon/networking/S2CTerminalUpdateDisplayedItems.kt @@ -7,9 +7,11 @@ import net.minecraft.client.MinecraftClient import net.minecraft.client.network.ClientPlayNetworkHandler import net.minecraft.network.Packet import net.minecraft.network.PacketByteBuf +import net.shadowfacts.phycon.PhysicalConnectivityClient import net.shadowfacts.phycon.block.terminal.TerminalBlockEntity import net.shadowfacts.phycon.block.terminal.TerminalScreenHandler import net.shadowfacts.phycon.util.SortMode +import net.shadowfacts.phycon.util.TerminalSettings import net.shadowfacts.phycon.util.readItemStackWithoutCount import net.shadowfacts.phycon.util.writeItemStackWithoutCount @@ -19,7 +21,7 @@ import net.shadowfacts.phycon.util.writeItemStackWithoutCount object S2CTerminalUpdateDisplayedItems: ClientReceiver { override val CHANNEL = C2STerminalUpdateDisplayedItems.CHANNEL - operator fun invoke(terminal: TerminalBlockEntity, entries: List, query: String, sortMode: SortMode, scrollPosition: Float, totalEntries: Int): Packet<*> { + operator fun invoke(terminal: TerminalBlockEntity, entries: List, query: String, settings: TerminalSettings, scrollPosition: Float, totalEntries: Int): Packet<*> { val buf = PacketByteBufs.create() buf.writeIdentifier(terminal.world!!.registryKey.value) @@ -32,7 +34,7 @@ object S2CTerminalUpdateDisplayedItems: ClientReceiver { } buf.writeString(query) - buf.writeVarInt(sortMode.ordinal) + buf.writeCompoundTag(settings.toTag()) buf.writeFloat(scrollPosition) buf.writeInt(totalEntries) @@ -48,7 +50,7 @@ object S2CTerminalUpdateDisplayedItems: ClientReceiver { entries.add(TerminalScreenHandler.Entry(buf.readItemStackWithoutCount(), buf.readVarInt())) } val query = buf.readString() - val sortMode = SortMode.values()[buf.readVarInt()] + PhysicalConnectivityClient.terminalSettings.fromTag(buf.readCompoundTag()!!) val scrollPosition = buf.readFloat() val totalEntries = buf.readInt() @@ -57,7 +59,7 @@ object S2CTerminalUpdateDisplayedItems: ClientReceiver { val screenHandler = client.player!!.currentScreenHandler if (screenHandler !is TerminalScreenHandler) return@execute if (screenHandler.terminal.pos != pos) return@execute - screenHandler.receivedUpdatedItemsFromServer(entries, query, sortMode, scrollPosition, totalEntries) + screenHandler.receivedUpdatedItemsFromServer(entries, query, scrollPosition, totalEntries) } } } diff --git a/src/main/kotlin/net/shadowfacts/phycon/util/SortMode.kt b/src/main/kotlin/net/shadowfacts/phycon/util/SortMode.kt index fbcde94..7d304e4 100644 --- a/src/main/kotlin/net/shadowfacts/phycon/util/SortMode.kt +++ b/src/main/kotlin/net/shadowfacts/phycon/util/SortMode.kt @@ -2,20 +2,30 @@ package net.shadowfacts.phycon.util import net.minecraft.text.LiteralText import net.minecraft.text.Text +import net.minecraft.util.Identifier +import net.shadowfacts.phycon.PhysicalConnectivity +import net.shadowfacts.phycon.api.TerminalSetting /** * @author shadowfacts */ -enum class SortMode: RotatableEnum { +enum class SortMode: TerminalSetting { COUNT_HIGH_FIRST, COUNT_LOW_FIRST, ALPHABETICAL; - val tooltip: Text - get() = when (this) { - COUNT_HIGH_FIRST -> LiteralText("Count, highest first") - COUNT_LOW_FIRST -> LiteralText("Count, lowest first") - ALPHABETICAL -> LiteralText("Name") - } + override fun getIconTexture() = Identifier(PhysicalConnectivity.MODID, "textures/gui/terminal.png") + + override fun getUV() = when (this) { + COUNT_HIGH_FIRST -> intArrayOf(0, 230) + COUNT_LOW_FIRST -> intArrayOf(16, 230) + ALPHABETICAL -> intArrayOf(32, 230) + } + + override fun getTooltip() = when (this) { + COUNT_HIGH_FIRST -> LiteralText("Count, highest first") + COUNT_LOW_FIRST -> LiteralText("Count, lowest first") + ALPHABETICAL -> LiteralText("Name") + } } diff --git a/src/main/kotlin/net/shadowfacts/phycon/util/TerminalSettings.kt b/src/main/kotlin/net/shadowfacts/phycon/util/TerminalSettings.kt new file mode 100644 index 0000000..8140d6a --- /dev/null +++ b/src/main/kotlin/net/shadowfacts/phycon/util/TerminalSettings.kt @@ -0,0 +1,83 @@ +package net.shadowfacts.phycon.util + +import net.minecraft.nbt.CompoundTag +import net.minecraft.util.Identifier +import net.shadowfacts.phycon.PhysicalConnectivityClient +import net.shadowfacts.phycon.api.TerminalSettingKey +import net.shadowfacts.phycon.api.TerminalSetting + +/** + * @author shadowfacts + */ +class TerminalSettings { + + companion object { + private val SETTINGS = mutableMapOf>() + private val DEFAULTS = mutableMapOf, Enum<*>>() + + val allKeys: Collection> + get() = SETTINGS.values + + fun register(id: Identifier, defaultValue: E): SettingKey where E: Enum, E: TerminalSetting { + val setting = SettingKey(id, defaultValue.javaClass) + SETTINGS[id] = setting + DEFAULTS[setting] = defaultValue + return setting + } + + fun getDefault(setting: TerminalSettingKey): E where E: Enum, E: TerminalSetting { + @Suppress("UNCHECKED_CAST") + return DEFAULTS[setting] as E + } + } + + class SettingKey( + val id: Identifier, + val clazz: Class, + ): TerminalSettingKey where E: Enum, E: TerminalSetting { + fun value(ordinal: Int): E? { + @Suppress("UNCHECKED_CAST") + return if (clazz.enumConstants.size <= ordinal) null + else clazz.enumConstants[ordinal] as E + } + + override fun getID() = id + override fun getValue() = PhysicalConnectivityClient.terminalSettings[this] + } + + private val settings = mutableMapOf, Enum<*>>() + + operator fun get(key: TerminalSettingKey): E where E: Enum, E: TerminalSetting { + @Suppress("UNCHECKED_CAST") + return settings[key] as? E ?: getDefault(key) + } + + operator fun set(key: SettingKey, value: E) where E: Enum, E: TerminalSetting { + settings[key] = value + } + + fun toTag(): CompoundTag { + return CompoundTag().also { + settings.forEach { (s, v) -> + it.putInt(s.id.toString(), v.ordinal) + } + } + } + + fun fromTag(tag: CompoundTag) { + settings.clear() + tag.keys.forEach { k -> + val id = Identifier.tryParse(k) ?: return@forEach + val setting = SETTINGS[id] ?: return@forEach + setValueFromOrdinal(setting, tag.getInt(k)) + } + } + + private fun setValueFromOrdinal(setting: SettingKey, ordinal: Int) where E: Enum, E: TerminalSetting { + val value = setting.value(ordinal) + if (value != null) { + this[setting] = value + } + } + +} diff --git a/src/main/resources/fabric.mod.json b/src/main/resources/fabric.mod.json index c2f87c8..ea13295 100644 --- a/src/main/resources/fabric.mod.json +++ b/src/main/resources/fabric.mod.json @@ -35,6 +35,12 @@ "adapter": "kotlin", "value": "net.shadowfacts.phycon.PhysicalConnectivityClient" } + ], + "phycon": [ + { + "adapter": "kotlin", + "value": "net.shadowfacts.phycon.DefaultPlugin" + } ] }, "mixins": [