Skip to content

Commit c345f62

Browse files
XxFran10xXclaude
andcommitted
fix: clear a plate's sauce once its last food is taken off
The sauce visual stayed on a plate after its food was removed, so hasSauce rejected sauce for every later dish on that plate (reported with chicken legs, but any food was affected). Remove the sauce slot when the last food leaves, clear leftover sauce on plates saved before this fix, and keep the ladle full when sauce is ladled onto an empty plate. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
1 parent 729ad1a commit c345f62

2 files changed

Lines changed: 73 additions & 0 deletions

File tree

‎src/main/java/net/tfminecraft/cooking/manager/PlateManager.java‎

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
import org.bukkit.Sound;
1111
import org.bukkit.entity.Player;
1212
import org.bukkit.event.EventHandler;
13+
import org.bukkit.event.EventPriority;
1314
import org.bukkit.event.Listener;
1415
import org.bukkit.inventory.ItemStack;
1516
import org.bukkit.inventory.meta.ItemMeta;
@@ -31,6 +32,7 @@
3132
import net.tfminecraft.interactiblefurniture.events.FurnitureBreakEvent;
3233
import net.tfminecraft.interactiblefurniture.events.FurnitureInteractEvent;
3334
import net.tfminecraft.interactiblefurniture.events.FurnitureSlotItemAddEvent;
35+
import net.tfminecraft.interactiblefurniture.events.FurnitureSlotItemTakeEvent;
3436
import net.tfminecraft.interactiblefurniture.furniture.Furniture;
3537
import net.tfminecraft.interactiblefurniture.furniture.PlacedSlot;
3638
import net.tfminecraft.interactiblefurniture.furniture.data.DisplayData;
@@ -56,6 +58,11 @@ public void run() {
5658
}
5759

5860
public void update(Furniture f) {
61+
// Also clears plates saved with leftover sauce before the take handler existed.
62+
if(hasLeftoverSauce(f, null)) {
63+
f.removeActiveSlot("sauce");
64+
InteractibleFurniture.getInstance().getFurnitureManager().persistFurniture(f);
65+
}
5966
for(PlacedSlot slot : f.getActiveSlots().values()) {
6067
if(slot.getId().contains("display")) continue;
6168
ItemStack item = slot.getCurrentItem();
@@ -99,10 +106,35 @@ public boolean hasSauce(Furniture f) {
99106
return false;
100107
}
101108

109+
/**
110+
* True when the plate shows a sauce visual but no food would remain once {@code leavingSlot}
111+
* is gone. A leftover sauce visual makes hasSauce reject the next dish on the plate.
112+
*/
113+
boolean hasLeftoverSauce(Furniture f, String leavingSlot) {
114+
if(!f.hasActiveSlot("sauce")) return false;
115+
for(String id : f.getActiveSlots().keySet()) {
116+
if(id.equals("sauce") || id.equals(leavingSlot)) continue;
117+
return false;
118+
}
119+
return true;
120+
}
121+
122+
@EventHandler(priority = EventPriority.HIGHEST, ignoreCancelled = true)
123+
public void takeItem(FurnitureSlotItemTakeEvent e) {
124+
Furniture f = e.getFurniture();
125+
if(!FurnitureCache.isPlate(f)) return;
126+
// The taken slot is still active here; InteractibleFurniture removes it and saves the plate next.
127+
if(hasLeftoverSauce(f, e.getSlot().getId())) {
128+
f.removeActiveSlot("sauce");
129+
}
130+
}
131+
102132
// Keep the existing legacy text representation, formatting, and exact-string comparisons.
103133
@SuppressWarnings("deprecation")
104134
public void addSauce(Player p, Furniture f, FoodItem sauce, ItemStack base) {
105135
if (hasSauce(f)) return;
136+
// Sauce on an empty plate would never reach food added later, so keep the ladle full.
137+
if (f.getActiveSlots().isEmpty()) return;
106138

107139
// Replace player ladle with empty ladle
108140
p.getInventory().setItemInMainHand(

‎src/test/java/net/tfminecraft/cooking/manager/PlateManagerTest.java‎

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -116,4 +116,45 @@ public boolean hasItemMeta() {
116116

117117
assertFalse(new PlateManager().hasSauce(plate));
118118
}
119+
120+
@Test
121+
void sauceIsLeftoverOnceTheLastFoodLeaves() {
122+
Furniture plate = plateWithSauceVisual();
123+
plate.getActiveSlots().put("item_1", new PlacedSlot(plate, "item_1"));
124+
125+
assertFalse(new PlateManager().hasLeftoverSauce(plate, null));
126+
assertTrue(new PlateManager().hasLeftoverSauce(plate, "item_1"));
127+
}
128+
129+
@Test
130+
void sauceStaysWhileOtherFoodRemains() {
131+
Furniture plate = plateWithSauceVisual();
132+
plate.getActiveSlots().put("item_1", new PlacedSlot(plate, "item_1"));
133+
plate.getActiveSlots().put("item_2", new PlacedSlot(plate, "item_2"));
134+
135+
assertFalse(new PlateManager().hasLeftoverSauce(plate, "item_1"));
136+
}
137+
138+
@Test
139+
void sauceAloneOnAPlateIsLeftover() {
140+
assertTrue(new PlateManager().hasLeftoverSauce(plateWithSauceVisual(), null));
141+
}
142+
143+
@Test
144+
void plateWithoutSauceHasNoLeftover() {
145+
Furniture plate = new Furniture("plate", null, UUID.randomUUID());
146+
plate.getActiveSlots().put("item_1", new PlacedSlot(plate, "item_1"));
147+
148+
assertFalse(new PlateManager().hasLeftoverSauce(plate, null));
149+
assertFalse(new PlateManager().hasLeftoverSauce(plate, "item_1"));
150+
}
151+
152+
@Test
153+
void sauceOnAnEmptyPlateReturnsBeforeTouchingThePlayerOrLadle() {
154+
Furniture plate = new Furniture("plate", null, UUID.randomUUID());
155+
156+
// Null interaction arguments ensure the empty-plate attempt exits before using them.
157+
assertDoesNotThrow(() -> new PlateManager().addSauce(null, plate, null, null));
158+
assertTrue(plate.getActiveSlots().isEmpty());
159+
}
119160
}

0 commit comments

Comments
 (0)