Reorganized Imports/Packages
This commit is contained in:
parent
cb9459f176
commit
3ee10482ab
721 changed files with 34873 additions and 33558 deletions
|
@ -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