*WIP*: Merge commit 'ce4cb8974f' into 1.18

This commit is contained in:
Frank 2021-11-13 19:30:01 +01:00
commit c6a7a1d4f7
76 changed files with 2754 additions and 738 deletions

View file

@ -0,0 +1,95 @@
package ru.bclib.mixin.client;
import com.google.common.collect.Lists;
import com.mojang.blaze3d.vertex.PoseStack;
import net.minecraft.client.gui.components.AbstractWidget;
import net.minecraft.client.gui.components.Button;
import net.minecraft.client.gui.components.EditBox;
import net.minecraft.client.gui.screens.inventory.AnvilScreen;
import net.minecraft.client.gui.screens.inventory.ItemCombinerScreen;
import net.minecraft.network.chat.Component;
import net.minecraft.network.chat.TextComponent;
import net.minecraft.resources.ResourceLocation;
import net.minecraft.world.entity.player.Inventory;
import net.minecraft.world.inventory.AbstractContainerMenu;
import net.minecraft.world.inventory.AnvilMenu;
import net.minecraft.world.item.ItemStack;
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 ru.bclib.interfaces.AnvilScreenHandlerExtended;
import java.util.List;
@Mixin(AnvilScreen.class)
public class AnvilScreenMixin extends ItemCombinerScreen<AnvilMenu> {
@Shadow
private EditBox name;
private final List<AbstractWidget> be_buttons = Lists.newArrayList();
public AnvilScreenMixin(AnvilMenu handler, Inventory playerInventory, Component title, ResourceLocation texture) {
super(handler, playerInventory, title, texture);
}
@Inject(method = "subInit", at = @At("TAIL"))
protected void be_subInit(CallbackInfo info) {
int x = (width - imageWidth) / 2;
int y = (height - imageHeight) / 2;
be_buttons.clear();
be_buttons.add(new Button(x + 8, y + 45, 15, 20, new TextComponent("<"), b -> be_previousRecipe()));
be_buttons.add(new Button(x + 154, y + 45, 15, 20, new TextComponent(">"), b -> be_nextRecipe()));
}
@Inject(method = "renderFg", at = @At("TAIL"))
protected void be_renderForeground(PoseStack matrices, int mouseX, int mouseY, float delta, CallbackInfo info) {
be_buttons.forEach(button -> {
button.render(matrices, mouseX, mouseY, delta);
});
}
@Inject(method = "slotChanged", at = @At("HEAD"), cancellable = true)
public void be_onSlotUpdate(AbstractContainerMenu handler, int slotId, ItemStack stack, CallbackInfo info) {
AnvilScreenHandlerExtended anvilHandler = (AnvilScreenHandlerExtended) handler;
if (anvilHandler.be_getCurrentRecipe() != null) {
if (anvilHandler.be_getRecipes().size() > 1) {
be_buttons.forEach(button -> button.visible = true);
}
else {
be_buttons.forEach(button -> button.visible = false);
}
name.setValue("");
info.cancel();
}
else {
be_buttons.forEach(button -> button.visible = false);
}
}
private void be_nextRecipe() {
((AnvilScreenHandlerExtended) menu).be_nextRecipe();
}
private void be_previousRecipe() {
((AnvilScreenHandlerExtended) menu).be_previousRecipe();
}
@Override
public boolean mouseClicked(double mouseX, double mouseY, int button) {
if (minecraft != null) {
for (AbstractWidget elem : be_buttons) {
if (elem.visible && elem.mouseClicked(mouseX, mouseY, button)) {
if (minecraft.gameMode != null) {
int i = be_buttons.indexOf(elem);
minecraft.gameMode.handleInventoryButtonClick(menu.containerId, i);
return true;
}
}
}
}
return super.mouseClicked(mouseX, mouseY, button);
}
}

View file

@ -23,6 +23,7 @@ public class BackgroundRendererMixin {
private static final MutableBlockPos BCLIB_LAST_POS = new MutableBlockPos(0, -100, 0);
private static final MutableBlockPos BCLIB_MUT_POS = new MutableBlockPos();
private static final float[] BCLIB_FOG_DENSITY = new float[8];
//private static boolean isEnd;
@Shadow
private static float fogRed;

View file

@ -1,2 +0,0 @@
package ru.bclib.mixin.client;public class ClientLevelMixin {
}

View file

@ -0,0 +1,20 @@
package ru.bclib.mixin.client;
import net.minecraft.client.ClientRecipeBook;
import net.minecraft.client.RecipeBookCategories;
import net.minecraft.world.item.crafting.Recipe;
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.CallbackInfoReturnable;
import ru.bclib.interfaces.UnknownReceipBookCategory;
@Mixin(ClientRecipeBook.class)
public abstract class ClientRecipeBookMixin {
@Inject(method = "getCategory", at = @At("HEAD"), cancellable = true)
private static void be_getGroupForRecipe(Recipe<?> recipe, CallbackInfoReturnable<RecipeBookCategories> info) {
if (recipe instanceof UnknownReceipBookCategory) {
info.setReturnValue(RecipeBookCategories.UNKNOWN);
}
}
}

View file

@ -1,18 +0,0 @@
package ru.bclib.mixin.client;
import net.minecraft.network.protocol.game.ClientGamePacketListener;
import net.minecraft.network.protocol.game.ClientboundLoginPacket;
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;
@Mixin(ClientboundLoginPacket.class)
public abstract class ClientboundLoginPacketMixin {
@Inject(method = "handle", cancellable = true, at=@At("HEAD"))
public void bclib_handle(ClientGamePacketListener clientGamePacketListener, CallbackInfo ci){
//cLevel.setBCLibDidSendHello();
// DataExchangeAPI.sendOnEnter();
// ci.cancel();
}
}

View file

@ -100,8 +100,7 @@ public abstract class MinecraftMixin {
DataExchangeAPI.prepareServerside();
if (DataFixerAPI.fixData(this.levelSource, levelID, true, (appliedFixes) -> {
bclib_doLoadLevel_BACKUP(levelID, RegistryAccess.builtin(), Minecraft::loadDataPacks, Minecraft::loadWorldData, false);
//this.doLoadLevel(levelID, RegistryAccess.builtin(), Minecraft::loadDataPacks, Minecraft::loadWorldData, false, Minecraft.ExperimentalDialogType.BACKUP);
this.doLoadLevel(levelID, RegistryAccess.builtin(), Minecraft::loadDataPacks, Minecraft::loadWorldData, false, appliedFixes?ExperimentalDialogType.NONE:ExperimentalDialogType.BACKUP);
})) {
ci.cancel();
}

View file

@ -9,6 +9,8 @@ import net.minecraft.world.inventory.DataSlot;
import net.minecraft.world.inventory.ItemCombinerMenu;
import net.minecraft.world.inventory.MenuType;
import net.minecraft.world.item.ItemStack;
import net.minecraft.world.item.crafting.RecipeManager;
import net.minecraft.world.level.block.Block;
import net.minecraft.world.level.block.state.BlockState;
import org.jetbrains.annotations.Nullable;
import org.spongepowered.asm.mixin.Final;
@ -17,10 +19,22 @@ 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 org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
import ru.bclib.blocks.BaseAnvilBlock;
import ru.bclib.blocks.LeveledAnvilBlock;
import ru.bclib.interfaces.AnvilScreenHandlerExtended;
import ru.bclib.recipes.AnvilRecipe;
import java.util.Collections;
import java.util.List;
import java.util.stream.Collectors;
@Mixin(AnvilMenu.class)
public abstract class AnvilMenuMixin extends ItemCombinerMenu {
public abstract class AnvilMenuMixin extends ItemCombinerMenu implements AnvilScreenHandlerExtended {
private List<AnvilRecipe> be_recipes = Collections.emptyList();
private AnvilRecipe be_currentRecipe;
private DataSlot anvilLevel;
@Shadow
private int repairItemCountCost;
@ -31,9 +45,64 @@ public abstract class AnvilMenuMixin extends ItemCombinerMenu {
public AnvilMenuMixin(@Nullable MenuType<?> menuType, int i, Inventory inventory, ContainerLevelAccess containerLevelAccess) {
super(menuType, i, inventory, containerLevelAccess);
}
@Inject(method = "<init>(ILnet/minecraft/world/entity/player/Inventory;Lnet/minecraft/world/inventory/ContainerLevelAccess;)V", at = @At("TAIL"))
public void be_initAnvilLevel(int syncId, Inventory inventory, ContainerLevelAccess context, CallbackInfo info) {
this.anvilLevel = addDataSlot(DataSlot.standalone());
if (context != ContainerLevelAccess.NULL) {
int level = context.evaluate((world, blockPos) -> {
Block anvilBlock = world.getBlockState(blockPos).getBlock();
if (anvilBlock instanceof LeveledAnvilBlock) {
return ((LeveledAnvilBlock) anvilBlock).getCraftingLevel();
}
return 1;
}, 1);
anvilLevel.set(level);
}
else {
anvilLevel.set(1);
}
}
@Shadow
public abstract void createResult();
@Inject(method = "mayPickup", at = @At("HEAD"), cancellable = true)
protected void be_canTakeOutput(Player player, boolean present, CallbackInfoReturnable<Boolean> info) {
if (be_currentRecipe != null) {
info.setReturnValue(be_currentRecipe.checkHammerDurability(inputSlots, player));
}
}
@Inject(method = "onTake", at = @At("HEAD"), cancellable = true)
protected void bclib_onTakeAnvilOutput(Player player, ItemStack stack, CallbackInfo info) {
if (be_currentRecipe != null) {
inputSlots.getItem(0).shrink(be_currentRecipe.getInputCount());
stack = be_currentRecipe.craft(inputSlots, player);
slotsChanged(inputSlots);
access.execute((world, blockPos) -> {
final BlockState anvilState = world.getBlockState(blockPos);
final Block anvilBlock = anvilState.getBlock();
if (anvilBlock instanceof BaseAnvilBlock) {
final BaseAnvilBlock anvil = (BaseAnvilBlock) anvilBlock;
if (!player.getAbilities().instabuild && anvilState.is(BlockTags.ANVIL) && player.getRandom().nextDouble() < 0.1) {
BlockState damagedState = anvil.damageAnvilUse(anvilState, player.getRandom());
if (damagedState == null) {
world.removeBlock(blockPos, false);
world.levelEvent(1029, blockPos, 0);
} else {
world.setBlock(blockPos, damagedState, 2);
world.levelEvent(1030, blockPos, 0);
}
} else {
world.levelEvent(1030, blockPos, 0);
}
}
});
info.cancel();
return;
}
this.access.execute((level, blockPos) -> {
BlockState blockState = level.getBlockState(blockPos);
if (blockState.getBlock() instanceof BaseAnvilBlock) {
@ -77,4 +146,68 @@ public abstract class AnvilMenuMixin extends ItemCombinerMenu {
}
});
}
@Inject(method = "createResult", at = @At("HEAD"), cancellable = true)
public void be_updateOutput(CallbackInfo info) {
RecipeManager recipeManager = this.player.level.getRecipeManager();
be_recipes = recipeManager.getRecipesFor(AnvilRecipe.TYPE, inputSlots, player.level);
if (be_recipes.size() > 0) {
int anvilLevel = this.anvilLevel.get();
be_recipes = be_recipes.stream()
.filter(recipe -> anvilLevel >= recipe.getAnvilLevel())
.collect(Collectors.toList());
if (be_recipes.size() > 0) {
if (be_currentRecipe == null || !be_recipes.contains(be_currentRecipe)) {
be_currentRecipe = be_recipes.get(0);
}
be_updateResult();
info.cancel();
}
else {
be_currentRecipe = null;
}
}
}
@Inject(method = "setItemName", at = @At("HEAD"), cancellable = true)
public void be_setNewItemName(String string, CallbackInfo info) {
if (be_currentRecipe != null) {
info.cancel();
}
}
@Override
public boolean clickMenuButton(Player player, int id) {
if (id == 0) {
be_previousRecipe();
return true;
}
else if (id == 1) {
be_nextRecipe();
return true;
}
return super.clickMenuButton(player, id);
}
private void be_updateResult() {
if (be_currentRecipe == null) return;
resultSlots.setItem(0, be_currentRecipe.assemble(inputSlots));
broadcastChanges();
}
@Override
public void be_updateCurrentRecipe(AnvilRecipe recipe) {
this.be_currentRecipe = recipe;
be_updateResult();
}
@Override
public AnvilRecipe be_getCurrentRecipe() {
return be_currentRecipe;
}
@Override
public List<AnvilRecipe> be_getRecipes() {
return be_recipes;
}
}

View file

@ -0,0 +1,134 @@
package ru.bclib.mixin.common;
import net.fabricmc.loader.api.FabricLoader;
import net.minecraft.core.BlockPos;
import net.minecraft.util.BitStorage;
import net.minecraft.util.Mth;
import net.minecraft.world.level.biome.Biome;
import net.minecraft.world.level.chunk.ChunkBiomeContainer;
import org.spongepowered.asm.mixin.Final;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Shadow;
import ru.bclib.BCLib;
import ru.bclib.interfaces.BiomeSetter;
import java.lang.reflect.Field;
@Mixin(ChunkBiomeContainer.class)
public class ChunkBiomeContainerMixin implements BiomeSetter {
private static boolean bclib_hasHydrogen = FabricLoader.getInstance().isModLoaded("hydrogen");
@Final
@Shadow
private Biome[] biomes;
@Final
@Shadow
private static int WIDTH_BITS;
@Final
@Shadow
private static int HORIZONTAL_MASK;
@Override
public void bclib_setBiome(Biome biome, BlockPos pos) {
int biomeX = pos.getX() >> 2;
int biomeY = pos.getY() >> 2;
int biomeZ = pos.getZ() >> 2;
int index = be_getArrayIndex(biomeX, biomeY, biomeZ);
if (bclib_hasHydrogen && be_shouldWriteToHydrogen()) {
try {
ChunkBiomeContainer self = (ChunkBiomeContainer) (Object) this;
BitStorage storage = be_getHydrogenStorage(self);
Biome[] palette = be_getHydrogenPalette(self);
int paletteIndex = be_getHydrogenPaletteIndex(biome, palette);
if (paletteIndex == -1) {
Biome[] newPalette = new Biome[palette.length + 1];
System.arraycopy(palette, 0, newPalette, 0, palette.length);
paletteIndex = palette.length;
palette = newPalette;
palette[paletteIndex] = biome;
be_setHydrogenPalette(self, palette);
}
try {
storage.set(index, paletteIndex);
}
catch (Exception e) {
int size = storage.getSize();
int bits = Mth.ceillog2(palette.length);
BitStorage newStorage = new BitStorage(bits, size);
for (int i = 0; i < size; i++) {
newStorage.set(i, storage.get(i));
}
storage = newStorage;
storage.set(index, paletteIndex);
be_setHydrogenStorage(self, storage);
}
}
catch (Exception e) {
BCLib.LOGGER.warning(e.getLocalizedMessage());
}
return;
}
biomes[index] = biome;
}
@Shadow
@Final
private int quartMinY;
@Shadow
@Final
private int quartHeight;
private boolean be_shouldWriteToHydrogen() {
try {
Field field = ChunkBiomeContainer.class.getDeclaredField("intArray");
return field != null;
}
catch (NoSuchFieldException e) {
return false;
}
}
private int be_getArrayIndex(int biomeX, int biomeY, int biomeZ) {
int i = biomeX & HORIZONTAL_MASK;
int j = Mth.clamp(biomeY - this.quartMinY, 0, this.quartHeight);
int k = biomeZ & HORIZONTAL_MASK;
return j << WIDTH_BITS + WIDTH_BITS | k << WIDTH_BITS | i;
}
private Field be_getField(String name) throws Exception {
Field field = ChunkBiomeContainer.class.getDeclaredField(name);
field.setAccessible(true);
return field;
}
private BitStorage be_getHydrogenStorage(ChunkBiomeContainer container) throws Exception {
return (BitStorage) be_getField("intArray").get(container);
}
private Biome[] be_getHydrogenPalette(ChunkBiomeContainer container) throws Exception {
return (Biome[]) be_getField("palette").get(container);
}
private int be_getHydrogenPaletteIndex(Biome biome, Biome[] palette) {
int index = -1;
for (int i = 0; i < palette.length; i++) {
if (palette[i] == biome) {
index = i;
break;
}
}
return index;
}
private void be_setHydrogenPalette(ChunkBiomeContainer container, Biome[] palette) throws Exception {
be_getField("palette").set(container, palette);
}
private void be_setHydrogenStorage(ChunkBiomeContainer container, BitStorage storage) throws Exception {
be_getField("intArray").set(container, storage);
}
}

View file

@ -0,0 +1,31 @@
package ru.bclib.mixin.common;
import net.minecraft.world.entity.player.Player;
import net.minecraft.world.inventory.ContainerLevelAccess;
import net.minecraft.world.inventory.CraftingMenu;
import net.minecraft.world.level.block.CraftingTableBlock;
import net.minecraft.world.level.block.state.BlockState;
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.CallbackInfoReturnable;
import ru.bclib.api.TagAPI;
@Mixin(CraftingMenu.class)
public abstract class CraftingMenuMixin {
@Final
@Shadow
private ContainerLevelAccess access;
@Inject(method = "stillValid", at = @At("HEAD"), cancellable = true)
private void bclib_stillValid(Player player, CallbackInfoReturnable<Boolean> info) {
if (access.evaluate((world, pos) -> {
BlockState state = world.getBlockState(pos);
return state.getBlock() instanceof CraftingTableBlock || state.is(TagAPI.BLOCK_WORKBENCHES);
}, true)) {
info.setReturnValue(true);
}
}
}

View file

@ -12,24 +12,29 @@ import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
import ru.bclib.world.generator.BCLibEndBiomeSource;
import ru.bclib.world.generator.BCLibNetherBiomeSource;
import ru.bclib.world.generator.GeneratorOptions;
@Mixin(value = DimensionType.class, priority = 100)
public class DimensionTypeMixin {
@Inject(method = "defaultNetherGenerator", at = @At("HEAD"), cancellable = true)
private static void be_replaceNetherBiomeSource(Registry<Biome> biomeRegistry, Registry<NoiseGeneratorSettings> chunkGeneratorSettingsRegistry, long seed, CallbackInfoReturnable<ChunkGenerator> info) {
info.setReturnValue(new NoiseBasedChunkGenerator(
new BCLibNetherBiomeSource(biomeRegistry, seed),
seed,
() -> chunkGeneratorSettingsRegistry.getOrThrow(NoiseGeneratorSettings.NETHER)
));
if (GeneratorOptions.customNetherBiomeSource()) {
info.setReturnValue(new NoiseBasedChunkGenerator(
new BCLibNetherBiomeSource(biomeRegistry, seed),
seed,
() -> chunkGeneratorSettingsRegistry.getOrThrow(NoiseGeneratorSettings.NETHER)
));
}
}
@Inject(method = "defaultEndGenerator", at = @At("HEAD"), cancellable = true)
private static void be_replaceEndBiomeSource(Registry<Biome> biomeRegistry, Registry<NoiseGeneratorSettings> chunkGeneratorSettingsRegistry, long seed, CallbackInfoReturnable<ChunkGenerator> info) {
info.setReturnValue(new NoiseBasedChunkGenerator(
new BCLibEndBiomeSource(biomeRegistry, seed),
seed,
() -> chunkGeneratorSettingsRegistry.getOrThrow(NoiseGeneratorSettings.END)
));
if (GeneratorOptions.customEndBiomeSource()) {
info.setReturnValue(new NoiseBasedChunkGenerator(
new BCLibEndBiomeSource(biomeRegistry, seed),
seed,
() -> chunkGeneratorSettingsRegistry.getOrThrow(NoiseGeneratorSettings.END)
));
}
}
}

View file

@ -0,0 +1,23 @@
package ru.bclib.mixin.common;
import net.minecraft.core.BlockPos;
import net.minecraft.core.Direction;
import net.minecraft.world.level.Level;
import net.minecraft.world.level.block.piston.PistonBaseBlock;
import net.minecraft.world.level.block.state.BlockState;
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.CallbackInfoReturnable;
import ru.bclib.api.TagAPI;
@Mixin(PistonBaseBlock.class)
public class PistonBaseBlockMixin {
@Inject(method="isPushable", at=@At("HEAD"), cancellable = true)
private static void bclib_isPushable(BlockState blockState, Level level, BlockPos blockPos, Direction direction, boolean bl, Direction direction2, CallbackInfoReturnable<Boolean> cir){
if (blockState.is(TagAPI.BLOCK_IMMOBILE)){
cir.setReturnValue(false);
cir.cancel();
}
}
}

View file

@ -0,0 +1,33 @@
package ru.bclib.mixin.common;
import net.minecraft.core.BlockPos;
import net.minecraft.world.level.BlockGetter;
import net.minecraft.world.level.block.state.BlockBehaviour.StatePredicate;
import net.minecraft.world.level.block.state.BlockState;
import net.minecraft.world.level.portal.PortalShape;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Redirect;
import ru.bclib.api.TagAPI;
@Mixin(PortalShape.class)
public class PortalShapeMixin {
@Redirect(method="getDistanceUntilEdgeAboveFrame", at=@At(value="INVOKE", target="Lnet/minecraft/world/level/block/state/BlockBehaviour$StatePredicate;test(Lnet/minecraft/world/level/block/state/BlockState;Lnet/minecraft/world/level/BlockGetter;Lnet/minecraft/core/BlockPos;)Z"))
private boolean be_getDistanceUntilEdgeAboveFrame(StatePredicate statePredicate, BlockState blockState, BlockGetter blockGetter, BlockPos blockPos){
return be_FRAME(statePredicate, blockState, blockGetter, blockPos);
}
@Redirect(method="hasTopFrame", at=@At(value="INVOKE", target="Lnet/minecraft/world/level/block/state/BlockBehaviour$StatePredicate;test(Lnet/minecraft/world/level/block/state/BlockState;Lnet/minecraft/world/level/BlockGetter;Lnet/minecraft/core/BlockPos;)Z"))
private boolean be_hasTopFrame(StatePredicate statePredicate, BlockState blockState, BlockGetter blockGetter, BlockPos blockPos){
return be_FRAME(statePredicate, blockState, blockGetter, blockPos);
}
@Redirect(method="getDistanceUntilTop", at=@At(value="INVOKE", target="Lnet/minecraft/world/level/block/state/BlockBehaviour$StatePredicate;test(Lnet/minecraft/world/level/block/state/BlockState;Lnet/minecraft/world/level/BlockGetter;Lnet/minecraft/core/BlockPos;)Z"))
private boolean be_getDistanceUntilTop(StatePredicate statePredicate, BlockState blockState, BlockGetter blockGetter, BlockPos blockPos){
return be_FRAME(statePredicate, blockState, blockGetter, blockPos);
}
private static boolean be_FRAME(StatePredicate FRAME, BlockState state, BlockGetter getter, BlockPos pos){
return state.is(TagAPI.BLOCK_NETHER_PORTAL_FRAME) || FRAME.test(state, getter, pos);
}
}

View file

@ -33,6 +33,7 @@ public abstract class ServerLevelMixin extends Level {
@Inject(method = "<init>*", at = @At("TAIL"))
private void bclib_onServerWorldInit(MinecraftServer server, Executor workerExecutor, LevelStorageSource.LevelStorageAccess session, ServerLevelData properties, ResourceKey<Level> registryKey, DimensionType dimensionType, ChunkProgressListener worldGenerationProgressListener, ChunkGenerator chunkGenerator, boolean debugWorld, long l, List<CustomSpawner> list, boolean bl, CallbackInfo info) {
BiomeAPI.initRegistry(server);
BiomeAPI.applyModifications(ServerLevel.class.cast(this));
if (bclib_lastWorld != null && bclib_lastWorld.equals(session.getLevelId())) {
return;

View file

@ -0,0 +1,17 @@
package ru.bclib.mixin.common.shears;
import net.minecraft.world.item.Item;
import net.minecraft.world.item.ItemStack;
import net.minecraft.world.level.block.BeehiveBlock;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Redirect;
import ru.bclib.items.tool.BaseShearsItem;
@Mixin(BeehiveBlock.class)
public class BeehiveBlockMixin {
@Redirect(method="use", at=@At(value="INVOKE", target="Lnet/minecraft/world/item/ItemStack;is(Lnet/minecraft/world/item/Item;)Z"))
public boolean bn_useProxy(ItemStack itemStack, Item item){
return BaseShearsItem.isShear(itemStack, item);
}
}

View file

@ -0,0 +1,17 @@
package ru.bclib.mixin.common.shears;
import net.minecraft.world.item.Item;
import net.minecraft.world.item.ItemStack;
import net.minecraft.world.item.enchantment.DiggingEnchantment;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Redirect;
import ru.bclib.items.tool.BaseShearsItem;
@Mixin(DiggingEnchantment.class)
public class DiggingEnchantmentMixin {
@Redirect(method="canEnchant", at=@At(value="INVOKE", target="Lnet/minecraft/world/item/ItemStack;is(Lnet/minecraft/world/item/Item;)Z"))
public boolean bn_mobInteractProxy(ItemStack itemStack, Item item){
return BaseShearsItem.isShear(itemStack, item);
}
}

View file

@ -0,0 +1,17 @@
package ru.bclib.mixin.common.shears;
import net.minecraft.world.entity.animal.MushroomCow;
import net.minecraft.world.item.Item;
import net.minecraft.world.item.ItemStack;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Redirect;
import ru.bclib.items.tool.BaseShearsItem;
@Mixin(MushroomCow.class)
public class MushroomCowMixin {
@Redirect(method="mobInteract", at=@At(value="INVOKE", target="Lnet/minecraft/world/item/ItemStack;is(Lnet/minecraft/world/item/Item;)Z"))
public boolean bn_mobInteractProxy(ItemStack itemStack, Item item){
return BaseShearsItem.isShear(itemStack, item);
}
}

View file

@ -0,0 +1,17 @@
package ru.bclib.mixin.common.shears;
import net.minecraft.world.item.Item;
import net.minecraft.world.item.ItemStack;
import net.minecraft.world.level.block.PumpkinBlock;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Redirect;
import ru.bclib.items.tool.BaseShearsItem;
@Mixin(PumpkinBlock.class)
public abstract class PumpkinBlockMixin {
@Redirect(method="use", at=@At(value="INVOKE", target="Lnet/minecraft/world/item/ItemStack;is(Lnet/minecraft/world/item/Item;)Z"))
public boolean bn_useProxy(ItemStack itemStack, Item item){
return BaseShearsItem.isShear(itemStack, item);
}
}

View file

@ -0,0 +1,17 @@
package ru.bclib.mixin.common.shears;
import net.minecraft.world.entity.animal.Sheep;
import net.minecraft.world.item.Item;
import net.minecraft.world.item.ItemStack;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Redirect;
import ru.bclib.items.tool.BaseShearsItem;
@Mixin(Sheep.class)
public class SheepMixin {
@Redirect(method="mobInteract", at=@At(value="INVOKE", target="Lnet/minecraft/world/item/ItemStack;is(Lnet/minecraft/world/item/Item;)Z"))
public boolean bn_mobInteractProxy(ItemStack itemStack, Item item){
return BaseShearsItem.isShear(itemStack, item);
}
}

View file

@ -0,0 +1,17 @@
package ru.bclib.mixin.common.shears;
import net.minecraft.world.entity.animal.SnowGolem;
import net.minecraft.world.item.Item;
import net.minecraft.world.item.ItemStack;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Redirect;
import ru.bclib.items.tool.BaseShearsItem;
@Mixin(SnowGolem.class)
public class SnowGolemMixin {
@Redirect(method="mobInteract", at=@At(value="INVOKE", target="Lnet/minecraft/world/item/ItemStack;is(Lnet/minecraft/world/item/Item;)Z"))
public boolean bn_mobInteractProxy(ItemStack itemStack, Item item){
return BaseShearsItem.isShear(itemStack, item);
}
}

View file

@ -0,0 +1,17 @@
package ru.bclib.mixin.common.shears;
import net.minecraft.world.item.Item;
import net.minecraft.world.item.ItemStack;
import net.minecraft.world.level.block.TripWireBlock;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Redirect;
import ru.bclib.items.tool.BaseShearsItem;
@Mixin(TripWireBlock.class)
public class TripWireBlockMixin {
@Redirect(method="playerWillDestroy", at=@At(value="INVOKE", target="Lnet/minecraft/world/item/ItemStack;is(Lnet/minecraft/world/item/Item;)Z"))
public boolean bn_useProxy(ItemStack itemStack, Item item){
return BaseShearsItem.isShear(itemStack, item);
}
}