User Tools

Site Tools


tutorial:propertydelegates

Differences

This shows you the differences between two versions of the page.

Link to this comparison view

Both sides previous revisionPrevious revision
Next revision
Previous revision
tutorial:propertydelegates [2020/08/14 17:06] manymoney2tutorial:propertydelegates [2022/05/27 16:00] (current) solidblock
Line 1: Line 1:
 ====== Syncing Integers with PropertyDelegates ====== ====== Syncing Integers with PropertyDelegates ======
-**PropertyDelegate:** A PropertyDelegate is a kind of Container which contains a specific amounts of integer values which can be read or changed.+**PropertyDelegate:** A ''PropertyDelegate'' is a kind of Container which contains a specific amounts of integer values which can be read or changed.
  
-In this Tutorial we will sync Integer values between the client and the Server, an example for this in vanilla would be the smelting progress of a furnace.+In this Tutorial we will sync Integer values between the client and the server, an example for this in Vanilla would be the smelting progress of a furnace.
  
-To understand this tutorial you need to read the first [[tutorial:screenhandler|Screenhandler]] tutorial. +To understand this tutorial you need to read the first [[tutorial:screenhandler|ScreenHandler]] tutorial. 
 Methods which have no code here were already shown in that tutorial. Methods which have no code here were already shown in that tutorial.
  
Line 11: Line 11:
 ====== BlockEntity ====== ====== BlockEntity ======
 As the Block class does not need to be changed at all we leave it out here. As the Block class does not need to be changed at all we leave it out here.
-Our BlockEntity now implements Tickable, this will provide the tick() method which gets called every tick. We use it to increase our Integer we want to sync+ 
 +Our ''BlockEntity'' now implements ''Tickable'', this will provide the ''tick()'' method which gets called every tick. We use it to increase our Integer we want to sync.
  
 <code java [enable_line_numbers="true"] BoxBlockEntity.java> <code java [enable_line_numbers="true"] BoxBlockEntity.java>
Line 66: Line 67:
     @Override     @Override
     public Text getDisplayName() {     public Text getDisplayName() {
-        return new TranslatableText(getCachedState().getBlock().getTranslationKey());+        // For versions 1.18.2 and below, please use return new TranslatableText(getCachedState().getBlock().getTranslationKey()); 
 +        return Text.translatable(getCachedState().getBlock().getTranslationKey());
     }     }
  
Line 78: Line 80:
  
 </code> </code>
 +
 +====== Our new ScreenHandler ======
 +<code java [enable_line_numbers="true"] BoxScreenHandler.java>
 +
 +public class BoxScreenHandler extends ScreenHandler {
 +    private final Inventory inventory;
 +    PropertyDelegate propertyDelegate;
 +
 +    //This constructor gets called on the client when the server wants it to open the screenHandler,
 +    //The client will call the super constructor with an empty Inventory and the screenHandler will automatically
 +    //sync this empty inventory with the inventory on the server
 +
 +    //Similar to the inventory, the client will allocate an empty propertyDelegate which will be synced with the Server automatically
 +    
 +    public BoxScreenHandler(int syncId, PlayerInventory playerInventory) {
 +        this(syncId, playerInventory, new SimpleInventory(9),new ArrayPropertyDelegate(1));
 +    }
 +
 +    //This constructor gets called from the BlockEntity on the server, the server knows the inventory of the container
 +    //and can therefore directly provide it as an argument. This inventory aswell as the propertyDelegate will then be synced to the Client
 +    public BoxScreenHandler(int syncId, PlayerInventory playerInventory, Inventory inventory, PropertyDelegate propertyDelegate) {
 +        super(Test.BOX_SCREEN_HANDLER, syncId);
 +        checkSize(inventory, 9);
 +        this.inventory = inventory;
 +        this.propertyDelegate = propertyDelegate;
 +        //some inventories do custom logic when a player opens it.
 +        inventory.onOpen(playerInventory.player);
 +        
 +        //we need to tell the screenhandler about our propertyDelegate, otherwise it will not sync the data inside.
 +        this.addProperties(propertyDelegate);
 +
 +        //This will place the slot in the correct locations for a 3x3 Grid. The slots exist on both server and client!
 +        [...]
 +
 +    }
 +    
 +    //we provide this getter for the synced integer so the Screen can access this to show it on screen
 +    public int getSyncedNumber(){
 +        return propertyDelegate.get(0);
 +    }
 +
 +    @Override
 +    public boolean canUse(PlayerEntity player) {
 +        return this.inventory.canPlayerUse(player);
 +    }
 +
 +    @Override
 +    public ItemStack transferSlot(PlayerEntity player, int invSlot) {[...]}
 +}
 +
 +
 +</code>
 +
 +====== Showing the Information with the Screen ======
 +As the screen gets the ''ScreenHandler'' in its constructor, we have access to the property delegate from above and can render the integer on screen.
 +<code java [enable_line_numbers="true"] BoxScreen.java>
 +
 +public class BoxScreen extends HandledScreen<ScreenHandler> {
 +    private static final Identifier TEXTURE = new Identifier("minecraft", "textures/gui/container/dispenser.png");
 +    BoxScreenHandler screenHandler;
 +
 +    public BoxScreen(ScreenHandler handler, PlayerInventory inventory, Text title) {
 +        super(handler, inventory, title);
 +        //we save a reference to the screenhandler so we can render the number from our propertyDelegate on screen
 +        screenHandler = (BoxScreenHandler) handler;
 +
 +    }
 +
 +    @Override
 +    protected void drawBackground(MatrixStack matrices, float delta, int mouseX, int mouseY) {[...]}
 +
 +    @Override
 +    public void render(MatrixStack matrices, int mouseX, int mouseY, float delta) {
 +        //We just render our synced number somewhere in the container, this is a demonstration after all
 +        //the last argument is a color code, making the font bright green
 +        textRenderer.draw(matrices, Integer.toString(screenHandler.getSyncedNumber()), 0, 0, 65280);
 +        renderBackground(matrices);
 +        super.render(matrices, mouseX, mouseY, delta);
 +        drawMouseoverTooltip(matrices, mouseX, mouseY);
 +    }
 +
 +    @Override
 +    protected void init() {
 +        super.init();
 +        // Center the title
 +        titleX = (backgroundWidth - textRenderer.getWidth(title)) / 2;
 +    }
 +}
 +
 +</code>
 +
 +====== Result ======
 +As the registration of the ''ScreenHandler'' is identical to that of the first tutorial we can see the result already!
 +When the BlockEntity is placed it will increase the ''syncedInt'' by one each tick; when we look inside the container, the integer will
 +automatically be synced to the client and rendered in the top left corner.
 +
 +[[https://streamable.com/7aic8q|Example Video]]
 +
 +If you want a more realistic example, you might want to have a look at ''AbstractFurnaceEntity'' and ''AbstractFurnaceScreenHandler'' in the Minecraft code.
  
  
tutorial/propertydelegates.1597424818.txt.gz · Last modified: 2020/08/14 17:06 by manymoney2