Enhanced Enchantment Menu and Table mixins (#72)

This commit is contained in:
paulevsGitch 2022-01-13 18:51:59 +03:00
parent 8ebcf2352a
commit ec61972724
3 changed files with 19 additions and 164 deletions

View file

@ -11,7 +11,7 @@ loader_version= 0.12.12
fabric_version = 0.44.0+1.18
# Mod Properties
mod_version = 1.2.3
mod_version = 1.2.4
maven_group = ru.bclib
archives_base_name = bclib

View file

@ -1,53 +1,25 @@
package ru.bclib.mixin.client;
import net.minecraft.core.BlockPos;
import net.minecraft.core.particles.ParticleTypes;
import net.minecraft.world.level.Level;
import net.minecraft.world.level.block.Block;
import net.minecraft.world.level.block.Blocks;
import net.minecraft.world.level.block.EnchantmentTableBlock;
import net.minecraft.world.level.block.state.BlockState;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
import org.spongepowered.asm.mixin.injection.Redirect;
import ru.bclib.api.TagAPI;
import java.util.Random;
@Mixin(EnchantmentTableBlock.class)
public abstract class EnchantingTableBlockMixin extends Block {
public EnchantingTableBlockMixin(Properties settings) {
super(settings);
}
@Inject(method = "animateTick", at = @At(value = "TAIL"))
private void be_onRandomDisplayTick(BlockState state, Level world, BlockPos pos, Random random, CallbackInfo info) {
for (int px = -2; px <= 2; ++px) {
for (int pz = -2; pz <= 2; ++pz) {
if (px > -2 && px < 2 && pz == -1) {
pz = 2;
}
if (random.nextInt(16) == 0) {
for (int py = 0; py <= 1; ++py) {
BlockPos blockPos = pos.offset(px, py, pz);
if (world.getBlockState(blockPos).is(TagAPI.BLOCK_BOOKSHELVES)) {
if (!world.isEmptyBlock(pos.offset(px / 2, 0, pz / 2))) {
break;
}
world.addParticle(
ParticleTypes.ENCHANT,
pos.getX() + 0.5,
pos.getY() + 2.0,
pos.getZ() + 0.5,
px + random.nextFloat() - 0.5,
py - random.nextFloat() - 1.0,
pz + random.nextFloat() - 0.5
);
}
}
}
}
}
@Redirect(method = "animateTick", at = @At(
value = "INVOKE",
target = "Lnet/minecraft/world/level/block/state/BlockState;is(Lnet/minecraft/world/level/block/Block;)Z")//,
)
private boolean bclib_isBookshelf(BlockState state, Block block) {
return block == Blocks.BOOKSHELF ? state.is(TagAPI.BLOCK_BOOKSHELVES) : state.is(block);
}
}

View file

@ -1,144 +1,27 @@
package ru.bclib.mixin.common;
import net.minecraft.core.Registry;
import net.minecraft.world.Container;
import net.minecraft.world.inventory.AbstractContainerMenu;
import net.minecraft.world.inventory.ContainerLevelAccess;
import net.minecraft.world.inventory.DataSlot;
import net.minecraft.world.inventory.EnchantmentMenu;
import net.minecraft.world.inventory.MenuType;
import net.minecraft.world.item.ItemStack;
import net.minecraft.world.item.enchantment.EnchantmentHelper;
import net.minecraft.world.item.enchantment.EnchantmentInstance;
import org.spongepowered.asm.mixin.Final;
import net.minecraft.world.level.block.Block;
import net.minecraft.world.level.block.Blocks;
import net.minecraft.world.level.block.state.BlockState;
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.Redirect;
import ru.bclib.api.TagAPI;
import java.util.List;
import java.util.Random;
@Mixin(EnchantmentMenu.class)
public abstract class EnchantmentMenuMixin extends AbstractContainerMenu {
@Final
@Shadow
private Container enchantSlots;
@Final
@Shadow
private ContainerLevelAccess access;
@Final
@Shadow
private Random random;
@Final
@Shadow
private DataSlot enchantmentSeed;
@Shadow
@Final
public int[] costs;
@Shadow
@Final
public int[] enchantClue;
@Shadow
@Final
public int[] levelClue;
protected EnchantmentMenuMixin(MenuType<?> type, int syncId) {
super(type, syncId);
}
@Inject(method = "slotsChanged", at = @At("HEAD"), cancellable = true)
private void be_slotsChanged(Container inventory, CallbackInfo info) {
if (inventory == this.enchantSlots) {
ItemStack itemStack = inventory.getItem(0);
if (!itemStack.isEmpty() && itemStack.isEnchantable()) {
this.access.execute((world, blockPos) -> {
int i = 0;
int j;
for (j = -1; j <= 1; ++j) {
for (int k = -1; k <= 1; ++k) {
if ((j != 0 || k != 0) && world.isEmptyBlock(blockPos.offset(
k,
0,
j
)) && world.isEmptyBlock(blockPos.offset(k, 1, j))) {
if (world.getBlockState(blockPos.offset(k * 2, 0, j * 2)).is(TagAPI.BLOCK_BOOKSHELVES)) {
++i;
}
if (world.getBlockState(blockPos.offset(k * 2, 1, j * 2)).is(TagAPI.BLOCK_BOOKSHELVES)) {
++i;
}
if (k != 0 && j != 0) {
if (world.getBlockState(blockPos.offset(k * 2, 0, j)).is(TagAPI.BLOCK_BOOKSHELVES)) {
++i;
}
if (world.getBlockState(blockPos.offset(k * 2, 1, j)).is(TagAPI.BLOCK_BOOKSHELVES)) {
++i;
}
if (world.getBlockState(blockPos.offset(k, 0, j * 2)).is(TagAPI.BLOCK_BOOKSHELVES)) {
++i;
}
if (world.getBlockState(blockPos.offset(k, 1, j * 2)).is(TagAPI.BLOCK_BOOKSHELVES)) {
++i;
}
}
}
}
}
random.setSeed(enchantmentSeed.get());
for (j = 0; j < 3; ++j) {
costs[j] = EnchantmentHelper.getEnchantmentCost(this.random, j, i, itemStack);
enchantClue[j] = -1;
levelClue[j] = -1;
if (costs[j] < j + 1) {
costs[j] = 0;
}
}
for (j = 0; j < 3; ++j) {
if (this.costs[j] > 0) {
List<EnchantmentInstance> list = this.getEnchantmentList(itemStack, j, this.costs[j]);
if (list != null && !list.isEmpty()) {
EnchantmentInstance enchantmentLevelEntry = (EnchantmentInstance) list.get(this.random.nextInt(
list.size()));
enchantClue[j] = Registry.ENCHANTMENT.getId(enchantmentLevelEntry.enchantment);
levelClue[j] = enchantmentLevelEntry.level;
}
}
}
broadcastChanges();
});
}
else {
for (int i = 0; i < 3; ++i) {
costs[i] = 0;
enchantClue[i] = -1;
levelClue[i] = -1;
}
}
info.cancel();
}
}
@Shadow
private List<EnchantmentInstance> getEnchantmentList(ItemStack stack, int slot, int level) {
return null;
@Redirect(method = "lambda$slotsChanged$0(Lnet/minecraft/world/item/ItemStack;Lnet/minecraft/world/level/Level;Lnet/minecraft/core/BlockPos;)V", at = @At(
value = "INVOKE",
target = "Lnet/minecraft/world/level/block/state/BlockState;is(Lnet/minecraft/world/level/block/Block;)Z")//,
)
private boolean bclib_isBookshelf(BlockState state, Block block) {
return block == Blocks.BOOKSHELF ? state.is(TagAPI.BLOCK_BOOKSHELVES) : state.is(block);
}
}