Skip to content

Commit eed85fa

Browse files
Merge pull request #18 from CodeMonkeysMods/feat/add-furnace-block-basics
More workbench block abstractions
2 parents 5da607c + bcaaf02 commit eed85fa

22 files changed

Lines changed: 1606 additions & 285 deletions
Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,22 @@
11
package com.tcm.MineTale;
22

33
import com.tcm.MineTale.block.workbenches.screen.FurnaceWorkbenchScreen;
4+
import com.tcm.MineTale.block.workbenches.screen.CampfireWorkbenchScreen;
45
import com.tcm.MineTale.registry.ModMenuTypes;
56

67
import net.fabricmc.api.ClientModInitializer;
78
import net.minecraft.client.gui.screens.MenuScreens;
89

910
public class MineTaleClient implements ClientModInitializer {
1011
/**
11-
* Registers the screen factory for the furnace workbench menu so the client can create FurnaceWorkbenchScreen instances for that menu type.
12+
* Registers client-side screen factories for custom workbench menu types.
13+
*
14+
* Binds the furnace and campfire workbench menu types to their corresponding screen constructors
15+
* so the client can create the appropriate GUI when those menus are opened.
1216
*/
1317
@Override
1418
public void onInitializeClient() {
1519
MenuScreens.register(ModMenuTypes.FURNACE_WORKBENCH_MENU, FurnaceWorkbenchScreen::new);
20+
MenuScreens.register(ModMenuTypes.CAMPFIRE_WORKBENCH_MENU, CampfireWorkbenchScreen::new);
1621
}
1722
}
Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
package com.tcm.MineTale.block.workbenches.screen;
2+
3+
import com.tcm.MineTale.block.workbenches.menu.CampfireWorkbenchMenu;
4+
5+
import net.minecraft.client.gui.GuiGraphics;
6+
import net.minecraft.client.gui.screens.inventory.AbstractContainerScreen;
7+
import net.minecraft.client.renderer.RenderPipelines;
8+
import net.minecraft.resources.Identifier;
9+
import net.minecraft.world.entity.player.Inventory;
10+
import net.minecraft.network.chat.Component;
11+
12+
public class CampfireWorkbenchScreen extends AbstractContainerScreen<CampfireWorkbenchMenu> {
13+
private static final Identifier TEXTURE =
14+
// Identifier.fromNamespaceAndPath(MineTale.MOD_ID, "textures/gui/container/furnace_workbench.png");
15+
Identifier.withDefaultNamespace("textures/gui/container/furnace.png");
16+
17+
/**
18+
* Creates a campfire workbench screen for the provided menu, player inventory, and title.
19+
*
20+
* @param menu the container menu that provides slots and synchronizes state for this screen
21+
* @param inventory the player's inventory to display and interact with
22+
* @param title the title component shown at the top of the screen
23+
*/
24+
public CampfireWorkbenchScreen(CampfireWorkbenchMenu menu, Inventory inventory, Component title) {
25+
super(menu, inventory, title);
26+
}
27+
28+
/**
29+
* Initializes the screen and centers the title horizontally by setting {@code titleLabelX}.
30+
*/
31+
@Override
32+
protected void init() {
33+
super.init();
34+
this.titleLabelX = (this.imageWidth - this.font.width(this.title)) / 2;
35+
}
36+
37+
/**
38+
* Renders the campfire workbench background texture at the screen's top-left position.
39+
*
40+
* @param guiGraphics the graphics context used for drawing
41+
* @param f partial ticks for interpolation
42+
* @param i current mouse x position
43+
* @param j current mouse y position
44+
*/
45+
protected void renderBg(GuiGraphics guiGraphics, float f, int i, int j) {
46+
int k = this.leftPos;
47+
int l = this.topPos;
48+
guiGraphics.blit(RenderPipelines.GUI_TEXTURED, TEXTURE, k, l, 0.0F, 0.0F, this.imageWidth, this.imageHeight, 256, 256);
49+
}
50+
51+
/**
52+
* Renders the campfire workbench screen, drawing its background, contents, and tooltips.
53+
*
54+
* @param graphics the graphics context used for rendering
55+
* @param mouseX the current mouse X coordinate
56+
* @param mouseY the current mouse Y coordinate
57+
* @param delta the frame time delta (partial tick) used for animated rendering
58+
*/
59+
@Override
60+
public void render(GuiGraphics graphics, int mouseX, int mouseY, float delta) {
61+
renderBackground(graphics, mouseX, mouseY, delta);
62+
super.render(graphics, mouseX, mouseY, delta);
63+
renderTooltip(graphics, mouseX, mouseY);
64+
}
65+
}
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
// 1.21.11 -999999999-01-01T00:00:00 Example mod/minetaleModRecipeProvider
2+
dcc5dac31dc51d16b53e14666f87d47297089c0d data/minetale/advancement/recipes/campfire_pork_cooking.json
3+
96af174cae154bddc108902a40e90c9bd971c7cf data/minetale/recipe/campfire_pork_cooking.json
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
{
2+
"parent": "minecraft:recipes/root",
3+
"criteria": {
4+
"has_the_recipe": {
5+
"conditions": {
6+
"recipe": "minetale:campfire_pork_cooking"
7+
},
8+
"trigger": "minecraft:recipe_unlocked"
9+
}
10+
},
11+
"requirements": [
12+
[
13+
"has_the_recipe"
14+
]
15+
],
16+
"rewards": {
17+
"recipes": [
18+
"minetale:campfire_pork_cooking"
19+
]
20+
}
21+
}
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
{
2+
"type": "minetale:campfire_alloying",
3+
"cookTime": 600,
4+
"ingredients": [
5+
"minecraft:porkchop"
6+
],
7+
"results": [
8+
{
9+
"count": 1,
10+
"id": "minecraft:cooked_porkchop"
11+
}
12+
]
13+
}

src/main/java/com/tcm/MineTale/MineTale.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
import com.tcm.MineTale.registry.ModEntityDataSerializers;
1414
import com.tcm.MineTale.registry.ModItems;
1515
import com.tcm.MineTale.registry.ModMenuTypes;
16+
import com.tcm.MineTale.registry.ModRecipes;
1617

1718
import static com.tcm.MineTale.item.ModCreativeTab.MINETALE_CREATIVE_TAB;
1819
import static com.tcm.MineTale.item.ModCreativeTab.MINETALE_CREATIVE_TAB_KEY;
@@ -34,6 +35,7 @@ public class MineTale implements ModInitializer {
3435
@Override
3536
public void onInitialize() {
3637
ModBlocks.initialize();
38+
ModRecipes.initialize();
3739
ModBlockEntities.initialize();
3840
ModMenuTypes.initialize();
3941
ModEntities.initialize();

src/main/java/com/tcm/MineTale/block/workbenches/CampfireWorkbench.java

Lines changed: 29 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -5,23 +5,22 @@
55
import org.jetbrains.annotations.Nullable;
66

77
import com.mojang.serialization.MapCodec;
8+
import com.tcm.MineTale.block.workbenches.entity.AbstractWorkbenchEntity;
89
import com.tcm.MineTale.block.workbenches.entity.CampfireWorkbenchEntity;
910
import com.tcm.MineTale.registry.ModBlockEntities;
1011

1112
import net.minecraft.core.BlockPos;
1213
import net.minecraft.core.Direction;
13-
import net.minecraft.world.InteractionResult;
14-
import net.minecraft.world.entity.player.Player;
1514
import net.minecraft.world.level.BlockGetter;
1615
import net.minecraft.world.level.Level;
1716
import net.minecraft.world.level.block.Block;
1817
import net.minecraft.world.level.block.RenderShape;
1918
import net.minecraft.world.level.block.entity.BlockEntity;
19+
import net.minecraft.world.level.block.entity.BlockEntityTicker;
2020
import net.minecraft.world.level.block.entity.BlockEntityType;
2121
import net.minecraft.world.level.block.state.BlockState;
2222
import net.minecraft.world.level.block.state.properties.ChestType;
2323
import net.minecraft.world.level.block.state.properties.DoubleBlockHalf;
24-
import net.minecraft.world.phys.BlockHitResult;
2524
import net.minecraft.world.phys.shapes.CollisionContext;
2625
import net.minecraft.world.phys.shapes.VoxelShape;
2726

@@ -44,16 +43,33 @@ public CampfireWorkbench(Properties properties) {
4443
}
4544

4645
/**
47-
* Creates a CampfireWorkbench with the given block properties and block-entity type supplier.
46+
* Constructs a CampfireWorkbench using the provided block properties and block-entity type supplier.
4847
*
49-
* @param properties the block's properties
50-
* @param supplier supplier that provides the BlockEntityType for this workbench
48+
* @param properties block properties to apply to this workbench
49+
* @param supplier supplier that provides the BlockEntityType for the CampfireWorkbenchEntity
5150
*/
5251
public CampfireWorkbench(Properties properties, Supplier<BlockEntityType<? extends CampfireWorkbenchEntity>> supplier) {
5352
// isWide = false, isTall = false (1x1 footprint)
5453
super(properties, supplier, IS_WIDE, IS_TALL);
5554
}
5655

56+
/**
57+
* Provides a ticker that updates campfire workbench block entities each tick.
58+
*
59+
* @return a BlockEntityTicker that invokes AbstractWorkbenchEntity.tick for CampfireWorkbenchEntity instances, or `null` if the supplied block entity type does not match the campfire workbench type.
60+
*/
61+
@Nullable
62+
@Override
63+
public <T extends BlockEntity> BlockEntityTicker<T> getTicker(Level level, BlockState state, BlockEntityType<T> type) {
64+
// This connects the Level's ticking system to your static tick method
65+
return createTickerHelper(type, ModBlockEntities.CAMPFIRE_WORKBENCH_BE, AbstractWorkbenchEntity::tick);
66+
}
67+
68+
/**
69+
* The codec used to serialize and deserialize this CampfireWorkbench type.
70+
*
71+
* @return the MapCodec for this CampfireWorkbench
72+
*/
5773
@Override
5874
protected MapCodec<? extends CampfireWorkbench> codec() {
5975
return CODEC;
@@ -84,49 +100,18 @@ public VoxelShape getShape(BlockState state, BlockGetter level, BlockPos pos, Co
84100
}
85101

86102
/**
87-
* Creates and returns the block entity for this block only when the block represents the master
88-
* position (the lower half and not of type RIGHT).
103+
* Create a block entity for the master block of this workbench.
104+
*
105+
* Only the master block of the multi-block workbench receives an entity; other positions return {@code null}.
89106
*
90-
* @return the created BlockEntity when this block is the master (HALF == LOWER and TYPE != RIGHT), or `null` otherwise
107+
* @return the block entity for the master block ({@link CampfireWorkbenchEntity}), or {@code null} if this position does not host an entity
91108
*/
92109
@Nullable
93110
@Override
94111
public BlockEntity newBlockEntity(BlockPos pos, BlockState state) {
95-
// Only spawn the entity at the "Master" position (LOWER + LEFT or LOWER + SINGLE)
96-
if (state.getValue(HALF) == DoubleBlockHalf.LOWER && state.getValue(TYPE) != ChestType.RIGHT) {
97-
return blockEntityType.get().create(pos, state);
98-
}
99-
return null;
100-
}
101-
102-
/**
103-
* Handles a player's interaction with the workbench when no item is used.
104-
*
105-
* <p>On the client this acknowledges the interaction. On the server this method
106-
* is a hook for workbench-specific handling; if the workbench processes the
107-
* interaction it will consume it, otherwise the interaction is passed to other handlers.</p>
108-
*
109-
* @param state the block state of the workbench
110-
* @param level the world in which the interaction occurs
111-
* @param pos the position of the interacted block
112-
* @param player the player performing the interaction
113-
* @param hit the hit result describing the interaction point
114-
* @return {@code InteractionResult.SUCCESS} on client, {@code InteractionResult.CONSUME} if handled by the workbench, or {@code InteractionResult.PASS} otherwise
115-
*/
116-
@Override
117-
protected InteractionResult useWithoutItem(BlockState state, Level level, BlockPos pos, Player player, BlockHitResult hit) {
118-
if (level.isClientSide()) return InteractionResult.SUCCESS;
119-
120-
// BlockPos masterPos = getMasterPos(state, pos);
121-
// BlockEntity be = level.getBlockEntity(masterPos);
122-
123-
// if (be instanceof AbstractWorkbenchEntity) {
124-
// // Open UI or handle Recycling logic here
125-
// // Example: if player is holding a tool, try to recycle it
126-
// return InteractionResult.CONSUME;
127-
// }
128-
129-
return InteractionResult.PASS;
112+
// AbstractWorkbench logic ensures only the Master block gets the entity.
113+
// We override it here to point specifically to our Furnace entity.
114+
return super.newBlockEntity(pos, state);
130115
}
131116

132117
/**

0 commit comments

Comments
 (0)