Skip to main content

Using Prebuilt Classes

MrCrayfish's Furniture Mod: Refurbished provides many prebuilt classes that you can extend to avoid common boilerplate code. You'll need to decide whether you are going to create a Module or a Source. A Module is an electricity block that recieves electrical power (like the Computer), while a Source is an electricity block (like the Electricity Generator) that produces and provides electrical power to modules.

For a block entity to become an electricity block, they implement one of the following interfaces: IModuleNode for Modules, and ISourceNode for Sources. Since this guide is about using one of the prebuilt classes, you will not need to worry about implementing these interfaces. You can however read the Custom Implementation guide to learn more about how the electricity system is implemented from scratch.

List of Available Classes

Create a new block and make it extend one of the classes below. All classes are available under the package: com.mrcrayfish.furniture.refurbished.blockentity

Officially Supported

  • Module ElectricityModuleBlockEntity - Base class of BlockEntity with IModuleNode implementation.
  • Module ElectricityModuleContainerBlockEntity - Vanilla's container block entity with IModuleNode implementation.
  • Source ElectricitySourceBlockEntity - Base class of BlockEntity with ISourceNode implementation.
  • Source ElectricitySourceContainerBlockEntity - Vanilla's container block entity with ISourceNode implementation.

Extras

You may additonally use some custom classes created for the mod. They are used frequently in the mod for setting up new containers and processing blocks. There are no gaurantees these will be suitable for your use case, they are custom designed for the mod. Use at your own discretion!

  • Module ElectricityModuleLootBlockEntity - A class extending BasicLootBlockEntity, a custom class used in the mod to help set up new container blocks. It uses a IModuleNode implementation. You can see an example of it being used for the Workbench.
  • Module ElectricityModuleProcessingLootBlockEntity - A class extending ProcessingContainerBlockEntity, a custom class used in the mod to help set up new processing blocks with containers. It uses a IModuleNode implementation. You can see an example of it being used for the Freezer.
  • Source ElectricitySourceLootBlockEntity - A class extending BasicLootBlockEntity, a custom class used in the mod to help set up new container blocks. It uses a ISourceNode implementation. You can see an example of it being used for the Electricity Generator.

Implementing the Methods

Every electricity block, modules and sources, have a powered state. Upon extending one of the classes, there are two core methods you'll need to implement: isNodePowered() and setNodePowered(boolean). These methods control the powered state and must be implemented correctly for your block to work. It is important that the implementation of isNodePowered() returns the correct state on both client and server side. The powered state must also be saved to disk. This guide will cover two options for implementing these methods.

note

Depending on the class you extend, there may be more methods you need to write an implementation for. This guide will not cover vanilla methods or methods from classes in the Extras section.

Block State Property Easy

This is the best option when it comes to implementing the powered state as you do not need to worry about saving and syncing the value, the game already handles this for you. It is also great as allows you to change the model of your block; you can show a different block model when it is powered. Below is all the code you need in your block entity.

ExampleBlockEntity.java
@Override
public boolean isNodePowered() {
BlockState state = this.getBlockState();
return state.hasProperty(BlockStateProperties.POWERED) && state.getValue(BlockStateProperties.POWERED);
}

@Override
public void setNodePowered(boolean powered) {
BlockState state = this.getBlockState();
if(state.hasProperty(BlockStateProperties.POWERED)) {
this.level.setBlock(this.worldPosition, state.setValue(BlockStateProperties.POWERED, powered), Block.UPDATE_ALL);
}
}

Block Entity Variable Advanced

If you've gone with a simple boolean variable in your block entity class to represent the powered state, you will need to handle loading/saving and syncing. This is however quite simple, you just need to append the following to your load(CompoundTag) and saveAdditional(CompoundTag) methods of your block entity.

note

The following example is an implementation that will sync everything in saveAdditional(CompoundTag) to clients. This may not be ideal since you should only send what is needed for the client. You can customise what is sent to the client by overriding the method getUpdateTag(). Make sure powered state and the nodes connections are still sent if you override this method.

ExampleBlockEntity.java
// Your variable, may be named different
protected boolean powered;

@Override
public boolean isNodePowered() {
return this.powered;
}

@Override
public void setNodePowered(boolean powered) {
this.powered = powered;
// From BlockEntity. Must call or block entity won't save.
this.setChanged();
// From IElectricityNode. Helper method to sync block entity data
// You must update clients immediately of change.
this.syncDataToTrackingClients();
}

@Override
public void load(CompoundTag tag) {
// ...
this.powered = tag.getBoolean("Powered");
}

@Override
public void saveAdditional(CompoundTag tag) {
// ...
tag.putBoolean("Powered", this.powered);
}

Register the Block Entity Renderer

In order to render the node and its connections, you'll need to register a block entity renderer for your block entity. This is also crucial for enabling interaction with the Wrench.

MrCrayfish's Furniture Mod: Refurbished comes with a default block entity renderer for electricity blocks. Simply bind your block entity type with ElectricBlockEntityRenderer and rendering and interactions will be handled for you. This option is only suitable if you don't plan to do any extra rendering. See Custom Implementation for explainations on creating a custom block entity renderer.

import com.mrcrayfish.furniture.refurbished.client.renderer.blockentity.ElectricBlockEntityRenderer;

// Make sure to register this event on the mod event bus
public static void onRegisterRenderers(EntityRenderersEvent.RegisterRenderers event) {
// Replace <YourBlockEntityType> with the instance of the block entity type
event.registerBlockEntityRenderer(<YourBlockEntityType>, ElectricBlockEntityRenderer::new);
}