From 834389712b8c9966a60ed9fd392bd1535b6b9f78 Mon Sep 17 00:00:00 2001 From: paulevsGitch Date: Wed, 26 May 2021 16:26:48 +0300 Subject: [PATCH 1/4] Accessors, recipe builders --- gradle.properties | 2 +- .../mixin/common/ComposterBlockAccessor.java | 15 +++ .../mixin/common/PotionBrewingAccessor.java | 16 +++ .../mixin/common/RecipeManagerAccessor.java | 20 +++ .../mixin/common/RecipeManagerMixin.java | 64 ++++++++++ .../ru/bclib/recipes/BCLRecipeManager.java | 93 ++++++++++++++ .../java/ru/bclib/recipes/FurnaceRecipe.java | 96 ++++++++++++++ .../java/ru/bclib/recipes/GridRecipe.java | 120 ++++++++++++++++++ .../ru/bclib/recipes/SmithingTableRecipe.java | 95 ++++++++++++++ src/main/resources/bclib.mixins.common.json | 4 + 10 files changed, 524 insertions(+), 1 deletion(-) create mode 100644 src/main/java/ru/bclib/mixin/common/ComposterBlockAccessor.java create mode 100644 src/main/java/ru/bclib/mixin/common/PotionBrewingAccessor.java create mode 100644 src/main/java/ru/bclib/mixin/common/RecipeManagerAccessor.java create mode 100644 src/main/java/ru/bclib/mixin/common/RecipeManagerMixin.java create mode 100644 src/main/java/ru/bclib/recipes/BCLRecipeManager.java create mode 100644 src/main/java/ru/bclib/recipes/FurnaceRecipe.java create mode 100644 src/main/java/ru/bclib/recipes/GridRecipe.java create mode 100644 src/main/java/ru/bclib/recipes/SmithingTableRecipe.java diff --git a/gradle.properties b/gradle.properties index 09498443..40fc81b4 100644 --- a/gradle.properties +++ b/gradle.properties @@ -8,7 +8,7 @@ yarn_mappings=6 loader_version=0.11.3 # Mod Properties -mod_version = 0.1.1 +mod_version = 0.1.2 maven_group = ru.bclib archives_base_name = bclib diff --git a/src/main/java/ru/bclib/mixin/common/ComposterBlockAccessor.java b/src/main/java/ru/bclib/mixin/common/ComposterBlockAccessor.java new file mode 100644 index 00000000..81a2ba6c --- /dev/null +++ b/src/main/java/ru/bclib/mixin/common/ComposterBlockAccessor.java @@ -0,0 +1,15 @@ +package ru.bclib.mixin.common; + +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.gen.Invoker; + +import net.minecraft.world.level.ItemLike; +import net.minecraft.world.level.block.ComposterBlock; + +@Mixin(ComposterBlock.class) +public interface ComposterBlockAccessor { + @Invoker + static void callAdd(float levelIncreaseChance, ItemLike item) { + throw new AssertionError("@Invoker dummy body called"); + } +} diff --git a/src/main/java/ru/bclib/mixin/common/PotionBrewingAccessor.java b/src/main/java/ru/bclib/mixin/common/PotionBrewingAccessor.java new file mode 100644 index 00000000..b0c8e3f4 --- /dev/null +++ b/src/main/java/ru/bclib/mixin/common/PotionBrewingAccessor.java @@ -0,0 +1,16 @@ +package ru.bclib.mixin.common; + +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.gen.Invoker; + +import net.minecraft.world.item.Item; +import net.minecraft.world.item.alchemy.Potion; +import net.minecraft.world.item.alchemy.PotionBrewing; + +@Mixin(PotionBrewing.class) +public interface PotionBrewingAccessor { + @Invoker + static void callAddMix(Potion input, Item item, Potion output) { + throw new AssertionError("@Invoker dummy body called"); + } +} diff --git a/src/main/java/ru/bclib/mixin/common/RecipeManagerAccessor.java b/src/main/java/ru/bclib/mixin/common/RecipeManagerAccessor.java new file mode 100644 index 00000000..dba423b6 --- /dev/null +++ b/src/main/java/ru/bclib/mixin/common/RecipeManagerAccessor.java @@ -0,0 +1,20 @@ +package ru.bclib.mixin.common; + +import java.util.Map; + +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.gen.Accessor; + +import net.minecraft.resources.ResourceLocation; +import net.minecraft.world.item.crafting.Recipe; +import net.minecraft.world.item.crafting.RecipeManager; +import net.minecraft.world.item.crafting.RecipeType; + +@Mixin(RecipeManager.class) +public interface RecipeManagerAccessor { + @Accessor("recipes") + Map, Map>> be_getRecipes(); + + @Accessor("recipes") + void be_setRecipes(Map, Map>> recipes); +} \ No newline at end of file diff --git a/src/main/java/ru/bclib/mixin/common/RecipeManagerMixin.java b/src/main/java/ru/bclib/mixin/common/RecipeManagerMixin.java new file mode 100644 index 00000000..5c2092f6 --- /dev/null +++ b/src/main/java/ru/bclib/mixin/common/RecipeManagerMixin.java @@ -0,0 +1,64 @@ +package ru.bclib.mixin.common; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.List; +import java.util.Map; +import java.util.Optional; + +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.Overwrite; +import org.spongepowered.asm.mixin.Shadow; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.Inject; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; + +import com.google.gson.JsonElement; + +import net.minecraft.Util; +import net.minecraft.resources.ResourceLocation; +import net.minecraft.server.packs.resources.ResourceManager; +import net.minecraft.util.profiling.ProfilerFiller; +import net.minecraft.world.Container; +import net.minecraft.world.item.crafting.Recipe; +import net.minecraft.world.item.crafting.RecipeManager; +import net.minecraft.world.item.crafting.RecipeType; +import net.minecraft.world.level.Level; +import ru.bclib.recipes.BCLRecipeManager; + +@Mixin(RecipeManager.class) +public abstract class RecipeManagerMixin { + @Shadow + private Map, Map>> recipes; + + @Inject(method = "apply", at = @At(value = "RETURN")) + private void be_apply(Map map, ResourceManager resourceManager, ProfilerFiller profiler, CallbackInfo info) { + recipes = BCLRecipeManager.getMap(recipes); + } + + @Shadow + private > Map> byType(RecipeType type) { + return null; + } + + /** + * @author paulevs + * @reason Remove conflicts with vanilla tags + * Change recipe order to show mod recipes first, helps when block have vanilla tag + * (example - mod stone with vanilla tags and furnace from that stone) + */ + @Overwrite + public > Optional getRecipeFor(RecipeType type, C inventory, Level world) { + Collection> values = byType(type).values(); + List> list = new ArrayList>(values); + list.sort((v1, v2) -> { + boolean b1 = v1.getId().getNamespace().equals("minecraft"); + boolean b2 = v2.getId().getNamespace().equals("minecraft"); + return b1 ^ b2 ? (b1 ? 1 : -1) : 0; + }); + + return list.stream().flatMap((recipe) -> { + return Util.toStream(type.tryMatch(recipe, world, inventory)); + }).findFirst(); + } +} \ No newline at end of file diff --git a/src/main/java/ru/bclib/recipes/BCLRecipeManager.java b/src/main/java/ru/bclib/recipes/BCLRecipeManager.java new file mode 100644 index 00000000..8e2f6e71 --- /dev/null +++ b/src/main/java/ru/bclib/recipes/BCLRecipeManager.java @@ -0,0 +1,93 @@ +package ru.bclib.recipes; + +import java.util.Map; +import java.util.Map.Entry; + +import com.google.common.collect.Maps; + +import net.minecraft.core.Registry; +import net.minecraft.resources.ResourceLocation; +import net.minecraft.world.item.crafting.Recipe; +import net.minecraft.world.item.crafting.RecipeSerializer; +import net.minecraft.world.item.crafting.RecipeType; +import net.minecraft.world.level.ItemLike; +import net.minecraft.world.level.block.Block; + +public class BCLRecipeManager { + private static final Map, Map>> RECIPES = Maps.newHashMap(); + + public static void addRecipe(RecipeType type, Recipe recipe) { + Map> list = RECIPES.get(type); + if (list == null) { + list = Maps.newHashMap(); + RECIPES.put(type, list); + } + list.put(recipe.getId(), recipe); + } + + @SuppressWarnings("unchecked") + public static > T getRecipe(RecipeType type, ResourceLocation id) { + if (RECIPES.containsKey(type)) { + return (T) RECIPES.get(type).get(id); + } + return null; + } + + public static Map, Map>> getMap(Map, Map>> recipes) { + Map, Map>> result = Maps.newHashMap(); + + for (RecipeType type : recipes.keySet()) { + Map> typeList = Maps.newHashMap(); + typeList.putAll(recipes.get(type)); + result.put(type, typeList); + } + + for (RecipeType type : RECIPES.keySet()) { + Map> list = RECIPES.get(type); + if (list != null) { + Map> typeList = result.get(type); + if (typeList == null) { + typeList = Maps.newHashMap(); + result.put(type, typeList); + } + for (Entry> entry : list.entrySet()) { + ResourceLocation id = entry.getKey(); + if (!typeList.containsKey(id)) + typeList.put(id, entry.getValue()); + } + } + } + + return result; + } + + public static , T extends Recipe> S registerSerializer(String modID, String id, S serializer) { + return Registry.register(Registry.RECIPE_SERIALIZER, modID + ":" + id, serializer); + } + + public static > RecipeType registerType(String modID, String type) { + ResourceLocation recipeTypeId = new ResourceLocation(modID, type); + return Registry.register(Registry.RECIPE_TYPE, recipeTypeId, new RecipeType() { + public String toString() { + return type; + } + }); + } + + public static boolean exists(ItemLike item) { + if (item instanceof Block) { + return Registry.BLOCK.getKey((Block) item) != Registry.BLOCK.getDefaultKey(); + } else { + return Registry.ITEM.getKey(item.asItem()) != Registry.ITEM.getDefaultKey(); + } + } + + public static boolean exists(ItemLike... items) { + for (ItemLike item : items) { + if (!exists(item)) { + return false; + } + } + return true; + } +} \ No newline at end of file diff --git a/src/main/java/ru/bclib/recipes/FurnaceRecipe.java b/src/main/java/ru/bclib/recipes/FurnaceRecipe.java new file mode 100644 index 00000000..e6f9e596 --- /dev/null +++ b/src/main/java/ru/bclib/recipes/FurnaceRecipe.java @@ -0,0 +1,96 @@ +package ru.bclib.recipes; + +import net.minecraft.resources.ResourceLocation; +import net.minecraft.world.item.ItemStack; +import net.minecraft.world.item.crafting.BlastingRecipe; +import net.minecraft.world.item.crafting.CampfireCookingRecipe; +import net.minecraft.world.item.crafting.Ingredient; +import net.minecraft.world.item.crafting.RecipeType; +import net.minecraft.world.item.crafting.SmeltingRecipe; +import net.minecraft.world.item.crafting.SmokingRecipe; +import net.minecraft.world.level.ItemLike; +import ru.bclib.BCLib; + +public class FurnaceRecipe { + private static final FurnaceRecipe INSTANCE = new FurnaceRecipe(); + + private ResourceLocation id; + private ItemLike input; + private ItemLike output; + private boolean exist; + private String group; + private int count; + private int time; + private float xp; + + private FurnaceRecipe() {} + + public static FurnaceRecipe make(String modID, String name, ItemLike input, ItemLike output) { + INSTANCE.id = new ResourceLocation(modID, name); + INSTANCE.group = ""; + INSTANCE.input = input; + INSTANCE.output = output; + INSTANCE.count = 1; + INSTANCE.time = 200; + INSTANCE.xp = 0; + INSTANCE.exist = BCLRecipeManager.exists(output) && BCLRecipeManager.exists(input); + return INSTANCE; + } + + public FurnaceRecipe setGroup(String group) { + this.group = group; + return this; + } + + public FurnaceRecipe setOutputCount(int count) { + this.count = count; + return this; + } + + public FurnaceRecipe setXP(float xp) { + this.xp = xp; + return this; + } + + public FurnaceRecipe setCookTime(int time) { + this.time = time; + return this; + } + + public void build() { + build(false, false, false); + } + + public void buildWithBlasting() { + build(true, false, false); + } + + public void buildFoodlike() { + build(false, true, true); + } + + public void build(boolean blasting, boolean campfire, boolean smoker) { + if (exist) { + SmeltingRecipe recipe = new SmeltingRecipe(id, group, Ingredient.of(input), new ItemStack(output, count), xp, time); + BCLRecipeManager.addRecipe(RecipeType.SMELTING, recipe); + + if (blasting) { + BlastingRecipe recipe2 = new BlastingRecipe(id, group, Ingredient.of(input), new ItemStack(output, count), xp, time / 2); + BCLRecipeManager.addRecipe(RecipeType.BLASTING, recipe2); + } + + if (campfire) { + CampfireCookingRecipe recipe2 = new CampfireCookingRecipe(id, group, Ingredient.of(input), new ItemStack(output, count), xp, time * 3); + BCLRecipeManager.addRecipe(RecipeType.CAMPFIRE_COOKING, recipe2); + } + + if (smoker) { + SmokingRecipe recipe2 = new SmokingRecipe(id, group, Ingredient.of(input), new ItemStack(output, count), xp, time / 2); + BCLRecipeManager.addRecipe(RecipeType.SMOKING, recipe2); + } + } + else { + BCLib.LOGGER.debug("Furnace recipe {} couldn't be added", id); + } + } +} diff --git a/src/main/java/ru/bclib/recipes/GridRecipe.java b/src/main/java/ru/bclib/recipes/GridRecipe.java new file mode 100644 index 00000000..ca63ad5d --- /dev/null +++ b/src/main/java/ru/bclib/recipes/GridRecipe.java @@ -0,0 +1,120 @@ +package ru.bclib.recipes; + +import java.util.Arrays; +import java.util.Map; + +import com.google.common.collect.Maps; + +import net.minecraft.core.NonNullList; +import net.minecraft.resources.ResourceLocation; +import net.minecraft.tags.Tag; +import net.minecraft.world.item.Item; +import net.minecraft.world.item.ItemStack; +import net.minecraft.world.item.crafting.CraftingRecipe; +import net.minecraft.world.item.crafting.Ingredient; +import net.minecraft.world.item.crafting.RecipeType; +import net.minecraft.world.item.crafting.ShapedRecipe; +import net.minecraft.world.item.crafting.ShapelessRecipe; +import net.minecraft.world.level.ItemLike; +import ru.bclib.BCLib; + +public class GridRecipe { + private static final GridRecipe INSTANCE = new GridRecipe(); + + private ResourceLocation id; + private ItemLike output; + + private String group; + private RecipeType type; + private boolean shaped; + private String[] shape; + private Map materialKeys = Maps.newHashMap(); + private int count; + private boolean exist = true; + + private GridRecipe() {} + + public static GridRecipe make(String modID, String name, ItemLike output) { + INSTANCE.id = new ResourceLocation(modID, name); + INSTANCE.output = output; + + INSTANCE.group = ""; + INSTANCE.type = RecipeType.CRAFTING; + INSTANCE.shaped = true; + INSTANCE.shape = new String[] {"#"}; + INSTANCE.materialKeys.clear(); + INSTANCE.count = 1; + + INSTANCE.exist = BCLRecipeManager.exists(output); + + return INSTANCE; + } + + public GridRecipe setGroup(String group) { + this.group = group; + return this; + } + + public GridRecipe setShape(String... shape) { + this.shape = shape; + return this; + } + + public GridRecipe setList(String shape) { + this.shape = new String[] { shape }; + this.shaped = false; + return this; + } + + public GridRecipe addMaterial(char key, Tag value) { + return addMaterial(key, Ingredient.of(value)); + } + + public GridRecipe addMaterial(char key, ItemStack... value) { + return addMaterial(key, Ingredient.of(Arrays.stream(value))); + } + + public GridRecipe addMaterial(char key, ItemLike... values) { + for (ItemLike item: values) { + exist &= BCLRecipeManager.exists(item); + } + return addMaterial(key, Ingredient.of(values)); + } + + private GridRecipe addMaterial(char key, Ingredient value) { + materialKeys.put(key, value); + return this; + } + + public GridRecipe setOutputCount(int count) { + this.count = count; + return this; + } + + private NonNullList getMaterials(int width, int height) { + NonNullList materials = NonNullList.withSize(width * height, Ingredient.EMPTY); + int pos = 0; + for (String line: shape) { + for (int i = 0; i < width; i++) { + char c = line.charAt(i); + Ingredient material = materialKeys.get(c); + materials.set(pos ++, material == null ? Ingredient.EMPTY : material); + } + } + return materials; + } + + public void build() { + if (exist) { + int height = shape.length; + int width = shape[0].length(); + ItemStack result = new ItemStack(output, count); + NonNullList materials = this.getMaterials(width, height); + + CraftingRecipe recipe = shaped ? new ShapedRecipe(id, group, width, height, materials, result) : new ShapelessRecipe(id, group, result, materials); + BCLRecipeManager.addRecipe(type, recipe); + } else { + BCLib.LOGGER.debug("Recipe {} couldn't be added", id); + } + } +} diff --git a/src/main/java/ru/bclib/recipes/SmithingTableRecipe.java b/src/main/java/ru/bclib/recipes/SmithingTableRecipe.java new file mode 100644 index 00000000..006a1724 --- /dev/null +++ b/src/main/java/ru/bclib/recipes/SmithingTableRecipe.java @@ -0,0 +1,95 @@ +package ru.bclib.recipes; + +import net.minecraft.resources.ResourceLocation; +import net.minecraft.tags.Tag; +import net.minecraft.world.item.Item; +import net.minecraft.world.item.ItemStack; +import net.minecraft.world.item.crafting.Ingredient; +import net.minecraft.world.item.crafting.RecipeType; +import net.minecraft.world.item.crafting.UpgradeRecipe; +import net.minecraft.world.level.ItemLike; +import ru.bclib.BCLib; + +public class SmithingTableRecipe { + + private final static SmithingTableRecipe BUILDER = new SmithingTableRecipe(); + private final static RecipeType TYPE = RecipeType.SMITHING; + + public static SmithingTableRecipe create(String modID, String name) { + return create(new ResourceLocation(modID, name)); + } + + public static SmithingTableRecipe create(ResourceLocation id) { + BUILDER.id = id; + BUILDER.base = null; + BUILDER.addition = null; + BUILDER.result = null; + BUILDER.alright = true; + + return BUILDER; + } + + private ResourceLocation id; + private Ingredient base; + private Ingredient addition; + private ItemStack result; + private boolean alright; + + private SmithingTableRecipe() {} + + public SmithingTableRecipe setResult(ItemLike item) { + return this.setResult(item, 1); + } + + public SmithingTableRecipe setResult(ItemLike item, int count) { + this.alright &= BCLRecipeManager.exists(item); + this.result = new ItemStack(item, count); + return this; + } + + public SmithingTableRecipe setBase(ItemLike... items) { + this.alright &= BCLRecipeManager.exists(items); + this.base = Ingredient.of(items); + return this; + } + + public SmithingTableRecipe setBase(Tag tag) { + this.base = (Ingredient.of(tag)); + return this; + } + + public SmithingTableRecipe setAddition(ItemLike... items) { + this.alright &= BCLRecipeManager.exists(items); + this.addition = Ingredient.of(items); + return this; + } + + public SmithingTableRecipe setAddition(Tag tag) { + this.addition = (Ingredient.of(tag)); + return this; + } + + public void build() { + if (base == null) { + BCLib.LOGGER.warning("Base input for Smithing recipe can't be 'null', recipe {} will be ignored!", id); + return; + } + if (addition == null) { + BCLib.LOGGER.warning("Addition input for Smithing recipe can't be 'null', recipe {} will be ignored!", id); + return; + } + if(result == null) { + BCLib.LOGGER.warning("Result for Smithing recipe can't be 'null', recipe {} will be ignored!", id); + return; + } + if (BCLRecipeManager.getRecipe(TYPE, id) != null) { + BCLib.LOGGER.warning("Can't add Smithing recipe! Id {} already exists!", id); + return; + } + if (!alright) { + BCLib.LOGGER.debug("Can't add Smithing recipe {}! Ingeredients or output not exists.", id); + return; + } + BCLRecipeManager.addRecipe(TYPE, new UpgradeRecipe(id, base, addition, result)); + } +} diff --git a/src/main/resources/bclib.mixins.common.json b/src/main/resources/bclib.mixins.common.json index 2d182b8c..874c057c 100644 --- a/src/main/resources/bclib.mixins.common.json +++ b/src/main/resources/bclib.mixins.common.json @@ -4,6 +4,10 @@ "package": "ru.bclib.mixin.common", "compatibilityLevel": "JAVA_8", "mixins": [ + "ComposterBlockAccessor", + "PotionBrewingAccessor", + "RecipeManagerAccessor", + "RecipeManagerMixin", "BoneMealItemMixin", "TagLoaderMixin" ], From 8472ad3c1ddf487ba18c4ae5adcaf13921347444 Mon Sep 17 00:00:00 2001 From: paulevsGitch Date: Wed, 26 May 2021 16:38:09 +0300 Subject: [PATCH 2/4] Enchantment Menu mixin, Tag API rename --- src/main/java/ru/bclib/BCLib.java | 4 +- .../bclib/api/{BCLibTags.java => TagAPI.java} | 2 +- .../bclib/mixin/common/BoneMealItemMixin.java | 4 +- .../mixin/common/EnchantmentMenuMixin.java | 140 ++++++++++++++++++ .../java/ru/bclib/util/StructureHelper.java | 8 +- .../world/features/NBTStructureFeature.java | 8 +- src/main/resources/bclib.mixins.common.json | 1 + 7 files changed, 154 insertions(+), 13 deletions(-) rename src/main/java/ru/bclib/api/{BCLibTags.java => TagAPI.java} (97%) create mode 100644 src/main/java/ru/bclib/mixin/common/EnchantmentMenuMixin.java diff --git a/src/main/java/ru/bclib/BCLib.java b/src/main/java/ru/bclib/BCLib.java index fc4704e9..2712ff6f 100644 --- a/src/main/java/ru/bclib/BCLib.java +++ b/src/main/java/ru/bclib/BCLib.java @@ -5,7 +5,7 @@ import net.fabricmc.api.ModInitializer; import net.fabricmc.loader.api.FabricLoader; import ru.bclib.util.Logger; import ru.bclib.world.surface.BCLSurfaceBuilders; -import ru.bclib.api.BCLibTags; +import ru.bclib.api.TagAPI; public class BCLib implements ModInitializer { public static final String MOD_ID = "bclib"; @@ -14,7 +14,7 @@ public class BCLib implements ModInitializer { @Override public void onInitialize() { BCLSurfaceBuilders.register(); - BCLibTags.init(); + TagAPI.init(); } public static boolean isDevEnvironment() { diff --git a/src/main/java/ru/bclib/api/BCLibTags.java b/src/main/java/ru/bclib/api/TagAPI.java similarity index 97% rename from src/main/java/ru/bclib/api/BCLibTags.java rename to src/main/java/ru/bclib/api/TagAPI.java index d27e5676..8a4accba 100644 --- a/src/main/java/ru/bclib/api/BCLibTags.java +++ b/src/main/java/ru/bclib/api/TagAPI.java @@ -16,7 +16,7 @@ import net.minecraft.world.level.block.Blocks; import ru.bclib.BCLib; import ru.bclib.util.TagHelper; -public class BCLibTags { +public class TagAPI { // Block Tags public static final Tag.Named BOOKSHELVES = makeCommonBlockTag("bookshelves"); public static final Tag.Named GEN_TERRAIN = makeBlockTag(BCLib.MOD_ID, "gen_terrain"); diff --git a/src/main/java/ru/bclib/mixin/common/BoneMealItemMixin.java b/src/main/java/ru/bclib/mixin/common/BoneMealItemMixin.java index 01df4312..dc2bec59 100644 --- a/src/main/java/ru/bclib/mixin/common/BoneMealItemMixin.java +++ b/src/main/java/ru/bclib/mixin/common/BoneMealItemMixin.java @@ -16,7 +16,7 @@ import net.minecraft.world.level.biome.Biome.BiomeCategory; import net.minecraft.world.level.block.Block; import net.minecraft.world.level.block.Blocks; import net.minecraft.world.level.block.state.BlockState; -import ru.bclib.api.BCLibTags; +import ru.bclib.api.TagAPI; import ru.bclib.api.BiomeAPI; import ru.bclib.api.BonemealAPI; import ru.bclib.util.BlocksHelper; @@ -34,7 +34,7 @@ public class BoneMealItemMixin { BlockPos offseted = blockPos.relative(context.getClickedFace()); boolean endBiome = world.getBiome(offseted).getBiomeCategory() == BiomeCategory.THEEND; - if (world.getBlockState(blockPos).is(BCLibTags.END_GROUND)) { + if (world.getBlockState(blockPos).is(TagAPI.END_GROUND)) { boolean consume = false; if (world.getBlockState(blockPos).is(Blocks.END_STONE)) { BlockState nylium = bclib_getNylium(world, blockPos); diff --git a/src/main/java/ru/bclib/mixin/common/EnchantmentMenuMixin.java b/src/main/java/ru/bclib/mixin/common/EnchantmentMenuMixin.java new file mode 100644 index 00000000..d0af1dd8 --- /dev/null +++ b/src/main/java/ru/bclib/mixin/common/EnchantmentMenuMixin.java @@ -0,0 +1,140 @@ +package ru.bclib.mixin.common; + +import java.util.List; +import java.util.Random; + +import org.spongepowered.asm.mixin.Final; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.Shadow; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.Inject; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; + +import net.minecraft.core.Registry; +import net.minecraft.world.Container; +import net.minecraft.world.inventory.AbstractContainerMenu; +import net.minecraft.world.inventory.ContainerLevelAccess; +import net.minecraft.world.inventory.DataSlot; +import net.minecraft.world.inventory.EnchantmentMenu; +import net.minecraft.world.inventory.MenuType; +import net.minecraft.world.item.ItemStack; +import net.minecraft.world.item.enchantment.EnchantmentHelper; +import net.minecraft.world.item.enchantment.EnchantmentInstance; +import ru.bclib.api.TagAPI; + +@Mixin(EnchantmentMenu.class) +public abstract class EnchantmentMenuMixin extends AbstractContainerMenu { + @Final + @Shadow + private Container enchantSlots; + + @Final + @Shadow + private ContainerLevelAccess access; + + @Final + @Shadow + private Random random; + + @Final + @Shadow + private DataSlot enchantmentSeed; + + @Shadow + @Final + public int[] costs; + + @Shadow + @Final + public int[] enchantClue; + + @Shadow + @Final + public int[] levelClue; + + protected EnchantmentMenuMixin(MenuType type, int syncId) { + super(type, syncId); + } + + @Inject(method = "slotsChanged", at = @At("HEAD"), cancellable = true) + private void be_slotsChanged(Container inventory, CallbackInfo info) { + if (inventory == this.enchantSlots) { + ItemStack itemStack = inventory.getItem(0); + if (!itemStack.isEmpty() && itemStack.isEnchantable()) { + this.access.execute((world, blockPos) -> { + int i = 0; + + int j; + for (j = -1; j <= 1; ++j) { + for (int k = -1; k <= 1; ++k) { + if ((j != 0 || k != 0) && world.isEmptyBlock(blockPos.offset(k, 0, j)) && world.isEmptyBlock(blockPos.offset(k, 1, j))) { + if (world.getBlockState(blockPos.offset(k * 2, 0, j * 2)).is(TagAPI.BOOKSHELVES)) { + ++i; + } + + if (world.getBlockState(blockPos.offset(k * 2, 1, j * 2)).is(TagAPI.BOOKSHELVES)) { + ++i; + } + + if (k != 0 && j != 0) { + if (world.getBlockState(blockPos.offset(k * 2, 0, j)).is(TagAPI.BOOKSHELVES)) { + ++i; + } + + if (world.getBlockState(blockPos.offset(k * 2, 1, j)).is(TagAPI.BOOKSHELVES)) { + ++i; + } + + if (world.getBlockState(blockPos.offset(k, 0, j * 2)).is(TagAPI.BOOKSHELVES)) { + ++i; + } + + if (world.getBlockState(blockPos.offset(k, 1, j * 2)).is(TagAPI.BOOKSHELVES)) { + ++i; + } + } + } + } + } + + random.setSeed(enchantmentSeed.get()); + + for (j = 0; j < 3; ++j) { + costs[j] = EnchantmentHelper.getEnchantmentCost(this.random, j, i, itemStack); + enchantClue[j] = -1; + levelClue[j] = -1; + if (costs[j] < j + 1) { + costs[j] = 0; + } + } + + for (j = 0; j < 3; ++j) { + if (this.costs[j] > 0) { + List list = this.getEnchantmentList(itemStack, j, this.costs[j]); + if (list != null && !list.isEmpty()) { + EnchantmentInstance enchantmentLevelEntry = (EnchantmentInstance) list.get(this.random.nextInt(list.size())); + enchantClue[j] = Registry.ENCHANTMENT.getId(enchantmentLevelEntry.enchantment); + levelClue[j] = enchantmentLevelEntry.level; + } + } + } + + broadcastChanges(); + }); + } + else { + for (int i = 0; i < 3; ++i) { + costs[i] = 0; + enchantClue[i] = -1; + levelClue[i] = -1; + } + } + info.cancel(); + } + } + + @Shadow + private List getEnchantmentList(ItemStack stack, int slot, int level) { + return null; + } +} diff --git a/src/main/java/ru/bclib/util/StructureHelper.java b/src/main/java/ru/bclib/util/StructureHelper.java index f0cc810a..205676bc 100644 --- a/src/main/java/ru/bclib/util/StructureHelper.java +++ b/src/main/java/ru/bclib/util/StructureHelper.java @@ -27,7 +27,7 @@ import net.minecraft.world.level.levelgen.structure.BoundingBox; import net.minecraft.world.level.levelgen.structure.templatesystem.StructurePlaceSettings; import net.minecraft.world.level.levelgen.structure.templatesystem.StructureTemplate; import net.minecraft.world.level.material.Material; -import ru.bclib.api.BCLibTags; +import ru.bclib.api.TagAPI; public class StructureHelper { private static final Direction[] DIR = BlocksHelper.makeHorizontal(); @@ -264,7 +264,7 @@ public class StructureHelper { private static boolean isTerrainNear(WorldGenLevel world, BlockPos pos) { for (Direction dir: BlocksHelper.DIRECTIONS) { - if (world.getBlockState(pos.relative(dir)).is(BCLibTags.GEN_TERRAIN)) { + if (world.getBlockState(pos.relative(dir)).is(TagAPI.GEN_TERRAIN)) { return true; } } @@ -344,7 +344,7 @@ public class StructureHelper { private static boolean ignore(BlockState state) { return state.getMaterial().isReplaceable() || !state.getFluidState().isEmpty() || - state.is(BCLibTags.END_GROUND) || + state.is(TagAPI.END_GROUND) || state.is(BlockTags.LOGS) || state.is(BlockTags.LEAVES) || state.getMaterial().equals(Material.PLANT) || @@ -362,7 +362,7 @@ public class StructureHelper { for (int y = bounds.y1; y >= bounds.y0; y--) { mut.setY(y); BlockState state = world.getBlockState(mut); - if (state.is(BCLibTags.END_GROUND) && !world.getBlockState(mut.above()).getMaterial().isSolidBlocking()) { + if (state.is(TagAPI.END_GROUND) && !world.getBlockState(mut.above()).getMaterial().isSolidBlocking()) { BlocksHelper.setWithoutUpdate(world, mut, top); } } diff --git a/src/main/java/ru/bclib/world/features/NBTStructureFeature.java b/src/main/java/ru/bclib/world/features/NBTStructureFeature.java index 7422e599..27bf3d1d 100644 --- a/src/main/java/ru/bclib/world/features/NBTStructureFeature.java +++ b/src/main/java/ru/bclib/world/features/NBTStructureFeature.java @@ -22,7 +22,7 @@ import net.minecraft.world.level.levelgen.structure.BoundingBox; import net.minecraft.world.level.levelgen.structure.templatesystem.StructurePlaceSettings; import net.minecraft.world.level.levelgen.structure.templatesystem.StructureTemplate; import net.minecraft.world.level.levelgen.surfacebuilders.SurfaceBuilderConfiguration; -import ru.bclib.api.BCLibTags; +import ru.bclib.api.TagAPI; import ru.bclib.api.BiomeAPI; import ru.bclib.util.BlocksHelper; import ru.bclib.world.processors.DestructionStructureProcessor; @@ -124,11 +124,11 @@ public abstract class NBTStructureFeature extends DefaultFeature { mut.setZ(z); mut.setY(surfMax); BlockState state = world.getBlockState(mut); - if (!state.is(BCLibTags.GEN_TERRAIN) && state.isFaceSturdy(world, mut, Direction.DOWN)) { + if (!state.is(TagAPI.GEN_TERRAIN) && state.isFaceSturdy(world, mut, Direction.DOWN)) { for (int i = 0; i < 10; i++) { mut.setY(mut.getY() - 1); BlockState stateSt = world.getBlockState(mut); - if (!stateSt.is(BCLibTags.GEN_TERRAIN)) { + if (!stateSt.is(TagAPI.GEN_TERRAIN)) { if (merge == TerrainMerge.SURFACE) { SurfaceBuilderConfiguration config = world.getBiome(mut).getGenerationSettings().getSurfaceBuilderConfig(); boolean isTop = mut.getY() == surfMax && state.getMaterial().isSolidBlocking(); @@ -140,7 +140,7 @@ public abstract class NBTStructureFeature extends DefaultFeature { } } else { - if (stateSt.is(BCLibTags.END_GROUND) && state.getMaterial().isSolidBlocking()) { + if (stateSt.is(TagAPI.END_GROUND) && state.getMaterial().isSolidBlocking()) { if (merge == TerrainMerge.SURFACE) { SurfaceBuilderConfiguration config = world.getBiome(mut).getGenerationSettings() .getSurfaceBuilderConfig(); diff --git a/src/main/resources/bclib.mixins.common.json b/src/main/resources/bclib.mixins.common.json index 874c057c..e90d188a 100644 --- a/src/main/resources/bclib.mixins.common.json +++ b/src/main/resources/bclib.mixins.common.json @@ -7,6 +7,7 @@ "ComposterBlockAccessor", "PotionBrewingAccessor", "RecipeManagerAccessor", + "EnchantmentMenuMixin", "RecipeManagerMixin", "BoneMealItemMixin", "TagLoaderMixin" From a00c1f749c956c03c24434b9cbace591db6cab52 Mon Sep 17 00:00:00 2001 From: paulevsGitch Date: Wed, 26 May 2021 16:42:13 +0300 Subject: [PATCH 3/4] Recipe config check --- src/main/java/ru/bclib/recipes/FurnaceRecipe.java | 6 ++++++ src/main/java/ru/bclib/recipes/GridRecipe.java | 6 ++++++ .../java/ru/bclib/recipes/SmithingTableRecipe.java | 11 +++++++++++ 3 files changed, 23 insertions(+) diff --git a/src/main/java/ru/bclib/recipes/FurnaceRecipe.java b/src/main/java/ru/bclib/recipes/FurnaceRecipe.java index e6f9e596..66c4ae28 100644 --- a/src/main/java/ru/bclib/recipes/FurnaceRecipe.java +++ b/src/main/java/ru/bclib/recipes/FurnaceRecipe.java @@ -10,6 +10,7 @@ import net.minecraft.world.item.crafting.SmeltingRecipe; import net.minecraft.world.item.crafting.SmokingRecipe; import net.minecraft.world.level.ItemLike; import ru.bclib.BCLib; +import ru.bclib.config.PathConfig; public class FurnaceRecipe { private static final FurnaceRecipe INSTANCE = new FurnaceRecipe(); @@ -37,6 +38,11 @@ public class FurnaceRecipe { return INSTANCE; } + public FurnaceRecipe checkConfig(PathConfig config) { + exist = config.getBoolean("furnace", id.getPath(), true); + return this; + } + public FurnaceRecipe setGroup(String group) { this.group = group; return this; diff --git a/src/main/java/ru/bclib/recipes/GridRecipe.java b/src/main/java/ru/bclib/recipes/GridRecipe.java index ca63ad5d..06a15b2b 100644 --- a/src/main/java/ru/bclib/recipes/GridRecipe.java +++ b/src/main/java/ru/bclib/recipes/GridRecipe.java @@ -17,6 +17,7 @@ import net.minecraft.world.item.crafting.ShapedRecipe; import net.minecraft.world.item.crafting.ShapelessRecipe; import net.minecraft.world.level.ItemLike; import ru.bclib.BCLib; +import ru.bclib.config.PathConfig; public class GridRecipe { private static final GridRecipe INSTANCE = new GridRecipe(); @@ -49,6 +50,11 @@ public class GridRecipe { return INSTANCE; } + + public GridRecipe checkConfig(PathConfig config) { + exist = config.getBoolean("grid", id.getPath(), true); + return this; + } public GridRecipe setGroup(String group) { this.group = group; diff --git a/src/main/java/ru/bclib/recipes/SmithingTableRecipe.java b/src/main/java/ru/bclib/recipes/SmithingTableRecipe.java index 006a1724..45947b4c 100644 --- a/src/main/java/ru/bclib/recipes/SmithingTableRecipe.java +++ b/src/main/java/ru/bclib/recipes/SmithingTableRecipe.java @@ -9,6 +9,7 @@ import net.minecraft.world.item.crafting.RecipeType; import net.minecraft.world.item.crafting.UpgradeRecipe; import net.minecraft.world.level.ItemLike; import ru.bclib.BCLib; +import ru.bclib.config.PathConfig; public class SmithingTableRecipe { @@ -34,9 +35,15 @@ public class SmithingTableRecipe { private Ingredient addition; private ItemStack result; private boolean alright; + private boolean exist; private SmithingTableRecipe() {} + public SmithingTableRecipe checkConfig(PathConfig config) { + exist = config.getBoolean("smithing", id.getPath(), true); + return this; + } + public SmithingTableRecipe setResult(ItemLike item) { return this.setResult(item, 1); } @@ -70,6 +77,10 @@ public class SmithingTableRecipe { } public void build() { + if (!exist) { + return; + } + if (base == null) { BCLib.LOGGER.warning("Base input for Smithing recipe can't be 'null', recipe {} will be ignored!", id); return; From f2839447987cbf21f8bcc65f94fc0bba58d8c88f Mon Sep 17 00:00:00 2001 From: paulevsGitch Date: Wed, 26 May 2021 16:50:36 +0300 Subject: [PATCH 4/4] Enchanting table mixin --- .../client/EnchantingTableBlockMixin.java | 46 +++++++++++++++++++ src/main/resources/bclib.mixins.client.json | 4 +- 2 files changed, 49 insertions(+), 1 deletion(-) create mode 100644 src/main/java/ru/bclib/mixin/client/EnchantingTableBlockMixin.java diff --git a/src/main/java/ru/bclib/mixin/client/EnchantingTableBlockMixin.java b/src/main/java/ru/bclib/mixin/client/EnchantingTableBlockMixin.java new file mode 100644 index 00000000..a78291c5 --- /dev/null +++ b/src/main/java/ru/bclib/mixin/client/EnchantingTableBlockMixin.java @@ -0,0 +1,46 @@ +package ru.bclib.mixin.client; + +import java.util.Random; + +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 net.minecraft.core.BlockPos; +import net.minecraft.core.particles.ParticleTypes; +import net.minecraft.world.level.Level; +import net.minecraft.world.level.block.Block; +import net.minecraft.world.level.block.EnchantmentTableBlock; +import net.minecraft.world.level.block.state.BlockState; +import ru.bclib.api.TagAPI; + +@Mixin(EnchantmentTableBlock.class) +public abstract class EnchantingTableBlockMixin extends Block { + public EnchantingTableBlockMixin(Properties settings) { + super(settings); + } + + @Inject(method = "animateTick", at = @At(value = "TAIL")) + private void be_onRandomDisplayTick(BlockState state, Level world, BlockPos pos, Random random, CallbackInfo info) { + for (int px = -2; px <= 2; ++px) { + for (int pz = -2; pz <= 2; ++pz) { + if (px > -2 && px < 2 && pz == -1) { + pz = 2; + } + if (random.nextInt(16) == 0) { + for (int py = 0; py <= 1; ++py) { + BlockPos blockPos = pos.offset(px, py, pz); + if (world.getBlockState(blockPos).is(TagAPI.BOOKSHELVES)) { + if (!world.isEmptyBlock(pos.offset(px / 2, 0, pz / 2))) { + break; + } + world.addParticle(ParticleTypes.ENCHANT, pos.getX() + 0.5, pos.getY() + 2.0, pos.getZ() + 0.5, px + random.nextFloat() - 0.5, py - random.nextFloat() - 1.0, pz + random.nextFloat() - 0.5); + } + } + } + } + } + + } +} diff --git a/src/main/resources/bclib.mixins.client.json b/src/main/resources/bclib.mixins.client.json index fd357b79..ed90fa1d 100644 --- a/src/main/resources/bclib.mixins.client.json +++ b/src/main/resources/bclib.mixins.client.json @@ -3,7 +3,9 @@ "minVersion": "0.8", "package": "ru.bclib.mixin.client", "compatibilityLevel": "JAVA_8", - "client": [], + "client": [ + "EnchantingTableBlockMixin" + ], "injectors": { "defaultRequire": 1 }