From 64bc9937d6ec04c6d66240a84b4fb345026c0b12 Mon Sep 17 00:00:00 2001 From: shedaniel Date: Tue, 9 Mar 2021 21:30:12 +0800 Subject: Very primitive background rendering for JEI plugins Signed-off-by: shedaniel --- .../me/shedaniel/rei/RoughlyEnoughItemsCore.java | 5 +- .../rei/api/gui/config/entry/FilteringScreen.java | 5 - .../shedaniel/rei/gui/ContainerScreenOverlay.java | 119 +++++---- .../me/shedaniel/rei/gui/CurrentDraggingStack.java | 125 +++++++++ .../shedaniel/rei/gui/credits/CreditsScreen.java | 4 +- .../shedaniel/rei/gui/widget/EntryListWidget.java | 33 ++- .../me/shedaniel/rei/gui/widget/EntryWidget.java | 2 +- .../rei/gui/widget/FavoritesListWidget.java | 289 ++++++++++----------- .../shedaniel/rei/impl/EntryTypeRegistryImpl.java | 11 + .../me/shedaniel/rei/impl/ExclusionZonesImpl.java | 42 ++- .../rei/impl/registry/CategoryRegistryImpl.java | 4 +- 11 files changed, 413 insertions(+), 226 deletions(-) create mode 100644 runtime/src/main/java/me/shedaniel/rei/gui/CurrentDraggingStack.java (limited to 'runtime/src/main/java') diff --git a/runtime/src/main/java/me/shedaniel/rei/RoughlyEnoughItemsCore.java b/runtime/src/main/java/me/shedaniel/rei/RoughlyEnoughItemsCore.java index f0cfe81b5..c668dc282 100644 --- a/runtime/src/main/java/me/shedaniel/rei/RoughlyEnoughItemsCore.java +++ b/runtime/src/main/java/me/shedaniel/rei/RoughlyEnoughItemsCore.java @@ -74,6 +74,7 @@ import net.minecraft.client.gui.screens.recipebook.GhostRecipe; import net.minecraft.client.gui.screens.recipebook.RecipeBookComponent; import net.minecraft.client.gui.screens.recipebook.RecipeUpdateListener; import net.minecraft.client.resources.language.I18n; +import net.minecraft.network.FriendlyByteBuf; import net.minecraft.network.chat.Component; import net.minecraft.network.chat.FormattedText; import net.minecraft.network.chat.TextComponent; @@ -337,7 +338,7 @@ public class RoughlyEnoughItemsCore { @ApiStatus.Internal public static T registerPlugin(T plugin) { PLUGINS.add(plugin); - RoughlyEnoughItemsCore.LOGGER.debug("Registered plugin %s", plugin.getPluginName()); + RoughlyEnoughItemsCore.LOGGER.info("Registered plugin %s", plugin.getPluginName()); return plugin; } @@ -504,7 +505,7 @@ public class RoughlyEnoughItemsCore { } return InteractionResult.PASS; }); - ClientScreenInputEvent.KEY_RELEASED_PRE.register((minecraftClient, screen, mouseX, mouseY, button) -> { + ClientScreenInputEvent.MOUSE_RELEASED_PRE.register((minecraftClient, screen, mouseX, mouseY, button) -> { isLeftModePressed = false; if (shouldReturn(screen)) return InteractionResult.PASS; diff --git a/runtime/src/main/java/me/shedaniel/rei/api/gui/config/entry/FilteringScreen.java b/runtime/src/main/java/me/shedaniel/rei/api/gui/config/entry/FilteringScreen.java index a54845f60..f5d5464a2 100644 --- a/runtime/src/main/java/me/shedaniel/rei/api/gui/config/entry/FilteringScreen.java +++ b/runtime/src/main/java/me/shedaniel/rei/api/gui/config/entry/FilteringScreen.java @@ -482,11 +482,6 @@ public class FilteringScreen extends Screen { } } - @Override - public EntryStack getCurrentEntry() { - return super.getCurrentEntry(); - } - public boolean isSelected() { return getSelection().intersects(getBounds()); } diff --git a/runtime/src/main/java/me/shedaniel/rei/gui/ContainerScreenOverlay.java b/runtime/src/main/java/me/shedaniel/rei/gui/ContainerScreenOverlay.java index a63d38459..e44a56f18 100644 --- a/runtime/src/main/java/me/shedaniel/rei/gui/ContainerScreenOverlay.java +++ b/runtime/src/main/java/me/shedaniel/rei/gui/ContainerScreenOverlay.java @@ -23,25 +23,27 @@ package me.shedaniel.rei.gui; +import com.google.common.collect.Iterables; import com.google.common.collect.Lists; import com.mojang.blaze3d.platform.Window; import com.mojang.blaze3d.systems.RenderSystem; import com.mojang.blaze3d.vertex.PoseStack; -import com.mojang.blaze3d.vertex.Tesselator; -import com.mojang.math.Matrix4f; import com.mojang.math.Vector4f; import me.shedaniel.math.Point; import me.shedaniel.math.Rectangle; import me.shedaniel.math.impl.PointHelper; import me.shedaniel.rei.RoughlyEnoughItemsCore; import me.shedaniel.rei.api.*; +import me.shedaniel.rei.api.gui.drag.DraggableStack; +import me.shedaniel.rei.api.gui.drag.DraggableStackProvider; +import me.shedaniel.rei.api.gui.drag.DraggableStackVisitor; +import me.shedaniel.rei.api.gui.drag.DraggingContext; import me.shedaniel.rei.api.gui.widgets.*; import me.shedaniel.rei.api.ingredient.EntryStack; import me.shedaniel.rei.api.ingredient.util.EntryStacks; import me.shedaniel.rei.api.favorites.FavoriteEntry; import me.shedaniel.rei.api.gui.config.SearchFieldLocation; import me.shedaniel.rei.api.registry.category.CategoryRegistry; -import me.shedaniel.rei.api.registry.display.DisplayRegistry; import me.shedaniel.rei.api.registry.screen.ClickArea; import me.shedaniel.rei.api.registry.screen.DisplayBoundsProvider; import me.shedaniel.rei.api.registry.screen.OverlayDecider; @@ -60,7 +62,6 @@ import net.minecraft.client.gui.components.events.GuiEventListener; import net.minecraft.client.gui.screens.Screen; import net.minecraft.client.gui.screens.inventory.AbstractContainerScreen; import net.minecraft.client.multiplayer.ClientLevel; -import net.minecraft.client.renderer.MultiBufferSource; import net.minecraft.client.renderer.entity.ItemRenderer; import net.minecraft.client.resources.language.I18n; import net.minecraft.client.resources.sounds.SimpleSoundInstance; @@ -75,7 +76,6 @@ import net.minecraft.world.inventory.Slot; import net.minecraft.world.item.ItemStack; import net.minecraft.world.level.GameType; import net.minecraft.world.level.block.Blocks; -import org.apache.logging.log4j.util.TriConsumer; import org.jetbrains.annotations.ApiStatus; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -83,7 +83,6 @@ import org.jetbrains.annotations.Nullable; import java.util.*; import java.util.function.Consumer; import java.util.function.Predicate; -import java.util.stream.Collectors; @ApiStatus.Internal public class ContainerScreenOverlay extends WidgetWithBounds implements REIOverlay { @@ -93,43 +92,11 @@ public class ContainerScreenOverlay extends WidgetWithBounds implements REIOverl private static final EntryListWidget ENTRY_LIST_WIDGET = new EntryListWidget(); private static FavoritesListWidget favoritesListWidget = null; private final List widgets = Lists.newLinkedList(); - public boolean shouldReInit = false; - private int tooltipWidth; - private int tooltipHeight; - private List tooltipLines; - public final TriConsumer renderTooltipCallback = (matrices, mouse, aFloat) -> { - RenderSystem.disableRescaleNormal(); - RenderSystem.disableDepthTest(); - matrices.pushPose(); - matrices.translate(0, 0, 999); - int x = mouse.x; - int y = mouse.y; - this.fillGradient(matrices, x - 3, y - 4, x + tooltipWidth + 3, y - 3, -267386864, -267386864); - this.fillGradient(matrices, x - 3, y + tooltipHeight + 3, x + tooltipWidth + 3, y + tooltipHeight + 4, -267386864, -267386864); - this.fillGradient(matrices, x - 3, y - 3, x + tooltipWidth + 3, y + tooltipHeight + 3, -267386864, -267386864); - this.fillGradient(matrices, x - 4, y - 3, x - 3, y + tooltipHeight + 3, -267386864, -267386864); - this.fillGradient(matrices, x + tooltipWidth + 3, y - 3, x + tooltipWidth + 4, y + tooltipHeight + 3, -267386864, -267386864); - this.fillGradient(matrices, x - 3, y - 3 + 1, x - 3 + 1, y + tooltipHeight + 3 - 1, 1347420415, 1344798847); - this.fillGradient(matrices, x + tooltipWidth + 2, y - 3 + 1, x + tooltipWidth + 3, y + tooltipHeight + 3 - 1, 1347420415, 1344798847); - this.fillGradient(matrices, x - 3, y - 3, x + tooltipWidth + 3, y - 3 + 1, 1347420415, 1347420415); - this.fillGradient(matrices, x - 3, y + tooltipHeight + 2, x + tooltipWidth + 3, y + tooltipHeight + 3, 1344798847, 1344798847); - int currentY = y; - MultiBufferSource.BufferSource immediate = MultiBufferSource.immediate(Tesselator.getInstance().getBuilder()); - Matrix4f matrix = matrices.last().pose(); - for (int lineIndex = 0; lineIndex < tooltipLines.size(); lineIndex++) { - font.drawInBatch(tooltipLines.get(lineIndex), x, currentY, -1, true, matrix, immediate, false, 0, 15728880); - currentY += lineIndex == 0 ? 12 : 10; - } - immediate.endBatch(); - matrices.popPose(); - RenderSystem.enableDepthTest(); - RenderSystem.enableRescaleNormal(); - }; + public boolean shouldReload = false; private Rectangle bounds; private Window window; private Button leftButton, rightButton; - @ApiStatus.Experimental - private Rectangle subsetsButtonBounds; + private CurrentDraggingStack draggingStack = new CurrentDraggingStack(); @Nullable private ContainerScreenOverlay.OverlayMenu overlayMenu = null; @@ -208,7 +175,12 @@ public class ContainerScreenOverlay extends WidgetWithBounds implements REIOverl @Override public void queueReloadOverlay() { - shouldReInit = true; + shouldReload = true; + } + + @Override + public DraggingContext getDraggingContext() { + return draggingStack; } public void init(boolean useless) { @@ -216,7 +188,11 @@ public class ContainerScreenOverlay extends WidgetWithBounds implements REIOverl } public void init() { - this.shouldReInit = false; + Iterable stackProviders = (Iterable) Iterables.filter(widgets, widget -> widget instanceof DraggableStackProvider); + Iterable stackVisitors = (Iterable) Iterables.filter(widgets, widget -> widget instanceof DraggableStackVisitor); + draggingStack.set(DraggableStackProvider.from(() -> stackProviders), DraggableStackVisitor.from(() -> stackVisitors)); + + this.shouldReload = false; //Update Variables this.children().clear(); this.removeOverlayMenu(); @@ -224,8 +200,9 @@ public class ContainerScreenOverlay extends WidgetWithBounds implements REIOverl this.bounds = ScreenRegistry.getInstance().getOverlayBounds(ConfigObject.getInstance().getDisplayPanelLocation(), Minecraft.getInstance().screen); widgets.add(ENTRY_LIST_WIDGET); if (ConfigObject.getInstance().isFavoritesEnabled()) { - if (favoritesListWidget == null) + if (favoritesListWidget == null) { favoritesListWidget = new FavoritesListWidget(); + } favoritesListWidget.favoritePanel.resetRows(); widgets.add(favoritesListWidget); } @@ -353,12 +330,12 @@ public class ContainerScreenOverlay extends WidgetWithBounds implements REIOverl helper.blit(matrices, weatherButton.getBounds().x + 3, weatherButton.getBounds().y + 3, getCurrentWeather().getId() * 14, 14, 14, 14); })); } - subsetsButtonBounds = getSubsetsButtonBounds(); + Rectangle subsetsButtonBounds = getSubsetsButtonBounds(); if (ConfigObject.getInstance().isSubsetsEnabled()) { widgets.add(InternalWidgets.wrapLateRenderable(InternalWidgets.wrapTranslate(Widgets.createButton(subsetsButtonBounds, ClientHelperImpl.getInstance().isAprilFools.get() ? new TranslatableComponent("text.rei.tiny_potato") : new TranslatableComponent("text.rei.subsets")) .onClick(button -> { proceedOpenMenuOrElse(Menu.SUBSETS, () -> { - openMenu(Menu.SUBSETS, Menu.createSubsetsMenuFromRegistry(new Point(this.subsetsButtonBounds.x, this.subsetsButtonBounds.getMaxY())), point -> true); + openMenu(Menu.SUBSETS, Menu.createSubsetsMenuFromRegistry(new Point(subsetsButtonBounds.x, subsetsButtonBounds.getMaxY())), point -> true); }, menu -> { removeOverlayMenu(); }); @@ -397,6 +374,56 @@ public class ContainerScreenOverlay extends WidgetWithBounds implements REIOverl )); tmp.setZ(600); } + + widgets.add(draggingStack); + + if (Minecraft.getInstance().screen instanceof RecipeViewingScreen) { + widgets.add(new RecipeViewingScreenDraggable()); + } + } + + private static class RecipeViewingScreenDraggable extends Widget implements DraggableStackProvider{ + @Nullable + @Override + public DraggableStack getHoveredStack(DraggingContext context, double mouseX, double mouseY) { + for (Widget widget : ((RecipeViewingScreen) Minecraft.getInstance().screen).getWidgets()) { + if (widget instanceof EntryWidget) { + if (widget.containsMouse(mouseX, mouseY)) { + return new DraggableStack() { + EntryStack stack = ((EntryWidget)widget).getCurrentEntry().copy().rewrap(); + + @Override + public EntryStack getStack() { + return stack; + } + + @Override + public void drag() { + + } + + @Override + public void release(boolean accepted) { + if (!accepted) { + context.registerRenderBackToPosition(this, () -> new Point(((EntryWidget) widget).getBounds().x - 8, ((EntryWidget) widget).getBounds().y - 8)); + } + } + }; + } + } + } + return null; + } + + @Override + public void render(PoseStack poseStack, int i, int j, float f) { + + } + + @Override + public List children() { + return Collections.emptyList(); + } } private Rectangle getSubsetsButtonBounds() { @@ -513,7 +540,7 @@ public class ContainerScreenOverlay extends WidgetWithBounds implements REIOverl @Override public void render(PoseStack matrices, int mouseX, int mouseY, float delta) { - if (shouldReInit) { + if (shouldReload) { ENTRY_LIST_WIDGET.updateSearch(ScreenHelper.getSearchField().getText(), true); init(); } else { diff --git a/runtime/src/main/java/me/shedaniel/rei/gui/CurrentDraggingStack.java b/runtime/src/main/java/me/shedaniel/rei/gui/CurrentDraggingStack.java new file mode 100644 index 000000000..6f464100e --- /dev/null +++ b/runtime/src/main/java/me/shedaniel/rei/gui/CurrentDraggingStack.java @@ -0,0 +1,125 @@ +package me.shedaniel.rei.gui; + +import com.mojang.blaze3d.vertex.PoseStack; +import me.shedaniel.math.Point; +import me.shedaniel.math.Rectangle; +import me.shedaniel.math.impl.PointHelper; +import me.shedaniel.rei.RoughlyEnoughItemsCore; +import me.shedaniel.rei.api.gui.drag.DraggableStack; +import me.shedaniel.rei.api.gui.drag.DraggableStackProvider; +import me.shedaniel.rei.api.gui.drag.DraggableStackVisitor; +import me.shedaniel.rei.api.gui.drag.DraggingContext; +import me.shedaniel.rei.api.gui.widgets.Widget; +import me.shedaniel.rei.gui.widget.LateRenderable; +import net.minecraft.client.gui.components.events.GuiEventListener; +import org.jetbrains.annotations.Nullable; + +import java.util.Collections; +import java.util.List; +import java.util.Optional; +import java.util.function.Supplier; + +public class CurrentDraggingStack extends Widget implements LateRenderable, DraggingContext { + private DraggableStackProvider provider; + private DraggableStackVisitor visitor; + @Nullable + private DraggableEntry entry; + + public void set(DraggableStackProvider provider, DraggableStackVisitor visitor) { + this.provider = provider; + this.visitor = visitor; + } + + @Override + public void render(PoseStack matrices, int mouseX, int mouseY, float delta) { + if (entry != null && entry.dragging) { + if (!RoughlyEnoughItemsCore.isLeftModePressed) { + drop(); + return; + } + matrices.pushPose(); + matrices.translate(0, 0, 600); + entry.stack.render(matrices, new Rectangle(mouseX - 8, mouseY - 8, 16, 16), mouseX, mouseY, delta); + matrices.popPose(); + } + } + + @Override + public List children() { + return Collections.emptyList(); + } + + @Override + public boolean mouseClicked(double mouseX, double mouseY, int button) { + drop(); + DraggableStack hoveredStack = provider.getHoveredStack(this, mouseX, mouseY); + if (hoveredStack != null) { + entry = new DraggableEntry(hoveredStack, new Point(mouseX, mouseY)); + return true; + } + return false; + } + + @Override + public boolean mouseReleased(double d, double e, int i) { + return false; + } + + @Override + public boolean mouseDragged(double mouseX1, double mouseY1, int button, double mouseX2, double mouseY2) { + if (entry != null && !entry.dragging) { + Point startPoint = entry.start; + double xDistance = Math.abs(startPoint.x - mouseX1); + double yDistance = Math.abs(startPoint.y - mouseY1); + double requiredDistance = 4; + + if (xDistance * xDistance + yDistance * yDistance > requiredDistance * requiredDistance) { + entry.dragging = true; + entry.stack.drag(); + } + } + + return entry != null; + } + + private boolean drop() { + if (entry != null && entry.dragging) { + Optional acceptor = visitor.visitDraggedStack(entry.stack); + entry.stack.release(acceptor.isPresent()); + acceptor.ifPresent(a -> a.accept(entry.stack)); + entry = null; + return true; + } + + entry = null; + return false; + } + + @Override + @Nullable + public DraggableStack getCurrentStack() { + return entry != null && entry.dragging ? entry.stack : null; + } + + @Override + @Nullable + public Point getCurrentPosition() { + return isDraggingStack() ? PointHelper.ofMouse() : null; + } + + @Override + public void registerRenderBackToPosition(DraggableStack stack, Supplier position) { + + } + + private class DraggableEntry { + private final DraggableStack stack; + private final Point start; + private boolean dragging = false; + + private DraggableEntry(DraggableStack stack, Point start) { + this.stack = stack; + this.start = start; + } + } +} diff --git a/runtime/src/main/java/me/shedaniel/rei/gui/credits/CreditsScreen.java b/runtime/src/main/java/me/shedaniel/rei/gui/credits/CreditsScreen.java index 1e676e405..4f3ed051e 100644 --- a/runtime/src/main/java/me/shedaniel/rei/gui/credits/CreditsScreen.java +++ b/runtime/src/main/java/me/shedaniel/rei/gui/credits/CreditsScreen.java @@ -25,13 +25,13 @@ package me.shedaniel.rei.gui.credits; import com.google.common.collect.Lists; import com.mojang.blaze3d.vertex.PoseStack; +import me.shedaniel.architectury.platform.Platform; import me.shedaniel.clothconfig2.impl.EasingMethod; import me.shedaniel.rei.api.ConfigObject; import me.shedaniel.rei.api.util.ImmutableLiteralText; import me.shedaniel.rei.gui.TransformingScreen; import me.shedaniel.rei.gui.credits.CreditsEntryListWidget.TextCreditsItem; import me.shedaniel.rei.gui.credits.CreditsEntryListWidget.TranslationCreditsItem; -import net.fabricmc.loader.api.FabricLoader; import net.minecraft.Util; import net.minecraft.client.Minecraft; import net.minecraft.client.gui.chat.NarratorChatListener; @@ -100,7 +100,7 @@ public class CreditsScreen extends Screen { ); }).collect(Collectors.toList()); int i = width - 80 - 6; - for (String line : String.format("§lRoughly Enough Items (v%s)\n§7Originally a fork for Almost Enough Items.\n\n§lLanguage Translation\n%s\n\n§lLicense\n§7Roughly Enough Items is licensed under MIT.", FabricLoader.getInstance().getModContainer("roughlyenoughitems").map(mod -> mod.getMetadata().getVersion().getFriendlyString()).orElse("Unknown"), "%translators%").split("\n")) + for (String line : String.format("§lRoughly Enough Items (v%s)\n§7Originally a fork for Almost Enough Items.\n\n§lLanguage Translation\n%s\n\n§lLicense\n§7Roughly Enough Items is licensed under MIT.", Platform.getMod("roughlyenoughitems").getVersion(), "%translators%").split("\n")) if (line.equalsIgnoreCase("%translators%")) { if (exception[0] != null) { entryListWidget.creditsAddEntry(new TextCreditsItem(new ImmutableLiteralText("Failed to get translators: " + exception[0].toString()))); diff --git a/runtime/src/main/java/me/shedaniel/rei/gui/widget/EntryListWidget.java b/runtime/src/main/java/me/shedaniel/rei/gui/widget/EntryListWidget.java index 4eba1f245..e89023651 100644 --- a/runtime/src/main/java/me/shedaniel/rei/gui/widget/EntryListWidget.java +++ b/runtime/src/main/java/me/shedaniel/rei/gui/widget/EntryListWidget.java @@ -44,6 +44,9 @@ import me.shedaniel.math.impl.PointHelper; import me.shedaniel.rei.RoughlyEnoughItemsCore; import me.shedaniel.rei.api.*; import me.shedaniel.rei.api.gui.config.EntryPanelOrdering; +import me.shedaniel.rei.api.gui.drag.DraggableStack; +import me.shedaniel.rei.api.gui.drag.DraggableStackProvider; +import me.shedaniel.rei.api.gui.drag.DraggingContext; import me.shedaniel.rei.api.gui.widgets.Tooltip; import me.shedaniel.rei.api.gui.widgets.Widget; import me.shedaniel.rei.api.gui.widgets.WidgetWithBounds; @@ -79,6 +82,7 @@ import org.apache.commons.lang3.mutable.MutableInt; import org.apache.commons.lang3.mutable.MutableLong; import org.jetbrains.annotations.ApiStatus; import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; import java.util.ArrayList; import java.util.Collections; @@ -92,7 +96,7 @@ import java.util.function.Consumer; import java.util.stream.Collectors; @ApiStatus.Internal -public class EntryListWidget extends WidgetWithBounds { +public class EntryListWidget extends WidgetWithBounds implements DraggableStackProvider { static final Comparator> ENTRY_NAME_COMPARER = Comparator.comparing(stack -> stack.asFormatStrippedText().getString()); static final Comparator> ENTRY_GROUP_COMPARER = Comparator.comparingInt(stack -> { if (stack.getType() == VanillaEntryTypes.ITEM) { @@ -180,6 +184,33 @@ public class EntryListWidget extends WidgetWithBounds { return new Rectangle((int) (bounds.getCenterX() - width * (entrySize / 2f)), (int) (bounds.getCenterY() - height * (entrySize / 2f)), width * entrySize, height * entrySize); } + @Override + @Nullable + public DraggableStack getHoveredStack(DraggingContext context, double mouseX, double mouseY) { + for (EntryListEntry entry : entries) { + if (!entry.getCurrentEntry().isEmpty() && entry.containsMouse(mouseX, mouseY)) { + return new DraggableStack() { + EntryStack stack = entry.getCurrentEntry().copy(); + + @Override + public EntryStack getStack() { + return stack; + } + + @Override + public void drag() { + } + + @Override + public void release(boolean accepted) { + context.registerRenderBackToPosition(this, () -> new Point(entry.getBounds().x - 8, entry.getBounds().y - 8)); + } + }; + } + } + return null; + } + @Override public boolean mouseScrolled(double double_1, double double_2, double double_3) { if (bounds.contains(double_1, double_2)) { diff --git a/runtime/src/main/java/me/shedaniel/rei/gui/widget/EntryWidget.java b/runtime/src/main/java/me/shedaniel/rei/gui/widget/EntryWidget.java index a98f55b2f..4c15dd4d9 100644 --- a/runtime/src/main/java/me/shedaniel/rei/gui/widget/EntryWidget.java +++ b/runtime/src/main/java/me/shedaniel/rei/gui/widget/EntryWidget.java @@ -244,7 +244,7 @@ public class EntryWidget extends Slot { return this; } - protected EntryStack getCurrentEntry() { + public EntryStack getCurrentEntry() { if (entryStacks.isEmpty()) return EntryStack.empty(); if (entryStacks.size() == 1) diff --git a/runtime/src/main/java/me/shedaniel/rei/gui/widget/FavoritesListWidget.java b/runtime/src/main/java/me/shedaniel/rei/gui/widget/FavoritesListWidget.java index 1fa2abd3a..4fb4a62ce 100644 --- a/runtime/src/main/java/me/shedaniel/rei/gui/widget/FavoritesListWidget.java +++ b/runtime/src/main/java/me/shedaniel/rei/gui/widget/FavoritesListWidget.java @@ -37,23 +37,33 @@ import me.shedaniel.clothconfig2.gui.widget.DynamicNewSmoothScrollingEntryListWi import me.shedaniel.math.Point; import me.shedaniel.math.Rectangle; import me.shedaniel.math.impl.PointHelper; -import me.shedaniel.rei.RoughlyEnoughItemsCore; -import me.shedaniel.rei.api.*; -import me.shedaniel.rei.api.gui.widgets.Widget; -import me.shedaniel.rei.api.gui.widgets.WidgetWithBounds; -import me.shedaniel.rei.api.ingredient.entry.BatchEntryRenderer; +import me.shedaniel.rei.api.ConfigManager; +import me.shedaniel.rei.api.ConfigObject; +import me.shedaniel.rei.api.REIHelper; +import me.shedaniel.rei.api.REIOverlay; import me.shedaniel.rei.api.favorites.FavoriteEntry; import me.shedaniel.rei.api.favorites.FavoriteEntryType; import me.shedaniel.rei.api.favorites.FavoriteMenuEntry; +import me.shedaniel.rei.api.gui.drag.DraggableStack; +import me.shedaniel.rei.api.gui.drag.DraggableStackProvider; +import me.shedaniel.rei.api.gui.drag.DraggableStackVisitor; +import me.shedaniel.rei.api.gui.drag.DraggingContext; +import me.shedaniel.rei.api.gui.widgets.Tooltip; +import me.shedaniel.rei.api.gui.widgets.Widget; +import me.shedaniel.rei.api.gui.widgets.WidgetWithBounds; +import me.shedaniel.rei.api.ingredient.EntryStack; +import me.shedaniel.rei.api.ingredient.entry.BatchEntryRenderer; import me.shedaniel.rei.api.ingredient.util.EntryStacks; import me.shedaniel.rei.api.registry.screen.ScreenRegistry; +import me.shedaniel.rei.api.util.CollectionUtils; import me.shedaniel.rei.api.util.ImmutableLiteralText; -import me.shedaniel.rei.api.gui.widgets.Tooltip; import me.shedaniel.rei.gui.ContainerScreenOverlay; import me.shedaniel.rei.gui.modules.Menu; import me.shedaniel.rei.gui.modules.MenuEntry; -import me.shedaniel.rei.impl.*; -import me.shedaniel.rei.api.util.CollectionUtils; +import me.shedaniel.rei.impl.Animator; +import me.shedaniel.rei.impl.ConfigManagerImpl; +import me.shedaniel.rei.impl.ConfigObjectImpl; +import me.shedaniel.rei.impl.ScreenHelper; import net.minecraft.client.Minecraft; import net.minecraft.client.gui.components.events.AbstractContainerEventHandler; import net.minecraft.client.gui.components.events.GuiEventListener; @@ -77,7 +87,7 @@ import java.util.stream.Stream; import static me.shedaniel.rei.gui.widget.EntryListWidget.*; @ApiStatus.Internal -public class FavoritesListWidget extends WidgetWithBounds { +public class FavoritesListWidget extends WidgetWithBounds implements DraggableStackProvider, DraggableStackVisitor { protected final ScrollingContainer scrolling = new ScrollingContainer() { @Override public Rectangle getBounds() { @@ -102,7 +112,6 @@ public class FavoritesListWidget extends WidgetWithBounds { private final Int2ObjectMap removedEntries = new Int2ObjectLinkedOpenHashMap<>(); private List entriesList = Lists.newArrayList(); private List children = Lists.newArrayList(); - private Entry lastTouchedEntry = null; public final AddFavoritePanel favoritePanel = new AddFavoritePanel(this); public final ToggleAddFavoritePanelButton favoritePanelButton = new ToggleAddFavoritePanelButton(this); @@ -142,6 +151,71 @@ public class FavoritesListWidget extends WidgetWithBounds { return fullBounds; } + @Override + @Nullable + public DraggableStack getHoveredStack(DraggingContext context, double mouseX, double mouseY) { + Function apply = entry -> new DraggableStack() { + private FavoriteEntry favoriteEntry = entry.getEntry(); + private EntryStack stack = EntryStacks.of(favoriteEntry.getRenderer(false)).copy(); + + @Override + public EntryStack getStack() { + return stack; + } + + @Override + public void drag() { + entries.remove(entry.hashIgnoreAmount()); + applyNewFavorites(entries.values().stream() + .map(Entry::getEntry) + .collect(Collectors.toList())); + } + + @Override + public void release(boolean accepted) { + if (!accepted) { + drop(entry, this, favoriteEntry); + } + } + }; + if (innerBounds.contains(mouseX, mouseY)) { + for (Entry entry : entries.values()) { + if (entry.getWidget().containsMouse(mouseX, mouseY)) { + return apply.apply(entry); + } + } + } + if (favoritePanel.bounds.contains(mouseX, mouseY)) { + for (AddFavoritePanel.Row row : favoritePanel.rows.get()) { + if (row instanceof AddFavoritePanel.SectionEntriesRow) { + for (AddFavoritePanel.SectionEntriesRow.SectionFavoriteWidget widget : ((AddFavoritePanel.SectionEntriesRow) row).widgets) { + if (widget.containsMouse(mouseX, mouseY)) { + Entry entry = new Entry(widget.entry.copy(), entrySize()); + entry.size.setAs(entrySize() * 100); + return apply.apply(entry); + } + } + } + } + } + return null; + } + + @Override + public Optional visitDraggedStack(DraggableStack stack) { + if (innerBounds.contains(PointHelper.ofMouse())) { + return Optional.of(this::acceptDraggedStack); + } + return Optional.empty(); + } + + private void acceptDraggedStack(DraggableStack stack) { + FavoriteEntry favoriteEntry = FavoriteEntry.fromEntryStack(stack.getStack().copy()); + Entry entry = new Entry(favoriteEntry, entrySize()); + entry.size.setAs(entrySize() * 100); + drop(entry, stack, favoriteEntry); + } + @Override public void render(PoseStack matrices, int mouseX, int mouseY, float delta) { if (fullBounds.isEmpty() || currentBounds.isEmpty()) @@ -149,19 +223,9 @@ public class FavoritesListWidget extends WidgetWithBounds { int entrySize = entrySize(); boolean fastEntryRendering = ConfigObject.getInstance().doesFastEntryRendering(); updateEntriesPosition(entry -> true); - if (lastTouchedEntry != null && lastTouchedEntry.dragged) { - lastTouchedEntry.x.setAs(mouseX - entrySize / 2); - lastTouchedEntry.y.setAs(mouseY - entrySize / 2 + (int) scrolling.scrollAmount); - - if (!RoughlyEnoughItemsCore.isLeftModePressed) - resetDraggedEntry(); - } for (Entry entry : entries.values()) { entry.update(delta); } - if (lastTouchedEntry != null && lastTouchedEntry.madeUp) { - lastTouchedEntry.update(delta); - } ObjectIterator removedEntriesIterator = removedEntries.values().iterator(); while (removedEntriesIterator.hasNext()) { Entry removedEntry = removedEntriesIterator.next(); @@ -176,7 +240,6 @@ public class FavoritesListWidget extends WidgetWithBounds { ScissorsHandler.INSTANCE.scissor(currentBounds); Stream entryStream = this.entriesList.stream() - .filter(entry -> lastTouchedEntry == null || entry != lastTouchedEntry.getWidget()) .filter(entry -> entry.getBounds().getMaxY() >= this.currentBounds.getY() && entry.getBounds().y <= this.currentBounds.getMaxY()); if (fastEntryRendering) { @@ -193,13 +256,6 @@ public class FavoritesListWidget extends WidgetWithBounds { ScissorsHandler.INSTANCE.removeLastScissor(); renderAddFavorite(matrices, mouseX, mouseY, delta); - - if (lastTouchedEntry != null) { - matrices.pushPose(); - matrices.translate(0, 0, 600); - lastTouchedEntry.widget.render(matrices, mouseX, mouseY, delta); - matrices.popPose(); - } } private void renderAddFavorite(PoseStack matrices, int mouseX, int mouseY, float delta) { @@ -209,15 +265,6 @@ public class FavoritesListWidget extends WidgetWithBounds { @Override public boolean mouseDragged(double mouseX, double mouseY, int int_1, double double_3, double double_4) { - if (lastTouchedEntry != null && !lastTouchedEntry.dragged) { - Point startPoint = lastTouchedEntry.startedDraggingPosition; - double xDistance = Math.abs(startPoint.x - mouseX); - double yDistance = Math.abs(startPoint.y - mouseY); - double requiredDistance = entrySize() * .4; - if (xDistance * xDistance + yDistance * yDistance > requiredDistance * requiredDistance) { - lastTouchedEntry.dragged = true; - } - } if (scrolling.mouseDragged(mouseX, mouseY, int_1, double_3, double_4, ConfigObject.getInstance().doesSnapToRows(), entrySize())) return true; return super.mouseDragged(mouseX, mouseY, int_1, double_3, double_4); @@ -305,11 +352,10 @@ public class FavoritesListWidget extends WidgetWithBounds { int width = innerBounds.width / entrySize; int currentX = 0; int currentY = 0; - int releaseIndex = lastTouchedEntry != null && lastTouchedEntry.dragged ? getReleaseIndex() : -2; + int releaseIndex = getReleaseIndex(); int slotIndex = 0; for (Entry entry : this.entries.values()) { - if (entry.dragged) continue; while (true) { int xPos = currentX * entrySize + innerBounds.x; int yPos = currentY * entrySize + innerBounds.y; @@ -340,14 +386,15 @@ public class FavoritesListWidget extends WidgetWithBounds { } public int getReleaseIndex() { - if (lastTouchedEntry != null && lastTouchedEntry.dragged && currentBounds.contains(PointHelper.ofMouse())) { + DraggingContext context = DraggingContext.getInstance(); + Point position = context.getCurrentPosition(); + if (context.isDraggingStack() && currentBounds.contains(position)) { int entrySize = entrySize(); int width = innerBounds.width / entrySize; int currentX = 0; int currentY = 0; List> entriesPoints = Lists.newArrayList(); for (Entry entry : this.entries.values()) { - if (entry.dragged) continue; while (true) { int xPos = currentX * entrySize + innerBounds.x; int yPos = currentY * entrySize + innerBounds.y; @@ -377,8 +424,8 @@ public class FavoritesListWidget extends WidgetWithBounds { } } - double x = lastTouchedEntry.x.doubleValue(); - double y = lastTouchedEntry.y.doubleValue(); + double x = position.x - 8; + double y = position.y - 8; return Mth.clamp(entriesPoints.stream() .filter(value -> { @@ -397,115 +444,69 @@ public class FavoritesListWidget extends WidgetWithBounds { 0, entriesPoints.size()); } - return entries.size(); + return -2; } - public void resetDraggedEntry() { - if (lastTouchedEntry != null && lastTouchedEntry.dragged) { - Entry entry = lastTouchedEntry; - double x = entry.x.doubleValue(); - double y = entry.y.doubleValue(); - entry.startedDraggingPosition = null; + public void drop(Entry entry, DraggableStack stack, FavoriteEntry favoriteEntry) { + DraggingContext context = DraggingContext.getInstance(); + double x = context.getCurrentPosition().x; + double y = context.getCurrentPosition().y; + entry.startedDraggingPosition = null; + + entry.x.setAs(x - 8); + entry.y.setAs(y - 8); + + boolean contains = currentBounds.contains(PointHelper.ofMouse()); + int newIndex = contains ? getReleaseIndex() : Iterables.indexOf(entries.values(), e -> e == entry); + + if (entries.size() - 1 <= newIndex) { + this.entries.remove(entry.hashIgnoreAmount()); + this.entries.put(entry.hashIgnoreAmount(), entry); + } else { + Int2ObjectMap prevEntries = new Int2ObjectLinkedOpenHashMap<>(entries); + this.entries.clear(); - boolean contains = currentBounds.contains(PointHelper.ofMouse()); - if (contains || !entry.madeUp) { - int newIndex = contains ? getReleaseIndex() : Iterables.indexOf(entries.values(), e -> e == entry); - entry.dragged = false; - - if (entries.size() - 1 <= newIndex) { - this.entries.remove(entry.hashIgnoreAmount()); + int index = 0; + for (Int2ObjectMap.Entry entryEntry : prevEntries.int2ObjectEntrySet()) { + if (index == newIndex) this.entries.put(entry.hashIgnoreAmount(), entry); - } else { - Int2ObjectMap prevEntries = new Int2ObjectLinkedOpenHashMap<>(entries); - this.entries.clear(); - - int index = 0; - for (Int2ObjectMap.Entry entryEntry : prevEntries.int2ObjectEntrySet()) { - if (index == newIndex) - this.entries.put(entry.hashIgnoreAmount(), entry); - if (entryEntry.getIntKey() != entry.hashIgnoreAmount()) { - this.entries.put(entryEntry.getIntKey(), entryEntry.getValue()); - - index++; - } - } - } - - applyNewEntriesList(); - - if (ConfigObject.getInstance().isFavoritesEnabled()) { - List favorites = ConfigObject.getInstance().getFavoriteEntries(); - favorites.clear(); - for (Entry value : this.entries.values()) { - favorites.add(value.entry.copy()); - } + if (entryEntry.getIntKey() != entry.hashIgnoreAmount()) { + this.entries.put(entryEntry.getIntKey(), entryEntry.getValue()); - ConfigManager.getInstance().saveConfig(); + index++; } - - if (entry.madeUp) { - applyNewFavorites(this.entries.values().stream() - .map(Entry::getEntry) - .collect(Collectors.toList())); - } - - entry.madeUp = false; } } - lastTouchedEntry = null; + applyNewEntriesList(); + + if (ConfigObject.getInstance().isFavoritesEnabled()) { + List favorites = ConfigObject.getInstance().getFavoriteEntries(); + favorites.clear(); + for (Entry value : this.entries.values()) { + favorites.add(value.entry.copy()); + } + + ConfigManager.getInstance().saveConfig(); + } + + applyNewFavorites(this.entries.values().stream() + .map(Entry::getEntry) + .collect(Collectors.toList())); } @Override - public boolean mouseClicked(double mouseX, double mouseY, int int_1) { - resetDraggedEntry(); - - if (scrolling.updateDraggingState(mouseX, mouseY, int_1)) + public boolean mouseClicked(double mouseX, double mouseY, int button) { + if (scrolling.updateDraggingState(mouseX, mouseY, button)) return true; - if (innerBounds.contains(mouseX, mouseY)) { - for (Entry entry : entries.values()) { - if (entry.getWidget().containsMouse(mouseX, mouseY)) { - lastTouchedEntry = entry; - lastTouchedEntry.startedDraggingPosition = new Point(mouseX, mouseY); - break; - } - } - } else if (favoritePanel.bounds.contains(mouseX, mouseY)) { - back: - for (AddFavoritePanel.Row row : favoritePanel.rows.get()) { - if (row instanceof AddFavoritePanel.SectionEntriesRow) { - for (AddFavoritePanel.SectionEntriesRow.SectionFavoriteWidget widget : ((AddFavoritePanel.SectionEntriesRow) row).widgets) { - if (widget.containsMouse(mouseX, mouseY)) { - lastTouchedEntry = new Entry(widget.entry.copy(), entrySize()); - lastTouchedEntry.madeUp = true; - lastTouchedEntry.dragged = true; - lastTouchedEntry.size.setAs(entrySize() * 100); - applyNewFavorites(this.entries.values().stream() - .map(Entry::getEntry) - .map(FavoriteEntry::copy) - .filter(entry -> !entry.equals(widget.entry)) - .collect(Collectors.toList())); - break back; - } - } - } - } - } for (Widget widget : children()) - if (widget.mouseClicked(mouseX, mouseY, int_1)) + if (widget.mouseClicked(mouseX, mouseY, button)) return true; - return lastTouchedEntry != null; + return false; } @Override public boolean mouseReleased(double mouseX, double mouseY, int button) { - if (lastTouchedEntry != null && lastTouchedEntry.dragged) { - resetDraggedEntry(); - return true; - } - - lastTouchedEntry = null; - if (containsMouse(mouseX, mouseY)) { for (Widget widget : children()) if (widget.mouseReleased(mouseX, mouseY, button)) @@ -519,8 +520,6 @@ public class FavoritesListWidget extends WidgetWithBounds { private final EntryListEntry widget; private boolean hidden; private Point startedDraggingPosition; - private boolean dragged; - private boolean madeUp; private Animator x = new Animator(); private Animator y = new Animator(); private Animator size = new Animator(); @@ -601,18 +600,6 @@ public class FavoritesListWidget extends WidgetWithBounds { return true; } - @Override - public void queueTooltip(PoseStack matrices, int mouseX, int mouseY, float delta) { - if (lastTouchedEntry == null || !lastTouchedEntry.dragged) - super.queueTooltip(matrices, mouseX, mouseY, delta); - } - - @Override - protected void drawHighlighted(PoseStack matrices, int mouseX, int mouseY, float delta) { - if (lastTouchedEntry == null || !lastTouchedEntry.dragged) - super.drawHighlighted(matrices, mouseX, mouseY, delta); - } - @Override public void render(PoseStack matrices, int mouseX, int mouseY, float delta) { Optional overlayOptional = ScreenHelper.getOptionalOverlay(); @@ -622,11 +609,7 @@ public class FavoritesListWidget extends WidgetWithBounds { UUID uuid = favoriteEntry.getUuid(); boolean isOpened = overlay.isMenuOpened(uuid); - if (entry.dragged || entry.madeUp) { - if (isOpened) { - overlay.removeOverlayMenu(); - } - } else if (isOpened || !overlay.isAnyMenuOpened()) { + if (isOpened || !overlay.isAnyMenuOpened()) { boolean inBounds = containsMouse(mouseX, mouseY) || overlay.isMenuInBounds(uuid); if (isOpened != inBounds) { if (inBounds) { @@ -955,7 +938,7 @@ public class FavoritesListWidget extends WidgetWithBounds { this.getBounds().x = (int) Math.round(x.doubleValue() + offsetSize); this.getBounds().y = (int) Math.round(y.doubleValue() + offsetSize) - (int) scroller.scrollAmount; } - + @Override public @Nullable Tooltip getCurrentTooltip(Point point) { Tooltip tooltip = super.getCurrentTooltip(point); diff --git a/runtime/src/main/java/me/shedaniel/rei/impl/EntryTypeRegistryImpl.java b/runtime/src/main/java/me/shedaniel/rei/impl/EntryTypeRegistryImpl.java index b6342a780..e8fe8cec6 100644 --- a/runtime/src/main/java/me/shedaniel/rei/impl/EntryTypeRegistryImpl.java +++ b/runtime/src/main/java/me/shedaniel/rei/impl/EntryTypeRegistryImpl.java @@ -39,6 +39,7 @@ import org.jetbrains.annotations.NotNull; import java.util.ArrayList; import java.util.Collections; import java.util.List; +import java.util.Set; @ApiStatus.Internal public class EntryTypeRegistryImpl implements EntryTypeRegistry { @@ -69,6 +70,16 @@ public class EntryTypeRegistryImpl implements EntryTypeRegistry { return this.entryTypes.get(id); } + @Override + public Set keySet() { + return this.entryTypes.keySet(); + } + + @Override + public Set> values() { + return this.entryTypes.values(); + } + @Override @NotNull public Iterable> getBridgesFor(EntryType original, EntryType destination) { diff --git a/runtime/src/main/java/me/shedaniel/rei/impl/ExclusionZonesImpl.java b/runtime/src/main/java/me/shedaniel/rei/impl/ExclusionZonesImpl.java index 99d3da4d1..8bdd2c472 100644 --- a/runtime/src/main/java/me/shedaniel/rei/impl/ExclusionZonesImpl.java +++ b/runtime/src/main/java/me/shedaniel/rei/impl/ExclusionZonesImpl.java @@ -23,7 +23,9 @@ package me.shedaniel.rei.impl; +import com.google.common.collect.HashMultimap; import com.google.common.collect.Lists; +import com.google.common.collect.Multimap; import me.shedaniel.math.Rectangle; import me.shedaniel.rei.api.gui.config.DisplayPanelLocation; import me.shedaniel.rei.api.registry.screen.ExclusionZones; @@ -32,22 +34,22 @@ import net.fabricmc.api.EnvType; import net.fabricmc.api.Environment; import net.minecraft.client.Minecraft; import net.minecraft.client.gui.screens.Screen; -import net.minecraft.util.Tuple; import net.minecraft.world.InteractionResult; import org.jetbrains.annotations.ApiStatus; +import java.util.Collection; import java.util.Comparator; import java.util.List; +import java.util.Map; import java.util.function.Supplier; @ApiStatus.Internal @Environment(EnvType.CLIENT) public class ExclusionZonesImpl implements ExclusionZones { - private static final Comparator RECTANGLE_COMPARER = Comparator.comparingLong(Rectangle::hashCode); private long lastArea = -1; - private List, Float>, Supplier>>> list = Lists.newArrayList(); + private Multimap, Supplier>> list = HashMultimap.create(); @Override public boolean isHandingScreen(Class screen) { @@ -62,12 +64,19 @@ public class ExclusionZonesImpl implements ExclusionZones { @Override public InteractionResult isInZone(double mouseX, double mouseY) { Class screenClass = Minecraft.getInstance().screen.getClass(); - for (Tuple, Float>, Supplier>> pair : list) { - if (pair.getA().getA().isAssignableFrom(screenClass)) - for (Rectangle zone : pair.getB().get()) - if (zone.contains(mouseX, mouseY)) - return InteractionResult.FAIL; + + for (Map.Entry, Collection>>> collectionEntry : list.asMap().entrySet()) { + if (collectionEntry.getKey().isAssignableFrom(screenClass)) { + for (Supplier> listSupplier : collectionEntry.getValue()) { + for (Rectangle zone : listSupplier.get()) { + if (zone.contains(mouseX, mouseY)) { + return InteractionResult.FAIL; + } + } + } + } } + return InteractionResult.PASS; } @@ -81,18 +90,23 @@ public class ExclusionZonesImpl implements ExclusionZones { } private long currentHashCode(DisplayPanelLocation location) { - return areasHashCode(ScreenRegistry.getInstance().getOverlayBounds(location, Minecraft.getInstance().screen), getExclusionZones(Minecraft.getInstance().screen.getClass(), false)); + return areasHashCode(ScreenRegistry.getInstance().getOverlayBounds(location, Minecraft.getInstance().screen), + getExclusionZones(Minecraft.getInstance().screen.getClass(), false)); } @Override public List getExclusionZones(Class currentScreenClass, boolean sort) { List rectangles = Lists.newArrayList(); - for (Tuple, Float>, Supplier>> pair : list) { - if (pair.getA().getA().isAssignableFrom(currentScreenClass)) - rectangles.addAll(pair.getB().get()); + for (Map.Entry, Collection>>> collectionEntry : list.asMap().entrySet()) { + if (collectionEntry.getKey().isAssignableFrom(currentScreenClass)) { + for (Supplier> listSupplier : collectionEntry.getValue()) { + rectangles.addAll(listSupplier.get()); + } + } } - if (sort) + if (sort) { rectangles.sort(RECTANGLE_COMPARER); + } return rectangles; } @@ -103,7 +117,7 @@ public class ExclusionZonesImpl implements ExclusionZones { @Override public void register(Class screenClass, Supplier> supplier) { - list.add(new Tuple<>(new Tuple<>(screenClass, 0f), supplier)); + list.put(screenClass, supplier); } private long areasHashCode(Rectangle rectangle, List exclusionZones) { diff --git a/runtime/src/main/java/me/shedaniel/rei/impl/registry/CategoryRegistryImpl.java b/runtime/src/main/java/me/shedaniel/rei/impl/registry/CategoryRegistryImpl.java index a6742e5ca..4a60b92d5 100644 --- a/runtime/src/main/java/me/shedaniel/rei/impl/registry/CategoryRegistryImpl.java +++ b/runtime/src/main/java/me/shedaniel/rei/impl/registry/CategoryRegistryImpl.java @@ -40,8 +40,8 @@ import java.util.function.Consumer; @ApiStatus.Internal public class CategoryRegistryImpl implements CategoryRegistry, Reloadable { - private final Map> categories = new ConcurrentHashMap<>(); - private final Map>>> listeners = new ConcurrentHashMap<>(); + private final Map> categories = new LinkedHashMap<>(); + private final Map>>> listeners = new HashMap<>(); @Override public void acceptPlugin(REIPlugin plugin) { -- cgit