Compare commits

...

3 commits

9 changed files with 126 additions and 52 deletions

View file

@ -3,7 +3,7 @@ org.gradle.jvmargs = -Xmx4G
org.gradle.parallel = true org.gradle.parallel = true
# Mod Properties # Mod Properties
version = 2.0.2 version = 2.0.3
maven_group = pm.c7.scout maven_group = pm.c7.scout
archives_base_name = Scout archives_base_name = Scout

View file

@ -3,11 +3,6 @@ package pm.c7.scout;
import dev.emi.trinkets.api.SlotReference; import dev.emi.trinkets.api.SlotReference;
import dev.emi.trinkets.api.TrinketComponent; import dev.emi.trinkets.api.TrinketComponent;
import dev.emi.trinkets.api.TrinketsApi; import dev.emi.trinkets.api.TrinketsApi;
import net.minecraft.client.MinecraftClient;
import net.minecraft.client.gui.screen.Screen;
import net.minecraft.client.gui.screen.ingame.BeaconScreen;
import net.minecraft.client.gui.screen.ingame.CreativeInventoryScreen;
import net.minecraft.client.gui.screen.ingame.MerchantScreen;
import net.minecraft.entity.player.PlayerEntity; import net.minecraft.entity.player.PlayerEntity;
import net.minecraft.inventory.Inventory; import net.minecraft.inventory.Inventory;
import net.minecraft.item.ItemStack; import net.minecraft.item.ItemStack;
@ -130,20 +125,4 @@ public class ScoutUtil {
out.addAll(scoutScreenHandler.scout$getRightPouchSlots()); out.addAll(scoutScreenHandler.scout$getRightPouchSlots());
return out; return out;
} }
public static @Nullable PlayerScreenHandler getPlayerScreenHandler() {
var client = MinecraftClient.getInstance();
if (client != null && client.player != null) {
return client.player.playerScreenHandler;
}
return null;
}
// FIXME: registry system for mods to register their own blacklisted screens
public static boolean isScreenBlacklisted(Screen screen) {
return screen instanceof CreativeInventoryScreen
|| screen instanceof MerchantScreen // FIXME: needs repositioning
|| screen instanceof BeaconScreen; // FIXME: needs repositioning
}
} }

View file

@ -110,7 +110,7 @@ public class ScoutClient implements ClientModInitializer {
ScreenEvents.AFTER_INIT.register((client, screen, scaledWidth, scaledHeight) -> { ScreenEvents.AFTER_INIT.register((client, screen, scaledWidth, scaledHeight) -> {
if (screen instanceof HandledScreen<?> handledScreen && client.player != null) { if (screen instanceof HandledScreen<?> handledScreen && client.player != null) {
if (ScoutUtil.isScreenBlacklisted(screen)) { if (ScoutUtilClient.isScreenBlacklisted(screen)) {
// realistically no one is going to have a screen bigger than 2147483647 pixels // realistically no one is going to have a screen bigger than 2147483647 pixels
for (Slot slot : ScoutUtil.getAllBagSlots(client.player.playerScreenHandler)) { for (Slot slot : ScoutUtil.getAllBagSlots(client.player.playerScreenHandler)) {
BagSlot bagSlot = (BagSlot) slot; BagSlot bagSlot = (BagSlot) slot;

View file

@ -0,0 +1,28 @@
package pm.c7.scout.client;
import org.jetbrains.annotations.Nullable;
import net.minecraft.client.MinecraftClient;
import net.minecraft.client.gui.screen.Screen;
import net.minecraft.client.gui.screen.ingame.BeaconScreen;
import net.minecraft.client.gui.screen.ingame.CreativeInventoryScreen;
import net.minecraft.client.gui.screen.ingame.MerchantScreen;
import net.minecraft.screen.PlayerScreenHandler;
public class ScoutUtilClient {
public static @Nullable PlayerScreenHandler getPlayerScreenHandler() {
var client = MinecraftClient.getInstance();
if (client != null && client.player != null) {
return client.player.playerScreenHandler;
}
return null;
}
// FIXME: registry system for mods to register their own blacklisted screens
public static boolean isScreenBlacklisted(Screen screen) {
return screen instanceof CreativeInventoryScreen
|| screen instanceof MerchantScreen // FIXME: needs repositioning
|| screen instanceof BeaconScreen; // FIXME: needs repositioning
}
}

View file

@ -4,9 +4,12 @@ import dev.emi.emi.api.EmiPlugin;
import dev.emi.emi.api.EmiRegistry; import dev.emi.emi.api.EmiRegistry;
import dev.emi.emi.api.widget.Bounds; import dev.emi.emi.api.widget.Bounds;
import net.minecraft.client.MinecraftClient; import net.minecraft.client.MinecraftClient;
import net.minecraft.client.gui.screen.ingame.InventoryScreen; import net.minecraft.client.gui.screen.ingame.GenericContainerScreen;
import net.minecraft.client.gui.screen.ingame.HandledScreen;
import net.minecraft.client.gui.screen.ingame.ShulkerBoxScreen;
import net.minecraft.item.ItemStack; import net.minecraft.item.ItemStack;
import pm.c7.scout.ScoutUtil; import pm.c7.scout.ScoutUtil;
import pm.c7.scout.client.ScoutUtilClient;
import pm.c7.scout.item.BaseBagItem; import pm.c7.scout.item.BaseBagItem;
import pm.c7.scout.item.BaseBagItem.BagType; import pm.c7.scout.item.BaseBagItem.BagType;
import pm.c7.scout.mixin.client.HandledScreenAccessor; import pm.c7.scout.mixin.client.HandledScreenAccessor;
@ -14,18 +17,55 @@ import pm.c7.scout.mixin.client.HandledScreenAccessor;
public class ScoutEmiPlugin implements EmiPlugin { public class ScoutEmiPlugin implements EmiPlugin {
@Override @Override
public void register(EmiRegistry registry) { public void register(EmiRegistry registry) {
registry.addExclusionArea(InventoryScreen.class, (screen, consumer) -> { registry.addGenericExclusionArea((screen, consumer) -> {
if (!(screen instanceof HandledScreen<?> handledScreen)) return;
if (ScoutUtilClient.isScreenBlacklisted(screen)) return;
MinecraftClient client = MinecraftClient.getInstance(); MinecraftClient client = MinecraftClient.getInstance();
var handledScreenAccessor = (HandledScreenAccessor) handledScreen;
var sx = handledScreenAccessor.getX();
var sy = handledScreenAccessor.getY();
var sw = handledScreenAccessor.getBackgroundWidth();
var sh = handledScreenAccessor.getBackgroundHeight();
ItemStack satchelStack = ScoutUtil.findBagItem(client.player, BagType.SATCHEL, false);
if (!satchelStack.isEmpty()) {
BaseBagItem bagItem = (BaseBagItem) satchelStack.getItem();
int slots = bagItem.getSlotCount();
int rows = (int) Math.ceil(slots / 9);
int x = sx;
int y = sy + sh;
if (screen instanceof GenericContainerScreen || screen instanceof ShulkerBoxScreen) {
y -= 1;
}
int w = sw;
int h = (rows * 18) + 8;
consumer.accept(new Bounds(x, y, w, h));
}
ItemStack leftPouchStack = ScoutUtil.findBagItem(client.player, BagType.POUCH, false); ItemStack leftPouchStack = ScoutUtil.findBagItem(client.player, BagType.POUCH, false);
if (!leftPouchStack.isEmpty()) { if (!leftPouchStack.isEmpty()) {
BaseBagItem bagItem = (BaseBagItem) leftPouchStack.getItem(); BaseBagItem bagItem = (BaseBagItem) leftPouchStack.getItem();
int slots = bagItem.getSlotCount(); int slots = bagItem.getSlotCount();
int columns = (int) Math.ceil(slots / 3); int columns = (int) Math.ceil(slots / 3);
int x = ((HandledScreenAccessor) screen).getX() - (columns * 18); int x = sx - (columns * 18);
int y = ((HandledScreenAccessor) screen).getY() + 76; int y = (sy + sh) - 100;
consumer.accept(new Bounds(x, y, columns * 18, 68)); if (screen instanceof GenericContainerScreen || screen instanceof ShulkerBoxScreen) {
y -= 1;
}
int w = (columns * 18);
int h = 68;
consumer.accept(new Bounds(x, y, w, h));
} }
ItemStack rightPouchStack = ScoutUtil.findBagItem(client.player, BagType.POUCH, true); ItemStack rightPouchStack = ScoutUtil.findBagItem(client.player, BagType.POUCH, true);
@ -34,10 +74,17 @@ public class ScoutEmiPlugin implements EmiPlugin {
int slots = bagItem.getSlotCount(); int slots = bagItem.getSlotCount();
int columns = (int) Math.ceil(slots / 3); int columns = (int) Math.ceil(slots / 3);
int x = ((HandledScreenAccessor) screen).getX() + 176; int x = sx + sw;
int y = ((HandledScreenAccessor) screen).getY() + 76; int y = (sy + sh) - 100;
consumer.accept(new Bounds(x, y, columns * 18, 68)); if (screen instanceof GenericContainerScreen || screen instanceof ShulkerBoxScreen) {
y -= 1;
}
int w = (columns * 18);
int h = 68;
consumer.accept(new Bounds(x, y, w, h));
} }
}); });
} }

View file

@ -15,7 +15,6 @@ import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject; import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.Redirect; import org.spongepowered.asm.mixin.injection.Redirect;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
import org.spongepowered.asm.mixin.injection.callback.LocalCapture; import org.spongepowered.asm.mixin.injection.callback.LocalCapture;
import pm.c7.scout.ScoutMixin.Transformer; import pm.c7.scout.ScoutMixin.Transformer;
import pm.c7.scout.ScoutUtil; import pm.c7.scout.ScoutUtil;
@ -23,18 +22,6 @@ import pm.c7.scout.ScoutUtil;
@Mixin(value = ScreenHandler.class, priority = 950) @Mixin(value = ScreenHandler.class, priority = 950)
@Transformer(ScreenHandlerTransformer.class) @Transformer(ScreenHandlerTransformer.class)
public abstract class ScreenHandlerMixin { public abstract class ScreenHandlerMixin {
@Inject(method = "getSlot", at = @At("HEAD"), cancellable = true)
public void scout$fixGetSlot(int index, CallbackInfoReturnable<Slot> cir) {
var playerScreenHandler = ScoutUtil.getPlayerScreenHandler();
if (ScoutUtil.isBagSlot(index)) {
if (playerScreenHandler != null) {
cir.setReturnValue(ScoutUtil.getBagSlot(index, playerScreenHandler));
} else {
cir.setReturnValue(null);
}
}
}
@Inject(method = "internalOnSlotClick", at = @At(value = "INVOKE_ASSIGN", target = "Lnet/minecraft/screen/ScreenHandler;getCursorStack()Lnet/minecraft/item/ItemStack;", ordinal = 11), locals = LocalCapture.CAPTURE_FAILEXCEPTION) @Inject(method = "internalOnSlotClick", at = @At(value = "INVOKE_ASSIGN", target = "Lnet/minecraft/screen/ScreenHandler;getCursorStack()Lnet/minecraft/item/ItemStack;", ordinal = 11), locals = LocalCapture.CAPTURE_FAILEXCEPTION)
public void scout$fixDoubleClick(int slotIndex, int button, SlotActionType actionType, PlayerEntity player, CallbackInfo ci, PlayerInventory playerInventory, Slot slot3) { public void scout$fixDoubleClick(int slotIndex, int button, SlotActionType actionType, PlayerEntity player, CallbackInfo ci, PlayerInventory playerInventory, Slot slot3) {
var cursorStack = this.getCursorStack(); var cursorStack = this.getCursorStack();

View file

@ -1,18 +1,22 @@
package pm.c7.scout.mixin; package pm.c7.scout.mixin.client;
import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.injection.At; import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject; import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
import net.fabricmc.api.EnvType;
import net.fabricmc.api.Environment;
import net.minecraft.util.collection.DefaultedList; import net.minecraft.util.collection.DefaultedList;
import pm.c7.scout.ScoutUtil; import pm.c7.scout.ScoutUtil;
import pm.c7.scout.client.ScoutUtilClient;
@Environment(EnvType.CLIENT)
@Mixin(DefaultedList.class) @Mixin(DefaultedList.class)
public class DefaultedListMixin { public class DefaultedListMixin {
@Inject(method = "get", at = @At("HEAD"), cancellable = true) @Inject(method = "get", at = @At("HEAD"), cancellable = true)
public void scout$fixIndexingSlots(int index, CallbackInfoReturnable<Object> cir) { public void scout$fixIndexingSlots(int index, CallbackInfoReturnable<Object> cir) {
var playerScreenHandler = ScoutUtil.getPlayerScreenHandler(); var playerScreenHandler = ScoutUtilClient.getPlayerScreenHandler();
if (ScoutUtil.isBagSlot(index)) { if (ScoutUtil.isBagSlot(index)) {
if (playerScreenHandler != null) { if (playerScreenHandler != null) {
cir.setReturnValue(ScoutUtil.getBagSlot(index, playerScreenHandler)); cir.setReturnValue(ScoutUtil.getBagSlot(index, playerScreenHandler));

View file

@ -1,6 +1,5 @@
package pm.c7.scout.mixin.client; package pm.c7.scout.mixin.client;
import com.mojang.blaze3d.systems.RenderSystem;
import net.fabricmc.api.EnvType; import net.fabricmc.api.EnvType;
import net.fabricmc.api.Environment; import net.fabricmc.api.Environment;
import net.minecraft.client.gui.DrawContext; import net.minecraft.client.gui.DrawContext;
@ -21,6 +20,7 @@ import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
import pm.c7.scout.ScoutMixin; import pm.c7.scout.ScoutMixin;
import pm.c7.scout.ScoutUtil; import pm.c7.scout.ScoutUtil;
import pm.c7.scout.client.ScoutUtilClient;
import pm.c7.scout.item.BaseBagItem; import pm.c7.scout.item.BaseBagItem;
import pm.c7.scout.screen.BagSlot; import pm.c7.scout.screen.BagSlot;
@ -46,7 +46,7 @@ public abstract class HandledScreenMixin<T extends ScreenHandler> extends Screen
@Inject(method = "render", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/gui/screen/ingame/HandledScreen;drawBackground(Lnet/minecraft/client/gui/DrawContext;FII)V")) @Inject(method = "render", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/gui/screen/ingame/HandledScreen;drawBackground(Lnet/minecraft/client/gui/DrawContext;FII)V"))
private void scout$drawSatchelRow(DrawContext graphics, int mouseX, int mouseY, float delta, CallbackInfo ci) { private void scout$drawSatchelRow(DrawContext graphics, int mouseX, int mouseY, float delta, CallbackInfo ci) {
if (this.client != null && this.client.player != null && !ScoutUtil.isScreenBlacklisted(this)) { if (this.client != null && this.client.player != null && !ScoutUtilClient.isScreenBlacklisted(this)) {
ItemStack backStack = ScoutUtil.findBagItem(this.client.player, BaseBagItem.BagType.SATCHEL, false); ItemStack backStack = ScoutUtil.findBagItem(this.client.player, BaseBagItem.BagType.SATCHEL, false);
if (!backStack.isEmpty()) { if (!backStack.isEmpty()) {
BaseBagItem bagItem = (BaseBagItem) backStack.getItem(); BaseBagItem bagItem = (BaseBagItem) backStack.getItem();
@ -97,7 +97,7 @@ public abstract class HandledScreenMixin<T extends ScreenHandler> extends Screen
@Inject(method = "render", at = @At(value = "INVOKE", target = "Lcom/mojang/blaze3d/systems/RenderSystem;disableDepthTest()V", remap = false)) @Inject(method = "render", at = @At(value = "INVOKE", target = "Lcom/mojang/blaze3d/systems/RenderSystem;disableDepthTest()V", remap = false))
private void scout$drawPouchSlots(DrawContext graphics, int mouseX, int mouseY, float delta, CallbackInfo ci) { private void scout$drawPouchSlots(DrawContext graphics, int mouseX, int mouseY, float delta, CallbackInfo ci) {
if (this.client != null && this.client.player != null && !ScoutUtil.isScreenBlacklisted(this)) { if (this.client != null && this.client.player != null && !ScoutUtilClient.isScreenBlacklisted(this)) {
ItemStack leftPouchStack = ScoutUtil.findBagItem(this.client.player, BaseBagItem.BagType.POUCH, false); ItemStack leftPouchStack = ScoutUtil.findBagItem(this.client.player, BaseBagItem.BagType.POUCH, false);
if (!leftPouchStack.isEmpty()) { if (!leftPouchStack.isEmpty()) {
BaseBagItem bagItem = (BaseBagItem) leftPouchStack.getItem(); BaseBagItem bagItem = (BaseBagItem) leftPouchStack.getItem();
@ -234,7 +234,7 @@ public abstract class HandledScreenMixin<T extends ScreenHandler> extends Screen
@Inject(method = "isClickOutsideBounds", at = @At("TAIL"), cancellable = true) @Inject(method = "isClickOutsideBounds", at = @At("TAIL"), cancellable = true)
private void scout$adjustOutsideBounds(double mouseX, double mouseY, int left, int top, int button, CallbackInfoReturnable<Boolean> callbackInfo) { private void scout$adjustOutsideBounds(double mouseX, double mouseY, int left, int top, int button, CallbackInfoReturnable<Boolean> callbackInfo) {
if (this.client != null && this.client.player != null && !ScoutUtil.isScreenBlacklisted(this)) { if (this.client != null && this.client.player != null && !ScoutUtilClient.isScreenBlacklisted(this)) {
ItemStack backStack = ScoutUtil.findBagItem(this.client.player, BaseBagItem.BagType.SATCHEL, false); ItemStack backStack = ScoutUtil.findBagItem(this.client.player, BaseBagItem.BagType.SATCHEL, false);
if (!backStack.isEmpty()) { if (!backStack.isEmpty()) {
BaseBagItem bagItem = (BaseBagItem) backStack.getItem(); BaseBagItem bagItem = (BaseBagItem) backStack.getItem();
@ -272,7 +272,7 @@ public abstract class HandledScreenMixin<T extends ScreenHandler> extends Screen
@Inject(method = "render", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/gui/screen/ingame/HandledScreen;drawForeground(Lnet/minecraft/client/gui/DrawContext;II)V")) @Inject(method = "render", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/gui/screen/ingame/HandledScreen;drawForeground(Lnet/minecraft/client/gui/DrawContext;II)V"))
public void scout$drawOurSlots(DrawContext graphics, int mouseX, int mouseY, float delta, CallbackInfo ci) { public void scout$drawOurSlots(DrawContext graphics, int mouseX, int mouseY, float delta, CallbackInfo ci) {
if (this.client != null && this.client.player != null && !ScoutUtil.isScreenBlacklisted(this)) { if (this.client != null && this.client.player != null && !ScoutUtilClient.isScreenBlacklisted(this)) {
for (int i = ScoutUtil.SATCHEL_SLOT_START; i > ScoutUtil.BAG_SLOTS_END; i--) { for (int i = ScoutUtil.SATCHEL_SLOT_START; i > ScoutUtil.BAG_SLOTS_END; i--) {
BagSlot slot = (BagSlot) ScoutUtil.getBagSlot(i, this.client.player.playerScreenHandler); BagSlot slot = (BagSlot) ScoutUtil.getBagSlot(i, this.client.player.playerScreenHandler);
if (slot != null && slot.isEnabled()) { if (slot != null && slot.isEnabled()) {
@ -298,7 +298,7 @@ public abstract class HandledScreenMixin<T extends ScreenHandler> extends Screen
@Inject(method = "getSlotAt", at = @At("RETURN"), cancellable = true) @Inject(method = "getSlotAt", at = @At("RETURN"), cancellable = true)
public void scout$addSlots(double x, double y, CallbackInfoReturnable<Slot> cir) { public void scout$addSlots(double x, double y, CallbackInfoReturnable<Slot> cir) {
if (this.client != null && this.client.player != null && !ScoutUtil.isScreenBlacklisted(this)) { if (this.client != null && this.client.player != null && !ScoutUtilClient.isScreenBlacklisted(this)) {
for (int i = ScoutUtil.SATCHEL_SLOT_START; i > ScoutUtil.BAG_SLOTS_END; i--) { for (int i = ScoutUtil.SATCHEL_SLOT_START; i > ScoutUtil.BAG_SLOTS_END; i--) {
BagSlot slot = (BagSlot) ScoutUtil.getBagSlot(i, this.client.player.playerScreenHandler); BagSlot slot = (BagSlot) ScoutUtil.getBagSlot(i, this.client.player.playerScreenHandler);
if (this.isPointOverSlot(slot, x, y) && slot != null && slot.isEnabled()) { if (this.isPointOverSlot(slot, x, y) && slot != null && slot.isEnabled()) {

View file

@ -0,0 +1,29 @@
package pm.c7.scout.mixin.client;
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.CallbackInfoReturnable;
import net.fabricmc.api.EnvType;
import net.fabricmc.api.Environment;
import net.minecraft.screen.ScreenHandler;
import net.minecraft.screen.slot.Slot;
import pm.c7.scout.ScoutUtil;
import pm.c7.scout.client.ScoutUtilClient;
@Environment(EnvType.CLIENT)
@Mixin(value = ScreenHandler.class, priority = 950)
public abstract class ScreenHandlerMixin {
@Inject(method = "getSlot", at = @At("HEAD"), cancellable = true)
public void scout$fixGetSlot(int index, CallbackInfoReturnable<Slot> cir) {
var playerScreenHandler = ScoutUtilClient.getPlayerScreenHandler();
if (ScoutUtil.isBagSlot(index)) {
if (playerScreenHandler != null) {
cir.setReturnValue(ScoutUtil.getBagSlot(index, playerScreenHandler));
} else {
cir.setReturnValue(null);
}
}
}
}