Skip to content

Commit 07a58ad

Browse files
fix: armorers can create items
1 parent dd6ea76 commit 07a58ad

3 files changed

Lines changed: 131 additions & 47 deletions

File tree

src/client/java/com/tcm/MineTale/block/workbenches/screen/ArmorersWorkbenchScreen.java

Lines changed: 55 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,8 @@ public class ArmorersWorkbenchScreen extends AbstractRecipeBookScreen<ArmorersWo
4343

4444
private final MineTaleRecipeBookComponent mineTaleRecipeBook;
4545

46+
private RecipeDisplayId lastKnownSelectedId = null;
47+
4648
private Button craftOneBtn;
4749
private Button craftTenBtn;
4850
private Button craftAllBtn;
@@ -81,10 +83,10 @@ private static MineTaleRecipeBookComponent createRecipeBookComponent(ArmorersWor
8183
ItemStack tabIcon = new ItemStack(ModBlocks.ARMORERS_WORKBENCH_BLOCK.asItem());
8284

8385
List<RecipeBookComponent.TabInfo> tabs = List.of(
84-
new RecipeBookComponent.TabInfo(tabIcon.getItem(), ModRecipeDisplay.WORKBENCH_SEARCH)
86+
new RecipeBookComponent.TabInfo(tabIcon.getItem(), ModRecipeDisplay.ARMORERS_SEARCH)
8587
);
8688

87-
return new MineTaleRecipeBookComponent(menu, tabs, ModRecipes.WORKBENCH_TYPE);
89+
return new MineTaleRecipeBookComponent(menu, tabs, ModRecipes.ARMORERS_TYPE);
8890
}
8991

9092
/**
@@ -128,34 +130,52 @@ protected void init() {
128130
* @param amount the quantity to craft; use -1 to request crafting of the full available stack ("All")
129131
*/
130132

131-
private void handleCraftRequest(int amount) {
132-
// 1. Cast the book component to the Accessor to get the selected data
133-
RecipeBookComponentAccessor accessor = (RecipeBookComponentAccessor) this.mineTaleRecipeBook;
133+
// private void handleCraftRequest(int amount) {
134+
// // 1. Cast the book component to the Accessor to get the selected data
135+
// RecipeBookComponentAccessor accessor = (RecipeBookComponentAccessor) this.mineTaleRecipeBook;
134136

135-
RecipeCollection collection = accessor.getLastRecipeCollection();
136-
RecipeDisplayId displayId = accessor.getLastRecipe();
137-
138-
if (collection != null && displayId != null) {
139-
// 2. Find the visual entry
140-
for (RecipeDisplayEntry entry : collection.getSelectedRecipes(RecipeCollection.CraftableStatus.ANY)) {
141-
if (entry.id().equals(displayId)) {
142-
// 3. Resolve result for the packet
143-
List<ItemStack> results = entry.resultItems(SlotDisplayContext.fromLevel(this.minecraft.level));
137+
// RecipeCollection collection = accessor.getLastRecipeCollection();
138+
// RecipeDisplayId displayId = accessor.getLastRecipe();
139+
140+
// if (collection != null && displayId != null) {
141+
// // 2. Find the visual entry
142+
// for (RecipeDisplayEntry entry : collection.getSelectedRecipes(RecipeCollection.CraftableStatus.ANY)) {
143+
// if (entry.id().equals(displayId)) {
144+
// // 3. Resolve result for the packet
145+
// List<ItemStack> results = entry.resultItems(SlotDisplayContext.fromLevel(this.minecraft.level));
144146

145-
if (!results.isEmpty()) {
146-
ItemStack resultStack = results.get(0);
147+
// if (!results.isEmpty()) {
148+
// ItemStack resultStack = results.get(0);
147149

148-
// 4. LOG FOR DEBUGGING
149-
System.out.println("Sending craft request for: " + resultStack + " amount: " + amount);
150+
// // 4. LOG FOR DEBUGGING
151+
// System.out.println("Sending craft request for: " + resultStack + " amount: " + amount);
150152

151-
ClientPlayNetworking.send(new CraftRequestPayload(resultStack, amount));
152-
}
153-
break;
153+
// ClientPlayNetworking.send(new CraftRequestPayload(resultStack, amount));
154+
// }
155+
// break;
156+
// }
157+
// }
158+
// } else {
159+
// System.out.println("Request failed: Collection or DisplayID is null!");
160+
// }
161+
// }
162+
163+
private void handleCraftRequest(int amount) {
164+
// Look at our "Memory" instead of the component
165+
if (this.lastKnownSelectedId != null) {
166+
ClientRecipeBook book = this.minecraft.player.getRecipeBook();
167+
RecipeDisplayEntry entry = ((ClientRecipeBookAccessor) book).getKnown().get(this.lastKnownSelectedId);
168+
169+
if (entry != null) {
170+
List<ItemStack> results = entry.resultItems(SlotDisplayContext.fromLevel(this.minecraft.level));
171+
if (!results.isEmpty()) {
172+
System.out.println("Persistent Selection Success: " + results.get(0));
173+
ClientPlayNetworking.send(new CraftRequestPayload(results.get(0), amount));
174+
return;
154175
}
155176
}
156-
} else {
157-
System.out.println("Request failed: Collection or DisplayID is null!");
158177
}
178+
System.out.println("Request failed: No recipe was ever selected!");
159179
}
160180

161181
/**
@@ -177,18 +197,22 @@ public void render(GuiGraphics graphics, int mouseX, int mouseY, float delta) {
177197
renderBackground(graphics, mouseX, mouseY, delta);
178198
super.render(graphics, mouseX, mouseY, delta);
179199

180-
// Get the ID of the recipe clicked in the ghost-book
181-
RecipeDisplayId displayId = this.mineTaleRecipeBook.getSelectedRecipeId();
182-
RecipeDisplayEntry selectedEntry = null;
200+
// 1. Get the current selection from the book
201+
RecipeDisplayId currentId = this.mineTaleRecipeBook.getSelectedRecipeId();
202+
203+
// 2. If it's NOT null, remember it!
204+
if (currentId != null) {
205+
this.lastKnownSelectedId = currentId;
206+
}
183207

184-
if (displayId != null && this.minecraft.level != null) {
208+
// 3. Use the remembered ID to find the entry for button activation
209+
RecipeDisplayEntry selectedEntry = null;
210+
if (this.lastKnownSelectedId != null && this.minecraft.level != null) {
185211
ClientRecipeBook book = this.minecraft.player.getRecipeBook();
186-
// Accessing the known recipes via your Accessor
187-
Map<RecipeDisplayId, RecipeDisplayEntry> knownRecipes = ((ClientRecipeBookAccessor) book).getKnown();
188-
selectedEntry = knownRecipes.get(displayId);
212+
selectedEntry = ((ClientRecipeBookAccessor) book).getKnown().get(this.lastKnownSelectedId);
189213
}
190214

191-
// 2. Button Activation Logic
215+
// Logic for enabling/disabling buttons...
192216
if (selectedEntry != null) {
193217
// We use the entry directly. It contains the 15 ingredients needed!
194218
boolean canCraftOne = canCraft(this.minecraft.player, selectedEntry, 1);

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

Lines changed: 73 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818

1919
import com.tcm.MineTale.block.workbenches.entity.AbstractWorkbenchEntity;
2020
import com.tcm.MineTale.block.workbenches.menu.AbstractWorkbenchContainerMenu;
21+
import com.tcm.MineTale.block.workbenches.menu.ArmorersWorkbenchMenu;
2122
import com.tcm.MineTale.block.workbenches.menu.WorkbenchWorkbenchMenu;
2223
import com.tcm.MineTale.network.ClientboundNearbyInventorySyncPacket;
2324
import com.tcm.MineTale.network.CraftRequestPayload;
@@ -81,31 +82,82 @@ public void onInitialize() {
8182
PayloadTypeRegistry.playS2C().register(ClientboundNearbyInventorySyncPacket.TYPE, ClientboundNearbyInventorySyncPacket.STREAM_CODEC);
8283

8384
// Register the server-side receiver using .TYPE
85+
// ServerPlayNetworking.registerGlobalReceiver(CraftRequestPayload.TYPE, (payload, context) -> {
86+
// context.server().execute(() -> {
87+
// ServerPlayer player = context.player();
88+
89+
// // --- SECURITY GUARD ---
90+
// // Ensure the player actually has the Workbench UI open before processing the craft
91+
// if (!(player.containerMenu instanceof WorkbenchWorkbenchMenu)) {
92+
// return;
93+
// }
94+
95+
// ItemStack requestedResult = payload.resultItem();
96+
// int amount = payload.amount();
97+
98+
// // 1. Get the RecipeManager from the server level
99+
// RecipeManager recipeManager = player.level().recipeAccess();
100+
101+
// // 2. Find the recipe by matching the output ItemStack
102+
// Optional<RecipeHolder<WorkbenchRecipe>> recipeOpt = recipeManager.getAllOfType(ModRecipes.WORKBENCH_TYPE).stream()
103+
// .filter(holder -> {
104+
// // Guard against recipes with no results before accessing index 0
105+
// if (holder.value().results().isEmpty()) {
106+
// return false;
107+
// }
108+
109+
// // Compare the first result of the workbench recipe to the requested item
110+
// ItemStack result = holder.value().results().get(0);
111+
// return ItemStack.isSameItem(result, requestedResult);
112+
// })
113+
// .findFirst();
114+
115+
// if (recipeOpt.isPresent()) {
116+
// WorkbenchRecipe recipe = recipeOpt.get().value();
117+
118+
// // 2. Determine craft limit (Handle "All" logic)
119+
// int limit = (amount == -1) ? 64 : Math.min(Math.max(amount, 0), 64);
120+
121+
// for (int i = 0; i < limit; i++) {
122+
// if (hasIngredients(player, recipe)) {
123+
// consumeIngredients(player, recipe);
124+
// player.getInventory().add(recipe.results().get(0).copy());
125+
// } else {
126+
// break;
127+
// }
128+
// }
129+
130+
// // 3. Sync inventory changes to the client screen
131+
// player.containerMenu.broadcastChanges();
132+
// }
133+
// });
134+
// });
135+
84136
ServerPlayNetworking.registerGlobalReceiver(CraftRequestPayload.TYPE, (payload, context) -> {
85137
context.server().execute(() -> {
86138
ServerPlayer player = context.player();
139+
140+
// --- SELECTIVE SECURITY GUARD ---
141+
// Only proceed if the menu is one of the two specific workbenches
142+
boolean isWorkbench = player.containerMenu instanceof WorkbenchWorkbenchMenu;
143+
boolean isArmorers = player.containerMenu instanceof ArmorersWorkbenchMenu;
87144

88-
// --- SECURITY GUARD ---
89-
// Ensure the player actually has the Workbench UI open before processing the craft
90-
if (!(player.containerMenu instanceof WorkbenchWorkbenchMenu)) {
91-
return;
145+
if (!isWorkbench && !isArmorers) {
146+
return; // Reject packets from Campfires, Furnaces, or other menus
92147
}
93148

94149
ItemStack requestedResult = payload.resultItem();
95150
int amount = payload.amount();
96-
97-
// 1. Get the RecipeManager from the server level
98151
RecipeManager recipeManager = player.level().recipeAccess();
99152

100-
// 2. Find the recipe by matching the output ItemStack
101-
Optional<RecipeHolder<WorkbenchRecipe>> recipeOpt = recipeManager.getAllOfType(ModRecipes.WORKBENCH_TYPE).stream()
153+
// 1. Determine which Recipe Type to search based on the open menu
154+
var targetType = isWorkbench ? ModRecipes.WORKBENCH_TYPE : ModRecipes.ARMORERS_TYPE;
155+
156+
// 2. Find the recipe within that specific type
157+
Optional<RecipeHolder<WorkbenchRecipe>> recipeOpt = recipeManager.getAllOfType(targetType).stream()
102158
.filter(holder -> {
103-
// Guard against recipes with no results before accessing index 0
104-
if (holder.value().results().isEmpty()) {
105-
return false;
106-
}
159+
if (holder.value().results().isEmpty()) return false;
107160

108-
// Compare the first result of the workbench recipe to the requested item
109161
ItemStack result = holder.value().results().get(0);
110162
return ItemStack.isSameItem(result, requestedResult);
111163
})
@@ -114,19 +166,24 @@ public void onInitialize() {
114166
if (recipeOpt.isPresent()) {
115167
WorkbenchRecipe recipe = recipeOpt.get().value();
116168

117-
// 2. Determine craft limit (Handle "All" logic)
169+
// 3. Logic for crafting amount
118170
int limit = (amount == -1) ? 64 : Math.min(Math.max(amount, 0), 64);
119171

120172
for (int i = 0; i < limit; i++) {
173+
// IMPORTANT: Ensure these methods check nearby items if your benches use them!
121174
if (hasIngredients(player, recipe)) {
122175
consumeIngredients(player, recipe);
123-
player.getInventory().add(recipe.results().get(0).copy());
176+
177+
// Give the item to the player
178+
ItemStack output = recipe.results().get(0).copy();
179+
if (!player.getInventory().add(output)) {
180+
player.drop(output, false); // Drop on floor if inventory is full
181+
}
124182
} else {
125183
break;
126184
}
127185
}
128186

129-
// 3. Sync inventory changes to the client screen
130187
player.containerMenu.broadcastChanges();
131188
}
132189
});

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

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,9 @@ public class ModRecipeDisplay {
2727
public static final RecipeDisplay.Type<WorkbenchRecipeDisplay> WORKBENCH_TYPE =
2828
new RecipeDisplay.Type<>(WorkbenchRecipeDisplay.CODEC, STREAM_CODEC);
2929

30+
public static final RecipeDisplay.Type<WorkbenchRecipeDisplay> ARMORERS_TYPE =
31+
new RecipeDisplay.Type<>(WorkbenchRecipeDisplay.CODEC, STREAM_CODEC);
32+
3033
// 1. Declare the fields but don't assign them yet
3134
public static final RecipeBookCategory CAMPFIRE_SEARCH = registerCategory("campfire_recipe_book_category");
3235
public static final RecipeBookCategory WORKBENCH_SEARCH = registerCategory("workbench_recipe_book_category");

0 commit comments

Comments
 (0)