2014-04-29 10:54:20 +10:00
package codechicken.nei ;
2023-09-25 00:35:24 +02:00
import java.io.File ;
import java.util.Comparator ;
import java.util.HashMap ;
import java.util.HashSet ;
import java.util.List ;
2024-02-15 09:51:48 -08:00
import java.util.Map ;
2024-08-29 23:14:52 +03:00
import java.util.Set ;
2023-09-25 00:35:24 +02:00
import java.util.function.Function ;
import java.util.regex.Pattern ;
2025-02-08 20:11:17 +02:00
import java.util.stream.Stream ;
2023-09-25 00:35:24 +02:00
import net.minecraft.client.Minecraft ;
import net.minecraft.client.gui.GuiScreen ;
import net.minecraft.client.renderer.OpenGlHelper ;
import net.minecraft.item.ItemStack ;
import net.minecraft.nbt.NBTTagCompound ;
2024-06-27 18:03:50 +03:00
import net.minecraft.util.EnumChatFormatting ;
2023-09-25 00:35:24 +02:00
import net.minecraft.world.World ;
import net.minecraft.world.storage.SaveFormatComparator ;
import net.minecraftforge.common.MinecraftForge ;
import org.apache.logging.log4j.LogManager ;
import org.apache.logging.log4j.Logger ;
import org.lwjgl.input.Keyboard ;
import com.google.common.base.Objects ;
2024-08-29 08:17:00 +02:00
import com.google.common.reflect.TypeToken ;
import com.google.gson.Gson ;
import com.google.gson.JsonParseException ;
2023-09-25 00:35:24 +02:00
2019-12-24 13:37:41 -08:00
import codechicken.core.CCUpdateChecker ;
import codechicken.core.ClientUtils ;
import codechicken.core.CommonUtils ;
2014-04-29 10:54:20 +10:00
import codechicken.lib.config.ConfigFile ;
import codechicken.lib.config.ConfigTag ;
import codechicken.lib.config.ConfigTagParent ;
2019-12-24 13:37:41 -08:00
import codechicken.nei.api.API ;
import codechicken.nei.api.GuiInfo ;
import codechicken.nei.api.IConfigureNEI ;
import codechicken.nei.api.ItemInfo ;
import codechicken.nei.api.NEIInfo ;
import codechicken.nei.config.ConfigSet ;
import codechicken.nei.config.GuiHighlightTips ;
import codechicken.nei.config.GuiNEIOptionList ;
import codechicken.nei.config.GuiOptionList ;
2022-05-06 22:41:45 +03:00
import codechicken.nei.config.GuiPanelSettings ;
2019-12-24 13:37:41 -08:00
import codechicken.nei.config.OptionCycled ;
import codechicken.nei.config.OptionGamemodes ;
2024-02-21 18:12:28 +02:00
import codechicken.nei.config.OptionIntegerField ;
2019-12-24 13:37:41 -08:00
import codechicken.nei.config.OptionList ;
import codechicken.nei.config.OptionOpenGui ;
import codechicken.nei.config.OptionTextField ;
import codechicken.nei.config.OptionToggleButton ;
2021-03-20 22:38:46 -07:00
import codechicken.nei.config.OptionToggleButtonBoubs ;
2019-12-24 13:37:41 -08:00
import codechicken.nei.config.OptionUtilities ;
2024-07-26 18:44:54 +03:00
import codechicken.nei.config.preset.GuiPresetList ;
2021-08-13 22:49:00 +03:00
import codechicken.nei.event.NEIConfigsLoadedEvent ;
2021-03-28 00:12:17 -07:00
import codechicken.nei.recipe.GuiRecipeTab ;
2021-10-16 11:31:43 -06:00
import codechicken.nei.recipe.IRecipeHandler ;
2022-01-31 01:01:12 +09:00
import codechicken.nei.recipe.RecipeCatalysts ;
2014-04-29 10:54:20 +10:00
import codechicken.nei.recipe.RecipeInfo ;
2025-01-26 20:59:16 +02:00
import codechicken.nei.util.NEIKeyboardUtils ;
2014-04-29 10:54:20 +10:00
import codechicken.obfuscator.ObfuscationRun ;
2023-01-28 17:55:51 -08:00
2021-04-13 20:16:56 -07:00
public class NEIClientConfig {
2023-01-28 17:55:51 -08:00
2023-05-10 23:55:45 +02:00
private static boolean mainNEIConfigLoaded ;
private static boolean pluginNEIConfigLoaded ;
2014-04-29 10:54:20 +10:00
private static boolean enabledOverride ;
2022-01-09 19:05:30 +02:00
private static String worldPath ;
2014-04-29 10:54:20 +10:00
public static Logger logger = LogManager . getLogger ( "NotEnoughItems" );
public static File configDir = new File ( CommonUtils . getMinecraftDir (), "config/NEI/" );
2022-06-24 12:32:13 +01:00
public static ConfigSet global = new ConfigSet (
new File ( "saves/NEI/client.dat" ),
new ConfigFile ( new File ( configDir , "client.cfg" )));
2014-04-29 10:54:20 +10:00
public static ConfigSet world ;
2021-03-28 00:12:17 -07:00
public static final File handlerFile = new File ( configDir , "handlers.csv" );
2022-01-31 01:01:12 +09:00
public static final File catalystFile = new File ( configDir , "catalysts.csv" );
2021-04-13 20:16:56 -07:00
2022-01-09 19:05:30 +02:00
@Deprecated
public static File bookmarkFile ;
2021-04-13 20:16:56 -07:00
// Set of handlers that need to be run in serial
2021-10-16 11:31:43 -06:00
public static HashSet < String > serialHandlers = new HashSet <> ();
2021-11-28 15:25:48 -07:00
// Set of regexes matching handler ID of handlers that need the hack in GuiRecipe.startHeightHack().
// We use regex here so that we can apply the height hack to entire mods with one entry.
public static HashSet < Pattern > heightHackHandlerRegex = new HashSet <> ();
2021-10-16 11:31:43 -06:00
2024-02-04 14:09:24 +02:00
// Set of handler Name or Id of handlers that need hide.
public static HashSet < String > hiddenHandlers = new HashSet <> ();
2021-10-16 11:31:43 -06:00
// Map of handler ID to sort order.
// Handlers will be sorted in ascending order, so smaller numbers show up earlier.
// Any handler not in the map will be assigned to 0, and negative numbers are fine.
public static HashMap < String , Integer > handlerOrdering = new HashMap <> ();
2024-08-29 23:14:52 +03:00
public static final Set < Class <?>> pluginsList = new HashSet <> ();
2021-10-16 11:31:43 -06:00
// Function that extracts the handler ID from a handler, with special logic for
// TemplateRecipeHandler: prefer using the overlay ID if it exists.
public static final Function < IRecipeHandler , String > HANDLER_ID_FUNCTION = handler -> Objects
2022-06-24 12:32:13 +01:00
. firstNonNull ( handler . getOverlayIdentifier (), handler . getHandlerId ());
2021-10-16 11:31:43 -06:00
2022-08-27 05:14:08 +09:00
public static int getHandlerOrder ( IRecipeHandler handler ) {
2022-09-03 17:25:40 +09:00
if ( handlerOrdering . get ( handler . getOverlayIdentifier ()) != null ) {
return handlerOrdering . get ( handler . getOverlayIdentifier ());
}
if ( handlerOrdering . get ( handler . getHandlerId ()) != null ) {
return handlerOrdering . get ( handler . getHandlerId ());
}
return 0 ;
2022-08-27 05:14:08 +09:00
}
2021-10-16 11:31:43 -06:00
// Comparator that compares handlers using the handlerOrdering map.
public static final Comparator < IRecipeHandler > HANDLER_COMPARATOR = Comparator
2022-08-27 05:14:08 +09:00
. comparingInt ( NEIClientConfig :: getHandlerOrder );
2014-04-29 10:54:20 +10:00
2019-12-24 13:37:41 -08:00
public static ItemStack [] creativeInv ;
2014-04-29 10:54:20 +10:00
public static boolean hasSMPCounterpart ;
2019-12-30 20:19:16 -08:00
public static HashSet < String > permissableActions = new HashSet <> ();
public static HashSet < String > disabledActions = new HashSet <> ();
public static HashSet < String > enabledActions = new HashSet <> ();
2014-04-29 10:54:20 +10:00
public static ItemStackSet bannedBlocks = new ItemStackSet ();
static {
2022-06-24 12:32:13 +01:00
if ( global . config . getTag ( "checkUpdates" ). getBooleanValue ( true )) CCUpdateChecker . updateCheck ( "NotEnoughItems" );
2014-04-29 10:54:20 +10:00
linkOptionList ();
setDefaults ();
}
private static void setDefaults () {
ConfigTagParent tag = global . config ;
2022-06-24 12:32:13 +01:00
tag . setComment (
"Main configuration of NEI.\nMost of these options can be changed ingame.\nDeleting any element will restore it to it's default value" );
2014-04-29 10:54:20 +10:00
2022-06-24 12:32:13 +01:00
tag . getTag ( "command" ). useBraces (). setComment (
"Change these options if you have a different mod installed on the server that handles the commands differently, Eg. Bukkit Essentials" );
2014-04-29 10:54:20 +10:00
tag . setNewLineMode ( 1 );
tag . getTag ( "inventory.widgetsenabled" ). getBooleanValue ( true );
API . addOption ( new OptionToggleButton ( "inventory.widgetsenabled" ));
2021-11-22 05:31:02 +02:00
2014-04-29 10:54:20 +10:00
tag . getTag ( "inventory.hidden" ). getBooleanValue ( false );
tag . getTag ( "inventory.cheatmode" ). getIntValue ( 2 );
2022-06-24 12:32:13 +01:00
tag . getTag ( "inventory.lockmode" ). setComment (
"For those who can't help themselves.\nSet this to a mode and you will be unable to change it ingame" )
. getIntValue ( - 1 );
API . addOption ( new OptionCycled ( "inventory.cheatmode" , 3 ) {
2023-01-28 17:55:51 -08:00
2014-04-29 10:54:20 +10:00
@Override
public boolean optionValid ( int index ) {
return getLockedMode () == - 1 || getLockedMode () == index && NEIInfo . isValidMode ( index );
}
});
2024-10-02 17:21:50 +02:00
canChangeCheatMode ();
2014-04-29 10:54:20 +10:00
tag . getTag ( "inventory.utilities" ). setDefaultValue ( "delete, magnet" );
API . addOption ( new OptionUtilities ( "inventory.utilities" ));
tag . getTag ( "inventory.gamemodes" ). setDefaultValue ( "creative, creative+, adventure" );
API . addOption ( new OptionGamemodes ( "inventory.gamemodes" ));
2014-06-29 20:31:37 +10:00
ItemSorter . initConfig ( tag );
2024-10-13 23:00:06 +03:00
setInventorySearchDefaults ( tag );
2024-08-29 08:17:00 +02:00
2024-08-17 23:24:27 +03:00
tag . getTag ( "inventory.bookmarks.enabled" ). setComment ( "Enable/Disable Bookmark Panel" ). getBooleanValue ( true );
API . addOption ( new OptionToggleButton ( "inventory.bookmarks.enabled" , true ));
tag . getTag ( "inventory.bookmarks.worldSpecific" ). setComment ( "Global or world specific bookmarks" )
. getBooleanValue ( false );
API . addOption ( new OptionToggleButton ( "inventory.bookmarks.worldSpecific" , true ) {
@Override
public boolean onClick ( int button ) {
super . onClick ( button );
2024-08-29 23:14:52 +03:00
ItemPanels . bookmarkPanel . load ();
2024-08-17 23:24:27 +03:00
return true ;
}
});
tag . getTag ( "inventory.bookmarks.animation" ). setComment ( "REI Style Animation in Bookmarks" )
. getBooleanValue ( true );
API . addOption ( new OptionToggleButton ( "inventory.bookmarks.animation" , true ));
tag . getTag ( "inventory.bookmarks.recipeTooltipsMode" ). setComment ( "Show recipe tooltips in Bookmarks" )
. getIntValue ( 1 );
API . addOption ( new OptionCycled ( "inventory.bookmarks.recipeTooltipsMode" , 4 , true ));
tag . getTag ( "inventory.bookmarks.showRecipeMarker" ). setComment ( "Show Recipe Marker" ). getBooleanValue ( false );
API . addOption ( new OptionToggleButton ( "inventory.bookmarks.showRecipeMarker" , true ));
tag . getTag ( "inventory.bookmarks.craftingChainDir" ). getIntValue ( 1 );
API . addOption ( new OptionCycled ( "inventory.bookmarks.craftingChainDir" , 2 , true ));
tag . getTag ( "inventory.bookmarks.ignorePotionOverlap" ). setComment ( "Ignore overlap with potion effect HUD" )
. getBooleanValue ( false );
API . addOption ( new OptionToggleButton ( "inventory.bookmarks.ignorePotionOverlap" , true ));
tag . getTag ( "inventory.guirecipe.jeiStyleTabs" ). setComment ( "Enable/disable JEI Style Tabs" )
. getBooleanValue ( true );
API . addOption ( new OptionToggleButtonBoubs ( "inventory.guirecipe.jeiStyleTabs" , true ));
tag . getTag ( "inventory.guirecipe.jeiStyleRecipeCatalyst" ). setComment ( "Enable/disable JEI Style Recipe Catalysts" )
. getBooleanValue ( true );
API . addOption ( new OptionToggleButton ( "inventory.guirecipe.jeiStyleRecipeCatalyst" , true ));
tag . getTag ( "inventory.guirecipe.jeiStyleCycledIngredients" ). setComment ( "JEI styled cycled ingredients" )
. getBooleanValue ( true );
API . addOption ( new OptionToggleButton ( "inventory.guirecipe.jeiStyleCycledIngredients" , true ));
tag . getTag ( "inventory.guirecipe.cycledIngredientsTooltip" ). setComment ( "Show cycled ingredients tooltip" )
. getBooleanValue ( true );
API . addOption ( new OptionToggleButton ( "inventory.guirecipe.cycledIngredientsTooltip" , true ));
tag . getTag ( "inventory.guirecipe.creativeTabStyle" ). setComment ( "Creative or JEI style tabs" )
. getBooleanValue ( false );
API . addOption ( new OptionToggleButton ( "inventory.guirecipe.creativeTabStyle" , true ));
tag . getTag ( "inventory.guirecipe.itemPresenceOverlay" ). setComment ( "Item presence overlay on ?-hover" )
. getIntValue ( 1 );
API . addOption ( new OptionCycled ( "inventory.guirecipe.itemPresenceOverlay" , 3 , true ));
tag . getTag ( "inventory.guirecipe.slotHighlightPresent" ). setComment ( "Highlight Present Item" )
. getBooleanValue ( true );
API . addOption ( new OptionToggleButton ( "inventory.guirecipe.slotHighlightPresent" , true ));
tag . getTag ( "inventory.guirecipe.shiftOverlayRecipe" )
. setComment ( "Require holding shift to move items when overlaying recipe" ). getBooleanValue ( true );
API . addOption ( new OptionToggleButton ( "inventory.guirecipe.shiftOverlayRecipe" , true ));
2025-01-16 22:12:26 +02:00
tag . getTag ( "inventory.subsets.enabled" ). setComment ( "Enable/disable Subsets Dropdown" ). getBooleanValue ( true );
API . addOption ( new OptionToggleButton ( "inventory.subsets.enabled" , true ));
tag . getTag ( "inventory.subsets.widgetPosition" ). setComment ( "Subsets Widget Position" ). getBooleanValue ( true );
API . addOption ( new OptionToggleButton ( "inventory.subsets.widgetPosition" , true ));
2024-08-17 23:24:27 +03:00
tag . getTag ( "inventory.guirecipe.profile" ). getBooleanValue ( false );
API . addOption ( new OptionToggleButton ( "inventory.guirecipe.profile" , true ));
2024-02-21 18:12:28 +02:00
tag . getTag ( "inventory.history.enabled" ). setComment ( "Enable/disable History Panel" ). getBooleanValue ( true );
API . addOption ( new OptionToggleButton ( "inventory.history.enabled" , true ));
tag . getTag ( "inventory.history.historyColor" ). setComment ( "Color of the history area display" )
. getHexValue ( 0xee555555 );
2024-12-29 04:36:53 +02:00
API . addOption ( new OptionIntegerField ( "inventory.history.historyColor" , 0 , OptionIntegerField . UNSIGNED_INT_MAX ));
2024-02-21 18:12:28 +02:00
tag . getTag ( "inventory.history.useRows" ). setComment ( "Rows used in historical areas" ). getIntValue ( 2 );
API . addOption ( new OptionIntegerField ( "inventory.history.useRows" , 1 , 5 ));
tag . getTag ( "inventory.history.splittingMode" ). getIntValue ( 1 );
API . addOption ( new OptionCycled ( "inventory.history.splittingMode" , 2 , true ));
2024-07-26 18:44:54 +03:00
tag . getTag ( "inventory.collapsibleItems.enabled" ). getBooleanValue ( true );
API . addOption ( new OptionToggleButton ( "inventory.collapsibleItems.enabled" , true ) {
@Override
public boolean onClick ( int button ) {
2024-08-29 23:14:52 +03:00
super . onClick ( button );
2024-12-05 21:25:17 +02:00
CollapsibleItems . saveStates ();
CollapsibleItems . load ();
2024-07-26 18:44:54 +03:00
LayoutManager . markItemsDirty ();
2024-08-29 23:14:52 +03:00
return true ;
2024-07-26 18:44:54 +03:00
}
});
2024-08-17 23:24:27 +03:00
tag . getTag ( "inventory.collapsibleItems.customName" ). getBooleanValue ( true );
API . addOption ( new OptionToggleButton ( "inventory.collapsibleItems.customName" , true ));
2024-07-26 18:44:54 +03:00
tag . getTag ( "inventory.collapsibleItems.expandedColor" )
. setComment ( "Color of the collapsible item expanded state" ). getHexValue ( 0x335555EE );
2024-12-29 04:36:53 +02:00
API . addOption (
new OptionIntegerField (
"inventory.collapsibleItems.expandedColor" ,
0 ,
OptionIntegerField . UNSIGNED_INT_MAX ));
2024-07-26 18:44:54 +03:00
tag . getTag ( "inventory.collapsibleItems.collapsedColor" )
. setComment ( "Color of the collapsible item collapsed state" ). getHexValue ( 0x335555EE );
2024-12-29 04:36:53 +02:00
API . addOption (
new OptionIntegerField (
"inventory.collapsibleItems.collapsedColor" ,
0 ,
OptionIntegerField . UNSIGNED_INT_MAX ));
2024-07-26 18:44:54 +03:00
2024-08-17 23:24:27 +03:00
tag . getTag ( "inventory.itemzoom.enabled" ). getBooleanValue ( true );
API . addOption ( new OptionToggleButton ( "inventory.itemzoom.enabled" , true ));
tag . getTag ( "inventory.itemzoom.neiOnly" )
. setComment ( "Zoom items only from the JEI ingredient and bookmark list overlays." )
. getBooleanValue ( false );
API . addOption ( new OptionToggleButton ( "inventory.itemzoom.neiOnly" , true ));
tag . getTag ( "inventory.itemzoom.onlySolid" ). getBooleanValue ( false );
API . addOption ( new OptionToggleButton ( "inventory.itemzoom.onlySolid" , true ));
tag . getTag ( "inventory.itemzoom.helpText" )
. setComment ( "Display name \"Item Zoom\" and the hotkey to toggle this mod below the zoomed item." )
. getBooleanValue ( true );
API . addOption ( new OptionToggleButton ( "inventory.itemzoom.helpText" , true ));
tag . getTag ( "inventory.itemzoom.zoom" ). getIntValue ( 500 );
API . addOption ( new OptionIntegerField ( "inventory.itemzoom.zoom" , ItemZoom . MIN_ZOOM , ItemZoom . MAX_ZOOM ));
tag . getTag ( "inventory.itemzoom.showName" ). getBooleanValue ( true );
API . addOption ( new OptionToggleButton ( "inventory.itemzoom.showName" , true ));
tag . getTag ( "inventory.itemzoom.nameColor" ). getHexValue ( 0xFFFFFFFF );
2024-12-29 04:36:53 +02:00
API . addOption ( new OptionIntegerField ( "inventory.itemzoom.nameColor" , 0 , OptionIntegerField . UNSIGNED_INT_MAX ));
2024-08-17 23:24:27 +03:00
2014-04-29 10:54:20 +10:00
tag . getTag ( "inventory.itemIDs" ). getIntValue ( 1 );
API . addOption ( new OptionCycled ( "inventory.itemIDs" , 3 , true ));
tag . getTag ( "world.highlight_tips" ). getBooleanValue ( false );
tag . getTag ( "world.highlight_tips.x" ). getIntValue ( 5000 );
tag . getTag ( "world.highlight_tips.y" ). getIntValue ( 100 );
2014-06-29 20:31:37 +10:00
API . addOption ( new OptionOpenGui ( "world.highlight_tips" , GuiHighlightTips . class ));
2014-04-29 10:54:20 +10:00
2022-05-06 22:41:45 +03:00
tag . getTag ( "world.panels.bookmarks.left" ). getIntValue ( 0 );
tag . getTag ( "world.panels.bookmarks.right" ). getIntValue ( 0 );
tag . getTag ( "world.panels.bookmarks.top" ). getIntValue ( 0 );
tag . getTag ( "world.panels.bookmarks.bottom" ). getIntValue ( 0 );
tag . getTag ( "world.panels.items.left" ). getIntValue ( 0 );
tag . getTag ( "world.panels.items.right" ). getIntValue ( 0 );
tag . getTag ( "world.panels.items.top" ). getIntValue ( 0 );
tag . getTag ( "world.panels.items.bottom" ). getIntValue ( 0 );
API . addOption ( new OptionOpenGui ( "world.panels" , GuiPanelSettings . class ));
2024-07-26 18:44:54 +03:00
API . addOption ( new OptionOpenGui ( "world.presets" , GuiPresetList . class ));
2025-03-13 18:48:25 +01:00
tag . getTag ( "world.overlays.lock" ). getBooleanValue ( true );
API . addOption ( new OptionToggleButton ( "world.overlays.lock" , true ));
2021-04-10 22:42:09 -07:00
tag . getTag ( "inventory.disableMouseScrollTransfer" ). getBooleanValue ( false );
API . addOption ( new OptionToggleButton ( "inventory.disableMouseScrollTransfer" , true ));
tag . getTag ( "inventory.invertMouseScrollTransfer" ). getBooleanValue ( false );
API . addOption ( new OptionToggleButton ( "inventory.invertMouseScrollTransfer" , true ) {
2023-01-28 17:55:51 -08:00
2021-04-10 22:42:09 -07:00
@Override
public boolean isEnabled () {
return isMouseScrollTransferEnabled ();
}
});
2022-05-27 07:42:41 -04:00
2025-01-16 07:23:16 +02:00
tag . getTag ( "inventory.gridRenderingCacheFPS" ). getIntValue ( 8 );
tag . getTag ( "inventory.gridRenderingCacheMode" ). getIntValue ( 0 );
API . addOption ( new OptionCycled ( "inventory.gridRenderingCacheMode" , 3 , true ));
2022-06-24 12:32:13 +01:00
2025-03-24 17:01:41 +02:00
tag . getTag ( "inventory.gridRenderingCacheFPS" ). getIntValue ( 8 );
API . addOption ( new OptionIntegerField ( "inventory.gridRenderingCacheFPS" , 1 , 144 ) {
@Override
public boolean isEnabled () {
return OpenGlHelper . framebufferSupported && getIntSetting ( "inventory.gridRenderingCacheMode" ) == 1 ;
}
});
2025-03-24 16:48:11 +02:00
tag . getTag ( "inventory.hotkeysHelpText" ). getBooleanValue ( true );
API . addOption ( new OptionToggleButton ( "inventory.hotkeysHelpText" , true ));
2025-02-08 20:11:17 +02:00
tag . getTag ( "loadPluginsInParallel" ). getBooleanValue ( true );
2021-10-16 06:07:25 +02:00
tag . getTag ( "itemLoadingTimeout" ). getIntValue ( 500 );
2021-04-10 22:42:09 -07:00
2014-04-29 10:54:20 +10:00
tag . getTag ( "command.creative" ). setDefaultValue ( "/gamemode {0} {1}" );
API . addOption ( new OptionTextField ( "command.creative" ));
2014-06-29 20:31:37 +10:00
tag . getTag ( "command.item" ). setDefaultValue ( "/give {0} {1} {2} {3} {4}" );
2014-04-29 10:54:20 +10:00
API . addOption ( new OptionTextField ( "command.item" ));
tag . getTag ( "command.time" ). setDefaultValue ( "/time set {0}" );
API . addOption ( new OptionTextField ( "command.time" ));
tag . getTag ( "command.rain" ). setDefaultValue ( "/toggledownfall" );
API . addOption ( new OptionTextField ( "command.rain" ));
tag . getTag ( "command.heal" ). setDefaultValue ( "" );
API . addOption ( new OptionTextField ( "command.heal" ));
2021-11-22 05:31:02 +02:00
2022-08-19 15:03:42 +03:00
tag . getTag ( "inventory.showItemQuantityWidget" ). setComment ( "Show Item Quantity Widget" ). getBooleanValue ( true );
API . addOption ( new OptionToggleButton ( "inventory.showItemQuantityWidget" , true ));
2022-10-18 03:59:14 +09:00
tag . getTag ( "inventory.optimize_gui_overlap_computation" ). setComment ( "Optimize computation for GUI overlap" )
. getBooleanValue ( false );
API . addOption ( new OptionToggleButton ( "inventory.optimize_gui_overlap_computation" , true ));
2022-06-24 12:32:13 +01:00
tag . getTag ( "tools.handler_load_from_config" ). setComment ( "ADVANCED: Load handlers from config" )
. getBooleanValue ( false );
2021-03-28 00:12:17 -07:00
API . addOption ( new OptionToggleButton ( "tools.handler_load_from_config" , true ) {
2023-01-28 17:55:51 -08:00
2021-03-28 00:12:17 -07:00
@Override
public boolean onClick ( int button ) {
super . onClick ( button );
GuiRecipeTab . loadHandlerInfo ();
return true ;
}
});
2022-01-31 01:01:12 +09:00
2022-06-24 12:32:13 +01:00
tag . getTag ( "tools.catalyst_load_from_config" ). setComment ( "ADVANCED: Load catalysts from config" )
. getBooleanValue ( false );
2022-01-31 01:01:12 +09:00
API . addOption ( new OptionToggleButton ( "tools.catalyst_load_from_config" , true ) {
2023-01-28 17:55:51 -08:00
2022-01-31 01:01:12 +09:00
@Override
public boolean onClick ( int button ) {
super . onClick ( button );
RecipeCatalysts . loadCatalystInfo ();
return true ;
}
});
2014-04-29 10:54:20 +10:00
setDefaultKeyBindings ();
}
private static void linkOptionList () {
2022-06-24 12:32:13 +01:00
OptionList . setOptionList ( new OptionList ( "nei.options" ) {
2023-01-28 17:55:51 -08:00
2014-07-25 14:45:45 +10:00
@Override
public ConfigSet globalConfigSet () {
return global ;
}
2014-04-29 10:54:20 +10:00
@Override
public ConfigSet worldConfigSet () {
return world ;
}
@Override
2014-07-25 14:45:45 +10:00
public OptionList configBase () {
return this ;
}
@Override
public GuiOptionList getGui ( GuiScreen parent , OptionList list , boolean world ) {
return new GuiNEIOptionList ( parent , list , world );
2014-04-29 10:54:20 +10:00
}
});
}
2024-10-13 23:00:06 +03:00
private static void setInventorySearchDefaults ( ConfigTagParent tag ) {
tag . getTag ( "inventory.search.widgetPosition" ). setComment ( "Widget Position" ). getBooleanValue ( true );
API . addOption ( new OptionToggleButton ( "inventory.search.widgetPosition" , true ));
2025-01-09 09:53:27 +02:00
tag . getTag ( "inventory.search.hideUntilSearching" ). setComment ( "Hide Items Until Searching" )
. getBooleanValue ( false );
API . addOption ( new OptionToggleButton ( "inventory.search.hideUntilSearching" , true ) {
@Override
public boolean onClick ( int button ) {
super . onClick ( button );
ItemList . updateFilter . restart ();
return true ;
}
});
2024-10-13 23:00:06 +03:00
tag . getTag ( "inventory.search.widgetAutofocus" )
. setComment (
"Focus Search Widget on Open, blurs/unfocuses on mouse move unless typing has started first" )
. getIntValue ( 0 );
API . addOption ( new OptionCycled ( "inventory.search.widgetAutofocus" , 3 , true ));
tag . getTag ( "inventory.search.patternMode" ). setComment ( "Search Mode" ). getIntValue ( 1 );
2024-12-17 21:15:41 +02:00
API . addOption ( new OptionCycled ( "inventory.search.patternMode" , 3 , true ) {
@Override
public boolean onClick ( int button ) {
SearchField . searchParser . clearCache ();
return super . onClick ( button );
}
});
2024-10-13 23:00:06 +03:00
tag . getTag ( "inventory.search.quoteDropItemName" ). setComment ( "Quote Drop Item Name" ). getBooleanValue ( true );
API . addOption ( new OptionToggleButton ( "inventory.search.quoteDropItemName" , true ));
tag . getTag ( "inventory.search.format" ). setComment ( "Search Format (true: old format, false: custom format)" )
. getBooleanValue ( false );
API . addOption ( new OptionToggleButton ( "inventory.search.format" , true ) {
@Override
public boolean onClick ( int button ) {
if ( ! super . onClick ( button )) {
return false ;
}
if ( state ()) {
2024-12-23 12:21:28 +02:00
NEIClientConfig . setIntSetting ( "inventory.search.spaceMode" , 1 );
2024-10-13 23:00:06 +03:00
NEIClientConfig . setIntSetting ( "inventory.search.modNameSearchMode" , 0 );
NEIClientConfig . setIntSetting ( "inventory.search.tooltipSearchMode" , 0 );
NEIClientConfig . setIntSetting ( "inventory.search.identifierSearchMode" , 0 );
NEIClientConfig . setIntSetting ( "inventory.search.oreDictSearchMode" , 0 );
NEIClientConfig . setIntSetting ( "inventory.search.subsetsSearchMode" , 1 );
tag . getTag ( "inventory.search.prefixRedefinitions" ). setValue ( "{\"%\": \"@\", \"@\": \"%\"}" );
SearchField . searchParser . prefixRedefinitions . clear ();
SearchField . searchParser . prefixRedefinitions . put ( '%' , '@' );
SearchField . searchParser . prefixRedefinitions . put ( '@' , '%' );
2024-12-17 21:15:41 +02:00
SearchField . searchParser . clearCache ();
2024-10-13 23:00:06 +03:00
} else {
2024-12-23 12:21:28 +02:00
NEIClientConfig . setIntSetting ( "inventory.search.spaceMode" , 0 );
2024-10-13 23:00:06 +03:00
NEIClientConfig . setIntSetting ( "inventory.search.modNameSearchMode" , 1 );
NEIClientConfig . setIntSetting ( "inventory.search.tooltipSearchMode" , 0 );
NEIClientConfig . setIntSetting ( "inventory.search.identifierSearchMode" , 0 );
NEIClientConfig . setIntSetting ( "inventory.search.oreDictSearchMode" , 0 );
NEIClientConfig . setIntSetting ( "inventory.search.subsetsSearchMode" , 1 );
tag . getTag ( "inventory.search.prefixRedefinitions" ). setValue ( "{}" );
SearchField . searchParser . prefixRedefinitions . clear ();
2024-12-17 21:15:41 +02:00
SearchField . searchParser . clearCache ();
2024-10-13 23:00:06 +03:00
}
return true ;
}
});
2024-12-23 12:21:28 +02:00
tag . getTag ( "inventory.search.spaceMode" ). setComment ( "Search Space Rules" ). getIntValue ( 0 );
API . addOption ( new OptionCycled ( "inventory.search.spaceMode" , 3 , true ) {
@Override
public boolean onClick ( int button ) {
// SearchField.searchParser.clearCache();
return super . onClick ( button );
}
@Override
public boolean isEnabled () {
return ! tag . getTag ( "inventory.search.format" ). getBooleanValue ();
}
});
2024-10-13 23:00:06 +03:00
tag . getTag ( "inventory.search.modNameSearchMode" ). setComment ( "Search mode for Mod Names (prefix: @)" )
. getIntValue ( 1 );
API . addOption ( new OptionCycled ( "inventory.search.modNameSearchMode" , 3 , true ) {
2024-12-17 21:15:41 +02:00
@Override
public boolean onClick ( int button ) {
SearchField . searchParser . clearCache ();
return super . onClick ( button );
}
2024-10-13 23:00:06 +03:00
@Override
public String getButtonText () {
return translateN (
name + "." + value (),
EnumChatFormatting . LIGHT_PURPLE
+ String . valueOf ( SearchField . searchParser . getRedefinedPrefix ( '@' )));
}
@Override
public boolean isEnabled () {
return ! tag . getTag ( "inventory.search.format" ). getBooleanValue ();
}
});
tag . getTag ( "inventory.search.tooltipSearchMode" ). setComment ( "Search mode for Tooltips (prefix: #)" )
. getIntValue ( 0 );
API . addOption ( new OptionCycled ( "inventory.search.tooltipSearchMode" , 3 , true ) {
2024-12-17 21:15:41 +02:00
@Override
public boolean onClick ( int button ) {
SearchField . searchParser . clearCache ();
return super . onClick ( button );
}
2024-10-13 23:00:06 +03:00
@Override
public String getButtonText () {
return translateN (
name + "." + value (),
EnumChatFormatting . YELLOW + String . valueOf ( SearchField . searchParser . getRedefinedPrefix ( '#' )));
}
@Override
public boolean isEnabled () {
return ! tag . getTag ( "inventory.search.format" ). getBooleanValue ();
}
});
tag . getTag ( "inventory.search.identifierSearchMode" ). setComment ( "Search mode for identifier (prefix: &)" )
. getIntValue ( 0 );
API . addOption ( new OptionCycled ( "inventory.search.identifierSearchMode" , 3 , true ) {
2024-12-17 21:15:41 +02:00
@Override
public boolean onClick ( int button ) {
SearchField . searchParser . clearCache ();
return super . onClick ( button );
}
2024-10-13 23:00:06 +03:00
@Override
public String getButtonText () {
return translateN (
name + "." + value (),
EnumChatFormatting . GOLD + String . valueOf ( SearchField . searchParser . getRedefinedPrefix ( '&' )));
}
@Override
public boolean isEnabled () {
return ! tag . getTag ( "inventory.search.format" ). getBooleanValue ();
}
});
tag . getTag ( "inventory.search.oreDictSearchMode" ). setComment ( "Search mode for Tag Names (prefix: $)" )
. getIntValue ( 0 );
API . addOption ( new OptionCycled ( "inventory.search.oreDictSearchMode" , 3 , true ) {
2024-12-17 21:15:41 +02:00
@Override
public boolean onClick ( int button ) {
SearchField . searchParser . clearCache ();
return super . onClick ( button );
}
2024-10-13 23:00:06 +03:00
@Override
public String getButtonText () {
return translateN (
name + "." + value (),
EnumChatFormatting . AQUA + String . valueOf ( SearchField . searchParser . getRedefinedPrefix ( '$' )));
}
@Override
public boolean isEnabled () {
return ! tag . getTag ( "inventory.search.format" ). getBooleanValue ();
}
});
tag . getTag ( "inventory.search.subsetsSearchMode" ). setComment ( "Search mode for Item Subsets (prefix: %)" )
. getIntValue ( 1 );
API . addOption ( new OptionCycled ( "inventory.search.subsetsSearchMode" , 3 , true ) {
2024-12-17 21:15:41 +02:00
@Override
public boolean onClick ( int button ) {
SearchField . searchParser . clearCache ();
return super . onClick ( button );
}
2024-10-13 23:00:06 +03:00
@Override
public String getButtonText () {
return translateN (
name + "." + value (),
EnumChatFormatting . DARK_PURPLE
+ String . valueOf ( SearchField . searchParser . getRedefinedPrefix ( '%' )));
}
@Override
public boolean isEnabled () {
return ! tag . getTag ( "inventory.search.format" ). getBooleanValue ();
}
});
String prefixRedefinitions = tag . getTag ( "inventory.search.prefixRedefinitions" ). setComment (
"Redefine search prefixes by providing a char-to-char map (JSON). The keys are the original prefixes, the values the new ones. Example: { \"$\": \"€\", \"#\": \"+\", \"@\": \"°\", \"%\": \"!\" }" )
. getValue ( "{}" );
try {
TypeToken < Map < Character , Character >> typeToken = new TypeToken < Map < Character , Character >> () {
private static final long serialVersionUID = 1L ;
};
Map < Character , Character > charMap = new Gson (). fromJson ( prefixRedefinitions , typeToken . getType ());
SearchField . searchParser . prefixRedefinitions . putAll ( charMap );
} catch ( JsonParseException e ) {
logger . warn ( "Failed to convert prefix redefinitions from JSON to CharToCharMap:" , e );
}
}
2014-04-29 10:54:20 +10:00
private static void setDefaultKeyBindings () {
2022-08-19 15:03:42 +03:00
API . addHashBind ( "gui.recipe" , Keyboard . KEY_R );
API . addHashBind ( "gui.usage" , Keyboard . KEY_U );
2014-04-29 10:54:20 +10:00
API . addKeyBind ( "gui.back" , Keyboard . KEY_BACK );
2022-08-19 15:03:42 +03:00
API . addHashBind ( "gui.enchant" , Keyboard . KEY_X );
API . addHashBind ( "gui.potion" , Keyboard . KEY_P );
2014-04-29 10:54:20 +10:00
API . addKeyBind ( "gui.prev" , Keyboard . KEY_PRIOR );
API . addKeyBind ( "gui.next" , Keyboard . KEY_NEXT );
2020-01-02 21:00:34 -08:00
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 );
2022-08-19 15:03:42 +03:00
API . addHashBind ( "gui.hide" , Keyboard . KEY_O );
API . addHashBind ( "gui.search" , Keyboard . KEY_F );
API . addHashBind ( "gui.bookmark" , Keyboard . KEY_A );
API . addHashBind ( "gui.bookmark_recipe" , Keyboard . KEY_A + NEIClientUtils . SHIFT_HASH );
2024-08-17 23:24:27 +03:00
API . addHashBind ( "gui.remove_recipe" , Keyboard . KEY_A + NEIClientUtils . SHIFT_HASH );
2022-08-19 15:03:42 +03:00
API . addHashBind ( "gui.bookmark_count" , Keyboard . KEY_A + NEIClientUtils . CTRL_HASH );
API . addHashBind (
"gui.bookmark_recipe_count" ,
Keyboard . KEY_A + NEIClientUtils . SHIFT_HASH + NEIClientUtils . CTRL_HASH );
2023-08-07 15:29:05 +02:00
API . addHashBind ( "gui.bookmark_pull_items" , Keyboard . KEY_V );
2024-02-04 14:09:24 +02:00
API . addHashBind ( "gui.bookmark_pull_items_ingredients" , Keyboard . KEY_V + NEIClientUtils . SHIFT_HASH );
2022-08-19 15:03:42 +03:00
API . addHashBind ( "gui.overlay" , Keyboard . KEY_S );
API . addHashBind ( "gui.overlay_use" , Keyboard . KEY_S + NEIClientUtils . SHIFT_HASH );
API . addHashBind ( "gui.overlay_hide" , Keyboard . KEY_S + NEIClientUtils . CTRL_HASH );
API . addHashBind ( "gui.hide_bookmarks" , Keyboard . KEY_B );
2022-09-11 01:35:48 +09:00
API . addKeyBind ( "gui.getprevioussearch" , Keyboard . KEY_UP );
API . addKeyBind ( "gui.getnextsearch" , Keyboard . KEY_DOWN );
2023-02-04 18:35:36 +09:00
API . addHashBind ( "gui.next_tooltip" , Keyboard . KEY_Z );
2022-08-19 15:03:42 +03:00
2024-08-17 23:24:27 +03:00
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 );
2014-04-29 10:54:20 +10:00
API . addKeyBind ( "world.chunkoverlay" , Keyboard . KEY_F9 );
API . addKeyBind ( "world.moboverlay" , Keyboard . KEY_F7 );
API . addKeyBind ( "world.highlight_tips" , Keyboard . KEY_NUMPAD0 );
API . addKeyBind ( "world.dawn" , 0 );
API . addKeyBind ( "world.noon" , 0 );
API . addKeyBind ( "world.dusk" , 0 );
API . addKeyBind ( "world.midnight" , 0 );
API . addKeyBind ( "world.rain" , 0 );
API . addKeyBind ( "world.heal" , 0 );
API . addKeyBind ( "world.creative" , 0 );
2024-02-21 18:12:28 +02:00
API . addHashBind ( "gui.copy_name" , Keyboard . KEY_C + NEIClientUtils . CTRL_HASH );
API . addHashBind ( "gui.copy_oredict" , Keyboard . KEY_D + NEIClientUtils . CTRL_HASH );
2014-04-29 10:54:20 +10:00
}
public static OptionList getOptionList () {
return OptionList . getOptionList ( "nei.options" );
}
2022-01-09 19:05:30 +02:00
public static void loadWorld ( String worldPath ) {
2024-08-29 23:14:52 +03:00
unloadWorld ();
2025-01-16 22:12:26 +02:00
setInternalEnabled ( true );
2014-04-29 10:54:20 +10:00
2025-01-21 18:50:16 +02:00
if ( ! worldPath . equals ( NEIClientConfig . worldPath )) {
NEIClientConfig . worldPath = worldPath ;
2024-12-31 20:33:21 +02:00
2025-01-21 18:50:16 +02:00
logger . debug ( "Loading " + ( Minecraft . getMinecraft (). isSingleplayer () ? "Local" : "Remote" ) + " World" );
final File specificDir = new File ( CommonUtils . getMinecraftDir (), "saves/NEI/" + worldPath );
final boolean newWorld = ! specificDir . exists ();
2025-01-16 22:12:26 +02:00
2025-01-21 18:50:16 +02:00
if ( newWorld ) {
specificDir . mkdirs ();
}
world = new ConfigSet ( new File ( specificDir , "NEI.dat" ), new ConfigFile ( new File ( specificDir , "NEI.cfg" )));
bootNEI ( ClientUtils . getWorld ());
onWorldLoad ( newWorld );
}
2014-04-29 10:54:20 +10:00
}
2024-08-29 23:14:52 +03:00
public static String getWorldPath () {
return NEIClientConfig . worldPath ;
}
2014-04-29 10:54:20 +10:00
private static void onWorldLoad ( boolean newWorld ) {
2022-06-24 12:32:13 +01:00
world . config . setComment (
"World based configuration of NEI.\nMost of these options can be changed ingame.\nDeleting any element will restore it to it's default value" );
2014-04-29 10:54:20 +10:00
setWorldDefaults ();
creativeInv = new ItemStack [ 54 ] ;
LayoutManager . searchField . setText ( getSearchExpression ());
2025-01-16 22:12:26 +02:00
LayoutManager . quantity . setText ( Integer . toString ( getItemQuantity ()));
2014-04-29 10:54:20 +10:00
2025-01-16 22:12:26 +02:00
if ( newWorld && Minecraft . getMinecraft (). isSingleplayer ()) {
world . config . getTag ( "inventory.cheatmode" )
. setIntValue ( NEIClientUtils . mc (). playerController . isInCreativeMode () ? 2 : 0 );
}
2014-04-29 10:54:20 +10:00
NEIInfo . load ( ClientUtils . getWorld ());
}
private static void setWorldDefaults () {
NBTTagCompound nbt = world . nbt ;
if ( ! nbt . hasKey ( "search" )) nbt . setString ( "search" , "" );
if ( ! nbt . hasKey ( "quantity" )) nbt . setInteger ( "quantity" , 0 );
if ( ! nbt . hasKey ( "validateenchantments" )) nbt . setBoolean ( "validateenchantments" , false );
world . saveNBT ();
}
2024-02-04 14:09:24 +02:00
public static void unloadWorld () {
if ( ItemPanels . bookmarkPanel != null ) {
ItemPanels . bookmarkPanel . saveBookmarks ();
}
2025-01-16 22:12:26 +02:00
SubsetWidget . saveHidden ();
2024-12-05 21:25:17 +02:00
CollapsibleItems . saveStates ();
2024-02-04 14:09:24 +02:00
if ( world != null ) {
world . saveNBT ();
}
}
2024-02-15 09:51:48 -08:00
private static final Map < String , String > keySettings = new HashMap <> ();
2014-04-29 10:54:20 +10:00
public static int getKeyBinding ( String string ) {
2025-01-26 20:59:16 +02:00
final String key = keySettings . computeIfAbsent ( string , s -> "keys." + s );
2024-02-15 09:51:48 -08:00
return getSetting ( key ). getIntValue ( Keyboard . KEY_NONE );
2014-04-29 10:54:20 +10:00
}
public static void setDefaultKeyBinding ( String string , int key ) {
getSetting ( "keys." + string ). getIntValue ( key );
}
2022-08-19 15:03:42 +03:00
public static boolean isKeyHashDown ( String string ) {
final int hash = getKeyBinding ( string );
2025-01-26 20:59:16 +02:00
if ( hash != Keyboard . CHAR_NONE && Keyboard . getEventKeyState ()) {
return KeyManager . keyStates . containsKey ( string ) ? hash == Keyboard . getEventKey ()
: hash == NEIClientUtils . getKeyHash ();
}
return false ;
2022-08-19 15:03:42 +03:00
}
2024-09-01 23:19:12 +03:00
public static String getKeyName ( String keyBind ) {
2025-01-26 20:59:16 +02:00
return getKeyName ( keyBind , 0 );
}
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 );
}
public static String getKeyName ( String keyBind , int meta ) {
2024-09-01 23:19:12 +03:00
final int hash = getKeyBinding ( keyBind );
2023-02-04 18:35:36 +09:00
2024-09-01 23:19:12 +03:00
if ( hash == Keyboard . CHAR_NONE ) {
return null ;
2023-02-04 18:35:36 +09:00
}
2025-01-26 20:59:16 +02:00
return NEIKeyboardUtils . getKeyName ( hash + meta );
2023-02-04 18:35:36 +09:00
}
2014-04-29 10:54:20 +10:00
public static void bootNEI ( World world ) {
2024-12-05 21:25:17 +02:00
if ( ! mainNEIConfigLoaded ) {
// main NEI config loading
ItemInfo . load ( world );
GuiInfo . load ();
RecipeInfo . load ();
HeldItemHandler . load ();
LayoutManager . load ();
NEIController . load ();
BookmarkContainerInfo . load ();
mainNEIConfigLoaded = true ;
new Thread ( "NEI Plugin Loader" ) {
@Override
public void run () {
2025-02-08 20:11:17 +02:00
final Stream < Class <?>> stream = NEIClientConfig . getBooleanSetting ( "loadPluginsInParallel" )
? NEIClientConfig . pluginsList . parallelStream ()
: NEIClientConfig . pluginsList . stream ();
2024-12-05 21:25:17 +02:00
2025-02-08 20:11:17 +02:00
stream . forEach ( clazz -> {
2024-12-05 21:25:17 +02:00
try {
IConfigureNEI config = ( IConfigureNEI ) clazz . getConstructor (). newInstance ();
config . loadConfig ();
NEIModContainer . plugins . add ( config );
logger . debug ( "Loaded {}" , clazz . getName ());
} catch ( Throwable e ) {
logger . error ( "Failed to Load {}" , clazz . getName (), e );
}
});
RecipeCatalysts . loadCatalystInfo ();
2025-01-16 22:12:26 +02:00
ItemPanels . bookmarkPanel . load ();
2024-12-31 20:33:21 +02:00
SubsetWidget . loadHidden ();
2025-01-16 22:12:26 +02:00
CollapsibleItems . load ();
2024-12-05 21:25:17 +02:00
ItemSorter . loadConfig ();
// Set pluginNEIConfigLoaded here before posting the NEIConfigsLoadedEvent. This used to be the
// other way around, but apparently if your modpack includes 800 mods the event poster might not
// return in time and cause issues when loading a world for a second time as configLoaded is still
// false. This may cause issues in case one of the event handler calls the (non-thread-safe) NEI
// API. I don't expect any handler to do this, but who knows what modders have come up with...
pluginNEIConfigLoaded = true ;
MinecraftForge . EVENT_BUS . post ( new NEIConfigsLoadedEvent ());
ItemList . loadItems . restart ();
}
}. start ();
2025-01-16 22:12:26 +02:00
} else {
ItemPanels . bookmarkPanel . load ();
SubsetWidget . loadHidden ();
ItemList . loadItems . restart ();
2024-12-05 21:25:17 +02:00
}
2022-02-06 17:42:11 +02:00
}
2014-04-29 10:54:20 +10:00
public static boolean isWorldSpecific ( String setting ) {
2022-06-24 12:32:13 +01:00
if ( world == null ) return false ;
2014-12-14 14:32:30 +10:00
ConfigTag tag = world . config . getTag ( setting , false );
return tag != null && tag . value != null ;
2014-04-29 10:54:20 +10:00
}
public static ConfigTag getSetting ( String s ) {
return isWorldSpecific ( s ) ? world . config . getTag ( s ) : global . config . getTag ( s );
}
public static boolean getBooleanSetting ( String s ) {
return getSetting ( s ). getBooleanValue ();
}
public static boolean isHidden () {
return ! enabledOverride || getBooleanSetting ( "inventory.hidden" );
}
2022-06-24 12:32:13 +01:00
2021-03-14 12:22:27 -07:00
public static boolean isBookmarkPanelHidden () {
2024-08-17 23:24:27 +03:00
return ! getBooleanSetting ( "inventory.bookmarks.enabled" );
2021-03-20 22:38:46 -07:00
}
2022-06-24 12:32:13 +01:00
2022-09-18 19:08:16 +09:00
public static boolean areBookmarksAnimated () {
2024-08-17 23:24:27 +03:00
return getBooleanSetting ( "inventory.bookmarks.animation" );
2022-09-18 19:08:16 +09:00
}
2024-02-04 14:09:24 +02:00
public static int getRecipeTooltipsMode () {
2024-08-17 23:24:27 +03:00
return getIntSetting ( "inventory.bookmarks.recipeTooltipsMode" );
2023-07-10 17:38:07 +01:00
}
2022-05-06 22:41:45 +03:00
public static boolean showRecipeMarker () {
2024-08-17 23:24:27 +03:00
return getBooleanSetting ( "inventory.bookmarks.showRecipeMarker" );
2022-05-06 22:41:45 +03:00
}
2022-06-24 12:32:13 +01:00
2022-08-19 15:03:42 +03:00
public static boolean showItemQuantityWidget () {
return getBooleanSetting ( "inventory.showItemQuantityWidget" );
}
2025-01-09 09:53:27 +02:00
public static boolean hideItemsUntilSearching () {
return getBooleanSetting ( "inventory.search.hideUntilSearching" );
}
2023-04-01 16:16:18 -05:00
public static boolean isSearchWidgetCentered () {
2024-06-27 18:03:50 +03:00
return getBooleanSetting ( "inventory.search.widgetPosition" );
2023-04-01 16:16:18 -05:00
}
2025-01-16 22:12:26 +02:00
public static boolean showSubsetWidget () {
return getBooleanSetting ( "inventory.subsets.enabled" );
}
public static boolean subsetWidgetOnTop () {
return getBooleanSetting ( "inventory.subsets.widgetPosition" );
}
2024-08-17 23:24:27 +03:00
public static int searchWidgetAutofocus () {
return getIntSetting ( "inventory.search.widgetAutofocus" );
2024-06-11 12:18:49 -06:00
}
2021-03-20 22:38:46 -07:00
public static boolean areJEIStyleTabsVisible () {
2024-08-17 23:24:27 +03:00
return getBooleanSetting ( "inventory.guirecipe.jeiStyleTabs" );
2021-03-14 12:22:27 -07:00
}
2022-06-24 12:32:13 +01:00
2024-02-22 01:26:41 +02:00
public static int itemPresenceOverlay () {
2024-08-17 23:24:27 +03:00
return getIntSetting ( "inventory.guirecipe.itemPresenceOverlay" );
2024-02-22 01:26:41 +02:00
}
public static boolean isSlotHighlightPresent () {
2024-08-17 23:24:27 +03:00
return getBooleanSetting ( "inventory.guirecipe.slotHighlightPresent" );
2021-05-22 18:31:40 +01:00
}
2022-06-24 12:32:13 +01:00
2022-01-22 13:16:28 +09:00
public static boolean areJEIStyleRecipeCatalystsVisible () {
2024-08-17 23:24:27 +03:00
return getBooleanSetting ( "inventory.guirecipe.jeiStyleRecipeCatalyst" );
2022-01-22 13:16:28 +09:00
}
2022-06-24 12:32:13 +01:00
2021-03-22 20:22:00 -07:00
public static boolean useCreativeTabStyle () {
2024-08-17 23:24:27 +03:00
return getBooleanSetting ( "inventory.guirecipe.creativeTabStyle" );
2021-03-22 20:22:00 -07:00
}
2022-06-24 12:32:13 +01:00
2022-05-31 23:38:14 +09:00
public static boolean ignorePotionOverlap () {
2024-08-17 23:24:27 +03:00
return getBooleanSetting ( "inventory.bookmarks.ignorePotionOverlap" );
}
public static int craftingChainDir () {
return getIntSetting ( "inventory.bookmarks.craftingChainDir" );
2022-05-31 23:38:14 +09:00
}
2022-06-24 12:32:13 +01:00
2022-10-18 03:59:14 +09:00
public static boolean optimizeGuiOverlapComputation () {
return getBooleanSetting ( "inventory.optimize_gui_overlap_computation" );
}
2023-02-06 00:57:09 +09:00
public static boolean useJEIStyledCycledIngredients () {
2024-08-17 23:24:27 +03:00
return getBooleanSetting ( "inventory.guirecipe.jeiStyleCycledIngredients" );
}
public static boolean showCycledIngredientsTooltip () {
return getBooleanSetting ( "inventory.guirecipe.cycledIngredientsTooltip" );
2023-02-06 00:57:09 +09:00
}
2023-02-09 19:21:30 +09:00
public static boolean requireShiftForOverlayRecipe () {
2024-08-17 23:24:27 +03:00
return getBooleanSetting ( "inventory.guirecipe.shiftOverlayRecipe" );
2023-02-09 19:21:30 +09:00
}
2014-04-29 10:54:20 +10:00
public static boolean isEnabled () {
return enabledOverride && getBooleanSetting ( "inventory.widgetsenabled" );
}
2022-06-24 12:32:13 +01:00
2023-05-05 21:01:50 +02:00
public static boolean isLoaded () {
2023-05-10 23:55:45 +02:00
return mainNEIConfigLoaded && pluginNEIConfigLoaded ;
2023-05-05 21:01:50 +02:00
}
2021-03-28 00:12:17 -07:00
public static boolean loadHandlersFromJar () {
2021-11-22 05:31:02 +02:00
return ! getBooleanSetting ( "tools.handler_load_from_config" );
2021-03-28 00:12:17 -07:00
}
2022-06-24 12:32:13 +01:00
2022-01-31 01:01:12 +09:00
public static boolean loadCatalystsFromJar () {
return ! getBooleanSetting ( "tools.catalyst_load_from_config" );
}
2014-04-29 10:54:20 +10:00
2024-05-27 20:25:19 +08:00
public static boolean isProfileRecipeEnabled () {
2024-08-17 23:24:27 +03:00
return NEIClientConfig . getBooleanSetting ( "inventory.guirecipe.profile" );
2024-05-27 20:25:19 +08:00
}
2014-04-29 10:54:20 +10:00
public static void setEnabled ( boolean flag ) {
getSetting ( "inventory.widgetsenabled" ). setBooleanValue ( flag );
}
public static int getItemQuantity () {
return world . nbt . getInteger ( "quantity" );
}
public static int getCheatMode () {
return getIntSetting ( "inventory.cheatmode" );
}
2024-10-02 17:21:50 +02:00
public static boolean canChangeCheatMode () {
if ( getLockedMode () != - 1 ) {
setIntSetting ( "inventory.cheatmode" , getLockedMode ());
return false ;
}
return true ;
2014-04-29 10:54:20 +10:00
}
public static int getLockedMode () {
return getIntSetting ( "inventory.lockmode" );
}
public static int getLayoutStyle () {
return getIntSetting ( "inventory.layoutstyle" );
}
public static String getStringSetting ( String s ) {
return getSetting ( s ). getValue ();
}
public static boolean showIDs () {
int i = getIntSetting ( "inventory.itemIDs" );
return i == 2 || ( i == 1 && isEnabled () && ! isHidden ());
}
2022-06-24 12:32:13 +01:00
2021-10-16 06:07:25 +02:00
public static int getItemLoadingTimeout () {
return getIntSetting ( "itemLoadingTimeout" );
}
2014-04-29 10:54:20 +10:00
public static void toggleBooleanSetting ( String setting ) {
ConfigTag tag = getSetting ( setting );
tag . setBooleanValue ( ! tag . getBooleanValue ());
}
public static void cycleSetting ( String setting , int max ) {
ConfigTag tag = getSetting ( setting );
tag . setIntValue (( tag . getIntValue () + 1 ) % max );
}
public static int getIntSetting ( String setting ) {
return getSetting ( setting ). getIntValue ();
}
public static void setIntSetting ( String setting , int val ) {
getSetting ( setting ). setIntValue ( val );
}
public static String getSearchExpression () {
return world . nbt . getString ( "search" );
}
public static void setSearchExpression ( String expression ) {
world . nbt . setString ( "search" , expression );
}
2021-04-10 22:42:09 -07:00
public static boolean isMouseScrollTransferEnabled () {
return ! getBooleanSetting ( "inventory.disableMouseScrollTransfer" );
}
public static boolean shouldInvertMouseScrollTransfer () {
return ! getBooleanSetting ( "inventory.invertMouseScrollTransfer" );
}
2021-11-22 05:31:02 +02:00
2024-02-21 18:12:28 +02:00
public static boolean showHistoryPanelWidget () {
return getBooleanSetting ( "inventory.history.enabled" );
}
2025-01-16 07:23:16 +02:00
public static int getGridRenderingCacheMode () {
return OpenGlHelper . framebufferSupported ? getIntSetting ( "inventory.gridRenderingCacheMode" ) : 0 ;
2022-05-27 07:42:41 -04:00
}
2024-07-26 18:44:54 +03:00
public static boolean enableCollapsibleItems () {
return getBooleanSetting ( "inventory.collapsibleItems.enabled" );
}
2014-04-29 10:54:20 +10:00
public static boolean getMagnetMode () {
return enabledActions . contains ( "magnet" );
}
public static boolean invCreativeMode () {
return enabledActions . contains ( "creative+" ) && canPerformAction ( "creative+" );
}
public static boolean areDamageVariantsShown () {
return hasSMPCounterPart () || getSetting ( "command.item" ). getValue (). contains ( "{3}" );
}
public static boolean hasSMPCounterPart () {
return hasSMPCounterpart ;
}
public static void setHasSMPCounterPart ( boolean flag ) {
hasSMPCounterpart = flag ;
permissableActions . clear ();
bannedBlocks . clear ();
disabledActions . clear ();
enabledActions . clear ();
}
2014-06-29 20:31:37 +10:00
public static boolean canCheatItem ( ItemStack stack ) {
return canPerformAction ( "item" ) && ! bannedBlocks . contains ( stack );
}
2014-04-29 10:54:20 +10:00
public static boolean canPerformAction ( String name ) {
2022-06-24 12:32:13 +01:00
if ( ! isEnabled ()) return false ;
2014-04-29 10:54:20 +10:00
2022-06-24 12:32:13 +01:00
if ( ! modePermitsAction ( name )) return false ;
2014-04-29 10:54:20 +10:00
String base = NEIActions . base ( name );
2022-06-24 12:32:13 +01:00
if ( hasSMPCounterpart ) return permissableActions . contains ( base );
2014-04-29 10:54:20 +10:00
2022-06-24 12:32:13 +01:00
if ( NEIActions . smpRequired ( name )) return false ;
2014-04-29 10:54:20 +10:00
String cmd = getStringSetting ( "command." + base );
2019-12-24 13:37:41 -08:00
return cmd != null && cmd . startsWith ( "/" );
2014-04-29 10:54:20 +10:00
}
private static boolean modePermitsAction ( String name ) {
if ( getCheatMode () == 0 ) return false ;
if ( getCheatMode () == 2 ) return true ;
String [] actions = getStringArrSetting ( "inventory.utilities" );
2022-06-24 12:32:13 +01:00
for ( String action : actions ) if ( action . equalsIgnoreCase ( name )) return true ;
2014-04-29 10:54:20 +10:00
return false ;
}
public static String [] getStringArrSetting ( String s ) {
return getStringSetting ( s ). replace ( " " , "" ). split ( "," );
}
public static void setInternalEnabled ( boolean b ) {
enabledOverride = b ;
}
public static void reloadSaves () {
File saveDir = new File ( CommonUtils . getMinecraftDir (), "saves/NEI/local" );
2022-06-24 12:32:13 +01:00
if ( ! saveDir . exists ()) return ;
2014-04-29 10:54:20 +10:00
List < SaveFormatComparator > saves ;
try {
saves = Minecraft . getMinecraft (). getSaveLoader (). getSaveList ();
} catch ( Exception e ) {
2014-06-29 20:31:37 +10:00
logger . error ( "Error loading saves" , e );
2014-04-29 10:54:20 +10:00
return ;
}
2019-12-30 20:19:16 -08:00
HashSet < String > saveFileNames = new HashSet <> ();
2022-06-24 12:32:13 +01:00
for ( SaveFormatComparator save : saves ) saveFileNames . add ( save . getFileName ());
2014-04-29 10:54:20 +10:00
2014-06-29 20:31:37 +10:00
for ( File file : saveDir . listFiles ())
2022-06-24 12:32:13 +01:00
if ( file . isDirectory () && ! saveFileNames . contains ( file . getName ())) ObfuscationRun . deleteDir ( file , true );
2014-04-29 10:54:20 +10:00
}
}