*WIP*: Merge commit 'ce4cb8974f
' into 1.18
This commit is contained in:
commit
c6a7a1d4f7
76 changed files with 2754 additions and 738 deletions
95
src/main/java/ru/bclib/mixin/client/AnvilScreenMixin.java
Normal file
95
src/main/java/ru/bclib/mixin/client/AnvilScreenMixin.java
Normal 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);
|
||||
}
|
||||
}
|
|
@ -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;
|
||||
|
|
|
@ -1,2 +0,0 @@
|
|||
package ru.bclib.mixin.client;public class ClientLevelMixin {
|
||||
}
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -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();
|
||||
}
|
||||
}
|
|
@ -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();
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
31
src/main/java/ru/bclib/mixin/common/CraftingMenuMixin.java
Normal file
31
src/main/java/ru/bclib/mixin/common/CraftingMenuMixin.java
Normal 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);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -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)
|
||||
));
|
||||
}
|
||||
}
|
||||
}
|
|
@ -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();
|
||||
}
|
||||
}
|
||||
}
|
33
src/main/java/ru/bclib/mixin/common/PortalShapeMixin.java
Normal file
33
src/main/java/ru/bclib/mixin/common/PortalShapeMixin.java
Normal 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);
|
||||
}
|
||||
}
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
|
@ -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);
|
||||
}
|
||||
}
|
|
@ -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);
|
||||
}
|
||||
}
|
|
@ -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);
|
||||
}
|
||||
}
|
17
src/main/java/ru/bclib/mixin/common/shears/SheepMixin.java
Normal file
17
src/main/java/ru/bclib/mixin/common/shears/SheepMixin.java
Normal 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);
|
||||
}
|
||||
}
|
|
@ -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);
|
||||
}
|
||||
}
|
|
@ -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);
|
||||
}
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue