aboutsummaryrefslogtreecommitdiff
path: root/default-plugin/src/main/java/me/shedaniel/rei/plugin/client
diff options
context:
space:
mode:
authorshedaniel <daniel@shedaniel.me>2021-03-25 18:15:16 +0800
committershedaniel <daniel@shedaniel.me>2021-03-25 18:15:16 +0800
commit02d1d95dd54285cc1237d1b5016401274a5ae5f0 (patch)
treec3bed1a8a8ff8d4775394d6c0354587c0460f729 /default-plugin/src/main/java/me/shedaniel/rei/plugin/client
parent995b8b58aa8c890c9181ae479e12a4facfa05a25 (diff)
downloadRoughlyEnoughItems-02d1d95dd54285cc1237d1b5016401274a5ae5f0.tar.gz
RoughlyEnoughItems-02d1d95dd54285cc1237d1b5016401274a5ae5f0.tar.bz2
RoughlyEnoughItems-02d1d95dd54285cc1237d1b5016401274a5ae5f0.zip
Refactor Default Plugin packages, fix favorites
Signed-off-by: shedaniel <daniel@shedaniel.me>
Diffstat (limited to 'default-plugin/src/main/java/me/shedaniel/rei/plugin/client')
-rw-r--r--default-plugin/src/main/java/me/shedaniel/rei/plugin/client/DefaultClientPlugin.java101
-rw-r--r--default-plugin/src/main/java/me/shedaniel/rei/plugin/client/categories/DefaultBrewingCategory.java85
-rw-r--r--default-plugin/src/main/java/me/shedaniel/rei/plugin/client/categories/DefaultCampfireCategory.java81
-rw-r--r--default-plugin/src/main/java/me/shedaniel/rei/plugin/client/categories/DefaultCompostingCategory.java124
-rw-r--r--default-plugin/src/main/java/me/shedaniel/rei/plugin/client/categories/DefaultFuelCategory.java118
-rw-r--r--default-plugin/src/main/java/me/shedaniel/rei/plugin/client/categories/DefaultInformationCategory.java216
-rw-r--r--default-plugin/src/main/java/me/shedaniel/rei/plugin/client/categories/DefaultPathingCategory.java76
-rw-r--r--default-plugin/src/main/java/me/shedaniel/rei/plugin/client/categories/DefaultSmithingCategory.java76
-rw-r--r--default-plugin/src/main/java/me/shedaniel/rei/plugin/client/categories/DefaultStoneCuttingCategory.java80
-rw-r--r--default-plugin/src/main/java/me/shedaniel/rei/plugin/client/categories/DefaultStrippingCategory.java76
-rw-r--r--default-plugin/src/main/java/me/shedaniel/rei/plugin/client/categories/DefaultTillingCategory.java76
-rw-r--r--default-plugin/src/main/java/me/shedaniel/rei/plugin/client/categories/beacon/DefaultBeaconBaseCategory.java183
-rw-r--r--default-plugin/src/main/java/me/shedaniel/rei/plugin/client/categories/beacon/DefaultBeaconPaymentCategory.java183
-rw-r--r--default-plugin/src/main/java/me/shedaniel/rei/plugin/client/categories/cooking/DefaultCookingCategory.java121
-rw-r--r--default-plugin/src/main/java/me/shedaniel/rei/plugin/client/categories/crafting/DefaultCraftingCategory.java112
-rw-r--r--default-plugin/src/main/java/me/shedaniel/rei/plugin/client/favorites/GameModeFavoriteEntry.java289
-rw-r--r--default-plugin/src/main/java/me/shedaniel/rei/plugin/client/favorites/WeatherFavoriteEntry.java335
17 files changed, 2288 insertions, 44 deletions
diff --git a/default-plugin/src/main/java/me/shedaniel/rei/plugin/client/DefaultClientPlugin.java b/default-plugin/src/main/java/me/shedaniel/rei/plugin/client/DefaultClientPlugin.java
index b05868492..2088d523b 100644
--- a/default-plugin/src/main/java/me/shedaniel/rei/plugin/client/DefaultClientPlugin.java
+++ b/default-plugin/src/main/java/me/shedaniel/rei/plugin/client/DefaultClientPlugin.java
@@ -42,51 +42,31 @@ import me.shedaniel.rei.api.client.registry.screen.ExclusionZones;
import me.shedaniel.rei.api.client.registry.screen.ScreenRegistry;
import me.shedaniel.rei.api.client.registry.transfer.TransferHandlerRegistry;
import me.shedaniel.rei.api.common.entry.EntryIngredient;
+import me.shedaniel.rei.api.common.util.CollectionUtils;
import me.shedaniel.rei.api.common.util.EntryIngredients;
import me.shedaniel.rei.api.common.util.EntryStacks;
-import me.shedaniel.rei.api.common.util.CollectionUtils;
import me.shedaniel.rei.impl.ClientInternals;
import me.shedaniel.rei.plugin.autocrafting.DefaultRecipeBookHandler;
-import me.shedaniel.rei.plugin.beacon.base.DefaultBeaconBaseCategory;
-import me.shedaniel.rei.plugin.beacon.base.DefaultBeaconBaseDisplay;
-import me.shedaniel.rei.plugin.beacon.payment.DefaultBeaconPaymentCategory;
-import me.shedaniel.rei.plugin.beacon.payment.DefaultBeaconPaymentDisplay;
-import me.shedaniel.rei.plugin.blasting.DefaultBlastingDisplay;
-import me.shedaniel.rei.plugin.brewing.DefaultBrewingCategory;
-import me.shedaniel.rei.plugin.brewing.DefaultBrewingDisplay;
-import me.shedaniel.rei.plugin.brewing.RegisteredBrewingRecipe;
+import me.shedaniel.rei.plugin.client.categories.*;
+import me.shedaniel.rei.plugin.client.categories.beacon.DefaultBeaconBaseCategory;
+import me.shedaniel.rei.plugin.client.categories.beacon.DefaultBeaconPaymentCategory;
+import me.shedaniel.rei.plugin.client.categories.cooking.DefaultCookingCategory;
+import me.shedaniel.rei.plugin.client.categories.crafting.DefaultCraftingCategory;
import me.shedaniel.rei.plugin.client.exclusionzones.DefaultPotionEffectExclusionZones;
import me.shedaniel.rei.plugin.client.exclusionzones.DefaultRecipeBookExclusionZones;
-import me.shedaniel.rei.plugin.common.campfire.DefaultCampfireCategory;
-import me.shedaniel.rei.plugin.common.campfire.DefaultCampfireDisplay;
-import me.shedaniel.rei.plugin.common.composting.DefaultCompostingCategory;
-import me.shedaniel.rei.plugin.common.composting.DefaultCompostingDisplay;
-import me.shedaniel.rei.plugin.common.cooking.DefaultCookingCategory;
-import me.shedaniel.rei.plugin.common.crafting.DefaultCraftingCategory;
-import me.shedaniel.rei.plugin.common.crafting.DefaultCustomDisplay;
-import me.shedaniel.rei.plugin.common.crafting.DefaultShapedDisplay;
-import me.shedaniel.rei.plugin.common.crafting.DefaultShapelessDisplay;
-import me.shedaniel.rei.plugin.common.stonecutting.DefaultStoneCuttingCategory;
-import me.shedaniel.rei.plugin.common.stonecutting.DefaultStoneCuttingDisplay;
-import me.shedaniel.rei.plugin.favorites.GameModeFavoriteEntry;
-import me.shedaniel.rei.plugin.favorites.WeatherFavoriteEntry;
-import me.shedaniel.rei.plugin.fuel.DefaultFuelCategory;
-import me.shedaniel.rei.plugin.fuel.DefaultFuelDisplay;
-import me.shedaniel.rei.plugin.information.DefaultInformationCategory;
-import me.shedaniel.rei.plugin.information.DefaultInformationDisplay;
-import me.shedaniel.rei.plugin.pathing.DefaultPathingCategory;
-import me.shedaniel.rei.plugin.pathing.DefaultPathingDisplay;
-import me.shedaniel.rei.plugin.pathing.DummyShovelItem;
-import me.shedaniel.rei.plugin.smelting.DefaultSmeltingDisplay;
-import me.shedaniel.rei.plugin.smithing.DefaultSmithingCategory;
-import me.shedaniel.rei.plugin.smithing.DefaultSmithingDisplay;
-import me.shedaniel.rei.plugin.smoking.DefaultSmokingDisplay;
-import me.shedaniel.rei.plugin.stripping.DefaultStrippingCategory;
-import me.shedaniel.rei.plugin.stripping.DefaultStrippingDisplay;
-import me.shedaniel.rei.plugin.stripping.DummyAxeItem;
-import me.shedaniel.rei.plugin.tilling.DefaultTillingCategory;
-import me.shedaniel.rei.plugin.tilling.DefaultTillingDisplay;
-import me.shedaniel.rei.plugin.tilling.DummyHoeItem;
+import me.shedaniel.rei.plugin.client.favorites.GameModeFavoriteEntry;
+import me.shedaniel.rei.plugin.client.favorites.WeatherFavoriteEntry;
+import me.shedaniel.rei.plugin.common.displays.*;
+import me.shedaniel.rei.plugin.common.displays.beacon.DefaultBeaconBaseDisplay;
+import me.shedaniel.rei.plugin.common.displays.beacon.DefaultBeaconPaymentDisplay;
+import me.shedaniel.rei.plugin.common.displays.brewing.BrewingRecipe;
+import me.shedaniel.rei.plugin.common.displays.brewing.DefaultBrewingDisplay;
+import me.shedaniel.rei.plugin.common.displays.cooking.DefaultBlastingDisplay;
+import me.shedaniel.rei.plugin.common.displays.cooking.DefaultSmeltingDisplay;
+import me.shedaniel.rei.plugin.common.displays.cooking.DefaultSmokingDisplay;
+import me.shedaniel.rei.plugin.common.displays.crafting.DefaultCustomDisplay;
+import me.shedaniel.rei.plugin.common.displays.crafting.DefaultShapedDisplay;
+import me.shedaniel.rei.plugin.common.displays.crafting.DefaultShapelessDisplay;
import net.fabricmc.api.EnvType;
import net.fabricmc.api.Environment;
import net.minecraft.client.Minecraft;
@@ -108,8 +88,10 @@ import net.minecraft.world.item.alchemy.PotionUtils;
import net.minecraft.world.item.crafting.*;
import net.minecraft.world.level.GameType;
import net.minecraft.world.level.ItemLike;
+import net.minecraft.world.level.block.Block;
import net.minecraft.world.level.block.ComposterBlock;
import net.minecraft.world.level.block.entity.AbstractFurnaceBlockEntity;
+import net.minecraft.world.level.block.state.BlockState;
import net.minecraft.world.level.material.Fluid;
import net.minecraft.world.level.material.FluidState;
import org.jetbrains.annotations.ApiStatus;
@@ -123,10 +105,10 @@ import java.util.stream.Stream;
@ApiStatus.Internal
public class DefaultClientPlugin implements REIClientPlugin, BuiltinClientPlugin {
public DefaultClientPlugin() {
- ClientInternals.attachInstance((Supplier<Object>) () ->this, "builtinClientPlugin");
+ ClientInternals.attachInstance((Supplier<Object>) () -> this, "builtinClientPlugin");
}
- public static void registerBrewingRecipe(RegisteredBrewingRecipe recipe) {
+ public static void registerBrewingRecipe(BrewingRecipe recipe) {
DisplayRegistry.getInstance().registerDisplay(new DefaultBrewingDisplay(recipe.input, recipe.ingredient, recipe.output));
}
@@ -136,7 +118,7 @@ public class DefaultClientPlugin implements REIClientPlugin, BuiltinClientPlugin
@Override
public void registerBrewingRecipe(Ingredient input, Ingredient ingredient, ItemStack output) {
- registerBrewingRecipe(new RegisteredBrewingRecipe(input, ingredient, output));
+ registerBrewingRecipe(new BrewingRecipe(input, ingredient, output));
}
@Override
@@ -148,7 +130,7 @@ public class DefaultClientPlugin implements REIClientPlugin, BuiltinClientPlugin
public void registerEntries(EntryRegistry registry) {
for (Item item : Registry.ITEM) {
try {
- registry.registerEntries(EntryStacks.ofItemStacks(registry.appendStacksForItem(item)));
+ registry.registerEntries(EntryIngredients.ofItemStacks(registry.appendStacksForItem(item)));
} catch (Exception ignored) {
registry.registerEntry(EntryStacks.of(item));
}
@@ -359,7 +341,7 @@ public class DefaultClientPlugin implements REIClientPlugin, BuiltinClientPlugin
registry.getOrCrateSection(new TranslatableComponent(GameModeFavoriteEntry.TRANSLATION_KEY))
.add(Stream.concat(
Arrays.stream(GameType.values())
- .filter(type -> type != GameType.NOT_SET),
+ .filter(type -> type.getId() >= 0),
Stream.of((GameType) null)
).<FavoriteEntry>map(GameModeFavoriteEntry.Type.INSTANCE::fromArgs).toArray(FavoriteEntry[]::new));
registry.register(WeatherFavoriteEntry.ID, WeatherFavoriteEntry.Type.INSTANCE);
@@ -374,4 +356,35 @@ public class DefaultClientPlugin implements REIClientPlugin, BuiltinClientPlugin
public int getPriority() {
return -100;
}
+
+ public static class DummyShovelItem extends ShovelItem {
+ public DummyShovelItem(Tier tier, float f, float g, Properties properties) {
+ super(tier, f, g, properties);
+ }
+
+ public static Map<Block, BlockState> getPathBlocksMap() {
+ return FLATTENABLES;
+ }
+ }
+
+ public static class DummyAxeItem extends AxeItem {
+ public DummyAxeItem(Tier tier, float f, float g, Properties properties) {
+ super(tier, f, g, properties);
+ }
+
+ public static Map<Block, Block> getStrippedBlocksMap() {
+ return STRIPABLES;
+ }
+ }
+
+ public static class DummyHoeItem extends HoeItem {
+ public DummyHoeItem(Tier tier, int i, float f, Properties properties) {
+ super(tier, i, f, properties);
+ }
+
+ public static Map<Block, BlockState> getTilledBlocksMap() {
+ return TILLABLES;
+ }
+ }
+
}
diff --git a/default-plugin/src/main/java/me/shedaniel/rei/plugin/client/categories/DefaultBrewingCategory.java b/default-plugin/src/main/java/me/shedaniel/rei/plugin/client/categories/DefaultBrewingCategory.java
new file mode 100644
index 000000000..42434df3a
--- /dev/null
+++ b/default-plugin/src/main/java/me/shedaniel/rei/plugin/client/categories/DefaultBrewingCategory.java
@@ -0,0 +1,85 @@
+/*
+ * This file is licensed under the MIT License, part of Roughly Enough Items.
+ * Copyright (c) 2018, 2019, 2020 shedaniel
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+package me.shedaniel.rei.plugin.client.categories;
+
+import com.google.common.collect.Lists;
+import me.shedaniel.math.Point;
+import me.shedaniel.math.Rectangle;
+import me.shedaniel.rei.api.client.REIHelper;
+import me.shedaniel.rei.api.client.gui.Renderer;
+import me.shedaniel.rei.api.client.gui.widgets.Widget;
+import me.shedaniel.rei.api.client.gui.widgets.Widgets;
+import me.shedaniel.rei.api.client.registry.display.DisplayCategory;
+import me.shedaniel.rei.api.common.category.CategoryIdentifier;
+import me.shedaniel.rei.api.common.util.EntryStacks;
+import me.shedaniel.rei.plugin.common.BuiltinPlugin;
+import me.shedaniel.rei.plugin.common.displays.brewing.DefaultBrewingDisplay;
+import net.fabricmc.api.EnvType;
+import net.fabricmc.api.Environment;
+import net.minecraft.client.Minecraft;
+import net.minecraft.network.chat.Component;
+import net.minecraft.network.chat.TranslatableComponent;
+import net.minecraft.util.Mth;
+import net.minecraft.world.item.Items;
+import net.minecraft.world.level.block.Blocks;
+
+import java.util.List;
+
+@Environment(EnvType.CLIENT)
+public class DefaultBrewingCategory implements DisplayCategory<DefaultBrewingDisplay> {
+ @Override
+ public CategoryIdentifier<? extends DefaultBrewingDisplay> getCategoryIdentifier() {
+ return BuiltinPlugin.BREWING;
+ }
+
+ @Override
+ public Renderer getIcon() {
+ return EntryStacks.of(Blocks.BREWING_STAND);
+ }
+
+ @Override
+ public Component getTitle() {
+ return new TranslatableComponent("category.rei.brewing");
+ }
+
+ @Override
+ public List<Widget> setupDisplay(DefaultBrewingDisplay display, Rectangle bounds) {
+ Point startPoint = new Point(bounds.getCenterX() - 52, bounds.getCenterY() - 29);
+ List<Widget> widgets = Lists.newArrayList();
+ widgets.add(Widgets.createRecipeBase(bounds));
+ widgets.add(Widgets.createDrawableWidget((helper, matrices, mouseX, mouseY, delta) -> {
+ Minecraft.getInstance().getTextureManager().bind(REIHelper.getInstance().getDefaultDisplayTexture());
+ helper.blit(matrices, startPoint.x, startPoint.y, 0, 108, 103, 59);
+ int width = Mth.ceil(System.currentTimeMillis() / 250d % 18d);
+ helper.blit(matrices, startPoint.x + 44, startPoint.y + 28, 103, 163, width, 4);
+ }));
+ widgets.add(Widgets.createSlot(new Point(startPoint.x + 1, startPoint.y + 1)).entry(EntryStacks.of(Items.BLAZE_POWDER)).disableBackground().markInput());
+ widgets.add(Widgets.createSlot(new Point(startPoint.x + 40, startPoint.y + 1)).entries(display.getInputEntries().get(0)).disableBackground().markInput());
+ widgets.add(Widgets.createSlot(new Point(startPoint.x + 63, startPoint.y + 1)).entries(display.getInputEntries().get(1)).disableBackground().markInput());
+ widgets.add(Widgets.createSlot(new Point(startPoint.x + 40, startPoint.y + 35)).entries(display.getOutput(0)).disableBackground().markOutput());
+ widgets.add(Widgets.createSlot(new Point(startPoint.x + 63, startPoint.y + 42)).entries(display.getOutput(1)).disableBackground().markOutput());
+ widgets.add(Widgets.createSlot(new Point(startPoint.x + 86, startPoint.y + 35)).entries(display.getOutput(2)).disableBackground().markOutput());
+ return widgets;
+ }
+}
diff --git a/default-plugin/src/main/java/me/shedaniel/rei/plugin/client/categories/DefaultCampfireCategory.java b/default-plugin/src/main/java/me/shedaniel/rei/plugin/client/categories/DefaultCampfireCategory.java
new file mode 100644
index 000000000..87c630e98
--- /dev/null
+++ b/default-plugin/src/main/java/me/shedaniel/rei/plugin/client/categories/DefaultCampfireCategory.java
@@ -0,0 +1,81 @@
+/*
+ * This file is licensed under the MIT License, part of Roughly Enough Items.
+ * Copyright (c) 2018, 2019, 2020 shedaniel
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+package me.shedaniel.rei.plugin.client.categories;
+
+import com.google.common.collect.Lists;
+import me.shedaniel.math.Point;
+import me.shedaniel.math.Rectangle;
+import me.shedaniel.rei.api.client.gui.Renderer;
+import me.shedaniel.rei.api.client.gui.widgets.Widget;
+import me.shedaniel.rei.api.client.gui.widgets.Widgets;
+import me.shedaniel.rei.api.client.registry.display.DisplayCategory;
+import me.shedaniel.rei.api.common.category.CategoryIdentifier;
+import me.shedaniel.rei.api.common.util.EntryStacks;
+import me.shedaniel.rei.plugin.common.BuiltinPlugin;
+import me.shedaniel.rei.plugin.common.displays.DefaultCampfireDisplay;
+import net.minecraft.network.chat.Component;
+import net.minecraft.network.chat.TranslatableComponent;
+import net.minecraft.world.level.block.Blocks;
+
+import java.text.DecimalFormat;
+import java.util.List;
+
+public class DefaultCampfireCategory implements DisplayCategory<DefaultCampfireDisplay> {
+ @Override
+ public CategoryIdentifier<? extends DefaultCampfireDisplay> getCategoryIdentifier() {
+ return BuiltinPlugin.CAMPFIRE;
+ }
+
+ @Override
+ public Renderer getIcon() {
+ return EntryStacks.of(Blocks.CAMPFIRE);
+ }
+
+ @Override
+ public Component getTitle() {
+ return new TranslatableComponent("category.rei.campfire");
+ }
+
+ @Override
+ public List<Widget> setupDisplay(DefaultCampfireDisplay display, Rectangle bounds) {
+ Point startPoint = new Point(bounds.getCenterX() - 41, bounds.y + 10);
+ final double cookingTime = display.getCookTime();
+ DecimalFormat df = new DecimalFormat("###.##");
+ List<Widget> widgets = Lists.newArrayList();
+ widgets.add(Widgets.createRecipeBase(bounds));
+ widgets.add(Widgets.createResultSlotBackground(new Point(startPoint.x + 61, startPoint.y + 9)));
+ widgets.add(Widgets.createBurningFire(new Point(startPoint.x + 1, startPoint.y + 20)).animationDurationMS(10000));
+ widgets.add(Widgets.createLabel(new Point(bounds.x + bounds.width - 5, bounds.y + 5),
+ new TranslatableComponent("category.rei.campfire.time", df.format(cookingTime / 20d))).noShadow().rightAligned().color(0xFF404040, 0xFFBBBBBB));
+ widgets.add(Widgets.createArrow(new Point(startPoint.x + 24, startPoint.y + 8)).animationDurationTicks(cookingTime));
+ widgets.add(Widgets.createSlot(new Point(startPoint.x + 1, startPoint.y + 1)).entries(display.getInputEntries().get(0)).markInput());
+ widgets.add(Widgets.createSlot(new Point(startPoint.x + 61, startPoint.y + 9)).entries(display.getOutputEntries().get(0)).disableBackground().markOutput());
+ return widgets;
+ }
+
+ @Override
+ public int getDisplayHeight() {
+ return 49;
+ }
+}
diff --git a/default-plugin/src/main/java/me/shedaniel/rei/plugin/client/categories/DefaultCompostingCategory.java b/default-plugin/src/main/java/me/shedaniel/rei/plugin/client/categories/DefaultCompostingCategory.java
new file mode 100644
index 000000000..c152eed69
--- /dev/null
+++ b/default-plugin/src/main/java/me/shedaniel/rei/plugin/client/categories/DefaultCompostingCategory.java
@@ -0,0 +1,124 @@
+/*
+ * This file is licensed under the MIT License, part of Roughly Enough Items.
+ * Copyright (c) 2018, 2019, 2020 shedaniel
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+package me.shedaniel.rei.plugin.client.categories;
+
+import com.google.common.collect.Lists;
+import com.mojang.blaze3d.vertex.PoseStack;
+import me.shedaniel.math.Point;
+import me.shedaniel.math.Rectangle;
+import me.shedaniel.rei.api.client.gui.DisplayRenderer;
+import me.shedaniel.rei.api.client.gui.Renderer;
+import me.shedaniel.rei.api.client.gui.widgets.Widget;
+import me.shedaniel.rei.api.client.gui.widgets.Widgets;
+import me.shedaniel.rei.api.client.registry.display.DisplayCategory;
+import me.shedaniel.rei.api.common.category.CategoryIdentifier;
+import me.shedaniel.rei.api.common.entry.EntryIngredient;
+import me.shedaniel.rei.api.common.entry.EntryStack;
+import me.shedaniel.rei.api.common.util.EntryStacks;
+import me.shedaniel.rei.plugin.common.BuiltinPlugin;
+import me.shedaniel.rei.plugin.common.displays.DefaultCompostingDisplay;
+import net.fabricmc.api.EnvType;
+import net.fabricmc.api.Environment;
+import net.minecraft.ChatFormatting;
+import net.minecraft.client.Minecraft;
+import net.minecraft.network.chat.Component;
+import net.minecraft.network.chat.TranslatableComponent;
+import net.minecraft.util.Mth;
+import net.minecraft.world.level.block.Blocks;
+import net.minecraft.world.level.block.ComposterBlock;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+import java.util.Objects;
+
+@Environment(EnvType.CLIENT)
+public class DefaultCompostingCategory implements DisplayCategory<DefaultCompostingDisplay> {
+ @Override
+ public CategoryIdentifier<? extends DefaultCompostingDisplay> getCategoryIdentifier() {
+ return BuiltinPlugin.COMPOSTING;
+ }
+
+ @Override
+ public Renderer getIcon() {
+ return EntryStacks.of(Blocks.COMPOSTER);
+ }
+
+ @Override
+ public Component getTitle() {
+ return new TranslatableComponent("category.rei.composting");
+ }
+
+ @Override
+ public DisplayRenderer getDisplayRenderer(DefaultCompostingDisplay display) {
+ return new DisplayRenderer() {
+ private Component text = new TranslatableComponent("text.rei.composting.page", display.getPage() + 1);
+
+ @Override
+ public int getHeight() {
+ return 10 + Minecraft.getInstance().font.lineHeight;
+ }
+
+ @Override
+ public void render(PoseStack matrices, Rectangle rectangle, int mouseX, int mouseY, float delta) {
+ Minecraft.getInstance().font.draw(matrices, text.getVisualOrderText(), rectangle.x + 5, rectangle.y + 6, -1);
+ }
+ };
+ }
+
+ @Override
+ public List<Widget> setupDisplay(DefaultCompostingDisplay display, Rectangle bounds) {
+ List<Widget> widgets = Lists.newArrayList();
+ Point startingPoint = new Point(bounds.x + bounds.width - 55, bounds.y + 110);
+ List<EntryIngredient> stacks = new ArrayList<>(display.getInputEntries());
+ int i = 0;
+ for (int y = 0; y < 6; y++)
+ for (int x = 0; x < 8; x++) {
+ EntryIngredient entryStack = stacks.size() > i ? stacks.get(i) : EntryIngredient.empty();
+ if (!entryStack.isEmpty()) {
+ ComposterBlock.COMPOSTABLES.object2FloatEntrySet().stream().filter(entry -> entry.getKey() != null && Objects.equals(entry.getKey().asItem(), entryStack.get(0).getValue())).findAny().map(Map.Entry::getValue).ifPresent(chance -> {
+ for (EntryStack<?> stack : entryStack) {
+ stack.tooltip(new TranslatableComponent("text.rei.composting.chance", Mth.fastFloor(chance * 100)).withStyle(ChatFormatting.YELLOW));
+ }
+ });
+ }
+ widgets.add(Widgets.createSlot(new Point(bounds.getCenterX() - 72 + x * 18, bounds.y + 3 + y * 18)).entries(entryStack).markInput());
+ i++;
+ }
+ widgets.add(Widgets.createArrow(new Point(startingPoint.x - 1, startingPoint.y + 7)));
+ widgets.add(Widgets.createResultSlotBackground(new Point(startingPoint.x + 33, startingPoint.y + 8)));
+ widgets.add(Widgets.createSlot(new Point(startingPoint.x + 33, startingPoint.y + 8)).entries(display.getOutputEntries().get(0)).disableBackground().markOutput());
+ return widgets;
+ }
+
+ @Override
+ public int getDisplayHeight() {
+ return 140;
+ }
+
+ @Override
+ public int getFixedDisplaysPerPage() {
+ return 1;
+ }
+} \ No newline at end of file
diff --git a/default-plugin/src/main/java/me/shedaniel/rei/plugin/client/categories/DefaultFuelCategory.java b/default-plugin/src/main/java/me/shedaniel/rei/plugin/client/categories/DefaultFuelCategory.java
new file mode 100644
index 000000000..ad396ed18
--- /dev/null
+++ b/default-plugin/src/main/java/me/shedaniel/rei/plugin/client/categories/DefaultFuelCategory.java
@@ -0,0 +1,118 @@
+/*
+ * This file is licensed under the MIT License, part of Roughly Enough Items.
+ * Copyright (c) 2018, 2019, 2020 shedaniel
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+package me.shedaniel.rei.plugin.client.categories;
+
+import com.google.common.collect.Lists;
+import com.mojang.blaze3d.vertex.PoseStack;
+import me.shedaniel.math.Point;
+import me.shedaniel.math.Rectangle;
+import me.shedaniel.rei.api.client.gui.DisplayRenderer;
+import me.shedaniel.rei.api.client.gui.Renderer;
+import me.shedaniel.rei.api.client.gui.widgets.Slot;
+import me.shedaniel.rei.api.client.gui.widgets.Tooltip;
+import me.shedaniel.rei.api.client.gui.widgets.Widget;
+import me.shedaniel.rei.api.client.gui.widgets.Widgets;
+import me.shedaniel.rei.api.client.registry.display.DisplayCategory;
+import me.shedaniel.rei.api.common.category.CategoryIdentifier;
+import me.shedaniel.rei.api.common.util.EntryStacks;
+import me.shedaniel.rei.plugin.common.BuiltinPlugin;
+import me.shedaniel.rei.plugin.common.displays.DefaultFuelDisplay;
+import net.fabricmc.api.EnvType;
+import net.fabricmc.api.Environment;
+import net.minecraft.client.Minecraft;
+import net.minecraft.network.chat.Component;
+import net.minecraft.network.chat.TranslatableComponent;
+import net.minecraft.world.item.Items;
+import org.jetbrains.annotations.Nullable;
+
+import java.text.DecimalFormat;
+import java.util.List;
+
+@Environment(EnvType.CLIENT)
+public class DefaultFuelCategory implements DisplayCategory<DefaultFuelDisplay> {
+ private static final DecimalFormat DECIMAL_FORMAT = new DecimalFormat("#.##");
+
+ @Override
+ public CategoryIdentifier<? extends DefaultFuelDisplay> getCategoryIdentifier() {
+ return BuiltinPlugin.FUEL;
+ }
+
+ @Override
+ public Component getTitle() {
+ return new TranslatableComponent("category.rei.fuel");
+ }
+
+ @Override
+ public int getDisplayHeight() {
+ return 49;
+ }
+
+ @Override
+ public Renderer getIcon() {
+ return EntryStacks.of(Items.COAL);
+ }
+
+ @Override
+ public List<Widget> setupDisplay(DefaultFuelDisplay display, Rectangle bounds) {
+ Point startPoint = new Point(bounds.getCenterX() - 41, bounds.getCenterY() - 17);
+ String burnItems = DECIMAL_FORMAT.format(display.getFuelTime() / 200d);
+ List<Widget> widgets = Lists.newArrayList();
+ widgets.add(Widgets.createRecipeBase(bounds));
+ widgets.add(Widgets.createLabel(new Point(bounds.x + 26, bounds.getMaxY() - 15), new TranslatableComponent("category.rei.fuel.time.items", burnItems))
+ .color(0xFF404040, 0xFFBBBBBB).noShadow().leftAligned());
+ widgets.add(Widgets.createBurningFire(new Point(bounds.x + 6, startPoint.y + 1)).animationDurationTicks(display.getFuelTime()));
+ widgets.add(Widgets.createSlot(new Point(bounds.x + 6, startPoint.y + 18)).entries(display.getInputEntries().get(0)).markInput());
+ return widgets;
+ }
+
+ @Override
+ public DisplayRenderer getDisplayRenderer(DefaultFuelDisplay display) {
+ Slot slot = Widgets.createSlot(new Point(0, 0)).entries(display.getInputEntries().get(0)).disableBackground().disableHighlight();
+ String burnItems = DECIMAL_FORMAT.format(display.getFuelTime() / 200d);
+ return new DisplayRenderer() {
+ private TranslatableComponent text = new TranslatableComponent("category.rei.fuel.time_short.items", burnItems);
+
+ @Override
+ public int getHeight() {
+ return 22;
+ }
+
+ @Nullable
+ @Override
+ public Tooltip getTooltip(Point point) {
+ if (slot.containsMouse(point))
+ return slot.getCurrentTooltip(point);
+ return null;
+ }
+
+ @Override
+ public void render(PoseStack matrices, Rectangle bounds, int mouseX, int mouseY, float delta) {
+ slot.setZ(getZ() + 50);
+ slot.getBounds().setLocation(bounds.x + 4, bounds.y + 2);
+ slot.render(matrices, mouseX, mouseY, delta);
+ Minecraft.getInstance().font.drawShadow(matrices, text.getVisualOrderText(), bounds.x + 25, bounds.y + 8, -1);
+ }
+ };
+ }
+}
diff --git a/default-plugin/src/main/java/me/shedaniel/rei/plugin/client/categories/DefaultInformationCategory.java b/default-plugin/src/main/java/me/shedaniel/rei/plugin/client/categories/DefaultInformationCategory.java
new file mode 100644
index 000000000..6dfc4e1b3
--- /dev/null
+++ b/