Compare commits

...
639 Commits
Author SHA1 Message Date
slprime 8e6b31de18 Speed up GUID cache and bookmark recipe lookups (#1119) 2026-11-13 23:25:20 +02:00
DarkShadow44andslprime 1a27b02412 Don't copy stack unless it changed (#1116)
Co-authored-by: slprime <[email protected]>
2026-11-13 01:53:07 +02:00
slprime 0185cd64b1 Optimize GUI overlap scan for item panels (#1118) 2026-11-12 01:35:53 +02:00
slprime fbbeafcd79 Fix WorldClient leak after leaving the world (#1115) 2026-11-10 19:22:17 +02:00
UltraProdigy 9839d1d08f ci: run build and test on release branches 2026-11-09 01:11:38 -05:00
slprime 84d42de15f Make name optional in API.addCollapsibleGroup (#1114) 2026-11-08 18:13:37 +02:00
slprime d04e1c8e83 Add API.addCollapsibleGroup for registering collapsible item groups (#1113) 2026-11-08 17:37:44 +02:00
slprime 514af5669c Rollback fluent setters in PositionedStack added in #1106 (#1110) 2026-11-06 21:26:08 +01:00
slprime 41c2b96c88 Fix NPE in StackInfo.getItemStackWithMinimumDamage for unregistered items (#1109) 2026-11-05 18:19:48 +02:00
slprime 8e1541eab1 Remove creative tab style option for recipe tabs (#1107) 2026-11-04 16:34:56 +02:00
slprime 9411541fd8 Move RecipeTransferRectHandler out of TemplateRecipeHandler and tidy up PositionedStack (#1106) 2026-11-03 20:35:40 +02:00
slprime ae0d6c6108 Add getResultStacks/getAuxiliaryStacks to IRecipeHandler (#1105) 2026-11-03 17:33:07 +02:00
slprime aea4c2866a Stop auto-creating NEI config files, add export buttons instead (#1104) 2026-11-02 22:20:09 +02:00
slprime c1a525594c Fix ConcurrentModificationException when iterating the crafting recipe list (#1103) 2026-11-02 19:38:18 +02:00
slprimeandMartin Robertz afc8a2380b Remove per-world config override (#1094)
Co-authored-by: Martin Robertz <[email protected]>
2026-11-02 18:20:18 +02:00
slprime a0b2430458 Remove hardcoded vanilla block name overrides (#1102) 2026-11-01 21:53:37 +02:00
Armisael5 4dc6be839b Add NEI Recipe Exporting (#1100) 2026-11-01 15:25:25 +02:00
slprime 030795e3c7 Fix NEI plugin loading crash under a SecurityManager (#1099) 2026-10-29 20:59:01 +02:00
slprime 897a22ad17 Run NEI hotkeys before third-party lastKeyTyped handlers (#1097) 2026-10-28 17:37:45 +02:00
5faed21218 Revert missing item count rendering changes from #1044 (#1091)
Co-authored-by: Martin Robertz <[email protected]>
Co-authored-by: slprime <[email protected]>
2026-10-26 00:21:23 +02:00
Worive aa9da2e0a0 Fix NEI initialization aborting while logging plugin errors (#1093) 2026-10-25 17:10:38 +02:00
slprime e9a3a494d5 Add Mouse Binding (#1092) 2026-10-25 02:49:38 +03:00
slprime ebe83f970f Fix group drag between bookmark namespaces (#1090) 2026-10-24 01:09:00 +03:00
slprime ad9beb7f90 Fill crafting grid with one recipe when Ctrl is held (#1089) 2026-10-23 23:44:16 +03:00
slprime 68bdb51c6b Update tree camera and scrollbar dragging every frame (#1087) 2026-10-22 23:58:41 +03:00
slprime e4e1964dec Fix NPE in BookmarksGridSlot when dragging a group across namespaces (#1086) 2026-10-22 16:22:23 +03:00
slprime 560618024f Autocrafting Optimization (#1084) 2026-10-21 01:24:40 +03:00
slprime e2a2d2a9df Batch 9-slice quads in DrawableResource (#1082) 2026-10-19 15:47:52 +03:00
slprime 7163630cb1 Move 9-slice setup into DrawableBuilder (#1081) 2026-10-16 23:18:28 +03:00
RessedandMartin Robertz ab168ad6ba Make StrictIdentifierFilter (<modid:name:meta>) resolve item on first match (#1080)
Co-authored-by: Martin Robertz <[email protected]>
2026-10-16 20:42:59 +03:00
Martin Robertz e13e3483f0 update+deps+bs 2026-10-16 10:20:51 +02:00
slprime de26547b64 Treat item aliases as translation keys (#1079) 2026-10-15 20:19:58 +03:00
slprime c49f8808fd Fix NPE in item panel getMask (#1078) 2026-10-15 18:59:55 +03:00
slprime 1c6cc8b693 Unify hovered recipe lookup into HoveredRecipe (#1076) 2026-10-12 22:03:07 +03:00
slprime 43ae1b613a Add recipe origins to handler debug widget (#1072) 2026-10-12 13:43:22 +03:00
Wilhelm Schuster 402c4325a6 Update java version in GitHub issue template (#1074) 2026-10-11 23:33:54 +02:00
slprime 550e85c456 Fix -@mod and !@mod search syntax in Extended mode (#1071) 2026-10-10 14:58:17 +03:00
slprime 1673079cbb ItemZoom: Add side priority option (#1070) 2026-10-10 14:36:28 +03:00
slprime e6174c446a Add options for vertical line count in chain tooltips (#1068) 2026-10-09 21:14:11 +03:00
slprime 869b4571b0 Add recipe cycle freeze option (#1067) 2026-10-09 19:47:38 +03:00
slprime 35f5400ecb Fix Crafting Tree NPE (#1064) 2026-10-06 19:57:10 +03:00
micvog 1e2801c891 Fix crash when returning to the crafting tree after its bookmark group was removed (#1063) 2026-10-06 19:46:37 +03:00
Ressedandslprime 1b3b495fec Fix crash while dragging bookmark group to another grid (#1062)
Co-authored-by: slprime <[email protected]>
2026-10-05 20:07:52 +03:00
slprime 2844ea35bc Fix Old Handlers Hack (#1061) 2026-10-04 22:07:41 +03:00
slprime c020ecbf1f Add Custom Renderer API for Fluids (#1059) 2026-10-02 01:22:58 +03:00
slprime a105a60a1a Fix Subset Width Calculation (#1058) 2026-10-01 23:16:35 +03:00
slprime 3a4a6734dc Fix NPE on GT fluid display without NBT (#1057) 2026-09-29 22:30:43 +03:00
slprime 11f9194de9 Fix EnderIo Tank (#1056) 2026-09-29 20:00:29 +03:00
slprimeandgithub-actions[bot] a685efb3b7 Recipe Group Optimization (#1054)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2026-09-28 00:19:29 +03:00
danyadevandMartin Robertz 9f3697bb67 fix cycling for fluid permutations (#1048)
Co-authored-by: Martin Robertz <[email protected]>
2026-09-27 18:21:56 +03:00
slprime 18abb880f8 Add widget size to recipe event (#1053) 2026-09-27 14:13:27 +03:00
slprime 5868187410 Save Tree State (#1052) 2026-09-27 11:00:27 +03:00
slprime f84c4ef2bd Rename PositionStack.Fluid to Tank (#1051) 2026-09-27 08:09:52 +03:00
slprime a54c414595 Add Recipe Groups to GuiRecipe (#1049) 2026-09-27 07:39:27 +03:00
slprime 3c472a02cb Add Flowinf Texture to PositionStack (#1047) 2026-09-26 01:06:38 +03:00
slprime 382278bebb Fix Keybinding Category Names (#1046) 2026-09-25 23:36:57 +03:00
slprime 55c9811a2b Fix search autofocus losing the first typed character (#1045) 2026-09-25 22:17:38 +03:00
slprime 0ec87a8b9e Refactoring Chain Tooltip (#1044) 2026-09-25 22:08:15 +03:00
slprime 939845a9ed Add List View to Recipe (#1041) 2026-09-23 00:14:39 +03:00
Martin Robertz c9db437dd1 update+gradle+bs+deps+gitignore
fix curse auto uploader
2026-09-18 00:21:05 +02:00
Jakub b1f20104a6 Publishing (#1039) 2026-09-17 14:09:06 +02:00
AlexandAlex Vermette ab8d5f275f fix(NEIController): Skip MMB on slot click to avoid unecessary conflict with itemstack using it (#1038)
Co-authored-by: Alex Vermette <[email protected]>
2026-09-17 09:16:46 +03:00
slprime 9e87f2b158 Item Craftables Panel Optimization (#1036) 2026-09-14 18:36:58 +03:00
Dream Master ab512d3fd8 update deps 2026-09-14 10:28:02 +02:00
slprime 4a9f17590b Fix Slot Highlighting (#1035) 2026-09-14 08:44:35 +03:00
slprime a845e6c3e5 Registry NEI Fluids in Server (#1033) 2026-09-12 23:41:17 +03:00
Chitak 985 4f3a0826fe ItemFluidDisplay/getSubItems skips the last fluid (#1032) 2026-09-12 22:43:05 +03:00
slprime 6cd7697ca0 Repair Handler Optimization (#1031) 2026-09-12 20:02:52 +03:00
slprime 38dc14eca1 Fix concurrent modification crash in API.hideItem (#1030) 2026-09-11 08:30:49 +03:00
slprime 1fc824410b Change Fluid Amount Limit (#1029) 2026-09-11 08:10:28 +03:00
slprime af6dba1269 Correctly filtering neifluids (#1027) 2026-09-10 22:52:37 +03:00
slprime 2bf5a1cf9f Fix Bookmark Fluid Factor Limit (#1025) 2026-09-09 19:07:19 +03:00
Ranzuandgithub-actions[bot] 2126ec78bc Destroy one pixel and add color localization (#1022)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2026-09-09 13:34:25 +03:00
slprime 5f6209366a Fix Detect Fluid Display (#1021) 2026-09-09 07:06:14 +03:00
JarnexisandMykhailo Balaker f5fc4e704d Add Ukrainian (uk_UA) localization and translate README (#996)
Co-authored-by: Mykhailo Balaker <[email protected]>
2026-09-08 18:52:48 +02:00
slprimeandgithub-actions[bot] 3d6c1c6e19 Implement Bookmark Tree Screen (#1018)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2026-09-08 13:56:58 +03:00
slprime fda7688807 Added fluid support in recipes (#1020) 2026-09-08 13:41:16 +03:00
boubou19andMartin Robertz 3f38e6f39b Various CPU and RAM improvements (#1015)
Co-authored-by: Martin Robertz <[email protected]>
2026-09-03 00:07:25 +03:00
vcwdfca 866b796411 add centerOverlay (#1016) 2026-08-31 19:21:39 +03:00
slprime 7817640d96 Check unknown bookmark group (#1014) 2026-08-26 16:57:07 +03:00
vcwdfcaandslprime bd595f739c Add feature to save history like bookmarks (#1011)
Co-authored-by: slprime <[email protected]>
2026-08-26 13:40:18 +03:00
slprime 4c74a01930 Fix crash when recipe search results change mid-rebuild (#1012) 2026-08-25 09:09:53 +03:00
slprime 6ced1e0604 Fix Fluid Untranslator (#1009) 2026-08-20 22:25:35 +03:00
slprime f8d00a5445 Add Accepts Label (#1007) 2026-08-14 22:41:15 +03:00
Taran Robertsandslprime 75d53b12ca New worlds ignoring global cheatmode (#1003)
Co-authored-by: slprime <[email protected]>
2026-08-14 16:20:31 +03:00
slprime f93d5977ed Fix Autocrafting With GTTools (#1006) 2026-08-14 15:22:35 +03:00
slprimeandgithub-actions[bot] c4f9c54200 Fix Autocrafting Infinity Loop (#1004)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2026-08-14 13:27:42 +03:00
slprime 7d4c8b82ba Add custom render for PositionedStack (#1002) 2026-08-13 21:49:05 +03:00
slprime c6170f9795 Bookmarks: Fix Permutations with different amount (#1000) 2026-08-12 22:45:39 +03:00
Dream Master 5a533c8994 update+gradle+bs+deps 2026-08-11 00:26:14 +07:00
Nikolay S.andslprime d70a47a3a4 Modernize Java code (#997)
Co-authored-by: slprime <[email protected]>
2026-08-10 14:55:40 +03:00
boubou19andgithub-actions[bot] 6c3db443d7 Cache enum .values() (#998)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2026-08-10 07:40:36 +02:00
boubou19 a51836fe9b Optimize updateUnlimitedItems (#995) 2026-08-07 19:05:01 +03:00
slprime 139ca22e51 Fix Untranslator With Broken Item (#993) 2026-08-04 19:43:34 +03:00
slprime 10fc78bdcf Add Recipe Filter syntax tooltip (#992) 2026-08-04 19:18:27 +03: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 <[email protected]>
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 2b28068382 Simplify the keybinding (#982) 2026-07-25 02:14:12 +03: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 <[email protected]>
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 <[email protected]>
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
Martin Robertz a406021f26 deps 2026-06-27 15:15:43 +02:00
slprime 8500ac57eb Persist hidden items by GUID across reloads (#959) 2026-06-27 00:48:39 +03:00
slprime d97123ec13 ItemLoader Refactoring/Optimization (#958) 2026-06-26 21:25:07 +03:00
slprime 434931bfac Fix Loading Items error log (#956) 2026-06-21 00:57:41 +03:00
RanzuandMartin Robertz 860011036b Convert color class (#947)
Co-authored-by: Martin Robertz <[email protected]>
2026-06-16 10:21:20 +02:00
slprime 937c1858a4 Fix Config Option NPE (#951) 2026-06-14 21:14:44 +03:00
slprime 4562ecf087 Fix Broken DisplayName in Untranslator (#949) 2026-06-13 17:46:46 +03:00
slprime d621d5d5bd Fix Autocrefing Permission (#948) 2026-06-13 17:25:07 +03:00
Martin Robertz 3175b316af update+gradle+deps+bs 2026-06-12 23:32:41 +02:00
slprime 61930ac7a8 Add server-controlled autocraft permission (#942) 2026-06-10 18:58:23 +03:00
slprime fcbf1dcade Fix Single Item In Bookmarks With Amount (#941) 2026-06-07 20:22:42 +03:00
slprime 3fa69e826c Guard loadTransferRects against plugin init errors (#939) 2026-05-27 08:26:29 +03:00
31fff21a55 Smart-Fallback & Alchemic Chemistry Set Fix (#935)
Co-authored-by: FFS <FFS@OhFuckOff>
Co-authored-by: slprime <[email protected]>
2026-05-27 02:29:59 +03:00
slprime 2e9ab88692 Fix ItemStack load from NBT with short overflow (#938) 2026-05-27 02:22:47 +03:00
slprime a02d293d44 Fix Recipe Page Area (#932) 2026-05-11 18:47:36 +03:00
sisyphussy 1265113390 Fix mui2 screen capture (#930) 2026-05-07 20:30:52 +03:00
slprime 4ffd614017 GuiRecipe: Add scrollPages Option (#929) 2026-05-07 18:57:15 +03:00
slprime 41554f4c5b Options: fix memory leaks (#928) 2026-05-06 22:36:07 +02:00
slprime 2104184077 GuiInfo: fix memory leaks (#927) 2026-05-06 20:18:35 +02:00
slprime d5f25a4be8 Prevent ConcurrentModificationException while searching for fuels in ItemList (#926) 2026-05-06 19:43:50 +03:00
slprime ccbf94790a Add Horizontal Scroll to Recipe GUI (#924) 2026-05-06 19:31:00 +03:00
slprime 2f4f72a2d6 Fix Filter Loading (#925) 2026-05-06 07:55:49 +03:00
danyadevandslprime f8cec9a78c Much faster recipe dumper (#920)
Co-authored-by: slprime <[email protected]>
2026-04-25 14:58:50 +03:00
Lucaandslprime fb43a662eb Fix StringIndexOutOfBoundsException in FormattedTextField (#922)
Co-authored-by: slprime <[email protected]>
2026-04-25 10:30:32 +00:00
Luca b2e0b8878a Fix bookmark recipe item order being inconsistent (#921) 2026-04-25 13:21:46 +03:00
slprime 374f019103 Fix Autocrafting NPE (#917) 2026-04-14 01:29:26 +03:00
slprime 5dfcff6f30 Rollback PR#913 (#916) 2026-04-13 20:39:15 +03:00
slprime bd17301cb9 Fix Collapsed Recipes in Bookmarks (#915) 2026-04-13 15:41:30 +03:00
lc-1337 96ccd4e109 fix client -> server sync in creative gui (#913) 2026-04-12 14:47:27 +03:00
Kogepan229 b30ca57e68 Don't block slot click if canCheatItem is false (#912) 2026-04-08 18:35:08 +03:00
slprime 8f949bc1d1 Refactor recipe profiler (#911) 2026-04-07 13:10:39 +03:00
slprime d25365942a Fix Repair Handler with broken ItemStack (#910) 2026-04-06 21:35:47 +03:00
slprime eb58e1dabc Improve Recipe Badge (#909) 2026-04-06 20:39:41 +03:00
slprime f4601e7eed Disable badge by default (#907) 2026-04-04 21:12:05 +03:00
slprime ba48806667 Chance tooltip (#906) 2026-04-04 00:03:15 +03:00
Martin Robertz 70c332796a update+deps 2026-04-03 16:34:57 +02:00
slprime bcc25d4369 Fix Collapsed Recipes in Bookmarks (#905) 2026-03-31 20:47:23 +03:00
slprime 10a3109714 Add recipe chance to bookmarks (#903) 2026-03-30 20:36:55 +03:00
koolkrafter5 b60769864f Improve image exporter data dumper (#902) 2026-03-30 08:19:34 +03:00
slprime 6bc899769f Add Reset to Debug Handler (#901) 2026-03-26 22:22:13 +02:00
slprime 0ba14091fb Refactor DebugHandlerWidget (#900) 2026-03-22 14:10:10 +02:00
slprimeandUltraProdigy 6ed0be7961 Add Repair Handler (#899)
Co-authored-by: UltraProdigy <[email protected]>
2026-03-21 15:04:09 +02:00
slprime d40b951cce Fix areStacksSameTypeWithNBT damage check (#896) 2026-03-19 14:43:45 +02:00
slprime ecdf7892ce updateBuildScript (#895) 2026-03-19 09:39:59 +02:00
slprime 1eaaac94bc Fix filtered permutations (#893) 2026-03-18 01:25:27 +02:00
slprime e99167dddb Change calculateBounds (#892) 2026-03-15 22:41:31 +02:00
slprime 34cb0dc43f Set minimum GTNHLib version to 0.9.6 (#891) 2026-03-15 16:07:31 +01:00
slprime acaad4bf91 Fix Favorite Option (#887) 2026-03-09 21:23:22 +02:00
slprime 3de75f4e26 Fix bookmark slot placement logic (#885) 2026-03-08 12:23:18 +02:00
slprime 47497090ea fix glColor4f; disabled generateSingleRecipeFavorites by default (#884) 2026-03-07 16:58:30 +02:00
slprime 8b45a1757f Add Favorite Item Support (#880) 2026-03-07 16:34:41 +02:00
UltraProdigy 2782f8252e Optimize images (#883) 2026-03-07 09:40:11 +01:00
slprime a5538b2566 Always Show Recipe Ingredients Overlay (#878) 2026-03-01 11:38:05 +02:00
slprime a1f324b796 Remove Generated Favorites from Accepts Followings Tooltip (#873) 2026-02-23 09:32:15 +02:00
slprimeandMartin Robertz f3b6be26df Generate Single-Recipe Favorites (#863)
Co-authored-by: Martin Robertz <[email protected]>
2026-02-16 23:14:55 +01:00
slprime 9c764e3682 Restore the 'get infinite items' action (#867) 2026-02-16 18:39:17 +02:00
slprime 08605c3d73 Removed GTNHLib from required dependency (#866) 2026-02-16 04:37:20 -05:00
slprime 9ec1e0f0cd Change Bookmarks Panel Width (#862) 2026-02-10 19:41:28 +02:00
UltraProdigy e61151186c Exclude Duplicates (#860) 2026-02-09 23:05:15 +01:00
Martin Robertz f7787a9a22 update gradle + deps + bs 2026-02-09 22:32:25 +01:00
slprimeandUltraProdigy a91083bb5a Fix Pull Bookmarked Items (#857)
Co-authored-by: UltraProdigy <[email protected]>
2026-02-09 21:29:07 +00:00
slprimeandUltraProdigy 51f830bdf6 Reset item panel page on search result size change (#855)
Co-authored-by: UltraProdigy <[email protected]>
2026-02-09 16:18:22 -05:00
slprime 9326ac48ad Align panels from center to edges (#856) 2026-02-09 21:11:10 +00:00
c125b71ae0 Added checks for abstract classes when retrieving entities (#833)
Co-authored-by: Martin Robertz <[email protected]>
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2026-02-08 20:49:58 +00:00
Ranzu 805b90d6f8 Add debug text localization and tooltips (#854) 2026-02-03 17:58:20 +02:00
RanzuandMartin Robertz 900b9f90e7 Added show all handlers and recipes function (#852)
Co-authored-by: Martin Robertz <[email protected]>
2026-02-03 15:38:35 +02:00
Ranzuandslprime 06d4a96c3a Add texture for toggled state of magnet button (#849)
Co-authored-by: slprime <[email protected]>
2026-01-26 20:15:10 +02:00
sbwaz 9a5a4a77ef [Extended+] Quote in extended+ depending on "Quote Drop Item Name" NEI option (#848) 2026-01-26 20:08:27 +02:00
Connor-ColensoandConnor Colenso 4d874ec910 Format number centralisation (#846)
Co-authored-by: Connor Colenso <colen@CONNORSPC>
2026-01-23 20:51:38 -05:00
slprime 7f0f2466a5 Fix Information Handler Background Padding (#843) 2026-01-19 13:13:14 +02:00
slprime 83e1966ff2 Fix Recipe Handlers Padding (#842) 2026-01-19 07:47:05 +01:00
slprime 548f754823 Fix Autocrafting for recipe without ingredients in bookmarks (#841) 2026-01-19 07:46:46 +01:00
slprime e036fd14a8 Correctly crop colored text (#839) 2026-01-13 15:16:09 +02:00
slprime 463f4c9b60 Fix transparency border (#838) 2026-01-13 13:06:59 +02:00
Ranzu 5070fde640 Added optional subset label localization (#836) 2026-01-06 03:02:38 +02:00
454b4f7e1d Added Transparency Border to recipe-background and catalyst-tab (#822)
Co-authored-by: Martin Robertz <[email protected]>
Co-authored-by: slprime <[email protected]>
2025-12-28 15:40:21 +01:00
7b83456f01 Add tooltip for "Required Crafts" with shift (#810)
Co-authored-by: Wilhelm Schuster <[email protected]>
Co-authored-by: Martin Robertz <[email protected]>
Co-authored-by: slprime <[email protected]>
2025-12-28 15:36:39 +02:00
PLASMAchicken 4b7b84b031 Restore NEIModContainer public plugins field (#829) 2025-12-26 19:31:41 +01:00
slprime 75309b81ec Hide Untranslator Subset when Untranslator disabled (#827) 2025-12-21 13:26:26 +02:00
slprimeandMartin Robertz 24e46bb43e Add the ability to move bookmark groups between namespaces (#803)
Co-authored-by: Martin Robertz <[email protected]>
2025-12-16 23:39:32 +02:00
Alexdoru 2ba0773401 [Memory-opti:fix leak] Fix WorldServer leak in NEIServerConfig (#815) 2025-12-16 19:44:15 +00:00
PLASMAchicken eac913c80c Remove Obsolete Code from ModContainer (#820) 2025-12-13 12:42:40 +02:00
slprime 126f0ea73c Fix missing favorites and incorrect crafting chains for recipes with identical ingredients (#814) 2025-11-25 07:24:30 +01:00
slprimeandMartin Robertz cd4668ec84 Backup bookmarks.ini if loading failed (#798)
Co-authored-by: Martin Robertz <[email protected]>
2025-11-24 08:52:01 +02:00
slprime 7c247dd0d2 Ignore space hotkeys when typing in search bar (#808) 2025-11-24 00:21:24 +02:00
slprime 87b549fab5 Normalize Fluid Packet (#811) 2025-11-16 14:17:56 +02:00
slprimeandMartin Robertz 8ed1f7a043 Properly clears inventory before filling a recipe (#796)
Co-authored-by: Martin Robertz <[email protected]>
2025-11-13 08:19:55 +02:00
slprime f2efa35654 Extend HandlerInfo.Builder interface (#809) 2025-11-08 23:54:35 +02:00
slprime bcef287e71 Fix Permutations for Information Handler (#804) 2025-11-08 09:32:47 +02:00
slprime 7f555f7a7f Add Tooltip for debug option (#805) 2025-11-08 09:27:21 +02:00
slprime 9fd38da205 Correctly collapse recipe (#807) 2025-11-08 09:18:14 +02:00
slprime 2fa5563408 Optimizing cross-dimension loading (#806) 2025-11-08 09:12:40 +02:00
slprimeandMartin Robertz 541c0e2def Add 'Bookmark recipe with count' Option (#776)
Co-authored-by: Martin Robertz <[email protected]>
2025-11-07 19:54:09 +02:00
Martin Robertz ac868097e7 update 2025-11-07 18:32:09 +01:00
slprimeandMartin Robertz 2f0de0b6a8 Add 'Show only favorites' option to the 'Craftables' panel (#800)
Co-authored-by: Martin Robertz <[email protected]>
2025-11-06 17:37:00 +02:00
sisyphussy 32bc29e654 Remove glBlitFramebuffer (#801) 2025-11-06 14:36:30 +02:00
slprimeandMartin Robertz ef8a7d8bd5 Create normalizeRecipeQueryStack (#772)
Co-authored-by: Martin Robertz <[email protected]>
2025-11-05 23:15:45 +02:00
slprimeandMartin Robertz adc5a5df16 Add GuiOverlapSlots for subpanels (#799)
Co-authored-by: Martin Robertz <[email protected]>
2025-11-05 21:55:33 +02:00
slprime a828ff227a Remove try/catch from static block (#797) 2025-11-05 19:08:55 +01:00
slprime 9b6f98330e Remove Permutations from Output (#777) 2025-11-05 19:14:48 +02:00
slprime 667c8cb5b6 Implement Dynamic Handler Height (#792) 2025-11-05 19:00:09 +02:00
slprimeandMartin Robertz a186f69444 Fix favorite state refresh (#787)
Co-authored-by: Martin Robertz <[email protected]>
2025-11-04 23:11:00 +01:00
slprime 16f4f20239 Fixed small mouse movement while double-clicking causing drop all items (#793) 2025-11-04 23:10:43 +01:00
slprime bac207cacb Change item slot size in GuiRecipe (#789) 2025-11-04 23:10:32 +01:00
slprime 630e856d83 Fix hotkeys when keyBinding disabled (#786) 2025-10-30 10:17:16 +02:00
slprime 42d96aed0c Show 'Delete Item' tooltip in Creative Mode (#785) 2025-10-29 21:47:34 +01:00
slprimeandsisyphussy bd6384bf24 Сalculate the height of the container before scrolling to the recipe (#782)
Co-authored-by: sisyphussy <[email protected]>
2025-10-29 07:52:33 +00:00
slprime af9726d356 Fixed shift+scroll of ingredients in the recipe GUI (#783) 2025-10-29 07:42:18 +00:00
Martin Robertz 1e1d2f1076 update 2025-10-29 07:54:19 +01:00
slprimeandWilhelm Schuster 7cb94fb22a Clear rawText before formatting (#780)
Co-authored-by: Wilhelm Schuster <[email protected]>
2025-10-25 15:20:28 +02:00
Martin Robertz 87aa4f9ed5 update 2025-10-25 14:18:58 +02:00
DarkShadow44andMartin Robertz 9760fd3eaf Fix another race condition, affecting IndustrialGrafter (#779)
Co-authored-by: Martin Robertz <[email protected]>
2025-10-25 14:11:49 +02:00
slprime 1054871982 Add Scroll to Recipe Catalysts (#770) 2025-10-21 12:28:14 +00:00
slprime d90a667f68 Fix Bookmarks Chain Tooltip Height (#773) 2025-10-19 21:33:46 +03:00
slprime 69e6df5848 Fix Button Texture (#771) 2025-10-19 19:56:23 +02:00
slprime 25fa7ce44e Add defaultbookmarkcontainers.cfg (#769) 2025-10-19 16:07:45 +03:00
slprime e3cd7b860d Fix recipe result count (#767) 2025-10-18 11:07:39 +00:00
slprime 2a3aabc073 Add recipe index to recipe handler height (#768) 2025-10-18 13:03:08 +02:00
slprimeandMartin Robertz 76db43c835 Optimize permutations (#761)
Co-authored-by: Martin Robertz <[email protected]>
2025-10-17 22:23:10 +03:00
slprimeandMartin Robertz 40e53eea7a Fixing HUD flickering (#762)
Co-authored-by: Martin Robertz <[email protected]>
2025-10-17 21:36:30 +03:00
Martin Robertz 6c4d16d6b9 update 2025-10-17 12:50:52 +02:00
RealSilverMoon 4a2abe9fd7 Add a function to copy item name and meta (#758) 2025-10-17 10:54:47 +03:00
sisyphussy d47417302e Fix recipe tooltip lighting (#757) 2025-10-14 17:09:02 +03:00
e13401ded8 Optimize Bookmark Chains with Containers (#751)
Co-authored-by: Martin Robertz <[email protected]>
Co-authored-by: sisyphussy <[email protected]>
2025-10-13 11:01:58 +00:00
sisyphussy 7ada842ef3 Fix tooltip item lighting (#755) 2025-10-13 00:29:09 +03:00
slprimeandMartin Robertz fe0c5d4e50 Create Recipe Widget; Recipe GUI: Infinity Scroll; Recipe GUI: Max Height Settings (#701)
Co-authored-by: Martin Robertz <[email protected]>
2025-10-12 18:39:21 +02:00
slprime 2ea9ae1eb9 Show Handler Icon in Bookmarks (#747) 2025-10-09 21:22:37 +02:00
slprime f7f0596fda Show Items Loading Message (#745) 2025-10-08 16:58:23 +02:00
sbwaz d5e919a9cd [Extended+] Fix the prefixed sequence parsing. (#741) 2025-10-04 13:19:00 +02:00
sisyphussyandMartin Robertz a0ed5da699 Speedup rendering (#740)
Co-authored-by: Martin Robertz <[email protected]>
2025-10-02 12:53:18 +02:00
Martin Robertz 99fb5a656e update 2025-10-02 12:13:08 +02:00
DarkShadow44 4b663222b1 Force tag compounds to be initialized so doesn't happen concurrently later (#730) 2025-10-02 07:15:28 +02:00
Martin Robertz 3e5d0088bc update 2025-10-01 17:21:16 +02:00
948be399d2 allow the steam furnace multiblock to show up in NEI under furnaces (#702)
Co-authored-by: Martin Robertz <[email protected]>
Co-authored-by: EnderProyects <[email protected]>
2025-09-28 13:39:45 +02:00
DarkShadow44 5f6091924d Add more logging for fuel crash (#736) 2025-09-28 01:02:47 +03:00
Dredonkey c5bd1f897a Fix pressing '2' when hovering crafting output not putting the crafted item(s) in the hotbar (#733) 2025-09-27 10:17:40 +00:00
Julia 61d4b6ab62 Revert "Replace lambda with method reference" (#735) 2025-09-27 03:09:17 -07:00
Julia 791d05d5f5 Support Inline Comments After # (#734) 2025-09-26 18:11:47 -07:00
Mike_be 66001275c4 Remove UXV and MAX biolab from NEI recipe catalysts (#732) 2025-09-26 21:40:03 +02:00
slprime db6b83c906 Try fix Fuels (#729) 2025-09-24 13:17:34 +02:00
slprime 58ef6c85e0 Fix NBT Copy (#728) 2025-09-22 20:28:05 -07:00
Martin Robertz ab0aeef872 update 2025-09-21 21:38:41 +02:00
slprime 23b7c69e2f Fix None hotkeys for java8 (#726) 2025-09-21 19:44:20 +02:00
slprime bb89384493 Fix Bookmarks Shadow Items (#724) 2025-09-18 19:07:51 +02:00
slprime e96e4dfdde Create Item Untranslator (#719) 2025-09-17 12:42:35 +00:00
slprime 0a6a6771d8 Fixed Favorite Recipes in bookmarks for ingredients (#720) 2025-09-15 19:21:52 +02:00
sbwaz c96199a727 [Extended+] Filter permutations on the left. Fail on recipe expression, when not searching a recipe. (#716) 2025-09-13 11:18:29 +02:00
azod ab4ea2cfa1 feat(moboverlay): add chat message (on/off) (#715) 2025-09-11 03:45:06 -03:00
Mike_be b679883d02 Remove old entries which resulted in ghost catalysts (#714) 2025-09-08 20:11:32 +02:00
Worive 0048ef80d0 Fix(MobSpawnOverlay): avoid IOB from checking light value from block outside of world (#711) 2025-09-07 11:03:21 +00:00
slprime 84576aa7a2 Fix Permutation Filter (#712) 2025-09-06 22:32:14 +02:00
Dream Master c5cd5b9e61 update 2025-09-05 16:08:54 +02:00
slprimeandMartin Robertz b1bedcf403 Recipe search improvement (#706)
Co-authored-by: Martin Robertz <[email protected]>
2025-09-04 15:59:51 +02:00
Matthew Bentham bba0a11466 Add missing lang key for favorite keybind (#709) 2025-09-04 13:20:53 +02:00
slprime b80948f2f2 Fix Subset Name (#705) 2025-08-31 18:34:19 +02:00
slprime 28539bbacc Fix Keyboard IndexOutOfBoundsException (#704) 2025-08-31 18:33:59 +02:00
UltraProdigy ec28bdf116 Make EFR Lingering Potion Recipes Visible in NEI (#703) 2025-08-30 09:10:05 -04:00
sbwaz e5d55a9bd8 Advanced search expressions and improved recipe search in a new pattern mode: extended+ (#692) 2025-08-24 14:35:59 +07:00
slprime c1f7489de1 Presets: Custom Subsets Mode (#671) 2025-08-22 12:22:09 +00:00
slprime fa6fd01a3a Add Option to Disable Hotkeys Tooltip (#680) 2025-08-22 12:15:23 +00:00
slprime 453ba6667f Add Favorite Hotkey (#681) 2025-08-22 19:12:42 +07:00
slprime 4e11a45852 Add the ability to create a chain of items with zero (#682) 2025-08-22 12:06:27 +00:00
slprime 95274339a0 Change panel position algorithm (#683) 2025-08-22 12:03:05 +00:00
slprime 31fcd6af51 Crate Craftables Panel (#696) 2025-08-22 11:58:41 +00:00
koolkrafter5 860bc059ca Allow shift+scrolling other stacks in recipes (#698) 2025-08-18 19:57:08 +07:00
koolkrafter5 2fc2152809 Strict Item Identify Format (#697) 2025-08-16 21:11:27 +07:00
slprimeandkoolkrafter5 57e865fc6f Custom Subsets in config; RecipeId Command (#691)
Co-authored-by: koolkrafter5 <[email protected]>
2025-08-16 18:56:59 +07:00
Dream Master 6dcd26a978 update 2025-08-16 18:39:01 +07:00
koolkrafter5 aeb59081d9 Information Handler (#695) 2025-08-16 18:24:40 +07:00
slprime ef8706ae38 Loading items after the player to ensure the hint cache works correctly in some mods (#687) 2025-08-16 07:38:24 +07:00
Dream Master b49d066231 update 2025-08-08 19:05:06 +07:00
slprime 594fbe6f79 Allowed fill crafting grid without all ingredients (#693) 2025-08-06 13:40:52 -04:00
koolkrafter5andEthryan 3edb85b317 Allow handlers to hide the favorite and overlay buttons via IMC (#678)
Co-authored-by: Ethryan <[email protected]>
2025-07-29 20:37:37 +07:00
TotallyNotOndre 5fd0a74363 Add ability to bookmark linked items (#674) 2025-07-26 07:42:34 +07:00
Dream Master 2ae94e94a0 update 2025-07-17 22:31:09 +07:00
TotallyNotOndre fa3adde3e6 Add ability to link Item in chat (#673) 2025-07-17 10:09:43 +07:00
slprime 56941cc45d Correctly used tools in favorites (#670) 2025-07-12 07:44:34 +02:00
slprimeandCaedis cd7d014704 Bookmarks Chains: Use active Item as preferred if exists (#664)
Co-authored-by: Caedis <[email protected]>
2025-07-11 14:36:10 +00:00
slprime 0634466851 Bookmarks Chains: Optimize GTTools (#667) 2025-07-11 14:33:14 +00:00
slprimeandCaedis b87e389132 Bookmarks Hotkeys: optimization thaumcraft recipes (#663)
Co-authored-by: Caedis <[email protected]>
2025-07-11 14:25:15 +00:00
slprimeandCaedis c788a07cf5 Bookmarks Chains Math: fix infinity loop (#662)
Co-authored-by: Caedis <[email protected]>
2025-07-11 16:21:32 +02:00
Martin Robertz 7d4ed91e86 update 2025-07-09 14:43:40 +02:00
slprime ca79cdd3c9 Disable play sound when crafting with gt tools (#659) 2025-07-08 15:41:42 +02:00
slprime 3a0722adc2 Update Bookmark Chain Tooltip Cache (#657) 2025-07-01 05:52:46 -05:00
slprime 77fa3bafd6 Autocrafting Improvement (#655) 2025-06-27 08:32:54 -05:00
Martin Robertz e23e542aac update 2025-06-22 18:27:06 +02:00
slprime 7ec2ad132e Tools in autocrafting (#653) 2025-06-22 17:49:20 +02:00
slprime 7b43826d05 Clear Crafting Grid after autocrafting (#652) 2025-06-20 09:25:02 -05:00
slprime c7a18dd288 Fix Item Tooltip (#651) 2025-06-19 16:22:12 +00:00
slprime 4fb1d7b1d8 Add Autocrafting Option (#649) 2025-06-16 23:30:10 +02:00
AlexdoruandMartin Robertz 081071562f Fix WorldClient leak in ItemModSpawner and ClientHandler (#637)
Co-authored-by: Martin Robertz <[email protected]>
2025-06-15 12:09:55 +02:00
Martin Robertz 81e05dc030 update 2025-06-14 00:08:03 +02:00
slprime efc54fb662 Add Translation to Item Count Details (#647) 2025-06-13 23:46:32 +02:00
slprime 6e75124ea2 Set Minimum Zoom Size (#648) 2025-06-13 23:46:22 +02:00
slprime 2c9f17983a Fix Paged Tooltip with Line Handler (#645) 2025-06-13 23:46:05 +02:00
slprime e0b6d62143 Add Bookmark items with recipe Option (#644) 2025-06-13 23:45:50 +02:00
Martin Robertz 3d5e9aecf0 update 2025-06-08 11:59:07 +02:00
FalsePattern 07cec30f3e allow setOverrideName to remove name overrides (#643) 2025-06-06 14:11:33 +00:00
koolkrafter5 f3add01e74 Too Many (Hidden) Items (#641) 2025-06-03 08:26:44 +02:00
Maya d469fdc90d update 2025-06-01 18:05:04 -06:00
abel1502 763d9b8cd4 Fix Incorrect handleDragNDrop Implementation (#639) 2025-06-01 18:04:55 -06:00
Jason Mitchell 55ccb70c8b Update JarJar detection so it works when jarjar is loaded but rfb is not setup properly. (#636) 2025-05-26 16:49:52 -04:00
2e1c7764b7 Ignore prefix when SearchMode is ALWAYS (#635)
Co-authored-by: Martin Robertz <[email protected]>
Co-authored-by: Maya <[email protected]>
2025-05-26 15:55:37 +00:00
Martin Robertz 9daa9cabb2 update 2025-05-26 08:46:40 +02:00
Jason Mitchell 74dc7c34d9 Don't exclude locals/frames when transforming. (#632) 2025-05-18 17:50:06 -05:00
slprimeandslprime e5f85e32ec Add Settings: Dynamic Font Size (#631)
Co-authored-by: slprime <[email protected]>
2025-05-18 11:18:12 -05:00
Maya 5383e0891a update 2025-05-13 19:14:13 -05:00
slprimeandslprime 6142d4cc6d Subset: Memory Optimization (#626)
Co-authored-by: slprime <[email protected]>
2025-05-13 19:13:17 -05:00
Maya 6aa6b2e6d2 update 2025-05-12 09:46:11 -05:00
koolkrafter5andMaya 29ade6f327 Make the "Accepts following:" tooltip work for otherStacks (#625)
Co-authored-by: Maya <[email protected]>
2025-05-12 14:45:57 +00:00
slprimeandslprime 5ad6095c43 Filtering the input in the ItemQuantityField (#623)
Co-authored-by: slprime <[email protected]>
2025-05-12 09:40:42 -05:00
Martin Robertz 8ae3304861 update 2025-04-25 13:38:04 +02:00
0dc7bc1228 Create Favorites Widget; More hotkeys; More Tooltips; (#617)
Co-authored-by: slprime <[email protected]>
Co-authored-by: Maya <[email protected]>
2025-04-24 17:48:40 +02:00
Maya 19d8b42993 update 2025-04-08 23:53:43 -05:00
Kogepan229 3b7eae67af Add AE2 Cell View handlers (#621) 2025-04-08 23:51:52 -05:00
Glease 64a747e4bd prevent empty pages from being produced (#615) 2025-03-25 15:06:45 +01:00
Martin Robertz 4f60928b61 update 2025-03-24 16:05:00 +01:00
8dba2ff4c1 Add option to adjust FPS rendering of items (#612)
Co-authored-by: slprime <[email protected]>
Co-authored-by: Martin Robertz <[email protected]>
2025-03-24 15:01:41 +00:00
eb40e3b112 Add Hotkeys Widget Settings (#613)
Co-authored-by: slprime <[email protected]>
Co-authored-by: Martin Robertz <[email protected]>
2025-03-24 15:48:11 +01:00
Martin Robertz 98c8981f05 update 2025-03-19 16:45:47 +01:00
Spacebuilder2020 1ed35c8357 Implement Forge Essentials Permission Checking (#611) 2025-03-18 08:15:30 -07:00
Martin Robertz 6249bab886 update 2025-03-14 19:04:03 +01:00
azodandThéo Jacquelin b525760dd3 feature: Overlays Settings GUI (Keep overlays through dimensions) (#610)
Signed-off-by: AzodFR <[email protected]>
Co-authored-by: Théo Jacquelin <[email protected]>
2025-03-13 17:48:25 +00:00
Jason Mitchell 83b4855f5e Use the updated ASMDataTable (with interfaces) when JarJar is present (#608) 2025-03-13 07:04:41 -07:00
Maya 75352caf11 update 2025-02-08 12:14:10 -06:00
475f5811f6 Add loadPluginsInParallel Option (#604)
Co-authored-by: slprime <[email protected]>
Co-authored-by: Maya <[email protected]>
2025-02-08 18:11:17 +00:00
slprimeandslprime 7503e1dfcb Fix NC marker in recipe after fluid pattern terminal (#603)
Co-authored-by: slprime <[email protected]>
2025-02-08 12:08:36 -06:00
Martin Robertz 9d1f475941 update 2025-01-27 08:06:08 +01:00
slprimeandslprime ac50d1b27e Added hotkey utils methods (#599)
Co-authored-by: slprime <[email protected]>
2025-01-26 12:59:16 -06:00
Maya 48934d621f update 2025-01-25 13:17:03 -06:00
slprimeandslprime 0bbb889f39 Change Permutation Filter (#598)
Co-authored-by: slprime <[email protected]>
2025-01-25 13:16:28 -06:00
Martin Robertz af55a6b191 update
(cherry picked from commit bd7e8d05fa)
2025-01-21 17:55:50 +01:00
slprimeandslprime b3e1f23683 Restore Issue 583 (#593)
Co-authored-by: slprime <[email protected]>
2025-01-21 10:50:16 -06:00
slprimeandslprime 39578a4419 Update Render Cache after window resize (#592)
Co-authored-by: slprime <[email protected]>
2025-01-19 11:33:26 -06:00
e3574800c0 Subset Widget Improvement (#577)
Co-authored-by: slprime <[email protected]>
Co-authored-by: Martin Robertz <[email protected]>
Co-authored-by: Caedis <[email protected]>
Co-authored-by: Maya <[email protected]>
2025-01-16 21:12:26 +01:00
Martin Robertz 5cd7556e6a update 2025-01-16 12:44:42 +01:00
80c2cba778 Created Grid Rendering Cache Mode (#573)
Co-authored-by: slprime <[email protected]>
Co-authored-by: Martin Robertz <[email protected]>
Co-authored-by: Caedis <[email protected]>
2025-01-15 23:23:16 -06:00
Glease 31173a1fbd fix memory leak fixes not working for MP (#590)
#258 addresses the memory leak in ItemMobSpawner. Unfortunately the clean up handler is not consistently called on every world unloaded. This PR fixes this issue by moving the call out of that if block
2025-01-10 17:11:52 +08:00
Caedis fd08a93554 Fix NPE in ItemsTooltipLineHandler (#589) 2025-01-10 10:42:23 +02:00
Martin Robertz 4dace1f6e5 update 2025-01-09 21:05:10 +01:00
0c0cf37eb0 Add 'Hide Item List Until Searching' option (#572)
Co-authored-by: slprime <[email protected]>
Co-authored-by: Martin Robertz <[email protected]>
Co-authored-by: Maya <[email protected]>
2025-01-09 07:53:27 +00:00
Chris Stone 3ec4f8dd68 Add mod handlers for mods in Per Fabrica Ad Astra modpack (#587) 2025-01-08 12:30:34 -06:00
lailani-fandlailani-f e0dd6847cb Item List Sort: Ensure access to shared private field is atomic (#584)
Co-authored-by: lailani-f <>
2025-01-04 14:03:53 +00:00
slprimeandslprime 6374c162ba Fixed NEI reload when changing dimension (#583)
Co-authored-by: slprime <[email protected]>
2024-12-31 19:33:21 +01:00
8dd36f1c4a Add RenderTooltipEvent Compat (#574)
Co-authored-by: Martin Robertz <[email protected]>
Co-authored-by: Maya <[email protected]>
2024-12-28 23:00:02 -06:00
4613ade468 Change OptionIntegerField Width (#575)
Co-authored-by: slprime <[email protected]>
Co-authored-by: Maya <[email protected]>
2024-12-29 02:36:53 +00:00
ca7030df72 Add Space Mode Settings to Search (#571)
Co-authored-by: slprime <[email protected]>
Co-authored-by: boubou19 <[email protected]>
2024-12-23 10:21:28 +00:00
Martin Robertz b32f25c2ce update 2024-12-22 11:38:38 +01:00
4be7a30578 Fix Accept Folowing for custom recipe handlers (#570)
Co-authored-by: slprime <[email protected]>
Co-authored-by: Martin Robertz <[email protected]>
2024-12-22 03:01:44 +01:00
Martin Robertz 7ac3e32635 update 2024-12-17 20:36:35 +01:00
Martin Robertz 088d37a11a update 2024-12-17 20:36:29 +01:00
slprime 6a787dd5b7 Clear Search Filter Cache after Change Settings (#569) 2024-12-17 13:15:41 -06:00
c305649b95 Optimize TooltipItemFilter; ItemFilter limited cache (#565)
Co-authored-by: slprime <[email protected]>
Co-authored-by: Martin Robertz <[email protected]>
2024-12-07 15:29:09 +01:00
slprimeandslprime b5d2815eab Fix CME in registerRectsToGuis during plugin loading (#566)
Co-authored-by: slprime <[email protected]>
2024-12-07 10:32:00 +01:00
slprimeandslprime 6049d0e9c3 Fix restoring collapsible items state (#564)
Co-authored-by: slprime <[email protected]>
2024-12-05 20:25:17 +01:00
9288fc4575 Fix Zoom Position in Right Panel (#559)
Co-authored-by: slprime <[email protected]>
Co-authored-by: Ethryan <[email protected]>
2024-12-03 06:52:51 +01:00
Alexdoru ec749ecc8e Fix mob spawners spawning mobs at world 0 0 0 (#563) 2024-12-03 02:39:34 +01:00
Alexdoru 7471a82bca fix the handlerordering.csv being empty when created (#561) 2024-12-01 16:56:02 +01:00
kstvr32 3f3c1791cb Fix handler ordering config (#560) 2024-11-29 20:28:13 +00:00
a0e16835c2 Fix Presets Scroll; Fix Placeholder position in the quantity field; Hide rendering error in chat; (#555)
Co-authored-by: slprime <[email protected]>
Co-authored-by: Martin Robertz <[email protected]>
2024-11-17 16:31:10 +01:00
Martin Robertz e9ce5cf72b update 2024-11-16 15:32:06 +01:00
slprimeandslprime fac011b67e Fix Zoom Position (#554)
Co-authored-by: slprime <[email protected]>
2024-11-15 10:20:32 +01:00
Worive f9c8ac504e Fix typo for cycledIngredientsTooltip.false in English(#553) 2024-11-14 14:27:14 +00:00
Maya f97711a33a add issue templates 2024-11-11 04:43:49 -06:00
kurrycat b2934c4910 replace GL immediate draw with Tessellator calls for chunk bounds rendering (#549) 2024-10-22 09:29:00 +02:00
Dream Master 759ea69c9f update 2024-10-13 22:01:17 +02:00
36a2cafdac Small Fixes (#543)
Co-authored-by: slprime <[email protected]>
Co-authored-by: Martin Robertz <[email protected]>
2024-10-13 22:00:06 +02:00
Maya 6100012f5b Add Helioflare Power Forge (Gorge) to smelting catalysts (#544) 2024-10-13 21:48:11 +02:00
slprimeandslprime 2e5781beb5 fix catalysts in multiblock structure recipes when shown bookmarks recipe tooltip (#542)
Co-authored-by: slprime <[email protected]>
2024-10-06 12:10:05 +02:00
Alexdoru 43918f3bb1 give names to NEI threads (#540) 2024-10-04 21:46:29 +02:00
AtHisF1nestandMarcin Siekierski a41299dfca fix issue #17509 (#539)
Co-authored-by: Marcin Siekierski <[email protected]>
2024-10-02 17:21:50 +02:00
slprimeandslprime ee060b9253 Small Fixes (#536)
* Small Fixes

* fix shift+v

* fix subset zindex

---------

Co-authored-by: slprime <[email protected]>
2024-09-28 18:05:06 +02:00
Jon 82a2273995 Update en_US.lang (#534) 2024-09-15 22:10:18 +02:00
06fadcc362 Try fix Item Render & GuiRecipeHandler (#528)
Co-authored-by: slprime <[email protected]>
Co-authored-by: Martin Robertz <[email protected]>
2024-09-15 16:57:55 +02:00
slprimeandslprime b328fd3db1 Fix DraggedStack in Bookmarks (#527)
Co-authored-by: slprime <[email protected]>
2024-09-12 18:14:00 +02:00
Martin Robertz 9563ebfe5a update 2024-09-07 18:18:02 +02:00
slprimeandslprime d9143c584e Rename GT Classes; Correct show Meta Keys (#525)
Co-authored-by: slprime <[email protected]>
2024-09-07 14:49:46 +02:00
slprimeandslprime 65652e5896 Small fixes & changes (#523)
* fix hotkeys

* code cleanup

* fix recipe tooltip overlay

* search item by original name

* overlay button refactoring

* fix subset filter

* change keyname; issue 524

* cleanup code

* move overlayformat logic

---------

Co-authored-by: slprime <[email protected]>
2024-09-01 22:19:12 +02:00
slprimeandslprime bd5e991a84 NEI Optimization (#519)
* NEI Optimization

* save setting after death

---------

Co-authored-by: slprime <[email protected]>
2024-08-29 22:14:52 +02:00
glowredman 165afa2910 Small Cleanup (#518)
* Deobfuscate parameters

* Fix generics

* Replace deprecated methods

* Add `serialVersionUID`s

* Fix static access

* Add default switch case

* Close OutputStreams

* Fix wrong variable usage

* Explicitly declare exceptions
2024-08-29 20:07:14 +02:00
glowredman 2507634196 Allow any Character to be used as Search-Prefix (#522)
* Allow any character to be used as prefix

* Enable Jabel

* Add back search mode settings and add ingame setting for prefixes

* Implement prefix redefinitions
2024-08-29 08:17:00 +02:00
slprimeandslprime e0171adc65 Show Delete Item Tooltip only in creative (#517)
Co-authored-by: slprime <[email protected]>
2024-08-18 09:27:57 +02:00
72ad8aa2e7 More QOL (#510)
* ItemZoom, hotkeys & more tooltips

* fix tooltips

* fix hover crash to unnamed item

* fix bookmark group with groupIds bigger than 127

---------

Co-authored-by: slprime <[email protected]>
Co-authored-by: Martin Robertz <[email protected]>
2024-08-17 22:24:27 +02:00
Dream Master f0a554bcc1 update 2024-08-08 12:02:41 +07:00
cutiegin 65781a1649 Update ru_RU.lang (#512)
* Update ru_RU.lang

* Update ru_RU.lang
2024-08-08 11:50:46 +07:00
Dream Master 6ad8f05323 update 2024-07-26 22:48:08 +07:00
slprimeandslprime d61a545d9d Collapsibleitems (#506)
* Create Collapsible Items; Presets refactoring

* change lang

* fix preset settings

* fix .top

* fix tooltip

---------

Co-authored-by: slprime <[email protected]>
2024-07-26 22:44:54 +07:00
chochem 1774685af6 improve advanced search defaults (#498) 2024-07-26 22:42:42 +07:00
slprimeandslprime a63a227c3c Add Create Groups Method to Bookmarks (#497)
* Add Create Groups Method to Bookmarks

* fix dnd with empty handleName

---------

Co-authored-by: slprime <[email protected]>
2024-07-26 07:41:15 +07:00
Dream Master 0f115d5439 update 2024-07-08 13:04:31 +07:00
Jason Mitchell 0fad93fb3b Update CCL Dep (#501) 2024-07-03 09:41:26 -07:00
b1a34c761b Create JEI-like Advanced Search (#485)
* Create JEI like Search

* add subfilter

* fix extended search pattern

* fix search crash without prefixes

* fix unicode case in search

* add regexp to extended patternMode

* move autofocus config to seatch widget panel

* code refactoring

* add matching language to searh parser

* fix type

* fix modname search

* clean cache after add new provider

---------

Co-authored-by: slprime <[email protected]>
Co-authored-by: Martin Robertz <[email protected]>
2024-06-27 17:03:50 +02:00
Martin Robertz cc9715d9f2 update 2024-06-18 20:33:08 +02:00
Jason Mitchell be253a00d2 Broaden visibility (#495)
Fixes #473
2024-06-18 20:25:26 +02:00
OvermindDL1 5dde3b2e2f More inventory interaction enhancements - autofocus-quickclose (#493)
* Added option (default on because it just feels so much better) to instantly close the inventory when it was just opened with it when pressing the inventory close key is the first input the screen receives, letting you flash open and close it again as is common when inspecting inventory

* Forgot to add the vanilla survival inventory to the autofocus allowlist defaults (should this be hardcoded instead?)  Added missing loadEnableAutoFocus() call.

* Removed logging entry, added a new autofocus default that tests successful (and it overwrites the vanilla inventory gui so needed anyway for it), shortened config comment.
2024-06-11 20:18:49 +02:00
OvermindDL1andMartin Robertz 8da541460f Added ability to have the NEI search be auto-focused on open. (#492)
* Added open to have the NEI search be auto-focused on open.  It will automatically blue if the mouse is moved before typing anything so immediate 'r' and such use works as expected.

* Added open to have the NEI search be auto-focused on open.  It will automatically blue if the mouse is moved before typing anything so immediate 'r' and such use works as expected.

* Add an allowlist for what classnames to allow the search auto-focus to work on

* sa

* Add `INEIAutoFocusSearchEnable` interface for opting in to autofocus search box by a mod.  Moved the autofocus list from config into a standalone file at the loss of live-updating.

* Remove now-superfluous lang entries for search focus prefix allowlist

* Undo intellij automatic star-imports...

---------

Co-authored-by: Martin Robertz <[email protected]>
2024-06-10 22:19:25 +02:00
Lasm Gratel dc4426d9c9 fix #479 (#483) 2024-05-27 14:25:19 +02:00
Martin Robertz d05a9eafb3 update 2024-05-04 13:54:08 +02:00
Lasm Gratel 5056fe5437 Concurrent recipe profiler (#478)
* concurrent recipe profiler

* eliminate NPE by giving nulls a name
2024-05-04 13:50:56 +02:00
slprimeandslprime 9fd9aad357 Fix Bookmarks DnD (#476)
Co-authored-by: slprime <[email protected]>
2024-04-24 21:25:46 +02:00
Martin Robertz acaead41ee update 2024-04-22 12:51:44 +02:00
D-Cysteine 951f1b0d0d Add Railcraft NEI handlers to height hack (#475) 2024-04-21 21:52:54 +02:00
Martin Robertz daab313288 update 2024-03-21 20:35:30 +01:00
MalTeeez 25eaa492f7 Update icon (#471) 2024-03-21 20:32:17 +01:00
Caedis 1b34b24495 Adjust readability and padding of item panel footer size (#470) 2024-03-07 05:32:08 -06:00
Martin Robertz b9cd48f8f9 Update settings.gradle (#469) 2024-03-07 11:08:51 +01:00
Caedis b2afc8c9e0 Fix history being hidden when search is centered and item quantity bar is disabled (#468) 2024-03-07 11:01:02 +01:00
Martin Robertz dc400ea560 update 2024-03-02 00:30:18 +01:00
slprimeandslprime ea03cfa17d Correctly find the recipeId under mouse when using the search (#465)
* Correctly find the recipeId under mouse when using the search

* optimize

---------

Co-authored-by: slprime <[email protected]>
2024-03-01 19:36:15 +01:00
slprimeandslprime 94676e0934 DnD big ItemStack; Show green slot highlighting overlay (#463)
* DnD big ItemStack; Show green slot highlighting overlay

* change config

* spotless

* remove system.log

* remove system.log

* show formatted stacksize

* fix draw handler foreground

---------

Co-authored-by: slprime <[email protected]>
2024-02-22 00:26:41 +01:00
slprimeandslprime f7ba34c0af Migrate NEI-Utilities (#461)
Co-authored-by: slprime <[email protected]>
2024-02-21 17:12:28 +01:00
Caedis db1fd255bb Slot Highlighting Overlay Option (#458)
* Add option to highlight the entire slot instead of showing an icon for recipe overlay

* Move skip to full slot highlight only
2024-02-19 13:12:01 +01:00
Martin Robertz 94ca7f3134 update 2024-02-15 19:21:14 +01:00
Jason Mitchell dea024173f Less StringBuilder allocation nonsense (#455)
* Less StringBuilder allocation nonsense
2024-02-15 09:51:48 -08:00
Raven Szewczyk af320a6c9f [ci skip] upgraded build system 2024-02-04 20:00:44 +00:00
Martin Robertz dcb10bb79d update bs+deps 2024-02-04 15:08:35 +01:00
Martin Robertz d3b6603d06 update bs+properties
(cherry picked from commit ceae486a31)
2024-02-04 15:08:05 +01:00
slprimeandslprime adf2065305 Create Bookmarks Groups; Search Recipe (#451)
* Create Bookmarks Groups; Search Recipe

* fix crash after DnD; add remove group function

* change hiddenhandler handlerId

* Pull all Bookmarked Items: use groups

* Optimize Chain Algorithm

* remove println

* fix input V in ME terminal

* Add Search Recipe Icon

* fix recipe extra information

* Change Search Recipe Algorithm

* fixed rounding in chain calculation

* fix creating groups for 2-line recipes

* fix fast DnD and recipe tooltip

* Bookmarks Recipe Chains: fluid canner

* Bookmarks Recipe Chains: fluid cell

* Open GuiRecipe: normalizeItemStack

---------

Co-authored-by: slprime <[email protected]>
2024-02-04 13:09:24 +01:00
bombcarandMartin Robertz e30f6a41ad undo dependencies removal, it's loadbearing (#449)
* undo dependencies removal, it's loadbearing

* update bs, dependencies, and settings.gradle

* cleaned too much

* cleaner

---------

Co-authored-by: Martin Robertz <[email protected]>
2024-01-10 00:28:27 +01:00
Martin Robertz b1a45d0305 update bs 2024-01-08 23:13:51 +01:00
Raven Szewczyk 566d1b095d [ci skip] upgraded build system 2024-01-08 21:28:03 +00:00
Caedis f35a92a101 Add chat message to chunk overlay key press (#450)
* Add chat message to chunk overlay key

* spotless
2024-01-08 13:36:16 -06:00
bombcar fdf130f741 Update bs and dependencies (#447)
* Update bs and dependencies

* remove dependencies.info

* updatedate
2024-01-06 16:58:20 +01:00
Martin Robertz 064f31f8db update gradle+bs+deps 2023-12-03 17:10:11 +01:00
slprimeandslprime 9b081ed2a7 fix bookmarks Infinite loop in todo list (#442)
Co-authored-by: slprime <[email protected]>
2023-12-03 17:07:54 +01:00
miozune 2fc2ecf082 Suppress warning for recipe catalyst item from config not being found (#441) 2023-11-09 18:38:50 +09:00
miozune bc7efcfce5 Improve the way catalyst info is loaded via API (#434) 2023-11-08 18:34:14 +09:00
miozune 0c5af2b892 Add method to directly set DrawableResource for HandlerInfo builder (#440) 2023-11-08 18:03:42 +09:00
Martin Robertz 0c61e559ec update bs 2023-11-08 08:19:08 +01:00
miozune b94bd11e64 Move handler info load to LoadCompleteEvent (#439) 2023-11-07 22:44:13 +09:00
miozune 151a9957de Add another method for handler info event (#438) 2023-11-07 22:44:04 +09:00
Nico Spiske b011024164 Fix TiCo Crafting Stations not working with compressed chests (#435)
* [major] fixes compressed chests not working with the tico crafting station

* [minor] comply with review + bs
2023-11-03 17:19:51 +09:00
Martin Robertz 74d98a86f3 update bs 2023-10-30 08:31:09 +01:00
Ryan Nasers bd5946f5bf Fix the case where the bookmark key is the same key that is used to close a GUI. (#433)
* This should fix the case where the bookmark key is the same key that is used to close a GUI

* Spotless
2023-10-30 08:17:53 +01:00
miozune 1647e8765f Fix DefaultStackStringifyHandler not using short for item id (#430) 2023-10-15 16:12:39 +09:00
Martin Robertz 744b2ffc64 update bs 2023-10-14 13:03:15 +02:00
ghostflyby e88348aabf fix non-centered searchfield considering gui space (#429) 2023-10-14 13:02:11 +02:00
Martin Robertz 4766d90db0 missing imports 2023-09-25 00:36:46 +02:00
Martin Robertz 1dc02a3730 sa 2023-09-25 00:35:24 +02:00
Martin Robertz a6a5e19e80 add missing imports 2023-09-25 00:34:42 +02:00
Martin Robertz e9ab2eba9e sa+wci 2023-09-24 23:02:09 +02:00
Martin Robertz 0e3ff1ee06 update bs 2023-09-24 22:37:31 +02:00
ghostflyby 95e9ac3c89 New: scroll on ItemQuantityField (#421) 2023-09-24 13:18:11 +02:00
querns 1ed004e619 Holding ALT now increases bookmark stack increase in increments of output item's stack size (#418) 2023-09-09 09:22:33 +02:00
Nico Spiske 153da523d6 Hide bookmarkItemPulling button if currently opened gui is not supported (#419)
* [minor] hide pullBookmarkedItems button if open container is not supported

* [minor] spotless apply
2023-09-08 07:16:37 +02:00
miozune c732361bbc More readable packet IDs (#417) 2023-09-06 11:05:15 +02:00
miozune bdb206b45d Fix world specific settings on MP being also specific to dimension (#414) 2023-08-18 21:42:20 +02:00
Raven Szewczyk aa44a97f80 Partial fix for the NEI custom diagram in recipe tooltip issue (#413) 2023-08-17 10:36:15 +02:00
Nico Spiske 00c4411ec5 Pull bookmarked items from container to player inventory (#410)
* [major] first potential version for basic chests

* [major] added api to register chest/inventory guis for bookmark item pulling

* [minor] added hotkey to pull all bookmarked items

* [major] finished

* [minor] spotless apply

* [minor] removed bak file

* [minor] function cleanup

* [minor] fixed bookmarks being set to 0

* [minor] little oversight

* [minor] private attribute and curly brackets
2023-08-07 15:29:05 +02:00
miozune 4f23d21d37 Fix recipe tooltip crash with BetterQuesting (#409)
* updateBuildScript

* Fix recipe tooltip crash with BetterQuesting
2023-07-28 13:20:45 +02:00
8569431e1d Recipe tooltip fixes (#402)
* Unconditionally override Minecraft.currentScreen when drawing tooltips

* Fix bad item lighting in recipe tooltips

* Update buildscript

* Fix NEI ignoring handler switching on click

Handlers might call Minecraft#displayGuiScreen and overwrite Minecraft.currentScreen, but the height hack would unconditionally undo this again.

* spotlessApply (#404)

Co-authored-by: GitHub GTNH Actions <>

* Attempt to fix CME when opening recipes immediately after load (#403)

* Rename the internal private class HeightHack->CompatibilityHacks to better reflect the new usage.

* Move trueGui assignment down.

* Fix overlay button y offsets

* Fix wrong recipe tooltip background rendering

* Apply spotless

---------

Co-authored-by: Wilhelm Schuster <[email protected]>
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2023-07-23 08:04:31 +02:00
Wilhelm Schuster 5b9c27e253 Fix potential NPE when calling ItemMobSpawner#loadSpawners. (#405) 2023-07-16 14:29:31 +02:00
Raven Szewczyk d613d06471 Attempt to fix CME when opening recipes immediately after load (#403) 2023-07-16 09:00:35 +01:00
65ffbad491 Show a full recipe widget in item tooltips for bookmarked recipes (#398)
* Update buildscript

* Show a full recipe widget in item tooltips for bookmarked recipes

* Make recipe tooltips configurable and only show in the bookmarks panel

* Fix layout relative to tooltip boxes

* Fix wildcard import

* spotlessApply (#401)

Co-authored-by: GitHub GTNH Actions <>

* Fix handler tooltip offsets for new&legacy handlers

* Fix render order to draw crafting tooltips on top of container manager buttons

* Fix wrong mouse Y half-point calculation

* Allow saving recipes with empty item ingredient lists to bookmarks (e.g. fluid-only)

* Fix waila vs. non-waila tooltip offsets

Co-authored-by: Wilhelm Schuster <[email protected]>

---------

Co-authored-by: Wilhelm Schuster <[email protected]>
2023-07-10 17:38:07 +01:00
Wilhelm Schuster 885609720e Extend height hack for legacy recipe handlers (#395)
* Store heighthackhandlers.cfg as an internal asset instead of an array of strings

Is copied into the config directory upon first launch. Also, comments
are now allowed (only from the beginning of the file).

* Store serialhandlers.cfg as an internal asset instead of an array of strings

Is copied into the config directory upon first launch. Also, comments
are now allowed (only from the beginning of the file).

Removes GTNH-specific code to be replaced with a configuration file.

* Extend the height hack to also cover guiTop and getRecipePosition

Certain legacy recipe handlers hardcode even more of the NEI recipe
screen layout, requiring only the singular recipe handler switcher
widget at the top, whereas this improved NEI moves the recipe pager to
the top as well expecting recipe handler to move down another 16px. One
such mod that breaks is Immersive Engineering. To fix it we move the top
edge of the gui (guiTop) down by 16px so that the old gap calculation
works correctly. This required special handling in getRecipePosition()
and refreshSlots().

* Fix Immersive Engineering recipe handlers

* Fix Ex Nihilo recipe handlers

* Fix Thermal Expansion recipe handlers

These handlers expect only two recipes to be displayed at a time. This can only be fixed through asm AFAICT.
2023-07-08 23:23:19 +02:00
chochemandglowredman bacf246504 Adjust nei overlay to gt oregen changes (#391)
* adjust to oregen changes

* add compat for old worlds

* remove testing debug

* Update buildscript

* Adjust to changed oregenPattern API

* fix fieldname

---------

Co-authored-by: glowredman <[email protected]>
2023-07-04 18:36:35 +02:00
Wilhelm Schuster 1ab3350eb8 Adjust recipe handler scrolling again (#393)
* Update buildscript

* Rework recipe handler tab scrolling again

Move the recipe handler tab scrolling before the handler-specific
scrolling again. This ensures that tab scrolling while hovering over the
tab bar will always be possible, regardless of how a recipe handler
handles scrolling itself. This mostly reverts back to how this feature
was implemented originally with one change: the Shift-scrolling behavior
is moved outside the recipe tabs scroll handler after the recipe
handler-specific scroll handling to prevent this from overwriting any
other behavior.
2023-06-24 12:01:21 +02:00
Wilhelm Schuster f3aa12483d Expand the tooltips for the time manipulation action buttons (#392) 2023-06-15 23:19:57 +02:00
miozune d86c472790 Fix crash with IC2 setItemDamage (#387)
* Ducttape fix for crash with IC2 setItemDamage

* Use Items.feather
2023-06-01 07:20:24 +02:00
Wilhelm Schuster 4124151208 Prevent recipe handler tab scrolling from overwriting recipe handler-specific scrolling (#384)
* Rename variable in GuiRecipeTabs to avoid confusion

Based on feedback in a previous PR review.

* Make sure recipe handler-specific scrolling behavior takes precedence over recipe handler tab scrolling
2023-05-13 17:40:08 +02:00
miozune 68ad800620 Remove handlers for Et Futurum Requiem (#383)
* Update dependencies

* updateBuildScript

* Remove handlers for Et Futurum Requiem
2023-05-13 14:12:22 +02:00
Wilhelm Schuster 2c7207485d Ensure the NEI config is really only initialized once (#381)
bootNEI() is supposed to only be called once during the client's
lifetime. Turns out, if your pack has 800 mods, bootNEI() might be
called a second time before configLoaded is set to true at the end of
the plugin loading thread. This introduces a second variable that is
set at the end of the single threaded portion of bootNEI() so that it
truly can only be called once, but we can still retain the ability to
check if the plugin loading thread has finished.
2023-05-10 23:55:45 +02:00
Wilhelm Schuster e8094794c3 Allow scrolling through recipe handlers (#379)
In addition to scrolling through all recipes of a single handler, you
can now scroll through all the recipe handlers while hovering over the
handler tab bar (or anywhere in the recipe area while holding left
shift).
2023-05-09 21:57:27 +02:00
miozune ad86d8f9c5 Separate logic to get detailed string of fluid amount (#378)
* Separate logic to get detailed string of fluid amount

* updateBuildScript & spotlessApply

* probably better way
2023-05-07 20:10:18 +02:00
Wilhelm Schuster 30c87e9160 Make sure NEI plugins are loaded before processing keybindings (#375)
NEI plugins are initialized in a separate thread. If this takes too long,
the client tick handler might already be running checking the keybindings
in KeyManager while a plugin calls API.addKeyBind() which can lead to a
CME.

Reported in https://github.com/GTNewHorizons/GT-New-Horizons-Modpack/issues/13292
Thanks to @Denostrov for helping me track this down.
2023-05-05 21:01:50 +02:00
chill 5eeb001534 Readme: fix wording (#374) 2023-05-05 12:16:22 +02:00
MalTeeez 962754ee10 Create handlers for Fusion Crafting (DE-), Techguns and some missing NC recipes (#372)
* Add Fusion Crafting catalyst.csv

* Add Fusion Crafter handler.csv

* Add Techguns handlers & some missing NuclearCraft handlers

* Add Techguns catalysts & some missing NuclearCraft catalysts

* Fix typo

* Add heights to handlers and fix typo

* Small height increase

* Group NC catalysts

* Group NC handlers
2023-04-28 08:24:58 +02:00
Jason Mitchell 0e34840c21 More robust IMC handling (#371)
* Complain if IMC adds a handler/catalyst for a handlerID that doesn't exist.

* Look at the right maps this time

* Don't show matches, only misses
2023-04-16 21:22:09 +02:00
CaedisandMartin Robertz a12fadb10d Add option to have the search widget under item panel (#364)
* Add option to have the search widget under item panel

* update bs+sa

* Make heights consistent

---------

Co-authored-by: Martin Robertz <[email protected]>
2023-04-01 23:16:18 +02:00
Raven Szewczyk 9218e233aa Ignore nonstackables in max overlaid recipe count calculation (#365)
* Update buildscript

* Ignore nonstackables in max overlaid recipe count calculation
2023-03-30 21:47:33 +02:00
theOnly1iKnow 23e16abae6 Add handlers of Reikas mods plus fixes (#362)
* Added Handlers for some of Reikas mods aswell as:
 - a fix for the Industrialcraft Fluid/Solid Canning Machine
 - Tiling for all MFR machines with multiple recipes 
 - Added Cyanite Reporcessor from Big Reactors

* Bring metalformer in line with other IC2 machines
2023-03-20 08:30:15 -07:00
theOnly1iKnow b3cb4db9ca Added handlers for Factorization plus a missing MFR handler (#359)
* Added Handlers for Factorization
as well as a missing MFR Handler

* Added three more MFR handlers
2023-03-06 13:10:28 +01:00
Raven Szewczyk 45fea43a4b Fix MissingFileException in <https://github.com/GTNewHorizons/GT-New-Horizons-Modpack/issues/12791> (#360) 2023-03-05 14:11:45 +01:00
miozune 088d9c08a8 Prevent NPE with null value for keybind (#358) 2023-03-03 11:15:13 +01:00
miozune 98547c2bcf Prevent NPE with null overlayHandler (#357) 2023-03-03 11:14:56 +01:00
Raven Szewczyk 02fa633043 Fix mob spawn spots sometimes showing as gray (#355) 2023-03-01 13:39:08 +01:00
r1tsuu 9df6ab0232 MacOS Command key accessibility (#354)
* MacOS Command key accessibility

* MacOS Command key accessibility

* Fixed spotless violation build error

* Fixed RMENU key to RMETA as CTRL on MacOS
2023-02-28 15:53:59 +01:00
Raven Szewczyk 89cc203875 Light/chunk overlay fixes (#353)
* Update buildscript

* Fix mob/chunk overlay rendering at very far x/z coordinates

Closes <https://github.com/GTNewHorizons/GT-New-Horizons-Modpack/issues/12680>

* Use Tesselator for mob spawn overlay drawing for a minor performance boost

* Missed a couple of offsets in the other chunk overlay modes
2023-02-27 13:31:44 +01:00
asdflj 4b247d08a5 add more api (#352) 2023-02-15 11:55:16 +01:00
Midnight145 8ecc8f20d5 add legacy handlers for botania,neiplugins (#349)
* add missing handlers for Blightfall

* update gitignore

* remove trailing commas

* add fluid registry handler

* readd missing quotes
2023-02-13 16:41:32 +00:00
miozune 74b9f8339a Require shift by default for moving items with overlaying recipe (#351) 2023-02-13 07:26:28 +01:00
miozune e20756a196 Don't require holding shift to move items when overlaying recipe (#348)
* updateBuildScript

* Remove redundant public modifier

* Don't require holding shift to move items when overlaying recipe
2023-02-09 11:21:30 +01:00
miozune 6d0f83c499 Make recipe query load all the uncrashed handlers instead of all-or-nothing if one of the handlers crashed (#347)
* Make recipe query load all the uncrashed handlers instead of all-or-nothing if one of the handlers crashed

* better error handling
2023-02-08 08:54:43 +01:00
miozune 8e219c06be Add JEI styled cycle ingredients (#346) 2023-02-05 16:57:09 +01:00
miozune 3fc576b6fc Add more error message for crash with recipe lookup (#345) 2023-02-05 11:27:52 +01:00
miozune 249cb2b308 Allow using hash for tooltip pagination keybind (#344) 2023-02-04 10:35:36 +01:00
miozune e8d8c1994b Add tooltip pagination (#343) 2023-02-03 15:35:03 +01:00
Raven Szewczyk 195b47944f There is no more 1.7.10- in the gha urls (#342) 2023-01-31 19:21:17 +01:00
Raven Szewczyk 3224fdef7d [ci skip] upgraded build system 2023-01-31 09:54:53 +00:00
Raven Szewczyk 46a159d788 Update buildscript, dependencies and modid injection shenanigans 2023-01-30 11:53:56 +00:00
İlker ARICI bd20e00a6e Add Actually Additions Catalysts.csv (#340)
* Actually Additions Catalysts.csv

* Update catalysts.csv

* Update catalysts.csv
2023-01-29 15:56:08 +01:00
İlker ARICI bf06b09d5a Add Actually Additions handlers (#339)
* Update handlers.csv

I have no experience in coding and not sure if this works, but here is my try at adding Actually Additions handlers to NEI

* Update handlers.csv

* Update handlers.csv

* Update handlers.csv

* Update handlers.csv
2023-01-29 15:55:59 +01:00
Jason Mitchell 1b1dd3567a [ci skip] Add git-blame-ignore-revs for spotlessApply 2023-01-28 17:55:51 -08:00
Jason Mitchell f106b5e766 [ci skip] spotlessApply with the new settings 2023-01-28 17:55:51 -08:00
Jason Mitchell f1dea5460a [ci skip] Update buildscript to RetroFuturaGradle 2023-01-28 17:55:49 -08:00
miozune 9b73b94d16 Fix meta id for MAX Bio Lab (#338) 2023-01-28 17:24:57 +01:00
Raven Szewczyk e133afc774 Fix jar resource loading on newer Java versions (still works on 8) (#337) 2023-01-25 20:50:48 +01:00
asdflj 75ff631f16 bookmark item stack size readable conversion (#335) 2023-01-23 10:59:29 +01:00
Raven Szewczyk 6f5d45c4ea Update CodeChicken dependencies (#330) 2023-01-05 12:18:21 +00:00
miozune fb51475bb9 Fix stack size of permutations on PositionedStack (#327) 2022-12-26 19:14:45 +01:00
Jason Mitchell 99ec3a4204 Add cf & modrinth deps (#325)
* Add cf & modrinth deps

* rm jitpack

* Spotless, you are annoying sometimes
2022-12-22 20:58:39 +01:00
miozune 8c4d609e4c Expose some members in GuiContainerManager (#324) 2022-12-21 10:37:43 +01:00
miozune 336c7dc621 Fix inventory desync when closing GuiRecipe (#320) 2022-11-29 18:21:45 +01:00
Yang Xizhi 2130a47f6f fix overlap of ? button (#321) 2022-11-29 11:19:42 +01:00
miozune 73b492b0e3 Add Dangote Distillus to catalyst for distillery (#319) 2022-11-18 07:33:16 +01:00
miozune efa69f31b6 Fix incorrect RecipeCatalysts for naquadah generators (#318) 2022-11-08 07:38:28 +01:00
makamys 95b437e5c9 Only mark item list as dirty if it's actually modified (#316)
Fixes #315
2022-10-23 11:53:29 +02:00
miozune afe3c54c29 Add config to not optimize computation for GUI overlap (#314) 2022-10-17 20:59:14 +02:00
Jason MitchellandGitHub GTNH Actions 2cab09e91b Try/Catch AIOBE - maybe fixes #295 (#312)
* Try/Catch AIOBE - maybe fixes #295

* spotlessApply

Co-authored-by: GitHub GTNH Actions <unknown>
2022-10-17 11:34:06 +02:00
Jason Mitchell 4b4ab434c0 Update buildscript and add CF/Modrinth project IDs 2022-10-15 08:20:59 -07:00
Yang Xizhi 9d108b21f9 fix missing yShift (#309) 2022-10-15 15:40:52 +02:00
slprimeandslprime 2302dac5c0 Bookmarks: save result that has output bigger than 64 (#308)
Co-authored-by: slprime <[email protected]>
2022-10-13 20:49:43 +02:00
slprimeandslprime 7c2fb2df5f fix bookmarks (#307)
Co-authored-by: slprime <[email protected]>
2022-10-13 10:06:08 +02:00
miozune 14aa3728ca Add AE2 Stuff Inscriber to RecipeCatalyst (#306) 2022-10-13 08:50:04 +02:00
Kiwi 66fc2270dd Update zh_CN.lang (#301) 2022-09-24 12:25:39 +02:00
miozune 138d25dbfd Fix incorrect color applied to GuiRecipeCatalyst (#300) 2022-09-19 05:58:46 +02:00
Raven Szewczyk d9191750a7 Update CodeChickenLib (#299) 2022-09-18 23:15:42 +02:00
くぁーりぃ 6d9ec0c0da Backport some of REI bookmark features (#296)
* add placeholder bookmark drop

* add item panel to bookmark panel injection support

* fix outofboundsexception

* fix drag'n drop voids bookmark

* add itemstack moving animation

* implement pop animation

* fix crashes

* disable ItemPanel Animation

* disable pop animation on bookmark load

* spotlessapply

* disable move animation on gui scale

* add config option
2022-09-18 12:08:16 +02:00
くぁーりぃ 617ac0600d Add search history (#294)
* add search history

* spotlessApply

* linkedlist->arraylist
2022-09-10 18:35:48 +02:00
7d7e3b61a6 Fix other mods cannot mixin GuiContainer.java when NEI is loaded (#291)
Co-authored-by: くぁーりぃ <[email protected]>
Co-authored-by: GitHub GTNH Actions <>
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2022-09-05 18:47:51 +08:00
miozune 748695158f Allow using handlerId for handler order (#290) 2022-09-03 10:25:40 +02:00
DrParadox7 a2c037e0c0 Update Handlers (#288)
Updated Handlers and Catalyst for the following:
-Minefactory Reloaded
-GregTech 4
-Nuclearcraft
2022-08-31 17:30:14 +02:00
miozune e93d23e444 Show message while loading itempanel (#286)
* Show message while loading itempanel

* Move to ItemsGrid

* Add bookmark message

* ItemList

* Revert "Add bookmark message"

This reverts commit 030b5ed1ef.

* Item List

* Use Label

* clean
2022-08-31 10:43:22 +02:00
miozune 748cfe3754 Fix crash when itempanel is not initialized yet (#285) 2022-08-28 14:23:11 +02:00
firenoo b64d104d7e README.md: Add some documentation for getting started on development (#283) 2022-08-27 17:19:09 +02:00
miozune 46d90b6923 Show handler order when hovering on tab and shift pressed (#281) 2022-08-26 22:14:08 +02:00
slprime e61120099a Fix DnD Real Item as Ghost (#279) 2022-08-23 21:15:37 +02:00
Yang Xizhi bcb6eb214f fix dead loop when click certain gui with real item (#278)
fix https://github.com/GTNewHorizons/GT-New-Horizons-Modpack/issues/11067
2022-08-23 06:41:34 +01:00
slprimeandVladislav Laetansky 9221434b2e Create ShortcutInputHandler api class (#277)
* Add RecipeItemInputHandler#lastKeyTyped(ItemStack)

* move shortcut to api

* Update src/main/java/codechicken/nei/api/ShortcutInputHandler.java

Co-authored-by: Vladislav Laetansky <[email protected]>

Co-authored-by: Vladislav Laetansky <[email protected]>
2022-08-21 16:33:52 +02:00
slprime 02937061d4 Presets: Open List Fatal & Slot Overlay (#276)
* Presets: Open List Fatal

* fix slot overlay
2022-08-21 11:34:56 +02:00
miozuneGitHub GTNH Actionsgithub-actions[bot]
0e6425295b Catch exception on drawSlotItem (#273)
* Catch exception on drawSlotItem

* updateBuildScript

* updateBuildScript

* spotlessApply

* spotlessApply (#274)

Co-authored-by: miozune <[email protected]>
Co-authored-by: GitHub GTNH Actions <>

* spotlessApply (#275)

Co-authored-by: miozune <[email protected]>
Co-authored-by: GitHub GTNH Actions <>

Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2022-08-20 11:41:22 +02:00
slprime fb9d517f78 Added keyboard shortcuts to NEI And More... (#271)
* Added keyboard shortcuts to NEI

* OptionButton: Add Tooltip to long prefix

* fix formatting

* Tooltip shown when shift is held
2022-08-19 14:03:42 +02:00
miozune 529f4374d6 Add catalysts for large boiler fuel (#270) 2022-08-10 01:43:05 +02:00
miozune 0bf369a996 Purge OpV (#269) 2022-08-03 11:32:22 +07:00
Jason Mitchell 1897dba35a [ci skip] Migrate github actions to GTNH-Actions-Workflows 2022-07-16 10:50:05 -07:00
YannickMG 5bbf275980 Focus the previous recipe if it's still visible when loading usage re… (#263)
* Focus the previous recipe if it's still visible when loading usage recipes.

* Reduced code duplication by extracting getRecipeHandlers

* Moved RecipeHandlerQuery to its own package-private file

* Refactored RecipeHandlerQuery methods

* Saving the current recipe when left clicking a machine's "Recipes" button

* Restored prevScreen so we can restore it with overlay

* Genericized GuiRecipe so that currentHandlers is no longer hidden in subclasses

* Cleaned up overlay handling

* Fixed trivial IDE warnings & bad JavaDoc on files I touched
2022-06-29 20:18:48 +02:00
Raven Szewczyk f7a900e910 Update buildscript & apply automatic formatting rules 2022-06-27 10:23:18 -07:00
slprime a7683b885d Add another bookmark view mode (#261)
* add another bookmark view mode

* enum BookmarkViewMode
2022-06-23 00:03:29 +02:00
glowredman fe4566901a Update handlers and catalysts (#259)
New:
- Ex Astris
- Ex Compressum
- RFTools
- Steves Carts
- Thaumcraft NEI Plugin
- TC NEI Additions
- Bibliocraft
- ComputerCraft

Updated:
- Thermal Expansion
- Project Red
2022-06-08 16:12:47 +02:00
embeddedt de2b2ece69 Fix minor memory leaks (#258)
* Fix memory leak caused by mob spawner items

* Use a weak hash map instead of manually clearing the map

* Clear manager reference to prevent holding a WorldClient reference through the GUI

* Revert "Use a weak hash map instead of manually clearing the map"

This reverts commit 91bb997250.
2022-06-06 17:05:02 +02:00
Kiwiand[Kiwi233] d20a80a77c Update zh_CN.lang (#257)
* Update zh_CN.lang

* Update zh_CN.lang

* Update zh_CN.lang

* Update zh_CN.lang

* Update zh_CN.lang

* Update zh_CN.lang

Co-authored-by: [Kiwi233] <[[email protected]]>
2022-06-04 22:57:15 +02:00
Jerome226 6cced8dea0 Added compat for TFC+, IE and other mods 2022-05-31 21:16:48 -07:00
miozune 68b9453328 Add config to ignore overlap with potion effect HUD (#255) 2022-05-31 16:38:14 +02:00
embeddedt ae21012ea2 Use a proper key implementation for the search cache (#254)
* Use a proper key implementation for the search cache
* Synchronize itemSearchNames accesses to prevent CMEs
* Use a ConcurrentHashMap instead of synchronizing
  This allows multiple threads to read at the same time, which is the more common scenario.
2022-05-29 12:25:39 -07:00
miozune 2b31129ef9 Use OverlayIdentifier for GT4 2022-05-29 11:32:49 -07:00
Raven Szewczyk ba77a63545 Make sure to use utf-8 for bookmark reading as well as writing (#253) 2022-05-27 19:38:54 +02:00
embeddedt 8f7d698e7d Add option to cache item grid rendering (#250)
* Add option to cache item grid rendering

* Fix highlighting for bookmarks

* Tweak GL state slightly

* Fix focus box being in the wrong place

* Fix flickering for one frame when searching

* Prevent potion effects from rendering over NEI slots

Fixes #231

* Invalidate the buffer if `invalidSlotMap` changes

* Clean up imports

* Delay blitting until after the buffer is refreshed

but still avoid waiting for the next frame

* Refactor slot focus logic to handle highlighting multiple slots

* Refresh grid when sorting bookmarks

* Minor code cleanup, fix some more hovering issues

* Remove `slotNeedsOutline`, it is now redundant

* Remove focus parameter from drawItem
2022-05-27 13:42:41 +02:00
glowredman 72d44fd711 Fix AppleCore's reflection
AppleCore accesses `getStackMouseOver` via reflection but it has been moved to the `PanelWidget` class -> the reflection fails
2022-05-16 10:40:12 -07:00
MuXiu1997 d735cc2a38 Use shortcut key to trigger overlay recipe (#248)
* Use shortcut key to trigger overlay recipe

* Add a way to remove overlay renderer

* Change of implementation

* Fix crash
2022-05-16 17:57:00 +02:00
slprimeandSerghei Borovetchi 91e9b2a5ae Panel settings (#240)
* panel settings

* Highlight hidden items; mark item with recipe

* open gui usage with recipeId

* small  changes

* restore gl after draw item

Co-authored-by: Serghei Borovetchi <[email protected]>
2022-05-06 21:41:45 +02:00
miozune 96e4fe55e8 Send chat to player when recipe loading was errored (#241) 2022-05-03 20:42:09 +02:00
miozune 8717df0cbb Fix scrolling recipes when hovering over ingredients changes stack size (#237) 2022-04-28 15:46:01 +02:00
miozune d6a6551561 Allow GuiRecipe to back to general GuiScreen (#236) 2022-04-25 15:31:50 +02:00
Jason Mitchell 995ed24056 Fix catalysts for gt6 2022-04-20 08:19:47 -07:00
Kiwiand[Kiwi233] 2917f2a4c9 Update zh_CN.lang (#235)
* Update zh_CN.lang

* Update zh_CN.lang

* Update zh_CN.lang

* Update zh_CN.lang

* Update zh_CN.lang

Co-authored-by: [Kiwi233] <[[email protected]]>
2022-04-14 20:04:31 +02:00
NoXъ 5b2ff42d4f typo correction, russification (#234) 2022-04-09 18:11:15 +02:00
miozune 6f2782b06e Add way to register catalysts via IMC (#232) 2022-04-08 21:15:24 +02:00
Glease f17bf6e8e2 fix weird cme (#230) 2022-03-12 15:03:44 +01:00
Glease 10ee4d17ef super unlikely NPE fix (#229) 2022-03-12 12:22:17 +01:00
miozune f6acd768f3 Fix not being able to scroll recipes when hovering over ingredients (#228) 2022-03-05 11:05:26 +01:00
miozune 8a5146b672 Workaround for issue where GT++ registers Chemical Plant handler twice 2022-03-03 08:23:55 -08:00
miozune 1632a90d15 Add support for Natura and Campfire Backport (#226) 2022-03-01 11:28:25 +01:00
miozune 269b16a8de Remove uncraftable catalysts 2022-02-17 18:45:51 -08:00
Serghei Borovetchi 1e93f719fe visibility fix 2022-02-17 18:45:26 -08:00
bombcar db6e3d33ca clean up repos 2022-02-11 08:12:11 -08:00
bombcar 991a6dc772 update buildscript, fix mcmod info not displaying 2022-02-11 08:12:11 -08:00
Serghei Borovetchi 5f1ed67a8b create presets module 2022-02-10 08:43:16 -08:00
miozune 49b22e0683 Add more util function 2022-02-10 08:38:02 -08:00
Kiwiand[Kiwi233] 00dacef241 Update zh_CN.lang (#213)
* Update zh_CN.lang

* Update zh_CN.lang

* Update zh_CN.lang

* Update zh_CN.lang

Co-authored-by: [Kiwi233] <[[email protected]]>
2022-02-07 21:42:39 +01:00
miozune c4da6706a5 Move fuel info from tooltip to foreground 2022-02-07 12:39:24 -08:00
Oleg Ivanov f588543b64 Add new chunk overlay mode for gregtech ore regions (#211)
* Add new chunk overlay mode for gregtech ore regions
* Change GregTech existence check to GregTech 5 only
* Add GT-like region shift on negative coords
2022-02-07 12:18:02 -08:00
Socolio f006a93dd5 Add mob overlay cache, optimize mob overlay spawn check 2022-02-07 12:14:26 -08:00
miozune 6609911d96 Add a way to compare NBT leniently (#209)
* Fix itemstack comparator not handling NBT leniently
* add util function to PositionedStack
2022-02-07 12:12:26 -08:00
bombcar 3291dab52d LGPL-3.0 2022-02-07 12:10:36 -08:00
bombcar b31de63fe6 buildscript 2022-02-07 12:10:36 -08:00
bombcar 0cfc3301f6 fix mcmod.info 2022-02-07 12:10:36 -08:00
Mikhail Golikov 837411aa41 Ignore "drop key" presses in slot click handler. 2022-02-01 02:55:14 +09:00
YannickMG ee3d685a14 Code & Javadoc cleanup 2022-01-30 17:48:14 -08:00
YannickMG 47951372cb Made handler tab names customizable
Allow Recipe Handlers to have a different tab name than what's displayed on top of the UI.
2022-01-30 17:48:14 -08:00
miozune 7834d72ecf RecipeCatalyst Enhancements (#199)
* Fix serial handlers not searching catalysts

* Prevent null stack from being added

* Prevent duplicate stack from being added

* Prevent empty handlerID from being added

* Extract code to get modded items

* Use HANDLER_ID_FUNCTION to determine handler's id
This allows mods that don't implement getOverlayIdentifier to work with

* Implement priority

* Fix typo

* Allow catalysts to be loaded from csv
Add IC2 catalysts

* minor cleanup

* Add Avaritia, BM, Forestry

* Log if TransferRects fail

* Implement removing catalyst

* Add placeholder for version controlling

* Add a BUNCH of catalysts

* Add Schematics

* Add more NASA

* Add way to resolve conflict with handlerID
resolve conflict between IC2 Compressor and Mekanism Osmium Compressor

* Add more catalysts

* Add ALL GT catalysts

* Add more

* temporary "fix" for item rendering
reverts 9bbdd7b174

* enable by default

* forgot this one

* Add ability to skip search for catalysts

* resolve some todos
2022-01-30 17:01:12 +01:00
DrParadox7 3ced04b4d3 Updates Handlers
Adds icons for:
-EtFuturum Requiem
-Modular Powersuits
-Metallurgy 4
-Nuclearcraft

Fixes Nuclearcraft's Workspace recipes not displaying correctly
2022-01-27 08:03:21 -08:00
Jason Mitchell 75c02f0357 Adds a few more methods that weren't implemented and at least one that NEI relied on (addFirst was really the only one I found) 2022-01-26 23:34:29 -08:00
Glease 51ea8bba34 Add final modifiers on those handlers fields
Also added an optional asm transformer to catch potential problems
2022-01-26 20:54:04 -08:00
Glease b0c6f358f7 Use copy on write lists for handler lists 2022-01-26 20:54:04 -08:00
miozune c73edaa72e Use String key for RecipeCatalyst instead of IRecipeHandler.class (#197)
* Use String key for RecipeCatalyst instead of IRecipeHandler.class

* deprecate old methods

* delete commented out code
2022-01-22 23:37:54 +01:00
Jason Mitchell caebccc1fd update buildscript again 2022-01-22 09:45:21 -08:00
Jason Mitchell a0c5ea42b9 update buildscript 2022-01-21 22:49:59 -08:00
Jason Mitchell 23d4be06e8 update buildscript 2022-01-21 21:50:17 -08:00
miozune 1e36822fa4 Add RecipeCatalyst system (#195)
* Add RecipeCatalyst system
2022-01-21 20:16:28 -08:00
Jason Mitchell 3ce702343d update buildscript - publish shaded jars properly 2022-01-17 21:46:41 -08:00
Jason Mitchell a3387f0290 update and pin dependencies 2022-01-17 20:27:25 -08:00
Jason Mitchell 116b96f67b maven publish buildscript update 2022-01-17 20:27:25 -08:00
makamys 60fe49d18c Make item loading timeout configurable 2022-01-17 12:39:11 -08:00
slprimeandSerghei Borovetchi cab0aff563 Мove bookmarks.ini (#194)
* move bookmarks.ini

* add world specific bookmarks option

Co-authored-by: Serghei Borovetchi <[email protected]>
2022-01-09 09:05:30 -08:00
slprimeandSerghei Borovetchi 144a37cebb Fix crash with null fluid stack (#193)
* fix crash with null fluid stack

* change minimum stack size in bookmarks

Co-authored-by: Serghei Borovetchi <[email protected]>
2022-01-07 09:06:05 -08:00
Jason Mitchell 2d18dcf42b Small bug fixes 2022-01-04 21:46:46 -08:00
Serghei Borovetchi 5bbcc570f9 fix save last bookmarks set 2022-01-04 09:20:34 -08:00
Serghei Borovetchi 98c9f03e74 d&d to search input; fix giveStack; change grid size 2022-01-03 09:44:33 -08:00
slprimeandSerghei Borovetchi 5dde7cad8b NEI Bookmarks improvements (#188)
* Add bookmarks sets; save items count in bookmarks; change counts in bookmarks; save ingredients in bookmarks; fill fluidcontainers in bookmarks;
* change fill container controls
* fix fill container
* rollback public variables

Co-authored-by: Serghei Borovetchi <[email protected]>
2022-01-02 13:30:54 -08:00
miozune ce17ec8026 Add harvestcraft Garden handler (#187) 2021-12-31 14:49:15 -08:00
Kiwiand[Kiwi233] 63f49a5e4a Update zh_CN.lang (#186)
* Update zh_CN.lang

* Update zh_CN.lang

Co-authored-by: [Kiwi233] <[[email protected]]>
2021-12-30 14:47:30 +01:00
bombcar e2a9d02c4c fix derpendencies.info (#185) 2021-12-26 09:51:14 -08:00
bombcar 6695185c54 Dependencies (#183)
* upgradebuild script
* allow NEI to load without GTNH
2021-12-21 08:36:49 -08:00
Martin Robertz e5b8a4c9c9 ignore bat files 2021-12-11 20:00:21 +01:00
Johann Bernhardt 60d033e879 Update build script and CI (#178) 2021-11-30 15:51:00 +01:00
Jason Mitchell 0310b4177f * Change default max handlers to page to 1
* Add bigger crafting table Handler Info
2021-11-29 21:33:11 -08:00
D-Cysteine 304cc12750 Add regex support for height hack handlers config (#177)
* Make handler height hack configured via regex
2021-11-28 14:25:48 -08:00
Johann Bernhardt a7ca6c8527 Unified build script (#175)
* Update build script
* Update build script to import fix for shadow in dev and sources artifacts
* Update fixed build script to shadow csv dependency in dev jar as well
* Moved jitpack
* Move new files
2021-11-22 08:56:35 -08:00
Jason Mitchell 43b71b1de6 Update build.properties 2021-11-21 19:31:57 -08:00
slprimeandSerghei Borovetchi b6070dd508 Bookmarks Improvements (#174)
* Add Drag&Drop (sorting items) in bookmarks
* save recipes in bookmarks
* Add possibility to extend bookmarks save/restore functions; in future supports GT++ fluids
* change items sorting algorithm
* add NBT support for different bookmarks
* change saving recipe algorithm
* save correct number type in bookmarks.ini

Co-authored-by: Serghei Borovetchi <[email protected]>
2021-11-21 19:31:02 -08:00
Prometheus0000 492c99b8e3 Fix crash (#166)
* Fix server crash
2021-10-18 19:43:19 -04:00
D-Cysteine 4fc368135d Fix height hack and add ordering config (#165)
* Fix height hack and add ordering config

* Use AutoCloseable for height hack

* Address comments
2021-10-16 19:31:43 +02:00
D-Cysteine 58117fa368 Some changes to NEI that are needed by NEI Custom Diagram (#163)
* Add IRecipeHandler support for handling mouse scrollwheel
* Add accessors for handler and recipe indices
* Make Shift+R not be handled as U
* Clean up redundant code
2021-09-30 21:17:14 -07:00
Prometheus0000 db339e94f4 Add yshifts 2021-09-30 21:14:57 -07:00
Jason Mitchell 7126a6d3b0 Bump mod version 2021-09-24 16:46:02 -07:00
D-Cysteine b00f4d1514 Add back in removed unused public methods, which were actually used by some NEI add-ons (#162)
* Fix compatibility with add-ons by re-adding unused public methods
2021-09-24 06:50:34 -07:00
GlodBlock 5b3a255be9 attampt to fix imc (#161)
* attampt to fix imc
2021-09-22 23:38:53 -07:00
Glease 65710c959a Prevent the load of client only classes on dedicated servers 2021-09-15 21:49:58 -07:00
makamys 95ee685b93 Preserve BossStatus#hasColorModifier when rendering spawners
Fixes wither spawner dimming screen (https://github.com/Chicken-Bones/NotEnoughItems/issues/80)
2021-09-14 12:01:36 -07:00
Glease 888f86f2da Remove IMC hack 2021-08-26 12:21:46 -07:00
D-Cysteine b4780716ec Add support for custom handler IDs (#154)
* Always show quantity text box

* Increment version

* Properly fix quantity text field

* Add support for custom handler names

* Add overloads
2021-08-25 06:14:34 +02:00
Andrey 52fb89daf6 Add builder for use in NEIRegisterHandlerInfosEvent (#153) 2021-08-22 10:16:15 -07:00
D-Cysteine dd18d2b775 Properly fix NEI quantity text field behavior (#152)
* Always show quantity text box
* Increment version
* Properly fix quantity text field
2021-08-22 10:15:23 -07:00
440 changed files with 57985 additions and 15876 deletions

No files matched your search

+2
View File
@@ -0,0 +1,2 @@
# Ignore spotlessApply reformat
f106b5e7665df6341ae8539f74dc391a7efc98b1
+44
View File
@@ -0,0 +1,44 @@
* text eol=lf
*.[jJ][aA][rR] binary
*.[pP][nN][gG] binary
*.[jJ][pP][gG] binary
*.[jJ][pP][eE][gG] binary
*.[gG][iI][fF] binary
*.[tT][iI][fF] binary
*.[tT][iI][fF][fF] binary
*.[iI][cC][oO] binary
*.[sS][vV][gG] text
*.[eE][pP][sS] binary
*.[xX][cC][fF] binary
*.[kK][aA][rR] binary
*.[mM]4[aA] binary
*.[mM][iI][dD] binary
*.[mM][iI][dD][iI] binary
*.[mM][pP]3 binary
*.[oO][gG][gG] binary
*.[rR][aA] binary
*.7[zZ] binary
*.[gG][zZ] binary
*.[tT][aA][rR] binary
*.[tT][gG][zZ] binary
*.[zZ][iI][pP] binary
*.[tT][cC][nN] binary
*.[sS][oO] binary
*.[dD][lL][lL] binary
*.[dD][yY][lL][iI][bB] binary
*.[pP][sS][dD] binary
*.[tT][tT][fF] binary
*.[oO][tT][fF] binary
*.[pP][aA][tT][cC][hH] -text
*.[bB][aA][tT] text eol=crlf
*.[cC][mM][dD] text eol=crlf
*.[pP][sS]1 text eol=crlf
*[aA][uU][tT][oO][gG][eE][nN][eE][rR][aA][tT][eE][dD]* binary
+60
View File
@@ -0,0 +1,60 @@
name: Report Bug
description: "Report a bug."
body:
- type: markdown
attributes:
value: "A bug/crash report with sufficient information and logs to reproduce and track down."
- type: input
id: discord
attributes:
label: Your GTNH Discord Username
description: Leave empty if you don't have one, but this will make it harder to contact you if we need additional info.
placeholder: "Example: Fake#1234"
- type: input
id: version
attributes:
label: Mod Version
description: "What version of the Mod are you using?"
placeholder: "Example: 1.0.0"
validations:
required: true
- type: textarea
id: report
attributes:
label: Bug Report
description: "Relevant information, as well as relevant logs attached such as `logs/fml-client-latest.log."
placeholder: "Example: https://mclo.gs/ OR submit the file to github by dragging it to this textbox."
validations:
required: true
- type: dropdown
id: java
attributes:
label: Java Version
description: What Java version are you using? It's worth mentioning that if you play on Java9+ you should try update to latest minor release (e.g. prefer Java 17.0.6 over 17.0.2) of that version.
options:
- Java 8
- Java 17
- Java 21
- java 25
- java 26
- Other (Please Specify)
validations:
required: true
- type: textarea
id: modlist
attributes:
label: Mod List or GTNH Pack Version
description: "List of mods, ideally a minimal reproducible set (can be retrieved from latest.log). If using GTNH please indicate pack version and any changed mods, not the entire modlist."
placeholder: "List of mods or GTNH Pack version goes here"
validations:
required: true
- type: checkboxes
id: final
attributes:
label: Final Checklist
description: Certify that you read things
options:
- label: "I have searched the issues and haven't found a similar issue."
required: true
@@ -0,0 +1,28 @@
name: Feature Request
description: "Request a feature."
body:
- type: markdown
attributes:
value: "Please use this form to request features. We ask you check if it was already requested though"
- type: input
id: discord
attributes:
label: Your GTNH Discord Username
description: Leave empty if you don't have one, but this will make it harder to contact you if we need additional info.
placeholder: "Example: Wumpus#1234"
- type: textarea
id: request
attributes:
label: Feature Request
description: "Relevant information, as well as relevant images"
placeholder: "Example: https://mclo.gs/ OR submit the file to github by dragging it to this textbox."
validations:
required: true
- type: checkboxes
id: final
attributes:
label: Final Checklist
description: Certify that you read things
options:
- label: "I have searched the issues and haven't found a similar issue."
required: true
+13
View File
@@ -0,0 +1,13 @@
name: Build and test
on:
pull_request:
branches: [ master, main, release/** ]
push:
branches: [ master, main, release/** ]
jobs:
build-and-test:
uses: GTNewHorizons/GTNH-Actions-Workflows/.github/workflows/build-and-test.yml@master
secrets: inherit
+17
View File
@@ -0,0 +1,17 @@
name: Optimize images
on:
pull_request:
branches: [ master, main, release/** ]
paths:
- "**/*.png"
push:
branches: [ master, main, release/** ]
paths:
- "**/*.png"
jobs:
optimize-images:
uses: GTNewHorizons/GTNH-Actions-Workflows/.github/workflows/optimize-images.yml@master
secrets: inherit
+14
View File
@@ -0,0 +1,14 @@
name: Release tagged build
on:
push:
tags: [ '*' ]
permissions:
contents: write
jobs:
release-tags:
uses: GTNewHorizons/GTNH-Actions-Workflows/.github/workflows/release-tags.yml@master
secrets: inherit
+38 -13
View File
@@ -1,15 +1,40 @@
./build/
NotEnoughItems.iml
NotEnoughItems.ipr
NotEnoughItems.iws
*.ipr
*.iml
*.iws
.idea/**
run/*
.gradle/
*.bat
.gradle
.settings
/.idea/
/.vscode/
/run/
/build/
/eclipse/
.classpath
.project
.settings/**
/bin/
/config/
/crash-reports/
/logs/
options.txt
/saves/
usernamecache.json
banned-ips.json
banned-players.json
eula.txt
ops.json
server.properties
servers.dat
usercache.json
whitelist.json
/out/
*.iml
*.ipr
*.iws
src/main/resources/mixins.*([!.]).json
*.bat
*.sh
*.DS_Store
!gradlew.bat
.factorypath
addon.local.gradle
addon.local.gradle.kts
addon.late.local.gradle
addon.late.local.gradle.kts
layout.json
+3
View File
@@ -0,0 +1,3 @@
# Any Github changes require admin approval
/.github/** @GTNewHorizons/admin
-674
View File
@@ -1,674 +0,0 @@
GNU GENERAL PUBLIC LICENSE
Version 3, 29 June 2007
Copyright (C) 2007 Free Software Foundation, Inc. <https://fsf.org/>
Everyone is permitted to copy and distribute verbatim copies
of this license document, but changing it is not allowed.
Preamble
The GNU General Public License is a free, copyleft license for
software and other kinds of works.
The licenses for most software and other practical works are designed
to take away your freedom to share and change the works. By contrast,
the GNU General Public License is intended to guarantee your freedom to
share and change all versions of a program--to make sure it remains free
software for all its users. We, the Free Software Foundation, use the
GNU General Public License for most of our software; it applies also to
any other work released this way by its authors. You can apply it to
your programs, too.
When we speak of free software, we are referring to freedom, not
price. Our General Public Licenses are designed to make sure that you
have the freedom to distribute copies of free software (and charge for
them if you wish), that you receive source code or can get it if you
want it, that you can change the software or use pieces of it in new
free programs, and that you know you can do these things.
To protect your rights, we need to prevent others from denying you
these rights or asking you to surrender the rights. Therefore, you have
certain responsibilities if you distribute copies of the software, or if
you modify it: responsibilities to respect the freedom of others.
For example, if you distribute copies of such a program, whether
gratis or for a fee, you must pass on to the recipients the same
freedoms that you received. You must make sure that they, too, receive
or can get the source code. And you must show them these terms so they
know their rights.
Developers that use the GNU GPL protect your rights with two steps:
(1) assert copyright on the software, and (2) offer you this License
giving you legal permission to copy, distribute and/or modify it.
For the developers' and authors' protection, the GPL clearly explains
that there is no warranty for this free software. For both users' and
authors' sake, the GPL requires that modified versions be marked as
changed, so that their problems will not be attributed erroneously to
authors of previous versions.
Some devices are designed to deny users access to install or run
modified versions of the software inside them, although the manufacturer
can do so. This is fundamentally incompatible with the aim of
protecting users' freedom to change the software. The systematic
pattern of such abuse occurs in the area of products for individuals to
use, which is precisely where it is most unacceptable. Therefore, we
have designed this version of the GPL to prohibit the practice for those
products. If such problems arise substantially in other domains, we
stand ready to extend this provision to those domains in future versions
of the GPL, as needed to protect the freedom of users.
Finally, every program is threatened constantly by software patents.
States should not allow patents to restrict development and use of
software on general-purpose computers, but in those that do, we wish to
avoid the special danger that patents applied to a free program could
make it effectively proprietary. To prevent this, the GPL assures that
patents cannot be used to render the program non-free.
The precise terms and conditions for copying, distribution and
modification follow.
TERMS AND CONDITIONS
0. Definitions.
"This License" refers to version 3 of the GNU General Public License.
"Copyright" also means copyright-like laws that apply to other kinds of
works, such as semiconductor masks.
"The Program" refers to any copyrightable work licensed under this
License. Each licensee is addressed as "you". "Licensees" and
"recipients" may be individuals or organizations.
To "modify" a work means to copy from or adapt all or part of the work
in a fashion requiring copyright permission, other than the making of an
exact copy. The resulting work is called a "modified version" of the
earlier work or a work "based on" the earlier work.
A "covered work" means either the unmodified Program or a work based
on the Program.
To "propagate" a work means to do anything with it that, without
permission, would make you directly or secondarily liable for
infringement under applicable copyright law, except executing it on a
computer or modifying a private copy. Propagation includes copying,
distribution (with or without modification), making available to the
public, and in some countries other activities as well.
To "convey" a work means any kind of propagation that enables other
parties to make or receive copies. Mere interaction with a user through
a computer network, with no transfer of a copy, is not conveying.
An interactive user interface displays "Appropriate Legal Notices"
to the extent that it includes a convenient and prominently visible
feature that (1) displays an appropriate copyright notice, and (2)
tells the user that there is no warranty for the work (except to the
extent that warranties are provided), that licensees may convey the
work under this License, and how to view a copy of this License. If
the interface presents a list of user commands or options, such as a
menu, a prominent item in the list meets this criterion.
1. Source Code.
The "source code" for a work means the preferred form of the work
for making modifications to it. "Object code" means any non-source
form of a work.
A "Standard Interface" means an interface that either is an official
standard defined by a recognized standards body, or, in the case of
interfaces specified for a particular programming language, one that
is widely used among developers working in that language.
The "System Libraries" of an executable work include anything, other
than the work as a whole, that (a) is included in the normal form of
packaging a Major Component, but which is not part of that Major
Component, and (b) serves only to enable use of the work with that
Major Component, or to implement a Standard Interface for which an
implementation is available to the public in source code form. A
"Major Component", in this context, means a major essential component
(kernel, window system, and so on) of the specific operating system
(if any) on which the executable work runs, or a compiler used to
produce the work, or an object code interpreter used to run it.
The "Corresponding Source" for a work in object code form means all
the source code needed to generate, install, and (for an executable
work) run the object code and to modify the work, including scripts to
control those activities. However, it does not include the work's
System Libraries, or general-purpose tools or generally available free
programs which are used unmodified in performing those activities but
which are not part of the work. For example, Corresponding Source
includes interface definition files associated with source files for
the work, and the source code for shared libraries and dynamically
linked subprograms that the work is specifically designed to require,
such as by intimate data communication or control flow between those
subprograms and other parts of the work.
The Corresponding Source need not include anything that users
can regenerate automatically from other parts of the Corresponding
Source.
The Corresponding Source for a work in source code form is that
same work.
2. Basic Permissions.
All rights granted under this License are granted for the term of
copyright on the Program, and are irrevocable provided the stated
conditions are met. This License explicitly affirms your unlimited
permission to run the unmodified Program. The output from running a
covered work is covered by this License only if the output, given its
content, constitutes a covered work. This License acknowledges your
rights of fair use or other equivalent, as provided by copyright law.
You may make, run and propagate covered works that you do not
convey, without conditions so long as your license otherwise remains
in force. You may convey covered works to others for the sole purpose
of having them make modifications exclusively for you, or provide you
with facilities for running those works, provided that you comply with
the terms of this License in conveying all material for which you do
not control copyright. Those thus making or running the covered works
for you must do so exclusively on your behalf, under your direction
and control, on terms that prohibit them from making any copies of
your copyrighted material outside their relationship with you.
Conveying under any other circumstances is permitted solely under
the conditions stated below. Sublicensing is not allowed; section 10
makes it unnecessary.
3. Protecting Users' Legal Rights From Anti-Circumvention Law.
No covered work shall be deemed part of an effective technological
measure under any applicable law fulfilling obligations under article
11 of the WIPO copyright treaty adopted on 20 December 1996, or
similar laws prohibiting or restricting circumvention of such
measures.
When you convey a covered work, you waive any legal power to forbid
circumvention of technological measures to the extent such circumvention
is effected by exercising rights under this License with respect to
the covered work, and you disclaim any intention to limit operation or
modification of the work as a means of enforcing, against the work's
users, your or third parties' legal rights to forbid circumvention of
technological measures.
4. Conveying Verbatim Copies.
You may convey verbatim copies of the Program's source code as you
receive it, in any medium, provided that you conspicuously and
appropriately publish on each copy an appropriate copyright notice;
keep intact all notices stating that this License and any
non-permissive terms added in accord with section 7 apply to the code;
keep intact all notices of the absence of any warranty; and give all
recipients a copy of this License along with the Program.
You may charge any price or no price for each copy that you convey,
and you may offer support or warranty protection for a fee.
5. Conveying Modified Source Versions.
You may convey a work based on the Program, or the modifications to
produce it from the Program, in the form of source code under the
terms of section 4, provided that you also meet all of these conditions:
a) The work must carry prominent notices stating that you modified
it, and giving a relevant date.
b) The work must carry prominent notices stating that it is
released under this License and any conditions added under section
7. This requirement modifies the requirement in section 4 to
"keep intact all notices".
c) You must license the entire work, as a whole, under this
License to anyone who comes into possession of a copy. This
License will therefore apply, along with any applicable section 7
additional terms, to the whole of the work, and all its parts,
regardless of how they are packaged. This License gives no
permission to license the work in any other way, but it does not
invalidate such permission if you have separately received it.
d) If the work has interactive user interfaces, each must display
Appropriate Legal Notices; however, if the Program has interactive
interfaces that do not display Appropriate Legal Notices, your
work need not make them do so.
A compilation of a covered work with other separate and independent
works, which are not by their nature extensions of the covered work,
and which are not combined with it such as to form a larger program,
in or on a volume of a storage or distribution medium, is called an
"aggregate" if the compilation and its resulting copyright are not
used to limit the access or legal rights of the compilation's users
beyond what the individual works permit. Inclusion of a covered work
in an aggregate does not cause this License to apply to the other
parts of the aggregate.
6. Conveying Non-Source Forms.
You may convey a covered work in object code form under the terms
of sections 4 and 5, provided that you also convey the
machine-readable Corresponding Source under the terms of this License,
in one of these ways:
a) Convey the object code in, or embodied in, a physical product
(including a physical distribution medium), accompanied by the
Corresponding Source fixed on a durable physical medium
customarily used for software interchange.
b) Convey the object code in, or embodied in, a physical product
(including a physical distribution medium), accompanied by a
written offer, valid for at least three years and valid for as
long as you offer spare parts or customer support for that product
model, to give anyone who possesses the object code either (1) a
copy of the Corresponding Source for all the software in the
product that is covered by this License, on a durable physical
medium customarily used for software interchange, for a price no
more than your reasonable cost of physically performing this
conveying of source, or (2) access to copy the
Corresponding Source from a network server at no charge.
c) Convey individual copies of the object code with a copy of the
written offer to provide the Corresponding Source. This
alternative is allowed only occasionally and noncommercially, and
only if you received the object code with such an offer, in accord
with subsection 6b.
d) Convey the object code by offering access from a designated
place (gratis or for a charge), and offer equivalent access to the
Corresponding Source in the same way through the same place at no
further charge. You need not require recipients to copy the
Corresponding Source along with the object code. If the place to
copy the object code is a network server, the Corresponding Source
may be on a different server (operated by you or a third party)
that supports equivalent copying facilities, provided you maintain
clear directions next to the object code saying where to find the
Corresponding Source. Regardless of what server hosts the
Corresponding Source, you remain obligated to ensure that it is
available for as long as needed to satisfy these requirements.
e) Convey the object code using peer-to-peer transmission, provided
you inform other peers where the object code and Corresponding
Source of the work are being offered to the general public at no
charge under subsection 6d.
A separable portion of the object code, whose source code is excluded
from the Corresponding Source as a System Library, need not be
included in conveying the object code work.
A "User Product" is either (1) a "consumer product", which means any
tangible personal property which is normally used for personal, family,
or household purposes, or (2) anything designed or sold for incorporation
into a dwelling. In determining whether a product is a consumer product,
doubtful cases shall be resolved in favor of coverage. For a particular
product received by a particular user, "normally used" refers to a
typical or common use of that class of product, regardless of the status
of the particular user or of the way in which the particular user
actually uses, or expects or is expected to use, the product. A product
is a consumer product regardless of whether the product has substantial
commercial, industrial or non-consumer uses, unless such uses represent
the only significant mode of use of the product.
"Installation Information" for a User Product means any methods,
procedures, authorization keys, or other information required to install
and execute modified versions of a covered work in that User Product from
a modified version of its Corresponding Source. The information must
suffice to ensure that the continued functioning of the modified object
code is in no case prevented or interfered with solely because
modification has been made.
If you convey an object code work under this section in, or with, or
specifically for use in, a User Product, and the conveying occurs as
part of a transaction in which the right of possession and use of the
User Product is transferred to the recipient in perpetuity or for a
fixed term (regardless of how the transaction is characterized), the
Corresponding Source conveyed under this section must be accompanied
by the Installation Information. But this requirement does not apply
if neither you nor any third party retains the ability to install
modified object code on the User Product (for example, the work has
been installed in ROM).
The requirement to provide Installation Information does not include a
requirement to continue to provide support service, warranty, or updates
for a work that has been modified or installed by the recipient, or for
the User Product in which it has been modified or installed. Access to a
network may be denied when the modification itself materially and
adversely affects the operation of the network or violates the rules and
protocols for communication across the network.
Corresponding Source conveyed, and Installation Information provided,
in accord with this section must be in a format that is publicly
documented (and with an implementation available to the public in
source code form), and must require no special password or key for
unpacking, reading or copying.
7. Additional Terms.
"Additional permissions" are terms that supplement the terms of this
License by making exceptions from one or more of its conditions.
Additional permissions that are applicable to the entire Program shall
be treated as though they were included in this License, to the extent
that they are valid under applicable law. If additional permissions
apply only to part of the Program, that part may be used separately
under those permissions, but the entire Program remains governed by
this License without regard to the additional permissions.
When you convey a copy of a covered work, you may at your option
remove any additional permissions from that copy, or from any part of
it. (Additional permissions may be written to require their own
removal in certain cases when you modify the work.) You may place
additional permissions on material, added by you to a covered work,
for which you have or can give appropriate copyright permission.
Notwithstanding any other provision of this License, for material you
add to a covered work, you may (if authorized by the copyright holders of
that material) supplement the terms of this License with terms:
a) Disclaiming warranty or limiting liability differently from the
terms of sections 15 and 16 of this License; or
b) Requiring preservation of specified reasonable legal notices or
author attributions in that material or in the Appropriate Legal
Notices displayed by works containing it; or
c) Prohibiting misrepresentation of the origin of that material, or
requiring that modified versions of such material be marked in
reasonable ways as different from the original version; or
d) Limiting the use for publicity purposes of names of licensors or
authors of the material; or
e) Declining to grant rights under trademark law for use of some
trade names, trademarks, or service marks; or
f) Requiring indemnification of licensors and authors of that
material by anyone who conveys the material (or modified versions of
it) with contractual assumptions of liability to the recipient, for
any liability that these contractual assumptions directly impose on
those licensors and authors.
All other non-permissive additional terms are considered "further
restrictions" within the meaning of section 10. If the Program as you
received it, or any part of it, contains a notice stating that it is
governed by this License along with a term that is a further
restriction, you may remove that term. If a license document contains
a further restriction but permits relicensing or conveying under this
License, you may add to a covered work material governed by the terms
of that license document, provided that the further restriction does
not survive such relicensing or conveying.
If you add terms to a covered work in accord with this section, you
must place, in the relevant source files, a statement of the
additional terms that apply to those files, or a notice indicating
where to find the applicable terms.
Additional terms, permissive or non-permissive, may be stated in the
form of a separately written license, or stated as exceptions;
the above requirements apply either way.
8. Termination.
You may not propagate or modify a covered work except as expressly
provided under this License. Any attempt otherwise to propagate or
modify it is void, and will automatically terminate your rights under
this License (including any patent licenses granted under the third
paragraph of section 11).
However, if you cease all violation of this License, then your
license from a particular copyright holder is reinstated (a)
provisionally, unless and until the copyright holder explicitly and
finally terminates your license, and (b) permanently, if the copyright
holder fails to notify you of the violation by some reasonable means
prior to 60 days after the cessation.
Moreover, your license from a particular copyright holder is
reinstated permanently if the copyright holder notifies you of the
violation by some reasonable means, this is the first time you have
received notice of violation of this License (for any work) from that
copyright holder, and you cure the violation prior to 30 days after
your receipt of the notice.
Termination of your rights under this section does not terminate the
licenses of parties who have received copies or rights from you under
this License. If your rights have been terminated and not permanently
reinstated, you do not qualify to receive new licenses for the same
material under section 10.
9. Acceptance Not Required for Having Copies.
You are not required to accept this License in order to receive or
run a copy of the Program. Ancillary propagation of a covered work
occurring solely as a consequence of using peer-to-peer transmission
to receive a copy likewise does not require acceptance. However,
nothing other than this License grants you permission to propagate or
modify any covered work. These actions infringe copyright if you do
not accept this License. Therefore, by modifying or propagating a
covered work, you indicate your acceptance of this License to do so.
10. Automatic Licensing of Downstream Recipients.
Each time you convey a covered work, the recipient automatically
receives a license from the original licensors, to run, modify and
propagate that work, subject to this License. You are not responsible
for enforcing compliance by third parties with this License.
An "entity transaction" is a transaction transferring control of an
organization, or substantially all assets of one, or subdividing an
organization, or merging organizations. If propagation of a covered
work results from an entity transaction, each party to that
transaction who receives a copy of the work also receives whatever
licenses to the work the party's predecessor in interest had or could
give under the previous paragraph, plus a right to possession of the
Corresponding Source of the work from the predecessor in interest, if
the predecessor has it or can get it with reasonable efforts.
You may not impose any further restrictions on the exercise of the
rights granted or affirmed under this License. For example, you may
not impose a license fee, royalty, or other charge for exercise of
rights granted under this License, and you may not initiate litigation
(including a cross-claim or counterclaim in a lawsuit) alleging that
any patent claim is infringed by making, using, selling, offering for
sale, or importing the Program or any portion of it.
11. Patents.
A "contributor" is a copyright holder who authorizes use under this
License of the Program or a work on which the Program is based. The
work thus licensed is called the contributor's "contributor version".
A contributor's "essential patent claims" are all patent claims
owned or controlled by the contributor, whether already acquired or
hereafter acquired, that would be infringed by some manner, permitted
by this License, of making, using, or selling its contributor version,
but do not include claims that would be infringed only as a
consequence of further modification of the contributor version. For
purposes of this definition, "control" includes the right to grant
patent sublicenses in a manner consistent with the requirements of
this License.
Each contributor grants you a non-exclusive, worldwide, royalty-free
patent license under the contributor's essential patent claims, to
make, use, sell, offer for sale, import and otherwise run, modify and
propagate the contents of its contributor version.
In the following three paragraphs, a "patent license" is any express
agreement or commitment, however denominated, not to enforce a patent
(such as an express permission to practice a patent or covenant not to
sue for patent infringement). To "grant" such a patent license to a
party means to make such an agreement or commitment not to enforce a
patent against the party.
If you convey a covered work, knowingly relying on a patent license,
and the Corresponding Source of the work is not available for anyone
to copy, free of charge and under the terms of this License, through a
publicly available network server or other readily accessible means,
then you must either (1) cause the Corresponding Source to be so
available, or (2) arrange to deprive yourself of the benefit of the
patent license for this particular work, or (3) arrange, in a manner
consistent with the requirements of this License, to extend the patent
license to downstream recipients. "Knowingly relying" means you have
actual knowledge that, but for the patent license, your conveying the
covered work in a country, or your recipient's use of the covered work
in a country, would infringe one or more identifiable patents in that
country that you have reason to believe are valid.
If, pursuant to or in connection with a single transaction or
arrangement, you convey, or propagate by procuring conveyance of, a
covered work, and grant a patent license to some of the parties
receiving the covered work authorizing them to use, propagate, modify
or convey a specific copy of the covered work, then the patent license
you grant is automatically extended to all recipients of the covered
work and works based on it.
A patent license is "discriminatory" if it does not include within
the scope of its coverage, prohibits the exercise of, or is
conditioned on the non-exercise of one or more of the rights that are
specifically granted under this License. You may not convey a covered
work if you are a party to an arrangement with a third party that is
in the business of distributing software, under which you make payment
to the third party based on the extent of your activity of conveying
the work, and under which the third party grants, to any of the
parties who would receive the covered work from you, a discriminatory
patent license (a) in connection with copies of the covered work
conveyed by you (or copies made from those copies), or (b) primarily
for and in connection with specific products or compilations that
contain the covered work, unless you entered into that arrangement,
or that patent license was granted, prior to 28 March 2007.
Nothing in this License shall be construed as excluding or limiting
any implied license or other defenses to infringement that may
otherwise be available to you under applicable patent law.
12. No Surrender of Others' Freedom.
If conditions are imposed on you (whether by court order, agreement or
otherwise) that contradict the conditions of this License, they do not
excuse you from the conditions of this License. If you cannot convey a
covered work so as to satisfy simultaneously your obligations under this
License and any other pertinent obligations, then as a consequence you may
not convey it at all. For example, if you agree to terms that obligate you
to collect a royalty for further conveying from those to whom you convey
the Program, the only way you could satisfy both those terms and this
License would be to refrain entirely from conveying the Program.
13. Use with the GNU Affero General Public License.
Notwithstanding any other provision of this License, you have
permission to link or combine any covered work with a work licensed
under version 3 of the GNU Affero General Public License into a single
combined work, and to convey the resulting work. The terms of this
License will continue to apply to the part which is the covered work,
but the special requirements of the GNU Affero General Public License,
section 13, concerning interaction through a network will apply to the
combination as such.
14. Revised Versions of this License.
The Free Software Foundation may publish revised and/or new versions of
the GNU General Public License from time to time. Such new versions will
be similar in spirit to the present version, but may differ in detail to
address new problems or concerns.
Each version is given a distinguishing version number. If the
Program specifies that a certain numbered version of the GNU General
Public License "or any later version" applies to it, you have the
option of following the terms and conditions either of that numbered
version or of any later version published by the Free Software
Foundation. If the Program does not specify a version number of the
GNU General Public License, you may choose any version ever published
by the Free Software Foundation.
If the Program specifies that a proxy can decide which future
versions of the GNU General Public License can be used, that proxy's
public statement of acceptance of a version permanently authorizes you
to choose that version for the Program.
Later license versions may give you additional or different
permissions. However, no additional obligations are imposed on any
author or copyright holder as a result of your choosing to follow a
later version.
15. Disclaimer of Warranty.
THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY
APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT
HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY
OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO,
THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM
IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF
ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
16. Limitation of Liability.
IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS
THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY
GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE
USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF
DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD
PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS),
EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF
SUCH DAMAGES.
17. Interpretation of Sections 15 and 16.
If the disclaimer of warranty and limitation of liability provided
above cannot be given local legal effect according to their terms,
reviewing courts shall apply local law that most closely approximates
an absolute waiver of all civil liability in connection with the
Program, unless a warranty or assumption of liability accompanies a
copy of the Program in return for a fee.
END OF TERMS AND CONDITIONS
How to Apply These Terms to Your New Programs
If you develop a new program, and you want it to be of the greatest
possible use to the public, the best way to achieve this is to make it
free software which everyone can redistribute and change under these terms.
To do so, attach the following notices to the program. It is safest
to attach them to the start of each source file to most effectively
state the exclusion of warranty; and each file should have at least
the "copyright" line and a pointer to where the full notice is found.
<one line to give the program's name and a brief idea of what it does.>
Copyright (C) <year> <name of author>
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <https://www.gnu.org/licenses/>.
Also add information on how to contact you by electronic and paper mail.
If the program does terminal interaction, make it output a short
notice like this when it starts in an interactive mode:
<program> Copyright (C) <year> <name of author>
This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
This is free software, and you are welcome to redistribute it
under certain conditions; type `show c' for details.
The hypothetical commands `show w' and `show c' should show the appropriate
parts of the General Public License. Of course, your program's commands
might be different; for a GUI interface, you would use an "about box".
You should also get your employer (if you work as a programmer) or school,
if any, to sign a "copyright disclaimer" for the program, if necessary.
For more information on this, and how to apply and follow the GNU GPL, see
<https://www.gnu.org/licenses/>.
The GNU General Public License does not permit incorporating your program
into proprietary programs. If your program is a subroutine library, you
may consider it more useful to permit linking proprietary applications with
the library. If this is what you want to do, use the GNU Lesser General
Public License instead of this License. But first, please read
<https://www.gnu.org/licenses/why-not-lgpl.html>.1996
-165
View File
@@ -1,165 +0,0 @@
GNU LESSER GENERAL PUBLIC LICENSE
Version 3, 29 June 2007
Copyright (C) 2007 Free Software Foundation, Inc. <https://fsf.org/>
Everyone is permitted to copy and distribute verbatim copies
of this license document, but changing it is not allowed.
This version of the GNU Lesser General Public License incorporates
the terms and conditions of version 3 of the GNU General Public
License, supplemented by the additional permissions listed below.
0. Additional Definitions.
As used herein, "this License" refers to version 3 of the GNU Lesser
General Public License, and the "GNU GPL" refers to version 3 of the GNU
General Public License.
"The Library" refers to a covered work governed by this License,
other than an Application or a Combined Work as defined below.
An "Application" is any work that makes use of an interface provided
by the Library, but which is not otherwise based on the Library.
Defining a subclass of a class defined by the Library is deemed a mode
of using an interface provided by the Library.
A "Combined Work" is a work produced by combining or linking an
Application with the Library. The particular version of the Library
with which the Combined Work was made is also called the "Linked
Version".
The "Minimal Corresponding Source" for a Combined Work means the
Corresponding Source for the Combined Work, excluding any source code
for portions of the Combined Work that, considered in isolation, are
based on the Application, and not on the Linked Version.
The "Corresponding Application Code" for a Combined Work means the
object code and/or source code for the Application, including any data
and utility programs needed for reproducing the Combined Work from the
Application, but excluding the System Libraries of the Combined Work.
1. Exception to Section 3 of the GNU GPL.
You may convey a covered work under sections 3 and 4 of this License
without being bound by section 3 of the GNU GPL.
2. Conveying Modified Versions.
If you modify a copy of the Library, and, in your modifications, a
facility refers to a function or data to be supplied by an Application
that uses the facility (other than as an argument passed when the
facility is invoked), then you may convey a copy of the modified
version:
a) under this License, provided that you make a good faith effort to
ensure that, in the event an Application does not supply the
function or data, the facility still operates, and performs
whatever part of its purpose remains meaningful, or
b) under the GNU GPL, with none of the additional permissions of
this License applicable to that copy.
3. Object Code Incorporating Material from Library Header Files.
The object code form of an Application may incorporate material from
a header file that is part of the Library. You may convey such object
code under terms of your choice, provided that, if the incorporated
material is not limited to numerical parameters, data structure
layouts and accessors, or small macros, inline functions and templates
(ten or fewer lines in length), you do both of the following:
a) Give prominent notice with each copy of the object code that the
Library is used in it and that the Library and its use are
covered by this License.
b) Accompany the object code with a copy of the GNU GPL and this license
document.
4. Combined Works.
You may convey a Combined Work under terms of your choice that,
taken together, effectively do not restrict modification of the
portions of the Library contained in the Combined Work and reverse
engineering for debugging such modifications, if you also do each of
the following:
a) Give prominent notice with each copy of the Combined Work that
the Library is used in it and that the Library and its use are
covered by this License.
b) Accompany the Combined Work with a copy of the GNU GPL and this license
document.
c) For a Combined Work that displays copyright notices during
execution, include the copyright notice for the Library among
these notices, as well as a reference directing the user to the
copies of the GNU GPL and this license document.
d) Do one of the following:
0) Convey the Minimal Corresponding Source under the terms of this
License, and the Corresponding Application Code in a form
suitable for, and under terms that permit, the user to
recombine or relink the Application with a modified version of
the Linked Version to produce a modified Combined Work, in the
manner specified by section 6 of the GNU GPL for conveying
Corresponding Source.
1) Use a suitable shared library mechanism for linking with the
Library. A suitable mechanism is one that (a) uses at run time
a copy of the Library already present on the user's computer
system, and (b) will operate properly with a modified version
of the Library that is interface-compatible with the Linked
Version.
e) Provide Installation Information, but only if you would otherwise
be required to provide such information under section 6 of the
GNU GPL, and only to the extent that such information is
necessary to install and execute a modified version of the
Combined Work produced by recombining or relinking the
Application with a modified version of the Linked Version. (If
you use option 4d0, the Installation Information must accompany
the Minimal Corresponding Source and Corresponding Application
Code. If you use option 4d1, you must provide the Installation
Information in the manner specified by section 6 of the GNU GPL
for conveying Corresponding Source.)
5. Combined Libraries.
You may place library facilities that are a work based on the
Library side by side in a single library together with other library
facilities that are not Applications and are not covered by this
License, and convey such a combined library under terms of your
choice, if you do both of the following:
a) Accompany the combined library with a copy of the same work based
on the Library, uncombined with any other library facilities,
conveyed under the terms of this License.
b) Give prominent notice with the combined library that part of it
is a work based on the Library, and explaining where to find the
accompanying uncombined form of the same work.
6. Revised Versions of the GNU Lesser General Public License.
The Free Software Foundation may publish revised and/or new versions
of the GNU Lesser General Public License from time to time. Such new
versions will be similar in spirit to the present version, but may
differ in detail to address new problems or concerns.
Each version is given a distinguishing version number. If the
Library as you received it specifies that a certain numbered version
of the GNU Lesser General Public License "or any later version"
applies to it, you have the option of following the terms and
conditions either of that published version or of any later version
published by the Free Software Foundation. If the Library as you
received it does not specify a version number of the GNU Lesser
General Public License, you may choose any version of the GNU Lesser
General Public License ever published by the Free Software Foundation.
If the Library as you received it specifies that a proxy can decide
whether future versions of the GNU Lesser General Public License shall
apply, that proxy's public statement of acceptance of any version is
permanent authorization for you to choose that version for the
Library.
+149 -44
View File
@@ -1,60 +1,165 @@
GTNH Modifications:
GNU LESSER GENERAL PUBLIC LICENSE
Version 3, 29 June 2007
Copyright (c) 2019 mitchej123
GNU LESSER GENERAL PUBLIC LICENSE - See COPYING & COPYING.LESSER
Copyright (C) 2007 Free Software Foundation, Inc. <https://fsf.org/>
Everyone is permitted to copy and distribute verbatim copies
of this license document, but changing it is not allowed.
-----------------------------------------------------------------------------
This version of the GNU Lesser General Public License incorporates
the terms and conditions of version 3 of the GNU General Public
License, supplemented by the additional permissions listed below.
Parts inspired/borrowed/backported from JEI under the MIT License:
0. Additional Definitions.
https://github.com/mezz/JustEnoughItems/tree/1.12
The MIT License (MIT)
As used herein, "this License" refers to version 3 of the GNU Lesser
General Public License, and the "GNU GPL" refers to version 3 of the GNU
General Public License.
Copyright (c) 2014-2015 mezz
"The Library" refers to a covered work governed by this License,
other than an Application or a Combined Work as defined below.
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
An "Application" is any work that makes use of an interface provided
by the Library, but which is not otherwise based on the Library.
Defining a subclass of a class defined by the Library is deemed a mode
of using an interface provided by the Library.
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
A "Combined Work" is a work produced by combining or linking an
Application with the Library. The particular version of the Library
with which the Combined Work was made is also called the "Linked
Version".
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
The "Minimal Corresponding Source" for a Combined Work means the
Corresponding Source for the Combined Work, excluding any source code
for portions of the Combined Work that, considered in isolation, are
based on the Application, and not on the Linked Version.
-----------------------------------------------------------------------------
The "Corresponding Application Code" for a Combined Work means the
object code and/or source code for the Application, including any data
and utility programs needed for reproducing the Combined Work from the
Application, but excluding the System Libraries of the Combined Work.
Base NEI License:
1. Exception to Section 3 of the GNU GPL.
The MIT License (MIT)
You may convey a covered work under sections 3 and 4 of this License
without being bound by section 3 of the GNU GPL.
Copyright (c) 2014 ChickenBones
2. Conveying Modified Versions.
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
If you modify a copy of the Library, and, in your modifications, a
facility refers to a function or data to be supplied by an Application
that uses the facility (other than as an argument passed when the
facility is invoked), then you may convey a copy of the modified
version:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
a) under this License, provided that you make a good faith effort to
ensure that, in the event an Application does not supply the
function or data, the facility still operates, and performs
whatever part of its purpose remains meaningful, or
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
b) under the GNU GPL, with none of the additional permissions of
this License applicable to that copy.
3. Object Code Incorporating Material from Library Header Files.
The object code form of an Application may incorporate material from
a header file that is part of the Library. You may convey such object
code under terms of your choice, provided that, if the incorporated
material is not limited to numerical parameters, data structure
layouts and accessors, or small macros, inline functions and templates
(ten or fewer lines in length), you do both of the following:
a) Give prominent notice with each copy of the object code that the
Library is used in it and that the Library and its use are
covered by this License.
b) Accompany the object code with a copy of the GNU GPL and this license
document.
4. Combined Works.
You may convey a Combined Work under terms of your choice that,
taken together, effectively do not restrict modification of the
portions of the Library contained in the Combined Work and reverse
engineering for debugging such modifications, if you also do each of
the following:
a) Give prominent notice with each copy of the Combined Work that
the Library is used in it and that the Library and its use are
covered by this License.
b) Accompany the Combined Work with a copy of the GNU GPL and this license
document.
c) For a Combined Work that displays copyright notices during
execution, include the copyright notice for the Library among
these notices, as well as a reference directing the user to the
copies of the GNU GPL and this license document.
d) Do one of the following:
0) Convey the Minimal Corresponding Source under the terms of this
License, and the Corresponding Application Code in a form
suitable for, and under terms that permit, the user to
recombine or relink the Application with a modified version of
the Linked Version to produce a modified Combined Work, in the
manner specified by section 6 of the GNU GPL for conveying
Corresponding Source.
1) Use a suitable shared library mechanism for linking with the
Library. A suitable mechanism is one that (a) uses at run time
a copy of the Library already present on the user's computer
system, and (b) will operate properly with a modified version
of the Library that is interface-compatible with the Linked
Version.
e) Provide Installation Information, but only if you would otherwise
be required to provide such information under section 6 of the
GNU GPL, and only to the extent that such information is
necessary to install and execute a modified version of the
Combined Work produced by recombining or relinking the
Application with a modified version of the Linked Version. (If
you use option 4d0, the Installation Information must accompany
the Minimal Corresponding Source and Corresponding Application
Code. If you use option 4d1, you must provide the Installation
Information in the manner specified by section 6 of the GNU GPL
for conveying Corresponding Source.)
5. Combined Libraries.
You may place library facilities that are a work based on the
Library side by side in a single library together with other library
facilities that are not Applications and are not covered by this
License, and convey such a combined library under terms of your
choice, if you do both of the following:
a) Accompany the combined library with a copy of the same work based
on the Library, uncombined with any other library facilities,
conveyed under the terms of this License.
b) Give prominent notice with the combined library that part of it
is a work based on the Library, and explaining where to find the
accompanying uncombined form of the same work.
6. Revised Versions of the GNU Lesser General Public License.
The Free Software Foundation may publish revised and/or new versions
of the GNU Lesser General Public License from time to time. Such new
versions will be similar in spirit to the present version, but may
differ in detail to address new problems or concerns.
Each version is given a distinguishing version number. If the
Library as you received it specifies that a certain numbered version
of the GNU Lesser General Public License "or any later version"
applies to it, you have the option of following the terms and
conditions either of that published version or of any later version
published by the Free Software Foundation. If the Library as you
received it does not specify a version number of the GNU Lesser
General Public License, you may choose any version of the GNU Lesser
General Public License ever published by the Free Software Foundation.
If the Library as you received it specifies that a proxy can decide
whether future versions of the GNU Lesser General Public License shall
apply, that proxy's public statement of acceptance of any version is
permanent authorization for you to choose that version for the
Library.
+72 -10
View File
@@ -1,31 +1,93 @@
# NotEnoughItems Unofficial - By the GTNH Team
🌐 **Languages:** [English](README.md) | [Українська](README_uk.md)
A continuation of NotEnoughItems for 1.7.10 by the developers of Gregtech: New Horizons modpack, with features either inspired and/or backported from JustEnoughItems
We've tested this against all of the mods included in GTNH, as well as a limited set of other mods (like Reika's mods). Every effort has been made to maintain backwards compatibility, however the focus is on the mods contained in the GTNH modpack.
We've tested this against all of the mods included in GTNH, as well as a limited set of other mods (like Reika's mods). Every effort has been made to maintain backwards compatibility, however the focus is on the mods contained in the GTNH modpack.
If you have issues with NEI outside of the GTNH modpack you may report them in the [GTNH NEI GitHub](https://github.com/GTNewHorizons/NotEnoughItems).
## New Features:
* Speed
* Speed
- Uses a parallel stream to search the item list over multiple cores, resulting in 2-6x faster searches on average
- Loads the recipe handlers in parallel
- Loads the recipe handlers in parallel
* A textbox for search with most of the features you'd expect - moving forward, backwards, selection, etc
* Bookmarks! What are you in the process of crafting? Bookmark it using either 'A' or configure your own key.
* Bookmarks! Are you in the process of crafting? Bookmark it using either 'A' or configure your own key.
* Toggle bookmark pane. Default shortcut key `B`. Item Subsets menu is only available if bookmarks are not visible.
* Utility/Cheat buttons line up and wrap based on GUI size
* ItemList is no longer regenerated from the ItemRegistry on every inventory load
* JEI (Or Creative) Style tabs [Optional] Note: Requires explicit support to be added for an ItemStack to render, otherwise falls back to the first two letters of the handler name.
* JEI (Or Creative) Style tabs [Optional] Note: Requires explicit support to be added for an ItemStack to render, otherwise falls back to the first two letters of the handler name.
* Tabs/Handlers are loaded from a CSV config in the JAR (or optionally from the config folder). NBT IMCEvents `registerHandlerInfo` and `removeHandlerInfo` are available for mod authors to add handler information, using the same fields as the CSV file
* `@[Mod]->[item]` searching. ex: `@Mod.gregtech->iron ingot`
* Cycle between Recipe, Utility, and Cheat mode by ctrl clicking on the Wrench Icon
* Cycle between Recipe, Utility, and Cheat mode by ctrl clicking on the Wrench Icon
* GT5u Tools/Items and GT6 tools should now properly work with the Overlay Recipe Transfer
### Information Page Handler
Want to add some information about a block or item without making a massive tooltip for it? You can add information about any block or item by registering it in the Information Handler.
Information page(s) are displayed when either the uses or recipes of a matching item are searched. All matching items will cycle at the top of the information page.
Your mod can call:
```java
FMLInterModComms.sendMessage("NotEnoughItems", "addItemInfo", nbt);
```
Where nbt is an NBTTagCompound formatted as described below.
| Tag | Type | Description |
|------------------|----------------------------|----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| `filter` | String | A string filter to match what items should return this information page.<br/>modname:itemname, metadata, Ore Dictionary tags, and regex can all be used. The full format may be seen in `config/NEI/collapsibleitems.cfg`. |
| `page` / `pages` | String / String NBTTagList | The actual text to display. See below for differences between single and multi-page messages.<br/>Both formats will automatically translate provided strings. |
#### Single Page Format
Use the `"page"` string tag when you only want to add one page of information:
```java
NBTTagCompound tag = new NBTTagCompound();
tag.setString("filter", "minecraft:log 3");
tag.setString("page", "Exotic wood found in tropical climates.");
FMLInterModComms.sendMessage("NotEnoughItems", "addItemInfo", tag);
```
#### Multiple Page Format
Use the `"pages"` tag as an `NBTTagList` of strings when you want more than one page:
```java
NBTTagCompound tag = new NBTTagCompound();
tag.setString("filter", "minecraft:diamond_sword");
NBTTagList pages = new NBTTagList();
pages.appendTag(new NBTTagString("A powerful melee weapon."));
pages.appendTag(new NBTTagString("Can be enchanted for extra effects."));
tag.setTag("pages", pages);
FMLInterModComms.sendMessage("NotEnoughItems", "addItemInfo", tag);
```
* Each list entry is one page.
* Pages will appear in NEI with buttons to scroll through them.
#### Item Matching
All items that match `filter` will show your information page. See `config/NEI/collapsibleitems.cfg` for the full filter format.
#### Item Information Config File
If you're a modpack creator and want to make custom item information pages, they can easily be added in `config/NEI/informationpages.cfg`, which has a few more examples. The file is not created automatically: use the Export button in the NEI options under Tools > Default Config Files to copy the defaults to `config/NEI`.
## Other items of note:
* Licensed under LGPL - Use this however you want, but please give back any modifications
* Remove TMI style
* Removed inventory Load/Save state
## License
GTNH Modifications Copyright (c) 2019-2024 mitchej123 and the GTNH Team
Licensed under LGPL-3.0 or later - use this however you want, but please give back any modifications
Parts inspired/borrowed/backported from [JEI](https://github.com/mezz/JustEnoughItems/tree/1.12) under the MIT License.
Originial code Copyright (c) 2014-2015 mezz and was licensed under the MIT License.
+93
View File
@@ -0,0 +1,93 @@
# NotEnoughItems Unofficial — від команди GTNH
🌐 **Мови:** [English](README.md) | [Українська](README_uk.md)
Продовження модифікації NotEnoughItems для 1.7.10 від розробників збірки GregTech: New Horizons із функціями, натхненними та/або бекпортованими з JustEnoughItems.
Ми протестували цю версію з усіма модами, що входять до GTNH, а також із обмеженим набором інших модів (як-от моди від Reika). Було докладено всіх зусиль для збереження зворотної сумісності, однак основну увагу приділено модам зі збірки GTNH.
Якщо у вас виникли проблеми з NEI за межами збірки GTNH, ви можете повідомити про них у [GitHub-репозиторії GTNH NEI](https://github.com/GTNewHorizons/NotEnoughItems).
## Нові можливості:
* Швидкодія
- Використовує паралельний потік для пошуку у списку предметів на кількох ядрах процесора, що в середньому пришвидшує пошук у 2–6 разів.
- Завантажує обробники рецептів паралельно.
* Текстове поле пошуку з більшістю очікуваних функцій — переміщення курсора вперед/назад, виділення тексту тощо.
* Закладки! Перебуваєте у процесі крафту? Додайте потрібний рецепт до закладок за допомогою клавіші «A» або налаштуйте власну клавішу.
* Перемикання видимості панелі закладок. Гаряча клавіша за замовчуванням — `B`. Меню «Підгрупи предметів» доступне лише тоді, коли панель закладок прихована.
* Кнопки утиліт та читів вирівнюються в ряд та переносяться на новий рядок залежно від розміру графічного інтерфейсу.
* Список предметів (`ItemList`) більше не генерується повторно з `ItemRegistry` під час кожного відкриття інвентарю.
* Вкладки у стилі JEI (або творчого режиму) [За бажанням]. Примітка: вимагає явної підтримки для рендерингу `ItemStack`, інакше використовуються перші дві літери назви обробника.
* Вкладки/обробники завантажуються з конфігураційного CSV-файлу в JAR-архіві (або за бажанням з папки `config`). Для авторів модів доступні IMC-повідомлення з NBT-даними `registerHandlerInfo` та `removeHandlerInfo` для додавання інформації про обробники з використанням тих самих полів, що й у CSV-файлі.
* Пошук за допомогою синтаксису `@[Мод]->[предмет]`. Наприклад: `@Mod.gregtech->iron ingot`.
* Перемикання між режимами рецептів, утиліт та читів за допомогою CTRL + ЛКМ по іконці гайкового ключа.
* Інструменти/предмети з GT5u та інструменти з GT6 тепер мають коректно працювати з функцією накладення та перенесення рецепта.
### Обробник інформаційних сторінок
Хочете додати інформацію про блок чи предмет, не створюючи для нього величезну підказку? Ви можете додати інформацію про будь-який блок чи предмет, зареєструвавши його в обробнику інформації.
Інформаційні сторінки відображаються під час пошуку рецептів або способів використання відповідного предмета. Усі відповідні предмети будуть циклічно змінюватися у верхній частині інформаційної сторінки.
Ваш мод може викликати:
```java
FMLInterModComms.sendMessage("NotEnoughItems", "addItemInfo", nbt);
```
Де `nbt` — це `NBTTagCompound`, відформатований, як описано нижче.
| Тег | Тип | Опис |
|------------------|--------------------------------|----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| `filter` | `String` | Текстовий фільтр для визначення предметів, для яких має відображатися ця інформаційна сторінка.<br/>Можна використовувати `modname:itemname`, метадані, теги OreDictionary та регулярні вирази. Повний формат можна переглянути у `config/NEI/collapsibleitems.cfg`. |
| `page` / `pages` | `String` / `String NBTTagList` | Безпосередньо текст для відображення. Різницю між одно- та багатосторінковими повідомленнями див. нижче.<br/>Обидва формати підтримують автоматичний переклад наданих рядків. |
#### Односторінковий формат
Використовуйте текстовий тег `"page"`, якщо хочете додати лише одну сторінку інформації:
```java
NBTTagCompound tag = new NBTTagCompound();
tag.setString("filter", "minecraft:log 3");
tag.setString("page", "Exotic wood found in tropical climates.");
FMLInterModComms.sendMessage("NotEnoughItems", "addItemInfo", tag);
```
#### Багатосторінковий формат
Використовуйте тег `"pages"` як `NBTTagList` із рядків, якщо потрібно додати понад одну сторінку:
```java
NBTTagCompound tag = new NBTTagCompound();
tag.setString("filter", "minecraft:diamond_sword");
NBTTagList pages = new NBTTagList();
pages.appendTag(new NBTTagString("A powerful melee weapon."));
pages.appendTag(new NBTTagString("Can be enchanted for extra effects."));
tag.setTag("pages", pages);
FMLInterModComms.sendMessage("NotEnoughItems", "addItemInfo", tag);
```
* Кожен елемент списку — це одна сторінка.
* Сторінки з’являтимуться в NEI з кнопками для їх гортання.
#### Відповідність предметів
Усі предмети, що відповідають фільтру `filter`, відображатимуть вашу інформаційну сторінку. Повний формат фільтра див. у `config/NEI/collapsibleitems.cfg`.
#### Файл конфігурації інформації про предмети
Якщо ви творець збірки модів і хочете створити власні інформаційні сторінки для предметів, їх можна легко додати у файлі `config/NEI/informationpages.cfg`, де також наведено ще кілька прикладів.
## Інші примітки:
* Вилучено стиль TMI
* Вилучено збереження/завантаження стану інвентарю
## Ліцензія
Авторські права на модифікації від команди GTNH (c) 2019-2024 належать mitchej123 та команді GTNH.
Поширюється за ліцензією LGPL-3.0 або новішої версії — використовуйте цей код на власний розсуд, але, будь ласка, діліться з розробниками будь-якими внесеними вами змінами.
Окремі частини коду натхненні, запозичені або бекпортовані з [JEI](https://github.com/mezz/JustEnoughItems/tree/1.12) за ліцензією MIT.
Авторські права на оригінальний код (c) 2014-2015 належать mezz; код поширювався за ліцензією MIT.
+29
View File
@@ -0,0 +1,29 @@
compileJava {
options.encoding = "UTF-8"
}
generateGrammarSource {
maxHeapSize = "128m"
arguments += ['-package', 'codechicken.nei.search', '-visitor', '-no-listener']
outputDirectory = file("${projectDir}/build/generated/sources/search/antlr/codechicken/nei/search/")
}
compileJava.dependsOn generateGrammarSource
sourcesJar.dependsOn generateGrammarSource
sourcesJar {
duplicatesStrategy = DuplicatesStrategy.EXCLUDE
}
sourceSets {
main {
java.srcDirs += ["build/generated/sources/search/antlr/"]
}
}
test {
useJUnitPlatform()
testLogging {
events "passed", "skipped", "failed"
}
}
+3 -161
View File
@@ -1,164 +1,6 @@
buildscript {
repositories {
mavenCentral()
jcenter()
maven {
name = "gt"
url = "https://gregtech.overminddl1.com/"
}
maven {
name = "forge"
url = "http://files.minecraftforge.net/maven"
}
maven {
name = "jitpack"
url = "https://jitpack.io"
}
}
dependencies {
classpath "com.github.GTNH2:ForgeGradle:FG_1.2-SNAPSHOT"
}
}
//version: 1707058017
plugins {
id("org.ajoberstar.grgit") version("3.1.1")
id 'antlr'
id 'com.gtnewhorizons.gtnhconvention'
}
//add dependency repositories
repositories {
maven {
name = "chickenbones"
url = "http://chickenbones.net/maven"
}
}
apply plugin: "java"
apply plugin: "idea"
apply plugin: 'forge'
idea {
module {
inheritOutputDirs = true
downloadJavadoc = true
downloadSources = true
}
}
java {
sourceCompatibility = JavaVersion.VERSION_1_8
targetCompatibility = JavaVersion.VERSION_1_8
}
group = "codechicken"
archivesBaseName = "NotEnoughItems"
// Define properties file
ext.configFile = file "build.properties"
configFile.withReader {
// Load config. It shall from now be referenced as simply config or project.config
def prop = new Properties()
prop.load(it)
project.ext.config = new ConfigSlurper().parse prop
}
//
//configurations.all {
// resolutionStrategy.cacheChangingModulesFor(0, TimeUnit.SECONDS)
// setTransitive(false)
//}
configurations {
shade
compile.extendsFrom shade
}
dependencies {
compile "codechicken:CodeChickenLib:${config.mc_version}-${config.ccl_version}:dev"
compile "codechicken:CodeChickenCore:${config.mc_version}-${config.ccc_version}:dev"
shade "org.apache.commons:commons-csv:1.5"
}
version = "${project.config.mod_version}"
println config.mc_version + "-" + config.forge_version
// Setup the forge minecraft plugin data. Specify the preferred forge/minecraft version here
minecraft {
version = config.mc_version + "-" + config.forge_version
}
def root = project.projectDir;
sourceSets {
main {
java {
srcDir new File(root, "src")
}
resources {
srcDir new File(root, "resources")
}
}
}
processResources {
//redo task if any of these properties change
inputs.property "version", project.version
inputs.property "mc_version", config.mc_version
// Replace properties in info files
from(sourceSets.main.resources.srcDirs) {
include '*.info'
expand 'version':project.version,'mc_version':config.mc_version
}
// Move access transformer to META-INF
rename '(.+_at.cfg)', 'META-INF/$1'
//
// // copy everything else, that's not the mcmod.info
// from(sourceSets.main.resources.srcDirs) {
// exclude "mcmod.info"
// }
}
version = "${project.minecraft.version}-${project.version}"
def commonManifest = {
attributes 'FMLCorePlugin': 'codechicken.nei.asm.NEICorePlugin'
attributes 'FMLAT': 'nei_at.cfg'
}
jar {
getArchiveClassifier().set("universal")
manifest commonManifest
configurations.shade.each { dep ->
from(project.zipTree(dep)){
exclude 'META-INF', 'META-INF/**'
}
}
}
task sourceJar(type: Jar) {
from sourceSets.main.java
from new File(root, "dev")
getArchiveClassifier().set("src")
}
task devJar(type: Jar) {
from sourceSets.main.output
getArchiveClassifier().set("dev")
manifest commonManifest
configurations.shade.each { dep ->
from(project.zipTree(dep)){
exclude 'META-INF', 'META-INF/**'
}
}
}
// Tell the artifact system about our extra jars
artifacts {
archives sourceJar, devJar
}
minecraft {
srgExtra "PK: org/apache/commons/csv nei/org/apache/commons/csv"
srgExtra "PK: org/apache/commons/csv/CSVFormat nei/org/apache/commons/csv/CSVFormat"
}
-5
View File
@@ -1,5 +0,0 @@
mc_version=1.7.10
forge_version=10.13.4.1614-1.7.10
ccl_version=1.1.3.138
ccc_version=1.0.7.+
mod_version=2.1.9-GTNH
+42
View File
@@ -0,0 +1,42 @@
// Add your dependencies here
configurations.create('gtnhlibEmbed') {
canBeConsumed = false
canBeResolved = true
}
dependencies {
api('com.github.GTNewHorizons:CodeChickenCore:1.4.22:dev')
devOnlyNonPublishable('com.github.GTNewHorizons:GTNHLib:0.11.54:dev')
shadowImplementation('org.apache.commons:commons-csv:1.10.0')
compileOnly('maven.modrinth:forge-essentials:7.5.1')
compileOnly('com.cardinalstar.cubicchunks:CubicChunks1710:v0.1.14-alpha:dev')
antlr('org.antlr:antlr4:4.13.2')
shadowImplementation('org.antlr:antlr4-runtime:4.13.2')
testImplementation(platform('org.junit:junit-bom:5.13.4'))
testImplementation('org.junit.jupiter:junit-jupiter')
testImplementation("org.mockito:mockito-core:5.+")
testRuntimeOnly('org.junit.platform:junit-platform-launcher')
testRuntimeOnly("org.lwjgl.lwjgl:lwjgl:2.9.3");
compileOnly("com.github.GTNewHorizons:GTNHLib:0.11.54") { transitive = false }
gtnhlibEmbed("com.github.GTNewHorizons:GTNHLib:0.11.54") { transitive = false }
}
def embedArchiveOperations = gtnhGradle.archiveOperations
def gtnhlibEmbedContents = configurations.gtnhlibEmbed.elements.map { files ->
files.collect { embedArchiveOperations.zipTree(it.asFile) }
}
[tasks.jar, tasks.shadowJar].each {
it.configure {
from(gtnhlibEmbedContents) {
include 'com/gtnewhorizon/gtnhlib/color/ColorResource.class'
include 'com/gtnewhorizon/gtnhlib/color/ColorResource$*.class'
}
}
}
@@ -1,808 +0,0 @@
package net.minecraft.client.gui.inventory;
import codechicken.nei.guihook.GuiContainerManager;
import cpw.mods.fml.relauncher.Side;
import cpw.mods.fml.relauncher.SideOnly;
import java.util.HashSet;
import java.util.Iterator;
import java.util.Set;
import net.minecraft.client.Minecraft;
import net.minecraft.client.gui.FontRenderer;
import net.minecraft.client.gui.GuiScreen;
import net.minecraft.client.renderer.OpenGlHelper;
import net.minecraft.client.renderer.RenderHelper;
import net.minecraft.client.renderer.texture.TextureMap;
import net.minecraft.entity.player.InventoryPlayer;
import net.minecraft.inventory.Container;
import net.minecraft.inventory.Slot;
import net.minecraft.item.ItemStack;
import net.minecraft.util.EnumChatFormatting;
import net.minecraft.util.IIcon;
import net.minecraft.util.MathHelper;
import net.minecraft.util.ResourceLocation;
import org.lwjgl.input.Keyboard;
import org.lwjgl.opengl.GL11;
import org.lwjgl.opengl.GL12;
@SideOnly(Side.CLIENT)
public abstract class GuiContainer extends GuiScreen
{
protected static final ResourceLocation field_147001_a = new ResourceLocation("textures/gui/container/inventory.png");
/** The X size of the inventory window in pixels. */
public int xSize = 176;
/** The Y size of the inventory window in pixels. */
public int ySize = 166;
/** A list of the players inventory slots */
public Container inventorySlots;
/**
* Starting X position for the Gui. Inconsistent use for Gui backgrounds.
*/
public int guiLeft;
/**
* Starting Y position for the Gui. Inconsistent use for Gui backgrounds.
*/
public int guiTop;
private Slot theSlot;
/** Used when touchscreen is enabled. */
private Slot clickedSlot;
/** Used when touchscreen is enabled. */
private boolean isRightMouseClick;
/** Used when touchscreen is enabled */
private ItemStack draggedStack;
private int field_147011_y;
private int field_147010_z;
private Slot returningStackDestSlot;
private long returningStackTime;
/** Used when touchscreen is enabled */
private ItemStack returningStack;
private Slot field_146985_D;
private long field_146986_E;
protected final Set field_147008_s = new HashSet();
protected boolean field_147007_t;
private int field_146987_F;
private int field_146988_G;
private boolean field_146995_H;
private int field_146996_I;
private long field_146997_J;
private Slot field_146998_K;
private int field_146992_L;
private boolean field_146993_M;
private ItemStack field_146994_N;
private static final String __OBFID = "CL_00000737";
public GuiContainerManager manager;
public GuiContainer(Container par1Container)
{
this.inventorySlots = par1Container;
this.field_146995_H = true;
}
/**
* Adds the buttons (and other controls) to the screen in question.
*/
public void initGui()
{
super.initGui();
this.mc.thePlayer.openContainer = this.inventorySlots;
this.guiLeft = (this.width - this.xSize) / 2;
this.guiTop = (this.height - this.ySize) / 2;
}
/**
* Draws the screen and all the components in it.
*/
public void drawScreen(int par1, int par2, float par3)
{
manager.preDraw();
this.drawDefaultBackground();
int k = this.guiLeft;
int l = this.guiTop;
this.drawGuiContainerBackgroundLayer(par3, par1, par2);
GL11.glDisable(GL12.GL_RESCALE_NORMAL);
RenderHelper.disableStandardItemLighting();
GL11.glDisable(GL11.GL_LIGHTING);
GL11.glDisable(GL11.GL_DEPTH_TEST);
super.drawScreen(par1, par2, par3);
RenderHelper.enableGUIStandardItemLighting();
GL11.glPushMatrix();
GL11.glTranslatef((float)k, (float)l, 0.0F);
GL11.glColor4f(1.0F, 1.0F, 1.0F, 1.0F);
GL11.glEnable(GL12.GL_RESCALE_NORMAL);
this.theSlot = null;
short short1 = 240;
short short2 = 240;
OpenGlHelper.setLightmapTextureCoords(OpenGlHelper.lightmapTexUnit, (float)short1 / 1.0F, (float)short2 / 1.0F);
GL11.glColor4f(1.0F, 1.0F, 1.0F, 1.0F);
int k1;
for (int i1 = 0; i1 < this.inventorySlots.inventorySlots.size(); ++i1)
{
Slot slot = (Slot)this.inventorySlots.inventorySlots.get(i1);
this.func_146977_a(slot);
if (this.isMouseOverSlot(slot, par1, par2) && slot.func_111238_b() && !manager.objectUnderMouse(par1, par2))
{
this.theSlot = slot;
GL11.glDisable(GL11.GL_LIGHTING);
GL11.glDisable(GL11.GL_DEPTH_TEST);
int j1 = slot.xDisplayPosition;
k1 = slot.yDisplayPosition;
GL11.glColorMask(true, true, true, false);
this.drawGradientRect(j1, k1, j1 + 16, k1 + 16, -2130706433, -2130706433);
GL11.glColorMask(true, true, true, true);
GL11.glEnable(GL11.GL_LIGHTING);
GL11.glEnable(GL11.GL_DEPTH_TEST);
}
}
//Forge: Force lighting to be disabled as there are some issue where lighting would
//incorrectly be applied based on items that are in the inventory.
GL11.glDisable(GL11.GL_LIGHTING);
this.drawGuiContainerForegroundLayer(par1, par2);
GL11.glEnable(GL11.GL_LIGHTING);
manager.renderObjects(par1, par2);
InventoryPlayer inventoryplayer = this.mc.thePlayer.inventory;
ItemStack itemstack = this.draggedStack == null ? inventoryplayer.getItemStack() : this.draggedStack;
if (itemstack != null)
{
byte b0 = 8;
k1 = this.draggedStack == null ? 8 : 16;
String s = null;
if (this.draggedStack != null && this.isRightMouseClick)
{
itemstack = itemstack.copy();
itemstack.stackSize = MathHelper.ceiling_float_int((float)itemstack.stackSize / 2.0F);
}
else if (this.field_147007_t && this.field_147008_s.size() > 1)
{
itemstack = itemstack.copy();
itemstack.stackSize = this.field_146996_I;
if (itemstack.stackSize == 0)
{
s = "" + EnumChatFormatting.YELLOW + "0";
}
}
this.drawItemStack(itemstack, par1 - k - b0, par2 - l - k1, s);
}
if (this.returningStack != null)
{
float f1 = (float)(Minecraft.getSystemTime() - this.returningStackTime) / 100.0F;
if (f1 >= 1.0F)
{
f1 = 1.0F;
this.returningStack = null;
}
k1 = this.returningStackDestSlot.xDisplayPosition - this.field_147011_y;
int j2 = this.returningStackDestSlot.yDisplayPosition - this.field_147010_z;
int l1 = this.field_147011_y + (int)((float)k1 * f1);
int i2 = this.field_147010_z + (int)((float)j2 * f1);
this.drawItemStack(this.returningStack, l1, i2, (String)null);
}
GL11.glPopMatrix();
/*
if (inventoryplayer.getItemStack() == null && this.theSlot != null && this.theSlot.getHasStack())
{
ItemStack itemstack1 = this.theSlot.getStack();
this.renderToolTip(itemstack1, par1, par2);
}
*/
manager.renderToolTips(par1, par2);
GL11.glEnable(GL11.GL_LIGHTING);
GL11.glEnable(GL11.GL_DEPTH_TEST);
RenderHelper.enableStandardItemLighting();
}
private void drawItemStack(ItemStack p_146982_1_, int p_146982_2_, int p_146982_3_, String p_146982_4_)
{
GL11.glTranslatef(0.0F, 0.0F, 32.0F);
this.zLevel = 500.0F;
itemRender.zLevel = 500.0F;
FontRenderer font = null;
if (p_146982_1_ != null) font = p_146982_1_.getItem().getFontRenderer(p_146982_1_);
if (font == null) font = fontRendererObj;
itemRender.renderItemAndEffectIntoGUI(font, this.mc.getTextureManager(), p_146982_1_, p_146982_2_, p_146982_3_);
itemRender.renderItemOverlayIntoGUI(font, this.mc.getTextureManager(), p_146982_1_, p_146982_2_, p_146982_3_ - (this.draggedStack == null ? 0 : 8), p_146982_4_);
this.zLevel = 0.0F;
itemRender.zLevel = 0.0F;
}
/**
* Draw the foreground layer for the GuiContainer (everything in front of the items)
*/
protected void drawGuiContainerForegroundLayer(int p_146979_1_, int p_146979_2_) {}
protected abstract void drawGuiContainerBackgroundLayer(float var1, int var2, int var3);
private void func_146977_a(Slot p_146977_1_)
{
int i = p_146977_1_.xDisplayPosition;
int j = p_146977_1_.yDisplayPosition;
ItemStack itemstack = p_146977_1_.getStack();
boolean flag = false;
boolean flag1 = p_146977_1_ == this.clickedSlot && this.draggedStack != null && !this.isRightMouseClick;
ItemStack itemstack1 = this.mc.thePlayer.inventory.getItemStack();
String s = null;
if (p_146977_1_ == this.clickedSlot && this.draggedStack != null && this.isRightMouseClick && itemstack != null)
{
itemstack = itemstack.copy();
itemstack.stackSize /= 2;
}
else if (this.field_147007_t && this.field_147008_s.contains(p_146977_1_) && itemstack1 != null)
{
if (this.field_147008_s.size() == 1)
{
return;
}
if (Container.func_94527_a(p_146977_1_, itemstack1, true) && this.inventorySlots.canDragIntoSlot(p_146977_1_))
{
itemstack = itemstack1.copy();
flag = true;
Container.func_94525_a(this.field_147008_s, this.field_146987_F, itemstack, p_146977_1_.getStack() == null ? 0 : p_146977_1_.getStack().stackSize);
if (itemstack.stackSize > itemstack.getMaxStackSize())
{
s = EnumChatFormatting.YELLOW + "" + itemstack.getMaxStackSize();
itemstack.stackSize = itemstack.getMaxStackSize();
}
if (itemstack.stackSize > p_146977_1_.getSlotStackLimit())
{
s = EnumChatFormatting.YELLOW + "" + p_146977_1_.getSlotStackLimit();
itemstack.stackSize = p_146977_1_.getSlotStackLimit();
}
}
else
{
this.field_147008_s.remove(p_146977_1_);
this.func_146980_g();
}
}
this.zLevel = 100.0F;
itemRender.zLevel = 100.0F;
if (itemstack == null)
{
IIcon iicon = p_146977_1_.getBackgroundIconIndex();
if (iicon != null)
{
GL11.glDisable(GL11.GL_LIGHTING);
this.mc.getTextureManager().bindTexture(TextureMap.locationItemsTexture);
this.drawTexturedModelRectFromIcon(i, j, iicon, 16, 16);
GL11.glEnable(GL11.GL_LIGHTING);
flag1 = true;
}
}
if (!flag1)
{
if (flag)
{
drawRect(i, j, i + 16, j + 16, -2130706433);
}
GL11.glEnable(GL11.GL_DEPTH_TEST);
manager.renderSlotUnderlay(p_146977_1_);
manager.drawSlotItem(p_146977_1_, itemstack, i, j, s);
manager.renderSlotOverlay(p_146977_1_);
}
itemRender.zLevel = 0.0F;
this.zLevel = 0.0F;
}
private void func_146980_g()
{
ItemStack itemstack = this.mc.thePlayer.inventory.getItemStack();
if (itemstack != null && this.field_147007_t)
{
this.field_146996_I = itemstack.stackSize;
ItemStack itemstack1;
int i;
for (Iterator iterator = this.field_147008_s.iterator(); iterator.hasNext(); this.field_146996_I -= itemstack1.stackSize - i)
{
Slot slot = (Slot)iterator.next();
itemstack1 = itemstack.copy();
i = slot.getStack() == null ? 0 : slot.getStack().stackSize;
Container.func_94525_a(this.field_147008_s, this.field_146987_F, itemstack1, i);
if (itemstack1.stackSize > itemstack1.getMaxStackSize())
{
itemstack1.stackSize = itemstack1.getMaxStackSize();
}
if (itemstack1.stackSize > slot.getSlotStackLimit())
{
itemstack1.stackSize = slot.getSlotStackLimit();
}
}
}
}
/**
* Returns the slot at the given coordinates or null if there is none.
*/
public Slot getSlotAtPosition(int p_146975_1_, int p_146975_2_)
{
for (int k = 0; k < this.inventorySlots.inventorySlots.size(); ++k)
{
Slot slot = (Slot)this.inventorySlots.inventorySlots.get(k);
if (this.isMouseOverSlot(slot, p_146975_1_, p_146975_2_))
{
return slot;
}
}
return null;
}
/**
* Called when the mouse is clicked.
*/
protected void mouseClicked(int par1, int par2, int par3)
{
if (manager.mouseClicked(par1, par2, par3))
return;
super.mouseClicked(par1, par2, par3);
boolean flag = par3 == this.mc.gameSettings.keyBindPickBlock.getKeyCode() + 100;
Slot slot = this.getSlotAtPosition(par1, par2);
long l = Minecraft.getSystemTime();
this.field_146993_M = this.field_146998_K == slot && l - this.field_146997_J < 250L && this.field_146992_L == par3;
this.field_146995_H = false;
if (par3 == 0 || par3 == 1 || flag)
{
int i1 = this.guiLeft;
int j1 = this.guiTop;
boolean flag1 = par1 < i1 || par2 < j1 || par1 >= i1 + this.xSize || par2 >= j1 + this.ySize;
int k1 = -1;
if (slot != null)
{
k1 = slot.slotNumber;
}
if (flag1)
{
k1 = -999;
}
if (this.mc.gameSettings.touchscreen && flag1 && this.mc.thePlayer.inventory.getItemStack() == null)
{
this.mc.displayGuiScreen((GuiScreen)null);
return;
}
if (k1 != -1)
{
if (this.mc.gameSettings.touchscreen)
{
if (slot != null && slot.getHasStack())
{
this.clickedSlot = slot;
this.draggedStack = null;
this.isRightMouseClick = par3 == 1;
}
else
{
this.clickedSlot = null;
}
}
else if (!this.field_147007_t)
{
if (this.mc.thePlayer.inventory.getItemStack() == null)
{
if (par3 == this.mc.gameSettings.keyBindPickBlock.getKeyCode() + 100)
{
managerHandleMouseClick(slot, k1, par3, 3);
}
else
{
boolean flag2 = k1 != -999 && (Keyboard.isKeyDown(42) || Keyboard.isKeyDown(54));
byte b0 = 0;
if (flag2)
{
this.field_146994_N = slot != null && slot.getHasStack() ? slot.getStack() : null;
b0 = 1;
}
else if (k1 == -999)
{
b0 = 4;
}
managerHandleMouseClick(slot, k1, par3, b0);
}
this.field_146995_H = true;
}
else
{
this.field_147007_t = true;
this.field_146988_G = par3;
this.field_147008_s.clear();
if (par3 == 0)
{
this.field_146987_F = 0;
}
else if (par3 == 1)
{
this.field_146987_F = 1;
}
}
}
}
}
this.field_146998_K = slot;
this.field_146997_J = l;
this.field_146992_L = par3;
}
/**
* Called when a mouse button is pressed and the mouse is moved around. Parameters are : mouseX, mouseY,
* lastButtonClicked & timeSinceMouseClick.
*/
protected void mouseClickMove(int p_146273_1_, int p_146273_2_, int p_146273_3_, long p_146273_4_)
{
Slot slot = this.getSlotAtPosition(p_146273_1_, p_146273_2_);
ItemStack itemstack = this.mc.thePlayer.inventory.getItemStack();
manager.mouseDragged(p_146273_1_, p_146273_2_, p_146273_3_, p_146273_4_);
if (this.clickedSlot != null && this.mc.gameSettings.touchscreen)
{
if (p_146273_3_ == 0 || p_146273_3_ == 1)
{
if (this.draggedStack == null)
{
if (slot != this.clickedSlot)
{
this.draggedStack = this.clickedSlot.getStack().copy();
}
}
else if (this.draggedStack.stackSize > 1 && slot != null && Container.func_94527_a(slot, this.draggedStack, false))
{
long i1 = Minecraft.getSystemTime();
if (this.field_146985_D == slot)
{
if (i1 - this.field_146986_E > 500L)
{
managerHandleMouseClick(this.clickedSlot, this.clickedSlot.slotNumber, 0, 0);
managerHandleMouseClick(slot, slot.slotNumber, 1, 0);
managerHandleMouseClick(this.clickedSlot, this.clickedSlot.slotNumber, 0, 0);
this.field_146986_E = i1 + 750L;
--this.draggedStack.stackSize;
}
}
else
{
this.field_146985_D = slot;
this.field_146986_E = i1;
}
}
}
}
else if (this.field_147007_t && slot != null && itemstack != null && itemstack.stackSize > this.field_147008_s.size() && Container.func_94527_a(slot, itemstack, true) && slot.isItemValid(itemstack) && this.inventorySlots.canDragIntoSlot(slot))
{
this.field_147008_s.add(slot);
this.func_146980_g();
}
}
/**
* Called when the mouse is moved or a mouse button is released. Signature: (mouseX, mouseY, which) which==-1 is
* mouseMove, which==0 or which==1 is mouseUp
*/
protected void mouseMovedOrUp(int p_146286_1_, int p_146286_2_, int p_146286_3_)
{
if(manager.overrideMouseUp(p_146286_1_, p_146286_2_, p_146286_3_))
return;
Slot slot = this.getSlotAtPosition(p_146286_1_, p_146286_2_);
int l = this.guiLeft;
int i1 = this.guiTop;
boolean flag = p_146286_1_ < l || p_146286_2_ < i1 || p_146286_1_ >= l + this.xSize || p_146286_2_ >= i1 + this.ySize;
int j1 = -1;
if (slot != null)
{
j1 = slot.slotNumber;
}
if (flag)
{
j1 = -999;
}
Slot slot1;
Iterator iterator;
if (this.field_146993_M && slot != null && p_146286_3_ == 0 && this.inventorySlots.func_94530_a((ItemStack)null, slot))
{
if (isShiftKeyDown())
{
if (slot != null && slot.inventory != null && this.field_146994_N != null)
{
iterator = this.inventorySlots.inventorySlots.iterator();
while (iterator.hasNext())
{
slot1 = (Slot)iterator.next();
if (slot1 != null && slot1.canTakeStack(this.mc.thePlayer) && slot1.getHasStack() && slot1.inventory == slot.inventory && Container.func_94527_a(slot1, this.field_146994_N, true))
{
managerHandleMouseClick(slot1, slot1.slotNumber, p_146286_3_, 1);
}
}
}
}
else
{
managerHandleMouseClick(slot, j1, p_146286_3_, 6);
}
this.field_146993_M = false;
this.field_146997_J = 0L;
}
else
{
if (this.field_147007_t && this.field_146988_G != p_146286_3_)
{
this.field_147007_t = false;
this.field_147008_s.clear();
this.field_146995_H = true;
return;
}
if (this.field_146995_H)
{
this.field_146995_H = false;
return;
}
boolean flag1;
if (this.clickedSlot != null && this.mc.gameSettings.touchscreen)
{
if (p_146286_3_ == 0 || p_146286_3_ == 1)
{
if (this.draggedStack == null && slot != this.clickedSlot)
{
this.draggedStack = this.clickedSlot.getStack();
}
flag1 = Container.func_94527_a(slot, this.draggedStack, false);
if (j1 != -1 && this.draggedStack != null && flag1)
{
managerHandleMouseClick(this.clickedSlot, this.clickedSlot.slotNumber, p_146286_3_, 0);
managerHandleMouseClick(slot, j1, 0, 0);
if (this.mc.thePlayer.inventory.getItemStack() != null)
{
managerHandleMouseClick(this.clickedSlot, this.clickedSlot.slotNumber, p_146286_3_, 0);
this.field_147011_y = p_146286_1_ - l;
this.field_147010_z = p_146286_2_ - i1;
this.returningStackDestSlot = this.clickedSlot;
this.returningStack = this.draggedStack;
this.returningStackTime = Minecraft.getSystemTime();
}
else
{
this.returningStack = null;
}
}
else if (this.draggedStack != null)
{
this.field_147011_y = p_146286_1_ - l;
this.field_147010_z = p_146286_2_ - i1;
this.returningStackDestSlot = this.clickedSlot;
this.returningStack = this.draggedStack;
this.returningStackTime = Minecraft.getSystemTime();
}
this.draggedStack = null;
this.clickedSlot = null;
}
}
else if (this.field_147007_t && !this.field_147008_s.isEmpty())
{
managerHandleMouseClick((Slot)null, -999, Container.func_94534_d(0, this.field_146987_F), 5);
iterator = this.field_147008_s.iterator();
while (iterator.hasNext())
{
slot1 = (Slot)iterator.next();
managerHandleMouseClick(slot1, slot1.slotNumber, Container.func_94534_d(1, this.field_146987_F), 5);
}
managerHandleMouseClick((Slot)null, -999, Container.func_94534_d(2, this.field_146987_F), 5);
}
else if (this.mc.thePlayer.inventory.getItemStack() != null)
{
if (p_146286_3_ == this.mc.gameSettings.keyBindPickBlock.getKeyCode() + 100)
{
managerHandleMouseClick(slot, j1, p_146286_3_, 3);
}
else
{
flag1 = j1 != -999 && (Keyboard.isKeyDown(42) || Keyboard.isKeyDown(54));
if (flag1)
{
this.field_146994_N = slot != null && slot.getHasStack() ? slot.getStack() : null;
}
managerHandleMouseClick(slot, j1, p_146286_3_, flag1 ? 1 : 0);
}
}
else if(p_146286_3_ >= 0)
manager.mouseUp(p_146286_1_, p_146286_2_, p_146286_3_);
}
if (this.mc.thePlayer.inventory.getItemStack() == null)
{
this.field_146997_J = 0L;
}
this.field_147007_t = false;
}
/**
* Returns if the passed mouse position is over the specified slot.
*/
private boolean isMouseOverSlot(Slot p_146981_1_, int p_146981_2_, int p_146981_3_)
{
return this.func_146978_c(p_146981_1_.xDisplayPosition, p_146981_1_.yDisplayPosition, 16, 16, p_146981_2_, p_146981_3_);
}
protected boolean func_146978_c(int p_146978_1_, int p_146978_2_, int p_146978_3_, int p_146978_4_, int p_146978_5_, int p_146978_6_)
{
int k1 = this.guiLeft;
int l1 = this.guiTop;
p_146978_5_ -= k1;
p_146978_6_ -= l1;
return p_146978_5_ >= p_146978_1_ - 1 && p_146978_5_ < p_146978_1_ + p_146978_3_ + 1 && p_146978_6_ >= p_146978_2_ - 1 && p_146978_6_ < p_146978_2_ + p_146978_4_ + 1;
}
protected void handleMouseClick(Slot p_146984_1_, int p_146984_2_, int p_146984_3_, int p_146984_4_)
{
if (p_146984_1_ != null)
{
p_146984_2_ = p_146984_1_.slotNumber;
}
manager.handleSlotClick(p_146984_2_, p_146984_3_, p_146984_4_);
}
/**
* Fired when a key is typed. This is the equivalent of KeyListener.keyTyped(KeyEvent e).
*/
protected void keyTyped(char par1, int par2)
{
if(manager.lastKeyTyped(par2, par1))
return;
if (par2 == 1 || par2 == this.mc.gameSettings.keyBindInventory.getKeyCode())
{
this.mc.thePlayer.closeScreen();
}
this.checkHotbarKeys(par2);
if (this.theSlot != null && this.theSlot.getHasStack())
{
if (par2 == this.mc.gameSettings.keyBindPickBlock.getKeyCode())
{
managerHandleMouseClick(this.theSlot, this.theSlot.slotNumber, 0, 3);
}
else if (par2 == this.mc.gameSettings.keyBindDrop.getKeyCode())
{
managerHandleMouseClick(this.theSlot, this.theSlot.slotNumber, isCtrlKeyDown() ? 1 : 0, 4);
}
}
}
/**
* This function is what controls the hotbar shortcut check when you press a number key when hovering a stack.
*/
protected boolean checkHotbarKeys(int p_146983_1_)
{
if (this.mc.thePlayer.inventory.getItemStack() == null && this.theSlot != null)
{
for (int j = 0; j < 9; ++j)
{
if (p_146983_1_ == this.mc.gameSettings.keyBindsHotbar[j].getKeyCode())
{
managerHandleMouseClick(this.theSlot, this.theSlot.slotNumber, j, 2);
return true;
}
}
}
return false;
}
/**
* Called when the screen is unloaded. Used to disable keyboard repeat events
*/
public void onGuiClosed()
{
if (this.mc.thePlayer != null)
{
this.inventorySlots.onContainerClosed(this.mc.thePlayer);
}
}
/**
* Returns true if this GUI should pause the game when it is displayed in single-player
*/
public boolean doesGuiPauseGame()
{
return false;
}
/**
* Called from the main game loop to update the screen.
*/
public void updateScreen()
{
super.updateScreen();
manager.updateScreen();
if (!this.mc.thePlayer.isEntityAlive() || this.mc.thePlayer.isDead)
{
this.mc.thePlayer.closeScreen();
}
}
public void setWorldAndResolution(Minecraft mc, int i, int j)
{
super.setWorldAndResolution(mc, i, j);
if(mc.currentScreen == this)
{
manager = new GuiContainerManager(this);
manager.load();
}
}
public void handleKeyboardInput()
{
manager.handleKeyboardInput();
}
public void handleMouseInput()
{
super.handleMouseInput();
manager.handleMouseWheel();
}
public void managerHandleMouseClick(Slot slot, int slotIndex, int button, int modifiers)
{
manager.handleMouseClick(slot, slotIndex, button, modifiers);
}
}
+243
View File
@@ -0,0 +1,243 @@
# ExampleMod tag to use as Blowdryer (Spotless, etc.) settings version, leave empty to disable.
# LOCAL to test local config updates.
gtnh.settings.blowdryerTag = 0.2.0
# Human-readable mod name, available for mcmod.info population.
modName = NotEnoughItems
# Case-sensitive identifier string, available for mcmod.info population and used for automatic mixin JSON generation.
# Conventionally lowercase.
modId = NotEnoughItems
# Root package of the mod, used to find various classes in other properties,
# mcmod.info substitution, enabling assertions in run tasks, etc.
modGroup = codechicken.nei
# Whether to use modGroup as the maven publishing group.
# When false, com.github.GTNewHorizons is used.
useModGroupForPublishing = false
# Updates your build.gradle and settings.gradle automatically whenever an update is available.
autoUpdateBuildScript = false
# Version of Minecraft to target
minecraftVersion = 1.7.10
# Version of Minecraft Forge to target
forgeVersion = 10.13.4.1614
# Specify an MCP channel for dependency deobfuscation and the deobfParams task.
channel = stable
# Specify an MCP mappings version for dependency deobfuscation and the deobfParams task.
mappingsVersion = 12
# Defines other MCP mappings for dependency deobfuscation.
remoteMappings = https\://raw.githubusercontent.com/MinecraftForge/FML/1.7.10/conf/
# Select a default username for testing your mod. You can always override this per-run by running
# `./gradlew runClient --username=AnotherPlayer`, or configuring this command in your IDE.
developmentEnvironmentUserName = Developer
# Enables modern Java syntax support. Valid values:
# - false: No modern syntax, Java 8 only
# - jabel: Jabel syntax-only support, compiles to J8 bytecode
# - jvmDowngrader: Full modern Java via JVM Downgrader (syntax + stdlib APIs)
# - modern: Native modern Java bytecode, no downgrading
enableModernJavaSyntax = jabel
# If set, ignores the above setting and compiles with the given toolchain. This may cause unexpected issues,
# and should *not* be used in most situations. -1 disables this.
# forceToolchainVersion = -1
# Target JVM version for JVM Downgrader bytecode downgrading.
# Only used when enableModernJavaSyntax = jvmDowngrader
# downgradeTargetVersion = 8
# Comma-separated list of Java versions for multi-release jar support (JVM Downgrader only).
# Classes will be available in META-INF/versions/N/ for each version N in this list.
# Default: "21,25" (J25+ gets native classes, J21-24 gets partial downgrade, J8-20 gets full downgrade).
# jvmDowngraderMultiReleaseVersions = 21,25
# Specifies how JVM Downgrader API stubs are provided. Options:
# - shade: Shade minimized stubs into the jar
# - gtnhlib: GTNHLib provides stubs at runtime (adds version constraint)
# - external: Another dependency provides stubs (no constraint, no warning)
# - (empty): Warning reminding you to configure stubs
# Note: 'shade' option requires you to verify license compliance, see: https://github.com/unimined/JvmDowngrader/blob/main/LICENSE.md
# jvmDowngraderStubsProvider =
# Enables injecting missing generics into the decompiled source code for a better coding experience.
# Turns most publicly visible List, Map, etc. into proper List<E>, Map<K, V> types.
enableGenericInjection = true
# Generate a class with a String field for the mod version named as defined below.
# If generateGradleTokenClass is empty or not missing, no such class will be generated.
# If gradleTokenVersion is empty or missing, the field will not be present in the class.
generateGradleTokenClass = codechicken.nei.Tags
# Name of the token containing the project's current version to generate/replace.
gradleTokenVersion = VERSION
# [DEPRECATED] Mod ID replacement token.
gradleTokenModId =
# [DEPRECATED] Mod name replacement token.
gradleTokenModName =
# [DEPRECATED] Mod Group replacement token.
gradleTokenGroupName =
# [DEPRECATED]
# Multiple source files can be defined here by providing a comma-separated list: Class1.java,Class2.java,Class3.java
# public static final String VERSION = "GRADLETOKEN_VERSION";
# The string's content will be replaced with your mod's version when compiled. You should use this to specify your mod's
# version in @Mod([...], version = VERSION, [...]).
# Leave these properties empty to skip individual token replacements.
replaceGradleTokenInFile =
# In case your mod provides an API for other mods to implement you may declare its package here. Otherwise, you can
# leave this property empty.
# Example value: (apiPackage = api) + (modGroup = com.myname.mymodid) -> com.myname.mymodid.api
apiPackage =
# Specify the configuration file for Forge's access transformers here. It must be placed into /src/main/resources/META-INF/
# There can be multiple files in a space-separated list.
# Example value: mymodid_at.cfg nei_at.cfg
accessTransformersFile = nei_at.cfg
# Provides setup for Mixins if enabled. If you don't know what mixins are: Keep it disabled!
usesMixins = false
# Set to a non-empty string to configure mixins in a separate source set under src/VALUE, instead of src/main.
# This can speed up compile times thanks to not running the mixin annotation processor on all input sources.
# Mixin classes will have access to "main" classes, but not the other way around.
separateMixinSourceSet =
# Adds some debug arguments like verbose output and class export.
usesMixinDebug = false
# Specify the location of your implementation of IMixinConfigPlugin. Leave it empty otherwise.
mixinPlugin =
# Specify the package that contains all of your Mixins. The package must exist or
# the build will fail. If you have a package property defined in your mixins.<modid>.json,
# it must match with this or the build will fail.
mixinsPackage =
# Specify the core mod entry class if you use a core mod. This class must implement IFMLLoadingPlugin!
# This parameter is for legacy compatibility only
# Example value: (coreModClass = asm.FMLPlugin) + (modGroup = com.myname.mymodid) -> com.myname.mymodid.asm.FMLPlugin
coreModClass = asm.NEICorePlugin
# If your project is only a consolidation of mixins or a core mod and does NOT contain a 'normal' mod ( = some class
# that is annotated with @Mod) you want this to be true. When in doubt: leave it on false!
containsMixinsAndOrCoreModOnly = true
# Enables Mixins even if this mod doesn't use them, useful if one of the dependencies uses mixins.
forceEnableMixins = false
# If enabled, you may use 'shadowCompile' for dependencies. They will be integrated into your jar. It is your
# responsibility to check the license and request permission for distribution if required.
usesShadowedDependencies = true
# If disabled, won't remove unused classes from shadowed dependencies. Some libraries use reflection to access
# their own classes, making the minimization unreliable.
minimizeShadowedDependencies = true
# If disabled, won't rename the shadowed classes.
relocateShadowedDependencies = true
# Adds CurseMaven, Modrinth, and some more well-known 1.7.10 repositories.
includeWellKnownRepositories = true
# A list of repositories to exclude from the includeWellKnownRepositories setting. Should be a space separated
# list of strings, with the acceptable keys being(case does not matter):
# cursemaven
# modrinth
excludeWellKnownRepositories =
# Change these to your Maven coordinates if you want to publish to a custom Maven repository instead of the default GTNH Maven.
# Authenticate with the MAVEN_USER and MAVEN_PASSWORD environment variables.
# If you need a more complex setup disable maven publishing here and add a publishing repository to addon.gradle.
usesMavenPublishing = true
# Maven repository to publish the mod to.
# mavenPublishUrl = https\://nexus.gtnewhorizons.com/repository/releases/
# Publishing to Modrinth requires you to set the MODRINTH_TOKEN environment variable to your current Modrinth API token.
#
# The project's ID on Modrinth. Can be either the slug or the ID.
# Leave this empty if you don't want to publish to Modrinth.
modrinthProjectId = notenoughitems-unofficial
# The project's relations on Modrinth. You can use this to refer to other projects on Modrinth.
# Syntax: scope1-type1:name1;scope2-type2:name2;...
# Where scope can be one of [required, optional, incompatible, embedded],
# type can be one of [project, version],
# and the name is the Modrinth project or version slug/id of the other mod.
# Example: required-project:fplib;optional-project:gasstation;incompatible-project:gregtech
# Note: UniMixins is automatically set as a required dependency if usesMixins = true.
modrinthRelations = required-project\:codechickencore-unofficial
# Publishing to CurseForge requires you to set the CURSEFORGE_TOKEN environment variable to one of your CurseForge API tokens.
#
# The project's numeric ID on CurseForge. You can find this in the About Project box.
# Leave this empty if you don't want to publish on CurseForge.
curseForgeProjectId = 358228
# Comma-separated supported CurseForge environments: client, server (case-insensitive).
# Use client or server for mods that only support one environment. Defaults to client,server.
# These tags describe where the mod can run, not whether installation is required on both sides.
curseForgeEnvironments = client,server
# The project's relations on CurseForge. You can use this to refer to other projects on CurseForge.
# Syntax: type1:name1;type2:name2;...
# Where type can be one of [requiredDependency, embeddedLibrary, optionalDependency, tool, incompatible],
# and the name is the CurseForge project slug of the other mod.
# Example: requiredDependency:railcraft;embeddedLibrary:cofhlib;incompatible:buildcraft
# Note: UniMixins is automatically set as a required dependency if usesMixins = true.
curseForgeRelations = requiredDependency\:codechickencore-unofficial
# Optional parameter to customize the produced artifacts. Use this to preserve artifact naming when migrating older
# projects. New projects should not use this parameter.
# customArchiveBaseName =
# Optional parameter to customize the default working directory used by the runClient* tasks. Relative to the project directory.
# runClientWorkingDirectory = run/client
# Optional parameter to customize the default working directory used by the runServer* tasks. Relative to the project directory.
# runServerWorkingDirectory = run/server
# Optional parameter to have the build automatically fail if an illegal version is used.
# This can be useful if you e.g. only want to allow versions in the form of '1.1.xxx'.
# The check is ONLY performed if the version is a git tag.
# Note: the specified string must be escaped, so e.g. 1\\.1\\.\\d+ instead of 1\.1\.\d+
# versionPattern =
# Uncomment to prevent the source code from being published.
# noPublishedSources = true
# Uncomment this to disable Spotless checks.
# This should only be uncommented to keep it easier to sync with upstream/other forks.
# That is, if there is no other active fork/upstream, NEVER change this.
# disableSpotless = true
# Uncomment this to disable Checkstyle checks (currently wildcard import check).
# disableCheckstyle = true
# Override the IDEA build type. Valid values are: "" (leave blank, do not override), "idea" (force use native IDEA build), "gradle"
# (force use delegated build).
# This is meant to be set in $HOME/.gradle/gradle.properties.
# e.g. add "systemProp.org.gradle.project.ideaOverrideBuildType=idea" will override the build type to be native build.
# WARNING: If you do use this option, it will overwrite whatever you have in your existing projects. This might not be what you want!
# Usually there is no need to uncomment this here as other developers do not necessarily use the same build type as you.
# ideaOverrideBuildType = idea
# Whether IDEA should run spotless checks when pressing the Build button.
# This is meant to be set in $HOME/.gradle/gradle.properties.
# ideaCheckSpotlessOnBuild = true
# Non-GTNH properties
org.gradle.configuration-cache = true
org.gradle.parallel = true
+12
View File
@@ -0,0 +1,12 @@
#This file is generated by updateDaemonJvm
toolchainUrl.FREE_BSD.AARCH64=https\://api.foojay.io/disco/v3.0/ids/539ea72837c6244075f8ee037babc29e/redirect
toolchainUrl.FREE_BSD.X86_64=https\://api.foojay.io/disco/v3.0/ids/876dbbf00bf4ef6190f7da074cee903a/redirect
toolchainUrl.LINUX.AARCH64=https\://api.foojay.io/disco/v3.0/ids/539ea72837c6244075f8ee037babc29e/redirect
toolchainUrl.LINUX.X86_64=https\://api.foojay.io/disco/v3.0/ids/876dbbf00bf4ef6190f7da074cee903a/redirect
toolchainUrl.MAC_OS.AARCH64=https\://api.foojay.io/disco/v3.0/ids/9064f22734b42ac03e85df04b632e167/redirect
toolchainUrl.MAC_OS.X86_64=https\://api.foojay.io/disco/v3.0/ids/4d0277c49991306ac78048580fe34bcf/redirect
toolchainUrl.UNIX.AARCH64=https\://api.foojay.io/disco/v3.0/ids/539ea72837c6244075f8ee037babc29e/redirect
toolchainUrl.UNIX.X86_64=https\://api.foojay.io/disco/v3.0/ids/876dbbf00bf4ef6190f7da074cee903a/redirect
toolchainUrl.WINDOWS.AARCH64=https\://api.foojay.io/disco/v3.0/ids/a9fa3b809e484a1e1ac4308a5dda661a/redirect
toolchainUrl.WINDOWS.X86_64=https\://api.foojay.io/disco/v3.0/ids/aa99913fa6d767d899ffc96082da01ca/redirect
toolchainVersion=25
Binary file not shown.
+5 -1
View File
@@ -1,5 +1,9 @@
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-5.6.4-bin.zip
distributionUrl=https\://services.gradle.org/distributions/gradle-9.7.1-bin.zip
networkTimeout=10000
retries=0
retryBackOffMs=500
validateDistributionUrl=true
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
Vendored
+178 -118
View File
@@ -1,7 +1,7 @@
#!/usr/bin/env sh
#!/bin/sh
#
# Copyright 2015 the original author or authors.
# Copyright © 2015 the original authors.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
@@ -15,80 +15,114 @@
# See the License for the specific language governing permissions and
# limitations under the License.
#
# SPDX-License-Identifier: Apache-2.0
#
##############################################################################
##
## Gradle start up script for UN*X
##
#
# gradlew start up script for POSIX generated by Gradle.
#
# Important for running:
#
# (1) You need a POSIX-compliant shell to run this script. If your /bin/sh is
# noncompliant, but you have some other compliant shell such as ksh or
# bash, then to run this script, type that shell name before the whole
# command line, like:
#
# ksh gradlew
#
# Busybox and similar reduced shells will NOT work, because this script
# requires all of these POSIX shell features:
# * functions;
# * expansions «$var», «${var}», «${var:-default}», «${var+SET}»,
# «${var#prefix}», «${var%suffix}», and «$( cmd )»;
# * compound commands having a testable exit status, especially «case»;
# * various built-in commands including «command», «set», and «ulimit».
#
# Important for patching:
#
# (2) This script targets any POSIX shell, so it avoids extensions provided
# by Bash, Ksh, etc; in particular arrays are avoided.
#
# The "traditional" practice of packing multiple parameters into a
# space-separated string is a well documented source of bugs and security
# problems, so this is (mostly) avoided, by progressively accumulating
# options in "$@", and eventually passing that to Java.
#
# Where the inherited environment variables (DEFAULT_JVM_OPTS, JAVA_OPTS,
# and GRADLE_OPTS) rely on word-splitting, this is performed explicitly;
# see the in-line comments for details.
#
# There are tweaks for specific operating systems such as AIX, CygWin,
# Darwin, MinGW, and NonStop.
#
# (3) This script is generated from the Groovy template
# https://github.com/gradle/gradle/blob/3d91ce3b8caaf77ad09f381f43615b715b53f72c/platforms/jvm/plugins-application/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt
# within the Gradle project.
#
# You can find Gradle at https://github.com/gradle/gradle/.
#
##############################################################################
# Attempt to set APP_HOME
# Resolve links: $0 may be a link
PRG="$0"
# Need this for relative symlinks.
while [ -h "$PRG" ] ; do
ls=`ls -ld "$PRG"`
link=`expr "$ls" : '.*-> \(.*\)$'`
if expr "$link" : '/.*' > /dev/null; then
PRG="$link"
else
PRG=`dirname "$PRG"`"/$link"
fi
app_path=$0
# Need this for daisy-chained symlinks.
while
APP_HOME=${app_path%"${app_path##*/}"} # leaves a trailing /; empty if no leading path
[ -h "$app_path" ]
do
ls=$( ls -ld "$app_path" )
link=${ls#*' -> '}
case $link in #(
/*) app_path=$link ;; #(
*) app_path=$APP_HOME$link ;;
esac
done
SAVED="`pwd`"
cd "`dirname \"$PRG\"`/" >/dev/null
APP_HOME="`pwd -P`"
cd "$SAVED" >/dev/null
APP_NAME="Gradle"
APP_BASE_NAME=`basename "$0"`
# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"'
# This is normally unused
# shellcheck disable=SC2034
APP_BASE_NAME=${0##*/}
# Discard cd standard output in case $CDPATH is set (https://github.com/gradle/gradle/issues/25036)
APP_HOME=$( cd -P "${APP_HOME:-./}" > /dev/null && printf '%s\n' "$PWD" ) || exit
# Use the maximum available, or set MAX_FD != -1 to use that value.
MAX_FD="maximum"
MAX_FD=maximum
warn () {
echo "$*"
}
} >&2
die () {
echo
echo "$*"
echo
exit 1
}
} >&2
# OS specific support (must be 'true' or 'false').
cygwin=false
msys=false
darwin=false
nonstop=false
case "`uname`" in
CYGWIN* )
cygwin=true
;;
Darwin* )
darwin=true
;;
MINGW* )
msys=true
;;
NONSTOP* )
nonstop=true
;;
case "$( uname )" in #(
CYGWIN* ) cygwin=true ;; #(
Darwin* ) darwin=true ;; #(
MSYS* | MINGW* ) msys=true ;; #(
NONSTOP* ) nonstop=true ;;
esac
CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
# Determine the Java command to use to start the JVM.
if [ -n "$JAVA_HOME" ] ; then
if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
# IBM's JDK on AIX uses strange locations for the executables
JAVACMD="$JAVA_HOME/jre/sh/java"
JAVACMD=$JAVA_HOME/jre/sh/java
else
JAVACMD="$JAVA_HOME/bin/java"
JAVACMD=$JAVA_HOME/bin/java
fi
if [ ! -x "$JAVACMD" ] ; then
die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
@@ -97,92 +131,118 @@ Please set the JAVA_HOME variable in your environment to match the
location of your Java installation."
fi
else
JAVACMD="java"
which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
JAVACMD=java
if ! command -v java >/dev/null 2>&1
then
die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
Please set the JAVA_HOME variable in your environment to match the
location of your Java installation."
fi
fi
# Increase the maximum file descriptors if we can.
if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then
MAX_FD_LIMIT=`ulimit -H -n`
if [ $? -eq 0 ] ; then
if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
MAX_FD="$MAX_FD_LIMIT"
fi
ulimit -n $MAX_FD
if [ $? -ne 0 ] ; then
warn "Could not set maximum file descriptor limit: $MAX_FD"
fi
else
warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT"
fi
fi
# For Darwin, add options to specify how the application appears in the dock
if $darwin; then
GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
fi
# For Cygwin or MSYS, switch paths to Windows format before running java
if [ "$cygwin" = "true" -o "$msys" = "true" ] ; then
APP_HOME=`cygpath --path --mixed "$APP_HOME"`
CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
JAVACMD=`cygpath --unix "$JAVACMD"`
# We build the pattern for arguments to be converted via cygpath
ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`
SEP=""
for dir in $ROOTDIRSRAW ; do
ROOTDIRS="$ROOTDIRS$SEP$dir"
SEP="|"
done
OURCYGPATTERN="(^($ROOTDIRS))"
# Add a user-defined pattern to the cygpath arguments
if [ "$GRADLE_CYGPATTERN" != "" ] ; then
OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)"
fi
# Now convert the arguments - kludge to limit ourselves to /bin/sh
i=0
for arg in "$@" ; do
CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -`
CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option
if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition
eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"`
else
eval `echo args$i`="\"$arg\""
fi
i=$((i+1))
done
case $i in
(0) set -- ;;
(1) set -- "$args0" ;;
(2) set -- "$args0" "$args1" ;;
(3) set -- "$args0" "$args1" "$args2" ;;
(4) set -- "$args0" "$args1" "$args2" "$args3" ;;
(5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
(6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
(7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
(8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
(9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
if ! "$cygwin" && ! "$darwin" && ! "$nonstop" ; then
case $MAX_FD in #(
max*)
# In POSIX sh, ulimit -H is undefined. That's why the result is checked to see if it worked.
# shellcheck disable=SC2039,SC3045
MAX_FD=$( ulimit -H -n ) ||
warn "Could not query maximum file descriptor limit"
esac
case $MAX_FD in #(
'' | soft) :;; #(
*)
# In POSIX sh, ulimit -n is undefined. That's why the result is checked to see if it worked.
# shellcheck disable=SC2039,SC3045
ulimit -n "$MAX_FD" ||
warn "Could not set maximum file descriptor limit to $MAX_FD"
esac
fi
# Escape application args
save () {
for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done
echo " "
}
APP_ARGS=$(save "$@")
# Collect all arguments for the java command, stacking in reverse order:
# * args from the command line
# * the main class name
# * -classpath
# * -D...appname settings
# * --module-path (only if needed)
# * DEFAULT_JVM_OPTS, JAVA_OPTS, and GRADLE_OPTS environment variables.
# Collect all arguments for the java command, following the shell quoting and substitution rules
eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS"
# For Cygwin or MSYS, switch paths to Windows format before running java
if "$cygwin" || "$msys" ; then
APP_HOME=$( cygpath --path --mixed "$APP_HOME" )
# by default we should be in the correct project dir, but when run from Finder on Mac, the cwd is wrong
if [ "$(uname)" = "Darwin" ] && [ "$HOME" = "$PWD" ]; then
cd "$(dirname "$0")"
JAVACMD=$( cygpath --unix "$JAVACMD" )
# Now convert the arguments - kludge to limit ourselves to /bin/sh
for arg do
if
case $arg in #(
-*) false ;; # don't mess with options #(
/?*) t=${arg#/} t=/${t%%/*} # looks like a POSIX filepath
[ -e "$t" ] ;; #(
*) false ;;
esac
then
arg=$( cygpath --path --ignore --mixed "$arg" )
fi
# Roll the args list around exactly as many times as the number of
# args, so each arg winds up back in the position where it started, but
# possibly modified.
#
# NB: a `for` loop captures its iteration list before it begins, so
# changing the positional parameters here affects neither the number of
# iterations, nor the values presented in `arg`.
shift # remove old arg
set -- "$@" "$arg" # push replacement arg
done
fi
# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"'
# Collect all arguments for the java command:
# * DEFAULT_JVM_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments,
# and any embedded shellness will be escaped.
# * For example: A user cannot expect ${Hostname} to be expanded, as it is an environment variable and will be
# treated as '${Hostname}' itself on the command line.
set -- \
"-Dorg.gradle.appname=$APP_BASE_NAME" \
-jar "$APP_HOME/gradle/wrapper/gradle-wrapper.jar" \
"$@"
# Stop when "xargs" is not available.
if ! command -v xargs >/dev/null 2>&1
then
die "xargs is not available"
fi
# Use "xargs" to parse quoted args.
#
# With -n1 it outputs one arg per line, with the quotes and backslashes removed.
#
# In Bash we could simply go:
#
# readarray ARGS < <( xargs -n1 <<<"$var" ) &&
# set -- "${ARGS[@]}" "$@"
#
# but POSIX shell has neither arrays nor command substitution, so instead we
# post-process each arg (as a line of input to sed) to backslash-escape any
# character that might be a shell metacharacter, then use eval to reverse
# that process (while maintaining the separation between arguments), and wrap
# the whole thing up as a single "set" statement.
#
# This will of course break if any of these variables contains a newline or
# an unmatched quote.
#
eval "set -- $(
printf '%s\n' "$DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS" |
xargs -n1 |
sed ' s~[^-[:alnum:]+,./:=@_]~\\&~g; ' |
tr '\n' ' '
)" '"$@"'
exec "$JAVACMD" "$@"
Vendored
+32 -50
View File
@@ -13,22 +13,28 @@
@rem See the License for the specific language governing permissions and
@rem limitations under the License.
@rem
@rem SPDX-License-Identifier: Apache-2.0
@rem
@if "%DEBUG%" == "" @echo off
@if "%DEBUG%"=="" @echo off
@rem ##########################################################################
@rem
@rem Gradle startup script for Windows
@rem gradlew startup script for Windows
@rem
@rem ##########################################################################
@rem Set local scope for the variables with windows NT shell
if "%OS%"=="Windows_NT" setlocal
@rem Set local scope for the variables, and ensure extensions are enabled
setlocal EnableExtensions
set DIRNAME=%~dp0
if "%DIRNAME%" == "" set DIRNAME=.
if "%DIRNAME%"=="" set DIRNAME=.
@rem This is normally unused
set APP_BASE_NAME=%~n0
set APP_HOME=%DIRNAME%
@rem Resolve any "." and ".." in APP_HOME to make it shorter.
for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi
@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m"
@@ -37,64 +43,40 @@ if defined JAVA_HOME goto findJavaFromJavaHome
set JAVA_EXE=java.exe
%JAVA_EXE% -version >NUL 2>&1
if "%ERRORLEVEL%" == "0" goto init
if %ERRORLEVEL% equ 0 goto execute
echo.
echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
echo.
echo Please set the JAVA_HOME variable in your environment to match the
echo location of your Java installation.
echo. 1>&2
echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 1>&2
echo. 1>&2
echo Please set the JAVA_HOME variable in your environment to match the 1>&2
echo location of your Java installation. 1>&2
goto fail
"%COMSPEC%" /c exit 1
:findJavaFromJavaHome
set JAVA_HOME=%JAVA_HOME:"=%
set JAVA_EXE=%JAVA_HOME%/bin/java.exe
if exist "%JAVA_EXE%" goto init
if exist "%JAVA_EXE%" goto execute
echo.
echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
echo.
echo Please set the JAVA_HOME variable in your environment to match the
echo location of your Java installation.
echo. 1>&2
echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% 1>&2
echo. 1>&2
echo Please set the JAVA_HOME variable in your environment to match the 1>&2
echo location of your Java installation. 1>&2
goto fail
:init
@rem Get command-line arguments, handling Windows variants
if not "%OS%" == "Windows_NT" goto win9xME_args
:win9xME_args
@rem Slurp the command line arguments.
set CMD_LINE_ARGS=
set _SKIP=2
:win9xME_args_slurp
if "x%~1" == "x" goto execute
set CMD_LINE_ARGS=%*
"%COMSPEC%" /c exit 1
:execute
@rem Setup the command line
set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
@rem Execute Gradle
"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS%
:end
@rem End local scope for the variables with windows NT shell
if "%ERRORLEVEL%"=="0" goto mainEnd
@rem Execute gradlew
@rem endlocal doesn't take effect until after the line is parsed and variables are expanded
@rem which allows us to clear the local environment before executing the java command
endlocal & "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -jar "%APP_HOME%\gradle\wrapper\gradle-wrapper.jar" %* & call :exitWithErrorLevel
:fail
rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
rem the _cmd.exe /c_ return code!
if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
exit /b 1
:mainEnd
if "%OS%"=="Windows_NT" endlocal
:omega
:exitWithErrorLevel
@rem Use "%COMSPEC%" /c exit to allow operators to work properly in scripts
"%COMSPEC%" /c exit %ERRORLEVEL%
+2
View File
@@ -0,0 +1,2 @@
before_install:
- ./gradlew setupCIWorkspace
+8
View File
@@ -0,0 +1,8 @@
// Add any additional repositories for your dependencies here
repositories {
maven {
name = "Modrinth"
url = "https://api.modrinth.com/maven"
}
}
-451
View File
@@ -1,451 +0,0 @@
handler,modName,itemName,nbtInfo,modId,modRequired,excludedModId,yShift,handlerHeight,handlerWidth,maxRecipesPerPage,imageResource,imageX,imageY,imageWidth,imageHeight,itemNotes
codechicken.nei.recipe.BrewingRecipeHandler,Minecraft,minecraft:brewing_stand,,minecraft,FALSE,,,65,166,5,,,,,,
codechicken.nei.recipe.FireworkRecipeHandler,Minecraft,minecraft:fireworks,,minecraft,FALSE,,,65,166,5,,,,,,
codechicken.nei.recipe.FurnaceRecipeHandler,Minecraft,minecraft:furnace,,minecraft,FALSE,,,65,166,5,,,,,,
codechicken.nei.recipe.ShapedRecipeHandler,Minecraft,minecraft:crafting_table,,minecraft,FALSE,,,65,166,5,,,,,,
codechicken.nei.recipe.ShapelessRecipeHandler,Minecraft,minecraft:crafting_table,,minecraft,FALSE,,,65,166,5,,,,,,
codechicken.nei.recipe.FuelRecipeHandler,Minecraft,,,minecraft,FALSE,,,65,166,5,nei:textures/nei_tabbed_sprites.png,80,0,14,14,
advsolar.client.nei.MTRecipeHandler,Advanced Solar Panels,AdvancedSolarPanel:BlockMolecularTransformer,,AdvancedSolarPanel,TRUE,,,68,,5,,,,,,
appeng.integration.modules.NEIHelpers.NEIAEShapedRecipeHandler,Applied Energistics 2,appliedenergistics2:item.ItemMultiPart:380,,appliedenergistics2,TRUE,,,65,,5,,,,,,
appeng.integration.modules.NEIHelpers.NEIAEShapelessRecipeHandler,Applied Energistics 2,appliedenergistics2:item.ItemMultiPart:380,,appliedenergistics2,TRUE,,,65,,5,,,,,,
appeng.integration.modules.NEIHelpers.NEIFacadeRecipeHandler,Applied Energistics 2,appliedenergistics2:item.ItemFacade:192,,appliedenergistics2,TRUE,,,65,,5,,,,,,
appeng.integration.modules.NEIHelpers.NEIGrinderRecipeHandler,Applied Energistics 2,appliedenergistics2:tile.BlockGrinder,,appliedenergistics2,TRUE,,,,,,,,,,,
appeng.integration.modules.NEIHelpers.NEIInscriberRecipeHandler,Applied Energistics 2,appliedenergistics2:tile.BlockInscriber,,appliedenergistics2,TRUE,,,70,,5,,,,,,
appeng.integration.modules.NEIHelpers.NEIWorldCraftingHandler,Applied Energistics 2,appliedenergistics2:item.ItemMultiMaterial:9,,appliedenergistics2,TRUE,,,85,,5,,,,,,There's only some explanatory text for fluix crystals and QEDs
aroma1997.core.recipes.nei.ShapedAromicRecipeHandler,AromaBackup,minecraft:crafting_table,,AromaBackup,TRUE,,,65,,5,,,,,,
aroma1997.core.recipes.nei.ShapelessAromicRecipeHandler,AromaBackup,minecraft:crafting_table,,AromaBackup,TRUE,,,,,,,,,,,
fox.spiteful.avaritia.compat.nei.CompressionHandler,Avaritia,Avaritia:Neutronium_Compressor,,Avaritia,TRUE,,,50,,6,,,,,,
fox.spiteful.avaritia.compat.nei.ExtremeShapedRecipeHandler,Avaritia,Avaritia:Dire_Crafting,,Avaritia,TRUE,,,208,256,1,,,,,,Part of it even goes off the left side (included)
fox.spiteful.avaritia.compat.nei.ExtremeShapelessRecipeHandler,Avaritia,Avaritia:Dire_Crafting,,Avaritia,TRUE,,,208,256,1,,,,,,"If you can cut off/place over the jaggedness at the bottom, you could barely get a second on"
WayofTime.alchemicalWizardry.client.nei.NEIAlchemyRecipeHandler,Blood Magic,AWWayofTime:blockWritingTable,,AWWayofTime,TRUE,,,68,,5,,,,,,
WayofTime.alchemicalWizardry.client.nei.NEIAltarRecipeHandler,Blood Magic,AWWayofTime:Altar,,AWWayofTime,TRUE,,,65,,5,,,,,,Handler name needs shifting left
WayofTime.alchemicalWizardry.client.nei.NEIBindingRitualHandler,Blood Magic,AWWayofTime:sacrificialKnife,,AWWayofTime,TRUE,,,50,,6,,,,,,
WayofTime.alchemicalWizardry.client.nei.NEIBloodOrbShapedHandler,Blood Magic,AWWayofTime:AlchemicalWizardrybloodRune:3,,AWWayofTime,TRUE,,,65,,5,,,,,,
WayofTime.alchemicalWizardry.client.nei.NEIBloodOrbShapelessHandler,Blood Magic,AWWayofTime:AlchemicalWizardrybloodRune:4,,AWWayofTime,TRUE,,,65,,5,,,,,,
bw.fuels.acidgens,BartWorks,gregtech:gt.blockmachines:12726,,bartworks,TRUE,,,145,,2,,,,,,
bw.recipe.cal,BartWorks,gregtech:gt.blockmachines:12735,,bartworks,TRUE,,,135,,2,,,,,,
gg.recipe.naquadah_reactor,Good Generator,gregtech:gt.blockmachines:12732,,GoodGenerator,TRUE,,,145,,1,,,,,,
gg.recipe.naquadah_fuel_refine_factory,Good Generator,gregtech:gt.blockmachines:16999,,GoodGenerator,TRUE,,,145,,1,,,,,,
com.github.bartimaeusnek.bartworks.neiHandler.BW_NEI_BioLabHandler,BartWorks,gregtech:gt.blockmachines:12699,,bartworks,TRUE,,,145,,2,,,,,,
com.github.bartimaeusnek.bartworks.neiHandler.BW_NEI_BioVatHandler,BartWorks,gregtech:gt.blockmachines:12712,,bartworks,TRUE,,,140,,2,,,,,,
com.github.bartimaeusnek.bartworks.neiHandler.BW_NEI_OreHandler,BartWorks,bartworks:bw.blockores.01:89,,bartworks,TRUE,,,135,,2,,,,,,
gt.recipe.electricimplosioncompressor,BartWorks,gregtech:gt.blockmachines:12734,,bartworks,TRUE,,,135,,2,,,,,,
net.bdew.neiaddons.botany.flowers.FlowerBreedingHandler,Botany,Botany:flower,,Botany,TRUE,,,65,,5,,,,,,
buildcraft.compat.nei.RecipeHandlerRefinery,BuildCraft,BuildCraft|Factory:refineryBlock,,BuildCraft|Factory,TRUE,,,60,,5,,,,,,There's only 2 recipes though
buildcraft.compat.nei.RecipeHandlerAssemblyTable,BuildCraft,BuildCraft|Silicon:laserTableBlock,,BuildCraft|Silicon,TRUE,,,100,,3,,,,,,
buildcraft.compat.nei.RecipeHandlerIntegrationTable,BuildCraft,BuildCraft|Silicon:laserTableBlock:2,,BuildCraft|Silicon,TRUE,,,85,,4,,,,,,
team.chisel.compat.nei.RecipeHandlerChisel,Chisel,chisel:chisel,,chisel,TRUE,,,135,,2,,,,,,
crazypants.enderio.nei.AlloySmelterRecipeHandler,Ender IO,EnderIO:blockAlloySmelter,,EnderIO,TRUE,,,65,,5,,,,,,
crazypants.enderio.nei.EnchanterRecipeHandler,Ender IO,EnderIO:blockEnchanter,,EnderIO,TRUE,,,65,,5,,,,,,
crazypants.enderio.nei.SagMillRecipeHandler,Ender IO,EnderIO:blockSagMill,,EnderIO,TRUE,,,68,,5,,,,,,
crazypants.enderio.nei.SliceAndSpliceRecipeHandler,Ender IO,EnderIO:blockSliceAndSplice,,EnderIO,TRUE,,,65,,5,,,,,,
crazypants.enderio.nei.SoulBinderRecipeHandler,Ender IO,EnderIO:blockSoulBinder,,EnderIO,TRUE,,,68,,5,,,,,,
crazypants.enderio.nei.VatRecipeHandler,Ender IO,EnderIO:blockVat,,EnderIO,TRUE,,,65,,5,,,,,,
extracells.integration.nei.UniversalTerminalRecipe,Extra Cells 2,extracells:part.base:9,,extracells,TRUE,,,65,,5,,,,,,
com.rwtema.extrautils.nei.EnderConstructorHandler,Extra Utilities,ExtraUtilities:endConstructor,,ExtraUtilities,TRUE,,,68,,5,,,,,,
com.rwtema.extrautils.nei.FMPMicroBlocksHandler,Extra Utilities,ForgeMicroblock:sawIron,,ExtraUtilities,TRUE,,,65,,5,,,,,,
com.rwtema.extrautils.nei.InfoHandler,Extra Utilities,ExtraUtilities:chandelier,,ExtraUtilities,TRUE,,,135,,2,,,,,,"Info on blocks, can vary wildly. EQ was this length, there might be a longer one"
com.rwtema.extrautils.nei.MicroBlocksHandler,Extra Utilities,ExtraUtilities:microblocks:1,,ExtraUtilities,TRUE,,,,,,,,,,,
com.rwtema.extrautils.nei.SoulHandler,Extra Utilities,ExtraUtilities:mini-soul,,ExtraUtilities,TRUE,,,,,,,,,,,
hellfirepvp.beebetteratbees.client.gui.BBABGuiRecipeTreeHandler,Bees,Forestry:beeQueenGE,,Forestry,TRUE,,,140,,2,,,,,,
forestry.factory.recipes.nei.NEIHandlerBottler,Forestry for Minecraft,Forestry:factory,,Forestry,TRUE,,,68,,5,,,,,,
forestry.factory.recipes.nei.NEIHandlerCarpenter,Forestry for Minecraft,Forestry:factory:1,,Forestry,TRUE,,,65,,5,,,,,,
forestry.factory.recipes.nei.NEIHandlerCentrifuge,Forestry for Minecraft,Forestry:factory:2,,Forestry,TRUE,,,65,,5,,,,,,
forestry.factory.recipes.nei.NEIHandlerFabricator,Forestry for Minecraft,Forestry:factory2,,Forestry,TRUE,,,,,,,,,,,
forestry.factory.recipes.nei.NEIHandlerFermenter,Forestry for Minecraft,Forestry:factory:3,,Forestry,TRUE,,,65,,5,,,,,,
forestry.factory.recipes.nei.NEIHandlerMoistener,Forestry for Minecraft,Forestry:factory:4,,Forestry,TRUE,,,68,,5,,,,,,
forestry.factory.recipes.nei.NEIHandlerSqueezer,Forestry for Minecraft,Forestry:factory:5,,Forestry,TRUE,,,68,,5,,,,,,
forestry.factory.recipes.nei.NEIHandlerStill,Forestry for Minecraft,Forestry:factory:6,,Forestry,TRUE,,,65,,5,,,,,,
net.bdew.neiaddons.forestry.bees.BeeBreedingHandler,Forestry for Minecraft,Forestry:beeQueenGE,,Forestry,TRUE,,,65,,5,,,,,,
net.bdew.neiaddons.forestry.bees.BeeProduceHandler,Forestry for Minecraft,Forestry:beeQueenGE,,Forestry,TRUE,,,65,,5,,,,,,
net.bdew.neiaddons.forestry.butterflies.ButterflyBreedingHandler,Forestry for Minecraft,Forestry:butterflyGE,,Forestry,TRUE,,,,,,,,,,,
net.bdew.neiaddons.forestry.trees.TreeBreedingHandler,Forestry for Minecraft,Forestry:saplingGE,,Forestry,TRUE,,,65,,5,,,,,,
net.bdew.neiaddons.forestry.trees.TreeProduceHandler,Forestry for Minecraft,Forestry:saplingGE,,Forestry,TRUE,,,65,,5,,,,,,
galaxyspace.core.nei.rocket.RocketT1RecipeHandler,Galacticraft,GalacticraftCore:item.spaceship,,GalacticraftCore,TRUE,,,125,,2,,,,,,
micdoodle8.mods.galacticraft.core.nei.BuggyRecipeHandler,Galacticraft,GalacticraftCore:tile.rocketWorkbench,,GalacticraftCore,TRUE,,10,135,,2,,,,,,
micdoodle8.mods.galacticraft.core.nei.CircuitFabricatorRecipeHandler,Galacticraft,GalacticraftCore:tile.machine2:4,,GalacticraftCore,TRUE,,,,,,,,,,,
micdoodle8.mods.galacticraft.core.nei.ElectricIngotCompressorRecipeHandler,Galacticraft,GalacticraftCore:tile.machine2,,GalacticraftCore,TRUE,,,,,,,,,,,
micdoodle8.mods.galacticraft.core.nei.IngotCompressorRecipeHandler,Galacticraft,GalacticraftCore:tile.machine:12,,GalacticraftCore,TRUE,,,,,,,,,,,
micdoodle8.mods.galacticraft.core.nei.RefineryRecipeHandler,Galacticraft,GalacticraftCore:tile.refinery,,GalacticraftCore,TRUE,,,,,,,,,,,
micdoodle8.mods.galacticraft.planets.asteroids.nei.AstroMinerRecipeHandler,Galacticraft,GalacticraftCore:tile.rocketWorkbench,,GalacticraftCore,TRUE,,,100,,3,,,,,,
micdoodle8.mods.galacticraft.planets.mars.nei.CargoRocketRecipeHandler,Galacticraft,GalacticraftCore:tile.rocketWorkbench,,GalacticraftCore,TRUE,,10,125,,2,,,,,,
micdoodle8.mods.galacticraft.planets.mars.nei.GasLiquefierRecipeHandler,Galacticraft,GalacticraftMars:tile.marsMachineT2,,GalacticraftCore,TRUE,,,,,,,,,,,
micdoodle8.mods.galacticraft.planets.mars.nei.MethaneSynthesizerRecipeHandler,Galacticraft,GalacticraftMars:tile.marsMachineT2:4,,GalacticraftCore,TRUE,,,,,,,,,,,
galaxyspace.core.nei.rocket.RocketT2RecipeHandler,Galacticraft,GalacticraftMars:item.spaceshipTier2:1,,GalacticraftMars,TRUE,,5,145,,2,,,,,,
galaxyspace.core.nei.rocket.RocketT3RecipeHandler,Galacticraft,GalacticraftMars:item.itemTier3Rocket,,GalacticraftMars,TRUE,,5,145,,2,,,,,,
galaxyspace.core.nei.AssemblyMachineRecipeHandler,GalaxySpace,GalaxySpace:assemblymachine,,GalaxySpace,TRUE,,,,,,,,,,,
galaxyspace.core.nei.rocket.RocketT4RecipeHandler,GalaxySpace,GalaxySpace:item.Tier4Rocket,,GalaxySpace,TRUE,,10,160,,2,,,,,,
galaxyspace.core.nei.rocket.RocketT5RecipeHandler,GalaxySpace,GalaxySpace:item.Tier5Rocket,,GalaxySpace,TRUE,,10,160,,2,,,,,,
galaxyspace.core.nei.rocket.RocketT6RecipeHandler,GalaxySpace,GalaxySpace:item.Tier6Rocket,,GalaxySpace,TRUE,,10,160,,2,,,,,,
galaxyspace.core.nei.rocket.RocketT7RecipeHandler,GalaxySpace,GalaxySpace:item.Tier7Rocket,,GalaxySpace,TRUE,,10,180,,1,,,,,,
galaxyspace.core.nei.rocket.RocketT8RecipeHandler,GalaxySpace,GalaxySpace:item.Tier8Rocket,,GalaxySpace,TRUE,,10,180,,1,,,,,,
net.bdew.gendustry.nei.ExtractorHandler,Gendustry,gendustry:Extractor,,gendustry,TRUE,,,68,,5,,,,,,
net.bdew.gendustry.nei.ImprinterHandler,Gendustry,gendustry:Imprinter,,gendustry,TRUE,,,68,,5,,,,,,
net.bdew.gendustry.nei.LiquifierHandler,Gendustry,gendustry:Liquifier,,gendustry,TRUE,,,68,,5,,,,,,
net.bdew.gendustry.nei.MutagenProducerHandler,Gendustry,gendustry:MutagenProducer,,gendustry,TRUE,,,68,,5,,,,,,
net.bdew.gendustry.nei.MutatronHandler,Gendustry,gendustry:Mutatron,,gendustry,TRUE,,,65,,5,,,,,,
net.bdew.gendustry.nei.ReplicatorHandler,Gendustry,gendustry:Replicator,,gendustry,TRUE,,,68,,5,,,,,,
net.bdew.gendustry.nei.SamplerHandler,Gendustry,gendustry:Sampler,,gendustry,TRUE,,,68,,5,,,,,,
net.bdew.gendustry.nei.TemplateCraftingHandler,Gendustry,gendustry:GeneTemplate,,gendustry,TRUE,,,105,,3,,,,,,
net.bdew.gendustry.nei.TransposerHandler,Gendustry,gendustry:Transposer,,gendustry,TRUE,,,68,,5,,,,,,
gt.recipe.alloysmelter,GregTech,gregtech:gt.blockmachines:201,,gregtech,TRUE,gregapi_post,6,135,166,2,,,,,,
gt.recipe.arcfurnace,GregTech,gregtech:gt.blockmachines:651,,gregtech,TRUE,gregapi_post,6,135,166,2,,,,,,
gt.recipe.assembler,GregTech,gregtech:gt.blockmachines:211,,gregtech,TRUE,gregapi_post,6,145,166,2,,,,,,
gt.recipe.autoclave,GregTech,gregtech:gt.blockmachines:571,,gregtech,TRUE,gregapi_post,6,135,166,2,,,,,,
gt.recipe.blastfurnace,GregTech,gregtech:gt.blockmachines:1000,,gregtech,TRUE,gregapi_post,6,135,166,2,,,,,,
gt.recipe.brewer,GregTech,gregtech:gt.blockmachines:491,,gregtech,TRUE,gregapi_post,6,135,166,2,,,,,,
gt.recipe.byproductlist,GregTech,gregtech:gt.metaitem.01:2019,,gregtech,TRUE,gregapi_post,6,135,166,2,,,,,,
gt.recipe.canner,GregTech,gregtech:gt.blockmachines:231,,gregtech,TRUE,gregapi_post,6,135,166,2,,,,,,
gt.recipe.centrifuge,GregTech,gregtech:gt.blockmachines:361,,gregtech,TRUE,gregapi_post,6,135,166,2,,,,,,
gt.recipe.chemicalbath,GregTech,gregtech:gt.blockmachines:541,,gregtech,TRUE,gregapi_post,6,135,166,2,,,,,,
gt.recipe.chemicalreactor,GregTech,gregtech:gt.blockmachines:421,,gregtech,TRUE,gregapi_post,6,135,166,2,,,,,,
gt.recipe.circuitassembler,GregTech,gregtech:gt.blockmachines:1180,,gregtech,TRUE,gregapi_post,6,135,166,2,,,,,,
gt.recipe.cncmachine,GregTech,gregtech:gt.metaitem.01:23305,,gregtech,TRUE,gregapi_post,6,135,166,2,,,,,,
gt.recipe.cokeoven,GregTech,gregtech:gt.blockmachines:791,,gregtech,TRUE,gregapi_post,6,135,166,2,,,,,,
gt.recipe.componentassembler,GregTech,gregtech:gt.blockmachines:211,,gregtech,TRUE,gregapi_post,6,135,166,2,,,,,,
gt.recipe.compressor,GregTech,gregtech:gt.blockmachines:241,,gregtech,TRUE,gregapi_post,6,135,166,2,,,,,,
gt.recipe.craker,GregTech,gregtech:gt.blockmachines:1160,,gregtech,TRUE,gregapi_post,6,135,166,2,,,,,,
gt.recipe.cuttingsaw,GregTech,gregtech:gt.blockmachines:251,,gregtech,TRUE,gregapi_post,6,135,166,2,,,,,,
gt.recipe.dieselgeneratorfuel,GregTech,gregtech:gt.blockmachines:1110,,gregtech,TRUE,gregapi_post,6,135,166,2,,,,,,
gt.recipe.distillationtower,GregTech,gregtech:gt.blockmachines:1126,,gregtech,TRUE,gregapi_post,6,135,166,2,,,,,,
gt.recipe.distillery,GregTech,gregtech:gt.blockmachines:531,,gregtech,TRUE,gregapi_post,6,135,166,2,,,,,,
gt.recipe.electrolyzer,GregTech,gregtech:gt.blockmachines:371,,gregtech,TRUE,gregapi_post,6,135,166,2,,,,,,
gt.recipe.electromagneticseparator,GregTech,gregtech:gt.blockmachines:561,,gregtech,TRUE,gregapi_post,6,135,166,2,,,,,,
gt.recipe.extractor,GregTech,gregtech:gt.blockmachines:271,,gregtech,TRUE,gregapi_post,6,135,166,2,,,,,,
gt.recipe.extrahugenaquadahreactor,GregTech,gregtech:gt.blockmachines:1189,,gregtech,TRUE,gregapi_post,6,135,166,2,,,,,,
gt.recipe.extremedieselgeneratorfuel,GregTech,gregtech:gt.blockmachines:2105,,gregtech,TRUE,gregapi_post,6,135,166,2,,,,,,
gt.recipe.extruder,GregTech,gregtech:gt.blockmachines:281,,gregtech,TRUE,gregapi_post,6,135,166,2,,,,,,
gt.recipe.fakeAssemblylineProcess,GregTech,gregtech:gt.blockmachines:1170,,gregtech,TRUE,gregapi_post,12,135,166,2,,,,,,
gt.recipe.fermenter,GregTech,gregtech:gt.blockmachines:501,,gregtech,TRUE,gregapi_post,6,135,166,2,,,,,,
gt.recipe.fluidcanner,GregTech,gregtech:gt.blockmachines:431,,gregtech,TRUE,gregapi_post,6,135,166,2,,,,,,
gt.recipe.fluidextractor,GregTech,gregtech:gt.blockmachines:511,,gregtech,TRUE,gregapi_post,6,135,166,2,,,,,,
gt.recipe.fluidheater,GregTech,gregtech:gt.blockmachines:621,,gregtech,TRUE,gregapi_post,6,135,166,2,,,,,,
gt.recipe.fluidnaquadahreactor,GregTech,gregtech:gt.blockmachines:1192,,gregtech,TRUE,gregapi_post,6,135,166,2,,,,,,
gt.recipe.fluidsolidifier,GregTech,gregtech:gt.blockmachines:521,,gregtech,TRUE,gregapi_post,6,135,166,2,,,,,,
gt.recipe.fusionreactor,GregTech,gregtech:gt.blockmachines:1193,,gregtech,TRUE,gregapi_post,6,135,166,2,,,,,,
gt.recipe.gasturbinefuel,GregTech,gregtech:gt.blockmachines:1115,,gregtech,TRUE,gregapi_post,6,135,166,2,,,,,,
gt.recipe.hammer,GregTech,gregtech:gt.blockmachines:611,,gregtech,TRUE,gregapi_post,6,135,166,2,,,,,,
gt.recipe.hugenaquadahreactor,GregTech,gregtech:gt.blockmachines:1188,,gregtech,TRUE,gregapi_post,6,135,166,2,,,,,,
gt.recipe.implosioncompressor,GregTech,gregtech:gt.blockmachines:12734,,gregtech,TRUE,gregapi_post,6,135,166,2,,,,,,
gt.recipe.largeboilerfakefuels,GregTech,gregtech:gt.blockmachines:1020,,gregtech,TRUE,gregapi_post,6,135,166,2,,,,,,
gt.recipe.largechemicalreactor,GregTech,gregtech:gt.blockmachines:1169,,gregtech,TRUE,gregapi_post,6,135,166,2,,,,,,
gt.recipe.largenaquadahreactor,GregTech,gregtech:gt.blockmachines:1191,,gregtech,TRUE,gregapi_post,6,135,166,2,,,,,,
gt.recipe.laserengraver,GregTech,gregtech:gt.blockmachines:591,,gregtech,TRUE,gregapi_post,6,135,166,2,,,,,,
gt.recipe.lathe,GregTech,gregtech:gt.blockmachines:291,,gregtech,TRUE,gregapi_post,6,135,166,2,,,,,,
gt.recipe.macerator,GregTech,gregtech:gt.blockmachines:301,,gregtech,TRUE,gregapi_post,6,135,166,2,,,,,,
gt.recipe.magicfuels,GregTech,gregtech:gt.blockmachines:1123,,gregtech,TRUE,gregapi_post,6,135,166,2,,,,,,
gt.recipe.massfab,GregTech,gregtech:gt.blockmachines:461,,gregtech,TRUE,gregapi_post,6,135,166,2,,,,,,
gt.recipe.metalbender,GregTech,gregtech:gt.blockmachines:221,,gregtech,TRUE,gregapi_post,6,135,166,2,,,,,,
gt.recipe.microwave,GregTech,gregtech:gt.blockmachines:311,,gregtech,TRUE,gregapi_post,6,135,166,2,,,,,,
gt.recipe.mixer,GregTech,gregtech:gt.blockmachines:581,,gregtech,TRUE,gregapi_post,6,135,166,2,,,,,,
gt.recipe.orewasher,GregTech,gregtech:gt.blockmachines:391,,gregtech,TRUE,gregapi_post,6,135,166,2,,,,,,
gt.recipe.packager,GregTech,gregtech:gt.blockmachines:401,,gregtech,TRUE,gregapi_post,6,135,166,2,,,,,,
gt.recipe.plasmaarcfurnace,GregTech,gregtech:gt.blockmachines:661,,gregtech,TRUE,gregapi_post,6,135,166,2,,,,,,
gt.recipe.plasmageneratorfuels,GregTech,gregtech:gt.blockmachines:1196,,gregtech,TRUE,gregapi_post,6,135,166,2,,,,,,
gt.recipe.polarizer,GregTech,gregtech:gt.blockmachines:551,,gregtech,TRUE,gregapi_post,6,135,166,2,,,,,,
gt.recipe.press,GregTech,gregtech:gt.blockmachines:601,,gregtech,TRUE,gregapi_post,6,135,166,2,,,,,,
gt.recipe.primitiveblastfurnace,GregTech,gregtech:gt.blockmachines:140,,gregtech,TRUE,gregapi_post,6,135,166,2,,,,,,
gt.recipe.printer,GregTech,gregtech:gt.blockmachines:321,,gregtech,TRUE,gregapi_post,6,135,166,2,,,,,,
gt.recipe.pyro,GregTech,gregtech:gt.blockmachines:1159,,gregtech,TRUE,gregapi_post,6,135,166,2,,,,,,
gt.recipe.replicator,GregTech,gregtech:gt.blockmachines:481,,gregtech,TRUE,gregapi_post,6,135,166,2,,,,,,
gt.recipe.rockbreaker,GregTech,gregtech:gt.blockmachines:441,,gregtech,TRUE,gregapi_post,6,135,166,2,,,,,,
gt.recipe.scanner,GregTech,gregtech:gt.blockmachines:341,,gregtech,TRUE,gregapi_post,6,135,166,2,,,,,,
gt.recipe.semifluidboilerfuels,GregTech,gregtech:gt.blockmachines:1020,,gregtech,TRUE,gregapi_post,6,135,166,2,,,,,,
gt.recipe.sifter,GregTech,gregtech:gt.blockmachines:641,,gregtech,TRUE,gregapi_post,6,135,166,2,,,,,,
gt.recipe.slicer,GregTech,gregtech:gt.blockmachines:631,,gregtech,TRUE,gregapi_post,6,135,166,2,,,,,,
gt.recipe.smallnaquadahreactor,GregTech,gregtech:gt.blockmachines:1190,,gregtech,TRUE,gregapi_post,6,135,166,2,,,,,,
gt.recipe.thermalcentrifuge,GregTech,gregtech:gt.blockmachines:381,,gregtech,TRUE,gregapi_post,6,135,166,2,,,,,,
gt.recipe.thermalgeneratorfuel,GregTech,IC2:blockGenerator:1,,gregtech,TRUE,gregapi_post,6,135,166,2,,,,,,
gt.recipe.unpackager,GregTech,gregtech:gt.blockmachines:411,,gregtech,TRUE,gregapi_post,6,135,166,2,,,,,,
gt.recipe.uuamplifier,GregTech,gregtech:gt.blockmachines:471,,gregtech,TRUE,gregapi_post,6,135,166,2,,,,,,
gt.recipe.vacuumfreezer,GregTech,gregtech:gt.blockmachines:1002,,gregtech,TRUE,gregapi_post,6,135,166,2,,,,,,
gt.recipe.wiremill,GregTech,gregtech:gt.blockmachines:351,,gregtech,TRUE,gregapi_post,6,135,166,2,,,,,,
ic.recipe.recycler,GregTech,gregtech:gt.blockmachines:331,,gregtech,TRUE,gregapi_post,6,135,166,2,,,,,,
pers.gwyog.gtneioreplugin.plugin.gregtech5.PluginGT5SmallOreStat,GregTech,gregtech:gt.blockores:85,,gregtech,TRUE,,,145,,2,,,,,,
pers.gwyog.gtneioreplugin.plugin.gregtech5.PluginGT5VeinStat,GregTech,gregtech:gt.blockores:386,,gregtech,TRUE,,,135,,2,,,,,,
ic2.neiIntegration.core.recipehandler.AdvRecipeHandler,IndustrialCraft 2,IC2:blockreactorvessel,,IC2,TRUE,,,65,,5,,,,,,
ic2.neiIntegration.core.recipehandler.AdvShapelessRecipeHandler,IndustrialCraft 2,IC2:blockreactorvessel,,IC2,TRUE,,,65,,5,,,,,,
ic2.neiIntegration.core.recipehandler.BlastFurnaceRecipeHandler,IndustrialCraft 2,IC2:blockMachine3:1,,IC2,TRUE,,,65,,5,,,,,,
ic2.neiIntegration.core.recipehandler.BlockCutterRecipeHandler,IndustrialCraft 2,IC2:blockMachine3:2,,IC2,TRUE,,,65,,5,,,,,,
ic2.neiIntegration.core.recipehandler.CentrifugeRecipeHandler,IndustrialCraft 2,IC2:blockMachine2:3,,IC2,TRUE,,,65,,5,,,,,,
ic2.neiIntegration.core.recipehandler.CompressorRecipeHandler,IndustrialCraft 2,IC2:blockMachine:5,,IC2,TRUE,,,65,,5,,,,,,
ic2.neiIntegration.core.recipehandler.ExtractorRecipeHandler,IndustrialCraft 2,IC2:blockMachine:4,,IC2,TRUE,,,65,,5,,,,,,
ic2.neiIntegration.core.recipehandler.FluidCannerRecipeHandler,IndustrialCraft 2,IC2:blockMachine:6,,IC2,TRUE,,,65,,5,,,,,,
ic2.neiIntegration.core.recipehandler.LatheRecipeHandler,IndustrialCraft 2,IC2:blockMachine3:8,,IC2,TRUE,,,65,,5,,,,,,
ic2.neiIntegration.core.recipehandler.MaceratorRecipeHandler,IndustrialCraft 2,IC2:blockMachine:3,,IC2,TRUE,,,65,,5,,,,,,
ic2.neiIntegration.core.recipehandler.MetalFormerRecipeHandlerCutting,IndustrialCraft 2,IC2:blockMachine2:4,,IC2,TRUE,,,55,,6,,,,,,
ic2.neiIntegration.core.recipehandler.MetalFormerRecipeHandlerExtruding,IndustrialCraft 2,IC2:blockMachine2:4,,IC2,TRUE,,,55,,6,,,,,,
ic2.neiIntegration.core.recipehandler.MetalFormerRecipeHandlerRolling,IndustrialCraft 2,IC2:blockMachine2:4,,IC2,TRUE,,,55,,6,,,,,,
ic2.neiIntegration.core.recipehandler.OreWashingRecipeHandler,IndustrialCraft 2,IC2:blockMachine2:5,,IC2,TRUE,,,,,,,,,,,
ic2.neiIntegration.core.recipehandler.ScrapboxRecipeHandler,IndustrialCraft 2,IC2:itemScrapbox,,IC2,TRUE,,,50,,6,,,,,,
ic2.neiIntegration.core.recipehandler.SolidCannerRecipeHandler,IndustrialCraft 2,IC2:blockMachine2:9,,IC2,TRUE,,,,,,,,,,,
speiger.src.crops.prediction.NEIPlugin,IC2CropsNEI,IC2:blockCrop,,Ic2Nei,TRUE,,,135,,2,,,,,,"Not actual recipes, just info"
tonius.neiintegration.mods.mcforge.RecipeHandlerFluidRegistry,Minecraft,minecraft:water,,minecraft,FALSE,,,,,,,,,,,
tonius.neiintegration.mods.mcforge.RecipeHandlerOreDictionary,Minecraft,minecraft:iron_ore,,minecraft,FALSE,,,,,,,,,,,
gt.recipe.alloyblastsmelter,GT++,gregtech:gt.blockmachines:810,,miscutils,TRUE,,6,135,166,2,,,,,,ABS
gt.recipe.rocketenginefuel,GT++,gregtech:gt.blockmachines:793,,miscutils,TRUE,,6,135,166,2,,,,,,Basic (EV) rocket fuel gen
gt.recipe.cyclotron,GT++,gregtech:gt.blockmachines:828,,miscutils,TRUE,,6,135,166,2,,,,,,Cyclotron
gt.recipe.chemicaldehydrator,GT++,gregtech:gt.blockmachines:911,,miscutils,TRUE,,6,135,166,2,,,,,,Dehydrator
gt.recipe.slowfusionreactor,GT++,gregtech:gt.blockmachines:31015,,miscutils,TRUE,,6,135,166,2,,,,,,gt.blockmachines.gtplusplus.fusion.single
gt.recipe.RTGgenerators,GT++,gregtech:gt.blockmachines:869,,miscutils,TRUE,,6,135,166,2,,,,,,GT++ version of the RTG
gt.recipe.cokeoven,GT++,gregtech:gt.blockmachines:791,,miscutils,TRUE,,6,135,166,2,,,,,,ICO
gt.recipe.semifluidgeneratorfuels,GT++,gregtech:gt.blockmachines:837,,miscutils,TRUE,,6,135,166,2,,,,,,Semifluid gen
gt.recipe.fishpond,GT++,gregtech:gt.blockmachines:829,,miscutils,TRUE,,6,135,166,2,,,,,,Zhuhai
gt.recipe.advanced.mixer,GT++,gregtech:gt.blockmachines:811,,miscutils,TRUE,,6,135,166,2,,,,,,
gt.recipe.cryogenicfreezer,GT++,gregtech:gt.blockmachines:910,,miscutils,TRUE,,6,135,166,2,,,,,,
gt.recipe.fissionfuel,GT++,gregtech:gt.blockmachines:835,,miscutils,TRUE,,6,135,166,2,,,,,,
gt.recipe.geothermalfuel,GT++,gregtech:gt.blockmachines:830,,miscutils,TRUE,,6,135,166,2,,,,,,
gt.recipe.lftr,GT++,gregtech:gt.blockmachines:751,,miscutils,TRUE,,6,135,166,2,,,,,,
gt.recipe.lftr.2,GT++,gregtech:gt.blockmachines:751,,miscutils,TRUE,,6,135,166,2,,,,,,
gt.recipe.matterfab2,GT++,gregtech:gt.blockmachines:799,,miscutils,TRUE,,6,135,166,2,,,,,,
gt.recipe.multicentrifuge,GT++,gregtech:gt.blockmachines:790,,miscutils,TRUE,,6,135,166,2,,,,,,
gt.recipe.multielectro,GT++,gregtech:gt.blockmachines:796,,miscutils,TRUE,,6,135,166,2,,,,,,
gt.recipe.simplewasher,GT++,gregtech:gt.blockmachines:767,,miscutils,TRUE,,6,135,166,2,,,,,,
gt.recipe.vacfurnace,GT++,gregtech:gt.blockmachines:995,,miscutils,TRUE,,6,135,166,2,,,,,,
gtPlusPlus.nei.DecayableRecipeHandler,GT++,miscutils:dustRadium226,,miscutils,TRUE,,,75,,4,,,,,,
gtPlusPlus.nei.GT_NEI_FlotationCell,GT++,gregtech:gt.blockmachines:31028,,miscutils,TRUE,,,120,,2,,,,,,
gtPlusPlus.nei.GT_NEI_FluidReactor,GT++,gregtech:gt.blockmachines:998,,miscutils,TRUE,,,120,,2,,,,,,
gtPlusPlus.nei.GT_NEI_MillingMachine,GT++,gregtech:gt.blockmachines:31027,,miscutils,TRUE,,,120,,2,,,,,,
li.cil.oc.integration.nei.CallbackDocHandler,OpenComputers,OpenComputers:item:98,,OpenComputers,TRUE,,,120,,2,,,,,,
li.cil.oc.integration.nei.ManualUsageHandler,OpenComputers,OpenComputers:item:98,,OpenComputers,TRUE,,,120,,2,,,,,,
tonius.neiintegration.mods.harvestcraft.RecipeHandlerApiary,Pam's Harvestcraft,harvestcraft:apiary,,harvestcraft,TRUE,,,70,,5,,,,,,There's only 1 though
tonius.neiintegration.mods.harvestcraft.RecipeHandlerChurn,Pam's Harvestcraft,harvestcraft:churn,,harvestcraft,TRUE,,,65,,5,,,,,,Same as above
tonius.neiintegration.mods.harvestcraft.RecipeHandlerOven,Pam's Harvestcraft,harvestcraft:oven,,harvestcraft,TRUE,,,65,,5,,,,,,
tonius.neiintegration.mods.harvestcraft.RecipeHandlerPresser,Pam's Harvestcraft,harvestcraft:presser,,harvestcraft,TRUE,,,65,,5,,,,,,
tonius.neiintegration.mods.harvestcraft.RecipeHandlerQuern,Pam's Harvestcraft,harvestcraft:quern,,harvestcraft,TRUE,,,65,,5,,,,,,
gcewing.projectblue.nei.NEIRecipeHandler,ProjectBlue,ProjectBlue:sprayCan,,ProjectBlue,TRUE,,,65,,5,,,,,,
mrtjp.projectred.core.libmc.recipe.PRShapedRecipeHandler,ProjectRed,ProjRed|Transmission:projectred.transmission.wire:7,,ProjRed|Transmission,TRUE,,,,,,,,,,,
mrtjp.projectred.core.libmc.recipe.PRShapelessRecipeHandler,ProjectRed,ProjRed|Transmission:projectred.transmission.wire:7,,ProjRed|Transmission,TRUE,,,,,,,,,,,
tonius.neiintegration.mods.railcraft.RecipeHandlerBlastFurnace,Railcraft,Railcraft:machine.alpha:12,,Railcraft,TRUE,,,,,,,,,,,
tonius.neiintegration.mods.railcraft.RecipeHandlerCokeOven,Railcraft,Railcraft:machine.alpha:7,,Railcraft,TRUE,,,65,,5,,,,,,
tonius.neiintegration.mods.railcraft.RecipeHandlerRockCrusher,Railcraft,Railcraft:machine.alpha:15,,Railcraft,TRUE,,,,,,,,,,,
tonius.neiintegration.mods.railcraft.RecipeHandlerRollingMachineShaped,Railcraft,Railcraft:machine.alpha:8,,Railcraft,TRUE,,,65,,5,,,,,,
tonius.neiintegration.mods.railcraft.RecipeHandlerRollingMachineShapeless,Railcraft,Railcraft:machine.alpha:8,,Railcraft,TRUE,,,,,,,,,,,
lumien.randomthings.Handler.ModCompability.NEI.ImbuingStationRecipeHandler,RandomThings,RandomThings:imbuingStation,,RandomThings,TRUE,,,120,,2,,,,,,
com.github.technus.tectech.nei.TT_NEI_ResearchHandler,TecTech,gregtech:gt.blockmachines:15331,,tectech,TRUE,,6,140,,2,,,,,,
com.github.technus.tectech.nei.TT_NEI_ScannerHandler,TecTech,tectech:item.em.definitionScanStorage,,tectech,TRUE,,,,,,,,,,,
com.djgiannuzz.thaumcraftneiplugin.nei.recipehandler.ArcaneShapedRecipeHandler,Thaumcraft,Thaumcraft:blockTable:15,,Thaumcraft,TRUE,,,140,,2,,,,,,
com.djgiannuzz.thaumcraftneiplugin.nei.recipehandler.ArcaneShapelessRecipeHandler,Thaumcraft,Thaumcraft:blockTable:15,,Thaumcraft,TRUE,,,140,,2,,,,,,
com.djgiannuzz.thaumcraftneiplugin.nei.recipehandler.CrucibleRecipeHandler,Thaumcraft,Thaumcraft:blockMetalDevice,,Thaumcraft,TRUE,,,140,,2,,,,,,Using R on an item you get from the crucible basically never works
com.djgiannuzz.thaumcraftneiplugin.nei.recipehandler.InfusionRecipeHandler,Thaumcraft,Thaumcraft:blockStoneDevice:2,,Thaumcraft,TRUE,,,140,,2,,,,,,
ru.timeconqueror.tcneiadditions.nei.arcaneworkbench.ArcaneCraftingShapedHandler,Thaumcraft,Thaumcraft:blockTable:15,,Thaumcraft,TRUE,,,140,,2,,,,,,
ru.timeconqueror.tcneiadditions.nei.AspectCombinationHandler,Thaumcraft,Thaumcraft:ItemResearchNotes,,Thaumcraft,TRUE,,,130,,2,,,,,,In sets of 5. Each one is ~30 height
ru.timeconqueror.tcneiadditions.nei.AspectFromItemStackHandler,Thaumcraft,Thaumcraft:ItemResearchNotes,,Thaumcraft,TRUE,,,140,,2,,,,,,
tconstruct.plugins.nei.RecipeHandlerAlloying,Tinker's Construct,TConstruct:Smeltery,,TConstruct,TRUE,,,65,,5,,,,,,
tconstruct.plugins.nei.RecipeHandlerCastingBasin,Tinker's Construct,TConstruct:SearedBlock:2,,TConstruct,TRUE,,,65,,5,,,,,,
tconstruct.plugins.nei.RecipeHandlerCastingTable,Tinker's Construct,TConstruct:SearedBlock,,TConstruct,TRUE,,,65,,5,,,,,,
tconstruct.plugins.nei.RecipeHandlerDryingRack,Tinker's Construct,TConstruct:Armor.DryingRack,,TConstruct,TRUE,,,55,,5,,,,,,
tconstruct.plugins.nei.RecipeHandlerMelting,Tinker's Construct,TConstruct:LavaTank:2,,TConstruct,TRUE,,,65,,5,,,,,,
tconstruct.plugins.nei.RecipeHandlerToolMaterials,Tinker's Construct,TConstruct:ToolStationBlock,,TConstruct,TRUE,,,110,,3,,,,,,"Longer if more modifiers, I went through the whole list"
net.p455w0rd.wirelesscraftingterminal.integration.modules.NEIHelpers.NEIAEShapedRecipeHandler,Wireless Crafting Terminal,ae2wct:wirelessCraftingTerminal,,ae2wct,TRUE,,,,,,,,,,,
alkalus.main.nei.NEI_Handler_Cauldron,Witchery,witchery:cauldron,,WitcheryExtras,TRUE,,,65,,5,,,,,,
alkalus.main.nei.NEI_Handler_Distillery,Witchery,witchery:distilleryidle,,WitcheryExtras,TRUE,,,140,,2,,,,,,
alkalus.main.nei.NEI_Handler_Kettle,Witchery,witchery:kettle,,WitcheryExtras,TRUE,,,65,,5,,,,,,
alkalus.main.nei.NEI_Handler_Oven,Witchery,witchery:witchesovenidle,,WitcheryExtras,TRUE,,,,,,,,,,,Not working at all now
alkalus.main.nei.NEI_Handler_SpinningWheel,Witchery,witchery:spinningwheel,,WitcheryExtras,TRUE,,,65,,5,,,,,,
com.emoniph.witchery.integration.NEICauldronRecipeHandler,Witchery,witchery:cauldron,,witchery,TRUE,,,65,,5,,,,,,Replaced by WE presumably
com.emoniph.witchery.integration.NEIDistilleryRecipeHandler,Witchery,witchery:distilleryidle,,witchery,TRUE,,,140,,2,,,,,,Replaced by WE presumably
com.emoniph.witchery.integration.NEIKettleRecipeHandler,Witchery,witchery:kettle,,witchery,TRUE,,,65,,5,,,,,,Replaced by WE presumably
com.emoniph.witchery.integration.NEISpinningWheelRecipeHandler,Witchery,witchery:spinningwheel,,witchery,TRUE,,,,,,,,,,,Replaced by WE presumably
com.emoniph.witchery.integration.NEIWitchesOvenRecipeHandler,Witchery,witchery:witchesovenidle,,witchery,TRUE,,,65,,5,,,,,,Replaced by WE presumably
witchinggadgets.client.nei.NEIInfernalBlastfurnaceHandler,WitchingGadgets,WitchingGadgets:WG_StoneDevice:2,,WitchingGadgets,TRUE,,,65,,5,,,,,,
witchinggadgets.client.nei.NEISpinningWheelHandler,WitchingGadgets,WitchingGadgets:WG_WoodenDevice,,WitchingGadgets,TRUE,,,110,,3,,,,,,
gt.recipe.anvil,GregTech 6,gregtech:gt.multitileentity:32031,,gregapi_post,TRUE,,15,145,166,2,,,,,,
gt.recipe.anvil.bend.big,GregTech 6,gregtech:gt.multitileentity:32031,,gregapi_post,TRUE,,15,145,166,2,,,,,,
gt.recipe.anvil.bend.small,GregTech 6,gregtech:gt.multitileentity:32031,,gregapi_post,TRUE,,15,145,166,2,,,,,,
gt.recipe.aquaticfarm,GregTech 6,gregtech:gt.multitileentity:17131,,gregapi_post,TRUE,,15,145,166,2,,,,,,
gt.recipe.assembler,GregTech 6,gregtech:gt.multitileentity:20621,,gregapi_post,TRUE,,15,145,166,2,,,,,,
gt.recipe.autoclave,GregTech 6,gregtech:gt.multitileentity:22004,,gregapi_post,TRUE,,15,145,166,2,,,,,,
gt.recipe.bath,GregTech 6,gregtech:gt.multitileentity:22002,,gregapi_post,TRUE,,15,145,166,2,,,,,,
gt.recipe.bedrockorelist,GregTech 6,gregtech:gt.multitileentity:17999,,gregapi_post,TRUE,,15,145,166,2,,,,,,
gt.recipe.biolab,GregTech 6,gregtech:gt.multitileentity:17127,,gregapi_post,TRUE,,15,145,166,2,,,,,,
gt.recipe.boxinator,GregTech 6,gregtech:gt.multitileentity:20581,,gregapi_post,TRUE,,15,145,166,2,,,,,,
gt.recipe.bumblelyzer,GregTech 6,gregtech:gt.multitileentity:20541,,gregapi_post,TRUE,,15,145,166,2,,,,,,
gt.recipe.bumblequeen,GregTech 6,gregtech:gt.multiitem.bumblebee:1,"{""gt.bumble"": {}}",gregapi_post,TRUE,,15,145,166,2,,,,,,
gt.recipe.burnmixer,GregTech 6,gregtech:gt.multitileentity:20521,,gregapi_post,TRUE,,15,145,166,2,,,,,,
gt.recipe.byproductlist,GregTech 6,minecraft:diamond_ore,,gregapi_post,TRUE,,15,145,166,2,,,,,,
gt.recipe.canner,GregTech 6,gregtech:gt.multitileentity:20161,,gregapi_post,TRUE,,15,145,166,2,,,,,,
gt.recipe.catalyticcracking,GregTech 6,gregtech:gt.multitileentity:20481,,gregapi_post,TRUE,,15,145,166,2,,,,,,
gt.recipe.centrifuge,GregTech 6,gregtech:gt.multitileentity:20081,,gregapi_post,TRUE,,15,145,166,2,,,,,,
gt.recipe.clustermill,GregTech 6,gregtech:gt.multitileentity:20141,,gregapi_post,TRUE,,15,145,166,2,,,,,,
gt.recipe.coagulator,GregTech 6,gregtech:gt.multitileentity:22000,,gregapi_post,TRUE,,15,145,166,2,,,,,,
gt.recipe.cokeoven,GregTech 6,gregtech:gt.multitileentity:17000,,gregapi_post,TRUE,,15,145,166,2,,,,,,
gt.recipe.compressor,GregTech 6,gregtech:gt.multitileentity:20101,,gregapi_post,TRUE,,15,145,166,2,,,,,,
gt.recipe.crackingtower,GregTech 6,gregtech:gt.multitileentity:17115,,gregapi_post,TRUE,,15,145,166,2,,,,,,
gt.recipe.cruciblealloying,GregTech 6,gregtech:gt.multitileentity:1005,,gregapi_post,TRUE,,15,145,166,2,,,,,,
gt.recipe.cruciblesmelting,GregTech 6,gregtech:gt.multitileentity:1005,,gregapi_post,TRUE,,15,145,166,2,,,,,,
gt.recipe.crusher,GregTech 6,gregtech:gt.multitileentity:20021,,gregapi_post,TRUE,,15,145,166,2,,,,,,
gt.recipe.cryodistillationtower,GregTech 6,gregtech:gt.multitileentity:17111,,gregapi_post,TRUE,,15,145,166,2,,,,,,
gt.recipe.cryomixer,GregTech 6,gregtech:gt.multitileentity:20571,,gregapi_post,TRUE,,15,145,166,2,,,,,,
gt.recipe.crystallisationcrucible,GregTech 6,gregtech:gt.multitileentity:20251,,gregapi_post,TRUE,,15,145,166,2,,,,,,
gt.recipe.cutter,GregTech 6,gregtech:gt.multitileentity:20061,,gregapi_post,TRUE,,15,145,166,2,,,,,,
gt.recipe.debarker,GregTech 6,gregtech:gt.multitileentity:20551,,gregapi_post,TRUE,,15,145,166,2,,,,,,
gt.recipe.distillationtower,GregTech 6,gregtech:gt.multitileentity:20191,,gregapi_post,TRUE,,15,145,166,2,,,,,,
gt.recipe.distillery,GregTech 6,gregtech:gt.multitileentity:20191,,gregapi_post,TRUE,,15,145,166,2,,,,,,
gt.recipe.drying,GregTech 6,gregtech:gt.multitileentity:20311,,gregapi_post,TRUE,,15,145,166,2,,,,,,
gt.recipe.electrolyzer,GregTech 6,gregtech:gt.multitileentity:20091,,gregapi_post,TRUE,,15,145,166,2,,,,,,
gt.recipe.extruder,GregTech 6,gregtech:gt.multitileentity:20202,,gregapi_post,TRUE,,15,145,166,2,,,,,,
gt.recipe.fermenter,GregTech 6,gregtech:gt.multitileentity:22003,,gregapi_post,TRUE,,15,145,166,2,,,,,,
gt.recipe.fluidsolidifier,GregTech 6,gregtech:gt.multitileentity:20611,,gregapi_post,TRUE,,15,145,166,2,,,,,,
gt.recipe.freezer,GregTech 6,gregtech:gt.multitileentity:20561,,gregapi_post,TRUE,,15,145,166,2,,,,,,
gt.recipe.fuels.burn,GregTech 6,gregtech:gt.multitileentity:1109,,gregapi_post,TRUE,,15,145,166,2,,,,,,
gt.recipe.fuels.engine,GregTech 6,gregtech:gt.multitileentity:9147,,gregapi_post,TRUE,,15,145,166,2,,,,,,
gt.recipe.fuels.fluidbed,GregTech 6,gregtech:gt.multitileentity:9009,,gregapi_post,TRUE,,15,145,166,2,,,,,,
gt.recipe.fuels.gas,GregTech 6,gregtech:gt.multitileentity:1609,,gregapi_post,TRUE,,15,145,166,2,,,,,,
gt.recipe.fuels.plasma,GregTech 6,gregtech:gt.multitileentity:17251,,gregapi_post,TRUE,,15,145,166,2,,,,,,
gt.recipe.fuels.turbine,GregTech 6,gregtech:gt.multitileentity:17231,,gregapi_post,TRUE,,15,145,166,2,,,,,,
gt.recipe.fusionreactor,GregTech 6,gregtech:gt.multitileentity:17198,,gregapi_post,TRUE,,15,145,166,2,,,,,,
gt.recipe.generifier,GregTech 6,gregtech:gt.multitileentity:22001,,gregapi_post,TRUE,,15,145,166,2,,,,,,
gt.recipe.heatmixer,GregTech 6,gregtech:gt.multitileentity:20506,,gregapi_post,TRUE,,15,145,166,2,,,,,,
gt.recipe.implosioncompressor,GregTech 6,gregtech:gt.multitileentity:17110,,gregapi_post,TRUE,,15,145,166,2,,,,,,
gt.recipe.incubator,GregTech 6,gregtech:gt.multitileentity:22005,,gregapi_post,TRUE,,15,145,166,2,,,,,,
gt.recipe.injector,GregTech 6,gregtech:gt.multitileentity:20261,,gregapi_post,TRUE,,15,145,166,2,,,,,,
gt.recipe.ionizer,GregTech 6,gregtech:gt.multitileentity:17315,,gregapi_post,TRUE,,15,145,166,2,,,,,,
gt.recipe.juicer,GregTech 6,gregtech:gt.multitileentity:32722,,gregapi_post,TRUE,,15,145,166,2,,,,,,
gt.recipe.laminator,GregTech 6,gregtech:gt.multitileentity:20391,,gregapi_post,TRUE,,15,145,166,2,,,,,,
gt.recipe.lasercutter,GregTech 6,gregtech:gt.multitileentity:20631,,gregapi_post,TRUE,,15,145,166,2,,,,,,
gt.recipe.laserengraver,GregTech 6,gregtech:gt.multitileentity:20321,,gregapi_post,TRUE,,15,145,166,2,,,,,,
gt.recipe.lathe,GregTech 6,gregtech:gt.multitileentity:20041,,gregapi_post,TRUE,,15,145,166,2,,,,,,
gt.recipe.lightning,GregTech 6,gregtech:gt.multitileentity:20501,,gregapi_post,TRUE,,15,145,166,2,,,,,,
gt.recipe.loom,GregTech 6,gregtech:gt.multitileentity:20211,,gregapi_post,TRUE,,15,145,166,2,,,,,,
gt.recipe.magneticseparator,GregTech 6,gregtech:gt.multitileentity:20301,,gregapi_post,TRUE,,15,145,166,2,,,,,,
gt.recipe.maskaligner,GregTech 6,gregtech:gt.multitileentity:17122,,gregapi_post,TRUE,,15,145,166,2,,,,,,
gt.recipe.massfab,GregTech 6,gregtech:gt.multitileentity:20411,,gregapi_post,TRUE,,15,145,166,2,,,,,,
gt.recipe.mixer,GregTech 6,gregtech:gt.multitileentity:20181,,gregapi_post,TRUE,,15,145,166,2,,,,,,
gt.recipe.mortar,GregTech 6,gregtech:gt.multitileentity:32735,,gregapi_post,TRUE,,15,145,166,2,,,,,,
gt.recipe.nanofab,GregTech 6,gregtech:gt.multitileentity:20441,,gregapi_post,TRUE,,15,145,166,2,,,,,,
gt.recipe.oilcleaner,GregTech 6,gregtech:gt.multitileentity:17116,,gregapi_post,TRUE,,15,145,166,2,,,,,,
gt.recipe.particlecollider,GregTech 6,gregtech:gt.multitileentity:17200,,gregapi_post,TRUE,,15,145,166,2,,,,,,
gt.recipe.plantalyzer,GregTech 6,gregtech:gt.multitileentity:20531,,gregapi_post,TRUE,,15,145,166,2,,,,,,
gt.recipe.polarizer,GregTech 6,gregtech:gt.multitileentity:20221,,gregapi_post,TRUE,,15,145,166,2,,,,,,
gt.recipe.press,GregTech 6,gregtech:gt.multitileentity:20231,,gregapi_post,TRUE,,15,145,166,2,,,,,,
gt.recipe.printer,GregTech 6,gregtech:gt.multitileentity:20271,,gregapi_post,TRUE,,15,145,166,2,,,,,,
gt.recipe.replicator,GregTech 6,gregtech:gt.multitileentity:20431,,gregapi_post,TRUE,,15,145,166,2,,,,,,
gt.recipe.roaster,GregTech 6,gregtech:gt.multitileentity:20171,,gregapi_post,TRUE,,15,145,166,2,,,,,,
gt.recipe.rollbender,GregTech 6,gregtech:gt.multitileentity:20121,,gregapi_post,TRUE,,15,145,166,2,,,,,,
gt.recipe.rollformer,GregTech 6,gregtech:gt.multitileentity:20131,,gregapi_post,TRUE,,15,145,166,2,,,,,,
gt.recipe.rollingmill,GregTech 6,gregtech:gt.multitileentity:20111,,gregapi_post,TRUE,,15,145,166,2,,,,,,
gt.recipe.scannermolecular,GregTech 6,gregtech:gt.multitileentity:20423,,gregapi_post,TRUE,,15,145,166,2,,,,,,
gt.recipe.scannervisuals,GregTech 6,gregtech:gt.multitileentity:20281,,gregapi_post,TRUE,,15,145,166,2,,,,,,
gt.recipe.sharpener,GregTech 6,gregtech:gt.multitileentity:20511,,gregapi_post,TRUE,,15,145,166,2,,,,,,
gt.recipe.shredder,GregTech 6,gregtech:gt.multitileentity:20011,,gregapi_post,TRUE,,15,145,166,2,,,,,,
gt.recipe.sifter,GregTech 6,gregtech:gt.multitileentity:20051,,gregapi_post,TRUE,,15,145,166,2,,,,,,
gt.recipe.slicer,GregTech 6,gregtech:gt.multitileentity:20381,,gregapi_post,TRUE,,15,145,166,2,,,,,,
gt.recipe.sluice,GregTech 6,gregtech:gt.multitileentity:20291,,gregapi_post,TRUE,,15,145,166,2,,,,,,
gt.recipe.smelter,GregTech 6,gregtech:gt.multitileentity:20241,,gregapi_post,TRUE,,15,145,166,2,,,,,,
gt.recipe.squeezer,GregTech 6,gregtech:gt.multitileentity:20071,,gregapi_post,TRUE,,15,145,166,2,,,,,,
gt.recipe.steamcracking,GregTech 6,gregtech:gt.multitileentity:20491,,gregapi_post,TRUE,,15,145,166,2,,,,,,
gt.recipe.toolhead,GregTech 6,gregtech:gt.meta.toolHeadPickaxe:260,,gregapi_post,TRUE,,15,145,166,2,,,,,,
gt.recipe.unboxinator,GregTech 6,gregtech:gt.multitileentity:20591,,gregapi_post,TRUE,,15,145,166,2,,,,,,
gt.recipe.welder,GregTech 6,gregtech:gt.multitileentity:20331,,gregapi_post,TRUE,,15,145,166,2,,,,,,
gt.recipe.well,GregTech 6,gregtech:gt.multitileentity:17124,,gregapi_post,TRUE,,15,145,166,2,,,,,,
gt.recipe.wiremill,GregTech 6,gregtech:gt.multitileentity:20151,,gregapi_post,TRUE,,15,145,166,2,,,,,,
smelting,GregTech 6,gregtech:gt.multitileentity:20001,,gregapi_post,TRUE,,15,145,166,2,,,,,,This uses the same recipe map as the MC furnace
gt.recipe.trees,GregTech 6,minecraft:sapling,,gregapi_post,TRUE,,15,145,166,2,,,,,,
moze_intel.projecte.integration.NEI.NEIWorldTransmuteHandler,ProjectE,ProjectE:item.pe_philosophers_stone,,ProjectE,TRUE,,,45,,10,,,,,,
moze_intel.projecte.integration.NEI.NEIPhiloSmeltingHandler,ProjectE,ProjectE:item.pe_philosophers_stone,,ProjectE,TRUE,,,,,5,,,,,,
moze_intel.projecte.integration.NEI.NEIKleinStarHandler,ProjectE,ProjectE:item.pe_klein_star,,ProjectE,TRUE,,,,,5,,,,,,
moze_intel.projecte.integration.NEI.NEIAlchBagHandler,ProjectE,ProjectE:item.pe_alchemical_bag,,ProjectE,TRUE,,,,,5,,,,,,
de.katzenpapst.amunra.nei.recipehandler.ARCircuitFab,Pra's Galacticraft Mod,GalacticraftCore:tile.machine2:4,,GalacticraftAmunRa,TRUE,,,,,,,,,,,
de.katzenpapst.amunra.nei.recipehandler.ARNasaWorkbenchShuttle,Pra's Galacticraft Mod,GalacticraftAmunRa:item.itemShuttle,,GalacticraftAmunRa,TRUE,,,130,168,16,,,,,,
vazkii.botania.client.integration.nei.recipe.RecipeHandlerFloatingFlowers,Botania,Botania:miniIsland,,Botania,TRUE,,,,,5,,,,,,
vazkii.botania.client.integration.nei.recipe.RecipeHandlerPetalApothecary,Botania,Botania:altar,,Botania,TRUE,,,102,137,4,,,,,,
vazkii.botania.client.integration.nei.recipe.RecipeHandlerRunicAltar,Botania,Botania:runeAltar,,Botania,TRUE,,,122,137,4,,,,,,
vazkii.botania.client.integration.nei.recipe.RecipeHandlerManaPool,Botania,Botania:pool,,Botania,TRUE,,,90,137,4,,,,,,
vazkii.botania.client.integration.nei.recipe.RecipeHandlerElvenTrade,Botania,Botania:alfheimPortal,,Botania,TRUE,,,90,130,4,,,,,,
vazkii.botania.client.integration.nei.recipe.RecipeHandlerBrewery,Botania,Botania:brewery,,Botania,TRUE,,,,,4,,,,,,
vazkii.botania.client.integration.nei.recipe.RecipeHandlerPureDaisy,Botania,Botania:specialFlower,"{""type"": ""puredaisy""}",Botania,TRUE,,,,,4,,,,,,
vazkii.botania.client.integration.nei.recipe.RecipeHandlerLexicaBotania,Botania,Botania:lexicon,,Botania,TRUE,,,,,,,,,,,
com.jaquadro.minecraft.storagedrawers.integration.notenoughitems.UpgradeItemRecipeHandler,Storage Drawers,minecraft:crafting_table,,StorageDrawers,TRUE,,,65,166,5,,,,,,
ieArcFurnace,Immersive Engineering,ImmersiveEngineering:graphiteElectrode,,ImmersiveEngineering,TRUE,,,65,166,5,,,,,,
NEIArcFurnaceHandlerAlloying,Immersive Engineering,terrafirmacraftplus:item.Bronze Ingot,,ImmersiveEngineering,TRUE,,,65,166,5,,,,,,
NEIArcFurnaceHandlerOres,Immersive Engineering,minecraft:iron_ore,,ImmersiveEngineering,TRUE,,,65,166,5,,,,,,
NEIArcFurnaceHandlerSmelting,Immersive Engineering,terrafirmacraftplus:item.Ore:100,,ImmersiveEngineering,TRUE,,,65,166,5,,,,,,
NEIArcFurnaceHandlerGlassworking,Immersive Engineering,minecraft:glass,,ImmersiveEngineering,TRUE,,,65,166,5,,,,,,
NEIArcFurnaceHandlerDecarburization,Immersive Engineering,terrafirmacraftplus:item.Wrought Iron Ingot,,ImmersiveEngineering,TRUE,,,65,166,5,,,,,,
NEIArcFurnaceHandlerCarburization,Immersive Engineering,terrafirmacraftplus:item.HC Steel Ingot,,ImmersiveEngineering,TRUE,,,65,166,5,,,,,,
NEIArcFurnaceHandlerHeating,Immersive Engineering,,,ImmersiveEngineering,TRUE,,,65,166,5,nei:textures/nei_tabbed_sprites.png,80,0,14,14,
NEIArcFurnaceHandlerMelting,Immersive Engineering,terrafirmacraftplus:item.Molten Glass,,ImmersiveEngineering,TRUE,,,65,166,5,,,,,,
NEIArcFurnaceHandlerWelding,Immersive Engineering,terrafirmacraftplus:item.Bismuth Double Ingot,,ImmersiveEngineering,TRUE,,,65,166,5,,,,,,
NEIArcFurnaceHandlerElectrolysis,Immersive Engineering,teloaddon:Alumina,,ImmersiveEngineering,TRUE,,,65,166,5,,,,,,
blusunrize.immersiveengineering.client.nei.NEIShaderBagHandler,Immersive Engineering,ImmersiveEngineering:shaderBag,,ImmersiveEngineering,TRUE,,,65,166,5,,,,,,
blusunrize.immersiveengineering.client.nei.NEIBlueprintHandler,Immersive Engineering,ImmersiveEngineering:blueprint,,ImmersiveEngineering,TRUE,,,65,166,5,,,,,,
blusunrize.immersiveengineering.client.nei.NEICokeOvenHandler,Immersive Engineering,ImmersiveEngineering:stoneDecoration:1,,ImmersiveEngineering,TRUE,,,71,166,5,,,,,,
blusunrize.immersiveengineering.client.nei.NEIBlastFurnaceHandler,Immersive Engineering,ImmersiveEngineering:stoneDecoration:2,,ImmersiveEngineering,TRUE,,,71,166,5,,,,,,
blusunrize.immersiveengineering.client.nei.NEISqueezerHandler,Immersive Engineering,ImmersiveEngineering:metalMultiblock:2,,ImmersiveEngineering,TRUE,,,71,166,5,,,,,,
blusunrize.immersiveengineering.client.nei.NEIFermenterHandler,Immersive Engineering,ImmersiveEngineering:metalMultiblock:3,,ImmersiveEngineering,TRUE,,,71,166,5,,,,,,
blusunrize.immersiveengineering.client.nei.NEIRefineryHandler,Immersive Engineering,ImmersiveEngineering:metalDevice2:5,,ImmersiveEngineering,TRUE,,,65,166,5,,,,,,
blusunrize.immersiveengineering.client.nei.NEIBottlingMachineHandler,Immersive Engineering,minecraft:glass_bottle,,ImmersiveEngineering,TRUE,,,65,166,5,,,,,,
blusunrize.immersiveengineering.client.nei.NEIMetalPressHandler,Immersive Engineering,ImmersiveEngineering:mold,,ImmersiveEngineering,TRUE,,,65,166,5,,,,,,
blusunrize.immersiveengineering.client.nei.NEICrusherHandler,Immersive Engineering,minecraft:hopper,,ImmersiveEngineering,TRUE,,,71,166,5,,,,,,
net.dries007.tfcnei.recipeHandlers.AnvilRecipeHandler,TerraFirmaCraft+,terrafirmacraftplus:Anvil,,terrafirmacraftplus,TRUE,,10,138,208,2,,,,,,
net.dries007.tfcnei.recipeHandlers.QuernRecipeHandler,TerraFirmaCraft+,terrafirmacraftplus:item.Quern,,terrafirmacraftplus,TRUE,,,65,166,5,,,,,,
net.dries007.tfcnei.recipeHandlers.KilnRecipeHandler,TerraFirmaCraft+,,,terrafirmacraftplus,TRUE,,,65,166,5,terrafirmacraftneiplugin:textures/gui/pitkiln.png,47,38,14,14,
net.dries007.tfcnei.recipeHandlers.LoomRecipeHandler,TerraFirmaCraft+,terrafirmacraftplus:Loom,,terrafirmacraftplus,TRUE,,,65,166,5,,,,,,
net.dries007.tfcnei.recipeHandlers.KnappingRecipeHandler,TerraFirmaCraft+,terrafirmacraftplus:item.LooseRock,,terrafirmacraftplus,TRUE,,,96,166,3,,,,,,
net.dries007.tfcnei.recipeHandlers.ClothingRecipeHandler,TerraFirmaCraft+,terrafirmacraftplus:item.Bone Needle Thread,,terrafirmacraftplus,TRUE,,,65,166,5,,,,,,
net.dries007.tfcnei.recipeHandlers.BarrelRecipeHandler,TerraFirmaCraft+,terrafirmacraftplus:Barrel,,terrafirmacraftplus,TRUE,,,65,166,5,,,,,,
net.dries007.tfcnei.recipeHandlers.AlloyRecipeHandler,TerraFirmaCraft+,terrafirmacraftplus:Crucible,,terrafirmacraftplus,TRUE,,,65,166,5,,,,,,
net.dries007.tfcnei.recipeHandlers.HeatRecipeHandler,TerraFirmaCraft+,terrafirmacraftplus:Firepit,,terrafirmacraftplus,TRUE,,,65,166,5,,,,,,
minechem.nei.ChemicalBucketNEIRecipeHandler,Minecraft,minecraft:crafting_table,,minechem,TRUE,,,65,166,5,,,,,,
minechem.nei.DecomposerNEIRecipeHandler,Minechem,minechem:tile.chemicalDecomposer,,minechem,TRUE,,,131,166,2,,,,,,
minechem.nei.SynthesisNEIRecipeHandler,Minechem,minechem:tile.chemicalSynthesizer,,minechem,TRUE,,,65,166,5,,,,,,
exter.fodc.nei.ODCRecipeHandler,Ore Dictionary Converter,fodc:oreConvTable,,fodc,TRUE,,,,,4,,,,,,
cofh.thermalexpansion.plugins.nei.handlers.RecipeHandlerCharger,Thermal Expansion,ThermalExpansion:Machine:10,,ThermalExpansion,TRUE,,,65,166,5,,,,,,
cofh.thermalexpansion.plugins.nei.handlers.RecipeHandlerCraftingMachine,Thermal Expansion,ThermalExpansion:Frame,,ThermalExpansion,TRUE,,,65,166,5,,,,,,
cofh.thermalexpansion.plugins.nei.handlers.RecipeHandlerCraftingSecure,Thermal Expansion,ThermalExpansion:material:16,,ThermalExpansion,TRUE,,,65,166,5,,,,,,
cofh.thermalexpansion.plugins.nei.handlers.RecipeHandlerCraftingUpgrade,Thermal Expansion,ThermalExpansion:Frame:3,,ThermalExpansion,TRUE,,,65,166,5,,,,,,
cofh.thermalexpansion.plugins.nei.handlers.RecipeHandlerCrucible,Thermal Expansion,ThermalExpansion:Machine:4,,ThermalExpansion,TRUE,,,65,166,5,,,,,,
cofh.thermalexpansion.plugins.nei.handlers.RecipeHandlerFurnace,Thermal Expansion,ThermalExpansion:Machine:0,,ThermalExpansion,TRUE,,,65,166,5,,,,,,
cofh.thermalexpansion.plugins.nei.handlers.RecipeHandlerInsolator,Thermal Expansion,ThermalExpansion:Machine:11,,ThermalExpansion,TRUE,,,65,166,5,,,,,,
cofh.thermalexpansion.plugins.nei.handlers.RecipeHandlerPulverizer,Thermal Expansion,ThermalExpansion:Machine:1,,ThermalExpansion,TRUE,,,65,166,5,,,,,,
cofh.thermalexpansion.plugins.nei.handlers.RecipeHandlerSawmill,Thermal Expansion,ThermalExpansion:Machine:2,,ThermalExpansion,TRUE,,,65,166,5,,,,,,
cofh.thermalexpansion.plugins.nei.handlers.RecipeHandlerSmelter,Thermal Expansion,ThermalExpansion:Machine:3,,ThermalExpansion,TRUE,,,65,166,5,,,,,,
cofh.thermalexpansion.plugins.nei.handlers.RecipeHandlerTransposer,Thermal Expansion,ThermalExpansion:Machine:5,,ThermalExpansion,TRUE,,,65,166,5,,,,,,
mekanism.client.nei.ChemicalCrystallizerRecipeHandler,Mekanism,Mekanism:MachineBlock2:8,,Mekanism,TRUE,,,79,,4,,,,,,
mekanism.client.nei.ChemicalDissolutionChamberRecipeHandler,Mekanism,Mekanism:MachineBlock2:6,,Mekanism,TRUE,,,79,,4,,,,,,
mekanism.client.nei.ChemicalInfuserRecipeHandler,Mekanism,Mekanism:MachineBlock2:2,,Mekanism,TRUE,,,80,,4,,,,,,
mekanism.client.nei.ChemicalInjectionChamberRecipeHandler,Mekanism,Mekanism:MachineBlock2:3,,Mekanism,TRUE,,,68,,5,,,,,,
mekanism.client.nei.ChemicalOxidizerRecipeHandler,Mekanism,Mekanism:MachineBlock2:1,,Mekanism,TRUE,,,62,,5,,,,,,
mekanism.client.nei.ChemicalWasherRecipeHandler,Mekanism,Mekanism:MachineBlock2:7,,Mekanism,TRUE,,,70,,5,,,,,,
mekanism.client.nei.CombinerRecipeHandler,Mekanism,Mekanism:MachineBlock:2,,Mekanism,TRUE,,,68,,5,,,,,,
mekanism.client.nei.CrusherRecipeHandler,Mekanism,Mekanism:MachineBlock:3,,Mekanism,TRUE,,,68,,5,,,,,,
mekanism.client.nei.MetallurgicInfuserRecipeHandler,Mekanism,Mekanism:MachineBlock:8,,Mekanism,TRUE,,,56,,5,,,,,,
mekanism.client.nei.OsmiumCompressorRecipeHandler,Mekanism,Mekanism:MachineBlock:1,,Mekanism,TRUE,,,68,,5,,,,,,
mekanism.client.nei.PRCRecipeHandler,Mekanism,Mekanism:MachineBlock2:10,,Mekanism,TRUE,,,68,,5,,,,,,
mekanism.client.nei.PrecisionSawmillRecipeHandler,Mekanism,Mekanism:MachineBlock2:5,,Mekanism,TRUE,,,68,,5,,,,,,
mekanism.client.nei.PurificationChamberRecipeHandler,Mekanism,Mekanism:MachineBlock:9,,Mekanism,TRUE,,,68,,5,,,,,,
mekanism.client.nei.RotaryCondensentratorRecipeHandler,Mekanism,Mekanism:MachineBlock2:0,,Mekanism,TRUE,,,71,,5,,,,,,
mekanism.client.nei.ShapedMekanismRecipeHandler,Mekanism,minecraft:crafting_table,,Mekanism,TRUE,,,65,166,5,,,,,,
mekanism.client.nei.ShapelessMekanismRecipeHandler,Mekanism,minecraft:crafting_table,,Mekanism,TRUE,,,65,166,5,,,,,,
mekanism.client.nei.SolarNeutronRecipeHandler,Mekanism,Mekanism:MachineBlock3:1,,Mekanism,TRUE,,,70,,5,,,,,,
mekanism.client.nei.ThermalEvaporationRecipeHandler,Mekanism,Mekanism:BasicBlock:14,,Mekanism,TRUE,,,62,,5,,,,,,
exnihilo.compatibility.nei.RecipeHandlerHammer,Ex Nihilo,exnihilo:hammer_iron,,exnihilo,TRUE,,,58,,5,,,,,,
exnihilo.compatibility.nei.RecipeHandlerSieve,Ex Nihilo,exnihilo:sifting_table,,exnihilo,TRUE,,,130,,2,,,,,,
gregtechmod.mistaqur.nei.handlers.AlloySmelterRecipeHandler,GregTech-Addon,gregtech_addon:machine:56,,gregtech_addon,TRUE,,15,145,166,2,,,,,,
gregtechmod.mistaqur.nei.handlers.AssemblerRecipeHandler,GregTech-Addon,gregtech_addon:machine:60,,gregtech_addon,TRUE,,15,145,166,2,,,,,,
gregtechmod.mistaqur.nei.handlers.BenderRecipeHandler,GregTech-Addon,gregtech_addon:machine:59,,gregtech_addon,TRUE,,15,145,166,2,,,,,,
gregtechmod.mistaqur.nei.handlers.BlastRecipeHandler,GregTech-Addon,gregtech_addon:machine:29,,gregtech_addon,TRUE,,15,145,166,2,,,,,,
gregtechmod.mistaqur.nei.handlers.BronzeBlastRecipeHandler,GregTech-Addon,gregtech_addon:machine:136,,gregtech_addon,TRUE,,15,145,166,2,,,,,,
gregtechmod.mistaqur.nei.handlers.CannerRecipeHandler,GregTech-Addon,gregtech_addon:machine:57,,gregtech_addon,TRUE,,15,145,166,2,,,,,,
gregtechmod.mistaqur.nei.handlers.CentrifugeRecipeHandler,GregTech-Addon,gregtech_addon:machine:62,,gregtech_addon,TRUE,,15,145,166,2,,,,,,
gregtechmod.mistaqur.nei.handlers.ChemicalRecipeHandler,GregTech-Addon,gregtech_addon:machine:41,,gregtech_addon,TRUE,,15,145,166,2,,,,,,
gregtechmod.mistaqur.nei.handlers.CutterRecipeHandler,GregTech-Addon,gregtech_addon:machine:113,,gregtech_addon,TRUE,,15,145,166,2,,,,,,
gregtechmod.mistaqur.nei.handlers.DistillationRecipeHandler,GregTech-Addon,gregtech_addon:machine:44,,gregtech_addon,TRUE,,15,145,166,2,,,,,,
gregtechmod.mistaqur.nei.handlers.ElectrolyzerRecipeHandler,GregTech-Addon,gregtech_addon:machine:25,,gregtech_addon,TRUE,,15,145,166,2,,,,,,
gregtechmod.mistaqur.nei.handlers.ExtruderRecipeHandler,GregTech-Addon,gregtech_addon:machine:115,,gregtech_addon,TRUE,,15,145,166,2,,,,,,
gregtechmod.mistaqur.nei.handlers.FusionRecipeHandler,GregTech-Addon,gregtech_addon:machine:80,,gregtech_addon,TRUE,,15,145,166,2,,,,,,
gregtechmod.mistaqur.nei.handlers.GeneratorHandler,GregTech-Addon,,,gregtech_addon,TRUE,,15,145,166,2,nei:textures/nei_tabbed_sprites.png,80,0,14,14,
gregtechmod.mistaqur.nei.handlers.GrinderRecipeHandler,GregTech-Addon,gregtech_addon:machine:28,,gregtech_addon,TRUE,,15,145,166,2,,,,,,
gregtechmod.mistaqur.nei.handlers.ImplosionRecipeHandler,GregTech-Addon,gregtech_addon:machine:31,,gregtech_addon,TRUE,,15,145,166,2,,,,,,
gregtechmod.mistaqur.nei.handlers.LatheRecipeHandler,GregTech-Addon,gregtech_addon:machine:111,,gregtech_addon,TRUE,,15,145,166,2,,,,,,
gregtechmod.mistaqur.nei.handlers.SawmillRecipeHandler,GregTech-Addon,gregtech_addon:machine:32,,gregtech_addon,TRUE,,15,145,166,2,,,,,,
gregtechmod.mistaqur.nei.handlers.VacuumFreezerRecipeHandler,GregTech-Addon,gregtech_addon:machine:38,,gregtech_addon,TRUE,,15,145,166,2,,,,,,
gregtechmod.mistaqur.nei.handlers.WiremillRecipeHandler,GregTech-Addon,gregtech_addon:machine:55,,gregtech_addon,TRUE,,15,145,166,2,,,,,,
cofh.thermaldynamics.plugins.nei.RecipeHandlerCover,Thermal Dynamics,ThermalDynamics:cover,"{Block:""minecraft:glass"",Meta:0b}",ThermalDynamics,TRUE,,,65,166,5,,,,,,
neresources.nei.NEIAdvSeedHandler,Not Enough Resources,minecraft:wheat,,neresources,TRUE,,,65,166,5,,,,,,
neresources.nei.NEIDungeonHandler,Not Enough Resources,minecraft:chest,,neresources,TRUE,,,130,166,2,,,,,,
neresources.nei.NEIEnchantmentHandler,Not Enough Resources,minecraft:anvil,,neresources,TRUE,,,130,166,2,,,,,,
neresources.nei.NEIMobHandler,Not Enough Resources,minecraft:skull:4,,neresources,TRUE,,,130,166,2,,,,,,
neresources.nei.NEIOreHandler,Not Enough Resources,minecraft:diamond_ore,,neresources,TRUE,,,65,166,5,,,,,,
neresources.nei.NEIPlantHandler,Not Enough Resources,minecraft:wheat,,neresources,TRUE,,,130,166,2,,,,,,
1 handler modName itemName nbtInfo modId modRequired excludedModId yShift handlerHeight handlerWidth maxRecipesPerPage imageResource imageX imageY imageWidth imageHeight itemNotes
2 codechicken.nei.recipe.BrewingRecipeHandler Minecraft minecraft:brewing_stand minecraft FALSE 65 166 5
3 codechicken.nei.recipe.FireworkRecipeHandler Minecraft minecraft:fireworks minecraft FALSE 65 166 5
4 codechicken.nei.recipe.FurnaceRecipeHandler Minecraft minecraft:furnace minecraft FALSE 65 166 5
5 codechicken.nei.recipe.ShapedRecipeHandler Minecraft minecraft:crafting_table minecraft FALSE 65 166 5
6 codechicken.nei.recipe.ShapelessRecipeHandler Minecraft minecraft:crafting_table minecraft FALSE 65 166 5
7 codechicken.nei.recipe.FuelRecipeHandler Minecraft minecraft FALSE 65 166 5 nei:textures/nei_tabbed_sprites.png 80 0 14 14
8 advsolar.client.nei.MTRecipeHandler Advanced Solar Panels AdvancedSolarPanel:BlockMolecularTransformer AdvancedSolarPanel TRUE 68 5
9 appeng.integration.modules.NEIHelpers.NEIAEShapedRecipeHandler Applied Energistics 2 appliedenergistics2:item.ItemMultiPart:380 appliedenergistics2 TRUE 65 5
10 appeng.integration.modules.NEIHelpers.NEIAEShapelessRecipeHandler Applied Energistics 2 appliedenergistics2:item.ItemMultiPart:380 appliedenergistics2 TRUE 65 5
11 appeng.integration.modules.NEIHelpers.NEIFacadeRecipeHandler Applied Energistics 2 appliedenergistics2:item.ItemFacade:192 appliedenergistics2 TRUE 65 5
12 appeng.integration.modules.NEIHelpers.NEIGrinderRecipeHandler Applied Energistics 2 appliedenergistics2:tile.BlockGrinder appliedenergistics2 TRUE
13 appeng.integration.modules.NEIHelpers.NEIInscriberRecipeHandler Applied Energistics 2 appliedenergistics2:tile.BlockInscriber appliedenergistics2 TRUE 70 5
14 appeng.integration.modules.NEIHelpers.NEIWorldCraftingHandler Applied Energistics 2 appliedenergistics2:item.ItemMultiMaterial:9 appliedenergistics2 TRUE 85 5 There's only some explanatory text for fluix crystals and QEDs
15 aroma1997.core.recipes.nei.ShapedAromicRecipeHandler AromaBackup minecraft:crafting_table AromaBackup TRUE 65 5
16 aroma1997.core.recipes.nei.ShapelessAromicRecipeHandler AromaBackup minecraft:crafting_table AromaBackup TRUE
17 fox.spiteful.avaritia.compat.nei.CompressionHandler Avaritia Avaritia:Neutronium_Compressor Avaritia TRUE 50 6
18 fox.spiteful.avaritia.compat.nei.ExtremeShapedRecipeHandler Avaritia Avaritia:Dire_Crafting Avaritia TRUE 208 256 1 Part of it even goes off the left side (included)
19 fox.spiteful.avaritia.compat.nei.ExtremeShapelessRecipeHandler Avaritia Avaritia:Dire_Crafting Avaritia TRUE 208 256 1 If you can cut off/place over the jaggedness at the bottom, you could barely get a second on
20 WayofTime.alchemicalWizardry.client.nei.NEIAlchemyRecipeHandler Blood Magic AWWayofTime:blockWritingTable AWWayofTime TRUE 68 5
21 WayofTime.alchemicalWizardry.client.nei.NEIAltarRecipeHandler Blood Magic AWWayofTime:Altar AWWayofTime TRUE 65 5 Handler name needs shifting left
22 WayofTime.alchemicalWizardry.client.nei.NEIBindingRitualHandler Blood Magic AWWayofTime:sacrificialKnife AWWayofTime TRUE 50 6
23 WayofTime.alchemicalWizardry.client.nei.NEIBloodOrbShapedHandler Blood Magic AWWayofTime:AlchemicalWizardrybloodRune:3 AWWayofTime TRUE 65 5
24 WayofTime.alchemicalWizardry.client.nei.NEIBloodOrbShapelessHandler Blood Magic AWWayofTime:AlchemicalWizardrybloodRune:4 AWWayofTime TRUE 65 5
25 bw.fuels.acidgens BartWorks gregtech:gt.blockmachines:12726 bartworks TRUE 145 2
26 bw.recipe.cal BartWorks gregtech:gt.blockmachines:12735 bartworks TRUE 135 2
27 gg.recipe.naquadah_reactor Good Generator gregtech:gt.blockmachines:12732 GoodGenerator TRUE 145 1
28 gg.recipe.naquadah_fuel_refine_factory Good Generator gregtech:gt.blockmachines:16999 GoodGenerator TRUE 145 1
29 com.github.bartimaeusnek.bartworks.neiHandler.BW_NEI_BioLabHandler BartWorks gregtech:gt.blockmachines:12699 bartworks TRUE 145 2
30 com.github.bartimaeusnek.bartworks.neiHandler.BW_NEI_BioVatHandler BartWorks gregtech:gt.blockmachines:12712 bartworks TRUE 140 2
31 com.github.bartimaeusnek.bartworks.neiHandler.BW_NEI_OreHandler BartWorks bartworks:bw.blockores.01:89 bartworks TRUE 135 2
32 gt.recipe.electricimplosioncompressor BartWorks gregtech:gt.blockmachines:12734 bartworks TRUE 135 2
33 net.bdew.neiaddons.botany.flowers.FlowerBreedingHandler Botany Botany:flower Botany TRUE 65 5
34 buildcraft.compat.nei.RecipeHandlerRefinery BuildCraft BuildCraft|Factory:refineryBlock BuildCraft|Factory TRUE 60 5 There's only 2 recipes though
35 buildcraft.compat.nei.RecipeHandlerAssemblyTable BuildCraft BuildCraft|Silicon:laserTableBlock BuildCraft|Silicon TRUE 100 3
36 buildcraft.compat.nei.RecipeHandlerIntegrationTable BuildCraft BuildCraft|Silicon:laserTableBlock:2 BuildCraft|Silicon TRUE 85 4
37 team.chisel.compat.nei.RecipeHandlerChisel Chisel chisel:chisel chisel TRUE 135 2
38 crazypants.enderio.nei.AlloySmelterRecipeHandler Ender IO EnderIO:blockAlloySmelter EnderIO TRUE 65 5
39 crazypants.enderio.nei.EnchanterRecipeHandler Ender IO EnderIO:blockEnchanter EnderIO TRUE 65 5
40 crazypants.enderio.nei.SagMillRecipeHandler Ender IO EnderIO:blockSagMill EnderIO TRUE 68 5
41 crazypants.enderio.nei.SliceAndSpliceRecipeHandler Ender IO EnderIO:blockSliceAndSplice EnderIO TRUE 65 5
42 crazypants.enderio.nei.SoulBinderRecipeHandler Ender IO EnderIO:blockSoulBinder EnderIO TRUE 68 5
43 crazypants.enderio.nei.VatRecipeHandler Ender IO EnderIO:blockVat EnderIO TRUE 65 5
44 extracells.integration.nei.UniversalTerminalRecipe Extra Cells 2 extracells:part.base:9 extracells TRUE 65 5
45 com.rwtema.extrautils.nei.EnderConstructorHandler Extra Utilities ExtraUtilities:endConstructor ExtraUtilities TRUE 68 5
46 com.rwtema.extrautils.nei.FMPMicroBlocksHandler Extra Utilities ForgeMicroblock:sawIron ExtraUtilities TRUE 65 5
47 com.rwtema.extrautils.nei.InfoHandler Extra Utilities ExtraUtilities:chandelier ExtraUtilities TRUE 135 2 Info on blocks, can vary wildly. EQ was this length, there might be a longer one
48 com.rwtema.extrautils.nei.MicroBlocksHandler Extra Utilities ExtraUtilities:microblocks:1 ExtraUtilities TRUE
49 com.rwtema.extrautils.nei.SoulHandler Extra Utilities ExtraUtilities:mini-soul ExtraUtilities TRUE
50 hellfirepvp.beebetteratbees.client.gui.BBABGuiRecipeTreeHandler Bees Forestry:beeQueenGE Forestry TRUE 140 2
51 forestry.factory.recipes.nei.NEIHandlerBottler Forestry for Minecraft Forestry:factory Forestry TRUE 68 5
52 forestry.factory.recipes.nei.NEIHandlerCarpenter Forestry for Minecraft Forestry:factory:1 Forestry TRUE 65 5
53 forestry.factory.recipes.nei.NEIHandlerCentrifuge Forestry for Minecraft Forestry:factory:2 Forestry TRUE 65 5
54 forestry.factory.recipes.nei.NEIHandlerFabricator Forestry for Minecraft Forestry:factory2 Forestry TRUE
55 forestry.factory.recipes.nei.NEIHandlerFermenter Forestry for Minecraft Forestry:factory:3 Forestry TRUE 65 5
56 forestry.factory.recipes.nei.NEIHandlerMoistener Forestry for Minecraft Forestry:factory:4 Forestry TRUE 68 5
57 forestry.factory.recipes.nei.NEIHandlerSqueezer Forestry for Minecraft Forestry:factory:5 Forestry TRUE 68 5
58 forestry.factory.recipes.nei.NEIHandlerStill Forestry for Minecraft Forestry:factory:6 Forestry TRUE 65 5
59 net.bdew.neiaddons.forestry.bees.BeeBreedingHandler Forestry for Minecraft Forestry:beeQueenGE Forestry TRUE 65 5
60 net.bdew.neiaddons.forestry.bees.BeeProduceHandler Forestry for Minecraft Forestry:beeQueenGE Forestry TRUE 65 5
61 net.bdew.neiaddons.forestry.butterflies.ButterflyBreedingHandler Forestry for Minecraft Forestry:butterflyGE Forestry TRUE
62 net.bdew.neiaddons.forestry.trees.TreeBreedingHandler Forestry for Minecraft Forestry:saplingGE Forestry TRUE 65 5
63 net.bdew.neiaddons.forestry.trees.TreeProduceHandler Forestry for Minecraft Forestry:saplingGE Forestry TRUE 65 5
64 galaxyspace.core.nei.rocket.RocketT1RecipeHandler Galacticraft GalacticraftCore:item.spaceship GalacticraftCore TRUE 125 2
65 micdoodle8.mods.galacticraft.core.nei.BuggyRecipeHandler Galacticraft GalacticraftCore:tile.rocketWorkbench GalacticraftCore TRUE 10 135 2
66 micdoodle8.mods.galacticraft.core.nei.CircuitFabricatorRecipeHandler Galacticraft GalacticraftCore:tile.machine2:4 GalacticraftCore TRUE
67 micdoodle8.mods.galacticraft.core.nei.ElectricIngotCompressorRecipeHandler Galacticraft GalacticraftCore:tile.machine2 GalacticraftCore TRUE
68 micdoodle8.mods.galacticraft.core.nei.IngotCompressorRecipeHandler Galacticraft GalacticraftCore:tile.machine:12 GalacticraftCore TRUE
69 micdoodle8.mods.galacticraft.core.nei.RefineryRecipeHandler Galacticraft GalacticraftCore:tile.refinery GalacticraftCore TRUE
70 micdoodle8.mods.galacticraft.planets.asteroids.nei.AstroMinerRecipeHandler Galacticraft GalacticraftCore:tile.rocketWorkbench GalacticraftCore TRUE 100 3
71 micdoodle8.mods.galacticraft.planets.mars.nei.CargoRocketRecipeHandler Galacticraft GalacticraftCore:tile.rocketWorkbench GalacticraftCore TRUE 10 125 2
72 micdoodle8.mods.galacticraft.planets.mars.nei.GasLiquefierRecipeHandler Galacticraft GalacticraftMars:tile.marsMachineT2 GalacticraftCore TRUE
73 micdoodle8.mods.galacticraft.planets.mars.nei.MethaneSynthesizerRecipeHandler Galacticraft GalacticraftMars:tile.marsMachineT2:4 GalacticraftCore TRUE
74 galaxyspace.core.nei.rocket.RocketT2RecipeHandler Galacticraft GalacticraftMars:item.spaceshipTier2:1 GalacticraftMars TRUE 5 145 2
75 galaxyspace.core.nei.rocket.RocketT3RecipeHandler Galacticraft GalacticraftMars:item.itemTier3Rocket GalacticraftMars TRUE 5 145 2
76 galaxyspace.core.nei.AssemblyMachineRecipeHandler GalaxySpace GalaxySpace:assemblymachine GalaxySpace TRUE
77 galaxyspace.core.nei.rocket.RocketT4RecipeHandler GalaxySpace GalaxySpace:item.Tier4Rocket GalaxySpace TRUE 10 160 2
78 galaxyspace.core.nei.rocket.RocketT5RecipeHandler GalaxySpace GalaxySpace:item.Tier5Rocket GalaxySpace TRUE 10 160 2
79 galaxyspace.core.nei.rocket.RocketT6RecipeHandler GalaxySpace GalaxySpace:item.Tier6Rocket GalaxySpace TRUE 10 160 2
80 galaxyspace.core.nei.rocket.RocketT7RecipeHandler GalaxySpace GalaxySpace:item.Tier7Rocket GalaxySpace TRUE 10 180 1
81 galaxyspace.core.nei.rocket.RocketT8RecipeHandler GalaxySpace GalaxySpace:item.Tier8Rocket GalaxySpace TRUE 10 180 1
82 net.bdew.gendustry.nei.ExtractorHandler Gendustry gendustry:Extractor gendustry TRUE 68 5
83 net.bdew.gendustry.nei.ImprinterHandler Gendustry gendustry:Imprinter gendustry TRUE 68 5
84 net.bdew.gendustry.nei.LiquifierHandler Gendustry gendustry:Liquifier gendustry TRUE 68 5
85 net.bdew.gendustry.nei.MutagenProducerHandler Gendustry gendustry:MutagenProducer gendustry TRUE 68 5
86 net.bdew.gendustry.nei.MutatronHandler Gendustry gendustry:Mutatron gendustry TRUE 65 5
87 net.bdew.gendustry.nei.ReplicatorHandler Gendustry gendustry:Replicator gendustry TRUE 68 5
88 net.bdew.gendustry.nei.SamplerHandler Gendustry gendustry:Sampler gendustry TRUE 68 5
89 net.bdew.gendustry.nei.TemplateCraftingHandler Gendustry gendustry:GeneTemplate gendustry TRUE 105 3
90 net.bdew.gendustry.nei.TransposerHandler Gendustry gendustry:Transposer gendustry TRUE 68 5
91 gt.recipe.alloysmelter GregTech gregtech:gt.blockmachines:201 gregtech TRUE gregapi_post 6 135 166 2
92 gt.recipe.arcfurnace GregTech gregtech:gt.blockmachines:651 gregtech TRUE gregapi_post 6 135 166 2
93 gt.recipe.assembler GregTech gregtech:gt.blockmachines:211 gregtech TRUE gregapi_post 6 145 166 2
94 gt.recipe.autoclave GregTech gregtech:gt.blockmachines:571 gregtech TRUE gregapi_post 6 135 166 2
95 gt.recipe.blastfurnace GregTech gregtech:gt.blockmachines:1000 gregtech TRUE gregapi_post 6 135 166 2
96 gt.recipe.brewer GregTech gregtech:gt.blockmachines:491 gregtech TRUE gregapi_post 6 135 166 2
97 gt.recipe.byproductlist GregTech gregtech:gt.metaitem.01:2019 gregtech TRUE gregapi_post 6 135 166 2
98 gt.recipe.canner GregTech gregtech:gt.blockmachines:231 gregtech TRUE gregapi_post 6 135 166 2
99 gt.recipe.centrifuge GregTech gregtech:gt.blockmachines:361 gregtech TRUE gregapi_post 6 135 166 2
100 gt.recipe.chemicalbath GregTech gregtech:gt.blockmachines:541 gregtech TRUE gregapi_post 6 135 166 2
101 gt.recipe.chemicalreactor GregTech gregtech:gt.blockmachines:421 gregtech TRUE gregapi_post 6 135 166 2
102 gt.recipe.circuitassembler GregTech gregtech:gt.blockmachines:1180 gregtech TRUE gregapi_post 6 135 166 2
103 gt.recipe.cncmachine GregTech gregtech:gt.metaitem.01:23305 gregtech TRUE gregapi_post 6 135 166 2
104 gt.recipe.cokeoven GregTech gregtech:gt.blockmachines:791 gregtech TRUE gregapi_post 6 135 166 2
105 gt.recipe.componentassembler GregTech gregtech:gt.blockmachines:211 gregtech TRUE gregapi_post 6 135 166 2
106 gt.recipe.compressor GregTech gregtech:gt.blockmachines:241 gregtech TRUE gregapi_post 6 135 166 2
107 gt.recipe.craker GregTech gregtech:gt.blockmachines:1160 gregtech TRUE gregapi_post 6 135 166 2
108 gt.recipe.cuttingsaw GregTech gregtech:gt.blockmachines:251 gregtech TRUE gregapi_post 6 135 166 2
109 gt.recipe.dieselgeneratorfuel GregTech gregtech:gt.blockmachines:1110 gregtech TRUE gregapi_post 6 135 166 2
110 gt.recipe.distillationtower GregTech gregtech:gt.blockmachines:1126 gregtech TRUE gregapi_post 6 135 166 2
111 gt.recipe.distillery GregTech gregtech:gt.blockmachines:531 gregtech TRUE gregapi_post 6 135 166 2
112 gt.recipe.electrolyzer GregTech gregtech:gt.blockmachines:371 gregtech TRUE gregapi_post 6 135 166 2
113 gt.recipe.electromagneticseparator GregTech gregtech:gt.blockmachines:561 gregtech TRUE gregapi_post 6 135 166 2
114 gt.recipe.extractor GregTech gregtech:gt.blockmachines:271 gregtech TRUE gregapi_post 6 135 166 2
115 gt.recipe.extrahugenaquadahreactor GregTech gregtech:gt.blockmachines:1189 gregtech TRUE gregapi_post 6 135 166 2
116 gt.recipe.extremedieselgeneratorfuel GregTech gregtech:gt.blockmachines:2105 gregtech TRUE gregapi_post 6 135 166 2
117 gt.recipe.extruder GregTech gregtech:gt.blockmachines:281 gregtech TRUE gregapi_post 6 135 166 2
118 gt.recipe.fakeAssemblylineProcess GregTech gregtech:gt.blockmachines:1170 gregtech TRUE gregapi_post 12 135 166 2
119 gt.recipe.fermenter GregTech gregtech:gt.blockmachines:501 gregtech TRUE gregapi_post 6 135 166 2
120 gt.recipe.fluidcanner GregTech gregtech:gt.blockmachines:431 gregtech TRUE gregapi_post 6 135 166 2
121 gt.recipe.fluidextractor GregTech gregtech:gt.blockmachines:511 gregtech TRUE gregapi_post 6 135 166 2
122 gt.recipe.fluidheater GregTech gregtech:gt.blockmachines:621 gregtech TRUE gregapi_post 6 135 166 2
123 gt.recipe.fluidnaquadahreactor GregTech gregtech:gt.blockmachines:1192 gregtech TRUE gregapi_post 6 135 166 2
124 gt.recipe.fluidsolidifier GregTech gregtech:gt.blockmachines:521 gregtech TRUE gregapi_post 6 135 166 2
125 gt.recipe.fusionreactor GregTech gregtech:gt.blockmachines:1193 gregtech TRUE gregapi_post 6 135 166 2
126 gt.recipe.gasturbinefuel GregTech gregtech:gt.blockmachines:1115 gregtech TRUE gregapi_post 6 135 166 2
127 gt.recipe.hammer GregTech gregtech:gt.blockmachines:611 gregtech TRUE gregapi_post 6 135 166 2
128 gt.recipe.hugenaquadahreactor GregTech gregtech:gt.blockmachines:1188 gregtech TRUE gregapi_post 6 135 166 2
129 gt.recipe.implosioncompressor GregTech gregtech:gt.blockmachines:12734 gregtech TRUE gregapi_post 6 135 166 2
130 gt.recipe.largeboilerfakefuels GregTech gregtech:gt.blockmachines:1020 gregtech TRUE gregapi_post 6 135 166 2
131 gt.recipe.largechemicalreactor GregTech gregtech:gt.blockmachines:1169 gregtech TRUE gregapi_post 6 135 166 2
132 gt.recipe.largenaquadahreactor GregTech gregtech:gt.blockmachines:1191 gregtech TRUE gregapi_post 6 135 166 2
133 gt.recipe.laserengraver GregTech gregtech:gt.blockmachines:591 gregtech TRUE gregapi_post 6 135 166 2
134 gt.recipe.lathe GregTech gregtech:gt.blockmachines:291 gregtech TRUE gregapi_post 6 135 166 2
135 gt.recipe.macerator GregTech gregtech:gt.blockmachines:301 gregtech TRUE gregapi_post 6 135 166 2
136 gt.recipe.magicfuels GregTech gregtech:gt.blockmachines:1123 gregtech TRUE gregapi_post 6 135 166 2
137 gt.recipe.massfab GregTech gregtech:gt.blockmachines:461 gregtech TRUE gregapi_post 6 135 166 2
138 gt.recipe.metalbender GregTech gregtech:gt.blockmachines:221 gregtech TRUE gregapi_post 6 135 166 2
139 gt.recipe.microwave GregTech gregtech:gt.blockmachines:311 gregtech TRUE gregapi_post 6 135 166 2
140 gt.recipe.mixer GregTech gregtech:gt.blockmachines:581 gregtech TRUE gregapi_post 6 135 166 2
141 gt.recipe.orewasher GregTech gregtech:gt.blockmachines:391 gregtech TRUE gregapi_post 6 135 166 2
142 gt.recipe.packager GregTech gregtech:gt.blockmachines:401 gregtech TRUE gregapi_post 6 135 166 2
143 gt.recipe.plasmaarcfurnace GregTech gregtech:gt.blockmachines:661 gregtech TRUE gregapi_post 6 135 166 2
144 gt.recipe.plasmageneratorfuels GregTech gregtech:gt.blockmachines:1196 gregtech TRUE gregapi_post 6 135 166 2
145 gt.recipe.polarizer GregTech gregtech:gt.blockmachines:551 gregtech TRUE gregapi_post 6 135 166 2
146 gt.recipe.press GregTech gregtech:gt.blockmachines:601 gregtech TRUE gregapi_post 6 135 166 2
147 gt.recipe.primitiveblastfurnace GregTech gregtech:gt.blockmachines:140 gregtech TRUE gregapi_post 6 135 166 2
148 gt.recipe.printer GregTech gregtech:gt.blockmachines:321 gregtech TRUE gregapi_post 6 135 166 2
149 gt.recipe.pyro GregTech gregtech:gt.blockmachines:1159 gregtech TRUE gregapi_post 6 135 166 2
150 gt.recipe.replicator GregTech gregtech:gt.blockmachines:481 gregtech TRUE gregapi_post 6 135 166 2
151 gt.recipe.rockbreaker GregTech gregtech:gt.blockmachines:441 gregtech TRUE gregapi_post 6 135 166 2
152 gt.recipe.scanner GregTech gregtech:gt.blockmachines:341 gregtech TRUE gregapi_post 6 135 166 2
153 gt.recipe.semifluidboilerfuels GregTech gregtech:gt.blockmachines:1020 gregtech TRUE gregapi_post 6 135 166 2
154 gt.recipe.sifter GregTech gregtech:gt.blockmachines:641 gregtech TRUE gregapi_post 6 135 166 2
155 gt.recipe.slicer GregTech gregtech:gt.blockmachines:631 gregtech TRUE gregapi_post 6 135 166 2
156 gt.recipe.smallnaquadahreactor GregTech gregtech:gt.blockmachines:1190 gregtech TRUE gregapi_post 6 135 166 2
157 gt.recipe.thermalcentrifuge GregTech gregtech:gt.blockmachines:381 gregtech TRUE gregapi_post 6 135 166 2
158 gt.recipe.thermalgeneratorfuel GregTech IC2:blockGenerator:1 gregtech TRUE gregapi_post 6 135 166 2
159 gt.recipe.unpackager GregTech gregtech:gt.blockmachines:411 gregtech TRUE gregapi_post 6 135 166 2
160 gt.recipe.uuamplifier GregTech gregtech:gt.blockmachines:471 gregtech TRUE gregapi_post 6 135 166 2
161 gt.recipe.vacuumfreezer GregTech gregtech:gt.blockmachines:1002 gregtech TRUE gregapi_post 6 135 166 2
162 gt.recipe.wiremill GregTech gregtech:gt.blockmachines:351 gregtech TRUE gregapi_post 6 135 166 2
163 ic.recipe.recycler GregTech gregtech:gt.blockmachines:331 gregtech TRUE gregapi_post 6 135 166 2
164 pers.gwyog.gtneioreplugin.plugin.gregtech5.PluginGT5SmallOreStat GregTech gregtech:gt.blockores:85 gregtech TRUE 145 2
165 pers.gwyog.gtneioreplugin.plugin.gregtech5.PluginGT5VeinStat GregTech gregtech:gt.blockores:386 gregtech TRUE 135 2
166 ic2.neiIntegration.core.recipehandler.AdvRecipeHandler IndustrialCraft 2 IC2:blockreactorvessel IC2 TRUE 65 5
167 ic2.neiIntegration.core.recipehandler.AdvShapelessRecipeHandler IndustrialCraft 2 IC2:blockreactorvessel IC2 TRUE 65 5
168 ic2.neiIntegration.core.recipehandler.BlastFurnaceRecipeHandler IndustrialCraft 2 IC2:blockMachine3:1 IC2 TRUE 65 5
169 ic2.neiIntegration.core.recipehandler.BlockCutterRecipeHandler IndustrialCraft 2 IC2:blockMachine3:2 IC2 TRUE 65 5
170 ic2.neiIntegration.core.recipehandler.CentrifugeRecipeHandler IndustrialCraft 2 IC2:blockMachine2:3 IC2 TRUE 65 5
171 ic2.neiIntegration.core.recipehandler.CompressorRecipeHandler IndustrialCraft 2 IC2:blockMachine:5 IC2 TRUE 65 5
172 ic2.neiIntegration.core.recipehandler.ExtractorRecipeHandler IndustrialCraft 2 IC2:blockMachine:4 IC2 TRUE 65 5
173 ic2.neiIntegration.core.recipehandler.FluidCannerRecipeHandler IndustrialCraft 2 IC2:blockMachine:6 IC2 TRUE 65 5
174 ic2.neiIntegration.core.recipehandler.LatheRecipeHandler IndustrialCraft 2 IC2:blockMachine3:8 IC2 TRUE 65 5
175 ic2.neiIntegration.core.recipehandler.MaceratorRecipeHandler IndustrialCraft 2 IC2:blockMachine:3 IC2 TRUE 65 5
176 ic2.neiIntegration.core.recipehandler.MetalFormerRecipeHandlerCutting IndustrialCraft 2 IC2:blockMachine2:4 IC2 TRUE 55 6
177 ic2.neiIntegration.core.recipehandler.MetalFormerRecipeHandlerExtruding IndustrialCraft 2 IC2:blockMachine2:4 IC2 TRUE 55 6
178 ic2.neiIntegration.core.recipehandler.MetalFormerRecipeHandlerRolling IndustrialCraft 2 IC2:blockMachine2:4 IC2 TRUE 55 6
179 ic2.neiIntegration.core.recipehandler.OreWashingRecipeHandler IndustrialCraft 2 IC2:blockMachine2:5 IC2 TRUE
180 ic2.neiIntegration.core.recipehandler.ScrapboxRecipeHandler IndustrialCraft 2 IC2:itemScrapbox IC2 TRUE 50 6
181 ic2.neiIntegration.core.recipehandler.SolidCannerRecipeHandler IndustrialCraft 2 IC2:blockMachine2:9 IC2 TRUE
182 speiger.src.crops.prediction.NEIPlugin IC2CropsNEI IC2:blockCrop Ic2Nei TRUE 135 2 Not actual recipes, just info
183 tonius.neiintegration.mods.mcforge.RecipeHandlerFluidRegistry Minecraft minecraft:water minecraft FALSE
184 tonius.neiintegration.mods.mcforge.RecipeHandlerOreDictionary Minecraft minecraft:iron_ore minecraft FALSE
185 gt.recipe.alloyblastsmelter GT++ gregtech:gt.blockmachines:810 miscutils TRUE 6 135 166 2 ABS
186 gt.recipe.rocketenginefuel GT++ gregtech:gt.blockmachines:793 miscutils TRUE 6 135 166 2 Basic (EV) rocket fuel gen
187 gt.recipe.cyclotron GT++ gregtech:gt.blockmachines:828 miscutils TRUE 6 135 166 2 Cyclotron
188 gt.recipe.chemicaldehydrator GT++ gregtech:gt.blockmachines:911 miscutils TRUE 6 135 166 2 Dehydrator
189 gt.recipe.slowfusionreactor GT++ gregtech:gt.blockmachines:31015 miscutils TRUE 6 135 166 2 gt.blockmachines.gtplusplus.fusion.single
190 gt.recipe.RTGgenerators GT++ gregtech:gt.blockmachines:869 miscutils TRUE 6 135 166 2 GT++ version of the RTG
191 gt.recipe.cokeoven GT++ gregtech:gt.blockmachines:791 miscutils TRUE 6 135 166 2 ICO
192 gt.recipe.semifluidgeneratorfuels GT++ gregtech:gt.blockmachines:837 miscutils TRUE 6 135 166 2 Semifluid gen
193 gt.recipe.fishpond GT++ gregtech:gt.blockmachines:829 miscutils TRUE 6 135 166 2 Zhuhai
194 gt.recipe.advanced.mixer GT++ gregtech:gt.blockmachines:811 miscutils TRUE 6 135 166 2
195 gt.recipe.cryogenicfreezer GT++ gregtech:gt.blockmachines:910 miscutils TRUE 6 135 166 2
196 gt.recipe.fissionfuel GT++ gregtech:gt.blockmachines:835 miscutils TRUE 6 135 166 2
197 gt.recipe.geothermalfuel GT++ gregtech:gt.blockmachines:830 miscutils TRUE 6 135 166 2
198 gt.recipe.lftr GT++ gregtech:gt.blockmachines:751 miscutils TRUE 6 135 166 2
199 gt.recipe.lftr.2 GT++ gregtech:gt.blockmachines:751 miscutils TRUE 6 135 166 2
200 gt.recipe.matterfab2 GT++ gregtech:gt.blockmachines:799 miscutils TRUE 6 135 166 2
201 gt.recipe.multicentrifuge GT++ gregtech:gt.blockmachines:790 miscutils TRUE 6 135 166 2
202 gt.recipe.multielectro GT++ gregtech:gt.blockmachines:796 miscutils TRUE 6 135 166 2
203 gt.recipe.simplewasher GT++ gregtech:gt.blockmachines:767 miscutils TRUE 6 135 166 2
204 gt.recipe.vacfurnace GT++ gregtech:gt.blockmachines:995 miscutils TRUE 6 135 166 2
205 gtPlusPlus.nei.DecayableRecipeHandler GT++ miscutils:dustRadium226 miscutils TRUE 75 4
206 gtPlusPlus.nei.GT_NEI_FlotationCell GT++ gregtech:gt.blockmachines:31028 miscutils TRUE 120 2
207 gtPlusPlus.nei.GT_NEI_FluidReactor GT++ gregtech:gt.blockmachines:998 miscutils TRUE 120 2
208 gtPlusPlus.nei.GT_NEI_MillingMachine GT++ gregtech:gt.blockmachines:31027 miscutils TRUE 120 2
209 li.cil.oc.integration.nei.CallbackDocHandler OpenComputers OpenComputers:item:98 OpenComputers TRUE 120 2
210 li.cil.oc.integration.nei.ManualUsageHandler OpenComputers OpenComputers:item:98 OpenComputers TRUE 120 2
211 tonius.neiintegration.mods.harvestcraft.RecipeHandlerApiary Pam's Harvestcraft harvestcraft:apiary harvestcraft TRUE 70 5 There's only 1 though
212 tonius.neiintegration.mods.harvestcraft.RecipeHandlerChurn Pam's Harvestcraft harvestcraft:churn harvestcraft TRUE 65 5 Same as above
213 tonius.neiintegration.mods.harvestcraft.RecipeHandlerOven Pam's Harvestcraft harvestcraft:oven harvestcraft TRUE 65 5
214 tonius.neiintegration.mods.harvestcraft.RecipeHandlerPresser Pam's Harvestcraft harvestcraft:presser harvestcraft TRUE 65 5
215 tonius.neiintegration.mods.harvestcraft.RecipeHandlerQuern Pam's Harvestcraft harvestcraft:quern harvestcraft TRUE 65 5
216 gcewing.projectblue.nei.NEIRecipeHandler ProjectBlue ProjectBlue:sprayCan ProjectBlue TRUE 65 5
217 mrtjp.projectred.core.libmc.recipe.PRShapedRecipeHandler ProjectRed ProjRed|Transmission:projectred.transmission.wire:7 ProjRed|Transmission TRUE
218 mrtjp.projectred.core.libmc.recipe.PRShapelessRecipeHandler ProjectRed ProjRed|Transmission:projectred.transmission.wire:7 ProjRed|Transmission TRUE
219 tonius.neiintegration.mods.railcraft.RecipeHandlerBlastFurnace Railcraft Railcraft:machine.alpha:12 Railcraft TRUE
220 tonius.neiintegration.mods.railcraft.RecipeHandlerCokeOven Railcraft Railcraft:machine.alpha:7 Railcraft TRUE 65 5
221 tonius.neiintegration.mods.railcraft.RecipeHandlerRockCrusher Railcraft Railcraft:machine.alpha:15 Railcraft TRUE
222 tonius.neiintegration.mods.railcraft.RecipeHandlerRollingMachineShaped Railcraft Railcraft:machine.alpha:8 Railcraft TRUE 65 5
223 tonius.neiintegration.mods.railcraft.RecipeHandlerRollingMachineShapeless Railcraft Railcraft:machine.alpha:8 Railcraft TRUE
224 lumien.randomthings.Handler.ModCompability.NEI.ImbuingStationRecipeHandler RandomThings RandomThings:imbuingStation RandomThings TRUE 120 2
225 com.github.technus.tectech.nei.TT_NEI_ResearchHandler TecTech gregtech:gt.blockmachines:15331 tectech TRUE 6 140 2
226 com.github.technus.tectech.nei.TT_NEI_ScannerHandler TecTech tectech:item.em.definitionScanStorage tectech TRUE
227 com.djgiannuzz.thaumcraftneiplugin.nei.recipehandler.ArcaneShapedRecipeHandler Thaumcraft Thaumcraft:blockTable:15 Thaumcraft TRUE 140 2
228 com.djgiannuzz.thaumcraftneiplugin.nei.recipehandler.ArcaneShapelessRecipeHandler Thaumcraft Thaumcraft:blockTable:15 Thaumcraft TRUE 140 2
229 com.djgiannuzz.thaumcraftneiplugin.nei.recipehandler.CrucibleRecipeHandler Thaumcraft Thaumcraft:blockMetalDevice Thaumcraft TRUE 140 2 Using R on an item you get from the crucible basically never works
230 com.djgiannuzz.thaumcraftneiplugin.nei.recipehandler.InfusionRecipeHandler Thaumcraft Thaumcraft:blockStoneDevice:2 Thaumcraft TRUE 140 2
231 ru.timeconqueror.tcneiadditions.nei.arcaneworkbench.ArcaneCraftingShapedHandler Thaumcraft Thaumcraft:blockTable:15 Thaumcraft TRUE 140 2
232 ru.timeconqueror.tcneiadditions.nei.AspectCombinationHandler Thaumcraft Thaumcraft:ItemResearchNotes Thaumcraft TRUE 130 2 In sets of 5. Each one is ~30 height
233 ru.timeconqueror.tcneiadditions.nei.AspectFromItemStackHandler Thaumcraft Thaumcraft:ItemResearchNotes Thaumcraft TRUE 140 2
234 tconstruct.plugins.nei.RecipeHandlerAlloying Tinker's Construct TConstruct:Smeltery TConstruct TRUE 65 5
235 tconstruct.plugins.nei.RecipeHandlerCastingBasin Tinker's Construct TConstruct:SearedBlock:2 TConstruct TRUE 65 5
236 tconstruct.plugins.nei.RecipeHandlerCastingTable Tinker's Construct TConstruct:SearedBlock TConstruct TRUE 65 5
237 tconstruct.plugins.nei.RecipeHandlerDryingRack Tinker's Construct TConstruct:Armor.DryingRack TConstruct TRUE 55 5
238 tconstruct.plugins.nei.RecipeHandlerMelting Tinker's Construct TConstruct:LavaTank:2 TConstruct TRUE 65 5
239 tconstruct.plugins.nei.RecipeHandlerToolMaterials Tinker's Construct TConstruct:ToolStationBlock TConstruct TRUE 110 3 Longer if more modifiers, I went through the whole list
240 net.p455w0rd.wirelesscraftingterminal.integration.modules.NEIHelpers.NEIAEShapedRecipeHandler Wireless Crafting Terminal ae2wct:wirelessCraftingTerminal ae2wct TRUE
241 alkalus.main.nei.NEI_Handler_Cauldron Witchery witchery:cauldron WitcheryExtras TRUE 65 5
242 alkalus.main.nei.NEI_Handler_Distillery Witchery witchery:distilleryidle WitcheryExtras TRUE 140 2
243 alkalus.main.nei.NEI_Handler_Kettle Witchery witchery:kettle WitcheryExtras TRUE 65 5
244 alkalus.main.nei.NEI_Handler_Oven Witchery witchery:witchesovenidle WitcheryExtras TRUE Not working at all now
245 alkalus.main.nei.NEI_Handler_SpinningWheel Witchery witchery:spinningwheel WitcheryExtras TRUE 65 5
246 com.emoniph.witchery.integration.NEICauldronRecipeHandler Witchery witchery:cauldron witchery TRUE 65 5 Replaced by WE presumably
247 com.emoniph.witchery.integration.NEIDistilleryRecipeHandler Witchery witchery:distilleryidle witchery TRUE 140 2 Replaced by WE presumably
248 com.emoniph.witchery.integration.NEIKettleRecipeHandler Witchery witchery:kettle witchery TRUE 65 5 Replaced by WE presumably
249 com.emoniph.witchery.integration.NEISpinningWheelRecipeHandler Witchery witchery:spinningwheel witchery TRUE Replaced by WE presumably
250 com.emoniph.witchery.integration.NEIWitchesOvenRecipeHandler Witchery witchery:witchesovenidle witchery TRUE 65 5 Replaced by WE presumably
251 witchinggadgets.client.nei.NEIInfernalBlastfurnaceHandler WitchingGadgets WitchingGadgets:WG_StoneDevice:2 WitchingGadgets TRUE 65 5
252 witchinggadgets.client.nei.NEISpinningWheelHandler WitchingGadgets WitchingGadgets:WG_WoodenDevice WitchingGadgets TRUE 110 3
253 gt.recipe.anvil GregTech 6 gregtech:gt.multitileentity:32031 gregapi_post TRUE 15 145 166 2
254 gt.recipe.anvil.bend.big GregTech 6 gregtech:gt.multitileentity:32031 gregapi_post TRUE 15 145 166 2
255 gt.recipe.anvil.bend.small GregTech 6 gregtech:gt.multitileentity:32031 gregapi_post TRUE 15 145 166 2
256 gt.recipe.aquaticfarm GregTech 6 gregtech:gt.multitileentity:17131 gregapi_post TRUE 15 145 166 2
257 gt.recipe.assembler GregTech 6 gregtech:gt.multitileentity:20621 gregapi_post TRUE 15 145 166 2
258 gt.recipe.autoclave GregTech 6 gregtech:gt.multitileentity:22004 gregapi_post TRUE 15 145 166 2
259 gt.recipe.bath GregTech 6 gregtech:gt.multitileentity:22002 gregapi_post TRUE 15 145 166 2
260 gt.recipe.bedrockorelist GregTech 6 gregtech:gt.multitileentity:17999 gregapi_post TRUE 15 145 166 2
261 gt.recipe.biolab GregTech 6 gregtech:gt.multitileentity:17127 gregapi_post TRUE 15 145 166 2
262 gt.recipe.boxinator GregTech 6 gregtech:gt.multitileentity:20581 gregapi_post TRUE 15 145 166 2
263 gt.recipe.bumblelyzer GregTech 6 gregtech:gt.multitileentity:20541 gregapi_post TRUE 15 145 166 2
264 gt.recipe.bumblequeen GregTech 6 gregtech:gt.multiitem.bumblebee:1 {"gt.bumble": {}} gregapi_post TRUE 15 145 166 2
265 gt.recipe.burnmixer GregTech 6 gregtech:gt.multitileentity:20521 gregapi_post TRUE 15 145 166 2
266 gt.recipe.byproductlist GregTech 6 minecraft:diamond_ore gregapi_post TRUE 15 145 166 2
267 gt.recipe.canner GregTech 6 gregtech:gt.multitileentity:20161 gregapi_post TRUE 15 145 166 2
268 gt.recipe.catalyticcracking GregTech 6 gregtech:gt.multitileentity:20481 gregapi_post TRUE 15 145 166 2
269 gt.recipe.centrifuge GregTech 6 gregtech:gt.multitileentity:20081 gregapi_post TRUE 15 145 166 2
270 gt.recipe.clustermill GregTech 6 gregtech:gt.multitileentity:20141 gregapi_post TRUE 15 145 166 2
271 gt.recipe.coagulator GregTech 6 gregtech:gt.multitileentity:22000 gregapi_post TRUE 15 145 166 2
272 gt.recipe.cokeoven GregTech 6 gregtech:gt.multitileentity:17000 gregapi_post TRUE 15 145 166 2
273 gt.recipe.compressor GregTech 6 gregtech:gt.multitileentity:20101 gregapi_post TRUE 15 145 166 2
274 gt.recipe.crackingtower GregTech 6 gregtech:gt.multitileentity:17115 gregapi_post TRUE 15 145 166 2
275 gt.recipe.cruciblealloying GregTech 6 gregtech:gt.multitileentity:1005 gregapi_post TRUE 15 145 166 2
276 gt.recipe.cruciblesmelting GregTech 6 gregtech:gt.multitileentity:1005 gregapi_post TRUE 15 145 166 2
277 gt.recipe.crusher GregTech 6 gregtech:gt.multitileentity:20021 gregapi_post TRUE 15 145 166 2
278 gt.recipe.cryodistillationtower GregTech 6 gregtech:gt.multitileentity:17111 gregapi_post TRUE 15 145 166 2
279 gt.recipe.cryomixer GregTech 6 gregtech:gt.multitileentity:20571 gregapi_post TRUE 15 145 166 2
280 gt.recipe.crystallisationcrucible GregTech 6 gregtech:gt.multitileentity:20251 gregapi_post TRUE 15 145 166 2
281 gt.recipe.cutter GregTech 6 gregtech:gt.multitileentity:20061 gregapi_post TRUE 15 145 166 2
282 gt.recipe.debarker GregTech 6 gregtech:gt.multitileentity:20551 gregapi_post TRUE 15 145 166 2
283 gt.recipe.distillationtower GregTech 6 gregtech:gt.multitileentity:20191 gregapi_post TRUE 15 145 166 2
284 gt.recipe.distillery GregTech 6 gregtech:gt.multitileentity:20191 gregapi_post TRUE 15 145 166 2
285 gt.recipe.drying GregTech 6 gregtech:gt.multitileentity:20311 gregapi_post TRUE 15 145 166 2
286 gt.recipe.electrolyzer GregTech 6 gregtech:gt.multitileentity:20091 gregapi_post TRUE 15 145 166 2
287 gt.recipe.extruder GregTech 6 gregtech:gt.multitileentity:20202 gregapi_post TRUE 15 145 166 2
288 gt.recipe.fermenter GregTech 6 gregtech:gt.multitileentity:22003 gregapi_post TRUE 15 145 166 2
289 gt.recipe.fluidsolidifier GregTech 6 gregtech:gt.multitileentity:20611 gregapi_post TRUE 15 145 166 2
290 gt.recipe.freezer GregTech 6 gregtech:gt.multitileentity:20561 gregapi_post TRUE 15 145 166 2
291 gt.recipe.fuels.burn GregTech 6 gregtech:gt.multitileentity:1109 gregapi_post TRUE 15 145 166 2
292 gt.recipe.fuels.engine GregTech 6 gregtech:gt.multitileentity:9147 gregapi_post TRUE 15 145 166 2
293 gt.recipe.fuels.fluidbed GregTech 6 gregtech:gt.multitileentity:9009 gregapi_post TRUE 15 145 166 2
294 gt.recipe.fuels.gas GregTech 6 gregtech:gt.multitileentity:1609 gregapi_post TRUE 15 145 166 2
295 gt.recipe.fuels.plasma GregTech 6 gregtech:gt.multitileentity:17251 gregapi_post TRUE 15 145 166 2
296 gt.recipe.fuels.turbine GregTech 6 gregtech:gt.multitileentity:17231 gregapi_post TRUE 15 145 166 2
297 gt.recipe.fusionreactor GregTech 6 gregtech:gt.multitileentity:17198 gregapi_post TRUE 15 145 166 2
298 gt.recipe.generifier GregTech 6 gregtech:gt.multitileentity:22001 gregapi_post TRUE 15 145 166 2
299 gt.recipe.heatmixer GregTech 6 gregtech:gt.multitileentity:20506 gregapi_post TRUE 15 145 166 2
300 gt.recipe.implosioncompressor GregTech 6 gregtech:gt.multitileentity:17110 gregapi_post TRUE 15 145 166 2
301 gt.recipe.incubator GregTech 6 gregtech:gt.multitileentity:22005 gregapi_post TRUE 15 145 166 2
302 gt.recipe.injector GregTech 6 gregtech:gt.multitileentity:20261 gregapi_post TRUE 15 145 166 2
303 gt.recipe.ionizer GregTech 6 gregtech:gt.multitileentity:17315 gregapi_post TRUE 15 145 166 2
304 gt.recipe.juicer GregTech 6 gregtech:gt.multitileentity:32722 gregapi_post TRUE 15 145 166 2
305 gt.recipe.laminator GregTech 6 gregtech:gt.multitileentity:20391 gregapi_post TRUE 15 145 166 2
306 gt.recipe.lasercutter GregTech 6 gregtech:gt.multitileentity:20631 gregapi_post TRUE 15 145 166 2
307 gt.recipe.laserengraver GregTech 6 gregtech:gt.multitileentity:20321 gregapi_post TRUE 15 145 166 2
308 gt.recipe.lathe GregTech 6 gregtech:gt.multitileentity:20041 gregapi_post TRUE 15 145 166 2
309 gt.recipe.lightning GregTech 6 gregtech:gt.multitileentity:20501 gregapi_post TRUE 15 145 166 2
310 gt.recipe.loom GregTech 6 gregtech:gt.multitileentity:20211 gregapi_post TRUE 15 145 166 2
311 gt.recipe.magneticseparator GregTech 6 gregtech:gt.multitileentity:20301 gregapi_post TRUE 15 145 166 2
312 gt.recipe.maskaligner GregTech 6 gregtech:gt.multitileentity:17122 gregapi_post TRUE 15 145 166 2
313 gt.recipe.massfab GregTech 6 gregtech:gt.multitileentity:20411 gregapi_post TRUE 15 145 166 2
314 gt.recipe.mixer GregTech 6 gregtech:gt.multitileentity:20181 gregapi_post TRUE 15 145 166 2
315 gt.recipe.mortar GregTech 6 gregtech:gt.multitileentity:32735 gregapi_post TRUE 15 145 166 2
316 gt.recipe.nanofab GregTech 6 gregtech:gt.multitileentity:20441 gregapi_post TRUE 15 145 166 2
317 gt.recipe.oilcleaner GregTech 6 gregtech:gt.multitileentity:17116 gregapi_post TRUE 15 145 166 2
318 gt.recipe.particlecollider GregTech 6 gregtech:gt.multitileentity:17200 gregapi_post TRUE 15 145 166 2
319 gt.recipe.plantalyzer GregTech 6 gregtech:gt.multitileentity:20531 gregapi_post TRUE 15 145 166 2
320 gt.recipe.polarizer GregTech 6 gregtech:gt.multitileentity:20221 gregapi_post TRUE 15 145 166 2
321 gt.recipe.press GregTech 6 gregtech:gt.multitileentity:20231 gregapi_post TRUE 15 145 166 2
322 gt.recipe.printer GregTech 6 gregtech:gt.multitileentity:20271 gregapi_post TRUE 15 145 166 2
323 gt.recipe.replicator GregTech 6 gregtech:gt.multitileentity:20431 gregapi_post TRUE 15 145 166 2
324 gt.recipe.roaster GregTech 6 gregtech:gt.multitileentity:20171 gregapi_post TRUE 15 145 166 2
325 gt.recipe.rollbender GregTech 6 gregtech:gt.multitileentity:20121 gregapi_post TRUE 15 145 166 2
326 gt.recipe.rollformer GregTech 6 gregtech:gt.multitileentity:20131 gregapi_post TRUE 15 145 166 2
327 gt.recipe.rollingmill GregTech 6 gregtech:gt.multitileentity:20111 gregapi_post TRUE 15 145 166 2
328 gt.recipe.scannermolecular GregTech 6 gregtech:gt.multitileentity:20423 gregapi_post TRUE 15 145 166 2
329 gt.recipe.scannervisuals GregTech 6 gregtech:gt.multitileentity:20281 gregapi_post TRUE 15 145 166 2
330 gt.recipe.sharpener GregTech 6 gregtech:gt.multitileentity:20511 gregapi_post TRUE 15 145 166 2
331 gt.recipe.shredder GregTech 6 gregtech:gt.multitileentity:20011 gregapi_post TRUE 15 145 166 2
332 gt.recipe.sifter GregTech 6 gregtech:gt.multitileentity:20051 gregapi_post TRUE 15 145 166 2
333 gt.recipe.slicer GregTech 6 gregtech:gt.multitileentity:20381 gregapi_post TRUE 15 145 166 2
334 gt.recipe.sluice GregTech 6 gregtech:gt.multitileentity:20291 gregapi_post TRUE 15 145 166 2
335 gt.recipe.smelter GregTech 6 gregtech:gt.multitileentity:20241 gregapi_post TRUE 15 145 166 2
336 gt.recipe.squeezer GregTech 6 gregtech:gt.multitileentity:20071 gregapi_post TRUE 15 145 166 2
337 gt.recipe.steamcracking GregTech 6 gregtech:gt.multitileentity:20491 gregapi_post TRUE 15 145 166 2
338 gt.recipe.toolhead GregTech 6 gregtech:gt.meta.toolHeadPickaxe:260 gregapi_post TRUE 15 145 166 2
339 gt.recipe.unboxinator GregTech 6 gregtech:gt.multitileentity:20591 gregapi_post TRUE 15 145 166 2
340 gt.recipe.welder GregTech 6 gregtech:gt.multitileentity:20331 gregapi_post TRUE 15 145 166 2
341 gt.recipe.well GregTech 6 gregtech:gt.multitileentity:17124 gregapi_post TRUE 15 145 166 2
342 gt.recipe.wiremill GregTech 6 gregtech:gt.multitileentity:20151 gregapi_post TRUE 15 145 166 2
343 smelting GregTech 6 gregtech:gt.multitileentity:20001 gregapi_post TRUE 15 145 166 2 This uses the same recipe map as the MC furnace
344 gt.recipe.trees GregTech 6 minecraft:sapling gregapi_post TRUE 15 145 166 2
345 moze_intel.projecte.integration.NEI.NEIWorldTransmuteHandler ProjectE ProjectE:item.pe_philosophers_stone ProjectE TRUE 45 10
346 moze_intel.projecte.integration.NEI.NEIPhiloSmeltingHandler ProjectE ProjectE:item.pe_philosophers_stone ProjectE TRUE 5
347 moze_intel.projecte.integration.NEI.NEIKleinStarHandler ProjectE ProjectE:item.pe_klein_star ProjectE TRUE 5
348 moze_intel.projecte.integration.NEI.NEIAlchBagHandler ProjectE ProjectE:item.pe_alchemical_bag ProjectE TRUE 5
349 de.katzenpapst.amunra.nei.recipehandler.ARCircuitFab Pra's Galacticraft Mod GalacticraftCore:tile.machine2:4 GalacticraftAmunRa TRUE
350 de.katzenpapst.amunra.nei.recipehandler.ARNasaWorkbenchShuttle Pra's Galacticraft Mod GalacticraftAmunRa:item.itemShuttle GalacticraftAmunRa TRUE 130 168 16
351 vazkii.botania.client.integration.nei.recipe.RecipeHandlerFloatingFlowers Botania Botania:miniIsland Botania TRUE 5
352 vazkii.botania.client.integration.nei.recipe.RecipeHandlerPetalApothecary Botania Botania:altar Botania TRUE 102 137 4
353 vazkii.botania.client.integration.nei.recipe.RecipeHandlerRunicAltar Botania Botania:runeAltar Botania TRUE 122 137 4
354 vazkii.botania.client.integration.nei.recipe.RecipeHandlerManaPool Botania Botania:pool Botania TRUE 90 137 4
355 vazkii.botania.client.integration.nei.recipe.RecipeHandlerElvenTrade Botania Botania:alfheimPortal Botania TRUE 90 130 4
356 vazkii.botania.client.integration.nei.recipe.RecipeHandlerBrewery Botania Botania:brewery Botania TRUE 4
357 vazkii.botania.client.integration.nei.recipe.RecipeHandlerPureDaisy Botania Botania:specialFlower {"type": "puredaisy"} Botania TRUE 4
358 vazkii.botania.client.integration.nei.recipe.RecipeHandlerLexicaBotania Botania Botania:lexicon Botania TRUE
359 com.jaquadro.minecraft.storagedrawers.integration.notenoughitems.UpgradeItemRecipeHandler Storage Drawers minecraft:crafting_table StorageDrawers TRUE 65 166 5
360 ieArcFurnace Immersive Engineering ImmersiveEngineering:graphiteElectrode ImmersiveEngineering TRUE 65 166 5
361 NEIArcFurnaceHandlerAlloying Immersive Engineering terrafirmacraftplus:item.Bronze Ingot ImmersiveEngineering TRUE 65 166 5
362 NEIArcFurnaceHandlerOres Immersive Engineering minecraft:iron_ore ImmersiveEngineering TRUE 65 166 5
363 NEIArcFurnaceHandlerSmelting Immersive Engineering terrafirmacraftplus:item.Ore:100 ImmersiveEngineering TRUE 65 166 5
364 NEIArcFurnaceHandlerGlassworking Immersive Engineering minecraft:glass ImmersiveEngineering TRUE 65 166 5
365 NEIArcFurnaceHandlerDecarburization Immersive Engineering terrafirmacraftplus:item.Wrought Iron Ingot ImmersiveEngineering TRUE 65 166 5
366 NEIArcFurnaceHandlerCarburization Immersive Engineering terrafirmacraftplus:item.HC Steel Ingot ImmersiveEngineering TRUE 65 166 5
367 NEIArcFurnaceHandlerHeating Immersive Engineering ImmersiveEngineering TRUE 65 166 5 nei:textures/nei_tabbed_sprites.png 80 0 14 14
368 NEIArcFurnaceHandlerMelting Immersive Engineering terrafirmacraftplus:item.Molten Glass ImmersiveEngineering TRUE 65 166 5
369 NEIArcFurnaceHandlerWelding Immersive Engineering terrafirmacraftplus:item.Bismuth Double Ingot ImmersiveEngineering TRUE 65 166 5
370 NEIArcFurnaceHandlerElectrolysis Immersive Engineering teloaddon:Alumina ImmersiveEngineering TRUE 65 166 5
371 blusunrize.immersiveengineering.client.nei.NEIShaderBagHandler Immersive Engineering ImmersiveEngineering:shaderBag ImmersiveEngineering TRUE 65 166 5
372 blusunrize.immersiveengineering.client.nei.NEIBlueprintHandler Immersive Engineering ImmersiveEngineering:blueprint ImmersiveEngineering TRUE 65 166 5
373 blusunrize.immersiveengineering.client.nei.NEICokeOvenHandler Immersive Engineering ImmersiveEngineering:stoneDecoration:1 ImmersiveEngineering TRUE 71 166 5
374 blusunrize.immersiveengineering.client.nei.NEIBlastFurnaceHandler Immersive Engineering ImmersiveEngineering:stoneDecoration:2 ImmersiveEngineering TRUE 71 166 5
375 blusunrize.immersiveengineering.client.nei.NEISqueezerHandler Immersive Engineering ImmersiveEngineering:metalMultiblock:2 ImmersiveEngineering TRUE 71 166 5
376 blusunrize.immersiveengineering.client.nei.NEIFermenterHandler Immersive Engineering ImmersiveEngineering:metalMultiblock:3 ImmersiveEngineering TRUE 71 166 5
377 blusunrize.immersiveengineering.client.nei.NEIRefineryHandler Immersive Engineering ImmersiveEngineering:metalDevice2:5 ImmersiveEngineering TRUE 65 166 5
378 blusunrize.immersiveengineering.client.nei.NEIBottlingMachineHandler Immersive Engineering minecraft:glass_bottle ImmersiveEngineering TRUE 65 166 5
379 blusunrize.immersiveengineering.client.nei.NEIMetalPressHandler Immersive Engineering ImmersiveEngineering:mold ImmersiveEngineering TRUE 65 166 5
380 blusunrize.immersiveengineering.client.nei.NEICrusherHandler Immersive Engineering minecraft:hopper ImmersiveEngineering TRUE 71 166 5
381 net.dries007.tfcnei.recipeHandlers.AnvilRecipeHandler TerraFirmaCraft+ terrafirmacraftplus:Anvil terrafirmacraftplus TRUE 10 138 208 2
382 net.dries007.tfcnei.recipeHandlers.QuernRecipeHandler TerraFirmaCraft+ terrafirmacraftplus:item.Quern terrafirmacraftplus TRUE 65 166 5
383 net.dries007.tfcnei.recipeHandlers.KilnRecipeHandler TerraFirmaCraft+ terrafirmacraftplus TRUE 65 166 5 terrafirmacraftneiplugin:textures/gui/pitkiln.png 47 38 14 14
384 net.dries007.tfcnei.recipeHandlers.LoomRecipeHandler TerraFirmaCraft+ terrafirmacraftplus:Loom terrafirmacraftplus TRUE 65 166 5
385 net.dries007.tfcnei.recipeHandlers.KnappingRecipeHandler TerraFirmaCraft+ terrafirmacraftplus:item.LooseRock terrafirmacraftplus TRUE 96 166 3
386 net.dries007.tfcnei.recipeHandlers.ClothingRecipeHandler TerraFirmaCraft+ terrafirmacraftplus:item.Bone Needle Thread terrafirmacraftplus TRUE 65 166 5
387 net.dries007.tfcnei.recipeHandlers.BarrelRecipeHandler TerraFirmaCraft+ terrafirmacraftplus:Barrel terrafirmacraftplus TRUE 65 166 5
388 net.dries007.tfcnei.recipeHandlers.AlloyRecipeHandler TerraFirmaCraft+ terrafirmacraftplus:Crucible terrafirmacraftplus TRUE 65 166 5
389 net.dries007.tfcnei.recipeHandlers.HeatRecipeHandler TerraFirmaCraft+ terrafirmacraftplus:Firepit terrafirmacraftplus TRUE 65 166 5
390 minechem.nei.ChemicalBucketNEIRecipeHandler Minecraft minecraft:crafting_table minechem TRUE 65 166 5
391 minechem.nei.DecomposerNEIRecipeHandler Minechem minechem:tile.chemicalDecomposer minechem TRUE 131 166 2
392 minechem.nei.SynthesisNEIRecipeHandler Minechem minechem:tile.chemicalSynthesizer minechem TRUE 65 166 5
393 exter.fodc.nei.ODCRecipeHandler Ore Dictionary Converter fodc:oreConvTable fodc TRUE 4
394 cofh.thermalexpansion.plugins.nei.handlers.RecipeHandlerCharger Thermal Expansion ThermalExpansion:Machine:10 ThermalExpansion TRUE 65 166 5
395 cofh.thermalexpansion.plugins.nei.handlers.RecipeHandlerCraftingMachine Thermal Expansion ThermalExpansion:Frame ThermalExpansion TRUE 65 166 5
396 cofh.thermalexpansion.plugins.nei.handlers.RecipeHandlerCraftingSecure Thermal Expansion ThermalExpansion:material:16 ThermalExpansion TRUE 65 166 5
397 cofh.thermalexpansion.plugins.nei.handlers.RecipeHandlerCraftingUpgrade Thermal Expansion ThermalExpansion:Frame:3 ThermalExpansion TRUE 65 166 5
398 cofh.thermalexpansion.plugins.nei.handlers.RecipeHandlerCrucible Thermal Expansion ThermalExpansion:Machine:4 ThermalExpansion TRUE 65 166 5
399 cofh.thermalexpansion.plugins.nei.handlers.RecipeHandlerFurnace Thermal Expansion ThermalExpansion:Machine:0 ThermalExpansion TRUE 65 166 5
400 cofh.thermalexpansion.plugins.nei.handlers.RecipeHandlerInsolator Thermal Expansion ThermalExpansion:Machine:11 ThermalExpansion TRUE 65 166 5
401 cofh.thermalexpansion.plugins.nei.handlers.RecipeHandlerPulverizer Thermal Expansion ThermalExpansion:Machine:1 ThermalExpansion TRUE 65 166 5
402 cofh.thermalexpansion.plugins.nei.handlers.RecipeHandlerSawmill Thermal Expansion ThermalExpansion:Machine:2 ThermalExpansion TRUE 65 166 5
403 cofh.thermalexpansion.plugins.nei.handlers.RecipeHandlerSmelter Thermal Expansion ThermalExpansion:Machine:3 ThermalExpansion TRUE 65 166 5
404 cofh.thermalexpansion.plugins.nei.handlers.RecipeHandlerTransposer Thermal Expansion ThermalExpansion:Machine:5 ThermalExpansion TRUE 65 166 5
405 mekanism.client.nei.ChemicalCrystallizerRecipeHandler Mekanism Mekanism:MachineBlock2:8 Mekanism TRUE 79 4
406 mekanism.client.nei.ChemicalDissolutionChamberRecipeHandler Mekanism Mekanism:MachineBlock2:6 Mekanism TRUE 79 4
407 mekanism.client.nei.ChemicalInfuserRecipeHandler Mekanism Mekanism:MachineBlock2:2 Mekanism TRUE 80 4
408 mekanism.client.nei.ChemicalInjectionChamberRecipeHandler Mekanism Mekanism:MachineBlock2:3 Mekanism TRUE 68 5
409 mekanism.client.nei.ChemicalOxidizerRecipeHandler Mekanism Mekanism:MachineBlock2:1 Mekanism TRUE 62 5
410 mekanism.client.nei.ChemicalWasherRecipeHandler Mekanism Mekanism:MachineBlock2:7 Mekanism TRUE 70 5
411 mekanism.client.nei.CombinerRecipeHandler Mekanism Mekanism:MachineBlock:2 Mekanism TRUE 68 5
412 mekanism.client.nei.CrusherRecipeHandler Mekanism Mekanism:MachineBlock:3 Mekanism TRUE 68 5
413 mekanism.client.nei.MetallurgicInfuserRecipeHandler Mekanism Mekanism:MachineBlock:8 Mekanism TRUE 56 5
414 mekanism.client.nei.OsmiumCompressorRecipeHandler Mekanism Mekanism:MachineBlock:1 Mekanism TRUE 68 5
415 mekanism.client.nei.PRCRecipeHandler Mekanism Mekanism:MachineBlock2:10 Mekanism TRUE 68 5
416 mekanism.client.nei.PrecisionSawmillRecipeHandler Mekanism Mekanism:MachineBlock2:5 Mekanism TRUE 68 5
417 mekanism.client.nei.PurificationChamberRecipeHandler Mekanism Mekanism:MachineBlock:9 Mekanism TRUE 68 5
418 mekanism.client.nei.RotaryCondensentratorRecipeHandler Mekanism Mekanism:MachineBlock2:0 Mekanism TRUE 71 5
419 mekanism.client.nei.ShapedMekanismRecipeHandler Mekanism minecraft:crafting_table Mekanism TRUE 65 166 5
420 mekanism.client.nei.ShapelessMekanismRecipeHandler Mekanism minecraft:crafting_table Mekanism TRUE 65 166 5
421 mekanism.client.nei.SolarNeutronRecipeHandler Mekanism Mekanism:MachineBlock3:1 Mekanism TRUE 70 5
422 mekanism.client.nei.ThermalEvaporationRecipeHandler Mekanism Mekanism:BasicBlock:14 Mekanism TRUE 62 5
423 exnihilo.compatibility.nei.RecipeHandlerHammer Ex Nihilo exnihilo:hammer_iron exnihilo TRUE 58 5
424 exnihilo.compatibility.nei.RecipeHandlerSieve Ex Nihilo exnihilo:sifting_table exnihilo TRUE 130 2
425 gregtechmod.mistaqur.nei.handlers.AlloySmelterRecipeHandler GregTech-Addon gregtech_addon:machine:56 gregtech_addon TRUE 15 145 166 2
426 gregtechmod.mistaqur.nei.handlers.AssemblerRecipeHandler GregTech-Addon gregtech_addon:machine:60 gregtech_addon TRUE 15 145 166 2
427 gregtechmod.mistaqur.nei.handlers.BenderRecipeHandler GregTech-Addon gregtech_addon:machine:59 gregtech_addon TRUE 15 145 166 2
428 gregtechmod.mistaqur.nei.handlers.BlastRecipeHandler GregTech-Addon gregtech_addon:machine:29 gregtech_addon TRUE 15 145 166 2
429 gregtechmod.mistaqur.nei.handlers.BronzeBlastRecipeHandler GregTech-Addon gregtech_addon:machine:136 gregtech_addon TRUE 15 145 166 2
430 gregtechmod.mistaqur.nei.handlers.CannerRecipeHandler GregTech-Addon gregtech_addon:machine:57 gregtech_addon TRUE 15 145 166 2
431 gregtechmod.mistaqur.nei.handlers.CentrifugeRecipeHandler GregTech-Addon gregtech_addon:machine:62 gregtech_addon TRUE 15 145 166 2
432 gregtechmod.mistaqur.nei.handlers.ChemicalRecipeHandler GregTech-Addon gregtech_addon:machine:41 gregtech_addon TRUE 15 145 166 2
433 gregtechmod.mistaqur.nei.handlers.CutterRecipeHandler GregTech-Addon gregtech_addon:machine:113 gregtech_addon TRUE 15 145 166 2
434 gregtechmod.mistaqur.nei.handlers.DistillationRecipeHandler GregTech-Addon gregtech_addon:machine:44 gregtech_addon TRUE 15 145 166 2
435 gregtechmod.mistaqur.nei.handlers.ElectrolyzerRecipeHandler GregTech-Addon gregtech_addon:machine:25 gregtech_addon TRUE 15 145 166 2
436 gregtechmod.mistaqur.nei.handlers.ExtruderRecipeHandler GregTech-Addon gregtech_addon:machine:115 gregtech_addon TRUE 15 145 166 2
437 gregtechmod.mistaqur.nei.handlers.FusionRecipeHandler GregTech-Addon gregtech_addon:machine:80 gregtech_addon TRUE 15 145 166 2
438 gregtechmod.mistaqur.nei.handlers.GeneratorHandler GregTech-Addon gregtech_addon TRUE 15 145 166 2 nei:textures/nei_tabbed_sprites.png 80 0 14 14
439 gregtechmod.mistaqur.nei.handlers.GrinderRecipeHandler GregTech-Addon gregtech_addon:machine:28 gregtech_addon TRUE 15 145 166 2
440 gregtechmod.mistaqur.nei.handlers.ImplosionRecipeHandler GregTech-Addon gregtech_addon:machine:31 gregtech_addon TRUE 15 145 166 2
441 gregtechmod.mistaqur.nei.handlers.LatheRecipeHandler GregTech-Addon gregtech_addon:machine:111 gregtech_addon TRUE 15 145 166 2
442 gregtechmod.mistaqur.nei.handlers.SawmillRecipeHandler GregTech-Addon gregtech_addon:machine:32 gregtech_addon TRUE 15 145 166 2
443 gregtechmod.mistaqur.nei.handlers.VacuumFreezerRecipeHandler GregTech-Addon gregtech_addon:machine:38 gregtech_addon TRUE 15 145 166 2
444 gregtechmod.mistaqur.nei.handlers.WiremillRecipeHandler GregTech-Addon gregtech_addon:machine:55 gregtech_addon TRUE 15 145 166 2
445 cofh.thermaldynamics.plugins.nei.RecipeHandlerCover Thermal Dynamics ThermalDynamics:cover {Block:"minecraft:glass",Meta:0b} ThermalDynamics TRUE 65 166 5
446 neresources.nei.NEIAdvSeedHandler Not Enough Resources minecraft:wheat neresources TRUE 65 166 5
447 neresources.nei.NEIDungeonHandler Not Enough Resources minecraft:chest neresources TRUE 130 166 2
448 neresources.nei.NEIEnchantmentHandler Not Enough Resources minecraft:anvil neresources TRUE 130 166 2
449 neresources.nei.NEIMobHandler Not Enough Resources minecraft:skull:4 neresources TRUE 130 166 2
450 neresources.nei.NEIOreHandler Not Enough Resources minecraft:diamond_ore neresources TRUE 65 166 5
451 neresources.nei.NEIPlantHandler Not Enough Resources minecraft:wheat neresources TRUE 130 166 2
-265
View File
@@ -1,265 +0,0 @@
nei.load=Load
nei.save=Save
# PC/Linux Control Key
nei.key.ctrl=CTRL
# Mac Command Key
nei.key.ctrl.mac=CMD
nei.bookmark.toggle=Bookmarks
nei.bookmark.toggle.tip=Toggle visibility of the Bookmark Panel
nei.enchant=Enchant
nei.enchant.level=Level
nei.enchant.locked=Locked
nei.enchant.unlocked=Unlocked
nei.potion.favourite=Favourite Potions
nei.potion.duration=Duration
nei.potion.level=Level
nei.inventory.options=Options
nei.inventory.options.tip=NEI Config
nei.inventory.options.tip.cheatmode.0=Recipe Mode
nei.inventory.options.tip.cheatmode.1=Utility Mode
nei.inventory.options.tip.cheatmode.2=Cheat Mode
nei.inventory.options.tip.cheatmode.disable=%s-click here to cycle between Recipe, Utility, and Cheat Mode.
nei.inventory.prev=Prev
nei.inventory.next=Next
nei.inventory.item_subsets=Item Subsets
nei.inventory.delete.inv=DELETE ALL ITEMS from current inventory screen
nei.inventory.delete.one=Delete %s
nei.inventory.delete.all=Delete ALL %s
nei.inventory.delete.enable=Enable delete mode
nei.inventory.delete.1=Turn delete mode on
nei.inventory.delete.0=Turn delete mode off
nei.inventory.rain.enable=Enable rain
nei.inventory.rain.1=Turn rain on
nei.inventory.rain.0=Turn rain off
nei.inventory.magnet.enable=Enable magnet mode
nei.inventory.magnet.1=Turn magnet mode on
nei.inventory.magnet.0=Turn magnet mode off
nei.inventory.dawn.enable=Enable dawn-noon
nei.inventory.dawn.set=Set time to dawn
nei.inventory.noon.enable=Enable noon-dusk
nei.inventory.noon.set=Set time to noon
nei.inventory.dusk.enable=Enable dusk-midnight
nei.inventory.dusk.set=Set time to dusk
nei.inventory.midnight.enable=Enable midnight-dawn
nei.inventory.midnight.set=Set time to midnight
nei.inventory.heal=Heal the player
nei.inventory.current.gamemode.0=Current gamemode: survival
nei.inventory.current.gamemode.1=Current gamemode: creative
nei.inventory.current.gamemode.2=Current gamemode: creative+
nei.inventory.current.gamemode.3=Current gamemode: adventure
nei.inventory.gamemode.0=Click: Set gamemode to survival
nei.inventory.gamemode.1=Click: Set gamemode to creative
nei.inventory.gamemode.2=Click: Set gamemode to creative+
nei.inventory.gamemode.3=Click: Set gamemode to adventure
nei.chat.gamemode.0=You are now playing survival
nei.chat.gamemode.1=You are now playing creative
nei.chat.gamemode.2=You are now playing creative+
nei.chat.gamemode.3=You are now playing adventure
nei.chat.rain.on=Rain turned on
nei.chat.rain.off=Rain turned off
nei.chat.time=Day %d. %d:00
nei.chat.give.noitem=No such item.
nei.options=NEI Options
nei.options.back=Back
nei.options.world=World
nei.options.global=Global
nei.options.global.tip.0=Options apply to all worlds
nei.options.global.tip.1=Click the W beside an:option to enable an:override for this world
nei.options.wbutton.tip.0=Using global settings
nei.options.wbutton.tip.1=Overriding global setting
nei.options.keys=KeyBindings
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.gui.enchant=Enchantments
nei.options.keys.gui.potion=Potions
nei.options.keys.gui.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.search=Focus Search Bar
nei.options.keys.gui.bookmark=Add Bookmark
nei.options.keys.gui.hide_bookmarks=Toggle Bookmark Panel Visibility
nei.options.keys.world=World
nei.options.keys.world.chunkoverlay=Chunk Boundary Overlay
nei.options.keys.world.moboverlay=Mob Spawn Overlay
nei.options.keys.world.highlight_tips=Highlight Tooltips
nei.options.keys.world.dawn=Dawn
nei.options.keys.world.noon=Noon
nei.options.keys.world.dusk=Dusk
nei.options.keys.world.midnight=Midnight
nei.options.keys.world.rain=Rain
nei.options.keys.world.heal=Heal
nei.options.keys.world.creative=Gamemode
nei.options.keys.world.creative.tip=Cycle Gamemode
nei.options.inventory=Inventory
nei.options.inventory.bookmarksEnabled=Bookmarks Panel Visibility
nei.options.inventory.bookmarksEnabled.true=Visible
nei.options.inventory.bookmarksEnabled.false=Hidden
nei.options.inventory.jei_style_tabs=JEI Style Tabs
nei.options.inventory.jei_style_tabs.true=Yes
nei.options.inventory.jei_style_tabs.false=No [Weirdo]
nei.options.inventory.jei_style_item_presence_overlay=JEI Style Item Overlay on ?-Hover
nei.options.inventory.jei_style_item_presence_overlay.true=Yes
nei.options.inventory.jei_style_item_presence_overlay.false=No
nei.options.inventory.creative_tab_style=Creative or JEI tab style
nei.options.inventory.creative_tab_style.true=Creative
nei.options.inventory.creative_tab_style.false=JEI
nei.options.inventory.widgetsenabled.true=NEI Enabled
nei.options.inventory.widgetsenabled.false=NEI Disabled
nei.options.inventory.cheatmode.0=Recipe Mode
nei.options.inventory.cheatmode.1=Utility Mode
nei.options.inventory.cheatmode.2=Cheat Mode
nei.options.inventory.profileRecipes=Profile Recipes
nei.options.inventory.profileRecipes.true=True
nei.options.inventory.profileRecipes.false=False
nei.options.inventory.itemsort=Item Panel Sorting
nei.options.inventory.itemIDs=Item IDs
nei.options.inventory.itemIDs.0=Hidden
nei.options.inventory.itemIDs.1=Auto
nei.options.inventory.itemIDs.2=Shown
nei.options.inventory.searchmode=Search Mode
nei.options.inventory.searchmode.0=Plain
nei.options.inventory.searchmode.1=Extended
nei.options.inventory.searchmode.2=Regex
nei.options.inventory.utilities=Utilities
nei.options.inventory.utilities.tip=Select features for utility mode
nei.options.inventory.utilities.time=Time
nei.options.inventory.utilities.rain=Rain
nei.options.inventory.utilities.heal=Heal
nei.options.inventory.utilities.delete=Delete
nei.options.inventory.utilities.magnet=Magnet
nei.options.inventory.utilities.gamemode=Gamemode
nei.options.inventory.utilities.enchant=Enchanting
nei.options.inventory.utilities.potion=Potions
nei.options.inventory.utilities.item=Items
nei.options.inventory.gamemodes=Gamemodes
nei.options.inventory.gamemodes.tip=Select the gamemodes to cycle through
nei.options.inventory.gamemodes.creative=Creative
nei.options.inventory.gamemodes.creative+=Creative+
nei.options.inventory.gamemodes.adventure=Adventure
nei.options.inventory.disableMouseScrollTransfer=Disable Mouse Wheel Transfer
nei.options.inventory.disableMouseScrollTransfer.true=True
nei.options.inventory.disableMouseScrollTransfer.false=False
nei.options.inventory.invertMouseScrollTransfer=Invert Mouse Wheel Transfer Direction
nei.options.inventory.invertMouseScrollTransfer.true=True
nei.options.inventory.invertMouseScrollTransfer.false=False
nei.options.command=Commands
nei.options.command.creative=Gamemode
nei.options.command.creative.tip={0} = 1 for creative, 0 for survival, {1} = player
nei.options.command.item=Item
nei.options.command.item.tip={0} = player, {1} = id, {2} = amount, {3} = damage, {4} = nbt, {5} = name
nei.options.command.time=Time
nei.options.command.time.tip={0} = worldtime
nei.options.command.rain=Rain
nei.options.command.rain.tip={0} = 1 for on, 0 for off
nei.options.command.heal=Heal
nei.options.command.heal.tip={0} = player
nei.options.world.highlight_tips=Highlight Tooltips
nei.options.world.highlight_tips.hide=Hidden
nei.options.world.highlight_tips.show=Shown
nei.options.world.highlight_tips.sample=Sample
nei.options.tools=Tools
nei.options.tools.handler_load_from_config=Load handlers from Config
nei.options.tools.handler_load_from_config.true=Config
nei.options.tools.handler_load_from_config.false=JAR
nei.options.tools.dump=Data Dumps
nei.options.tools.dump.dump=Dump
nei.options.tools.dump.dumped=%s IDs dumped to %s
nei.options.tools.dump.mode.0=Used
nei.options.tools.dump.mode.1=Free
nei.options.tools.dump.mode.2=All
nei.options.tools.dump.item=Item
nei.options.tools.dump.items=Items
nei.options.tools.dump.block=Block
nei.options.tools.dump.blocks=Blocks
nei.options.tools.dump.potion=Potion
nei.options.tools.dump.potions=Potions
nei.options.tools.dump.enchantment=Enchantment
nei.options.tools.dump.enchantments=Enchantments
nei.options.tools.dump.biome=Biome
nei.options.tools.dump.biomes=Biomes
nei.options.tools.dump.itempanel=Item Panel
nei.options.tools.dump.itempanel.dumped=Item Panel contents were dumped to %s
nei.options.tools.dump.itempanel.mode.0=CSV
nei.options.tools.dump.itempanel.mode.1=NBT
nei.options.tools.dump.itempanel.mode.2=Json
nei.options.tools.dump.itempanel.mode.3=PNG
nei.options.tools.dump.itempanel.icon.dumped=Item Panel icons were dumped to %s
nei.options.tools.dump.itempanel.icon.cancelled=Dump cancelled
nei.options.tools.dump.handlers=NEI Handlers
nei.options.tools.dump.handlers.dumped=handlers were dumped to %s
nei.options.tools.dump.handlers.mode.0=CSV
nei.options.tools.dump.handlers.mode.1=Json
nei.recipe.page=Page %s/%s
nei.recipe.tooltip=Recipes
nei.recipe.shaped=Shaped Crafting
nei.recipe.shapeless=Shapeless Crafting
nei.recipe.furnace=Smelting
nei.recipe.fuel=Fuel
nei.recipe.fuel.required=%s required
nei.recipe.fuel.processed=%s processed
nei.recipe.fuel.produced=%s produced
nei.recipe.firework=Fireworks
nei.recipe.firework.tooltip0=Dyes add colours to the charges
nei.recipe.firework.tooltip1=Recolouring adds fade colours to the charge
nei.recipe.firework.tooltip2=Multiple charges can be spawned from one rocket
nei.recipe.brewing=Brewing
nei.recipe.profiler.crafting=Crafting Profiling
nei.recipe.profiler.usage=Usage Profiling
nei.itemsort.minecraft=Minecraft
nei.itemsort.minecraft.tip=Sorts items from vanilla minecraft first
nei.itemsort.mod=Mod
nei.itemsort.mod.tip=Groups items in the same mod, sorted by mod name
nei.itemsort.id=Item ID
nei.itemsort.default=Default
nei.itemsort.default.tip=Leave the natural ordering of each item unchanged
nei.itemsort.damage=Item Damage
nei.itemsort.name=Display Name
nei.subsets.Blocks=Blocks
nei.subsets.Blocks.MobSpawners=Mob Spawners
nei.subsets.CreativeTabs=Creative Tabs
nei.subsets.Items=Items
nei.subsets.Items.Armor=Armor
nei.subsets.Items.Armor.Boots=Boots
nei.subsets.Items.Armor.Chestplates=Chestplates
nei.subsets.Items.Armor.Helmets=Helmets
nei.subsets.Items.Armor.Leggings=Leggings
nei.subsets.Items.Food=Food
nei.subsets.Items.Potions=Potions
nei.subsets.Items.Potions.Ingredients=Ingredients
nei.subsets.Items.Potions.Negative=Negative
nei.subsets.Items.Potions.Neutral=Neutral
nei.subsets.Items.Potions.Positive=Positive
nei.subsets.Items.Potions.Splash=Splash
nei.subsets.Items.Tools=Tools
nei.subsets.Items.Tools.Axes=Axes
nei.subsets.Items.Tools.Hoes=Hoes
nei.subsets.Items.Tools.Other=Other
nei.subsets.Items.Tools.Pickaxes=Pickaxes
nei.subsets.Items.Tools.Shovels=Shovels
nei.subsets.Items.Weapons=Weapons
nei.subsets.Items.Weapons.Ranged=Ranged
nei.subsets.Items.Weapons.Swords=Swords
nei.subsets.Mod=Mod
-218
View File
@@ -1,218 +0,0 @@
nei.load=Загрузить
nei.save=Сохранить
nei.enchant=Зачаровывание
nei.enchant.level=Уровень
nei.enchant.locked=Открытые
nei.enchant.unlocked=Закрытые
nei.potion.favourite=Любимые зелья
nei.potion.duration=Длительность
nei.potion.level=Уровень
nei.inventory.options=Опции
nei.inventory.prev=Предыдущая
nei.inventory.next=Следующая
nei.inventory.item_subsets=Подмножества предметов
nei.inventory.delete.one=Удалить %s
nei.inventory.delete.all=Удалить ВСЕ %s
nei.inventory.delete.enable=Режим удаления
nei.inventory.delete.1=Включить режим удаления
nei.inventory.delete.0=Выключить режим удаления
nei.inventory.rain.enable=Дождь
nei.inventory.rain.1=Включить дождь
nei.inventory.rain.0=Выключить дождь
nei.inventory.magnet.enable=Режим магнита
nei.inventory.magnet.1=Включить режим магнита
nei.inventory.magnet.0=Выключить режим магнита
nei.inventory.dawn.enable=Включить рассвет-полдень
nei.inventory.dawn.set=Установить время на рассвет
nei.inventory.noon.enable=Включить полдень-сумерки
nei.inventory.noon.set=Установить время на полдень
nei.inventory.dusk.enable=Включить сумерки-полночь
nei.inventory.dusk.set=Установить время на сумерки
nei.inventory.midnight.enable=Включить полночь-рассвет
nei.inventory.midnight.set=Установить время на полночь
nei.inventory.heal=Исцелить игрока
nei.inventory.gamemode.0=Установить игровой режим на выживание
nei.inventory.gamemode.1=Установить игровой режим на творческий
nei.inventory.gamemode.2=Установить игровой режим на творческий+
nei.inventory.gamemode.3=Установить игровой режим на приключение
nei.chat.gamemode.0=Теперь Вы играете в режиме выживание
nei.chat.gamemode.1=Теперь Вы играете в режиме творчество
nei.chat.gamemode.2=Теперь Вы играете в режиме творчество+
nei.chat.gamemode.3=Теперь Вы играете в режиме приключение
nei.chat.rain.on=Дождь включён
nei.chat.rain.off=Дождь выключен
nei.chat.time=День %d. %d:00
nei.chat.give.noitem=Нет такого предмета.
nei.options=Опции NEI
nei.options.back=Назад
nei.options.world=Мировые
nei.options.global=Глобальные
nei.options.global.tip.0=Настройки применяются ко всем мирам
nei.options.global.tip.1=Нажмите W рядом с:опцией, чтобы включить:перезапись для этого мира
nei.options.wbutton.tip.0=Использование глобальных настроек
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.enchant=Чары
nei.options.keys.gui.potion=Зелья
nei.options.keys.gui.back=Предыдущий рецепт
nei.options.keys.gui.prev=Предыдущая страница
nei.options.keys.gui.next=Следующая страница
nei.options.keys.gui.hide=Переключить видимость NEI
nei.options.keys.gui.search=Сфокусироваться на панели поиска
nei.options.keys.world=Мир
nei.options.keys.world.chunkoverlay=Наложение границ чанков
nei.options.keys.world.moboverlay=Наложение появления мобов
nei.options.keys.world.highlight_tips=Показывать всплывающие подсказки
nei.options.keys.world.dawn=Рассвет
nei.options.keys.world.noon=Полдень
nei.options.keys.world.dusk=Сумерки
nei.options.keys.world.midnight=Полночь
nei.options.keys.world.rain=Дождь
nei.options.keys.world.heal=Исцеление
nei.options.keys.world.creative=Игровой режим
nei.options.keys.world.creative.tip=Круг игровых режимов
nei.options.inventory=Инвентарь
nei.options.inventory.widgetsenabled.true=NEI включён
nei.options.inventory.widgetsenabled.false=NEI выключен
nei.options.inventory.cheatmode.0=Режим рецептов
nei.options.inventory.cheatmode.1=Режим полезностей
nei.options.inventory.cheatmode.2=Чит-режим
nei.options.inventory.profileRecipes=Рецепты профиля
nei.options.inventory.profileRecipes.true=Да
nei.options.inventory.profileRecipes.false=Нет
nei.options.inventory.itemsort=Панель сортировки предметов
nei.options.inventory.itemIDs=ID предметов
nei.options.inventory.itemIDs.0=Спрятаны
nei.options.inventory.itemIDs.1=Авто
nei.options.inventory.itemIDs.2=Показаны
nei.options.inventory.searchmode=Режим поиска
nei.options.inventory.searchmode.0=Обычный
nei.options.inventory.searchmode.1=Расширенный
nei.options.inventory.searchmode.2=Регулярные выражения
nei.options.inventory.utilities=Полезности
nei.options.inventory.utilities.tip=Выберете функции для режима полезностей
nei.options.inventory.utilities.time=Время
nei.options.inventory.utilities.rain=Дождь
nei.options.inventory.utilities.heal=Исцеление
nei.options.inventory.utilities.delete=Удаление
nei.options.inventory.utilities.magnet=Магнит
nei.options.inventory.utilities.gamemode=Игровой режим
nei.options.inventory.utilities.enchant=Зачаровывание
nei.options.inventory.utilities.potion=Зелья
nei.options.inventory.utilities.item=Предметы
nei.options.inventory.gamemodes=Игровые режимы
nei.options.inventory.gamemodes.tip=Выберете игровые режимы для переключения между ними
nei.options.inventory.gamemodes.creative=Творческий
nei.options.inventory.gamemodes.creative+=Творческий+
nei.options.inventory.gamemodes.adventure=Приключение
nei.options.command=Команды
nei.options.command.creative=Игровой режим
nei.options.command.creative.tip={0} = 1 для творческого, 0 для выживания, {1} = игрок
nei.options.command.item=Предмет
nei.options.command.item.tip={0} = игрок, {1} = id, {2} = количество, {3} = урон, {4} = nbt, {5} = имя
nei.options.command.time=Время
nei.options.command.time.tip={0} = мировое время
nei.options.command.rain=Дождь
nei.options.command.rain.tip={0} = 1 для включения, 0 для выключения
nei.options.command.heal=Исцеление
nei.options.command.heal.tip={0} = игрок
nei.options.world.highlight_tips=Всплывающие подсказки
nei.options.world.highlight_tips.hide=Спрятаны
nei.options.world.highlight_tips.show=Показаны
nei.options.world.highlight_tips.sample=Пример
nei.options.tools=Инструменты
nei.options.tools.dump=Дампы памяти
nei.options.tools.dump.dump=Дамп
nei.options.tools.dump.dumped=ID %s сохранены в %s
nei.options.tools.dump.mode.0=Используемые
nei.options.tools.dump.mode.1=Свободные
nei.options.tools.dump.mode.2=Все
nei.options.tools.dump.item=Предмет
nei.options.tools.dump.items=Предметы
nei.options.tools.dump.block=Блок
nei.options.tools.dump.blocks=Блоки
nei.options.tools.dump.potion=Зелье
nei.options.tools.dump.potions=Зелья
nei.options.tools.dump.enchantment=Зачарование
nei.options.tools.dump.enchantments=Зачарования
nei.options.tools.dump.biome=Биом
nei.options.tools.dump.biomes=Биомы
nei.options.tools.dump.itempanel=Панель предметов
nei.options.tools.dump.itempanel.dumped=Содержимое панели предметов сохранено в %s
nei.options.tools.dump.itempanel.mode.0=CSV
nei.options.tools.dump.itempanel.mode.1=NBT
nei.options.tools.dump.itempanel.mode.2=Json
nei.options.tools.dump.itempanel.mode.3=PNG
nei.options.tools.dump.itempanel.icon.dumped=Иконки панели предметов сохранены в %s
nei.options.tools.dump.itempanel.icon.cancelled=Дамп отменён
nei.recipe.page=Страница %s/%s
nei.recipe.tooltip=Рецепты
nei.recipe.shaped=Форменное создание
nei.recipe.shapeless=Бесформенное создание
nei.recipe.furnace=Выплавка
nei.recipe.fuel=Топливо
nei.recipe.fuel.required=Требуется: %s
nei.recipe.fuel.processed=Обработано: %s
nei.recipe.fuel.produced=Произведено: %s
nei.recipe.firework=Фейерверки
nei.recipe.firework.tooltip0=Красители добавляют цвета на звёздочку
nei.recipe.firework.tooltip1=Recolouring adds fade colours to the charge
nei.recipe.firework.tooltip2=Multiple charges can be spawned from one rocket
nei.recipe.brewing=Зельеварение
nei.recipe.profiler.crafting=Профилирование создания
nei.recipe.profiler.usage=Использование профилирования
nei.itemsort.minecraft=Minecraft
nei.itemsort.minecraft.tip=Сортирует предметы сначало из оригинального Minecraft
nei.itemsort.mod=По модификации
nei.itemsort.mod.tip=Группирует предметы в один мод, на основе имени мода
nei.itemsort.id=ID предмета
nei.itemsort.default=По-умолчанию
nei.itemsort.default.tip=Обычный порядок предметов
nei.itemsort.damage=Повреждение предмета
nei.itemsort.name=Отображаемое имя
nei.subsets.Blocks=Блоки
nei.subsets.Blocks.MobSpawners=Спаунеры
nei.subsets.CreativeTabs=Творческие вкладки
nei.subsets.Items=Предметы
nei.subsets.Items.Armor=Броня
nei.subsets.Items.Armor.Boots=Ботинки
nei.subsets.Items.Armor.Chestplates=Кирасы
nei.subsets.Items.Armor.Helmets=Шлемы
nei.subsets.Items.Armor.Leggings=Поножи
nei.subsets.Items.Food=Еда
nei.subsets.Items.Potions=Зелья
nei.subsets.Items.Potions.Ingredients=Ингридиенты
nei.subsets.Items.Potions.Negative=Негативные
nei.subsets.Items.Potions.Neutral=Нейтральные
nei.subsets.Items.Potions.Positive=Полезные
nei.subsets.Items.Potions.Splash=Взрывные
nei.subsets.Items.Tools=Инструменты
nei.subsets.Items.Tools.Axes=Топоры
nei.subsets.Items.Tools.Hoes=Мотыги
nei.subsets.Items.Tools.Other=Другие
nei.subsets.Items.Tools.Pickaxes=Кирки
nei.subsets.Items.Tools.Shovels=Лопаты
nei.subsets.Items.Weapons=Оружие
nei.subsets.Items.Weapons.Ranged=Дальнего боя
nei.subsets.Items.Weapons.Swords=Мечи
nei.subsets.Mod=Модификации
Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.9 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 37 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.1 KiB

-21
View File
@@ -1,21 +0,0 @@
[
{
"modid": "NotEnoughItems",
"name": "Not Enough Items",
"version": "${version}",
"mcversion": "${mc_version}",
"description": "Recipe Viewer, Inventory Manager, Item Spawner, Cheats and more; GTNH Version
<plugins>
Supporters: EmuCraft Team, Victor Zimmer, lexi85, Ace_Trainer_Tullius, Bacon_Donut, Iarinu",
"url": "http://www.minecraftforum.net/topic/909223",
"credits": "Alexandria - original idea",
"license": "LGPL-3.0",
"authorList": [ "ChickenBones", "mitchej123" ],
"dependencies": [
"CodeChickenCore"
]
}
]
+24 -17
View File
@@ -1,19 +1,26 @@
/*
* This settings file was auto generated by the Gradle buildInit task
* by 'sunstrike' at '21/11/13 14:14' with Gradle 1.9
*
* The settings file is used to specify which projects to include in your build.
* In a single project build this file can be empty or even removed.
*
* Detailed information about configuring a multi-project build in Gradle can be found
* in the user guide at http://gradle.org/docs/1.9/userguide/multi_project_builds.html
*/
/*
// To declare projects as part of a multi-project build use the 'include' method
include 'shared'
include 'api'
include 'services:webservice'
*/
pluginManagement {
repositories {
maven {
// RetroFuturaGradle
name "GTNH Maven"
url "https://nexus.gtnewhorizons.com/repository/public/"
mavenContent {
includeGroup("com.gtnewhorizons")
includeGroupByRegex("com\\.gtnewhorizons\\..+")
}
}
gradlePluginPortal()
mavenCentral()
mavenLocal()
}
}
plugins {
id 'com.gtnewhorizons.gtnhsettingsconvention' version '2.0.34'
}
rootProject.name = "NotEnoughItems"
rootProject.name = 'NotEnoughItems'
-174
View File
@@ -1,174 +0,0 @@
package codechicken.nei;
import codechicken.nei.util.NBTJson;
import com.google.gson.JsonParser;
import com.google.gson.JsonSyntaxException;
import cpw.mods.fml.common.registry.GameData;
import net.minecraft.client.gui.inventory.GuiContainer;
import net.minecraft.item.Item;
import net.minecraft.item.ItemStack;
import net.minecraft.nbt.NBTTagCompound;
import org.apache.commons.io.IOUtils;
import java.io.File;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
/*
* TODO:
* 1) Bookmark button to toggle visibility
*/
public class BookmarkPanel extends ItemPanel {
public void init() {
super.init();
}
@Override
protected void setItems() {
realItems = _items;
}
public String getLabelText() {
return super.getLabelText() + " [" + realItems.size() + "]";
}
public void addOrRemoveItem(ItemStack item) {
ItemStack normalized = normalize(item);
if(!remove(normalized)) {
_items.add(normalized);
}
saveBookmarks();
}
public static NBTTagCompound itemStackToNBT(ItemStack stack, NBTTagCompound nbTag)
{
String strId = Item.itemRegistry.getNameForObject(stack.getItem());
nbTag.setString("strId", strId);
nbTag.setByte("Count", (byte)stack.stackSize);
nbTag.setShort("Damage", (short)stack.getItemDamage());
if (stack.stackTagCompound != null)
{
nbTag.setTag("tag", stack.stackTagCompound);
}
return nbTag;
}
public static ItemStack loadFromNBT(NBTTagCompound nbtTag)
{
if (!nbtTag.hasKey("id")) {
final short id = (short)GameData.getItemRegistry().getId(nbtTag.getString("strId"));
nbtTag.setShort("id", id);
}
ItemStack stack = ItemStack.loadItemStackFromNBT(nbtTag);
return stack;
}
public void saveBookmarks() {
List<String> strings = new ArrayList<>();
for (ItemStack item:_items) {
strings.add(NBTJson.toJson(itemStackToNBT(item, new NBTTagCompound())));
}
File file = NEIClientConfig.bookmarkFile;
if(file != null) {
try(FileWriter writer = new FileWriter(file)) {
IOUtils.writeLines(strings, "\n", writer);
} catch (IOException e) {
NEIClientConfig.logger.error("Filed to save bookmarks list to file {}", file, e);
}
}
}
public void loadBookmarks() {
File file = NEIClientConfig.bookmarkFile;
if (file == null || !file.exists()) {
return;
}
List<String> itemStrings;
try (FileReader reader = new FileReader(file)) {
NEIClientConfig.logger.info("Loading bookmarks from file {}", file);
itemStrings = IOUtils.readLines(reader);
} catch (IOException e) {
NEIClientConfig.logger.error("Failed to load bookmarks from file {}", file, e);
return;
}
_items.clear();
JsonParser parser = new JsonParser();
for (String itemStr: itemStrings) {
try {
NBTTagCompound itemStackNBT = (NBTTagCompound) NBTJson.toNbt(parser.parse(itemStr));
ItemStack itemStack = loadFromNBT(itemStackNBT);
if (itemStack != null) {
_items.add(itemStack);
} else {
NEIClientConfig.logger.warn("Failed to load bookmarked ItemStack from json string, the item no longer exists:\n{}", itemStr);
}
} catch (IllegalArgumentException | JsonSyntaxException e) {
NEIClientConfig.logger.error("Failed to load bookmarked ItemStack from json string:\n{}", itemStr);
}
}
}
protected ItemStack normalize(ItemStack item) {
ItemStack copy = item.copy();
copy.stackSize = 1;
return copy;
}
private boolean remove(ItemStack item) {
int i = 0;
for (ItemStack existing : _items) {
if (existing == item || existing.isItemEqual(item)) {
_items.remove(i);
return true;
}
i++;
}
return false;
}
@Override
public int getX(GuiContainer gui) {
return 5;
}
@Override
public int getMarginLeft() {
return 5;
}
@Override
public int getButtonTop() {
LayoutStyleMinecraft layout = (LayoutStyleMinecraft)LayoutManager.getLayoutStyle();
return 2 + (((int)Math.ceil((double)layout.buttonCount / layout.numButtons)) * 18);
}
@Override
public int getNextX(GuiContainer gui) {
return gui.width - prev.w - 2 - ((gui.xSize + gui.width) /2 + 2) - 16;
}
@Override
public int getPrevX(GuiContainer gui) {
return 2;
}
@Override
public int getPageX(GuiContainer gui) {
return gui.guiLeft * 3 / 2 + gui.xSize + 1 - ((gui.xSize + gui.width) / 2 + 2) - 16;
}
public int getHightAdjustment() {
return 0;
}
public int getWidth(GuiContainer gui) {
return LayoutManager.getLeftSize(gui) - ( (gui.xSize + gui.width) / 2 + 3 ) - 16;
}
}
-264
View File
@@ -1,264 +0,0 @@
package codechicken.nei;
import codechicken.core.ClientUtils;
import codechicken.core.GuiModListScroll;
import codechicken.lib.packet.PacketCustom;
import codechicken.nei.api.API;
import codechicken.nei.api.ItemInfo;
import cpw.mods.fml.client.CustomModLoadingErrorDisplayException;
import cpw.mods.fml.common.FMLCommonHandler;
import cpw.mods.fml.common.Loader;
import cpw.mods.fml.common.eventhandler.SubscribeEvent;
import cpw.mods.fml.common.gameevent.TickEvent;
import cpw.mods.fml.common.gameevent.TickEvent.Phase;
import net.minecraft.client.Minecraft;
import net.minecraft.client.entity.EntityPlayerSP;
import net.minecraft.client.gui.FontRenderer;
import net.minecraft.client.gui.GuiErrorScreen;
import net.minecraft.client.gui.GuiMainMenu;
import net.minecraft.client.gui.GuiScreen;
import net.minecraft.client.gui.GuiSelectWorld;
import net.minecraft.client.multiplayer.WorldClient;
import net.minecraft.entity.Entity;
import net.minecraft.entity.item.EntityItem;
import net.minecraft.world.World;
import net.minecraftforge.client.event.RenderWorldLastEvent;
import net.minecraftforge.common.MinecraftForge;
import org.apache.commons.io.IOUtils;
import java.io.File;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
public class ClientHandler
{
private static String[] defaultSerialHandlers = {
"WayofTime.alchemicalWizardry.client.nei.NEIAlchemyRecipeHandler"
};
private static ClientHandler instance;
private ArrayList<EntityItem> SMPmagneticItems = new ArrayList<>();
private World lastworld;
private GuiScreen lastGui;
public void addSMPMagneticItem(int i, World world) {
WorldClient cworld = (WorldClient) world;
Entity e = cworld.getEntityByID(i);
if (!(e instanceof EntityItem)) {
return;
}
SMPmagneticItems.add((EntityItem) e);
}
private void updateMagnetMode(World world, EntityPlayerSP player) {
if (!NEIClientConfig.getMagnetMode()) return;
float distancexz = 16;
float distancey = 8;
double maxspeedxz = 0.5;
double maxspeedy = 0.5;
double speedxz = 0.05;
double speedy = 0.07;
List<EntityItem> items;
if (world.isRemote) {
items = SMPmagneticItems;
} else {
items = world.getEntitiesWithinAABB(EntityItem.class, player.boundingBox.expand(distancexz, distancey, distancexz));
}
for (Iterator<EntityItem> iterator = items.iterator(); iterator.hasNext(); ) {
EntityItem item = iterator.next();
if (item.delayBeforeCanPickup > 0) continue;
if (item.isDead && world.isRemote) iterator.remove();
if (!NEIClientUtils.canItemFitInInventory(player, item.getEntityItem())) continue;
double dx = player.posX - item.posX;
double dy = player.posY + player.getEyeHeight() - item.posY;
double dz = player.posZ - item.posZ;
double absxz = Math.sqrt(dx * dx + dz * dz);
double absy = Math.abs(dy);
if (absxz > distancexz) {
continue;
}
if (absxz > 1) {
dx /= absxz;
dz /= absxz;
}
if (absy > 1) {
dy /= absy;
}
double vx = item.motionX + speedxz * dx;
double vy = item.motionY + speedy * dy;
double vz = item.motionZ + speedxz * dz;
double absvxz = Math.sqrt(vx * vx + vz * vz);
double absvy = Math.abs(vy);
double rationspeedxz = absvxz / maxspeedxz;
if (rationspeedxz > 1) {
vx /= rationspeedxz;
vz /= rationspeedxz;
}
double rationspeedy = absvy / maxspeedy;
if (rationspeedy > 1) {
vy /= rationspeedy;
}
if (absvxz < 0.2 && absxz < 0.2 && world.isRemote) {
item.setDead();
}
item.setVelocity(vx, vy, vz);
}
}
public static void preInit() {
loadSerialHandlers();
ItemInfo.preInit();
}
public static void loadSerialHandlers() {
File file = NEIClientConfig.serialHandlersFile;
if(!file.exists()) {
try(FileWriter writer = new FileWriter(file)) {
NEIClientConfig.logger.info("Creating default serial handlers list {}", file);
Collection<String> toSave = Loader.isModLoaded("dreamcraft") ? Collections.singletonList("") : Arrays.asList(defaultSerialHandlers);
IOUtils.writeLines(toSave, "\n", writer);
} catch (IOException e) {
NEIClientConfig.logger.error("Failed to save default serial handlers list to file {}", file, e);
}
}
try (FileReader reader = new FileReader(file)) {
NEIClientConfig.logger.info("Loading serial handlers from file {}", file);
NEIClientConfig.serialHandlers = new HashSet<>(IOUtils.readLines(reader));
} catch (IOException e) {
NEIClientConfig.logger.error("Failed to load serial handlers from file {}", file, e);
}
}
public static void load() {
instance = new ClientHandler();
GuiModListScroll.register("NotEnoughItems");
PacketCustom.assignHandler(NEICPH.channel, new NEICPH());
FMLCommonHandler.instance().bus().register(instance);
MinecraftForge.EVENT_BUS.register(instance);
API.registerHighlightHandler(new DefaultHighlightHandler(), ItemInfo.Layout.HEADER);
HUDRenderer.load();
WorldOverlayRenderer.load();
}
@SubscribeEvent
public void tickEvent(TickEvent.ClientTickEvent event) {
if(event.phase == Phase.END)
return;
Minecraft mc = Minecraft.getMinecraft();
if(mc.theWorld != null) {
loadWorld(mc.theWorld, false);
if (!NEIClientConfig.isEnabled())
return;
KeyManager.tickKeyStates();
NEIController.updateUnlimitedItems(mc.thePlayer.inventory);
if (mc.currentScreen == null)
NEIController.processCreativeCycling(mc.thePlayer.inventory);
updateMagnetMode(mc.theWorld, mc.thePlayer);
}
GuiScreen gui = mc.currentScreen;
if (gui != lastGui) {
if (gui instanceof GuiMainMenu)
lastworld = null;
else if (gui instanceof GuiSelectWorld)
NEIClientConfig.reloadSaves();
}
lastGui = gui;
}
@SubscribeEvent
public void tickEvent(TickEvent.RenderTickEvent event) {
if(event.phase == Phase.END && NEIClientConfig.isEnabled())
HUDRenderer.renderOverlay();
}
@SubscribeEvent
public void renderLastEvent(RenderWorldLastEvent event) {
if (NEIClientConfig.isEnabled())
WorldOverlayRenderer.render(event.partialTicks);
}
public void loadWorld(World world, boolean fromServer) {
if (world != lastworld) {
SMPmagneticItems.clear();
WorldOverlayRenderer.reset();
if (!fromServer) {
NEIClientConfig.setHasSMPCounterPart(false);
NEIClientConfig.setInternalEnabled(false);
if (!Minecraft.getMinecraft().isSingleplayer())//wait for server to initiate in singleplayer
NEIClientConfig.loadWorld("remote/" + ClientUtils.getServerIP().replace(':', '~'));
}
lastworld = world;
}
}
public static ClientHandler instance() {
return instance;
}
public static RuntimeException throwCME(final String message) {
final GuiScreen errorGui = new GuiErrorScreen(null, null)
{
@Override
public void handleMouseInput() {}
@Override
public void handleKeyboardInput() {}
@Override
public void drawScreen(int par1, int par2, float par3) {
drawDefaultBackground();
String[] s_msg = message.split("\n");
for (int i = 0; i < s_msg.length; ++i)
drawCenteredString(fontRendererObj, s_msg[i], width / 2, height / 3 + 12 * i, 0xFFFFFFFF);
}
};
@SuppressWarnings("serial")
CustomModLoadingErrorDisplayException e = new CustomModLoadingErrorDisplayException()
{
@Override
public void initGui(GuiErrorScreen errorScreen, FontRenderer fontRenderer) {
Minecraft.getMinecraft().displayGuiScreen(errorGui);
}
@Override
public void drawScreen(GuiErrorScreen errorScreen, FontRenderer fontRenderer, int mouseRelX, int mouseRelY, float tickTime) {}
};
throw e;
}
}
@@ -1,22 +0,0 @@
package codechicken.nei;
import codechicken.nei.api.ItemFilter;
import net.minecraft.item.ItemStack;
public class DoubleFilteredFilter implements ItemFilter {
private ItemFilter filter;
private ItemList.PatternItemFilter patternFilter;
public DoubleFilteredFilter(ItemFilter filter, String itemFilter) {
this.filter = filter;
this.patternFilter = new ItemList.PatternItemFilter(SearchField.getPattern(itemFilter));
}
@Override
public boolean matches(ItemStack item) {
if(filter.matches(item)) {
return patternFilter.matches(item);
}
return false;
}
}
-41
View File
@@ -1,41 +0,0 @@
package codechicken.nei;
import net.minecraft.client.Minecraft;
import net.minecraft.client.gui.FontRenderer;
import net.minecraft.client.gui.GuiButton;
import net.minecraft.util.ResourceLocation;
import org.lwjgl.opengl.GL11;
public class GuiNEIButton extends GuiButton
{
protected static final ResourceLocation guiTex = new ResourceLocation("textures/gui/widgets.png");
public GuiNEIButton(int i, int j, int k, int l, int i1, String s)
{
super(i, j, k, l, i1, s);
}
public void drawButton(Minecraft minecraft, int i, int j)
{
if(!visible)
return;
FontRenderer fontrenderer = minecraft.fontRenderer;
minecraft.renderEngine.bindTexture(guiTex);
GL11.glColor4f(1, 1, 1, 1);
boolean flag = i >= xPosition && j >= yPosition && i < xPosition + width && j < yPosition + height;
int k = getHoverState(flag);
drawTexturedModalRect(xPosition, yPosition, 0, 46 + k * 20, width / 2, height / 2);//top left
drawTexturedModalRect(xPosition + width / 2, yPosition, 200 - width / 2, 46 + k * 20, width / 2, height / 2);//top right
drawTexturedModalRect(xPosition, yPosition + height / 2, 0, 46 + k * 20 + 20 - height / 2, width / 2, height / 2);//bottom left
drawTexturedModalRect(xPosition + width / 2, yPosition + height / 2, 200 - width / 2, 46 + k * 20 + 20 - height / 2, width / 2, height / 2);//bottom right
mouseDragged(minecraft, i, j);
if(!enabled)
drawCenteredString(fontrenderer, displayString, xPosition + width / 2, yPosition + (height - 8) / 2, 0xffa0a0a0);
else if(flag)
drawCenteredString(fontrenderer, displayString, xPosition + width / 2, yPosition + (height - 8) / 2, 0xffffa0);
else
drawCenteredString(fontrenderer, displayString, xPosition + width / 2, yPosition + (height - 8) / 2, 0xe0e0e0);
}
}
-285
View File
@@ -1,285 +0,0 @@
package codechicken.nei;
import codechicken.nei.ThreadOperationTimer.TimeoutException;
import codechicken.nei.api.ItemFilter;
import codechicken.nei.api.ItemFilter.ItemFilterProvider;
import codechicken.nei.api.ItemInfo;
import codechicken.nei.guihook.GuiContainerManager;
import com.google.common.collect.ArrayListMultimap;
import com.google.common.collect.ListMultimap;
import net.minecraft.item.Item;
import net.minecraft.item.ItemStack;
import net.minecraft.util.IIcon;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.LinkedList;
import java.util.List;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ForkJoinPool;
import java.util.regex.Pattern;
import java.util.stream.Collectors;
public class ItemList
{
/**
* Fields are replaced atomically and contents never modified.
*/
public static volatile List<ItemStack> items = new ArrayList<>();
/**
* Fields are replaced atomically and contents never modified.
*/
public static volatile ListMultimap<Item, ItemStack> itemMap = ArrayListMultimap.create();
/**
* Updates to this should be synchronised on this
*/
public static final List<ItemFilterProvider> itemFilterers = new LinkedList<>();
public static final List<ItemsLoadedCallback> loadCallbacks = new LinkedList<>();
private static final HashSet<Item> erroredItems = new HashSet<>();
private static final HashSet<String> stackTraces = new HashSet<>();
public static class EverythingItemFilter implements ItemFilter
{
@Override
public boolean matches(ItemStack item) {
return true;
}
}
public static class NothingItemFilter implements ItemFilter
{
@Override
public boolean matches(ItemStack item) {
return false;
}
}
public static class PatternItemFilter implements ItemFilter
{
public Pattern pattern;
public PatternItemFilter(Pattern pattern) {
this.pattern = pattern;
}
@Override
public boolean matches(ItemStack item) {
return pattern.matcher(ItemInfo.getSearchName(item)).find();
}
}
public static class AllMultiItemFilter implements ItemFilter
{
public List<ItemFilter> filters;
public AllMultiItemFilter(List<ItemFilter> filters) {
this.filters = filters;
}
public AllMultiItemFilter() {
this(new LinkedList<>());
}
@Override
public boolean matches(ItemStack item) {
for(ItemFilter filter : filters)
try {
if (!filter.matches(item)) return false;
} catch (Exception e) {
NEIClientConfig.logger.error("Exception filtering "+item+" with "+filter, e);
}
return true;
}
}
public static class AnyMultiItemFilter implements ItemFilter
{
public List<ItemFilter> filters;
public AnyMultiItemFilter(List<ItemFilter> filters) {
this.filters = filters;
}
public AnyMultiItemFilter() {
this(new LinkedList<>());
}
@Override
public boolean matches(ItemStack item) {
for(ItemFilter filter : filters)
try {
if (filter.matches(item)) return true;
} catch (Exception e) {
NEIClientConfig.logger.error("Exception filtering "+item+" with "+filter, e);
}
return false;
}
}
public static interface ItemsLoadedCallback
{
public void itemsLoaded();
}
public static boolean itemMatchesAll(ItemStack item, List<ItemFilter> filters) {
for(ItemFilter filter : filters) {
try {
if (!filter.matches(item))
return false;
} catch (Exception e) {
NEIClientConfig.logger.error("Exception filtering "+item+" with "+filter, e);
}
}
return true;
}
/**
* @deprecated use getItemListFilter().matches(item)
*/
@Deprecated
public static boolean itemMatches(ItemStack item) {
return getItemListFilter().matches(item);
}
public static ItemFilter getItemListFilter() {
return new AllMultiItemFilter(getItemFilters());
}
public static List<ItemFilter> getItemFilters() {
LinkedList<ItemFilter> filters = new LinkedList<>();
synchronized (itemFilterers) {
for(ItemFilterProvider p : itemFilterers)
filters.add(p.getFilter());
}
return filters;
}
public static final RestartableTask loadItems = new RestartableTask("NEI Item Loading")
{
private void damageSearch(Item item, List<ItemStack> permutations) {
HashSet<String> damageIconSet = new HashSet<>();
for (int damage = 0; damage < 16; damage++)
try {
ItemStack itemstack = new ItemStack(item, 1, damage);
IIcon icon = item.getIconIndex(itemstack);
String name = GuiContainerManager.concatenatedDisplayName(itemstack, false);
String s = name + "@" + (icon == null ? 0 : icon.hashCode());
if (!damageIconSet.contains(s)) {
damageIconSet.add(s);
permutations.add(itemstack);
}
}
catch(TimeoutException t) {
throw t;
}
catch(Throwable t) {
NEIServerUtils.logOnce(t, stackTraces, "Ommiting "+item+":"+damage+" "+item.getClass().getSimpleName(), item.toString());
}
}
@Override
@SuppressWarnings("unchecked")
public void execute() {
// System.out.println("Executing NEI Item Loading");
ThreadOperationTimer timer = getTimer(500);
LinkedList<ItemStack> items = new LinkedList<>();
LinkedList<ItemStack> permutations = new LinkedList<>();
ListMultimap<Item, ItemStack> itemMap = ArrayListMultimap.create();
timer.setLimit(500);
for (Item item : (Iterable<Item>) Item.itemRegistry) {
if (interrupted()) return;
if (item == null || erroredItems.contains(item))
continue;
try {
timer.reset(item);
permutations.clear();
permutations.addAll(ItemInfo.itemOverrides.get(item));
if (permutations.isEmpty())
item.getSubItems(item, null, permutations);
if (permutations.isEmpty())
damageSearch(item, permutations);
permutations.addAll(ItemInfo.itemVariants.get(item));
timer.reset();
items.addAll(permutations);
itemMap.putAll(item, permutations);
} catch (Throwable t) {
NEIServerConfig.logger.error("Removing item: " + item + " from list.", t);
erroredItems.add(item);
}
}
if(interrupted()) return;
ItemList.items = items;
ItemList.itemMap = itemMap;
for(ItemsLoadedCallback callback : loadCallbacks)
callback.itemsLoaded();
updateFilter.restart();
}
};
public static ForkJoinPool getPool(int poolSize) {
if(poolSize < 1)
poolSize = 1;
return new ForkJoinPool(poolSize);
}
public static final int numProcessors = Runtime.getRuntime().availableProcessors();
public static ForkJoinPool forkJoinPool = getPool(numProcessors * 2 / 3);
public static final RestartableTask updateFilter = new RestartableTask("NEI Item Filtering")
{
@Override
public void execute() {
// System.out.println("Executing NEI Item Filtering");
ArrayList<ItemStack> filtered;
ItemFilter filter = getItemListFilter();
try {
filtered = ItemList.forkJoinPool.submit(() -> items.parallelStream()
.filter(filter::matches)
.collect(Collectors.toCollection(ArrayList::new))).get();
} catch (InterruptedException | ExecutionException e) {
filtered = new ArrayList<>();
e.printStackTrace();
stop();
}
if(interrupted()) return;
ItemSorter.sort(filtered);
if(interrupted()) return;
ItemPanel.updateItemList(filtered);
}
};
/**
* @deprecated Use updateFilter.restart()
*/
@Deprecated
public static void updateFilter() {
updateFilter.restart();
}
/**
* @deprecated Use loadItems.restart()
*/
@Deprecated
public static void loadItems() {
loadItems.restart();
}
}
-141
View File
@@ -1,141 +0,0 @@
package codechicken.nei;
import net.minecraft.creativetab.CreativeTabs;
import net.minecraft.entity.Entity;
import net.minecraft.entity.EntityList;
import net.minecraft.entity.EntityLiving;
import net.minecraft.entity.monster.IMob;
import net.minecraft.entity.passive.EntityPig;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.init.Blocks;
import net.minecraft.item.Item;
import net.minecraft.item.ItemBlock;
import net.minecraft.item.ItemStack;
import net.minecraft.tileentity.TileEntityMobSpawner;
import net.minecraft.util.IIcon;
import net.minecraft.world.World;
import net.minecraftforge.client.MinecraftForgeClient;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
public class ItemMobSpawner extends ItemBlock
{
private static Map<Integer, EntityLiving> entityHashMap;
private static Map<Integer, String> IDtoNameMap;
public static int idPig;
private static boolean loaded;
public ItemMobSpawner() {
super(Blocks.mob_spawner);
hasSubtypes = true;
MinecraftForgeClient.registerItemRenderer(this, new SpawnerRenderer());
entityHashMap = new HashMap<>();
IDtoNameMap = new HashMap<>();
}
/**
* These are ASM translated from BlockMobSpawner
*/
public static int placedX;
public static int placedY;
public static int placedZ;
@Override
public IIcon getIconFromDamage(int par1) {
return Blocks.mob_spawner.getBlockTextureFromSide(0);
}
public boolean onItemUse(ItemStack itemstack, EntityPlayer entityplayer, World world, int x, int y, int z, int par7, float par8, float par9, float par10) {
if (super.onItemUse(itemstack, entityplayer, world, x, y, z, par7, par8, par9, par10) && world.isRemote) {
TileEntityMobSpawner tileentitymobspawner = (TileEntityMobSpawner) world.getTileEntity(placedX, placedY, placedZ);
if (tileentitymobspawner != null) {
setDefaultTag(itemstack);
String mobtype = IDtoNameMap.get(itemstack.getItemDamage());
if (mobtype != null) {
NEICPH.sendMobSpawnerID(placedX, placedY, placedZ, mobtype);
tileentitymobspawner.func_145881_a().setEntityName(mobtype);
}
}
return true;
}
return false;
}
@Override
public void addInformation(ItemStack itemstack, EntityPlayer par2EntityPlayer, List list, boolean par4) {
setDefaultTag(itemstack);
int meta = itemstack.getItemDamage();
if (meta == 0) {
meta = idPig;
}
Entity e = getEntity(meta);
list.add("\u00A7" + (e instanceof IMob ? "4" : "3") + IDtoNameMap.get(meta));
}
public static EntityLiving getEntity(int ID) {
EntityLiving e = entityHashMap.get(ID);
if (e == null) {
World world = NEIClientUtils.mc().theWorld;
loadSpawners(world);
Class<?> clazz = (Class<?>) EntityList.IDtoClassMapping.get(ID);
try {
e = (EntityLiving) clazz.getConstructor(new Class[]{World.class}).newInstance(world);
} catch (Throwable t) {
if(clazz == null)
NEIClientConfig.logger.error("Null class for entity ("+ID+", "+IDtoNameMap.get(ID));
else
NEIClientConfig.logger.error("Error creating instance of entity: " + clazz.getName(), t);
e = getEntity(idPig);
}
entityHashMap.put(ID, e);
}
return e;
}
private void setDefaultTag(ItemStack itemstack) {
if (!IDtoNameMap.containsKey(itemstack.getItemDamage()))
itemstack.setItemDamage(idPig);
}
public static void loadSpawners(World world) {
if (loaded) return;
loaded = true;
HashMap<Class<Entity>, String> classToStringMapping = (HashMap<Class<Entity>, String>) EntityList.classToStringMapping;
HashMap<Class<Entity>, Integer> classToIDMapping = (HashMap<Class<Entity>, Integer>) EntityList.classToIDMapping;
for (Class<Entity> eclass : classToStringMapping.keySet()) {
if (!EntityLiving.class.isAssignableFrom(eclass))
continue;
try {
EntityLiving entityliving = (EntityLiving) eclass.getConstructor(new Class[]{World.class}).newInstance(world);
entityliving.isChild();
int id = classToIDMapping.get(eclass);
String name = classToStringMapping.get(eclass);
if (name.equals("EnderDragon"))
continue;
IDtoNameMap.put(id, name);
if (name.equals("Pig"))
idPig = id;
} catch (Throwable ignored) {
}
}
IDtoNameMap.entrySet().removeIf(e -> getEntity(e.getKey()).getClass() == EntityPig.class && !e.getValue().equals("Pig"));
}
@Override
public void getSubItems(Item item, CreativeTabs tab, List list) {
if(!NEIClientConfig.hasSMPCounterPart())
list.add(new ItemStack(item));
else
for(int i : IDtoNameMap.keySet())
list.add(new ItemStack(item, 1, i));
}
}
-489
View File
@@ -1,489 +0,0 @@
package codechicken.nei;
import codechicken.lib.vec.Rectangle4i;
import codechicken.nei.api.GuiInfo;
import codechicken.nei.api.INEIGuiHandler;
import codechicken.nei.guihook.GuiContainerManager;
import codechicken.nei.recipe.GuiCraftingRecipe;
import codechicken.nei.recipe.GuiRecipe;
import codechicken.nei.recipe.GuiUsageRecipe;
import net.minecraft.client.gui.inventory.GuiContainer;
import net.minecraft.inventory.Slot;
import net.minecraft.item.ItemStack;
import java.util.ArrayList;
import static codechicken.lib.gui.GuiDraw.drawRect;
import static codechicken.nei.NEIClientConfig.canPerformAction;
public class ItemPanel extends Widget {
/**
* Backwards compat :-/
*/
public static ArrayList<ItemStack> items = new ArrayList<>();
/**
* Should not be externally modified, use updateItemList
*/
public ArrayList<ItemStack> realItems = new ArrayList<>();
/**
* Swapped into visible items on update
*/
protected ArrayList<ItemStack> _items = realItems;
public ArrayList<ItemStack> getItems() {
return realItems;
}
public static void updateItemList(ArrayList<ItemStack> newItems) {
ItemPanels.itemPanel._items = newItems;
}
public class ItemPanelSlot
{
public ItemStack item;
public int slotIndex;
public ItemPanelSlot(int index) {
item = realItems.get(index);
slotIndex = index;
}
}
public ItemStack draggedStack;
public int mouseDownSlot = -1;
public Button prev;
public Button next;
public Label pageLabel;
private int marginLeft;
private int marginTop;
private int rows;
private int columns;
private boolean[] validSlotMap;
private int firstIndex;
private int itemsPerPage;
private int page;
private int numPages;
public void init() {
pageLabel = new Label("(0/0)", true);
prev = new Button("Prev")
{
public boolean onButtonPress(boolean rightclick) {
if (!rightclick) {
scroll(-1);
return true;
}
return false;
}
@Override
public String getRenderLabel() {
return "<";
}
};
next = new Button("Next")
{
public boolean onButtonPress(boolean rightclick) {
if (!rightclick) {
scroll(1);
return true;
}
return false;
}
@Override
public String getRenderLabel() {
return ">";
}
};
}
public int getX(GuiContainer gui) {
return (gui.xSize + gui.width) / 2 + 3;
}
public int getMarginLeft() {
return x + (w % 18) / 2;
}
public int getMarginTop() {
return y + (h % 18) / 2;
}
public int getButtonTop() {
return 2;
}
public int getNextX(GuiContainer gui) {
return gui.width - prev.w - 2;
}
public int getPrevX(GuiContainer gui) {
return (gui.xSize + gui.width) / 2 + 2;
}
public int getPageX(GuiContainer gui) {
return gui.guiLeft * 3 / 2 + gui.xSize + 1;
}
public int getHeight(GuiContainer gui) {
return gui.height - 15 - y;
}
public int getWidth(GuiContainer gui) {
return LayoutManager.getSideWidth(gui) - x;
}
public String getLabelText() {
return pageLabel.text = "(" + getPage() + "/" + getNumPages() + ")";
}
protected void setItems() {
realItems = _items;
// Backwards compat
ItemPanels.itemPanel._items = _items;
}
public void resize(GuiContainer gui) {
setItems();
final int buttonHeight = 16;
final int buttonWidth = 16;
prev.x = getPrevX(gui);
prev.y = getButtonTop();
prev.h = buttonHeight;
prev.w = buttonWidth;
next.x = getNextX(gui);
next.y = getButtonTop();
next.h = buttonHeight;
next.w = buttonWidth;
pageLabel.x = getPageX(gui);
pageLabel.y = prev.y + 5;
pageLabel.text = getLabelText();
y = prev.h + prev.y;
x = getX(gui);
w = getWidth(gui);
h = getHeight(gui);
marginLeft = getMarginLeft();
marginTop = getMarginTop();
columns = w / 18;
rows = h / 18;
//sometimes width and height can be negative with certain resizing
if(rows < 0) rows = 0;
if(columns < 0) columns = 0;
calculatePage();
updateValidSlots();
}
private void calculatePage() {
if (itemsPerPage == 0)
numPages = 0;
else
numPages = (int) Math.ceil((float) realItems.size() / (float) itemsPerPage);
if (firstIndex >= realItems.size())
firstIndex = 0;
if (numPages == 0)
page = 0;
else
page = firstIndex / itemsPerPage + 1;
}
public void setVisible() {
LayoutManager.addWidget(prev);
LayoutManager.addWidget(next);
LayoutManager.addWidget(pageLabel);
}
private void updateValidSlots() {
GuiContainer gui = NEIClientUtils.getGuiContainer();
validSlotMap = new boolean[rows * columns];
itemsPerPage = 0;
for (int i = 0; i < validSlotMap.length; i++)
if (slotValid(gui, i)) {
validSlotMap[i] = true;
itemsPerPage++;
}
}
private boolean slotValid(GuiContainer gui, int i) {
Rectangle4i rect = getSlotRect(i);
try {
GuiInfo.readLock.lock();
if(GuiInfo.guiHandlers.stream().anyMatch(handler -> handler.hideItemPanelSlot(gui, rect.x, rect.y, rect.w, rect.h)))
return false;
} finally {
GuiInfo.readLock.unlock();
}
return true;
}
public Rectangle4i getSlotRect(int i) {
return getSlotRect(i / columns, i % columns);
}
public Rectangle4i getSlotRect(int row, int column) {
return new Rectangle4i(marginLeft + column * 18, marginTop + row * 18, 18, 18);
}
@Override
public void draw(int mousex, int mousey) {
if (itemsPerPage == 0)
return;
GuiContainerManager.enableMatrixStackLogging();
int index = firstIndex;
for (int i = 0; i < rows * columns && index < realItems.size(); i++) {
if (validSlotMap[i]) {
Rectangle4i rect = getSlotRect(i);
if (rect.contains(mousex, mousey))
drawRect(rect.x, rect.y, rect.w, rect.h, 0xee555555);//highlight
GuiContainerManager.drawItem(rect.x + 1, rect.y + 1, realItems.get(index));
index++;
}
}
GuiContainerManager.disableMatrixStackLogging();
}
@Override
public void postDraw(int mousex, int mousey) {
if (draggedStack != null) {
GuiContainerManager.drawItems.zLevel += 100;
GuiContainerManager.drawItem(mousex - 8, mousey - 8, draggedStack);
GuiContainerManager.drawItems.zLevel -= 100;
}
}
@Override
public void mouseDragged(int mousex, int mousey, int button, long heldTime) {
if (mouseDownSlot >= 0 && draggedStack == null && NEIClientUtils.getHeldItem() == null &&
NEIClientConfig.hasSMPCounterPart() && !GuiInfo.hasCustomSlots(NEIClientUtils.getGuiContainer())) {
ItemPanelSlot mouseOverSlot = getSlotMouseOver(mousex, mousey);
ItemStack stack = new ItemPanelSlot(mouseDownSlot).item;
if (stack != null && (mouseOverSlot == null || mouseOverSlot.slotIndex != mouseDownSlot || heldTime > 500)) {
int amount = NEIClientConfig.getItemQuantity();
if (amount == 0)
amount = stack.getMaxStackSize();
draggedStack = NEIServerUtils.copyStack(stack, amount);
}
}
}
@Override
public boolean handleClick(int mousex, int mousey, int button) {
if (handleDraggedClick(mousex, mousey, button))
return true;
if (NEIClientUtils.getHeldItem() != null) {
try {
GuiInfo.readLock.lock();
if (GuiInfo.guiHandlers.stream().anyMatch(handler -> handler.hideItemPanelSlot(NEIClientUtils.getGuiContainer(), mousex, mousey, 1, 1)))
return false;
} finally {
GuiInfo.readLock.unlock();
}
if (NEIClientConfig.canPerformAction("delete") && NEIClientConfig.canPerformAction("item"))
if (button == 1)
NEIClientUtils.decreaseSlotStack(-999);
else
NEIClientUtils.deleteHeldItem();
else
NEIClientUtils.dropHeldItem();
return true;
}
ItemPanelSlot hoverSlot = getSlotMouseOver(mousex, mousey);
if (hoverSlot != null) {
if (button == 2) {
ItemStack stack = hoverSlot.item;
if (stack != null) {
int amount = NEIClientConfig.getItemQuantity();
if (amount == 0)
amount = stack.getMaxStackSize();
draggedStack = NEIServerUtils.copyStack(stack, amount);
}
} else {
mouseDownSlot = hoverSlot.slotIndex;
}
return true;
}
return false;
}
private boolean handleDraggedClick(int mousex, int mousey, int button) {
if (draggedStack == null)
return false;
GuiContainer gui = NEIClientUtils.getGuiContainer();
boolean handled = false;
try {
GuiInfo.readLock.lock();
for (INEIGuiHandler handler : GuiInfo.guiHandlers) {
if (handler.handleDragNDrop(gui, mousex, mousey, draggedStack, button)) {
handled = true;
if (draggedStack.stackSize == 0) {
draggedStack = null;
return true;
}
}
}
} finally {
GuiInfo.readLock.unlock();
}
if (handled)
return true;
Slot overSlot = gui.getSlotAtPosition(mousex, mousey);
if (overSlot != null && overSlot.isItemValid(draggedStack)) {
if (NEIClientConfig.canCheatItem(draggedStack)) {
int contents = overSlot.getHasStack() ? overSlot.getStack().stackSize : 0;
int add = button == 0 ? draggedStack.stackSize : 1;
if (overSlot.getHasStack() && !NEIServerUtils.areStacksSameType(draggedStack, overSlot.getStack()))
contents = 0;
int total = Math.min(contents + add, Math.min(overSlot.getSlotStackLimit(), draggedStack.getMaxStackSize()));
if (total > contents) {
NEIClientUtils.setSlotContents(overSlot.slotNumber, NEIServerUtils.copyStack(draggedStack, total), true);
NEICPH.sendGiveItem(NEIServerUtils.copyStack(draggedStack, total), false, false);
draggedStack.stackSize -= total - contents;
}
if (draggedStack.stackSize == 0)
draggedStack = null;
} else {
draggedStack = null;
}
} else if (mousex < gui.guiLeft || mousey < gui.guiTop || mousex >= gui.guiLeft + gui.xSize || mousey >= gui.guiTop + gui.ySize) {
draggedStack = null;
}
return true;
}
@Override
public boolean handleClickExt(int mousex, int mousey, int button) {
return handleDraggedClick(mousex, mousey, button);
}
@Override
public void mouseUp(int mousex, int mousey, int button) {
ItemPanelSlot hoverSlot = getSlotMouseOver(mousex, mousey);
if (hoverSlot != null && hoverSlot.slotIndex == mouseDownSlot && draggedStack == null) {
ItemStack item = hoverSlot.item;
if (NEIController.manager.window instanceof GuiRecipe || !NEIClientConfig.canCheatItem(item)) {
if (button == 0)
GuiCraftingRecipe.openRecipeGui("item", item);
else if (button == 1)
GuiUsageRecipe.openRecipeGui("item", item);
draggedStack = null;
mouseDownSlot = -1;
return;
}
NEIClientUtils.cheatItem(item, button, -1);
}
mouseDownSlot = -1;
}
@Override
public boolean onMouseWheel(int i, int mousex, int mousey) {
if (!contains(mousex, mousey))
return false;
scroll(-i);
return true;
}
@Override
public boolean handleKeyPress(int keyID, char keyChar) {
if (keyID == NEIClientConfig.getKeyBinding("gui.next")) {
scroll(1);
return true;
}
if (keyID == NEIClientConfig.getKeyBinding("gui.prev")) {
scroll(-1);
return true;
}
return false;
}
@Override
public ItemStack getStackMouseOver(int mousex, int mousey) {
ItemPanelSlot slot = getSlotMouseOver(mousex, mousey);
return slot == null ? null : slot.item;
}
public ItemPanelSlot getSlotMouseOver(int mousex, int mousey) {
int index = firstIndex;
for (int i = 0; i < rows * columns && index < realItems.size(); i++)
if (validSlotMap[i]) {
if (getSlotRect(i).contains(mousex, mousey))
return new ItemPanelSlot(index);
index++;
}
return null;
}
public void scroll(int i) {
if (itemsPerPage != 0) {
int oldIndex = firstIndex;
firstIndex += i * itemsPerPage;
if (firstIndex >= realItems.size())
firstIndex = 0;
if (firstIndex < 0)
if (oldIndex > 0)
firstIndex = 0;
else
firstIndex = (realItems.size() - 1) / itemsPerPage * itemsPerPage;
calculatePage();
}
}
public int getPage() {
return page;
}
public int getNumPages() {
return numPages;
}
@Override
public boolean contains(int px, int py) {
GuiContainer gui = NEIClientUtils.getGuiContainer();
Rectangle4i rect = new Rectangle4i(px, py, 1, 1);
try {
GuiInfo.readLock.lock();
if(GuiInfo.guiHandlers.stream().anyMatch(handler -> handler.hideItemPanelSlot(gui, rect.x, rect.y, rect.w, rect.h)))
return false;
} finally {
GuiInfo.readLock.unlock();
}
return super.contains(px, py);
}
}
@@ -1,44 +0,0 @@
package codechicken.nei;
public class ItemQuantityField extends TextField
{
public ItemQuantityField(String ident) {
super(ident);
centered = true;
}
// Find a way to work this back in
public boolean isValid(String string) {
if (string.equals(""))
return true;
try {
return Integer.parseInt(string) >= 0;
} catch (NumberFormatException nfe) {
return false;
}
}
public int intValue() {
return intValue(text());
}
public int intValue(String s) {
try {
return Integer.parseInt(s);
} catch (NumberFormatException nfe) {
return 0;
}
}
@Override
public void loseFocus() {
setText(Integer.toString(NEIClientConfig.getItemQuantity()));
}
@Override
public void onTextChange(String oldText) {
if (intValue(oldText) != intValue())//hacky recursion stopper
NEIClientUtils.setItemQuantity(intValue());
}
}
-52
View File
@@ -1,52 +0,0 @@
package codechicken.nei;
import org.lwjgl.input.Keyboard;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.Map.Entry;
/**
* Good old down/held/up keystate tracker
*/
public class KeyManager
{
public static interface IKeyStateTracker
{
public void tickKeyStates();
}
public static class KeyState
{
public boolean down;
public boolean held;
public boolean up;
}
public static HashMap<String, KeyState> keyStates = new HashMap<>();
public static LinkedList<IKeyStateTracker> trackers = new LinkedList<>();
public static void tickKeyStates()
{
for(Entry<String, KeyState> entry : keyStates.entrySet())
{
int keyCode = NEIClientConfig.getKeyBinding(entry.getKey());
boolean down = keyCode != 0 && Keyboard.isKeyDown(keyCode);
KeyState state = entry.getValue();
if(down)
{
state.down = !state.held;
state.up = false;
}
else
{
state.up = state.held;
state.down = false;
}
state.held = down;
}
for(IKeyStateTracker tracker : trackers)
tracker.tickKeyStates();
}
}
@@ -1,207 +0,0 @@
package codechicken.nei;
import codechicken.nei.api.LayoutStyle;
import codechicken.nei.drawable.DrawableBuilder;
import net.minecraft.client.gui.inventory.GuiContainer;
import org.lwjgl.opengl.GL11;
import static codechicken.lib.gui.GuiDraw.drawStringC;
import static codechicken.nei.LayoutManager.bookmarkPanel;
import static codechicken.nei.LayoutManager.bookmarksButton;
import static codechicken.nei.LayoutManager.delete;
import static codechicken.nei.LayoutManager.dropDown;
import static codechicken.nei.LayoutManager.gamemode;
import static codechicken.nei.LayoutManager.heal;
import static codechicken.nei.LayoutManager.itemPanel;
import static codechicken.nei.LayoutManager.itemPresenceOverlays;
import static codechicken.nei.LayoutManager.less;
import static codechicken.nei.LayoutManager.magnet;
import static codechicken.nei.LayoutManager.more;
import static codechicken.nei.LayoutManager.options;
import static codechicken.nei.LayoutManager.quantity;
import static codechicken.nei.LayoutManager.rain;
import static codechicken.nei.LayoutManager.searchField;
import static codechicken.nei.LayoutManager.timeButtons;
import static codechicken.nei.NEIClientConfig.canPerformAction;
import static codechicken.nei.NEIClientConfig.disabledActions;
import static codechicken.nei.NEIClientConfig.getMagnetMode;
import static codechicken.nei.NEIClientConfig.isEnabled;
public class LayoutStyleMinecraft extends LayoutStyle
{
public int buttonCount;
public int leftSize;
public int numButtons;
@Override
public String getName() {
return "minecraft";
}
@Override
public void init() {
delete.icon = new Image(144, 12, 12, 12);
rain.icon = new Image(120, 12, 12, 12);
gamemode.icons[0] = new Image(132, 12, 12, 12);
gamemode.icons[1] = new Image(156, 12, 12, 12);
gamemode.icons[2] = new Image(168, 12, 12, 12);
magnet.icon = new Image(180, 24, 12, 12);
timeButtons[0].icon = new Image(132, 24, 12, 12);
timeButtons[1].icon = new Image(120, 24, 12, 12);
timeButtons[2].icon = new Image(144, 24, 12, 12);
timeButtons[3].icon = new Image(156, 24, 12, 12);
heal.icon = new Image(168, 24, 12, 12);
itemPresenceOverlays[0] = new DrawableBuilder("nei:textures/nei_tabbed_sprites.png", 0, 40, 8, 8).build();
itemPresenceOverlays[1] = new DrawableBuilder("nei:textures/nei_tabbed_sprites.png", 8, 40, 8, 8).build();
}
@Override
public void reset() {
buttonCount = 0;
}
@Override
public void layout(GuiContainer gui, VisiblityData visiblity) {
reset();
leftSize = ItemPanels.bookmarkPanel.getWidth(gui);
numButtons = Math.max(leftSize / 18, 1);
delete.state = 0x4;
if (NEIController.getDeleteMode())
delete.state |= 1;
else if (!visiblity.enableDeleteMode)
delete.state |= 2;
rain.state = 0x4;
if (disabledActions.contains("rain"))
rain.state |= 2;
else if (NEIClientUtils.isRaining())
rain.state |= 1;
gamemode.state = 0x4;
if (NEIClientUtils.getGamemode() != 0) {
gamemode.state |= 0x1;
gamemode.index = NEIClientUtils.getGamemode() - 1;
} else {
if (NEIClientUtils.isValidGamemode("creative"))
gamemode.index = 0;
else if (NEIClientUtils.isValidGamemode("creative+"))
gamemode.index = 1;
else if (NEIClientUtils.isValidGamemode("adventure"))
gamemode.index = 2;
}
bookmarksButton.index = NEIClientConfig.isBookmarkPanelHidden() ? 0 : 1;
options.index = NEIClientConfig.getCheatMode();
magnet.state = 0x4 | (getMagnetMode() ? 1 : 0);
if (canPerformAction("delete"))
layoutButton(delete);
if (canPerformAction("rain"))
layoutButton(rain);
if (NEIClientUtils.isValidGamemode("creative") ||
NEIClientUtils.isValidGamemode("creative+") ||
NEIClientUtils.isValidGamemode("adventure"))
layoutButton(gamemode);
if (canPerformAction("magnet"))
layoutButton(magnet);
if (canPerformAction("time")) {
for (int i = 0; i < 4; i++) {
timeButtons[i].state = disabledActions.contains(NEIActions.timeZones[i]) ? 2 : 0;
layoutButton(timeButtons[i]);
}
}
if (canPerformAction("heal"))
layoutButton(heal);
itemPanel.resize(gui);
bookmarkPanel.resize(gui);
more.w = more.h = less.w = less.h = 16;
less.x = itemPanel.prev.x;
more.x = gui.width - less.w - 2;
more.y = less.y = gui.height - more.h - 2;
quantity.x = less.x + less.w + 2;
quantity.y = less.y;
quantity.w = more.x - quantity.x - 2;
quantity.h = less.h;
options.x = isEnabled() ? 0 : 6;
options.y = isEnabled() ? gui.height - 22 : gui.height - 28;
options.w = 22;
options.h = 22;
bookmarksButton.x = 24 + (isEnabled() ? 0 : 6);
bookmarksButton.y = isEnabled() ? gui.height - 22 : gui.height - 28;
bookmarksButton.w = 22;
bookmarksButton.h = 22;
searchField.y = gui.height - searchField.h - 2;
dropDown.x = Math.min(numButtons, buttonCount) * 20 + 3;
dropDown.h = 20;
dropDown.w = itemPanel.x - dropDown.x - 3;
searchField.h = 20;
searchField.w = 150;
searchField.x = (gui.width - searchField.w) / 2;
if (!visiblity.showItemSection) {
searchField.setFocus(false);
}
}
public void layoutButton(Button button) {
button.x = 2 + (buttonCount % numButtons) * 20;
button.y = (buttonCount / numButtons) * 18;
button.h = 17;
button.w = button.contentWidth() + 6;
buttonCount++;
}
@Override
public void drawButton(Button b, int mousex, int mousey) {
GL11.glDisable(GL11.GL_LIGHTING);
GL11.glColor4f(1, 1, 1, 1);
int tex;
if ((b.state & 0x3) == 2)
tex = 0;
else if ((b.state & 0x4) == 0 && b.contains(mousex, mousey) ||//not a state button and mouseover
(b.state & 0x3) == 1)//state active
tex = 2;
else
tex = 1;
LayoutManager.drawButtonBackground(b.x, b.y, b.w, b.h, true, tex);
Image icon = b.getRenderIcon();
if (icon == null) {
int colour = tex == 2 ? 0xffffa0 : tex == 0 ? 0x601010 : 0xe0e0e0;
drawStringC(b.getRenderLabel(), b.x + b.w / 2, b.y + (b.h - 8) / 2, colour);
} else {
GL11.glColor4f(1, 1, 1, 1);
final int iconX = b.x + (b.w - icon.width) / 2;
final int iconY = b.y + (b.h - icon.height) / 2;
LayoutManager.drawIcon(iconX, iconY, icon);
}
}
@Override
public void drawSubsetTag(String text, int x, int y, int w, int h, int state, boolean mouseover) {
if(state == 1)
GL11.glColor4f(0.65F, 0.65F, 0.65F, 1.0F);
else
GL11.glColor4f(1, 1, 1, 1);
LayoutManager.drawButtonBackground(x, y, w, h, false, state == 0 ? 0 : 1);
if(text != null)
drawStringC(text, x, y, w, h, state == 2 ? 0xFFE0E0E0 : 0xFFA0A0A0);
}
}
-501
View File
@@ -1,501 +0,0 @@
package codechicken.nei;
import codechicken.core.CCUpdateChecker;
import codechicken.core.ClassDiscoverer;
import codechicken.core.ClientUtils;
import codechicken.core.CommonUtils;
import codechicken.lib.config.ConfigFile;
import codechicken.lib.config.ConfigTag;
import codechicken.lib.config.ConfigTagParent;
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;
import codechicken.nei.config.OptionCycled;
import codechicken.nei.config.OptionGamemodes;
import codechicken.nei.config.OptionList;
import codechicken.nei.config.OptionOpenGui;
import codechicken.nei.config.OptionTextField;
import codechicken.nei.config.OptionToggleButton;
import codechicken.nei.config.OptionToggleButtonBoubs;
import codechicken.nei.config.OptionUtilities;
import codechicken.nei.event.NEIConfigsLoadedEvent;
import codechicken.nei.recipe.GuiRecipeTab;
import codechicken.nei.recipe.RecipeInfo;
import codechicken.obfuscator.ObfuscationRun;
import net.minecraft.client.Minecraft;
import net.minecraft.client.gui.GuiScreen;
import net.minecraft.item.ItemStack;
import net.minecraft.nbt.NBTTagCompound;
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 java.io.File;
import java.util.HashSet;
import java.util.List;
public class NEIClientConfig {
private static boolean configLoaded;
private static boolean enabledOverride;
public static Logger logger = LogManager.getLogger("NotEnoughItems");
public static File configDir = new File(CommonUtils.getMinecraftDir(), "config/NEI/");
public static ConfigSet global = new ConfigSet(
new File("saves/NEI/client.dat"),
new ConfigFile(new File(configDir, "client.cfg")));
public static ConfigSet world;
public static final File bookmarkFile = new File(configDir, "bookmarks.ini");
public static final File handlerFile = new File(configDir, "handlers.csv");
public static final File serialHandlersFile = new File(configDir, "serialhandlers.cfg");
// Set of handlers that need to be run in serial
public static HashSet<String> serialHandlers = new HashSet<>();
public static ItemStack[] creativeInv;
public static boolean hasSMPCounterpart;
public static HashSet<String> permissableActions = new HashSet<>();
public static HashSet<String> disabledActions = new HashSet<>();
public static HashSet<String> enabledActions = new HashSet<>();
public static ItemStackSet bannedBlocks = new ItemStackSet();
static {
if (global.config.getTag("checkUpdates").getBooleanValue(true))
CCUpdateChecker.updateCheck("NotEnoughItems");
linkOptionList();
setDefaults();
}
private static void setDefaults() {
ConfigTagParent tag = global.config;
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");
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");
tag.setNewLineMode(1);
tag.getTag("inventory.widgetsenabled").getBooleanValue(true);
API.addOption(new OptionToggleButton("inventory.widgetsenabled"));
tag.getTag("inventory.hidden").getBooleanValue(false);
tag.getTag("inventory.cheatmode").getIntValue(2);
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)
{
@Override
public boolean optionValid(int index) {
return getLockedMode() == -1 || getLockedMode() == index && NEIInfo.isValidMode(index);
}
});
checkCheatMode();
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"));
ItemSorter.initConfig(tag);
tag.getTag("inventory.itemIDs").getIntValue(1);
API.addOption(new OptionCycled("inventory.itemIDs", 3, true));
tag.getTag("inventory.searchmode").getIntValue(1);
API.addOption(new OptionCycled("inventory.searchmode", 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);
API.addOption(new OptionOpenGui("world.highlight_tips", GuiHighlightTips.class));
tag.getTag("inventory.profileRecipes").getBooleanValue(false);
API.addOption(new OptionToggleButton("inventory.profileRecipes", true));
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) {
@Override
public boolean isEnabled() {
return isMouseScrollTransferEnabled();
}
});
tag.getTag("command.creative").setDefaultValue("/gamemode {0} {1}");
API.addOption(new OptionTextField("command.creative"));
tag.getTag("command.item").setDefaultValue("/give {0} {1} {2} {3} {4}");
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"));
tag.getTag("inventory.bookmarksEnabled").setComment("Enable/disable bookmarks").getBooleanValue(true);
API.addOption(new OptionToggleButton("inventory.bookmarksEnabled", true));
tag.getTag("inventory.jei_style_tabs").setComment("Enable/disable JEI Style Tabs").getBooleanValue(true);
API.addOption(new OptionToggleButtonBoubs("inventory.jei_style_tabs", true));
tag.getTag("inventory.jei_style_item_presence_overlay").setComment("Enable/disable JEI Style item presence overlay on ?-hover").getBooleanValue(true);
API.addOption(new OptionToggleButton("inventory.jei_style_item_presence_overlay", true));
tag.getTag("inventory.creative_tab_style").setComment("Creative or JEI style tabs").getBooleanValue(false);
API.addOption(new OptionToggleButton("inventory.creative_tab_style", true));
tag.getTag("tools.handler_load_from_config").setComment("ADVANCED: Load handlers from config").getBooleanValue(false);
API.addOption(new OptionToggleButton("tools.handler_load_from_config", true) {
@Override
public boolean onClick(int button) {
super.onClick(button);
GuiRecipeTab.loadHandlerInfo();
return true;
}
});
setDefaultKeyBindings();
}
private static void linkOptionList() {
OptionList.setOptionList(new OptionList("nei.options")
{
@Override
public ConfigSet globalConfigSet() {
return global;
}
@Override
public ConfigSet worldConfigSet() {
return world;
}
@Override
public OptionList configBase() {
return this;
}
@Override
public GuiOptionList getGui(GuiScreen parent, OptionList list, boolean world) {
return new GuiNEIOptionList(parent, list, world);
}
});
}
private static void setDefaultKeyBindings() {
API.addKeyBind("gui.recipe", Keyboard.KEY_R);
API.addKeyBind("gui.usage", Keyboard.KEY_U);
API.addKeyBind("gui.back", Keyboard.KEY_BACK);
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.addKeyBind("gui.hide", Keyboard.KEY_O);
API.addKeyBind("gui.search", Keyboard.KEY_F);
API.addKeyBind("gui.bookmark", Keyboard.KEY_A);
API.addKeyBind("gui.hide_bookmarks", Keyboard.KEY_B);
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);
}
public static OptionList getOptionList() {
return OptionList.getOptionList("nei.options");
}
public static void loadWorld(String saveName) {
setInternalEnabled(true);
logger.debug("Loading "+(Minecraft.getMinecraft().isSingleplayer() ? "Local" : "Remote")+" World");
bootNEI(ClientUtils.getWorld());
File saveDir = new File(CommonUtils.getMinecraftDir(), "saves/NEI/" + saveName);
boolean newWorld = !saveDir.exists();
if (newWorld)
saveDir.mkdirs();
world = new ConfigSet(new File(saveDir, "NEI.dat"), new ConfigFile(new File(saveDir, "NEI.cfg")));
onWorldLoad(newWorld);
}
private static void onWorldLoad(boolean newWorld) {
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");
setWorldDefaults();
creativeInv = new ItemStack[54];
LayoutManager.searchField.setText(getSearchExpression());
LayoutManager.quantity.setText(Integer.toString(getItemQuantity()));
SubsetWidget.loadHidden();
if (newWorld && Minecraft.getMinecraft().isSingleplayer())
world.config.getTag("inventory.cheatmode").setIntValue(NEIClientUtils.mc().playerController.isInCreativeMode() ? 2 : 0);
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();
}
public static int getKeyBinding(String string) {
return getSetting("keys." + string).getIntValue();
}
public static void setDefaultKeyBinding(String string, int key) {
getSetting("keys." + string).getIntValue(key);
}
public static void bootNEI(World world) {
if (configLoaded)
return;
ItemInfo.load(world);
GuiInfo.load();
RecipeInfo.load();
LayoutManager.load();
ItemPanels.bookmarkPanel.loadBookmarks();
NEIController.load();
configLoaded = true;
new Thread("NEI Plugin Loader") {
@Override
public void run() {
ClassDiscoverer classDiscoverer = new ClassDiscoverer(test -> test.startsWith("NEI") && test.endsWith("Config.class"), IConfigureNEI.class);
classDiscoverer.findClasses();
for (Class<?> clazz : classDiscoverer.classes) {
try {
IConfigureNEI config = (IConfigureNEI) clazz.newInstance();
config.loadConfig();
NEIModContainer.plugins.add(config);
logger.debug("Loaded " + clazz.getName());
} catch (Exception e) {
logger.error("Failed to Load " + clazz.getName(), e);
}
}
MinecraftForge.EVENT_BUS.post(new NEIConfigsLoadedEvent());
}
}.start();
ItemSorter.loadConfig();
}
public static boolean isWorldSpecific(String setting) {
if(world == null) return false;
ConfigTag tag = world.config.getTag(setting, false);
return tag != null && tag.value != null;
}
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");
}
public static boolean isBookmarkPanelHidden() {
return !getBooleanSetting("inventory.bookmarksEnabled");
}
public static boolean areJEIStyleTabsVisible() {
return getBooleanSetting("inventory.jei_style_tabs");
}
public static boolean isJEIStyleItemPresenceOverlayVisible() {
return getBooleanSetting("inventory.jei_style_item_presence_overlay");
}
public static boolean useCreativeTabStyle() {
return getBooleanSetting("inventory.creative_tab_style");
}
public static boolean isEnabled() {
return enabledOverride && getBooleanSetting("inventory.widgetsenabled");
}
public static boolean loadHandlersFromJar() {
return !getBooleanSetting("tools.handler_load_from_config");
}
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");
}
private static void checkCheatMode() {
if (getLockedMode() != -1)
setIntSetting("inventory.cheatmode", getLockedMode());
}
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());
}
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);
world.saveNBT();
}
public static boolean isMouseScrollTransferEnabled() {
return !getBooleanSetting("inventory.disableMouseScrollTransfer");
}
public static boolean shouldInvertMouseScrollTransfer() {
return !getBooleanSetting("inventory.invertMouseScrollTransfer");
}
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();
}
public static boolean canCheatItem(ItemStack stack) {
return canPerformAction("item") && !bannedBlocks.contains(stack);
}
public static boolean canPerformAction(String name) {
if (!isEnabled())
return false;
if (!modePermitsAction(name))
return false;
String base = NEIActions.base(name);
if (hasSMPCounterpart)
return permissableActions.contains(base);
if (NEIActions.smpRequired(name))
return false;
String cmd = getStringSetting("command." + base);
return cmd != null && cmd.startsWith("/");
}
private static boolean modePermitsAction(String name) {
if (getCheatMode() == 0) return false;
if (getCheatMode() == 2) return true;
String[] actions = getStringArrSetting("inventory.utilities");
for (String action : actions)
if (action.equalsIgnoreCase(name))
return true;
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");
if (!saveDir.exists())
return;
List<SaveFormatComparator> saves;
try {
saves = Minecraft.getMinecraft().getSaveLoader().getSaveList();
} catch (Exception e) {
logger.error("Error loading saves", e);
return;
}
HashSet<String> saveFileNames = new HashSet<>();
for (SaveFormatComparator save : saves)
saveFileNames.add(save.getFileName());
for (File file : saveDir.listFiles())
if (file.isDirectory() && !saveFileNames.contains(file.getName()))
ObfuscationRun.deleteDir(file, true);
}
}
-372
View File
@@ -1,372 +0,0 @@
package codechicken.nei;
import codechicken.lib.inventory.InventoryRange;
import codechicken.lib.inventory.InventoryUtils;
import codechicken.lib.util.LangProxy;
import codechicken.nei.api.GuiInfo;
import codechicken.nei.api.IInfiniteItemHandler;
import codechicken.nei.api.INEIGuiHandler;
import codechicken.nei.api.ItemInfo;
import com.google.common.collect.Iterables;
import net.minecraft.client.Minecraft;
import net.minecraft.client.audio.PositionedSoundRecord;
import net.minecraft.client.gui.inventory.GuiContainer;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.inventory.Container;
import net.minecraft.inventory.Slot;
import net.minecraft.item.Item;
import net.minecraft.item.ItemStack;
import net.minecraft.util.IChatComponent;
import net.minecraft.util.ResourceLocation;
import org.lwjgl.input.Keyboard;
import java.text.MessageFormat;
import java.text.NumberFormat;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.LinkedList;
import java.util.List;
import java.util.stream.Collectors;
import static codechicken.nei.NEIClientConfig.canCheatItem;
import static codechicken.nei.NEIClientConfig.canPerformAction;
import static codechicken.nei.NEIClientConfig.getItemQuantity;
import static codechicken.nei.NEIClientConfig.getStringArrSetting;
import static codechicken.nei.NEIClientConfig.getStringSetting;
import static codechicken.nei.NEIClientConfig.hasSMPCounterPart;
import static codechicken.nei.NEIClientConfig.invCreativeMode;
import static codechicken.nei.NEIClientConfig.world;
public class NEIClientUtils extends NEIServerUtils
{
public static LangProxy lang = new LangProxy("nei");
public static Minecraft mc() {
return Minecraft.getMinecraft();
}
public static String translate(String key, Object... params) {
return lang.format(key, params);
}
public static void printChatMessage(IChatComponent msg) {
if (mc().ingameGUI != null)
mc().ingameGUI.getChatGUI().printChatMessage(msg);
}
public static void deleteHeldItem() {
deleteSlotStack(-999);
}
public static void dropHeldItem() {
mc().playerController.windowClick(((GuiContainer) mc().currentScreen).inventorySlots.windowId, -999, 0, 0, mc().thePlayer);
}
public static void deleteSlotStack(int slotNumber) {
setSlotContents(slotNumber, null, true);
}
public static void decreaseSlotStack(int slotNumber) {
ItemStack stack = slotNumber == -999 ? getHeldItem() : mc().thePlayer.openContainer.getSlot(slotNumber).getStack();
if (stack == null)
return;
if (stack.stackSize == 1)
deleteSlotStack(slotNumber);
else {
stack = stack.copy();
stack.stackSize--;
setSlotContents(slotNumber, stack, true);
}
}
public static void deleteEverything() {
NEICPH.sendDeleteAllItems();
}
public static void deleteItemsOfType(ItemStack type) {
Container c = getGuiContainer().inventorySlots;
for (int i = 0; i < c.inventorySlots.size(); i++) {
Slot slot = c.getSlot(i);
if (slot == null)
continue;
ItemStack stack = slot.getStack();
if (stack != null && stack.getItem() == type.getItem() && stack.getItemDamage() == type.getItemDamage()) {
setSlotContents(i, null, true);
slot.putStack(null);
}
}
}
public static ItemStack getHeldItem() {
return mc().thePlayer.inventory.getItemStack();
}
public static void setSlotContents(int slot, ItemStack item, boolean containerInv) {
NEICPH.sendSetSlot(slot, item, containerInv);
if (slot == -999)
mc().thePlayer.inventory.setItemStack(item);
}
/**
* @param mode -1 = normal cheats, 0 = no infinites, 1 = replenish stack
*/
public static void cheatItem(ItemStack stack, int button, int mode) {
if (!canCheatItem(stack))
return;
if (mode == -1 && button == 0 && shiftKey() && NEIClientConfig.hasSMPCounterPart()) {
for (IInfiniteItemHandler handler : ItemInfo.infiniteHandlers) {
if (!handler.canHandleItem(stack))
continue;
ItemStack inf = handler.getInfiniteItem(stack);
if (inf != null) {
giveStack(inf, inf.stackSize, true);
return;
}
}
cheatItem(stack, button, 0);
} else if (button == 1) {
giveStack(stack, 1);
} else {
if (mode == 1 && stack.stackSize < stack.getMaxStackSize()) {
giveStack(stack, stack.getMaxStackSize() - stack.stackSize);
} else {
int amount = getItemQuantity();
if (amount == 0)
amount = stack.getMaxStackSize();
giveStack(stack, amount);
}
}
}
public static void giveStack(ItemStack itemstack) {
giveStack(itemstack, itemstack.stackSize);
}
public static void giveStack(ItemStack itemstack, int i) {
giveStack(itemstack, i, false);
}
public static void giveStack(ItemStack base, int i, boolean infinite) {
ItemStack stack = copyStack(base, i);
if (hasSMPCounterPart()) {
ItemStack typestack = copyStack(stack, 1);
if (!infinite && !canItemFitInInventory(mc().thePlayer, stack) && (mc().currentScreen instanceof GuiContainer)) {
GuiContainer gui = getGuiContainer();
final List<Iterable<Integer>> handlerSlots;
try {
GuiInfo.readLock.lock();
handlerSlots = GuiInfo.guiHandlers.stream().map(handler -> handler.getItemSpawnSlots(gui, typestack)).collect(Collectors.toCollection(LinkedList::new));
} finally {
GuiInfo.readLock.unlock();
}
int increment = typestack.getMaxStackSize();
int given = 0;
for(int slotNo : Iterables.concat(handlerSlots)) {
Slot slot = gui.inventorySlots.getSlot(slotNo);
if(!slot.isItemValid(typestack) || !InventoryUtils.canStack(slot.getStack(), typestack))
continue;
int qty = Math.min(stack.stackSize - given, increment);
int current = slot.getHasStack() ? slot.getStack().stackSize : 0;
qty = Math.min(qty, slot.getSlotStackLimit() - current);
ItemStack newStack = copyStack(typestack, qty + current);
slot.putStack(newStack);
setSlotContents(slotNo, newStack, true);
given += qty;
if(given >= stack.stackSize)
break;
}
if(given > 0)
NEICPH.sendGiveItem(copyStack(typestack, given), false, false);
} else
NEICPH.sendGiveItem(stack, infinite, true);
} else {
for (int given = 0; given < stack.stackSize; ) {
int qty = Math.min(stack.stackSize - given, stack.getMaxStackSize());
sendCommand(getStringSetting("command.item"),
mc().thePlayer.getCommandSenderName(),
Item.getIdFromItem(stack.getItem()),
qty,
stack.getItemDamage(),
stack.hasTagCompound() ? stack.getTagCompound().toString() : "",
Item.itemRegistry.getNameForObject(stack.getItem()));
given += qty;
}
}
}
public static boolean canItemFitInInventory(EntityPlayer player, ItemStack itemstack) {
return InventoryUtils.getInsertibleQuantity(new InventoryRange(player.inventory, 0, 36), itemstack) > 0;
}
public static boolean shiftKey() {
return Keyboard.isKeyDown(Keyboard.KEY_LSHIFT) || Keyboard.isKeyDown(Keyboard.KEY_RSHIFT);
}
public static boolean controlKey() {
return Keyboard.isKeyDown(Keyboard.KEY_LCONTROL) || Keyboard.isKeyDown(Keyboard.KEY_RCONTROL);
}
public static int getGamemode() {
if (invCreativeMode())
return 2;
else if (mc().playerController.isInCreativeMode())
return 1;
else if (mc().playerController.currentGameType.isAdventure())
return 3;
else
return 0;
}
public static boolean isValidGamemode(String s) {
return s.equals("survival") ||
canPerformAction(s) &&
Arrays.asList(getStringArrSetting("inventory.gamemodes")).contains(s);
}
public static int getNextGamemode() {
int mode = getGamemode();
int nmode = mode;
while (true) {
nmode = (nmode + 1) % NEIActions.gameModes.length;
if (nmode == mode || isValidGamemode(NEIActions.gameModes[nmode]))
break;
}
return nmode;
}
public static void cycleGamemode() {
int mode = getGamemode();
int nmode = getNextGamemode();
if (mode == nmode)
return;
if (hasSMPCounterPart())
NEICPH.sendGamemode(nmode);
else
sendCommand(getStringSetting("command.creative"), getGameType(nmode), mc().thePlayer.getCommandSenderName());
}
public static long getTime() {
return mc().theWorld.getWorldInfo().getWorldTime();
}
public static void setTime(long l) {
mc().theWorld.getWorldInfo().setWorldTime(l);
}
public static void setHourForward(int hour) {
long day = (getTime() / 24000L) * 24000L;
long newTime = day + 24000L + hour * 1000;
if (hasSMPCounterPart())
NEICPH.sendSetTime(hour);
else
sendCommand(getStringSetting("command.time"), newTime);
}
public static void sendCommand(String command, Object... args) {
if (command.length() == 0)
return;
NumberFormat numberformat = NumberFormat.getIntegerInstance();
numberformat.setGroupingUsed(false);
MessageFormat messageformat = new MessageFormat(command);
for (int i = 0; i < args.length; i++)
if (args[i] instanceof Integer || args[i] instanceof Long)
messageformat.setFormatByArgumentIndex(i, numberformat);
mc().thePlayer.sendChatMessage(messageformat.format(args));
}
public static boolean isRaining() {
return mc().theWorld.getWorldInfo().isRaining();
}
public static void toggleRaining() {
if (hasSMPCounterPart())
NEICPH.sendToggleRain();
else
sendCommand(getStringSetting("command.rain"), isRaining() ? 0 : 1);
}
public static void healPlayer() {
if (hasSMPCounterPart())
NEICPH.sendHeal();
else
sendCommand(getStringSetting("command.heal"), mc().thePlayer.getCommandSenderName());
}
public static void toggleMagnetMode() {
if (hasSMPCounterPart())
NEICPH.sendToggleMagnetMode();
}
public static ArrayList<int[]> concatIntegersToRanges(List<Integer> damages) {
ArrayList<int[]> ranges = new ArrayList<>();
if (damages.size() == 0) return ranges;
Collections.sort(damages);
int start = -1;
int next = 0;
for (Integer i : damages) {
if (start == -1) {
start = next = i;
continue;
}
if (next + 1 != i) {
ranges.add(new int[]{start, next});
start = next = i;
continue;
}
next = i;
}
ranges.add(new int[]{start, next});
return ranges;
}
public static ArrayList<int[]> addIntegersToRanges(List<int[]> ranges, List<Integer> damages) {
for (int[] range : ranges)
for (int integer = range[0]; integer <= range[1]; integer++)
damages.add(integer);
return concatIntegersToRanges(damages);
}
public static boolean safeKeyDown(int keyCode) {
try {
return Keyboard.isKeyDown(keyCode);
} catch (IndexOutOfBoundsException e) {
return false;
}
}
public static void setItemQuantity(int i) {
world.nbt.setInteger("quantity", i);
world.saveNBT();
LayoutManager.quantity.setText(Integer.toString(i));
}
public static GuiContainer getGuiContainer() {
if (mc().currentScreen instanceof GuiContainer)
return (GuiContainer) mc().currentScreen;
return null;
}
public static boolean altKey() {
return Keyboard.isKeyDown(Keyboard.KEY_LMENU) || Keyboard.isKeyDown(Keyboard.KEY_RMENU);
}
public static void playClickSound() {
mc().getSoundHandler().playSound(PositionedSoundRecord.func_147674_a(new ResourceLocation("gui.button.press"), 1.0F));
}
}
@@ -1,5 +0,0 @@
package codechicken.nei;
public class NEICompatibility
{
}
-137
View File
@@ -1,137 +0,0 @@
package codechicken.nei;
import codechicken.core.CommonUtils;
import codechicken.core.launch.CodeChickenCorePlugin;
import codechicken.nei.api.IConfigureNEI;
import codechicken.nei.asm.NEICorePlugin;
import codechicken.nei.config.IMCHandler;
import codechicken.nei.recipe.GuiRecipeTab;
import com.google.common.collect.ArrayListMultimap;
import com.google.common.collect.ImmutableList;
import com.google.common.eventbus.EventBus;
import com.google.common.eventbus.Subscribe;
import cpw.mods.fml.client.FMLFileResourcePack;
import cpw.mods.fml.client.FMLFolderResourcePack;
import cpw.mods.fml.common.DummyModContainer;
import cpw.mods.fml.common.LoadController;
import cpw.mods.fml.common.MetadataCollection;
import cpw.mods.fml.common.ModMetadata;
import cpw.mods.fml.common.event.FMLInitializationEvent;
import cpw.mods.fml.common.event.FMLInterModComms;
import cpw.mods.fml.common.event.FMLPreInitializationEvent;
import cpw.mods.fml.common.event.FMLPostInitializationEvent;
import cpw.mods.fml.common.versioning.ArtifactVersion;
import cpw.mods.fml.common.versioning.VersionParser;
import cpw.mods.fml.common.versioning.VersionRange;
import net.minecraft.util.EnumChatFormatting;
import java.io.File;
import java.lang.reflect.Field;
import java.util.HashSet;
import java.util.LinkedList;
import java.util.List;
import java.util.Set;
public class NEIModContainer extends DummyModContainer
{
public static LinkedList<IConfigureNEI> plugins = new LinkedList<>();
public NEIModContainer() {
super(MetadataCollection.from(MetadataCollection.class.getResourceAsStream("/neimod.info"), "NotEnoughItems").getMetadataForId("NotEnoughItems", null));
loadMetadata();
}
@Override
public Set<ArtifactVersion> getRequirements() {
Set<ArtifactVersion> deps = new HashSet<>();
deps.add(VersionParser.parseVersionReference("CodeChickenCore@["+CodeChickenCorePlugin.version+",)"));
return deps;
}
@Override
public List<ArtifactVersion> getDependencies() {
return new LinkedList<>(getRequirements());
}
private String description;
private void loadMetadata() {
description = super.getMetadata().description.replace("Supporters:", EnumChatFormatting.AQUA+"Supporters:");
}
@Override
public ModMetadata getMetadata() {
StringBuilder s_plugins = new StringBuilder();
if (plugins.size() == 0) {
s_plugins.append(EnumChatFormatting.RED).append("No installed plugins.");
} else {
s_plugins.append(EnumChatFormatting.GREEN).append("Installed plugins: ");
for (int i = 0; i < plugins.size(); i++) {
if (i > 0)
s_plugins.append(", ");
IConfigureNEI plugin = plugins.get(i);
s_plugins.append(plugin.getName()).append(" ").append(plugin.getVersion());
}
s_plugins.append(".");
}
ModMetadata meta = super.getMetadata();
meta.description = description.replace("<plugins>", s_plugins.toString());
return meta;
}
@Override
public boolean registerBus(EventBus bus, LoadController controller) {
bus.register(this);
return true;
}
@Subscribe
public void preInit(FMLPreInitializationEvent event) {
if (CommonUtils.isClient())
ClientHandler.preInit();
}
@Subscribe
public void init(FMLInitializationEvent event) {
if (CommonUtils.isClient())
ClientHandler.load();
ServerHandler.load();
}
@Subscribe
public void postInit(FMLPostInitializationEvent event) {
if (CommonUtils.isClient())
GuiRecipeTab.loadHandlerInfo();
handleIMCMessages();
}
@SuppressWarnings("unchecked")
private void handleIMCMessages() {
try {
/* Pay no attention to these unholy hacks:
* NEI Apparently doesn't have a registered mod container, so let's use some reflection to simulate what `fetchRuntimeMessages` does
*/
Field modMessagesField = FMLInterModComms.class.getDeclaredField("modMessages");
modMessagesField.setAccessible(true);
IMCHandler.processIMC(ImmutableList.copyOf(((ArrayListMultimap<String, FMLInterModComms.IMCMessage>)modMessagesField.get(FMLInterModComms.class)).removeAll("NotEnoughItems")));
} catch (NoSuchFieldException | IllegalAccessException e) {
e.printStackTrace();
}
}
@Override
public VersionRange acceptableMinecraftVersionRange() {
return VersionParser.parseRange(CodeChickenCorePlugin.mcVersion);
}
@Override
public File getSource() {
return NEICorePlugin.location;
}
@Override
public Class<?> getCustomResourcePackClass() {
return getSource().isDirectory() ? FMLFolderResourcePack.class : FMLFileResourcePack.class;
}
}
-411
View File
@@ -1,411 +0,0 @@
package codechicken.nei;
import codechicken.core.CommonUtils;
import codechicken.core.ServerUtils;
import codechicken.lib.inventory.InventoryRange;
import codechicken.lib.inventory.InventoryUtils;
import codechicken.lib.packet.PacketCustom;
import net.minecraft.command.ICommandSender;
import net.minecraft.enchantment.Enchantment;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.entity.player.EntityPlayerMP;
import net.minecraft.entity.player.InventoryPlayer;
import net.minecraft.inventory.Slot;
import net.minecraft.item.Item;
import net.minecraft.item.ItemStack;
import net.minecraft.nbt.CompressedStreamTools;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.nbt.NBTTagList;
import net.minecraft.server.MinecraftServer;
import net.minecraft.util.ChatComponentTranslation;
import net.minecraft.util.EnumChatFormatting;
import net.minecraft.util.IChatComponent;
import net.minecraft.world.World;
import net.minecraft.world.WorldServer;
import net.minecraft.world.WorldSettings.GameType;
import net.minecraftforge.oredict.OreDictionary;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.PrintWriter;
import java.io.StringWriter;
import java.util.AbstractList;
import java.util.ArrayList;
import java.util.List;
import java.util.Set;
import java.util.zip.ZipException;
public class NEIServerUtils
{
public static boolean isRaining(World world) {
return world.getWorldInfo().isRaining();
}
public static void toggleRaining(World world, boolean notify) {
boolean raining = !world.isRaining();
if (!raining)//turn off
((WorldServer) world).provider.resetRainAndThunder();
else
world.getWorldInfo().setRaining(!isRaining(world));
if (notify)
ServerUtils.sendChatToAll(new ChatComponentTranslation("nei.chat.rain." + (raining ? "on" : "off")));
}
public static void healPlayer(EntityPlayer player) {
player.heal(20);
player.getFoodStats().addStats(20, 1);
player.extinguish();
}
public static long getTime(World world) {
return world.getWorldInfo().getWorldTime();
}
public static void setTime(long l, World world) {
world.getWorldInfo().setWorldTime(l);
}
public static void setSlotContents(EntityPlayer player, int slot, ItemStack item, boolean containerInv) {
if (slot == -999)
player.inventory.setItemStack(item);
else if (containerInv)
player.openContainer.putStackInSlot(slot, item);
else
player.inventory.setInventorySlotContents(slot, item);
}
public static ItemStack getSlotContents(EntityPlayer player, int slot, boolean containerInv) {
if (slot == -999)
return player.inventory.getItemStack();
else if (containerInv)
return player.openContainer.getSlot(slot).getStack();
else
return player.inventory.getStackInSlot(slot);
}
@SuppressWarnings("unchecked")
public static void deleteAllItems(EntityPlayerMP player) {
for (Slot slot : (List<Slot>) player.openContainer.inventorySlots)
slot.putStack(null);
player.sendContainerAndContentsToPlayer(player.openContainer, player.openContainer.getInventory());
}
public static void setHourForward(World world, int hour, boolean notify) {
long day = (getTime(world) / 24000L) * 24000L;
long newTime = day + 24000L + hour * 1000;
setTime(newTime, world);
if (notify)
ServerUtils.sendChatToAll(new ChatComponentTranslation("nei.chat.time", getTime(world) / 24000L, hour));
}
public static void advanceDisabledTimes(World world) {
int dim = CommonUtils.getDimension(world);
int hour = (int) (getTime(world) % 24000) / 1000;
int newhour = hour;
while (NEIServerConfig.isActionDisabled(dim, NEIActions.timeZones[newhour / 6]))
newhour = ((newhour / 6 + 1) % 4) * 6;
if (newhour != hour)
setHourForward(world, newhour, false);
}
public static boolean canItemFitInInventory(EntityPlayer player, ItemStack itemstack) {
return InventoryUtils.insertItem(new InventoryRange(player.inventory, 0, 36), itemstack, true) == 0;
}
public static void sendNotice(ICommandSender sender, IChatComponent msg, String permission) {
ChatComponentTranslation notice = new ChatComponentTranslation("chat.type.admin", sender.getCommandSenderName(), msg.createCopy());
notice.getChatStyle().setColor(EnumChatFormatting.GRAY).setItalic(true);
if (NEIServerConfig.canPlayerPerformAction("CONSOLE", permission))
MinecraftServer.getServer().addChatMessage(notice);
for (EntityPlayer p : ServerUtils.getPlayers())
if(p == sender)
p.addChatComponentMessage(msg);
else if (NEIServerConfig.canPlayerPerformAction(p.getCommandSenderName(), permission))
p.addChatComponentMessage(notice);
}
/**
* @param stack1 The {@link ItemStack} being compared.
* @param stack2 The {@link ItemStack} to compare to.
* @return whether the two items are the same in terms of damage and itemID.
*/
public static boolean areStacksSameType(ItemStack stack1, ItemStack stack2) {
return stack1 != null && stack2 != null &&
(stack1.getItem() == stack2.getItem() &&
(!stack2.getHasSubtypes() || stack2.getItemDamage() == stack1.getItemDamage()) &&
ItemStack.areItemStackTagsEqual(stack2, stack1));
}
/**
* {@link ItemStack}s with damage -1 are wildcards allowing all damages. Eg all colours of wool are allowed to create Beds.
*
* @param stack1 The {@link ItemStack} being compared.
* @param stack2 The {@link ItemStack} to compare to.
* @return whether the two items are the same from the perspective of a crafting inventory.
*/
public static boolean areStacksSameTypeCrafting(ItemStack stack1, ItemStack stack2) {
return stack1 != null && stack2 != null &&
stack1.getItem() == stack2.getItem() &&
(stack1.getItemDamage() == stack2.getItemDamage() || stack1.getItemDamage() == OreDictionary.WILDCARD_VALUE || stack2.getItemDamage() == OreDictionary.WILDCARD_VALUE || stack1.getItem().isDamageable());
}
/**
* A simple function for comparing ItemStacks in a compatible with comparators.
*
* @param stack1 The {@link ItemStack} being compared.
* @param stack2 The {@link ItemStack} to compare to.
* @return The ordering of stack1 relative to stack2.
*/
public static int compareStacks(ItemStack stack1, ItemStack stack2) {
if (stack1 == stack2) return 0;//catches both null
if (stack1 == null || stack2 == null) return stack1 == null ? -1 : 1;//null stack goes first
if (stack1.getItem() != stack2.getItem()) return Item.getIdFromItem(stack1.getItem()) - Item.getIdFromItem(stack2.getItem());
if (stack1.stackSize != stack2.stackSize) return stack1.stackSize - stack2.stackSize;
return stack1.getItemDamage() - stack2.getItemDamage();
}
public static boolean areStacksIdentical(ItemStack stack1, ItemStack stack2) {
return compareStacks(stack1, stack2) == 0;
}
public static IChatComponent setColour(IChatComponent msg, EnumChatFormatting colour) {
msg.getChatStyle().setColor(colour);
return msg;
}
public static void givePlayerItem(EntityPlayerMP player, ItemStack stack, boolean infinite, boolean doGive) {
if (stack.getItem() == null) {
player.addChatComponentMessage(setColour(new ChatComponentTranslation("nei.chat.give.noitem"), EnumChatFormatting.WHITE));
return;
}
int given = stack.stackSize;
if(doGive) {
if (infinite)
player.inventory.addItemStackToInventory(stack);
else
given -= InventoryUtils.insertItem(player.inventory, stack, false);
}
sendNotice(player, new ChatComponentTranslation("commands.give.success", stack.func_151000_E(), infinite ? "\u221E" : Integer.toString(given), player.getCommandSenderName()), "notify-item");
player.openContainer.detectAndSendChanges();
}
public static ItemStack copyStack(ItemStack itemstack, int i) {
if (itemstack == null)
return null;
itemstack.stackSize += i;
return itemstack.splitStack(i);
}
public static ItemStack copyStack(ItemStack itemstack) {
if (itemstack == null)
return null;
return copyStack(itemstack, itemstack.stackSize);
}
public static void toggleMagnetMode(EntityPlayerMP player) {
PlayerSave playerSave = NEIServerConfig.forPlayer(player.getCommandSenderName());
playerSave.enableAction("magnet", !playerSave.isActionEnabled("magnet"));
}
public static int getCreativeMode(EntityPlayerMP player) {
if (NEIServerConfig.forPlayer(player.getCommandSenderName()).isActionEnabled("creative+"))
return 2;
else if (player.theItemInWorldManager.isCreative())
return 1;
else if (player.theItemInWorldManager.getGameType().isAdventure())
return 3;
else
return 0;
}
public static GameType getGameType(int mode) {
switch (mode) {
case 0:
return GameType.SURVIVAL;
case 1:
case 2:
return GameType.CREATIVE;
case 3:
return GameType.ADVENTURE;
}
return null;
}
public static void setGamemode(EntityPlayerMP player, int mode) {
if (mode < 0 || mode >= NEIActions.gameModes.length ||
NEIActions.nameActionMap.containsKey(NEIActions.gameModes[mode]) &&
!NEIServerConfig.canPlayerPerformAction(player.getCommandSenderName(), NEIActions.gameModes[mode]))
return;
//creative+
NEIServerConfig.forPlayer(player.getCommandSenderName()).enableAction("creative+", mode == 2);
if(mode == 2 && !(player.openContainer instanceof ContainerCreativeInv))//open the container immediately for the client
NEISPH.processCreativeInv(player, true);
//change it on the server
player.theItemInWorldManager.setGameType(getGameType(mode));
//tell the client to change it
new PacketCustom(NEISPH.channel, 14).writeByte(mode).sendToPlayer(player);
player.addChatMessage(new ChatComponentTranslation("nei.chat.gamemode." + mode));
}
public static void cycleCreativeInv(EntityPlayerMP player, int steps) {
InventoryPlayer inventory = player.inventory;
//top down [row][col]
ItemStack[][] slots = new ItemStack[10][9];
PlayerSave playerSave = NEIServerConfig.forPlayer(player.getCommandSenderName());
//get
System.arraycopy(inventory.mainInventory, 0, slots[9], 0, 9);
for (int row = 0; row < 3; row++)
System.arraycopy(inventory.mainInventory, (row + 1) * 9, slots[row + 6], 0, 9);
for (int row = 0; row < 6; row++)
System.arraycopy(playerSave.creativeInv, row * 9, slots[row], 0, 9);
ItemStack[][] newslots = new ItemStack[10][];
//put back
for (int row = 0; row < 10; row++)
newslots[(row + steps + 10) % 10] = slots[row];
System.arraycopy(newslots[9], 0, inventory.mainInventory, 0, 9);
for (int row = 0; row < 3; row++)
System.arraycopy(newslots[row + 6], 0, inventory.mainInventory, (row + 1) * 9, 9);
for (int row = 0; row < 6; row++)
System.arraycopy(newslots[row], 0, playerSave.creativeInv, row * 9, 9);
playerSave.setDirty();
}
public static List<int[]> getEnchantments(ItemStack itemstack) {
ArrayList<int[]> arraylist = new ArrayList<>();
if (itemstack != null) {
NBTTagList nbttaglist = itemstack.getEnchantmentTagList();
if (nbttaglist != null)
for (int i = 0; i < nbttaglist.tagCount(); i++) {
NBTTagCompound tag = nbttaglist.getCompoundTagAt(i);
arraylist.add(new int[]{tag.getShort("id"), tag.getShort("lvl")});
}
}
return arraylist;
}
public static boolean stackHasEnchantment(ItemStack itemstack, int e) {
List<int[]> allenchantments = getEnchantments(itemstack);
for (int[] ai : allenchantments)
if (ai[0] == e)
return true;
return false;
}
public static int getEnchantmentLevel(ItemStack itemstack, int e) {
List<int[]> allenchantments = getEnchantments(itemstack);
for (int[] ai : allenchantments)
if (ai[0] == e)
return ai[1];
return -1;
}
public static boolean doesEnchantmentConflict(List<int[]> enchantments, Enchantment e) {
for (int[] ai : enchantments)
if (!e.canApplyTogether(Enchantment.enchantmentsList[ai[0]]))
return true;
return false;
}
public static RuntimeException throwCME(String msg) {
if (CommonUtils.isClient())
return ClientHandler.throwCME(msg);
throw new RuntimeException(msg);
}
@SuppressWarnings("unchecked")
public static ItemStack[] extractRecipeItems(Object obj) {
if (obj instanceof ItemStack)
return new ItemStack[]{(ItemStack) obj};
if (obj instanceof ItemStack[])
return (ItemStack[]) obj;
if (obj instanceof List)
return ((List<ItemStack>) obj).toArray(new ItemStack[0]);
throw new ClassCastException(obj+" not an ItemStack, ItemStack[] or List<ItemStack?");
}
public static List<Integer> getRange(final int start, final int end) {
return new AbstractList<Integer>()
{
@Override
public Integer get(int index) {
return start+index;
}
@Override
public int size() {
return end-start;
}
};
}
public static StringBuilder fixTrailingCommaList(StringBuilder sb) {
if(sb.charAt(sb.length()-1) == ',')
sb.deleteCharAt(sb.length()-1);
return sb;
}
public static void logOnce(Throwable t, Set<String> stackTraces, String message) {
logOnce(t, stackTraces, message, "");
}
public static void logOnce(Throwable t, Set<String> stackTraces, String message, String identifier) {
StringWriter sw = new StringWriter();
t.printStackTrace(new PrintWriter(sw));
String stackTrace = identifier + sw.toString();
if (!stackTraces.contains(stackTrace)) {
NEIServerConfig.logger.error(message, t);
stackTraces.add(stackTrace);
}
}
public static NBTTagCompound readNBT(File file) throws IOException {
if(!file.exists()) return null;
FileInputStream in = new FileInputStream(file);
NBTTagCompound tag;
try {
tag = CompressedStreamTools.readCompressed(in);
} catch(ZipException e) {
if(e.getMessage().equals("Not in GZIP format"))
tag = CompressedStreamTools.read(file);
else
throw e;
}
in.close();
return tag;
}
public static void writeNBT(NBTTagCompound tag, File file) throws IOException {
FileOutputStream out = new FileOutputStream(file);
CompressedStreamTools.writeCompressed(tag, out);
out.close();
}
}
-113
View File
@@ -1,113 +0,0 @@
package codechicken.nei;
import net.minecraft.init.Blocks;
import net.minecraft.item.Item;
import net.minecraft.item.ItemStack;
import net.minecraftforge.oredict.OreDictionary;
import java.util.ArrayList;
import java.util.List;
/**
* Simply an {@link ItemStack} with position.
* Mainly used in the recipe handlers.
*/
public class PositionedStack
{
public int relx;
public int rely;
public ItemStack[] items;
//compatibility dummy
public ItemStack item;
private boolean permutated = false;
public PositionedStack(Object object, int x, int y, boolean genPerms) {
items = NEIServerUtils.extractRecipeItems(object);
relx = x;
rely = y;
if(genPerms)
generatePermutations();
else
setPermutationToRender(0);
}
public PositionedStack(Object object, int x, int y)
{
this(object, x, y, true);
}
public void generatePermutations() {
if(permutated)
return;
ArrayList<ItemStack> stacks = new ArrayList<>();
for(ItemStack item : items) {
if(item == null || item.getItem() == null)
continue;
if(item.getItemDamage() == Short.MAX_VALUE) {
List<ItemStack> permutations = ItemList.itemMap.get(item.getItem());
if(!permutations.isEmpty()) {
for(ItemStack stack : permutations)
stacks.add(stack.copy());
}
else {
ItemStack base = new ItemStack(item.getItem(), item.stackSize);
base.stackTagCompound = item.stackTagCompound;
stacks.add(base);
}
continue;
}
stacks.add(item.copy());
}
items = stacks.toArray(new ItemStack[0]);
if(items.length == 0)
items = new ItemStack[]{new ItemStack(Blocks.fire)};
permutated = true;
setPermutationToRender(0);
}
public void setMaxSize(int i) {
for(ItemStack item : items)
if(item.stackSize > i)
item.stackSize = i;
}
public PositionedStack copy() {
return new PositionedStack(items, relx, rely);
}
public void setPermutationToRender(int index) {
item = items[index].copy();
if(item.getItem() == null)
item = new ItemStack(Blocks.fire);
else if(item.getItemDamage() == OreDictionary.WILDCARD_VALUE && item.getItem() != null && item.getItem().isRepairable())
item.setItemDamage(0);
}
public boolean contains(ItemStack ingredient) {
for(ItemStack item : items)
if(NEIServerUtils.areStacksSameTypeCrafting(item, ingredient))
return true;
return false;
}
public boolean contains(Item ingred) {
for(ItemStack item : items)
if(item.getItem() == ingred)
return true;
return false;
}
@Override
public String toString() {
return "PositionedStack(output='" + item.toString() + "')";
}
}
-157
View File
@@ -1,157 +0,0 @@
package codechicken.nei;
import codechicken.lib.gui.GuiDraw;
import codechicken.nei.ItemList.AnyMultiItemFilter;
import codechicken.nei.ItemList.EverythingItemFilter;
import codechicken.nei.ItemList.PatternItemFilter;
import codechicken.nei.api.API;
import codechicken.nei.api.ItemFilter;
import codechicken.nei.api.ItemFilter.ItemFilterProvider;
import net.minecraft.util.EnumChatFormatting;
import java.util.LinkedList;
import java.util.List;
import java.util.regex.Pattern;
import java.util.regex.PatternSyntaxException;
import static codechicken.nei.NEIClientConfig.world;
public class SearchField extends TextField implements ItemFilterProvider
{
/**
* Interface for returning a custom filter based on search field text
*/
public static interface ISearchProvider
{
/**
* @return false if this filter should only be used if no other non-default filters match the search string
*/
public boolean isPrimary();
/**
* @return An item filter for items matching SearchTex null to ignore this provider
*/
public ItemFilter getFilter(String searchText);
}
private static class DefaultSearchProvider implements ISearchProvider
{
@Override
public boolean isPrimary() {
return false;
}
@Override
public ItemFilter getFilter(String searchText) {
Pattern pattern = getPattern(searchText);
return pattern == null ? null : new PatternItemFilter(pattern);
}
}
public static List<ISearchProvider> searchProviders = new LinkedList<>();
long lastclicktime;
public SearchField(String ident) {
super(ident);
API.addItemFilter(this);
API.addSearchProvider(new DefaultSearchProvider());
}
public static boolean searchInventories() {
return world.nbt.getBoolean("searchinventories");
}
@Override
public int getTextColour() {
if(ItemPanels.itemPanel.realItems.size() == 0) {
return focused() ? 0xFFcc3300 : 0xFF993300;
} else {
return focused() ? 0xFFE0E0E0 : 0xFF909090;
}
}
@Override
public void draw(int mousex, int mousey) {
super.draw(mousex, mousey);
if (searchInventories()) {
GuiDraw.drawGradientRect(x - 1, y - 1, 1, h + 2, 0xFFFFFF00, 0xFFC0B000); //Left
GuiDraw.drawGradientRect(x - 1, y - 1, w + 2, 1, 0xFFFFFF00, 0xFFC0B000); //Top
GuiDraw.drawGradientRect(x + w, y - 1, 1, h + 2, 0xFFFFFF00, 0xFFC0B000); //Left
GuiDraw.drawGradientRect(x - 1, y + h, w + 2, 1, 0xFFFFFF00, 0xFFC0B000); //Bottom
}
}
@Override
public boolean handleClick(int mousex, int mousey, int button) {
if (button == 0) {
if (focused() && (System.currentTimeMillis() - lastclicktime < 400)) { //double click
NEIClientConfig.world.nbt.setBoolean("searchinventories", !searchInventories());
NEIClientConfig.world.saveNBT();
}
lastclicktime = System.currentTimeMillis();
}
return super.handleClick(mousex, mousey, button);
}
@Override
public void onTextChange(String oldText) {
final String newText = text();
if( newText.length() > 0)
NEIClientConfig.logger.debug("Searching for " + text());
NEIClientConfig.setSearchExpression(newText);
ItemList.updateFilter.restart();
}
@Override
public void lastKeyTyped(int keyID, char keyChar) {
if (keyID == NEIClientConfig.getKeyBinding("gui.search"))
setFocus(true);
}
@Override
public String filterText(String s) {
return EnumChatFormatting.getTextWithoutFormattingCodes(s);
}
public static Pattern getPattern(String search) {
switch (NEIClientConfig.getIntSetting("inventory.searchmode")) {
case 0://plain
search = "\\Q" + search + "\\E";
break;
case 1:
search = search
.replace(".", "")
.replace("?", ".")
.replace("*", ".+?");
break;
}
Pattern pattern = null;
try {
pattern = Pattern.compile(search);
} catch (PatternSyntaxException ignored) {}
return pattern == null || pattern.toString().length() == 0 ? null : pattern;
}
@Override
public ItemFilter getFilter() {
String s_filter = text().toLowerCase();
List<ItemFilter> primary = new LinkedList<>();
List<ItemFilter> secondary = new LinkedList<>();
for (ISearchProvider p : searchProviders) {
ItemFilter filter = p.getFilter(s_filter);
if (filter != null)
(p.isPrimary() ? primary : secondary).add(filter);
}
if (!primary.isEmpty()) return new AnyMultiItemFilter(primary);
if (!secondary.isEmpty()) return new AnyMultiItemFilter(secondary);
return new EverythingItemFilter();
}
}
-873
View File
@@ -1,873 +0,0 @@
package codechicken.nei;
import codechicken.core.gui.GuiScrollSlot;
import codechicken.lib.gui.GuiDraw;
import codechicken.lib.vec.Rectangle4i;
import codechicken.nei.ItemList.AnyMultiItemFilter;
import codechicken.nei.ItemList.ItemsLoadedCallback;
import codechicken.nei.ItemList.NothingItemFilter;
import codechicken.nei.SearchField.ISearchProvider;
import codechicken.nei.api.API;
import codechicken.nei.api.ItemFilter;
import codechicken.nei.api.ItemFilter.ItemFilterProvider;
import codechicken.nei.api.ItemInfo;
import codechicken.nei.guihook.GuiContainerManager;
import net.minecraft.client.Minecraft;
import net.minecraft.item.ItemStack;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.nbt.NBTTagList;
import net.minecraft.util.EnumChatFormatting;
import java.awt.Point;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.TreeMap;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicReference;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantReadWriteLock;
import java.util.regex.Pattern;
import static codechicken.nei.NEIClientUtils.translate;
public class SubsetWidget extends Button implements ItemFilterProvider, ItemsLoadedCallback, ISearchProvider
{
public static ReentrantReadWriteLock hiddenItemLock = new ReentrantReadWriteLock();
public static Lock writeLock = hiddenItemLock.writeLock();
public static Lock readLock = hiddenItemLock.readLock();
public static class SubsetState
{
int state = 2;
ArrayList<ItemStack> items = new ArrayList<>();
}
public static class SubsetTag
{
protected class SubsetSlot extends GuiScrollSlot
{
public SubsetSlot() {
super(0, 0, 0, 0);
setSmoothScroll(false);
}
@Override
public int getSlotHeight(int slot) {
return 18;
}
@Override
protected int getNumSlots() {
return children.size()+state.items.size();
}
@Override
protected void slotClicked(int slot, int button, int mx, int my, int count) {
if(slot < sorted.size()) {
SubsetTag tag = sorted.get(slot);
if (NEIClientUtils.shiftKey())
codechicken.nei.LayoutManager.searchField.setText("@" + tag.fullname);
else if (button == 0 && count >= 2)
SubsetWidget.showOnly(tag);
else
SubsetWidget.setHidden(tag, button == 1);
} else {
ItemStack item = state.items.get(slot-sorted.size());
if(NEIClientUtils.controlKey())
NEIClientUtils.cheatItem(item, button, -1);
else
SubsetWidget.setHidden(state.items.get(slot-sorted.size()), button == 1);
}
}
@Override
protected void drawSlot(int slot, int x, int y, int mx, int my, float frame) {
int w = windowBounds().width;
Rectangle4i r = new Rectangle4i(x, y, w, getSlotHeight(slot));
if(slot < sorted.size()) {
SubsetTag tag = sorted.get(slot);
codechicken.nei.LayoutManager.getLayoutStyle().drawSubsetTag(tag.displayName(), x, y, r.w, r.h, tag.state.state, r.contains(mx, my));
}
else {
ItemStack stack = state.items.get(slot-sorted.size());
boolean hidden = SubsetWidget.isHidden(stack);
int itemx = w/2-8;
int itemy = 1;
codechicken.nei.LayoutManager.getLayoutStyle().drawSubsetTag(null, x, y, r.w, r.h, hidden ? 0 : 2, false);
GuiContainerManager.drawItem(x+itemx, y+itemy, stack);
if(new Rectangle4i(itemx, itemy, 16, 16).contains(mx, my))
SubsetWidget.hoverStack = stack;
}
}
@Override
public void drawOverlay(float frame) {
}
@Override
public void drawBackground(float frame) {
drawRect(x, y, x+width, y+height, 0xFF202020);
}
@Override
public int scrollbarAlignment() {
return -1;
}
@Override
public void drawScrollbar(float frame) {
if(hasScrollbar())
super.drawScrollbar(frame);
}
@Override
public int scrollbarGuideAlignment() {
return 0;
}
}
public final String fullname;
public final ItemFilter filter;
public TreeMap<String, SubsetTag> children = new TreeMap<>();
public List<SubsetTag> sorted = Collections.emptyList();
private int childwidth;
protected SubsetState state = new SubsetState();
protected final SubsetSlot slot = new SubsetSlot();
private SubsetTag selectedChild;
private int visible;
public SubsetTag(String fullname) {
this(fullname, new NothingItemFilter());
}
public SubsetTag(String fullname, ItemFilter filter) {
assert filter != null : "Filter cannot be null";
this.fullname = EnumChatFormatting.getTextWithoutFormattingCodes(fullname);
this.filter = filter;
}
public String displayName() {
String translated = translate("subsets."+fullname);
if(!translated.startsWith("nei."))
return translated;
int idx = fullname.lastIndexOf('.');
return idx < 0 ? fullname : fullname.substring(idx + 1);
}
public String name() {
int idx = fullname.indexOf('.');
return idx < 0 ? fullname : fullname.substring(idx+1);
}
public String parent() {
int idx = fullname.lastIndexOf('.');
return idx < 0 ? null : fullname.substring(0, idx);
}
private SubsetTag getTag(String name) {
int idx = name.indexOf('.');
String childname = idx > 0 ? name.substring(0, idx) : name;
SubsetTag child = children.get(childname.toLowerCase());
if(child == null)
return null;
return idx > 0 ? child.getTag(name.substring(idx+1)) : child;
}
private void recacheChildren() {
sorted = new ArrayList<>(children.values());
childwidth = 0;
for(SubsetTag tag : sorted)
childwidth = Math.max(childwidth, tag.nameWidth()+2);
}
private void addTag(SubsetTag tag) {
String name = fullname == null ? tag.fullname : tag.fullname.substring(fullname.length()+1);
int idx = name.indexOf('.');
if(idx < 0) {//add or replace tag
SubsetTag prev = children.put(name.toLowerCase(), tag);
if(prev != null) {//replaced, load children
tag.children = prev.children;
tag.sorted = prev.sorted;
}
recacheChildren();
}
else {
String childname = name.substring(0, idx);
SubsetTag child = children.get(childname.toLowerCase());
if(child == null)
children.put(childname.toLowerCase(), child = new SubsetTag(fullname == null ? childname : fullname+'.'+childname));
recacheChildren();
child.addTag(tag);
}
}
protected void cacheState() {
state = SubsetWidget.getState(this);
for(SubsetTag tag : sorted)
tag.cacheState();
}
public void addFiltersWithItem(List<ItemFilter> filters, String itemSearch) {
if(itemSearch == null) {
addFilters(filters);
} else {
if(filter != null)
filters.add(new DoubleFilteredFilter(filter, itemSearch));
for(SubsetTag child : sorted)
child.addFiltersWithItem(filters, itemSearch);
}
}
public void addFilters(List<ItemFilter> filters) {
if(filter != null)
filters.add(filter);
for(SubsetTag child : sorted)
child.addFilters(filters);
}
public void search(List<SubsetTag> tags, Pattern p) {
if(fullname != null && p.matcher(fullname.toLowerCase()).find())
tags.add(this);
else
for(SubsetTag child : sorted)
child.search(tags, p);
}
public void updateVisiblity(int mx, int my) {
if(selectedChild != null) {
selectedChild.updateVisiblity(mx, my);
if(!selectedChild.isVisible())
selectedChild = null;
}
if(slot.contains(mx, my) && (selectedChild == null || !selectedChild.contains(mx, my))) {
int mslot = slot.getClickedSlot(my);
if(mslot >= 0 && mslot < sorted.size()) {
SubsetTag mtag = sorted.get(mslot);
if(mtag != null) {
if(mtag != selectedChild && selectedChild != null)
selectedChild.setHidden();
selectedChild = mtag;
selectedChild.setVisible();
}
}
setVisible();
}
if(selectedChild == null)
countdownVisible();
}
public void setHidden() {
visible = 0;
slot.mouseMovedOrUp(0, 0, 0);//cancel any scrolling
if(selectedChild != null) {
selectedChild.setHidden();
selectedChild = null;
}
}
public void setVisible() {
visible = 10;
cacheState();
}
private void countdownVisible() {
if(visible > 0 && --visible == 0)
setHidden();
}
public void resize(int x, int pwidth, int y) {
int mheight = area.h;
int dheight = area.y2()-y;
int cheight = slot.contentHeight();
int height = cheight;
if(cheight > mheight) {
y = area.y;
height = mheight;
} else if(cheight > dheight) {
y = area.y2() - cheight;
}
height = height/slot.getSlotHeight(0)*slot.getSlotHeight(0);//floor to a multiple of slot height
int width = childwidth;
if(!state.items.isEmpty())
width = Math.max(childwidth, 18);
if(slot.contentHeight() > height)
width+=slot.scrollbarDim().width;
boolean fitLeft = x-width >= area.x1();
boolean fitRight = x+width+pwidth <= area.x2();
if(pwidth >= 0 ? !fitRight && fitLeft : !fitLeft)
pwidth*=-1;//swap
x += pwidth >= 0 ? pwidth : -width;
slot.setSize(x, y, width, height);
slot.setMargins(slot.hasScrollbar() ? slot.scrollbarDim().width : 0, 0, 0, 0);
if(selectedChild != null) {
y = slot.getSlotY(sorted.indexOf(selectedChild))-slot.scrolledPixels()+slot.y;
selectedChild.resize(x, pwidth >= 0 ? width : -width, y);
}
}
protected int nameWidth() {
return Minecraft.getMinecraft().fontRenderer.getStringWidth(displayName());
}
public boolean isVisible() {
return visible > 0;
}
public void draw(int mx, int my) {
slot.draw(mx, my, 0);
if(selectedChild != null)
selectedChild.draw(mx, my);
}
public boolean contains(int px, int py) {
return slot.contains(px, py) ||
selectedChild != null && selectedChild.contains(px, py);
}
public void mouseClicked(int mx, int my, int button) {
if(selectedChild != null && selectedChild.contains(mx, my))
selectedChild.mouseClicked(mx, my, button);
else if(slot.contains(mx, my))
slot.mouseClicked(mx, my, button);
}
public void mouseDragged(int mx, int my, int button, long heldTime) {
slot.mouseDragged(mx, my, button, heldTime);
if(selectedChild != null)
selectedChild.mouseDragged(mx, my, button, heldTime);
}
public void mouseUp(int mx, int my, int button) {
slot.mouseMovedOrUp(mx, my, button);
if(selectedChild != null)
selectedChild.mouseUp(mx, my, button);
}
public boolean mouseScrolled(int mx, int my, int scroll) {
if(slot.hasScrollbar() && slot.contains(mx, my)) {
slot.scroll(scroll);
return true;
}
if(selectedChild != null && selectedChild.mouseScrolled(mx, my, scroll))
return true;
if(slot.hasScrollbar() && !contains(mx, my)) {
slot.scroll(scroll);
return true;
}
return false;
}
public boolean isScrolling() {
return slot.isScrolling() ||
selectedChild != null && selectedChild.isScrolling();
}
}
protected static final SubsetTag root = new SubsetTag(null);
public static Rectangle4i area = new Rectangle4i();
public static ItemStack hoverStack;
private static HashMap<String, SubsetState> subsetState = new HashMap<>();
/**
* All operations on this variable should be synchronised.
*/
private static final ItemStackSet hiddenItems = new ItemStackSet();
private static final AtomicReference<NBTTagList> dirtyHiddenItems = new AtomicReference<>();
public static SubsetState getState(SubsetTag tag) {
SubsetState state = subsetState.get(tag.fullname);
return state == null ? new SubsetState() : state;
}
public static void addTag(SubsetTag tag) {
updateState.stop();
synchronized (root) {
root.addTag(tag);
updateState.reallocate();
}
}
public static SubsetTag getTag(String name) {
return name == null ? root : root.getTag(name);
}
public static boolean isHidden(ItemStack item) {
try {
if(readLock.tryLock(5, TimeUnit.SECONDS)) {
try {
return hiddenItems.contains(item);
} finally {
readLock.unlock();
}
} else {
NEIClientConfig.logger.error("Unable to obtain read lock in 'isHidden'");
}
} catch (InterruptedException e) {
e.printStackTrace();
}
return false;
}
private static void _setHidden(SubsetTag tag, boolean hidden) {
for(ItemStack item : getState(tag).items)
_setHidden(item, hidden);
for(SubsetTag child : tag.sorted)
_setHidden(child, hidden);
}
private static void _setHidden(ItemStack item, boolean hidden) {
if (hiddenItemLock.isWriteLockedByCurrentThread()) {
if (hidden)
hiddenItems.add(item);
else
hiddenItems.remove(item);
}
}
public static void showOnly(SubsetTag tag) {
try {
if(writeLock.tryLock(5, TimeUnit.SECONDS)) {
try {
for (ItemStack item : ItemList.items)
_setHidden(item, true);
setHidden(tag, false);
} finally {
writeLock.unlock();
}
} else {
NEIClientConfig.logger.error("Unable to obtain write lock in 'showOnly'");
}
} catch (InterruptedException e) {
e.printStackTrace();
}
}
public static void setHidden(SubsetTag tag, boolean hidden) {
try {
if(writeLock.tryLock(5, TimeUnit.SECONDS)) {
try {
_setHidden(tag, hidden);
updateHiddenItems();
} finally {
writeLock.unlock();
}
} else {
NEIClientConfig.logger.error("Unable to obtain write lock in 'setHidden'");
}
} catch (InterruptedException e) {
e.printStackTrace();
}
}
public static void setHidden(ItemStack item, boolean hidden) {
try {
if(writeLock.tryLock(5, TimeUnit.SECONDS)) {
try {
_setHidden(item, hidden);
updateHiddenItems();
} finally {
writeLock.unlock();
}
} else {
NEIClientConfig.logger.error("Unable to obtain write lock in 'setHidden'");
}
} catch (InterruptedException e) {
e.printStackTrace();
}
}
public static void unhideAll() {
try {
if(writeLock.tryLock(5, TimeUnit.SECONDS)) {
try {
hiddenItems.clear();
updateHiddenItems();
} finally {
writeLock.unlock();
}
} else {
NEIClientConfig.logger.error("Unable to obtain write lock in 'unhideAll'");
}
} catch (InterruptedException e) {
e.printStackTrace();
}
}
private static void updateHiddenItems() {
prepareDirtyHiddenItems.restart();
updateState.restart();
}
public static void loadHidden() {
try {
if(writeLock.tryLock(5, TimeUnit.SECONDS)) {
try {
hiddenItems.clear();
} finally {
writeLock.unlock();
}
} else {
NEIClientConfig.logger.error("Unable to obtain write lock in 'loadHidden'");
}
} catch (InterruptedException e) {
e.printStackTrace();
return;
}
List<ItemStack> itemList = new LinkedList<>();
try {
NBTTagList list = NEIClientConfig.world.nbt.getTagList("hiddenItems", 10);
for(int i = 0; i < list.tagCount(); i++)
itemList.add(ItemStack.loadItemStackFromNBT(list.getCompoundTagAt(i)));
}
catch (Exception e) {
NEIClientConfig.logger.error("Error loading hiddenItems", e);
return;
}
try {
if(writeLock.tryLock(5, TimeUnit.SECONDS)) {
try {
for (ItemStack item : itemList)
hiddenItems.add(item);
} finally {
writeLock.unlock();
}
} else {
NEIClientConfig.logger.error("Unable to obtain second write lock in 'loadHidden'");
}
} catch (InterruptedException e) {
e.printStackTrace();
}
updateState.restart();
}
private static void saveHidden() {
NBTTagList list = dirtyHiddenItems.getAndSet(null);
if(list != null) {
NEIClientConfig.world.nbt.setTag("hiddenItems", list);
NEIClientConfig.world.saveNBT();
}
}
private static final RestartableTask prepareDirtyHiddenItems = new RestartableTask("NEI Subset Save Thread")
{
private List<ItemStack> getList() {
try {
if(readLock.tryLock(5, TimeUnit.SECONDS)) {
try {
return hiddenItems.values();
} finally {
readLock.unlock();
}
} else {
NEIClientConfig.logger.error("Unable to obtain read lock in 'NEI Subset Save Thread'");
}
} catch (InterruptedException e) {
e.printStackTrace();
}
return new ArrayList<>();
}
@Override
public void execute() {
NBTTagList list = new NBTTagList();
for(ItemStack item : getList()) {
if(interrupted()) return;
NBTTagCompound tag = new NBTTagCompound();
item.writeToNBT(tag);
list.appendTag(tag);
}
dirtyHiddenItems.set(list);
}
};
private static final UpdateStateTask updateState = new UpdateStateTask();
private static class UpdateStateTask extends RestartableTask
{
private volatile boolean reallocate;
public UpdateStateTask() {
super("NEI Subset Item Allocation");
}
@Override
public void clearTasks() {
super.clearTasks();
reallocate = false;
}
public synchronized void reallocate() {
// System.out.println("NEI Subset - Reallocate");
// Thread.dumpStack();
reallocate = true;
restart();
}
@Override
public void execute() {
// System.out.println("Executing NEI Subset Item Allocation");
HashMap<String, SubsetState> state = new HashMap<>();
List<SubsetTag> tags = new LinkedList<>();
synchronized (root) {
cloneStates(root, tags, state);
if(interrupted()) return;
}
if(reallocate) {
for (ItemStack item : ItemList.items) {
if(interrupted()) return;
if(ItemInfo.isHidden(item)) continue;
for (SubsetTag tag : tags)
if (tag.filter.matches(item))
state.get(tag.fullname).items.add(item);
}
}
synchronized (root) {
calculateVisibility(root, state);
if(interrupted()) return;
}
subsetState = state;
ItemList.updateFilter.restart();
}
private void cloneStates(SubsetTag tag, List<SubsetTag> tags, HashMap<String, SubsetState> state) {
for(SubsetTag child : tag.sorted) {
if(interrupted()) return;
cloneStates(child, tags, state);
}
tags.add(tag);
SubsetState sstate = new SubsetState();
if(!reallocate)
sstate.items = SubsetWidget.getState(tag).items;
state.put(tag.fullname, sstate);
}
private void calculateVisibility(SubsetTag tag, Map<String, SubsetState> state) {
SubsetState sstate = state.get(tag.fullname);
int hidden = 0;
for(SubsetTag child : tag.sorted) {
if(interrupted()) return;
calculateVisibility(child, state);
int cstate = state.get(child.fullname).state;
if(cstate == 1)
sstate.state = 1;
else if(cstate == 0)
hidden++;
}
if(sstate.state == 1) return;
List<ItemStack> items = sstate.items;
for(ItemStack item : items) {
if(interrupted()) return;
if (isHidden(item))
hidden++;
}
if(hidden == tag.sorted.size()+items.size())
sstate.state = 0;
else if(hidden > 0)
sstate.state = 1;
}
}
private long lastclicktime;
public SubsetWidget() {
super("NEI Subsets");
API.addItemFilter(this);
API.addSearchProvider(this);
ItemList.loadCallbacks.add(this);
}
@Override
public String getRenderLabel() {
return translate("inventory.item_subsets");
}
@Override
public void draw(int mx, int my) {
super.draw(mx, my);
area.set(x, y + h, w, LayoutManager.searchField.y - h - y); //23 for the search box
hoverStack = null;
if (root.isVisible()) {
root.resize(area.x, 0, area.y);
root.cacheState();
root.draw(mx, my);
}
}
@Override
public void update() {
Point mouse = GuiDraw.getMousePosition();
updateVisiblity(mouse.x, mouse.y);
saveHidden();
}
private void updateVisiblity(int mx, int my) {
if(!root.isVisible() || root.isScrolling())
return;
root.updateVisiblity(mx, my);
if(!root.isVisible() && bounds().contains(mx, my))
root.setVisible();
}
@Override
public boolean contains(int px, int py) {
return super.contains(px, py) ||
root.isVisible() && root.contains(px, py);
}
@Override
public boolean handleClick(int mx, int my, int button) {
if(root.isVisible() && root.contains(mx, my)) {
root.mouseClicked(mx, my, button);
return true;
}
if(button == 0) {
if(System.currentTimeMillis() - lastclicktime < 500)
unhideAll();
else
root.setVisible();
NEIClientUtils.playClickSound();
lastclicktime = System.currentTimeMillis();
}
return true;
}
/**
* Not called
*/
@Override
public boolean onButtonPress(boolean rightclick) {
return false;
}
@Override
public void mouseDragged(int mx, int my, int button, long heldTime) {
if(root.isVisible())
root.mouseDragged(mx, my, button, heldTime);
}
@Override
public void mouseUp(int mx, int my, int button) {
if(root.isVisible())
root.mouseUp(mx, my, button);
}
@Override
public boolean onMouseWheel(int i, int mx, int my) {
return root.isVisible() && root.mouseScrolled(mx, my, -i);
}
@Override
public void onGuiClick(int mx, int my) {
if(!contains(mx, my))
root.setHidden();
}
@Override
public ItemStack getStackMouseOver(int mx, int my) {
return hoverStack;
}
@Override
public ItemFilter getFilter() {
//synchronise access on hiddenItems
return item -> {
try {
if(readLock.tryLock(5, TimeUnit.SECONDS)) {
try {
return !hiddenItems.matches(item);
} finally {
readLock.unlock();
}
} else {
NEIClientConfig.logger.error("Unable to obtain read lock in 'getFilter'");
}
} catch (InterruptedException e) {
e.printStackTrace();
}
return false;
};
}
@Override
public boolean isPrimary() {
return true;
}
@Override
public ItemFilter getFilter(String searchText) {
if(!searchText.startsWith("@"))
return null;
searchText = searchText.substring(1);
String itemSearch = null;
if(searchText.contains("->")) {
String[] split = searchText.split("->");
searchText = split[0];
if(split.length > 1) itemSearch = split[1];
}
AnyMultiItemFilter filter = new AnyMultiItemFilter();
SubsetTag tag = getTag(searchText);
if(tag != null) {
// We've got an exact match
tag.addFiltersWithItem(filter.filters, itemSearch);
}
else {
// Try searching for a substring
Pattern p = SearchField.getPattern(searchText);
if(p == null) return null;
List<SubsetTag> matching = new LinkedList<>();
root.search(matching, p);
if(matching.isEmpty()) return null;
for(SubsetTag tag2 : matching) {
tag2.addFiltersWithItem(filter.filters, itemSearch);
}
}
return filter;
}
@Override
public void itemsLoaded() {
updateState.reallocate();
}
}
-18
View File
@@ -1,18 +0,0 @@
package codechicken.nei;
import java.util.Comparator;
public class WidgetZOrder
implements Comparator<Widget>
{
final boolean topfirst;
public WidgetZOrder(boolean topfirst)
{
this.topfirst = topfirst;
}
public int compare(Widget w1, Widget w2)
{
return w1.z != w2.z ? ((topfirst ? w1.z > w2.z : w1.z < w2.z) ? 1 : -1) : 1;
}
}
@@ -1,222 +0,0 @@
package codechicken.nei;
import codechicken.lib.math.MathHelper;
import codechicken.lib.render.RenderUtils;
import codechicken.nei.KeyManager.IKeyStateTracker;
import net.minecraft.client.Minecraft;
import net.minecraft.entity.Entity;
import net.minecraft.entity.EnumCreatureType;
import net.minecraft.entity.passive.EntityPig;
import net.minecraft.util.AxisAlignedBB;
import net.minecraft.world.EnumSkyBlock;
import net.minecraft.world.SpawnerAnimals;
import net.minecraft.world.World;
import net.minecraft.world.biome.BiomeGenBase;
import net.minecraft.world.chunk.Chunk;
import org.lwjgl.opengl.GL11;
public class WorldOverlayRenderer implements IKeyStateTracker
{
public static int mobOverlay = 0;
public static int chunkOverlay = 0;
public static void reset() {
mobOverlay = 0;
chunkOverlay = 0;
}
@Override
public void tickKeyStates() {
if (Minecraft.getMinecraft().currentScreen != null)
return;
if (KeyManager.keyStates.get("world.moboverlay").down)
mobOverlay = (mobOverlay + 1) % 2;
if (KeyManager.keyStates.get("world.chunkoverlay").down)
chunkOverlay = (chunkOverlay + 1) % 3;
}
public static void render(float frame) {
GL11.glPushMatrix();
Entity entity = Minecraft.getMinecraft().renderViewEntity;
RenderUtils.translateToWorldCoords(entity, frame);
renderChunkBounds(entity);
renderMobSpawnOverlay(entity);
GL11.glPopMatrix();
}
private static void renderMobSpawnOverlay(Entity entity) {
if (mobOverlay == 0)
return;
GL11.glDisable(GL11.GL_TEXTURE_2D);
GL11.glEnable(GL11.GL_BLEND);
GL11.glBlendFunc(GL11.GL_SRC_ALPHA, GL11.GL_ONE_MINUS_SRC_ALPHA);
GL11.glDisable(GL11.GL_LIGHTING);
GL11.glLineWidth(1.5F);
GL11.glBegin(GL11.GL_LINES);
GL11.glColor4f(1, 0, 0, 1);
int curSpawnMode = 2;
World world = entity.worldObj;
int x1 = (int) entity.posX;
int z1 = (int) entity.posZ;
int y1 = (int) MathHelper.clip(entity.posY, 16, world.getHeight() - 16);
for (int x = x1 - 16; x <= x1 + 16; x++)
for (int z = z1 - 16; z <= z1 + 16; z++) {
Chunk chunk = world.getChunkFromBlockCoords(x, z);
BiomeGenBase biome = world.getBiomeGenForCoords(x, z);
if (biome.getSpawnableList(EnumCreatureType.monster).isEmpty() || biome.getSpawningChance() <= 0)
continue;
for (int y = y1 - 16; y < y1 + 16; y++) {
int spawnMode = getSpawnMode(chunk, x, y, z);
if (spawnMode == 0)
continue;
if (spawnMode != curSpawnMode) {
if (spawnMode == 1)
GL11.glColor4f(1, 1, 0, 1);
else
GL11.glColor4f(1, 0, 0, 1);
curSpawnMode = spawnMode;
}
GL11.glVertex3d(x, y + 0.004, z);
GL11.glVertex3d(x + 1, y + 0.004, z + 1);
GL11.glVertex3d(x + 1, y + 0.004, z);
GL11.glVertex3d(x, y + 0.004, z + 1);
}
}
GL11.glEnd();
GL11.glEnable(GL11.GL_LIGHTING);
GL11.glEnable(GL11.GL_TEXTURE_2D);
GL11.glDisable(GL11.GL_BLEND);
}
private static final Entity dummyEntity = new EntityPig(null);
private static final AxisAlignedBB aabb = AxisAlignedBB.getBoundingBox(0, 0, 0, 0, 0, 0);
private static int getSpawnMode(Chunk chunk, int x, int y, int z) {
if (!SpawnerAnimals.canCreatureTypeSpawnAtLocation(EnumCreatureType.monster, chunk.worldObj, x, y, z) ||
chunk.getSavedLightValue(EnumSkyBlock.Block, x & 15, y, z & 15) >= 8)
return 0;
aabb.minX = x + 0.2;
aabb.maxX = x + 0.8;
aabb.minY = y + 0.01;
aabb.maxY = y + 1.8;
aabb.minZ = z + 0.2;
aabb.maxZ = z + 0.8;
if (!chunk.worldObj.checkNoEntityCollision(aabb) ||
!chunk.worldObj.getCollidingBoundingBoxes(dummyEntity, aabb).isEmpty() ||
chunk.worldObj.isAnyLiquid(aabb))
return 0;
if (chunk.getSavedLightValue(EnumSkyBlock.Sky, x & 15, y, z & 15) >= 8)
return 1;
return 2;
}
private static void renderChunkBounds(Entity entity) {
if (chunkOverlay == 0)
return;
GL11.glDisable(GL11.GL_TEXTURE_2D);
GL11.glEnable(GL11.GL_BLEND);
GL11.glBlendFunc(GL11.GL_SRC_ALPHA, GL11.GL_ONE_MINUS_SRC_ALPHA);
GL11.glDisable(GL11.GL_LIGHTING);
GL11.glLineWidth(1.5F);
GL11.glBegin(GL11.GL_LINES);
for (int cx = -4; cx <= 4; cx++)
for (int cz = -4; cz <= 4; cz++) {
double x1 = (entity.chunkCoordX + cx) << 4;
double z1 = (entity.chunkCoordZ + cz) << 4;
double x2 = x1 + 16;
double z2 = z1 + 16;
double dy = 128;
double y1 = Math.floor(entity.posY - dy / 2);
double y2 = y1 + dy;
if (y1 < 0) {
y1 = 0;
y2 = dy;
}
if (y1 > entity.worldObj.getHeight()) {
y2 = entity.worldObj.getHeight();
y1 = y2 - dy;
}
double dist = Math.pow(1.5, -(cx * cx + cz * cz));
GL11.glColor4d(0.9, 0, 0, dist);
if (cx >= 0 && cz >= 0) {
GL11.glVertex3d(x2, y1, z2);
GL11.glVertex3d(x2, y2, z2);
}
if (cx >= 0 && cz <= 0) {
GL11.glVertex3d(x2, y1, z1);
GL11.glVertex3d(x2, y2, z1);
}
if (cx <= 0 && cz >= 0) {
GL11.glVertex3d(x1, y1, z2);
GL11.glVertex3d(x1, y2, z2);
}
if (cx <= 0 && cz <= 0) {
GL11.glVertex3d(x1, y1, z1);
GL11.glVertex3d(x1, y2, z1);
}
if (chunkOverlay == 2 && cx == 0 && cz == 0) {
dy = 32;
y1 = Math.floor(entity.posY - dy / 2);
y2 = y1 + dy;
if (y1 < 0) {
y1 = 0;
y2 = dy;
}
if (y1 > entity.worldObj.getHeight()) {
y2 = entity.worldObj.getHeight();
y1 = y2 - dy;
}
GL11.glColor4d(0, 0.9, 0, 0.4);
for (double y = (int) y1; y <= y2; y++) {
GL11.glVertex3d(x2, y, z1);
GL11.glVertex3d(x2, y, z2);
GL11.glVertex3d(x1, y, z1);
GL11.glVertex3d(x1, y, z2);
GL11.glVertex3d(x1, y, z2);
GL11.glVertex3d(x2, y, z2);
GL11.glVertex3d(x1, y, z1);
GL11.glVertex3d(x2, y, z1);
}
for (double h = 1; h <= 15; h++) {
GL11.glVertex3d(x1 + h, y1, z1);
GL11.glVertex3d(x1 + h, y2, z1);
GL11.glVertex3d(x1 + h, y1, z2);
GL11.glVertex3d(x1 + h, y2, z2);
GL11.glVertex3d(x1, y1, z1 + h);
GL11.glVertex3d(x1, y2, z1 + h);
GL11.glVertex3d(x2, y1, z1 + h);
GL11.glVertex3d(x2, y2, z1 + h);
}
}
}
GL11.glEnd();
GL11.glEnable(GL11.GL_LIGHTING);
GL11.glEnable(GL11.GL_TEXTURE_2D);
GL11.glDisable(GL11.GL_BLEND);
}
public static void load() {
KeyManager.trackers.add(new WorldOverlayRenderer());
}
}
-287
View File
@@ -1,287 +0,0 @@
package codechicken.nei.api;
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;
import codechicken.nei.SearchField;
import codechicken.nei.SearchField.ISearchProvider;
import codechicken.nei.SubsetWidget;
import codechicken.nei.SubsetWidget.SubsetTag;
import codechicken.nei.api.ItemFilter.ItemFilterProvider;
import codechicken.nei.config.Option;
import codechicken.nei.config.OptionKeyBind;
import codechicken.nei.recipe.GuiCraftingRecipe;
import codechicken.nei.recipe.GuiUsageRecipe;
import codechicken.nei.recipe.ICraftingHandler;
import codechicken.nei.recipe.IUsageHandler;
import codechicken.nei.recipe.RecipeInfo;
import net.minecraft.block.Block;
import net.minecraft.client.gui.inventory.GuiContainer;
import net.minecraft.inventory.Slot;
import net.minecraft.item.Item;
import net.minecraft.item.ItemStack;
import org.lwjgl.input.Keyboard;
import java.util.Collections;
import java.util.Comparator;
/**
* This is the main class that handles item property configuration.
* WARNING: DO NOT access this class until the world has been loaded
* These methods should be called from INEIConfig implementors
*/
public class API
{
/**
* Register a new Crafting Recipe handler;
*
* @param handler The handler to register
*/
public static void registerRecipeHandler(ICraftingHandler handler) {
GuiCraftingRecipe.registerRecipeHandler(handler);
}
/**
* Register a new Usage Recipe handler;
*
* @param handler The handler to register
*/
public static void registerUsageHandler(IUsageHandler handler) {
GuiUsageRecipe.registerUsageHandler(handler);
}
/**
* Add a gui to the default overlay renderer with the default position
*
* @param classz The class of your gui
* @param ident The identification string, currently
* {crafting, crafting2x2, smelting, fuel, brewing}
*/
public static void registerGuiOverlay(Class<? extends GuiContainer> classz, String ident) {
registerGuiOverlay(classz, ident, 5, 11);
}
/**
* Add a gui to the default overlay renderer with an offset
*
* @param classz The class of your gui
* @param ident The identification string, currently
* {crafting, crafting2x2, smelting, fuel, brewing}
* @param x x-offset
* @param y y-offset
*/
public static void registerGuiOverlay(Class<? extends GuiContainer> classz, String ident, int x, int y) {
registerGuiOverlay(classz, ident, new OffsetPositioner(x, y));
}
/**
* Add a gui to the default overlay renderer
*
* @param classz The class of your gui
* @param ident The identification string, currently
* {crafting, crafting2x2, smelting, fuel, brewing}
* @param positioner A Stack Repositioner for moving the items to the right place
*/
public static void registerGuiOverlay(Class<? extends GuiContainer> classz, String ident, IStackPositioner positioner) {
RecipeInfo.registerGuiOverlay(classz, ident, positioner);
}
/**
* @param classz The class of your gui
* @param handler The handler to register
* @param ident The recipe identification string
*/
public static void registerGuiOverlayHandler(Class<? extends GuiContainer> classz, IOverlayHandler handler, String ident) {
RecipeInfo.registerOverlayHandler(classz, handler, ident);
}
/**
* Set the offset to be added to items to translate them into recipe coords on the actual gui, default is 5, 11. Primarily RecipeTransferRects
*
* @param classz The class of your gui
* @param x
* @param y
*/
public static void setGuiOffset(Class<? extends GuiContainer> classz, int x, int y) {
RecipeInfo.setGuiOffset(classz, x, y);
}
public static void registerNEIGuiHandler(INEIGuiHandler handler) {
try {
GuiInfo.writeLock.lock();
GuiInfo.guiHandlers.add(handler);
} finally {
GuiInfo.writeLock.unlock();
}
}
/**
* Hide an item from the item panel
* Damage values of OreDictionary.WILDCARD_VALUE and ItemStackMap.WILDCARD_TAG tags function as wildcards for their respective variables
*/
public static void hideItem(ItemStack item) {
ItemInfo.hiddenItems.add(item);
LayoutManager.markItemsDirty();
}
/**
* Add or replace the name normally shown on the item tooltip
*/
public static void setOverrideName(ItemStack item, String name) {
ItemInfo.nameOverrides.put(item, name);
LayoutManager.markItemsDirty();
}
/**
* Adds an item to the item panel. Any items added using this function will override the default search pattern.
* @param item an item with data
*/
public static void addItemListEntry(ItemStack item) {
ItemInfo.itemOverrides.put(item.getItem(), item);
LayoutManager.markItemsDirty();
}
/**
* Sets the item variants to appear in the item panel, overriding the default search pattern for a given item
*/
public static void setItemListEntries(Item item, Iterable<ItemStack> items) {
if(items == null)
items = Collections.emptyList();
ItemInfo.itemOverrides.replaceValues(item, items);
LayoutManager.markItemsDirty();
}
/**
* 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}
*/
public static void addKeyBind(String ident, int defaultKey) {
NEIClientConfig.setDefaultKeyBinding(ident, defaultKey);
KeyManager.keyStates.put(ident, new KeyState());
addOption(new OptionKeyBind(ident));
}
public static void addOption(Option option) {
NEIClientConfig.getOptionList().addOption(option);
}
/**
* Add a new Layout Style for the NEI interface
* @param styleID The Unique ID to be used for storing your style in the config and cycling through avaliable styles
* @param style The style to add.
*/
public static void addLayoutStyle(int styleID, LayoutStyle style) {
LayoutManager.layoutStyles.put(styleID, style);
}
/**
* Registers a new Infinite Item Handler.
* @param handler The handler to be registered.
*/
public static void addInfiniteItemHandler(IInfiniteItemHandler handler) {
ItemInfo.infiniteHandlers.addFirst(handler);
}
/**
* Registers a new Infinite Item Handler.
* @param block The block to handle, null for all.
* @param handler The handler to be registered.
*/
public static void registerHighlightIdentifier(Block block, IHighlightHandler handler) {
ItemInfo.highlightIdentifiers.put(block, handler);
}
/**
* Tells NEI not to perform any Fast Transfer operations on slots of a particular class
* @param slotClass The class of slot to be exempted
*/
public static void addFastTransferExemptSlot(Class<? extends Slot> slotClass) {
ItemInfo.fastTransferExemptions.add(slotClass);
}
/**
* Register a new text handler for the block highlight tooltip with a layout specification (HEADER, BODY or FOOTER).
* @param handler The handler to be registered.
* @param layout A HUDAugmenterRegistry.Layout entry. HEADER is displayed before BODY which is displayed before FOOTER.
*/
public static void registerHighlightHandler(IHighlightHandler handler, ItemInfo.Layout... layout) {
ItemInfo.registerHighlightHandler(handler, layout);
}
/**
* Register a mode handler for overriding NEI recipe/utility/cheat mode settings.
* @param handler The handler to be registered.
*/
public static void registerModeHandler(INEIModeHandler handler) {
NEIInfo.modeHandlers.add(handler);
}
/**
* Register a filter provider for the item panel.
* @param filterProvider The filter provider to be registered.
*/
public static void addItemFilter(ItemFilterProvider filterProvider) {
synchronized (ItemList.itemFilterers) {
ItemList.itemFilterers.add(filterProvider);
}
}
/**
* Adds a new tag to the item subset dropdown.
* @param name The fully qualified name, Eg Blocks.MobSpawners. NOT case sensitive
* @param filter A filter for matching items that fit in this subset
*/
public static void addSubset(String name, ItemFilter filter) {
addSubset(new SubsetTag(name, filter));
}
/**
* Adds a new tag to the item subset dropdown.
* @param name The fully qualified name, Eg Blocks.MobSpawners. NOT case sensitive
* @param items An iterable of itemstacks to be added as a subset
*/
public static void addSubset(String name, Iterable<ItemStack> items) {
ItemStackSet filter = new ItemStackSet();
for(ItemStack item : items)
filter.add(item);
addSubset(new SubsetTag(name, filter));
}
/**
* Adds a new tag to the item subset dropdown.
*/
public static void addSubset(SubsetTag tag) {
SubsetWidget.addTag(tag);
}
/**
* Adds a new search provider to the search field
*/
public static void addSearchProvider(ISearchProvider provider) {
SearchField.searchProviders.add(provider);
}
/**
* Adds a new sorting option to the item panel sort menu
* @param name A unique id for this sort option. Will be used in the config for saving and translated in the options gui. Note that if the translation key name.tip exists, it will be used for a tooltip
*/
public static void addSortOption(String name, Comparator<ItemStack> comparator) {
ItemSorter.add(name, comparator);
}
/**
* Adds an additional item list entry for an item, sorted after the rest of the items are found through the normal process
* @param item The item to add the variant for
* @param variant The stack to appear in the item panel
*/
public static void addItemVariant(Item item, ItemStack variant) {
ItemInfo.itemVariants.put(item, variant);
LayoutManager.markItemsDirty();
}
}
-42
View File
@@ -1,42 +0,0 @@
package codechicken.nei.api;
import codechicken.nei.NEIChestGuiHandler;
import codechicken.nei.NEICreativeGuiHandler;
import codechicken.nei.NEIDummySlotHandler;
import net.minecraft.client.gui.inventory.GuiContainer;
import net.minecraft.client.gui.inventory.GuiContainerCreative;
import java.util.HashSet;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantReadWriteLock;
public class GuiInfo {
public static final LinkedList<INEIGuiHandler> guiHandlers = new LinkedList<>();
public static final HashSet<Class<? extends GuiContainer>> customSlotGuis = new HashSet<>();
public static ReentrantReadWriteLock guiHandlersLock = new ReentrantReadWriteLock();
public static Lock writeLock = guiHandlersLock.writeLock();
public static Lock readLock = guiHandlersLock.readLock();
public static void load() {
API.registerNEIGuiHandler(new NEICreativeGuiHandler());
API.registerNEIGuiHandler(new NEIChestGuiHandler());
API.registerNEIGuiHandler(new NEIDummySlotHandler());
customSlotGuis.add(GuiContainerCreative.class);
}
public static void clearGuiHandlers() {
try {
GuiInfo.writeLock.lock();
guiHandlers.removeIf(ineiGuiHandler -> ineiGuiHandler instanceof GuiContainer);
} finally {
GuiInfo.writeLock.unlock();
}
}
public static boolean hasCustomSlots(GuiContainer gui) {
return customSlotGuis.contains(gui.getClass());
}
}
@@ -1,8 +0,0 @@
package codechicken.nei.api;
import net.minecraft.client.gui.inventory.GuiContainer;
public interface IGuiContainerOverlay
{
public GuiContainer getFirstScreen();
}
@@ -1,43 +0,0 @@
package codechicken.nei.api;
import codechicken.nei.VisiblityData;
import net.minecraft.client.gui.inventory.GuiContainer;
import net.minecraft.item.ItemStack;
import java.util.Collections;
import java.util.List;
/**
* Lets you just override those things you want to
*/
public class INEIGuiAdapter implements INEIGuiHandler
{
@Override
public VisiblityData modifyVisiblity(GuiContainer gui, VisiblityData currentVisibility)
{
return currentVisibility;
}
@Override
public Iterable<Integer> getItemSpawnSlots(GuiContainer gui, ItemStack item) {
return Collections.emptyList();
}
@Override
public List<TaggedInventoryArea> getInventoryAreas(GuiContainer gui)
{
return null;
}
@Override
public boolean handleDragNDrop(GuiContainer gui, int mousex, int mousey, ItemStack draggedStack, int button)
{
return false;
}
@Override
public boolean hideItemPanelSlot(GuiContainer gui, int x, int y, int w, int h)
{
return false;
}
}
@@ -1,49 +0,0 @@
package codechicken.nei.api;
import codechicken.nei.VisiblityData;
import net.minecraft.client.gui.inventory.GuiContainer;
import net.minecraft.item.ItemStack;
import java.util.List;
/**
* If this is implemented on a gui, it will be automatically registered
*/
public interface INEIGuiHandler
{
public VisiblityData modifyVisiblity(GuiContainer gui, VisiblityData currentVisibility);
/**
* NEI will give the specified item to the InventoryRange returned if the player's inventory is full.
* Should not return null, just an empty list
*/
public Iterable<Integer> getItemSpawnSlots(GuiContainer gui, ItemStack item);
/**
* @return A list of TaggedInventoryAreas that will be used with the savestates.
*/
public List<TaggedInventoryArea> getInventoryAreas(GuiContainer gui);
/**
* Handles clicks while an itemstack has been dragged from the item panel. Use this to set configurable slots and the like.
* Changes made to the stackSize of the dragged stack will be kept
* @param gui The current gui instance
* @param mousex The x position of the mouse
* @param mousey The y position of the mouse
* @param draggedStack The stack being dragged from the item panel
* @param button The button presed
* @return True if the drag n drop was handled. False to resume processing through other routes. The held stack will be deleted if draggedStack.stackSize == 0
*/
public boolean handleDragNDrop(GuiContainer gui, int mousex, int mousey, ItemStack draggedStack, int button);
/**
* Used to prevent the item panel from drawing on top of other gui elements.
* This function will also be called with a 1x1 size rectangle on the mouse position for determining if the given coordinate should override item panel functions such as scrolling
* @param x The x coordinate of the rectangle bounding the slot
* @param y The y coordinate of the rectangle bounding the slot
* @param w The w coordinate of the rectangle bounding the slot
* @param h The h coordinate of the rectangle bounding the slot
* @return true if the item panel slot within the specified rectangle should not be rendered.
*/
public boolean hideItemPanelSlot(GuiContainer gui, int x, int y, int w, int h);
}
@@ -1,9 +0,0 @@
package codechicken.nei.api;
import codechicken.nei.recipe.IRecipeHandler;
import net.minecraft.client.gui.inventory.GuiContainer;
public interface IOverlayHandler
{
public void overlayRecipe(GuiContainer firstGui, IRecipeHandler recipe, int recipeIndex, boolean shift);
}
-275
View File
@@ -1,275 +0,0 @@
package codechicken.nei.asm;
import codechicken.lib.asm.ASMBlock;
import codechicken.lib.asm.ASMHelper;
import codechicken.lib.asm.ASMInit;
import codechicken.lib.asm.ASMReader;
import codechicken.lib.asm.ClassHeirachyManager;
import codechicken.lib.asm.InsnListSection;
import codechicken.lib.asm.ModularASMTransformer;
import codechicken.lib.asm.ModularASMTransformer.FieldWriter;
import codechicken.lib.asm.ModularASMTransformer.MethodInjector;
import codechicken.lib.asm.ModularASMTransformer.MethodReplacer;
import codechicken.lib.asm.ModularASMTransformer.MethodTransformer;
import codechicken.lib.asm.ModularASMTransformer.MethodWriter;
import codechicken.lib.asm.ObfMapping;
import cpw.mods.fml.relauncher.FMLLaunchHandler;
import net.minecraft.launchwrapper.IClassTransformer;
import org.objectweb.asm.ClassReader;
import org.objectweb.asm.ClassWriter;
import org.objectweb.asm.Type;
import org.objectweb.asm.tree.ClassNode;
import org.objectweb.asm.tree.FieldInsnNode;
import org.objectweb.asm.tree.InsnList;
import org.objectweb.asm.tree.InsnNode;
import org.objectweb.asm.tree.MethodNode;
import org.objectweb.asm.tree.VarInsnNode;
import java.util.Map;
import static codechicken.lib.asm.InsnComparator.findN;
import static codechicken.lib.asm.InsnComparator.findOnce;
import static codechicken.lib.asm.InsnComparator.getControlFlowLabels;
import static codechicken.lib.asm.InsnComparator.matches;
import static org.objectweb.asm.ClassWriter.COMPUTE_FRAMES;
import static org.objectweb.asm.ClassWriter.COMPUTE_MAXS;
import static org.objectweb.asm.Opcodes.*;
public class NEITransformer implements IClassTransformer
{
static {
ASMInit.init();
}
private final ModularASMTransformer transformer = new ModularASMTransformer();
private final Map<String, ASMBlock> asmblocks = ASMReader.loadResource("/assets/nei/asm/blocks.asm");
public NEITransformer() {
if(FMLLaunchHandler.side().isClient()) {
//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(ACC_PUBLIC,
new ObfMapping("net/minecraft/block/BlockMobSpawner", "func_149689_a", "(Lnet/minecraft/world/World;IIILnet/minecraft/entity/EntityLivingBase;Lnet/minecraft/item/ItemStack;)V"),
asmblocks.get("spawnerPlaced")));
//Make MobSpawnerBaseLogic use getSpawnerWorld when creating new entities
transformer.add(new MethodReplacer(new ObfMapping("net/minecraft/tileentity/MobSpawnerBaseLogic", "func_98281_h", "()Lnet/minecraft/entity/Entity;"),
asmblocks.get("d_spawnerWorld"), asmblocks.get("spawnerWorld")));
}
//Removes trailing seperators from NBTTagList/Compound.toString because OCD
transformer.add(new MethodInjector(new ObfMapping("net/minecraft/nbt/NBTTagCompound", "toString", "()Ljava/lang/String;"),
asmblocks.get("n_commaFix"), asmblocks.get("commaFix"), true));
transformer.add(new MethodInjector(new ObfMapping("net/minecraft/nbt/NBTTagList", "toString", "()Ljava/lang/String;"),
asmblocks.get("n_commaFix"), 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("net/minecraft/inventory/ContainerWorkbench", "func_82846_b", "(Lnet/minecraft/entity/player/EntityPlayer;I)Lnet/minecraft/item/ItemStack;"))
{
@Override
public void transform(MethodNode mv) {
ASMHelper.logger.debug("NEI: Applying workbench fix");
InsnListSection key = findN(mv.instructions, asmblocks.get("n_workbenchFix").list).get(0);
key.insertBefore(asmblocks.get("workbenchFix").rawListCopy());
}
});
//put glint alpha into the buffer correctly for exporting
transformer.add(new MethodReplacer(new ObfMapping("net/minecraft/client/renderer/entity/RenderItem", "func_77018_a", "(IIIII)V"),
asmblocks.get("d_glintAlphaFix"), asmblocks.get("glintAlphaFix")));
String GuiContainer = "net/minecraft/client/gui/inventory/GuiContainer";
//add manager field
transformer.add(new FieldWriter(ACC_PUBLIC, new ObfMapping(GuiContainer, "manager", "Lcodechicken/nei/guihook/GuiContainerManager;")));
//Fill out getManager in GuiContainerManager
transformer.add(new MethodWriter(ACC_PUBLIC | ACC_STATIC,
new ObfMapping("codechicken/nei/guihook/GuiContainerManager", "getManager", "(Lnet/minecraft/client/gui/inventory/GuiContainer;)Lcodechicken/nei/guihook/GuiContainerManager;"),
asmblocks.get("m_getManager")));
//Generate load method
transformer.add(new MethodWriter(ACC_PUBLIC, new ObfMapping(GuiContainer, "func_146280_a", "(Lnet/minecraft/client/Minecraft;II)V"), asmblocks.get("m_setWorldAndResolution")));
//Generate handleKeyboardInput method
transformer.add(new MethodWriter(ACC_PUBLIC, new ObfMapping(GuiContainer, "func_146282_l", "()V"), asmblocks.get("m_handleKeyboardInput")));
//Generate handleKeyboardInput method
transformer.add(new MethodWriter(ACC_PUBLIC, new ObfMapping(GuiContainer, "func_146282_l", "()V"), asmblocks.get("m_handleKeyboardInput")));
//Generate handleKeyboardInput method
transformer.add(new MethodWriter(ACC_PUBLIC, new ObfMapping(GuiContainer, "func_146282_l", "()V"), asmblocks.get("m_handleKeyboardInput")));
//Generate handleMouseInput method
transformer.add(new MethodWriter(ACC_PUBLIC, new ObfMapping(GuiContainer, "func_146274_d", "()V"), asmblocks.get("m_handleMouseInput")));
addProtectedForwarder(
new ObfMapping(GuiContainer, "func_73869_a", "(CI)V"),
new ObfMapping("codechicken/nei/guihook/GuiContainerManager", "callKeyTyped", "(Lnet/minecraft/client/gui/inventory/GuiContainer;CI)V"));
addProtectedForwarder(
new ObfMapping(GuiContainer, "func_146984_a", "(Lnet/minecraft/inventory/Slot;III)V"),
new ObfMapping("codechicken/nei/guihook/DefaultSlotClickHandler", "callHandleMouseClick", "(Lnet/minecraft/client/gui/inventory/GuiContainer;Lnet/minecraft/inventory/Slot;III)V"));
//Inject preDraw at the start of drawScreen
transformer.add(new MethodInjector(new ObfMapping(GuiContainer, "func_73863_a", "(IIF)V"), asmblocks.get("preDraw"), true));
//Inject objectUnderMouse check before drawing slot highlights
transformer.add(new MethodInjector(new ObfMapping(GuiContainer, "func_73863_a", "(IIF)V"), asmblocks.get("n_objectUnderMouse"), asmblocks.get("objectUnderMouse"), false));
//Inject renderObjects after drawGuiContainerForegroundLayer
transformer.add(new MethodInjector(new ObfMapping(GuiContainer, "func_73863_a", "(IIF)V"), asmblocks.get("n_renderObjects"), asmblocks.get("renderObjects"), false));
//Replace default renderToolTip with delegate
transformer.add(new MethodReplacer(new ObfMapping(GuiContainer, "func_73863_a", "(IIF)V"), asmblocks.get("d_renderToolTip"), asmblocks.get("renderTooltips")));
//Replace zLevel = 200 with zLevel = 500 in drawItemStack
transformer.add(new MethodReplacer(new ObfMapping(GuiContainer, "func_146982_a", "(Lnet/minecraft/item/ItemStack;IILjava/lang/String;)V"),
asmblocks.get("d_zLevel"), asmblocks.get("zLevel")));
//Replace default renderItem with delegate and slot overlay/underlay
transformer.add(new MethodReplacer(new ObfMapping(GuiContainer, "func_146977_a", "(Lnet/minecraft/inventory/Slot;)V"), asmblocks.get("d_drawSlot"), asmblocks.get("drawSlot")));
//Inject mouseClicked hook at the start of mouseClicked
transformer.add(new MethodInjector(new ObfMapping(GuiContainer, "func_73864_a", "(III)V"), asmblocks.get("mouseClicked"), true));
//Replace general handleMouseClicked call with delegate
transformer.add(new MethodReplacer(new ObfMapping(GuiContainer, "func_73864_a", "(III)V"), asmblocks.get("d_handleMouseClick"), asmblocks.get("handleMouseClick")));//mouseClicked
transformer.add(new MethodReplacer(new ObfMapping(GuiContainer, "func_146273_a", "(IIIJ)V"), asmblocks.get("d_handleMouseClick"), asmblocks.get("handleMouseClick")));//mouseClickMove
transformer.add(new MethodReplacer(new ObfMapping(GuiContainer, "func_146286_b", "(III)V"), asmblocks.get("d_handleMouseClick"), asmblocks.get("handleMouseClick")));//mouseMovedOrUp
transformer.add(new MethodReplacer(new ObfMapping(GuiContainer, "func_73869_a", "(CI)V"), asmblocks.get("d_handleMouseClick"), asmblocks.get("handleMouseClick")));//keyTyped
transformer.add(new MethodReplacer(new ObfMapping(GuiContainer, "func_146983_a", "(I)Z"), asmblocks.get("d_handleMouseClick"), asmblocks.get("handleMouseClick")));//checkHotbarKeys
//Write delegate for handleMouseClicked
transformer.add(new MethodWriter(ACC_PUBLIC, new ObfMapping(GuiContainer, "managerHandleMouseClick", "(Lnet/minecraft/inventory/Slot;III)V"), asmblocks.get("m_managerHandleMouseClick")));
//Inject mouseDragged hook after super call in mouseDragged
transformer.add(new MethodInjector(new ObfMapping(GuiContainer, "func_146273_a", "(IIIJ)V"), asmblocks.get("n_mouseDragged"), asmblocks.get("mouseDragged"), false));
//Inject overrideMouseUp at the start of mouseMovedOrUp
transformer.add(new MethodInjector(new ObfMapping(GuiContainer, "func_146286_b", "(III)V"), asmblocks.get("overrideMouseUp"), true));
//Inject mouseUp at the end of main elseif chain in mouseMovedOrUp
transformer.add(new MethodTransformer(new ObfMapping(GuiContainer, "func_146286_b", "(III)V"))
{
@Override
public void transform(MethodNode mv) {
ASMHelper.logger.debug("NEI: Injecting mouseUp call");
ASMBlock gotoBlock = asmblocks.get("n_mouseUpGoto");
ASMBlock needleBlock = asmblocks.get("n_mouseUp");
ASMBlock injectionBlock = asmblocks.get("mouseUp");
gotoBlock.mergeLabels(injectionBlock);
findOnce(mv.instructions, gotoBlock.list).replace(gotoBlock.list.list);
InsnListSection needle = findOnce(mv.instructions, needleBlock.list);
injectionBlock.mergeLabels(needleBlock.applyLabels(needle));
needle.insertBefore(injectionBlock.list.list);
}
});
//Replace general handleSlotClick call with delegate
transformer.add(new MethodReplacer(new ObfMapping(GuiContainer, "func_146984_a", "(Lnet/minecraft/inventory/Slot;III)V"),
asmblocks.get("d_handleSlotClick"), asmblocks.get("handleSlotClick")));
//Inject lastKeyTyped at the start of keyTyped
transformer.add(new MethodInjector(new ObfMapping(GuiContainer, "func_73869_a", "(CI)V"), asmblocks.get("lastKeyTyped"), true));
//Inject updateScreen hook after super call
transformer.add(new MethodInjector(new ObfMapping(GuiContainer, "func_73876_c", "()V"), asmblocks.get("n_updateScreen"), asmblocks.get("updateScreen"), false));
//Cancel tab click calls when tabs are obscured
transformer.add(new MethodInjector(new ObfMapping("net/minecraft/client/gui/inventory/GuiContainerCreative", "func_147049_a", "(Lnet/minecraft/creativetab/CreativeTabs;II)Z"),
asmblocks.get("handleTabClick"), true));
//Cancel tab tooltip rendering when tabs are obscured
transformer.add(new MethodInjector(new ObfMapping("net/minecraft/client/gui/inventory/GuiContainerCreative", "func_147052_b", "(Lnet/minecraft/creativetab/CreativeTabs;II)Z"),
asmblocks.get("renderTabTooltip"), true));
String[] buttons = new String[]{"CancelButton", "ConfirmButton", "PowerButton"};
String[] this_fields = new String[]{"field_146146_o", "field_146147_o", "field_146150_o"};
for(int i = 0; i < 3; i++) {
ObfMapping m = new ObfMapping("net/minecraft/client/gui/inventory/GuiBeacon$"+buttons[i], "func_146111_b", "(II)V");
InsnListSection l = asmblocks.get("beaconButtonObscured").list.copy();
FieldInsnNode this_ref = ((FieldInsnNode)l.get(1));
this_ref.owner = m.toClassloading().s_owner;
if(ObfMapping.obfuscated) //missing srg mappings for inner outer reference fields
this_ref.name = ObfMapping.obfMapper.mapFieldName(null, this_fields[i], null);
transformer.add(new MethodInjector(m, l.list, true));
}
}
private void addProtectedForwarder(ObfMapping called, ObfMapping caller) {
InsnList forward1 = new InsnList();
InsnList forward2 = new InsnList();
ObfMapping publicCall = new ObfMapping(called.s_owner, "public_"+called.s_name, called.s_desc);
Type[] args = Type.getArgumentTypes(caller.s_desc);
for(int i = 0; i < args.length; i++) {
forward1.add(new VarInsnNode(args[i].getOpcode(ILOAD), i));
forward2.add(new VarInsnNode(args[i].getOpcode(ILOAD), i));
}
forward1.add(publicCall.toInsn(INVOKEVIRTUAL));
forward2.add(called.toClassloading().toInsn(INVOKEVIRTUAL));
forward1.add(new InsnNode(Type.getReturnType(called.s_desc).getOpcode(IRETURN)));
forward2.add(new InsnNode(Type.getReturnType(called.s_desc).getOpcode(IRETURN)));
transformer.add(new MethodWriter(ACC_PUBLIC|ACC_STATIC, caller, forward1));
transformer.add(new MethodWriter(ACC_PUBLIC, publicCall, forward2));
}
private final ObfMapping c_GuiContainer = new ObfMapping("net/minecraft/client/gui/inventory/GuiContainer").toClassloading();
/**
* Adds super.updateScreen() to non implementing GuiContainer subclasses
*/
public byte[] transformSubclasses(String name, byte[] bytes) {
if (ClassHeirachyManager.classExtends(name, c_GuiContainer.javaClass())) {
ClassNode cnode = ASMHelper.createClassNode(bytes);
ObfMapping methodmap = new ObfMapping(cnode.superName, "func_73876_c", "()V").toClassloading();
InsnListSection supercall = new InsnListSection();
supercall.add(new VarInsnNode(ALOAD, 0));
supercall.add(methodmap.toInsn(INVOKESPECIAL));
boolean changed = false;
for (MethodNode mv : cnode.methods) {
if (methodmap.matches(mv)) {
if (matches(new InsnListSection(mv.instructions), supercall, getControlFlowLabels(mv.instructions)) == null) {
mv.instructions.insert(supercall.list);
ASMHelper.logger.debug("Inserted super call into " + methodmap);
changed = true;
}
}
}
if (changed)
bytes = ASMHelper.createBytes(cnode, COMPUTE_MAXS | COMPUTE_FRAMES);
}
return bytes;
}
@Override
public byte[] transform(String name, String tname, byte[] bytes) {
if (bytes == null) return null;
try {
if (FMLLaunchHandler.side().isClient()) {
if (name.equals("net.minecraftforge.oredict.OreDictionary")) {
ClassReader cr = new ClassReader(bytes);
ClassWriter cw = new ClassWriter(ClassWriter.COMPUTE_FRAMES);
cr.accept(new OreDictionaryVisitor(ASM5, cw), ClassReader.SKIP_DEBUG | ClassReader.SKIP_FRAMES);
bytes = cw.toByteArray();
}
bytes = transformSubclasses(name, bytes);
}
bytes = transformer.transform(name, bytes);
} catch (Exception e) {
throw new RuntimeException(e);
}
return bytes;
}
}
@@ -1,149 +0,0 @@
package codechicken.nei.asm;
import static org.objectweb.asm.Opcodes.*;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.objectweb.asm.ClassVisitor;
import org.objectweb.asm.Label;
import org.objectweb.asm.MethodVisitor;
/**
* Code without this patch
* <pre>
public class OreDictionary {
public static int getOreID(String name) {
Integer val = nameToId.get(name);
if (val == null)
{
idToName.add(name);
val = idToName.size() - 1; //0 indexed
nameToId.put(name, val);
idToStack.add(new ArrayList<ItemStack>());
idToStackUn.add(new UnmodifiableArrayList(idToStack.get(val)));
}
return val;
}
}
</pre>
Code with this patch
<pre>
public class OreDictionary {
private static final Object emptyEntryCreationLock = new Object();
public static int getOreID(String name) {
Integer val = nameToId.get(name);
if (val == null)
{
synchronized (emptyEntryCreationLock) {
if ((val = nameToId.get(name)) != null)
return val;
idToName.add(name);
val = idToName.size() - 1; //0 indexed
nameToId.put(name, val);
idToStack.add(new ArrayList<ItemStack>());
idToStackUn.add(new UnmodifiableArrayList(idToStack.get(val)));
}
}
return val;
}
}
* </pre>
*/
public class OreDictionaryVisitor extends ClassVisitor {
private static final Logger logger = LogManager.getLogger("OreDictionaryVisitor");
private static class GetOreIDVisitor extends MethodVisitor {
Label jumpEnd;
Label catchStart = new Label();
Label exitStart = new Label();
public GetOreIDVisitor(int api, MethodVisitor mv) {
super(api, mv);
}
@Override
public void visitJumpInsn(int opcode, Label label) {
super.visitJumpInsn(opcode, label);
logger.trace("Adding getOreID MONITERENTER");
jumpEnd = label;
mv.visitFieldInsn(GETSTATIC, "net/minecraftforge/oredict/OreDictionary", "emptyEntryCreationLock", "Ljava/lang/Object;");
mv.visitInsn(MONITORENTER);
mv.visitLabel(catchStart);
mv.visitFieldInsn(GETSTATIC, "net/minecraftforge/oredict/OreDictionary", "nameToId", "Ljava/util/Map;");
mv.visitVarInsn(ALOAD, 0);
mv.visitMethodInsn(INVOKEINTERFACE, "java/util/Map", "get", "(Ljava/lang/Object;)Ljava/lang/Object;", true);
mv.visitTypeInsn(CHECKCAST, "java/lang/Integer");
mv.visitVarInsn(ASTORE, 1);
mv.visitVarInsn(ALOAD, 1);
mv.visitJumpInsn(IFNONNULL, exitStart);
}
@Override
public void visitLabel(Label label) {
if (label.equals(jumpEnd)) {
logger.trace("Adding getOreID MONITEREXIT");
// normal exit
mv.visitLabel(exitStart);
mv.visitFieldInsn(GETSTATIC, "net/minecraftforge/oredict/OreDictionary", "emptyEntryCreationLock", "Ljava/lang/Object;");
mv.visitInsn(MONITOREXIT);
// not normal
mv.visitJumpInsn(GOTO, jumpEnd);
Label catchBegin = new Label();
mv.visitLabel(catchBegin);
mv.visitFieldInsn(GETSTATIC, "net/minecraftforge/oredict/OreDictionary", "emptyEntryCreationLock", "Ljava/lang/Object;");
mv.visitInsn(MONITOREXIT);
mv.visitInsn(ATHROW);
// try-catch block metadata
mv.visitTryCatchBlock(catchStart, catchBegin, catchBegin, null);
}
super.visitLabel(label);
}
@Override
public void visitEnd() {
super.visitEnd();
}
}
private static class ClassInitializerVisitor extends MethodVisitor{
public ClassInitializerVisitor(int api, MethodVisitor mv) {
super(api, mv);
}
@Override
public void visitCode() {
super.visitCode();
logger.trace("Adding emptyEntryCreationLock initializer");
mv.visitTypeInsn(NEW, "java/lang/Object");
mv.visitInsn(DUP);
mv.visitMethodInsn(INVOKESPECIAL, "java/lang/Object", "<init>", "()V", false);
mv.visitFieldInsn(PUTSTATIC, "net/minecraftforge/oredict/OreDictionary","emptyEntryCreationLock", "Ljava/lang/Object;");
}
@Override
public void visitEnd() {
super.visitEnd();
}
}
public OreDictionaryVisitor(int api, ClassVisitor cv) {
super(api, cv);
}
@Override
public void visitEnd() {
logger.debug("Adding emptyEntryCreationLock");
cv.visitField(ACC_PRIVATE | ACC_STATIC | ACC_FINAL, "emptyEntryCreationLock", "Ljava/lang/Object;", null, null);
super.visitEnd();
}
@Override
public MethodVisitor visitMethod(int access, String name, String desc, String signature, String[] exceptions) {
if (name.equals("getOreID") && desc.equals("(Ljava/lang/String;)I")) {
logger.debug("Patching getOreID");
return new GetOreIDVisitor(api, super.visitMethod(access, name, desc, signature, exceptions));
} else if (name.equals("<clinit>")) {
// some classes don't have clinit. not this one.
logger.debug("Patching clinit");
return new ClassInitializerVisitor(api, super.visitMethod(access, name, desc, signature, exceptions));
}
return super.visitMethod(access, name, desc, signature, exceptions);
}
}
@@ -1,87 +0,0 @@
package codechicken.nei.config;
import codechicken.nei.NEIClientConfig;
import codechicken.nei.recipe.GuiRecipeTab;
import codechicken.nei.recipe.HandlerInfo;
import cpw.mods.fml.common.FMLLog;
import cpw.mods.fml.common.Loader;
import cpw.mods.fml.common.event.FMLInterModComms;
import net.minecraft.nbt.NBTTagCompound;
import java.util.List;
public class IMCHandler {
private IMCHandler() {}
public static void processIMC(List<FMLInterModComms.IMCMessage> messages) {
for (FMLInterModComms.IMCMessage message : messages) {
String type = message.key;
if (type == null || type.isEmpty()) continue;
if(type.equals("registerHandlerInfo")) {
if (!message.isNBTMessage()) {
logInvalidMessage(message, "NBT");
continue;
}
final NBTTagCompound tag = message.getNBTValue();
final String handler = tag.getString("handler");
NEIClientConfig.logger.info("Processing registerHandlerInfo `" + handler + "` from " + message.getSender());
final String modName = tag.getString("modName");
final String modId = tag.getString("modId");
final boolean requiresMod = tag.getBoolean("modRequired");
final String excludedModId = tag.hasKey("excludedModId") ? tag.getString("excludedModId") : null;
if(handler.equals("") || modName.equals("") || modId.equals("")) {
NEIClientConfig.logger.warn("Missing relevant information to registerHandlerInfo!");
continue;
}
if (requiresMod && !Loader.isModLoaded(modId)) continue;
if (excludedModId != null && Loader.isModLoaded(excludedModId)) continue;
HandlerInfo info = new HandlerInfo(handler, modName, modId, requiresMod, excludedModId);
final String imageResource = tag.hasKey("imageResource") ? tag.getString("imageResource") : null;
if(imageResource != null && !imageResource.equals("")) {
info.setImage(imageResource, tag.getInteger("imageX"), tag.getInteger("imageY"), tag.getInteger("imageWidth"), tag.getInteger("imageHeight"));
}
if(!info.hasImageOrItem()) {
final String itemName = tag.getString("itemName");
if (itemName != null && !itemName.equals("")) {
info.setItem(itemName, tag.hasKey("nbtInfo") ? tag.getString("nbtInfo") : null);
}
}
final int yShift = tag.hasKey("yShift") ? tag.getInteger("yShift") : 0;
info.setYShift(yShift);
try {
final int imageHeight = tag.hasKey("handlerHeight") ? tag.getInteger("handlerHeight") : HandlerInfo.DEFAULT_HEIGHT;
final int imageWidth = tag.hasKey("handlerWidth") ? tag.getInteger("handlerWidth") : HandlerInfo.DEFAULT_WIDTH;
final int maxRecipesPerPage = tag.hasKey("maxRecipesPerPage") ? tag.getInteger("maxRecipesPerPage") : HandlerInfo.DEFAULT_MAX_PER_PAGE;
info.setHandlerDimensions(imageHeight, imageWidth, maxRecipesPerPage);
} catch (NumberFormatException ignored) {
NEIClientConfig.logger.info("Error setting handler dimensions for " + handler);
}
GuiRecipeTab.handlerMap.remove(handler);
GuiRecipeTab.handlerMap.put(handler, info);
} else if(type.equals("removeHandlerInfo")) {
if (!message.isNBTMessage()) {
logInvalidMessage(message, "NBT");
continue;
}
final NBTTagCompound tag = message.getNBTValue();
final String handler = tag.getString("handler");
NEIClientConfig.logger.info("Processing removeHandlerInfo `" + handler + "` from " + message.getSender());
GuiRecipeTab.handlerMap.remove(handler);
}
}
}
private static void logInvalidMessage(FMLInterModComms.IMCMessage message, String type) {
FMLLog.bigWarning(String.format("Received invalid IMC '%s' from %s. Not a %s Message.", message.key, message.getSender(), type));
}
}
@@ -1,150 +0,0 @@
package codechicken.nei.config;
import codechicken.lib.inventory.InventoryUtils;
import codechicken.lib.vec.Rectangle4i;
import codechicken.nei.ItemPanels;
import codechicken.nei.NEIClientUtils;
import codechicken.nei.guihook.GuiContainerManager;
import net.minecraft.client.Minecraft;
import net.minecraft.item.Item;
import net.minecraft.item.ItemStack;
import net.minecraft.nbt.CompressedStreamTools;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.nbt.NBTTagList;
import net.minecraft.util.ChatComponentTranslation;
import net.minecraft.util.EnumChatFormatting;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.LinkedList;
public class ItemPanelDumper extends DataDumper
{
private static final int[] resolutions = new int[]{16, 32, 48, 64, 128, 256};
public ItemPanelDumper(String name) {
super(name);
}
@Override
public String[] header() {
return new String[]{"Item Name", "Item ID", "Item meta", "Has NBT", "Display Name"};
}
@Override
public Iterable<String[]> dump(int mode) {
LinkedList<String[]> list = new LinkedList<>();
for (ItemStack stack : ItemPanels.itemPanel.realItems)
list.add(new String[]{
Item.itemRegistry.getNameForObject(stack.getItem()),
Integer.toString(Item.getIdFromItem(stack.getItem())),
Integer.toString(InventoryUtils.actualDamage(stack)),
stack.stackTagCompound == null ? "false" : "true",
EnumChatFormatting.getTextWithoutFormattingCodes(GuiContainerManager.itemDisplayNameShort(stack))
});
return list;
}
@Override
public String renderName() {
return translateN(name);
}
public int getRes() {
int i = renderTag(name+".res").getIntValue(0);
if(i >= resolutions.length || i < 0) renderTag().setIntValue(i = 0);
return resolutions[i];
}
public Rectangle4i resButtonSize() {
int width = 50;
return new Rectangle4i(modeButtonSize().x - width - 6, 0, width, 20);
}
@Override
public void draw(int mousex, int mousey, float frame) {
super.draw(mousex, mousey, frame);
if(getMode() == 3) {
int res = getRes();
drawButton(mousex, mousey, resButtonSize(), res+"x"+res);
}
}
@Override
public void mouseClicked(int mousex, int mousey, int button) {
if(getMode() == 3 && resButtonSize().contains(mousex, mousey)) {
NEIClientUtils.playClickSound();
getTag(name+".res").setIntValue((renderTag(name+".res").getIntValue(0) + 1) % resolutions.length);
}
else
super.mouseClicked(mousex, mousey, button);
}
@Override
public String getFileExtension() {
switch(getMode()) {
case 0: return ".csv";
case 1: return ".nbt";
case 2: return ".json";
}
return null;
}
@Override
public ChatComponentTranslation dumpMessage(File file) {
return new ChatComponentTranslation(namespaced(name + ".dumped"), "dumps/" + file.getName());
}
@Override
public String modeButtonText() {
return translateN(name + ".mode." + getMode());
}
@Override
public void dumpFile() {
if(getMode() == 3)
Minecraft.getMinecraft().displayGuiScreen(new GuiItemIconDumper(this, getRes()));
else
super.dumpFile();
}
@Override
public void dumpTo(File file) throws IOException {
if (getMode() == 0)
super.dumpTo(file);
else if (getMode() == 1)
dumpNBT(file);
else
dumpJson(file);
}
public void dumpNBT(File file) throws IOException {
NBTTagList list = new NBTTagList();
for (ItemStack stack : ItemPanels.itemPanel.realItems)
list.appendTag(stack.writeToNBT(new NBTTagCompound()));
NBTTagCompound tag = new NBTTagCompound();
tag.setTag("list", list);
CompressedStreamTools.writeCompressed(tag, new FileOutputStream(file));
}
public void dumpJson(File file) throws IOException {
PrintWriter p = new PrintWriter(file);
for (ItemStack stack : ItemPanels.itemPanel.realItems) {
NBTTagCompound tag = stack.writeToNBT(new NBTTagCompound());
tag.removeTag("Count");
p.println(tag);
}
p.close();
}
@Override
public int modeCount() {
return 4;
}
}
-227
View File
@@ -1,227 +0,0 @@
package codechicken.nei.config;
import codechicken.lib.config.ConfigTag;
import codechicken.nei.config.GuiOptionList.OptionScrollSlot;
import net.minecraft.client.Minecraft;
import net.minecraft.client.audio.PositionedSoundRecord;
import net.minecraft.util.ResourceLocation;
import net.minecraft.util.StatCollector;
import java.util.List;
public abstract class Option
{
public static void playClickSound() {
Minecraft.getMinecraft().getSoundHandler().playSound(PositionedSoundRecord.func_147674_a(new ResourceLocation("gui.button.press"), 1.0F));
}
public OptionScrollSlot slot;
public String namespace = null;
public final String name;
public OptionList parent;
public Option(String name) {
this.name = name;
}
public String fullName() {
return namespaced(name);
}
public String configName() {
return fullName().substring(configBase().fullName().length() + 1);
}
public String namespaced(String name) {
return namespace == null ? name : (namespace + "." + name);
}
public String translateN(String s, Object... args) {
return StatCollector.translateToLocalFormatted(namespaced(s), args);
}
public int getHeight() {
return 20;
}
private <T> T assertParentOverride(T elem) {
if(elem == null) throw new IllegalStateException("Option "+fullName()+" does not have a defined parent list. Use OptionList.setOptionList to insert a parent");
return elem;
}
public ConfigSet globalConfigSet() {
return assertParentOverride(parent.globalConfigSet());
}
public ConfigSet worldConfigSet() {
return assertParentOverride(parent.worldConfigSet());
}
public OptionList configBase() {
return assertParentOverride(parent.configBase());
}
/**
* @return true if the world config contains a tag with this name
*/
public boolean worldSpecific() {
return worldSpecific(configName());
}
/**
* @return true if the world config contains a tag with this name
*/
public boolean worldSpecific(String s) {
ConfigTag tag = worldConfigSet().config.getTag(s, false);
return tag != null && tag.value != null;
}
/**
* @return The currently config set for the gui based on the world/global button
*/
public ConfigSet configSet() {
return worldConfig() ? worldConfigSet() : globalConfigSet();
}
/**
* @return The tag to render, world if world override, otherwise global
*/
public ConfigTag renderTag() {
return renderTag(configName());
}
/**
* @return The tag to render, world if world override, otherwise global
*/
public ConfigTag renderTag(String s) {
return (worldConfig() && worldSpecific(s) ? worldConfigSet() : globalConfigSet()).config.getTag(s);
}
/**
* @return The tag with this name from the current configSet
*/
public ConfigTag getTag() {
return getTag(configName());
}
/**
* @return The tag with this name from the current configSet
*/
public ConfigTag getTag(String s) {
return configSet().config.getTag(s);
}
/**
* @return The tag currently being used ingame, world if a world override exists, otherwise global
*/
public ConfigTag activeTag() {
return activeTag(configName());
}
/**
* @return The tag currently being used ingame, world if a world override exists, otherwise global
*/
public ConfigTag activeTag(String s) {
return (worldSpecific() ? worldConfigSet() : globalConfigSet()).config.getTag(s);
}
/**
* @return true if the gui is in world config mode
*/
public boolean worldConfig() {
return slot.getGui().worldConfig();
}
/**
* @return true if in world mode, but this tag has no world override. Changes should not be made in this mode
*/
public boolean defaulting() {
return defaulting(configName());
}
/**
* @return true if in world mode, but this tag has no world override. Changes should not be made in this mode
*/
public boolean defaulting(String s) {
return worldConfig() && !worldSpecific(s);
}
/**
* Called when world specific is disabled for this option. Should delete all world specific overrides
*/
public void useGlobals() {
useGlobal(configName());
}
/**
* Deletes a specific named tag from the worldConfig
*/
public void useGlobal(String s) {
if (worldConfig())
worldConfigSet().config.removeTag(s);
}
/**
* Called when world specific is activated for this option. Should copy the global value into a world specific override
*/
public void copyGlobals() {
copyGlobal(configName(), true);
}
/**
* Copies the global value into a world specific override
*/
public void copyGlobal(String s) {
copyGlobal(s, false);
}
public void copyGlobal(String s, boolean recursive) {
if (!worldConfig())
return;
ConfigTag tag = globalConfigSet().config.getTag(s);
worldConfigSet().config.getTag(s).setValue(tag.getValue());
if(recursive)
for(String s2 : tag.childTagMap().keySet())
copyGlobal(s+"."+s2);
}
public void onAdded(OptionScrollSlot slot) {
this.slot = slot;
}
public void onAdded(OptionList list) {
parent = list;
}
/**
* Mouse coordinates are relative to screen
*/
public void onMouseClicked(int mx, int my, int button) {
}
public void mouseClicked(int mx, int my, int button) {
}
public void update() {
}
public void draw(int mx, int my, float frame) {
}
public void keyTyped(char c, int keycode) {
}
public List<String> handleTooltip(int mx, int my, List<String> currenttip) {
return currenttip;
}
public boolean showWorldSelector() {
return true;
}
public boolean hasWorldOverride() {
return worldSpecific();
}
}
@@ -1,27 +0,0 @@
package codechicken.nei.config;
import codechicken.nei.Image;
import codechicken.nei.LayoutManager;
public class OptionGamemodes extends OptionStringSet
{
public OptionGamemodes(String name)
{
super(name);
options.add("creative");
options.add("creative+");
options.add("adventure");
}
@Override
public void drawIcons()
{
int x = buttonX();
LayoutManager.drawIcon(x+4, 4, new Image(132, 12, 12, 12));
x+=24;
LayoutManager.drawIcon(x+4, 4, new Image(156, 12, 12, 12));
x+=24;
LayoutManager.drawIcon(x+4, 4, new Image(168, 12, 12, 12));
}
}
@@ -1,39 +0,0 @@
package codechicken.nei.config;
public class OptionIntegerField extends OptionTextField
{
public final int min;
public final int max;
public OptionIntegerField(String name, int min, int max) {
super(name);
this.min = min;
this.max = max;
}
public OptionIntegerField(String name) {
this(name, Integer.MIN_VALUE, Integer.MAX_VALUE);
}
@Override
public boolean isValidInput(String s) {
if(s.length() == 0)
return true;
try {
Integer.parseInt(s);
return true;
}
catch (NumberFormatException nfe) {
return false;
}
}
@Override
public boolean isValidValue(String s) {
if(s.length() == 0 || !isValidInput(s))
return false;
int i = Integer.parseInt(s);
return i >= min && i <= max;
}
}
@@ -1,79 +0,0 @@
package codechicken.nei.config;
import net.minecraft.util.EnumChatFormatting;
import org.lwjgl.input.Keyboard;
public class OptionKeyBind extends OptionButton
{
private boolean hasFocus = false;
public OptionKeyBind(String name) {
super("keys." + name);
}
@Override
public void onMouseClicked(int mousex, int mousey, int button) {
hasFocus = false;
}
@Override
public void keyTyped(char c, int keycode) {
if (hasFocus) {
setValue(keycode);
hasFocus = false;
}
}
@Override
public boolean onClick(int button) {
if (button == 0) {
hasFocus = true;
return true;
}
if (button == 1 && getValue() != 0) {
setValue(0);
return true;
}
return false;
}
public boolean conflicted() {
if (getValue() == 0)
return false;
for (Option o : slot.options)
if (o instanceof OptionKeyBind && o != this && ((OptionKeyBind) o).getValue() == getValue())
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 String getButtonText() {
if (hasFocus)
return EnumChatFormatting.WHITE + "> " + EnumChatFormatting.YELLOW + "??? " + EnumChatFormatting.WHITE + "<";
if (conflicted())
return EnumChatFormatting.RED + Keyboard.getKeyName(getValue());
return Keyboard.getKeyName(getValue());
}
@Override
public int getTextColour(int mousex, int mousey) {
return -1;
}
}
@@ -1,101 +0,0 @@
package codechicken.nei.config;
import codechicken.lib.vec.Rectangle4i;
import codechicken.nei.TextField;
import codechicken.nei.config.GuiOptionList.OptionScrollSlot;
import java.util.List;
import static codechicken.lib.gui.GuiDraw.drawString;
import static codechicken.lib.gui.GuiDraw.getStringWidth;
public class OptionTextField extends Option
{
private boolean focused = false;
private TextField textField = new TextField("test")
{
@Override
public void onTextChange(String oldText) {
if(focused() && isValidValue(text()))
if(!defaulting() || !text().equals(getTag().getValue())) //don't override global if text hasn't changed
getTag().setValue(text());
}
@Override
public boolean focused() {
return focused;
}
@Override
public void setFocus(boolean focus) {
if (!focus && !isValidValue(text()))
setText(renderTag().getValue());
focused = focus;
}
};
public OptionTextField(String name) {
super(name);
textField.h = 20;
}
@Override
public void onAdded(OptionScrollSlot slot) {
super.onAdded(slot);
}
@Override
public void update() {
textField.update();
if(!textField.focused())
textField.setText(renderTag().getValue());
}
public String getPrefix() {
return translateN(name);
}
@Override
public void draw(int mousex, int mousey, float frame) {
drawString(getPrefix(), 10, 6, -1);
textField.w = slot.slotWidth() - getStringWidth(getPrefix()) - 16;
textField.x = slot.slotWidth() - textField.w;
textField.draw(mousex, mousey);
}
@Override
public void keyTyped(char c, int keycode) {
textField.handleKeyPress(keycode, c);
}
@Override
public void mouseClicked(int mousex, int mousey, int button) {
if (textField.contains(mousex, mousey))
textField.handleClick(mousex, mousey, button);
}
@Override
public void onMouseClicked(int mousex, int mousey, int button) {
textField.onGuiClick(mousex, mousey);
}
@Override
public List<String> handleTooltip(int mousex, int mousey, List<String> currenttip) {
if (new Rectangle4i(10, 0, textField.x - 10, 20).contains(mousex, mousey)) {
String tip = translateN(name + ".tip");
if (!tip.equals(name + ".tip"))
currenttip.add(tip);
}
return currenttip;
}
public boolean isValidInput(String s) {
return true;
}
public boolean isValidValue(String s) {
return true;
}
}
@@ -1,56 +0,0 @@
package codechicken.nei.drawable;
import codechicken.nei.Image;
import net.minecraft.client.Minecraft;
import net.minecraft.client.gui.Gui;
import net.minecraft.util.ResourceLocation;
public class DrawableResource extends Image {
private final ResourceLocation resourceLocation;
private final int textureWidth;
private final int textureHeight;
private final int paddingTop;
private final int paddingBottom;
private final int paddingLeft;
private final int paddingRight;
public DrawableResource(ResourceLocation resourceLocation, int u, int v, int width, int height, int paddingTop, int paddingBottom, int paddingLeft, int paddingRight, int textureWidth, int textureHeight) {
super(u, v, width, height);
this.resourceLocation = resourceLocation;
this.textureWidth = textureWidth;
this.textureHeight = textureHeight;
this.paddingTop = paddingTop;
this.paddingBottom = paddingBottom;
this.paddingLeft = paddingLeft;
this.paddingRight = paddingRight;
}
public int getWidth() {
return width + paddingLeft + paddingRight;
}
public int getHeight() {
return height + paddingTop + paddingBottom;
}
public void draw(int xOffset, int yOffset) {
draw(xOffset, yOffset, 0, 0, 0, 0);
}
public void draw(int xOffset, int yOffset, int maskTop, int maskBottom, int maskLeft, int maskRight) {
Minecraft.getMinecraft().getTextureManager().bindTexture(this.resourceLocation);
final int x = xOffset + this.paddingLeft + maskLeft;
final int y = yOffset + this.paddingTop + maskTop;
final int textureX = this.x + maskLeft;
final int textureY = this.y + maskTop;
final int width = this.width - maskRight - maskLeft;
final int height = this.height - maskBottom - maskTop;
// drawModalRectWithCustomSizedTexture
Gui.func_146110_a(x, y, textureX, textureY, width, height, textureWidth, textureHeight);
}
}
@@ -1,27 +0,0 @@
package codechicken.nei.event;
import codechicken.nei.NEIClientConfig;
import codechicken.nei.recipe.GuiRecipeTab;
import codechicken.nei.recipe.HandlerInfo;
import codechicken.nei.recipe.IRecipeHandler;
import cpw.mods.fml.common.eventhandler.Event;
import net.minecraftforge.common.MinecraftForge;
/**
* Event is posted every time the handler infos got registered or reloaded.
* During it, you can safely register your custom handler info.
*
* <br>
* This event does not have a result. {@link HasResult}<br>
* <br>
* This event is fired on the {@link MinecraftForge#EVENT_BUS}.
*/
public class RegisterHandlerInfosEvent extends Event {
public void registerHandlerInfo(Class<? extends IRecipeHandler> handlerClazz, HandlerInfo info) {
if (GuiRecipeTab.handlerMap.put(handlerClazz.getName(), info) != null) {
NEIClientConfig.logger.info("Replaced handler info for {}", handlerClazz.getName());
} else {
NEIClientConfig.logger.info("Added handler info for {}", handlerClazz.getName());
}
}
}
@@ -1,529 +0,0 @@
package codechicken.nei.guihook;
import codechicken.lib.gui.GuiDraw;
import net.minecraft.client.Minecraft;
import net.minecraft.client.gui.FontRenderer;
import net.minecraft.client.gui.GuiScreen;
import net.minecraft.client.gui.inventory.GuiContainer;
import net.minecraft.client.renderer.Tessellator;
import net.minecraft.client.renderer.entity.RenderItem;
import net.minecraft.init.Blocks;
import net.minecraft.inventory.Slot;
import net.minecraft.item.ItemStack;
import net.minecraft.util.EnumChatFormatting;
import org.lwjgl.input.Keyboard;
import org.lwjgl.input.Mouse;
import org.lwjgl.opengl.GL11;
import java.awt.Point;
import java.io.PrintWriter;
import java.io.StringWriter;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashSet;
import java.util.LinkedList;
import java.util.List;
import java.util.regex.Pattern;
import static codechicken.lib.gui.GuiDraw.drawMultilineTip;
import static codechicken.lib.gui.GuiDraw.fontRenderer;
import static codechicken.lib.gui.GuiDraw.getMousePosition;
import static codechicken.lib.gui.GuiDraw.renderEngine;
public class GuiContainerManager
{
public GuiContainer window;
public static RenderItem drawItems = new RenderItem();
public static LinkedList<IContainerTooltipHandler> tooltipHandlers = new LinkedList<>();
public static LinkedList<IContainerInputHandler> inputHandlers = new LinkedList<>();
public static LinkedList<IContainerDrawHandler> drawHandlers = new LinkedList<>();
public static LinkedList<IContainerObjectHandler> objectHandlers = new LinkedList<>();
public static LinkedList<IContainerSlotClickHandler> slotClickHandlers = new LinkedList<>();
static {
addSlotClickHandler(new DefaultSlotClickHandler());
}
public static GuiContainerManager getManager() {
GuiScreen gui = Minecraft.getMinecraft().currentScreen;
return gui instanceof GuiContainer ? getManager((GuiContainer) gui) : null;
}
public static GuiContainerManager getManager(GuiContainer gui) {
//gets GuiContainer.manager using ASM
return null;
}
/**
* Register a new Tooltip render handler;
*
* @param handler The handler to register
*/
public static void addTooltipHandler(IContainerTooltipHandler handler) {
tooltipHandlers.add(handler);
}
/**
* Register a new Input handler;
*
* @param handler The handler to register
*/
public static void addInputHandler(IContainerInputHandler handler) {
inputHandlers.add(handler);
}
/**
* Register a new Drawing handler;
*
* @param handler The handler to register
*/
public static void addDrawHandler(IContainerDrawHandler handler) {
drawHandlers.add(handler);
}
/**
* Register a new Object handler;
*
* @param handler The handler to register
*/
public static void addObjectHandler(IContainerObjectHandler handler) {
objectHandlers.add(handler);
}
/**
* Care needs to be taken with this method. It will insert your handler at the start of the list to be called first. You may need to simply edit the list yourself.
*
* @param handler The handler to register.
*/
public static void addSlotClickHandler(IContainerSlotClickHandler handler) {
slotClickHandlers.addFirst(handler);
}
public static FontRenderer getFontRenderer(ItemStack stack) {
if (stack != null && stack.getItem() != null) {
FontRenderer f = stack.getItem().getFontRenderer(stack);
if (f != null)
return f;
}
return fontRenderer;
}
/**
* Extra lines are often used for more information. For example enchantments, potion effects and mob spawner contents.
*
* @param stack The item to get the name for.
* @param gui An instance of the currentscreen passed to tooltip handlers. If null, only gui inspecific handlers should respond
* @param includeHandlers If true tooltip handlers will add to the item tip
* @return A list of Strings representing the text to be displayed on each line of the tool tip.
*/
public static List<String> itemDisplayNameMultiline(ItemStack stack, GuiContainer gui, boolean includeHandlers) {
List<String> namelist = null;
try {
namelist = stack.getTooltip(Minecraft.getMinecraft().thePlayer, includeHandlers && Minecraft.getMinecraft().gameSettings.advancedItemTooltips);
} catch (Throwable ignored) {}
if (namelist == null)
namelist = new ArrayList<>();
if (namelist.size() == 0)
namelist.add("Unnamed");
if (namelist.get(0) == null || namelist.get(0).equals(""))
namelist.set(0, "Unnamed");
if (includeHandlers) {
for (IContainerTooltipHandler handler : tooltipHandlers) {
namelist = handler.handleItemDisplayName(gui, stack, namelist);
}
}
namelist.set(0, stack.getRarity().rarityColor.toString() + namelist.get(0));
for (int i = 1; i < namelist.size(); i++)
namelist.set(i, "\u00a77" + namelist.get(i));
return namelist;
}
/**
* The general name of this item.
*
* @param itemstack The {@link ItemStack} to get the name for.
* @return The first line of the multiline display name.
*/
public static String itemDisplayNameShort(ItemStack itemstack) {
List<String> list = itemDisplayNameMultiline(itemstack, null, false);
return list.get(0);
}
/**
* Concatenates the multiline display name into one line for easy searching using string and {@link Pattern} functions.
*
* @param itemstack The stack to get the name for
* @return The multiline display name of this item separated by '#'
*/
public static String concatenatedDisplayName(ItemStack itemstack, boolean includeHandlers) {
List<String> list = itemDisplayNameMultiline(itemstack, null, includeHandlers);
StringBuilder sb = new StringBuilder();
boolean first = true;
for (String name : list) {
if (first) {
first = false;
} else {
sb.append("#");
}
sb.append(name);
}
return EnumChatFormatting.getTextWithoutFormattingCodes(sb.toString());
}
public static void drawItem(int i, int j, ItemStack itemstack) {
drawItem(i, j, itemstack, getFontRenderer(itemstack));
}
private static int modelviewDepth = -1;
private static final HashSet<String> stackTraces = new HashSet<>();
public static void drawItem(int i, int j, ItemStack itemstack, FontRenderer fontRenderer) {
enable3DRender();
float zLevel = drawItems.zLevel += 100F;
try {
drawItems.renderItemAndEffectIntoGUI(fontRenderer, renderEngine, itemstack, i, j);
drawItems.renderItemOverlayIntoGUI(fontRenderer, renderEngine, itemstack, i, j);
if (!checkMatrixStack())
throw new IllegalStateException("Modelview matrix stack too deep");
if (Tessellator.instance.isDrawing)
throw new IllegalStateException("Still drawing");
} catch (Exception e) {
StringWriter sw = new StringWriter();
e.printStackTrace(new PrintWriter(sw));
String stackTrace = itemstack + sw.toString();
if (!stackTraces.contains(stackTrace)) {
System.err.println("Error while rendering: " + itemstack);
e.printStackTrace();
stackTraces.add(stackTrace);
}
restoreMatrixStack();
if (Tessellator.instance.isDrawing)
Tessellator.instance.draw();
drawItems.zLevel = zLevel;
drawItems.renderItemIntoGUI(fontRenderer, renderEngine, new ItemStack(Blocks.fire), i, j);
}
enable2DRender();
drawItems.zLevel = zLevel - 100;
}
public static void enableMatrixStackLogging() {
modelviewDepth = GL11.glGetInteger(GL11.GL_MODELVIEW_STACK_DEPTH);
}
public static void disableMatrixStackLogging() {
modelviewDepth = -1;
}
public static boolean checkMatrixStack() {
return modelviewDepth < 0 || GL11.glGetInteger(GL11.GL_MODELVIEW_STACK_DEPTH) == modelviewDepth;
}
public static void restoreMatrixStack() {
if (modelviewDepth >= 0)
for (int i = GL11.glGetInteger(GL11.GL_MODELVIEW_STACK_DEPTH); i > modelviewDepth; i--)
GL11.glPopMatrix();
}
public static void setColouredItemRender(boolean enable) {
drawItems.renderWithColor = !enable;
}
public static void enable3DRender() {
GL11.glEnable(GL11.GL_LIGHTING);
GL11.glEnable(GL11.GL_DEPTH_TEST);
}
public static void enable2DRender() {
GL11.glDisable(GL11.GL_LIGHTING);
GL11.glDisable(GL11.GL_DEPTH_TEST);
}
private int clickHandled = 0;
private final List<IContainerTooltipHandler> instanceTooltipHandlers;
public GuiContainerManager(GuiContainer screen) {
window = screen;
if (screen instanceof IContainerTooltipHandler) {
instanceTooltipHandlers = Collections.synchronizedList(new LinkedList<>());
instanceTooltipHandlers.add((IContainerTooltipHandler) screen);
instanceTooltipHandlers.addAll(tooltipHandlers);
} else
instanceTooltipHandlers = tooltipHandlers;
}
public static ItemStack getStackMouseOver(GuiContainer window) {
Point mousePos = getMousePosition();
for (IContainerObjectHandler objectHandler : objectHandlers) {
ItemStack item = objectHandler.getStackUnderMouse(window, mousePos.x, mousePos.y);
if (item != null)
return item;
}
Slot slot = getSlotMouseOver(window);
if (slot != null)
return slot.getStack();
return null;
}
public static Slot getSlotMouseOver(GuiContainer window) {
Point mousePos = getMousePosition();
if (getManager(window).objectUnderMouse(mousePos.x, mousePos.y))
return null;
return window.getSlotAtPosition(mousePos.x, mousePos.y);
}
public void load() {
clickHandled = 0;
for (IContainerObjectHandler objectHandler : objectHandlers)
objectHandler.load(window);
}
/**
* Called from updateScreen
*/
public void updateScreen() {
for (IContainerObjectHandler objectHandler : objectHandlers)
objectHandler.guiTick(window);
}
/**
* Override for keyTyped
*/
public boolean lastKeyTyped(int keyID, char keyChar) {
if (keyID == 1)
return false;
for (IContainerInputHandler inputhander : inputHandlers)
if (inputhander.lastKeyTyped(window, keyChar, keyID))
return true;
return false;
}
public boolean firstKeyTyped(char keyChar, int keyID) {
for (IContainerInputHandler inputhander : inputHandlers)
inputhander.onKeyTyped(window, keyChar, keyID);
for (IContainerInputHandler inputhander : inputHandlers)
if (inputhander.keyTyped(window, keyChar, keyID))
return true;
return false;
}
public boolean mouseClicked(int mousex, int mousey, int button) {
for (IContainerInputHandler inputhander : inputHandlers)
inputhander.onMouseClicked(window, mousex, mousey, button);
for (IContainerInputHandler inputhander : inputHandlers)
if (inputhander.mouseClicked(window, mousex, mousey, button)) {
clickHandled |= 1 << button;
return true;
}
return false;
}
public void mouseScrolled(int scrolled) {
Point mousepos = getMousePosition();
for (IContainerInputHandler inputHandler : inputHandlers)
inputHandler.onMouseScrolled(window, mousepos.x, mousepos.y, scrolled);
for (IContainerInputHandler inputHandler : inputHandlers)
if (inputHandler.mouseScrolled(window, mousepos.x, mousepos.y, scrolled))
return;
if (window instanceof IGuiHandleMouseWheel)
((IGuiHandleMouseWheel) window).mouseScrolled(scrolled);
}
/**
* Override for mouseMovedOrUp
*/
public boolean overrideMouseUp(int mousex, int mousey, int button) {
if (button >= 0 && (clickHandled & 1 << button) != 0) {
clickHandled &= ~(1 << button);
mouseUp(mousex, mousey, button);
return true;
}
return false;
}
public void mouseUp(int mousex, int mousey, int button) {
for (IContainerInputHandler inputhander : inputHandlers)
inputhander.onMouseUp(window, mousex, mousey, button);
}
/**
* Called from mouseClickMove
*/
public void mouseDragged(int mousex, int mousey, int button, long heldTime) {
for (IContainerInputHandler inputhander : inputHandlers)
inputhander.onMouseDragged(window, mousex, mousey, button, heldTime);
}
/**
* Called at the start of drawScreen
*/
public void preDraw() {
for (IContainerDrawHandler drawHandler : drawHandlers)
drawHandler.onPreDraw(window);
}
public void renderObjects(int mousex, int mousey) {
GL11.glTranslatef(-window.guiLeft, -window.guiTop, 200F);
for (IContainerDrawHandler drawHandler : drawHandlers)
drawHandler.renderObjects(window, mousex, mousey);
for (IContainerDrawHandler drawHandler : drawHandlers)
drawHandler.postRenderObjects(window, mousex, mousey);
GL11.glTranslatef(window.guiLeft, window.guiTop, -200F);
}
public void renderToolTips(int mousex, int mousey) {
List<String> tooltip = new LinkedList<>();
FontRenderer font = GuiDraw.fontRenderer;
synchronized (instanceTooltipHandlers) {
for (IContainerTooltipHandler handler : instanceTooltipHandlers)
tooltip = handler.handleTooltip(window, mousex, mousey, tooltip);
}
if (tooltip.isEmpty() && shouldShowTooltip(window)) {//mouseover tip, not holding an item
ItemStack stack = getStackMouseOver(window);
font = getFontRenderer(stack);
if (stack != null)
tooltip = itemDisplayNameMultiline(stack, window, true);
synchronized (instanceTooltipHandlers) {
for (IContainerTooltipHandler handler : instanceTooltipHandlers)
tooltip = handler.handleItemTooltip(window, stack, mousex, mousey, tooltip);
}
}
if (tooltip.size() > 0)
tooltip.set(0, tooltip.get(0) + GuiDraw.TOOLTIP_LINESPACE);//add space after 'title'
drawMultilineTip(font, mousex + 12, mousey - 12, tooltip);
}
public static boolean shouldShowTooltip(GuiContainer window) {
for (IContainerObjectHandler handler : objectHandlers)
if (!handler.shouldShowTooltip(window))
return false;
return window.mc.thePlayer.inventory.getItemStack() == null;
}
public void renderSlotUnderlay(Slot slot) {
for (IContainerDrawHandler drawHandler : drawHandlers)
drawHandler.renderSlotUnderlay(window, slot);
}
public void renderSlotOverlay(Slot slot) {
for (IContainerDrawHandler drawHandler : drawHandlers)
drawHandler.renderSlotOverlay(window, slot);
GL11.glEnable(GL11.GL_ALPHA_TEST);
}
/**
* Returns true if there is an object of yours obscuring the slot that the mouse would otherwise be hovering over.
*/
public boolean objectUnderMouse(int mousex, int mousey) {
for (IContainerObjectHandler objectHandler : objectHandlers)
if (objectHandler.objectUnderMouse(window, mousex, mousey))
return true;
return false;
}
public void handleMouseClick(Slot slot, int slotIndex, int button, int modifier) {
for (IContainerSlotClickHandler handler : slotClickHandlers)
handler.beforeSlotClick(window, slotIndex, button, slot, modifier);
boolean eventHandled = false;
for (IContainerSlotClickHandler handler : slotClickHandlers)
eventHandled = handler.handleSlotClick(window, slotIndex, button, slot, modifier, eventHandled);
for (IContainerSlotClickHandler handler : slotClickHandlers)
handler.afterSlotClick(window, slotIndex, button, slot, modifier);
}
// Support inputting Chinese characters
public void handleKeyboardInput() {
// Support for LWGJL 2.9.0 or later
int k = Keyboard.getEventKey();
char c = Keyboard.getEventCharacter();
if (Keyboard.getEventKeyState() || (k == 0 && Character.isDefined(c))) {
try {
keyTyped(c, k);
} catch (java.lang.IndexOutOfBoundsException e) {
System.err.println("Caught out of bounds exception pressing " + c + " " + k);
e.printStackTrace();
}
}
window.mc.func_152348_aa();
}
public void keyTyped(char c, int k) {
if (firstKeyTyped(c, k))
return;
callKeyTyped(window, c, k);
}
private static void callKeyTyped(GuiContainer window, char c, int k) {
//calls GuiContainer.keyTyped using ASM generated forwarder
}
/**
* Delegate for changing item rendering for certain slots. Eg. Shrinking text for large itemstacks
*/
public void drawSlotItem(Slot slot, ItemStack stack, int x, int y, String quantity) {
if(window instanceof IGuiSlotDraw)
((IGuiSlotDraw)window).drawSlotItem(slot, stack, x, y, quantity);
else {
drawItems.renderItemAndEffectIntoGUI(fontRenderer, window.mc.getTextureManager(), stack, x, y);
drawItems.renderItemOverlayIntoGUI(fontRenderer, window.mc.getTextureManager(), stack, x, y, quantity);
}
}
/**
* Implementation for handleMouseClick
*/
public void handleSlotClick(int slotIndex, int button, int modifiers) {
if (slotIndex == -1)
return;
if (window instanceof IGuiClientSide)//send the calls directly to the container bypassing the MPController window send
window.mc.thePlayer.openContainer.slotClick(slotIndex, button, modifiers, window.mc.thePlayer);
else
window.mc.playerController.windowClick(window.inventorySlots.windowId, slotIndex, button, modifiers, window.mc.thePlayer);
}
/**
* Called from handleMouseInput
*/
public void handleMouseWheel() {
int i = Mouse.getEventDWheel();
if (i != 0)
mouseScrolled(i > 0 ? 1 : -1);
}
}
@@ -1,40 +0,0 @@
package codechicken.nei.guihook;
import net.minecraft.client.gui.inventory.GuiContainer;
import net.minecraft.item.ItemStack;
import java.util.List;
/**
* If this interface is implemented by a GuiContainer then it will be the first handler delegated to but handleItmeDisplayName will not be called
*/
public interface IContainerTooltipHandler
{
/**
* Use this to add tooltips for other objects. If the current tip has lines in it after this call, the item tootip will not be handled. GuiContainerManager.shouldShowTooltip is not enforced here. It is recommended that you make this check yourself
* @param gui An instance of the currentscreen
* @param mousex The x position of the mouse in pixels from left
* @param mousey The y position of the mouse in pixels from top
* @param currenttip A list of strings, representing each line of the current tooltip as modified by other handlers
* @return The modified list. NOTE: Do not return null
*/
public List<String> handleTooltip(GuiContainer gui, int mousex, int mousey, List<String> currenttip);
/**
* Use this for modifying the multiline display name of an item which may not necessarily be under the mouse. GuiContainerManager.shouldShowTooltip is enforced here.
* @param gui An instance of the currentscreen. If only general information about the item is wanted (Eg. potion effects) then this may be null.
* @param itemstack The ItemStack under the mouse
* @param currenttip A list of strings, representing each line of the current tooltip as modified by other handlers
* @return The modified list. NOTE: Do not return null
*/
public List<String> handleItemDisplayName(GuiContainer gui, ItemStack itemstack, List<String> currenttip);
/**
* Use this for modifying the tooltips of items that are under the mouse. GuiContainerManager.shouldShowTooltip is enforced here.
* @param gui An instance of the currentscreen
* @param itemstack The ItemStack under the mouse
* @param currenttip A list of strings, representing each line of the current tooltip as modified by other handlers
* @return The modified list. NOTE: Do not return null
*/
public List<String> handleItemTooltip(GuiContainer gui, ItemStack itemstack, int mousex, int mousey, List<String> currenttip);
}
@@ -1,203 +0,0 @@
package codechicken.nei.recipe;
import codechicken.nei.ItemStackSet;
import codechicken.nei.NEIClientUtils;
import codechicken.nei.NEIServerUtils;
import codechicken.nei.PositionedStack;
import codechicken.nei.api.API;
import net.minecraft.client.gui.inventory.GuiBrewingStand;
import net.minecraft.client.gui.inventory.GuiContainer;
import net.minecraft.item.ItemPotion;
import net.minecraft.item.ItemStack;
import net.minecraft.potion.Potion;
import net.minecraft.potion.PotionEffect;
import net.minecraft.potion.PotionHelper;
import java.awt.Rectangle;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.TreeSet;
import java.util.stream.Collectors;
import static net.minecraft.init.Items.potionitem;
public class BrewingRecipeHandler extends TemplateRecipeHandler
{
public static class BrewingRecipe
{
public PositionedStack precursorPotion;
public PositionedStack result;
public PositionedStack ingredient;
public BrewingRecipe(ItemStack ingred, int basePotionID, int resultDamage) {
precursorPotion = new PositionedStack(new ItemStack(potionitem, 1, basePotionID), 51, 35);
ingredient = new PositionedStack(ingred, 74, 6);
result = new PositionedStack(new ItemStack(potionitem, 1, resultDamage), 97, 35);
}
}
public class CachedBrewingRecipe extends CachedRecipe
{
public final BrewingRecipe recipe;
public CachedBrewingRecipe(BrewingRecipe recipe) {
this.recipe = recipe;
}
@Override
public PositionedStack getResult() {
return recipe.result;
}
@Override
public ArrayList<PositionedStack> getIngredients() {
ArrayList<PositionedStack> recipestacks = new ArrayList<>();
recipestacks.add(recipe.ingredient);
recipestacks.add(recipe.precursorPotion);
return recipestacks;
}
}
public static final ItemStackSet ingredients = new ItemStackSet();
public static final HashSet<BrewingRecipe> apotions = new HashSet<>();
@Override
public void loadTransferRects() {
transferRects.add(new RecipeTransferRect(new Rectangle(58, 3, 14, 30), "brewing"));
transferRects.add(new RecipeTransferRect(new Rectangle(92, 3, 14, 30), "brewing"));
transferRects.add(new RecipeTransferRect(new Rectangle(68, 23, 28, 18), "brewing"));
}
@Override
public Class<? extends GuiContainer> getGuiClass() {
return GuiBrewingStand.class;
}
@Override
public String getRecipeName() {
return NEIClientUtils.translate("recipe.brewing");
}
@Override
public void loadCraftingRecipes(String outputId, Object... results) {
if (outputId.equals("brewing") && getClass() == BrewingRecipeHandler.class)//don't want subclasses getting a hold of this
for (BrewingRecipe recipe : apotions)
arecipes.add(new CachedBrewingRecipe(recipe));
else
super.loadCraftingRecipes(outputId, results);
}
@Override
public void loadCraftingRecipes(ItemStack result) {
if (result.getItem() != potionitem) return;
int damage = result.getItemDamage();
// Note: Not safe as written for parallelStream
apotions.stream()
.filter(recipe -> recipe.result.item.getItemDamage() == damage)
.map(CachedBrewingRecipe::new)
.collect(Collectors.toCollection(() -> arecipes));
}
@Override
public void loadUsageRecipes(ItemStack ingredient) {
if (ingredient.getItem() != potionitem && !ingredients.contains(ingredient)) return;
// Note: Not safe as written for parallelStream
apotions.stream()
.filter(recipe -> NEIServerUtils.areStacksSameType(recipe.ingredient.item, ingredient) || NEIServerUtils.areStacksSameType(recipe.precursorPotion.item, ingredient))
.map(CachedBrewingRecipe::new)
.collect(Collectors.toCollection(() -> arecipes));
}
@Override
public String getGuiTexture() {
return "textures/gui/container/brewing_stand.png";
}
@Override
public void drawExtras(int recipe) {
drawProgressBar(92, 5, 176, 0, 8, 30, 120, 1);
drawProgressBar(60, 1, 185, -2, 12, 30, 35, 3);
}
public static void searchPotions() {
TreeSet<Integer> allPotions = new TreeSet<>();
HashSet<Integer> searchPotions = new HashSet<>();
searchPotions.add(0);
allPotions.add(0);
do {
HashSet<Integer> newPotions = new HashSet<>();
for (Integer basePotion : searchPotions) {
if (ItemPotion.isSplash(basePotion))
continue;
for (ItemStack ingred : ingredients.values()) {
int result = PotionHelper.applyIngredient(basePotion, ingred.getItem().getPotionEffect(ingred));
if (ItemPotion.isSplash(result)) {//splash potions qualify
addPotion(ingred, basePotion, result, allPotions, newPotions);
continue;
}
List<?> baseMods = potionitem.getEffects(basePotion);
List<?> newMods = potionitem.getEffects(result);//compare ID's
if (basePotion > 0 && baseMods == newMods || //same modifers and not water->empty
baseMods != null && (baseMods.equals(newMods) || newMods == null) || //modifiers different and doesn't lose modifiers
basePotion == result ||//same potion
levelModifierChanged(basePotion, result))//redstone/glowstone cycle
continue;
addPotion(ingred, basePotion, result, allPotions, newPotions);
}
}
searchPotions = newPotions;
}
while (!searchPotions.isEmpty());
API.setItemListEntries(potionitem, allPotions.stream().map(potionID -> new ItemStack(potionitem, 1, potionID)).collect(Collectors.toList()));
API.addSubset("Items.Potions", new ItemStackSet().with(potionitem));
API.addSubset("Items.Potions.Splash", item -> item.getItem() == potionitem && (item.getItemDamage() & 0x4000) != 0);
ItemStackSet positivepots = new ItemStackSet();
ItemStackSet negativepots = new ItemStackSet();
ItemStackSet neutralpots = new ItemStackSet();
for (int potionID : allPotions) {
List<PotionEffect> effectlist = potionitem.getEffects(potionID);
int type = 0;
if (effectlist != null && !effectlist.isEmpty())
for (PotionEffect potioneffect : effectlist)
if (Potion.potionTypes[potioneffect.getPotionID()].isBadEffect())
type--;
else
type++;
(type == 0 ? neutralpots : type > 0 ? positivepots : negativepots).add(new ItemStack(potionitem, 1, potionID));
}
API.addSubset("Items.Potions.Positive", positivepots);
API.addSubset("Items.Potions.Negative", negativepots);
API.addSubset("Items.Potions.Neutral", neutralpots);
}
private static boolean levelModifierChanged(int basePotionID, int result) {
int basemod = basePotionID & 0xE0;
int resultmod = result & 0xE0;
return basemod != 0 && basemod != resultmod;
}
private static void addPotion(ItemStack ingred, int basePotion, int result, TreeSet<Integer> allPotions, HashSet<Integer> newPotions) {
apotions.add(new BrewingRecipe(ingred, basePotion, result));
if (allPotions.add(result))//it's new
newPotions.add(result);
}
@Override
public String getOverlayIdentifier() {
return "brewing";
}
}
@@ -1,146 +0,0 @@
package codechicken.nei.recipe;
import codechicken.nei.PositionedStack;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.inventory.Container;
import net.minecraft.inventory.IInventory;
import net.minecraft.inventory.Slot;
import net.minecraft.item.ItemStack;
public class ContainerRecipe extends Container
{
private class RecipeInventory implements IInventory
{
@Override
public boolean isUseableByPlayer(EntityPlayer entityplayer) {
return true;
}
@Override
public int getSizeInventory() {
return inventorySlots.size();
}
@Override
public ItemStack getStackInSlot(int i) {
if (i < 0 || i > inventoryItemStacks.size())
return null;
return (ItemStack) inventoryItemStacks.get(i);
}
@Override
public ItemStack decrStackSize(int i, int j) {
return null;
}
@Override
public void setInventorySlotContents(int slot, ItemStack itemstack) {
if (slot < 0 || slot >= inventoryItemStacks.size())
return;
inventoryItemStacks.set(slot, itemstack);
}
@Override
public String getInventoryName() {
return null;
}
@Override
public int getInventoryStackLimit() {
return 1;
}
@Override
public void markDirty() {
}
@Override
public void openInventory() {
}
@Override
public void closeInventory() {
}
@Override
public ItemStack getStackInSlotOnClosing(int var1) {
return null;
}
@Override
public boolean isItemValidForSlot(int i, ItemStack itemstack) {
return false;
}
@Override
public boolean hasCustomInventoryName() {
return false;
}
}
private final RecipeInventory recipeInventory = new RecipeInventory();
public void clearInventory()
{
inventoryItemStacks.clear();
inventorySlots.clear();
}
public ItemStack slotClick(int slot, int button, boolean flag, EntityPlayer entityplayer)
{
if(slot < 0)
return null;
ItemStack stack = recipeInventory.getStackInSlot(slot);
if(stack != null)
{
if(button == 0)
GuiCraftingRecipe.openRecipeGui("item", stack);
else if(button == 1)
GuiUsageRecipe.openRecipeGui("item", stack);
}
return null;
}
public void addSlot(PositionedStack stack, int recipex, int recipey)
{
int slot = inventorySlots.size();
addSlotToContainer(new Slot(recipeInventory, slot, recipex+stack.relx, recipey+stack.rely)
{
@Override
public boolean isItemValid(ItemStack par1ItemStack)
{
return false;
}
});
recipeInventory.setInventorySlotContents(slot, stack.item);
}
public Slot getSlotWithStack(PositionedStack stack, int recipex, int recipey)
{
for (Object inventorySlot : inventorySlots) {
Slot slot = (Slot) inventorySlot;
if (slot.xDisplayPosition == (stack.relx + recipex) && slot.yDisplayPosition == (stack.rely + recipey))
return slot;
}
return null;
}
public boolean canInteractWith(EntityPlayer entityplayer)
{
return true;
}
@Override
public void putStackInSlot(int par1, ItemStack par2ItemStack)
{
//Server side updates do nothing!
}
@Override
public ItemStack transferStackInSlot(EntityPlayer par1EntityPlayer, int par2)
{
return null;//no shift clicking (scrolling...)
}
}
@@ -1,315 +0,0 @@
package codechicken.nei.recipe;
import codechicken.lib.inventory.InventoryUtils;
import codechicken.nei.FastTransferManager;
import codechicken.nei.PositionedStack;
import codechicken.nei.api.IOverlayHandler;
import net.minecraft.client.gui.inventory.GuiContainer;
import net.minecraft.entity.player.InventoryPlayer;
import net.minecraft.inventory.Slot;
import net.minecraft.item.ItemStack;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
@SuppressWarnings("rawtypes, unchecked")
public class DefaultOverlayHandler implements IOverlayHandler {
public static Class gtItem;
static {
try {
gtItem = Class.forName("gregtech.api.items.GT_MetaBase_Item");
} catch (ClassNotFoundException ignored) {
gtItem = null;
}
}
public static class DistributedIngred {
public DistributedIngred(ItemStack item)
{
stack = InventoryUtils.copyStack(item, 1);
}
public ItemStack stack;
public int invAmount;
public int distributed;
public int numSlots;
public int recipeAmount;
}
public static class IngredientDistribution {
public IngredientDistribution(DistributedIngred distrib, ItemStack permutation) {
this.distrib = distrib;
this.permutation = permutation;
}
public DistributedIngred distrib;
public ItemStack permutation;
public Slot[] slots;
}
public DefaultOverlayHandler(int x, int y) {
offsetx = x;
offsety = y;
}
public DefaultOverlayHandler()
{
this(5, 11);
}
public int offsetx;
public int offsety;
@Override
public void overlayRecipe(GuiContainer gui, IRecipeHandler recipe, int recipeIndex, boolean shift) {
List<PositionedStack> ingredients = recipe.getIngredientStacks(recipeIndex);
List<DistributedIngred> ingredStacks = getPermutationIngredients(ingredients);
if(!clearIngredients(gui, ingredients))
return;
findInventoryQuantities(gui, ingredStacks);
List<IngredientDistribution> assignedIngredients = assignIngredients(ingredients, ingredStacks);
if(assignedIngredients == null)
return;
assignIngredSlots(gui, ingredients, assignedIngredients);
int quantity = calculateRecipeQuantity(assignedIngredients);
if(quantity != 0)
moveIngredients(gui, assignedIngredients, quantity);
}
@SuppressWarnings("unchecked")
private boolean clearIngredients(GuiContainer gui, List<PositionedStack> ingreds) {
for(PositionedStack pstack : ingreds)
for(Slot slot : (List<Slot>)gui.inventorySlots.inventorySlots)
if(slot.xDisplayPosition == pstack.relx+offsetx && slot.yDisplayPosition == pstack.rely+offsety) {
if(!slot.getHasStack())
continue;
FastTransferManager.clickSlot(gui, slot.slotNumber, 0, 1);
if(slot.getHasStack())
return false;
}
return true;
}
@SuppressWarnings("unchecked")
private void moveIngredients(GuiContainer gui, List<IngredientDistribution> assignedIngredients, int quantity) {
for(IngredientDistribution distrib : assignedIngredients) {
if(distrib.slots.length == 0) continue;
ItemStack pstack = distrib.permutation;
int transferCap = quantity*pstack.stackSize;
int transferred = 0;
int destSlotIndex = 0;
Slot dest = distrib.slots[0];
int slotTransferred = 0;
int slotTransferCap = pstack.getMaxStackSize();
for(Slot slot : (List<Slot>)gui.inventorySlots.inventorySlots) {
if(!slot.getHasStack() || !canMoveFrom(slot, gui))
continue;
ItemStack stack = slot.getStack();
if(!canStack(stack, pstack))
continue;
FastTransferManager.clickSlot(gui, slot.slotNumber);
int amount = Math.min(transferCap-transferred, stack.stackSize);
for(int c = 0; c < amount; c++) {
FastTransferManager.clickSlot(gui, dest.slotNumber, 1);
transferred++;
slotTransferred++;
if(slotTransferred >= slotTransferCap) {
destSlotIndex++;
if(destSlotIndex == distrib.slots.length) {
dest = null;
break;
}
dest = distrib.slots[destSlotIndex];
slotTransferred = 0;
}
}
FastTransferManager.clickSlot(gui, slot.slotNumber);
if(transferred >= transferCap || dest == null)
break;
}
}
}
private int calculateRecipeQuantity(List<IngredientDistribution> assignedIngredients) {
int quantity = Integer.MAX_VALUE;
for(IngredientDistribution distrib : assignedIngredients) {
DistributedIngred istack = distrib.distrib;
if(istack.numSlots == 0)
return 0;
int allSlots = istack.invAmount;
if(allSlots/istack.numSlots > istack.stack.getMaxStackSize())
allSlots = istack.numSlots*istack.stack.getMaxStackSize();
quantity = Math.min(quantity, allSlots/istack.distributed);
}
return quantity;
}
private Slot[][] assignIngredSlots(GuiContainer gui, List<PositionedStack> ingredients, List<IngredientDistribution> assignedIngredients) {
Slot[][] recipeSlots = mapIngredSlots(gui, ingredients);//setup the slot map
HashMap<Slot, Integer> distribution = new HashMap<>();
for (Slot[] recipeSlot : recipeSlots)
for (Slot slot : recipeSlot)
if (!distribution.containsKey(slot))
distribution.put(slot, -1);
HashSet<Slot> avaliableSlots = new HashSet<>(distribution.keySet());
HashSet<Integer> remainingIngreds = new HashSet<>();
ArrayList<LinkedList<Slot>> assignedSlots = new ArrayList<>();
for(int i = 0; i < ingredients.size(); i++) {
remainingIngreds.add(i);
assignedSlots.add(new LinkedList<>());
}
while(avaliableSlots.size() > 0 && remainingIngreds.size() > 0) {
for(Iterator<Integer> iterator = remainingIngreds.iterator(); iterator.hasNext();) {
int i = iterator.next();
boolean assigned = false;
DistributedIngred istack = assignedIngredients.get(i).distrib;
for(Slot slot : recipeSlots[i]) {
if(avaliableSlots.contains(slot)) {
avaliableSlots.remove(slot);
if(slot.getHasStack())
continue;
istack.numSlots++;
assignedSlots.get(i).add(slot);
assigned = true;
break;
}
}
if(!assigned || istack.numSlots*istack.stack.getMaxStackSize() >= istack.invAmount)
iterator.remove();
}
}
for(int i = 0; i < ingredients.size(); i++)
assignedIngredients.get(i).slots = assignedSlots.get(i).toArray(new Slot[0]);
return recipeSlots;
}
private List<IngredientDistribution> assignIngredients(List<PositionedStack> ingredients, List<DistributedIngred> ingredStacks)
{
ArrayList<IngredientDistribution> assignedIngredients = new ArrayList<>();
for(PositionedStack posstack : ingredients)//assign what we need and have
{
DistributedIngred biggestIngred = null;
ItemStack permutation = null;
int biggestSize = 0;
for(ItemStack pstack : posstack.items) {
for (DistributedIngred istack : ingredStacks) {
if (!canStack(pstack, istack.stack) || istack.invAmount - istack.distributed < pstack.stackSize || istack.recipeAmount == 0 || pstack.stackSize == 0)
continue;
int relsize = (istack.invAmount - istack.invAmount / istack.recipeAmount * istack.distributed) / pstack.stackSize;
if (relsize > biggestSize) {
biggestSize = relsize;
biggestIngred = istack;
permutation = pstack;
break;
}
}
}
if(biggestIngred == null)//not enough ingreds
return null;
biggestIngred.distributed+=permutation.stackSize;
assignedIngredients.add(new IngredientDistribution(biggestIngred, permutation));
}
return assignedIngredients;
}
@SuppressWarnings("unchecked")
private void findInventoryQuantities(GuiContainer gui, List<DistributedIngred> ingredStacks) {
for(Slot slot : (List<Slot>)gui.inventorySlots.inventorySlots)/*work out how much we have to go round*/ {
if(slot.getHasStack() && canMoveFrom(slot, gui)) {
ItemStack pstack = slot.getStack();
DistributedIngred istack = findIngred(ingredStacks, pstack);
if(istack != null)
istack.invAmount+=pstack.stackSize;
}
}
}
private List<DistributedIngred> getPermutationIngredients(List<PositionedStack> ingredients) {
ArrayList<DistributedIngred> ingredStacks = new ArrayList<>();
for(PositionedStack posstack : ingredients)/*work out what we need*/ {
for(ItemStack pstack : posstack.items) {
DistributedIngred istack = findIngred(ingredStacks, pstack);
if(istack == null)
ingredStacks.add(istack = new DistributedIngred(pstack));
istack.recipeAmount+=pstack.stackSize;
}
}
return ingredStacks;
}
public boolean canMoveFrom(Slot slot, GuiContainer gui) {
return slot.inventory instanceof InventoryPlayer;
}
@SuppressWarnings("unchecked")
public Slot[][] mapIngredSlots(GuiContainer gui, List<PositionedStack> ingredients)
{
Slot[][] recipeSlotList = new Slot[ingredients.size()][];
for(int i = 0; i < ingredients.size(); i++)/*identify slots*/ {
LinkedList<Slot> recipeSlots = new LinkedList<>();
PositionedStack pstack = ingredients.get(i);
for(Slot slot : (List<Slot>)gui.inventorySlots.inventorySlots) {
if(slot.xDisplayPosition == pstack.relx+offsetx && slot.yDisplayPosition == pstack.rely+offsety) {
recipeSlots.add(slot);
break;
}
}
recipeSlotList[i] = recipeSlots.toArray(new Slot[0]);
}
return recipeSlotList;
}
public DistributedIngred findIngred(List<DistributedIngred> ingredStacks, ItemStack pstack) {
for(DistributedIngred istack : ingredStacks)
if(canStack(pstack, istack.stack))
return istack;
return null;
}
protected boolean canStack(ItemStack stack1, ItemStack stack2) {
if (stack1 == null || stack2 == null)
return true;
if(stack1.getItem() == stack2.getItem() && stack1.getItemDamage() == stack2.getItemDamage()) {
if (ItemStack.areItemStackTagsEqual(stack2, stack1)) return true;
// GT Items don't have any NBT set for the recipe, so if either of the stacks has a NULL nbt, and the other doesn't, pretend they stack
if (((gtItem != null && gtItem.isInstance(stack1.getItem())) || (stack1.getMaxStackSize() == 1 && stack2.getMaxStackSize() == 1))
&& (stack1.stackTagCompound == null ^ stack2.stackTagCompound == null)
)
return true;
}
return false;
}
}
@@ -1,176 +0,0 @@
package codechicken.nei.recipe;
import codechicken.lib.gui.GuiDraw;
import codechicken.nei.InventoryCraftingDummy;
import codechicken.nei.NEIClientUtils;
import codechicken.nei.PositionedStack;
import codechicken.nei.guihook.GuiContainerManager;
import net.minecraft.init.Items;
import net.minecraft.inventory.InventoryCrafting;
import net.minecraft.item.Item;
import net.minecraft.item.ItemStack;
import net.minecraft.item.crafting.RecipeFireworks;
import java.awt.Point;
import java.awt.Rectangle;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.LinkedList;
import java.util.List;
public class FireworkRecipeHandler extends ShapelessRecipeHandler
{
public class CachedFireworkRecipe extends CachedShapelessRecipe
{
final LinkedList<Object> itemList = new LinkedList<>();
public final Object[] baseIngredients;
public final Object extraIngred;
public final int recipeType;
public CachedFireworkRecipe(Object[] base, Object extra, int type) {
super(new ItemStack(Items.fireworks));
this.baseIngredients = base;
this.extraIngred = extra;
this.recipeType = type;
cycle();
}
public void cycle() {
itemList.clear();
itemList.addAll(Arrays.asList(baseIngredients));
int extras = (cycleticks / 40) % (10 - itemList.size());
for (int i = 0; i < extras; i++)
itemList.add(extraIngred);
setIngredients(itemList);
List<PositionedStack> ingreds = getIngredients();
for (int i = 0; i < 9; i++)
inventoryCrafting.setInventorySlotContents(i, i < ingreds.size() ? ingreds.get(i).item : null);
if (!recipeFireworks.matches(inventoryCrafting, null))
throw new RuntimeException("Invalid Recipe?");
setResult(recipeFireworks.getCraftingResult(null));
}
}
private final InventoryCrafting inventoryCrafting = new InventoryCraftingDummy();
private final RecipeFireworks recipeFireworks = new RecipeFireworks();
public final ArrayList<CachedFireworkRecipe> mfireworks = new ArrayList<>();
public FireworkRecipeHandler() {
super();
stackorder = new int[][]{
{0, 0},
{1, 0},
{2, 0},
{0, 1},
{1, 1},
{2, 1},
{0, 2},
{1, 2},
{2, 2}};
loadAllFireworks();
}
private void loadAllFireworks() {
//charges
Item[] shapes = new Item[]{null, Items.fire_charge, Items.gold_nugget, Items.feather, Items.skull};
Item[] effects = new Item[]{null, Items.diamond, Items.glowstone_dust};
for (Item shape : shapes)
for (Item effect : effects)
genRecipe(Items.gunpowder, shape, effect, Items.dye, Items.dye, 0);
//fireworks
genRecipe(Items.gunpowder, Items.paper, Items.firework_charge, 2);
genRecipe(Items.gunpowder, Items.gunpowder, Items.paper, Items.firework_charge, 2);
genRecipe(Items.gunpowder, Items.gunpowder, Items.gunpowder, Items.paper, Items.firework_charge, 2);
//setup a valid charge to use for the recolour recipe
for (int i = 0; i < 9; i++)
inventoryCrafting.setInventorySlotContents(i, null);
inventoryCrafting.setInventorySlotContents(0, new ItemStack(Items.gunpowder));
inventoryCrafting.setInventorySlotContents(1, new ItemStack(Items.dye));
recipeFireworks.matches(inventoryCrafting, null);
ItemStack charge = recipeFireworks.getCraftingResult(null);
genRecipe(charge, Items.dye, Items.dye, 1);
}
private void genRecipe(Object... params) {
int numIngreds = 0;
for (int i = 0; i < params.length - 2; i++)
if (params[i] != null)
numIngreds++;
for (int i = 0; i < params.length - 1; i++)
if (params[i] instanceof Item)
params[i] = new ItemStack((Item) params[i], 1, Short.MAX_VALUE);
Object[] ingreds = new Object[numIngreds];
for (int i = 0, j = 0; i < params.length - 2; i++)
if (params[i] != null)
ingreds[j++] = params[i];
mfireworks.add(new CachedFireworkRecipe(ingreds, params[params.length - 2], (Integer) params[params.length - 1]));
}
@Override
public void loadCraftingRecipes(ItemStack result) {
for (CachedFireworkRecipe recipe : mfireworks) {
if (recipe.result.item.getItem() == result.getItem()) {
recipe.cycle();
arecipes.add(recipe);
}
}
//show random recolouring recipes as well
}
@Override
public void loadCraftingRecipes(String outputId, Object... results) {
if (outputId.equals("crafting") && getClass() == FireworkRecipeHandler.class) {
arecipes.addAll(mfireworks);
} else {
super.loadCraftingRecipes(outputId, results);
}
}
@Override
public void loadUsageRecipes(ItemStack ingredient) {
for (CachedFireworkRecipe recipe : mfireworks) {
if (recipe.contains(recipe.ingredients, ingredient)) {
recipe.cycle();
arecipes.add(recipe);
}
}
}
@Override
public void onUpdate() {
if (!NEIClientUtils.shiftKey()) {
cycleticks++;
if (cycleticks % 20 == 0)
for (CachedRecipe crecipe : arecipes)
((CachedFireworkRecipe) crecipe).cycle();
}
}
@Override
public String getRecipeName() {
return NEIClientUtils.translate("recipe.firework");
}
@Override
public List<String> handleTooltip(GuiRecipe gui, List<String> currenttip, int recipe) {
currenttip = super.handleTooltip(gui, currenttip, recipe);
Point mousepos = GuiDraw.getMousePosition();
Point relMouse = new Point(mousepos.x - gui.guiLeft, mousepos.y - gui.guiTop);
Point recipepos = gui.getRecipePosition(recipe);
if (currenttip.isEmpty() && GuiContainerManager.getStackMouseOver(gui) == null &&
new Rectangle(recipepos.x, recipepos.y, 166, 55).contains(relMouse))
currenttip.add(NEIClientUtils.translate(
"recipe.firework.tooltip" + ((CachedFireworkRecipe) arecipes.get(recipe)).recipeType));
return currenttip;
}
}
@@ -1,108 +0,0 @@
package codechicken.nei.recipe;
import codechicken.nei.NEIClientUtils;
import codechicken.nei.PositionedStack;
import net.minecraft.item.ItemStack;
import net.minecraft.item.crafting.FurnaceRecipes;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.stream.Collectors;
import static codechicken.nei.NEIClientUtils.translate;
public class FuelRecipeHandler extends FurnaceRecipeHandler
{
public class CachedFuelRecipe extends CachedRecipe
{
public final FuelPair fuel;
public CachedFuelRecipe(FuelPair fuel) {
this.fuel = fuel;
}
@Override
public PositionedStack getIngredient() {
return mfurnace.get(cycleticks / 48 % mfurnace.size()).ingred;
}
@Override
public PositionedStack getResult() {
return mfurnace.get(cycleticks / 48 % mfurnace.size()).result;
}
@Override
public PositionedStack getOtherStack() {
return fuel.stack;
}
}
private final ArrayList<SmeltingPair> mfurnace = new ArrayList<>();
public FuelRecipeHandler() {
super();
loadAllSmelting();
}
public String getRecipeName() {
return NEIClientUtils.translate("recipe.fuel");
}
@SuppressWarnings("unchecked")
private void loadAllSmelting() {
// Note: Not safe as written for parallelStream
final Map<ItemStack, ItemStack> smeltingRecipes = (Map<ItemStack, ItemStack>) FurnaceRecipes.smelting().getSmeltingList();
smeltingRecipes.entrySet().stream()
.map(recipe -> new SmeltingPair(recipe.getKey(), recipe.getValue()))
.collect(Collectors.toCollection(() -> mfurnace));
}
@Override
public void loadCraftingRecipes(String outputId, Object... results) {
// Note: Not safe as written for parallelStream
if (outputId.equals("fuel") && getClass() == FuelRecipeHandler.class)
afuels.stream()
.map(CachedFuelRecipe::new)
.collect(Collectors.toCollection(() -> arecipes));
}
public void loadUsageRecipes(ItemStack ingredient) {
// Note: Not safe as written for parallelStream
afuels.stream()
.filter(fuel -> fuel != null && fuel.stack != null && fuel.stack.contains(ingredient))
.map(CachedFuelRecipe::new)
.collect(Collectors.toCollection(() -> arecipes));
}
public String getOverlayIdentifier() {
return "fuel";
}
@Override
public List<String> handleItemTooltip(GuiRecipe gui, ItemStack stack, List<String> currenttip, int recipe) {
CachedFuelRecipe crecipe = (CachedFuelRecipe) arecipes.get(recipe);
FuelPair fuel = crecipe.fuel;
float burnTime = fuel.burnTime / 200F;
if (gui.isMouseOver(fuel.stack, recipe) && burnTime < 1) {
burnTime = 1F / burnTime;
String s_time = Float.toString(burnTime);
if (burnTime == Math.round(burnTime))
s_time = Integer.toString((int) burnTime);
currenttip.add(translate("recipe.fuel.required", s_time));
} else if ((gui.isMouseOver(crecipe.getResult(), recipe) || gui.isMouseOver(crecipe.getIngredient(), recipe)) && burnTime > 1) {
String s_time = Float.toString(burnTime);
if (burnTime == Math.round(burnTime))
s_time = Integer.toString((int) burnTime);
currenttip.add(translate("recipe.fuel." + (gui.isMouseOver(crecipe.getResult(), recipe) ? "produced" : "processed"), s_time));
}
return currenttip;
}
}
@@ -1,76 +0,0 @@
package codechicken.nei.recipe;
import codechicken.core.TaskProfiler;
import codechicken.nei.ItemList;
import codechicken.nei.NEIClientConfig;
import codechicken.nei.NEIClientUtils;
import net.minecraft.client.Minecraft;
import net.minecraft.client.gui.GuiScreen;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.concurrent.ExecutionException;
import java.util.stream.Collectors;
public class GuiCraftingRecipe extends GuiRecipe
{
public static boolean openRecipeGui(String outputId, Object... results) {
Minecraft mc = NEIClientUtils.mc();
GuiScreen prevscreen = mc.currentScreen;// instanceof GuiContainer ? (GuiContainer) mc.currentScreen : null;
ArrayList<ICraftingHandler> handlers;
TaskProfiler profiler = ProfilerRecipeHandler.getProfiler();
profiler.start("recipe.concurrent.crafting");
// Pre-find the fuels so we're not fighting over it
FuelRecipeHandler.findFuelsOnceParallel();
try {
handlers = serialCraftingHandlers.stream().map(h -> h.getRecipeHandler(outputId, results))
.filter(h -> h.numRecipes() > 0)
.collect(Collectors.toCollection(ArrayList::new));
handlers.addAll(ItemList.forkJoinPool.submit(() -> craftinghandlers.parallelStream()
.map(h -> h.getRecipeHandler(outputId, results))
.filter(h -> h.numRecipes() > 0)
.collect(Collectors.toCollection(ArrayList::new))).get());
} catch (InterruptedException | ExecutionException e) {
e.printStackTrace();
return false;
} finally {
profiler.end();
}
if (handlers.isEmpty())
return false;
mc.displayGuiScreen(new GuiCraftingRecipe(prevscreen, handlers));
return true;
}
private GuiCraftingRecipe(GuiScreen prevgui, ArrayList<ICraftingHandler> handlers) {
super(prevgui);
currenthandlers = handlers;
}
public static void registerRecipeHandler(ICraftingHandler handler) {
final Class<? extends ICraftingHandler> handlerClass = handler.getClass();
if(craftinghandlers.stream().anyMatch(h -> h.getClass() == handlerClass) || serialCraftingHandlers.stream().anyMatch(h -> h.getClass() == handlerClass))
return;
final String handlerClassStr = handlerClass.getName();
if(NEIClientConfig.serialHandlers.contains(handlerClassStr))
serialCraftingHandlers.add(handler);
else
craftinghandlers.add(handler);
}
public ArrayList<? extends IRecipeHandler> getCurrentRecipeHandlers() {
return currenthandlers;
}
public ArrayList<ICraftingHandler> currenthandlers;
public static ArrayList<ICraftingHandler> craftinghandlers = new ArrayList<>();
public static ArrayList<ICraftingHandler> serialCraftingHandlers = new ArrayList<>();
}
-575
View File
@@ -1,575 +0,0 @@
package codechicken.nei.recipe;
import codechicken.lib.gui.GuiDraw;
import codechicken.nei.GuiNEIButton;
import codechicken.nei.LayoutManager;
import codechicken.nei.NEIClientConfig;
import codechicken.nei.NEIClientUtils;
import codechicken.nei.PositionedStack;
import codechicken.nei.VisiblityData;
import codechicken.nei.api.IGuiContainerOverlay;
import codechicken.nei.api.INEIGuiHandler;
import codechicken.nei.api.IOverlayHandler;
import codechicken.nei.api.IRecipeOverlayRenderer;
import codechicken.nei.api.TaggedInventoryArea;
import codechicken.nei.drawable.DrawableBuilder;
import codechicken.nei.drawable.DrawableResource;
import codechicken.nei.guihook.GuiContainerManager;
import codechicken.nei.guihook.IContainerTooltipHandler;
import codechicken.nei.guihook.IGuiClientSide;
import codechicken.nei.guihook.IGuiHandleMouseWheel;
import net.minecraft.client.gui.GuiButton;
import net.minecraft.client.gui.GuiScreen;
import net.minecraft.client.gui.inventory.GuiContainer;
import net.minecraft.client.renderer.OpenGlHelper;
import net.minecraft.client.renderer.RenderHelper;
import net.minecraft.inventory.Slot;
import net.minecraft.item.ItemStack;
import org.lwjgl.input.Keyboard;
import org.lwjgl.opengl.GL11;
import java.awt.Point;
import java.awt.Rectangle;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import java.util.Optional;
import java.util.stream.Collectors;
public abstract class GuiRecipe extends GuiContainer implements IGuiContainerOverlay, IGuiClientSide, IGuiHandleMouseWheel, IContainerTooltipHandler, INEIGuiHandler {
// Background image calculations
private static final int BG_TOP_HEIGHT = 6;
private static final int BG_MIDDLE_HEIGHT = 154;
private static final int BG_BOTTOM_HEIGHT = 6;
private static final int BG_TOP_Y = 0;
private static final int BG_MIDDLE_Y = BG_TOP_Y + BG_TOP_HEIGHT;
private static final int BG_BOTTOM_Y = BG_MIDDLE_Y + BG_MIDDLE_HEIGHT;
// Button sizes
private static final int borderPadding = 6;
private static final int buttonWidth = 13;
private static final int buttonHeight = 12;
// Background image
final DrawableResource bgTop = new DrawableBuilder("nei:textures/gui/recipebg.png", 0, BG_TOP_Y, 176, BG_TOP_HEIGHT).build();
final DrawableResource bgMiddle = new DrawableBuilder("nei:textures/gui/recipebg.png", 0, BG_MIDDLE_Y, 176, BG_MIDDLE_HEIGHT).build();
final DrawableResource bgBottom = new DrawableBuilder("nei:textures/gui/recipebg.png", 0, BG_BOTTOM_Y, 176, BG_BOTTOM_HEIGHT).build();
public ArrayList<? extends IRecipeHandler> currenthandlers = new ArrayList<>();
public int page;
public int recipetype;
public ContainerRecipe slotcontainer;
public GuiContainer firstGui;
public GuiScreen prevGui;
public GuiButton nextpage;
public GuiButton prevpage;
private GuiButton nexttype;
private GuiButton prevtype;
private int OVERLAY_BUTTON_ID_START = 4;
private GuiButton[] overlayButtons;
private final Rectangle area = new Rectangle();
private final GuiRecipeTabs recipeTabs;
private IRecipeHandler handler;
private HandlerInfo handlerInfo;
private int yShift = 0;
protected GuiRecipe(GuiScreen prevgui) {
super(new ContainerRecipe());
recipeTabs = new GuiRecipeTabs(this);
slotcontainer = (ContainerRecipe) inventorySlots;
this.prevGui = prevgui;
if(prevgui instanceof GuiContainer)
this.firstGui = (GuiContainer)prevgui;
if (prevgui instanceof IGuiContainerOverlay)
this.firstGui = ((IGuiContainerOverlay) prevgui).getFirstScreen();
}
@Override
@SuppressWarnings("unchecked")
public void initGui() {
xSize = 176;
ySize = Math.min(Math.max(height - 68, 166), 370);
super.initGui();
guiTop = (height - ySize) / 2 + 10;
currenthandlers = getCurrentRecipeHandlers(); // Probably don't comment me out
if(handler == null)
setRecipePage(recipetype);
else
initOverlayButtons();
checkYShift();
final int rightButtonX = guiLeft + xSize - borderPadding - buttonWidth;
final int leftButtonX = guiLeft + borderPadding;
nexttype = new GuiNEIButton(0, leftButtonX, guiTop + 3, buttonWidth, buttonHeight, "<");
prevtype = new GuiNEIButton(1, rightButtonX, guiTop + 3, buttonWidth, buttonHeight, ">");
nextpage = new GuiNEIButton(2, leftButtonX, guiTop + 17, buttonWidth, buttonHeight, "<");
prevpage = new GuiNEIButton(3, rightButtonX, guiTop + 17, buttonWidth, buttonHeight, ">");
buttonList.addAll(Arrays.asList(nexttype, prevtype, nextpage, prevpage));
if (currenthandlers.size() == 1) {
nexttype.visible = false;
prevtype.visible = false;
}
recipeTabs.initLayout();
refreshPage();
}
@SuppressWarnings("unchecked")
private void initOverlayButtons() {
if (overlayButtons != null) {
buttonList.removeIf(Arrays.asList(overlayButtons)::contains);
}
final int recipesPerPage = getRecipesPerPage();
overlayButtons = new GuiButton[recipesPerPage];
for (int i = 0 ; i < recipesPerPage ; i++) {
overlayButtons[i] = new GuiNEIButton(
OVERLAY_BUTTON_ID_START + i,
(width / 2) + 65,
guiTop + 16 + (handlerInfo.getHeight() * (i+1)) - 2,
buttonWidth,
buttonHeight,
"?");
}
Collections.addAll(buttonList, overlayButtons);
itemPresenceCacheRecipe = -1;
}
private void checkYShift() {
yShift = handlerInfo == null ? 0 : handlerInfo.getYShift();
}
public void setRecipePage(int idx) {
recipetype = idx;
if (recipetype < 0) recipetype = currenthandlers.size() - 1;
else if (recipetype >= currenthandlers.size()) recipetype = 0;
handler = currenthandlers.get(recipetype);
handlerInfo = getHandlerInfo(handler);
page = 0;
recipeTabs.calcPageNumber();
checkYShift();
initOverlayButtons();
}
@Override
public void keyTyped(char c, int i) {
if (i == Keyboard.KEY_ESCAPE) //esc
{
mc.displayGuiScreen(firstGui);
return;
}
if (GuiContainerManager.getManager(this).lastKeyTyped(i, c))
return;
final int recipesPerPage = getRecipesPerPage();
for (int recipe = page * recipesPerPage; recipe < handler.numRecipes() && recipe < (page + 1) * recipesPerPage; recipe++)
if (handler.keyTyped(this, c, i, recipe))
return;
if (i == mc.gameSettings.keyBindInventory.getKeyCode())
mc.displayGuiScreen(firstGui);
else if (i == NEIClientConfig.getKeyBinding("gui.back"))
mc.displayGuiScreen(prevGui);
else if (i == NEIClientConfig.getKeyBinding("gui.prev_machine"))
prevType();
else if (i == NEIClientConfig.getKeyBinding("gui.next_machine"))
nextType();
else if (i == NEIClientConfig.getKeyBinding("gui.prev_recipe"))
prevPage();
else if (i == NEIClientConfig.getKeyBinding("gui.next_recipe"))
nextPage();
}
@Override
protected void mouseClicked(int x, int y, int button) {
final int recipesPerPage = getRecipesPerPage();
for (int recipe = page * recipesPerPage; recipe < handler.numRecipes() && recipe < (page + 1) * recipesPerPage; recipe++)
if (handler.mouseClicked(this, button, recipe))
return;
if (recipeTabs.mouseClicked(x, y, button))
return;
super.mouseClicked(x, y, button);
}
@Override
protected void actionPerformed(GuiButton guibutton) {
super.actionPerformed(guibutton);
final int recipesPerPage = getRecipesPerPage();
switch (guibutton.id) {
case 0:
prevType();
return;
case 1:
nextType();
return;
case 2:
prevPage();
return;
case 3:
nextPage();
return;
}
if (overlayButtons != null && guibutton.id >= OVERLAY_BUTTON_ID_START && guibutton.id < OVERLAY_BUTTON_ID_START + overlayButtons.length) {
overlayRecipe(page * recipesPerPage + guibutton.id - OVERLAY_BUTTON_ID_START);
}
}
@Override
public void updateScreen() {
super.updateScreen();
handler.onUpdate();
refreshPage();
}
@Override
public List<String> handleTooltip(GuiContainer gui, int mousex, int mousey, List<String> currenttip) {
final int recipesPerPage = getRecipesPerPage();
/*
* Several mods try to figure out the relative mouse position for fluid tooltips. This worked fine
* when it was a static 166.. however now that we're scaling it this no longer works. Rather than
* patching the individual mods (so that we can be as compatible as possible), we'll just fake
* the height for their tooltip rendering.
*/
// Begin Hax
final int oldHeight = this.height;
this.height = 166 + handlerInfo.getHeight() + 18 + (guiTop - 44) * 2;
for (int i = page * recipesPerPage; i < handler.numRecipes() && i < (page + 1) * recipesPerPage; i++) {
currenttip = handler.handleTooltip(this, currenttip, i);
}
recipeTabs.handleTooltip(mousex, mousey, currenttip);
this.height = oldHeight;
// End Hax
return currenttip;
}
@Override
public List<String> handleItemTooltip(GuiContainer gui, ItemStack stack, int mousex, int mousey, List<String> currenttip) {
final int recipesPerPage = getRecipesPerPage();
for (int i = page * recipesPerPage; i < handler.numRecipes() && i < (page + 1) * recipesPerPage; i++)
currenttip = handler.handleItemTooltip(this, stack, currenttip, i);
return currenttip;
}
@Override
public List<String> handleItemDisplayName(GuiContainer gui, ItemStack itemstack, List<String> currenttip) {
return currenttip;
}
private void nextPage() {
page++;
if (page > (handler.numRecipes() - 1) / getRecipesPerPage()) page = 0;
}
private void prevPage() {
page--;
if (page < 0) page = (handler.numRecipes() - 1) / getRecipesPerPage();
}
private void nextType() {
setRecipePage(++recipetype);
}
private void prevType() {
setRecipePage(--recipetype);
}
public HandlerInfo getHandlerInfo(IRecipeHandler handler) {
final String handlerID;
if(handler instanceof TemplateRecipeHandler) {
handlerID = (((TemplateRecipeHandler)handler).getOverlayIdentifier());
} else {
handlerID = null;
}
HandlerInfo info = GuiRecipeTab.getHandlerInfo(handler.getClass().getName(), handlerID);
if (info == null)
return GuiRecipeTab.DEFAULT_HANDLER_INFO;
return info;
}
private void overlayRecipe(int recipe) {
final IRecipeOverlayRenderer renderer = handler.getOverlayRenderer(firstGui, recipe);
final IOverlayHandler overlayHandler = handler.getOverlayHandler(firstGui, recipe);
final boolean shift = NEIClientUtils.shiftKey();
if (handler != null && (renderer == null || shift)) {
mc.displayGuiScreen(firstGui);
overlayHandler.overlayRecipe(firstGui, currenthandlers.get(recipetype), recipe, shift);
} else if (renderer != null) {
mc.displayGuiScreen(firstGui);
LayoutManager.overlayRenderer = renderer;
}
}
public void refreshPage() {
refreshSlots();
final int recipesPerPage = getRecipesPerPage();
final boolean multiplepages = handler.numRecipes() > recipesPerPage;
final int numRecipes = Math.min(handler.numRecipes() - (page * recipesPerPage), recipesPerPage);
area.width = handlerInfo.getWidth();
area.height = handlerInfo.getHeight() * numRecipes;
area.x = guiLeft - 2;
area.y = guiTop - 4 + yShift;
checkYShift();
nextpage.enabled = prevpage.enabled = multiplepages;
if(firstGui == null) {
for (GuiButton overlay : overlayButtons) {
overlay.visible = false;
}
} else {
for(int i = 0 ; i < overlayButtons.length ; i ++) {
if (i >= numRecipes) {
overlayButtons[i].visible = false;
} else {
final int curRecipe = page * recipesPerPage + i;
overlayButtons[i].visible = handler.hasOverlay(firstGui, firstGui.inventorySlots, curRecipe);
}
}
}
recipeTabs.refreshPage();
}
private void refreshSlots() {
slotcontainer.inventorySlots.clear();
final int recipesPerPage = getRecipesPerPage();
for (int i = page * recipesPerPage; i < handler.numRecipes() && i < (page + 1) * recipesPerPage; i++) {
Point p = getRecipePosition(i);
List<PositionedStack> stacks = handler.getIngredientStacks(i);
for (PositionedStack stack : stacks)
slotcontainer.addSlot(stack, p.x, p.y);
stacks = handler.getOtherStacks(i);
for (PositionedStack stack : stacks)
slotcontainer.addSlot(stack, p.x, p.y);
PositionedStack result = handler.getResultStack(i);
if (result != null)
slotcontainer.addSlot(result, p.x, p.y);
}
}
private int itemPresenceCacheRecipe = -1;
private ArrayList<Boolean> itemPresenceCacheSlots;
private void updateItemPresenceCache(int recipe) {
if (itemPresenceCacheSlots == null) {
itemPresenceCacheSlots = new ArrayList<>();
}
itemPresenceCacheRecipe = recipe;
itemPresenceCacheSlots.clear();
List<PositionedStack> ingredients = handler.getIngredientStacks(recipe);
ArrayList<ItemStack> invStacks = ((List<Slot>) firstGui.inventorySlots.inventorySlots).stream()
.filter(s -> s != null && s.getStack() != null && s.getStack().stackSize > 0 && s.isItemValid(s.getStack()) && s.canTakeStack(mc.thePlayer))
.map(s -> s.getStack().copy())
.collect(Collectors.toCollection(ArrayList::new));
for (PositionedStack stack : ingredients) {
Optional<ItemStack> used = invStacks.stream().filter(is -> is.stackSize > 0 && stack.contains(is)).findFirst();
itemPresenceCacheSlots.add(used.isPresent());
if (used.isPresent()) {
ItemStack is = used.get();
is.stackSize -= 1;
}
}
}
@Override
protected void drawGuiContainerForegroundLayer(int mouseX, int mouseY) {
GuiContainerManager.enable2DRender();
final int recipesPerPage = getRecipesPerPage();
String s = handler.getRecipeName().trim();
fontRendererObj.drawStringWithShadow(s, (xSize - fontRendererObj.getStringWidth(s)) / 2, 5, 0xffffff);
s = NEIClientUtils.translate("recipe.page", page + 1, (handler.numRecipes() - 1) / recipesPerPage + 1);
fontRendererObj.drawStringWithShadow(s, (xSize - fontRendererObj.getStringWidth(s)) / 2, 19, 0xffffff);
final boolean drawItemPresence = NEIClientConfig.isJEIStyleItemPresenceOverlayVisible();
GL11.glPushMatrix();
GL11.glTranslatef(5, 32 + yShift, 0);
for (int i = page * recipesPerPage; i < handler.numRecipes() && i < (page + 1) * recipesPerPage; i++) {
handler.drawForeground(i);
if (drawItemPresence && isMouseOverOverlayButton(i - page * recipesPerPage)
&& firstGui.inventorySlots != null) {
List<PositionedStack> ingredients = handler.getIngredientStacks(i);
if (itemPresenceCacheRecipe != i || itemPresenceCacheSlots == null || itemPresenceCacheSlots.size() != ingredients.size()) {
updateItemPresenceCache(i);
}
for (int j = 0; j < ingredients.size(); j++) {
PositionedStack stack = ingredients.get(j);
boolean isPresent = itemPresenceCacheSlots.get(j);
LayoutManager.drawItemPresenceOverlay(stack.relx, stack.rely, isPresent);
}
}
GL11.glTranslatef(0, handlerInfo.getHeight(), 0);
}
GL11.glPopMatrix();
}
@Override
protected void drawGuiContainerBackgroundLayer(float f, int mouseX, int mouseY) {
final int recipesPerPage = getRecipesPerPage();
GL11.glColor4f(1, 1, 1, 1);
final int j = (width - xSize) / 2;
final int k = guiTop;
drawBackgroundTiled(j, k);
drawRect(guiLeft + borderPadding + buttonWidth - 1,
nexttype.yPosition,
guiLeft + xSize - borderPadding - buttonWidth,
nexttype.yPosition + buttonHeight,
0x30000000);
drawRect(guiLeft + borderPadding + buttonWidth - 1,
nextpage.yPosition,
guiLeft + xSize - borderPadding - buttonWidth,
nextpage.yPosition + buttonHeight,
0x30000000);
if (NEIClientConfig.areJEIStyleTabsVisible()) {
RenderHelper.enableGUIStandardItemLighting();
OpenGlHelper.setLightmapTextureCoords(OpenGlHelper.lightmapTexUnit, 240f, 240f);
recipeTabs.draw(mouseX, mouseY);
RenderHelper.disableStandardItemLighting();
}
GL11.glPushMatrix();
GL11.glTranslatef(j + 5, k + 32 + yShift, 0);
for (int i = page * recipesPerPage; i < handler.numRecipes() && i < (page + 1) * recipesPerPage; i++) {
handler.drawBackground(i);
GL11.glTranslatef(0, handlerInfo.getHeight(), 0);
}
GL11.glPopMatrix();
}
private void drawBackgroundTiled(int j, int k) {
// Draw the top
bgTop.draw(j, k + BG_TOP_Y);
// Maybe Tile the middle
final int tiledHeight = ySize - BG_TOP_HEIGHT - BG_BOTTOM_HEIGHT;
if (tiledHeight > 0) {
final int yTileCount = tiledHeight / BG_MIDDLE_HEIGHT;
final int yRemainder = tiledHeight - (yTileCount * BG_MIDDLE_HEIGHT);
final int yStart = k + BG_TOP_HEIGHT + tiledHeight;
for (int yTile = 0; yTile <= yTileCount; yTile++) {
final int tileHeight = (yTile == yTileCount) ? yRemainder : BG_MIDDLE_HEIGHT;
final int y = yStart - ((yTile + 1) * BG_MIDDLE_HEIGHT);
if (tileHeight > 0) {
bgMiddle.draw(j, y, BG_MIDDLE_HEIGHT - tileHeight, 0, 0, 0);
}
}
}
// Draw the bottom
bgBottom.draw(j, k + ySize - BG_BOTTOM_HEIGHT);
}
@Override
public GuiContainer getFirstScreen() {
return firstGui;
}
public boolean isMouseOver(PositionedStack stack, int recipe) {
Slot stackSlot = slotcontainer.getSlotWithStack(stack, getRecipePosition(recipe).x, getRecipePosition(recipe).y);
Point mousepos = GuiDraw.getMousePosition();
Slot mouseoverSlot = getSlotAtPosition(mousepos.x, mousepos.y);
return stackSlot == mouseoverSlot;
}
private boolean isMouseOverOverlayButton(int buttonId) {
if(buttonId >= 0 && buttonId < overlayButtons.length) {
GuiButton button = overlayButtons[buttonId];
Point mousePos = GuiDraw.getMousePosition();
return button.visible && mousePos.x >= button.xPosition && mousePos.y >= button.yPosition
&& mousePos.x < button.xPosition + button.width && mousePos.y < button.yPosition + button.height;
} else {
return false;
}
}
private int getRecipesPerPage() {
if(handlerInfo != null)
return Math.max(Math.min(((ySize - (buttonHeight*3)) / handlerInfo.getHeight()), handlerInfo.getMaxRecipesPerPage()), 1);
else
return (handler.recipiesPerPage());
}
public Point getRecipePosition(int recipe) {
return new Point(5, 32 + yShift + ((recipe % getRecipesPerPage()) * handlerInfo.getHeight()));
}
@Override
public void mouseScrolled(int i) {
if (new Rectangle(guiLeft, guiTop, xSize, ySize).contains(GuiDraw.getMousePosition())) {
if (i > 0) prevPage();
else nextPage();
}
}
public abstract ArrayList<? extends IRecipeHandler> getCurrentRecipeHandlers();
@Override
public VisiblityData modifyVisiblity(GuiContainer gui, VisiblityData currentVisibility)
{
return currentVisibility;
}
@Override
public Iterable<Integer> getItemSpawnSlots(GuiContainer gui, ItemStack item) {
return Collections.emptyList();
}
@Override
public List<TaggedInventoryArea> getInventoryAreas(GuiContainer gui) {
return null;
}
@Override
public boolean handleDragNDrop(GuiContainer gui, int mousex, int mousey, ItemStack draggedStack, int button) {
return false;
}
@Override
public boolean hideItemPanelSlot(GuiContainer gui, int x, int y, int w, int h) {
// Because some of the handlers *cough avaritia* are oversized
Rectangle rect = new Rectangle(area);
return rect.contains(x, y, w, h);
}
}
@@ -1,285 +0,0 @@
package codechicken.nei.recipe;
import codechicken.lib.gui.GuiDraw;
import codechicken.nei.NEIClientConfig;
import codechicken.nei.Widget;
import codechicken.nei.drawable.DrawableResource;
import codechicken.nei.event.RegisterHandlerInfosEvent;
import codechicken.nei.guihook.GuiContainerManager;
import cpw.mods.fml.common.Loader;
import net.minecraft.client.gui.FontRenderer;
import net.minecraft.item.ItemStack;
import net.minecraft.util.EnumChatFormatting;
import net.minecraftforge.common.MinecraftForge;
import org.apache.commons.csv.CSVFormat;
import org.apache.commons.csv.CSVParser;
import org.apache.commons.csv.CSVRecord;
import org.lwjgl.input.Keyboard;
import org.lwjgl.opengl.GL11;
import org.lwjgl.opengl.GL12;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.MalformedURLException;
import java.net.URL;
import java.nio.channels.Channels;
import java.nio.channels.FileChannel;
import java.nio.channels.ReadableByteChannel;
import java.util.HashMap;
import java.util.List;
public abstract class GuiRecipeTab extends Widget {
public static HandlerInfo DEFAULT_HANDLER_INFO = getDefaultHandlerInfo();
public static HashMap<String, HandlerInfo> handlerMap = new HashMap<>();
private final GuiRecipe guiRecipe;
private final IRecipeHandler handler;
private final String handlerName;
private final String handlerID;
private boolean selected;
public abstract int getWidth();
public abstract int getHeight();
public abstract DrawableResource getSelectedTabImage();
public abstract DrawableResource getUnselectedTabImage();
protected abstract int getForegroundIconX();
protected abstract int getForegroundIconY();
public GuiRecipeTab(GuiRecipe guiRecipe, IRecipeHandler handler, int x, int y) {
super();
this.x = x;
this.y = y;
this.w = getWidth();
this.h = getHeight();
this.handler = handler;
this.handlerName = handler.toString().split("@")[0];
this.guiRecipe = guiRecipe;
this.selected = false;
if(handler instanceof TemplateRecipeHandler) {
handlerID = (((TemplateRecipeHandler)handler).getOverlayIdentifier());
} else {
handlerID = null;
}
}
@Override
public void draw(int mouseX, int mouseY) {
drawBackground(mouseX, mouseY);
drawForeground(mouseX, mouseY);
}
public void drawBackground(int mouseX, int mouseY) {
GL11.glDisable(GL11.GL_LIGHTING);
GL11.glColor4f(1, 1, 1, 1);
final DrawableResource image;
if (selected) image = getSelectedTabImage();
else image = getUnselectedTabImage();
final int iconX = x + (w - image.getWidth()) / 2;
final int iconY = y + (h - image.getHeight()) / 2;
image.draw(iconX, iconY);
}
public void drawForeground(int mouseX, int mouseY) {
final int iconX = getForegroundIconX();
final int iconY = getForegroundIconY();
final FontRenderer fontRenderer = GuiDraw.fontRenderer;
final HandlerInfo handlerInfo = getHandlerInfo(handlerName, handlerID);
final DrawableResource icon = handlerInfo != null ? handlerInfo.getImage() : null;
final ItemStack itemStack = handlerInfo != null ? handlerInfo.getItemStack() : null;
if (icon != null) {
icon.draw(iconX + 1, iconY + 1);
} else if (itemStack != null) {
boolean isEnabled = GL11.glIsEnabled(GL12.GL_RESCALE_NORMAL);
GL11.glEnable(GL12.GL_RESCALE_NORMAL);
GuiContainerManager.drawItems.zLevel += 100;
GuiContainerManager.drawItem(iconX, iconY, itemStack);
GuiContainerManager.drawItems.zLevel -= 100;
if (!isEnabled)
GL11.glDisable(GL12.GL_RESCALE_NORMAL);
} else {
// Text fallback
String text = handler.getRecipeName();
if (text != null && text.length() > 0) {
if (text.length() > 2) {
text = text.substring(0, 2);
}
} else {
text = "??";
}
int textCenterX = x + (int) (getWidth() / 2f);
int textCenterY = y + (int) (getHeight() / 2f) - 3;
int color = selected ? 0xffffa0 : 0xe0e0e0;
fontRenderer.drawStringWithShadow(text, textCenterX - (int) (fontRenderer.getStringWidth(text) / 2f), textCenterY, color);
GL11.glColor4f(1, 1, 1, 1);
}
}
public void addTooltips(List<String> tooltip) {
tooltip.add(handler.getRecipeName().trim());
String handlerMod = getHandlerMod(handlerName, handlerID);
tooltip.add(EnumChatFormatting.BLUE + handlerMod);
boolean shiftHeld = Keyboard.getEventKeyState() && (Keyboard.getEventKey() == Keyboard.KEY_LSHIFT || Keyboard.getEventKey() == Keyboard.KEY_RSHIFT);
if (handlerMod.equals("Unknown") || shiftHeld) {
tooltip.add("");
tooltip.add("HandlerName: " + handlerName);
tooltip.add("HandlerID: " + handlerID);
}
}
public boolean onButtonPress(boolean rightclick) {
int newIdx = guiRecipe.currenthandlers.indexOf(handler);
if (newIdx == -1)
return false;
guiRecipe.setRecipePage(newIdx);
return true;
}
public void setSelected(IRecipeHandler current) {
selected = handler == current;
}
public static HandlerInfo getHandlerInfo(String name, String name2) {
HandlerInfo res = handlerMap.get(name);
if (res == null) res = handlerMap.get(name2);
return res;
}
public static String getHandlerMod(String name, String name2) {
HandlerInfo info = getHandlerInfo(name, name2);
if (info == null)
return "Unknown";
return info.getModName();
}
public static void loadHandlerInfo() {
final boolean fromJar = NEIClientConfig.loadHandlersFromJar();
NEIClientConfig.logger.info("Loading handler info from " + (fromJar ? "JAR" : "Config"));
handlerMap.clear();
URL handlerUrl = Thread.currentThread().getContextClassLoader().getResource("assets/nei/csv/handlers.csv");
URL url;
if (fromJar) {
url = handlerUrl;
if (url == null) {
NEIClientConfig.logger.info("Invalid URL for handlers csv.");
return;
}
} else {
File handlerFile = NEIClientConfig.handlerFile;
if(!handlerFile.exists()) {
NEIClientConfig.logger.info("Config file doesn't exit, creating");
try {
assert handlerUrl != null;
ReadableByteChannel readableByteChannel = Channels.newChannel(handlerUrl.openStream());
FileOutputStream fileOutputStream = new FileOutputStream(handlerFile.getAbsoluteFile());
FileChannel fileChannel = fileOutputStream.getChannel();
fileChannel.transferFrom(readableByteChannel, 0, Long.MAX_VALUE);
} catch (IOException e) {
e.printStackTrace();
return;
}
}
try {
url = NEIClientConfig.handlerFile.toURI().toURL();
} catch (MalformedURLException e) {
NEIClientConfig.logger.info("Invalid URL for handlers csv (via config).");
e.printStackTrace();
return;
}
}
try {
BufferedReader input = new BufferedReader(new InputStreamReader(url.openStream()));
CSVParser csvParser = CSVFormat.EXCEL.withFirstRecordAsHeader().parse(input);
for (CSVRecord record : csvParser) {
final String handler = record.get("handler");
final String modName = record.get("modName");
final String modId = record.get("modId");
final boolean requiresMod = Boolean.parseBoolean(record.get("modRequired"));
final String excludedModId = record.get("excludedModId");
if (requiresMod && !Loader.isModLoaded(modId)) continue;
if (excludedModId != null && Loader.isModLoaded(excludedModId)) continue;
HandlerInfo info = new HandlerInfo(handler, modName, modId, requiresMod, excludedModId);
final String imageResource = record.get("imageResource");
if(imageResource != null && !imageResource.equals("")) {
info.setImage(imageResource,
Integer.parseInt(record.get("imageX")),
Integer.parseInt(record.get("imageY")),
Integer.parseInt(record.get("imageWidth")),
Integer.parseInt(record.get("imageHeight"))
);
}
if(!info.hasImageOrItem()) {
final String itemName = record.get("itemName");
if (itemName != null && !itemName.equals("")) {
info.setItem(itemName, record.get("nbtInfo"));
}
}
final String yShift = record.get("yShift");
if (yShift != null && !yShift.equals(""))
info.setYShift(Integer.parseInt(yShift));
try {
final int imageHeight = intOrDefault(record.get("handlerHeight"), HandlerInfo.DEFAULT_HEIGHT);
final int imageWidth = intOrDefault(record.get("handlerWidth"), HandlerInfo.DEFAULT_WIDTH);
final int maxRecipesPerPage = intOrDefault(record.get("maxRecipesPerPage"), HandlerInfo.DEFAULT_MAX_PER_PAGE);
info.setHandlerDimensions(imageHeight, imageWidth, maxRecipesPerPage);
} catch (NumberFormatException ignored) {
NEIClientConfig.logger.info("Error setting handler dimensions for " + handler);
}
handlerMap.put(handler, info);
NEIClientConfig.logger.info("Loaded " + handler);
}
} catch (IOException e) {
NEIClientConfig.logger.info("Error parsing CSV");
e.printStackTrace();
} catch (Exception e) {
NEIClientConfig.logger.info("Error parsing CSV");
e.printStackTrace();
}
NEIClientConfig.logger.info("Sending {}", RegisterHandlerInfosEvent.class.getSimpleName());
MinecraftForge.EVENT_BUS.post(new RegisterHandlerInfosEvent());
}
private static HandlerInfo getDefaultHandlerInfo() {
final HandlerInfo info = new HandlerInfo("Unknown", "Unknown", "Unknown", false, "");
info.setHandlerDimensions(HandlerInfo.DEFAULT_HEIGHT, HandlerInfo.DEFAULT_WIDTH, HandlerInfo.DEFAULT_MAX_PER_PAGE);
return info;
}
private static int intOrDefault(String str, int defaultValue) {
if (str == null || str.equals("")) return defaultValue;
try {
return Integer.parseInt(str);
} catch (NumberFormatException e) {
return defaultValue;
}
}
}
@@ -1,47 +0,0 @@
package codechicken.nei.recipe;
import codechicken.nei.drawable.DrawableBuilder;
import codechicken.nei.drawable.DrawableResource;
public class GuiRecipeTabCreative extends GuiRecipeTab {
public static final int TAB_WIDTH = 28;
public static final int TAB_HEIGHT = 31;
private static final DrawableResource selectedTabImage = new DrawableBuilder("minecraft:textures/gui/container/creative_inventory/tabs.png", 28, 32, 28, 32).build();
private static final DrawableResource unselectedTabImage = new DrawableBuilder("minecraft:textures/gui/container/creative_inventory/tabs.png", 28, 0, 28, 30).build();
public GuiRecipeTabCreative(GuiRecipe guiRecipe, IRecipeHandler handler, int x, int y) {
super(guiRecipe, handler, x, y);
}
@Override
public int getWidth() {
return TAB_WIDTH;
}
@Override
public int getHeight() {
return TAB_HEIGHT;
}
@Override
protected int getForegroundIconX() {
return x + (w - 16) / 2;
}
@Override
protected int getForegroundIconY() {
return y + h - 22;
}
@Override
public DrawableResource getSelectedTabImage() {
return selectedTabImage;
}
@Override
public DrawableResource getUnselectedTabImage() {
return unselectedTabImage;
}
}
@@ -1,47 +0,0 @@
package codechicken.nei.recipe;
import codechicken.nei.drawable.DrawableBuilder;
import codechicken.nei.drawable.DrawableResource;
public class GuiRecipeTabJEI extends GuiRecipeTab {
public static final int TAB_WIDTH = 24;
public static final int TAB_HEIGHT = 24;
private static final DrawableResource selectedTabImage = new DrawableBuilder("nei:textures/nei_tabbed_sprites.png", 0, 16, 24, 24).build();
private static final DrawableResource unselectedTabImage = new DrawableBuilder("nei:textures/nei_tabbed_sprites.png", 24, 16, 24, 24).build();
public GuiRecipeTabJEI(GuiRecipe guiRecipe, IRecipeHandler handler, int x, int y) {
super(guiRecipe, handler, x, y);
}
@Override
public int getWidth() {
return TAB_WIDTH;
}
@Override
public int getHeight() {
return TAB_HEIGHT;
}
@Override
protected int getForegroundIconX() {
return x + 4;
}
@Override
protected int getForegroundIconY() {
return y + 4;
}
@Override
public DrawableResource getSelectedTabImage() {
return selectedTabImage;
}
@Override
public DrawableResource getUnselectedTabImage() {
return unselectedTabImage;
}
}
@@ -1,196 +0,0 @@
package codechicken.nei.recipe;
import codechicken.nei.Button;
import codechicken.nei.NEIClientConfig;
import codechicken.nei.NEIClientUtils;
import java.awt.*;
import java.util.ArrayList;
import java.util.List;
public class GuiRecipeTabs {
private final GuiRecipe guiRecipe;
private final List<GuiRecipeTab> tabs = new ArrayList<>();
private final List<Button> buttons = new ArrayList<>();
private final Rectangle area = new Rectangle();
private boolean creative_tab_style;
private int pageCount = 1;
private int pageNumber = 0;
private int categoriesPerPage = 1;
private int numHandlers = 1;
private int tabWidth;
private int tabHeight;
public GuiRecipeTabs(GuiRecipe guiRecipe) {
this.guiRecipe = guiRecipe;
}
public void initLayout() {
creative_tab_style = NEIClientConfig.useCreativeTabStyle();
if(creative_tab_style) {
tabWidth = GuiRecipeTabCreative.TAB_WIDTH;
tabHeight = GuiRecipeTabCreative.TAB_HEIGHT;
} else {
tabWidth = GuiRecipeTabJEI.TAB_WIDTH;
tabHeight = GuiRecipeTabJEI.TAB_HEIGHT;
}
int totalWidth = 0;
categoriesPerPage = 0;
numHandlers = guiRecipe.currenthandlers.size();
for (IRecipeHandler handler : guiRecipe.currenthandlers) {
if (totalWidth + tabWidth < (guiRecipe.xSize - 4)) {
totalWidth += tabWidth;
categoriesPerPage++;
} else {
break;
}
}
area.width = totalWidth;
area.height = tabHeight;
area.x = guiRecipe.guiLeft + 4;
area.y = guiRecipe.guiTop - tabHeight + 3;
pageCount = (int) Math.ceil((float) numHandlers / categoriesPerPage);
calcPageNumber();
Rectangle navigationArea = new Rectangle(area);
navigationArea.height = 20;
navigationArea.translate(0, -(2 + navigationArea.height));
}
public void calcPageNumber() {
pageNumber = guiRecipe.recipetype / Math.max(categoriesPerPage, 1);
}
public void refreshPage() {
tabs.clear();
buttons.clear();
final int startIndex = pageNumber * categoriesPerPage;
for (int i = 0 ; i < categoriesPerPage ; i++) {
final int index = i + startIndex;
if (index >= numHandlers) break;
IRecipeHandler handler = guiRecipe.currenthandlers.get(index);
int tabX = area.x + (i * tabWidth);
if(NEIClientConfig.useCreativeTabStyle())
tabs.add(new GuiRecipeTabCreative(guiRecipe, handler, tabX, area.y));
else
tabs.add(new GuiRecipeTabJEI(guiRecipe, handler, tabX, area.y));
}
// Maybe add buttons
if (numHandlers > categoriesPerPage) {
Button prevTab = new Button("prevTab") {
@Override
public boolean onButtonPress(boolean rightClick) {
if (!rightClick) {
NEIClientUtils.playClickSound();
return previousPage();
} else
return false;
}
@Override
public String getRenderLabel() {
return "<";
}
};
prevTab.w = 8;
prevTab.h = tabHeight - 4;
prevTab.x = area.x - prevTab.w + 1;
prevTab.y = area.y + 2;
buttons.add(prevTab);
Button nextTab = new Button("nextTab") {
@Override
public boolean onButtonPress(boolean rightclick) {
if (!rightclick) {
NEIClientUtils.playClickSound();
return nextPage();
} else return false;
}
@Override
public String getRenderLabel() {
return ">";
}
};
nextTab.w = prevTab.w;
nextTab.h = prevTab.h;
nextTab.x = area.x + area.width - 1;
nextTab.y = prevTab.y;
buttons.add(nextTab);
}
}
public boolean nextPage() {
if (hasNext()) pageNumber++;
else pageNumber = 0;
refreshPage();
return true;
}
public boolean hasNext() {
return pageNumber + 1 < pageCount;
}
public boolean previousPage() {
if (hasPrevious()) pageNumber--;
else pageNumber = pageCount - 1;
refreshPage();
return true;
}
public boolean hasPrevious() {
return pageNumber > 0;
}
public void draw(int mouseX, int mouseY) {
IRecipeHandler current = guiRecipe.currenthandlers.get(guiRecipe.recipetype);
for (GuiRecipeTab tab : tabs) {
tab.setSelected(current);
tab.draw(mouseX, mouseY);
}
for (Button button : buttons) {
button.draw(mouseX, mouseY);
}
}
public void handleTooltip(int mousex, int mousey, List<String> tooltips) {
if (!NEIClientConfig.areJEIStyleTabsVisible()) return;
for (GuiRecipeTab tab : tabs) {
if (tab.contains(mousex, mousey)) {
tab.addTooltips(tooltips);
}
}
for (Button button : buttons) {
if (button.contains(mousex, mousey)){
button.addTooltips(tooltips);
}
}
}
protected boolean mouseClicked(int x, int y, int mouseButton) {
if (!NEIClientConfig.areJEIStyleTabsVisible()) return false;
for (Button button : buttons) {
if (button.contains(x, y)) {
return button.onButtonPress(mouseButton == 1);
}
}
for (GuiRecipeTab tab : tabs) {
if (tab.contains(x, y)) {
return tab.onButtonPress(mouseButton == 1);
}
}
return false;
}
}
@@ -1,76 +0,0 @@
package codechicken.nei.recipe;
import codechicken.core.TaskProfiler;
import codechicken.nei.ItemList;
import codechicken.nei.NEIClientConfig;
import codechicken.nei.NEIClientUtils;
import net.minecraft.client.Minecraft;
import net.minecraft.client.gui.inventory.GuiContainer;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.concurrent.ExecutionException;
import java.util.stream.Collectors;
public class GuiUsageRecipe extends GuiRecipe
{
public static boolean openRecipeGui(String inputId, Object... ingredients) {
Minecraft mc = NEIClientUtils.mc();
GuiContainer prevscreen = mc.currentScreen instanceof GuiContainer ? (GuiContainer) mc.currentScreen : null;
ArrayList<IUsageHandler> handlers;
TaskProfiler profiler = ProfilerRecipeHandler.getProfiler();
// Pre-find the fuels so we're not fighting over it
FuelRecipeHandler.findFuelsOnceParallel();
profiler.start("recipe.concurrent.usage");
try {
handlers = serialUsageHandlers.stream().map(h -> h.getUsageHandler(inputId, ingredients))
.filter(h -> h.numRecipes() > 0)
.collect(Collectors.toCollection(ArrayList::new));
handlers.addAll(ItemList.forkJoinPool.submit(() -> usagehandlers.parallelStream()
.map(h -> h.getUsageHandler(inputId, ingredients))
.filter(h -> h.numRecipes() > 0)
.collect(Collectors.toCollection(ArrayList::new))).get());
} catch (InterruptedException | ExecutionException e) {
e.printStackTrace();
return false;
} finally {
profiler.end();
}
if (handlers.isEmpty())
return false;
mc.displayGuiScreen(new GuiUsageRecipe(prevscreen, handlers));
return true;
}
private GuiUsageRecipe(GuiContainer prevgui, ArrayList<IUsageHandler> handlers) {
super(prevgui);
currenthandlers = handlers;
}
public static void registerUsageHandler(IUsageHandler handler) {
final Class<? extends IUsageHandler> handlerClass = handler.getClass();
if(usagehandlers.stream().anyMatch(h -> h.getClass() == handlerClass) || serialUsageHandlers.stream().anyMatch(h -> h.getClass() == handlerClass))
return;
final String handlerClassStr = handlerClass.getName();
if(NEIClientConfig.serialHandlers.contains(handlerClassStr))
serialUsageHandlers.add(handler);
else
usagehandlers.add(handler);
}
public ArrayList<? extends IRecipeHandler> getCurrentRecipeHandlers() {
return currenthandlers;
}
public ArrayList<IUsageHandler> currenthandlers;
public static ArrayList<IUsageHandler> usagehandlers = new ArrayList<>();
public static ArrayList<IUsageHandler> serialUsageHandlers = new ArrayList<>();
}
-156
View File
@@ -1,156 +0,0 @@
package codechicken.nei.recipe;
import codechicken.nei.NEIClientConfig;
import codechicken.nei.drawable.DrawableBuilder;
import codechicken.nei.drawable.DrawableResource;
import cpw.mods.fml.common.FMLLog;
import cpw.mods.fml.common.registry.GameRegistry;
import net.minecraft.item.ItemStack;
import net.minecraft.nbt.JsonToNBT;
import net.minecraft.nbt.NBTBase;
import net.minecraft.nbt.NBTException;
import net.minecraft.nbt.NBTTagCompound;
import org.apache.logging.log4j.Level;
public class HandlerInfo {
public static int DEFAULT_HEIGHT = 65;
public static int DEFAULT_WIDTH = 166;
public static int DEFAULT_MAX_PER_PAGE = 2;
private String handler;
private String modName;
private String modId;
private boolean requiresMod = true;
private String excludedModId;
private String itemId;
private String nbtString;
private int yShift = 0;
private int height = DEFAULT_HEIGHT;
private int width = DEFAULT_WIDTH;
private int maxRecipesPerPage = DEFAULT_MAX_PER_PAGE;
private ItemStack itemStack = null;
private DrawableResource image = null;
public HandlerInfo(String handler, String modName, String modId, boolean requiresMod, String excludedModId) {
this.handler = handler;
this.modName = modName;
this.modId = modId;
this.requiresMod = requiresMod;
this.excludedModId = excludedModId;
}
public void setHandlerDimensions(int height, int width, int maxRecipesPerPage) {
this.height = height;
this.width = width;
this.maxRecipesPerPage = maxRecipesPerPage;
}
public boolean setItem(String itemId, String nbtString) {
if(hasImageOrItem())
return false;
int meta = -1;
if (!itemId.contains(":")) {
NEIClientConfig.logger.info("Item ID missing colon for handler " + handler + " - " + modName);
return false;
}
final String[] split = itemId.split(":");
// ModID:ItemID
String itemLookupId = split[0] + ":" + split[1];
if(split.length >= 3) {
int mIdx = -1;
if (split[2].matches("\\d+")) {
mIdx = 2;
} else {
itemLookupId += ":" + split[2];
if (split.length >= 4) mIdx = 3;
}
if (mIdx != -1) meta = Integer.parseInt(split[mIdx]);
}
if (meta != -1) {
itemStack = GameRegistry.makeItemStack(itemLookupId, meta, 1, nbtString == null ? "" : nbtString);
} else {
itemStack = GameRegistry.findItemStack(split[0], split[1], 1);
if (nbtString != null && !nbtString.equals("")) {
try {
final NBTBase nbttag = JsonToNBT.func_150315_a(nbtString);
if (!(nbttag instanceof NBTTagCompound)) {
NEIClientConfig.logger.info("Unexpected NBT string - multiple values {}", nbtString);
return false;
}
itemStack.setTagCompound((NBTTagCompound) nbttag);
} catch (NBTException e) {
FMLLog.getLogger().log(Level.WARN, "Encountered an exception parsing ItemStack NBT string {}", nbtString, e);
return false;
}
}
}
if (itemStack == null)
NEIClientConfig.logger.info("Couldn't find " + modName + " - " + itemLookupId);
else {
this.itemId = itemId;
this.nbtString = nbtString;
}
return (itemStack != null);
}
public boolean setImage(String resourceLocation, int imageX, int imageY, int imageWidth, int imageHeight) {
if(hasImageOrItem())
return false;
this.image = new DrawableBuilder(resourceLocation, imageX, imageY, imageWidth, imageHeight).build();
return true;
}
public DrawableResource getImage() {
return image;
}
public ItemStack getItemStack() {
return itemStack;
}
public String getModName() {
return modName;
}
public String getModId() {
return modId;
}
public int getHeight() {
return height;
}
public int getWidth() {
return width;
}
public int getMaxRecipesPerPage() {
return Math.max(maxRecipesPerPage, 1);
}
public int getYShift() {
return yShift;
}
public boolean hasImageOrItem() {
if (image != null) return true;
if (itemStack != null) return true;
return false;
}
public void setYShift(int yShift) {
this.yShift = yShift;
}
}
@@ -1,121 +0,0 @@
package codechicken.nei.recipe;
import codechicken.nei.PositionedStack;
import codechicken.nei.api.IOverlayHandler;
import codechicken.nei.api.IRecipeOverlayRenderer;
import net.minecraft.client.gui.inventory.GuiContainer;
import net.minecraft.inventory.Container;
import net.minecraft.item.ItemStack;
import org.lwjgl.input.Keyboard;
import java.util.List;
/**
* Do not implement this. Implement one of it's subinterfaces, either {@link ICraftingHandler} or {@link IUsageHandler}
*/
public interface IRecipeHandler
{
/**
*
* @return The name of this inventory.
* To be displayed at the top of the viewing container.
*/
public String getRecipeName();
/**
*
* @return The number of recipes that this handler contains.
*/
public int numRecipes();
/**
* Draw the background of this recipe handler (basically the slot layout image).
* @param gui A GuiManager for drawing functions.
* @param recipe The recipe index to draw at this position.
*/
public void drawBackground(int recipe);
/**
* Draw the foreground of this recipe handler (for things like progress bars).
* @param gui A GuiManager for drawing functions.
* @param recipe The recipe index to draw at this position.
*/
public void drawForeground(int recipe);
/**
*
* @param recipe The recipe index to get items for.
* @return A list of the ingredient {@link PositionedStack}s in this recipe relative to the top left corner of your recipe drawing space.
*/
public List<PositionedStack> getIngredientStacks(int recipe);
/**
*
* @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.
*/
public List<PositionedStack> getOtherStacks(int recipetype);
/**
*
* @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.
*/
public PositionedStack getResultStack(int recipe);
/**
* A tick function called for updating progress bars and cycling damage items.
*/
public void onUpdate();
/**
*
* @param recipe The recipe index to check for.
* @param gui The GUI to overlay.
* @param container The container of the GUI.
* @return true if this recipe can render an overlay for the specified type of inventory GUI.
*/
public boolean hasOverlay(GuiContainer gui, Container container, int recipe);
/**
*
* @param recipe The recipe index to get the overlay renderer for.
* @return An instance of {@link IRecipeOverlayRenderer} to be used for rendering the overlay of this specific recipe.
*/
public IRecipeOverlayRenderer getOverlayRenderer(GuiContainer gui, int recipe);
/**
*
* @param recipe The recipe index to get the overlay renderer for.
* @return An instance of {@link IOverlayHandler} to be used for rendering the overlay of this specific recipe.
*/
public IOverlayHandler getOverlayHandler(GuiContainer gui, int recipe);
/**
*
* @return The number of recipes that can fit on a page in the viewer (1 or 2)
*/
public int recipiesPerPage();
/**
*
* @param gui An instance of the currentscreen
* @param currenttip The current tooltip, will contain item name and info
* @param recipe The recipe index being handled
* @return The modified tooltip. DO NOT return null
*/
public List<String> handleTooltip(GuiRecipe gui, List<String> currenttip, int recipe);
/**
*
* @param gui An instance of the currentscreen
* @param The itemstack currently under the mouse
* @param The current tooltip, will contain item name and info
* @param recipe The recipe index being handled
* @return The modified tooltip. DO NOT return null
*/
public List<String> handleItemTooltip(GuiRecipe gui, ItemStack stack, List<String> currenttip, int recipe);
/**
*
* @param gui An instance of the currentscreen
* @param keyChar The character representing the keyPress
* @param keyCode The KeyCode as defined in {@link Keyboard}
* @return true to terminate further processing of this event.
*/
public boolean keyTyped(GuiRecipe gui, char keyChar, int keyCode, int recipe);
/**
*
* @param gui An instance of the currentscreen
* @param button The button index being pressed, {0 = Left Click, 1 = Right Click, 2 = Middle Click}
* @return true to terminate further processing of this event.
*/
public boolean mouseClicked(GuiRecipe gui, int button, int recipe);
}
@@ -1,19 +0,0 @@
package codechicken.nei.recipe;
/**
*
* Implement this to show custom recipes in the usage viewer.
* See the default vanilla ones for more info.
*
*/
public interface IUsageHandler extends IRecipeHandler
{
/**
*
* @param inputId A String identifier representing the type of ingredients used. Eg. {"item", "fuel"}
* @param ingredients Objects representing the ingredients that matching recipes must contain.
* @return An instance of {@link IUsageHandler} configured with a list of recipes that contain matching input
*/
public IUsageHandler getUsageHandler(String inputId, Object... ingredients);
}
@@ -1,170 +0,0 @@
package codechicken.nei.recipe;
import codechicken.core.TaskProfiler;
import codechicken.core.TaskProfiler.ProfilerResult;
import codechicken.nei.NEIClientConfig;
import codechicken.nei.NEIClientUtils;
import codechicken.nei.PositionedStack;
import codechicken.nei.api.IOverlayHandler;
import codechicken.nei.api.IRecipeOverlayRenderer;
import net.minecraft.client.gui.inventory.GuiContainer;
import net.minecraft.inventory.Container;
import net.minecraft.item.ItemStack;
import java.text.DecimalFormat;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import static codechicken.lib.gui.GuiDraw.drawString;
import static codechicken.lib.gui.GuiDraw.getStringWidth;
public class ProfilerRecipeHandler implements ICraftingHandler, IUsageHandler
{
private static final TaskProfiler profiler = new TaskProfiler();
public static TaskProfiler getProfiler()
{
profiler.clear();
return profiler;
}
private final boolean crafting;
public ProfilerRecipeHandler(boolean crafting)
{
this.crafting = crafting;
}
@Override
public String getRecipeName()
{
return NEIClientUtils.translate("recipe.profiler."+(crafting ? "crafting" : "usage"));
}
@Override
public int numRecipes()
{
if(!NEIClientConfig.getBooleanSetting("inventory.profileRecipes"))
return 0;
return (int) Math.ceil(((crafting ?
GuiCraftingRecipe.craftinghandlers.size() :
GuiUsageRecipe.usagehandlers.size())-1)/6D);
}
@Override
public void drawBackground(int recipe)
{
}
@Override
public void drawForeground(int recipe)
{
List<ProfilerResult> results = profiler.getResults();
for(Iterator<ProfilerResult> it = results.iterator(); it.hasNext();)
if(it.next().name.equals(getRecipeName()))
it.remove();
results.sort((o1, o2) -> o1.time < o2.time ? 1 : -1);
for(int i = recipe*6; i < results.size() && i < (recipe+1)*6; i++)
{
ProfilerResult r = results.get(i);
int y = (i%6)*20+6;
drawString(r.name, 8, y, 0xFF808080, false);
DecimalFormat format = new DecimalFormat("0.00");
String s = format.format(r.fraction*100)+"%";
if(r.time < 1000000L)
s+= " ("+(r.time/1000)+"us)";
else
s+= " ("+(r.time/1000000)+"ms)";
drawString(s, 156-getStringWidth(s), y+10, 0xFF404040, false);
}
}
@Override
public ArrayList<PositionedStack> getIngredientStacks(int recipe)
{
return new ArrayList<>();
}
@Override
public ArrayList<PositionedStack> getOtherStacks(int recipetype)
{
return new ArrayList<>();
}
@Override
public PositionedStack getResultStack(int recipe)
{
return null;
}
@Override
public void onUpdate()
{
}
@Override
public boolean hasOverlay(GuiContainer gui, Container container, int recipe)
{
return false;
}
@Override
public IRecipeOverlayRenderer getOverlayRenderer(GuiContainer gui, int recipe)
{
return null;
}
@Override
public IOverlayHandler getOverlayHandler(GuiContainer gui, int recipe)
{
return null;
}
@Override
public int recipiesPerPage()
{
return 1;
}
@Override
public List<String> handleTooltip(GuiRecipe gui, List<String> currenttip, int recipe)
{
return currenttip;
}
@Override
public List<String> handleItemTooltip(GuiRecipe gui, ItemStack stack, List<String> currenttip, int recipe)
{
return currenttip;
}
@Override
public boolean keyTyped(GuiRecipe gui, char keyChar, int keyCode, int recipe)
{
return false;
}
@Override
public boolean mouseClicked(GuiRecipe gui, int button, int recipe)
{
return false;
}
@Override
public IUsageHandler getUsageHandler(String inputId, Object... ingredients)
{
return this;
}
@Override
public ICraftingHandler getRecipeHandler(String outputId, Object... results)
{
return this;
}
}
-123
View File
@@ -1,123 +0,0 @@
package codechicken.nei.recipe;
import codechicken.nei.OffsetPositioner;
import codechicken.nei.api.API;
import codechicken.nei.api.IOverlayHandler;
import codechicken.nei.api.IStackPositioner;
import com.google.common.base.Objects;
import net.minecraft.client.gui.inventory.GuiBrewingStand;
import net.minecraft.client.gui.inventory.GuiContainer;
import net.minecraft.client.gui.inventory.GuiCrafting;
import net.minecraft.client.gui.inventory.GuiFurnace;
import net.minecraft.client.gui.inventory.GuiInventory;
import java.util.HashMap;
public class RecipeInfo
{
private static class OverlayKey
{
final String ident;
final Class<? extends GuiContainer> guiClass;
public OverlayKey(Class<? extends GuiContainer> classz, String ident)
{
this.guiClass = classz;
this.ident = ident;
}
@Override
public boolean equals(Object obj)
{
if(!(obj instanceof OverlayKey))
return false;
OverlayKey key = (OverlayKey)obj;
return Objects.equal(ident, key.ident) && guiClass == key.guiClass;
}
@Override
public int hashCode()
{
return Objects.hashCode(ident, guiClass);
}
}
static final HashMap<OverlayKey, IOverlayHandler> overlayMap = new HashMap<>();
static final HashMap<OverlayKey, IStackPositioner> positionerMap = new HashMap<>();
static final HashMap<Class<? extends GuiContainer>, int[]> offsets = new HashMap<>();
public static void registerOverlayHandler(Class<? extends GuiContainer> classz, IOverlayHandler handler, String ident)
{
overlayMap.put(new OverlayKey(classz, ident), handler);
}
public static void registerGuiOverlay(Class<? extends GuiContainer> classz, String ident, IStackPositioner positioner)
{
positionerMap.put(new OverlayKey(classz, ident), positioner);
if(positioner instanceof OffsetPositioner && !offsets.containsKey(classz))
{
OffsetPositioner p = (OffsetPositioner)positioner;
setGuiOffset(classz, p.offsetx, p.offsety);
}
}
public static void setGuiOffset(Class<? extends GuiContainer> classz, int x, int y)
{
offsets.put(classz, new int[]{x, y});
}
public static boolean hasDefaultOverlay(GuiContainer gui, String ident)
{
return positionerMap.containsKey(new OverlayKey(gui.getClass(), ident));
}
public static boolean hasOverlayHandler(GuiContainer gui, String ident)
{
return overlayMap.containsKey(new OverlayKey(gui.getClass(), ident));
}
public static IOverlayHandler getOverlayHandler(GuiContainer gui, String ident)
{
return overlayMap.get(new OverlayKey(gui.getClass(), ident));
}
public static IStackPositioner getStackPositioner(GuiContainer gui, String ident)
{
return positionerMap.get(new OverlayKey(gui.getClass(), ident));
}
public static int[] getGuiOffset(GuiContainer gui)
{
int[] offset = offsets.get(gui.getClass());
return offset == null ? new int[]{5, 11} : offset;
}
public static void load()
{
API.registerRecipeHandler(new ShapedRecipeHandler());
API.registerUsageHandler(new ShapedRecipeHandler());
API.registerRecipeHandler(new ShapelessRecipeHandler());
API.registerUsageHandler(new ShapelessRecipeHandler());
API.registerRecipeHandler(new FireworkRecipeHandler());
API.registerUsageHandler(new FireworkRecipeHandler());
API.registerRecipeHandler(new FurnaceRecipeHandler());
API.registerUsageHandler(new FurnaceRecipeHandler());
API.registerRecipeHandler(new BrewingRecipeHandler());
API.registerUsageHandler(new BrewingRecipeHandler());
API.registerRecipeHandler(new FuelRecipeHandler());
API.registerUsageHandler(new FuelRecipeHandler());
API.registerGuiOverlay(GuiCrafting.class, "crafting");
API.registerGuiOverlay(GuiInventory.class, "crafting2x2", 63, 20);
API.registerGuiOverlay(GuiFurnace.class, "smelting");
API.registerGuiOverlay(GuiFurnace.class, "fuel");
API.registerGuiOverlay(GuiBrewingStand.class, "brewing");
API.registerGuiOverlayHandler(GuiCrafting.class, new DefaultOverlayHandler(), "crafting");
API.registerGuiOverlayHandler(GuiInventory.class, new DefaultOverlayHandler(63, 20), "crafting2x2");
API.registerGuiOverlayHandler(GuiBrewingStand.class, new BrewingOverlayHandler(), "brewing");
API.registerRecipeHandler(new ProfilerRecipeHandler(true));
API.registerUsageHandler(new ProfilerRecipeHandler(false));
}
}
@@ -1,90 +0,0 @@
package codechicken.nei.recipe;
import codechicken.nei.ItemPanels;
import codechicken.nei.NEIClientConfig;
import codechicken.nei.NEIClientUtils;
import codechicken.nei.guihook.GuiContainerManager;
import codechicken.nei.guihook.IContainerInputHandler;
import net.minecraft.client.gui.inventory.GuiContainer;
import net.minecraft.item.ItemStack;
public class RecipeItemInputHandler implements IContainerInputHandler
{
@Override
public boolean lastKeyTyped(GuiContainer gui, char keyChar, int keyCode)
{
ItemStack stackover = GuiContainerManager.getStackMouseOver(gui);
if(stackover == null)
return false;
if(keyCode == NEIClientConfig.getKeyBinding("gui.usage") || (keyCode == NEIClientConfig.getKeyBinding("gui.recipe") && NEIClientUtils.shiftKey()))
return GuiUsageRecipe.openRecipeGui("item", stackover.copy());
if(keyCode == NEIClientConfig.getKeyBinding("gui.recipe"))
return GuiCraftingRecipe.openRecipeGui("item", stackover.copy());
if(keyCode == NEIClientConfig.getKeyBinding("gui.bookmark")) {
NEIClientConfig.logger.debug("Adding or removing {} from bookmarks", stackover.getDisplayName());
ItemPanels.bookmarkPanel.addOrRemoveItem(stackover.copy());
}
return false;
}
@Override
public boolean mouseClicked(GuiContainer gui, int mousex, int mousey, int button)
{
ItemStack stackover = GuiContainerManager.getStackMouseOver(gui);
if(stackover == null)
return false;
if (!(gui instanceof GuiRecipe))
return false;
if(button == 0)
return GuiCraftingRecipe.openRecipeGui("item", stackover.copy());
if(button == 1)
return GuiUsageRecipe.openRecipeGui("item", stackover.copy());
return false;
}
@Override
public void onKeyTyped(GuiContainer gui, char keyChar, int keyID)
{
}
@Override
public void onMouseClicked(GuiContainer gui, int mousex, int mousey, int button)
{
}
@Override
public void onMouseUp(GuiContainer gui, int mousex, int mousey, int button)
{
}
@Override
public boolean keyTyped(GuiContainer gui, char keyChar, int keyID)
{
return false;
}
@Override
public boolean mouseScrolled(GuiContainer gui, int mousex, int mousey, int scrolled)
{
return false;
}
@Override
public void onMouseScrolled(GuiContainer gui, int mousex, int mousey, int scrolled)
{
}
@Override
public void onMouseDragged(GuiContainer gui, int mousex, int mousey, int button, long heldTime)
{
}
}
-158
View File
@@ -1,158 +0,0 @@
package codechicken.nei.util;
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import com.google.gson.JsonArray;
import com.google.gson.JsonElement;
import com.google.gson.JsonObject;
import com.google.gson.JsonParser;
import com.google.gson.JsonPrimitive;
import net.minecraft.nbt.NBTBase;
import net.minecraft.nbt.NBTTagByte;
import net.minecraft.nbt.NBTTagByteArray;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.nbt.NBTTagDouble;
import net.minecraft.nbt.NBTTagFloat;
import net.minecraft.nbt.NBTTagInt;
import net.minecraft.nbt.NBTTagIntArray;
import net.minecraft.nbt.NBTTagList;
import net.minecraft.nbt.NBTTagLong;
import net.minecraft.nbt.NBTTagShort;
import net.minecraft.nbt.NBTTagString;
import java.io.ByteArrayOutputStream;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.stream.IntStream;
public class NBTJson {
private static final Pattern numberPattern = Pattern.compile("^([-+]?[\\d]+\\.?[0-9]*)([bBsSlLfFdD]?)$");
private static final JsonParser parser = new JsonParser();
private static final Gson gson = new GsonBuilder().create();
public static String toJson(NBTTagCompound tag) {
final String jsonString = toJsonObject(tag).toString();
return gson.toJson(parser.parse(jsonString));
}
@SuppressWarnings("unchecked")
public static JsonElement toJsonObject(NBTBase nbt) {
if (nbt instanceof NBTTagCompound) {
// NBTTagCompound
final NBTTagCompound nbtTagCompound = (NBTTagCompound) nbt;
final Map<String, NBTBase> tagMap = (Map<String, NBTBase>)nbtTagCompound.tagMap;
JsonObject root = new JsonObject();
for (Map.Entry<String, NBTBase> nbtEntry : tagMap.entrySet() ) {
root.add(nbtEntry.getKey(), toJsonObject(nbtEntry.getValue()));
}
return root;
} else if (nbt instanceof NBTBase.NBTPrimitive) {
// Number
return new JsonPrimitive(((NBTBase.NBTPrimitive) nbt).func_150286_g());
} else if (nbt instanceof NBTTagString) {
// String
return new JsonPrimitive(((NBTTagString) nbt).func_150285_a_());
} else if (nbt instanceof NBTTagList) {
// Tag List
JsonArray arr = new JsonArray();
((NBTTagList) nbt).tagList.forEach(c -> arr.add(toJsonObject((NBTBase) c)));
return arr;
} else if (nbt instanceof NBTTagIntArray) {
// Int Array
JsonArray arr = new JsonArray();
for(int i : ((NBTTagIntArray) nbt).func_150302_c()) {
arr.add(new JsonPrimitive(i));
}
return arr;
} else if (nbt instanceof NBTTagByteArray) {
// Byte Array
JsonArray arr = new JsonArray();
for(int i : ((NBTTagByteArray) nbt).func_150292_c()) {
arr.add(new JsonPrimitive(i));
}
return arr;
} else {
throw new IllegalArgumentException("Unsupported NBT Tag: " + NBTBase.NBTTypes[nbt.getId()] + " - " + nbt);
}
}
public static NBTBase toNbt(JsonElement jsonElement) {
if (jsonElement instanceof JsonPrimitive) {
// Number or String
final JsonPrimitive jsonPrimitive = (JsonPrimitive) jsonElement;
final String jsonString = jsonPrimitive.getAsString();
final Matcher m = numberPattern.matcher(jsonString);
if(m.find()) {
// Number
final String numberString = m.group(1);
if (m.groupCount() == 2 && m.group(2).length() > 0) {
final char numberType = m.group(2).charAt(0);
switch(numberType) {
case 'b':
case 'B':
return new NBTTagByte(Byte.parseByte(numberString));
case 's':
case 'S':
return new NBTTagShort(Short.parseShort(numberString));
case 'l':
case 'L':
return new NBTTagLong(Long.parseLong(numberString));
case 'f':
case 'F':
return new NBTTagFloat(Float.parseFloat(numberString));
case 'd':
case 'D':
return new NBTTagDouble(Double.parseDouble(numberString));
}
} else {
if (numberString.contains("."))
return new NBTTagDouble(Double.parseDouble(numberString));
else
return new NBTTagInt(Integer.parseInt(numberString));
}
} else {
// String
return new NBTTagString(jsonString);
}
} else if (jsonElement instanceof JsonArray) {
// NBTTagIntArray or NBTTagList
final JsonArray jsonArray = (JsonArray) jsonElement;
final List<NBTBase> nbtList = new ArrayList<>();
for (JsonElement element : jsonArray) {
nbtList.add(toNbt(element));
}
if (nbtList.stream().allMatch(n -> n instanceof NBTTagInt)) {
return new NBTTagIntArray(nbtList.stream().mapToInt(i -> ((NBTTagInt)i).func_150287_d() ).toArray());
} else if (nbtList.stream().allMatch(n -> n instanceof NBTTagByte)) {
return new NBTTagByteArray(toByteArray(nbtList.stream().mapToInt(i -> ((NBTTagInt)i).func_150287_d() )));
} else {
NBTTagList nbtTagList = new NBTTagList();
nbtList.forEach(nbtTagList::appendTag);
return nbtTagList;
}
} else if (jsonElement instanceof JsonObject) {
// NBTTagCompound
final JsonObject jsonObject = (JsonObject) jsonElement;
NBTTagCompound nbtTagCompound = new NBTTagCompound();
for (Map.Entry<String, JsonElement> jsonEntry : jsonObject.entrySet()) {
nbtTagCompound.setTag(jsonEntry.getKey(), toNbt(jsonEntry.getValue()));
}
return nbtTagCompound;
}
throw new IllegalArgumentException("Unhandled element " + jsonElement);
}
public static byte[] toByteArray(IntStream stream) {
return stream.collect(ByteArrayOutputStream::new, (baos, i) -> baos.write((byte) i), (baos1, baos2) -> baos1.write(baos2.toByteArray(), 0, baos2.size()))
.toByteArray();
}
}
+47
View File
@@ -0,0 +1,47 @@
lexer grammar SearchExpressionLexer;
// Antlr4 generates imports with .*
@header {
// CHECKSTYLE:OFF
import codechicken.nei.SearchTokenParser;
}
@members {
private SearchTokenParser searchParser;
public SearchExpressionLexer(CharStream input, SearchTokenParser searchParser) {
this(input);
this.searchParser = searchParser;
}
}
// Lexer rules
REGEX_LEFT : 'r'? '/' -> pushMode(REGEX) ;
QUOTE_LEFT : '"' -> pushMode(QUOTED) ;
DASH : '-' ;
RECIPE_INGREDIENTS : '<&' | '<' ;
RECIPE_RESULT : '>&' | '>' ;
RECIPE_OTHERS : '^&' | '^' ;
OR : '|' ;
LEFT_BRACKET : '{' ;
RIGHT_BRACKET : '}' ;
NEWLINE_OR_TAB : [\t\r\n] -> skip ;
SPACE : ' ' ;
ESCAPED_SYMBOL : '\\' . ;
PREFIX : CLEAN_SYMBOL {searchParser.hasRedefinedPrefix(getText().charAt(0))}? ;
CLEAN_SYMBOL : ~[-<>^{}|/\\ "] ;
mode REGEX;
REGEX_CONTENT : (~[/] | '\\/')+ ;
REGEX_RIGHT : '/' -> popMode ;
mode QUOTED;
QUOTED_CONTENT : (~["] | '\\"')+ ;
QUOTE_RIGHT : '"' -> popMode ;
+73
View File
@@ -0,0 +1,73 @@
parser grammar SearchExpressionParser;
// Antlr4 generates imports with .*
@header {
// CHECKSTYLE:OFF
}
options { tokenVocab=SearchExpressionLexer; }
// Parser rules
// Should only be used for recipes. Thanks to antlr inability to properly
// inherit grammars, this is included where it's not supposed to be
recipeSearchExpression
: recipeClauseExpression*
;
recipeClauseExpression
: ingredientsPrefix=RECIPE_INGREDIENTS searchExpression[0, $ingredientsPrefix.getText().length() > 1]
| resultPrefix=RECIPE_RESULT searchExpression[1, $resultPrefix.getText().length() > 1]
| othersPrefix=RECIPE_OTHERS searchExpression[2, $othersPrefix.getText().length() > 1]
| searchExpression[3, false]
;
// General search expression rules
searchExpression[int type, boolean allRecipe]
: orExpression
;
orExpression
: sequenceExpression (OR sequenceExpression)*
;
sequenceExpression
: (SPACE* unaryExpression SPACE*)+
;
unaryExpression
: LEFT_BRACKET orExpression RIGHT_BRACKET?
| prefixedExpression
| negateExpression
| token['\0']
;
negateExpression
: DASH unaryExpression
;
prefixedExpression
locals [
Character prefix
]
: prefixToken=PREFIX { $prefix = $prefixToken.getText().charAt(0); } token[$prefix]
;
token[Character prefix]
: regex[prefix]
| quoted[prefix]
| plainText
;
regex[Character prefix]
: REGEX_LEFT REGEX_CONTENT REGEX_RIGHT?
;
quoted[Character prefix]
: QUOTE_LEFT QUOTED_CONTENT QUOTE_RIGHT?
;
plainText
: (CLEAN_SYMBOL | ESCAPED_SYMBOL)+
;
@@ -0,0 +1,151 @@
package codechicken.nei;
import net.minecraft.client.gui.inventory.GuiContainer;
import net.minecraft.item.ItemStack;
import org.lwjgl.opengl.GL11;
import codechicken.lib.vec.Rectangle4i;
import codechicken.nei.ItemsGrid.ItemsGridSlot;
import codechicken.nei.api.GuiInfo;
import codechicken.nei.api.INEIGuiHandler;
import codechicken.nei.api.ShortcutInputHandler;
import codechicken.nei.drawable.DrawableBuilder;
import codechicken.nei.drawable.DrawableResource;
import codechicken.nei.guihook.IContainerTooltipHandler;
import codechicken.nei.recipe.GuiRecipe;
public abstract class AbstractSubpanel<T extends ItemsGrid<? extends ItemsGridSlot, ? extends ItemsGrid.MouseContext>>
extends Widget implements IContainerTooltipHandler {
final DrawableResource DASH = new DrawableBuilder("nei:textures/dash.png", 0, 0, 6, 1).setTextureSize(6, 1).build();
protected int mouseDownItemIndex = -1;
protected int splittingLineColor = 0xffffffff;
protected int linePaddingStart = 0;
protected T grid;
public boolean isEmpty() {
return this.grid.isEmpty();
}
public void draw(int mousex, int mousey) {
drawSplittingLine();
this.grid.draw(mousex, mousey);
}
public void update() {
this.grid.update();
}
public abstract int setPanelWidth(int width);
public void resize(GuiContainer gui) {
this.grid.setGridSize(x, y + 4, w, h - 8);
this.grid.refresh(gui);
}
@Override
public ItemStack getStackMouseOver(int mousex, int mousey) {
final ItemsGridSlot slot = getSlotMouseOver(mousex, mousey);
return slot == null ? null : slot.getItemStack();
}
public ItemsGridSlot getSlotMouseOver(int mousex, int mousey) {
return this.grid.getSlotMouseOver(mousex, mousey);
}
protected void updateLinePadding() {
final GuiContainer guiContainer = NEIClientUtils.getGuiContainer();
final INEIGuiHandler[] handlers = GuiInfo.getGuiHandlersSnapshot();
final Rectangle4i rect = new Rectangle4i(this.x, this.y - 1, 10, 2);
this.linePaddingStart = 0;
while (this.linePaddingStart < this.w && GuiInfo.hideItemPanelSlot(guiContainer, rect, handlers)) {
this.linePaddingStart += 10;
rect.x += 10;
}
}
protected void drawSplittingLine() {
float alpha = (this.splittingLineColor >> 24 & 255) / 255.0F;
float red = (this.splittingLineColor >> 16 & 255) / 255.0F;
float green = (this.splittingLineColor >> 8 & 255) / 255.0F;
float blue = (this.splittingLineColor & 255) / 255.0F;
int width = this.grid.columns * ItemsGrid.SLOT_SIZE - this.linePaddingStart;
int repeat = width / 6;
int shiftX = this.x + this.linePaddingStart + (this.w - width) / 2;
GL11.glColor4f(red, green, blue, alpha);
for (int i = 0; i < repeat; i++) {
DASH.draw(shiftX + i * 6, this.y);
}
GL11.glColor4f(1, 1, 1, 1);
}
@Override
public void mouseDragged(int mousex, int mousey, int button, long heldTime) {
if (this.mouseDownItemIndex >= 0 && ItemPanels.itemPanel.draggedStack == null
&& NEIClientUtils.getHeldItem() == null
&& NEIClientConfig.hasSMPCounterPart()) {
final ItemsGridSlot mouseOverSlot = getSlotMouseOver(mousex, mousey);
if (mouseOverSlot == null || mouseOverSlot.itemIndex != this.mouseDownItemIndex || heldTime > 500) {
ItemPanels.itemPanel.draggedStack = getDraggedStackWithQuantity(
this.grid.getItem(this.mouseDownItemIndex));
this.mouseDownItemIndex = -1;
}
}
}
@Override
public boolean handleClick(int mousex, int mousey, int button) {
if (handleClickExt(mousex, mousey, button)) return true;
final ItemsGridSlot hoverSlot = this.grid.getSlotMouseOver(mousex, mousey);
if (hoverSlot != null) {
if (button == 2) {
ItemPanels.itemPanel.draggedStack = getDraggedStackWithQuantity(hoverSlot.getItemStack());
} else {
mouseDownItemIndex = hoverSlot.itemIndex;
}
return true;
}
return false;
}
protected abstract ItemStack getDraggedStackWithQuantity(ItemStack itemStack);
public ItemStack getStackMouseOverWithQuantity(int mousex, int mousey) {
final ItemStack hoverSlot = getStackMouseOver(mousex, mousey);
return hoverSlot != null ? getDraggedStackWithQuantity(hoverSlot) : null;
}
@Override
public void mouseUp(int mousex, int mousey, int button) {
final ItemsGridSlot hoverSlot = getSlotMouseOver(mousex, mousey);
if (hoverSlot != null && hoverSlot.itemIndex == this.mouseDownItemIndex
&& ItemPanels.itemPanel.draggedStack == null) {
if (NEIController.manager.window instanceof GuiRecipe || NEIClientUtils.shiftKey()
|| !NEIClientConfig.canCheatItem(hoverSlot.getItemStack())) {
ShortcutInputHandler.handleMouseClick(hoverSlot.getItemStack().copy());
} else {
NEIClientUtils.cheatItem(getDraggedStackWithQuantity(hoverSlot.getItemStack()), button, -1);
}
}
this.mouseDownItemIndex = -1;
}
}
@@ -0,0 +1,180 @@
package codechicken.nei;
import static codechicken.lib.gui.GuiDraw.getMousePosition;
import java.awt.Point;
import java.util.ArrayList;
import java.util.List;
import net.minecraft.client.Minecraft;
import net.minecraft.client.gui.GuiTextField;
import net.minecraft.client.gui.inventory.GuiContainer;
import net.minecraft.client.settings.GameSettings;
import net.minecraft.util.ChatAllowedCharacters;
import org.lwjgl.input.Keyboard;
import codechicken.nei.guihook.GuiContainerManager;
import codechicken.nei.guihook.IContainerInputHandler;
public class AutoFocusWidget implements IContainerInputHandler {
/**
* Implement this interface on a GuiContainer to enable the autofocus search in NEI (if the autofocus option is
* enabled) without needing to add the classname to the config file .
*/
public interface INEIAutoFocusSearchEnable {
}
public static AutoFocusWidget instance = new AutoFocusWidget();
public static List<String> enableAutoFocusPrefixes = new ArrayList<>();
protected boolean autofocus = false;
protected Point mouse;
protected Point pendingMouse;
protected GuiTextField textInputHolder;
public AutoFocusWidget() {
GuiContainerManager.addInputHandler(this);
}
public void load(GuiContainer gui) {
this.autofocus = LayoutManager.searchField.isVisible() && NEIClientConfig.searchWidgetAutofocus() != 0
&& isAllowedGuiAutoSearchFocus(gui);
this.mouse = null;
this.pendingMouse = null;
if (this.autofocus) {
beginTextInput();
}
}
protected void beginTextInput() {
if (this.textInputHolder == null) {
this.textInputHolder = new GuiTextField(Minecraft.getMinecraft().fontRenderer, 0, 0, 0, 0);
}
this.textInputHolder.setFocused(true);
}
protected void endTextInput() {
if (this.textInputHolder != null) {
this.textInputHolder.setFocused(false);
}
}
public void guiTick() {
if (!this.autofocus) {
return;
}
final Point current = getMousePosition();
if (this.mouse == null) {
if (current.equals(this.pendingMouse)) {
this.mouse = current;
}
this.pendingMouse = current;
} else if (!this.mouse.equals(current)) {
cancel();
}
}
protected void cancel() {
if (this.autofocus) {
this.autofocus = false;
endTextInput();
}
}
@Override
public boolean keyTyped(GuiContainer gui, char keyChar, int keyCode) {
if (this.autofocus) {
if (NEIClientConfig.searchWidgetAutofocus() == 2
&& GameSettings.isKeyDown(Minecraft.getMinecraft().gameSettings.keyBindInventory)) {
cancel();
return false;
}
if (keyCode == Keyboard.KEY_RETURN || keyCode == Keyboard.KEY_NUMPADENTER
|| keyCode == Keyboard.KEY_ESCAPE) {
cancel();
return false;
}
if (!ChatAllowedCharacters.isAllowedCharacter(keyChar)) {
return false;
}
this.autofocus = false;
LayoutManager.searchField.setFocus(true);
endTextInput();
final String oldText = LayoutManager.searchField.text();
LayoutManager.searchField.handleKeyPress(keyCode, keyChar);
return !LayoutManager.searchField.text().equals(oldText);
}
return false;
}
@Override
public boolean lastKeyTyped(GuiContainer gui, char keyChar, int keyID) {
return false;
}
@Override
public boolean mouseClicked(GuiContainer gui, int mousex, int mousey, int button) {
cancel();
return false;
}
@Override
public boolean mouseScrolled(GuiContainer gui, int mousex, int mousey, int scrolled) {
cancel();
return false;
}
@Override
public void onKeyTyped(GuiContainer gui, char keyChar, int keyID) {}
@Override
public void onMouseClicked(GuiContainer gui, int mousex, int mousey, int button) {
cancel();
}
@Override
public void onMouseDragged(GuiContainer gui, int mousex, int mousey, int button, long heldTime) {
cancel();
}
@Override
public void onMouseScrolled(GuiContainer gui, int mousex, int mousey, int scrolled) {
cancel();
}
@Override
public void onMouseUp(GuiContainer gui, int mousex, int mousey, int button) {
cancel();
}
protected boolean isAllowedGuiAutoSearchFocus(GuiContainer gui) {
if (gui instanceof INEIAutoFocusSearchEnable) {
return true;
}
String guiClassName = gui.getClass().getName();
for (String prefix : enableAutoFocusPrefixes) {
if (guiClassName.startsWith(prefix)) {
return true;
}
}
return false;
}
}
@@ -0,0 +1,34 @@
package codechicken.nei;
import java.util.HashMap;
import net.minecraft.client.gui.inventory.GuiChest;
import net.minecraft.client.gui.inventory.GuiContainer;
import codechicken.nei.api.API;
import codechicken.nei.api.IBookmarkContainerHandler;
public class BookmarkContainerInfo {
private static final HashMap<Class<? extends GuiContainer>, IBookmarkContainerHandler> handlerMap = new HashMap<>();
public static void registerBookmarkContainerHandler(Class<? extends GuiContainer> classz,
IBookmarkContainerHandler handler) {
handlerMap.put(classz, handler);
}
public static boolean hasBookmarkContainerHandler(Class<? extends GuiContainer> classz) {
return handlerMap.containsKey(classz);
}
public static IBookmarkContainerHandler getBookmarkContainerHandler(GuiContainer gui) {
if (gui != null) {
return handlerMap.get(gui.getClass());
}
return null;
}
public static void load() {
API.registerBookmarkContainerHandler(GuiChest.class, new DefaultBookmarkContainerHandler());
}
}
File diff suppressed because it is too large. Load diff
@@ -1,11 +1,11 @@
package codechicken.nei;
import java.util.List;
import static codechicken.lib.gui.GuiDraw.getStringWidth;
public abstract class Button extends Widget
{
import java.util.List;
public abstract class Button extends Widget {
public Button(String s) {
label = s;
}
@@ -15,7 +15,7 @@ public abstract class Button extends Widget
}
public int contentWidth() {
return getRenderIcon() == null ? getStringWidth(label) : getRenderIcon().width;
return getRenderIcon() == null ? getStringWidth(getRenderLabel()) : getRenderIcon().width;
}
@Override
@@ -25,9 +25,7 @@ public abstract class Button extends Widget
@Override
public boolean handleClick(int mx, int my, int button) {
if (button == 1 || button == 0)
if (onButtonPress(button == 1))
NEIClientUtils.playClickSound();
if (button == 1 || button == 0) if (onButtonPress(button == 1)) NEIClientUtils.playClickSound();
return true;
}
@@ -39,36 +37,35 @@ public abstract class Button extends Widget
@Override
public List<String> handleTooltip(int mx, int my, List<String> tooltip) {
if (!contains(mx, my))
return tooltip;
if (!contains(mx, my)) return tooltip;
final String tip = getButtonTip();
if (tip != null)
tooltip.add(tip);
if (tip != null) tooltip.add(tip);
addTooltips(tooltip);
return tooltip;
}
public String getButtonTip() {
return null;
}
public void addTooltips(List<String> tooltip) {}
public void addTooltips(List<String> tooltip) {}
public String getRenderLabel() {
return label;
}
public int getRenderLabelColor() {
return 0;
}
public final String label;
public Image icon;
/**
* 0x4 = state flag, as opposed to 1 click
* 0 = normal
* 1 = on
* 2 = disabled
* 0x4 = state flag, as opposed to 1 click 0 = normal 1 = on 2 = disabled
*/
public int state;
}
Loaded 100 of 440 files, more files were not shown because too many files have changed in this diff. Show more