diff --git a/changelog.md b/changelog.md index ebe24bbc..d7a075f7 100644 --- a/changelog.md +++ b/changelog.md @@ -16,7 +16,8 @@ Changes - Redid Bank Terminal texture to match other Create textures - You can now insert or extract items from all sides of a vendor - The buying/selling item slot in the vendor gui now acts like a ghost item (does not require actual items). - Backwards compatible with existing vendors, so the items will remain 'real' until you remove them + Backwards compatible with existing vendors, so the items will remain 'real' until you remove them. + Additionally, enchantments and dyes can be applied to some items by shift-dragging items when using EMI on fabric or JEI on forge ------------------------------------------------------ Numismatics 1.0.6 ------------------------------------------------------ diff --git a/common/src/generated/resources/.cache/630af4bded938901e0e1fd57c58a2ac245292828 b/common/src/generated/resources/.cache/630af4bded938901e0e1fd57c58a2ac245292828 index 94b2507f..889e8118 100644 --- a/common/src/generated/resources/.cache/630af4bded938901e0e1fd57c58a2ac245292828 +++ b/common/src/generated/resources/.cache/630af4bded938901e0e1fd57c58a2ac245292828 @@ -1,4 +1,4 @@ -// 1.20.1 2024-07-21T20:22:37.447106096 Create: Numismatics/Numismatics' Advancements +// 1.20.1 2024-07-24T07:41:10.619577249 Create: Numismatics/Numismatics' Advancements 4ab84595dc44460d6d89ff3608940dd8694b93d6 data/numismatics/advancements/is_this_legal.json 645c92e6e449889ed4cf617432fd6fa87ffe355b data/numismatics/advancements/questionable_investment.json 8f32fb49ef81058e2e660fac983dbef2f554db38 data/numismatics/advancements/root.json diff --git a/common/src/generated/resources/.cache/6ba62358bf8e130d42215f5f9edbedd611809677 b/common/src/generated/resources/.cache/6ba62358bf8e130d42215f5f9edbedd611809677 index 22a184de..e18bfd25 100644 --- a/common/src/generated/resources/.cache/6ba62358bf8e130d42215f5f9edbedd611809677 +++ b/common/src/generated/resources/.cache/6ba62358bf8e130d42215f5f9edbedd611809677 @@ -1,4 +1,4 @@ -// 1.20.1 2024-07-21T20:22:37.445651836 Create: Numismatics/Numismatics Standard Recipes +// 1.20.1 2024-07-24T07:41:10.617662486 Create: Numismatics/Numismatics Standard Recipes 0e1680b878cfa51c04809504b3542cb6312027a1 data/numismatics/recipes/crafting/gray_id_card.json 61954216f844eecdbee266da7e517a983993d2f8 data/numismatics/advancements/recipes/misc/crafting/brown_card.json 2c732f9c3bc02a29a4d86a0552f4dbbae986a34a data/numismatics/recipes/crafting/blue_authorized_card.json @@ -21,8 +21,8 @@ a9acb103fdf3c06e561b7252083fae594074ba40 data/numismatics/advancements/recipes/m da540ae92c84519149c1b37ad49290814f507a8a data/numismatics/advancements/recipes/misc/crafting/white_authorized_card.json 12014c6c5ac12fdddc45d61bdb3841e2f930125d data/numismatics/recipes/crafting/red_card.json 858305a3537cdcb5bb19b883e688ddb876f0473c data/numismatics/recipes/crafting/brown_id_card.json -ce32a3a7c2a5564e84b30bb1b71007ca4adc985d data/numismatics/recipes/crafting/lime_authorized_card.json 35d3c0460a2ba41603bea8e1453b26d662a1f2d5 data/numismatics/advancements/recipes/misc/crafting/yellow_authorized_card.json +ce32a3a7c2a5564e84b30bb1b71007ca4adc985d data/numismatics/recipes/crafting/lime_authorized_card.json 501f27ee03faeb675a05b63b0c8058f1473f02d5 data/numismatics/advancements/recipes/misc/crafting/purple_id_card.json 8d863132d01d516db98d228e9038425923b7354d data/numismatics/recipes/crafting/black_card.json 78af0a7f17e04133eae7172df3255aaa34034537 data/numismatics/advancements/recipes/misc/crafting/red_id_card.json diff --git a/common/src/generated/resources/.cache/816056b233c115f7af92c9ed2c207f096721f5cf b/common/src/generated/resources/.cache/816056b233c115f7af92c9ed2c207f096721f5cf new file mode 100644 index 00000000..7886b3ad --- /dev/null +++ b/common/src/generated/resources/.cache/816056b233c115f7af92c9ed2c207f096721f5cf @@ -0,0 +1,2 @@ +// 1.20.1 2024-07-24T07:41:10.61410668 Create: Numismatics/Numismatics EMI excluded tags +b57edab6f7e7a6e1b1211daa4c3b217ffd09ce62 assets/emi/tag/exclusions/numismatics.json diff --git a/common/src/generated/resources/.cache/c6e4c19894bc5aece2976a0277ba8e1dbf023865 b/common/src/generated/resources/.cache/c6e4c19894bc5aece2976a0277ba8e1dbf023865 index aabd1706..2c994166 100644 --- a/common/src/generated/resources/.cache/c6e4c19894bc5aece2976a0277ba8e1dbf023865 +++ b/common/src/generated/resources/.cache/c6e4c19894bc5aece2976a0277ba8e1dbf023865 @@ -1 +1 @@ -// 1.20.1 2024-07-21T20:22:37.446740402 Create: Numismatics/Numismatics' Sequenced Assembly Recipes +// 1.20.1 2024-07-24T07:41:10.619204352 Create: Numismatics/Numismatics' Sequenced Assembly Recipes diff --git a/common/src/generated/resources/.cache/d6a1ec2d08c6d6d7facbde77dda6f0158c00bbd6 b/common/src/generated/resources/.cache/d6a1ec2d08c6d6d7facbde77dda6f0158c00bbd6 index 5b875dcc..d327fefb 100644 --- a/common/src/generated/resources/.cache/d6a1ec2d08c6d6d7facbde77dda6f0158c00bbd6 +++ b/common/src/generated/resources/.cache/d6a1ec2d08c6d6d7facbde77dda6f0158c00bbd6 @@ -1,4 +1,4 @@ -// 1.20.1 2024-07-21T20:22:37.442752776 Create: Numismatics/Registrate Provider for numismatics [Recipes, Advancements, Loot Tables, Tags (blocks), Tags (items), Tags (fluids), Tags (entity_types), Blockstates, Item models, Lang (en_us/en_ud)] +// 1.20.1 2024-07-24T07:41:10.615215734 Create: Numismatics/Registrate Provider for numismatics [Recipes, Advancements, Loot Tables, Tags (blocks), Tags (items), Tags (fluids), Tags (entity_types), Blockstates, Item models, Lang (en_us/en_ud)] 2f1dad2a2e0086d54cf4b88378feacc04341d87f data/numismatics/tags/items/internal/ingots/iron_ingots.json dc5c60bbbaf3a5d7bc1f9bc0c9377757dbd8de49 data/numismatics/loot_tables/blocks/bank_terminal.json 5b0244502972f49d063d98fa0cb3f6fc65af82b2 data/numismatics/tags/items/internal/string.json @@ -8,7 +8,7 @@ a96d3d02794064cd9be1bca25a9ba6217675e6c5 assets/numismatics/models/item/white_id bb2a77462e6213eddde134f3cc3e9a3f07f07f3f assets/numismatics/models/item/yellow_authorized_card.json 74a4c7ca7a48382782e5dba33018dfc8255192c5 assets/numismatics/models/block/brass_depositor_locked.json 3f0d912779200aaaf55bef102d9b96acead1a636 data/numismatics/tags/items/internal/dyes/purple_dyes.json -60932ebc47cf9e9a14fc5bd8b4f8d30506a1d074 assets/numismatics/lang/en_us.json +bf4853dab3c317eaaf2f1196def7cda67212b493 assets/numismatics/lang/en_us.json 377e460c0dcf6d7de1b7ae235959105a7c45e4c4 assets/numismatics/models/item/cyan_authorized_card.json bde18ccd9c21484154597c6271750c0406082f61 data/forge/tags/blocks/relocation_not_supported.json eca751589c40725750e2c2baa6607e83255fd5f4 assets/numismatics/models/item/brown_authorized_card.json @@ -18,7 +18,7 @@ ad712dd2a2a7268dfa773f38a50d526952758d5c data/numismatics/tags/items/internal/dy 8550097149cebbfd50bdeac2003327b60a4aee9a assets/numismatics/models/item/light_gray_card.json 95b492bd9230dc90fca9395c823cef39e644d8f2 assets/numismatics/models/item/sprocket.json 70c481f36a9718ac48632e6939ac6ba785be4c9e assets/numismatics/models/item/black_id_card.json -b6539c792df61fc097c1dc8f843f7c4e9999cb73 assets/numismatics/lang/en_ud.json +64524e27a031690bba14cf8ea1f1d92e03f2ad54 assets/numismatics/lang/en_ud.json 1e78f650091a4a2c43e36fb815f23d0591e058a6 assets/numismatics/models/item/magenta_card.json 909f5d14f23199c064f6b91a421bb7b15e0f1a7d assets/numismatics/models/item/orange_authorized_card.json d6f017479b3cc538f73d7fb0a1e65d1742bab266 assets/numismatics/models/item/light_blue_id_card.json @@ -53,8 +53,8 @@ bde18ccd9c21484154597c6271750c0406082f61 data/c/tags/blocks/relocation_not_suppo d048d04208faa63f0014d614d6026a66fe118c11 data/numismatics/loot_tables/blocks/brass_depositor.json 790ff3c5da6a67a5de1ceb7138fa3e1c0fe97f80 data/numismatics/tags/items/internal/dyes/lime_dyes.json a8cb82f19034a0e724e12df45c883e9cd469c210 assets/numismatics/models/item/green_card.json -e1087e56db7b4d8812ab4617344f0ac8b0f0e6c7 assets/numismatics/models/item/light_gray_authorized_card.json 390db78c5393fca4f90018df51d1a79d11a64f72 assets/numismatics/models/item/light_blue_authorized_card.json +e1087e56db7b4d8812ab4617344f0ac8b0f0e6c7 assets/numismatics/models/item/light_gray_authorized_card.json c09892d2d189f147997d77f4ce39b0570729f030 assets/numismatics/models/item/lime_authorized_card.json 06ecd28cd97f4e8200dc396858695cad57b871c8 assets/numismatics/blockstates/blaze_banker.json 95ef415a564eba1d212053195d25b199427b94e3 assets/numismatics/blockstates/creative_vendor.json diff --git a/common/src/generated/resources/assets/emi/tag/exclusions/numismatics.json b/common/src/generated/resources/assets/emi/tag/exclusions/numismatics.json new file mode 100644 index 00000000..a0b09462 --- /dev/null +++ b/common/src/generated/resources/assets/emi/tag/exclusions/numismatics.json @@ -0,0 +1,31 @@ +{ + "block": [ + "numismatics:internal/relocation_not_supported" + ], + "item": [ + "numismatics:internal/string", + "numismatics:internal/nuggets/iron_nuggets", + "numismatics:internal/nuggets/zinc_nuggets", + "numismatics:internal/nuggets/brass_nuggets", + "numismatics:internal/plates/iron_plates", + "numismatics:internal/plates/gold_plates", + "numismatics:internal/ingots/copper_ingots", + "numismatics:internal/ingots/iron_ingots", + "numismatics:internal/dyes/white_dyes", + "numismatics:internal/dyes/orange_dyes", + "numismatics:internal/dyes/magenta_dyes", + "numismatics:internal/dyes/light_blue_dyes", + "numismatics:internal/dyes/yellow_dyes", + "numismatics:internal/dyes/lime_dyes", + "numismatics:internal/dyes/pink_dyes", + "numismatics:internal/dyes/gray_dyes", + "numismatics:internal/dyes/light_gray_dyes", + "numismatics:internal/dyes/cyan_dyes", + "numismatics:internal/dyes/purple_dyes", + "numismatics:internal/dyes/blue_dyes", + "numismatics:internal/dyes/brown_dyes", + "numismatics:internal/dyes/green_dyes", + "numismatics:internal/dyes/red_dyes", + "numismatics:internal/dyes/black_dyes" + ] +} \ No newline at end of file diff --git a/common/src/generated/resources/assets/numismatics/lang/en_ud.json b/common/src/generated/resources/assets/numismatics/lang/en_ud.json index f361ebfb..630b25c0 100644 --- a/common/src/generated/resources/assets/numismatics/lang/en_ud.json +++ b/common/src/generated/resources/assets/numismatics/lang/en_ud.json @@ -165,5 +165,12 @@ "numismatics.authorization_type.trusted_players": "ʎןuO sɹǝʎɐןԀ pǝʇsnɹ⟘", "numismatics.authorization_type.trusted_players.description": "ʇsıן ʇsnɹʇ ǝɥʇ uo sɹǝʎɐןd ʎןuO", "numismatics.special.ltr": "ǝnɹʇ", - "numismatics.trust_list.configure": "ʇsıꞀ ʇsnɹ⟘ ǝɹnbıɟuoƆ" + "numismatics.trust_list.configure": "ʇsıꞀ ʇsnɹ⟘ ǝɹnbıɟuoƆ", + "tag.block.numismatics.numismatics_blocks": "sʞɔoןᗺ sɔıʇɐɯsıɯnN", + "tag.item.forge.string": "buıɹʇS", + "tag.item.numismatics.authorized_cards": "spɹɐƆ pǝzıɹoɥʇnⱯ", + "tag.item.numismatics.cards": "spɹɐƆ", + "tag.item.numismatics.coins": "suıoƆ", + "tag.item.numismatics.id_cards": "spɹɐƆ pI", + "tag.item.numismatics.numismatics_items": "sɯǝʇI sɔıʇɐɯsıɯnN" } \ No newline at end of file diff --git a/common/src/generated/resources/assets/numismatics/lang/en_us.json b/common/src/generated/resources/assets/numismatics/lang/en_us.json index b9a16b97..f88a38e2 100644 --- a/common/src/generated/resources/assets/numismatics/lang/en_us.json +++ b/common/src/generated/resources/assets/numismatics/lang/en_us.json @@ -165,5 +165,12 @@ "numismatics.authorization_type.trusted_players": "Trusted Players Only", "numismatics.authorization_type.trusted_players.description": "Only players on the trust list", "numismatics.special.ltr": "true", - "numismatics.trust_list.configure": "Configure Trust List" + "numismatics.trust_list.configure": "Configure Trust List", + "tag.block.numismatics.numismatics_blocks": "Numismatics Blocks", + "tag.item.forge.string": "String", + "tag.item.numismatics.authorized_cards": "Authorized Cards", + "tag.item.numismatics.cards": "Cards", + "tag.item.numismatics.coins": "Coins", + "tag.item.numismatics.id_cards": "Id Cards", + "tag.item.numismatics.numismatics_items": "Numismatics Items" } \ No newline at end of file diff --git a/common/src/main/java/dev/ithundxr/createnumismatics/Numismatics.java b/common/src/main/java/dev/ithundxr/createnumismatics/Numismatics.java index 7f23a080..6128976d 100644 --- a/common/src/main/java/dev/ithundxr/createnumismatics/Numismatics.java +++ b/common/src/main/java/dev/ithundxr/createnumismatics/Numismatics.java @@ -29,6 +29,7 @@ import com.tterrag.registrate.providers.ProviderType; import dev.architectury.injectables.annotations.ExpectPlatform; import dev.ithundxr.createnumismatics.base.data.NumismaticsTagGen; +import dev.ithundxr.createnumismatics.base.data.emi.EmiExcludedTagGen; import dev.ithundxr.createnumismatics.base.data.lang.NumismaticsLangGen; import dev.ithundxr.createnumismatics.base.data.recipe.NumismaticsSequencedAssemblyRecipeGen; import dev.ithundxr.createnumismatics.base.data.recipe.NumismaticsStandardRecipeGen; @@ -106,6 +107,7 @@ public static void gatherData(DataGenerator.PackGenerator gen) { gen.addProvider(NumismaticsSequencedAssemblyRecipeGen::new); gen.addProvider(NumismaticsStandardRecipeGen::new); gen.addProvider(NumismaticsAdvancements::new); + gen.addProvider(EmiExcludedTagGen::new); } public static ResourceLocation asResource(String path) { diff --git a/common/src/main/java/dev/ithundxr/createnumismatics/base/data/emi/EmiExcludedTagGen.java b/common/src/main/java/dev/ithundxr/createnumismatics/base/data/emi/EmiExcludedTagGen.java new file mode 100644 index 00000000..d3998053 --- /dev/null +++ b/common/src/main/java/dev/ithundxr/createnumismatics/base/data/emi/EmiExcludedTagGen.java @@ -0,0 +1,77 @@ +/* + * Steam 'n' Rails + * Copyright (c) 2022-2024 The Railways Team + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see . + */ + +package dev.ithundxr.createnumismatics.base.data.emi; + +import com.google.gson.JsonArray; +import com.google.gson.JsonElement; +import com.google.gson.JsonObject; +import dev.ithundxr.createnumismatics.multiloader.CommonTag; +import dev.ithundxr.createnumismatics.multiloader.CommonTags; +import net.minecraft.data.CachedOutput; +import net.minecraft.data.DataProvider; +import net.minecraft.data.PackOutput; +import net.minecraft.world.item.Item; +import net.minecraft.world.level.block.Block; +import org.jetbrains.annotations.NotNull; + +import java.nio.file.Path; +import java.util.concurrent.CompletableFuture; + +public class EmiExcludedTagGen implements DataProvider { + private static final String INDENT = " "; + private final PackOutput packOutput; + + public EmiExcludedTagGen(PackOutput packOutput) { + this.packOutput = packOutput; + } + + @Override + public @NotNull CompletableFuture run(@NotNull CachedOutput output) { + Path path = this.packOutput.getOutputFolder() + .resolve("assets/emi/tag/exclusions/numismatics.json"); + + return DataProvider.saveStable(output, run(), path); + } + + private JsonElement run() { + JsonObject object = new JsonObject(); + { + JsonArray item = new JsonArray(); + // fill in items + for (CommonTag itemTag : CommonTags.ALL_ITEMS) { + item.add(itemTag.tag.location().toString()); + } + object.add("item", item); + } + { + JsonArray block = new JsonArray(); + // fill in blocks + for (CommonTag blockTag : CommonTags.ALL_BLOCKS) { + block.add(blockTag.tag.location().toString()); + } + object.add("block", block); + } + return object; + } + + @Override + public String getName() { + return "Numismatics EMI excluded tags"; + } +} diff --git a/common/src/main/java/dev/ithundxr/createnumismatics/base/data/lang/NumismaticsLangGen.java b/common/src/main/java/dev/ithundxr/createnumismatics/base/data/lang/NumismaticsLangGen.java index 2979308e..743e980c 100644 --- a/common/src/main/java/dev/ithundxr/createnumismatics/base/data/lang/NumismaticsLangGen.java +++ b/common/src/main/java/dev/ithundxr/createnumismatics/base/data/lang/NumismaticsLangGen.java @@ -25,6 +25,7 @@ import dev.ithundxr.createnumismatics.content.backend.Coin; import dev.ithundxr.createnumismatics.content.backend.sub_authorization.AuthorizationType; import dev.ithundxr.createnumismatics.registry.NumismaticsAdvancements; +import dev.ithundxr.createnumismatics.registry.NumismaticsTags; import java.util.Map; import java.util.function.BiConsumer; @@ -38,6 +39,7 @@ public static void generate(RegistrateLangProvider provider) { NumismaticsAdvancements.provideLang(langConsumer); AuthorizationType.provideLang(langConsumer); Coin.provideLang(langConsumer); + NumismaticsTags.provideLang(langConsumer); /* ================= */ /* Special data keys */ diff --git a/common/src/main/java/dev/ithundxr/createnumismatics/compat/Mods.java b/common/src/main/java/dev/ithundxr/createnumismatics/compat/Mods.java index ce1c9ad4..83816e26 100644 --- a/common/src/main/java/dev/ithundxr/createnumismatics/compat/Mods.java +++ b/common/src/main/java/dev/ithundxr/createnumismatics/compat/Mods.java @@ -31,7 +31,9 @@ public enum Mods { CARRYON("carryon"), SODIUM("sodium"), - COMPUTERCRAFT("computercraft") + COMPUTERCRAFT("computercraft"), + EMI("emi"), + JEI("jei") ; public final boolean isLoaded; diff --git a/common/src/main/java/dev/ithundxr/createnumismatics/content/backend/IGhostItemMenu.java b/common/src/main/java/dev/ithundxr/createnumismatics/content/backend/IGhostItemMenu.java new file mode 100644 index 00000000..eb311e8c --- /dev/null +++ b/common/src/main/java/dev/ithundxr/createnumismatics/content/backend/IGhostItemMenu.java @@ -0,0 +1,29 @@ +/* + * Numismatics + * Copyright (c) 2024 The Railways Team + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see . + */ + +package dev.ithundxr.createnumismatics.content.backend; + +import net.minecraft.world.item.ItemStack; + +public interface IGhostItemMenu { + void setGhostStackInSlot(int slotID, ItemStack stack); + boolean isSlotGhost(int slotID); + default boolean shouldGhostApplyEnchantsAndDye(int slotID) { + return true; + } +} diff --git a/common/src/main/java/dev/ithundxr/createnumismatics/content/vendor/VendorMenu.java b/common/src/main/java/dev/ithundxr/createnumismatics/content/vendor/VendorMenu.java index 8618e697..dfbb06db 100644 --- a/common/src/main/java/dev/ithundxr/createnumismatics/content/vendor/VendorMenu.java +++ b/common/src/main/java/dev/ithundxr/createnumismatics/content/vendor/VendorMenu.java @@ -21,6 +21,7 @@ import com.simibubi.create.foundation.gui.menu.MenuBase; import dev.ithundxr.createnumismatics.content.backend.BigStackSizeContainerSynchronizer; import dev.ithundxr.createnumismatics.content.backend.Coin; +import dev.ithundxr.createnumismatics.content.backend.IGhostItemMenu; import dev.ithundxr.createnumismatics.content.backend.IScrollableSlotMenu; import dev.ithundxr.createnumismatics.content.bank.AnyCardSlot; import dev.ithundxr.createnumismatics.content.coins.CoinDisplaySlot; @@ -41,7 +42,7 @@ import net.minecraft.world.level.block.entity.BlockEntity; import org.jetbrains.annotations.NotNull; -public class VendorMenu extends MenuBase implements IScrollableSlotMenu { +public class VendorMenu extends MenuBase implements IScrollableSlotMenu, IGhostItemMenu { public static final int COIN_SLOTS = Coin.values().length; public static final int CARD_SLOT_INDEX = COIN_SLOTS; public static final int FILTER_SLOT_INDEX = CARD_SLOT_INDEX + 1; @@ -225,7 +226,7 @@ public void setSynchronizer(@NotNull ContainerSynchronizer synchronizer) { @Override public void scrollSlot(int slotID, double delta, boolean shift) { - if (slotID == FILTER_SLOT_INDEX && !contentHolder.isFilterSlotLegacy()) { + if (isSlotGhost(slotID)) { Slot slot = getSlot(slotID); if (!slot.hasItem()) return; @@ -240,4 +241,16 @@ public void scrollSlot(int slotID, double delta, boolean shift) { slot.set(count == 0 ? ItemStack.EMPTY : stack.copyWithCount(count)); } } + + @Override + public void setGhostStackInSlot(int slotID, ItemStack stack) { + if (isSlotGhost(slotID)) { + getSlot(slotID).set(stack); + } + } + + @Override + public boolean isSlotGhost(int slotID) { + return slotID == FILTER_SLOT_INDEX && !contentHolder.isFilterSlotLegacy(); + } } diff --git a/common/src/main/java/dev/ithundxr/createnumismatics/multiloader/CommonTags.java b/common/src/main/java/dev/ithundxr/createnumismatics/multiloader/CommonTags.java index 64d62526..ac8e6f16 100644 --- a/common/src/main/java/dev/ithundxr/createnumismatics/multiloader/CommonTags.java +++ b/common/src/main/java/dev/ithundxr/createnumismatics/multiloader/CommonTags.java @@ -24,10 +24,15 @@ import net.minecraft.world.item.Item; import net.minecraft.world.level.block.Block; +import java.util.ArrayList; import java.util.EnumMap; +import java.util.List; import java.util.Map; public class CommonTags { + public static final List> ALL_ITEMS = new ArrayList<>(); + public static final List> ALL_BLOCKS = new ArrayList<>(); + public static final CommonTag STRING = item("string"), IRON_NUGGETS = item("nuggets/iron_nuggets", "iron_nuggets", "nuggets/iron"), @@ -55,11 +60,15 @@ public class CommonTags { RELOCATION_NOT_SUPPORTED = block("relocation_not_supported"); public static CommonTag block(String path) { - return CommonTag.conventional(Registries.BLOCK, path); + CommonTag tag = CommonTag.conventional(Registries.BLOCK, path); + ALL_BLOCKS.add(tag); + return tag; } public static CommonTag item(String common, String fabric, String forge) { - return CommonTag.conventional(Registries.ITEM, common, fabric, forge); + CommonTag tag = CommonTag.conventional(Registries.ITEM, common, fabric, forge); + ALL_ITEMS.add(tag); + return tag; } public static CommonTag item(String path) { diff --git a/common/src/main/java/dev/ithundxr/createnumismatics/registry/NumismaticsPackets.java b/common/src/main/java/dev/ithundxr/createnumismatics/registry/NumismaticsPackets.java index fc8d37b9..9f1ad3c0 100644 --- a/common/src/main/java/dev/ithundxr/createnumismatics/registry/NumismaticsPackets.java +++ b/common/src/main/java/dev/ithundxr/createnumismatics/registry/NumismaticsPackets.java @@ -40,6 +40,7 @@ public class NumismaticsPackets { .c2s(ConfigureSubAccountPacket.class, ConfigureSubAccountPacket::new) .c2s(AddSubAccountPacket.class, AddSubAccountPacket::new) .c2s(ScrollSlotPacket.class, ScrollSlotPacket::new) + .c2s(GhostItemSubmitPacket.class, GhostItemSubmitPacket::new) .s2c(BankAccountLabelPacket.class, BankAccountLabelPacket::new) .s2c(VarIntContainerSetDataPacket.class, VarIntContainerSetDataPacket::new) diff --git a/common/src/main/java/dev/ithundxr/createnumismatics/registry/NumismaticsTags.java b/common/src/main/java/dev/ithundxr/createnumismatics/registry/NumismaticsTags.java index 1190eb5e..9d271b50 100644 --- a/common/src/main/java/dev/ithundxr/createnumismatics/registry/NumismaticsTags.java +++ b/common/src/main/java/dev/ithundxr/createnumismatics/registry/NumismaticsTags.java @@ -20,6 +20,7 @@ import com.simibubi.create.foundation.utility.Lang; import dev.ithundxr.createnumismatics.Numismatics; +import dev.ithundxr.createnumismatics.util.TextUtils; import net.minecraft.core.Registry; import net.minecraft.core.registries.BuiltInRegistries; import net.minecraft.resources.ResourceLocation; @@ -30,6 +31,8 @@ import net.minecraft.world.level.block.Block; import net.minecraft.world.level.block.state.BlockState; +import java.util.function.BiConsumer; + public class NumismaticsTags { public enum NameSpace { @@ -157,4 +160,19 @@ public static void register() { AllBlockTags.register(); AllItemTags.register(); } + + public static void provideLang(BiConsumer consumer) { + for (AllBlockTags blockTag : AllBlockTags.values()) { + ResourceLocation loc = blockTag.tag.location(); + consumer.accept("tag.block." + loc.getNamespace() + "." + loc.getPath().replace('/', '.'), + TextUtils.titleCaseConversion(blockTag.name()).replace('_', ' ')); + } + + for (AllItemTags itemTag : AllItemTags.values()) { + ResourceLocation loc = itemTag.tag.location(); + consumer.accept("tag.item." + loc.getNamespace() + "." + loc.getPath().replace('/', '.'), + TextUtils.titleCaseConversion(itemTag.name().replace('_', ' '))); + } + consumer.accept("tag.item.forge.string", "String"); + } } diff --git a/common/src/main/java/dev/ithundxr/createnumismatics/registry/packets/GhostItemSubmitPacket.java b/common/src/main/java/dev/ithundxr/createnumismatics/registry/packets/GhostItemSubmitPacket.java new file mode 100644 index 00000000..392b98bb --- /dev/null +++ b/common/src/main/java/dev/ithundxr/createnumismatics/registry/packets/GhostItemSubmitPacket.java @@ -0,0 +1,47 @@ +/* + * Numismatics + * Copyright (c) 2024 The Railways Team + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see . + */ + +package dev.ithundxr.createnumismatics.registry.packets; + +import dev.ithundxr.createnumismatics.content.backend.IGhostItemMenu; +import dev.ithundxr.createnumismatics.multiloader.C2SPacket; +import net.minecraft.network.FriendlyByteBuf; +import net.minecraft.server.level.ServerPlayer; +import net.minecraft.world.item.ItemStack; + +public record GhostItemSubmitPacket(int slot, ItemStack stack) implements C2SPacket { + + public GhostItemSubmitPacket(FriendlyByteBuf buf) { + this(buf.readVarInt(), buf.readItem()); + } + + @Override + public void write(FriendlyByteBuf buffer) { + buffer.writeVarInt(slot); + buffer.writeItem(stack); + } + + @Override + public void handle(ServerPlayer sender) { + if (sender.containerMenu instanceof IGhostItemMenu ghostItemMenu) { + if (ghostItemMenu.isSlotGhost(slot)) { + ghostItemMenu.setGhostStackInSlot(slot, stack); + } + } + } +} diff --git a/common/src/main/java/dev/ithundxr/createnumismatics/util/ClientCraftingUtils.java b/common/src/main/java/dev/ithundxr/createnumismatics/util/ClientCraftingUtils.java new file mode 100644 index 00000000..01d090dc --- /dev/null +++ b/common/src/main/java/dev/ithundxr/createnumismatics/util/ClientCraftingUtils.java @@ -0,0 +1,224 @@ +/* + * Numismatics + * Copyright (c) 2024 The Railways Team + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see . + */ + +package dev.ithundxr.createnumismatics.util; + +import net.fabricmc.api.EnvType; +import net.fabricmc.api.Environment; +import net.minecraft.client.Minecraft; +import net.minecraft.world.SimpleContainer; +import net.minecraft.world.inventory.CraftingContainer; +import net.minecraft.world.item.EnchantedBookItem; +import net.minecraft.world.item.ItemStack; +import net.minecraft.world.item.Items; +import net.minecraft.world.item.crafting.ArmorDyeRecipe; +import net.minecraft.world.item.enchantment.Enchantment; +import net.minecraft.world.item.enchantment.EnchantmentHelper; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +import java.util.List; +import java.util.Map; + +@Environment(EnvType.CLIENT) +public class ClientCraftingUtils { + /** + * Apply stacking crafts to an item stack. + * @param targetStack The item stack to apply the stacking crafts to. + * @param droppedStack The item stack to apply the stacking crafts from. + * @return The item stack with the stacking crafts applied, or null if it couldn't be applied. + * Note: The stack may be identical, but it will never be the same instance. + */ + public static @NotNull Result applyStackingCrafts(@NotNull ItemStack targetStack, @NotNull ItemStack droppedStack) { + Result dyeResult = applyDye(targetStack, droppedStack); + if (dyeResult.isOk()) + return dyeResult; + return applyEnchant(targetStack, droppedStack); + } + + /** + * Apply an enchantment from an enchanted book to an item stack. + * @param targetStack The item stack to apply the enchantment to. + * @param enchantedBook The enchanted book to apply the enchantment from. + * @return The item stack with the enchantment applied, or null if it couldn't be applied. + * Note: The stack may be identical, but it will never be the same instance. + */ + public static @NotNull Result applyEnchant(@NotNull ItemStack targetStack, @NotNull ItemStack enchantedBook) { + if (targetStack.isEmpty() || enchantedBook.isEmpty()) + return targetStack.isEmpty() ? Result.failureReplace(enchantedBook.copy()) : Result.failureKeep(); + + if (!enchantedBook.is(Items.ENCHANTED_BOOK)) + return Result.failureReplace(enchantedBook.copy()); + + if (EnchantedBookItem.getEnchantments(enchantedBook).isEmpty()) + return Result.failureKeep(); + + targetStack = targetStack.copy(); + + Map targetEnchants = EnchantmentHelper.getEnchantments(targetStack); + Map bookEnchants = EnchantmentHelper.getEnchantments(enchantedBook); + boolean someEnchantsSucceeded = false; + boolean someEnchantsFailed = false; + + for (Enchantment bookEnchantment : bookEnchants.keySet()) { + if (bookEnchantment == null) + continue; + + int existingLevel = targetEnchants.getOrDefault(bookEnchantment, 0); + int bookLevel = bookEnchants.get(bookEnchantment); + + if (existingLevel == bookLevel) + bookLevel++; + else + bookLevel = Math.max(bookLevel, existingLevel); + + boolean ok = bookEnchantment.canEnchant(targetStack) || targetStack.is(Items.ENCHANTED_BOOK); + + for (Enchantment existingEnchantment : targetEnchants.keySet()) { + if (existingEnchantment != bookEnchantment && !bookEnchantment.isCompatibleWith(existingEnchantment)) { + ok = false; + } + } + + if (!ok) { + someEnchantsFailed = true; + } else { + someEnchantsSucceeded = true; + + if (bookLevel > bookEnchantment.getMaxLevel()) + bookLevel = bookEnchantment.getMaxLevel(); + + targetEnchants.put(bookEnchantment, bookLevel); + } + } + + if (someEnchantsFailed && !someEnchantsSucceeded) + return Result.failureKeep(); + + EnchantmentHelper.setEnchantments(targetEnchants, targetStack); + return Result.ok(targetStack); + } + + /** + * Apply a dye to an item stack. + * @param targetStack The item stack to apply the dye to (leather armor etc.). + * @param dye The dye to apply. + * @return The item stack with the dye applied, or null if it couldn't be applied. + */ + public static @NotNull Result applyDye(@NotNull ItemStack targetStack, @NotNull ItemStack dye) { + targetStack = targetStack.copy(); + ItemStack dye$ = dye.copy(); + + Minecraft mc = Minecraft.getInstance(); + if (mc.level == null) + return Result.failureKeep(); + + CraftingContainer craftingContainer = new SimpleCraftingContainer(2, 1); + craftingContainer.setItem(0, targetStack); + craftingContainer.setItem(1, dye$); + + return mc.level.getRecipeManager() + .getRecipes() + .stream() + .filter(recipe -> recipe instanceof ArmorDyeRecipe) + .map(recipe -> (ArmorDyeRecipe) recipe) + .filter(recipe -> recipe.matches(craftingContainer, mc.level)) + .findFirst() + .map(recipe -> recipe.assemble(craftingContainer, mc.level.registryAccess())) + .filter(result -> !result.isEmpty()) + .map(Result::ok) + .orElseGet(() -> Result.failureReplace(dye$)); + } + + private static class SimpleCraftingContainer extends SimpleContainer implements CraftingContainer { + + protected int width; + protected int height; + + public SimpleCraftingContainer(int width, int height) { + super(width * height); + + this.width = width; + this.height = height; + } + + @Override + public int getWidth() { + return width; + } + + @Override + public int getHeight() { + return height; + } + + @Override + public @NotNull List getItems() { + return items; + } + } + + public static class Result { + private final @Nullable ItemStack stack; + private final @NotNull ResultType type; + + private static final Result FAILURE_KEEP = new Result(null, ResultType.FAILURE_KEEP); + + private Result(@Nullable ItemStack stack, @NotNull ResultType type) { + this.stack = stack; + this.type = type; + } + + public static Result ok(@NotNull ItemStack stack) { + return new Result(stack, ResultType.SUCCESS); + } + + public static Result failureReplace(@NotNull ItemStack new_) { + return new Result(new_, ResultType.FAILURE_REPLACE); + } + + public static Result failureKeep() { + return FAILURE_KEEP; + } + + public boolean isOk() { + return type == ResultType.SUCCESS; + } + + public @NotNull ItemStack getResult(@NotNull ItemStack existing, boolean inheritCount) { + return switch (type) { + case SUCCESS -> stack == null + ? existing : + (inheritCount + ? stack.copyWithCount(existing.getCount()) + : stack + ); + case FAILURE_REPLACE -> stack == null + ? existing + : stack; + case FAILURE_KEEP -> existing; + }; + } + } + + public enum ResultType { + SUCCESS, + FAILURE_REPLACE, + FAILURE_KEEP + } +} diff --git a/fabric/build.gradle.kts b/fabric/build.gradle.kts index 11fb4b12..b58312cd 100644 --- a/fabric/build.gradle.kts +++ b/fabric/build.gradle.kts @@ -82,6 +82,7 @@ dependencies { modLocalRuntime("maven.modrinth:lazydfu:${"lazydfu_version"()}") modLocalRuntime("com.terraformersmc:modmenu:${"modmenu_version"()}") + modCompileOnly("dev.emi:emi-fabric:${"emi_version"()}:api") modLocalRuntime("dev.emi:emi-fabric:${"emi_version"()}") modCompileOnly("cc.tweaked:cc-tweaked-${"minecraft_version"()}-fabric-api:${"cc_version"()}") diff --git a/fabric/src/main/java/dev/ithundxr/createnumismatics/compat/emi/fabric/GhostIngredientHandler.java b/fabric/src/main/java/dev/ithundxr/createnumismatics/compat/emi/fabric/GhostIngredientHandler.java new file mode 100644 index 00000000..a0a480f6 --- /dev/null +++ b/fabric/src/main/java/dev/ithundxr/createnumismatics/compat/emi/fabric/GhostIngredientHandler.java @@ -0,0 +1,81 @@ +/* + * Numismatics + * Copyright (c) 2024 The Railways Team + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see . + */ + +package dev.ithundxr.createnumismatics.compat.emi.fabric; + +import com.simibubi.create.AllKeys; +import com.simibubi.create.foundation.gui.menu.AbstractSimiContainerScreen; +import com.simibubi.create.foundation.gui.menu.MenuBase; +import dev.emi.emi.api.EmiDragDropHandler; +import dev.emi.emi.api.stack.EmiIngredient; +import dev.emi.emi.api.stack.EmiStack; +import dev.ithundxr.createnumismatics.content.backend.IGhostItemMenu; +import dev.ithundxr.createnumismatics.registry.NumismaticsPackets; +import dev.ithundxr.createnumismatics.registry.packets.GhostItemSubmitPacket; +import dev.ithundxr.createnumismatics.util.ClientCraftingUtils; +import io.github.fabricators_of_create.porting_lib.mixin.accessors.client.accessor.AbstractContainerScreenAccessor; +import io.github.fabricators_of_create.porting_lib.transfer.item.ItemHandlerHelper; +import net.minecraft.MethodsReturnNonnullByDefault; +import net.minecraft.client.renderer.Rect2i; +import net.minecraft.world.inventory.Slot; +import net.minecraft.world.item.ItemStack; + +import javax.annotation.ParametersAreNonnullByDefault; +import java.util.List; + +@MethodsReturnNonnullByDefault +@ParametersAreNonnullByDefault +public class GhostIngredientHandler & IGhostItemMenu> + implements EmiDragDropHandler> { + + @Override + public boolean dropStack(AbstractSimiContainerScreen gui, EmiIngredient ingredient, int x, int y) { + List stacks = ingredient.getEmiStacks(); + if (!(gui instanceof AbstractContainerScreenAccessor access) || stacks.size() != 1) + return false; + ItemStack stack = stacks.get(0).getItemStack(); + if (stack.isEmpty()) + return false; + + for (int i = 0; i < gui.getMenu().slots.size(); i++) { + Slot slot = gui.getMenu().slots.get(i); + if (slot.isActive() && gui.getMenu().isSlotGhost(i)) { + Rect2i slotArea = new Rect2i(access.port_lib$getGuiLeft() + slot.x, access.port_lib$getGuiTop() + slot.y, 16, 16); + if (slotArea.contains(x, y)) { + acceptStack(gui, i, stack); + return true; + } + } + } + + return false; + } + + private void acceptStack(AbstractSimiContainerScreen gui, int slotIndex, ItemStack stack) { + stack = ItemHandlerHelper.copyStackWithSize(stack, 1); + if (gui.getMenu().shouldGhostApplyEnchantsAndDye(slotIndex) && AllKeys.shiftDown()) { + ItemStack existing = gui.getMenu().getSlot(slotIndex).getItem(); + ClientCraftingUtils.Result result = ClientCraftingUtils.applyStackingCrafts(existing, stack); + stack = result.getResult(existing, true); + } + gui.getMenu().setGhostStackInSlot(slotIndex, stack); + + // sync new filter contents with server + NumismaticsPackets.PACKETS.send(new GhostItemSubmitPacket(slotIndex, stack)); + } +} diff --git a/fabric/src/main/java/dev/ithundxr/createnumismatics/compat/emi/fabric/NumismaticsEmiPlugin.java b/fabric/src/main/java/dev/ithundxr/createnumismatics/compat/emi/fabric/NumismaticsEmiPlugin.java new file mode 100644 index 00000000..df9cace4 --- /dev/null +++ b/fabric/src/main/java/dev/ithundxr/createnumismatics/compat/emi/fabric/NumismaticsEmiPlugin.java @@ -0,0 +1,31 @@ +/* + * Numismatics + * Copyright (c) 2024 The Railways Team + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see . + */ + +package dev.ithundxr.createnumismatics.compat.emi.fabric; + +import dev.emi.emi.api.EmiPlugin; +import dev.emi.emi.api.EmiRegistry; +import dev.ithundxr.createnumismatics.content.vendor.VendorScreen; + +public class NumismaticsEmiPlugin implements EmiPlugin { + @Override + @SuppressWarnings({"rawtypes", "unchecked"}) // Java isn't clever enough to figure out GhostIngredientHandler + public void register(EmiRegistry registry) { + registry.addDragDropHandler(VendorScreen.class, new GhostIngredientHandler()); + } +} diff --git a/fabric/src/main/resources/fabric.mod.json b/fabric/src/main/resources/fabric.mod.json index fc8fbcf8..c7c98b09 100644 --- a/fabric/src/main/resources/fabric.mod.json +++ b/fabric/src/main/resources/fabric.mod.json @@ -22,6 +22,9 @@ ], "fabric-datagen": [ "dev.ithundxr.createnumismatics.fabric.NumismaticsDataFabric" + ], + "emi": [ + "dev.ithundxr.createnumismatics.compat.emi.fabric.NumismaticsEmiPlugin" ] }, "mixins": [ diff --git a/forge/build.gradle.kts b/forge/build.gradle.kts index 77dc4bec..c4898143 100644 --- a/forge/build.gradle.kts +++ b/forge/build.gradle.kts @@ -48,6 +48,20 @@ repositories { includeGroup("cc.tweaked") } } + maven("https://maven.blamejared.com/") { + // location of the maven that hosts JEI files since January 2023 + name = "Jared's maven" + content { + includeGroup("mezz.jei") + } + } + maven("https://modmaven.dev") { + // location of a maven mirror for JEI files, as a fallback + name = "ModMaven" + content { + includeGroup("mezz.jei") + } + } } dependencies { @@ -71,6 +85,12 @@ dependencies { forgeRuntimeLibrary("io.netty:netty-codec-socks:4.1.82.Final") forgeRuntimeLibrary("io.netty:netty-handler-proxy:4.1.82.Final") + // compile against the JEI API but do not include it at runtime + modCompileOnly("mezz.jei:jei-${"minecraft_version"()}-common-api:${"jei_version"()}") + modCompileOnly("mezz.jei:jei-${"minecraft_version"()}-forge-api:${"jei_version"()}") + // at runtime, use the full JEI jar for Forge + modLocalRuntime("mezz.jei:jei-${"minecraft_version"()}-forge:${"jei_version"()}") + if ("enable_cc"().toBoolean()) { modLocalRuntime("cc.tweaked:cc-tweaked-${"minecraft_version"()}-forge:${"cc_version"()}") } diff --git a/forge/src/main/java/dev/ithundxr/createnumismatics/compat/jei/forge/GhostIngredientHandler.java b/forge/src/main/java/dev/ithundxr/createnumismatics/compat/jei/forge/GhostIngredientHandler.java new file mode 100644 index 00000000..23a39aac --- /dev/null +++ b/forge/src/main/java/dev/ithundxr/createnumismatics/compat/jei/forge/GhostIngredientHandler.java @@ -0,0 +1,106 @@ +/* + * Numismatics + * Copyright (c) 2024 The Railways Team + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see . + */ + +package dev.ithundxr.createnumismatics.compat.jei.forge; + +import com.simibubi.create.AllKeys; +import com.simibubi.create.foundation.gui.menu.AbstractSimiContainerScreen; +import com.simibubi.create.foundation.gui.menu.MenuBase; +import dev.ithundxr.createnumismatics.content.backend.IGhostItemMenu; +import dev.ithundxr.createnumismatics.registry.NumismaticsPackets; +import dev.ithundxr.createnumismatics.registry.packets.GhostItemSubmitPacket; +import dev.ithundxr.createnumismatics.util.ClientCraftingUtils; +import mezz.jei.api.constants.VanillaTypes; +import mezz.jei.api.gui.handlers.IGhostIngredientHandler; +import mezz.jei.api.ingredients.ITypedIngredient; +import net.minecraft.MethodsReturnNonnullByDefault; +import net.minecraft.client.renderer.Rect2i; +import net.minecraft.world.inventory.Slot; +import net.minecraft.world.item.ItemStack; + +import javax.annotation.ParametersAreNonnullByDefault; +import java.util.LinkedList; +import java.util.List; + +@MethodsReturnNonnullByDefault +@ParametersAreNonnullByDefault +public class GhostIngredientHandler & IGhostItemMenu> + implements IGhostIngredientHandler> { + + @Override + public List> getTargetsTyped(AbstractSimiContainerScreen gui, ITypedIngredient ingredient, + boolean doStart) { + List> targets = new LinkedList<>(); + + if (ingredient.getType() == VanillaTypes.ITEM_STACK) { + for (int i = 0; i < gui.getMenu().slots.size(); i++) { + if (gui.getMenu().slots.get(i).isActive() && gui.getMenu().isSlotGhost(i)) + targets.add(new GhostTarget<>(gui, i)); + } + } + + return targets; + } + + @Override + public void onComplete() {} + + @Override + public boolean shouldHighlightTargets() { + // TODO change to false and highlight the slots ourself in some better way + return true; + } + + private static class GhostTarget & IGhostItemMenu> implements Target { + + private final Rect2i area; + private final AbstractSimiContainerScreen gui; + private final int slotIndex; + + public GhostTarget(AbstractSimiContainerScreen gui, int slotIndex) { + this.gui = gui; + this.slotIndex = slotIndex; + Slot slot = gui.getMenu().slots.get(slotIndex); + this.area = new Rect2i(gui.getGuiLeft() + slot.x, gui.getGuiTop() + slot.y, 16, 16); + } + + @Override + public Rect2i getArea() { + return area; + } + + @Override + public void accept(I ingredient) { + ItemStack stack = ((ItemStack) ingredient).copy(); + stack.setCount(1); + if (!gui.getMenu().isSlotGhost(slotIndex)) + return; + + if (gui.getMenu().shouldGhostApplyEnchantsAndDye(slotIndex) && AllKeys.shiftDown()) { + ItemStack existing = gui.getMenu().getSlot(slotIndex).getItem(); + ClientCraftingUtils.Result result = ClientCraftingUtils.applyStackingCrafts(existing, stack); + stack = result.getResult(existing, true); + } + + gui.getMenu().setGhostStackInSlot(slotIndex, stack); + + // sync new filter contents with server + NumismaticsPackets.PACKETS.send(new GhostItemSubmitPacket(slotIndex, stack)); + } + } +} diff --git a/forge/src/main/java/dev/ithundxr/createnumismatics/compat/jei/forge/NumismaticsJEI.java b/forge/src/main/java/dev/ithundxr/createnumismatics/compat/jei/forge/NumismaticsJEI.java new file mode 100644 index 00000000..ca106495 --- /dev/null +++ b/forge/src/main/java/dev/ithundxr/createnumismatics/compat/jei/forge/NumismaticsJEI.java @@ -0,0 +1,48 @@ +/* + * Numismatics + * Copyright (c) 2024 The Railways Team + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see . + */ + +package dev.ithundxr.createnumismatics.compat.jei.forge; + +import dev.ithundxr.createnumismatics.Numismatics; +import dev.ithundxr.createnumismatics.content.vendor.VendorScreen; +import mezz.jei.api.IModPlugin; +import mezz.jei.api.JeiPlugin; +import mezz.jei.api.registration.IGuiHandlerRegistration; +import net.minecraft.resources.ResourceLocation; +import org.jetbrains.annotations.NotNull; + +import javax.annotation.ParametersAreNonnullByDefault; + +@JeiPlugin +@SuppressWarnings("unused") +@ParametersAreNonnullByDefault +public class NumismaticsJEI implements IModPlugin { + + private static final ResourceLocation ID = Numismatics.asResource("jei_plugin"); + + @Override + public @NotNull ResourceLocation getPluginUid() { + return ID; + } + + @Override + @SuppressWarnings({"rawtypes", "unchecked"}) + public void registerGuiHandlers(IGuiHandlerRegistration registration) { + registration.addGhostIngredientHandler(VendorScreen.class, new GhostIngredientHandler()); + } +} diff --git a/gradle.properties b/gradle.properties index dab0faff..925f8bc8 100644 --- a/gradle.properties +++ b/gradle.properties @@ -38,17 +38,12 @@ flywheel_forge_version = 0.6.10-8 # https://github.com/LlamaLad7/MixinExtras mixin_extras_version = 0.3.5 -# Development QOL -# Create Fabric supports all 3 recipe viewers: JEI, REI, and EMI. This decides which is enabled at runtime. -# set to disabled to have none of them. -recipe_viewer = emi -# JEI - https://www.curseforge.com/minecraft/mc-mods/jei/files -jei_version = 15.2.0.27 -# REI - https://modrinth.com/mod/rei/versions -rei_version = 12.0.674 # EMI - https://modrinth.com/mod/emi/versions emi_version = 1.0.28+1.20.1 +# JEI - https://modrinth.com/mod/jei/versions +jei_version = 15.8.0.16 + # Mod Menu - https://modrinth.com/mod/modmenu/versions modmenu_version = 7.2.2 # LazyDFU - https://modrinth.com/mod/lazydfu/versions