Merge remote-tracking branch 'origin/main' into main

# Conflicts:
#	src/main/resources/bclib.mixins.client.json
This commit is contained in:
Aleksey 2021-05-26 17:24:12 +03:00
commit feb6c5172c
18 changed files with 749 additions and 15 deletions

View file

@ -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

View file

@ -6,7 +6,7 @@ import net.fabricmc.loader.api.FabricLoader;
import net.minecraft.resources.ResourceLocation;
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";
@ -15,7 +15,7 @@ public class BCLib implements ModInitializer {
@Override
public void onInitialize() {
BCLSurfaceBuilders.register();
BCLibTags.init();
TagAPI.init();
}
public static boolean isDevEnvironment() {

View file

@ -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<Block> BOOKSHELVES = makeCommonBlockTag("bookshelves");
public static final Tag.Named<Block> GEN_TERRAIN = makeBlockTag(BCLib.MOD_ID, "gen_terrain");

View file

@ -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);
}
}
}
}
}
}
}

View file

@ -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);

View file

@ -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");
}
}

View file

@ -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<EnchantmentInstance> 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<EnchantmentInstance> getEnchantmentList(ItemStack stack, int slot, int level) {
return null;
}
}

View file

@ -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");
}
}

View file

@ -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<RecipeType<?>, Map<ResourceLocation, Recipe<?>>> be_getRecipes();
@Accessor("recipes")
void be_setRecipes(Map<RecipeType<?>, Map<ResourceLocation, Recipe<?>>> recipes);
}

View file

@ -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<RecipeType<?>, Map<ResourceLocation, Recipe<?>>> recipes;
@Inject(method = "apply", at = @At(value = "RETURN"))
private void be_apply(Map<ResourceLocation, JsonElement> map, ResourceManager resourceManager, ProfilerFiller profiler, CallbackInfo info) {
recipes = BCLRecipeManager.getMap(recipes);
}
@Shadow
private <C extends Container, T extends Recipe<C>> Map<ResourceLocation, Recipe<C>> byType(RecipeType<T> 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 <C extends Container, T extends Recipe<C>> Optional<T> getRecipeFor(RecipeType<T> type, C inventory, Level world) {
Collection<Recipe<C>> values = byType(type).values();
List<Recipe<C>> list = new ArrayList<Recipe<C>>(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();
}
}

View file

@ -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<RecipeType<?>, Map<ResourceLocation, Recipe<?>>> RECIPES = Maps.newHashMap();
public static void addRecipe(RecipeType<?> type, Recipe<?> recipe) {
Map<ResourceLocation, Recipe<?>> list = RECIPES.get(type);
if (list == null) {
list = Maps.newHashMap();
RECIPES.put(type, list);
}
list.put(recipe.getId(), recipe);
}
@SuppressWarnings("unchecked")
public static <T extends Recipe<?>> T getRecipe(RecipeType<T> type, ResourceLocation id) {
if (RECIPES.containsKey(type)) {
return (T) RECIPES.get(type).get(id);
}
return null;
}
public static Map<RecipeType<?>, Map<ResourceLocation, Recipe<?>>> getMap(Map<RecipeType<?>, Map<ResourceLocation, Recipe<?>>> recipes) {
Map<RecipeType<?>, Map<ResourceLocation, Recipe<?>>> result = Maps.newHashMap();
for (RecipeType<?> type : recipes.keySet()) {
Map<ResourceLocation, Recipe<?>> typeList = Maps.newHashMap();
typeList.putAll(recipes.get(type));
result.put(type, typeList);
}
for (RecipeType<?> type : RECIPES.keySet()) {
Map<ResourceLocation, Recipe<?>> list = RECIPES.get(type);
if (list != null) {
Map<ResourceLocation, Recipe<?>> typeList = result.get(type);
if (typeList == null) {
typeList = Maps.newHashMap();
result.put(type, typeList);
}
for (Entry<ResourceLocation, Recipe<?>> entry : list.entrySet()) {
ResourceLocation id = entry.getKey();
if (!typeList.containsKey(id))
typeList.put(id, entry.getValue());
}
}
}
return result;
}
public static <S extends RecipeSerializer<T>, T extends Recipe<?>> S registerSerializer(String modID, String id, S serializer) {
return Registry.register(Registry.RECIPE_SERIALIZER, modID + ":" + id, serializer);
}
public static <T extends Recipe<?>> RecipeType<T> registerType(String modID, String type) {
ResourceLocation recipeTypeId = new ResourceLocation(modID, type);
return Registry.register(Registry.RECIPE_TYPE, recipeTypeId, new RecipeType<T>() {
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;
}
}

View file

@ -0,0 +1,102 @@
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;
import ru.bclib.config.PathConfig;
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 checkConfig(PathConfig config) {
exist = config.getBoolean("furnace", id.getPath(), true);
return this;
}
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);
}
}
}

View file

@ -0,0 +1,126 @@
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;
import ru.bclib.config.PathConfig;
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<Character, Ingredient> 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 checkConfig(PathConfig config) {
exist = config.getBoolean("grid", id.getPath(), true);
return this;
}
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<Item> 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<Ingredient> getMaterials(int width, int height) {
NonNullList<Ingredient> 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<Ingredient> 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);
}
}
}

View file

@ -0,0 +1,106 @@
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;
import ru.bclib.config.PathConfig;
public class SmithingTableRecipe {
private final static SmithingTableRecipe BUILDER = new SmithingTableRecipe();
private final static RecipeType<UpgradeRecipe> 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 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);
}
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<Item> 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<Item> tag) {
this.addition = (Ingredient.of(tag));
return this;
}
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;
}
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));
}
}

View file

@ -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);
}
}

View file

@ -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();

View file

@ -4,6 +4,7 @@
"package": "ru.bclib.mixin.client",
"compatibilityLevel": "JAVA_8",
"client": [
"EnchantingTableBlockMixin",
"ModelBakeryMixin"
],
"injectors": {

View file

@ -4,6 +4,11 @@
"package": "ru.bclib.mixin.common",
"compatibilityLevel": "JAVA_8",
"mixins": [
"ComposterBlockAccessor",
"PotionBrewingAccessor",
"RecipeManagerAccessor",
"EnchantmentMenuMixin",
"RecipeManagerMixin",
"BoneMealItemMixin",
"TagLoaderMixin"
],