Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
package com.kneelawk.wiredredstone.mixin.api;

public interface MouseScrollListener {
void onMouseScroll(long window, double scrollDeltaX, double scrollDeltaY);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
package com.kneelawk.wiredredstone.mixin.api;

import java.util.ArrayList;
import java.util.List;

public class MouseScrollListenerRegistry {
private static final List<MouseScrollListener> listeners = new ArrayList<>();

public static void registerListener(MouseScrollListener listener) {
listeners.add(listener);
}

public static void notifyListeners(long window, double scrollDeltaX, double scrollDeltaY) {
for (MouseScrollListener listener : listeners) {
listener.onMouseScroll(window, scrollDeltaX, scrollDeltaY);
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
package com.kneelawk.wiredredstone.mixin.impl;

import com.kneelawk.wiredredstone.keybinding.WRKeyBindings;
import net.minecraft.client.gui.hud.InGameHud;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.ModifyArg;

@Mixin(InGameHud.class)
public abstract class InGameHudMixin {
@ModifyArg(method = "renderHeldItemTooltip", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/gui/GuiGraphics;drawShadowedText(Lnet/minecraft/client/font/TextRenderer;Lnet/minecraft/text/Text;III)I"), index = 3)
private int modifyHeldItemTooltipOffset(int offset) {
return offset - WRKeyBindings.getHeldItemTooltipOffset();
Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Found out that I can greatly simplify the mixin responsible for HUD offset

Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is fine and makes sense.

}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
package com.kneelawk.wiredredstone.mixin.impl;

import com.kneelawk.wiredredstone.mixin.api.MouseScrollListenerRegistry;
import net.minecraft.client.Mouse;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;

@Mixin(Mouse.class)
public class MouseMixin {
@Inject(at = @At("HEAD"), method = "onMouseScroll")
private void onMouseScroll(long window, double scrollDeltaX, double scrollDeltaY, CallbackInfo ci) {
MouseScrollListenerRegistry.notifyListeners(window, scrollDeltaX, scrollDeltaY);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
package com.kneelawk.wiredredstone.mixin.impl;

import com.kneelawk.wiredredstone.keybinding.WRKeyBindings;
import net.minecraft.entity.player.PlayerInventory;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;

@Mixin(PlayerInventory.class)
public abstract class PlayerInventoryMixin {
@Inject(at = @At("HEAD"), method = "scrollInHotbar(D)V", cancellable = true)
private void disableScrolling(double scrollAmount, CallbackInfo callbackInfo) {
if (!WRKeyBindings.isHotbarScrollEnabled()) {
callbackInfo.cancel();
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ import com.kneelawk.wiredredstone.node.WRBlockNodes
import com.kneelawk.wiredredstone.part.WRParts
import com.kneelawk.wiredredstone.recipe.WRRecipes
import com.kneelawk.wiredredstone.screenhandler.WRScreenHandlers
import com.kneelawk.wiredredstone.keybinding.WRKeyBindings

@Suppress("unused")
fun init() {
Expand All @@ -29,6 +30,7 @@ fun init() {
WRRecipes.init()
WRScreenHandlers.init()
WRNetworking.init()
WRKeyBindings.init()

CCIntegrationHandler.init()
EMIIntegrationHandler.init()
Expand Down
123 changes: 123 additions & 0 deletions src/main/kotlin/com/kneelawk/wiredredstone/keybinding/WRKeyBindings.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,123 @@
package com.kneelawk.wiredredstone.keybinding

import com.kneelawk.wiredredstone.item.WRItems.BUNDLED_CABLES
import com.kneelawk.wiredredstone.item.WRItems.INSULATED_WIRES
import com.kneelawk.wiredredstone.item.WRItems.RED_ALLOY_WIRE
import com.kneelawk.wiredredstone.item.WRItems.STANDING_BUNDLED_CABLES
import com.kneelawk.wiredredstone.item.WRItems.STANDING_INSULATED_WIRES
import com.kneelawk.wiredredstone.item.WRItems.STANDING_RED_ALLOY_WIRE
import com.kneelawk.wiredredstone.mixin.api.MouseScrollListenerRegistry
import com.kneelawk.wiredredstone.net.WRNetworking
import com.mojang.blaze3d.platform.InputUtil
import io.netty.buffer.Unpooled
import net.fabricmc.fabric.api.client.keybinding.v1.KeyBindingHelper
import net.fabricmc.fabric.api.client.networking.v1.ClientPlayNetworking
import net.fabricmc.fabric.api.client.rendering.v1.HudRenderCallback
import net.minecraft.client.MinecraftClient
import net.minecraft.client.option.KeyBind
import net.minecraft.item.ItemStack
import net.minecraft.network.PacketByteBuf
import org.lwjgl.glfw.GLFW

object WRKeyBindings {
private var hotbarScrollEnabled = true
private var heldTooltipOffset = 0

// Wires + Buses (toggle)
private val mapWiresAndCables by lazy {
sequenceOf(INSULATED_WIRES, STANDING_INSULATED_WIRES, BUNDLED_CABLES, STANDING_BUNDLED_CABLES)
.plus(mapOf(null to RED_ALLOY_WIRE))
.plus(mapOf(null to STANDING_RED_ALLOY_WIRE))
.map { it.entries }.reduce { a, b -> a + b }
.associate {
it.value to sequenceOf(
INSULATED_WIRES[it.key] ?: RED_ALLOY_WIRE,
STANDING_INSULATED_WIRES[it.key] ?: STANDING_RED_ALLOY_WIRE,
BUNDLED_CABLES[it.key]!!,
STANDING_BUNDLED_CABLES[it.key]!!
)
}
}

// Keybindings
val TOGGLE_WIRE_STATE by lazy {
KeyBind(
"key.wiredredstone.toggle_wire_state",
InputUtil.Type.KEYSYM,
GLFW.GLFW_KEY_R,
"key.wiredredstone.mod_name"
)
}

fun init() {
KeyBindingHelper.registerKeyBinding(TOGGLE_WIRE_STATE)

// Scroll menu
MouseScrollListenerRegistry.registerListener { _, _, scrollDeltaY ->
if (hotbarScrollEnabled) return@registerListener

val client = MinecraftClient.getInstance()
val player = client.player ?: return@registerListener
val activeStack = player.mainHandStack
val wiresAndCables = mapWiresAndCables[activeStack.item]?.toList()

if (TOGGLE_WIRE_STATE.isPressed && wiresAndCables != null) {
val menuIndex = wiresAndCables.indexOf(activeStack.item)
var newIndex = menuIndex - scrollDeltaY.toInt()
if (newIndex < 0) newIndex = wiresAndCables.size - 1
if (newIndex >= wiresAndCables.size) newIndex = 0
val newItem = wiresAndCables[newIndex]

val newStack = ItemStack(newItem, activeStack.count)
newStack.nbt = activeStack.nbt

val buf = PacketByteBuf(Unpooled.buffer())
buf.writeInt(player.inventory.selectedSlot)
buf.writeItemStack(newStack)

ClientPlayNetworking.send(WRNetworking.INVENTORY_UPDATE_CHANNEL, buf)
}
}

// Render select list over hotbar
HudRenderCallback.EVENT.register { guiGraphics, _ ->
val player = MinecraftClient.getInstance().player ?: return@register
if (!player.isCreative) return@register
val activeItem = player.mainHandStack.item
val activeSlot = player.inventory.selectedSlot
val wiresAndCables = mapWiresAndCables[activeItem]?.toList()

if (TOGGLE_WIRE_STATE.isPressed && wiresAndCables != null) {
hotbarScrollEnabled = false
val menuIndex = wiresAndCables.indexOf(activeItem)

val hotbarX = guiGraphics.scaledWindowWidth / 2 - 91
val hotbarY = guiGraphics.scaledWindowHeight - 22
Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Magic code, don't touch if works

Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This code looks fine. I can tell generally what it's doing and how to tweak it if necessary.


heldTooltipOffset = 12

wiresAndCables.forEachIndexed { index, item ->
val itemStack = ItemStack(item)
val x = hotbarX + (index + activeSlot - menuIndex) * 20 + 3
val y = hotbarY - 20

guiGraphics.drawItem(itemStack, x, y)
if (index == menuIndex) guiGraphics.fill(x - 1, y - 1, x + 17, y + 17, -2130706433)
}
} else {
hotbarScrollEnabled = true
heldTooltipOffset = 0
}
}
}

@JvmStatic
fun isHotbarScrollEnabled(): Boolean {
return hotbarScrollEnabled
}

@JvmStatic
fun getHeldItemTooltipOffset(): Int {
return heldTooltipOffset
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ object WRNetworking {

val HELLO_CHANNEL = id("hello")
val CONFIG_SYNC_CHANNEL = id("config_sync")
val INVENTORY_UPDATE_CHANNEL = id("inventory_update")

private val MISSING_MOD_LOGIN_TEXT = Text.literal("Client is missing Wired Redstone mod version >= 0.4.15")
private val MISSING_MOD_PLAY_TEXT = Text.literal("Client is missing Wired Redstone mod version >= 0.4.16")
Expand Down Expand Up @@ -78,6 +79,12 @@ object WRNetworking {
}
}

ServerPlayNetworking.registerGlobalReceiver(INVENTORY_UPDATE_CHANNEL) { _, player, handler, buf, _ ->
val slot = buf.readInt()
val itemStack = buf.readItemStack()
player.server.execute { player.inventory.setStack(slot, itemStack) }
}

ServerPlayConnectionEvents.DISCONNECT.register { handler, _ ->
missingResponses.remove(NetworkHelper.getAddress(handler))
}
Expand Down
6 changes: 5 additions & 1 deletion src/main/resources/assets/wiredredstone/lang/en_us.json
Original file line number Diff line number Diff line change
Expand Up @@ -167,5 +167,9 @@
"tag.wiredredstone.insulated_wires": "Insulated Wires",
"tag.wiredredstone.colored_standing_bundled_cables": "Colored Standing Bundled Cables",
"tag.wiredredstone.standing_insulated_wires": "Standing Insulated Wires",
"tag.wiredredstone.screwdrivers": "Screwdrivers"
"tag.wiredredstone.screwdrivers": "Screwdrivers",

"key.wiredredstone.mod_name": "Wired Redstone",
"key.wiredredstone.toggle_wire_state": "Toggle Wire State"
}

5 changes: 4 additions & 1 deletion src/main/resources/assets/wiredredstone/lang/ru_ru.json
Original file line number Diff line number Diff line change
Expand Up @@ -167,5 +167,8 @@
"tag.wiredredstone.insulated_wires": "Изолированные провода",
"tag.wiredredstone.colored_standing_bundled_cables": "Цветные постоянные связанные кабели",
"tag.wiredredstone.standing_insulated_wires": "Постоянные изолированные провода",
"tag.wiredredstone.screwdrivers": "Отвертки"
"tag.wiredredstone.screwdrivers": "Отвертки",

"key.wiredredstone.mod_name": "Проводной редстоун",
"key.wiredredstone.toggle_wire_state": "Переключить состояние провода"
}
1 change: 1 addition & 0 deletions src/main/resources/fabric.mod.json
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,7 @@
"fabricloader": ">=0.12.12",
"fabric": "*",
"fabric-language-kotlin": ">=1.8.1+kotlin.1.7.0",
"fabric-key-binding-api-v1": "*",
"graphlib": "*",
"libmultipart": ">=0.7.3-pre.3",
"libnetworkstack": ">=0.6.0",
Expand Down
3 changes: 3 additions & 0 deletions src/main/resources/wiredredstone.mixins.json
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,9 @@
"client": [
"ClientRecipeBookMixin",
"GameRendererAccessor",
"InGameHudMixin",
"MouseMixin",
"PlayerInventoryMixin",
"RenderLayerAccessor"
],
"mixins": [
Expand Down