mirror of
https://github.com/FabricMC/fabric.git
synced 2025-04-05 19:47:00 -04:00
Screen handler API (#584)
* Add screen handler API
* Use more descriptive letters for FabricHandledScreens generics
* Add missing Deprecated annotations
* Bump fabric-containers-v0 version
* Remove unused ServerPlayerEntityAccessor
* Remove [Fabric] from log messages
* Convert FabricHandledScreens to a class
* Add dependency on networking-v0
* Resolve threading issues with NetworkingClient
* Use Identifiers instead of int IDs, make ScreenHandlers a class
Also added a private constructor to FabricHandledScreens.
* NetworkingClient -> ClientNetworking
* Use more descriptive names for injections
* Use ID parameter instead of fetching again
* Add clarifying comment
* Port changes from FabLabs
* Fix compilation
* Replace the content of links in FabricHandledScreens for readability
* Sync with FabLabs
* Add test mod
* I suppose IInv shouldn't have CC0 anymore 👀
* Improve logging
- Networking now uses a logger instead of an exception
- The loggers are now suffixed with their side
- Fixed the client unregistered screen message using the title instead of the ID
* Fix test mod on 20w21a
* Fix ExtendedScreenHandlerFactory javadoc referencing old names
* Update test mod to 1.16-pre2
Just a simple mapping update. :)
* Fix incorrect javadoc references to screen-handler-api in containers-v0
* Remove Minecraft exclusion from build.gradle (thanks to Loom 0.4) + testmod change
Resource loader v0 is now testmodRuntimeOnly as it's not needed for compiling.
This commit is contained in:
parent
c824e0ac2c
commit
045df74fe0
44 changed files with 1646 additions and 1 deletions
fabric-containers-v0
build.gradle
src/main/java/net/fabricmc/fabric/api
fabric-screen-handler-api-v1
build.gradle
settings.gradlesrc
main
java/net/fabricmc/fabric
api
client/screenhandler/v1
screenhandler/v1
impl/screenhandler
mixin/screenhandler
resources
assets/fabric-screen-handler-api-v1
fabric-screen-handler-api-v1.accesswidenerfabric-screen-handler-api-v1.mixins.jsonfabric.mod.jsontestmod
java/net/fabricmc/fabric/test/screenhandler
resources
assets/fabric-screen-handler-api-v1-testmod
blockstates
lang
models
textures
data/fabric-screen-handler-api-v1-testmod/loot_tables/blocks
fabric.mod.json
|
@ -1,5 +1,5 @@
|
|||
archivesBaseName = "fabric-containers-v0"
|
||||
version = getSubprojectVersion(project, "0.1.7")
|
||||
version = getSubprojectVersion(project, "0.1.8")
|
||||
|
||||
dependencies {
|
||||
compile project(path: ':fabric-api-base', configuration: 'dev')
|
||||
|
|
|
@ -19,6 +19,10 @@ package net.fabricmc.fabric.api.client.screen;
|
|||
import net.minecraft.client.gui.screen.ingame.HandledScreen;
|
||||
import net.minecraft.screen.ScreenHandler;
|
||||
|
||||
/**
|
||||
* @deprecated Use {@link net.fabricmc.fabric.api.client.screenhandler.v1.ScreenRegistry.Factory} instead.
|
||||
*/
|
||||
@Deprecated
|
||||
@FunctionalInterface
|
||||
public interface ContainerScreenFactory<C extends ScreenHandler> {
|
||||
HandledScreen create(C container);
|
||||
|
|
|
@ -24,6 +24,10 @@ import net.fabricmc.fabric.api.container.ContainerFactory;
|
|||
import net.fabricmc.fabric.api.container.ContainerProviderRegistry;
|
||||
import net.fabricmc.fabric.impl.client.container.ScreenProviderRegistryImpl;
|
||||
|
||||
/**
|
||||
* @deprecated Use {@link net.fabricmc.fabric.api.client.screenhandler.v1.ScreenRegistry} instead.
|
||||
*/
|
||||
@Deprecated
|
||||
public interface ScreenProviderRegistry {
|
||||
ScreenProviderRegistry INSTANCE = ScreenProviderRegistryImpl.INSTANCE;
|
||||
|
||||
|
|
|
@ -20,6 +20,10 @@ import net.minecraft.entity.player.PlayerEntity;
|
|||
import net.minecraft.util.Identifier;
|
||||
import net.minecraft.network.PacketByteBuf;
|
||||
|
||||
/**
|
||||
* @deprecated Use {@link net.fabricmc.fabric.api.screenhandler.v1.ScreenHandlerRegistry.ExtendedClientHandlerFactory} instead.
|
||||
*/
|
||||
@Deprecated
|
||||
@FunctionalInterface
|
||||
public interface ContainerFactory<T> {
|
||||
/**
|
||||
|
|
|
@ -27,6 +27,10 @@ import net.minecraft.network.PacketByteBuf;
|
|||
import net.fabricmc.fabric.api.client.screen.ScreenProviderRegistry;
|
||||
import net.fabricmc.fabric.impl.container.ContainerProviderImpl;
|
||||
|
||||
/**
|
||||
* @deprecated Use {@link net.fabricmc.fabric.api.screenhandler.v1.ScreenHandlerRegistry} instead.
|
||||
*/
|
||||
@Deprecated
|
||||
public interface ContainerProviderRegistry {
|
||||
ContainerProviderRegistry INSTANCE = ContainerProviderImpl.INSTANCE;
|
||||
|
||||
|
|
12
fabric-screen-handler-api-v1/build.gradle
Normal file
12
fabric-screen-handler-api-v1/build.gradle
Normal file
|
@ -0,0 +1,12 @@
|
|||
archivesBaseName = "fabric-screen-handler-api-v1"
|
||||
version = getSubprojectVersion(project, "1.0.0")
|
||||
|
||||
minecraft {
|
||||
accessWidener = file('src/main/resources/fabric-screen-handler-api-v1.accesswidener')
|
||||
}
|
||||
|
||||
dependencies {
|
||||
compile(project(path: ':fabric-api-base', configuration: 'dev'))
|
||||
compile(project(path: ':fabric-networking-v0', configuration: 'dev'))
|
||||
testmodRuntimeOnly(project(path: ':fabric-resource-loader-v0', configuration: 'dev'))
|
||||
}
|
|
@ -0,0 +1,87 @@
|
|||
/*
|
||||
* Copyright (c) 2016, 2017, 2018, 2019 FabricMC
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package net.fabricmc.fabric.api.client.screenhandler.v1;
|
||||
|
||||
import net.minecraft.client.gui.screen.Screen;
|
||||
import net.minecraft.client.gui.screen.ingame.HandledScreens;
|
||||
import net.minecraft.client.gui.screen.ingame.ScreenHandlerProvider;
|
||||
import net.minecraft.entity.player.PlayerInventory;
|
||||
import net.minecraft.screen.ScreenHandler;
|
||||
import net.minecraft.screen.ScreenHandlerType;
|
||||
import net.minecraft.text.Text;
|
||||
|
||||
import net.fabricmc.api.EnvType;
|
||||
import net.fabricmc.api.Environment;
|
||||
|
||||
/**
|
||||
* An API for registering handled screens that represent screen handlers on the client.
|
||||
* Exposes vanilla's private {@link HandledScreens#register HandledScreens.register()} to modders as {@link #register ScreenRegistry.register()}.
|
||||
*
|
||||
* <h2>Example</h2>
|
||||
* <pre>
|
||||
* {@code
|
||||
* // In a client-side initialization method:
|
||||
* ScreenRegistry.register(MyScreenHandlers.OVEN, OvenScreen::new);
|
||||
*
|
||||
* // Screen class
|
||||
* public class OvenScreen extends HandledScreen<OvenScreenHandler> {
|
||||
* public OvenScreen(OvenScreenHandler handler, PlayerInventory inventory, Text title) {
|
||||
* super(handler, inventory, title);
|
||||
* }
|
||||
* }
|
||||
* }
|
||||
* </pre>
|
||||
*
|
||||
* @see net.fabricmc.fabric.api.screenhandler.v1.ScreenHandlerRegistry registering screen handlers
|
||||
*/
|
||||
@Environment(EnvType.CLIENT)
|
||||
public final class ScreenRegistry {
|
||||
private ScreenRegistry() {
|
||||
}
|
||||
|
||||
/**
|
||||
* Registers a new screen factory for a screen handler type.
|
||||
*
|
||||
* @param type the screen handler type object
|
||||
* @param screenFactory the screen handler factory
|
||||
* @param <H> the screen handler type
|
||||
* @param <S> the screen type
|
||||
*/
|
||||
public static <H extends ScreenHandler, S extends Screen & ScreenHandlerProvider<H>> void register(ScreenHandlerType<? extends H> type, Factory<? super H, ? extends S> screenFactory) {
|
||||
// Convert our factory to the vanilla provider here as the vanilla interface won't be available to modders.
|
||||
HandledScreens.<H, S>register(type, screenFactory::create);
|
||||
}
|
||||
|
||||
/**
|
||||
* A factory for handled screens.
|
||||
*
|
||||
* @param <H> the screen handler type
|
||||
* @param <S> the screen type
|
||||
*/
|
||||
@FunctionalInterface
|
||||
public interface Factory<H extends ScreenHandler, S extends Screen & ScreenHandlerProvider<H>> {
|
||||
/**
|
||||
* Creates a new handled screen.
|
||||
*
|
||||
* @param handler the screen handler
|
||||
* @param inventory the player inventory
|
||||
* @param title the title of the screen
|
||||
* @return the created screen
|
||||
*/
|
||||
S create(H handler, PlayerInventory inventory, Text title);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,20 @@
|
|||
/*
|
||||
* Copyright (c) 2016, 2017, 2018, 2019 FabricMC
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
/**
|
||||
* API for working with screen handlers on the client.
|
||||
*/
|
||||
package net.fabricmc.fabric.api.client.screenhandler.v1;
|
|
@ -0,0 +1,36 @@
|
|||
/*
|
||||
* Copyright (c) 2016, 2017, 2018, 2019 FabricMC
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package net.fabricmc.fabric.api.screenhandler.v1;
|
||||
|
||||
import net.minecraft.network.PacketByteBuf;
|
||||
import net.minecraft.screen.NamedScreenHandlerFactory;
|
||||
import net.minecraft.server.network.ServerPlayerEntity;
|
||||
|
||||
/**
|
||||
* An extension of {@code NamedScreenHandlerFactory} that can write additional data to a screen opening packet.
|
||||
*
|
||||
* @see ScreenHandlerRegistry#registerExtended(net.minecraft.util.Identifier, ScreenHandlerRegistry.ExtendedClientHandlerFactory)
|
||||
*/
|
||||
public interface ExtendedScreenHandlerFactory extends NamedScreenHandlerFactory {
|
||||
/**
|
||||
* Writes additional server -> client screen opening data to the buffer.
|
||||
*
|
||||
* @param player the player that is opening the screen
|
||||
* @param buf the packet buffer
|
||||
*/
|
||||
void writeScreenOpeningData(ServerPlayerEntity player, PacketByteBuf buf);
|
||||
}
|
|
@ -0,0 +1,140 @@
|
|||
/*
|
||||
* Copyright (c) 2016, 2017, 2018, 2019 FabricMC
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package net.fabricmc.fabric.api.screenhandler.v1;
|
||||
|
||||
import net.minecraft.entity.player.PlayerInventory;
|
||||
import net.minecraft.network.PacketByteBuf;
|
||||
import net.minecraft.screen.ScreenHandler;
|
||||
import net.minecraft.screen.ScreenHandlerType;
|
||||
import net.minecraft.util.Identifier;
|
||||
import net.minecraft.util.registry.Registry;
|
||||
|
||||
import net.fabricmc.api.EnvType;
|
||||
import net.fabricmc.api.Environment;
|
||||
import net.fabricmc.fabric.impl.screenhandler.ExtendedScreenHandlerType;
|
||||
|
||||
/**
|
||||
* An API for creating and registering {@linkplain ScreenHandlerType screen handler types}.
|
||||
*
|
||||
* <p>This class exposes the private {@link ScreenHandlerType} constructor,
|
||||
* as well as adds support for creating types using Fabric's extended screen handler API.
|
||||
*
|
||||
* <p>Screen handlers types are used to synchronize {@linkplain ScreenHandler screen handlers}
|
||||
* between the server and the client. Screen handlers manage the items and integer properties that are
|
||||
* needed to show on screens, such as the items in a chest or the progress of a furnace.
|
||||
*
|
||||
* <h2>Simple and extended screen handlers</h2>
|
||||
* Simple screen handlers are the type of screen handlers used in vanilla.
|
||||
* They can automatically synchronize items and integer properties between the server and the client,
|
||||
* but they don't support having custom data sent in the opening packet.
|
||||
*
|
||||
* <p>This module adds <i>extended screen handlers</i> that can synchronize their own custom data
|
||||
* when they are opened, which can be useful for defining additional properties of a screen on the server.
|
||||
* For example, a mod can synchronize text that will show up as a label.
|
||||
*
|
||||
* <h2>Example</h2>
|
||||
* <pre>
|
||||
* {@code
|
||||
* // Creating the screen handler type
|
||||
* public static final ScreenHandlerType<OvenScreenHandler> OVEN = ScreenHandlerRegistry.registerSimple(new Identifier("my_mod", "oven"), OvenScreenHandler::new);
|
||||
*
|
||||
* // Screen handler class
|
||||
* public class OvenScreenHandler extends ScreenHandler {
|
||||
* public OvenScreenHandler(int syncId) {
|
||||
* super(MyScreenHandlers.OVEN, syncId);
|
||||
* }
|
||||
* }
|
||||
*
|
||||
* // Opening the screen
|
||||
* NamedScreenHandlerFactory factory = ...;
|
||||
* player.openHandledScreen(factory); // only works on ServerPlayerEntity instances
|
||||
* }
|
||||
* </pre>
|
||||
*
|
||||
* @see net.fabricmc.fabric.api.client.screenhandler.v1.ScreenRegistry registering screens for screen handlers
|
||||
*/
|
||||
public final class ScreenHandlerRegistry {
|
||||
private ScreenHandlerRegistry() {
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates and registers a new {@code ScreenHandlerType} that creates client-sided screen handlers using the factory.
|
||||
*
|
||||
* @param id the registry ID
|
||||
* @param factory the client-sided screen handler factory
|
||||
* @param <T> the screen handler type
|
||||
* @return the created type object
|
||||
*/
|
||||
public static <T extends ScreenHandler> ScreenHandlerType<T> registerSimple(Identifier id, SimpleClientHandlerFactory<T> factory) {
|
||||
// Wrap our factory in vanilla's factory; it will not be public for users.
|
||||
ScreenHandlerType<T> type = new ScreenHandlerType<>(factory::create);
|
||||
return Registry.register(Registry.SCREEN_HANDLER, id, type);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates and registers a new {@code ScreenHandlerType} that creates client-sided screen handlers with additional
|
||||
* networked opening data.
|
||||
*
|
||||
* <p>These screen handlers must be opened with a {@link ExtendedScreenHandlerFactory}.
|
||||
*
|
||||
* @param id the registry ID
|
||||
* @param factory the client-sided screen handler factory
|
||||
* @param <T> the screen handler type
|
||||
* @return the created type object
|
||||
*/
|
||||
public static <T extends ScreenHandler> ScreenHandlerType<T> registerExtended(Identifier id, ExtendedClientHandlerFactory<T> factory) {
|
||||
ScreenHandlerType<T> type = new ExtendedScreenHandlerType<>(factory);
|
||||
return Registry.register(Registry.SCREEN_HANDLER, id, type);
|
||||
}
|
||||
|
||||
/**
|
||||
* A factory for client-sided screen handler instances.
|
||||
*
|
||||
* @param <T> the screen handler type
|
||||
*/
|
||||
public interface SimpleClientHandlerFactory<T extends ScreenHandler> {
|
||||
/**
|
||||
* Creates a new client-sided screen handler.
|
||||
*
|
||||
* @param syncId the synchronization ID
|
||||
* @param inventory the player inventory
|
||||
* @return the created screen handler
|
||||
*/
|
||||
@Environment(EnvType.CLIENT)
|
||||
T create(int syncId, PlayerInventory inventory);
|
||||
}
|
||||
|
||||
/**
|
||||
* A factory for client-sided screen handler instances
|
||||
* with additional screen opening data.
|
||||
*
|
||||
* @param <T> the screen handler type
|
||||
* @see ExtendedScreenHandlerFactory
|
||||
*/
|
||||
public interface ExtendedClientHandlerFactory<T extends ScreenHandler> {
|
||||
/**
|
||||
* Creates a new client-sided screen handler with additional screen opening data.
|
||||
*
|
||||
* @param syncId the synchronization ID
|
||||
* @param inventory the player inventory
|
||||
* @param buf the packet buffer
|
||||
* @return the created screen handler
|
||||
*/
|
||||
@Environment(EnvType.CLIENT)
|
||||
T create(int syncId, PlayerInventory inventory, PacketByteBuf buf);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,20 @@
|
|||
/*
|
||||
* Copyright (c) 2016, 2017, 2018, 2019 FabricMC
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
/**
|
||||
* The Fabric screen handler API for creating screen handlers.
|
||||
*/
|
||||
package net.fabricmc.fabric.api.screenhandler.v1;
|
|
@ -0,0 +1,46 @@
|
|||
/*
|
||||
* Copyright (c) 2016, 2017, 2018, 2019 FabricMC
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package net.fabricmc.fabric.impl.screenhandler;
|
||||
|
||||
import net.minecraft.entity.player.PlayerInventory;
|
||||
import net.minecraft.network.PacketByteBuf;
|
||||
import net.minecraft.screen.ScreenHandler;
|
||||
import net.minecraft.screen.ScreenHandlerType;
|
||||
|
||||
import net.fabricmc.api.EnvType;
|
||||
import net.fabricmc.api.Environment;
|
||||
import net.fabricmc.fabric.api.screenhandler.v1.ScreenHandlerRegistry;
|
||||
|
||||
public final class ExtendedScreenHandlerType<T extends ScreenHandler> extends ScreenHandlerType<T> {
|
||||
private final ScreenHandlerRegistry.ExtendedClientHandlerFactory<T> factory;
|
||||
|
||||
public ExtendedScreenHandlerType(ScreenHandlerRegistry.ExtendedClientHandlerFactory<T> factory) {
|
||||
super(null);
|
||||
this.factory = factory;
|
||||
}
|
||||
|
||||
@Environment(EnvType.CLIENT)
|
||||
@Override
|
||||
public T create(int syncId, PlayerInventory inventory) {
|
||||
throw new UnsupportedOperationException("Use ExtendedScreenHandlerType.create(int, PlayerInventory, PacketByteBuf)!");
|
||||
}
|
||||
|
||||
@Environment(EnvType.CLIENT)
|
||||
public T create(int syncId, PlayerInventory inventory, PacketByteBuf buf) {
|
||||
return factory.create(syncId, inventory, buf);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,72 @@
|
|||
/*
|
||||
* Copyright (c) 2016, 2017, 2018, 2019 FabricMC
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package net.fabricmc.fabric.impl.screenhandler;
|
||||
|
||||
import java.util.Objects;
|
||||
|
||||
import io.netty.buffer.Unpooled;
|
||||
import org.apache.logging.log4j.LogManager;
|
||||
import org.apache.logging.log4j.Logger;
|
||||
|
||||
import net.minecraft.network.PacketByteBuf;
|
||||
import net.minecraft.screen.ScreenHandler;
|
||||
import net.minecraft.server.network.ServerPlayerEntity;
|
||||
import net.minecraft.util.Identifier;
|
||||
import net.minecraft.util.registry.Registry;
|
||||
|
||||
import net.fabricmc.fabric.api.network.ServerSidePacketRegistry;
|
||||
import net.fabricmc.fabric.api.screenhandler.v1.ExtendedScreenHandlerFactory;
|
||||
|
||||
public final class Networking {
|
||||
private static final Logger LOGGER = LogManager.getLogger("fabric-screen-handler-api-v1/server");
|
||||
|
||||
// [Packet format]
|
||||
// typeId: identifier
|
||||
// syncId: varInt
|
||||
// title: text
|
||||
// customData: buf
|
||||
public static final Identifier OPEN_ID = new Identifier("fabric-screen-handler-api-v1", "open_screen");
|
||||
|
||||
/**
|
||||
* Opens an extended screen handler by sending a custom packet to the client.
|
||||
*
|
||||
* @param player the player
|
||||
* @param factory the screen handler factory
|
||||
* @param handler the screen handler instance
|
||||
* @param syncId the synchronization ID
|
||||
*/
|
||||
public static void sendOpenPacket(ServerPlayerEntity player, ExtendedScreenHandlerFactory factory, ScreenHandler handler, int syncId) {
|
||||
Objects.requireNonNull(player, "player is null");
|
||||
Objects.requireNonNull(factory, "factory is null");
|
||||
Objects.requireNonNull(handler, "handler is null");
|
||||
|
||||
Identifier typeId = Registry.SCREEN_HANDLER.getId(handler.getType());
|
||||
|
||||
if (typeId == null) {
|
||||
LOGGER.warn("Trying to open unregistered screen handler {}", handler);
|
||||
return;
|
||||
}
|
||||
|
||||
PacketByteBuf buf = new PacketByteBuf(Unpooled.buffer());
|
||||
buf.writeIdentifier(typeId);
|
||||
buf.writeVarInt(syncId);
|
||||
buf.writeText(factory.getDisplayName());
|
||||
factory.writeScreenOpeningData(player, buf);
|
||||
|
||||
ServerSidePacketRegistry.INSTANCE.sendToPlayer(player, OPEN_ID, buf);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,87 @@
|
|||
/*
|
||||
* Copyright (c) 2016, 2017, 2018, 2019 FabricMC
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package net.fabricmc.fabric.impl.screenhandler.client;
|
||||
|
||||
import org.apache.logging.log4j.LogManager;
|
||||
import org.apache.logging.log4j.Logger;
|
||||
|
||||
import net.minecraft.client.MinecraftClient;
|
||||
import net.minecraft.client.gui.screen.Screen;
|
||||
import net.minecraft.client.gui.screen.ingame.HandledScreens;
|
||||
import net.minecraft.client.gui.screen.ingame.ScreenHandlerProvider;
|
||||
import net.minecraft.entity.player.PlayerEntity;
|
||||
import net.minecraft.network.PacketByteBuf;
|
||||
import net.minecraft.screen.ScreenHandlerType;
|
||||
import net.minecraft.text.Text;
|
||||
import net.minecraft.util.Identifier;
|
||||
import net.minecraft.util.registry.Registry;
|
||||
|
||||
import net.fabricmc.api.ClientModInitializer;
|
||||
import net.fabricmc.api.EnvType;
|
||||
import net.fabricmc.api.Environment;
|
||||
import net.fabricmc.fabric.api.network.ClientSidePacketRegistry;
|
||||
import net.fabricmc.fabric.impl.screenhandler.ExtendedScreenHandlerType;
|
||||
import net.fabricmc.fabric.impl.screenhandler.Networking;
|
||||
|
||||
@Environment(EnvType.CLIENT)
|
||||
public final class ClientNetworking implements ClientModInitializer {
|
||||
private static final Logger LOGGER = LogManager.getLogger("fabric-screen-handler-api-v1/client");
|
||||
|
||||
@Override
|
||||
public void onInitializeClient() {
|
||||
ClientSidePacketRegistry.INSTANCE.register(Networking.OPEN_ID, (ctx, buf) -> {
|
||||
Identifier typeId = buf.readIdentifier();
|
||||
int syncId = buf.readVarInt();
|
||||
Text title = buf.readText();
|
||||
buf.retain();
|
||||
ctx.getTaskQueue().execute(() -> openScreen(typeId, syncId, title, buf));
|
||||
});
|
||||
}
|
||||
|
||||
@SuppressWarnings({"rawtypes", "unchecked"})
|
||||
private void openScreen(Identifier typeId, int syncId, Text title, PacketByteBuf buf) {
|
||||
ScreenHandlerType<?> type = Registry.SCREEN_HANDLER.get(typeId);
|
||||
|
||||
if (type == null) {
|
||||
LOGGER.warn("Unknown screen handler ID: {}", typeId);
|
||||
return;
|
||||
}
|
||||
|
||||
if (!(type instanceof ExtendedScreenHandlerType<?>)) {
|
||||
LOGGER.warn("Received extended opening packet for non-extended screen handler {}", typeId);
|
||||
return;
|
||||
}
|
||||
|
||||
HandledScreens.Provider screenFactory = HandledScreens.getProvider(type);
|
||||
|
||||
if (screenFactory != null) {
|
||||
MinecraftClient client = MinecraftClient.getInstance();
|
||||
PlayerEntity player = client.player;
|
||||
|
||||
Screen screen = screenFactory.create(
|
||||
((ExtendedScreenHandlerType<?>) type).create(syncId, player.inventory, buf),
|
||||
player.inventory,
|
||||
title
|
||||
);
|
||||
|
||||
player.currentScreenHandler = ((ScreenHandlerProvider<?>) screen).getScreenHandler();
|
||||
client.openScreen(screen);
|
||||
} else {
|
||||
LOGGER.warn("Screen not registered for screen handler {}!", typeId);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,81 @@
|
|||
/*
|
||||
* Copyright (c) 2016, 2017, 2018, 2019 FabricMC
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package net.fabricmc.fabric.mixin.screenhandler;
|
||||
|
||||
import java.util.OptionalInt;
|
||||
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
import org.spongepowered.asm.mixin.Shadow;
|
||||
import org.spongepowered.asm.mixin.Unique;
|
||||
import org.spongepowered.asm.mixin.injection.At;
|
||||
import org.spongepowered.asm.mixin.injection.Inject;
|
||||
import org.spongepowered.asm.mixin.injection.Redirect;
|
||||
import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
|
||||
import org.spongepowered.asm.mixin.injection.callback.LocalCapture;
|
||||
|
||||
import net.minecraft.network.Packet;
|
||||
import net.minecraft.screen.NamedScreenHandlerFactory;
|
||||
import net.minecraft.screen.ScreenHandler;
|
||||
import net.minecraft.server.network.ServerPlayerEntity;
|
||||
import net.minecraft.server.network.ServerPlayNetworkHandler;
|
||||
import net.minecraft.util.Identifier;
|
||||
import net.minecraft.util.registry.Registry;
|
||||
|
||||
import net.fabricmc.fabric.api.screenhandler.v1.ExtendedScreenHandlerFactory;
|
||||
import net.fabricmc.fabric.impl.screenhandler.ExtendedScreenHandlerType;
|
||||
import net.fabricmc.fabric.impl.screenhandler.Networking;
|
||||
|
||||
@Mixin(ServerPlayerEntity.class)
|
||||
public class ServerPlayerEntityMixin {
|
||||
@Shadow
|
||||
private int screenHandlerSyncId;
|
||||
|
||||
@Unique
|
||||
private final ThreadLocal<ScreenHandler> fabric_openedScreenHandler = new ThreadLocal<>();
|
||||
|
||||
@Inject(method = "openHandledScreen(Lnet/minecraft/screen/NamedScreenHandlerFactory;)Ljava/util/OptionalInt;", at = @At(value = "INVOKE", target = "Lnet/minecraft/server/network/ServerPlayNetworkHandler;sendPacket(Lnet/minecraft/network/Packet;)V"), locals = LocalCapture.CAPTURE_FAILHARD)
|
||||
private void fabric_storeOpenedScreenHandler(NamedScreenHandlerFactory factory, CallbackInfoReturnable<OptionalInt> info, ScreenHandler handler) {
|
||||
if (factory instanceof ExtendedScreenHandlerFactory) {
|
||||
fabric_openedScreenHandler.set(handler);
|
||||
} else if (handler.getType() instanceof ExtendedScreenHandlerType<?>) {
|
||||
Identifier id = Registry.SCREEN_HANDLER.getId(handler.getType());
|
||||
throw new IllegalArgumentException("[Fabric] Extended screen handler " + id + " must be opened with an ExtendedScreenHandlerFactory!");
|
||||
}
|
||||
}
|
||||
|
||||
@Redirect(method = "openHandledScreen(Lnet/minecraft/screen/NamedScreenHandlerFactory;)Ljava/util/OptionalInt;", at = @At(value = "INVOKE", target = "Lnet/minecraft/server/network/ServerPlayNetworkHandler;sendPacket(Lnet/minecraft/network/Packet;)V"))
|
||||
private void fabric_replaceVanillaScreenPacket(ServerPlayNetworkHandler networkHandler, Packet<?> packet, NamedScreenHandlerFactory factory) {
|
||||
if (factory instanceof ExtendedScreenHandlerFactory) {
|
||||
ScreenHandler handler = fabric_openedScreenHandler.get();
|
||||
|
||||
if (handler.getType() instanceof ExtendedScreenHandlerType<?>) {
|
||||
Networking.sendOpenPacket((ServerPlayerEntity) (Object) this, (ExtendedScreenHandlerFactory) factory, handler, screenHandlerSyncId);
|
||||
} else {
|
||||
Identifier id = Registry.SCREEN_HANDLER.getId(handler.getType());
|
||||
throw new IllegalArgumentException("[Fabric] Non-extended screen handler " + id + " must not be opened with an ExtendedScreenHandlerFactory!");
|
||||
}
|
||||
} else {
|
||||
// Use vanilla logic for non-extended screen handlers
|
||||
networkHandler.sendPacket(packet);
|
||||
}
|
||||
}
|
||||
|
||||
@Inject(method = "openHandledScreen(Lnet/minecraft/screen/NamedScreenHandlerFactory;)Ljava/util/OptionalInt;", at = @At("RETURN"))
|
||||
private void fabric_clearStoredScreenHandler(NamedScreenHandlerFactory factory, CallbackInfoReturnable<OptionalInt> info) {
|
||||
fabric_openedScreenHandler.remove();
|
||||
}
|
||||
}
|
Binary file not shown.
After ![]() (image error) Size: 1.5 KiB |
|
@ -0,0 +1,8 @@
|
|||
accessWidener v1 named
|
||||
accessible class net/minecraft/screen/ScreenHandlerType$Factory
|
||||
accessible method net/minecraft/screen/ScreenHandlerType <init> (Lnet/minecraft/screen/ScreenHandlerType$Factory;)V
|
||||
extendable method net/minecraft/screen/ScreenHandlerType <init> (Lnet/minecraft/screen/ScreenHandlerType$Factory;)V
|
||||
|
||||
accessible class net/minecraft/client/gui/screen/ingame/HandledScreens$Provider
|
||||
accessible method net/minecraft/client/gui/screen/ingame/HandledScreens register (Lnet/minecraft/screen/ScreenHandlerType;Lnet/minecraft/client/gui/screen/ingame/HandledScreens$Provider;)V
|
||||
accessible method net/minecraft/client/gui/screen/ingame/HandledScreens getProvider (Lnet/minecraft/screen/ScreenHandlerType;)Lnet/minecraft/client/gui/screen/ingame/HandledScreens$Provider;
|
|
@ -0,0 +1,13 @@
|
|||
{
|
||||
"required": true,
|
||||
"package": "net.fabricmc.fabric.mixin.screenhandler",
|
||||
"compatibilityLevel": "JAVA_8",
|
||||
"mixins": [
|
||||
"ServerPlayerEntityMixin"
|
||||
],
|
||||
"client": [
|
||||
],
|
||||
"injectors": {
|
||||
"defaultRequire": 1
|
||||
}
|
||||
}
|
|
@ -0,0 +1,31 @@
|
|||
{
|
||||
"schemaVersion": 1,
|
||||
"id": "fabric-screen-handler-api-v1",
|
||||
"name": "Fabric Screen Handler API (v1)",
|
||||
"version": "${version}",
|
||||
"environment": "*",
|
||||
"license": "Apache-2.0",
|
||||
"icon": "assets/fabric-screen-handler-api-v1/icon.png",
|
||||
"contact": {
|
||||
"homepage": "https://fabricmc.net",
|
||||
"irc": "irc://irc.esper.net:6667/fabric",
|
||||
"issues": "https://github.com/FabricMC/fabric/issues",
|
||||
"sources": "https://github.com/FabricMC/fabric"
|
||||
},
|
||||
"authors": [
|
||||
"FabricMC"
|
||||
],
|
||||
"depends": {
|
||||
"fabricloader": ">=0.8.0",
|
||||
"fabric-api-base": "*",
|
||||
"fabric-networking-v0": "*"
|
||||
},
|
||||
"entrypoints": {
|
||||
"client": ["net.fabricmc.fabric.impl.screenhandler.client.ClientNetworking"]
|
||||
},
|
||||
"description": "Hooks and extensions for creating screen handlers.",
|
||||
"mixins": [
|
||||
"fabric-screen-handler-api-v1.mixins.json"
|
||||
],
|
||||
"accessWidener": "fabric-screen-handler-api-v1.accesswidener"
|
||||
}
|
|
@ -0,0 +1,64 @@
|
|||
/*
|
||||
* Copyright (c) 2016, 2017, 2018, 2019 FabricMC
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package net.fabricmc.fabric.test.screenhandler;
|
||||
|
||||
import net.minecraft.block.AbstractBlock;
|
||||
import net.minecraft.block.Block;
|
||||
import net.minecraft.block.Blocks;
|
||||
import net.minecraft.block.entity.BlockEntityType;
|
||||
import net.minecraft.item.BlockItem;
|
||||
import net.minecraft.item.Item;
|
||||
import net.minecraft.item.ItemGroup;
|
||||
import net.minecraft.screen.ScreenHandlerType;
|
||||
import net.minecraft.util.Identifier;
|
||||
import net.minecraft.util.registry.Registry;
|
||||
|
||||
import net.fabricmc.api.ModInitializer;
|
||||
import net.fabricmc.fabric.api.screenhandler.v1.ScreenHandlerRegistry;
|
||||
import net.fabricmc.fabric.test.screenhandler.block.BoxBlock;
|
||||
import net.fabricmc.fabric.test.screenhandler.block.BoxBlockEntity;
|
||||
import net.fabricmc.fabric.test.screenhandler.item.BagItem;
|
||||
import net.fabricmc.fabric.test.screenhandler.item.PositionedBagItem;
|
||||
import net.fabricmc.fabric.test.screenhandler.screen.BagScreenHandler;
|
||||
import net.fabricmc.fabric.test.screenhandler.screen.BoxScreenHandler;
|
||||
import net.fabricmc.fabric.test.screenhandler.screen.PositionedBagScreenHandler;
|
||||
|
||||
public class ScreenHandlerTest implements ModInitializer {
|
||||
public static final String ID = "fabric-screen-handler-api-v1-testmod";
|
||||
|
||||
public static final Item BAG = new BagItem(new Item.Settings().group(ItemGroup.TOOLS).maxCount(1));
|
||||
public static final Item POSITIONED_BAG = new PositionedBagItem(new Item.Settings().group(ItemGroup.TOOLS).maxCount(1));
|
||||
public static final Block BOX = new BoxBlock(AbstractBlock.Settings.copy(Blocks.OAK_WOOD));
|
||||
public static final Item BOX_ITEM = new BlockItem(BOX, new Item.Settings().group(ItemGroup.DECORATIONS));
|
||||
public static final BlockEntityType<?> BOX_ENTITY = BlockEntityType.Builder.create(BoxBlockEntity::new, BOX).build(null);
|
||||
public static final ScreenHandlerType<BagScreenHandler> BAG_SCREEN_HANDLER = ScreenHandlerRegistry.registerSimple(id("bag"), BagScreenHandler::new);
|
||||
public static final ScreenHandlerType<PositionedBagScreenHandler> POSITIONED_BAG_SCREEN_HANDLER = ScreenHandlerRegistry.registerExtended(id("positioned_bag"), PositionedBagScreenHandler::new);
|
||||
public static final ScreenHandlerType<BoxScreenHandler> BOX_SCREEN_HANDLER = ScreenHandlerRegistry.registerExtended(id("box"), BoxScreenHandler::new);
|
||||
|
||||
public static Identifier id(String path) {
|
||||
return new Identifier(ID, path);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onInitialize() {
|
||||
Registry.register(Registry.ITEM, id("bag"), BAG);
|
||||
Registry.register(Registry.ITEM, id("positioned_bag"), POSITIONED_BAG);
|
||||
Registry.register(Registry.BLOCK, id("box"), BOX);
|
||||
Registry.register(Registry.ITEM, id("box"), BOX_ITEM);
|
||||
Registry.register(Registry.BLOCK_ENTITY_TYPE, id("box"), BOX_ENTITY);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,81 @@
|
|||
/*
|
||||
* Copyright (c) 2016, 2017, 2018, 2019 FabricMC
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package net.fabricmc.fabric.test.screenhandler.block;
|
||||
|
||||
import net.minecraft.block.BlockRenderType;
|
||||
import net.minecraft.block.BlockState;
|
||||
import net.minecraft.block.BlockWithEntity;
|
||||
import net.minecraft.block.entity.BlockEntity;
|
||||
import net.minecraft.entity.player.PlayerEntity;
|
||||
import net.minecraft.inventory.Inventory;
|
||||
import net.minecraft.screen.NamedScreenHandlerFactory;
|
||||
import net.minecraft.screen.ScreenHandler;
|
||||
import net.minecraft.util.ActionResult;
|
||||
import net.minecraft.util.Hand;
|
||||
import net.minecraft.util.ItemScatterer;
|
||||
import net.minecraft.util.hit.BlockHitResult;
|
||||
import net.minecraft.util.math.BlockPos;
|
||||
import net.minecraft.world.BlockView;
|
||||
import net.minecraft.world.World;
|
||||
|
||||
public class BoxBlock extends BlockWithEntity {
|
||||
public BoxBlock(Settings settings) {
|
||||
super(settings);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ActionResult onUse(BlockState state, World world, BlockPos pos, PlayerEntity player, Hand hand, BlockHitResult hit) {
|
||||
if (!world.isClient) {
|
||||
NamedScreenHandlerFactory screenHandlerFactory = state.createScreenHandlerFactory(world, pos);
|
||||
|
||||
if (screenHandlerFactory != null) {
|
||||
player.openHandledScreen(screenHandlerFactory);
|
||||
}
|
||||
}
|
||||
|
||||
return ActionResult.SUCCESS;
|
||||
}
|
||||
|
||||
@Override
|
||||
public BlockEntity createBlockEntity(BlockView world) {
|
||||
return new BoxBlockEntity();
|
||||
}
|
||||
|
||||
@Override
|
||||
public BlockRenderType getRenderType(BlockState state) {
|
||||
return BlockRenderType.MODEL;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onStateReplaced(BlockState state, World world, BlockPos pos, BlockState newState, boolean moved) {
|
||||
if (state.getBlock() != newState.getBlock()) {
|
||||
BlockEntity be = world.getBlockEntity(pos);
|
||||
|
||||
if (be instanceof Inventory) {
|
||||
ItemScatterer.spawn(world, pos, (Inventory) be);
|
||||
world.updateComparators(pos, this);
|
||||
}
|
||||
|
||||
super.onStateReplaced(state, world, pos, newState, moved);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getComparatorOutput(BlockState state, World world, BlockPos pos) {
|
||||
return ScreenHandler.calculateComparatorOutput(world.getBlockEntity(pos));
|
||||
}
|
||||
}
|
|
@ -0,0 +1,69 @@
|
|||
/*
|
||||
* Copyright (c) 2016, 2017, 2018, 2019 FabricMC
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package net.fabricmc.fabric.test.screenhandler.block;
|
||||
|
||||
import net.minecraft.block.entity.LootableContainerBlockEntity;
|
||||
import net.minecraft.entity.player.PlayerInventory;
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.network.PacketByteBuf;
|
||||
import net.minecraft.screen.ScreenHandler;
|
||||
import net.minecraft.server.network.ServerPlayerEntity;
|
||||
import net.minecraft.text.Text;
|
||||
import net.minecraft.text.TranslatableText;
|
||||
import net.minecraft.util.collection.DefaultedList;
|
||||
|
||||
import net.fabricmc.fabric.api.screenhandler.v1.ExtendedScreenHandlerFactory;
|
||||
import net.fabricmc.fabric.test.screenhandler.ScreenHandlerTest;
|
||||
import net.fabricmc.fabric.test.screenhandler.screen.BoxScreenHandler;
|
||||
|
||||
public class BoxBlockEntity extends LootableContainerBlockEntity implements ExtendedScreenHandlerFactory {
|
||||
private DefaultedList<ItemStack> items = DefaultedList.ofSize(size(), ItemStack.EMPTY);
|
||||
|
||||
public BoxBlockEntity() {
|
||||
super(ScreenHandlerTest.BOX_ENTITY);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected DefaultedList<ItemStack> getInvStackList() {
|
||||
return items;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void setInvStackList(DefaultedList<ItemStack> list) {
|
||||
this.items = list;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Text getContainerName() {
|
||||
return new TranslatableText(getCachedState().getBlock().getTranslationKey());
|
||||
}
|
||||
|
||||
@Override
|
||||
protected ScreenHandler createScreenHandler(int syncId, PlayerInventory playerInventory) {
|
||||
return new BoxScreenHandler(syncId, playerInventory, this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int size() {
|
||||
return 3 * 3;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeScreenOpeningData(ServerPlayerEntity player, PacketByteBuf buf) {
|
||||
buf.writeBlockPos(pos);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,40 @@
|
|||
/*
|
||||
* Copyright (c) 2016, 2017, 2018, 2019 FabricMC
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package net.fabricmc.fabric.test.screenhandler.client;
|
||||
|
||||
import net.minecraft.client.gui.screen.ingame.Generic3x3ContainerScreen;
|
||||
|
||||
import net.fabricmc.fabric.api.client.screenhandler.v1.ScreenRegistry;
|
||||
import net.fabricmc.fabric.test.screenhandler.ScreenHandlerTest;
|
||||
import net.fabricmc.fabric.test.screenhandler.screen.BoxScreenHandler;
|
||||
import net.fabricmc.fabric.test.screenhandler.screen.PositionedBagScreenHandler;
|
||||
import net.fabricmc.api.ClientModInitializer;
|
||||
|
||||
public class ClientScreenHandlerTest implements ClientModInitializer {
|
||||
@Override
|
||||
public void onInitializeClient() {
|
||||
ScreenRegistry.register(ScreenHandlerTest.BAG_SCREEN_HANDLER, Generic3x3ContainerScreen::new);
|
||||
ScreenRegistry.<PositionedBagScreenHandler, PositionedScreen<PositionedBagScreenHandler>>register(
|
||||
ScreenHandlerTest.POSITIONED_BAG_SCREEN_HANDLER,
|
||||
PositionedScreen::new
|
||||
);
|
||||
ScreenRegistry.<BoxScreenHandler, PositionedScreen<BoxScreenHandler>>register(
|
||||
ScreenHandlerTest.BOX_SCREEN_HANDLER,
|
||||
PositionedScreen::new
|
||||
);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,62 @@
|
|||
/*
|
||||
* Copyright (c) 2016, 2017, 2018, 2019 FabricMC
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package net.fabricmc.fabric.test.screenhandler.client;
|
||||
|
||||
import com.mojang.blaze3d.systems.RenderSystem;
|
||||
|
||||
import net.minecraft.client.gui.screen.ingame.HandledScreen;
|
||||
import net.minecraft.client.util.math.MatrixStack;
|
||||
import net.minecraft.entity.player.PlayerInventory;
|
||||
import net.minecraft.screen.ScreenHandler;
|
||||
import net.minecraft.text.LiteralText;
|
||||
import net.minecraft.text.Text;
|
||||
import net.minecraft.util.Identifier;
|
||||
import net.minecraft.util.math.BlockPos;
|
||||
|
||||
import net.fabricmc.fabric.test.screenhandler.screen.PositionedScreenHandler;
|
||||
|
||||
public class PositionedScreen<T extends ScreenHandler & PositionedScreenHandler> extends HandledScreen<T> {
|
||||
private static final Identifier TEXTURE = new Identifier("minecraft", "textures/gui/container/dispenser.png");
|
||||
|
||||
public PositionedScreen(T handler, PlayerInventory inventory, Text title) {
|
||||
super(handler, inventory, title);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void render(MatrixStack matrices, int mouseX, int mouseY, float delta) {
|
||||
renderBackground(matrices);
|
||||
super.render(matrices, mouseX, mouseY, delta);
|
||||
drawMouseoverTooltip(matrices, mouseX, mouseY);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void drawForeground(MatrixStack matrices, int mouseX, int mouseY) {
|
||||
BlockPos pos = handler.getPos();
|
||||
Text usedTitle = pos != null ? new LiteralText("(" + pos.toShortString() + ")") : title;
|
||||
textRenderer.draw(matrices, usedTitle, (float) (backgroundWidth / 2 - textRenderer.getWidth(usedTitle) / 2), 6.0F, 0x404040);
|
||||
textRenderer.draw(matrices, playerInventory.getDisplayName(), 8.0F, backgroundHeight - 96 + 2, 0x404040);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void drawBackground(MatrixStack matrices, float delta, int mouseX, int mouseY) {
|
||||
RenderSystem.color4f(1.0F, 1.0F, 1.0F, 1.0F);
|
||||
client.getTextureManager().bindTexture(TEXTURE);
|
||||
int x = (width - backgroundWidth) / 2;
|
||||
int y = (height - backgroundHeight) / 2;
|
||||
drawTexture(matrices, x, y, 0, 0, backgroundWidth, backgroundHeight);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,47 @@
|
|||
/*
|
||||
* Copyright (c) 2016, 2017, 2018, 2019 FabricMC
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package net.fabricmc.fabric.test.screenhandler.item;
|
||||
|
||||
import net.minecraft.inventory.Inventories;
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.nbt.CompoundTag;
|
||||
import net.minecraft.util.collection.DefaultedList;
|
||||
|
||||
final class BagInventory implements ImplementedInventory {
|
||||
private final ItemStack stack;
|
||||
private final DefaultedList<ItemStack> items = DefaultedList.ofSize(9, ItemStack.EMPTY);
|
||||
|
||||
BagInventory(ItemStack stack) {
|
||||
this.stack = stack;
|
||||
CompoundTag tag = stack.getSubTag("Items");
|
||||
|
||||
if (tag != null) {
|
||||
Inventories.fromTag(tag, items);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public DefaultedList<ItemStack> getItems() {
|
||||
return items;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void markDirty() {
|
||||
CompoundTag tag = stack.getOrCreateSubTag("Items");
|
||||
Inventories.toTag(tag, items);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,47 @@
|
|||
/*
|
||||
* Copyright (c) 2016, 2017, 2018, 2019 FabricMC
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package net.fabricmc.fabric.test.screenhandler.item;
|
||||
|
||||
import net.minecraft.entity.player.PlayerEntity;
|
||||
import net.minecraft.item.Item;
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.screen.NamedScreenHandlerFactory;
|
||||
import net.minecraft.screen.SimpleNamedScreenHandlerFactory;
|
||||
import net.minecraft.util.Hand;
|
||||
import net.minecraft.util.TypedActionResult;
|
||||
import net.minecraft.world.World;
|
||||
|
||||
import net.fabricmc.fabric.test.screenhandler.screen.BagScreenHandler;
|
||||
|
||||
public class BagItem extends Item {
|
||||
public BagItem(Settings settings) {
|
||||
super(settings);
|
||||
}
|
||||
|
||||
@Override
|
||||
public TypedActionResult<ItemStack> use(World world, PlayerEntity user, Hand hand) {
|
||||
ItemStack stack = user.getStackInHand(hand);
|
||||
user.openHandledScreen(createScreenHandlerFactory(stack));
|
||||
return TypedActionResult.success(stack);
|
||||
}
|
||||
|
||||
private NamedScreenHandlerFactory createScreenHandlerFactory(ItemStack stack) {
|
||||
return new SimpleNamedScreenHandlerFactory((syncId, inventory, player) -> {
|
||||
return new BagScreenHandler(syncId, inventory, new BagInventory(stack));
|
||||
}, stack.getName());
|
||||
}
|
||||
}
|
|
@ -0,0 +1,232 @@
|
|||
/*
|
||||
* Copyright (c) 2016, 2017, 2018, 2019 FabricMC
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package net.fabricmc.fabric.test.screenhandler.item;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import net.minecraft.entity.player.PlayerEntity;
|
||||
import net.minecraft.inventory.Inventories;
|
||||
import net.minecraft.inventory.Inventory;
|
||||
import net.minecraft.inventory.SidedInventory;
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.nbt.CompoundTag;
|
||||
import net.minecraft.util.collection.DefaultedList;
|
||||
import net.minecraft.util.math.Direction;
|
||||
|
||||
/**
|
||||
* A simple {@code SidedInventory} implementation with only default methods + an item list getter.
|
||||
*
|
||||
* <h2>Reading and writing to tags</h2>
|
||||
* Use {@link Inventories#fromTag(CompoundTag, DefaultedList)} and {@link Inventories#toTag(CompoundTag, DefaultedList)}
|
||||
* on {@linkplain #getItems() the item list}.
|
||||
*
|
||||
* @author Juuz
|
||||
*/
|
||||
@FunctionalInterface
|
||||
public interface ImplementedInventory extends SidedInventory {
|
||||
/**
|
||||
* Gets the item list of this inventory.
|
||||
* Must return the same instance every time it's called.
|
||||
*
|
||||
* @return the item list
|
||||
*/
|
||||
DefaultedList<ItemStack> getItems();
|
||||
|
||||
// Creation
|
||||
|
||||
/**
|
||||
* Creates an inventory from the item list.
|
||||
*
|
||||
* @param items the item list
|
||||
* @return a new inventory
|
||||
*/
|
||||
static ImplementedInventory of(DefaultedList<ItemStack> items) {
|
||||
return () -> items;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new inventory with the size.
|
||||
*
|
||||
* @param size the inventory size
|
||||
* @return a new inventory
|
||||
*/
|
||||
static ImplementedInventory ofSize(int size) {
|
||||
return of(DefaultedList.ofSize(size, ItemStack.EMPTY));
|
||||
}
|
||||
|
||||
// SidedInventory
|
||||
|
||||
/**
|
||||
* Gets the available slots to automation on the side.
|
||||
*
|
||||
* <p>The default implementation returns an array of all slots.
|
||||
*
|
||||
* @param side the side
|
||||
* @return the available slots
|
||||
*/
|
||||
@Override
|
||||
default int[] getAvailableSlots(Direction side) {
|
||||
int[] result = new int[getItems().size()];
|
||||
|
||||
for (int i = 0; i < result.length; i++) {
|
||||
result[i] = i;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if the stack can be inserted in the slot at the side.
|
||||
*
|
||||
* <p>The default implementation returns true.
|
||||
*
|
||||
* @param slot the slot
|
||||
* @param stack the stack
|
||||
* @param side the side
|
||||
* @return true if the stack can be inserted
|
||||
*/
|
||||
@Override
|
||||
default boolean canInsert(int slot, ItemStack stack, Direction side) {
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if the stack can be extracted from the slot at the side.
|
||||
*
|
||||
* <p>The default implementation returns true.
|
||||
*
|
||||
* @param slot the slot
|
||||
* @param stack the stack
|
||||
* @param side the side
|
||||
* @return true if the stack can be extracted
|
||||
*/
|
||||
@Override
|
||||
default boolean canExtract(int slot, ItemStack stack, Direction side) {
|
||||
return true;
|
||||
}
|
||||
|
||||
// Inventory
|
||||
|
||||
/**
|
||||
* Returns the inventory size.
|
||||
*
|
||||
* <p>The default implementation returns the size of {@link #getItems()}.
|
||||
*
|
||||
* @return the inventory size
|
||||
*/
|
||||
@Override
|
||||
default int size() {
|
||||
return getItems().size();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return true if this inventory has only empty stacks, false otherwise
|
||||
*/
|
||||
@Override
|
||||
default boolean isEmpty() {
|
||||
for (int i = 0; i < size(); i++) {
|
||||
ItemStack stack = getStack(i);
|
||||
|
||||
if (!stack.isEmpty()) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the item in the slot.
|
||||
*
|
||||
* @param slot the slot
|
||||
* @return the item in the slot
|
||||
*/
|
||||
@Override
|
||||
default ItemStack getStack(int slot) {
|
||||
return getItems().get(slot);
|
||||
}
|
||||
|
||||
/**
|
||||
* Takes a stack of the size from the slot.
|
||||
*
|
||||
* <p>(default implementation) If there are less items in the slot than what are requested,
|
||||
* takes all items in that slot.
|
||||
*
|
||||
* @param slot the slot
|
||||
* @param count the item count
|
||||
* @return a stack
|
||||
*/
|
||||
@Override
|
||||
default ItemStack removeStack(int slot, int count) {
|
||||
ItemStack result = Inventories.splitStack(getItems(), slot, count);
|
||||
|
||||
if (!result.isEmpty()) {
|
||||
markDirty();
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes the current stack in the {@code slot} and returns it.
|
||||
*
|
||||
* <p>The default implementation uses {@link Inventories#removeStack(List, int)}
|
||||
*
|
||||
* @param slot the slot
|
||||
* @return the removed stack
|
||||
*/
|
||||
@Override
|
||||
default ItemStack removeStack(int slot) {
|
||||
return Inventories.removeStack(getItems(), slot);
|
||||
}
|
||||
|
||||
/**
|
||||
* Replaces the current stack in the {@code slot} with the provided stack.
|
||||
*
|
||||
* <p>If the stack is too big for this inventory ({@link Inventory#getMaxCountPerStack()} ()}),
|
||||
* it gets resized to this inventory's maximum amount.
|
||||
*
|
||||
* @param slot the slot
|
||||
* @param stack the stack
|
||||
*/
|
||||
@Override
|
||||
default void setStack(int slot, ItemStack stack) {
|
||||
getItems().set(slot, stack);
|
||||
|
||||
if (stack.getCount() > getMaxCountPerStack()) {
|
||||
stack.setCount(getMaxCountPerStack());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Clears {@linkplain #getItems() the item list}}.
|
||||
*/
|
||||
@Override
|
||||
default void clear() {
|
||||
getItems().clear();
|
||||
}
|
||||
|
||||
@Override
|
||||
default void markDirty() {
|
||||
// Override if you want behavior.
|
||||
}
|
||||
|
||||
@Override
|
||||
default boolean canPlayerUse(PlayerEntity player) {
|
||||
return true;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,76 @@
|
|||
/*
|
||||
* Copyright (c) 2016, 2017, 2018, 2019 FabricMC
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package net.fabricmc.fabric.test.screenhandler.item;
|
||||
|
||||
import net.minecraft.entity.player.PlayerEntity;
|
||||
import net.minecraft.entity.player.PlayerInventory;
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.item.ItemUsageContext;
|
||||
import net.minecraft.network.PacketByteBuf;
|
||||
import net.minecraft.screen.ScreenHandler;
|
||||
import net.minecraft.server.network.ServerPlayerEntity;
|
||||
import net.minecraft.text.Text;
|
||||
import net.minecraft.util.ActionResult;
|
||||
import net.minecraft.util.Hand;
|
||||
import net.minecraft.util.TypedActionResult;
|
||||
import net.minecraft.util.math.BlockPos;
|
||||
import net.minecraft.world.World;
|
||||
|
||||
import net.fabricmc.fabric.api.screenhandler.v1.ExtendedScreenHandlerFactory;
|
||||
import net.fabricmc.fabric.test.screenhandler.screen.PositionedBagScreenHandler;
|
||||
|
||||
public class PositionedBagItem extends BagItem {
|
||||
public PositionedBagItem(Settings settings) {
|
||||
super(settings);
|
||||
}
|
||||
|
||||
@Override
|
||||
public TypedActionResult<ItemStack> use(World world, PlayerEntity user, Hand hand) {
|
||||
ItemStack stack = user.getStackInHand(hand);
|
||||
user.openHandledScreen(createScreenHandlerFactory(stack, null));
|
||||
return TypedActionResult.success(stack);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ActionResult useOnBlock(ItemUsageContext context) {
|
||||
PlayerEntity user = context.getPlayer();
|
||||
ItemStack stack = user.getStackInHand(context.getHand());
|
||||
BlockPos pos = context.getBlockPos();
|
||||
user.openHandledScreen(createScreenHandlerFactory(stack, pos));
|
||||
return ActionResult.SUCCESS;
|
||||
}
|
||||
|
||||
private ExtendedScreenHandlerFactory createScreenHandlerFactory(ItemStack stack, BlockPos pos) {
|
||||
return new ExtendedScreenHandlerFactory() {
|
||||
@Override
|
||||
public ScreenHandler createMenu(int syncId, PlayerInventory inventory, PlayerEntity player) {
|
||||
return new PositionedBagScreenHandler(syncId, inventory, new BagInventory(stack), pos);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Text getDisplayName() {
|
||||
return stack.getName();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeScreenOpeningData(ServerPlayerEntity player, PacketByteBuf buf) {
|
||||
buf.writeBoolean(pos != null);
|
||||
buf.writeBlockPos(pos != null ? pos : BlockPos.ORIGIN);
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
|
@ -0,0 +1,65 @@
|
|||
/*
|
||||
* Copyright (c) 2016, 2017, 2018, 2019 FabricMC
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package net.fabricmc.fabric.test.screenhandler.screen;
|
||||
|
||||
import net.minecraft.entity.player.PlayerEntity;
|
||||
import net.minecraft.entity.player.PlayerInventory;
|
||||
import net.minecraft.inventory.Inventory;
|
||||
import net.minecraft.inventory.SimpleInventory;
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.screen.Generic3x3ContainerScreenHandler;
|
||||
import net.minecraft.screen.ScreenHandlerType;
|
||||
import net.minecraft.screen.slot.SlotActionType;
|
||||
|
||||
import net.fabricmc.fabric.test.screenhandler.ScreenHandlerTest;
|
||||
import net.fabricmc.fabric.test.screenhandler.item.BagItem;
|
||||
|
||||
public class BagScreenHandler extends Generic3x3ContainerScreenHandler {
|
||||
private final ScreenHandlerType<?> type;
|
||||
|
||||
public BagScreenHandler(int syncId, PlayerInventory playerInventory) {
|
||||
this(syncId, playerInventory, new SimpleInventory(9));
|
||||
}
|
||||
|
||||
public BagScreenHandler(int syncId, PlayerInventory playerInventory, Inventory inventory) {
|
||||
this(ScreenHandlerTest.BAG_SCREEN_HANDLER, syncId, playerInventory, inventory);
|
||||
}
|
||||
|
||||
protected BagScreenHandler(ScreenHandlerType<?> type, int syncId, PlayerInventory playerInventory, Inventory inventory) {
|
||||
super(syncId, playerInventory, inventory);
|
||||
this.type = type;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ScreenHandlerType<?> getType() {
|
||||
return type;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ItemStack onSlotClick(int slotId, int clickData, SlotActionType actionType, PlayerEntity playerEntity) {
|
||||
if (slotId >= 0) { // slotId < 0 are used for networking internals
|
||||
ItemStack stack = getSlot(slotId).getStack();
|
||||
|
||||
if (stack.getItem() instanceof BagItem) {
|
||||
// Prevent moving bags around
|
||||
return stack;
|
||||
}
|
||||
}
|
||||
|
||||
return super.onSlotClick(slotId, clickData, actionType, playerEntity);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,50 @@
|
|||
/*
|
||||
* Copyright (c) 2016, 2017, 2018, 2019 FabricMC
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package net.fabricmc.fabric.test.screenhandler.screen;
|
||||
|
||||
import net.minecraft.entity.player.PlayerInventory;
|
||||
import net.minecraft.inventory.Inventory;
|
||||
import net.minecraft.network.PacketByteBuf;
|
||||
import net.minecraft.screen.Generic3x3ContainerScreenHandler;
|
||||
import net.minecraft.screen.ScreenHandlerType;
|
||||
import net.minecraft.util.math.BlockPos;
|
||||
|
||||
import net.fabricmc.fabric.test.screenhandler.ScreenHandlerTest;
|
||||
|
||||
public class BoxScreenHandler extends Generic3x3ContainerScreenHandler implements PositionedScreenHandler {
|
||||
private final BlockPos pos;
|
||||
|
||||
public BoxScreenHandler(int syncId, PlayerInventory playerInventory, PacketByteBuf buf) {
|
||||
super(syncId, playerInventory);
|
||||
this.pos = buf.readBlockPos();
|
||||
}
|
||||
|
||||
public BoxScreenHandler(int syncId, PlayerInventory playerInventory, Inventory inventory) {
|
||||
super(syncId, playerInventory, inventory);
|
||||
this.pos = BlockPos.ORIGIN;
|
||||
}
|
||||
|
||||
@Override
|
||||
public BlockPos getPos() {
|
||||
return pos;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ScreenHandlerType<?> getType() {
|
||||
return ScreenHandlerTest.BOX_SCREEN_HANDLER;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,49 @@
|
|||
/*
|
||||
* Copyright (c) 2016, 2017, 2018, 2019 FabricMC
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package net.fabricmc.fabric.test.screenhandler.screen;
|
||||
|
||||
import net.minecraft.entity.player.PlayerInventory;
|
||||
import net.minecraft.inventory.Inventory;
|
||||
import net.minecraft.inventory.SimpleInventory;
|
||||
import net.minecraft.network.PacketByteBuf;
|
||||
import net.minecraft.util.math.BlockPos;
|
||||
|
||||
import net.fabricmc.fabric.test.screenhandler.ScreenHandlerTest;
|
||||
|
||||
public class PositionedBagScreenHandler extends BagScreenHandler implements PositionedScreenHandler {
|
||||
private final BlockPos pos;
|
||||
|
||||
public PositionedBagScreenHandler(int syncId, PlayerInventory playerInventory, PacketByteBuf buf) {
|
||||
this(syncId, playerInventory, new SimpleInventory(9), readOptionalPos(buf));
|
||||
}
|
||||
|
||||
private static BlockPos readOptionalPos(PacketByteBuf buf) {
|
||||
boolean hasPos = buf.readBoolean();
|
||||
BlockPos pos = buf.readBlockPos();
|
||||
return hasPos ? pos : null;
|
||||
}
|
||||
|
||||
public PositionedBagScreenHandler(int syncId, PlayerInventory playerInventory, Inventory inventory, BlockPos pos) {
|
||||
super(ScreenHandlerTest.POSITIONED_BAG_SCREEN_HANDLER, syncId, playerInventory, inventory);
|
||||
this.pos = pos;
|
||||
}
|
||||
|
||||
@Override
|
||||
public BlockPos getPos() {
|
||||
return pos;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,23 @@
|
|||
/*
|
||||
* Copyright (c) 2016, 2017, 2018, 2019 FabricMC
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package net.fabricmc.fabric.test.screenhandler.screen;
|
||||
|
||||
import net.minecraft.util.math.BlockPos;
|
||||
|
||||
public interface PositionedScreenHandler {
|
||||
BlockPos getPos();
|
||||
}
|
|
@ -0,0 +1,5 @@
|
|||
{
|
||||
"variants": {
|
||||
"": { "model": "fabric-screen-handler-api-v1-testmod:block/box" }
|
||||
}
|
||||
}
|
|
@ -0,0 +1,5 @@
|
|||
{
|
||||
"block.fabric-screen-handler-api-v1-testmod.box": "Box",
|
||||
"item.fabric-screen-handler-api-v1-testmod.bag": "Bag",
|
||||
"item.fabric-screen-handler-api-v1-testmod.positioned_bag": "Positioned Bag"
|
||||
}
|
|
@ -0,0 +1,6 @@
|
|||
{
|
||||
"parent": "minecraft:block/cube_all",
|
||||
"textures": {
|
||||
"all": "fabric-screen-handler-api-v1-testmod:block/box"
|
||||
}
|
||||
}
|
|
@ -0,0 +1,6 @@
|
|||
{
|
||||
"parent": "item/generated",
|
||||
"textures": {
|
||||
"layer0": "fabric-screen-handler-api-v1-testmod:item/bag"
|
||||
}
|
||||
}
|
|
@ -0,0 +1,3 @@
|
|||
{
|
||||
"parent": "fabric-screen-handler-api-v1-testmod:block/box"
|
||||
}
|
|
@ -0,0 +1,6 @@
|
|||
{
|
||||
"parent": "item/generated",
|
||||
"textures": {
|
||||
"layer0": "fabric-screen-handler-api-v1-testmod:item/positioned_bag"
|
||||
}
|
||||
}
|
Binary file not shown.
After ![]() (image error) Size: 616 B |
Binary file not shown.
After ![]() (image error) Size: 837 B |
Binary file not shown.
After ![]() (image error) Size: 2 KiB |
|
@ -0,0 +1,19 @@
|
|||
{
|
||||
"type": "minecraft:block",
|
||||
"pools": [
|
||||
{
|
||||
"rolls": 1,
|
||||
"entries": [
|
||||
{
|
||||
"type": "minecraft:item",
|
||||
"name": "fabric-screen-handler-api-v1-testmod:box"
|
||||
}
|
||||
],
|
||||
"conditions": [
|
||||
{
|
||||
"condition": "minecraft:survives_explosion"
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
|
@ -0,0 +1,20 @@
|
|||
{
|
||||
"schemaVersion": 1,
|
||||
"id": "fabric-screen-handler-api-v1-testmod",
|
||||
"name": "Fabric Screen Handler API (v1) Test Mod",
|
||||
"version": "1.0.0",
|
||||
"environment": "*",
|
||||
"license": "Apache-2.0",
|
||||
"depends": {
|
||||
"fabric-resource-loader-v0": "*",
|
||||
"fabric-screen-handler-api-v1": "*"
|
||||
},
|
||||
"entrypoints": {
|
||||
"main": [
|
||||
"net.fabricmc.fabric.test.screenhandler.ScreenHandlerTest"
|
||||
],
|
||||
"client": [
|
||||
"net.fabricmc.fabric.test.screenhandler.client.ClientScreenHandlerTest"
|
||||
]
|
||||
}
|
||||
}
|
|
@ -44,6 +44,7 @@ include 'fabric-rendering-v1'
|
|||
include 'fabric-rendering-data-attachment-v1'
|
||||
include 'fabric-rendering-fluids-v1'
|
||||
include 'fabric-resource-loader-v0'
|
||||
include 'fabric-screen-handler-api-v1'
|
||||
include 'fabric-tag-extensions-v0'
|
||||
include 'fabric-textures-v0'
|
||||
include 'fabric-tool-attribute-api-v1'
|
||||
|
|
Loading…
Add table
Reference in a new issue