aboutsummaryrefslogtreecommitdiff
path: root/runtime/src/main/java
diff options
context:
space:
mode:
authorshedaniel <daniel@shedaniel.me>2021-06-27 16:38:33 +0800
committershedaniel <daniel@shedaniel.me>2021-06-27 16:38:33 +0800
commitc0c2bd8d259b9ccc55d2111d806220753b9d89bd (patch)
tree52059a5dd2bcc6320e750a48e1b1e4c22adebbca /runtime/src/main/java
parentf6b10e75179c8237cab172d757238d1404273187 (diff)
downloadRoughlyEnoughItems-c0c2bd8d259b9ccc55d2111d806220753b9d89bd.tar.gz
RoughlyEnoughItems-c0c2bd8d259b9ccc55d2111d806220753b9d89bd.tar.bz2
RoughlyEnoughItems-c0c2bd8d259b9ccc55d2111d806220753b9d89bd.zip
Fix #572 & add getDraggableAcceptingBounds
Diffstat (limited to 'runtime/src/main/java')
-rw-r--r--runtime/src/main/java/me/shedaniel/rei/RoughlyEnoughItemsCoreClient.java15
-rw-r--r--runtime/src/main/java/me/shedaniel/rei/impl/client/config/ConfigManagerImpl.java9
-rw-r--r--runtime/src/main/java/me/shedaniel/rei/impl/client/favorites/DelegatingFavoriteEntryProviderImpl.java10
-rw-r--r--runtime/src/main/java/me/shedaniel/rei/impl/client/favorites/FavoriteEntryTypeRegistryImpl.java12
-rw-r--r--runtime/src/main/java/me/shedaniel/rei/impl/client/gui/dragging/CurrentDraggingStack.java79
-rw-r--r--runtime/src/main/java/me/shedaniel/rei/impl/client/gui/widget/EntryWidget.java48
-rw-r--r--runtime/src/main/java/me/shedaniel/rei/impl/client/gui/widget/FavoritesListWidget.java70
-rw-r--r--runtime/src/main/java/me/shedaniel/rei/plugin/client/DefaultClientRuntimePlugin.java21
8 files changed, 197 insertions, 67 deletions
diff --git a/runtime/src/main/java/me/shedaniel/rei/RoughlyEnoughItemsCoreClient.java b/runtime/src/main/java/me/shedaniel/rei/RoughlyEnoughItemsCoreClient.java
index dfe241863..7cd3f0a34 100644
--- a/runtime/src/main/java/me/shedaniel/rei/RoughlyEnoughItemsCoreClient.java
+++ b/runtime/src/main/java/me/shedaniel/rei/RoughlyEnoughItemsCoreClient.java
@@ -24,6 +24,7 @@
package me.shedaniel.rei;
import com.google.common.collect.Lists;
+import com.mojang.serialization.DataResult;
import dev.architectury.event.EventResult;
import dev.architectury.event.events.client.ClientGuiEvent;
import dev.architectury.event.events.client.ClientRecipeUpdateEvent;
@@ -76,7 +77,6 @@ import net.minecraft.client.gui.components.ImageButton;
import net.minecraft.client.gui.screens.Screen;
import net.minecraft.client.gui.screens.inventory.AbstractContainerScreen;
import net.minecraft.client.gui.screens.inventory.CraftingScreen;
-import net.minecraft.client.gui.screens.inventory.tooltip.ClientTooltipComponent;
import net.minecraft.client.gui.screens.recipebook.GhostRecipe;
import net.minecraft.client.gui.screens.recipebook.RecipeBookComponent;
import net.minecraft.client.resources.language.I18n;
@@ -97,7 +97,6 @@ import org.jetbrains.annotations.Nullable;
import java.util.Collection;
import java.util.ConcurrentModificationException;
import java.util.List;
-import java.util.Objects;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
@@ -111,8 +110,8 @@ import java.util.stream.Stream;
public class RoughlyEnoughItemsCoreClient {
@ApiStatus.Experimental
public static boolean isLeftMousePressed = false;
- private static final ExecutorService RELOAD_PLUGINS = Executors.newSingleThreadScheduledExecutor(r -> {
- Thread thread = new Thread(r, "REI-ReloadPlugins");
+ private static final ExecutorService RELOAD_PLUGINS = Executors.newSingleThreadScheduledExecutor(task -> {
+ Thread thread = new Thread(task, "REI-ReloadPlugins");
thread.setDaemon(true);
return thread;
});
@@ -121,11 +120,13 @@ public class RoughlyEnoughItemsCoreClient {
InternalWidgets.attach();
EmptyEntryDefinition.EmptyRenderer emptyEntryRenderer = new EmptyEntryDefinition.EmptyRenderer();
ClientInternals.attachInstance((Supplier<EntryRenderer<?>>) () -> emptyEntryRenderer, "emptyEntryRenderer");
- ClientInternals.attachInstance((BiFunction<Supplier<FavoriteEntry>, Supplier<CompoundTag>, FavoriteEntry>) DelegatingFavoriteEntryProviderImpl::new, "delegateFavoriteEntry");
- ClientInternals.attachInstance((Function<CompoundTag, FavoriteEntry>) (object) -> {
+ ClientInternals.attachInstance((BiFunction<Supplier<DataResult<FavoriteEntry>>, Supplier<CompoundTag>, FavoriteEntry>) DelegatingFavoriteEntryProviderImpl::new, "delegateFavoriteEntry");
+ ClientInternals.attachInstance((Function<CompoundTag, DataResult<FavoriteEntry>>) (object) -> {
String type = object.getString(FavoriteEntry.TYPE_KEY);
ResourceLocation id = new ResourceLocation(type);
- return Objects.requireNonNull(Objects.requireNonNull(FavoriteEntryType.registry().get(id)).read(object));
+ FavoriteEntryType<FavoriteEntry> entryType = FavoriteEntryType.registry().get(id);
+ if (entryType == null) return DataResult.error("Unknown favorite type: " + id + ", json: " + object);
+ return entryType.readResult(object);
}, "favoriteEntryFromJson");
ClientInternals.attachInstance((BiFunction<@Nullable Point, Collection<Tooltip.Entry>, Tooltip>) QueuedTooltip::impl, "tooltipProvider");
ClientInternals.attachInstance((Function<Object, Tooltip.Entry>) QueuedTooltip.TooltipEntryImpl::new, "tooltipEntryProvider");
diff --git a/runtime/src/main/java/me/shedaniel/rei/impl/client/config/ConfigManagerImpl.java b/runtime/src/main/java/me/shedaniel/rei/impl/client/config/ConfigManagerImpl.java
index 2068523e8..c41c8754a 100644
--- a/runtime/src/main/java/me/shedaniel/rei/impl/client/config/ConfigManagerImpl.java
+++ b/runtime/src/main/java/me/shedaniel/rei/impl/client/config/ConfigManagerImpl.java
@@ -224,17 +224,12 @@ public class ConfigManagerImpl implements ConfigManager {
}
});
builder.registerDeserializer(Tag.class, FavoriteEntry.class, (value, marshaller) -> {
- try {
- return FavoriteEntry.delegate(() -> FavoriteEntry.read((CompoundTag) value), () -> (CompoundTag) value);
- } catch (Exception e) {
- e.printStackTrace();
- return null;
- }
+ return FavoriteEntry.readDelegated((CompoundTag) value);
});
builder.registerDeserializer(String.class, FavoriteEntry.class, (value, marshaller) -> {
try {
CompoundTag tag = TagParser.parseTag(value);
- return FavoriteEntry.delegate(() -> FavoriteEntry.read(tag), () -> tag);
+ return FavoriteEntry.readDelegated(tag);
} catch (Exception e) {
e.printStackTrace();
return null;
diff --git a/runtime/src/main/java/me/shedaniel/rei/impl/client/favorites/DelegatingFavoriteEntryProviderImpl.java b/runtime/src/main/java/me/shedaniel/rei/impl/client/favorites/DelegatingFavoriteEntryProviderImpl.java
index d58f7e6e4..6ff8497f3 100644
--- a/runtime/src/main/java/me/shedaniel/rei/impl/client/favorites/DelegatingFavoriteEntryProviderImpl.java
+++ b/runtime/src/main/java/me/shedaniel/rei/impl/client/favorites/DelegatingFavoriteEntryProviderImpl.java
@@ -23,6 +23,7 @@
package me.shedaniel.rei.impl.client.favorites;
+import com.mojang.serialization.DataResult;
import me.shedaniel.rei.api.client.favorites.FavoriteEntry;
import me.shedaniel.rei.api.client.favorites.FavoriteMenuEntry;
import me.shedaniel.rei.api.client.gui.Renderer;
@@ -36,11 +37,11 @@ import java.util.UUID;
import java.util.function.Supplier;
public class DelegatingFavoriteEntryProviderImpl extends FavoriteEntry {
- private final Supplier<FavoriteEntry> supplier;
+ private final Supplier<DataResult<FavoriteEntry>> supplier;
private final Supplier<CompoundTag> toJson;
private FavoriteEntry value = null;
- public DelegatingFavoriteEntryProviderImpl(Supplier<FavoriteEntry> supplier, Supplier<CompoundTag> toJson) {
+ public DelegatingFavoriteEntryProviderImpl(Supplier<DataResult<FavoriteEntry>> supplier, Supplier<CompoundTag> toJson) {
this.supplier = supplier;
this.toJson = toJson;
}
@@ -49,7 +50,8 @@ public class DelegatingFavoriteEntryProviderImpl extends FavoriteEntry {
public FavoriteEntry getUnwrapped() {
synchronized (this) {
if (this.value == null) {
- this.value = supplier.get();
+ DataResult<FavoriteEntry> result = supplier.get();
+ this.value = result.getOrThrow(false, error -> {});
}
}
return Objects.requireNonNull(value).getUnwrapped();
@@ -91,7 +93,7 @@ public class DelegatingFavoriteEntryProviderImpl extends FavoriteEntry {
@Override
public FavoriteEntry copy() {
- return FavoriteEntry.delegate(supplier, toJson);
+ return FavoriteEntry.delegateResult(supplier, toJson);
}
@Override
diff --git a/runtime/src/main/java/me/shedaniel/rei/impl/client/favorites/FavoriteEntryTypeRegistryImpl.java b/runtime/src/main/java/me/shedaniel/rei/impl/client/favorites/FavoriteEntryTypeRegistryImpl.java
index 3fc5511a3..f5b2aedfe 100644
--- a/runtime/src/main/java/me/shedaniel/rei/impl/client/favorites/FavoriteEntryTypeRegistryImpl.java
+++ b/runtime/src/main/java/me/shedaniel/rei/impl/client/favorites/FavoriteEntryTypeRegistryImpl.java
@@ -26,6 +26,8 @@ package me.shedaniel.rei.impl.client.favorites;
import com.google.common.collect.BiMap;
import com.google.common.collect.HashBiMap;
import com.google.common.collect.Maps;
+import me.shedaniel.rei.api.client.config.ConfigManager;
+import me.shedaniel.rei.api.client.config.ConfigObject;
import me.shedaniel.rei.api.client.favorites.FavoriteEntry;
import me.shedaniel.rei.api.client.favorites.FavoriteEntryType;
import me.shedaniel.rei.api.client.plugins.REIClientPlugin;
@@ -81,6 +83,16 @@ public class FavoriteEntryTypeRegistryImpl implements FavoriteEntryType.Registry
this.sections.clear();
}
+ @Override
+ public void endReload() {
+ if (ConfigObject.getInstance().isFavoritesEnabled()) {
+ List<FavoriteEntry> favorites = ConfigObject.getInstance().getFavoriteEntries();
+ favorites.removeIf(FavoriteEntry::isInvalid);
+
+ ConfigManager.getInstance().saveConfig();
+ }
+ }
+
private static class SectionImpl implements FavoriteEntryType.Section {
private final Component text;
private final List<FavoriteEntry> entries = new ArrayList<>();
diff --git a/runtime/src/main/java/me/shedaniel/rei/impl/client/gui/dragging/CurrentDraggingStack.java b/runtime/src/main/java/me/shedaniel/rei/impl/client/gui/dragging/CurrentDraggingStack.java
index 7aab6ac7c..742a5bc39 100644
--- a/runtime/src/main/java/me/shedaniel/rei/impl/client/gui/dragging/CurrentDraggingStack.java
+++ b/runtime/src/main/java/me/shedaniel/rei/impl/client/gui/dragging/CurrentDraggingStack.java
@@ -38,6 +38,7 @@ import me.shedaniel.rei.impl.client.gui.widget.LateRenderable;
import net.minecraft.client.Minecraft;
import net.minecraft.client.gui.components.events.GuiEventListener;
import net.minecraft.client.gui.screens.Screen;
+import net.minecraft.world.phys.shapes.VoxelShape;
import org.jetbrains.annotations.Nullable;
import java.util.*;
@@ -49,6 +50,7 @@ public class CurrentDraggingStack extends Widget implements LateRenderable, Drag
@Nullable
private DraggableEntry entry;
private final List<RenderBackEntry> backToOriginals = new ArrayList<>();
+ private final Set<ShapeBounds> bounds = new HashSet<>();
public void set(DraggableStackProvider<Screen> provider, DraggableStackVisitor<Screen> visitor) {
this.provider = provider;
@@ -57,6 +59,8 @@ public class CurrentDraggingStack extends Widget implements LateRenderable, Drag
@Override
public void render(PoseStack matrices, int mouseX, int mouseY, float delta) {
+ Integer hash = null;
+
if (entry != null) {
if (!entry.dragging) {
Point startPoint = entry.start;
@@ -69,6 +73,7 @@ public class CurrentDraggingStack extends Widget implements LateRenderable, Drag
entry.stack.drag();
}
}
+
if (!RoughlyEnoughItemsCoreClient.isLeftMousePressed) {
drop();
} else if (entry.dragging) {
@@ -76,6 +81,36 @@ public class CurrentDraggingStack extends Widget implements LateRenderable, Drag
matrices.translate(0, 0, 600);
entry.stack.render(matrices, new Rectangle(mouseX - 8, mouseY - 8, 16, 16), mouseX, mouseY, delta);
matrices.popPose();
+
+ VoxelShape shape = entry.getBoundsProvider().bounds();
+ ShapeBounds shapeBounds = new ShapeBounds(shape);
+ shapeBounds.alpha.setTo(60, 300);
+ bounds.add(shapeBounds);
+ hash = shapeBounds.hash;
+ }
+ }
+
+ for (ShapeBounds bound : bounds) {
+ if ((hash == null || hash != bound.hash) && bound.alpha.target() != 0) {
+ bound.alpha.setTo(0, 300);
+ }
+ }
+
+ {
+ Iterator<ShapeBounds> iterator = bounds.iterator();
+ while (iterator.hasNext()) {
+ ShapeBounds bounds = iterator.next();
+ bounds.update(delta);
+ if (bounds.alpha.target() == 0 && bounds.alpha.doubleValue() <= 2) {
+ iterator.remove();
+ } else {
+ bounds.shape.forAllBoxes((x1, y1, z1, x2, y2, z2) -> {
+ matrices.pushPose();
+ matrices.translate(0, 0, 500);
+ fillGradient(matrices, (int) x1, (int) y1, (int) x2, (int) y2, 0xfdff6b | (bounds.alpha.intValue() << 24), 0xfdff6b | (bounds.alpha.intValue() << 24));
+ matrices.popPose();
+ });
+ }
}
}
@@ -121,9 +156,8 @@ public class CurrentDraggingStack extends Widget implements LateRenderable, Drag
private boolean drop() {
if (entry != null && entry.dragging) {
- Optional<DraggableStackVisitor.Acceptor> acceptor = visitor.visitDraggedStack(this, entry.stack);
- entry.stack.release(acceptor.isPresent());
- acceptor.ifPresent(a -> a.accept(entry.stack));
+ boolean released = visitor.acceptDraggedStack(this, entry.stack);
+ entry.stack.release(released);
entry = null;
return true;
}
@@ -154,15 +188,52 @@ public class CurrentDraggingStack extends Widget implements LateRenderable, Drag
backToOriginals.add(new RenderBackEntry(stack, initialPosition, position));
}
- private static class DraggableEntry {
+ private class DraggableEntry {
private final DraggableStack stack;
private final Point start;
private boolean dragging = false;
+ private DraggableStackVisitor.BoundsProvider boundsProvider;
private DraggableEntry(DraggableStack stack, Point start) {
this.stack = stack;
this.start = start;
}
+
+ public DraggableStackVisitor.BoundsProvider getBoundsProvider() {
+ if (boundsProvider == null) {
+ boundsProvider = DraggableStackVisitor.BoundsProvider.concat(visitor.getDraggableAcceptingBounds(CurrentDraggingStack.this, stack).toList());
+ }
+
+ return boundsProvider;
+ }
+ }
+
+ private static class ShapeBounds {
+ private VoxelShape shape;
+ private Animator alpha;
+ private int hash;
+
+ public ShapeBounds(VoxelShape shape) {
+ this.shape = shape;
+ this.alpha = new Animator(0);
+ this.hash = shape.toAabbs().hashCode();
+ }
+
+ @Override
+ public boolean equals(Object o) {
+ if (this == o) return true;
+ if (!(o instanceof ShapeBounds shapeBounds)) return false;
+ return hash == shapeBounds.hash;
+ }
+
+ @Override
+ public int hashCode() {
+ return hash;
+ }
+
+ public void update(double delta) {
+ this.alpha.update(delta);
+ }
}
private static class RenderBackEntry {
diff --git a/runtime/src/main/java/me/shedaniel/rei/impl/client/gui/widget/EntryWidget.java b/runtime/src/main/java/me/shedaniel/rei/impl/client/gui/widget/EntryWidget.java
index 55bb8f98d..053186a50 100644
--- a/runtime/src/main/java/me/shedaniel/rei/impl/client/gui/widget/EntryWidget.java
+++ b/runtime/src/main/java/me/shedaniel/rei/impl/client/gui/widget/EntryWidget.java
@@ -383,17 +383,19 @@ public class EntryWidget extends Slot implements DraggableStackProviderWidget {
ModifierKeyCode keyCode = ConfigObject.getInstance().getFavoriteKeyCode();
if (keyCode.matchesMouse(button)) {
FavoriteEntry favoriteEntry = asFavoriteEntry();
- if (reverseFavoritesAction())
- ConfigObject.getInstance().getFavoriteEntries().remove(favoriteEntry);
- else {
- ConfigObject.getInstance().getFavoriteEntries().remove(favoriteEntry);
- ConfigObject.getInstance().getFavoriteEntries().add(favoriteEntry);
+ if (favoriteEntry != null) {
+ if (reverseFavoritesAction())
+ ConfigObject.getInstance().getFavoriteEntries().remove(favoriteEntry);
+ else {
+ ConfigObject.getInstance().getFavoriteEntries().remove(favoriteEntry);
+ ConfigObject.getInstance().getFavoriteEntries().add(favoriteEntry);
+ }
+ ConfigManager.getInstance().saveConfig();
+ FavoritesListWidget favoritesListWidget = ScreenOverlayImpl.getFavoritesListWidget();
+ if (favoritesListWidget != null)
+ favoritesListWidget.updateSearch();
+ return true;
}
- ConfigManager.getInstance().saveConfig();
- FavoritesListWidget favoritesListWidget = ScreenOverlayImpl.getFavoritesListWidget();
- if (favoritesListWidget != null)
- favoritesListWidget.updateSearch();
- return true;
}
}
if ((ConfigObject.getInstance().getRecipeKeybind().getType() != InputConstants.Type.MOUSE && button == 0) || ConfigObject.getInstance().getRecipeKeybind().matchesMouse(button))
@@ -405,8 +407,10 @@ public class EntryWidget extends Slot implements DraggableStackProviderWidget {
}
@ApiStatus.Internal
+ @Nullable
protected FavoriteEntry asFavoriteEntry() {
- return FavoriteEntry.fromEntryStack(getCurrentEntry().normalize());
+ FavoriteEntry entry = FavoriteEntry.fromEntryStack(getCurrentEntry().normalize());
+ return entry.isInvalid() ? null : entry;
}
@ApiStatus.Internal
@@ -432,17 +436,19 @@ public class EntryWidget extends Slot implements DraggableStackProviderWidget {
ModifierKeyCode keyCode = ConfigObject.getInstance().getFavoriteKeyCode();
if (keyCode.matchesKey(int_1, int_2)) {
FavoriteEntry favoriteEntry = asFavoriteEntry();
- if (reverseFavoritesAction())
- ConfigObject.getInstance().getFavoriteEntries().remove(favoriteEntry);
- else {
- ConfigObject.getInstance().getFavoriteEntries().remove(favoriteEntry);
- ConfigObject.getInstance().getFavoriteEntries().add(favoriteEntry);
+ if (favoriteEntry != null) {
+ if (reverseFavoritesAction())
+ ConfigObject.getInstance().getFavoriteEntries().remove(favoriteEntry);
+ else {
+ ConfigObject.getInstance().getFavoriteEntries().remove(favoriteEntry);
+ ConfigObject.getInstance().getFavoriteEntries().add(favoriteEntry);
+ }
+ ConfigManager.getInstance().saveConfig();
+ FavoritesListWidget favoritesListWidget = ScreenOverlayImpl.getFavoritesListWidget();
+ if (favoritesListWidget != null)
+ favoritesListWidget.updateSearch();
+ return true;
}
- ConfigManager.getInstance().saveConfig();
- FavoritesListWidget favoritesListWidget = ScreenOverlayImpl.getFavoritesListWidget();
- if (favoritesListWidget != null)
- favoritesListWidget.updateSearch();
- return true;
}
}
if (ConfigObject.getInstance().getRecipeKeybind().matchesKey(int_1, int_2))
diff --git a/runtime/src/main/java/me/shedaniel/rei/impl/client/gui/widget/FavoritesListWidget.java b/runtime/src/main/java/me/shedaniel/rei/impl/client/gui/widget/FavoritesListWidget.java
index e48af7699..7af03436f 100644
--- a/runtime/src/main/java/me/shedaniel/rei/impl/client/gui/widget/FavoritesListWidget.java
+++ b/runtime/src/main/java/me/shedaniel/rei/impl/client/gui/widget/FavoritesListWidget.java
@@ -51,6 +51,7 @@ import me.shedaniel.rei.api.client.gui.widgets.Widget;
import me.shedaniel.rei.api.client.gui.widgets.WidgetWithBounds;
import me.shedaniel.rei.api.client.overlay.OverlayListWidget;
import me.shedaniel.rei.api.client.overlay.ScreenOverlay;
+import me.shedaniel.rei.api.client.registry.screen.ScreenRegistry;
import me.shedaniel.rei.api.client.util.ClientEntryStacks;
import me.shedaniel.rei.api.common.entry.EntrySerializer;
import me.shedaniel.rei.api.common.entry.EntryStack;
@@ -70,6 +71,10 @@ import net.minecraft.network.chat.Component;
import net.minecraft.network.chat.TranslatableComponent;
import net.minecraft.util.Mth;
import net.minecraft.util.Tuple;
+import net.minecraft.util.Unit;
+import net.minecraft.world.phys.shapes.BooleanOp;
+import net.minecraft.world.phys.shapes.Shapes;
+import net.minecraft.world.phys.shapes.VoxelShape;
import org.jetbrains.annotations.ApiStatus;
import org.jetbrains.annotations.Nullable;
@@ -153,7 +158,7 @@ public class FavoritesListWidget extends WidgetWithBounds implements DraggableSt
if (innerBounds.contains(mouseX, mouseY)) {
for (Entry entry : entries.values()) {
if (entry.getWidget().containsMouse(mouseX, mouseY)) {
- return new FavoriteDraggableStack(entry, false);
+ return new FavoriteDraggableStack(entry, null);
}
}
}
@@ -164,7 +169,7 @@ public class FavoritesListWidget extends WidgetWithBounds implements DraggableSt
if (widget.containsMouse(mouseX, mouseY)) {
Entry entry = new Entry(widget.entry.copy(), entrySize());
entry.size.setAs(entrySize() * 100);
- return new FavoriteDraggableStack(entry, true);
+ return new FavoriteDraggableStack(entry, widget);
}
}
}
@@ -209,13 +214,13 @@ public class FavoritesListWidget extends WidgetWithBounds implements DraggableSt
private Entry entry;
private FavoriteEntry favoriteEntry;
private EntryStack<?> stack;
- private boolean showcase;
+ private WidgetWithBounds showcaseWidget;
- public FavoriteDraggableStack(Entry entry, boolean showcase) {
+ public FavoriteDraggableStack(Entry entry, WidgetWithBounds showcaseWidget) {
this.entry = entry;
this.favoriteEntry = entry.getEntry();
this.stack = ClientEntryStacks.of(favoriteEntry.getRenderer(false));
- this.showcase = showcase;
+ this.showcaseWidget = showcaseWidget;
}
@Override
@@ -225,7 +230,7 @@ public class FavoritesListWidget extends WidgetWithBounds implements DraggableSt
@Override
public void drag() {
- if (!showcase) {
+ if (showcaseWidget == null) {
entries.remove(entry.hashIgnoreAmount());
applyNewFavorites(CollectionUtils.map(entries.values(), Entry::getEntry));
}
@@ -234,28 +239,53 @@ public class FavoritesListWidget extends WidgetWithBounds implements DraggableSt
@Override
public void release(boolean accepted) {
if (!accepted) {
- drop(entry, this, favoriteEntry);
+ if (showcaseWidget != null) {
+ DraggingContext.getInstance().renderBackToPosition(this, DraggingContext.getInstance().getCurrentPosition(),
+ () -> new Point(showcaseWidget.getBounds().x, showcaseWidget.getBounds().y));
+ } else {
+ drop(entry, this, favoriteEntry);
+ }
}
}
}
- @Override
- public Optional<DraggableStackVisitor.Acceptor> visitDraggedStack(DraggingContext<Screen> context, DraggableStack stack) {
- if (innerBounds.contains(PointHelper.ofMouse())) {
- EntrySerializer<?> serializer = stack.getStack().getDefinition().getSerializer();
- if (stack instanceof FavoriteDraggableStack || (serializer.supportReading() && serializer.supportSaving())) {
- return Optional.of(this::acceptDraggedStack);
+ public Optional<Tuple<Entry, FavoriteEntry>> checkDraggedStacks(DraggingContext<Screen> context, DraggableStack stack) {
+ EntrySerializer<?> serializer = stack.getStack().getDefinition().getSerializer();
+ if (stack instanceof FavoriteDraggableStack || (serializer.supportReading() && serializer.supportSaving())) {
+ try {
+ FavoriteEntry favoriteEntry = stack instanceof FavoriteDraggableStack ? ((FavoriteDraggableStack) stack).favoriteEntry.copy()
+ : FavoriteEntry.fromEntryStack(stack.getStack().copy());
+ Entry entry = new Entry(favoriteEntry, entrySize());
+ entry.size.setAs(entrySize() * 100);
+ return Optional.of(new Tuple<>(entry, favoriteEntry));
+ } catch (Throwable ignored) {
}
}
return Optional.empty();
}
- private void acceptDraggedStack(DraggableStack stack) {
- FavoriteEntry favoriteEntry = stack instanceof FavoriteDraggableStack ? ((FavoriteDraggableStack) stack).favoriteEntry.copy()
- : FavoriteEntry.fromEntryStack(stack.getStack().copy());
- Entry entry = new Entry(favoriteEntry, entrySize());
- entry.size.setAs(entrySize() * 100);
- drop(entry, stack, favoriteEntry);
+ @Override
+ public boolean acceptDraggedStack(DraggingContext<Screen> context, DraggableStack stack) {
+ return checkDraggedStacks(context, stack)
+ .filter(tuple -> innerBounds.contains(context.getCurrentPosition()))
+ .map(tuple -> {
+ drop(tuple.getA(), stack, tuple.getB());
+ return Unit.INSTANCE;
+ }).isPresent();
+ }
+
+ @Override
+ public Stream<DraggableStackVisitor.BoundsProvider> getDraggableAcceptingBounds(DraggingContext<Screen> context, DraggableStack stack) {
+ return checkDraggedStacks(context, stack).isPresent() ? Stream.of(DraggableStackVisitor.BoundsProvider.ofShape(buildBounds())) : Stream.empty();
+ }
+
+ private VoxelShape buildBounds() {
+ Class<? extends Screen> screenClass = Minecraft.getInstance().screen.getClass();
+ VoxelShape shape = DraggableStackVisitor.BoundsProvider.fromRectangle(innerBounds);
+ for (Rectangle zone : ScreenRegistry.getInstance().exclusionZones().getExclusionZones(screenClass)) {
+ shape = Shapes.joinUnoptimized(shape, DraggableStackVisitor.BoundsProvider.fromRectangle(zone), BooleanOp.ONLY_FIRST);
+ }
+ return shape.optimize();
}
@Override
@@ -424,7 +454,7 @@ public class FavoritesListWidget extends WidgetWithBounds implements DraggableSt
public int getReleaseIndex() {
DraggingContext<?> context = DraggingContext.getInstance();
Point position = context.getCurrentPosition();
- if (context.isDraggingStack() && currentBounds.contains(position)) {
+ if (context.isDraggingStack() && currentBounds.contains(position) && checkDraggedStacks(context.cast(), context.getCurrentStack()).isPresent()) {
int entrySize = entrySize();
int width = innerBounds.width / entrySize;
int currentX = 0;
diff --git a/runtime/src/main/java/me/shedaniel/rei/plugin/client/DefaultClientRuntimePlugin.java b/runtime/src/main/java/me/shedaniel/rei/plugin/client/DefaultClientRuntimePlugin.java
index ec1ffd2d2..a87cfc722 100644
--- a/runtime/src/main/java/me/shedaniel/rei/plugin/client/DefaultClientRuntimePlugin.java
+++ b/runtime/src/main/java/me/shedaniel/rei/plugin/client/DefaultClientRuntimePlugin.java
@@ -25,6 +25,8 @@ package me.shedaniel.rei.plugin.client;
import com.mojang.blaze3d.systems.RenderSystem;
import com.mojang.blaze3d.vertex.PoseStack;
+import com.mojang.serialization.DataResult;
+import com.mojang.serialization.Lifecycle;
import dev.architectury.fluid.FluidStack;
import me.shedaniel.math.Point;
import me.shedaniel.math.Rectangle;
@@ -160,13 +162,24 @@ public class DefaultClientRuntimePlugin implements REIClientPlugin {
}
@Override
- public EntryStackFavoriteEntry read(CompoundTag object) {
- return new EntryStackFavoriteEntry(EntryStack.read(object.getCompound(key)));
+ public DataResult<EntryStackFavoriteEntry> readResult(CompoundTag object) {
+ EntryStack<?> stack;
+ try {
+ stack = EntryStack.read(object.getCompound(key));
+ } catch (Throwable throwable) {
+ return DataResult.error(throwable.getMessage());
+ }
+ return DataResult.success(new EntryStackFavoriteEntry(stack), Lifecycle.stable());
}
@Override
- public EntryStackFavoriteEntry fromArgs(Object... args) {
- return new EntryStackFavoriteEntry((EntryStack<?>) args[0]);
+ public DataResult<EntryStackFavoriteEntry> fromArgsResult(Object... args) {
+ if (args.length == 0) return DataResult.error("Cannot create EntryStackFavoriteEntry from empty args!");
+ if (!(args[0] instanceof EntryStack<?> stack))
+ return DataResult.error("Creation of EntryStackFavoriteEntry from args expected EntryStack as the first argument!");
+ if (!stack.supportSaving())
+ return DataResult.error("Creation of EntryStackFavoriteEntry from an unserializable stack!");
+ return DataResult.success(new EntryStackFavoriteEntry(stack), Lifecycle.stable());
}
@Override