mirror of
https://github.com/PaperMC/Paper.git
synced 2025-03-23 23:39:34 +01:00
Allow For Default Titles in InventoryView Builders (#12013)
This commit is contained in:
parent
84609dc046
commit
8eb8e44ac3
18 changed files with 201 additions and 70 deletions
paper-api/src/main/java/org/bukkit/inventory
MenuType.java
view/builder
paper-server
patches/sources/net/minecraft/world/level/block
src/main/java/org/bukkit/craftbukkit
CraftServer.java
inventory
CraftMenuType.javaCraftMerchantCustom.java
util
view/builder
CraftAbstractInventoryViewBuilder.javaCraftAbstractLocationInventoryViewBuilder.javaCraftAccessLocationInventoryViewBuilder.javaCraftBlockEntityInventoryViewBuilder.javaCraftDoubleChestInventoryViewBuilder.javaCraftEnchantmentInventoryViewBuilder.javaCraftMerchantInventoryViewBuilder.javaCraftStandardInventoryViewBuilder.java
|
@ -1,5 +1,6 @@
|
|||
package org.bukkit.inventory;
|
||||
|
||||
import net.kyori.adventure.text.Component;
|
||||
import org.bukkit.Keyed;
|
||||
import org.bukkit.NamespacedKey;
|
||||
import org.bukkit.Registry;
|
||||
|
@ -18,12 +19,14 @@ import org.bukkit.inventory.view.builder.InventoryViewBuilder;
|
|||
import org.bukkit.inventory.view.builder.LocationInventoryViewBuilder;
|
||||
import org.bukkit.inventory.view.builder.MerchantInventoryViewBuilder;
|
||||
import org.jetbrains.annotations.ApiStatus;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jspecify.annotations.NullMarked;
|
||||
import org.jspecify.annotations.Nullable;
|
||||
|
||||
/**
|
||||
* Represents different kinds of views, also known as menus, which can be
|
||||
* created and viewed by the player.
|
||||
*/
|
||||
@NullMarked
|
||||
@ApiStatus.Experimental
|
||||
public interface MenuType extends Keyed, io.papermc.paper.world.flag.FeatureDependant { // Paper - make FeatureDependant
|
||||
|
||||
|
@ -138,6 +141,20 @@ public interface MenuType extends Keyed, io.papermc.paper.world.flag.FeatureDepe
|
|||
*/
|
||||
interface Typed<V extends InventoryView, B extends InventoryViewBuilder<V>> extends MenuType {
|
||||
|
||||
/**
|
||||
* Creates a view of the specified menu type.
|
||||
* <p>
|
||||
* The player provided to create this view must be the player the view
|
||||
* is opened for. See {@link HumanEntity#openInventory(InventoryView)}
|
||||
* for more information.
|
||||
*
|
||||
* @param player the player the view belongs to
|
||||
* @return the created {@link InventoryView}
|
||||
*/
|
||||
default V create(HumanEntity player) {
|
||||
return create(player, (Component) null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a view of the specified menu type.
|
||||
* <p>
|
||||
|
@ -148,11 +165,10 @@ public interface MenuType extends Keyed, io.papermc.paper.world.flag.FeatureDepe
|
|||
* @param player the player the view belongs to
|
||||
* @param title the title of the view
|
||||
* @return the created {@link InventoryView}
|
||||
* @deprecated Use {@link #create(HumanEntity, net.kyori.adventure.text.Component)} instead.
|
||||
* @deprecated Use {@link #create(HumanEntity, Component)} instead.
|
||||
*/
|
||||
@NotNull
|
||||
@Deprecated(since = "1.21") // Paper - adventure
|
||||
V create(@NotNull HumanEntity player, @NotNull String title);
|
||||
V create(HumanEntity player, @Nullable String title);
|
||||
|
||||
// Paper start - adventure
|
||||
/**
|
||||
|
@ -166,11 +182,9 @@ public interface MenuType extends Keyed, io.papermc.paper.world.flag.FeatureDepe
|
|||
* @param title the title of the view
|
||||
* @return the created {@link InventoryView}
|
||||
*/
|
||||
@NotNull
|
||||
V create(@NotNull HumanEntity player, @NotNull net.kyori.adventure.text.Component title);
|
||||
V create(HumanEntity player, @Nullable Component title);
|
||||
// Paper end - adventure
|
||||
|
||||
@NotNull
|
||||
B builder();
|
||||
}
|
||||
|
||||
|
@ -186,8 +200,7 @@ public interface MenuType extends Keyed, io.papermc.paper.world.flag.FeatureDepe
|
|||
* @param title the title of the view
|
||||
* @return the created {@link InventoryView}
|
||||
*/
|
||||
@NotNull
|
||||
InventoryView create(@NotNull HumanEntity player, @NotNull net.kyori.adventure.text.Component title);
|
||||
InventoryView create(HumanEntity player, @Nullable Component title);
|
||||
// Paper end - adventure
|
||||
|
||||
/**
|
||||
|
@ -196,7 +209,6 @@ public interface MenuType extends Keyed, io.papermc.paper.world.flag.FeatureDepe
|
|||
*
|
||||
* @return the typed MenuType.
|
||||
*/
|
||||
@NotNull
|
||||
MenuType.Typed<InventoryView, InventoryViewBuilder<InventoryView>> typed();
|
||||
|
||||
/**
|
||||
|
@ -213,19 +225,16 @@ public interface MenuType extends Keyed, io.papermc.paper.world.flag.FeatureDepe
|
|||
* @throws IllegalArgumentException if the provided viewClass cannot be
|
||||
* typed to this MenuType
|
||||
*/
|
||||
@NotNull
|
||||
<V extends InventoryView, B extends InventoryViewBuilder<V>> MenuType.Typed<V, B> typed(@NotNull final Class<V> viewClass) throws IllegalArgumentException;
|
||||
<V extends InventoryView, B extends InventoryViewBuilder<V>> MenuType.Typed<V, B> typed(final Class<V> viewClass) throws IllegalArgumentException;
|
||||
|
||||
/**
|
||||
* Gets the {@link InventoryView} class of this MenuType.
|
||||
*
|
||||
* @return the {@link InventoryView} class of this MenuType
|
||||
*/
|
||||
@NotNull
|
||||
Class<? extends InventoryView> getInventoryViewClass();
|
||||
|
||||
@NotNull
|
||||
private static <T extends MenuType> T get(@NotNull final String key) {
|
||||
private static <T extends MenuType> T get(final String key) {
|
||||
return (T) Registry.MENU.getOrThrow(NamespacedKey.minecraft(key));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -4,6 +4,7 @@ import net.kyori.adventure.text.Component;
|
|||
import org.bukkit.entity.HumanEntity;
|
||||
import org.bukkit.inventory.InventoryView;
|
||||
import org.jetbrains.annotations.ApiStatus;
|
||||
import org.jspecify.annotations.Nullable;
|
||||
|
||||
/**
|
||||
* Generic Builder for InventoryView's with no special attributes or parameters
|
||||
|
@ -23,10 +24,10 @@ public interface InventoryViewBuilder<V extends InventoryView> {
|
|||
/**
|
||||
* Sets the title of the builder
|
||||
*
|
||||
* @param title the title
|
||||
* @param title the title, or null for a default title
|
||||
* @return this builder
|
||||
*/
|
||||
InventoryViewBuilder<V> title(final Component title);
|
||||
InventoryViewBuilder<V> title(@Nullable final Component title);
|
||||
|
||||
/**
|
||||
* Builds this builder into a InventoryView
|
||||
|
|
|
@ -4,7 +4,7 @@ import net.kyori.adventure.text.Component;
|
|||
import org.bukkit.Location;
|
||||
import org.bukkit.inventory.InventoryView;
|
||||
import org.jetbrains.annotations.ApiStatus;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jspecify.annotations.Nullable;
|
||||
|
||||
/**
|
||||
* An InventoryViewBuilder that can be bound by location within the world
|
||||
|
@ -18,7 +18,7 @@ public interface LocationInventoryViewBuilder<V extends InventoryView> extends I
|
|||
LocationInventoryViewBuilder<V> copy();
|
||||
|
||||
@Override
|
||||
LocationInventoryViewBuilder<V> title(final @NotNull Component title);
|
||||
LocationInventoryViewBuilder<V> title(final @Nullable Component title);
|
||||
|
||||
/**
|
||||
* Determines whether or not the server should check if the player can reach
|
||||
|
|
|
@ -5,7 +5,7 @@ import org.bukkit.Server;
|
|||
import org.bukkit.inventory.InventoryView;
|
||||
import org.bukkit.inventory.Merchant;
|
||||
import org.jetbrains.annotations.ApiStatus;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jspecify.annotations.Nullable;
|
||||
|
||||
/**
|
||||
* An InventoryViewBuilder for creating merchant views
|
||||
|
@ -19,7 +19,7 @@ public interface MerchantInventoryViewBuilder<V extends InventoryView> extends I
|
|||
MerchantInventoryViewBuilder<V> copy();
|
||||
|
||||
@Override
|
||||
MerchantInventoryViewBuilder<V> title(final @NotNull Component title);
|
||||
MerchantInventoryViewBuilder<V> title(final @Nullable Component title);
|
||||
|
||||
/**
|
||||
* Adds a merchant to this builder
|
||||
|
|
|
@ -9,8 +9,12 @@
|
|||
@Nullable
|
||||
@Override
|
||||
public AbstractContainerMenu createMenu(int containerId, Inventory playerInventory, Player player) {
|
||||
@@ -106,7 +_,7 @@
|
||||
return (Component)(second.hasCustomName() ? second.getDisplayName() : Component.translatable("container.chestDouble"));
|
||||
@@ -103,10 +_,10 @@
|
||||
if (first.hasCustomName()) {
|
||||
return first.getDisplayName();
|
||||
} else {
|
||||
- return (Component)(second.hasCustomName() ? second.getDisplayName() : Component.translatable("container.chestDouble"));
|
||||
+ return (Component)(second.hasCustomName() ? second.getDisplayName() : Component.translatable("container.chestDouble")); // Paper - diff on change - CraftDoubleChestInventoryViewBuilder.defaultTitle
|
||||
}
|
||||
}
|
||||
- });
|
||||
|
|
|
@ -37,3 +37,12 @@
|
|||
protected ChestBlockEntity(BlockEntityType<?> type, BlockPos pos, BlockState blockState) {
|
||||
super(type, pos, blockState);
|
||||
}
|
||||
@@ -71,7 +_,7 @@
|
||||
|
||||
@Override
|
||||
protected Component getDefaultName() {
|
||||
- return Component.translatable("container.chest");
|
||||
+ return Component.translatable("container.chest"); // Paper - diff on change - CraftStandardInventoryViewBuilder.defaultTitle
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -2479,7 +2479,7 @@ public final class CraftServer implements Server {
|
|||
|
||||
@Override
|
||||
public @NotNull Merchant createMerchant() {
|
||||
return new CraftMerchantCustom(net.kyori.adventure.text.Component.empty());
|
||||
return new CraftMerchantCustom();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -38,7 +38,7 @@ public class CraftMenuType<V extends InventoryView, B extends InventoryViewBuild
|
|||
@Override
|
||||
public V create(final HumanEntity player, final String title) {
|
||||
// Paper start - adventure
|
||||
return builder().title(net.kyori.adventure.text.serializer.legacy.LegacyComponentSerializer.legacySection().deserialize(title)).build(player);
|
||||
return builder().title(title != null ? net.kyori.adventure.text.serializer.legacy.LegacyComponentSerializer.legacySection().deserialize(title) : null).build(player);
|
||||
}
|
||||
@Override
|
||||
public V create(final HumanEntity player, final net.kyori.adventure.text.Component title) {
|
||||
|
|
|
@ -4,6 +4,7 @@ import com.google.common.base.Preconditions;
|
|||
import net.minecraft.network.chat.Component;
|
||||
import net.minecraft.sounds.SoundEvent;
|
||||
import net.minecraft.sounds.SoundEvents;
|
||||
import net.minecraft.world.entity.EntityType;
|
||||
import net.minecraft.world.entity.player.Player;
|
||||
import net.minecraft.world.item.ItemStack;
|
||||
import net.minecraft.world.item.trading.Merchant;
|
||||
|
@ -25,6 +26,11 @@ public class CraftMerchantCustom implements CraftMerchant {
|
|||
this.merchant = new MinecraftMerchant(title);
|
||||
getMerchant().craftMerchant = this;
|
||||
}
|
||||
|
||||
public CraftMerchantCustom() {
|
||||
this.merchant = new MinecraftMerchant();
|
||||
getMerchant().craftMerchant = this;
|
||||
}
|
||||
// Paper end
|
||||
|
||||
@Override
|
||||
|
@ -54,6 +60,10 @@ public class CraftMerchantCustom implements CraftMerchant {
|
|||
Preconditions.checkArgument(title != null, "Title cannot be null");
|
||||
this.title = io.papermc.paper.adventure.PaperAdventure.asVanilla(title);
|
||||
}
|
||||
|
||||
public MinecraftMerchant() {
|
||||
this.title = EntityType.VILLAGER.getDescription();
|
||||
}
|
||||
// Paper end
|
||||
|
||||
@Override
|
||||
|
|
|
@ -17,6 +17,7 @@ import net.minecraft.world.level.block.Blocks;
|
|||
import net.minecraft.world.level.block.entity.BeaconBlockEntity;
|
||||
import net.minecraft.world.level.block.entity.BlastFurnaceBlockEntity;
|
||||
import net.minecraft.world.level.block.entity.BrewingStandBlockEntity;
|
||||
import net.minecraft.world.level.block.entity.ChestBlockEntity;
|
||||
import net.minecraft.world.level.block.entity.CrafterBlockEntity;
|
||||
import net.minecraft.world.level.block.entity.DispenserBlockEntity;
|
||||
import net.minecraft.world.level.block.entity.FurnaceBlockEntity;
|
||||
|
@ -29,6 +30,7 @@ import org.bukkit.craftbukkit.inventory.CraftMerchant;
|
|||
import org.bukkit.craftbukkit.inventory.view.builder.CraftAccessLocationInventoryViewBuilder;
|
||||
import org.bukkit.craftbukkit.inventory.view.builder.CraftBlockEntityInventoryViewBuilder;
|
||||
import org.bukkit.craftbukkit.inventory.view.builder.CraftDoubleChestInventoryViewBuilder;
|
||||
import org.bukkit.craftbukkit.inventory.view.builder.CraftEnchantmentInventoryViewBuilder;
|
||||
import org.bukkit.craftbukkit.inventory.view.builder.CraftMerchantInventoryViewBuilder;
|
||||
import org.bukkit.craftbukkit.inventory.view.builder.CraftStandardInventoryViewBuilder;
|
||||
import org.bukkit.inventory.InventoryView;
|
||||
|
@ -87,7 +89,7 @@ public final class CraftMenus {
|
|||
return asType(new MenuTypeData<>(InventoryView.class, () -> new CraftDoubleChestInventoryViewBuilder<>(handle)));
|
||||
}
|
||||
if (menuType == MenuType.GENERIC_9X3) {
|
||||
return asType(new MenuTypeData<>(InventoryView.class, () -> new CraftBlockEntityInventoryViewBuilder<>(handle, Blocks.CHEST, null)));
|
||||
return asType(new MenuTypeData<>(InventoryView.class, () -> new CraftBlockEntityInventoryViewBuilder<>(handle, Blocks.CHEST, ChestBlockEntity::new, false)));
|
||||
}
|
||||
// this isn't ideal as both dispenser and dropper are 3x3, InventoryType can't currently handle generic 3x3s with size 9
|
||||
// this needs to be removed when inventory creation is overhauled
|
||||
|
@ -98,7 +100,7 @@ public final class CraftMenus {
|
|||
return asType(new MenuTypeData<>(CrafterView.class, () -> new CraftBlockEntityInventoryViewBuilder<>(handle, Blocks.CRAFTER, CrafterBlockEntity::new)));
|
||||
}
|
||||
if (menuType == MenuType.ANVIL) {
|
||||
return asType(new MenuTypeData<>(AnvilView.class, () -> new CraftAccessLocationInventoryViewBuilder<>(handle, AnvilMenu::new)));
|
||||
return asType(new MenuTypeData<>(AnvilView.class, () -> new CraftAccessLocationInventoryViewBuilder<>(handle, Blocks.ANVIL)));
|
||||
}
|
||||
if (menuType == MenuType.BEACON) {
|
||||
return asType(new MenuTypeData<>(BeaconView.class, () -> new CraftBlockEntityInventoryViewBuilder<>(handle, Blocks.BEACON, BeaconBlockEntity::new)));
|
||||
|
@ -110,16 +112,16 @@ public final class CraftMenus {
|
|||
return asType(new MenuTypeData<>(BrewingStandView.class, () -> new CraftBlockEntityInventoryViewBuilder<>(handle, Blocks.BREWING_STAND, BrewingStandBlockEntity::new)));
|
||||
}
|
||||
if (menuType == MenuType.CRAFTING) {
|
||||
return asType(new MenuTypeData<>(InventoryView.class, () -> new CraftAccessLocationInventoryViewBuilder<>(handle, CraftingMenu::new)));
|
||||
return asType(new MenuTypeData<>(InventoryView.class, () -> new CraftAccessLocationInventoryViewBuilder<>(handle, Blocks.CRAFTING_TABLE)));
|
||||
}
|
||||
if (menuType == MenuType.ENCHANTMENT) {
|
||||
return asType(new MenuTypeData<>(EnchantmentView.class, () -> new CraftAccessLocationInventoryViewBuilder<>(handle, EnchantmentMenu::new)));
|
||||
return asType(new MenuTypeData<>(EnchantmentView.class, () -> new CraftEnchantmentInventoryViewBuilder(handle)));
|
||||
}
|
||||
if (menuType == MenuType.FURNACE) {
|
||||
return asType(new MenuTypeData<>(FurnaceView.class, () -> new CraftBlockEntityInventoryViewBuilder<>(handle, Blocks.FURNACE, FurnaceBlockEntity::new)));
|
||||
}
|
||||
if (menuType == MenuType.GRINDSTONE) {
|
||||
return asType(new MenuTypeData<>(InventoryView.class, () -> new CraftAccessLocationInventoryViewBuilder<>(handle, GrindstoneMenu::new)));
|
||||
return asType(new MenuTypeData<>(InventoryView.class, () -> new CraftAccessLocationInventoryViewBuilder<>(handle, Blocks.GRINDSTONE)));
|
||||
}
|
||||
// We really don't need to be creating a tile entity for hopper but currently InventoryType doesn't have capacity
|
||||
// to understand otherwise
|
||||
|
@ -131,7 +133,7 @@ public final class CraftMenus {
|
|||
return asType(new MenuTypeData<>(LecternView.class, () -> new CraftBlockEntityInventoryViewBuilder<>(handle, Blocks.LECTERN, LecternBlockEntity::new)));
|
||||
}
|
||||
if (menuType == MenuType.LOOM) {
|
||||
return asType(new MenuTypeData<>(LoomView.class, () -> new CraftStandardInventoryViewBuilder<>(handle)));
|
||||
return asType(new MenuTypeData<>(LoomView.class, () -> new CraftAccessLocationInventoryViewBuilder<>(handle, Blocks.LOOM)));
|
||||
}
|
||||
if (menuType == MenuType.MERCHANT) {
|
||||
return asType(new MenuTypeData<>(MerchantView.class, () -> new CraftMerchantInventoryViewBuilder<>(handle)));
|
||||
|
@ -140,16 +142,16 @@ public final class CraftMenus {
|
|||
return asType(new MenuTypeData<>(InventoryView.class, () -> new CraftBlockEntityInventoryViewBuilder<>(handle, Blocks.SHULKER_BOX, ShulkerBoxBlockEntity::new)));
|
||||
}
|
||||
if (menuType == MenuType.SMITHING) {
|
||||
return asType(new MenuTypeData<>(InventoryView.class, () -> new CraftAccessLocationInventoryViewBuilder<>(handle, SmithingMenu::new)));
|
||||
return asType(new MenuTypeData<>(InventoryView.class, () -> new CraftAccessLocationInventoryViewBuilder<>(handle, Blocks.SMITHING_TABLE)));
|
||||
}
|
||||
if (menuType == MenuType.SMOKER) {
|
||||
return asType(new MenuTypeData<>(FurnaceView.class, () -> new CraftBlockEntityInventoryViewBuilder<>(handle, Blocks.SMOKER, SmokerBlockEntity::new)));
|
||||
}
|
||||
if (menuType == MenuType.CARTOGRAPHY_TABLE) {
|
||||
return asType(new MenuTypeData<>(InventoryView.class, () -> new CraftAccessLocationInventoryViewBuilder<>(handle, CartographyTableMenu::new)));
|
||||
return asType(new MenuTypeData<>(InventoryView.class, () -> new CraftAccessLocationInventoryViewBuilder<>(handle, Blocks.CARTOGRAPHY_TABLE)));
|
||||
}
|
||||
if (menuType == MenuType.STONECUTTER) {
|
||||
return asType(new MenuTypeData<>(StonecutterView.class, () -> new CraftAccessLocationInventoryViewBuilder<>(handle, StonecutterMenu::new)));
|
||||
return asType(new MenuTypeData<>(StonecutterView.class, () -> new CraftAccessLocationInventoryViewBuilder<>(handle, Blocks.STONECUTTER)));
|
||||
}
|
||||
|
||||
return asType(new MenuTypeData<>(InventoryView.class, () -> new CraftStandardInventoryViewBuilder<>(handle)));
|
||||
|
|
|
@ -10,21 +10,22 @@ import org.bukkit.craftbukkit.entity.CraftHumanEntity;
|
|||
import org.bukkit.entity.HumanEntity;
|
||||
import org.bukkit.inventory.InventoryView;
|
||||
import org.bukkit.inventory.view.builder.InventoryViewBuilder;
|
||||
import org.checkerframework.checker.nullness.qual.MonotonicNonNull;
|
||||
import org.jspecify.annotations.Nullable;
|
||||
|
||||
public abstract class CraftAbstractInventoryViewBuilder<V extends InventoryView> implements InventoryViewBuilder<V> {
|
||||
|
||||
protected final MenuType<?> handle;
|
||||
|
||||
protected boolean checkReachable = false;
|
||||
protected @MonotonicNonNull Component title = null;
|
||||
protected @Nullable Component title = null;
|
||||
protected net.minecraft.network.chat.Component defaultTitle = null;
|
||||
|
||||
public CraftAbstractInventoryViewBuilder(final MenuType<?> handle) {
|
||||
this.handle = handle;
|
||||
}
|
||||
|
||||
@Override
|
||||
public InventoryViewBuilder<V> title(final Component title) {
|
||||
public InventoryViewBuilder<V> title(final @Nullable Component title) {
|
||||
this.title = title;
|
||||
return this;
|
||||
}
|
||||
|
@ -33,14 +34,14 @@ public abstract class CraftAbstractInventoryViewBuilder<V extends InventoryView>
|
|||
@Override
|
||||
public V build(final HumanEntity player) {
|
||||
Preconditions.checkArgument(player != null, "The given player must not be null");
|
||||
Preconditions.checkArgument(this.title != null, "The given title must not be null");
|
||||
Preconditions.checkArgument(player instanceof CraftHumanEntity, "The given player must be a CraftHumanEntity");
|
||||
final CraftHumanEntity craftHuman = (CraftHumanEntity) player;
|
||||
Preconditions.checkArgument(craftHuman.getHandle() instanceof ServerPlayer, "The given player must be an EntityPlayer");
|
||||
Preconditions.checkArgument(craftHuman.getHandle() instanceof ServerPlayer, "The given player must be an ServerPlayer");
|
||||
final ServerPlayer serverPlayer = (ServerPlayer) craftHuman.getHandle();
|
||||
|
||||
final AbstractContainerMenu container = buildContainer(serverPlayer);
|
||||
container.checkReachable = this.checkReachable;
|
||||
container.setTitle(PaperAdventure.asVanilla(this.title));
|
||||
container.setTitle(this.title != null ? PaperAdventure.asVanilla(this.title) : this.defaultTitle);
|
||||
return (V) container.getBukkitView();
|
||||
}
|
||||
|
||||
|
|
|
@ -22,7 +22,7 @@ public abstract class CraftAbstractLocationInventoryViewBuilder<V extends Invent
|
|||
}
|
||||
|
||||
@Override
|
||||
public LocationInventoryViewBuilder<V> title(final Component title) {
|
||||
public LocationInventoryViewBuilder<V> title(final @Nullable Component title) {
|
||||
return (LocationInventoryViewBuilder<V>) super.title(title);
|
||||
}
|
||||
|
||||
|
|
|
@ -1,37 +1,50 @@
|
|||
package org.bukkit.craftbukkit.inventory.view.builder;
|
||||
|
||||
import net.minecraft.core.BlockPos;
|
||||
import net.minecraft.server.level.ServerPlayer;
|
||||
import net.minecraft.world.MenuProvider;
|
||||
import net.minecraft.world.entity.player.Inventory;
|
||||
import net.minecraft.world.inventory.AbstractContainerMenu;
|
||||
import net.minecraft.world.inventory.ContainerLevelAccess;
|
||||
import net.minecraft.world.inventory.MenuType;
|
||||
import net.minecraft.world.level.Level;
|
||||
import net.minecraft.world.level.block.Block;
|
||||
import net.minecraft.world.level.block.state.BlockState;
|
||||
import org.bukkit.inventory.InventoryView;
|
||||
import org.bukkit.inventory.view.builder.LocationInventoryViewBuilder;
|
||||
|
||||
public class CraftAccessLocationInventoryViewBuilder<V extends InventoryView> extends CraftAbstractLocationInventoryViewBuilder<V> {
|
||||
|
||||
private final CraftAccessContainerObjectBuilder containerBuilder;
|
||||
private final Block block;
|
||||
|
||||
public CraftAccessLocationInventoryViewBuilder(final MenuType<?> handle, final CraftAccessContainerObjectBuilder containerBuilder) {
|
||||
public CraftAccessLocationInventoryViewBuilder(final MenuType<?> handle, final Block block) {
|
||||
super(handle);
|
||||
this.containerBuilder = containerBuilder;
|
||||
this.block = block;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected AbstractContainerMenu buildContainer(final ServerPlayer player) {
|
||||
final ContainerLevelAccess access;
|
||||
if (super.position == null) {
|
||||
access = ContainerLevelAccess.create(player.level(), player.blockPosition());
|
||||
final BlockState effectiveBlockState;
|
||||
final BlockPos effectiveBlockPos;
|
||||
final Level effectiveLevel;
|
||||
if (super.position != null) {
|
||||
effectiveBlockPos = super.position;
|
||||
effectiveLevel = super.world;
|
||||
effectiveBlockState = super.world.getBlockState(position);
|
||||
} else {
|
||||
access = ContainerLevelAccess.create(super.world, super.position);
|
||||
effectiveBlockPos = player.blockPosition();
|
||||
effectiveLevel = player.level();
|
||||
effectiveBlockState = block.defaultBlockState();
|
||||
}
|
||||
|
||||
return this.containerBuilder.build(player.nextContainerCounter(), player.getInventory(), access);
|
||||
final MenuProvider provider = block.getMenuProvider(effectiveBlockState, effectiveLevel, effectiveBlockPos);
|
||||
super.defaultTitle = provider.getDisplayName();
|
||||
return provider.createMenu(player.nextContainerCounter(), player.getInventory(), player);
|
||||
}
|
||||
|
||||
@Override
|
||||
public LocationInventoryViewBuilder<V> copy() {
|
||||
final CraftAccessLocationInventoryViewBuilder<V> copy = new CraftAccessLocationInventoryViewBuilder<>(this.handle, this.containerBuilder);
|
||||
final CraftAccessLocationInventoryViewBuilder<V> copy = new CraftAccessLocationInventoryViewBuilder<>(this.handle, this.block);
|
||||
copy.world = super.world;
|
||||
copy.position = super.position;
|
||||
copy.checkReachable = super.checkReachable;
|
||||
|
|
|
@ -16,10 +16,25 @@ import org.jspecify.annotations.Nullable;
|
|||
public class CraftBlockEntityInventoryViewBuilder<V extends InventoryView> extends CraftAbstractLocationInventoryViewBuilder<V> {
|
||||
|
||||
private final Block block;
|
||||
private final @Nullable CraftTileInventoryBuilder builder;
|
||||
private final boolean useFakeBlockEntity;
|
||||
private final @Nullable CraftBlockInventoryBuilder builder;
|
||||
|
||||
public CraftBlockEntityInventoryViewBuilder(final MenuType<?> handle, final Block block, final @Nullable CraftTileInventoryBuilder builder) {
|
||||
public CraftBlockEntityInventoryViewBuilder(
|
||||
final MenuType<?> handle,
|
||||
final Block block,
|
||||
final @Nullable CraftBlockInventoryBuilder builder
|
||||
) {
|
||||
this(handle, block, builder, true);
|
||||
}
|
||||
|
||||
public CraftBlockEntityInventoryViewBuilder(
|
||||
final MenuType<?> handle,
|
||||
final Block block,
|
||||
final @Nullable CraftBlockInventoryBuilder builder,
|
||||
final boolean useFakeBlockEntity
|
||||
) {
|
||||
super(handle);
|
||||
this.useFakeBlockEntity = useFakeBlockEntity;
|
||||
this.block = block;
|
||||
this.builder = builder;
|
||||
}
|
||||
|
@ -32,35 +47,44 @@ public class CraftBlockEntityInventoryViewBuilder<V extends InventoryView> exten
|
|||
|
||||
if (this.position == null) {
|
||||
this.position = player.blockPosition();
|
||||
return buildFakeBlockEntity(player);
|
||||
}
|
||||
|
||||
final BlockEntity entity = this.world.getBlockEntity(position);
|
||||
if (!(entity instanceof final MenuConstructor container)) {
|
||||
return buildFakeTile(player);
|
||||
return buildFakeBlockEntity(player);
|
||||
}
|
||||
|
||||
final AbstractContainerMenu atBlock = container.createMenu(player.nextContainerCounter(), player.getInventory(), player);
|
||||
if (atBlock.getType() != super.handle) {
|
||||
return buildFakeTile(player);
|
||||
return buildFakeBlockEntity(player);
|
||||
}
|
||||
|
||||
if (!(entity instanceof final MenuProvider provider)) {
|
||||
throw new IllegalStateException("Provided blockEntity during MenuType creation can not find a default title! This is a bug!");
|
||||
}
|
||||
|
||||
super.defaultTitle = provider.getDisplayName();
|
||||
return atBlock;
|
||||
}
|
||||
|
||||
private AbstractContainerMenu buildFakeTile(final ServerPlayer player) {
|
||||
if (this.builder == null) {
|
||||
private AbstractContainerMenu buildFakeBlockEntity(final ServerPlayer player) {
|
||||
final MenuProvider inventory = this.builder.build(this.position, this.block.defaultBlockState());
|
||||
if (inventory instanceof final BlockEntity blockEntity) {
|
||||
blockEntity.setLevel(this.world);
|
||||
super.defaultTitle = inventory.getDisplayName();
|
||||
}
|
||||
|
||||
if (!this.useFakeBlockEntity) { // gets around open noise for chest
|
||||
return handle.create(player.nextContainerCounter(), player.getInventory());
|
||||
}
|
||||
final MenuProvider inventory = this.builder.build(this.position, this.block.defaultBlockState());
|
||||
if (inventory instanceof final BlockEntity tile) {
|
||||
tile.setLevel(this.world);
|
||||
}
|
||||
|
||||
return inventory.createMenu(player.nextContainerCounter(), player.getInventory(), player);
|
||||
}
|
||||
|
||||
@Override
|
||||
public LocationInventoryViewBuilder<V> copy() {
|
||||
final CraftBlockEntityInventoryViewBuilder<V> copy = new CraftBlockEntityInventoryViewBuilder<>(super.handle, this.block, this.builder);
|
||||
final CraftBlockEntityInventoryViewBuilder<V> copy = new CraftBlockEntityInventoryViewBuilder<>(super.handle, this.block, this.builder, this.useFakeBlockEntity);
|
||||
copy.world = this.world;
|
||||
copy.position = this.position;
|
||||
copy.checkReachable = super.checkReachable;
|
||||
|
@ -68,7 +92,7 @@ public class CraftBlockEntityInventoryViewBuilder<V extends InventoryView> exten
|
|||
return copy;
|
||||
}
|
||||
|
||||
public interface CraftTileInventoryBuilder {
|
||||
public interface CraftBlockInventoryBuilder {
|
||||
MenuProvider build(BlockPos blockPosition, BlockState blockData);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
package org.bukkit.craftbukkit.inventory.view.builder;
|
||||
|
||||
import net.minecraft.network.chat.Component;
|
||||
import net.minecraft.server.level.ServerPlayer;
|
||||
import net.minecraft.world.MenuProvider;
|
||||
import net.minecraft.world.inventory.AbstractContainerMenu;
|
||||
|
@ -15,6 +16,7 @@ public class CraftDoubleChestInventoryViewBuilder<V extends InventoryView> exten
|
|||
|
||||
public CraftDoubleChestInventoryViewBuilder(final MenuType<?> handle) {
|
||||
super(handle);
|
||||
super.defaultTitle = Component.translatable("container.chestDouble");
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -24,7 +26,9 @@ public class CraftDoubleChestInventoryViewBuilder<V extends InventoryView> exten
|
|||
}
|
||||
|
||||
final ChestBlock chest = (ChestBlock) Blocks.CHEST;
|
||||
final DoubleBlockCombiner.NeighborCombineResult<? extends ChestBlockEntity> result = chest.combine(super.world.getBlockState(super.position), super.world, super.position, false);
|
||||
final DoubleBlockCombiner.NeighborCombineResult<? extends ChestBlockEntity> result = chest.combine(
|
||||
super.world.getBlockState(super.position), super.world, super.position, false
|
||||
);
|
||||
if (result instanceof DoubleBlockCombiner.NeighborCombineResult.Single<? extends ChestBlockEntity>) {
|
||||
return handle.create(player.nextContainerCounter(), player.getInventory());
|
||||
}
|
||||
|
@ -33,6 +37,7 @@ public class CraftDoubleChestInventoryViewBuilder<V extends InventoryView> exten
|
|||
if (combined == null) {
|
||||
return handle.create(player.nextContainerCounter(), player.getInventory());
|
||||
}
|
||||
|
||||
return combined.createMenu(player.nextContainerCounter(), player.getInventory(), player);
|
||||
}
|
||||
|
||||
|
|
|
@ -0,0 +1,40 @@
|
|||
package org.bukkit.craftbukkit.inventory.view.builder;
|
||||
|
||||
import net.minecraft.server.level.ServerPlayer;
|
||||
import net.minecraft.world.inventory.AbstractContainerMenu;
|
||||
import net.minecraft.world.inventory.ContainerLevelAccess;
|
||||
import net.minecraft.world.inventory.EnchantmentMenu;
|
||||
import net.minecraft.world.inventory.MenuType;
|
||||
import net.minecraft.world.level.block.Blocks;
|
||||
import net.minecraft.world.level.block.entity.BlockEntity;
|
||||
import net.minecraft.world.level.block.entity.EnchantingTableBlockEntity;
|
||||
import org.bukkit.inventory.view.EnchantmentView;
|
||||
|
||||
public class CraftEnchantmentInventoryViewBuilder extends CraftAbstractLocationInventoryViewBuilder<EnchantmentView> {
|
||||
|
||||
public CraftEnchantmentInventoryViewBuilder(final MenuType<?> handle) {
|
||||
super(handle);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected AbstractContainerMenu buildContainer(final ServerPlayer player) {
|
||||
if (this.world == null) {
|
||||
this.world = player.level();
|
||||
}
|
||||
|
||||
if (this.position == null) {
|
||||
this.position = player.blockPosition();
|
||||
super.defaultTitle = new EnchantingTableBlockEntity(this.position, Blocks.ENCHANTING_TABLE.defaultBlockState()).getDisplayName();
|
||||
return new EnchantmentMenu(player.nextContainerCounter(), player.getInventory(), ContainerLevelAccess.create(this.world, this.position));
|
||||
}
|
||||
|
||||
final BlockEntity entity = this.world.getBlockEntity(position);
|
||||
if (entity instanceof final EnchantingTableBlockEntity enchantingBlockEntity) {
|
||||
super.defaultTitle = enchantingBlockEntity.getDisplayName();
|
||||
} else {
|
||||
super.defaultTitle = new EnchantingTableBlockEntity(this.position, Blocks.ENCHANTING_TABLE.defaultBlockState()).getDisplayName();
|
||||
}
|
||||
|
||||
return new EnchantmentMenu(player.nextContainerCounter(), player.getInventory(), ContainerLevelAccess.create(this.world, this.position));
|
||||
}
|
||||
}
|
|
@ -4,6 +4,7 @@ import com.google.common.base.Preconditions;
|
|||
import io.papermc.paper.adventure.PaperAdventure;
|
||||
import net.kyori.adventure.text.Component;
|
||||
import net.minecraft.server.level.ServerPlayer;
|
||||
import net.minecraft.world.entity.npc.AbstractVillager;
|
||||
import net.minecraft.world.inventory.AbstractContainerMenu;
|
||||
import net.minecraft.world.inventory.MenuType;
|
||||
import net.minecraft.world.inventory.MerchantMenu;
|
||||
|
@ -25,7 +26,7 @@ public class CraftMerchantInventoryViewBuilder<V extends InventoryView> extends
|
|||
}
|
||||
|
||||
@Override
|
||||
public MerchantInventoryViewBuilder<V> title(final Component title) {
|
||||
public MerchantInventoryViewBuilder<V> title(final @Nullable Component title) {
|
||||
return (MerchantInventoryViewBuilder<V>) super.title(title);
|
||||
}
|
||||
|
||||
|
@ -44,24 +45,34 @@ public class CraftMerchantInventoryViewBuilder<V extends InventoryView> extends
|
|||
@Override
|
||||
public V build(final HumanEntity player) {
|
||||
Preconditions.checkArgument(player != null, "The given player must not be null");
|
||||
Preconditions.checkArgument(this.title != null, "The given title must not be null");
|
||||
Preconditions.checkArgument(player instanceof CraftHumanEntity, "The given player must be a CraftHumanEntity");
|
||||
final CraftHumanEntity craftHuman = (CraftHumanEntity) player;
|
||||
Preconditions.checkArgument(craftHuman.getHandle() instanceof ServerPlayer, "The given player must be an EntityPlayer");
|
||||
Preconditions.checkArgument(craftHuman.getHandle() instanceof ServerPlayer, "The given player must be an ServerPlayer");
|
||||
final ServerPlayer serverPlayer = (ServerPlayer) craftHuman.getHandle();
|
||||
|
||||
final MerchantMenu container;
|
||||
if (this.merchant == null) {
|
||||
container = new MerchantMenu(serverPlayer.nextContainerCounter(), serverPlayer.getInventory(), new CraftMerchantCustom(title).getMerchant());
|
||||
} else {
|
||||
container = new MerchantMenu(serverPlayer.nextContainerCounter(), serverPlayer.getInventory(), this.merchant);
|
||||
this.merchant = this.title == null ? new CraftMerchantCustom().getMerchant() : new CraftMerchantCustom(title).getMerchant();
|
||||
}
|
||||
|
||||
container = new MerchantMenu(serverPlayer.nextContainerCounter(), serverPlayer.getInventory(), this.merchant);
|
||||
|
||||
container.checkReachable = super.checkReachable;
|
||||
container.setTitle(PaperAdventure.asVanilla(this.title));
|
||||
setDefaultTitle(this.merchant);
|
||||
container.setTitle(super.title != null ? PaperAdventure.asVanilla(this.title) : super.defaultTitle);
|
||||
return (V) container.getBukkitView();
|
||||
}
|
||||
|
||||
private void setDefaultTitle(final net.minecraft.world.item.trading.Merchant merchant) {
|
||||
if (merchant instanceof final AbstractVillager villager) {
|
||||
super.defaultTitle = villager.getDisplayName();
|
||||
} else if (merchant instanceof final CraftMerchantCustom.MinecraftMerchant custom) {
|
||||
super.defaultTitle = custom.getScoreboardDisplayName();
|
||||
} else {
|
||||
throw new IllegalStateException("Provided merchant during MenuType creation can not find a default title! This is a bug!");
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected AbstractContainerMenu buildContainer(final ServerPlayer player) {
|
||||
throw new UnsupportedOperationException("buildContainer is not supported for CraftMerchantInventoryViewBuilder");
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
package org.bukkit.craftbukkit.inventory.view.builder;
|
||||
|
||||
import net.minecraft.network.chat.Component;
|
||||
import net.minecraft.server.level.ServerPlayer;
|
||||
import net.minecraft.world.inventory.AbstractContainerMenu;
|
||||
import net.minecraft.world.inventory.MenuType;
|
||||
|
@ -10,6 +11,7 @@ public class CraftStandardInventoryViewBuilder<V extends InventoryView> extends
|
|||
|
||||
public CraftStandardInventoryViewBuilder(final MenuType<?> handle) {
|
||||
super(handle);
|
||||
super.defaultTitle = Component.translatable("container.chest");
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
Loading…
Add table
Reference in a new issue