-
-
Notifications
You must be signed in to change notification settings - Fork 2
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
f28ca5d
commit 048a631
Showing
8 changed files
with
347 additions
and
3 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
45 changes: 45 additions & 0 deletions
45
src/main/java/org/cyclops/integratedterminalscompat/modcompat/rei/RecipeInputSlotRei.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,45 @@ | ||
package org.cyclops.integratedterminalscompat.modcompat.rei; | ||
|
||
import com.google.common.collect.Lists; | ||
import me.shedaniel.rei.api.common.entry.EntryIngredient; | ||
import net.minecraft.world.item.ItemStack; | ||
import org.cyclops.integratedterminalscompat.modcompat.common.RecipeInputSlot; | ||
import org.jetbrains.annotations.NotNull; | ||
|
||
import java.util.Iterator; | ||
|
||
/** | ||
* @author rubensworks | ||
*/ | ||
public class RecipeInputSlotRei implements RecipeInputSlot { | ||
|
||
private final EntryIngredient ingredient; | ||
private final boolean input; | ||
private final int index; | ||
|
||
public RecipeInputSlotRei(EntryIngredient ingredient, boolean input, int index) { | ||
this.ingredient = ingredient; | ||
this.input = input; | ||
this.index = index; | ||
} | ||
|
||
public int getIndex() { | ||
return index; | ||
} | ||
|
||
@Override | ||
public boolean isEmpty() { | ||
return !this.input || this.ingredient.isEmpty(); | ||
} | ||
|
||
@NotNull | ||
@Override | ||
public Iterator<ItemStack> iterator() { | ||
if (!this.input) { | ||
return Lists.<ItemStack>newArrayList().iterator(); | ||
} | ||
return this.ingredient.stream() | ||
.map(i -> i.<ItemStack>castValue()) | ||
.iterator(); | ||
} | ||
} |
121 changes: 121 additions & 0 deletions
121
...ava/org/cyclops/integratedterminalscompat/modcompat/rei/ReiIntegratedTerminalsConfig.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,121 @@ | ||
package org.cyclops.integratedterminalscompat.modcompat.rei; | ||
|
||
import me.shedaniel.rei.api.client.REIRuntime; | ||
import me.shedaniel.rei.api.client.plugins.REIClientPlugin; | ||
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.comparison.ItemComparatorRegistry; | ||
import me.shedaniel.rei.forge.REIPluginClient; | ||
import net.minecraft.client.Minecraft; | ||
import net.minecraft.world.item.ItemStack; | ||
import net.minecraftforge.client.event.ScreenEvent; | ||
import net.minecraftforge.common.MinecraftForge; | ||
import net.minecraftforge.eventbus.api.SubscribeEvent; | ||
import org.cyclops.commoncapabilities.api.capability.itemhandler.ItemMatch; | ||
import org.cyclops.cyclopscore.client.gui.component.input.WidgetTextFieldExtended; | ||
import org.cyclops.integratedterminals.api.terminalstorage.event.TerminalStorageScreenSizeEvent; | ||
import org.cyclops.integratedterminals.api.terminalstorage.event.TerminalStorageTabClientLoadButtonsEvent; | ||
import org.cyclops.integratedterminals.api.terminalstorage.event.TerminalStorageTabClientSearchFieldUpdateEvent; | ||
import org.cyclops.integratedterminals.client.gui.container.ContainerScreenTerminalStorage; | ||
import org.cyclops.integratedterminalscompat.modcompat.common.button.TerminalButtonItemStackCraftingGridSearchSync; | ||
import org.cyclops.integratedterminalscompat.modcompat.rei.terminalstorage.TerminalStorageReiFocusedStackProvider; | ||
import org.cyclops.integratedterminalscompat.modcompat.rei.terminalstorage.TerminalStorageReiTransferHandler; | ||
|
||
/** | ||
* @author rubensworks | ||
*/ | ||
@REIPluginClient | ||
public class ReiIntegratedTerminalsConfig implements REIClientPlugin { | ||
|
||
private static ItemComparatorRegistry itemComparatorRegistry; | ||
|
||
public static int getItemStackMatchCondition(ItemStack itemStack) { | ||
// By default, REI ignores NBT when matching items, unless sub type info is set. | ||
|
||
// Ideally, we would have to do a plain item extraction, and filter the items that match the subtype string, | ||
// but just using the heuristic that the existence of sub type info implies NBT matching seems to work out so far. | ||
// So if we would run into problems with this, this filtering is what we'd need to do. | ||
|
||
return !itemComparatorRegistry.containsComparator(itemStack.getItem()) ? ItemMatch.ITEM : ItemMatch.ITEM | ItemMatch.TAG; | ||
} | ||
|
||
private boolean loaded = false; | ||
private boolean wasReiVisible = false; | ||
|
||
public ReiIntegratedTerminalsConfig() { | ||
MinecraftForge.EVENT_BUS.register(this); | ||
} | ||
|
||
@Override | ||
public void registerItemComparators(ItemComparatorRegistry registry) { | ||
itemComparatorRegistry = registry; | ||
} | ||
|
||
@Override | ||
public void registerScreens(ScreenRegistry registry) { | ||
loaded = true; | ||
registry.registerFocusedStack(new TerminalStorageReiFocusedStackProvider()); | ||
} | ||
|
||
@Override | ||
public void registerTransferHandlers(TransferHandlerRegistry registry) { | ||
registry.register(new TerminalStorageReiTransferHandler()); | ||
} | ||
|
||
@SubscribeEvent | ||
public void onTerminalStorageButtons(TerminalStorageTabClientLoadButtonsEvent event) { | ||
if (this.loaded && !event.getButtons().stream() | ||
.anyMatch((button) -> button instanceof TerminalButtonItemStackCraftingGridSearchSync)) { | ||
event.getButtons().add(new TerminalButtonItemStackCraftingGridSearchSync( | ||
"rei", event.getContainer().getGuiState(), event.getClientTab())); | ||
} | ||
} | ||
|
||
@SubscribeEvent | ||
public void onTerminalStorageScreenSize(TerminalStorageScreenSizeEvent event) { | ||
if (this.loaded) { | ||
try { | ||
boolean isOpen = REIRuntime.getInstance().getOverlay().isPresent(); | ||
boolean wasJeiVisiblePrevious = wasReiVisible; | ||
if (isOpen) { | ||
wasReiVisible = true; | ||
event.setWidth(event.getWidth() - 170); | ||
} else { | ||
wasReiVisible = false; | ||
} | ||
|
||
// Re-init screen if JEI was just made (in)visible | ||
if (wasJeiVisiblePrevious != wasReiVisible) { | ||
((ContainerScreenTerminalStorage) Minecraft.getInstance().screen).init(); | ||
} | ||
} catch (NoClassDefFoundError | ClassCastException e) { | ||
// Do nothing when we detect some JEI API issues | ||
} | ||
} | ||
} | ||
|
||
@SubscribeEvent | ||
public void onSearchFieldUpdated(TerminalStorageTabClientSearchFieldUpdateEvent event) { | ||
// Copy the terminal search box contents into the JEI search box. | ||
if (REIRuntime.getInstance().getOverlay().isPresent() && TerminalButtonItemStackCraftingGridSearchSync.isSearchSynced(event.getClientTab())) { | ||
REIRuntime.getInstance().getSearchTextField().setText(event.getSearchString() + ""); | ||
} | ||
} | ||
|
||
@SubscribeEvent | ||
public void onKeyTyped(ScreenEvent.KeyReleased.Post event) { | ||
// Copy the JEI search box contents into the terminal search box. | ||
if (event.getScreen() instanceof ContainerScreenTerminalStorage) { | ||
ContainerScreenTerminalStorage<?, ?> gui = ((ContainerScreenTerminalStorage<?, ?>) event.getScreen()); | ||
if (REIRuntime.getInstance().getOverlay().isPresent() && REIRuntime.getInstance().getSearchTextField().isFocused()) { | ||
gui.getSelectedClientTab().ifPresent(tab -> { | ||
if (TerminalButtonItemStackCraftingGridSearchSync.isSearchSynced(tab)) { | ||
WidgetTextFieldExtended fieldSearch = gui.getFieldSearch(); | ||
fieldSearch.setValue(REIRuntime.getInstance().getSearchTextField().getText()); | ||
tab.setInstanceFilter(gui.getMenu().getSelectedChannel(), fieldSearch.getValue() + ""); | ||
} | ||
}); | ||
} | ||
} | ||
} | ||
} |
45 changes: 45 additions & 0 deletions
45
...terminalscompat/modcompat/rei/terminalstorage/TerminalStorageReiFocusedStackProvider.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,45 @@ | ||
package org.cyclops.integratedterminalscompat.modcompat.rei.terminalstorage; | ||
|
||
import dev.architectury.event.CompoundEventResult; | ||
import me.shedaniel.math.Point; | ||
import me.shedaniel.rei.api.client.registry.screen.FocusedStackProvider; | ||
import me.shedaniel.rei.api.common.entry.EntryStack; | ||
import me.shedaniel.rei.api.common.util.EntryStacks; | ||
import net.minecraft.client.gui.screens.Screen; | ||
import net.minecraft.world.item.ItemStack; | ||
import net.minecraftforge.fluids.FluidStack; | ||
import org.cyclops.integratedterminals.client.gui.container.ContainerScreenTerminalStorage; | ||
import org.cyclops.integratedterminals.core.terminalstorage.TerminalStorageTabIngredientComponentClient; | ||
|
||
import java.util.Optional; | ||
|
||
/** | ||
* @author rubensworks | ||
*/ | ||
public class TerminalStorageReiFocusedStackProvider implements FocusedStackProvider { | ||
@Override | ||
public CompoundEventResult<EntryStack<?>> provide(Screen screen, Point point) { | ||
if (screen instanceof ContainerScreenTerminalStorage containerScreen) { | ||
return createClickableIngredient(containerScreen, point.x, point.y); | ||
} | ||
return CompoundEventResult.pass(); | ||
} | ||
|
||
private <T> CompoundEventResult<EntryStack<?>> createClickableIngredient( | ||
ContainerScreenTerminalStorage<T, ?> containerScreen, int mouseX, int mouseY) { | ||
int slotIndex = containerScreen.getStorageSlotIndexAtPosition(mouseX, mouseY); | ||
@SuppressWarnings("unchecked") // Cast is safe due to filter | ||
Optional<TerminalStorageTabIngredientComponentClient<T, ?>> tabOptional = containerScreen.getSelectedClientTab() | ||
.filter(TerminalStorageTabIngredientComponentClient.class::isInstance) | ||
.map(TerminalStorageTabIngredientComponentClient.class::cast); | ||
if(slotIndex >= 0 && tabOptional.isPresent()) { | ||
TerminalStorageTabIngredientComponentClient<T, ?> tab = tabOptional.get(); | ||
int channel = containerScreen.getMenu().getSelectedChannel(); | ||
Optional<T> instanceOptional = tab.getSlotInstance(channel, slotIndex); | ||
return instanceOptional | ||
.map(instance -> CompoundEventResult.interruptTrue(instance instanceof ItemStack itemStack ? EntryStacks.of(itemStack) : (instance instanceof FluidStack fluidStack ? EntryStacks.of(fluidStack.getFluid(), fluidStack.getAmount()) : EntryStack.empty()))) | ||
.orElse(CompoundEventResult.pass()); | ||
} | ||
return CompoundEventResult.pass(); | ||
} | ||
} |
120 changes: 120 additions & 0 deletions
120
...ratedterminalscompat/modcompat/rei/terminalstorage/TerminalStorageReiTransferHandler.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,120 @@ | ||
package org.cyclops.integratedterminalscompat.modcompat.rei.terminalstorage; | ||
|
||
import com.google.common.collect.Lists; | ||
import me.shedaniel.math.Rectangle; | ||
import me.shedaniel.rei.api.client.gui.widgets.Slot; | ||
import me.shedaniel.rei.api.client.gui.widgets.Widget; | ||
import me.shedaniel.rei.api.client.registry.transfer.TransferHandler; | ||
import me.shedaniel.rei.api.common.entry.EntryIngredient; | ||
import me.shedaniel.rei.plugin.common.BuiltinPlugin; | ||
import me.shedaniel.rei.plugin.common.displays.crafting.DefaultCraftingDisplay; | ||
import net.minecraft.client.gui.GuiComponent; | ||
import net.minecraft.network.chat.Component; | ||
import org.cyclops.integratedterminals.api.terminalstorage.ITerminalStorageTabCommon; | ||
import org.cyclops.integratedterminals.core.terminalstorage.TerminalStorageTabIngredientComponentClient; | ||
import org.cyclops.integratedterminals.core.terminalstorage.TerminalStorageTabIngredientComponentItemStackCrafting; | ||
import org.cyclops.integratedterminals.core.terminalstorage.TerminalStorageTabIngredientComponentItemStackCraftingCommon; | ||
import org.cyclops.integratedterminals.inventory.container.ContainerTerminalStorageBase; | ||
import org.cyclops.integratedterminalscompat.modcompat.common.RecipeTransferHelpers; | ||
import org.cyclops.integratedterminalscompat.modcompat.common.RecipeTransferResult; | ||
import org.cyclops.integratedterminalscompat.modcompat.rei.RecipeInputSlotRei; | ||
import org.cyclops.integratedterminalscompat.modcompat.rei.ReiIntegratedTerminalsConfig; | ||
|
||
import java.util.Collection; | ||
import java.util.Objects; | ||
|
||
/** | ||
* @author rubensworks | ||
*/ | ||
public class TerminalStorageReiTransferHandler implements TransferHandler { | ||
|
||
private int previousChangeId; | ||
|
||
@Override | ||
public Result handle(Context context) { | ||
if (context.getDisplay().getCategoryIdentifier().equals(BuiltinPlugin.CRAFTING) && | ||
context.getDisplay() instanceof DefaultCraftingDisplay<?> displayCrafting && | ||
context.getMenu() instanceof ContainerTerminalStorageBase<?> container && | ||
Objects.equals(container.getSelectedTab(), TerminalStorageTabIngredientComponentItemStackCrafting.NAME.toString())) { | ||
ITerminalStorageTabCommon tabCommon = container.getTabCommon(container.getSelectedTab()); | ||
TerminalStorageTabIngredientComponentItemStackCraftingCommon tabCommonCrafting = | ||
(TerminalStorageTabIngredientComponentItemStackCraftingCommon) tabCommon; | ||
|
||
if (context.isActuallyCrafting()) { | ||
RecipeTransferHelpers.transferRecipe( | ||
container, | ||
getRecipeInputSlots(displayCrafting), | ||
context.getMinecraft().player, | ||
tabCommonCrafting, | ||
ReiIntegratedTerminalsConfig::getItemStackMatchCondition, | ||
context.isStackedCrafting() | ||
); | ||
return Result.createSuccessful().blocksFurtherHandling(); | ||
} else { | ||
TerminalStorageTabIngredientComponentClient tabClient = (TerminalStorageTabIngredientComponentClient) | ||
container.getTabClient(container.getSelectedTab()); | ||
return RecipeTransferHelpers.getMissingItems( | ||
displayCrafting.getOptionalRecipe().orElse(null), | ||
container, | ||
getRecipeInputSlots(displayCrafting), | ||
context.getMinecraft().player, | ||
tabCommonCrafting, | ||
tabClient, | ||
ReiIntegratedTerminalsConfig::getItemStackMatchCondition, | ||
() -> previousChangeId, | ||
id -> previousChangeId = id | ||
).map(transferResult -> Result.createSuccessful() | ||
.color(transferResult.getButtonHighlightColor()) | ||
.tooltip(transferResult.getMessage().stream().reduce(Component.empty(), (c1, c2) -> c1.copy().append("\n").append(c2))) | ||
.renderer((poseStack, mouseX, mouseY, v, widgets, rectangle, display) -> { | ||
int index = 0; | ||
for (Widget widget : widgets) { | ||
if (widget instanceof Slot widgetSlot && widgetSlot.getNoticeMark() == Slot.INPUT) { | ||
// Determine if this slot requires any highlighting | ||
int color = -1; | ||
for (RecipeInputSlotRei slot : transferResult.getSlotsMissing()) { | ||
if (slot.getIndex() == index) { | ||
color = RecipeTransferResult.SLOT_COLOR_MISSING; | ||
break; | ||
} | ||
} | ||
for (RecipeInputSlotRei slot : transferResult.getSlotsCraftable()) { | ||
if (slot.getIndex() == index) { | ||
color = RecipeTransferResult.SLOT_COLOR_CRAFTABLE; | ||
break; | ||
} | ||
} | ||
|
||
// Draw the highlight | ||
if (color != -1) { | ||
Rectangle bounds = widgetSlot.getInnerBounds(); | ||
poseStack.pushPose(); | ||
poseStack.translate(0, 0, 20); | ||
GuiComponent.fill(poseStack, bounds.x, bounds.y, bounds.getMaxX(), bounds.getMaxY(), color); | ||
poseStack.popPose(); | ||
} | ||
|
||
index++; | ||
} | ||
} | ||
|
||
}) | ||
.blocksFurtherHandling()) | ||
.orElse(Result.createSuccessful().blocksFurtherHandling()); | ||
} | ||
} | ||
return Result.createNotApplicable(); | ||
} | ||
|
||
private Collection<RecipeInputSlotRei> getRecipeInputSlots(DefaultCraftingDisplay<?> context) { | ||
Collection<RecipeInputSlotRei> recipeInputSlots = Lists.newArrayList(); | ||
for (EntryIngredient outputEntry : context.getOutputEntries()) { | ||
recipeInputSlots.add(new RecipeInputSlotRei(outputEntry, false, 0)); | ||
} | ||
int i = 0; | ||
for (EntryIngredient outputEntry : context.getOrganisedInputEntries(3, 3)) { | ||
recipeInputSlots.add(new RecipeInputSlotRei(outputEntry, true, i++)); | ||
} | ||
return recipeInputSlots; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters