diff options
| author | 2024-01-05 22:18:56 +0100 | |
|---|---|---|
| committer | 2024-01-05 22:18:56 +0100 | |
| commit | 9445749ede3c61d3db9324184971b319b4a8bd1d (patch) | |
| tree | 22b1b6b2c337756fe6d0b97effbca60fb8a8c961 /src/main/java/lv | |
| download | mc-eris-alchemy-9445749ede3c61d3db9324184971b319b4a8bd1d.tar.gz mc-eris-alchemy-9445749ede3c61d3db9324184971b319b4a8bd1d.tar.xz mc-eris-alchemy-9445749ede3c61d3db9324184971b319b4a8bd1d.zip | |
Initial Commit
Diffstat (limited to 'src/main/java/lv')
3 files changed, 256 insertions, 0 deletions
diff --git a/src/main/java/lv/enes/mc/eris_alchemy/CovalenceRepair.java b/src/main/java/lv/enes/mc/eris_alchemy/CovalenceRepair.java new file mode 100644 index 0000000..2e9da77 --- /dev/null +++ b/src/main/java/lv/enes/mc/eris_alchemy/CovalenceRepair.java | |||
| @@ -0,0 +1,167 @@ | |||
| 1 | package lv.enes.mc.eris_alchemy; | ||
| 2 | |||
| 3 | import com.google.gson.Gson; | ||
| 4 | import com.google.gson.JsonElement; | ||
| 5 | import com.google.gson.JsonObject; | ||
| 6 | import com.google.gson.JsonSyntaxException; | ||
| 7 | import net.minecraft.core.RegistryAccess; | ||
| 8 | import net.minecraft.network.FriendlyByteBuf; | ||
| 9 | import net.minecraft.resources.ResourceLocation; | ||
| 10 | import net.minecraft.world.inventory.CraftingContainer; | ||
| 11 | import net.minecraft.world.item.ItemStack; | ||
| 12 | import net.minecraft.world.item.crafting.CraftingBookCategory; | ||
| 13 | import net.minecraft.world.item.crafting.CustomRecipe; | ||
| 14 | import net.minecraft.world.item.crafting.Ingredient; | ||
| 15 | import net.minecraft.world.item.crafting.RecipeSerializer; | ||
| 16 | import net.minecraft.world.level.Level; | ||
| 17 | import org.quiltmc.qsl.recipe.api.serializer.QuiltRecipeSerializer; | ||
| 18 | |||
| 19 | import java.util.ArrayList; | ||
| 20 | import java.util.Arrays; | ||
| 21 | |||
| 22 | public class CovalenceRepair extends CustomRecipe { | ||
| 23 | static class Serializer implements QuiltRecipeSerializer<CovalenceRepair> { | ||
| 24 | private static class Json { | ||
| 25 | CraftingBookCategory category = CraftingBookCategory.MISC; | ||
| 26 | JsonElement dust; | ||
| 27 | JsonElement materials = new JsonObject(); | ||
| 28 | JsonElement tools = new JsonObject(); | ||
| 29 | } | ||
| 30 | |||
| 31 | private Serializer() {} | ||
| 32 | |||
| 33 | public static final Serializer INSTANCE = new Serializer(); | ||
| 34 | public static final ResourceLocation ID = new ResourceLocation(ErisAlchemy.ID, "covalence_repair"); | ||
| 35 | |||
| 36 | @Override | ||
| 37 | public JsonObject toJson(CovalenceRepair recipe) { | ||
| 38 | var res = new JsonObject(); | ||
| 39 | res.addProperty("category", recipe.category().toString()); | ||
| 40 | res.add("dust", recipe.dust.toJson()); | ||
| 41 | res.add("materials", recipe.materials.toJson()); | ||
| 42 | res.add("tools", recipe.tools.toJson()); | ||
| 43 | return res; | ||
| 44 | } | ||
| 45 | |||
| 46 | @Override | ||
| 47 | public CovalenceRepair fromJson(ResourceLocation id, JsonObject json) { | ||
| 48 | var recipeJson = new Gson().fromJson(json, Json.class); | ||
| 49 | if (recipeJson.dust == null) { | ||
| 50 | throw new JsonSyntaxException("A required attribute is missing"); | ||
| 51 | } | ||
| 52 | |||
| 53 | var dust = Ingredient.fromJson(recipeJson.dust); | ||
| 54 | var materials = Ingredient.fromJson(recipeJson.materials); | ||
| 55 | var tools = Ingredient.fromJson(recipeJson.tools); | ||
| 56 | |||
| 57 | return new CovalenceRepair(id, recipeJson.category, dust, materials, tools); | ||
| 58 | } | ||
| 59 | |||
| 60 | @Override | ||
| 61 | public void toNetwork(FriendlyByteBuf buf, CovalenceRepair recipe) { | ||
| 62 | buf.writeEnum(recipe.category()); | ||
| 63 | recipe.dust.toNetwork(buf); | ||
| 64 | recipe.materials.toNetwork(buf); | ||
| 65 | recipe.tools.toNetwork(buf); | ||
| 66 | } | ||
| 67 | |||
| 68 | @Override | ||
| 69 | public CovalenceRepair fromNetwork(ResourceLocation id, FriendlyByteBuf buf) { | ||
| 70 | var category = buf.readEnum(CraftingBookCategory.class); | ||
| 71 | var dust = Ingredient.fromNetwork(buf); | ||
| 72 | var materials = Ingredient.fromNetwork(buf); | ||
| 73 | var tools = Ingredient.fromNetwork(buf); | ||
| 74 | return new CovalenceRepair(id, category, dust, materials, tools); | ||
| 75 | } | ||
| 76 | } | ||
| 77 | |||
| 78 | private record Inputs(ItemStack toolStack, int dustCount) {} | ||
| 79 | |||
| 80 | private final static int DUSTS_TO_FIX = 8; | ||
| 81 | |||
| 82 | /** What dust do we use to repair. */ | ||
| 83 | private final Ingredient dust; | ||
| 84 | /** What materials this dust can repair. */ | ||
| 85 | private final Ingredient materials; | ||
| 86 | /** What tools can this dust repair. */ | ||
| 87 | private final Ingredient tools; | ||
| 88 | |||
| 89 | public CovalenceRepair(ResourceLocation id, CraftingBookCategory category, Ingredient dust, Ingredient materials, Ingredient tools) { | ||
| 90 | super(id, category); | ||
| 91 | |||
| 92 | this.dust = dust; | ||
| 93 | this.materials = materials; | ||
| 94 | this.tools = tools; | ||
| 95 | } | ||
| 96 | |||
| 97 | @Override | ||
| 98 | public boolean canCraftInDimensions(int width, int height) { | ||
| 99 | return width * height > 2; | ||
| 100 | } | ||
| 101 | |||
| 102 | @Override | ||
| 103 | public boolean matches(CraftingContainer inventory, Level world) { | ||
| 104 | return getInputs(inventory) != null; | ||
| 105 | } | ||
| 106 | |||
| 107 | @Override | ||
| 108 | public ItemStack assemble(CraftingContainer inventory, RegistryAccess registryManager) { | ||
| 109 | var inputs = getInputs(inventory); | ||
| 110 | if (inputs == null) { | ||
| 111 | return ItemStack.EMPTY; | ||
| 112 | } | ||
| 113 | |||
| 114 | var newToolStack = inputs.toolStack.copy(); | ||
| 115 | var repairedAmount = inputs.toolStack.getItem().getMaxDamage() * inputs.dustCount / DUSTS_TO_FIX; | ||
| 116 | newToolStack.setDamageValue(inputs.toolStack.getDamageValue() - repairedAmount); | ||
| 117 | return newToolStack; | ||
| 118 | } | ||
| 119 | |||
| 120 | @Override | ||
| 121 | public RecipeSerializer<?> getSerializer() { | ||
| 122 | return Serializer.INSTANCE; | ||
| 123 | } | ||
| 124 | |||
| 125 | private boolean isTool(ItemStack stack) { | ||
| 126 | if (!stack.isDamageableItem() || !stack.isDamaged() || stack.getCount() != 1) { | ||
| 127 | return false; | ||
| 128 | } | ||
| 129 | |||
| 130 | if (tools.test(stack)) { | ||
| 131 | return true; | ||
| 132 | } | ||
| 133 | |||
| 134 | var item = stack.getItem(); | ||
| 135 | return Arrays.stream(materials.getItems()).anyMatch(material -> item.isValidRepairItem(stack, material)); | ||
| 136 | } | ||
| 137 | |||
| 138 | private boolean isDust(ItemStack stack) { | ||
| 139 | return dust.test(stack); | ||
| 140 | } | ||
| 141 | |||
| 142 | /** @return null if recipe isn't correct. */ | ||
| 143 | private Inputs getInputs(CraftingContainer inventory) { | ||
| 144 | ItemStack toolStack = null; | ||
| 145 | var dustStacks = new ArrayList<ItemStack>(); | ||
| 146 | for (var i = 0; i < inventory.getContainerSize(); i++) { | ||
| 147 | var stack = inventory.getItem(i); | ||
| 148 | if (stack.isEmpty()) { | ||
| 149 | continue; | ||
| 150 | } | ||
| 151 | |||
| 152 | if (isDust(stack) && (dustStacks.isEmpty() || ItemStack.isSameItemSameTags(dustStacks.get(0), stack))) { | ||
| 153 | dustStacks.add(stack); | ||
| 154 | } else if (toolStack == null) { | ||
| 155 | toolStack = stack; | ||
| 156 | } else { | ||
| 157 | return null; | ||
| 158 | } | ||
| 159 | } | ||
| 160 | |||
| 161 | if (toolStack == null || dustStacks.isEmpty() || !isTool(toolStack)) { | ||
| 162 | return null; | ||
| 163 | } | ||
| 164 | |||
| 165 | return new Inputs(toolStack, dustStacks.size()); | ||
| 166 | } | ||
| 167 | } | ||
diff --git a/src/main/java/lv/enes/mc/eris_alchemy/ErisAlchemy.java b/src/main/java/lv/enes/mc/eris_alchemy/ErisAlchemy.java new file mode 100644 index 0000000..34e6b09 --- /dev/null +++ b/src/main/java/lv/enes/mc/eris_alchemy/ErisAlchemy.java | |||
| @@ -0,0 +1,68 @@ | |||
| 1 | package lv.enes.mc.eris_alchemy; | ||
| 2 | |||
| 3 | import net.fabricmc.fabric.api.itemgroup.v1.FabricItemGroup; | ||
| 4 | import net.fabricmc.fabric.api.itemgroup.v1.ItemGroupEvents; | ||
| 5 | import net.minecraft.core.Registry; | ||
| 6 | import net.minecraft.core.registries.BuiltInRegistries; | ||
| 7 | import net.minecraft.core.registries.Registries; | ||
| 8 | import net.minecraft.network.chat.Component; | ||
| 9 | import net.minecraft.resources.ResourceLocation; | ||
| 10 | import net.minecraft.world.item.CreativeModeTab; | ||
| 11 | import net.minecraft.world.item.CreativeModeTabs; | ||
| 12 | import net.minecraft.world.item.Item; | ||
| 13 | import net.minecraft.world.item.ItemStack; | ||
| 14 | import org.quiltmc.loader.api.ModContainer; | ||
| 15 | import org.quiltmc.qsl.base.api.entrypoint.ModInitializer; | ||
| 16 | import org.quiltmc.qsl.item.setting.api.QuiltItemSettings; | ||
| 17 | import org.slf4j.Logger; | ||
| 18 | import org.slf4j.LoggerFactory; | ||
| 19 | |||
| 20 | public class ErisAlchemy implements ModInitializer { | ||
| 21 | public static final String ID = "eris_alchemy"; | ||
| 22 | public static final Logger LOGGER = LoggerFactory.getLogger(ID); | ||
| 23 | |||
| 24 | // Aside from crafting recipe inputs, covalence dusts can be used to repair equipment via shapeless crafting | ||
| 25 | // Low covalence dust: | ||
| 26 | // - wooden and stone tools | ||
| 27 | // - leather armour | ||
| 28 | // - fishing rods | ||
| 29 | // - wooden bows | ||
| 30 | // - turtle shells | ||
| 31 | // Medium covalence dust: | ||
| 32 | // - iron, gold, bronze, ruby, sapphire, and green sapphire tools and armour | ||
| 33 | // - flints & steels | ||
| 34 | // - shears | ||
| 35 | // - elytras | ||
| 36 | // High covalence dust: | ||
| 37 | // - diamond and netherite tools and armour | ||
| 38 | // 8 dusts are enough to repair 100% :3 | ||
| 39 | public static final Item LOW_COVALENCE_DUST = new Item(new QuiltItemSettings()); | ||
| 40 | public static final Item MEDIUM_COVALENCE_DUST = new Item(new QuiltItemSettings()); | ||
| 41 | public static final Item HIGH_COVALENCE_DUST = new Item(new QuiltItemSettings()); | ||
| 42 | |||
| 43 | public static final CreativeModeTab ITEM_GROUP = FabricItemGroup.builder() | ||
| 44 | .icon(() -> new ItemStack(LOW_COVALENCE_DUST)) | ||
| 45 | .title(Component.translatable("itemGroup.eris_alchemy.item_group")) | ||
| 46 | .displayItems((context, entries) -> { | ||
| 47 | entries.accept(LOW_COVALENCE_DUST); | ||
| 48 | entries.accept(MEDIUM_COVALENCE_DUST); | ||
| 49 | entries.accept(HIGH_COVALENCE_DUST); | ||
| 50 | }) | ||
| 51 | .build(); | ||
| 52 | |||
| 53 | @Override | ||
| 54 | public void onInitialize(ModContainer mod) { | ||
| 55 | LOGGER.info("Hello World from {}!", mod.metadata().name()); | ||
| 56 | if (!mod.metadata().id().equals(ID)) { | ||
| 57 | throw new RuntimeException("Hardcoded mod ID doesn't match the configured one!"); | ||
| 58 | } | ||
| 59 | |||
| 60 | Registry.register(BuiltInRegistries.CREATIVE_MODE_TAB, new ResourceLocation(ID, "item_group"), ITEM_GROUP); | ||
| 61 | |||
| 62 | Registry.register(BuiltInRegistries.ITEM, new ResourceLocation(ID, "low_covalence_dust"), LOW_COVALENCE_DUST); | ||
| 63 | Registry.register(BuiltInRegistries.ITEM, new ResourceLocation(ID, "medium_covalence_dust"), MEDIUM_COVALENCE_DUST); | ||
| 64 | Registry.register(BuiltInRegistries.ITEM, new ResourceLocation(ID, "high_covalence_dust"), HIGH_COVALENCE_DUST); | ||
| 65 | |||
| 66 | Registry.register(BuiltInRegistries.RECIPE_SERIALIZER, CovalenceRepair.Serializer.ID, CovalenceRepair.Serializer.INSTANCE); | ||
| 67 | } | ||
| 68 | } | ||
diff --git a/src/main/java/lv/enes/mc/eris_alchemy/mixin/ItemMixin.java b/src/main/java/lv/enes/mc/eris_alchemy/mixin/ItemMixin.java new file mode 100644 index 0000000..54a2fd0 --- /dev/null +++ b/src/main/java/lv/enes/mc/eris_alchemy/mixin/ItemMixin.java | |||
| @@ -0,0 +1,21 @@ | |||
| 1 | package lv.enes.mc.eris_alchemy.mixin; | ||
| 2 | |||
| 3 | import net.minecraft.network.chat.Component; | ||
| 4 | import net.minecraft.world.item.Item; | ||
| 5 | import net.minecraft.world.item.ItemStack; | ||
| 6 | import net.minecraft.world.item.TooltipFlag; | ||
| 7 | import net.minecraft.world.level.Level; | ||
| 8 | import org.spongepowered.asm.mixin.Mixin; | ||
| 9 | import org.spongepowered.asm.mixin.injection.At; | ||
| 10 | import org.spongepowered.asm.mixin.injection.Inject; | ||
| 11 | import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; | ||
| 12 | |||
| 13 | import java.util.List; | ||
| 14 | |||
| 15 | @Mixin(Item.class) | ||
| 16 | public class ItemMixin { | ||
| 17 | @Inject(method = "appendHoverText", at = @At("RETURN")) | ||
| 18 | public void onAppendHoverText(ItemStack stack, Level world, List<Component> tooltip, TooltipFlag context, CallbackInfo ci) { | ||
| 19 | tooltip.add(Component.literal("EMC ???")); | ||
| 20 | } | ||
| 21 | } | ||