Add parchmentMC mappings, changed structure a little, add networking and completed enchanting

This commit is contained in:
Andrew 2022-08-07 13:26:36 +07:00
parent 38ee524bf9
commit 6bfb963839
20 changed files with 793 additions and 18 deletions

View file

@ -1,5 +1,6 @@
plugins { plugins {
id 'net.minecraftforge.gradle' version '5.1.+' id 'net.minecraftforge.gradle' version '5.1.+'
id 'org.parchmentmc.librarian.forgegradle' version '1.+'
} }
@ -26,6 +27,7 @@ minecraft {
// Use non-default mappings at your own risk. They may not always work. // Use non-default mappings at your own risk. They may not always work.
// Simply re-run your setup task after changing the mappings to update your workspace. // Simply re-run your setup task after changing the mappings to update your workspace.
mappings channel: 'official', version: '1.18.2' mappings channel: 'official', version: '1.18.2'
mappings channel: 'parchment', version: '2022.08.02-1.18.2'
// accessTransformer = file('src/main/resources/META-INF/accesstransformer.cfg') // accessTransformer = file('src/main/resources/META-INF/accesstransformer.cfg')

View file

@ -2,6 +2,7 @@ pluginManagement {
repositories { repositories {
gradlePluginPortal() gradlePluginPortal()
maven { url = 'https://maven.minecraftforge.net/' } maven { url = 'https://maven.minecraftforge.net/' }
maven { url = 'https://maven.parchmentmc.org' }
} }
} }

View file

@ -1,29 +1,41 @@
package xyz.nuark.enchantrium; package xyz.nuark.enchantrium;
import com.mojang.logging.LogUtils; import com.mojang.logging.LogUtils;
import net.minecraft.client.gui.screens.MenuScreens;
import net.minecraft.resources.ResourceLocation;
import net.minecraftforge.api.distmarker.Dist;
import net.minecraftforge.common.MinecraftForge; import net.minecraftforge.common.MinecraftForge;
import net.minecraftforge.eventbus.api.IEventBus; import net.minecraftforge.eventbus.api.IEventBus;
import net.minecraftforge.fml.DistExecutor;
import net.minecraftforge.fml.common.Mod; import net.minecraftforge.fml.common.Mod;
import net.minecraftforge.fml.event.lifecycle.FMLClientSetupEvent;
import net.minecraftforge.fml.javafmlmod.FMLJavaModLoadingContext; import net.minecraftforge.fml.javafmlmod.FMLJavaModLoadingContext;
import net.minecraftforge.network.NetworkRegistry;
import net.minecraftforge.network.simple.SimpleChannel;
import org.slf4j.Logger; import org.slf4j.Logger;
import xyz.nuark.enchantrium.block.ModBlocks; import xyz.nuark.enchantrium.block.ModBlocks;
import xyz.nuark.enchantrium.block.entity.ModBlockEntities; import xyz.nuark.enchantrium.block.entity.ModBlockEntities;
import xyz.nuark.enchantrium.item.ModItems; import xyz.nuark.enchantrium.item.ModItems;
import xyz.nuark.enchantrium.network.Networking;
import xyz.nuark.enchantrium.screen.EnchanterScreen;
import xyz.nuark.enchantrium.screen.ModMenuTypes; import xyz.nuark.enchantrium.screen.ModMenuTypes;
import xyz.nuark.enchantrium.setup.ClientSetup;
import xyz.nuark.enchantrium.setup.ModSetup;
import xyz.nuark.enchantrium.setup.Registration;
@Mod(Enchantrium.MOD_ID) @Mod(Enchantrium.MOD_ID)
public class Enchantrium { public class Enchantrium {
public static final String MOD_ID = "enchantrium"; public static final String MOD_ID = "enchantrium";
public static final Logger LOGGER = LogUtils.getLogger(); public static final Logger LOGGER = LogUtils.getLogger();
public Enchantrium() { public Enchantrium() {
IEventBus eventBus = FMLJavaModLoadingContext.get().getModEventBus(); IEventBus eventBus = FMLJavaModLoadingContext.get().getModEventBus();
ModItems.register(eventBus); ModSetup.setup();
ModBlocks.register(eventBus); Registration.register(eventBus);
ModBlockEntities.register(eventBus);
ModMenuTypes.register(eventBus);
MinecraftForge.EVENT_BUS.register(this); eventBus.addListener(ModSetup::init);
DistExecutor.unsafeRunWhenOn(Dist.CLIENT, () -> () -> eventBus.addListener(ClientSetup::init));
} }
} }

View file

@ -8,6 +8,8 @@ import net.minecraft.world.item.ItemStack;
import net.minecraft.world.item.TooltipFlag; import net.minecraft.world.item.TooltipFlag;
import net.minecraft.world.level.Level; import net.minecraft.world.level.Level;
import net.minecraft.world.level.block.Block; import net.minecraft.world.level.block.Block;
import net.minecraft.world.level.block.Blocks;
import net.minecraft.world.level.block.state.BlockBehaviour;
import net.minecraftforge.eventbus.api.IEventBus; import net.minecraftforge.eventbus.api.IEventBus;
import net.minecraftforge.registries.DeferredRegister; import net.minecraftforge.registries.DeferredRegister;
import net.minecraftforge.registries.ForgeRegistries; import net.minecraftforge.registries.ForgeRegistries;
@ -15,7 +17,9 @@ import net.minecraftforge.registries.RegistryObject;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable; import org.jetbrains.annotations.Nullable;
import xyz.nuark.enchantrium.Enchantrium; import xyz.nuark.enchantrium.Enchantrium;
import xyz.nuark.enchantrium.block.custom.EnchanterBlock;
import xyz.nuark.enchantrium.item.ModItems; import xyz.nuark.enchantrium.item.ModItems;
import xyz.nuark.enchantrium.setup.ModSetup;
import java.util.List; import java.util.List;
import java.util.function.Supplier; import java.util.function.Supplier;
@ -24,6 +28,10 @@ public class ModBlocks {
public static final DeferredRegister<Block> BLOCKS = public static final DeferredRegister<Block> BLOCKS =
DeferredRegister.create(ForgeRegistries.BLOCKS, Enchantrium.MOD_ID); DeferredRegister.create(ForgeRegistries.BLOCKS, Enchantrium.MOD_ID);
public static final RegistryObject<Block> ENCHANTER = registerBlock("enchanter",
() -> new EnchanterBlock(BlockBehaviour.Properties.copy(Blocks.ENCHANTING_TABLE).noOcclusion())
);
private static <T extends Block> RegistryObject<T> registerBlockWithoutBlockItem(String name, Supplier<T> block) { private static <T extends Block> RegistryObject<T> registerBlockWithoutBlockItem(String name, Supplier<T> block) {
return BLOCKS.register(name, block); return BLOCKS.register(name, block);
} }
@ -36,7 +44,7 @@ public class ModBlocks {
private static <T extends Block> RegistryObject<Item> registerBlockItem(String name, RegistryObject<T> block, String tooltipKey) { private static <T extends Block> RegistryObject<Item> registerBlockItem(String name, RegistryObject<T> block, String tooltipKey) {
return ModItems.ITEMS.register(name, () -> new BlockItem(block.get(), return ModItems.ITEMS.register(name, () -> new BlockItem(block.get(),
new Item.Properties().tab(ModItems.ITEM_GROUP)) { new Item.Properties().tab(ModSetup.ITEM_GROUP)) {
@Override @Override
public void appendHoverText(@NotNull ItemStack pStack, @Nullable Level pLevel, @NotNull List<Component> pTooltip, @NotNull TooltipFlag pFlag) { public void appendHoverText(@NotNull ItemStack pStack, @Nullable Level pLevel, @NotNull List<Component> pTooltip, @NotNull TooltipFlag pFlag) {
pTooltip.add(new TranslatableComponent(tooltipKey)); pTooltip.add(new TranslatableComponent(tooltipKey));
@ -52,7 +60,7 @@ public class ModBlocks {
private static <T extends Block> RegistryObject<Item> registerBlockItem(String name, RegistryObject<T> block) { private static <T extends Block> RegistryObject<Item> registerBlockItem(String name, RegistryObject<T> block) {
return ModItems.ITEMS.register(name, () -> new BlockItem(block.get(), return ModItems.ITEMS.register(name, () -> new BlockItem(block.get(),
new Item.Properties().tab(ModItems.ITEM_GROUP))); new Item.Properties().tab(ModSetup.ITEM_GROUP)));
} }
public static void register(IEventBus eventBus) { public static void register(IEventBus eventBus) {

View file

@ -0,0 +1,62 @@
package xyz.nuark.enchantrium.block.custom;
import net.minecraft.core.BlockPos;
import net.minecraft.server.level.ServerPlayer;
import net.minecraft.world.InteractionHand;
import net.minecraft.world.InteractionResult;
import net.minecraft.world.entity.player.Player;
import net.minecraft.world.level.Level;
import net.minecraft.world.level.block.BaseEntityBlock;
import net.minecraft.world.level.block.Block;
import net.minecraft.world.level.block.RenderShape;
import net.minecraft.world.level.block.entity.BlockEntity;
import net.minecraft.world.level.block.state.BlockBehaviour;
import net.minecraft.world.level.block.state.BlockState;
import net.minecraft.world.phys.BlockHitResult;
import net.minecraftforge.network.NetworkHooks;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import xyz.nuark.enchantrium.block.entity.custom.EnchanterBlockEntity;
public class EnchanterBlock extends BaseEntityBlock {
public EnchanterBlock(BlockBehaviour.Properties properties) {
super(properties);
}
@Override
public RenderShape getRenderShape(BlockState pState) {
return RenderShape.MODEL;
}
@Override
public void onRemove(BlockState pState, @NotNull Level pLevel, @NotNull BlockPos pPos, BlockState pNewState, boolean pIsMoving) {
if (pState.getBlock() != pNewState.getBlock()) {
BlockEntity blockEntity = pLevel.getBlockEntity(pPos);
if (blockEntity instanceof EnchanterBlockEntity) {
((EnchanterBlockEntity) blockEntity).drops();
}
}
super.onRemove(pState, pLevel, pPos, pNewState, pIsMoving);
}
@Override
public InteractionResult use(BlockState blockState, Level level, BlockPos blockPos,
Player player, InteractionHand interactionHand, BlockHitResult hitResult) {
if (!level.isClientSide()) {
BlockEntity entity = level.getBlockEntity(blockPos);
if(entity instanceof EnchanterBlockEntity) {
NetworkHooks.openGui(((ServerPlayer)player), (EnchanterBlockEntity)entity, blockPos);
} else {
throw new IllegalStateException("Our Container provider is missing!");
}
}
return InteractionResult.sidedSuccess(level.isClientSide());
}
@Nullable
@Override
public BlockEntity newBlockEntity(@NotNull BlockPos blockPos, @NotNull BlockState blockState) {
return new EnchanterBlockEntity(blockPos, blockState);
}
}

View file

@ -4,12 +4,18 @@ import net.minecraft.world.level.block.entity.BlockEntityType;
import net.minecraftforge.eventbus.api.IEventBus; import net.minecraftforge.eventbus.api.IEventBus;
import net.minecraftforge.registries.DeferredRegister; import net.minecraftforge.registries.DeferredRegister;
import net.minecraftforge.registries.ForgeRegistries; import net.minecraftforge.registries.ForgeRegistries;
import net.minecraftforge.registries.RegistryObject;
import xyz.nuark.enchantrium.Enchantrium; import xyz.nuark.enchantrium.Enchantrium;
import xyz.nuark.enchantrium.block.ModBlocks;
import xyz.nuark.enchantrium.block.entity.custom.EnchanterBlockEntity;
public class ModBlockEntities { public class ModBlockEntities {
public static final DeferredRegister<BlockEntityType<?>> BLOCK_ENTITIES = public static final DeferredRegister<BlockEntityType<?>> BLOCK_ENTITIES =
DeferredRegister.create(ForgeRegistries.BLOCK_ENTITIES, Enchantrium.MOD_ID); DeferredRegister.create(ForgeRegistries.BLOCK_ENTITIES, Enchantrium.MOD_ID);
public static final RegistryObject<BlockEntityType<EnchanterBlockEntity>> ENCHANTER_BLOCK_ENTITY =
BLOCK_ENTITIES.register("enchanter_block_entity", () -> BlockEntityType.Builder.of(EnchanterBlockEntity::new, ModBlocks.ENCHANTER.get()).build(null));
public static void register(IEventBus eventBus) { public static void register(IEventBus eventBus) {
BLOCK_ENTITIES.register(eventBus); BLOCK_ENTITIES.register(eventBus);
} }

View file

@ -0,0 +1,122 @@
package xyz.nuark.enchantrium.block.entity.custom;
import net.minecraft.core.BlockPos;
import net.minecraft.core.Direction;
import net.minecraft.nbt.CompoundTag;
import net.minecraft.network.chat.Component;
import net.minecraft.network.chat.TextComponent;
import net.minecraft.world.Containers;
import net.minecraft.world.MenuProvider;
import net.minecraft.world.SimpleContainer;
import net.minecraft.world.entity.player.Inventory;
import net.minecraft.world.entity.player.Player;
import net.minecraft.world.inventory.AbstractContainerMenu;
import net.minecraft.world.inventory.ContainerLevelAccess;
import net.minecraft.world.item.ItemStack;
import net.minecraft.world.item.Items;
import net.minecraft.world.item.enchantment.EnchantmentInstance;
import net.minecraft.world.level.block.entity.BlockEntity;
import net.minecraft.world.level.block.state.BlockState;
import net.minecraftforge.common.capabilities.Capability;
import net.minecraftforge.common.util.LazyOptional;
import net.minecraftforge.items.CapabilityItemHandler;
import net.minecraftforge.items.ItemStackHandler;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import xyz.nuark.enchantrium.Enchantrium;
import xyz.nuark.enchantrium.block.entity.ModBlockEntities;
import xyz.nuark.enchantrium.screen.EnchanterMenu;
import java.util.List;
public class EnchanterBlockEntity extends BlockEntity implements MenuProvider {
private final ItemStackHandler itemHandler = new ItemStackHandler(2) {
@Override
protected void onContentsChanged(int slot) {
setChanged();
}
};
private LazyOptional<ItemStackHandler> lazyItemHandler = LazyOptional.empty();
public EnchanterBlockEntity(BlockPos pos, BlockState blockState) {
super(ModBlockEntities.ENCHANTER_BLOCK_ENTITY.get(), pos, blockState);
}
@Override
public @NotNull Component getDisplayName() {
return new TextComponent("Enchanter");
}
@Nullable
@Override
public AbstractContainerMenu createMenu(int containerID, Inventory inventory, Player player) {
return new EnchanterMenu(containerID, inventory, this);
}
@NotNull
@Override
public <T> LazyOptional<T> getCapability(@NotNull Capability<T> cap, @javax.annotation.Nullable Direction side) {
if (cap == CapabilityItemHandler.ITEM_HANDLER_CAPABILITY) {
return lazyItemHandler.cast();
}
return super.getCapability(cap, side);
}
@Override
public void onLoad() {
super.onLoad();
lazyItemHandler = LazyOptional.of(() -> itemHandler);
}
@Override
public void invalidateCaps() {
super.invalidateCaps();
lazyItemHandler.invalidate();
}
@Override
protected void saveAdditional(@NotNull CompoundTag tag) {
tag.put("inventory", itemHandler.serializeNBT());
super.saveAdditional(tag);
}
@Override
public void load(@NotNull CompoundTag nbt) {
super.load(nbt);
itemHandler.deserializeNBT(nbt.getCompound("inventory"));
}
public void drops() {
SimpleContainer inventory = new SimpleContainer(itemHandler.getSlots());
for (int i = 0; i < itemHandler.getSlots(); i++) {
inventory.setItem(i, itemHandler.getStackInSlot(i));
}
if (this.level != null) {
Containers.dropContents(this.level, this.worldPosition, inventory);
} else {
Enchantrium.LOGGER.error("EnchanterBlockEntity.drops() - level is null");
}
}
public ItemStack getInput() {
return itemHandler.getStackInSlot(0);
}
public void enchant(List<EnchantmentInstance> enchantments) {
if (itemHandler.extractItem(1, 1, true).is(Items.AIR)) {
return;
}
ItemStack input = itemHandler.extractItem(0, 1, false);
itemHandler.extractItem(1, 1, false);
for (EnchantmentInstance enchantment : enchantments) {
input.enchant(enchantment.enchantment, enchantment.level);
}
itemHandler.setStackInSlot(0, input);
itemHandler.insertItem(0, input, false);
}
}

View file

@ -1,26 +1,17 @@
package xyz.nuark.enchantrium.item; package xyz.nuark.enchantrium.item;
import net.minecraft.world.item.CreativeModeTab;
import net.minecraft.world.item.Item; import net.minecraft.world.item.Item;
import net.minecraft.world.item.ItemStack;
import net.minecraftforge.eventbus.api.IEventBus; import net.minecraftforge.eventbus.api.IEventBus;
import net.minecraftforge.registries.DeferredRegister; import net.minecraftforge.registries.DeferredRegister;
import net.minecraftforge.registries.ForgeRegistries; import net.minecraftforge.registries.ForgeRegistries;
import net.minecraftforge.registries.RegistryObject; import net.minecraftforge.registries.RegistryObject;
import org.jetbrains.annotations.NotNull;
import xyz.nuark.enchantrium.Enchantrium; import xyz.nuark.enchantrium.Enchantrium;
import xyz.nuark.enchantrium.setup.ModSetup;
public class ModItems { public class ModItems {
public static final CreativeModeTab ITEM_GROUP = new CreativeModeTab(Enchantrium.MOD_ID) {
@Override
public @NotNull ItemStack makeIcon() {
return new ItemStack(TEST_ITEM.get());
}
};
public static final DeferredRegister<Item> ITEMS = DeferredRegister.create(ForgeRegistries.ITEMS, Enchantrium.MOD_ID); public static final DeferredRegister<Item> ITEMS = DeferredRegister.create(ForgeRegistries.ITEMS, Enchantrium.MOD_ID);
public static final RegistryObject<Item> TEST_ITEM = ITEMS.register("test_item", () -> new Item(new Item.Properties().tab(ITEM_GROUP))); public static final RegistryObject<Item> TEST_ITEM = ITEMS.register("test_item", () -> new Item(new Item.Properties().tab(ModSetup.ITEM_GROUP)));
public static void register(IEventBus eventBus) { public static void register(IEventBus eventBus) {
ITEMS.register(eventBus); ITEMS.register(eventBus);

View file

@ -0,0 +1,51 @@
package xyz.nuark.enchantrium.network;
import net.minecraft.resources.ResourceLocation;
import net.minecraft.server.level.ServerPlayer;
import net.minecraftforge.network.NetworkDirection;
import net.minecraftforge.network.NetworkRegistry;
import net.minecraftforge.network.PacketDistributor;
import net.minecraftforge.network.simple.SimpleChannel;
import xyz.nuark.enchantrium.Enchantrium;
import xyz.nuark.enchantrium.network.message.PacketEnchantItem;
import xyz.nuark.enchantrium.network.message.PacketSyncEnchantedItemToClient;
public class Networking {
public static final String PROTOCOL_VERSION = "1";
public static SimpleChannel INSTANCE;
private static int packetId = 0;
private static int nextPacketId() {
return packetId++;
}
public static void register() {
INSTANCE = NetworkRegistry.ChannelBuilder
.named(new ResourceLocation(Enchantrium.MOD_ID, "main"))
.networkProtocolVersion(() -> PROTOCOL_VERSION)
.clientAcceptedVersions(PROTOCOL_VERSION::equals)
.serverAcceptedVersions(PROTOCOL_VERSION::equals)
.simpleChannel();
INSTANCE.messageBuilder(PacketEnchantItem.class, nextPacketId(), NetworkDirection.PLAY_TO_SERVER)
.encoder(PacketEnchantItem::encode)
.decoder(PacketEnchantItem::decode)
.consumer(PacketEnchantItem::handle)
.add();
INSTANCE.messageBuilder(PacketSyncEnchantedItemToClient.class, nextPacketId(), NetworkDirection.PLAY_TO_CLIENT)
.encoder(PacketSyncEnchantedItemToClient::encode)
.decoder(PacketSyncEnchantedItemToClient::decode)
.consumer(PacketSyncEnchantedItemToClient::handle)
.add();
}
public static <MSG> void sendToServer(MSG message) {
INSTANCE.sendToServer(message);
}
public static <MSG> void sendToPlayer(MSG message, ServerPlayer player) {
INSTANCE.send(PacketDistributor.PLAYER.with(() -> player), message);
}
}

View file

@ -0,0 +1,55 @@
package xyz.nuark.enchantrium.network.message;
import net.minecraft.core.BlockPos;
import net.minecraft.core.Registry;
import net.minecraft.network.FriendlyByteBuf;
import net.minecraft.world.item.ItemStack;
import net.minecraft.world.item.enchantment.Enchantment;
import net.minecraft.world.item.enchantment.EnchantmentInstance;
import net.minecraft.world.level.Level;
import net.minecraftforge.network.NetworkEvent;
import net.minecraftforge.registries.ForgeRegistries;
import xyz.nuark.enchantrium.Enchantrium;
import xyz.nuark.enchantrium.block.entity.custom.EnchanterBlockEntity;
import xyz.nuark.enchantrium.network.Networking;
import java.util.List;
import java.util.Objects;
import java.util.function.Supplier;
public class PacketEnchantItem {
private final BlockPos blockEntityPos;
private final List<EnchantmentInstance> enchantments;
public PacketEnchantItem(BlockPos blockEntityPos, List<EnchantmentInstance> enchantments) {
this.blockEntityPos = blockEntityPos;
this.enchantments = enchantments;
}
public boolean handle(Supplier<NetworkEvent.Context> supplier) {
NetworkEvent.Context ctx = supplier.get();
ctx.enqueueWork(() -> {
EnchanterBlockEntity ebe = (EnchanterBlockEntity)ctx.getSender().level.getBlockEntity(blockEntityPos);
ebe.enchant(enchantments);
});
return true;
}
public void encode(FriendlyByteBuf friendlyByteBuf) {
friendlyByteBuf.writeBlockPos(blockEntityPos);
friendlyByteBuf.writeCollection(enchantments, (buf, enchantment) -> {
buf.writeResourceLocation(ForgeRegistries.ENCHANTMENTS.getKey(enchantment.enchantment));
buf.writeVarInt(enchantment.level);
});
}
public static PacketEnchantItem decode(FriendlyByteBuf friendlyByteBuf) {
return new PacketEnchantItem(
friendlyByteBuf.readBlockPos(),
friendlyByteBuf.readList((buf) -> new EnchantmentInstance(
ForgeRegistries.ENCHANTMENTS.getValue(buf.readResourceLocation()),
buf.readVarInt()
))
);
}
}

View file

@ -0,0 +1,183 @@
package xyz.nuark.enchantrium.screen;
import com.google.common.collect.Lists;
import net.minecraft.Util;
import net.minecraft.network.FriendlyByteBuf;
import net.minecraft.world.entity.player.Inventory;
import net.minecraft.world.entity.player.Player;
import net.minecraft.world.inventory.AbstractContainerMenu;
import net.minecraft.world.inventory.ContainerLevelAccess;
import net.minecraft.world.inventory.Slot;
import net.minecraft.world.item.ItemStack;
import net.minecraft.world.item.Items;
import net.minecraft.world.item.enchantment.EnchantmentInstance;
import net.minecraft.world.level.Level;
import net.minecraft.world.level.block.entity.BlockEntity;
import net.minecraftforge.common.Tags;
import net.minecraftforge.items.CapabilityItemHandler;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import xyz.nuark.enchantrium.Enchantrium;
import xyz.nuark.enchantrium.block.ModBlocks;
import xyz.nuark.enchantrium.block.entity.custom.EnchanterBlockEntity;
import xyz.nuark.enchantrium.network.Networking;
import xyz.nuark.enchantrium.network.message.PacketEnchantItem;
import xyz.nuark.enchantrium.screen.slot.FilteredSlot;
import xyz.nuark.enchantrium.util.EnchantmentUtil;
import java.util.List;
public class EnchanterMenu extends AbstractContainerMenu {
private final EnchanterBlockEntity blockEntity;
private final Level level;
private ItemStack inputStack = new ItemStack(Items.AIR);
private List<EnchantmentInstance> enchantments = Lists.newArrayList();
private int currentEnchantmentIndex = -1;
private final Object lock = new Object();
public EnchanterMenu(int containerId, Inventory inv, FriendlyByteBuf extraData) {
this(containerId, inv, inv.player.level.getBlockEntity(extraData.readBlockPos()));
}
public EnchanterMenu(int containerId, Inventory inv, BlockEntity entity) {
super(ModMenuTypes.ENCHANTER_MENU.get(), containerId);
checkContainerSize(inv, 2);
blockEntity = ((EnchanterBlockEntity) entity);
this.level = inv.player.level;
addPlayerInventory(inv);
addPlayerHotbar(inv);
this.blockEntity.getCapability(CapabilityItemHandler.ITEM_HANDLER_CAPABILITY).ifPresent(handler -> {
this.addSlot(new FilteredSlot(
handler, 0, 8, 19,
stack -> EnchantmentUtil.canBeEnchanted(stack) && !stack.isEnchanted() && !stack.is(Items.BOOK)
));
this.addSlot(new FilteredSlot(
handler, 1, 8, 43,
stack -> stack.is(Tags.Items.GEMS_EMERALD) || stack.is(Tags.Items.INGOTS_NETHERITE)
));
});
}
@Nullable
public EnchantmentInstance getCurrentEnchantment() {
synchronized (lock) {
if (blockEntity.getInput().isEmpty() || blockEntity.getInput().isEnchanted()) {
currentEnchantmentIndex = -1;
return null;
} else if (currentEnchantmentIndex == -1) {
currentEnchantmentIndex = 0;
}
if (!this.inputStack.sameItem(blockEntity.getInput())) {
this.enchantments = EnchantmentUtil.getApplicableEnchantments(blockEntity.getInput());
currentEnchantmentIndex = 0;
this.inputStack = blockEntity.getInput();
}
return this.enchantments.size() > 0 ? this.enchantments.get(currentEnchantmentIndex) : null;
}
}
@Override
public boolean clickMenuButton(Player player, int buttonId) {
if (buttonId < 0 || buttonId >= 5) {
Util.logAndPauseIfInIde(player.getName() + " pressed invalid button id: " + buttonId);
return false;
}
Enchantrium.LOGGER.debug("{} clicked button {}", player.getName(), buttonId);
synchronized (lock) {
if (buttonId == 0) {
Networking.sendToServer(new PacketEnchantItem(blockEntity.getBlockPos(), this.enchantments.stream().filter(e -> e.level > 0).toList()));
} else if (buttonId == 1) {
currentEnchantmentIndex = (currentEnchantmentIndex + 1) % enchantments.size();
} else if (buttonId == 2) {
currentEnchantmentIndex = (currentEnchantmentIndex - 1 + enchantments.size()) % enchantments.size();
} else if (buttonId == 3) {
var enchantment = this.enchantments.get(currentEnchantmentIndex);
this.enchantments.set(currentEnchantmentIndex, new EnchantmentInstance(
enchantment.enchantment,
enchantment.level < enchantment.enchantment.getMaxLevel() ? (enchantment.level + 1) : enchantment.level
));
} else {
var enchantment = this.enchantments.get(currentEnchantmentIndex);
this.enchantments.set(currentEnchantmentIndex, new EnchantmentInstance(
enchantment.enchantment,
enchantment.level > 0 ? (enchantment.level - 1) : 0
));
}
}
return true;
}
@Override
public boolean stillValid(@NotNull Player player) {
return stillValid(ContainerLevelAccess.create(level, blockEntity.getBlockPos()), player, ModBlocks.ENCHANTER.get());
}
private void addPlayerInventory(Inventory playerInventory) {
for (int i = 0; i < 3; i++) {
for (int j = 0; j < 9; j++) {
addSlot(new Slot(playerInventory, j + i * 9 + 9, 8 + j * 18, 86 + i * 18));
}
}
}
private void addPlayerHotbar(Inventory playerInventory) {
for (int i = 0; i < 9; i++) {
addSlot(new Slot(playerInventory, i, 8 + i * 18, 144));
}
}
// CREDIT GOES TO: diesieben07 | https://github.com/diesieben07/SevenCommons
// must assign a slot number to each of the slots used by the GUI.
// For this container, we can see both the tile inventory's slots and the player inventory slots and the hotbar.
// Each time we add a Slot to the container, it automatically increases the slotIndex, which means
// 0 - 8 = hotbar slots (which will map to the InventoryPlayer slot numbers 0 - 8)
// 9 - 35 = player inventory slots (which map to the InventoryPlayer slot numbers 9 - 35)
// 36 - 44 = TileInventory slots, which map to our TileEntity slot numbers 0 - 8)
private static final int HOTBAR_SLOT_COUNT = 9;
private static final int PLAYER_INVENTORY_ROW_COUNT = 3;
private static final int PLAYER_INVENTORY_COLUMN_COUNT = 9;
private static final int PLAYER_INVENTORY_SLOT_COUNT = PLAYER_INVENTORY_COLUMN_COUNT * PLAYER_INVENTORY_ROW_COUNT;
private static final int VANILLA_SLOT_COUNT = HOTBAR_SLOT_COUNT + PLAYER_INVENTORY_SLOT_COUNT;
private static final int VANILLA_FIRST_SLOT_INDEX = 0;
private static final int TE_INVENTORY_FIRST_SLOT_INDEX = VANILLA_FIRST_SLOT_INDEX + VANILLA_SLOT_COUNT;
// THIS YOU HAVE TO DEFINE!
private static final int TE_INVENTORY_SLOT_COUNT = 2; // must be the number of slots you have!
@Override
public @NotNull ItemStack quickMoveStack(@NotNull Player playerIn, int index) {
Slot sourceSlot = slots.get(index);
if (sourceSlot == null || !sourceSlot.hasItem()) return ItemStack.EMPTY; //EMPTY_ITEM
ItemStack sourceStack = sourceSlot.getItem();
ItemStack copyOfSourceStack = sourceStack.copy();
// Check if the slot clicked is one of the vanilla container slots
if (index < VANILLA_FIRST_SLOT_INDEX + VANILLA_SLOT_COUNT) {
// This is a vanilla container slot so merge the stack into the tile inventory
if (!moveItemStackTo(sourceStack, TE_INVENTORY_FIRST_SLOT_INDEX, TE_INVENTORY_FIRST_SLOT_INDEX
+ TE_INVENTORY_SLOT_COUNT, false)) {
return ItemStack.EMPTY; // EMPTY_ITEM
}
} else if (index < TE_INVENTORY_FIRST_SLOT_INDEX + TE_INVENTORY_SLOT_COUNT) {
// This is a TE slot so merge the stack into the players inventory
if (!moveItemStackTo(sourceStack, VANILLA_FIRST_SLOT_INDEX, VANILLA_FIRST_SLOT_INDEX + VANILLA_SLOT_COUNT, false)) {
return ItemStack.EMPTY;
}
} else {
System.out.println("Invalid slotIndex:" + index);
return ItemStack.EMPTY;
}
// If stack size == 0 (the entire stack was moved) set slot contents to null
if (sourceStack.getCount() == 0) {
sourceSlot.set(ItemStack.EMPTY);
} else {
sourceSlot.setChanged();
}
sourceSlot.onTake(playerIn, sourceStack);
return copyOfSourceStack;
}
}

View file

@ -0,0 +1,124 @@
package xyz.nuark.enchantrium.screen;
import com.mojang.blaze3d.systems.RenderSystem;
import com.mojang.blaze3d.vertex.PoseStack;
import net.minecraft.client.Minecraft;
import net.minecraft.client.gui.components.Button;
import net.minecraft.client.gui.screens.inventory.AbstractContainerScreen;
import net.minecraft.client.renderer.GameRenderer;
import net.minecraft.network.chat.Component;
import net.minecraft.network.chat.TextComponent;
import net.minecraft.network.chat.TranslatableComponent;
import net.minecraft.network.protocol.game.ServerboundContainerButtonClickPacket;
import net.minecraft.resources.ResourceLocation;
import net.minecraft.world.entity.player.Inventory;
import net.minecraftforge.network.NetworkHooks;
import org.jetbrains.annotations.NotNull;
import xyz.nuark.enchantrium.Enchantrium;
import xyz.nuark.enchantrium.network.Networking;
import xyz.nuark.enchantrium.network.message.PacketEnchantItem;
import xyz.nuark.enchantrium.screen.widget.Label;
public class EnchanterScreen extends AbstractContainerScreen<EnchanterMenu> {
private static final ResourceLocation TEXTURE =
new ResourceLocation(Enchantrium.MOD_ID, "textures/gui/enchanter_gui.png");
private Label currentEnchantmentLabel;
private Button enchantBtn;
private Button nextBtn;
private Button prevBtn;
private Button increaseLevelBtn;
private Button decreaseLevelBtn;
public EnchanterScreen(EnchanterMenu enchanterMenu, Inventory inventory, Component title) {
super(enchanterMenu, inventory, title);
}
@Override
protected void init() {
super.init();
currentEnchantmentLabel = new Label(
new TextComponent(""),
width / 2, height / 2 + 80, 0xFFFFFF, true
);
enchantBtn = new Button(
width / 2 - 50, height / 2 + 100, 100, 20,
new TextComponent("Enchant"),
button -> clickButton(0)
);
nextBtn = new Button(
width / 2 + 60, height / 2 + 100, 20, 20,
new TextComponent("\u2192"),
button -> clickButton(1)
);
prevBtn = new Button(
width / 2 - 80, height / 2 + 100, 20, 20,
new TextComponent("\u2190"),
button -> clickButton(2)
);
increaseLevelBtn = new Button(
width / 2 + 90, height / 2 + 100, 20, 10,
new TextComponent("\u2191"),
button -> clickButton(3)
);
decreaseLevelBtn = new Button(
width / 2 + 90, height / 2 + 110, 20, 10,
new TextComponent("\u2193"),
button -> clickButton(4)
);
addRenderableWidget(enchantBtn);
addRenderableWidget(nextBtn);
addRenderableWidget(prevBtn);
addRenderableWidget(increaseLevelBtn);
addRenderableWidget(decreaseLevelBtn);
addRenderableOnly(currentEnchantmentLabel);
}
private void clickButton(int buttonId) {
assert Minecraft.getInstance().player != null;
menu.clickMenuButton(Minecraft.getInstance().player, buttonId);
}
@Override
protected void renderBg(@NotNull PoseStack pPoseStack, float pPartialTick, int pMouseX, int pMouseY) {
RenderSystem.setShader(GameRenderer::getPositionTexShader);
RenderSystem.setShaderColor(1.0F, 1.0F, 1.0F, 1.0F);
RenderSystem.setShaderTexture(0, TEXTURE);
int x = (width - imageWidth) / 2;
int y = (height - imageHeight) / 2;
this.blit(pPoseStack, x, y, 0, 0, imageWidth, imageHeight);
}
@Override
public void render(@NotNull PoseStack pPoseStack, int mouseX, int mouseY, float delta) {
renderBackground(pPoseStack);
super.render(pPoseStack, mouseX, mouseY, delta);
renderTooltip(pPoseStack, mouseX, mouseY);
var enchantmentInstance = menu.getCurrentEnchantment();
if (enchantmentInstance != null) {
var enchantment = enchantmentInstance.enchantment;
var level = enchantmentInstance.level;
Component description;
if (level == 0) {
description = new TranslatableComponent(enchantment.getDescriptionId());
} else {
description = enchantment.getFullname(level);
}
currentEnchantmentLabel.setText(description);
} else {
currentEnchantmentLabel.setText(new TextComponent("No enchantment selected"));
}
enchantBtn.active = enchantmentInstance != null;
nextBtn.active = enchantmentInstance != null;
prevBtn.active = enchantmentInstance != null;
increaseLevelBtn.active = enchantmentInstance != null;
decreaseLevelBtn.active = enchantmentInstance != null;
}
}

View file

@ -14,6 +14,10 @@ public class ModMenuTypes {
public static final DeferredRegister<MenuType<?>> MENUS = public static final DeferredRegister<MenuType<?>> MENUS =
DeferredRegister.create(ForgeRegistries.CONTAINERS, Enchantrium.MOD_ID); DeferredRegister.create(ForgeRegistries.CONTAINERS, Enchantrium.MOD_ID);
public static final RegistryObject<MenuType<EnchanterMenu>> ENCHANTER_MENU = registerMenuType(
EnchanterMenu::new, "enchanter_menu"
);
private static <T extends AbstractContainerMenu> RegistryObject<MenuType<T>> registerMenuType(IContainerFactory<T> factory, String name) { private static <T extends AbstractContainerMenu> RegistryObject<MenuType<T>> registerMenuType(IContainerFactory<T> factory, String name) {
return MENUS.register(name, () -> IForgeMenuType.create(factory)); return MENUS.register(name, () -> IForgeMenuType.create(factory));
} }

View file

@ -0,0 +1,22 @@
package xyz.nuark.enchantrium.screen.slot;
import net.minecraft.world.item.ItemStack;
import net.minecraftforge.items.IItemHandler;
import net.minecraftforge.items.SlotItemHandler;
import org.jetbrains.annotations.NotNull;
import java.util.function.Predicate;
public class FilteredSlot extends SlotItemHandler {
Predicate<ItemStack> filter;
public FilteredSlot(IItemHandler itemHandler, int index, int xPosition, int yPosition, Predicate<ItemStack> filter) {
super(itemHandler, index, xPosition, yPosition);
this.filter = filter;
}
@Override
public boolean mayPlace(@NotNull ItemStack stack) {
return filter.test(stack);
}
}

View file

@ -0,0 +1,44 @@
package xyz.nuark.enchantrium.screen.widget;
import com.mojang.blaze3d.vertex.PoseStack;
import net.minecraft.client.Minecraft;
import net.minecraft.client.gui.GuiComponent;
import net.minecraft.client.gui.components.Widget;
import net.minecraft.network.chat.Component;
import net.minecraft.network.chat.MutableComponent;
import net.minecraftforge.api.distmarker.Dist;
import net.minecraftforge.api.distmarker.OnlyIn;
import org.jetbrains.annotations.NotNull;
@OnlyIn(Dist.CLIENT)
public class Label implements Widget {
private Component text;
private final int x;
private final int y;
private final int color;
private final boolean centered;
public Label(Component p_120736_, int p_120737_, int p_120738_, int p_120739_, boolean centered) {
this.text = p_120736_.copy();
this.x = p_120737_;
this.y = p_120738_;
this.color = p_120739_;
this.centered = centered;
}
public void render(@NotNull PoseStack p_175036_, int p_175037_, int p_175038_, float p_175039_) {
if (centered) {
GuiComponent.drawCenteredString(p_175036_, Minecraft.getInstance().font, this.text, this.x, this.y, this.color);
} else {
GuiComponent.drawString(p_175036_, Minecraft.getInstance().font, this.text, this.x, this.y, this.color);
}
}
public void setText(Component p_175041_) {
this.text = p_175041_;
}
public Component getText() {
return this.text;
}
}

View file

@ -0,0 +1,15 @@
package xyz.nuark.enchantrium.setup;
import net.minecraft.client.gui.screens.MenuScreens;
import net.minecraftforge.eventbus.api.Event;
import net.minecraftforge.fml.event.lifecycle.FMLClientSetupEvent;
import xyz.nuark.enchantrium.screen.EnchanterScreen;
import xyz.nuark.enchantrium.screen.ModMenuTypes;
public class ClientSetup {
public static void init(final FMLClientSetupEvent event) {
event.enqueueWork(() -> {
MenuScreens.register(ModMenuTypes.ENCHANTER_MENU.get(), EnchanterScreen::new);
});
}
}

View file

@ -0,0 +1,30 @@
package xyz.nuark.enchantrium.setup;
import net.minecraft.world.item.CreativeModeTab;
import net.minecraft.world.item.ItemStack;
import net.minecraftforge.common.MinecraftForge;
import net.minecraftforge.eventbus.api.IEventBus;
import net.minecraftforge.fml.common.Mod;
import net.minecraftforge.fml.event.lifecycle.FMLCommonSetupEvent;
import org.jetbrains.annotations.NotNull;
import xyz.nuark.enchantrium.Enchantrium;
import xyz.nuark.enchantrium.item.ModItems;
import xyz.nuark.enchantrium.network.Networking;
@Mod.EventBusSubscriber(modid = Enchantrium.MOD_ID, bus = Mod.EventBusSubscriber.Bus.MOD)
public class ModSetup {
public static final CreativeModeTab ITEM_GROUP = new CreativeModeTab(Enchantrium.MOD_ID) {
@Override
public @NotNull ItemStack makeIcon() {
return new ItemStack(ModItems.TEST_ITEM.get());
}
};
public static void setup() {
IEventBus bus = MinecraftForge.EVENT_BUS;
}
public static void init(FMLCommonSetupEvent event) {
Networking.register();
}
}

View file

@ -0,0 +1,16 @@
package xyz.nuark.enchantrium.setup;
import net.minecraftforge.eventbus.api.IEventBus;
import xyz.nuark.enchantrium.block.ModBlocks;
import xyz.nuark.enchantrium.block.entity.ModBlockEntities;
import xyz.nuark.enchantrium.item.ModItems;
import xyz.nuark.enchantrium.screen.ModMenuTypes;
public class Registration {
public static void register(IEventBus eventBus) {
ModItems.register(eventBus);
ModBlocks.register(eventBus);
ModBlockEntities.register(eventBus);
ModMenuTypes.register(eventBus);
}
}

View file

@ -0,0 +1,27 @@
package xyz.nuark.enchantrium.util;
import com.google.common.collect.Lists;
import net.minecraft.world.item.ItemStack;
import net.minecraft.world.item.enchantment.Enchantment;
import net.minecraft.world.item.enchantment.EnchantmentInstance;
import net.minecraftforge.registries.ForgeRegistries;
import java.util.List;
public class EnchantmentUtil {
public static boolean canBeEnchanted(ItemStack stack) {
return stack.getItem().isEnchantable(stack);
}
public static List<EnchantmentInstance> getApplicableEnchantments(ItemStack itemStack) {
List<EnchantmentInstance> list = Lists.newArrayList();
for (Enchantment enchantment : ForgeRegistries.ENCHANTMENTS) {
if (enchantment.canEnchant(itemStack) && !enchantment.isCurse()) {
list.add(new EnchantmentInstance(enchantment, 0));
}
}
return list;
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 991 B