Skip to content

Commit

Permalink
Synfav slot highlighting and various fixes
Browse files Browse the repository at this point in the history
  • Loading branch information
emilyploszaj committed Sep 23, 2023
1 parent 3301e59 commit 3ca0029
Show file tree
Hide file tree
Showing 10 changed files with 122 additions and 41 deletions.
14 changes: 9 additions & 5 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,11 @@
### Tweaks
* Made JEMI recipes without icons default to the first workstation, if present
### Additions
* Synfavs will now highlight missing items in inventories like chests, for quickly finding them
* Added a forward bind for navigating history

### Fixes
* Fixed crafting grid misplacement in misbehaving indexed storage mods #273 #280
* Fixed cheat mode excessive logging #286
* Fixed display of certain JEMI recipes that mutate at runtime #304
* Fixed getting disconnected when attempting to cheat in large nbt on vanilla servers #221
* Fixed inventory overlay not working on screens that reimplement rendering #276
* Fixed history navigation not working properly with non-handled screens #312
* Fixed setting recipe defaults outside of recipe tree context #315
* Fixed endless loop and div by zero caused by absurd abyss exclusion areas #300
* Fixed #268
1 change: 1 addition & 0 deletions xplat/src/main/java/dev/emi/emi/api/EmiApi.java
Original file line number Diff line number Diff line change
Expand Up @@ -182,6 +182,7 @@ private static void push() {
EmiHistory.push(bs);
} else {
EmiHistory.clear();
EmiHistory.push(client.currentScreen);
}
}

Expand Down
5 changes: 5 additions & 0 deletions xplat/src/main/java/dev/emi/emi/api/widget/SlotWidget.java
Original file line number Diff line number Diff line change
Expand Up @@ -288,6 +288,11 @@ private boolean slotInteraction(Function<EmiBind, Boolean> function) {
EmiHistory.pop();
return true;
}
} else {
if (function.apply(EmiConfig.defaultStack)) {
BoM.addRecipe(getStack(), getRecipe());
return true;
}
}
return false;
}
Expand Down
4 changes: 4 additions & 0 deletions xplat/src/main/java/dev/emi/emi/config/EmiConfig.java
Original file line number Diff line number Diff line change
Expand Up @@ -375,6 +375,10 @@ public class EmiConfig {
@ConfigValue("binds.back")
public static EmiBind back = new EmiBind("key.emi.back", GLFW.GLFW_KEY_BACKSPACE);

@Comment("Return to the next page in EMI after going back.")
@ConfigValue("binds.forward")
public static EmiBind forward = new EmiBind("key.emi.forward", InputUtil.UNKNOWN_KEY.getCode());

@ConfigGroup("binds.crafts")
@Comment("When on a stack with an associated recipe:\n"
+ "Move ingredients for a single result.")
Expand Down
18 changes: 0 additions & 18 deletions xplat/src/main/java/dev/emi/emi/mixin/HandledScreenMixin.java
Original file line number Diff line number Diff line change
Expand Up @@ -10,19 +10,15 @@
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;

import dev.emi.emi.EmiPort;
import dev.emi.emi.api.stack.EmiStack;
import dev.emi.emi.platform.EmiAgnos;
import dev.emi.emi.runtime.EmiDrawContext;
import dev.emi.emi.screen.EmiScreen;
import dev.emi.emi.screen.EmiScreenManager;
import dev.emi.emi.search.EmiSearch;
import dev.emi.emi.search.EmiSearch.CompiledQuery;
import net.minecraft.client.gui.DrawContext;
import net.minecraft.client.gui.screen.Screen;
import net.minecraft.client.gui.screen.ingame.HandledScreen;
import net.minecraft.client.gui.screen.recipebook.RecipeBookProvider;
import net.minecraft.client.util.Window;
import net.minecraft.screen.slot.Slot;

@Mixin(HandledScreen.class)
public abstract class HandledScreenMixin extends Screen implements EmiScreen {
Expand Down Expand Up @@ -63,20 +59,6 @@ private void renderForeground(DrawContext raw, int mouseX, int mouseY, float del
context.pop();
}

@Inject(at = @At("TAIL"), method = "drawSlot")
private void drawSlot(DrawContext raw, Slot slot, CallbackInfo info) {
EmiDrawContext context = EmiDrawContext.wrap(raw);
if (EmiScreenManager.search.highlight) {
CompiledQuery query = EmiSearch.compiledQuery;
if (query != null && !query.test(EmiStack.of(slot.getStack()))) {
context.push();
context.matrices().translate(0, 0, 300);
context.fill(slot.x - 1, slot.y - 1, 18, 18, 0x77000000);
context.pop();
}
}
}

@Override
public int emi$getLeft() {
if (this instanceof RecipeBookProvider provider) {
Expand Down
19 changes: 13 additions & 6 deletions xplat/src/main/java/dev/emi/emi/registry/EmiExclusionAreas.java
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

import java.util.List;
import java.util.Map;
import java.util.function.Consumer;

import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
Expand Down Expand Up @@ -39,20 +40,26 @@ public static List<Bounds> getExclusion(Screen screen) {
try {
if (fromClass.containsKey(screen.getClass())) {
for (EmiExclusionArea exclusion : fromClass.get(screen.getClass())) {
exclusion.addExclusionArea(screen, rect -> {
list.add((Bounds) rect);
});
exclusion.addExclusionArea(screen, addBounds(list));
}
}
for (EmiExclusionArea exclusion : generic) {
exclusion.addExclusionArea(screen, rect -> {
list.add((Bounds) rect);
});
exclusion.addExclusionArea(screen, addBounds(list));
}
} catch (Exception e) {
EmiLog.error("Exception thrown when adding exclusion areas");
e.printStackTrace();
}
return list;
}

private static Consumer<Bounds> addBounds(List<Bounds> list) {
return rect -> {
// Impossible sizing, or integer overflow
if (rect.empty() || rect.right() <= rect.x() || rect.bottom() <= rect.y()) {
return;
}
list.add(rect);
};
}
}
6 changes: 3 additions & 3 deletions xplat/src/main/java/dev/emi/emi/runtime/EmiFavorites.java
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@

public class EmiFavorites {
public static List<EmiFavorite> favorites = Lists.newArrayList();
public static List<EmiFavorite> syntheticFavorites = Lists.newArrayList();
public static List<EmiFavorite.Synthetic> syntheticFavorites = Lists.newArrayList();
public static List<EmiFavorite> favoriteSidebar = new CompoundList<>(favorites, syntheticFavorites);

public static JsonArray save() {
Expand Down Expand Up @@ -267,9 +267,9 @@ public static void countRecipes(Object2LongMap<EmiRecipe> batches, Object2LongMa
}

private static class CompoundList<T> extends AbstractList<T> {
private List<T> a, b;
private List<? extends T> a, b;

public CompoundList(List<T> a, List<T> b) {
public CompoundList(List<? extends T> a, List<? extends T> b) {
this.a = a;
this.b = b;
}
Expand Down
29 changes: 23 additions & 6 deletions xplat/src/main/java/dev/emi/emi/runtime/EmiHistory.java
Original file line number Diff line number Diff line change
Expand Up @@ -11,13 +11,19 @@

public class EmiHistory {
private static final List<Screen> HISTORIES = Lists.newArrayList();
private static final List<Screen> FORWARD_HISTORIES = Lists.newArrayList();

public static boolean isEmpty() {
return HISTORIES.isEmpty();
}

public static boolean isForwardEmpty() {
return FORWARD_HISTORIES.isEmpty();
}

public static void push(Screen history) {
HISTORIES.add(history);
FORWARD_HISTORIES.clear();
}

public static void pop() {
Expand All @@ -28,16 +34,27 @@ public static void pop() {
}
int i = HISTORIES.size() - 1;
HandledScreen<?> screen = EmiApi.getHandledScreen();
if (screen != null) {
if (i >= 0) {
client.setScreen(HISTORIES.remove(i));
} else {
client.setScreen(screen);
}
if (i >= 0) {
Screen popped = HISTORIES.remove(i);
FORWARD_HISTORIES.add(client.currentScreen);
client.setScreen(popped);
} else if (screen != null) {
client.setScreen(screen);
}
}

public static void forward() {
MinecraftClient client = MinecraftClient.getInstance();
int i = FORWARD_HISTORIES.size() - 1;
if (i >= 0 && client.currentScreen != null) {
Screen popped = FORWARD_HISTORIES.remove(i);
HISTORIES.add(client.currentScreen);
client.setScreen(popped);
}
}

public static void clear() {
HISTORIES.clear();
FORWARD_HISTORIES.clear();
}
}
66 changes: 63 additions & 3 deletions xplat/src/main/java/dev/emi/emi/screen/EmiScreenManager.java
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package dev.emi.emi.screen;

import java.util.List;
import java.util.Set;
import java.util.function.Function;
import java.util.function.Supplier;
import java.util.stream.Collectors;
Expand All @@ -10,6 +11,7 @@
import org.lwjgl.glfw.GLFW;

import com.google.common.collect.Lists;
import com.google.common.collect.Sets;
import com.mojang.blaze3d.systems.RenderSystem;

import dev.emi.emi.EmiPort;
Expand All @@ -19,6 +21,8 @@
import dev.emi.emi.api.EmiFillAction;
import dev.emi.emi.api.recipe.EmiPlayerInventory;
import dev.emi.emi.api.recipe.EmiRecipe;
import dev.emi.emi.api.recipe.handler.EmiRecipeHandler;
import dev.emi.emi.api.recipe.handler.StandardRecipeHandler;
import dev.emi.emi.api.stack.EmiIngredient;
import dev.emi.emi.api.stack.EmiStack;
import dev.emi.emi.api.stack.EmiStackInteraction;
Expand Down Expand Up @@ -59,6 +63,7 @@
import dev.emi.emi.screen.widget.SidebarButtonWidget;
import dev.emi.emi.screen.widget.SizedButtonWidget;
import dev.emi.emi.search.EmiSearch;
import dev.emi.emi.search.EmiSearch.CompiledQuery;
import net.minecraft.client.MinecraftClient;
import net.minecraft.client.gui.Element;
import net.minecraft.client.gui.ParentElement;
Expand All @@ -69,7 +74,9 @@
import net.minecraft.client.gui.widget.TextFieldWidget;
import net.minecraft.client.sound.PositionedSoundInstance;
import net.minecraft.client.util.math.MatrixStack;
import net.minecraft.entity.player.PlayerInventory;
import net.minecraft.item.ItemStack;
import net.minecraft.screen.slot.Slot;
import net.minecraft.sound.SoundEvents;
import net.minecraft.text.Text;
import net.minecraft.util.Identifier;
Expand Down Expand Up @@ -327,7 +334,7 @@ private static void createScreenSpace(SidebarPanel panel, Screen screen, List<Bo
private static Bounds constrainBounds(List<Bounds> exclusion, Bounds bounds, ScreenAlign align, int headerOffset) {
for (int i = 0; i < exclusion.size(); i++) {
Bounds overlap = exclusion.get(i).overlap(bounds);
if (!overlap.empty()) {
if (!overlap.empty() && !bounds.empty()) {
if (overlap.top() < bounds.top() + ENTRY_SIZE + headerOffset || overlap.width() >= bounds.width() / 2
|| overlap.height() >= bounds.height() / 3) {
int widthFactor = overlap.width() * 10 / bounds.width();
Expand Down Expand Up @@ -596,6 +603,9 @@ public static void render(EmiDrawContext context, int mouseX, int mouseY, float
client.getProfiler().pop();

renderExclusionAreas(context, mouseX, mouseY, delta, screen);

client.getProfiler().swap("slots");
renderSlotOverlays(context, mouseX, mouseY, delta, screen);
client.getProfiler().pop();

RenderSystem.disableDepthTest();
Expand Down Expand Up @@ -773,6 +783,49 @@ private static void renderExclusionAreas(EmiDrawContext context, int mouseX, int
}
}

@SuppressWarnings({"rawtypes", "unchecked"})
private static void renderSlotOverlays(EmiDrawContext context, int mouseX, int mouseY, float delta, Screen screen) {
CompiledQuery query = null;
if (EmiScreenManager.search.highlight) {
query = EmiSearch.compiledQuery;
}
Set<Slot> ignoredSlots = Sets.newHashSet();
Set<EmiStack> synfavs = Sets.newHashSet();
if (BoM.craftingMode && BoM.tree != null) {
List<EmiFavorite.Synthetic> syntheticFavorites = EmiFavorites.syntheticFavorites;
for (EmiFavorite.Synthetic fav : syntheticFavorites) {
synfavs.addAll(fav.getEmiStacks());
}

for (EmiRecipeHandler handler : EmiRecipeFiller.getAllHandlers(EmiApi.getHandledScreen())) {
if (handler instanceof StandardRecipeHandler standard) {
ignoredSlots.addAll(standard.getInputSources(EmiApi.getHandledScreen().getScreenHandler()));
ignoredSlots.addAll(standard.getCraftingSlots(EmiApi.getHandledScreen().getScreenHandler()));
}
}
}
if (screen instanceof HandledScreen<?> hs && screen instanceof EmiScreen emi) {
context.push();
context.matrices().translate(emi.emi$getLeft(), emi.emi$getTop(), 0);
for (Slot slot : hs.getScreenHandler().slots) {
EmiStack stack = EmiStack.of(slot.getStack());
context.push();
context.matrices().translate(0, 0, 300);
if (query != null) {
if (!query.test(stack)) {
context.fill(slot.x - 1, slot.y - 1, 18, 18, 0x77000000);
}
} else if (BoM.craftingMode && BoM.tree != null) {
if (!(slot.inventory instanceof PlayerInventory) && !ignoredSlots.contains(slot) && synfavs.contains(stack)) {
context.fill(slot.x - 1, slot.y - 1, 18, 18, 0x7700BBFF);
}
}
context.pop();
}
context.pop();
}
}

public static void addWidgets(Screen screen) {
forceRecalculate();
if (EmiConfig.centerSearchBar) {
Expand Down Expand Up @@ -1011,6 +1064,11 @@ public static boolean genericInteraction(Function<EmiBind, Boolean> function) {
EmiHistory.pop();
return true;
}
} else if (function.apply(EmiConfig.forward)) {
if (!EmiHistory.isForwardEmpty()) {
EmiHistory.forward();
return true;
}
}
return false;
}
Expand Down Expand Up @@ -1162,8 +1220,10 @@ private static boolean give(EmiStack stack, int amount, int mode) {
command += is.getNbt().toString();
}
command += " " + amount;
client.player.networkHandler.sendChatCommand(command);
return true;
if (command.length() < 256) {
client.player.networkHandler.sendChatCommand(command);
return true;
}
}
return false;
}
Expand Down
1 change: 1 addition & 0 deletions xplat/src/main/resources/assets/emi/lang/en_us.json
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
"key.emi.view_stack_tree": "View Stack Tree",
"key.emi.view_tree": "View Tree",
"key.emi.back": "Back",
"key.emi.forward": "Forward",
"key.emi.craft_one": "Craft One",
"key.emi.craft_all": "Craft All",
"key.emi.craft_one_to_inventory": "Craft One to Inventory",
Expand Down

0 comments on commit 3ca0029

Please sign in to comment.