Reorganized Imports/Packages
This commit is contained in:
parent
cb9459f176
commit
3ee10482ab
721 changed files with 34873 additions and 33558 deletions
|
@ -0,0 +1,93 @@
|
|||
package org.betterx.bclib.mixin.client;
|
||||
|
||||
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.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 com.google.common.collect.Lists;
|
||||
import com.mojang.blaze3d.vertex.PoseStack;
|
||||
import org.betterx.bclib.interfaces.AnvilScreenHandlerExtended;
|
||||
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 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, Component.literal("<"), b -> be_previousRecipe()));
|
||||
be_buttons.add(new Button(x + 154, y + 45, 15, 20, Component.literal(">"), 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);
|
||||
}
|
||||
}
|
30
src/main/java/org/betterx/bclib/mixin/client/BlockMixin.java
Normal file
30
src/main/java/org/betterx/bclib/mixin/client/BlockMixin.java
Normal file
|
@ -0,0 +1,30 @@
|
|||
package org.betterx.bclib.mixin.client;
|
||||
|
||||
import net.minecraft.network.chat.Component;
|
||||
import net.minecraft.world.item.ItemStack;
|
||||
import net.minecraft.world.item.TooltipFlag;
|
||||
import net.minecraft.world.level.BlockGetter;
|
||||
import net.minecraft.world.level.block.Block;
|
||||
|
||||
import org.betterx.bclib.interfaces.SurvivesOnSpecialGround;
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
import org.spongepowered.asm.mixin.injection.At;
|
||||
import org.spongepowered.asm.mixin.injection.Inject;
|
||||
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
|
||||
|
||||
import java.util.List;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
@Mixin(Block.class)
|
||||
public class BlockMixin {
|
||||
@Inject(method = "appendHoverText", at = @At("HEAD"))
|
||||
void bclib_appendSurvivalBlock(ItemStack itemStack,
|
||||
@Nullable BlockGetter blockGetter,
|
||||
List<Component> list,
|
||||
TooltipFlag tooltipFlag,
|
||||
CallbackInfo ci) {
|
||||
if (this instanceof SurvivesOnSpecialGround surv) {
|
||||
SurvivesOnSpecialGround.appendHoverText(list, surv.getSurvivableBlocksString());
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,21 @@
|
|||
package org.betterx.bclib.mixin.client;
|
||||
|
||||
import net.minecraft.client.ClientRecipeBook;
|
||||
import net.minecraft.client.RecipeBookCategories;
|
||||
import net.minecraft.world.item.crafting.Recipe;
|
||||
|
||||
import org.betterx.bclib.interfaces.UnknownReceipBookCategory;
|
||||
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;
|
||||
|
||||
@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);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,24 @@
|
|||
package org.betterx.bclib.mixin.client;
|
||||
|
||||
import net.minecraft.client.gui.screens.Screen;
|
||||
import net.minecraft.client.gui.screens.worldselection.CreateWorldScreen;
|
||||
import net.minecraft.client.gui.screens.worldselection.WorldGenSettingsComponent;
|
||||
import net.minecraft.core.Registry;
|
||||
import net.minecraft.world.level.DataPackConfig;
|
||||
|
||||
import org.betterx.bclib.api.biomes.BiomeAPI;
|
||||
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(CreateWorldScreen.class)
|
||||
public class CreateWorldScreenMixin {
|
||||
@Inject(method = "<init>", at = @At("TAIL"))
|
||||
private void bcl_init(Screen screen,
|
||||
DataPackConfig dataPackConfig,
|
||||
WorldGenSettingsComponent worldGenSettingsComponent,
|
||||
CallbackInfo ci) {
|
||||
BiomeAPI.initRegistry(worldGenSettingsComponent.registryHolder().registryOrThrow(Registry.BIOME_REGISTRY));
|
||||
}
|
||||
}
|
|
@ -0,0 +1,68 @@
|
|||
package org.betterx.bclib.mixin.client;
|
||||
|
||||
import net.minecraft.client.Camera;
|
||||
import net.minecraft.client.multiplayer.ClientLevel;
|
||||
import net.minecraft.client.renderer.FogRenderer;
|
||||
import net.minecraft.world.effect.MobEffectInstance;
|
||||
import net.minecraft.world.effect.MobEffects;
|
||||
import net.minecraft.world.entity.Entity;
|
||||
import net.minecraft.world.entity.LivingEntity;
|
||||
import net.minecraft.world.level.Level;
|
||||
import net.minecraft.world.level.material.FogType;
|
||||
|
||||
import org.betterx.bclib.client.render.CustomFogRenderer;
|
||||
import org.betterx.bclib.util.BackgroundInfo;
|
||||
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;
|
||||
|
||||
@Mixin(FogRenderer.class)
|
||||
public class FogRendererMixin {
|
||||
@Shadow
|
||||
private static float fogRed;
|
||||
@Shadow
|
||||
private static float fogGreen;
|
||||
@Shadow
|
||||
private static float fogBlue;
|
||||
|
||||
@Inject(method = "setupColor", at = @At("RETURN"))
|
||||
private static void bclib_onRender(Camera camera,
|
||||
float tickDelta,
|
||||
ClientLevel world,
|
||||
int i,
|
||||
float f,
|
||||
CallbackInfo info) {
|
||||
FogType fogType = camera.getFluidInCamera();
|
||||
if (fogType != FogType.WATER && world.dimension().equals(Level.END)) {
|
||||
Entity entity = camera.getEntity();
|
||||
boolean skip = false;
|
||||
if (entity instanceof LivingEntity) {
|
||||
MobEffectInstance effect = ((LivingEntity) entity).getEffect(MobEffects.NIGHT_VISION);
|
||||
skip = effect != null && effect.getDuration() > 0;
|
||||
}
|
||||
if (!skip) {
|
||||
fogRed *= 4;
|
||||
fogGreen *= 4;
|
||||
fogBlue *= 4;
|
||||
}
|
||||
}
|
||||
|
||||
BackgroundInfo.fogColorRed = fogRed;
|
||||
BackgroundInfo.fogColorGreen = fogGreen;
|
||||
BackgroundInfo.fogColorBlue = fogBlue;
|
||||
}
|
||||
|
||||
@Inject(method = "setupFog", at = @At("HEAD"), cancellable = true)
|
||||
private static void bclib_fogDensity(Camera camera,
|
||||
FogRenderer.FogMode fogMode,
|
||||
float viewDistance,
|
||||
boolean thickFog,
|
||||
float g,
|
||||
CallbackInfo ci) {
|
||||
if (CustomFogRenderer.applyFogDensity(camera, viewDistance, thickFog)) {
|
||||
ci.cancel();
|
||||
}
|
||||
}
|
||||
}
|
18
src/main/java/org/betterx/bclib/mixin/client/GameMixin.java
Normal file
18
src/main/java/org/betterx/bclib/mixin/client/GameMixin.java
Normal file
|
@ -0,0 +1,18 @@
|
|||
package org.betterx.bclib.mixin.client;
|
||||
|
||||
import net.minecraft.client.Game;
|
||||
|
||||
import org.betterx.bclib.api.dataexchange.DataExchangeAPI;
|
||||
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(Game.class)
|
||||
public class GameMixin {
|
||||
|
||||
@Inject(method = "onStartGameSession", at = @At("TAIL"))
|
||||
public void bclib_onStart(CallbackInfo ci) {
|
||||
DataExchangeAPI.sendOnEnter();
|
||||
}
|
||||
}
|
|
@ -0,0 +1,36 @@
|
|||
package org.betterx.bclib.mixin.client;
|
||||
|
||||
import net.minecraft.client.Minecraft;
|
||||
import net.minecraft.client.color.block.BlockColors;
|
||||
import net.minecraft.client.color.item.ItemColors;
|
||||
import net.minecraft.client.main.GameConfig;
|
||||
import net.minecraft.core.Registry;
|
||||
|
||||
import org.betterx.bclib.interfaces.CustomColorProvider;
|
||||
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;
|
||||
|
||||
@Mixin(Minecraft.class)
|
||||
public abstract class MinecraftMixin {
|
||||
@Final
|
||||
@Shadow
|
||||
private BlockColors blockColors;
|
||||
|
||||
@Final
|
||||
@Shadow
|
||||
private ItemColors itemColors;
|
||||
|
||||
@Inject(method = "<init>*", at = @At("TAIL"))
|
||||
private void bclib_onMCInit(GameConfig args, CallbackInfo info) {
|
||||
Registry.BLOCK.forEach(block -> {
|
||||
if (block instanceof CustomColorProvider provider) {
|
||||
blockColors.register(provider.getProvider(), block);
|
||||
itemColors.register(provider.getItemProvider(), block.asItem());
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
|
@ -0,0 +1,38 @@
|
|||
package org.betterx.bclib.mixin.client;
|
||||
|
||||
import net.minecraft.client.color.block.BlockColors;
|
||||
import net.minecraft.client.resources.model.ModelBakery;
|
||||
import net.minecraft.client.resources.model.UnbakedModel;
|
||||
import net.minecraft.resources.ResourceLocation;
|
||||
import net.minecraft.server.packs.resources.ResourceManager;
|
||||
import net.minecraft.util.profiling.ProfilerFiller;
|
||||
|
||||
import org.betterx.bclib.api.ModIntegrationAPI;
|
||||
import org.betterx.bclib.client.models.CustomModelBakery;
|
||||
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 java.util.Map;
|
||||
|
||||
@Mixin(ModelBakery.class)
|
||||
public abstract class ModelBakeryMixin {
|
||||
@Final
|
||||
@Shadow
|
||||
private Map<ResourceLocation, UnbakedModel> unbakedCache;
|
||||
|
||||
@Inject(method = "<init>*", at = @At("TAIL"))
|
||||
private void bclib_findEmissiveModels(ResourceManager resourceManager,
|
||||
BlockColors blockColors,
|
||||
ProfilerFiller profiler,
|
||||
int mipmap,
|
||||
CallbackInfo info) {
|
||||
//CustomModelBakery.setModelsLoaded(false);
|
||||
if (ModIntegrationAPI.hasCanvas()) {
|
||||
CustomModelBakery.loadEmissiveModels(unbakedCache);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,22 @@
|
|||
package org.betterx.bclib.mixin.client;
|
||||
|
||||
import net.minecraft.client.resources.model.ModelBakery;
|
||||
import net.minecraft.client.resources.model.ModelManager;
|
||||
import net.minecraft.server.packs.resources.ResourceManager;
|
||||
import net.minecraft.util.profiling.ProfilerFiller;
|
||||
|
||||
import org.betterx.bclib.client.BCLibClient;
|
||||
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;
|
||||
|
||||
@Mixin(ModelManager.class)
|
||||
public class ModelManagerMixin {
|
||||
@Inject(method = "prepare", at = @At("HEAD"))
|
||||
private void bclib_loadCustomModels(ResourceManager resourceManager,
|
||||
ProfilerFiller profilerFiller,
|
||||
CallbackInfoReturnable<ModelBakery> info) {
|
||||
BCLibClient.modelBakery.loadCustomModels(resourceManager);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,55 @@
|
|||
package org.betterx.bclib.mixin.client;
|
||||
|
||||
import net.minecraft.resources.ResourceLocation;
|
||||
import net.minecraft.server.packs.resources.FallbackResourceManager;
|
||||
import net.minecraft.server.packs.resources.MultiPackResourceManager;
|
||||
import net.minecraft.server.packs.resources.Resource;
|
||||
import net.minecraft.server.packs.resources.ResourceManager;
|
||||
|
||||
import org.betterx.bclib.BCLib;
|
||||
import org.betterx.bclib.api.ModIntegrationAPI;
|
||||
import org.betterx.bclib.client.render.EmissiveTextureInfo;
|
||||
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 java.io.IOException;
|
||||
import java.util.Map;
|
||||
|
||||
@Mixin(MultiPackResourceManager.class)
|
||||
public class MultiPackResourceManagerMixin {
|
||||
@Final
|
||||
@Shadow
|
||||
private Map<String, FallbackResourceManager> namespacedManagers;
|
||||
|
||||
private final ResourceLocation bclib_alphaEmissionMaterial = BCLib.makeID("materialmaps/block/alpha_emission.json");
|
||||
|
||||
@Inject(method = "getResource", at = @At("HEAD"), cancellable = true)
|
||||
private void bclib_getResource(ResourceLocation resourceLocation,
|
||||
CallbackInfoReturnable<Resource> info) throws IOException {
|
||||
if (!ModIntegrationAPI.hasCanvas()) {
|
||||
return;
|
||||
}
|
||||
if (!resourceLocation.getPath().startsWith("materialmaps")) {
|
||||
return;
|
||||
}
|
||||
if (!resourceLocation.getPath().contains("/block/")) {
|
||||
return;
|
||||
}
|
||||
|
||||
String name = resourceLocation.getPath().replace("materialmaps/block/", "").replace(".json", "");
|
||||
ResourceLocation blockID = new ResourceLocation(resourceLocation.getNamespace(), name);
|
||||
|
||||
if (!EmissiveTextureInfo.isEmissiveBlock(blockID)) {
|
||||
return;
|
||||
}
|
||||
|
||||
ResourceManager resourceManager = this.namespacedManagers.get(resourceLocation.getNamespace());
|
||||
if (resourceManager != null && resourceManager.getResource(resourceLocation).isEmpty()) {
|
||||
info.setReturnValue(resourceManager.getResource(bclib_alphaEmissionMaterial).get());
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,77 @@
|
|||
package org.betterx.bclib.mixin.client;
|
||||
|
||||
import net.minecraft.client.gui.screens.Screen;
|
||||
import net.minecraft.client.gui.screens.inventory.SignEditScreen;
|
||||
import net.minecraft.client.renderer.MultiBufferSource;
|
||||
import net.minecraft.client.renderer.blockentity.SignRenderer;
|
||||
import net.minecraft.network.chat.Component;
|
||||
import net.minecraft.world.level.block.Block;
|
||||
import net.minecraft.world.level.block.entity.SignBlockEntity;
|
||||
import net.minecraft.world.level.block.state.BlockState;
|
||||
|
||||
import com.mojang.blaze3d.vertex.PoseStack;
|
||||
import com.mojang.blaze3d.vertex.VertexConsumer;
|
||||
import org.betterx.bclib.blocks.BaseSignBlock;
|
||||
import org.betterx.bclib.client.render.BaseSignBlockEntityRenderer;
|
||||
import org.spongepowered.asm.mixin.Final;
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
import org.spongepowered.asm.mixin.Shadow;
|
||||
import org.spongepowered.asm.mixin.Unique;
|
||||
import org.spongepowered.asm.mixin.injection.At;
|
||||
import org.spongepowered.asm.mixin.injection.At.Shift;
|
||||
import org.spongepowered.asm.mixin.injection.Inject;
|
||||
import org.spongepowered.asm.mixin.injection.ModifyArg;
|
||||
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
|
||||
import org.spongepowered.asm.mixin.injection.callback.LocalCapture;
|
||||
|
||||
@Mixin(SignEditScreen.class)
|
||||
public abstract class SignEditScreenMixin extends Screen {
|
||||
@Shadow
|
||||
@Final
|
||||
private SignBlockEntity sign;
|
||||
@Shadow
|
||||
private SignRenderer.SignModel signModel;
|
||||
@Unique
|
||||
private boolean bclib_renderStick;
|
||||
@Unique
|
||||
private boolean bclib_isSign;
|
||||
|
||||
protected SignEditScreenMixin(Component component) {
|
||||
super(component);
|
||||
}
|
||||
|
||||
@Inject(method = "render(Lcom/mojang/blaze3d/vertex/PoseStack;IIF)V", at = @At(
|
||||
value = "INVOKE",
|
||||
target = "Lcom/mojang/blaze3d/vertex/PoseStack;pushPose()V",
|
||||
shift = Shift.BEFORE
|
||||
), locals = LocalCapture.CAPTURE_FAILSOFT)
|
||||
private void bclib_checkOffset(PoseStack poseStack,
|
||||
int i,
|
||||
int j,
|
||||
float f,
|
||||
CallbackInfo info,
|
||||
float g,
|
||||
BlockState blockState,
|
||||
boolean bl,
|
||||
boolean bl2,
|
||||
float h) {
|
||||
bclib_isSign = blockState.getBlock() instanceof BaseSignBlock;
|
||||
if (bclib_isSign) {
|
||||
bclib_renderStick = blockState.getValue(BaseSignBlock.FLOOR);
|
||||
if (bclib_renderStick) {
|
||||
poseStack.translate(0.0, 0.3125, 0.0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ModifyArg(method = "render(Lcom/mojang/blaze3d/vertex/PoseStack;IIF)V", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/model/geom/ModelPart;render(Lcom/mojang/blaze3d/vertex/PoseStack;Lcom/mojang/blaze3d/vertex/VertexConsumer;II)V"), index = 1)
|
||||
private VertexConsumer bclib_signRender(VertexConsumer consumer) {
|
||||
if (bclib_isSign) {
|
||||
signModel.stick.visible = bclib_renderStick;
|
||||
Block block = sign.getBlockState().getBlock();
|
||||
MultiBufferSource.BufferSource bufferSource = this.minecraft.renderBuffers().bufferSource();
|
||||
return BaseSignBlockEntityRenderer.getConsumer(bufferSource, block);
|
||||
}
|
||||
return consumer;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,111 @@
|
|||
package org.betterx.bclib.mixin.client;
|
||||
|
||||
import net.minecraft.client.renderer.texture.TextureAtlas;
|
||||
import net.minecraft.client.renderer.texture.TextureAtlasSprite;
|
||||
import net.minecraft.resources.ResourceLocation;
|
||||
import net.minecraft.server.packs.resources.Resource;
|
||||
import net.minecraft.server.packs.resources.ResourceManager;
|
||||
|
||||
import net.fabricmc.fabric.impl.client.texture.FabricSprite;
|
||||
import net.fabricmc.loader.api.FabricLoader;
|
||||
|
||||
import com.mojang.blaze3d.platform.NativeImage;
|
||||
import org.betterx.bclib.BCLib;
|
||||
import org.betterx.bclib.client.render.EmissiveTextureInfo;
|
||||
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 org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.Optional;
|
||||
|
||||
@Mixin(TextureAtlas.class)
|
||||
public class TextureAtlasMixin {
|
||||
private static final int EMISSIVE_ALPHA = 254 << 24;
|
||||
private boolean bclib_modifyAtlas;
|
||||
|
||||
@Inject(method = "<init>*", at = @At("TAIL"))
|
||||
private void bclib_onAtlasInit(ResourceLocation resourceLocation, CallbackInfo info) {
|
||||
boolean hasOptifine = FabricLoader.getInstance().isModLoaded("optifabric");
|
||||
bclib_modifyAtlas = !hasOptifine && resourceLocation.toString().equals("minecraft:textures/atlas/blocks.png");
|
||||
if (bclib_modifyAtlas) {
|
||||
EmissiveTextureInfo.clear();
|
||||
}
|
||||
}
|
||||
|
||||
@Inject(method = "load(Lnet/minecraft/server/packs/resources/ResourceManager;Lnet/minecraft/client/renderer/texture/TextureAtlasSprite$Info;IIIII)Lnet/minecraft/client/renderer/texture/TextureAtlasSprite;", at = @At("HEAD"), cancellable = true)
|
||||
private void bclib_loadSprite(ResourceManager resourceManager,
|
||||
TextureAtlasSprite.Info spriteInfo,
|
||||
int atlasWidth,
|
||||
int atlasHeight,
|
||||
int maxLevel,
|
||||
int posX,
|
||||
int posY,
|
||||
CallbackInfoReturnable<TextureAtlasSprite> info) {
|
||||
if (!bclib_modifyAtlas) {
|
||||
return;
|
||||
}
|
||||
|
||||
ResourceLocation location = spriteInfo.name();
|
||||
if (!location.getPath().startsWith("block")) {
|
||||
return;
|
||||
}
|
||||
|
||||
ResourceLocation emissiveLocation = new ResourceLocation(
|
||||
location.getNamespace(),
|
||||
"textures/" + location.getPath() + "_e.png"
|
||||
);
|
||||
Optional<Resource> emissiveRes = resourceManager.getResource(emissiveLocation);
|
||||
if (emissiveRes.isPresent()) {
|
||||
NativeImage sprite = null;
|
||||
NativeImage emission = null;
|
||||
try {
|
||||
ResourceLocation spriteLocation = new ResourceLocation(
|
||||
location.getNamespace(),
|
||||
"textures/" + location.getPath() + ".png"
|
||||
);
|
||||
Resource resource = resourceManager.getResource(spriteLocation).orElse(null);
|
||||
sprite = NativeImage.read(resource.open());
|
||||
|
||||
resource = emissiveRes.get();
|
||||
emission = NativeImage.read(resource.open());
|
||||
} catch (IOException e) {
|
||||
BCLib.LOGGER.warning(e.getMessage());
|
||||
}
|
||||
if (sprite != null && emission != null) {
|
||||
int width = Math.min(sprite.getWidth(), emission.getWidth());
|
||||
int height = Math.min(sprite.getHeight(), emission.getHeight());
|
||||
for (int x = 0; x < width; x++) {
|
||||
for (int y = 0; y < height; y++) {
|
||||
int argb = emission.getPixelRGBA(x, y);
|
||||
int alpha = (argb >> 24) & 255;
|
||||
if (alpha > 127) {
|
||||
int r = (argb >> 16) & 255;
|
||||
int g = (argb >> 8) & 255;
|
||||
int b = argb & 255;
|
||||
if (r > 0 || g > 0 || b > 0) {
|
||||
argb = (argb & 0x00FFFFFF) | EMISSIVE_ALPHA;
|
||||
sprite.setPixelRGBA(x, y, argb);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
TextureAtlas self = (TextureAtlas) (Object) this;
|
||||
FabricSprite result = new FabricSprite(
|
||||
self,
|
||||
spriteInfo,
|
||||
maxLevel,
|
||||
atlasWidth,
|
||||
atlasHeight,
|
||||
posX,
|
||||
posY,
|
||||
sprite
|
||||
);
|
||||
EmissiveTextureInfo.addTexture(location);
|
||||
info.setReturnValue(result);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,21 @@
|
|||
package org.betterx.bclib.mixin.common;
|
||||
|
||||
import net.minecraft.world.level.block.AnvilBlock;
|
||||
import net.minecraft.world.level.block.state.BlockState;
|
||||
|
||||
import org.betterx.bclib.blocks.BaseAnvilBlock;
|
||||
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;
|
||||
|
||||
@Mixin(AnvilBlock.class)
|
||||
public class AnvilBlockMixin {
|
||||
@Inject(method = "damage", at = @At("HEAD"), cancellable = true)
|
||||
private static void bclib_anvilDamage(BlockState state, CallbackInfoReturnable<BlockState> info) {
|
||||
if (state.getBlock() instanceof BaseAnvilBlock) {
|
||||
BaseAnvilBlock anvil = (BaseAnvilBlock) state.getBlock();
|
||||
info.setReturnValue(anvil.damageAnvilFall(state));
|
||||
}
|
||||
}
|
||||
}
|
208
src/main/java/org/betterx/bclib/mixin/common/AnvilMenuMixin.java
Normal file
208
src/main/java/org/betterx/bclib/mixin/common/AnvilMenuMixin.java
Normal file
|
@ -0,0 +1,208 @@
|
|||
package org.betterx.bclib.mixin.common;
|
||||
|
||||
import net.minecraft.tags.BlockTags;
|
||||
import net.minecraft.world.entity.player.Inventory;
|
||||
import net.minecraft.world.entity.player.Player;
|
||||
import net.minecraft.world.inventory.*;
|
||||
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.betterx.bclib.blocks.BaseAnvilBlock;
|
||||
import org.betterx.bclib.blocks.LeveledAnvilBlock;
|
||||
import org.betterx.bclib.interfaces.AnvilScreenHandlerExtended;
|
||||
import org.betterx.bclib.recipes.AnvilRecipe;
|
||||
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 org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.stream.Collectors;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
@Mixin(AnvilMenu.class)
|
||||
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;
|
||||
|
||||
@Final
|
||||
@Shadow
|
||||
private DataSlot cost;
|
||||
|
||||
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) {
|
||||
info.cancel();
|
||||
if (!player.getAbilities().instabuild) {
|
||||
player.giveExperienceLevels(-this.cost.get());
|
||||
}
|
||||
|
||||
this.inputSlots.setItem(0, ItemStack.EMPTY);
|
||||
if (this.repairItemCountCost > 0) {
|
||||
ItemStack itemStack2 = this.inputSlots.getItem(1);
|
||||
if (!itemStack2.isEmpty() && itemStack2.getCount() > this.repairItemCountCost) {
|
||||
itemStack2.shrink(this.repairItemCountCost);
|
||||
this.inputSlots.setItem(1, itemStack2);
|
||||
} else {
|
||||
this.inputSlots.setItem(1, ItemStack.EMPTY);
|
||||
}
|
||||
} else {
|
||||
this.inputSlots.setItem(1, ItemStack.EMPTY);
|
||||
}
|
||||
|
||||
this.cost.set(0);
|
||||
|
||||
if (!player.getAbilities().instabuild && blockState.is(BlockTags.ANVIL) && player.getRandom()
|
||||
.nextFloat() < 0.12F) {
|
||||
BaseAnvilBlock anvil = (BaseAnvilBlock) blockState.getBlock();
|
||||
BlockState damaged = anvil.damageAnvilUse(blockState, player.getRandom());
|
||||
if (damaged == null) {
|
||||
level.removeBlock(blockPos, false);
|
||||
level.levelEvent(1029, blockPos, 0);
|
||||
} else {
|
||||
level.setBlock(blockPos, damaged, 2);
|
||||
level.levelEvent(1030, blockPos, 0);
|
||||
}
|
||||
} else {
|
||||
level.levelEvent(1030, blockPos, 0);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@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,39 @@
|
|||
package org.betterx.bclib.mixin.common;
|
||||
|
||||
import net.minecraft.core.HolderSet;
|
||||
import net.minecraft.world.level.biome.BiomeGenerationSettings;
|
||||
import net.minecraft.world.level.levelgen.GenerationStep;
|
||||
import net.minecraft.world.level.levelgen.carver.ConfiguredWorldCarver;
|
||||
import net.minecraft.world.level.levelgen.feature.ConfiguredFeature;
|
||||
import net.minecraft.world.level.levelgen.placement.PlacedFeature;
|
||||
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
import org.spongepowered.asm.mixin.Mutable;
|
||||
import org.spongepowered.asm.mixin.gen.Accessor;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.function.Supplier;
|
||||
|
||||
@Mixin(BiomeGenerationSettings.class)
|
||||
public interface BiomeGenerationSettingsAccessor {
|
||||
@Accessor("features")
|
||||
List<HolderSet<PlacedFeature>> bclib_getFeatures();
|
||||
|
||||
@Accessor("features")
|
||||
@Mutable
|
||||
void bclib_setFeatures(List<HolderSet<PlacedFeature>> value);
|
||||
|
||||
@Accessor("featureSet")
|
||||
void bclib_setFeatureSet(Supplier<Set<PlacedFeature>> featureSet);
|
||||
|
||||
@Accessor("flowerFeatures")
|
||||
void bclib_setFlowerFeatures(Supplier<List<ConfiguredFeature<?, ?>>> flowerFeatures);
|
||||
|
||||
@Accessor("carvers")
|
||||
Map<GenerationStep.Carving, HolderSet<ConfiguredWorldCarver<?>>> bclib_getCarvers();
|
||||
|
||||
@Accessor("carvers")
|
||||
void bclib_setCarvers(Map<GenerationStep.Carving, HolderSet<ConfiguredWorldCarver<?>>> features);
|
||||
}
|
|
@ -0,0 +1,9 @@
|
|||
package org.betterx.bclib.mixin.common;
|
||||
|
||||
import net.minecraft.world.level.biome.Biome;
|
||||
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
|
||||
@Mixin(Biome.class)
|
||||
public class BiomeMixin {
|
||||
}
|
|
@ -0,0 +1,36 @@
|
|||
package org.betterx.bclib.mixin.common;
|
||||
|
||||
import net.minecraft.world.level.biome.Biome;
|
||||
import net.minecraft.world.level.biome.BiomeSource;
|
||||
import net.minecraft.world.level.biome.BiomeSource.StepFeatureData;
|
||||
|
||||
import com.google.common.base.Suppliers;
|
||||
import org.betterx.bclib.BCLib;
|
||||
import org.betterx.bclib.interfaces.BiomeSourceAccessor;
|
||||
import org.spongepowered.asm.mixin.Final;
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
import org.spongepowered.asm.mixin.Mutable;
|
||||
import org.spongepowered.asm.mixin.Shadow;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
import java.util.function.Supplier;
|
||||
|
||||
@Mixin(BiomeSource.class)
|
||||
public abstract class BiomeSourceMixin implements BiomeSourceAccessor {
|
||||
@Shadow
|
||||
protected abstract List<StepFeatureData> buildFeaturesPerStep(List<Biome> list, boolean bl);
|
||||
|
||||
@Shadow
|
||||
public abstract Set<Biome> possibleBiomes();
|
||||
|
||||
@Mutable
|
||||
@Shadow
|
||||
@Final
|
||||
private Supplier<List<StepFeatureData>> featuresPerStep;
|
||||
|
||||
public void bclRebuildFeatures() {
|
||||
BCLib.LOGGER.info("Rebuilding features in BiomeSource " + this);
|
||||
featuresPerStep = Suppliers.memoize(() -> buildFeaturesPerStep(this.possibleBiomes().stream().toList(), true));
|
||||
}
|
||||
}
|
|
@ -0,0 +1,23 @@
|
|||
package org.betterx.bclib.mixin.common;
|
||||
|
||||
import net.minecraft.world.level.block.Block;
|
||||
import net.minecraft.world.level.block.state.BlockBehaviour.BlockStateBase;
|
||||
|
||||
import org.betterx.bclib.util.MethodReplace;
|
||||
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 java.util.function.Function;
|
||||
|
||||
@Mixin(BlockStateBase.class)
|
||||
public class BlockStateBaseMixin {
|
||||
@Inject(method = "is(Lnet/minecraft/world/level/block/Block;)Z", at = @At("HEAD"), cancellable = true)
|
||||
private void bclib_replaceFunction(Block block, CallbackInfoReturnable<Boolean> info) {
|
||||
Function<BlockStateBase, Boolean> replacement = MethodReplace.getBlockReplace(block);
|
||||
if (replacement != null) {
|
||||
info.setReturnValue(replacement.apply(BlockStateBase.class.cast(this)));
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,163 @@
|
|||
package org.betterx.bclib.mixin.common;
|
||||
|
||||
import net.minecraft.core.BlockPos;
|
||||
import net.minecraft.core.BlockPos.MutableBlockPos;
|
||||
import net.minecraft.core.Vec3i;
|
||||
import net.minecraft.world.InteractionResult;
|
||||
import net.minecraft.world.item.BoneMealItem;
|
||||
import net.minecraft.world.item.context.UseOnContext;
|
||||
import net.minecraft.world.level.Level;
|
||||
import net.minecraft.world.level.block.Block;
|
||||
import net.minecraft.world.level.block.Blocks;
|
||||
import net.minecraft.world.level.block.state.BlockState;
|
||||
import net.minecraft.world.level.block.state.properties.Property;
|
||||
|
||||
import org.betterx.bclib.api.BonemealAPI;
|
||||
import org.betterx.bclib.api.biomes.BiomeAPI;
|
||||
import org.betterx.bclib.util.BlocksHelper;
|
||||
import org.betterx.bclib.util.MHelper;
|
||||
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;
|
||||
|
||||
@Mixin(BoneMealItem.class)
|
||||
public class BoneMealItemMixin {
|
||||
private static final MutableBlockPos bclib_BLOCK_POS = new MutableBlockPos();
|
||||
|
||||
@Inject(method = "useOn", at = @At("HEAD"), cancellable = true)
|
||||
private void bclib_onUse(UseOnContext context, CallbackInfoReturnable<InteractionResult> info) {
|
||||
Level world = context.getLevel();
|
||||
BlockPos blockPos = context.getClickedPos();
|
||||
if (!world.isClientSide) {
|
||||
BlockPos offseted = blockPos.relative(context.getClickedFace());
|
||||
if (BonemealAPI.isTerrain(world.getBlockState(blockPos).getBlock())) {
|
||||
boolean consume = false;
|
||||
if (BonemealAPI.isSpreadableTerrain(world.getBlockState(blockPos).getBlock())) {
|
||||
BlockState terrain = bclib_getSpreadable(world, blockPos);
|
||||
if (terrain != null) {
|
||||
BlocksHelper.setWithoutUpdate(world, blockPos, terrain);
|
||||
consume = true;
|
||||
}
|
||||
} else {
|
||||
BlockState stateAbove = world.getBlockState(blockPos.above());
|
||||
if (!stateAbove.getFluidState().isEmpty()) {
|
||||
if (stateAbove.is(Blocks.WATER)) {
|
||||
consume = bclib_growWaterGrass(world, blockPos);
|
||||
}
|
||||
} else if (stateAbove.isAir()) {
|
||||
consume = bclib_growLandGrass(world, blockPos);
|
||||
}
|
||||
}
|
||||
if (consume) {
|
||||
if (!context.getPlayer().isCreative()) {
|
||||
context.getItemInHand().shrink(1);
|
||||
}
|
||||
world.levelEvent(2005, blockPos, 0);
|
||||
info.setReturnValue(InteractionResult.SUCCESS);
|
||||
info.cancel();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private boolean bclib_growLandGrass(Level world, BlockPos pos) {
|
||||
int y1 = pos.getY() + 3;
|
||||
int y2 = pos.getY() - 3;
|
||||
boolean result = false;
|
||||
for (int i = 0; i < 64; i++) {
|
||||
int x = (int) (pos.getX() + world.random.nextGaussian() * 2);
|
||||
int z = (int) (pos.getZ() + world.random.nextGaussian() * 2);
|
||||
bclib_BLOCK_POS.setX(x);
|
||||
bclib_BLOCK_POS.setZ(z);
|
||||
for (int y = y1; y >= y2; y--) {
|
||||
bclib_BLOCK_POS.setY(y);
|
||||
BlockPos down = bclib_BLOCK_POS.below();
|
||||
if (world.isEmptyBlock(bclib_BLOCK_POS) && !world.isEmptyBlock(down)) {
|
||||
BlockState grass = bclib_getLandGrassState(world, down);
|
||||
if (grass != null) {
|
||||
BlocksHelper.setWithoutUpdate(world, bclib_BLOCK_POS, grass);
|
||||
result = true;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
private boolean bclib_growWaterGrass(Level world, BlockPos pos) {
|
||||
int y1 = pos.getY() + 3;
|
||||
int y2 = pos.getY() - 3;
|
||||
boolean result = false;
|
||||
for (int i = 0; i < 64; i++) {
|
||||
int x = (int) (pos.getX() + world.random.nextGaussian() * 2);
|
||||
int z = (int) (pos.getZ() + world.random.nextGaussian() * 2);
|
||||
bclib_BLOCK_POS.setX(x);
|
||||
bclib_BLOCK_POS.setZ(z);
|
||||
for (int y = y1; y >= y2; y--) {
|
||||
bclib_BLOCK_POS.setY(y);
|
||||
BlockPos down = bclib_BLOCK_POS.below();
|
||||
if (BlocksHelper.isFluid(world.getBlockState(bclib_BLOCK_POS)) && !BlocksHelper.isFluid(world.getBlockState(
|
||||
down))) {
|
||||
BlockState grass = bclib_getWaterGrassState(world, down);
|
||||
if (grass != null) {
|
||||
BlocksHelper.setWithoutUpdate(world, bclib_BLOCK_POS, grass);
|
||||
result = true;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
private BlockState bclib_getLandGrassState(Level world, BlockPos pos) {
|
||||
BlockState state = world.getBlockState(pos);
|
||||
Block block = state.getBlock();
|
||||
block = BonemealAPI.getLandGrass(BiomeAPI.getBiomeID(world.getBiome(pos)), block, world.getRandom());
|
||||
return block == null ? null : block.defaultBlockState();
|
||||
}
|
||||
|
||||
private BlockState bclib_getWaterGrassState(Level world, BlockPos pos) {
|
||||
BlockState state = world.getBlockState(pos);
|
||||
Block block = state.getBlock();
|
||||
block = BonemealAPI.getWaterGrass(BiomeAPI.getBiomeID(world.getBiome(pos)), block, world.getRandom());
|
||||
return block == null ? null : block.defaultBlockState();
|
||||
}
|
||||
|
||||
private BlockState bclib_getSpreadable(Level world, BlockPos pos) {
|
||||
Vec3i[] offsets = MHelper.getOffsets(world.getRandom());
|
||||
BlockState center = world.getBlockState(pos);
|
||||
for (Vec3i dir : offsets) {
|
||||
BlockPos p = pos.offset(dir);
|
||||
BlockState state = world.getBlockState(p);
|
||||
Block terrain = BonemealAPI.getSpreadable(state.getBlock());
|
||||
if (center.is(terrain)) {
|
||||
if (bclib_haveSameProperties(state, center)) {
|
||||
for (Property property : center.getProperties()) {
|
||||
state = state.setValue(property, center.getValue(property));
|
||||
}
|
||||
}
|
||||
return state;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private boolean bclib_haveSameProperties(BlockState state1, BlockState state2) {
|
||||
Property<?>[] properties1 = state1.getProperties().toArray(new Property[0]);
|
||||
Property<?>[] properties2 = state2.getProperties().toArray(new Property[0]);
|
||||
if (properties1.length != properties2.length) {
|
||||
return false;
|
||||
}
|
||||
for (int i = 0; i < properties1.length; i++) {
|
||||
String name1 = properties1[i].getName();
|
||||
String name2 = properties2[i].getName();
|
||||
if (!name1.equals(name2)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,42 @@
|
|||
package org.betterx.bclib.mixin.common;
|
||||
|
||||
import net.minecraft.core.Registry;
|
||||
import net.minecraft.world.level.StructureManager;
|
||||
import net.minecraft.world.level.WorldGenLevel;
|
||||
import net.minecraft.world.level.chunk.ChunkAccess;
|
||||
import net.minecraft.world.level.chunk.ChunkGenerator;
|
||||
import net.minecraft.world.level.levelgen.structure.StructureSet;
|
||||
|
||||
import org.betterx.bclib.interfaces.ChunkGeneratorAccessor;
|
||||
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.ModifyArg;
|
||||
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
|
||||
|
||||
@Mixin(ChunkGenerator.class)
|
||||
public class ChunkGeneratorMixin implements ChunkGeneratorAccessor {
|
||||
@Shadow
|
||||
@Final
|
||||
protected Registry<StructureSet> structureSets;
|
||||
private int bclib_featureIteratorSeed;
|
||||
|
||||
@ModifyArg(method = "applyBiomeDecoration", at = @At(value = "INVOKE", target = "Lnet/minecraft/world/level/levelgen/WorldgenRandom;setFeatureSeed(JII)V"))
|
||||
private long bclib_updateFeatureSeed(long seed) {
|
||||
return Long.rotateRight(seed, bclib_featureIteratorSeed++);
|
||||
}
|
||||
|
||||
@Inject(method = "applyBiomeDecoration", at = @At("HEAD"))
|
||||
private void bclib_obBiomeGenerate(WorldGenLevel worldGenLevel,
|
||||
ChunkAccess chunkAccess,
|
||||
StructureManager structureFeatureManager,
|
||||
CallbackInfo ci) {
|
||||
bclib_featureIteratorSeed = 0;
|
||||
}
|
||||
|
||||
public Registry<StructureSet> bclib_getStructureSetsRegistry() {
|
||||
return structureSets;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,15 @@
|
|||
package org.betterx.bclib.mixin.common;
|
||||
|
||||
import net.minecraft.world.level.ItemLike;
|
||||
import net.minecraft.world.level.block.ComposterBlock;
|
||||
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
import org.spongepowered.asm.mixin.gen.Invoker;
|
||||
|
||||
@Mixin(ComposterBlock.class)
|
||||
public interface ComposterBlockAccessor {
|
||||
@Invoker
|
||||
static void callAdd(float levelIncreaseChance, ItemLike item) {
|
||||
throw new AssertionError("@Invoker dummy body called");
|
||||
}
|
||||
}
|
|
@ -0,0 +1,32 @@
|
|||
package org.betterx.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.betterx.bclib.api.tag.CommonBlockTags;
|
||||
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;
|
||||
|
||||
@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(CommonBlockTags.WORKBENCHES);
|
||||
}, true)) {
|
||||
info.setReturnValue(true);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,16 @@
|
|||
package org.betterx.bclib.mixin.common;
|
||||
|
||||
import net.minecraft.tags.TagKey;
|
||||
import net.minecraft.world.item.DiggerItem;
|
||||
import net.minecraft.world.level.block.Block;
|
||||
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
import org.spongepowered.asm.mixin.Mutable;
|
||||
import org.spongepowered.asm.mixin.gen.Accessor;
|
||||
|
||||
@Mixin(DiggerItem.class)
|
||||
public interface DiggerItemAccessor {
|
||||
@Accessor("blocks")
|
||||
@Mutable
|
||||
TagKey<Block> bclib_getBlockTag();
|
||||
}
|
|
@ -0,0 +1,62 @@
|
|||
package org.betterx.bclib.mixin.common;
|
||||
|
||||
import net.minecraft.core.Registry;
|
||||
import net.minecraft.core.RegistryAccess;
|
||||
import net.minecraft.core.WritableRegistry;
|
||||
import net.minecraft.world.level.dimension.DimensionType;
|
||||
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
|
||||
|
||||
@Mixin(DimensionType.class)
|
||||
public class DimensionTypeMixin {
|
||||
// @Inject(
|
||||
// method = "defaultDimensions(Lnet/minecraft/core/RegistryAccess;JZ)Lnet/minecraft/core/Registry;",
|
||||
// locals = LocalCapture.CAPTURE_FAILHARD,
|
||||
// at = @At("TAIL")
|
||||
// )
|
||||
private static void bclib_updateDimensions(RegistryAccess registryAccess,
|
||||
long seed,
|
||||
boolean bl,
|
||||
CallbackInfoReturnable<Registry> info,
|
||||
WritableRegistry writableRegistry,
|
||||
Registry registry,
|
||||
Registry biomeRegistry,
|
||||
Registry structureRegistry,
|
||||
Registry noiseSettingsRegistry,
|
||||
Registry noiseParamRegistry) {
|
||||
//This probably moved to WorldPresets.bootstrap();
|
||||
// int id = writableRegistry.getId(writableRegistry.get(LevelStem.NETHER));
|
||||
// writableRegistry.registerOrOverride(
|
||||
// OptionalInt.of(id),
|
||||
// LevelStem.NETHER,
|
||||
// new LevelStem(
|
||||
// registry.getOrCreateHolder(BuiltinDimensionTypes.NETHER),
|
||||
// new NoiseBasedChunkGenerator(
|
||||
// structureRegistry,
|
||||
// noiseParamRegistry,
|
||||
// new BCLibNetherBiomeSource(biomeRegistry, seed),
|
||||
// seed,
|
||||
// noiseSettingsRegistry.getOrCreateHolder(NoiseGeneratorSettings.NETHER))
|
||||
// ),
|
||||
// Lifecycle.stable()
|
||||
// );
|
||||
//
|
||||
//
|
||||
// id = writableRegistry.getId(writableRegistry.get(LevelStem.END));
|
||||
// writableRegistry.registerOrOverride(
|
||||
// OptionalInt.of(id),
|
||||
// LevelStem.END,
|
||||
// new LevelStem(
|
||||
// registry.getOrCreateHolder(BuiltinDimensionTypes.END),
|
||||
// new NoiseBasedChunkGenerator(
|
||||
// structureRegistry,
|
||||
// noiseParamRegistry,
|
||||
// new BCLibEndBiomeSource(biomeRegistry, seed),
|
||||
// seed,
|
||||
// noiseSettingsRegistry.getOrCreateHolder(NoiseGeneratorSettings.END))
|
||||
// ),
|
||||
// Lifecycle.stable()
|
||||
// );
|
||||
}
|
||||
}
|
|
@ -0,0 +1,29 @@
|
|||
package org.betterx.bclib.mixin.common;
|
||||
|
||||
import net.minecraft.core.BlockPos;
|
||||
import net.minecraft.world.level.Level;
|
||||
import net.minecraft.world.level.block.Block;
|
||||
import net.minecraft.world.level.block.Blocks;
|
||||
import net.minecraft.world.level.block.EnchantmentTableBlock;
|
||||
|
||||
import org.betterx.bclib.api.tag.CommonBlockTags;
|
||||
import org.betterx.bclib.util.MethodReplace;
|
||||
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;
|
||||
|
||||
@Mixin(EnchantmentTableBlock.class)
|
||||
public abstract class EnchantingTableBlockMixin extends Block {
|
||||
public EnchantingTableBlockMixin(Properties settings) {
|
||||
super(settings);
|
||||
}
|
||||
|
||||
@Inject(method = "isValidBookShelf(Lnet/minecraft/world/level/Level;Lnet/minecraft/core/BlockPos;Lnet/minecraft/core/BlockPos;)Z", at = @At("HEAD"), cancellable = true)
|
||||
private static void bclib_isBookshelf(Level level,
|
||||
BlockPos blockPos,
|
||||
BlockPos blockPos2,
|
||||
CallbackInfoReturnable<Boolean> info) {
|
||||
MethodReplace.addBlockReplace(Blocks.BOOKSHELF, state -> state.is(CommonBlockTags.BOOKSHELVES));
|
||||
}
|
||||
}
|
|
@ -0,0 +1,23 @@
|
|||
package org.betterx.bclib.mixin.common;
|
||||
|
||||
import net.minecraft.world.item.Item;
|
||||
import net.minecraft.world.item.ItemStack;
|
||||
|
||||
import org.betterx.bclib.util.MethodReplace;
|
||||
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 java.util.function.Function;
|
||||
|
||||
@Mixin(ItemStack.class)
|
||||
public class ItemStackMixin {
|
||||
@Inject(method = "is(Lnet/minecraft/world/item/Item;)Z", at = @At("HEAD"), cancellable = true)
|
||||
private void bclib_replaceFunction(Item item, CallbackInfoReturnable<Boolean> info) {
|
||||
Function<ItemStack, Boolean> replacement = MethodReplace.getItemReplace(item);
|
||||
if (replacement != null) {
|
||||
info.setReturnValue(replacement.apply(ItemStack.class.cast(this)));
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,35 @@
|
|||
package org.betterx.bclib.mixin.common;
|
||||
|
||||
import net.minecraft.core.BlockPos;
|
||||
import net.minecraft.core.SectionPos;
|
||||
import net.minecraft.world.level.chunk.DataLayer;
|
||||
import net.minecraft.world.level.lighting.LayerLightSectionStorage;
|
||||
|
||||
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;
|
||||
|
||||
@Mixin(LayerLightSectionStorage.class)
|
||||
public class LayerLightSectionStorageMixin {
|
||||
@Shadow
|
||||
protected DataLayer getDataLayer(long sectionPos, boolean cached) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Inject(method = "getStoredLevel", at = @At(value = "HEAD"), cancellable = true)
|
||||
private void bclib_lightFix(long blockPos, CallbackInfoReturnable<Integer> info) {
|
||||
try {
|
||||
long pos = SectionPos.blockToSection(blockPos);
|
||||
DataLayer dataLayer = this.getDataLayer(pos, true);
|
||||
info.setReturnValue(dataLayer.get(
|
||||
SectionPos.sectionRelative(BlockPos.getX(blockPos)),
|
||||
SectionPos.sectionRelative(BlockPos.getY(blockPos)),
|
||||
SectionPos.sectionRelative(BlockPos.getZ(blockPos))
|
||||
));
|
||||
} catch (Exception e) {
|
||||
info.setReturnValue(0);
|
||||
}
|
||||
}
|
||||
}
|
61
src/main/java/org/betterx/bclib/mixin/common/MainMixin.java
Normal file
61
src/main/java/org/betterx/bclib/mixin/common/MainMixin.java
Normal file
|
@ -0,0 +1,61 @@
|
|||
package org.betterx.bclib.mixin.common;
|
||||
|
||||
import net.minecraft.server.Main;
|
||||
import net.minecraft.server.dedicated.DedicatedServerSettings;
|
||||
import net.minecraft.world.level.storage.LevelStorageSource;
|
||||
|
||||
import joptsimple.ArgumentAcceptingOptionSpec;
|
||||
import joptsimple.OptionParser;
|
||||
import joptsimple.OptionSet;
|
||||
import org.betterx.bclib.api.LifeCycleAPI;
|
||||
import org.betterx.bclib.api.datafixer.DataFixerAPI;
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
import org.spongepowered.asm.mixin.injection.At;
|
||||
import org.spongepowered.asm.mixin.injection.Inject;
|
||||
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
|
||||
|
||||
import java.io.File;
|
||||
import java.nio.file.Path;
|
||||
import java.nio.file.Paths;
|
||||
import java.util.Optional;
|
||||
|
||||
@Mixin(Main.class)
|
||||
abstract public class MainMixin {
|
||||
@Inject(method = "main", at = @At(value = "INVOKE", target = "Lnet/minecraft/world/level/storage/LevelStorageSource;createDefault(Ljava/nio/file/Path;)Lnet/minecraft/world/level/storage/LevelStorageSource;"))
|
||||
private static void bclib_callServerFix(String[] args, CallbackInfo ci) {
|
||||
OptionParser parser = new OptionParser();
|
||||
ArgumentAcceptingOptionSpec<String> optionUniverse = parser.accepts("universe")
|
||||
.withRequiredArg()
|
||||
.defaultsTo(".", new String[0]);
|
||||
ArgumentAcceptingOptionSpec<String> optionWorld = parser.accepts("world").withRequiredArg();
|
||||
|
||||
//this is only for compat reasons, we do not need to read thise options in our mixin, but it seems to cause
|
||||
//errors if they are not defined
|
||||
parser.accepts("nogui");
|
||||
parser.accepts("initSettings", "Initializes 'server.properties' and 'eula.txt', then quits");
|
||||
parser.accepts("demo");
|
||||
parser.accepts("bonusChest");
|
||||
parser.accepts("forceUpgrade");
|
||||
parser.accepts("eraseCache");
|
||||
parser.accepts("safeMode", "Loads level with vanilla datapack only");
|
||||
parser.accepts("help").forHelp();
|
||||
parser.accepts("singleplayer").withRequiredArg();
|
||||
parser.accepts("port").withRequiredArg().ofType(Integer.class).defaultsTo(-1, new Integer[0]);
|
||||
parser.accepts("serverId").withRequiredArg();
|
||||
parser.accepts("jfrProfile");
|
||||
parser.nonOptions();
|
||||
|
||||
OptionSet options = parser.parse(args);
|
||||
|
||||
Path settingPath = Paths.get("server.properties");
|
||||
DedicatedServerSettings settings = new DedicatedServerSettings(settingPath);
|
||||
|
||||
File file = new File(options.valueOf(optionUniverse));
|
||||
String levelID = Optional.ofNullable(options.valueOf(optionWorld)).orElse(settings.getProperties().levelName);
|
||||
|
||||
LevelStorageSource levelStorageSource = LevelStorageSource.createDefault(file.toPath());
|
||||
DataFixerAPI.fixData(levelStorageSource, levelID, false, (didFix) -> {/* not called when showUI==false */});
|
||||
|
||||
LifeCycleAPI._runBeforeLevelLoad();
|
||||
}
|
||||
}
|
|
@ -0,0 +1,82 @@
|
|||
package org.betterx.bclib.mixin.common;
|
||||
|
||||
import net.minecraft.resources.ResourceKey;
|
||||
import net.minecraft.server.MinecraftServer;
|
||||
import net.minecraft.server.WorldStem;
|
||||
import net.minecraft.server.level.ServerLevel;
|
||||
import net.minecraft.server.level.progress.ChunkProgressListener;
|
||||
import net.minecraft.server.level.progress.ChunkProgressListenerFactory;
|
||||
import net.minecraft.server.packs.repository.PackRepository;
|
||||
import net.minecraft.server.players.GameProfileCache;
|
||||
import net.minecraft.world.level.Level;
|
||||
import net.minecraft.world.level.storage.LevelStorageSource.LevelStorageAccess;
|
||||
import net.minecraft.world.level.storage.WorldData;
|
||||
|
||||
import com.mojang.authlib.GameProfileRepository;
|
||||
import com.mojang.authlib.minecraft.MinecraftSessionService;
|
||||
import com.mojang.datafixers.DataFixer;
|
||||
import org.betterx.bclib.api.dataexchange.DataExchangeAPI;
|
||||
import org.betterx.bclib.recipes.BCLRecipeManager;
|
||||
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 org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
|
||||
|
||||
import java.net.Proxy;
|
||||
import java.util.Collection;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
|
||||
@Mixin(MinecraftServer.class)
|
||||
public class MinecraftServerMixin {
|
||||
@Shadow
|
||||
private MinecraftServer.ReloadableResources resources;
|
||||
|
||||
@Final
|
||||
@Shadow
|
||||
private Map<ResourceKey<Level>, ServerLevel> levels;
|
||||
|
||||
@Final
|
||||
@Shadow
|
||||
protected WorldData worldData;
|
||||
|
||||
@Inject(method = "<init>*", at = @At("TAIL"))
|
||||
private void bclib_onServerInit(Thread thread,
|
||||
LevelStorageAccess levelStorageAccess,
|
||||
PackRepository packRepository,
|
||||
WorldStem worldStem,
|
||||
Proxy proxy,
|
||||
DataFixer dataFixer,
|
||||
MinecraftSessionService minecraftSessionService,
|
||||
GameProfileRepository gameProfileRepository,
|
||||
GameProfileCache gameProfileCache,
|
||||
ChunkProgressListenerFactory chunkProgressListenerFactory,
|
||||
CallbackInfo ci) {
|
||||
DataExchangeAPI.prepareServerside();
|
||||
}
|
||||
|
||||
@Inject(method = "reloadResources", at = @At(value = "RETURN"), cancellable = true)
|
||||
private void bclib_reloadResources(Collection<String> collection,
|
||||
CallbackInfoReturnable<CompletableFuture<Void>> info) {
|
||||
bclib_injectRecipes();
|
||||
}
|
||||
|
||||
@Inject(method = "loadLevel", at = @At(value = "RETURN"), cancellable = true)
|
||||
private void bclib_loadLevel(CallbackInfo info) {
|
||||
bclib_injectRecipes();
|
||||
}
|
||||
|
||||
private void bclib_injectRecipes() {
|
||||
RecipeManagerAccessor accessor = (RecipeManagerAccessor) resources.managers().getRecipeManager();
|
||||
accessor.bclib_setRecipesByName(BCLRecipeManager.getMapByName(accessor.bclib_getRecipesByName()));
|
||||
accessor.bclib_setRecipes(BCLRecipeManager.getMap(accessor.bclib_getRecipes()));
|
||||
}
|
||||
|
||||
@Inject(method = "createLevels", at = @At(value = "HEAD"))
|
||||
private void bcl_createLevel(ChunkProgressListener chunkProgressListener, CallbackInfo ci) {
|
||||
System.out.println(this.worldData);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,22 @@
|
|||
package org.betterx.bclib.mixin.common;
|
||||
|
||||
import net.minecraft.util.random.WeightedRandomList;
|
||||
import net.minecraft.world.entity.MobCategory;
|
||||
import net.minecraft.world.level.biome.MobSpawnSettings;
|
||||
import net.minecraft.world.level.biome.MobSpawnSettings.SpawnerData;
|
||||
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
import org.spongepowered.asm.mixin.Mutable;
|
||||
import org.spongepowered.asm.mixin.gen.Accessor;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
@Mixin(MobSpawnSettings.class)
|
||||
public interface MobSpawnSettingsAccessor {
|
||||
@Accessor("spawners")
|
||||
Map<MobCategory, WeightedRandomList<SpawnerData>> bcl_getSpawners();
|
||||
|
||||
@Accessor("spawners")
|
||||
@Mutable
|
||||
void bcl_setSpawners(Map<MobCategory, WeightedRandomList<SpawnerData>> spawners);
|
||||
}
|
|
@ -0,0 +1,35 @@
|
|||
package org.betterx.bclib.mixin.common;
|
||||
|
||||
import net.minecraft.resources.ResourceLocation;
|
||||
import net.minecraft.server.packs.resources.MultiPackResourceManager;
|
||||
import net.minecraft.server.packs.resources.Resource;
|
||||
|
||||
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 java.util.Optional;
|
||||
|
||||
@Mixin(MultiPackResourceManager.class)
|
||||
public class MultiPackResourceManagerMixin {
|
||||
private static final String[] BCLIB_MISSING_RESOURCES = new String[]{
|
||||
"dimension/the_end.json",
|
||||
"dimension/the_nether.json",
|
||||
"dimension_type/the_end.json",
|
||||
"dimension_type/the_nether.json"
|
||||
};
|
||||
|
||||
@Inject(method = "getResource", at = @At("HEAD"), cancellable = true)
|
||||
private void bclib_hasResource(ResourceLocation resourceLocation, CallbackInfoReturnable<Optional<Resource>> info) {
|
||||
if (resourceLocation.getNamespace().equals("minecraft")) {
|
||||
for (String key : BCLIB_MISSING_RESOURCES) {
|
||||
if (resourceLocation.getPath().equals(key)) {
|
||||
info.setReturnValue(Optional.empty());
|
||||
info.cancel();
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,23 @@
|
|||
package org.betterx.bclib.mixin.common;
|
||||
|
||||
import net.minecraft.resources.ResourceKey;
|
||||
import net.minecraft.world.level.biome.Biome;
|
||||
import net.minecraft.world.level.biome.Climate;
|
||||
|
||||
import net.fabricmc.fabric.impl.biome.NetherBiomeData;
|
||||
|
||||
import org.betterx.bclib.world.biomes.FabricBiomesData;
|
||||
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(value = NetherBiomeData.class, remap = false)
|
||||
public class NetherBiomeDataMixin {
|
||||
@Inject(method = "addNetherBiome", at = @At(value = "HEAD"))
|
||||
private static void bclib_addNetherBiome(ResourceKey<Biome> biome,
|
||||
Climate.ParameterPoint spawnNoisePoint,
|
||||
CallbackInfo info) {
|
||||
FabricBiomesData.NETHER_BIOMES.add(biome);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,70 @@
|
|||
package org.betterx.bclib.mixin.common;
|
||||
|
||||
import net.minecraft.core.BlockPos;
|
||||
import net.minecraft.core.Holder;
|
||||
import net.minecraft.server.level.ServerLevel;
|
||||
import net.minecraft.world.level.StructureManager;
|
||||
import net.minecraft.world.level.biome.Biome;
|
||||
import net.minecraft.world.level.block.Blocks;
|
||||
import net.minecraft.world.level.block.state.BlockState;
|
||||
import net.minecraft.world.level.chunk.ChunkAccess;
|
||||
import net.minecraft.world.level.levelgen.*;
|
||||
import net.minecraft.world.level.levelgen.blending.Blender;
|
||||
import net.minecraft.world.level.levelgen.carver.CarvingContext;
|
||||
|
||||
import org.betterx.bclib.interfaces.NoiseGeneratorSettingsProvider;
|
||||
import org.betterx.bclib.interfaces.SurfaceProvider;
|
||||
import org.spongepowered.asm.mixin.Final;
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
import org.spongepowered.asm.mixin.Shadow;
|
||||
|
||||
import java.lang.reflect.Constructor;
|
||||
import java.util.Optional;
|
||||
|
||||
@Mixin(NoiseBasedChunkGenerator.class)
|
||||
public abstract class NoiseBasedChunkGeneratorMixin implements SurfaceProvider, NoiseGeneratorSettingsProvider {
|
||||
@Final
|
||||
@Shadow
|
||||
protected Holder<NoiseGeneratorSettings> settings;
|
||||
|
||||
@Final
|
||||
@Shadow
|
||||
private Aquifer.FluidPicker globalFluidPicker;
|
||||
|
||||
private static final BlockState bclib_air = Blocks.AIR.defaultBlockState();
|
||||
private static Constructor<?> bclib_constructor;
|
||||
|
||||
@Override
|
||||
public NoiseGeneratorSettings bclib_getNoiseGeneratorSettings() {
|
||||
return settings.value();
|
||||
}
|
||||
|
||||
@Shadow
|
||||
protected abstract NoiseChunk createNoiseChunk(ChunkAccess chunkAccess,
|
||||
StructureManager structureManager,
|
||||
Blender blender,
|
||||
RandomState randomState);
|
||||
|
||||
@Override
|
||||
@SuppressWarnings("deprecation")
|
||||
public BlockState bclib_getSurface(BlockPos pos, Holder<Biome> biome, ServerLevel level) {
|
||||
ChunkAccess chunkAccess = level.getChunk(pos.getX() >> 4, pos.getZ() >> 4);
|
||||
StructureManager structureManager = level.structureManager();
|
||||
NoiseBasedChunkGenerator generator = NoiseBasedChunkGenerator.class.cast(this);
|
||||
RandomState randomState = level.getChunkSource().randomState();
|
||||
|
||||
NoiseChunk noiseChunk = chunkAccess.getOrCreateNoiseChunk(ca -> this.createNoiseChunk(ca,
|
||||
structureManager,
|
||||
Blender.empty(),
|
||||
randomState));
|
||||
|
||||
CarvingContext carvingContext = new CarvingContext(generator,
|
||||
level.registryAccess(),
|
||||
chunkAccess.getHeightAccessorForGeneration(),
|
||||
noiseChunk,
|
||||
randomState,
|
||||
this.settings.value().surfaceRule());
|
||||
Optional<BlockState> optional = carvingContext.topMaterial(bpos -> biome, chunkAccess, pos, false);
|
||||
return optional.isPresent() ? optional.get() : bclib_air;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,92 @@
|
|||
package org.betterx.bclib.mixin.common;
|
||||
|
||||
import net.minecraft.world.level.biome.BiomeSource;
|
||||
import net.minecraft.world.level.levelgen.NoiseGeneratorSettings;
|
||||
import net.minecraft.world.level.levelgen.SurfaceRules;
|
||||
import net.minecraft.world.level.levelgen.SurfaceRules.RuleSource;
|
||||
|
||||
import org.betterx.bclib.api.biomes.BiomeAPI;
|
||||
import org.betterx.bclib.interfaces.SurfaceRuleProvider;
|
||||
import org.spongepowered.asm.mixin.Final;
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
import org.spongepowered.asm.mixin.Mutable;
|
||||
import org.spongepowered.asm.mixin.Shadow;
|
||||
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
@Mixin(NoiseGeneratorSettings.class)
|
||||
public class NoiseGeneratorSettingsMixin implements SurfaceRuleProvider {
|
||||
@Mutable
|
||||
@Final
|
||||
@Shadow
|
||||
private SurfaceRules.RuleSource surfaceRule;
|
||||
|
||||
private SurfaceRules.RuleSource bclib_originalSurfaceRule;
|
||||
private final Set<BiomeSource> bclib_biomeSources = new HashSet<>();
|
||||
|
||||
private void bclib_updateCustomRules() {
|
||||
bclib_setCustomRules(BiomeAPI.getRuleSources(bclib_biomeSources));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void bclib_addBiomeSource(BiomeSource source) {
|
||||
bclib_biomeSources.add(source);
|
||||
bclib_updateCustomRules();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void bclib_clearBiomeSources() {
|
||||
bclib_biomeSources.clear();
|
||||
bclib_clearCustomRules();
|
||||
}
|
||||
|
||||
private void bclib_clearCustomRules() {
|
||||
if (bclib_originalSurfaceRule != null) {
|
||||
this.surfaceRule = bclib_originalSurfaceRule;
|
||||
bclib_originalSurfaceRule = null;
|
||||
}
|
||||
}
|
||||
|
||||
private void bclib_setCustomRules(List<RuleSource> rules) {
|
||||
if (rules.size() == 0) {
|
||||
bclib_clearCustomRules();
|
||||
return;
|
||||
}
|
||||
|
||||
RuleSource org = bclib_getOriginalSurfaceRule();
|
||||
if (org instanceof SurfaceRules.SequenceRuleSource sequenceRule) {
|
||||
List<RuleSource> currentSequence = sequenceRule.sequence();
|
||||
rules = rules.stream().filter(r -> currentSequence.indexOf(r) < 0).collect(Collectors.toList());
|
||||
rules.addAll(sequenceRule.sequence());
|
||||
} else {
|
||||
rules.add(org);
|
||||
}
|
||||
|
||||
bclib_setSurfaceRule(SurfaceRules.sequence(rules.toArray(new RuleSource[rules.size()])));
|
||||
}
|
||||
|
||||
void bclib_setSurfaceRule(SurfaceRules.RuleSource surfaceRule) {
|
||||
if (bclib_originalSurfaceRule == null) {
|
||||
bclib_originalSurfaceRule = this.surfaceRule;
|
||||
}
|
||||
this.surfaceRule = surfaceRule;
|
||||
}
|
||||
|
||||
RuleSource bclib_getOriginalSurfaceRule() {
|
||||
if (bclib_originalSurfaceRule == null) {
|
||||
return surfaceRule;
|
||||
}
|
||||
|
||||
return bclib_originalSurfaceRule;
|
||||
}
|
||||
|
||||
// @Inject(method = "surfaceRule", at = @At("HEAD"), cancellable = true)
|
||||
// private void bclib_surfaceRule(CallbackInfoReturnable<SurfaceRules.RuleSource> info) {
|
||||
// if (bclib_surfaceRule != null) {
|
||||
// info.setReturnValue(bclib_surfaceRule);
|
||||
// }
|
||||
// }
|
||||
}
|
|
@ -0,0 +1,30 @@
|
|||
package org.betterx.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.betterx.bclib.api.tag.CommonBlockTags;
|
||||
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;
|
||||
|
||||
@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(CommonBlockTags.IMMOBILE)) {
|
||||
cir.setReturnValue(false);
|
||||
cir.cancel();
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,43 @@
|
|||
package org.betterx.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.betterx.bclib.api.tag.CommonBlockTags;
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
import org.spongepowered.asm.mixin.injection.At;
|
||||
import org.spongepowered.asm.mixin.injection.Redirect;
|
||||
|
||||
@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(CommonBlockTags.NETHER_PORTAL_FRAME) || FRAME.test(state, getter, pos);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,16 @@
|
|||
package org.betterx.bclib.mixin.common;
|
||||
|
||||
import net.minecraft.world.item.Item;
|
||||
import net.minecraft.world.item.alchemy.Potion;
|
||||
import net.minecraft.world.item.alchemy.PotionBrewing;
|
||||
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
import org.spongepowered.asm.mixin.gen.Invoker;
|
||||
|
||||
@Mixin(PotionBrewing.class)
|
||||
public interface PotionBrewingAccessor {
|
||||
@Invoker
|
||||
static void callAddMix(Potion input, Item item, Potion output) {
|
||||
throw new AssertionError("@Invoker dummy body called");
|
||||
}
|
||||
}
|
|
@ -0,0 +1,26 @@
|
|||
package org.betterx.bclib.mixin.common;
|
||||
|
||||
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;
|
||||
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
import org.spongepowered.asm.mixin.gen.Accessor;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
@Mixin(RecipeManager.class)
|
||||
public interface RecipeManagerAccessor {
|
||||
@Accessor("recipes")
|
||||
Map<RecipeType<?>, Map<ResourceLocation, Recipe<?>>> bclib_getRecipes();
|
||||
|
||||
@Accessor("recipes")
|
||||
void bclib_setRecipes(Map<RecipeType<?>, Map<ResourceLocation, Recipe<?>>> recipes);
|
||||
|
||||
@Accessor("byName")
|
||||
Map<ResourceLocation, Recipe<?>> bclib_getRecipesByName();
|
||||
|
||||
@Accessor("byName")
|
||||
void bclib_setRecipesByName(Map<ResourceLocation, Recipe<?>> recipes);
|
||||
}
|
|
@ -0,0 +1,34 @@
|
|||
package org.betterx.bclib.mixin.common;
|
||||
|
||||
import net.minecraft.resources.ResourceLocation;
|
||||
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 org.betterx.bclib.recipes.BCLRecipeManager;
|
||||
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 java.util.Map;
|
||||
import java.util.Optional;
|
||||
|
||||
@Mixin(RecipeManager.class)
|
||||
public abstract class RecipeManagerMixin {
|
||||
@Shadow
|
||||
private <C extends Container, T extends Recipe<C>> Map<ResourceLocation, Recipe<C>> byType(RecipeType<T> type) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Inject(method = "getRecipeFor", at = @At(value = "HEAD"), cancellable = true)
|
||||
private <C extends Container, T extends Recipe<C>> void bclib_getRecipeFor(RecipeType<T> type,
|
||||
C inventory,
|
||||
Level level,
|
||||
CallbackInfoReturnable<Optional<T>> info) {
|
||||
info.setReturnValue(BCLRecipeManager.getSortedRecipe(type, inventory, level, this::byType));
|
||||
}
|
||||
}
|
|
@ -0,0 +1,86 @@
|
|||
package org.betterx.bclib.mixin.common;
|
||||
|
||||
import net.minecraft.core.Holder;
|
||||
import net.minecraft.resources.ResourceKey;
|
||||
import net.minecraft.server.MinecraftServer;
|
||||
import net.minecraft.server.level.ServerLevel;
|
||||
import net.minecraft.server.level.progress.ChunkProgressListener;
|
||||
import net.minecraft.util.profiling.ProfilerFiller;
|
||||
import net.minecraft.world.level.Level;
|
||||
import net.minecraft.world.level.dimension.DimensionType;
|
||||
import net.minecraft.world.level.dimension.LevelStem;
|
||||
import net.minecraft.world.level.storage.LevelStorageSource.LevelStorageAccess;
|
||||
import net.minecraft.world.level.storage.ServerLevelData;
|
||||
import net.minecraft.world.level.storage.WritableLevelData;
|
||||
|
||||
import org.betterx.bclib.api.LifeCycleAPI;
|
||||
import org.betterx.bclib.api.biomes.BiomeAPI;
|
||||
import org.betterx.bclib.world.generator.BCLBiomeSource;
|
||||
import org.betterx.bclib.world.generator.BCLibNetherBiomeSource;
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
import org.spongepowered.asm.mixin.injection.At;
|
||||
import org.spongepowered.asm.mixin.injection.Inject;
|
||||
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.concurrent.Executor;
|
||||
import java.util.function.Supplier;
|
||||
|
||||
@Mixin(ServerLevel.class)
|
||||
public abstract class ServerLevelMixin extends Level {
|
||||
private static String bclib_lastWorld = null;
|
||||
|
||||
protected ServerLevelMixin(WritableLevelData writableLevelData,
|
||||
ResourceKey<Level> resourceKey,
|
||||
Holder<DimensionType> holder,
|
||||
Supplier<ProfilerFiller> supplier,
|
||||
boolean bl,
|
||||
boolean bl2,
|
||||
long l,
|
||||
int i) {
|
||||
super(writableLevelData, resourceKey, holder, supplier, bl, bl2, l, i);
|
||||
}
|
||||
|
||||
|
||||
@Inject(method = "<init>*", at = @At("TAIL"))
|
||||
private void bclib_onServerWorldInit(MinecraftServer server,
|
||||
Executor executor,
|
||||
LevelStorageAccess levelStorageAccess,
|
||||
ServerLevelData serverLevelData,
|
||||
ResourceKey resourceKey,
|
||||
LevelStem levelStem,
|
||||
ChunkProgressListener chunkProgressListener,
|
||||
boolean bl,
|
||||
long l,
|
||||
List list,
|
||||
boolean bl2,
|
||||
CallbackInfo ci) {
|
||||
ServerLevel level = ServerLevel.class.cast(this);
|
||||
LifeCycleAPI._runLevelLoad(level,
|
||||
server,
|
||||
executor,
|
||||
levelStorageAccess,
|
||||
serverLevelData,
|
||||
resourceKey,
|
||||
chunkProgressListener,
|
||||
bl,
|
||||
l,
|
||||
list,
|
||||
bl2);
|
||||
|
||||
BiomeAPI.applyModifications(ServerLevel.class.cast(this));
|
||||
|
||||
if (level.dimension() == Level.NETHER) {
|
||||
BCLibNetherBiomeSource.setWorldHeight(level.getChunkSource().getGenerator().getGenDepth());
|
||||
}
|
||||
if (levelStem.generator().getBiomeSource() instanceof BCLBiomeSource source) {
|
||||
source.setSeed(level.getSeed());
|
||||
}
|
||||
|
||||
if (bclib_lastWorld != null && bclib_lastWorld.equals(levelStorageAccess.getLevelId())) {
|
||||
return;
|
||||
}
|
||||
|
||||
bclib_lastWorld = levelStorageAccess.getLevelId();
|
||||
}
|
||||
}
|
|
@ -0,0 +1,18 @@
|
|||
package org.betterx.bclib.mixin.common;
|
||||
|
||||
import net.minecraft.world.item.ShovelItem;
|
||||
import net.minecraft.world.level.block.Block;
|
||||
import net.minecraft.world.level.block.state.BlockState;
|
||||
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
import org.spongepowered.asm.mixin.gen.Accessor;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
@Mixin(ShovelItem.class)
|
||||
public interface ShovelItemAccessor {
|
||||
@Accessor("FLATTENABLES")
|
||||
static Map<Block, BlockState> bclib_getFlattenables() {
|
||||
throw new AssertionError("@Accessor dummy body called");
|
||||
}
|
||||
}
|
|
@ -0,0 +1,17 @@
|
|||
package org.betterx.bclib.mixin.common;
|
||||
|
||||
import net.minecraft.core.Holder;
|
||||
import net.minecraft.data.worldgen.Structures;
|
||||
import net.minecraft.resources.ResourceKey;
|
||||
import net.minecraft.world.level.levelgen.structure.Structure;
|
||||
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
import org.spongepowered.asm.mixin.gen.Invoker;
|
||||
|
||||
@Mixin(Structures.class)
|
||||
public interface StructuresAccessor {
|
||||
@Invoker
|
||||
static Holder<Structure> callRegister(ResourceKey<Structure> resourceKey, Structure structure) {
|
||||
throw new RuntimeException("Unexpected call");
|
||||
}
|
||||
}
|
|
@ -0,0 +1,48 @@
|
|||
package org.betterx.bclib.mixin.common;
|
||||
|
||||
import net.minecraft.core.Holder;
|
||||
import net.minecraft.world.level.biome.Biome;
|
||||
import net.minecraft.world.level.chunk.ChunkAccess;
|
||||
import net.minecraft.world.level.levelgen.NoiseChunk;
|
||||
import net.minecraft.world.level.levelgen.SurfaceRules;
|
||||
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
import org.spongepowered.asm.mixin.gen.Accessor;
|
||||
|
||||
import java.util.function.Supplier;
|
||||
|
||||
@Mixin(SurfaceRules.Context.class)
|
||||
public interface SurfaceRulesContextAccessor {
|
||||
@Accessor("blockX")
|
||||
int getBlockX();
|
||||
|
||||
@Accessor("blockY")
|
||||
int getBlockY();
|
||||
|
||||
@Accessor("blockZ")
|
||||
int getBlockZ();
|
||||
|
||||
@Accessor("surfaceDepth")
|
||||
int getSurfaceDepth();
|
||||
|
||||
@Accessor("biome")
|
||||
Supplier<Holder<Biome>> getBiome();
|
||||
|
||||
@Accessor("chunk")
|
||||
ChunkAccess getChunk();
|
||||
|
||||
@Accessor("noiseChunk")
|
||||
NoiseChunk getNoiseChunk();
|
||||
|
||||
@Accessor("stoneDepthAbove")
|
||||
int getStoneDepthAbove();
|
||||
|
||||
@Accessor("stoneDepthBelow")
|
||||
int getStoneDepthBelow();
|
||||
|
||||
@Accessor("lastUpdateY")
|
||||
long getLastUpdateY();
|
||||
|
||||
@Accessor("lastUpdateXZ")
|
||||
long getLastUpdateXZ();
|
||||
}
|
|
@ -0,0 +1,26 @@
|
|||
package org.betterx.bclib.mixin.common;
|
||||
|
||||
import net.minecraft.resources.ResourceLocation;
|
||||
import net.minecraft.tags.Tag;
|
||||
import net.minecraft.tags.TagLoader;
|
||||
|
||||
import org.betterx.bclib.api.tag.TagAPI;
|
||||
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.ModifyArg;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
@Mixin(TagLoader.class)
|
||||
public class TagLoaderMixin {
|
||||
@Final
|
||||
@Shadow
|
||||
private String directory;
|
||||
|
||||
@ModifyArg(method = "loadAndBuild", at = @At(value = "INVOKE", target = "Lnet/minecraft/tags/TagLoader;build(Ljava/util/Map;)Ljava/util/Map;"))
|
||||
public Map<ResourceLocation, Tag.Builder> be_modifyTags(Map<ResourceLocation, Tag.Builder> tagsMap) {
|
||||
return TagAPI.apply(directory, tagsMap);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,45 @@
|
|||
package org.betterx.bclib.mixin.common;
|
||||
|
||||
import net.minecraft.resources.ResourceKey;
|
||||
import net.minecraft.world.level.biome.Biome;
|
||||
import net.minecraft.world.level.biome.Biomes;
|
||||
|
||||
import net.fabricmc.fabric.impl.biome.TheEndBiomeData;
|
||||
|
||||
import org.betterx.bclib.world.biomes.FabricBiomesData;
|
||||
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(value = TheEndBiomeData.class, remap = false)
|
||||
public class TheEndBiomeDataMixin {
|
||||
@Inject(method = "addEndBiomeReplacement", at = @At(value = "HEAD"))
|
||||
private static void bclib_addEndBiomeReplacement(ResourceKey<Biome> replaced,
|
||||
ResourceKey<Biome> variant,
|
||||
double weight,
|
||||
CallbackInfo info) {
|
||||
if (replaced == Biomes.END_BARRENS || replaced == Biomes.SMALL_END_ISLANDS) {
|
||||
FabricBiomesData.END_VOID_BIOMES.put(variant, (float) weight);
|
||||
} else {
|
||||
FabricBiomesData.END_LAND_BIOMES.put(variant, (float) weight);
|
||||
}
|
||||
}
|
||||
|
||||
@Inject(method = "addEndMidlandsReplacement", at = @At(value = "HEAD"))
|
||||
private static void bclib_addEndMidlandsReplacement(ResourceKey<Biome> highlands,
|
||||
ResourceKey<Biome> midlands,
|
||||
double weight,
|
||||
CallbackInfo info) {
|
||||
FabricBiomesData.END_LAND_BIOMES.put(midlands, (float) weight);
|
||||
}
|
||||
|
||||
@Inject(method = "addEndBarrensReplacement", at = @At(value = "HEAD"))
|
||||
private static void bclib_addEndBarrensReplacement(ResourceKey<Biome> highlands,
|
||||
ResourceKey<Biome> barrens,
|
||||
double weight,
|
||||
CallbackInfo info) {
|
||||
FabricBiomesData.END_LAND_BIOMES.put(barrens, (float) weight);
|
||||
FabricBiomesData.END_VOID_BIOMES.put(barrens, (float) weight);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,15 @@
|
|||
package org.betterx.bclib.mixin.common;
|
||||
|
||||
import net.minecraft.server.dedicated.DedicatedServerProperties;
|
||||
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
import org.spongepowered.asm.mixin.injection.At;
|
||||
import org.spongepowered.asm.mixin.injection.ModifyArg;
|
||||
|
||||
@Mixin(DedicatedServerProperties.WorldGenProperties.class)
|
||||
public class WorldGenPropertiesMixin {
|
||||
@ModifyArg(method = "create", at = @At(value = "INVOKE", target = "Lnet/minecraft/world/level/levelgen/presets/WorldPreset;createWorldGenSettings(JZZ)Lnet/minecraft/world/level/levelgen/WorldGenSettings;"))
|
||||
public long bcl_create(long seed) {
|
||||
return seed;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,27 @@
|
|||
package org.betterx.bclib.mixin.common;
|
||||
|
||||
import net.minecraft.core.BlockPos;
|
||||
import net.minecraft.server.level.WorldGenRegion;
|
||||
import net.minecraft.world.level.chunk.ChunkAccess;
|
||||
|
||||
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;
|
||||
|
||||
@Mixin(WorldGenRegion.class)
|
||||
public class WorldGenRegionMixin {
|
||||
@Final
|
||||
@Shadow
|
||||
private ChunkAccess center;
|
||||
|
||||
@Inject(method = "ensureCanWrite", at = @At("HEAD"), cancellable = true)
|
||||
private void be_alterBlockCheck(BlockPos blockPos, CallbackInfoReturnable<Boolean> info) {
|
||||
int x = blockPos.getX() >> 4;
|
||||
int z = blockPos.getZ() >> 4;
|
||||
WorldGenRegion region = (WorldGenRegion) (Object) this;
|
||||
info.setReturnValue(Math.abs(x - center.getPos().x) < 2 && Math.abs(z - center.getPos().z) < 2);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,80 @@
|
|||
package org.betterx.bclib.mixin.common;
|
||||
|
||||
import net.minecraft.client.gui.screens.Screen;
|
||||
import net.minecraft.client.gui.screens.worldselection.WorldOpenFlows;
|
||||
import net.minecraft.core.RegistryAccess;
|
||||
import net.minecraft.server.ReloadableServerResources;
|
||||
import net.minecraft.world.level.LevelSettings;
|
||||
import net.minecraft.world.level.levelgen.WorldGenSettings;
|
||||
import net.minecraft.world.level.storage.LevelStorageSource;
|
||||
import net.minecraft.world.level.storage.WorldData;
|
||||
|
||||
import org.betterx.bclib.api.LifeCycleAPI;
|
||||
import org.betterx.bclib.api.biomes.BiomeAPI;
|
||||
import org.betterx.bclib.api.dataexchange.DataExchangeAPI;
|
||||
import org.betterx.bclib.api.datafixer.DataFixerAPI;
|
||||
import org.betterx.bclib.config.Configs;
|
||||
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;
|
||||
|
||||
@Mixin(WorldOpenFlows.class)
|
||||
public abstract class WorldOpenFlowsMixin {
|
||||
|
||||
@Shadow
|
||||
@Final
|
||||
private LevelStorageSource levelSource;
|
||||
|
||||
@Shadow
|
||||
protected abstract void doLoadLevel(Screen screen, String levelID, boolean safeMode, boolean canAskForBackup);
|
||||
|
||||
@Inject(method = "loadLevel", cancellable = true, at = @At("HEAD"))
|
||||
private void bcl_callFixerOnLoad(Screen screen, String levelID, CallbackInfo ci) {
|
||||
DataExchangeAPI.prepareServerside();
|
||||
BiomeAPI.prepareNewLevel();
|
||||
|
||||
if (DataFixerAPI.fixData(this.levelSource, levelID, true, (appliedFixes) -> {
|
||||
LifeCycleAPI._runBeforeLevelLoad();
|
||||
this.doLoadLevel(screen, levelID, false, false);
|
||||
})) {
|
||||
//cancel call when fix-screen is presented
|
||||
ci.cancel();
|
||||
} else {
|
||||
LifeCycleAPI._runBeforeLevelLoad();
|
||||
if (Configs.CLIENT_CONFIG.suppressExperimentalDialog()) {
|
||||
this.doLoadLevel(screen, levelID, false, false);
|
||||
//cancel call as we manually start the level load here
|
||||
ci.cancel();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Inject(method = "createFreshLevel", at = @At("HEAD"))
|
||||
public void bcl_createFreshLevel(String levelID,
|
||||
LevelSettings levelSettings,
|
||||
RegistryAccess registryAccess,
|
||||
WorldGenSettings worldGenSettings,
|
||||
CallbackInfo ci) {
|
||||
DataExchangeAPI.prepareServerside();
|
||||
BiomeAPI.prepareNewLevel();
|
||||
|
||||
DataFixerAPI.initializeWorldData(this.levelSource, levelID, true);
|
||||
LifeCycleAPI._runBeforeLevelLoad();
|
||||
}
|
||||
|
||||
@Inject(method = "createLevelFromExistingSettings", at = @At("HEAD"))
|
||||
public void bcl_createLevelFromExistingSettings(LevelStorageSource.LevelStorageAccess levelStorageAccess,
|
||||
ReloadableServerResources reloadableServerResources,
|
||||
RegistryAccess.Frozen frozen,
|
||||
WorldData worldData,
|
||||
CallbackInfo ci) {
|
||||
DataExchangeAPI.prepareServerside();
|
||||
BiomeAPI.prepareNewLevel();
|
||||
|
||||
DataFixerAPI.initializeWorldData(levelStorageAccess, true);
|
||||
LifeCycleAPI._runBeforeLevelLoad();
|
||||
}
|
||||
}
|
|
@ -0,0 +1,93 @@
|
|||
package org.betterx.bclib.mixin.common;
|
||||
|
||||
import net.minecraft.core.Holder;
|
||||
import net.minecraft.core.Registry;
|
||||
import net.minecraft.data.BuiltinRegistries;
|
||||
import net.minecraft.resources.ResourceKey;
|
||||
import net.minecraft.world.level.biome.Biome;
|
||||
import net.minecraft.world.level.dimension.DimensionType;
|
||||
import net.minecraft.world.level.dimension.LevelStem;
|
||||
import net.minecraft.world.level.levelgen.NoiseBasedChunkGenerator;
|
||||
import net.minecraft.world.level.levelgen.NoiseGeneratorSettings;
|
||||
import net.minecraft.world.level.levelgen.presets.WorldPreset;
|
||||
import net.minecraft.world.level.levelgen.presets.WorldPresets;
|
||||
import net.minecraft.world.level.levelgen.structure.StructureSet;
|
||||
import net.minecraft.world.level.levelgen.synth.NormalNoise;
|
||||
|
||||
import org.betterx.bclib.BCLib;
|
||||
import org.betterx.bclib.world.generator.BCLibEndBiomeSource;
|
||||
import org.betterx.bclib.world.generator.BCLibNetherBiomeSource;
|
||||
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.ModifyArg;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
@Mixin(WorldPresets.Bootstrap.class)
|
||||
public abstract class WorldPresetsBootstrapMixin {
|
||||
private static final ResourceKey<WorldPreset> BCL_NORMAL = bcl_register("normal");
|
||||
@Shadow
|
||||
@Final
|
||||
private Registry<WorldPreset> presets;
|
||||
@Shadow
|
||||
@Final
|
||||
private Registry<Biome> biomes;
|
||||
@Shadow
|
||||
@Final
|
||||
private Registry<StructureSet> structureSets;
|
||||
@Shadow
|
||||
@Final
|
||||
private Registry<NormalNoise.NoiseParameters> noises;
|
||||
@Shadow
|
||||
@Final
|
||||
private Holder<DimensionType> netherDimensionType;
|
||||
@Shadow
|
||||
@Final
|
||||
private Holder<NoiseGeneratorSettings> netherNoiseSettings;
|
||||
@Shadow
|
||||
@Final
|
||||
private Holder<DimensionType> endDimensionType;
|
||||
@Shadow
|
||||
@Final
|
||||
private Holder<NoiseGeneratorSettings> endNoiseSettings;
|
||||
|
||||
//see WorldPresets.register
|
||||
private static ResourceKey<WorldPreset> bcl_register(String string) {
|
||||
return ResourceKey.create(Registry.WORLD_PRESET_REGISTRY, BCLib.makeID(string));
|
||||
}
|
||||
|
||||
@ModifyArg(method = "run", at = @At(value = "INVOKE", ordinal = 0, target = "Lnet/minecraft/world/level/levelgen/presets/WorldPresets$Bootstrap;registerCustomOverworldPreset(Lnet/minecraft/resources/ResourceKey;Lnet/minecraft/world/level/dimension/LevelStem;)Lnet/minecraft/core/Holder;"))
|
||||
private LevelStem bcl_getOverworldStem(LevelStem overworldStem) {
|
||||
BCLibNetherBiomeSource netherSource = new BCLibNetherBiomeSource(this.biomes);
|
||||
BCLibEndBiomeSource endSource = new BCLibEndBiomeSource(this.biomes);
|
||||
|
||||
LevelStem bclNether = new LevelStem(
|
||||
this.netherDimensionType,
|
||||
new NoiseBasedChunkGenerator(
|
||||
this.structureSets,
|
||||
this.noises,
|
||||
netherSource,
|
||||
this.netherNoiseSettings)
|
||||
);
|
||||
|
||||
LevelStem bclEnd = new LevelStem(
|
||||
this.endDimensionType,
|
||||
new NoiseBasedChunkGenerator(
|
||||
this.structureSets,
|
||||
this.noises,
|
||||
endSource,
|
||||
this.endNoiseSettings)
|
||||
);
|
||||
WorldPreset preset = new WorldPreset(Map.of(LevelStem.OVERWORLD,
|
||||
overworldStem,
|
||||
LevelStem.NETHER,
|
||||
bclNether,
|
||||
LevelStem.END,
|
||||
bclEnd));
|
||||
BuiltinRegistries.register(this.presets, BCL_NORMAL, preset);
|
||||
|
||||
return overworldStem;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,32 @@
|
|||
package org.betterx.bclib.mixin.common.shears;
|
||||
|
||||
import net.minecraft.core.BlockPos;
|
||||
import net.minecraft.world.InteractionHand;
|
||||
import net.minecraft.world.InteractionResult;
|
||||
import net.minecraft.world.entity.player.Player;
|
||||
import net.minecraft.world.item.Items;
|
||||
import net.minecraft.world.level.Level;
|
||||
import net.minecraft.world.level.block.BeehiveBlock;
|
||||
import net.minecraft.world.level.block.state.BlockState;
|
||||
import net.minecraft.world.phys.BlockHitResult;
|
||||
|
||||
import org.betterx.bclib.items.tool.BaseShearsItem;
|
||||
import org.betterx.bclib.util.MethodReplace;
|
||||
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;
|
||||
|
||||
@Mixin(BeehiveBlock.class)
|
||||
public class BeehiveBlockMixin {
|
||||
@Inject(method = "use(Lnet/minecraft/world/level/block/state/BlockState;Lnet/minecraft/world/level/Level;Lnet/minecraft/core/BlockPos;Lnet/minecraft/world/entity/player/Player;Lnet/minecraft/world/InteractionHand;Lnet/minecraft/world/phys/BlockHitResult;)Lnet/minecraft/world/InteractionResult;", at = @At("HEAD"))
|
||||
private void bclib_isShears(BlockState blockState,
|
||||
Level level,
|
||||
BlockPos blockPos,
|
||||
Player player,
|
||||
InteractionHand interactionHand,
|
||||
BlockHitResult blockHitResult,
|
||||
CallbackInfoReturnable<InteractionResult> info) {
|
||||
MethodReplace.addItemReplace(Items.SHEARS, BaseShearsItem::isShear);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,18 @@
|
|||
package org.betterx.bclib.mixin.common.shears;
|
||||
|
||||
import net.minecraft.world.item.ItemStack;
|
||||
import net.minecraft.world.item.enchantment.DiggingEnchantment;
|
||||
|
||||
import org.betterx.bclib.items.tool.BaseShearsItem;
|
||||
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;
|
||||
|
||||
@Mixin(DiggingEnchantment.class)
|
||||
public class DiggingEnchantmentMixin {
|
||||
@Inject(method = "canEnchant(Lnet/minecraft/world/item/ItemStack;)Z", at = @At("HEAD"), cancellable = true)
|
||||
private void bclib_isShears(ItemStack itemStack, CallbackInfoReturnable<Boolean> info) {
|
||||
if (BaseShearsItem.isShear(itemStack)) info.setReturnValue(true);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,33 @@
|
|||
package org.betterx.bclib.mixin.common.shears;
|
||||
|
||||
import net.minecraft.advancements.critereon.ItemPredicate;
|
||||
import net.minecraft.world.item.Item;
|
||||
import net.minecraft.world.item.ItemStack;
|
||||
import net.minecraft.world.item.Items;
|
||||
|
||||
import org.betterx.bclib.api.tag.CommonItemTags;
|
||||
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 java.util.Set;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
@Mixin(ItemPredicate.class)
|
||||
public abstract class ItemPredicateBuilderMixin {
|
||||
@Shadow
|
||||
@Final
|
||||
private @Nullable Set<Item> items;
|
||||
|
||||
@Inject(method = "matches", at = @At("HEAD"), cancellable = true)
|
||||
void bclib_isShears(ItemStack itemStack, CallbackInfoReturnable<Boolean> info) {
|
||||
if (this.items != null && this.items.size() == 1 && this.items.contains(Items.SHEARS)) {
|
||||
if (itemStack.is(CommonItemTags.SHEARS)) {
|
||||
info.setReturnValue(true);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,24 @@
|
|||
package org.betterx.bclib.mixin.common.shears;
|
||||
|
||||
import net.minecraft.world.InteractionHand;
|
||||
import net.minecraft.world.InteractionResult;
|
||||
import net.minecraft.world.entity.animal.MushroomCow;
|
||||
import net.minecraft.world.entity.player.Player;
|
||||
import net.minecraft.world.item.Items;
|
||||
|
||||
import org.betterx.bclib.items.tool.BaseShearsItem;
|
||||
import org.betterx.bclib.util.MethodReplace;
|
||||
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;
|
||||
|
||||
@Mixin(MushroomCow.class)
|
||||
public class MushroomCowMixin {
|
||||
@Inject(method = "mobInteract(Lnet/minecraft/world/entity/player/Player;Lnet/minecraft/world/InteractionHand;)Lnet/minecraft/world/InteractionResult;", at = @At("HEAD"))
|
||||
private void bclib_isShears(Player player,
|
||||
InteractionHand interactionHand,
|
||||
CallbackInfoReturnable<InteractionResult> info) {
|
||||
MethodReplace.addItemReplace(Items.SHEARS, BaseShearsItem::isShear);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,32 @@
|
|||
package org.betterx.bclib.mixin.common.shears;
|
||||
|
||||
import net.minecraft.core.BlockPos;
|
||||
import net.minecraft.world.InteractionHand;
|
||||
import net.minecraft.world.InteractionResult;
|
||||
import net.minecraft.world.entity.player.Player;
|
||||
import net.minecraft.world.item.Items;
|
||||
import net.minecraft.world.level.Level;
|
||||
import net.minecraft.world.level.block.PumpkinBlock;
|
||||
import net.minecraft.world.level.block.state.BlockState;
|
||||
import net.minecraft.world.phys.BlockHitResult;
|
||||
|
||||
import org.betterx.bclib.items.tool.BaseShearsItem;
|
||||
import org.betterx.bclib.util.MethodReplace;
|
||||
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;
|
||||
|
||||
@Mixin(PumpkinBlock.class)
|
||||
public abstract class PumpkinBlockMixin {
|
||||
@Inject(method = "use", at = @At("HEAD"))
|
||||
private void bclib_isShears(BlockState blockState,
|
||||
Level level,
|
||||
BlockPos blockPos,
|
||||
Player player,
|
||||
InteractionHand interactionHand,
|
||||
BlockHitResult blockHitResult,
|
||||
CallbackInfoReturnable<InteractionResult> info) {
|
||||
MethodReplace.addItemReplace(Items.SHEARS, BaseShearsItem::isShear);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,24 @@
|
|||
package org.betterx.bclib.mixin.common.shears;
|
||||
|
||||
import net.minecraft.world.InteractionHand;
|
||||
import net.minecraft.world.InteractionResult;
|
||||
import net.minecraft.world.entity.animal.Sheep;
|
||||
import net.minecraft.world.entity.player.Player;
|
||||
import net.minecraft.world.item.Items;
|
||||
|
||||
import org.betterx.bclib.items.tool.BaseShearsItem;
|
||||
import org.betterx.bclib.util.MethodReplace;
|
||||
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;
|
||||
|
||||
@Mixin(Sheep.class)
|
||||
public class SheepMixin {
|
||||
@Inject(method = "mobInteract(Lnet/minecraft/world/entity/player/Player;Lnet/minecraft/world/InteractionHand;)Lnet/minecraft/world/InteractionResult;", at = @At("HEAD"))
|
||||
private void bclib_isShears(Player player,
|
||||
InteractionHand interactionHand,
|
||||
CallbackInfoReturnable<InteractionResult> info) {
|
||||
MethodReplace.addItemReplace(Items.SHEARS, BaseShearsItem::isShear);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,24 @@
|
|||
package org.betterx.bclib.mixin.common.shears;
|
||||
|
||||
import net.minecraft.world.InteractionHand;
|
||||
import net.minecraft.world.InteractionResult;
|
||||
import net.minecraft.world.entity.animal.SnowGolem;
|
||||
import net.minecraft.world.entity.player.Player;
|
||||
import net.minecraft.world.item.Items;
|
||||
|
||||
import org.betterx.bclib.items.tool.BaseShearsItem;
|
||||
import org.betterx.bclib.util.MethodReplace;
|
||||
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;
|
||||
|
||||
@Mixin(SnowGolem.class)
|
||||
public class SnowGolemMixin {
|
||||
@Inject(method = "mobInteract(Lnet/minecraft/world/entity/player/Player;Lnet/minecraft/world/InteractionHand;)Lnet/minecraft/world/InteractionResult;", at = @At("HEAD"))
|
||||
private void bclib_isShears(Player player,
|
||||
InteractionHand interactionHand,
|
||||
CallbackInfoReturnable<InteractionResult> info) {
|
||||
MethodReplace.addItemReplace(Items.SHEARS, BaseShearsItem::isShear);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,27 @@
|
|||
package org.betterx.bclib.mixin.common.shears;
|
||||
|
||||
import net.minecraft.core.BlockPos;
|
||||
import net.minecraft.world.entity.player.Player;
|
||||
import net.minecraft.world.item.Items;
|
||||
import net.minecraft.world.level.Level;
|
||||
import net.minecraft.world.level.block.TripWireBlock;
|
||||
import net.minecraft.world.level.block.state.BlockState;
|
||||
|
||||
import org.betterx.bclib.items.tool.BaseShearsItem;
|
||||
import org.betterx.bclib.util.MethodReplace;
|
||||
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(TripWireBlock.class)
|
||||
public class TripWireBlockMixin {
|
||||
@Inject(method = "playerWillDestroy(Lnet/minecraft/world/level/Level;Lnet/minecraft/core/BlockPos;Lnet/minecraft/world/level/block/state/BlockState;Lnet/minecraft/world/entity/player/Player;)V", at = @At("HEAD"))
|
||||
private void bclib_isShears(Level level,
|
||||
BlockPos blockPos,
|
||||
BlockState blockState,
|
||||
Player player,
|
||||
CallbackInfo info) {
|
||||
MethodReplace.addItemReplace(Items.SHEARS, BaseShearsItem::isShear);
|
||||
}
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue