From 4d84f0e601326c7bc8be4a8d707398fd69c24a2f Mon Sep 17 00:00:00 2001 From: XxFran10xX <318299142+XxFran10xX@users.noreply.github.com> Date: Mon, 28 Sep 2026 17:15:43 +0200 Subject: [PATCH] fix: accept any input and ruin non-exact crafts The bench now accepts any woodworking material and any tool hit, in any order and amount. Finishing with the branding tool gives the furniture only when the materials, their amounts and the hits match the recipe exactly. Any other finish ruins the project and the deposited materials are lost. Previously a wrong mix filled the type bucket, blocked further input and left the bench stuck until the project was cancelled. Co-Authored-By: Claude Opus 5.5 (1M context) --- README.md | 2 +- .../woodworking/station/StationFeedback.java | 4 -- .../woodworking/station/StationManager.java | 47 ++++++---------- .../woodworking/station/WoodStation.java | 54 +++++-------------- 4 files changed, 30 insertions(+), 77 deletions(-) diff --git a/README.md b/README.md index 4cbd249..88b3e28 100644 --- a/README.md +++ b/README.md @@ -15,7 +15,7 @@ Woodworking turns furniture production into a practical workshop activity. Playe ## From materials to furniture -Each workbench holds a project while its materials and required actions are completed. Finishing checks the recipe and tool work before producing the furniture item. Players can inspect progress with the branding tool or deliberately cancel a project when changing plans. +Each workbench holds a project while its materials and required actions are completed. The bench accepts any woodworking material and any tool action, so players have to know the design. Finishing produces the furniture only when the materials, their amounts and the tool actions all match the recipe exactly. Any other finish ruins the project and the deposited materials are lost. Players can inspect progress with the branding tool or deliberately cancel a project, with a full refund, when changing plans. ## Documentation diff --git a/src/main/java/net/tfminecraft/woodworking/station/StationFeedback.java b/src/main/java/net/tfminecraft/woodworking/station/StationFeedback.java index 6e0eea9..b1e570a 100644 --- a/src/main/java/net/tfminecraft/woodworking/station/StationFeedback.java +++ b/src/main/java/net/tfminecraft/woodworking/station/StationFeedback.java @@ -3,11 +3,7 @@ /** Result of a station action. Callers own player-facing messages. */ public enum StationFeedback { SUCCESS, - CAPACITY, WRONG_TYPE, - NONE, - LACKING_ITEMS, - LACKING_HITS, RECIPE_MISMATCH, NO_PROJECT } diff --git a/src/main/java/net/tfminecraft/woodworking/station/StationManager.java b/src/main/java/net/tfminecraft/woodworking/station/StationManager.java index 251dd91..1f1a2e3 100644 --- a/src/main/java/net/tfminecraft/woodworking/station/StationManager.java +++ b/src/main/java/net/tfminecraft/woodworking/station/StationManager.java @@ -292,10 +292,6 @@ private void handleRightClick(PlayerInteractEvent e) { playWorkFx(existing.getLoc(), Material.OAK_LOG); p.getWorld().playSound(existing.getLoc(), Sound.ITEM_AXE_WAX_OFF, 0.7f, 2f); break; - case CAPACITY: - p.sendMessage("§cYou already have the needed amount of this type"); - p.playSound(p.getLocation(), Sound.BLOCK_NOTE_BLOCK_BASS, 1f, 0.5f); - break; case WRONG_TYPE: p.sendMessage("§cThis item type is not needed for the project"); p.playSound(p.getLocation(), Sound.ENTITY_VILLAGER_NO, 1f, 1f); @@ -329,20 +325,8 @@ private void handleLeftClick(PlayerInteractEvent e) { p.getWorld().playSound(station.getLoc(), Sound.ITEM_SHIELD_BREAK, 0.4f, 1f); return; } - StationFeedback finish = station.canFinish(); - if (finish == StationFeedback.LACKING_ITEMS) { - p.sendMessage("§cYou have to add all the items before working"); - p.playSound(p.getLocation(), Sound.ENTITY_VILLAGER_NO, 1f, 1f); - return; - } - if (finish == StationFeedback.LACKING_HITS) { - p.sendMessage("§cYou need to complete all the hits before finishing"); - p.playSound(p.getLocation(), Sound.ENTITY_VILLAGER_NO, 1f, 1f); - return; - } - if (finish == StationFeedback.RECIPE_MISMATCH) { - p.sendMessage("§cThe materials do not match the recipe"); - p.playSound(p.getLocation(), Sound.ENTITY_VILLAGER_NO, 1f, 1f); + if (station.canFinish() != StationFeedback.SUCCESS) { + failCraft(p, station); return; } completeCraft(p, station); @@ -366,22 +350,10 @@ private void handleLeftClick(PlayerInteractEvent e) { playWorkFx(station.getLoc(), Material.OAK_PLANKS); p.getWorld().playSound(station.getLoc(), Sound.BLOCK_ANVIL_USE, 0.4f, 1f); break; - case LACKING_ITEMS: - p.sendMessage("§cYou have to add all the items before working"); - p.playSound(p.getLocation(), Sound.ENTITY_VILLAGER_NO, 1f, 1f); - break; case WRONG_TYPE: p.sendMessage("§cThis item cannot be used for woodworking hits"); p.playSound(p.getLocation(), Sound.ENTITY_VILLAGER_NO, 1f, 1f); break; - case NONE: - p.sendMessage("§cThis tool is not needed for this project"); - p.playSound(p.getLocation(), Sound.ENTITY_VILLAGER_NO, 1f, 1f); - break; - case CAPACITY: - p.sendMessage("§cYou dont need more hits with this tool"); - p.playSound(p.getLocation(), Sound.BLOCK_NOTE_BLOCK_BASS, 1f, 0.5f); - break; default: break; } @@ -427,6 +399,21 @@ private void completeCraft(Player p, WoodStation station) { remove(station.getLoc()); } + /** A wrong recipe or hit mix destroys the work. Deposited materials are not refunded. */ + // Keep the existing legacy text representation, formatting, and exact-string comparisons. + @SuppressWarnings("deprecation") + private void failCraft(Player p, WoodStation station) { + String name = station.getProject().getName(); + station.cancel(); + remove(station.getLoc()); + p.sendTitle("§cThe craft failed", "§7" + name + " §7was ruined and the materials were lost", 5, 40, 10); + Location loc = station.getLoc().clone().add(0.5, 1, 0.5); + if (loc.getWorld() != null) { + loc.getWorld().playSound(loc, Sound.ENTITY_ITEM_BREAK, 1f, 0.8f); + loc.getWorld().spawnParticle(Particle.SMOKE, loc, 20, 0.2, 0.2, 0.2, 0.02); + } + } + private boolean isBranding(ItemStack item) { return TLibs.getItemAPI().getChecker().checkItemWithPath(item, Cache.brandingTool); } diff --git a/src/main/java/net/tfminecraft/woodworking/station/WoodStation.java b/src/main/java/net/tfminecraft/woodworking/station/WoodStation.java index dea6471..08f72ac 100644 --- a/src/main/java/net/tfminecraft/woodworking/station/WoodStation.java +++ b/src/main/java/net/tfminecraft/woodworking/station/WoodStation.java @@ -118,8 +118,7 @@ public void applySavedProgress(Map materials, Map new IntCounter()).increaseCurrent(amount); } } if (hitCounts != null) { @@ -139,8 +138,7 @@ public void applySavedProgress(Map materials, Map e : hits.entrySet()) { HitType type = e.getKey().getType(); if (type == null) continue; - IntCounter bucket = hitTypes.get(type); - if (bucket != null) bucket.increaseCurrent(e.getValue().getCurrent()); + hitTypes.computeIfAbsent(type, k -> new IntCounter()).increaseCurrent(e.getValue().getCurrent()); } } if (savedDeposited != null) { @@ -148,16 +146,15 @@ public void applySavedProgress(Map materials, Map new IntCounter()).increaseCurrent(1); depositedByMaterial.merge(material, 1, Integer::sum); if (stack != null) { ItemStack copy = stack.clone(); @@ -167,42 +164,16 @@ public StationFeedback addMaterial(WoodMaterial material, ItemStack stack) { return StationFeedback.SUCCESS; } + /** Accepts any hit, in any order and amount, like {@link #addMaterial(WoodMaterial, ItemStack)}. */ public StationFeedback hit(CraftingHit hit) { if (project == null) return StationFeedback.NO_PROJECT; - if (!checkItems()) return StationFeedback.LACKING_ITEMS; if (hit == null || hit.getType() == null) return StationFeedback.WRONG_TYPE; - if (!hitTypes.containsKey(hit.getType())) return StationFeedback.NONE; - if (hitTypes.get(hit.getType()).isEqual()) return StationFeedback.CAPACITY; - if (hits.containsKey(hit)) { - hits.get(hit).increaseCurrent(1); - } else { - IntCounter counter = new IntCounter(); - counter.setCurrent(1); - hits.put(hit, counter); - } - hitTypes.get(hit.getType()).increaseCurrent(1); + hits.computeIfAbsent(hit, k -> new IntCounter()).increaseCurrent(1); + hitTypes.computeIfAbsent(hit.getType(), k -> new IntCounter()).increaseCurrent(1); return StationFeedback.SUCCESS; } - /** True when every material-type bucket is exactly filled. */ - public boolean checkItems() { - if (project == null) return false; - for (IntCounter c : types.values()) { - if (!c.isEqual()) return false; - } - return true; - } - - /** True when every hit-type bucket is exactly filled. */ - public boolean checkHits() { - if (project == null) return false; - for (IntCounter c : hitTypes.values()) { - if (!c.isEqual()) return false; - } - return true; - } - /** True when every required hit count matches and there are no extra leftover hits. */ public boolean checkExactHits() { if (project == null) return false; @@ -228,11 +199,10 @@ public boolean checkExactRecipe() { return true; } + /** SUCCESS only when the deposited materials and the hits both match the project exactly. */ public StationFeedback canFinish() { if (project == null) return StationFeedback.NO_PROJECT; - if (!checkItems()) return StationFeedback.LACKING_ITEMS; - if (!checkExactHits()) return StationFeedback.LACKING_HITS; - if (!checkExactRecipe()) return StationFeedback.RECIPE_MISMATCH; + if (!checkExactRecipe() || !checkExactHits()) return StationFeedback.RECIPE_MISMATCH; return StationFeedback.SUCCESS; }