Skip to content

Commit

Permalink
chore: future proof mixins
Browse files Browse the repository at this point in the history
mostly by using MixinExtras where applicable.

also fixes some typos and general warnings
  • Loading branch information
RubixDev committed Mar 15, 2024
1 parent e21a445 commit 1174508
Show file tree
Hide file tree
Showing 22 changed files with 252 additions and 240 deletions.
44 changes: 27 additions & 17 deletions src/main/java/me/lizardofoz/inventorio/mixin/PlayerEntityMixin.java
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
package me.lizardofoz.inventorio.mixin;

import com.llamalad7.mixinextras.injector.ModifyReturnValue;
import com.llamalad7.mixinextras.injector.wrapoperation.Operation;
import com.llamalad7.mixinextras.injector.wrapoperation.WrapOperation;
import com.mojang.authlib.GameProfile;
import me.lizardofoz.inventorio.player.InventorioScreenHandler;
import me.lizardofoz.inventorio.player.PlayerAddonSerializer;
Expand Down Expand Up @@ -39,8 +42,8 @@ private void inventorioCreateAddon(World world, BlockPos pos, float yaw, GamePro
}

/**
* This inject causes the selected UtilityBelt item to be displayed in the
* offhand
* This injection causes the selected UtilityBelt item to be displayed in
* the offhand
*/
@Inject(method = "getEquippedStack", at = @At(value = "HEAD"), cancellable = true)
private void inventorioDisplayOffhand(EquipmentSlot slot, CallbackInfoReturnable<ItemStack> cir) {
Expand All @@ -52,21 +55,25 @@ private void inventorioDisplayOffhand(EquipmentSlot slot, CallbackInfoReturnable
* hands. First, the offhand is attached to the utility belt, rather than a
* vanilla slot. Second, a player can swap the main hand and the offhand.
*/
@Redirect(
@SuppressWarnings({ "unchecked", "MixinExtrasOperationParameters" })
@WrapOperation(
method = "equipStack",
at = @At(
value = "INVOKE",
target = "Lnet/minecraft/util/collection/DefaultedList;set(ILjava/lang/Object;)Ljava/lang/Object;",
ordinal = 0
)
)
private <E> E inventorioEquipMainHand(DefaultedList<E> defaultedList, int index, E stack) {
ItemStack itemStack = (ItemStack) stack;
if (inventorioAddon.getSwappedHands()) inventorioAddon.setSelectedUtilityStack(itemStack);
else getInventory().main.set(getInventory().selectedSlot, itemStack);
return (E) ItemStack.EMPTY;
private <E> E inventorioEquipMainHand(DefaultedList<E> instance, int index, E element, Operation<E> original) {
if (inventorioAddon.getSwappedHands()) {
inventorioAddon.setSelectedUtilityStack((ItemStack) element);
// TODO: should this return something else?
return (E) ItemStack.EMPTY;
}
return original.call(instance, index, element);
}

@SuppressWarnings("unchecked")
@Redirect(
method = "equipStack",
at = @At(
Expand All @@ -79,12 +86,13 @@ private <E> E inventorioEquipOffhand(DefaultedList<E> defaultedList, int index,
ItemStack itemStack = (ItemStack) stack;
if (inventorioAddon.getSwappedHands()) inventorioAddon.setSelectedHotbarStack(itemStack);
else inventorioAddon.setSelectedUtilityStack(itemStack);
// TODO: should this return something else?
return (E) ItemStack.EMPTY;
}

/**
* This mixin refreshes the available slots when we equip armor through
* right clicking or a dispenser
* right-clicking or a dispenser
*/
@Inject(method = "equipStack", at = @At(value = "RETURN"))
private void inventorioOnEquipArmor(EquipmentSlot slot, ItemStack stack, CallbackInfo ci) {
Expand All @@ -95,16 +103,16 @@ private void inventorioOnEquipArmor(EquipmentSlot slot, ItemStack stack, Callbac
/**
* This mixin allows arrows stored in the addon slots to be used by a bow
*/
@Inject(method = "getProjectileType", at = @At(value = "RETURN"), cancellable = true)
private void inventorioGetArrowType(ItemStack bowStack, CallbackInfoReturnable<ItemStack> cir) {
if (!cir.getReturnValue().isEmpty()) return;
@ModifyReturnValue(method = "getProjectileType", at = @At("RETURN"))
private ItemStack inventorioGetArrowType(ItemStack original, ItemStack bowStack) {
if (!original.isEmpty()) return original;
ItemStack arrowStack = inventorioAddon.getActiveArrowType(bowStack);
if (arrowStack != null) cir.setReturnValue(arrowStack);
return arrowStack != null ? arrowStack : original;
}

/**
* These 2 injects cause a correct weapon to be automatically selected and
* withdrawn upon attack
* These 2 injections cause a correct weapon to be automatically selected
* and withdrawn upon attack
*/
@Inject(method = "attack", at = @At(value = "HEAD"))
private void inventorioPreAttack(Entity target, CallbackInfo ci) {
Expand All @@ -117,7 +125,7 @@ private void inventorioPostAttack(Entity target, CallbackInfo ci) {
}

/**
* These 2 injects read and write additional data into Player's NBT
* These 2 injections read and write additional data into Player's NBT
*/
@Inject(method = "readCustomDataFromNbt", at = @At(value = "RETURN"))
private void inventorioDeserializePlayerAddon(NbtCompound tag, CallbackInfo ci) {
Expand All @@ -137,5 +145,7 @@ private void inventorioEmptyMainHandDisplayTool(CallbackInfo ci) {
}

@Nullable @Override
public PlayerInventoryAddon getInventorioAddon() { return inventorioAddon; }
public PlayerInventoryAddon inventorio$getInventorioAddon() {
return inventorioAddon;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -28,9 +28,9 @@ public abstract class PlayerInventoryMixin {
public PlayerEntity player;

/**
* This mixin causes inventory addon to get copied when the main inventory
* is (e.g. playing dying with /gamerule keepInventory true or going from
* the End to the Overworld)
* This mixin also copies inventory addon when the main inventory is copied
* (e.g. when playing with `/gamerule keepInventory true` or going from the
* End to the Overworld)
*/
@Inject(method = "clone", at = @At(value = "RETURN"))
private void inventorioClonePlayerInventory(PlayerInventory sourceInventory, CallbackInfo ci) {
Expand All @@ -57,11 +57,11 @@ private void inventorioGetBlockBreakingSpeed(BlockState block, CallbackInfoRetur
}

/**
* Here's how it works: when an item is getting inserted into player's
* Here's how it works: when an item is getting inserted into a player's
* inventory (e.g. by picking up an item from the ground), it will find a
* similar incomplete stack in the Deep Pockets and Utility Belt first. If
* none is present, it will go through vanilla logic, and if the Main
* Inventory is full, it will find a free slot in the Deep Pockets
* Inventory is full, it will find a free slot in the Deep Pockets.
*/
@Inject(method = "insertStack(ILnet/minecraft/item/ItemStack;)Z", at = @At(value = "HEAD"), cancellable = true)
private void inventorioInsertSimilarStackIntoAddon(
Expand All @@ -75,20 +75,15 @@ private void inventorioInsertSimilarStackIntoAddon(
});
}

@Inject(method = "insertStack(ILnet/minecraft/item/ItemStack;)Z", at = @At(value = "RETURN"), cancellable = true)
private void inventorioInsertStackIntoAddon(
int slot,
ItemStack originalStack,
CallbackInfoReturnable<Boolean> cir
) {
MixinHelpers.withInventoryAddon(player, inventorioAddon -> {
if (
slot == -1
&& !cir.getReturnValue()
&& inventorioAddon != null
&& inventorioAddon.insertStackIntoEmptySlot(originalStack)
) cir.setReturnValue(true);
});
@ModifyReturnValue(method = "insertStack(ILnet/minecraft/item/ItemStack;)Z", at = @At("RETURN"))
private boolean inventorioInsertStackIntoAddon(boolean original, int slot, ItemStack originalStack) {
return original
|| Boolean.TRUE.equals(
MixinHelpers.withInventoryAddonReturning(
player,
addon -> (slot == -1 && addon.insertStackIntoEmptySlot(originalStack))
)
);
}

@Inject(method = "removeOne", at = @At(value = "HEAD"), cancellable = true)
Expand All @@ -111,8 +106,8 @@ private void inventorioClearAddon(CallbackInfo ci) {
/**
* If player has a "scroll utility belt with a mouse wheel" setting enabled,
* hijack the vanilla hotbar scrolling and scroll the utility belt instead.
* Otherwise, set the selected hotbar segment value to -1 in case if a
* player scrolls a mouse wheel while using Segmented Hotbar
* Otherwise, set the selected hotbar segment value to -1 in case a player
* scrolls a mouse wheel while using Segmented Hotbar
*/
@Inject(method = "scrollInHotbar", at = @At(value = "HEAD"), cancellable = true)
@Environment(EnvType.CLIENT)
Expand All @@ -122,17 +117,13 @@ private void inventorioScrollInHotbar(double scrollAmount, CallbackInfo ci) {

@ModifyReturnValue(method = "contains(Lnet/minecraft/item/ItemStack;)Z", at = @At("RETURN"))
private boolean searchAddon(boolean original, ItemStack stack) {
if (original) return true;
PlayerInventoryAddon addon = PlayerInventoryAddon.getInventoryAddon(player);
if (addon == null) return false;
return addon.contains(stack);
return original
|| Boolean.TRUE.equals(MixinHelpers.withInventoryAddonReturning(player, addon -> addon.contains(stack)));
}

@ModifyReturnValue(method = "contains(Lnet/minecraft/registry/tag/TagKey;)Z", at = @At("RETURN"))
private boolean searchAddon(boolean original, TagKey<Item> tag) {
if (original) return true;
PlayerInventoryAddon addon = PlayerInventoryAddon.getInventoryAddon(player);
if (addon == null) return false;
return addon.contains(tag);
return original
|| Boolean.TRUE.equals(MixinHelpers.withInventoryAddonReturning(player, addon -> addon.contains(tag)));
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -45,12 +45,10 @@ private void inventorioSetPlayerSettings(
CallbackInfoReturnable<ServerPlayerEntity> cir
) {
ServerPlayerEntity newPlayer = cir.getReturnValue();
MixinHelpers.withInventoryAddon(newPlayer, newAddon -> {
MixinHelpers.withInventoryAddon(oldPlayer, oldAddon -> {
newAddon.setSwappedHands(oldAddon.getSwappedHands());
newAddon.setSelectedUtility(oldAddon.getSelectedUtility());
});
});
MixinHelpers.withInventoryAddon(newPlayer, newAddon -> MixinHelpers.withInventoryAddon(oldPlayer, oldAddon -> {
newAddon.setSwappedHands(oldAddon.getSwappedHands());
newAddon.setSelectedUtility(oldAddon.getSelectedUtility());
}));
InventorioNetworking.getInstance().s2cSelectUtilitySlot(newPlayer);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,8 @@ public class ServerPlayNetworkHandlerMixin {
public ServerPlayerEntity player;

/**
* These 3 injects remove the display tool (server-side) when a player tries
* to use (right-click) something from the main hand, so that the item
* These two injections remove the display tool (server-side) when a player
* tries to use (right-click) something from the main hand, so that the item
* that's ACTUALLY in the main hand can be used immediately
*/
@Inject(method = "onPlayerInteractBlock", at = @At(value = "HEAD"))
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
import org.spongepowered.asm.mixin.Mutable;
import org.spongepowered.asm.mixin.gen.Accessor;

@SuppressWarnings("unused")
@Mixin(Slot.class)
public interface SlotAccessor {
@Accessor("x")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,8 @@
@Mixin(ClientPlayNetworkHandler.class)
public class ClientPlayNetworkHandlerMixin {
/**
* When a player joins, this mixin sends a packet to the server, telling if
* the player uses Swapped Hands or not
* When a player joins, this mixin sends a packet to the server, telling
* whether the player uses Swapped Hands or not
*/
@Inject(method = "onGameJoin", at = @At(value = "RETURN"))
private void inventorioSendSwappedHandsStatus(GameJoinS2CPacket packet, CallbackInfo ci) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,8 @@
public class ClientPlayerInteractionManagerMixin {
/**
* The default implementation stops an item from being used if the vanilla
* "use" key isn't pressed. This mods adds an optional secondary use key,
* and this prevents the secondary item usage from being cancelled
* "use" key isn't pressed. This mod adds an optional secondary use key, and
* this prevents the secondary item usage from being cancelled
*/
@Inject(method = "stopUsingItem", at = @At(value = "HEAD"), cancellable = true)
private void inventorioStopUsingItem(PlayerEntity player, CallbackInfo ci) {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,18 +1,19 @@
package me.lizardofoz.inventorio.mixin.client;

import com.llamalad7.mixinextras.injector.wrapoperation.Operation;
import com.llamalad7.mixinextras.injector.wrapoperation.WrapOperation;
import me.lizardofoz.inventorio.util.MixinHelpers;
import net.fabricmc.api.EnvType;
import net.fabricmc.api.Environment;
import net.minecraft.client.MinecraftClient;
import net.minecraft.client.gui.screen.ingame.HandledScreen;
import net.minecraft.screen.slot.Slot;
import net.minecraft.screen.slot.SlotActionType;
import org.jetbrains.annotations.Nullable;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Shadow;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
import org.spongepowered.asm.mixin.injection.Slice;

@Mixin(value = HandledScreen.class)
@Environment(EnvType.CLIENT)
Expand All @@ -21,46 +22,69 @@ public class HandledScreenMixin {
@Nullable protected Slot focusedSlot;

/**
* This inject allows to use the vanilla Swap Offhand key (F by default) to
* move items to the Utility Belt in the inventory (the injected method is
* an edge-case handler when you have "swap offhand" on mouse buttons)
* This injection allows to use the vanilla Swap Offhand key (F by default)
* to move items to the Utility Belt in the inventory (the injected method
* is an edge-case handler when you have "swap offhand" on mouse buttons)
*/
@Inject(
@WrapOperation(
method = "onMouseClick(I)V",
at = @At(
value = "INVOKE",
target = "Lnet/minecraft/client/gui/screen/ingame/HandledScreen;onMouseClick(Lnet/minecraft/screen/slot/Slot;IILnet/minecraft/screen/slot/SlotActionType;)V",
ordinal = 0
),
cancellable = true
slice = @Slice(
from = @At(
value = "FIELD",
target = "Lnet/minecraft/client/option/GameOptions;swapHandsKey:Lnet/minecraft/client/option/KeyBinding;"
)
)
)
private void inventorioOffhandSwapWithMouse(int i, CallbackInfo ci) {
private void inventorioOffhandSwapWithMouse(
HandledScreen<?> instance,
Slot slot,
int slotId,
int button,
SlotActionType actionType,
Operation<Void> original
) {
MixinHelpers.withScreenHandler(
MinecraftClient.getInstance().player,
screenHandler -> screenHandler.tryTransferToUtilityBeltSlot(focusedSlot)
screenHandler -> screenHandler.tryTransferToUtilityBeltSlot(focusedSlot),
player -> original.call(instance, slot, slotId, button, actionType, original)
);
ci.cancel();
}

/**
* This inject allows to use the vanilla Swap Offhand key (F by default) to
* move items to the Utility Belt in the inventory
* This injection allows to use the vanilla Swap Offhand key (F by default)
* to move items to the Utility Belt in the inventory
*/
@Inject(
@WrapOperation(
method = "handleHotbarKeyPressed",
at = @At(
value = "INVOKE",
target = "Lnet/minecraft/client/gui/screen/ingame/HandledScreen;onMouseClick(Lnet/minecraft/screen/slot/Slot;IILnet/minecraft/screen/slot/SlotActionType;)V",
ordinal = 0
),
cancellable = true
slice = @Slice(
from = @At(
value = "FIELD",
target = "Lnet/minecraft/client/option/GameOptions;swapHandsKey:Lnet/minecraft/client/option/KeyBinding;"
)
)
)
private void inventorioOffhandSwapWithKeyboard(int keyCode, int scanCode, CallbackInfoReturnable<Boolean> cir) {
boolean[] result = new boolean[1];
private void inventorioOffhandSwapWithKeyboard(
HandledScreen<?> instance,
Slot slot,
int slotId,
int button,
SlotActionType actionType,
Operation<Void> original
) {
MixinHelpers.withScreenHandler(
MinecraftClient.getInstance().player,
screenHandler -> result[0] = screenHandler.tryTransferToUtilityBeltSlot(focusedSlot)
screenHandler -> screenHandler.tryTransferToUtilityBeltSlot(focusedSlot),
player -> original.call(instance, slot, slotId, button, actionType)
);
cir.setReturnValue(result[0]);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@
public class InGameHudMixinHP {
/**
* This mixin calls the renderer of hotbar addons. Note: this mixin doesn't
* work in NeoForge and substituted with a NeoForge event.
* work in (Neo)Forge and is substituted with a (Neo)Forge event.
*/
@Inject(method = "render", at = @At(value = "RETURN"))
private void inventorioRenderHotbarAddons(DrawContext context, float tickDelta, CallbackInfo ci) {
Expand Down
Loading

0 comments on commit 1174508

Please sign in to comment.