From 75895899f49a86d80e345a073af1ce881938c499 Mon Sep 17 00:00:00 2001 From: bruberu <80226372+bruberu@users.noreply.github.com> Date: Sat, 21 Aug 2021 11:39:54 -0500 Subject: [PATCH] Port Clipboard to GT (#44) * Start on clipboard GUI * Complete everything up to the actual rendering * Don't forget the buttons * Remove TileEntity systems, since they're not really needed * Wait, this shouldn't be an MTE :thonk: * Fiddle around with blockstates * Add proper clipboard-placing behavior * Add a clipboard back * Begin movement to MTE, by Yefancy's request * Remove aged TE code * Complete step two of four * A husk of a renderMetaTileEntityDynamic * Fix model rendering * Pull in FakeModularGui and FakeModularUIContainer, and start on a few helper functions * Create a Death Ray * Complete check 3/4 * Fix references to removed class * Tweak clipboard's location * Remove more old code * Get GUI interactivity online! (4/4) :lets: * Add crafting recipe, and fix some minor issues * ...Why was that there? * Fix more various bugs * Fix more bugs * Fix more bugs * Fix non-in-world GUI, and add explainer text to tooltip * Fix certain formatting and extraneous import problems * Fix certain formatting and extraneous import problems * Reformat GregFakePlayer * Yeet ModelCache.java * Keep removing useless imports * Behaviour -> Behavior (as per Tech's request) * Implement @Tech22's suggestions * Continue transition to behavior * Apply all of Kila's suggestions that could be simply implemented * Fix up ClipboardBehavior.java * Fix up MetaTileEntityClipboard.java * Continue removing unnecessary checks from PlayerInventoryHolder.java * Add Max's textures! * Squashed commit of the following: commit 713fd9e2c64ff981b318f201966ee7ab450a0424 Author: ALongStringOfNumbers <31759736+ALongStringOfNumbers@users.noreply.github.com> Date: Fri Aug 20 23:33:54 2021 -0700 Fix for null materials being entered into the washedIn pair (#98) commit e0d55c8ce2cdfd245125cfc959887d083eac28f3 Author: ALongStringOfNumbers <31759736+ALongStringOfNumbers@users.noreply.github.com> Date: Fri Aug 20 22:59:08 2021 -0700 Allow specifying the amount of fluid for chemical bath processing (#97) commit 98e3befed157f56ac3859ee19d4a8b0954fed113 Author: froot <66188216+kumquat-ir@users.noreply.github.com> Date: Fri Aug 20 22:38:12 2021 -0700 Material Tree JEI page returns (#66) commit 0f6c8b7f800791d30ee98c77814c533731868765 Author: KilaBash Date: Sat Aug 21 13:11:31 2021 +0800 GuideBook stuff (#46) commit 63adb22f554e72115c27131c2d0756004eab1ef5 Author: ALongStringOfNumbers <31759736+ALongStringOfNumbers@users.noreply.github.com> Date: Fri Aug 20 22:05:50 2021 -0700 Fix infinite Energy emitter decrement amperage not working (#94) commit f0c9a841c883fc9a87f57a3cfb7bbc7021986b79 Author: DStrand1 Date: Fri Aug 20 23:54:37 2021 -0500 fix oilsands recipe commit 0dc9f97a5758d6dfe123b4d8d2cd993626362633 Author: ALongStringOfNumbers <31759736+ALongStringOfNumbers@users.noreply.github.com> Date: Fri Aug 20 21:44:06 2021 -0700 Fix Infinite Emitter breaking particles (#93) commit f8f1284d6da7a7607dfe3856cdfe18ea40434b8f Author: DStrand1 Date: Fri Aug 20 23:08:35 2021 -0500 remove multi fluid pipes for Wood commit 0672a79fb4c92ea8b3b4c14ac1c36e8e0eb2e641 Author: DStrand1 Date: Fri Aug 20 22:21:01 2021 -0500 fix primitive multis workable fix diamond composition commit c50fdb272f84ba6f251d39a70f395c07a957b28a Author: BraggestSage833 <46819052+BraggestSage833@users.noreply.github.com> Date: Fri Aug 20 23:18:33 2021 -0400 fix the default output side on quantum tanks/chest (#92) commit 5c464537fe6f115266cda3e22e23bdf16ed37221 Author: PrototypeTrousers Date: Fri Aug 20 23:24:16 2021 -0300 "Better Idling" for MTEs (#91) Co-authored-by: Exa <11907282+Exaxxion@users.noreply.github.com> commit 835b5b9da923d22d826595e3b211498d73f14246 Author: DStrand1 Date: Fri Aug 20 21:12:55 2021 -0500 make battery tooltips better commit 78e37f755b8c452e3c18ccd81c871697fb9354cb Author: Tech22 Date: Fri Aug 20 03:53:31 2021 -0400 add tiered superconductors commit 4eb9133e25eeb2b1b86bbef410cf374a6353d05d Author: DStrand1 Date: Fri Aug 20 02:13:06 2021 -0500 add new EV-UV batteries commit 1e6ff1ebcbb9e7b1e6a7f824ad01f0425d8811dc Author: DStrand1 Date: Fri Aug 20 01:00:52 2021 -0500 remove line from build.gradle commit 312c188175afd8a5e4cfe4e424a24b9b3d636202 Author: DStrand1 Date: Thu Aug 19 19:39:11 2021 -0500 fix log warning about missing recipe property commit d76afa3c4aa7a3bdac550ee7bac5905d13400d38 Author: Rongmario Date: Thu Aug 19 07:32:25 2021 +0100 Add config to turn on/off GT adding loot (#87) commit 4fa4e3f57a91213f36b7f0a6c03f56396cd1d149 Author: brachy84 <45517902+brachy84@users.noreply.github.com> Date: Thu Aug 19 08:30:20 2021 +0200 Fix issue from #80 (#88) commit c7e9f84e368ef1d7ee8354b88c0a4d883f7c4b62 Author: brachy84 <45517902+brachy84@users.noreply.github.com> Date: Thu Aug 19 08:27:07 2021 +0200 Pipefixes (#80) * i forgor release() commit aba97f094c3a92f7ce7332a2148cf48919db6594 Author: DStrand1 Date: Wed Aug 18 23:23:30 2021 -0500 clean out dead prefixes (will cause ID shift) commit 0bbdc6542670b0a5a9007b87f73310514ac90302 Author: DStrand1 Date: Wed Aug 18 23:21:03 2021 -0500 clean up current batteries commit b59f0dc859f2d1121d85886732b722b76b243587 Author: DStrand1 Date: Wed Aug 18 22:13:06 2021 -0500 finish Supercon value on WireProperty commit 5018bbedac00daf0f47e5afb207ebd13461728bc Author: DStrand1 Date: Tue Aug 17 23:24:12 2021 -0500 add some missing iconset files from gregicality commit ce2d5febfe8c334d7ff141a9dbbd7aa42d3acf28 Author: DStrand1 Date: Tue Aug 17 22:39:13 2021 -0500 add `heat` getter to fusion reactor commit 3e599b5156eae971e7fdf86dbdb2d86ba3d34930 Author: DStrand1 Date: Tue Aug 17 20:50:58 2021 -0500 remove ExNi stuff (in Gregification) commit 0cb6427133f7a9eea3789aa84d50161c462c6fef Author: Dane Strandboge Date: Tue Aug 17 01:21:31 2021 -0500 Primitive Multi Rewrite (#85) * new PBF working * implement primitive recipes * finish PBF * refactor Coke Oven * update changelog * fix tech memeing on me commit 61a52dbb2337e31ee9a5183d3a8251c105c0fdcc Author: DStrand1 Date: Mon Aug 16 21:47:28 2021 -0500 update changelog for #75 commit d51ae3e0b76826c962d224725b258c6095aa3867 Author: bruberu <80226372+bruberu@users.noreply.github.com> Date: Mon Aug 16 21:46:42 2021 -0500 Add Highlighting to the Crafting Station (#75) commit 36ef03982dda421870e2f9f5e12b33bad7981b8f Author: DStrand1 Date: Mon Aug 16 21:03:29 2021 -0500 relocate `RecipeMapSteamMultiblockController` commit 13b7827f22611f57a72c88b5ba6b15ac5c238de0 Author: DStrand1 Date: Mon Aug 16 02:00:04 2021 -0500 clean up components, make constructor public commit 77ce62e91effb5369b91794a20d1a97e2e287ddf Author: brachy84 <45517902+brachy84@users.noreply.github.com> Date: Mon Aug 16 08:58:55 2021 +0200 rework creative energy (#84) commit 48b12848628cc79737fd4a02c05712b0836f8602 Author: DStrand1 Date: Mon Aug 16 01:33:26 2021 -0500 add circuit markers to CraftingComponent commit 2100c869ec1cad8fd3b2ad566bd9c099a1813b6a Author: DStrand1 Date: Mon Aug 16 00:55:09 2021 -0500 rework crafting component loading commit 612bc74d22ed9efc9e990156c509e295406436bc Author: Rongmario Date: Mon Aug 16 02:11:59 2021 +0100 De-enumify MaterialIconSet + MaterialIconType (#82) - Names are converted to the right format in the ctor commit 826556ad1fadf19ed721fe2ce74365b947b5aa60 Author: DStrand1 Date: Sun Aug 15 17:11:57 2021 -0500 pull changes from upstream #1710 commit 0ef0b33af613e4593326af41d86a98d91c91cb74 Author: DStrand1 Date: Sun Aug 15 17:08:44 2021 -0500 add some MetaItem MaterialInfos commit 523627d76f2390ea0d23a70418c87077e40c3288 Author: Rongmario Date: Sun Aug 15 16:33:16 2021 +0100 No longer hardcode biomes for primitive water pump (#81) - Now utilizes Forge's BiomeDictionary types - Ocean/River => `Type.WATER` (1000) - Swamp => `Type.SWAMP` and `Type.WET` (800) - Jungle => `Type.JUNGLE` (350) - Snow => `Type.SNOWY` (300) - Plains/Forest => `Type.PLAINS` and `Type.FOREST` (250) - Taiga => `Type.COLD` (175) - Beach => `Type.BEACH` (170) commit 85b3e98bb6ea95703cbb1e5dddedfd46fbe9e333 Author: DStrand1 Date: Sun Aug 15 01:34:08 2021 -0500 update changelog for EnergyNet updates commit 7a9b1db57d47d8552d66b99dda44862facce20ab Author: brachy84 <45517902+brachy84@users.noreply.github.com> Date: Sun Aug 15 08:32:02 2021 +0200 Electric pipes rework (#78) commit 757264a432126cb4be703901c67c3afe9daaa999 Author: BraggestSage833 <46819052+BraggestSage833@users.noreply.github.com> Date: Sun Aug 15 02:17:23 2021 -0400 reinstate metaArmor classes (#79) commit 11ecde267d5b66eeac199fce931c42d4b05e70a3 Author: DStrand1 Date: Sun Aug 15 00:57:00 2021 -0500 remove energy field projector, cleanup commit 73f6bdc9fcd103c235a2c3fe0cc4a874fd866f26 Author: DStrand1 Date: Sat Aug 14 22:38:35 2021 -0500 update changelog for buffers commit dc81fa8947860508ab8f5b905e7cebc634f80dc6 Author: DStrand1 Date: Sat Aug 14 22:37:29 2021 -0500 port the Buffer to CEu commit fa1b388a4e15f85357db84e236cab00804376de4 Author: DStrand1 Date: Sat Aug 14 19:59:18 2021 -0500 pull changes from upstream #1701 commit 2bede3b403d98755efb2b2b1ee09c033f8e90b3c Author: DStrand1 Date: Sat Aug 14 19:48:36 2021 -0500 merge changes from upstream #1709 commit db8a4a94c8f445b3ce4a551ef6a85706116eb000 Author: Tech22 Date: Sat Aug 14 20:45:52 2021 -0400 change isotope element symbols to a dash commit 6eff9e6bf5f8407fd3611278c0a0e82740480979 Author: DStrand1 Date: Sat Aug 14 19:45:39 2021 -0500 fix Water missing fluid tooltip commit ecae98a388ec75f1349a1de7f5e170ca7b347fa6 Author: DStrand1 Date: Sat Aug 14 19:14:34 2021 -0500 add `.chancedOutputs` builder call for List commit 5a403541c1a02b9505c22f512db7656c587e9090 Author: DStrand1 Date: Sat Aug 14 18:08:29 2021 -0500 add some missing material flags commit 59fb179b13309f1d7da251c349e3f1a542811116 Author: DStrand1 Date: Sat Aug 14 14:43:23 2021 -0500 buff Indium (small over tiny dust) commit 6f828573ecbb5d22addbf5c975fc532e3f6ddd4c Author: Tech22 Date: Sat Aug 14 12:49:04 2021 -0400 change distillation EUt to reflect config commit 9e10cf273c49a29191cbd1b0fac14fc84b02040e Author: DStrand1 Date: Sat Aug 14 02:27:23 2021 -0500 add more changes, fix some mistakes commit 82fb2546e35ca6519cf385268bf5a9452d99d1a1 Author: Dane Strandboge Date: Sat Aug 14 02:03:55 2021 -0500 fix some changelog mistakes commit 4289c6589a9e3db82ff35569bc67f8feae5e2d57 Author: DStrand1 Date: Sat Aug 14 02:01:26 2021 -0500 add GTCEu changelog (probably missed something) commit 90c4e2fde3a1136599c4e165db5e9b2a8b9938f2 Author: DStrand1 Date: Sat Aug 14 00:55:44 2021 -0500 fix DT outputs sometimes on wrong layers commit 859bcb99a432bed96d0402f6c70287e12fdedf29 Author: brachy84 <45517902+brachy84@users.noreply.github.com> Date: Sat Aug 14 07:03:57 2021 +0200 Fluid pipes rework, MultiFluid Pipes (#53) commit ba74b2f71aebaf030784685c6f71c89d8f240c77 Author: Rongmario Date: Fri Aug 13 21:56:25 2021 +0100 Made material tool enchantability not implicitly tied to icon sets (#76) * Made material tool enchantability not implicitly tied to icon sets - Nano Saber gets 33 enchantability, it inherited platinum's enchantability before but right now platinum doesn't have the tool property - Deprecated old static helper method to get a material enchantability (delete outright?) * Remove deprecated method commit 1b3c24112e9b98eed37eb31133a6e70018582958 Author: Tech22 Date: Fri Aug 13 02:58:17 2021 -0400 infinite water cover tweaks commit 9a7af7d463c8f11f054cc6017e5a841609615c58 Author: Tech22 Date: Fri Aug 13 02:30:35 2021 -0400 add recipes to adjustables, simple washer commit d4b0dfa3e3166a81caf913f51d8956cdfbb298af Author: DStrand1 Date: Fri Aug 13 01:22:47 2021 -0500 add infinite water cover commit 664bd32ab946b96a90ed419a4ef86f743522f629 Author: Tech22 Date: Fri Aug 13 00:44:57 2021 -0400 add simple washer commit 807092abb4a393a63283b7be89691840139d83c6 Author: DStrand1 Date: Thu Aug 12 23:42:24 2021 -0500 Revert "remove RecipeMap minimums" This reverts commit 201c564b510a778c154bfec9b03e9ab88d87d1c7. commit 806dfd21c36e4a946cb68e1a5b978d480167edcc Author: DStrand1 Date: Thu Aug 12 22:08:39 2021 -0500 small cleanup on OreProperty commit bf2e3976ba3337ea31fed21bcaddc9b2772b5c29 Author: DStrand1 Date: Thu Aug 12 22:06:24 2021 -0500 require DustProperty for oreByProducts commit eb03b825cf6dff659614abc91be2f29be7301997 Author: DStrand1 Date: Thu Aug 12 21:57:28 2021 -0500 port Native EU to FE commit d1bceee12d78073c24601e9cf9f4701ab30ec05b Author: DStrand1 Date: Thu Aug 12 21:39:32 2021 -0500 port Diodes from Gregicality commit 3c4a9cf2d6094ce8484817eb12ceb6d816888c12 Author: DStrand1 Date: Thu Aug 12 21:06:28 2021 -0500 Squashed commit of the following: commit 22cf3164da2ca2c2d9baf2c0fa20c386aa861cc3 Author: DStrand1 Date: Thu Aug 12 21:05:58 2021 -0500 Revert "clean up duplicated code in energy hatch" This reverts commit 44b1b7f746dfc4551a078029c4df8811af4750a8. commit 44b1b7f746dfc4551a078029c4df8811af4750a8 Author: DStrand1 Date: Thu Aug 12 20:07:39 2021 -0500 clean up duplicated code in energy hatch commit 016376420385061837d3ba957966f990fa77379a Author: Tech22 Date: Thu Aug 12 15:51:32 2021 -0400 adjustable energy hatches commit 6acee8685ef6975176f107a723eca20b905c512d Author: Tech22 Date: Thu Aug 12 14:57:21 2021 -0400 adjustable transformers commit 45e27fa221abe8191d0eb1f707670e33597c5554 Author: Tech22 Date: Thu Aug 12 03:28:29 2021 -0400 fix off-centered lignite gem texture commit 254ea67091920f0223e1e707b055f2c6e73b50aa Author: Tech22 Date: Thu Aug 12 03:26:32 2021 -0400 better coke oven jei page commit 19ce5157287becff8285442ab81094b1c4464039 Author: DStrand1 Date: Thu Aug 12 02:05:19 2021 -0500 add method for addons to register MTEs easily commit f0c75f2db1419765200156b72125d784eec0b2e0 Author: DStrand1 Date: Thu Aug 12 00:19:46 2021 -0500 merge material changes from multi PR commit 308d43659dbf92a0862e3b47d22e7b8e7eab5141 Author: DStrand1 Date: Wed Aug 11 23:06:11 2021 -0500 more code cleanup commit 3789f4b569cf133fb5348b67b36cc786ca15ca15 Author: DStrand1 Date: Wed Aug 11 22:40:41 2021 -0500 clean up configs a bit commit 052fd4eef6a48b175fc625753dc341724a7cb4b5 Author: DStrand1 Date: Wed Aug 11 20:36:08 2021 -0500 add registration, CT method commit b6cad8cd54834ddd62692bea7e2495fe540d8b34 Author: DStrand1 Date: Wed Aug 11 20:30:45 2021 -0500 port MetaOreDictItem commit c1e978085979b53d1f12b836254c8a582158b82a Author: DStrand1 Date: Wed Aug 11 19:58:54 2021 -0500 make addOrePrefix take varargs commit afe3e353f1a74fb529543423a9a9b46b70d47ea1 Author: DStrand1 Date: Wed Aug 11 19:54:46 2021 -0500 make `addOrePrefix` public commit 09600d227030e266e084afb13cf31c371b63b08f Author: DStrand1 Date: Wed Aug 11 19:30:58 2021 -0500 make OrePrefix constructor public commit cde0631e469d8266ffef1898ed977875c379aa3f Author: Tech22 Date: Wed Aug 11 18:59:45 2021 -0400 fix extra facade material recipes being registered commit 292ff214ef05a3fa5b6f71ce3feb1b2d82af75ea Author: Tech22 Date: Wed Aug 11 18:47:10 2021 -0400 use dimension names for gas collector property commit 189f6458bbcc15138e49a6555f984938dc4b7d87 Author: Tech22 Date: Wed Aug 11 10:41:27 2021 -0400 fix missing resource location commit 724b20ec068df578837916be465cb6391ccd8b36 Author: Tech22 Date: Wed Aug 11 10:36:10 2021 -0400 add missing components to H2S and FeCl3 commit 18c4373aa4e8e7329c536e07ea7e0aa32ba89641 Author: Tech22 Date: Wed Aug 11 02:19:53 2021 -0400 prevent DT jei page overlaps commit 201c564b510a778c154bfec9b03e9ab88d87d1c7 Author: DStrand1 Date: Wed Aug 11 01:20:18 2021 -0500 remove RecipeMap minimums commit 9a307e10138de2937a0250844e3dc2b8ed1e8f17 Author: TechLord22 <37029404+TechLord22@users.noreply.github.com> Date: Wed Aug 11 01:30:34 2021 -0400 Add Cryogenic Air Recipes (#74) commit d1a5619d58cc4d0046c4e3edef3f353317eaaf8b Author: DStrand1 Date: Tue Aug 10 23:58:21 2021 -0500 clean up tool classes impl commit 41ff7ce843cb1b620ef5a36a542ceccb8a5f4f5d Author: BraggestSage833 <46819052+BraggestSage833@users.noreply.github.com> Date: Wed Aug 11 00:51:19 2021 -0400 Update ToolWrench.java (#70) commit cdd99234beb7611cd0787addb55fc0b84a64f7c7 Author: DStrand1 Date: Tue Aug 10 23:46:33 2021 -0500 clean up steam-era recipe duration and EUt commit e53885d870706dd03d72af29db2d11de7cdf9b3c Author: DStrand1 Date: Tue Aug 10 23:19:16 2021 -0500 :monkey: dust blocks :monkey: commit 81f2eef6a9f6af6dd718d35ec886995e20974491 Author: DStrand1 Date: Tue Aug 10 23:13:29 2021 -0500 rename bricked steel hull commit 8f5ad1df8e1cab3f21666afb6ec8dff841b66302 Author: DStrand1 Date: Tue Aug 10 22:58:53 2021 -0500 make steam great again commit 346ce2ceb8789e60057205837c3127f4030e24dd Author: DStrand1 Date: Tue Aug 10 21:05:59 2021 -0500 rework Steam Machine logic commit 8288ff0f6d1cb49ebda3cac16a4263ead468cf4a Author: DStrand1 Date: Tue Aug 10 20:22:02 2021 -0500 wipe recipe cache on multiblock deformation commit f1e6a956df487c17230793c029bf83c1bd182adb Author: Tech22 Date: Tue Aug 10 19:10:51 2021 -0400 make NaOH not power positive, change cumene to consume H3PO4 commit b37cdf2e3c4b7a2b73db881c26c0c92886fa9587 Author: DStrand1 Date: Mon Aug 9 22:49:04 2021 -0500 fix issues in UniversalDistillationBuilder commit 30cf93ccd3f6f81bee442e48ebcb22e3b3ee7798 Author: BraggestSage833 <46819052+BraggestSage833@users.noreply.github.com> Date: Mon Aug 9 20:28:52 2021 -0400 Quantum Tanks/Chests can now disallow input from their export face via screwdriver (#69) commit 95d1f58c202cc257b6ccefa0eba9165776e2f9bb Author: Tech22 Date: Mon Aug 9 18:54:31 2021 -0400 fix crate guis commit a4634bd877020371dfdea795d99d1d4a8420db11 Author: Tech22 Date: Mon Aug 9 17:56:17 2021 -0400 fix drum TOP display commit b1ac5e5338c5804d76086789f9876b1032195656 Author: Tech22 Date: Mon Aug 9 02:23:41 2021 -0400 add toolstats to Flint commit a22aa3587c3d0b880ba198d058a11d8b88a187ea Author: Tech22 Date: Mon Aug 9 02:12:04 2021 -0400 fix missing filter and crate recipes commit 019ed5349f9f5035849bf4caa9bc879e137baee4 Author: DStrand1 Date: Mon Aug 9 01:04:54 2021 -0500 remove ULV from overclock button commit 98a6ca6552f710a5c4008aa8144da7baa891bb46 Author: TechLord22 <37029404+TechLord22@users.noreply.github.com> Date: Mon Aug 9 02:04:08 2021 -0400 Add Gas Collectors (#68) * add dimension-specific gas collectors commit 17d8f742f317d3ae4ada4f3d243215ca9a63313c Author: Tech22 Date: Mon Aug 9 01:53:14 2021 -0400 add polished stone autoclave recipes commit 90b8e041f5483a91d008aacdada61c55626017dd Author: DStrand1 Date: Mon Aug 9 00:25:49 2021 -0500 trim lossless wire configs commit 4f36d36b2e3235fdfa9464bcae3d303e288a9fbf Author: DStrand1 Date: Mon Aug 9 00:16:30 2021 -0500 clean up MetaTileEntities commit 161a216a3b98d8a94612e7eb63f0bce48315eaf9 Author: DStrand1 Date: Sun Aug 8 23:12:45 2021 -0500 add UV-UXV circuit assembler lang keys commit a65bbaa4ba779a428061b520498a4fab97e22dce Author: DStrand1 Date: Sun Aug 8 22:05:16 2021 -0500 fix crash on furnace recipe removal commit 932be0f8786e574c49485f165bc7489c6e4ced0d Author: DStrand1 Date: Sun Aug 8 21:57:13 2021 -0500 add debug logging to recipe removals commit 7f557a9bf2b4efe571ca44cae46fa7879ef5405c Author: DStrand1 Date: Sun Aug 8 21:09:03 2021 -0500 config to disable in-world concrete commit 2cd6159e7b8197a1bb3ab308e0df7fb7cf840fdb Author: ALongStringOfNumbers <31759736+ALongStringOfNumbers@users.noreply.github.com> Date: Sun Aug 8 18:29:28 2021 -0700 A bunch of small cleanups (#67) * Slight cleanup of unused constructors Slight fix to Assembly Line JEI page Remove Legacy method of specifying surface rocks * Fix typo in Electric Furnace recipe map localization * compatibility * Fix remaining issues Co-authored-by: Yefancy --- .../api/block/machines/BlockMachine.java | 1 - .../java/gregtech/api/cover/ICoverable.java | 4 + .../java/gregtech/api/gui/GuiTextures.java | 6 + src/main/java/gregtech/api/gui/Widget.java | 18 +- .../gregtech/api/gui/impl/FakeModularGui.java | 123 +++++ .../gui/widgets/ImageCycleButtonWidget.java | 149 +++++++ .../api/gui/widgets/ImageTextFieldWidget.java | 33 ++ .../api/gui/widgets/SimpleTextWidget.java | 17 +- .../api/gui/widgets/TextFieldWidget.java | 20 + .../api/items/gui/PlayerInventoryHolder.java | 9 +- .../InaccessibleItemStackHandler.java | 22 + .../api/metatileentity/MetaTileEntity.java | 3 + .../metatileentity/MetaTileEntityHolder.java | 10 +- .../MetaTileEntityUIFactory.java | 1 - .../java/gregtech/api/net/NetworkHandler.java | 30 ++ .../net/PacketClipboardUIWidgetUpdate.java | 28 ++ .../api/render/ClipboardRenderer.java | 109 +++++ .../java/gregtech/api/render/Textures.java | 7 +- .../java/gregtech/api/util/GTUtility.java | 11 + .../gregtech/api/util/GregFakePlayer.java | 85 +++- .../java/gregtech/api/util/RenderUtil.java | 11 +- .../impl/FakeModularUIContainerClipboard.java | 127 ++++++ .../java/gregtech/common/items/MetaItem1.java | 2 +- .../java/gregtech/common/items/MetaItems.java | 2 + .../items/behaviors/ClipboardBehavior.java | 257 +++++++++++ .../metatileentities/MetaTileEntities.java | 4 + .../MetaTileEntityClipboard.java | 421 ++++++++++++++++++ .../common/render/WrenchOverlayRenderer.java | 6 + .../loaders/recipe/CraftingRecipeLoader.java | 2 + .../gregtech/blockstates/clipboard.json | 10 + .../resources/assets/gregtech/lang/en_us.lang | 5 + .../gregtech/models/block/clipboard.json | 97 ++++ .../models/item/metaitems/clipboard.json | 94 ++++ .../textures/blocks/clipboard/clip.png | Bin 0 -> 343 bytes .../textures/blocks/clipboard/page.png | Bin 0 -> 139 bytes .../textures/blocks/clipboard/wood.png | Bin 0 -> 438 bytes .../gregtech/textures/gui/base/blank.png | Bin 0 -> 119 bytes .../textures/gui/widget/clipboard_button.png | Bin 0 -> 7214 bytes .../gui/widget/clipboard_checkbox.png | Bin 0 -> 721 bytes .../gui/widget/clipboard_text_box.png | Bin 0 -> 5637 bytes .../gregtech/textures/gui/widget/left.png | Bin 0 -> 288 bytes .../gregtech/textures/gui/widget/right.png | Bin 0 -> 297 bytes .../items/metaitems/clipboard/clipboard.png | Bin 0 -> 495 bytes .../items/metaitems/clipboard/page.png | Bin 0 -> 336 bytes 44 files changed, 1689 insertions(+), 35 deletions(-) create mode 100644 src/main/java/gregtech/api/gui/impl/FakeModularGui.java create mode 100644 src/main/java/gregtech/api/gui/widgets/ImageCycleButtonWidget.java create mode 100644 src/main/java/gregtech/api/gui/widgets/ImageTextFieldWidget.java create mode 100644 src/main/java/gregtech/api/items/itemhandlers/InaccessibleItemStackHandler.java create mode 100644 src/main/java/gregtech/api/net/PacketClipboardUIWidgetUpdate.java create mode 100644 src/main/java/gregtech/api/render/ClipboardRenderer.java create mode 100644 src/main/java/gregtech/common/gui/impl/FakeModularUIContainerClipboard.java create mode 100644 src/main/java/gregtech/common/items/behaviors/ClipboardBehavior.java create mode 100644 src/main/java/gregtech/common/metatileentities/MetaTileEntityClipboard.java create mode 100644 src/main/resources/assets/gregtech/blockstates/clipboard.json create mode 100644 src/main/resources/assets/gregtech/models/block/clipboard.json create mode 100644 src/main/resources/assets/gregtech/models/item/metaitems/clipboard.json create mode 100644 src/main/resources/assets/gregtech/textures/blocks/clipboard/clip.png create mode 100644 src/main/resources/assets/gregtech/textures/blocks/clipboard/page.png create mode 100644 src/main/resources/assets/gregtech/textures/blocks/clipboard/wood.png create mode 100644 src/main/resources/assets/gregtech/textures/gui/base/blank.png create mode 100644 src/main/resources/assets/gregtech/textures/gui/widget/clipboard_button.png create mode 100644 src/main/resources/assets/gregtech/textures/gui/widget/clipboard_checkbox.png create mode 100644 src/main/resources/assets/gregtech/textures/gui/widget/clipboard_text_box.png create mode 100644 src/main/resources/assets/gregtech/textures/gui/widget/left.png create mode 100644 src/main/resources/assets/gregtech/textures/gui/widget/right.png create mode 100644 src/main/resources/assets/gregtech/textures/items/metaitems/clipboard/clipboard.png create mode 100644 src/main/resources/assets/gregtech/textures/items/metaitems/clipboard/page.png diff --git a/src/main/java/gregtech/api/block/machines/BlockMachine.java b/src/main/java/gregtech/api/block/machines/BlockMachine.java index 419d3754d50..876d9eae530 100755 --- a/src/main/java/gregtech/api/block/machines/BlockMachine.java +++ b/src/main/java/gregtech/api/block/machines/BlockMachine.java @@ -84,7 +84,6 @@ public BlockMachine() { setHardness(6.0f); setResistance(6.0f); setTranslationKey("unnamed"); - setHarvestLevel("wrench", 1); setDefaultState(getDefaultState().withProperty(OPAQUE, true)); } diff --git a/src/main/java/gregtech/api/cover/ICoverable.java b/src/main/java/gregtech/api/cover/ICoverable.java index 061223ca08f..0157a00c632 100644 --- a/src/main/java/gregtech/api/cover/ICoverable.java +++ b/src/main/java/gregtech/api/cover/ICoverable.java @@ -198,4 +198,8 @@ static Cuboid6 getCoverPlateBox(EnumFacing side, double plateThickness) { throw new UnsupportedOperationException(); } } + + public default boolean canRenderMachineGrid() { + return true; + } } diff --git a/src/main/java/gregtech/api/gui/GuiTextures.java b/src/main/java/gregtech/api/gui/GuiTextures.java index 207062eb83f..0f54787ef42 100644 --- a/src/main/java/gregtech/api/gui/GuiTextures.java +++ b/src/main/java/gregtech/api/gui/GuiTextures.java @@ -15,6 +15,7 @@ public class GuiTextures { public static final TextureArea BORDERED_BACKGROUND = AdoptableTextureArea.fullImage("textures/gui/base/bordered_background.png", 195, 136, 4, 4); public static final TextureArea BOXED_BACKGROUND = AdoptableTextureArea.fullImage("textures/gui/base/boxed_background.png", 256, 174, 11, 11); + public static final TextureArea BLANK = AdoptableTextureArea.fullImage("textures/gui/base/blank.png", 1, 1, 0, 0); public static final TextureArea DISPLAY = TextureArea.fullImage("textures/gui/base/display.png"); public static final TextureArea FLUID_SLOT = AdoptableTextureArea.fullImage("textures/gui/base/fluid_slot.png", 18, 18, 1, 1); public static final TextureArea FLUID_TANK_BACKGROUND = TextureArea.fullImage("textures/gui/base/fluid_tank_background.png"); @@ -22,6 +23,7 @@ public class GuiTextures { public static final TextureArea SLOT = AdoptableTextureArea.fullImage("textures/gui/base/slot.png", 18, 18, 1, 1); public static final TextureArea SLOT_DARKENED = TextureArea.fullImage("textures/gui/base/darkened_slot.png"); + //FLUID & ITEM OUTPUT BUTTONS public static final TextureArea BLOCKS_INPUT = TextureArea.fullImage("textures/gui/widget/button_blocks_input.png"); public static final TextureArea BUTTON = TextureArea.fullImage("textures/gui/widget/button.png"); @@ -32,8 +34,12 @@ public class GuiTextures { public static final TextureArea BUTTON_FILTER_NBT = TextureArea.fullImage("textures/gui/widget/button_filter_nbt.png"); public static final TextureArea BUTTON_FLUID_OUTPUT = TextureArea.fullImage("textures/gui/widget/button_fluid_output.png"); public static final TextureArea BUTTON_ITEM_OUTPUT = TextureArea.fullImage("textures/gui/widget/button_item_output.png"); + public static final TextureArea BUTTON_LEFT = TextureArea.fullImage("textures/gui/widget/left.png"); public static final TextureArea BUTTON_OVERCLOCK = TextureArea.fullImage("textures/gui/widget/button_overclock.png"); + public static final TextureArea BUTTON_RIGHT = TextureArea.fullImage("textures/gui/widget/right.png"); public static final TextureArea BUTTON_SWITCH_VIEW = TextureArea.fullImage("textures/gui/widget/button_switch_view.png"); + public static final TextureArea CLIPBOARD_BUTTON = TextureArea.fullImage("textures/gui/widget/clipboard_button.png"); + public static final SizedTextureArea CLIPBOARD_TEXT_BOX = AdoptableTextureArea.fullImage("textures/gui/widget/clipboard_text_box.png", 9, 18, 1, 1); public static final TextureArea DISTRIBUTION_MODE = TextureArea.fullImage("textures/gui/widget/button_distribution_mode.png"); public static final TextureArea LOCK = TextureArea.fullImage("textures/gui/widget/lock.png"); public static final TextureArea SWITCH = TextureArea.fullImage("textures/gui/widget/switch.png"); diff --git a/src/main/java/gregtech/api/gui/Widget.java b/src/main/java/gregtech/api/gui/Widget.java index efdc9688432..81d52b17ba0 100644 --- a/src/main/java/gregtech/api/gui/Widget.java +++ b/src/main/java/gregtech/api/gui/Widget.java @@ -275,7 +275,7 @@ protected void writeClientAction(int id, Consumer packetBufferWrit } @SideOnly(Side.CLIENT) - protected void drawBorder(int x, int y, int width, int height, int stroke, int stroke_width) { + public void drawBorder(int x, int y, int width, int height, int stroke, int stroke_width) { drawGradientRect(x - stroke_width, y - stroke_width, width + 2 * stroke_width, stroke_width, stroke, stroke); drawGradientRect(x - stroke_width, y + height, width + 2 * stroke_width, stroke_width, stroke, stroke); drawGradientRect(x - stroke_width, y - stroke_width, stroke_width, height + 2 * stroke_width, stroke, stroke); @@ -283,7 +283,7 @@ protected void drawBorder(int x, int y, int width, int height, int stroke, int s } @SideOnly(Side.CLIENT) - protected void drawHoveringText(ItemStack itemStack, List tooltip, int maxTextWidth, int mouseX, int mouseY) { + public void drawHoveringText(ItemStack itemStack, List tooltip, int maxTextWidth, int mouseX, int mouseY) { Minecraft mc = Minecraft.getMinecraft(); GuiUtils.drawHoveringText(itemStack, tooltip, mouseX, mouseY, sizes.getScreenWidth(), @@ -291,7 +291,7 @@ protected void drawHoveringText(ItemStack itemStack, List tooltip, int m } @SideOnly(Side.CLIENT) - protected void drawStringSized(String text, double x, double y, int color, boolean dropShadow, float scale, boolean center) { + public void drawStringSized(String text, double x, double y, int color, boolean dropShadow, float scale, boolean center) { GlStateManager.pushMatrix(); FontRenderer fontRenderer = Minecraft.getMinecraft().fontRenderer; double scaledTextWidth = center ? fontRenderer.getStringWidth(text) * scale : 0.0; @@ -302,7 +302,7 @@ protected void drawStringSized(String text, double x, double y, int color, boole } @SideOnly(Side.CLIENT) - protected void drawStringFixedCorner(String text, double x, double y, int color, boolean dropShadow, float scale) { + public void drawStringFixedCorner(String text, double x, double y, int color, boolean dropShadow, float scale) { FontRenderer fontRenderer = Minecraft.getMinecraft().fontRenderer; double scaledWidth = fontRenderer.getStringWidth(text) * scale; double scaledHeight = fontRenderer.FONT_HEIGHT * scale; @@ -310,7 +310,7 @@ protected void drawStringFixedCorner(String text, double x, double y, int color, } @SideOnly(Side.CLIENT) - protected static void drawItemStack(ItemStack itemStack, int x, int y, @Nullable String altTxt) { + public static void drawItemStack(ItemStack itemStack, int x, int y, @Nullable String altTxt) { GlStateManager.pushMatrix(); GlStateManager.translate(0.0F, 0.0F, 32.0F); GlStateManager.color(1F, 1F, 1F, 1F); @@ -331,7 +331,7 @@ protected static void drawItemStack(ItemStack itemStack, int x, int y, @Nullable } @SideOnly(Side.CLIENT) - protected static List getItemToolTip(ItemStack itemStack) { + public static List getItemToolTip(ItemStack itemStack) { Minecraft mc = Minecraft.getMinecraft(); ITooltipFlag flag = mc.gameSettings.advancedItemTooltips ? ITooltipFlag.TooltipFlags.ADVANCED : ITooltipFlag.TooltipFlags.NORMAL; List tooltip = itemStack.getTooltip(mc.player, flag); @@ -346,7 +346,7 @@ protected static List getItemToolTip(ItemStack itemStack) { } @SideOnly(Side.CLIENT) - protected static void drawSelectionOverlay(int x, int y, int width, int height) { + public static void drawSelectionOverlay(int x, int y, int width, int height) { GlStateManager.disableDepth(); GlStateManager.colorMask(true, true, true, false); drawGradientRect(x, y, width, height, -2130706433, -2130706433); @@ -356,14 +356,14 @@ protected static void drawSelectionOverlay(int x, int y, int width, int height) } @SideOnly(Side.CLIENT) - protected static void drawSolidRect(int x, int y, int width, int height, int color) { + public static void drawSolidRect(int x, int y, int width, int height, int color) { Gui.drawRect(x, y, x + width, y + height, color); GlStateManager.color(1.0f, 1.0f, 1.0f, 1.0f); GlStateManager.enableBlend(); } @SideOnly(Side.CLIENT) - protected static void drawGradientRect(int x, int y, int width, int height, int startColor, int endColor) { + public static void drawGradientRect(int x, int y, int width, int height, int startColor, int endColor) { drawGradientRect(x, y, width, height, startColor, endColor, false); } diff --git a/src/main/java/gregtech/api/gui/impl/FakeModularGui.java b/src/main/java/gregtech/api/gui/impl/FakeModularGui.java new file mode 100644 index 00000000000..5698981d9b0 --- /dev/null +++ b/src/main/java/gregtech/api/gui/impl/FakeModularGui.java @@ -0,0 +1,123 @@ +package gregtech.api.gui.impl; + +import gregtech.api.gui.IRenderContext; +import gregtech.api.gui.ModularUI; +import gregtech.api.gui.Widget; +import gregtech.api.util.RenderUtil; +import gregtech.common.gui.impl.FakeModularUIContainerClipboard; +import net.minecraft.client.Minecraft; +import net.minecraft.client.gui.FontRenderer; +import net.minecraft.client.renderer.GlStateManager; +import net.minecraft.client.util.ITooltipFlag; +import net.minecraft.inventory.Slot; +import net.minecraft.item.ItemStack; +import net.minecraft.network.PacketBuffer; +import net.minecraft.util.text.TextFormatting; +import net.minecraftforge.fml.client.config.GuiUtils; +import net.minecraftforge.fml.relauncher.Side; +import net.minecraftforge.fml.relauncher.SideOnly; + +import java.util.List; +import java.util.Optional; + +import static gregtech.api.gui.impl.ModularUIGui.*; + +@SideOnly(Side.CLIENT) +public class FakeModularGui implements IRenderContext { + public final ModularUI modularUI; + public FakeModularUIContainerClipboard container; + protected Minecraft mc; + protected FontRenderer fr; + + public FakeModularGui(ModularUI modularUI, FakeModularUIContainerClipboard fakeModularUIContainer){ + this.modularUI = modularUI; + this.container = fakeModularUIContainer; + this.modularUI.updateScreenSize(this.modularUI.getWidth(), this.modularUI.getHeight()); + this.mc = Minecraft.getMinecraft(); + this.fr = mc.fontRenderer; + } + + public void updateScreen() { + modularUI.guiWidgets.values().forEach(Widget::updateScreen); + } + + public void handleWidgetUpdate(int windowId, int widgetId, PacketBuffer updateData) { + if (windowId == container.windowId) { + Widget widget = modularUI.guiWidgets.get(Optional.of(widgetId)); + int updateId = updateData.readVarInt(); + if (widget != null) { + widget.readUpdateInfo(updateId, updateData); + } + } + } + + public void drawScreen(double x, double y, float partialTicks) { + float halfW = modularUI.getWidth() / 2f; + float halfH = modularUI.getHeight() / 2f; + float scale = 0.5f / Math.max(halfW, halfH); + int mouseX = (int) ((x / scale) + (halfW > halfH? 0: (halfW - halfH))); + int mouseY = (int) ((y / scale) + (halfH > halfW? 0: (halfH - halfW))); + + GlStateManager.translate(-scale * halfW, -scale * halfH, 0.01); + GlStateManager.scale(scale, scale, 1); + GlStateManager.depthMask(false); + + drawGuiContainerBackgroundLayer(partialTicks, mouseX, mouseY); + + GlStateManager.scale(1, 1, 0); + drawGuiContainerForegroundLayer(mouseX, mouseY); + + for (int i = 0; i < this.container.inventorySlots.size(); ++i) { + Slot slot = this.container.inventorySlots.get(i); + if (!slot.getStack().isEmpty() && slot.xPos < mouseX && mouseX < slot.xPos + 18 && slot.yPos < mouseY && mouseY < slot.yPos + 18) { + Widget.drawSolidRect(slot.xPos, slot.yPos, 18, 18, 0X8fffffff); + renderToolTip(slot.getStack(), slot.xPos, slot.yPos); + } + } + + GlStateManager.depthMask(true); + GlStateManager.color(1.0f, 1.0f, 1.0f); + GlStateManager.disableLighting(); + } + + protected void renderToolTip(ItemStack stack, int x, int y) { + FontRenderer font = stack.getItem().getFontRenderer(stack); + GuiUtils.preItemToolTip(stack); + GuiUtils.drawHoveringText(this.getItemToolTip(stack), x, y, modularUI.getScreenWidth(), modularUI.getScreenHeight(), -1, (font == null ? fr : font)); + net.minecraftforge.fml.client.config.GuiUtils.postItemToolTip(); + } + + protected List getItemToolTip(ItemStack itemStack) { + List list = itemStack.getTooltip(mc.player, mc.gameSettings.advancedItemTooltips ? ITooltipFlag.TooltipFlags.ADVANCED : ITooltipFlag.TooltipFlags.NORMAL); + list.set(0, itemStack.getItem().getForgeRarity(itemStack).getColor() + list.get(0)); + for (int i = 1; i < list.size(); ++i) { + list.set(i, TextFormatting.GRAY + list.get(i)); + } + return list; + } + + public void drawGuiContainerBackgroundLayer(float partialTicks, int mouseX, int mouseY) { + GlStateManager.color(rColorForOverlay, gColorForOverlay, bColorForOverlay, 1.0F); + modularUI.backgroundPath.draw(0, 0, modularUI.getWidth(), modularUI.getHeight()); + for (Widget widget : modularUI.guiWidgets.values()) { + GlStateManager.pushMatrix(); + GlStateManager.color(1.0f, 1.0f, 1.0f); + GlStateManager.enableBlend(); + widget.drawInBackground(mouseX, mouseY, this); + GlStateManager.popMatrix(); + } + } + + public void drawGuiContainerForegroundLayer(int mouseX, int mouseY) { + for (Widget widget : modularUI.guiWidgets.values()) { + GlStateManager.pushMatrix(); + GlStateManager.color(1.0f, 1.0f, 1.0f); + widget.drawInForeground(mouseX, mouseY); + GlStateManager.popMatrix(); + } + } + + public boolean mouseClicked(int mouseX, int mouseY, int mouseButton) { + return modularUI.guiWidgets.values().stream().anyMatch(widget -> widget.mouseClicked(mouseX, mouseY, mouseButton)); + } +} diff --git a/src/main/java/gregtech/api/gui/widgets/ImageCycleButtonWidget.java b/src/main/java/gregtech/api/gui/widgets/ImageCycleButtonWidget.java new file mode 100644 index 00000000000..3af8493ca4a --- /dev/null +++ b/src/main/java/gregtech/api/gui/widgets/ImageCycleButtonWidget.java @@ -0,0 +1,149 @@ +package gregtech.api.gui.widgets; + +import gregtech.api.gui.GuiTextures; +import gregtech.api.gui.IRenderContext; +import gregtech.api.gui.Widget; +import gregtech.api.gui.resources.SizedTextureArea; +import gregtech.api.gui.resources.TextureArea; +import gregtech.api.util.GTUtility; +import gregtech.api.util.Position; +import gregtech.api.util.Size; +import gregtech.api.util.function.BooleanConsumer; +import net.minecraft.client.Minecraft; +import net.minecraft.client.gui.FontRenderer; +import net.minecraft.client.renderer.GlStateManager; +import net.minecraft.client.resources.I18n; +import net.minecraft.item.ItemStack; +import net.minecraft.network.PacketBuffer; +import net.minecraft.util.IStringSerializable; +import net.minecraft.util.math.MathHelper; +import net.minecraftforge.fml.relauncher.Side; +import net.minecraftforge.fml.relauncher.SideOnly; + +import java.util.Arrays; +import java.util.List; +import java.util.function.*; + +public class ImageCycleButtonWidget extends Widget { + + protected TextureArea buttonTexture; + private int textColor = 0xFFFFFF; + private IntSupplier currentOptionSupplier; + private IntConsumer setOptionExecutor; + private int optionCount; + private final int RIGHT_MOUSE = 1; + protected int currentOption; + protected String tooltipHoverString; + protected long hoverStartTime = -1L; + protected boolean isMouseHovered; + + public ImageCycleButtonWidget(int xPosition, int yPosition, int width, int height, TextureArea buttonTexture, int optionCount, IntSupplier currentOptionSupplier, IntConsumer setOptionExecutor) { + super(new Position(xPosition, yPosition), new Size(width, height)); + this.buttonTexture = buttonTexture; + this.currentOptionSupplier = currentOptionSupplier; + this.setOptionExecutor = setOptionExecutor; + this.optionCount = optionCount; + } + + + public ImageCycleButtonWidget(int xPosition, int yPosition, int width, int height, TextureArea buttonTexture, int optionCount, BooleanSupplier supplier, BooleanConsumer updater) { + super(new Position(xPosition, yPosition), new Size(width, height)); + this.buttonTexture = buttonTexture; + this.currentOptionSupplier = () -> supplier.getAsBoolean() ? 1 : 0; + this.setOptionExecutor = (value) -> updater.apply(value >= 1); + this.optionCount = optionCount; + } + + public ImageCycleButtonWidget setTooltipHoverString(String hoverString) { + this.tooltipHoverString = hoverString; + return this; + } + + public ImageCycleButtonWidget setButtonTexture(TextureArea texture) { + this.buttonTexture = texture; + return this; + } + + public ImageCycleButtonWidget setTextColor(int textColor) { + this.textColor = textColor; + return this; + } + + @Override + @SideOnly(Side.CLIENT) + public void drawInBackground(int mouseX, int mouseY, IRenderContext context) { + Position pos = getPosition(); + Size size = getSize(); + if (buttonTexture instanceof SizedTextureArea) { + ((SizedTextureArea) buttonTexture).drawHorizontalCutSubArea(pos.x, pos.y, size.width, size.height, (float)currentOption / optionCount, (float)1 / optionCount); + } else { + buttonTexture.drawSubArea(pos.x, pos.y, size.width, size.height, 0.0, (float)currentOption / optionCount, 1.0, (float)1 / optionCount); + } + } + + @Override + public void drawInForeground(int mouseX, int mouseY) { + boolean isHovered = isMouseOverElement(mouseX, mouseY); + boolean wasHovered = isMouseHovered; + if (isHovered && !wasHovered) { + this.isMouseHovered = true; + this.hoverStartTime = System.currentTimeMillis(); + } else if (!isHovered && wasHovered) { + this.isMouseHovered = false; + this.hoverStartTime = 0L; + } else if (isHovered) { + long timeSinceHover = System.currentTimeMillis() - hoverStartTime; + if (timeSinceHover > 1000L && tooltipHoverString != null) { + List hoverList = Arrays.asList(I18n.format(tooltipHoverString).split("/n")); + drawHoveringText(ItemStack.EMPTY, hoverList, 300, mouseX, mouseY); + } + } + } + + @Override + public void detectAndSendChanges() { + super.detectAndSendChanges(); + if (currentOptionSupplier.getAsInt() != currentOption) { + this.currentOption = currentOptionSupplier.getAsInt(); + writeUpdateInfo(1, buf -> buf.writeVarInt(currentOption)); + } + } + + @Override + public void readUpdateInfo(int id, PacketBuffer buffer) { + super.readUpdateInfo(id, buffer); + if (id == 1) { + this.currentOption = buffer.readVarInt(); + } + } + + @Override + @SideOnly(Side.CLIENT) + public boolean mouseClicked(int mouseX, int mouseY, int button) { + super.mouseClicked(mouseX, mouseY, button); + if (isMouseOverElement(mouseX, mouseY)) { + //Allow only the RMB to reverse cycle + if(button == RIGHT_MOUSE) { + //Wrap from the first option to the last if needed + this.currentOption = currentOption == 0 ? optionCount - 1 : currentOption - 1; + } else { + this.currentOption = (currentOption + 1) % optionCount; + } + writeClientAction(1, buf -> buf.writeVarInt(currentOption)); + playButtonClickSound(); + return true; + } + return false; + } + + + @Override + public void handleClientAction(int id, PacketBuffer buffer) { + super.handleClientAction(id, buffer); + if (id == 1) { + this.currentOption = MathHelper.clamp(buffer.readVarInt(), 0, optionCount); + setOptionExecutor.accept(currentOption); + } + } + +} diff --git a/src/main/java/gregtech/api/gui/widgets/ImageTextFieldWidget.java b/src/main/java/gregtech/api/gui/widgets/ImageTextFieldWidget.java new file mode 100644 index 00000000000..b042e450846 --- /dev/null +++ b/src/main/java/gregtech/api/gui/widgets/ImageTextFieldWidget.java @@ -0,0 +1,33 @@ +package gregtech.api.gui.widgets; + +import gregtech.api.gui.IRenderContext; +import gregtech.api.gui.resources.SizedTextureArea; + +import java.util.function.Consumer; +import java.util.function.Supplier; + +public class ImageTextFieldWidget extends TextFieldWidget { + SizedTextureArea textureArea; + + public ImageTextFieldWidget(int xPosition, int yPosition, int width, int height, SizedTextureArea textureArea, Supplier textSupplier, Consumer textResponder) { + super(xPosition, yPosition, width, height, false, textSupplier, textResponder); + this.textureArea = textureArea; + } + + public ImageTextFieldWidget(int xPosition, int yPosition, int width, int height, SizedTextureArea textureArea, Supplier textSupplier, Consumer textResponder, int maxStringLength) { + super(xPosition, yPosition, width, height, false, textSupplier, textResponder, maxStringLength); + this.textureArea = textureArea; + } + + public ImageTextFieldWidget(int xPosition, int yPosition, int width, int height, SizedTextureArea textureArea, Supplier textSupplier, Consumer textResponder, int maxStringLength, int color) { + this(xPosition, yPosition, width, height, textureArea, textSupplier, textResponder, maxStringLength); + this.textField.setTextColor(color); + } + + + @Override + public void drawInBackground(int mouseX, int mouseY, IRenderContext context) { + this.textureArea.drawHorizontalCutArea(this.getPosition().x - 2, this.getPosition().y, this.getSize().width, this.getSize().height); + super.drawInBackground(mouseX, mouseY, context); + } +} diff --git a/src/main/java/gregtech/api/gui/widgets/SimpleTextWidget.java b/src/main/java/gregtech/api/gui/widgets/SimpleTextWidget.java index 9135d98dde0..5bca44fa6e2 100644 --- a/src/main/java/gregtech/api/gui/widgets/SimpleTextWidget.java +++ b/src/main/java/gregtech/api/gui/widgets/SimpleTextWidget.java @@ -24,14 +24,12 @@ public class SimpleTextWidget extends Widget { protected final int color; protected final Supplier textSupplier; protected String lastText = ""; + protected boolean isCentered = true; protected boolean clientWidget; protected boolean isShadow; public SimpleTextWidget(int xPosition, int yPosition, String formatLocale, int color, Supplier textSupplier) { - super(new Position(xPosition, yPosition), Size.ZERO); - this.color = color; - this.formatLocale = formatLocale; - this.textSupplier = textSupplier; + this(xPosition, yPosition, formatLocale, color, textSupplier, true); } public SimpleTextWidget(int xPosition, int yPosition, String formatLocale, int color, Supplier textSupplier, boolean clientWidget) { @@ -43,7 +41,7 @@ public SimpleTextWidget(int xPosition, int yPosition, String formatLocale, int c } public SimpleTextWidget(int xPosition, int yPosition, String formatLocale, Supplier textSupplier) { - this(xPosition, yPosition, formatLocale, 0x404040, textSupplier); + this(xPosition, yPosition, formatLocale, 0x404040, textSupplier, true); } public SimpleTextWidget setShadow(boolean shadow) { @@ -51,6 +49,11 @@ public SimpleTextWidget setShadow(boolean shadow) { return this; } + public SimpleTextWidget setCenter(boolean isCentered) { + this.isCentered = isCentered; + return this; + } + private void updateSize() { FontRenderer fontRenderer = Minecraft.getMinecraft().fontRenderer; int stringWidth = fontRenderer.getStringWidth(lastText); @@ -79,8 +82,8 @@ public void drawInBackground(int mouseX, int mouseY, IRenderContext context) { String text = formatLocale.isEmpty() ? (I18n.hasKey(lastText) ? I18n.format(lastText) : lastText) : I18n.format(formatLocale, lastText); Position position = getPosition(); fontRenderer.drawString(text, - position.x - fontRenderer.getStringWidth(text) / 2f, - position.y - fontRenderer.FONT_HEIGHT / 2f, color, isShadow); + isCentered ? position.x - fontRenderer.getStringWidth(text) / 2 : position.x, + isCentered ? position.y - fontRenderer.FONT_HEIGHT / 2 : position.y, color, isShadow); GlStateManager.color(rColorForOverlay, gColorForOverlay, bColorForOverlay, 1.0F); } diff --git a/src/main/java/gregtech/api/gui/widgets/TextFieldWidget.java b/src/main/java/gregtech/api/gui/widgets/TextFieldWidget.java index 26995fbce86..1f68db69659 100644 --- a/src/main/java/gregtech/api/gui/widgets/TextFieldWidget.java +++ b/src/main/java/gregtech/api/gui/widgets/TextFieldWidget.java @@ -36,6 +36,24 @@ public TextFieldWidget(int xPosition, int yPosition, int width, int height, bool super(new Position(xPosition, yPosition), new Size(width, height)); if (isClientSide()) { this.enableBackground = enableBackground; + FontRenderer fontRenderer = Minecraft.getMinecraft().fontRenderer; + if (enableBackground) { + this.textField = new GuiTextField(0, fontRenderer, xPosition, yPosition, width, height); + } else { + this.textField = new GuiTextField(0, fontRenderer, xPosition + 1, yPosition + (height - fontRenderer.FONT_HEIGHT) / 2 + 1, width - 2, height); + } + this.textField.setCanLoseFocus(true); + this.textField.setEnableBackgroundDrawing(enableBackground); + this.textField.setMaxStringLength(this.maxStringLength); + this.textField.setGuiResponder(MCGuiUtil.createTextFieldResponder(this::onTextChanged)); + } + this.textSupplier = textSupplier; + this.textResponder = textResponder; + } + + public TextFieldWidget(int xPosition, int yPosition, int width, int height, boolean enableBackground, Supplier textSupplier, Consumer textResponder, int maxStringLength) { + super(new Position(xPosition, yPosition), new Size(width, height)); + if (isClientSide()) { FontRenderer fontRenderer = Minecraft.getMinecraft().fontRenderer; if (enableBackground) { this.textField = new GuiTextField(0, fontRenderer, xPosition, yPosition, width, height); @@ -45,6 +63,7 @@ public TextFieldWidget(int xPosition, int yPosition, int width, int height, bool this.textField.setCanLoseFocus(true); this.textField.setEnableBackgroundDrawing(enableBackground); this.textField.setMaxStringLength(maxStringLength); + this.maxStringLength = maxStringLength; this.textField.setGuiResponder(MCGuiUtil.createTextFieldResponder(this::onTextChanged)); } this.textSupplier = textSupplier; @@ -92,6 +111,7 @@ public String getCurrentString() { return this.currentString; } + @Override protected void onPositionUpdate() { if (isClientSide() && textField != null) { diff --git a/src/main/java/gregtech/api/items/gui/PlayerInventoryHolder.java b/src/main/java/gregtech/api/items/gui/PlayerInventoryHolder.java index 84581a2ffff..ac15eb23795 100644 --- a/src/main/java/gregtech/api/items/gui/PlayerInventoryHolder.java +++ b/src/main/java/gregtech/api/items/gui/PlayerInventoryHolder.java @@ -17,7 +17,7 @@ public class PlayerInventoryHolder implements IUIHolder { /*package-local*/ ItemStack sampleItem; @SideOnly(Side.CLIENT) - /*package-local*/ PlayerInventoryHolder(EntityPlayer player, EnumHand hand, ItemStack sampleItem) { + /*package-local*/ public PlayerInventoryHolder(EntityPlayer player, EnumHand hand, ItemStack sampleItem) { this.player = player; this.hand = hand; this.sampleItem = sampleItem; @@ -27,8 +27,6 @@ public PlayerInventoryHolder(EntityPlayer entityPlayer, EnumHand hand) { this.player = entityPlayer; this.hand = hand; this.sampleItem = player.getHeldItem(hand); - Preconditions.checkArgument(sampleItem.getItem() instanceof ItemUIFactory, - "Current Item should implement ItemUIFactory"); } public static void openHandItemUI(EntityPlayer player, EnumHand hand) { @@ -68,11 +66,6 @@ public ItemStack getCurrentItem() { * will also update sample item to this item */ public void setCurrentItem(ItemStack item) { - ItemStack itemStack = player.getHeldItem(hand); - if (!ItemStack.areItemsEqual(sampleItem, itemStack)) - return; - Preconditions.checkArgument(item.getItem() instanceof ItemUIFactory, - "Current Item should implement ItemUIFactory"); this.sampleItem = item; player.setHeldItem(hand, item); } diff --git a/src/main/java/gregtech/api/items/itemhandlers/InaccessibleItemStackHandler.java b/src/main/java/gregtech/api/items/itemhandlers/InaccessibleItemStackHandler.java new file mode 100644 index 00000000000..2044c3fc642 --- /dev/null +++ b/src/main/java/gregtech/api/items/itemhandlers/InaccessibleItemStackHandler.java @@ -0,0 +1,22 @@ +package gregtech.api.items.itemhandlers; + +import net.minecraft.item.ItemStack; +import net.minecraftforge.items.ItemStackHandler; + +import javax.annotation.Nonnull; + +public class InaccessibleItemStackHandler extends ItemStackHandler { + @Nonnull + public ItemStack insertItem(int slot, @Nonnull ItemStack stack, boolean simulate) { + return stack; + } + + @Nonnull + public ItemStack extractItem(int slot, int amount, boolean simulate) { + return ItemStack.EMPTY; + } + + public void setStackInSlot(int slot, ItemStack stack) { + this.stacks.set(slot, stack); + } +} diff --git a/src/main/java/gregtech/api/metatileentity/MetaTileEntity.java b/src/main/java/gregtech/api/metatileentity/MetaTileEntity.java index f690b8a4d39..6809093e3b2 100644 --- a/src/main/java/gregtech/api/metatileentity/MetaTileEntity.java +++ b/src/main/java/gregtech/api/metatileentity/MetaTileEntity.java @@ -1278,4 +1278,7 @@ public boolean keepsInventory() { public boolean getWitherProof() { return false; } + + public void preInit(Object... data) { + } } diff --git a/src/main/java/gregtech/api/metatileentity/MetaTileEntityHolder.java b/src/main/java/gregtech/api/metatileentity/MetaTileEntityHolder.java index 3b34661d759..014ac24481d 100644 --- a/src/main/java/gregtech/api/metatileentity/MetaTileEntityHolder.java +++ b/src/main/java/gregtech/api/metatileentity/MetaTileEntityHolder.java @@ -39,11 +39,15 @@ public MetaTileEntity getMetaTileEntity() { * Sets this holder's current meta tile entity to copy of given one * Note that this method copies given meta tile entity and returns actual instance * so it is safe to call it on sample meta tile entities + * Also can use certain data to preinit the block before data is synced */ - public MetaTileEntity setMetaTileEntity(MetaTileEntity sampleMetaTileEntity) { + public MetaTileEntity setMetaTileEntity(MetaTileEntity sampleMetaTileEntity, Object... data) { Preconditions.checkNotNull(sampleMetaTileEntity, "metaTileEntity"); this.metaTileEntity = sampleMetaTileEntity.createMetaTileEntity(this); this.metaTileEntity.holder = this; + if(data.length != 0) { + this.metaTileEntity.preInit(data); + } this.metaTileEntity.onAttached(); if (hasWorld() && !getWorld().isRemote) { updateBlockOpacity(); @@ -231,8 +235,8 @@ public void onChunkUnload() { } @Override - public boolean shouldRefresh(@Nonnull World world, @Nonnull BlockPos pos, IBlockState oldState, IBlockState newSate) { - return oldState.getBlock() != newSate.getBlock(); //MetaTileEntityHolder should never refresh (until block changes) + public boolean shouldRefresh(@Nonnull World world, @Nonnull BlockPos pos, IBlockState oldState, IBlockState newState) { + return oldState.getBlock() != newState.getBlock(); //MetaTileEntityHolder should never refresh (until block changes) } @Override diff --git a/src/main/java/gregtech/api/metatileentity/MetaTileEntityUIFactory.java b/src/main/java/gregtech/api/metatileentity/MetaTileEntityUIFactory.java index f3351548a03..6a73f9f16c6 100644 --- a/src/main/java/gregtech/api/metatileentity/MetaTileEntityUIFactory.java +++ b/src/main/java/gregtech/api/metatileentity/MetaTileEntityUIFactory.java @@ -25,7 +25,6 @@ public void init() { } @Override - @SuppressWarnings("unchecked") protected ModularUI createUITemplate(MetaTileEntityHolder holder, EntityPlayer entityPlayer) { return holder.getMetaTileEntity().createUI(entityPlayer); } diff --git a/src/main/java/gregtech/api/net/NetworkHandler.java b/src/main/java/gregtech/api/net/NetworkHandler.java index fc8317f51e2..209b55ef4c4 100755 --- a/src/main/java/gregtech/api/net/NetworkHandler.java +++ b/src/main/java/gregtech/api/net/NetworkHandler.java @@ -7,8 +7,10 @@ import gregtech.api.gui.UIFactory; import gregtech.api.gui.impl.ModularUIContainer; import gregtech.api.gui.impl.ModularUIGui; +import gregtech.api.metatileentity.MetaTileEntityHolder; import gregtech.api.util.ClipboardUtil; import gregtech.api.util.GTLog; +import gregtech.common.metatileentities.MetaTileEntityClipboard; import io.netty.buffer.ByteBuf; import io.netty.buffer.Unpooled; import net.minecraft.block.state.IBlockState; @@ -20,6 +22,7 @@ import net.minecraft.network.INetHandler; import net.minecraft.network.NetHandlerPlayServer; import net.minecraft.network.PacketBuffer; +import net.minecraft.tileentity.TileEntity; import net.minecraft.util.IThreadListener; import net.minecraft.util.IntIdentityHashBiMap; import net.minecraft.util.math.BlockPos; @@ -193,6 +196,27 @@ public static void init() { (buf) -> new PacketClipboard(buf.readString(32767)) )); + registerPacket(6, PacketClipboardUIWidgetUpdate.class, new NetworkHandler.PacketCodec<>( + (packet, buf) -> { + buf.writeVarInt(packet.clipboard.getWorld().provider.getDimension()); + buf.writeBlockPos(packet.clipboard.getPos()); + buf.writeVarInt(packet.id); + if(packet.payloadWriter != null) { + packet.payloadWriter.accept(buf); + } + }, + (buf) -> { + int dim = buf.readVarInt(); + BlockPos pos = buf.readBlockPos(); + TileEntity te = FMLCommonHandler.instance().getMinecraftServerInstance().getWorld(dim).getTileEntity(pos); + if(te instanceof MetaTileEntityHolder && ((MetaTileEntityHolder) te).getMetaTileEntity() instanceof MetaTileEntityClipboard) { + return new PacketClipboardUIWidgetUpdate((MetaTileEntityClipboard) ((MetaTileEntityHolder) te).getMetaTileEntity(), buf); + } + return new PacketClipboardUIWidgetUpdate(null, buf); + } + )); + + registerServerExecutor(PacketUIClientAction.class, (packet, handler) -> { Container openContainer = handler.player.openContainer; if (openContainer instanceof ModularUIContainer && @@ -203,6 +227,12 @@ public static void init() { } }); + NetworkHandler.registerServerExecutor(PacketClipboardUIWidgetUpdate.class, (packet, handler) -> { + if (packet.clipboard != null) { + packet.clipboard.readUIAction(handler.player, packet.id, packet.buf); + } + }); + if (FMLCommonHandler.instance().getSide().isClient()) { initClient(); } diff --git a/src/main/java/gregtech/api/net/PacketClipboardUIWidgetUpdate.java b/src/main/java/gregtech/api/net/PacketClipboardUIWidgetUpdate.java new file mode 100644 index 00000000000..2200e17c68e --- /dev/null +++ b/src/main/java/gregtech/api/net/PacketClipboardUIWidgetUpdate.java @@ -0,0 +1,28 @@ +package gregtech.api.net; + +import gregtech.api.metatileentity.MetaTileEntityHolder; +import gregtech.common.metatileentities.MetaTileEntityClipboard; +import net.minecraft.network.PacketBuffer; +import net.minecraft.tileentity.TileEntity; +import net.minecraft.util.math.BlockPos; +import net.minecraftforge.fml.common.FMLCommonHandler; + +import java.util.function.Consumer; + +public class PacketClipboardUIWidgetUpdate implements NetworkHandler.Packet { + public MetaTileEntityClipboard clipboard; + public int id; + public Consumer payloadWriter; + public PacketBuffer buf; + + public PacketClipboardUIWidgetUpdate(MetaTileEntityClipboard clipboard, int id, Consumer payloadWriter) { + this.clipboard = clipboard; + this.id = id; + this.payloadWriter = payloadWriter; + } + + public PacketClipboardUIWidgetUpdate(MetaTileEntityClipboard clipboard, PacketBuffer buf) { + this(clipboard, buf.readVarInt(), null); + this.buf = buf; + } +} diff --git a/src/main/java/gregtech/api/render/ClipboardRenderer.java b/src/main/java/gregtech/api/render/ClipboardRenderer.java new file mode 100644 index 00000000000..5b158d3b649 --- /dev/null +++ b/src/main/java/gregtech/api/render/ClipboardRenderer.java @@ -0,0 +1,109 @@ +package gregtech.api.render; + +import codechicken.lib.render.CCRenderState; +import codechicken.lib.render.pipeline.IVertexOperation; +import codechicken.lib.texture.TextureUtils; +import codechicken.lib.vec.Cuboid6; +import codechicken.lib.vec.Matrix4; +import codechicken.lib.vec.Rotation; +import gregtech.api.gui.ModularUI; +import gregtech.api.gui.Widget; +import gregtech.api.gui.impl.FakeModularGui; +import gregtech.common.gui.impl.FakeModularUIContainerClipboard; +import gregtech.api.util.GTLog; +import gregtech.api.util.GregFakePlayer; +import gregtech.common.metatileentities.MetaTileEntityClipboard; +import net.minecraft.client.Minecraft; +import net.minecraft.client.renderer.GlStateManager; +import net.minecraft.client.renderer.RenderHelper; +import net.minecraft.client.renderer.texture.TextureAtlasSprite; +import net.minecraft.client.renderer.texture.TextureMap; +import net.minecraft.util.EnumFacing; +import net.minecraft.util.ResourceLocation; +import net.minecraftforge.common.util.FakePlayer; +import net.minecraftforge.fml.relauncher.Side; +import net.minecraftforge.fml.relauncher.SideOnly; +import org.apache.commons.lang3.tuple.Pair; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.HashMap; +import java.util.List; + +public class ClipboardRenderer implements TextureUtils.IIconRegister { + + private static final Cuboid6 pageBox = new Cuboid6(3 / 16.0, 0.25 / 16.0, 0.25 / 16.0, 13 / 16.0, 14.25 / 16.0, 0.3 / 16.0); + private static final Cuboid6 boardBox = new Cuboid6(2.75 / 16.0, 0 / 16.0, 0 / 16.0, 13.25 / 16.0, 15.25 / 16.0, 0.25 / 16.0); + private static final Cuboid6 clipBox = new Cuboid6(5.75 / 16.0, 14.75 / 16.0, 0.25 / 16.0, 10.25 / 16.0, 15.5 / 16.0, 0.4 / 16.0); + private static final Cuboid6 graspBox = new Cuboid6(7 / 16.0, 15.25 / 16.0, 0.1 / 16.0, 9 / 16.0, 16 / 16.0, 0.35 / 16.0); + + private static final List rotations = Arrays.asList(EnumFacing.NORTH, EnumFacing.WEST, EnumFacing.SOUTH, EnumFacing.EAST); + + private static HashMap boxTextureMap = new HashMap<>(); + + @SideOnly(Side.CLIENT) + private TextureAtlasSprite[] textures = new TextureAtlasSprite[3]; + + + public ClipboardRenderer() { + Textures.iconRegisters.add(this); + } + + @Override + public void registerIcons(TextureMap textureMap) { + this.textures[0] = textureMap.registerSprite(new ResourceLocation("gregtech:blocks/clipboard/wood")); + boxTextureMap.put(boardBox, this.textures[0]); + this.textures[1] = textureMap.registerSprite(new ResourceLocation("gregtech:blocks/clipboard/clip")); + boxTextureMap.put(clipBox, this.textures[1]); + boxTextureMap.put(graspBox, this.textures[1]); + this.textures[2] = textureMap.registerSprite(new ResourceLocation("gregtech:blocks/clipboard/page")); + boxTextureMap.put(pageBox, this.textures[2]); + } + + @SideOnly(Side.CLIENT) + public void renderBoard(CCRenderState renderState, Matrix4 translation, IVertexOperation[] pipeline, EnumFacing rotation, MetaTileEntityClipboard clipboard, float partialTicks) { + translation.translate(0.5, 0.5, 0.5); + translation.rotate(Math.toRadians(90.0 * rotations.indexOf(rotation)), Rotation.axes[1]); + translation.translate(-0.5, -0.5, -0.5); + + // Render Clipboard + for (EnumFacing renderSide : EnumFacing.VALUES) { + boxTextureMap.forEach((box, sprite) -> Textures.renderFace(renderState, translation, pipeline, renderSide, box, sprite)); + } + } + + + @SideOnly(Side.CLIENT) + public void renderGUI(double x, double y, double z, EnumFacing rotation, MetaTileEntityClipboard clipboard, float partialTicks) { + GlStateManager.pushMatrix(); + RenderHelper.disableStandardItemLighting(); + + // All of these are done in reverse order, by the way, if you're reviewing this :P + + GlStateManager.translate(x, y, z); + GlStateManager.translate(0.5, 0.451, 0.5); + GlStateManager.rotate((float) (90.0 * rotations.indexOf(rotation)), 0, 1, 0); + GlStateManager.translate(0, 0, -0.468); + GlStateManager.rotate(180, 1, 0, 0); + GlStateManager.scale(0.875, 0.875, 0.875); + + if (clipboard.guiCache != null) { + Pair result = clipboard.checkLookingAt(); + if (result == null) { + clipboard.guiCache.drawScreen(0, 0, partialTicks); + } else { + clipboard.guiCache.drawScreen(result.getKey(), result.getValue(), partialTicks); + } + } + + RenderHelper.enableStandardItemLighting(); + GlStateManager.popMatrix(); + } + + + + @SideOnly(Side.CLIENT) + public TextureAtlasSprite getParticleTexture() { + return textures[0]; + } +} diff --git a/src/main/java/gregtech/api/render/Textures.java b/src/main/java/gregtech/api/render/Textures.java index e69733b2cae..7015fcf8efd 100644 --- a/src/main/java/gregtech/api/render/Textures.java +++ b/src/main/java/gregtech/api/render/Textures.java @@ -29,13 +29,14 @@ public class Textures { private static final ThreadLocal blockFaces = ThreadLocal.withInitial(BlockFace::new); public static final List iconRegisters = new ArrayList<>(); - public static final SafeRenderer SAFE = new SafeRenderer("storage/safe"); + public static ClipboardRenderer CLIPBOARD_RENDERER = new ClipboardRenderer(); + public static final CrateRenderer WOODEN_CRATE = new CrateRenderer("storage/crates/wooden_crate"); + public static final CrateRenderer METAL_CRATE = new CrateRenderer("storage/crates/metal_crate"); public static final DrumRenderer WOODEN_DRUM = new DrumRenderer("storage/drums/wooden_drum"); public static final DrumRenderer DRUM = new DrumRenderer("storage/drums/drum"); + public static final SafeRenderer SAFE = new SafeRenderer("storage/safe"); public static final TankRenderer WOODEN_TANK = new TankRenderer("storage/tank/wooden"); public static final TankRenderer METAL_TANK = new TankRenderer("storage/tank/metal"); - public static final CrateRenderer WOODEN_CRATE = new CrateRenderer("storage/crates/wooden_crate"); - public static final CrateRenderer METAL_CRATE = new CrateRenderer("storage/crates/metal_crate"); public static final SimpleSidedCubeRenderer STEAM_CASING_BRONZE = new SimpleSidedCubeRenderer("casings/steam/bronze"); public static final SimpleSidedCubeRenderer STEAM_CASING_STEEL = new SimpleSidedCubeRenderer("casings/steam/steel"); public static final SimpleSidedCubeRenderer STEAM_BRICKED_CASING_BRONZE = new SimpleSidedCubeRenderer("casings/steam/bricked_bronze"); diff --git a/src/main/java/gregtech/api/util/GTUtility.java b/src/main/java/gregtech/api/util/GTUtility.java index 4e31ac757c3..92abab7f8bf 100644 --- a/src/main/java/gregtech/api/util/GTUtility.java +++ b/src/main/java/gregtech/api/util/GTUtility.java @@ -900,4 +900,15 @@ public static boolean isFluidStackAmountDivisible(FluidStack fluidStack, int div public static boolean isItemStackCountDivisible(ItemStack itemStack, int divisor) { return itemStack.getCount() % divisor == 0 && itemStack.getCount() % divisor != itemStack.getCount() && itemStack.getCount() / divisor != 0; } + + public static AxisAlignedBB rotateAroundYAxis(AxisAlignedBB aabb, EnumFacing from, EnumFacing to) { + if(from == EnumFacing.UP || from == EnumFacing.DOWN || to == EnumFacing.UP || to == EnumFacing.DOWN) + throw new IllegalArgumentException("Either the second or third parameters were EnumFacing.DOWN or EnumFacing.UP."); + AxisAlignedBB rotatedAABB = new AxisAlignedBB(aabb.minX, aabb.minY, aabb.minZ, aabb.maxX, aabb.maxY, aabb.maxZ); + while(from != to) { + from = from.rotateY(); + rotatedAABB = new AxisAlignedBB(1 - rotatedAABB.maxZ, rotatedAABB.minY, rotatedAABB.minX, 1 - rotatedAABB.minZ, rotatedAABB.maxY, rotatedAABB.maxX); + } + return rotatedAABB; + } } diff --git a/src/main/java/gregtech/api/util/GregFakePlayer.java b/src/main/java/gregtech/api/util/GregFakePlayer.java index 6aafd3d4fe9..6c534956679 100644 --- a/src/main/java/gregtech/api/util/GregFakePlayer.java +++ b/src/main/java/gregtech/api/util/GregFakePlayer.java @@ -1,14 +1,25 @@ package gregtech.api.util; import com.mojang.authlib.GameProfile; +import net.minecraft.entity.Entity; +import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.item.ItemStack; +import net.minecraft.server.MinecraftServer; +import net.minecraft.stats.StatBase; +import net.minecraft.util.DamageSource; +import net.minecraft.util.math.Vec3d; +import net.minecraft.util.text.ITextComponent; +import net.minecraft.world.World; import net.minecraft.world.WorldServer; import net.minecraftforge.common.util.FakePlayer; import net.minecraftforge.common.util.FakePlayerFactory; +import net.minecraftforge.common.util.ITeleporter; +import net.minecraftforge.fml.common.FMLCommonHandler; import java.lang.ref.WeakReference; import java.util.UUID; -public class GregFakePlayer { +public class GregFakePlayer extends EntityPlayer { private static final GameProfile GREGTECH = new GameProfile(UUID.fromString("518FDF18-EC2A-4322-832A-58ED1721309B"), "[GregTech]"); private static WeakReference GREGTECH_PLAYER = null; @@ -22,4 +33,76 @@ public static FakePlayer get(WorldServer world) { return ret; } + public GregFakePlayer(World worldIn) { + super(worldIn, GREGTECH); + } + + @Override + public boolean isSpectator() { + return false; + } + + @Override + public boolean isCreative() { + return false; + } + + @Override + public Vec3d getPositionVector() { + return new Vec3d(0, 0, 0); + } + + @Override + public boolean canUseCommand(int i, String s) { + return false; + } + + @Override + public void sendStatusMessage(ITextComponent chatComponent, boolean actionBar) { + } + + @Override + public void sendMessage(ITextComponent component) { + } + + @Override + public void addStat(StatBase par1StatBase, int par2) { + } + + @Override + public void openGui(Object mod, int modGuiId, World world, int x, int y, int z) { + } + + @Override + public boolean isEntityInvulnerable(DamageSource source) { + return true; + } + + @Override + public boolean canAttackPlayer(EntityPlayer player) { + return false; + } + + @Override + public void onDeath(DamageSource source) { + return; + } + + @Override + public void onUpdate() { + return; + } + + @Override + public Entity changeDimension(int dim, ITeleporter teleporter) { + return this; + } + + @Override + public MinecraftServer getServer() { + return FMLCommonHandler.instance().getMinecraftServerInstance(); + } + + @Override + protected void playEquipSound(ItemStack stack) { } } diff --git a/src/main/java/gregtech/api/util/RenderUtil.java b/src/main/java/gregtech/api/util/RenderUtil.java index d3f98e3f67d..c150c1b1555 100644 --- a/src/main/java/gregtech/api/util/RenderUtil.java +++ b/src/main/java/gregtech/api/util/RenderUtil.java @@ -1,7 +1,17 @@ package gregtech.api.util; import net.minecraft.client.Minecraft; +import net.minecraft.client.entity.EntityPlayerSP; +import net.minecraft.client.gui.FontRenderer; import net.minecraft.client.gui.ScaledResolution; +import net.minecraft.client.renderer.BufferBuilder; +import net.minecraft.client.renderer.GlStateManager; +import net.minecraft.client.renderer.RenderItem; +import net.minecraft.client.renderer.Tessellator; +import net.minecraft.client.renderer.vertex.DefaultVertexFormats; +import net.minecraft.inventory.Slot; +import net.minecraft.item.ItemStack; +import net.minecraft.util.math.MathHelper; import net.minecraftforge.client.GuiIngameForge; import org.lwjgl.opengl.GL11; @@ -85,5 +95,4 @@ private static void applyScissor(int x, int y, int w, int h) { int translatedY = r.getScaledHeight() - y - h; GL11.glScissor(x * s, translatedY * s, w * s, h * s); } - } diff --git a/src/main/java/gregtech/common/gui/impl/FakeModularUIContainerClipboard.java b/src/main/java/gregtech/common/gui/impl/FakeModularUIContainerClipboard.java new file mode 100644 index 00000000000..6b95f557ace --- /dev/null +++ b/src/main/java/gregtech/common/gui/impl/FakeModularUIContainerClipboard.java @@ -0,0 +1,127 @@ +package gregtech.common.gui.impl; + +import com.google.common.collect.Lists; +import gregtech.api.gui.INativeWidget; +import gregtech.api.gui.ModularUI; +import gregtech.api.gui.Widget; +import gregtech.api.gui.widgets.WidgetUIAccess; +import gregtech.api.net.NetworkHandler; +import gregtech.api.net.PacketClipboardUIWidgetUpdate; +import gregtech.common.metatileentities.MetaTileEntityClipboard; +import net.minecraft.inventory.Slot; +import net.minecraft.item.ItemStack; +import net.minecraft.network.PacketBuffer; +import net.minecraft.util.NonNullList; +import net.minecraft.util.Tuple; + +import java.util.ArrayList; +import java.util.List; +import java.util.function.Consumer; + + +// Note: when porting the central monitor, please make this more generic. +public class FakeModularUIContainerClipboard implements WidgetUIAccess { + private final NonNullList inventoryItemStacks = NonNullList.create(); + public final List inventorySlots = Lists.newArrayList(); + public final ModularUI modularUI; + public int windowId; + public MetaTileEntityClipboard clipboard; + + public FakeModularUIContainerClipboard(ModularUI modularUI, MetaTileEntityClipboard clipboard) { + this.modularUI = modularUI; + this.clipboard = clipboard; + modularUI.initWidgets(); + modularUI.guiWidgets.values().forEach(widget -> widget.setUiAccess(this)); + modularUI.guiWidgets.values().stream().flatMap(widget -> widget.getNativeWidgets().stream()).forEach(nativeWidget -> addSlotToContainer(nativeWidget.getHandle())); + modularUI.triggerOpenListeners(); + } + + protected void addSlotToContainer(Slot slotIn) { + slotIn.slotNumber = this.inventorySlots.size(); + this.inventorySlots.add(slotIn); + this.inventoryItemStacks.add(ItemStack.EMPTY); + } + + public void handleSlotUpdate(PacketBuffer updateData) { + try { + int size = updateData.readVarInt(); + for (int i = 0; i < size; i++) { + inventorySlots.get(updateData.readVarInt()).putStack(updateData.readItemStack()); + } + } catch (Exception ignored) { + + } + } + + public void handleClientAction(PacketBuffer buffer) { + int windowId = buffer.readVarInt(); + if (windowId == this.windowId) { + Widget widget = modularUI.guiWidgets.get(buffer.readVarInt()); + if (widget != null) { + widget.handleClientAction(buffer.readVarInt(), buffer); + } + } + } + + public void detectAndSendChanges() { + List> toUpdate = new ArrayList<>(); + for (int i = 0; i < this.inventorySlots.size(); ++i) { + ItemStack real = this.inventorySlots.get(i).getStack(); + ItemStack fake = this.inventoryItemStacks.get(i); + + if (!ItemStack.areItemStacksEqual(fake, real)) { + boolean clientStackChanged = !ItemStack.areItemStacksEqualUsingNBTShareTag(fake, real); + fake = real.isEmpty() ? ItemStack.EMPTY : real.copy(); + this.inventoryItemStacks.set(i, fake); + + if (clientStackChanged) { + toUpdate.add(new Tuple<>(i, fake)); + } + } + } + modularUI.guiWidgets.values().forEach(Widget::detectAndSendChanges); + } + + @Override + public void notifySizeChange() { + + } + + @Override + public void notifyWidgetChange() { + + } + + @Override + public boolean attemptMergeStack(ItemStack itemStack, boolean b, boolean b1) { + return false; + } + + @Override + public void sendSlotUpdate(INativeWidget iNativeWidget) { + } + + @Override + public void sendHeldItemUpdate() { + } + + @Override + public void writeClientAction(Widget widget, int updateId, Consumer payloadWriter) { + NetworkHandler.channel.sendToServer(new PacketClipboardUIWidgetUpdate(this.clipboard, updateId, buffer -> { + buffer.writeVarInt(windowId); + buffer.writeVarInt(modularUI.guiWidgets.inverse().get(widget)); + buffer.writeVarInt(updateId); + payloadWriter.accept(buffer); + }).toFMLPacket()); + } + + @Override + public void writeUpdateInfo(Widget widget, int updateId, Consumer payloadWriter) { + this.clipboard.writeCustomData(0, buf -> { + buf.writeVarInt(windowId); + buf.writeVarInt(modularUI.guiWidgets.inverse().get(widget)); + buf.writeVarInt(updateId); + payloadWriter.accept(buf); + }); + } +} diff --git a/src/main/java/gregtech/common/items/MetaItem1.java b/src/main/java/gregtech/common/items/MetaItem1.java index 8e7d7b63fd2..3a14e45a2ae 100644 --- a/src/main/java/gregtech/common/items/MetaItem1.java +++ b/src/main/java/gregtech/common/items/MetaItem1.java @@ -377,7 +377,7 @@ public void registerSubItems() { NANO_SABER = addItem(463, "nano_saber").addComponents(ElectricStats.createElectricItem(4000000L, GTValues.HV)).addComponents(new NanoSaberBehavior()).setMaxStackSize(1); // Free ID 464 SCANNER = addItem(465, "scanner").addComponents(ElectricStats.createElectricItem(200_000L, GTValues.LV), new ScannerBehavior(50)); - /* CLIPBOARD GOES HERE - ID 466 */ + CLIPBOARD = addItem(466, "clipboard").addComponents(new ClipboardBehavior()).setMaxStackSize(1); TERMINAL = addItem(467, "terminal").addComponents(new TerminalBehaviour()); // Misc Crafting Items: ID 491-515 diff --git a/src/main/java/gregtech/common/items/MetaItems.java b/src/main/java/gregtech/common/items/MetaItems.java index dad05326824..ff4ce16f24e 100644 --- a/src/main/java/gregtech/common/items/MetaItems.java +++ b/src/main/java/gregtech/common/items/MetaItems.java @@ -488,6 +488,8 @@ private MetaItems() { public static MetaItem.MetaValueItem VOLTAGE_COIL_ZPM; public static MetaItem.MetaValueItem VOLTAGE_COIL_UV; + public static MetaItem.MetaValueItem CLIPBOARD; + private static final List orePrefixes = new ArrayList() {{ add(OrePrefix.dust); add(OrePrefix.dustSmall); diff --git a/src/main/java/gregtech/common/items/behaviors/ClipboardBehavior.java b/src/main/java/gregtech/common/items/behaviors/ClipboardBehavior.java new file mode 100644 index 00000000000..e30b3e990f1 --- /dev/null +++ b/src/main/java/gregtech/common/items/behaviors/ClipboardBehavior.java @@ -0,0 +1,257 @@ +package gregtech.common.items.behaviors; + +import codechicken.lib.raytracer.RayTracer; +import gregtech.api.gui.GuiTextures; +import gregtech.api.gui.ModularUI; +import gregtech.api.gui.widgets.*; +import gregtech.api.items.gui.ItemUIFactory; +import gregtech.api.items.gui.PlayerInventoryHolder; +import gregtech.api.items.metaitem.stats.IItemBehaviour; +import gregtech.api.metatileentity.MetaTileEntityHolder; +import gregtech.api.util.RenderUtil; +import gregtech.common.items.MetaItems; +import gregtech.common.metatileentities.MetaTileEntityClipboard; +import net.minecraft.block.Block; +import net.minecraft.block.state.IBlockState; +import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.item.ItemStack; +import net.minecraft.nbt.NBTTagCompound; +import net.minecraft.util.ActionResult; +import net.minecraft.util.EnumActionResult; +import net.minecraft.util.EnumFacing; +import net.minecraft.util.EnumHand; +import net.minecraft.util.math.BlockPos; +import net.minecraft.util.math.RayTraceResult; +import net.minecraft.world.World; + +import static gregtech.common.blocks.MetaBlocks.MACHINE; +import static gregtech.common.metatileentities.MetaTileEntities.CLIPBOARD_TILE; + +public class ClipboardBehavior implements IItemBehaviour, ItemUIFactory { + public static final int MAX_PAGES = 25; + + @Override + public ModularUI createUI(PlayerInventoryHolder holder, EntityPlayer entityPlayer) { + initNBT(holder.getCurrentItem()); + ModularUI.Builder builder = ModularUI.builder(GuiTextures.BACKGROUND, 170, 238); + + builder.widget(new ImageTextFieldWidget(20, 10, 130, 12, GuiTextures.CLIPBOARD_TEXT_BOX, + () -> getTitle(holder), (x) -> setTitle(holder, x), 23, 0xFFFFFF) + .setValidator((x) -> true)); + + for (int i = 0; i < 8; i++) { + int finalI = i; + builder.widget(new ImageCycleButtonWidget(6, 37 + 20 * i, 15, 15, GuiTextures.CLIPBOARD_BUTTON, 4, + () -> getButtonState(holder, finalI), (x) -> setButton(holder, finalI, x))); + builder.widget(new ImageTextFieldWidget(24, 40 + 20 * i, 140, 12, GuiTextures.CLIPBOARD_TEXT_BOX, + () -> getString(holder, finalI), (x) -> setString(holder, finalI, x), 23, 0xFFFFFF) + .setValidator((x) -> true)); + } + + builder.widget(new ClickButtonWidget(30, 200, 16, 16, "", (x) -> incrPageNum(holder, -1)) + .setButtonTexture(GuiTextures.BUTTON_LEFT).setShouldClientCallback(true)); + builder.widget(new ClickButtonWidget(124, 200, 16, 16, "", (x) -> incrPageNum(holder, 1)) + .setButtonTexture(GuiTextures.BUTTON_RIGHT).setShouldClientCallback(true)); + builder.widget(new SimpleTextWidget(85, 208, "", 0xFFFFFF, + () -> (getPageNum(holder) + 1) + " / " + MAX_PAGES)); + + return builder.build(holder, entityPlayer); + } + + public ModularUI createMTEUI(PlayerInventoryHolder holder, EntityPlayer entityPlayer) { // So that people don't click on any text fields + initNBT(holder.getCurrentItem()); + ModularUI.Builder builder = ModularUI.builder(GuiTextures.BACKGROUND, 170, 238); + + builder.image(18, 8, 130, 14, GuiTextures.CLIPBOARD_TEXT_BOX); + builder.widget(new SimpleTextWidget(20, 10, "", 0xFFFFFF, () -> getTitle(holder)).setCenter(false)); + + + for (int i = 0; i < 8; i++) { + int finalI = i; + builder.widget(new ImageCycleButtonWidget(6, 37 + 20 * i, 15, 15, GuiTextures.CLIPBOARD_BUTTON, 4, + () -> getButtonState(holder, finalI), (x) -> setButton(holder, finalI, x))); + builder.image(22, 38 + 20 * i, 140, 12, GuiTextures.CLIPBOARD_TEXT_BOX); + builder.widget(new SimpleTextWidget(24, 40 + 20 * i, "", 0xFFFFFF, () -> getString(holder, finalI)).setCenter(false)); + } + + builder.widget(new ClickButtonWidget(30, 200, 16, 16, "", (x) -> incrPageNum(holder, -1)) + .setButtonTexture(GuiTextures.BUTTON_LEFT).setShouldClientCallback(true)); + builder.widget(new ClickButtonWidget(124, 200, 16, 16, "", (x) -> incrPageNum(holder, 1)) + .setButtonTexture(GuiTextures.BUTTON_RIGHT).setShouldClientCallback(true)); + builder.widget(new SimpleTextWidget(85, 208, "", 0xFFFFFF, + () -> (getPageNum(holder) + 1) + " / " + MAX_PAGES)); + + return builder.build(holder, entityPlayer); + } + + + private static NBTTagCompound getPageCompound(ItemStack stack) { + if (!MetaItems.CLIPBOARD.isItemEqual(stack)) + throw new IllegalArgumentException("Given item stack is not a clipboard!"); + assert stack.getTagCompound() != null; + short pageNum = stack.getTagCompound().getShort("PageIndex"); + return stack.getTagCompound().getCompoundTag("Page" + pageNum); + } + + private static void setPageCompound(ItemStack stack, NBTTagCompound pageCompound) { + if (!MetaItems.CLIPBOARD.isItemEqual(stack)) + throw new IllegalArgumentException("Given item stack is not a clipboard!"); + assert stack.getTagCompound() != null; + short pageNum = stack.getTagCompound().getShort("PageIndex"); + stack.getTagCompound().setTag("Page" + pageNum, pageCompound); + } + + private static void initNBT(ItemStack stack) { + if (!MetaItems.CLIPBOARD.isItemEqual(stack)) + throw new IllegalArgumentException("Given item stack is not a clipboard!"); + NBTTagCompound tagCompound = stack.getTagCompound(); + if (tagCompound == null) { + tagCompound = new NBTTagCompound(); + tagCompound.setShort("PageIndex", (short) 0); + tagCompound.setShort("TotalPages", (short) 0); + + NBTTagCompound pageCompound = new NBTTagCompound(); + pageCompound.setShort("ButStat", (short) 0); + pageCompound.setString("Title", ""); + for (int i = 0; i < 8; i++) { + pageCompound.setString("Task" + i, ""); + } + + for (int i = 0; i < MAX_PAGES; i++) { + tagCompound.setTag("Page" + i, pageCompound.copy()); + } + + stack.setTagCompound(tagCompound); + } + } + + private static void setButton(PlayerInventoryHolder holder, int pos, int newState) { + ItemStack stack = holder.getCurrentItem(); + if (!MetaItems.CLIPBOARD.isItemEqual(stack)) + throw new IllegalArgumentException("Given item stack is not a clipboard!"); + NBTTagCompound tagCompound = getPageCompound(stack); + short buttonState; + buttonState = tagCompound.getShort("ButStat"); + + short clearedState = (short) (buttonState & ~(3 << (pos * 2))); // Clear out the desired slot + buttonState = (short) (clearedState | (newState << (pos * 2))); // And add the new state back in + + tagCompound.setShort("ButStat", buttonState); + setPageCompound(stack, tagCompound); + } + + private static int getButtonState(PlayerInventoryHolder holder, int pos) { + ItemStack stack = holder.getCurrentItem(); + if (!MetaItems.CLIPBOARD.isItemEqual(stack)) + throw new IllegalArgumentException("Given item stack is not a clipboard!"); + NBTTagCompound tagCompound = getPageCompound(stack); + short buttonState; + buttonState = tagCompound.getShort("ButStat"); + return ((buttonState >> pos * 2) & 3); + } + + private static void setString(PlayerInventoryHolder holder, int pos, String newString) { + ItemStack stack = holder.getCurrentItem(); + if (!MetaItems.CLIPBOARD.isItemEqual(stack)) + throw new IllegalArgumentException("Given item stack is not a clipboard!"); + NBTTagCompound tagCompound = getPageCompound(stack); + tagCompound.setString("Task" + pos, newString); + setPageCompound(stack, tagCompound); + } + + private static String getString(PlayerInventoryHolder holder, int pos) { + ItemStack stack = holder.getCurrentItem(); + if (!MetaItems.CLIPBOARD.isItemEqual(stack)) + throw new IllegalArgumentException("Given item stack is not a clipboard!"); + NBTTagCompound tagCompound = getPageCompound(stack); + return tagCompound.getString("Task" + pos); + } + + private static void setTitle(PlayerInventoryHolder holder, String newString) { + ItemStack stack = holder.getCurrentItem(); + if (!MetaItems.CLIPBOARD.isItemEqual(stack)) + throw new IllegalArgumentException("Given item stack is not a clipboard!"); + NBTTagCompound tagCompound = getPageCompound(stack); + assert tagCompound != null; + tagCompound.setString("Title", newString); + setPageCompound(stack, tagCompound); + } + + private static String getTitle(PlayerInventoryHolder holder) { + ItemStack stack = holder.getCurrentItem(); + if (!MetaItems.CLIPBOARD.isItemEqual(stack)) + throw new IllegalArgumentException("Given item stack is not a clipboard!"); + NBTTagCompound tagCompound = getPageCompound(stack); + return tagCompound.getString("Title"); + } + + private static int getPageNum(PlayerInventoryHolder holder) { + ItemStack stack = holder.getCurrentItem(); + if (!MetaItems.CLIPBOARD.isItemEqual(stack)) + throw new IllegalArgumentException("Given item stack is not a clipboard!"); + NBTTagCompound tagCompound = stack.getTagCompound(); + return tagCompound.getInteger("PageIndex"); + } + + private static void incrPageNum(PlayerInventoryHolder holder, int increment) { + ItemStack stack = holder.getCurrentItem(); + if (!MetaItems.CLIPBOARD.isItemEqual(stack)) + throw new IllegalArgumentException("Given item stack is not a clipboard!"); + NBTTagCompound tagCompound = stack.getTagCompound(); + assert tagCompound != null; + + int currentIndex = tagCompound.getInteger("PageIndex"); + // Clamps currentIndex between 0 and MAX_PAGES. + tagCompound.setInteger("PageIndex", Math.max(Math.min(currentIndex + increment, MAX_PAGES - 1), 0)); + stack.setTagCompound(tagCompound); + } + + + @Override + public ActionResult onItemRightClick(World world, EntityPlayer player, EnumHand hand) { + ItemStack heldItem = player.getHeldItem(hand); + if (!world.isRemote && RayTracer.retrace(player).typeOfHit != RayTraceResult.Type.BLOCK) { // So that the player doesn't place a clipboard before suddenly getting the GUI + PlayerInventoryHolder holder = new PlayerInventoryHolder(player, hand); + holder.openUI(); + } + return ActionResult.newResult(EnumActionResult.SUCCESS, heldItem); + } + + @Override + public ActionResult onItemUse(EntityPlayer player, World world, BlockPos pos, EnumHand hand, EnumFacing facing, float hitX, float hitY, float hitZ) { + if(!world.isRemote) { + ItemStack heldItem = player.getHeldItem(hand).copy(); + heldItem.setCount(1); // don't place multiple items at a time + EnumFacing playerFacing = player.getHorizontalFacing(); + // Make sure it's the right block + Block testBlock = world.getBlockState(pos).getBlock(); + IBlockState testState = testBlock.getDefaultState(); + if (!testBlock.isAir(world.getBlockState(pos), world, pos) && testState.isSideSolid(world, pos, playerFacing)) { + // Step away from the block so you don't replace it, and then give it our fun blockstate + BlockPos shiftedPos = pos.offset(playerFacing.getOpposite()); + Block shiftedBlock = world.getBlockState(shiftedPos).getBlock(); + if (shiftedBlock.isAir(world.getBlockState(shiftedPos), world, shiftedPos)) { + IBlockState state = MACHINE.getDefaultState(); + world.setBlockState(shiftedPos, state); + // Get new TE + shiftedBlock.createTileEntity(world, state); + // And manipulate it to our liking + MetaTileEntityHolder holder = (MetaTileEntityHolder) world.getTileEntity(shiftedPos); + if (holder != null) { + MetaTileEntityClipboard clipboard = (MetaTileEntityClipboard) holder.setMetaTileEntity(CLIPBOARD_TILE, heldItem); + if (clipboard != null) { + clipboard.setFrontFacing(playerFacing); + clipboard.setClipboard(heldItem); + ItemStack returnedStack = player.getHeldItem(hand); + if (!player.isCreative()) { + returnedStack.setCount(player.getHeldItem(hand).getCount() - 1); + } + return ActionResult.newResult(EnumActionResult.SUCCESS, returnedStack); + } + } + } + } + } + return ActionResult.newResult(EnumActionResult.FAIL, player.getHeldItem(hand)); + } +} diff --git a/src/main/java/gregtech/common/metatileentities/MetaTileEntities.java b/src/main/java/gregtech/common/metatileentities/MetaTileEntities.java index 2f549f7c0ea..db8c455df43 100644 --- a/src/main/java/gregtech/common/metatileentities/MetaTileEntities.java +++ b/src/main/java/gregtech/common/metatileentities/MetaTileEntities.java @@ -197,6 +197,8 @@ public class MetaTileEntities { public static final MetaTileEntityFisher[] FISHER = new MetaTileEntityFisher[4]; public static MetaTileEntityCreativeEnergy CREATIVE_ENERGY; + + public static MetaTileEntityClipboard CLIPBOARD_TILE; public static void init() { GTLog.logger.info("Registering MetaTileEntities"); @@ -633,6 +635,8 @@ public static void init() { STEAM_HATCH = GregTechAPI.registerMetaTileEntity(1652, new MetaTileEntitySteamHatch(gregtechId("steam_hatch"))); SIMPLE_ORE_WASHER = GregTechAPI.registerMetaTileEntity(1653, new MetaTileEntitySimpleOreWasher(gregtechId("ore_washer.simple"), RecipeMaps.SIMPLE_WASHER_RECIPES, Textures.ORE_WASHER_OVERLAY, 0)); + CLIPBOARD_TILE = GregTechAPI.registerMetaTileEntity(1636, new MetaTileEntityClipboard(gregtechId("clipboard"))); + /* * FOR ADDON DEVELOPERS: * diff --git a/src/main/java/gregtech/common/metatileentities/MetaTileEntityClipboard.java b/src/main/java/gregtech/common/metatileentities/MetaTileEntityClipboard.java new file mode 100644 index 00000000000..d5175cb3827 --- /dev/null +++ b/src/main/java/gregtech/common/metatileentities/MetaTileEntityClipboard.java @@ -0,0 +1,421 @@ +package gregtech.common.metatileentities; + +import codechicken.lib.raytracer.CuboidRayTraceResult; +import codechicken.lib.raytracer.IndexedCuboid6; +import codechicken.lib.render.CCRenderState; +import codechicken.lib.render.pipeline.IVertexOperation; +import codechicken.lib.vec.Cuboid6; +import codechicken.lib.vec.Matrix4; +import codechicken.lib.vec.Vector3; +import gregtech.api.block.BlockCustomParticle; +import gregtech.api.gui.ModularUI; +import gregtech.api.gui.Widget; +import gregtech.api.gui.impl.FakeModularGui; +import gregtech.api.items.gui.PlayerInventoryHolder; +import gregtech.api.items.itemhandlers.InaccessibleItemStackHandler; +import gregtech.api.items.metaitem.MetaItem; +import gregtech.api.items.metaitem.stats.IItemBehaviour; +import gregtech.api.metatileentity.*; +import gregtech.api.util.GTLog; +import gregtech.api.util.GTUtility; +import gregtech.api.util.GregFakePlayer; +import gregtech.common.gui.impl.FakeModularUIContainerClipboard; +import gregtech.common.items.behaviors.ClipboardBehavior; +import net.minecraft.block.Block; +import net.minecraft.client.Minecraft; +import net.minecraft.client.renderer.texture.TextureAtlasSprite; +import net.minecraft.creativetab.CreativeTabs; +import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.entity.player.EntityPlayerMP; +import net.minecraft.init.Blocks; +import net.minecraft.item.ItemStack; +import net.minecraft.nbt.NBTBase; +import net.minecraft.nbt.NBTTagCompound; +import net.minecraft.nbt.NBTTagInt; +import net.minecraft.network.PacketBuffer; +import net.minecraft.tileentity.TileEntity; +import net.minecraft.util.*; +import net.minecraft.util.math.AxisAlignedBB; +import net.minecraft.util.math.BlockPos; +import net.minecraft.util.math.Vec3d; +import net.minecraft.world.World; +import org.apache.commons.lang3.tuple.Pair; + +import javax.annotation.Nullable; +import java.util.ArrayList; +import java.util.List; +import java.util.Optional; + +import static codechicken.lib.raytracer.RayTracer.*; +import static gregtech.api.render.Textures.CLIPBOARD_RENDERER; +import static gregtech.common.items.MetaItems.CLIPBOARD; + +public class MetaTileEntityClipboard extends MetaTileEntity implements IRenderMetaTileEntity, IFastRenderMetaTileEntity { + private static final AxisAlignedBB CLIPBOARD_AABB = new AxisAlignedBB(2.75 / 16.0, 0.0, 0.0, 13.25 / 16.0, 1.0, 0.4 / 16.0); + public static final float scale = 1; + public FakeModularGui guiCache; + public FakeModularUIContainerClipboard guiContainerCache; + private static final Cuboid6 pageBox = new Cuboid6(3 / 16.0, 0.25 / 16.0, 0.25 / 16.0, 13 / 16.0, 14.25 / 16.0, 0.3 / 16.0); + + private static final int RENDER_PASS_NORMAL = 0; + private static final NBTBase NO_CLIPBOARD_SIG = new NBTTagInt(0); + + + public MetaTileEntityClipboard(ResourceLocation metaTileEntityId) { + super(metaTileEntityId); + } + + @Override + public void update() { + super.update(); + if (this.getWorld().isRemote) { + if (guiCache != null) + guiCache.updateScreen(); + } else { + if (getOffsetTimer() % 20 == 0) + createFakeGui(); + if (guiContainerCache != null) + guiContainerCache.detectAndSendChanges(); + } + } + + @Override + public int getLightOpacity() { + return 0; + } + + @Override + public void renderMetaTileEntityDynamic(double x, double y, double z, float partialTicks) { + if (this.getClipboard() != null) + CLIPBOARD_RENDERER.renderGUI(x, y, z, this.getFrontFacing(), this, partialTicks); + } + + @Override + public void renderMetaTileEntityFast(CCRenderState renderState, Matrix4 translation, float partialTicks) { + CLIPBOARD_RENDERER.renderBoard(renderState, translation.copy(), new IVertexOperation[]{}, getFrontFacing(), this, partialTicks); + } + + public AxisAlignedBB getRenderBoundingBox() { + return new AxisAlignedBB(getPos().add(-1, 0, -1), getPos().add(2, 2, 2)); + } + + @Override + public boolean shouldRenderInPass(int pass) { + return pass == RENDER_PASS_NORMAL; + } + + @Override + public boolean isGlobalRenderer() { + return true; + } + + @Override + public boolean isOpaqueCube() { + return false; + } + + @Override + public MetaTileEntity createMetaTileEntity(MetaTileEntityHolder holder) { + return new MetaTileEntityClipboard(metaTileEntityId); + } + + @Override + public ModularUI createUI(EntityPlayer entityPlayer) { + if (getClipboard().isItemEqual(CLIPBOARD.getStackForm())) { + List behaviours = ((MetaItem) getClipboard().getItem()).getBehaviours(getClipboard()); + Optional clipboardBehaviour = behaviours.stream().filter((x) -> x instanceof ClipboardBehavior).findFirst(); + if (!clipboardBehaviour.isPresent()) + return null; + if (clipboardBehaviour.get() instanceof ClipboardBehavior) { + PlayerInventoryHolder holder = new PlayerInventoryHolder(new GregFakePlayer(entityPlayer.world), EnumHand.MAIN_HAND); // We can't have this actually set the player's hand + holder.setCurrentItem(this.getClipboard()); + if(entityPlayer instanceof GregFakePlayer) { // This is how to tell if this is being called in-world or not + return ((ClipboardBehavior) clipboardBehaviour.get()).createMTEUI(holder, entityPlayer); + } else { + return ((ClipboardBehavior) clipboardBehaviour.get()).createUI(holder, entityPlayer); + } + } + } + return null; + } + + public void createFakeGui() { + // Basically just the original function from the PluginBehavior, but with a lot of now useless stuff stripped out. + try { + GregFakePlayer fakePlayer = new GregFakePlayer(this.getWorld()); + fakePlayer.setHeldItem(EnumHand.MAIN_HAND, this.getClipboard()); + ModularUI ui = this.createUI(fakePlayer); + + ModularUI.Builder builder = new ModularUI.Builder(ui.backgroundPath, ui.getWidth(), ui.getHeight()); + + List widgets = new ArrayList<>(ui.guiWidgets.values()); + + for (Widget widget : widgets) { + builder.widget(widget); + } + ui = builder.build(ui.holder, ui.entityPlayer); + FakeModularUIContainerClipboard fakeModularUIContainer = new FakeModularUIContainerClipboard(ui, this); + this.guiContainerCache = fakeModularUIContainer; + this.guiCache = new FakeModularGui(ui, fakeModularUIContainer); + this.writeCustomData(1, buffer -> { }); + } catch (Exception e) { + GTLog.logger.error(e); + } + } + + + @Override + protected void initializeInventory() { + super.initializeInventory(); + this.itemInventory = new InaccessibleItemStackHandler(); + } + + public ItemStack getClipboard() { + if (this.itemInventory.getStackInSlot(0) == ItemStack.EMPTY) { + ((InaccessibleItemStackHandler) this.itemInventory).setStackInSlot(0, CLIPBOARD.getStackForm()); + } + return this.itemInventory.getStackInSlot(0); + } + + public void setClipboard(ItemStack stack) { + ((InaccessibleItemStackHandler) this.itemInventory).setStackInSlot(0, stack.copy()); + } + + @Override + public void getDrops(NonNullList dropsList, @Nullable EntityPlayer harvester) { + dropsList.clear(); + dropsList.add(this.getClipboard()); + } + + @Override + public float getBlockHardness() { + return 100; + } + + @Override + public int getHarvestLevel() { + return 4; + } + + @Override + public boolean onRightClick(EntityPlayer playerIn, EnumHand hand, EnumFacing facing, CuboidRayTraceResult hitResult) { + if (!playerIn.isSneaking()) { + if (getWorld() != null && !getWorld().isRemote) { + MetaTileEntityUIFactory.INSTANCE.openUI(getHolder(), (EntityPlayerMP) playerIn); + } + } else { + BlockPos pos = this.getPos(); // Saving this for later so it doesn't get mangled + World world = this.getWorld(); // Same here + + NonNullList drops = NonNullList.create(); + getDrops(drops, playerIn); + + Block.spawnAsEntity(playerIn.world, this.getPos(), drops.get(0)); + this.dropAllCovers(); + this.onRemoval(); + + world.removeTileEntity(pos); + world.setBlockState(pos, Blocks.AIR.getDefaultState(), 3); + } + return true; + } + + + @Override + public String getHarvestTool() { + return "axe"; + } + + @Override + public void addCollisionBoundingBox(List collisionList) { + collisionList.add(new IndexedCuboid6(null, GTUtility.rotateAroundYAxis(CLIPBOARD_AABB, EnumFacing.NORTH, this.getFrontFacing()))); + } + + public IndexedCuboid6 getPageCuboid() { + return new IndexedCuboid6(null, GTUtility.rotateAroundYAxis(pageBox.aabb(), EnumFacing.NORTH, this.getFrontFacing())); + } + + @Override + public Pair getParticleTexture() { + return Pair.of(CLIPBOARD_RENDERER.getParticleTexture(), 0xFFFFFF); + } + + public Pair checkLookingAt() { + EntityPlayer player = Minecraft.getMinecraft().player; + if (this.getWorld() != null && player != null) { + Vec3d startVec = getStartVec(player); + Vec3d endVec = getEndVec(player); + CuboidRayTraceResult rayTraceResult = rayTrace(this.getPos(), new Vector3(startVec), new Vector3(endVec), getPageCuboid()); + if (rayTraceResult != null && rayTraceResult.sideHit == this.getFrontFacing().getOpposite()) { + TileEntity tileEntity = this.getWorld().getTileEntity(rayTraceResult.getBlockPos()); + if (tileEntity instanceof MetaTileEntityHolder && ((MetaTileEntityHolder) tileEntity).getMetaTileEntity() instanceof MetaTileEntityClipboard) { + double[] pos = handleRayTraceResult(rayTraceResult, this.getFrontFacing().getOpposite()); + if (pos[0] >= 0 && pos[0] <= 1 && pos[1] >= 0 && pos[1] <= 1) + return Pair.of(pos[0], pos[1]); + } + } + } + return null; + } + + private double[] handleRayTraceResult(CuboidRayTraceResult rayTraceResult, EnumFacing spin) { + double x, y; + double dX = rayTraceResult.sideHit.getAxis() == EnumFacing.Axis.X + ? rayTraceResult.hitVec.z - rayTraceResult.getBlockPos().getZ() + : rayTraceResult.hitVec.x - rayTraceResult.getBlockPos().getX(); + double dY = rayTraceResult.sideHit.getAxis() == EnumFacing.Axis.Y + ? rayTraceResult.hitVec.z - rayTraceResult.getBlockPos().getZ() + : rayTraceResult.hitVec.y - rayTraceResult.getBlockPos().getY(); + if (spin == EnumFacing.NORTH) { + x = 1 - dX; + } else if (spin == EnumFacing.SOUTH) { + x = dX; + } else if (spin == EnumFacing.EAST) { + x = 1 - dX; + if (rayTraceResult.sideHit.getXOffset() < 0 || rayTraceResult.sideHit.getZOffset() > 0) { + x = 1 - x; + } + } else { + x = 1 - dX; + if (rayTraceResult.sideHit.getXOffset() < 0 || rayTraceResult.sideHit.getZOffset() > 0) { + x = 1 - x; + } + } + + y = 1 - dY; // Since y values are quite weird here + + // Scale these to be 0 - 1 + x -= 3.0 / 16; + y -= 1.75 / 16; + x /= 14.0 / 16; + y /= 14.0 / 16; + + return new double[]{x, y}; + } + + @Override + public NBTTagCompound writeToNBT(NBTTagCompound data) { + super.writeToNBT(data); + if (this.getClipboard() != null && this.getClipboard().getTagCompound() != null) + data.setTag("clipboardNBT", this.getClipboard().getTagCompound()); + else + data.setTag("clipboardNBT", NO_CLIPBOARD_SIG); + return data; + } + + + @Override + public void readFromNBT(NBTTagCompound data) { + super.readFromNBT(data); + NBTBase clipboardNBT = data.getTag("clipboardNBT"); + if (clipboardNBT != NO_CLIPBOARD_SIG && clipboardNBT instanceof NBTTagCompound) { + ItemStack clipboard = this.getClipboard(); + clipboard.setTagCompound((NBTTagCompound) clipboardNBT); + this.setClipboard(clipboard); + } + } + + @Override + public void writeInitialSyncData(PacketBuffer buf) { + super.writeInitialSyncData(buf); + if (this.getClipboard() != null && this.getClipboard().getTagCompound() != null) + buf.writeCompoundTag(this.getClipboard().getTagCompound()); + else { + buf.writeCompoundTag(new NBTTagCompound()); + } + } + + @Override + public void receiveInitialSyncData(PacketBuffer buf) { + super.receiveInitialSyncData(buf); + try { + NBTTagCompound clipboardNBT = buf.readCompoundTag(); + if (clipboardNBT != new NBTTagCompound() && clipboardNBT != null) { + ItemStack clipboard = this.getClipboard(); + clipboard.setTagCompound(clipboardNBT); + this.setClipboard(clipboard); + } + } catch (Exception e) { + e.printStackTrace(); + } + } + + @Override + public void receiveCustomData(int dataId, PacketBuffer buf) { + super.receiveCustomData(dataId, buf); + if (dataId == 0) { + int windowID = buf.readVarInt(); + int widgetID = buf.readVarInt(); + if (guiCache != null) + guiCache.handleWidgetUpdate(windowID, widgetID, buf); + this.scheduleRenderUpdate(); + } else if (dataId == 1) { + createFakeGui(); + this.scheduleRenderUpdate(); + } else if (dataId == 2) { + int mouseX = buf.readVarInt(); + int mouseY = buf.readVarInt(); + if (guiCache != null && guiContainerCache != null) { + guiCache.mouseClicked(mouseX, mouseY, 0); // Left mouse button + } + this.scheduleRenderUpdate(); + } + } + + @Override + public void preInit(Object... data) { + if (data.length != 0 && data[0] instanceof ItemStack) + this.setClipboard((ItemStack) data[0]); + } + + @Override + public void getSubItems(CreativeTabs creativeTab, NonNullList subItems) { // JEI shouldn't show this + } + + @Override + public void renderMetaTileEntity(CCRenderState renderState, Matrix4 translation, IVertexOperation[] pipeline) { + } + + public void readUIAction(EntityPlayerMP player, int id, PacketBuffer buf) { + if (id == 1) { + if (this.guiContainerCache != null) { + guiContainerCache.handleClientAction(buf); + } + } + } + + @Override + public void onLeftClick(EntityPlayer player, EnumFacing facing, CuboidRayTraceResult hitResult) { + if (this.getWorld().isRemote) return; + Pair clickCoords = this.checkLookingAt(); + if (this.guiContainerCache != null && guiContainerCache.modularUI != null) { + int width = guiContainerCache.modularUI.getWidth(); + int height = guiContainerCache.modularUI.getHeight(); + double scale = 1.0 / Math.max(width, height); + int mouseX = (int) ((clickCoords.getLeft() / scale)); + int mouseY = (int) ((clickCoords.getRight() / scale)); + if (0 <= mouseX && mouseX <= width && 0 <= mouseY && mouseY <= height) { + this.writeCustomData(2, buf -> { + buf.writeVarInt(mouseX); + buf.writeVarInt(mouseY); + }); + } + } + + } + + @Override + public boolean canPlaceCoverOnSide(EnumFacing side) { + return false; + } + + @Override + public boolean canRenderMachineGrid() { + return false; + } + + @Override + public ItemStack getPickItem(CuboidRayTraceResult result, EntityPlayer player) { + return this.getClipboard(); + } +} diff --git a/src/main/java/gregtech/common/render/WrenchOverlayRenderer.java b/src/main/java/gregtech/common/render/WrenchOverlayRenderer.java index 3222e6aead3..eff34535b33 100644 --- a/src/main/java/gregtech/common/render/WrenchOverlayRenderer.java +++ b/src/main/java/gregtech/common/render/WrenchOverlayRenderer.java @@ -4,6 +4,7 @@ import codechicken.lib.vec.Vector3; import gregtech.api.capability.GregtechCapabilities; import gregtech.api.capability.GregtechTileCapabilities; +import gregtech.api.cover.ICoverable; import gregtech.api.cover.ICoverable.PrimaryBoxData; import gregtech.api.metatileentity.MetaTileEntityHolder; import gregtech.api.pipenet.tile.TileEntityPipeBase; @@ -92,6 +93,11 @@ public static boolean useGridForRayTraceResult(RayTraceResult result) { } public static boolean shouldDrawOverlayForItem(ItemStack itemStack, TileEntity tileEntity) { + if (tileEntity instanceof MetaTileEntityHolder) { + if(!((MetaTileEntityHolder) tileEntity).getMetaTileEntity().canRenderMachineGrid()) + return false; + } + if (tileEntity instanceof TileEntityPipeBase) { TileEntityPipeBase pipeTE = (TileEntityPipeBase) tileEntity; Class pipeClass = pipeTE.getPipeBlock().getPipeTypeClass(); diff --git a/src/main/java/gregtech/loaders/recipe/CraftingRecipeLoader.java b/src/main/java/gregtech/loaders/recipe/CraftingRecipeLoader.java index b8cf97ddc22..0795b8a96a4 100644 --- a/src/main/java/gregtech/loaders/recipe/CraftingRecipeLoader.java +++ b/src/main/java/gregtech/loaders/recipe/CraftingRecipeLoader.java @@ -64,6 +64,8 @@ private static void loadCraftingRecipes() { ModHandler.addSmeltingRecipe(new UnificationEntry(OrePrefix.nugget, Materials.Iron), OreDictUnifier.get(OrePrefix.nugget, Materials.WroughtIron)); + ModHandler.addShapedRecipe("clipboard", MetaItems.CLIPBOARD.getStackForm(), " Sd", "BWR", "PPP", 'P', Items.PAPER, 'R', new UnificationEntry(OrePrefix.springSmall, Iron), 'B', new UnificationEntry(OrePrefix.bolt, Iron), 'S', new UnificationEntry(OrePrefix.screw, Iron), 'W', new UnificationEntry(OrePrefix.plate, Wood)); + for (MetaValueItem batteryItem : ToolRecipeHandler.batteryItems[0]) { ModHandler.addShapedEnergyTransferRecipe("scanner_" + batteryItem.unlocalizedName, MetaItems.SCANNER.getStackForm(), batteryItem::isItemEqual, true, diff --git a/src/main/resources/assets/gregtech/blockstates/clipboard.json b/src/main/resources/assets/gregtech/blockstates/clipboard.json new file mode 100644 index 00000000000..607049158bf --- /dev/null +++ b/src/main/resources/assets/gregtech/blockstates/clipboard.json @@ -0,0 +1,10 @@ +{ + "forge_marker": 1, + "defaults": { + "model": "gregtech:clipboard" + }, + "variants": { + "normal": [{}], + "inventory": [{}] + } +} \ No newline at end of file diff --git a/src/main/resources/assets/gregtech/lang/en_us.lang b/src/main/resources/assets/gregtech/lang/en_us.lang index 2b17ba266c1..b07f882e64c 100644 --- a/src/main/resources/assets/gregtech/lang/en_us.lang +++ b/src/main/resources/assets/gregtech/lang/en_us.lang @@ -844,6 +844,9 @@ metaitem.turbine_rotor.name=%s Turbine Rotor metaitem.turbine_rotor.tooltip=Turbine Rotors for your power station metaitem.tool.magnifying_glass.name=%s Magnifying Glass +metaitem.clipboard.name=Clipboard +metaitem.clipboard.tooltip=Can be written on (without any writing Instrument). Right-click on Wall to place, and Shift-Right-Click to remove + metaitem.drill.mode.three_cube=3x3x3 Cube metaitem.drill.mode.five_cube=5x5x5 Cube metaitem.drill.mode.seven_cube=7x7x7 Cube @@ -2162,6 +2165,8 @@ gregtech.machine.stainless_steel_tank.name=Stainless Steel Tank gregtech.machine.titanium_tank.name=Titanium Tank gregtech.machine.tungstensteel_tank.name=Tungstensteel Tank +gregtech.machine.clipboard.name=Clipboard + # Granite blocks tile.granite.black_granite.normal.name=Black Granite tile.granite.black_granite.cracked.name=Black Granite Cobblestone diff --git a/src/main/resources/assets/gregtech/models/block/clipboard.json b/src/main/resources/assets/gregtech/models/block/clipboard.json new file mode 100644 index 00000000000..34b1288b6b3 --- /dev/null +++ b/src/main/resources/assets/gregtech/models/block/clipboard.json @@ -0,0 +1,97 @@ +{ + "credit": "Made with Blockbench", + "textures": { + "0": "clipboard/clipboard", + "1": "clipboard/page", + "particle": "clipboard/clipboard" + }, + "elements": [ + { + "from": [3, 0.25, 0.25], + "to": [13, 14.25, 0.3], + "rotation": {"angle": 0, "axis": "y", "origin": [8, 6.59375, 9.0125]}, + "faces": { + "north": {"uv": [8.5, 8.5, 13.5, 15.5], "texture": "#0"}, + "east": {"uv": [8.5, 8.5, 8.55, 15.5], "texture": "#0"}, + "south": {"uv": [0, 0, 11.42857, 16], "texture": "#1"}, + "west": {"uv": [8.5, 8.5, 8.55, 15.5], "texture": "#0"}, + "up": {"uv": [8.5, 8.5, 13.5, 8.55], "rotation": 180, "texture": "#0"}, + "down": {"uv": [8.5, 8.5, 13.5, 8.55], "rotation": 180, "texture": "#0"} + } + }, + { + "from": [2.75, 0, 0], + "to": [13.25, 15.25, 0.25], + "rotation": {"angle": 0, "axis": "y", "origin": [8, 6.59375, 9.0125]}, + "faces": { + "north": {"uv": [8.5, 0, 14, 7.75], "texture": "#0"}, + "east": {"uv": [8.5, 0, 8.75, 7.75], "texture": "#0"}, + "south": {"uv": [8.5, 0, 14, 7.75], "texture": "#0"}, + "west": {"uv": [8.5, 0, 8.75, 7.75], "texture": "#0"}, + "up": {"uv": [8.5, 0.5, 14, 0.75], "rotation": 180, "texture": "#0"}, + "down": {"uv": [8.5, 0.5, 14, 0.75], "rotation": 180, "texture": "#0"} + } + }, + { + "from": [5.75, 14.75, 0.25], + "to": [10.25, 15.5, 0.4], + "rotation": {"angle": 0, "axis": "y", "origin": [8, 6.59375, 9.0125]}, + "faces": { + "north": {"uv": [0.5, 0.5, 4, 1.25], "texture": "#0"}, + "east": {"uv": [0.5, 0.5, 0.65, 1.25], "texture": "#0"}, + "south": {"uv": [0.5, 0.5, 4, 1.25], "texture": "#0"}, + "west": {"uv": [0.5, 0.5, 0.65, 1.25], "texture": "#0"}, + "up": {"uv": [0.5, 0.5, 4, 0.65], "rotation": 180, "texture": "#0"}, + "down": {"uv": [0.5, 0.5, 4, 0.65], "rotation": 180, "texture": "#0"} + } + }, + { + "from": [7, 15.25, 0.1], + "to": [9, 16, 0.35], + "rotation": {"angle": 0, "axis": "y", "origin": [8, 6.59375, 9.0125]}, + "faces": { + "north": {"uv": [0.5, 0.5, 1.5, 1.25], "texture": "#0"}, + "east": {"uv": [0.5, 0.5, 0.75, 1.25], "texture": "#0"}, + "south": {"uv": [0.5, 0.5, 1.5, 1.25], "texture": "#0"}, + "west": {"uv": [0.5, 0.5, 0.75, 1.25], "texture": "#0"}, + "up": {"uv": [0.5, 0.5, 1.5, 0.75], "rotation": 180, "texture": "#0"}, + "down": {"uv": [0.5, 0.5, 1.5, 0.75], "rotation": 180, "texture": "#0"} + } + } + ], + "display": { + "thirdperson_righthand": { + "translation": [0, 4, 4], + "scale": [0.5, 0.5, 0.5] + }, + "thirdperson_lefthand": { + "translation": [0, 4, 4], + "scale": [0.5, 0.5, 0.5] + }, + "firstperson_righthand": { + "rotation": [-10, 0, 0], + "translation": [-1.5, 7.25, 7], + "scale": [0.5, 0.5, 0.5] + }, + "firstperson_lefthand": { + "rotation": [-10, 0, 0], + "translation": [-1.5, 7.25, 7], + "scale": [0.5, 0.5, 0.5] + }, + "ground": { + "translation": [0, 0.75, 4], + "scale": [0.5, 0.5, 0.5] + }, + "gui": { + "translation": [0.25, 0.25, 0] + }, + "head": { + "translation": [0, -8.25, 22.25], + "scale": [2, 2, 2] + }, + "fixed": { + "rotation": [0, -180, 0], + "translation": [0, 0.25, -8] + } + } +} \ No newline at end of file diff --git a/src/main/resources/assets/gregtech/models/item/metaitems/clipboard.json b/src/main/resources/assets/gregtech/models/item/metaitems/clipboard.json new file mode 100644 index 00000000000..7be55aa10b1 --- /dev/null +++ b/src/main/resources/assets/gregtech/models/item/metaitems/clipboard.json @@ -0,0 +1,94 @@ +{ + "credit": "Made with Blockbench", + "textures": { + "0": "gregtech:items/metaitems/clipboard/clipboard", + "1": "gregtech:items/metaitems/clipboard/page", + "particle": "gregtech:items/metaitems/clipboard/clipboard" + }, + "elements": [ + { + "from": [6, 1, 9.025], + "to": [11, 8, 9.075], + "rotation": {"angle": 0, "axis": "y", "origin": [8.5, 6.59375, 9.0125]}, + "faces": { + "north": {"uv": [8.5, 8.5, 13.5, 15.5], "texture": "#0"}, + "east": {"uv": [8.5, 8.5, 8.55, 15.5], "texture": "#0"}, + "south": {"uv": [0, 0, 11.42857, 16], "texture": "#1"}, + "west": {"uv": [8.5, 8.5, 8.55, 15.5], "texture": "#0"}, + "up": {"uv": [8.5, 8.5, 13.5, 8.55], "rotation": 180, "texture": "#0"}, + "down": {"uv": [8.5, 8.5, 13.5, 8.55], "rotation": 180, "texture": "#0"} + } + }, + { + "from": [5.75, 0.75, 8.775], + "to": [11.25, 8.5, 9.025], + "rotation": {"angle": 0, "axis": "y", "origin": [8.5, 6.59375, 9.0125]}, + "faces": { + "north": {"uv": [8.5, 0, 14, 7.75], "texture": "#0"}, + "east": {"uv": [8.5, 0, 8.75, 7.75], "texture": "#0"}, + "south": {"uv": [8.5, 0, 14, 7.75], "texture": "#0"}, + "west": {"uv": [8.5, 0, 8.75, 7.75], "texture": "#0"}, + "up": {"uv": [8.5, 0.5, 14, 0.75], "rotation": 180, "texture": "#0"}, + "down": {"uv": [8.5, 0.5, 14, 0.75], "rotation": 180, "texture": "#0"} + } + }, + { + "from": [6.75, 8, 9.025], + "to": [10.25, 8.75, 9.175], + "rotation": {"angle": 0, "axis": "y", "origin": [8.5, 6.59375, 9.0125]}, + "faces": { + "north": {"uv": [0.5, 0.5, 4, 1.25], "texture": "#0"}, + "east": {"uv": [0.5, 0.5, 0.65, 1.25], "texture": "#0"}, + "south": {"uv": [0.5, 0.5, 4, 1.25], "texture": "#0"}, + "west": {"uv": [0.5, 0.5, 0.65, 1.25], "texture": "#0"}, + "up": {"uv": [0.5, 0.5, 4, 0.65], "rotation": 180, "texture": "#0"}, + "down": {"uv": [0.5, 0.5, 4, 0.65], "rotation": 180, "texture": "#0"} + } + }, + { + "from": [8, 8.5, 8.875], + "to": [9, 9.25, 9.125], + "rotation": {"angle": 0, "axis": "y", "origin": [8.5, 6.59375, 9.0125]}, + "faces": { + "north": {"uv": [0.5, 0.5, 1.5, 1.25], "texture": "#0"}, + "east": {"uv": [0.5, 0.5, 0.75, 1.25], "texture": "#0"}, + "south": {"uv": [0.5, 0.5, 1.5, 1.25], "texture": "#0"}, + "west": {"uv": [0.5, 0.5, 0.75, 1.25], "texture": "#0"}, + "up": {"uv": [0.5, 0.5, 1.5, 0.75], "rotation": 180, "texture": "#0"}, + "down": {"uv": [0.5, 0.5, 1.5, 0.75], "rotation": 180, "texture": "#0"} + } + } + ], + "display": { + "thirdperson_righthand": { + "translation": [-0.5, 7, -0.5] + }, + "thirdperson_lefthand": { + "translation": [0.5, 7, -0.5] + }, + "firstperson_righthand": { + "rotation": [-10, 0, 0], + "translation": [-3, 10, 2.5] + }, + "firstperson_lefthand": { + "rotation": [-10, 0, 0], + "translation": [-2, 10, 2.5] + }, + "ground": { + "translation": [0, 3.75, 0] + }, + "gui": { + "translation": [-1, 5.5, 0], + "scale": [1.75, 1.75, 1.75] + }, + "head": { + "translation": [-1, 5.75, 5], + "scale": [2, 2, 2] + }, + "fixed": { + "rotation": [0, -180, 0], + "translation": [1.25, 8.25, 1.5], + "scale": [2.5, 2.5, 2.5] + } + } +} \ No newline at end of file diff --git a/src/main/resources/assets/gregtech/textures/blocks/clipboard/clip.png b/src/main/resources/assets/gregtech/textures/blocks/clipboard/clip.png new file mode 100644 index 0000000000000000000000000000000000000000..fcc101e54f2ba230ab5fd5a5f9b9c4f8b596f37b GIT binary patch literal 343 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61|;P_|4#%`jKx9jP7LeL$-D$|SkfJR9T^xl z_H+M9WCij$3p^r=85sBufG}g$wN6f;;2TdD#}Etu*vZ^{hYWa}Z|8l#&bMdn2cGp^ zS(;C>)uk`2e?2SL`MoXMvpKmv7w>)djeDJNBjLod1?jyrWB zuO;leN#*?0)@b%0F%Ks6YK6%MCi+}_|G4jKQG+wr_307j($BL^5+h3YEb3xB`r-c{ z@qi~WtSet@|J?Up)LrAIyjHl7Y0mMeBkW=9nMy&)Rp&g}1QQtE%O6$jJYxOi$#f2n l4pqjEBNDZWJHOwvd-Rd_!mI2i=c)I$ztaD0e0ssfCAoc(N literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/gregtech/textures/blocks/clipboard/wood.png b/src/main/resources/assets/gregtech/textures/blocks/clipboard/wood.png new file mode 100644 index 0000000000000000000000000000000000000000..304d851ba107a228dea20391741c9dd622050464 GIT binary patch literal 438 zcmV;n0ZIOeP)Px#1ZP1_K>z@;j|==^1poj532;bRa{vGizyJUazyWI3i3tDz0ZU0lK~y+TUD8={ z!!Qg3P}|vare3N?>KXHs&2jV4U?vS`WJx3dF4p+-{k4qaIILEy;qiD3(=_FLyWMi0 z=XqF`Wq@HY>-9Q2-?Z6m60jF^y_TrQVn0^*aA zj}gR4#XtyE

BjNdng;emEQ=JQdt*gc5j(l~mzohGSDcdU>vvsGZIP`FuX-ULve{ zxJQ7hGC8$VF@8ILXGM?*(Fpi3q=JaFjh+q89o`+zecJE$|4J(e;Cw$DvOG3GK|n+csDx(fBRZW%>y+)t`fAT5iSr?S`tuUoZ~r|Z*`2k~Br?J=@%#~>{>la!f<+9* gLV{Dx-%RG=7lZ3hxKlNv^#A|>07*qoM6N<$g1-{Gh5!Hn literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/gregtech/textures/gui/base/blank.png b/src/main/resources/assets/gregtech/textures/gui/base/blank.png new file mode 100644 index 0000000000000000000000000000000000000000..598fdc2de573fae8eca9cf331ee73e5fb7c06ad4 GIT binary patch literal 119 zcmeAS@N?(olHy`uVBq!ia0vp^j3CUx1SBVv2j2s6ii6yp7}lMWc?smOq&xaLGB9lH z=l+w(3gmMZctjR6FbI`^Fyp;6`3j&QkEe@ch(vgDLP7#a3j<@!+5ee97K5j&pUXO@ GgeCxVr5W}B literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/gregtech/textures/gui/widget/clipboard_button.png b/src/main/resources/assets/gregtech/textures/gui/widget/clipboard_button.png new file mode 100644 index 0000000000000000000000000000000000000000..cc5d98d8aaa2ead5951d4d778c2452c2da7744c2 GIT binary patch literal 7214 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 KU75|6o&N&&9c(QC literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/gregtech/textures/gui/widget/clipboard_checkbox.png b/src/main/resources/assets/gregtech/textures/gui/widget/clipboard_checkbox.png new file mode 100644 index 0000000000000000000000000000000000000000..04b8efe7722a669bf636bfc48e883bd40502be4a GIT binary patch literal 721 zcmV;?0xtcDP)EX>4Tx04R}tkvm8OK@>$#q7spag(*ZVwonUE5EZeMD2kvUNrXf#+}-?y>>73> zHkN{|VBx3nSJ+rg7?1B@S z3~TYkycT#NKoAJgqnmDiCOQ$L=K8$Dr_S3xl~w!QpQ|~Ua!v4Q!lP#1DF`nK53d#S zig#5NW>!xMp9%LmQlRjI(v1?oD$W$yuQEeUEHWk>64o+RY*ewCbu8f_;m)LGOTIr| z;-unr#a3?BEZ3wvT&NC=4mLEH$V|OEA;3-y1(-%Z` zB1>%T6*eL##;8|+L47$&!Zle*3nxVF6=1+c&Dp~bkn2-Km5MeY00000NkvXXu0mjf DeuymD literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/gregtech/textures/gui/widget/clipboard_text_box.png b/src/main/resources/assets/gregtech/textures/gui/widget/clipboard_text_box.png new file mode 100644 index 0000000000000000000000000000000000000000..21e4e0c365a6bab0a5eeec528ee93785c05bdcd6 GIT binary patch literal 5637 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 ALI3~& literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/gregtech/textures/gui/widget/left.png b/src/main/resources/assets/gregtech/textures/gui/widget/left.png new file mode 100644 index 0000000000000000000000000000000000000000..3d32885b8b71cc3952f78590c3620154eba5ac56 GIT binary patch literal 288 zcmV+*0pI?KP)Tu|i^jgSirAO95duorqUo;~x>byh3O6 z&_dseKrp;R2M7GY4LUf`?qBhXRa}95&TydByWktMFb9zV+N*OMXm-y~W$g(_&RZbo zEg7Aua~x=dCrGLM5QaO0;m%=__g|QW1?W!B(aM2(c!HEL`p7y{W;hgkp*uN8D+g-9 z5vq7P1j*PFK|INsiZgYN16BWkZ=y*bByEk6vBqMr&T*j9-s2Y;`kdiFxwV514wRZ( m=-@!Hv4IW|p!da6fwm{dnYJILaol780000Px#<4Ht8R5*>Ll1)y-Fc3zcom`+Ye+f|T%94w4FBYv*YN9SsThWe~l~b!P!pJ!iRi`O41; v2Y|kl>ooAzzA*v$9@cZ8L+-d`BQ00000NkvXXu0mjfWuA9< literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/gregtech/textures/items/metaitems/clipboard/clipboard.png b/src/main/resources/assets/gregtech/textures/items/metaitems/clipboard/clipboard.png new file mode 100644 index 0000000000000000000000000000000000000000..af69676cc7f8bf0e13deb94a7179a537dfc6b821 GIT binary patch literal 495 zcmVPx#1ZP1_K>z@;j|==^1poj5MNmvsMUaq?k&%&-l9H2?lc8}uqH;Z@bwHzYKB#y@ zpl~~+bU%)cj*pLzrglN9dPS#qLaBK~pKm&zZaI{cl&gD2oozV(|NoxUo$LSr010qN zS#tmY4!{5a4!{9w)`eL_t(IPwkOgcEd0TL_y*q5fRx=oBc1fgR_7xphf5S zLyU&YnC{}%xO073)ZB)fis}q?dQf8ssP)wsFG_ue=?LF`%y}BM27`J{%(NCw$w-r7 zLv-fl1cN%!lvI6;>1s;*b3=DjSK$uZf!>a)(_|((IF{C2y?X`nkO%4pMfp7o+-boFyt=akR{0AlKa A&j0`b literal 0 HcmV?d00001