mirror of
https://github.com/GTNewHorizons/NotEnoughItems.git
synced 2026-10-26 22:33:52 +00:00
Compare commits
88
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
2169ba03d0 | ||
|
|
7f182757c3 | ||
|
|
83ee2e0d53 | ||
|
|
ff518c81b3 | ||
|
|
5fb5ab6698 | ||
|
|
f47a8766a9 | ||
|
|
4cc72444d9 | ||
|
|
b48956ef94 | ||
|
|
583d28ed12 | ||
|
|
384813347c | ||
|
|
2660460c87 | ||
|
|
2b28068382 | ||
|
|
1767d4be63 | ||
|
|
e6684ddebb | ||
|
|
89110ccb7e | ||
|
|
434b4ac879 | ||
|
|
24e6f7c57d | ||
|
|
2c204c25aa | ||
|
|
5e6ff1d63b | ||
|
|
53ce50b35a | ||
|
|
835c4f7e01 | ||
|
|
f8c1f39faf | ||
|
|
4c4716e64f | ||
|
|
c84ac27a18 | ||
|
|
47baee272c | ||
|
|
f55dc716e3 | ||
|
|
26beb079f0 | ||
|
|
841b73c6fe | ||
|
|
0c7eeebb1f | ||
|
|
65b56735a7 | ||
|
|
ff428bf538 | ||
|
|
a406021f26 | ||
|
|
8500ac57eb | ||
|
|
d97123ec13 | ||
|
|
434931bfac | ||
|
|
860011036b | ||
|
|
937c1858a4 | ||
|
|
4562ecf087 | ||
|
|
d621d5d5bd | ||
|
|
3175b316af | ||
|
|
61930ac7a8 | ||
|
|
fcbf1dcade | ||
|
|
3fa69e826c | ||
|
|
31fff21a55 | ||
|
|
2e9ab88692 | ||
|
|
a02d293d44 | ||
|
|
1265113390 | ||
|
|
4ffd614017 | ||
|
|
41554f4c5b | ||
|
|
2104184077 | ||
|
|
d5f25a4be8 | ||
|
|
ccbf94790a | ||
|
|
2f4f72a2d6 | ||
|
|
f8cec9a78c | ||
|
|
fb43a662eb | ||
|
|
b2e0b8878a | ||
|
|
374f019103 | ||
|
|
5dfcff6f30 | ||
|
|
bd17301cb9 | ||
|
|
96ccd4e109 | ||
|
|
b30ca57e68 | ||
|
|
8f949bc1d1 | ||
|
|
d25365942a | ||
|
|
eb58e1dabc | ||
|
|
f4601e7eed | ||
|
|
ba48806667 | ||
|
|
70c332796a | ||
|
|
bcc25d4369 | ||
|
|
10a3109714 | ||
|
|
b60769864f | ||
|
|
6bc899769f | ||
|
|
0ba14091fb | ||
|
|
6ed0be7961 | ||
|
|
d40b951cce | ||
|
|
ecdf7892ce | ||
|
|
1eaaac94bc | ||
|
|
e99167dddb | ||
|
|
34cb0dc43f | ||
|
|
acaad4bf91 | ||
|
|
3de75f4e26 | ||
|
|
47497090ea | ||
|
|
8b45a1757f | ||
|
|
2782f8252e | ||
|
|
a5538b2566 | ||
|
|
a1f324b796 | ||
|
|
f3b6be26df | ||
|
|
9c764e3682 | ||
|
|
08605c3d73 |
No files matched your search
@@ -0,0 +1,17 @@
|
||||
name: Optimize images
|
||||
|
||||
on:
|
||||
pull_request:
|
||||
branches: [ master, main, release/** ]
|
||||
paths:
|
||||
- "**/*.png"
|
||||
|
||||
push:
|
||||
branches: [ master, main, release/** ]
|
||||
paths:
|
||||
- "**/*.png"
|
||||
|
||||
jobs:
|
||||
optimize-images:
|
||||
uses: GTNewHorizons/GTNH-Actions-Workflows/.github/workflows/optimize-images.yml@master
|
||||
secrets: inherit
|
||||
+18
-2
@@ -1,8 +1,12 @@
|
||||
// Add your dependencies here
|
||||
configurations.create('gtnhlibEmbed') {
|
||||
canBeConsumed = false
|
||||
canBeResolved = true
|
||||
}
|
||||
|
||||
dependencies {
|
||||
api('com.github.GTNewHorizons:CodeChickenCore:1.4.10:dev')
|
||||
implementation('com.github.GTNewHorizons:GTNHLib:0.9.13:dev')
|
||||
api('com.github.GTNewHorizons:CodeChickenCore:1.4.16:dev')
|
||||
devOnlyNonPublishable('com.github.GTNewHorizons:GTNHLib:0.11.23:dev')
|
||||
|
||||
shadowImplementation('org.apache.commons:commons-csv:1.10.0')
|
||||
|
||||
@@ -17,4 +21,16 @@ dependencies {
|
||||
|
||||
testRuntimeOnly('org.junit.platform:junit-platform-launcher')
|
||||
testRuntimeOnly("org.lwjgl.lwjgl:lwjgl:2.9.3");
|
||||
|
||||
compileOnly("com.github.GTNewHorizons:GTNHLib:0.11.23") { transitive = false }
|
||||
gtnhlibEmbed("com.github.GTNewHorizons:GTNHLib:0.11.23") { transitive = false }
|
||||
}
|
||||
|
||||
[tasks.jar, tasks.shadowJar].each {
|
||||
it.configure {
|
||||
from({ project.configurations.getByName('gtnhlibEmbed').collect { zipTree(it) } }) {
|
||||
include 'com/gtnewhorizon/gtnhlib/color/ColorResource.class'
|
||||
include 'com/gtnewhorizon/gtnhlib/color/ColorResource$*.class'
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,12 +1,12 @@
|
||||
#This file is generated by updateDaemonJvm
|
||||
toolchainUrl.FREE_BSD.AARCH64=https\://api.foojay.io/disco/v3.0/ids/df211d3c3eefdc408b462041881bc575/redirect
|
||||
toolchainUrl.FREE_BSD.X86_64=https\://api.foojay.io/disco/v3.0/ids/b41931cf1e70bc8e08d7dd19c343ef00/redirect
|
||||
toolchainUrl.LINUX.AARCH64=https\://api.foojay.io/disco/v3.0/ids/4945f00643ec68e7c7a6b66f90124f89/redirect
|
||||
toolchainUrl.LINUX.X86_64=https\://api.foojay.io/disco/v3.0/ids/93aeea858331bd6bb00ba94759830234/redirect
|
||||
toolchainUrl.MAC_OS.AARCH64=https\://api.foojay.io/disco/v3.0/ids/3426ffcaa54c3f62406beb1f1ab8b179/redirect
|
||||
toolchainUrl.MAC_OS.X86_64=https\://api.foojay.io/disco/v3.0/ids/f636c800fdb3f9ae33f019dfa048ba72/redirect
|
||||
toolchainUrl.UNIX.AARCH64=https\://api.foojay.io/disco/v3.0/ids/df211d3c3eefdc408b462041881bc575/redirect
|
||||
toolchainUrl.UNIX.X86_64=https\://api.foojay.io/disco/v3.0/ids/93aeea858331bd6bb00ba94759830234/redirect
|
||||
toolchainUrl.WINDOWS.AARCH64=https\://api.foojay.io/disco/v3.0/ids/3cd7045fca9a72cd9bc7d14a385e594c/redirect
|
||||
toolchainUrl.WINDOWS.X86_64=https\://api.foojay.io/disco/v3.0/ids/552c7bffe0370c66410a51c55985b511/redirect
|
||||
toolchainUrl.FREE_BSD.AARCH64=https\://api.foojay.io/disco/v3.0/ids/cf726b4a1c84b50457225f9bba6d7650/redirect
|
||||
toolchainUrl.FREE_BSD.X86_64=https\://api.foojay.io/disco/v3.0/ids/fa1e318c287360478e3c83a9a3ef1007/redirect
|
||||
toolchainUrl.LINUX.AARCH64=https\://api.foojay.io/disco/v3.0/ids/cf726b4a1c84b50457225f9bba6d7650/redirect
|
||||
toolchainUrl.LINUX.X86_64=https\://api.foojay.io/disco/v3.0/ids/fa1e318c287360478e3c83a9a3ef1007/redirect
|
||||
toolchainUrl.MAC_OS.AARCH64=https\://api.foojay.io/disco/v3.0/ids/c2dd35c9d0aaf0ba6ad0791320f99dfc/redirect
|
||||
toolchainUrl.MAC_OS.X86_64=https\://api.foojay.io/disco/v3.0/ids/e5810bd7fd1f8a586644409d395a7e55/redirect
|
||||
toolchainUrl.UNIX.AARCH64=https\://api.foojay.io/disco/v3.0/ids/cf726b4a1c84b50457225f9bba6d7650/redirect
|
||||
toolchainUrl.UNIX.X86_64=https\://api.foojay.io/disco/v3.0/ids/fa1e318c287360478e3c83a9a3ef1007/redirect
|
||||
toolchainUrl.WINDOWS.AARCH64=https\://api.foojay.io/disco/v3.0/ids/7b3c4877c0749019e6805bb61e421497/redirect
|
||||
toolchainUrl.WINDOWS.X86_64=https\://api.foojay.io/disco/v3.0/ids/d76df094a9cbbabd3b08251f9e61444a/redirect
|
||||
toolchainVersion=25
|
||||
Vendored
BIN
Binary file not shown.
+1
-1
@@ -1,6 +1,6 @@
|
||||
distributionBase=GRADLE_USER_HOME
|
||||
distributionPath=wrapper/dists
|
||||
distributionUrl=https\://services.gradle.org/distributions/gradle-9.2.1-bin.zip
|
||||
distributionUrl=https\://services.gradle.org/distributions/gradle-9.4.0-bin.zip
|
||||
networkTimeout=10000
|
||||
validateDistributionUrl=true
|
||||
zipStoreBase=GRADLE_USER_HOME
|
||||
|
||||
@@ -57,7 +57,7 @@
|
||||
# Darwin, MinGW, and NonStop.
|
||||
#
|
||||
# (3) This script is generated from the Groovy template
|
||||
# https://github.com/gradle/gradle/blob/HEAD/platforms/jvm/plugins-application/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt
|
||||
# https://github.com/gradle/gradle/blob/b631911858264c0b6e4d6603d677ff5218766cee/platforms/jvm/plugins-application/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt
|
||||
# within the Gradle project.
|
||||
#
|
||||
# You can find Gradle at https://github.com/gradle/gradle/.
|
||||
|
||||
+1
-1
@@ -17,7 +17,7 @@ pluginManagement {
|
||||
}
|
||||
|
||||
plugins {
|
||||
id 'com.gtnewhorizons.gtnhsettingsconvention' version '2.0.19'
|
||||
id 'com.gtnewhorizons.gtnhsettingsconvention' version '2.0.26'
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -19,6 +19,7 @@ import net.minecraft.client.gui.inventory.GuiContainer;
|
||||
import net.minecraft.entity.player.InventoryPlayer;
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.nbt.NBTTagCompound;
|
||||
import net.minecraft.util.EnumChatFormatting;
|
||||
|
||||
import org.apache.commons.io.IOUtils;
|
||||
|
||||
@@ -184,27 +185,33 @@ public class BookmarkPanel extends PanelWidget<BookmarkGrid> {
|
||||
if (itemStack != null && this.grid.indexOf(groupId, itemStack, recipeId, false) == -1) {
|
||||
final boolean existsRecipe = recipeId != null
|
||||
&& this.grid.existsRecipe(recipeId, BookmarkGrid.DEFAULT_GROUP_ID);
|
||||
final NBTTagCompound nbTag = StackInfo.itemStackToNBT(itemStack);
|
||||
long count = nbTag.getInteger("Count");
|
||||
long factor = existsRecipe ? Math.max(count, 1) : 1;
|
||||
final Recipe recipe = Recipe.of(recipeId);
|
||||
final BookmarkItem.Builder builder;
|
||||
|
||||
if (recipe != null) {
|
||||
builder = BookmarkItem.builder(groupId, itemStack, recipe, BookmarkItemType.RESULT).multiplier(1);
|
||||
} else if (recipeId != null) {
|
||||
builder = BookmarkItem.builder(groupId, itemStack).recipeId(recipeId)
|
||||
.factor(StackInfo.getAmount(itemStack)).multiplier(1);
|
||||
} else {
|
||||
builder = BookmarkItem.builder(groupId, itemStack).factor(1).multiplier(StackInfo.getAmount(itemStack));
|
||||
}
|
||||
|
||||
if (existsRecipe) {
|
||||
builder.type(BookmarkItemType.RESULT);
|
||||
|
||||
for (int i = 0; i < this.grid.size(); i++) {
|
||||
if (this.grid.getBookmarkItem(i).equalsRecipe(recipeId, groupId)) {
|
||||
count *= this.grid.getBookmarkItem(i).getMultiplier();
|
||||
builder.multiplier(this.grid.getBookmarkItem(i).getMultiplier());
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
} else {
|
||||
builder.type(BookmarkItemType.ITEM);
|
||||
}
|
||||
|
||||
this.grid.addItem(
|
||||
BookmarkItem.of(
|
||||
groupId,
|
||||
StackInfo.withAmount(itemStack, count),
|
||||
factor,
|
||||
recipeId,
|
||||
existsRecipe ? BookmarkItemType.RESULT : BookmarkItemType.ITEM),
|
||||
true);
|
||||
this.grid.addItem(builder.build(), true);
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -212,9 +219,11 @@ public class BookmarkPanel extends PanelWidget<BookmarkGrid> {
|
||||
}
|
||||
|
||||
public boolean addRecipe(Recipe recipe, int multiplier, int groupId) {
|
||||
if (recipe == null) return false;
|
||||
|
||||
final RecipeId recipeId = recipe.getRecipeId();
|
||||
|
||||
if (recipe != null && this.grid.getGroup(groupId) != null && !this.grid.existsRecipe(recipeId, groupId)) {
|
||||
if (this.grid.getGroup(groupId) != null && !this.grid.existsRecipe(recipeId, groupId)) {
|
||||
this.grid.addRecipe(recipe, multiplier, groupId);
|
||||
return true;
|
||||
}
|
||||
@@ -245,15 +254,22 @@ public class BookmarkPanel extends PanelWidget<BookmarkGrid> {
|
||||
ItemStack stack = recipeId.getResult();
|
||||
|
||||
if (stack != null && uniqueRecipe.add(recipeId)) {
|
||||
this.grid.addItem(
|
||||
BookmarkItem
|
||||
.of(groupId, stack, StackInfo.getAmount(stack), recipeId, BookmarkItemType.ITEM),
|
||||
true);
|
||||
final Recipe recipe = Recipe.of(recipeId);
|
||||
final BookmarkItem.Builder builder;
|
||||
|
||||
if (recipe != null) {
|
||||
builder = BookmarkItem.builder(groupId, stack, recipe, BookmarkItemType.RESULT);
|
||||
} else {
|
||||
builder = BookmarkItem.builder(groupId, stack).recipeId(recipeId)
|
||||
.factor(StackInfo.getAmount(stack));
|
||||
}
|
||||
|
||||
this.grid.addItem(builder.multiplier(1).type(BookmarkItemType.ITEM).build(), true);
|
||||
uniqueStack.add(stack);
|
||||
}
|
||||
|
||||
} else {
|
||||
ItemStack stack = extractItem(item);
|
||||
final ItemStack stack = extractItem(item);
|
||||
|
||||
if (stack != null && !uniqueStack.contains(stack)) {
|
||||
this.grid.addItem(BookmarkItem.of(groupId, stack), true);
|
||||
@@ -510,8 +526,7 @@ public class BookmarkPanel extends PanelWidget<BookmarkGrid> {
|
||||
}
|
||||
|
||||
@Override
|
||||
public Rectangle4i calculateBounds() {
|
||||
final GuiContainer gui = NEIClientUtils.getGuiContainer();
|
||||
public Rectangle4i calculateBounds(GuiContainer gui) {
|
||||
final int maxWidth = (gui.width - 176) / 2 - PADDING * 2;
|
||||
final int maxHeight = gui.height - PADDING * 2;
|
||||
final int freeSpace = (gui.width - gui.xSize) / 2 - PADDING * 2;
|
||||
@@ -784,15 +799,15 @@ public class BookmarkPanel extends PanelWidget<BookmarkGrid> {
|
||||
NEIMouseUtils.getKeyName(NEIMouseUtils.MOUSE_BTN_RMB),
|
||||
NEIClientUtils.translate("bookmark.group.toggle_crafting_chain"));
|
||||
hotkeys.put(
|
||||
NEIClientConfig.getKeyName("gui.remove_recipe"),
|
||||
KeyManager.getKeyName("bookmark.remove_recipe", NEIClientUtils.SHIFT_HASH),
|
||||
NEIClientUtils.translate("bookmark.group.remove_recipe"));
|
||||
|
||||
if (BookmarkContainerInfo.getBookmarkContainerHandler(NEIClientUtils.getGuiContainer()) != null) {
|
||||
hotkeys.put(
|
||||
NEIClientConfig.getKeyName("gui.bookmark_pull_items"),
|
||||
KeyManager.getKeyName("bookmark.pull_items"),
|
||||
NEIClientUtils.translate("bookmark.group.pull_items"));
|
||||
hotkeys.put(
|
||||
NEIClientConfig.getKeyName("gui.bookmark_pull_items", NEIClientUtils.SHIFT_HASH),
|
||||
KeyManager.getKeyName("bookmark.pull_items", NEIClientUtils.SHIFT_HASH),
|
||||
NEIClientUtils.translate("bookmark.group.pull_items_shift"));
|
||||
}
|
||||
|
||||
@@ -926,6 +941,17 @@ public class BookmarkPanel extends PanelWidget<BookmarkGrid> {
|
||||
|
||||
if (slot != null) {
|
||||
|
||||
if (slot.getBookmarkItem().chance != PositionedStack.CHANCE_FULL) {
|
||||
final String chanceText = NEIClientUtils
|
||||
.formatChance(slot.getBookmarkItem().chance / (float) PositionedStack.CHANCE_FULL);
|
||||
currenttip.add(
|
||||
1,
|
||||
EnumChatFormatting.GRAY + NEIClientUtils.translate(
|
||||
slot.getType() == BookmarkItemType.INGREDIENT ? "recipe.badge.chance.consume"
|
||||
: "recipe.badge.chance.output",
|
||||
chanceText));
|
||||
}
|
||||
|
||||
if (slot.getType() == BookmarkItemType.INGREDIENT && slot.getRecipeId() != null
|
||||
&& slot.getBookmarkItem().permutations.size() > 1) {
|
||||
RecipeId recipeId = slot.getRecipeId();
|
||||
@@ -1120,7 +1146,7 @@ public class BookmarkPanel extends PanelWidget<BookmarkGrid> {
|
||||
|
||||
for (BookmarkItem item : math.initialItems) {
|
||||
final long invStackSize = inventory.getOrDefault(item.itemStack, 0L);
|
||||
final long amount = item.amount - invStackSize * item.fluidCellAmount;
|
||||
final long amount = item.getAmount() - invStackSize * item.fluidCellAmount;
|
||||
if (amount > 0) {
|
||||
pullItemStacks.add(item.getItemStack(amount));
|
||||
}
|
||||
@@ -1134,7 +1160,7 @@ public class BookmarkPanel extends PanelWidget<BookmarkGrid> {
|
||||
for (BookmarkItem item : math.initialItems) {
|
||||
final long invStackSize = inventory.getOrDefault(item.itemStack, 0L);
|
||||
final long strStackSize = containerStorage.getOrDefault(item.itemStack, 0L);
|
||||
final long amount = item.amount - invStackSize * item.fluidCellAmount
|
||||
final long amount = item.getAmount() - invStackSize * item.fluidCellAmount
|
||||
- strStackSize * item.fluidCellAmount;
|
||||
|
||||
if (amount > 0) {
|
||||
@@ -1268,7 +1294,7 @@ public class BookmarkPanel extends PanelWidget<BookmarkGrid> {
|
||||
public BookmarkRecipeId getBookmarkRecipeId(int itemIndex) {
|
||||
BookmarkItem item = this.grid.getCalculatedItem(itemIndex);
|
||||
return item == null || item.type == BookmarkItemType.INGREDIENT || item.recipeId == null ? null
|
||||
: new BookmarkRecipeId(item.recipeId.getHandleName(), item.recipeId.getIngredients());
|
||||
: new BookmarkRecipeId(item.recipeId.getHandlerName(), item.recipeId.getIngredients());
|
||||
}
|
||||
|
||||
@Deprecated
|
||||
|
||||
@@ -57,6 +57,10 @@ public abstract class Button extends Widget {
|
||||
return label;
|
||||
}
|
||||
|
||||
public int getRenderLabelColor() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
public final String label;
|
||||
public Image icon;
|
||||
|
||||
|
||||
@@ -45,6 +45,7 @@ import codechicken.core.ClassDiscoverer;
|
||||
import codechicken.core.ClientUtils;
|
||||
import codechicken.lib.packet.PacketCustom;
|
||||
import codechicken.nei.api.API;
|
||||
import codechicken.nei.api.GuiInfo;
|
||||
import codechicken.nei.api.IConfigureNEI;
|
||||
import codechicken.nei.api.ItemInfo;
|
||||
import codechicken.nei.guihook.GuiContainerManager;
|
||||
@@ -374,6 +375,7 @@ public class ClientHandler {
|
||||
} else if (event.gui == null) {
|
||||
/* prevent WorldClient reference being held in the Gui */
|
||||
NEIController.manager = null;
|
||||
GuiInfo.clearGuiHandlers();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,22 @@
|
||||
package codechicken.nei;
|
||||
|
||||
import com.gtnewhorizon.gtnhlib.color.ColorResource;
|
||||
|
||||
public class ColorUtils {
|
||||
|
||||
private static final ColorResource.Factory color = new ColorResource.Factory("nei");
|
||||
|
||||
public static final ColorResource
|
||||
// spotless:off
|
||||
textGray = color.rgb("textGray", "0x404040"),
|
||||
textLightGray = color.rgb("textLightGray", "0x606060"),
|
||||
recipeTitle = color.rgb("recipeTitle", "0xFFFFFF"),
|
||||
recipeTitleHover = color.rgb("recipeTitleHover", "0xFFFF55"),
|
||||
subsetWidget = color.rgb("subsetWidget", "0xAA00AA"),
|
||||
recipeBadge = color.rgb("recipeBadge", "0xFDD835"),
|
||||
buttonLabelNormal = color.rgb("buttonLabelNormal", "0xE0E0E0"),
|
||||
buttonLabelHover = color.rgb("buttonLabelHover", "0xFFFFA0"),
|
||||
buttonLabelDisabled = color.rgb("buttonLabelDisabled", "0x601010"),
|
||||
buttonLabelInactive = color.rgb("buttonLabelInactive", "0xA0A0A0");
|
||||
// spotless:on
|
||||
}
|
||||
@@ -12,35 +12,137 @@ import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Optional;
|
||||
import java.util.Objects;
|
||||
import java.util.Set;
|
||||
|
||||
import net.minecraft.item.Item;
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.nbt.NBTTagCompound;
|
||||
import net.minecraftforge.fluids.FluidRegistry;
|
||||
import net.minecraftforge.fluids.FluidStack;
|
||||
|
||||
import org.apache.commons.io.IOUtils;
|
||||
|
||||
import com.google.common.io.Files;
|
||||
import com.google.gson.JsonObject;
|
||||
import com.google.gson.JsonParser;
|
||||
import com.google.gson.JsonSyntaxException;
|
||||
|
||||
import codechicken.core.CommonUtils;
|
||||
import codechicken.nei.api.API;
|
||||
import codechicken.nei.recipe.GuiCraftingRecipe;
|
||||
import codechicken.nei.recipe.GuiRecipeTab;
|
||||
import codechicken.nei.recipe.ICraftingHandler;
|
||||
import codechicken.nei.recipe.IRecipeHandler;
|
||||
import codechicken.nei.recipe.Recipe.RecipeId;
|
||||
import codechicken.nei.recipe.RecipeHandlerRef;
|
||||
import codechicken.nei.recipe.StackInfo;
|
||||
import codechicken.nei.util.FavoriteStorage;
|
||||
import codechicken.nei.util.NBTJson;
|
||||
|
||||
public class FavoriteRecipes {
|
||||
|
||||
private static final Set<NBTTagCompound> tools = new HashSet<>();
|
||||
private static final Map<NBTTagCompound, RecipeId> items = new HashMap<>();
|
||||
private static final Map<String, RecipeId> fluids = new HashMap<>();
|
||||
protected static final class FastKey {
|
||||
|
||||
public final ItemStack stack;
|
||||
private int hash;
|
||||
|
||||
public FastKey(ItemStack stack) {
|
||||
this.stack = stack;
|
||||
|
||||
this.hash = 31 + Item.getIdFromItem(stack.getItem());
|
||||
this.hash = 31 * this.hash + stack.getItemDamage();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return this.hash;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (this == o) return true;
|
||||
|
||||
if (o instanceof FastKey k && this.stack.getItem() == k.stack.getItem()
|
||||
&& this.stack.getItemDamage() == k.stack.getItemDamage()) {
|
||||
return this.stack == k.stack || Objects.equals(this.stack.stackTagCompound, k.stack.stackTagCompound);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
private static final RestartableTask singleRecipeFavoritesTask = new RestartableTask(
|
||||
"Generate Single-Recipe Favorites") {
|
||||
|
||||
@Override
|
||||
public void execute() {
|
||||
final List<ICraftingHandler> handlers = GuiCraftingRecipe.getCraftingHandlers("all");
|
||||
final Map<FastKey, RecipeHandlerRef> autogeneratedRecipes = new HashMap<>();
|
||||
final Set<FastKey> whitelistItems = new HashSet<>(ItemList.items.size());
|
||||
final FavoriteStorage storage = new FavoriteStorage();
|
||||
|
||||
for (ItemStack stack : ItemList.items) {
|
||||
whitelistItems.add(new FastKey(stack));
|
||||
}
|
||||
|
||||
if (interrupted()) return;
|
||||
|
||||
for (ICraftingHandler handler : handlers) {
|
||||
if (!GuiRecipeTab.getHandlerInfo(handler).getShowFavoritesButton()) continue;
|
||||
|
||||
for (int i = 0; i < handler.numRecipes(); i++) {
|
||||
RecipeHandlerRef ref = null;
|
||||
|
||||
for (PositionedStack result : getOutputs(handler, i)) {
|
||||
ItemStack stack = StackInfo.getItemStackWithMinimumDamage(result.items);
|
||||
final FastKey key = new FastKey(stack);
|
||||
|
||||
if (!whitelistItems.contains(key)) continue;
|
||||
|
||||
if (autogeneratedRecipes.get(key) == null) {
|
||||
|
||||
if (ref == null) {
|
||||
ref = RecipeHandlerRef.of(handler, i);
|
||||
}
|
||||
|
||||
autogeneratedRecipes.put(key, ref);
|
||||
} else {
|
||||
autogeneratedRecipes.remove(key);
|
||||
whitelistItems.remove(key);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
if (interrupted()) return;
|
||||
}
|
||||
|
||||
final Map<RecipeHandlerRef, RecipeId> recipesCache = new HashMap<>();
|
||||
|
||||
for (Map.Entry<FastKey, RecipeHandlerRef> entry : autogeneratedRecipes.entrySet()) {
|
||||
final RecipeId recipeId = recipesCache
|
||||
.computeIfAbsent(entry.getValue(), r -> RecipeId.of(r.handler, r.recipeIndex));
|
||||
storage.add(entry.getKey().stack, recipeId);
|
||||
}
|
||||
|
||||
FavoriteRecipes.autoFavorites = storage;
|
||||
updateSubsetVisibility();
|
||||
}
|
||||
|
||||
protected List<PositionedStack> getOutputs(IRecipeHandler handler, int recipeIndex) {
|
||||
final List<PositionedStack> pStackResults = handler.getResultStacks(recipeIndex);
|
||||
return !pStackResults.isEmpty() ? pStackResults : handler.getOtherStacks(recipeIndex);
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
public static final String FAVORITE_ITEM = "FavoriteItem";
|
||||
private static final FavoriteStorage manualFavorites = new FavoriteStorage();
|
||||
private static FavoriteStorage autoFavorites = new FavoriteStorage();
|
||||
private static File favoriteFile;
|
||||
private static int revision = 0;
|
||||
|
||||
static {
|
||||
API.addSubset("Favorites", FavoriteRecipes::contains);
|
||||
API.addSubset("Favorites.Manual", manualFavorites::contains);
|
||||
API.addSubset("Favorites.Generated", stack -> FavoriteRecipes.autoFavorites.contains(stack));
|
||||
}
|
||||
|
||||
private FavoriteRecipes() {}
|
||||
@@ -66,7 +168,6 @@ public class FavoriteRecipes {
|
||||
final File defaultFavorites = configFavorites.exists() ? configFavorites : globalFavorites;
|
||||
|
||||
if (defaultFavorites.exists()) {
|
||||
|
||||
try {
|
||||
if (favoriteFile.createNewFile()) {
|
||||
InputStream src = new FileInputStream(defaultFavorites);
|
||||
@@ -101,7 +202,9 @@ public class FavoriteRecipes {
|
||||
}
|
||||
|
||||
final JsonParser parser = new JsonParser();
|
||||
items.clear();
|
||||
boolean hasErrors = false;
|
||||
|
||||
manualFavorites.clear();
|
||||
|
||||
for (String itemStr : itemStrings) {
|
||||
|
||||
@@ -121,70 +224,97 @@ public class FavoriteRecipes {
|
||||
continue;
|
||||
}
|
||||
|
||||
final String fluidKey = getFluidKey(stack);
|
||||
|
||||
if (fluidKey != null) {
|
||||
fluids.put(fluidKey, recipeId);
|
||||
if (FAVORITE_ITEM.equals(recipeId.getHandlerName()) || RecipeHandlerRef.of(recipeId) != null) {
|
||||
manualFavorites.add(stack, recipeId);
|
||||
} else {
|
||||
hasErrors = true;
|
||||
}
|
||||
|
||||
items.put(itemStackNBT, recipeId);
|
||||
|
||||
if (NEIServerUtils.isItemTool(stack)) {
|
||||
tools.add(itemStackNBT);
|
||||
}
|
||||
}
|
||||
|
||||
} catch (Exception e) {
|
||||
NEIClientConfig.logger.error("Failed to load favorite from json string: {}", itemStr);
|
||||
hasErrors = true;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
SubsetWidget.updateHiddenItems();
|
||||
if (hasErrors) {
|
||||
|
||||
try {
|
||||
Files.copy(
|
||||
favoriteFile,
|
||||
new File(favoriteFile.getAbsolutePath() + ".backup-" + System.currentTimeMillis()));
|
||||
NEIClientConfig.logger.info("Backed up invalid favorite file to {}", favoriteFile);
|
||||
} catch (IOException e) {
|
||||
NEIClientConfig.logger.error("Failed to backup invalid favorite file to {}", favoriteFile, e);
|
||||
}
|
||||
|
||||
save();
|
||||
}
|
||||
|
||||
loadAutoGeneratedRecipes();
|
||||
}
|
||||
|
||||
public static RecipeId getGeneratedFavorite(ItemStack stack) {
|
||||
if (NEIClientConfig.favoritesEnabled() && stack != null) {
|
||||
return autoFavorites.getRecipeId(stack);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public static ItemStack getGeneratedFavorite(RecipeId recipeId) {
|
||||
if (NEIClientConfig.favoritesEnabled() && recipeId != null) {
|
||||
return autoFavorites.getItemStack(recipeId);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public static RecipeId getManualFavorite(ItemStack stack) {
|
||||
if (NEIClientConfig.favoritesEnabled() && stack != null) {
|
||||
return manualFavorites.getRecipeId(stack);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public static ItemStack getManualFavorite(RecipeId recipeId) {
|
||||
if (NEIClientConfig.favoritesEnabled() && recipeId != null) {
|
||||
return manualFavorites.getItemStack(recipeId);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public static RecipeId getFavorite(ItemStack stack) {
|
||||
|
||||
if (NEIClientConfig.favoritesEnabled() && stack != null) {
|
||||
RecipeId recipeId = items.get(StackInfo.itemStackToNBT(stack, false));
|
||||
|
||||
if (recipeId == null) {
|
||||
recipeId = fluids.get(getFluidKey(stack));
|
||||
}
|
||||
|
||||
if (recipeId != null) {
|
||||
return recipeId;
|
||||
}
|
||||
|
||||
if (NEIServerUtils.isItemTool(stack)
|
||||
&& (stack.stackTagCompound == null || !stack.stackTagCompound.hasKey("GT.ToolStats"))) {
|
||||
for (NBTTagCompound nbt : tools) {
|
||||
if (NEIServerUtils.areStacksSameTypeCraftingWithNBT(stack, StackInfo.loadFromNBT(nbt))) {
|
||||
return items.get(nbt);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
final RecipeId recipeId = manualFavorites.getRecipeId(stack);
|
||||
return recipeId != null ? recipeId : autoFavorites.getRecipeId(stack);
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public static ItemStack getFavorite(RecipeId recipeId) {
|
||||
if (NEIClientConfig.favoritesEnabled()) {
|
||||
final Optional<Map.Entry<NBTTagCompound, RecipeId>> result = items.entrySet().stream()
|
||||
.filter(entry -> entry.getValue().equals(recipeId)).findAny();
|
||||
|
||||
if (result.isPresent()) {
|
||||
return StackInfo.loadFromNBT(result.get().getKey());
|
||||
}
|
||||
if (NEIClientConfig.favoritesEnabled() && recipeId != null) {
|
||||
final ItemStack stack = manualFavorites.getItemStack(recipeId);
|
||||
return stack != null ? stack : autoFavorites.getItemStack(recipeId);
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public static int size() {
|
||||
return items.size() + fluids.size();
|
||||
return manualFavorites.size() + autoFavorites.size();
|
||||
}
|
||||
|
||||
public static void reload() {
|
||||
save();
|
||||
load();
|
||||
}
|
||||
|
||||
public static boolean containsManual(ItemStack stack) {
|
||||
return getManualFavorite(stack) != null;
|
||||
}
|
||||
|
||||
public static boolean contains(ItemStack stack) {
|
||||
@@ -192,36 +322,37 @@ public class FavoriteRecipes {
|
||||
}
|
||||
|
||||
public static void setFavorite(ItemStack stack, RecipeId recipeId) {
|
||||
final NBTTagCompound itemStackNBT = StackInfo.itemStackToNBT(stack, false);
|
||||
final String fluidKey = getFluidKey(stack);
|
||||
if (stack == null) return;
|
||||
|
||||
items.entrySet().removeIf(entry -> entry.getKey().equals(itemStackNBT) || entry.getValue().equals(recipeId));
|
||||
fluids.entrySet().removeIf(entry -> entry.getKey().equals(fluidKey) || entry.getValue().equals(recipeId));
|
||||
manualFavorites.removeItemStack(stack);
|
||||
|
||||
if (recipeId != null) {
|
||||
items.put(itemStackNBT, recipeId);
|
||||
|
||||
if (NEIServerUtils.isItemTool(stack)) {
|
||||
tools.add(itemStackNBT);
|
||||
}
|
||||
|
||||
if (fluidKey != null) {
|
||||
fluids.put(fluidKey, recipeId);
|
||||
}
|
||||
manualFavorites.removeRecipeId(recipeId);
|
||||
manualFavorites.add(stack, recipeId);
|
||||
}
|
||||
|
||||
SubsetWidget.updateHiddenItems();
|
||||
ItemList.updateFilter.restart();
|
||||
updateSubsetVisibility();
|
||||
}
|
||||
|
||||
private static String getFluidKey(ItemStack stack) {
|
||||
final FluidStack fluid = StackInfo.getFluid(stack);
|
||||
public static void loadAutoGeneratedRecipes() {
|
||||
if (ItemList.loadFinished
|
||||
&& NEIClientConfig.getBooleanSetting("inventory.favorites.generateSingleRecipeFavorites")) {
|
||||
singleRecipeFavoritesTask.restart();
|
||||
} else {
|
||||
singleRecipeFavoritesTask.stop();
|
||||
autoFavorites.clear();
|
||||
|
||||
if (fluid != null) {
|
||||
return FluidRegistry.getFluidName(fluid);
|
||||
updateSubsetVisibility();
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
protected static void updateSubsetVisibility() {
|
||||
SubsetWidget.updateHiddenItems();
|
||||
FavoriteRecipes.revision++;
|
||||
}
|
||||
|
||||
public static int getRevision() {
|
||||
return revision;
|
||||
}
|
||||
|
||||
public static void save() {
|
||||
@@ -232,7 +363,7 @@ public class FavoriteRecipes {
|
||||
|
||||
final List<String> strings = new ArrayList<>();
|
||||
|
||||
for (Map.Entry<NBTTagCompound, RecipeId> entry : items.entrySet()) {
|
||||
for (Map.Entry<NBTTagCompound, RecipeId> entry : manualFavorites.getAllFavorites()) {
|
||||
|
||||
try {
|
||||
final JsonObject line = new JsonObject();
|
||||
|
||||
@@ -278,7 +278,7 @@ public class FormattedTextField extends GuiTextField {
|
||||
}
|
||||
|
||||
Tessellator tessellator = Tessellator.instance;
|
||||
GL11.glColor4f(0.0F, 0.0F, 255.0F, 255.0F);
|
||||
GL11.glColor4f(0.0F, 0.0F, 1.0F, 1.0F);
|
||||
GL11.glDisable(GL11.GL_TEXTURE_2D);
|
||||
GL11.glEnable(GL11.GL_COLOR_LOGIC_OP);
|
||||
GL11.glLogicOp(GL11.GL_OR_REVERSE);
|
||||
@@ -296,15 +296,26 @@ public class FormattedTextField extends GuiTextField {
|
||||
int shift = 0;
|
||||
|
||||
for (int i = 0; i < position; i++) {
|
||||
while (this.formattedText.length() > i + shift && this.formattedText.charAt(i + shift) == '\u00a7') {
|
||||
while (this.formattedText.length() > i + shift + 1 && this.formattedText.charAt(i + shift) == '\u00a7'
|
||||
&& isFormattingCode(this.formattedText.charAt(i + shift + 1))) {
|
||||
shift += 2;
|
||||
}
|
||||
}
|
||||
|
||||
return position + shift;
|
||||
return Math.min(position + shift, this.formattedText.length());
|
||||
}
|
||||
|
||||
private static boolean isFormattingCode(char c) {
|
||||
return (c >= '0' && c <= '9') || (c >= 'a' && c <= 'f')
|
||||
|| (c >= 'k' && c <= 'o')
|
||||
|| c == 'r'
|
||||
|| (c >= 'A' && c <= 'F')
|
||||
|| (c >= 'K' && c <= 'O')
|
||||
|| c == 'R';
|
||||
}
|
||||
|
||||
private String getPreviousColor(int position) {
|
||||
position = Math.min(position, this.formattedText.length() - 1);
|
||||
while (position >= 0) {
|
||||
if (this.formattedText.charAt(position) == '\u00a7') {
|
||||
return this.formattedText.substring(position, position + 2);
|
||||
|
||||
@@ -24,8 +24,8 @@ public class GuiEnchantmentModifier extends GuiContainer {
|
||||
|
||||
@Override
|
||||
protected void drawGuiContainerForegroundLayer(int par1, int par2) {
|
||||
fontRendererObj.drawString(translate("enchant"), 12, 6, 0x404040);
|
||||
fontRendererObj.drawString(translate("enchant.level"), 19, 20, 0x404040);
|
||||
fontRendererObj.drawString(translate("enchant"), 12, 6, ColorUtils.textGray.getColor());
|
||||
fontRendererObj.drawString(translate("enchant.level"), 19, 20, ColorUtils.textGray.getColor());
|
||||
}
|
||||
|
||||
protected void drawGuiContainerBackgroundLayer(float f, int i, int j) {
|
||||
@@ -39,7 +39,11 @@ public class GuiEnchantmentModifier extends GuiContainer {
|
||||
container.drawScrollBar(this);
|
||||
|
||||
String levelstring = "" + container.level;
|
||||
fontRendererObj.drawString(levelstring, 33 - fontRendererObj.getStringWidth(levelstring) / 2, 34, 0xFF606060);
|
||||
fontRendererObj.drawString(
|
||||
levelstring,
|
||||
33 - fontRendererObj.getStringWidth(levelstring) / 2,
|
||||
34,
|
||||
ColorUtils.textLightGray.getColor());
|
||||
|
||||
GL11.glTranslatef(-guiLeft, -guiTop, 0);
|
||||
}
|
||||
|
||||
@@ -45,15 +45,14 @@ public class GuiNEIButton extends GuiButton {
|
||||
}
|
||||
|
||||
protected int getTextColour(boolean mouseOver) {
|
||||
int color = 0xe0e0e0;
|
||||
|
||||
if (!enabled) {
|
||||
color = 0xffa0a0a0;
|
||||
return ColorUtils.buttonLabelInactive.getColor();
|
||||
} else if (mouseOver) {
|
||||
color = 0xffffa0;
|
||||
return ColorUtils.buttonLabelHover.getColor();
|
||||
}
|
||||
|
||||
return color;
|
||||
return ColorUtils.buttonLabelNormal.getColor();
|
||||
}
|
||||
|
||||
protected void drawContent(Minecraft minecraft, int y, int x, boolean mouseOver) {
|
||||
|
||||
@@ -289,10 +289,10 @@ public class GuiPotionCreator extends GuiContainerWidget {
|
||||
CCRenderState.changeTexture("nei:textures/gui/potion.png");
|
||||
drawTexturedModalRect(0, 0, 0, 0, xSize, ySize);
|
||||
|
||||
FontUtils.drawCenteredString(translate("potion.favourite"), xSize / 2, 4, 0x404040);
|
||||
fontRendererObj.drawString(translate("potion.duration"), 12, 40, 0x404040);
|
||||
fontRendererObj.drawString(translate("potion.level"), 19, 73, 0x404040);
|
||||
FontUtils.drawCenteredString(translateAmplifier(amplifier), 33, 86, 0xFF606060);
|
||||
FontUtils.drawCenteredString(translate("potion.favourite"), xSize / 2, 4, ColorUtils.textGray.getColor());
|
||||
fontRendererObj.drawString(translate("potion.duration"), 12, 40, ColorUtils.textGray.getColor());
|
||||
fontRendererObj.drawString(translate("potion.level"), 19, 73, ColorUtils.textGray.getColor());
|
||||
FontUtils.drawCenteredString(translateAmplifier(amplifier), 33, 86, ColorUtils.textGray.getColor());
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -28,7 +28,7 @@ public class HUDRenderer implements IKeyStateTracker {
|
||||
|
||||
@Override
|
||||
public void tickKeyStates() {
|
||||
if (KeyManager.keyStates.get("world.highlight_tips").down) {
|
||||
if (KeyManager.isPressed("world.highlight_tips")) {
|
||||
ConfigTag tag = NEIClientConfig.getSetting("world.highlight_tips");
|
||||
tag.setBooleanValue(!tag.getBooleanValue());
|
||||
}
|
||||
|
||||
@@ -0,0 +1,161 @@
|
||||
package codechicken.nei;
|
||||
|
||||
import net.minecraft.client.gui.GuiRepair;
|
||||
import net.minecraft.client.gui.inventory.GuiBrewingStand;
|
||||
import net.minecraft.client.gui.inventory.GuiCrafting;
|
||||
import net.minecraft.client.gui.inventory.GuiFurnace;
|
||||
import net.minecraft.client.gui.inventory.GuiInventory;
|
||||
import net.minecraft.nbt.NBTTagCompound;
|
||||
|
||||
import codechicken.nei.api.API;
|
||||
import codechicken.nei.recipe.BrewingOverlayHandler;
|
||||
import codechicken.nei.recipe.BrewingRecipeHandler;
|
||||
import codechicken.nei.recipe.DefaultOverlayHandler;
|
||||
import codechicken.nei.recipe.FireworkRecipeHandler;
|
||||
import codechicken.nei.recipe.FuelRecipeHandler;
|
||||
import codechicken.nei.recipe.FurnaceRecipeHandler;
|
||||
import codechicken.nei.recipe.InformationHandler;
|
||||
import codechicken.nei.recipe.ProfilerRecipeHandler;
|
||||
import codechicken.nei.recipe.RepairOverlayHandler;
|
||||
import codechicken.nei.recipe.RepairRecipeHandler;
|
||||
import codechicken.nei.recipe.ShapedRecipeHandler;
|
||||
import codechicken.nei.recipe.ShapelessRecipeHandler;
|
||||
import cpw.mods.fml.common.event.FMLInterModComms;
|
||||
|
||||
public class IMCForNEI {
|
||||
|
||||
public static void IMCSender() {
|
||||
|
||||
API.registerRecipeHandler(new ShapedRecipeHandler());
|
||||
API.registerUsageHandler(new ShapedRecipeHandler());
|
||||
sendHandler("codechicken.nei.recipe.ShapedRecipeHandler", "minecraft:crafting_table");
|
||||
|
||||
API.registerRecipeHandler(new ShapelessRecipeHandler());
|
||||
API.registerUsageHandler(new ShapelessRecipeHandler());
|
||||
sendHandler("codechicken.nei.recipe.ShapelessRecipeHandler", "minecraft:crafting_table");
|
||||
|
||||
API.registerRecipeHandler(new FireworkRecipeHandler());
|
||||
API.registerUsageHandler(new FireworkRecipeHandler());
|
||||
sendHandler("codechicken.nei.recipe.FireworkRecipeHandler", "minecraft:fireworks");
|
||||
|
||||
API.registerRecipeHandler(new FurnaceRecipeHandler());
|
||||
API.registerUsageHandler(new FurnaceRecipeHandler());
|
||||
sendHandler("codechicken.nei.recipe.FurnaceRecipeHandler", "minecraft:furnace");
|
||||
|
||||
API.registerRecipeHandler(new BrewingRecipeHandler());
|
||||
API.registerUsageHandler(new BrewingRecipeHandler());
|
||||
sendHandler("codechicken.nei.recipe.BrewingRecipeHandler", "minecraft:brewing_stand");
|
||||
|
||||
API.registerRecipeHandler(new FuelRecipeHandler());
|
||||
API.registerUsageHandler(new FuelRecipeHandler());
|
||||
sendFuelRecipeHandler();
|
||||
|
||||
API.registerRecipeHandler(new InformationHandler());
|
||||
API.registerUsageHandler(new InformationHandler());
|
||||
sendInformationHandler();
|
||||
|
||||
API.registerRecipeHandler(new RepairRecipeHandler());
|
||||
API.registerUsageHandler(new RepairRecipeHandler());
|
||||
sendRepairHandler();
|
||||
sendCatalyst("repair", "minecraft:anvil");
|
||||
|
||||
API.registerGuiOverlay(GuiCrafting.class, "crafting");
|
||||
API.registerGuiOverlay(GuiInventory.class, "crafting2x2", 63, 20);
|
||||
API.registerGuiOverlay(GuiFurnace.class, "smelting");
|
||||
API.registerGuiOverlay(GuiFurnace.class, "fuel");
|
||||
API.registerGuiOverlay(GuiBrewingStand.class, "brewing");
|
||||
API.registerGuiOverlay(GuiRepair.class, "repair", 2, 37);
|
||||
|
||||
API.registerGuiOverlayHandler(GuiCrafting.class, new DefaultOverlayHandler(), "crafting");
|
||||
API.registerGuiOverlayHandler(GuiInventory.class, new DefaultOverlayHandler(63, 20), "crafting2x2");
|
||||
API.registerGuiOverlayHandler(GuiBrewingStand.class, new BrewingOverlayHandler(), "brewing");
|
||||
API.registerGuiOverlayHandler(GuiRepair.class, new RepairOverlayHandler(), "repair");
|
||||
|
||||
API.registerRecipeHandler(new ProfilerRecipeHandler(true));
|
||||
API.registerUsageHandler(new ProfilerRecipeHandler(false));
|
||||
sendProfilerRecipeHandler();
|
||||
}
|
||||
|
||||
private static void sendHandler(String aName, String aBlock) {
|
||||
NBTTagCompound aNBT = new NBTTagCompound();
|
||||
aNBT.setString("handler", aName);
|
||||
aNBT.setString("modName", "Minecraft");
|
||||
aNBT.setString("modId", "minecraft");
|
||||
aNBT.setString("itemName", aBlock);
|
||||
aNBT.setInteger("handlerWidth", 166);
|
||||
aNBT.setInteger("handlerHeight", 65);
|
||||
aNBT.setBoolean("multipleWidgetsAllowed", true);
|
||||
aNBT.setInteger("yShift", 0);
|
||||
FMLInterModComms.sendMessage("NotEnoughItems", "registerHandlerInfo", aNBT);
|
||||
}
|
||||
|
||||
private static void sendRepairHandler() {
|
||||
NBTTagCompound aNBT = new NBTTagCompound();
|
||||
aNBT.setString("handler", "codechicken.nei.recipe.RepairRecipeHandler");
|
||||
aNBT.setString("modName", "Minecraft");
|
||||
aNBT.setString("modId", "minecraft");
|
||||
aNBT.setString("itemName", "minecraft:anvil");
|
||||
aNBT.setInteger("handlerHeight", 39);
|
||||
aNBT.setInteger("handlerWidth", 166);
|
||||
aNBT.setBoolean("multipleWidgetsAllowed", true);
|
||||
aNBT.setBoolean("showFavoritesButton", false);
|
||||
aNBT.setInteger("yShift", 0);
|
||||
FMLInterModComms.sendMessage("NotEnoughItems", "registerHandlerInfo", aNBT);
|
||||
}
|
||||
|
||||
private static void sendFuelRecipeHandler() {
|
||||
NBTTagCompound aNBT = new NBTTagCompound();
|
||||
aNBT.setString("handler", "codechicken.nei.recipe.FuelRecipeHandler");
|
||||
aNBT.setString("modName", "Minecraft");
|
||||
aNBT.setString("modId", "minecraft");
|
||||
aNBT.setString("imageResource", "nei:textures/nei_tabbed_sprites.png");
|
||||
aNBT.setInteger("imageX", 80);
|
||||
aNBT.setInteger("imageY", 0);
|
||||
aNBT.setInteger("imageWidth", 14);
|
||||
aNBT.setInteger("imageHeight", 14);
|
||||
aNBT.setInteger("handlerHeight", 65);
|
||||
aNBT.setInteger("handlerWidth", 166);
|
||||
aNBT.setBoolean("multipleWidgetsAllowed", true);
|
||||
aNBT.setInteger("yShift", 0);
|
||||
FMLInterModComms.sendMessage("NotEnoughItems", "registerHandlerInfo", aNBT);
|
||||
}
|
||||
|
||||
private static void sendInformationHandler() {
|
||||
NBTTagCompound aNBT = new NBTTagCompound();
|
||||
aNBT.setString("handler", "codechicken.nei.recipe.InformationHandler");
|
||||
aNBT.setString("modName", "Not Enough Items");
|
||||
aNBT.setString("modId", "nei");
|
||||
aNBT.setString("imageResource", "nei:textures/nei_tabbed_sprites.png");
|
||||
aNBT.setInteger("imageX", 96);
|
||||
aNBT.setInteger("imageY", 0);
|
||||
aNBT.setInteger("imageWidth", 16);
|
||||
aNBT.setInteger("imageHeight", 16);
|
||||
aNBT.setInteger("handlerHeight", 65);
|
||||
aNBT.setInteger("handlerWidth", 166);
|
||||
aNBT.setBoolean("multipleWidgetsAllowed", true);
|
||||
aNBT.setInteger("yShift", 0);
|
||||
FMLInterModComms.sendMessage("NotEnoughItems", "registerHandlerInfo", aNBT);
|
||||
}
|
||||
|
||||
private static void sendProfilerRecipeHandler() {
|
||||
NBTTagCompound aNBT = new NBTTagCompound();
|
||||
aNBT.setString("handler", "codechicken.nei.recipe.ProfilerRecipeHandler");
|
||||
aNBT.setString("modName", "Not Enough Items");
|
||||
aNBT.setString("modId", "nei");
|
||||
aNBT.setString("itemName", "minecraft:clock");
|
||||
aNBT.setInteger("handlerHeight", 16);
|
||||
aNBT.setInteger("handlerWidth", 166);
|
||||
aNBT.setBoolean("multipleWidgetsAllowed", true);
|
||||
aNBT.setInteger("yShift", 0);
|
||||
FMLInterModComms.sendMessage("NotEnoughItems", "registerHandlerInfo", aNBT);
|
||||
}
|
||||
|
||||
private static void sendCatalyst(String aName, String aStack) {
|
||||
NBTTagCompound aNBT = new NBTTagCompound();
|
||||
aNBT.setString("handlerID", aName);
|
||||
aNBT.setString("itemName", aStack);
|
||||
aNBT.setInteger("priority", 0);
|
||||
FMLInterModComms.sendMessage("NotEnoughItems", "registerCatalystInfo", aNBT);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -117,7 +117,8 @@ public class ItemCraftablesPanel
|
||||
.entrySet().stream()
|
||||
.sorted(
|
||||
Map.Entry.comparingByKey(
|
||||
Comparator.comparing(FavoriteRecipes::contains).reversed()
|
||||
Comparator.comparing(FavoriteRecipes::containsManual)
|
||||
.thenComparing(FavoriteRecipes::contains).reversed()
|
||||
.thenComparing(ItemSorter.instance)))
|
||||
.limit(maxSlotIndex).collect(Collectors.toList());
|
||||
int slotIndex = 0;
|
||||
|
||||
@@ -2,38 +2,23 @@ package codechicken.nei;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Comparator;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.ExecutionException;
|
||||
import java.util.concurrent.ForkJoinPool;
|
||||
import java.util.concurrent.ForkJoinWorkerThread;
|
||||
import java.util.regex.Pattern;
|
||||
import java.util.stream.Collectors;
|
||||
import java.util.stream.StreamSupport;
|
||||
|
||||
import net.minecraft.client.Minecraft;
|
||||
import net.minecraft.init.Blocks;
|
||||
import net.minecraft.item.Item;
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.util.EnumChatFormatting;
|
||||
import net.minecraft.util.IIcon;
|
||||
import net.minecraftforge.fluids.IFluidContainerItem;
|
||||
|
||||
import com.google.common.collect.ArrayListMultimap;
|
||||
import com.google.common.collect.ListMultimap;
|
||||
|
||||
import codechicken.nei.ThreadOperationTimer.TimeoutException;
|
||||
import codechicken.nei.api.ItemFilter;
|
||||
import codechicken.nei.api.ItemFilter.ItemFilterProvider;
|
||||
import codechicken.nei.api.ItemInfo;
|
||||
import codechicken.nei.recipe.InformationHandler;
|
||||
import codechicken.nei.search.TooltipFilter;
|
||||
import codechicken.nei.util.ItemUntranslator;
|
||||
import cpw.mods.fml.common.FMLLog;
|
||||
|
||||
public class ItemList {
|
||||
|
||||
@@ -51,9 +36,6 @@ public class ItemList {
|
||||
public static final List<ItemFilterProvider> itemFilterers = new LinkedList<>();
|
||||
public static final List<ItemsLoadedCallback> loadCallbacks = new LinkedList<>();
|
||||
|
||||
private static final HashSet<Item> erroredItems = new HashSet<>();
|
||||
private static final HashSet<String> stackTraces = new HashSet<>();
|
||||
private static Map<ItemStack, Integer> ordering = new HashMap<>();
|
||||
/**
|
||||
* Unlike {@link LayoutManager#itemsLoaded}, this indicates whether item loading is actually finished or not.
|
||||
*/
|
||||
@@ -115,7 +97,15 @@ public class ItemList {
|
||||
displayName = EnumChatFormatting
|
||||
.getTextWithoutFormattingCodes(item.getItem().getItemStackDisplayName(item));
|
||||
|
||||
return displayName != null && !displayName.isEmpty() && this.pattern.matcher(displayName).find();
|
||||
if (displayName != null && !displayName.isEmpty() && this.pattern.matcher(displayName).find()) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
for (String alias : ItemInfo.getAliases(item)) {
|
||||
if (this.pattern.matcher(alias).find()) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
@@ -216,228 +206,6 @@ public class ItemList {
|
||||
return filters;
|
||||
}
|
||||
|
||||
public static final RestartableTask loadItems = new RestartableTask("NEI Item Loading") {
|
||||
|
||||
private void damageSearch(Item item, List<ItemStack> permutations) {
|
||||
HashSet<String> damageIconSet = new HashSet<>();
|
||||
for (int damage = 0; damage < 16; damage++) try {
|
||||
ItemStack itemstack = new ItemStack(item, 1, damage);
|
||||
IIcon icon = item.getIconIndex(itemstack);
|
||||
String name = getTooltip(itemstack);
|
||||
String s = name + "@" + (icon == null ? 0 : icon.hashCode());
|
||||
if (damageIconSet.add(s)) {
|
||||
permutations.add(itemstack);
|
||||
}
|
||||
} catch (TimeoutException t) {
|
||||
throw t;
|
||||
} catch (Throwable t) {
|
||||
NEIServerUtils.logOnce(
|
||||
t,
|
||||
stackTraces,
|
||||
"Ommiting " + item + ":" + damage + " " + item.getClass().getSimpleName(),
|
||||
item.toString());
|
||||
}
|
||||
}
|
||||
|
||||
private String getTooltip(ItemStack stack) {
|
||||
try {
|
||||
return String.join("\n", stack.getTooltip(Minecraft.getMinecraft().thePlayer, false));
|
||||
} catch (Throwable ignored) {}
|
||||
|
||||
return "";
|
||||
}
|
||||
|
||||
private void updateOrdering(List<ItemStack> items) {
|
||||
final Map<ItemStack, Integer> newOrdering = new HashMap<>();
|
||||
ItemSorter.sort(items);
|
||||
|
||||
if (!CollapsibleItems.isEmpty()) {
|
||||
final HashMap<Integer, Integer> groups = new HashMap<>();
|
||||
int orderIndex = 0;
|
||||
|
||||
for (ItemStack stack : items) {
|
||||
final int groupIndex = CollapsibleItems.getGroupIndex(stack);
|
||||
|
||||
if (groupIndex == -1) {
|
||||
newOrdering.put(stack, orderIndex++);
|
||||
} else {
|
||||
|
||||
if (!groups.containsKey(groupIndex)) {
|
||||
groups.put(groupIndex, orderIndex++);
|
||||
}
|
||||
|
||||
newOrdering.put(stack, groups.get(groupIndex));
|
||||
}
|
||||
}
|
||||
} else {
|
||||
int orderIndex = 0;
|
||||
|
||||
for (ItemStack stack : items) {
|
||||
newOrdering.put(stack, orderIndex++);
|
||||
}
|
||||
}
|
||||
|
||||
ItemList.ordering = newOrdering;
|
||||
}
|
||||
|
||||
private List<ItemStack> getPermutations(Item item) {
|
||||
final List<ItemStack> permutations = new LinkedList<>(ItemInfo.itemOverrides.get(item));
|
||||
|
||||
if (permutations.isEmpty()) {
|
||||
item.getSubItems(item, null, permutations);
|
||||
}
|
||||
|
||||
if (permutations.isEmpty()) {
|
||||
damageSearch(item, permutations);
|
||||
}
|
||||
|
||||
permutations.addAll(ItemInfo.itemVariants.get(item));
|
||||
|
||||
return permutations.stream()
|
||||
.filter(
|
||||
stack -> stack.getItem() != null && stack.getItem().delegate.name() != null
|
||||
&& !ItemInfo.isHidden(stack))
|
||||
.collect(Collectors.toList());
|
||||
}
|
||||
|
||||
private void runChecked(ItemStack stack, Runnable action, String reason) {
|
||||
int hashOld = 0;
|
||||
if (stack.hasTagCompound()) {
|
||||
hashOld = stack.stackTagCompound.hashCode();
|
||||
}
|
||||
|
||||
action.run();
|
||||
|
||||
if (stack.hasTagCompound() && hashOld != stack.stackTagCompound.hashCode()) {
|
||||
FMLLog.warning(
|
||||
"NEI: Forced tag update with reason (" + reason
|
||||
+ ") for "
|
||||
+ stack
|
||||
+ "("
|
||||
+ stack.getItem()
|
||||
+ ")");
|
||||
}
|
||||
}
|
||||
|
||||
private void forceTagCompoundInitialization(ItemStack stack) {
|
||||
Item item = stack.getItem();
|
||||
if (item == null) {
|
||||
return;
|
||||
}
|
||||
if (item instanceof IFluidContainerItem) {
|
||||
IFluidContainerItem fluidItem = (IFluidContainerItem) item;
|
||||
runChecked(stack, () -> fluidItem.getFluid(stack), "getFluid");
|
||||
}
|
||||
runChecked(stack, () -> item.isDamaged(stack), "isDamaged");
|
||||
runChecked(stack, () -> item.getDamage(stack), "getDamage");
|
||||
runChecked(stack, () -> item.showDurabilityBar(stack), "showDurabilityBar");
|
||||
runChecked(stack, () -> item.getAttributeModifiers(stack), "getAttributeModifiers");
|
||||
runChecked(stack, () -> item.getDurabilityForDisplay(stack), "getDurabilityForDisplay");
|
||||
runChecked(stack, () -> item.getItemStackLimit(stack), "getItemStackLimit");
|
||||
runChecked(stack, () -> item.getToolClasses(stack), "getToolClasses");
|
||||
runChecked(stack, () -> item.getUnlocalizedNameInefficiently(stack), "getUnlocalizedNameInefficiently");
|
||||
runChecked(stack, () -> item.hasEffect(stack), "hasEffect");
|
||||
runChecked(stack, () -> item.getDigSpeed(stack, Blocks.stone, 0), "getDigSpeed");
|
||||
|
||||
/*
|
||||
* unused... for now runChecked(stack, () -> GameRegistry.getFuelValue(stack), "getFuelValue");
|
||||
* runChecked(stack, () -> item.getUnlocalizedName(stack), "getUnlocalizedName"); runChecked(stack, () ->
|
||||
* item.doesContainerItemLeaveCraftingGrid(stack), "doesContainerItemLeaveCraftingGrid"); runChecked(stack,
|
||||
* () -> item.getItemUseAction(stack), "getItemUseAction"); runChecked(stack, () ->
|
||||
* item.getMaxItemUseDuration(stack), "getMaxItemUseDuration"); runChecked(stack, () ->
|
||||
* item.getPotionEffect(stack), "getPotionEffect"); runChecked(stack, () -> item.isPotionIngredient(stack),
|
||||
* "isPotionIngredient"); runChecked(stack, () -> item.getRarity(stack), "getRarity"); runChecked(stack, ()
|
||||
* -> item.hasCustomEntity(stack), "hasCustomEntity"); runChecked(stack, () ->
|
||||
* item.getSmeltingExperience(stack), "getSmeltingExperience"); runChecked(stack, () ->
|
||||
* item.getMaxDamage(stack), "getMaxDamage"); runChecked(stack, () -> item.getDamage(stack), "getDamage");
|
||||
* runChecked(stack, stack::isItemDamaged, "isItemDamaged"); runChecked(stack, () -> item.hasEffect(stack,
|
||||
* 0), "hasEffect"); runChecked(stack, () -> item.getItemEnchantability(stack), "getItemEnchantability");
|
||||
* runChecked(stack, () -> item.isBeaconPayment(stack), "isBeaconPayment"); runChecked(stack, () ->
|
||||
* item.getDamage(stack), "getDamage"); runChecked(stack, () -> item.getDamage(stack), "getDamage");
|
||||
* runChecked(stack, () -> item.getDamage(stack), "getDamage");
|
||||
*/
|
||||
}
|
||||
|
||||
// Generate itemlist, permutations, orders, collapsibleitems, and informationhandler stacks
|
||||
@Override
|
||||
@SuppressWarnings("unchecked")
|
||||
public void execute() {
|
||||
if (!NEIClientConfig.isEnabled() || NEIClientUtils.mc().thePlayer == null) return;
|
||||
|
||||
ThreadOperationTimer timer = getTimer(NEIClientConfig.getItemLoadingTimeout());
|
||||
LayoutManager.itemsLoaded = true;
|
||||
loadFinished = false;
|
||||
|
||||
SearchField.searchParser.clearCache();
|
||||
ItemSorter.instance.ordering.clear();
|
||||
CollapsibleItems.clearCache();
|
||||
TooltipFilter.clearCache();
|
||||
InformationHandler.clearCache();
|
||||
|
||||
List<ItemStack> items = new ArrayList<>();
|
||||
ListMultimap<Item, ItemStack> itemMap = ArrayListMultimap.create();
|
||||
ItemStackSet unique = new ItemStackSet();
|
||||
|
||||
StreamSupport.stream(((Iterable<Item>) Item.itemRegistry).spliterator(), true).forEach(item -> {
|
||||
if (item == null || item.delegate.name() == null || erroredItems.contains(item)) return;
|
||||
|
||||
try {
|
||||
timer.reset(item);
|
||||
List<ItemStack> permutations = getPermutations(item);
|
||||
timer.reset();
|
||||
|
||||
for (ItemStack stack : permutations) {
|
||||
if (!unique.contains(stack)) {
|
||||
|
||||
synchronized (unique) {
|
||||
unique.add(stack);
|
||||
}
|
||||
|
||||
synchronized (items) {
|
||||
items.add(stack);
|
||||
}
|
||||
|
||||
forceTagCompoundInitialization(stack);
|
||||
|
||||
CollapsibleItems.putItem(stack);
|
||||
TooltipFilter.getSearchTooltip(stack);
|
||||
InformationHandler.populateStacks(stack);
|
||||
}
|
||||
}
|
||||
|
||||
synchronized (itemMap) {
|
||||
itemMap.putAll(item, permutations);
|
||||
}
|
||||
} catch (Throwable t) {
|
||||
NEIServerConfig.logger.error("Removing item: {} from list.", item, t);
|
||||
erroredItems.add(item);
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
int index = 0;
|
||||
for (Item item : (Iterable<Item>) Item.itemRegistry) {
|
||||
for (ItemStack stack : itemMap.get(item)) {
|
||||
ItemSorter.instance.ordering.put(stack, index++);
|
||||
}
|
||||
}
|
||||
|
||||
if (interrupted()) return;
|
||||
ItemList.items = items;
|
||||
ItemList.itemMap = itemMap;
|
||||
for (ItemsLoadedCallback callback : loadCallbacks) callback.itemsLoaded();
|
||||
|
||||
if (interrupted()) return;
|
||||
updateOrdering(ItemList.items);
|
||||
|
||||
loadFinished = true;
|
||||
|
||||
SubsetWidget.updateHiddenItems();
|
||||
ItemPanels.bookmarkPanel.load();
|
||||
updateFilter.restart();
|
||||
}
|
||||
};
|
||||
|
||||
public static ForkJoinPool forkJoinPool;
|
||||
|
||||
static {
|
||||
@@ -457,35 +225,12 @@ public class ItemList {
|
||||
forkJoinPool = new ForkJoinPool(poolSize, factory, null, false);
|
||||
}
|
||||
|
||||
public static final RestartableTask updateFilter = new RestartableTask("NEI Item Filtering") {
|
||||
// The item list pipeline lives in ItemListLoader; these references are kept for backward compatibility.
|
||||
public static final RestartableTask loadItems = ItemListLoader.loadItems;
|
||||
|
||||
@Override
|
||||
public void execute() {
|
||||
public static final RestartableTask refreshItems = ItemListLoader.refreshItems;
|
||||
|
||||
if (!loadFinished) return;
|
||||
ItemFilter filter = getItemListFilter();
|
||||
ArrayList<ItemStack> filtered;
|
||||
|
||||
try {
|
||||
filtered = ItemList.forkJoinPool.submit(
|
||||
() -> items.parallelStream().filter(filter::matches)
|
||||
.collect(Collectors.toCollection(ArrayList::new)))
|
||||
.get();
|
||||
} catch (InterruptedException | ExecutionException e) {
|
||||
filtered = new ArrayList<>();
|
||||
e.printStackTrace();
|
||||
stop();
|
||||
}
|
||||
|
||||
if (interrupted()) return;
|
||||
|
||||
filtered.sort(Comparator.comparingInt(ItemList.ordering::get));
|
||||
|
||||
if (interrupted()) return;
|
||||
|
||||
ItemPanel.updateItemList(filtered);
|
||||
}
|
||||
};
|
||||
public static final RestartableTask updateFilter = ItemListLoader.updateFilter;
|
||||
|
||||
/**
|
||||
* @deprecated Use updateFilter.restart()
|
||||
|
||||
@@ -0,0 +1,376 @@
|
||||
package codechicken.nei;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Comparator;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.ExecutionException;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import net.minecraft.client.Minecraft;
|
||||
import net.minecraft.entity.player.EntityPlayer;
|
||||
import net.minecraft.init.Blocks;
|
||||
import net.minecraft.item.Item;
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.util.IIcon;
|
||||
import net.minecraftforge.fluids.IFluidContainerItem;
|
||||
|
||||
import com.google.common.base.Throwables;
|
||||
import com.google.common.collect.ArrayListMultimap;
|
||||
import com.google.common.collect.ListMultimap;
|
||||
|
||||
import codechicken.nei.ItemList.ItemsLoadedCallback;
|
||||
import codechicken.nei.ThreadOperationTimer.TimeoutException;
|
||||
import codechicken.nei.api.ItemFilter;
|
||||
import codechicken.nei.api.ItemInfo;
|
||||
import codechicken.nei.recipe.InformationHandler;
|
||||
import codechicken.nei.recipe.RecipeHandlerRef;
|
||||
import codechicken.nei.recipe.RepairRecipeHandler;
|
||||
import codechicken.nei.search.TooltipFilter;
|
||||
import cpw.mods.fml.common.FMLLog;
|
||||
|
||||
public class ItemListLoader {
|
||||
|
||||
private static final HashSet<Item> erroredItems = new HashSet<>();
|
||||
private static final HashSet<String> stackTraces = new HashSet<>();
|
||||
private static Map<ItemStack, Integer> ordering = new HashMap<>();
|
||||
|
||||
private ItemListLoader() {}
|
||||
|
||||
private static void damageSearch(Item item, List<ItemStack> permutations) {
|
||||
final Set<String> damageIconSet = new HashSet<>();
|
||||
final EntityPlayer player = Minecraft.getMinecraft().thePlayer;
|
||||
|
||||
for (int damage = 0; damage < 16; damage++) {
|
||||
try {
|
||||
final ItemStack itemstack = new ItemStack(item, 1, damage);
|
||||
final IIcon icon = item.getIconIndex(itemstack);
|
||||
final String key = itemstack.getDisplayName() + "@"
|
||||
+ (icon == null ? 0 : icon.hashCode())
|
||||
+ "@"
|
||||
+ getInformation(itemstack, player);
|
||||
|
||||
if (damageIconSet.add(key)) {
|
||||
permutations.add(itemstack);
|
||||
}
|
||||
} catch (TimeoutException t) {
|
||||
throw t;
|
||||
} catch (Throwable t) {
|
||||
NEIServerUtils.logOnce(
|
||||
t,
|
||||
stackTraces,
|
||||
"Ommiting " + item + ":" + damage + " " + item.getClass().getSimpleName(),
|
||||
item.toString());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static String getInformation(ItemStack stack, EntityPlayer player) {
|
||||
try {
|
||||
final List<String> tooltip = new ArrayList<>();
|
||||
stack.getItem().addInformation(stack, player, tooltip, false);
|
||||
return String.join("\n", tooltip);
|
||||
} catch (Throwable ignored) {}
|
||||
|
||||
return "";
|
||||
}
|
||||
|
||||
private static void updateOrdering(List<ItemStack> items) {
|
||||
final Map<ItemStack, Integer> newOrdering = new HashMap<>();
|
||||
|
||||
if (!CollapsibleItems.isEmpty()) {
|
||||
final HashMap<Integer, Integer> groups = new HashMap<>();
|
||||
int orderIndex = 0;
|
||||
|
||||
for (ItemStack stack : items) {
|
||||
final int groupIndex = CollapsibleItems.getGroupIndex(stack);
|
||||
|
||||
if (groupIndex == -1) {
|
||||
newOrdering.put(stack, orderIndex++);
|
||||
} else {
|
||||
|
||||
if (!groups.containsKey(groupIndex)) {
|
||||
groups.put(groupIndex, orderIndex++);
|
||||
}
|
||||
|
||||
newOrdering.put(stack, groups.get(groupIndex));
|
||||
}
|
||||
}
|
||||
} else {
|
||||
int orderIndex = 0;
|
||||
|
||||
for (ItemStack stack : items) {
|
||||
newOrdering.put(stack, orderIndex++);
|
||||
}
|
||||
}
|
||||
|
||||
ordering = newOrdering;
|
||||
}
|
||||
|
||||
private static List<ItemStack> getPermutations(Item item) {
|
||||
final List<ItemStack> permutations = new LinkedList<>(ItemInfo.itemOverrides.get(item));
|
||||
|
||||
if (permutations.isEmpty()) {
|
||||
item.getSubItems(item, null, permutations);
|
||||
}
|
||||
|
||||
if (permutations.isEmpty()) {
|
||||
damageSearch(item, permutations);
|
||||
}
|
||||
|
||||
permutations.addAll(ItemInfo.itemVariants.get(item));
|
||||
|
||||
return permutations.stream()
|
||||
.filter(
|
||||
stack -> stack.getItem() != null && stack.getItem().delegate.name() != null
|
||||
&& !ItemInfo.isHidden(stack))
|
||||
.collect(Collectors.toList());
|
||||
}
|
||||
|
||||
private static void runChecked(ItemStack stack, Runnable action, String reason) {
|
||||
int hashOld = 0;
|
||||
if (stack.hasTagCompound()) {
|
||||
hashOld = stack.stackTagCompound.hashCode();
|
||||
}
|
||||
|
||||
action.run();
|
||||
|
||||
if (stack.hasTagCompound() && hashOld != stack.stackTagCompound.hashCode()) {
|
||||
FMLLog.warning(
|
||||
"NEI: Forced tag update with reason (" + reason + ") for " + stack + "(" + stack.getItem() + ")");
|
||||
}
|
||||
}
|
||||
|
||||
private static void forceTagCompoundInitialization(ItemStack stack) {
|
||||
Item item = stack.getItem();
|
||||
if (item == null) {
|
||||
return;
|
||||
}
|
||||
if (item instanceof IFluidContainerItem) {
|
||||
IFluidContainerItem fluidItem = (IFluidContainerItem) item;
|
||||
runChecked(stack, () -> fluidItem.getFluid(stack), "getFluid");
|
||||
}
|
||||
runChecked(stack, () -> item.isDamaged(stack), "isDamaged");
|
||||
runChecked(stack, () -> item.getDamage(stack), "getDamage");
|
||||
runChecked(stack, () -> item.showDurabilityBar(stack), "showDurabilityBar");
|
||||
runChecked(stack, () -> item.getAttributeModifiers(stack), "getAttributeModifiers");
|
||||
runChecked(stack, () -> item.getDurabilityForDisplay(stack), "getDurabilityForDisplay");
|
||||
runChecked(stack, () -> item.getItemStackLimit(stack), "getItemStackLimit");
|
||||
runChecked(stack, () -> item.getToolClasses(stack), "getToolClasses");
|
||||
runChecked(stack, () -> item.getUnlocalizedNameInefficiently(stack), "getUnlocalizedNameInefficiently");
|
||||
runChecked(stack, () -> item.hasEffect(stack), "hasEffect");
|
||||
runChecked(stack, () -> item.getDigSpeed(stack, Blocks.stone, 0), "getDigSpeed");
|
||||
|
||||
/*
|
||||
* unused... for now runChecked(stack, () -> GameRegistry.getFuelValue(stack), "getFuelValue");
|
||||
* runChecked(stack, () -> item.getUnlocalizedName(stack), "getUnlocalizedName"); runChecked(stack, () ->
|
||||
* item.doesContainerItemLeaveCraftingGrid(stack), "doesContainerItemLeaveCraftingGrid"); runChecked(stack, ()
|
||||
* -> item.getItemUseAction(stack), "getItemUseAction"); runChecked(stack, () ->
|
||||
* item.getMaxItemUseDuration(stack), "getMaxItemUseDuration"); runChecked(stack, () ->
|
||||
* item.getPotionEffect(stack), "getPotionEffect"); runChecked(stack, () -> item.isPotionIngredient(stack),
|
||||
* "isPotionIngredient"); runChecked(stack, () -> item.getRarity(stack), "getRarity"); runChecked(stack, () ->
|
||||
* item.hasCustomEntity(stack), "hasCustomEntity"); runChecked(stack, () -> item.getSmeltingExperience(stack),
|
||||
* "getSmeltingExperience"); runChecked(stack, () -> item.getMaxDamage(stack), "getMaxDamage");
|
||||
* runChecked(stack, () -> item.getDamage(stack), "getDamage"); runChecked(stack, stack::isItemDamaged,
|
||||
* "isItemDamaged"); runChecked(stack, () -> item.hasEffect(stack, 0), "hasEffect"); runChecked(stack, () ->
|
||||
* item.getItemEnchantability(stack), "getItemEnchantability"); runChecked(stack, () ->
|
||||
* item.isBeaconPayment(stack), "isBeaconPayment"); runChecked(stack, () -> item.getDamage(stack), "getDamage");
|
||||
* runChecked(stack, () -> item.getDamage(stack), "getDamage"); runChecked(stack, () -> item.getDamage(stack),
|
||||
* "getDamage");
|
||||
*/
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
private static List<ItemStack> gatherItems(ThreadOperationTimer timer) {
|
||||
ItemSorter.instance.ordering.clear();
|
||||
|
||||
List<ItemStack> items = new ArrayList<>();
|
||||
ListMultimap<Item, ItemStack> itemMap = ArrayListMultimap.create();
|
||||
ItemStackSet unique = new ItemStackSet();
|
||||
|
||||
final List<Item> registryItems = new ArrayList<>();
|
||||
for (Item item : (Iterable<Item>) Item.itemRegistry) registryItems.add(item);
|
||||
|
||||
registryItems.parallelStream().forEach(item -> {
|
||||
if (item == null || item.delegate.name() == null || erroredItems.contains(item)) return;
|
||||
|
||||
try {
|
||||
timer.reset(item);
|
||||
List<ItemStack> permutations = getPermutations(item);
|
||||
timer.reset();
|
||||
|
||||
synchronized (itemMap) {
|
||||
itemMap.putAll(item, permutations);
|
||||
}
|
||||
} catch (Throwable t) {
|
||||
NEIServerConfig.logger.error(
|
||||
"Removing item: {} from list.\n{}: {}",
|
||||
item,
|
||||
t.getMessage(),
|
||||
Throwables.getStackTraceAsString(t));
|
||||
erroredItems.add(item);
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
int index = 0;
|
||||
for (Item item : (Iterable<Item>) Item.itemRegistry) {
|
||||
for (ItemStack stack : itemMap.get(item)) {
|
||||
ItemSorter.instance.ordering.put(stack, index++);
|
||||
|
||||
if (!unique.contains(stack)) {
|
||||
unique.add(stack);
|
||||
items.add(stack);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ItemList.itemMap = itemMap;
|
||||
|
||||
return items;
|
||||
}
|
||||
|
||||
private static void buildItemCaches(List<ItemStack> items) {
|
||||
SearchField.searchParser.clearCache();
|
||||
TooltipFilter.clearCache();
|
||||
InformationHandler.clearCache();
|
||||
|
||||
items.parallelStream().forEach(stack -> {
|
||||
try {
|
||||
forceTagCompoundInitialization(stack);
|
||||
InformationHandler.populateStacks(stack);
|
||||
} catch (Throwable t) {
|
||||
NEIServerConfig.logger.error(
|
||||
"Failed to build caches for: {}\n{}: {}",
|
||||
stack,
|
||||
t.getMessage(),
|
||||
Throwables.getStackTraceAsString(t));
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private static void indexCollapsibleItems(List<ItemStack> items) {
|
||||
CollapsibleItems.clearCache();
|
||||
items.parallelStream().forEach(CollapsibleItems::putItem);
|
||||
}
|
||||
|
||||
public static final RestartableTask loadItems = new RestartableTask("NEI Item Loading") {
|
||||
|
||||
@Override
|
||||
public void execute() {
|
||||
if (!NEIClientConfig.isEnabled() || NEIClientUtils.mc().thePlayer == null) return;
|
||||
|
||||
final ThreadOperationTimer timer = getTimer(NEIClientConfig.getItemLoadingTimeout());
|
||||
LayoutManager.itemsLoaded = true;
|
||||
ItemList.loadFinished = false;
|
||||
warmTooltips.stop();
|
||||
|
||||
List<ItemStack> items = gatherItems(timer);
|
||||
|
||||
if (interrupted()) return;
|
||||
buildItemCaches(items);
|
||||
indexCollapsibleItems(items);
|
||||
|
||||
if (interrupted()) return;
|
||||
ItemSorter.sort(items);
|
||||
|
||||
if (interrupted()) return;
|
||||
ItemList.items = items;
|
||||
for (ItemsLoadedCallback callback : ItemList.loadCallbacks) callback.itemsLoaded();
|
||||
|
||||
if (interrupted()) return;
|
||||
updateOrdering(ItemList.items);
|
||||
|
||||
ItemList.loadFinished = true;
|
||||
|
||||
RepairRecipeHandler.findRepairRecipesOnceParallel();
|
||||
RecipeHandlerRef.clearCache();
|
||||
FavoriteRecipes.reload();
|
||||
SubsetWidget.updateHiddenItems();
|
||||
updateFilter.restart();
|
||||
warmTooltips.restart();
|
||||
loadBookmarks.restart();
|
||||
}
|
||||
};
|
||||
|
||||
public static final RestartableTask warmTooltips = new RestartableTask("NEI Tooltip Caching") {
|
||||
|
||||
@Override
|
||||
public void execute() {
|
||||
if (!ItemList.loadFinished) return;
|
||||
// Use the common pool, not ItemList.forkJoinPool, so it does not queue behind updateFilter.
|
||||
ItemList.items.parallelStream().forEach(stack -> {
|
||||
if (interrupted()) return;
|
||||
try {
|
||||
TooltipFilter.getSearchTooltip(stack);
|
||||
} catch (Throwable ignored) {}
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
public static final RestartableTask loadBookmarks = new RestartableTask("NEI Bookmark Loading") {
|
||||
|
||||
@Override
|
||||
public void execute() {
|
||||
ItemPanels.bookmarkPanel.load();
|
||||
}
|
||||
};
|
||||
|
||||
public static final RestartableTask refreshItems = new RestartableTask("NEI Item Reordering") {
|
||||
|
||||
@Override
|
||||
public void execute() {
|
||||
if (!ItemList.loadFinished) return;
|
||||
|
||||
final List<ItemStack> items = new ArrayList<>(ItemList.items);
|
||||
|
||||
indexCollapsibleItems(items);
|
||||
|
||||
if (interrupted()) return;
|
||||
ItemSorter.sort(items);
|
||||
|
||||
if (interrupted()) return;
|
||||
ItemList.items = items;
|
||||
updateOrdering(ItemList.items);
|
||||
|
||||
FavoriteRecipes.reload();
|
||||
SubsetWidget.updateHiddenItems();
|
||||
updateFilter.restart();
|
||||
loadBookmarks.restart();
|
||||
}
|
||||
};
|
||||
|
||||
public static final RestartableTask updateFilter = new RestartableTask("NEI Item Filtering") {
|
||||
|
||||
@Override
|
||||
public void execute() {
|
||||
|
||||
if (!ItemList.loadFinished) return;
|
||||
ItemFilter filter = ItemList.getItemListFilter();
|
||||
ArrayList<ItemStack> filtered;
|
||||
|
||||
try {
|
||||
filtered = ItemList.forkJoinPool.submit(
|
||||
() -> ItemList.items.parallelStream().filter(filter::matches)
|
||||
.collect(Collectors.toCollection(ArrayList::new)))
|
||||
.get();
|
||||
} catch (InterruptedException | ExecutionException e) {
|
||||
filtered = new ArrayList<>();
|
||||
e.printStackTrace();
|
||||
stop();
|
||||
}
|
||||
|
||||
if (interrupted()) return;
|
||||
|
||||
filtered.sort(Comparator.comparingInt(ordering::get));
|
||||
|
||||
if (interrupted()) return;
|
||||
|
||||
ItemPanel.updateItemList(filtered);
|
||||
}
|
||||
};
|
||||
}
|
||||
@@ -23,6 +23,7 @@ import net.minecraft.util.EnumChatFormatting;
|
||||
import net.minecraft.util.IIcon;
|
||||
import net.minecraft.world.World;
|
||||
import net.minecraftforge.client.MinecraftForgeClient;
|
||||
import net.minecraftforge.common.util.ForgeDirection;
|
||||
|
||||
import cpw.mods.fml.relauncher.Side;
|
||||
import cpw.mods.fml.relauncher.SideOnly;
|
||||
@@ -65,26 +66,40 @@ public class ItemMobSpawner extends ItemBlock {
|
||||
@Override
|
||||
public boolean onItemUse(ItemStack itemstack, EntityPlayer entityplayer, World world, int x, int y, int z, int side,
|
||||
float hitX, float hitY, float hitZ) {
|
||||
int targetX = x;
|
||||
int targetY = y;
|
||||
int targetZ = z;
|
||||
|
||||
placedX = x;
|
||||
placedY = y;
|
||||
placedZ = z;
|
||||
if (!world.getBlock(x, y, z).isReplaceable(world, x, y, z)) {
|
||||
ForgeDirection direction = ForgeDirection.getOrientation(side);
|
||||
targetX += direction.offsetX;
|
||||
targetY += direction.offsetY;
|
||||
targetZ += direction.offsetZ;
|
||||
}
|
||||
|
||||
placedX = targetX;
|
||||
placedY = targetY;
|
||||
placedZ = targetZ;
|
||||
|
||||
String mobType = getMobTypeFromItemStack(itemstack);
|
||||
|
||||
boolean placed = super.onItemUse(itemstack, entityplayer, world, x, y, z, side, hitX, hitY, hitZ);
|
||||
|
||||
if (placed && !world.isRemote) {
|
||||
TileEntity tileEntity = world.getTileEntity(x, y, z);
|
||||
if (tileEntity instanceof TileEntityMobSpawner) {
|
||||
TileEntityMobSpawner spawner = (TileEntityMobSpawner) tileEntity;
|
||||
String mobType = getMobTypeFromItemStack(itemstack);
|
||||
if (mobType != null) {
|
||||
spawner.func_145881_a().setEntityName(mobType);
|
||||
world.markBlockForUpdate(x, y, z);
|
||||
NEICPH.sendMobSpawnerID(x, y, z, mobType);
|
||||
if (placed) {
|
||||
TileEntity tileEntity = world.getTileEntity(targetX, targetY, targetZ);
|
||||
|
||||
if (tileEntity instanceof TileEntityMobSpawner spawner && mobType != null) {
|
||||
spawner.func_145881_a().setEntityName(mobType);
|
||||
|
||||
if (!world.isRemote) {
|
||||
world.markBlockForUpdate(targetX, targetY, targetZ);
|
||||
NEICPH.sendMobSpawnerID(targetX, targetY, targetZ, mobType);
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
return placed;
|
||||
}
|
||||
|
||||
|
||||
@@ -122,8 +122,7 @@ public class ItemPanel extends PanelWidget<ItemsPanelGrid> {
|
||||
}
|
||||
|
||||
@Override
|
||||
public Rectangle4i calculateBounds() {
|
||||
final GuiContainer gui = NEIClientUtils.getGuiContainer();
|
||||
public Rectangle4i calculateBounds(GuiContainer gui) {
|
||||
final int maxWidth = (gui.width - 176) / 2 - PADDING * 2;
|
||||
final int maxHeight = gui.height - PADDING * 2;
|
||||
final int freeSpace = (gui.width - gui.xSize) / 2 - PADDING * 2;
|
||||
|
||||
@@ -42,7 +42,7 @@ public class ItemZoom extends Widget implements IContainerInputHandler {
|
||||
|
||||
if (this.stack != null && this.availableAreaWidth >= SLOT_SIZE * 2
|
||||
&& (NEIClientConfig.getBooleanSetting("inventory.itemzoom.enabled")
|
||||
|| NEIClientConfig.isKeyHashDown("gui.itemzoom_hold"))
|
||||
|| KeyManager.isKeyDown("itemzoom.hold"))
|
||||
&& GuiContainerManager.shouldShowTooltip(NEIClientUtils.getGuiContainer())) {
|
||||
final float inverseScaleFactor = 1.0f / this.scale;
|
||||
final float screenScale = getScreenScale();
|
||||
@@ -74,7 +74,7 @@ public class ItemZoom extends Widget implements IContainerInputHandler {
|
||||
|
||||
if (NEIClientConfig.getBooleanSetting("inventory.itemzoom.enabled")
|
||||
&& NEIClientConfig.getBooleanSetting("inventory.itemzoom.helpText")) {
|
||||
String keyName = NEIClientConfig.getKeyName("gui.itemzoom_toggle");
|
||||
String keyName = KeyManager.getKeyName("itemzoom.toggle", NEIClientUtils.SHIFT_HASH);
|
||||
|
||||
if (keyName != null) {
|
||||
String helpText = NEIClientUtils.translate("itemzoom.toggle", keyName);
|
||||
@@ -198,24 +198,24 @@ public class ItemZoom extends Widget implements IContainerInputHandler {
|
||||
@Override
|
||||
public boolean lastKeyTyped(GuiContainer gui, char keyChar, int keyID) {
|
||||
|
||||
if (NEIClientConfig.isKeyHashDown("gui.itemzoom_toggle")) {
|
||||
if (KeyManager.isHashDown("itemzoom.toggle", NEIClientUtils.SHIFT_HASH)) {
|
||||
NEIClientConfig.getSetting("inventory.itemzoom.enabled")
|
||||
.setBooleanValue(!NEIClientConfig.getBooleanSetting("inventory.itemzoom.enabled"));
|
||||
return true;
|
||||
}
|
||||
|
||||
if (this.stack != null && NEIClientConfig.isKeyHashDown("gui.itemzoom_hold")) {
|
||||
if (this.stack != null && KeyManager.isKeyDown("itemzoom.hold")) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (this.stack != null && NEIClientConfig.isKeyHashDown("gui.itemzoom_zoom_in")) {
|
||||
if (this.stack != null && KeyManager.isKeyDown("itemzoom.zoom_in")) {
|
||||
increaseZoom(gui);
|
||||
previousKeyboardRepeatEnabled = Keyboard.areRepeatEventsEnabled();
|
||||
Keyboard.enableRepeatEvents(true);
|
||||
return true;
|
||||
}
|
||||
|
||||
if (this.stack != null && NEIClientConfig.isKeyHashDown("gui.itemzoom_zoom_out")) {
|
||||
if (this.stack != null && KeyManager.isKeyDown("itemzoom.zoom_out")) {
|
||||
decreaseZoom(gui);
|
||||
previousKeyboardRepeatEnabled = Keyboard.areRepeatEventsEnabled();
|
||||
Keyboard.enableRepeatEvents(true);
|
||||
|
||||
@@ -15,6 +15,7 @@ import net.minecraft.client.shader.Framebuffer;
|
||||
import net.minecraft.item.ItemStack;
|
||||
|
||||
import org.lwjgl.opengl.GL11;
|
||||
import org.lwjgl.opengl.GL30;
|
||||
|
||||
import codechicken.lib.vec.Rectangle4i;
|
||||
import codechicken.nei.api.GuiInfo;
|
||||
@@ -27,7 +28,7 @@ public abstract class ItemsGrid<T extends ItemsGrid.ItemsGridSlot, M extends Ite
|
||||
protected static class ScreenCapture {
|
||||
|
||||
private long nextCacheRefresh = 0;
|
||||
private Framebuffer framebuffer;
|
||||
private final Framebuffer framebuffer;
|
||||
|
||||
public ScreenCapture() {
|
||||
this.framebuffer = new Framebuffer(1, 1, true);
|
||||
@@ -51,7 +52,7 @@ public abstract class ItemsGrid<T extends ItemsGrid.ItemsGridSlot, M extends Ite
|
||||
}
|
||||
|
||||
public void captureScreen(Runnable callback, int mode) {
|
||||
GL11.glPushAttrib(GL11.GL_ENABLE_BIT | GL11.GL_COLOR_BUFFER_BIT | GL11.GL_LIGHTING_BIT);
|
||||
GL11.glPushAttrib(GL11.GL_ENABLE_BIT);
|
||||
|
||||
resetFramebuffer();
|
||||
this.framebuffer.bindFramebuffer(false);
|
||||
@@ -84,6 +85,21 @@ public abstract class ItemsGrid<T extends ItemsGrid.ItemsGridSlot, M extends Ite
|
||||
} else {
|
||||
this.framebuffer.framebufferClear();
|
||||
}
|
||||
|
||||
// Copy stencil values (required by mui2)
|
||||
OpenGlHelper.func_153171_g(GL30.GL_READ_FRAMEBUFFER, minecraft.getFramebuffer().framebufferObject);
|
||||
OpenGlHelper.func_153171_g(GL30.GL_DRAW_FRAMEBUFFER, this.framebuffer.framebufferObject);
|
||||
GL30.glBlitFramebuffer(
|
||||
0,
|
||||
0,
|
||||
minecraft.displayWidth,
|
||||
minecraft.displayHeight,
|
||||
0,
|
||||
0,
|
||||
minecraft.displayWidth,
|
||||
minecraft.displayHeight,
|
||||
GL11.GL_DEPTH_BUFFER_BIT | GL11.GL_STENCIL_BUFFER_BIT,
|
||||
GL11.GL_NEAREST);
|
||||
}
|
||||
|
||||
public void renderCapturedScreen() {
|
||||
|
||||
@@ -2,14 +2,21 @@ package codechicken.nei;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.LinkedList;
|
||||
import java.util.Map.Entry;
|
||||
import java.util.Map;
|
||||
import java.util.StringJoiner;
|
||||
|
||||
import net.minecraft.client.Minecraft;
|
||||
import net.minecraft.client.settings.KeyBinding;
|
||||
|
||||
import org.lwjgl.input.Keyboard;
|
||||
import org.lwjgl.input.Mouse;
|
||||
|
||||
import codechicken.nei.util.NEIKeyboardUtils;
|
||||
import codechicken.nei.util.NEIMouseUtils;
|
||||
import cpw.mods.fml.client.registry.ClientRegistry;
|
||||
|
||||
/**
|
||||
* Good old down/held/up keystate tracker
|
||||
* Registers NEI key bindings as vanilla {@link KeyBinding}s and exposes their state to the rest of NEI.
|
||||
*/
|
||||
public class KeyManager {
|
||||
|
||||
@@ -18,31 +25,132 @@ public class KeyManager {
|
||||
public void tickKeyStates();
|
||||
}
|
||||
|
||||
public static class KeyState {
|
||||
public static LinkedList<IKeyStateTracker> trackers = new LinkedList<>();
|
||||
private static final Map<String, KeyBinding> keyBindings = new HashMap<>();
|
||||
private static final Map<String, String> keyAliases = new HashMap<>();
|
||||
private static volatile boolean pendingOptionsReload = false;
|
||||
|
||||
public boolean down;
|
||||
public boolean held;
|
||||
public boolean up;
|
||||
static {
|
||||
// Aliases for legacy keybinds
|
||||
keyAliases.put("gui.recipe", "recipe.recipe");
|
||||
keyAliases.put("gui.usage", "recipe.usage");
|
||||
keyAliases.put("gui.hide_bookmarks", "bookmark.hide");
|
||||
}
|
||||
|
||||
public static HashMap<String, KeyState> keyStates = new HashMap<>();
|
||||
public static LinkedList<IKeyStateTracker> trackers = new LinkedList<>();
|
||||
public static KeyBinding registerKeyBinding(String ident, int defaultKey) {
|
||||
return keyBindings.computeIfAbsent(ident, id -> {
|
||||
final KeyBinding binding = new KeyBinding(
|
||||
"nei.options.keys." + id,
|
||||
NEIKeyboardUtils.unhash(defaultKey),
|
||||
categoryFor(id));
|
||||
ClientRegistry.registerKeyBinding(binding);
|
||||
return binding;
|
||||
});
|
||||
}
|
||||
|
||||
public static KeyBinding getKeyBinding(String ident) {
|
||||
return keyBindings.get(keyAliases.getOrDefault(ident, ident));
|
||||
}
|
||||
|
||||
public static boolean isRegistered(String description) {
|
||||
for (KeyBinding binding : keyBindings.values()) {
|
||||
if (binding.getKeyDescription().equals(description)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public static int getKeyCode(String ident) {
|
||||
final KeyBinding binding = getKeyBinding(ident);
|
||||
return binding == null ? Keyboard.KEY_NONE : binding.getKeyCode();
|
||||
}
|
||||
|
||||
public static boolean isKeyDown(String ident) {
|
||||
final KeyBinding binding = getKeyBinding(ident);
|
||||
|
||||
if (binding != null) {
|
||||
final int keyCode = binding.getKeyCode();
|
||||
|
||||
if (keyCode < 0) {
|
||||
return Mouse.isButtonDown(keyCode + 100);
|
||||
} else if (keyCode > Keyboard.KEY_NONE && keyCode < Keyboard.KEYBOARD_SIZE) {
|
||||
return Keyboard.isKeyDown(keyCode);
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public static boolean isHashDown(String ident) {
|
||||
return isHashDown(ident, 0);
|
||||
}
|
||||
|
||||
public static boolean isHashDown(String ident, int modifierMask) {
|
||||
|
||||
if (!isKeyDown(ident)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (NEIKeyboardUtils.isHashKey(getKeyCode(ident))) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return ((modifierMask & NEIKeyboardUtils.CTRL_HASH) != 0) == NEIClientUtils.controlKey()
|
||||
&& ((modifierMask & NEIKeyboardUtils.SHIFT_HASH) != 0) == NEIClientUtils.shiftKey()
|
||||
&& ((modifierMask & NEIKeyboardUtils.ALT_HASH) != 0) == NEIClientUtils.altKey();
|
||||
}
|
||||
|
||||
public static String getKeyName(String ident) {
|
||||
return getKeyName(ident, 0);
|
||||
}
|
||||
|
||||
public static String getKeyName(String ident, int meta) {
|
||||
final int keyCode = getKeyCode(ident);
|
||||
return keyCode == Keyboard.KEY_NONE ? null : NEIKeyboardUtils.getKeyName(keyCode + meta);
|
||||
}
|
||||
|
||||
public static String getKeyName(String ident, int meta, int mouseBind) {
|
||||
final int keyCode = getKeyCode(ident);
|
||||
return keyCode == Keyboard.KEY_NONE && mouseBind == NEIMouseUtils.MOUSE_BTN_NONE ? null
|
||||
: getKeyName(keyCode + meta, mouseBind);
|
||||
}
|
||||
|
||||
public static String getKeyName(int keyBind, int mouseBind) {
|
||||
StringJoiner keyText = new StringJoiner(" + ");
|
||||
String keyHash = keyBind == Keyboard.KEY_NONE ? "" : NEIKeyboardUtils.getKeyName(keyBind);
|
||||
String mouseHash = mouseBind == NEIMouseUtils.MOUSE_BTN_NONE ? "" : NEIMouseUtils.getKeyName(mouseBind);
|
||||
|
||||
if (!keyHash.isEmpty()) {
|
||||
keyText.add(keyHash);
|
||||
}
|
||||
|
||||
if (!mouseHash.isEmpty()) {
|
||||
keyText.add(mouseHash);
|
||||
}
|
||||
|
||||
return keyText.toString();
|
||||
}
|
||||
|
||||
public static boolean isPressed(String ident) {
|
||||
final KeyBinding binding = getKeyBinding(ident);
|
||||
return binding != null && binding.isPressed();
|
||||
}
|
||||
|
||||
private static String categoryFor(String ident) {
|
||||
final int dot = ident.indexOf('.');
|
||||
return dot < 0 ? "nei.options.keys" : "nei.options.keys." + ident.substring(0, dot);
|
||||
}
|
||||
|
||||
public static void requestOptionsReload() {
|
||||
pendingOptionsReload = true;
|
||||
}
|
||||
|
||||
public static void tickKeyStates() {
|
||||
for (Entry<String, KeyState> entry : keyStates.entrySet()) {
|
||||
final int keyCode = NEIKeyboardUtils.unhash(NEIClientConfig.getKeyBinding(entry.getKey()));
|
||||
final boolean down = keyCode > 0 && keyCode < Keyboard.KEYBOARD_SIZE && Keyboard.isKeyDown(keyCode);
|
||||
final KeyState state = entry.getValue();
|
||||
|
||||
if (down) {
|
||||
state.down = !state.held;
|
||||
state.up = false;
|
||||
} else {
|
||||
state.up = state.held;
|
||||
state.down = false;
|
||||
}
|
||||
|
||||
state.held = down;
|
||||
if (pendingOptionsReload) {
|
||||
pendingOptionsReload = false;
|
||||
Minecraft.getMinecraft().gameSettings.loadOptions();
|
||||
}
|
||||
|
||||
for (IKeyStateTracker tracker : trackers) tracker.tickKeyStates();
|
||||
|
||||
@@ -66,9 +66,9 @@ import codechicken.nei.guihook.IContainerInputHandler;
|
||||
import codechicken.nei.guihook.IContainerObjectHandler;
|
||||
import codechicken.nei.guihook.IContainerTooltipHandler;
|
||||
import codechicken.nei.recipe.AutoCraftingManager;
|
||||
import codechicken.nei.recipe.DebugHandlerWidget;
|
||||
import codechicken.nei.recipe.GuiRecipeTab;
|
||||
import codechicken.nei.recipe.RecipeCatalysts;
|
||||
import codechicken.nei.recipe.debug.DebugHandlerWidget;
|
||||
|
||||
public class LayoutManager implements IContainerInputHandler, IContainerTooltipHandler, IContainerDrawHandler,
|
||||
IContainerObjectHandler, IKeyStateTracker {
|
||||
@@ -92,7 +92,6 @@ public class LayoutManager implements IContainerInputHandler, IContainerTooltipH
|
||||
public static SubsetWidget dropDown;
|
||||
public static SearchField searchField;
|
||||
public static ItemZoom itemZoom;
|
||||
public static DebugHandlerWidget recipeHandlerWidget;
|
||||
|
||||
public static ButtonCycled options;
|
||||
public static ButtonCycled bookmarksButton;
|
||||
@@ -225,17 +224,17 @@ public class LayoutManager implements IContainerInputHandler, IContainerTooltipH
|
||||
@Override
|
||||
public boolean lastKeyTyped(GuiContainer gui, char keyChar, int keyID) {
|
||||
|
||||
if (NEIClientConfig.isKeyHashDown("gui.hide")) {
|
||||
if (KeyManager.isKeyDown("gui.hide")) {
|
||||
toggleBooleanSetting("inventory.hidden");
|
||||
return true;
|
||||
}
|
||||
|
||||
if (NEIClientConfig.isKeyHashDown("gui.hide_bookmarks")) {
|
||||
if (KeyManager.isKeyDown("bookmark.hide")) {
|
||||
toggleBooleanSetting("inventory.bookmarks.enabled");
|
||||
return true;
|
||||
}
|
||||
|
||||
if (NEIClientConfig.isKeyHashDown("gui.next_tooltip") && GuiContainerManager.incrementTooltipPage()) {
|
||||
if (KeyManager.isKeyDown("gui.next_tooltip") && GuiContainerManager.incrementTooltipPage()) {
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -406,8 +405,6 @@ public class LayoutManager implements IContainerInputHandler, IContainerTooltipH
|
||||
|
||||
itemZoom = new ItemZoom();
|
||||
|
||||
recipeHandlerWidget = new DebugHandlerWidget();
|
||||
|
||||
dropDown = new SubsetWidget();
|
||||
searchField = new SearchField("search");
|
||||
API.addItemFilter(searchField);
|
||||
@@ -786,8 +783,7 @@ public class LayoutManager implements IContainerInputHandler, IContainerTooltipH
|
||||
addWidget(dropDown);
|
||||
}
|
||||
|
||||
addWidget(recipeHandlerWidget);
|
||||
recipeHandlerWidget.setVisible();
|
||||
addWidget(DebugHandlerWidget.instance);
|
||||
}
|
||||
|
||||
public static LayoutStyle getLayoutStyle(int id) {
|
||||
@@ -945,12 +941,12 @@ public class LayoutManager implements IContainerInputHandler, IContainerTooltipH
|
||||
public void tickKeyStates() {
|
||||
if (Minecraft.getMinecraft().currentScreen != null) return;
|
||||
|
||||
if (KeyManager.keyStates.get("world.dawn").down) timeButtons[0].onButtonPress(false);
|
||||
if (KeyManager.keyStates.get("world.noon").down) timeButtons[1].onButtonPress(false);
|
||||
if (KeyManager.keyStates.get("world.dusk").down) timeButtons[2].onButtonPress(false);
|
||||
if (KeyManager.keyStates.get("world.midnight").down) timeButtons[3].onButtonPress(false);
|
||||
if (KeyManager.keyStates.get("world.rain").down) rain.onButtonPress(false);
|
||||
if (KeyManager.keyStates.get("world.heal").down) heal.onButtonPress(false);
|
||||
if (KeyManager.keyStates.get("world.creative").down) gamemode.onButtonPress(false);
|
||||
if (KeyManager.isPressed("world.dawn")) timeButtons[0].onButtonPress(false);
|
||||
if (KeyManager.isPressed("world.noon")) timeButtons[1].onButtonPress(false);
|
||||
if (KeyManager.isPressed("world.dusk")) timeButtons[2].onButtonPress(false);
|
||||
if (KeyManager.isPressed("world.midnight")) timeButtons[3].onButtonPress(false);
|
||||
if (KeyManager.isPressed("world.rain")) rain.onButtonPress(false);
|
||||
if (KeyManager.isPressed("world.heal")) heal.onButtonPress(false);
|
||||
if (KeyManager.isPressed("world.creative")) gamemode.onButtonPress(false);
|
||||
}
|
||||
}
|
||||
@@ -244,7 +244,11 @@ public class LayoutStyleMinecraft extends LayoutStyle {
|
||||
|
||||
Image icon = b.getRenderIcon();
|
||||
if (icon == null) {
|
||||
int colour = tex == 2 ? 0xffffa0 : tex == 0 ? 0x601010 : 0xe0e0e0;
|
||||
int labelColor = b.getRenderLabelColor();
|
||||
int colour = labelColor != 0 ? labelColor
|
||||
: tex == 2 ? ColorUtils.buttonLabelHover.getColor()
|
||||
: tex == 0 ? ColorUtils.buttonLabelDisabled.getColor()
|
||||
: ColorUtils.buttonLabelNormal.getColor();
|
||||
|
||||
drawStringC(b.getRenderLabel(), b.x + b.w / 2, b.y + (b.h - 8) / 2, colour);
|
||||
} else {
|
||||
|
||||
@@ -54,6 +54,7 @@ public class NEIActions {
|
||||
addAction("magnet", true);
|
||||
addAction("enchant", true);
|
||||
addAction("potion", true);
|
||||
addAction("autocraft");
|
||||
|
||||
canDisable.add("dawn");
|
||||
canDisable.add("noon");
|
||||
|
||||
@@ -6,6 +6,7 @@ import static codechicken.nei.PacketIDs.S2C;
|
||||
import net.minecraft.client.Minecraft;
|
||||
import net.minecraft.client.gui.inventory.GuiInventory;
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.nbt.NBTTagCompound;
|
||||
import net.minecraft.network.play.INetHandlerPlayClient;
|
||||
import net.minecraft.util.ChatComponentTranslation;
|
||||
import net.minecraft.world.World;
|
||||
@@ -14,6 +15,7 @@ import codechicken.core.ClientUtils;
|
||||
import codechicken.lib.inventory.InventoryUtils;
|
||||
import codechicken.lib.packet.PacketCustom;
|
||||
import codechicken.lib.packet.PacketCustom.IClientPacketHandler;
|
||||
import codechicken.nei.commands.CommandBookmarkAdd;
|
||||
import cpw.mods.fml.relauncher.Side;
|
||||
|
||||
public class NEICPH implements IClientPacketHandler {
|
||||
@@ -56,6 +58,18 @@ public class NEICPH implements IClientPacketHandler {
|
||||
case S2C.OPEN_POTION_GUI:
|
||||
ClientUtils.openSMPGui(packet.readUByte(), new GuiPotionCreator(mc.thePlayer.inventory));
|
||||
break;
|
||||
case S2C.CACHE_BOOKMARK_DATA:
|
||||
handleCacheBookmarkData(packet);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
private void handleCacheBookmarkData(PacketCustom packet) {
|
||||
final String payloadId = packet.readString();
|
||||
final NBTTagCompound payloadTag = packet.readNBTTagCompound();
|
||||
|
||||
if (payloadTag != null) {
|
||||
CommandBookmarkAdd.cachePayload(payloadId, payloadTag);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -186,9 +200,9 @@ public class NEICPH implements IClientPacketHandler {
|
||||
packet.sendToServer();
|
||||
}
|
||||
|
||||
public static void sendChatLink(ItemStack stackover) {
|
||||
public static void sendChatLink(NBTTagCompound payloadTag) {
|
||||
PacketCustom packet = new PacketCustom(channel, C2S.SEND_CHAT_ITEM_LINK);
|
||||
packet.writeItemStack(stackover);
|
||||
packet.writeNBTTagCompound(payloadTag);
|
||||
packet.sendToServer();
|
||||
}
|
||||
|
||||
|
||||
@@ -56,14 +56,11 @@ import codechicken.nei.config.OptionToggleButtonBoubs;
|
||||
import codechicken.nei.config.OptionUtilities;
|
||||
import codechicken.nei.config.preset.GuiPresetList;
|
||||
import codechicken.nei.event.NEIConfigsLoadedEvent;
|
||||
import codechicken.nei.recipe.DebugHandlerWidget;
|
||||
import codechicken.nei.recipe.GuiRecipeTab;
|
||||
import codechicken.nei.recipe.IRecipeHandler;
|
||||
import codechicken.nei.recipe.InformationHandler;
|
||||
import codechicken.nei.recipe.RecipeCatalysts;
|
||||
import codechicken.nei.recipe.RecipeInfo;
|
||||
import codechicken.nei.util.ItemUntranslator;
|
||||
import codechicken.nei.util.NEIKeyboardUtils;
|
||||
import codechicken.obfuscator.ObfuscationRun;
|
||||
|
||||
public class NEIClientConfig {
|
||||
@@ -149,6 +146,7 @@ public class NEIClientConfig {
|
||||
API.addOption(new OptionToggleButton("inventory.widgetsenabled"));
|
||||
|
||||
tag.getTag("findFuelsParallel").getBooleanValue(true);
|
||||
tag.getTag("showRepairOnlyForDamageableItems").getBooleanValue(true);
|
||||
|
||||
tag.getTag("inventory.autocrafting").getBooleanValue(true);
|
||||
tag.getTag("inventory.dynamicFontSize").getBooleanValue(true);
|
||||
@@ -264,6 +262,10 @@ public class NEIClientConfig {
|
||||
.setComment("Require holding shift to move items when overlaying recipe").getBooleanValue(true);
|
||||
API.addOption(new OptionToggleButton("inventory.guirecipe.shiftOverlayRecipe", true));
|
||||
|
||||
tag.getTag("inventory.guirecipe.scrollPages").setComment("Disable page scroll when overlaying recipe")
|
||||
.getBooleanValue(true);
|
||||
API.addOption(new OptionToggleButton("inventory.guirecipe.scrollPages", true));
|
||||
|
||||
tag.getTag("inventory.guirecipe.profile").getBooleanValue(false);
|
||||
API.addOption(new OptionToggleButton("inventory.guirecipe.profile", true));
|
||||
|
||||
@@ -308,7 +310,7 @@ public class NEIClientConfig {
|
||||
super.onClick(button);
|
||||
CollapsibleItems.saveStates();
|
||||
CollapsibleItems.load();
|
||||
LayoutManager.markItemsDirty();
|
||||
ItemList.refreshItems.restart();
|
||||
return true;
|
||||
}
|
||||
});
|
||||
@@ -782,8 +784,7 @@ public class NEIClientConfig {
|
||||
@Override
|
||||
public boolean onClick(int button) {
|
||||
super.onClick(button);
|
||||
FavoriteRecipes.save();
|
||||
FavoriteRecipes.load();
|
||||
FavoriteRecipes.reload();
|
||||
return true;
|
||||
}
|
||||
});
|
||||
@@ -796,39 +797,55 @@ public class NEIClientConfig {
|
||||
.getBooleanValue(false);
|
||||
API.addOption(new OptionToggleButton("inventory.favorites.showRecipeTooltipInGui", true));
|
||||
|
||||
tag.getTag("inventory.favorites.depth").setComment("Bookmark creation depth").getIntValue(3);
|
||||
tag.getTag("inventory.favorites.generateSingleRecipeFavorites")
|
||||
.setComment("Automatically generate favorites for items with only one recipe").getBooleanValue(false);
|
||||
API.addOption(new OptionToggleButton("inventory.favorites.generateSingleRecipeFavorites", true) {
|
||||
|
||||
@Override
|
||||
public boolean onClick(int button) {
|
||||
super.onClick(button);
|
||||
FavoriteRecipes.loadAutoGeneratedRecipes();
|
||||
return true;
|
||||
}
|
||||
});
|
||||
|
||||
tag.getTag("inventory.favorites.depth").setComment("Bookmark creation depth").getIntValue(9);
|
||||
API.addOption(new OptionIntegerField("inventory.favorites.depth", 0, 100));
|
||||
}
|
||||
|
||||
private static void setDefaultKeyBindings() {
|
||||
API.addHashBind("gui.recipe", Keyboard.KEY_R);
|
||||
API.addHashBind("gui.usage", Keyboard.KEY_U);
|
||||
API.addKeyBind("gui.back", Keyboard.KEY_BACK);
|
||||
API.addHashBind("gui.enchant", Keyboard.KEY_X);
|
||||
API.addHashBind("gui.potion", Keyboard.KEY_P);
|
||||
API.addKeyBind("gui.enchant", Keyboard.KEY_X);
|
||||
API.addKeyBind("gui.potion", Keyboard.KEY_P);
|
||||
API.addKeyBind("gui.prev", Keyboard.KEY_PRIOR);
|
||||
API.addKeyBind("gui.next", Keyboard.KEY_NEXT);
|
||||
API.addKeyBind("gui.prev_machine", Keyboard.KEY_UP);
|
||||
API.addKeyBind("gui.next_machine", Keyboard.KEY_DOWN);
|
||||
API.addKeyBind("gui.prev_recipe", Keyboard.KEY_LEFT);
|
||||
API.addKeyBind("gui.next_recipe", Keyboard.KEY_RIGHT);
|
||||
API.addHashBind("gui.hide", Keyboard.KEY_O);
|
||||
API.addHashBind("gui.search", Keyboard.KEY_F);
|
||||
API.addKeyBind("gui.bookmark", Keyboard.KEY_A);
|
||||
API.addHashBind("gui.favorite", Keyboard.KEY_F + NEIClientUtils.SHIFT_HASH);
|
||||
API.addHashBind("gui.remove_recipe", Keyboard.KEY_A + NEIClientUtils.SHIFT_HASH);
|
||||
API.addKeyBind("gui.bookmark_pull_items", Keyboard.KEY_V);
|
||||
API.addKeyBind("gui.hide", Keyboard.KEY_O);
|
||||
API.addKeyBind("gui.search", Keyboard.KEY_F);
|
||||
API.addKeyBind("gui.overlay", Keyboard.KEY_S);
|
||||
API.addKeyBind("gui.craft_items", Keyboard.KEY_C);
|
||||
API.addHashBind("gui.hide_bookmarks", Keyboard.KEY_B);
|
||||
API.addKeyBind("gui.getprevioussearch", Keyboard.KEY_UP);
|
||||
API.addKeyBind("gui.getnextsearch", Keyboard.KEY_DOWN);
|
||||
API.addKeyBind("gui.next_tooltip", Keyboard.KEY_Z);
|
||||
|
||||
API.addHashBind("gui.itemzoom_toggle", Keyboard.KEY_Z + NEIClientUtils.SHIFT_HASH);
|
||||
API.addHashBind("gui.itemzoom_hold", 0);
|
||||
API.addHashBind("gui.itemzoom_zoom_in", 0);
|
||||
API.addHashBind("gui.itemzoom_zoom_out", 0);
|
||||
API.addKeyBind("recipe.recipe", Keyboard.KEY_R);
|
||||
API.addKeyBind("recipe.usage", Keyboard.KEY_U);
|
||||
API.addKeyBind("recipe.back", Keyboard.KEY_BACK);
|
||||
API.addKeyBind("recipe.prev_machine", Keyboard.KEY_UP);
|
||||
API.addKeyBind("recipe.next_machine", Keyboard.KEY_DOWN);
|
||||
API.addKeyBind("recipe.prev_recipe", Keyboard.KEY_LEFT);
|
||||
API.addKeyBind("recipe.next_recipe", Keyboard.KEY_RIGHT);
|
||||
|
||||
API.addKeyBind("bookmark.add", Keyboard.KEY_A);
|
||||
API.addKeyBind("bookmark.favorite", Keyboard.KEY_F);
|
||||
API.addKeyBind("bookmark.favorite_item", Keyboard.KEY_F);
|
||||
API.addKeyBind("bookmark.remove_recipe", Keyboard.KEY_A);
|
||||
API.addKeyBind("bookmark.pull_items", Keyboard.KEY_V);
|
||||
API.addKeyBind("bookmark.chat_link", Keyboard.KEY_L);
|
||||
API.addKeyBind("bookmark.hide", Keyboard.KEY_B);
|
||||
|
||||
API.addKeyBind("itemzoom.toggle", Keyboard.KEY_Z);
|
||||
API.addKeyBind("itemzoom.hold", 0);
|
||||
API.addKeyBind("itemzoom.zoom_in", 0);
|
||||
API.addKeyBind("itemzoom.zoom_out", 0);
|
||||
|
||||
API.addKeyBind("world.chunkoverlay", Keyboard.KEY_F9);
|
||||
API.addKeyBind("world.moboverlay", Keyboard.KEY_F7);
|
||||
@@ -840,10 +857,10 @@ public class NEIClientConfig {
|
||||
API.addKeyBind("world.rain", 0);
|
||||
API.addKeyBind("world.heal", 0);
|
||||
API.addKeyBind("world.creative", 0);
|
||||
API.addHashBind("gui.copy_name", Keyboard.KEY_C + NEIClientUtils.CTRL_HASH);
|
||||
API.addHashBind("gui.copy_oredict", Keyboard.KEY_D + NEIClientUtils.CTRL_HASH);
|
||||
API.addHashBind("gui.copy_id", Keyboard.KEY_X + NEIClientUtils.CTRL_HASH);
|
||||
API.addHashBind("gui.chat_link_item", Keyboard.KEY_L + NEIClientUtils.CTRL_HASH);
|
||||
|
||||
API.addKeyBind("copy.name", Keyboard.KEY_C);
|
||||
API.addKeyBind("copy.oredict", Keyboard.KEY_D);
|
||||
API.addKeyBind("copy.identifier", Keyboard.KEY_X);
|
||||
}
|
||||
|
||||
public static OptionList getOptionList() {
|
||||
@@ -914,50 +931,28 @@ public class NEIClientConfig {
|
||||
world.saveNBT();
|
||||
}
|
||||
|
||||
private static final Map<String, String> keySettings = new HashMap<>();
|
||||
|
||||
public static int getKeyBinding(String string) {
|
||||
final String key = keySettings.computeIfAbsent(string, s -> "keys." + s);
|
||||
return getSetting(key).getIntValue(Keyboard.KEY_NONE);
|
||||
return KeyManager.getKeyCode(string);
|
||||
}
|
||||
|
||||
public static void setDefaultKeyBinding(String string, int key) {
|
||||
getSetting("keys." + string).getIntValue(key);
|
||||
KeyManager.registerKeyBinding(string, key);
|
||||
}
|
||||
|
||||
public static boolean isKeyHashDown(String string) {
|
||||
final int hash = getKeyBinding(string);
|
||||
|
||||
if (hash != Keyboard.CHAR_NONE && Keyboard.getEventKeyState()) {
|
||||
return KeyManager.keyStates.containsKey(string) ? Keyboard.isKeyDown(NEIKeyboardUtils.unhash(hash))
|
||||
: hash == NEIClientUtils.getKeyHash();
|
||||
}
|
||||
|
||||
return false;
|
||||
return KeyManager.isHashDown(string);
|
||||
}
|
||||
|
||||
public static String getKeyName(String keyBind) {
|
||||
return getKeyName(keyBind, 0);
|
||||
return KeyManager.getKeyName(keyBind);
|
||||
}
|
||||
|
||||
public static String getKeyName(String keyBind, int meta, int mouseBind) {
|
||||
final int hash = getKeyBinding(keyBind);
|
||||
|
||||
if (hash == Keyboard.CHAR_NONE) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return NEIClientUtils.getKeyName(hash + meta, mouseBind);
|
||||
return KeyManager.getKeyName(keyBind, meta, mouseBind);
|
||||
}
|
||||
|
||||
public static String getKeyName(String keyBind, int meta) {
|
||||
final int hash = getKeyBinding(keyBind);
|
||||
|
||||
if (hash == Keyboard.CHAR_NONE) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return NEIKeyboardUtils.getKeyName(hash + meta);
|
||||
return KeyManager.getKeyName(keyBind, meta);
|
||||
}
|
||||
|
||||
public static void bootNEI() {
|
||||
@@ -966,7 +961,6 @@ public class NEIClientConfig {
|
||||
// main NEI config loading
|
||||
ItemInfo.load();
|
||||
GuiInfo.load();
|
||||
RecipeInfo.load();
|
||||
HeldItemHandler.load();
|
||||
LayoutManager.load();
|
||||
NEIController.load();
|
||||
@@ -993,12 +987,12 @@ public class NEIClientConfig {
|
||||
}
|
||||
});
|
||||
|
||||
KeyManager.requestOptionsReload();
|
||||
RecipeCatalysts.loadCatalystInfo();
|
||||
SubsetWidget.loadCustomSubsets();
|
||||
SubsetWidget.loadHidden();
|
||||
CollapsibleItems.load();
|
||||
ItemSorter.loadConfig();
|
||||
FavoriteRecipes.load();
|
||||
|
||||
// Set pluginNEIConfigLoaded here before posting the NEIConfigsLoadedEvent. This used to be the
|
||||
// other way around, but apparently if your modpack includes 800 mods the event poster might not
|
||||
@@ -1007,14 +1001,16 @@ public class NEIClientConfig {
|
||||
// API. I don't expect any handler to do this, but who knows what modders have come up with...
|
||||
pluginNEIConfigLoaded = true;
|
||||
MinecraftForge.EVENT_BUS.post(new NEIConfigsLoadedEvent());
|
||||
|
||||
DebugHandlerWidget.loadHandlerInfoPatch();
|
||||
ItemList.loadItems.restart();
|
||||
}
|
||||
}.start();
|
||||
} else {
|
||||
SubsetWidget.loadHidden();
|
||||
ItemList.loadItems.restart();
|
||||
if (ItemList.loadFinished) {
|
||||
ItemList.refreshItems.restart();
|
||||
} else {
|
||||
ItemList.loadItems.restart();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1038,7 +1034,9 @@ public class NEIClientConfig {
|
||||
}
|
||||
|
||||
public static boolean autocraftingEnabled() {
|
||||
return getBooleanSetting("inventory.autocrafting");
|
||||
if (!getBooleanSetting("inventory.autocrafting")) return false;
|
||||
if (hasSMPCounterpart) return permissableActions.contains("autocraft");
|
||||
return true;
|
||||
}
|
||||
|
||||
public static boolean favoritesEnabled() {
|
||||
|
||||
@@ -25,7 +25,6 @@ import java.util.List;
|
||||
import java.util.Locale;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.StringJoiner;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import net.minecraft.client.Minecraft;
|
||||
@@ -39,6 +38,7 @@ import net.minecraft.inventory.Container;
|
||||
import net.minecraft.inventory.Slot;
|
||||
import net.minecraft.item.Item;
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.nbt.NBTTagCompound;
|
||||
import net.minecraft.util.IChatComponent;
|
||||
import net.minecraft.util.ResourceLocation;
|
||||
|
||||
@@ -46,6 +46,7 @@ import org.lwjgl.input.Keyboard;
|
||||
import org.lwjgl.opengl.GL11;
|
||||
|
||||
import com.google.common.collect.Iterables;
|
||||
import com.gtnewhorizon.gtnhlib.util.numberformatting.NumberFormatUtil;
|
||||
|
||||
import codechicken.lib.gui.GuiDraw;
|
||||
import codechicken.lib.inventory.InventoryRange;
|
||||
@@ -56,7 +57,6 @@ import codechicken.nei.api.GuiInfo;
|
||||
import codechicken.nei.api.IInfiniteItemHandler;
|
||||
import codechicken.nei.api.ItemInfo;
|
||||
import codechicken.nei.util.NEIKeyboardUtils;
|
||||
import codechicken.nei.util.NEIMouseUtils;
|
||||
|
||||
public class NEIClientUtils extends NEIServerUtils {
|
||||
|
||||
@@ -94,6 +94,7 @@ public class NEIClientUtils extends NEIServerUtils {
|
||||
|
||||
/** Formats a number with group separator and at most 2 fraction digits. */
|
||||
private static final Map<Locale, DecimalFormat> decimalFormatters = new HashMap<>();
|
||||
private static final DecimalFormat CHANCE_FORMAT = new DecimalFormat("##0.##%");
|
||||
|
||||
public static final int ALT_HASH = NEIKeyboardUtils.ALT_HASH;
|
||||
public static final int SHIFT_HASH = NEIKeyboardUtils.SHIFT_HASH;
|
||||
@@ -125,6 +126,28 @@ public class NEIClientUtils extends NEIServerUtils {
|
||||
});
|
||||
}
|
||||
|
||||
public static String formatNumber(Number aNumber) {
|
||||
|
||||
if (NEIModContainer.isGTNHLibLoaded()) {
|
||||
return NumberFormatUtil.formatNumber(aNumber);
|
||||
}
|
||||
|
||||
return getDecimalFormat().format(aNumber);
|
||||
}
|
||||
|
||||
public static String formatFluid(Number aNumber) {
|
||||
|
||||
if (NEIModContainer.isGTNHLibLoaded()) {
|
||||
return NumberFormatUtil.formatFluid(aNumber);
|
||||
}
|
||||
|
||||
return getDecimalFormat().format(aNumber) + " L";
|
||||
}
|
||||
|
||||
public static String formatChance(float chance) {
|
||||
return CHANCE_FORMAT.format(chance);
|
||||
}
|
||||
|
||||
public static void deleteHeldItem() {
|
||||
deleteSlotStack(-999);
|
||||
}
|
||||
@@ -185,7 +208,7 @@ public class NEIClientUtils extends NEIServerUtils {
|
||||
public static void cheatItem(ItemStack stack, int button, int mode) {
|
||||
if (!canCheatItem(stack)) return;
|
||||
|
||||
if (mode == -1 && button == 0 && shiftKey() && NEIClientConfig.hasSMPCounterPart()) {
|
||||
if (mode == -1 && button == 0 && controlKey() && NEIClientConfig.hasSMPCounterPart()) {
|
||||
for (IInfiniteItemHandler handler : ItemInfo.infiniteHandlers) {
|
||||
if (!handler.canHandleItem(stack)) continue;
|
||||
|
||||
@@ -357,8 +380,8 @@ public class NEIClientUtils extends NEIServerUtils {
|
||||
else sendCommand(getStringSetting("command.heal"), mc().thePlayer.getCommandSenderName());
|
||||
}
|
||||
|
||||
public static void sendChatItemLink(ItemStack stackover) {
|
||||
if (hasSMPCounterPart()) NEICPH.sendChatLink(stackover);
|
||||
public static void sendChatItemLink(NBTTagCompound payload) {
|
||||
if (hasSMPCounterPart()) NEICPH.sendChatLink(payload);
|
||||
}
|
||||
|
||||
public static void toggleMagnetMode() {
|
||||
@@ -432,55 +455,8 @@ public class NEIClientUtils extends NEIServerUtils {
|
||||
return Keyboard.isKeyDown(Keyboard.KEY_LMENU) || Keyboard.isKeyDown(Keyboard.KEY_RMENU);
|
||||
}
|
||||
|
||||
public static int getMetaHash() {
|
||||
if (Keyboard.getEventKeyState()) {
|
||||
int hash = 0;
|
||||
|
||||
if (altKey()) {
|
||||
hash = hash | ALT_HASH;
|
||||
}
|
||||
|
||||
if (shiftKey()) {
|
||||
hash = hash | SHIFT_HASH;
|
||||
}
|
||||
|
||||
if (controlKey()) {
|
||||
hash = hash | CTRL_HASH;
|
||||
}
|
||||
|
||||
return hash;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
public static int getKeyHash() {
|
||||
|
||||
if (Keyboard.getEventKeyState()) {
|
||||
final int keycode = Keyboard.getEventKey();
|
||||
|
||||
if (!NEIKeyboardUtils.isHashKey(keycode)) {
|
||||
return getMetaHash() + keycode;
|
||||
}
|
||||
}
|
||||
|
||||
return Keyboard.CHAR_NONE;
|
||||
}
|
||||
|
||||
public static String getKeyName(int keyBind, int mouseBind) {
|
||||
StringJoiner keyText = new StringJoiner(" + ");
|
||||
String keyHash = keyBind == Keyboard.KEY_NONE ? "" : NEIKeyboardUtils.getKeyName(keyBind);
|
||||
String mouseHash = mouseBind == NEIMouseUtils.MOUSE_BTN_NONE ? "" : NEIMouseUtils.getKeyName(mouseBind);
|
||||
|
||||
if (!keyHash.isEmpty()) {
|
||||
keyText.add(keyHash);
|
||||
}
|
||||
|
||||
if (!mouseHash.isEmpty()) {
|
||||
keyText.add(mouseHash);
|
||||
}
|
||||
|
||||
return keyText.toString();
|
||||
return KeyManager.getKeyName(keyBind, mouseBind);
|
||||
}
|
||||
|
||||
public static void playClickSound() {
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
package codechicken.nei;
|
||||
|
||||
import static codechicken.lib.gui.GuiDraw.getMousePosition;
|
||||
import static codechicken.nei.NEIClientConfig.canCheatItem;
|
||||
|
||||
import java.awt.Point;
|
||||
import java.util.LinkedList;
|
||||
@@ -26,7 +27,7 @@ import codechicken.nei.commands.CommandUntranslator;
|
||||
import codechicken.nei.guihook.GuiContainerManager;
|
||||
import codechicken.nei.guihook.IContainerInputHandler;
|
||||
import codechicken.nei.guihook.IContainerSlotClickHandler;
|
||||
import codechicken.nei.recipe.GuiRecipe;
|
||||
import codechicken.nei.util.EmptyContainer;
|
||||
import cpw.mods.fml.relauncher.Side;
|
||||
import cpw.mods.fml.relauncher.SideOnly;
|
||||
|
||||
@@ -151,6 +152,8 @@ public class NEIController implements IContainerSlotClickHandler, IContainerInpu
|
||||
&& slot != null
|
||||
&& slot.getStack() != null
|
||||
&& slot.isItemValid(slot.getStack())) {
|
||||
if (!canCheatItem(slot.getStack())) return false;
|
||||
|
||||
NEIClientUtils.cheatItem(slot.getStack(), button, 1);
|
||||
return true;
|
||||
}
|
||||
@@ -249,7 +252,7 @@ public class NEIController implements IContainerSlotClickHandler, IContainerInpu
|
||||
|
||||
// slot in GuiRecipe does not contain actual stack
|
||||
// and scroll should be handled by GuiRecipe, not here
|
||||
if (gui instanceof GuiRecipe) return false;
|
||||
if (gui.inventorySlots instanceof EmptyContainer) return false;
|
||||
|
||||
Point mousePos = getMousePosition();
|
||||
Slot mouseover = manager.window.getSlotAtPosition(mousePos.x, mousePos.y);
|
||||
|
||||
@@ -43,6 +43,7 @@ public class NEIModContainer extends DummyModContainer {
|
||||
|
||||
private static boolean gregTech5Loaded;
|
||||
private static boolean gtnhLibLoaded;
|
||||
private static boolean cubicChunksLoaded;
|
||||
|
||||
private static ASMDataTable asmDataTable;
|
||||
|
||||
@@ -55,7 +56,7 @@ public class NEIModContainer extends DummyModContainer {
|
||||
modMetadata.name = "NotEnoughItems";
|
||||
modMetadata.modId = "NotEnoughItems";
|
||||
modMetadata.version = Tags.VERSION;
|
||||
modMetadata.authorList = Arrays.asList("ChickenBones", "mitchej123");
|
||||
modMetadata.authorList = Arrays.asList("ChickenBones", "mitchej123", "SLPrime");
|
||||
modMetadata.url = "https://github.com/GTNewHorizons/NotEnoughItems";
|
||||
modMetadata.description = "Recipe Viewer, Inventory Manager, Item Spawner, Cheats and more; GTNH Version includes many enhancements.";
|
||||
return modMetadata;
|
||||
@@ -69,6 +70,10 @@ public class NEIModContainer extends DummyModContainer {
|
||||
return gtnhLibLoaded;
|
||||
}
|
||||
|
||||
public static boolean isCCLoaded() {
|
||||
return cubicChunksLoaded;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Set<ArtifactVersion> getRequirements() {
|
||||
Set<ArtifactVersion> deps = new HashSet<>();
|
||||
@@ -80,7 +85,7 @@ public class NEIModContainer extends DummyModContainer {
|
||||
public List<ArtifactVersion> getDependencies() {
|
||||
List<ArtifactVersion> deps = new ArrayList<>();
|
||||
deps.add(VersionParser.parseVersionReference("CodeChickenCore@[" + codechicken.core.asm.Tags.VERSION + ",)"));
|
||||
deps.add(VersionParser.parseVersionReference("gtnhlib@[0.6.0,)"));
|
||||
deps.add(VersionParser.parseVersionReference("gtnhlib@[0.9.6,)"));
|
||||
return deps;
|
||||
}
|
||||
|
||||
@@ -96,6 +101,7 @@ public class NEIModContainer extends DummyModContainer {
|
||||
public void preInit(FMLPreInitializationEvent event) {
|
||||
gregTech5Loaded = Loader.isModLoaded("gregtech") && !Loader.isModLoaded("gregapi_post");
|
||||
gtnhLibLoaded = Loader.isModLoaded("gtnhlib");
|
||||
cubicChunksLoaded = Loader.isModLoaded("cubicchunks");
|
||||
if (CommonUtils.isClient()) ClientHandler.preInit();
|
||||
asmDataTable = event.getAsmData();
|
||||
}
|
||||
@@ -104,6 +110,7 @@ public class NEIModContainer extends DummyModContainer {
|
||||
public void init(FMLInitializationEvent event) {
|
||||
if (CommonUtils.isClient()) {
|
||||
ClientHandler.load();
|
||||
IMCForNEI.IMCSender();
|
||||
}
|
||||
ServerHandler.load();
|
||||
}
|
||||
|
||||
@@ -11,6 +11,7 @@ import net.minecraft.entity.player.EntityPlayerMP;
|
||||
import net.minecraft.inventory.InventoryBasic;
|
||||
import net.minecraft.inventory.Slot;
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.nbt.NBTTagCompound;
|
||||
import net.minecraft.network.play.INetHandlerPlayServer;
|
||||
import net.minecraft.tileentity.TileEntity;
|
||||
import net.minecraft.tileentity.TileEntityMobSpawner;
|
||||
@@ -95,7 +96,8 @@ public class NEISPH implements IServerPacketHandler {
|
||||
}
|
||||
|
||||
private void handleSendChatItemLink(EntityPlayerMP sender, PacketCustom packet) {
|
||||
NEIServerUtils.sendChatItemLink(sender, packet.readItemStack());
|
||||
final NBTTagCompound payloadTag = packet.readNBTTagCompound();
|
||||
NEIServerUtils.sendChatItemLink(sender, payloadTag);
|
||||
}
|
||||
|
||||
private void handleDummySlotSet(EntityPlayerMP sender, PacketCustom packet) {
|
||||
|
||||
@@ -108,6 +108,7 @@ public class NEIServerConfig {
|
||||
setDefaultFeature("save-state");
|
||||
setDefaultFeature("item");
|
||||
setDefaultFeature("delete");
|
||||
setDefaultFeature("autocraft", "ALL");
|
||||
setDefaultFeature("notify-item", "CONSOLE, OP");
|
||||
}
|
||||
|
||||
|
||||
@@ -10,6 +10,7 @@ import java.util.AbstractList;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
import java.util.UUID;
|
||||
import java.util.zip.ZipException;
|
||||
|
||||
import net.minecraft.command.ICommandSender;
|
||||
@@ -28,6 +29,7 @@ import net.minecraft.nbt.NBTException;
|
||||
import net.minecraft.nbt.NBTTagCompound;
|
||||
import net.minecraft.nbt.NBTTagList;
|
||||
import net.minecraft.server.MinecraftServer;
|
||||
import net.minecraft.util.ChatComponentText;
|
||||
import net.minecraft.util.ChatComponentTranslation;
|
||||
import net.minecraft.util.EnumChatFormatting;
|
||||
import net.minecraft.util.IChatComponent;
|
||||
@@ -44,6 +46,7 @@ import codechicken.lib.inventory.InventoryRange;
|
||||
import codechicken.lib.inventory.InventoryUtils;
|
||||
import codechicken.lib.packet.PacketCustom;
|
||||
import codechicken.nei.PacketIDs.S2C;
|
||||
import codechicken.nei.recipe.StackInfo;
|
||||
import codechicken.nei.util.NBTHelper;
|
||||
import cpw.mods.fml.common.FMLLog;
|
||||
import cpw.mods.fml.common.registry.GameRegistry;
|
||||
@@ -86,16 +89,46 @@ public class NEIServerUtils {
|
||||
player.extinguish();
|
||||
}
|
||||
|
||||
public static void sendChatItemLink(EntityPlayerMP sender, ItemStack stackover) {
|
||||
ServerUtils.sendChatToAll(
|
||||
new ChatComponentTranslation(
|
||||
"nei.chat.item_link.text",
|
||||
sender.getDisplayName(),
|
||||
stackover.func_151000_E().setChatStyle(
|
||||
stackover.func_151000_E().getChatStyle().setChatClickEvent(
|
||||
new ClickEvent(
|
||||
ClickEvent.Action.RUN_COMMAND,
|
||||
"/nei_bookmark " + stackover.writeToNBT(new NBTTagCompound()))))));
|
||||
public static void sendChatItemLink(EntityPlayerMP sender, NBTTagCompound payload) {
|
||||
if (payload == null) {
|
||||
sender.addChatMessage(new ChatComponentText("Invalid bookmark payload"));
|
||||
return;
|
||||
}
|
||||
|
||||
final String linkType = payload.getString("linkType");
|
||||
final String payloadId = UUID.randomUUID().toString().substring(0, 8);
|
||||
final PacketCustom packet = new PacketCustom(NEISPH.channel, S2C.CACHE_BOOKMARK_DATA).writeString(payloadId)
|
||||
.writeNBTTagCompound((NBTTagCompound) payload.copy());
|
||||
|
||||
for (EntityPlayer player : ServerUtils.getPlayers()) {
|
||||
if (player instanceof EntityPlayerMP playerMP) {
|
||||
packet.sendToPlayer(playerMP);
|
||||
}
|
||||
}
|
||||
|
||||
try {
|
||||
final IChatComponent clickable;
|
||||
|
||||
if (payload.hasKey("item")) {
|
||||
clickable = StackInfo.loadFromNBT(payload.getCompoundTag("item")).func_151000_E();
|
||||
} else {
|
||||
clickable = new ChatComponentText("[")
|
||||
.appendSibling(new ChatComponentTranslation("nei.chat.item_link." + linkType + ".text"))
|
||||
.appendText("]");
|
||||
}
|
||||
|
||||
if (clickable == null) {
|
||||
throw new Exception("Invalid ItemStack NBT");
|
||||
}
|
||||
|
||||
clickable.getChatStyle()
|
||||
.setChatClickEvent(new ClickEvent(ClickEvent.Action.RUN_COMMAND, "/nei_bookmark " + payloadId));
|
||||
ServerUtils.sendChatToAll(
|
||||
new ChatComponentTranslation("nei.chat.item_link.text", sender.getDisplayName(), clickable));
|
||||
} catch (Exception e) {
|
||||
sender.addChatMessage(new ChatComponentText(e.toString()));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public static long getTime(World world) {
|
||||
@@ -183,7 +216,7 @@ public class NEIServerUtils {
|
||||
public static boolean areStacksSameTypeWithNBT(ItemStack stack1, ItemStack stack2) {
|
||||
return stack1 != null && stack2 != null
|
||||
&& stack1.getItem() == stack2.getItem()
|
||||
&& (!stack2.getHasSubtypes() || stack2.getItemDamage() == stack1.getItemDamage())
|
||||
&& (stack2.isItemStackDamageable() || stack2.getItemDamage() == stack1.getItemDamage())
|
||||
&& NBTHelper.matchTag(stack1.getTagCompound(), stack2.getTagCompound());
|
||||
}
|
||||
|
||||
|
||||
@@ -37,5 +37,6 @@ public final class PacketIDs {
|
||||
public static final int OPEN_ENCHANTMENT_GUI = 21;
|
||||
public static final int SET_CREATIVE_PLUS_MODE = 23;
|
||||
public static final int OPEN_POTION_GUI = 24;
|
||||
public static final int CACHE_BOOKMARK_DATA = 25;
|
||||
}
|
||||
}
|
||||
@@ -82,14 +82,14 @@ public abstract class PanelWidget<T extends ItemsGrid<? extends ItemsGridSlot, ?
|
||||
|
||||
public abstract String getLabelText();
|
||||
|
||||
public abstract Rectangle4i calculateBounds();
|
||||
public abstract Rectangle4i calculateBounds(GuiContainer gui);
|
||||
|
||||
protected static int snapDownToMultiple(int value, int multiple) {
|
||||
return (value / multiple) * multiple;
|
||||
}
|
||||
|
||||
public void resize(GuiContainer gui) {
|
||||
final Rectangle4i bounds = calculateBounds();
|
||||
final Rectangle4i bounds = calculateBounds(gui);
|
||||
|
||||
x = bounds.x;
|
||||
y = bounds.y;
|
||||
@@ -309,12 +309,12 @@ public abstract class PanelWidget<T extends ItemsGrid<? extends ItemsGridSlot, ?
|
||||
final Point mouse = GuiDraw.getMousePosition();
|
||||
if (!contains(mouse.x, mouse.y)) return false;
|
||||
|
||||
if (NEIClientConfig.isKeyHashDown("gui.next")) {
|
||||
if (KeyManager.isKeyDown("gui.next")) {
|
||||
this.grid.shiftPage(1);
|
||||
return true;
|
||||
}
|
||||
|
||||
if (NEIClientConfig.isKeyHashDown("gui.prev")) {
|
||||
if (KeyManager.isKeyDown("gui.prev")) {
|
||||
this.grid.shiftPage(-1);
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -24,12 +24,12 @@ public class PopupInputHandler implements IContainerInputHandler {
|
||||
@Override
|
||||
public boolean lastKeyTyped(GuiContainer gui, char keyChar, int keyID) {
|
||||
|
||||
if (NEIClientConfig.isKeyHashDown("gui.enchant") && canPerformAction("enchant")) {
|
||||
if (KeyManager.isHashDown("gui.enchant") && canPerformAction("enchant")) {
|
||||
NEICPH.sendOpenEnchantmentWindow();
|
||||
return true;
|
||||
}
|
||||
|
||||
if (NEIClientConfig.isKeyHashDown("gui.potion") && canPerformAction("potion")) {
|
||||
if (KeyManager.isHashDown("gui.potion") && canPerformAction("potion")) {
|
||||
NEICPH.sendOpenPotionWindow();
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -13,6 +13,7 @@ import net.minecraftforge.oredict.OreDictionary;
|
||||
|
||||
import codechicken.nei.api.ItemFilter;
|
||||
import codechicken.nei.api.ItemInfo;
|
||||
import codechicken.nei.recipe.Badge;
|
||||
import codechicken.nei.recipe.GuiRecipe;
|
||||
import codechicken.nei.recipe.StackInfo;
|
||||
|
||||
@@ -21,12 +22,16 @@ import codechicken.nei.recipe.StackInfo;
|
||||
*/
|
||||
public class PositionedStack {
|
||||
|
||||
/** Maximum chance value representing 100% probability (1 unit = 0.01%). */
|
||||
public static final int CHANCE_FULL = 10_000;
|
||||
|
||||
public int relx;
|
||||
public int rely;
|
||||
public ItemStack[] items;
|
||||
// compatibility dummy
|
||||
public ItemStack item;
|
||||
|
||||
protected int chance = CHANCE_FULL;
|
||||
private boolean permutated = false;
|
||||
|
||||
public PositionedStack(Object object, int x, int y, boolean genPerms) {
|
||||
@@ -82,6 +87,18 @@ public class PositionedStack {
|
||||
for (ItemStack item : items) if (item.stackSize > i) item.stackSize = i;
|
||||
}
|
||||
|
||||
public List<Badge> getBadges() {
|
||||
return null;
|
||||
}
|
||||
|
||||
public int getChance() {
|
||||
return this.chance;
|
||||
}
|
||||
|
||||
public void setChance(int chance) {
|
||||
this.chance = chance;
|
||||
}
|
||||
|
||||
public PositionedStack copy() {
|
||||
PositionedStack pStack = new PositionedStack(
|
||||
Arrays.stream(this.items).map(ItemStack::copy).toArray(ItemStack[]::new),
|
||||
@@ -89,6 +106,7 @@ public class PositionedStack {
|
||||
rely,
|
||||
false);
|
||||
pStack.permutated = this.permutated;
|
||||
pStack.chance = this.chance;
|
||||
return pStack;
|
||||
}
|
||||
|
||||
@@ -104,7 +122,7 @@ public class PositionedStack {
|
||||
items = filteringPermutations(items, GuiRecipe.getSearchItemFilter());
|
||||
items = filteringPermutations(items, additionalFilter);
|
||||
|
||||
items.sort(Comparator.comparing(FavoriteRecipes::contains).reversed());
|
||||
items.sort(Comparator.comparing(FavoriteRecipes::containsManual).reversed());
|
||||
return items;
|
||||
}
|
||||
|
||||
|
||||
@@ -89,9 +89,9 @@ public class PresetsList {
|
||||
return false;
|
||||
}
|
||||
|
||||
final PositionedStack result = handler.getResultStack(recipeIndex);
|
||||
final List<PositionedStack> results = handler.getResultStacks(recipeIndex);
|
||||
|
||||
if (result != null && matchPositionedStack(result)) {
|
||||
if (!results.isEmpty() && matchPositionedStack(results, true)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -101,7 +101,13 @@ public class PresetsList {
|
||||
return true;
|
||||
}
|
||||
|
||||
return result == null && others.isEmpty();
|
||||
final List<PositionedStack> extraInputs = handler.getCatalystStacks(recipeIndex);
|
||||
|
||||
if (!extraInputs.isEmpty() && matchPositionedStack(extraInputs, true)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return results.isEmpty() && others.isEmpty();
|
||||
}
|
||||
|
||||
private boolean matchPositionedStack(List<PositionedStack> items, boolean dir) {
|
||||
@@ -251,7 +257,7 @@ public class PresetsList {
|
||||
updateSubsets();
|
||||
CollapsibleItems.saveStates();
|
||||
CollapsibleItems.load();
|
||||
LayoutManager.markItemsDirty();
|
||||
ItemList.refreshItems.restart();
|
||||
}
|
||||
|
||||
private static void updateSubsets() {
|
||||
|
||||
@@ -50,11 +50,11 @@ public abstract class RecipeSearchField extends TextField implements ItemFilterP
|
||||
@Override
|
||||
public void lastKeyTyped(int keyID, char keyChar) {
|
||||
|
||||
if (focused() && NEIClientConfig.isKeyHashDown("gui.getprevioussearch")) {
|
||||
if (focused() && KeyManager.isKeyDown("gui.getprevioussearch")) {
|
||||
handleNavigateHistory(TextHistory.Direction.PREVIOUS);
|
||||
}
|
||||
|
||||
if (focused() && NEIClientConfig.isKeyHashDown("gui.getnextsearch")) {
|
||||
if (focused() && KeyManager.isKeyDown("gui.getnextsearch")) {
|
||||
handleNavigateHistory(TextHistory.Direction.NEXT);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -222,7 +222,6 @@ public class SearchField extends TextField implements ItemFilterProvider {
|
||||
public void onTextChange(String oldText) {
|
||||
final String newText = text();
|
||||
if (!newText.equals(oldText)) {
|
||||
if (newText.length() > 0) NEIClientConfig.logger.debug("Searching for " + newText);
|
||||
NEIClientConfig.setSearchExpression(newText);
|
||||
ItemList.updateFilter.restart();
|
||||
}
|
||||
@@ -231,14 +230,14 @@ public class SearchField extends TextField implements ItemFilterProvider {
|
||||
@Override
|
||||
public void lastKeyTyped(int keyID, char keyChar) {
|
||||
|
||||
if (isVisible() && NEIClientConfig.isKeyHashDown("gui.search")) {
|
||||
if (isVisible() && KeyManager.isHashDown("gui.search")) {
|
||||
setFocus(true);
|
||||
}
|
||||
if (focused() && NEIClientConfig.isKeyHashDown("gui.getprevioussearch")) {
|
||||
if (focused() && KeyManager.isKeyDown("gui.getprevioussearch")) {
|
||||
handleNavigateHistory(TextHistory.Direction.PREVIOUS);
|
||||
}
|
||||
|
||||
if (focused() && NEIClientConfig.isKeyHashDown("gui.getnextsearch")) {
|
||||
if (focused() && KeyManager.isKeyDown("gui.getnextsearch")) {
|
||||
handleNavigateHistory(TextHistory.Direction.NEXT);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -111,7 +111,7 @@ public class SearchTokenParser {
|
||||
clearCache();
|
||||
}
|
||||
|
||||
public void clearCache() {
|
||||
public synchronized void clearCache() {
|
||||
this.providersCache.clear();
|
||||
this.filtersCache.clear();
|
||||
this.recipesCache.clear();
|
||||
|
||||
@@ -6,13 +6,9 @@ import java.util.ArrayList;
|
||||
import java.util.Comparator;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.concurrent.locks.Lock;
|
||||
import java.util.concurrent.locks.ReentrantReadWriteLock;
|
||||
import java.util.regex.Pattern;
|
||||
import java.util.stream.Collectors;
|
||||
import java.util.stream.Stream;
|
||||
@@ -22,6 +18,7 @@ import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.nbt.NBTBase;
|
||||
import net.minecraft.nbt.NBTTagCompound;
|
||||
import net.minecraft.nbt.NBTTagList;
|
||||
import net.minecraft.nbt.NBTTagString;
|
||||
import net.minecraft.util.EnumChatFormatting;
|
||||
|
||||
import org.lwjgl.opengl.GL11;
|
||||
@@ -53,9 +50,7 @@ public class SubsetWidget extends Button implements ItemFilterProvider {
|
||||
protected static final int MARGIN = 2;
|
||||
protected static final char PREFIX = '%';
|
||||
|
||||
protected static ReentrantReadWriteLock hiddenItemLock = new ReentrantReadWriteLock();
|
||||
protected static Lock hiddenWriteLock = hiddenItemLock.writeLock();
|
||||
protected static Lock hiddenReadLock = hiddenItemLock.readLock();
|
||||
private static final Object hiddenLock = new Object();
|
||||
|
||||
public static class SubsetTag {
|
||||
|
||||
@@ -377,11 +372,18 @@ public class SubsetWidget extends Button implements ItemFilterProvider {
|
||||
}
|
||||
final AnyMultiItemFilter filter = new AnyMultiItemFilter();
|
||||
final Set<ItemStack> filteredItems = new HashSet<>();
|
||||
final List<SubsetTag> snapshot;
|
||||
|
||||
for (SubsetTag tag : tags.values()) {
|
||||
synchronized (tags) {
|
||||
snapshot = new ArrayList<>(tags.values());
|
||||
}
|
||||
|
||||
for (SubsetTag tag : snapshot) {
|
||||
if (tag.filter != null && matches(tag.path, searchText, pattern)) {
|
||||
filteredItems.addAll(tag.items);
|
||||
filter.filters.add(tag.filter);
|
||||
synchronized (tag.items) {
|
||||
filteredItems.addAll(tag.items);
|
||||
filter.filters.add(tag.filter);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -411,9 +413,11 @@ public class SubsetWidget extends Button implements ItemFilterProvider {
|
||||
}
|
||||
|
||||
/**
|
||||
* All operations on this variable should be synchronised.
|
||||
* Canonical {@link StackInfo#getItemStackGUID(ItemStack)} of every hidden item, stored by GUID so the state
|
||||
* survives world reloads. All operations should be synchronised.
|
||||
*/
|
||||
private static final ItemStackSet hiddenItems = new ItemStackSet();
|
||||
private static final Set<String> hiddenItems = new HashSet<>();
|
||||
|
||||
private static final Map<String, SubsetTag> tags = new HashMap<>();
|
||||
private static final SubsetTag root = new SubsetTag("");
|
||||
protected static boolean enableSearchBySubsets = false;
|
||||
@@ -436,6 +440,7 @@ public class SubsetWidget extends Button implements ItemFilterProvider {
|
||||
}
|
||||
|
||||
updateHiddenItems();
|
||||
SearchField.searchParser.clearCache();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -447,24 +452,19 @@ public class SubsetWidget extends Button implements ItemFilterProvider {
|
||||
parentpath -> parentpath.equals(path.toLowerCase())
|
||||
|| parentpath.startsWith(path.toLowerCase() + "."));
|
||||
updateHiddenItems();
|
||||
SearchField.searchParser.clearCache();
|
||||
}
|
||||
}
|
||||
|
||||
public static boolean isHidden(ItemStack item) {
|
||||
try {
|
||||
if (hiddenReadLock.tryLock(5, TimeUnit.SECONDS)) {
|
||||
try {
|
||||
return hiddenItems.contains(item);
|
||||
} finally {
|
||||
hiddenReadLock.unlock();
|
||||
}
|
||||
} else {
|
||||
NEIClientConfig.logger.error("Unable to obtain read lock in 'isHidden'");
|
||||
}
|
||||
} catch (InterruptedException e) {
|
||||
e.printStackTrace();
|
||||
final String guid = StackInfo.getItemStackGUID(item);
|
||||
synchronized (hiddenLock) {
|
||||
return hiddenItems.contains(guid);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private static List<String> toGUIDs(List<ItemStack> items) {
|
||||
return items.stream().map(StackInfo::getItemStackGUID).collect(Collectors.toList());
|
||||
}
|
||||
|
||||
private static List<ItemStack> getItems(SubsetTag tag, List<ItemStack> items) {
|
||||
@@ -478,90 +478,50 @@ public class SubsetWidget extends Button implements ItemFilterProvider {
|
||||
}
|
||||
|
||||
public static void showOnly(SubsetTag tag) {
|
||||
try {
|
||||
if (hiddenWriteLock.tryLock(5, TimeUnit.SECONDS)) {
|
||||
try {
|
||||
hiddenItems.clear();
|
||||
hiddenItems.addAll(getItems(root, new ArrayList<>()));
|
||||
hiddenItems.removeAll(getItems(tag, new ArrayList<>()));
|
||||
} finally {
|
||||
hiddenWriteLock.unlock();
|
||||
}
|
||||
} else {
|
||||
NEIClientConfig.logger.error("Unable to obtain write lock in 'showOnly'");
|
||||
}
|
||||
final List<String> allItems = toGUIDs(getItems(root, new ArrayList<>()));
|
||||
final List<String> tagItems = toGUIDs(getItems(tag, new ArrayList<>()));
|
||||
|
||||
calculateVisibility();
|
||||
} catch (InterruptedException e) {
|
||||
e.printStackTrace();
|
||||
synchronized (hiddenLock) {
|
||||
hiddenItems.clear();
|
||||
hiddenItems.addAll(allItems);
|
||||
hiddenItems.removeAll(tagItems);
|
||||
}
|
||||
|
||||
calculateVisibility();
|
||||
}
|
||||
|
||||
public static void setHidden(SubsetTag tag, boolean hidden) {
|
||||
try {
|
||||
if (hiddenWriteLock.tryLock(5, TimeUnit.SECONDS)) {
|
||||
try {
|
||||
List<ItemStack> tagItems = getItems(tag, new ArrayList<>());
|
||||
final List<String> tagItems = toGUIDs(getItems(tag, new ArrayList<>()));
|
||||
|
||||
if (hidden) {
|
||||
hiddenItems.addAll(tagItems);
|
||||
} else {
|
||||
hiddenItems.removeAll(tagItems);
|
||||
}
|
||||
|
||||
} finally {
|
||||
hiddenWriteLock.unlock();
|
||||
}
|
||||
synchronized (hiddenLock) {
|
||||
if (hidden) {
|
||||
hiddenItems.addAll(tagItems);
|
||||
} else {
|
||||
NEIClientConfig.logger.error("Unable to obtain write lock in 'setHidden'");
|
||||
hiddenItems.removeAll(tagItems);
|
||||
}
|
||||
|
||||
calculateVisibility();
|
||||
} catch (InterruptedException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
calculateVisibility();
|
||||
}
|
||||
|
||||
public static void setHidden(ItemStack item, boolean hidden) {
|
||||
try {
|
||||
if (hiddenWriteLock.tryLock(5, TimeUnit.SECONDS)) {
|
||||
try {
|
||||
final String guid = StackInfo.getItemStackGUID(item);
|
||||
|
||||
if (hidden) {
|
||||
hiddenItems.add(item);
|
||||
} else {
|
||||
hiddenItems.remove(item);
|
||||
}
|
||||
|
||||
} finally {
|
||||
hiddenWriteLock.unlock();
|
||||
}
|
||||
synchronized (hiddenLock) {
|
||||
if (hidden) {
|
||||
hiddenItems.add(guid);
|
||||
} else {
|
||||
NEIClientConfig.logger.error("Unable to obtain write lock in 'setHidden'");
|
||||
hiddenItems.remove(guid);
|
||||
}
|
||||
|
||||
calculateVisibility();
|
||||
} catch (InterruptedException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
calculateVisibility();
|
||||
}
|
||||
|
||||
public static void unhideAll() {
|
||||
try {
|
||||
if (hiddenWriteLock.tryLock(5, TimeUnit.SECONDS)) {
|
||||
try {
|
||||
hiddenItems.clear();
|
||||
} finally {
|
||||
hiddenWriteLock.unlock();
|
||||
}
|
||||
} else {
|
||||
NEIClientConfig.logger.error("Unable to obtain write lock in 'unhideAll'");
|
||||
}
|
||||
|
||||
calculateVisibility();
|
||||
} catch (InterruptedException e) {
|
||||
e.printStackTrace();
|
||||
synchronized (hiddenLock) {
|
||||
hiddenItems.clear();
|
||||
}
|
||||
calculateVisibility();
|
||||
}
|
||||
|
||||
public static void updateHiddenItems() {
|
||||
@@ -633,42 +593,43 @@ public class SubsetWidget extends Button implements ItemFilterProvider {
|
||||
}
|
||||
|
||||
public static void loadHidden() {
|
||||
final List<ItemStack> itemList = new LinkedList<>();
|
||||
final Set<String> guids = new HashSet<>();
|
||||
|
||||
try {
|
||||
final NBTTagList guidList = NEIClientConfig.world.nbt.getTagList("hiddenItems", 8);
|
||||
|
||||
for (int i = 0; i < guidList.tagCount(); i++) {
|
||||
guids.add(guidList.getStringTagAt(i));
|
||||
}
|
||||
|
||||
final NBTTagList list = NEIClientConfig.world.nbt.getTagList("hiddenItems", 10);
|
||||
|
||||
for (int i = 0; i < list.tagCount(); i++) {
|
||||
itemList.add(ItemStack.loadItemStackFromNBT(list.getCompoundTagAt(i)));
|
||||
final ItemStack stack = ItemStack.loadItemStackFromNBT(list.getCompoundTagAt(i));
|
||||
|
||||
if (stack != null) {
|
||||
guids.add(StackInfo.getItemStackGUID(stack));
|
||||
}
|
||||
}
|
||||
} catch (Exception e) {
|
||||
NEIClientConfig.logger.error("Error loading hiddenItems", e);
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
if (hiddenWriteLock.tryLock(5, TimeUnit.SECONDS)) {
|
||||
try {
|
||||
hiddenItems.clear();
|
||||
hiddenItems.addAll(itemList);
|
||||
} finally {
|
||||
hiddenWriteLock.unlock();
|
||||
}
|
||||
} else {
|
||||
NEIClientConfig.logger.error("Unable to obtain second write lock in 'loadHidden'");
|
||||
}
|
||||
} catch (InterruptedException e) {
|
||||
e.printStackTrace();
|
||||
synchronized (hiddenLock) {
|
||||
hiddenItems.clear();
|
||||
hiddenItems.addAll(guids);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public static void saveHidden() {
|
||||
if (NEIClientConfig.world == null) return;
|
||||
|
||||
final NBTTagList list = new NBTTagList();
|
||||
for (ItemStack stack : hiddenItems.values()) {
|
||||
list.appendTag(stack.writeToNBT(new NBTTagCompound()));
|
||||
synchronized (hiddenLock) {
|
||||
for (String guid : hiddenItems) {
|
||||
list.appendTag(new NBTTagString(guid));
|
||||
}
|
||||
}
|
||||
|
||||
NEIClientConfig.world.nbt.setTag("hiddenItems", list);
|
||||
@@ -686,14 +647,22 @@ public class SubsetWidget extends Button implements ItemFilterProvider {
|
||||
public void execute() {
|
||||
|
||||
try {
|
||||
final List<SubsetTag> list = new ArrayList<>(tags.values());
|
||||
final List<SubsetTag> list;
|
||||
|
||||
synchronized (tags) {
|
||||
list = new ArrayList<>(tags.values());
|
||||
}
|
||||
|
||||
root.clearCache();
|
||||
|
||||
list.parallelStream().forEach(tag -> {
|
||||
tag.clearCache();
|
||||
ItemList.items.stream().filter(tag.filter::matches)
|
||||
.collect(Collectors.toCollection(() -> tag.items));
|
||||
|
||||
if (!(tag.filter instanceof NothingItemFilter)) {
|
||||
ItemList.items.stream().filter(tag.filter::matches)
|
||||
.collect(Collectors.toCollection(() -> tag.items));
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
for (SubsetTag tag : list) {
|
||||
@@ -729,6 +698,7 @@ public class SubsetWidget extends Button implements ItemFilterProvider {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
SearchField.searchParser.clearCache();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -740,20 +710,17 @@ public class SubsetWidget extends Button implements ItemFilterProvider {
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getRenderLabel() {
|
||||
public int getRenderLabelColor() {
|
||||
return NEIClientConfig.subsetWidgetOnTop() ? 0 : ColorUtils.subsetWidget.getColor();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getRenderLabel() {
|
||||
if (NEIClientConfig.subsetWidgetOnTop()) {
|
||||
return NEIClientUtils.translate("inventory.item_subsets");
|
||||
} else {
|
||||
final String translated = NEIClientUtils.translate("gui.button.label.subset");
|
||||
if (!translated.startsWith("nei.")) { // Optional localization string for resource packs
|
||||
return translated;
|
||||
}
|
||||
|
||||
return EnumChatFormatting.DARK_PURPLE + String.valueOf(SearchField.searchParser.getRedefinedPrefix(PREFIX))
|
||||
+ EnumChatFormatting.RESET;
|
||||
return String.valueOf(SearchField.searchParser.getRedefinedPrefix(PREFIX));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -1,5 +1,13 @@
|
||||
package codechicken.nei;
|
||||
|
||||
import java.lang.invoke.MethodHandle;
|
||||
import java.lang.invoke.MethodHandles;
|
||||
import java.lang.reflect.Field;
|
||||
import java.lang.reflect.Method;
|
||||
import java.util.concurrent.Callable;
|
||||
|
||||
import net.minecraft.block.Block;
|
||||
import net.minecraft.block.BlockSnow;
|
||||
import net.minecraft.client.Minecraft;
|
||||
import net.minecraft.client.renderer.Tessellator;
|
||||
import net.minecraft.entity.Entity;
|
||||
@@ -26,24 +34,23 @@ public class WorldOverlayRenderer implements IKeyStateTracker {
|
||||
public static int mobOverlay = 0;
|
||||
private static byte[] mobSpawnCache;
|
||||
private static long mobOverlayUpdateTime;
|
||||
private static String oregenPatternName;
|
||||
|
||||
public static void reset() {
|
||||
mobOverlay = 0;
|
||||
chunkOverlay = 0;
|
||||
oregenPatternName = null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void tickKeyStates() {
|
||||
if (Minecraft.getMinecraft().currentScreen != null) return;
|
||||
|
||||
if (KeyManager.keyStates.get("world.moboverlay").down) {
|
||||
if (KeyManager.isPressed("world.moboverlay")) {
|
||||
mobOverlay = (mobOverlay + 1) % 2;
|
||||
NEIClientUtils
|
||||
.printChatMessage(new ChatComponentText(NEIClientUtils.translate("chat.moboverlay." + mobOverlay)));
|
||||
}
|
||||
if (KeyManager.keyStates.get("world.chunkoverlay").down) {
|
||||
|
||||
if (KeyManager.isPressed("world.chunkoverlay")) {
|
||||
chunkOverlay = (chunkOverlay + 1) % (NEIModContainer.isGT5Loaded() ? 4 : 3);
|
||||
// 0-2 (or 3 with gt)
|
||||
NEIClientUtils.printChatMessage(
|
||||
@@ -53,6 +60,7 @@ public class WorldOverlayRenderer implements IKeyStateTracker {
|
||||
}
|
||||
|
||||
public static void render(float frame) {
|
||||
GL11.glPushAttrib(GL11.GL_ENABLE_BIT | GL11.GL_COLOR_BUFFER_BIT | GL11.GL_DEPTH_BUFFER_BIT | GL11.GL_LINE_BIT);
|
||||
GL11.glPushMatrix();
|
||||
Entity entity = Minecraft.getMinecraft().renderViewEntity;
|
||||
|
||||
@@ -66,9 +74,12 @@ public class WorldOverlayRenderer implements IKeyStateTracker {
|
||||
|
||||
GL11.glTranslated(-interpPosX + intOffsetX, -interpPosY + intOffsetY, -interpPosZ + intOffsetZ);
|
||||
|
||||
GL11.glEnable(GL11.GL_DEPTH_TEST);
|
||||
GL11.glDepthFunc(GL11.GL_LEQUAL);
|
||||
renderChunkBounds(entity, intOffsetX, intOffsetY, intOffsetZ);
|
||||
renderMobSpawnOverlay(entity, intOffsetX, intOffsetY, intOffsetZ);
|
||||
GL11.glPopMatrix();
|
||||
GL11.glPopAttrib();
|
||||
}
|
||||
|
||||
private static void buildMobSpawnOverlay(Entity entity) {
|
||||
@@ -116,6 +127,15 @@ public class WorldOverlayRenderer implements IKeyStateTracker {
|
||||
}
|
||||
}
|
||||
|
||||
private static double getOverlayYOffset(World world, int x, int y, int z) {
|
||||
Block block = world.getBlock(x, y, z);
|
||||
if (block instanceof BlockSnow) {
|
||||
int meta = world.getBlockMetadata(x, y, z) & 7;
|
||||
return (1 + meta) / 8.0 + 0.02;
|
||||
}
|
||||
return 0.02;
|
||||
}
|
||||
|
||||
private static void renderMobSpawnOverlay(Entity entity, int intOffsetX, int intOffsetY, int intOffsetZ) {
|
||||
if (mobOverlay == 0) {
|
||||
if (mobSpawnCache != null) {
|
||||
@@ -171,10 +191,12 @@ public class WorldOverlayRenderer implements IKeyStateTracker {
|
||||
curSpawnMode = spawnMode;
|
||||
}
|
||||
|
||||
tess.addVertex(x, y + 0.02, z);
|
||||
tess.addVertex(x + 1, y + 0.02, z + 1);
|
||||
tess.addVertex(x + 1, y + 0.02, z);
|
||||
tess.addVertex(x, y + 0.02, z + 1);
|
||||
double yOff = getOverlayYOffset(world, x + intOffsetX, y + intOffsetY, z + intOffsetZ);
|
||||
|
||||
tess.addVertex(x, y + yOff, z);
|
||||
tess.addVertex(x + 1, y + yOff, z + 1);
|
||||
tess.addVertex(x + 1, y + yOff, z);
|
||||
tess.addVertex(x, y + yOff, z + 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -215,6 +237,9 @@ public class WorldOverlayRenderer implements IKeyStateTracker {
|
||||
private static void renderChunkBounds(Entity entity, int intOffsetX, int intOffsetY, int intOffsetZ) {
|
||||
if (chunkOverlay == 0) return;
|
||||
|
||||
int worldMinY = worldMinHeight(entity.worldObj);
|
||||
int worldMaxY = worldMaxHeight(entity.worldObj);
|
||||
|
||||
GL11.glDisable(GL11.GL_TEXTURE_2D);
|
||||
GL11.glEnable(GL11.GL_BLEND);
|
||||
GL11.glBlendFunc(GL11.GL_SRC_ALPHA, GL11.GL_ONE_MINUS_SRC_ALPHA);
|
||||
@@ -233,14 +258,13 @@ public class WorldOverlayRenderer implements IKeyStateTracker {
|
||||
double dy = 128;
|
||||
double y1 = Math.floor(entity.posY - dy / 2);
|
||||
double y2 = y1 + dy;
|
||||
if (y1 < 0) {
|
||||
y1 = 0;
|
||||
y2 = dy;
|
||||
if (y1 < worldMinY) {
|
||||
y1 = worldMinY;
|
||||
y2 = worldMinY + dy;
|
||||
}
|
||||
|
||||
if (y1 > entity.worldObj.getHeight()) {
|
||||
y2 = entity.worldObj.getHeight();
|
||||
y1 = y2 - dy;
|
||||
if (y2 > worldMaxY) {
|
||||
y2 = worldMaxY;
|
||||
y1 = Math.max(worldMaxY - dy, worldMinY);
|
||||
}
|
||||
|
||||
y1 -= intOffsetY;
|
||||
@@ -266,19 +290,34 @@ public class WorldOverlayRenderer implements IKeyStateTracker {
|
||||
tess.addVertex(x1, y2, z1);
|
||||
}
|
||||
|
||||
if (NEIModContainer.isCCLoaded()) {
|
||||
tess.setColorRGBA_F(0, 0.5F, 0.9F, (float) dist * 0.5F);
|
||||
int cubeBase = (int) Math.floor((y1 + intOffsetY) / 16.0) * 16;
|
||||
for (int cubeY = cubeBase; cubeY <= y2 + intOffsetY; cubeY += 16) {
|
||||
double ry = cubeY - intOffsetY;
|
||||
tess.addVertex(x1, ry, z1);
|
||||
tess.addVertex(x2, ry, z1);
|
||||
tess.addVertex(x1, ry, z2);
|
||||
tess.addVertex(x2, ry, z2);
|
||||
tess.addVertex(x1, ry, z1);
|
||||
tess.addVertex(x1, ry, z2);
|
||||
tess.addVertex(x2, ry, z1);
|
||||
tess.addVertex(x2, ry, z2);
|
||||
}
|
||||
}
|
||||
|
||||
if (cx == 0 && cz == 0) {
|
||||
if (chunkOverlay == 2) {
|
||||
dy = 32;
|
||||
y1 = Math.floor(entity.posY - dy / 2);
|
||||
y2 = y1 + dy;
|
||||
if (y1 < 0) {
|
||||
y1 = 0;
|
||||
y2 = dy;
|
||||
if (y1 < worldMinY) {
|
||||
y1 = worldMinY;
|
||||
y2 = worldMinY + dy;
|
||||
}
|
||||
|
||||
if (y1 > entity.worldObj.getHeight()) {
|
||||
y2 = entity.worldObj.getHeight();
|
||||
y1 = y2 - dy;
|
||||
if (y2 > worldMaxY) {
|
||||
y2 = worldMaxY;
|
||||
y1 = Math.max(worldMaxY - dy, worldMinY);
|
||||
}
|
||||
|
||||
y1 -= intOffsetY;
|
||||
@@ -377,20 +416,75 @@ public class WorldOverlayRenderer implements IKeyStateTracker {
|
||||
GL11.glDisable(GL11.GL_BLEND);
|
||||
}
|
||||
|
||||
private static String getOregenPatternName() {
|
||||
/** Holder defers class loading until Cubic Chunks is confirmed present. */
|
||||
private static final class CCWorldBounds {
|
||||
|
||||
if (oregenPatternName == null) {
|
||||
static final MethodHandle GET_MIN_HEIGHT;
|
||||
static final MethodHandle GET_MAX_HEIGHT;
|
||||
|
||||
static {
|
||||
try {
|
||||
final ClassLoader loader = WorldOverlayRenderer.class.getClassLoader();
|
||||
final Class<?> gtWorldGenerator = ReflectionHelper
|
||||
.getClass(loader, "gregtech.common.GTWorldgenerator", "gregtech.common.GT_Worldgenerator");
|
||||
oregenPatternName = ((Enum<?>) gtWorldGenerator.getDeclaredField("oregenPattern").get(null)).name();
|
||||
} catch (Exception ignored) {
|
||||
oregenPatternName = "AXISSYMMETRICAL";
|
||||
MethodHandles.Lookup lookup = MethodHandles.lookup();
|
||||
// Mixined into World by CC, use reflection + MethodHandles to call these
|
||||
GET_MIN_HEIGHT = lookup.unreflect(World.class.getMethod("getMinHeight"));
|
||||
GET_MAX_HEIGHT = lookup.unreflect(World.class.getMethod("getMaxHeight"));
|
||||
} catch (ReflectiveOperationException e) {
|
||||
throw new ExceptionInInitializerError(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return oregenPatternName;
|
||||
private static int worldMinHeight(World world) {
|
||||
if (!NEIModContainer.isCCLoaded()) return 0;
|
||||
try {
|
||||
return (int) CCWorldBounds.GET_MIN_HEIGHT.invoke(world);
|
||||
} catch (Throwable ignored) {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
private static int worldMaxHeight(World world) {
|
||||
if (!NEIModContainer.isCCLoaded()) return world.getHeight();
|
||||
try {
|
||||
return (int) CCWorldBounds.GET_MAX_HEIGHT.invoke(world);
|
||||
} catch (Throwable ignored) {
|
||||
return world.getHeight();
|
||||
}
|
||||
}
|
||||
|
||||
private static Callable<String> oregenPatternReader;
|
||||
|
||||
private static String getOregenPatternName() {
|
||||
if (oregenPatternReader == null) {
|
||||
oregenPatternReader = resolveOregenPatternReader();
|
||||
}
|
||||
try {
|
||||
return oregenPatternReader.call();
|
||||
} catch (Exception ignored) {
|
||||
return "AXISSYMMETRICAL";
|
||||
}
|
||||
}
|
||||
|
||||
private static Callable<String> resolveOregenPatternReader() {
|
||||
try {
|
||||
final Class<?> gtWorldGenerator = ReflectionHelper.getClass(
|
||||
WorldOverlayRenderer.class.getClassLoader(),
|
||||
"gregtech.common.GTWorldgenerator",
|
||||
"gregtech.common.GT_Worldgenerator");
|
||||
|
||||
try {
|
||||
// GT5-Unofficial >= 5.09.54.29 support
|
||||
final Method accessor = gtWorldGenerator.getMethod("getOregenPattern");
|
||||
return () -> ((Enum<?>) accessor.invoke(null)).name();
|
||||
} catch (NoSuchMethodException legacy) {
|
||||
// Older GT
|
||||
final Field oregenPattern = gtWorldGenerator.getDeclaredField("oregenPattern");
|
||||
oregenPattern.setAccessible(true);
|
||||
return () -> ((Enum<?>) oregenPattern.get(null)).name();
|
||||
}
|
||||
} catch (Exception ignored) {
|
||||
return () -> "AXISSYMMETRICAL";
|
||||
}
|
||||
}
|
||||
|
||||
public static void load() {
|
||||
|
||||
@@ -1,9 +1,11 @@
|
||||
package codechicken.nei.api;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.Comparator;
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import net.minecraft.block.Block;
|
||||
import net.minecraft.client.gui.inventory.GuiContainer;
|
||||
@@ -20,7 +22,6 @@ import codechicken.nei.ItemList;
|
||||
import codechicken.nei.ItemSorter;
|
||||
import codechicken.nei.ItemStackSet;
|
||||
import codechicken.nei.KeyManager;
|
||||
import codechicken.nei.KeyManager.KeyState;
|
||||
import codechicken.nei.LayoutManager;
|
||||
import codechicken.nei.NEIClientConfig;
|
||||
import codechicken.nei.OffsetPositioner;
|
||||
@@ -32,7 +33,6 @@ import codechicken.nei.SubsetWidget.SubsetTag;
|
||||
import codechicken.nei.api.IRecipeFilter.IRecipeFilterProvider;
|
||||
import codechicken.nei.api.ItemFilter.ItemFilterProvider;
|
||||
import codechicken.nei.config.Option;
|
||||
import codechicken.nei.config.OptionKeyBind;
|
||||
import codechicken.nei.recipe.CatalystInfo;
|
||||
import codechicken.nei.recipe.GuiCraftingRecipe;
|
||||
import codechicken.nei.recipe.GuiRecipe;
|
||||
@@ -176,6 +176,21 @@ public class API {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Add an alias name that this item can be found by in the search field, in addition to its display name.
|
||||
*/
|
||||
public static void setAliases(ItemStack item, String... aliases) {
|
||||
final List<String> list = Arrays.asList(aliases).stream().filter(Objects::nonNull).map(String::trim)
|
||||
.filter(s -> !s.isEmpty()).collect(Collectors.toList());
|
||||
|
||||
if (list.isEmpty()) {
|
||||
ItemInfo.itemAliases.remove(item);
|
||||
} else {
|
||||
ItemInfo.itemAliases.put(item, list);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds an item to the item panel. Any items added using this function will override the default search pattern.
|
||||
*
|
||||
@@ -206,20 +221,12 @@ public class API {
|
||||
* @param defaultKey The default value, commonly obtained from {@link Keyboard}
|
||||
*/
|
||||
public static void addKeyBind(String ident, int defaultKey) {
|
||||
NEIClientConfig.setDefaultKeyBinding(ident, defaultKey);
|
||||
KeyManager.keyStates.put(ident, new KeyState());
|
||||
addOption(new OptionKeyBind(ident));
|
||||
KeyManager.registerKeyBinding(ident, defaultKey);
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a custom KeyBinding to be configured in the Controls menu.
|
||||
*
|
||||
* @param ident An identifier for your key, eg "shoot"
|
||||
* @param defaultKey The default value, commonly obtained from {@link Keyboard}
|
||||
*/
|
||||
@Deprecated
|
||||
public static void addHashBind(String ident, int defaultKey) {
|
||||
NEIClientConfig.setDefaultKeyBinding(ident, defaultKey);
|
||||
addOption(new OptionKeyBind(ident, true));
|
||||
KeyManager.registerKeyBinding(ident, defaultKey);
|
||||
}
|
||||
|
||||
public static void addOption(Option option) {
|
||||
|
||||
@@ -8,6 +8,7 @@ import java.util.stream.Collectors;
|
||||
import net.minecraft.client.gui.inventory.GuiContainer;
|
||||
import net.minecraft.item.ItemStack;
|
||||
|
||||
import codechicken.nei.NEIClientConfig;
|
||||
import codechicken.nei.PositionedStack;
|
||||
import codechicken.nei.recipe.GuiOverlayButton.ItemOverlayState;
|
||||
import codechicken.nei.recipe.IRecipeHandler;
|
||||
@@ -32,6 +33,10 @@ public interface IOverlayHandler {
|
||||
return false;
|
||||
}
|
||||
|
||||
default boolean requireShiftForOverlayRecipe() {
|
||||
return NEIClientConfig.requireShiftForOverlayRecipe();
|
||||
}
|
||||
|
||||
default List<ItemOverlayState> presenceOverlay(GuiContainer firstGui, IRecipeHandler recipe, int recipeIndex) {
|
||||
final List<ItemOverlayState> itemPresenceSlots = new ArrayList<>();
|
||||
final List<PositionedStack> ingredients = recipe.getIngredientStacks(recipeIndex);
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
package codechicken.nei.api;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.LinkedList;
|
||||
@@ -84,6 +85,7 @@ public class ItemInfo {
|
||||
|
||||
public static final ArrayListMultimap<Layout, IHighlightHandler> highlightHandlers = ArrayListMultimap.create();
|
||||
public static final ItemStackMap<String> nameOverrides = new ItemStackMap<>();
|
||||
public static final ItemStackMap<List<String>> itemAliases = new ItemStackMap<>();
|
||||
public static final ItemStackSet hiddenItems = new ItemStackSet();
|
||||
public static final AnyMultiItemFilter hiddenItemsRules = new AnyMultiItemFilter();
|
||||
public static final ItemStackSet finiteItems = new ItemStackSet();
|
||||
@@ -109,6 +111,11 @@ public class ItemInfo {
|
||||
return nameOverrides.get(stack);
|
||||
}
|
||||
|
||||
public static List<String> getAliases(ItemStack stack) {
|
||||
final List<String> aliases = itemAliases.get(stack);
|
||||
return aliases != null ? aliases : Collections.emptyList();
|
||||
}
|
||||
|
||||
public static boolean canBeInfinite(ItemStack stack) {
|
||||
return !finiteItems.contains(stack);
|
||||
}
|
||||
|
||||
@@ -5,6 +5,7 @@ import java.util.LinkedList;
|
||||
import net.minecraft.world.World;
|
||||
|
||||
import codechicken.nei.NEIClientConfig;
|
||||
import codechicken.nei.config.GuiOptionList;
|
||||
import codechicken.nei.config.OptionCycled;
|
||||
|
||||
public class NEIInfo {
|
||||
@@ -13,7 +14,8 @@ public class NEIInfo {
|
||||
|
||||
public static void load(World world) {
|
||||
OptionCycled modeOption = (OptionCycled) NEIClientConfig.getOptionList().getOption("inventory.cheatmode");
|
||||
modeOption.parent.synthesizeEnvironment(false);
|
||||
// kept alive so the WeakReference in Option.slotRef isn't GC'd before copyGlobals/cycle use it
|
||||
GuiOptionList env = modeOption.parent.synthesizeEnvironment(false);
|
||||
if (!modeOption.optionValid(modeOption.value())) {
|
||||
modeOption.copyGlobals();
|
||||
modeOption.cycle();
|
||||
|
||||
@@ -20,14 +20,17 @@ import codechicken.nei.FavoriteRecipes;
|
||||
import codechicken.nei.ItemPanels;
|
||||
import codechicken.nei.ItemQuantityField;
|
||||
import codechicken.nei.ItemsGrid.ItemsGridSlot;
|
||||
import codechicken.nei.KeyManager;
|
||||
import codechicken.nei.LayoutManager;
|
||||
import codechicken.nei.NEIClientConfig;
|
||||
import codechicken.nei.NEIClientUtils;
|
||||
import codechicken.nei.PositionedStack;
|
||||
import codechicken.nei.SearchField;
|
||||
import codechicken.nei.bookmark.BookmarkGrid;
|
||||
import codechicken.nei.bookmark.BookmarkGroup;
|
||||
import codechicken.nei.bookmark.BookmarkItem;
|
||||
import codechicken.nei.bookmark.BookmarkItem.BookmarkItemType;
|
||||
import codechicken.nei.bookmark.BookmarkPayload;
|
||||
import codechicken.nei.bookmark.BookmarksGridSlot;
|
||||
import codechicken.nei.recipe.AutoCraftingManager;
|
||||
import codechicken.nei.recipe.GuiCraftingRecipe;
|
||||
@@ -74,8 +77,7 @@ public abstract class ShortcutInputHandler {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (NEIClientConfig.isKeyHashDown("gui.overlay") && stackover == null
|
||||
&& LayoutManager.overlayRenderer != null) {
|
||||
if (KeyManager.isKeyDown("gui.overlay") && stackover == null && LayoutManager.overlayRenderer != null) {
|
||||
LayoutManager.overlayRenderer = null;
|
||||
return true;
|
||||
}
|
||||
@@ -85,16 +87,21 @@ public abstract class ShortcutInputHandler {
|
||||
|
||||
if (groupId != -1) {
|
||||
|
||||
if (NEIClientConfig.isKeyHashDown("gui.remove_recipe")) {
|
||||
if (KeyManager.isHashDown("bookmark.remove_recipe", NEIClientUtils.SHIFT_HASH)) {
|
||||
ItemPanels.bookmarkPanel.removeGroup(groupId);
|
||||
return true;
|
||||
}
|
||||
|
||||
if (NEIClientConfig.isKeyHashDown("gui.bookmark_pull_items")) {
|
||||
if (KeyManager.isKeyDown("bookmark.pull_items")) {
|
||||
return ItemPanels.bookmarkPanel.pullBookmarkItems(groupId, NEIClientUtils.shiftKey());
|
||||
}
|
||||
|
||||
if (NEIClientConfig.autocraftingEnabled() && NEIClientConfig.isKeyHashDown("gui.craft_items")
|
||||
if (KeyManager.isKeyDown("bookmark.chat_link") && NEIClientUtils.controlKey()) {
|
||||
NEIClientUtils.sendChatItemLink(BookmarkPayload.of(groupId).toNBT());
|
||||
return true;
|
||||
}
|
||||
|
||||
if (NEIClientConfig.autocraftingEnabled() && KeyManager.isKeyDown("gui.craft_items")
|
||||
&& NEIClientUtils.shiftKey()
|
||||
&& ItemPanels.bookmarkPanel.getGrid().isCraftingMode(groupId)) {
|
||||
final RecipeChainMath math = ItemPanels.bookmarkPanel.getGrid().createRecipeChainMath(groupId);
|
||||
@@ -117,46 +124,47 @@ public abstract class ShortcutInputHandler {
|
||||
|
||||
stackover = stackover.copy();
|
||||
|
||||
if (NEIClientConfig.isKeyHashDown("gui.overlay")) {
|
||||
if (KeyManager.isKeyDown("gui.overlay")) {
|
||||
return openOverlayRecipe(stackover);
|
||||
}
|
||||
|
||||
if (NEIClientConfig.isKeyHashDown("gui.copy_name")) {
|
||||
if (KeyManager.isHashDown("copy.name", NEIClientUtils.CTRL_HASH)) {
|
||||
return copyItemStackName(stackover);
|
||||
}
|
||||
if (NEIClientConfig.isKeyHashDown("gui.copy_id")) {
|
||||
|
||||
if (KeyManager.isHashDown("copy.identifier", NEIClientUtils.CTRL_HASH)) {
|
||||
return copyItemStackID(stackover);
|
||||
}
|
||||
|
||||
if (NEIClientConfig.isKeyHashDown("gui.copy_oredict")) {
|
||||
if (KeyManager.isHashDown("copy.oredict", NEIClientUtils.CTRL_HASH)) {
|
||||
return copyItemStackOreDictionary(stackover);
|
||||
}
|
||||
|
||||
if (NEIClientConfig.isKeyHashDown("gui.chat_link_item")) {
|
||||
return sendItemStackChatLink(stackover);
|
||||
if (KeyManager.isKeyDown("bookmark.chat_link") && NEIClientUtils.controlKey()) {
|
||||
return sendRecipeInChatLink(stackover, NEIClientUtils.shiftKey());
|
||||
}
|
||||
|
||||
if (NEIClientConfig.isKeyHashDown("gui.recipe")) {
|
||||
if (KeyManager.isKeyDown("recipe.recipe")) {
|
||||
return GuiCraftingRecipe.openRecipeGui("item", stackover);
|
||||
}
|
||||
|
||||
if (NEIClientConfig.isKeyHashDown("gui.usage")) {
|
||||
if (KeyManager.isKeyDown("recipe.usage")) {
|
||||
return GuiUsageRecipe.openRecipeGui("item", stackover);
|
||||
}
|
||||
|
||||
if (NEIClientConfig.isKeyHashDown("gui.favorite")) {
|
||||
if (KeyManager.isHashDown("bookmark.favorite", NEIClientUtils.SHIFT_HASH)) {
|
||||
return saveFavoriteTree(stackover);
|
||||
}
|
||||
|
||||
if (NEIClientConfig.isKeyHashDown("gui.bookmark")) {
|
||||
if (KeyManager.isKeyDown("bookmark.add")) {
|
||||
return saveRecipeInBookmark(stackover, NEIClientUtils.shiftKey(), NEIClientUtils.controlKey());
|
||||
}
|
||||
|
||||
if (NEIClientConfig.isKeyHashDown("gui.bookmark_pull_items")) {
|
||||
if (KeyManager.isKeyDown("bookmark.pull_items")) {
|
||||
return pullRecipeItems(stackover, NEIClientUtils.shiftKey());
|
||||
}
|
||||
|
||||
if (NEIClientConfig.autocraftingEnabled() && NEIClientConfig.isKeyHashDown("gui.craft_items")
|
||||
if (NEIClientConfig.autocraftingEnabled() && KeyManager.isKeyDown("gui.craft_items")
|
||||
&& NEIClientUtils.shiftKey()) {
|
||||
return runAutoCrafting(stackover, !NEIClientUtils.controlKey());
|
||||
}
|
||||
@@ -196,10 +204,37 @@ public abstract class ShortcutInputHandler {
|
||||
return true;
|
||||
}
|
||||
|
||||
private static boolean sendItemStackChatLink(ItemStack stackover) {
|
||||
if (stackover == null) return false;
|
||||
private static boolean sendRecipeInChatLink(ItemStack stackover, boolean saveIngredients) {
|
||||
final Point mousePos = GuiDraw.getMousePosition();
|
||||
final BookmarksGridSlot slot = ItemPanels.bookmarkPanel.getSlotMouseOver(mousePos.x, mousePos.y);
|
||||
|
||||
NEIClientUtils.sendChatItemLink(stackover); // I wish clients could just send formatted messages
|
||||
if (slot != null && saveIngredients && slot.getType() == BookmarkItemType.RESULT) {
|
||||
NEIClientUtils.sendChatItemLink(BookmarkPayload.of(slot.getBookmarkItem()).toNBT());
|
||||
return true;
|
||||
}
|
||||
|
||||
final Recipe recipe = getFocusedRecipe(stackover, mousePos.x, mousePos.y, saveIngredients);
|
||||
|
||||
if (recipe != null && saveIngredients) {
|
||||
NEIClientUtils.sendChatItemLink(BookmarkPayload.of(recipe).toNBT());
|
||||
return true;
|
||||
}
|
||||
|
||||
final RecipeId recipeId;
|
||||
|
||||
if (slot != null) {
|
||||
recipeId = slot.getType() == BookmarkItemType.INGREDIENT ? null : slot.getRecipeId();
|
||||
} else {
|
||||
recipeId = recipe != null ? recipe.getRecipeId() : null;
|
||||
}
|
||||
|
||||
final boolean existsRecipe = NEIClientConfig.getBooleanSetting("inventory.bookmarks.bookmarkItemsWithRecipe");
|
||||
|
||||
if (ItemPanels.itemPanel.containsWithSubpanels(mousePos.x, mousePos.y)) {
|
||||
stackover = ItemQuantityField.prepareStackWithQuantity(stackover, 0);
|
||||
}
|
||||
|
||||
NEIClientUtils.sendChatItemLink(BookmarkPayload.of(stackover, existsRecipe ? recipeId : null).toNBT());
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -444,15 +479,19 @@ public abstract class ShortcutInputHandler {
|
||||
if (groupId != -1) {
|
||||
|
||||
hotkeys.put(
|
||||
NEIClientConfig.getKeyName("gui.remove_recipe"),
|
||||
KeyManager.getKeyName("bookmark.remove_recipe", NEIClientUtils.SHIFT_HASH),
|
||||
NEIClientUtils.translate("bookmark.group.remove_recipe"));
|
||||
|
||||
hotkeys.put(
|
||||
KeyManager.getKeyName("bookmark.chat_link", NEIClientUtils.CTRL_HASH),
|
||||
NEIClientUtils.translate("bookmark.group.chat_link"));
|
||||
|
||||
if (BookmarkContainerInfo.getBookmarkContainerHandler(gui) != null) {
|
||||
hotkeys.put(
|
||||
NEIClientConfig.getKeyName("gui.bookmark_pull_items"),
|
||||
KeyManager.getKeyName("bookmark.pull_items"),
|
||||
NEIClientUtils.translate("bookmark.group.pull_items"));
|
||||
hotkeys.put(
|
||||
NEIClientConfig.getKeyName("gui.bookmark_pull_items", NEIClientUtils.SHIFT_HASH),
|
||||
KeyManager.getKeyName("bookmark.pull_items", NEIClientUtils.SHIFT_HASH),
|
||||
NEIClientUtils.translate("bookmark.group.pull_items_shift"));
|
||||
}
|
||||
|
||||
@@ -462,7 +501,7 @@ public abstract class ShortcutInputHandler {
|
||||
.getKeyName("gui.craft_items", NEIClientUtils.SHIFT_HASH + NEIClientUtils.CTRL_HASH),
|
||||
NEIClientUtils.translate("bookmark.group.craft_missing"));
|
||||
hotkeys.put(
|
||||
NEIClientConfig.getKeyName("gui.craft_items", NEIClientUtils.SHIFT_HASH),
|
||||
KeyManager.getKeyName("gui.craft_items", NEIClientUtils.SHIFT_HASH),
|
||||
NEIClientUtils.translate("bookmark.group.craft_all"));
|
||||
}
|
||||
|
||||
@@ -483,30 +522,28 @@ public abstract class ShortcutInputHandler {
|
||||
|
||||
if (group.crafting != null && group.collapsed) {
|
||||
hotkeys.put(
|
||||
NEIClientConfig.getKeyName("gui.bookmark", NEIClientUtils.SHIFT_HASH),
|
||||
KeyManager.getKeyName("bookmark.add", NEIClientUtils.SHIFT_HASH),
|
||||
NEIClientUtils.translate("bookmark.group.remove_recipe"));
|
||||
} else if (slot.getRecipeId() == null || slot.getType() == BookmarkItemType.ITEM) {
|
||||
hotkeys.put(
|
||||
NEIClientConfig.getKeyName("gui.bookmark"),
|
||||
NEIClientUtils.translate("bookmark.remove_item"));
|
||||
hotkeys.put(KeyManager.getKeyName("bookmark.add"), NEIClientUtils.translate("bookmark.remove_item"));
|
||||
} else if (group.crafting != null && group.crafting.recipeRelations.entrySet().stream().anyMatch(
|
||||
entry -> entry.getKey().equals(slot.getRecipeId())
|
||||
|| entry.getValue().contains(slot.getRecipeId()))) {
|
||||
hotkeys.put(
|
||||
NEIClientConfig.getKeyName("gui.bookmark", NEIClientUtils.SHIFT_HASH),
|
||||
KeyManager.getKeyName("bookmark.add", NEIClientUtils.SHIFT_HASH),
|
||||
NEIClientUtils.translate("bookmark.remove_recipe"));
|
||||
} else {
|
||||
hotkeys.put(
|
||||
NEIClientConfig.getKeyName("gui.bookmark", NEIClientUtils.SHIFT_HASH),
|
||||
KeyManager.getKeyName("bookmark.add", NEIClientUtils.SHIFT_HASH),
|
||||
NEIClientUtils.translate("bookmark.remove_recipe"));
|
||||
|
||||
if (slot.getType() == BookmarkItemType.INGREDIENT) {
|
||||
hotkeys.put(
|
||||
NEIClientConfig.getKeyName("gui.bookmark"),
|
||||
KeyManager.getKeyName("bookmark.add"),
|
||||
NEIClientUtils.translate("bookmark.remove_item"));
|
||||
|
||||
hotkeys.put(
|
||||
NEIClientConfig.getKeyName("gui.bookmark", NEIClientUtils.SHIFT_HASH),
|
||||
KeyManager.getKeyName("bookmark.add", NEIClientUtils.SHIFT_HASH),
|
||||
NEIClientUtils.translate("bookmark.remove_recipe"));
|
||||
} else {
|
||||
final BookmarkItem item = slot.getBookmarkItem();
|
||||
@@ -516,14 +553,14 @@ public abstract class ShortcutInputHandler {
|
||||
m -> m.type == BookmarkItemType.RESULT && !m.equals(item)
|
||||
&& item.equalsRecipe(m))) {
|
||||
hotkeys.put(
|
||||
NEIClientConfig.getKeyName("gui.bookmark"),
|
||||
KeyManager.getKeyName("bookmark.add"),
|
||||
NEIClientUtils.translate("bookmark.remove_recipe"));
|
||||
} else {
|
||||
hotkeys.put(
|
||||
NEIClientConfig.getKeyName("gui.bookmark"),
|
||||
KeyManager.getKeyName("bookmark.add"),
|
||||
NEIClientUtils.translate("bookmark.remove_item"));
|
||||
hotkeys.put(
|
||||
NEIClientConfig.getKeyName("gui.bookmark", NEIClientUtils.SHIFT_HASH),
|
||||
KeyManager.getKeyName("bookmark.add", NEIClientUtils.SHIFT_HASH),
|
||||
NEIClientUtils.translate("bookmark.remove_recipe"));
|
||||
}
|
||||
|
||||
@@ -533,58 +570,67 @@ public abstract class ShortcutInputHandler {
|
||||
|
||||
if (BookmarkContainerInfo.getBookmarkContainerHandler(gui) != null) {
|
||||
hotkeys.put(
|
||||
NEIClientConfig.getKeyName("gui.bookmark_pull_items"),
|
||||
KeyManager.getKeyName("bookmark.pull_items"),
|
||||
NEIClientUtils.translate("bookmark.group.pull_items"));
|
||||
hotkeys.put(
|
||||
NEIClientConfig.getKeyName("gui.bookmark_pull_items", NEIClientUtils.SHIFT_HASH),
|
||||
KeyManager.getKeyName("bookmark.pull_items", NEIClientUtils.SHIFT_HASH),
|
||||
NEIClientUtils.translate("bookmark.group.pull_items_shift"));
|
||||
}
|
||||
|
||||
} else {
|
||||
hotkeys.put(NEIClientConfig.getKeyName("gui.bookmark"), NEIClientUtils.translate("bookmark.add_item"));
|
||||
hotkeys.put(KeyManager.getKeyName("bookmark.add"), NEIClientUtils.translate("bookmark.add_item"));
|
||||
|
||||
if (StackInfo.getAmount(stack) > 0) {
|
||||
hotkeys.put(
|
||||
NEIClientConfig.getKeyName("gui.bookmark", NEIClientUtils.CTRL_HASH),
|
||||
KeyManager.getKeyName("bookmark.add", NEIClientUtils.CTRL_HASH),
|
||||
NEIClientUtils.translate("bookmark.add_item_with_count"));
|
||||
}
|
||||
|
||||
if (recipeId != null) {
|
||||
hotkeys.put(
|
||||
NEIClientConfig
|
||||
.getKeyName("gui.bookmark", NEIClientUtils.SHIFT_HASH + NEIClientUtils.CTRL_HASH),
|
||||
KeyManager.getKeyName("bookmark.add", NEIClientUtils.SHIFT_HASH + NEIClientUtils.CTRL_HASH),
|
||||
NEIClientUtils.translate("bookmark.add_item_with_recipe_and_count"));
|
||||
hotkeys.put(
|
||||
NEIClientConfig.getKeyName("gui.bookmark", NEIClientUtils.SHIFT_HASH),
|
||||
KeyManager.getKeyName("bookmark.add", NEIClientUtils.SHIFT_HASH),
|
||||
NEIClientUtils.translate("bookmark.add_item_with_recipe"));
|
||||
}
|
||||
|
||||
if ((ItemPanels.itemPanel.contains(mousex, mousey)
|
||||
|| ItemPanels.itemPanel.historyPanel.contains(mousex, mousey)) && FavoriteRecipes.contains(stack)) {
|
||||
hotkeys.put(
|
||||
NEIClientConfig.getKeyName("gui.favorite"),
|
||||
KeyManager.getKeyName("bookmark.favorite", NEIClientUtils.SHIFT_HASH),
|
||||
NEIClientUtils.translate("recipe.favorite.bookmark_recipe"));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
hotkeys.put(NEIClientConfig.getKeyName("gui.recipe"), NEIClientUtils.translate("itempanel.open_crafting"));
|
||||
hotkeys.put(NEIClientConfig.getKeyName("gui.usage"), NEIClientUtils.translate("itempanel.open_usage"));
|
||||
hotkeys.put(KeyManager.getKeyName("recipe.recipe"), NEIClientUtils.translate("itempanel.open_crafting"));
|
||||
hotkeys.put(KeyManager.getKeyName("recipe.usage"), NEIClientUtils.translate("itempanel.open_usage"));
|
||||
|
||||
hotkeys.put(NEIClientConfig.getKeyName("gui.copy_name"), NEIClientUtils.translate("itempanel.copy_name"));
|
||||
hotkeys.put(NEIClientConfig.getKeyName("gui.copy_oredict"), NEIClientUtils.translate("itempanel.copy_oredict"));
|
||||
hotkeys.put(NEIClientConfig.getKeyName("gui.copy_id"), NEIClientUtils.translate("itempanel.copy_id"));
|
||||
hotkeys.put(
|
||||
NEIClientConfig.getKeyName("gui.chat_link_item"),
|
||||
NEIClientUtils.translate("itempanel.chat_link_item"));
|
||||
KeyManager.getKeyName("copy.name", NEIClientUtils.CTRL_HASH),
|
||||
NEIClientUtils.translate("itempanel.copy_name"));
|
||||
hotkeys.put(
|
||||
KeyManager.getKeyName("copy.oredict", NEIClientUtils.CTRL_HASH),
|
||||
NEIClientUtils.translate("itempanel.copy_oredict"));
|
||||
hotkeys.put(
|
||||
KeyManager.getKeyName("copy.identifier", NEIClientUtils.CTRL_HASH),
|
||||
NEIClientUtils.translate("itempanel.copy_id"));
|
||||
|
||||
hotkeys.put(
|
||||
KeyManager.getKeyName("bookmark.chat_link", NEIClientUtils.CTRL_HASH),
|
||||
NEIClientUtils.translate("bookmark.item.chat_link"));
|
||||
|
||||
if (!(gui instanceof GuiRecipe) && NEIClientConfig.canCheatItem(stack)) {
|
||||
hotkeys.put(
|
||||
NEIClientUtils.getKeyName(NEIClientUtils.SHIFT_HASH, NEIMouseUtils.MOUSE_BTN_LMB),
|
||||
KeyManager.getKeyName(NEIClientUtils.SHIFT_HASH, NEIMouseUtils.MOUSE_BTN_LMB),
|
||||
NEIClientUtils.translate("itempanel.open_crafting"));
|
||||
hotkeys.put(
|
||||
NEIClientUtils.getKeyName(NEIClientUtils.SHIFT_HASH, NEIMouseUtils.MOUSE_BTN_RMB),
|
||||
KeyManager.getKeyName(NEIClientUtils.SHIFT_HASH, NEIMouseUtils.MOUSE_BTN_RMB),
|
||||
NEIClientUtils.translate("itempanel.open_usage"));
|
||||
hotkeys.put(
|
||||
KeyManager.getKeyName(NEIClientUtils.CTRL_HASH, NEIMouseUtils.MOUSE_BTN_LMB),
|
||||
NEIClientUtils.translate("itempanel.infinite_item"));
|
||||
} else {
|
||||
hotkeys.put(
|
||||
NEIMouseUtils.getKeyName(NEIMouseUtils.MOUSE_BTN_LMB),
|
||||
@@ -601,18 +647,18 @@ public abstract class ShortcutInputHandler {
|
||||
|
||||
if (handlerRef.canUseOverlayRenderer(gui)) {
|
||||
hotkeys.put(
|
||||
NEIClientConfig.getKeyName("gui.overlay"),
|
||||
KeyManager.getKeyName("gui.overlay"),
|
||||
NEIClientUtils.translate("itempanel.overlay_recipe"));
|
||||
}
|
||||
|
||||
if (handlerRef.canFillCraftingGrid(gui)) {
|
||||
hotkeys.put(
|
||||
NEIClientConfig.getKeyName("gui.overlay", NEIClientUtils.SHIFT_HASH),
|
||||
KeyManager.getKeyName("gui.overlay", NEIClientUtils.SHIFT_HASH),
|
||||
NEIClientUtils.translate("itempanel.fill_crafting_grid"));
|
||||
|
||||
if (handlerRef.allowedTransferAlghoritm(gui)) {
|
||||
hotkeys.put(
|
||||
NEIClientConfig.getKeyName(
|
||||
KeyManager.getKeyName(
|
||||
"gui.overlay",
|
||||
NEIClientUtils.SHIFT_HASH + NEIClientUtils.CTRL_HASH),
|
||||
NEIClientUtils.translate("itempanel.fill_crafting_grid_quantity"));
|
||||
@@ -621,16 +667,19 @@ public abstract class ShortcutInputHandler {
|
||||
|
||||
if (NEIClientConfig.autocraftingEnabled()) {
|
||||
hotkeys.put(
|
||||
NEIClientConfig.getKeyName(
|
||||
KeyManager.getKeyName(
|
||||
"gui.craft_items",
|
||||
NEIClientUtils.SHIFT_HASH + NEIClientUtils.CTRL_HASH),
|
||||
NEIClientUtils.translate("itempanel.craft_missing"));
|
||||
hotkeys.put(
|
||||
NEIClientConfig.getKeyName("gui.craft_items", NEIClientUtils.SHIFT_HASH),
|
||||
KeyManager.getKeyName("gui.craft_items", NEIClientUtils.SHIFT_HASH),
|
||||
NEIClientUtils.translate("itempanel.craft_all"));
|
||||
}
|
||||
}
|
||||
|
||||
hotkeys.put(
|
||||
KeyManager.getKeyName("bookmark.chat_link", NEIClientUtils.SHIFT_HASH + NEIClientUtils.CTRL_HASH),
|
||||
NEIClientUtils.translate("bookmark.recipe.chat_link"));
|
||||
}
|
||||
|
||||
hotkeysCache.update(mousex, mousey, stack, groupId, hotkeys);
|
||||
@@ -643,8 +692,10 @@ public abstract class ShortcutInputHandler {
|
||||
final List<ItemStack> playerInventory = AutoCraftingManager.getInventoryItems(guiContainer).values();
|
||||
final RecipeId rootRecipeId = math.createMasterRoot();
|
||||
|
||||
for (BookmarkItem item : math.recipeIngredients) {
|
||||
if (item.amount > 0 && rootRecipeId.equals(item.recipeId)) {
|
||||
for (int i = 0; i < math.recipeIngredients.size(); i++) {
|
||||
final BookmarkItem item = math.recipeIngredients.get(i);
|
||||
|
||||
if (item.getAmount() > 0 && rootRecipeId.equals(item.recipeId)) {
|
||||
long amount = 0;
|
||||
|
||||
for (ItemStack stack : playerInventory) {
|
||||
@@ -653,8 +704,12 @@ public abstract class ShortcutInputHandler {
|
||||
}
|
||||
}
|
||||
|
||||
if (amount >= item.amount) {
|
||||
item.factor = item.amount = amount + item.amount - (amount % item.amount);
|
||||
if (amount >= item.getAmount()) {
|
||||
math.recipeIngredients.set(
|
||||
i,
|
||||
BookmarkItem.builder(item).multiplier(1)
|
||||
.factor(amount + item.getAmount() - (amount % item.getAmount()))
|
||||
.chance(PositionedStack.CHANCE_FULL).build());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,76 @@
|
||||
package codechicken.nei.asm;
|
||||
|
||||
import java.lang.reflect.Field;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
import net.minecraft.client.settings.KeyBinding;
|
||||
|
||||
import cpw.mods.fml.relauncher.ReflectionHelper;
|
||||
|
||||
public final class KeyBindingFixHooks {
|
||||
|
||||
private static volatile boolean initialized;
|
||||
private static Field keybindArrayField;
|
||||
private static Field pressedField;
|
||||
private static Field pressTimeField;
|
||||
|
||||
private KeyBindingFixHooks() {}
|
||||
|
||||
public static void onTickAll(int keyCode) {
|
||||
|
||||
if (keyCode == 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
for (KeyBinding binding : getBindings()) {
|
||||
if (binding.getKeyCode() == keyCode) {
|
||||
try {
|
||||
pressTimeField.setInt(binding, pressTimeField.getInt(binding) + 1);
|
||||
} catch (Exception ignored) {}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public static void setKeyBindStateAll(int keyCode, boolean pressed) {
|
||||
|
||||
if (keyCode == 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
for (KeyBinding binding : getBindings()) {
|
||||
if (binding.getKeyCode() == keyCode) {
|
||||
try {
|
||||
pressedField.setBoolean(binding, pressed);
|
||||
} catch (Exception ignored) {}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
private static List<KeyBinding> getBindings() {
|
||||
init();
|
||||
|
||||
try {
|
||||
return (List<KeyBinding>) keybindArrayField.get(null);
|
||||
} catch (Exception ignored) {}
|
||||
|
||||
return Collections.emptyList();
|
||||
}
|
||||
|
||||
private static synchronized void init() {
|
||||
|
||||
if (initialized) {
|
||||
return;
|
||||
}
|
||||
|
||||
keybindArrayField = ReflectionHelper.findField(KeyBinding.class, "keybindArray", "field_74516_a");
|
||||
pressedField = ReflectionHelper.findField(KeyBinding.class, "pressed", "field_74513_e");
|
||||
pressTimeField = ReflectionHelper.findField(KeyBinding.class, "pressTime", "field_151474_i");
|
||||
|
||||
initialized = true;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -56,7 +56,8 @@ public class NEITransformer implements IClassTransformer {
|
||||
|
||||
public NEITransformer() {
|
||||
if (FMLLaunchHandler.side().isClient()) {
|
||||
// Generates method to set the placed position of a mob spawner for the item callback. More portable than
|
||||
// Generates method to set the placed position of a mob spawner for the item
|
||||
// callback. More portable than
|
||||
// copying vanilla placement code
|
||||
transformer.add(
|
||||
new MethodWriter(
|
||||
@@ -82,7 +83,6 @@ public class NEITransformer implements IClassTransformer {
|
||||
asmblocks.get("commaFix"),
|
||||
true));
|
||||
|
||||
// fix workbench container losing items on shift click output without room for the full stack
|
||||
transformer.add(
|
||||
new MethodTransformer(
|
||||
new ObfMapping(
|
||||
@@ -105,6 +105,33 @@ public class NEITransformer implements IClassTransformer {
|
||||
asmblocks.get("d_glintAlphaFix"),
|
||||
asmblocks.get("glintAlphaFix")));
|
||||
|
||||
if (FMLLaunchHandler.side().isClient()) {
|
||||
transformer.add(
|
||||
new MethodWriter(
|
||||
ACC_PUBLIC | ACC_STATIC,
|
||||
new ObfMapping("net/minecraft/client/settings/KeyBinding", "func_74507_a", "(I)V"),
|
||||
asmblocks.get("m_keyBindingOnTickAll")));
|
||||
|
||||
transformer.add(
|
||||
new MethodWriter(
|
||||
ACC_PUBLIC | ACC_STATIC,
|
||||
new ObfMapping("net/minecraft/client/settings/KeyBinding", "func_74510_a", "(IZ)V"),
|
||||
asmblocks.get("m_keyBindingSetStateAll")));
|
||||
|
||||
transformer.add(
|
||||
new MethodInjector(
|
||||
new ObfMapping("net/minecraft/client/settings/GameSettings", "func_74303_b", "()V"),
|
||||
asmblocks.get("saveOptionsHook"),
|
||||
true));
|
||||
|
||||
transformer.add(
|
||||
new MethodInjector(
|
||||
new ObfMapping("net/minecraft/client/settings/GameSettings", "func_74303_b", "()V"),
|
||||
asmblocks.get("n_saveOptionsSendSettings"),
|
||||
asmblocks.get("saveOptionsRestoreHook"),
|
||||
false));
|
||||
}
|
||||
|
||||
String GuiContainer = "net/minecraft/client/gui/inventory/GuiContainer";
|
||||
// add manager field
|
||||
transformer.add(
|
||||
|
||||
@@ -0,0 +1,78 @@
|
||||
package codechicken.nei.asm;
|
||||
|
||||
import java.io.BufferedReader;
|
||||
import java.io.File;
|
||||
import java.io.FileReader;
|
||||
import java.io.FileWriter;
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import codechicken.core.CommonUtils;
|
||||
import codechicken.nei.KeyManager;
|
||||
import codechicken.nei.NEIClientConfig;
|
||||
|
||||
public final class SaveOptionsFixHooks {
|
||||
|
||||
private static final String KEY_PREFIX = "key_nei.options.keys.";
|
||||
|
||||
private static List<String> pendingRestoreLines;
|
||||
|
||||
private SaveOptionsFixHooks() {}
|
||||
|
||||
public static void onBeforeSaveOptions() {
|
||||
pendingRestoreLines = null;
|
||||
|
||||
if (NEIClientConfig.isLoaded()) {
|
||||
return;
|
||||
}
|
||||
|
||||
final File optionsFile = new File(CommonUtils.getMinecraftDir(), "options.txt");
|
||||
if (!optionsFile.exists()) {
|
||||
return;
|
||||
}
|
||||
|
||||
final List<String> missing = new ArrayList<>();
|
||||
|
||||
try (BufferedReader reader = new BufferedReader(new FileReader(optionsFile))) {
|
||||
String line;
|
||||
while ((line = reader.readLine()) != null) {
|
||||
if (!line.startsWith(KEY_PREFIX)) continue;
|
||||
final int colon = line.indexOf(':');
|
||||
if (colon <= 0) continue;
|
||||
|
||||
final String description = line.substring(4, colon);
|
||||
if (!KeyManager.isRegistered(description)) {
|
||||
missing.add(line);
|
||||
}
|
||||
}
|
||||
} catch (IOException e) {
|
||||
NEIClientConfig.logger.error("Failed to read key bindings before options save", e);
|
||||
return;
|
||||
}
|
||||
|
||||
if (!missing.isEmpty()) {
|
||||
pendingRestoreLines = missing;
|
||||
}
|
||||
}
|
||||
|
||||
public static void onAfterSaveOptions() {
|
||||
final List<String> restore = pendingRestoreLines;
|
||||
pendingRestoreLines = null;
|
||||
|
||||
if (restore == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
final File optionsFile = new File(CommonUtils.getMinecraftDir(), "options.txt");
|
||||
|
||||
try (FileWriter writer = new FileWriter(optionsFile, true)) {
|
||||
for (String line : restore) {
|
||||
writer.write(line);
|
||||
writer.write(System.lineSeparator());
|
||||
}
|
||||
} catch (IOException e) {
|
||||
NEIClientConfig.logger.error("Failed to restore NEI key bindings after options save", e);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -24,7 +24,7 @@ import codechicken.lib.gui.GuiDraw;
|
||||
import codechicken.lib.vec.Rectangle4i;
|
||||
import codechicken.nei.BookmarkPanel.BookmarkViewMode;
|
||||
import codechicken.nei.ItemPanels;
|
||||
import codechicken.nei.ItemStackAmount;
|
||||
import codechicken.nei.ItemStackSet;
|
||||
import codechicken.nei.ItemsGrid;
|
||||
import codechicken.nei.ItemsGrid.MouseContext;
|
||||
import codechicken.nei.LayoutManager;
|
||||
@@ -33,6 +33,7 @@ import codechicken.nei.NEIClientUtils;
|
||||
import codechicken.nei.bookmark.BookmarkItem.BookmarkItemType;
|
||||
import codechicken.nei.recipe.Recipe;
|
||||
import codechicken.nei.recipe.Recipe.RecipeId;
|
||||
import codechicken.nei.recipe.Recipe.RecipeIngredient;
|
||||
import codechicken.nei.recipe.StackInfo;
|
||||
import codechicken.nei.recipe.chain.RecipeChainMath;
|
||||
|
||||
@@ -139,17 +140,16 @@ public class BookmarkGrid extends ItemsGrid<BookmarksGridSlot, BookmarkGrid.Book
|
||||
if (group.collapsedRecipes.contains(collapsedRecipeId)) {
|
||||
|
||||
for (BookmarkItem item : this.bookmarkItems) {
|
||||
if (item.groupId == groupId && collapsedRecipeId.equals(item.recipeId)
|
||||
&& item.amount == item.factor) {
|
||||
item.amount = 0;
|
||||
if (item.groupId == groupId && collapsedRecipeId.equals(item.recipeId) && item.multiplier == 1) {
|
||||
item.multiplier = 0;
|
||||
}
|
||||
}
|
||||
|
||||
} else {
|
||||
|
||||
for (BookmarkItem item : this.bookmarkItems) {
|
||||
if (item.groupId == groupId && collapsedRecipeId.equals(item.recipeId) && item.amount == 0) {
|
||||
item.amount = item.factor;
|
||||
if (item.groupId == groupId && collapsedRecipeId.equals(item.recipeId) && item.multiplier == 0) {
|
||||
item.multiplier = 1;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -627,15 +627,17 @@ public class BookmarkGrid extends ItemsGrid<BookmarksGridSlot, BookmarkGrid.Book
|
||||
for (int itemIndex = 0; itemIndex < this.bookmarkItems.size(); itemIndex++) {
|
||||
final BookmarkItem item = this.bookmarkItems.get(itemIndex);
|
||||
if (item.groupId == groupId && (recipeRelations == null || recipeRelations.contains(item.recipeId))) {
|
||||
long amount = item.amount;
|
||||
|
||||
if (recipeId != null && group.crafting != null
|
||||
&& group.crafting.calculatedItems.containsKey(itemIndex)
|
||||
&& recipeId.equals(item.recipeId)) {
|
||||
amount = group.crafting.calculatedItems.get(itemIndex).getCalculatedAmount();
|
||||
chainItems.add(
|
||||
item.copyWithMultiplier(
|
||||
group.crafting.calculatedItems.get(itemIndex).getCalculatedMultiplier()));
|
||||
} else {
|
||||
chainItems.add(item.copy());
|
||||
}
|
||||
|
||||
chainItems.add(item.copyWithAmount(amount));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -896,34 +898,38 @@ public class BookmarkGrid extends ItemsGrid<BookmarksGridSlot, BookmarkGrid.Book
|
||||
}
|
||||
|
||||
public void addRecipe(Recipe recipe, int multiplier, int groupId) {
|
||||
final RecipeId recipeId = recipe.getRecipeId();
|
||||
final List<ItemStack> results = recipe.getResults().stream().map(res -> res.getItemStack())
|
||||
.collect(Collectors.toList());
|
||||
final List<ItemStack> ingredients = recipe.getIngredients().stream().map(ingr -> ingr.getItemStack())
|
||||
.collect(Collectors.toList());
|
||||
final ItemStackSet seenResults = new ItemStackSet();
|
||||
final ItemStackSet seenIngredients = new ItemStackSet();
|
||||
final List<ItemStack> results = new ArrayList<>();
|
||||
final List<ItemStack> ingredients = new ArrayList<>();
|
||||
|
||||
for (ItemStack stack : ItemStackAmount.of(results).values()) {
|
||||
long factor = StackInfo.getAmount(stack);
|
||||
for (RecipeIngredient result : recipe.getResults()) {
|
||||
ItemStack stack = result.getItemStack();
|
||||
if (!seenResults.contains(stack)) {
|
||||
seenResults.add(stack);
|
||||
results.add(stack);
|
||||
}
|
||||
}
|
||||
|
||||
for (RecipeIngredient ingr : recipe.getIngredients()) {
|
||||
ItemStack stack = ingr.getItemStack();
|
||||
if (!seenIngredients.contains(stack)) {
|
||||
seenIngredients.add(stack);
|
||||
ingredients.add(stack);
|
||||
}
|
||||
}
|
||||
|
||||
for (ItemStack stack : results) {
|
||||
this.addItem(
|
||||
BookmarkItem.of(
|
||||
groupId,
|
||||
StackInfo.withAmount(stack, factor * multiplier),
|
||||
factor,
|
||||
recipeId,
|
||||
BookmarkItemType.RESULT),
|
||||
BookmarkItem.builder(groupId, stack, recipe, BookmarkItemType.RESULT).multiplier(multiplier)
|
||||
.build(),
|
||||
true);
|
||||
}
|
||||
|
||||
for (ItemStack stack : ItemStackAmount.of(ingredients).values()) {
|
||||
long factor = StackInfo.getAmount(stack);
|
||||
for (ItemStack stack : ingredients) {
|
||||
this.addItem(
|
||||
BookmarkItem.of(
|
||||
groupId,
|
||||
StackInfo.withAmount(stack, factor * multiplier),
|
||||
factor,
|
||||
recipeId,
|
||||
BookmarkItemType.INGREDIENT,
|
||||
BookmarkItem.generatePermutations(stack, recipe)),
|
||||
BookmarkItem.builder(groupId, stack, recipe, BookmarkItemType.INGREDIENT).multiplier(multiplier)
|
||||
.build(),
|
||||
true);
|
||||
}
|
||||
}
|
||||
@@ -1133,8 +1139,8 @@ public class BookmarkGrid extends ItemsGrid<BookmarksGridSlot, BookmarkGrid.Book
|
||||
final Set<Long> sizes = new HashSet<>();
|
||||
|
||||
for (BookmarkItem item : this.bookmarkItems) {
|
||||
if (item.groupId == targetGroupId && item.amount > 0) {
|
||||
sizes.add(Math.max(item.getStackSize(), item.factor / item.fluidCellAmount));
|
||||
if (item.groupId == targetGroupId && item.getAmount() > 0) {
|
||||
sizes.add(Math.max(item.getStackSize(), item.getStackSize(item.getAmount(1))));
|
||||
items.add(item);
|
||||
}
|
||||
}
|
||||
@@ -1143,14 +1149,16 @@ public class BookmarkGrid extends ItemsGrid<BookmarksGridSlot, BookmarkGrid.Book
|
||||
long multiplier = Integer.MAX_VALUE;
|
||||
|
||||
for (BookmarkItem item : items) {
|
||||
long customFactor = (long) Math.ceil(item.amount / (double) gcd);
|
||||
long customMultiplier = (long) (customFactor > 0 ? Math.ceil(item.amount / (double) customFactor) : 0);
|
||||
final long amount = item.getAmount();
|
||||
final long customFactor = (amount + gcd - 1) / gcd;
|
||||
final long customMultiplier = customFactor > 0 ? ((amount + customFactor - 1) / customFactor) : 0;
|
||||
multiplier = Math.min(shiftMultiplier(customMultiplier, shift, 1), multiplier);
|
||||
}
|
||||
|
||||
for (BookmarkItem item : items) {
|
||||
long customFactor = (long) Math.ceil(item.amount / (double) gcd);
|
||||
item.amount = customFactor * multiplier;
|
||||
final long amount = item.getAmount();
|
||||
final long customFactor = (amount + gcd - 1) / gcd;
|
||||
item.multiplier = item.getMultiplierFromAmount(customFactor * multiplier);
|
||||
}
|
||||
} else {
|
||||
final Map<RecipeId, Long> recipeMultipliers = new HashMap<>();
|
||||
@@ -1158,7 +1166,7 @@ public class BookmarkGrid extends ItemsGrid<BookmarksGridSlot, BookmarkGrid.Book
|
||||
final List<BookmarkItem> items = new ArrayList<>();
|
||||
|
||||
for (BookmarkItem item : this.bookmarkItems) {
|
||||
if (item.factor > 0
|
||||
if (!item.emptyFactor()
|
||||
&& outputRecipes.stream().anyMatch(recipeId -> item.equalsRecipe(recipeId, targetGroupId))) {
|
||||
final long multiplier = recipeMultipliers.getOrDefault(item.recipeId, (long) Integer.MAX_VALUE);
|
||||
final boolean recipeInMiddle = group.crafting != null
|
||||
@@ -1168,7 +1176,7 @@ public class BookmarkGrid extends ItemsGrid<BookmarksGridSlot, BookmarkGrid.Book
|
||||
item.recipeId,
|
||||
Math.min(
|
||||
shiftMultiplier(
|
||||
Math.max(recipeInMiddle ? 1 : 0, item.getMultiplier()),
|
||||
Math.max(recipeInMiddle ? 1 : 0, item.multiplier),
|
||||
shift,
|
||||
recipeInMiddle ? 1 : 0),
|
||||
multiplier));
|
||||
@@ -1177,7 +1185,7 @@ public class BookmarkGrid extends ItemsGrid<BookmarksGridSlot, BookmarkGrid.Book
|
||||
}
|
||||
|
||||
for (BookmarkItem item : items) {
|
||||
item.amount = item.factor * recipeMultipliers.getOrDefault(item.recipeId, 0L);
|
||||
item.multiplier = recipeMultipliers.getOrDefault(item.recipeId, 0L);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1197,10 +1205,10 @@ public class BookmarkGrid extends ItemsGrid<BookmarksGridSlot, BookmarkGrid.Book
|
||||
long multiplier = Integer.MAX_VALUE;
|
||||
|
||||
for (BookmarkItem item : this.bookmarkItems) {
|
||||
if (item.equalsRecipe(recipeId, targetItem.groupId) && item.factor > 0) {
|
||||
if (item.equalsRecipe(recipeId, targetItem.groupId) && !item.emptyFactor()) {
|
||||
multiplier = Math.min(
|
||||
shiftMultiplier(
|
||||
Math.max(recipeInMiddle ? 1 : 0, item.getMultiplier()),
|
||||
Math.max(recipeInMiddle ? 1 : 0, item.multiplier),
|
||||
shift,
|
||||
recipeInMiddle ? 1 : 0),
|
||||
multiplier);
|
||||
@@ -1208,8 +1216,8 @@ public class BookmarkGrid extends ItemsGrid<BookmarksGridSlot, BookmarkGrid.Book
|
||||
}
|
||||
|
||||
for (BookmarkItem item : this.bookmarkItems) {
|
||||
if (item.equalsRecipe(recipeId, targetItem.groupId) && item.factor > 0) {
|
||||
item.amount = item.factor * multiplier;
|
||||
if (item.equalsRecipe(recipeId, targetItem.groupId) && !item.emptyFactor()) {
|
||||
item.multiplier = multiplier;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1217,7 +1225,7 @@ public class BookmarkGrid extends ItemsGrid<BookmarksGridSlot, BookmarkGrid.Book
|
||||
|
||||
for (BookmarkItem item : this.bookmarkItems) {
|
||||
if (targetItem.equals(item)) {
|
||||
item.amount = item.factor * shiftMultiplier(item.getMultiplier(), shift, 0);
|
||||
item.multiplier = shiftMultiplier(item.multiplier, shift, 0);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -66,10 +66,14 @@ public class BookmarkGridGenerator {
|
||||
while (itemIndex < size && absoluteSlotIndex != -1) {
|
||||
final BookmarkItem bookmarkItem = this.grid.getBookmarkItem(itemIndex);
|
||||
final BookmarkGroup group = this.grid.getGroup(bookmarkItem.groupId);
|
||||
final boolean isCollapsedRecipeAnchor = group.crafting != null && bookmarkItem.recipeId != null
|
||||
&& bookmarkItem.type != BookmarkItemType.INGREDIENT
|
||||
&& group.collapsedRecipes.contains(bookmarkItem.recipeId);
|
||||
|
||||
if (group.crafting != null && (!group.crafting.calculatedItems.containsKey(itemIndex)
|
||||
|| bookmarkItem.recipeId != null && !bookmarkItem.recipeId
|
||||
.equals(group.crafting.itemToRecipe.getOrDefault(itemIndex, bookmarkItem.recipeId)))) {
|
||||
if (group.crafting != null && !isCollapsedRecipeAnchor
|
||||
&& (!group.crafting.calculatedItems.containsKey(itemIndex)
|
||||
|| bookmarkItem.recipeId != null && !bookmarkItem.recipeId.equals(
|
||||
group.crafting.itemToRecipe.getOrDefault(itemIndex, bookmarkItem.recipeId)))) {
|
||||
itemIndex++;
|
||||
} else if (group.collapsed) {
|
||||
final List<Integer> results = getGroupResults(bookmarkItem.groupId, itemIndex, size);
|
||||
@@ -189,13 +193,11 @@ public class BookmarkGridGenerator {
|
||||
for (int shadowIndex : shadows) {
|
||||
final boolean isIngredient = shadows.get(0) != shadowIndex
|
||||
|| group.crafting.calculatedItems.get(shadowIndex).calculatedType == CalculatedType.INGREDIENT;
|
||||
final BookmarkItem shadowBookmarkItem = BookmarkItem.of(
|
||||
bookmarkItem.groupId,
|
||||
bookmarkItem.itemStack,
|
||||
1,
|
||||
bookmarkItem.recipeId,
|
||||
isIngredient ? BookmarkItemType.INGREDIENT : BookmarkItemType.RESULT,
|
||||
Collections.emptyMap());
|
||||
|
||||
final BookmarkItem shadowBookmarkItem = BookmarkItem.builder(bookmarkItem.groupId, bookmarkItem.itemStack)
|
||||
.multiplier(1).factor(StackInfo.getAmount(bookmarkItem.itemStack)).recipeId(bookmarkItem.recipeId)
|
||||
.type(isIngredient ? BookmarkItemType.INGREDIENT : BookmarkItemType.RESULT)
|
||||
.permutations(Collections.emptyMap()).build();
|
||||
|
||||
if ((absoluteSlotIndex = nextSlotIndex(
|
||||
absoluteSlotIndex + 1,
|
||||
@@ -228,7 +230,7 @@ public class BookmarkGridGenerator {
|
||||
index = Math.max(0, index);
|
||||
|
||||
while (j++ < maxIndex) {
|
||||
boolean isFirstColumn = (index % gridColumns) == 0;
|
||||
final boolean isFirstColumn = (index % gridColumns) == 0;
|
||||
|
||||
if (this.grid.isInvalidSlot(index % maxIndex)) {
|
||||
index++;
|
||||
@@ -239,7 +241,7 @@ public class BookmarkGridGenerator {
|
||||
return index;
|
||||
} else if (isFirstColumn && (meta.recipeId == null || previousMeta == null
|
||||
|| previousMeta.groupId != meta.groupId
|
||||
|| meta.type == BookmarkItemType.ITEM
|
||||
|| meta.type != BookmarkItemType.INGREDIENT
|
||||
|| !meta.recipeId.equals(previousMeta.recipeId)
|
||||
|| index + 1 < maxIndex && this.grid.isInvalidSlot((index + 1) % maxIndex))) {
|
||||
// In first column must be an item without recipe, a recipe result, or an ingredient
|
||||
@@ -248,6 +250,7 @@ public class BookmarkGridGenerator {
|
||||
} else
|
||||
if (!isFirstColumn && meta.type != BookmarkItemType.ITEM
|
||||
&& previousMeta.type != BookmarkItemType.ITEM
|
||||
&& meta.groupId == previousMeta.groupId
|
||||
&& meta.recipeId != null
|
||||
&& meta.recipeId.equals(previousMeta.recipeId)) {
|
||||
return index;
|
||||
@@ -319,7 +322,7 @@ public class BookmarkGridGenerator {
|
||||
return group.crafting.calculatedItems.get(itemIndex);
|
||||
} else {
|
||||
BookmarkChainItem item = BookmarkChainItem.of(this.grid.getBookmarkItem(itemIndex));
|
||||
item.setRealAmount(item.getShiftAmount());
|
||||
item.setRealMultiplier(item.getCalculatedMultiplier());
|
||||
return item;
|
||||
}
|
||||
}
|
||||
@@ -332,7 +335,7 @@ public class BookmarkGridGenerator {
|
||||
return new BookmarksGridSlot(
|
||||
slotIndex,
|
||||
itemIndex,
|
||||
chainItem.getRealAmount(),
|
||||
chainItem.getRealMultiplier(),
|
||||
0,
|
||||
0,
|
||||
chainItem.getItem(),
|
||||
@@ -342,9 +345,9 @@ public class BookmarkGridGenerator {
|
||||
return new BookmarksGridSlot(
|
||||
slotIndex,
|
||||
itemIndex,
|
||||
chainItem.getRealAmount(),
|
||||
chainItem.getRealMultiplier(),
|
||||
chainItem.getShiftAmount(),
|
||||
chainItem.getCalculatedAmount(),
|
||||
chainItem.getCalculatedMultiplier(),
|
||||
chainItem.getItem(),
|
||||
chainItem.calculatedType,
|
||||
group);
|
||||
|
||||
@@ -2,6 +2,7 @@ package codechicken.nei.bookmark;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
|
||||
@@ -9,14 +10,160 @@ import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.nbt.NBTTagCompound;
|
||||
import net.minecraftforge.fluids.FluidStack;
|
||||
|
||||
import com.google.gson.JsonObject;
|
||||
import com.google.gson.JsonPrimitive;
|
||||
|
||||
import codechicken.nei.NEIClientUtils;
|
||||
import codechicken.nei.PositionedStack;
|
||||
import codechicken.nei.recipe.Recipe;
|
||||
import codechicken.nei.recipe.Recipe.RecipeId;
|
||||
import codechicken.nei.recipe.Recipe.RecipeIngredient;
|
||||
import codechicken.nei.recipe.StackInfo;
|
||||
import codechicken.nei.util.NBTJson;
|
||||
|
||||
public class BookmarkItem {
|
||||
|
||||
public static class Builder {
|
||||
|
||||
private static Map<ItemStack, String> fuzzyPermutations = new HashMap<>();
|
||||
|
||||
private final int groupId;
|
||||
private final ItemStack stack;
|
||||
private long factor;
|
||||
private long multiplier = -1;
|
||||
private long chance = PositionedStack.CHANCE_FULL;
|
||||
private RecipeId recipeId = null;
|
||||
private Recipe recipe = null;
|
||||
private BookmarkItemType type = BookmarkItemType.ITEM;
|
||||
private Map<String, ItemStack> permutations = null;
|
||||
|
||||
private Builder(int groupId, ItemStack stack) {
|
||||
final NBTTagCompound nbTag = StackInfo.itemStackToNBT(stack);
|
||||
|
||||
this.groupId = groupId;
|
||||
this.stack = stack;
|
||||
this.factor = nbTag.hasKey("gtFluidName") ? Math.min(144, nbTag.getInteger("Count")) : 1;
|
||||
}
|
||||
|
||||
public Builder factor(long factor) {
|
||||
this.factor = factor;
|
||||
return this;
|
||||
}
|
||||
|
||||
public Builder multiplier(long multiplier) {
|
||||
this.multiplier = multiplier;
|
||||
return this;
|
||||
}
|
||||
|
||||
public Builder chance(long chance) {
|
||||
this.chance = chance;
|
||||
return this;
|
||||
}
|
||||
|
||||
public Builder recipe(Recipe recipe) {
|
||||
this.recipe = recipe;
|
||||
this.recipeId = null;
|
||||
return this;
|
||||
}
|
||||
|
||||
public Builder recipeId(RecipeId recipeId) {
|
||||
this.recipeId = recipeId;
|
||||
this.recipe = null;
|
||||
return this;
|
||||
}
|
||||
|
||||
public Builder type(BookmarkItemType type) {
|
||||
this.type = type;
|
||||
return this;
|
||||
}
|
||||
|
||||
public Builder permutations(Map<String, ItemStack> permutations) {
|
||||
this.permutations = permutations;
|
||||
return this;
|
||||
}
|
||||
|
||||
public BookmarkItem build() {
|
||||
final Map<String, ItemStack> perms;
|
||||
long multiplier = 0;
|
||||
|
||||
if (this.permutations != null) {
|
||||
perms = this.permutations;
|
||||
} else if (this.type == BookmarkItemType.INGREDIENT) {
|
||||
|
||||
if (this.recipe != null) {
|
||||
perms = Builder.generatePermutations(this.stack, this.recipe);
|
||||
} else if (this.recipeId != null) {
|
||||
perms = Builder.generatePermutations(this.stack, Recipe.of(this.recipeId));
|
||||
} else {
|
||||
perms = Builder.generatePermutations(this.stack);
|
||||
}
|
||||
|
||||
} else {
|
||||
perms = Builder.generatePermutations(this.stack);
|
||||
}
|
||||
|
||||
if (this.multiplier >= 0) {
|
||||
multiplier = this.multiplier;
|
||||
} else if (this.factor > 0) {
|
||||
multiplier = StackInfo.getAmount(this.stack) / this.factor;
|
||||
}
|
||||
|
||||
return new BookmarkItem(
|
||||
this.groupId,
|
||||
multiplier,
|
||||
this.factor,
|
||||
this.chance,
|
||||
this.stack,
|
||||
perms,
|
||||
this.recipeId != null ? this.recipeId : this.recipe != null ? this.recipe.getRecipeId() : null,
|
||||
this.type);
|
||||
}
|
||||
|
||||
public static Map<String, ItemStack> generatePermutations(ItemStack stack) {
|
||||
return Collections.singletonMap(getItemGUID(stack), stack);
|
||||
}
|
||||
|
||||
public static Map<String, ItemStack> generatePermutations(ItemStack stack, Recipe recipe) {
|
||||
|
||||
if (recipe != null) {
|
||||
final RecipeIngredient ingr = recipe.getIngredients().stream()
|
||||
.filter(ingredient -> ingredient.contains(stack)).findAny().orElse(null);
|
||||
|
||||
if (ingr != null) {
|
||||
final Map<String, ItemStack> permutations = new HashMap<>();
|
||||
for (ItemStack ingrStack : ingr.getPermutations()) {
|
||||
permutations.put(getItemGUID(ingrStack), ingrStack);
|
||||
}
|
||||
return permutations;
|
||||
}
|
||||
}
|
||||
|
||||
return generatePermutations(stack);
|
||||
}
|
||||
|
||||
private static synchronized String getItemGUID(ItemStack stack) {
|
||||
final FluidStack fluidStack = StackInfo.getFluid(stack);
|
||||
|
||||
if (fluidStack != null) {
|
||||
return fluidStack.getFluid().getName() + ":" + fluidStack.tag;
|
||||
} else {
|
||||
|
||||
for (Map.Entry<ItemStack, String> entry : Builder.fuzzyPermutations.entrySet()) {
|
||||
if (NEIClientUtils.areStacksSameTypeCraftingWithNBT(stack, entry.getKey())) {
|
||||
Builder.fuzzyPermutations.put(stack, entry.getValue());
|
||||
return entry.getValue();
|
||||
}
|
||||
}
|
||||
|
||||
final String stackGUID = StackInfo.getItemStackGUID(stack);
|
||||
Builder.fuzzyPermutations.put(stack, stackGUID);
|
||||
|
||||
return stackGUID;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public enum BookmarkItemType {
|
||||
|
||||
INGREDIENT,
|
||||
@@ -32,150 +179,167 @@ public class BookmarkItem {
|
||||
}
|
||||
}
|
||||
|
||||
private static Map<ItemStack, String> fuzzyPermutations = new HashMap<>();
|
||||
|
||||
public int groupId;
|
||||
|
||||
public long amount = 0L;
|
||||
public final int fluidCellAmount;
|
||||
public ItemStack itemStack;
|
||||
public Map<String, ItemStack> permutations;
|
||||
|
||||
public long factor;
|
||||
public RecipeId recipeId;
|
||||
public BookmarkItemType type = BookmarkItemType.ITEM;
|
||||
|
||||
protected BookmarkItem(int groupId, long amount, int fluidCellAmount, ItemStack itemStack,
|
||||
Map<String, ItemStack> permutations, long factor, RecipeId recipeId, BookmarkItemType type) {
|
||||
public long multiplier = 1L;
|
||||
public final long factor;
|
||||
public final int fluidCellAmount;
|
||||
public final long chance;
|
||||
|
||||
protected BookmarkItem(int groupId, long multiplier, long factor, long chance, ItemStack itemStack,
|
||||
Map<String, ItemStack> permutations, RecipeId recipeId, BookmarkItemType type) {
|
||||
final FluidStack fluidStack = StackInfo.getFluid(itemStack);
|
||||
|
||||
if (fluidStack != null) {
|
||||
this.fluidCellAmount = Math.max(1, StackInfo.isFluidContainer(itemStack) ? fluidStack.amount : 1);
|
||||
} else {
|
||||
this.fluidCellAmount = 1;
|
||||
}
|
||||
|
||||
this.groupId = groupId;
|
||||
|
||||
this.amount = amount;
|
||||
this.fluidCellAmount = fluidCellAmount;
|
||||
this.itemStack = itemStack;
|
||||
this.permutations = permutations;
|
||||
|
||||
this.factor = factor;
|
||||
this.recipeId = recipeId;
|
||||
this.type = type == null ? BookmarkItemType.ITEM : type;
|
||||
|
||||
this.multiplier = multiplier;
|
||||
this.factor = factor;
|
||||
this.chance = chance;
|
||||
}
|
||||
|
||||
public static BookmarkItem of(int groupId, ItemStack stack, long factor, RecipeId recipeId, BookmarkItemType type,
|
||||
Map<String, ItemStack> permutations) {
|
||||
final FluidStack fluidStack = StackInfo.getFluid(stack);
|
||||
int fluidCellAmount = 1;
|
||||
long amount;
|
||||
public static Builder builder(int groupId, ItemStack stack) {
|
||||
return new Builder(groupId, stack);
|
||||
}
|
||||
|
||||
if (fluidStack != null) {
|
||||
amount = fluidStack.amount * (long) Math.max(0, stack.stackSize);
|
||||
fluidCellAmount = Math.max(1, StackInfo.isFluidContainer(stack) ? fluidStack.amount : 1);
|
||||
} else {
|
||||
amount = StackInfo.getAmount(stack);
|
||||
public static Builder builder(BookmarkItem item) {
|
||||
return new Builder(item.groupId, item.itemStack).factor(item.factor).multiplier(item.multiplier)
|
||||
.chance(item.chance).recipeId(item.recipeId).type(item.type).permutations(item.permutations);
|
||||
}
|
||||
|
||||
public static Builder builder(int groupId, ItemStack stack, Recipe recipe, BookmarkItemType type) {
|
||||
final List<RecipeIngredient> items = type == BookmarkItemType.RESULT ? recipe.getResults()
|
||||
: recipe.getIngredients();
|
||||
final Builder builder = builder(groupId, stack).type(type).recipe(recipe);
|
||||
long amount = 0;
|
||||
|
||||
for (RecipeIngredient res : items) {
|
||||
if (res.contains(stack)) {
|
||||
amount += 1L * res.getAmount() * res.getChance();
|
||||
}
|
||||
}
|
||||
|
||||
return new BookmarkItem(
|
||||
groupId,
|
||||
amount,
|
||||
fluidCellAmount,
|
||||
stack,
|
||||
permutations,
|
||||
factor * fluidCellAmount,
|
||||
recipeId,
|
||||
type);
|
||||
}
|
||||
if ((amount % PositionedStack.CHANCE_FULL) == 0) {
|
||||
builder.factor(amount / PositionedStack.CHANCE_FULL);
|
||||
} else {
|
||||
builder.factor(1).chance(amount);
|
||||
}
|
||||
|
||||
public static BookmarkItem of(int groupId, ItemStack stack, long factor, RecipeId recipeId, BookmarkItemType type) {
|
||||
return of(
|
||||
groupId,
|
||||
stack,
|
||||
factor,
|
||||
recipeId,
|
||||
type,
|
||||
generatePermutations(stack, recipeId, type == BookmarkItemType.INGREDIENT));
|
||||
return builder;
|
||||
}
|
||||
|
||||
public static BookmarkItem of(int groupId, ItemStack stack) {
|
||||
final NBTTagCompound nbTag = StackInfo.itemStackToNBT(stack);
|
||||
final long factor = nbTag.hasKey("gtFluidName") ? Math.min(144, nbTag.getInteger("Count")) : 1;
|
||||
return BookmarkItem.of(
|
||||
groupId,
|
||||
stack,
|
||||
factor,
|
||||
null,
|
||||
BookmarkItemType.ITEM,
|
||||
Collections.singletonMap(getItemGUID(stack), stack));
|
||||
return builder(groupId, stack).build();
|
||||
}
|
||||
|
||||
public BookmarkItem copyWithAmount(long amount) {
|
||||
public static BookmarkItem of(JsonObject jsonObject) {
|
||||
final NBTTagCompound itemStackNBT = (NBTTagCompound) NBTJson.toNbt(jsonObject.get("item"));
|
||||
final ItemStack itemStack = StackInfo.loadFromNBT(itemStackNBT);
|
||||
|
||||
if (itemStack != null) {
|
||||
final int groupId = jsonObject.has("groupId") ? jsonObject.get("groupId").getAsInt()
|
||||
: BookmarkGrid.DEFAULT_GROUP_ID;
|
||||
final BookmarkItem.Builder builder = BookmarkItem.builder(groupId, itemStack);
|
||||
|
||||
if (jsonObject.has("type")) {
|
||||
builder.type(BookmarkItemType.fromInt(jsonObject.get("type").getAsInt()));
|
||||
} else if (jsonObject.has("ingredient") && jsonObject.get("ingredient").getAsBoolean()) {
|
||||
builder.type(BookmarkItemType.INGREDIENT);
|
||||
} else {
|
||||
builder.type(BookmarkItemType.RESULT);
|
||||
}
|
||||
|
||||
if (jsonObject.has("multiplier")) {
|
||||
builder.multiplier(jsonObject.get("multiplier").getAsInt());
|
||||
}
|
||||
|
||||
if (jsonObject.has("factor")) {
|
||||
builder.factor(jsonObject.get("factor").getAsInt());
|
||||
}
|
||||
|
||||
if (jsonObject.has("chance")) {
|
||||
builder.chance(jsonObject.get("chance").getAsInt());
|
||||
}
|
||||
|
||||
if (jsonObject.get("recipeId") instanceof JsonObject recipeJson) {
|
||||
builder.recipeId(RecipeId.of(recipeJson));
|
||||
}
|
||||
|
||||
return builder.build();
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public BookmarkItem copyWithMultiplier(long multiplier) {
|
||||
return new BookmarkItem(
|
||||
this.groupId,
|
||||
amount,
|
||||
this.fluidCellAmount,
|
||||
multiplier,
|
||||
this.factor,
|
||||
this.chance,
|
||||
this.itemStack,
|
||||
this.permutations,
|
||||
this.factor,
|
||||
this.recipeId,
|
||||
this.type);
|
||||
}
|
||||
|
||||
public BookmarkItem copyWithAmount(long amount) {
|
||||
return copyWithMultiplier(getMultiplierFromAmount(amount));
|
||||
}
|
||||
|
||||
public BookmarkItem copy() {
|
||||
return copyWithAmount(this.amount);
|
||||
}
|
||||
|
||||
public static Map<String, ItemStack> generatePermutations(ItemStack stack, RecipeId recipeId,
|
||||
boolean isIngredient) {
|
||||
|
||||
if (isIngredient && recipeId != null) {
|
||||
return generatePermutations(stack, Recipe.of(recipeId));
|
||||
}
|
||||
|
||||
return Collections.singletonMap(getItemGUID(stack), stack);
|
||||
}
|
||||
|
||||
public static Map<String, ItemStack> generatePermutations(ItemStack stack, Recipe recipe) {
|
||||
|
||||
if (recipe != null) {
|
||||
final RecipeIngredient ingr = recipe.getIngredients().stream()
|
||||
.filter(ingredient -> ingredient.contains(stack)).findAny().orElse(null);
|
||||
|
||||
if (ingr != null) {
|
||||
final Map<String, ItemStack> permutations = new HashMap<>();
|
||||
for (ItemStack ingrStack : ingr.getPermutations()) {
|
||||
permutations.put(getItemGUID(ingrStack), ingrStack);
|
||||
}
|
||||
return permutations;
|
||||
}
|
||||
}
|
||||
|
||||
return Collections.singletonMap(getItemGUID(stack), stack);
|
||||
}
|
||||
|
||||
private static synchronized String getItemGUID(ItemStack stack) {
|
||||
final FluidStack fluidStack = StackInfo.getFluid(stack);
|
||||
|
||||
if (fluidStack != null) {
|
||||
return fluidStack.getFluid().getName() + ":" + fluidStack.tag;
|
||||
} else {
|
||||
|
||||
for (Map.Entry<ItemStack, String> entry : BookmarkItem.fuzzyPermutations.entrySet()) {
|
||||
if (NEIClientUtils.areStacksSameTypeCraftingWithNBT(stack, entry.getKey())) {
|
||||
BookmarkItem.fuzzyPermutations.put(stack, entry.getValue());
|
||||
return entry.getValue();
|
||||
}
|
||||
}
|
||||
|
||||
final String stackGUID = StackInfo.getItemStackGUID(stack);
|
||||
BookmarkItem.fuzzyPermutations.put(stack, stackGUID);
|
||||
|
||||
return stackGUID;
|
||||
}
|
||||
return copyWithMultiplier(this.multiplier);
|
||||
}
|
||||
|
||||
public boolean containsItems(BookmarkItem item) {
|
||||
return this.permutations.keySet().stream().anyMatch(item.permutations::containsKey);
|
||||
}
|
||||
|
||||
public long getAmount() {
|
||||
return getAmount(this.multiplier);
|
||||
}
|
||||
|
||||
public long getAmount(long multiplier) {
|
||||
long amount = this.factor * multiplier;
|
||||
|
||||
if (this.fluidCellAmount > 1) {
|
||||
amount = amount * this.fluidCellAmount;
|
||||
}
|
||||
|
||||
if (this.chance != PositionedStack.CHANCE_FULL) {
|
||||
|
||||
if (this.type == BookmarkItemType.INGREDIENT) {
|
||||
// For ingredients, round up the expected amount to be conservative.
|
||||
amount = (amount * this.chance + PositionedStack.CHANCE_FULL - 1) / PositionedStack.CHANCE_FULL;
|
||||
} else {
|
||||
// For results, round down the expected amount to be conservative.
|
||||
amount = (amount * this.chance) / PositionedStack.CHANCE_FULL;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return amount;
|
||||
}
|
||||
|
||||
public ItemStack getItemStack() {
|
||||
return getItemStack(this.amount);
|
||||
return getItemStack(getAmount());
|
||||
}
|
||||
|
||||
public ItemStack getItemStack(long amount) {
|
||||
@@ -183,23 +347,34 @@ public class BookmarkItem {
|
||||
}
|
||||
|
||||
public long getStackSize() {
|
||||
return getStackSize(this.amount);
|
||||
return getStackSize(getAmount());
|
||||
}
|
||||
|
||||
public long getStackSize(long amount) {
|
||||
return (long) (this.factor > 0 ? Math.ceil(amount / (double) this.fluidCellAmount) : 0);
|
||||
|
||||
if (this.fluidCellAmount > 1) {
|
||||
amount = (amount + this.fluidCellAmount - 1) / this.fluidCellAmount;
|
||||
}
|
||||
|
||||
return amount;
|
||||
}
|
||||
|
||||
public long getMultiplierFromAmount(long amount) {
|
||||
if (this.factor <= 0 || this.chance <= 0) return 0;
|
||||
|
||||
if (this.fluidCellAmount > 1) {
|
||||
amount = (amount + this.fluidCellAmount - 1) / this.fluidCellAmount;
|
||||
}
|
||||
|
||||
if (this.chance == PositionedStack.CHANCE_FULL) {
|
||||
return (amount + this.factor - 1) / this.factor;
|
||||
}
|
||||
|
||||
return (amount * PositionedStack.CHANCE_FULL + this.factor * this.chance - 1) / (this.factor * this.chance);
|
||||
}
|
||||
|
||||
public long getMultiplier() {
|
||||
return getMultiplier(this.amount);
|
||||
}
|
||||
|
||||
public long getMultiplier(long amount) {
|
||||
return (long) (this.factor > 0 ? Math.ceil(amount / (double) this.factor) : 0);
|
||||
}
|
||||
|
||||
public long getFactor() {
|
||||
return this.factor / this.fluidCellAmount;
|
||||
return this.multiplier;
|
||||
}
|
||||
|
||||
public boolean equalsRecipe(BookmarkItem meta) {
|
||||
@@ -210,6 +385,10 @@ public class BookmarkItem {
|
||||
return groupId == this.groupId && recipeId != null && recipeId.equals(this.recipeId);
|
||||
}
|
||||
|
||||
public boolean emptyFactor() {
|
||||
return this.factor <= 0 || this.chance <= 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return Objects.hash(this.groupId, this.fluidCellAmount, this.type.toInt(), this.recipeId);
|
||||
@@ -228,4 +407,27 @@ public class BookmarkItem {
|
||||
return false;
|
||||
}
|
||||
|
||||
public JsonObject toJsonObject() {
|
||||
final JsonObject jsonObject = new JsonObject();
|
||||
|
||||
jsonObject.add("item", NBTJson.toJsonObject(StackInfo.itemStackToNBT(getItemStack())));
|
||||
jsonObject.add("multiplier", new JsonPrimitive(this.multiplier));
|
||||
jsonObject.add("factor", new JsonPrimitive(this.factor));
|
||||
jsonObject.add("type", new JsonPrimitive(this.type.toInt()));
|
||||
|
||||
if (this.groupId != BookmarkGrid.DEFAULT_GROUP_ID) {
|
||||
jsonObject.add("groupId", new JsonPrimitive(this.groupId));
|
||||
}
|
||||
|
||||
if (this.recipeId != null) {
|
||||
jsonObject.add("recipeId", this.recipeId.toJsonObject());
|
||||
}
|
||||
|
||||
if (this.chance != PositionedStack.CHANCE_FULL) {
|
||||
jsonObject.add("chance", new JsonPrimitive(this.chance));
|
||||
}
|
||||
|
||||
return jsonObject;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,283 @@
|
||||
package codechicken.nei.bookmark;
|
||||
|
||||
import java.awt.Point;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.nbt.NBTTagCompound;
|
||||
import net.minecraft.nbt.NBTTagList;
|
||||
|
||||
import com.google.gson.JsonObject;
|
||||
|
||||
import codechicken.lib.gui.GuiDraw;
|
||||
import codechicken.nei.BookmarkPanel.BookmarkViewMode;
|
||||
import codechicken.nei.ItemPanels;
|
||||
import codechicken.nei.ItemQuantityField;
|
||||
import codechicken.nei.ItemStackSet;
|
||||
import codechicken.nei.bookmark.BookmarkItem.BookmarkItemType;
|
||||
import codechicken.nei.recipe.Recipe;
|
||||
import codechicken.nei.recipe.Recipe.RecipeId;
|
||||
import codechicken.nei.recipe.Recipe.RecipeIngredient;
|
||||
import codechicken.nei.recipe.StackInfo;
|
||||
import codechicken.nei.util.NBTJson;
|
||||
|
||||
public class BookmarkPayload {
|
||||
|
||||
private String linkType;
|
||||
private NBTTagCompound target;
|
||||
|
||||
private NBTTagCompound group;
|
||||
|
||||
private NBTTagList items = new NBTTagList();
|
||||
private NBTTagList recipes = new NBTTagList();
|
||||
|
||||
private BookmarkPayload(String linkType, ItemStack stack) {
|
||||
this.linkType = linkType;
|
||||
this.target = stack != null ? StackInfo.itemStackToNBT(stack) : null;
|
||||
}
|
||||
|
||||
public static BookmarkPayload of(NBTTagCompound nbt) {
|
||||
final BookmarkPayload payload = new BookmarkPayload(nbt.getString("linkType"), null);
|
||||
|
||||
if (nbt.hasKey("item")) {
|
||||
payload.target = nbt.getCompoundTag("item");
|
||||
}
|
||||
|
||||
if (nbt.hasKey("group")) {
|
||||
payload.group = nbt.getCompoundTag("group");
|
||||
}
|
||||
|
||||
payload.items = nbt.getTagList("items", 10);
|
||||
payload.recipes = nbt.getTagList("recipes", 10);
|
||||
|
||||
return payload;
|
||||
}
|
||||
|
||||
public static BookmarkPayload of(BookmarkItem item) {
|
||||
final BookmarkPayload payload = new BookmarkPayload("recipe", item.getItemStack());
|
||||
final BookmarkGrid grid = ItemPanels.bookmarkPanel.getGrid();
|
||||
final Map<RecipeId, Integer> recipesIndexes = new HashMap<>();
|
||||
final RecipeId recipeId = item.recipeId;
|
||||
final int groupId = item.groupId;
|
||||
|
||||
payload.items = new NBTTagList();
|
||||
payload.recipes = new NBTTagList();
|
||||
|
||||
if (recipeId != null) {
|
||||
|
||||
for (int itemIndex = 0; itemIndex < grid.size(); itemIndex++) {
|
||||
final BookmarkItem currentItem = grid.getBookmarkItem(itemIndex);
|
||||
|
||||
if (currentItem != null && currentItem.groupId == groupId && recipeId.equals(currentItem.recipeId)) {
|
||||
addBookmarkItemToPayload(payload, currentItem, recipesIndexes);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
} else {
|
||||
addBookmarkItemToPayload(payload, item, recipesIndexes);
|
||||
}
|
||||
|
||||
return payload;
|
||||
}
|
||||
|
||||
public static BookmarkPayload of(Recipe recipe) {
|
||||
final BookmarkPayload payload = new BookmarkPayload("recipe", recipe.getResult());
|
||||
final Map<RecipeId, Integer> recipesIndexes = new HashMap<>();
|
||||
final ItemStackSet seenIngredients = new ItemStackSet();
|
||||
final ItemStackSet seenResults = new ItemStackSet();
|
||||
|
||||
for (RecipeIngredient result : recipe.getResults()) {
|
||||
ItemStack stack = result.getItemStack();
|
||||
if (!seenResults.contains(stack)) {
|
||||
final BookmarkItem item = BookmarkItem.builder(-1, stack, recipe, BookmarkItemType.RESULT).build();
|
||||
addBookmarkItemToPayload(payload, item, recipesIndexes);
|
||||
seenResults.add(stack);
|
||||
}
|
||||
}
|
||||
|
||||
for (RecipeIngredient ingr : recipe.getIngredients()) {
|
||||
ItemStack stack = ingr.getItemStack();
|
||||
if (!seenIngredients.contains(stack)) {
|
||||
final BookmarkItem item = BookmarkItem.builder(-1, stack, recipe, BookmarkItemType.INGREDIENT).build();
|
||||
addBookmarkItemToPayload(payload, item, recipesIndexes);
|
||||
seenIngredients.add(stack);
|
||||
}
|
||||
}
|
||||
|
||||
return payload;
|
||||
}
|
||||
|
||||
public static BookmarkPayload of(int groupId) {
|
||||
final BookmarkPayload payload = new BookmarkPayload("group", null);
|
||||
final Map<RecipeId, Integer> recipesIndexes = new HashMap<>();
|
||||
final BookmarkGrid grid = ItemPanels.bookmarkPanel.getGrid();
|
||||
|
||||
for (int itemIndex = 0; itemIndex < grid.size(); itemIndex++) {
|
||||
final BookmarkItem item = grid.getBookmarkItem(itemIndex);
|
||||
|
||||
if (item != null && item.groupId == groupId) {
|
||||
addBookmarkItemToPayload(payload, item, recipesIndexes);
|
||||
}
|
||||
}
|
||||
|
||||
payload.group = generateGroup(grid.getGroup(groupId));
|
||||
|
||||
return payload;
|
||||
}
|
||||
|
||||
public static BookmarkPayload of(ItemStack stackover, RecipeId recipeId) {
|
||||
final BookmarkPayload payload = new BookmarkPayload("item", stackover);
|
||||
final Map<RecipeId, Integer> recipesIndexes = new HashMap<>();
|
||||
final Point mousePos = GuiDraw.getMousePosition();
|
||||
|
||||
if (ItemPanels.itemPanel.containsWithSubpanels(mousePos.x, mousePos.y)) {
|
||||
stackover = ItemQuantityField.prepareStackWithQuantity(stackover, 0);
|
||||
}
|
||||
|
||||
final BookmarkItem item = BookmarkItem.builder(-1, stackover).recipeId(recipeId).type(BookmarkItemType.ITEM)
|
||||
.build();
|
||||
|
||||
addBookmarkItemToPayload(payload, item, recipesIndexes);
|
||||
|
||||
return payload;
|
||||
}
|
||||
|
||||
private static NBTTagCompound generateGroup(BookmarkGroup group) {
|
||||
final NBTTagCompound groupTag = new NBTTagCompound();
|
||||
final NBTTagList collapsedRecipes = new NBTTagList();
|
||||
|
||||
groupTag.setString("viewmode", group.viewMode.toString());
|
||||
groupTag.setBoolean("crafting", group.crafting != null);
|
||||
groupTag.setBoolean("collapsed", group.collapsed);
|
||||
|
||||
for (RecipeId recipeId : group.collapsedRecipes) {
|
||||
collapsedRecipes.appendTag(NBTJson.toNbt(recipeId.toJsonObject()));
|
||||
}
|
||||
|
||||
groupTag.setTag("collapsedRecipes", collapsedRecipes);
|
||||
|
||||
return groupTag;
|
||||
}
|
||||
|
||||
private static void addBookmarkItemToPayload(BookmarkPayload payload, BookmarkItem item,
|
||||
Map<RecipeId, Integer> recipesIndexes) {
|
||||
final JsonObject itemTag = item.toJsonObject();
|
||||
itemTag.remove("groupId");
|
||||
|
||||
if (item.recipeId != null) {
|
||||
final int recipeIndex = recipesIndexes
|
||||
.computeIfAbsent(item.recipeId, recipeId -> addRecipeToPayload(payload, recipeId, recipesIndexes));
|
||||
itemTag.addProperty("recipeId", recipeIndex);
|
||||
}
|
||||
|
||||
payload.items.appendTag(NBTJson.toNbt(itemTag));
|
||||
}
|
||||
|
||||
private static int addRecipeToPayload(BookmarkPayload payload, RecipeId recipeId,
|
||||
Map<RecipeId, Integer> recipesIndexes) {
|
||||
final NBTTagCompound recipeTag = new NBTTagCompound();
|
||||
final int recipeIndex = payload.recipes.tagCount();
|
||||
|
||||
recipeTag.setTag("recipeId", NBTJson.toNbt(recipeId.toJsonObject()));
|
||||
recipeTag.setInteger("recipeIndex", recipeIndex);
|
||||
payload.recipes.appendTag(recipeTag);
|
||||
|
||||
return recipeIndex;
|
||||
}
|
||||
|
||||
public NBTTagCompound toNBT() {
|
||||
final NBTTagCompound payloadTag = new NBTTagCompound();
|
||||
payloadTag.setString("linkType", linkType);
|
||||
|
||||
if (target != null) {
|
||||
payloadTag.setTag("item", target);
|
||||
}
|
||||
|
||||
if (group != null) {
|
||||
payloadTag.setTag("group", group);
|
||||
}
|
||||
|
||||
payloadTag.setTag("items", items);
|
||||
payloadTag.setTag("recipes", recipes);
|
||||
|
||||
return payloadTag;
|
||||
}
|
||||
|
||||
public String getLinkType() {
|
||||
return this.linkType;
|
||||
}
|
||||
|
||||
public ItemStack getTargetStack() {
|
||||
return this.target != null ? StackInfo.loadFromNBT(this.target) : null;
|
||||
}
|
||||
|
||||
public BookmarkGroup getGroup() {
|
||||
if (this.group == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
final boolean crafting = this.group.hasKey("crafting") && this.group.getBoolean("crafting");
|
||||
final BookmarkViewMode viewMode;
|
||||
|
||||
if (this.group.hasKey("viewmode")) {
|
||||
viewMode = BookmarkViewMode.valueOf(this.group.getString("viewmode"));
|
||||
} else {
|
||||
viewMode = BookmarkViewMode.TODO_LIST;
|
||||
}
|
||||
|
||||
final BookmarkGroup group = new BookmarkGroup(viewMode, crafting);
|
||||
|
||||
if (this.group.hasKey("collapsed")) {
|
||||
group.collapsed = this.group.getBoolean("collapsed");
|
||||
}
|
||||
|
||||
if (this.group.hasKey("collapsedRecipes")) {
|
||||
final NBTTagList collapsedRecipes = this.group.getTagList("collapsedRecipes", 10);
|
||||
|
||||
for (int i = 0; i < collapsedRecipes.tagCount(); i++) {
|
||||
final NBTTagCompound recipeTag = collapsedRecipes.getCompoundTagAt(i);
|
||||
final RecipeId recipeId = RecipeId.of((JsonObject) NBTJson.toJsonObject(recipeTag));
|
||||
group.collapsedRecipes.add(recipeId);
|
||||
}
|
||||
}
|
||||
|
||||
return group;
|
||||
}
|
||||
|
||||
public List<BookmarkItem> getBookmarkItems(int groupId) {
|
||||
final List<BookmarkItem> bookmarkItems = new ArrayList<>();
|
||||
final Map<Integer, RecipeId> recipesMap = new HashMap<>();
|
||||
|
||||
for (int i = 0; i < recipes.tagCount(); i++) {
|
||||
final NBTTagCompound recipeTag = recipes.getCompoundTagAt(i);
|
||||
final RecipeId recipeId = RecipeId
|
||||
.of((JsonObject) NBTJson.toJsonObject(recipeTag.getCompoundTag("recipeId")));
|
||||
recipesMap.put(recipeTag.getInteger("recipeIndex"), recipeId);
|
||||
}
|
||||
|
||||
for (int i = 0; i < items.tagCount(); i++) {
|
||||
final NBTTagCompound itemTag = items.getCompoundTagAt(i);
|
||||
RecipeId recipeId = null;
|
||||
|
||||
if (itemTag.hasKey("recipeId")) {
|
||||
recipeId = recipesMap.get(itemTag.getInteger("recipeId"));
|
||||
itemTag.removeTag("recipeId");
|
||||
}
|
||||
|
||||
final BookmarkItem item = BookmarkItem.of((JsonObject) NBTJson.toJsonObject(itemTag));
|
||||
|
||||
if (item != null) {
|
||||
item.groupId = groupId;
|
||||
item.recipeId = recipeId;
|
||||
bookmarkItems.add(item);
|
||||
}
|
||||
}
|
||||
|
||||
return bookmarkItems;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -10,7 +10,6 @@ import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.nbt.NBTTagCompound;
|
||||
|
||||
import org.apache.commons.io.IOUtils;
|
||||
@@ -25,9 +24,7 @@ import com.google.gson.JsonSyntaxException;
|
||||
|
||||
import codechicken.nei.BookmarkPanel.BookmarkViewMode;
|
||||
import codechicken.nei.NEIClientConfig;
|
||||
import codechicken.nei.bookmark.BookmarkItem.BookmarkItemType;
|
||||
import codechicken.nei.recipe.Recipe.RecipeId;
|
||||
import codechicken.nei.recipe.StackInfo;
|
||||
import codechicken.nei.util.NBTJson;
|
||||
|
||||
public class BookmarkStorage {
|
||||
@@ -198,7 +195,11 @@ public class BookmarkStorage {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!addItemToGrid(grid, parser.parse(itemStr).getAsJsonObject())) {
|
||||
final BookmarkItem item = BookmarkItem.of(parser.parse(itemStr).getAsJsonObject());
|
||||
|
||||
if (item != null) {
|
||||
grid.addItem(item, false);
|
||||
} else {
|
||||
wasError = true;
|
||||
NEIClientConfig.logger.warn(
|
||||
"Failed to load bookmarked ItemStack from json string, the item no longer exists:\n{}",
|
||||
@@ -237,47 +238,6 @@ public class BookmarkStorage {
|
||||
this.bookmarkFile = bookmarkFile;
|
||||
}
|
||||
|
||||
private boolean addItemToGrid(BookmarkGrid grid, JsonObject jsonObject) {
|
||||
NBTTagCompound itemStackNBT;
|
||||
|
||||
if (jsonObject.get("item") != null) {
|
||||
itemStackNBT = (NBTTagCompound) NBTJson.toNbt(jsonObject.get("item"));
|
||||
} else { // old format
|
||||
itemStackNBT = (NBTTagCompound) NBTJson.toNbt(jsonObject);
|
||||
}
|
||||
|
||||
ItemStack itemStack = StackInfo.loadFromNBT(itemStackNBT);
|
||||
|
||||
if (itemStack != null) {
|
||||
RecipeId recipeId = null;
|
||||
boolean isFluid = itemStackNBT.hasKey("gtFluidName");
|
||||
int groupId = jsonObject.has("groupId") ? jsonObject.get("groupId").getAsInt()
|
||||
: BookmarkGrid.DEFAULT_GROUP_ID;
|
||||
int factor = jsonObject.has("factor") ? Math.abs(jsonObject.get("factor").getAsInt()) : (isFluid ? 144 : 1);
|
||||
BookmarkItemType type = jsonObject.has("type") ? BookmarkItemType.fromInt(jsonObject.get("type").getAsInt())
|
||||
: null;
|
||||
|
||||
if (type == null) {
|
||||
// old format
|
||||
type = jsonObject.has("ingredient") && jsonObject.get("ingredient").getAsBoolean()
|
||||
? BookmarkItemType.INGREDIENT
|
||||
: BookmarkItemType.RESULT;
|
||||
}
|
||||
|
||||
if (jsonObject.get("recipeId") instanceof JsonObject recipeJson) {
|
||||
recipeId = RecipeId.of(recipeJson);
|
||||
}
|
||||
|
||||
if (!grid.groups.containsKey(groupId)) {
|
||||
groupId = BookmarkGrid.DEFAULT_GROUP_ID;
|
||||
}
|
||||
|
||||
grid.addItem(BookmarkItem.of(groupId, itemStack, factor, recipeId, type), false);
|
||||
}
|
||||
|
||||
return itemStack != null;
|
||||
}
|
||||
|
||||
public void save() {
|
||||
|
||||
if (this.bookmarkFile == null) {
|
||||
@@ -318,21 +278,7 @@ public class BookmarkStorage {
|
||||
|
||||
for (BookmarkItem item : grid.bookmarkItems) {
|
||||
try {
|
||||
JsonObject row = new JsonObject();
|
||||
|
||||
row.add("item", NBTJson.toJsonObject(StackInfo.itemStackToNBT(item.getItemStack())));
|
||||
row.add("factor", new JsonPrimitive(item.getFactor()));
|
||||
row.add("type", new JsonPrimitive(item.type.toInt()));
|
||||
|
||||
if (item.groupId != BookmarkGrid.DEFAULT_GROUP_ID) {
|
||||
row.add("groupId", new JsonPrimitive(item.groupId));
|
||||
}
|
||||
|
||||
if (item.recipeId != null) {
|
||||
row.add("recipeId", item.recipeId.toJsonObject());
|
||||
}
|
||||
|
||||
strings.add(NBTJson.toJson(row));
|
||||
strings.add(NBTJson.toJson(item.toJsonObject()));
|
||||
} catch (JsonSyntaxException e) {
|
||||
NEIClientConfig.logger.error("Failed to stringify bookmarked ItemStack to json string");
|
||||
}
|
||||
|
||||
@@ -14,6 +14,7 @@ import codechicken.nei.ItemsGrid.MouseContext;
|
||||
import codechicken.nei.NEIClientConfig;
|
||||
import codechicken.nei.NEIClientUtils;
|
||||
import codechicken.nei.NEIClientUtils.Alignment;
|
||||
import codechicken.nei.PositionedStack;
|
||||
import codechicken.nei.bookmark.BookmarkGrid.BookmarkMouseContext;
|
||||
import codechicken.nei.bookmark.BookmarkItem.BookmarkItemType;
|
||||
import codechicken.nei.bookmark.RecipeChainDetails.CalculatedType;
|
||||
@@ -63,18 +64,18 @@ public class BookmarksGridSlot extends ItemsGridSlot {
|
||||
protected final boolean isFirstOutput;
|
||||
protected final int rowIndex;
|
||||
|
||||
public BookmarksGridSlot(int slotIndex, int itemIndex, long realAmount, long shiftAmount, long calculatedAmount,
|
||||
BookmarkItem bookmarkItem, CalculatedType calculatedType, BookmarkGroup group) {
|
||||
public BookmarksGridSlot(int slotIndex, int itemIndex, long realMultiplier, long shiftAmount,
|
||||
long calculatedMultiplier, BookmarkItem bookmarkItem, CalculatedType calculatedType, BookmarkGroup group) {
|
||||
super(
|
||||
slotIndex,
|
||||
itemIndex,
|
||||
calculatedType != null ? bookmarkItem.getItemStack(calculatedAmount)
|
||||
: bookmarkItem.getItemStack(realAmount));
|
||||
calculatedType != null ? bookmarkItem.getItemStack(bookmarkItem.getAmount(calculatedMultiplier))
|
||||
: bookmarkItem.getItemStack(bookmarkItem.getAmount(realMultiplier)));
|
||||
|
||||
this.emptyItemStack = bookmarkItem.getItemStack(0);
|
||||
this.realAmount = realAmount;
|
||||
this.realAmount = bookmarkItem.getAmount(realMultiplier);
|
||||
this.shiftAmount = shiftAmount;
|
||||
this.calculatedAmount = calculatedAmount;
|
||||
this.calculatedAmount = calculatedType != null ? bookmarkItem.getAmount(calculatedMultiplier) : this.realAmount;
|
||||
|
||||
this.group = group;
|
||||
this.calculatedType = calculatedType;
|
||||
@@ -83,8 +84,8 @@ public class BookmarksGridSlot extends ItemsGridSlot {
|
||||
this.isOutputRecipe = group.crafting != null && group.crafting.outputRecipes.contains(bookmarkItem.recipeId);
|
||||
this.isFluidDisplay = StackInfo.itemStackToNBT(bookmarkItem.itemStack).hasKey("gtFluidName");
|
||||
|
||||
this.realMultiplier = bookmarkItem.getMultiplier(realAmount);
|
||||
this.calculatedMultiplier = bookmarkItem.getMultiplier(calculatedAmount);
|
||||
this.realMultiplier = realMultiplier;
|
||||
this.calculatedMultiplier = calculatedMultiplier;
|
||||
|
||||
if (this.group.crafting != null && this.group.crafting.calculatedItems.containsKey(this.itemIndex)) {
|
||||
this.realType = this.group.crafting.calculatedItems.get(this.itemIndex).calculatedType
|
||||
@@ -192,7 +193,7 @@ public class BookmarksGridSlot extends ItemsGridSlot {
|
||||
|
||||
protected HandlerInfo getHandlerInfo() {
|
||||
if (this.bookmarkItem.recipeId != null && this.handlerInfo == null) {
|
||||
this.handlerInfo = GuiRecipeTab.getHandlerInfo(this.bookmarkItem.recipeId.getHandleName(), null);
|
||||
this.handlerInfo = GuiRecipeTab.getHandlerInfo(this.bookmarkItem.recipeId.getHandlerName(), null);
|
||||
}
|
||||
return this.handlerInfo;
|
||||
}
|
||||
@@ -347,17 +348,22 @@ public class BookmarksGridSlot extends ItemsGridSlot {
|
||||
}
|
||||
|
||||
protected void drawStackSize(Rectangle4i rect, ShownItemType shownItemType) {
|
||||
boolean drawChance = this.calculatedMultiplier > 0;
|
||||
long amount = this.calculatedAmount;
|
||||
|
||||
if (shownItemType == null || shownItemType == ShownItemType.REAL || this.calculatedType == null) {
|
||||
amount = this.realAmount;
|
||||
drawChance = this.realMultiplier > 0;
|
||||
} else if (shownItemType == ShownItemType.SHIFT) {
|
||||
amount = this.shiftAmount;
|
||||
drawChance = false;
|
||||
}
|
||||
|
||||
if (amount > 0 || shownItemType == ShownItemType.REAL && this.bookmarkItem.factor > 0) {
|
||||
if (amount > 0 || this.bookmarkItem.chance != PositionedStack.CHANCE_FULL && drawChance
|
||||
|| shownItemType == ShownItemType.REAL && !this.bookmarkItem.emptyFactor()) {
|
||||
final float panelFactor = (rect.w - 2) / (DEFAULT_SLOT_SIZE - 2);
|
||||
final long stackSize = this.bookmarkItem.getStackSize(amount);
|
||||
int color = 0xFFFFFF;
|
||||
String amountString = "";
|
||||
|
||||
if (stackSize < 10_000) {
|
||||
@@ -370,11 +376,16 @@ public class BookmarksGridSlot extends ItemsGridSlot {
|
||||
amountString += "L";
|
||||
}
|
||||
|
||||
if (this.bookmarkItem.chance != PositionedStack.CHANCE_FULL) {
|
||||
amountString = "~" + amountString;
|
||||
color = 0xFFAA00;
|
||||
}
|
||||
|
||||
NEIClientUtils.drawNEIOverlayText(
|
||||
amountString,
|
||||
new Rectangle4i(rect.x + 1, rect.y + 1, rect.w - 2, rect.h - 2),
|
||||
panelFactor,
|
||||
0xFFFFFF,
|
||||
color,
|
||||
true,
|
||||
this.isFluidDisplay ? Alignment.BottomLeft : Alignment.BottomRight);
|
||||
}
|
||||
|
||||
@@ -42,34 +42,35 @@ public class RecipeChainDetails {
|
||||
|
||||
private final BookmarkItem item;
|
||||
|
||||
private long realAmount = 0L;
|
||||
private long realMultiplier = 0L;
|
||||
private long shiftAmount = 0L;
|
||||
private long calculatedAmount = 0L;
|
||||
private long calculatedMultiplier = 0L;
|
||||
|
||||
public CalculatedType calculatedType;
|
||||
|
||||
protected BookmarkChainItem(BookmarkItem item, long shiftItem, long calculatedItem,
|
||||
protected BookmarkChainItem(BookmarkItem item, long shiftItem, long calculatedMultiplier,
|
||||
CalculatedType calculatedType) {
|
||||
this.item = item.copy();
|
||||
this.shiftAmount = shiftItem;
|
||||
this.calculatedAmount = calculatedItem;
|
||||
this.calculatedMultiplier = calculatedMultiplier;
|
||||
this.calculatedType = calculatedType;
|
||||
}
|
||||
|
||||
public static BookmarkChainItem of(BookmarkItem item, long shiftItem, long calculatedAmount,
|
||||
public static BookmarkChainItem of(BookmarkItem item, long shiftItem, long calculatedMultiplier,
|
||||
CalculatedType calculatedType) {
|
||||
return new BookmarkChainItem(item, shiftItem, calculatedAmount, calculatedType);
|
||||
return new BookmarkChainItem(item, shiftItem, calculatedMultiplier, calculatedType);
|
||||
}
|
||||
|
||||
public static BookmarkChainItem of(BookmarkItem item, long shiftItem, CalculatedType calculatedType) {
|
||||
return new BookmarkChainItem(item, shiftItem, item.amount, calculatedType);
|
||||
return new BookmarkChainItem(item, shiftItem, item.getMultiplier(), calculatedType);
|
||||
}
|
||||
|
||||
public static BookmarkChainItem of(BookmarkItem item) {
|
||||
final long amount = item.getAmount();
|
||||
return new BookmarkChainItem(
|
||||
item,
|
||||
item.amount,
|
||||
item.amount,
|
||||
amount,
|
||||
item.getMultiplier(),
|
||||
item.type == BookmarkItemType.INGREDIENT ? CalculatedType.INGREDIENT : CalculatedType.RESULT);
|
||||
}
|
||||
|
||||
@@ -77,30 +78,34 @@ public class RecipeChainDetails {
|
||||
return this.item.getItemStack(amount);
|
||||
}
|
||||
|
||||
public void setRealAmount(long amount) {
|
||||
this.realAmount = amount;
|
||||
public void setRealMultiplier(long multiplier) {
|
||||
this.realMultiplier = multiplier;
|
||||
}
|
||||
|
||||
public long getRealAmount() {
|
||||
return this.realAmount;
|
||||
public long getRealMultiplier() {
|
||||
return this.realMultiplier;
|
||||
}
|
||||
|
||||
public void setCalculatedMultiplier(long multiplier) {
|
||||
this.calculatedMultiplier = multiplier;
|
||||
}
|
||||
|
||||
public long getCalculatedMultiplier() {
|
||||
return this.calculatedMultiplier;
|
||||
}
|
||||
|
||||
public long getShiftAmount() {
|
||||
return this.shiftAmount;
|
||||
}
|
||||
|
||||
public long getCalculatedAmount() {
|
||||
return this.calculatedAmount;
|
||||
}
|
||||
|
||||
public BookmarkItem getItem() {
|
||||
return this.item;
|
||||
}
|
||||
|
||||
public void append(long amount, long calculatedAmount) {
|
||||
this.shiftAmount += amount;
|
||||
this.calculatedAmount += calculatedAmount;
|
||||
this.item.amount = this.calculatedAmount;
|
||||
this.calculatedMultiplier += this.item.getMultiplierFromAmount(calculatedAmount);
|
||||
this.item.multiplier = this.calculatedMultiplier;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -180,10 +185,9 @@ public class RecipeChainDetails {
|
||||
if (itemIndex >= 0 && this.calculatedItems.containsKey(itemIndex)) {
|
||||
final BookmarkItem item = entry.getValue();
|
||||
if (this.recipeInMiddle.contains(item.recipeId)) {
|
||||
this.calculatedItems.get(itemIndex)
|
||||
.setRealAmount(Math.max(0, item.factor * (item.getMultiplier() - 1)));
|
||||
this.calculatedItems.get(itemIndex).setRealMultiplier(Math.max(0, item.getMultiplier() - 1));
|
||||
} else {
|
||||
this.calculatedItems.get(itemIndex).setRealAmount(item.amount);
|
||||
this.calculatedItems.get(itemIndex).setRealMultiplier(item.getMultiplier());
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -239,7 +243,7 @@ public class RecipeChainDetails {
|
||||
|
||||
for (BookmarkItem item : chainItems) {
|
||||
if (recipeRelations.contains(item.recipeId)) {
|
||||
subChainItems.add(item.copyWithAmount(recipeId.equals(item.recipeId) ? item.amount : 0));
|
||||
subChainItems.add(item.copyWithMultiplier(recipeId.equals(item.recipeId) ? item.multiplier : 0));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -258,7 +262,8 @@ public class RecipeChainDetails {
|
||||
}
|
||||
|
||||
if (this.calculatedItems.containsKey(itemIndex)) {
|
||||
this.calculatedItems.get(itemIndex).setRealAmount(value.getShiftAmount());
|
||||
this.calculatedItems.get(itemIndex)
|
||||
.setRealMultiplier(value.getItem().getMultiplierFromAmount(value.getShiftAmount()));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -272,18 +277,19 @@ public class RecipeChainDetails {
|
||||
for (RecipeId relRecipeId : recipeRelations) {
|
||||
for (BookmarkItem item : math.recipeResults) {
|
||||
if (item.recipeId.equals(relRecipeId)) {
|
||||
final long amount = item.amount - math.requiredAmount.getOrDefault(item, 0L);
|
||||
final long amount = item.getAmount() - math.requiredAmount.getOrDefault(item, 0L);
|
||||
|
||||
if (item.recipeId.equals(recipeId)) {
|
||||
multiplier.put(item.recipeId, item.getMultiplier());
|
||||
items.computeIfAbsent(
|
||||
StackInfo.getItemStackGUID(item.itemStack),
|
||||
is -> BookmarkChainItem.of(item, 0, 0, CalculatedType.RESULT))
|
||||
.append(amount, item.amount);
|
||||
.append(amount, item.getAmount());
|
||||
} else if (amount > 0) {
|
||||
items.computeIfAbsent(
|
||||
StackInfo.getItemStackGUID(item.itemStack),
|
||||
is -> BookmarkChainItem.of(item, 0, 0, CalculatedType.RESULT)).append(amount, amount);
|
||||
is -> BookmarkChainItem.of(item, 0, 0, CalculatedType.RESULT))
|
||||
.append(amount, item.getAmount());
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -292,17 +298,17 @@ public class RecipeChainDetails {
|
||||
if (item.recipeId.equals(relRecipeId)) {
|
||||
final BookmarkItem prefItem = math.preferredItems.get(item);
|
||||
final long amount = math.requiredAmount.containsKey(prefItem) ? 0
|
||||
: math.requiredAmount.getOrDefault(item, item.amount);
|
||||
: math.requiredAmount.getOrDefault(item, item.getAmount());
|
||||
final long refAmount = prefItem != null && !topLevelRecipes.contains(prefItem.recipeId)
|
||||
? math.requiredAmount.getOrDefault(prefItem, 0L)
|
||||
: 0;
|
||||
|
||||
if (amount != 0 || item.amount > refAmount && math.requiredAmount.containsKey(prefItem)
|
||||
if (amount != 0 || item.getAmount() > refAmount && math.requiredAmount.containsKey(prefItem)
|
||||
|| recipeId.equals(item.recipeId) && multiplier.get(recipeId) == 0) {
|
||||
items.computeIfAbsent(
|
||||
StackInfo.getItemStackGUID(item.itemStack),
|
||||
is -> BookmarkChainItem.of(item, 0, 0, CalculatedType.INGREDIENT))
|
||||
.append(amount, item.amount - refAmount);
|
||||
.append(amount, item.getAmount() - refAmount);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -312,7 +318,7 @@ public class RecipeChainDetails {
|
||||
}
|
||||
|
||||
private void generateResult(RecipeChainMath math, BookmarkItem item, int itemIndex) {
|
||||
final long amount = item.amount - math.requiredAmount.getOrDefault(item, 0L);
|
||||
final long amount = item.getAmount() - math.requiredAmount.getOrDefault(item, 0L);
|
||||
final CalculatedType calculatedType = math.outputRecipes.containsKey(item.recipeId) ? CalculatedType.RESULT
|
||||
: CalculatedType.REMAINDER;
|
||||
|
||||
@@ -322,7 +328,7 @@ public class RecipeChainDetails {
|
||||
private void generateIngredient(RecipeChainMath math, BookmarkItem item, int itemIndex) {
|
||||
final BookmarkItem prefItem = math.preferredItems.get(item);
|
||||
final long amount = math.requiredAmount.containsKey(prefItem) ? 0
|
||||
: math.requiredAmount.getOrDefault(item, item.amount);
|
||||
: math.requiredAmount.getOrDefault(item, item.getAmount());
|
||||
|
||||
this.calculatedItems.put(itemIndex, BookmarkChainItem.of(item, amount, CalculatedType.INGREDIENT));
|
||||
}
|
||||
|
||||
@@ -1,18 +1,39 @@
|
||||
package codechicken.nei.commands;
|
||||
|
||||
import java.util.Arrays;
|
||||
|
||||
import net.minecraft.command.CommandBase;
|
||||
import net.minecraft.command.ICommandSender;
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.nbt.JsonToNBT;
|
||||
import net.minecraft.nbt.NBTException;
|
||||
import net.minecraft.nbt.NBTTagCompound;
|
||||
import net.minecraft.util.ChatComponentText;
|
||||
import net.minecraft.util.ChatComponentTranslation;
|
||||
|
||||
import codechicken.nei.ItemPanels;
|
||||
import codechicken.nei.LRUCache;
|
||||
import codechicken.nei.bookmark.BookmarkGrid;
|
||||
import codechicken.nei.bookmark.BookmarkGroup;
|
||||
import codechicken.nei.bookmark.BookmarkPayload;
|
||||
|
||||
public class CommandBookmarkAdd extends CommandBase {
|
||||
|
||||
private static final LRUCache<String, NBTTagCompound> PAYLOAD_CACHE = new LRUCache<>(64);
|
||||
|
||||
public static void cachePayload(String payloadId, NBTTagCompound payload) {
|
||||
if (payloadId == null || payloadId.isEmpty() || payload == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
synchronized (PAYLOAD_CACHE) {
|
||||
PAYLOAD_CACHE.put(payloadId, (NBTTagCompound) payload.copy());
|
||||
}
|
||||
}
|
||||
|
||||
private static NBTTagCompound getCachedPayload(String payloadId) {
|
||||
synchronized (PAYLOAD_CACHE) {
|
||||
return PAYLOAD_CACHE.get(payloadId);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getCommandName() {
|
||||
return "nei_bookmark";
|
||||
@@ -20,7 +41,7 @@ public class CommandBookmarkAdd extends CommandBase {
|
||||
|
||||
@Override
|
||||
public String getCommandUsage(ICommandSender sender) {
|
||||
return "/nei_bookmark <nbt>";
|
||||
return "/nei_bookmark <payloadId>";
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -30,19 +51,37 @@ public class CommandBookmarkAdd extends CommandBase {
|
||||
|
||||
@Override
|
||||
public void processCommand(ICommandSender sender, String[] args) {
|
||||
|
||||
if (args.length < 1 || args[0].length() < 3) {
|
||||
sender.addChatMessage(new ChatComponentText("§c/nei_bookmark <nbt>"));
|
||||
if (args.length < 1) {
|
||||
sender.addChatMessage(new ChatComponentText("§c/nei_bookmark <payloadId>"));
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
ItemPanels.bookmarkPanel.addItem(
|
||||
ItemStack.loadItemStackFromNBT((NBTTagCompound) JsonToNBT.func_150315_a(String.join(" ", args))));
|
||||
final String payloadId = String.join(" ", Arrays.copyOfRange(args, 0, args.length));
|
||||
final NBTTagCompound payload = getCachedPayload(payloadId);
|
||||
|
||||
if (payload == null) {
|
||||
throw new IllegalArgumentException("Missing cached payload");
|
||||
}
|
||||
|
||||
addBookmarkFromPayload((NBTTagCompound) payload.copy());
|
||||
sender.addChatMessage(new ChatComponentTranslation("nei.chat.bookmark_added.text"));
|
||||
} catch (NBTException e) {
|
||||
} catch (Exception e) {
|
||||
sender.addChatMessage(new ChatComponentText(e.toString()));
|
||||
}
|
||||
}
|
||||
|
||||
private static void addBookmarkFromPayload(NBTTagCompound nbt) {
|
||||
final BookmarkPayload payload = BookmarkPayload.of(nbt);
|
||||
final BookmarkGrid grid = ItemPanels.bookmarkPanel.getGrid();
|
||||
final BookmarkGroup group = payload.getGroup();
|
||||
int groupId = BookmarkGrid.DEFAULT_GROUP_ID;
|
||||
|
||||
if (group != null) {
|
||||
groupId = grid.addGroup(group);
|
||||
}
|
||||
|
||||
payload.getBookmarkItems(groupId).forEach(item -> grid.addItem(item, true));
|
||||
}
|
||||
|
||||
}
|
||||
@@ -8,13 +8,15 @@ import java.io.IOException;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.nio.file.Files;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.TreeMap;
|
||||
import java.util.TreeSet;
|
||||
import java.util.concurrent.ExecutionException;
|
||||
import java.util.concurrent.atomic.AtomicInteger;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import net.minecraft.command.CommandBase;
|
||||
@@ -39,6 +41,7 @@ import codechicken.nei.recipe.GuiRecipeTab;
|
||||
import codechicken.nei.recipe.ICraftingHandler;
|
||||
import codechicken.nei.recipe.Recipe;
|
||||
import codechicken.nei.recipe.RecipeHandlerQuery;
|
||||
import codechicken.nei.recipe.TemplateRecipeHandler;
|
||||
import codechicken.nei.util.NBTJson;
|
||||
|
||||
public class CommandRecipeId extends CommandBase {
|
||||
@@ -125,12 +128,16 @@ public class CommandRecipeId extends CommandBase {
|
||||
|
||||
private ArrayList<ICraftingHandler> craftinghandlers = new ArrayList<>();
|
||||
private ArrayList<ICraftingHandler> serialCraftingHandlers = new ArrayList<>();
|
||||
|
||||
protected final ICommandSender sender;
|
||||
protected final File currFile;
|
||||
protected final boolean fastDump;
|
||||
|
||||
public ProcessDumpThread(ICommandSender sender, File currFile) {
|
||||
public ProcessDumpThread(ICommandSender sender, File currFile, boolean fastDump) {
|
||||
this.sender = sender;
|
||||
this.currFile = currFile;
|
||||
this.fastDump = fastDump;
|
||||
|
||||
ClientHandler.loadSettingsFile("recipeidblacklist.cfg", lines -> {
|
||||
final Set<String> names = lines.collect(Collectors.toSet());
|
||||
|
||||
@@ -150,38 +157,10 @@ public class CommandRecipeId extends CommandBase {
|
||||
sendChatInfoMessage(sender, "nei.chat.recipeid.dump.start");
|
||||
|
||||
try (BufferedWriter writer = Files.newBufferedWriter(currFile.toPath(), StandardCharsets.UTF_8)) {
|
||||
int total = ItemList.items.size();
|
||||
int count = 0;
|
||||
|
||||
for (ItemStack stack : ItemList.items) {
|
||||
|
||||
if (count % 1000 == 0) {
|
||||
NEIClientConfig.logger.info(
|
||||
"({}/{}). Processing {} crafting recipes...",
|
||||
count,
|
||||
total,
|
||||
stack.getDisplayName());
|
||||
}
|
||||
|
||||
count++;
|
||||
|
||||
for (ICraftingHandler handler : getCraftingHandlers(stack)) {
|
||||
for (int index = 0, num = handler.numRecipes(); index < num; index++) {
|
||||
try {
|
||||
final Recipe recipe = Recipe.of(handler, index);
|
||||
if (!recipe.getIngredients().isEmpty() && !recipe.getResults().isEmpty()) {
|
||||
writer.write(NBTJson.toJson(recipe.getRecipeId().toJsonObject()));
|
||||
writer.newLine();
|
||||
}
|
||||
} catch (Exception ex) {
|
||||
NEIClientConfig.logger.error(
|
||||
"Found Broken RecipeId {}:{}",
|
||||
GuiRecipeTab.getHandlerInfo(handler).getHandlerName(),
|
||||
stack,
|
||||
ex);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (fastDump) {
|
||||
processFastDump(writer);
|
||||
} else {
|
||||
processDump(writer);
|
||||
}
|
||||
|
||||
} catch (Exception e) {
|
||||
@@ -192,15 +171,118 @@ public class CommandRecipeId extends CommandBase {
|
||||
sendChatInfoMessage(sender, "nei.chat.recipeid.dump.finish");
|
||||
}
|
||||
|
||||
/**
|
||||
* + technically more reliable and supports some weird handlers
|
||||
* <p>
|
||||
* - very very very slow, took 1 hour to get a dump in GTNH on M1 in background
|
||||
* <p>
|
||||
* - generates a lot of duplicates, up to 75% of file size is duplicates (and it's 300mb out of 400mb...)
|
||||
*/
|
||||
private void processDump(BufferedWriter writer) throws IOException {
|
||||
final int total = ItemList.items.size();
|
||||
int count = 0;
|
||||
|
||||
for (ItemStack stack : ItemList.items) {
|
||||
if (count % 1000 == 0) {
|
||||
NEIClientConfig.logger
|
||||
.info("({}/{}). Processing {} crafting recipes...", count, total, stack.getDisplayName());
|
||||
}
|
||||
|
||||
count++;
|
||||
|
||||
for (ICraftingHandler handler : getCraftingHandlers(stack)) {
|
||||
writeLines(writer, collectRecipeLines(handler, stack.toString()));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* - may skip some handlers if they're not TemplateRecipeHandler / just weird ones (like gendustry handlers)
|
||||
* <p>
|
||||
* + but in terms of GT recipes everything is dumped, and surprisingly it catches even more GT recipes than the
|
||||
* regular dumper (in particular, it has a lot of new hammer, extruder, blast furnace, etc. recipes)
|
||||
* <p>
|
||||
* + way faster, took like 2.5 minutes
|
||||
* <p>
|
||||
* + doesn't have nearly as many duplicates, but something can still slip in, for example from
|
||||
* FuelRecipeHandler. The dump has a size of only 100 MB instead of 400 MB from the regular dumper
|
||||
*/
|
||||
private void processFastDump(BufferedWriter writer) throws IOException {
|
||||
final ArrayList<ICraftingHandler> handlers = getCraftingHandlers();
|
||||
final int total = handlers.size();
|
||||
final AtomicInteger count = new AtomicInteger();
|
||||
|
||||
try {
|
||||
final List<List<String>> linesByHandler = ItemList.forkJoinPool.submit(() -> {
|
||||
return handlers.parallelStream().map(handler -> {
|
||||
final String handlerName = GuiRecipeTab.getHandlerInfo(handler).getHandlerName();
|
||||
final List<String> lines = collectRecipeLines(handler, handlerName);
|
||||
final int current = count.incrementAndGet();
|
||||
NEIClientConfig.logger
|
||||
.info("({}/{}). Processed {} handler recipes.", current, total, handlerName);
|
||||
return lines;
|
||||
}).collect(Collectors.toList());
|
||||
}).get();
|
||||
|
||||
for (List<String> lines : linesByHandler) {
|
||||
writeLines(writer, lines);
|
||||
}
|
||||
} catch (InterruptedException e) {
|
||||
Thread.currentThread().interrupt();
|
||||
throw new IOException("Interrupted while dumping RecipeId", e);
|
||||
} catch (ExecutionException e) {
|
||||
throw new IOException("Error while dumping RecipeId", e);
|
||||
}
|
||||
}
|
||||
|
||||
private List<String> collectRecipeLines(ICraftingHandler handler, String context) {
|
||||
final List<String> lines = new ArrayList<>(handler.numRecipes());
|
||||
|
||||
for (int index = 0, num = handler.numRecipes(); index < num; index++) {
|
||||
try {
|
||||
final Recipe recipe = Recipe.of(handler, index);
|
||||
if (!recipe.getIngredients().isEmpty() && !recipe.getResults().isEmpty()) {
|
||||
lines.add(NBTJson.toJson(recipe.getRecipeId().toJsonObject()));
|
||||
}
|
||||
} catch (Exception ex) {
|
||||
NEIClientConfig.logger.error(
|
||||
"Found Broken RecipeId {}:{}",
|
||||
GuiRecipeTab.getHandlerInfo(handler).getHandlerName(),
|
||||
context,
|
||||
ex);
|
||||
}
|
||||
}
|
||||
|
||||
return lines;
|
||||
}
|
||||
|
||||
private void writeLines(BufferedWriter writer, List<String> lines) throws IOException {
|
||||
for (String line : lines) {
|
||||
writer.write(line);
|
||||
writer.newLine();
|
||||
}
|
||||
}
|
||||
|
||||
private ArrayList<ICraftingHandler> getCraftingHandlers(Object... results) {
|
||||
return new RecipeHandlerQuery<>(
|
||||
h -> h.getRecipeHandler("item", results),
|
||||
handler -> handler.getRecipeHandler("item", results),
|
||||
this.craftinghandlers,
|
||||
this.serialCraftingHandlers,
|
||||
"Error while looking up crafting recipe",
|
||||
"outputId: item",
|
||||
"results: " + Arrays.toString(results))
|
||||
.runWithProfiling(NEIClientUtils.translate("recipe.concurrent.crafting"));
|
||||
"outputId: item").runWithProfiling(NEIClientUtils.translate("recipe.concurrent.crafting"));
|
||||
}
|
||||
|
||||
private ArrayList<ICraftingHandler> getCraftingHandlers() {
|
||||
return new RecipeHandlerQuery<>(handler -> {
|
||||
if (handler instanceof TemplateRecipeHandler templateHandler) {
|
||||
return templateHandler.getAllRecipeHandler();
|
||||
}
|
||||
return handler.getRecipeHandler("all");
|
||||
},
|
||||
this.craftinghandlers,
|
||||
this.serialCraftingHandlers,
|
||||
"Error while looking up crafting recipe",
|
||||
"outputId: all").runWithProfiling(NEIClientUtils.translate("recipe.concurrent.crafting"));
|
||||
}
|
||||
|
||||
}
|
||||
@@ -212,7 +294,7 @@ public class CommandRecipeId extends CommandBase {
|
||||
|
||||
@Override
|
||||
public String getCommandUsage(ICommandSender sender) {
|
||||
return "/recipeid dump <filename> OR /recipeid diff <prev-filename> <curr-filename> [subset name]";
|
||||
return "/recipeid [dump|fast-dump] <filename> OR /recipeid diff <prev-filename> <curr-filename> <subset name>";
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -220,12 +302,27 @@ public class CommandRecipeId extends CommandBase {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<String> addTabCompletionOptions(ICommandSender sender, String[] args) {
|
||||
if (args.length == 1) {
|
||||
return getListOfStringsMatchingLastWord(args, "dump", "fast-dump", "diff");
|
||||
}
|
||||
|
||||
if ("diff".equals(args[0]) && (args.length == 2 || args.length == 3)) {
|
||||
return getListOfStringsMatchingLastWord(args, getRecipeIdFilenames());
|
||||
}
|
||||
|
||||
return Collections.emptyList();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void processCommand(ICommandSender sender, String[] args) {
|
||||
final String command = args.length == 0 ? null : args[0];
|
||||
|
||||
if ("dump".equals(command)) {
|
||||
processDumpCommand(sender, args);
|
||||
processDumpCommand(sender, args, false);
|
||||
} else if ("fast-dump".equals(command)) {
|
||||
processDumpCommand(sender, args, true);
|
||||
} else if ("diff".equals(command)) {
|
||||
processDiffCommand(sender, args);
|
||||
} else {
|
||||
@@ -263,7 +360,7 @@ public class CommandRecipeId extends CommandBase {
|
||||
(new ProcessDiffThread(sender, prevFilename, currFilename, diffFilename)).start();
|
||||
}
|
||||
|
||||
protected void processDumpCommand(ICommandSender sender, String[] args) {
|
||||
protected void processDumpCommand(ICommandSender sender, String[] args, boolean fastDump) {
|
||||
|
||||
if (args.length > 2) {
|
||||
sendChatErrorMessage(sender, "nei.chat.recipeid.many_params", getCommandUsage(sender));
|
||||
@@ -274,13 +371,30 @@ public class CommandRecipeId extends CommandBase {
|
||||
final String currFilename = args.length == 2 ? args[1] : "recipeId";
|
||||
if (!dir.exists()) dir.mkdirs();
|
||||
|
||||
(new ProcessDumpThread(sender, getFile(currFilename))).start();
|
||||
(new ProcessDumpThread(sender, getFile(currFilename), fastDump)).start();
|
||||
}
|
||||
|
||||
private static File getFile(String filename) {
|
||||
return new File(CommonUtils.getMinecraftDir(), "recipeid/" + filename + ".json");
|
||||
}
|
||||
|
||||
private static String[] getRecipeIdFilenames() {
|
||||
final File dir = new File(CommonUtils.getMinecraftDir(), "recipeid");
|
||||
final File[] files = dir.listFiles((currentDir, name) -> name.endsWith(".json"));
|
||||
|
||||
if (files == null || files.length == 0) {
|
||||
return new String[] {};
|
||||
}
|
||||
|
||||
final String[] names = new String[files.length];
|
||||
for (int i = 0; i < files.length; i++) {
|
||||
final String name = files[i].getName();
|
||||
names[i] = name.substring(0, name.length() - ".json".length());
|
||||
}
|
||||
|
||||
return names;
|
||||
}
|
||||
|
||||
private static void sendChatInfoMessage(ICommandSender sender, String translationKey, Object... args) {
|
||||
sender.addChatMessage(
|
||||
new ChatComponentTranslation(translationKey, args)
|
||||
|
||||
@@ -92,8 +92,8 @@ public abstract class DataDumper extends Option {
|
||||
}
|
||||
|
||||
public Rectangle4i dumpButtonSize() {
|
||||
int width = 80;
|
||||
return new Rectangle4i(slot.slotWidth() - width, 0, width, 20);
|
||||
int width = 50;
|
||||
return new Rectangle4i(getSlot().slotWidth() - width, 0, width, 20);
|
||||
}
|
||||
|
||||
public Rectangle4i modeButtonSize() {
|
||||
|
||||
@@ -18,6 +18,7 @@ import org.lwjgl.input.Keyboard;
|
||||
|
||||
import codechicken.core.gui.GuiCCButton;
|
||||
import codechicken.core.gui.GuiScreenWidget;
|
||||
import codechicken.lib.config.ConfigTag;
|
||||
import codechicken.lib.math.MathHelper;
|
||||
import codechicken.lib.vec.Rectangle4i;
|
||||
import codechicken.nei.HUDRenderer;
|
||||
@@ -27,12 +28,16 @@ public class GuiHighlightTips extends GuiScreenWidget {
|
||||
private final String name;
|
||||
private GuiCCButton toggleButton;
|
||||
private final Option opt;
|
||||
private final GuiOptionList parentGui;
|
||||
private final boolean world;
|
||||
private Point dragDown;
|
||||
|
||||
public GuiHighlightTips(Option opt) {
|
||||
super(80, 20);
|
||||
this.opt = opt;
|
||||
name = opt.name;
|
||||
this.parentGui = (GuiOptionList) Minecraft.getMinecraft().currentScreen;
|
||||
this.world = parentGui.worldConfig();
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -48,7 +53,7 @@ public class GuiHighlightTips extends GuiScreenWidget {
|
||||
@Override
|
||||
public void actionPerformed(String ident, Object... params) {
|
||||
if (ident.equals("show")) {
|
||||
opt.getTag(name).setBooleanValue(!show());
|
||||
getTag(name).setBooleanValue(!show());
|
||||
updateNames();
|
||||
}
|
||||
}
|
||||
@@ -58,13 +63,21 @@ public class GuiHighlightTips extends GuiScreenWidget {
|
||||
}
|
||||
|
||||
private boolean show() {
|
||||
return opt.renderTag(name).getBooleanValue();
|
||||
return renderTag(name).getBooleanValue();
|
||||
}
|
||||
|
||||
private ConfigTag getTag(String s) {
|
||||
return (world ? opt.worldConfigSet() : opt.globalConfigSet()).config.getTag(s);
|
||||
}
|
||||
|
||||
private ConfigTag renderTag(String s) {
|
||||
return (world && opt.worldSpecific(s) ? opt.worldConfigSet() : opt.globalConfigSet()).config.getTag(s);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void keyTyped(char c, int keycode) {
|
||||
if (keycode == Keyboard.KEY_ESCAPE || keycode == Keyboard.KEY_BACK) {
|
||||
Minecraft.getMinecraft().displayGuiScreen(opt.slot.getGui());
|
||||
Minecraft.getMinecraft().displayGuiScreen(parentGui);
|
||||
return;
|
||||
}
|
||||
super.keyTyped(c, keycode);
|
||||
@@ -82,7 +95,7 @@ public class GuiHighlightTips extends GuiScreenWidget {
|
||||
}
|
||||
|
||||
public Point getPos() {
|
||||
return new Point(opt.renderTag(name + ".x").getIntValue(), opt.renderTag(name + ".y").getIntValue());
|
||||
return new Point(renderTag(name + ".x").getIntValue(), renderTag(name + ".y").getIntValue());
|
||||
}
|
||||
|
||||
public Dimension sampleSize() // copied from HUDManager when running with the sample for this gui
|
||||
@@ -148,8 +161,8 @@ public class GuiHighlightTips extends GuiScreenWidget {
|
||||
}
|
||||
|
||||
private void setPos(Point p) {
|
||||
opt.getTag(name).setBooleanValue(show()); // duplicates global tag for the option gui if in world mode
|
||||
opt.getTag(name + ".x").setIntValue(p.x);
|
||||
opt.getTag(name + ".y").setIntValue(p.y);
|
||||
getTag(name).setBooleanValue(show()); // duplicates global tag for the option gui if in world mode
|
||||
getTag(name + ".x").setIntValue(p.x);
|
||||
getTag(name + ".y").setIntValue(p.y);
|
||||
}
|
||||
}
|
||||
@@ -43,6 +43,7 @@ public class GuiItemIconDumper extends GuiScreen {
|
||||
}
|
||||
|
||||
private Option opt;
|
||||
private final GuiOptionList parentGui;
|
||||
private int drawIndex;
|
||||
private int parseIndex;
|
||||
private final File dir = new File(CommonUtils.getMinecraftDir(), "dumps/itempanel_icons");
|
||||
@@ -52,6 +53,7 @@ public class GuiItemIconDumper extends GuiScreen {
|
||||
|
||||
public GuiItemIconDumper(Option opt, int iconSize) {
|
||||
this.opt = opt;
|
||||
this.parentGui = (GuiOptionList) Minecraft.getMinecraft().currentScreen;
|
||||
this.iconSize = iconSize;
|
||||
borderSize = iconSize / 16;
|
||||
boxSize = iconSize + borderSize * 2;
|
||||
@@ -62,7 +64,7 @@ public class GuiItemIconDumper extends GuiScreen {
|
||||
}
|
||||
|
||||
private void returnScreen(IChatComponent msg) {
|
||||
Minecraft.getMinecraft().displayGuiScreen(opt.slot.getGui());
|
||||
Minecraft.getMinecraft().displayGuiScreen(parentGui);
|
||||
NEIClientUtils.printChatMessage(msg);
|
||||
}
|
||||
|
||||
|
||||
@@ -7,11 +7,14 @@ import java.awt.Rectangle;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import net.minecraft.client.Minecraft;
|
||||
import net.minecraft.client.gui.GuiScreen;
|
||||
|
||||
import org.lwjgl.opengl.GL11;
|
||||
|
||||
import codechicken.lib.config.ConfigTag;
|
||||
import codechicken.lib.math.MathHelper;
|
||||
import codechicken.nei.ItemList;
|
||||
import codechicken.nei.ItemSorter;
|
||||
import codechicken.nei.ItemSorter.SortEntry;
|
||||
import codechicken.nei.LayoutManager;
|
||||
@@ -48,6 +51,8 @@ public class GuiItemSorter extends GuiOptionPane {
|
||||
public final Option opt;
|
||||
public final List<SortItem> slots = new ArrayList<>();
|
||||
public final List<SortEntry> list;
|
||||
private final GuiOptionList parentGui;
|
||||
private final boolean world;
|
||||
|
||||
boolean dragging;
|
||||
public SortItem dragged;
|
||||
@@ -56,7 +61,9 @@ public class GuiItemSorter extends GuiOptionPane {
|
||||
|
||||
public GuiItemSorter(Option opt) {
|
||||
this.opt = opt;
|
||||
list = ItemSorter.fromSaveString(opt.renderTag().getValue());
|
||||
this.parentGui = (GuiOptionList) Minecraft.getMinecraft().currentScreen;
|
||||
this.world = parentGui.worldConfig();
|
||||
list = ItemSorter.fromSaveString(renderTag(opt.configName()).getValue());
|
||||
for (SortEntry e : list) slots.add(new SortItem(e));
|
||||
}
|
||||
|
||||
@@ -98,7 +105,7 @@ public class GuiItemSorter extends GuiOptionPane {
|
||||
|
||||
@Override
|
||||
public GuiScreen getParentScreen() {
|
||||
return opt.slot.getGui();
|
||||
return parentGui;
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -114,16 +121,25 @@ public class GuiItemSorter extends GuiOptionPane {
|
||||
list.remove(dragged.e);
|
||||
list.add(nslot, dragged.e);
|
||||
|
||||
opt.getTag().setValue(ItemSorter.getSaveString(list));
|
||||
LayoutManager.markItemsDirty();
|
||||
getTag(opt.configName()).setValue(ItemSorter.getSaveString(list));
|
||||
|
||||
if (opt.activeTag() == opt.getTag()) {
|
||||
if (opt.activeTag() == getTag(opt.configName())) {
|
||||
ItemSorter.list = new ArrayList<>(list);
|
||||
}
|
||||
|
||||
ItemList.refreshItems.restart();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private ConfigTag getTag(String s) {
|
||||
return (world ? opt.worldConfigSet() : opt.globalConfigSet()).config.getTag(s);
|
||||
}
|
||||
|
||||
private ConfigTag renderTag(String s) {
|
||||
return (world && opt.worldSpecific(s) ? opt.worldConfigSet() : opt.globalConfigSet()).config.getTag(s);
|
||||
}
|
||||
|
||||
public SortItem itemAt(int mx, int my) {
|
||||
if (!pane.windowBounds().contains(mx, my)) return null;
|
||||
|
||||
|
||||
@@ -12,6 +12,7 @@ import org.lwjgl.opengl.GL11;
|
||||
import org.lwjgl.opengl.GL12;
|
||||
|
||||
import codechicken.core.gui.GuiScreenWidget;
|
||||
import codechicken.lib.config.ConfigTag;
|
||||
import codechicken.lib.gui.GuiDraw;
|
||||
import codechicken.lib.render.CCRenderState;
|
||||
import codechicken.lib.vec.Rectangle4i;
|
||||
@@ -21,7 +22,7 @@ import codechicken.nei.guihook.GuiContainerManager;
|
||||
|
||||
public class GuiPanelSettings extends GuiScreenWidget {
|
||||
|
||||
private final Option opt;
|
||||
private final GuiOptionList parentGui;
|
||||
|
||||
private PanelPlaceholder bookmarksPanel;
|
||||
private PanelPlaceholder itemsPanel;
|
||||
@@ -54,6 +55,7 @@ public class GuiPanelSettings extends GuiScreenWidget {
|
||||
|
||||
private final Option opt;
|
||||
private final String name;
|
||||
private final boolean world;
|
||||
private Rectangle4i margin;
|
||||
private Point dragDown;
|
||||
private String dragDir;
|
||||
@@ -67,9 +69,10 @@ public class GuiPanelSettings extends GuiScreenWidget {
|
||||
private PanelResizeButton rightButton = new PanelResizeButton(PANEL_SIZE, PANEL_SIZE * 2);
|
||||
private PanelResizeButton bottomButton = new PanelResizeButton(PANEL_SIZE * 2, PANEL_SIZE);
|
||||
|
||||
public PanelPlaceholder(Option opt, String name) {
|
||||
public PanelPlaceholder(Option opt, String name, boolean world) {
|
||||
this.opt = opt;
|
||||
this.name = name;
|
||||
this.world = world;
|
||||
}
|
||||
|
||||
public void resize(Rectangle4i margin) {
|
||||
@@ -116,10 +119,10 @@ public class GuiPanelSettings extends GuiScreenWidget {
|
||||
final int minWidth = ItemsGrid.SLOT_SIZE;
|
||||
final int minHeight = ItemsGrid.SLOT_SIZE;
|
||||
|
||||
int paddingLeft = (int) Math.ceil(margin.w * opt.renderTag(name + ".left").getIntValue() / 100000.0);
|
||||
int paddingTop = (int) Math.ceil(margin.h * opt.renderTag(name + ".top").getIntValue() / 100000.0);
|
||||
int paddingRight = (int) Math.ceil(margin.w * opt.renderTag(name + ".right").getIntValue() / 100000.0);
|
||||
int paddingBottom = (int) Math.ceil(margin.h * opt.renderTag(name + ".bottom").getIntValue() / 100000.0);
|
||||
int paddingLeft = (int) Math.ceil(margin.w * getTag(name + ".left").getIntValue() / 100000.0);
|
||||
int paddingTop = (int) Math.ceil(margin.h * getTag(name + ".top").getIntValue() / 100000.0);
|
||||
int paddingRight = (int) Math.ceil(margin.w * getTag(name + ".right").getIntValue() / 100000.0);
|
||||
int paddingBottom = (int) Math.ceil(margin.h * getTag(name + ".bottom").getIntValue() / 100000.0);
|
||||
|
||||
if (dragDir != null) {
|
||||
final Point mouse = GuiDraw.getMousePosition();
|
||||
@@ -159,6 +162,10 @@ public class GuiPanelSettings extends GuiScreenWidget {
|
||||
return new int[] { paddingLeft, paddingTop, paddingRight, paddingBottom };
|
||||
}
|
||||
|
||||
private ConfigTag getTag(String s) {
|
||||
return (world ? opt.worldConfigSet() : opt.globalConfigSet()).config.getTag(s);
|
||||
}
|
||||
|
||||
protected void drawItems() {
|
||||
final int columns = (w - 2) / ItemsGrid.SLOT_SIZE;
|
||||
final int rows = (h - (PANEL_SIZE + 2) * 2 - 2) / ItemsGrid.SLOT_SIZE;
|
||||
@@ -219,10 +226,10 @@ public class GuiPanelSettings extends GuiScreenWidget {
|
||||
if (button == 0 && dragDown != null) {
|
||||
int[] padding = getPaddings();
|
||||
|
||||
opt.renderTag(name + ".left").setIntValue(padding[0] * 100000 / margin.w);
|
||||
opt.renderTag(name + ".top").setIntValue(padding[1] * 100000 / margin.h);
|
||||
opt.renderTag(name + ".right").setIntValue(padding[2] * 100000 / margin.w);
|
||||
opt.renderTag(name + ".bottom").setIntValue(padding[3] * 100000 / margin.h);
|
||||
getTag(name + ".left").setIntValue(padding[0] * 100000 / margin.w);
|
||||
getTag(name + ".top").setIntValue(padding[1] * 100000 / margin.h);
|
||||
getTag(name + ".right").setIntValue(padding[2] * 100000 / margin.w);
|
||||
getTag(name + ".bottom").setIntValue(padding[3] * 100000 / margin.h);
|
||||
|
||||
dragDir = null;
|
||||
dragDown = null;
|
||||
@@ -232,10 +239,11 @@ public class GuiPanelSettings extends GuiScreenWidget {
|
||||
|
||||
public GuiPanelSettings(Option opt) {
|
||||
super(176, 198);
|
||||
this.opt = opt;
|
||||
this.parentGui = (GuiOptionList) Minecraft.getMinecraft().currentScreen;
|
||||
|
||||
bookmarksPanel = new PanelPlaceholder(opt, opt.name + ".bookmarks");
|
||||
itemsPanel = new PanelPlaceholder(opt, opt.name + ".items");
|
||||
boolean world = parentGui.worldConfig();
|
||||
bookmarksPanel = new PanelPlaceholder(opt, opt.name + ".bookmarks", world);
|
||||
itemsPanel = new PanelPlaceholder(opt, opt.name + ".items", world);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -247,7 +255,7 @@ public class GuiPanelSettings extends GuiScreenWidget {
|
||||
public void keyTyped(char c, int keycode) {
|
||||
|
||||
if (keycode == Keyboard.KEY_ESCAPE || keycode == Keyboard.KEY_BACK) {
|
||||
Minecraft.getMinecraft().displayGuiScreen(opt.slot.getGui());
|
||||
Minecraft.getMinecraft().displayGuiScreen(parentGui);
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
@@ -93,15 +93,18 @@ public class IMCHandler {
|
||||
final boolean multipleWidgetsAllowed = tag.hasKey("multipleWidgetsAllowed")
|
||||
? tag.getBoolean("multipleWidgetsAllowed")
|
||||
: tag.hasKey("maxRecipesPerPage") && tag.getInteger("maxRecipesPerPage") > 1;
|
||||
info.setHandlerDimensions(handlerWidth, handlerHeight, multipleWidgetsAllowed);
|
||||
info.setHandlerDimensions(handlerWidth, handlerHeight);
|
||||
info.setMultipleWidgetsAllowed(multipleWidgetsAllowed);
|
||||
} catch (NumberFormatException ignored) {
|
||||
NEIClientConfig.logger.info("Error setting handler dimensions for {}", handler);
|
||||
}
|
||||
|
||||
// true if not set to false
|
||||
info.setUseCustomScroll(tag.hasKey("useCustomScroll") && tag.getBoolean("useCustomScroll"));
|
||||
final boolean allowOverflow = tag.hasKey("useCustomScroll") && tag.getBoolean("useCustomScroll");
|
||||
info.setAllowOverflowX(tag.hasKey("allowOverflowX") ? tag.getBoolean("allowOverflowX") : true);
|
||||
info.setAllowOverflowY(tag.hasKey("allowOverflowY") ? tag.getBoolean("allowOverflowY") : allowOverflow);
|
||||
info.setShowFavoritesButton(!tag.hasKey("showFavoritesButton") || tag.getBoolean("showFavoritesButton"));
|
||||
info.setShowOverlayButton(!tag.hasKey("showOverlayButton") || tag.getBoolean("showOverlayButton"));
|
||||
info.setShowBadge(tag.hasKey("showBadge") && tag.getBoolean("showBadge"));
|
||||
|
||||
GuiRecipeTab.handlerAdderFromIMC.remove(handler);
|
||||
GuiRecipeTab.handlerAdderFromIMC.put(handler, info);
|
||||
|
||||
@@ -5,6 +5,7 @@ import java.io.FileOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.PrintWriter;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
|
||||
import net.minecraft.client.Minecraft;
|
||||
import net.minecraft.item.Item;
|
||||
@@ -23,7 +24,11 @@ import codechicken.nei.guihook.GuiContainerManager;
|
||||
|
||||
public class ItemPanelDumper extends DataDumper {
|
||||
|
||||
private static final int[] resolutions = new int[] { 16, 32, 48, 64, 128, 256 };
|
||||
public static final int CSV = 0;
|
||||
public static final int NBT = 1;
|
||||
public static final int JSON = 2;
|
||||
public static final int PNG = 3;
|
||||
private static final Minecraft mc = Minecraft.getMinecraft();
|
||||
|
||||
public ItemPanelDumper(String name) {
|
||||
super(name);
|
||||
@@ -54,19 +59,29 @@ public class ItemPanelDumper extends DataDumper {
|
||||
|
||||
public int getRes() {
|
||||
int i = renderTag(name + ".res").getIntValue(0);
|
||||
if (i >= resolutions.length || i < 0) renderTag().setIntValue(i = 0);
|
||||
return resolutions[i];
|
||||
int size = 16 << i;
|
||||
if (size >= getSmallerScreenAxisSize() || i < 0) {
|
||||
getTag(name + ".res").setIntValue(0);
|
||||
size = 16;
|
||||
}
|
||||
return size;
|
||||
}
|
||||
|
||||
private int getSmallerScreenAxisSize() {
|
||||
int width = mc.displayWidth;
|
||||
int height = mc.displayHeight;
|
||||
return Math.min(width, height);
|
||||
}
|
||||
|
||||
public Rectangle4i resButtonSize() {
|
||||
int width = 50;
|
||||
int width = 60;
|
||||
return new Rectangle4i(modeButtonSize().x - width - 6, 0, width, 20);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void draw(int mousex, int mousey, float frame) {
|
||||
super.draw(mousex, mousey, frame);
|
||||
if (getMode() == 3) {
|
||||
if (getMode() == PNG) {
|
||||
int res = getRes();
|
||||
drawButton(mousex, mousey, resButtonSize(), res + "x" + res);
|
||||
}
|
||||
@@ -74,23 +89,35 @@ public class ItemPanelDumper extends DataDumper {
|
||||
|
||||
@Override
|
||||
public void mouseClicked(int mousex, int mousey, int button) {
|
||||
if (getMode() == 3 && resButtonSize().contains(mousex, mousey)) {
|
||||
if (getMode() != PNG) {
|
||||
super.mouseClicked(mousex, mousey, button);
|
||||
return;
|
||||
}
|
||||
if (resButtonSize().contains(mousex, mousey)) {
|
||||
NEIClientUtils.playClickSound();
|
||||
getTag(name + ".res").setIntValue((renderTag(name + ".res").getIntValue(0) + 1) % resolutions.length);
|
||||
} else super.mouseClicked(mousex, mousey, button);
|
||||
int current = renderTag(name + ".res").getIntValue(0);
|
||||
int next;
|
||||
// 31 - numberOfLeadingZeros(x) = floor(log2(x))
|
||||
int max = 31 - Integer.numberOfLeadingZeros(getSmallerScreenAxisSize()) - 3;
|
||||
if (button == 1) { // Right click to cycle backward
|
||||
next = (current - 1 + max) % max;
|
||||
} else { // Left click to cycle forward
|
||||
next = (current + 1) % max;
|
||||
}
|
||||
getTag(name + ".res").setIntValue(next);
|
||||
} else if (!dumpButtonSize().contains(mousex, mousey) || acknowledgedItemSizeWarning()) {
|
||||
super.mouseClicked(mousex, mousey, button);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getFileExtension() {
|
||||
switch (getMode()) {
|
||||
case 0:
|
||||
return ".csv";
|
||||
case 1:
|
||||
return ".nbt";
|
||||
case 2:
|
||||
return ".json";
|
||||
}
|
||||
return null;
|
||||
return switch (getMode()) {
|
||||
case CSV -> ".csv";
|
||||
case NBT -> ".nbt";
|
||||
case JSON -> ".json";
|
||||
default -> null;
|
||||
};
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -105,15 +132,29 @@ public class ItemPanelDumper extends DataDumper {
|
||||
|
||||
@Override
|
||||
public void dumpFile() {
|
||||
if (getMode() == 3) Minecraft.getMinecraft().displayGuiScreen(new GuiItemIconDumper(this, getRes()));
|
||||
if (getMode() == PNG && acknowledgedItemSizeWarning())
|
||||
mc.displayGuiScreen(new GuiItemIconDumper(this, getRes()));
|
||||
else super.dumpFile();
|
||||
}
|
||||
|
||||
private boolean acknowledgedItemSizeWarning() {
|
||||
return !showItemSizeWarning() || NEIClientUtils.shiftKey();
|
||||
}
|
||||
|
||||
private boolean showItemSizeWarning() {
|
||||
int res = getRes();
|
||||
// More than 4 items at 2048x2048, 16 items at 1024x1024, 64 at 512x512, etc.
|
||||
int WARNING_SIZE = 16_777_216;
|
||||
return ItemPanels.itemPanel.getItems().size() * res * res > WARNING_SIZE;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void dumpTo(File file) throws IOException {
|
||||
if (getMode() == 0) super.dumpTo(file);
|
||||
else if (getMode() == 1) dumpNBT(file);
|
||||
else dumpJson(file);
|
||||
switch (getMode()) {
|
||||
case CSV -> super.dumpTo(file);
|
||||
case NBT -> dumpNBT(file);
|
||||
default -> dumpJson(file);
|
||||
}
|
||||
}
|
||||
|
||||
public void dumpNBT(File file) throws IOException {
|
||||
@@ -141,4 +182,22 @@ public class ItemPanelDumper extends DataDumper {
|
||||
public int modeCount() {
|
||||
return 4;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<String> handleTooltip(int mousex, int mousey, List<String> currenttip) {
|
||||
if (getMode() == PNG && dumpButtonSize().contains(mousex, mousey) && showItemSizeWarning()) {
|
||||
int res = getRes();
|
||||
currenttip.add(
|
||||
NEIClientUtils.translate(
|
||||
"options.tools.dump.itempanel.icon.warning.1",
|
||||
ItemPanels.itemPanel.getItems().size(),
|
||||
res,
|
||||
res));
|
||||
currenttip.add(
|
||||
NEIClientUtils.translate(
|
||||
"options.tools.dump.itempanel.icon.warning.2",
|
||||
NEIClientUtils.translate("key.shift")));
|
||||
}
|
||||
return currenttip;
|
||||
}
|
||||
}
|
||||
@@ -1,5 +1,6 @@
|
||||
package codechicken.nei.config;
|
||||
|
||||
import java.lang.ref.WeakReference;
|
||||
import java.util.List;
|
||||
|
||||
import net.minecraft.client.Minecraft;
|
||||
@@ -17,7 +18,11 @@ public abstract class Option {
|
||||
.playSound(PositionedSoundRecord.func_147674_a(new ResourceLocation("gui.button.press"), 1.0F));
|
||||
}
|
||||
|
||||
public OptionScrollSlot slot;
|
||||
private WeakReference<OptionScrollSlot> slotRef;
|
||||
|
||||
public OptionScrollSlot getSlot() {
|
||||
return slotRef != null ? slotRef.get() : null;
|
||||
}
|
||||
|
||||
public String namespace = null;
|
||||
public final String name;
|
||||
@@ -134,7 +139,7 @@ public abstract class Option {
|
||||
* @return true if the gui is in world config mode
|
||||
*/
|
||||
public boolean worldConfig() {
|
||||
return slot.getGui().worldConfig();
|
||||
return getSlot().getGui().worldConfig();
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -189,7 +194,7 @@ public abstract class Option {
|
||||
}
|
||||
|
||||
public void onAdded(OptionScrollSlot slot) {
|
||||
this.slot = slot;
|
||||
this.slotRef = new WeakReference<>(slot);
|
||||
}
|
||||
|
||||
public void onAdded(OptionList list) {
|
||||
|
||||
@@ -57,10 +57,10 @@ public abstract class OptionButton extends Option {
|
||||
}
|
||||
|
||||
public Rectangle buttonSize() {
|
||||
if (getPrefix() == null) return new Rectangle(0, 0, slot.slotWidth(), 20);
|
||||
if (getPrefix() == null) return new Rectangle(0, 0, getSlot().slotWidth(), 20);
|
||||
|
||||
int width = Math.max(60, getStringWidth(getButtonText()) + 8);
|
||||
return new Rectangle(slot.slotWidth() - width, 0, width, 20);
|
||||
return new Rectangle(getSlot().slotWidth() - width, 0, width, 20);
|
||||
}
|
||||
|
||||
public String getPrefix() {
|
||||
|
||||
@@ -1,137 +0,0 @@
|
||||
package codechicken.nei.config;
|
||||
|
||||
import static codechicken.lib.gui.GuiDraw.drawRect;
|
||||
import static codechicken.lib.gui.GuiDraw.drawStringC;
|
||||
|
||||
import java.awt.Rectangle;
|
||||
|
||||
import org.lwjgl.input.Keyboard;
|
||||
|
||||
import codechicken.nei.NEIClientUtils;
|
||||
import codechicken.nei.util.NEIKeyboardUtils;
|
||||
|
||||
public class OptionKeyBind extends OptionButton {
|
||||
|
||||
private boolean editing = false;
|
||||
private boolean useHash = false;
|
||||
private int keyboard = Keyboard.CHAR_NONE;
|
||||
|
||||
public OptionKeyBind(String name) {
|
||||
this(name, false);
|
||||
}
|
||||
|
||||
public OptionKeyBind(final String name, final boolean useHash) {
|
||||
super("keys." + name);
|
||||
this.useHash = useHash;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onMouseClicked(int mousex, int mousey, int button) {
|
||||
if (editing) {
|
||||
resetChanges();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void keyTyped(char c, int keycode) {
|
||||
|
||||
if (!editing) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (keycode == Keyboard.KEY_RETURN) {
|
||||
applyChanges();
|
||||
return;
|
||||
}
|
||||
|
||||
keyboard = useHash ? NEIClientUtils.getKeyHash() : keycode;
|
||||
|
||||
if (keyboard != Keyboard.CHAR_NONE) {
|
||||
applyChanges();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onClick(int btn) {
|
||||
|
||||
if (editing) {
|
||||
return true;
|
||||
} else if (btn == 0) {
|
||||
editing = true;
|
||||
return true;
|
||||
} else if (btn == 1) {
|
||||
keyboard = Keyboard.CHAR_NONE;
|
||||
applyChanges();
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
protected void applyChanges() {
|
||||
setValue(keyboard);
|
||||
resetChanges();
|
||||
}
|
||||
|
||||
protected void resetChanges() {
|
||||
editing = false;
|
||||
keyboard = Keyboard.CHAR_NONE;
|
||||
}
|
||||
|
||||
public boolean conflicted() {
|
||||
final int keyboard = getValue();
|
||||
|
||||
if (keyboard <= 0) {
|
||||
return false;
|
||||
}
|
||||
|
||||
for (Option o : slot.options) {
|
||||
if (o instanceof OptionKeyBind && o != this && ((OptionKeyBind) o).getValue() == keyboard) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public void setValue(int keycode) {
|
||||
getTag().setIntValue(keycode);
|
||||
}
|
||||
|
||||
public int getValue() {
|
||||
return renderTag().getIntValue();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getPrefix() {
|
||||
return translateN(name);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void drawButton(int mx, int my) {
|
||||
|
||||
if (editing) {
|
||||
Rectangle b = buttonSize();
|
||||
drawRect(b.x, b.y, b.width, b.height, -6250336);
|
||||
drawRect(b.x + 1, b.y + 1, b.width - 2, b.height - 2, -16777216);
|
||||
drawStringC(getButtonText(), b.x, b.y, b.width, b.height, getTextColour(mx, my));
|
||||
} else {
|
||||
super.drawButton(mx, my);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getButtonText() {
|
||||
|
||||
if (editing) {
|
||||
return NEIKeyboardUtils.getHashName(NEIClientUtils.getMetaHash());
|
||||
}
|
||||
|
||||
return NEIKeyboardUtils.getKeyName(Math.max(getValue(), 0));
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getTextColour(int mousex, int mousey) {
|
||||
return !editing && conflicted() ? 0xFFFF6666 : -1;
|
||||
}
|
||||
}
|
||||
@@ -131,13 +131,15 @@ public class OptionList extends OptionButton {
|
||||
/**
|
||||
* Adds this option to a temporary slot and gui for internal setting manipulation.
|
||||
*/
|
||||
public void synthesizeEnvironment(boolean world) {
|
||||
getGui(null, this, world).addWidgets();
|
||||
public GuiOptionList synthesizeEnvironment(boolean world) {
|
||||
GuiOptionList gui = getGui(null, this, world);
|
||||
gui.addWidgets();
|
||||
return gui;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onClick(int button) {
|
||||
openGui(slot.getGui(), slot.getGui().worldConfig());
|
||||
openGui(getSlot().getGui(), getSlot().getGui().worldConfig());
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
@@ -131,6 +131,6 @@ public abstract class OptionStringSet extends Option {
|
||||
}
|
||||
|
||||
public int buttonX() {
|
||||
return slot.slotWidth() - (24 * options.size() - 4);
|
||||
return getSlot().slotWidth() - (24 * options.size() - 4);
|
||||
}
|
||||
}
|
||||
@@ -53,7 +53,7 @@ public class OptionTextField extends Option {
|
||||
}
|
||||
|
||||
protected int getMaxInputWidth() {
|
||||
return slot.slotWidth();
|
||||
return getSlot().slotWidth();
|
||||
}
|
||||
|
||||
public boolean isEnabled() {
|
||||
@@ -64,9 +64,10 @@ public class OptionTextField extends Option {
|
||||
public void draw(int mousex, int mousey, float frame) {
|
||||
GuiDraw.drawString(getPrefix(), 10, 6, -1);
|
||||
|
||||
textField.w = Math
|
||||
.max(60, Math.min(getMaxInputWidth(), slot.slotWidth() - GuiDraw.getStringWidth(getPrefix())) - 16);
|
||||
textField.x = slot.slotWidth() - textField.w;
|
||||
textField.w = Math.max(
|
||||
60,
|
||||
Math.min(getMaxInputWidth(), getSlot().slotWidth() - GuiDraw.getStringWidth(getPrefix())) - 16);
|
||||
textField.x = getSlot().slotWidth() - textField.w;
|
||||
textField.draw(mousex, mousey);
|
||||
}
|
||||
|
||||
|
||||
@@ -5,6 +5,7 @@ import static codechicken.lib.gui.GuiDraw.drawStringC;
|
||||
import org.lwjgl.opengl.GL11;
|
||||
|
||||
import codechicken.nei.Button;
|
||||
import codechicken.nei.ColorUtils;
|
||||
import codechicken.nei.LayoutManager;
|
||||
|
||||
public abstract class CheckboxButton extends Button {
|
||||
@@ -38,7 +39,8 @@ public abstract class CheckboxButton extends Button {
|
||||
tex = 1;
|
||||
}
|
||||
|
||||
int colour = tex == 2 ? 0xffffa0 : tex == 0 ? 0x601010 : 0xe0e0e0;
|
||||
int colour = tex == 2 ? ColorUtils.buttonLabelHover.getColor()
|
||||
: tex == 0 ? ColorUtils.buttonLabelDisabled.getColor() : ColorUtils.buttonLabelNormal.getColor();
|
||||
LayoutManager.drawButtonBackground(x, y, w, h, true, isChecked() ? 0 : tex);
|
||||
drawStringC(getRenderLabel(), x + w / 2, y + (h - 8) / 2, colour);
|
||||
}
|
||||
|
||||
@@ -17,12 +17,14 @@ import codechicken.nei.LayoutManager;
|
||||
import codechicken.nei.NEIClientUtils;
|
||||
import codechicken.nei.PresetsList;
|
||||
import codechicken.nei.PresetsList.Preset;
|
||||
import codechicken.nei.config.GuiOptionList;
|
||||
import codechicken.nei.config.GuiOptionPane;
|
||||
import codechicken.nei.config.Option;
|
||||
|
||||
public class GuiPresetList extends GuiOptionPane {
|
||||
|
||||
private final Option opt;
|
||||
private final GuiOptionList parentGui;
|
||||
protected static final int SLOT_HEIGHT = 24;
|
||||
protected static final int BUTTON_HEIGHT = 20;
|
||||
protected GuiCCButton createButton;
|
||||
@@ -31,6 +33,7 @@ public class GuiPresetList extends GuiOptionPane {
|
||||
|
||||
public GuiPresetList(Option opt) {
|
||||
this.opt = opt;
|
||||
this.parentGui = (GuiOptionList) Minecraft.getMinecraft().currentScreen;
|
||||
this.createButton = new GuiCCButton(0, 2, 0, 16, NEIClientUtils.translate("presets.new"))
|
||||
.setActionCommand("create");
|
||||
this.toggleButton = new GuiCCButton(0, 2, 0, 16, NEIClientUtils.translate("presets.toggle"))
|
||||
@@ -253,7 +256,7 @@ public class GuiPresetList extends GuiOptionPane {
|
||||
|
||||
@Override
|
||||
public GuiScreen getParentScreen() {
|
||||
return opt.slot.getGui();
|
||||
return parentGui;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -21,7 +21,7 @@ import codechicken.nei.ItemList.AnyMultiItemFilter;
|
||||
import codechicken.nei.ItemList.NegatedItemFilter;
|
||||
import codechicken.nei.ItemsGrid;
|
||||
import codechicken.nei.ItemsGrid.ItemsGridSlot;
|
||||
import codechicken.nei.NEIClientConfig;
|
||||
import codechicken.nei.KeyManager;
|
||||
import codechicken.nei.NEIClientUtils;
|
||||
import codechicken.nei.PresetsList;
|
||||
import codechicken.nei.PresetsList.Preset;
|
||||
@@ -81,15 +81,15 @@ public class RightPanel extends GuiWidget {
|
||||
@Override
|
||||
public void lastKeyTyped(int keyID, char keyChar) {
|
||||
|
||||
if (!focused() && NEIClientConfig.isKeyHashDown("gui.search")) {
|
||||
if (!focused() && KeyManager.isHashDown("gui.search")) {
|
||||
setFocus(true);
|
||||
}
|
||||
|
||||
if (focused() && NEIClientConfig.isKeyHashDown("gui.getprevioussearch")) {
|
||||
if (focused() && KeyManager.isKeyDown("gui.getprevioussearch")) {
|
||||
handleNavigateHistory(TextHistory.Direction.PREVIOUS);
|
||||
}
|
||||
|
||||
if (focused() && NEIClientConfig.isKeyHashDown("gui.getnextsearch")) {
|
||||
if (focused() && KeyManager.isKeyDown("gui.getnextsearch")) {
|
||||
handleNavigateHistory(TextHistory.Direction.NEXT);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -24,6 +24,12 @@ public class AllOthersRecipeFilter implements IRecipeFilter {
|
||||
}
|
||||
}
|
||||
|
||||
for (PositionedStack pStack : handler.getCatalystStacks(recipeIndex)) {
|
||||
if (!match(pStack)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
@@ -24,6 +24,12 @@ public class AnyOthersRecipeFilter implements IRecipeFilter {
|
||||
}
|
||||
}
|
||||
|
||||
for (PositionedStack pStack : handler.getCatalystStacks(recipeIndex)) {
|
||||
if (match(pStack)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
@@ -48,9 +48,7 @@ public class RecipeFilter implements IRecipeFilter {
|
||||
}
|
||||
|
||||
if (this.context == FilterContext.ANY || this.context == FilterContext.OUTPUT) {
|
||||
final PositionedStack result = handler.getResultStack(recipeIndex);
|
||||
|
||||
if (result != null && matchPositionedStack(result) == this.anyMatch) {
|
||||
if (matchPositionedStack(handler.getResultStacks(recipeIndex), this.anyMatch)) {
|
||||
return this.anyMatch;
|
||||
}
|
||||
|
||||
@@ -58,6 +56,10 @@ public class RecipeFilter implements IRecipeFilter {
|
||||
return this.anyMatch;
|
||||
}
|
||||
|
||||
if (matchPositionedStack(handler.getCatalystStacks(recipeIndex), this.anyMatch)) {
|
||||
return this.anyMatch;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return !this.anyMatch;
|
||||
|
||||
@@ -5,7 +5,6 @@ import static codechicken.lib.gui.GuiDraw.fontRenderer;
|
||||
import static codechicken.lib.gui.GuiDraw.getMousePosition;
|
||||
import static codechicken.lib.gui.GuiDraw.renderEngine;
|
||||
import static codechicken.nei.NEIClientUtils.translate;
|
||||
import static com.gtnewhorizon.gtnhlib.util.numberformatting.NumberFormatUtil.formatNumber;
|
||||
|
||||
import java.awt.Point;
|
||||
import java.util.ArrayList;
|
||||
@@ -44,11 +43,10 @@ import org.lwjgl.input.Mouse;
|
||||
import org.lwjgl.opengl.GL11;
|
||||
import org.lwjgl.opengl.GL12;
|
||||
|
||||
import com.gtnewhorizon.gtnhlib.util.numberformatting.NumberFormatUtil;
|
||||
|
||||
import codechicken.lib.gui.GuiDraw;
|
||||
import codechicken.nei.ItemList;
|
||||
import codechicken.nei.ItemStackSet;
|
||||
import codechicken.nei.KeyManager;
|
||||
import codechicken.nei.NEIClientConfig;
|
||||
import codechicken.nei.NEIClientUtils;
|
||||
import codechicken.nei.NEIModContainer;
|
||||
@@ -213,14 +211,14 @@ public class GuiContainerManager {
|
||||
return String.format(
|
||||
fullPattern,
|
||||
valueFormatter.apply(stackSize),
|
||||
formatNumber(units),
|
||||
NEIClientUtils.formatNumber(units),
|
||||
valueFormatter.apply(maxStackSize),
|
||||
valueFormatter.apply(remainder));
|
||||
} else {
|
||||
return String.format(
|
||||
shortPattern,
|
||||
valueFormatter.apply(stackSize),
|
||||
formatNumber(units),
|
||||
NEIClientUtils.formatNumber(units),
|
||||
valueFormatter.apply(maxStackSize));
|
||||
}
|
||||
}
|
||||
@@ -238,7 +236,7 @@ public class GuiContainerManager {
|
||||
stack.getMaxStackSize(),
|
||||
translate("inventory.tooltip.count.item", "%s = %s * %s + %s"),
|
||||
translate("inventory.tooltip.count.item", "%s = %s * %s"),
|
||||
NumberFormatUtil::formatNumber);
|
||||
NEIClientUtils::formatNumber);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -255,7 +253,7 @@ public class GuiContainerManager {
|
||||
144,
|
||||
translate("inventory.tooltip.count.fluid", "%s = %s * %s + %s"),
|
||||
translate("inventory.tooltip.count.fluid", "%s = %s * %s"),
|
||||
NumberFormatUtil::formatFluid);
|
||||
NEIClientUtils::formatFluid);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -627,7 +625,7 @@ public class GuiContainerManager {
|
||||
tooltip.set(0, tooltip.get(0) + GuiDraw.TOOLTIP_LINESPACE);
|
||||
}
|
||||
|
||||
} else if (!tooltip.isEmpty()) {
|
||||
} else if (!tooltip.isEmpty() && !tooltip.get(0).startsWith(GuiDraw.TOOLTIP_HANDLER)) {
|
||||
tooltip.set(0, tooltip.get(0) + GuiDraw.TOOLTIP_LINESPACE);
|
||||
}
|
||||
|
||||
@@ -765,7 +763,7 @@ public class GuiContainerManager {
|
||||
"inventory.tooltip.page",
|
||||
tooltipPage + 1,
|
||||
maxTooltipPage,
|
||||
NEIClientConfig.getKeyName("gui.next_tooltip"));
|
||||
KeyManager.getKeyName("gui.next_tooltip"));
|
||||
|
||||
if (lastLine.startsWith(GuiDraw.TOOLTIP_HANDLER)) {
|
||||
currentTooltip.add(lastLine);
|
||||
|
||||
@@ -31,7 +31,7 @@ public class AcceptsFollowingTooltipLineHandler extends ItemsTooltipLineHandler
|
||||
ItemStack activeStack, int maxRows) {
|
||||
|
||||
if (items.size() > 1) {
|
||||
items.sort(Comparator.comparing(FavoriteRecipes::contains).reversed());
|
||||
items.sort(Comparator.comparing(FavoriteRecipes::containsManual).reversed());
|
||||
return new AcceptsFollowingTooltipLineHandler(tooltipGUID, items, activeStack, maxRows);
|
||||
}
|
||||
|
||||
@@ -42,7 +42,7 @@ public class AcceptsFollowingTooltipLineHandler extends ItemsTooltipLineHandler
|
||||
protected void drawItem(int x, int y, ItemStack drawStack, String stackSize) {
|
||||
super.drawItem(x, y, drawStack, stackSize);
|
||||
|
||||
if (FavoriteRecipes.contains(drawStack)) {
|
||||
if (FavoriteRecipes.containsManual(drawStack)) {
|
||||
NEIClientUtils.drawNEIOverlayText("F", x, y);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -91,7 +91,7 @@ public class AutoCraftingManager {
|
||||
|
||||
for (BookmarkItem item : math.initialItems) {
|
||||
final long invStackSize = inventory.getOrDefault(item.itemStack, 0L);
|
||||
final long amount = Math.max(0, item.amount - invStackSize * item.fluidCellAmount);
|
||||
final long amount = Math.max(0, item.getAmount() - invStackSize * item.fluidCellAmount);
|
||||
if (amount > 0) {
|
||||
initialItems.add(item.copyWithAmount(amount));
|
||||
}
|
||||
|
||||
@@ -0,0 +1,89 @@
|
||||
package codechicken.nei.recipe;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import net.minecraft.util.EnumChatFormatting;
|
||||
|
||||
import codechicken.lib.vec.Rectangle4i;
|
||||
import codechicken.nei.ColorUtils;
|
||||
import codechicken.nei.NEIClientUtils;
|
||||
import codechicken.nei.NEIClientUtils.Alignment;
|
||||
|
||||
public class Badge {
|
||||
|
||||
protected final String text;
|
||||
protected final List<String> tooltip;
|
||||
protected int badgeTextColor;
|
||||
protected boolean shadow = false;
|
||||
protected Alignment alignment = Alignment.TopLeft;
|
||||
|
||||
public Badge(String text, String... tooltip) {
|
||||
this.text = text;
|
||||
this.tooltip = Arrays.stream(tooltip).map(t -> EnumChatFormatting.GRAY + t).collect(Collectors.toList());
|
||||
this.badgeTextColor = ColorUtils.recipeBadge.getColor();
|
||||
}
|
||||
|
||||
public String getText() {
|
||||
return this.text;
|
||||
}
|
||||
|
||||
public List<String> getTooltip() {
|
||||
return this.tooltip;
|
||||
}
|
||||
|
||||
public Badge setColor(int color) {
|
||||
this.badgeTextColor = color;
|
||||
return this;
|
||||
}
|
||||
|
||||
public int getColor() {
|
||||
return this.badgeTextColor;
|
||||
}
|
||||
|
||||
public Badge setShadow(boolean shadow) {
|
||||
this.shadow = shadow;
|
||||
return this;
|
||||
}
|
||||
|
||||
public boolean hasShadow() {
|
||||
return this.shadow;
|
||||
}
|
||||
|
||||
public Badge setAlignment(Alignment alignment) {
|
||||
this.alignment = alignment;
|
||||
return this;
|
||||
}
|
||||
|
||||
public Alignment getAlignment() {
|
||||
return this.alignment;
|
||||
}
|
||||
|
||||
public void draw(Rectangle4i rect) {
|
||||
NEIClientUtils.drawNEIOverlayText(getText(), rect, 0.5f, getColor(), hasShadow(), getAlignment());
|
||||
}
|
||||
|
||||
public static Badge notConsumed() {
|
||||
return new Badge(
|
||||
NEIClientUtils.translate("recipe.badge.nc"),
|
||||
NEIClientUtils.translate("recipe.badge.nc.tooltip"));
|
||||
}
|
||||
|
||||
public static Badge notConsumedParallel() {
|
||||
return new Badge(
|
||||
NEIClientUtils.translate("recipe.badge.ncp"),
|
||||
NEIClientUtils.translate("recipe.badge.ncp.tooltip"));
|
||||
}
|
||||
|
||||
public static Badge consumeChance(float chance) {
|
||||
final String chanceText = NEIClientUtils.formatChance(chance);
|
||||
return new Badge(chanceText, NEIClientUtils.translate("recipe.badge.chance.consume", chanceText));
|
||||
}
|
||||
|
||||
public static Badge outputChance(float chance) {
|
||||
final String chanceText = NEIClientUtils.formatChance(chance);
|
||||
return new Badge(chanceText, NEIClientUtils.translate("recipe.badge.chance.output", chanceText));
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,718 +0,0 @@
|
||||
package codechicken.nei.recipe;
|
||||
|
||||
import java.awt.Point;
|
||||
import java.io.File;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import net.minecraft.client.Minecraft;
|
||||
import net.minecraft.client.gui.GuiScreen;
|
||||
import net.minecraft.client.gui.inventory.GuiContainer;
|
||||
import net.minecraft.util.EnumChatFormatting;
|
||||
|
||||
import org.apache.commons.io.IOUtils;
|
||||
import org.lwjgl.input.Keyboard;
|
||||
import org.lwjgl.opengl.GL11;
|
||||
|
||||
import codechicken.lib.gui.GuiDraw;
|
||||
import codechicken.lib.vec.Rectangle4i;
|
||||
import codechicken.nei.Button;
|
||||
import codechicken.nei.ClientHandler;
|
||||
import codechicken.nei.FormattedTextField;
|
||||
import codechicken.nei.LayoutManager;
|
||||
import codechicken.nei.NEIClientConfig;
|
||||
import codechicken.nei.NEIClientUtils;
|
||||
import codechicken.nei.TextField;
|
||||
import codechicken.nei.Widget;
|
||||
import codechicken.nei.drawable.DrawableBuilder;
|
||||
import codechicken.nei.drawable.DrawableResource;
|
||||
import codechicken.nei.guihook.GuiContainerManager;
|
||||
import codechicken.nei.guihook.IContainerInputHandler;
|
||||
import codechicken.nei.recipe.TemplateRecipeHandler.RecipeTransferRect;
|
||||
|
||||
public class DebugHandlerWidget extends Widget implements IContainerInputHandler {
|
||||
|
||||
private static abstract class IntegerField extends TextField {
|
||||
|
||||
protected int defaultValue = 0;
|
||||
|
||||
public IntegerField(String ident, int defaultValue) {
|
||||
super(ident);
|
||||
this.defaultValue = defaultValue;
|
||||
this.h = LINE_HEIGHT;
|
||||
this.z = 2;
|
||||
((FormattedTextField) field).setPlaceholder(Integer.toString(this.defaultValue));
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void initInternalTextField() {
|
||||
field = new FormattedTextField(Minecraft.getMinecraft().fontRenderer, 0, 0, 0, 0) {
|
||||
|
||||
@Override
|
||||
public String getText() {
|
||||
String text = super.getText();
|
||||
return !isFocused() && this.placeholder.equals(text) ? "" : text;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean beforeWrite(String text) {
|
||||
if (text == null || text.isEmpty()) return true;
|
||||
try {
|
||||
return Integer.parseInt(text) >= 0;
|
||||
} catch (NumberFormatException e) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean textboxKeyTyped(char keyChar, int keyID) {
|
||||
if (!isFocused()) return false;
|
||||
|
||||
if (super.textboxKeyTyped(keyChar, keyID)) {
|
||||
return true;
|
||||
} else if (keyID == Keyboard.KEY_DOWN) {
|
||||
setText(Integer.toString(getInteger() - 1));
|
||||
return true;
|
||||
} else if (keyID == Keyboard.KEY_UP) {
|
||||
setText(Integer.toString(getInteger() + 1));
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
};
|
||||
field.setMaxStringLength(maxSearchLength);
|
||||
field.setCursorPositionZero();
|
||||
}
|
||||
|
||||
protected int getInteger() {
|
||||
try {
|
||||
return Integer.parseInt(text());
|
||||
} catch (NumberFormatException nfe) {
|
||||
return this.defaultValue;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onMouseWheel(int i, int mx, int my) {
|
||||
if (!contains(mx, my)) return false;
|
||||
setText(Integer.toString(getInteger() + i));
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private final int[] COLORS = new int[] { 0x2200FF00, 0x22FF0000, 0x220000FF, 0x2200FFFF, 0x22FF00FF, 0x22FFFF00 };
|
||||
|
||||
private IRecipeHandler handler;
|
||||
private HandlerInfo handlerInfo;
|
||||
|
||||
private static final int WINDOW_WIDTH = 176;
|
||||
private static final int LINE_HEIGHT = 16;
|
||||
private static final int INLINE_PADDING = 6;
|
||||
private static final int LABEL_WIDTH = 50;
|
||||
|
||||
private IntegerField order;
|
||||
private IntegerField yShift;
|
||||
private IntegerField handlerHeight;
|
||||
private IntegerField handlerWidth;
|
||||
private Button multipleWidgetsAllowed;
|
||||
private Button useCustomScroll;
|
||||
|
||||
private Point dragPoint = null;
|
||||
public boolean showWidget = false;
|
||||
|
||||
private static final int BORDER_PADDING = 6;
|
||||
private static final int TRANSPARENCY_BORDER = 4;
|
||||
private static final String TOOLTIP_PREFIX = "debug.RecipeHandler.";
|
||||
private static final Map<String, String> TOOLTIP_KEYS = new HashMap<>();
|
||||
|
||||
static {
|
||||
TOOLTIP_KEYS.put("Name", TOOLTIP_PREFIX + "Name");
|
||||
TOOLTIP_KEYS.put("ID", TOOLTIP_PREFIX + "Id");
|
||||
TOOLTIP_KEYS.put("Key", TOOLTIP_PREFIX + "Key");
|
||||
TOOLTIP_KEYS.put("H.Hack", TOOLTIP_PREFIX + "HHack");
|
||||
TOOLTIP_KEYS.put("Mod Name", TOOLTIP_PREFIX + "ModName");
|
||||
TOOLTIP_KEYS.put("Mod ID", TOOLTIP_PREFIX + "ModId");
|
||||
TOOLTIP_KEYS.put("Order", TOOLTIP_PREFIX + "Order");
|
||||
TOOLTIP_KEYS.put("yShift", TOOLTIP_PREFIX + "yShift");
|
||||
TOOLTIP_KEYS.put("Multi Widgets", TOOLTIP_PREFIX + "MultiWidgets");
|
||||
TOOLTIP_KEYS.put("Height", TOOLTIP_PREFIX + "Height");
|
||||
TOOLTIP_KEYS.put("Width", TOOLTIP_PREFIX + "Width");
|
||||
TOOLTIP_KEYS.put("Use Custom Scroll", TOOLTIP_PREFIX + "UseCustomScroll");
|
||||
}
|
||||
private final DrawableResource BG_TEXTURE = new DrawableBuilder(
|
||||
"nei:textures/gui/recipebg.png",
|
||||
0,
|
||||
0,
|
||||
176 + TRANSPARENCY_BORDER * 2,
|
||||
166 + TRANSPARENCY_BORDER * 2).build();
|
||||
|
||||
public DebugHandlerWidget() {
|
||||
GuiContainerManager.addInputHandler(this);
|
||||
|
||||
this.order = new IntegerField("order", 0) {
|
||||
|
||||
@Override
|
||||
public void onTextChange(String oldText) {
|
||||
|
||||
if (NEIClientConfig.handlerOrdering.get(handler.getOverlayIdentifier()) != null) {
|
||||
if (getInteger() != NEIClientConfig.handlerOrdering.get(handler.getOverlayIdentifier())) {
|
||||
updatePatch(5, getInteger(), this.defaultValue);
|
||||
}
|
||||
} else if (NEIClientConfig.handlerOrdering.get(handler.getHandlerId()) != null) {
|
||||
if (getInteger() != NEIClientConfig.handlerOrdering.get(handler.getHandlerId())) {
|
||||
updatePatch(5, getInteger(), this.defaultValue);
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
this.yShift = new IntegerField("yShift", 0) {
|
||||
|
||||
@Override
|
||||
public void onTextChange(String oldText) {
|
||||
if (getInteger() != handlerInfo.getYShift()) {
|
||||
handlerInfo.setYShift(getInteger());
|
||||
updatePatch(1, getInteger(), this.defaultValue);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
this.multipleWidgetsAllowed = new Button() {
|
||||
|
||||
{
|
||||
this.h = LINE_HEIGHT;
|
||||
this.z = 2;
|
||||
}
|
||||
|
||||
public String getRenderLabel() {
|
||||
return handlerInfo.isMultipleWidgetsAllowed() ? "On" : "Off";
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onButtonPress(boolean rightclick) {
|
||||
handlerInfo.setHandlerDimensions(
|
||||
handlerInfo.getWidth(),
|
||||
handlerInfo.getHeight(),
|
||||
!handlerInfo.isMultipleWidgetsAllowed());
|
||||
updatePatch(4, handlerInfo.isMultipleWidgetsAllowed() ? 1 : 0, 1);
|
||||
return true;
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
this.handlerHeight = new IntegerField("handlerHeight", HandlerInfo.DEFAULT_HEIGHT) {
|
||||
|
||||
@Override
|
||||
public void draw(int mx, int my) {
|
||||
this.field.setEnabled(handler.getRecipeHeight(0) <= 0);
|
||||
super.draw(mx, my);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onTextChange(String oldText) {
|
||||
if (getInteger() != handlerInfo.getHeight()) {
|
||||
handlerInfo.setHandlerDimensions(
|
||||
handlerInfo.getWidth(),
|
||||
getInteger(),
|
||||
handlerInfo.isMultipleWidgetsAllowed());
|
||||
updatePatch(2, getInteger(), this.defaultValue);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
this.handlerWidth = new IntegerField("handlerWidth", HandlerInfo.DEFAULT_WIDTH) {
|
||||
|
||||
@Override
|
||||
public void onTextChange(String oldText) {
|
||||
if (getInteger() != handlerInfo.getWidth()) {
|
||||
handlerInfo.setHandlerDimensions(
|
||||
getInteger(),
|
||||
handlerInfo.getHeight(),
|
||||
handlerInfo.isMultipleWidgetsAllowed());
|
||||
updatePatch(3, getInteger(), this.defaultValue);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
this.useCustomScroll = new Button() {
|
||||
|
||||
{
|
||||
this.h = LINE_HEIGHT;
|
||||
this.z = 2;
|
||||
}
|
||||
|
||||
public String getRenderLabel() {
|
||||
return handlerInfo.getUseCustomScroll() ? "On" : "Off";
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onButtonPress(boolean rightclick) {
|
||||
handlerInfo.setUseCustomScroll(!handlerInfo.getUseCustomScroll());
|
||||
updatePatch(6, handlerInfo.getUseCustomScroll() ? 1 : 0, 0);
|
||||
return true;
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
this.w = WINDOW_WIDTH;
|
||||
this.h = 10 + 13 * LINE_HEIGHT;
|
||||
this.x = 10;
|
||||
this.y = 50;
|
||||
this.z = 1;
|
||||
}
|
||||
|
||||
private void updatePatch(int key, int value, int defaultValue) {
|
||||
final String handlerKey = getHandlerID(handler);
|
||||
|
||||
if (!patches.containsKey(handlerKey)) {
|
||||
patches.put(handlerKey, new String[] { handlerKey, null, null, null, null, null, null });
|
||||
}
|
||||
|
||||
if (value == defaultValue) {
|
||||
patches.get(handlerKey)[key] = null;
|
||||
} else {
|
||||
patches.get(handlerKey)[key] = String.valueOf(value);
|
||||
}
|
||||
|
||||
saveHandlerInfoPatch();
|
||||
|
||||
if (NEIClientUtils.getGuiContainer() instanceof GuiRecipe<?>recipe) {
|
||||
recipe.forceRefreshPage();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private void drawKeyLabel(String keyLabel, int topShift) {
|
||||
final String displayLabel = translateDisplayLabel(keyLabel);
|
||||
GuiDraw.drawString(
|
||||
NEIClientUtils.cropText(GuiDraw.fontRenderer, displayLabel, LABEL_WIDTH),
|
||||
this.x + INLINE_PADDING,
|
||||
topShift,
|
||||
0x66555555,
|
||||
false);
|
||||
GuiDraw.drawString(":", this.x + INLINE_PADDING + LABEL_WIDTH, topShift, 0x66555555, false);
|
||||
}
|
||||
|
||||
private void drawDetail(String keyLabel, String valueLabel, int topShift, int spaceWidth) {
|
||||
drawKeyLabel(keyLabel, topShift);
|
||||
GuiDraw.drawString(
|
||||
NEIClientUtils.cropText(
|
||||
GuiDraw.fontRenderer,
|
||||
valueLabel,
|
||||
this.w - INLINE_PADDING * 2 - LABEL_WIDTH - spaceWidth),
|
||||
this.x + INLINE_PADDING + LABEL_WIDTH + spaceWidth,
|
||||
topShift,
|
||||
0xffffff);
|
||||
}
|
||||
|
||||
private void drawControl(String keyLabel, Widget field, int topShift, int spaceWidth) {
|
||||
drawKeyLabel(keyLabel, topShift);
|
||||
|
||||
field.x = this.x + INLINE_PADDING + LABEL_WIDTH + spaceWidth;
|
||||
field.y = topShift - 4;
|
||||
field.w = this.w - INLINE_PADDING * 2 - LABEL_WIDTH - spaceWidth;
|
||||
}
|
||||
|
||||
private static String translateTooltipLabel(String label) {
|
||||
String key = TOOLTIP_KEYS.get(label);
|
||||
String text = label;
|
||||
if (key == null) {
|
||||
return EnumChatFormatting.WHITE + EnumChatFormatting.getTextWithoutFormattingCodes(text);
|
||||
}
|
||||
text = NEIClientUtils.translate(key);
|
||||
return EnumChatFormatting.WHITE + EnumChatFormatting.getTextWithoutFormattingCodes(text);
|
||||
}
|
||||
|
||||
private static String translateDisplayLabel(String label) {
|
||||
String key = TOOLTIP_KEYS.get(label);
|
||||
if (key == null) {
|
||||
return label;
|
||||
}
|
||||
return NEIClientUtils.translate(key);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void draw(int mx, int my) {
|
||||
|
||||
if (this.handler != null) {
|
||||
final int spaceWidth = GuiDraw.fontRenderer.getStringWidth(": ");
|
||||
int topShift = this.y + BORDER_PADDING + 12 + 6;
|
||||
|
||||
GL11.glColor4f(1F, 1F, 1F, 1F);
|
||||
GL11.glScaled(1, 1, 2f);
|
||||
GL11.glDisable(GL11.GL_DEPTH_TEST);
|
||||
BG_TEXTURE.draw(
|
||||
this.x - TRANSPARENCY_BORDER,
|
||||
this.y - TRANSPARENCY_BORDER,
|
||||
this.w + TRANSPARENCY_BORDER * 2,
|
||||
this.h + TRANSPARENCY_BORDER * 2,
|
||||
BORDER_PADDING + TRANSPARENCY_BORDER,
|
||||
BORDER_PADDING + TRANSPARENCY_BORDER,
|
||||
BORDER_PADDING + TRANSPARENCY_BORDER,
|
||||
BORDER_PADDING + TRANSPARENCY_BORDER);
|
||||
GuiDraw.drawRect(
|
||||
this.x + INLINE_PADDING,
|
||||
this.y + BORDER_PADDING,
|
||||
this.w - INLINE_PADDING * 2,
|
||||
12,
|
||||
0x30000000);
|
||||
GuiDraw.drawStringC(
|
||||
NEIClientUtils.translate("debug.RecipeHandler.title"),
|
||||
this.x + this.w / 2,
|
||||
this.y + BORDER_PADDING + 2,
|
||||
0xffffff);
|
||||
|
||||
for (Map.Entry<String, String> entry : getDetailsInfo().entrySet()) {
|
||||
drawDetail(entry.getKey(), entry.getValue(), topShift, spaceWidth);
|
||||
topShift += LINE_HEIGHT;
|
||||
}
|
||||
|
||||
drawControl("Order", this.order, topShift, spaceWidth);
|
||||
topShift += LINE_HEIGHT;
|
||||
|
||||
drawControl("yShift", this.yShift, topShift, spaceWidth);
|
||||
topShift += LINE_HEIGHT;
|
||||
|
||||
drawControl("Multi Widgets", this.multipleWidgetsAllowed, topShift, spaceWidth);
|
||||
topShift += LINE_HEIGHT;
|
||||
|
||||
drawControl("Height", this.handlerHeight, topShift, spaceWidth);
|
||||
topShift += LINE_HEIGHT;
|
||||
|
||||
drawControl("Width", this.handlerWidth, topShift, spaceWidth);
|
||||
topShift += LINE_HEIGHT;
|
||||
|
||||
drawControl("Use Custom Scroll", this.useCustomScroll, topShift, spaceWidth);
|
||||
topShift += LINE_HEIGHT;
|
||||
|
||||
GL11.glScaled(1, 1, 1 / 2f);
|
||||
}
|
||||
}
|
||||
|
||||
private Map<String, String> getDetailsInfo() {
|
||||
final Map<String, String> lines = new LinkedHashMap<>();
|
||||
final boolean isHeightHackApplied = NEIClientConfig.heightHackHandlerRegex.stream()
|
||||
.map(pattern -> pattern.matcher(this.handler.getHandlerId())).anyMatch(Matcher::matches);
|
||||
|
||||
lines.put("Name", this.handler.getRecipeName());
|
||||
lines.put("ID", this.handler.getOverlayIdentifier());
|
||||
lines.put("Key", this.handler.getHandlerId());
|
||||
lines.put("H.Hack", String.valueOf(isHeightHackApplied));
|
||||
lines.put("Mod Name", this.handlerInfo.getModName());
|
||||
lines.put("Mod ID", this.handlerInfo.getModId());
|
||||
|
||||
return lines;
|
||||
}
|
||||
|
||||
public void setVisible() {
|
||||
if (showWidget && this.handler != null) {
|
||||
LayoutManager.addWidget(this.order);
|
||||
LayoutManager.addWidget(this.yShift);
|
||||
LayoutManager.addWidget(this.handlerHeight);
|
||||
LayoutManager.addWidget(this.handlerWidth);
|
||||
LayoutManager.addWidget(this.multipleWidgetsAllowed);
|
||||
LayoutManager.addWidget(this.useCustomScroll);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void update() {
|
||||
final GuiContainer gui = NEIClientUtils.getGuiContainer();
|
||||
|
||||
if (showWidget && gui instanceof GuiRecipe recipe) {
|
||||
|
||||
if (this.handler != recipe.getHandler()) {
|
||||
this.handler = recipe.getHandler();
|
||||
this.handlerInfo = GuiRecipeTab.getHandlerInfo(handler);
|
||||
|
||||
this.order.setText(String.valueOf(NEIClientConfig.getHandlerOrder(this.handler)));
|
||||
this.yShift.setText(String.valueOf(this.handlerInfo.getYShift()));
|
||||
this.handlerHeight.setText(String.valueOf(this.handlerInfo.getHeight()));
|
||||
this.handlerWidth.setText(String.valueOf(this.handlerInfo.getWidth()));
|
||||
}
|
||||
|
||||
} else {
|
||||
this.handler = null;
|
||||
this.handlerInfo = null;
|
||||
showWidget = false;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<String> handleTooltip(int mx, int my, List<String> tooltip) {
|
||||
|
||||
if (this.handler != null) {
|
||||
final int spaceWidth = GuiDraw.fontRenderer.getStringWidth(": ");
|
||||
final int leftShift = this.x + INLINE_PADDING;
|
||||
|
||||
if (mx >= leftShift && mx < this.x + WINDOW_WIDTH - INLINE_PADDING) {
|
||||
int topShift = this.y + BORDER_PADDING + 12 + 6;
|
||||
|
||||
for (Map.Entry<String, String> entry : getDetailsInfo().entrySet()) {
|
||||
if (my >= topShift && my < topShift + LINE_HEIGHT) {
|
||||
|
||||
if (mx < leftShift + LABEL_WIDTH + spaceWidth) {
|
||||
tooltip.add(translateTooltipLabel(entry.getKey()));
|
||||
} else {
|
||||
tooltip.add(String.valueOf(entry.getValue()));
|
||||
}
|
||||
|
||||
return tooltip;
|
||||
}
|
||||
topShift += LINE_HEIGHT;
|
||||
}
|
||||
|
||||
String[] controlLabels = new String[] { "Order", "yShift", "Multi Widgets", "Height", "Width",
|
||||
"Use Custom Scroll" };
|
||||
for (String label : controlLabels) {
|
||||
if (my >= topShift && my < topShift + LINE_HEIGHT) {
|
||||
tooltip.add(translateTooltipLabel(label));
|
||||
return tooltip;
|
||||
}
|
||||
topShift += LINE_HEIGHT;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return tooltip;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean keyTyped(GuiContainer gui, char keyChar, int keyCode) {
|
||||
|
||||
if (NEIClientConfig.getBooleanSetting("inventory.guirecipe.handlerInfo") && showWidget
|
||||
&& keyCode == Keyboard.KEY_C
|
||||
&& NEIClientUtils.controlKey()) {
|
||||
final int spaceWidth = GuiDraw.fontRenderer.getStringWidth(": ");
|
||||
final Point mouse = GuiDraw.getMousePosition();
|
||||
|
||||
if (mouse.x >= this.x + INLINE_PADDING + LABEL_WIDTH + spaceWidth
|
||||
&& mouse.x < this.x + WINDOW_WIDTH - INLINE_PADDING) {
|
||||
int topShift = this.y + BORDER_PADDING + 12 + 6;
|
||||
|
||||
for (Map.Entry<String, String> entry : getDetailsInfo().entrySet()) {
|
||||
if (mouse.y >= topShift && mouse.y < topShift + LINE_HEIGHT) {
|
||||
GuiScreen.setClipboardString(entry.getValue());
|
||||
return true;
|
||||
}
|
||||
topShift += LINE_HEIGHT;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean mouseClicked(GuiContainer gui, int mousex, int mousey, int button) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onKeyTyped(GuiContainer gui, char keyChar, int keyID) {}
|
||||
|
||||
@Override
|
||||
public boolean lastKeyTyped(GuiContainer gui, char keyChar, int keyID) {
|
||||
|
||||
if (NEIClientConfig.getBooleanSetting("inventory.guirecipe.handlerInfo") && keyID == Keyboard.KEY_D
|
||||
&& NEIClientUtils.shiftKey()) {
|
||||
showWidget = !showWidget;
|
||||
return true;
|
||||
} else if (this.handler != null) {
|
||||
return this.order.focused() || this.yShift.focused()
|
||||
|| this.handlerHeight.focused()
|
||||
|| this.handlerWidth.focused();
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onMouseClicked(GuiContainer gui, int mousex, int mousey, int button) {
|
||||
if (this.handler != null
|
||||
&& new Rectangle4i(this.x + INLINE_PADDING, this.y + BORDER_PADDING, this.w - INLINE_PADDING * 2, 12)
|
||||
.contains(mousex, mousey)) {
|
||||
this.dragPoint = new Point(mousex, mousey);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean contains(int px, int py) {
|
||||
return this.handler != null && super.contains(px, py);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onMouseUp(GuiContainer gui, int mousex, int mousey, int button) {
|
||||
this.dragPoint = null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean mouseScrolled(GuiContainer gui, int mousex, int mousey, int scrolled) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onMouseScrolled(GuiContainer gui, int mousex, int mousey, int scrolled) {}
|
||||
|
||||
@Override
|
||||
public boolean handleClickExt(int mx, int my, int button) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onMouseDragged(GuiContainer gui, int mousex, int mousey, int button, long heldTime) {
|
||||
if (this.dragPoint != null) {
|
||||
this.x -= this.dragPoint.x - mousex;
|
||||
this.y -= this.dragPoint.y - mousey;
|
||||
this.dragPoint.move(mousex, mousey);
|
||||
}
|
||||
}
|
||||
|
||||
public void drawGuiPlaceholder(NEIRecipeWidget widget) {
|
||||
if (!showWidget) return;
|
||||
|
||||
NEIClientUtils.gl2DRenderContext(() -> {
|
||||
|
||||
// background
|
||||
GuiDraw.drawRect(
|
||||
widget.x,
|
||||
widget.y,
|
||||
widget.w,
|
||||
widget.h,
|
||||
COLORS[widget.handlerRef.recipeIndex % COLORS.length]);
|
||||
|
||||
// center cross
|
||||
GuiDraw.drawRect(widget.x + widget.w / 2 - 1, widget.y, 1, widget.h, 0x88ffffff);
|
||||
GuiDraw.drawRect(widget.x, widget.y + widget.h / 2 - 1, widget.w, 1, 0x88ffffff);
|
||||
|
||||
// blue-line-top (grid-top)
|
||||
GuiDraw.drawRect(widget.x + 14, widget.y + 5, widget.w - 38, 1, 0xff0000aa);
|
||||
|
||||
// blue-line-bottom {grid-bottom}
|
||||
GuiDraw.drawRect(widget.x + 14, widget.y + widget.h - 7, widget.w - 38, 1, 0xff0000aa);
|
||||
|
||||
// blue-left (grid start)
|
||||
GuiDraw.drawRect(widget.x + 24, widget.y + (widget.h - 16) / 2, 1, 16, 0xffaa00aa);
|
||||
|
||||
// purple (before favorite)
|
||||
GuiDraw.drawRect(
|
||||
widget.x + Math.min(168, widget.w) - 27,
|
||||
widget.y + widget.h - 6 - GuiRecipeButton.BUTTON_HEIGHT * 2 - 4,
|
||||
GuiRecipeButton.BUTTON_WIDTH,
|
||||
1,
|
||||
0xffaa00aa);
|
||||
|
||||
// green ()
|
||||
GuiDraw.drawRect(
|
||||
widget.x + Math.min(168, widget.w) - 35,
|
||||
widget.y + widget.h - 6 - GuiRecipeButton.BUTTON_HEIGHT - 3,
|
||||
20,
|
||||
1,
|
||||
0xff00aa00);
|
||||
|
||||
// purple space before bottom grid
|
||||
GuiDraw.drawRect(
|
||||
widget.x + 14,
|
||||
widget.y + widget.h - 7 - GuiRecipeButton.BUTTON_WIDTH / 2,
|
||||
38,
|
||||
1,
|
||||
0xffaa00aa);
|
||||
|
||||
if (widget.handlerRef.handler instanceof TemplateRecipeHandler handler) {
|
||||
int yShift = widget.getHandlerInfo().getYShift();
|
||||
|
||||
for (RecipeTransferRect rect : handler.transferRects) {
|
||||
GuiDraw.drawRect(
|
||||
widget.x + rect.rect.x,
|
||||
widget.y + yShift + rect.rect.y,
|
||||
rect.rect.width,
|
||||
rect.rect.height,
|
||||
0x40ff0000);
|
||||
}
|
||||
}
|
||||
|
||||
});
|
||||
}
|
||||
|
||||
private static Map<String, String[]> patches = new HashMap<>();
|
||||
|
||||
public static void loadHandlerInfoPatch() {
|
||||
|
||||
ClientHandler.loadSettingsFile("handlers.patch", lines -> {
|
||||
|
||||
for (String line : lines.collect(Collectors.toCollection(HashSet::new))) {
|
||||
final String[] parts = line.split(",");
|
||||
final String handler = parts[0];
|
||||
|
||||
if (GuiRecipeTab.handlerMap.containsKey(handler)) {
|
||||
final HandlerInfo info = GuiRecipeTab.handlerMap.get(handler);
|
||||
final int yShift = intOrDefault(parts[1], info.getYShift());
|
||||
final int height = intOrDefault(parts[2], info.getHeight());
|
||||
final int width = intOrDefault(parts[3], info.getWidth());
|
||||
final boolean isMultipleWidgetsAllowed = intOrDefault(
|
||||
parts[4],
|
||||
info.isMultipleWidgetsAllowed() ? 1 : 0) == 1;
|
||||
final int order = intOrDefault(parts[5], NEIClientConfig.handlerOrdering.getOrDefault(handler, 0));
|
||||
final boolean useCustomScroll = intOrDefault(parts[6], info.getUseCustomScroll() ? 1 : 0) == 1;
|
||||
|
||||
info.setYShift(yShift);
|
||||
info.setHandlerDimensions(width, height, isMultipleWidgetsAllowed);
|
||||
info.setUseCustomScroll(useCustomScroll);
|
||||
NEIClientConfig.handlerOrdering.put(handler, order);
|
||||
}
|
||||
|
||||
patches.put(handler, parts);
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
private static void saveHandlerInfoPatch() {
|
||||
final List<String> lines = new ArrayList<>();
|
||||
|
||||
for (String[] line : patches.values()) {
|
||||
lines.add(String.join(",", line));
|
||||
}
|
||||
|
||||
final File path = new File(NEIClientConfig.configDir, "handlers.patch");
|
||||
|
||||
try (FileOutputStream output = new FileOutputStream(path)) {
|
||||
IOUtils.writeLines(lines, "\n", output, StandardCharsets.UTF_8);
|
||||
} catch (IOException e) {}
|
||||
}
|
||||
|
||||
private static int intOrDefault(String str, int defaultValue) {
|
||||
if (str == null || str.equals("")) return defaultValue;
|
||||
try {
|
||||
return Integer.parseInt(str);
|
||||
} catch (NumberFormatException e) {
|
||||
return defaultValue;
|
||||
}
|
||||
}
|
||||
|
||||
private static String getHandlerID(IRecipeHandler handler) {
|
||||
|
||||
if (GuiRecipeTab.handlerMap.containsKey(handler.getHandlerId())) {
|
||||
return handler.getHandlerId();
|
||||
} else if (handler instanceof TemplateRecipeHandler) {
|
||||
return handler.getOverlayIdentifier();
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -98,10 +98,14 @@ public class DefaultOverlayHandler implements IOverlayHandler {
|
||||
&& presenceOverlay(firstGui, handler, recipeIndex).stream().allMatch(state -> state.isPresent());
|
||||
}
|
||||
|
||||
protected Slot getCraftingResultSlot(GuiContainer gui) {
|
||||
return gui.inventorySlots.inventorySlots.stream().filter(slot -> slot instanceof SlotCrafting).findFirst()
|
||||
.orElse(null);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean craft(GuiContainer firstGui, IRecipeHandler handler, int recipeIndex, int multiplier) {
|
||||
final Slot craftingSlot = firstGui.inventorySlots.inventorySlots.stream()
|
||||
.filter(slot -> slot instanceof SlotCrafting).findFirst().orElse(null);
|
||||
final Slot craftingSlot = getCraftingResultSlot(firstGui);
|
||||
|
||||
if (craftingSlot == null) {
|
||||
return false;
|
||||
@@ -145,7 +149,7 @@ public class DefaultOverlayHandler implements IOverlayHandler {
|
||||
|
||||
/**
|
||||
* Gets the slots in the crafting matrix for the given GUI and recipe handler.
|
||||
*
|
||||
*
|
||||
* @param gui
|
||||
* @param handler
|
||||
* @return
|
||||
@@ -193,10 +197,11 @@ public class DefaultOverlayHandler implements IOverlayHandler {
|
||||
return ingredSlots;
|
||||
}
|
||||
|
||||
private void moveIngredients(GuiContainer gui, List<IngredientDistribution> assignedIngredients, int multiplier) {
|
||||
protected void moveIngredients(GuiContainer gui, List<IngredientDistribution> assignedIngredients, int multiplier) {
|
||||
final Slot craftingSlot = getCraftingResultSlot(gui);
|
||||
|
||||
for (Slot slot : gui.inventorySlots.inventorySlots) {
|
||||
if (slot instanceof SlotCrafting || !slot.getHasStack()
|
||||
if (slot == craftingSlot || !slot.getHasStack()
|
||||
|| !canMoveFrom(slot, gui)
|
||||
|| !slot.canTakeStack(gui.mc.thePlayer))
|
||||
continue;
|
||||
@@ -205,7 +210,7 @@ public class DefaultOverlayHandler implements IOverlayHandler {
|
||||
|
||||
for (IngredientDistribution distrib : assignedIngredients) {
|
||||
if (distrib.slots.length == 0 || !slot.getHasStack() || !canStack(distrib.permutation, stack)) continue;
|
||||
int transferCap = Math.min(slotTransferCap, multiplier * distrib.permutation.stackSize);
|
||||
int transferCap = Math.min(slotTransferCap, Math.max(multiplier * distrib.permutation.stackSize, 1));
|
||||
int stackSize = slot.getStack().stackSize;
|
||||
boolean pickup = false;
|
||||
|
||||
@@ -244,7 +249,7 @@ public class DefaultOverlayHandler implements IOverlayHandler {
|
||||
}
|
||||
}
|
||||
|
||||
private int calculateRecipeQuantity(List<IngredientDistribution> assignedIngredients) {
|
||||
protected int calculateRecipeQuantity(List<IngredientDistribution> assignedIngredients) {
|
||||
int quantity = Integer.MAX_VALUE;
|
||||
|
||||
for (IngredientDistribution distrib : assignedIngredients) {
|
||||
@@ -270,7 +275,7 @@ public class DefaultOverlayHandler implements IOverlayHandler {
|
||||
return quantity;
|
||||
}
|
||||
|
||||
private Slot[][] assignIngredSlots(GuiContainer gui, List<PositionedStack> ingredients,
|
||||
protected Slot[][] assignIngredSlots(GuiContainer gui, List<PositionedStack> ingredients,
|
||||
List<IngredientDistribution> assignedIngredients) {
|
||||
Slot[][] recipeSlots = mapIngredSlots(gui, ingredients); // setup the slot map
|
||||
|
||||
@@ -315,7 +320,7 @@ public class DefaultOverlayHandler implements IOverlayHandler {
|
||||
return recipeSlots;
|
||||
}
|
||||
|
||||
private List<IngredientDistribution> assignIngredients(List<PositionedStack> ingredients,
|
||||
protected List<IngredientDistribution> assignIngredients(List<PositionedStack> ingredients,
|
||||
List<DistributedIngred> ingredStacks) {
|
||||
ArrayList<IngredientDistribution> assignedIngredients = new ArrayList<>();
|
||||
for (PositionedStack posstack : ingredients) // assign what we need and have
|
||||
@@ -353,7 +358,7 @@ public class DefaultOverlayHandler implements IOverlayHandler {
|
||||
return assignedIngredients;
|
||||
}
|
||||
|
||||
private void findInventoryQuantities(GuiContainer gui, List<DistributedIngred> ingredStacks) {
|
||||
protected void findInventoryQuantities(GuiContainer gui, List<DistributedIngred> ingredStacks) {
|
||||
for (Slot slot : gui.inventorySlots.inventorySlots) /* work out how much we have to go round */ {
|
||||
if (slot.getHasStack() && canMoveFrom(slot, gui)) {
|
||||
final ItemStack pstack = slot.getStack();
|
||||
@@ -385,7 +390,7 @@ public class DefaultOverlayHandler implements IOverlayHandler {
|
||||
}
|
||||
}
|
||||
|
||||
private List<DistributedIngred> getPermutationIngredients(List<PositionedStack> ingredients) {
|
||||
protected List<DistributedIngred> getPermutationIngredients(List<PositionedStack> ingredients) {
|
||||
ArrayList<DistributedIngred> ingredStacks = new ArrayList<>();
|
||||
for (PositionedStack posstack : ingredients) /* work out what we need */ {
|
||||
for (ItemStack pstack : posstack.items) {
|
||||
@@ -422,8 +427,8 @@ public class DefaultOverlayHandler implements IOverlayHandler {
|
||||
return null;
|
||||
}
|
||||
|
||||
protected boolean canStack(ItemStack stack1, ItemStack stack2) {
|
||||
if (stack1 == null || stack2 == null) return true;
|
||||
return NEIClientUtils.areStacksSameTypeCraftingWithNBT(stack1, stack2);
|
||||
protected boolean canStack(ItemStack dst, ItemStack src) {
|
||||
if (dst == null || src == null) return true;
|
||||
return NEIClientUtils.areStacksSameTypeCraftingWithNBT(dst, src);
|
||||
}
|
||||
}
|
||||
@@ -38,6 +38,11 @@ public class FuelRecipeHandler extends FurnaceRecipeHandler {
|
||||
public PositionedStack getOtherStack() {
|
||||
return fuel.stack;
|
||||
}
|
||||
|
||||
@Override
|
||||
public PositionedStack getCatalyst() {
|
||||
return fuel.stack;
|
||||
}
|
||||
}
|
||||
|
||||
private final ArrayList<SmeltingPair> mfurnace = new ArrayList<>();
|
||||
|
||||
@@ -21,7 +21,6 @@ import codechicken.nei.NEIClientUtils;
|
||||
import codechicken.nei.bookmark.BookmarkItem.BookmarkItemType;
|
||||
import codechicken.nei.bookmark.BookmarksGridSlot;
|
||||
import codechicken.nei.recipe.Recipe.RecipeId;
|
||||
import codechicken.nei.recipe.TemplateRecipeHandler.RecipeTransferRect;
|
||||
|
||||
public class GuiCraftingRecipe extends GuiRecipe<ICraftingHandler> {
|
||||
|
||||
@@ -83,8 +82,8 @@ public class GuiCraftingRecipe extends GuiRecipe<ICraftingHandler> {
|
||||
} else if ("recipeId".equals(outputId)) {
|
||||
ItemStack stack = (ItemStack) results[0];
|
||||
RecipeId recipeId = (RecipeId) results[1];
|
||||
craftinghandlers = filterByHandlerName(craftinghandlers, recipeId.getHandleName());
|
||||
serialCraftingHandlers = filterByHandlerName(serialCraftingHandlers, recipeId.getHandleName());
|
||||
craftinghandlers = filterByHandlerName(craftinghandlers, recipeId.getHandlerName());
|
||||
serialCraftingHandlers = filterByHandlerName(serialCraftingHandlers, recipeId.getHandlerName());
|
||||
recipeHandlerFunction = h -> h.getRecipeHandler("item", stack);
|
||||
} else {
|
||||
recipeHandlerFunction = h -> h.getRecipeHandler(outputId, results);
|
||||
@@ -103,18 +102,7 @@ public class GuiCraftingRecipe extends GuiRecipe<ICraftingHandler> {
|
||||
|
||||
private static ICraftingHandler buildAllRecipesHandler(ICraftingHandler handler) {
|
||||
if (handler instanceof TemplateRecipeHandler templateHandler) {
|
||||
TemplateRecipeHandler allHandler = templateHandler.newInstance();
|
||||
if (allHandler.transferRects.isEmpty()) {
|
||||
allHandler.loadCraftingRecipes("all");
|
||||
return allHandler;
|
||||
}
|
||||
for (RecipeTransferRect rect : allHandler.transferRects) {
|
||||
if (allHandler.specifyTransferRect() == null
|
||||
|| allHandler.specifyTransferRect().equals(rect.outputId)) {
|
||||
allHandler.loadCraftingRecipes(rect.outputId, rect.results);
|
||||
return allHandler;
|
||||
}
|
||||
}
|
||||
return templateHandler.getAllRecipeHandler();
|
||||
}
|
||||
return handler.getRecipeHandler("all");
|
||||
}
|
||||
|
||||
@@ -19,6 +19,7 @@ import codechicken.nei.FavoriteRecipes;
|
||||
import codechicken.nei.Image;
|
||||
import codechicken.nei.ItemPanels;
|
||||
import codechicken.nei.ItemStackSet;
|
||||
import codechicken.nei.KeyManager;
|
||||
import codechicken.nei.LayoutManager;
|
||||
import codechicken.nei.NEIClientConfig;
|
||||
import codechicken.nei.NEIClientUtils;
|
||||
@@ -54,7 +55,7 @@ public class GuiFavoriteButton extends GuiRecipeButton {
|
||||
super(handlerRef, x, y, BUTTON_ID_START + handlerRef.recipeIndex, "❤");
|
||||
this.recipe = Recipe.of(this.handlerRef);
|
||||
|
||||
ItemStack stack = FavoriteRecipes.getFavorite(this.recipe.getRecipeId());
|
||||
ItemStack stack = FavoriteRecipes.getManualFavorite(this.recipe.getRecipeId());
|
||||
this.favorite = stack != null;
|
||||
|
||||
if (stack == null) {
|
||||
@@ -88,7 +89,7 @@ public class GuiFavoriteButton extends GuiRecipeButton {
|
||||
|
||||
@Override
|
||||
public void update() {
|
||||
this.favorite = this.favorite && FavoriteRecipes.getFavorite(this.recipe.getRecipeId()) != null;
|
||||
this.favorite = this.favorite && FavoriteRecipes.getManualFavorite(this.recipe.getRecipeId()) != null;
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -122,7 +123,7 @@ public class GuiFavoriteButton extends GuiRecipeButton {
|
||||
|
||||
public void lastKeyTyped(char keyChar, int keyID) {
|
||||
|
||||
if (NEIClientConfig.isKeyHashDown("gui.bookmark") && NEIClientUtils.shiftKey()) {
|
||||
if (KeyManager.isKeyDown("bookmark.add") && NEIClientUtils.shiftKey()) {
|
||||
saveRecipeInBookmark();
|
||||
}
|
||||
|
||||
@@ -131,7 +132,7 @@ public class GuiFavoriteButton extends GuiRecipeButton {
|
||||
@Override
|
||||
public Map<String, String> handleHotkeys(int mousex, int mousey, Map<String, String> hotkeys) {
|
||||
hotkeys.put(
|
||||
NEIClientConfig.getKeyName("gui.bookmark", NEIClientUtils.SHIFT_HASH),
|
||||
KeyManager.getKeyName("bookmark.add", NEIClientUtils.SHIFT_HASH),
|
||||
translate("recipe.favorite.bookmark_recipe"));
|
||||
|
||||
if (this.recipe.getResults().size() > 1) {
|
||||
@@ -146,7 +147,6 @@ public class GuiFavoriteButton extends GuiRecipeButton {
|
||||
@Override
|
||||
public List<String> handleTooltip(List<String> currenttip) {
|
||||
currenttip.add(translate("recipe.favorite"));
|
||||
|
||||
return currenttip;
|
||||
}
|
||||
|
||||
@@ -178,7 +178,7 @@ public class GuiFavoriteButton extends GuiRecipeButton {
|
||||
this.selectedResult = results.get(nextIndex);
|
||||
this.favorite = StackInfo.equalItemAndNBT(
|
||||
results.get(nextIndex).getItemStack(),
|
||||
FavoriteRecipes.getFavorite(this.recipe.getRecipeId()),
|
||||
FavoriteRecipes.getManualFavorite(this.recipe.getRecipeId()),
|
||||
true);
|
||||
|
||||
return true;
|
||||
@@ -206,29 +206,47 @@ public class GuiFavoriteButton extends GuiRecipeButton {
|
||||
|
||||
if (stack == null) {
|
||||
stack = ingr.getItemStack();
|
||||
RecipeId recipeId = FavoriteRecipes.getFavorite(stack);
|
||||
RecipeId recipeId = FavoriteRecipes.getManualFavorite(stack);
|
||||
|
||||
if (recipeId == null) {
|
||||
for (ItemStack permStack : permutations) {
|
||||
if ((recipeId = FavoriteRecipes.getFavorite(permStack)) != null) {
|
||||
if ((recipeId = FavoriteRecipes.getManualFavorite(permStack)) != null) {
|
||||
stack = permStack;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Recipe recipe = Recipe.of(recipeId);
|
||||
if (recipeId == null) {
|
||||
recipeId = FavoriteRecipes.getGeneratedFavorite(stack);
|
||||
}
|
||||
|
||||
if (recipe == null) {
|
||||
stack = null;
|
||||
} else {
|
||||
items.add(stack);
|
||||
|
||||
if (depth >= 0) {
|
||||
result.add(recipe);
|
||||
localLoop.add(recipe);
|
||||
if (recipeId == null) {
|
||||
for (ItemStack permStack : permutations) {
|
||||
if ((recipeId = FavoriteRecipes.getGeneratedFavorite(permStack)) != null) {
|
||||
stack = permStack;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (recipeId != null && FavoriteRecipes.FAVORITE_ITEM.contains(recipeId.getHandlerName())) {
|
||||
items.add(stack);
|
||||
} else {
|
||||
Recipe recipe = Recipe.of(recipeId);
|
||||
|
||||
if (recipe == null) {
|
||||
stack = null;
|
||||
} else {
|
||||
items.add(stack);
|
||||
|
||||
if (depth >= 0) {
|
||||
result.add(recipe);
|
||||
localLoop.add(recipe);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if (stack != null) {
|
||||
|
||||
@@ -3,7 +3,6 @@ package codechicken.nei.recipe;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Optional;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import net.minecraft.client.Minecraft;
|
||||
@@ -16,11 +15,14 @@ import org.lwjgl.opengl.GL11;
|
||||
import codechicken.lib.gui.GuiDraw;
|
||||
import codechicken.nei.ItemPanels;
|
||||
import codechicken.nei.ItemsTooltipLineHandler;
|
||||
import codechicken.nei.KeyManager;
|
||||
import codechicken.nei.LayoutManager;
|
||||
import codechicken.nei.NEIClientConfig;
|
||||
import codechicken.nei.NEIClientUtils;
|
||||
import codechicken.nei.PositionedStack;
|
||||
import codechicken.nei.api.IOverlayHandler;
|
||||
import codechicken.nei.bookmark.BookmarkGrid;
|
||||
import codechicken.nei.bookmark.BookmarkPayload;
|
||||
import codechicken.nei.drawable.DrawableBuilder;
|
||||
import codechicken.nei.drawable.DrawableResource;
|
||||
import codechicken.nei.util.NEIMouseUtils;
|
||||
@@ -97,26 +99,37 @@ public class GuiOverlayButton extends GuiRecipeButton {
|
||||
super(handlerRef, x, y, handlerRef.recipeIndex + BUTTON_ID_SHIFT, "+");
|
||||
this.firstGui = firstGui != null && firstGui.inventorySlots != null ? firstGui : null;
|
||||
|
||||
this.canUseOverlayRenderer = this.firstGui != null && handlerRef.getRecipeOverlayRenderer(firstGui) != null;
|
||||
this.canFillCraftingGrid = this.firstGui != null && handlerRef.getOverlayHandler(firstGui) != null;
|
||||
this.hasOverlay = this.canUseOverlayRenderer || this.canFillCraftingGrid;
|
||||
IOverlayHandler overlayHandler = null;
|
||||
|
||||
setRequireShiftForOverlayRecipe(NEIClientConfig.requireShiftForOverlayRecipe());
|
||||
if (this.firstGui != null) {
|
||||
overlayHandler = this.handlerRef.getOverlayHandler(this.firstGui);
|
||||
this.canUseOverlayRenderer = this.handlerRef.getRecipeOverlayRenderer(this.firstGui) != null;
|
||||
this.canFillCraftingGrid = this.handlerRef.canFillCraftingGrid(this.firstGui);
|
||||
this.hasOverlay = this.canUseOverlayRenderer || overlayHandler != null;
|
||||
}
|
||||
|
||||
setRequireShiftForOverlayRecipe(
|
||||
overlayHandler != null ? overlayHandler.requireShiftForOverlayRecipe()
|
||||
: NEIClientConfig.requireShiftForOverlayRecipe());
|
||||
ingredientsOverlay();
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<String> handleTooltip(List<String> currenttip) {
|
||||
currenttip.add(NEIClientUtils.translate("recipe.overlay"));
|
||||
|
||||
if (!this.enabled && requireShiftForOverlayRecipe() && canFillCraftingGrid()) {
|
||||
currenttip.set(currenttip.size() - 1, currenttip.get(currenttip.size() - 1) + GuiDraw.TOOLTIP_LINESPACE);
|
||||
currenttip.add(
|
||||
EnumChatFormatting.RED + NEIClientUtils.translate("recipe.overlay.mismatch")
|
||||
+ EnumChatFormatting.RESET);
|
||||
} else if (this.missedMaterialsTooltipLineHandler != null) {
|
||||
if (!this.enabled || this.missedMaterialsTooltipLineHandler != null && this.canFillCraftingGrid) {
|
||||
currenttip.add(NEIClientUtils.translate("recipe.overlay") + GuiDraw.TOOLTIP_LINESPACE);
|
||||
} else {
|
||||
currenttip.add(NEIClientUtils.translate("recipe.overlay"));
|
||||
}
|
||||
|
||||
if ((!requireShiftForOverlayRecipe() || NEIClientUtils.shiftKey()) && canFillCraftingGrid()) {
|
||||
if (!this.enabled) {
|
||||
currenttip.add(EnumChatFormatting.RED + NEIClientUtils.translate("recipe.overlay.mismatch"));
|
||||
}
|
||||
|
||||
if (this.missedMaterialsTooltipLineHandler != null && this.canFillCraftingGrid) {
|
||||
|
||||
if (!requireShiftForOverlayRecipe() || NEIClientUtils.shiftKey()) {
|
||||
this.missedMaterialsTooltipLineHandler.setLabelColor(EnumChatFormatting.RED);
|
||||
} else {
|
||||
this.missedMaterialsTooltipLineHandler.setLabelColor(EnumChatFormatting.GRAY);
|
||||
@@ -152,13 +165,17 @@ public class GuiOverlayButton extends GuiRecipeButton {
|
||||
}
|
||||
|
||||
hotkeys.put(
|
||||
NEIClientConfig.getKeyName("gui.bookmark", NEIClientUtils.SHIFT_HASH),
|
||||
KeyManager.getKeyName("bookmark.add", NEIClientUtils.SHIFT_HASH),
|
||||
NEIClientUtils.translate("recipe.overlay.bookmarkRecipe"));
|
||||
|
||||
hotkeys.put(
|
||||
NEIClientConfig.getKeyName("gui.bookmark", NEIClientUtils.SHIFT_HASH + NEIClientUtils.CTRL_HASH),
|
||||
KeyManager.getKeyName("bookmark.add", NEIClientUtils.SHIFT_HASH + NEIClientUtils.CTRL_HASH),
|
||||
NEIClientUtils.translate("recipe.overlay.bookmarkRecipeAndCount"));
|
||||
|
||||
hotkeys.put(
|
||||
KeyManager.getKeyName("bookmark.chat_link", NEIClientUtils.SHIFT_HASH + NEIClientUtils.CTRL_HASH),
|
||||
NEIClientUtils.translate("recipe.overlay.sendRecipeToChat"));
|
||||
|
||||
return hotkeys;
|
||||
}
|
||||
|
||||
@@ -174,7 +191,7 @@ public class GuiOverlayButton extends GuiRecipeButton {
|
||||
protected void drawContent(Minecraft minecraft, int y, int x, boolean mouseOver) {
|
||||
DrawableResource icon = ICON_OVERLAY;
|
||||
|
||||
if (hasOverlay() && (!requireShiftForOverlayRecipe() || NEIClientUtils.shiftKey())) {
|
||||
if (this.canFillCraftingGrid && (!requireShiftForOverlayRecipe() || NEIClientUtils.shiftKey())) {
|
||||
icon = this.missedMaterialsTooltipLineHandler == null ? ICON_FILL : ICON_FILL_ERROR;
|
||||
}
|
||||
|
||||
@@ -212,10 +229,12 @@ public class GuiOverlayButton extends GuiRecipeButton {
|
||||
if (this.itemPresenceCache.size() != ingredients.size()) {
|
||||
this.itemPresenceCache.clear();
|
||||
|
||||
if (canFillCraftingGrid()) {
|
||||
if (this.firstGui != null) {
|
||||
this.itemPresenceCache.addAll(this.handlerRef.getPresenceOverlay(this.firstGui));
|
||||
} else if (this.firstGui != null) {
|
||||
this.itemPresenceCache.addAll(presenceOverlay(ingredients));
|
||||
|
||||
if (this.itemPresenceCache.isEmpty()) {
|
||||
this.itemPresenceCache.addAll(presenceOverlay(ingredients));
|
||||
}
|
||||
}
|
||||
|
||||
final List<ItemStack> items = this.itemPresenceCache.stream().filter(state -> !state.isPresent())
|
||||
@@ -230,6 +249,8 @@ public class GuiOverlayButton extends GuiRecipeButton {
|
||||
} else {
|
||||
this.missedMaterialsTooltipLineHandler = null;
|
||||
}
|
||||
|
||||
updateEnabled();
|
||||
}
|
||||
|
||||
return this.itemPresenceCache;
|
||||
@@ -237,7 +258,12 @@ public class GuiOverlayButton extends GuiRecipeButton {
|
||||
|
||||
public void setRequireShiftForOverlayRecipe(boolean require) {
|
||||
this.requireShiftForOverlayRecipe = require;
|
||||
this.enabled = hasOverlay() && (this.requireShiftForOverlayRecipe || canFillCraftingGrid());
|
||||
updateEnabled();
|
||||
}
|
||||
|
||||
private void updateEnabled() {
|
||||
this.enabled = hasOverlay() || this.canFillCraftingGrid
|
||||
&& (this.requireShiftForOverlayRecipe || this.missedMaterialsTooltipLineHandler == null);
|
||||
}
|
||||
|
||||
public void setCanUseOverlayRenderer(boolean use) {
|
||||
@@ -253,7 +279,7 @@ public class GuiOverlayButton extends GuiRecipeButton {
|
||||
}
|
||||
|
||||
public boolean canFillCraftingGrid() {
|
||||
return this.missedMaterialsTooltipLineHandler == null || this.handlerRef.canFillCraftingGrid(this.firstGui);
|
||||
return this.canFillCraftingGrid && this.missedMaterialsTooltipLineHandler == null;
|
||||
}
|
||||
|
||||
public boolean hasOverlay() {
|
||||
@@ -265,7 +291,7 @@ public class GuiOverlayButton extends GuiRecipeButton {
|
||||
}
|
||||
|
||||
protected List<ItemOverlayState> presenceOverlay(List<PositionedStack> ingredients) {
|
||||
final List<ItemOverlayState> itemPresenceSlots = new ArrayList<>();
|
||||
final List<ItemOverlayState> states = new ArrayList<>();
|
||||
final List<ItemStack> invStacks = this.firstGui.inventorySlots.inventorySlots.stream()
|
||||
.filter(
|
||||
s -> s != null && s.getStack() != null
|
||||
@@ -275,28 +301,29 @@ public class GuiOverlayButton extends GuiRecipeButton {
|
||||
.map(s -> s.getStack().copy()).collect(Collectors.toCollection(ArrayList::new));
|
||||
|
||||
for (PositionedStack stack : ingredients) {
|
||||
Optional<ItemStack> used = invStacks.stream().filter(is -> is.stackSize > 0 && stack.contains(is))
|
||||
.findAny();
|
||||
boolean found = false;
|
||||
|
||||
itemPresenceSlots.add(new ItemOverlayState(stack, used.isPresent()));
|
||||
|
||||
if (used.isPresent()) {
|
||||
ItemStack is = used.get();
|
||||
is.stackSize -= 1;
|
||||
for (ItemStack is : invStacks) {
|
||||
if (is.stackSize > 0 && stack.contains(is)) {
|
||||
is.stackSize--;
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
states.add(new ItemOverlayState(stack, found));
|
||||
}
|
||||
|
||||
return itemPresenceSlots;
|
||||
return states;
|
||||
}
|
||||
|
||||
public void overlayRecipe(boolean shift) {
|
||||
if (!hasOverlay()) return;
|
||||
|
||||
if (!requireShiftForOverlayRecipe() || shift) {
|
||||
if (canFillCraftingGrid()) {
|
||||
if (this.canFillCraftingGrid) {
|
||||
this.handlerRef.fillCraftingGrid(this.firstGui, 0);
|
||||
}
|
||||
} else if (useOverlayRenderer()) {
|
||||
} else if (hasOverlay() && useOverlayRenderer()) {
|
||||
this.handlerRef.useOverlayRenderer(this.firstGui);
|
||||
}
|
||||
|
||||
@@ -304,9 +331,13 @@ public class GuiOverlayButton extends GuiRecipeButton {
|
||||
|
||||
@Override
|
||||
public void lastKeyTyped(char keyChar, int keyID) {
|
||||
if (NEIClientConfig.isKeyHashDown("gui.bookmark") && NEIClientUtils.shiftKey()) {
|
||||
if (KeyManager.isKeyDown("bookmark.add") && NEIClientUtils.shiftKey()) {
|
||||
saveRecipeInBookmark();
|
||||
}
|
||||
|
||||
if (KeyManager.isKeyDown("bookmark.chat_link") && NEIClientUtils.controlKey() && NEIClientUtils.shiftKey()) {
|
||||
sendRecipeChatLink();
|
||||
}
|
||||
}
|
||||
|
||||
public void saveRecipeInBookmark() {
|
||||
@@ -321,4 +352,7 @@ public class GuiOverlayButton extends GuiRecipeButton {
|
||||
}
|
||||
}
|
||||
|
||||
private void sendRecipeChatLink() {
|
||||
NEIClientUtils.sendChatItemLink(BookmarkPayload.of(getRecipe()).toNBT());
|
||||
}
|
||||
}
|
||||
@@ -17,7 +17,6 @@ import net.minecraft.client.renderer.OpenGlHelper;
|
||||
import net.minecraft.client.renderer.RenderHelper;
|
||||
import net.minecraft.inventory.Slot;
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.util.EnumChatFormatting;
|
||||
|
||||
import org.lwjgl.input.Keyboard;
|
||||
import org.lwjgl.opengl.GL11;
|
||||
@@ -25,7 +24,9 @@ import org.lwjgl.opengl.GL11;
|
||||
import codechicken.lib.gui.GuiDraw;
|
||||
import codechicken.lib.vec.Rectangle4i;
|
||||
import codechicken.nei.Button;
|
||||
import codechicken.nei.ColorUtils;
|
||||
import codechicken.nei.GuiNEIButton;
|
||||
import codechicken.nei.KeyManager;
|
||||
import codechicken.nei.NEICPH;
|
||||
import codechicken.nei.NEIClientConfig;
|
||||
import codechicken.nei.NEIClientUtils;
|
||||
@@ -53,6 +54,7 @@ import codechicken.nei.scroll.ScrollBar;
|
||||
import codechicken.nei.scroll.ScrollBar.OverflowType;
|
||||
import codechicken.nei.scroll.ScrollBar.ScrollPlace;
|
||||
import codechicken.nei.scroll.ScrollContainer;
|
||||
import codechicken.nei.util.EmptyContainer;
|
||||
import codechicken.nei.util.SlotInaccessible;
|
||||
|
||||
public abstract class GuiRecipe<H extends IRecipeHandler> extends GuiContainer implements IGuiContainerOverlay,
|
||||
@@ -92,6 +94,9 @@ public abstract class GuiRecipe<H extends IRecipeHandler> extends GuiContainer i
|
||||
private GuiButton prevtype;
|
||||
private GuiButton nexttype;
|
||||
|
||||
private Rectangle typeArea = new Rectangle();
|
||||
private Rectangle pageArea = new Rectangle();
|
||||
|
||||
private int lastPage = -1;
|
||||
private final GuiRecipeTabs recipeTabs;
|
||||
private final GuiRecipeCatalyst recipeCatalyst;
|
||||
@@ -177,7 +182,7 @@ public abstract class GuiRecipe<H extends IRecipeHandler> extends GuiContainer i
|
||||
private boolean isHeightHackApplied = false;
|
||||
|
||||
protected GuiRecipe(GuiScreen prevgui) {
|
||||
super(new ContainerRecipe());
|
||||
super(new EmptyContainer());
|
||||
this.recipeTabs = new GuiRecipeTabs() {
|
||||
|
||||
@Override
|
||||
@@ -187,7 +192,7 @@ public abstract class GuiRecipe<H extends IRecipeHandler> extends GuiContainer i
|
||||
|
||||
};
|
||||
this.recipeCatalyst = new GuiRecipeCatalyst();
|
||||
this.slotcontainer = (ContainerRecipe) this.inventorySlots;
|
||||
this.slotcontainer = (EmptyContainer) this.inventorySlots;
|
||||
|
||||
this.prevGui = prevgui;
|
||||
this.firstGuiGeneral = prevgui;
|
||||
@@ -308,7 +313,7 @@ public abstract class GuiRecipe<H extends IRecipeHandler> extends GuiContainer i
|
||||
@Override
|
||||
public Widget getWidgetUnderMouse(int mousex, int mousey) {
|
||||
|
||||
if (handlerInfo.getUseCustomScroll() && !this.widgets.isEmpty()) {
|
||||
if (handlerInfo.isAllowOverflowY() && !this.widgets.isEmpty()) {
|
||||
return this.widgets.get(0);
|
||||
}
|
||||
|
||||
@@ -346,7 +351,7 @@ public abstract class GuiRecipe<H extends IRecipeHandler> extends GuiContainer i
|
||||
|
||||
this.container.x = this.guiLeft + 3;
|
||||
this.container.y = this.guiTop + 32;
|
||||
this.container.h = this.ySize - 32 - 5;
|
||||
this.container.h = this.ySize - 32 - 4;
|
||||
|
||||
GuiRecipe.toggleSearch.icon = new DrawableBuilder("nei:textures/nei_sprites.png", 0, 76, 10, 10).build();
|
||||
GuiRecipe.toggleSearch.w = GuiRecipe.toggleSearch.h = 12;
|
||||
@@ -358,8 +363,18 @@ public abstract class GuiRecipe<H extends IRecipeHandler> extends GuiContainer i
|
||||
GuiRecipe.searchField.w = this.xSize - (BORDER_PADDING + BUTTON_WIDTH) * 2 + 1 - GuiRecipe.toggleSearch.w - 45;
|
||||
GuiRecipe.searchField.h = 14;
|
||||
|
||||
this.buttonList.addAll(Arrays.asList(this.prevtype, this.nexttype, this.prevpage, this.nextpage));
|
||||
this.typeArea.setBounds(
|
||||
this.prevtype.xPosition + BUTTON_WIDTH,
|
||||
this.prevtype.yPosition,
|
||||
this.nexttype.xPosition - this.prevtype.xPosition - BUTTON_WIDTH - 1,
|
||||
BUTTON_HEIGHT);
|
||||
this.pageArea.setBounds(
|
||||
this.prevpage.xPosition + BUTTON_WIDTH,
|
||||
this.prevpage.yPosition,
|
||||
this.nextpage.xPosition - this.prevpage.xPosition - BUTTON_WIDTH - 1,
|
||||
BUTTON_HEIGHT);
|
||||
|
||||
this.buttonList.addAll(Arrays.asList(this.prevtype, this.nexttype, this.prevpage, this.nextpage));
|
||||
if (this.currenthandlers.size() == 1) {
|
||||
this.prevtype.visible = false;
|
||||
this.nexttype.visible = false;
|
||||
@@ -372,9 +387,19 @@ public abstract class GuiRecipe<H extends IRecipeHandler> extends GuiContainer i
|
||||
|
||||
if (this.handlerPages.rebuildPages() || this.lastPage != this.handlerPages.getCurrentPageIndex()) {
|
||||
this.lastPage = this.handlerPages.getCurrentPageIndex();
|
||||
updateContainerSize();
|
||||
|
||||
this.container.setWidgets(this.handlerPages.getCurrentPageWidgets());
|
||||
|
||||
if (this.handlerInfo.getUseCustomScroll()) {
|
||||
if (!this.handlerInfo.isAllowOverflowX() && this.handlerInfo.getWidth() > this.xSize - 6) {
|
||||
this.container.setPaddingInline(0, 2);
|
||||
this.container.setHorizontalScroll(ScrollBar.defaultHorizontalBar().setTrackPadding(1, 0, 1, 0));
|
||||
} else {
|
||||
this.container.setPaddingInline(0, 0);
|
||||
this.container.setHorizontalScroll(null);
|
||||
}
|
||||
|
||||
if (this.handlerInfo.isAllowOverflowY()) {
|
||||
this.container.setVerticalScroll(null);
|
||||
} else if (this.container.w == this.xSize - 6) {
|
||||
this.container.setVerticalScroll(VERTICAL_SCROLLBAR);
|
||||
@@ -416,7 +441,7 @@ public abstract class GuiRecipe<H extends IRecipeHandler> extends GuiContainer i
|
||||
this.recipetype = (this.currenthandlers.size() + idx) % this.currenthandlers.size();
|
||||
this.handler = new SearchRecipeHandler<>(this.currenthandlers.get(this.recipetype));
|
||||
this.handlerInfo = GuiRecipeTab.getHandlerInfo(this.handler.original);
|
||||
this.container.w = Math.max(this.xSize - 6, this.handlerInfo.getWidth());
|
||||
updateContainerSize();
|
||||
this.handlerPages = new RecipePageManager(this.handler, this.handlerInfo, this.container);
|
||||
this.prevpage.enabled = this.nextpage.enabled = this.handlerPages.getNumPages() > 1;
|
||||
this.lastPage = -1;
|
||||
@@ -426,9 +451,21 @@ public abstract class GuiRecipe<H extends IRecipeHandler> extends GuiContainer i
|
||||
GuiRecipe.toggleSearch.state = 0;
|
||||
|
||||
this.container.setVerticalScrollOffset(0);
|
||||
this.container.setHorizontalScrollOffset(0);
|
||||
this.recipeTabs.update(this);
|
||||
}
|
||||
|
||||
private void updateContainerSize() {
|
||||
final int width = this.xSize - 6;
|
||||
this.container.w = Math.max(width, this.handlerInfo.getWidth());
|
||||
this.container.h = this.ySize - 32 - 4;
|
||||
|
||||
if (!this.handlerInfo.isAllowOverflowX() && this.handlerInfo.getWidth() > width) {
|
||||
this.container.w = width;
|
||||
this.container.h -= 8;
|
||||
}
|
||||
}
|
||||
|
||||
public int openTargetRecipe(RecipeId recipeId) {
|
||||
int refIndex = -1;
|
||||
int recipetype = 0;
|
||||
@@ -440,7 +477,7 @@ public abstract class GuiRecipe<H extends IRecipeHandler> extends GuiContainer i
|
||||
final H localHandler = this.currenthandlers.get(j);
|
||||
final HandlerInfo localHandlerInfo = GuiRecipeTab.getHandlerInfo(localHandler);
|
||||
|
||||
if (localHandlerInfo.getHandlerName().equals(this.recipeId.getHandleName())) {
|
||||
if (localHandlerInfo.getHandlerName().equals(this.recipeId.getHandlerName())) {
|
||||
recipetype = j;
|
||||
|
||||
if (!this.recipeId.getIngredients().isEmpty()) {
|
||||
@@ -490,7 +527,7 @@ public abstract class GuiRecipe<H extends IRecipeHandler> extends GuiContainer i
|
||||
@Override
|
||||
public Slot getSlotAtPosition(int mousex, int mousey) {
|
||||
final Widget activeWidget = this.container.getWidgetUnderMouse(mousex, mousey);
|
||||
final ContainerRecipe slotcontainer = (ContainerRecipe) inventorySlots;
|
||||
final EmptyContainer slotcontainer = (EmptyContainer) inventorySlots;
|
||||
slotcontainer.setActiveStack(null);
|
||||
|
||||
if (activeWidget instanceof NEIRecipeWidget recipeWidget) {
|
||||
@@ -564,15 +601,15 @@ public abstract class GuiRecipe<H extends IRecipeHandler> extends GuiContainer i
|
||||
if (i == mc.gameSettings.keyBindInventory.getKeyCode()) {
|
||||
this.mc.displayGuiScreen(getFirstScreenGeneral());
|
||||
NEICPH.sendRequestContainer();
|
||||
} else if (NEIClientConfig.isKeyHashDown("gui.back")) {
|
||||
} else if (KeyManager.isKeyDown("recipe.back")) {
|
||||
this.mc.displayGuiScreen(this.prevGui);
|
||||
} else if (NEIClientConfig.isKeyHashDown("gui.prev_machine")) {
|
||||
} else if (KeyManager.isKeyDown("recipe.prev_machine")) {
|
||||
prevType();
|
||||
} else if (NEIClientConfig.isKeyHashDown("gui.next_machine")) {
|
||||
} else if (KeyManager.isKeyDown("recipe.next_machine")) {
|
||||
nextType();
|
||||
} else if (NEIClientConfig.isKeyHashDown("gui.prev_recipe")) {
|
||||
} else if (KeyManager.isKeyDown("recipe.prev_recipe")) {
|
||||
prevPage();
|
||||
} else if (NEIClientConfig.isKeyHashDown("gui.next_recipe")) {
|
||||
} else if (KeyManager.isKeyDown("recipe.next_recipe")) {
|
||||
nextPage();
|
||||
}
|
||||
}
|
||||
@@ -671,7 +708,7 @@ public abstract class GuiRecipe<H extends IRecipeHandler> extends GuiContainer i
|
||||
// If shift is held, try switching to the next recipe handler. Replicates the
|
||||
// GuiRecipeTabs.mouseScrolled()
|
||||
// without the checking for the cursor being inside the tabbar.
|
||||
if (NEIClientUtils.shiftKey()) {
|
||||
if (NEIClientUtils.shiftKey() || this.typeArea.contains(mouse)) {
|
||||
if (scroll < 0) {
|
||||
nextType();
|
||||
} else {
|
||||
@@ -683,7 +720,12 @@ public abstract class GuiRecipe<H extends IRecipeHandler> extends GuiContainer i
|
||||
|
||||
// Finally, if nothing else has handled scrolling, try changing to the next
|
||||
// recipe page.
|
||||
if (new Rectangle(this.guiLeft, this.guiTop, this.xSize, this.ySize).contains(mouse)) {
|
||||
if (NEIClientConfig.getBooleanSetting("inventory.guirecipe.scrollPages")
|
||||
&& this.container.boundsInside().contains(mouse.x, mouse.y)
|
||||
|| this.pageArea.contains(mouse)
|
||||
&& (!this.handler.searchingAvailable() || !GuiRecipe.toggleSearch.contains(mouse.x, mouse.y))
|
||||
&& (!GuiRecipe.searchField.isVisible() || !GuiRecipe.searchField.contains(mouse.x, mouse.y))) {
|
||||
|
||||
if (scroll > 0) {
|
||||
prevPage();
|
||||
} else {
|
||||
@@ -783,10 +825,11 @@ public abstract class GuiRecipe<H extends IRecipeHandler> extends GuiContainer i
|
||||
return this.recipeCatalyst;
|
||||
}
|
||||
|
||||
protected void forceRefreshPage() {
|
||||
this.currenthandlers.sort(NEIClientConfig.HANDLER_COMPARATOR);
|
||||
|
||||
public void forceRefreshPage() {
|
||||
final int currentPage = this.handlerPages.getCurrentPageIndex();
|
||||
this.currenthandlers.sort(NEIClientConfig.HANDLER_COMPARATOR);
|
||||
this.recipetype = this.currenthandlers.indexOf(this.handler.original);
|
||||
|
||||
setRecipePage(this.recipetype);
|
||||
this.handlerPages.changePage(currentPage);
|
||||
|
||||
@@ -824,26 +867,26 @@ public abstract class GuiRecipe<H extends IRecipeHandler> extends GuiContainer i
|
||||
final int textMiddle = (BUTTON_WIDTH - this.fontRendererObj.FONT_HEIGHT) / 2;
|
||||
|
||||
drawRect(
|
||||
this.prevtype.xPosition + BUTTON_WIDTH - 1,
|
||||
this.prevtype.yPosition,
|
||||
this.nexttype.xPosition,
|
||||
this.prevtype.yPosition + BUTTON_HEIGHT,
|
||||
this.typeArea.x,
|
||||
this.typeArea.y,
|
||||
this.typeArea.x + this.typeArea.width,
|
||||
this.typeArea.y + this.typeArea.height,
|
||||
0x30000000);
|
||||
drawRect(
|
||||
this.prevpage.xPosition + BUTTON_WIDTH - 1,
|
||||
this.prevpage.yPosition,
|
||||
this.nextpage.xPosition,
|
||||
this.prevpage.yPosition + BUTTON_HEIGHT,
|
||||
this.pageArea.x,
|
||||
this.pageArea.y,
|
||||
this.pageArea.x + this.pageArea.width,
|
||||
this.pageArea.y + this.pageArea.height,
|
||||
0x30000000);
|
||||
|
||||
final String handlerTitle = this.handler.original.getRecipeName().trim();
|
||||
final String titleColorCode = getHandlerTitleColorCode(isHandlerTitleHovered(mouseX, mouseY));
|
||||
final int titleColor = getHandlerTitleColor(isHandlerTitleHovered(mouseX, mouseY));
|
||||
drawCenteredString(
|
||||
this.fontRendererObj,
|
||||
titleColorCode + handlerTitle + EnumChatFormatting.RESET,
|
||||
handlerTitle,
|
||||
this.guiLeft + this.xSize / 2,
|
||||
this.prevtype.yPosition + textMiddle,
|
||||
0xffffff);
|
||||
this.typeArea.y + textMiddle,
|
||||
titleColor);
|
||||
|
||||
if (this.handler.searchingAvailable()) {
|
||||
GuiRecipe.toggleSearch.draw(mouseX, mouseY);
|
||||
@@ -865,7 +908,7 @@ public abstract class GuiRecipe<H extends IRecipeHandler> extends GuiContainer i
|
||||
this.fontRendererObj,
|
||||
recipePage,
|
||||
GuiRecipe.searchField.x + GuiRecipe.searchField.w + 22,
|
||||
this.prevpage.yPosition + textMiddle,
|
||||
this.pageArea.y + textMiddle,
|
||||
0xffffff);
|
||||
} else {
|
||||
final String recipePage = NEIClientUtils.translate(
|
||||
@@ -876,7 +919,7 @@ public abstract class GuiRecipe<H extends IRecipeHandler> extends GuiContainer i
|
||||
this.fontRendererObj,
|
||||
recipePage,
|
||||
this.guiLeft + this.xSize / 2,
|
||||
this.prevpage.yPosition + textMiddle,
|
||||
this.pageArea.y + textMiddle,
|
||||
0xffffff);
|
||||
}
|
||||
|
||||
@@ -897,13 +940,8 @@ public abstract class GuiRecipe<H extends IRecipeHandler> extends GuiContainer i
|
||||
return new Rectangle(titleX, titleY, titleWidth, this.fontRendererObj.FONT_HEIGHT).contains(mousex, mousey);
|
||||
}
|
||||
|
||||
private String getHandlerTitleColorCode(boolean hovered) {
|
||||
final String key = hovered ? "recipe.title.color.hover" : "recipe.title.color.normal";
|
||||
final String translated = NEIClientUtils.translate(key);
|
||||
if (!translated.startsWith("nei.")) { // Optional localization string for resource packs
|
||||
return translated;
|
||||
}
|
||||
return hovered ? EnumChatFormatting.YELLOW.toString() : EnumChatFormatting.WHITE.toString();
|
||||
private int getHandlerTitleColor(boolean hovered) {
|
||||
return hovered ? ColorUtils.recipeTitleHover.getColor() : ColorUtils.recipeTitle.getColor();
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -996,7 +1034,7 @@ public abstract class GuiRecipe<H extends IRecipeHandler> extends GuiContainer i
|
||||
private GuiOverlayButton[] overlayButtons = new GuiOverlayButton[0];
|
||||
|
||||
@Deprecated
|
||||
public ContainerRecipe slotcontainer;
|
||||
public EmptyContainer slotcontainer;
|
||||
|
||||
@Deprecated
|
||||
public List<GuiButton> getOverlayButtons() {
|
||||
|
||||
@@ -23,16 +23,18 @@ import net.minecraftforge.common.MinecraftForge;
|
||||
import org.apache.commons.csv.CSVFormat;
|
||||
import org.apache.commons.csv.CSVParser;
|
||||
import org.apache.commons.csv.CSVRecord;
|
||||
import org.lwjgl.input.Keyboard;
|
||||
import org.lwjgl.opengl.GL11;
|
||||
import org.lwjgl.opengl.GL12;
|
||||
|
||||
import codechicken.lib.gui.GuiDraw;
|
||||
import codechicken.nei.ColorUtils;
|
||||
import codechicken.nei.NEIClientConfig;
|
||||
import codechicken.nei.NEIClientUtils;
|
||||
import codechicken.nei.Widget;
|
||||
import codechicken.nei.drawable.DrawableResource;
|
||||
import codechicken.nei.event.NEIRegisterHandlerInfosEvent;
|
||||
import codechicken.nei.guihook.GuiContainerManager;
|
||||
import codechicken.nei.recipe.debug.DebugHandlerWidget;
|
||||
import cpw.mods.fml.common.Loader;
|
||||
|
||||
public abstract class GuiRecipeTab extends Widget {
|
||||
@@ -126,7 +128,7 @@ public abstract class GuiRecipeTab extends Widget {
|
||||
|
||||
int textCenterX = x + (int) (getWidth() / 2f);
|
||||
int textCenterY = y + (int) (getHeight() / 2f) - 3;
|
||||
int color = selected ? 0xffffa0 : 0xe0e0e0;
|
||||
int color = selected ? ColorUtils.buttonLabelHover.getColor() : ColorUtils.buttonLabelNormal.getColor();
|
||||
fontRenderer.drawStringWithShadow(
|
||||
text,
|
||||
textCenterX - (int) (fontRenderer.getStringWidth(text) / 2f),
|
||||
@@ -138,18 +140,16 @@ public abstract class GuiRecipeTab extends Widget {
|
||||
|
||||
public void addTooltips(List<String> tooltip) {
|
||||
tooltip.add(handler.getRecipeTabName().trim());
|
||||
|
||||
String handlerMod = getHandlerMod(handlerName, handlerID);
|
||||
tooltip.add(EnumChatFormatting.BLUE + handlerMod);
|
||||
|
||||
boolean shiftHeld = Keyboard.getEventKeyState()
|
||||
&& (Keyboard.getEventKey() == Keyboard.KEY_LSHIFT || Keyboard.getEventKey() == Keyboard.KEY_RSHIFT);
|
||||
if (handlerMod.equals("Unknown") || shiftHeld) {
|
||||
if (handlerMod.equals("Unknown") || NEIClientUtils.shiftKey()) {
|
||||
tooltip.add("");
|
||||
tooltip.add("HandlerName: " + handlerName);
|
||||
tooltip.add("HandlerID: " + handlerID);
|
||||
tooltip.add("HandlerOrder: " + NEIClientConfig.getHandlerOrder(handler));
|
||||
tooltip.add(EnumChatFormatting.GRAY + "HandlerName: " + handlerName);
|
||||
tooltip.add(EnumChatFormatting.GRAY + "HandlerID: " + handlerID);
|
||||
tooltip.add(EnumChatFormatting.GRAY + "HandlerOrder: " + NEIClientConfig.getHandlerOrder(handler));
|
||||
}
|
||||
|
||||
tooltip.add(EnumChatFormatting.BLUE + handlerMod);
|
||||
}
|
||||
|
||||
public abstract boolean onButtonPress(boolean rightclick);
|
||||
@@ -258,13 +258,19 @@ public abstract class GuiRecipeTab extends Widget {
|
||||
final int handlerHeight = intOrDefault(record.get("handlerHeight"), HandlerInfo.DEFAULT_HEIGHT);
|
||||
final int handlerWidth = intOrDefault(record.get("handlerWidth"), HandlerInfo.DEFAULT_WIDTH);
|
||||
final boolean multipleWidgetsAllowed = intOrDefault(record.get("maxRecipesPerPage"), 1) > 1;
|
||||
info.setHandlerDimensions(handlerWidth, handlerHeight, multipleWidgetsAllowed);
|
||||
info.setHandlerDimensions(handlerWidth, handlerHeight);
|
||||
info.setMultipleWidgetsAllowed(multipleWidgetsAllowed);
|
||||
} catch (NumberFormatException ignored) {
|
||||
NEIClientConfig.logger.info("Error setting handler dimensions for " + handler);
|
||||
}
|
||||
|
||||
info.setUseCustomScroll(
|
||||
record.isSet("useCustomScroll") ? Boolean.parseBoolean(record.get("useCustomScroll")) : false);
|
||||
final boolean allowOverflow = record.isSet("useCustomScroll")
|
||||
&& Boolean.parseBoolean(record.get("useCustomScroll"));
|
||||
info.setAllowOverflowX(
|
||||
record.isSet("allowOverflowX") ? Boolean.parseBoolean(record.get("allowOverflowX")) : true);
|
||||
info.setAllowOverflowY(
|
||||
record.isSet("allowOverflowY") ? Boolean.parseBoolean(record.get("allowOverflowY"))
|
||||
: allowOverflow);
|
||||
handlerMap.put(handler, info);
|
||||
NEIClientConfig.logger.info("Loaded " + handler);
|
||||
}
|
||||
@@ -292,11 +298,12 @@ public abstract class GuiRecipeTab extends Widget {
|
||||
}
|
||||
NEIClientConfig.logger.info("Sending {}", NEIRegisterHandlerInfosEvent.class.getSimpleName());
|
||||
MinecraftForge.EVENT_BUS.post(new NEIRegisterHandlerInfosEvent());
|
||||
DebugHandlerWidget.instance.loadHandlerInfoPatch();
|
||||
}
|
||||
|
||||
private static HandlerInfo getDefaultHandlerInfo() {
|
||||
final HandlerInfo info = new HandlerInfo("Unknown", "Unknown", "Unknown", false, "");
|
||||
info.setHandlerDimensions(HandlerInfo.DEFAULT_WIDTH, HandlerInfo.DEFAULT_HEIGHT, false);
|
||||
info.setHandlerDimensions(HandlerInfo.DEFAULT_WIDTH, HandlerInfo.DEFAULT_HEIGHT);
|
||||
return info;
|
||||
}
|
||||
|
||||
|
||||
@@ -30,7 +30,10 @@ public class HandlerInfo {
|
||||
private boolean multipleWidgetsAllowed = false;
|
||||
private boolean showFavoritesButton = true;
|
||||
private boolean showOverlayButton = true;
|
||||
private boolean useCustomScroll = false;
|
||||
private boolean showBadge = false;
|
||||
|
||||
private boolean allowOverflowX = true;
|
||||
private boolean allowOverflowY = false;
|
||||
|
||||
private ItemStack itemStack = null;
|
||||
private DrawableResource image = null;
|
||||
@@ -45,13 +48,13 @@ public class HandlerInfo {
|
||||
|
||||
@Deprecated
|
||||
public void setHandlerDimensions(int height, int width, int maxRecipesPerPage) {
|
||||
setHandlerDimensions(width, height, maxRecipesPerPage > 1);
|
||||
setHandlerDimensions(width, height);
|
||||
setMultipleWidgetsAllowed(maxRecipesPerPage > 1);
|
||||
}
|
||||
|
||||
public void setHandlerDimensions(int width, int height, boolean multipleWidgetsAllowed) {
|
||||
public void setHandlerDimensions(int width, int height) {
|
||||
this.height = height;
|
||||
this.width = width;
|
||||
this.multipleWidgetsAllowed = multipleWidgetsAllowed;
|
||||
}
|
||||
|
||||
public boolean setItem(String itemId, String nbtString) {
|
||||
@@ -102,6 +105,10 @@ public class HandlerInfo {
|
||||
return this.multipleWidgetsAllowed ? Integer.MAX_VALUE : 1;
|
||||
}
|
||||
|
||||
public void setMultipleWidgetsAllowed(boolean multipleWidgetsAllowed) {
|
||||
this.multipleWidgetsAllowed = multipleWidgetsAllowed;
|
||||
}
|
||||
|
||||
public boolean isMultipleWidgetsAllowed() {
|
||||
return this.multipleWidgetsAllowed;
|
||||
}
|
||||
@@ -138,12 +145,34 @@ public class HandlerInfo {
|
||||
this.showOverlayButton = showOverlayButton;
|
||||
}
|
||||
|
||||
public boolean getUseCustomScroll() {
|
||||
return this.useCustomScroll;
|
||||
public boolean getShowBadge() {
|
||||
return this.showBadge;
|
||||
}
|
||||
|
||||
public void setShowBadge(boolean showBadge) {
|
||||
this.showBadge = showBadge;
|
||||
}
|
||||
|
||||
@Deprecated
|
||||
public void setUseCustomScroll(boolean useCustomScroll) {
|
||||
this.useCustomScroll = useCustomScroll;
|
||||
this.allowOverflowX = useCustomScroll;
|
||||
this.allowOverflowY = useCustomScroll;
|
||||
}
|
||||
|
||||
public boolean isAllowOverflowX() {
|
||||
return this.allowOverflowX;
|
||||
}
|
||||
|
||||
public void setAllowOverflowX(boolean allowOverflowX) {
|
||||
this.allowOverflowX = allowOverflowX;
|
||||
}
|
||||
|
||||
public boolean isAllowOverflowY() {
|
||||
return this.allowOverflowY;
|
||||
}
|
||||
|
||||
public void setAllowOverflowY(boolean allowOverflowY) {
|
||||
this.allowOverflowY = allowOverflowY;
|
||||
}
|
||||
|
||||
public static class Builder {
|
||||
@@ -182,6 +211,7 @@ public class HandlerInfo {
|
||||
return this;
|
||||
}
|
||||
|
||||
@Deprecated
|
||||
public Builder setUseCustomScroll(boolean useCustomScroll) {
|
||||
this.info.setUseCustomScroll(useCustomScroll);
|
||||
return this;
|
||||
@@ -212,6 +242,11 @@ public class HandlerInfo {
|
||||
return this;
|
||||
}
|
||||
|
||||
public Builder setShowBadge(boolean showBadge) {
|
||||
this.info.showBadge = showBadge;
|
||||
return this;
|
||||
}
|
||||
|
||||
@Deprecated
|
||||
public Builder setMaxRecipesPerPage(int maxRecipesPerPage) {
|
||||
this.info.multipleWidgetsAllowed = maxRecipesPerPage > 1;
|
||||
@@ -223,6 +258,16 @@ public class HandlerInfo {
|
||||
return this;
|
||||
}
|
||||
|
||||
public Builder setAllowOverflowX(boolean allowOverflowX) {
|
||||
this.info.allowOverflowX = allowOverflowX;
|
||||
return this;
|
||||
}
|
||||
|
||||
public Builder setAllowOverflowY(boolean allowOverflowY) {
|
||||
this.info.allowOverflowY = allowOverflowY;
|
||||
return this;
|
||||
}
|
||||
|
||||
public HandlerInfo build() {
|
||||
return this.info;
|
||||
}
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
package codechicken.nei.recipe;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
import net.minecraft.client.gui.inventory.GuiContainer;
|
||||
@@ -82,15 +83,38 @@ public interface IRecipeHandler {
|
||||
* @return A list of the other {@link PositionedStack}s in this recipe relative to the top left corner of your
|
||||
* recipe drawing space. For example fuel in furnaces.
|
||||
*/
|
||||
default List<PositionedStack> getCatalystStacks(int recipe) {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
|
||||
/**
|
||||
* Legacy API, define either {@link #getCatalystStacks(int)} or {@link #getResultStacks(int)}
|
||||
*
|
||||
* @param recipe The recipe index to get items for.
|
||||
* @return A list of the other {@link PositionedStack}s in this recipe relative to the top left corner of your
|
||||
* recipe drawing space. For example fuel in furnaces.
|
||||
*/
|
||||
List<PositionedStack> getOtherStacks(int recipe);
|
||||
|
||||
/**
|
||||
* Legacy API, use {@link #getResultStacks(int) getResultStacks.get(0)} if you want the primary result
|
||||
*
|
||||
* @param recipe The recipe index to get the result for.
|
||||
* @return The recipe result {@link PositionedStack} relative to the top left corner of your recipe drawing space.
|
||||
*/
|
||||
PositionedStack getResultStack(int recipe);
|
||||
|
||||
/**
|
||||
*
|
||||
* @param recipe The recipe index to get the result for.
|
||||
* @return A list of the result {@link PositionedStack}s relative to the top left corner of your recipe drawing
|
||||
* space.
|
||||
*/
|
||||
default List<PositionedStack> getResultStacks(int recipe) {
|
||||
final PositionedStack result = getResultStack(recipe);
|
||||
return result != null ? Collections.singletonList(result) : Collections.emptyList();
|
||||
}
|
||||
|
||||
/**
|
||||
* A tick function called for updating progress bars and cycling damage items.
|
||||
*/
|
||||
|
||||
@@ -6,6 +6,7 @@ import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.WeakHashMap;
|
||||
import java.util.function.Function;
|
||||
import java.util.stream.Stream;
|
||||
@@ -13,6 +14,7 @@ import java.util.stream.Stream;
|
||||
import net.minecraft.client.Minecraft;
|
||||
import net.minecraft.client.gui.inventory.GuiContainer;
|
||||
import net.minecraft.client.renderer.RenderHelper;
|
||||
import net.minecraft.init.Blocks;
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraftforge.common.MinecraftForge;
|
||||
|
||||
@@ -20,8 +22,9 @@ import org.lwjgl.opengl.GL11;
|
||||
import org.lwjgl.opengl.GL12;
|
||||
|
||||
import codechicken.lib.gui.GuiDraw;
|
||||
import codechicken.lib.vec.Rectangle4i;
|
||||
import codechicken.nei.FavoriteRecipes;
|
||||
import codechicken.nei.LayoutManager;
|
||||
import codechicken.nei.KeyManager;
|
||||
import codechicken.nei.NEIClientConfig;
|
||||
import codechicken.nei.NEIClientUtils;
|
||||
import codechicken.nei.NEIServerUtils;
|
||||
@@ -31,12 +34,18 @@ import codechicken.nei.api.IGuiContainerOverlay;
|
||||
import codechicken.nei.api.ShortcutInputHandler;
|
||||
import codechicken.nei.guihook.GuiContainerManager;
|
||||
import codechicken.nei.recipe.GuiRecipeButton.UpdateRecipeButtonsEvent;
|
||||
import codechicken.nei.recipe.Recipe.RecipeId;
|
||||
import codechicken.nei.recipe.debug.DebugHandlerWidget;
|
||||
import codechicken.nei.util.NEIMouseUtils;
|
||||
import it.unimi.dsi.fastutil.longs.LongArraySet;
|
||||
|
||||
public class NEIRecipeWidget extends Widget {
|
||||
|
||||
protected AcceptsFollowingTooltipLineHandler acceptsFollowingTooltipLineHandler;
|
||||
protected final WeakHashMap<PositionedStack, List<ItemStack>> permutations = new WeakHashMap<>();
|
||||
protected final Map<PositionedStack, Integer> favoriteIndexes = new WeakHashMap<>();
|
||||
protected final Map<PositionedStack, List<ItemStack>> permutations = new WeakHashMap<>();
|
||||
protected final Map<PositionedStack, List<Badge>> badgeCache = new WeakHashMap<>();
|
||||
protected int favoriteRevision = -1;
|
||||
protected boolean update = true;
|
||||
protected int cycleticks = 0;
|
||||
protected int lastcycle = -1;
|
||||
@@ -47,6 +56,9 @@ public class NEIRecipeWidget extends Widget {
|
||||
protected boolean showAsWidget = false;
|
||||
protected List<GuiRecipeButton> recipeButtons = null;
|
||||
|
||||
// Handles re-draws for catalysts-outputs duplication to preserve full backward compatibility for otherStacks
|
||||
private final Set<Long> drawnSlots = new LongArraySet();
|
||||
|
||||
public NEIRecipeWidget(RecipeHandlerRef handlerRef) {
|
||||
this.handlerRef = handlerRef;
|
||||
this.handlerInfo = GuiRecipeTab.getHandlerInfo(this.handlerRef.handler);
|
||||
@@ -60,7 +72,7 @@ public class NEIRecipeWidget extends Widget {
|
||||
|
||||
public void update() {
|
||||
|
||||
if (this.showAsWidget || !this.handlerInfo.getUseCustomScroll()) {
|
||||
if (this.showAsWidget || !this.handlerInfo.isAllowOverflowY()) {
|
||||
final int recipeHeight = this.handlerRef.handler.getRecipeHeight(this.handlerRef.recipeIndex);
|
||||
this.w = Math.max(166, this.handlerInfo.getWidth());
|
||||
this.h = recipeHeight > 0 ? recipeHeight : this.handlerInfo.getHeight();
|
||||
@@ -123,23 +135,23 @@ public class NEIRecipeWidget extends Widget {
|
||||
final UpdateRecipeButtonsEvent.Post postEvent = new UpdateRecipeButtonsEvent.Post(
|
||||
guiRecipe,
|
||||
this,
|
||||
getDefatulButtons());
|
||||
getDefaultButtons());
|
||||
MinecraftForge.EVENT_BUS.post(postEvent);
|
||||
return postEvent.buttonList;
|
||||
}
|
||||
|
||||
} else {
|
||||
return getDefatulButtons();
|
||||
return getDefaultButtons();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
protected List<GuiRecipeButton> getDefatulButtons() {
|
||||
protected List<GuiRecipeButton> getDefaultButtons() {
|
||||
GuiContainer guiContainer = NEIClientUtils.getGuiContainer();
|
||||
final List<GuiRecipeButton> buttons = new ArrayList<>();
|
||||
final boolean showFavorites = NEIClientConfig.favoritesEnabled() && handlerInfo.getShowFavoritesButton();
|
||||
final boolean showOverlay = handlerInfo.getShowOverlayButton();
|
||||
final int x = Math.min(168, this.w) - GuiRecipeButton.BUTTON_WIDTH;
|
||||
final int x = Math.min(166, this.w) - GuiRecipeButton.BUTTON_WIDTH;
|
||||
int y = this.h - GuiRecipeButton.BUTTON_HEIGHT - 6;
|
||||
|
||||
if (guiContainer instanceof IGuiContainerOverlay overlay) {
|
||||
@@ -165,7 +177,7 @@ public class NEIRecipeWidget extends Widget {
|
||||
if (this.update) {
|
||||
this.update = false;
|
||||
|
||||
if (!NEIClientUtils.shiftKey() && (this.cycleticks++) / 20 != this.lastcycle || this.lastcycle == -1) {
|
||||
if (!NEIClientUtils.shiftKey() && ((this.cycleticks++) / 20) != this.lastcycle || this.lastcycle == -1) {
|
||||
this.lastcycle = this.cycleticks / 20;
|
||||
updatePermutations();
|
||||
}
|
||||
@@ -186,41 +198,51 @@ public class NEIRecipeWidget extends Widget {
|
||||
|
||||
GuiContainerManager.enableMatrixStackLogging();
|
||||
|
||||
for (PositionedStack pStack : getInputs()) {
|
||||
GuiContainerManager.drawItem(pStack.relx, pStack.rely, pStack.item);
|
||||
final List<PositionedStack> inputs = getInputs();
|
||||
final List<PositionedStack> catalysts = getCatalysts();
|
||||
final List<PositionedStack> outputs = getOutputs();
|
||||
|
||||
if (pStack.contains(mouseX - this.x, mouseY - this.y - yShift)) {
|
||||
NEIClientUtils.gl2DRenderContext(() -> GuiDraw.drawRect(pStack.relx, pStack.rely, 16, 16, 0x80FFFFFF));
|
||||
}
|
||||
drawnSlots.clear();
|
||||
for (PositionedStack pStack : inputs) {
|
||||
drawnSlots.add(slotKey(pStack));
|
||||
drawItem(pStack, mouseX, mouseY, yShift, false);
|
||||
}
|
||||
|
||||
for (PositionedStack pStack : getCatalysts()) {
|
||||
GuiContainerManager.drawItem(pStack.relx, pStack.rely, pStack.item);
|
||||
|
||||
if (pStack.contains(mouseX - this.x, mouseY - this.y - yShift)) {
|
||||
NEIClientUtils.gl2DRenderContext(() -> GuiDraw.drawRect(pStack.relx, pStack.rely, 16, 16, 0x80FFFFFF));
|
||||
for (PositionedStack pStack : catalysts) {
|
||||
if (!drawnSlots.add(slotKey(pStack))) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!this.permutations.containsKey(pStack)) {
|
||||
updatePermutationsFor(pStack);
|
||||
}
|
||||
|
||||
drawItem(pStack, mouseX, mouseY, yShift, true);
|
||||
}
|
||||
|
||||
for (PositionedStack pStack : getOutputs()) {
|
||||
GuiContainerManager.drawItem(pStack.relx, pStack.rely, pStack.item);
|
||||
|
||||
if (pStack.contains(mouseX - this.x, mouseY - this.y - yShift)) {
|
||||
NEIClientUtils.gl2DRenderContext(() -> GuiDraw.drawRect(pStack.relx, pStack.rely, 16, 16, 0x80FFFFFF));
|
||||
for (PositionedStack pStack : outputs) {
|
||||
if (!drawnSlots.add(slotKey(pStack))) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!this.permutations.containsKey(pStack)) {
|
||||
updatePermutationsFor(pStack);
|
||||
}
|
||||
|
||||
drawItem(pStack, mouseX, mouseY, yShift, true);
|
||||
}
|
||||
|
||||
GuiContainerManager.disableMatrixStackLogging();
|
||||
|
||||
this.handlerRef.handler.drawForeground(this.handlerRef.recipeIndex);
|
||||
|
||||
final GuiRecipeButton overlayButton = getRecipeButtons().stream()
|
||||
.filter(
|
||||
b -> this.showAsWidget ? b instanceof GuiOverlayButton
|
||||
: b.contains(mouseX - this.x, mouseY - this.y - yShift))
|
||||
.findAny().orElse(null);
|
||||
final GuiRecipeButton overlayButton = forEachButtons(
|
||||
button -> (this.showAsWidget ? button instanceof GuiOverlayButton : button.contains(mouseX, mouseY))
|
||||
? button
|
||||
: null,
|
||||
(GuiRecipeButton) null);
|
||||
|
||||
if (overlayButton != null && overlayButton.enabled) {
|
||||
if (overlayButton != null) {
|
||||
NEIClientUtils.gl2DRenderContext(() -> overlayButton.drawItemOverlay());
|
||||
}
|
||||
|
||||
@@ -238,11 +260,96 @@ public class NEIRecipeWidget extends Widget {
|
||||
}
|
||||
}
|
||||
|
||||
LayoutManager.recipeHandlerWidget.drawGuiPlaceholder(this);
|
||||
DebugHandlerWidget.instance.drawGuiPlaceholder(this);
|
||||
}
|
||||
|
||||
private static long slotKey(PositionedStack pStack) {
|
||||
return ((long) pStack.relx << 32) ^ (pStack.rely & 0xFFFFFFFFL);
|
||||
}
|
||||
|
||||
protected void drawItem(PositionedStack pStack, int mouseX, int mouseY, int yShift, boolean input) {
|
||||
GuiContainerManager.drawItem(pStack.relx, pStack.rely, pStack.item);
|
||||
|
||||
if (this.handlerInfo.getShowBadge()) {
|
||||
drawBadge(pStack, input);
|
||||
}
|
||||
|
||||
if (pStack.contains(mouseX - this.x, mouseY - this.y - yShift)) {
|
||||
NEIClientUtils.gl2DRenderContext(() -> GuiDraw.drawRect(pStack.relx, pStack.rely, 16, 16, 0x80FFFFFF));
|
||||
}
|
||||
}
|
||||
|
||||
protected List<Badge> getBadges(PositionedStack pStack, boolean input) {
|
||||
|
||||
return this.badgeCache.computeIfAbsent(pStack, k -> {
|
||||
final List<Badge> badges = k.getBadges();
|
||||
|
||||
if (badges == null) {
|
||||
|
||||
if (input) {
|
||||
if (StackInfo.getAmount(pStack.item) == 0) {
|
||||
return Collections.singletonList(Badge.notConsumed());
|
||||
} else if (pStack.getChance() == 0) {
|
||||
return Collections.singletonList(Badge.notConsumedParallel());
|
||||
} else if (pStack.getChance() != PositionedStack.CHANCE_FULL) {
|
||||
return Collections.singletonList(
|
||||
Badge.consumeChance(pStack.getChance() / (float) PositionedStack.CHANCE_FULL));
|
||||
}
|
||||
} else if (pStack.getChance() != PositionedStack.CHANCE_FULL) {
|
||||
return Collections.singletonList(
|
||||
Badge.outputChance(pStack.getChance() / (float) PositionedStack.CHANCE_FULL));
|
||||
}
|
||||
|
||||
return Collections.emptyList();
|
||||
}
|
||||
|
||||
return badges;
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
protected void drawBadge(PositionedStack pStack, boolean input) {
|
||||
final List<Badge> badges = getBadges(pStack, input);
|
||||
|
||||
for (Badge badge : badges) {
|
||||
badge.draw(new Rectangle4i(pStack.relx, pStack.rely, 16, 16));
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean handleKeyPress(int keyID, char keyChar) {
|
||||
|
||||
if (NEIClientConfig.favoritesEnabled()
|
||||
&& KeyManager.isHashDown("bookmark.favorite_item", NEIClientUtils.SHIFT_HASH)) {
|
||||
final Point mouse = GuiDraw.getMousePosition();
|
||||
final int yShift = this.handlerInfo.getYShift();
|
||||
PositionedStack pStackOver = null;
|
||||
|
||||
for (PositionedStack pStack : getInputs()) {
|
||||
if (pStack.contains(mouse.x - this.x, mouse.y - this.y - yShift)) {
|
||||
pStackOver = pStack;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (pStackOver != null) {
|
||||
|
||||
if (FavoriteRecipes.containsManual(pStackOver.item)) {
|
||||
FavoriteRecipes.setFavorite(pStackOver.item, null);
|
||||
} else {
|
||||
FavoriteRecipes.setFavorite(
|
||||
pStackOver.item,
|
||||
RecipeId.of(
|
||||
pStackOver.item,
|
||||
FavoriteRecipes.FAVORITE_ITEM,
|
||||
Arrays.asList(new ItemStack(Blocks.fire, 1), pStackOver.item)));
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -320,31 +427,27 @@ public class NEIRecipeWidget extends Widget {
|
||||
|
||||
tooltip = this.handlerRef.handler.handleItemTooltip(guiRecipe, itemstack, tooltip, this.handlerRef.recipeIndex);
|
||||
|
||||
if (NEIClientConfig.showCycledIngredientsTooltip() && itemstack != null) {
|
||||
final int yShift = this.handlerInfo.getYShift();
|
||||
PositionedStack hovered = null;
|
||||
if (itemstack != null) {
|
||||
final PositionedStack hovered = getPositionedStackMouseOver(mousex, mousey);
|
||||
|
||||
for (PositionedStack pStack : getInputs()) {
|
||||
if (pStack.contains(mousex - this.x, mousey - this.y - yShift)) {
|
||||
hovered = pStack;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (hovered != null && this.handlerInfo.getShowBadge()) {
|
||||
final List<Badge> badges = getBadges(hovered, getOutputs().indexOf(hovered) == -1);
|
||||
|
||||
if (hovered == null) {
|
||||
for (PositionedStack pStack : getCatalysts()) {
|
||||
if (pStack.contains(mousex - this.x, mousey - this.y - yShift)) {
|
||||
hovered = pStack;
|
||||
for (Badge badge : badges) {
|
||||
if (badge.getTooltip() != null && !badge.getTooltip().isEmpty()) {
|
||||
tooltip.addAll(badge.getTooltip());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (hovered == null || hovered.items.length <= 1) {
|
||||
if (hovered == null || !NEIClientConfig.showCycledIngredientsTooltip()
|
||||
|| this.permutations.getOrDefault(hovered, Collections.emptyList()).size() <= 1
|
||||
|| getOutputs().indexOf(hovered) != -1) {
|
||||
this.acceptsFollowingTooltipLineHandler = null;
|
||||
} else if (this.acceptsFollowingTooltipLineHandler == null
|
||||
|| this.acceptsFollowingTooltipLineHandler.tooltipGUID != hovered) {
|
||||
this.acceptsFollowingTooltipLineHandler = AcceptsFollowingTooltipLineHandler
|
||||
.of(hovered, hovered.getFilteredPermutations(), hovered.item);
|
||||
.of(hovered, this.permutations.get(hovered), hovered.item);
|
||||
}
|
||||
} else if (this.acceptsFollowingTooltipLineHandler != null) {
|
||||
this.acceptsFollowingTooltipLineHandler = null;
|
||||
@@ -359,6 +462,7 @@ public class NEIRecipeWidget extends Widget {
|
||||
|
||||
@Override
|
||||
public Map<String, String> handleHotkeys(int mouseX, int mouseY, Map<String, String> hotkeys) {
|
||||
final int yShift = this.handlerInfo.getYShift();
|
||||
final Map<String, String> buttonHotkeys = forEachButtons(
|
||||
button -> button.contains(mouseX, mouseY) ? button.handleHotkeys(mouseX, mouseY, hotkeys) : null,
|
||||
hotkeys);
|
||||
@@ -371,6 +475,14 @@ public class NEIRecipeWidget extends Widget {
|
||||
NEIClientUtils.translate("recipe.accepts.scroll"));
|
||||
}
|
||||
|
||||
if (getInputs().stream().anyMatch(
|
||||
pStack -> this.permutations.getOrDefault(pStack, Collections.emptyList()).size() > 1
|
||||
&& pStack.contains(mouseX - this.x, mouseY - this.y - yShift))) {
|
||||
hotkeys.put(
|
||||
KeyManager.getKeyName("bookmark.favorite_item", NEIClientUtils.SHIFT_HASH),
|
||||
NEIClientUtils.translate("recipe.favorite.toggle"));
|
||||
}
|
||||
|
||||
return buttonHotkeys;
|
||||
}
|
||||
|
||||
@@ -395,8 +507,8 @@ public class NEIRecipeWidget extends Widget {
|
||||
if (!NEIClientUtils.shiftKey()) return false;
|
||||
final PositionedStack overStack = getPositionedStackMouseOver(mx, my);
|
||||
|
||||
if (overStack != null && overStack.items.length > 1) {
|
||||
final List<ItemStack> items = overStack.getFilteredPermutations();
|
||||
if (overStack != null && this.permutations.getOrDefault(overStack, Collections.emptyList()).size() > 1) {
|
||||
final List<ItemStack> items = this.permutations.get(overStack);
|
||||
final int stackIndex = indexOf(items, overStack.item);
|
||||
final ItemStack stack = items.get((items.size() - scroll + stackIndex) % items.size());
|
||||
|
||||
@@ -505,21 +617,22 @@ public class NEIRecipeWidget extends Widget {
|
||||
}
|
||||
|
||||
protected void updatePermutations() {
|
||||
final int rev = FavoriteRecipes.getRevision();
|
||||
|
||||
if (this.favoriteRevision != rev) {
|
||||
this.favoriteRevision = rev;
|
||||
this.acceptsFollowingTooltipLineHandler = null;
|
||||
this.favoriteIndexes.clear();
|
||||
this.permutations.clear();
|
||||
this.badgeCache.clear();
|
||||
}
|
||||
|
||||
for (PositionedStack pStack : getInputs()) {
|
||||
if (pStack.items.length > 1) {
|
||||
final List<ItemStack> permutations = this.permutations
|
||||
.computeIfAbsent(pStack, stack -> stack.getFilteredPermutations(FavoriteRecipes::contains));
|
||||
pStack.setPermutationToRender(permutations.get(this.lastcycle % permutations.size()));
|
||||
}
|
||||
updatePermutationsFor(pStack);
|
||||
}
|
||||
|
||||
for (PositionedStack pStack : getCatalysts()) {
|
||||
if (pStack.items.length > 1) {
|
||||
final List<ItemStack> permutations = this.permutations
|
||||
.computeIfAbsent(pStack, stack -> stack.getFilteredPermutations(FavoriteRecipes::contains));
|
||||
pStack.setPermutationToRender(permutations.get(this.lastcycle % permutations.size()));
|
||||
}
|
||||
updatePermutationsFor(pStack);
|
||||
}
|
||||
|
||||
if (this.acceptsFollowingTooltipLineHandler != null) {
|
||||
@@ -529,18 +642,54 @@ public class NEIRecipeWidget extends Widget {
|
||||
|
||||
}
|
||||
|
||||
private void updatePermutationsFor(PositionedStack pStack) {
|
||||
List<ItemStack> perms = this.permutations.get(pStack);
|
||||
int favoriteIndex = this.favoriteIndexes.getOrDefault(pStack, -1);
|
||||
boolean needsUpdate = false;
|
||||
|
||||
if (perms == null) {
|
||||
perms = pStack.getFilteredPermutations();
|
||||
favoriteIndex = -1;
|
||||
|
||||
if (perms.size() > 1) {
|
||||
for (ItemStack item : perms) {
|
||||
if (!FavoriteRecipes.containsManual(item)) break;
|
||||
favoriteIndex++;
|
||||
}
|
||||
}
|
||||
|
||||
this.permutations.put(pStack, perms);
|
||||
this.favoriteIndexes.put(pStack, favoriteIndex);
|
||||
needsUpdate = true;
|
||||
}
|
||||
|
||||
if (perms.size() > 1 || needsUpdate) {
|
||||
final int size = favoriteIndex != -1 ? favoriteIndex + 1 : perms.size();
|
||||
|
||||
if (size > 0) {
|
||||
pStack.setPermutationToRender(perms.get(this.lastcycle % size));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protected List<PositionedStack> getInputs() {
|
||||
return this.handlerRef.handler.getIngredientStacks(this.handlerRef.recipeIndex);
|
||||
}
|
||||
|
||||
protected List<PositionedStack> getOutputs() {
|
||||
final PositionedStack pStackResult = this.handlerRef.handler.getResultStack(this.handlerRef.recipeIndex);
|
||||
return pStackResult != null ? Arrays.asList(pStackResult)
|
||||
final List<PositionedStack> pStackResults = this.handlerRef.handler
|
||||
.getResultStacks(this.handlerRef.recipeIndex);
|
||||
return !pStackResults.isEmpty() ? pStackResults
|
||||
: this.handlerRef.handler.getOtherStacks(this.handlerRef.recipeIndex);
|
||||
}
|
||||
|
||||
protected List<PositionedStack> getCatalysts() {
|
||||
if (this.handlerRef.handler.getResultStack(this.handlerRef.recipeIndex) == null) {
|
||||
List<PositionedStack> catalysts = this.handlerRef.handler.getCatalystStacks(this.handlerRef.recipeIndex);
|
||||
if (!catalysts.isEmpty()) {
|
||||
return catalysts;
|
||||
}
|
||||
|
||||
if (this.handlerRef.handler.getResultStacks(this.handlerRef.recipeIndex).isEmpty()) {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
return this.handlerRef.handler.getOtherStacks(this.handlerRef.recipeIndex);
|
||||
|
||||
@@ -1,16 +1,25 @@
|
||||
package codechicken.nei.recipe;
|
||||
|
||||
import static codechicken.lib.gui.GuiDraw.drawString;
|
||||
import static codechicken.lib.gui.GuiDraw.getStringWidth;
|
||||
|
||||
import java.awt.Point;
|
||||
import java.awt.Rectangle;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Comparator;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import java.util.concurrent.atomic.AtomicInteger;
|
||||
import java.util.function.Supplier;
|
||||
|
||||
import net.minecraft.client.gui.inventory.GuiContainer;
|
||||
import net.minecraft.inventory.Container;
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.util.EnumChatFormatting;
|
||||
|
||||
import codechicken.core.TaskProfiler.ProfilerResult;
|
||||
import codechicken.lib.gui.GuiDraw;
|
||||
import codechicken.nei.ColorUtils;
|
||||
import codechicken.nei.NEIClientConfig;
|
||||
import codechicken.nei.NEIClientUtils;
|
||||
import codechicken.nei.PositionedStack;
|
||||
@@ -20,12 +29,104 @@ import codechicken.nei.util.AsyncTaskProfiler;
|
||||
|
||||
public class ProfilerRecipeHandler implements ICraftingHandler, IUsageHandler {
|
||||
|
||||
private static final AsyncTaskProfiler profiler = new AsyncTaskProfiler();
|
||||
public static class RecipeProfiler {
|
||||
|
||||
private final AsyncTaskProfiler profiler = new AsyncTaskProfiler();
|
||||
private final Map<String, IRecipeHandler> handlerMap = new ConcurrentHashMap<>();
|
||||
private final AtomicInteger idCounter = new AtomicInteger(0);
|
||||
private boolean isProfiling = false;
|
||||
|
||||
public <T extends IRecipeHandler> ArrayList<T> start(String profilerSection, Supplier<ArrayList<T>> callback) {
|
||||
profilerInfos.clear();
|
||||
this.handlerMap.clear();
|
||||
this.idCounter.set(0);
|
||||
|
||||
if (NEIClientConfig.isProfileRecipeEnabled()) {
|
||||
this.profiler.clear();
|
||||
this.profiler.start(EnumChatFormatting.getTextWithoutFormattingCodes(profilerSection));
|
||||
this.isProfiling = true;
|
||||
|
||||
try {
|
||||
return callback.get();
|
||||
} finally {
|
||||
this.profiler.end();
|
||||
this.isProfiling = false;
|
||||
|
||||
final List<ProfilerResult> results = this.profiler.getResults();
|
||||
|
||||
results.sort(
|
||||
Comparator.comparingLong((ProfilerResult profilerResult) -> profilerResult.time)
|
||||
.reversed());
|
||||
|
||||
for (ProfilerResult profilerResult : results) {
|
||||
profilerInfos.add(new ProfilerInfo(handlerMap.get(profilerResult.name), profilerResult));
|
||||
}
|
||||
}
|
||||
|
||||
} else {
|
||||
return callback.get();
|
||||
}
|
||||
}
|
||||
|
||||
public <T extends IRecipeHandler> T profile(T handler, Supplier<T> callback) {
|
||||
if (this.isProfiling && !(handler instanceof ProfilerRecipeHandler)) {
|
||||
final String id = String.valueOf(idCounter.incrementAndGet());
|
||||
this.handlerMap.put(id, handler);
|
||||
this.profiler.clearCurrent();
|
||||
this.profiler.start(id);
|
||||
|
||||
try {
|
||||
T result = callback.get();
|
||||
|
||||
if (result != null) {
|
||||
this.handlerMap.put(id, result);
|
||||
}
|
||||
|
||||
return result;
|
||||
} finally {
|
||||
this.profiler.end();
|
||||
}
|
||||
} else {
|
||||
return callback.get();
|
||||
}
|
||||
}
|
||||
|
||||
public static AsyncTaskProfiler getProfiler() {
|
||||
return profiler;
|
||||
}
|
||||
|
||||
protected static class ProfilerInfo {
|
||||
|
||||
public final String modName;
|
||||
public final IRecipeHandler handler;
|
||||
public final List<String> tooltip = new ArrayList<>();
|
||||
public final String title;
|
||||
public final String time;
|
||||
|
||||
public ProfilerInfo(IRecipeHandler handler, ProfilerResult result) {
|
||||
this.handler = handler;
|
||||
this.time = (result.time < 1_000_000 ? (result.time / 1_000) + "us" : (result.time / 1_000_000) + "ms");
|
||||
|
||||
if (handler == null) {
|
||||
this.title = result.name;
|
||||
this.modName = "Unknown";
|
||||
} else {
|
||||
final HandlerInfo handlerInfo = GuiRecipeTab.getHandlerInfo(handler);
|
||||
final String handlerName = handlerInfo != null ? handlerInfo.getHandlerName() : "Unknown";
|
||||
|
||||
this.title = EnumChatFormatting.getTextWithoutFormattingCodes(handler.getRecipeName());
|
||||
this.modName = handlerInfo != null ? handlerInfo.getModName() : "Unknown";
|
||||
|
||||
this.tooltip.add(EnumChatFormatting.GRAY + "HandlerName: " + handlerName);
|
||||
this.tooltip.add(EnumChatFormatting.GRAY + "HandlerID: " + handler.getOverlayIdentifier());
|
||||
this.tooltip.add(EnumChatFormatting.GRAY + "HandlerOrder: " + NEIClientConfig.getHandlerOrder(handler));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public static final RecipeProfiler recipeProfiler = new RecipeProfiler();
|
||||
protected static final List<ProfilerInfo> profilerInfos = new ArrayList<>();
|
||||
private static final int WIDTH = 166;
|
||||
private final boolean crafting;
|
||||
|
||||
public ProfilerRecipeHandler(boolean crafting) {
|
||||
@@ -39,11 +140,7 @@ public class ProfilerRecipeHandler implements ICraftingHandler, IUsageHandler {
|
||||
|
||||
@Override
|
||||
public int numRecipes() {
|
||||
if (!NEIClientConfig.isProfileRecipeEnabled()) return 0;
|
||||
|
||||
return (int) Math.ceil(
|
||||
((crafting ? GuiCraftingRecipe.craftinghandlers.size() : GuiUsageRecipe.usagehandlers.size()) - 1)
|
||||
/ 6D);
|
||||
return NEIClientConfig.isProfileRecipeEnabled() ? Math.max(1, profilerInfos.size()) : 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -51,21 +148,32 @@ public class ProfilerRecipeHandler implements ICraftingHandler, IUsageHandler {
|
||||
|
||||
@Override
|
||||
public void drawForeground(int recipe) {
|
||||
List<ProfilerResult> results = profiler.getResults();
|
||||
results.removeIf(profilerResult -> getRecipeName().equals(profilerResult.name));
|
||||
if (recipe >= profilerInfos.size()) return;
|
||||
|
||||
results.sort((o1, o2) -> o1.time < o2.time ? 1 : -1);
|
||||
final ProfilerInfo info = profilerInfos.get(recipe);
|
||||
final int valueWidth = getStringWidth(info.time);
|
||||
final IRecipeHandler handler = info.handler;
|
||||
final boolean hovered = handler != null && handler.numRecipes() > 0
|
||||
&& isHandlerTitleHovered(recipe, GuiDraw.getMousePosition());
|
||||
|
||||
for (int i = recipe * 6; i < results.size() && i < (recipe + 1) * 6; i++) {
|
||||
ProfilerResult r = results.get(i);
|
||||
int y = (i % 6) * 20 + 6;
|
||||
drawString(r.name, 8, y, 0xFF808080, false);
|
||||
GuiDraw.drawString(
|
||||
NEIClientUtils.cropText(GuiDraw.fontRenderer, info.title, WIDTH - valueWidth - 2),
|
||||
0,
|
||||
3,
|
||||
hovered ? 0xFFFFDD00 : 0xFF808080,
|
||||
false);
|
||||
GuiDraw.drawString(info.time, WIDTH - valueWidth, 3, ColorUtils.textGray.getColor(), false);
|
||||
}
|
||||
|
||||
String s;
|
||||
if (r.time < 1000000L) s = (r.time / 1000) + "us";
|
||||
else s = (r.time / 1000000) + "ms";
|
||||
private boolean isHandlerTitleHovered(int recipe, Point mouse) {
|
||||
final GuiContainer guiContainer = NEIClientUtils.getGuiContainer();
|
||||
|
||||
drawString(s, 156 - getStringWidth(s), y + 10, 0xFF404040, false);
|
||||
if (guiContainer instanceof GuiRecipe guiRecipe) {
|
||||
final Point recipePosition = guiRecipe.getRecipePosition(recipe);
|
||||
return new Rectangle(recipePosition.x, recipePosition.y, WIDTH, 16)
|
||||
.contains(mouse.x - guiContainer.guiLeft, mouse.y - guiContainer.guiTop);
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -104,6 +212,22 @@ public class ProfilerRecipeHandler implements ICraftingHandler, IUsageHandler {
|
||||
|
||||
@Override
|
||||
public List<String> handleTooltip(GuiRecipe<?> gui, List<String> currenttip, int recipe) {
|
||||
if (recipe >= profilerInfos.size()) return currenttip;
|
||||
|
||||
final ProfilerInfo r = profilerInfos.get(recipe);
|
||||
|
||||
currenttip.add(r.title + ": " + r.time);
|
||||
|
||||
if (r.handler != null) {
|
||||
currenttip.add(EnumChatFormatting.GRAY + "Recipes: " + r.handler.numRecipes() + GuiDraw.TOOLTIP_LINESPACE);
|
||||
|
||||
if (NEIClientUtils.shiftKey()) {
|
||||
currenttip.addAll(r.tooltip);
|
||||
}
|
||||
|
||||
currenttip.add(EnumChatFormatting.BLUE + r.modName);
|
||||
}
|
||||
|
||||
return currenttip;
|
||||
}
|
||||
|
||||
@@ -119,6 +243,23 @@ public class ProfilerRecipeHandler implements ICraftingHandler, IUsageHandler {
|
||||
|
||||
@Override
|
||||
public boolean mouseClicked(GuiRecipe<?> gui, int button, int recipe) {
|
||||
if (recipe >= profilerInfos.size()) return false;
|
||||
|
||||
final ProfilerInfo r = profilerInfos.get(recipe);
|
||||
|
||||
if (r.handler != null) {
|
||||
final GuiContainer guiContainer = NEIClientUtils.getGuiContainer();
|
||||
|
||||
if (guiContainer instanceof GuiRecipe guiRecipe) {
|
||||
int index = guiRecipe.currenthandlers.indexOf(r.handler);
|
||||
|
||||
if (index != -1) {
|
||||
guiRecipe.setRecipePage(index);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
@@ -51,6 +51,31 @@ public class Recipe {
|
||||
return new RecipeId(extractItem(result), handlerName, extractIngredients(ingredients));
|
||||
}
|
||||
|
||||
public static RecipeId of(IRecipeHandler handler, int recipeIndex) {
|
||||
final List<PositionedStack> ingredients = handler.getIngredientStacks(recipeIndex);
|
||||
final String handlerName = GuiRecipeTab.getHandlerInfo(handler).getHandlerName();
|
||||
// Use getResultStacks even though getResult could work because if a handler, like GT for example, doesn't
|
||||
// return anything from getResult, but will define all the outputs in getResultStacks we can still pick up
|
||||
// the results here. If a handler still doesn't define getResultStacks, then it will naturally fall back to
|
||||
// getResult anyway
|
||||
List<PositionedStack> pStackResults = handler.getResultStacks(recipeIndex);
|
||||
|
||||
if (pStackResults.isEmpty()) {
|
||||
for (PositionedStack otherStack : handler.getOtherStacks(recipeIndex)) {
|
||||
if (!FluidContainerRegistry.isContainer(otherStack.items[0])
|
||||
|| StackInfo.getFluid(otherStack.items[0]) != null) {
|
||||
pStackResults.add(otherStack);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return new RecipeId(
|
||||
extractItem(!pStackResults.isEmpty() ? pStackResults.get(0) : null),
|
||||
handlerName,
|
||||
extractIngredients(ingredients));
|
||||
}
|
||||
|
||||
public static RecipeId of(JsonObject json) {
|
||||
String handlerName = null;
|
||||
List<ItemStack> ingredients = new ArrayList<>();
|
||||
@@ -71,7 +96,7 @@ public class Recipe {
|
||||
return new RecipeId(result, handlerName, ingredients);
|
||||
}
|
||||
|
||||
public String getHandleName() {
|
||||
public String getHandlerName() {
|
||||
return this.handlerName;
|
||||
}
|
||||
|
||||
@@ -264,17 +289,20 @@ public class Recipe {
|
||||
|
||||
protected final ItemStack[] items;
|
||||
protected int activeIndex = 0;
|
||||
|
||||
protected int amount = 0;
|
||||
protected int chance = PositionedStack.CHANCE_FULL;
|
||||
|
||||
protected int relx;
|
||||
protected int rely;
|
||||
|
||||
public RecipeIngredient(int relx, int rely, List<ItemStack> items, int activeIndex) {
|
||||
public RecipeIngredient(int relx, int rely, List<ItemStack> items, int chance, int activeIndex) {
|
||||
this.items = items.stream().map(ItemStack::copy).toArray(size -> new ItemStack[size]);
|
||||
this.amount = StackInfo.getAmount(this.items[activeIndex]);
|
||||
this.activeIndex = activeIndex;
|
||||
this.relx = relx;
|
||||
this.rely = rely;
|
||||
this.chance = chance;
|
||||
}
|
||||
|
||||
public static RecipeIngredient of(PositionedStack positionedStack) {
|
||||
@@ -293,17 +321,21 @@ public class Recipe {
|
||||
}
|
||||
}
|
||||
|
||||
return of(positionedStack.relx, positionedStack.rely, stacks, activeIndex);
|
||||
return of(positionedStack.relx, positionedStack.rely, stacks, positionedStack.getChance(), activeIndex);
|
||||
}
|
||||
|
||||
public static RecipeIngredient of(int relx, int rely, List<ItemStack> stacks, int activeIndex) {
|
||||
return new RecipeIngredient(relx, rely, stacks, activeIndex);
|
||||
public static RecipeIngredient of(int relx, int rely, List<ItemStack> stacks, int chance, int activeIndex) {
|
||||
return new RecipeIngredient(relx, rely, stacks, chance, activeIndex);
|
||||
}
|
||||
|
||||
public int getAmount() {
|
||||
return this.amount;
|
||||
}
|
||||
|
||||
public int getChance() {
|
||||
return this.chance;
|
||||
}
|
||||
|
||||
public ItemStack getItemStack() {
|
||||
return this.items[this.activeIndex];
|
||||
}
|
||||
@@ -330,11 +362,16 @@ public class Recipe {
|
||||
return this;
|
||||
}
|
||||
|
||||
public void setChance(int chance) {
|
||||
this.chance = chance;
|
||||
}
|
||||
|
||||
public RecipeIngredient copy() {
|
||||
return new RecipeIngredient(
|
||||
this.relx,
|
||||
this.rely,
|
||||
getPermutations().stream().map(ItemStack::copy).collect(Collectors.toList()),
|
||||
this.chance,
|
||||
this.activeIndex);
|
||||
}
|
||||
}
|
||||
@@ -359,8 +396,12 @@ public class Recipe {
|
||||
ingredients.add(RecipeIngredient.of(positionedStack));
|
||||
}
|
||||
|
||||
if (handler.getResultStack(recipeIndex) != null) {
|
||||
results.add(RecipeIngredient.of(handler.getResultStack(recipeIndex)));
|
||||
final List<PositionedStack> resultStacks = handler.getResultStacks(recipeIndex);
|
||||
|
||||
if (!resultStacks.isEmpty()) {
|
||||
for (PositionedStack positionedStack : resultStacks) {
|
||||
results.add(RecipeIngredient.of(positionedStack));
|
||||
}
|
||||
} else {
|
||||
for (PositionedStack positionedStack : handler.getOtherStacks(recipeIndex)) {
|
||||
results.add(RecipeIngredient.of(positionedStack));
|
||||
@@ -417,7 +458,7 @@ public class Recipe {
|
||||
}
|
||||
|
||||
if (item instanceof ItemStack stack) {
|
||||
return RecipeIngredient.of(0, 0, Arrays.asList(stack), 0);
|
||||
return RecipeIngredient.of(0, 0, Arrays.asList(stack), PositionedStack.CHANCE_FULL, 0);
|
||||
}
|
||||
|
||||
if (item instanceof RecipeIngredient ingr) {
|
||||
|
||||
Loaded 100 of 147 files, more files were not shown because too many files have changed in this diff.
Show more
Reference in new issue
Block a user