aboutsummaryrefslogtreecommitdiffhomepage
path: root/patches/server/0246-Implement-furnace-cook-speed-multiplier-API.patch
blob: 3a04c8b1ea0e6dd85ce621dca41e735922e7a58b (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Tassu <git@tassu.me>
Date: Thu, 13 Sep 2018 08:45:21 +0300
Subject: [PATCH] Implement furnace cook speed multiplier API

Fixed an issue where a furnace's cook-speed multiplier rounds down
to the nearest Integer when updating its current cook time.

== AT ==
public net.minecraft.world.level.block.entity.AbstractFurnaceBlockEntity getTotalCookTime(Lnet/minecraft/server/level/ServerLevel;Lnet/minecraft/world/level/block/entity/AbstractFurnaceBlockEntity;)I

Co-authored-by: Eric Su <ericsu@alumni.usc.edu>

diff --git a/src/main/java/net/minecraft/world/level/block/entity/AbstractFurnaceBlockEntity.java b/src/main/java/net/minecraft/world/level/block/entity/AbstractFurnaceBlockEntity.java
index 119ea31f6e15185b6d6171053f790e39c24f6823..187f380eae3948eb5e37e8703db6ea785aaf833d 100644
--- a/src/main/java/net/minecraft/world/level/block/entity/AbstractFurnaceBlockEntity.java
+++ b/src/main/java/net/minecraft/world/level/block/entity/AbstractFurnaceBlockEntity.java
@@ -74,11 +74,13 @@ public abstract class AbstractFurnaceBlockEntity extends BaseContainerBlockEntit
     protected NonNullList<ItemStack> items;
     public int litTime;
     int litDuration;
+    public double cookSpeedMultiplier = 1.0; // Paper - cook speed multiplier API
     public int cookingProgress;
     public int cookingTotalTime;
     protected final ContainerData dataAccess;
     public final Reference2IntOpenHashMap<ResourceKey<Recipe<?>>> recipesUsed;
     private final RecipeManager.CachedCheck<SingleRecipeInput, ? extends AbstractCookingRecipe> quickCheck;
+    public final RecipeType<? extends AbstractCookingRecipe> recipeType; // Paper - cook speed multiplier API
 
     protected AbstractFurnaceBlockEntity(BlockEntityType<?> blockEntityType, BlockPos pos, BlockState state, RecipeType<? extends AbstractCookingRecipe> recipeType) {
         super(blockEntityType, pos, state);
@@ -126,6 +128,7 @@ public abstract class AbstractFurnaceBlockEntity extends BaseContainerBlockEntit
         };
         this.recipesUsed = new Reference2IntOpenHashMap();
         this.quickCheck = RecipeManager.createCheck((RecipeType<AbstractCookingRecipe>) recipeType); // CraftBukkit - decompile error // Eclipse fail
+        this.recipeType = recipeType; // Paper - cook speed multiplier API
     }
 
     // CraftBukkit start - add fields and methods
@@ -180,6 +183,11 @@ public abstract class AbstractFurnaceBlockEntity extends BaseContainerBlockEntit
             this.recipesUsed.put(ResourceKey.create(Registries.RECIPE, ResourceLocation.parse(s)), nbttagcompound1.getInt(s));
         }
 
+        // Paper start - cook speed multiplier API
+        if (nbt.contains("Paper.CookSpeedMultiplier")) {
+            this.cookSpeedMultiplier = nbt.getDouble("Paper.CookSpeedMultiplier");
+        }
+        // Paper end - cook speed multiplier API
     }
 
     @Override
@@ -188,6 +196,7 @@ public abstract class AbstractFurnaceBlockEntity extends BaseContainerBlockEntit
         nbt.putShort("BurnTime", (short) this.litTime);
         nbt.putShort("CookTime", (short) this.cookingProgress);
         nbt.putShort("CookTimeTotal", (short) this.cookingTotalTime);
+        nbt.putDouble("Paper.CookSpeedMultiplier", this.cookSpeedMultiplier); // Paper - cook speed multiplier API
         ContainerHelper.saveAllItems(nbt, this.items, registries);
         CompoundTag nbttagcompound1 = new CompoundTag();
 
@@ -263,7 +272,7 @@ public abstract class AbstractFurnaceBlockEntity extends BaseContainerBlockEntit
                     CraftItemStack source = CraftItemStack.asCraftMirror(blockEntity.items.get(0));
                     CookingRecipe<?> recipe = (CookingRecipe<?>) recipeholder.toBukkitRecipe();
 
-                    FurnaceStartSmeltEvent event = new FurnaceStartSmeltEvent(CraftBlock.at(world, pos), source, recipe);
+                    FurnaceStartSmeltEvent event = new FurnaceStartSmeltEvent(CraftBlock.at(world, pos), source, recipe, AbstractFurnaceBlockEntity.getTotalCookTime(world, blockEntity, blockEntity.recipeType, blockEntity.cookSpeedMultiplier)); // Paper - cook speed multiplier API
                     world.getCraftServer().getPluginManager().callEvent(event);
 
                     blockEntity.cookingTotalTime = event.getTotalCookTime();
@@ -271,9 +280,9 @@ public abstract class AbstractFurnaceBlockEntity extends BaseContainerBlockEntit
                 // CraftBukkit end
 
                 ++blockEntity.cookingProgress;
-                if (blockEntity.cookingProgress == blockEntity.cookingTotalTime) {
+                if (blockEntity.cookingProgress >= blockEntity.cookingTotalTime) { // Paper - cook speed multiplier API
                     blockEntity.cookingProgress = 0;
-                    blockEntity.cookingTotalTime = AbstractFurnaceBlockEntity.getTotalCookTime(world, blockEntity);
+                    blockEntity.cookingTotalTime = AbstractFurnaceBlockEntity.getTotalCookTime(world, blockEntity, blockEntity.recipeType, blockEntity.cookSpeedMultiplier); // Paper - cook speed multiplier API
                     if (AbstractFurnaceBlockEntity.burn(blockEntity.level, blockEntity.worldPosition, world.registryAccess(), recipeholder, singlerecipeinput, blockEntity.items, i)) { // CraftBukkit
                         blockEntity.setRecipeUsed(recipeholder);
                     }
@@ -367,13 +376,14 @@ public abstract class AbstractFurnaceBlockEntity extends BaseContainerBlockEntit
         return fuelRegistry.burnDuration(stack);
     }
 
-    public static int getTotalCookTime(ServerLevel world, AbstractFurnaceBlockEntity furnace) {
-        if (world == null) return 200; // CraftBukkit - SPIGOT-4302
+    public static int getTotalCookTime(@Nullable ServerLevel world, AbstractFurnaceBlockEntity furnace, RecipeType<? extends AbstractCookingRecipe> recipeType, double cookSpeedMultiplier) { // Paper - cook speed multiplier API
         SingleRecipeInput singlerecipeinput = new SingleRecipeInput(furnace.getItem(0));
 
-        return (Integer) furnace.quickCheck.getRecipeFor(singlerecipeinput, world).map((recipeholder) -> {
-            return ((AbstractCookingRecipe) recipeholder.value()).cookingTime();
-        }).orElse(200);
+        // Paper start - cook speed multiplier API
+        /* Scale the recipe's cooking time to the current cookSpeedMultiplier */
+        int cookTime = world != null ? furnace.quickCheck.getRecipeFor(singlerecipeinput, world).map(holder -> holder.value().cookingTime()).orElse(200) : (net.minecraft.server.MinecraftServer.getServer().getRecipeManager().getRecipeFor(recipeType, singlerecipeinput, world /* passing a null level here is safe. world is only used for map extending recipes which won't happen here */).map(holder -> holder.value().cookingTime()).orElse(200));
+        return (int) Math.ceil (cookTime / cookSpeedMultiplier);
+        // Paper end - cook speed multiplier API
     }
 
     @Override
@@ -419,12 +429,11 @@ public abstract class AbstractFurnaceBlockEntity extends BaseContainerBlockEntit
             if (world instanceof ServerLevel) {
                 ServerLevel worldserver = (ServerLevel) world;
 
-                this.cookingTotalTime = AbstractFurnaceBlockEntity.getTotalCookTime(worldserver, this);
+                this.cookingTotalTime = AbstractFurnaceBlockEntity.getTotalCookTime(worldserver, this, this.recipeType, this.cookSpeedMultiplier); // Paper - cook speed multiplier API
                 this.cookingProgress = 0;
                 this.setChanged();
             }
         }
-
     }
 
     @Override
diff --git a/src/main/java/org/bukkit/craftbukkit/block/CraftFurnace.java b/src/main/java/org/bukkit/craftbukkit/block/CraftFurnace.java
index 7ed43bc29a4bc0f6db2cabd3cd4c8489ed81ee81..7b5f35779ac63b5f9b3a88cc4dcde38147fea2b7 100644
--- a/src/main/java/org/bukkit/craftbukkit/block/CraftFurnace.java
+++ b/src/main/java/org/bukkit/craftbukkit/block/CraftFurnace.java
@@ -88,4 +88,20 @@ public abstract class CraftFurnace<T extends AbstractFurnaceBlockEntity> extends
 
     @Override
     public abstract CraftFurnace<T> copy(Location location);
+
+    // Paper start - cook speed multiplier API
+    @Override
+    public double getCookSpeedMultiplier() {
+        return this.getSnapshot().cookSpeedMultiplier;
+    }
+
+    @Override
+    public void setCookSpeedMultiplier(double multiplier) {
+        com.google.common.base.Preconditions.checkArgument(multiplier >= 0, "Furnace speed multiplier cannot be negative");
+        com.google.common.base.Preconditions.checkArgument(multiplier <= 200, "Furnace speed multiplier cannot more than 200");
+        T snapshot = this.getSnapshot();
+        snapshot.cookSpeedMultiplier = multiplier;
+        snapshot.cookingTotalTime = AbstractFurnaceBlockEntity.getTotalCookTime(this.isPlaced() ? this.world.getHandle() : null, snapshot, snapshot.recipeType, snapshot.cookSpeedMultiplier); // Update the snapshot's current total cook time to scale with the newly set multiplier
+    }
+    // Paper end
 }