Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
42 changes: 21 additions & 21 deletions dependencies.gradle
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
dependencies {

api("com.github.GTNewHorizons:GTNHLib:0.11.48:dev")
implementation("com.github.GTNewHorizons:GTNHExtLib:1.0.4:dev")
api("com.github.GTNewHorizons:GTNHLib:0.11.52:dev")
implementation("com.github.GTNewHorizons:GTNHExtLib:1.0.5:dev")
implementation("io.github.legacymoddingmc:unimixins:0.3.1:dev")

shadowImplementation("org.yaml:snakeyaml:1.33") { transitive = false }
Expand All @@ -18,41 +18,41 @@ dependencies {
shadowImplementation("org.eclipse.elk:org.eclipse.elk.alg.layered:0.11.0")
shadowImplementation("org.eclipse.xtext:org.eclipse.xtext.xbase.lib:2.36.0")

devOnlyNonPublishable("com.github.GTNewHorizons:StructureLib:1.4.43:dev")
devOnlyNonPublishable("com.github.GTNewHorizons:GT5-Unofficial:5.09.54.194:dev")
devOnlyNonPublishable("com.github.GTNewHorizons:NotEnoughItems:2.8.140-GTNH:dev")
devOnlyNonPublishable("com.github.GTNewHorizons:Applied-Energistics-2-Unofficial:rv3-beta-1061-GTNH:dev")
devOnlyNonPublishable("com.github.GTNewHorizons:StructureLib:1.4.45:dev")
devOnlyNonPublishable("com.github.GTNewHorizons:GT5-Unofficial:5.09.54.205:dev")
devOnlyNonPublishable("com.github.GTNewHorizons:NotEnoughItems:2.8.155-GTNH:dev")
devOnlyNonPublishable("com.github.GTNewHorizons:Applied-Energistics-2-Unofficial:rv3-beta-1080-GTNH:dev")
devOnlyNonPublishable("com.github.GTNewHorizons:CarpentersBlocks:3.7.3-GTNH:dev")
devOnlyNonPublishable("com.github.GTNewHorizons:ForgeMultipart:1.7.14:dev")
devOnlyNonPublishable("com.github.GTNewHorizons:ForgeMultipart:1.7.16:dev")
devOnlyNonPublishable("com.github.GTNewHorizons:WirelessRedstone-CBE:1.7.12:dev")
devOnlyNonPublishable("com.github.GTNewHorizons:Railcraft:9.17.31:dev")
devOnlyNonPublishable("com.github.GTNewHorizons:EnhancedLootBags:1.3.4:dev")
devOnlyNonPublishable("com.github.GTNewHorizons:BetterQuesting:3.8.88-GTNH:dev")
devOnlyNonPublishable("com.github.GTNewHorizons:Angelica:2.2.13:dev")
devOnlyNonPublishable("com.github.GTNewHorizons:TX-Loader:1.9:dev")
devOnlyNonPublishable("com.github.GTNewHorizons:EnhancedLootBags:1.3.5:dev")
devOnlyNonPublishable("com.github.GTNewHorizons:BetterQuesting:3.8.89-GTNH:dev")
devOnlyNonPublishable("com.github.GTNewHorizons:Angelica:2.2.28:dev")
devOnlyNonPublishable("com.github.GTNewHorizons:TX-Loader:1.9.1:dev")
devOnlyNonPublishable("curse.maven:cofh-core-69162:2388751")

runtimeOnlyNonPublishable("com.github.GTNewHorizons:Baubles-Expanded:2.2.23-GTNH:dev")
runtimeOnlyNonPublishable("com.github.GTNewHorizons:Botania:1.13.36-GTNH:dev")
runtimeOnlyNonPublishable("com.github.GTNewHorizons:Baubles-Expanded:2.2.25-GTNH:dev")
runtimeOnlyNonPublishable("com.github.GTNewHorizons:Botania:1.13.37-GTNH:dev")
runtimeOnlyNonPublishable("com.github.GTNewHorizons:Botanic-horizons:1.12.10-GTNH:dev")
compileOnlyApi("com.github.GTNewHorizons:BlockRenderer6343:1.4.23:dev") { transitive = false }
runtimeOnlyNonPublishable("com.github.GTNewHorizons:BlockRenderer6343:1.4.23:dev") { transitive = false }
compileOnlyApi("com.github.GTNewHorizons:BlockRenderer6343:1.4.24:dev") { transitive = false }
runtimeOnlyNonPublishable("com.github.GTNewHorizons:BlockRenderer6343:1.4.24:dev") { transitive = false }
runtimeOnlyNonPublishable("com.github.GTNewHorizons:EnderCore:0.5.15:dev") { transitive = false }
runtimeOnlyNonPublishable("com.github.GTNewHorizons:ServerUtilities:2.4.10:dev")
runtimeOnlyNonPublishable("com.github.GTNewHorizons:ServerUtilities:2.4.14:dev")
runtimeOnlyNonPublishable("it.unimi.dsi:fastutil:8.5.18")
runtimeOnlyNonPublishable(rfg.deobf("curse.maven:spark-361579:4271867"))

compileOnlyApi("com.github.GTNewHorizons:nei-custom-diagram:1.8.36:dev") { transitive = false }
compileOnlyApi("com.github.GTNewHorizons:TinkersConstruct:1.14.112-GTNH:dev") { transitive = false }
compileOnlyApi("com.github.GTNewHorizons:TinkersConstruct:1.14.118-GTNH:dev") { transitive = false }
compileOnlyApi("com.github.GTNewHorizons:Mantle:0.5.4:dev") { transitive = false }
compileOnlyApi("com.github.GTNewHorizons:Mobs-Info:0.6.0-GTNH:dev") { transitive = false }
compileOnlyApi("com.github.GTNewHorizons:LogisticsPipes:1.5.36-GTNH:dev") { transitive = false }
compileOnlyApi("com.github.GTNewHorizons:BuildCraft:7.1.64:dev") { transitive = false }
compileOnlyApi("com.github.GTNewHorizons:Translocators:1.4.5:dev") { transitive = false }
compileOnlyApi("com.github.GTNewHorizons:SimpleSkinBackport:1.0.3-GTNH:dev") { transitive = false }
compileOnlyApi("com.github.GTNewHorizons:OpenComputers:1.12.61-GTNH:dev") { transitive = false }
compileOnlyApi("com.github.GTNewHorizons:OpenComputers:1.12.64-GTNH:dev") { transitive = false }
compileOnlyApi("com.github.slprime:ChromaticTooltips:1.0.28-GTNH:dev") { transitive = false }
compileOnlyApi("ganymedes01.etfuturum:Et-Futurum-Requiem:2.6.59-GTNH") { transitive = false }
compileOnlyApi("ganymedes01.etfuturum:Et-Futurum-Requiem:2.6.60-GTNH") { transitive = false }

// jvmDowngrader
compileOnly("javax.xml.bind:jaxb-api:2.3.1")
Expand All @@ -64,7 +64,7 @@ dependencies {
annotationProcessor("com.google.auto.value:auto-value:1.10.4")

testImplementation("org.junit.jupiter:junit-jupiter-api:5.12.2")
testImplementation("com.github.GTNewHorizons:StructureLib:1.4.43:dev")
testImplementation("com.github.GTNewHorizons:StructureLib:1.4.45:dev")
testImplementation("org.joml:joml:1.10.8")
testRuntimeOnly("org.junit.jupiter:junit-jupiter-engine:5.12.2")
testRuntimeOnly("org.junit.platform:junit-platform-launcher:1.12.2")
Expand All @@ -75,4 +75,4 @@ configurations.configureEach {
exclude group: "com.github.GTNewHorizons", module: "CodeChickenLib"
exclude group: "com.github.GTNewHorizons", module: "Hodgepodge"
exclude group: "com.github.GTNewHorizons", module: "Baubles"
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
import net.minecraft.item.Item;
import net.minecraft.item.ItemStack;
import net.minecraft.nbt.NBTBase;
import net.minecraftforge.oredict.OreDictionary;

import org.jetbrains.annotations.Nullable;

Expand Down Expand Up @@ -347,6 +348,14 @@ public interface HandlerRecipeAccess {

List<NeiRecipeLookup.Slot> readIngredientSlots(Object handler, int recipeIndex);

/**
* Reads catalyst or auxiliary slots exposed by a handler. Older integrations may not
* provide these slots, so the default keeps the access contract source-compatible.
*/
default List<NeiRecipeLookup.Slot> readOtherSlots(Object handler, int recipeIndex) {
return List.of();
}

@Nullable
NeiRecipeLookup.Slot readResultSlot(Object handler, int recipeIndex);
}
Expand Down Expand Up @@ -404,7 +413,8 @@ public static boolean stackMatches(@Nullable ItemStack stack, IdUtils.ParsedItem
if (stack == null) return false;
Item refItem = (Item) Item.itemRegistry.getObject(ref.rawKey());
if (refItem == null || stack.getItem() != refItem) return false;
if (!ref.isWildcardMeta() && stack.getItemDamage() != ref.meta()) return false;
if (!ref.isWildcardMeta() && stack.getItemDamage() != ref.meta()
&& stack.getItemDamage() != OreDictionary.WILDCARD_VALUE) return false;
if (ref.nbt() != null) {
if (stack.stackTagCompound == null) return false;
if (!ref.nbt()
Expand Down Expand Up @@ -433,6 +443,57 @@ public static boolean resultSlotContains(@Nullable NeiRecipeLookup.Slot result,
return false;
}

/**
* Matches a tag target against one handler recipe. Normal recipe tags are output queries. An
* explicitly named handler may instead expose the requested stack as an ingredient or
* catalyst, as Fuel and Brewing do in NEI, so those slots are checked when requested.
*/
public static boolean handlerTargetMatches(Object handler, int recipeIndex, IdUtils.ParsedItemRef ref,
HandlerRecipeAccess recipeAccess, boolean includeInputSlots) {
if (resultSlotContains(recipeAccess.readResultSlot(handler, recipeIndex), ref)) {
return true;
}
if (!includeInputSlots) {
return false;
}
if (slotsContain(recipeAccess.readIngredientSlots(handler, recipeIndex), ref)) {
return true;
}
if (slotsContain(recipeAccess.readOtherSlots(handler, recipeIndex), ref)) {
return true;
}
return ref.nbt() == null
&& damageableItemVariantPresent(recipeAccess.readIngredientSlots(handler, recipeIndex), ref);
}

public static boolean handlerTargetMatches(NeiRecipeLookup.Entry entry, IdUtils.ParsedItemRef ref,
boolean includeInputSlots) {
if (entry == null) return false;
if (resultSlotContains(entry.result, ref)) return true;
if (!includeInputSlots) return false;
if (slotsContain(entry.ingredients, ref)) return true;
if (slotsContain(entry.others, ref)) return true;
return ref.nbt() == null && damageableItemVariantPresent(entry.ingredients, ref);
}

private static boolean damageableItemVariantPresent(@Nullable List<NeiRecipeLookup.Slot> slots,
IdUtils.ParsedItemRef ref) {
if (slots == null) return false;
Item refItem = (Item) Item.itemRegistry.getObject(ref.rawKey());
if (refItem == null) return false;
for (NeiRecipeLookup.Slot slot : slots) {
if (slot == null || slot.stacks == null) continue;
for (ItemStack stack : slot.stacks) {
if (stack != null && stack.getItem() == refItem
&& stack.isItemStackDamageable()
&& stack.getItemDamage() > 0) {
return true;
}
}
}
return false;
}

public static boolean recipeSlotsContain(@Nullable List<RecipeSlot> slots, IdUtils.ParsedItemRef ref) {
if (slots == null) return false;
for (RecipeSlot slot : slots) {
Expand Down Expand Up @@ -581,6 +642,10 @@ public static boolean recipeMatches(Object handler, int recipeIndex, FilterExpr
return true;
}

public static boolean recipeMatches(NeiRecipeLookup.Entry entry, FilterExpr inputExpr, FilterExpr outputExpr) {
return entry != null && entryMatches(entry, inputExpr, outputExpr);
}

public static boolean entryMatches(NeiRecipeLookup.Entry e, FilterExpr inputExpr, FilterExpr outputExpr) {
if (!outputExpr.isEmpty() && !evalResultSlot(e.result, outputExpr)) return false;
if (!inputExpr.isEmpty() && !evalSlots(e.ingredients, inputExpr)) return false;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ private DefaultStyles() {}
.font(null)
.build();
public static final TextStyle HEADING3 = TextStyle.builder()
.fontScale(1f)
.fontScale(1.17f)
.font(null)
.build();
public static final TextStyle HEADING4 = TextStyle.builder()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,11 +8,11 @@
import lombok.Setter;

/**
* Places children into columns as wide as the widest of them, filling the shortest column first.
* Places children into the shortest available column while preserving each child's measured width.
*
* <p>
* Column count is based on the widest child and limited by {@link #getMaxColumns()}.
* Children wider than a column are laid out at their own width, falling back to a vertical stack.
* The highest column count whose measured column widths fit the available width is selected, up to
* {@link #getMaxColumns()}. If even two columns cannot fit, children are laid out as a vertical stack.
*/
@Getter
@Setter
Expand All @@ -34,56 +34,62 @@ protected LytRect computeBoxLayout(LayoutContext context, int x, int y, int avai
return verticalStack(context, x, y, availableWidth);
}

int widest = widestChildWidth(context, x, y, availableWidth);
int columns = columnCountFor(availableWidth, widest);
if (columns <= 1) {
return verticalStack(context, x, y, availableWidth);
int[] itemWidths = new int[count];
int[] itemHeights = new int[count];
for (int i = 0; i < count; i++) {
LytBlock child = children.get(i);
LytRect measured = child.layout(context, x, y, availableWidth);
itemWidths[i] = Math.max(1, measured.width() + child.getMarginLeft() + child.getMarginRight());
itemHeights[i] = Math.max(1, measured.height() + child.getMarginTop() + child.getMarginBottom());
}

int columnWidth = widest;
int columns = Math.min(count, maxColumns);
while (columns > 1) {
int[] assignments = new int[count];
int[] columnWidths = new int[columns];
int[] columnBottoms = new int[columns];
for (int i = 0; i < count; i++) {
int column = shortestColumn(columnBottoms);
assignments[i] = column;
columnWidths[column] = Math.max(columnWidths[column], itemWidths[i]);
columnBottoms[column] += itemHeights[i] + gap;
}
int requiredWidth = Math.max(0, columns - 1) * gap;
for (int width : columnWidths) {
requiredWidth += width;
}
if (requiredWidth <= availableWidth) {
return layoutColumns(context, x, y, availableWidth, assignments, columnWidths, columns);
}
columns--;
}
return verticalStack(context, x, y, availableWidth);
}

private LytRect layoutColumns(LayoutContext context, int x, int y, int availableWidth, int[] assignments,
int[] columnWidths, int columns) {
int[] columnBottoms = new int[columns];
LytBlock[] previousBlocks = new LytBlock[columns];
int contentWidth = 0;
int contentHeight = 0;

for (LytBlock child : children) {
int blockWidth = Math.max(1, columnWidth - child.getMarginLeft() - child.getMarginRight());
int columnIndex = shortestColumn(columnBottoms);

int columnX = x + columnIndex * (columnWidth + gap) + child.getMarginLeft();
int columnY = Layouts.offsetIntoContentArea(
LytAxis.VERTICAL,
y + columnBottoms[columnIndex],
previousBlocks[columnIndex],
child);
LytRect childBounds = child.layout(context, columnX, columnY, blockWidth);

columnBottoms[columnIndex] = childBounds.bottom() - y + child.getMarginBottom() + gap;
previousBlocks[columnIndex] = child;
int[] columnX = new int[columns];
for (int i = 1; i < columns; i++) {
columnX[i] = columnX[i - 1] + columnWidths[i - 1] + gap;
}
for (int i = 0; i < children.size(); i++) {
LytBlock child = children.get(i);
int column = assignments[i];
int blockWidth = Math.max(1, columnWidths[column] - child.getMarginLeft() - child.getMarginRight());
int childX = x + columnX[column] + child.getMarginLeft();
int childY = Layouts
.offsetIntoContentArea(LytAxis.VERTICAL, y + columnBottoms[column], previousBlocks[column], child);
LytRect childBounds = child.layout(context, childX, childY, blockWidth);
columnBottoms[column] = childBounds.bottom() - y + child.getMarginBottom() + gap;
previousBlocks[column] = child;
contentWidth = Math.max(contentWidth, childBounds.right() - x);
contentHeight = Math.max(contentHeight, childBounds.bottom() - y);
}

return new LytRect(x, y, contentWidth, contentHeight);
}

private int widestChildWidth(LayoutContext context, int x, int y, int availableWidth) {
int widest = 0;
for (LytBlock child : children) {
LytRect bounds = child.layout(context, x, y, availableWidth);
widest = Math.max(widest, bounds.width() + child.getMarginLeft() + child.getMarginRight());
}
return widest;
}

private int columnCountFor(int availableWidth, int widest) {
int limit = Math.min(children.size(), maxColumns);
if (widest <= 0) {
return Math.max(1, limit);
}
// Columns are as wide as the widest child, so n of them need n widths and n-1 gaps.
int byWidth = (availableWidth + gap) / (widest + gap);
return Math.max(1, Math.min(limit, byWidth));
return new LytRect(x, y, Math.min(availableWidth, contentWidth), contentHeight);
}

private static int shortestColumn(int[] columnBottoms) {
Expand Down
Loading