Skip to content

Commit

Permalink
Merge pull request #417 from refinedmods/feat/GH-177/ghost-ingredients
Browse files Browse the repository at this point in the history
feat: ghost ingredients
  • Loading branch information
raoulvdberge authored Aug 19, 2023
2 parents 58be4af + a61257a commit 5e9dde0
Show file tree
Hide file tree
Showing 37 changed files with 612 additions and 15 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
### Added

- Support for JEI/REI exclusion zones.
- Support for REI ghost ingredient dragging.

## [2.0.0-milestone.2.13] - 2023-08-18

Expand Down
Original file line number Diff line number Diff line change
@@ -1,12 +1,14 @@
package com.refinedmods.refinedstorage2.platform.api.integration.recipemod;

import com.refinedmods.refinedstorage2.api.storage.ResourceTemplate;

import java.util.Optional;

import org.apiguardian.api.API;

@API(status = API.Status.STABLE, since = "2.0.0-milestone.2.5")
public interface IngredientConverter {
Optional<Object> convertToResource(Object ingredient);
Optional<ResourceTemplate<?>> convertToResource(Object ingredient);

Optional<Object> convertToIngredient(Object resource);
}
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,8 @@ public interface ResourceContainer {

<T> long getMaxAmount(ResourceAmountTemplate<T> resourceAmount);

<T> boolean isValid(T resource);

void remove(int index);

int size();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,4 +8,6 @@
@API(status = API.Status.STABLE, since = "2.0.0-milestone.2.13")
public interface ResourceFactory<T> {
Optional<ResourceAmountTemplate<T>> create(ItemStack stack);

boolean isValid(Object resource);
}
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,8 @@ public interface Platform {

Optional<ResourceAmount<FluidResource>> convertToFluid(ItemStack stack);

Optional<FluidResource> convertJeiIngredientToFluid(Object ingredient);

Optional<ItemStack> convertToBucket(FluidResource fluidResource);

EnergyStorage createEnergyStorage(ControllerType controllerType, Runnable listener);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -127,6 +127,11 @@ public Optional<ResourceAmount<FluidResource>> convertToFluid(final ItemStack st
return ensureLoaded().convertToFluid(stack);
}

@Override
public Optional<FluidResource> convertJeiIngredientToFluid(final Object ingredient) {
return ensureLoaded().convertJeiIngredientToFluid(ingredient);
}

@Override
public Optional<ItemStack> convertToBucket(final FluidResource fluidResource) {
return ensureLoaded().convertToBucket(fluidResource);
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package com.refinedmods.refinedstorage2.platform.common.containermenu;

import com.refinedmods.refinedstorage2.platform.api.resource.ResourceAmountTemplate;
import com.refinedmods.refinedstorage2.platform.api.storage.channel.PlatformStorageChannelType;
import com.refinedmods.refinedstorage2.platform.common.Platform;
import com.refinedmods.refinedstorage2.platform.common.containermenu.slot.ResourceSlot;

Expand Down Expand Up @@ -51,6 +52,13 @@ public <T> void handleResourceSlotUpdate(final int slotIndex,
getResourceSlot(slotIndex).ifPresent(slot -> slot.change(resourceAmount));
}


public <T> void handleResourceFilterSlotUpdate(final int slotIndex,
final PlatformStorageChannelType<T> storageChannelType,
final T resource) {
getResourceSlot(slotIndex).ifPresent(slot -> slot.setFilter(storageChannelType, resource));
}

public void handleResourceSlotChange(final int slotIndex, final boolean tryAlternatives) {
getResourceSlot(slotIndex).ifPresent(slot -> slot.change(getCarried(), tryAlternatives));
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
import com.refinedmods.refinedstorage2.platform.api.resource.ResourceContainer;
import com.refinedmods.refinedstorage2.platform.api.resource.ResourceContainerType;
import com.refinedmods.refinedstorage2.platform.api.resource.ResourceFactory;
import com.refinedmods.refinedstorage2.platform.api.storage.channel.PlatformStorageChannelType;
import com.refinedmods.refinedstorage2.platform.common.Platform;

import java.util.Objects;
Expand Down Expand Up @@ -73,6 +74,11 @@ public boolean shouldRenderAmount() {
|| resourceContainer.getType() == ResourceContainerType.CONTAINER;
}

public boolean isFilter() {
return resourceContainer.getType() == ResourceContainerType.FILTER
|| resourceContainer.getType() == ResourceContainerType.FILTER_WITH_AMOUNT;
}

public boolean canModifyAmount() {
return resourceContainer.getType() == ResourceContainerType.FILTER_WITH_AMOUNT;
}
Expand Down Expand Up @@ -106,6 +112,21 @@ public <T> void change(@Nullable final ResourceAmountTemplate<T> instance) {
}
}

public <T> void setFilter(final PlatformStorageChannelType<T> storageChannelType, final T resource) {
if (!isFilter() || !isValid(resource)) {
return;
}
resourceContainer.set(getContainerSlot(), new ResourceAmountTemplate<>(
resource,
storageChannelType.normalizeAmount(1D),
storageChannelType
));
}

public <T> boolean isValid(final T resource) {
return resourceContainer.isValid(resource);
}

public boolean changeIfEmpty(final ItemStack stack) {
if (!isEmpty()) {
return false;
Expand All @@ -115,6 +136,9 @@ public boolean changeIfEmpty(final ItemStack stack) {
}

public void changeAmount(final long amount) {
if (resourceContainer.getType() != ResourceContainerType.FILTER_WITH_AMOUNT) {
return;
}
resourceContainer.setAmount(getContainerSlot(), amount);
}

Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package com.refinedmods.refinedstorage2.platform.common.integration.recipemod;

import com.refinedmods.refinedstorage2.api.storage.ResourceTemplate;
import com.refinedmods.refinedstorage2.platform.api.integration.recipemod.IngredientConverter;

import java.util.Collection;
Expand All @@ -10,17 +11,17 @@ public class CompositeIngredientConverter implements IngredientConverter {
private final Collection<IngredientConverter> converters = new HashSet<>();

@Override
public Optional<Object> convertToResource(final Object ingredient) {
public Optional<ResourceTemplate<?>> convertToResource(final Object ingredient) {
return converters.stream()
.flatMap(converter -> converter.convertToResource(ingredient).stream())
.findFirst();
.flatMap(converter -> converter.convertToResource(ingredient).stream())
.findFirst();
}

@Override
public Optional<Object> convertToIngredient(final Object resource) {
return converters.stream()
.flatMap(converter -> converter.convertToIngredient(resource).stream())
.findFirst();
.flatMap(converter -> converter.convertToIngredient(resource).stream())
.findFirst();
}

public void addConverter(final IngredientConverter converter) {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
package com.refinedmods.refinedstorage2.platform.common.integration.recipemod.jei;

import com.refinedmods.refinedstorage2.api.storage.ResourceTemplate;
import com.refinedmods.refinedstorage2.platform.api.integration.recipemod.IngredientConverter;
import com.refinedmods.refinedstorage2.platform.api.storage.channel.PlatformStorageChannelType;
import com.refinedmods.refinedstorage2.platform.common.Platform;
import com.refinedmods.refinedstorage2.platform.common.containermenu.AbstractResourceContainerMenu;
import com.refinedmods.refinedstorage2.platform.common.containermenu.slot.ResourceSlot;
import com.refinedmods.refinedstorage2.platform.common.screen.AbstractBaseScreen;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

import mezz.jei.api.gui.handlers.IGhostIngredientHandler;
import mezz.jei.api.ingredients.ITypedIngredient;
import net.minecraft.client.renderer.Rect2i;

@SuppressWarnings("rawtypes")
public class GhostIngredientHandler implements IGhostIngredientHandler<AbstractBaseScreen> {
private final IngredientConverter ingredientConverter;

public GhostIngredientHandler(final IngredientConverter ingredientConverter) {
this.ingredientConverter = ingredientConverter;
}

@Override
public <I> List<Target<I>> getTargetsTyped(final AbstractBaseScreen screen,
final ITypedIngredient<I> ingredient,
final boolean doStart) {
if (screen.getMenu() instanceof AbstractResourceContainerMenu menu) {
return getTargets(screen, ingredient.getIngredient(), menu);
}
return Collections.emptyList();
}

private <I> List<Target<I>> getTargets(final AbstractBaseScreen screen,
final I ingredient,
final AbstractResourceContainerMenu menu) {
final List<Target<I>> targets = new ArrayList<>();
ingredientConverter.convertToResource(ingredient).ifPresent(resource -> {
for (final ResourceSlot slot : menu.getResourceSlots()) {
if (slot.isFilter() && slot.isValid(resource.resource())) {
final Rect2i bounds = getBounds(screen, slot);
targets.add(new TargetImpl<>(bounds, slot.index));
}
}
});
return targets;
}

private Rect2i getBounds(final AbstractBaseScreen screen, final ResourceSlot slot) {
return new Rect2i(screen.getLeftPos() + slot.x, screen.getTopPos() + slot.y, 17, 17);
}

@Override
public void onComplete() {
// no op
}

private class TargetImpl<I> implements Target<I> {
private final Rect2i area;
private final int slotIndex;

TargetImpl(final Rect2i area, final int slotIndex) {
this.area = area;
this.slotIndex = slotIndex;
}

@Override
public Rect2i getArea() {
return area;
}

@Override
public void accept(final I ingredient) {
ingredientConverter.convertToResource(ingredient).ifPresent(this::accept);
}

private <T> void accept(final ResourceTemplate<T> resource) {
Platform.INSTANCE.getClientToServerCommunications().sendResourceFilterSlotChange(
(PlatformStorageChannelType<T>) resource.storageChannelType(),
resource.resource(),
slotIndex
);
}
}
}

Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package com.refinedmods.refinedstorage2.platform.common.integration.recipemod.jei;

import com.refinedmods.refinedstorage2.api.storage.ResourceTemplate;
import com.refinedmods.refinedstorage2.platform.api.integration.recipemod.IngredientConverter;
import com.refinedmods.refinedstorage2.platform.common.internal.grid.view.FluidGridResource;
import com.refinedmods.refinedstorage2.platform.common.internal.grid.view.ItemGridResource;
Expand All @@ -16,7 +17,7 @@ public GridResourceIngredientConverter(final IPlatformFluidHelper<?> fluidHelper
}

@Override
public Optional<Object> convertToResource(final Object ingredient) {
public Optional<ResourceTemplate<?>> convertToResource(final Object ingredient) {
return Optional.empty();
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,7 @@ public void registerGuiHandlers(final IGuiHandlerRegistration registration) {
AbstractBaseScreen.class,
new ExclusionZonesGuiContainerHandler()
);
registration.addGhostIngredientHandler(AbstractBaseScreen.class, new GhostIngredientHandler(converter));
}

@Nullable
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,13 @@
import com.refinedmods.refinedstorage2.platform.api.integration.recipemod.IngredientConverter;
import com.refinedmods.refinedstorage2.platform.api.resource.FluidResource;
import com.refinedmods.refinedstorage2.platform.api.resource.ItemResource;
import com.refinedmods.refinedstorage2.platform.common.Platform;
import com.refinedmods.refinedstorage2.platform.common.internal.storage.channel.StorageChannelTypes;

import java.util.Optional;

import mezz.jei.api.helpers.IPlatformFluidHelper;
import net.minecraft.world.item.ItemStack;

public class ResourceIngredientConverter implements IngredientConverter {
private final IPlatformFluidHelper<?> fluidHelper;
Expand All @@ -17,7 +20,20 @@ public ResourceIngredientConverter(final IPlatformFluidHelper<?> fluidHelper) {
}

@Override
public Optional<Object> convertToResource(final Object ingredient) {
public Optional<ResourceTemplate<?>> convertToResource(final Object ingredient) {
final var fluid = Platform.INSTANCE.convertJeiIngredientToFluid(ingredient);
if (fluid.isPresent()) {
return fluid.map(fluidResource -> new ResourceTemplate<>(
fluidResource,
StorageChannelTypes.FLUID
));
}
if (ingredient instanceof ItemStack itemStack) {
return Optional.of(new ResourceTemplate<>(
ItemResource.ofItemStack(itemStack),
StorageChannelTypes.ITEM
));
}
return Optional.empty();
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,4 +19,9 @@ public Optional<ResourceAmountTemplate<FluidResource>> create(final ItemStack st
StorageChannelTypes.FLUID
));
}

@Override
public boolean isValid(final Object resource) {
return resource instanceof FluidResource;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -21,4 +21,9 @@ public Optional<ResourceAmountTemplate<ItemResource>> create(final ItemStack sta
StorageChannelTypes.ITEM
));
}

@Override
public boolean isValid(final Object resource) {
return resource instanceof ItemResource;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,19 @@ private <T> void setSilently(final int index, final ResourceAmountTemplate<T> re
slots[index] = resourceAmount;
}

@Override
public <T> boolean isValid(final T resource) {
if (primaryResourceFactory.isValid(resource)) {
return true;
}
for (final ResourceFactory<?> resourceFactory : alternativeResourceFactories) {
if (resourceFactory.isValid(resource)) {
return true;
}
}
return false;
}

@Override
public long getAmount(final int index) {
final ResourceAmountTemplate<?> resourceAmount = slots[index];
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,8 @@ <T> void sendGridScroll(PlatformStorageChannelType<T> storageChannelType,

void sendResourceSlotChange(int slotIndex, boolean tryAlternatives);

<T> void sendResourceFilterSlotChange(PlatformStorageChannelType<T> storageChannelType, T resource, int slotIndex);

void sendResourceSlotAmountChange(int slotIndex, long amount);

void sendSingleAmountChange(double amount);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -298,4 +298,12 @@ public ResourceTemplate<?> getHoveredResource() {
? resourceSlot.getResourceAmount().getResourceTemplate()
: null;
}

public int getLeftPos() {
return leftPos;
}

public int getTopPos() {
return topPos;
}
}
1 change: 1 addition & 0 deletions refinedstorage2-platform-fabric/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,7 @@ dependencies {
modRuntimeOnly fabric.rei.impl

modCompileOnly common.jei.api
modCompileOnly fabric.jei.api
// modRuntimeOnly fabric.jei.impl

modRuntimeOnly fabric.wthit
Expand Down
Loading

0 comments on commit 5e9dde0

Please sign in to comment.