From 9445749ede3c61d3db9324184971b319b4a8bd1d Mon Sep 17 00:00:00 2001 From: Uko Kokņevičs Date: Fri, 5 Jan 2024 22:18:56 +0100 Subject: Initial Commit --- .../lv/enes/mc/eris_alchemy/CovalenceRepair.java | 167 +++++++++++++++++++++ .../java/lv/enes/mc/eris_alchemy/ErisAlchemy.java | 68 +++++++++ .../lv/enes/mc/eris_alchemy/mixin/ItemMixin.java | 21 +++ 3 files changed, 256 insertions(+) create mode 100644 src/main/java/lv/enes/mc/eris_alchemy/CovalenceRepair.java create mode 100644 src/main/java/lv/enes/mc/eris_alchemy/ErisAlchemy.java create mode 100644 src/main/java/lv/enes/mc/eris_alchemy/mixin/ItemMixin.java (limited to 'src/main/java/lv') 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 @@ +package lv.enes.mc.eris_alchemy; + +import com.google.gson.Gson; +import com.google.gson.JsonElement; +import com.google.gson.JsonObject; +import com.google.gson.JsonSyntaxException; +import net.minecraft.core.RegistryAccess; +import net.minecraft.network.FriendlyByteBuf; +import net.minecraft.resources.ResourceLocation; +import net.minecraft.world.inventory.CraftingContainer; +import net.minecraft.world.item.ItemStack; +import net.minecraft.world.item.crafting.CraftingBookCategory; +import net.minecraft.world.item.crafting.CustomRecipe; +import net.minecraft.world.item.crafting.Ingredient; +import net.minecraft.world.item.crafting.RecipeSerializer; +import net.minecraft.world.level.Level; +import org.quiltmc.qsl.recipe.api.serializer.QuiltRecipeSerializer; + +import java.util.ArrayList; +import java.util.Arrays; + +public class CovalenceRepair extends CustomRecipe { + static class Serializer implements QuiltRecipeSerializer { + private static class Json { + CraftingBookCategory category = CraftingBookCategory.MISC; + JsonElement dust; + JsonElement materials = new JsonObject(); + JsonElement tools = new JsonObject(); + } + + private Serializer() {} + + public static final Serializer INSTANCE = new Serializer(); + public static final ResourceLocation ID = new ResourceLocation(ErisAlchemy.ID, "covalence_repair"); + + @Override + public JsonObject toJson(CovalenceRepair recipe) { + var res = new JsonObject(); + res.addProperty("category", recipe.category().toString()); + res.add("dust", recipe.dust.toJson()); + res.add("materials", recipe.materials.toJson()); + res.add("tools", recipe.tools.toJson()); + return res; + } + + @Override + public CovalenceRepair fromJson(ResourceLocation id, JsonObject json) { + var recipeJson = new Gson().fromJson(json, Json.class); + if (recipeJson.dust == null) { + throw new JsonSyntaxException("A required attribute is missing"); + } + + var dust = Ingredient.fromJson(recipeJson.dust); + var materials = Ingredient.fromJson(recipeJson.materials); + var tools = Ingredient.fromJson(recipeJson.tools); + + return new CovalenceRepair(id, recipeJson.category, dust, materials, tools); + } + + @Override + public void toNetwork(FriendlyByteBuf buf, CovalenceRepair recipe) { + buf.writeEnum(recipe.category()); + recipe.dust.toNetwork(buf); + recipe.materials.toNetwork(buf); + recipe.tools.toNetwork(buf); + } + + @Override + public CovalenceRepair fromNetwork(ResourceLocation id, FriendlyByteBuf buf) { + var category = buf.readEnum(CraftingBookCategory.class); + var dust = Ingredient.fromNetwork(buf); + var materials = Ingredient.fromNetwork(buf); + var tools = Ingredient.fromNetwork(buf); + return new CovalenceRepair(id, category, dust, materials, tools); + } + } + + private record Inputs(ItemStack toolStack, int dustCount) {} + + private final static int DUSTS_TO_FIX = 8; + + /** What dust do we use to repair. */ + private final Ingredient dust; + /** What materials this dust can repair. */ + private final Ingredient materials; + /** What tools can this dust repair. */ + private final Ingredient tools; + + public CovalenceRepair(ResourceLocation id, CraftingBookCategory category, Ingredient dust, Ingredient materials, Ingredient tools) { + super(id, category); + + this.dust = dust; + this.materials = materials; + this.tools = tools; + } + + @Override + public boolean canCraftInDimensions(int width, int height) { + return width * height > 2; + } + + @Override + public boolean matches(CraftingContainer inventory, Level world) { + return getInputs(inventory) != null; + } + + @Override + public ItemStack assemble(CraftingContainer inventory, RegistryAccess registryManager) { + var inputs = getInputs(inventory); + if (inputs == null) { + return ItemStack.EMPTY; + } + + var newToolStack = inputs.toolStack.copy(); + var repairedAmount = inputs.toolStack.getItem().getMaxDamage() * inputs.dustCount / DUSTS_TO_FIX; + newToolStack.setDamageValue(inputs.toolStack.getDamageValue() - repairedAmount); + return newToolStack; + } + + @Override + public RecipeSerializer getSerializer() { + return Serializer.INSTANCE; + } + + private boolean isTool(ItemStack stack) { + if (!stack.isDamageableItem() || !stack.isDamaged() || stack.getCount() != 1) { + return false; + } + + if (tools.test(stack)) { + return true; + } + + var item = stack.getItem(); + return Arrays.stream(materials.getItems()).anyMatch(material -> item.isValidRepairItem(stack, material)); + } + + private boolean isDust(ItemStack stack) { + return dust.test(stack); + } + + /** @return null if recipe isn't correct. */ + private Inputs getInputs(CraftingContainer inventory) { + ItemStack toolStack = null; + var dustStacks = new ArrayList(); + for (var i = 0; i < inventory.getContainerSize(); i++) { + var stack = inventory.getItem(i); + if (stack.isEmpty()) { + continue; + } + + if (isDust(stack) && (dustStacks.isEmpty() || ItemStack.isSameItemSameTags(dustStacks.get(0), stack))) { + dustStacks.add(stack); + } else if (toolStack == null) { + toolStack = stack; + } else { + return null; + } + } + + if (toolStack == null || dustStacks.isEmpty() || !isTool(toolStack)) { + return null; + } + + return new Inputs(toolStack, dustStacks.size()); + } +} 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 @@ +package lv.enes.mc.eris_alchemy; + +import net.fabricmc.fabric.api.itemgroup.v1.FabricItemGroup; +import net.fabricmc.fabric.api.itemgroup.v1.ItemGroupEvents; +import net.minecraft.core.Registry; +import net.minecraft.core.registries.BuiltInRegistries; +import net.minecraft.core.registries.Registries; +import net.minecraft.network.chat.Component; +import net.minecraft.resources.ResourceLocation; +import net.minecraft.world.item.CreativeModeTab; +import net.minecraft.world.item.CreativeModeTabs; +import net.minecraft.world.item.Item; +import net.minecraft.world.item.ItemStack; +import org.quiltmc.loader.api.ModContainer; +import org.quiltmc.qsl.base.api.entrypoint.ModInitializer; +import org.quiltmc.qsl.item.setting.api.QuiltItemSettings; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class ErisAlchemy implements ModInitializer { + public static final String ID = "eris_alchemy"; + public static final Logger LOGGER = LoggerFactory.getLogger(ID); + + // Aside from crafting recipe inputs, covalence dusts can be used to repair equipment via shapeless crafting + // Low covalence dust: + // - wooden and stone tools + // - leather armour + // - fishing rods + // - wooden bows + // - turtle shells + // Medium covalence dust: + // - iron, gold, bronze, ruby, sapphire, and green sapphire tools and armour + // - flints & steels + // - shears + // - elytras + // High covalence dust: + // - diamond and netherite tools and armour + // 8 dusts are enough to repair 100% :3 + public static final Item LOW_COVALENCE_DUST = new Item(new QuiltItemSettings()); + public static final Item MEDIUM_COVALENCE_DUST = new Item(new QuiltItemSettings()); + public static final Item HIGH_COVALENCE_DUST = new Item(new QuiltItemSettings()); + + public static final CreativeModeTab ITEM_GROUP = FabricItemGroup.builder() + .icon(() -> new ItemStack(LOW_COVALENCE_DUST)) + .title(Component.translatable("itemGroup.eris_alchemy.item_group")) + .displayItems((context, entries) -> { + entries.accept(LOW_COVALENCE_DUST); + entries.accept(MEDIUM_COVALENCE_DUST); + entries.accept(HIGH_COVALENCE_DUST); + }) + .build(); + + @Override + public void onInitialize(ModContainer mod) { + LOGGER.info("Hello World from {}!", mod.metadata().name()); + if (!mod.metadata().id().equals(ID)) { + throw new RuntimeException("Hardcoded mod ID doesn't match the configured one!"); + } + + Registry.register(BuiltInRegistries.CREATIVE_MODE_TAB, new ResourceLocation(ID, "item_group"), ITEM_GROUP); + + Registry.register(BuiltInRegistries.ITEM, new ResourceLocation(ID, "low_covalence_dust"), LOW_COVALENCE_DUST); + Registry.register(BuiltInRegistries.ITEM, new ResourceLocation(ID, "medium_covalence_dust"), MEDIUM_COVALENCE_DUST); + Registry.register(BuiltInRegistries.ITEM, new ResourceLocation(ID, "high_covalence_dust"), HIGH_COVALENCE_DUST); + + Registry.register(BuiltInRegistries.RECIPE_SERIALIZER, CovalenceRepair.Serializer.ID, CovalenceRepair.Serializer.INSTANCE); + } +} 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 @@ +package lv.enes.mc.eris_alchemy.mixin; + +import net.minecraft.network.chat.Component; +import net.minecraft.world.item.Item; +import net.minecraft.world.item.ItemStack; +import net.minecraft.world.item.TooltipFlag; +import net.minecraft.world.level.Level; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.Inject; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; + +import java.util.List; + +@Mixin(Item.class) +public class ItemMixin { + @Inject(method = "appendHoverText", at = @At("RETURN")) + public void onAppendHoverText(ItemStack stack, Level world, List tooltip, TooltipFlag context, CallbackInfo ci) { + tooltip.add(Component.literal("EMC ???")); + } +} -- cgit v1.2.3