Compare commits

...
Author SHA1 Message Date
sbancuz 2169ba03d0 Merge remote-tracking branch 'origin/multi-result' into multi-result 2026-08-02 21:16:56 +02:00
sbancuz 7f182757c3 De-dupe draw calls 2026-08-02 21:16:43 +02:00
sbancuz 83ee2e0d53 FurnaceHandler 2026-08-02 21:01:08 +02:00
Luca Bancale ff518c81b3 Merge branch 'master' into multi-result 2026-08-02 20:50:13 +02:00
slprime 5fb5ab6698 Added Bookmark Chain Visitor (#991) 2026-08-01 20:35:19 +03:00
slprime f47a8766a9 Create EmptyContainer (#990) 2026-08-01 20:19:54 +03:00
slprime 4cc72444d9 Fix Tooltip with Component in first line (#989) 2026-08-01 20:00:17 +03:00
slprime b48956ef94 Bookmarks Chain: fix container item multiplier limit (#988) 2026-07-29 00:57:12 +03:00
Algentandslprime 583d28ed12 Fix GL reset (#984)
Co-authored-by: slprime <31038811+slprime@users.noreply.github.com>
2026-07-26 23:36:37 +03:00
koolkrafter5 384813347c Overlay Button moves one item if the recipe stack is size zero (#985) 2026-07-26 23:28:39 +03:00
slprime 2660460c87 Merge branch 'master' into multi-result 2026-07-25 02:14:33 +03:00
slprime 2b28068382 Simplify the keybinding (#982) 2026-07-25 02:14:12 +03:00
sbancuz 1767d4be63 Fix isEmpty conditions, and add catalysts for not breaking old APIs 2026-07-17 12:33:04 +02:00
sbancuz e6684ddebb Fix isEmpty conditions, and add extraInputs for not breaking old APIs 2026-07-17 11:54:34 +02:00
sbancuz 89110ccb7e Check if new behavior is supported (no fallbacks for now) 2026-07-16 16:47:56 +02:00
sbancuz 434b4ac879 Review 2026-07-16 16:05:32 +02:00
sbancuz 24e6f7c57d Allow proper representation of recipes with multiple results 2026-07-16 12:06:40 +02:00
slprime 2c204c25aa Rework chat item link to support bookmarking recipes and groups (#971) 2026-07-11 20:38:01 +03:00
Jordan Rey 5e6ff1d63b fix: spawner placement logic (#973) 2026-07-11 20:33:51 +03:00
Algent 53ce50b35a oregenPattern this time for sure (#974) 2026-07-11 19:53:43 +03:00
slprime 835c4f7e01 Fix Dynamic Keybinding (#972) 2026-07-11 14:20:03 +03:00
RecursivePineapple f8c1f39faf Add Cubic Chunks cube overlay & fix chunk grid above y=256, below y=0. (#970) 2026-07-10 11:02:43 +03:00
slprime 4c4716e64f Fix duplicate keybinding handling by patching KeyBinding static handlers (#968) 2026-07-08 09:19:48 +03:00
LunaandMartin Robertz c84ac27a18 Add offset for snow block to mob spawn overlay (#965)
Co-authored-by: Martin Robertz <dream-master@gmx.net>
2026-07-07 11:44:58 +02:00
mllfjn 47baee272c Remove redundant simplewasher recipe (#967) 2026-07-07 11:08:44 +02:00
Martin Robertz f55dc716e3 update deps 2026-07-04 19:50:07 +02:00
slprimeandMartin Robertz 26beb079f0 [Feature] Keybinding Refactoring (#957)
Co-authored-by: Martin Robertz <dream-master@gmx.net>
2026-07-04 14:38:02 +03:00
Algent 841b73c6fe Update way of getting oregen pattern for GT overlay (#964) 2026-06-30 18:18:32 +03:00
slprime 0c7eeebb1f Fix Debug Handler (#963) 2026-06-29 20:24:36 +03:00
slprime 65b56735a7 Add item name aliases for search (#961) 2026-06-29 18:08:59 +02:00
slprime ff428bf538 Allow plugins to force fill mode for overlay button (#960) 2026-06-28 13:11:27 -04:00
72 changed files with 1608 additions and 716 deletions

No files matched your search

+3 -3
View File
@@ -6,7 +6,7 @@ configurations.create('gtnhlibEmbed') {
dependencies {
api('com.github.GTNewHorizons:CodeChickenCore:1.4.16:dev')
devOnlyNonPublishable('com.github.GTNewHorizons:GTNHLib:0.11.20:dev')
devOnlyNonPublishable('com.github.GTNewHorizons:GTNHLib:0.11.23:dev')
shadowImplementation('org.apache.commons:commons-csv:1.10.0')
@@ -22,8 +22,8 @@ dependencies {
testRuntimeOnly('org.junit.platform:junit-platform-launcher')
testRuntimeOnly("org.lwjgl.lwjgl:lwjgl:2.9.3");
compileOnly("com.github.GTNewHorizons:GTNHLib:0.11.20") { transitive = false }
gtnhlibEmbed("com.github.GTNewHorizons:GTNHLib:0.11.20") { transitive = false }
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 {
@@ -799,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"));
}
@@ -1294,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
@@ -8,7 +8,6 @@ import java.io.InputStream;
import java.io.OutputStream;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
@@ -129,8 +128,8 @@ public class FavoriteRecipes {
}
protected List<PositionedStack> getOutputs(IRecipeHandler handler, int recipeIndex) {
final PositionedStack pStackResult = handler.getResultStack(recipeIndex);
return pStackResult != null ? Collections.singletonList(pStackResult) : handler.getOtherStacks(recipeIndex);
final List<PositionedStack> pStackResults = handler.getResultStacks(recipeIndex);
return !pStackResults.isEmpty() ? pStackResults : handler.getOtherStacks(recipeIndex);
}
};
@@ -225,7 +224,7 @@ public class FavoriteRecipes {
continue;
}
if (FAVORITE_ITEM.equals(recipeId.getHandleName()) || RecipeHandlerRef.of(recipeId) != null) {
if (FAVORITE_ITEM.equals(recipeId.getHandlerName()) || RecipeHandlerRef.of(recipeId) != null) {
manualFavorites.add(stack, recipeId);
} else {
hasErrors = true;
@@ -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());
}
+10 -1
View File
@@ -17,6 +17,7 @@ import com.google.common.collect.ListMultimap;
import codechicken.nei.api.ItemFilter;
import codechicken.nei.api.ItemFilter.ItemFilterProvider;
import codechicken.nei.api.ItemInfo;
import codechicken.nei.util.ItemUntranslator;
public class ItemList {
@@ -96,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;
@@ -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;
}
+6 -6
View File
@@ -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);
+129 -21
View File
@@ -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();
@@ -224,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;
}
@@ -941,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);
}
}
+16 -2
View File
@@ -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();
}
@@ -61,7 +61,6 @@ import codechicken.nei.recipe.IRecipeHandler;
import codechicken.nei.recipe.InformationHandler;
import codechicken.nei.recipe.RecipeCatalysts;
import codechicken.nei.util.ItemUntranslator;
import codechicken.nei.util.NEIKeyboardUtils;
import codechicken.obfuscator.ObfuscationRun;
public class NEIClientConfig {
@@ -815,35 +814,38 @@ public class NEIClientConfig {
}
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.addKeyBind("gui.favorite_item", Keyboard.KEY_F);
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);
@@ -855,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() {
@@ -929,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() {
@@ -1007,6 +987,7 @@ public class NEIClientConfig {
}
});
KeyManager.requestOptionsReload();
RecipeCatalysts.loadCatalystInfo();
SubsetWidget.loadCustomSubsets();
SubsetWidget.loadHidden();
@@ -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;
@@ -57,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 {
@@ -381,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() {
@@ -456,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() {
@@ -27,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;
@@ -252,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;
@@ -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<>();
@@ -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();
}
+3 -1
View File
@@ -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) {
@@ -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) {
@@ -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;
}
}
@@ -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;
}
@@ -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) {
@@ -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);
}
}
@@ -230,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);
}
}
@@ -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() {
+20 -13
View File
@@ -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);
}
@@ -20,6 +20,7 @@ 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;
@@ -29,6 +30,7 @@ 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;
@@ -75,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;
}
@@ -86,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);
@@ -118,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());
}
@@ -197,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;
}
@@ -445,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"));
}
@@ -463,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"));
}
@@ -484,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();
@@ -517,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"));
}
@@ -534,60 +570,66 @@ 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(
NEIClientUtils.getKeyName(NEIClientUtils.CTRL_HASH, NEIMouseUtils.MOUSE_BTN_LMB),
KeyManager.getKeyName(NEIClientUtils.CTRL_HASH, NEIMouseUtils.MOUSE_BTN_LMB),
NEIClientUtils.translate("itempanel.infinite_item"));
} else {
hotkeys.put(
@@ -605,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"));
@@ -625,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);
@@ -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);
}
}
}
@@ -10,12 +10,16 @@ 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 {
@@ -245,6 +249,45 @@ public class BookmarkItem {
return builder(groupId, stack).build();
}
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,
@@ -364,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,10 +24,7 @@ import com.google.gson.JsonSyntaxException;
import codechicken.nei.BookmarkPanel.BookmarkViewMode;
import codechicken.nei.NEIClientConfig;
import codechicken.nei.PositionedStack;
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 {
@@ -199,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{}",
@@ -238,53 +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) {
int groupId = jsonObject.has("groupId") && grid.groups.containsKey(jsonObject.get("groupId").getAsInt())
? 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));
}
grid.addItem(builder.build(), false);
}
return itemStack != null;
}
public void save() {
if (this.bookmarkFile == null) {
@@ -325,26 +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("multiplier", new JsonPrimitive(item.multiplier));
row.add("factor", new JsonPrimitive(item.factor));
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());
}
if (item.chance != PositionedStack.CHANCE_FULL) {
row.add("chance", new JsonPrimitive(item.chance));
}
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");
}
@@ -193,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;
}
@@ -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));
}
}
@@ -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 : getSlot().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;
}
}
@@ -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;
@@ -46,6 +46,7 @@ import org.lwjgl.opengl.GL12;
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;
@@ -624,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);
}
@@ -762,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);
@@ -210,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;
@@ -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<>();
@@ -82,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);
@@ -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;
@@ -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) {
@@ -229,7 +230,7 @@ public class GuiFavoriteButton extends GuiRecipeButton {
}
}
if (recipeId != null && FavoriteRecipes.FAVORITE_ITEM.contains(recipeId.getHandleName())) {
if (recipeId != null && FavoriteRecipes.FAVORITE_ITEM.contains(recipeId.getHandlerName())) {
items.add(stack);
} else {
Recipe recipe = Recipe.of(recipeId);
@@ -15,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;
@@ -96,13 +99,18 @@ public class GuiOverlayButton extends GuiRecipeButton {
super(handlerRef, x, y, handlerRef.recipeIndex + BUTTON_ID_SHIFT, "+");
this.firstGui = firstGui != null && firstGui.inventorySlots != null ? firstGui : null;
IOverlayHandler overlayHandler = null;
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 || this.handlerRef.getOverlayHandler(this.firstGui) != null;
this.hasOverlay = this.canUseOverlayRenderer || overlayHandler != null;
}
setRequireShiftForOverlayRecipe(NEIClientConfig.requireShiftForOverlayRecipe());
setRequireShiftForOverlayRecipe(
overlayHandler != null ? overlayHandler.requireShiftForOverlayRecipe()
: NEIClientConfig.requireShiftForOverlayRecipe());
ingredientsOverlay();
}
@@ -157,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;
}
@@ -319,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() {
@@ -336,4 +352,7 @@ public class GuiOverlayButton extends GuiRecipeButton {
}
}
private void sendRecipeChatLink() {
NEIClientUtils.sendChatItemLink(BookmarkPayload.of(getRecipe()).toNBT());
}
}
@@ -26,6 +26,7 @@ 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,
@@ -180,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
@@ -190,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;
@@ -475,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()) {
@@ -525,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) {
@@ -599,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();
}
}
@@ -1032,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() {
@@ -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;
@@ -23,6 +24,7 @@ import org.lwjgl.opengl.GL12;
import codechicken.lib.gui.GuiDraw;
import codechicken.lib.vec.Rectangle4i;
import codechicken.nei.FavoriteRecipes;
import codechicken.nei.KeyManager;
import codechicken.nei.NEIClientConfig;
import codechicken.nei.NEIClientUtils;
import codechicken.nei.NEIServerUtils;
@@ -35,6 +37,7 @@ 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 {
@@ -53,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);
@@ -192,28 +198,40 @@ public class NEIRecipeWidget extends Widget {
GuiContainerManager.enableMatrixStackLogging();
for (PositionedStack pStack : getInputs()) {
final List<PositionedStack> inputs = getInputs();
final List<PositionedStack> catalysts = getCatalysts();
final List<PositionedStack> outputs = getOutputs();
if (!this.permutations.containsKey(pStack)) {
updatePermutationsFor(pStack);
}
drawItem(pStack, mouseX, mouseY, yShift, true);
}
for (PositionedStack pStack : getCatalysts()) {
if (!this.permutations.containsKey(pStack)) {
updatePermutationsFor(pStack);
}
drawItem(pStack, mouseX, mouseY, yShift, true);
}
for (PositionedStack pStack : getOutputs()) {
drawnSlots.clear();
for (PositionedStack pStack : inputs) {
drawnSlots.add(slotKey(pStack));
drawItem(pStack, mouseX, mouseY, yShift, false);
}
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 : 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);
@@ -245,6 +263,10 @@ public class NEIRecipeWidget extends Widget {
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);
@@ -297,8 +319,8 @@ public class NEIRecipeWidget extends Widget {
@Override
public boolean handleKeyPress(int keyID, char keyChar) {
if (NEIClientConfig.favoritesEnabled() && NEIClientUtils.shiftKey()
&& NEIClientConfig.isKeyHashDown("gui.favorite_item")) {
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;
@@ -457,7 +479,7 @@ public class NEIRecipeWidget extends Widget {
pStack -> this.permutations.getOrDefault(pStack, Collections.emptyList()).size() > 1
&& pStack.contains(mouseX - this.x, mouseY - this.y - yShift))) {
hotkeys.put(
NEIClientConfig.getKeyName("gui.favorite_item", NEIClientUtils.SHIFT_HASH),
KeyManager.getKeyName("bookmark.favorite_item", NEIClientUtils.SHIFT_HASH),
NEIClientUtils.translate("recipe.favorite.toggle"));
}
@@ -655,13 +677,19 @@ public class NEIRecipeWidget extends Widget {
}
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);
@@ -54,19 +54,26 @@ public class Recipe {
public static RecipeId of(IRecipeHandler handler, int recipeIndex) {
final List<PositionedStack> ingredients = handler.getIngredientStacks(recipeIndex);
final String handlerName = GuiRecipeTab.getHandlerInfo(handler).getHandlerName();
PositionedStack pStackResult = handler.getResultStack(recipeIndex);
// 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 (pStackResult == null) {
if (pStackResults.isEmpty()) {
for (PositionedStack otherStack : handler.getOtherStacks(recipeIndex)) {
if (!FluidContainerRegistry.isContainer(otherStack.items[0])
|| StackInfo.getFluid(otherStack.items[0]) != null) {
pStackResult = otherStack;
pStackResults.add(otherStack);
break;
}
}
}
return new RecipeId(extractItem(pStackResult), handlerName, extractIngredients(ingredients));
return new RecipeId(
extractItem(!pStackResults.isEmpty() ? pStackResults.get(0) : null),
handlerName,
extractIngredients(ingredients));
}
public static RecipeId of(JsonObject json) {
@@ -89,7 +96,7 @@ public class Recipe {
return new RecipeId(result, handlerName, ingredients);
}
public String getHandleName() {
public String getHandlerName() {
return this.handlerName;
}
@@ -389,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));
@@ -4,6 +4,7 @@ import java.awt.Point;
import java.awt.Rectangle;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.HashSet;
import java.util.LinkedList;
import java.util.List;
@@ -30,6 +31,7 @@ import com.google.common.base.Stopwatch;
import codechicken.lib.gui.GuiDraw;
import codechicken.nei.ItemList;
import codechicken.nei.KeyManager;
import codechicken.nei.NEIClientConfig;
import codechicken.nei.NEIClientUtils;
import codechicken.nei.NEIServerUtils;
@@ -131,7 +133,48 @@ public abstract class TemplateRecipeHandler implements ICraftingHandler, IUsageH
public abstract PositionedStack getResult();
/**
* The ingredients required to produce the result Use this if you have more than one ingredient
* The multiple items produced by this recipe, with position
*
* @return A list of positioned ingredient items.
*/
public List<PositionedStack> getResults() {
ArrayList<PositionedStack> stacks = new ArrayList<>();
try {
PositionedStack stack = getResult();
if (stack != null) stacks.add(stack);
} catch (ArithmeticException e) {
NEIClientConfig.logger.error("Error in getOtherStacks: " + e);
}
return stacks;
}
/**
* Return extra items that are not directly involved in the ingredient->result relationship. Eg fuels.
*
* @return A list of positioned ingredient items.
*/
public List<PositionedStack> getCatalysts() {
ArrayList<PositionedStack> stacks = new ArrayList<>();
try {
PositionedStack stack = getCatalyst();
if (stack != null) stacks.add(stack);
} catch (ArithmeticException e) {
NEIClientConfig.logger.error("Error in getCatalysts: " + e);
}
return stacks;
}
/**
* Simple utility
*
* @return The another positioned stack
*/
public PositionedStack getCatalyst() {
return null;
}
/**
* The ingredients required to produce the result. Use this if you have more than one ingredient
*
* @return A list of positioned ingredient items.
*/
@@ -150,6 +193,8 @@ public abstract class TemplateRecipeHandler implements ICraftingHandler, IUsageH
}
/**
* Legacy API
*
* Return extra items that are not directly involved in the ingredient->result relationship. Eg fuels. Use this
* if you have more than one other stack
*
@@ -288,9 +333,9 @@ public abstract class TemplateRecipeHandler implements ICraftingHandler, IUsageH
public boolean lastKeyTyped(GuiContainer gui, char keyChar, int keyCode) {
if (!canHandle(gui)) return false;
if (NEIClientConfig.isKeyHashDown("gui.recipe")) {
if (KeyManager.isKeyDown("recipe.recipe")) {
return transferRect(gui, false);
} else if (NEIClientConfig.isKeyHashDown("gui.usage")) {
} else if (KeyManager.isKeyDown("recipe.usage")) {
return transferRect(gui, true);
}
@@ -624,13 +669,23 @@ public abstract class TemplateRecipeHandler implements ICraftingHandler, IUsageH
}
public PositionedStack getResultStack(int recipe) {
List<PositionedStack> results = getResultStacks(recipe);
if (results == null || results.isEmpty()) return null;
return results.get(0);
}
public List<PositionedStack> getResultStacks(int recipe) {
try {
return arecipes.get(recipe).getResult();
return arecipes.get(recipe).getResults();
} catch (ArrayIndexOutOfBoundsException ignored) {
return null;
return Collections.emptyList();
}
}
public List<PositionedStack> getCatalystStacks(int recipe) {
return arecipes.get(recipe).getCatalysts();
}
public List<PositionedStack> getOtherStacks(int recipe) {
return arecipes.get(recipe).getOtherStacks();
}
@@ -672,9 +727,9 @@ public abstract class TemplateRecipeHandler implements ICraftingHandler, IUsageH
@Override
public boolean keyTyped(GuiRecipe<?> gui, char keyChar, int keyCode, int recipe) {
if (NEIClientConfig.isKeyHashDown("gui.recipe")) {
if (KeyManager.isKeyDown("recipe.recipe")) {
return transferRect(gui, recipe, false);
} else if (NEIClientConfig.isKeyHashDown("gui.usage")) {
} else if (KeyManager.isKeyDown("recipe.usage")) {
return transferRect(gui, recipe, true);
}
@@ -25,6 +25,34 @@ import codechicken.nei.recipe.StackInfo;
public class RecipeChainMath {
public interface ChainVisitor {
void enterRecipe(RecipeId recipeId, long multiplier);
void addIngredient(BookmarkItem ingrItem, long requestedAmount);
void addIngredientFresh(BookmarkItem ingrItem, long freshAmount);
void leaveRecipe();
}
private static class EmptyChainVisitor implements ChainVisitor {
@Override
public void enterRecipe(RecipeId recipeId, long multiplier) {}
@Override
public void addIngredient(BookmarkItem ingrItem, long requestedAmount) {}
@Override
public void addIngredientFresh(BookmarkItem ingrItem, long freshAmount) {}
@Override
public void leaveRecipe() {}
}
private static class ContainerItemResult {
public ItemStack stack;
@@ -38,6 +66,8 @@ public class RecipeChainMath {
}
}
private static final ChainVisitor EMPTY_CHAIN_VISITOR = new EmptyChainVisitor();
private static final ItemStack ROOT_ITEM = new ItemStack(Blocks.fire);
private static final RecipeId ROOT_RECIPE_ID = RecipeId
.of(ROOT_ITEM, "recipe-autocrafting", Collections.emptyList());
@@ -298,6 +328,10 @@ public class RecipeChainMath {
}
public RecipeChainMath refresh() {
return refresh(EMPTY_CHAIN_VISITOR);
}
public RecipeChainMath refresh(ChainVisitor visitor) {
final boolean isPausedItemDamageSound = StackInfo.isPausedItemDamageSound();
StackInfo.pauseItemDamageSound(true);
@@ -321,7 +355,7 @@ public class RecipeChainMath {
}
this.preferredItems.put(prefItem, prefItem);
calculateSuitableRecipe(prefItem, prefAmount, new ArrayList<>());
calculateSuitableRecipe(prefItem, prefAmount, new ArrayList<>(), visitor);
this.preferredItems.remove(prefItem);
}
}
@@ -338,9 +372,12 @@ public class RecipeChainMath {
return this;
}
private void calculateSuitableRecipe(BookmarkItem ingrItem, long ingrAmount, List<RecipeId> visited) {
private void calculateSuitableRecipe(BookmarkItem ingrItem, long ingrAmount, List<RecipeId> visited,
ChainVisitor visitor) {
final BookmarkItem prefItem = this.preferredItems.get(ingrItem);
visitor.addIngredient(prefItem != null ? prefItem : ingrItem, ingrAmount);
// calculate existing containers
if (ingrAmount > 0) {
for (ItemStack stack : ingrItem.permutations.values()) {
@@ -358,7 +395,7 @@ public class RecipeChainMath {
if (ingrAmount > 0) {
for (BookmarkItem item : this.initialItems) {
if (item.containsItems(ingrItem)
&& (ingrAmount = addRequiredAmount(item, ingrAmount, item.getAmount())) == 0) {
&& (ingrAmount = addRequiredAmount(item, ingrAmount, item.getAmount(), visitor)) == 0) {
break;
}
}
@@ -366,33 +403,37 @@ public class RecipeChainMath {
// shift amount
if (prefItem == null) {
addRequiredAmount(ingrItem, ingrAmount, Long.MAX_VALUE);
addRequiredAmount(ingrItem, ingrAmount, Long.MAX_VALUE, visitor);
} else if (visited.contains(prefItem.recipeId)) {
addRequiredAmount(prefItem, ingrAmount, Long.MAX_VALUE);
addRequiredAmount(prefItem, ingrAmount, Long.MAX_VALUE, visitor);
} else {
addRequiredAmount(prefItem, ingrAmount, Long.MAX_VALUE);
addRequiredAmount(prefItem, ingrAmount, Long.MAX_VALUE, visitor);
final long multiplier = Math
.max(0, prefItem.getMultiplierFromAmount(this.requiredAmount.get(prefItem)) - prefItem.multiplier);
if (multiplier > 0) {
addShift(prefItem.recipeId, multiplier);
visited.add(prefItem.recipeId);
prepareIngredients(prefItem.recipeId, multiplier, visited);
prepareIngredients(prefItem.recipeId, multiplier, visited, visitor);
visited.remove(prefItem.recipeId);
}
}
}
private void prepareIngredients(RecipeId recipeId, long multiplier, List<RecipeId> visited) {
private void prepareIngredients(RecipeId recipeId, long multiplier, List<RecipeId> visited, ChainVisitor visitor) {
visitor.enterRecipe(recipeId, multiplier);
for (BookmarkItem item : this.recipeIngredients) {
if (!item.emptyFactor() && recipeId.equals(item.recipeId)) {
calculateSuitableRecipe(item, item.getAmount(multiplier), visited);
calculateSuitableRecipe(item, item.getAmount(multiplier), visited, visitor);
}
}
visitor.leaveRecipe();
}
private long addRequiredAmount(BookmarkItem prefItem, long ingrAmount, long maxAmount) {
private long addRequiredAmount(BookmarkItem prefItem, long ingrAmount, long maxAmount, ChainVisitor visitor) {
long shiftAmount = this.requiredAmount.getOrDefault(prefItem, 0L);
if (hasContainerItem(prefItem.itemStack)) {
@@ -411,8 +452,9 @@ public class RecipeChainMath {
final ContainerItemResult result = getToolsContainerItems(itemStack, steps);
if (result.stack == null) {
multiplier = steps / (steps - result.leftSteps);
steps = steps % (steps - result.leftSteps);
final long stepsPerReplacement = steps - result.leftSteps;
multiplier = Math.min(steps / stepsPerReplacement, maxAmount - shiftAmount);
steps -= multiplier * stepsPerReplacement;
} else {
steps = result.leftSteps;
}
@@ -448,6 +490,7 @@ public class RecipeChainMath {
ingrAmount -= initAmount;
}
visitor.addIngredientFresh(prefItem, shiftAmount - this.requiredAmount.getOrDefault(prefItem, 0L));
this.requiredAmount.put(prefItem, shiftAmount);
return ingrAmount;
@@ -612,14 +612,12 @@ public class DebugHandlerWidget extends Widget {
for (String line : linesList) {
final String[] parts = line.split(",");
final String handlerKey = parts[0];
if (GuiRecipeTab.handlerMap.containsKey(handlerKey)) {
final HandlerInfoRecord record = patches.computeIfAbsent(
handlerKey,
key -> new HandlerInfoRecord(key, GuiRecipeTab.handlerMap.get(key)));
record.apply((line + ",null,null,null,null,null,null,null,null,null,null"));
}
final HandlerInfoRecord record = patches.computeIfAbsent(
handlerKey,
key -> new HandlerInfoRecord(
key,
GuiRecipeTab.handlerMap.getOrDefault(key, GuiRecipeTab.DEFAULT_HANDLER_INFO)));
record.apply((line + ",null,null,null,null,null,null,null,null,null,null"));
}
});
@@ -666,9 +664,8 @@ public class DebugHandlerWidget extends Widget {
private String getHandlerID(IRecipeHandler handler) {
if (GuiRecipeTab.handlerMap.containsKey(handler.getHandlerId())) {
return handler.getHandlerId();
} else if (handler instanceof TemplateRecipeHandler) {
if (!GuiRecipeTab.handlerMap.containsKey(handler.getHandlerId()) && handler instanceof TemplateRecipeHandler
&& handler.getOverlayIdentifier() != null) {
return handler.getOverlayIdentifier();
}
@@ -1,4 +1,4 @@
package codechicken.nei.recipe;
package codechicken.nei.util;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.inventory.Container;
@@ -8,7 +8,7 @@ import net.minecraft.item.ItemStack;
import codechicken.nei.PositionedStack;
import codechicken.nei.api.ShortcutInputHandler;
public class ContainerRecipe extends Container {
public class EmptyContainer extends Container {
private ItemStack activeStack = null;
@@ -23,13 +23,13 @@ public class NEIKeyboardUtils {
keyHashMap.put(Keyboard.KEY_RSHIFT, SHIFT_HASH);
keyHashMap.put(Keyboard.KEY_LCONTROL, CTRL_HASH);
keyHashMap.put(Keyboard.KEY_LCONTROL, CTRL_HASH);
keyHashMap.put(Keyboard.KEY_RCONTROL, CTRL_HASH);
keyHashMap.put(Keyboard.KEY_LMETA, CTRL_HASH);
keyHashMap.put(Keyboard.KEY_RMETA, CTRL_HASH);
keyHashMap.put(Keyboard.KEY_LMENU, ALT_HASH);
keyHashMap.put(Keyboard.KEY_LMENU, ALT_HASH);
keyHashMap.put(Keyboard.KEY_RMENU, ALT_HASH);
}
private NEIKeyboardUtils() {}
@@ -67,7 +67,7 @@ public class NEIKeyboardUtils {
}
if (keyID != Keyboard.CHAR_NONE || hashText.isEmpty()) {
keyText.add(Keyboard.getKeyName(keyID));
keyText.add(keyID < 0 ? NEIMouseUtils.getKeyName(keyID + 100) : Keyboard.getKeyName(keyID));
}
return keyText.toString();
+21 -1
View File
@@ -62,6 +62,27 @@ ICONST_0
ICONST_1 #keep the destination alpha
INVOKESTATIC net/minecraft/client/renderer/OpenGlHelper.func_148821_a (IIII)V
list m_keyBindingOnTickAll
ILOAD 0
INVOKESTATIC codechicken/nei/asm/KeyBindingFixHooks.onTickAll (I)V
RETURN
list m_keyBindingSetStateAll
ILOAD 0
ILOAD 1
INVOKESTATIC codechicken/nei/asm/KeyBindingFixHooks.setKeyBindStateAll (IZ)V
RETURN
list saveOptionsHook
INVOKESTATIC codechicken/nei/asm/SaveOptionsFixHooks.onBeforeSaveOptions ()V
list n_saveOptionsSendSettings
ALOAD 0
INVOKEVIRTUAL net/minecraft/client/settings/GameSettings.func_82879_c ()V
list saveOptionsRestoreHook
INVOKESTATIC codechicken/nei/asm/SaveOptionsFixHooks.onAfterSaveOptions ()V
#begin GuiContainer patches
@@ -383,4 +404,3 @@ INVOKEVIRTUAL codechicken/nei/guihook/GuiContainerManager.objectUnderMouse (II)Z
IFEQ LCONT
RETURN
LCONT
@@ -1224,11 +1224,6 @@ gtpp.recipe.lftr.sparging,gregtech:gt.blockmachines:31035,,miscutils,TRUE,,,,,,n
gtpp.recipe.matterfab2,gregtech:gt.blockmachines:799,,miscutils,TRUE,,,,,,
gtpp.recipe.multicentrifuge,gregtech:gt.blockmachines:790,,miscutils,TRUE,,,,,,
gtpp.recipe.multielectro,gregtech:gt.blockmachines:796,,miscutils,TRUE,,,,,,
gtpp.recipe.simplewasher,gregtech:gt.blockmachines:767,,miscutils,TRUE,,,,,,
gtpp.recipe.simplewasher,gregtech:gt.blockmachines:31017,,miscutils,TRUE,,,,,,
gtpp.recipe.simplewasher,gregtech:gt.blockmachines:31018,,miscutils,TRUE,,,,,,
gtpp.recipe.simplewasher,gregtech:gt.blockmachines:31019,,miscutils,TRUE,,,,,,
gtpp.recipe.simplewasher,gregtech:gt.blockmachines:31020,,miscutils,TRUE,,,,,,
gtpp.recipe.vacfurnace,gregtech:gt.blockmachines:995,,miscutils,TRUE,,,,,,
gtpp.recipe.flotationcell,gregtech:gt.blockmachines:31028,,miscutils,TRUE,,,,,,
gtpp.recipe.fluidchemicaleactor,gregtech:gt.blockmachines:998,,miscutils,TRUE,,,,,,
1 handler itemName nbtInfo modId modRequired excludedModId priority minVersion maxVersion forceClassName itemNotes
1224 gtpp.recipe.matterfab2 gregtech:gt.blockmachines:799 miscutils TRUE
1225 gtpp.recipe.multicentrifuge gregtech:gt.blockmachines:790 miscutils TRUE
1226 gtpp.recipe.multielectro gregtech:gt.blockmachines:796 miscutils TRUE
gtpp.recipe.simplewasher gregtech:gt.blockmachines:767 miscutils TRUE
gtpp.recipe.simplewasher gregtech:gt.blockmachines:31017 miscutils TRUE
gtpp.recipe.simplewasher gregtech:gt.blockmachines:31018 miscutils TRUE
gtpp.recipe.simplewasher gregtech:gt.blockmachines:31019 miscutils TRUE
gtpp.recipe.simplewasher gregtech:gt.blockmachines:31020 miscutils TRUE
1227 gtpp.recipe.vacfurnace gregtech:gt.blockmachines:995 miscutils TRUE
1228 gtpp.recipe.flotationcell gregtech:gt.blockmachines:31028 miscutils TRUE
1229 gtpp.recipe.fluidchemicaleactor gregtech:gt.blockmachines:998 miscutils TRUE
@@ -60,11 +60,11 @@ nei.options.wbutton.tip.1=Přepisuji globální nastavení
nei.options.keys=Nastavení kláves
nei.options.keys.gui=Inventář
nei.options.keys.gui.recipe=Recept
nei.options.keys.gui.usage=Použití
nei.options.keys.recipe.recipe=Recept
nei.options.keys.recipe.usage=Použití
nei.options.keys.gui.enchant=Očarování
nei.options.keys.gui.potion=Lektvary
nei.options.keys.gui.back=Předchozí recept
nei.options.keys.recipe.back=Předchozí recept
nei.options.keys.gui.prev=Předchozí stránka
nei.options.keys.gui.next=Další stránka
nei.options.keys.gui.hide=Přepnout viditelnost NEI
@@ -64,11 +64,11 @@ nei.options.wbutton.tip.1=Übergeht globale Einstellungen
nei.options.keys=Tastenbelegung
nei.options.keys.gui=Inventar
nei.options.keys.gui.recipe=Rezept
nei.options.keys.gui.usage=Nutzung
nei.options.keys.recipe.recipe=Rezept
nei.options.keys.recipe.usage=Nutzung
nei.options.keys.gui.enchant=Verzauberungen
nei.options.keys.gui.potion=Tränke
nei.options.keys.gui.back=Vorheriges Rezept
nei.options.keys.recipe.back=Vorheriges Rezept
nei.options.keys.gui.prev=Vorherige Seite
nei.options.keys.gui.next=Nächste Seite
nei.options.keys.gui.hide=Verstelle NEI-Sichtbarkeit
+38 -25
View File
@@ -32,7 +32,9 @@ nei.bookmark.group.pull_items=Pull all Items
nei.bookmark.group.pull_items_shift=Pull missing Items
nei.bookmark.group.craft_missing=Craft Missing Items
nei.bookmark.group.craft_all=Craft Items
nei.bookmark.group.chat_link=Send Bookmark Group to Chat
nei.bookmark.item.sorting=Move Position
nei.bookmark.item.chat_link=Send Item to Chat
nei.bookmark.remove_recipe=Remove Recipe
nei.bookmark.remove_item=Remove Item
nei.bookmark.add_item=Add Bookmark
@@ -42,6 +44,7 @@ nei.bookmark.add_item_with_count=Add Bookmark with Count
nei.bookmark.change_quantity=Change Quantity
nei.bookmark.change_quantity_step=Change Quantity with Multiplier
nei.bookmark.recipe.toggle_collapse=Toggle Collapse/Expand
nei.bookmark.recipe.chat_link=Send Recipe to Chat
nei.bookmark.crafting_chain=Crafting Chain
nei.bookmark.crafting_chain.input=Ingredients
nei.bookmark.crafting_chain.missing=Missing Items
@@ -68,6 +71,7 @@ nei.itempanel.infinite_item=Give Infinite Item
nei.itempanel.copy_name=Copy Item Name
nei.itempanel.copy_oredict=Copy Item OreDictionary
nei.itempanel.copy_id=Copy Item ID
nei.itempanel.chat_link_item=Send item link to chat
nei.enchant=Enchant
@@ -143,6 +147,9 @@ nei.chat.chunkoverlay.3=Chunk Overlay: GT Ore Veins
nei.chat.moboverlay.0=Mob Spawning Overlay: §cOff
nei.chat.moboverlay.1=Mob Spawning Overlay: §2On
nei.chat.item_link.text=<%s> §6Click to add bookmark: %s
nei.chat.item_link.item.text=Bookmark Item
nei.chat.item_link.recipe.text=Bookmark Recipe
nei.chat.item_link.group.text=Bookmark Group
nei.chat.bookmark_added.text=Bookmark added!
nei.chat.recipeid.many_params=Too many parameters! Usage: %s
@@ -169,41 +176,46 @@ nei.options.wbutton.tip.0=Using global settings
nei.options.wbutton.tip.1=Overriding global setting
nei.options.keys=KeyBindings
nei.options.keys.tip=Configure NEI key bindings in the Minecraft controls screen
nei.options.keys.gui=NEI Inventory
nei.options.keys.world=NEI World
nei.options.keys.recipe=NEI Recipe
nei.options.keys.bookmark=NEI Bookmarks
nei.options.keys.copy=NEI Copy
nei.options.keys.itemzoom=NEI Item Zoom
nei.options.keys.showenchant=Show Enchant
nei.options.keys.gui=Inventory
nei.options.keys.gui.recipe=Recipe
nei.options.keys.gui.usage=Usage
nei.options.keys.recipe.recipe=Recipe
nei.options.keys.recipe.usage=Usage
nei.options.keys.gui.enchant=Enchantments
nei.options.keys.gui.potion=Potions
nei.options.keys.gui.back=Back to last Recipe
nei.options.keys.recipe.back=Back to last Recipe
nei.options.keys.gui.prev=Prev Item Panel Page
nei.options.keys.gui.next=Next Item Panel Page
nei.options.keys.gui.hide=Toggle NEI Visibility
nei.options.keys.gui.next_recipe=Next Recipe
nei.options.keys.gui.prev_recipe=Prev Recipe
nei.options.keys.gui.next_machine=Next Machine
nei.options.keys.gui.prev_machine=Prev Machine
nei.options.keys.gui.hide=Toggle Visibility
nei.options.keys.recipe.next_recipe=Next Recipe
nei.options.keys.recipe.prev_recipe=Prev Recipe
nei.options.keys.recipe.next_machine=Next Machine
nei.options.keys.recipe.prev_machine=Prev Machine
nei.options.keys.gui.search=Focus Search Bar
nei.options.keys.gui.bookmark=Add Bookmark
nei.options.keys.gui.remove_recipe=Remove Group from Bookmarks
nei.options.keys.gui.bookmark_pull_items=Pull all Bookmarked Items
nei.options.keys.gui.hide_bookmarks=Toggle Bookmark Panel Visibility
nei.options.keys.bookmark.add=Add Bookmark
nei.options.keys.bookmark.remove_recipe=Remove Group from Bookmarks (Shift +)
nei.options.keys.bookmark.pull_items=Pull all Bookmarked Items
nei.options.keys.bookmark.hide=Toggle Bookmark Panel Visibility
nei.options.keys.bookmark.chat_link=Send link to chat (Ctrl +)
nei.options.keys.gui.overlay=Fill/Overlay Crafting Grid
nei.options.keys.gui.getprevioussearch=Previous Search
nei.options.keys.gui.getnextsearch=Next Search
nei.options.keys.gui.next_tooltip=Next Tooltip
nei.options.keys.gui.copy_name=Copy Item Name
nei.options.keys.gui.craft_items=Craft Items
nei.options.keys.gui.copy_oredict=Copy Item OreDictionary
nei.options.keys.gui.copy_id=Copy Item ID
nei.options.keys.gui.chat_link_item=Send item link to chat
nei.options.keys.gui.itemzoom_toggle=Toggle Item Zoom
nei.options.keys.gui.itemzoom_hold=Hold to Display Item Zoom
nei.options.keys.gui.itemzoom_zoom_in=Item Zoom In
nei.options.keys.gui.itemzoom_zoom_out=Item Zoom Out
nei.options.keys.gui.favorite=Add Favorite
nei.options.keys.gui.favorite_item=Toggle Favorite
nei.options.keys.world=World
nei.options.keys.copy.name=Copy Item Name (Ctrl +)
nei.options.keys.gui.craft_items=Craft Items (Shift +)
nei.options.keys.copy.oredict=Copy Item OreDictionary (Ctrl +)
nei.options.keys.copy.identifier=Copy Item ID (Ctrl +)
nei.options.keys.itemzoom.toggle=Toggle Item Zoom (Shift +)
nei.options.keys.itemzoom.hold=Hold to Display Item Zoom
nei.options.keys.itemzoom.zoom_in=Item Zoom In
nei.options.keys.itemzoom.zoom_out=Item Zoom Out
nei.options.keys.bookmark.favorite=Add Favorite (Shift +)
nei.options.keys.bookmark.favorite_item=Toggle Favorite (Shift +)
nei.options.keys.world.chunkoverlay=Chunk Boundary Overlay
nei.options.keys.world.moboverlay=Mob Spawn Overlay
nei.options.keys.world.highlight_tips=Highlight Tooltips
@@ -600,6 +612,7 @@ nei.recipe.overlay.overlayRecipe=Overlay Recipe
nei.recipe.overlay.fillCraftingGrid=Fill Crafting Grid
nei.recipe.overlay.bookmarkRecipe=Save with Recipe
nei.recipe.overlay.bookmarkRecipeAndCount=Save with Recipe & Count
nei.recipe.overlay.sendRecipeToChat=Send Recipe to Chat
nei.recipe.favorite=Favorite
nei.recipe.favorite.bookmark_recipe=Save Recipe Tree
@@ -63,11 +63,11 @@ nei.options.wbutton.tip.1=Globaalsete seadmete ületegemine
nei.options.keys=Klahviseosed
nei.options.keys.gui=Seljakott
nei.options.keys.gui.recipe=Retsept
nei.options.keys.gui.usage=Kasutus
nei.options.keys.recipe.recipe=Retsept
nei.options.keys.recipe.usage=Kasutus
nei.options.keys.gui.enchant=Loitsud
nei.options.keys.gui.potion=Joogid
nei.options.keys.gui.back=Eel. Retsept
nei.options.keys.recipe.back=Eel. Retsept
nei.options.keys.gui.prev=Eel. Leht
nei.options.keys.gui.next=Järg. Leht
nei.options.keys.gui.hide=Lülita NEI nähtavust
@@ -61,11 +61,11 @@ nei.options.wbutton.tip.1=Annuler l'utilisation des paramètres globaux
nei.options.keys=Raccourcis clavier
nei.options.keys.gui=Inventaire
nei.options.keys.gui.recipe=Recette
nei.options.keys.gui.usage=Usage
nei.options.keys.recipe.recipe=Recette
nei.options.keys.recipe.usage=Usage
nei.options.keys.gui.enchant=Enchantements
nei.options.keys.gui.potion=Potions
nei.options.keys.gui.back=Recette précédente
nei.options.keys.recipe.back=Recette précédente
nei.options.keys.gui.prev=Recette suivante
nei.options.keys.gui.next=Page suivante
nei.options.keys.gui.hide=Afficher ou cacher NEI
@@ -64,11 +64,11 @@ nei.options.wbutton.tip.1=Sovrascrivendo le opzioni globali
nei.options.keys=Controlli
nei.options.keys.gui=Inventario
nei.options.keys.gui.recipe=Ricetta
nei.options.keys.gui.usage=Usi
nei.options.keys.recipe.recipe=Ricetta
nei.options.keys.recipe.usage=Usi
nei.options.keys.gui.enchant=Incantare
nei.options.keys.gui.potion=Pozioni
nei.options.keys.gui.back=Ricetta precedente
nei.options.keys.recipe.back=Ricetta precedente
nei.options.keys.gui.prev=Pagina precedente
nei.options.keys.gui.next=Pagina successiva
nei.options.keys.gui.hide=Modifica visibilità NEI
@@ -59,11 +59,11 @@ nei.options.wbutton.tip.1=전역 설정
nei.options.keys=키 바인딩
nei.options.keys.gui=인벤토리
nei.options.keys.gui.recipe=레시피
nei.options.keys.gui.usage=사용법
nei.options.keys.gui.nei.enchant=인첸트
nei.options.keys.recipe.recipe=레시피
nei.options.keys.recipe.usage=사용법
nei.options.keys.gui.enchant=인첸트
nei.options.keys.gui.potion=포션
nei.options.keys.gui.back=이전 레시피
nei.options.keys.recipe.back=이전 레시피
nei.options.keys.gui.prev=이전 페이지
nei.options.keys.gui.next=다음 페이지
nei.options.keys.gui.hide=NEI 활성/비활성화
@@ -60,11 +60,11 @@ nei.options.wbutton.tip.1=Nadpisywanie ustawienia globalnego
nei.options.keys=Ustawienia klawiszy
nei.options.keys.gui=Ekwipunek
nei.options.keys.gui.recipe=Recepta
nei.options.keys.gui.usage=Użytek
nei.options.keys.recipe.recipe=Recepta
nei.options.keys.recipe.usage=Użytek
nei.options.keys.gui.enchant=Zaklęcia
nei.options.keys.gui.potion=Eleksiry
nei.options.keys.gui.back=Poprzednia recepta
nei.options.keys.recipe.back=Poprzednia recepta
nei.options.keys.gui.prev=Poprzednia strona
nei.options.keys.gui.next=Następna strona
nei.options.keys.gui.hide=Przełącz widzialność NEI
@@ -60,11 +60,11 @@ nei.options.wbutton.tip.1=Substituindo configurações globais
nei.options.keys=Atalhos de Teclado
nei.options.keys.gui=Inventário
nei.options.keys.gui.recipe=Receita
nei.options.keys.gui.usage=Uso
nei.options.keys.recipe.recipe=Receita
nei.options.keys.recipe.usage=Uso
nei.options.keys.gui.enchant=Encantamentos
nei.options.keys.gui.potion=Poções
nei.options.keys.gui.back=Receita Ant.
nei.options.keys.recipe.back=Receita Ant.
nei.options.keys.gui.prev=Pág. Anterior
nei.options.keys.gui.next=Próxima Pág.
nei.options.keys.gui.hide=Trocar Visibilidade do NEI
+31 -22
View File
@@ -20,6 +20,7 @@ nei.bookmark.group.sorting=Сортировка
nei.bookmark.group.remove_recipe=Удалить группу
nei.bookmark.group.pull_items=Переместить все предметы
nei.bookmark.group.pull_items_shift=Переместить недостающие предметы
nei.bookmark.group.chat_link=Отправить группу в чат
nei.bookmark.crafting_chain=Цепочка крафта
nei.bookmark.crafting_chain.input=Ингредиенты
nei.bookmark.crafting_chain.output=Результаты
@@ -116,39 +117,46 @@ nei.options.wbutton.tip.0=Используются глобальные наст
nei.options.wbutton.tip.1=Переопределение глобальной настройки
nei.options.keys=Привязки клавиш
nei.options.keys.tip=Настройте привязки клавиш NEI на экране управления Minecraft
nei.options.keys.gui=NEI Инвентарь
nei.options.keys.world=NEI Мир
nei.options.keys.recipe=NEI Рецепт
nei.options.keys.bookmark=NEI Закладки
nei.options.keys.copy=NEI Копирование
nei.options.keys.itemzoom=NEI Увеличение предмета
nei.options.keys.showenchant=Показать зачарование
nei.options.keys.gui=Инвентарь
nei.options.keys.gui.recipe=Рецепт
nei.options.keys.gui.usage=Использование
nei.options.keys.recipe.recipe=Рецепт
nei.options.keys.recipe.usage=Использование
nei.options.keys.gui.enchant=Зачарования
nei.options.keys.gui.potion=Зелья
nei.options.keys.gui.back=Назад к последнему рецепту
nei.options.keys.recipe.back=Назад к последнему рецепту
nei.options.keys.gui.prev=Предыдущая страница панели предметов
nei.options.keys.gui.next=Следующая страница панели предметов
nei.options.keys.gui.hide=Переключить видимость NEI
nei.options.keys.gui.next_recipe=Следующий рецепт
nei.options.keys.gui.prev_recipe=Предыдущий рецепт
nei.options.keys.gui.next_machine=Следующая машина
nei.options.keys.gui.prev_machine=Предыдущая машина
nei.options.keys.recipe.next_recipe=Следующий рецепт
nei.options.keys.recipe.prev_recipe=Предыдущий рецепт
nei.options.keys.recipe.next_machine=Следующая машина
nei.options.keys.recipe.prev_machine=Предыдущая машина
nei.options.keys.gui.search=Сфокусироваться на строке поиска
nei.options.keys.gui.bookmark=Добавить закладку
nei.options.keys.gui.remove_recipe=Удалить группу из закладок
nei.options.keys.gui.bookmark_recipe=Добавить закладку с рецептом
nei.options.keys.gui.bookmark_count=Добавить закладку с учётом количества
nei.options.keys.gui.bookmark_pull_items=Переместить все отмеченные предметы
nei.options.keys.gui.hide_bookmarks=Переключить видимость панели закладок
nei.options.keys.bookmark.add=Добавить закладку
nei.options.keys.bookmark.remove_recipe=Удалить группу из закладок (Shift +)
nei.options.keys.bookmark.pull_items=Переместить все отмеченные предметы
nei.options.keys.bookmark.hide=Переключить видимость панели закладок
nei.options.keys.bookmark.chat_link=Отправить ссылку в чат (Ctrl +)
nei.options.keys.gui.overlay=Заполнить сетку крафта
nei.options.keys.gui.getprevioussearch=Предыдущий поиск
nei.options.keys.gui.getnextsearch=Следующий поиск
nei.options.keys.gui.next_tooltip=Следующая подсказка
nei.options.keys.gui.copy_name=Скопировать название предмета
nei.options.keys.gui.copy_oredict=Скопировать OreDictionary предмета
nei.options.keys.gui.chat_link_item=Отправить ссылку на предмет в чат
nei.options.keys.gui.itemzoom_toggle=Переключить увеличение предмета
nei.options.keys.gui.itemzoom_hold=Удерживать для отображения увеличения предмета
nei.options.keys.gui.itemzoom_zoom_in=Увеличить предмет
nei.options.keys.gui.itemzoom_zoom_out=Уменьшить предмет
nei.options.keys.world=Мир
nei.options.keys.copy.name=Скопировать название предмета (Ctrl +)
nei.options.keys.gui.craft_items=Создать предметы (Shift +)
nei.options.keys.copy.oredict=Скопировать OreDictionary предмета (Ctrl +)
nei.options.keys.copy.identifier=Скопировать ID предмета (Ctrl +)
nei.options.keys.itemzoom.toggle=Переключить увеличение предмета (Shift +)
nei.options.keys.itemzoom.hold=Удерживать для отображения увеличения предмета
nei.options.keys.itemzoom.zoom_in=Увеличить предмет
nei.options.keys.itemzoom.zoom_out=Уменьшить предмет
nei.options.keys.bookmark.favorite=Добавить в избранное (Shift +)
nei.options.keys.bookmark.favorite_item=Переключить избранное (Shift +)
nei.options.keys.world.chunkoverlay=Отображение границ чанков
nei.options.keys.world.moboverlay=Отображение спавна мобов
nei.options.keys.world.highlight_tips=Подсветка подсказок
@@ -415,6 +423,7 @@ nei.recipe.overlay.missing=Отсутствует следующее
nei.recipe.overlay.mismatch=Несоответствие сетки крафта
nei.recipe.overlay.fillCraftingGrid=Заполнить сетку крафта
nei.recipe.overlay.bookmarkRecipe=Сохранить с рецептом
nei.recipe.overlay.sendRecipeToChat=Отправить рецепт в чат
nei.itemsort.minecraft=Minecraft
nei.itemsort.minecraft.tip=Сортирует предметы из ванильного Minecraft первыми
@@ -60,11 +60,11 @@ nei.options.wbutton.tip.1=Globálne nastavenia sú nahradené
nei.options.keys=Klávesové skratky
nei.options.keys.gui=Inventár
nei.options.keys.gui.recipe=Recept
nei.options.keys.gui.usage=Použitie
nei.options.keys.recipe.recipe=Recept
nei.options.keys.recipe.usage=Použitie
nei.options.keys.gui.enchant=Očarovania
nei.options.keys.gui.potion=Elixíry
nei.options.keys.gui.back=Predchádzajúci recept
nei.options.keys.recipe.back=Predchádzajúci recept
nei.options.keys.gui.prev=Predchádzajúca strana
nei.options.keys.gui.next=Nasledujúca strana
nei.options.keys.gui.hide=Prepni viditeľnosť NEI
@@ -60,11 +60,11 @@ nei.options.wbutton.tip.1=Genel ayarların üstüne yazılıyor
nei.options.keys=Tuşlar
nei.options.keys.gui=Envanter
nei.options.keys.gui.recipe=Tarifler
nei.options.keys.gui.usage=Kullanım yeri
nei.options.keys.recipe.recipe=Tarifler
nei.options.keys.recipe.usage=Kullanım yeri
nei.options.keys.gui.enchant=Büylüler
nei.options.keys.gui.potion=İksirler
nei.options.keys.gui.back=Önceki tarif
nei.options.keys.recipe.back=Önceki tarif
nei.options.keys.gui.prev=Önceki sayfa
nei.options.keys.gui.next=Sonraki sayfa
nei.options.keys.gui.hide=Nei görünürlük ayarı
+12 -14
View File
@@ -89,29 +89,27 @@ nei.options.wbutton.tip.1=覆写全局设置
nei.options.keys=按键绑定
nei.options.keys.showenchant=显示附魔值
nei.options.keys.gui=物品栏
nei.options.keys.gui.recipe=查看合成
nei.options.keys.gui.usage=查看用途
nei.options.keys.recipe.recipe=查看合成
nei.options.keys.recipe.usage=查看用途
nei.options.keys.gui.enchant=附魔
nei.options.keys.gui.potion=药水
nei.options.keys.gui.back=返回上一合成表
nei.options.keys.recipe.back=返回上一合成表
nei.options.keys.gui.prev=上一页
nei.options.keys.gui.next=下一页
nei.options.keys.gui.hide=隐藏/显示NEI界面
nei.options.keys.gui.next_recipe=下一合成表
nei.options.keys.gui.prev_recipe=上一合成表
nei.options.keys.gui.next_machine=下一机器
nei.options.keys.gui.prev_machine=上一机器
nei.options.keys.recipe.next_recipe=下一合成表
nei.options.keys.recipe.prev_recipe=上一合成表
nei.options.keys.recipe.next_machine=下一机器
nei.options.keys.recipe.prev_machine=上一机器
nei.options.keys.gui.search=跳转到搜索框
nei.options.keys.gui.bookmark=添加书签
nei.options.keys.gui.bookmark_recipe=添加带有合成表的书签
nei.options.keys.gui.bookmark_count=添加带有数量的书签
nei.options.keys.gui.hide_bookmarks=显示/隐藏书签页
nei.options.keys.bookmark.add=添加书签
nei.options.keys.bookmark.hide=显示/隐藏书签页
nei.options.keys.gui.overlay=使用覆盖合成表
nei.options.keys.gui.getprevioussearch=上一个搜索
nei.options.keys.gui.getnextsearch=下一个搜索
nei.options.keys.gui.copy_name=复制物品名称
nei.options.keys.gui.copy_oredict=复制物品矿词词典
nei.options.keys.gui.copy_id=复制物品ID
nei.options.keys.copy.name=复制物品名称 (Ctrl +)
nei.options.keys.copy.oredict=复制物品矿词词典 (Ctrl +)
nei.options.keys.copy.identifier=复制物品ID (Ctrl +)
nei.options.keys.world=世界
nei.options.keys.world.chunkoverlay=区块(chunks)边界显示
nei.options.keys.world.moboverlay=刷怪区域显示
@@ -59,11 +59,11 @@ nei.options.wbutton.tip.1=覆蓋全局設定
nei.options.keys=按鍵設定
nei.options.keys.gui=物品欄
nei.options.keys.gui.recipe=合成表
nei.options.keys.gui.usage=用途
nei.options.keys.recipe.recipe=合成表
nei.options.keys.recipe.usage=用途
nei.options.keys.gui.enchant=附魔
nei.options.keys.gui.potion=藥水
nei.options.keys.gui.back=上一個合成表
nei.options.keys.recipe.back=上一個合成表
nei.options.keys.gui.prev=上一頁
nei.options.keys.gui.next=下一頁
nei.options.keys.gui.hide=隱藏/顯示NEI界面
@@ -15,6 +15,8 @@ import java.util.stream.Stream;
import net.minecraft.client.Minecraft;
import net.minecraft.client.resources.Language;
import net.minecraft.client.resources.LanguageManager;
import net.minecraft.client.settings.GameSettings;
import net.minecraft.client.settings.KeyBinding;
import net.minecraft.item.ItemStack;
import net.minecraft.util.EnumChatFormatting;
@@ -160,6 +162,11 @@ public class SearchTokenParserTest {
language = mock(Language.class);
when(languageManager.getCurrentLanguage()).thenReturn(language);
when(language.getLanguageCode()).thenReturn("en");
GameSettings gameSettings = mock(GameSettings.class);
gameSettings.keyBindings = new KeyBinding[0];
minecraft.gameSettings = gameSettings;
config = mockStatic(NEIClientConfig.class);
config.when(() -> NEIClientConfig.getBooleanSetting(eq("inventory.search.logSearchExceptions")))
.thenReturn(false);